LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
* [PATCHv2 00/13] ti-sysc driver changes to drop custom hwmods property
@ 2019-05-28  6:24 Tony Lindgren
  2019-05-28  6:24 ` [PATCH 01/13] bus: ti-sysc: Add support for missing clockdomain handling Tony Lindgren
                   ` (13 more replies)
  0 siblings, 14 replies; 15+ messages in thread
From: Tony Lindgren @ 2019-05-28  6:24 UTC (permalink / raw)
  To: linux-omap
  Cc: Dave Gerlach, Faiz Abbas, Greg Kroah-Hartman, Keerthy,
	Nishanth Menon, Peter Ujfalusi, Roger Quadros, Suman Anna,
	Tero Kristo, linux-kernel, linux-arm-kernel, Rob Herring,
	devicetree

Hi all,

Here are changes to improve ti-sysc driver to the point where we can
finally drop the custom hwmods property for most cases. This series
drops hwmods property only for omap4 UART and MMC as those can be
tested with core retention idle.

I'll be posting more patches for dropping hwmods properties as they
get tested.

Regards,

Tony

Changes since v1:

- Repost the series against v5.2-rc1 as the first patch in the series
  got accidentally left out for patch "bus: ti-sysc: Add support for
  missing clockdomain handling"


Tony Lindgren (13):
  bus: ti-sysc: Add support for missing clockdomain handling
  bus: ti-sysc: Support 16-bit writes too
  bus: ti-sysc: Make OCP reset work for sysstatus and sysconfig reset
    bits
  bus: ti-sysc: Allow QUIRK_LEGACY_IDLE even if legacy_mode is not set
  bus: ti-sysc: Enable interconnect target module autoidle bit on enable
  bus: ti-sysc: Handle clockactivity for enable and disable
  bus: ti-sysc: Handle swsup idle mode quirks
  bus: ti-sysc: Set ENAWAKEUP if available
  bus: ti-sysc: Add support for disabling module without legacy mode
  bus: ti-sysc: Do rstctrl reset handling in two phases
  bus: ti-sysc: Detect uarts also on omap34xx
  ARM: dts: Drop legacy custom hwmods property for omap4 uart
  ARM: dts: Drop legacy custom hwmods property for omap4 mmc

 arch/arm/boot/dts/omap4-l4.dtsi       |   9 -
 arch/arm/mach-omap2/omap_hwmod.c      |  39 +---
 arch/arm/mach-omap2/pdata-quirks.c    |  60 +++++
 drivers/bus/ti-sysc.c                 | 309 ++++++++++++++++++++------
 include/linux/platform_data/ti-sysc.h |   9 +
 5 files changed, 314 insertions(+), 112 deletions(-)

-- 
2.21.0

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 01/13] bus: ti-sysc: Add support for missing clockdomain handling
  2019-05-28  6:24 [PATCHv2 00/13] ti-sysc driver changes to drop custom hwmods property Tony Lindgren
