diff mbox

[v4,4/6] bus: ti-sysc: Add support for software reset

Message ID 20180705142319.19583-5-faiz_abbas@ti.com (mailing list archive)
State New, archived
Headers show

Commit Message

Faiz Abbas July 5, 2018, 2:23 p.m. UTC
Add support for the software reset of a target interconnect
module using its sysconfig and sysstatus registers.

Signed-off-by: Faiz Abbas <faiz_abbas@ti.com>
---
 drivers/bus/ti-sysc.c | 39 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 39 insertions(+)

Comments

Tony Lindgren July 5, 2018, 3:47 p.m. UTC | #1
* Faiz Abbas <faiz_abbas@ti.com> [180705 14:24]:
> +static int sysc_reset(struct sysc *ddata)
> +{
> +	int offset = ddata->offsets[SYSC_SYSCONFIG];
> +	int val = sysc_read(ddata, offset);

Can you please just warn and return early for now if no
syss_mask is specified? Otherwise we'll have mysterious
errors if somebody leaves out "ti,hwmods" for module types
we do not yet support reset for.

> +	val |= (0x1 << ddata->cap->regbits->srst_shift);
> +	sysc_write(ddata, offset, val);
> +
> +	/* Poll on reset status */
> +	if (ddata->cfg.syss_mask) {
> +		offset = ddata->offsets[SYSC_SYSSTATUS];
> +
> +		return readl_poll_timeout(ddata->module_va + offset, val,
> +				(val & ddata->cfg.syss_mask) == 0x0,
> +				100, MAX_MODULE_SOFTRESET_WAIT);
> +	}
> +
> +	return 0;
> +}
> +

Otherwise looks good to me.

Thanks,

Tony
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Faiz Abbas July 6, 2018, 10:04 a.m. UTC | #2
Hi,

On Thursday 05 July 2018 09:17 PM, Tony Lindgren wrote:
> * Faiz Abbas <faiz_abbas@ti.com> [180705 14:24]:
>> +static int sysc_reset(struct sysc *ddata)
>> +{
>> +	int offset = ddata->offsets[SYSC_SYSCONFIG];
>> +	int val = sysc_read(ddata, offset);
> 
> Can you please just warn and return early for now if no
> syss_mask is specified? Otherwise we'll have mysterious
> errors if somebody leaves out "ti,hwmods" for module types
> we do not yet support reset for.

RESET write to sysconfig can still happen even if there's no syss_mask
right? Not all modules need to poll on reset status.

Thanks,
Faiz
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Tony Lindgren July 6, 2018, 10:35 a.m. UTC | #3
* Faiz Abbas <faiz_abbas@ti.com> [180706 10:05]:
> Hi,
> 
> On Thursday 05 July 2018 09:17 PM, Tony Lindgren wrote:
> > * Faiz Abbas <faiz_abbas@ti.com> [180705 14:24]:
> >> +static int sysc_reset(struct sysc *ddata)
> >> +{
> >> +	int offset = ddata->offsets[SYSC_SYSCONFIG];
> >> +	int val = sysc_read(ddata, offset);
> > 
> > Can you please just warn and return early for now if no
> > syss_mask is specified? Otherwise we'll have mysterious
> > errors if somebody leaves out "ti,hwmods" for module types
> > we do not yet support reset for.
> 
> RESET write to sysconfig can still happen even if there's no syss_mask
> right? Not all modules need to poll on reset status.

It can but we currently don't have anything similar to
srst_udelay like we have in _ocp_softreset(). And we don't
currently have suport for sysc reset done bit.

So we want to warn and return error except in the known
working case for now.

Regards,

Tony
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Faiz Abbas July 6, 2018, 12:35 p.m. UTC | #4
Hi,

On Friday 06 July 2018 04:05 PM, Tony Lindgren wrote:
> * Faiz Abbas <faiz_abbas@ti.com> [180706 10:05]:
>> Hi,
>>
>> On Thursday 05 July 2018 09:17 PM, Tony Lindgren wrote:
>>> * Faiz Abbas <faiz_abbas@ti.com> [180705 14:24]:
>>>> +static int sysc_reset(struct sysc *ddata)
>>>> +{
>>>> +	int offset = ddata->offsets[SYSC_SYSCONFIG];
>>>> +	int val = sysc_read(ddata, offset);
>>>
>>> Can you please just warn and return early for now if no
>>> syss_mask is specified? Otherwise we'll have mysterious
>>> errors if somebody leaves out "ti,hwmods" for module types
>>> we do not yet support reset for.
>>
>> RESET write to sysconfig can still happen even if there's no syss_mask
>> right? Not all modules need to poll on reset status.
> 
> It can but we currently don't have anything similar to
> srst_udelay like we have in _ocp_softreset(). And we don't
> currently have suport for sysc reset done bit.
> 
> So we want to warn and return error except in the known
> working case for now.
> 

Ok.

Thanks,
Faiz
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c
index ad1cd6888757..ac65a4f336d5 100644
--- a/drivers/bus/ti-sysc.c
+++ b/drivers/bus/ti-sysc.c
@@ -23,11 +23,14 @@ 
 #include <linux/of_address.h>
 #include <linux/of_platform.h>
 #include <linux/slab.h>
+#include <linux/iopoll.h>
 
 #include <linux/platform_data/ti-sysc.h>
 
 #include <dt-bindings/bus/ti-sysc.h>
 
+#define MAX_MODULE_SOFTRESET_WAIT		10000
+
 static const char * const reg_names[] = { "rev", "sysc", "syss", };
 
 enum sysc_clocks {
@@ -88,6 +91,11 @@  struct sysc {
 	struct delayed_work idle_work;
 };
 
+void sysc_write(struct sysc *ddata, int offset, u32 value)
+{
+	writel_relaxed(value, ddata->module_va + offset);
+}
+
 static u32 sysc_read(struct sysc *ddata, int offset)
 {
 	if (ddata->cfg.quirks & SYSC_QUIRK_16BIT) {
@@ -943,6 +951,26 @@  static void sysc_init_revision_quirks(struct sysc *ddata)
 	}
 }
 
+static int sysc_reset(struct sysc *ddata)
+{
+	int offset = ddata->offsets[SYSC_SYSCONFIG];
+	int val = sysc_read(ddata, offset);
+
+	val |= (0x1 << ddata->cap->regbits->srst_shift);
+	sysc_write(ddata, offset, val);
+
+	/* Poll on reset status */
+	if (ddata->cfg.syss_mask) {
+		offset = ddata->offsets[SYSC_SYSSTATUS];
+
+		return readl_poll_timeout(ddata->module_va + offset, val,
+				(val & ddata->cfg.syss_mask) == 0x0,
+				100, MAX_MODULE_SOFTRESET_WAIT);
+	}
+
+	return 0;
+}
+
 /* At this point the module is configured enough to read the revision */
 static int sysc_init_module(struct sysc *ddata)
 {
@@ -960,6 +988,17 @@  static int sysc_init_module(struct sysc *ddata)
 		return 0;
 	}
 
+	if (!(ddata->cfg.quirks & SYSC_QUIRK_NO_RESET_ON_INIT) &&
+	    !ddata->legacy_mode) {
+		error = sysc_reset(ddata);
+		if (error) {
+			dev_err(ddata->dev, "Reset failed with %d\n", error);
+			pm_runtime_put_sync(ddata->dev);
+
+			return error;
+		}
+	}
+
 	ddata->revision = sysc_read_revision(ddata);
 	pm_runtime_put_sync(ddata->dev);