summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: c1d6b33)
raw | patch | inline | side by side (parent: c1d6b33)
author | Suman Anna <s-anna@ti.com> | |
Thu, 22 Nov 2018 11:39:01 +0000 (13:39 +0200) | ||
committer | Suman Anna <s-anna@ti.com> | |
Sun, 24 Feb 2019 01:20:48 +0000 (19:20 -0600) |
The PRUSS CFG module's SYSCFG register is used for managing the
PRCM clock management settings at the PRU-ICSS subsystem level.
Add two helper functions pruss_{enable/disable}_module() that
programs this SYSCFG register during probe and remove. The
register is currently programmed for the default Smart-Idle
and Smart-Standby always during probe. The MStandby is enabled
during remove to undo the settings in probe to properly configure
the SYSCFG in the case that a firmware has disabled MStandby.
This is needed on SoCs like AM57xx that do not have a reset line
and so cannot reset the register properly.
Signed-off-by: Suman Anna <s-anna@ti.com>
Signed-off-by: Roger Quadros <rogerq@ti.com>
PRCM clock management settings at the PRU-ICSS subsystem level.
Add two helper functions pruss_{enable/disable}_module() that
programs this SYSCFG register during probe and remove. The
register is currently programmed for the default Smart-Idle
and Smart-Standby always during probe. The MStandby is enabled
during remove to undo the settings in probe to properly configure
the SYSCFG in the case that a firmware has disabled MStandby.
This is needed on SoCs like AM57xx that do not have a reset line
and so cannot reset the register properly.
Signed-off-by: Suman Anna <s-anna@ti.com>
Signed-off-by: Roger Quadros <rogerq@ti.com>
drivers/soc/ti/pruss_soc_bus.c | patch | blob | history |
index afa55c9c9d94c201f9d5e1a9d50142ee0af0794e..ff1e0d0f59efed3ae75e2fff94c39061242bc04d 100644 (file)
#define SYSCFG_STANDBY_INIT BIT(4)
#define SYSCFG_SUB_MWAIT_READY BIT(5)
+#define SYSCFG_STANDBY_MODE_FORCE (0 << 2)
+#define SYSCFG_STANDBY_MODE_NO (1 << 2)
+#define SYSCFG_STANDBY_MODE_SMART (2 << 2)
+#define SYSCFG_STANDBY_MODE_MASK (3 << 2)
+
+#define SYSCFG_IDLE_MODE_FORCE 0
+#define SYSCFG_IDLE_MODE_NO 1
+#define SYSCFG_IDLE_MODE_SMART 2
+#define SYSCFG_IDLE_MODE_MASK 3
+
/**
* struct pruss_soc_bus - PRUSS SoC bus structure
* @syscfg: kernel mapped address for SYSCFG register
return ret;
}
+/* firmware must be idle when calling this function */
+static void pruss_disable_module(struct device *dev)
+{
+ struct pruss_soc_bus *psoc_bus = dev_get_drvdata(dev);
+
+ /* configure Smart Standby */
+ pruss_soc_bus_rmw(psoc_bus->syscfg, SYSCFG_STANDBY_MODE_MASK,
+ SYSCFG_STANDBY_MODE_SMART);
+
+ /* initiate MStandby */
+ pruss_soc_bus_rmw(psoc_bus->syscfg, SYSCFG_STANDBY_INIT,
+ SYSCFG_STANDBY_INIT);
+
+ /* tell PRCM to initiate IDLE request */
+ pm_runtime_put_sync(dev);
+}
+
+static int pruss_enable_module(struct device *dev)
+{
+ struct pruss_soc_bus *psoc_bus = dev_get_drvdata(dev);
+ int ret;
+
+ /* tell PRCM to de-assert IDLE request */
+ ret = pm_runtime_get_sync(dev);
+ if (ret < 0) {
+ pm_runtime_put_noidle(dev);
+ return ret;
+ }
+
+ /* configure for Smart Idle & Smart Standby */
+ pruss_soc_bus_rmw(psoc_bus->syscfg, SYSCFG_IDLE_MODE_MASK,
+ SYSCFG_IDLE_MODE_SMART);
+ pruss_soc_bus_rmw(psoc_bus->syscfg, SYSCFG_STANDBY_MODE_MASK,
+ SYSCFG_STANDBY_MODE_SMART);
+
+ return ret;
+}
+
static int pruss_soc_bus_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
}
pm_runtime_enable(dev);
- ret = pm_runtime_get_sync(dev);
+ ret = pruss_enable_module(dev);
if (ret < 0) {
- pm_runtime_put_noidle(dev);
- goto fail_clock;
+ dev_err(dev, "couldn't enable module\n");
+ goto fail_module;
}
ret = of_platform_populate(node, NULL, NULL, dev);
return 0;
fail_of:
- pm_runtime_put_sync(dev);
-fail_clock:
+ pruss_disable_module(dev);
+fail_module:
pm_runtime_disable(dev);
if (psoc_bus->has_reset)
pdata->assert_reset(pdev, pdata->reset_name);
of_platform_depopulate(dev);
- pm_runtime_put_sync(dev);
+ pruss_disable_module(dev);
pm_runtime_disable(dev);
if (psoc_bus->has_reset)