@ 2019-05-28  6:24 ` Tony Lindgren
  2019-05-28  6:24 ` [PATCH 02/13] bus: ti-sysc: Support 16-bit writes too Tony Lindgren
                   ` (12 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Tony Lindgren @ 2019-05-28  6:24 UTC (permalink / raw)
  To: linux-omap
  Cc: Dave Gerlach, Faiz Abbas, Greg Kroah-Hartman, Keerthy,
	Nishanth Menon, Peter Ujfalusi, Roger Quadros, Suman Anna,
	Tero Kristo, linux-kernel, linux-arm-kernel, Rob Herring,
	devicetree

We need to let ti-sysc driver manage clockdomain autoidle for the
duration of of reset, enable and idle. And we need to do it before we
enable the clock and after we disable it. Currently we are still
relying on platform callbacks indirectly managing clockdomain autoidle.
But I noticed that for device tree only probed drivers it now happens
only after we enabling the clocks and before we disable the clocks,
while it should be the other way around. So far I have not noticed
any issues with this though.

Let's add new ti_sysc_clkdm_deny_idle() and ti_sysc_clkdm_allow_idle()
functions for ti-sysc driver to use to manage clockdomains directly via
platform data callbacks. Note that we can implement the clockdomain
functions in pdata-quirks.c as for probing devices without "ti,hwmods"
custom property we don't need to use the other platform data callbacks.

Let's do this in one patch as there's is still an unlikely chance we
may need to apply this as a fix for v5.2 for dropping legacy platform
data for some devices. We also do have the option of adding back the
platform data if needed in case of trouble.

Signed-off-by: Tony Lindgren <tony@atomide.com>
---
 arch/arm/mach-omap2/omap_hwmod.c      |  39 +-------
 arch/arm/mach-omap2/pdata-quirks.c    |  60 ++++++++++++
 drivers/bus/ti-sysc.c                 | 127 ++++++++++++++++++++------
 include/linux/platform_data/ti-sysc.h |   8 ++
 4 files changed, 174 insertions(+), 60 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -3445,6 +3445,7 @@ static int omap_hwmod_check_module(struct device *dev,
  * @dev: struct device
  * @oh: module
  * @sysc_fields: sysc register bits
+ * @clockdomain: clockdomain
  * @rev_offs: revision register offset
  * @sysc_offs: sysconfig register offset
  * @syss_offs: sysstatus register offset
@@ -3456,6 +3457,7 @@ static int omap_hwmod_check_module(struct device *dev,
 static int omap_hwmod_allocate_module(struct device *dev, struct omap_hwmod *oh,
 				      const struct ti_sysc_module_data *data,
 				      struct sysc_regbits *sysc_fields,
+				      struct clockdomain *clkdm,
 				      s32 rev_offs, s32 sysc_offs,
 				      s32 syss_offs, u32 sysc_flags,
 				      u32 idlemodes)
@@ -3463,8 +3465,6 @@ static int omap_hwmod_allocate_module(struct device *dev, struct omap_hwmod *oh,
 	struct omap_hwmod_class_sysconfig *sysc;
 	struct omap_hwmod_class *class = NULL;
 	struct omap_hwmod_ocp_if *oi = NULL;
-	struct clockdomain *clkdm = NULL;
-	struct clk *clk = NULL;
 	void __iomem *regs = NULL;
 	unsigned long flags;
 
@@ -3511,36 +3511,6 @@ static int omap_hwmod_allocate_module(struct device *dev, struct omap_hwmod *oh,
 		oi->user = OCP_USER_MPU | OCP_USER_SDMA;
 	}
 
-	if (!oh->_clk) {
-		struct clk_hw_omap *hwclk;
-
-		clk = of_clk_get_by_name(dev->of_node, "fck");
-		if (!IS_ERR(clk))
-			clk_prepare(clk);
-		else
-			clk = NULL;
-
-		/*
-		 * Populate clockdomain based on dts clock. It is needed for
-		 * clkdm_deny_idle() and clkdm_allow_idle() until we have have
-		 * interconnect driver and reset driver capable of blocking
-		 * clockdomain idle during reset, enable and idle.
-		 */
-		if (clk) {
-			hwclk = to_clk_hw_omap(__clk_get_hw(clk));
-			if (hwclk && hwclk->clkdm_name)
-				clkdm = clkdm_lookup(hwclk->clkdm_name);
-		}
-
-		/*
-		 * Note that we assume interconnect driver manages the clocks
-		 * and do not need to populate oh->_clk for dynamically
-		 * allocated modules.
-		 */
-		clk_unprepare(clk);
-		clk_put(clk);
-	}
-
 	spin_lock_irqsave(&oh->_lock, flags);
 	if (regs)
 		oh->_mpu_rt_va = regs;
@@ -3626,7 +3596,7 @@ int omap_hwmod_init_module(struct device *dev,
 	u32 sysc_flags, idlemodes;
 	int error;
 
-	if (!dev || !data)
+	if (!dev || !data || !data->name || !cookie)
 		return -EINVAL;
 
 	oh = _lookup(data->name);
@@ -3697,7 +3667,8 @@ int omap_hwmod_init_module(struct device *dev,
 		return error;
 
 	return omap_hwmod_allocate_module(dev, oh, data, sysc_fields,
-					  rev_offs, sysc_offs, syss_offs,
+					  cookie->clkdm, rev_offs,
+					  sysc_offs, syss_offs,
 					  sysc_flags, idlemodes);
 }
 
diff --git a/arch/arm/mach-omap2/pdata-quirks.c b/arch/arm/mach-omap2/pdata-quirks.c
--- a/arch/arm/mach-omap2/pdata-quirks.c
+++ b/arch/arm/mach-omap2/pdata-quirks.c
@@ -29,6 +29,7 @@
 #include <linux/platform_data/wkup_m3.h>
 #include <linux/platform_data/asoc-ti-mcbsp.h>
 
+#include "clockdomain.h"
 #include "common.h"
 #include "common-board-devices.h"
 #include "control.h"
@@ -463,6 +464,62 @@ static void __init dra7x_evm_mmc_quirk(void)
 }
 #endif
 
+static struct clockdomain *ti_sysc_find_one_clockdomain(struct clk *clk)
+{
+	struct clockdomain *clkdm = NULL;
+	struct clk_hw_omap *hwclk;
+
+	hwclk = to_clk_hw_omap(__clk_get_hw(clk));
+	if (hwclk && hwclk->clkdm_name)
+		clkdm = clkdm_lookup(hwclk->clkdm_name);
+
+	return clkdm;
+}
+
+/**
+ * ti_sysc_clkdm_init - find clockdomain based on clock
+ * @fck: device functional clock
+ * @ick: device interface clock
+ * @dev: struct device
+ *
+ * Populate clockdomain based on clock. It is needed for
+ * clkdm_deny_idle() and clkdm_allow_idle() for blocking clockdomain
+ * clockdomain idle during reset, enable and idle.
+ *
+ * Note that we assume interconnect driver manages the clocks
+ * and do not need to populate oh->_clk for dynamically
+ * allocated modules.
+ */
+static int ti_sysc_clkdm_init(struct device *dev,
+			      struct clk *fck, struct clk *ick,
+			      struct ti_sysc_cookie *cookie)
+{
+	if (fck)
+		cookie->clkdm = ti_sysc_find_one_clockdomain(fck);
+	if (cookie->clkdm)
+		return 0;
+	if (ick)
+		cookie->clkdm = ti_sysc_find_one_clockdomain(ick);
+	if (cookie->clkdm)
+		return 0;
+
+	return -ENODEV;
+}
+
+static void ti_sysc_clkdm_deny_idle(struct device *dev,
+				    const struct ti_sysc_cookie *cookie)
+{
+	if (cookie->clkdm)
+		clkdm_deny_idle(cookie->clkdm);
+}
+
+static void ti_sysc_clkdm_allow_idle(struct device *dev,
+				     const struct ti_sysc_cookie *cookie)
+{
+	if (cookie->clkdm)
+		clkdm_allow_idle(cookie->clkdm);
+}
+
 static int ti_sysc_enable_module(struct device *dev,
 				 const struct ti_sysc_cookie *cookie)
 {
@@ -494,6 +551,9 @@ static struct of_dev_auxdata omap_auxdata_lookup[];
 
 static struct ti_sysc_platform_data ti_sysc_pdata = {
 	.auxdata = omap_auxdata_lookup,
+	.init_clockdomain = ti_sysc_clkdm_init,
+	.clkdm_deny_idle = ti_sysc_clkdm_deny_idle,
+	.clkdm_allow_idle = ti_sysc_clkdm_allow_idle,
 	.init_module = omap_hwmod_init_module,
 	.enable_module = ti_sysc_enable_module,
 	.idle_module = ti_sysc_idle_module,
diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c
--- a/drivers/bus/ti-sysc.c
+++ b/drivers/bus/ti-sysc.c
@@ -422,6 +422,30 @@ static void sysc_disable_opt_clocks(struct sysc *ddata)
 	}
 }
 
+static void sysc_clkdm_deny_idle(struct sysc *ddata)
+{
+	struct ti_sysc_platform_data *pdata;
+
+	if (ddata->legacy_mode)
+		return;
+
+	pdata = dev_get_platdata(ddata->dev);
+	if (pdata && pdata->clkdm_deny_idle)
+		pdata->clkdm_deny_idle(ddata->dev, &ddata->cookie);
+}
+
+static void sysc_clkdm_allow_idle(struct sysc *ddata)
+{
+	struct ti_sysc_platform_data *pdata;
+
+	if (ddata->legacy_mode)
+		return;
+
+	pdata = dev_get_platdata(ddata->dev);
+	if (pdata && pdata->clkdm_allow_idle)
+		pdata->clkdm_allow_idle(ddata->dev, &ddata->cookie);
+}
+
 /**
  * sysc_init_resets - init rstctrl reset line if configured
  * @ddata: device driver data
@@ -795,6 +819,7 @@ static void sysc_show_registers(struct sysc *ddata)
 
 #define SYSC_IDLE_MASK	(SYSC_NR_IDLEMODES - 1)
 
+/* Caller needs to manage sysc_clkdm_deny_idle() and sysc_clkdm_allow_idle() */
 static int sysc_enable_module(struct device *dev)
 {
 	struct sysc *ddata;
@@ -805,11 +830,6 @@ static int sysc_enable_module(struct device *dev)
 	if (ddata->offsets[SYSC_SYSCONFIG] == -ENODEV)
 		return 0;
 
-	/*
-	 * TODO: Need to prevent clockdomain autoidle?
-	 * See clkdm_deny_idle() in arch/mach-omap2/omap_hwmod.c
-	 */
-
 	regbits = ddata->cap->regbits;
 	reg = sysc_read(ddata, ddata->offsets[SYSC_SYSCONFIG]);
 
@@ -861,6 +881,7 @@ static int sysc_best_idle_mode(u32 idlemodes, u32 *best_mode)
 	return 0;
 }
 
+/* Caller needs to manage sysc_clkdm_deny_idle() and sysc_clkdm_allow_idle() */
 static int sysc_disable_module(struct device *dev)
 {
 	struct sysc *ddata;
@@ -872,11 +893,6 @@ static int sysc_disable_module(struct device *dev)
 	if (ddata->offsets[SYSC_SYSCONFIG] == -ENODEV)
 		return 0;
 
-	/*
-	 * TODO: Need to prevent clockdomain autoidle?
-	 * See clkdm_deny_idle() in arch/mach-omap2/omap_hwmod.c
-	 */
-
 	regbits = ddata->cap->regbits;
 	reg = sysc_read(ddata, ddata->offsets[SYSC_SYSCONFIG]);
 
@@ -966,14 +982,16 @@ static int __maybe_unused sysc_runtime_suspend(struct device *dev)
 	if (!ddata->enabled)
 		return 0;
 
+	sysc_clkdm_deny_idle(ddata);
+
 	if (ddata->legacy_mode) {
 		error = sysc_runtime_suspend_legacy(dev, ddata);
 		if (error)
-			return error;
+			goto err_allow_idle;
 	} else {
 		error = sysc_disable_module(dev);
 		if (error)
-			return error;
+			goto err_allow_idle;
 	}
 
 	sysc_disable_main_clocks(ddata);
@@ -983,6 +1001,9 @@ static int __maybe_unused sysc_runtime_suspend(struct device *dev)
 
 	ddata->enabled = false;
 
+err_allow_idle:
+	sysc_clkdm_allow_idle(ddata);
+
 	return error;
 }
 
@@ -996,10 +1017,12 @@ static int __maybe_unused sysc_runtime_resume(struct device *dev)
 	if (ddata->enabled)
 		return 0;
 
+	sysc_clkdm_deny_idle(ddata);
+
 	if (sysc_opt_clks_needed(ddata)) {
 		error = sysc_enable_opt_clocks(ddata);
 		if (error)
-			return error;
+			goto err_allow_idle;
 	}
 
 	error = sysc_enable_main_clocks(ddata);
@@ -1018,6 +1041,8 @@ static int __maybe_unused sysc_runtime_resume(struct device *dev)
 
 	ddata->enabled = true;
 
+	sysc_clkdm_allow_idle(ddata);
+
 	return 0;
 
 err_main_clocks:
@@ -1025,6 +1050,8 @@ static int __maybe_unused sysc_runtime_resume(struct device *dev)
 err_opt_clocks:
 	if (sysc_opt_clks_needed(ddata))
 		sysc_disable_opt_clocks(ddata);
+err_allow_idle:
+	sysc_clkdm_allow_idle(ddata);
 
 	return error;
 }
@@ -1246,6 +1273,33 @@ static void sysc_init_revision_quirks(struct sysc *ddata)
 	}
 }
 
+static int sysc_clockdomain_init(struct sysc *ddata)
+{
+	struct ti_sysc_platform_data *pdata = dev_get_platdata(ddata->dev);
+	struct clk *fck = NULL, *ick = NULL;
+	int error;
+
+	if (!pdata || !pdata->init_clockdomain)
+		return 0;
+
+	switch (ddata->nr_clocks) {
+	case 2:
+		ick = ddata->clocks[SYSC_ICK];
+		/* fallthrough */
+	case 1:
+		fck = ddata->clocks[SYSC_FCK];
+		break;
+	case 0:
+		return 0;
+	}
+
+	error = pdata->init_clockdomain(ddata->dev, fck, ick, &ddata->cookie);
+	if (!error || error == -ENODEV)
+		return 0;
+
+	return error;
+}
+
 /*
  * Note that pdata->init_module() typically does a reset first. After
  * pdata->init_module() is done, PM runtime can be used for the interconnect
@@ -1256,7 +1310,7 @@ static int sysc_legacy_init(struct sysc *ddata)
 	struct ti_sysc_platform_data *pdata = dev_get_platdata(ddata->dev);
 	int error;
 
-	if (!ddata->legacy_mode || !pdata || !pdata->init_module)
+	if (!pdata || !pdata->init_module)
 		return 0;
 
 	error = pdata->init_module(ddata->dev, ddata->mdata, &ddata->cookie);
@@ -1348,7 +1402,13 @@ static int sysc_init_module(struct sysc *ddata)
 	    (SYSC_QUIRK_NO_IDLE | SYSC_QUIRK_NO_IDLE_ON_INIT))
 		manage_clocks = false;
 
+	error = sysc_clockdomain_init(ddata);
+	if (error)
+		return error;
+
 	if (manage_clocks) {
+		sysc_clkdm_deny_idle(ddata);
+
 		error = sysc_enable_opt_clocks(ddata);
 		if (error)
 			return error;
@@ -1361,20 +1421,33 @@ static int sysc_init_module(struct sysc *ddata)
 	ddata->revision = sysc_read_revision(ddata);
 	sysc_init_revision_quirks(ddata);
 
-	error = sysc_legacy_init(ddata);
-	if (error)
-		goto err_main_clocks;
+	if (ddata->legacy_mode) {
+		error = sysc_legacy_init(ddata);
+		if (error)
+			goto err_main_clocks;
+	}
+
+	if (!ddata->legacy_mode && manage_clocks) {
+		error = sysc_enable_module(ddata->dev);
+		if (error)
+			goto err_main_clocks;
+	}
 
 	error = sysc_reset(ddata);
 	if (error)
 		dev_err(ddata->dev, "Reset failed with %d\n", error);
 
+	if (!ddata->legacy_mode && manage_clocks)
+		sysc_disable_module(ddata->dev);
+
 err_main_clocks:
 	if (manage_clocks)
 		sysc_disable_main_clocks(ddata);
 err_opt_clocks:
-	if (manage_clocks)
+	if (manage_clocks) {
 		sysc_disable_opt_clocks(ddata);
+		sysc_clkdm_allow_idle(ddata);
+	}
 
 	return error;
 }
@@ -2013,20 +2086,22 @@ static int sysc_init_pdata(struct sysc *ddata)
 	struct ti_sysc_platform_data *pdata = dev_get_platdata(ddata->dev);
 	struct ti_sysc_module_data *mdata;
 
-	if (!pdata || !ddata->legacy_mode)
+	if (!pdata)
 		return 0;
 
 	mdata = devm_kzalloc(ddata->dev, sizeof(*mdata), GFP_KERNEL);
 	if (!mdata)
 		return -ENOMEM;
 
-	mdata->name = ddata->legacy_mode;
-	mdata->module_pa = ddata->module_pa;
-	mdata->module_size = ddata->module_size;
-	mdata->offsets = ddata->offsets;
-	mdata->nr_offsets = SYSC_MAX_REGS;
-	mdata->cap = ddata->cap;
-	mdata->cfg = &ddata->cfg;
+	if (ddata->legacy_mode) {
+		mdata->name = ddata->legacy_mode;
+		mdata->module_pa = ddata->module_pa;
+		mdata->module_size = ddata->module_size;
+		mdata->offsets = ddata->offsets;
+		mdata->nr_offsets = SYSC_MAX_REGS;
+		mdata->cap = ddata->cap;
+		mdata->cfg = &ddata->cfg;
+	}
 
 	ddata->mdata = mdata;
 
diff --git a/include/linux/platform_data/ti-sysc.h b/include/linux/platform_data/ti-sysc.h
--- a/include/linux/platform_data/ti-sysc.h
+++ b/include/linux/platform_data/ti-sysc.h
@@ -19,6 +19,7 @@ enum ti_sysc_module_type {
 
 struct ti_sysc_cookie {
 	void *data;
+	void *clkdm;
 };
 
 /**
@@ -125,9 +126,16 @@ struct ti_sysc_module_data {
 };
 
 struct device;
+struct clk;
 
 struct ti_sysc_platform_data {
 	struct of_dev_auxdata *auxdata;
+	int (*init_clockdomain)(struct device *dev, struct clk *fck,
+				struct clk *ick, struct ti_sysc_cookie *cookie);
+	void (*clkdm_deny_idle)(struct device *dev,
+				const struct ti_sysc_cookie *cookie);
+	void (*clkdm_allow_idle)(struct device *dev,
+				 const struct ti_sysc_cookie *cookie);
 	int (*init_module)(struct device *dev,
 			   const struct ti_sysc_module_data *data,
 			   struct ti_sysc_cookie *cookie);
-- 
2.21.0

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 02/13] bus: ti-sysc: Support 16-bit writes too
  2019-05-28  6:24 [PATCHv2 00/13] ti-sysc driver changes to drop custom hwmods property Tony Lindgren
  2019-05-28  6:24 ` [PATCH 01/13] bus: ti-sysc: Add support for missing clockdomain handling Tony Lindgren
@ 2019-05-28  6:24 ` Tony Lindgren
  2019-05-28  6:24 ` [PATCH 03/13] bus: ti-sysc: Make OCP reset work for sysstatus and sysconfig reset bits Tony Lindgren
                   ` (11 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Tony Lindgren @ 2019-05-28  6:24 UTC (permalink / raw)
  To: linux-omap
  Cc: Dave Gerlach, Faiz Abbas, Greg Kroah-Hartman, Keerthy,
	Nishanth Menon, Peter Ujfalusi, Roger Quadros, Suman Anna,
	Tero Kristo, linux-kernel, linux-arm-kernel, Rob Herring,
	devicetree

We need to also support 16-bit writes for i2c in addition to the reads
when we start configuring the sysconfig register for reset and idle modes.

Signed-off-by: Tony Lindgren <tony@atomide.com>
---
 drivers/bus/ti-sysc.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c
--- a/drivers/bus/ti-sysc.c
+++ b/drivers/bus/ti-sysc.c
@@ -100,6 +100,13 @@ static void sysc_parse_dts_quirks(struct sysc *ddata, struct device_node *np,
 
 static void sysc_write(struct sysc *ddata, int offset, u32 value)
 {
+	if (ddata->cfg.quirks & SYSC_QUIRK_16BIT) {
+		writew_relaxed(value & 0xffff, ddata->module_va + offset);
+		writew_relaxed(value >> 16, ddata->module_va + offset + 4);
+
+		return;
+	}
+
 	writel_relaxed(value, ddata->module_va + offset);
 }
 
-- 
2.21.0

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 03/13] bus: ti-sysc: Make OCP reset work for sysstatus and sysconfig reset bits
  2019-05-28  6:24 [PATCHv2 00/13] ti-sysc driver changes to drop custom hwmods property Tony Lindgren
  2019-05-28  6:24 ` [PATCH 01/13] bus: ti-sysc: Add support for missing clockdomain handling Tony Lindgren
  2019-05-28  6:24 ` [PATCH 02/13] bus: ti-sysc: Support 16-bit writes too Tony Lindgren
@ 2019-05-28  6:24 ` Tony Lindgren
  2019-05-28  6:24 ` [PATCH 04/13] bus: ti-sysc: Allow QUIRK_LEGACY_IDLE even if legacy_mode is not set Tony Lindgren
                   ` (10 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Tony Lindgren @ 2019-05-28  6:24 UTC (permalink / raw)
  To: linux-omap
  Cc: Dave Gerlach, Faiz Abbas, Greg Kroah-Hartman, Keerthy,
	Nishanth Menon, Peter Ujfalusi, Roger Quadros, Suman Anna,
	Tero Kristo, linux-kernel, linux-arm-kernel, Rob Herring,
	devicetree

We've had minimal OCP softreset support in ti-sysc interconnect target
module driver only used for MCAN driver so far. But it turns out that
MCAN has the sysstatus register resetdone bit inverted compared to most
other modules.

Let's make OCP softreset work for other typical cases with reset status
in sysstatus or sysconfig register so we can use the new functions for
sysc_enable_module() and sysc_disable_module() without "ti,hwmods"
property in the following patches.

Signed-off-by: Tony Lindgren <tony@atomide.com>
---
 drivers/bus/ti-sysc.c                 | 72 ++++++++++++++++++++-------
 include/linux/platform_data/ti-sysc.h |  1 +
 2 files changed, 55 insertions(+), 18 deletions(-)

diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c
--- a/drivers/bus/ti-sysc.c
+++ b/drivers/bus/ti-sysc.c
@@ -139,6 +139,26 @@ static u32 sysc_read_revision(struct sysc *ddata)
 	return sysc_read(ddata, offset);
 }
 
