Merge tag 'armsoc-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 30 Sep 2019 17:04:28 +0000 (10:04 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 30 Sep 2019 17:04:28 +0000 (10:04 -0700)
Pull ARM SoC fixes from Olof Johansson:
 "A few fixes that have trickled in through the merge window:

   - Video fixes for OMAP due to panel-dpi driver removal

   - Clock fixes for OMAP that broke no-idle quirks + nfsroot on DRA7

   - Fixing arch version on ASpeed ast2500

   - Two fixes for reset handling on ARM SCMI"

* tag 'armsoc-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc:
  ARM: aspeed: ast2500 is ARMv6K
  reset: reset-scmi: add missing handle initialisation
  firmware: arm_scmi: reset: fix reset_state assignment in scmi_domain_reset
  bus: ti-sysc: Remove unpaired sysc_clkdm_deny_idle()
  ARM: dts: logicpd-som-lv: Fix i2c2 and i2c3 Pin mux
  ARM: dts: am3517-evm: Fix missing video
  ARM: dts: logicpd-torpedo-baseboard: Fix missing video
  ARM: omap2plus_defconfig: Fix missing video
  bus: ti-sysc: Fix handling of invalid clocks
  bus: ti-sysc: Fix clock handling for no-idle quirks

1  2 
arch/arm/mach-aspeed/Kconfig
drivers/bus/ti-sysc.c

index 56007b0b6120d626cc2c2deb0e63067dd521439b,44ee6bac255e6fa4b5e43f75b7e3403fe6a16b94..e8d6e9957d65b717548c1ffeec7a5666232b7c8b
@@@ -1,10 -1,11 +1,10 @@@
  # SPDX-License-Identifier: GPL-2.0-only
  menuconfig ARCH_ASPEED
        bool "Aspeed BMC architectures"
 -      depends on ARCH_MULTI_V5 || ARCH_MULTI_V6
 +      depends on ARCH_MULTI_V5 || ARCH_MULTI_V6 || ARCH_MULTI_V7
        select SRAM
        select WATCHDOG
        select ASPEED_WATCHDOG
 -      select FTTMR010_TIMER
        select MFD_SYSCON
        select PINCTRL
        help
@@@ -17,7 -18,6 +17,7 @@@ config MACH_ASPEED_G
        depends on ARCH_MULTI_V5
        select CPU_ARM926T
        select PINCTRL_ASPEED_G4
 +      select FTTMR010_TIMER
        help
         Say yes if you intend to run on an Aspeed ast2400 or similar
         fourth generation BMCs, such as those used by OpenPower Power8
  config MACH_ASPEED_G5
        bool "Aspeed SoC 5th Generation"
        depends on ARCH_MULTI_V6
-       select CPU_V6
        select PINCTRL_ASPEED_G5
 +      select FTTMR010_TIMER
        help
         Say yes if you intend to run on an Aspeed ast2500 or similar
         fifth generation Aspeed BMCs.
  
 +config MACH_ASPEED_G6
 +      bool "Aspeed SoC 6th Generation"
 +      depends on ARCH_MULTI_V7
 +      select CPU_V7
 +      select PINCTRL_ASPEED_G6
 +      select ARM_GIC
 +      select HAVE_ARM_ARCH_TIMER
 +      select HAVE_SMP
 +      help
 +       Say yes if you intend to run on an Aspeed ast2600 or similar
 +       sixth generation Aspeed BMCs.
 +
  endif
diff --combined drivers/bus/ti-sysc.c
index 9207ac2913412e9da29daa41222930442fd37673,364ee498feb348adf1b55a0e45ad220a98abd4bf..ad50efb470aaa296bdc9cae1ba7a3ea321ddcf1c
@@@ -1,6 -1,14 +1,6 @@@
 +// SPDX-License-Identifier: GPL-2.0
  /*
   * ti-sysc.c - Texas Instruments sysc interconnect target driver
 - *
 - * This program is free software; you can redistribute it and/or modify
 - * it under the terms of the GNU General Public License version 2 as
 - * published by the Free Software Foundation.
 - *
 - * This program is distributed "as is" WITHOUT ANY WARRANTY of any
 - * kind, whether express or implied; without even the implied warranty
 - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 - * GNU General Public License for more details.
   */
  
  #include <linux/io.h>
