]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
Merge tag 'omap-for-v5.5/ti-sysc-signed' of git://git.kernel.org/pub/scm/linux/kernel...
authorOlof Johansson <olof@lixom.net>
Wed, 23 Oct 2019 20:18:23 +0000 (13:18 -0700)
committerOlof Johansson <olof@lixom.net>
Wed, 23 Oct 2019 20:18:24 +0000 (13:18 -0700)
Changes for ti-sysc interconnect target module driver for v5.5

A series of changes from Tero Kristo for rpm reset control
driver to deal with the ordering requirements between clocks
and resets, and two changes to deal with quirks for musb otg
device.

* tag 'omap-for-v5.5/ti-sysc-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap:
  bus: ti-sysc: Use swsup quirks also for am335x musb
  bus: ti-sysc: Handle mstandby quirk and use it for musb
  bus: ti-sysc: Fix watchdog quirk handling
  bus: ti-sysc: avoid toggling power state of module during probe
  bus: ti-sysc: drop the extra hardreset during init
  bus: ti-sysc: re-order reset and main clock controls

Link: https://lore.kernel.org/r/pull-1571853258-16998@atomide.com-2
Signed-off-by: Olof Johansson <olof@lixom.net>
drivers/bus/ti-sysc.c

index ad50efb470aaa296bdc9cae1ba7a3ea321ddcf1c..97b85493aa43949e9ef7c6e8adc0ac98aa150c6e 100644 (file)
@@ -74,6 +74,7 @@ static const char * const clock_names[SYSC_MAX_CLOCKS] = {
  * @clk_disable_quirk: module specific clock disable quirk
  * @reset_done_quirk: module specific reset done quirk
  * @module_enable_quirk: module specific enable quirk
+ * @module_disable_quirk: module specific disable quirk
  */
 struct sysc {
        struct device *dev;
@@ -100,6 +101,7 @@ struct sysc {
        void (*clk_disable_quirk)(struct sysc *sysc);
        void (*reset_done_quirk)(struct sysc *sysc);
        void (*module_enable_quirk)(struct sysc *sysc);
+       void (*module_disable_quirk)(struct sysc *sysc);
 };
 
 static void sysc_parse_dts_quirks(struct sysc *ddata, struct device_node *np,
@@ -915,6 +917,9 @@ static int sysc_enable_module(struct device *dev)
                return -EINVAL;
        }
 
+       if (ddata->cfg.quirks & SYSC_QUIRK_SWSUP_MSTANDBY)
+               best_mode = SYSC_IDLE_NO;
+
        reg &= ~(SYSC_IDLE_MASK << regbits->midle_shift);
        reg |= best_mode << regbits->midle_shift;
        sysc_write(ddata, ddata->offsets[SYSC_SYSCONFIG], reg);
@@ -959,6 +964,9 @@ static int sysc_disable_module(struct device *dev)
        if (ddata->offsets[SYSC_SYSCONFIG] == -ENODEV)
                return 0;
 
+       if (ddata->module_disable_quirk)
+               ddata->module_disable_quirk(ddata);
+
        regbits = ddata->cap->regbits;
        reg = sysc_read(ddata, ddata->offsets[SYSC_SYSCONFIG]);
 
@@ -973,6 +981,9 @@ static int sysc_disable_module(struct device *dev)
                return ret;
        }
 
+       if (ddata->cfg.quirks & SYSC_QUIRK_SWSUP_MSTANDBY)
+               best_mode = SYSC_IDLE_FORCE;
+
        reg &= ~(SYSC_IDLE_MASK << regbits->midle_shift);
        reg |= best_mode << regbits->midle_shift;
        sysc_write(ddata, ddata->offsets[SYSC_SYSCONFIG], reg);
@@ -1032,8 +1043,6 @@ static int __maybe_unused sysc_runtime_resume_legacy(struct device *dev,
        struct ti_sysc_platform_data *pdata;
        int error;
 
-       reset_control_deassert(ddata->rsts);
-
        pdata = dev_get_platdata(ddata->dev);
        if (!pdata)
                return 0;
@@ -1046,6 +1055,8 @@ static int __maybe_unused sysc_runtime_resume_legacy(struct device *dev,
                dev_err(dev, "%s: could not enable: %i\n",
                        __func__, error);
 
+       reset_control_deassert(ddata->rsts);
+
        return 0;
 }
 
@@ -1099,8 +1110,6 @@ static int __maybe_unused sysc_runtime_resume(struct device *dev)
 
        sysc_clkdm_deny_idle(ddata);
 
-       reset_control_deassert(ddata->rsts);
-
        if (sysc_opt_clks_needed(ddata)) {
                error = sysc_enable_opt_clocks(ddata);
                if (error)
@@ -1111,6 +1120,8 @@ static int __maybe_unused sysc_runtime_resume(struct device *dev)
        if (error)
                goto err_opt_clocks;
 
+       reset_control_deassert(ddata->rsts);
+
        if (ddata->legacy_mode) {
                error = sysc_runtime_resume_legacy(dev, ddata);
                if (error)
@@ -1246,8 +1257,15 @@ static const struct sysc_revision_quirk sysc_revision_quirks[] = {
        SYSC_QUIRK("gpu", 0x50000000, 0x14, -1, -1, 0x00010201, 0xffffffff, 0),
        SYSC_QUIRK("gpu", 0x50000000, 0xfe00, 0xfe10, -1, 0x40000000 , 0xffffffff,
                   SYSC_MODULE_QUIRK_SGX),
+       SYSC_QUIRK("usb_otg_hs", 0, 0x400, 0x404, 0x408, 0x00000050,
+                  0xffffffff, SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_SWSUP_MSTANDBY),
+       SYSC_QUIRK("usb_otg_hs", 0, 0, 0x10, -1, 0x4ea2080d, 0xffffffff,
+                  SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_SWSUP_MSTANDBY),
        SYSC_QUIRK("wdt", 0, 0, 0x10, 0x14, 0x502a0500, 0xfffff0f0,
                   SYSC_MODULE_QUIRK_WDT),
+       /* Watchdog on am3 and am4 */
+       SYSC_QUIRK("wdt", 0x44e35000, 0, 0x10, 0x14, 0x502a0500, 0xfffff0f0,
+                  SYSC_MODULE_QUIRK_WDT | SYSC_QUIRK_SWSUP_SIDLE),
 
 #ifdef DEBUG
        SYSC_QUIRK("adc", 0, 0, 0x10, -1, 0x47300001, 0xffffffff, 0),
@@ -1301,8 +1319,6 @@ static const struct sysc_revision_quirk sysc_revision_quirks[] = {
        SYSC_QUIRK("usbhstll", 0, 0, 0x10, 0x14, 0x00000008, 0xffffffff, 0),
        SYSC_QUIRK("usb_host_hs", 0, 0, 0x10, 0x14, 0x50700100, 0xffffffff, 0),
        SYSC_QUIRK("usb_host_hs", 0, 0, 0x10, -1, 0x50700101, 0xffffffff, 0),
-       SYSC_QUIRK("usb_otg_hs", 0, 0x400, 0x404, 0x408, 0x00000050,
-                  0xffffffff, 0),
        SYSC_QUIRK("vfpe", 0, 0, 0x104, -1, 0x4d001200, 0xffffffff, 0),
 #endif
 };
@@ -1440,14 +1456,14 @@ static void sysc_reset_done_quirk_wdt(struct sysc *ddata)
                                   !(val & 0x10), 100,
                                   MAX_MODULE_SOFTRESET_WAIT);
        if (error)
-               dev_warn(ddata->dev, "wdt disable spr failed\n");
+               dev_warn(ddata->dev, "wdt disable step1 failed\n");
 
-       sysc_write(ddata, wps, 0x5555);
+       sysc_write(ddata, spr, 0x5555);
        error = readl_poll_timeout(ddata->module_va + wps, val,
                                   !(val & 0x10), 100,
                                   MAX_MODULE_SOFTRESET_WAIT);
        if (error)
-               dev_warn(ddata->dev, "wdt disable wps failed\n");
+               dev_warn(ddata->dev, "wdt disable step2 failed\n");
 }
 
 static void sysc_init_module_quirks(struct sysc *ddata)
@@ -1471,8 +1487,10 @@ static void sysc_init_module_quirks(struct sysc *ddata)
        if (ddata->cfg.quirks & SYSC_MODULE_QUIRK_SGX)
                ddata->module_enable_quirk = sysc_module_enable_quirk_sgx;
 
-       if (ddata->cfg.quirks & SYSC_MODULE_QUIRK_WDT)
+       if (ddata->cfg.quirks & SYSC_MODULE_QUIRK_WDT) {
                ddata->reset_done_quirk = sysc_reset_done_quirk_wdt;
+               ddata->module_disable_quirk = sysc_reset_done_quirk_wdt;
+       }
 }
 
 static int sysc_clockdomain_init(struct sysc *ddata)
@@ -1522,37 +1540,6 @@ static int sysc_legacy_init(struct sysc *ddata)
        return error;
 }
 
-/**
- * sysc_rstctrl_reset_deassert - deassert rstctrl reset
- * @ddata: device driver data
- * @reset: reset before deassert
- *
- * A module can have both OCP softreset control and external rstctrl.
- * If more complicated rstctrl resets are needed, please handle these
- * directly from the child device driver and map only the module reset
- * for the parent interconnect target module device.
- *
- * Automatic reset of the module on init can be skipped with the
- * "ti,no-reset-on-init" device tree property.
- */
-static int sysc_rstctrl_reset_deassert(struct sysc *ddata, bool reset)
-{
-       int error;
-
-       if (!ddata->rsts)
-               return 0;
-
-       if (reset) {
-               error = reset_control_assert(ddata->rsts);
-               if (error)
-                       return error;
-       }
-
-       reset_control_deassert(ddata->rsts);
-
-       return 0;
-}
-
 /*
  * Note that the caller must ensure the interconnect target module is enabled
  * before calling reset. Otherwise reset will not complete.
@@ -1615,15 +1602,6 @@ static int sysc_reset(struct sysc *ddata)
 static int sysc_init_module(struct sysc *ddata)
 {
        int error = 0;
-       bool manage_clocks = true;
-
-       error = sysc_rstctrl_reset_deassert(ddata, false);
-       if (error)
-               return error;
-
-       if (ddata->cfg.quirks &
-           (SYSC_QUIRK_NO_IDLE | SYSC_QUIRK_NO_IDLE_ON_INIT))
-               manage_clocks = false;
 
        error = sysc_clockdomain_init(ddata);
        if (error)
@@ -1644,7 +1622,7 @@ 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);
+               error = reset_control_deassert(ddata->rsts);
                if (error)
                        goto err_main_clocks;
        }
@@ -1656,28 +1634,32 @@ static int sysc_init_module(struct sysc *ddata)
        if (ddata->legacy_mode) {
                error = sysc_legacy_init(ddata);
                if (error)
-                       goto err_main_clocks;
+                       goto err_reset;
        }
 
        if (!ddata->legacy_mode) {
                error = sysc_enable_module(ddata->dev);
                if (error)
-                       goto err_main_clocks;
+                       goto err_reset;
        }
 
        error = sysc_reset(ddata);
        if (error)
                dev_err(ddata->dev, "Reset failed with %d\n", error);
 
-       if (!ddata->legacy_mode && manage_clocks)
+       if (error && !ddata->legacy_mode)
                sysc_disable_module(ddata->dev);
 
+err_reset:
+       if (error && !(ddata->cfg.quirks & SYSC_QUIRK_NO_RESET_ON_INIT))
+               reset_control_assert(ddata->rsts);
+
 err_main_clocks:
-       if (manage_clocks)
+       if (error)
                sysc_disable_main_clocks(ddata);
 err_opt_clocks:
        /* No re-enable of clockdomain autoidle to prevent module autoidle */
-       if (manage_clocks) {
+       if (error) {
                sysc_disable_opt_clocks(ddata);
                sysc_clkdm_allow_idle(ddata);
        }
@@ -2450,10 +2432,17 @@ static int sysc_probe(struct platform_device *pdev)
                goto unprepare;
        }
 
-       /* Balance reset counts */
-       if (ddata->rsts)
+       /* Balance use counts as PM runtime should have enabled these all */
+       if (!(ddata->cfg.quirks & SYSC_QUIRK_NO_RESET_ON_INIT))
                reset_control_assert(ddata->rsts);
 
+       if (!(ddata->cfg.quirks &
+             (SYSC_QUIRK_NO_IDLE | SYSC_QUIRK_NO_IDLE_ON_INIT))) {
+               sysc_disable_main_clocks(ddata);
+               sysc_disable_opt_clocks(ddata);
+               sysc_clkdm_allow_idle(ddata);
+       }
+
        sysc_show_registers(ddata);
 
        ddata->dev->type = &sysc_device_type;