+static u32 sysc_read_sysconfig(struct sysc *ddata)
+{
+	int offset = ddata->offsets[SYSC_SYSCONFIG];
+
+	if (offset < 0)
+		return 0;
+
+	return sysc_read(ddata, offset);
+}
+
+static u32 sysc_read_sysstatus(struct sysc *ddata)
+{
+	int offset = ddata->offsets[SYSC_SYSSTATUS];
+
+	if (offset < 0)
+		return 0;
+
+	return sysc_read(ddata, offset);
+}
+
 static int sysc_add_named_clock_from_child(struct sysc *ddata,
 					   const char *name,
 					   const char *optfck_name)
@@ -1356,34 +1376,49 @@ static int sysc_rstctrl_reset_deassert(struct sysc *ddata, bool reset)
 	return reset_control_deassert(ddata->rsts);
 }
 
+/*
+ * Note that the caller must ensure the interconnect target module is enabled
+ * before calling reset. Otherwise reset will not complete.
+ */
 static int sysc_reset(struct sysc *ddata)
 {
-	int offset = ddata->offsets[SYSC_SYSCONFIG];
-	int val;
+	int sysc_offset, syss_offset, sysc_val, rstval, quirks, error = 0;
+	u32 sysc_mask, syss_done;
+
+	sysc_offset = ddata->offsets[SYSC_SYSCONFIG];
+	syss_offset = ddata->offsets[SYSC_SYSSTATUS];
+	quirks = ddata->cfg.quirks;
 
-	if (ddata->legacy_mode || offset < 0 ||
+	if (ddata->legacy_mode || sysc_offset < 0 ||
+	    ddata->cap->regbits->srst_shift < 0 ||
 	    ddata->cfg.quirks & SYSC_QUIRK_NO_RESET_ON_INIT)
 		return 0;
 
-	/*
-	 * Currently only support reset status in sysstatus.
-	 * Warn and return error in all other cases
-	 */
-	if (!ddata->cfg.syss_mask) {
-		dev_err(ddata->dev, "No ti,syss-mask. Reset failed\n");
-		return -EINVAL;
-	}
+	sysc_mask = BIT(ddata->cap->regbits->srst_shift);
 
-	val = sysc_read(ddata, offset);
-	val |= (0x1 << ddata->cap->regbits->srst_shift);
-	sysc_write(ddata, offset, val);
+	if (ddata->cfg.quirks & SYSS_QUIRK_RESETDONE_INVERTED)
+		syss_done = 0;
+	else
+		syss_done = ddata->cfg.syss_mask;
+
+	sysc_val = sysc_read_sysconfig(ddata);
+	sysc_val |= sysc_mask;
+	sysc_write(ddata, sysc_offset, sysc_val);
 
 	/* Poll on reset status */
-	offset = ddata->offsets[SYSC_SYSSTATUS];
+	if (syss_offset >= 0) {
+		error = readx_poll_timeout(sysc_read_sysstatus, ddata, rstval,
+					   (rstval & ddata->cfg.syss_mask) ==
+					   syss_done,
+					   100, MAX_MODULE_SOFTRESET_WAIT);
+
+	} else if (ddata->cfg.quirks & SYSC_QUIRK_RESET_STATUS) {
+		error = readx_poll_timeout(sysc_read_sysconfig, ddata, rstval,
+					   !(rstval & sysc_mask),
+					   100, MAX_MODULE_SOFTRESET_WAIT);
+	}
 
-	return readl_poll_timeout(ddata->module_va + offset, val,
-				  (val & ddata->cfg.syss_mask) == 0x0,
-				  100, MAX_MODULE_SOFTRESET_WAIT);
+	return error;
 }
 
 /*
@@ -2086,6 +2121,7 @@ static const struct sysc_capabilities sysc_dra7_mcan = {
 	.type = TI_SYSC_DRA7_MCAN,
 	.sysc_mask = SYSC_DRA7_MCAN_ENAWAKEUP | SYSC_OMAP4_SOFTRESET,
 	.regbits = &sysc_regbits_dra7_mcan,
+	.mod_quirks = SYSS_QUIRK_RESETDONE_INVERTED,
 };
 
 static int sysc_init_pdata(struct sysc *ddata)
diff --git a/include/linux/platform_data/ti-sysc.h b/include/linux/platform_data/ti-sysc.h
--- a/include/linux/platform_data/ti-sysc.h
+++ b/include/linux/platform_data/ti-sysc.h
@@ -47,6 +47,7 @@ struct sysc_regbits {
 	s8 emufree_shift;
 };
 
+#define SYSS_QUIRK_RESETDONE_INVERTED	BIT(14)
 #define SYSC_QUIRK_SWSUP_MSTANDBY	BIT(13)
 #define SYSC_QUIRK_SWSUP_SIDLE_ACT	BIT(12)
 #define SYSC_QUIRK_SWSUP_SIDLE		BIT(11)
-- 
2.21.0

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 04/13] bus: ti-sysc: Allow QUIRK_LEGACY_IDLE even if legacy_mode is not set
  2019-05-28  6:24 [PATCHv2 00/13] ti-sysc driver changes to drop custom hwmods property Tony Lindgren
                   ` (2 preceding siblings ...)
  2019-05-28  6:24 ` [PATCH 03/13] bus: ti-sysc: Make OCP reset work for sysstatus and sysconfig reset bits Tony Lindgren
@ 2019-05-28  6:24 ` Tony Lindgren
  2019-05-28  6:24 ` [PATCH 05/13] bus: ti-sysc: Enable interconnect target module autoidle bit on enable Tony Lindgren
                   ` (9 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Tony Lindgren @ 2019-05-28  6:24 UTC (permalink / raw)
  To: linux-omap
  Cc: Dave Gerlach, Faiz Abbas, Greg Kroah-Hartman, Keerthy,
	Nishanth Menon, Peter Ujfalusi, Roger Quadros, Suman Anna,
	Tero Kristo, linux-kernel, linux-arm-kernel, Rob Herring,
	devicetree

We need to specify QUIRK_LEGACY_IDLE for device drivers that still have
pm_runtime_irq_safe() set like 8250.

Signed-off-by: Tony Lindgren <tony@atomide.com>
---
 drivers/bus/ti-sysc.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c
--- a/drivers/bus/ti-sysc.c
+++ b/drivers/bus/ti-sysc.c
@@ -1779,9 +1779,6 @@ static struct dev_pm_domain sysc_child_pm_domain = {
  */
 static void sysc_legacy_idle_quirk(struct sysc *ddata, struct device *child)
 {
-	if (!ddata->legacy_mode)
-		return;
-
 	if (ddata->cfg.quirks & SYSC_QUIRK_LEGACY_IDLE)
 		dev_pm_domain_set(child, &sysc_child_pm_domain);
 }
-- 
2.21.0

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 05/13] bus: ti-sysc: Enable interconnect target module autoidle bit on enable
  2019-05-28  6:24 [PATCHv2 00/13] ti-sysc driver changes to drop custom hwmods property Tony Lindgren
                   ` (3 preceding siblings ...)
  2019-05-28  6:24 ` [PATCH 04/13] bus: ti-sysc: Allow QUIRK_LEGACY_IDLE even if legacy_mode is not set Tony Lindgren
@ 2019-05-28  6:24 ` Tony Lindgren
  2019-05-28  6:24 ` [PATCH 06/13] bus: ti-sysc: Handle clockactivity for enable and disable Tony Lindgren
                   ` (8 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Tony Lindgren @ 2019-05-28  6:24 UTC (permalink / raw)
  To: linux-omap
  Cc: Dave Gerlach, Faiz Abbas, Greg Kroah-Hartman, Keerthy,
	Nishanth Menon, Peter Ujfalusi, Roger Quadros, Suman Anna,
	Tero Kristo, linux-kernel, linux-arm-kernel, Rob Herring,
	devicetree

For interconnect target modules with autoidle bit wired, we need to manage
it for enable and disable.

Signed-off-by: Tony Lindgren <tony@atomide.com>
---
 drivers/bus/ti-sysc.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c
--- a/drivers/bus/ti-sysc.c
+++ b/drivers/bus/ti-sysc.c
@@ -879,7 +879,7 @@ static int sysc_enable_module(struct device *dev)
 	/* Set MIDLE mode */
 	idlemodes = ddata->cfg.midlemodes;
 	if (!idlemodes || regbits->midle_shift < 0)
-		return 0;
+		goto set_autoidle;
 
 	best_mode = fls(ddata->cfg.midlemodes) - 1;
 	if (best_mode > SYSC_IDLE_MASK) {
@@ -891,6 +891,14 @@ static int sysc_enable_module(struct device *dev)
 	reg |= best_mode << regbits->midle_shift;
 	sysc_write(ddata, ddata->offsets[SYSC_SYSCONFIG], reg);
 
+set_autoidle:
+	/* Autoidle bit must enabled separately if available */
+	if (regbits->autoidle_shift >= 0 &&
+	    ddata->cfg.sysc_val & BIT(regbits->autoidle_shift)) {
+		reg |= 1 << regbits->autoidle_shift;
+		sysc_write(ddata, ddata->offsets[SYSC_SYSCONFIG], reg);
+	}
+
 	return 0;
 }
 
@@ -952,6 +960,9 @@ static int sysc_disable_module(struct device *dev)
 
 	reg &= ~(SYSC_IDLE_MASK << regbits->sidle_shift);
 	reg |= best_mode << regbits->sidle_shift;
+	if (regbits->autoidle_shift >= 0 &&
+	    ddata->cfg.sysc_val & BIT(regbits->autoidle_shift))
+		reg |= 1 << regbits->autoidle_shift;
 	sysc_write(ddata, ddata->offsets[SYSC_SYSCONFIG], reg);
 
 	return 0;
-- 
2.21.0

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 06/13] bus: ti-sysc: Handle clockactivity for enable and disable
  2019-05-28  6:24 [PATCHv2 00/13] ti-sysc driver changes to drop custom hwmods property Tony Lindgren
                   ` (4 preceding siblings ...)
  2019-05-28  6:24 ` [PATCH 05/13] bus: ti-sysc: Enable interconnect target module autoidle bit on enable Tony Lindgren
@ 2019-05-28  6:24 ` Tony Lindgren
  2019-05-28  6:24 ` [PATCH 07/13] bus: ti-sysc: Handle swsup idle mode quirks Tony Lindgren
                   ` (7 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Tony Lindgren @ 2019-05-28  6:24 UTC (permalink / raw)
  To: linux-omap
  Cc: Dave Gerlach, Faiz Abbas, Greg Kroah-Hartman, Keerthy,
	Nishanth Menon, Peter Ujfalusi, Roger Quadros, Suman Anna,
	Tero Kristo, linux-kernel, linux-arm-kernel, Rob Herring,
	devicetree

Modules with clockactivity need it configured during enable.

Signed-off-by: Tony Lindgren <tony@atomide.com>
---
 drivers/bus/ti-sysc.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c
--- a/drivers/bus/ti-sysc.c
+++ b/drivers/bus/ti-sysc.c
@@ -845,6 +845,7 @@ static void sysc_show_registers(struct sysc *ddata)
 }
 
 #define SYSC_IDLE_MASK	(SYSC_NR_IDLEMODES - 1)
+#define SYSC_CLOCACT_ICK	2
 
 /* Caller needs to manage sysc_clkdm_deny_idle() and sysc_clkdm_allow_idle() */
 static int sysc_enable_module(struct device *dev)
@@ -860,6 +861,12 @@ static int sysc_enable_module(struct device *dev)
 	regbits = ddata->cap->regbits;
 	reg = sysc_read(ddata, ddata->offsets[SYSC_SYSCONFIG]);
 
+	/* Set CLOCKACTIVITY, we only use it for ick */
+	if (regbits->clkact_shift >= 0 &&
+	    (ddata->cfg.quirks & SYSC_QUIRK_USE_CLOCKACT ||
+	     ddata->cfg.sysc_val & BIT(regbits->clkact_shift)))
+		reg |= SYSC_CLOCACT_ICK << regbits->clkact_shift;
+
 	/* Set SIDLE mode */
 	idlemodes = ddata->cfg.sidlemodes;
 	if (!idlemodes || regbits->sidle_shift < 0)
-- 
2.21.0

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 07/13] bus: ti-sysc: Handle swsup idle mode quirks
  2019-05-28  6:24 [PATCHv2 00/13] ti-sysc driver changes to drop custom hwmods property Tony Lindgren
                   ` (5 preceding siblings ...)
  2019-05-28  6:24 ` [PATCH 06/13] bus: ti-sysc: Handle clockactivity for enable and disable Tony Lindgren
@ 2019-05-28  6:24 ` Tony Lindgren
  2019-05-28  6:24 ` [PATCH 08/13] bus: ti-sysc: Set ENAWAKEUP if available Tony Lindgren
                   ` (6 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Tony Lindgren @ 2019-05-28  6:24 UTC (permalink / raw)
  To: linux-omap
  Cc: Dave Gerlach, Faiz Abbas, Greg Kroah-Hartman, Keerthy,
	Nishanth Menon, Peter Ujfalusi, Roger Quadros, Suman Anna,
	Tero Kristo, linux-kernel, linux-arm-kernel, Rob Herring,
	devicetree

Some modules have idlemodes wired, but not completely functional. We have
quirks for SWSUP_SIDLE and SWSUP_SIDLE_ACT to manage interconnect target
modules without hardware support, but we've been only using them so far
in legacy mode. Let's add support for SWSUP quirks in non-legacy mode too.

Signed-off-by: Tony Lindgren <tony@atomide.com>
---
 drivers/bus/ti-sysc.c | 25 +++++++++++++++++--------
 1 file changed, 17 insertions(+), 8 deletions(-)

diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c
--- a/drivers/bus/ti-sysc.c
+++ b/drivers/bus/ti-sysc.c
@@ -872,10 +872,15 @@ static int sysc_enable_module(struct device *dev)
 	if (!idlemodes || regbits->sidle_shift < 0)
 		goto set_midle;
 
-	best_mode = fls(ddata->cfg.sidlemodes) - 1;
-	if (best_mode > SYSC_IDLE_MASK) {
-		dev_err(dev, "%s: invalid sidlemode\n", __func__);
-		return -EINVAL;
+	if (ddata->cfg.quirks & (SYSC_QUIRK_SWSUP_SIDLE |
+				 SYSC_QUIRK_SWSUP_SIDLE_ACT)) {
+		best_mode = SYSC_IDLE_NO;
+	} else {
+		best_mode = fls(ddata->cfg.sidlemodes) - 1;
+		if (best_mode > SYSC_IDLE_MASK) {
+			dev_err(dev, "%s: invalid sidlemode\n", __func__);
+			return -EINVAL;
+		}
 	}
 
 	reg &= ~(SYSC_IDLE_MASK << regbits->sidle_shift);
@@ -959,10 +964,14 @@ static int sysc_disable_module(struct device *dev)
 	if (!idlemodes || regbits->sidle_shift < 0)
 		return 0;
 
-	ret = sysc_best_idle_mode(idlemodes, &best_mode);
-	if (ret) {
-		dev_err(dev, "%s: invalid sidlemode\n", __func__);
-		return ret;
+	if (ddata->cfg.quirks & SYSC_QUIRK_SWSUP_SIDLE) {
+		best_mode = SYSC_IDLE_FORCE;
+	} else {
+		ret = sysc_best_idle_mode(idlemodes, &best_mode);
+		if (ret) {
+			dev_err(dev, "%s: invalid sidlemode\n", __func__);
+			return ret;
+		}
 	}
 
 	reg &= ~(SYSC_IDLE_MASK << regbits->sidle_shift);
-- 
2.21.0

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 08/13] bus: ti-sysc: Set ENAWAKEUP if available
  2019-05-28  6:24 [PATCHv2 00/13] ti-sysc driver changes to drop custom hwmods property Tony Lindgren
                   ` (6 preceding siblings ...)
  2019-05-28  6:24 ` [PATCH 07/13] bus: ti-sysc: Handle swsup idle mode quirks Tony Lindgren
@ 2019-05-28  6:24 ` Tony Lindgren
  2019-05-28  6:24 ` [PATCH 09/13] bus: ti-sysc: Add support for disabling module without legacy mode Tony Lindgren
                   ` (5 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Tony Lindgren @ 2019-05-28  6:24 UTC (permalink / raw)
  To: linux-omap
  Cc: Dave Gerlach, Faiz Abbas, Greg Kroah-Hartman, Keerthy,
	Nishanth Menon, Peter Ujfalusi, Roger Quadros, Suman Anna,
	Tero Kristo, linux-kernel, linux-arm-kernel, Rob Herring,
	devicetree

Some modules have ENAWAKEUP bit that we need to configure when not
relying on platform data callbacks.

Signed-off-by: Tony Lindgren <tony@atomide.com>
---
 drivers/bus/ti-sysc.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c
--- a/drivers/bus/ti-sysc.c
+++ b/drivers/bus/ti-sysc.c
@@ -881,6 +881,11 @@ static int sysc_enable_module(struct device *dev)
 			dev_err(dev, "%s: invalid sidlemode\n", __func__);
 			return -EINVAL;
 		}