@@@ -54,26 -62,18 +54,26 @@@ static const char * const clock_names[S
   * @module_size: size of the interconnect target module
   * @module_va: virtual address of the interconnect target module
   * @offsets: register offsets from module base
 + * @mdata: ti-sysc to hwmod translation data for a module
   * @clocks: clocks used by the interconnect target module
   * @clock_roles: clock role names for the found clocks
   * @nr_clocks: number of clocks used by the interconnect target module
 + * @rsts: resets used by the interconnect target module
   * @legacy_mode: configured for legacy mode if set
   * @cap: interconnect target module capabilities
   * @cfg: interconnect target module configuration
 + * @cookie: data used by legacy platform callbacks
   * @name: name if available
   * @revision: interconnect target module revision
 + * @enabled: sysc runtime enabled status
   * @needs_resume: runtime resume needed on resume from suspend
 + * @child_needs_resume: runtime resume needed for child on resume from suspend
 + * @disable_on_idle: status flag used for disabling modules with resets
 + * @idle_work: work structure used to perform delayed idle on a module
   * @clk_enable_quirk: module specific clock enable quirk
   * @clk_disable_quirk: module specific clock disable quirk
   * @reset_done_quirk: module specific reset done quirk
 + * @module_enable_quirk: module specific enable quirk
   */
  struct sysc {
        struct device *dev;
        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;
        void (*clk_enable_quirk)(struct sysc *sysc);
        void (*clk_disable_quirk)(struct sysc *sysc);
        void (*reset_done_quirk)(struct sysc *sysc);
 +      void (*module_enable_quirk)(struct sysc *sysc);
  };
  
  static void sysc_parse_dts_quirks(struct sysc *ddata, struct device_node *np,
@@@ -280,9 -280,6 +280,6 @@@ static int sysc_get_one_clock(struct sy
  
        ddata->clocks[index] = devm_clk_get(ddata->dev, name);
        if (IS_ERR(ddata->clocks[index])) {
-               if (PTR_ERR(ddata->clocks[index]) == -ENOENT)
-                       return 0;
                dev_err(ddata->dev, "clock get error for %s: %li\n",
                        name, PTR_ERR(ddata->clocks[index]));
  
@@@ -357,7 -354,7 +354,7 @@@ static int sysc_get_clocks(struct sysc 
                        continue;
  
                error = sysc_get_one_clock(ddata, name);
-               if (error && error != -ENOENT)
+               if (error)
                        return error;
        }
  
@@@ -503,7 -500,7 +500,7 @@@ static void sysc_clkdm_allow_idle(struc
  static int sysc_init_resets(struct sysc *ddata)
  {
        ddata->rsts =
 -              devm_reset_control_get_optional(ddata->dev, "rstctrl");
 +              devm_reset_control_get_optional_shared(ddata->dev, "rstctrl");
        if (IS_ERR(ddata->rsts))
                return PTR_ERR(ddata->rsts);
  
@@@ -615,8 -612,8 +612,8 @@@ static void sysc_check_quirk_stdout(str
   * node but children have "ti,hwmods". These belong to the interconnect
   * target node and are managed by this driver.
   */
 -static int sysc_check_one_child(struct sysc *ddata,
 -                              struct device_node *np)
 +static void sysc_check_one_child(struct sysc *ddata,
 +                               struct device_node *np)
  {
        const char *name;
  
  
        sysc_check_quirk_stdout(ddata, np);
        sysc_parse_dts_quirks(ddata, np, true);
 -
 -      return 0;
  }
  
 -static int sysc_check_children(struct sysc *ddata)
 +static void sysc_check_children(struct sysc *ddata)
  {
        struct device_node *child;
 -      int error;
 -
 -      for_each_child_of_node(ddata->dev->of_node, child) {
 -              error = sysc_check_one_child(ddata, child);
 -              if (error)
 -                      return error;
 -      }
  
 -      return 0;
 +      for_each_child_of_node(ddata->dev->of_node, child)
 +              sysc_check_one_child(ddata, child);
  }
  
  /*
@@@ -786,7 -791,9 +783,7 @@@ static int sysc_map_and_check_registers
        if (error)
                return error;
  
 -      error = sysc_check_children(ddata);
 -      if (error)
 -              return error;
 +      sysc_check_children(ddata);
  
        error = sysc_parse_registers(ddata);
        if (error)
@@@ -930,9 -937,6 +927,9 @@@ set_autoidle
                sysc_write(ddata, ddata->offsets[SYSC_SYSCONFIG], reg);
        }
  
 +      if (ddata->module_enable_quirk)
 +              ddata->module_enable_quirk(ddata);
 +
        return 0;
  }
  
@@@ -1024,7 -1028,8 +1021,7 @@@ static int __maybe_unused sysc_runtime_
                dev_err(dev, "%s: could not idle: %i\n",
                        __func__, error);
  
 -      if (ddata->disable_on_idle)
 -              reset_control_assert(ddata->rsts);
 +      reset_control_assert(ddata->rsts);
  
        return 0;
  }
@@@ -1035,7 -1040,8 +1032,7 @@@ static int __maybe_unused sysc_runtime_
        struct ti_sysc_platform_data *pdata;
        int error;
  
 -      if (ddata->disable_on_idle)
 -              reset_control_deassert(ddata->rsts);
 +      reset_control_deassert(ddata->rsts);
  
        pdata = dev_get_platdata(ddata->dev);
        if (!pdata)
@@@ -1082,9 -1088,10 +1079,9 @@@ static int __maybe_unused sysc_runtime_
        ddata->enabled = false;
  
  err_allow_idle:
 -      sysc_clkdm_allow_idle(ddata);
 +      reset_control_assert(ddata->rsts);
  
 -      if (ddata->disable_on_idle)
 -              reset_control_assert(ddata->rsts);
 +      sysc_clkdm_allow_idle(ddata);
  
        return error;
  }
@@@ -1099,11 -1106,11 +1096,11 @@@ static int __maybe_unused sysc_runtime_
        if (ddata->enabled)
                return 0;
  
 -      if (ddata->disable_on_idle)
 -              reset_control_deassert(ddata->rsts);
  
        sysc_clkdm_deny_idle(ddata);
  
 +      reset_control_deassert(ddata->rsts);
 +
        if (sysc_opt_clks_needed(ddata)) {
                error = sysc_enable_opt_clocks(ddata);
                if (error)
@@@ -1246,9 -1253,6 +1243,9 @@@ static const struct sysc_revision_quir
                   SYSC_MODULE_QUIRK_I2C),
        SYSC_QUIRK("i2c", 0, 0, 0x10, 0x90, 0x5040000a, 0xfffff0f0,
                   SYSC_MODULE_QUIRK_I2C),
 +      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("wdt", 0, 0, 0x10, 0x14, 0x502a0500, 0xfffff0f0,
                   SYSC_MODULE_QUIRK_WDT),
  
        SYSC_QUIRK("dcan", 0, 0x20, -1, -1, 0x4edb1902, 0xffffffff, 0),
        SYSC_QUIRK("dmic", 0, 0, 0x10, -1, 0x50010000, 0xffffffff, 0),
        SYSC_QUIRK("dwc3", 0, 0, 0x10, -1, 0x500a0200, 0xffffffff, 0),
 +      SYSC_QUIRK("d2d", 0x4a0b6000, 0, 0x10, 0x14, 0x00000010, 0xffffffff, 0),
 +      SYSC_QUIRK("d2d", 0x4a0cd000, 0, 0x10, 0x14, 0x00000010, 0xffffffff, 0),
        SYSC_QUIRK("epwmss", 0, 0, 0x4, -1, 0x47400001, 0xffffffff, 0),
        SYSC_QUIRK("gpu", 0, 0x1fc00, 0x1fc10, -1, 0, 0, 0),
 +      SYSC_QUIRK("gpu", 0, 0xfe00, 0xfe10, -1, 0x40000000 , 0xffffffff, 0),
        SYSC_QUIRK("hsi", 0, 0, 0x10, 0x14, 0x50043101, 0xffffffff, 0),
        SYSC_QUIRK("iss", 0, 0, 0x10, -1, 0x40000101, 0xffffffff, 0),
        SYSC_QUIRK("lcdc", 0, 0, 0x54, -1, 0x4f201000, 0xffffffff, 0),
@@@ -1420,15 -1421,6 +1417,15 @@@ static void sysc_clk_disable_quirk_i2c(
        sysc_clk_quirk_i2c(ddata, false);
  }
  
 +/* 36xx SGX needs a quirk for to bypass OCP IPG interrupt logic */
 +static void sysc_module_enable_quirk_sgx(struct sysc *ddata)
 +{
 +      int offset = 0xff08;    /* OCP_DEBUG_CONFIG */
 +      u32 val = BIT(31);      /* THALIA_INT_BYPASS */
 +
 +      sysc_write(ddata, offset, val);
 +}
 +
  /* Watchdog timer needs a disable sequence after reset */
  static void sysc_reset_done_quirk_wdt(struct sysc *ddata)
  {
@@@ -1471,9 -1463,6 +1468,9 @@@ static void sysc_init_module_quirks(str
                return;
        }
  
 +      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)
                ddata->reset_done_quirk = sysc_reset_done_quirk_wdt;
  }
@@@ -1540,7 -1529,7 +1537,7 @@@ static int sysc_legacy_init(struct sys
   */
  static int sysc_rstctrl_reset_deassert(struct sysc *ddata, bool reset)
  {
 -      int error, val;
 +      int error;
  
        if (!ddata->rsts)
                return 0;
                        return error;
        }
  
 -      error = reset_control_deassert(ddata->rsts);
 -      if (error == -EEXIST)
 -              return 0;
 +      reset_control_deassert(ddata->rsts);
  
 -      error = readx_poll_timeout(reset_control_status, ddata->rsts, val,
 -                                 val == 0, 100, MAX_MODULE_SOFTRESET_WAIT);
 -
 -      return error;
 +      return 0;
  }
  
  /*
   */
  static int sysc_reset(struct sysc *ddata)
  {
 -      int sysc_offset, syss_offset, sysc_val, rstval, quirks, error = 0;
 +      int sysc_offset, syss_offset, sysc_val, rstval, 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 || sysc_offset < 0 ||
            ddata->cap->regbits->srst_shift < 0 ||
@@@ -1632,17 -1627,19 +1629,19 @@@ static int sysc_init_module(struct sys
        if (error)
                return error;
  
-       if (manage_clocks) {
-               sysc_clkdm_deny_idle(ddata);
+       sysc_clkdm_deny_idle(ddata);
  
-               error = sysc_enable_opt_clocks(ddata);
-               if (error)
-                       return error;
+       /*
+        * Always enable clocks. The bootloader may or may not have enabled
+        * the related clocks.
+        */
+       error = sysc_enable_opt_clocks(ddata);
+       if (error)
+               return error;
  
-               error = sysc_enable_main_clocks(ddata);
-               if (error)
-                       goto err_opt_clocks;
-       }
+       error = sysc_enable_main_clocks(ddata);
+       if (error)
+               goto err_opt_clocks;
  
        if (!(ddata->cfg.quirks & SYSC_QUIRK_NO_RESET_ON_INIT)) {
                error = sysc_rstctrl_reset_deassert(ddata, true);
                        goto err_main_clocks;
        }
  
-       if (!ddata->legacy_mode && manage_clocks) {
+       if (!ddata->legacy_mode) {
                error = sysc_enable_module(ddata->dev);
                if (error)
                        goto err_main_clocks;
@@@ -1677,6 -1674,7 +1676,7 @@@ err_main_clocks
        if (manage_clocks)
                sysc_disable_main_clocks(ddata);
  err_opt_clocks:
+       /* No re-enable of clockdomain autoidle to prevent module autoidle */
        if (manage_clocks) {
                sysc_disable_opt_clocks(ddata);
                sysc_clkdm_allow_idle(ddata);
@@@ -2357,6 -2355,27 +2357,27 @@@ static void ti_sysc_idle(struct work_st
  
        ddata = container_of(work, struct sysc, idle_work.work);
  
+       /*
+        * One time decrement of clock usage counts if left on from init.
+        * Note that we disable opt clocks unconditionally in this case
+        * as they are enabled unconditionally during init without
+        * considering sysc_opt_clks_needed() at that point.
+        */
+       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);
+       }
+       /* Keep permanent PM runtime usage count for SYSC_QUIRK_NO_IDLE */
+       if (ddata->cfg.quirks & SYSC_QUIRK_NO_IDLE)
+               return;
+       /*
+        * Decrement PM runtime usage count for SYSC_QUIRK_NO_IDLE_ON_INIT
+        * and SYSC_QUIRK_NO_RESET_ON_INIT
+        */
        if (pm_runtime_active(ddata->dev))
                pm_runtime_put_sync(ddata->dev);
  }
@@@ -2429,10 -2448,6 +2450,10 @@@ static int sysc_probe(struct platform_d
                goto unprepare;
        }
  
 +      /* Balance reset counts */
 +      if (ddata->rsts)
 +              reset_control_assert(ddata->rsts);
 +
        sysc_show_registers(ddata);
  
        ddata->dev->type = &sysc_device_type;
        INIT_DELAYED_WORK(&ddata->idle_work, ti_sysc_idle);
  
        /* At least earlycon won't survive without deferred idle */
-       if (ddata->cfg.quirks & (SYSC_QUIRK_NO_IDLE_ON_INIT |
+       if (ddata->cfg.quirks & (SYSC_QUIRK_NO_IDLE |
+                                SYSC_QUIRK_NO_IDLE_ON_INIT |
                                 SYSC_QUIRK_NO_RESET_ON_INIT)) {
                schedule_delayed_work(&ddata->idle_work, 3000);
        } else {
                pm_runtime_put(&pdev->dev);
        }
  
 -      if (!of_get_available_child_count(ddata->dev->of_node))
 -              ddata->disable_on_idle = true;
 -
        return 0;
  
  err: