]> git.proxmox.com Git - mirror_ubuntu-focal-kernel.git/commitdiff
Merge branch 'next/drivers' into next/late
authorOlof Johansson <olof@lixom.net>
Fri, 4 Jan 2019 22:30:36 +0000 (14:30 -0800)
committerOlof Johansson <olof@lixom.net>
Fri, 4 Jan 2019 22:31:38 +0000 (14:31 -0800)
Merge in a few missing patches from the pull request (my copy of the
branch was behind the staged version in linux-next).

* next/drivers:
  memory: pl353: Add driver for arm pl353 static memory controller
  dt-bindings: memory: Add pl353 smc controller devicetree binding information
  firmware: qcom: scm: fix compilation error when disabled

Signed-off-by: Olof Johansson <olof@lixom.net>
79 files changed:
Documentation/devicetree/bindings/arm/freescale/fsl,scu.txt
Documentation/devicetree/bindings/bus/ti-sysc.txt
Documentation/devicetree/bindings/memory-controllers/pl353-smc.txt [new file with mode: 0644]
Documentation/devicetree/bindings/power/fsl,imx-gpcv2.txt
Documentation/devicetree/bindings/soc/amlogic/clk-measure.txt [new file with mode: 0644]
Documentation/devicetree/bindings/soc/qcom/qcom,smd-rpm.txt
Documentation/devicetree/bindings/soc/rockchip/power_domain.txt
Documentation/devicetree/bindings/sram/sunxi-sram.txt
arch/arm/mach-omap2/omap_hwmod.c
drivers/bus/brcmstb_gisb.c
drivers/bus/ti-sysc.c
drivers/dma/pxa_dma.c
drivers/firmware/imx/Kconfig
drivers/firmware/imx/Makefile
drivers/firmware/imx/scu-pd.c [new file with mode: 0644]
drivers/firmware/raspberrypi.c
drivers/firmware/tegra/bpmp-debugfs.c
drivers/firmware/tegra/bpmp.c
drivers/gpu/drm/msm/adreno/a6xx_gmu.c
drivers/memory/Kconfig
drivers/memory/Makefile
drivers/memory/omap-gpmc.c
drivers/memory/pl353-smc.c [new file with mode: 0644]
drivers/memory/tegra/Kconfig
drivers/memory/tegra/Makefile
drivers/memory/tegra/tegra20-emc.c [new file with mode: 0644]
drivers/soc/Makefile
drivers/soc/amlogic/Kconfig
drivers/soc/amlogic/Makefile
drivers/soc/amlogic/meson-clk-measure.c [new file with mode: 0644]
drivers/soc/atmel/soc.c
drivers/soc/atmel/soc.h
drivers/soc/bcm/brcmstb/common.c
drivers/soc/bcm/brcmstb/pm/pm-arm.c
drivers/soc/bcm/raspberrypi-power.c
drivers/soc/imx/Kconfig
drivers/soc/imx/Makefile
drivers/soc/imx/gpc.c
drivers/soc/imx/gpcv2.c
drivers/soc/mediatek/Kconfig
drivers/soc/mediatek/Makefile
drivers/soc/mediatek/mtk-cmdq-helper.c [new file with mode: 0644]
drivers/soc/qcom/Kconfig
drivers/soc/qcom/cmd-db.c
drivers/soc/qcom/llcc-slice.c
drivers/soc/qcom/qcom-geni-se.c
drivers/soc/qcom/qmi_interface.c
drivers/soc/qcom/smd-rpm.c
drivers/soc/renesas/r8a77965-sysc.c
drivers/soc/renesas/r8a77970-sysc.c
drivers/soc/renesas/r8a77980-sysc.c
drivers/soc/renesas/r8a77990-sysc.c
drivers/soc/renesas/rcar-sysc.c
drivers/soc/rockchip/pm_domains.c
drivers/soc/sunxi/sunxi_sram.c
drivers/soc/tegra/common.c
drivers/soc/tegra/pmc.c
drivers/soc/ti/wkup_m3_ipc.c
include/dt-bindings/firmware/imx/rsrc.h [new file with mode: 0644]
include/dt-bindings/power/imx8mq-power.h [new file with mode: 0644]
include/dt-bindings/power/r8a77970-sysc.h
include/dt-bindings/power/r8a77980-sysc.h
include/dt-bindings/power/raspberrypi-power.h
include/dt-bindings/power/rk3066-power.h [new file with mode: 0644]
include/dt-bindings/power/rk3188-power.h [new file with mode: 0644]
include/linux/dma/pxa-dma.h
include/linux/firmware/imx/sci.h
include/linux/firmware/imx/svc/pm.h [new file with mode: 0644]
include/linux/firmware/imx/types.h
include/linux/pl353-smc.h [new file with mode: 0644]
include/linux/qcom_scm.h
include/linux/soc/mediatek/mtk-cmdq.h [new file with mode: 0644]
include/linux/soc/qcom/qmi.h
include/soc/bcm2835/raspberrypi-firmware.h
include/soc/qcom/cmd-db.h
include/soc/tegra/bpmp-abi.h
include/soc/tegra/bpmp.h
include/soc/tegra/fuse.h
include/soc/tegra/pmc.h

index 46d0af1f0872913e905ac0d7ba40cbbdbcdbbbf6..c20f38e56544f3d2af1b394cfa92fb9826a93d97 100644 (file)
@@ -58,19 +58,11 @@ This binding for the SCU power domain providers uses the generic power
 domain binding[2].
 
 Required properties:
-- compatible:          Should be "fsl,scu-pd".
-- #address-cells:      Should be 1.
-- #size-cells:         Should be 0.
-
-Required properties for power domain sub nodes:
-- #power-domain-cells: Must be 0.
-
-Optional Properties:
-- reg:                 Resource ID of this power domain.
-                       No exist means uncontrollable by user.
+- compatible:          Should be "fsl,imx8qxp-scu-pd".
+- #power-domain-cells: Must be 1. Contains the Resource ID used by
+                       SCU commands.
                        See detailed Resource ID list from:
-                       include/dt-bindings/power/imx-rsrc.h
-- power-domains:       phandle pointing to the parent power domain.
+                       include/dt-bindings/firmware/imx/rsrc.h
 
 Clock bindings based on SCU Message Protocol
 ------------------------------------------------------------
@@ -152,22 +144,9 @@ firmware {
                        ...
                };
 
-               imx8qx-pm {
-                       compatible = "fsl,scu-pd";
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-
-                       pd_dma: dma-power-domain {
-                               #power-domain-cells = <0>;
-
-                               pd_dma_lpuart0: dma-lpuart0@57 {
-                                       reg = <SC_R_UART_0>;
-                                       #power-domain-cells = <0>;
-                                       power-domains = <&pd_dma>;
-                               };
-                               ...
-                       };
-                       ...
+               pd: imx8qx-pd {
+                       compatible = "fsl,imx8qxp-scu-pd";
+                       #power-domain-cells = <1>;
                };
        };
 };
@@ -179,5 +158,5 @@ serial@5a060000 {
        clocks = <&clk IMX8QXP_UART0_CLK>,
                 <&clk IMX8QXP_UART0_IPG_CLK>;
        clock-names = "per", "ipg";
-       power-domains = <&pd_dma_lpuart0>;
+       power-domains = <&pd IMX_SC_R_UART_0>;
 };
index 91dc2333af012771e915981ed5df8bb8800d8d5b..85a23f551f024ca3e2c4e8c12b6aa2093d146341 100644 (file)
@@ -35,6 +35,7 @@ Required standard properties:
                "ti,sysc-omap3-sham"
                "ti,sysc-omap-aes"
                "ti,sysc-mcasp"
+               "ti,sysc-dra7-mcasp"
                "ti,sysc-usb-host-fs"
                "ti,sysc-dra7-mcan"
 
diff --git a/Documentation/devicetree/bindings/memory-controllers/pl353-smc.txt b/Documentation/devicetree/bindings/memory-controllers/pl353-smc.txt
new file mode 100644 (file)
index 0000000..d56615f
--- /dev/null
@@ -0,0 +1,47 @@
+Device tree bindings for ARM PL353 static memory controller
+
+PL353 static memory controller supports two kinds of memory
+interfaces.i.e NAND and SRAM/NOR interfaces.
+The actual devices are instantiated from the child nodes of pl353 smc node.
+
+Required properties:
+- compatible           : Should be "arm,pl353-smc-r2p1", "arm,primecell".
+- reg                  : Controller registers map and length.
+- clock-names          : List of input clock names - "memclk", "apb_pclk"
+                         (See clock bindings for details).
+- clocks               : Clock phandles (see clock bindings for details).
+- address-cells                : Must be 2.
+- size-cells           : Must be 1.
+
+Child nodes:
+ For NAND the "arm,pl353-nand-r2p1" and for NOR the "cfi-flash" drivers are
+supported as child nodes.
+
+for NAND partition information please refer the below file
+Documentation/devicetree/bindings/mtd/partition.txt
+
+Example:
+       smcc: memory-controller@e000e000
+                       compatible = "arm,pl353-smc-r2p1", "arm,primecell";
+                       clock-names = "memclk", "apb_pclk";
+                       clocks = <&clkc 11>, <&clkc 44>;
+                       reg = <0xe000e000 0x1000>;
+                       #address-cells = <2>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x0 0xe1000000 0x1000000 //Nand CS Region
+                                 0x1 0x0 0xe2000000 0x2000000 //SRAM/NOR CS Region
+                                 0x2 0x0 0xe4000000 0x2000000>; //SRAM/NOR CS Region
+                       nand_0: flash@e1000000 {
+                               compatible = "arm,pl353-nand-r2p1"
+                               reg = <0 0 0x1000000>;
+                               (...)
+                       };
+                       nor0: flash@e2000000 {
+                               compatible = "cfi-flash";
+                               reg = <1 0 0x2000000>;
+                       };
+                       nor1: flash@e4000000 {
+                               compatible = "cfi-flash";
+                               reg = <2 0 0x2000000>;
+                       };
+       };
index 9acce75b29abd9615e8ad0f0d7714231353eab7e..7c947a996df1c4e2f22e2e90df29454098b1b5b7 100644 (file)
@@ -6,7 +6,9 @@ Control (PGC) for various power domains.
 
 Required properties:
 
-- compatible: Should be "fsl,imx7d-gpc"
+- compatible: Should be one of:
+       - "fsl,imx7d-gpc"
+       - "fsl,imx8mq-gpc"
 
 - reg: should be register base and length as documented in the
   datasheet
@@ -22,7 +24,8 @@ which, in turn, is expected to contain the following:
 Required properties:
 
 - reg: Power domain index. Valid values are defined in
-  include/dt-bindings/power/imx7-power.h
+  include/dt-bindings/power/imx7-power.h for fsl,imx7d-gpc and
+  include/dt-bindings/power/imx8m-power.h for fsl,imx8mq-gpc
 
 - #power-domain-cells: Should be 0
 
diff --git a/Documentation/devicetree/bindings/soc/amlogic/clk-measure.txt b/Documentation/devicetree/bindings/soc/amlogic/clk-measure.txt
new file mode 100644 (file)
index 0000000..205a54b
--- /dev/null
@@ -0,0 +1,18 @@
+Amlogic Internal Clock Measurer
+===============================
+
+The Amlogic SoCs contains an IP to measure the internal clocks.
+The precision is multiple of MHz, useful to debug the clock states.
+
+Required properties:
+- compatible: Shall contain one of the following :
+                       "amlogic,meson-gx-clk-measure" for GX SoCs
+                       "amlogic,meson8-clk-measure" for Meson8 SoCs
+                       "amlogic,meson8b-clk-measure" for Meson8b SoCs
+- reg: base address and size of the Clock Measurer register space.
+
+Example:
+       clock-measure@8758 {
+               compatible = "amlogic,meson-gx-clk-measure";
+               reg = <0x0 0x8758 0x0 0x10>;
+       };
index 89e1cb9212f6899a51851ee7488bd6b73cc24db6..ec95705ba692fbd7c93454d5392f49501246387d 100644 (file)
@@ -23,6 +23,7 @@ resources.
                    "qcom,rpm-msm8916"
                    "qcom,rpm-msm8974"
                    "qcom,rpm-msm8998"
+                   "qcom,rpm-qcs404"
 
 - qcom,smd-channels:
        Usage: required
index 5d49d0a2ff29df92201d62f1171eeaec5e5f9d22..8304eceb62e41f518d9019e30b46c8f1c93f3b75 100644 (file)
@@ -7,7 +7,9 @@ Required properties for power domain controller:
 - compatible: Should be one of the following.
        "rockchip,px30-power-controller" - for PX30 SoCs.
        "rockchip,rk3036-power-controller" - for RK3036 SoCs.
+       "rockchip,rk3066-power-controller" - for RK3066 SoCs.
        "rockchip,rk3128-power-controller" - for RK3128 SoCs.
+       "rockchip,rk3188-power-controller" - for RK3188 SoCs.
        "rockchip,rk3228-power-controller" - for RK3228 SoCs.
        "rockchip,rk3288-power-controller" - for RK3288 SoCs.
        "rockchip,rk3328-power-controller" - for RK3328 SoCs.
@@ -23,7 +25,9 @@ Required properties for power domain sub nodes:
 - reg: index of the power domain, should use macros in:
        "include/dt-bindings/power/px30-power.h" - for PX30 type power domain.
        "include/dt-bindings/power/rk3036-power.h" - for RK3036 type power domain.
+       "include/dt-bindings/power/rk3066-power.h" - for RK3066 type power domain.
        "include/dt-bindings/power/rk3128-power.h" - for RK3128 type power domain.
+       "include/dt-bindings/power/rk3188-power.h" - for RK3188 type power domain.
        "include/dt-bindings/power/rk3228-power.h" - for RK3228 type power domain.
        "include/dt-bindings/power/rk3288-power.h" - for RK3288 type power domain.
        "include/dt-bindings/power/rk3328-power.h" - for RK3328 type power domain.
index 62dd0748f0efc1a035f5516210925df1d9056ca1..ab5a70bb9a648830f92066cc4caccd4b0d433211 100644 (file)
@@ -18,7 +18,9 @@ Required properties:
     - "allwinner,sun8i-h3-system-control"
     - "allwinner,sun50i-a64-sram-controller" (deprecated)
     - "allwinner,sun50i-a64-system-control"
+    - "allwinner,sun50i-h5-system-control"
     - "allwinner,sun50i-h6-system-control", "allwinner,sun50i-a64-system-control"
+    - "allwinner,suniv-f1c100s-system-control", "allwinner,sun4i-a10-system-control"
 - reg : sram controller register offset + length
 
 SRAM nodes
@@ -54,10 +56,17 @@ The valid sections compatible for H3 are:
 
 The valid sections compatible for A64 are:
     - allwinner,sun50i-a64-sram-c
+    - allwinner,sun50i-a64-sram-c1, allwinner,sun4i-a10-sram-c1
+
+The valid sections compatible for H5 are:
+    - allwinner,sun50i-h5-sram-c1, allwinner,sun4i-a10-sram-c1
 
 The valid sections compatible for H6 are:
     - allwinner,sun50i-h6-sram-c, allwinner,sun50i-a64-sram-c
 
+The valid sections compatible for F1C100s are:
+    - allwinner,suniv-f1c100s-sram-d, allwinner,sun4i-a10-sram-d
+
 Devices using SRAM sections
 ---------------------------
 
index 083dcd9942ce5c8643f0f56a8731f722fa514f63..b506d5d9da82210dc347675a8b5cb42a6110b98a 100644 (file)
@@ -2345,6 +2345,17 @@ static int __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data,
        return 0;
 }
 
+static void __init parse_module_flags(struct omap_hwmod *oh,
+                                     struct device_node *np)
+{
+       if (of_find_property(np, "ti,no-reset-on-init", NULL))
+               oh->flags |= HWMOD_INIT_NO_RESET;
+       if (of_find_property(np, "ti,no-idle-on-init", NULL))
+               oh->flags |= HWMOD_INIT_NO_IDLE;
+       if (of_find_property(np, "ti,no-idle", NULL))
+               oh->flags |= HWMOD_NO_IDLE;
+}
+
 /**
  * _init - initialize internal data for the hwmod @oh
  * @oh: struct omap_hwmod *
@@ -2392,12 +2403,12 @@ static int __init _init(struct omap_hwmod *oh, void *data)
        }
 
        if (np) {
-               if (of_find_property(np, "ti,no-reset-on-init", NULL))
-                       oh->flags |= HWMOD_INIT_NO_RESET;
-               if (of_find_property(np, "ti,no-idle-on-init", NULL))
-                       oh->flags |= HWMOD_INIT_NO_IDLE;
-               if (of_find_property(np, "ti,no-idle", NULL))
-                       oh->flags |= HWMOD_NO_IDLE;
+               struct device_node *child;
+
+               parse_module_flags(oh, np);
+               child = of_get_next_child(np, NULL);
+               if (child)
+                       parse_module_flags(oh, child);
        }
 
        oh->_state = _HWMOD_STATE_INITIALIZED;
index 68ac3e93b600766fb1bf6eb308c23bc2d9097bd2..f58ff67e97ac966b8682f7f88f549a9d372827d5 100644 (file)
@@ -150,8 +150,7 @@ static ssize_t gisb_arb_get_timeout(struct device *dev,
                                    struct device_attribute *attr,
                                    char *buf)
 {
-       struct platform_device *pdev = to_platform_device(dev);
-       struct brcmstb_gisb_arb_device *gdev = platform_get_drvdata(pdev);
+       struct brcmstb_gisb_arb_device *gdev = dev_get_drvdata(dev);
        u32 timeout;
 
        mutex_lock(&gdev->lock);
@@ -165,8 +164,7 @@ static ssize_t gisb_arb_set_timeout(struct device *dev,
                                    struct device_attribute *attr,
                                    const char *buf, size_t count)
 {
-       struct platform_device *pdev = to_platform_device(dev);
-       struct brcmstb_gisb_arb_device *gdev = platform_get_drvdata(pdev);
+       struct brcmstb_gisb_arb_device *gdev = dev_get_drvdata(dev);
        int val, ret;
 
        ret = kstrtoint(buf, 10, &val);
@@ -418,8 +416,7 @@ static int __init brcmstb_gisb_arb_probe(struct platform_device *pdev)
 #ifdef CONFIG_PM_SLEEP
 static int brcmstb_gisb_arb_suspend(struct device *dev)
 {
-       struct platform_device *pdev = to_platform_device(dev);
-       struct brcmstb_gisb_arb_device *gdev = platform_get_drvdata(pdev);
+       struct brcmstb_gisb_arb_device *gdev = dev_get_drvdata(dev);
 
        gdev->saved_timeout = gisb_read(gdev, ARB_TIMER);
 
@@ -431,8 +428,7 @@ static int brcmstb_gisb_arb_suspend(struct device *dev)
  */
 static int brcmstb_gisb_arb_resume_noirq(struct device *dev)
 {
-       struct platform_device *pdev = to_platform_device(dev);
-       struct brcmstb_gisb_arb_device *gdev = platform_get_drvdata(pdev);
+       struct brcmstb_gisb_arb_device *gdev = dev_get_drvdata(dev);
 
        gisb_write(gdev, gdev->saved_timeout, ARB_TIMER);
 
index a3a2d39280d952e5c51d812a041f61916310c318..f94d33525771bace16dd6ffc3e5fc47e53a28602 100644 (file)
@@ -91,6 +91,9 @@ struct sysc {
        struct delayed_work idle_work;
 };
 
+static void sysc_parse_dts_quirks(struct sysc *ddata, struct device_node *np,
+                                 bool is_child);
+
 void sysc_write(struct sysc *ddata, int offset, u32 value)
 {
        writel_relaxed(value, ddata->module_va + offset);
@@ -214,8 +217,13 @@ static int sysc_get_clocks(struct sysc *ddata)
        if (!ddata->clocks)
                return -ENOMEM;
 
-       for (i = 0; i < ddata->nr_clocks; i++) {
-               error = sysc_get_one_clock(ddata, ddata->clock_roles[i]);
+       for (i = 0; i < SYSC_MAX_CLOCKS; i++) {
+               const char *name = ddata->clock_roles[i];
+
+               if (!name)
+                       continue;
+
+               error = sysc_get_one_clock(ddata, name);
                if (error && error != -ENOENT)
                        return error;
        }
@@ -374,6 +382,7 @@ static int sysc_check_one_child(struct sysc *ddata,
                dev_warn(ddata->dev, "really a child ti,hwmods property?");
 
        sysc_check_quirk_stdout(ddata, np);
+       sysc_parse_dts_quirks(ddata, np, true);
 
        return 0;
 }
@@ -815,6 +824,7 @@ static const struct sysc_revision_quirk sysc_revision_quirks[] = {
        SYSC_QUIRK("ocp2scp", 0, 0, 0x10, 0x14, 0x50060005, 0xfffffff0, 0),
        SYSC_QUIRK("ocp2scp", 0, 0, -1, -1, 0x50060007, 0xffffffff, 0),
        SYSC_QUIRK("padconf", 0, 0, 0x10, -1, 0x4fff0800, 0xffffffff, 0),
+       SYSC_QUIRK("padconf", 0, 0, -1, -1, 0x40001100, 0xffffffff, 0),
        SYSC_QUIRK("prcm", 0, 0, -1, -1, 0x40000100, 0xffffffff, 0),
        SYSC_QUIRK("prcm", 0, 0, -1, -1, 0x00004102, 0xffffffff, 0),
        SYSC_QUIRK("prcm", 0, 0, -1, -1, 0x40000400, 0xffffffff, 0),
@@ -833,7 +843,9 @@ static const struct sysc_revision_quirk sysc_revision_quirks[] = {
        SYSC_QUIRK("rtc", 0, 0x74, 0x78, -1, 0x4eb01908, 0xffff00f0, 0),
        SYSC_QUIRK("timer32k", 0, 0, 0x4, -1, 0x00000060, 0xffffffff, 0),
        SYSC_QUIRK("usbhstll", 0, 0, 0x10, 0x14, 0x00000004, 0xffffffff, 0),
+       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("wdt", 0, 0, 0x10, 0x14, 0x502a0500, 0xfffff0f0, 0),
@@ -1271,23 +1283,37 @@ static const struct sysc_dts_quirk sysc_dts_quirks[] = {
          .mask = SYSC_QUIRK_NO_RESET_ON_INIT, },
 };
 
-static int sysc_init_dts_quirks(struct sysc *ddata)
+static void sysc_parse_dts_quirks(struct sysc *ddata, struct device_node *np,
+                                 bool is_child)
 {
-       struct device_node *np = ddata->dev->of_node;
        const struct property *prop;
-       int i, len, error;
-       u32 val;
-
-       ddata->legacy_mode = of_get_property(np, "ti,hwmods", NULL);
+       int i, len;
 
        for (i = 0; i < ARRAY_SIZE(sysc_dts_quirks); i++) {
-               prop = of_get_property(np, sysc_dts_quirks[i].name, &len);
+               const char *name = sysc_dts_quirks[i].name;
+
+               prop = of_get_property(np, name, &len);
                if (!prop)
                        continue;
 
                ddata->cfg.quirks |= sysc_dts_quirks[i].mask;
+               if (is_child) {
+                       dev_warn(ddata->dev,
+                                "dts flag should be at module level for %s\n",
+                                name);
+               }
        }
+}
 
+static int sysc_init_dts_quirks(struct sysc *ddata)
+{
+       struct device_node *np = ddata->dev->of_node;
+       int error;
+       u32 val;
+
+       ddata->legacy_mode = of_get_property(np, "ti,hwmods", NULL);
+
+       sysc_parse_dts_quirks(ddata, np, false);
        error = of_property_read_u32(np, "ti,sysc-delay-us", &val);
        if (!error) {
                if (val > 255) {
@@ -1498,6 +1524,16 @@ static const struct sysc_regbits sysc_regbits_omap4_mcasp = {
 static const struct sysc_capabilities sysc_omap4_mcasp = {
        .type = TI_SYSC_OMAP4_MCASP,
        .regbits = &sysc_regbits_omap4_mcasp,
+       .mod_quirks = SYSC_QUIRK_OPT_CLKS_NEEDED,
+};
+
+/*
+ * McASP found on dra7 and later
+ */
+static const struct sysc_capabilities sysc_dra7_mcasp = {
+       .type = TI_SYSC_OMAP4_SIMPLE,
+       .regbits = &sysc_regbits_omap4_simple,
+       .mod_quirks = SYSC_QUIRK_OPT_CLKS_NEEDED,
 };
 
 /*
@@ -1726,6 +1762,7 @@ static const struct of_device_id sysc_match[] = {
        { .compatible = "ti,sysc-omap3-sham", .data = &sysc_omap3_sham, },
        { .compatible = "ti,sysc-omap-aes", .data = &sysc_omap3_aes, },
        { .compatible = "ti,sysc-mcasp", .data = &sysc_omap4_mcasp, },
+       { .compatible = "ti,sysc-dra7-mcasp", .data = &sysc_dra7_mcasp, },
        { .compatible = "ti,sysc-usb-host-fs",
          .data = &sysc_omap4_usb_host_fs, },
        { .compatible = "ti,sysc-dra7-mcan", .data = &sysc_dra7_mcan, },
index 825725057e001b872d4b3bd69a777446b451102a..c7a328f81485bcae922316a90c589976e1cc60bc 100644 (file)
@@ -179,7 +179,7 @@ static unsigned int pxad_drcmr(unsigned int line)
        return 0x1000 + line * 4;
 }
 
-bool pxad_filter_fn(struct dma_chan *chan, void *param);
+static bool pxad_filter_fn(struct dma_chan *chan, void *param);
 
 /*
  * Debug fs
@@ -1500,7 +1500,7 @@ static struct platform_driver pxad_driver = {
        .remove         = pxad_remove,
 };
 
-bool pxad_filter_fn(struct dma_chan *chan, void *param)
+static bool pxad_filter_fn(struct dma_chan *chan, void *param)
 {
        struct pxad_chan *c = to_pxad_chan(chan);
        struct pxad_param *p = param;
@@ -1513,7 +1513,6 @@ bool pxad_filter_fn(struct dma_chan *chan, void *param)
 
        return true;
 }
-EXPORT_SYMBOL_GPL(pxad_filter_fn);
 
 module_platform_driver(pxad_driver);
 
index b170c2851e4835d77b8d2fe5671cc41877b5c838..6a7a7c2c5b5f6fb68f77cf3954ba4f6d7c4b972c 100644 (file)
@@ -9,3 +9,9 @@ config IMX_SCU
 
          This driver manages the IPC interface between host CPU and the
          SCU firmware running on M4.
+
+config IMX_SCU_PD
+       bool "IMX SCU Power Domain driver"
+       depends on IMX_SCU
+       help
+         The System Controller Firmware (SCFW) based power domain driver.
index 0ac04dfda8d472914b8ed0514b5a45dc4656093b..1b2e15b3c9caa4aa2cc12540d78ccaab06770f6c 100644 (file)
@@ -1,2 +1,3 @@
 # SPDX-License-Identifier: GPL-2.0
-obj-$(CONFIG_IMX_SCU)  += imx-scu.o misc.o
+obj-$(CONFIG_IMX_SCU)          += imx-scu.o misc.o
+obj-$(CONFIG_IMX_SCU_PD)       += scu-pd.o
diff --git a/drivers/firmware/imx/scu-pd.c b/drivers/firmware/imx/scu-pd.c
new file mode 100644 (file)
index 0000000..407245f
--- /dev/null
@@ -0,0 +1,339 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2018 NXP
+ *     Dong Aisheng <aisheng.dong@nxp.com>
+ *
+ * Implementation of the SCU based Power Domains
+ *
+ * NOTE: a better implementation suggested by Ulf Hansson is using a
+ * single global power domain and implement the ->attach|detach_dev()
+ * callback for the genpd and use the regular of_genpd_add_provider_simple().
+ * From within the ->attach_dev(), we could get the OF node for
+ * the device that is being attached and then parse the power-domain
+ * cell containing the "resource id" and store that in the per device
+ * struct generic_pm_domain_data (we have void pointer there for
+ * storing these kind of things).
+ *
+ * Additionally, we need to implement the ->stop() and ->start()
+ * callbacks of genpd, which is where you "power on/off" devices,
+ * rather than using the above ->power_on|off() callbacks.
+ *
+ * However, there're two known issues:
+ * 1. The ->attach_dev() of power domain infrastructure still does
+ *    not support multi domains case as the struct device *dev passed
+ *    in is a virtual PD device, it does not help for parsing the real
+ *    device resource id from device tree, so it's unware of which
+ *    real sub power domain of device should be attached.
+ *
+ *    The framework needs some proper extension to support multi power
+ *    domain cases.
+ *
+ * 2. It also breaks most of current drivers as the driver probe sequence
+ *    behavior changed if removing ->power_on|off() callback and use
+ *    ->start() and ->stop() instead. genpd_dev_pm_attach will only power
+ *    up the domain and attach device, but will not call .start() which
+ *    relies on device runtime pm. That means the device power is still
+ *    not up before running driver probe function. For SCU enabled
+ *    platforms, all device drivers accessing registers/clock without power
+ *    domain enabled will trigger a HW access error. That means we need fix
+ *    most drivers probe sequence with proper runtime pm.
+ *
+ * In summary, we need fix above two issue before being able to switch to
+ * the "single global power domain" way.
+ *
+ */
+
+#include <dt-bindings/firmware/imx/rsrc.h>
+#include <linux/firmware/imx/sci.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/pm.h>
+#include <linux/pm_domain.h>
+#include <linux/slab.h>
+
+/* SCU Power Mode Protocol definition */
+struct imx_sc_msg_req_set_resource_power_mode {
+       struct imx_sc_rpc_msg hdr;
+       u16 resource;
+       u8 mode;
+} __packed;
+
+#define IMX_SCU_PD_NAME_SIZE 20
+struct imx_sc_pm_domain {
+       struct generic_pm_domain pd;
+       char name[IMX_SCU_PD_NAME_SIZE];
+       u32 rsrc;
+};
+
+struct imx_sc_pd_range {
+       char *name;
+       u32 rsrc;
+       u8 num;
+       bool postfix;
+};
+
+struct imx_sc_pd_soc {
+       const struct imx_sc_pd_range *pd_ranges;
+       u8 num_ranges;
+};
+
+static const struct imx_sc_pd_range imx8qxp_scu_pd_ranges[] = {
+       /* LSIO SS */
+       { "lsio-pwm", IMX_SC_R_PWM_0, 8, 1 },
+       { "lsio-gpio", IMX_SC_R_GPIO_0, 8, 1 },
+       { "lsio-gpt", IMX_SC_R_GPT_0, 5, 1 },
+       { "lsio-kpp", IMX_SC_R_KPP, 1, 0 },
+       { "lsio-fspi", IMX_SC_R_FSPI_0, 2, 1 },
+       { "lsio-mu", IMX_SC_R_MU_0A, 14, 1 },
+
+       /* CONN SS */
+       { "con-usb", IMX_SC_R_USB_0, 2, 1 },
+       { "con-usb0phy", IMX_SC_R_USB_0_PHY, 1, 0 },
+       { "con-usb2", IMX_SC_R_USB_2, 1, 0 },
+       { "con-usb2phy", IMX_SC_R_USB_2_PHY, 1, 0 },
+       { "con-sdhc", IMX_SC_R_SDHC_0, 3, 1 },
+       { "con-enet", IMX_SC_R_ENET_0, 2, 1 },
+       { "con-nand", IMX_SC_R_NAND, 1, 0 },
+       { "con-mlb", IMX_SC_R_MLB_0, 1, 1 },
+
+       /* Audio DMA SS */
+       { "adma-audio-pll0", IMX_SC_R_AUDIO_PLL_0, 1, 0 },
+       { "adma-audio-pll1", IMX_SC_R_AUDIO_PLL_1, 1, 0 },
+       { "adma-audio-clk-0", IMX_SC_R_AUDIO_CLK_0, 1, 0 },
+       { "adma-dma0-ch", IMX_SC_R_DMA_0_CH0, 16, 1 },
+       { "adma-dma1-ch", IMX_SC_R_DMA_1_CH0, 16, 1 },
+       { "adma-dma2-ch", IMX_SC_R_DMA_2_CH0, 5, 1 },
+       { "adma-asrc0", IMX_SC_R_ASRC_0, 1, 0 },
+       { "adma-asrc1", IMX_SC_R_ASRC_1, 1, 0 },
+       { "adma-esai0", IMX_SC_R_ESAI_0, 1, 0 },
+       { "adma-spdif0", IMX_SC_R_SPDIF_0, 1, 0 },
+       { "adma-sai", IMX_SC_R_SAI_0, 3, 1 },
+       { "adma-amix", IMX_SC_R_AMIX, 1, 0 },
+       { "adma-mqs0", IMX_SC_R_MQS_0, 1, 0 },
+       { "adma-dsp", IMX_SC_R_DSP, 1, 0 },
+       { "adma-dsp-ram", IMX_SC_R_DSP_RAM, 1, 0 },
+       { "adma-can", IMX_SC_R_CAN_0, 3, 1 },
+       { "adma-ftm", IMX_SC_R_FTM_0, 2, 1 },
+       { "adma-lpi2c", IMX_SC_R_I2C_0, 4, 1 },
+       { "adma-adc", IMX_SC_R_ADC_0, 1, 1 },
+       { "adma-lcd", IMX_SC_R_LCD_0, 1, 1 },
+       { "adma-lcd0-pwm", IMX_SC_R_LCD_0_PWM_0, 1, 1 },
+       { "adma-lpuart", IMX_SC_R_UART_0, 4, 1 },
+       { "adma-lpspi", IMX_SC_R_SPI_0, 4, 1 },
+
+       /* VPU SS  */
+       { "vpu", IMX_SC_R_VPU, 1, 0 },
+       { "vpu-pid", IMX_SC_R_VPU_PID0, 8, 1 },
+       { "vpu-dec0", IMX_SC_R_VPU_DEC_0, 1, 0 },
+       { "vpu-enc0", IMX_SC_R_VPU_ENC_0, 1, 0 },
+
+       /* GPU SS */
+       { "gpu0-pid", IMX_SC_R_GPU_0_PID0, 4, 1 },
+
+       /* HSIO SS */
+       { "hsio-pcie-b", IMX_SC_R_PCIE_B, 1, 0 },
+       { "hsio-serdes-1", IMX_SC_R_SERDES_1, 1, 0 },
+       { "hsio-gpio", IMX_SC_R_HSIO_GPIO, 1, 0 },
+
+       /* MIPI/LVDS SS */
+       { "mipi0", IMX_SC_R_MIPI_0, 1, 0 },
+       { "mipi0-pwm0", IMX_SC_R_MIPI_0_PWM_0, 1, 0 },
+       { "mipi0-i2c", IMX_SC_R_MIPI_0_I2C_0, 2, 1 },
+       { "lvds0", IMX_SC_R_LVDS_0, 1, 0 },
+
+       /* DC SS */
+       { "dc0", IMX_SC_R_DC_0, 1, 0 },
+       { "dc0-pll", IMX_SC_R_DC_0_PLL_0, 2, 1 },
+};
+
+static const struct imx_sc_pd_soc imx8qxp_scu_pd = {
+       .pd_ranges = imx8qxp_scu_pd_ranges,
+       .num_ranges = ARRAY_SIZE(imx8qxp_scu_pd_ranges),
+};
+
+static struct imx_sc_ipc *pm_ipc_handle;
+
+static inline struct imx_sc_pm_domain *
+to_imx_sc_pd(struct generic_pm_domain *genpd)
+{
+       return container_of(genpd, struct imx_sc_pm_domain, pd);
+}
+
+static int imx_sc_pd_power(struct generic_pm_domain *domain, bool power_on)
+{
+       struct imx_sc_msg_req_set_resource_power_mode msg;
+       struct imx_sc_rpc_msg *hdr = &msg.hdr;
+       struct imx_sc_pm_domain *pd;
+       int ret;
+
+       pd = to_imx_sc_pd(domain);
+
+       hdr->ver = IMX_SC_RPC_VERSION;
+       hdr->svc = IMX_SC_RPC_SVC_PM;
+       hdr->func = IMX_SC_PM_FUNC_SET_RESOURCE_POWER_MODE;
+       hdr->size = 2;
+
+       msg.resource = pd->rsrc;
+       msg.mode = power_on ? IMX_SC_PM_PW_MODE_ON : IMX_SC_PM_PW_MODE_LP;
+
+       ret = imx_scu_call_rpc(pm_ipc_handle, &msg, true);
+       if (ret)
+               dev_err(&domain->dev, "failed to power %s resource %d ret %d\n",
+                       power_on ? "up" : "off", pd->rsrc, ret);
+
+       return ret;
+}
+
+static int imx_sc_pd_power_on(struct generic_pm_domain *domain)
+{
+       return imx_sc_pd_power(domain, true);
+}
+
+static int imx_sc_pd_power_off(struct generic_pm_domain *domain)
+{
+       return imx_sc_pd_power(domain, false);
+}
+
+static struct generic_pm_domain *imx_scu_pd_xlate(struct of_phandle_args *spec,
+                                                 void *data)
+{
+       struct generic_pm_domain *domain = ERR_PTR(-ENOENT);
+       struct genpd_onecell_data *pd_data = data;
+       unsigned int i;
+
+       for (i = 0; i < pd_data->num_domains; i++) {
+               struct imx_sc_pm_domain *sc_pd;
+
+               sc_pd = to_imx_sc_pd(pd_data->domains[i]);
+               if (sc_pd->rsrc == spec->args[0]) {
+                       domain = &sc_pd->pd;
+                       break;
+               }
+       }
+
+       return domain;
+}
+
+static struct imx_sc_pm_domain *
+imx_scu_add_pm_domain(struct device *dev, int idx,
+                     const struct imx_sc_pd_range *pd_ranges)
+{
+       struct imx_sc_pm_domain *sc_pd;
+       int ret;
+
+       sc_pd = devm_kzalloc(dev, sizeof(*sc_pd), GFP_KERNEL);
+       if (!sc_pd)
+               return ERR_PTR(-ENOMEM);
+
+       sc_pd->rsrc = pd_ranges->rsrc + idx;
+       sc_pd->pd.power_off = imx_sc_pd_power_off;
+       sc_pd->pd.power_on = imx_sc_pd_power_on;
+
+       if (pd_ranges->postfix)
+               snprintf(sc_pd->name, sizeof(sc_pd->name),
+                        "%s%i", pd_ranges->name, idx);
+       else
+               snprintf(sc_pd->name, sizeof(sc_pd->name),
+                        "%s", pd_ranges->name);
+
+       sc_pd->pd.name = sc_pd->name;
+
+       if (sc_pd->rsrc >= IMX_SC_R_LAST) {
+               dev_warn(dev, "invalid pd %s rsrc id %d found",
+                        sc_pd->name, sc_pd->rsrc);
+
+               devm_kfree(dev, sc_pd);
+               return NULL;
+       }
+
+       ret = pm_genpd_init(&sc_pd->pd, NULL, true);
+       if (ret) {
+               dev_warn(dev, "failed to init pd %s rsrc id %d",
+                        sc_pd->name, sc_pd->rsrc);
+               devm_kfree(dev, sc_pd);
+               return NULL;
+       }
+
+       return sc_pd;
+}
+
+static int imx_scu_init_pm_domains(struct device *dev,
+                                   const struct imx_sc_pd_soc *pd_soc)
+{
+       const struct imx_sc_pd_range *pd_ranges = pd_soc->pd_ranges;
+       struct generic_pm_domain **domains;
+       struct genpd_onecell_data *pd_data;
+       struct imx_sc_pm_domain *sc_pd;
+       u32 count = 0;
+       int i, j;
+
+       for (i = 0; i < pd_soc->num_ranges; i++)
+               count += pd_ranges[i].num;
+
+       domains = devm_kcalloc(dev, count, sizeof(*domains), GFP_KERNEL);
+       if (!domains)
+               return -ENOMEM;
+
+       pd_data = devm_kzalloc(dev, sizeof(*pd_data), GFP_KERNEL);
+       if (!pd_data)
+               return -ENOMEM;
+
+       count = 0;
+       for (i = 0; i < pd_soc->num_ranges; i++) {
+               for (j = 0; j < pd_ranges[i].num; j++) {
+                       sc_pd = imx_scu_add_pm_domain(dev, j, &pd_ranges[i]);
+                       if (IS_ERR_OR_NULL(sc_pd))
+                               continue;
+
+                       domains[count++] = &sc_pd->pd;
+                       dev_dbg(dev, "added power domain %s\n", sc_pd->pd.name);
+               }
+       }
+
+       pd_data->domains = domains;
+       pd_data->num_domains = count;
+       pd_data->xlate = imx_scu_pd_xlate;
+
+       of_genpd_add_provider_onecell(dev->of_node, pd_data);
+
+       return 0;
+}
+
+static int imx_sc_pd_probe(struct platform_device *pdev)
+{
+       const struct imx_sc_pd_soc *pd_soc;
+       int ret;
+
+       ret = imx_scu_get_handle(&pm_ipc_handle);
+       if (ret)
+               return ret;
+
+       pd_soc = of_device_get_match_data(&pdev->dev);
+       if (!pd_soc)
+               return -ENODEV;
+
+       return imx_scu_init_pm_domains(&pdev->dev, pd_soc);
+}
+
+static const struct of_device_id imx_sc_pd_match[] = {
+       { .compatible = "fsl,imx8qxp-scu-pd", &imx8qxp_scu_pd},
+       { /* sentinel */ }
+};
+
+static struct platform_driver imx_sc_pd_driver = {
+       .driver = {
+               .name = "imx-scu-pd",
+               .of_match_table = imx_sc_pd_match,
+       },
+       .probe = imx_sc_pd_probe,
+};
+builtin_platform_driver(imx_sc_pd_driver);
+
+MODULE_AUTHOR("Dong Aisheng <aisheng.dong@nxp.com>");
+MODULE_DESCRIPTION("IMX SCU Power Domain driver");
+MODULE_LICENSE("GPL v2");
index a200a217461191b796105682e599582bb736683e..a13558154ac305fc19e3dee687e07ea26e7c6f25 100644 (file)
@@ -1,12 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Defines interfaces for interacting wtih the Raspberry Pi firmware's
  * property channel.
  *
  * Copyright Â© 2015 Broadcom
- *
- * 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.
  */
 
 #include <linux/dma-mapping.h>
@@ -14,6 +11,7 @@
 #include <linux/module.h>
 #include <linux/of_platform.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <soc/bcm2835/raspberrypi-firmware.h>
 
 #define MBOX_MSG(chan, data28)         (((data28) & ~0xf) | ((chan) & 0xf))
@@ -21,8 +19,6 @@
 #define MBOX_DATA28(msg)               ((msg) & ~0xf)
 #define MBOX_CHAN_PROPERTY             8
 
-#define MAX_RPI_FW_PROP_BUF_SIZE       32
-
 static struct platform_device *rpi_hwmon;
 
 struct rpi_firmware {
@@ -56,8 +52,12 @@ rpi_firmware_transaction(struct rpi_firmware *fw, u32 chan, u32 data)
        reinit_completion(&fw->c);
        ret = mbox_send_message(fw->chan, &message);
        if (ret >= 0) {
-               wait_for_completion(&fw->c);
-               ret = 0;
+               if (wait_for_completion_timeout(&fw->c, HZ)) {
+                       ret = 0;
+               } else {
+                       ret = -ETIMEDOUT;
+                       WARN_ONCE(1, "Firmware transaction timeout");
+               }
        } else {
                dev_err(fw->cl.dev, "mbox_send_message returned %d\n", ret);
        }
@@ -144,28 +144,30 @@ EXPORT_SYMBOL_GPL(rpi_firmware_property_list);
 int rpi_firmware_property(struct rpi_firmware *fw,
                          u32 tag, void *tag_data, size_t buf_size)
 {
-       /* Single tags are very small (generally 8 bytes), so the
-        * stack should be safe.
-        */
-       u8 data[sizeof(struct rpi_firmware_property_tag_header) +
-               MAX_RPI_FW_PROP_BUF_SIZE];
-       struct rpi_firmware_property_tag_header *header =
-               (struct rpi_firmware_property_tag_header *)data;
+       struct rpi_firmware_property_tag_header *header;
        int ret;
 
-       if (WARN_ON(buf_size > sizeof(data) - sizeof(*header)))
-               return -EINVAL;
+       /* Some mailboxes can use over 1k bytes. Rather than checking
+        * size and using stack or kmalloc depending on requirements,
+        * just use kmalloc. Mailboxes don't get called enough to worry
+        * too much about the time taken in the allocation.
+        */
+       void *data = kmalloc(sizeof(*header) + buf_size, GFP_KERNEL);
 
+       if (!data)
+               return -ENOMEM;
+
+       header = data;
        header->tag = tag;
        header->buf_size = buf_size;
        header->req_resp_size = 0;
-       memcpy(data + sizeof(struct rpi_firmware_property_tag_header),
-              tag_data, buf_size);
+       memcpy(data + sizeof(*header), tag_data, buf_size);
+
+       ret = rpi_firmware_property_list(fw, data, buf_size + sizeof(*header));
+
+       memcpy(tag_data, data + sizeof(*header), buf_size);
 
-       ret = rpi_firmware_property_list(fw, &data, buf_size + sizeof(*header));
-       memcpy(tag_data,
-              data + sizeof(struct rpi_firmware_property_tag_header),
-              buf_size);
+       kfree(data);
 
        return ret;
 }
index f7f6a0a5cb0786081669756c66abc7036475d539..a84df1a8ca2b83e3630cd9d557262eeb29f04a3e 100644 (file)
@@ -379,33 +379,6 @@ static int create_debugfs_mirror(struct tegra_bpmp *bpmp, void *buf,
        return err;
 }
 
-static int mrq_is_supported(struct tegra_bpmp *bpmp, unsigned int mrq)
-{
-       struct mrq_query_abi_request req = { .mrq = cpu_to_le32(mrq) };
-       struct mrq_query_abi_response resp;
-       struct tegra_bpmp_message msg = {
-               .mrq = MRQ_QUERY_ABI,
-               .tx = {
-                       .data = &req,
-                       .size = sizeof(req),
-               },
-               .rx = {
-                       .data = &resp,
-                       .size = sizeof(resp),
-               },
-       };
-       int ret;
-
-       ret = tegra_bpmp_transfer(bpmp, &msg);
-       if (ret < 0) {
-               /* something went wrong; assume not supported */
-               dev_warn(bpmp->dev, "tegra_bpmp_transfer failed (%d)\n", ret);
-               return 0;
-       }
-
-       return resp.status ? 0 : 1;
-}
-
 int tegra_bpmp_init_debugfs(struct tegra_bpmp *bpmp)
 {
        dma_addr_t phys;
@@ -415,7 +388,7 @@ int tegra_bpmp_init_debugfs(struct tegra_bpmp *bpmp)
        int ret;
        struct dentry *root;
 
-       if (!mrq_is_supported(bpmp, MRQ_DEBUGFS))
+       if (!tegra_bpmp_mrq_is_supported(bpmp, MRQ_DEBUGFS))
                return 0;
 
        root = debugfs_create_dir("bpmp", NULL);
index a3d5b518c10e4a13deeba7c6e9309c13c33cdded..689478b92bce638ea364485087361a5a378b59dc 100644 (file)
@@ -28,6 +28,7 @@
 
 #define MSG_ACK                BIT(0)
 #define MSG_RING       BIT(1)
+#define TAG_SZ         32
 
 static inline struct tegra_bpmp *
 mbox_client_to_bpmp(struct mbox_client *client)
@@ -470,6 +471,31 @@ unlock:
 }
 EXPORT_SYMBOL_GPL(tegra_bpmp_free_mrq);
 
+bool tegra_bpmp_mrq_is_supported(struct tegra_bpmp *bpmp, unsigned int mrq)
+{
+       struct mrq_query_abi_request req = { .mrq = cpu_to_le32(mrq) };
+       struct mrq_query_abi_response resp;
+       struct tegra_bpmp_message msg = {
+               .mrq = MRQ_QUERY_ABI,
+               .tx = {
+                       .data = &req,
+                       .size = sizeof(req),
+               },
+               .rx = {
+                       .data = &resp,
+                       .size = sizeof(resp),
+               },
+       };
+       int ret;
+
+       ret = tegra_bpmp_transfer(bpmp, &msg);
+       if (ret || msg.rx.ret)
+               return false;
+
+       return resp.status == 0;
+}
+EXPORT_SYMBOL_GPL(tegra_bpmp_mrq_is_supported);
+
 static void tegra_bpmp_mrq_handle_ping(unsigned int mrq,
                                       struct tegra_bpmp_channel *channel,
                                       void *data)
@@ -521,8 +547,9 @@ static int tegra_bpmp_ping(struct tegra_bpmp *bpmp)
        return err;
 }
 
-static int tegra_bpmp_get_firmware_tag(struct tegra_bpmp *bpmp, char *tag,
-                                      size_t size)
+/* deprecated version of tag query */
+static int tegra_bpmp_get_firmware_tag_old(struct tegra_bpmp *bpmp, char *tag,
+                                          size_t size)
 {
        struct mrq_query_tag_request request;
        struct tegra_bpmp_message msg;
@@ -531,7 +558,10 @@ static int tegra_bpmp_get_firmware_tag(struct tegra_bpmp *bpmp, char *tag,
        void *virt;
        int err;
 
-       virt = dma_alloc_coherent(bpmp->dev, MSG_DATA_MIN_SZ, &phys,
+       if (size != TAG_SZ)
+               return -EINVAL;
+
+       virt = dma_alloc_coherent(bpmp->dev, TAG_SZ, &phys,
                                  GFP_KERNEL | GFP_DMA32);
        if (!virt)
                return -ENOMEM;
@@ -549,13 +579,44 @@ static int tegra_bpmp_get_firmware_tag(struct tegra_bpmp *bpmp, char *tag,
        local_irq_restore(flags);
 
        if (err == 0)
-               strlcpy(tag, virt, size);
+               memcpy(tag, virt, TAG_SZ);
 
-       dma_free_coherent(bpmp->dev, MSG_DATA_MIN_SZ, virt, phys);
+       dma_free_coherent(bpmp->dev, TAG_SZ, virt, phys);
 
        return err;
 }
 
+static int tegra_bpmp_get_firmware_tag(struct tegra_bpmp *bpmp, char *tag,
+                                      size_t size)
+{
+       if (tegra_bpmp_mrq_is_supported(bpmp, MRQ_QUERY_FW_TAG)) {
+               struct mrq_query_fw_tag_response resp;
+               struct tegra_bpmp_message msg = {
+                       .mrq = MRQ_QUERY_FW_TAG,
+                       .rx = {
+                               .data = &resp,
+                               .size = sizeof(resp),
+                       },
+               };
+               int err;
+
+               if (size != sizeof(resp.tag))
+                       return -EINVAL;
+
+               err = tegra_bpmp_transfer(bpmp, &msg);
+
+               if (err)
+                       return err;
+               if (msg.rx.ret < 0)
+                       return -EINVAL;
+
+               memcpy(tag, resp.tag, sizeof(resp.tag));
+               return 0;
+       }
+
+       return tegra_bpmp_get_firmware_tag_old(bpmp, tag, size);
+}
+
 static void tegra_bpmp_channel_signal(struct tegra_bpmp_channel *channel)
 {
        unsigned long flags = channel->ob->flags;
@@ -664,7 +725,7 @@ static int tegra_bpmp_probe(struct platform_device *pdev)
 {
        struct tegra_bpmp *bpmp;
        unsigned int i;
-       char tag[32];
+       char tag[TAG_SZ];
        size_t size;
        int err;
 
@@ -792,13 +853,13 @@ static int tegra_bpmp_probe(struct platform_device *pdev)
                goto free_mrq;
        }
 
-       err = tegra_bpmp_get_firmware_tag(bpmp, tag, sizeof(tag) - 1);
+       err = tegra_bpmp_get_firmware_tag(bpmp, tag, sizeof(tag));
        if (err < 0) {
                dev_err(&pdev->dev, "failed to get firmware tag: %d\n", err);
                goto free_mrq;
        }
 
-       dev_info(&pdev->dev, "firmware: %s\n", tag);
+       dev_info(&pdev->dev, "firmware: %.*s\n", (int)sizeof(tag), tag);
 
        platform_set_drvdata(pdev, bpmp);
 
index d4e98e5876bc4a7fbab76c9760c2e548afdfea73..0fb4718ef0df9c9ba7cfa72f71f0da952f9fb2c7 100644 (file)
@@ -902,26 +902,6 @@ static int a6xx_gmu_memory_probe(struct a6xx_gmu *gmu)
        return ret;
 }
 
-/* Get the list of RPMh voltage levels from cmd-db */
-static int a6xx_gmu_rpmh_arc_cmds(const char *id, void *vals, int size)
-{
-       u32 len = cmd_db_read_aux_data_len(id);
-
-       if (!len)
-               return 0;
-
-       if (WARN_ON(len > size))
-               return -EINVAL;
-
-       cmd_db_read_aux_data(id, vals, len);
-
-       /*
-        * The data comes back as an array of unsigned shorts so adjust the
-        * count accordingly
-        */
-       return len >> 1;
-}
-
 /* Return the 'arc-level' for the given frequency */
 static u32 a6xx_gmu_get_arc_level(struct device *dev, unsigned long freq)
 {
@@ -949,11 +929,30 @@ static u32 a6xx_gmu_get_arc_level(struct device *dev, unsigned long freq)
 }
 
 static int a6xx_gmu_rpmh_arc_votes_init(struct device *dev, u32 *votes,
-               unsigned long *freqs, int freqs_count,
-               u16 *pri, int pri_count,
-               u16 *sec, int sec_count)
+               unsigned long *freqs, int freqs_count, const char *id)
 {
        int i, j;
+       const u16 *pri, *sec;
+       size_t pri_count, sec_count;
+
+       pri = cmd_db_read_aux_data(id, &pri_count);
+       if (IS_ERR(pri))
+               return PTR_ERR(pri);
+       /*
+        * The data comes back as an array of unsigned shorts so adjust the
+        * count accordingly
+        */
+       pri_count >>= 1;
+       if (!pri_count)
+               return -EINVAL;
+
+       sec = cmd_db_read_aux_data("mx.lvl", &sec_count);
+       if (IS_ERR(sec))
+               return PTR_ERR(sec);
+
+       sec_count >>= 1;
+       if (!sec_count)
+               return -EINVAL;
 
        /* Construct a vote for each frequency */
        for (i = 0; i < freqs_count; i++) {
@@ -1012,25 +1011,15 @@ static int a6xx_gmu_rpmh_votes_init(struct a6xx_gmu *gmu)
        struct a6xx_gpu *a6xx_gpu = container_of(gmu, struct a6xx_gpu, gmu);
        struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
        struct msm_gpu *gpu = &adreno_gpu->base;
-
-       u16 gx[16], cx[16], mx[16];
-       u32 gxcount, cxcount, mxcount;
        int ret;
 
-       /* Get the list of available voltage levels for each component */
-       gxcount = a6xx_gmu_rpmh_arc_cmds("gfx.lvl", gx, sizeof(gx));
-       cxcount = a6xx_gmu_rpmh_arc_cmds("cx.lvl", cx, sizeof(cx));
-       mxcount = a6xx_gmu_rpmh_arc_cmds("mx.lvl", mx, sizeof(mx));
-
        /* Build the GX votes */
        ret = a6xx_gmu_rpmh_arc_votes_init(&gpu->pdev->dev, gmu->gx_arc_votes,
-               gmu->gpu_freqs, gmu->nr_gpu_freqs,
-               gx, gxcount, mx, mxcount);
+               gmu->gpu_freqs, gmu->nr_gpu_freqs, "gfx.lvl");
 
        /* Build the CX votes */
        ret |= a6xx_gmu_rpmh_arc_votes_init(gmu->dev, gmu->cx_arc_votes,
-               gmu->gmu_freqs, gmu->nr_gmu_freqs,
-               cx, cxcount, mx, mxcount);
+               gmu->gmu_freqs, gmu->nr_gmu_freqs, "cx.lvl");
 
        return ret;
 }
index 63389f075f1dcab5637f4a72bc1081303fc86075..2d91b00e3591e78f6616faa4b0ce95ebffafbb24 100644 (file)
@@ -145,6 +145,15 @@ config DA8XX_DDRCTL
          Texas Instruments da8xx SoCs. It's used to tweak various memory
          controller configuration options.
 
+config PL353_SMC
+       tristate "ARM PL35X Static Memory Controller(SMC) driver"
+       default y
+       depends on ARM
+       depends on ARM_AMBA
+       help
+         This driver is for the ARM PL351/PL353 Static Memory
+         Controller(SMC) module.
+
 source "drivers/memory/samsung/Kconfig"
 source "drivers/memory/tegra/Kconfig"
 
index a01ab3e22f94db6dc81c7032b06adab9ec4bc48e..90161dec6fa50cf591dc06e800ae9f2d4d8367e6 100644 (file)
@@ -19,6 +19,7 @@ obj-$(CONFIG_MVEBU_DEVBUS)    += mvebu-devbus.o
 obj-$(CONFIG_JZ4780_NEMC)      += jz4780-nemc.o
 obj-$(CONFIG_MTK_SMI)          += mtk-smi.o
 obj-$(CONFIG_DA8XX_DDRCTL)     += da8xx-ddrctl.o
+obj-$(CONFIG_PL353_SMC)                += pl353-smc.o
 
 obj-$(CONFIG_SAMSUNG_MC)       += samsung/
 obj-$(CONFIG_TEGRA_MC)         += tegra/
index c215287e80cf3bbff8d452f53bf097fba39148dd..a66dea4f1ed2500bd0b7dfed1e84428c2b1c9ae2 100644 (file)
@@ -2060,7 +2060,7 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
         * timings.
         */
        name = gpmc_cs_get_name(cs);
-       if (name && of_node_cmp(child->name, name) == 0)
+       if (name && of_node_name_eq(child, name))
                goto no_timings;
 
        ret = gpmc_cs_request(cs, resource_size(&res), &base);
@@ -2068,7 +2068,7 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
                dev_err(&pdev->dev, "cannot request GPMC CS %d\n", cs);
                return ret;
        }
-       gpmc_cs_set_name(cs, child->name);
+       gpmc_cs_set_name(cs, child->full_name);
 
        gpmc_read_settings_dt(child, &gpmc_s);
        gpmc_read_timings_dt(child, &gpmc_t);
@@ -2113,7 +2113,7 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
                goto err;
        }
 
-       if (of_node_cmp(child->name, "nand") == 0) {
+       if (of_node_name_eq(child, "nand")) {
                /* Warn about older DT blobs with no compatible property */
                if (!of_property_read_bool(child, "compatible")) {
                        dev_warn(&pdev->dev,
@@ -2123,7 +2123,7 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
                }
        }
 
-       if (of_node_cmp(child->name, "onenand") == 0) {
+       if (of_node_name_eq(child, "onenand")) {
                /* Warn about older DT blobs with no compatible property */
                if (!of_property_read_bool(child, "compatible")) {
                        dev_warn(&pdev->dev,
diff --git a/drivers/memory/pl353-smc.c b/drivers/memory/pl353-smc.c
new file mode 100644 (file)
index 0000000..73bd302
--- /dev/null
@@ -0,0 +1,463 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * ARM PL353 SMC driver
+ *
+ * Copyright (C) 2012 - 2018 Xilinx, Inc
+ * Author: Punnaiah Choudary Kalluri <punnaiah@xilinx.com>
+ * Author: Naga Sureshkumar Relli <nagasure@xilinx.com>
+ */
+
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/pl353-smc.h>
+#include <linux/amba/bus.h>
+
+/* Register definitions */
+#define PL353_SMC_MEMC_STATUS_OFFS     0       /* Controller status reg, RO */
+#define PL353_SMC_CFG_CLR_OFFS         0xC     /* Clear config reg, WO */
+#define PL353_SMC_DIRECT_CMD_OFFS      0x10    /* Direct command reg, WO */
+#define PL353_SMC_SET_CYCLES_OFFS      0x14    /* Set cycles register, WO */
+#define PL353_SMC_SET_OPMODE_OFFS      0x18    /* Set opmode register, WO */
+#define PL353_SMC_ECC_STATUS_OFFS      0x400   /* ECC status register */
+#define PL353_SMC_ECC_MEMCFG_OFFS      0x404   /* ECC mem config reg */
+#define PL353_SMC_ECC_MEMCMD1_OFFS     0x408   /* ECC mem cmd1 reg */
+#define PL353_SMC_ECC_MEMCMD2_OFFS     0x40C   /* ECC mem cmd2 reg */
+#define PL353_SMC_ECC_VALUE0_OFFS      0x418   /* ECC value 0 reg */
+
+/* Controller status register specific constants */
+#define PL353_SMC_MEMC_STATUS_RAW_INT_1_SHIFT  6
+
+/* Clear configuration register specific constants */
+#define PL353_SMC_CFG_CLR_INT_CLR_1    0x10
+#define PL353_SMC_CFG_CLR_ECC_INT_DIS_1        0x40
+#define PL353_SMC_CFG_CLR_INT_DIS_1    0x2
+#define PL353_SMC_CFG_CLR_DEFAULT_MASK (PL353_SMC_CFG_CLR_INT_CLR_1 | \
+                                        PL353_SMC_CFG_CLR_ECC_INT_DIS_1 | \
+                                        PL353_SMC_CFG_CLR_INT_DIS_1)
+
+/* Set cycles register specific constants */
+#define PL353_SMC_SET_CYCLES_T0_MASK   0xF
+#define PL353_SMC_SET_CYCLES_T0_SHIFT  0
+#define PL353_SMC_SET_CYCLES_T1_MASK   0xF
+#define PL353_SMC_SET_CYCLES_T1_SHIFT  4
+#define PL353_SMC_SET_CYCLES_T2_MASK   0x7
+#define PL353_SMC_SET_CYCLES_T2_SHIFT  8
+#define PL353_SMC_SET_CYCLES_T3_MASK   0x7
+#define PL353_SMC_SET_CYCLES_T3_SHIFT  11
+#define PL353_SMC_SET_CYCLES_T4_MASK   0x7
+#define PL353_SMC_SET_CYCLES_T4_SHIFT  14
+#define PL353_SMC_SET_CYCLES_T5_MASK   0x7
+#define PL353_SMC_SET_CYCLES_T5_SHIFT  17
+#define PL353_SMC_SET_CYCLES_T6_MASK   0xF
+#define PL353_SMC_SET_CYCLES_T6_SHIFT  20
+
+/* ECC status register specific constants */
+#define PL353_SMC_ECC_STATUS_BUSY      BIT(6)
+#define PL353_SMC_ECC_REG_SIZE_OFFS    4
+
+/* ECC memory config register specific constants */
+#define PL353_SMC_ECC_MEMCFG_MODE_MASK 0xC
+#define PL353_SMC_ECC_MEMCFG_MODE_SHIFT        2
+#define PL353_SMC_ECC_MEMCFG_PGSIZE_MASK       0xC
+
+#define PL353_SMC_DC_UPT_NAND_REGS     ((4 << 23) |    /* CS: NAND chip */ \
+                                (2 << 21))     /* UpdateRegs operation */
+
+#define PL353_NAND_ECC_CMD1    ((0x80)       | /* Write command */ \
+                                (0 << 8)     | /* Read command */ \
+                                (0x30 << 16) | /* Read End command */ \
+                                (1 << 24))     /* Read End command calid */
+
+#define PL353_NAND_ECC_CMD2    ((0x85)       | /* Write col change cmd */ \
+                                (5 << 8)     | /* Read col change cmd */ \
+                                (0xE0 << 16) | /* Read col change end cmd */ \
+                                (1 << 24)) /* Read col change end cmd valid */
+#define PL353_NAND_ECC_BUSY_TIMEOUT    (1 * HZ)
+/**
+ * struct pl353_smc_data - Private smc driver structure
+ * @memclk:            Pointer to the peripheral clock
+ * @aclk:              Pointer to the APER clock
+ */
+struct pl353_smc_data {
+       struct clk              *memclk;
+       struct clk              *aclk;
+};
+
+/* SMC virtual register base */
+static void __iomem *pl353_smc_base;
+
+/**
+ * pl353_smc_set_buswidth - Set memory buswidth
+ * @bw: Memory buswidth (8 | 16)
+ * Return: 0 on success or negative errno.
+ */
+int pl353_smc_set_buswidth(unsigned int bw)
+{
+       if (bw != PL353_SMC_MEM_WIDTH_8  && bw != PL353_SMC_MEM_WIDTH_16)
+               return -EINVAL;
+
+       writel(bw, pl353_smc_base + PL353_SMC_SET_OPMODE_OFFS);
+       writel(PL353_SMC_DC_UPT_NAND_REGS, pl353_smc_base +
+              PL353_SMC_DIRECT_CMD_OFFS);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(pl353_smc_set_buswidth);
+
+/**
+ * pl353_smc_set_cycles - Set memory timing parameters
+ * @timings: NAND controller timing parameters
+ *
+ * Sets NAND chip specific timing parameters.
+ */
+void pl353_smc_set_cycles(u32 timings[])
+{
+       /*
+        * Set write pulse timing. This one is easy to extract:
+        *
+        * NWE_PULSE = tWP
+        */
+       timings[0] &= PL353_SMC_SET_CYCLES_T0_MASK;
+       timings[1] = (timings[1] & PL353_SMC_SET_CYCLES_T1_MASK) <<
+                       PL353_SMC_SET_CYCLES_T1_SHIFT;
+       timings[2] = (timings[2]  & PL353_SMC_SET_CYCLES_T2_MASK) <<
+                       PL353_SMC_SET_CYCLES_T2_SHIFT;
+       timings[3] = (timings[3]  & PL353_SMC_SET_CYCLES_T3_MASK) <<
+                       PL353_SMC_SET_CYCLES_T3_SHIFT;
+       timings[4] = (timings[4] & PL353_SMC_SET_CYCLES_T4_MASK) <<
+                       PL353_SMC_SET_CYCLES_T4_SHIFT;
+       timings[5]  = (timings[5]  & PL353_SMC_SET_CYCLES_T5_MASK) <<
+                       PL353_SMC_SET_CYCLES_T5_SHIFT;
+       timings[6]  = (timings[6]  & PL353_SMC_SET_CYCLES_T6_MASK) <<
+                       PL353_SMC_SET_CYCLES_T6_SHIFT;
+       timings[0] |= timings[1] | timings[2] | timings[3] |
+                       timings[4] | timings[5] | timings[6];
+
+       writel(timings[0], pl353_smc_base + PL353_SMC_SET_CYCLES_OFFS);
+       writel(PL353_SMC_DC_UPT_NAND_REGS, pl353_smc_base +
+              PL353_SMC_DIRECT_CMD_OFFS);
+}
+EXPORT_SYMBOL_GPL(pl353_smc_set_cycles);
+
+/**
+ * pl353_smc_ecc_is_busy - Read ecc busy flag
+ * Return: the ecc_status bit from the ecc_status register. 1 = busy, 0 = idle
+ */
+bool pl353_smc_ecc_is_busy(void)
+{
+       return ((readl(pl353_smc_base + PL353_SMC_ECC_STATUS_OFFS) &
+                 PL353_SMC_ECC_STATUS_BUSY) == PL353_SMC_ECC_STATUS_BUSY);
+}
+EXPORT_SYMBOL_GPL(pl353_smc_ecc_is_busy);
+
+/**
+ * pl353_smc_get_ecc_val - Read ecc_valueN registers
+ * @ecc_reg: Index of the ecc_value reg (0..3)
+ * Return: the content of the requested ecc_value register.
+ *
+ * There are four valid ecc_value registers. The argument is truncated to stay
+ * within this valid boundary.
+ */
+u32 pl353_smc_get_ecc_val(int ecc_reg)
+{
+       u32 addr, reg;
+
+       addr = PL353_SMC_ECC_VALUE0_OFFS +
+               (ecc_reg * PL353_SMC_ECC_REG_SIZE_OFFS);
+       reg = readl(pl353_smc_base + addr);
+
+       return reg;
+}
+EXPORT_SYMBOL_GPL(pl353_smc_get_ecc_val);
+
+/**
+ * pl353_smc_get_nand_int_status_raw - Get NAND interrupt status bit
+ * Return: the raw_int_status1 bit from the memc_status register
+ */
+int pl353_smc_get_nand_int_status_raw(void)
+{
+       u32 reg;
+
+       reg = readl(pl353_smc_base + PL353_SMC_MEMC_STATUS_OFFS);
+       reg >>= PL353_SMC_MEMC_STATUS_RAW_INT_1_SHIFT;
+       reg &= 1;
+
+       return reg;
+}
+EXPORT_SYMBOL_GPL(pl353_smc_get_nand_int_status_raw);
+
+/**
+ * pl353_smc_clr_nand_int - Clear NAND interrupt
+ */
+void pl353_smc_clr_nand_int(void)
+{
+       writel(PL353_SMC_CFG_CLR_INT_CLR_1,
+              pl353_smc_base + PL353_SMC_CFG_CLR_OFFS);
+}
+EXPORT_SYMBOL_GPL(pl353_smc_clr_nand_int);
+
+/**
+ * pl353_smc_set_ecc_mode - Set SMC ECC mode
+ * @mode: ECC mode (BYPASS, APB, MEM)
+ * Return: 0 on success or negative errno.
+ */
+int pl353_smc_set_ecc_mode(enum pl353_smc_ecc_mode mode)
+{
+       u32 reg;
+       int ret = 0;
+
+       switch (mode) {
+       case PL353_SMC_ECCMODE_BYPASS:
+       case PL353_SMC_ECCMODE_APB:
+       case PL353_SMC_ECCMODE_MEM:
+
+               reg = readl(pl353_smc_base + PL353_SMC_ECC_MEMCFG_OFFS);
+               reg &= ~PL353_SMC_ECC_MEMCFG_MODE_MASK;
+               reg |= mode << PL353_SMC_ECC_MEMCFG_MODE_SHIFT;
+               writel(reg, pl353_smc_base + PL353_SMC_ECC_MEMCFG_OFFS);
+
+               break;
+       default:
+               ret = -EINVAL;
+       }
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(pl353_smc_set_ecc_mode);
+
+/**
+ * pl353_smc_set_ecc_pg_size - Set SMC ECC page size
+ * @pg_sz: ECC page size
+ * Return: 0 on success or negative errno.
+ */
+int pl353_smc_set_ecc_pg_size(unsigned int pg_sz)
+{
+       u32 reg, sz;
+
+       switch (pg_sz) {
+       case 0:
+               sz = 0;
+               break;
+       case SZ_512:
+               sz = 1;
+               break;
+       case SZ_1K:
+               sz = 2;
+               break;
+       case SZ_2K:
+               sz = 3;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       reg = readl(pl353_smc_base + PL353_SMC_ECC_MEMCFG_OFFS);
+       reg &= ~PL353_SMC_ECC_MEMCFG_PGSIZE_MASK;
+       reg |= sz;
+       writel(reg, pl353_smc_base + PL353_SMC_ECC_MEMCFG_OFFS);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(pl353_smc_set_ecc_pg_size);
+
+static int __maybe_unused pl353_smc_suspend(struct device *dev)
+{
+       struct pl353_smc_data *pl353_smc = dev_get_drvdata(dev);
+
+       clk_disable(pl353_smc->memclk);
+       clk_disable(pl353_smc->aclk);
+
+       return 0;
+}
+
+static int __maybe_unused pl353_smc_resume(struct device *dev)
+{
+       int ret;
+       struct pl353_smc_data *pl353_smc = dev_get_drvdata(dev);
+
+       ret = clk_enable(pl353_smc->aclk);
+       if (ret) {
+               dev_err(dev, "Cannot enable axi domain clock.\n");
+               return ret;
+       }
+
+       ret = clk_enable(pl353_smc->memclk);
+       if (ret) {
+               dev_err(dev, "Cannot enable memory clock.\n");
+               clk_disable(pl353_smc->aclk);
+               return ret;
+       }
+
+       return ret;
+}
+
+static struct amba_driver pl353_smc_driver;
+
+static SIMPLE_DEV_PM_OPS(pl353_smc_dev_pm_ops, pl353_smc_suspend,
+                        pl353_smc_resume);
+
+/**
+ * pl353_smc_init_nand_interface - Initialize the NAND interface
+ * @adev: Pointer to the amba_device struct
+ * @nand_node: Pointer to the pl353_nand device_node struct
+ */
+static void pl353_smc_init_nand_interface(struct amba_device *adev,
+                                         struct device_node *nand_node)
+{
+       unsigned long timeout;
+
+       pl353_smc_set_buswidth(PL353_SMC_MEM_WIDTH_8);
+       writel(PL353_SMC_CFG_CLR_INT_CLR_1,
+              pl353_smc_base + PL353_SMC_CFG_CLR_OFFS);
+       writel(PL353_SMC_DC_UPT_NAND_REGS, pl353_smc_base +
+              PL353_SMC_DIRECT_CMD_OFFS);
+
+       timeout = jiffies + PL353_NAND_ECC_BUSY_TIMEOUT;
+       /* Wait till the ECC operation is complete */
+       do {
+               if (pl353_smc_ecc_is_busy())
+                       cpu_relax();
+               else
+                       break;
+       } while (!time_after_eq(jiffies, timeout));
+
+       if (time_after_eq(jiffies, timeout))
+               return;
+
+       writel(PL353_NAND_ECC_CMD1,
+              pl353_smc_base + PL353_SMC_ECC_MEMCMD1_OFFS);
+       writel(PL353_NAND_ECC_CMD2,
+              pl353_smc_base + PL353_SMC_ECC_MEMCMD2_OFFS);
+}
+
+static const struct of_device_id pl353_smc_supported_children[] = {
+       {
+               .compatible = "cfi-flash"
+       },
+       {
+               .compatible = "arm,pl353-nand-r2p1",
+               .data = pl353_smc_init_nand_interface
+       },
+       {}
+};
+
+static int pl353_smc_probe(struct amba_device *adev, const struct amba_id *id)
+{
+       struct pl353_smc_data *pl353_smc;
+       struct device_node *child;
+       struct resource *res;
+       int err;
+       struct device_node *of_node = adev->dev.of_node;
+       static void (*init)(struct amba_device *adev,
+                           struct device_node *nand_node);
+       const struct of_device_id *match = NULL;
+
+       pl353_smc = devm_kzalloc(&adev->dev, sizeof(*pl353_smc), GFP_KERNEL);
+       if (!pl353_smc)
+               return -ENOMEM;
+
+       /* Get the NAND controller virtual address */
+       res = &adev->res;
+       pl353_smc_base = devm_ioremap_resource(&adev->dev, res);
+       if (IS_ERR(pl353_smc_base))
+               return PTR_ERR(pl353_smc_base);
+
+       pl353_smc->aclk = devm_clk_get(&adev->dev, "apb_pclk");
+       if (IS_ERR(pl353_smc->aclk)) {
+               dev_err(&adev->dev, "aclk clock not found.\n");
+               return PTR_ERR(pl353_smc->aclk);
+       }
+
+       pl353_smc->memclk = devm_clk_get(&adev->dev, "memclk");
+       if (IS_ERR(pl353_smc->memclk)) {
+               dev_err(&adev->dev, "memclk clock not found.\n");
+               return PTR_ERR(pl353_smc->memclk);
+       }
+
+       err = clk_prepare_enable(pl353_smc->aclk);
+       if (err) {
+               dev_err(&adev->dev, "Unable to enable AXI clock.\n");
+               return err;
+       }
+
+       err = clk_prepare_enable(pl353_smc->memclk);
+       if (err) {
+               dev_err(&adev->dev, "Unable to enable memory clock.\n");
+               goto out_clk_dis_aper;
+       }
+
+       amba_set_drvdata(adev, pl353_smc);
+
+       /* clear interrupts */
+       writel(PL353_SMC_CFG_CLR_DEFAULT_MASK,
+              pl353_smc_base + PL353_SMC_CFG_CLR_OFFS);
+
+       /* Find compatible children. Only a single child is supported */
+       for_each_available_child_of_node(of_node, child) {
+               match = of_match_node(pl353_smc_supported_children, child);
+               if (!match) {
+                       dev_warn(&adev->dev, "unsupported child node\n");
+                       continue;
+               }
+               break;
+       }
+       if (!match) {
+               dev_err(&adev->dev, "no matching children\n");
+               goto out_clk_disable;
+       }
+
+       init = match->data;
+       if (init)
+               init(adev, child);
+       of_platform_device_create(child, NULL, &adev->dev);
+
+       return 0;
+
+out_clk_disable:
+       clk_disable_unprepare(pl353_smc->memclk);
+out_clk_dis_aper:
+       clk_disable_unprepare(pl353_smc->aclk);
+
+       return err;
+}
+
+static int pl353_smc_remove(struct amba_device *adev)
+{
+       struct pl353_smc_data *pl353_smc = amba_get_drvdata(adev);
+
+       clk_disable_unprepare(pl353_smc->memclk);
+       clk_disable_unprepare(pl353_smc->aclk);
+
+       return 0;
+}
+
+static const struct amba_id pl353_ids[] = {
+       {
+       .id = 0x00041353,
+       .mask = 0x000fffff,
+       },
+       { 0, 0 },
+};
+MODULE_DEVICE_TABLE(amba, pl353_ids);
+
+static struct amba_driver pl353_smc_driver = {
+       .drv = {
+               .owner = THIS_MODULE,
+               .name = "pl353-smc",
+               .pm = &pl353_smc_dev_pm_ops,
+       },
+       .id_table = pl353_ids,
+       .probe = pl353_smc_probe,
+       .remove = pl353_smc_remove,
+};
+
+module_amba_driver(pl353_smc_driver);
+
+MODULE_AUTHOR("Xilinx, Inc.");
+MODULE_DESCRIPTION("ARM PL353 SMC Driver");
+MODULE_LICENSE("GPL");
index 6d74e499e18dde35f7881bacfba302864afde6b6..34e0b70f5c5fe0b33794342f1faf6f4b2cef3acd 100644 (file)
@@ -6,6 +6,16 @@ config TEGRA_MC
          This driver supports the Memory Controller (MC) hardware found on
          NVIDIA Tegra SoCs.
 
+config TEGRA20_EMC
+       bool "NVIDIA Tegra20 External Memory Controller driver"
+       default y
+       depends on ARCH_TEGRA_2x_SOC
+       help
+         This driver is for the External Memory Controller (EMC) found on
+         Tegra20 chips. The EMC controls the external DRAM on the board.
+         This driver is required to change memory timings / clock rate for
+         external memory.
+
 config TEGRA124_EMC
        bool "NVIDIA Tegra124 External Memory Controller driver"
        default y
index 94ab16ba075bce38d7cacdd1bc21288299600d3c..3971a6b7c4874aa555b3f9a36e1a1837478c4ae3 100644 (file)
@@ -10,5 +10,6 @@ tegra-mc-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210.o
 
 obj-$(CONFIG_TEGRA_MC) += tegra-mc.o
 
+obj-$(CONFIG_TEGRA20_EMC)  += tegra20-emc.o
 obj-$(CONFIG_TEGRA124_EMC) += tegra124-emc.o
 obj-$(CONFIG_ARCH_TEGRA_186_SOC) += tegra186.o
diff --git a/drivers/memory/tegra/tegra20-emc.c b/drivers/memory/tegra/tegra20-emc.c
new file mode 100644 (file)
index 0000000..9ee5bef
--- /dev/null
@@ -0,0 +1,591 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Tegra20 External Memory Controller driver
+ *
+ * Author: Dmitry Osipenko <digetx@gmail.com>
+ */
+
+#include <linux/clk.h>
+#include <linux/completion.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/iopoll.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/sort.h>
+#include <linux/types.h>
+
+#include <soc/tegra/fuse.h>
+
+#define EMC_INTSTATUS                          0x000
+#define EMC_INTMASK                            0x004
+#define EMC_TIMING_CONTROL                     0x028
+#define EMC_RC                                 0x02c
+#define EMC_RFC                                        0x030
+#define EMC_RAS                                        0x034
+#define EMC_RP                                 0x038
+#define EMC_R2W                                        0x03c
+#define EMC_W2R                                        0x040
+#define EMC_R2P                                        0x044
+#define EMC_W2P                                        0x048
+#define EMC_RD_RCD                             0x04c
+#define EMC_WR_RCD                             0x050
+#define EMC_RRD                                        0x054
+#define EMC_REXT                               0x058
+#define EMC_WDV                                        0x05c
+#define EMC_QUSE                               0x060
+#define EMC_QRST                               0x064
+#define EMC_QSAFE                              0x068
+#define EMC_RDV                                        0x06c
+#define EMC_REFRESH                            0x070
+#define EMC_BURST_REFRESH_NUM                  0x074
+#define EMC_PDEX2WR                            0x078
+#define EMC_PDEX2RD                            0x07c
+#define EMC_PCHG2PDEN                          0x080
+#define EMC_ACT2PDEN                           0x084
+#define EMC_AR2PDEN                            0x088
+#define EMC_RW2PDEN                            0x08c
+#define EMC_TXSR                               0x090
+#define EMC_TCKE                               0x094
+#define EMC_TFAW                               0x098
+#define EMC_TRPAB                              0x09c
+#define EMC_TCLKSTABLE                         0x0a0
+#define EMC_TCLKSTOP                           0x0a4
+#define EMC_TREFBW                             0x0a8
+#define EMC_QUSE_EXTRA                         0x0ac
+#define EMC_ODT_WRITE                          0x0b0
+#define EMC_ODT_READ                           0x0b4
+#define EMC_FBIO_CFG5                          0x104
+#define EMC_FBIO_CFG6                          0x114
+#define EMC_AUTO_CAL_INTERVAL                  0x2a8
+#define EMC_CFG_2                              0x2b8
+#define EMC_CFG_DIG_DLL                                0x2bc
+#define EMC_DLL_XFORM_DQS                      0x2c0
+#define EMC_DLL_XFORM_QUSE                     0x2c4
+#define EMC_ZCAL_REF_CNT                       0x2e0
+#define EMC_ZCAL_WAIT_CNT                      0x2e4
+#define EMC_CFG_CLKTRIM_0                      0x2d0
+#define EMC_CFG_CLKTRIM_1                      0x2d4
+#define EMC_CFG_CLKTRIM_2                      0x2d8
+
+#define EMC_CLKCHANGE_REQ_ENABLE               BIT(0)
+#define EMC_CLKCHANGE_PD_ENABLE                        BIT(1)
+#define EMC_CLKCHANGE_SR_ENABLE                        BIT(2)
+
+#define EMC_TIMING_UPDATE                      BIT(0)
+
+#define EMC_REFRESH_OVERFLOW_INT               BIT(3)
+#define EMC_CLKCHANGE_COMPLETE_INT             BIT(4)
+
+static const u16 emc_timing_registers[] = {
+       EMC_RC,
+       EMC_RFC,
+       EMC_RAS,
+       EMC_RP,
+       EMC_R2W,
+       EMC_W2R,
+       EMC_R2P,
+       EMC_W2P,
+       EMC_RD_RCD,
+       EMC_WR_RCD,
+       EMC_RRD,
+       EMC_REXT,
+       EMC_WDV,
+       EMC_QUSE,
+       EMC_QRST,
+       EMC_QSAFE,
+       EMC_RDV,
+       EMC_REFRESH,
+       EMC_BURST_REFRESH_NUM,
+       EMC_PDEX2WR,
+       EMC_PDEX2RD,
+       EMC_PCHG2PDEN,
+       EMC_ACT2PDEN,
+       EMC_AR2PDEN,
+       EMC_RW2PDEN,
+       EMC_TXSR,
+       EMC_TCKE,
+       EMC_TFAW,
+       EMC_TRPAB,
+       EMC_TCLKSTABLE,
+       EMC_TCLKSTOP,
+       EMC_TREFBW,
+       EMC_QUSE_EXTRA,
+       EMC_FBIO_CFG6,
+       EMC_ODT_WRITE,
+       EMC_ODT_READ,
+       EMC_FBIO_CFG5,
+       EMC_CFG_DIG_DLL,
+       EMC_DLL_XFORM_DQS,
+       EMC_DLL_XFORM_QUSE,
+       EMC_ZCAL_REF_CNT,
+       EMC_ZCAL_WAIT_CNT,
+       EMC_AUTO_CAL_INTERVAL,
+       EMC_CFG_CLKTRIM_0,
+       EMC_CFG_CLKTRIM_1,
+       EMC_CFG_CLKTRIM_2,
+};
+
+struct emc_timing {
+       unsigned long rate;
+       u32 data[ARRAY_SIZE(emc_timing_registers)];
+};
+
+struct tegra_emc {
+       struct device *dev;
+       struct completion clk_handshake_complete;
+       struct notifier_block clk_nb;
+       struct clk *backup_clk;
+       struct clk *emc_mux;
+       struct clk *pll_m;
+       struct clk *clk;
+       void __iomem *regs;
+
+       struct emc_timing *timings;
+       unsigned int num_timings;
+};
+
+static irqreturn_t tegra_emc_isr(int irq, void *data)
+{
+       struct tegra_emc *emc = data;
+       u32 intmask = EMC_REFRESH_OVERFLOW_INT | EMC_CLKCHANGE_COMPLETE_INT;
+       u32 status;
+
+       status = readl_relaxed(emc->regs + EMC_INTSTATUS) & intmask;
+       if (!status)
+               return IRQ_NONE;
+
+       /* notify about EMC-CAR handshake completion */
+       if (status & EMC_CLKCHANGE_COMPLETE_INT)
+               complete(&emc->clk_handshake_complete);
+
+       /* notify about HW problem */
+       if (status & EMC_REFRESH_OVERFLOW_INT)
+               dev_err_ratelimited(emc->dev,
+                                   "refresh request overflow timeout\n");
+
+       /* clear interrupts */
+       writel_relaxed(status, emc->regs + EMC_INTSTATUS);
+
+       return IRQ_HANDLED;
+}
+
+static struct emc_timing *tegra_emc_find_timing(struct tegra_emc *emc,
+                                               unsigned long rate)
+{
+       struct emc_timing *timing = NULL;
+       unsigned int i;
+
+       for (i = 0; i < emc->num_timings; i++) {
+               if (emc->timings[i].rate >= rate) {
+                       timing = &emc->timings[i];
+                       break;
+               }
+       }
+
+       if (!timing) {
+               dev_err(emc->dev, "no timing for rate %lu\n", rate);
+               return NULL;
+       }
+
+       return timing;
+}
+
+static int emc_prepare_timing_change(struct tegra_emc *emc, unsigned long rate)
+{
+       struct emc_timing *timing = tegra_emc_find_timing(emc, rate);
+       unsigned int i;
+
+       if (!timing)
+               return -EINVAL;
+
+       dev_dbg(emc->dev, "%s: using timing rate %lu for requested rate %lu\n",
+               __func__, timing->rate, rate);
+
+       /* program shadow registers */
+       for (i = 0; i < ARRAY_SIZE(timing->data); i++)
+               writel_relaxed(timing->data[i],
+                              emc->regs + emc_timing_registers[i]);
+
+       /* wait until programming has settled */
+       readl_relaxed(emc->regs + emc_timing_registers[i - 1]);
+
+       reinit_completion(&emc->clk_handshake_complete);
+
+       return 0;
+}
+
+static int emc_complete_timing_change(struct tegra_emc *emc, bool flush)
+{
+       long timeout;
+
+       dev_dbg(emc->dev, "%s: flush %d\n", __func__, flush);
+
+       if (flush) {
+               /* manually initiate memory timing update */
+               writel_relaxed(EMC_TIMING_UPDATE,
+                              emc->regs + EMC_TIMING_CONTROL);
+               return 0;
+       }
+
+       timeout = wait_for_completion_timeout(&emc->clk_handshake_complete,
+                                             usecs_to_jiffies(100));
+       if (timeout == 0) {
+               dev_err(emc->dev, "EMC-CAR handshake failed\n");
+               return -EIO;
+       } else if (timeout < 0) {
+               dev_err(emc->dev, "failed to wait for EMC-CAR handshake: %ld\n",
+                       timeout);
+               return timeout;
+       }
+
+       return 0;
+}
+
+static int tegra_emc_clk_change_notify(struct notifier_block *nb,
+                                      unsigned long msg, void *data)
+{
+       struct tegra_emc *emc = container_of(nb, struct tegra_emc, clk_nb);
+       struct clk_notifier_data *cnd = data;
+       int err;
+
+       switch (msg) {
+       case PRE_RATE_CHANGE:
+               err = emc_prepare_timing_change(emc, cnd->new_rate);
+               break;
+
+       case ABORT_RATE_CHANGE:
+               err = emc_prepare_timing_change(emc, cnd->old_rate);
+               if (err)
+                       break;
+
+               err = emc_complete_timing_change(emc, true);
+               break;
+
+       case POST_RATE_CHANGE:
+               err = emc_complete_timing_change(emc, false);
+               break;
+
+       default:
+               return NOTIFY_DONE;
+       }
+
+       return notifier_from_errno(err);
+}
+
+static int load_one_timing_from_dt(struct tegra_emc *emc,
+                                  struct emc_timing *timing,
+                                  struct device_node *node)
+{
+       u32 rate;
+       int err;
+
+       if (!of_device_is_compatible(node, "nvidia,tegra20-emc-table")) {
+               dev_err(emc->dev, "incompatible DT node: %pOF\n", node);
+               return -EINVAL;
+       }
+
+       err = of_property_read_u32(node, "clock-frequency", &rate);
+       if (err) {
+               dev_err(emc->dev, "timing %pOF: failed to read rate: %d\n",
+                       node, err);
+               return err;
+       }
+
+       err = of_property_read_u32_array(node, "nvidia,emc-registers",
+                                        timing->data,
+                                        ARRAY_SIZE(emc_timing_registers));
+       if (err) {
+               dev_err(emc->dev,
+                       "timing %pOF: failed to read emc timing data: %d\n",
+                       node, err);
+               return err;
+       }
+
+       /*
+        * The EMC clock rate is twice the bus rate, and the bus rate is
+        * measured in kHz.
+        */
+       timing->rate = rate * 2 * 1000;
+
+       dev_dbg(emc->dev, "%s: %pOF: EMC rate %lu\n",
+               __func__, node, timing->rate);
+
+       return 0;
+}
+
+static int cmp_timings(const void *_a, const void *_b)
+{
+       const struct emc_timing *a = _a;
+       const struct emc_timing *b = _b;
+
+       if (a->rate < b->rate)
+               return -1;
+
+       if (a->rate > b->rate)
+               return 1;
+
+       return 0;
+}
+
+static int tegra_emc_load_timings_from_dt(struct tegra_emc *emc,
+                                         struct device_node *node)
+{
+       struct device_node *child;
+       struct emc_timing *timing;
+       int child_count;
+       int err;
+
+       child_count = of_get_child_count(node);
+       if (!child_count) {
+               dev_err(emc->dev, "no memory timings in DT node: %pOF\n", node);
+               return -EINVAL;
+       }
+
+       emc->timings = devm_kcalloc(emc->dev, child_count, sizeof(*timing),
+                                   GFP_KERNEL);
+       if (!emc->timings)
+               return -ENOMEM;
+
+       emc->num_timings = child_count;
+       timing = emc->timings;
+
+       for_each_child_of_node(node, child) {
+               err = load_one_timing_from_dt(emc, timing++, child);
+               if (err) {
+                       of_node_put(child);
+                       return err;
+               }
+       }
+
+       sort(emc->timings, emc->num_timings, sizeof(*timing), cmp_timings,
+            NULL);
+
+       return 0;
+}
+
+static struct device_node *
+tegra_emc_find_node_by_ram_code(struct device *dev)
+{
+       struct device_node *np;
+       u32 value, ram_code;
+       int err;
+
+       if (!of_property_read_bool(dev->of_node, "nvidia,use-ram-code"))
+               return of_node_get(dev->of_node);
+
+       ram_code = tegra_read_ram_code();
+
+       for (np = of_find_node_by_name(dev->of_node, "emc-tables"); np;
+            np = of_find_node_by_name(np, "emc-tables")) {
+               err = of_property_read_u32(np, "nvidia,ram-code", &value);
+               if (err || value != ram_code) {
+                       of_node_put(np);
+                       continue;
+               }
+
+               return np;
+       }
+
+       dev_err(dev, "no memory timings for RAM code %u found in device tree\n",
+               ram_code);
+
+       return NULL;
+}
+
+static int emc_setup_hw(struct tegra_emc *emc)
+{
+       u32 intmask = EMC_REFRESH_OVERFLOW_INT | EMC_CLKCHANGE_COMPLETE_INT;
+       u32 emc_cfg;
+
+       emc_cfg = readl_relaxed(emc->regs + EMC_CFG_2);
+
+       /*
+        * Depending on a memory type, DRAM should enter either self-refresh
+        * or power-down state on EMC clock change.
+        */
+       if (!(emc_cfg & EMC_CLKCHANGE_PD_ENABLE) &&
+           !(emc_cfg & EMC_CLKCHANGE_SR_ENABLE)) {
+               dev_err(emc->dev,
+                       "bootloader didn't specify DRAM auto-suspend mode\n");
+               return -EINVAL;
+       }
+
+       /* enable EMC and CAR to handshake on PLL divider/source changes */
+       emc_cfg |= EMC_CLKCHANGE_REQ_ENABLE;
+       writel_relaxed(emc_cfg, emc->regs + EMC_CFG_2);
+
+       /* initialize interrupt */
+       writel_relaxed(intmask, emc->regs + EMC_INTMASK);
+       writel_relaxed(intmask, emc->regs + EMC_INTSTATUS);
+
+       return 0;
+}
+
+static int emc_init(struct tegra_emc *emc, unsigned long rate)
+{
+       int err;
+
+       err = clk_set_parent(emc->emc_mux, emc->backup_clk);
+       if (err) {
+               dev_err(emc->dev,
+                       "failed to reparent to backup source: %d\n", err);
+               return err;
+       }
+
+       err = clk_set_rate(emc->pll_m, rate);
+       if (err) {
+               dev_err(emc->dev,
+                       "failed to change pll_m rate: %d\n", err);
+               return err;
+       }
+
+       err = clk_set_parent(emc->emc_mux, emc->pll_m);
+       if (err) {
+               dev_err(emc->dev,
+                       "failed to reparent to pll_m: %d\n", err);
+               return err;
+       }
+
+       err = clk_set_rate(emc->clk, rate);
+       if (err) {
+               dev_err(emc->dev,
+                       "failed to change emc rate: %d\n", err);
+               return err;
+       }
+
+       return 0;
+}
+
+static int tegra_emc_probe(struct platform_device *pdev)
+{
+       struct device_node *np;
+       struct tegra_emc *emc;
+       struct resource *res;
+       int irq, err;
+
+       /* driver has nothing to do in a case of memory timing absence */
+       if (of_get_child_count(pdev->dev.of_node) == 0) {
+               dev_info(&pdev->dev,
+                        "EMC device tree node doesn't have memory timings\n");
+               return 0;
+       }
+
+       irq = platform_get_irq(pdev, 0);
+       if (irq < 0) {
+               dev_err(&pdev->dev, "interrupt not specified\n");
+               dev_err(&pdev->dev, "please update your device tree\n");
+               return irq;
+       }
+
+       np = tegra_emc_find_node_by_ram_code(&pdev->dev);
+       if (!np)
+               return -EINVAL;
+
+       emc = devm_kzalloc(&pdev->dev, sizeof(*emc), GFP_KERNEL);
+       if (!emc) {
+               of_node_put(np);
+               return -ENOMEM;
+       }
+
+       init_completion(&emc->clk_handshake_complete);
+       emc->clk_nb.notifier_call = tegra_emc_clk_change_notify;
+       emc->dev = &pdev->dev;
+
+       err = tegra_emc_load_timings_from_dt(emc, np);
+       of_node_put(np);
+       if (err)
+               return err;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       emc->regs = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(emc->regs))
+               return PTR_ERR(emc->regs);
+
+       err = emc_setup_hw(emc);
+       if (err)
+               return err;
+
+       err = devm_request_irq(&pdev->dev, irq, tegra_emc_isr, 0,
+                              dev_name(&pdev->dev), emc);
+       if (err) {
+               dev_err(&pdev->dev, "failed to request IRQ#%u: %d\n", irq, err);
+               return err;
+       }
+
+       emc->clk = devm_clk_get(&pdev->dev, "emc");
+       if (IS_ERR(emc->clk)) {
+               err = PTR_ERR(emc->clk);
+               dev_err(&pdev->dev, "failed to get emc clock: %d\n", err);
+               return err;
+       }
+
+       emc->pll_m = clk_get_sys(NULL, "pll_m");
+       if (IS_ERR(emc->pll_m)) {
+               err = PTR_ERR(emc->pll_m);
+               dev_err(&pdev->dev, "failed to get pll_m clock: %d\n", err);
+               return err;
+       }
+
+       emc->backup_clk = clk_get_sys(NULL, "pll_p");
+       if (IS_ERR(emc->backup_clk)) {
+               err = PTR_ERR(emc->backup_clk);
+               dev_err(&pdev->dev, "failed to get pll_p clock: %d\n", err);
+               goto put_pll_m;
+       }
+
+       emc->emc_mux = clk_get_parent(emc->clk);
+       if (IS_ERR(emc->emc_mux)) {
+               err = PTR_ERR(emc->emc_mux);
+               dev_err(&pdev->dev, "failed to get emc_mux clock: %d\n", err);
+               goto put_backup;
+       }
+
+       err = clk_notifier_register(emc->clk, &emc->clk_nb);
+       if (err) {
+               dev_err(&pdev->dev, "failed to register clk notifier: %d\n",
+                       err);
+               goto put_backup;
+       }
+
+       /* set DRAM clock rate to maximum */
+       err = emc_init(emc, emc->timings[emc->num_timings - 1].rate);
+       if (err) {
+               dev_err(&pdev->dev, "failed to initialize EMC clock rate: %d\n",
+                       err);
+               goto unreg_notifier;
+       }
+
+       return 0;
+
+unreg_notifier:
+       clk_notifier_unregister(emc->clk, &emc->clk_nb);
+put_backup:
+       clk_put(emc->backup_clk);
+put_pll_m:
+       clk_put(emc->pll_m);
+
+       return err;
+}
+
+static const struct of_device_id tegra_emc_of_match[] = {
+       { .compatible = "nvidia,tegra20-emc", },
+       {},
+};
+
+static struct platform_driver tegra_emc_driver = {
+       .probe = tegra_emc_probe,
+       .driver = {
+               .name = "tegra20-emc",
+               .of_match_table = tegra_emc_of_match,
+               .suppress_bind_attrs = true,
+       },
+};
+
+static int __init tegra_emc_init(void)
+{
+       return platform_driver_register(&tegra_emc_driver);
+}
+subsys_initcall(tegra_emc_init);
index 446166ba0bec43e65d3f041bf16244ebf3d98330..90b686e586c667e381121fa038903ab54099b6c8 100644 (file)
@@ -13,7 +13,7 @@ obj-$(CONFIG_ARCH_GEMINI)     += gemini/
 obj-$(CONFIG_ARCH_MXC)         += imx/
 obj-$(CONFIG_SOC_XWAY)         += lantiq/
 obj-y                          += mediatek/
-obj-$(CONFIG_ARCH_MESON)       += amlogic/
+obj-y                          += amlogic/
 obj-y                          += qcom/
 obj-y                          += renesas/
 obj-$(CONFIG_ARCH_ROCKCHIP)    += rockchip/
index 2f282b47291205a8a4304e0e74d07feda4459c8b..5501ad5650b23c839eef5cb82c6e306a12f9109d 100644 (file)
@@ -7,6 +7,15 @@ config MESON_CANVAS
        help
          Say yes to support the canvas IP for Amlogic SoCs.
 
+config MESON_CLK_MEASURE
+       bool "Amlogic Meson SoC Clock Measure driver"
+       depends on ARCH_MESON || COMPILE_TEST
+       default ARCH_MESON
+       select REGMAP_MMIO
+       help
+         Say yes to support of Measuring a set of internal SoC clocks
+         from the debugfs interface.
+
 config MESON_GX_SOCINFO
        bool "Amlogic Meson GX SoC Information driver"
        depends on ARCH_MESON || COMPILE_TEST
index 0ab16d35ac36dfc9cd8af43c29f62cc3aceac279..bf2d109f61e96eb5ec078ce30672d9684b9c613c 100644 (file)
@@ -1,4 +1,5 @@
 obj-$(CONFIG_MESON_CANVAS) += meson-canvas.o
+obj-$(CONFIG_MESON_CLK_MEASURE) += meson-clk-measure.o
 obj-$(CONFIG_MESON_GX_SOCINFO) += meson-gx-socinfo.o
 obj-$(CONFIG_MESON_GX_PM_DOMAINS) += meson-gx-pwrc-vpu.o
 obj-$(CONFIG_MESON_MX_SOCINFO) += meson-mx-socinfo.o
diff --git a/drivers/soc/amlogic/meson-clk-measure.c b/drivers/soc/amlogic/meson-clk-measure.c
new file mode 100644 (file)
index 0000000..daea191
--- /dev/null
@@ -0,0 +1,350 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2018 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ */
+
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/bitfield.h>
+#include <linux/seq_file.h>
+#include <linux/debugfs.h>
+#include <linux/regmap.h>
+
+#define MSR_CLK_DUTY           0x0
+#define MSR_CLK_REG0           0x4
+#define MSR_CLK_REG1           0x8
+#define MSR_CLK_REG2           0xc
+
+#define MSR_DURATION           GENMASK(15, 0)
+#define MSR_ENABLE             BIT(16)
+#define MSR_CONT               BIT(17) /* continuous measurement */
+#define MSR_INTR               BIT(18) /* interrupts */
+#define MSR_RUN                        BIT(19)
+#define MSR_CLK_SRC            GENMASK(26, 20)
+#define MSR_BUSY               BIT(31)
+
+#define MSR_VAL_MASK           GENMASK(15, 0)
+
+#define DIV_MIN                        32
+#define DIV_STEP               32
+#define DIV_MAX                        640
+
+#define CLK_MSR_MAX            128
+
+struct meson_msr_id {
+       struct meson_msr *priv;
+       unsigned int id;
+       const char *name;
+};
+
+struct meson_msr {
+       struct regmap *regmap;
+       struct meson_msr_id msr_table[CLK_MSR_MAX];
+};
+
+#define CLK_MSR_ID(__id, __name) \
+       [__id] = {.id = __id, .name = __name,}
+
+static struct meson_msr_id clk_msr_m8[CLK_MSR_MAX] = {
+       CLK_MSR_ID(0, "ring_osc_out_ee0"),
+       CLK_MSR_ID(1, "ring_osc_out_ee1"),
+       CLK_MSR_ID(2, "ring_osc_out_ee2"),
+       CLK_MSR_ID(3, "a9_ring_osck"),
+       CLK_MSR_ID(6, "vid_pll"),
+       CLK_MSR_ID(7, "clk81"),
+       CLK_MSR_ID(8, "encp"),
+       CLK_MSR_ID(9, "encl"),
+       CLK_MSR_ID(11, "eth_rmii"),
+       CLK_MSR_ID(13, "amclk"),
+       CLK_MSR_ID(14, "fec_clk_0"),
+       CLK_MSR_ID(15, "fec_clk_1"),
+       CLK_MSR_ID(16, "fec_clk_2"),
+       CLK_MSR_ID(18, "a9_clk_div16"),
+       CLK_MSR_ID(19, "hdmi_sys"),
+       CLK_MSR_ID(20, "rtc_osc_clk_out"),
+       CLK_MSR_ID(21, "i2s_clk_in_src0"),
+       CLK_MSR_ID(22, "clk_rmii_from_pad"),
+       CLK_MSR_ID(23, "hdmi_ch0_tmds"),
+       CLK_MSR_ID(24, "lvds_fifo"),
+       CLK_MSR_ID(26, "sc_clk_int"),
+       CLK_MSR_ID(28, "sar_adc"),
+       CLK_MSR_ID(30, "mpll_clk_test_out"),
+       CLK_MSR_ID(31, "audac_clkpi"),
+       CLK_MSR_ID(32, "vdac"),
+       CLK_MSR_ID(33, "sdhc_rx"),
+       CLK_MSR_ID(34, "sdhc_sd"),
+       CLK_MSR_ID(35, "mali"),
+       CLK_MSR_ID(36, "hdmi_tx_pixel"),
+       CLK_MSR_ID(38, "vdin_meas"),
+       CLK_MSR_ID(39, "pcm_sclk"),
+       CLK_MSR_ID(40, "pcm_mclk"),
+       CLK_MSR_ID(41, "eth_rx_tx"),
+       CLK_MSR_ID(42, "pwm_d"),
+       CLK_MSR_ID(43, "pwm_c"),
+       CLK_MSR_ID(44, "pwm_b"),
+       CLK_MSR_ID(45, "pwm_a"),
+       CLK_MSR_ID(46, "pcm2_sclk"),
+       CLK_MSR_ID(47, "ddr_dpll_pt"),
+       CLK_MSR_ID(48, "pwm_f"),
+       CLK_MSR_ID(49, "pwm_e"),
+       CLK_MSR_ID(59, "hcodec"),
+       CLK_MSR_ID(60, "usb_32k_alt"),
+       CLK_MSR_ID(61, "gpio"),
+       CLK_MSR_ID(62, "vid2_pll"),
+       CLK_MSR_ID(63, "mipi_csi_cfg"),
+};
+
+static struct meson_msr_id clk_msr_gx[CLK_MSR_MAX] = {
+       CLK_MSR_ID(0, "ring_osc_out_ee_0"),
+       CLK_MSR_ID(1, "ring_osc_out_ee_1"),
+       CLK_MSR_ID(2, "ring_osc_out_ee_2"),
+       CLK_MSR_ID(3, "a53_ring_osc"),
+       CLK_MSR_ID(4, "gp0_pll"),
+       CLK_MSR_ID(6, "enci"),
+       CLK_MSR_ID(7, "clk81"),
+       CLK_MSR_ID(8, "encp"),
+       CLK_MSR_ID(9, "encl"),
+       CLK_MSR_ID(10, "vdac"),
+       CLK_MSR_ID(11, "rgmii_tx"),
+       CLK_MSR_ID(12, "pdm"),
+       CLK_MSR_ID(13, "amclk"),
+       CLK_MSR_ID(14, "fec_0"),
+       CLK_MSR_ID(15, "fec_1"),
+       CLK_MSR_ID(16, "fec_2"),
+       CLK_MSR_ID(17, "sys_pll_div16"),
+       CLK_MSR_ID(18, "sys_cpu_div16"),
+       CLK_MSR_ID(19, "hdmitx_sys"),
+       CLK_MSR_ID(20, "rtc_osc_out"),
+       CLK_MSR_ID(21, "i2s_in_src0"),
+       CLK_MSR_ID(22, "eth_phy_ref"),
+       CLK_MSR_ID(23, "hdmi_todig"),
+       CLK_MSR_ID(26, "sc_int"),
+       CLK_MSR_ID(28, "sar_adc"),
+       CLK_MSR_ID(31, "mpll_test_out"),
+       CLK_MSR_ID(32, "vdec"),
+       CLK_MSR_ID(35, "mali"),
+       CLK_MSR_ID(36, "hdmi_tx_pixel"),
+       CLK_MSR_ID(37, "i958"),
+       CLK_MSR_ID(38, "vdin_meas"),
+       CLK_MSR_ID(39, "pcm_sclk"),
+       CLK_MSR_ID(40, "pcm_mclk"),
+       CLK_MSR_ID(41, "eth_rx_or_rmii"),
+       CLK_MSR_ID(42, "mp0_out"),
+       CLK_MSR_ID(43, "fclk_div5"),
+       CLK_MSR_ID(44, "pwm_b"),
+       CLK_MSR_ID(45, "pwm_a"),
+       CLK_MSR_ID(46, "vpu"),
+       CLK_MSR_ID(47, "ddr_dpll_pt"),
+       CLK_MSR_ID(48, "mp1_out"),
+       CLK_MSR_ID(49, "mp2_out"),
+       CLK_MSR_ID(50, "mp3_out"),
+       CLK_MSR_ID(51, "nand_core"),
+       CLK_MSR_ID(52, "sd_emmc_b"),
+       CLK_MSR_ID(53, "sd_emmc_a"),
+       CLK_MSR_ID(55, "vid_pll_div_out"),
+       CLK_MSR_ID(56, "cci"),
+       CLK_MSR_ID(57, "wave420l_c"),
+       CLK_MSR_ID(58, "wave420l_b"),
+       CLK_MSR_ID(59, "hcodec"),
+       CLK_MSR_ID(60, "alt_32k"),
+       CLK_MSR_ID(61, "gpio_msr"),
+       CLK_MSR_ID(62, "hevc"),
+       CLK_MSR_ID(66, "vid_lock"),
+       CLK_MSR_ID(70, "pwm_f"),
+       CLK_MSR_ID(71, "pwm_e"),
+       CLK_MSR_ID(72, "pwm_d"),
+       CLK_MSR_ID(73, "pwm_c"),
+       CLK_MSR_ID(75, "aoclkx2_int"),
+       CLK_MSR_ID(76, "aoclk_int"),
+       CLK_MSR_ID(77, "rng_ring_osc_0"),
+       CLK_MSR_ID(78, "rng_ring_osc_1"),
+       CLK_MSR_ID(79, "rng_ring_osc_2"),
+       CLK_MSR_ID(80, "rng_ring_osc_3"),
+       CLK_MSR_ID(81, "vapb"),
+       CLK_MSR_ID(82, "ge2d"),
+};
+
+static int meson_measure_id(struct meson_msr_id *clk_msr_id,
+                              unsigned int duration)
+{
+       struct meson_msr *priv = clk_msr_id->priv;
+       unsigned int val;
+       int ret;
+
+       regmap_write(priv->regmap, MSR_CLK_REG0, 0);
+
+       /* Set measurement duration */
+       regmap_update_bits(priv->regmap, MSR_CLK_REG0, MSR_DURATION,
+                          FIELD_PREP(MSR_DURATION, duration - 1));
+
+       /* Set ID */
+       regmap_update_bits(priv->regmap, MSR_CLK_REG0, MSR_CLK_SRC,
+                          FIELD_PREP(MSR_CLK_SRC, clk_msr_id->id));
+
+       /* Enable & Start */
+       regmap_update_bits(priv->regmap, MSR_CLK_REG0,
+                          MSR_RUN | MSR_ENABLE,
+                          MSR_RUN | MSR_ENABLE);
+
+       ret = regmap_read_poll_timeout(priv->regmap, MSR_CLK_REG0,
+                                      val, !(val & MSR_BUSY), 10, 10000);
+       if (ret)
+               return ret;
+
+       /* Disable */
+       regmap_update_bits(priv->regmap, MSR_CLK_REG0, MSR_ENABLE, 0);
+
+       /* Get the value in multiple of gate time counts */
+       regmap_read(priv->regmap, MSR_CLK_REG2, &val);
+
+       if (val >= MSR_VAL_MASK)
+               return -EINVAL;
+
+       return DIV_ROUND_CLOSEST_ULL((val & MSR_VAL_MASK) * 1000000ULL,
+                                    duration);
+}
+
+static int meson_measure_best_id(struct meson_msr_id *clk_msr_id,
+                                   unsigned int *precision)
+{
+       unsigned int duration = DIV_MAX;
+       int ret;
+
+       /* Start from max duration and down to min duration */
+       do {
+               ret = meson_measure_id(clk_msr_id, duration);
+               if (ret >= 0)
+                       *precision = (2 * 1000000) / duration;
+               else
+                       duration -= DIV_STEP;
+       } while (duration >= DIV_MIN && ret == -EINVAL);
+
+       return ret;
+}
+
+static int clk_msr_show(struct seq_file *s, void *data)
+{
+       struct meson_msr_id *clk_msr_id = s->private;
+       unsigned int precision = 0;
+       int val;
+
+       val = meson_measure_best_id(clk_msr_id, &precision);
+       if (val < 0)
+               return val;
+
+       seq_printf(s, "%d\t+/-%dHz\n", val, precision);
+
+       return 0;
+}
+DEFINE_SHOW_ATTRIBUTE(clk_msr);
+
+static int clk_msr_summary_show(struct seq_file *s, void *data)
+{
+       struct meson_msr_id *msr_table = s->private;
+       unsigned int precision = 0;
+       int val, i;
+
+       seq_puts(s, "  clock                     rate    precision\n");
+       seq_puts(s, "---------------------------------------------\n");
+
+       for (i = 0 ; i < CLK_MSR_MAX ; ++i) {
+               if (!msr_table[i].name)
+                       continue;
+
+               val = meson_measure_best_id(&msr_table[i], &precision);
+               if (val < 0)
+                       return val;
+
+               seq_printf(s, " %-20s %10d    +/-%dHz\n",
+                          msr_table[i].name, val, precision);
+       }
+
+       return 0;
+}
+DEFINE_SHOW_ATTRIBUTE(clk_msr_summary);
+
+static const struct regmap_config meson_clk_msr_regmap_config = {
+       .reg_bits = 32,
+       .val_bits = 32,
+       .reg_stride = 4,
+       .max_register = MSR_CLK_REG2,
+};
+
+static int meson_msr_probe(struct platform_device *pdev)
+{
+       const struct meson_msr_id *match_data;
+       struct meson_msr *priv;
+       struct resource *res;
+       struct dentry *root, *clks;
+       void __iomem *base;
+       int i;
+
+       priv = devm_kzalloc(&pdev->dev, sizeof(struct meson_msr),
+                           GFP_KERNEL);
+       if (!priv)
+               return -ENOMEM;
+
+       match_data = device_get_match_data(&pdev->dev);
+       if (!match_data) {
+               dev_err(&pdev->dev, "failed to get match data\n");
+               return -ENODEV;
+       }
+
+       memcpy(priv->msr_table, match_data, sizeof(priv->msr_table));
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       base = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(base)) {
+               dev_err(&pdev->dev, "io resource mapping failed\n");
+               return PTR_ERR(base);
+       }
+
+       priv->regmap = devm_regmap_init_mmio(&pdev->dev, base,
+                                            &meson_clk_msr_regmap_config);
+       if (IS_ERR(priv->regmap))
+               return PTR_ERR(priv->regmap);
+
+       root = debugfs_create_dir("meson-clk-msr", NULL);
+       clks = debugfs_create_dir("clks", root);
+
+       debugfs_create_file("measure_summary", 0444, root,
+                           priv->msr_table, &clk_msr_summary_fops);
+
+       for (i = 0 ; i < CLK_MSR_MAX ; ++i) {
+               if (!priv->msr_table[i].name)
+                       continue;
+
+               priv->msr_table[i].priv = priv;
+
+               debugfs_create_file(priv->msr_table[i].name, 0444, clks,
+                                   &priv->msr_table[i], &clk_msr_fops);
+       }
+
+       return 0;
+}
+
+static const struct of_device_id meson_msr_match_table[] = {
+       {
+               .compatible = "amlogic,meson-gx-clk-measure",
+               .data = (void *)clk_msr_gx,
+       },
+       {
+               .compatible = "amlogic,meson8-clk-measure",
+               .data = (void *)clk_msr_m8,
+       },
+       {
+               .compatible = "amlogic,meson8b-clk-measure",
+               .data = (void *)clk_msr_m8,
+       },
+       { /* sentinel */ }
+};
+
+static struct platform_driver meson_msr_driver = {
+       .probe  = meson_msr_probe,
+       .driver = {
+               .name           = "meson_msr",
+               .of_match_table = meson_msr_match_table,
+       },
+};
+builtin_platform_driver(meson_msr_driver);
index 4dd03b099c89358dc0c5bf48b8dd8a7786e031b8..096a83cf0caf33d098580b9b1f844cc534847336 100644 (file)
@@ -66,6 +66,8 @@ static const struct at91_soc __initconst socs[] = {
        AT91_SOC(AT91SAM9XE128_CIDR_MATCH, 0, "at91sam9xe128", "at91sam9xe128"),
        AT91_SOC(AT91SAM9XE256_CIDR_MATCH, 0, "at91sam9xe256", "at91sam9xe256"),
        AT91_SOC(AT91SAM9XE512_CIDR_MATCH, 0, "at91sam9xe512", "at91sam9xe512"),
+       AT91_SOC(SAM9X60_CIDR_MATCH, SAM9X60_EXID_MATCH,
+                "sam9x60", "sam9x60"),
 #endif
 #ifdef CONFIG_SOC_SAMA5
        AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D21CU_EXID_MATCH,
@@ -90,12 +92,20 @@ static const struct at91_soc __initconst socs[] = {
                 "sama5d27c 128MiB SiP", "sama5d2"),
        AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D27C_D5M_EXID_MATCH,
                 "sama5d27c 64MiB SiP", "sama5d2"),
+       AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D27C_LD1G_EXID_MATCH,
+                "sama5d27c 128MiB LPDDR2 SiP", "sama5d2"),
+       AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D27C_LD2G_EXID_MATCH,
+                "sama5d27c 256MiB LPDDR2 SiP", "sama5d2"),
        AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D28CU_EXID_MATCH,
                 "sama5d28", "sama5d2"),
        AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D28CN_EXID_MATCH,
                 "sama5d28", "sama5d2"),
        AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D28C_D1G_EXID_MATCH,
                 "sama5d28c 128MiB SiP", "sama5d2"),
+       AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D28C_LD1G_EXID_MATCH,
+                "sama5d28c 128MiB LPDDR2 SiP", "sama5d2"),
+       AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D28C_LD2G_EXID_MATCH,
+                "sama5d28c 256MiB LPDDR2 SiP", "sama5d2"),
        AT91_SOC(SAMA5D3_CIDR_MATCH, SAMA5D31_EXID_MATCH,
                 "sama5d31", "sama5d3"),
        AT91_SOC(SAMA5D3_CIDR_MATCH, SAMA5D33_EXID_MATCH,
index 94cd5d1ab5027b1dd577b3810bae7724d9208692..ee652e4841a5c38a4081892c6f1f996b35c21311 100644 (file)
@@ -42,6 +42,7 @@ at91_soc_init(const struct at91_soc *socs);
 #define AT91SAM9G45_CIDR_MATCH         0x019b05a0
 #define AT91SAM9X5_CIDR_MATCH          0x019a05a0
 #define AT91SAM9N12_CIDR_MATCH         0x019a07a0
+#define SAM9X60_CIDR_MATCH             0x019b35a0
 
 #define AT91SAM9M11_EXID_MATCH         0x00000001
 #define AT91SAM9M10_EXID_MATCH         0x00000002
@@ -58,6 +59,8 @@ at91_soc_init(const struct at91_soc *socs);
 #define AT91SAM9N12_EXID_MATCH         0x00000006
 #define AT91SAM9CN11_EXID_MATCH                0x00000009
 
+#define SAM9X60_EXID_MATCH             0x00000000
+
 #define AT91SAM9XE128_CIDR_MATCH       0x329973a0
 #define AT91SAM9XE256_CIDR_MATCH       0x329a93a0
 #define AT91SAM9XE512_CIDR_MATCH       0x329aa3a0
@@ -73,9 +76,13 @@ at91_soc_init(const struct at91_soc *socs);
 #define SAMA5D26CU_EXID_MATCH          0x00000012
 #define SAMA5D27C_D1G_EXID_MATCH       0x00000033
 #define SAMA5D27C_D5M_EXID_MATCH       0x00000032
+#define SAMA5D27C_LD1G_EXID_MATCH      0x00000061
+#define SAMA5D27C_LD2G_EXID_MATCH      0x00000062
 #define SAMA5D27CU_EXID_MATCH          0x00000011
 #define SAMA5D27CN_EXID_MATCH          0x00000021
 #define SAMA5D28C_D1G_EXID_MATCH       0x00000013
+#define SAMA5D28C_LD1G_EXID_MATCH      0x00000071
+#define SAMA5D28C_LD2G_EXID_MATCH      0x00000072
 #define SAMA5D28CU_EXID_MATCH          0x00000010
 #define SAMA5D28CN_EXID_MATCH          0x00000020
 
index 14185451901debbd2c6693c908317ad623070ccd..bf9123f727e8035c908d2891c575ff8c3ad10d37 100644 (file)
@@ -31,13 +31,17 @@ static const struct of_device_id brcmstb_machine_match[] = {
 
 bool soc_is_brcmstb(void)
 {
+       const struct of_device_id *match;
        struct device_node *root;
 
        root = of_find_node_by_path("/");
        if (!root)
                return false;
 
-       return of_match_node(brcmstb_machine_match, root) != NULL;
+       match = of_match_node(brcmstb_machine_match, root);
+       of_node_put(root);
+
+       return match != NULL;
 }
 
 u32 brcmstb_get_family_id(void)
index a5577dd5eb0870bccff391f38c69f47c8d708fde..8ee06347447c0dfa3dede7d3164ba584631e7866 100644 (file)
@@ -404,7 +404,7 @@ noinline int brcmstb_pm_s3_finish(void)
 {
        struct brcmstb_s3_params *params = ctrl.s3_params;
        dma_addr_t params_pa = ctrl.s3_params_pa;
-       phys_addr_t reentry = virt_to_phys(&cpu_resume);
+       phys_addr_t reentry = virt_to_phys(&cpu_resume_arm);
        enum bsp_initiate_command cmd;
        u32 flags;
 
index a78dfe0a2b503c3a98e09f48c606f45ea184a513..5d1aacdd84ef345f36820363a2c3b82c8e7c6da1 100644 (file)
@@ -1,8 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0
 /* (C) 2015 Pengutronix, Alexander Aring <aar@pengutronix.de>
- *
- * 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.
  *
  * Authors:
  * Alexander Aring <aar@pengutronix.de>
index a5b86a28f343bb9c90c575310848b94855fcc3b4..2112d18dbb7b91b1cd8c4b44586efcfbf8634a1f 100644 (file)
@@ -1,8 +1,8 @@
 menu "i.MX SoC drivers"
 
-config IMX7_PM_DOMAINS
-       bool "i.MX7 PM domains"
-       depends on SOC_IMX7D || (COMPILE_TEST && OF)
+config IMX_GPCV2_PM_DOMAINS
+       bool "i.MX GPCv2 PM domains"
+       depends on SOC_IMX7D || SOC_IMX8MQ || (COMPILE_TEST && OF)
        depends on PM
        select PM_GENERIC_DOMAINS
        default y if SOC_IMX7D
index aab41a5cc31790fdc00bc362035852e258b9c59c..506a6f3c2b9bdad27f059baabf3656ffbcea7c1b 100644 (file)
@@ -1,2 +1,2 @@
 obj-$(CONFIG_HAVE_IMX_GPC) += gpc.o
-obj-$(CONFIG_IMX7_PM_DOMAINS) += gpcv2.o
+obj-$(CONFIG_IMX_GPCV2_PM_DOMAINS) += gpcv2.o
index aa3729ecaa9ef86291ab685e2a5beafa6371e972..7d14a4b4e82a44f6a3d9da31d46cfb44142de8d7 100644 (file)
@@ -35,7 +35,7 @@
 #define GPU_VPU_PUP_REQ                BIT(1)
 #define GPU_VPU_PDN_REQ                BIT(0)
 
-#define GPC_CLK_MAX            6
+#define GPC_CLK_MAX            7
 
 #define PGC_DOMAIN_FLAG_NO_PD          BIT(0)
 
index e7b5994fee9d0b4d1f1908509b5b49ecfea453a7..8b4f48a2ca57a1c083331e575492d37973cd278d 100644 (file)
 #include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
 #include <dt-bindings/power/imx7-power.h>
+#include <dt-bindings/power/imx8mq-power.h>
 
 #define GPC_LPCR_A_CORE_BSC                    0x000
 
 #define GPC_PGC_CPU_MAPPING            0x0ec
-#define USB_HSIC_PHY_A_CORE_DOMAIN             BIT(6)
-#define USB_OTG2_PHY_A_CORE_DOMAIN             BIT(5)
-#define USB_OTG1_PHY_A_CORE_DOMAIN             BIT(4)
-#define PCIE_PHY_A_CORE_DOMAIN         BIT(3)
-#define MIPI_PHY_A_CORE_DOMAIN         BIT(2)
+
+#define IMX7_USB_HSIC_PHY_A_CORE_DOMAIN                BIT(6)
+#define IMX7_USB_OTG2_PHY_A_CORE_DOMAIN                BIT(5)
+#define IMX7_USB_OTG1_PHY_A_CORE_DOMAIN                BIT(4)
+#define IMX7_PCIE_PHY_A_CORE_DOMAIN            BIT(3)
+#define IMX7_MIPI_PHY_A_CORE_DOMAIN            BIT(2)
+
+#define IMX8M_PCIE2_A53_DOMAIN                 BIT(15)
+#define IMX8M_MIPI_CSI2_A53_DOMAIN             BIT(14)
+#define IMX8M_MIPI_CSI1_A53_DOMAIN             BIT(13)
+#define IMX8M_DISP_A53_DOMAIN                  BIT(12)
+#define IMX8M_HDMI_A53_DOMAIN                  BIT(11)
+#define IMX8M_VPU_A53_DOMAIN                   BIT(10)
+#define IMX8M_GPU_A53_DOMAIN                   BIT(9)
+#define IMX8M_DDR2_A53_DOMAIN                  BIT(8)
+#define IMX8M_DDR1_A53_DOMAIN                  BIT(7)
+#define IMX8M_OTG2_A53_DOMAIN                  BIT(5)
+#define IMX8M_OTG1_A53_DOMAIN                  BIT(4)
+#define IMX8M_PCIE1_A53_DOMAIN                 BIT(3)
+#define IMX8M_MIPI_A53_DOMAIN                  BIT(2)
 
 #define GPC_PU_PGC_SW_PUP_REQ          0x0f8
 #define GPC_PU_PGC_SW_PDN_REQ          0x104
-#define USB_HSIC_PHY_SW_Pxx_REQ                BIT(4)
-#define USB_OTG2_PHY_SW_Pxx_REQ                BIT(3)
-#define USB_OTG1_PHY_SW_Pxx_REQ                BIT(2)
-#define PCIE_PHY_SW_Pxx_REQ            BIT(1)
-#define MIPI_PHY_SW_Pxx_REQ            BIT(0)
+
+#define IMX7_USB_HSIC_PHY_SW_Pxx_REQ           BIT(4)
+#define IMX7_USB_OTG2_PHY_SW_Pxx_REQ           BIT(3)
+#define IMX7_USB_OTG1_PHY_SW_Pxx_REQ           BIT(2)
+#define IMX7_PCIE_PHY_SW_Pxx_REQ               BIT(1)
+#define IMX7_MIPI_PHY_SW_Pxx_REQ               BIT(0)
+
+#define IMX8M_PCIE2_SW_Pxx_REQ                 BIT(13)
+#define IMX8M_MIPI_CSI2_SW_Pxx_REQ             BIT(12)
+#define IMX8M_MIPI_CSI1_SW_Pxx_REQ             BIT(11)
+#define IMX8M_DISP_SW_Pxx_REQ                  BIT(10)
+#define IMX8M_HDMI_SW_Pxx_REQ                  BIT(9)
+#define IMX8M_VPU_SW_Pxx_REQ                   BIT(8)
+#define IMX8M_GPU_SW_Pxx_REQ                   BIT(7)
+#define IMX8M_DDR2_SW_Pxx_REQ                  BIT(6)
+#define IMX8M_DDR1_SW_Pxx_REQ                  BIT(5)
+#define IMX8M_OTG2_SW_Pxx_REQ                  BIT(3)
+#define IMX8M_OTG1_SW_Pxx_REQ                  BIT(2)
+#define IMX8M_PCIE1_SW_Pxx_REQ                 BIT(1)
+#define IMX8M_MIPI_SW_Pxx_REQ                  BIT(0)
 
 #define GPC_M4_PU_PDN_FLG              0x1bc
 
  * GPC_PGC memory map are incorrect, below offset
  * values are from design RTL.
  */
-#define PGC_MIPI                       16
-#define PGC_PCIE                       17
-#define PGC_USB_HSIC                   20
+#define IMX7_PGC_MIPI                  16
+#define IMX7_PGC_PCIE                  17
+#define IMX7_PGC_USB_HSIC              20
+
+#define IMX8M_PGC_MIPI                 16
+#define IMX8M_PGC_PCIE1                        17
+#define IMX8M_PGC_OTG1                 18
+#define IMX8M_PGC_OTG2                 19
+#define IMX8M_PGC_DDR1                 21
+#define IMX8M_PGC_GPU                  23
+#define IMX8M_PGC_VPU                  24
+#define IMX8M_PGC_DISP                 26
+#define IMX8M_PGC_MIPI_CSI1            27
+#define IMX8M_PGC_MIPI_CSI2            28
+#define IMX8M_PGC_PCIE2                        29
+
 #define GPC_PGC_CTRL(n)                        (0x800 + (n) * 0x40)
 #define GPC_PGC_SR(n)                  (GPC_PGC_CTRL(n) + 0xc)
 
@@ -67,6 +111,7 @@ struct imx_pgc_domain {
 struct imx_pgc_domain_data {
        const struct imx_pgc_domain *domains;
        size_t domains_num;
+       const struct regmap_access_table *reg_access_table;
 };
 
 static int imx_gpc_pu_pgc_sw_pxx_req(struct generic_pm_domain *genpd,
@@ -166,11 +211,11 @@ static const struct imx_pgc_domain imx7_pgc_domains[] = {
                        .name      = "mipi-phy",
                },
                .bits  = {
-                       .pxx = MIPI_PHY_SW_Pxx_REQ,
-                       .map = MIPI_PHY_A_CORE_DOMAIN,
+                       .pxx = IMX7_MIPI_PHY_SW_Pxx_REQ,
+                       .map = IMX7_MIPI_PHY_A_CORE_DOMAIN,
                },
                .voltage   = 1000000,
-               .pgc       = PGC_MIPI,
+               .pgc       = IMX7_PGC_MIPI,
        },
 
        [IMX7_POWER_DOMAIN_PCIE_PHY] = {
@@ -178,11 +223,11 @@ static const struct imx_pgc_domain imx7_pgc_domains[] = {
                        .name      = "pcie-phy",
                },
                .bits  = {
-                       .pxx = PCIE_PHY_SW_Pxx_REQ,
-                       .map = PCIE_PHY_A_CORE_DOMAIN,
+                       .pxx = IMX7_PCIE_PHY_SW_Pxx_REQ,
+                       .map = IMX7_PCIE_PHY_A_CORE_DOMAIN,
                },
                .voltage   = 1000000,
-               .pgc       = PGC_PCIE,
+               .pgc       = IMX7_PGC_PCIE,
        },
 
        [IMX7_POWER_DOMAIN_USB_HSIC_PHY] = {
@@ -190,17 +235,195 @@ static const struct imx_pgc_domain imx7_pgc_domains[] = {
                        .name      = "usb-hsic-phy",
                },
                .bits  = {
-                       .pxx = USB_HSIC_PHY_SW_Pxx_REQ,
-                       .map = USB_HSIC_PHY_A_CORE_DOMAIN,
+                       .pxx = IMX7_USB_HSIC_PHY_SW_Pxx_REQ,
+                       .map = IMX7_USB_HSIC_PHY_A_CORE_DOMAIN,
                },
                .voltage   = 1200000,
-               .pgc       = PGC_USB_HSIC,
+               .pgc       = IMX7_PGC_USB_HSIC,
        },
 };
 
+static const struct regmap_range imx7_yes_ranges[] = {
+               regmap_reg_range(GPC_LPCR_A_CORE_BSC,
+                                GPC_M4_PU_PDN_FLG),
+               regmap_reg_range(GPC_PGC_CTRL(IMX7_PGC_MIPI),
+                                GPC_PGC_SR(IMX7_PGC_MIPI)),
+               regmap_reg_range(GPC_PGC_CTRL(IMX7_PGC_PCIE),
+                                GPC_PGC_SR(IMX7_PGC_PCIE)),
+               regmap_reg_range(GPC_PGC_CTRL(IMX7_PGC_USB_HSIC),
+                                GPC_PGC_SR(IMX7_PGC_USB_HSIC)),
+};
+
+static const struct regmap_access_table imx7_access_table = {
+       .yes_ranges     = imx7_yes_ranges,
+       .n_yes_ranges   = ARRAY_SIZE(imx7_yes_ranges),
+};
+
 static const struct imx_pgc_domain_data imx7_pgc_domain_data = {
        .domains = imx7_pgc_domains,
        .domains_num = ARRAY_SIZE(imx7_pgc_domains),
+       .reg_access_table = &imx7_access_table,
+};
+
+static const struct imx_pgc_domain imx8m_pgc_domains[] = {
+       [IMX8M_POWER_DOMAIN_MIPI] = {
+               .genpd = {
+                       .name      = "mipi",
+               },
+               .bits  = {
+                       .pxx = IMX8M_MIPI_SW_Pxx_REQ,
+                       .map = IMX8M_MIPI_A53_DOMAIN,
+               },
+               .pgc       = IMX8M_PGC_MIPI,
+       },
+
+       [IMX8M_POWER_DOMAIN_PCIE1] = {
+               .genpd = {
+                       .name = "pcie1",
+               },
+               .bits  = {
+                       .pxx = IMX8M_PCIE1_SW_Pxx_REQ,
+                       .map = IMX8M_PCIE1_A53_DOMAIN,
+               },
+               .pgc   = IMX8M_PGC_PCIE1,
+       },
+
+       [IMX8M_POWER_DOMAIN_USB_OTG1] = {
+               .genpd = {
+                       .name = "usb-otg1",
+               },
+               .bits  = {
+                       .pxx = IMX8M_OTG1_SW_Pxx_REQ,
+                       .map = IMX8M_OTG1_A53_DOMAIN,
+               },
+               .pgc   = IMX8M_PGC_OTG1,
+       },
+
+       [IMX8M_POWER_DOMAIN_USB_OTG2] = {
+               .genpd = {
+                       .name = "usb-otg2",
+               },
+               .bits  = {
+                       .pxx = IMX8M_OTG2_SW_Pxx_REQ,
+                       .map = IMX8M_OTG2_A53_DOMAIN,
+               },
+               .pgc   = IMX8M_PGC_OTG2,
+       },
+
+       [IMX8M_POWER_DOMAIN_DDR1] = {
+               .genpd = {
+                       .name = "ddr1",
+               },
+               .bits  = {
+                       .pxx = IMX8M_DDR1_SW_Pxx_REQ,
+                       .map = IMX8M_DDR2_A53_DOMAIN,
+               },
+               .pgc   = IMX8M_PGC_DDR1,
+       },
+
+       [IMX8M_POWER_DOMAIN_GPU] = {
+               .genpd = {
+                       .name = "gpu",
+               },
+               .bits  = {
+                       .pxx = IMX8M_GPU_SW_Pxx_REQ,
+                       .map = IMX8M_GPU_A53_DOMAIN,
+               },
+               .pgc   = IMX8M_PGC_GPU,
+       },
+
+       [IMX8M_POWER_DOMAIN_VPU] = {
+               .genpd = {
+                       .name = "vpu",
+               },
+               .bits  = {
+                       .pxx = IMX8M_VPU_SW_Pxx_REQ,
+                       .map = IMX8M_VPU_A53_DOMAIN,
+               },
+               .pgc   = IMX8M_PGC_VPU,
+       },
+
+       [IMX8M_POWER_DOMAIN_DISP] = {
+               .genpd = {
+                       .name = "disp",
+               },
+               .bits  = {
+                       .pxx = IMX8M_DISP_SW_Pxx_REQ,
+                       .map = IMX8M_DISP_A53_DOMAIN,
+               },
+               .pgc   = IMX8M_PGC_DISP,
+       },
+
+       [IMX8M_POWER_DOMAIN_MIPI_CSI1] = {
+               .genpd = {
+                       .name = "mipi-csi1",
+               },
+               .bits  = {
+                       .pxx = IMX8M_MIPI_CSI1_SW_Pxx_REQ,
+                       .map = IMX8M_MIPI_CSI1_A53_DOMAIN,
+               },
+               .pgc   = IMX8M_PGC_MIPI_CSI1,
+       },
+
+       [IMX8M_POWER_DOMAIN_MIPI_CSI2] = {
+               .genpd = {
+                       .name = "mipi-csi2",
+               },
+               .bits  = {
+                       .pxx = IMX8M_MIPI_CSI2_SW_Pxx_REQ,
+                       .map = IMX8M_MIPI_CSI2_A53_DOMAIN,
+               },
+               .pgc   = IMX8M_PGC_MIPI_CSI2,
+       },
+
+       [IMX8M_POWER_DOMAIN_PCIE2] = {
+               .genpd = {
+                       .name = "pcie2",
+               },
+               .bits  = {
+                       .pxx = IMX8M_PCIE2_SW_Pxx_REQ,
+                       .map = IMX8M_PCIE2_A53_DOMAIN,
+               },
+               .pgc   = IMX8M_PGC_PCIE2,
+       },
+};
+
+static const struct regmap_range imx8m_yes_ranges[] = {
+               regmap_reg_range(GPC_LPCR_A_CORE_BSC,
+                                GPC_M4_PU_PDN_FLG),
+               regmap_reg_range(GPC_PGC_CTRL(IMX8M_PGC_MIPI),
+                                GPC_PGC_SR(IMX8M_PGC_MIPI)),
+               regmap_reg_range(GPC_PGC_CTRL(IMX8M_PGC_PCIE1),
+                                GPC_PGC_SR(IMX8M_PGC_PCIE1)),
+               regmap_reg_range(GPC_PGC_CTRL(IMX8M_PGC_OTG1),
+                                GPC_PGC_SR(IMX8M_PGC_OTG1)),
+               regmap_reg_range(GPC_PGC_CTRL(IMX8M_PGC_OTG2),
+                                GPC_PGC_SR(IMX8M_PGC_OTG2)),
+               regmap_reg_range(GPC_PGC_CTRL(IMX8M_PGC_DDR1),
+                                GPC_PGC_SR(IMX8M_PGC_DDR1)),
+               regmap_reg_range(GPC_PGC_CTRL(IMX8M_PGC_GPU),
+                                GPC_PGC_SR(IMX8M_PGC_GPU)),
+               regmap_reg_range(GPC_PGC_CTRL(IMX8M_PGC_VPU),
+                                GPC_PGC_SR(IMX8M_PGC_VPU)),
+               regmap_reg_range(GPC_PGC_CTRL(IMX8M_PGC_DISP),
+                                GPC_PGC_SR(IMX8M_PGC_DISP)),
+               regmap_reg_range(GPC_PGC_CTRL(IMX8M_PGC_MIPI_CSI1),
+                                GPC_PGC_SR(IMX8M_PGC_MIPI_CSI1)),
+               regmap_reg_range(GPC_PGC_CTRL(IMX8M_PGC_MIPI_CSI2),
+                                GPC_PGC_SR(IMX8M_PGC_MIPI_CSI2)),
+               regmap_reg_range(GPC_PGC_CTRL(IMX8M_PGC_PCIE2),
+                                GPC_PGC_SR(IMX8M_PGC_PCIE2)),
+};
+
+static const struct regmap_access_table imx8m_access_table = {
+       .yes_ranges     = imx8m_yes_ranges,
+       .n_yes_ranges   = ARRAY_SIZE(imx8m_yes_ranges),
+};
+
+static const struct imx_pgc_domain_data imx8m_pgc_domain_data = {
+       .domains = imx8m_pgc_domains,
+       .domains_num = ARRAY_SIZE(imx8m_pgc_domains),
+       .reg_access_table = &imx8m_access_table,
 };
 
 static int imx_pgc_domain_probe(struct platform_device *pdev)
@@ -217,7 +440,7 @@ static int imx_pgc_domain_probe(struct platform_device *pdev)
                                dev_err(domain->dev, "Failed to get domain's regulator\n");
                        return PTR_ERR(domain->regulator);
                }
-       } else {
+       } else if (domain->voltage) {
                regulator_set_voltage(domain->regulator,
                                      domain->voltage, domain->voltage);
        }
@@ -265,27 +488,15 @@ builtin_platform_driver(imx_pgc_domain_driver)
 
 static int imx_gpcv2_probe(struct platform_device *pdev)
 {
-       static const struct imx_pgc_domain_data *domain_data;
-       static const struct regmap_range yes_ranges[] = {
-               regmap_reg_range(GPC_LPCR_A_CORE_BSC,
-                                GPC_M4_PU_PDN_FLG),
-               regmap_reg_range(GPC_PGC_CTRL(PGC_MIPI),
-                                GPC_PGC_SR(PGC_MIPI)),
-               regmap_reg_range(GPC_PGC_CTRL(PGC_PCIE),
-                                GPC_PGC_SR(PGC_PCIE)),
-               regmap_reg_range(GPC_PGC_CTRL(PGC_USB_HSIC),
-                                GPC_PGC_SR(PGC_USB_HSIC)),
-       };
-       static const struct regmap_access_table access_table = {
-               .yes_ranges     = yes_ranges,
-               .n_yes_ranges   = ARRAY_SIZE(yes_ranges),
-       };
-       static const struct regmap_config regmap_config = {
+       const struct imx_pgc_domain_data *domain_data =
+                       of_device_get_match_data(&pdev->dev);
+
+       struct regmap_config regmap_config = {
                .reg_bits       = 32,
                .val_bits       = 32,
                .reg_stride     = 4,
-               .rd_table       = &access_table,
-               .wr_table       = &access_table,
+               .rd_table       = domain_data->reg_access_table,
+               .wr_table       = domain_data->reg_access_table,
                .max_register   = SZ_4K,
        };
        struct device *dev = &pdev->dev;
@@ -313,8 +524,6 @@ static int imx_gpcv2_probe(struct platform_device *pdev)
                return ret;
        }
 
-       domain_data = of_device_get_match_data(&pdev->dev);
-
        for_each_child_of_node(pgc_np, np) {
                struct platform_device *pd_pdev;
                struct imx_pgc_domain *domain;
@@ -372,6 +581,7 @@ static int imx_gpcv2_probe(struct platform_device *pdev)
 
 static const struct of_device_id imx_gpcv2_dt_ids[] = {
        { .compatible = "fsl,imx7d-gpc", .data = &imx7_pgc_domain_data, },
+       { .compatible = "fsl,imx8mq-gpc", .data = &imx8m_pgc_domain_data, },
        { }
 };
 
index a7d0667338f225fe9574132f6c51fb98c354279a..17bd7590464fd661c2932e14ca92d24e4349b33f 100644 (file)
@@ -4,6 +4,18 @@
 menu "MediaTek SoC drivers"
        depends on ARCH_MEDIATEK || COMPILE_TEST
 
+config MTK_CMDQ
+       tristate "MediaTek CMDQ Support"
+       depends on ARCH_MEDIATEK || COMPILE_TEST
+       select MAILBOX
+       select MTK_CMDQ_MBOX
+       select MTK_INFRACFG
+       help
+         Say yes here to add support for the MediaTek Command Queue (CMDQ)
+         driver. The CMDQ is used to help read/write registers with critical
+         time limitation, such as updating display configuration during the
+         vblank.
+
 config MTK_INFRACFG
        bool "MediaTek INFRACFG Support"
        select REGMAP
index 12998b08819e083bfed09b592b03d263dbed24b2..64ce5eeaba32d9dc3a5b3751e7d39f35279456ef 100644 (file)
@@ -1,3 +1,4 @@
+obj-$(CONFIG_MTK_CMDQ) += mtk-cmdq-helper.o
 obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o
 obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
 obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c b/drivers/soc/mediatek/mtk-cmdq-helper.c
new file mode 100644 (file)
index 0000000..ff9fef5
--- /dev/null
@@ -0,0 +1,300 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (c) 2018 MediaTek Inc.
+
+#include <linux/completion.h>
+#include <linux/errno.h>
+#include <linux/dma-mapping.h>
+#include <linux/module.h>
+#include <linux/mailbox_controller.h>
+#include <linux/soc/mediatek/mtk-cmdq.h>
+
+#define CMDQ_ARG_A_WRITE_MASK  0xffff
+#define CMDQ_WRITE_ENABLE_MASK BIT(0)
+#define CMDQ_EOC_IRQ_EN                BIT(0)
+#define CMDQ_EOC_CMD           ((u64)((CMDQ_CODE_EOC << CMDQ_OP_CODE_SHIFT)) \
+                               << 32 | CMDQ_EOC_IRQ_EN)
+
+static void cmdq_client_timeout(struct timer_list *t)
+{
+       struct cmdq_client *client = from_timer(client, t, timer);
+
+       dev_err(client->client.dev, "cmdq timeout!\n");
+}
+
+struct cmdq_client *cmdq_mbox_create(struct device *dev, int index, u32 timeout)
+{
+       struct cmdq_client *client;
+
+       client = kzalloc(sizeof(*client), GFP_KERNEL);
+       if (!client)
+               return (struct cmdq_client *)-ENOMEM;
+
+       client->timeout_ms = timeout;
+       if (timeout != CMDQ_NO_TIMEOUT) {
+               spin_lock_init(&client->lock);
+               timer_setup(&client->timer, cmdq_client_timeout, 0);
+       }
+       client->pkt_cnt = 0;
+       client->client.dev = dev;
+       client->client.tx_block = false;
+       client->chan = mbox_request_channel(&client->client, index);
+
+       if (IS_ERR(client->chan)) {
+               long err;
+
+               dev_err(dev, "failed to request channel\n");
+               err = PTR_ERR(client->chan);
+               kfree(client);
+
+               return ERR_PTR(err);
+       }
+
+       return client;
+}
+EXPORT_SYMBOL(cmdq_mbox_create);
+
+void cmdq_mbox_destroy(struct cmdq_client *client)
+{
+       if (client->timeout_ms != CMDQ_NO_TIMEOUT) {
+               spin_lock(&client->lock);
+               del_timer_sync(&client->timer);
+               spin_unlock(&client->lock);
+       }
+       mbox_free_channel(client->chan);
+       kfree(client);
+}
+EXPORT_SYMBOL(cmdq_mbox_destroy);
+
+struct cmdq_pkt *cmdq_pkt_create(struct cmdq_client *client, size_t size)
+{
+       struct cmdq_pkt *pkt;
+       struct device *dev;
+       dma_addr_t dma_addr;
+
+       pkt = kzalloc(sizeof(*pkt), GFP_KERNEL);
+       if (!pkt)
+               return ERR_PTR(-ENOMEM);
+       pkt->va_base = kzalloc(size, GFP_KERNEL);
+       if (!pkt->va_base) {
+               kfree(pkt);
+               return ERR_PTR(-ENOMEM);
+       }
+       pkt->buf_size = size;
+       pkt->cl = (void *)client;
+
+       dev = client->chan->mbox->dev;
+       dma_addr = dma_map_single(dev, pkt->va_base, pkt->buf_size,
+                                 DMA_TO_DEVICE);
+       if (dma_mapping_error(dev, dma_addr)) {
+               dev_err(dev, "dma map failed, size=%u\n", (u32)(u64)size);
+               kfree(pkt->va_base);
+               kfree(pkt);
+               return ERR_PTR(-ENOMEM);
+       }
+
+       pkt->pa_base = dma_addr;
+
+       return pkt;
+}
+EXPORT_SYMBOL(cmdq_pkt_create);
+
+void cmdq_pkt_destroy(struct cmdq_pkt *pkt)
+{
+       struct cmdq_client *client = (struct cmdq_client *)pkt->cl;
+
+       dma_unmap_single(client->chan->mbox->dev, pkt->pa_base, pkt->buf_size,
+                        DMA_TO_DEVICE);
+       kfree(pkt->va_base);
+       kfree(pkt);
+}
+EXPORT_SYMBOL(cmdq_pkt_destroy);
+
+static int cmdq_pkt_append_command(struct cmdq_pkt *pkt, enum cmdq_code code,
+                                  u32 arg_a, u32 arg_b)
+{
+       u64 *cmd_ptr;
+
+       if (unlikely(pkt->cmd_buf_size + CMDQ_INST_SIZE > pkt->buf_size)) {
+               /*
+                * In the case of allocated buffer size (pkt->buf_size) is used
+                * up, the real required size (pkt->cmdq_buf_size) is still
+                * increased, so that the user knows how much memory should be
+                * ultimately allocated after appending all commands and
+                * flushing the command packet. Therefor, the user can call
+                * cmdq_pkt_create() again with the real required buffer size.
+                */
+               pkt->cmd_buf_size += CMDQ_INST_SIZE;
+               WARN_ONCE(1, "%s: buffer size %u is too small !\n",
+                       __func__, (u32)pkt->buf_size);
+               return -ENOMEM;
+       }
+       cmd_ptr = pkt->va_base + pkt->cmd_buf_size;
+       (*cmd_ptr) = (u64)((code << CMDQ_OP_CODE_SHIFT) | arg_a) << 32 | arg_b;
+       pkt->cmd_buf_size += CMDQ_INST_SIZE;
+
+       return 0;
+}
+
+int cmdq_pkt_write(struct cmdq_pkt *pkt, u32 value, u32 subsys, u32 offset)
+{
+       u32 arg_a = (offset & CMDQ_ARG_A_WRITE_MASK) |
+                   (subsys << CMDQ_SUBSYS_SHIFT);
+
+       return cmdq_pkt_append_command(pkt, CMDQ_CODE_WRITE, arg_a, value);
+}
+EXPORT_SYMBOL(cmdq_pkt_write);
+
+int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u32 value,
+                       u32 subsys, u32 offset, u32 mask)
+{
+       u32 offset_mask = offset;
+       int err = 0;
+
+       if (mask != 0xffffffff) {
+               err = cmdq_pkt_append_command(pkt, CMDQ_CODE_MASK, 0, ~mask);
+               offset_mask |= CMDQ_WRITE_ENABLE_MASK;
+       }
+       err |= cmdq_pkt_write(pkt, value, subsys, offset_mask);
+
+       return err;
+}
+EXPORT_SYMBOL(cmdq_pkt_write_mask);
+
+int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u32 event)
+{
+       u32 arg_b;
+
+       if (event >= CMDQ_MAX_EVENT)
+               return -EINVAL;
+
+       /*
+        * WFE arg_b
+        * bit 0-11: wait value
+        * bit 15: 1 - wait, 0 - no wait
+        * bit 16-27: update value
+        * bit 31: 1 - update, 0 - no update
+        */
+       arg_b = CMDQ_WFE_UPDATE | CMDQ_WFE_WAIT | CMDQ_WFE_WAIT_VALUE;
+
+       return cmdq_pkt_append_command(pkt, CMDQ_CODE_WFE, event, arg_b);
+}
+EXPORT_SYMBOL(cmdq_pkt_wfe);
+
+int cmdq_pkt_clear_event(struct cmdq_pkt *pkt, u32 event)
+{
+       if (event >= CMDQ_MAX_EVENT)
+               return -EINVAL;
+
+       return cmdq_pkt_append_command(pkt, CMDQ_CODE_WFE, event,
+                                      CMDQ_WFE_UPDATE);
+}
+EXPORT_SYMBOL(cmdq_pkt_clear_event);
+
+static int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
+{
+       int err;
+
+       /* insert EOC and generate IRQ for each command iteration */
+       err = cmdq_pkt_append_command(pkt, CMDQ_CODE_EOC, 0, CMDQ_EOC_IRQ_EN);
+
+       /* JUMP to end */
+       err |= cmdq_pkt_append_command(pkt, CMDQ_CODE_JUMP, 0, CMDQ_JUMP_PASS);
+
+       return err;
+}
+
+static void cmdq_pkt_flush_async_cb(struct cmdq_cb_data data)
+{
+       struct cmdq_pkt *pkt = (struct cmdq_pkt *)data.data;
+       struct cmdq_task_cb *cb = &pkt->cb;
+       struct cmdq_client *client = (struct cmdq_client *)pkt->cl;
+
+       if (client->timeout_ms != CMDQ_NO_TIMEOUT) {
+               unsigned long flags = 0;
+
+               spin_lock_irqsave(&client->lock, flags);
+               if (--client->pkt_cnt == 0)
+                       del_timer(&client->timer);
+               else
+                       mod_timer(&client->timer, jiffies +
+                                 msecs_to_jiffies(client->timeout_ms));
+               spin_unlock_irqrestore(&client->lock, flags);
+       }
+
+       dma_sync_single_for_cpu(client->chan->mbox->dev, pkt->pa_base,
+                               pkt->cmd_buf_size, DMA_TO_DEVICE);
+       if (cb->cb) {
+               data.data = cb->data;
+               cb->cb(data);
+       }
+}
+
+int cmdq_pkt_flush_async(struct cmdq_pkt *pkt, cmdq_async_flush_cb cb,
+                        void *data)
+{
+       int err;
+       unsigned long flags = 0;
+       struct cmdq_client *client = (struct cmdq_client *)pkt->cl;
+
+       err = cmdq_pkt_finalize(pkt);
+       if (err < 0)
+               return err;
+
+       pkt->cb.cb = cb;
+       pkt->cb.data = data;
+       pkt->async_cb.cb = cmdq_pkt_flush_async_cb;
+       pkt->async_cb.data = pkt;
+
+       dma_sync_single_for_device(client->chan->mbox->dev, pkt->pa_base,
+                                  pkt->cmd_buf_size, DMA_TO_DEVICE);
+
+       if (client->timeout_ms != CMDQ_NO_TIMEOUT) {
+               spin_lock_irqsave(&client->lock, flags);
+               if (client->pkt_cnt++ == 0)
+                       mod_timer(&client->timer, jiffies +
+                                 msecs_to_jiffies(client->timeout_ms));
+               spin_unlock_irqrestore(&client->lock, flags);
+       }
+
+       mbox_send_message(client->chan, pkt);
+       /* We can send next packet immediately, so just call txdone. */
+       mbox_client_txdone(client->chan, 0);
+
+       return 0;
+}
+EXPORT_SYMBOL(cmdq_pkt_flush_async);
+
+struct cmdq_flush_completion {
+       struct completion cmplt;
+       bool err;
+};
+
+static void cmdq_pkt_flush_cb(struct cmdq_cb_data data)
+{
+       struct cmdq_flush_completion *cmplt;
+
+       cmplt = (struct cmdq_flush_completion *)data.data;
+       if (data.sta != CMDQ_CB_NORMAL)
+               cmplt->err = true;
+       else
+               cmplt->err = false;
+       complete(&cmplt->cmplt);
+}
+
+int cmdq_pkt_flush(struct cmdq_pkt *pkt)
+{
+       struct cmdq_flush_completion cmplt;
+       int err;
+
+       init_completion(&cmplt.cmplt);
+       err = cmdq_pkt_flush_async(pkt, cmdq_pkt_flush_cb, &cmplt);
+       if (err < 0)
+               return err;
+       wait_for_completion(&cmplt.cmplt);
+
+       return cmplt.err ? -EFAULT : 0;
+}
+EXPORT_SYMBOL(cmdq_pkt_flush);
+
+MODULE_LICENSE("GPL v2");
index 684cb51694d1ff7a917b6883d5d00847698570d3..fcbf8a2e40806415f14dd4eae2d78ced55cc8e1c 100644 (file)
@@ -75,11 +75,6 @@ config QCOM_QMI_HELPERS
        tristate
        depends on ARCH_QCOM || COMPILE_TEST
        depends on NET
-       help
-         Helper library for handling QMI encoded messages.  QMI encoded
-         messages are used in communication between the majority of QRTR
-         clients and this helpers provide the common functionality needed for
-         doing this from a kernel driver.
 
 config QCOM_RMTFS_MEM
        tristate "Qualcomm Remote Filesystem memory driver"
index a6f646295f0678d27e8a2526ce6f283b4cff1555..c701b3b010f13b90615f3b62790bb81ef70c2f93 100644 (file)
@@ -101,8 +101,7 @@ static bool cmd_db_magic_matches(const struct cmd_db_header *header)
 
 static struct cmd_db_header *cmd_db_header;
 
-
-static inline void *rsc_to_entry_header(struct rsc_hdr *hdr)
+static inline const void *rsc_to_entry_header(const struct rsc_hdr *hdr)
 {
        u16 offset = le16_to_cpu(hdr->header_offset);
 
@@ -110,7 +109,7 @@ static inline void *rsc_to_entry_header(struct rsc_hdr *hdr)
 }
 
 static inline void *
-rsc_offset(struct rsc_hdr *hdr, struct entry_header *ent)
+rsc_offset(const struct rsc_hdr *hdr, const struct entry_header *ent)
 {
        u16 offset = le16_to_cpu(hdr->data_offset);
        u16 loffset = le16_to_cpu(ent->offset);
@@ -134,11 +133,11 @@ int cmd_db_ready(void)
 }
 EXPORT_SYMBOL(cmd_db_ready);
 
-static int cmd_db_get_header(const char *id, struct entry_header *eh,
-                            struct rsc_hdr *rh)
+static int cmd_db_get_header(const char *id, const struct entry_header **eh,
+                            const struct rsc_hdr **rh)
 {
-       struct rsc_hdr *rsc_hdr;
-       struct entry_header *ent;
+       const struct rsc_hdr *rsc_hdr;
+       const struct entry_header *ent;
        int ret, i, j;
        u8 query[8];
 
@@ -146,9 +145,6 @@ static int cmd_db_get_header(const char *id, struct entry_header *eh,
        if (ret)
                return ret;
 
-       if (!eh || !rh)
-               return -EINVAL;
-
        /* Pad out query string to same length as in DB */
        strncpy(query, id, sizeof(query));
 
@@ -159,14 +155,13 @@ static int cmd_db_get_header(const char *id, struct entry_header *eh,
 
                ent = rsc_to_entry_header(rsc_hdr);
                for (j = 0; j < le16_to_cpu(rsc_hdr->cnt); j++, ent++) {
-                       if (memcmp(ent->id, query, sizeof(ent->id)) == 0)
-                               break;
-               }
-
-               if (j < le16_to_cpu(rsc_hdr->cnt)) {
-                       memcpy(eh, ent, sizeof(*ent));
-                       memcpy(rh, rsc_hdr, sizeof(*rh));
-                       return 0;
+                       if (memcmp(ent->id, query, sizeof(ent->id)) == 0) {
+                               if (eh)
+                                       *eh = ent;
+                               if (rh)
+                                       *rh = rsc_hdr;
+                               return 0;
+                       }
                }
        }
 
@@ -186,68 +181,39 @@ static int cmd_db_get_header(const char *id, struct entry_header *eh,
 u32 cmd_db_read_addr(const char *id)
 {
        int ret;
-       struct entry_header ent;
-       struct rsc_hdr rsc_hdr;
+       const struct entry_header *ent;
 
-       ret = cmd_db_get_header(id, &ent, &rsc_hdr);
+       ret = cmd_db_get_header(id, &ent, NULL);
 
-       return ret < 0 ? 0 : le32_to_cpu(ent.addr);
+       return ret < 0 ? 0 : le32_to_cpu(ent->addr);
 }
 EXPORT_SYMBOL(cmd_db_read_addr);
 
 /**
  * cmd_db_read_aux_data() - Query command db for aux data.
  *
- *  @id: Resource to retrieve AUX Data on.
- *  @data: Data buffer to copy returned aux data to. Returns size on NULL
- *  @len: Caller provides size of data buffer passed in.
+ *  @id: Resource to retrieve AUX Data on
+ *  @len: size of data buffer returned
  *
- *  Return: size of data on success, errno otherwise
+ *  Return: pointer to data on success, error pointer otherwise
  */
-int cmd_db_read_aux_data(const char *id, u8 *data, size_t len)
+const void *cmd_db_read_aux_data(const char *id, size_t *len)
 {
        int ret;
-       struct entry_header ent;
-       struct rsc_hdr rsc_hdr;
-       u16 ent_len;
-
-       if (!data)
-               return -EINVAL;
+       const struct entry_header *ent;
+       const struct rsc_hdr *rsc_hdr;
 
        ret = cmd_db_get_header(id, &ent, &rsc_hdr);
        if (ret)
-               return ret;
+               return ERR_PTR(ret);
 
-       ent_len = le16_to_cpu(ent.len);
-       if (len < ent_len)
-               return -EINVAL;
-
-       len = min_t(u16, ent_len, len);
-       memcpy(data, rsc_offset(&rsc_hdr, &ent), len);
+       if (len)
+               *len = le16_to_cpu(ent->len);
 
-       return len;
+       return rsc_offset(rsc_hdr, ent);
 }
 EXPORT_SYMBOL(cmd_db_read_aux_data);
 
-/**
- * cmd_db_read_aux_data_len - Get the length of the auxiliary data stored in DB.
- *
- * @id: Resource to retrieve AUX Data.
- *
- * Return: size on success, 0 on error
- */
-size_t cmd_db_read_aux_data_len(const char *id)
-{
-       int ret;
-       struct entry_header ent;
-       struct rsc_hdr rsc_hdr;
-
-       ret = cmd_db_get_header(id, &ent, &rsc_hdr);
-
-       return ret < 0 ? 0 : le16_to_cpu(ent.len);
-}
-EXPORT_SYMBOL(cmd_db_read_aux_data_len);
-
 /**
  * cmd_db_read_slave_id - Get the slave ID for a given resource address
  *
@@ -258,15 +224,14 @@ EXPORT_SYMBOL(cmd_db_read_aux_data_len);
 enum cmd_db_hw_type cmd_db_read_slave_id(const char *id)
 {
        int ret;
-       struct entry_header ent;
-       struct rsc_hdr rsc_hdr;
+       const struct entry_header *ent;
        u32 addr;
 
-       ret = cmd_db_get_header(id, &ent, &rsc_hdr);
+       ret = cmd_db_get_header(id, &ent, NULL);
        if (ret < 0)
                return CMD_DB_HW_INVALID;
 
-       addr = le32_to_cpu(ent.addr);
+       addr = le32_to_cpu(ent->addr);
        return (addr >> SLAVE_ID_SHIFT) & SLAVE_ID_MASK;
 }
 EXPORT_SYMBOL(cmd_db_read_slave_id);
index 192ca761b2cb3a1f6c7615b3e179c94b0e1be51c..80667f7be52c54ce85429b5c8915f5615a0ce5b2 100644 (file)
@@ -95,7 +95,8 @@ EXPORT_SYMBOL_GPL(llcc_slice_getd);
  */
 void llcc_slice_putd(struct llcc_slice_desc *desc)
 {
-       kfree(desc);
+       if (!IS_ERR_OR_NULL(desc))
+               kfree(desc);
 }
 EXPORT_SYMBOL_GPL(llcc_slice_putd);
 
@@ -142,6 +143,9 @@ int llcc_slice_activate(struct llcc_slice_desc *desc)
        int ret;
        u32 act_ctrl_val;
 
+       if (IS_ERR_OR_NULL(desc))
+               return -EINVAL;
+
        mutex_lock(&drv_data->lock);
        if (test_bit(desc->slice_id, drv_data->bitmap)) {
                mutex_unlock(&drv_data->lock);
@@ -176,6 +180,9 @@ int llcc_slice_deactivate(struct llcc_slice_desc *desc)
        u32 act_ctrl_val;
        int ret;
 
+       if (IS_ERR_OR_NULL(desc))
+               return -EINVAL;
+
        mutex_lock(&drv_data->lock);
        if (!test_bit(desc->slice_id, drv_data->bitmap)) {
                mutex_unlock(&drv_data->lock);
@@ -203,6 +210,9 @@ EXPORT_SYMBOL_GPL(llcc_slice_deactivate);
  */
 int llcc_get_slice_id(struct llcc_slice_desc *desc)
 {
+       if (IS_ERR_OR_NULL(desc))
+               return -EINVAL;
+
        return desc->slice_id;
 }
 EXPORT_SYMBOL_GPL(llcc_get_slice_id);
@@ -213,6 +223,9 @@ EXPORT_SYMBOL_GPL(llcc_get_slice_id);
  */
 size_t llcc_get_slice_size(struct llcc_slice_desc *desc)
 {
+       if (IS_ERR_OR_NULL(desc))
+               return 0;
+
        return desc->slice_size;
 }
 EXPORT_SYMBOL_GPL(llcc_get_slice_size);
@@ -360,5 +373,5 @@ int qcom_llcc_probe(struct platform_device *pdev,
        return ret;
 }
 EXPORT_SYMBOL_GPL(qcom_llcc_probe);
-
 MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Qualcomm Last Level Cache Controller");
index ee89ffb6dde84cacc0f37a82918461b8b20eb206..6b8ef01472e98af95df2053ab60160a5ac2391b0 100644 (file)
@@ -215,6 +215,16 @@ static void geni_se_io_init(void __iomem *base)
        writel_relaxed(FORCE_DEFAULT, base + GENI_FORCE_DEFAULT_REG);
 }
 
+static void geni_se_irq_clear(struct geni_se *se)
+{
+       writel_relaxed(0, se->base + SE_GSI_EVENT_EN);
+       writel_relaxed(0xffffffff, se->base + SE_GENI_M_IRQ_CLEAR);
+       writel_relaxed(0xffffffff, se->base + SE_GENI_S_IRQ_CLEAR);
+       writel_relaxed(0xffffffff, se->base + SE_DMA_TX_IRQ_CLR);
+       writel_relaxed(0xffffffff, se->base + SE_DMA_RX_IRQ_CLR);
+       writel_relaxed(0xffffffff, se->base + SE_IRQ_EN);
+}
+
 /**
  * geni_se_init() - Initialize the GENI serial engine
  * @se:                Pointer to the concerned serial engine.
@@ -228,6 +238,7 @@ void geni_se_init(struct geni_se *se, u32 rx_wm, u32 rx_rfr)
 {
        u32 val;
 
+       geni_se_irq_clear(se);
        geni_se_io_init(se->base);
        geni_se_io_set_mode(se->base);
 
@@ -249,12 +260,7 @@ static void geni_se_select_fifo_mode(struct geni_se *se)
        u32 proto = geni_se_read_proto(se);
        u32 val;
 
-       writel_relaxed(0, se->base + SE_GSI_EVENT_EN);
-       writel_relaxed(0xffffffff, se->base + SE_GENI_M_IRQ_CLEAR);
-       writel_relaxed(0xffffffff, se->base + SE_GENI_S_IRQ_CLEAR);
-       writel_relaxed(0xffffffff, se->base + SE_DMA_TX_IRQ_CLR);
-       writel_relaxed(0xffffffff, se->base + SE_DMA_RX_IRQ_CLR);
-       writel_relaxed(0xffffffff, se->base + SE_IRQ_EN);
+       geni_se_irq_clear(se);
 
        val = readl_relaxed(se->base + SE_GENI_M_IRQ_EN);
        if (proto != GENI_SE_UART) {
@@ -277,12 +283,7 @@ static void geni_se_select_dma_mode(struct geni_se *se)
 {
        u32 val;
 
-       writel_relaxed(0, se->base + SE_GSI_EVENT_EN);
-       writel_relaxed(0xffffffff, se->base + SE_GENI_M_IRQ_CLEAR);
-       writel_relaxed(0xffffffff, se->base + SE_GENI_S_IRQ_CLEAR);
-       writel_relaxed(0xffffffff, se->base + SE_DMA_TX_IRQ_CLR);
-       writel_relaxed(0xffffffff, se->base + SE_DMA_RX_IRQ_CLR);
-       writel_relaxed(0xffffffff, se->base + SE_IRQ_EN);
+       geni_se_irq_clear(se);
 
        val = readl_relaxed(se->base + SE_GENI_DMA_MODE_EN);
        val |= GENI_DMA_MODE_EN;
index 938ca41c56cdc794cd7bbc25409e8350668f0295..c239a28e503f93fd56935c6e9a865f4e64117df2 100644 (file)
@@ -318,7 +318,7 @@ int qmi_txn_init(struct qmi_handle *qmi, struct qmi_txn *txn,
        txn->dest = c_struct;
 
        mutex_lock(&qmi->txn_lock);
-       ret = idr_alloc_cyclic(&qmi->txns, txn, 0, INT_MAX, GFP_KERNEL);
+       ret = idr_alloc_cyclic(&qmi->txns, txn, 0, U16_MAX, GFP_KERNEL);
        if (ret < 0)
                pr_err("failed to allocate transaction id\n");
 
index 93517ed833558cd6962443ea9d085bc776f75c0d..b8e63724a49d5a9b81acfd01fb50fc6d61310763 100644 (file)
@@ -227,6 +227,7 @@ static const struct of_device_id qcom_smd_rpm_of_match[] = {
        { .compatible = "qcom,rpm-msm8974" },
        { .compatible = "qcom,rpm-msm8996" },
        { .compatible = "qcom,rpm-msm8998" },
+       { .compatible = "qcom,rpm-qcs404" },
        {}
 };
 MODULE_DEVICE_TABLE(of, qcom_smd_rpm_of_match);
index d7f7928e3c071b450aa8d88f7cb00e78abbdc042..e0533beb50fd7063b44e858ce2ad2e832a1a0d60 100644 (file)
@@ -28,7 +28,6 @@ static const struct rcar_sysc_area r8a77965_areas[] __initconst = {
        { "a2vc1",      0x3c0, 1, R8A77965_PD_A2VC1,    R8A77965_PD_A3VC },
        { "3dg-a",      0x100, 0, R8A77965_PD_3DG_A,    R8A77965_PD_ALWAYS_ON },
        { "3dg-b",      0x100, 1, R8A77965_PD_3DG_B,    R8A77965_PD_3DG_A },
-       { "a3ir",       0x180, 0, R8A77965_PD_A3IR,     R8A77965_PD_ALWAYS_ON },
 };
 
 const struct rcar_sysc_info r8a77965_sysc_info __initconst = {
index 35b30d6a8958a063cb04e7976bd87ae5a09c5720..280c48b80f24042479a9c07d262555109f6e82ed 100644 (file)
@@ -20,12 +20,11 @@ static const struct rcar_sysc_area r8a77970_areas[] __initconst = {
          PD_CPU_NOCR },
        { "ca53-cpu1",  0x200, 1, R8A77970_PD_CA53_CPU1, R8A77970_PD_CA53_SCU,
          PD_CPU_NOCR },
-       { "cr7",        0x240, 0, R8A77970_PD_CR7,      R8A77970_PD_ALWAYS_ON },
        { "a3ir",       0x180, 0, R8A77970_PD_A3IR,     R8A77970_PD_ALWAYS_ON },
        { "a2ir0",      0x400, 0, R8A77970_PD_A2IR0,    R8A77970_PD_A3IR },
        { "a2ir1",      0x400, 1, R8A77970_PD_A2IR1,    R8A77970_PD_A3IR },
-       { "a2ir2",      0x400, 2, R8A77970_PD_A2IR2,    R8A77970_PD_A3IR },
-       { "a2ir3",      0x400, 3, R8A77970_PD_A2IR3,    R8A77970_PD_A3IR },
+       { "a2dp",       0x400, 2, R8A77970_PD_A2DP,     R8A77970_PD_A3IR },
+       { "a2cn",       0x400, 3, R8A77970_PD_A2CN,     R8A77970_PD_A3IR },
        { "a2sc0",      0x400, 4, R8A77970_PD_A2SC0,    R8A77970_PD_A3IR },
        { "a2sc1",      0x400, 5, R8A77970_PD_A2SC1,    R8A77970_PD_A3IR },
 };
index 9265fb525ef342281546683ff2d0dcf13e335f25..a8dbe55e8ba82d7e40d6c2cdf58fa26796834513 100644 (file)
@@ -38,12 +38,12 @@ static const struct rcar_sysc_area r8a77980_areas[] __initconst = {
        { "a2sc2",      0x400, 8, R8A77980_PD_A2SC2,    R8A77980_PD_A3IR },
        { "a2sc3",      0x400, 9, R8A77980_PD_A2SC3,    R8A77980_PD_A3IR },
        { "a2sc4",      0x400, 10, R8A77980_PD_A2SC4,   R8A77980_PD_A3IR },
-       { "a2pd0",      0x400, 11, R8A77980_PD_A2PD0,   R8A77980_PD_A3IR },
-       { "a2pd1",      0x400, 12, R8A77980_PD_A2PD1,   R8A77980_PD_A3IR },
+       { "a2dp0",      0x400, 11, R8A77980_PD_A2DP0,   R8A77980_PD_A3IR },
+       { "a2dp1",      0x400, 12, R8A77980_PD_A2DP1,   R8A77980_PD_A3IR },
        { "a2cn",       0x400, 13, R8A77980_PD_A2CN,    R8A77980_PD_A3IR },
-       { "a3vip",      0x2c0, 0, R8A77980_PD_A3VIP,    R8A77980_PD_ALWAYS_ON },
-       { "a3vip1",     0x300, 0, R8A77980_PD_A3VIP1,   R8A77980_PD_A3VIP },
-       { "a3vip2",     0x280, 0, R8A77980_PD_A3VIP2,   R8A77980_PD_A3VIP },
+       { "a3vip0",     0x2c0, 0, R8A77980_PD_A3VIP0,   R8A77980_PD_ALWAYS_ON },
+       { "a3vip1",     0x300, 0, R8A77980_PD_A3VIP1,   R8A77980_PD_ALWAYS_ON },
+       { "a3vip2",     0x280, 0, R8A77980_PD_A3VIP2,   R8A77980_PD_ALWAYS_ON },
 };
 
 const struct rcar_sysc_info r8a77980_sysc_info __initconst = {
index 15579ebc5ed2059dbace28ba6137614e0a4c81e7..664b244eb1dd9d95fabe3305334784f69213c90c 100644 (file)
@@ -28,19 +28,6 @@ static struct rcar_sysc_area r8a77990_areas[] __initdata = {
        { "3dg-b",      0x100, 1, R8A77990_PD_3DG_B,    R8A77990_PD_3DG_A },
 };
 
-static void __init rcar_sysc_fix_parent(struct rcar_sysc_area *areas,
-                                       unsigned int num_areas, u8 id,
-                                       int new_parent)
-{
-       unsigned int i;
-
-       for (i = 0; i < num_areas; i++)
-               if (areas[i].isr_bit == id) {
-                       areas[i].parent = new_parent;
-                       return;
-               }
-}
-
 /* Fixups for R-Car E3 ES1.0 revision */
 static const struct soc_device_attribute r8a77990[] __initconst = {
        { .soc_id = "r8a77990", .revision = "ES1.0" },
@@ -50,12 +37,10 @@ static const struct soc_device_attribute r8a77990[] __initconst = {
 static int __init r8a77990_sysc_init(void)
 {
        if (soc_device_match(r8a77990)) {
-               rcar_sysc_fix_parent(r8a77990_areas,
-                                    ARRAY_SIZE(r8a77990_areas),
-                                    R8A77990_PD_3DG_A, R8A77990_PD_3DG_B);
-               rcar_sysc_fix_parent(r8a77990_areas,
-                                    ARRAY_SIZE(r8a77990_areas),
-                                    R8A77990_PD_3DG_B, R8A77990_PD_ALWAYS_ON);
+               /* Fix incorrect 3DG hierarchy */
+               swap(r8a77990_areas[7], r8a77990_areas[8]);
+               r8a77990_areas[7].parent = R8A77990_PD_ALWAYS_ON;
+               r8a77990_areas[8].parent = R8A77990_PD_3DG_B;
        }
 
        return 0;
index af53363eda0374ceeaaa22d362f2078539f64588..0c80fab4f8de6bc85f573006f43a62406d23aeb9 100644 (file)
@@ -105,6 +105,15 @@ static int rcar_sysc_power(const struct rcar_sysc_ch *sysc_ch, bool on)
 
        spin_lock_irqsave(&rcar_sysc_lock, flags);
 
+       /*
+        * The interrupt source needs to be enabled, but masked, to prevent the
+        * CPU from receiving it.
+        */
+       iowrite32(ioread32(rcar_sysc_base + SYSCIMR) | isr_mask,
+                 rcar_sysc_base + SYSCIMR);
+       iowrite32(ioread32(rcar_sysc_base + SYSCIER) | isr_mask,
+                 rcar_sysc_base + SYSCIER);
+
        iowrite32(isr_mask, rcar_sysc_base + SYSCISCR);
 
        /* Submit power shutoff or resume request until it was accepted */
@@ -146,16 +155,6 @@ static int rcar_sysc_power(const struct rcar_sysc_ch *sysc_ch, bool on)
        return ret;
 }
 
-static int rcar_sysc_power_down(const struct rcar_sysc_ch *sysc_ch)
-{
-       return rcar_sysc_power(sysc_ch, false);
-}
-
-static int rcar_sysc_power_up(const struct rcar_sysc_ch *sysc_ch)
-{
-       return rcar_sysc_power(sysc_ch, true);
-}
-
 static bool rcar_sysc_power_is_off(const struct rcar_sysc_ch *sysc_ch)
 {
        unsigned int st;
@@ -184,7 +183,7 @@ static int rcar_sysc_pd_power_off(struct generic_pm_domain *genpd)
        struct rcar_sysc_pd *pd = to_rcar_pd(genpd);
 
        pr_debug("%s: %s\n", __func__, genpd->name);
-       return rcar_sysc_power_down(&pd->ch);
+       return rcar_sysc_power(&pd->ch, false);
 }
 
 static int rcar_sysc_pd_power_on(struct generic_pm_domain *genpd)
@@ -192,7 +191,7 @@ static int rcar_sysc_pd_power_on(struct generic_pm_domain *genpd)
        struct rcar_sysc_pd *pd = to_rcar_pd(genpd);
 
        pr_debug("%s: %s\n", __func__, genpd->name);
-       return rcar_sysc_power_up(&pd->ch);
+       return rcar_sysc_power(&pd->ch, true);
 }
 
 static bool has_cpg_mstp;
@@ -252,7 +251,7 @@ static int __init rcar_sysc_pd_setup(struct rcar_sysc_pd *pd)
                goto finalize;
        }
 
-       rcar_sysc_power_up(&pd->ch);
+       rcar_sysc_power(&pd->ch, true);
 
 finalize:
        error = pm_genpd_init(genpd, gov, false);
@@ -334,7 +333,6 @@ static int __init rcar_sysc_pd_init(void)
        const struct of_device_id *match;
        struct rcar_pm_domains *domains;
        struct device_node *np;
-       u32 syscier, syscimr;
        void __iomem *base;
        unsigned int i;
        int error;
@@ -373,27 +371,6 @@ static int __init rcar_sysc_pd_init(void)
        domains->onecell_data.num_domains = ARRAY_SIZE(domains->domains);
        rcar_sysc_onecell_data = &domains->onecell_data;
 
-       for (i = 0, syscier = 0; i < info->num_areas; i++)
-               syscier |= BIT(info->areas[i].isr_bit);
-
-       /*
-        * Mask all interrupt sources to prevent the CPU from receiving them.
-        * Make sure not to clear reserved bits that were set before.
-        */
-       syscimr = ioread32(base + SYSCIMR);
-       syscimr |= syscier;
-       pr_debug("%pOF: syscimr = 0x%08x\n", np, syscimr);
-       iowrite32(syscimr, base + SYSCIMR);
-
-       /*
-        * SYSC needs all interrupt sources enabled to control power.
-        */
-       pr_debug("%pOF: syscier = 0x%08x\n", np, syscier);
-       iowrite32(syscier, base + SYSCIER);
-
-       /*
-        * First, create all PM domains
-        */
        for (i = 0; i < info->num_areas; i++) {
                const struct rcar_sysc_area *area = &info->areas[i];
                struct rcar_sysc_pd *pd;
@@ -421,22 +398,17 @@ static int __init rcar_sysc_pd_init(void)
                        goto out_put;
 
                domains->domains[area->isr_bit] = &pd->genpd;
-       }
 
-       /*
-        * Second, link all PM domains to their parents
-        */
-       for (i = 0; i < info->num_areas; i++) {
-               const struct rcar_sysc_area *area = &info->areas[i];
-
-               if (!area->name || area->parent < 0)
+               if (area->parent < 0)
                        continue;
 
                error = pm_genpd_add_subdomain(domains->domains[area->parent],
-                                              domains->domains[area->isr_bit]);
-               if (error)
+                                              &pd->genpd);
+               if (error) {
                        pr_warn("Failed to add PM subdomain %s to parent %u\n",
                                area->name, area->parent);
+                       goto out_put;
+               }
        }
 
        error = of_genpd_add_provider_onecell(np, &domains->onecell_data);
@@ -478,8 +450,7 @@ static int rcar_sysc_power_cpu(unsigned int idx, bool on)
                if (!(pd->flags & PD_CPU) || pd->ch.chan_bit != idx)
                        continue;
 
-               return on ? rcar_sysc_power_up(&pd->ch)
-                         : rcar_sysc_power_down(&pd->ch);
+               return rcar_sysc_power(&pd->ch, on);
        }
 
        return -ENOENT;
index 6f86a726bb45c1b1e8cd1227b7231b28d3ca8e0f..847c7c482b269f7d456c42ec74cb81712c7db041 100644 (file)
@@ -21,7 +21,9 @@
 #include <linux/mfd/syscon.h>
 #include <dt-bindings/power/px30-power.h>
 #include <dt-bindings/power/rk3036-power.h>
+#include <dt-bindings/power/rk3066-power.h>
 #include <dt-bindings/power/rk3128-power.h>
+#include <dt-bindings/power/rk3188-power.h>
 #include <dt-bindings/power/rk3228-power.h>
 #include <dt-bindings/power/rk3288-power.h>
 #include <dt-bindings/power/rk3328-power.h>
@@ -737,6 +739,14 @@ static const struct rockchip_domain_info rk3036_pm_domains[] = {
        [RK3036_PD_SYS]         = DOMAIN_RK3036(8, 22, 29, false),
 };
 
+static const struct rockchip_domain_info rk3066_pm_domains[] = {
+       [RK3066_PD_GPU]         = DOMAIN(9, 9, 3, 24, 29, false),
+       [RK3066_PD_VIDEO]       = DOMAIN(8, 8, 4, 23, 28, false),
+       [RK3066_PD_VIO]         = DOMAIN(7, 7, 5, 22, 27, false),
+       [RK3066_PD_PERI]        = DOMAIN(6, 6, 2, 25, 30, false),
+       [RK3066_PD_CPU]         = DOMAIN(-1, 5, 1, 26, 31, false),
+};
+
 static const struct rockchip_domain_info rk3128_pm_domains[] = {
        [RK3128_PD_CORE]        = DOMAIN_RK3288(0, 0, 4, false),
        [RK3128_PD_MSCH]        = DOMAIN_RK3288(-1, -1, 6, true),
@@ -745,6 +755,14 @@ static const struct rockchip_domain_info rk3128_pm_domains[] = {
        [RK3128_PD_GPU]         = DOMAIN_RK3288(1, 1, 3, false),
 };
 
+static const struct rockchip_domain_info rk3188_pm_domains[] = {
+       [RK3188_PD_GPU]         = DOMAIN(9, 9, 3, 24, 29, false),
+       [RK3188_PD_VIDEO]       = DOMAIN(8, 8, 4, 23, 28, false),
+       [RK3188_PD_VIO]         = DOMAIN(7, 7, 5, 22, 27, false),
+       [RK3188_PD_PERI]        = DOMAIN(6, 6, 2, 25, 30, false),
+       [RK3188_PD_CPU]         = DOMAIN(5, 5, 1, 26, 31, false),
+};
+
 static const struct rockchip_domain_info rk3228_pm_domains[] = {
        [RK3228_PD_CORE]        = DOMAIN_RK3036(0, 0, 16, true),
        [RK3228_PD_MSCH]        = DOMAIN_RK3036(1, 1, 17, true),
@@ -846,6 +864,17 @@ static const struct rockchip_pmu_info rk3036_pmu = {
        .domain_info = rk3036_pm_domains,
 };
 
+static const struct rockchip_pmu_info rk3066_pmu = {
+       .pwr_offset = 0x08,
+       .status_offset = 0x0c,
+       .req_offset = 0x38, /* PMU_MISC_CON1 */
+       .idle_offset = 0x0c,
+       .ack_offset = 0x0c,
+
+       .num_domains = ARRAY_SIZE(rk3066_pm_domains),
+       .domain_info = rk3066_pm_domains,
+};
+
 static const struct rockchip_pmu_info rk3128_pmu = {
        .pwr_offset = 0x04,
        .status_offset = 0x08,
@@ -857,6 +886,17 @@ static const struct rockchip_pmu_info rk3128_pmu = {
        .domain_info = rk3128_pm_domains,
 };
 
+static const struct rockchip_pmu_info rk3188_pmu = {
+       .pwr_offset = 0x08,
+       .status_offset = 0x0c,
+       .req_offset = 0x38, /* PMU_MISC_CON1 */
+       .idle_offset = 0x0c,
+       .ack_offset = 0x0c,
+
+       .num_domains = ARRAY_SIZE(rk3188_pm_domains),
+       .domain_info = rk3188_pm_domains,
+};
+
 static const struct rockchip_pmu_info rk3228_pmu = {
        .req_offset = 0x40c,
        .idle_offset = 0x488,
@@ -948,10 +988,18 @@ static const struct of_device_id rockchip_pm_domain_dt_match[] = {
                .compatible = "rockchip,rk3036-power-controller",
                .data = (void *)&rk3036_pmu,
        },
+       {
+               .compatible = "rockchip,rk3066-power-controller",
+               .data = (void *)&rk3066_pmu,
+       },
        {
                .compatible = "rockchip,rk3128-power-controller",
                .data = (void *)&rk3128_pmu,
        },
+       {
+               .compatible = "rockchip,rk3188-power-controller",
+               .data = (void *)&rk3188_pmu,
+       },
        {
                .compatible = "rockchip,rk3228-power-controller",
                .data = (void *)&rk3228_pmu,
index b4b0f3480bd36f4ee9662ef10628a4f12b5c52c3..1b0d50f3634935cbfe50dcf7b11ba484f4bfcd50 100644 (file)
@@ -155,17 +155,7 @@ static int sunxi_sram_show(struct seq_file *s, void *data)
        return 0;
 }
 
-static int sunxi_sram_open(struct inode *inode, struct file *file)
-{
-       return single_open(file, sunxi_sram_show, inode->i_private);
-}
-
-static const struct file_operations sunxi_sram_fops = {
-       .open = sunxi_sram_open,
-       .read = seq_read,
-       .llseek = seq_lseek,
-       .release = single_release,
-};
+DEFINE_SHOW_ATTRIBUTE(sunxi_sram);
 
 static inline struct sunxi_sram_desc *to_sram_desc(const struct sunxi_sram_data *data)
 {
@@ -300,6 +290,10 @@ static const struct sunxi_sramc_variant sun4i_a10_sramc_variant = {
        /* Nothing special */
 };
 
+static const struct sunxi_sramc_variant sun8i_h3_sramc_variant = {
+       .has_emac_clock = true,
+};
+
 static const struct sunxi_sramc_variant sun50i_a64_sramc_variant = {
        .has_emac_clock = true,
 };
@@ -379,7 +373,7 @@ static const struct of_device_id sunxi_sram_dt_match[] = {
        },
        {
                .compatible = "allwinner,sun8i-h3-system-control",
-               .data = &sun4i_a10_sramc_variant,
+               .data = &sun8i_h3_sramc_variant,
        },
        {
                .compatible = "allwinner,sun50i-a64-sram-controller",
@@ -389,6 +383,10 @@ static const struct of_device_id sunxi_sram_dt_match[] = {
                .compatible = "allwinner,sun50i-a64-system-control",
                .data = &sun50i_a64_sramc_variant,
        },
+       {
+               .compatible = "allwinner,sun50i-h5-system-control",
+               .data = &sun50i_a64_sramc_variant,
+       },
        { },
 };
 MODULE_DEVICE_TABLE(of, sunxi_sram_dt_match);
index cd8f41351addfdd69432d4d6e7d5136be4b28e68..7bfb154d6fa5ebe3ed6a78b38dd5177430801e3a 100644 (file)
@@ -22,11 +22,15 @@ static const struct of_device_id tegra_machine_match[] = {
 
 bool soc_is_tegra(void)
 {
+       const struct of_device_id *match;
        struct device_node *root;
 
        root = of_find_node_by_path("/");
        if (!root)
                return false;
 
-       return of_match_node(tegra_machine_match, root) != NULL;
+       match = of_match_node(tegra_machine_match, root);
+       of_node_put(root);
+
+       return match != NULL;
 }
index 1fa840e3d930dcc3058d272e15b3ed85885c49c8..8c46b0aace0b2132dc5eb3890802d1131112f6a8 100644 (file)
@@ -2,6 +2,7 @@
  * drivers/soc/tegra/pmc.c
  *
  * Copyright (c) 2010 Google, Inc
+ * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
  *
  * Author:
  *     Colin Cross <ccross@google.com>
 #include <linux/init.h>
 #include <linux/io.h>
 #include <linux/iopoll.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_clk.h>
+#include <linux/of_irq.h>
 #include <linux/of_platform.h>
 #include <linux/pinctrl/pinctrl.h>
 #include <linux/pinctrl/pinconf.h>
 #include <soc/tegra/fuse.h>
 #include <soc/tegra/pmc.h>
 
+#include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/pinctrl/pinctrl-tegra-io-pad.h>
+#include <dt-bindings/gpio/tegra186-gpio.h>
+#include <dt-bindings/gpio/tegra194-gpio.h>
 
 #define PMC_CNTRL                      0x0
 #define  PMC_CNTRL_INTR_POLARITY       BIT(17) /* inverts INTR polarity */
@@ -92,7 +99,6 @@
 #define  PMC_SENSOR_CTRL_SCRATCH_WRITE BIT(2)
 #define  PMC_SENSOR_CTRL_ENABLE_RST    BIT(1)
 
-#define PMC_RST_STATUS                 0x1b4
 #define  PMC_RST_STATUS_POR            0
 #define  PMC_RST_STATUS_WATCHDOG       1
 #define  PMC_RST_STATUS_SENSOR         2
 #define GPU_RG_CNTRL                   0x2d4
 
 /* Tegra186 and later */
+#define WAKE_AOWAKE_CNTRL(x) (0x000 + ((x) << 2))
+#define WAKE_AOWAKE_CNTRL_LEVEL (1 << 3)
+#define WAKE_AOWAKE_MASK_W(x) (0x180 + ((x) << 2))
+#define WAKE_AOWAKE_MASK_R(x) (0x300 + ((x) << 2))
+#define WAKE_AOWAKE_STATUS_W(x) (0x30c + ((x) << 2))
+#define WAKE_AOWAKE_STATUS_R(x) (0x48c + ((x) << 2))
+#define WAKE_AOWAKE_TIER0_ROUTING(x) (0x4b4 + ((x) << 2))
+#define WAKE_AOWAKE_TIER1_ROUTING(x) (0x4c0 + ((x) << 2))
+#define WAKE_AOWAKE_TIER2_ROUTING(x) (0x4cc + ((x) << 2))
+
 #define WAKE_AOWAKE_CTRL 0x4f4
 #define  WAKE_AOWAKE_CTRL_INTR_POLARITY BIT(0)
 
@@ -151,8 +167,45 @@ struct tegra_pmc_regs {
        unsigned int dpd_status;
        unsigned int dpd2_req;
        unsigned int dpd2_status;
+       unsigned int rst_status;
+       unsigned int rst_source_shift;
+       unsigned int rst_source_mask;
+       unsigned int rst_level_shift;
+       unsigned int rst_level_mask;
+};
+
+struct tegra_wake_event {
+       const char *name;
+       unsigned int id;
+       unsigned int irq;
+       struct {
+               unsigned int instance;
+               unsigned int pin;
+       } gpio;
 };
 
+#define TEGRA_WAKE_IRQ(_name, _id, _irq)               \
+       {                                               \
+               .name = _name,                          \
+               .id = _id,                              \
+               .irq = _irq,                            \
+               .gpio = {                               \
+                       .instance = UINT_MAX,           \
+                       .pin = UINT_MAX,                \
+               },                                      \
+       }
+
+#define TEGRA_WAKE_GPIO(_name, _id, _instance, _pin)   \
+       {                                               \
+               .name = _name,                          \
+               .id = _id,                              \
+               .irq = 0,                               \
+               .gpio = {                               \
+                       .instance = _instance,          \
+                       .pin = _pin,                    \
+               },                                      \
+       }
+
 struct tegra_pmc_soc {
        unsigned int num_powergates;
        const char *const *powergates;
@@ -175,6 +228,45 @@ struct tegra_pmc_soc {
        void (*setup_irq_polarity)(struct tegra_pmc *pmc,
                                   struct device_node *np,
                                   bool invert);
+
+       const char * const *reset_sources;
+       unsigned int num_reset_sources;
+       const char * const *reset_levels;
+       unsigned int num_reset_levels;
+
+       const struct tegra_wake_event *wake_events;
+       unsigned int num_wake_events;
+};
+
+static const char * const tegra186_reset_sources[] = {
+       "SYS_RESET",
+       "AOWDT",
+       "MCCPLEXWDT",
+       "BPMPWDT",
+       "SCEWDT",
+       "SPEWDT",
+       "APEWDT",
+       "BCCPLEXWDT",
+       "SENSOR",
+       "AOTAG",
+       "VFSENSOR",
+       "SWREST",
+       "SC7",
+       "HSM",
+       "CORESIGHT"
+};
+
+static const char * const tegra186_reset_levels[] = {
+       "L0", "L1", "L2", "WARM"
+};
+
+static const char * const tegra30_reset_sources[] = {
+       "POWER_ON_RESET",
+       "WATCHDOG",
+       "SENSOR",
+       "SW_MAIN",
+       "LP0",
+       "AOTAG"
 };
 
 /**
@@ -230,6 +322,9 @@ struct tegra_pmc {
        struct mutex powergates_lock;
 
        struct pinctrl_dev *pctl_dev;
+
+       struct irq_domain *domain;
+       struct irq_chip irq;
 };
 
 static struct tegra_pmc *pmc = &(struct tegra_pmc) {
@@ -538,16 +633,10 @@ EXPORT_SYMBOL(tegra_powergate_power_off);
  */
 int tegra_powergate_is_powered(unsigned int id)
 {
-       int status;
-
        if (!tegra_powergate_is_valid(id))
                return -EINVAL;
 
-       mutex_lock(&pmc->powergates_lock);
-       status = tegra_powergate_state(id);
-       mutex_unlock(&pmc->powergates_lock);
-
-       return status;
+       return tegra_powergate_state(id);
 }
 
 /**
@@ -717,17 +806,7 @@ static int powergate_show(struct seq_file *s, void *data)
        return 0;
 }
 
-static int powergate_open(struct inode *inode, struct file *file)
-{
-       return single_open(file, powergate_show, inode->i_private);
-}
-
-static const struct file_operations powergate_fops = {
-       .open = powergate_open,
-       .read = seq_read,
-       .llseek = seq_lseek,
-       .release = single_release,
-};
+DEFINE_SHOW_ATTRIBUTE(powergate);
 
 static int tegra_powergate_debugfs_init(void)
 {
@@ -847,22 +926,6 @@ static void tegra_powergate_add(struct tegra_pmc *pmc, struct device_node *np)
                goto remove_resets;
        }
 
-       /*
-        * FIXME: If XHCI is enabled for Tegra, then power-up the XUSB
-        * host and super-speed partitions. Once the XHCI driver
-        * manages the partitions itself this code can be removed. Note
-        * that we don't register these partitions with the genpd core
-        * to avoid it from powering down the partitions as they appear
-        * to be unused.
-        */
-       if (IS_ENABLED(CONFIG_USB_XHCI_TEGRA) &&
-           (id == TEGRA_POWERGATE_XUSBA || id == TEGRA_POWERGATE_XUSBC)) {
-               if (off)
-                       WARN_ON(tegra_powergate_power_up(pg, true));
-
-               goto remove_resets;
-       }
-
        err = pm_genpd_init(&pg->genpd, NULL, off);
        if (err < 0) {
                pr_err("failed to initialise PM domain %pOFn: %d\n", np,
@@ -1543,6 +1606,225 @@ static int tegra_pmc_pinctrl_init(struct tegra_pmc *pmc)
        return err;
 }
 
+static ssize_t reset_reason_show(struct device *dev,
+                       struct device_attribute *attr, char *buf)
+{
+       u32 value, rst_src;
+
+       value = tegra_pmc_readl(pmc->soc->regs->rst_status);
+       rst_src = (value & pmc->soc->regs->rst_source_mask) >>
+                       pmc->soc->regs->rst_source_shift;
+
+       return sprintf(buf, "%s\n", pmc->soc->reset_sources[rst_src]);
+}
+
+static DEVICE_ATTR_RO(reset_reason);
+
+static ssize_t reset_level_show(struct device *dev,
+                       struct device_attribute *attr, char *buf)
+{
+       u32 value, rst_lvl;
+
+       value = tegra_pmc_readl(pmc->soc->regs->rst_status);
+       rst_lvl = (value & pmc->soc->regs->rst_level_mask) >>
+                       pmc->soc->regs->rst_level_shift;
+
+       return sprintf(buf, "%s\n", pmc->soc->reset_levels[rst_lvl]);
+}
+
+static DEVICE_ATTR_RO(reset_level);
+
+static void tegra_pmc_reset_sysfs_init(struct tegra_pmc *pmc)
+{
+       struct device *dev = pmc->dev;
+       int err = 0;
+
+       if (pmc->soc->reset_sources) {
+               err = device_create_file(dev, &dev_attr_reset_reason);
+               if (err < 0)
+                       dev_warn(dev,
+                               "failed to create attr \"reset_reason\": %d\n",
+                               err);
+       }
+
+       if (pmc->soc->reset_levels) {
+               err = device_create_file(dev, &dev_attr_reset_level);
+               if (err < 0)
+                       dev_warn(dev,
+                               "failed to create attr \"reset_level\": %d\n",
+                               err);
+       }
+}
+
+static int tegra_pmc_irq_translate(struct irq_domain *domain,
+                                  struct irq_fwspec *fwspec,
+                                  unsigned long *hwirq,
+                                  unsigned int *type)
+{
+       if (WARN_ON(fwspec->param_count < 2))
+               return -EINVAL;
+
+       *hwirq = fwspec->param[0];
+       *type = fwspec->param[1];
+
+       return 0;
+}
+
+static int tegra_pmc_irq_alloc(struct irq_domain *domain, unsigned int virq,
+                              unsigned int num_irqs, void *data)
+{
+       struct tegra_pmc *pmc = domain->host_data;
+       const struct tegra_pmc_soc *soc = pmc->soc;
+       struct irq_fwspec *fwspec = data;
+       unsigned int i;
+       int err = 0;
+
+       for (i = 0; i < soc->num_wake_events; i++) {
+               const struct tegra_wake_event *event = &soc->wake_events[i];
+
+               if (fwspec->param_count == 2) {
+                       struct irq_fwspec spec;
+
+                       if (event->id != fwspec->param[0])
+                               continue;
+
+                       err = irq_domain_set_hwirq_and_chip(domain, virq,
+                                                           event->id,
+                                                           &pmc->irq, pmc);
+                       if (err < 0)
+                               break;
+
+                       spec.fwnode = &pmc->dev->of_node->fwnode;
+                       spec.param_count = 3;
+                       spec.param[0] = GIC_SPI;
+                       spec.param[1] = event->irq;
+                       spec.param[2] = fwspec->param[1];
+
+                       err = irq_domain_alloc_irqs_parent(domain, virq,
+                                                          num_irqs, &spec);
+
+                       break;
+               }
+
+               if (fwspec->param_count == 3) {
+                       if (event->gpio.instance != fwspec->param[0] ||
+                           event->gpio.pin != fwspec->param[1])
+                               continue;
+
+                       err = irq_domain_set_hwirq_and_chip(domain, virq,
+                                                           event->id,
+                                                           &pmc->irq, pmc);
+
+                       break;
+               }
+       }
+
+       if (i == soc->num_wake_events)
+               err = irq_domain_set_hwirq_and_chip(domain, virq, ULONG_MAX,
+                                                   &pmc->irq, pmc);
+
+       return err;
+}
+
+static const struct irq_domain_ops tegra_pmc_irq_domain_ops = {
+       .translate = tegra_pmc_irq_translate,
+       .alloc = tegra_pmc_irq_alloc,
+};
+
+static int tegra_pmc_irq_set_wake(struct irq_data *data, unsigned int on)
+{
+       struct tegra_pmc *pmc = irq_data_get_irq_chip_data(data);
+       unsigned int offset, bit;
+       u32 value;
+
+       offset = data->hwirq / 32;
+       bit = data->hwirq % 32;
+
+       /* clear wake status */
+       writel(0x1, pmc->wake + WAKE_AOWAKE_STATUS_W(data->hwirq));
+
+       /* route wake to tier 2 */
+       value = readl(pmc->wake + WAKE_AOWAKE_TIER2_ROUTING(offset));
+
+       if (!on)
+               value &= ~(1 << bit);
+       else
+               value |= 1 << bit;
+
+       writel(value, pmc->wake + WAKE_AOWAKE_TIER2_ROUTING(offset));
+
+       /* enable wakeup event */
+       writel(!!on, pmc->wake + WAKE_AOWAKE_MASK_W(data->hwirq));
+
+       return 0;
+}
+
+static int tegra_pmc_irq_set_type(struct irq_data *data, unsigned int type)
+{
+       struct tegra_pmc *pmc = irq_data_get_irq_chip_data(data);
+       u32 value;
+
+       if (data->hwirq == ULONG_MAX)
+               return 0;
+
+       value = readl(pmc->wake + WAKE_AOWAKE_CNTRL(data->hwirq));
+
+       switch (type) {
+       case IRQ_TYPE_EDGE_RISING:
+       case IRQ_TYPE_LEVEL_HIGH:
+               value |= WAKE_AOWAKE_CNTRL_LEVEL;
+               break;
+
+       case IRQ_TYPE_EDGE_FALLING:
+       case IRQ_TYPE_LEVEL_LOW:
+               value &= ~WAKE_AOWAKE_CNTRL_LEVEL;
+               break;
+
+       case IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING:
+               value ^= WAKE_AOWAKE_CNTRL_LEVEL;
+               break;
+
+       default:
+               return -EINVAL;
+       }
+
+       writel(value, pmc->wake + WAKE_AOWAKE_CNTRL(data->hwirq));
+
+       return 0;
+}
+
+static int tegra_pmc_irq_init(struct tegra_pmc *pmc)
+{
+       struct irq_domain *parent = NULL;
+       struct device_node *np;
+
+       np = of_irq_find_parent(pmc->dev->of_node);
+       if (np) {
+               parent = irq_find_host(np);
+               of_node_put(np);
+       }
+
+       if (!parent)
+               return 0;
+
+       pmc->irq.name = dev_name(pmc->dev);
+       pmc->irq.irq_mask = irq_chip_mask_parent;
+       pmc->irq.irq_unmask = irq_chip_unmask_parent;
+       pmc->irq.irq_eoi = irq_chip_eoi_parent;
+       pmc->irq.irq_set_affinity = irq_chip_set_affinity_parent;
+       pmc->irq.irq_set_type = tegra_pmc_irq_set_type;
+       pmc->irq.irq_set_wake = tegra_pmc_irq_set_wake;
+
+       pmc->domain = irq_domain_add_hierarchy(parent, 0, 96, pmc->dev->of_node,
+                                              &tegra_pmc_irq_domain_ops, pmc);
+       if (!pmc->domain) {
+               dev_err(pmc->dev, "failed to allocate domain\n");
+               return -ENOMEM;
+       }
+
+       return 0;
+}
+
 static int tegra_pmc_probe(struct platform_device *pdev)
 {
        void __iomem *base;
@@ -1612,6 +1894,8 @@ static int tegra_pmc_probe(struct platform_device *pdev)
 
        tegra_pmc_init_tsense_reset(pmc);
 
+       tegra_pmc_reset_sysfs_init(pmc);
+
        if (IS_ENABLED(CONFIG_DEBUG_FS)) {
                err = tegra_powergate_debugfs_init();
                if (err < 0)
@@ -1629,6 +1913,10 @@ static int tegra_pmc_probe(struct platform_device *pdev)
        if (err)
                goto cleanup_restart_handler;
 
+       err = tegra_pmc_irq_init(pmc);
+       if (err < 0)
+               goto cleanup_restart_handler;
+
        mutex_lock(&pmc->powergates_lock);
        iounmap(pmc->base);
        pmc->base = base;
@@ -1678,6 +1966,11 @@ static const struct tegra_pmc_regs tegra20_pmc_regs = {
        .dpd_status = 0x1bc,
        .dpd2_req = 0x1c0,
        .dpd2_status = 0x1c4,
+       .rst_status = 0x1b4,
+       .rst_source_shift = 0x0,
+       .rst_source_mask = 0x7,
+       .rst_level_shift = 0x0,
+       .rst_level_mask = 0x0,
 };
 
 static void tegra20_pmc_init(struct tegra_pmc *pmc)
@@ -1735,6 +2028,10 @@ static const struct tegra_pmc_soc tegra20_pmc_soc = {
        .regs = &tegra20_pmc_regs,
        .init = tegra20_pmc_init,
        .setup_irq_polarity = tegra20_pmc_setup_irq_polarity,
+       .reset_sources = NULL,
+       .num_reset_sources = 0,
+       .reset_levels = NULL,
+       .num_reset_levels = 0,
 };
 
 static const char * const tegra30_powergates[] = {
@@ -1776,6 +2073,10 @@ static const struct tegra_pmc_soc tegra30_pmc_soc = {
        .regs = &tegra20_pmc_regs,
        .init = tegra20_pmc_init,
        .setup_irq_polarity = tegra20_pmc_setup_irq_polarity,
+       .reset_sources = tegra30_reset_sources,
+       .num_reset_sources = 5,
+       .reset_levels = NULL,
+       .num_reset_levels = 0,
 };
 
 static const char * const tegra114_powergates[] = {
@@ -1821,6 +2122,10 @@ static const struct tegra_pmc_soc tegra114_pmc_soc = {
        .regs = &tegra20_pmc_regs,
        .init = tegra20_pmc_init,
        .setup_irq_polarity = tegra20_pmc_setup_irq_polarity,
+       .reset_sources = tegra30_reset_sources,
+       .num_reset_sources = 5,
+       .reset_levels = NULL,
+       .num_reset_levels = 0,
 };
 
 static const char * const tegra124_powergates[] = {
@@ -1926,6 +2231,10 @@ static const struct tegra_pmc_soc tegra124_pmc_soc = {
        .regs = &tegra20_pmc_regs,
        .init = tegra20_pmc_init,
        .setup_irq_polarity = tegra20_pmc_setup_irq_polarity,
+       .reset_sources = tegra30_reset_sources,
+       .num_reset_sources = 5,
+       .reset_levels = NULL,
+       .num_reset_levels = 0,
 };
 
 static const char * const tegra210_powergates[] = {
@@ -2027,6 +2336,10 @@ static const struct tegra_pmc_soc tegra210_pmc_soc = {
        .regs = &tegra20_pmc_regs,
        .init = tegra20_pmc_init,
        .setup_irq_polarity = tegra20_pmc_setup_irq_polarity,
+       .reset_sources = tegra30_reset_sources,
+       .num_reset_sources = 5,
+       .reset_levels = NULL,
+       .num_reset_levels = 0,
 };
 
 #define TEGRA186_IO_PAD_TABLE(_pad)                                         \
@@ -2084,6 +2397,11 @@ static const struct tegra_pmc_regs tegra186_pmc_regs = {
        .dpd_status = 0x78,
        .dpd2_req = 0x7c,
        .dpd2_status = 0x80,
+       .rst_status = 0x70,
+       .rst_source_shift = 0x2,
+       .rst_source_mask = 0x3C,
+       .rst_level_shift = 0x0,
+       .rst_level_mask = 0x3,
 };
 
 static void tegra186_pmc_setup_irq_polarity(struct tegra_pmc *pmc,
@@ -2121,6 +2439,11 @@ static void tegra186_pmc_setup_irq_polarity(struct tegra_pmc *pmc,
        iounmap(wake);
 }
 
+static const struct tegra_wake_event tegra186_wake_events[] = {
+       TEGRA_WAKE_GPIO("power", 29, 1, TEGRA_AON_GPIO(FF, 0)),
+       TEGRA_WAKE_IRQ("rtc", 73, 10),
+};
+
 static const struct tegra_pmc_soc tegra186_pmc_soc = {
        .num_powergates = 0,
        .powergates = NULL,
@@ -2136,10 +2459,87 @@ static const struct tegra_pmc_soc tegra186_pmc_soc = {
        .regs = &tegra186_pmc_regs,
        .init = NULL,
        .setup_irq_polarity = tegra186_pmc_setup_irq_polarity,
+       .reset_sources = tegra186_reset_sources,
+       .num_reset_sources = 14,
+       .reset_levels = tegra186_reset_levels,
+       .num_reset_levels = 3,
+       .num_wake_events = ARRAY_SIZE(tegra186_wake_events),
+       .wake_events = tegra186_wake_events,
+};
+
+static const struct tegra_io_pad_soc tegra194_io_pads[] = {
+       { .id = TEGRA_IO_PAD_CSIA, .dpd = 0, .voltage = UINT_MAX },
+       { .id = TEGRA_IO_PAD_CSIB, .dpd = 1, .voltage = UINT_MAX },
+       { .id = TEGRA_IO_PAD_MIPI_BIAS, .dpd = 3, .voltage = UINT_MAX },
+       { .id = TEGRA_IO_PAD_PEX_CLK_BIAS, .dpd = 4, .voltage = UINT_MAX },
+       { .id = TEGRA_IO_PAD_PEX_CLK3, .dpd = 5, .voltage = UINT_MAX },
+       { .id = TEGRA_IO_PAD_PEX_CLK2, .dpd = 6, .voltage = UINT_MAX },
+       { .id = TEGRA_IO_PAD_PEX_CLK1, .dpd = 7, .voltage = UINT_MAX },
+       { .id = TEGRA_IO_PAD_EQOS, .dpd = 8, .voltage = UINT_MAX },
+       { .id = TEGRA_IO_PAD_PEX_CLK2_BIAS, .dpd = 9, .voltage = UINT_MAX },
+       { .id = TEGRA_IO_PAD_PEX_CLK2, .dpd = 10, .voltage = UINT_MAX },
+       { .id = TEGRA_IO_PAD_DAP3, .dpd = 11, .voltage = UINT_MAX },
+       { .id = TEGRA_IO_PAD_DAP5, .dpd = 12, .voltage = UINT_MAX },
+       { .id = TEGRA_IO_PAD_UART, .dpd = 14, .voltage = UINT_MAX },
+       { .id = TEGRA_IO_PAD_PWR_CTL, .dpd = 15, .voltage = UINT_MAX },
+       { .id = TEGRA_IO_PAD_SOC_GPIO53, .dpd = 16, .voltage = UINT_MAX },
+       { .id = TEGRA_IO_PAD_AUDIO, .dpd = 17, .voltage = UINT_MAX },
+       { .id = TEGRA_IO_PAD_GP_PWM2, .dpd = 18, .voltage = UINT_MAX },
+       { .id = TEGRA_IO_PAD_GP_PWM3, .dpd = 19, .voltage = UINT_MAX },
+       { .id = TEGRA_IO_PAD_SOC_GPIO12, .dpd = 20, .voltage = UINT_MAX },
+       { .id = TEGRA_IO_PAD_SOC_GPIO13, .dpd = 21, .voltage = UINT_MAX },
+       { .id = TEGRA_IO_PAD_SOC_GPIO10, .dpd = 22, .voltage = UINT_MAX },
+       { .id = TEGRA_IO_PAD_UART4, .dpd = 23, .voltage = UINT_MAX },
+       { .id = TEGRA_IO_PAD_UART5, .dpd = 24, .voltage = UINT_MAX },
+       { .id = TEGRA_IO_PAD_DBG, .dpd = 25, .voltage = UINT_MAX },
+       { .id = TEGRA_IO_PAD_HDMI_DP3, .dpd = 26, .voltage = UINT_MAX },
+       { .id = TEGRA_IO_PAD_HDMI_DP2, .dpd = 27, .voltage = UINT_MAX },
+       { .id = TEGRA_IO_PAD_HDMI_DP0, .dpd = 28, .voltage = UINT_MAX },
+       { .id = TEGRA_IO_PAD_HDMI_DP1, .dpd = 29, .voltage = UINT_MAX },
+       { .id = TEGRA_IO_PAD_PEX_CNTRL, .dpd = 32, .voltage = UINT_MAX },
+       { .id = TEGRA_IO_PAD_PEX_CTL2, .dpd = 33, .voltage = UINT_MAX },
+       { .id = TEGRA_IO_PAD_PEX_L0_RST_N, .dpd = 34, .voltage = UINT_MAX },
+       { .id = TEGRA_IO_PAD_PEX_L1_RST_N, .dpd = 35, .voltage = UINT_MAX },
+       { .id = TEGRA_IO_PAD_SDMMC4, .dpd = 36, .voltage = UINT_MAX },
+       { .id = TEGRA_IO_PAD_PEX_L5_RST_N, .dpd = 37, .voltage = UINT_MAX },
+       { .id = TEGRA_IO_PAD_CSIC, .dpd = 43, .voltage = UINT_MAX },
+       { .id = TEGRA_IO_PAD_CSID, .dpd = 44, .voltage = UINT_MAX },
+       { .id = TEGRA_IO_PAD_CSIE, .dpd = 45, .voltage = UINT_MAX },
+       { .id = TEGRA_IO_PAD_CSIF, .dpd = 46, .voltage = UINT_MAX },
+       { .id = TEGRA_IO_PAD_SPI, .dpd = 47, .voltage = UINT_MAX },
+       { .id = TEGRA_IO_PAD_UFS, .dpd = 49, .voltage = UINT_MAX },
+       { .id = TEGRA_IO_PAD_CSIG, .dpd = 50, .voltage = UINT_MAX },
+       { .id = TEGRA_IO_PAD_CSIH, .dpd = 51, .voltage = UINT_MAX },
+       { .id = TEGRA_IO_PAD_EDP, .dpd = 53, .voltage = UINT_MAX },
+       { .id = TEGRA_IO_PAD_SDMMC1_HV, .dpd = 55, .voltage = UINT_MAX },
+       { .id = TEGRA_IO_PAD_SDMMC3_HV, .dpd = 56, .voltage = UINT_MAX },
+       { .id = TEGRA_IO_PAD_CONN, .dpd = 60, .voltage = UINT_MAX },
+       { .id = TEGRA_IO_PAD_AUDIO_HV, .dpd = 61, .voltage = UINT_MAX },
+};
+
+static const struct tegra_wake_event tegra194_wake_events[] = {
+       TEGRA_WAKE_GPIO("power", 29, 1, TEGRA194_AON_GPIO(EE, 4)),
+       TEGRA_WAKE_IRQ("rtc", 73, 10),
+};
+
+static const struct tegra_pmc_soc tegra194_pmc_soc = {
+       .num_powergates = 0,
+       .powergates = NULL,
+       .num_cpu_powergates = 0,
+       .cpu_powergates = NULL,
+       .has_tsense_reset = false,
+       .has_gpu_clamps = false,
+       .num_io_pads = ARRAY_SIZE(tegra194_io_pads),
+       .io_pads = tegra194_io_pads,
+       .regs = &tegra186_pmc_regs,
+       .init = NULL,
+       .setup_irq_polarity = tegra186_pmc_setup_irq_polarity,
+       .num_wake_events = ARRAY_SIZE(tegra194_wake_events),
+       .wake_events = tegra194_wake_events,
 };
 
 static const struct of_device_id tegra_pmc_match[] = {
-       { .compatible = "nvidia,tegra194-pmc", .data = &tegra186_pmc_soc },
+       { .compatible = "nvidia,tegra194-pmc", .data = &tegra194_pmc_soc },
        { .compatible = "nvidia,tegra186-pmc", .data = &tegra186_pmc_soc },
        { .compatible = "nvidia,tegra210-pmc", .data = &tegra210_pmc_soc },
        { .compatible = "nvidia,tegra132-pmc", .data = &tegra124_pmc_soc },
index f5cb8c0af09f3ab8ade4443ada270bf1f1eefa92..d65e361c5de1b4abf0e2ecc5d5b73c21a29ea4ef 100644 (file)
@@ -57,6 +57,7 @@
 static struct wkup_m3_ipc *m3_ipc_state;
 
 static const struct wkup_m3_wakeup_src wakeups[] = {
+       {.irq_nr = 16,  .src = "PRCM"},
        {.irq_nr = 35,  .src = "USB0_PHY"},
        {.irq_nr = 36,  .src = "USB1_PHY"},
        {.irq_nr = 40,  .src = "I2C0"},
diff --git a/include/dt-bindings/firmware/imx/rsrc.h b/include/dt-bindings/firmware/imx/rsrc.h
new file mode 100644 (file)
index 0000000..4481f2d
--- /dev/null
@@ -0,0 +1,559 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2018 NXP
+ */
+
+#ifndef __DT_BINDINGS_RSCRC_IMX_H
+#define __DT_BINDINGS_RSCRC_IMX_H
+
+/*
+ * These defines are used to indicate a resource. Resources include peripherals
+ * and bus masters (but not memory regions). Note items from list should
+ * never be changed or removed (only added to at the end of the list).
+ */
+
+#define IMX_SC_R_A53                   0
+#define IMX_SC_R_A53_0                 1
+#define IMX_SC_R_A53_1                 2
+#define IMX_SC_R_A53_2                 3
+#define IMX_SC_R_A53_3                 4
+#define IMX_SC_R_A72                   5
+#define IMX_SC_R_A72_0                 6
+#define IMX_SC_R_A72_1                 7
+#define IMX_SC_R_A72_2                 8
+#define IMX_SC_R_A72_3                 9
+#define IMX_SC_R_CCI                   10
+#define IMX_SC_R_DB                    11
+#define IMX_SC_R_DRC_0                 12
+#define IMX_SC_R_DRC_1                 13
+#define IMX_SC_R_GIC_SMMU              14
+#define IMX_SC_R_IRQSTR_M4_0           15
+#define IMX_SC_R_IRQSTR_M4_1           16
+#define IMX_SC_R_SMMU                  17
+#define IMX_SC_R_GIC                   18
+#define IMX_SC_R_DC_0_BLIT0            19
+#define IMX_SC_R_DC_0_BLIT1            20
+#define IMX_SC_R_DC_0_BLIT2            21
+#define IMX_SC_R_DC_0_BLIT_OUT         22
+#define IMX_SC_R_DC_0_CAPTURE0         23
+#define IMX_SC_R_DC_0_CAPTURE1         24
+#define IMX_SC_R_DC_0_WARP             25
+#define IMX_SC_R_DC_0_INTEGRAL0                26
+#define IMX_SC_R_DC_0_INTEGRAL1                27
+#define IMX_SC_R_DC_0_VIDEO0           28
+#define IMX_SC_R_DC_0_VIDEO1           29
+#define IMX_SC_R_DC_0_FRAC0            30
+#define IMX_SC_R_DC_0_FRAC1            31
+#define IMX_SC_R_DC_0                  32
+#define IMX_SC_R_GPU_2_PID0            33
+#define IMX_SC_R_DC_0_PLL_0            34
+#define IMX_SC_R_DC_0_PLL_1            35
+#define IMX_SC_R_DC_1_BLIT0            36
+#define IMX_SC_R_DC_1_BLIT1            37
+#define IMX_SC_R_DC_1_BLIT2            38
+#define IMX_SC_R_DC_1_BLIT_OUT         39
+#define IMX_SC_R_DC_1_CAPTURE0         40
+#define IMX_SC_R_DC_1_CAPTURE1         41
+#define IMX_SC_R_DC_1_WARP             42
+#define IMX_SC_R_DC_1_INTEGRAL0                43
+#define IMX_SC_R_DC_1_INTEGRAL1                44
+#define IMX_SC_R_DC_1_VIDEO0           45
+#define IMX_SC_R_DC_1_VIDEO1           46
+#define IMX_SC_R_DC_1_FRAC0            47
+#define IMX_SC_R_DC_1_FRAC1            48
+#define IMX_SC_R_DC_1                  49
+#define IMX_SC_R_GPU_3_PID0            50
+#define IMX_SC_R_DC_1_PLL_0            51
+#define IMX_SC_R_DC_1_PLL_1            52
+#define IMX_SC_R_SPI_0                 53
+#define IMX_SC_R_SPI_1                 54
+#define IMX_SC_R_SPI_2                 55
+#define IMX_SC_R_SPI_3                 56
+#define IMX_SC_R_UART_0                        57
+#define IMX_SC_R_UART_1                        58
+#define IMX_SC_R_UART_2                        59
+#define IMX_SC_R_UART_3                        60
+#define IMX_SC_R_UART_4                        61
+#define IMX_SC_R_EMVSIM_0              62
+#define IMX_SC_R_EMVSIM_1              63
+#define IMX_SC_R_DMA_0_CH0             64
+#define IMX_SC_R_DMA_0_CH1             65
+#define IMX_SC_R_DMA_0_CH2             66
+#define IMX_SC_R_DMA_0_CH3             67
+#define IMX_SC_R_DMA_0_CH4             68
+#define IMX_SC_R_DMA_0_CH5             69
+#define IMX_SC_R_DMA_0_CH6             70
+#define IMX_SC_R_DMA_0_CH7             71
+#define IMX_SC_R_DMA_0_CH8             72
+#define IMX_SC_R_DMA_0_CH9             73
+#define IMX_SC_R_DMA_0_CH10            74
+#define IMX_SC_R_DMA_0_CH11            75
+#define IMX_SC_R_DMA_0_CH12            76
+#define IMX_SC_R_DMA_0_CH13            77
+#define IMX_SC_R_DMA_0_CH14            78
+#define IMX_SC_R_DMA_0_CH15            79
+#define IMX_SC_R_DMA_0_CH16            80
+#define IMX_SC_R_DMA_0_CH17            81
+#define IMX_SC_R_DMA_0_CH18            82
+#define IMX_SC_R_DMA_0_CH19            83
+#define IMX_SC_R_DMA_0_CH20            84
+#define IMX_SC_R_DMA_0_CH21            85
+#define IMX_SC_R_DMA_0_CH22            86
+#define IMX_SC_R_DMA_0_CH23            87
+#define IMX_SC_R_DMA_0_CH24            88
+#define IMX_SC_R_DMA_0_CH25            89
+#define IMX_SC_R_DMA_0_CH26            90
+#define IMX_SC_R_DMA_0_CH27            91
+#define IMX_SC_R_DMA_0_CH28            92
+#define IMX_SC_R_DMA_0_CH29            93
+#define IMX_SC_R_DMA_0_CH30            94
+#define IMX_SC_R_DMA_0_CH31            95
+#define IMX_SC_R_I2C_0                 96
+#define IMX_SC_R_I2C_1                 97
+#define IMX_SC_R_I2C_2                 98
+#define IMX_SC_R_I2C_3                 99
+#define IMX_SC_R_I2C_4                 100
+#define IMX_SC_R_ADC_0                 101
+#define IMX_SC_R_ADC_1                 102
+#define IMX_SC_R_FTM_0                 103
+#define IMX_SC_R_FTM_1                 104
+#define IMX_SC_R_CAN_0                 105
+#define IMX_SC_R_CAN_1                 106
+#define IMX_SC_R_CAN_2                 107
+#define IMX_SC_R_DMA_1_CH0             108
+#define IMX_SC_R_DMA_1_CH1             109
+#define IMX_SC_R_DMA_1_CH2             110
+#define IMX_SC_R_DMA_1_CH3             111
+#define IMX_SC_R_DMA_1_CH4             112
+#define IMX_SC_R_DMA_1_CH5             113
+#define IMX_SC_R_DMA_1_CH6             114
+#define IMX_SC_R_DMA_1_CH7             115
+#define IMX_SC_R_DMA_1_CH8             116
+#define IMX_SC_R_DMA_1_CH9             117
+#define IMX_SC_R_DMA_1_CH10            118
+#define IMX_SC_R_DMA_1_CH11            119
+#define IMX_SC_R_DMA_1_CH12            120
+#define IMX_SC_R_DMA_1_CH13            121
+#define IMX_SC_R_DMA_1_CH14            122
+#define IMX_SC_R_DMA_1_CH15            123
+#define IMX_SC_R_DMA_1_CH16            124
+#define IMX_SC_R_DMA_1_CH17            125
+#define IMX_SC_R_DMA_1_CH18            126
+#define IMX_SC_R_DMA_1_CH19            127
+#define IMX_SC_R_DMA_1_CH20            128
+#define IMX_SC_R_DMA_1_CH21            129
+#define IMX_SC_R_DMA_1_CH22            130
+#define IMX_SC_R_DMA_1_CH23            131
+#define IMX_SC_R_DMA_1_CH24            132
+#define IMX_SC_R_DMA_1_CH25            133
+#define IMX_SC_R_DMA_1_CH26            134
+#define IMX_SC_R_DMA_1_CH27            135
+#define IMX_SC_R_DMA_1_CH28            136
+#define IMX_SC_R_DMA_1_CH29            137
+#define IMX_SC_R_DMA_1_CH30            138
+#define IMX_SC_R_DMA_1_CH31            139
+#define IMX_SC_R_UNUSED1               140
+#define IMX_SC_R_UNUSED2               141
+#define IMX_SC_R_UNUSED3               142
+#define IMX_SC_R_UNUSED4               143
+#define IMX_SC_R_GPU_0_PID0            144
+#define IMX_SC_R_GPU_0_PID1            145
+#define IMX_SC_R_GPU_0_PID2            146
+#define IMX_SC_R_GPU_0_PID3            147
+#define IMX_SC_R_GPU_1_PID0            148
+#define IMX_SC_R_GPU_1_PID1            149
+#define IMX_SC_R_GPU_1_PID2            150
+#define IMX_SC_R_GPU_1_PID3            151
+#define IMX_SC_R_PCIE_A                        152
+#define IMX_SC_R_SERDES_0              153
+#define IMX_SC_R_MATCH_0               154
+#define IMX_SC_R_MATCH_1               155
+#define IMX_SC_R_MATCH_2               156
+#define IMX_SC_R_MATCH_3               157
+#define IMX_SC_R_MATCH_4               158
+#define IMX_SC_R_MATCH_5               159
+#define IMX_SC_R_MATCH_6               160
+#define IMX_SC_R_MATCH_7               161
+#define IMX_SC_R_MATCH_8               162
+#define IMX_SC_R_MATCH_9               163
+#define IMX_SC_R_MATCH_10              164
+#define IMX_SC_R_MATCH_11              165
+#define IMX_SC_R_MATCH_12              166
+#define IMX_SC_R_MATCH_13              167
+#define IMX_SC_R_MATCH_14              168
+#define IMX_SC_R_PCIE_B                        169
+#define IMX_SC_R_SATA_0                        170
+#define IMX_SC_R_SERDES_1              171
+#define IMX_SC_R_HSIO_GPIO             172
+#define IMX_SC_R_MATCH_15              173
+#define IMX_SC_R_MATCH_16              174
+#define IMX_SC_R_MATCH_17              175
+#define IMX_SC_R_MATCH_18              176
+#define IMX_SC_R_MATCH_19              177
+#define IMX_SC_R_MATCH_20              178
+#define IMX_SC_R_MATCH_21              179
+#define IMX_SC_R_MATCH_22              180
+#define IMX_SC_R_MATCH_23              181
+#define IMX_SC_R_MATCH_24              182
+#define IMX_SC_R_MATCH_25              183
+#define IMX_SC_R_MATCH_26              184
+#define IMX_SC_R_MATCH_27              185
+#define IMX_SC_R_MATCH_28              186
+#define IMX_SC_R_LCD_0                 187
+#define IMX_SC_R_LCD_0_PWM_0           188
+#define IMX_SC_R_LCD_0_I2C_0           189
+#define IMX_SC_R_LCD_0_I2C_1           190
+#define IMX_SC_R_PWM_0                 191
+#define IMX_SC_R_PWM_1                 192
+#define IMX_SC_R_PWM_2                 193
+#define IMX_SC_R_PWM_3                 194
+#define IMX_SC_R_PWM_4                 195
+#define IMX_SC_R_PWM_5                 196
+#define IMX_SC_R_PWM_6                 197
+#define IMX_SC_R_PWM_7                 198
+#define IMX_SC_R_GPIO_0                        199
+#define IMX_SC_R_GPIO_1                        200
+#define IMX_SC_R_GPIO_2                        201
+#define IMX_SC_R_GPIO_3                        202
+#define IMX_SC_R_GPIO_4                        203
+#define IMX_SC_R_GPIO_5                        204
+#define IMX_SC_R_GPIO_6                        205
+#define IMX_SC_R_GPIO_7                        206
+#define IMX_SC_R_GPT_0                 207
+#define IMX_SC_R_GPT_1                 208
+#define IMX_SC_R_GPT_2                 209
+#define IMX_SC_R_GPT_3                 210
+#define IMX_SC_R_GPT_4                 211
+#define IMX_SC_R_KPP                   212
+#define IMX_SC_R_MU_0A                 213
+#define IMX_SC_R_MU_1A                 214
+#define IMX_SC_R_MU_2A                 215
+#define IMX_SC_R_MU_3A                 216
+#define IMX_SC_R_MU_4A                 217
+#define IMX_SC_R_MU_5A                 218
+#define IMX_SC_R_MU_6A                 219
+#define IMX_SC_R_MU_7A                 220
+#define IMX_SC_R_MU_8A                 221
+#define IMX_SC_R_MU_9A                 222
+#define IMX_SC_R_MU_10A                        223
+#define IMX_SC_R_MU_11A                        224
+#define IMX_SC_R_MU_12A                        225
+#define IMX_SC_R_MU_13A                        226
+#define IMX_SC_R_MU_5B                 227
+#define IMX_SC_R_MU_6B                 228
+#define IMX_SC_R_MU_7B                 229
+#define IMX_SC_R_MU_8B                 230
+#define IMX_SC_R_MU_9B                 231
+#define IMX_SC_R_MU_10B                        232
+#define IMX_SC_R_MU_11B                        233
+#define IMX_SC_R_MU_12B                        234
+#define IMX_SC_R_MU_13B                        235
+#define IMX_SC_R_ROM_0                 236
+#define IMX_SC_R_FSPI_0                        237
+#define IMX_SC_R_FSPI_1                        238
+#define IMX_SC_R_IEE                   239
+#define IMX_SC_R_IEE_R0                        240
+#define IMX_SC_R_IEE_R1                        241
+#define IMX_SC_R_IEE_R2                        242
+#define IMX_SC_R_IEE_R3                        243
+#define IMX_SC_R_IEE_R4                        244
+#define IMX_SC_R_IEE_R5                        245
+#define IMX_SC_R_IEE_R6                        246
+#define IMX_SC_R_IEE_R7                        247
+#define IMX_SC_R_SDHC_0                        248
+#define IMX_SC_R_SDHC_1                        249
+#define IMX_SC_R_SDHC_2                        250
+#define IMX_SC_R_ENET_0                        251
+#define IMX_SC_R_ENET_1                        252
+#define IMX_SC_R_MLB_0                 253
+#define IMX_SC_R_DMA_2_CH0             254
+#define IMX_SC_R_DMA_2_CH1             255
+#define IMX_SC_R_DMA_2_CH2             256
+#define IMX_SC_R_DMA_2_CH3             257
+#define IMX_SC_R_DMA_2_CH4             258
+#define IMX_SC_R_USB_0                 259
+#define IMX_SC_R_USB_1                 260
+#define IMX_SC_R_USB_0_PHY             261
+#define IMX_SC_R_USB_2                 262
+#define IMX_SC_R_USB_2_PHY             263
+#define IMX_SC_R_DTCP                  264
+#define IMX_SC_R_NAND                  265
+#define IMX_SC_R_LVDS_0                        266
+#define IMX_SC_R_LVDS_0_PWM_0          267
+#define IMX_SC_R_LVDS_0_I2C_0          268
+#define IMX_SC_R_LVDS_0_I2C_1          269
+#define IMX_SC_R_LVDS_1                        270
+#define IMX_SC_R_LVDS_1_PWM_0          271
+#define IMX_SC_R_LVDS_1_I2C_0          272
+#define IMX_SC_R_LVDS_1_I2C_1          273
+#define IMX_SC_R_LVDS_2                        274
+#define IMX_SC_R_LVDS_2_PWM_0          275
+#define IMX_SC_R_LVDS_2_I2C_0          276
+#define IMX_SC_R_LVDS_2_I2C_1          277
+#define IMX_SC_R_M4_0_PID0             278
+#define IMX_SC_R_M4_0_PID1             279
+#define IMX_SC_R_M4_0_PID2             280
+#define IMX_SC_R_M4_0_PID3             281
+#define IMX_SC_R_M4_0_PID4             282
+#define IMX_SC_R_M4_0_RGPIO            283
+#define IMX_SC_R_M4_0_SEMA42           284
+#define IMX_SC_R_M4_0_TPM              285
+#define IMX_SC_R_M4_0_PIT              286
+#define IMX_SC_R_M4_0_UART             287
+#define IMX_SC_R_M4_0_I2C              288
+#define IMX_SC_R_M4_0_INTMUX           289
+#define IMX_SC_R_M4_0_SIM              290
+#define IMX_SC_R_M4_0_WDOG             291
+#define IMX_SC_R_M4_0_MU_0B            292
+#define IMX_SC_R_M4_0_MU_0A0           293
+#define IMX_SC_R_M4_0_MU_0A1           294
+#define IMX_SC_R_M4_0_MU_0A2           295
+#define IMX_SC_R_M4_0_MU_0A3           296
+#define IMX_SC_R_M4_0_MU_1A            297
+#define IMX_SC_R_M4_1_PID0             298
+#define IMX_SC_R_M4_1_PID1             299
+#define IMX_SC_R_M4_1_PID2             300
+#define IMX_SC_R_M4_1_PID3             301
+#define IMX_SC_R_M4_1_PID4             302
+#define IMX_SC_R_M4_1_RGPIO            303
+#define IMX_SC_R_M4_1_SEMA42           304
+#define IMX_SC_R_M4_1_TPM              305
+#define IMX_SC_R_M4_1_PIT              306
+#define IMX_SC_R_M4_1_UART             307
+#define IMX_SC_R_M4_1_I2C              308
+#define IMX_SC_R_M4_1_INTMUX           309
+#define IMX_SC_R_M4_1_SIM              310
+#define IMX_SC_R_M4_1_WDOG             311
+#define IMX_SC_R_M4_1_MU_0B            312
+#define IMX_SC_R_M4_1_MU_0A0           313
+#define IMX_SC_R_M4_1_MU_0A1           314
+#define IMX_SC_R_M4_1_MU_0A2           315
+#define IMX_SC_R_M4_1_MU_0A3           316
+#define IMX_SC_R_M4_1_MU_1A            317
+#define IMX_SC_R_SAI_0                 318
+#define IMX_SC_R_SAI_1                 319
+#define IMX_SC_R_SAI_2                 320
+#define IMX_SC_R_IRQSTR_SCU2           321
+#define IMX_SC_R_IRQSTR_DSP            322
+#define IMX_SC_R_ELCDIF_PLL            323
+#define IMX_SC_R_UNUSED6               324
+#define IMX_SC_R_AUDIO_PLL_0           325
+#define IMX_SC_R_PI_0                  326
+#define IMX_SC_R_PI_0_PWM_0            327
+#define IMX_SC_R_PI_0_PWM_1            328
+#define IMX_SC_R_PI_0_I2C_0            329
+#define IMX_SC_R_PI_0_PLL              330
+#define IMX_SC_R_PI_1                  331
+#define IMX_SC_R_PI_1_PWM_0            332
+#define IMX_SC_R_PI_1_PWM_1            333
+#define IMX_SC_R_PI_1_I2C_0            334
+#define IMX_SC_R_PI_1_PLL              335
+#define IMX_SC_R_SC_PID0               336
+#define IMX_SC_R_SC_PID1               337
+#define IMX_SC_R_SC_PID2               338
+#define IMX_SC_R_SC_PID3               339
+#define IMX_SC_R_SC_PID4               340
+#define IMX_SC_R_SC_SEMA42             341
+#define IMX_SC_R_SC_TPM                        342
+#define IMX_SC_R_SC_PIT                        343
+#define IMX_SC_R_SC_UART               344
+#define IMX_SC_R_SC_I2C                        345
+#define IMX_SC_R_SC_MU_0B              346
+#define IMX_SC_R_SC_MU_0A0             347
+#define IMX_SC_R_SC_MU_0A1             348
+#define IMX_SC_R_SC_MU_0A2             349
+#define IMX_SC_R_SC_MU_0A3             350
+#define IMX_SC_R_SC_MU_1A              351
+#define IMX_SC_R_SYSCNT_RD             352
+#define IMX_SC_R_SYSCNT_CMP            353
+#define IMX_SC_R_DEBUG                 354
+#define IMX_SC_R_SYSTEM                        355
+#define IMX_SC_R_SNVS                  356
+#define IMX_SC_R_OTP                   357
+#define IMX_SC_R_VPU_PID0              358
+#define IMX_SC_R_VPU_PID1              359
+#define IMX_SC_R_VPU_PID2              360
+#define IMX_SC_R_VPU_PID3              361
+#define IMX_SC_R_VPU_PID4              362
+#define IMX_SC_R_VPU_PID5              363
+#define IMX_SC_R_VPU_PID6              364
+#define IMX_SC_R_VPU_PID7              365
+#define IMX_SC_R_VPU_UART              366
+#define IMX_SC_R_VPUCORE               367
+#define IMX_SC_R_VPUCORE_0             368
+#define IMX_SC_R_VPUCORE_1             369
+#define IMX_SC_R_VPUCORE_2             370
+#define IMX_SC_R_VPUCORE_3             371
+#define IMX_SC_R_DMA_4_CH0             372
+#define IMX_SC_R_DMA_4_CH1             373
+#define IMX_SC_R_DMA_4_CH2             374
+#define IMX_SC_R_DMA_4_CH3             375
+#define IMX_SC_R_DMA_4_CH4             376
+#define IMX_SC_R_ISI_CH0               377
+#define IMX_SC_R_ISI_CH1               378
+#define IMX_SC_R_ISI_CH2               379
+#define IMX_SC_R_ISI_CH3               380
+#define IMX_SC_R_ISI_CH4               381
+#define IMX_SC_R_ISI_CH5               382
+#define IMX_SC_R_ISI_CH6               383
+#define IMX_SC_R_ISI_CH7               384
+#define IMX_SC_R_MJPEG_DEC_S0          385
+#define IMX_SC_R_MJPEG_DEC_S1          386
+#define IMX_SC_R_MJPEG_DEC_S2          387
+#define IMX_SC_R_MJPEG_DEC_S3          388
+#define IMX_SC_R_MJPEG_ENC_S0          389
+#define IMX_SC_R_MJPEG_ENC_S1          390
+#define IMX_SC_R_MJPEG_ENC_S2          391
+#define IMX_SC_R_MJPEG_ENC_S3          392
+#define IMX_SC_R_MIPI_0                        393
+#define IMX_SC_R_MIPI_0_PWM_0          394
+#define IMX_SC_R_MIPI_0_I2C_0          395
+#define IMX_SC_R_MIPI_0_I2C_1          396
+#define IMX_SC_R_MIPI_1                        397
+#define IMX_SC_R_MIPI_1_PWM_0          398
+#define IMX_SC_R_MIPI_1_I2C_0          399
+#define IMX_SC_R_MIPI_1_I2C_1          400
+#define IMX_SC_R_CSI_0                 401
+#define IMX_SC_R_CSI_0_PWM_0           402
+#define IMX_SC_R_CSI_0_I2C_0           403
+#define IMX_SC_R_CSI_1                 404
+#define IMX_SC_R_CSI_1_PWM_0           405
+#define IMX_SC_R_CSI_1_I2C_0           406
+#define IMX_SC_R_HDMI                  407
+#define IMX_SC_R_HDMI_I2S              408
+#define IMX_SC_R_HDMI_I2C_0            409
+#define IMX_SC_R_HDMI_PLL_0            410
+#define IMX_SC_R_HDMI_RX               411
+#define IMX_SC_R_HDMI_RX_BYPASS                412
+#define IMX_SC_R_HDMI_RX_I2C_0         413
+#define IMX_SC_R_ASRC_0                        414
+#define IMX_SC_R_ESAI_0                        415
+#define IMX_SC_R_SPDIF_0               416
+#define IMX_SC_R_SPDIF_1               417
+#define IMX_SC_R_SAI_3                 418
+#define IMX_SC_R_SAI_4                 419
+#define IMX_SC_R_SAI_5                 420
+#define IMX_SC_R_GPT_5                 421
+#define IMX_SC_R_GPT_6                 422
+#define IMX_SC_R_GPT_7                 423
+#define IMX_SC_R_GPT_8                 424
+#define IMX_SC_R_GPT_9                 425
+#define IMX_SC_R_GPT_10                        426
+#define IMX_SC_R_DMA_2_CH5             427
+#define IMX_SC_R_DMA_2_CH6             428
+#define IMX_SC_R_DMA_2_CH7             429
+#define IMX_SC_R_DMA_2_CH8             430
+#define IMX_SC_R_DMA_2_CH9             431
+#define IMX_SC_R_DMA_2_CH10            432
+#define IMX_SC_R_DMA_2_CH11            433
+#define IMX_SC_R_DMA_2_CH12            434
+#define IMX_SC_R_DMA_2_CH13            435
+#define IMX_SC_R_DMA_2_CH14            436
+#define IMX_SC_R_DMA_2_CH15            437
+#define IMX_SC_R_DMA_2_CH16            438
+#define IMX_SC_R_DMA_2_CH17            439
+#define IMX_SC_R_DMA_2_CH18            440
+#define IMX_SC_R_DMA_2_CH19            441
+#define IMX_SC_R_DMA_2_CH20            442
+#define IMX_SC_R_DMA_2_CH21            443
+#define IMX_SC_R_DMA_2_CH22            444
+#define IMX_SC_R_DMA_2_CH23            445
+#define IMX_SC_R_DMA_2_CH24            446
+#define IMX_SC_R_DMA_2_CH25            447
+#define IMX_SC_R_DMA_2_CH26            448
+#define IMX_SC_R_DMA_2_CH27            449
+#define IMX_SC_R_DMA_2_CH28            450
+#define IMX_SC_R_DMA_2_CH29            451
+#define IMX_SC_R_DMA_2_CH30            452
+#define IMX_SC_R_DMA_2_CH31            453
+#define IMX_SC_R_ASRC_1                        454
+#define IMX_SC_R_ESAI_1                        455
+#define IMX_SC_R_SAI_6                 456
+#define IMX_SC_R_SAI_7                 457
+#define IMX_SC_R_AMIX                  458
+#define IMX_SC_R_MQS_0                 459
+#define IMX_SC_R_DMA_3_CH0             460
+#define IMX_SC_R_DMA_3_CH1             461
+#define IMX_SC_R_DMA_3_CH2             462
+#define IMX_SC_R_DMA_3_CH3             463
+#define IMX_SC_R_DMA_3_CH4             464
+#define IMX_SC_R_DMA_3_CH5             465
+#define IMX_SC_R_DMA_3_CH6             466
+#define IMX_SC_R_DMA_3_CH7             467
+#define IMX_SC_R_DMA_3_CH8             468
+#define IMX_SC_R_DMA_3_CH9             469
+#define IMX_SC_R_DMA_3_CH10            470
+#define IMX_SC_R_DMA_3_CH11            471
+#define IMX_SC_R_DMA_3_CH12            472
+#define IMX_SC_R_DMA_3_CH13            473
+#define IMX_SC_R_DMA_3_CH14            474
+#define IMX_SC_R_DMA_3_CH15            475
+#define IMX_SC_R_DMA_3_CH16            476
+#define IMX_SC_R_DMA_3_CH17            477
+#define IMX_SC_R_DMA_3_CH18            478
+#define IMX_SC_R_DMA_3_CH19            479
+#define IMX_SC_R_DMA_3_CH20            480
+#define IMX_SC_R_DMA_3_CH21            481
+#define IMX_SC_R_DMA_3_CH22            482
+#define IMX_SC_R_DMA_3_CH23            483
+#define IMX_SC_R_DMA_3_CH24            484
+#define IMX_SC_R_DMA_3_CH25            485
+#define IMX_SC_R_DMA_3_CH26            486
+#define IMX_SC_R_DMA_3_CH27            487
+#define IMX_SC_R_DMA_3_CH28            488
+#define IMX_SC_R_DMA_3_CH29            489
+#define IMX_SC_R_DMA_3_CH30            490
+#define IMX_SC_R_DMA_3_CH31            491
+#define IMX_SC_R_AUDIO_PLL_1           492
+#define IMX_SC_R_AUDIO_CLK_0           493
+#define IMX_SC_R_AUDIO_CLK_1           494
+#define IMX_SC_R_MCLK_OUT_0            495
+#define IMX_SC_R_MCLK_OUT_1            496
+#define IMX_SC_R_PMIC_0                        497
+#define IMX_SC_R_PMIC_1                        498
+#define IMX_SC_R_SECO                  499
+#define IMX_SC_R_CAAM_JR1              500
+#define IMX_SC_R_CAAM_JR2              501
+#define IMX_SC_R_CAAM_JR3              502
+#define IMX_SC_R_SECO_MU_2             503
+#define IMX_SC_R_SECO_MU_3             504
+#define IMX_SC_R_SECO_MU_4             505
+#define IMX_SC_R_HDMI_RX_PWM_0         506
+#define IMX_SC_R_A35                   507
+#define IMX_SC_R_A35_0                 508
+#define IMX_SC_R_A35_1                 509
+#define IMX_SC_R_A35_2                 510
+#define IMX_SC_R_A35_3                 511
+#define IMX_SC_R_DSP                   512
+#define IMX_SC_R_DSP_RAM               513
+#define IMX_SC_R_CAAM_JR1_OUT          514
+#define IMX_SC_R_CAAM_JR2_OUT          515
+#define IMX_SC_R_CAAM_JR3_OUT          516
+#define IMX_SC_R_VPU_DEC_0             517
+#define IMX_SC_R_VPU_ENC_0             518
+#define IMX_SC_R_CAAM_JR0              519
+#define IMX_SC_R_CAAM_JR0_OUT          520
+#define IMX_SC_R_PMIC_2                        521
+#define IMX_SC_R_DBLOGIC               522
+#define IMX_SC_R_HDMI_PLL_1            523
+#define IMX_SC_R_BOARD_R0              524
+#define IMX_SC_R_BOARD_R1              525
+#define IMX_SC_R_BOARD_R2              526
+#define IMX_SC_R_BOARD_R3              527
+#define IMX_SC_R_BOARD_R4              528
+#define IMX_SC_R_BOARD_R5              529
+#define IMX_SC_R_BOARD_R6              530
+#define IMX_SC_R_BOARD_R7              531
+#define IMX_SC_R_MJPEG_DEC_MP          532
+#define IMX_SC_R_MJPEG_ENC_MP          533
+#define IMX_SC_R_VPU_TS_0              534
+#define IMX_SC_R_VPU_MU_0              535
+#define IMX_SC_R_VPU_MU_1              536
+#define IMX_SC_R_VPU_MU_2              537
+#define IMX_SC_R_VPU_MU_3              538
+#define IMX_SC_R_VPU_ENC_1             539
+#define IMX_SC_R_VPU                   540
+#define IMX_SC_R_LAST                  541
+
+#endif /* __DT_BINDINGS_RSCRC_IMX_H */
diff --git a/include/dt-bindings/power/imx8mq-power.h b/include/dt-bindings/power/imx8mq-power.h
new file mode 100644 (file)
index 0000000..8a513bd
--- /dev/null
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */
+/*
+ *  Copyright (C) 2018 Pengutronix, Lucas Stach <kernel@pengutronix.de>
+ */
+
+#ifndef __DT_BINDINGS_IMX8MQ_POWER_H__
+#define __DT_BINDINGS_IMX8MQ_POWER_H__
+
+#define IMX8M_POWER_DOMAIN_MIPI                0
+#define IMX8M_POWER_DOMAIN_PCIE1       1
+#define IMX8M_POWER_DOMAIN_USB_OTG1    2
+#define IMX8M_POWER_DOMAIN_USB_OTG2    3
+#define IMX8M_POWER_DOMAIN_DDR1                4
+#define IMX8M_POWER_DOMAIN_GPU         5
+#define IMX8M_POWER_DOMAIN_VPU         6
+#define IMX8M_POWER_DOMAIN_DISP                7
+#define IMX8M_POWER_DOMAIN_MIPI_CSI1   8
+#define IMX8M_POWER_DOMAIN_MIPI_CSI2   9
+#define IMX8M_POWER_DOMAIN_PCIE2       10
+
+#endif
index bf54779d16252a46090096e969a0fe45ec1f9a29..85cc5f23cf9f8e723d0f4d41bd7be653fad13d73 100644 (file)
 
 #define R8A77970_PD_CA53_CPU0           5
 #define R8A77970_PD_CA53_CPU1           6
-#define R8A77970_PD_CR7                        13
 #define R8A77970_PD_CA53_SCU           21
 #define R8A77970_PD_A2IR0              23
-#define R8A77970_PD_A3IR                       24
+#define R8A77970_PD_A3IR               24
 #define R8A77970_PD_A2IR1              27
-#define R8A77970_PD_A2IR2              28
-#define R8A77970_PD_A2IR3              29
+#define R8A77970_PD_A2DP               28
+#define R8A77970_PD_A2CN               29
 #define R8A77970_PD_A2SC0              30
 #define R8A77970_PD_A2SC1              31
 
index 2c90c12377253e5f10d7772b2a292bd57cef1bd0..e12c8587b87ec8d58f3670c67a5a10a7805de6d9 100644 (file)
 #define R8A77980_PD_A2SC2              0
 #define R8A77980_PD_A2SC3              1
 #define R8A77980_PD_A2SC4              2
-#define R8A77980_PD_A2PD0              3
-#define R8A77980_PD_A2PD1              4
+#define R8A77980_PD_A2DP0              3
+#define R8A77980_PD_A2DP1              4
 #define R8A77980_PD_CA53_CPU0          5
 #define R8A77980_PD_CA53_CPU1          6
 #define R8A77980_PD_CA53_CPU2          7
 #define R8A77980_PD_CA53_CPU3          8
 #define R8A77980_PD_A2CN               10
-#define R8A77980_PD_A3VIP              11
+#define R8A77980_PD_A3VIP0             11
 #define R8A77980_PD_A2IR5              12
 #define R8A77980_PD_CR7                        13
 #define R8A77980_PD_A2IR4              15
index b3ff8e09a78f41ae29cf4a27bc956fac64f20dfb..3575f9f4b0bdfb75a89aeaf204dd74172279c9ac 100644 (file)
@@ -1,9 +1,6 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /*
  *  Copyright Â© 2015 Broadcom
- *
- * 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.
  */
 
 #ifndef _DT_BINDINGS_ARM_BCM2835_RPI_POWER_H
diff --git a/include/dt-bindings/power/rk3066-power.h b/include/dt-bindings/power/rk3066-power.h
new file mode 100644 (file)
index 0000000..acf9f31
--- /dev/null
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __DT_BINDINGS_POWER_RK3066_POWER_H__
+#define __DT_BINDINGS_POWER_RK3066_POWER_H__
+
+/* VD_CORE */
+#define RK3066_PD_A9_0         0
+#define RK3066_PD_A9_1         1
+#define RK3066_PD_DBG          4
+#define RK3066_PD_SCU          5
+
+/* VD_LOGIC */
+#define RK3066_PD_VIDEO                6
+#define RK3066_PD_VIO          7
+#define RK3066_PD_GPU          8
+#define RK3066_PD_PERI         9
+#define RK3066_PD_CPU          10
+#define RK3066_PD_ALIVE                11
+
+/* VD_PMU */
+#define RK3066_PD_RTC          12
+
+#endif
diff --git a/include/dt-bindings/power/rk3188-power.h b/include/dt-bindings/power/rk3188-power.h
new file mode 100644 (file)
index 0000000..93d23df
--- /dev/null
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __DT_BINDINGS_POWER_RK3188_POWER_H__
+#define __DT_BINDINGS_POWER_RK3188_POWER_H__
+
+/* VD_CORE */
+#define RK3188_PD_A9_0         0
+#define RK3188_PD_A9_1         1
+#define RK3188_PD_A9_2         2
+#define RK3188_PD_A9_3         3
+#define RK3188_PD_DBG          4
+#define RK3188_PD_SCU          5
+
+/* VD_LOGIC */
+#define RK3188_PD_VIDEO                6
+#define RK3188_PD_VIO          7
+#define RK3188_PD_GPU          8
+#define RK3188_PD_PERI         9
+#define RK3188_PD_CPU          10
+#define RK3188_PD_ALIVE                11
+
+/* VD_PMU */
+#define RK3188_PD_RTC          12
+
+#endif
index 9fc594f69eff3e693cf4297fe33a1dd249048c94..fceb5df0709715239d96696d170a823636666c92 100644 (file)
@@ -23,15 +23,4 @@ struct pxad_param {
        enum pxad_chan_prio prio;
 };
 
-struct dma_chan;
-
-#ifdef CONFIG_PXA_DMA
-bool pxad_filter_fn(struct dma_chan *chan, void *param);
-#else
-static inline bool pxad_filter_fn(struct dma_chan *chan, void *param)
-{
-       return false;
-}
-#endif
-
 #endif /* _PXA_DMA_H_ */
index 29ada609de030759d48750f2ad8ce307e55c8996..ebc55098faee29134fa8be693b69d081fe2f1a9a 100644 (file)
@@ -14,4 +14,5 @@
 #include <linux/firmware/imx/types.h>
 
 #include <linux/firmware/imx/svc/misc.h>
+#include <linux/firmware/imx/svc/pm.h>
 #endif /* _SC_SCI_H */
diff --git a/include/linux/firmware/imx/svc/pm.h b/include/linux/firmware/imx/svc/pm.h
new file mode 100644 (file)
index 0000000..1f6975d
--- /dev/null
@@ -0,0 +1,85 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2018 NXP
+ *
+ * Header file containing the public API for the System Controller (SC)
+ * Power Management (PM) function. This includes functions for power state
+ * control, clock control, reset control, and wake-up event control.
+ *
+ * PM_SVC (SVC) Power Management Service
+ *
+ * Module for the Power Management (PM) service.
+ */
+
+#ifndef _SC_PM_API_H
+#define _SC_PM_API_H
+
+#include <linux/firmware/imx/sci.h>
+
+/*
+ * This type is used to indicate RPC PM function calls.
+ */
+enum imx_sc_pm_func {
+       IMX_SC_PM_FUNC_UNKNOWN = 0,
+       IMX_SC_PM_FUNC_SET_SYS_POWER_MODE = 19,
+       IMX_SC_PM_FUNC_SET_PARTITION_POWER_MODE = 1,
+       IMX_SC_PM_FUNC_GET_SYS_POWER_MODE = 2,
+       IMX_SC_PM_FUNC_SET_RESOURCE_POWER_MODE = 3,
+       IMX_SC_PM_FUNC_GET_RESOURCE_POWER_MODE = 4,
+       IMX_SC_PM_FUNC_REQ_LOW_POWER_MODE = 16,
+       IMX_SC_PM_FUNC_SET_CPU_RESUME_ADDR = 17,
+       IMX_SC_PM_FUNC_REQ_SYS_IF_POWER_MODE = 18,
+       IMX_SC_PM_FUNC_SET_CLOCK_RATE = 5,
+       IMX_SC_PM_FUNC_GET_CLOCK_RATE = 6,
+       IMX_SC_PM_FUNC_CLOCK_ENABLE = 7,
+       IMX_SC_PM_FUNC_SET_CLOCK_PARENT = 14,
+       IMX_SC_PM_FUNC_GET_CLOCK_PARENT = 15,
+       IMX_SC_PM_FUNC_RESET = 13,
+       IMX_SC_PM_FUNC_RESET_REASON = 10,
+       IMX_SC_PM_FUNC_BOOT = 8,
+       IMX_SC_PM_FUNC_REBOOT = 9,
+       IMX_SC_PM_FUNC_REBOOT_PARTITION = 12,
+       IMX_SC_PM_FUNC_CPU_START = 11,
+};
+
+/*
+ * Defines for ALL parameters
+ */
+#define IMX_SC_PM_CLK_ALL              UINT8_MAX       /* All clocks */
+
+/*
+ * Defines for SC PM Power Mode
+ */
+#define IMX_SC_PM_PW_MODE_OFF  0       /* Power off */
+#define IMX_SC_PM_PW_MODE_STBY 1       /* Power in standby */
+#define IMX_SC_PM_PW_MODE_LP   2       /* Power in low-power */
+#define IMX_SC_PM_PW_MODE_ON   3       /* Power on */
+
+/*
+ * Defines for SC PM CLK
+ */
+#define IMX_SC_PM_CLK_SLV_BUS  0       /* Slave bus clock */
+#define IMX_SC_PM_CLK_MST_BUS  1       /* Master bus clock */
+#define IMX_SC_PM_CLK_PER      2       /* Peripheral clock */
+#define IMX_SC_PM_CLK_PHY      3       /* Phy clock */
+#define IMX_SC_PM_CLK_MISC     4       /* Misc clock */
+#define IMX_SC_PM_CLK_MISC0    0       /* Misc 0 clock */
+#define IMX_SC_PM_CLK_MISC1    1       /* Misc 1 clock */
+#define IMX_SC_PM_CLK_MISC2    2       /* Misc 2 clock */
+#define IMX_SC_PM_CLK_MISC3    3       /* Misc 3 clock */
+#define IMX_SC_PM_CLK_MISC4    4       /* Misc 4 clock */
+#define IMX_SC_PM_CLK_CPU      2       /* CPU clock */
+#define IMX_SC_PM_CLK_PLL      4       /* PLL */
+#define IMX_SC_PM_CLK_BYPASS   4       /* Bypass clock */
+
+/*
+ * Defines for SC PM CLK Parent
+ */
+#define IMX_SC_PM_PARENT_XTAL  0       /* Parent is XTAL. */
+#define IMX_SC_PM_PARENT_PLL0  1       /* Parent is PLL0 */
+#define IMX_SC_PM_PARENT_PLL1  2       /* Parent is PLL1 or PLL0/2 */
+#define IMX_SC_PM_PARENT_PLL2  3       /* Parent in PLL2 or PLL0/4 */
+#define IMX_SC_PM_PARENT_BYPS  4       /* Parent is a bypass clock. */
+
+#endif /* _SC_PM_API_H */
index 9cbf0c4a6069e520390d68e8bf7168141941c9a5..80821100e85fccf02387fc9d0d99782b0daec155 100644 (file)
@@ -9,558 +9,6 @@
 #ifndef _SC_TYPES_H
 #define _SC_TYPES_H
 
-/*
- * This type is used to indicate a resource. Resources include peripherals
- * and bus masters (but not memory regions). Note items from list should
- * never be changed or removed (only added to at the end of the list).
- */
-enum imx_sc_rsrc {
-       IMX_SC_R_A53 = 0,
-       IMX_SC_R_A53_0 = 1,
-       IMX_SC_R_A53_1 = 2,
-       IMX_SC_R_A53_2 = 3,
-       IMX_SC_R_A53_3 = 4,
-       IMX_SC_R_A72 = 5,
-       IMX_SC_R_A72_0 = 6,
-       IMX_SC_R_A72_1 = 7,
-       IMX_SC_R_A72_2 = 8,
-       IMX_SC_R_A72_3 = 9,
-       IMX_SC_R_CCI = 10,
-       IMX_SC_R_DB = 11,
-       IMX_SC_R_DRC_0 = 12,
-       IMX_SC_R_DRC_1 = 13,
-       IMX_SC_R_GIC_SMMU = 14,
-       IMX_SC_R_IRQSTR_M4_0 = 15,
-       IMX_SC_R_IRQSTR_M4_1 = 16,
-       IMX_SC_R_SMMU = 17,
-       IMX_SC_R_GIC = 18,
-       IMX_SC_R_DC_0_BLIT0 = 19,
-       IMX_SC_R_DC_0_BLIT1 = 20,
-       IMX_SC_R_DC_0_BLIT2 = 21,
-       IMX_SC_R_DC_0_BLIT_OUT = 22,
-       IMX_SC_R_DC_0_CAPTURE0 = 23,
-       IMX_SC_R_DC_0_CAPTURE1 = 24,
-       IMX_SC_R_DC_0_WARP = 25,
-       IMX_SC_R_DC_0_INTEGRAL0 = 26,
-       IMX_SC_R_DC_0_INTEGRAL1 = 27,
-       IMX_SC_R_DC_0_VIDEO0 = 28,
-       IMX_SC_R_DC_0_VIDEO1 = 29,
-       IMX_SC_R_DC_0_FRAC0 = 30,
-       IMX_SC_R_DC_0_FRAC1 = 31,
-       IMX_SC_R_DC_0 = 32,
-       IMX_SC_R_GPU_2_PID0 = 33,
-       IMX_SC_R_DC_0_PLL_0 = 34,
-       IMX_SC_R_DC_0_PLL_1 = 35,
-       IMX_SC_R_DC_1_BLIT0 = 36,
-       IMX_SC_R_DC_1_BLIT1 = 37,
-       IMX_SC_R_DC_1_BLIT2 = 38,
-       IMX_SC_R_DC_1_BLIT_OUT = 39,
-       IMX_SC_R_DC_1_CAPTURE0 = 40,
-       IMX_SC_R_DC_1_CAPTURE1 = 41,
-       IMX_SC_R_DC_1_WARP = 42,
-       IMX_SC_R_DC_1_INTEGRAL0 = 43,
-       IMX_SC_R_DC_1_INTEGRAL1 = 44,
-       IMX_SC_R_DC_1_VIDEO0 = 45,
-       IMX_SC_R_DC_1_VIDEO1 = 46,
-       IMX_SC_R_DC_1_FRAC0 = 47,
-       IMX_SC_R_DC_1_FRAC1 = 48,
-       IMX_SC_R_DC_1 = 49,
-       IMX_SC_R_GPU_3_PID0 = 50,
-       IMX_SC_R_DC_1_PLL_0 = 51,
-       IMX_SC_R_DC_1_PLL_1 = 52,
-       IMX_SC_R_SPI_0 = 53,
-       IMX_SC_R_SPI_1 = 54,
-       IMX_SC_R_SPI_2 = 55,
-       IMX_SC_R_SPI_3 = 56,
-       IMX_SC_R_UART_0 = 57,
-       IMX_SC_R_UART_1 = 58,
-       IMX_SC_R_UART_2 = 59,
-       IMX_SC_R_UART_3 = 60,
-       IMX_SC_R_UART_4 = 61,
-       IMX_SC_R_EMVSIM_0 = 62,
-       IMX_SC_R_EMVSIM_1 = 63,
-       IMX_SC_R_DMA_0_CH0 = 64,
-       IMX_SC_R_DMA_0_CH1 = 65,
-       IMX_SC_R_DMA_0_CH2 = 66,
-       IMX_SC_R_DMA_0_CH3 = 67,
-       IMX_SC_R_DMA_0_CH4 = 68,
-       IMX_SC_R_DMA_0_CH5 = 69,
-       IMX_SC_R_DMA_0_CH6 = 70,
-       IMX_SC_R_DMA_0_CH7 = 71,
-       IMX_SC_R_DMA_0_CH8 = 72,
-       IMX_SC_R_DMA_0_CH9 = 73,
-       IMX_SC_R_DMA_0_CH10 = 74,
-       IMX_SC_R_DMA_0_CH11 = 75,
-       IMX_SC_R_DMA_0_CH12 = 76,
-       IMX_SC_R_DMA_0_CH13 = 77,
-       IMX_SC_R_DMA_0_CH14 = 78,
-       IMX_SC_R_DMA_0_CH15 = 79,
-       IMX_SC_R_DMA_0_CH16 = 80,
-       IMX_SC_R_DMA_0_CH17 = 81,
-       IMX_SC_R_DMA_0_CH18 = 82,
-       IMX_SC_R_DMA_0_CH19 = 83,
-       IMX_SC_R_DMA_0_CH20 = 84,
-       IMX_SC_R_DMA_0_CH21 = 85,
-       IMX_SC_R_DMA_0_CH22 = 86,
-       IMX_SC_R_DMA_0_CH23 = 87,
-       IMX_SC_R_DMA_0_CH24 = 88,
-       IMX_SC_R_DMA_0_CH25 = 89,
-       IMX_SC_R_DMA_0_CH26 = 90,
-       IMX_SC_R_DMA_0_CH27 = 91,
-       IMX_SC_R_DMA_0_CH28 = 92,
-       IMX_SC_R_DMA_0_CH29 = 93,
-       IMX_SC_R_DMA_0_CH30 = 94,
-       IMX_SC_R_DMA_0_CH31 = 95,
-       IMX_SC_R_I2C_0 = 96,
-       IMX_SC_R_I2C_1 = 97,
-       IMX_SC_R_I2C_2 = 98,
-       IMX_SC_R_I2C_3 = 99,
-       IMX_SC_R_I2C_4 = 100,
-       IMX_SC_R_ADC_0 = 101,
-       IMX_SC_R_ADC_1 = 102,
-       IMX_SC_R_FTM_0 = 103,
-       IMX_SC_R_FTM_1 = 104,
-       IMX_SC_R_CAN_0 = 105,
-       IMX_SC_R_CAN_1 = 106,
-       IMX_SC_R_CAN_2 = 107,
-       IMX_SC_R_DMA_1_CH0 = 108,
-       IMX_SC_R_DMA_1_CH1 = 109,
-       IMX_SC_R_DMA_1_CH2 = 110,
-       IMX_SC_R_DMA_1_CH3 = 111,
-       IMX_SC_R_DMA_1_CH4 = 112,
-       IMX_SC_R_DMA_1_CH5 = 113,
-       IMX_SC_R_DMA_1_CH6 = 114,
-       IMX_SC_R_DMA_1_CH7 = 115,
-       IMX_SC_R_DMA_1_CH8 = 116,
-       IMX_SC_R_DMA_1_CH9 = 117,
-       IMX_SC_R_DMA_1_CH10 = 118,
-       IMX_SC_R_DMA_1_CH11 = 119,
-       IMX_SC_R_DMA_1_CH12 = 120,
-       IMX_SC_R_DMA_1_CH13 = 121,
-       IMX_SC_R_DMA_1_CH14 = 122,
-       IMX_SC_R_DMA_1_CH15 = 123,
-       IMX_SC_R_DMA_1_CH16 = 124,
-       IMX_SC_R_DMA_1_CH17 = 125,
-       IMX_SC_R_DMA_1_CH18 = 126,
-       IMX_SC_R_DMA_1_CH19 = 127,
-       IMX_SC_R_DMA_1_CH20 = 128,
-       IMX_SC_R_DMA_1_CH21 = 129,
-       IMX_SC_R_DMA_1_CH22 = 130,
-       IMX_SC_R_DMA_1_CH23 = 131,
-       IMX_SC_R_DMA_1_CH24 = 132,
-       IMX_SC_R_DMA_1_CH25 = 133,
-       IMX_SC_R_DMA_1_CH26 = 134,
-       IMX_SC_R_DMA_1_CH27 = 135,
-       IMX_SC_R_DMA_1_CH28 = 136,
-       IMX_SC_R_DMA_1_CH29 = 137,
-       IMX_SC_R_DMA_1_CH30 = 138,
-       IMX_SC_R_DMA_1_CH31 = 139,
-       IMX_SC_R_UNUSED1 = 140,
-       IMX_SC_R_UNUSED2 = 141,
-       IMX_SC_R_UNUSED3 = 142,
-       IMX_SC_R_UNUSED4 = 143,
-       IMX_SC_R_GPU_0_PID0 = 144,
-       IMX_SC_R_GPU_0_PID1 = 145,
-       IMX_SC_R_GPU_0_PID2 = 146,
-       IMX_SC_R_GPU_0_PID3 = 147,
-       IMX_SC_R_GPU_1_PID0 = 148,
-       IMX_SC_R_GPU_1_PID1 = 149,
-       IMX_SC_R_GPU_1_PID2 = 150,
-       IMX_SC_R_GPU_1_PID3 = 151,
-       IMX_SC_R_PCIE_A = 152,
-       IMX_SC_R_SERDES_0 = 153,
-       IMX_SC_R_MATCH_0 = 154,
-       IMX_SC_R_MATCH_1 = 155,
-       IMX_SC_R_MATCH_2 = 156,
-       IMX_SC_R_MATCH_3 = 157,
-       IMX_SC_R_MATCH_4 = 158,
-       IMX_SC_R_MATCH_5 = 159,
-       IMX_SC_R_MATCH_6 = 160,
-       IMX_SC_R_MATCH_7 = 161,
-       IMX_SC_R_MATCH_8 = 162,
-       IMX_SC_R_MATCH_9 = 163,
-       IMX_SC_R_MATCH_10 = 164,
-       IMX_SC_R_MATCH_11 = 165,
-       IMX_SC_R_MATCH_12 = 166,
-       IMX_SC_R_MATCH_13 = 167,
-       IMX_SC_R_MATCH_14 = 168,
-       IMX_SC_R_PCIE_B = 169,
-       IMX_SC_R_SATA_0 = 170,
-       IMX_SC_R_SERDES_1 = 171,
-       IMX_SC_R_HSIO_GPIO = 172,
-       IMX_SC_R_MATCH_15 = 173,
-       IMX_SC_R_MATCH_16 = 174,
-       IMX_SC_R_MATCH_17 = 175,
-       IMX_SC_R_MATCH_18 = 176,
-       IMX_SC_R_MATCH_19 = 177,
-       IMX_SC_R_MATCH_20 = 178,
-       IMX_SC_R_MATCH_21 = 179,
-       IMX_SC_R_MATCH_22 = 180,
-       IMX_SC_R_MATCH_23 = 181,
-       IMX_SC_R_MATCH_24 = 182,
-       IMX_SC_R_MATCH_25 = 183,
-       IMX_SC_R_MATCH_26 = 184,
-       IMX_SC_R_MATCH_27 = 185,
-       IMX_SC_R_MATCH_28 = 186,
-       IMX_SC_R_LCD_0 = 187,
-       IMX_SC_R_LCD_0_PWM_0 = 188,
-       IMX_SC_R_LCD_0_I2C_0 = 189,
-       IMX_SC_R_LCD_0_I2C_1 = 190,
-       IMX_SC_R_PWM_0 = 191,
-       IMX_SC_R_PWM_1 = 192,
-       IMX_SC_R_PWM_2 = 193,
-       IMX_SC_R_PWM_3 = 194,
-       IMX_SC_R_PWM_4 = 195,
-       IMX_SC_R_PWM_5 = 196,
-       IMX_SC_R_PWM_6 = 197,
-       IMX_SC_R_PWM_7 = 198,
-       IMX_SC_R_GPIO_0 = 199,
-       IMX_SC_R_GPIO_1 = 200,
-       IMX_SC_R_GPIO_2 = 201,
-       IMX_SC_R_GPIO_3 = 202,
-       IMX_SC_R_GPIO_4 = 203,
-       IMX_SC_R_GPIO_5 = 204,
-       IMX_SC_R_GPIO_6 = 205,
-       IMX_SC_R_GPIO_7 = 206,
-       IMX_SC_R_GPT_0 = 207,
-       IMX_SC_R_GPT_1 = 208,
-       IMX_SC_R_GPT_2 = 209,
-       IMX_SC_R_GPT_3 = 210,
-       IMX_SC_R_GPT_4 = 211,
-       IMX_SC_R_KPP = 212,
-       IMX_SC_R_MU_0A = 213,
-       IMX_SC_R_MU_1A = 214,
-       IMX_SC_R_MU_2A = 215,
-       IMX_SC_R_MU_3A = 216,
-       IMX_SC_R_MU_4A = 217,
-       IMX_SC_R_MU_5A = 218,
-       IMX_SC_R_MU_6A = 219,
-       IMX_SC_R_MU_7A = 220,
-       IMX_SC_R_MU_8A = 221,
-       IMX_SC_R_MU_9A = 222,
-       IMX_SC_R_MU_10A = 223,
-       IMX_SC_R_MU_11A = 224,
-       IMX_SC_R_MU_12A = 225,
-       IMX_SC_R_MU_13A = 226,
-       IMX_SC_R_MU_5B = 227,
-       IMX_SC_R_MU_6B = 228,
-       IMX_SC_R_MU_7B = 229,
-       IMX_SC_R_MU_8B = 230,
-       IMX_SC_R_MU_9B = 231,
-       IMX_SC_R_MU_10B = 232,
-       IMX_SC_R_MU_11B = 233,
-       IMX_SC_R_MU_12B = 234,
-       IMX_SC_R_MU_13B = 235,
-       IMX_SC_R_ROM_0 = 236,
-       IMX_SC_R_FSPI_0 = 237,
-       IMX_SC_R_FSPI_1 = 238,
-       IMX_SC_R_IEE = 239,
-       IMX_SC_R_IEE_R0 = 240,
-       IMX_SC_R_IEE_R1 = 241,
-       IMX_SC_R_IEE_R2 = 242,
-       IMX_SC_R_IEE_R3 = 243,
-       IMX_SC_R_IEE_R4 = 244,
-       IMX_SC_R_IEE_R5 = 245,
-       IMX_SC_R_IEE_R6 = 246,
-       IMX_SC_R_IEE_R7 = 247,
-       IMX_SC_R_SDHC_0 = 248,
-       IMX_SC_R_SDHC_1 = 249,
-       IMX_SC_R_SDHC_2 = 250,
-       IMX_SC_R_ENET_0 = 251,
-       IMX_SC_R_ENET_1 = 252,
-       IMX_SC_R_MLB_0 = 253,
-       IMX_SC_R_DMA_2_CH0 = 254,
-       IMX_SC_R_DMA_2_CH1 = 255,
-       IMX_SC_R_DMA_2_CH2 = 256,
-       IMX_SC_R_DMA_2_CH3 = 257,
-       IMX_SC_R_DMA_2_CH4 = 258,
-       IMX_SC_R_USB_0 = 259,
-       IMX_SC_R_USB_1 = 260,
-       IMX_SC_R_USB_0_PHY = 261,
-       IMX_SC_R_USB_2 = 262,
-       IMX_SC_R_USB_2_PHY = 263,
-       IMX_SC_R_DTCP = 264,
-       IMX_SC_R_NAND = 265,
-       IMX_SC_R_LVDS_0 = 266,
-       IMX_SC_R_LVDS_0_PWM_0 = 267,
-       IMX_SC_R_LVDS_0_I2C_0 = 268,
-       IMX_SC_R_LVDS_0_I2C_1 = 269,
-       IMX_SC_R_LVDS_1 = 270,
-       IMX_SC_R_LVDS_1_PWM_0 = 271,
-       IMX_SC_R_LVDS_1_I2C_0 = 272,
-       IMX_SC_R_LVDS_1_I2C_1 = 273,
-       IMX_SC_R_LVDS_2 = 274,
-       IMX_SC_R_LVDS_2_PWM_0 = 275,
-       IMX_SC_R_LVDS_2_I2C_0 = 276,
-       IMX_SC_R_LVDS_2_I2C_1 = 277,
-       IMX_SC_R_M4_0_PID0 = 278,
-       IMX_SC_R_M4_0_PID1 = 279,
-       IMX_SC_R_M4_0_PID2 = 280,
-       IMX_SC_R_M4_0_PID3 = 281,
-       IMX_SC_R_M4_0_PID4 = 282,
-       IMX_SC_R_M4_0_RGPIO = 283,
-       IMX_SC_R_M4_0_SEMA42 = 284,
-       IMX_SC_R_M4_0_TPM = 285,
-       IMX_SC_R_M4_0_PIT = 286,
-       IMX_SC_R_M4_0_UART = 287,
-       IMX_SC_R_M4_0_I2C = 288,
-       IMX_SC_R_M4_0_INTMUX = 289,
-       IMX_SC_R_M4_0_SIM = 290,
-       IMX_SC_R_M4_0_WDOG = 291,
-       IMX_SC_R_M4_0_MU_0B = 292,
-       IMX_SC_R_M4_0_MU_0A0 = 293,
-       IMX_SC_R_M4_0_MU_0A1 = 294,
-       IMX_SC_R_M4_0_MU_0A2 = 295,
-       IMX_SC_R_M4_0_MU_0A3 = 296,
-       IMX_SC_R_M4_0_MU_1A = 297,
-       IMX_SC_R_M4_1_PID0 = 298,
-       IMX_SC_R_M4_1_PID1 = 299,
-       IMX_SC_R_M4_1_PID2 = 300,
-       IMX_SC_R_M4_1_PID3 = 301,
-       IMX_SC_R_M4_1_PID4 = 302,
-       IMX_SC_R_M4_1_RGPIO = 303,
-       IMX_SC_R_M4_1_SEMA42 = 304,
-       IMX_SC_R_M4_1_TPM = 305,
-       IMX_SC_R_M4_1_PIT = 306,
-       IMX_SC_R_M4_1_UART = 307,
-       IMX_SC_R_M4_1_I2C = 308,
-       IMX_SC_R_M4_1_INTMUX = 309,
-       IMX_SC_R_M4_1_SIM = 310,
-       IMX_SC_R_M4_1_WDOG = 311,
-       IMX_SC_R_M4_1_MU_0B = 312,
-       IMX_SC_R_M4_1_MU_0A0 = 313,
-       IMX_SC_R_M4_1_MU_0A1 = 314,
-       IMX_SC_R_M4_1_MU_0A2 = 315,
-       IMX_SC_R_M4_1_MU_0A3 = 316,
-       IMX_SC_R_M4_1_MU_1A = 317,
-       IMX_SC_R_SAI_0 = 318,
-       IMX_SC_R_SAI_1 = 319,
-       IMX_SC_R_SAI_2 = 320,
-       IMX_SC_R_IRQSTR_SCU2 = 321,
-       IMX_SC_R_IRQSTR_DSP = 322,
-       IMX_SC_R_UNUSED5 = 323,
-       IMX_SC_R_UNUSED6 = 324,
-       IMX_SC_R_AUDIO_PLL_0 = 325,
-       IMX_SC_R_PI_0 = 326,
-       IMX_SC_R_PI_0_PWM_0 = 327,
-       IMX_SC_R_PI_0_PWM_1 = 328,
-       IMX_SC_R_PI_0_I2C_0 = 329,
-       IMX_SC_R_PI_0_PLL = 330,
-       IMX_SC_R_PI_1 = 331,
-       IMX_SC_R_PI_1_PWM_0 = 332,
-       IMX_SC_R_PI_1_PWM_1 = 333,
-       IMX_SC_R_PI_1_I2C_0 = 334,
-       IMX_SC_R_PI_1_PLL = 335,
-       IMX_SC_R_SC_PID0 = 336,
-       IMX_SC_R_SC_PID1 = 337,
-       IMX_SC_R_SC_PID2 = 338,
-       IMX_SC_R_SC_PID3 = 339,
-       IMX_SC_R_SC_PID4 = 340,
-       IMX_SC_R_SC_SEMA42 = 341,
-       IMX_SC_R_SC_TPM = 342,
-       IMX_SC_R_SC_PIT = 343,
-       IMX_SC_R_SC_UART = 344,
-       IMX_SC_R_SC_I2C = 345,
-       IMX_SC_R_SC_MU_0B = 346,
-       IMX_SC_R_SC_MU_0A0 = 347,
-       IMX_SC_R_SC_MU_0A1 = 348,
-       IMX_SC_R_SC_MU_0A2 = 349,
-       IMX_SC_R_SC_MU_0A3 = 350,
-       IMX_SC_R_SC_MU_1A = 351,
-       IMX_SC_R_SYSCNT_RD = 352,
-       IMX_SC_R_SYSCNT_CMP = 353,
-       IMX_SC_R_DEBUG = 354,
-       IMX_SC_R_SYSTEM = 355,
-       IMX_SC_R_SNVS = 356,
-       IMX_SC_R_OTP = 357,
-       IMX_SC_R_VPU_PID0 = 358,
-       IMX_SC_R_VPU_PID1 = 359,
-       IMX_SC_R_VPU_PID2 = 360,
-       IMX_SC_R_VPU_PID3 = 361,
-       IMX_SC_R_VPU_PID4 = 362,
-       IMX_SC_R_VPU_PID5 = 363,
-       IMX_SC_R_VPU_PID6 = 364,
-       IMX_SC_R_VPU_PID7 = 365,
-       IMX_SC_R_VPU_UART = 366,
-       IMX_SC_R_VPUCORE = 367,
-       IMX_SC_R_VPUCORE_0 = 368,
-       IMX_SC_R_VPUCORE_1 = 369,
-       IMX_SC_R_VPUCORE_2 = 370,
-       IMX_SC_R_VPUCORE_3 = 371,
-       IMX_SC_R_DMA_4_CH0 = 372,
-       IMX_SC_R_DMA_4_CH1 = 373,
-       IMX_SC_R_DMA_4_CH2 = 374,
-       IMX_SC_R_DMA_4_CH3 = 375,
-       IMX_SC_R_DMA_4_CH4 = 376,
-       IMX_SC_R_ISI_CH0 = 377,
-       IMX_SC_R_ISI_CH1 = 378,
-       IMX_SC_R_ISI_CH2 = 379,
-       IMX_SC_R_ISI_CH3 = 380,
-       IMX_SC_R_ISI_CH4 = 381,
-       IMX_SC_R_ISI_CH5 = 382,
-       IMX_SC_R_ISI_CH6 = 383,
-       IMX_SC_R_ISI_CH7 = 384,
-       IMX_SC_R_MJPEG_DEC_S0 = 385,
-       IMX_SC_R_MJPEG_DEC_S1 = 386,
-       IMX_SC_R_MJPEG_DEC_S2 = 387,
-       IMX_SC_R_MJPEG_DEC_S3 = 388,
-       IMX_SC_R_MJPEG_ENC_S0 = 389,
-       IMX_SC_R_MJPEG_ENC_S1 = 390,
-       IMX_SC_R_MJPEG_ENC_S2 = 391,
-       IMX_SC_R_MJPEG_ENC_S3 = 392,
-       IMX_SC_R_MIPI_0 = 393,
-       IMX_SC_R_MIPI_0_PWM_0 = 394,
-       IMX_SC_R_MIPI_0_I2C_0 = 395,
-       IMX_SC_R_MIPI_0_I2C_1 = 396,
-       IMX_SC_R_MIPI_1 = 397,
-       IMX_SC_R_MIPI_1_PWM_0 = 398,
-       IMX_SC_R_MIPI_1_I2C_0 = 399,
-       IMX_SC_R_MIPI_1_I2C_1 = 400,
-       IMX_SC_R_CSI_0 = 401,
-       IMX_SC_R_CSI_0_PWM_0 = 402,
-       IMX_SC_R_CSI_0_I2C_0 = 403,
-       IMX_SC_R_CSI_1 = 404,
-       IMX_SC_R_CSI_1_PWM_0 = 405,
-       IMX_SC_R_CSI_1_I2C_0 = 406,
-       IMX_SC_R_HDMI = 407,
-       IMX_SC_R_HDMI_I2S = 408,
-       IMX_SC_R_HDMI_I2C_0 = 409,
-       IMX_SC_R_HDMI_PLL_0 = 410,
-       IMX_SC_R_HDMI_RX = 411,
-       IMX_SC_R_HDMI_RX_BYPASS = 412,
-       IMX_SC_R_HDMI_RX_I2C_0 = 413,
-       IMX_SC_R_ASRC_0 = 414,
-       IMX_SC_R_ESAI_0 = 415,
-       IMX_SC_R_SPDIF_0 = 416,
-       IMX_SC_R_SPDIF_1 = 417,
-       IMX_SC_R_SAI_3 = 418,
-       IMX_SC_R_SAI_4 = 419,
-       IMX_SC_R_SAI_5 = 420,
-       IMX_SC_R_GPT_5 = 421,
-       IMX_SC_R_GPT_6 = 422,
-       IMX_SC_R_GPT_7 = 423,
-       IMX_SC_R_GPT_8 = 424,
-       IMX_SC_R_GPT_9 = 425,
-       IMX_SC_R_GPT_10 = 426,
-       IMX_SC_R_DMA_2_CH5 = 427,
-       IMX_SC_R_DMA_2_CH6 = 428,
-       IMX_SC_R_DMA_2_CH7 = 429,
-       IMX_SC_R_DMA_2_CH8 = 430,
-       IMX_SC_R_DMA_2_CH9 = 431,
-       IMX_SC_R_DMA_2_CH10 = 432,
-       IMX_SC_R_DMA_2_CH11 = 433,
-       IMX_SC_R_DMA_2_CH12 = 434,
-       IMX_SC_R_DMA_2_CH13 = 435,
-       IMX_SC_R_DMA_2_CH14 = 436,
-       IMX_SC_R_DMA_2_CH15 = 437,
-       IMX_SC_R_DMA_2_CH16 = 438,
-       IMX_SC_R_DMA_2_CH17 = 439,
-       IMX_SC_R_DMA_2_CH18 = 440,
-       IMX_SC_R_DMA_2_CH19 = 441,
-       IMX_SC_R_DMA_2_CH20 = 442,
-       IMX_SC_R_DMA_2_CH21 = 443,
-       IMX_SC_R_DMA_2_CH22 = 444,
-       IMX_SC_R_DMA_2_CH23 = 445,
-       IMX_SC_R_DMA_2_CH24 = 446,
-       IMX_SC_R_DMA_2_CH25 = 447,
-       IMX_SC_R_DMA_2_CH26 = 448,
-       IMX_SC_R_DMA_2_CH27 = 449,
-       IMX_SC_R_DMA_2_CH28 = 450,
-       IMX_SC_R_DMA_2_CH29 = 451,
-       IMX_SC_R_DMA_2_CH30 = 452,
-       IMX_SC_R_DMA_2_CH31 = 453,
-       IMX_SC_R_ASRC_1 = 454,
-       IMX_SC_R_ESAI_1 = 455,
-       IMX_SC_R_SAI_6 = 456,
-       IMX_SC_R_SAI_7 = 457,
-       IMX_SC_R_AMIX = 458,
-       IMX_SC_R_MQS_0 = 459,
-       IMX_SC_R_DMA_3_CH0 = 460,
-       IMX_SC_R_DMA_3_CH1 = 461,
-       IMX_SC_R_DMA_3_CH2 = 462,
-       IMX_SC_R_DMA_3_CH3 = 463,
-       IMX_SC_R_DMA_3_CH4 = 464,
-       IMX_SC_R_DMA_3_CH5 = 465,
-       IMX_SC_R_DMA_3_CH6 = 466,
-       IMX_SC_R_DMA_3_CH7 = 467,
-       IMX_SC_R_DMA_3_CH8 = 468,
-       IMX_SC_R_DMA_3_CH9 = 469,
-       IMX_SC_R_DMA_3_CH10 = 470,
-       IMX_SC_R_DMA_3_CH11 = 471,
-       IMX_SC_R_DMA_3_CH12 = 472,
-       IMX_SC_R_DMA_3_CH13 = 473,
-       IMX_SC_R_DMA_3_CH14 = 474,
-       IMX_SC_R_DMA_3_CH15 = 475,
-       IMX_SC_R_DMA_3_CH16 = 476,
-       IMX_SC_R_DMA_3_CH17 = 477,
-       IMX_SC_R_DMA_3_CH18 = 478,
-       IMX_SC_R_DMA_3_CH19 = 479,
-       IMX_SC_R_DMA_3_CH20 = 480,
-       IMX_SC_R_DMA_3_CH21 = 481,
-       IMX_SC_R_DMA_3_CH22 = 482,
-       IMX_SC_R_DMA_3_CH23 = 483,
-       IMX_SC_R_DMA_3_CH24 = 484,
-       IMX_SC_R_DMA_3_CH25 = 485,
-       IMX_SC_R_DMA_3_CH26 = 486,
-       IMX_SC_R_DMA_3_CH27 = 487,
-       IMX_SC_R_DMA_3_CH28 = 488,
-       IMX_SC_R_DMA_3_CH29 = 489,
-       IMX_SC_R_DMA_3_CH30 = 490,
-       IMX_SC_R_DMA_3_CH31 = 491,
-       IMX_SC_R_AUDIO_PLL_1 = 492,
-       IMX_SC_R_AUDIO_CLK_0 = 493,
-       IMX_SC_R_AUDIO_CLK_1 = 494,
-       IMX_SC_R_MCLK_OUT_0 = 495,
-       IMX_SC_R_MCLK_OUT_1 = 496,
-       IMX_SC_R_PMIC_0 = 497,
-       IMX_SC_R_PMIC_1 = 498,
-       IMX_SC_R_SECO = 499,
-       IMX_SC_R_CAAM_JR1 = 500,
-       IMX_SC_R_CAAM_JR2 = 501,
-       IMX_SC_R_CAAM_JR3 = 502,
-       IMX_SC_R_SECO_MU_2 = 503,
-       IMX_SC_R_SECO_MU_3 = 504,
-       IMX_SC_R_SECO_MU_4 = 505,
-       IMX_SC_R_HDMI_RX_PWM_0 = 506,
-       IMX_SC_R_A35 = 507,
-       IMX_SC_R_A35_0 = 508,
-       IMX_SC_R_A35_1 = 509,
-       IMX_SC_R_A35_2 = 510,
-       IMX_SC_R_A35_3 = 511,
-       IMX_SC_R_DSP = 512,
-       IMX_SC_R_DSP_RAM = 513,
-       IMX_SC_R_CAAM_JR1_OUT = 514,
-       IMX_SC_R_CAAM_JR2_OUT = 515,
-       IMX_SC_R_CAAM_JR3_OUT = 516,
-       IMX_SC_R_VPU_DEC_0 = 517,
-       IMX_SC_R_VPU_ENC_0 = 518,
-       IMX_SC_R_CAAM_JR0 = 519,
-       IMX_SC_R_CAAM_JR0_OUT = 520,
-       IMX_SC_R_PMIC_2 = 521,
-       IMX_SC_R_DBLOGIC = 522,
-       IMX_SC_R_HDMI_PLL_1 = 523,
-       IMX_SC_R_BOARD_R0 = 524,
-       IMX_SC_R_BOARD_R1 = 525,
-       IMX_SC_R_BOARD_R2 = 526,
-       IMX_SC_R_BOARD_R3 = 527,
-       IMX_SC_R_BOARD_R4 = 528,
-       IMX_SC_R_BOARD_R5 = 529,
-       IMX_SC_R_BOARD_R6 = 530,
-       IMX_SC_R_BOARD_R7 = 531,
-       IMX_SC_R_MJPEG_DEC_MP = 532,
-       IMX_SC_R_MJPEG_ENC_MP = 533,
-       IMX_SC_R_VPU_TS_0 = 534,
-       IMX_SC_R_VPU_MU_0 = 535,
-       IMX_SC_R_VPU_MU_1 = 536,
-       IMX_SC_R_VPU_MU_2 = 537,
-       IMX_SC_R_VPU_MU_3 = 538,
-       IMX_SC_R_VPU_ENC_1 = 539,
-       IMX_SC_R_VPU = 540,
-       IMX_SC_R_LAST
-};
-
-/* NOTE - please add by replacing some of the UNUSED from above! */
-
 /*
  * This type is used to indicate a control.
  */
diff --git a/include/linux/pl353-smc.h b/include/linux/pl353-smc.h
new file mode 100644 (file)
index 0000000..0e0d3df
--- /dev/null
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * ARM PL353 SMC Driver Header
+ *
+ * Copyright (C) 2012 - 2018 Xilinx, Inc
+ */
+
+#ifndef __LINUX_PL353_SMC_H
+#define __LINUX_PL353_SMC_H
+
+enum pl353_smc_ecc_mode {
+       PL353_SMC_ECCMODE_BYPASS = 0,
+       PL353_SMC_ECCMODE_APB = 1,
+       PL353_SMC_ECCMODE_MEM = 2
+};
+
+enum pl353_smc_mem_width {
+       PL353_SMC_MEM_WIDTH_8 = 0,
+       PL353_SMC_MEM_WIDTH_16 = 1
+};
+
+u32 pl353_smc_get_ecc_val(int ecc_reg);
+bool pl353_smc_ecc_is_busy(void);
+int pl353_smc_get_nand_int_status_raw(void);
+void pl353_smc_clr_nand_int(void);
+int pl353_smc_set_ecc_mode(enum pl353_smc_ecc_mode mode);
+int pl353_smc_set_ecc_pg_size(unsigned int pg_sz);
+int pl353_smc_set_buswidth(unsigned int bw);
+void pl353_smc_set_cycles(u32 timings[]);
+#endif
index 06996ad4f2bc1d2e075f65d492beb734828c9149..1637385bcc171a8476fb24b908bd87925fffba52 100644 (file)
@@ -67,6 +67,9 @@ extern int qcom_scm_iommu_secure_ptbl_init(u64 addr, u32 size, u32 spare);
 extern int qcom_scm_io_readl(phys_addr_t addr, unsigned int *val);
 extern int qcom_scm_io_writel(phys_addr_t addr, unsigned int val);
 #else
+
+#include <linux/errno.h>
+
 static inline
 int qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t *cpus)
 {
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h b/include/linux/soc/mediatek/mtk-cmdq.h
new file mode 100644 (file)
index 0000000..54ade13
--- /dev/null
@@ -0,0 +1,133 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2018 MediaTek Inc.
+ *
+ */
+
+#ifndef __MTK_CMDQ_H__
+#define __MTK_CMDQ_H__
+
+#include <linux/mailbox_client.h>
+#include <linux/mailbox/mtk-cmdq-mailbox.h>
+#include <linux/timer.h>
+
+#define CMDQ_NO_TIMEOUT                0xffffffffu
+
+/** cmdq event maximum */
+#define CMDQ_MAX_EVENT                         0x3ff
+
+struct cmdq_pkt;
+
+struct cmdq_client {
+       spinlock_t lock;
+       u32 pkt_cnt;
+       struct mbox_client client;
+       struct mbox_chan *chan;
+       struct timer_list timer;
+       u32 timeout_ms; /* in unit of microsecond */
+};
+
+/**
+ * cmdq_mbox_create() - create CMDQ mailbox client and channel
+ * @dev:       device of CMDQ mailbox client
+ * @index:     index of CMDQ mailbox channel
+ * @timeout:   timeout of a pkt execution by GCE, in unit of microsecond, set
+ *             CMDQ_NO_TIMEOUT if a timer is not used.
+ *
+ * Return: CMDQ mailbox client pointer
+ */
+struct cmdq_client *cmdq_mbox_create(struct device *dev, int index,
+                                    u32 timeout);
+
+/**
+ * cmdq_mbox_destroy() - destroy CMDQ mailbox client and channel
+ * @client:    the CMDQ mailbox client
+ */
+void cmdq_mbox_destroy(struct cmdq_client *client);
+
+/**
+ * cmdq_pkt_create() - create a CMDQ packet
+ * @client:    the CMDQ mailbox client
+ * @size:      required CMDQ buffer size
+ *
+ * Return: CMDQ packet pointer
+ */
+struct cmdq_pkt *cmdq_pkt_create(struct cmdq_client *client, size_t size);
+
+/**
+ * cmdq_pkt_destroy() - destroy the CMDQ packet
+ * @pkt:       the CMDQ packet
+ */
+void cmdq_pkt_destroy(struct cmdq_pkt *pkt);
+
+/**
+ * cmdq_pkt_write() - append write command to the CMDQ packet
+ * @pkt:       the CMDQ packet
+ * @value:     the specified target register value
+ * @subsys:    the CMDQ sub system code
+ * @offset:    register offset from CMDQ sub system
+ *
+ * Return: 0 for success; else the error code is returned
+ */
+int cmdq_pkt_write(struct cmdq_pkt *pkt, u32 value, u32 subsys, u32 offset);
+
+/**
+ * cmdq_pkt_write_mask() - append write command with mask to the CMDQ packet
+ * @pkt:       the CMDQ packet
+ * @value:     the specified target register value
+ * @subsys:    the CMDQ sub system code
+ * @offset:    register offset from CMDQ sub system
+ * @mask:      the specified target register mask
+ *
+ * Return: 0 for success; else the error code is returned
+ */
+int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u32 value,
+                       u32 subsys, u32 offset, u32 mask);
+
+/**
+ * cmdq_pkt_wfe() - append wait for event command to the CMDQ packet
+ * @pkt:       the CMDQ packet
+ * @event:     the desired event type to "wait and CLEAR"
+ *
+ * Return: 0 for success; else the error code is returned
+ */
+int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u32 event);
+
+/**
+ * cmdq_pkt_clear_event() - append clear event command to the CMDQ packet
+ * @pkt:       the CMDQ packet
+ * @event:     the desired event to be cleared
+ *
+ * Return: 0 for success; else the error code is returned
+ */
+int cmdq_pkt_clear_event(struct cmdq_pkt *pkt, u32 event);
+
+/**
+ * cmdq_pkt_flush_async() - trigger CMDQ to asynchronously execute the CMDQ
+ *                          packet and call back at the end of done packet
+ * @pkt:       the CMDQ packet
+ * @cb:                called at the end of done packet
+ * @data:      this data will pass back to cb
+ *
+ * Return: 0 for success; else the error code is returned
+ *
+ * Trigger CMDQ to asynchronously execute the CMDQ packet and call back
+ * at the end of done packet. Note that this is an ASYNC function. When the
+ * function returned, it may or may not be finished.
+ */
+int cmdq_pkt_flush_async(struct cmdq_pkt *pkt, cmdq_async_flush_cb cb,
+                        void *data);
+
+/**
+ * cmdq_pkt_flush() - trigger CMDQ to execute the CMDQ packet
+ * @pkt:       the CMDQ packet
+ *
+ * Return: 0 for success; else the error code is returned
+ *
+ * Trigger CMDQ to execute the CMDQ packet. Note that this is a
+ * synchronous flush function. When the function returned, the recorded
+ * commands have been done.
+ */
+int cmdq_pkt_flush(struct cmdq_pkt *pkt);
+
+#endif /* __MTK_CMDQ_H__ */
index f4de33654a6092b9c29ca50451534861e3937169..5efa2b67fa55792d37ecfe67b14ea9b0fca663fd 100644 (file)
@@ -166,7 +166,7 @@ struct qmi_ops {
 struct qmi_txn {
        struct qmi_handle *qmi;
 
-       int id;
+       u16 id;
 
        struct mutex lock;
        struct completion completion;
index c4a5c9e9fb478133d3fa518b0503fc7f074a93a9..4be1aa4435ae5e97a6b0b1ac42fcc808102e80b8 100644 (file)
@@ -1,9 +1,6 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /*
  *  Copyright Â© 2015 Broadcom
- *
- * 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.
  */
 
 #ifndef __SOC_RASPBERRY_FIRMWARE_H__
index 578180cbc1346c6cdf62b6cf992920e32534cb0c..af97222239251b72dffcdd49a32178eef67c55c6 100644 (file)
@@ -18,9 +18,7 @@ enum cmd_db_hw_type {
 #if IS_ENABLED(CONFIG_QCOM_COMMAND_DB)
 u32 cmd_db_read_addr(const char *resource_id);
 
-int cmd_db_read_aux_data(const char *resource_id, u8 *data, size_t len);
-
-size_t cmd_db_read_aux_data_len(const char *resource_id);
+const void *cmd_db_read_aux_data(const char *resource_id, size_t *len);
 
 enum cmd_db_hw_type cmd_db_read_slave_id(const char *resource_id);
 
@@ -29,12 +27,8 @@ int cmd_db_ready(void);
 static inline u32 cmd_db_read_addr(const char *resource_id)
 { return 0; }
 
-static inline int cmd_db_read_aux_data(const char *resource_id, u8 *data,
-                                      size_t len)
-{ return -ENODEV; }
-
-static inline size_t cmd_db_read_aux_data_len(const char *resource_id)
-{ return -ENODEV; }
+static inline const void *cmd_db_read_aux_data(const char *resource_id, size_t *len)
+{ return ERR_PTR(-ENODEV); }
 
 static inline enum cmd_db_hw_type cmd_db_read_slave_id(const char *resource_id)
 { return -ENODEV; }
index 98d8d38b99a13c367937762e44cc5caca4de51cf..ab7f8796a260dea1f1f9faabe1f8d181d82a2af3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2016, NVIDIA CORPORATION.  All rights reserved.
+ * Copyright (c) 2014-2018, NVIDIA CORPORATION.  All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -40,7 +40,6 @@
  * @file
  */
 
-
 /**
  * @defgroup MRQ MRQ Messages
  * @brief Messages sent to/from BPMP via IPC
@@ -53,7 +52,7 @@
  */
 
 /**
- * @addtogroup MRQ_Format Message Format
+ * @addtogroup MRQ_Format
  * @{
  * The CPU requests the BPMP to perform a particular service by
  * sending it an IVC frame containing a single MRQ message. An MRQ
@@ -76,7 +75,7 @@
 
 /**
  * @ingroup MRQ_Format
- * @brief header for an MRQ message
+ * @brief Header for an MRQ message
  *
  * Provides the MRQ number for the MRQ message: #mrq. The remainder of
  * the MRQ message is a payload (immediately following the
@@ -86,7 +85,7 @@ struct mrq_request {
        /** @brief MRQ number of the request */
        uint32_t mrq;
        /**
-        * @brief flags providing follow up directions to the receiver
+        * @brief Flags providing follow up directions to the receiver
         *
         * | Bit | Description                                |
         * |-----|--------------------------------------------|
@@ -98,7 +97,7 @@ struct mrq_request {
 
 /**
  * @ingroup MRQ_Format
- * @brief header for an MRQ response
+ * @brief Header for an MRQ response
  *
  *  Provides an error code for the associated MRQ message. The
  *  remainder of the MRQ response is a payload (immediately following
@@ -106,9 +105,9 @@ struct mrq_request {
  *  mrq_request::mrq
  */
 struct mrq_response {
-       /** @brief error code for the MRQ request itself */
+       /** @brief Error code for the MRQ request itself */
        int32_t err;
-       /** @brief reserved for future use */
+       /** @brief Reserved for future use */
        uint32_t flags;
 } __ABI_PACKED;
 
@@ -152,6 +151,14 @@ struct mrq_response {
 #define MRQ_TRACE_ITER         64
 #define MRQ_RINGBUF_CONSOLE    65
 #define MRQ_PG                 66
+#define MRQ_CPU_NDIV_LIMITS    67
+#define MRQ_STRAP               68
+#define MRQ_UPHY               69
+#define MRQ_CPU_AUTO_CC3       70
+#define MRQ_QUERY_FW_TAG       71
+#define MRQ_FMON               72
+#define MRQ_EC                 73
+#define MRQ_FBVOLT_STATUS      74
 
 /** @} */
 
@@ -160,31 +167,35 @@ struct mrq_response {
  * @brief Maximum MRQ code to be sent by CPU software to
  * BPMP. Subject to change in future
  */
-#define MAX_CPU_MRQ_ID         66
+#define MAX_CPU_MRQ_ID         74
 
 /**
- * @addtogroup MRQ_Payloads Message Payloads
+ * @addtogroup MRQ_Payloads
  * @{
- *   @defgroup Ping
+ *   @defgroup Ping Ping
  *   @defgroup Query_Tag Query Tag
  *   @defgroup Module Loadable Modules
- *   @defgroup Trace
- *   @defgroup Debugfs
- *   @defgroup Reset
- *   @defgroup I2C
- *   @defgroup Clocks
+ *   @defgroup Trace Trace
+ *   @defgroup Debugfs Debug File System
+ *   @defgroup Reset Reset
+ *   @defgroup I2C I2C
+ *   @defgroup Clocks Clocks
  *   @defgroup ABI_info ABI Info
- *   @defgroup MC_Flush MC Flush
- *   @defgroup Powergating
- *   @defgroup Thermal
+ *   @defgroup Powergating Power Gating
+ *   @defgroup Thermal Thermal
  *   @defgroup Vhint CPU Voltage hint
- *   @defgroup MRQ_Deprecated Deprecated MRQ messages
- *   @defgroup EMC
- *   @defgroup RingbufConsole
+ *   @defgroup EMC EMC
+ *   @defgroup CPU NDIV Limits
+ *   @defgroup RingbufConsole Ring Buffer Console
+ *   @defgroup Strap Straps
+ *   @defgroup UPHY UPHY
+ *   @defgroup CC3 Auto-CC3
+ *   @defgroup FMON FMON
+ *   @defgroup EC EC
+ *   @defgroup Fbvolt_status Fuse Burn Voltage Status
  * @}
  */
 
-
 /**
  * @ingroup MRQ_Codes
  * @def MRQ_PING
@@ -214,20 +225,20 @@ struct mrq_response {
 
 /**
  * @ingroup Ping
- * @brief request with #MRQ_PING
+ * @brief Request with #MRQ_PING
  *
  * Used by the sender of an #MRQ_PING message to request a pong from
  * recipient. The response from the recipient is computed based on
  * #challenge.
  */
 struct mrq_ping_request {
-/** @brief arbitrarily chosen value */
+/** @brief Arbitrarily chosen value */
        uint32_t challenge;
 } __ABI_PACKED;
 
 /**
  * @ingroup Ping
- * @brief response to #MRQ_PING
+ * @brief Response to #MRQ_PING
  *
  * Sent in response to an #MRQ_PING message. #reply should be the
  * mrq_ping_request challenge left shifted by 1 with the carry-bit
@@ -235,14 +246,16 @@ struct mrq_ping_request {
  *
  */
 struct mrq_ping_response {
-       /** @brief response to the MRQ_PING challege */
+       /** @brief Response to the MRQ_PING challege */
        uint32_t reply;
 } __ABI_PACKED;
 
 /**
  * @ingroup MRQ_Codes
  * @def MRQ_QUERY_TAG
- * @brief Query BPMP firmware's tag (i.e. version information)
+ * @brief Query BPMP firmware's tag (i.e. unique identifer)
+ *
+ * @deprecated Use #MRQ_QUERY_FW_TAG instead.
  *
  * * Platforms: All
  * * Initiators: CCPLEX
@@ -254,25 +267,50 @@ struct mrq_ping_response {
 
 /**
  * @ingroup Query_Tag
- * @brief request with #MRQ_QUERY_TAG
- *
- * Used by #MRQ_QUERY_TAG call to ask BPMP to fill in the memory
- * pointed by #addr with BPMP firmware header.
+ * @brief Request with #MRQ_QUERY_TAG
  *
- * The sender is reponsible for ensuring that #addr is mapped in to
- * the recipient's address map.
+ * @deprecated This structure will be removed in future version.
+ * Use MRQ_QUERY_FW_TAG instead.
  */
 struct mrq_query_tag_request {
-  /** @brief base address to store the firmware header */
+  /** @brief Base address to store the firmware tag */
        uint32_t addr;
 } __ABI_PACKED;
 
+
 /**
  * @ingroup MRQ_Codes
- * @def MRQ_MODULE_LOAD
- * @brief dynamically load a BPMP code module
+ * @def MRQ_QUERY_FW_TAG
+ * @brief Query BPMP firmware's tag (i.e. unique identifier)
  *
  * * Platforms: All
+ * * Initiators: Any
+ * * Targets: BPMP
+ * * Request Payload: N/A
+ * * Response Payload: @ref mrq_query_fw_tag_response
+ *
+ */
+
+/**
+ * @ingroup Query_Tag
+ * @brief Response to #MRQ_QUERY_FW_TAG
+ *
+ * Sent in response to #MRQ_QUERY_FW_TAG message. #tag contains the unique
+ * identifier for the version of firmware issuing the reply.
+ *
+ */
+struct mrq_query_fw_tag_response {
+  /** @brief Array to store tag information */
+       uint8_t tag[32];
+} __ABI_PACKED;
+
+/**
+ * @ingroup MRQ_Codes
+ * @def MRQ_MODULE_LOAD
+ * @brief Dynamically load a BPMP code module
+ *
+ * * Platforms: T210, T214, T186
+ * @cond (bpmp_t210 || bpmp_t214 || bpmp_t186)
  * * Initiators: CCPLEX
  * * Targets: BPMP
  * * Request Payload: @ref mrq_module_load_request
@@ -284,7 +322,7 @@ struct mrq_query_tag_request {
 
 /**
  * @ingroup Module
- * @brief request with #MRQ_MODULE_LOAD
+ * @brief Request with #MRQ_MODULE_LOAD
  *
  * Used by #MRQ_MODULE_LOAD calls to ask the recipient to dynamically
  * load the code located at #phys_addr and having size #size
@@ -300,29 +338,31 @@ struct mrq_query_tag_request {
  *
  */
 struct mrq_module_load_request {
-       /** @brief base address of the code to load. Treated as (void *) */
+       /** @brief Base address of the code to load. Treated as (void *) */
        uint32_t phys_addr; /* (void *) */
-       /** @brief size in bytes of code to load */
+       /** @brief Size in bytes of code to load */
        uint32_t size;
 } __ABI_PACKED;
 
 /**
  * @ingroup Module
- * @brief response to #MRQ_MODULE_LOAD
+ * @brief Response to #MRQ_MODULE_LOAD
  *
  * @todo document mrq_response::err
  */
 struct mrq_module_load_response {
-       /** @brief handle to the loaded module */
+       /** @brief Handle to the loaded module */
        uint32_t base;
 } __ABI_PACKED;
+/** @endcond*/
 
 /**
  * @ingroup MRQ_Codes
  * @def MRQ_MODULE_UNLOAD
- * @brief unload a previously loaded code module
+ * @brief Unload a previously loaded code module
  *
- * * Platforms: All
+ * * Platforms: T210, T214, T186
+ * @cond (bpmp_t210 || bpmp_t214 || bpmp_t186)
  * * Initiators: CCPLEX
  * * Targets: BPMP
  * * Request Payload: @ref mrq_module_unload_request
@@ -333,20 +373,21 @@ struct mrq_module_load_response {
 
 /**
  * @ingroup Module
- * @brief request with #MRQ_MODULE_UNLOAD
+ * @brief Request with #MRQ_MODULE_UNLOAD
  *
  * Used by #MRQ_MODULE_UNLOAD calls to request that a previously loaded
  * module be unloaded.
  */
 struct mrq_module_unload_request {
-       /** @brief handle of the module to unload */
+       /** @brief Handle of the module to unload */
        uint32_t base;
 } __ABI_PACKED;
+/** @endcond*/
 
 /**
  * @ingroup MRQ_Codes
  * @def MRQ_TRACE_MODIFY
- * @brief modify the set of enabled trace events
+ * @brief Modify the set of enabled trace events
  *
  * * Platforms: All
  * * Initiators: CCPLEX
@@ -359,22 +400,22 @@ struct mrq_module_unload_request {
 
 /**
  * @ingroup Trace
- * @brief request with #MRQ_TRACE_MODIFY
+ * @brief Request with #MRQ_TRACE_MODIFY
  *
  * Used by %MRQ_TRACE_MODIFY calls to enable or disable specify trace
  * events.  #set takes precedence for any bit set in both #set and
  * #clr.
  */
 struct mrq_trace_modify_request {
-       /** @brief bit mask of trace events to disable */
+       /** @brief Bit mask of trace events to disable */
        uint32_t clr;
-       /** @brief bit mask of trace events to enable */
+       /** @brief Bit mask of trace events to enable */
        uint32_t set;
 } __ABI_PACKED;
 
 /**
  * @ingroup Trace
- * @brief response to #MRQ_TRACE_MODIFY
+ * @brief Response to #MRQ_TRACE_MODIFY
  *
  * Sent in repsonse to an #MRQ_TRACE_MODIFY message. #mask reflects the
  * state of which events are enabled after the recipient acted on the
@@ -382,7 +423,7 @@ struct mrq_trace_modify_request {
  *
  */
 struct mrq_trace_modify_response {
-       /** @brief bit mask of trace event enable states */
+       /** @brief Bit mask of trace event enable states */
        uint32_t mask;
 } __ABI_PACKED;
 
@@ -407,7 +448,7 @@ struct mrq_trace_modify_response {
 
 /**
  * @ingroup Trace
- * @brief request with #MRQ_WRITE_TRACE
+ * @brief Request with #MRQ_WRITE_TRACE
  *
  * Used by MRQ_WRITE_TRACE calls to ask the recipient to copy trace
  * data from the recipient's local buffer to the output buffer. #area
@@ -420,22 +461,22 @@ struct mrq_trace_modify_response {
  * overwrites.
  */
 struct mrq_write_trace_request {
-       /** @brief base address of output buffer */
+       /** @brief Base address of output buffer */
        uint32_t area;
-       /** @brief size in bytes of the output buffer */
+       /** @brief Size in bytes of the output buffer */
        uint32_t size;
 } __ABI_PACKED;
 
 /**
  * @ingroup Trace
- * @brief response to #MRQ_WRITE_TRACE
+ * @brief Response to #MRQ_WRITE_TRACE
  *
  * Once this response is sent, the respondent will not access the
  * output buffer further.
  */
 struct mrq_write_trace_response {
        /**
-        * @brief flag whether more data remains in local buffer
+        * @brief Flag whether more data remains in local buffer
         *
         * Value is 1 if the entire local trace buffer has been
         * drained to the outputbuffer. Value is 0 otherwise.
@@ -456,9 +497,10 @@ struct mrq_threaded_ping_response {
 /**
  * @ingroup MRQ_Codes
  * @def MRQ_MODULE_MAIL
- * @brief send a message to a loadable module
+ * @brief Send a message to a loadable module
  *
- * * Platforms: All
+ * * Platforms: T210, T214, T186
+ * @cond (bpmp_t210 || bpmp_t214 || bpmp_t186)
  * * Initiators: Any
  * * Targets: BPMP
  * * Request Payload: @ref mrq_module_mail_request
@@ -469,12 +511,12 @@ struct mrq_threaded_ping_response {
 
 /**
  * @ingroup Module
- * @brief request with #MRQ_MODULE_MAIL
+ * @brief Request with #MRQ_MODULE_MAIL
  */
 struct mrq_module_mail_request {
-       /** @brief handle to the previously loaded module */
+       /** @brief Handle to the previously loaded module */
        uint32_t base;
-       /** @brief module-specific mail payload
+       /** @brief Module-specific mail payload
         *
         * The length of data[ ] is unknown to the BPMP core firmware
         * but it is limited to the size of an IPC message.
@@ -484,23 +526,24 @@ struct mrq_module_mail_request {
 
 /**
  * @ingroup Module
- * @brief response to #MRQ_MODULE_MAIL
+ * @brief Response to #MRQ_MODULE_MAIL
  */
 struct mrq_module_mail_response {
-       /** @brief module-specific mail payload
+       /** @brief Module-specific mail payload
         *
         * The length of data[ ] is unknown to the BPMP core firmware
         * but it is limited to the size of an IPC message.
         */
        uint8_t data[EMPTY_ARRAY];
 } __ABI_PACKED;
+/** @endcond */
 
 /**
  * @ingroup MRQ_Codes
  * @def MRQ_DEBUGFS
  * @brief Interact with BPMP's debugfs file nodes
  *
- * * Platforms: T186
+ * * Platforms: T186, T194
  * * Initiators: Any
  * * Targets: BPMP
  * * Request Payload: @ref mrq_debugfs_request
@@ -529,65 +572,70 @@ struct mrq_module_mail_response {
  *
  * @}
  */
+
 /** @ingroup Debugfs */
 enum mrq_debugfs_commands {
+       /** @brief Perform read */
        CMD_DEBUGFS_READ = 1,
+       /** @brief Perform write */
        CMD_DEBUGFS_WRITE = 2,
+       /** @brief Perform dumping directory */
        CMD_DEBUGFS_DUMPDIR = 3,
+       /** @brief Not a command */
        CMD_DEBUGFS_MAX
 };
 
 /**
  * @ingroup Debugfs
- * @brief parameters for CMD_DEBUGFS_READ/WRITE command
+ * @brief Parameters for CMD_DEBUGFS_READ/WRITE command
  */
 struct cmd_debugfs_fileop_request {
-       /** @brief physical address pointing at filename */
+       /** @brief Physical address pointing at filename */
        uint32_t fnameaddr;
-       /** @brief length in bytes of filename buffer */
+       /** @brief Length in bytes of filename buffer */
        uint32_t fnamelen;
-       /** @brief physical address pointing to data buffer */
+       /** @brief Physical address pointing to data buffer */
        uint32_t dataaddr;
-       /** @brief length in bytes of data buffer */
+       /** @brief Length in bytes of data buffer */
        uint32_t datalen;
 } __ABI_PACKED;
 
 /**
  * @ingroup Debugfs
- * @brief parameters for CMD_DEBUGFS_READ/WRITE command
+ * @brief Parameters for CMD_DEBUGFS_READ/WRITE command
  */
 struct cmd_debugfs_dumpdir_request {
-       /** @brief physical address pointing to data buffer */
+       /** @brief Physical address pointing to data buffer */
        uint32_t dataaddr;
-       /** @brief length in bytes of data buffer */
+       /** @brief Length in bytes of data buffer */
        uint32_t datalen;
 } __ABI_PACKED;
 
 /**
  * @ingroup Debugfs
- * @brief response data for CMD_DEBUGFS_READ/WRITE command
+ * @brief Response data for CMD_DEBUGFS_READ/WRITE command
  */
 struct cmd_debugfs_fileop_response {
-       /** @brief always 0 */
+       /** @brief Always 0 */
        uint32_t reserved;
-       /** @brief number of bytes read from or written to data buffer */
+       /** @brief Number of bytes read from or written to data buffer */
        uint32_t nbytes;
 } __ABI_PACKED;
 
 /**
  * @ingroup Debugfs
- * @brief response data for CMD_DEBUGFS_DUMPDIR command
+ * @brief Response data for CMD_DEBUGFS_DUMPDIR command
  */
 struct cmd_debugfs_dumpdir_response {
-       /** @brief always 0 */
+       /** @brief Always 0 */
        uint32_t reserved;
-       /** @brief number of bytes read from or written to data buffer */
+       /** @brief Number of bytes read from or written to data buffer */
        uint32_t nbytes;
 } __ABI_PACKED;
 
 /**
  * @ingroup Debugfs
- * @brief request with #MRQ_DEBUGFS.
+ * @brief Request with #MRQ_DEBUGFS.
  *
  * The sender of an MRQ_DEBUGFS message uses #cmd to specify a debugfs
  * command to execute. Legal commands are the values of @ref
@@ -601,6 +649,7 @@ struct cmd_debugfs_dumpdir_response {
  * |CMD_DEBUGFS_DUMPDIR|dumpdir|
  */
 struct mrq_debugfs_request {
+       /** @brief Sub-command (@ref mrq_debugfs_commands) */
        uint32_t cmd;
        union {
                struct cmd_debugfs_fileop_request fop;
@@ -612,14 +661,14 @@ struct mrq_debugfs_request {
  * @ingroup Debugfs
  */
 struct mrq_debugfs_response {
-       /** @brief always 0 */
+       /** @brief Always 0 */
        int32_t reserved;
        union {
-               /** @brief response data for CMD_DEBUGFS_READ OR
+               /** @brief Response data for CMD_DEBUGFS_READ OR
                 * CMD_DEBUGFS_WRITE command
                 */
                struct cmd_debugfs_fileop_response fop;
-               /** @brief response data for CMD_DEBUGFS_DUMPDIR command */
+               /** @brief Response data for CMD_DEBUGFS_DUMPDIR command */
                struct cmd_debugfs_dumpdir_response dumpdir;
        } __UNION_ANON;
 } __ABI_PACKED;
@@ -633,57 +682,58 @@ struct mrq_debugfs_response {
 #define DEBUGFS_S_IWUSR        (1 << 7)
 /** @} */
 
-
 /**
  * @ingroup MRQ_Codes
  * @def MRQ_RESET
- * @brief reset an IP block
+ * @brief Reset an IP block
  *
- * * Platforms: T186
+ * * Platforms: T186, T194
  * * Initiators: Any
  * * Targets: BPMP
  * * Request Payload: @ref mrq_reset_request
  * * Response Payload: @ref mrq_reset_response
+ *
+ * @addtogroup Reset
+ * @{
  */
 
-/**
- * @ingroup Reset
- */
 enum mrq_reset_commands {
+       /** @brief Assert module reset */
        CMD_RESET_ASSERT = 1,
+       /** @brief Deassert module reset */
        CMD_RESET_DEASSERT = 2,
+       /** @brief Assert and deassert the module reset */
        CMD_RESET_MODULE = 3,
+       /** @brief Get the highest reset ID */
        CMD_RESET_GET_MAX_ID = 4,
-       CMD_RESET_MAX, /* not part of ABI and subject to change */
+       /** @brief Not part of ABI and subject to change */
+       CMD_RESET_MAX,
 };
 
 /**
- * @ingroup Reset
- * @brief request with MRQ_RESET
+ * @brief Request with MRQ_RESET
  *
  * Used by the sender of an #MRQ_RESET message to request BPMP to
  * assert or or deassert a given reset line.
  */
 struct mrq_reset_request {
-       /** @brief reset action to perform (@enum mrq_reset_commands) */
+       /** @brief Reset action to perform (@ref mrq_reset_commands) */
        uint32_t cmd;
-       /** @brief id of the reset to affected */
+       /** @brief Id of the reset to affected */
        uint32_t reset_id;
 } __ABI_PACKED;
 
 /**
- * @ingroup Reset
  * @brief Response for MRQ_RESET sub-command CMD_RESET_GET_MAX_ID. When
  * this sub-command is not supported, firmware will return -BPMP_EBADCMD
  * in mrq_response::err.
  */
 struct cmd_reset_get_max_id_response {
-       /** @brief max reset id */
+       /** @brief Max reset id */
        uint32_t max_id;
 } __ABI_PACKED;
 
 /**
- * @ingroup Reset
  * @brief Response with MRQ_RESET
  *
  * Each sub-command supported by @ref mrq_reset_request may return
@@ -703,32 +753,25 @@ struct mrq_reset_response {
        } __UNION_ANON;
 } __ABI_PACKED;
 
+/** @} */
+
 /**
  * @ingroup MRQ_Codes
  * @def MRQ_I2C
- * @brief issue an i2c transaction
+ * @brief Issue an i2c transaction
  *
- * * Platforms: T186
+ * * Platforms: T186, T194
  * * Initiators: Any
  * * Targets: BPMP
  * * Request Payload: @ref mrq_i2c_request
  * * Response Payload: @ref mrq_i2c_response
- */
-
-/**
+ *
  * @addtogroup I2C
  * @{
  */
 #define TEGRA_I2C_IPC_MAX_IN_BUF_SIZE  (MSG_DATA_MIN_SZ - 12)
 #define TEGRA_I2C_IPC_MAX_OUT_BUF_SIZE (MSG_DATA_MIN_SZ - 4)
-/** @} */
 
-/**
- * @ingroup I2C
- * @name Serial I2C flags
- * Use these flags with serial_i2c_request::flags
- * @{
- */
 #define SERIALI2C_TEN           0x0010
 #define SERIALI2C_RD            0x0001
 #define SERIALI2C_STOP          0x8000
@@ -737,15 +780,13 @@ struct mrq_reset_response {
 #define SERIALI2C_IGNORE_NAK    0x1000
 #define SERIALI2C_NO_RD_ACK     0x0800
 #define SERIALI2C_RECV_LEN      0x0400
-/** @} */
-/** @ingroup I2C */
+
 enum {
        CMD_I2C_XFER = 1
 };
 
 /**
- * @ingroup I2C
- * @brief serializable i2c request
+ * @brief Serializable i2c request
  *
  * Instances of this structure are packed (little-endian) into
  * cmd_i2c_xfer_request::data_buf. Each instance represents a single
@@ -762,80 +803,75 @@ enum {
 struct serial_i2c_request {
        /** @brief I2C slave address */
        uint16_t addr;
-       /** @brief bitmask of SERIALI2C_ flags */
+       /** @brief Bitmask of SERIALI2C_ flags */
        uint16_t flags;
-       /** @brief length of I2C transaction in bytes */
+       /** @brief Length of I2C transaction in bytes */
        uint16_t len;
-       /** @brief for write transactions only, #len bytes of data */
+       /** @brief For write transactions only, #len bytes of data */
        uint8_t data[];
 } __ABI_PACKED;
 
 /**
- * @ingroup I2C
- * @brief trigger one or more i2c transactions
+ * @brief Trigger one or more i2c transactions
  */
 struct cmd_i2c_xfer_request {
-       /** @brief valid bus number from mach-t186/i2c-t186.h*/
+       /** @brief Valid bus number from @ref bpmp_i2c_ids*/
        uint32_t bus_id;
 
-       /** @brief count of valid bytes in #data_buf*/
+       /** @brief Count of valid bytes in #data_buf*/
        uint32_t data_size;
 
-       /** @brief serialized packed instances of @ref serial_i2c_request*/
+       /** @brief Serialized packed instances of @ref serial_i2c_request*/
        uint8_t data_buf[TEGRA_I2C_IPC_MAX_IN_BUF_SIZE];
 } __ABI_PACKED;
 
 /**
- * @ingroup I2C
- * @brief container for data read from the i2c bus
+ * @brief Container for data read from the i2c bus
  *
  * Processing an cmd_i2c_xfer_request::data_buf causes BPMP to execute
  * zero or more I2C reads. The data read from the bus is serialized
  * into #data_buf.
  */
 struct cmd_i2c_xfer_response {
-       /** @brief count of valid bytes in #data_buf*/
+       /** @brief Count of valid bytes in #data_buf*/
        uint32_t data_size;
-       /** @brief i2c read data */
+       /** @brief I2c read data */
        uint8_t data_buf[TEGRA_I2C_IPC_MAX_OUT_BUF_SIZE];
 } __ABI_PACKED;
 
 /**
- * @ingroup I2C
- * @brief request with #MRQ_I2C
+ * @brief Request with #MRQ_I2C
  */
 struct mrq_i2c_request {
-       /** @brief always CMD_I2C_XFER (i.e. 1) */
+       /** @brief Always CMD_I2C_XFER (i.e. 1) */
        uint32_t cmd;
-       /** @brief parameters of the transfer request */
+       /** @brief Parameters of the transfer request */
        struct cmd_i2c_xfer_request xfer;
 } __ABI_PACKED;
 
 /**
- * @ingroup I2C
- * @brief response to #MRQ_I2C
+ * @brief Response to #MRQ_I2C
  */
 struct mrq_i2c_response {
        struct cmd_i2c_xfer_response xfer;
 } __ABI_PACKED;
 
+/** @} */
+
 /**
  * @ingroup MRQ_Codes
  * @def MRQ_CLK
+ * @brief Perform a clock operation
  *
- * * Platforms: T186
+ * * Platforms: T186, T194
  * * Initiators: Any
  * * Targets: BPMP
  * * Request Payload: @ref mrq_clk_request
  * * Response Payload: @ref mrq_clk_response
+ *
  * @addtogroup Clocks
  * @{
  */
-
-/**
- * @name MRQ_CLK sub-commands
- * @{
- */
 enum {
        CMD_CLK_GET_RATE = 1,
        CMD_CLK_SET_RATE = 2,
@@ -847,20 +883,13 @@ enum {
        CMD_CLK_DISABLE = 8,
        CMD_CLK_GET_ALL_INFO = 14,
        CMD_CLK_GET_MAX_CLK_ID = 15,
+       CMD_CLK_GET_FMAX_AT_VMIN = 16,
        CMD_CLK_MAX,
 };
-/** @} */
 
-/**
- * @name MRQ_CLK properties
- * Flag bits for cmd_clk_properties_response::flags and
- * cmd_clk_get_all_info_response::flags
- * @{
- */
 #define BPMP_CLK_HAS_MUX       (1 << 0)
 #define BPMP_CLK_HAS_SET_RATE  (1 << 1)
 #define BPMP_CLK_IS_ROOT       (1 << 2)
-/** @} */
 
 #define MRQ_CLK_NAME_MAXLEN    40
 #define MRQ_CLK_MAX_PARENTS    16
@@ -959,11 +988,19 @@ struct cmd_clk_get_max_clk_id_request {
 struct cmd_clk_get_max_clk_id_response {
        uint32_t max_id;
 } __ABI_PACKED;
-/** @} */
+
+/** @private */
+struct cmd_clk_get_fmax_at_vmin_request {
+       EMPTY
+} __ABI_PACKED;
+
+struct cmd_clk_get_fmax_at_vmin_response {
+       int64_t rate;
+} __ABI_PACKED;
 
 /**
  * @ingroup Clocks
- * @brief request with #MRQ_CLK
+ * @brief Request with #MRQ_CLK
  *
  * Used by the sender of an #MRQ_CLK message to control clocks. The
  * clk_request is split into several sub-commands. Some sub-commands
@@ -982,11 +1019,13 @@ struct cmd_clk_get_max_clk_id_response {
  * |CMD_CLK_DISABLE             |-                      |
  * |CMD_CLK_GET_ALL_INFO        |-                      |
  * |CMD_CLK_GET_MAX_CLK_ID      |-                      |
+ * |CMD_CLK_GET_FMAX_AT_VMIN    |-
+ * |
  *
  */
 
 struct mrq_clk_request {
-       /** @brief sub-command and clock id concatenated to 32-bit word.
+       /** @brief Sub-command and clock id concatenated to 32-bit word.
         * - bits[31..24] is the sub-cmd.
         * - bits[23..0] is the clock id
         */
@@ -1010,12 +1049,14 @@ struct mrq_clk_request {
                struct cmd_clk_get_all_info_request clk_get_all_info;
                /** @private */
                struct cmd_clk_get_max_clk_id_request clk_get_max_clk_id;
+               /** @private */
+               struct cmd_clk_get_fmax_at_vmin_request clk_get_fmax_at_vmin;
        } __UNION_ANON;
 } __ABI_PACKED;
 
 /**
  * @ingroup Clocks
- * @brief response to MRQ_CLK
+ * @brief Response to MRQ_CLK
  *
  * Each sub-command supported by @ref mrq_clk_request may return
  * sub-command-specific data. Some do and some do not as indicated in
@@ -1033,6 +1074,7 @@ struct mrq_clk_request {
  * |CMD_CLK_DISABLE             |-                       |
  * |CMD_CLK_GET_ALL_INFO        |clk_get_all_info        |
  * |CMD_CLK_GET_MAX_CLK_ID      |clk_get_max_id          |
+ * |CMD_CLK_GET_FMAX_AT_VMIN    |clk_get_fmax_at_vmin    |
  *
  */
 
@@ -1050,13 +1092,16 @@ struct mrq_clk_response {
                struct cmd_clk_is_enabled_response clk_is_enabled;
                struct cmd_clk_get_all_info_response clk_get_all_info;
                struct cmd_clk_get_max_clk_id_response clk_get_max_clk_id;
+               struct cmd_clk_get_fmax_at_vmin_response clk_get_fmax_at_vmin;
        } __UNION_ANON;
 } __ABI_PACKED;
 
+/** @} */
+
 /**
  * @ingroup MRQ_Codes
  * @def MRQ_QUERY_ABI
- * @brief check if an MRQ is implemented
+ * @brief Check if an MRQ is implemented
  *
  * * Platforms: All
  * * Initiators: Any
@@ -1067,7 +1112,7 @@ struct mrq_clk_response {
 
 /**
  * @ingroup ABI_info
- * @brief request with MRQ_QUERY_ABI
+ * @brief Request with MRQ_QUERY_ABI
  *
  * Used by #MRQ_QUERY_ABI call to check if MRQ code #mrq is supported
  * by the recipient.
@@ -1079,7 +1124,7 @@ struct mrq_query_abi_request {
 
 /**
  * @ingroup ABI_info
- * @brief response to MRQ_QUERY_ABI
+ * @brief Response to MRQ_QUERY_ABI
  *
  * @note mrq_response::err of 0 indicates that the query was
  * successful, not that the MRQ itself is supported!
@@ -1092,19 +1137,19 @@ struct mrq_query_abi_response {
 /**
  * @ingroup MRQ_Codes
  * @def MRQ_PG_READ_STATE
- * @brief read the power-gating state of a partition
+ * @brief Read the power-gating state of a partition
  *
  * * Platforms: T186
+ * @cond bpmp_t186
  * * Initiators: Any
  * * Targets: BPMP
  * * Request Payload: @ref mrq_pg_read_state_request
  * * Response Payload: @ref mrq_pg_read_state_response
- * @addtogroup Powergating
- * @{
  */
 
 /**
- * @brief request with #MRQ_PG_READ_STATE
+ * @ingroup Powergating
+ * @brief Request with #MRQ_PG_READ_STATE
  *
  * Used by MRQ_PG_READ_STATE call to read the current state of a
  * partition.
@@ -1115,39 +1160,40 @@ struct mrq_pg_read_state_request {
 } __ABI_PACKED;
 
 /**
- * @brief response to MRQ_PG_READ_STATE
+ * @ingroup Powergating
+ * @brief Response to MRQ_PG_READ_STATE
  * @todo define possible errors.
  */
 struct mrq_pg_read_state_response {
-       /** @brief read as don't care */
+       /** @brief Read as don't care */
        uint32_t sram_state;
-       /** @brief state of power partition
+       /** @brief State of power partition
         * * 0 : off
         * * 1 : on
         */
        uint32_t logic_state;
 } __ABI_PACKED;
-
+/** @endcond*/
 /** @} */
 
 /**
  * @ingroup MRQ_Codes
  * @def MRQ_PG_UPDATE_STATE
- * @brief modify the power-gating state of a partition. In contrast to
+ * @brief Modify the power-gating state of a partition. In contrast to
  * MRQ_PG calls, the operations that change state (on/off) of power
  * partition are reference counted.
  *
  * * Platforms: T186
+ * @cond bpmp_t186
  * * Initiators: Any
  * * Targets: BPMP
  * * Request Payload: @ref mrq_pg_update_state_request
  * * Response Payload: N/A
- * @addtogroup Powergating
- * @{
  */
 
 /**
- * @brief request with mrq_pg_update_state_request
+ * @ingroup Powergating
+ * @brief Request with mrq_pg_update_state_request
  *
  * Used by #MRQ_PG_UPDATE_STATE call to request BPMP to change the
  * state of a power partition #partition_id.
@@ -1155,20 +1201,20 @@ struct mrq_pg_read_state_response {
 struct mrq_pg_update_state_request {
        /** @brief ID of partition */
        uint32_t partition_id;
-       /** @brief secondary control of power partition
+       /** @brief Secondary control of power partition
         *  @details Ignored by many versions of the BPMP
         *  firmware. For maximum compatibility, set the value
-        *  according to @logic_state
+        *  according to @ref logic_state
         * *  0x1: power ON partition (@ref logic_state == 0x3)
         * *  0x3: power OFF partition (@ref logic_state == 0x1)
         */
        uint32_t sram_state;
-       /** @brief controls state of power partition, legal values are
+       /** @brief Controls state of power partition, legal values are
         * *  0x1 : power OFF partition
         * *  0x3 : power ON partition
         */
        uint32_t logic_state;
-       /** @brief change state of clocks of the power partition, legal values
+       /** @brief Change state of clocks of the power partition, legal values
         * *  0x0 : do not change clock state
         * *  0x1 : disable partition clocks (only applicable when
         *          @ref logic_state == 0x1)
@@ -1177,7 +1223,7 @@ struct mrq_pg_update_state_request {
         */
        uint32_t clock_state;
 } __ABI_PACKED;
-/** @*/
+/** @endcond*/
 
 /**
  * @ingroup MRQ_Codes
@@ -1186,19 +1232,20 @@ struct mrq_pg_update_state_request {
  * MRQ_PG_UPDATE_STATE, operations that change the power partition
  * state are NOT reference counted
  *
- * * Platforms: T186
+ * @note BPMP-FW forcefully turns off some partitions as part of SC7 entry
+ * because their state cannot be adequately restored on exit. Therefore,
+ * it is recommended to power off all domains via MRQ_PG prior to SC7 entry.
+ * See @ref bpmp_pdomain_ids for further detail.
+ *
+ * * Platforms: T186, T194
  * * Initiators: Any
  * * Targets: BPMP
  * * Request Payload: @ref mrq_pg_request
  * * Response Payload: @ref mrq_pg_response
+ *
  * @addtogroup Powergating
  * @{
  */
-
-/**
- * @name MRQ_PG sub-commands
- * @{
- */
 enum mrq_pg_cmd {
        /**
         * @brief Check whether the BPMP driver supports the specified
@@ -1232,7 +1279,7 @@ enum mrq_pg_cmd {
        CMD_PG_GET_STATE = 2,
 
        /**
-        * @brief get the name string of specified power domain id.
+        * @brief Get the name string of specified power domain id.
         *
         * mrq_response:err is
         * 0: Success
@@ -1242,7 +1289,7 @@ enum mrq_pg_cmd {
 
 
        /**
-        * @brief get the highest power domain id in the system. Not
+        * @brief Get the highest power domain id in the system. Not
         * all IDs between 0 and max_id are valid IDs.
         *
         * mrq_response:err is
@@ -1251,35 +1298,36 @@ enum mrq_pg_cmd {
         */
        CMD_PG_GET_MAX_ID = 4,
 };
-/** @} */
 
 #define MRQ_PG_NAME_MAXLEN     40
 
-/**
- * @brief possible power domain states in
- * cmd_pg_set_state_request:state and cmd_pg_get_state_response:state.
- *  PG_STATE_OFF: power domain is OFF
- *  PG_STATE_ON: power domain is ON
- *  PG_STATE_RUNNING: power domain is ON and made into directly usable
- *                    state by turning on the clocks associated with
- *                    the domain
- */
 enum pg_states {
+       /** @brief Power domain is OFF */
        PG_STATE_OFF = 0,
+       /** @brief Power domain is ON */
        PG_STATE_ON = 1,
+       /**
+        * @brief a legacy state where power domain and the clock
+        * associated to the domain are ON.
+        * This state is only supported in T186, and the use of it is
+        * deprecated.
+        */
        PG_STATE_RUNNING = 2,
 };
 
 struct cmd_pg_query_abi_request {
-       uint32_t type; /* enum mrq_pg_cmd */
+       /** @ref mrq_pg_cmd */
+       uint32_t type;
 } __ABI_PACKED;
 
 struct cmd_pg_set_state_request {
-       uint32_t state; /* enum pg_states */
+       /** @ref pg_states */
+       uint32_t state;
 } __ABI_PACKED;
 
 struct cmd_pg_get_state_response {
-       uint32_t state; /* enum pg_states */
+       /** @ref pg_states */
+       uint32_t state;
 } __ABI_PACKED;
 
 struct cmd_pg_get_name_response {
@@ -1291,8 +1339,7 @@ struct cmd_pg_get_max_id_response {
 } __ABI_PACKED;
 
 /**
- * @ingroup Powergating
- * @brief request with #MRQ_PG
+ * @brief Request with #MRQ_PG
  *
  * Used by the sender of an #MRQ_PG message to control power
  * partitions. The pg_request is split into several sub-commands. Some
@@ -1308,7 +1355,6 @@ struct cmd_pg_get_max_id_response {
  * |CMD_PG_GET_MAX_ID           | -                     |
  *
  */
-
 struct mrq_pg_request {
        uint32_t cmd;
        uint32_t id;
@@ -1319,8 +1365,7 @@ struct mrq_pg_request {
 } __ABI_PACKED;
 
 /**
- * @ingroup Powergating
- * @brief response to MRQ_PG
+ * @brief Response to MRQ_PG
  *
  * Each sub-command supported by @ref mrq_pg_request may return
  * sub-command-specific data. Some do and some do not as indicated in
@@ -1333,9 +1378,7 @@ struct mrq_pg_request {
  * |CMD_PG_GET_STATE            | get_state             |
  * |CMD_PG_GET_NAME             | get_name              |
  * |CMD_PG_GET_MAX_ID           | get_max_id            |
- *
  */
-
 struct mrq_pg_response {
        union {
                struct cmd_pg_get_state_response get_state;
@@ -1344,12 +1387,14 @@ struct mrq_pg_response {
        } __UNION_ANON;
 } __ABI_PACKED;
 
+/** @} */
+
 /**
  * @ingroup MRQ_Codes
  * @def MRQ_THERMAL
- * @brief interact with BPMP thermal framework
+ * @brief Interact with BPMP thermal framework
  *
- * * Platforms: T186
+ * * Platforms: T186, T194
  * * Initiators: Any
  * * Targets: Any
  * * Request Payload: TODO
@@ -1562,17 +1607,18 @@ union mrq_thermal_bpmp_to_host_response {
  * @brief Query CPU voltage hint data
  *
  * * Platforms: T186
+ * @cond bpmp_t186
  * * Initiators: CCPLEX
  * * Targets: BPMP
  * * Request Payload: @ref mrq_cpu_vhint_request
  * * Response Payload: N/A
  *
- * @addtogroup Vhint CPU Voltage hint
+ * @addtogroup Vhint
  * @{
  */
 
 /**
- * @brief request with #MRQ_CPU_VHINT
+ * @brief Request with #MRQ_CPU_VHINT
  *
  * Used by #MRQ_CPU_VHINT call by CCPLEX to retrieve voltage hint data
  * from BPMP to memory space pointed by #addr. CCPLEX is responsible
@@ -1581,16 +1627,16 @@ union mrq_thermal_bpmp_to_host_response {
  */
 struct mrq_cpu_vhint_request {
        /** @brief IOVA address for the #cpu_vhint_data */
-       uint32_t addr; /* struct cpu_vhint_data * */
+       uint32_t addr;
        /** @brief ID of the cluster whose data is requested */
-       uint32_t cluster_id; /* enum cluster_id */
+       uint32_t cluster_id;
 } __ABI_PACKED;
 
 /**
- * @brief description of the CPU v/f relation
+ * @brief Description of the CPU v/f relation
  *
- * Used by #MRQ_CPU_VHINT call to carry data pointed by #addr of
- * struct mrq_cpu_vhint_request
+ * Used by #MRQ_CPU_VHINT call to carry data pointed by
+ * #mrq_cpu_vhint_request::addr
  */
 struct cpu_vhint_data {
        uint32_t ref_clk_hz; /**< reference frequency in Hz */
@@ -1612,7 +1658,7 @@ struct cpu_vhint_data {
        /** reserved for future use */
        uint16_t reserved[328];
 } __ABI_PACKED;
-
+/** @endcond */
 /** @} */
 
 /**
@@ -1620,7 +1666,7 @@ struct cpu_vhint_data {
  * @def MRQ_ABI_RATCHET
  * @brief ABI ratchet value query
  *
- * * Platforms: T186
+ * * Platforms: T186, T194
  * * Initiators: Any
  * * Targets: BPMP
  * * Request Payload: @ref mrq_abi_ratchet_request
@@ -1630,7 +1676,7 @@ struct cpu_vhint_data {
  */
 
 /**
- * @brief an ABI compatibility mechanism
+ * @brief An ABI compatibility mechanism
  *
  * BPMP_ABI_RATCHET_VALUE may increase for various reasons in a future
  * revision of this header file.
@@ -1644,7 +1690,7 @@ struct cpu_vhint_data {
 #define BPMP_ABI_RATCHET_VALUE 3
 
 /**
- * @brief request with #MRQ_ABI_RATCHET.
+ * @brief Request with #MRQ_ABI_RATCHET.
  *
  * #ratchet should be #BPMP_ABI_RATCHET_VALUE from the ABI header
  * against which the requester was compiled.
@@ -1657,12 +1703,12 @@ struct cpu_vhint_data {
  * Otherwise, err shall be 0.
  */
 struct mrq_abi_ratchet_request {
-       /** @brief requester's ratchet value */
+       /** @brief Requester's ratchet value */
        uint16_t ratchet;
 };
 
 /**
- * @brief response to #MRQ_ABI_RATCHET
+ * @brief Response to #MRQ_ABI_RATCHET
  *
  * #ratchet shall be #BPMP_ABI_RATCHET_VALUE from the ABI header
  * against which BPMP firwmare was compiled.
@@ -1685,9 +1731,9 @@ struct mrq_abi_ratchet_response {
 /**
  * @ingroup MRQ_Codes
  * @def MRQ_EMC_DVFS_LATENCY
- * @brief query frequency dependent EMC DVFS latency
+ * @brief Query frequency dependent EMC DVFS latency
  *
- * * Platforms: T186
+ * * Platforms: T186, T194
  * * Initiators: CCPLEX
  * * Targets: BPMP
  * * Request Payload: N/A
@@ -1697,7 +1743,7 @@ struct mrq_abi_ratchet_response {
  */
 
 /**
- * @brief used by @ref mrq_emc_dvfs_latency_response
+ * @brief Used by @ref mrq_emc_dvfs_latency_response
  */
 struct emc_dvfs_latency {
        /** @brief EMC frequency in kHz */
@@ -1708,10 +1754,10 @@ struct emc_dvfs_latency {
 
 #define EMC_DVFS_LATENCY_MAX_SIZE      14
 /**
- * @brief response to #MRQ_EMC_DVFS_LATENCY
+ * @brief Response to #MRQ_EMC_DVFS_LATENCY
  */
 struct mrq_emc_dvfs_latency_response {
-       /** @brief the number valid entries in #pairs */
+       /** @brief The number valid entries in #pairs */
        uint32_t num_pairs;
        /** @brief EMC <frequency, latency> information */
        struct emc_dvfs_latency pairs[EMC_DVFS_LATENCY_MAX_SIZE];
@@ -1719,10 +1765,98 @@ struct mrq_emc_dvfs_latency_response {
 
 /** @} */
 
+/**
+ * @ingroup MRQ_Codes
+ * @def MRQ_CPU_NDIV_LIMITS
+ * @brief CPU freq. limits in ndiv
+ *
+ * * Platforms: T194 onwards
+ * @cond bpmp_t194
+ * * Initiators: CCPLEX
+ * * Targets: BPMP
+ * * Request Payload: @ref mrq_cpu_ndiv_limits_request
+ * * Response Payload: @ref mrq_cpu_ndiv_limits_response
+ * @addtogroup CPU
+ * @{
+ */
+
+/**
+ * @brief Request for ndiv limits of a cluster
+ */
+struct mrq_cpu_ndiv_limits_request {
+       /** @brief Enum cluster_id */
+       uint32_t cluster_id;
+} __ABI_PACKED;
+
+/**
+ * @brief Response to #MRQ_CPU_NDIV_LIMITS
+ */
+struct mrq_cpu_ndiv_limits_response {
+       /** @brief Reference frequency in Hz */
+       uint32_t ref_clk_hz;
+       /** @brief Post divider value */
+       uint16_t pdiv;
+       /** @brief Input divider value */
+       uint16_t mdiv;
+       /** @brief FMAX expressed with max NDIV value */
+       uint16_t ndiv_max;
+       /** @brief Minimum allowed NDIV value */
+       uint16_t ndiv_min;
+} __ABI_PACKED;
+
+/** @} */
+/** @endcond */
+
+/**
+ * @ingroup MRQ_Codes
+ * @def MRQ_CPU_AUTO_CC3
+ * @brief Query CPU cluster auto-CC3 configuration
+ *
+ * * Platforms: T194 onwards
+ * @cond bpmp_t194
+ * * Initiators: CCPLEX
+ * * Targets: BPMP
+ * * Request Payload: @ref mrq_cpu_auto_cc3_request
+ * * Response Payload: @ref mrq_cpu_auto_cc3_response
+ * @addtogroup CC3
+ *
+ * Queries from BPMP auto-CC3 configuration (allowed/not allowed) for a
+ * specified cluster. CCPLEX s/w uses this information to override its own
+ * device tree auto-CC3 settings, so that BPMP device tree is a single source of
+ * auto-CC3 platform configuration.
+ *
+ * @{
+ */
+
+/**
+ * @brief Request for auto-CC3 configuration of a cluster
+ */
+struct mrq_cpu_auto_cc3_request {
+       /** @brief Enum cluster_id (logical cluster id, known to CCPLEX s/w) */
+       uint32_t cluster_id;
+} __ABI_PACKED;
+
+/**
+ * @brief Response to #MRQ_CPU_AUTO_CC3
+ */
+struct mrq_cpu_auto_cc3_response {
+       /**
+        * @brief auto-CC3 configuration
+        *
+        * - bits[31..10] reserved.
+        * - bits[9..1] cc3 ndiv
+        * - bit [0] if "1" auto-CC3 is allowed, if "0" auto-CC3 is not allowed
+        */
+       uint32_t auto_cc3_config;
+} __ABI_PACKED;
+
+/** @} */
+/** @endcond */
+
 /**
  * @ingroup MRQ_Codes
  * @def MRQ_TRACE_ITER
- * @brief manage the trace iterator
+ * @brief Manage the trace iterator
  *
  * * Platforms: All
  * * Initiators: CCPLEX
@@ -1735,12 +1869,12 @@ struct mrq_emc_dvfs_latency_response {
 enum {
        /** @brief (re)start the tracing now. Ignore older events */
        TRACE_ITER_INIT = 0,
-       /** @brief clobber all events in the trace buffer */
+       /** @brief Clobber all events in the trace buffer */
        TRACE_ITER_CLEAN = 1
 };
 
 /**
- * @brief request with #MRQ_TRACE_ITER
+ * @brief Request with #MRQ_TRACE_ITER
  */
 struct mrq_trace_iter_request {
        /** @brief TRACE_ITER_INIT or TRACE_ITER_CLEAN */
@@ -1900,7 +2034,7 @@ struct cmd_ringbuf_console_get_fifo_resp {
  */
 struct mrq_ringbuf_console_host_to_bpmp_request {
        /**
-        * @brief type of request. Values listed in enum
+        * @brief Type of request. Values listed in enum
         * #mrq_ringbuf_console_host_to_bpmp_cmd.
         */
        uint32_t type;
@@ -1927,49 +2061,616 @@ union mrq_ringbuf_console_bpmp_to_host_response {
 } __ABI_PACKED;
 /** @} */
 
-/*
- *  4. Enumerations
+/**
+ * @ingroup MRQ_Codes
+ * @def MRQ_STRAP
+ * @brief Set a strap value controlled by BPMP
+ *
+ * * Platforms: T194 onwards
+ * @cond bpmp_t194
+ * * Initiators: CCPLEX
+ * * Targets: BPMP
+ * * Request Payload: @ref mrq_strap_request
+ * * Response Payload: N/A
+ * @addtogroup Strap
+ *
+ * A strap is an input that is sampled by a hardware unit during the
+ * unit's startup process. The sampled value of a strap affects the
+ * behavior of the unit until the unit is restarted. Many hardware
+ * units sample their straps at the instant that their resets are
+ * deasserted.
+ *
+ * BPMP owns registers which act as straps to various units. It
+ * exposes limited control of those straps via #MRQ_STRAP.
+ *
+ * @{
  */
+enum mrq_strap_cmd {
+       /** @private */
+       STRAP_RESERVED = 0,
+       /** @brief Set a strap value */
+       STRAP_SET = 1
+};
 
-/*
- *   4.1 CPU enumerations
+/**
+ * @brief Request with #MRQ_STRAP
+ */
+struct mrq_strap_request {
+       /** @brief @ref mrq_strap_cmd */
+       uint32_t cmd;
+       /** @brief Strap ID from @ref Strap_Ids */
+       uint32_t id;
+       /** @brief Desired value for strap (if cmd is #STRAP_SET) */
+       uint32_t value;
+} __ABI_PACKED;
+
+/**
+ * @defgroup Strap_Ids Strap Identifiers
+ * @}
+ */
+/** @endcond */
+
+/**
+ * @ingroup MRQ_Codes
+ * @def MRQ_UPHY
+ * @brief Perform a UPHY operation
  *
- * See <mach-t186/system-t186.h>
+ * * Platforms: T194 onwards
+ * @cond bpmp_t194
+ * * Initiators: CCPLEX
+ * * Targets: BPMP
+ * * Request Payload: @ref mrq_uphy_request
+ * * Response Payload: @ref mrq_uphy_response
  *
- *   4.2 CPU Cluster enumerations
+ * @addtogroup UPHY
+ * @{
+ */
+enum {
+       CMD_UPHY_PCIE_LANE_MARGIN_CONTROL = 1,
+       CMD_UPHY_PCIE_LANE_MARGIN_STATUS = 2,
+       CMD_UPHY_PCIE_EP_CONTROLLER_PLL_INIT = 3,
+       CMD_UPHY_PCIE_CONTROLLER_STATE = 4,
+       CMD_UPHY_MAX,
+};
+
+struct cmd_uphy_margin_control_request {
+       /** @brief Enable margin */
+       int32_t en;
+       /** @brief Clear the number of error and sections */
+       int32_t clr;
+       /** @brief Set x offset (1's complement) for left/right margin type (y should be 0) */
+       uint32_t x;
+       /** @brief Set y offset (1's complement) for left/right margin type (x should be 0) */
+       uint32_t y;
+       /** @brief Set number of bit blocks for each margin section */
+       uint32_t nblks;
+} __ABI_PACKED;
+
+struct cmd_uphy_margin_status_response {
+       /** @brief Number of errors observed */
+       uint32_t status;
+} __ABI_PACKED;
+
+struct cmd_uphy_ep_controller_pll_init_request {
+       /** @brief EP controller number, valid: 0, 4, 5 */
+       uint8_t ep_controller;
+} __ABI_PACKED;
+
+struct cmd_uphy_pcie_controller_state_request {
+       /** @brief PCIE controller number, valid: 0, 1, 2, 3, 4 */
+       uint8_t pcie_controller;
+       uint8_t enable;
+} __ABI_PACKED;
+
+/**
+ * @ingroup UPHY
+ * @brief Request with #MRQ_UPHY
  *
- * See <mach-t186/system-t186.h>
+ * Used by the sender of an #MRQ_UPHY message to control UPHY Lane RX margining.
+ * The uphy_request is split into several sub-commands. Some sub-commands
+ * require no additional data. Others have a sub-command specific payload
  *
- *   4.3 System low power state enumerations
+ * |sub-command                          |payload                                 |
+ * |------------------------------------ |----------------------------------------|
+ * |CMD_UPHY_PCIE_LANE_MARGIN_CONTROL    |uphy_set_margin_control                 |
+ * |CMD_UPHY_PCIE_LANE_MARGIN_STATUS     |                                        |
+ * |CMD_UPHY_PCIE_EP_CONTROLLER_PLL_INIT |cmd_uphy_ep_controller_pll_init_request |
+ * |CMD_UPHY_PCIE_CONTROLLER_STATE       |cmd_uphy_pcie_controller_state_request  |
  *
- * See <mach-t186/system-t186.h>
  */
 
-/*
- *   4.4 Clock enumerations
+struct mrq_uphy_request {
+       /** @brief Lane number. */
+       uint16_t lane;
+       /** @brief Sub-command id. */
+       uint16_t cmd;
+
+       union {
+               struct cmd_uphy_margin_control_request uphy_set_margin_control;
+               struct cmd_uphy_ep_controller_pll_init_request ep_ctrlr_pll_init;
+               struct cmd_uphy_pcie_controller_state_request controller_state;
+       } __UNION_ANON;
+} __ABI_PACKED;
+
+/**
+ * @ingroup UPHY
+ * @brief Response to MRQ_UPHY
+ *
+ * Each sub-command supported by @ref mrq_uphy_request may return
+ * sub-command-specific data. Some do and some do not as indicated in
+ * the following table
+ *
+ * |sub-command                       |payload                 |
+ * |----------------------------      |------------------------|
+ * |CMD_UPHY_PCIE_LANE_MARGIN_CONTROL |                        |
+ * |CMD_UPHY_PCIE_LANE_MARGIN_STATUS  |uphy_get_margin_status  |
  *
- * For clock enumerations, see <mach-t186/clk-t186.h>
  */
 
-/*
- *   4.5 Reset enumerations
+struct mrq_uphy_response {
+       union {
+               struct cmd_uphy_margin_status_response uphy_get_margin_status;
+       } __UNION_ANON;
+} __ABI_PACKED;
+
+/** @} */
+/** @endcond */
+
+/**
+ * @ingroup MRQ_Codes
+ * @def MRQ_FMON
+ * @brief Perform a frequency monitor configuration operations
+ *
+ * * Platforms: T194 onwards
+ * @cond bpmp_t194
+ * * Initiators: CCPLEX
+ * * Targets: BPMP
+ * * Request Payload: @ref mrq_fmon_request
+ * * Response Payload: @ref mrq_fmon_response
  *
- * For reset enumerations, see <mach-t186/reset-t186.h>
+ * @addtogroup FMON
+ * @{
  */
+enum {
+       /**
+        * @brief Clamp FMON configuration to specified rate.
+        *
+        * The monitored clock must be running for clamp to succeed. If
+        * clamped, FMON configuration is preserved when clock rate
+        * and/or state is changed.
+        */
+       CMD_FMON_GEAR_CLAMP = 1,
+       /**
+        * @brief Release clamped FMON configuration.
+        *
+        * Allow FMON configuration to follow monitored clock rate
+        * and/or state changes.
+        */
+       CMD_FMON_GEAR_FREE = 2,
+       /**
+        * @brief Return rate FMON is clamped at, or 0 if FMON is not
+        *         clamped.
+        *
+        * Inherently racy, since clamp state can be changed
+        * concurrently. Useful for testing.
+        */
+       CMD_FMON_GEAR_GET = 3,
+       CMD_FMON_NUM,
+};
 
-/*
- *   4.6 Thermal sensor enumerations
+struct cmd_fmon_gear_clamp_request {
+       int32_t unused;
+       int64_t rate;
+} __ABI_PACKED;
+
+/** @private */
+struct cmd_fmon_gear_clamp_response {
+       EMPTY
+} __ABI_PACKED;
+
+/** @private */
+struct cmd_fmon_gear_free_request {
+       EMPTY
+} __ABI_PACKED;
+
+/** @private */
+struct cmd_fmon_gear_free_response {
+       EMPTY
+} __ABI_PACKED;
+
+/** @private */
+struct cmd_fmon_gear_get_request {
+       EMPTY
+} __ABI_PACKED;
+
+struct cmd_fmon_gear_get_response {
+       int64_t rate;
+} __ABI_PACKED;
+
+/**
+ * @ingroup FMON
+ * @brief Request with #MRQ_FMON
+ *
+ * Used by the sender of an #MRQ_FMON message to configure clock
+ * frequency monitors. The FMON request is split into several
+ * sub-commands. Some sub-commands require no additional data.
+ * Others have a sub-command specific payload
+ *
+ * |sub-command                 |payload                |
+ * |----------------------------|-----------------------|
+ * |CMD_FMON_GEAR_CLAMP         |fmon_gear_clamp        |
+ * |CMD_FMON_GEAR_FREE          |-                      |
+ * |CMD_FMON_GEAR_GET           |-                      |
+ *
+ */
+
+struct mrq_fmon_request {
+       /** @brief Sub-command and clock id concatenated to 32-bit word.
+        * - bits[31..24] is the sub-cmd.
+        * - bits[23..0] is monitored clock id used to select target
+        *   FMON
+        */
+       uint32_t cmd_and_id;
+
+       union {
+               struct cmd_fmon_gear_clamp_request fmon_gear_clamp;
+               /** @private */
+               struct cmd_fmon_gear_free_request fmon_gear_free;
+               /** @private */
+               struct cmd_fmon_gear_get_request fmon_gear_get;
+       } __UNION_ANON;
+} __ABI_PACKED;
+
+/**
+ * @ingroup FMON
+ * @brief Response to MRQ_FMON
+ *
+ * Each sub-command supported by @ref mrq_fmon_request may
+ * return sub-command-specific data as indicated below.
+ *
+ * |sub-command                 |payload                 |
+ * |----------------------------|------------------------|
+ * |CMD_FMON_GEAR_CLAMP         |-                       |
+ * |CMD_FMON_GEAR_FREE          |-                       |
+ * |CMD_FMON_GEAR_GET           |fmon_gear_get           |
+ *
+ */
+
+struct mrq_fmon_response {
+       union {
+               /** @private */
+               struct cmd_fmon_gear_clamp_response fmon_gear_clamp;
+               /** @private */
+               struct cmd_fmon_gear_free_response fmon_gear_free;
+               struct cmd_fmon_gear_get_response fmon_gear_get;
+       } __UNION_ANON;
+} __ABI_PACKED;
+
+/** @} */
+/** @endcond */
+
+/**
+ * @ingroup MRQ_Codes
+ * @def MRQ_EC
+ * @brief Provide status information on faults reported by Error
+ *        Collator (EC) to HSM.
+ *
+ * * Platforms: T194 onwards
+ * @cond bpmp_t194
+ * * Initiators: CCPLEX
+ * * Targets: BPMP
+ * * Request Payload: @ref mrq_ec_request
+ * * Response Payload: @ref mrq_ec_response
+ *
+ * @note This MRQ ABI is under construction, and subject to change
+ *
+ * @addtogroup EC
+ * @{
+ */
+enum {
+       /**
+        * @brief Retrieve specified EC status.
+        *
+        * mrq_response::err is 0 if the operation was successful, or @n
+        * -#BPMP_ENODEV if target EC is not owned by BPMP @n
+        * -#BPMP_EACCES if target EC power domain is turned off
+        */
+       CMD_EC_STATUS_GET = 1,
+       CMD_EC_NUM,
+};
+
+/** @brief BPMP ECs error types */
+enum bpmp_ec_err_type {
+       /** @brief Parity error on internal data path
+        *
+        *  Error descriptor @ref ec_err_simple_desc.
+        */
+       EC_ERR_TYPE_PARITY_INTERNAL             = 1,
+
+       /** @brief ECC SEC error on internal data path
+        *
+        *  Error descriptor @ref ec_err_simple_desc.
+        */
+       EC_ERR_TYPE_ECC_SEC_INTERNAL            = 2,
+
+       /** @brief ECC DED error on internal data path
+        *
+        *  Error descriptor @ref ec_err_simple_desc.
+        */
+       EC_ERR_TYPE_ECC_DED_INTERNAL            = 3,
+
+       /** @brief Comparator error
+        *
+        *  Error descriptor @ref ec_err_simple_desc.
+        */
+       EC_ERR_TYPE_COMPARATOR                  = 4,
+
+       /** @brief Register parity error
+        *
+        *  Error descriptor @ref ec_err_reg_parity_desc.
+        */
+       EC_ERR_TYPE_REGISTER_PARITY             = 5,
+
+       /** @brief Parity error from on-chip SRAM/FIFO
+        *
+        *  Error descriptor @ref ec_err_simple_desc.
+        */
+       EC_ERR_TYPE_PARITY_SRAM                 = 6,
+
+       /** @brief Clock Monitor error
+        *
+        *  Error descriptor @ref ec_err_fmon_desc.
+        */
+       EC_ERR_TYPE_CLOCK_MONITOR               = 9,
+
+       /** @brief Voltage Monitor error
+        *
+        *  Error descriptor @ref ec_err_vmon_desc.
+        */
+       EC_ERR_TYPE_VOLTAGE_MONITOR             = 10,
+
+       /** @brief SW Correctable error
+        *
+        *  Error descriptor @ref ec_err_simple_desc.
+        */
+       EC_ERR_TYPE_SW_CORRECTABLE              = 16,
+
+       /** @brief SW Uncorrectable error
+        *
+        *  Error descriptor @ref ec_err_simple_desc.
+        */
+       EC_ERR_TYPE_SW_UNCORRECTABLE            = 17,
+
+       /** @brief Other HW Correctable error
+        *
+        *  Error descriptor @ref ec_err_simple_desc.
+        */
+       EC_ERR_TYPE_OTHER_HW_CORRECTABLE        = 32,
+
+       /** @brief Other HW Uncorrectable error
+        *
+        *  Error descriptor @ref ec_err_simple_desc.
+        */
+       EC_ERR_TYPE_OTHER_HW_UNCORRECTABLE      = 33,
+};
+
+/** @brief Group of registers with parity error. */
+enum ec_registers_group {
+       /** @brief Functional registers group */
+       EC_ERR_GROUP_FUNC_REG           = 0,
+       /** @brief SCR registers group */
+       EC_ERR_GROUP_SCR_REG            = 1,
+};
+
+/**
+ * @defgroup bpmp_ec_status_flags EC Status Flags
+ * @addtogroup bpmp_ec_status_flags
+ * @{
+ */
+/** @brief No EC error found flag */
+#define EC_STATUS_FLAG_NO_ERROR                0x0001
+/** @brief Last EC error found flag */
+#define EC_STATUS_FLAG_LAST_ERROR      0x0002
+/** @brief EC latent error flag */
+#define EC_STATUS_FLAG_LATENT_ERROR    0x0004
+/** @} */
+
+/**
+ * @defgroup bpmp_ec_desc_flags EC Descriptor Flags
+ * @addtogroup bpmp_ec_desc_flags
+ * @{
+ */
+/** @brief EC descriptor error resolved flag */
+#define EC_DESC_FLAG_RESOLVED          0x0001
+/** @brief EC descriptor failed to retrieve id flag */
+#define EC_DESC_FLAG_NO_ID             0x0002
+/** @} */
+
+/**
+ * |error type                       | fmon_clk_id values        |
+ * |---------------------------------|---------------------------|
+ * |@ref EC_ERR_TYPE_CLOCK_MONITOR   |@ref bpmp_clock_ids        |
+ */
+struct ec_err_fmon_desc {
+       /** @brief Bitmask of @ref bpmp_ec_desc_flags  */
+       uint16_t desc_flags;
+       /** @brief FMON monitored clock id */
+       uint16_t fmon_clk_id;
+       /** @brief Bitmask of @ref bpmp_fmon_faults_flags */
+       uint32_t fmon_faults;
+       /** @brief FMON faults access error */
+       int32_t fmon_access_error;
+} __ABI_PACKED;
+
+/**
+ * |error type                       | vmon_adc_id values        |
+ * |---------------------------------|---------------------------|
+ * |@ref EC_ERR_TYPE_VOLTAGE_MONITOR |@ref bpmp_adc_ids          |
+ */
+struct ec_err_vmon_desc {
+       /** @brief Bitmask of @ref bpmp_ec_desc_flags  */
+       uint16_t desc_flags;
+       /** @brief VMON rail adc id */
+       uint16_t vmon_adc_id;
+       /** @brief Bitmask of @ref bpmp_vmon_faults_flags */
+       uint32_t vmon_faults;
+       /** @brief VMON faults access error */
+       int32_t vmon_access_error;
+} __ABI_PACKED;
+
+/**
+ * |error type                       | reg_id values             |
+ * |---------------------------------|---------------------------|
+ * |@ref EC_ERR_TYPE_REGISTER_PARITY |@ref bpmp_ec_registers_ids |
+ */
+struct ec_err_reg_parity_desc {
+       /** @brief Bitmask of @ref bpmp_ec_desc_flags  */
+       uint16_t desc_flags;
+       /** @brief Register id */
+       uint16_t reg_id;
+       /** @brief Register group @ref ec_registers_group */
+       uint16_t reg_group;
+} __ABI_PACKED;
+
+/**
+ * |error type                              | err_source_id values      |
+ * |----------------------------------------|---------------------------|
+ * |@ref EC_ERR_TYPE_PARITY_INTERNAL        |@ref bpmp_ec_ipath_ids     |
+ * |@ref EC_ERR_TYPE_ECC_SEC_INTERNAL       |@ref bpmp_ec_ipath_ids     |
+ * |@ref EC_ERR_TYPE_ECC_DED_INTERNAL       |@ref bpmp_ec_ipath_ids     |
+ * |@ref EC_ERR_TYPE_COMPARATOR             |@ref bpmp_ec_comparator_ids|
+ * |@ref EC_ERR_TYPE_PARITY_SRAM            |@ref bpmp_clock_ids        |
+ * |@ref EC_ERR_TYPE_SW_CORRECTABLE         |@ref bpmp_ec_misc_ids      |
+ * |@ref EC_ERR_TYPE_SW_UNCORRECTABLE       |@ref bpmp_ec_misc_ids      |
+ * |@ref EC_ERR_TYPE_OTHER_HW_CORRECTABLE   |@ref bpmp_ec_misc_ids      |
+ * |@ref EC_ERR_TYPE_OTHER_HW_UNCORRECTABLE |@ref bpmp_ec_misc_ids      |
+ */
+struct ec_err_simple_desc {
+       /** @brief Bitmask of @ref bpmp_ec_desc_flags  */
+       uint16_t desc_flags;
+       /** @brief Error source id. Id space depends on error type. */
+       uint16_t err_source_id;
+} __ABI_PACKED;
+
+/** @brief Union of EC error descriptors */
+union ec_err_desc {
+       struct ec_err_fmon_desc fmon_desc;
+       struct ec_err_vmon_desc vmon_desc;
+       struct ec_err_reg_parity_desc reg_parity_desc;
+       struct ec_err_simple_desc simple_desc;
+} __ABI_PACKED;
+
+struct cmd_ec_status_get_request {
+       /** @brief HSM error line number that identifies target EC. */
+       uint32_t ec_hsm_id;
+} __ABI_PACKED;
+
+/** EC status maximum number of descriptors */
+#define EC_ERR_STATUS_DESC_MAX_NUM     4
+
+struct cmd_ec_status_get_response {
+       /** @brief Target EC id (the same id received with request). */
+       uint32_t ec_hsm_id;
+       /**
+        * @brief Bitmask of @ref bpmp_ec_status_flags
+        *
+        * If NO_ERROR flag is set, error_ fields should be ignored
+        */
+       uint32_t ec_status_flags;
+       /** @brief Found EC error index. */
+       uint32_t error_idx;
+       /** @brief  Found EC error type @ref bpmp_ec_err_type. */
+       uint32_t error_type;
+       /** @brief  Number of returned EC error descriptors */
+       uint32_t error_desc_num;
+       /** @brief  EC error descriptors */
+       union ec_err_desc error_descs[EC_ERR_STATUS_DESC_MAX_NUM];
+} __ABI_PACKED;
+
+/**
+ * @ingroup EC
+ * @brief Request with #MRQ_EC
+ *
+ * Used by the sender of an #MRQ_EC message to access ECs owned
+ * by BPMP.
+ *
+ * |sub-command                 |payload                |
+ * |----------------------------|-----------------------|
+ * |@ref CMD_EC_STATUS_GET      |ec_status_get          |
  *
- * For thermal sensor enumerations, see <mach-t186/thermal-t186.h>
  */
 
+struct mrq_ec_request {
+       /** @brief Sub-command id. */
+       uint32_t cmd_id;
+
+       union {
+               struct cmd_ec_status_get_request ec_status_get;
+       } __UNION_ANON;
+} __ABI_PACKED;
+
 /**
- * @defgroup Error_Codes
+ * @ingroup EC
+ * @brief Response to MRQ_EC
+ *
+ * Each sub-command supported by @ref mrq_ec_request may return
+ * sub-command-specific data as indicated below.
+ *
+ * |sub-command                 |payload                 |
+ * |----------------------------|------------------------|
+ * |@ref CMD_EC_STATUS_GET      |ec_status_get           |
+ *
+ */
+
+struct mrq_ec_response {
+       union {
+               struct cmd_ec_status_get_response ec_status_get;
+       } __UNION_ANON;
+} __ABI_PACKED;
+
+/** @} */
+/** @endcond */
+
+/**
+ * @ingroup MRQ_Codes
+ * @def MRQ_FBVOLT_STATUS
+ * @brief Provides status information about voltage state for fuse burning
+ *
+ * * Platforms: T194 onwards
+ * @cond bpmp_t194
+ * * Initiators: CCPLEX
+ * * Target: BPMP
+ * * Request Payload: None
+ * * Response Payload: @ref mrq_fbvolt_status_response
+ * @{
+ */
+
+/**
+ * @ingroup Fbvolt_status
+ * @brief Response to #MRQ_FBVOLT_STATUS
+ *
+ * Value of #ready reflects if core voltages are in a suitable state for buring
+ * fuses. A value of 0x1 indicates that core voltages are ready for burning
+ * fuses. A value of 0x0 indicates that core voltages are not ready.
+ */
+struct mrq_fbvolt_status_response {
+       /** @brief Bit [0:0] - ready status, bits [31:1] - reserved */
+       uint32_t ready;
+       /** @brief Reserved */
+       uint32_t unused;
+} __ABI_PACKED;
+
+/** @} */
+/** @endcond */
+
+/**
+ * @addtogroup Error_Codes
  * Negative values for mrq_response::err generally indicate some
  * error. The ABI defines the following error codes. Negating these
  * defines is an exercise left to the user.
  * @{
  */
+
 /** @brief No such file or directory */
 #define BPMP_ENOENT    2
 /** @brief No MRQ handler */
@@ -1994,6 +2695,11 @@ union mrq_ringbuf_console_bpmp_to_host_response {
 #define BPMP_ETIMEDOUT  23
 /** @brief Out of range */
 #define BPMP_ERANGE    34
+/** @brief Function not implemented */
+#define  BPMP_ENOSYS   38
+/** @brief Invalid slot */
+#define BPMP_EBADSLT   57
+
 /** @} */
-/** @} */
+
 #endif
index e69e4c4d80ae91d053c32a2cf2c84fc3220a3968..b02f926a02166af960c25da152ca457c905d4451 100644 (file)
@@ -129,6 +129,7 @@ int tegra_bpmp_request_mrq(struct tegra_bpmp *bpmp, unsigned int mrq,
                           tegra_bpmp_mrq_handler_t handler, void *data);
 void tegra_bpmp_free_mrq(struct tegra_bpmp *bpmp, unsigned int mrq,
                         void *data);
+bool tegra_bpmp_mrq_is_supported(struct tegra_bpmp *bpmp, unsigned int mrq);
 #else
 static inline struct tegra_bpmp *tegra_bpmp_get(struct device *dev)
 {
@@ -164,6 +165,12 @@ static inline void tegra_bpmp_free_mrq(struct tegra_bpmp *bpmp,
                                       unsigned int mrq, void *data)
 {
 }
+
+static inline bool tegra_bpmp_mrq_is_supported(struct tegra_bpmp *bpmp,
+                                             unsigned int mrq)
+{
+       return false;
+}
 #endif
 
 #if IS_ENABLED(CONFIG_CLK_TEGRA_BPMP)
index 9b6ea0c7211780182c4cce20735ade7ef673695d..8fb2f8a87339320ab6b02a421634892ad702ec90 100644 (file)
@@ -60,7 +60,6 @@ struct tegra_sku_info {
 
 u32 tegra_read_straps(void);
 u32 tegra_read_ram_code(void);
-u32 tegra_read_chipid(void);
 int tegra_fuse_readl(unsigned long offset, u32 *value);
 
 extern struct tegra_sku_info tegra_sku_info;
index 562426812ab2a1adac08b03cc3791d71009a5b72..fd816f6aa9cc48d76d6f5c1ea78aab9369cced72 100644 (file)
@@ -90,6 +90,10 @@ enum tegra_io_pad {
        TEGRA_IO_PAD_CSID,
        TEGRA_IO_PAD_CSIE,
        TEGRA_IO_PAD_CSIF,
+       TEGRA_IO_PAD_CSIG,
+       TEGRA_IO_PAD_CSIH,
+       TEGRA_IO_PAD_DAP3,
+       TEGRA_IO_PAD_DAP5,
        TEGRA_IO_PAD_DBG,
        TEGRA_IO_PAD_DEBUG_NONAO,
        TEGRA_IO_PAD_DMIC,
@@ -102,10 +106,15 @@ enum tegra_io_pad {
        TEGRA_IO_PAD_EDP,
        TEGRA_IO_PAD_EMMC,
        TEGRA_IO_PAD_EMMC2,
+       TEGRA_IO_PAD_EQOS,
        TEGRA_IO_PAD_GPIO,
+       TEGRA_IO_PAD_GP_PWM2,
+       TEGRA_IO_PAD_GP_PWM3,
        TEGRA_IO_PAD_HDMI,
        TEGRA_IO_PAD_HDMI_DP0,
        TEGRA_IO_PAD_HDMI_DP1,
+       TEGRA_IO_PAD_HDMI_DP2,
+       TEGRA_IO_PAD_HDMI_DP3,
        TEGRA_IO_PAD_HSIC,
        TEGRA_IO_PAD_HV,
        TEGRA_IO_PAD_LVDS,
@@ -115,8 +124,14 @@ enum tegra_io_pad {
        TEGRA_IO_PAD_PEX_CLK_BIAS,
        TEGRA_IO_PAD_PEX_CLK1,
        TEGRA_IO_PAD_PEX_CLK2,
+       TEGRA_IO_PAD_PEX_CLK2_BIAS,
        TEGRA_IO_PAD_PEX_CLK3,
        TEGRA_IO_PAD_PEX_CNTRL,
+       TEGRA_IO_PAD_PEX_CTL2,
+       TEGRA_IO_PAD_PEX_L0_RST_N,
+       TEGRA_IO_PAD_PEX_L1_RST_N,
+       TEGRA_IO_PAD_PEX_L5_RST_N,
+       TEGRA_IO_PAD_PWR_CTL,
        TEGRA_IO_PAD_SDMMC1,
        TEGRA_IO_PAD_SDMMC1_HV,
        TEGRA_IO_PAD_SDMMC2,
@@ -124,10 +139,16 @@ enum tegra_io_pad {
        TEGRA_IO_PAD_SDMMC3,
        TEGRA_IO_PAD_SDMMC3_HV,
        TEGRA_IO_PAD_SDMMC4,
+       TEGRA_IO_PAD_SOC_GPIO10,
+       TEGRA_IO_PAD_SOC_GPIO12,
+       TEGRA_IO_PAD_SOC_GPIO13,
+       TEGRA_IO_PAD_SOC_GPIO53,
        TEGRA_IO_PAD_SPI,
        TEGRA_IO_PAD_SPI_HV,
        TEGRA_IO_PAD_SYS_DDC,
        TEGRA_IO_PAD_UART,
+       TEGRA_IO_PAD_UART4,
+       TEGRA_IO_PAD_UART5,
        TEGRA_IO_PAD_UFS,
        TEGRA_IO_PAD_USB0,
        TEGRA_IO_PAD_USB1,