+
+		/* Set WAKEUP */
+		if (regbits->enwkup_shift >= 0 &&
+		    ddata->cfg.sysc_val & BIT(regbits->enwkup_shift))
+			reg |= BIT(regbits->enwkup_shift);
 	}
 
 	reg &= ~(SYSC_IDLE_MASK << regbits->sidle_shift);
-- 
2.21.0

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 09/13] bus: ti-sysc: Add support for disabling module without legacy mode
  2019-05-28  6:24 [PATCHv2 00/13] ti-sysc driver changes to drop custom hwmods property Tony Lindgren
                   ` (7 preceding siblings ...)
  2019-05-28  6:24 ` [PATCH 08/13] bus: ti-sysc: Set ENAWAKEUP if available Tony Lindgren
@ 2019-05-28  6:24 ` Tony Lindgren
  2019-05-28  6:24 ` [PATCH 10/13] bus: ti-sysc: Do rstctrl reset handling in two phases Tony Lindgren
                   ` (4 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Tony Lindgren @ 2019-05-28  6:24 UTC (permalink / raw)
  To: linux-omap
  Cc: Dave Gerlach, Faiz Abbas, Greg Kroah-Hartman, Keerthy,
	Nishanth Menon, Peter Ujfalusi, Roger Quadros, Suman Anna,
	Tero Kristo, linux-kernel, linux-arm-kernel, Rob Herring,
	devicetree

We must not assert reset for modules with no child device drivers
until in runtime_suspend. Otherwise register access will fail without
legacy mode helping us.

Let's add a flag for disable_on_idle and move the reset driver
handling to runtime suspend and resume. We can then also use the
disable_on_idle flag to reconfigure sysconfig register for PM
modes requesting it.

Let's also make the other flags use bitfield while at it instead of
bool.

Signed-off-by: Tony Lindgren <tony@atomide.com>
---
 drivers/bus/ti-sysc.c | 21 +++++++++++++++++----
 1 file changed, 17 insertions(+), 4 deletions(-)

diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c
--- a/drivers/bus/ti-sysc.c
+++ b/drivers/bus/ti-sysc.c
@@ -89,9 +89,10 @@ struct sysc {
 	struct ti_sysc_cookie cookie;
 	const char *name;
 	u32 revision;
-	bool enabled;
-	bool needs_resume;
-	bool child_needs_resume;
+	unsigned int enabled:1;
+	unsigned int needs_resume:1;
+	unsigned int child_needs_resume:1;
+	unsigned int disable_on_idle:1;
 	struct delayed_work idle_work;
 };
 
@@ -1007,6 +1008,9 @@ static int __maybe_unused sysc_runtime_suspend_legacy(struct device *dev,
 		dev_err(dev, "%s: could not idle: %i\n",
 			__func__, error);
 
+	if (ddata->disable_on_idle)
+		reset_control_assert(ddata->rsts);
+
 	return 0;
 }
 
@@ -1016,6 +1020,9 @@ static int __maybe_unused sysc_runtime_resume_legacy(struct device *dev,
 	struct ti_sysc_platform_data *pdata;
 	int error;
 
+	if (ddata->disable_on_idle)
+		reset_control_deassert(ddata->rsts);
+
 	pdata = dev_get_platdata(ddata->dev);
 	if (!pdata)
 		return 0;
@@ -1063,6 +1070,9 @@ static int __maybe_unused sysc_runtime_suspend(struct device *dev)
 err_allow_idle:
 	sysc_clkdm_allow_idle(ddata);
 
+	if (ddata->disable_on_idle)
+		reset_control_assert(ddata->rsts);
+
 	return error;
 }
 
@@ -1076,6 +1086,9 @@ static int __maybe_unused sysc_runtime_resume(struct device *dev)
 	if (ddata->enabled)
 		return 0;
 
+	if (ddata->disable_on_idle)
+		reset_control_deassert(ddata->rsts);
+
 	sysc_clkdm_deny_idle(ddata);
 
 	if (sysc_opt_clks_needed(ddata)) {
@@ -2293,7 +2306,7 @@ static int sysc_probe(struct platform_device *pdev)
 	}
 
 	if (!of_get_available_child_count(ddata->dev->of_node))
-		reset_control_assert(ddata->rsts);
+		ddata->disable_on_idle = true;
 
 	return 0;
 
-- 
2.21.0

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 10/13] bus: ti-sysc: Do rstctrl reset handling in two phases
  2019-05-28  6:24 [PATCHv2 00/13] ti-sysc driver changes to drop custom hwmods property Tony Lindgren
                   ` (8 preceding siblings ...)
  2019-05-28  6:24 ` [PATCH 09/13] bus: ti-sysc: Add support for disabling module without legacy mode Tony Lindgren
@ 2019-05-28  6:24 ` Tony Lindgren
  2019-05-28  6:24 ` [PATCH 11/13] bus: ti-sysc: Detect uarts also on omap34xx Tony Lindgren
                   ` (3 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Tony Lindgren @ 2019-05-28  6:24 UTC (permalink / raw)
  To: linux-omap
  Cc: Dave Gerlach, Faiz Abbas, Greg Kroah-Hartman, Keerthy,
	Nishanth Menon, Peter Ujfalusi, Roger Quadros, Suman Anna,
	Tero Kristo, linux-kernel, linux-arm-kernel, Rob Herring,
	devicetree

We need to deassert rstctrl resets before enabling clocks to avoid clock
"failed to enable" errors. For asserting rstctrl reset, the clocks need
to be enabled.

As the reset controller status is not available for arrays, let's use
devm_reset_control_get_optional() so we can get the status after reset.

Note that depends on a proper PRM rstctrl driver, so far I've only
tested this with earlier reset-simple patches.

Signed-off-by: Tony Lindgren <tony@atomide.com>
---
 drivers/bus/ti-sysc.c | 25 +++++++++++++++++--------
 1 file changed, 17 insertions(+), 8 deletions(-)

diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c
--- a/drivers/bus/ti-sysc.c
+++ b/drivers/bus/ti-sysc.c
@@ -483,7 +483,7 @@ static void sysc_clkdm_allow_idle(struct sysc *ddata)
 static int sysc_init_resets(struct sysc *ddata)
 {
 	ddata->rsts =
-		devm_reset_control_array_get_optional_exclusive(ddata->dev);
+		devm_reset_control_get_optional(ddata->dev, "rstctrl");
 	if (IS_ERR(ddata->rsts))
 		return PTR_ERR(ddata->rsts);
 
@@ -1407,7 +1407,7 @@ static int sysc_legacy_init(struct sysc *ddata)
  */
 static int sysc_rstctrl_reset_deassert(struct sysc *ddata, bool reset)
 {
-	int error;
+	int error, val;
 
 	if (!ddata->rsts)
 		return 0;
@@ -1418,7 +1418,14 @@ static int sysc_rstctrl_reset_deassert(struct sysc *ddata, bool reset)
 			return error;
 	}
 
-	return reset_control_deassert(ddata->rsts);
+	error = reset_control_deassert(ddata->rsts);
+	if (error == -EEXIST)
+		return 0;
+
+	error = readx_poll_timeout(reset_control_status, ddata->rsts, val,
+				   val == 0, 100, MAX_MODULE_SOFTRESET_WAIT);
+
+	return error;
 }
 
 /*
@@ -1476,12 +1483,8 @@ static int sysc_init_module(struct sysc *ddata)
 {
 	int error = 0;
 	bool manage_clocks = true;
-	bool reset = true;
 
-	if (ddata->cfg.quirks & SYSC_QUIRK_NO_RESET_ON_INIT)
-		reset = false;
-
-	error = sysc_rstctrl_reset_deassert(ddata, reset);
+	error = sysc_rstctrl_reset_deassert(ddata, false);
 	if (error)
 		return error;
 
@@ -1505,6 +1508,12 @@ static int sysc_init_module(struct sysc *ddata)
 			goto err_opt_clocks;
 	}
 
+	if (!(ddata->cfg.quirks & SYSC_QUIRK_NO_RESET_ON_INIT)) {
+		error = sysc_rstctrl_reset_deassert(ddata, true);
+		if (error)
+			goto err_main_clocks;
+	}
+
 	ddata->revision = sysc_read_revision(ddata);
 	sysc_init_revision_quirks(ddata);
 
-- 
2.21.0

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 11/13] bus: ti-sysc: Detect uarts also on omap34xx
  2019-05-28  6:24 [PATCHv2 00/13] ti-sysc driver changes to drop custom hwmods property Tony Lindgren
                   ` (9 preceding siblings ...)
  2019-05-28  6:24 ` [PATCH 10/13] bus: ti-sysc: Do rstctrl reset handling in two phases Tony Lindgren
@ 2019-05-28  6:24 ` Tony Lindgren
  2019-05-28  6:24 ` [PATCH 12/13] ARM: dts: Drop legacy custom hwmods property for omap4 uart Tony Lindgren
                   ` (2 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Tony Lindgren @ 2019-05-28  6:24 UTC (permalink / raw)
  To: linux-omap
  Cc: Dave Gerlach, Faiz Abbas, Greg Kroah-Hartman, Keerthy,
	Nishanth Menon, Peter Ujfalusi, Roger Quadros, Suman Anna,
	Tero Kristo, linux-kernel, linux-arm-kernel, Rob Herring,
	devicetree

Looks like we currently only detect UART on omap36xx, let's also
add support for omap34xx. And let's also fix the SWSUP mode, it should
be SWSUP_SIDLE for omap3, not SWSUP_SIDLE_ACT like for omap4 and later.

Note that we are still booting omap3 for most part without ti-sysc,
so no need to treat this change as a fix.

Signed-off-by: Tony Lindgren <tony@atomide.com>
---
 drivers/bus/ti-sysc.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c
--- a/drivers/bus/ti-sysc.c
+++ b/drivers/bus/ti-sysc.c
@@ -1205,8 +1205,10 @@ static const struct sysc_revision_quirk sysc_revision_quirks[] = {
 		   0),
 	SYSC_QUIRK("timer", 0, 0, 0x10, -1, 0x4fff1301, 0xffff00ff,
 		   0),
+	SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x00000046, 0xffffffff,
+		   SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_LEGACY_IDLE),
 	SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x00000052, 0xffffffff,
-		   SYSC_QUIRK_SWSUP_SIDLE_ACT | SYSC_QUIRK_LEGACY_IDLE),
+		   SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_LEGACY_IDLE),
 	/* Uarts on omap4 and later */
 	SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x50411e03, 0xffff00ff,
 		   SYSC_QUIRK_SWSUP_SIDLE_ACT | SYSC_QUIRK_LEGACY_IDLE),
-- 
2.21.0

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 12/13] ARM: dts: Drop legacy custom hwmods property for omap4 uart
  2019-05-28  6:24 [PATCHv2 00/13] ti-sysc driver changes to drop custom hwmods property Tony Lindgren
                   ` (10 preceding siblings ...)
  2019-05-28  6:24 ` [PATCH 11/13] bus: ti-sysc: Detect uarts also on omap34xx Tony Lindgren
@ 2019-05-28  6:24 ` Tony Lindgren
  2019-05-28  6:24 ` [PATCH 13/13] ARM: dts: Drop legacy custom hwmods property for omap4 mmc Tony Lindgren
  2019-05-28  8:02 ` [PATCHv2 00/13] ti-sysc driver changes to drop custom hwmods property Keerthy
  13 siblings, 0 replies; 15+ messages in thread
From: Tony Lindgren @ 2019-05-28  6:24 UTC (permalink / raw)
  To: linux-omap
  Cc: Dave Gerlach, Faiz Abbas, Greg Kroah-Hartman, Keerthy,
	Nishanth Menon, Peter Ujfalusi, Roger Quadros, Suman Anna,
	Tero Kristo, linux-kernel, linux-arm-kernel, devicetree,
	Rob Herring

With recent ti-sysc driver changes, we can now finally probe most
modules without needing the custom ti,hwmods property.

Let's start with omap4 uart as we can test that for runtime PM
for core retention idle mode.

Cc: devicetree@vger.kernel.org
Cc: Rob Herring <robh@kernel.org>
Signed-off-by: Tony Lindgren <tony@atomide.com>
---
 arch/arm/boot/dts/omap4-l4.dtsi | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/arch/arm/boot/dts/omap4-l4.dtsi b/arch/arm/boot/dts/omap4-l4.dtsi
--- a/arch/arm/boot/dts/omap4-l4.dtsi
+++ b/arch/arm/boot/dts/omap4-l4.dtsi
@@ -1371,7 +1371,6 @@
 
 		target-module@20000 {			/* 0x48020000, ap 3 06.0 */
 			compatible = "ti,sysc-omap2", "ti,sysc";
-			ti,hwmods = "uart3";
 			reg = <0x20050 0x4>,
 			      <0x20054 0x4>,
 			      <0x20058 0x4>;
@@ -1728,7 +1727,6 @@
 
 		target-module@6a000 {			/* 0x4806a000, ap 26 18.0 */
 			compatible = "ti,sysc-omap2", "ti,sysc";
-			ti,hwmods = "uart1";
 			reg = <0x6a050 0x4>,
 			      <0x6a054 0x4>,
 			      <0x6a058 0x4>;
@@ -1758,7 +1756,6 @@
 
 		target-module@6c000 {			/* 0x4806c000, ap 28 20.0 */
 			compatible = "ti,sysc-omap2", "ti,sysc";
-			ti,hwmods = "uart2";
 			reg = <0x6c050 0x4>,
 			      <0x6c054 0x4>,
 			      <0x6c058 0x4>;
@@ -1788,7 +1785,6 @@
 
 		target-module@6e000 {			/* 0x4806e000, ap 30 1c.1 */
 			compatible = "ti,sysc-omap2", "ti,sysc";
-			ti,hwmods = "uart4";
 			reg = <0x6e050 0x4>,
 			      <0x6e054 0x4>,
 			      <0x6e058 0x4>;
-- 
2.21.0

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 13/13] ARM: dts: Drop legacy custom hwmods property for omap4 mmc
  2019-05-28  6:24 [PATCHv2 00/13] ti-sysc driver changes to drop custom hwmods property Tony Lindgren
                   ` (11 preceding siblings ...)
  2019-05-28  6:24 ` [PATCH 12/13] ARM: dts: Drop legacy custom hwmods property for omap4 uart Tony Lindgren
@ 2019-05-28  6:24 ` Tony Lindgren
  2019-05-28  8:02 ` [PATCHv2 00/13] ti-sysc driver changes to drop custom hwmods property Keerthy
  13 siblings, 0 replies; 15+ messages in thread
From: Tony Lindgren @ 2019-05-28  6:24 UTC (permalink / raw)
  To: linux-omap
  Cc: Dave Gerlach, Faiz Abbas, Greg Kroah-Hartman, Keerthy,
	Nishanth Menon, Peter Ujfalusi, Roger Quadros, Suman Anna,
	Tero Kristo, linux-kernel, linux-arm-kernel, devicetree,
	Rob Herring

With recent ti-sysc driver changes, we can now finally probe most
modules without needing the custom ti,hwmods property.

Let's drop it for omap4 MMC as we can test that for runtime PM
for core retention idle mode for wlcore WLAN.

Cc: devicetree@vger.kernel.org
Cc: Rob Herring <robh@kernel.org>
Signed-off-by: Tony Lindgren <tony@atomide.com>
---
 arch/arm/boot/dts/omap4-l4.dtsi | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/arch/arm/boot/dts/omap4-l4.dtsi b/arch/arm/boot/dts/omap4-l4.dtsi
--- a/arch/arm/boot/dts/omap4-l4.dtsi
+++ b/arch/arm/boot/dts/omap4-l4.dtsi
@@ -2103,7 +2103,6 @@
 
 		target-module@9c000 {			/* 0x4809c000, ap 53 36.0 */
 			compatible = "ti,sysc-omap4", "ti,sysc";
-			ti,hwmods = "mmc1";
 			reg = <0x9c000 0x4>,
 			      <0x9c010 0x4>;
 			reg-names = "rev", "sysc";
@@ -2171,7 +2170,6 @@
 
 		target-module@ad000 {			/* 0x480ad000, ap 63 50.0 */
 			compatible = "ti,sysc-omap4", "ti,sysc";
-			ti,hwmods = "mmc3";
 			reg = <0xad000 0x4>,
 			      <0xad010 0x4>;
 			reg-names = "rev", "sysc";
@@ -2237,7 +2235,6 @@
 
 		target-module@b4000 {			/* 0x480b4000, ap 67 46.0 */
 			compatible = "ti,sysc-omap4", "ti,sysc";
-			ti,hwmods = "mmc2";
 			reg = <0xb4000 0x4>,
 			      <0xb4010 0x4>;
 			reg-names = "rev", "sysc";
@@ -2332,7 +2329,6 @@
 
 		target-module@d1000 {			/* 0x480d1000, ap 73 44.0 */
 			compatible = "ti,sysc-omap4", "ti,sysc";
-			ti,hwmods = "mmc4";
 			reg = <0xd1000 0x4>,
 			      <0xd1010 0x4>;
 			reg-names = "rev", "sysc";
@@ -2365,7 +2361,6 @@
 
 		target-module@d5000 {			/* 0x480d5000, ap 75 4e.0 */
 			compatible = "ti,sysc-omap4", "ti,sysc";
-			ti,hwmods = "mmc5";
 			reg = <0xd5000 0x4>,
 			      <0xd5010 0x4>;
 			reg-names = "rev", "sysc";
-- 
2.21.0

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCHv2 00/13] ti-sysc driver changes to drop custom hwmods property
  2019-05-28  6:24 [PATCHv2 00/13] ti-sysc driver changes to drop custom hwmods property Tony Lindgren
                   ` (12 preceding siblings ...)
  2019-05-28  6:24 ` [PATCH 13/13] ARM: dts: Drop legacy custom hwmods property for omap4 mmc Tony Lindgren
@ 2019-05-28  8:02 ` Keerthy
  13 siblings, 0 replies; 15+ messages in thread
From: Keerthy @ 2019-05-28  8:02 UTC (permalink / raw)
  To: Tony Lindgren, linux-omap
  Cc: Dave Gerlach, Faiz Abbas, Greg Kroah-Hartman, Nishanth Menon,
	Peter Ujfalusi, Roger Quadros, Suman Anna, Tero Kristo,
	linux-kernel, linux-arm-kernel, Rob Herring, devicetree



On 28/05/19 11:54 AM, Tony Lindgren wrote:
> Hi all,
> 
> Here are changes to improve ti-sysc driver to the point where we can
> finally drop the custom hwmods property for most cases. This series
> drops hwmods property only for omap4 UART and MMC as those can be
> tested with core retention idle.
> 
> I'll be posting more patches for dropping hwmods properties as they
> get tested.


Added missing dra71/76 patches on linux-next which get them to boot.

Tested for boot on dra71/76.
Tested for DS0 on AM43/33.
Tested for RTC+DDR mode on am43.

For the series:

Tested-by: Keerthy <j-keerthy@ti.com>

> 
> Regards,
> 
> Tony
> 
> Changes since v1:
> 
> - Repost the series against v5.2-rc1 as the first patch in the series
>    got accidentally left out for patch "bus: ti-sysc: Add support for
>    missing clockdomain handling"
> 
> 
> Tony Lindgren (13):
>    bus: ti-sysc: Add support for missing clockdomain handling
>    bus: ti-sysc: Support 16-bit writes too
>    bus: ti-sysc: Make OCP reset work for sysstatus and sysconfig reset
>      bits
>    bus: ti-sysc: Allow QUIRK_LEGACY_IDLE even if legacy_mode is not set
>    bus: ti-sysc: Enable interconnect target module autoidle bit on enable
>    bus: ti-sysc: Handle clockactivity for enable and disable
>    bus: ti-sysc: Handle swsup idle mode quirks
>    bus: ti-sysc: Set ENAWAKEUP if available
>    bus: ti-sysc: Add support for disabling module without legacy mode
>    bus: ti-sysc: Do rstctrl reset handling in two phases
>    bus: ti-sysc: Detect uarts also on omap34xx
>    ARM: dts: Drop legacy custom hwmods property for omap4 uart
>    ARM: dts: Drop legacy custom hwmods property for omap4 mmc
> 
>   arch/arm/boot/dts/omap4-l4.dtsi       |   9 -
>   arch/arm/mach-omap2/omap_hwmod.c      |  39 +---
>   arch/arm/mach-omap2/pdata-quirks.c    |  60 +++++
>   drivers/bus/ti-sysc.c                 | 309 ++++++++++++++++++++------
>   include/linux/platform_data/ti-sysc.h |   9 +
>   5 files changed, 314 insertions(+), 112 deletions(-)
> 

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2019-05-28  8:01 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-05-28  6:24 [PATCHv2 00/13] ti-sysc driver changes to drop custom hwmods property Tony Lindgren
2019-05-28  6:24 ` [PATCH 01/13] bus: ti-sysc: Add support for missing clockdomain handling Tony Lindgren
2019-05-28  6:24 ` [PATCH 02/13] bus: ti-sysc: Support 16-bit writes too Tony Lindgren
2019-05-28  6:24 ` [PATCH 03/13] bus: ti-sysc: Make OCP reset work for sysstatus and sysconfig reset bits Tony Lindgren
2019-05-28  6:24 ` [PATCH 04/13] bus: ti-sysc: Allow QUIRK_LEGACY_IDLE even if legacy_mode is not set Tony Lindgren
2019-05-28  6:24 ` [PATCH 05/13] bus: ti-sysc: Enable interconnect target module autoidle bit on enable Tony Lindgren
2019-05-28  6:24 ` [PATCH 06/13] bus: ti-sysc: Handle clockactivity for enable and disable Tony Lindgren
2019-05-28  6:24 ` [PATCH 07/13] bus: ti-sysc: Handle swsup idle mode quirks Tony Lindgren
2019-05-28  6:24 ` [PATCH 08/13] bus: ti-sysc: Set ENAWAKEUP if available Tony Lindgren
2019-05-28  6:24 ` [PATCH 09/13] bus: ti-sysc: Add support for disabling module without legacy mode Tony Lindgren
2019-05-28  6:24 ` [PATCH 10/13] bus: ti-sysc: Do rstctrl reset handling in two phases Tony Lindgren
2019-05-28  6:24 ` [PATCH 11/13] bus: ti-sysc: Detect uarts also on omap34xx Tony Lindgren
2019-05-28  6:24 ` [PATCH 12/13] ARM: dts: Drop legacy custom hwmods property for omap4 uart Tony Lindgren
2019-05-28  6:24 ` [PATCH 13/13] ARM: dts: Drop legacy custom hwmods property for omap4 mmc Tony Lindgren
2019-05-28  8:02 ` [PATCHv2 00/13] ti-sysc driver changes to drop custom hwmods property Keerthy

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).