Merge branches 'clk-ingenic', 'clk-at91', 'clk-kconfig', 'clk-imx', 'clk-qcom', ...
authorStephen Boyd <sboyd@kernel.org>
Tue, 20 Oct 2020 18:47:07 +0000 (11:47 -0700)
committerStephen Boyd <sboyd@kernel.org>
Tue, 20 Oct 2020 18:47:07 +0000 (11:47 -0700)
 - Support qcom SM8150/SM8250 video and display clks
 - Change how qcom's display port clks work

* clk-ingenic:
  clk: ingenic: Respect CLK_SET_RATE_PARENT in .round_rate
  clk: ingenic: Don't tag custom clocks with CLK_SET_RATE_PARENT
  clk: ingenic: Don't use CLK_SET_RATE_GATE for PLL
  clk: ingenic: Use readl_poll_timeout instead of custom loop
  clk: ingenic: Use to_clk_info() macro for all clocks

* clk-at91:
  clk: at91: sam9x60: support only two programmable clocks
  clk: at91: clk-sam9x60-pll: remove unused variable
  clk: at91: clk-main: update key before writing AT91_CKGR_MOR
  clk: at91: remove the checking of parent_name

* clk-kconfig:
  clk: Restrict CLK_HSDK to ARC_SOC_HSDK

* clk-imx:
  clk: imx8mq: Fix usdhc parents order
  clk: imx: imx21: Remove clock driver
  clk: imx: gate2: Fix a few typos
  clk: imx: Fix and update kerneldoc
  clk: imx: fix i.MX7D peripheral clk mux flags
  clk: imx: fix composite peripheral flags
  clk: imx: Correct the memrepair clock on imx8mp
  clk: imx: Correct the root clk of media ldb on imx8mp
  clk: imx: vf610: Add CRC clock
  clk: imx: Explicitly include bits.h
  clk: imx8qxp: Support building i.MX8QXP clock driver as module
  clk: imx8m: Support module build
  clk: imx: Add clock configuration for ARMv7 platforms
  clk: imx: Support building i.MX common clock driver as module
  clk: composite: Export clk_hw_register_composite()
  clk: imx6sl: Use BIT(x) to avoid shifting signed 32-bit value by 31 bits

* clk-qcom:
  clk: qcom: gdsc: Keep RETAIN_FF bit set if gdsc is already on
  clk: qcom: Add display clock controller driver for SM8150 and SM8250
  dt-bindings: clock: add QCOM SM8150 and SM8250 display clock bindings
  clk: qcom: add video clock controller driver for SM8250
  clk: qcom: add video clock controller driver for SM8150
  dt-bindings: clock: add SM8250 QCOM video clock bindings
  dt-bindings: clock: add SM8150 QCOM video clock bindings
  dt-bindings: clock: combine qcom,sdm845-videocc and qcom,sc7180-videocc
  clk: qcom: gcc-msm8994: Add missing clocks, resets and GDSCs
  clk/qcom: fix spelling typo
  clk: qcom: gcc-sdm660: Fix wrong parent_map
  clk: qcom: dispcc: Update DP clk ops for phy design
  clk: qcom: gcc-msm8939: remove defined but not used variables
  clk: qcom: ipq8074: make pcie0_rchng_clk_src static

* clk-prima2:
  clk: clk-prima2: fix return value check in prima2_clk_init()

* clk-bcm:
  clk: bcm2835: add missing release if devm_clk_hw_register fails
  clk: bcm: rpi: Add register to control pixel bvb clk

137 files changed:
Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt
Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.txt
Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt
Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt
Documentation/devicetree/bindings/arm/mediatek/mediatek,mfgcfg.txt
Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt
Documentation/devicetree/bindings/arm/mediatek/mediatek,vdecsys.txt
Documentation/devicetree/bindings/clock/allwinner,sun4i-a10-ccu.yaml
Documentation/devicetree/bindings/clock/renesas,cpg-mssr.yaml
drivers/clk/Kconfig
drivers/clk/at91/at91sam9g45.c
drivers/clk/at91/clk-main.c
drivers/clk/at91/clk-peripheral.c
drivers/clk/at91/clk-sam9x60-pll.c
drivers/clk/at91/sam9x60.c
drivers/clk/baikal-t1/clk-ccu-pll.c
drivers/clk/bcm/clk-bcm2835.c
drivers/clk/bcm/clk-raspberrypi.c
drivers/clk/clk-axi-clkgen.c
drivers/clk/clk-composite.c
drivers/clk/clk-fixed-factor.c
drivers/clk/clk-fixed-rate.c
drivers/clk/clk-qoriq.c
drivers/clk/clk-s2mps11.c
drivers/clk/clk-si5341.c
drivers/clk/davinci/da8xx-cfgchip.c
drivers/clk/imx/Kconfig
drivers/clk/imx/Makefile
drivers/clk/imx/clk-busy.c
drivers/clk/imx/clk-composite-7ulp.c
drivers/clk/imx/clk-composite-8m.c
drivers/clk/imx/clk-cpu.c
drivers/clk/imx/clk-fixup-mux.c
drivers/clk/imx/clk-frac-pll.c
drivers/clk/imx/clk-gate2.c
drivers/clk/imx/clk-imx21.c [deleted file]
drivers/clk/imx/clk-imx6q.c
drivers/clk/imx/clk-imx6sl.c
drivers/clk/imx/clk-imx6sx.c
drivers/clk/imx/clk-imx7d.c
drivers/clk/imx/clk-imx8mm.c
drivers/clk/imx/clk-imx8mn.c
drivers/clk/imx/clk-imx8mp.c
drivers/clk/imx/clk-imx8mq.c
drivers/clk/imx/clk-imx8qxp-lpcg.c
drivers/clk/imx/clk-imx8qxp.c
drivers/clk/imx/clk-lpcg-scu.c
drivers/clk/imx/clk-pfd.c
drivers/clk/imx/clk-pfdv2.c
drivers/clk/imx/clk-pll14xx.c
drivers/clk/imx/clk-pllv1.c
drivers/clk/imx/clk-pllv3.c
drivers/clk/imx/clk-pllv4.c
drivers/clk/imx/clk-sscg-pll.c
drivers/clk/imx/clk-vf610.c
drivers/clk/imx/clk.c
drivers/clk/imx/clk.h
drivers/clk/ingenic/cgu.c
drivers/clk/keystone/sci-clk.c
drivers/clk/mediatek/Kconfig
drivers/clk/mediatek/Makefile
drivers/clk/mediatek/clk-mt6765.c
drivers/clk/mediatek/clk-mt6779.c
drivers/clk/mediatek/clk-mt6797.c
drivers/clk/mediatek/clk-mt7629.c
drivers/clk/mediatek/clk-mt8167-aud.c [new file with mode: 0644]
drivers/clk/mediatek/clk-mt8167-img.c [new file with mode: 0644]
drivers/clk/mediatek/clk-mt8167-mfgcfg.c [new file with mode: 0644]
drivers/clk/mediatek/clk-mt8167-mm.c [new file with mode: 0644]
drivers/clk/mediatek/clk-mt8167-vdec.c [new file with mode: 0644]
drivers/clk/mediatek/clk-mt8167.c [new file with mode: 0644]
drivers/clk/meson/Kconfig
drivers/clk/meson/axg-audio.c
drivers/clk/meson/clk-phase.c
drivers/clk/meson/clk-phase.h
drivers/clk/meson/g12a.c
drivers/clk/meson/meson-aoclk.c
drivers/clk/mmp/clk-of-mmp2.c
drivers/clk/mmp/clk-of-pxa1928.c
drivers/clk/mvebu/ap-cpu-clk.c
drivers/clk/pxa/clk-pxa.h
drivers/clk/renesas/Kconfig
drivers/clk/renesas/Makefile
drivers/clk/renesas/r7s9210-cpg-mssr.c
drivers/clk/renesas/r8a7742-cpg-mssr.c
drivers/clk/renesas/r8a7743-cpg-mssr.c
drivers/clk/renesas/r8a7745-cpg-mssr.c
drivers/clk/renesas/r8a77470-cpg-mssr.c
drivers/clk/renesas/r8a7790-cpg-mssr.c
drivers/clk/renesas/r8a7791-cpg-mssr.c
drivers/clk/renesas/r8a7792-cpg-mssr.c
drivers/clk/renesas/r8a7794-cpg-mssr.c
drivers/clk/renesas/r8a779a0-cpg-mssr.c [new file with mode: 0644]
drivers/clk/renesas/renesas-cpg-mssr.c
drivers/clk/renesas/renesas-cpg-mssr.h
drivers/clk/rockchip/Kconfig [new file with mode: 0644]
drivers/clk/rockchip/Makefile
drivers/clk/rockchip/clk-ddr.c
drivers/clk/rockchip/clk-half-divider.c
drivers/clk/rockchip/clk-rk3308.c
drivers/clk/rockchip/clk-rk3399.c
drivers/clk/rockchip/clk.c
drivers/clk/rockchip/softrst.c
drivers/clk/samsung/clk-cpu.c
drivers/clk/samsung/clk-cpu.h
drivers/clk/samsung/clk-exynos3250.c
drivers/clk/samsung/clk-exynos4.c
drivers/clk/samsung/clk-exynos5250.c
drivers/clk/samsung/clk-exynos5420.c
drivers/clk/samsung/clk-exynos5433.c
drivers/clk/sirf/clk-prima2.c
drivers/clk/socfpga/clk-agilex.c
drivers/clk/sunxi-ng/Kconfig
drivers/clk/sunxi-ng/Makefile
drivers/clk/sunxi-ng/ccu-sun50i-a100-r.c [new file with mode: 0644]
drivers/clk/sunxi-ng/ccu-sun50i-a100-r.h [new file with mode: 0644]
drivers/clk/sunxi-ng/ccu-sun50i-a100.c [new file with mode: 0644]
drivers/clk/sunxi-ng/ccu-sun50i-a100.h [new file with mode: 0644]
drivers/clk/sunxi-ng/ccu-sun8i-r40.c
drivers/clk/tegra/clk-tegra210-emc.c
drivers/clk/ti/autoidle.c
drivers/clk/ti/clk-7xx.c
drivers/clk/ti/clockdomain.c
drivers/clk/uniphier/clk-uniphier-cpugear.c
drivers/clk/uniphier/clk-uniphier-mux.c
include/dt-bindings/clock/dra7.h
include/dt-bindings/clock/exynos5250.h
include/dt-bindings/clock/exynos5420.h
include/dt-bindings/clock/imx8mp-clock.h
include/dt-bindings/clock/mt8167-clk.h [new file with mode: 0644]
include/dt-bindings/clock/r8a779a0-cpg-mssr.h [new file with mode: 0644]
include/dt-bindings/clock/sun50i-a100-ccu.h [new file with mode: 0644]
include/dt-bindings/clock/sun50i-a100-r-ccu.h [new file with mode: 0644]
include/dt-bindings/clock/vf610-clock.h
include/dt-bindings/power/r8a779a0-sysc.h [new file with mode: 0644]
include/dt-bindings/reset/sun50i-a100-ccu.h [new file with mode: 0644]
include/dt-bindings/reset/sun50i-a100-r-ccu.h [new file with mode: 0644]

index bd7a0fa..ea827e8 100644 (file)
@@ -15,6 +15,7 @@ Required Properties:
        - "mediatek,mt7623-apmixedsys", "mediatek,mt2701-apmixedsys"
        - "mediatek,mt7629-apmixedsys"
        - "mediatek,mt8135-apmixedsys"
+       - "mediatek,mt8167-apmixedsys", "syscon"
        - "mediatek,mt8173-apmixedsys"
        - "mediatek,mt8183-apmixedsys", "syscon"
        - "mediatek,mt8516-apmixedsys"
index 38309db..b32d374 100644 (file)
@@ -11,6 +11,7 @@ Required Properties:
        - "mediatek,mt6779-audio", "syscon"
        - "mediatek,mt7622-audsys", "syscon"
        - "mediatek,mt7623-audsys", "mediatek,mt2701-audsys", "syscon"
+       - "mediatek,mt8167-audiosys", "syscon"
        - "mediatek,mt8183-audiosys", "syscon"
        - "mediatek,mt8516-audsys", "syscon"
 - #clock-cells: Must be 1
index 1e1f007..dce4c92 100644 (file)
@@ -12,6 +12,7 @@ Required Properties:
        - "mediatek,mt6779-imgsys", "syscon"
        - "mediatek,mt6797-imgsys", "syscon"
        - "mediatek,mt7623-imgsys", "mediatek,mt2701-imgsys", "syscon"
+       - "mediatek,mt8167-imgsys", "syscon"
        - "mediatek,mt8173-imgsys", "syscon"
        - "mediatek,mt8183-imgsys", "syscon"
 - #clock-cells: Must be 1
index 49a968b..eb3523c 100644 (file)
@@ -16,6 +16,7 @@ Required Properties:
        - "mediatek,mt7623-infracfg", "mediatek,mt2701-infracfg", "syscon"
        - "mediatek,mt7629-infracfg", "syscon"
        - "mediatek,mt8135-infracfg", "syscon"
+       - "mediatek,mt8167-infracfg", "syscon"
        - "mediatek,mt8173-infracfg", "syscon"
        - "mediatek,mt8183-infracfg", "syscon"
        - "mediatek,mt8516-infracfg", "syscon"
index ad5f9d2..054424f 100644 (file)
@@ -8,6 +8,7 @@ Required Properties:
 - compatible: Should be one of:
        - "mediatek,mt2712-mfgcfg", "syscon"
        - "mediatek,mt6779-mfgcfg", "syscon"
+       - "mediatek,mt8167-mfgcfg", "syscon"
        - "mediatek,mt8183-mfgcfg", "syscon"
 - #clock-cells: Must be 1
 
index 9b0394c..5ce7578 100644 (file)
@@ -15,6 +15,7 @@ Required Properties:
        - "mediatek,mt7623-topckgen", "mediatek,mt2701-topckgen"
        - "mediatek,mt7629-topckgen"
        - "mediatek,mt8135-topckgen"
+       - "mediatek,mt8167-topckgen", "syscon"
        - "mediatek,mt8173-topckgen"
        - "mediatek,mt8183-topckgen", "syscon"
        - "mediatek,mt8516-topckgen"
index 7894558..9819516 100644 (file)
@@ -11,6 +11,7 @@ Required Properties:
        - "mediatek,mt6779-vdecsys", "syscon"
        - "mediatek,mt6797-vdecsys", "syscon"
        - "mediatek,mt7623-vdecsys", "mediatek,mt2701-vdecsys", "syscon"
+       - "mediatek,mt8167-vdecsys", "syscon"
        - "mediatek,mt8173-vdecsys", "syscon"
        - "mediatek,mt8183-vdecsys", "syscon"
 - #clock-cells: Must be 1
index 4d38212..3b45344 100644 (file)
@@ -36,6 +36,8 @@ properties:
       - allwinner,sun9i-a80-ccu
       - allwinner,sun50i-a64-ccu
       - allwinner,sun50i-a64-r-ccu
+      - allwinner,sun50i-a100-ccu
+      - allwinner,sun50i-a100-r-ccu
       - allwinner,sun50i-h5-ccu
       - allwinner,sun50i-h6-ccu
       - allwinner,sun50i-h6-r-ccu
@@ -78,6 +80,7 @@ if:
         - allwinner,sun8i-a83t-r-ccu
         - allwinner,sun8i-h3-r-ccu
         - allwinner,sun50i-a64-r-ccu
+        - allwinner,sun50i-a100-r-ccu
         - allwinner,sun50i-h6-r-ccu
 
 then:
@@ -94,7 +97,9 @@ else:
   if:
     properties:
       compatible:
-        const: allwinner,sun50i-h6-ccu
+        enum:
+          - allwinner,sun50i-a100-ccu
+          - allwinner,sun50i-h6-ccu
 
   then:
     properties:
index e13aee8..9b414fb 100644 (file)
@@ -47,6 +47,7 @@ properties:
       - renesas,r8a77980-cpg-mssr # R-Car V3H
       - renesas,r8a77990-cpg-mssr # R-Car E3
       - renesas,r8a77995-cpg-mssr # R-Car D3
+      - renesas,r8a779a0-cpg-mssr # R-Car V3U
 
   reg:
     maxItems: 1
index 4026fac..c715d46 100644 (file)
@@ -49,7 +49,7 @@ source "drivers/clk/versatile/Kconfig"
 
 config CLK_HSDK
        bool "PLL Driver for HSDK platform"
-       depends on OF || COMPILE_TEST
+       depends on ARC_SOC_HSDK || COMPILE_TEST
        depends on HAS_IOMEM
        help
          This driver supports the HSDK core, system, ddr, tunnel and hdmi PLLs
@@ -373,6 +373,7 @@ source "drivers/clk/meson/Kconfig"
 source "drivers/clk/mvebu/Kconfig"
 source "drivers/clk/qcom/Kconfig"
 source "drivers/clk/renesas/Kconfig"
+source "drivers/clk/rockchip/Kconfig"
 source "drivers/clk/samsung/Kconfig"
 source "drivers/clk/sifive/Kconfig"
 source "drivers/clk/sprd/Kconfig"
index c88ee20..cb4a406 100644 (file)
@@ -46,13 +46,6 @@ static const struct {
        { .n = "pck1",  .p = "prog1",    .id = 9 },
 };
 
-static const struct clk_pcr_layout at91sam9g45_pcr_layout = {
-       .offset = 0x10c,
-       .cmd = BIT(12),
-       .pid_mask = GENMASK(5, 0),
-       .div_mask = GENMASK(17, 16),
-};
-
 struct pck {
        char *n;
        u8 id;
index 5c83e89..cfae2f5 100644 (file)
@@ -437,12 +437,17 @@ static int clk_sam9x5_main_set_parent(struct clk_hw *hw, u8 index)
                return -EINVAL;
 
        regmap_read(regmap, AT91_CKGR_MOR, &tmp);
-       tmp &= ~MOR_KEY_MASK;
 
        if (index && !(tmp & AT91_PMC_MOSCSEL))
-               regmap_write(regmap, AT91_CKGR_MOR, tmp | AT91_PMC_MOSCSEL);
+               tmp = AT91_PMC_MOSCSEL;
        else if (!index && (tmp & AT91_PMC_MOSCSEL))
-               regmap_write(regmap, AT91_CKGR_MOR, tmp & ~AT91_PMC_MOSCSEL);
+               tmp = 0;
+       else
+               return 0;
+
+       regmap_update_bits(regmap, AT91_CKGR_MOR,
+                          AT91_PMC_MOSCSEL | MOR_KEY_MASK,
+                          tmp | AT91_PMC_KEY);
 
        while (!clk_sam9x5_main_ready(regmap))
                cpu_relax();
index 7867eaf..7a27ba8 100644 (file)
@@ -112,8 +112,8 @@ at91_clk_register_peripheral(struct regmap *regmap, const char *name,
 
        init.name = name;
        init.ops = &peripheral_ops;
-       init.parent_names = (parent_name ? &parent_name : NULL);
-       init.num_parents = (parent_name ? 1 : 0);
+       init.parent_names = &parent_name;
+       init.num_parents = 1;
        init.flags = 0;
 
        periph->id = id;
index b473298..78f458a 100644 (file)
@@ -331,7 +331,7 @@ static long sam9x60_div_pll_compute_div(struct sam9x60_pll_core *core,
        struct clk_hw *parent = clk_hw_get_parent(&core->hw);
        unsigned long tmp_rate, tmp_parent_rate, tmp_diff;
        long best_diff = -1, best_rate = -EINVAL;
-       u32 divid, best_div;
+       u32 divid;
 
        if (!rate)
                return 0;
@@ -352,7 +352,6 @@ static long sam9x60_div_pll_compute_div(struct sam9x60_pll_core *core,
                        *parent_rate = tmp_parent_rate;
                        best_rate = tmp_rate;
                        best_diff = tmp_diff;
-                       best_div = divid;
                }
 
                if (!best_diff)
index ab6318c..3c4c956 100644 (file)
@@ -279,7 +279,7 @@ static void __init sam9x60_pmc_setup(struct device_node *np)
        parent_names[3] = "masterck";
        parent_names[4] = "pllack_divck";
        parent_names[5] = "upllck_divck";
-       for (i = 0; i < 8; i++) {
+       for (i = 0; i < 2; i++) {
                char name[6];
 
                snprintf(name, sizeof(name), "prog%d", i);
index 1eec8c0..2445d4b 100644 (file)
@@ -51,11 +51,13 @@ struct ccu_pll_info {
 };
 
 /*
- * Mark as critical all PLLs except Ethernet one. CPU and DDR PLLs are sources
- * of CPU cores and DDR controller reference clocks, due to which they
- * obviously shouldn't be ever gated. SATA and PCIe PLLs are the parents of
- * APB-bus and DDR controller AXI-bus clocks. If they are gated the system will
- * be unusable.
+ * Alas we have to mark all PLLs as critical. CPU and DDR PLLs are sources of
+ * CPU cores and DDR controller reference clocks, due to which they obviously
+ * shouldn't be ever gated. SATA and PCIe PLLs are the parents of APB-bus and
+ * DDR controller AXI-bus clocks. If they are gated the system will be
+ * unusable. Moreover disabling SATA and Ethernet PLLs causes automatic reset
+ * of the corresponding subsystems. So until we aren't ready to re-initialize
+ * all the devices consuming those PLLs, they will be marked as critical too.
  */
 static const struct ccu_pll_info pll_info[] = {
        CCU_PLL_INFO(CCU_CPU_PLL, "cpu_pll", "ref_clk", CCU_CPU_PLL_BASE,
@@ -67,7 +69,7 @@ static const struct ccu_pll_info pll_info[] = {
        CCU_PLL_INFO(CCU_PCIE_PLL, "pcie_pll", "ref_clk", CCU_PCIE_PLL_BASE,
                     CLK_IS_CRITICAL),
        CCU_PLL_INFO(CCU_ETH_PLL, "eth_pll", "ref_clk", CCU_ETH_PLL_BASE,
-                    CLK_SET_RATE_GATE)
+                    CLK_IS_CRITICAL | CLK_SET_RATE_GATE)
 };
 
 struct ccu_pll_data {
index 3439bc6..1ac803e 100644 (file)
@@ -1338,8 +1338,10 @@ static struct clk_hw *bcm2835_register_pll(struct bcm2835_cprman *cprman,
        pll->hw.init = &init;
 
        ret = devm_clk_hw_register(cprman->dev, &pll->hw);
-       if (ret)
+       if (ret) {
+               kfree(pll);
                return NULL;
+       }
        return &pll->hw;
 }
 
index 5cc8295..f89b9cf 100644 (file)
@@ -271,6 +271,7 @@ static int raspberrypi_discover_clocks(struct raspberrypi_clk *rpi,
                case RPI_FIRMWARE_CORE_CLK_ID:
                case RPI_FIRMWARE_M2MC_CLK_ID:
                case RPI_FIRMWARE_V3D_CLK_ID:
+               case RPI_FIRMWARE_PIXEL_BVB_CLK_ID:
                        hw = raspberrypi_clk_register(rpi, clks->parent,
                                                      clks->id);
                        if (IS_ERR(hw))
index 96f3517..14d803e 100644 (file)
 
 #define AXI_CLKGEN_V2_DRP_STATUS_BUSY  BIT(16)
 
+#define MMCM_REG_CLKOUT5_2     0x07
 #define MMCM_REG_CLKOUT0_1     0x08
 #define MMCM_REG_CLKOUT0_2     0x09
+#define MMCM_REG_CLKOUT6_2     0x13
 #define MMCM_REG_CLK_FB1       0x14
 #define MMCM_REG_CLK_FB2       0x15
 #define MMCM_REG_CLK_DIV       0x16
 #define MMCM_REG_LOCK1         0x18
 #define MMCM_REG_LOCK2         0x19
 #define MMCM_REG_LOCK3         0x1a
+#define MMCM_REG_POWER         0x28
 #define MMCM_REG_FILTER1       0x4e
 #define MMCM_REG_FILTER2       0x4f
 
 #define MMCM_CLKOUT_NOCOUNT    BIT(6)
 
+#define MMCM_CLK_DIV_DIVIDE    BIT(11)
 #define MMCM_CLK_DIV_NOCOUNT   BIT(12)
 
 struct axi_clkgen {
@@ -107,6 +111,8 @@ static void axi_clkgen_calc_params(unsigned long fin, unsigned long fout,
        unsigned long d, d_min, d_max, _d_min, _d_max;
        unsigned long m, m_min, m_max;
        unsigned long f, dout, best_f, fvco;
+       unsigned long fract_shift = 0;
+       unsigned long fvco_min_fract, fvco_max_fract;
 
        fin /= 1000;
        fout /= 1000;
@@ -119,42 +125,89 @@ static void axi_clkgen_calc_params(unsigned long fin, unsigned long fout,
        d_min = max_t(unsigned long, DIV_ROUND_UP(fin, fpfd_max), 1);
        d_max = min_t(unsigned long, fin / fpfd_min, 80);
 
-       m_min = max_t(unsigned long, DIV_ROUND_UP(fvco_min, fin) * d_min, 1);
-       m_max = min_t(unsigned long, fvco_max * d_max / fin, 64);
+again:
+       fvco_min_fract = fvco_min << fract_shift;
+       fvco_max_fract = fvco_max << fract_shift;
+
+       m_min = max_t(unsigned long, DIV_ROUND_UP(fvco_min_fract, fin) * d_min, 1);
+       m_max = min_t(unsigned long, fvco_max_fract * d_max / fin, 64 << fract_shift);
 
        for (m = m_min; m <= m_max; m++) {
-               _d_min = max(d_min, DIV_ROUND_UP(fin * m, fvco_max));
-               _d_max = min(d_max, fin * m / fvco_min);
+               _d_min = max(d_min, DIV_ROUND_UP(fin * m, fvco_max_fract));
+               _d_max = min(d_max, fin * m / fvco_min_fract);
 
                for (d = _d_min; d <= _d_max; d++) {
                        fvco = fin * m / d;
 
                        dout = DIV_ROUND_CLOSEST(fvco, fout);
-                       dout = clamp_t(unsigned long, dout, 1, 128);
+                       dout = clamp_t(unsigned long, dout, 1, 128 << fract_shift);
                        f = fvco / dout;
                        if (abs(f - fout) < abs(best_f - fout)) {
                                best_f = f;
                                *best_d = d;
-                               *best_m = m;
-                               *best_dout = dout;
+                               *best_m = m << (3 - fract_shift);
+                               *best_dout = dout << (3 - fract_shift);
                                if (best_f == fout)
                                        return;
                        }
                }
        }
+
+       /* Lets see if we find a better setting in fractional mode */
+       if (fract_shift == 0) {
+               fract_shift = 3;
+               goto again;
+       }
 }
 
-static void axi_clkgen_calc_clk_params(unsigned int divider, unsigned int *low,
-       unsigned int *high, unsigned int *edge, unsigned int *nocount)
+struct axi_clkgen_div_params {
+       unsigned int low;
+       unsigned int high;
+       unsigned int edge;
+       unsigned int nocount;
+       unsigned int frac_en;
+       unsigned int frac;
+       unsigned int frac_wf_f;
+       unsigned int frac_wf_r;
+       unsigned int frac_phase;
+};
+
+static void axi_clkgen_calc_clk_params(unsigned int divider,
+       unsigned int frac_divider, struct axi_clkgen_div_params *params)
 {
-       if (divider == 1)
-               *nocount = 1;
-       else
-               *nocount = 0;
 
-       *high = divider / 2;
-       *edge = divider % 2;
-       *low = divider - *high;
+       memset(params, 0x0, sizeof(*params));
+
+       if (divider == 1) {
+               params->nocount = 1;
+               return;
+       }
+
+       if (frac_divider == 0) {
+               params->high = divider / 2;
+               params->edge = divider % 2;
+               params->low = divider - params->high;
+       } else {
+               params->frac_en = 1;
+               params->frac = frac_divider;
+
+               params->high = divider / 2;
+               params->edge = divider % 2;
+               params->low = params->high;
+
+               if (params->edge == 0) {
+                       params->high--;
+                       params->frac_wf_r = 1;
+               }
+
+               if (params->edge == 0 || frac_divider == 1)
+                       params->low--;
+               if (((params->edge == 0) ^ (frac_divider == 1)) ||
+                       (divider == 2 && frac_divider == 1))
+                       params->frac_wf_f = 1;
+
+               params->frac_phase = params->edge * 4 + frac_divider / 2;
+       }
 }
 
 static void axi_clkgen_write(struct axi_clkgen *axi_clkgen,
@@ -246,15 +299,29 @@ static struct axi_clkgen *clk_hw_to_axi_clkgen(struct clk_hw *clk_hw)
        return container_of(clk_hw, struct axi_clkgen, clk_hw);
 }
 
+static void axi_clkgen_set_div(struct axi_clkgen *axi_clkgen,
+       unsigned int reg1, unsigned int reg2, unsigned int reg3,
+       struct axi_clkgen_div_params *params)
+{
+       axi_clkgen_mmcm_write(axi_clkgen, reg1,
+               (params->high << 6) | params->low, 0xefff);
+       axi_clkgen_mmcm_write(axi_clkgen, reg2,
+               (params->frac << 12) | (params->frac_en << 11) |
+               (params->frac_wf_r << 10) | (params->edge << 7) |
+               (params->nocount << 6), 0x7fff);
+       if (reg3 != 0) {
+               axi_clkgen_mmcm_write(axi_clkgen, reg3,
+                       (params->frac_phase << 11) | (params->frac_wf_f << 10), 0x3c00);
+       }
+}
+
 static int axi_clkgen_set_rate(struct clk_hw *clk_hw,
        unsigned long rate, unsigned long parent_rate)
 {
        struct axi_clkgen *axi_clkgen = clk_hw_to_axi_clkgen(clk_hw);
        unsigned int d, m, dout;
-       unsigned int nocount;
-       unsigned int high;
-       unsigned int edge;
-       unsigned int low;
+       struct axi_clkgen_div_params params;
+       uint32_t power = 0;
        uint32_t filter;
        uint32_t lock;
 
@@ -266,24 +333,26 @@ static int axi_clkgen_set_rate(struct clk_hw *clk_hw,
        if (d == 0 || dout == 0 || m == 0)
                return -EINVAL;
 
+       if ((dout & 0x7) != 0 || (m & 0x7) != 0)
+               power |= 0x9800;
+
+       axi_clkgen_mmcm_write(axi_clkgen, MMCM_REG_POWER, power, 0x9800);
+
        filter = axi_clkgen_lookup_filter(m - 1);
        lock = axi_clkgen_lookup_lock(m - 1);
 
-       axi_clkgen_calc_clk_params(dout, &low, &high, &edge, &nocount);
-       axi_clkgen_mmcm_write(axi_clkgen, MMCM_REG_CLKOUT0_1,
-               (high << 6) | low, 0xefff);
-       axi_clkgen_mmcm_write(axi_clkgen, MMCM_REG_CLKOUT0_2,
-               (edge << 7) | (nocount << 6), 0x03ff);
+       axi_clkgen_calc_clk_params(dout >> 3, dout & 0x7, &params);
+       axi_clkgen_set_div(axi_clkgen,  MMCM_REG_CLKOUT0_1, MMCM_REG_CLKOUT0_2,
+               MMCM_REG_CLKOUT5_2, &params);
 
-       axi_clkgen_calc_clk_params(d, &low, &high, &edge, &nocount);
+       axi_clkgen_calc_clk_params(d, 0, &params);
        axi_clkgen_mmcm_write(axi_clkgen, MMCM_REG_CLK_DIV,
-               (edge << 13) | (nocount << 12) | (high << 6) | low, 0x3fff);
+               (params.edge << 13) | (params.nocount << 12) |
+               (params.high << 6) | params.low, 0x3fff);
 
-       axi_clkgen_calc_clk_params(m, &low, &high, &edge, &nocount);
-       axi_clkgen_mmcm_write(axi_clkgen, MMCM_REG_CLK_FB1,
-               (high << 6) | low, 0xefff);
-       axi_clkgen_mmcm_write(axi_clkgen, MMCM_REG_CLK_FB2,
-               (edge << 7) | (nocount << 6), 0x03ff);
+       axi_clkgen_calc_clk_params(m >> 3, m & 0x7, &params);
+       axi_clkgen_set_div(axi_clkgen,  MMCM_REG_CLK_FB1, MMCM_REG_CLK_FB2,
+               MMCM_REG_CLKOUT6_2, &params);
 
        axi_clkgen_mmcm_write(axi_clkgen, MMCM_REG_LOCK1, lock & 0x3ff, 0x3ff);
        axi_clkgen_mmcm_write(axi_clkgen, MMCM_REG_LOCK2,
@@ -313,35 +382,51 @@ static long axi_clkgen_round_rate(struct clk_hw *hw, unsigned long rate,
        return min_t(unsigned long long, tmp, LONG_MAX);
 }
 
+static unsigned int axi_clkgen_get_div(struct axi_clkgen *axi_clkgen,
+       unsigned int reg1, unsigned int reg2)
+{
+       unsigned int val1, val2;
+       unsigned int div;
+
+       axi_clkgen_mmcm_read(axi_clkgen, reg2, &val2);
+       if (val2 & MMCM_CLKOUT_NOCOUNT)
+               return 8;
+
+       axi_clkgen_mmcm_read(axi_clkgen, reg1, &val1);
+
+       div = (val1 & 0x3f) + ((val1 >> 6) & 0x3f);
+       div <<= 3;
+
+       if (val2 & MMCM_CLK_DIV_DIVIDE) {
+               if ((val2 & BIT(7)) && (val2 & 0x7000) != 0x1000)
+                       div += 8;
+               else
+                       div += 16;
+
+               div += (val2 >> 12) & 0x7;
+       }
+
+       return div;
+}
+
 static unsigned long axi_clkgen_recalc_rate(struct clk_hw *clk_hw,
        unsigned long parent_rate)
 {
        struct axi_clkgen *axi_clkgen = clk_hw_to_axi_clkgen(clk_hw);
        unsigned int d, m, dout;
-       unsigned int reg;
        unsigned long long tmp;
+       unsigned int val;
 
-       axi_clkgen_mmcm_read(axi_clkgen, MMCM_REG_CLKOUT0_2, &reg);
-       if (reg & MMCM_CLKOUT_NOCOUNT) {
-               dout = 1;
-       } else {
-               axi_clkgen_mmcm_read(axi_clkgen, MMCM_REG_CLKOUT0_1, &reg);
-               dout = (reg & 0x3f) + ((reg >> 6) & 0x3f);
-       }
+       dout = axi_clkgen_get_div(axi_clkgen, MMCM_REG_CLKOUT0_1,
+               MMCM_REG_CLKOUT0_2);
+       m = axi_clkgen_get_div(axi_clkgen, MMCM_REG_CLK_FB1,
+               MMCM_REG_CLK_FB2);
 
-       axi_clkgen_mmcm_read(axi_clkgen, MMCM_REG_CLK_DIV, &reg);
-       if (reg & MMCM_CLK_DIV_NOCOUNT)
+       axi_clkgen_mmcm_read(axi_clkgen, MMCM_REG_CLK_DIV, &val);
+       if (val & MMCM_CLK_DIV_NOCOUNT)
                d = 1;
        else
-               d = (reg & 0x3f) + ((reg >> 6) & 0x3f);
-
-       axi_clkgen_mmcm_read(axi_clkgen, MMCM_REG_CLK_FB2, &reg);
-       if (reg & MMCM_CLKOUT_NOCOUNT) {
-               m = 1;
-       } else {
-               axi_clkgen_mmcm_read(axi_clkgen, MMCM_REG_CLK_FB1, &reg);
-               m = (reg & 0x3f) + ((reg >> 6) & 0x3f);
-       }
+               d = (val & 0x3f) + ((val >> 6) & 0x3f);
 
        if (d == 0 || dout == 0)
                return 0;
index 7376f57..2ddb54f 100644 (file)
@@ -328,6 +328,7 @@ struct clk_hw *clk_hw_register_composite(struct device *dev, const char *name,
                                           rate_hw, rate_ops, gate_hw,
                                           gate_ops, flags);
 }
+EXPORT_SYMBOL_GPL(clk_hw_register_composite);
 
 struct clk_hw *clk_hw_register_composite_pdata(struct device *dev,
                        const char *name,
index 8b343e5..910e6e7 100644 (file)
@@ -206,6 +206,7 @@ static struct clk_hw *_of_fixed_factor_clk_setup(struct device_node *node)
 
 /**
  * of_fixed_factor_clk_setup() - Setup function for simple fixed factor clock
+ * @node:      device node for the clock
  */
 void __init of_fixed_factor_clk_setup(struct device_node *node)
 {
index 77499a2..4550163 100644 (file)
@@ -168,6 +168,7 @@ static struct clk_hw *_of_fixed_clk_setup(struct device_node *node)
 
 /**
  * of_fixed_clk_setup() - Setup function for simple fixed rate clock
+ * @node:      device node for the clock
  */
 void __init of_fixed_clk_setup(struct device_node *node)
 {
index 5942e98..46101c6 100644 (file)
@@ -31,7 +31,7 @@
 #define CGA_PLL4       4       /* only on clockgen-1.0, which lacks CGB */
 #define CGB_PLL1       4
 #define CGB_PLL2       5
-#define MAX_PLL_DIV    16
+#define MAX_PLL_DIV    32
 
 struct clockgen_pll_div {
        struct clk *clk;
index 2ce370c..aa21371 100644 (file)
@@ -267,18 +267,7 @@ static struct platform_driver s2mps11_clk_driver = {
        .remove = s2mps11_clk_remove,
        .id_table = s2mps11_clk_id,
 };
-
-static int __init s2mps11_clk_init(void)
-{
-       return platform_driver_register(&s2mps11_clk_driver);
-}
-subsys_initcall(s2mps11_clk_init);
-
-static void __exit s2mps11_clk_cleanup(void)
-{
-       platform_driver_unregister(&s2mps11_clk_driver);
-}
-module_exit(s2mps11_clk_cleanup);
+module_platform_driver(s2mps11_clk_driver);
 
 MODULE_DESCRIPTION("S2MPS11 Clock Driver");
 MODULE_AUTHOR("Yadwinder Singh Brar <yadi.brar@samsung.com>");
index 3d7acab..e0446e6 100644 (file)
@@ -883,11 +883,9 @@ static int si5341_output_set_parent(struct clk_hw *hw, u8 index)
 static u8 si5341_output_get_parent(struct clk_hw *hw)
 {
        struct clk_si5341_output *output = to_clk_si5341_output(hw);
-       int err;
        u32 val;
 
-       err = regmap_read(output->data->regmap,
-                       SI5341_OUT_MUX_SEL(output), &val);
+       regmap_read(output->data->regmap, SI5341_OUT_MUX_SEL(output), &val);
 
        return val & 0x7;
 }
index bdc5236..77d1827 100644 (file)
@@ -571,6 +571,7 @@ static const struct clk_ops da8xx_usb1_clk48_ops = {
 
 /**
  * da8xx_cfgchip_register_usb1_clk48 - Register a new USB 1.1 PHY clock
+ * @dev: The device
  * @regmap: The CFGCHIP regmap
  */
 static struct da8xx_usb1_clk48 *
index db0253f..3b393cb 100644 (file)
 # SPDX-License-Identifier: GPL-2.0
 # common clock support for NXP i.MX SoC family.
 config MXC_CLK
-       bool
-       def_bool ARCH_MXC
+       tristate "IMX clock"
+       depends on ARCH_MXC || COMPILE_TEST
 
 config MXC_CLK_SCU
-       bool
-       depends on IMX_SCU
+       tristate "IMX SCU clock"
+       depends on ARCH_MXC || COMPILE_TEST
+       depends on IMX_SCU && HAVE_ARM_SMCCC
+
+config CLK_IMX1
+       def_bool SOC_IMX1
+       select MXC_CLK
+
+config CLK_IMX25
+       def_bool SOC_IMX25
+       select MXC_CLK
+
+config CLK_IMX27
+       def_bool SOC_IMX27
+       select MXC_CLK
+
+config CLK_IMX31
+       def_bool SOC_IMX31
+       select MXC_CLK
+
+config CLK_IMX35
+       def_bool SOC_IMX35
+       select MXC_CLK
+
+config CLK_IMX5
+       def_bool SOC_IMX5
+       select MXC_CLK
+
+config CLK_IMX6Q
+       def_bool SOC_IMX6Q
+       select MXC_CLK
+
+config CLK_IMX6SL
+       def_bool SOC_IMX6SL
+       select MXC_CLK
+
+config CLK_IMX6SLL
+       def_bool SOC_IMX6SLL
+       select MXC_CLK
+
+config CLK_IMX6SX
+       def_bool SOC_IMX6SX
+       select MXC_CLK
+
+config CLK_IMX6UL
+       def_bool SOC_IMX6UL
+       select MXC_CLK
+
+config CLK_IMX7D
+       def_bool SOC_IMX7D
+       select MXC_CLK
+
+config CLK_IMX7ULP
+       def_bool SOC_IMX7ULP
+       select MXC_CLK
+
+config CLK_VF610
+       def_bool SOC_VF610
+       select MXC_CLK
 
 config CLK_IMX8MM
-       bool "IMX8MM CCM Clock Driver"
-       depends on ARCH_MXC
+       tristate "IMX8MM CCM Clock Driver"
+       depends on ARCH_MXC || COMPILE_TEST
+       select MXC_CLK
        help
            Build the driver for i.MX8MM CCM Clock Driver
 
 config CLK_IMX8MN
-       bool "IMX8MN CCM Clock Driver"
-       depends on ARCH_MXC
+       tristate "IMX8MN CCM Clock Driver"
+       depends on ARCH_MXC || COMPILE_TEST
+       select MXC_CLK
        help
            Build the driver for i.MX8MN CCM Clock Driver
 
 config CLK_IMX8MP
-       bool "IMX8MP CCM Clock Driver"
-       depends on ARCH_MXC
+       tristate "IMX8MP CCM Clock Driver"
+       depends on ARCH_MXC || COMPILE_TEST
+       select MXC_CLK
        help
            Build the driver for i.MX8MP CCM Clock Driver
 
 config CLK_IMX8MQ
-       bool "IMX8MQ CCM Clock Driver"
-       depends on ARCH_MXC
+       tristate "IMX8MQ CCM Clock Driver"
+       depends on ARCH_MXC || COMPILE_TEST
+       select MXC_CLK
        help
            Build the driver for i.MX8MQ CCM Clock Driver
 
 config CLK_IMX8QXP
-       bool "IMX8QXP SCU Clock"
-       depends on ARCH_MXC && IMX_SCU && ARM64
+       tristate "IMX8QXP SCU Clock"
+       depends on (ARCH_MXC && ARM64) || COMPILE_TEST
+       depends on IMX_SCU && HAVE_ARM_SMCCC
        select MXC_CLK_SCU
        help
          Build the driver for IMX8QXP SCU based clocks.
index 928f874..dd6a737 100644 (file)
@@ -1,48 +1,46 @@
 # SPDX-License-Identifier: GPL-2.0
 
-obj-$(CONFIG_MXC_CLK) += \
-       clk.o \
-       clk-busy.o \
-       clk-composite-8m.o \
-       clk-cpu.o \
-       clk-composite-7ulp.o \
-       clk-divider-gate.o \
-       clk-fixup-div.o \
-       clk-fixup-mux.o \
-       clk-frac-pll.o \
-       clk-gate-exclusive.o \
-       clk-gate2.o \
-       clk-pfd.o \
-       clk-pfdv2.o \
-       clk-pllv1.o \
-       clk-pllv2.o \
-       clk-pllv3.o \
-       clk-pllv4.o \
-       clk-sscg-pll.o \
-       clk-pll14xx.o
-
-obj-$(CONFIG_MXC_CLK_SCU) += \
-       clk-scu.o \
-       clk-lpcg-scu.o
+mxc-clk-objs += clk.o
+mxc-clk-objs += clk-busy.o
+mxc-clk-objs += clk-composite-7ulp.o
+mxc-clk-objs += clk-composite-8m.o
+mxc-clk-objs += clk-cpu.o
+mxc-clk-objs += clk-divider-gate.o
+mxc-clk-objs += clk-fixup-div.o
+mxc-clk-objs += clk-fixup-mux.o
+mxc-clk-objs += clk-frac-pll.o
+mxc-clk-objs += clk-gate2.o
+mxc-clk-objs += clk-gate-exclusive.o
+mxc-clk-objs += clk-pfd.o
+mxc-clk-objs += clk-pfdv2.o
+mxc-clk-objs += clk-pllv1.o
+mxc-clk-objs += clk-pllv2.o
+mxc-clk-objs += clk-pllv3.o
+mxc-clk-objs += clk-pllv4.o
+mxc-clk-objs += clk-pll14xx.o
+mxc-clk-objs += clk-sscg-pll.o
+obj-$(CONFIG_MXC_CLK) += mxc-clk.o
 
 obj-$(CONFIG_CLK_IMX8MM) += clk-imx8mm.o
 obj-$(CONFIG_CLK_IMX8MN) += clk-imx8mn.o
 obj-$(CONFIG_CLK_IMX8MP) += clk-imx8mp.o
 obj-$(CONFIG_CLK_IMX8MQ) += clk-imx8mq.o
-obj-$(CONFIG_CLK_IMX8QXP) += clk-imx8qxp.o clk-imx8qxp-lpcg.o
 
-obj-$(CONFIG_SOC_IMX1)   += clk-imx1.o
-obj-$(CONFIG_SOC_IMX21)  += clk-imx21.o
-obj-$(CONFIG_SOC_IMX25)  += clk-imx25.o
-obj-$(CONFIG_SOC_IMX27)  += clk-imx27.o
-obj-$(CONFIG_SOC_IMX31)  += clk-imx31.o
-obj-$(CONFIG_SOC_IMX35)  += clk-imx35.o
-obj-$(CONFIG_SOC_IMX5)   += clk-imx5.o
-obj-$(CONFIG_SOC_IMX6Q)  += clk-imx6q.o
-obj-$(CONFIG_SOC_IMX6SL) += clk-imx6sl.o
-obj-$(CONFIG_SOC_IMX6SLL) += clk-imx6sll.o
-obj-$(CONFIG_SOC_IMX6SX) += clk-imx6sx.o
-obj-$(CONFIG_SOC_IMX6UL) += clk-imx6ul.o
-obj-$(CONFIG_SOC_IMX7D)  += clk-imx7d.o
-obj-$(CONFIG_SOC_IMX7ULP) += clk-imx7ulp.o
-obj-$(CONFIG_SOC_VF610)  += clk-vf610.o
+obj-$(CONFIG_MXC_CLK_SCU) += clk-imx-scu.o clk-imx-lpcg-scu.o
+clk-imx-scu-$(CONFIG_CLK_IMX8QXP) += clk-scu.o clk-imx8qxp.o
+clk-imx-lpcg-scu-$(CONFIG_CLK_IMX8QXP) += clk-lpcg-scu.o clk-imx8qxp-lpcg.o
+
+obj-$(CONFIG_CLK_IMX1)   += clk-imx1.o
+obj-$(CONFIG_CLK_IMX25)  += clk-imx25.o
+obj-$(CONFIG_CLK_IMX27)  += clk-imx27.o
+obj-$(CONFIG_CLK_IMX31)  += clk-imx31.o
+obj-$(CONFIG_CLK_IMX35)  += clk-imx35.o
+obj-$(CONFIG_CLK_IMX5)   += clk-imx5.o
+obj-$(CONFIG_CLK_IMX6Q)  += clk-imx6q.o
+obj-$(CONFIG_CLK_IMX6SL) += clk-imx6sl.o
+obj-$(CONFIG_CLK_IMX6SLL) += clk-imx6sll.o
+obj-$(CONFIG_CLK_IMX6SX) += clk-imx6sx.o
+obj-$(CONFIG_CLK_IMX6UL) += clk-imx6ul.o
+obj-$(CONFIG_CLK_IMX7D)  += clk-imx7d.o
+obj-$(CONFIG_CLK_IMX7ULP) += clk-imx7ulp.o
+obj-$(CONFIG_CLK_VF610)  += clk-vf610.o
index 25c863d..6f17311 100644 (file)
@@ -4,6 +4,7 @@
  * Copyright 2012 Linaro Ltd.
  */
 
+#include <linux/bits.h>
 #include <linux/clk.h>
 #include <linux/clk-provider.h>
 #include <linux/io.h>
index b9efcc8..7c4f31b 100644 (file)
@@ -5,6 +5,7 @@
  *
  */
 
+#include <linux/bits.h>
 #include <linux/clk-provider.h>
 #include <linux/err.h>
 #include <linux/slab.h>
index d2b5af8..2c309e3 100644 (file)
@@ -5,6 +5,7 @@
 
 #include <linux/clk-provider.h>
 #include <linux/errno.h>
+#include <linux/export.h>
 #include <linux/io.h>
 #include <linux/slab.h>
 
@@ -215,6 +216,7 @@ struct clk_hw *imx8m_clk_hw_composite_flags(const char *name,
                div->width = PCG_PREDIV_WIDTH;
                divider_ops = &imx8m_clk_composite_divider_ops;
                mux_ops = &clk_mux_ops;
+               flags |= CLK_SET_PARENT_GATE;
        }
 
        div->lock = &imx_ccm_lock;
@@ -243,3 +245,4 @@ fail:
        kfree(mux);
        return ERR_CAST(hw);
 }
+EXPORT_SYMBOL_GPL(imx8m_clk_hw_composite_flags);
index cb182be..cb6ca4c 100644 (file)
@@ -5,6 +5,7 @@
 
 #include <linux/clk.h>
 #include <linux/clk-provider.h>
+#include <linux/export.h>
 #include <linux/slab.h>
 #include "clk.h"
 
@@ -104,3 +105,4 @@ struct clk_hw *imx_clk_hw_cpu(const char *name, const char *parent_name,
 
        return hw;
 }
+EXPORT_SYMBOL_GPL(imx_clk_hw_cpu);
index 58a6763..c824015 100644 (file)
@@ -3,6 +3,7 @@
  * Copyright (C) 2013 Freescale Semiconductor, Inc.
  */
 
+#include <linux/bits.h>
 #include <linux/clk-provider.h>
 #include <linux/err.h>
 #include <linux/io.h>
index 101e0a3..c703056 100644 (file)
@@ -10,6 +10,7 @@
 
 #include <linux/clk-provider.h>
 #include <linux/err.h>
+#include <linux/export.h>
 #include <linux/io.h>
 #include <linux/iopoll.h>
 #include <linux/slab.h>
@@ -233,3 +234,4 @@ struct clk_hw *imx_clk_hw_frac_pll(const char *name,
 
        return hw;
 }
+EXPORT_SYMBOL_GPL(imx_clk_hw_frac_pll);
index b87ab3c..7eed708 100644 (file)
@@ -7,6 +7,7 @@
  */
 
 #include <linux/clk-provider.h>
+#include <linux/export.h>
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/io.h>
@@ -15,7 +16,7 @@
 #include "clk.h"
 
 /**
- * DOC: basic gatable clock which can gate and ungate it's ouput
+ * DOC: basic gateable clock which can gate and ungate its output
  *
  * Traits of this clock:
  * prepare - clk_(un)prepare only ensures parent is (un)prepared
@@ -177,3 +178,4 @@ struct clk_hw *clk_hw_register_gate2(struct device *dev, const char *name,
 
        return hw;
 }
+EXPORT_SYMBOL_GPL(clk_hw_register_gate2);
diff --git a/drivers/clk/imx/clk-imx21.c b/drivers/clk/imx/clk-imx21.c
deleted file mode 100644 (file)
index 077b4a7..0000000
+++ /dev/null
@@ -1,171 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
- * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
- * Copyright 2008 Martin Fuzzey, mfuzzey@gmail.com
- */
-
-#include <linux/clk-provider.h>
-#include <linux/clkdev.h>
-#include <linux/io.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <dt-bindings/clock/imx21-clock.h>
-#include <soc/imx/timer.h>
-#include <asm/irq.h>
-
-#include "clk.h"
-
-#define MX21_CCM_BASE_ADDR     0x10027000
-#define MX21_GPT1_BASE_ADDR    0x10003000
-#define MX21_INT_GPT1          (NR_IRQS_LEGACY + 26)
-
-static void __iomem *ccm __initdata;
-
-/* Register offsets */
-#define CCM_CSCR       (ccm + 0x00)
-#define CCM_MPCTL0     (ccm + 0x04)
-#define CCM_SPCTL0     (ccm + 0x0c)
-#define CCM_PCDR0      (ccm + 0x18)
-#define CCM_PCDR1      (ccm + 0x1c)
-#define CCM_PCCR0      (ccm + 0x20)
-#define CCM_PCCR1      (ccm + 0x24)
-
-static const char *mpll_osc_sel_clks[] = { "ckih_gate", "ckih_div1p5", };
-static const char *mpll_sel_clks[] = { "fpm_gate", "mpll_osc_sel", };
-static const char *spll_sel_clks[] = { "fpm_gate", "mpll_osc_sel", };
-static const char *ssi_sel_clks[] = { "spll_gate", "mpll_gate", };
-
-static struct clk *clk[IMX21_CLK_MAX];
-static struct clk_onecell_data clk_data;
-
-static void __init _mx21_clocks_init(unsigned long lref, unsigned long href)
-{
-       BUG_ON(!ccm);
-
-       clk[IMX21_CLK_DUMMY] = imx_clk_fixed("dummy", 0);
-       clk[IMX21_CLK_CKIL] = imx_obtain_fixed_clock("ckil", lref);
-       clk[IMX21_CLK_CKIH] = imx_obtain_fixed_clock("ckih", href);
-       clk[IMX21_CLK_FPM] = imx_clk_fixed_factor("fpm", "ckil", 512, 1);
-       clk[IMX21_CLK_CKIH_DIV1P5] = imx_clk_fixed_factor("ckih_div1p5", "ckih_gate", 2, 3);
-
-       clk[IMX21_CLK_MPLL_GATE] = imx_clk_gate("mpll_gate", "mpll", CCM_CSCR, 0);
-       clk[IMX21_CLK_SPLL_GATE] = imx_clk_gate("spll_gate", "spll", CCM_CSCR, 1);
-       clk[IMX21_CLK_FPM_GATE] = imx_clk_gate("fpm_gate", "fpm", CCM_CSCR, 2);
-       clk[IMX21_CLK_CKIH_GATE] = imx_clk_gate_dis("ckih_gate", "ckih", CCM_CSCR, 3);
-       clk[IMX21_CLK_MPLL_OSC_SEL] = imx_clk_mux("mpll_osc_sel", CCM_CSCR, 4, 1, mpll_osc_sel_clks, ARRAY_SIZE(mpll_osc_sel_clks));
-       clk[IMX21_CLK_IPG] = imx_clk_divider("ipg", "hclk", CCM_CSCR, 9, 1);
-       clk[IMX21_CLK_HCLK] = imx_clk_divider("hclk", "fclk", CCM_CSCR, 10, 4);
-       clk[IMX21_CLK_MPLL_SEL] = imx_clk_mux("mpll_sel", CCM_CSCR, 16, 1, mpll_sel_clks, ARRAY_SIZE(mpll_sel_clks));
-       clk[IMX21_CLK_SPLL_SEL] = imx_clk_mux("spll_sel", CCM_CSCR, 17, 1, spll_sel_clks, ARRAY_SIZE(spll_sel_clks));
-       clk[IMX21_CLK_SSI1_SEL] = imx_clk_mux("ssi1_sel", CCM_CSCR, 19, 1, ssi_sel_clks, ARRAY_SIZE(ssi_sel_clks));
-       clk[IMX21_CLK_SSI2_SEL] = imx_clk_mux("ssi2_sel", CCM_CSCR, 20, 1, ssi_sel_clks, ARRAY_SIZE(ssi_sel_clks));
-       clk[IMX21_CLK_USB_DIV] = imx_clk_divider("usb_div", "spll_gate", CCM_CSCR, 26, 3);
-       clk[IMX21_CLK_FCLK] = imx_clk_divider("fclk", "mpll_gate", CCM_CSCR, 29, 3);
-
-       clk[IMX21_CLK_MPLL] = imx_clk_pllv1(IMX_PLLV1_IMX21, "mpll", "mpll_sel", CCM_MPCTL0);
-
-       clk[IMX21_CLK_SPLL] = imx_clk_pllv1(IMX_PLLV1_IMX21, "spll", "spll_sel", CCM_SPCTL0);
-
-       clk[IMX21_CLK_NFC_DIV] = imx_clk_divider("nfc_div", "fclk", CCM_PCDR0, 12, 4);
-       clk[IMX21_CLK_SSI1_DIV] = imx_clk_divider("ssi1_div", "ssi1_sel", CCM_PCDR0, 16, 6);
-       clk[IMX21_CLK_SSI2_DIV] = imx_clk_divider("ssi2_div", "ssi2_sel", CCM_PCDR0, 26, 6);
-
-       clk[IMX21_CLK_PER1] = imx_clk_divider("per1", "mpll_gate", CCM_PCDR1, 0, 6);
-       clk[IMX21_CLK_PER2] = imx_clk_divider("per2", "mpll_gate", CCM_PCDR1, 8, 6);
-       clk[IMX21_CLK_PER3] = imx_clk_divider("per3", "mpll_gate", CCM_PCDR1, 16, 6);
-       clk[IMX21_CLK_PER4] = imx_clk_divider("per4", "mpll_gate", CCM_PCDR1, 24, 6);
-
-       clk[IMX21_CLK_UART1_IPG_GATE] = imx_clk_gate("uart1_ipg_gate", "ipg", CCM_PCCR0, 0);
-       clk[IMX21_CLK_UART2_IPG_GATE] = imx_clk_gate("uart2_ipg_gate", "ipg", CCM_PCCR0, 1);
-       clk[IMX21_CLK_UART3_IPG_GATE] = imx_clk_gate("uart3_ipg_gate", "ipg", CCM_PCCR0, 2);
-       clk[IMX21_CLK_UART4_IPG_GATE] = imx_clk_gate("uart4_ipg_gate", "ipg", CCM_PCCR0, 3);
-       clk[IMX21_CLK_CSPI1_IPG_GATE] = imx_clk_gate("cspi1_ipg_gate", "ipg", CCM_PCCR0, 4);
-       clk[IMX21_CLK_CSPI2_IPG_GATE] = imx_clk_gate("cspi2_ipg_gate", "ipg", CCM_PCCR0, 5);
-       clk[IMX21_CLK_SSI1_GATE] = imx_clk_gate("ssi1_gate", "ipg", CCM_PCCR0, 6);
-       clk[IMX21_CLK_SSI2_GATE] = imx_clk_gate("ssi2_gate", "ipg", CCM_PCCR0, 7);
-       clk[IMX21_CLK_SDHC1_IPG_GATE] = imx_clk_gate("sdhc1_ipg_gate", "ipg", CCM_PCCR0, 9);
-       clk[IMX21_CLK_SDHC2_IPG_GATE] = imx_clk_gate("sdhc2_ipg_gate", "ipg", CCM_PCCR0, 10);
-       clk[IMX21_CLK_GPIO_GATE] = imx_clk_gate("gpio_gate", "ipg", CCM_PCCR0, 11);
-       clk[IMX21_CLK_I2C_GATE] = imx_clk_gate("i2c_gate", "ipg", CCM_PCCR0, 12);
-       clk[IMX21_CLK_DMA_GATE] = imx_clk_gate("dma_gate", "ipg", CCM_PCCR0, 13);
-       clk[IMX21_CLK_USB_GATE] = imx_clk_gate("usb_gate", "usb_div", CCM_PCCR0, 14);
-       clk[IMX21_CLK_EMMA_GATE] = imx_clk_gate("emma_gate", "ipg", CCM_PCCR0, 15);
-       clk[IMX21_CLK_SSI2_BAUD_GATE] = imx_clk_gate("ssi2_baud_gate", "ipg", CCM_PCCR0, 16);
-       clk[IMX21_CLK_SSI1_BAUD_GATE] = imx_clk_gate("ssi1_baud_gate", "ipg", CCM_PCCR0, 17);
-       clk[IMX21_CLK_LCDC_IPG_GATE] = imx_clk_gate("lcdc_ipg_gate", "ipg", CCM_PCCR0, 18);
-       clk[IMX21_CLK_NFC_GATE] = imx_clk_gate("nfc_gate", "nfc_div", CCM_PCCR0, 19);
-       clk[IMX21_CLK_SLCDC_HCLK_GATE] = imx_clk_gate("slcdc_hclk_gate", "hclk", CCM_PCCR0, 21);
-       clk[IMX21_CLK_PER4_GATE] = imx_clk_gate("per4_gate", "per4", CCM_PCCR0, 22);
-       clk[IMX21_CLK_BMI_GATE] = imx_clk_gate("bmi_gate", "hclk", CCM_PCCR0, 23);
-       clk[IMX21_CLK_USB_HCLK_GATE] = imx_clk_gate("usb_hclk_gate", "hclk", CCM_PCCR0, 24);
-       clk[IMX21_CLK_SLCDC_GATE] = imx_clk_gate("slcdc_gate", "hclk", CCM_PCCR0, 25);
-       clk[IMX21_CLK_LCDC_HCLK_GATE] = imx_clk_gate("lcdc_hclk_gate", "hclk", CCM_PCCR0, 26);
-       clk[IMX21_CLK_EMMA_HCLK_GATE] = imx_clk_gate("emma_hclk_gate", "hclk", CCM_PCCR0, 27);
-       clk[IMX21_CLK_BROM_GATE] = imx_clk_gate("brom_gate", "hclk", CCM_PCCR0, 28);
-       clk[IMX21_CLK_DMA_HCLK_GATE] = imx_clk_gate("dma_hclk_gate", "hclk", CCM_PCCR0, 30);
-       clk[IMX21_CLK_CSI_HCLK_GATE] = imx_clk_gate("csi_hclk_gate", "hclk", CCM_PCCR0, 31);
-
-       clk[IMX21_CLK_CSPI3_IPG_GATE] = imx_clk_gate("cspi3_ipg_gate", "ipg", CCM_PCCR1, 23);
-       clk[IMX21_CLK_WDOG_GATE] = imx_clk_gate("wdog_gate", "ipg", CCM_PCCR1, 24);
-       clk[IMX21_CLK_GPT1_IPG_GATE] = imx_clk_gate("gpt1_ipg_gate", "ipg", CCM_PCCR1, 25);
-       clk[IMX21_CLK_GPT2_IPG_GATE] = imx_clk_gate("gpt2_ipg_gate", "ipg", CCM_PCCR1, 26);
-       clk[IMX21_CLK_GPT3_IPG_GATE] = imx_clk_gate("gpt3_ipg_gate", "ipg", CCM_PCCR1, 27);
-       clk[IMX21_CLK_PWM_IPG_GATE] = imx_clk_gate("pwm_ipg_gate", "ipg", CCM_PCCR1, 28);
-       clk[IMX21_CLK_RTC_GATE] = imx_clk_gate("rtc_gate", "ipg", CCM_PCCR1, 29);
-       clk[IMX21_CLK_KPP_GATE] = imx_clk_gate("kpp_gate", "ipg", CCM_PCCR1, 30);
-       clk[IMX21_CLK_OWIRE_GATE] = imx_clk_gate("owire_gate", "ipg", CCM_PCCR1, 31);
-
-       imx_check_clocks(clk, ARRAY_SIZE(clk));
-}
-
-int __init mx21_clocks_init(unsigned long lref, unsigned long href)
-{
-       ccm = ioremap(MX21_CCM_BASE_ADDR, SZ_2K);
-
-       _mx21_clocks_init(lref, href);
-
-       clk_register_clkdev(clk[IMX21_CLK_PER1], "per", "imx21-uart.0");
-       clk_register_clkdev(clk[IMX21_CLK_UART1_IPG_GATE], "ipg", "imx21-uart.0");
-       clk_register_clkdev(clk[IMX21_CLK_PER1], "per", "imx21-uart.1");
-       clk_register_clkdev(clk[IMX21_CLK_UART2_IPG_GATE], "ipg", "imx21-uart.1");
-       clk_register_clkdev(clk[IMX21_CLK_PER1], "per", "imx21-uart.2");
-       clk_register_clkdev(clk[IMX21_CLK_UART3_IPG_GATE], "ipg", "imx21-uart.2");
-       clk_register_clkdev(clk[IMX21_CLK_PER1], "per", "imx21-uart.3");
-       clk_register_clkdev(clk[IMX21_CLK_UART4_IPG_GATE], "ipg", "imx21-uart.3");
-       clk_register_clkdev(clk[IMX21_CLK_GPT1_IPG_GATE], "ipg", "imx-gpt.0");
-       clk_register_clkdev(clk[IMX21_CLK_PER1], "per", "imx-gpt.0");
-       clk_register_clkdev(clk[IMX21_CLK_PER2], "per", "imx21-cspi.0");
-       clk_register_clkdev(clk[IMX21_CLK_CSPI1_IPG_GATE], "ipg", "imx21-cspi.0");
-       clk_register_clkdev(clk[IMX21_CLK_PER2], "per", "imx21-cspi.1");
-       clk_register_clkdev(clk[IMX21_CLK_CSPI2_IPG_GATE], "ipg", "imx21-cspi.1");
-       clk_register_clkdev(clk[IMX21_CLK_PER2], "per", "imx21-cspi.2");
-       clk_register_clkdev(clk[IMX21_CLK_CSPI3_IPG_GATE], "ipg", "imx21-cspi.2");
-       clk_register_clkdev(clk[IMX21_CLK_PER3], "per", "imx21-fb.0");
-       clk_register_clkdev(clk[IMX21_CLK_LCDC_IPG_GATE], "ipg", "imx21-fb.0");
-       clk_register_clkdev(clk[IMX21_CLK_LCDC_HCLK_GATE], "ahb", "imx21-fb.0");
-       clk_register_clkdev(clk[IMX21_CLK_USB_GATE], "per", "imx21-hcd.0");
-       clk_register_clkdev(clk[IMX21_CLK_USB_HCLK_GATE], "ahb", "imx21-hcd.0");
-       clk_register_clkdev(clk[IMX21_CLK_NFC_GATE], NULL, "imx21-nand.0");
-       clk_register_clkdev(clk[IMX21_CLK_DMA_HCLK_GATE], "ahb", "imx21-dma");
-       clk_register_clkdev(clk[IMX21_CLK_DMA_GATE], "ipg", "imx21-dma");
-       clk_register_clkdev(clk[IMX21_CLK_WDOG_GATE], NULL, "imx2-wdt.0");
-       clk_register_clkdev(clk[IMX21_CLK_I2C_GATE], NULL, "imx21-i2c.0");
-       clk_register_clkdev(clk[IMX21_CLK_OWIRE_GATE], NULL, "mxc_w1.0");
-
-       mxc_timer_init(MX21_GPT1_BASE_ADDR, MX21_INT_GPT1, GPT_TYPE_IMX21);
-
-       return 0;
-}
-
-static void __init mx21_clocks_init_dt(struct device_node *np)
-{
-       ccm = of_iomap(np, 0);
-
-       _mx21_clocks_init(32768, 26000000);
-
-       clk_data.clks = clk;
-       clk_data.clk_num = ARRAY_SIZE(clk);
-       of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
-}
-CLK_OF_DECLARE(imx27_ccm, "fsl,imx21-ccm", mx21_clocks_init_dt);
index ba33c79..b2ff187 100644 (file)
@@ -6,6 +6,7 @@
 
 #include <linux/init.h>
 #include <linux/types.h>
+#include <linux/bits.h>
 #include <linux/clk.h>
 #include <linux/clkdev.h>
 #include <linux/clk-provider.h>
index 0f647d1..2f93619 100644 (file)
@@ -3,6 +3,7 @@
  * Copyright 2013-2014 Freescale Semiconductor, Inc.
  */
 
+#include <linux/bits.h>
 #include <linux/clk.h>
 #include <linux/clkdev.h>
 #include <linux/err.h>
 #include "clk.h"
 
 #define CCSR                   0xc
-#define BM_CCSR_PLL1_SW_CLK_SEL        (1 << 2)
+#define BM_CCSR_PLL1_SW_CLK_SEL        BIT(2)
 #define CACRR                  0x10
 #define CDHIPR                 0x48
-#define BM_CDHIPR_ARM_PODF_BUSY        (1 << 16)
+#define BM_CDHIPR_ARM_PODF_BUSY        BIT(16)
 #define ARM_WAIT_DIV_396M      2
 #define ARM_WAIT_DIV_792M      4
 #define ARM_WAIT_DIV_996M      6
 
 #define PLL_ARM                        0x0
-#define BM_PLL_ARM_DIV_SELECT  (0x7f << 0)
-#define BM_PLL_ARM_POWERDOWN   (1 << 12)
-#define BM_PLL_ARM_ENABLE      (1 << 13)
-#define BM_PLL_ARM_LOCK                (1 << 31)
+#define BM_PLL_ARM_DIV_SELECT  0x7f
+#define BM_PLL_ARM_POWERDOWN   BIT(12)
+#define BM_PLL_ARM_ENABLE      BIT(13)
+#define BM_PLL_ARM_LOCK                BIT(31)
 #define PLL_ARM_DIV_792M       66
 
 static const char *step_sels[]         = { "osc", "pll2_pfd2", };
@@ -145,7 +146,7 @@ static void imx6sl_enable_pll_arm(bool enable)
                val |= BM_PLL_ARM_ENABLE;
                val &= ~BM_PLL_ARM_POWERDOWN;
                writel_relaxed(val, anatop_base + PLL_ARM);
-               while (!(__raw_readl(anatop_base + PLL_ARM) & BM_PLL_ARM_LOCK))
+               while (!(readl_relaxed(anatop_base + PLL_ARM) & BM_PLL_ARM_LOCK))
                        ;
        } else {
                 writel_relaxed(saved_pll_arm, anatop_base + PLL_ARM);
index 89ba712..20dcce5 100644 (file)
@@ -4,6 +4,7 @@
  */
 
 #include <dt-bindings/clock/imx6sx-clock.h>
+#include <linux/bits.h>
 #include <linux/clk.h>
 #include <linux/clkdev.h>
 #include <linux/clk-provider.h>
index b2057bd..22d24a6 100644 (file)
@@ -4,6 +4,7 @@
  */
 
 #include <dt-bindings/clock/imx7d-clock.h>
+#include <linux/bits.h>
 #include <linux/clk.h>
 #include <linux/clkdev.h>
 #include <linux/clk-provider.h>
@@ -505,72 +506,73 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
        hws[IMX7D_ARM_M4_ROOT_SRC] = imx_clk_hw_mux2("arm_m4_src", base + 0x8080, 24, 3, arm_m4_sel, ARRAY_SIZE(arm_m4_sel));
        hws[IMX7D_MAIN_AXI_ROOT_SRC] = imx_clk_hw_mux2("axi_src", base + 0x8800, 24, 3, axi_sel, ARRAY_SIZE(axi_sel));
        hws[IMX7D_DISP_AXI_ROOT_SRC] = imx_clk_hw_mux2("disp_axi_src", base + 0x8880, 24, 3, disp_axi_sel, ARRAY_SIZE(disp_axi_sel));
-       hws[IMX7D_ENET_AXI_ROOT_SRC] = imx_clk_hw_mux2("enet_axi_src", base + 0x8900, 24, 3, enet_axi_sel, ARRAY_SIZE(enet_axi_sel));
-       hws[IMX7D_NAND_USDHC_BUS_ROOT_SRC] = imx_clk_hw_mux2("nand_usdhc_src", base + 0x8980, 24, 3, nand_usdhc_bus_sel, ARRAY_SIZE(nand_usdhc_bus_sel));
        hws[IMX7D_AHB_CHANNEL_ROOT_SRC] = imx_clk_hw_mux2("ahb_src", base + 0x9000, 24, 3, ahb_channel_sel, ARRAY_SIZE(ahb_channel_sel));
-       hws[IMX7D_DRAM_PHYM_ROOT_SRC] = imx_clk_hw_mux2("dram_phym_src", base + 0x9800, 24, 1, dram_phym_sel, ARRAY_SIZE(dram_phym_sel));
-       hws[IMX7D_DRAM_ROOT_SRC] = imx_clk_hw_mux2("dram_src", base + 0x9880, 24, 1, dram_sel, ARRAY_SIZE(dram_sel));
-       hws[IMX7D_DRAM_PHYM_ALT_ROOT_SRC] = imx_clk_hw_mux2("dram_phym_alt_src", base + 0xa000, 24, 3, dram_phym_alt_sel, ARRAY_SIZE(dram_phym_alt_sel));
-       hws[IMX7D_DRAM_ALT_ROOT_SRC]  = imx_clk_hw_mux2("dram_alt_src", base + 0xa080, 24, 3, dram_alt_sel, ARRAY_SIZE(dram_alt_sel));
-       hws[IMX7D_USB_HSIC_ROOT_SRC] = imx_clk_hw_mux2("usb_hsic_src", base + 0xa100, 24, 3, usb_hsic_sel, ARRAY_SIZE(usb_hsic_sel));
-       hws[IMX7D_PCIE_CTRL_ROOT_SRC] = imx_clk_hw_mux2("pcie_ctrl_src", base + 0xa180, 24, 3, pcie_ctrl_sel, ARRAY_SIZE(pcie_ctrl_sel));
-       hws[IMX7D_PCIE_PHY_ROOT_SRC] = imx_clk_hw_mux2("pcie_phy_src", base + 0xa200, 24, 3, pcie_phy_sel, ARRAY_SIZE(pcie_phy_sel));
-       hws[IMX7D_EPDC_PIXEL_ROOT_SRC] = imx_clk_hw_mux2("epdc_pixel_src", base + 0xa280, 24, 3, epdc_pixel_sel, ARRAY_SIZE(epdc_pixel_sel));
-       hws[IMX7D_LCDIF_PIXEL_ROOT_SRC] = imx_clk_hw_mux2("lcdif_pixel_src", base + 0xa300, 24, 3, lcdif_pixel_sel, ARRAY_SIZE(lcdif_pixel_sel));
-       hws[IMX7D_MIPI_DSI_ROOT_SRC] = imx_clk_hw_mux2("mipi_dsi_src", base + 0xa380, 24, 3,  mipi_dsi_sel, ARRAY_SIZE(mipi_dsi_sel));
-       hws[IMX7D_MIPI_CSI_ROOT_SRC] = imx_clk_hw_mux2("mipi_csi_src", base + 0xa400, 24, 3, mipi_csi_sel, ARRAY_SIZE(mipi_csi_sel));
-       hws[IMX7D_MIPI_DPHY_ROOT_SRC] = imx_clk_hw_mux2("mipi_dphy_src", base + 0xa480, 24, 3, mipi_dphy_sel, ARRAY_SIZE(mipi_dphy_sel));
-       hws[IMX7D_SAI1_ROOT_SRC] = imx_clk_hw_mux2("sai1_src", base + 0xa500, 24, 3, sai1_sel, ARRAY_SIZE(sai1_sel));
-       hws[IMX7D_SAI2_ROOT_SRC] = imx_clk_hw_mux2("sai2_src", base + 0xa580, 24, 3, sai2_sel, ARRAY_SIZE(sai2_sel));
-       hws[IMX7D_SAI3_ROOT_SRC] = imx_clk_hw_mux2("sai3_src", base + 0xa600, 24, 3, sai3_sel, ARRAY_SIZE(sai3_sel));
-       hws[IMX7D_SPDIF_ROOT_SRC] = imx_clk_hw_mux2("spdif_src", base + 0xa680, 24, 3, spdif_sel, ARRAY_SIZE(spdif_sel));
-       hws[IMX7D_ENET1_REF_ROOT_SRC] = imx_clk_hw_mux2("enet1_ref_src", base + 0xa700, 24, 3, enet1_ref_sel, ARRAY_SIZE(enet1_ref_sel));
-       hws[IMX7D_ENET1_TIME_ROOT_SRC] = imx_clk_hw_mux2("enet1_time_src", base + 0xa780, 24, 3, enet1_time_sel, ARRAY_SIZE(enet1_time_sel));
-       hws[IMX7D_ENET2_REF_ROOT_SRC] = imx_clk_hw_mux2("enet2_ref_src", base + 0xa800, 24, 3, enet2_ref_sel, ARRAY_SIZE(enet2_ref_sel));
-       hws[IMX7D_ENET2_TIME_ROOT_SRC] = imx_clk_hw_mux2("enet2_time_src", base + 0xa880, 24, 3, enet2_time_sel, ARRAY_SIZE(enet2_time_sel));
-       hws[IMX7D_ENET_PHY_REF_ROOT_SRC] = imx_clk_hw_mux2("enet_phy_ref_src", base + 0xa900, 24, 3, enet_phy_ref_sel, ARRAY_SIZE(enet_phy_ref_sel));
-       hws[IMX7D_EIM_ROOT_SRC] = imx_clk_hw_mux2("eim_src", base + 0xa980, 24, 3, eim_sel, ARRAY_SIZE(eim_sel));
-       hws[IMX7D_NAND_ROOT_SRC] = imx_clk_hw_mux2("nand_src", base + 0xaa00, 24, 3, nand_sel, ARRAY_SIZE(nand_sel));
-       hws[IMX7D_QSPI_ROOT_SRC] = imx_clk_hw_mux2("qspi_src", base + 0xaa80, 24, 3, qspi_sel, ARRAY_SIZE(qspi_sel));
-       hws[IMX7D_USDHC1_ROOT_SRC] = imx_clk_hw_mux2("usdhc1_src", base + 0xab00, 24, 3, usdhc1_sel, ARRAY_SIZE(usdhc1_sel));
-       hws[IMX7D_USDHC2_ROOT_SRC] = imx_clk_hw_mux2("usdhc2_src", base + 0xab80, 24, 3, usdhc2_sel, ARRAY_SIZE(usdhc2_sel));
-       hws[IMX7D_USDHC3_ROOT_SRC] = imx_clk_hw_mux2("usdhc3_src", base + 0xac00, 24, 3, usdhc3_sel, ARRAY_SIZE(usdhc3_sel));
-       hws[IMX7D_CAN1_ROOT_SRC] = imx_clk_hw_mux2("can1_src", base + 0xac80, 24, 3, can1_sel, ARRAY_SIZE(can1_sel));
-       hws[IMX7D_CAN2_ROOT_SRC] = imx_clk_hw_mux2("can2_src", base + 0xad00, 24, 3, can2_sel, ARRAY_SIZE(can2_sel));
-       hws[IMX7D_I2C1_ROOT_SRC] = imx_clk_hw_mux2("i2c1_src", base + 0xad80, 24, 3, i2c1_sel, ARRAY_SIZE(i2c1_sel));
-       hws[IMX7D_I2C2_ROOT_SRC] = imx_clk_hw_mux2("i2c2_src", base + 0xae00, 24, 3, i2c2_sel, ARRAY_SIZE(i2c2_sel));
-       hws[IMX7D_I2C3_ROOT_SRC] = imx_clk_hw_mux2("i2c3_src", base + 0xae80, 24, 3, i2c3_sel, ARRAY_SIZE(i2c3_sel));
-       hws[IMX7D_I2C4_ROOT_SRC] = imx_clk_hw_mux2("i2c4_src", base + 0xaf00, 24, 3, i2c4_sel, ARRAY_SIZE(i2c4_sel));
-       hws[IMX7D_UART1_ROOT_SRC] = imx_clk_hw_mux2("uart1_src", base + 0xaf80, 24, 3, uart1_sel, ARRAY_SIZE(uart1_sel));
-       hws[IMX7D_UART2_ROOT_SRC] = imx_clk_hw_mux2("uart2_src", base + 0xb000, 24, 3, uart2_sel, ARRAY_SIZE(uart2_sel));
-       hws[IMX7D_UART3_ROOT_SRC] = imx_clk_hw_mux2("uart3_src", base + 0xb080, 24, 3, uart3_sel, ARRAY_SIZE(uart3_sel));
-       hws[IMX7D_UART4_ROOT_SRC] = imx_clk_hw_mux2("uart4_src", base + 0xb100, 24, 3, uart4_sel, ARRAY_SIZE(uart4_sel));
-       hws[IMX7D_UART5_ROOT_SRC] = imx_clk_hw_mux2("uart5_src", base + 0xb180, 24, 3, uart5_sel, ARRAY_SIZE(uart5_sel));
-       hws[IMX7D_UART6_ROOT_SRC] = imx_clk_hw_mux2("uart6_src", base + 0xb200, 24, 3, uart6_sel, ARRAY_SIZE(uart6_sel));
-       hws[IMX7D_UART7_ROOT_SRC] = imx_clk_hw_mux2("uart7_src", base + 0xb280, 24, 3, uart7_sel, ARRAY_SIZE(uart7_sel));
-       hws[IMX7D_ECSPI1_ROOT_SRC] = imx_clk_hw_mux2("ecspi1_src", base + 0xb300, 24, 3, ecspi1_sel, ARRAY_SIZE(ecspi1_sel));
-       hws[IMX7D_ECSPI2_ROOT_SRC] = imx_clk_hw_mux2("ecspi2_src", base + 0xb380, 24, 3, ecspi2_sel, ARRAY_SIZE(ecspi2_sel));
-       hws[IMX7D_ECSPI3_ROOT_SRC] = imx_clk_hw_mux2("ecspi3_src", base + 0xb400, 24, 3, ecspi3_sel, ARRAY_SIZE(ecspi3_sel));
-       hws[IMX7D_ECSPI4_ROOT_SRC] = imx_clk_hw_mux2("ecspi4_src", base + 0xb480, 24, 3, ecspi4_sel, ARRAY_SIZE(ecspi4_sel));
-       hws[IMX7D_PWM1_ROOT_SRC] = imx_clk_hw_mux2("pwm1_src", base + 0xb500, 24, 3, pwm1_sel, ARRAY_SIZE(pwm1_sel));
-       hws[IMX7D_PWM2_ROOT_SRC] = imx_clk_hw_mux2("pwm2_src", base + 0xb580, 24, 3, pwm2_sel, ARRAY_SIZE(pwm2_sel));
-       hws[IMX7D_PWM3_ROOT_SRC] = imx_clk_hw_mux2("pwm3_src", base + 0xb600, 24, 3, pwm3_sel, ARRAY_SIZE(pwm3_sel));
-       hws[IMX7D_PWM4_ROOT_SRC] = imx_clk_hw_mux2("pwm4_src", base + 0xb680, 24, 3, pwm4_sel, ARRAY_SIZE(pwm4_sel));
-       hws[IMX7D_FLEXTIMER1_ROOT_SRC] = imx_clk_hw_mux2("flextimer1_src", base + 0xb700, 24, 3, flextimer1_sel, ARRAY_SIZE(flextimer1_sel));
-       hws[IMX7D_FLEXTIMER2_ROOT_SRC] = imx_clk_hw_mux2("flextimer2_src", base + 0xb780, 24, 3, flextimer2_sel, ARRAY_SIZE(flextimer2_sel));
-       hws[IMX7D_SIM1_ROOT_SRC] = imx_clk_hw_mux2("sim1_src", base + 0xb800, 24, 3, sim1_sel, ARRAY_SIZE(sim1_sel));
-       hws[IMX7D_SIM2_ROOT_SRC] = imx_clk_hw_mux2("sim2_src", base + 0xb880, 24, 3, sim2_sel, ARRAY_SIZE(sim2_sel));
-       hws[IMX7D_GPT1_ROOT_SRC] = imx_clk_hw_mux2("gpt1_src", base + 0xb900, 24, 3, gpt1_sel, ARRAY_SIZE(gpt1_sel));
-       hws[IMX7D_GPT2_ROOT_SRC] = imx_clk_hw_mux2("gpt2_src", base + 0xb980, 24, 3, gpt2_sel, ARRAY_SIZE(gpt2_sel));
-       hws[IMX7D_GPT3_ROOT_SRC] = imx_clk_hw_mux2("gpt3_src", base + 0xba00, 24, 3, gpt3_sel, ARRAY_SIZE(gpt3_sel));
-       hws[IMX7D_GPT4_ROOT_SRC] = imx_clk_hw_mux2("gpt4_src", base + 0xba80, 24, 3, gpt4_sel, ARRAY_SIZE(gpt4_sel));
-       hws[IMX7D_TRACE_ROOT_SRC] = imx_clk_hw_mux2("trace_src", base + 0xbb00, 24, 3, trace_sel, ARRAY_SIZE(trace_sel));
-       hws[IMX7D_WDOG_ROOT_SRC] = imx_clk_hw_mux2("wdog_src", base + 0xbb80, 24, 3, wdog_sel, ARRAY_SIZE(wdog_sel));
-       hws[IMX7D_CSI_MCLK_ROOT_SRC] = imx_clk_hw_mux2("csi_mclk_src", base + 0xbc00, 24, 3, csi_mclk_sel, ARRAY_SIZE(csi_mclk_sel));
-       hws[IMX7D_AUDIO_MCLK_ROOT_SRC] = imx_clk_hw_mux2("audio_mclk_src", base + 0xbc80, 24, 3, audio_mclk_sel, ARRAY_SIZE(audio_mclk_sel));
-       hws[IMX7D_WRCLK_ROOT_SRC] = imx_clk_hw_mux2("wrclk_src", base + 0xbd00, 24, 3, wrclk_sel, ARRAY_SIZE(wrclk_sel));
-       hws[IMX7D_CLKO1_ROOT_SRC] = imx_clk_hw_mux2("clko1_src", base + 0xbd80, 24, 3, clko1_sel, ARRAY_SIZE(clko1_sel));
-       hws[IMX7D_CLKO2_ROOT_SRC] = imx_clk_hw_mux2("clko2_src", base + 0xbe00, 24, 3, clko2_sel, ARRAY_SIZE(clko2_sel));
+
+       hws[IMX7D_ENET_AXI_ROOT_SRC] = imx_clk_hw_mux2_flags("enet_axi_src", base + 0x8900, 24, 3, enet_axi_sel, ARRAY_SIZE(enet_axi_sel), CLK_SET_PARENT_GATE);
+       hws[IMX7D_NAND_USDHC_BUS_ROOT_SRC] = imx_clk_hw_mux2_flags("nand_usdhc_src", base + 0x8980, 24, 3, nand_usdhc_bus_sel, ARRAY_SIZE(nand_usdhc_bus_sel), CLK_SET_PARENT_GATE);
+       hws[IMX7D_DRAM_PHYM_ROOT_SRC] = imx_clk_hw_mux2_flags("dram_phym_src", base + 0x9800, 24, 1, dram_phym_sel, ARRAY_SIZE(dram_phym_sel), CLK_SET_PARENT_GATE);
+       hws[IMX7D_DRAM_ROOT_SRC] = imx_clk_hw_mux2_flags("dram_src", base + 0x9880, 24, 1, dram_sel, ARRAY_SIZE(dram_sel), CLK_SET_PARENT_GATE);
+       hws[IMX7D_DRAM_PHYM_ALT_ROOT_SRC] = imx_clk_hw_mux2_flags("dram_phym_alt_src", base + 0xa000, 24, 3, dram_phym_alt_sel, ARRAY_SIZE(dram_phym_alt_sel), CLK_SET_PARENT_GATE);
+       hws[IMX7D_DRAM_ALT_ROOT_SRC]  = imx_clk_hw_mux2_flags("dram_alt_src", base + 0xa080, 24, 3, dram_alt_sel, ARRAY_SIZE(dram_alt_sel), CLK_SET_PARENT_GATE);
+       hws[IMX7D_USB_HSIC_ROOT_SRC] = imx_clk_hw_mux2_flags("usb_hsic_src", base + 0xa100, 24, 3, usb_hsic_sel, ARRAY_SIZE(usb_hsic_sel), CLK_SET_PARENT_GATE);
+       hws[IMX7D_PCIE_CTRL_ROOT_SRC] = imx_clk_hw_mux2_flags("pcie_ctrl_src", base + 0xa180, 24, 3, pcie_ctrl_sel, ARRAY_SIZE(pcie_ctrl_sel), CLK_SET_PARENT_GATE);
+       hws[IMX7D_PCIE_PHY_ROOT_SRC] = imx_clk_hw_mux2_flags("pcie_phy_src", base + 0xa200, 24, 3, pcie_phy_sel, ARRAY_SIZE(pcie_phy_sel), CLK_SET_PARENT_GATE);
+       hws[IMX7D_EPDC_PIXEL_ROOT_SRC] = imx_clk_hw_mux2_flags("epdc_pixel_src", base + 0xa280, 24, 3, epdc_pixel_sel, ARRAY_SIZE(epdc_pixel_sel), CLK_SET_PARENT_GATE);
+       hws[IMX7D_LCDIF_PIXEL_ROOT_SRC] = imx_clk_hw_mux2_flags("lcdif_pixel_src", base + 0xa300, 24, 3, lcdif_pixel_sel, ARRAY_SIZE(lcdif_pixel_sel), CLK_SET_PARENT_GATE);
+       hws[IMX7D_MIPI_DSI_ROOT_SRC] = imx_clk_hw_mux2_flags("mipi_dsi_src", base + 0xa380, 24, 3,  mipi_dsi_sel, ARRAY_SIZE(mipi_dsi_sel), CLK_SET_PARENT_GATE);
+       hws[IMX7D_MIPI_CSI_ROOT_SRC] = imx_clk_hw_mux2_flags("mipi_csi_src", base + 0xa400, 24, 3, mipi_csi_sel, ARRAY_SIZE(mipi_csi_sel), CLK_SET_PARENT_GATE);
+       hws[IMX7D_MIPI_DPHY_ROOT_SRC] = imx_clk_hw_mux2_flags("mipi_dphy_src", base + 0xa480, 24, 3, mipi_dphy_sel, ARRAY_SIZE(mipi_dphy_sel), CLK_SET_PARENT_GATE);
+       hws[IMX7D_SAI1_ROOT_SRC] = imx_clk_hw_mux2_flags("sai1_src", base + 0xa500, 24, 3, sai1_sel, ARRAY_SIZE(sai1_sel), CLK_SET_PARENT_GATE);
+       hws[IMX7D_SAI2_ROOT_SRC] = imx_clk_hw_mux2_flags("sai2_src", base + 0xa580, 24, 3, sai2_sel, ARRAY_SIZE(sai2_sel), CLK_SET_PARENT_GATE);
+       hws[IMX7D_SAI3_ROOT_SRC] = imx_clk_hw_mux2_flags("sai3_src", base + 0xa600, 24, 3, sai3_sel, ARRAY_SIZE(sai3_sel), CLK_SET_PARENT_GATE);
+       hws[IMX7D_SPDIF_ROOT_SRC] = imx_clk_hw_mux2_flags("spdif_src", base + 0xa680, 24, 3, spdif_sel, ARRAY_SIZE(spdif_sel), CLK_SET_PARENT_GATE);
+       hws[IMX7D_ENET1_REF_ROOT_SRC] = imx_clk_hw_mux2_flags("enet1_ref_src", base + 0xa700, 24, 3, enet1_ref_sel, ARRAY_SIZE(enet1_ref_sel), CLK_SET_PARENT_GATE);
+       hws[IMX7D_ENET1_TIME_ROOT_SRC] = imx_clk_hw_mux2_flags("enet1_time_src", base + 0xa780, 24, 3, enet1_time_sel, ARRAY_SIZE(enet1_time_sel), CLK_SET_PARENT_GATE);
+       hws[IMX7D_ENET2_REF_ROOT_SRC] = imx_clk_hw_mux2_flags("enet2_ref_src", base + 0xa800, 24, 3, enet2_ref_sel, ARRAY_SIZE(enet2_ref_sel), CLK_SET_PARENT_GATE);
+       hws[IMX7D_ENET2_TIME_ROOT_SRC] = imx_clk_hw_mux2_flags("enet2_time_src", base + 0xa880, 24, 3, enet2_time_sel, ARRAY_SIZE(enet2_time_sel), CLK_SET_PARENT_GATE);
+       hws[IMX7D_ENET_PHY_REF_ROOT_SRC] = imx_clk_hw_mux2_flags("enet_phy_ref_src", base + 0xa900, 24, 3, enet_phy_ref_sel, ARRAY_SIZE(enet_phy_ref_sel), CLK_SET_PARENT_GATE);
+       hws[IMX7D_EIM_ROOT_SRC] = imx_clk_hw_mux2_flags("eim_src", base + 0xa980, 24, 3, eim_sel, ARRAY_SIZE(eim_sel), CLK_SET_PARENT_GATE);
+       hws[IMX7D_NAND_ROOT_SRC] = imx_clk_hw_mux2_flags("nand_src", base + 0xaa00, 24, 3, nand_sel, ARRAY_SIZE(nand_sel), CLK_SET_PARENT_GATE);
+       hws[IMX7D_QSPI_ROOT_SRC] = imx_clk_hw_mux2_flags("qspi_src", base + 0xaa80, 24, 3, qspi_sel, ARRAY_SIZE(qspi_sel), CLK_SET_PARENT_GATE);
+       hws[IMX7D_USDHC1_ROOT_SRC] = imx_clk_hw_mux2_flags("usdhc1_src", base + 0xab00, 24, 3, usdhc1_sel, ARRAY_SIZE(usdhc1_sel), CLK_SET_PARENT_GATE);
+       hws[IMX7D_USDHC2_ROOT_SRC] = imx_clk_hw_mux2_flags("usdhc2_src", base + 0xab80, 24, 3, usdhc2_sel, ARRAY_SIZE(usdhc2_sel), CLK_SET_PARENT_GATE);
+       hws[IMX7D_USDHC3_ROOT_SRC] = imx_clk_hw_mux2_flags("usdhc3_src", base + 0xac00, 24, 3, usdhc3_sel, ARRAY_SIZE(usdhc3_sel), CLK_SET_PARENT_GATE);
+       hws[IMX7D_CAN1_ROOT_SRC] = imx_clk_hw_mux2_flags("can1_src", base + 0xac80, 24, 3, can1_sel, ARRAY_SIZE(can1_sel), CLK_SET_PARENT_GATE);
+       hws[IMX7D_CAN2_ROOT_SRC] = imx_clk_hw_mux2_flags("can2_src", base + 0xad00, 24, 3, can2_sel, ARRAY_SIZE(can2_sel), CLK_SET_PARENT_GATE);
+       hws[IMX7D_I2C1_ROOT_SRC] = imx_clk_hw_mux2_flags("i2c1_src", base + 0xad80, 24, 3, i2c1_sel, ARRAY_SIZE(i2c1_sel), CLK_SET_PARENT_GATE);
+       hws[IMX7D_I2C2_ROOT_SRC] = imx_clk_hw_mux2_flags("i2c2_src", base + 0xae00, 24, 3, i2c2_sel, ARRAY_SIZE(i2c2_sel), CLK_SET_PARENT_GATE);
+       hws[IMX7D_I2C3_ROOT_SRC] = imx_clk_hw_mux2_flags("i2c3_src", base + 0xae80, 24, 3, i2c3_sel, ARRAY_SIZE(i2c3_sel), CLK_SET_PARENT_GATE);
+       hws[IMX7D_I2C4_ROOT_SRC] = imx_clk_hw_mux2_flags("i2c4_src", base + 0xaf00, 24, 3, i2c4_sel, ARRAY_SIZE(i2c4_sel), CLK_SET_PARENT_GATE);
+       hws[IMX7D_UART1_ROOT_SRC] = imx_clk_hw_mux2_flags("uart1_src", base + 0xaf80, 24, 3, uart1_sel, ARRAY_SIZE(uart1_sel), CLK_SET_PARENT_GATE);
+       hws[IMX7D_UART2_ROOT_SRC] = imx_clk_hw_mux2_flags("uart2_src", base + 0xb000, 24, 3, uart2_sel, ARRAY_SIZE(uart2_sel), CLK_SET_PARENT_GATE);
+       hws[IMX7D_UART3_ROOT_SRC] = imx_clk_hw_mux2_flags("uart3_src", base + 0xb080, 24, 3, uart3_sel, ARRAY_SIZE(uart3_sel), CLK_SET_PARENT_GATE);
+       hws[IMX7D_UART4_ROOT_SRC] = imx_clk_hw_mux2_flags("uart4_src", base + 0xb100, 24, 3, uart4_sel, ARRAY_SIZE(uart4_sel), CLK_SET_PARENT_GATE);
+       hws[IMX7D_UART5_ROOT_SRC] = imx_clk_hw_mux2_flags("uart5_src", base + 0xb180, 24, 3, uart5_sel, ARRAY_SIZE(uart5_sel), CLK_SET_PARENT_GATE);
+       hws[IMX7D_UART6_ROOT_SRC] = imx_clk_hw_mux2_flags("uart6_src", base + 0xb200, 24, 3, uart6_sel, ARRAY_SIZE(uart6_sel), CLK_SET_PARENT_GATE);
+       hws[IMX7D_UART7_ROOT_SRC] = imx_clk_hw_mux2_flags("uart7_src", base + 0xb280, 24, 3, uart7_sel, ARRAY_SIZE(uart7_sel), CLK_SET_PARENT_GATE);
+       hws[IMX7D_ECSPI1_ROOT_SRC] = imx_clk_hw_mux2_flags("ecspi1_src", base + 0xb300, 24, 3, ecspi1_sel, ARRAY_SIZE(ecspi1_sel), CLK_SET_PARENT_GATE);
+       hws[IMX7D_ECSPI2_ROOT_SRC] = imx_clk_hw_mux2_flags("ecspi2_src", base + 0xb380, 24, 3, ecspi2_sel, ARRAY_SIZE(ecspi2_sel), CLK_SET_PARENT_GATE);
+       hws[IMX7D_ECSPI3_ROOT_SRC] = imx_clk_hw_mux2_flags("ecspi3_src", base + 0xb400, 24, 3, ecspi3_sel, ARRAY_SIZE(ecspi3_sel), CLK_SET_PARENT_GATE);
+       hws[IMX7D_ECSPI4_ROOT_SRC] = imx_clk_hw_mux2_flags("ecspi4_src", base + 0xb480, 24, 3, ecspi4_sel, ARRAY_SIZE(ecspi4_sel), CLK_SET_PARENT_GATE);
+       hws[IMX7D_PWM1_ROOT_SRC] = imx_clk_hw_mux2_flags("pwm1_src", base + 0xb500, 24, 3, pwm1_sel, ARRAY_SIZE(pwm1_sel), CLK_SET_PARENT_GATE);
+       hws[IMX7D_PWM2_ROOT_SRC] = imx_clk_hw_mux2_flags("pwm2_src", base + 0xb580, 24, 3, pwm2_sel, ARRAY_SIZE(pwm2_sel), CLK_SET_PARENT_GATE);
+       hws[IMX7D_PWM3_ROOT_SRC] = imx_clk_hw_mux2_flags("pwm3_src", base + 0xb600, 24, 3, pwm3_sel, ARRAY_SIZE(pwm3_sel), CLK_SET_PARENT_GATE);
+       hws[IMX7D_PWM4_ROOT_SRC] = imx_clk_hw_mux2_flags("pwm4_src", base + 0xb680, 24, 3, pwm4_sel, ARRAY_SIZE(pwm4_sel), CLK_SET_PARENT_GATE);
+       hws[IMX7D_FLEXTIMER1_ROOT_SRC] = imx_clk_hw_mux2_flags("flextimer1_src", base + 0xb700, 24, 3, flextimer1_sel, ARRAY_SIZE(flextimer1_sel), CLK_SET_PARENT_GATE);
+       hws[IMX7D_FLEXTIMER2_ROOT_SRC] = imx_clk_hw_mux2_flags("flextimer2_src", base + 0xb780, 24, 3, flextimer2_sel, ARRAY_SIZE(flextimer2_sel), CLK_SET_PARENT_GATE);
+       hws[IMX7D_SIM1_ROOT_SRC] = imx_clk_hw_mux2_flags("sim1_src", base + 0xb800, 24, 3, sim1_sel, ARRAY_SIZE(sim1_sel), CLK_SET_PARENT_GATE);
+       hws[IMX7D_SIM2_ROOT_SRC] = imx_clk_hw_mux2_flags("sim2_src", base + 0xb880, 24, 3, sim2_sel, ARRAY_SIZE(sim2_sel), CLK_SET_PARENT_GATE);
+       hws[IMX7D_GPT1_ROOT_SRC] = imx_clk_hw_mux2_flags("gpt1_src", base + 0xb900, 24, 3, gpt1_sel, ARRAY_SIZE(gpt1_sel), CLK_SET_PARENT_GATE);
+       hws[IMX7D_GPT2_ROOT_SRC] = imx_clk_hw_mux2_flags("gpt2_src", base + 0xb980, 24, 3, gpt2_sel, ARRAY_SIZE(gpt2_sel), CLK_SET_PARENT_GATE);
+       hws[IMX7D_GPT3_ROOT_SRC] = imx_clk_hw_mux2_flags("gpt3_src", base + 0xba00, 24, 3, gpt3_sel, ARRAY_SIZE(gpt3_sel), CLK_SET_PARENT_GATE);
+       hws[IMX7D_GPT4_ROOT_SRC] = imx_clk_hw_mux2_flags("gpt4_src", base + 0xba80, 24, 3, gpt4_sel, ARRAY_SIZE(gpt4_sel), CLK_SET_PARENT_GATE);
+       hws[IMX7D_TRACE_ROOT_SRC] = imx_clk_hw_mux2_flags("trace_src", base + 0xbb00, 24, 3, trace_sel, ARRAY_SIZE(trace_sel), CLK_SET_PARENT_GATE);
+       hws[IMX7D_WDOG_ROOT_SRC] = imx_clk_hw_mux2_flags("wdog_src", base + 0xbb80, 24, 3, wdog_sel, ARRAY_SIZE(wdog_sel), CLK_SET_PARENT_GATE);
+       hws[IMX7D_CSI_MCLK_ROOT_SRC] = imx_clk_hw_mux2_flags("csi_mclk_src", base + 0xbc00, 24, 3, csi_mclk_sel, ARRAY_SIZE(csi_mclk_sel), CLK_SET_PARENT_GATE);
+       hws[IMX7D_AUDIO_MCLK_ROOT_SRC] = imx_clk_hw_mux2_flags("audio_mclk_src", base + 0xbc80, 24, 3, audio_mclk_sel, ARRAY_SIZE(audio_mclk_sel), CLK_SET_PARENT_GATE);
+       hws[IMX7D_WRCLK_ROOT_SRC] = imx_clk_hw_mux2_flags("wrclk_src", base + 0xbd00, 24, 3, wrclk_sel, ARRAY_SIZE(wrclk_sel), CLK_SET_PARENT_GATE);
+       hws[IMX7D_CLKO1_ROOT_SRC] = imx_clk_hw_mux2_flags("clko1_src", base + 0xbd80, 24, 3, clko1_sel, ARRAY_SIZE(clko1_sel), CLK_SET_PARENT_GATE);
+       hws[IMX7D_CLKO2_ROOT_SRC] = imx_clk_hw_mux2_flags("clko2_src", base + 0xbe00, 24, 3, clko2_sel, ARRAY_SIZE(clko2_sel), CLK_SET_PARENT_GATE);
 
        hws[IMX7D_ARM_A7_ROOT_CG] = imx_clk_hw_gate3("arm_a7_cg", "arm_a7_src", base + 0x8000, 28);
        hws[IMX7D_ARM_M4_ROOT_CG] = imx_clk_hw_gate3("arm_m4_cg", "arm_m4_src", base + 0x8080, 28);
index b793264..0de0be0 100644 (file)
@@ -657,3 +657,7 @@ static struct platform_driver imx8mm_clk_driver = {
        },
 };
 module_platform_driver(imx8mm_clk_driver);
+
+MODULE_AUTHOR("Bai Ping <ping.bai@nxp.com>");
+MODULE_DESCRIPTION("NXP i.MX8MM clock driver");
+MODULE_LICENSE("GPL v2");
index 213cc37..e984de5 100644 (file)
@@ -608,3 +608,7 @@ static struct platform_driver imx8mn_clk_driver = {
        },
 };
 module_platform_driver(imx8mn_clk_driver);
+
+MODULE_AUTHOR("Anson Huang <Anson.Huang@nxp.com>");
+MODULE_DESCRIPTION("NXP i.MX8MN clock driver");
+MODULE_LICENSE("GPL v2");
index ca74771..12ce477 100644 (file)
@@ -152,10 +152,6 @@ static const char * const imx8mp_can2_sels[] = {"osc_24m", "sys_pll2_200m", "sys
                                                "sys_pll1_160m", "sys_pll1_800m", "sys_pll3_out",
                                                "sys_pll2_250m", "audio_pll2_out", };
 
-static const char * const imx8mp_memrepair_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m",
-                                                    "sys_pll3_out", "audio_pll1_out", "video_pll1_out",
-                                                    "audio_pll2_out", "sys_pll1_133m", };
-
 static const char * const imx8mp_pcie_phy_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll2_500m",
                                                    "clk_ext1", "clk_ext2", "clk_ext3",
                                                    "clk_ext4", "sys_pll1_400m", };
@@ -375,15 +371,14 @@ static const char * const imx8mp_media_cam2_pix_sels[] = {"osc_24m", "sys_pll1_2
                                                          "sys_pll3_out", "audio_pll2_out",
                                                          "video_pll1_out", };
 
-static const char * const imx8mp_media_mipi_phy2_ref_sels[] = {"osc_24m", "sys_pll2_333m", "sys_pll2_100m",
-                                                              "sys_pll1_800m", "sys_pll2_1000m",
-                                                              "clk_ext2", "audio_pll2_out",
-                                                              "video_pll1_out", };
+static const char * const imx8mp_media_ldb_sels[] = {"osc_24m", "sys_pll2_333m", "sys_pll2_100m",
+                                                    "sys_pll1_800m", "sys_pll2_1000m",
+                                                    "clk_ext2", "audio_pll2_out",
+                                                    "video_pll1_out", };
 
-static const char * const imx8mp_media_mipi_csi2_esc_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_80m",
-                                                              "sys_pll1_800m", "sys_pll2_1000m",
-                                                              "sys_pll3_out", "clk_ext3",
-                                                              "audio_pll2_out", };
+static const char * const imx8mp_memrepair_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_80m",
+                                                       "sys_pll1_800m", "sys_pll2_1000m", "sys_pll3_out",
+                                                       "clk_ext3", "audio_pll2_out", };
 
 static const char * const imx8mp_pcie2_ctrl_sels[] = {"osc_24m", "sys_pll2_250m", "sys_pll2_200m",
                                                      "sys_pll1_266m", "sys_pll1_800m", "sys_pll2_500m",
@@ -590,7 +585,6 @@ static int imx8mp_clocks_probe(struct platform_device *pdev)
        hws[IMX8MP_CLK_VPU_G2] = imx8m_clk_hw_composite("vpu_g2", imx8mp_vpu_g2_sels, ccm_base + 0xa180);
        hws[IMX8MP_CLK_CAN1] = imx8m_clk_hw_composite("can1", imx8mp_can1_sels, ccm_base + 0xa200);
        hws[IMX8MP_CLK_CAN2] = imx8m_clk_hw_composite("can2", imx8mp_can2_sels, ccm_base + 0xa280);
-       hws[IMX8MP_CLK_MEMREPAIR] = imx8m_clk_hw_composite("memrepair", imx8mp_memrepair_sels, ccm_base + 0xa300);
        hws[IMX8MP_CLK_PCIE_PHY] = imx8m_clk_hw_composite("pcie_phy", imx8mp_pcie_phy_sels, ccm_base + 0xa380);
        hws[IMX8MP_CLK_PCIE_AUX] = imx8m_clk_hw_composite("pcie_aux", imx8mp_pcie_aux_sels, ccm_base + 0xa400);
        hws[IMX8MP_CLK_I2C5] = imx8m_clk_hw_composite("i2c5", imx8mp_i2c5_sels, ccm_base + 0xa480);
@@ -647,8 +641,8 @@ static int imx8mp_clocks_probe(struct platform_device *pdev)
        hws[IMX8MP_CLK_MEDIA_MIPI_PHY1_REF] = imx8m_clk_hw_composite("media_mipi_phy1_ref", imx8mp_media_mipi_phy1_ref_sels, ccm_base + 0xbd80);
        hws[IMX8MP_CLK_MEDIA_DISP1_PIX] = imx8m_clk_hw_composite("media_disp1_pix", imx8mp_media_disp1_pix_sels, ccm_base + 0xbe00);
        hws[IMX8MP_CLK_MEDIA_CAM2_PIX] = imx8m_clk_hw_composite("media_cam2_pix", imx8mp_media_cam2_pix_sels, ccm_base + 0xbe80);
-       hws[IMX8MP_CLK_MEDIA_MIPI_PHY2_REF] = imx8m_clk_hw_composite("media_mipi_phy2_ref", imx8mp_media_mipi_phy2_ref_sels, ccm_base + 0xbf00);
-       hws[IMX8MP_CLK_MEDIA_MIPI_CSI2_ESC] = imx8m_clk_hw_composite("media_mipi_csi2_esc", imx8mp_media_mipi_csi2_esc_sels, ccm_base + 0xbf80);
+       hws[IMX8MP_CLK_MEDIA_LDB] = imx8m_clk_hw_composite("media_ldb", imx8mp_media_ldb_sels, ccm_base + 0xbf00);
+       hws[IMX8MP_CLK_MEMREPAIR] = imx8m_clk_hw_composite_critical("mem_repair", imx8mp_memrepair_sels, ccm_base + 0xbf80);
        hws[IMX8MP_CLK_PCIE2_CTRL] = imx8m_clk_hw_composite("pcie2_ctrl", imx8mp_pcie2_ctrl_sels, ccm_base + 0xc000);
        hws[IMX8MP_CLK_PCIE2_PHY] = imx8m_clk_hw_composite("pcie2_phy", imx8mp_pcie2_phy_sels, ccm_base + 0xc080);
        hws[IMX8MP_CLK_MEDIA_MIPI_TEST_BYTE] = imx8m_clk_hw_composite("media_mipi_test_byte", imx8mp_media_mipi_test_byte_sels, ccm_base + 0xc100);
@@ -773,3 +767,7 @@ static struct platform_driver imx8mp_clk_driver = {
        },
 };
 module_platform_driver(imx8mp_clk_driver);
+
+MODULE_AUTHOR("Anson Huang <Anson.Huang@nxp.com>");
+MODULE_DESCRIPTION("NXP i.MX8MP clock driver");
+MODULE_LICENSE("GPL v2");
index a64aace..8265d1d 100644 (file)
@@ -157,10 +157,10 @@ static const char * const imx8mq_qspi_sels[] = {"osc_25m", "sys1_pll_400m", "sys
                                         "audio_pll2_out", "sys1_pll_266m", "sys3_pll_out", "sys1_pll_100m", };
 
 static const char * const imx8mq_usdhc1_sels[] = {"osc_25m", "sys1_pll_400m", "sys1_pll_800m", "sys2_pll_500m",
-                                        "audio_pll2_out", "sys1_pll_266m", "sys3_pll_out", "sys1_pll_100m", };
+                                        "sys3_pll_out", "sys1_pll_266m", "audio_pll2_out", "sys1_pll_100m", };
 
 static const char * const imx8mq_usdhc2_sels[] = {"osc_25m", "sys1_pll_400m", "sys1_pll_800m", "sys2_pll_500m",
-                                        "audio_pll2_out", "sys1_pll_266m", "sys3_pll_out", "sys1_pll_100m", };
+                                        "sys3_pll_out", "sys1_pll_266m", "audio_pll2_out", "sys1_pll_100m", };
 
 static const char * const imx8mq_i2c1_sels[] = {"osc_25m", "sys1_pll_160m", "sys2_pll_50m", "sys3_pll_out", "audio_pll1_out",
                                         "video_pll1_out", "audio_pll2_out", "sys1_pll_133m", };
@@ -643,3 +643,7 @@ static struct platform_driver imx8mq_clk_driver = {
        },
 };
 module_platform_driver(imx8mq_clk_driver);
+
+MODULE_AUTHOR("Abel Vesa <abel.vesa@nxp.com>");
+MODULE_DESCRIPTION("NXP i.MX8MQ clock driver");
+MODULE_LICENSE("GPL v2");
index 04c8ee3..e947a70 100644 (file)
@@ -232,3 +232,7 @@ static struct platform_driver imx8qxp_lpcg_clk_driver = {
 };
 
 builtin_platform_driver(imx8qxp_lpcg_clk_driver);
+
+MODULE_AUTHOR("Aisheng Dong <aisheng.dong@nxp.com>");
+MODULE_DESCRIPTION("NXP i.MX8QXP LPCG clock driver");
+MODULE_LICENSE("GPL v2");
index 5e2903e..d650ca3 100644 (file)
@@ -152,3 +152,7 @@ static struct platform_driver imx8qxp_clk_driver = {
        .probe = imx8qxp_clk_probe,
 };
 builtin_platform_driver(imx8qxp_clk_driver);
+
+MODULE_AUTHOR("Aisheng Dong <aisheng.dong@nxp.com>");
+MODULE_DESCRIPTION("NXP i.MX8QXP clock driver");
+MODULE_LICENSE("GPL v2");
index a73a799..1f0e44f 100644 (file)
@@ -4,6 +4,7 @@
  *     Dong Aisheng <aisheng.dong@nxp.com>
  */
 
+#include <linux/bits.h>
 #include <linux/clk-provider.h>
 #include <linux/err.h>
 #include <linux/io.h>
index 50b7c30..5d2a9a3 100644 (file)
@@ -12,7 +12,7 @@
 
 /**
  * struct clk_pfd - IMX PFD clock
- * @clk_hw:    clock source
+ * @hw:                clock source
  * @reg:       PFD register address
  * @idx:       the index of PFD encoded in the register
  *
index 78e1f76..6b744c8 100644 (file)
@@ -17,7 +17,7 @@
 
 /**
  * struct clk_pfdv2 - IMX PFD clock
- * @clk_hw:    clock source
+ * @hw:                clock source
  * @reg:       PFD register address
  * @gate_bit:  Gate bit offset
  * @vld_bit:   Valid bit offset
index f9eb189..aba36e4 100644 (file)
@@ -3,9 +3,10 @@
  * Copyright 2017-2018 NXP.
  */
 
-#include <linux/bitops.h>
+#include <linux/bits.h>
 #include <linux/clk-provider.h>
 #include <linux/err.h>
+#include <linux/export.h>
 #include <linux/io.h>
 #include <linux/iopoll.h>
 #include <linux/slab.h>
@@ -68,6 +69,7 @@ struct imx_pll14xx_clk imx_1443x_pll = {
        .rate_table = imx_pll1443x_tbl,
        .rate_count = ARRAY_SIZE(imx_pll1443x_tbl),
 };
+EXPORT_SYMBOL_GPL(imx_1443x_pll);
 
 struct imx_pll14xx_clk imx_1443x_dram_pll = {
        .type = PLL_1443X,
@@ -75,12 +77,14 @@ struct imx_pll14xx_clk imx_1443x_dram_pll = {
        .rate_count = ARRAY_SIZE(imx_pll1443x_tbl),
        .flags = CLK_GET_RATE_NOCACHE,
 };
+EXPORT_SYMBOL_GPL(imx_1443x_dram_pll);
 
 struct imx_pll14xx_clk imx_1416x_pll = {
        .type = PLL_1416X,
        .rate_table = imx_pll1416x_tbl,
        .rate_count = ARRAY_SIZE(imx_pll1416x_tbl),
 };
+EXPORT_SYMBOL_GPL(imx_1416x_pll);
 
 static const struct imx_pll14xx_rate_table *imx_get_pll_settings(
                struct clk_pll14xx *pll, unsigned long rate)
@@ -436,3 +440,4 @@ struct clk_hw *imx_dev_clk_hw_pll14xx(struct device *dev, const char *name,
 
        return hw;
 }
+EXPORT_SYMBOL_GPL(imx_dev_clk_hw_pll14xx);
index de4f8a4..36ffb05 100644 (file)
@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: GPL-2.0
+#include <linux/bits.h>
 #include <linux/clk-provider.h>
 #include <linux/io.h>
 #include <linux/slab.h>
index b20cdea..20ee961 100644 (file)
 
 /**
  * struct clk_pllv3 - IMX PLL clock version 3
- * @clk_hw:     clock source
+ * @hw:                clock source
  * @base:       base address of PLL registers
  * @power_bit:  pll power bit mask
  * @powerup_set: set power_bit to power up the PLL
  * @div_mask:   mask of divider bits
  * @div_shift:  shift of divider bits
+ * @ref_clock: reference clock rate
+ * @num_offset:        num register offset
+ * @denom_offset: denom register offset
  *
  * IMX PLL clock version 3, found on i.MX6 series.  Divider for pllv3
  * is actually a multiplier, and always sits at bit 0.
index a494504..8ec703f 100644 (file)
@@ -7,6 +7,7 @@
  *
  */
 
+#include <linux/bits.h>
 #include <linux/clk-provider.h>
 #include <linux/err.h>
 #include <linux/io.h>
index 773d8a5..9d6cdff 100644 (file)
@@ -10,6 +10,7 @@
 
 #include <linux/clk-provider.h>
 #include <linux/err.h>
+#include <linux/export.h>
 #include <linux/io.h>
 #include <linux/iopoll.h>
 #include <linux/slab.h>
@@ -537,3 +538,4 @@ struct clk_hw *imx_clk_hw_sscg_pll(const char *name,
 
        return hw;
 }
+EXPORT_SYMBOL_GPL(imx_clk_hw_sscg_pll);
index 5129ef8..9e11f1c 100644 (file)
@@ -4,6 +4,7 @@
  */
 
 #include <linux/of_address.h>
+#include <linux/bits.h>
 #include <linux/clk.h>
 #include <linux/syscore_ops.h>
 #include <dt-bindings/clock/vf610-clock.h>
@@ -328,6 +329,7 @@ static void __init vf610_clocks_init(struct device_node *ccm_node)
        clk[VF610_CLK_DSPI2] = imx_clk_gate2("dspi2", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(12));
        clk[VF610_CLK_DSPI3] = imx_clk_gate2("dspi3", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(13));
 
+       clk[VF610_CLK_CRC] = imx_clk_gate2("crc", "ipg_bus", CCM_CCGR1, CCM_CCGRx_CGn(3));
        clk[VF610_CLK_WDT] = imx_clk_gate2("wdt", "ipg_bus", CCM_CCGR1, CCM_CCGRx_CGn(14));
 
        clk[VF610_CLK_ESDHC0_SEL] = imx_clk_mux("esdhc0_sel", CCM_CSCMR1, 16, 2, esdhc_sels, 4);
index 87ab8db..47882c5 100644 (file)
@@ -1,8 +1,10 @@
 // SPDX-License-Identifier: GPL-2.0
+#include <linux/bits.h>
 #include <linux/clk.h>
 #include <linux/clk-provider.h>
 #include <linux/err.h>
 #include <linux/io.h>
+#include <linux/module.h>
 #include <linux/of.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
@@ -13,6 +15,7 @@
 #define CCDR_MMDC_CH1_MASK             BIT(16)
 
 DEFINE_SPINLOCK(imx_ccm_lock);
+EXPORT_SYMBOL_GPL(imx_ccm_lock);
 
 void imx_unregister_clocks(struct clk *clks[], unsigned int count)
 {
@@ -29,8 +32,9 @@ void imx_unregister_hw_clocks(struct clk_hw *hws[], unsigned int count)
        for (i = 0; i < count; i++)
                clk_hw_unregister(hws[i]);
 }
+EXPORT_SYMBOL_GPL(imx_unregister_hw_clocks);
 
-void __init imx_mmdc_mask_handshake(void __iomem *ccm_base,
+void imx_mmdc_mask_handshake(void __iomem *ccm_base,
                                    unsigned int chn)
 {
        unsigned int reg;
@@ -59,8 +63,9 @@ void imx_check_clk_hws(struct clk_hw *clks[], unsigned int count)
                        pr_err("i.MX clk %u: register failed with %ld\n",
                               i, PTR_ERR(clks[i]));
 }
+EXPORT_SYMBOL_GPL(imx_check_clk_hws);
 
-static struct clk * __init imx_obtain_fixed_clock_from_dt(const char *name)
+static struct clk *imx_obtain_fixed_clock_from_dt(const char *name)
 {
        struct of_phandle_args phandle;
        struct clk *clk = ERR_PTR(-ENODEV);
@@ -80,7 +85,7 @@ static struct clk * __init imx_obtain_fixed_clock_from_dt(const char *name)
        return clk;
 }
 
-struct clk * __init imx_obtain_fixed_clock(
+struct clk *imx_obtain_fixed_clock(
                        const char *name, unsigned long rate)
 {
        struct clk *clk;
@@ -91,7 +96,7 @@ struct clk * __init imx_obtain_fixed_clock(
        return clk;
 }
 
-struct clk_hw * __init imx_obtain_fixed_clock_hw(
+struct clk_hw *imx_obtain_fixed_clock_hw(
                        const char *name, unsigned long rate)
 {
        struct clk *clk;
@@ -113,6 +118,7 @@ struct clk_hw * imx_obtain_fixed_clk_hw(struct device_node *np,
 
        return __clk_get_hw(clk);
 }
+EXPORT_SYMBOL_GPL(imx_obtain_fixed_clk_hw);
 
 /*
  * This fixups the register CCM_CSCMR1 write value.
@@ -140,6 +146,7 @@ void imx_cscmr1_fixup(u32 *val)
        return;
 }
 
+#ifndef MODULE
 static int imx_keep_uart_clocks;
 static struct clk ** const *imx_uart_clocks;
 
@@ -177,3 +184,6 @@ static int __init imx_clk_disable_uart(void)
        return 0;
 }
 late_initcall_sync(imx_clk_disable_uart);
+#endif
+
+MODULE_LICENSE("GPL v2");
index 16adbc3..3b796b3 100644 (file)
@@ -2,6 +2,7 @@
 #ifndef __MACH_IMX_CLK_H
 #define __MACH_IMX_CLK_H
 
+#include <linux/bits.h>
 #include <linux/spinlock.h>
 #include <linux/clk-provider.h>
 
@@ -11,7 +12,13 @@ extern spinlock_t imx_ccm_lock;
 
 void imx_check_clocks(struct clk *clks[], unsigned int count);
 void imx_check_clk_hws(struct clk_hw *clks[], unsigned int count);
+#ifndef MODULE
 void imx_register_uart_clocks(struct clk ** const clks[]);
+#else
+static inline void imx_register_uart_clocks(struct clk ** const clks[])
+{
+}
+#endif
 void imx_mmdc_mask_handshake(void __iomem *ccm_base, unsigned int chn);
 void imx_unregister_clocks(struct clk *clks[], unsigned int count);
 void imx_unregister_hw_clocks(struct clk_hw *hws[], unsigned int count);
index d7981b6..dac6edc 100644 (file)
 #include <linux/clkdev.h>
 #include <linux/delay.h>
 #include <linux/io.h>
+#include <linux/iopoll.h>
 #include <linux/math64.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
+#include <linux/time.h>
+
 #include "cgu.h"
 
 #define MHZ (1000 * 1000)
 
+static inline const struct ingenic_cgu_clk_info *
+to_clk_info(struct ingenic_clk *clk)
+{
+       return &clk->cgu->clock_info[clk->idx];
+}
+
 /**
  * ingenic_cgu_gate_get() - get the value of clock gate register bit
  * @cgu: reference to the CGU whose registers should be read
@@ -71,14 +80,13 @@ static unsigned long
 ingenic_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
 {
        struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
+       const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk);
        struct ingenic_cgu *cgu = ingenic_clk->cgu;
-       const struct ingenic_cgu_clk_info *clk_info;
        const struct ingenic_cgu_pll_info *pll_info;
        unsigned m, n, od_enc, od;
        bool bypass;
        u32 ctl;
 
-       clk_info = &cgu->clock_info[ingenic_clk->idx];
        BUG_ON(clk_info->type != CGU_CLK_PLL);
        pll_info = &clk_info->pll;
 
@@ -144,18 +152,6 @@ ingenic_pll_calc(const struct ingenic_cgu_clk_info *clk_info,
                n * od);
 }
 
-static inline const struct ingenic_cgu_clk_info *to_clk_info(
-               struct ingenic_clk *ingenic_clk)
-{
-       struct ingenic_cgu *cgu = ingenic_clk->cgu;
-       const struct ingenic_cgu_clk_info *clk_info;
-
-       clk_info = &cgu->clock_info[ingenic_clk->idx];
-       BUG_ON(clk_info->type != CGU_CLK_PLL);
-
-       return clk_info;
-}
-
 static long
 ingenic_pll_round_rate(struct clk_hw *hw, unsigned long req_rate,
                       unsigned long *prate)
@@ -166,6 +162,16 @@ ingenic_pll_round_rate(struct clk_hw *hw, unsigned long req_rate,
        return ingenic_pll_calc(clk_info, req_rate, *prate, NULL, NULL, NULL);
 }
 
+static inline int ingenic_pll_check_stable(struct ingenic_cgu *cgu,
+                                          const struct ingenic_cgu_pll_info *pll_info)
+{
+       u32 ctl;
+
+       return readl_poll_timeout(cgu->base + pll_info->reg, ctl,
+                                 ctl & BIT(pll_info->stable_bit),
+                                 0, 100 * USEC_PER_MSEC);
+}
+
 static int
 ingenic_pll_set_rate(struct clk_hw *hw, unsigned long req_rate,
                     unsigned long parent_rate)
@@ -176,6 +182,7 @@ ingenic_pll_set_rate(struct clk_hw *hw, unsigned long req_rate,
        const struct ingenic_cgu_pll_info *pll_info = &clk_info->pll;
        unsigned long rate, flags;
        unsigned int m, n, od;
+       int ret = 0;
        u32 ctl;
 
        rate = ingenic_pll_calc(clk_info, req_rate, parent_rate,
@@ -197,9 +204,14 @@ ingenic_pll_set_rate(struct clk_hw *hw, unsigned long req_rate,
        ctl |= pll_info->od_encoding[od - 1] << pll_info->od_shift;
 
        writel(ctl, cgu->base + pll_info->reg);
+
+       /* If the PLL is enabled, verify that it's stable */
+       if (ctl & BIT(pll_info->enable_bit))
+               ret = ingenic_pll_check_stable(cgu, pll_info);
+
        spin_unlock_irqrestore(&cgu->lock, flags);
 
-       return 0;
+       return ret;
 }
 
 static int ingenic_pll_enable(struct clk_hw *hw)
@@ -208,9 +220,8 @@ static int ingenic_pll_enable(struct clk_hw *hw)
        struct ingenic_cgu *cgu = ingenic_clk->cgu;
        const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk);
        const struct ingenic_cgu_pll_info *pll_info = &clk_info->pll;
-       const unsigned int timeout = 100;
        unsigned long flags;
-       unsigned int i;
+       int ret;
        u32 ctl;
 
        spin_lock_irqsave(&cgu->lock, flags);
@@ -226,20 +237,10 @@ static int ingenic_pll_enable(struct clk_hw *hw)
 
        writel(ctl, cgu->base + pll_info->reg);
 
-       /* wait for the PLL to stabilise */
-       for (i = 0; i < timeout; i++) {
-               ctl = readl(cgu->base + pll_info->reg);
-               if (ctl & BIT(pll_info->stable_bit))
-                       break;
-               mdelay(1);
-       }
-
+       ret = ingenic_pll_check_stable(cgu, pll_info);
        spin_unlock_irqrestore(&cgu->lock, flags);
 
-       if (i == timeout)
-               return -EBUSY;
-
-       return 0;
+       return ret;
 }
 
 static void ingenic_pll_disable(struct clk_hw *hw)
@@ -290,13 +291,11 @@ static const struct clk_ops ingenic_pll_ops = {
 static u8 ingenic_clk_get_parent(struct clk_hw *hw)
 {
        struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
+       const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk);
        struct ingenic_cgu *cgu = ingenic_clk->cgu;
-       const struct ingenic_cgu_clk_info *clk_info;
        u32 reg;
        u8 i, hw_idx, idx = 0;
 
-       clk_info = &cgu->clock_info[ingenic_clk->idx];
-
        if (clk_info->type & CGU_CLK_MUX) {
                reg = readl(cgu->base + clk_info->mux.reg);
                hw_idx = (reg >> clk_info->mux.shift) &
@@ -318,14 +317,12 @@ static u8 ingenic_clk_get_parent(struct clk_hw *hw)
 static int ingenic_clk_set_parent(struct clk_hw *hw, u8 idx)
 {
        struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
+       const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk);
        struct ingenic_cgu *cgu = ingenic_clk->cgu;
-       const struct ingenic_cgu_clk_info *clk_info;
        unsigned long flags;
        u8 curr_idx, hw_idx, num_poss;
        u32 reg, mask;
 
-       clk_info = &cgu->clock_info[ingenic_clk->idx];
-
        if (clk_info->type & CGU_CLK_MUX) {
                /*
                 * Convert the parent index to the hardware index by adding
@@ -368,13 +365,11 @@ static unsigned long
 ingenic_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
 {
        struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
+       const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk);
        struct ingenic_cgu *cgu = ingenic_clk->cgu;
-       const struct ingenic_cgu_clk_info *clk_info;
        unsigned long rate = parent_rate;
        u32 div_reg, div;
 
-       clk_info = &cgu->clock_info[ingenic_clk->idx];
-
        if (clk_info->type & CGU_CLK_DIV) {
                div_reg = readl(cgu->base + clk_info->div.reg);
                div = (div_reg >> clk_info->div.shift) &
@@ -443,35 +438,41 @@ ingenic_clk_round_rate(struct clk_hw *hw, unsigned long req_rate,
                       unsigned long *parent_rate)
 {
        struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
-       struct ingenic_cgu *cgu = ingenic_clk->cgu;
-       const struct ingenic_cgu_clk_info *clk_info;
+       const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk);
        unsigned int div = 1;
 
-       clk_info = &cgu->clock_info[ingenic_clk->idx];
-
        if (clk_info->type & CGU_CLK_DIV)
                div = ingenic_clk_calc_div(clk_info, *parent_rate, req_rate);
        else if (clk_info->type & CGU_CLK_FIXDIV)
                div = clk_info->fixdiv.div;
+       else if (clk_hw_can_set_rate_parent(hw))
+               *parent_rate = req_rate;
 
        return DIV_ROUND_UP(*parent_rate, div);
 }
 
+static inline int ingenic_clk_check_stable(struct ingenic_cgu *cgu,
+                                          const struct ingenic_cgu_clk_info *clk_info)
+{
+       u32 reg;
+
+       return readl_poll_timeout(cgu->base + clk_info->div.reg, reg,
+                                 !(reg & BIT(clk_info->div.busy_bit)),
+                                 0, 100 * USEC_PER_MSEC);
+}
+
 static int
 ingenic_clk_set_rate(struct clk_hw *hw, unsigned long req_rate,
                     unsigned long parent_rate)
 {
        struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
+       const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk);
        struct ingenic_cgu *cgu = ingenic_clk->cgu;
-       const struct ingenic_cgu_clk_info *clk_info;
-       const unsigned timeout = 100;
        unsigned long rate, flags;
-       unsigned int hw_div, div, i;
+       unsigned int hw_div, div;
        u32 reg, mask;
        int ret = 0;
 
-       clk_info = &cgu->clock_info[ingenic_clk->idx];
-
        if (clk_info->type & CGU_CLK_DIV) {
                div = ingenic_clk_calc_div(clk_info, parent_rate, req_rate);
                rate = DIV_ROUND_UP(parent_rate, div);
@@ -504,16 +505,8 @@ ingenic_clk_set_rate(struct clk_hw *hw, unsigned long req_rate,
                writel(reg, cgu->base + clk_info->div.reg);
 
                /* wait for the change to take effect */
-               if (clk_info->div.busy_bit != -1) {
-                       for (i = 0; i < timeout; i++) {
-                               reg = readl(cgu->base + clk_info->div.reg);
-                               if (!(reg & BIT(clk_info->div.busy_bit)))
-                                       break;
-                               mdelay(1);
-                       }
-                       if (i == timeout)
-                               ret = -EBUSY;
-               }
+               if (clk_info->div.busy_bit != -1)
+                       ret = ingenic_clk_check_stable(cgu, clk_info);
 
                spin_unlock_irqrestore(&cgu->lock, flags);
                return ret;
@@ -525,12 +518,10 @@ ingenic_clk_set_rate(struct clk_hw *hw, unsigned long req_rate,
 static int ingenic_clk_enable(struct clk_hw *hw)
 {
        struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
+       const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk);
        struct ingenic_cgu *cgu = ingenic_clk->cgu;
-       const struct ingenic_cgu_clk_info *clk_info;
        unsigned long flags;
 
-       clk_info = &cgu->clock_info[ingenic_clk->idx];
-
        if (clk_info->type & CGU_CLK_GATE) {
                /* ungate the clock */
                spin_lock_irqsave(&cgu->lock, flags);
@@ -547,12 +538,10 @@ static int ingenic_clk_enable(struct clk_hw *hw)
 static void ingenic_clk_disable(struct clk_hw *hw)
 {
        struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
+       const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk);
        struct ingenic_cgu *cgu = ingenic_clk->cgu;
-       const struct ingenic_cgu_clk_info *clk_info;
        unsigned long flags;
 
-       clk_info = &cgu->clock_info[ingenic_clk->idx];
-
        if (clk_info->type & CGU_CLK_GATE) {
                /* gate the clock */
                spin_lock_irqsave(&cgu->lock, flags);
@@ -564,12 +553,10 @@ static void ingenic_clk_disable(struct clk_hw *hw)
 static int ingenic_clk_is_enabled(struct clk_hw *hw)
 {
        struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
+       const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk);
        struct ingenic_cgu *cgu = ingenic_clk->cgu;
-       const struct ingenic_cgu_clk_info *clk_info;
        int enabled = 1;
 
-       clk_info = &cgu->clock_info[ingenic_clk->idx];
-
        if (clk_info->type & CGU_CLK_GATE)
                enabled = !ingenic_cgu_gate_get(cgu, &clk_info->gate);
 
@@ -644,6 +631,13 @@ static int ingenic_register_clock(struct ingenic_cgu *cgu, unsigned idx)
 
        caps = clk_info->type;
 
+       if (caps & CGU_CLK_DIV) {
+               caps &= ~CGU_CLK_DIV;
+       } else if (!(caps & CGU_CLK_CUSTOM)) {
+               /* pass rate changes to the parent clock */
+               clk_init.flags |= CLK_SET_RATE_PARENT;
+       }
+
        if (caps & (CGU_CLK_MUX | CGU_CLK_CUSTOM)) {
                clk_init.num_parents = 0;
 
@@ -683,7 +677,6 @@ static int ingenic_register_clock(struct ingenic_cgu *cgu, unsigned idx)
                }
        } else if (caps & CGU_CLK_PLL) {
                clk_init.ops = &ingenic_pll_ops;
-               clk_init.flags |= CLK_SET_RATE_GATE;
 
                caps &= ~CGU_CLK_PLL;
 
@@ -706,13 +699,6 @@ static int ingenic_register_clock(struct ingenic_cgu *cgu, unsigned idx)
                caps &= ~(CGU_CLK_MUX | CGU_CLK_MUX_GLITCHFREE);
        }
 
-       if (caps & CGU_CLK_DIV) {
-               caps &= ~CGU_CLK_DIV;
-       } else {
-               /* pass rate changes to the parent clock */
-               clk_init.flags |= CLK_SET_RATE_PARENT;
-       }
-
        if (caps) {
                pr_err("%s: unknown clock type 0x%x\n", __func__, caps);
                goto out;
index 2ad26cb..aaf31ab 100644 (file)
@@ -54,6 +54,8 @@ struct sci_clk_provider {
  * @provider:   Master clock provider
  * @flags:      Flags for the clock
  * @node:       Link for handling clocks probed via DT
+ * @cached_req:         Cached requested freq for determine rate calls
+ * @cached_res:         Cached result freq for determine rate calls
  */
 struct sci_clk {
        struct clk_hw hw;
@@ -63,6 +65,8 @@ struct sci_clk {
        struct sci_clk_provider *provider;
        u8 flags;
        struct list_head node;
+       unsigned long cached_req;
+       unsigned long cached_res;
 };
 
 #define to_sci_clk(_hw) container_of(_hw, struct sci_clk, hw)
@@ -175,6 +179,11 @@ static int sci_clk_determine_rate(struct clk_hw *hw,
        int ret;
        u64 new_rate;
 
+       if (clk->cached_req && clk->cached_req == req->rate) {
+               req->rate = clk->cached_res;
+               return 0;
+       }
+
        ret = clk->provider->ops->get_best_match_freq(clk->provider->sci,
                                                      clk->dev_id,
                                                      clk->clk_id,
@@ -189,6 +198,9 @@ static int sci_clk_determine_rate(struct clk_hw *hw,
                return ret;
        }
 
+       clk->cached_req = req->rate;
+       clk->cached_res = new_rate;
+
        req->rate = new_rate;
 
        return 0;
@@ -209,7 +221,8 @@ static int sci_clk_set_rate(struct clk_hw *hw, unsigned long rate,
        struct sci_clk *clk = to_sci_clk(hw);
 
        return clk->provider->ops->set_freq(clk->provider->sci, clk->dev_id,
-                                           clk->clk_id, rate, rate, rate);
+                                           clk->clk_id, rate / 10 * 9, rate,
+                                           rate / 10 * 11);
 }
 
 /**
@@ -249,6 +262,8 @@ static int sci_clk_set_parent(struct clk_hw *hw, u8 index)
 {
        struct sci_clk *clk = to_sci_clk(hw);
 
+       clk->cached_req = 0;
+
        return clk->provider->ops->set_parent(clk->provider->sci, clk->dev_id,
                                              clk->clk_id,
                                              index + 1 + clk->clk_id);
@@ -522,7 +537,7 @@ static int ti_sci_scan_clocks_from_dt(struct sci_clk_provider *provider)
                np = of_find_node_with_property(np, *clk_name);
                if (!np) {
                        clk_name++;
-                       break;
+                       continue;
                }
 
                if (!of_device_is_available(np))
index 89ceb2f..ce84750 100644 (file)
@@ -352,6 +352,54 @@ config COMMON_CLK_MT8135
        help
          This driver supports MediaTek MT8135 clocks.
 
+config COMMON_CLK_MT8167
+       bool "Clock driver for MediaTek MT8167"
+       depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST
+       select COMMON_CLK_MEDIATEK
+       default ARCH_MEDIATEK
+       help
+         This driver supports MediaTek MT8167 basic clocks.
+
+config COMMON_CLK_MT8167_AUDSYS
+       bool "Clock driver for MediaTek MT8167 audsys"
+       depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST
+       select COMMON_CLK_MEDIATEK
+       default ARCH_MEDIATEK
+       help
+         This driver supports MediaTek MT8167 audsys clocks.
+
+config COMMON_CLK_MT8167_IMGSYS
+       bool "Clock driver for MediaTek MT8167 imgsys"
+       depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST
+       select COMMON_CLK_MEDIATEK
+       default ARCH_MEDIATEK
+       help
+         This driver supports MediaTek MT8167 imgsys clocks.
+
+config COMMON_CLK_MT8167_MFGCFG
+       bool "Clock driver for MediaTek MT8167 mfgcfg"
+       depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST
+       select COMMON_CLK_MEDIATEK
+       default ARCH_MEDIATEK
+       help
+         This driver supports MediaTek MT8167 mfgcfg clocks.
+
+config COMMON_CLK_MT8167_MMSYS
+       bool "Clock driver for MediaTek MT8167 mmsys"
+       depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST
+       select COMMON_CLK_MEDIATEK
+       default ARCH_MEDIATEK
+       help
+         This driver supports MediaTek MT8167 mmsys clocks.
+
+config COMMON_CLK_MT8167_VDECSYS
+       bool "Clock driver for MediaTek MT8167 vdecsys"
+       depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST
+       select COMMON_CLK_MEDIATEK
+       default ARCH_MEDIATEK
+       help
+         This driver supports MediaTek MT8167 vdecsys clocks.
+
 config COMMON_CLK_MT8173
        bool "Clock driver for MediaTek MT8173"
        depends on ARCH_MEDIATEK || COMPILE_TEST
index 959b556..3b0c2be 100644 (file)
@@ -47,6 +47,12 @@ obj-$(CONFIG_COMMON_CLK_MT7629) += clk-mt7629.o
 obj-$(CONFIG_COMMON_CLK_MT7629_ETHSYS) += clk-mt7629-eth.o
 obj-$(CONFIG_COMMON_CLK_MT7629_HIFSYS) += clk-mt7629-hif.o
 obj-$(CONFIG_COMMON_CLK_MT8135) += clk-mt8135.o
+obj-$(CONFIG_COMMON_CLK_MT8167) += clk-mt8167.o
+obj-$(CONFIG_COMMON_CLK_MT8167_AUDSYS) += clk-mt8167-aud.o
+obj-$(CONFIG_COMMON_CLK_MT8167_IMGSYS) += clk-mt8167-img.o
+obj-$(CONFIG_COMMON_CLK_MT8167_MFGCFG) += clk-mt8167-mfgcfg.o
+obj-$(CONFIG_COMMON_CLK_MT8167_MMSYS) += clk-mt8167-mm.o
+obj-$(CONFIG_COMMON_CLK_MT8167_VDECSYS) += clk-mt8167-vdec.o
 obj-$(CONFIG_COMMON_CLK_MT8173) += clk-mt8173.o
 obj-$(CONFIG_COMMON_CLK_MT8173_MMSYS) += clk-mt8173-mm.o
 obj-$(CONFIG_COMMON_CLK_MT8183) += clk-mt8183.o
index db8db1b..d77ea5a 100644 (file)
@@ -909,7 +909,6 @@ static struct platform_driver clk_mt6765_drv = {
        .probe = clk_mt6765_probe,
        .driver = {
                .name = "clk-mt6765",
-               .owner = THIS_MODULE,
                .of_match_table = of_match_clk_mt6765,
        },
 };
index 9766ccc..6e0d3a1 100644 (file)
@@ -919,6 +919,8 @@ static const struct mtk_gate infra_clks[] = {
                    "pwm_sel", 19),
        GATE_INFRA0(CLK_INFRA_PWM, "infra_pwm",
                    "pwm_sel", 21),
+       GATE_INFRA0(CLK_INFRA_UART0, "infra_uart0",
+                   "uart_sel", 22),
        GATE_INFRA0(CLK_INFRA_UART1, "infra_uart1",
                    "uart_sel", 23),
        GATE_INFRA0(CLK_INFRA_UART2, "infra_uart2",
index f35389a..428eb24 100644 (file)
@@ -582,7 +582,7 @@ CLK_OF_DECLARE_DRIVER(mtk_infra, "mediatek,mt6797-infracfg",
 
 static int mtk_infrasys_init(struct platform_device *pdev)
 {
-       int r, i;
+       int i;
        struct device_node *node = pdev->dev.of_node;
 
        if (!infra_clk_data) {
@@ -599,11 +599,7 @@ static int mtk_infrasys_init(struct platform_device *pdev)
        mtk_clk_register_factors(infra_fixed_divs, ARRAY_SIZE(infra_fixed_divs),
                                 infra_clk_data);
 
-       r = of_clk_add_provider(node, of_clk_src_onecell_get, infra_clk_data);
-       if (r)
-               return r;
-
-       return 0;
+       return of_clk_add_provider(node, of_clk_src_onecell_get, infra_clk_data);
 }
 
 #define MT6797_PLL_FMAX                (3000UL * MHZ)
index b73bdf1..a0ee079 100644 (file)
@@ -601,7 +601,6 @@ static int mtk_infrasys_init(struct platform_device *pdev)
 {
        struct device_node *node = pdev->dev.of_node;
        struct clk_onecell_data *clk_data;
-       int r;
 
        clk_data = mtk_alloc_clk_data(CLK_INFRA_NR_CLK);
 
@@ -611,12 +610,8 @@ static int mtk_infrasys_init(struct platform_device *pdev)
        mtk_clk_register_cpumuxes(node, infra_muxes, ARRAY_SIZE(infra_muxes),
                                  clk_data);
 
-       r = of_clk_add_provider(node, of_clk_src_onecell_get,
-                               clk_data);
-       if (r)
-               return r;
-
-       return 0;
+       return of_clk_add_provider(node, of_clk_src_onecell_get,
+                                  clk_data);
 }
 
 static int mtk_pericfg_init(struct platform_device *pdev)
diff --git a/drivers/clk/mediatek/clk-mt8167-aud.c b/drivers/clk/mediatek/clk-mt8167-aud.c
new file mode 100644 (file)
index 0000000..3f7bf64
--- /dev/null
@@ -0,0 +1,66 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2020 MediaTek Inc.
+ * Copyright (c) 2020 BayLibre, SAS
+ * Author: James Liao <jamesjj.liao@mediatek.com>
+ *         Fabien Parent <fparent@baylibre.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+
+#include "clk-mtk.h"
+#include "clk-gate.h"
+
+#include <dt-bindings/clock/mt8167-clk.h>
+
+static const struct mtk_gate_regs aud_cg_regs = {
+       .set_ofs = 0x0,
+       .clr_ofs = 0x0,
+       .sta_ofs = 0x0,
+};
+
+#define GATE_AUD(_id, _name, _parent, _shift) {        \
+               .id = _id,                      \
+               .name = _name,                  \
+               .parent_name = _parent,         \
+               .regs = &aud_cg_regs,           \
+               .shift = _shift,                \
+               .ops = &mtk_clk_gate_ops_no_setclr,             \
+       }
+
+static const struct mtk_gate aud_clks[] __initconst = {
+       GATE_AUD(CLK_AUD_AFE, "aud_afe", "clk26m_ck", 2),
+       GATE_AUD(CLK_AUD_I2S, "aud_i2s", "i2s_infra_bck", 6),
+       GATE_AUD(CLK_AUD_22M, "aud_22m", "rg_aud_engen1", 8),
+       GATE_AUD(CLK_AUD_24M, "aud_24m", "rg_aud_engen2", 9),
+       GATE_AUD(CLK_AUD_INTDIR, "aud_intdir", "rg_aud_spdif_in", 15),
+       GATE_AUD(CLK_AUD_APLL2_TUNER, "aud_apll2_tuner", "rg_aud_engen2", 18),
+       GATE_AUD(CLK_AUD_APLL_TUNER, "aud_apll_tuner", "rg_aud_engen1", 19),
+       GATE_AUD(CLK_AUD_HDMI, "aud_hdmi", "apll12_div4", 20),
+       GATE_AUD(CLK_AUD_SPDF, "aud_spdf", "apll12_div6", 21),
+       GATE_AUD(CLK_AUD_ADC, "aud_adc", "aud_afe", 24),
+       GATE_AUD(CLK_AUD_DAC, "aud_dac", "aud_afe", 25),
+       GATE_AUD(CLK_AUD_DAC_PREDIS, "aud_dac_predis", "aud_afe", 26),
+       GATE_AUD(CLK_AUD_TML, "aud_tml", "aud_afe", 27),
+};
+
+static void __init mtk_audsys_init(struct device_node *node)
+{
+       struct clk_onecell_data *clk_data;
+       int r;
+
+       clk_data = mtk_alloc_clk_data(CLK_AUD_NR_CLK);
+
+       mtk_clk_register_gates(node, aud_clks, ARRAY_SIZE(aud_clks), clk_data);
+
+       r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+       if (r)
+               pr_err("%s(): could not register clock provider: %d\n",
+                       __func__, r);
+
+}
+CLK_OF_DECLARE(mtk_audsys, "mediatek,mt8167-audsys", mtk_audsys_init);
diff --git a/drivers/clk/mediatek/clk-mt8167-img.c b/drivers/clk/mediatek/clk-mt8167-img.c
new file mode 100644 (file)
index 0000000..3b4ec9e
--- /dev/null
@@ -0,0 +1,60 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2020 MediaTek Inc.
+ * Copyright (c) 2020 BayLibre, SAS
+ * Author: James Liao <jamesjj.liao@mediatek.com>
+ *         Fabien Parent <fparent@baylibre.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+
+#include "clk-mtk.h"
+#include "clk-gate.h"
+
+#include <dt-bindings/clock/mt8167-clk.h>
+
+static const struct mtk_gate_regs img_cg_regs = {
+       .set_ofs = 0x4,
+       .clr_ofs = 0x8,
+       .sta_ofs = 0x0,
+};
+
+#define GATE_IMG(_id, _name, _parent, _shift) {                \
+               .id = _id,                              \
+               .name = _name,                          \
+               .parent_name = _parent,                 \
+               .regs = &img_cg_regs,                   \
+               .shift = _shift,                        \
+               .ops = &mtk_clk_gate_ops_setclr,        \
+       }
+
+static const struct mtk_gate img_clks[] __initconst = {
+       GATE_IMG(CLK_IMG_LARB1_SMI, "img_larb1_smi", "smi_mm", 0),
+       GATE_IMG(CLK_IMG_CAM_SMI, "img_cam_smi", "smi_mm", 5),
+       GATE_IMG(CLK_IMG_CAM_CAM, "img_cam_cam", "smi_mm", 6),
+       GATE_IMG(CLK_IMG_SEN_TG, "img_sen_tg", "cam_mm", 7),
+       GATE_IMG(CLK_IMG_SEN_CAM, "img_sen_cam", "smi_mm", 8),
+       GATE_IMG(CLK_IMG_VENC, "img_venc", "smi_mm", 9),
+};
+
+static void __init mtk_imgsys_init(struct device_node *node)
+{
+       struct clk_onecell_data *clk_data;
+       int r;
+
+       clk_data = mtk_alloc_clk_data(CLK_IMG_NR_CLK);
+
+       mtk_clk_register_gates(node, img_clks, ARRAY_SIZE(img_clks), clk_data);
+
+       r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+
+       if (r)
+               pr_err("%s(): could not register clock provider: %d\n",
+                       __func__, r);
+
+}
+CLK_OF_DECLARE(mtk_imgsys, "mediatek,mt8167-imgsys", mtk_imgsys_init);
diff --git a/drivers/clk/mediatek/clk-mt8167-mfgcfg.c b/drivers/clk/mediatek/clk-mt8167-mfgcfg.c
new file mode 100644 (file)
index 0000000..90b8717
--- /dev/null
@@ -0,0 +1,58 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2020 MediaTek Inc.
+ * Copyright (c) 2020 BayLibre, SAS
+ * Author: James Liao <jamesjj.liao@mediatek.com>
+ *         Fabien Parent <fparent@baylibre.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+
+#include "clk-mtk.h"
+#include "clk-gate.h"
+
+#include <dt-bindings/clock/mt8167-clk.h>
+
+static const struct mtk_gate_regs mfg_cg_regs = {
+       .set_ofs = 0x4,
+       .clr_ofs = 0x8,
+       .sta_ofs = 0x0,
+};
+
+#define GATE_MFG(_id, _name, _parent, _shift) {                \
+               .id = _id,                              \
+               .name = _name,                          \
+               .parent_name = _parent,                 \
+               .regs = &mfg_cg_regs,                   \
+               .shift = _shift,                        \
+               .ops = &mtk_clk_gate_ops_setclr,        \
+       }
+
+static const struct mtk_gate mfg_clks[] __initconst = {
+       GATE_MFG(CLK_MFG_BAXI, "mfg_baxi", "ahb_infra_sel", 0),
+       GATE_MFG(CLK_MFG_BMEM, "mfg_bmem", "gfmux_emi1x_sel", 1),
+       GATE_MFG(CLK_MFG_BG3D, "mfg_bg3d", "mfg_mm", 2),
+       GATE_MFG(CLK_MFG_B26M, "mfg_b26m", "clk26m_ck", 3),
+};
+
+static void __init mtk_mfgcfg_init(struct device_node *node)
+{
+       struct clk_onecell_data *clk_data;
+       int r;
+
+       clk_data = mtk_alloc_clk_data(CLK_MFG_NR_CLK);
+
+       mtk_clk_register_gates(node, mfg_clks, ARRAY_SIZE(mfg_clks), clk_data);
+
+       r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+
+       if (r)
+               pr_err("%s(): could not register clock provider: %d\n",
+                       __func__, r);
+
+}
+CLK_OF_DECLARE(mtk_mfgcfg, "mediatek,mt8167-mfgcfg", mtk_mfgcfg_init);
diff --git a/drivers/clk/mediatek/clk-mt8167-mm.c b/drivers/clk/mediatek/clk-mt8167-mm.c
new file mode 100644 (file)
index 0000000..963b129
--- /dev/null
@@ -0,0 +1,132 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2020 MediaTek Inc.
+ * Copyright (c) 2020 BayLibre, SAS
+ * Author: James Liao <jamesjj.liao@mediatek.com>
+ *         Fabien Parent <fparent@baylibre.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+
+#include "clk-mtk.h"
+#include "clk-gate.h"
+
+#include <dt-bindings/clock/mt8167-clk.h>
+
+static const struct mtk_gate_regs mm0_cg_regs = {
+       .set_ofs = 0x104,
+       .clr_ofs = 0x108,
+       .sta_ofs = 0x100,
+};
+
+static const struct mtk_gate_regs mm1_cg_regs = {
+       .set_ofs = 0x114,
+       .clr_ofs = 0x118,
+       .sta_ofs = 0x110,
+};
+
+#define GATE_MM0(_id, _name, _parent, _shift) {                \
+               .id = _id,                              \
+               .name = _name,                          \
+               .parent_name = _parent,                 \
+               .regs = &mm0_cg_regs,                   \
+               .shift = _shift,                        \
+               .ops = &mtk_clk_gate_ops_setclr,        \
+       }
+
+#define GATE_MM1(_id, _name, _parent, _shift) {                \
+               .id = _id,                              \
+               .name = _name,                          \
+               .parent_name = _parent,                 \
+               .regs = &mm1_cg_regs,                   \
+               .shift = _shift,                        \
+               .ops = &mtk_clk_gate_ops_setclr,        \
+       }
+
+static const struct mtk_gate mm_clks[] = {
+       /* MM0 */
+       GATE_MM0(CLK_MM_SMI_COMMON, "mm_smi_common", "smi_mm", 0),
+       GATE_MM0(CLK_MM_SMI_LARB0, "mm_smi_larb0", "smi_mm", 1),
+       GATE_MM0(CLK_MM_CAM_MDP, "mm_cam_mdp", "smi_mm", 2),
+       GATE_MM0(CLK_MM_MDP_RDMA, "mm_mdp_rdma", "smi_mm", 3),
+       GATE_MM0(CLK_MM_MDP_RSZ0, "mm_mdp_rsz0", "smi_mm", 4),
+       GATE_MM0(CLK_MM_MDP_RSZ1, "mm_mdp_rsz1", "smi_mm", 5),
+       GATE_MM0(CLK_MM_MDP_TDSHP, "mm_mdp_tdshp", "smi_mm", 6),
+       GATE_MM0(CLK_MM_MDP_WDMA, "mm_mdp_wdma", "smi_mm", 7),
+       GATE_MM0(CLK_MM_MDP_WROT, "mm_mdp_wrot", "smi_mm", 8),
+       GATE_MM0(CLK_MM_FAKE_ENG, "mm_fake_eng", "smi_mm", 9),
+       GATE_MM0(CLK_MM_DISP_OVL0, "mm_disp_ovl0", "smi_mm", 10),
+       GATE_MM0(CLK_MM_DISP_RDMA0, "mm_disp_rdma0", "smi_mm", 11),
+       GATE_MM0(CLK_MM_DISP_RDMA1, "mm_disp_rdma1", "smi_mm", 12),
+       GATE_MM0(CLK_MM_DISP_WDMA, "mm_disp_wdma", "smi_mm", 13),
+       GATE_MM0(CLK_MM_DISP_COLOR, "mm_disp_color", "smi_mm", 14),
+       GATE_MM0(CLK_MM_DISP_CCORR, "mm_disp_ccorr", "smi_mm", 15),
+       GATE_MM0(CLK_MM_DISP_AAL, "mm_disp_aal", "smi_mm", 16),
+       GATE_MM0(CLK_MM_DISP_GAMMA, "mm_disp_gamma", "smi_mm", 17),
+       GATE_MM0(CLK_MM_DISP_DITHER, "mm_disp_dither", "smi_mm", 18),
+       GATE_MM0(CLK_MM_DISP_UFOE, "mm_disp_ufoe", "smi_mm", 19),
+       /* MM1 */
+       GATE_MM1(CLK_MM_DISP_PWM_MM, "mm_disp_pwm_mm", "smi_mm", 0),
+       GATE_MM1(CLK_MM_DISP_PWM_26M, "mm_disp_pwm_26m", "smi_mm", 1),
+       GATE_MM1(CLK_MM_DSI_ENGINE, "mm_dsi_engine", "smi_mm", 2),
+       GATE_MM1(CLK_MM_DSI_DIGITAL, "mm_dsi_digital", "dsi0_lntc_dsick", 3),
+       GATE_MM1(CLK_MM_DPI0_ENGINE, "mm_dpi0_engine", "smi_mm", 4),
+       GATE_MM1(CLK_MM_DPI0_PXL, "mm_dpi0_pxl", "rg_fdpi0", 5),
+       GATE_MM1(CLK_MM_LVDS_PXL, "mm_lvds_pxl", "vpll_dpix", 14),
+       GATE_MM1(CLK_MM_LVDS_CTS, "mm_lvds_cts", "lvdstx_dig_cts", 15),
+       GATE_MM1(CLK_MM_DPI1_ENGINE, "mm_dpi1_engine", "smi_mm", 16),
+       GATE_MM1(CLK_MM_DPI1_PXL, "mm_dpi1_pxl", "rg_fdpi1", 17),
+       GATE_MM1(CLK_MM_HDMI_PXL, "mm_hdmi_pxl", "rg_fdpi1", 18),
+       GATE_MM1(CLK_MM_HDMI_SPDIF, "mm_hdmi_spdif", "apll12_div6", 19),
+       GATE_MM1(CLK_MM_HDMI_ADSP_BCK, "mm_hdmi_adsp_b", "apll12_div4b", 20),
+       GATE_MM1(CLK_MM_HDMI_PLL, "mm_hdmi_pll", "hdmtx_dig_cts", 21),
+};
+
+struct clk_mt8167_mm_driver_data {
+       const struct mtk_gate *gates_clk;
+       int gates_num;
+};
+
+static const struct clk_mt8167_mm_driver_data mt8167_mmsys_driver_data = {
+       .gates_clk = mm_clks,
+       .gates_num = ARRAY_SIZE(mm_clks),
+};
+
+static int clk_mt8167_mm_probe(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct device_node *node = dev->parent->of_node;
+       const struct clk_mt8167_mm_driver_data *data;
+       struct clk_onecell_data *clk_data;
+       int ret;
+
+       clk_data = mtk_alloc_clk_data(CLK_MM_NR_CLK);
+       if (!clk_data)
+               return -ENOMEM;
+
+       data = &mt8167_mmsys_driver_data;
+
+       ret = mtk_clk_register_gates(node, data->gates_clk, data->gates_num,
+                                    clk_data);
+       if (ret)
+               return ret;
+
+       ret = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
+static struct platform_driver clk_mt8173_mm_drv = {
+       .driver = {
+               .name = "clk-mt8167-mm",
+       },
+       .probe = clk_mt8167_mm_probe,
+};
+
+builtin_platform_driver(clk_mt8173_mm_drv);
diff --git a/drivers/clk/mediatek/clk-mt8167-vdec.c b/drivers/clk/mediatek/clk-mt8167-vdec.c
new file mode 100644 (file)
index 0000000..910b283
--- /dev/null
@@ -0,0 +1,73 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2020 MediaTek Inc.
+ * Copyright (c) 2020 BayLibre, SAS
+ * Author: James Liao <jamesjj.liao@mediatek.com>
+ *         Fabien Parent <fparent@baylibre.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+
+#include "clk-mtk.h"
+#include "clk-gate.h"
+
+#include <dt-bindings/clock/mt8167-clk.h>
+
+static const struct mtk_gate_regs vdec0_cg_regs = {
+       .set_ofs = 0x0,
+       .clr_ofs = 0x4,
+       .sta_ofs = 0x0,
+};
+
+static const struct mtk_gate_regs vdec1_cg_regs = {
+       .set_ofs = 0x8,
+       .clr_ofs = 0xc,
+       .sta_ofs = 0x8,
+};
+
+#define GATE_VDEC0_I(_id, _name, _parent, _shift) {    \
+               .id = _id,                              \
+               .name = _name,                          \
+               .parent_name = _parent,                 \
+               .regs = &vdec0_cg_regs,                 \
+               .shift = _shift,                        \
+               .ops = &mtk_clk_gate_ops_setclr_inv,    \
+       }
+
+#define GATE_VDEC1_I(_id, _name, _parent, _shift) {    \
+               .id = _id,                              \
+               .name = _name,                          \
+               .parent_name = _parent,                 \
+               .regs = &vdec1_cg_regs,                 \
+               .shift = _shift,                        \
+               .ops = &mtk_clk_gate_ops_setclr_inv,    \
+       }
+
+static const struct mtk_gate vdec_clks[] __initconst = {
+       /* VDEC0 */
+       GATE_VDEC0_I(CLK_VDEC_CKEN, "vdec_cken", "rg_vdec", 0),
+       /* VDEC1 */
+       GATE_VDEC1_I(CLK_VDEC_LARB1_CKEN, "vdec_larb1_cken", "smi_mm", 0),
+};
+
+static void __init mtk_vdecsys_init(struct device_node *node)
+{
+       struct clk_onecell_data *clk_data;
+       int r;
+
+       clk_data = mtk_alloc_clk_data(CLK_VDEC_NR_CLK);
+
+       mtk_clk_register_gates(node, vdec_clks, ARRAY_SIZE(vdec_clks), clk_data);
+
+       r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+
+       if (r)
+               pr_err("%s(): could not register clock provider: %d\n",
+                       __func__, r);
+
+}
+CLK_OF_DECLARE(mtk_vdecsys, "mediatek,mt8167-vdecsys", mtk_vdecsys_init);
diff --git a/drivers/clk/mediatek/clk-mt8167.c b/drivers/clk/mediatek/clk-mt8167.c
new file mode 100644 (file)
index 0000000..e5ea10e
--- /dev/null
@@ -0,0 +1,1062 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2020 MediaTek Inc.
+ * Copyright (c) 2020 BayLibre, SAS
+ * Author: James Liao <jamesjj.liao@mediatek.com>
+ *         Fabien Parent <fparent@baylibre.com>
+ */
+
+#include <linux/delay.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/slab.h>
+#include <linux/mfd/syscon.h>
+
+#include "clk-mtk.h"
+#include "clk-gate.h"
+
+#include <dt-bindings/clock/mt8167-clk.h>
+
+static DEFINE_SPINLOCK(mt8167_clk_lock);
+
+static const struct mtk_fixed_clk fixed_clks[] __initconst = {
+       FIXED_CLK(CLK_TOP_CLK_NULL, "clk_null", NULL, 0),
+       FIXED_CLK(CLK_TOP_I2S_INFRA_BCK, "i2s_infra_bck", "clk_null", 26000000),
+       FIXED_CLK(CLK_TOP_MEMPLL, "mempll", "clk26m", 800000000),
+       FIXED_CLK(CLK_TOP_DSI0_LNTC_DSICK, "dsi0_lntc_dsick", "clk26m", 75000000),
+       FIXED_CLK(CLK_TOP_VPLL_DPIX, "vpll_dpix", "clk26m", 75000000),
+       FIXED_CLK(CLK_TOP_LVDSTX_CLKDIG_CTS, "lvdstx_dig_cts", "clk26m", 52500000),
+};
+
+static const struct mtk_fixed_factor top_divs[] __initconst = {
+       FACTOR(CLK_TOP_DMPLL, "dmpll_ck", "mempll", 1, 1),
+       FACTOR(CLK_TOP_MAINPLL_D2, "mainpll_d2", "mainpll", 1, 2),
+       FACTOR(CLK_TOP_MAINPLL_D4, "mainpll_d4", "mainpll", 1, 4),
+       FACTOR(CLK_TOP_MAINPLL_D8, "mainpll_d8", "mainpll", 1, 8),
+       FACTOR(CLK_TOP_MAINPLL_D16, "mainpll_d16", "mainpll", 1, 16),
+       FACTOR(CLK_TOP_MAINPLL_D11, "mainpll_d11", "mainpll", 1, 11),
+       FACTOR(CLK_TOP_MAINPLL_D22, "mainpll_d22", "mainpll", 1, 22),
+       FACTOR(CLK_TOP_MAINPLL_D3, "mainpll_d3", "mainpll", 1, 3),
+       FACTOR(CLK_TOP_MAINPLL_D6, "mainpll_d6", "mainpll", 1, 6),
+       FACTOR(CLK_TOP_MAINPLL_D12, "mainpll_d12", "mainpll", 1, 12),
+       FACTOR(CLK_TOP_MAINPLL_D5, "mainpll_d5", "mainpll", 1, 5),
+       FACTOR(CLK_TOP_MAINPLL_D10, "mainpll_d10", "mainpll", 1, 10),
+       FACTOR(CLK_TOP_MAINPLL_D20, "mainpll_d20", "mainpll", 1, 20),
+       FACTOR(CLK_TOP_MAINPLL_D40, "mainpll_d40", "mainpll", 1, 40),
+       FACTOR(CLK_TOP_MAINPLL_D7, "mainpll_d7", "mainpll", 1, 7),
+       FACTOR(CLK_TOP_MAINPLL_D14, "mainpll_d14", "mainpll", 1, 14),
+       FACTOR(CLK_TOP_UNIVPLL_D2, "univpll_d2", "univpll", 1, 2),
+       FACTOR(CLK_TOP_UNIVPLL_D4, "univpll_d4", "univpll", 1, 4),
+       FACTOR(CLK_TOP_UNIVPLL_D8, "univpll_d8", "univpll", 1, 8),
+       FACTOR(CLK_TOP_UNIVPLL_D16, "univpll_d16", "univpll", 1, 16),
+       FACTOR(CLK_TOP_UNIVPLL_D3, "univpll_d3", "univpll", 1, 3),
+       FACTOR(CLK_TOP_UNIVPLL_D6, "univpll_d6", "univpll", 1, 6),
+       FACTOR(CLK_TOP_UNIVPLL_D12, "univpll_d12", "univpll", 1, 12),
+       FACTOR(CLK_TOP_UNIVPLL_D24, "univpll_d24", "univpll", 1, 24),
+       FACTOR(CLK_TOP_UNIVPLL_D5, "univpll_d5", "univpll", 1, 5),
+       FACTOR(CLK_TOP_UNIVPLL_D20, "univpll_d20", "univpll", 1, 20),
+       FACTOR(CLK_TOP_MMPLL380M, "mmpll380m", "mmpll", 1, 1),
+       FACTOR(CLK_TOP_MMPLL_D2, "mmpll_d2", "mmpll", 1, 2),
+       FACTOR(CLK_TOP_MMPLL_200M, "mmpll_200m", "mmpll", 1, 3),
+       FACTOR(CLK_TOP_LVDSPLL, "lvdspll_ck", "lvdspll", 1, 1),
+       FACTOR(CLK_TOP_LVDSPLL_D2, "lvdspll_d2", "lvdspll", 1, 2),
+       FACTOR(CLK_TOP_LVDSPLL_D4, "lvdspll_d4", "lvdspll", 1, 4),
+       FACTOR(CLK_TOP_LVDSPLL_D8, "lvdspll_d8", "lvdspll", 1, 8),
+       FACTOR(CLK_TOP_USB_PHY48M, "usb_phy48m_ck", "univpll", 1, 26),
+       FACTOR(CLK_TOP_APLL1, "apll1_ck", "apll1", 1, 1),
+       FACTOR(CLK_TOP_APLL1_D2, "apll1_d2", "apll1_ck", 1, 2),
+       FACTOR(CLK_TOP_APLL1_D4, "apll1_d4", "rg_apll1_d2_en", 1, 2),
+       FACTOR(CLK_TOP_APLL1_D8, "apll1_d8", "rg_apll1_d4_en", 1, 2),
+       FACTOR(CLK_TOP_APLL2, "apll2_ck", "apll2", 1, 1),
+       FACTOR(CLK_TOP_APLL2_D2, "apll2_d2", "apll2_ck", 1, 2),
+       FACTOR(CLK_TOP_APLL2_D4, "apll2_d4", "rg_apll2_d2_en", 1, 2),
+       FACTOR(CLK_TOP_APLL2_D8, "apll2_d8", "rg_apll2_d4_en", 1, 2),
+       FACTOR(CLK_TOP_CLK26M, "clk26m_ck", "clk26m", 1, 1),
+       FACTOR(CLK_TOP_CLK26M_D2, "clk26m_d2", "clk26m", 1, 2),
+       FACTOR(CLK_TOP_MIPI_26M, "mipi_26m", "clk26m", 1, 1),
+       FACTOR(CLK_TOP_TVDPLL, "tvdpll_ck", "tvdpll", 1, 1),
+       FACTOR(CLK_TOP_TVDPLL_D2, "tvdpll_d2", "tvdpll_ck", 1, 2),
+       FACTOR(CLK_TOP_TVDPLL_D4, "tvdpll_d4", "tvdpll_ck", 1, 4),
+       FACTOR(CLK_TOP_TVDPLL_D8, "tvdpll_d8", "tvdpll_ck", 1, 8),
+       FACTOR(CLK_TOP_TVDPLL_D16, "tvdpll_d16", "tvdpll_ck", 1, 16),
+       FACTOR(CLK_TOP_AHB_INFRA_D2, "ahb_infra_d2", "ahb_infra_sel", 1, 2),
+       FACTOR(CLK_TOP_NFI1X, "nfi1x_ck", "nfi2x_pad_sel", 1, 2),
+       FACTOR(CLK_TOP_ETH_D2, "eth_d2_ck", "eth_sel", 1, 2),
+};
+
+static const char * const uart0_parents[] __initconst = {
+       "clk26m_ck",
+       "univpll_d24"
+};
+
+static const char * const gfmux_emi1x_parents[] __initconst = {
+       "clk26m_ck",
+       "dmpll_ck"
+};
+
+static const char * const emi_ddrphy_parents[] __initconst = {
+       "gfmux_emi1x_sel",
+       "gfmux_emi1x_sel"
+};
+
+static const char * const ahb_infra_parents[] __initconst = {
+       "clk_null",
+       "clk26m_ck",
+       "mainpll_d11",
+       "clk_null",
+       "mainpll_d12",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "mainpll_d10"
+};
+
+static const char * const csw_mux_mfg_parents[] __initconst = {
+       "clk_null",
+       "clk_null",
+       "univpll_d3",
+       "univpll_d2",
+       "clk26m_ck",
+       "mainpll_d4",
+       "univpll_d24",
+       "mmpll380m"
+};
+
+static const char * const msdc0_parents[] __initconst = {
+       "clk26m_ck",
+       "univpll_d6",
+       "mainpll_d8",
+       "univpll_d8",
+       "mainpll_d16",
+       "mmpll_200m",
+       "mainpll_d12",
+       "mmpll_d2"
+};
+
+static const char * const camtg_mm_parents[] __initconst = {
+       "clk_null",
+       "clk26m_ck",
+       "usb_phy48m_ck",
+       "clk_null",
+       "univpll_d6"
+};
+
+static const char * const pwm_mm_parents[] __initconst = {
+       "clk26m_ck",
+       "univpll_d12"
+};
+
+static const char * const uart1_parents[] __initconst = {
+       "clk26m_ck",
+       "univpll_d24"
+};
+
+static const char * const msdc1_parents[] __initconst = {
+       "clk26m_ck",
+       "univpll_d6",
+       "mainpll_d8",
+       "univpll_d8",
+       "mainpll_d16",
+       "mmpll_200m",
+       "mainpll_d12",
+       "mmpll_d2"
+};
+
+static const char * const spm_52m_parents[] __initconst = {
+       "clk26m_ck",
+       "univpll_d24"
+};
+
+static const char * const pmicspi_parents[] __initconst = {
+       "univpll_d20",
+       "usb_phy48m_ck",
+       "univpll_d16",
+       "clk26m_ck"
+};
+
+static const char * const qaxi_aud26m_parents[] __initconst = {
+       "clk26m_ck",
+       "ahb_infra_sel"
+};
+
+static const char * const aud_intbus_parents[] __initconst = {
+       "clk_null",
+       "clk26m_ck",
+       "mainpll_d22",
+       "clk_null",
+       "mainpll_d11"
+};
+
+static const char * const nfi2x_pad_parents[] __initconst = {
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk26m_ck",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "mainpll_d12",
+       "mainpll_d8",
+       "clk_null",
+       "mainpll_d6",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "mainpll_d4",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "mainpll_d10",
+       "mainpll_d7",
+       "clk_null",
+       "mainpll_d5"
+};
+
+static const char * const nfi1x_pad_parents[] __initconst = {
+       "ahb_infra_sel",
+       "nfi1x_ck"
+};
+
+static const char * const mfg_mm_parents[] __initconst = {
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "csw_mux_mfg_sel",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "mainpll_d3",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "mainpll_d5",
+       "mainpll_d7",
+       "clk_null",
+       "mainpll_d14"
+};
+
+static const char * const ddrphycfg_parents[] __initconst = {
+       "clk26m_ck",
+       "mainpll_d16"
+};
+
+static const char * const smi_mm_parents[] __initconst = {
+       "clk26m_ck",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "univpll_d4",
+       "mainpll_d7",
+       "clk_null",
+       "mainpll_d14"
+};
+
+static const char * const usb_78m_parents[] __initconst = {
+       "clk_null",
+       "clk26m_ck",
+       "univpll_d16",
+       "clk_null",
+       "mainpll_d20"
+};
+
+static const char * const scam_mm_parents[] __initconst = {
+       "clk_null",
+       "clk26m_ck",
+       "mainpll_d14",
+       "clk_null",
+       "mainpll_d12"
+};
+
+static const char * const spinor_parents[] __initconst = {
+       "clk26m_d2",
+       "clk26m_ck",
+       "mainpll_d40",
+       "univpll_d24",
+       "univpll_d20",
+       "mainpll_d20",
+       "mainpll_d16",
+       "univpll_d12"
+};
+
+static const char * const msdc2_parents[] __initconst = {
+       "clk26m_ck",
+       "univpll_d6",
+       "mainpll_d8",
+       "univpll_d8",
+       "mainpll_d16",
+       "mmpll_200m",
+       "mainpll_d12",
+       "mmpll_d2"
+};
+
+static const char * const eth_parents[] __initconst = {
+       "clk26m_ck",
+       "mainpll_d40",
+       "univpll_d24",
+       "univpll_d20",
+       "mainpll_d20"
+};
+
+static const char * const vdec_mm_parents[] __initconst = {
+       "clk26m_ck",
+       "univpll_d4",
+       "mainpll_d4",
+       "univpll_d5",
+       "univpll_d6",
+       "mainpll_d6"
+};
+
+static const char * const dpi0_mm_parents[] __initconst = {
+       "clk26m_ck",
+       "lvdspll_ck",
+       "lvdspll_d2",
+       "lvdspll_d4",
+       "lvdspll_d8"
+};
+
+static const char * const dpi1_mm_parents[] __initconst = {
+       "clk26m_ck",
+       "tvdpll_d2",
+       "tvdpll_d4",
+       "tvdpll_d8",
+       "tvdpll_d16"
+};
+
+static const char * const axi_mfg_in_parents[] __initconst = {
+       "clk26m_ck",
+       "mainpll_d11",
+       "univpll_d24",
+       "mmpll380m"
+};
+
+static const char * const slow_mfg_parents[] __initconst = {
+       "clk26m_ck",
+       "univpll_d12",
+       "univpll_d24"
+};
+
+static const char * const aud1_parents[] __initconst = {
+       "clk26m_ck",
+       "apll1_ck"
+};
+
+static const char * const aud2_parents[] __initconst = {
+       "clk26m_ck",
+       "apll2_ck"
+};
+
+static const char * const aud_engen1_parents[] __initconst = {
+       "clk26m_ck",
+       "rg_apll1_d2_en",
+       "rg_apll1_d4_en",
+       "rg_apll1_d8_en"
+};
+
+static const char * const aud_engen2_parents[] __initconst = {
+       "clk26m_ck",
+       "rg_apll2_d2_en",
+       "rg_apll2_d4_en",
+       "rg_apll2_d8_en"
+};
+
+static const char * const i2c_parents[] __initconst = {
+       "clk26m_ck",
+       "univpll_d20",
+       "univpll_d16",
+       "univpll_d12"
+};
+
+static const char * const aud_i2s0_m_parents[] __initconst = {
+       "rg_aud1",
+       "rg_aud2"
+};
+
+static const char * const pwm_parents[] __initconst = {
+       "clk26m_ck",
+       "univpll_d12"
+};
+
+static const char * const spi_parents[] __initconst = {
+       "clk26m_ck",
+       "univpll_d12",
+       "univpll_d8",
+       "univpll_d6"
+};
+
+static const char * const aud_spdifin_parents[] __initconst = {
+       "clk26m_ck",
+       "univpll_d2"
+};
+
+static const char * const uart2_parents[] __initconst = {
+       "clk26m_ck",
+       "univpll_d24"
+};
+
+static const char * const bsi_parents[] __initconst = {
+       "clk26m_ck",
+       "mainpll_d10",
+       "mainpll_d12",
+       "mainpll_d20"
+};
+
+static const char * const dbg_atclk_parents[] __initconst = {
+       "clk_null",
+       "clk26m_ck",
+       "mainpll_d5",
+       "clk_null",
+       "univpll_d5"
+};
+
+static const char * const csw_nfiecc_parents[] __initconst = {
+       "clk_null",
+       "mainpll_d7",
+       "mainpll_d6",
+       "clk_null",
+       "mainpll_d5"
+};
+
+static const char * const nfiecc_parents[] __initconst = {
+       "clk_null",
+       "nfi2x_pad_sel",
+       "mainpll_d4",
+       "clk_null",
+       "csw_nfiecc_sel"
+};
+
+static struct mtk_composite top_muxes[] __initdata = {
+       /* CLK_MUX_SEL0 */
+       MUX(CLK_TOP_UART0_SEL, "uart0_sel", uart0_parents,
+               0x000, 0, 1),
+       MUX(CLK_TOP_GFMUX_EMI1X_SEL, "gfmux_emi1x_sel", gfmux_emi1x_parents,
+               0x000, 1, 1),
+       MUX(CLK_TOP_EMI_DDRPHY_SEL, "emi_ddrphy_sel", emi_ddrphy_parents,
+               0x000, 2, 1),
+       MUX(CLK_TOP_AHB_INFRA_SEL, "ahb_infra_sel", ahb_infra_parents,
+               0x000, 4, 4),
+       MUX(CLK_TOP_CSW_MUX_MFG_SEL, "csw_mux_mfg_sel", csw_mux_mfg_parents,
+               0x000, 8, 3),
+       MUX(CLK_TOP_MSDC0_SEL, "msdc0_sel", msdc0_parents,
+               0x000, 11, 3),
+       MUX(CLK_TOP_CAMTG_MM_SEL, "camtg_mm_sel", camtg_mm_parents,
+               0x000, 15, 3),
+       MUX(CLK_TOP_PWM_MM_SEL, "pwm_mm_sel", pwm_mm_parents,
+               0x000, 18, 1),
+       MUX(CLK_TOP_UART1_SEL, "uart1_sel", uart1_parents,
+               0x000, 19, 1),
+       MUX(CLK_TOP_MSDC1_SEL, "msdc1_sel", msdc1_parents,
+               0x000, 20, 3),
+       MUX(CLK_TOP_SPM_52M_SEL, "spm_52m_sel", spm_52m_parents,
+               0x000, 23, 1),
+       MUX(CLK_TOP_PMICSPI_SEL, "pmicspi_sel", pmicspi_parents,
+               0x000, 24, 2),
+       MUX(CLK_TOP_QAXI_AUD26M_SEL, "qaxi_aud26m_sel", qaxi_aud26m_parents,
+               0x000, 26, 1),
+       MUX(CLK_TOP_AUD_INTBUS_SEL, "aud_intbus_sel", aud_intbus_parents,
+               0x000, 27, 3),
+       /* CLK_MUX_SEL1 */
+       MUX(CLK_TOP_NFI2X_PAD_SEL, "nfi2x_pad_sel", nfi2x_pad_parents,
+               0x004, 0, 7),
+       MUX(CLK_TOP_NFI1X_PAD_SEL, "nfi1x_pad_sel", nfi1x_pad_parents,
+               0x004, 7, 1),
+       MUX(CLK_TOP_MFG_MM_SEL, "mfg_mm_sel", mfg_mm_parents,
+               0x004, 8, 6),
+       MUX(CLK_TOP_DDRPHYCFG_SEL, "ddrphycfg_sel", ddrphycfg_parents,
+               0x004, 15, 1),
+       MUX(CLK_TOP_SMI_MM_SEL, "smi_mm_sel", smi_mm_parents,
+               0x004, 16, 4),
+       MUX(CLK_TOP_USB_78M_SEL, "usb_78m_sel", usb_78m_parents,
+               0x004, 20, 3),
+       MUX(CLK_TOP_SCAM_MM_SEL, "scam_mm_sel", scam_mm_parents,
+               0x004, 23, 3),
+       /* CLK_MUX_SEL8 */
+       MUX(CLK_TOP_SPINOR_SEL, "spinor_sel", spinor_parents,
+               0x040, 0, 3),
+       MUX(CLK_TOP_MSDC2_SEL, "msdc2_sel", msdc2_parents,
+               0x040, 3, 3),
+       MUX(CLK_TOP_ETH_SEL, "eth_sel", eth_parents,
+               0x040, 6, 3),
+       MUX(CLK_TOP_VDEC_MM_SEL, "vdec_mm_sel", vdec_mm_parents,
+               0x040, 9, 3),
+       MUX(CLK_TOP_DPI0_MM_SEL, "dpi0_mm_sel", dpi0_mm_parents,
+               0x040, 12, 3),
+       MUX(CLK_TOP_DPI1_MM_SEL, "dpi1_mm_sel", dpi1_mm_parents,
+               0x040, 15, 3),
+       MUX(CLK_TOP_AXI_MFG_IN_SEL, "axi_mfg_in_sel", axi_mfg_in_parents,
+               0x040, 18, 2),
+       MUX(CLK_TOP_SLOW_MFG_SEL, "slow_mfg_sel", slow_mfg_parents,
+               0x040, 20, 2),
+       MUX(CLK_TOP_AUD1_SEL, "aud1_sel", aud1_parents,
+               0x040, 22, 1),
+       MUX(CLK_TOP_AUD2_SEL, "aud2_sel", aud2_parents,
+               0x040, 23, 1),
+       MUX(CLK_TOP_AUD_ENGEN1_SEL, "aud_engen1_sel", aud_engen1_parents,
+               0x040, 24, 2),
+       MUX(CLK_TOP_AUD_ENGEN2_SEL, "aud_engen2_sel", aud_engen2_parents,
+               0x040, 26, 2),
+       MUX(CLK_TOP_I2C_SEL, "i2c_sel", i2c_parents,
+               0x040, 28, 2),
+       /* CLK_SEL_9 */
+       MUX(CLK_TOP_AUD_I2S0_M_SEL, "aud_i2s0_m_sel", aud_i2s0_m_parents,
+               0x044, 12, 1),
+       MUX(CLK_TOP_AUD_I2S1_M_SEL, "aud_i2s1_m_sel", aud_i2s0_m_parents,
+               0x044, 13, 1),
+       MUX(CLK_TOP_AUD_I2S2_M_SEL, "aud_i2s2_m_sel", aud_i2s0_m_parents,
+               0x044, 14, 1),
+       MUX(CLK_TOP_AUD_I2S3_M_SEL, "aud_i2s3_m_sel", aud_i2s0_m_parents,
+               0x044, 15, 1),
+       MUX(CLK_TOP_AUD_I2S4_M_SEL, "aud_i2s4_m_sel", aud_i2s0_m_parents,
+               0x044, 16, 1),
+       MUX(CLK_TOP_AUD_I2S5_M_SEL, "aud_i2s5_m_sel", aud_i2s0_m_parents,
+               0x044, 17, 1),
+       MUX(CLK_TOP_AUD_SPDIF_B_SEL, "aud_spdif_b_sel", aud_i2s0_m_parents,
+               0x044, 18, 1),
+       /* CLK_MUX_SEL13 */
+       MUX(CLK_TOP_PWM_SEL, "pwm_sel", pwm_parents,
+               0x07c, 0, 1),
+       MUX(CLK_TOP_SPI_SEL, "spi_sel", spi_parents,
+               0x07c, 1, 2),
+       MUX(CLK_TOP_AUD_SPDIFIN_SEL, "aud_spdifin_sel", aud_spdifin_parents,
+               0x07c, 3, 1),
+       MUX(CLK_TOP_UART2_SEL, "uart2_sel", uart2_parents,
+               0x07c, 4, 1),
+       MUX(CLK_TOP_BSI_SEL, "bsi_sel", bsi_parents,
+               0x07c, 5, 2),
+       MUX(CLK_TOP_DBG_ATCLK_SEL, "dbg_atclk_sel", dbg_atclk_parents,
+               0x07c, 7, 3),
+       MUX(CLK_TOP_CSW_NFIECC_SEL, "csw_nfiecc_sel", csw_nfiecc_parents,
+               0x07c, 10, 3),
+       MUX(CLK_TOP_NFIECC_SEL, "nfiecc_sel", nfiecc_parents,
+               0x07c, 13, 3),
+};
+
+static const char * const ifr_mux1_parents[] __initconst = {
+       "clk26m_ck",
+       "armpll",
+       "univpll",
+       "mainpll_d2"
+};
+
+static const char * const ifr_eth_25m_parents[] __initconst = {
+       "eth_d2_ck",
+       "rg_eth"
+};
+
+static const char * const ifr_i2c0_parents[] __initconst = {
+       "ahb_infra_d2",
+       "rg_i2c"
+};
+
+static const struct mtk_composite ifr_muxes[] __initconst = {
+       MUX(CLK_IFR_MUX1_SEL, "ifr_mux1_sel", ifr_mux1_parents, 0x000,
+               2, 2),
+       MUX(CLK_IFR_ETH_25M_SEL, "ifr_eth_25m_sel", ifr_eth_25m_parents, 0x080,
+               0, 1),
+       MUX(CLK_IFR_I2C0_SEL, "ifr_i2c0_sel", ifr_i2c0_parents, 0x080,
+               1, 1),
+       MUX(CLK_IFR_I2C1_SEL, "ifr_i2c1_sel", ifr_i2c0_parents, 0x080,
+               2, 1),
+       MUX(CLK_IFR_I2C2_SEL, "ifr_i2c2_sel", ifr_i2c0_parents, 0x080,
+               3, 1),
+};
+
+#define DIV_ADJ(_id, _name, _parent, _reg, _shift, _width) {   \
+               .id = _id,                                      \
+               .name = _name,                                  \
+               .parent_name = _parent,                         \
+               .div_reg = _reg,                                \
+               .div_shift = _shift,                            \
+               .div_width = _width,                            \
+}
+
+static const struct mtk_clk_divider top_adj_divs[] = {
+       DIV_ADJ(CLK_TOP_APLL12_CK_DIV0, "apll12_ck_div0", "aud_i2s0_m_sel",
+               0x0048, 0, 8),
+       DIV_ADJ(CLK_TOP_APLL12_CK_DIV1, "apll12_ck_div1", "aud_i2s1_m_sel",
+               0x0048, 8, 8),
+       DIV_ADJ(CLK_TOP_APLL12_CK_DIV2, "apll12_ck_div2", "aud_i2s2_m_sel",
+               0x0048, 16, 8),
+       DIV_ADJ(CLK_TOP_APLL12_CK_DIV3, "apll12_ck_div3", "aud_i2s3_m_sel",
+               0x0048, 24, 8),
+       DIV_ADJ(CLK_TOP_APLL12_CK_DIV4, "apll12_ck_div4", "aud_i2s4_m_sel",
+               0x004c, 0, 8),
+       DIV_ADJ(CLK_TOP_APLL12_CK_DIV4B, "apll12_ck_div4b", "apll12_div4",
+               0x004c, 8, 8),
+       DIV_ADJ(CLK_TOP_APLL12_CK_DIV5, "apll12_ck_div5", "aud_i2s5_m_sel",
+               0x004c, 16, 8),
+       DIV_ADJ(CLK_TOP_APLL12_CK_DIV5B, "apll12_ck_div5b", "apll12_div5",
+               0x004c, 24, 8),
+       DIV_ADJ(CLK_TOP_APLL12_CK_DIV6, "apll12_ck_div6", "aud_spdif_b_sel",
+               0x0078, 0, 8),
+};
+
+#define DIV_ADJ_FLAG(_id, _name, _parent, _reg, _shift, _width, _flag) {       \
+               .id = _id,                                      \
+               .name = _name,                                  \
+               .parent_name = _parent,                         \
+               .div_reg = _reg,                                \
+               .div_shift = _shift,                            \
+               .div_width = _width,                            \
+               .clk_divider_flags = _flag,                             \
+}
+
+static const struct mtk_clk_divider apmixed_adj_divs[] = {
+       DIV_ADJ_FLAG(CLK_APMIXED_HDMI_REF, "hdmi_ref", "tvdpll",
+               0x1c4, 24, 3, CLK_DIVIDER_POWER_OF_TWO),
+};
+
+static const struct mtk_gate_regs top0_cg_regs = {
+       .set_ofs = 0x50,
+       .clr_ofs = 0x80,
+       .sta_ofs = 0x20,
+};
+
+static const struct mtk_gate_regs top1_cg_regs = {
+       .set_ofs = 0x54,
+       .clr_ofs = 0x84,
+       .sta_ofs = 0x24,
+};
+
+static const struct mtk_gate_regs top2_cg_regs = {
+       .set_ofs = 0x6c,
+       .clr_ofs = 0x9c,
+       .sta_ofs = 0x3c,
+};
+
+static const struct mtk_gate_regs top3_cg_regs = {
+       .set_ofs = 0xa0,
+       .clr_ofs = 0xb0,
+       .sta_ofs = 0x70,
+};
+
+static const struct mtk_gate_regs top4_cg_regs = {
+       .set_ofs = 0xa4,
+       .clr_ofs = 0xb4,
+       .sta_ofs = 0x74,
+};
+
+static const struct mtk_gate_regs top5_cg_regs = {
+       .set_ofs = 0x44,
+       .clr_ofs = 0x44,
+       .sta_ofs = 0x44,
+};
+
+#define GATE_TOP0(_id, _name, _parent, _shift) {       \
+               .id = _id,                              \
+               .name = _name,                          \
+               .parent_name = _parent,                 \
+               .regs = &top0_cg_regs,                  \
+               .shift = _shift,                        \
+               .ops = &mtk_clk_gate_ops_setclr,        \
+       }
+
+#define GATE_TOP0_I(_id, _name, _parent, _shift) {     \
+               .id = _id,                              \
+               .name = _name,                          \
+               .parent_name = _parent,                 \
+               .regs = &top0_cg_regs,                  \
+               .shift = _shift,                        \
+               .ops = &mtk_clk_gate_ops_setclr_inv,    \
+       }
+
+#define GATE_TOP1(_id, _name, _parent, _shift) {       \
+               .id = _id,                              \
+               .name = _name,                          \
+               .parent_name = _parent,                 \
+               .regs = &top1_cg_regs,                  \
+               .shift = _shift,                        \
+               .ops = &mtk_clk_gate_ops_setclr,        \
+       }
+
+#define GATE_TOP2(_id, _name, _parent, _shift) {       \
+               .id = _id,                              \
+               .name = _name,                          \
+               .parent_name = _parent,                 \
+               .regs = &top2_cg_regs,                  \
+               .shift = _shift,                        \
+               .ops = &mtk_clk_gate_ops_setclr,        \
+       }
+
+#define GATE_TOP2_I(_id, _name, _parent, _shift) {     \
+               .id = _id,                              \
+               .name = _name,                          \
+               .parent_name = _parent,                 \
+               .regs = &top2_cg_regs,                  \
+               .shift = _shift,                        \
+               .ops = &mtk_clk_gate_ops_setclr_inv,    \
+       }
+
+#define GATE_TOP3(_id, _name, _parent, _shift) {       \
+               .id = _id,                              \
+               .name = _name,                          \
+               .parent_name = _parent,                 \
+               .regs = &top3_cg_regs,                  \
+               .shift = _shift,                        \
+               .ops = &mtk_clk_gate_ops_setclr,        \
+       }
+
+#define GATE_TOP4_I(_id, _name, _parent, _shift) {     \
+               .id = _id,                              \
+               .name = _name,                          \
+               .parent_name = _parent,                 \
+               .regs = &top4_cg_regs,                  \
+               .shift = _shift,                        \
+               .ops = &mtk_clk_gate_ops_setclr_inv,    \
+       }
+
+#define GATE_TOP5(_id, _name, _parent, _shift) {       \
+               .id = _id,                              \
+               .name = _name,                          \
+               .parent_name = _parent,                 \
+               .regs = &top5_cg_regs,                  \
+               .shift = _shift,                        \
+               .ops = &mtk_clk_gate_ops_no_setclr,     \
+       }
+
+static const struct mtk_gate top_clks[] __initconst = {
+       /* TOP0 */
+       GATE_TOP0(CLK_TOP_PWM_MM, "pwm_mm", "pwm_mm_sel", 0),
+       GATE_TOP0(CLK_TOP_CAM_MM, "cam_mm", "camtg_mm_sel", 1),
+       GATE_TOP0(CLK_TOP_MFG_MM, "mfg_mm", "mfg_mm_sel", 2),
+       GATE_TOP0(CLK_TOP_SPM_52M, "spm_52m", "spm_52m_sel", 3),
+       GATE_TOP0_I(CLK_TOP_MIPI_26M_DBG, "mipi_26m_dbg", "mipi_26m", 4),
+       GATE_TOP0(CLK_TOP_SCAM_MM, "scam_mm", "scam_mm_sel", 5),
+       GATE_TOP0(CLK_TOP_SMI_MM, "smi_mm", "smi_mm_sel", 9),
+       /* TOP1 */
+       GATE_TOP1(CLK_TOP_THEM, "them", "ahb_infra_sel", 1),
+       GATE_TOP1(CLK_TOP_APDMA, "apdma", "ahb_infra_sel", 2),
+       GATE_TOP1(CLK_TOP_I2C0, "i2c0", "ifr_i2c0_sel", 3),
+       GATE_TOP1(CLK_TOP_I2C1, "i2c1", "ifr_i2c1_sel", 4),
+       GATE_TOP1(CLK_TOP_AUXADC1, "auxadc1", "ahb_infra_sel", 5),
+       GATE_TOP1(CLK_TOP_NFI, "nfi", "nfi1x_pad_sel", 6),
+       GATE_TOP1(CLK_TOP_NFIECC, "nfiecc", "rg_nfiecc", 7),
+       GATE_TOP1(CLK_TOP_DEBUGSYS, "debugsys", "rg_dbg_atclk", 8),
+       GATE_TOP1(CLK_TOP_PWM, "pwm", "ahb_infra_sel", 9),
+       GATE_TOP1(CLK_TOP_UART0, "uart0", "uart0_sel", 10),
+       GATE_TOP1(CLK_TOP_UART1, "uart1", "uart1_sel", 11),
+       GATE_TOP1(CLK_TOP_BTIF, "btif", "ahb_infra_sel", 12),
+       GATE_TOP1(CLK_TOP_USB, "usb", "usb_78m", 13),
+       GATE_TOP1(CLK_TOP_FLASHIF_26M, "flashif_26m", "clk26m_ck", 14),
+       GATE_TOP1(CLK_TOP_AUXADC2, "auxadc2", "ahb_infra_sel", 15),
+       GATE_TOP1(CLK_TOP_I2C2, "i2c2", "ifr_i2c2_sel", 16),
+       GATE_TOP1(CLK_TOP_MSDC0, "msdc0", "msdc0_sel", 17),
+       GATE_TOP1(CLK_TOP_MSDC1, "msdc1", "msdc1_sel", 18),
+       GATE_TOP1(CLK_TOP_NFI2X, "nfi2x", "nfi2x_pad_sel", 19),
+       GATE_TOP1(CLK_TOP_PMICWRAP_AP, "pwrap_ap", "clk26m_ck", 20),
+       GATE_TOP1(CLK_TOP_SEJ, "sej", "ahb_infra_sel", 21),
+       GATE_TOP1(CLK_TOP_MEMSLP_DLYER, "memslp_dlyer", "clk26m_ck", 22),
+       GATE_TOP1(CLK_TOP_SPI, "spi", "spi_sel", 23),
+       GATE_TOP1(CLK_TOP_APXGPT, "apxgpt", "clk26m_ck", 24),
+       GATE_TOP1(CLK_TOP_AUDIO, "audio", "clk26m_ck", 25),
+       GATE_TOP1(CLK_TOP_PMICWRAP_MD, "pwrap_md", "clk26m_ck", 27),
+       GATE_TOP1(CLK_TOP_PMICWRAP_CONN, "pwrap_conn", "clk26m_ck", 28),
+       GATE_TOP1(CLK_TOP_PMICWRAP_26M, "pwrap_26m", "clk26m_ck", 29),
+       GATE_TOP1(CLK_TOP_AUX_ADC, "aux_adc", "clk26m_ck", 30),
+       GATE_TOP1(CLK_TOP_AUX_TP, "aux_tp", "clk26m_ck", 31),
+       /* TOP2 */
+       GATE_TOP2(CLK_TOP_MSDC2, "msdc2", "ahb_infra_sel", 0),
+       GATE_TOP2(CLK_TOP_RBIST, "rbist", "univpll_d12", 1),
+       GATE_TOP2(CLK_TOP_NFI_BUS, "nfi_bus", "ahb_infra_sel", 2),
+       GATE_TOP2(CLK_TOP_GCE, "gce", "ahb_infra_sel", 4),
+       GATE_TOP2(CLK_TOP_TRNG, "trng", "ahb_infra_sel", 5),
+       GATE_TOP2(CLK_TOP_SEJ_13M, "sej_13m", "clk26m_ck", 6),
+       GATE_TOP2(CLK_TOP_AES, "aes", "ahb_infra_sel", 7),
+       GATE_TOP2(CLK_TOP_PWM_B, "pwm_b", "rg_pwm_infra", 8),
+       GATE_TOP2(CLK_TOP_PWM1_FB, "pwm1_fb", "rg_pwm_infra", 9),
+       GATE_TOP2(CLK_TOP_PWM2_FB, "pwm2_fb", "rg_pwm_infra", 10),
+       GATE_TOP2(CLK_TOP_PWM3_FB, "pwm3_fb", "rg_pwm_infra", 11),
+       GATE_TOP2(CLK_TOP_PWM4_FB, "pwm4_fb", "rg_pwm_infra", 12),
+       GATE_TOP2(CLK_TOP_PWM5_FB, "pwm5_fb", "rg_pwm_infra", 13),
+       GATE_TOP2(CLK_TOP_USB_1P, "usb_1p", "usb_78m", 14),
+       GATE_TOP2(CLK_TOP_FLASHIF_FREERUN, "flashif_freerun", "ahb_infra_sel",
+               15),
+       GATE_TOP2(CLK_TOP_26M_HDMI_SIFM, "hdmi_sifm_26m", "clk26m_ck", 16),
+       GATE_TOP2(CLK_TOP_26M_CEC, "cec_26m", "clk26m_ck", 17),
+       GATE_TOP2(CLK_TOP_32K_CEC, "cec_32k", "clk32k", 18),
+       GATE_TOP2(CLK_TOP_66M_ETH, "eth_66m", "ahb_infra_d2", 19),
+       GATE_TOP2(CLK_TOP_133M_ETH, "eth_133m", "ahb_infra_sel", 20),
+       GATE_TOP2(CLK_TOP_FETH_25M, "feth_25m", "ifr_eth_25m_sel", 21),
+       GATE_TOP2(CLK_TOP_FETH_50M, "feth_50m", "rg_eth", 22),
+       GATE_TOP2(CLK_TOP_FLASHIF_AXI, "flashif_axi", "ahb_infra_sel", 23),
+       GATE_TOP2(CLK_TOP_USBIF, "usbif", "ahb_infra_sel", 24),
+       GATE_TOP2(CLK_TOP_UART2, "uart2", "rg_uart2", 25),
+       GATE_TOP2(CLK_TOP_BSI, "bsi", "ahb_infra_sel", 26),
+       GATE_TOP2(CLK_TOP_GCPU_B, "gcpu_b", "ahb_infra_sel", 27),
+       GATE_TOP2_I(CLK_TOP_MSDC0_INFRA, "msdc0_infra", "msdc0", 28),
+       GATE_TOP2_I(CLK_TOP_MSDC1_INFRA, "msdc1_infra", "msdc1", 29),
+       GATE_TOP2_I(CLK_TOP_MSDC2_INFRA, "msdc2_infra", "rg_msdc2", 30),
+       GATE_TOP2(CLK_TOP_USB_78M, "usb_78m", "usb_78m_sel", 31),
+       /* TOP3 */
+       GATE_TOP3(CLK_TOP_RG_SPINOR, "rg_spinor", "spinor_sel", 0),
+       GATE_TOP3(CLK_TOP_RG_MSDC2, "rg_msdc2", "msdc2_sel", 1),
+       GATE_TOP3(CLK_TOP_RG_ETH, "rg_eth", "eth_sel", 2),
+       GATE_TOP3(CLK_TOP_RG_VDEC, "rg_vdec", "vdec_mm_sel", 3),
+       GATE_TOP3(CLK_TOP_RG_FDPI0, "rg_fdpi0", "dpi0_mm_sel", 4),
+       GATE_TOP3(CLK_TOP_RG_FDPI1, "rg_fdpi1", "dpi1_mm_sel", 5),
+       GATE_TOP3(CLK_TOP_RG_AXI_MFG, "rg_axi_mfg", "axi_mfg_in_sel", 6),
+       GATE_TOP3(CLK_TOP_RG_SLOW_MFG, "rg_slow_mfg", "slow_mfg_sel", 7),
+       GATE_TOP3(CLK_TOP_RG_AUD1, "rg_aud1", "aud1_sel", 8),
+       GATE_TOP3(CLK_TOP_RG_AUD2, "rg_aud2", "aud2_sel", 9),
+       GATE_TOP3(CLK_TOP_RG_AUD_ENGEN1, "rg_aud_engen1", "aud_engen1_sel", 10),
+       GATE_TOP3(CLK_TOP_RG_AUD_ENGEN2, "rg_aud_engen2", "aud_engen2_sel", 11),
+       GATE_TOP3(CLK_TOP_RG_I2C, "rg_i2c", "i2c_sel", 12),
+       GATE_TOP3(CLK_TOP_RG_PWM_INFRA, "rg_pwm_infra", "pwm_sel", 13),
+       GATE_TOP3(CLK_TOP_RG_AUD_SPDIF_IN, "rg_aud_spdif_in", "aud_spdifin_sel",
+               14),
+       GATE_TOP3(CLK_TOP_RG_UART2, "rg_uart2", "uart2_sel", 15),
+       GATE_TOP3(CLK_TOP_RG_BSI, "rg_bsi", "bsi_sel", 16),
+       GATE_TOP3(CLK_TOP_RG_DBG_ATCLK, "rg_dbg_atclk", "dbg_atclk_sel", 17),
+       GATE_TOP3(CLK_TOP_RG_NFIECC, "rg_nfiecc", "nfiecc_sel", 18),
+       /* TOP4 */
+       GATE_TOP4_I(CLK_TOP_RG_APLL1_D2_EN, "rg_apll1_d2_en", "apll1_d2", 8),
+       GATE_TOP4_I(CLK_TOP_RG_APLL1_D4_EN, "rg_apll1_d4_en", "apll1_d4", 9),
+       GATE_TOP4_I(CLK_TOP_RG_APLL1_D8_EN, "rg_apll1_d8_en", "apll1_d8", 10),
+       GATE_TOP4_I(CLK_TOP_RG_APLL2_D2_EN, "rg_apll2_d2_en", "apll2_d2", 11),
+       GATE_TOP4_I(CLK_TOP_RG_APLL2_D4_EN, "rg_apll2_d4_en", "apll2_d4", 12),
+       GATE_TOP4_I(CLK_TOP_RG_APLL2_D8_EN, "rg_apll2_d8_en", "apll2_d8", 13),
+       /* TOP5 */
+       GATE_TOP5(CLK_TOP_APLL12_DIV0, "apll12_div0", "apll12_ck_div0", 0),
+       GATE_TOP5(CLK_TOP_APLL12_DIV1, "apll12_div1", "apll12_ck_div1", 1),
+       GATE_TOP5(CLK_TOP_APLL12_DIV2, "apll12_div2", "apll12_ck_div2", 2),
+       GATE_TOP5(CLK_TOP_APLL12_DIV3, "apll12_div3", "apll12_ck_div3", 3),
+       GATE_TOP5(CLK_TOP_APLL12_DIV4, "apll12_div4", "apll12_ck_div4", 4),
+       GATE_TOP5(CLK_TOP_APLL12_DIV4B, "apll12_div4b", "apll12_ck_div4b", 5),
+       GATE_TOP5(CLK_TOP_APLL12_DIV5, "apll12_div5", "apll12_ck_div5", 6),
+       GATE_TOP5(CLK_TOP_APLL12_DIV5B, "apll12_div5b", "apll12_ck_div5b", 7),
+       GATE_TOP5(CLK_TOP_APLL12_DIV6, "apll12_div6", "apll12_ck_div6", 8),
+};
+
+static void __init mtk_topckgen_init(struct device_node *node)
+{
+       struct clk_onecell_data *clk_data;
+       int r;
+       void __iomem *base;
+
+       base = of_iomap(node, 0);
+       if (!base) {
+               pr_err("%s(): ioremap failed\n", __func__);
+               return;
+       }
+
+       clk_data = mtk_alloc_clk_data(MT8167_CLK_TOP_NR_CLK);
+
+       mtk_clk_register_fixed_clks(fixed_clks, ARRAY_SIZE(fixed_clks),
+                                   clk_data);
+       mtk_clk_register_gates(node, top_clks, ARRAY_SIZE(top_clks), clk_data);
+
+       mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs), clk_data);
+       mtk_clk_register_composites(top_muxes, ARRAY_SIZE(top_muxes), base,
+               &mt8167_clk_lock, clk_data);
+       mtk_clk_register_dividers(top_adj_divs, ARRAY_SIZE(top_adj_divs),
+                               base, &mt8167_clk_lock, clk_data);
+
+       r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+       if (r)
+               pr_err("%s(): could not register clock provider: %d\n",
+                       __func__, r);
+}
+CLK_OF_DECLARE(mtk_topckgen, "mediatek,mt8167-topckgen", mtk_topckgen_init);
+
+static void __init mtk_infracfg_init(struct device_node *node)
+{
+       struct clk_onecell_data *clk_data;
+       int r;
+       void __iomem *base;
+
+       base = of_iomap(node, 0);
+       if (!base) {
+               pr_err("%s(): ioremap failed\n", __func__);
+               return;
+       }
+
+       clk_data = mtk_alloc_clk_data(CLK_IFR_NR_CLK);
+
+       mtk_clk_register_composites(ifr_muxes, ARRAY_SIZE(ifr_muxes), base,
+               &mt8167_clk_lock, clk_data);
+
+       r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+       if (r)
+               pr_err("%s(): could not register clock provider: %d\n",
+                       __func__, r);
+}
+CLK_OF_DECLARE(mtk_infracfg, "mediatek,mt8167-infracfg", mtk_infracfg_init);
+
+#define MT8167_PLL_FMAX                (2500UL * MHZ)
+
+#define CON0_MT8167_RST_BAR    BIT(27)
+
+#define PLL_B(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits,  \
+                       _pd_reg, _pd_shift, _tuner_reg, _pcw_reg,       \
+                       _pcw_shift, _div_table) {                       \
+               .id = _id,                                              \
+               .name = _name,                                          \
+               .reg = _reg,                                            \
+               .pwr_reg = _pwr_reg,                                    \
+               .en_mask = _en_mask,                                    \
+               .flags = _flags,                                        \
+               .rst_bar_mask = CON0_MT8167_RST_BAR,                    \
+               .fmax = MT8167_PLL_FMAX,                                \
+               .pcwbits = _pcwbits,                                    \
+               .pd_reg = _pd_reg,                                      \
+               .pd_shift = _pd_shift,                                  \
+               .tuner_reg = _tuner_reg,                                \
+               .pcw_reg = _pcw_reg,                                    \
+               .pcw_shift = _pcw_shift,                                \
+               .div_table = _div_table,                                \
+       }
+
+#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits,    \
+                       _pd_reg, _pd_shift, _tuner_reg, _pcw_reg,       \
+                       _pcw_shift)                                     \
+               PLL_B(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, \
+                       _pd_reg, _pd_shift, _tuner_reg, _pcw_reg, _pcw_shift, \
+                       NULL)
+
+static const struct mtk_pll_div_table mmpll_div_table[] = {
+       { .div = 0, .freq = MT8167_PLL_FMAX },
+       { .div = 1, .freq = 1000000000 },
+       { .div = 2, .freq = 604500000 },
+       { .div = 3, .freq = 253500000 },
+       { .div = 4, .freq = 126750000 },
+       { } /* sentinel */
+};
+
+static const struct mtk_pll_data plls[] = {
+       PLL(CLK_APMIXED_ARMPLL, "armpll", 0x0100, 0x0110, 0x00000001, 0,
+               21, 0x0104, 24, 0, 0x0104, 0),
+       PLL(CLK_APMIXED_MAINPLL, "mainpll", 0x0120, 0x0130, 0x00000001,
+               HAVE_RST_BAR, 21, 0x0124, 24, 0, 0x0124, 0),
+       PLL(CLK_APMIXED_UNIVPLL, "univpll", 0x0140, 0x0150, 0x30000001,
+               HAVE_RST_BAR, 7, 0x0144, 24, 0, 0x0144, 0),
+       PLL_B(CLK_APMIXED_MMPLL, "mmpll", 0x0160, 0x0170, 0x00000001, 0,
+               21, 0x0164, 24, 0, 0x0164, 0, mmpll_div_table),
+       PLL(CLK_APMIXED_APLL1, "apll1", 0x0180, 0x0190, 0x00000001, 0,
+               31, 0x0180, 1, 0x0194, 0x0184, 0),
+       PLL(CLK_APMIXED_APLL2, "apll2", 0x01A0, 0x01B0, 0x00000001, 0,
+               31, 0x01A0, 1, 0x01B4, 0x01A4, 0),
+       PLL(CLK_APMIXED_TVDPLL, "tvdpll", 0x01C0, 0x01D0, 0x00000001, 0,
+               21, 0x01C4, 24, 0, 0x01C4, 0),
+       PLL(CLK_APMIXED_LVDSPLL, "lvdspll", 0x01E0, 0x01F0, 0x00000001, 0,
+               21, 0x01E4, 24, 0, 0x01E4, 0),
+};
+
+static void __init mtk_apmixedsys_init(struct device_node *node)
+{
+       struct clk_onecell_data *clk_data;
+       void __iomem *base;
+       int r;
+
+       base = of_iomap(node, 0);
+       if (!base) {
+               pr_err("%s(): ioremap failed\n", __func__);
+               return;
+       }
+
+       clk_data = mtk_alloc_clk_data(MT8167_CLK_APMIXED_NR_CLK);
+
+       mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
+       mtk_clk_register_dividers(apmixed_adj_divs, ARRAY_SIZE(apmixed_adj_divs),
+               base, &mt8167_clk_lock, clk_data);
+
+       r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+       if (r)
+               pr_err("%s(): could not register clock provider: %d\n",
+                       __func__, r);
+
+}
+CLK_OF_DECLARE(mtk_apmixedsys, "mediatek,mt8167-apmixedsys",
+               mtk_apmixedsys_init);
index dabeb43..034da20 100644 (file)
@@ -1,4 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0-only
+menu "Clock support for Amlogic platforms"
+       depends on ARCH_MESON || COMPILE_TEST
+
 config COMMON_CLK_MESON_REGMAP
        tristate
        select REGMAP
@@ -41,8 +44,9 @@ config COMMON_CLK_MESON_CPU_DYNDIV
        select COMMON_CLK_MESON_REGMAP
 
 config COMMON_CLK_MESON8B
-       bool
-       depends on ARCH_MESON
+       bool "Meson8 SoC Clock controller support"
+       depends on ARM
+       default y
        select COMMON_CLK_MESON_REGMAP
        select COMMON_CLK_MESON_MPLL
        select COMMON_CLK_MESON_PLL
@@ -54,8 +58,9 @@ config COMMON_CLK_MESON8B
          want peripherals and CPU frequency scaling to work.
 
 config COMMON_CLK_GXBB
-       bool
-       depends on ARCH_MESON
+       bool "GXBB and GXL SoC clock controllers support"
+       depends on ARM64
+       default y
        select COMMON_CLK_MESON_REGMAP
        select COMMON_CLK_MESON_DUALDIV
        select COMMON_CLK_MESON_VID_PLL_DIV
@@ -69,8 +74,9 @@ config COMMON_CLK_GXBB
          Say Y if you want peripherals and CPU frequency scaling to work.
 
 config COMMON_CLK_AXG
-       bool
-       depends on ARCH_MESON
+       bool "AXG SoC clock controllers support"
+       depends on ARM64
+       default y
        select COMMON_CLK_MESON_REGMAP
        select COMMON_CLK_MESON_DUALDIV
        select COMMON_CLK_MESON_MPLL
@@ -84,7 +90,7 @@ config COMMON_CLK_AXG
 
 config COMMON_CLK_AXG_AUDIO
        tristate "Meson AXG Audio Clock Controller Driver"
-       depends on ARCH_MESON
+       depends on ARM64
        select COMMON_CLK_MESON_REGMAP
        select COMMON_CLK_MESON_PHASE
        select COMMON_CLK_MESON_SCLK_DIV
@@ -94,8 +100,9 @@ config COMMON_CLK_AXG_AUDIO
          aka axg, Say Y if you want audio subsystem to work.
 
 config COMMON_CLK_G12A
-       bool
-       depends on ARCH_MESON
+       bool "G12 and SM1 SoC clock controllers support"
+       depends on ARM64
+       default y
        select COMMON_CLK_MESON_REGMAP
        select COMMON_CLK_MESON_DUALDIV
        select COMMON_CLK_MESON_MPLL
@@ -107,3 +114,4 @@ config COMMON_CLK_G12A
        help
          Support for the clock controller on Amlogic S905D2, S905X2 and S905Y2
          devices, aka g12a. Say Y if you want peripherals to work.
+endmenu
index 53715e3..7c8d021 100644 (file)
        },                                                              \
 }
 
+#define AUD_SCLK_WS(_name, _reg, _width, _shift_ph, _shift_ws, _pname, \
+                   _iflags) {                                          \
+       .data = &(struct meson_sclk_ws_inv_data) {                      \
+               .ph = {                                                 \
+                       .reg_off = (_reg),                              \
+                       .shift   = (_shift_ph),                         \
+                       .width   = (_width),                            \
+               },                                                      \
+               .ws = {                                                 \
+                       .reg_off = (_reg),                              \
+                       .shift   = (_shift_ws),                         \
+                       .width   = (_width),                            \
+               },                                                      \
+       },                                                              \
+       .hw.init = &(struct clk_init_data) {                            \
+               .name = "aud_"#_name,                                   \
+               .ops = &meson_clk_phase_ops,                            \
+               .parent_names = (const char *[]){ #_pname },            \
+               .num_parents = 1,                                       \
+               .flags = (_iflags),                                     \
+       },                                                              \
+}
+
 /* Audio Master Clocks */
 static const struct clk_parent_data mst_mux_parent_data[] = {
        { .fw_name = "mst_in0", },
@@ -254,6 +277,10 @@ static const struct clk_parent_data tdm_lrclk_parent_data[] = {
        AUD_PHASE(tdm##_name##_sclk, _reg, 1, 29,                       \
                  aud_tdm##_name##_sclk_post_en,                        \
                  CLK_DUTY_CYCLE_PARENT | CLK_SET_RATE_PARENT)
+#define AUD_TDM_SCLK_WS(_name, _reg)                                   \
+       AUD_SCLK_WS(tdm##_name##_sclk, _reg, 1, 29, 28,                 \
+                   aud_tdm##_name##_sclk_post_en,                      \
+                   CLK_DUTY_CYCLE_PARENT | CLK_SET_RATE_PARENT)
 
 #define AUD_TDM_LRLCK(_name, _reg)                                     \
        AUD_MUX(tdm##_name##_lrclk, _reg, 0xf, 20,                      \
@@ -499,12 +526,6 @@ static struct clk_regmap tdmin_c_sclk =
        AUD_TDM_SCLK(in_c, AUDIO_CLK_TDMIN_C_CTRL);
 static struct clk_regmap tdmin_lb_sclk =
        AUD_TDM_SCLK(in_lb, AUDIO_CLK_TDMIN_LB_CTRL);
-static struct clk_regmap tdmout_a_sclk =
-       AUD_TDM_SCLK(out_a, AUDIO_CLK_TDMOUT_A_CTRL);
-static struct clk_regmap tdmout_b_sclk =
-       AUD_TDM_SCLK(out_b, AUDIO_CLK_TDMOUT_B_CTRL);
-static struct clk_regmap tdmout_c_sclk =
-       AUD_TDM_SCLK(out_c, AUDIO_CLK_TDMOUT_C_CTRL);
 
 static struct clk_regmap tdmin_a_lrclk =
        AUD_TDM_LRLCK(in_a, AUDIO_CLK_TDMIN_A_CTRL);
@@ -521,6 +542,14 @@ static struct clk_regmap tdmout_b_lrclk =
 static struct clk_regmap tdmout_c_lrclk =
        AUD_TDM_LRLCK(out_c, AUDIO_CLK_TDMOUT_C_CTRL);
 
+/* AXG Clocks */
+static struct clk_regmap axg_tdmout_a_sclk =
+       AUD_TDM_SCLK(out_a, AUDIO_CLK_TDMOUT_A_CTRL);
+static struct clk_regmap axg_tdmout_b_sclk =
+       AUD_TDM_SCLK(out_b, AUDIO_CLK_TDMOUT_B_CTRL);
+static struct clk_regmap axg_tdmout_c_sclk =
+       AUD_TDM_SCLK(out_c, AUDIO_CLK_TDMOUT_C_CTRL);
+
 /* AXG/G12A Clocks */
 static struct clk_hw axg_aud_top = {
        .init = &(struct clk_init_data) {
@@ -591,7 +620,13 @@ static struct clk_regmap g12a_tdm_sclk_pad_1 = AUD_TDM_PAD_CTRL(
 static struct clk_regmap g12a_tdm_sclk_pad_2 = AUD_TDM_PAD_CTRL(
        sclk_pad_2, AUDIO_MST_PAD_CTRL1, 8, sclk_pad_ctrl_parent_data);
 
-/* G12a/SM1 clocks */
+static struct clk_regmap g12a_tdmout_a_sclk =
+       AUD_TDM_SCLK_WS(out_a, AUDIO_CLK_TDMOUT_A_CTRL);
+static struct clk_regmap g12a_tdmout_b_sclk =
+       AUD_TDM_SCLK_WS(out_b, AUDIO_CLK_TDMOUT_B_CTRL);
+static struct clk_regmap g12a_tdmout_c_sclk =
+       AUD_TDM_SCLK_WS(out_c, AUDIO_CLK_TDMOUT_C_CTRL);
+
 static struct clk_regmap toram =
        AUD_PCLK_GATE(toram, AUDIO_CLK_GATE_EN, 20);
 static struct clk_regmap spdifout_b =
@@ -889,9 +924,9 @@ static struct clk_hw_onecell_data axg_audio_hw_onecell_data = {
                [AUD_CLKID_TDMIN_B_SCLK]        = &tdmin_b_sclk.hw,
                [AUD_CLKID_TDMIN_C_SCLK]        = &tdmin_c_sclk.hw,
                [AUD_CLKID_TDMIN_LB_SCLK]       = &tdmin_lb_sclk.hw,
-               [AUD_CLKID_TDMOUT_A_SCLK]       = &tdmout_a_sclk.hw,
-               [AUD_CLKID_TDMOUT_B_SCLK]       = &tdmout_b_sclk.hw,
-               [AUD_CLKID_TDMOUT_C_SCLK]       = &tdmout_c_sclk.hw,
+               [AUD_CLKID_TDMOUT_A_SCLK]       = &axg_tdmout_a_sclk.hw,
+               [AUD_CLKID_TDMOUT_B_SCLK]       = &axg_tdmout_b_sclk.hw,
+               [AUD_CLKID_TDMOUT_C_SCLK]       = &axg_tdmout_c_sclk.hw,
                [AUD_CLKID_TDMIN_A_LRCLK]       = &tdmin_a_lrclk.hw,
                [AUD_CLKID_TDMIN_B_LRCLK]       = &tdmin_b_lrclk.hw,
                [AUD_CLKID_TDMIN_C_LRCLK]       = &tdmin_c_lrclk.hw,
@@ -1026,9 +1061,9 @@ static struct clk_hw_onecell_data g12a_audio_hw_onecell_data = {
                [AUD_CLKID_TDMIN_B_SCLK]        = &tdmin_b_sclk.hw,
                [AUD_CLKID_TDMIN_C_SCLK]        = &tdmin_c_sclk.hw,
                [AUD_CLKID_TDMIN_LB_SCLK]       = &tdmin_lb_sclk.hw,
-               [AUD_CLKID_TDMOUT_A_SCLK]       = &tdmout_a_sclk.hw,
-               [AUD_CLKID_TDMOUT_B_SCLK]       = &tdmout_b_sclk.hw,
-               [AUD_CLKID_TDMOUT_C_SCLK]       = &tdmout_c_sclk.hw,
+               [AUD_CLKID_TDMOUT_A_SCLK]       = &g12a_tdmout_a_sclk.hw,
+               [AUD_CLKID_TDMOUT_B_SCLK]       = &g12a_tdmout_b_sclk.hw,
+               [AUD_CLKID_TDMOUT_C_SCLK]       = &g12a_tdmout_c_sclk.hw,
                [AUD_CLKID_TDMIN_A_LRCLK]       = &tdmin_a_lrclk.hw,
                [AUD_CLKID_TDMIN_B_LRCLK]       = &tdmin_b_lrclk.hw,
                [AUD_CLKID_TDMIN_C_LRCLK]       = &tdmin_c_lrclk.hw,
@@ -1170,9 +1205,9 @@ static struct clk_hw_onecell_data sm1_audio_hw_onecell_data = {
                [AUD_CLKID_TDMIN_B_SCLK]        = &tdmin_b_sclk.hw,
                [AUD_CLKID_TDMIN_C_SCLK]        = &tdmin_c_sclk.hw,
                [AUD_CLKID_TDMIN_LB_SCLK]       = &tdmin_lb_sclk.hw,
-               [AUD_CLKID_TDMOUT_A_SCLK]       = &tdmout_a_sclk.hw,
-               [AUD_CLKID_TDMOUT_B_SCLK]       = &tdmout_b_sclk.hw,
-               [AUD_CLKID_TDMOUT_C_SCLK]       = &tdmout_c_sclk.hw,
+               [AUD_CLKID_TDMOUT_A_SCLK]       = &g12a_tdmout_a_sclk.hw,
+               [AUD_CLKID_TDMOUT_B_SCLK]       = &g12a_tdmout_b_sclk.hw,
+               [AUD_CLKID_TDMOUT_C_SCLK]       = &g12a_tdmout_c_sclk.hw,
                [AUD_CLKID_TDMIN_A_LRCLK]       = &tdmin_a_lrclk.hw,
                [AUD_CLKID_TDMIN_B_LRCLK]       = &tdmin_b_lrclk.hw,
                [AUD_CLKID_TDMIN_C_LRCLK]       = &tdmin_c_lrclk.hw,
@@ -1209,13 +1244,132 @@ static struct clk_hw_onecell_data sm1_audio_hw_onecell_data = {
 };
 
 
-/* Convenience table to populate regmap in .probe()
- * Note that this table is shared between both AXG and G12A,
- * with spdifout_b clocks being exclusive to G12A. Since those
- * clocks are not declared within the AXG onecell table, we do not
- * feel the need to have separate AXG/G12A regmap tables.
- */
+/* Convenience table to populate regmap in .probe(). */
 static struct clk_regmap *const axg_clk_regmaps[] = {
+       &ddr_arb,
+       &pdm,
+       &tdmin_a,
+       &tdmin_b,
+       &tdmin_c,
+       &tdmin_lb,
+       &tdmout_a,
+       &tdmout_b,
+       &tdmout_c,
+       &frddr_a,
+       &frddr_b,
+       &frddr_c,
+       &toddr_a,
+       &toddr_b,
+       &toddr_c,
+       &loopback,
+       &spdifin,
+       &spdifout,
+       &resample,
+       &power_detect,
+       &mst_a_mclk_sel,
+       &mst_b_mclk_sel,
+       &mst_c_mclk_sel,
+       &mst_d_mclk_sel,
+       &mst_e_mclk_sel,
+       &mst_f_mclk_sel,
+       &mst_a_mclk_div,
+       &mst_b_mclk_div,
+       &mst_c_mclk_div,
+       &mst_d_mclk_div,
+       &mst_e_mclk_div,
+       &mst_f_mclk_div,
+       &mst_a_mclk,
+       &mst_b_mclk,
+       &mst_c_mclk,
+       &mst_d_mclk,
+       &mst_e_mclk,
+       &mst_f_mclk,
+       &spdifout_clk_sel,
+       &spdifout_clk_div,
+       &spdifout_clk,
+       &spdifin_clk_sel,
+       &spdifin_clk_div,
+       &spdifin_clk,
+       &pdm_dclk_sel,
+       &pdm_dclk_div,
+       &pdm_dclk,
+       &pdm_sysclk_sel,
+       &pdm_sysclk_div,
+       &pdm_sysclk,
+       &mst_a_sclk_pre_en,
+       &mst_b_sclk_pre_en,
+       &mst_c_sclk_pre_en,
+       &mst_d_sclk_pre_en,
+       &mst_e_sclk_pre_en,
+       &mst_f_sclk_pre_en,
+       &mst_a_sclk_div,
+       &mst_b_sclk_div,
+       &mst_c_sclk_div,
+       &mst_d_sclk_div,
+       &mst_e_sclk_div,
+       &mst_f_sclk_div,
+       &mst_a_sclk_post_en,
+       &mst_b_sclk_post_en,
+       &mst_c_sclk_post_en,
+       &mst_d_sclk_post_en,
+       &mst_e_sclk_post_en,
+       &mst_f_sclk_post_en,
+       &mst_a_sclk,
+       &mst_b_sclk,
+       &mst_c_sclk,
+       &mst_d_sclk,
+       &mst_e_sclk,
+       &mst_f_sclk,
+       &mst_a_lrclk_div,
+       &mst_b_lrclk_div,
+       &mst_c_lrclk_div,
+       &mst_d_lrclk_div,
+       &mst_e_lrclk_div,
+       &mst_f_lrclk_div,
+       &mst_a_lrclk,
+       &mst_b_lrclk,
+       &mst_c_lrclk,
+       &mst_d_lrclk,
+       &mst_e_lrclk,
+       &mst_f_lrclk,
+       &tdmin_a_sclk_sel,
+       &tdmin_b_sclk_sel,
+       &tdmin_c_sclk_sel,
+       &tdmin_lb_sclk_sel,
+       &tdmout_a_sclk_sel,
+       &tdmout_b_sclk_sel,
+       &tdmout_c_sclk_sel,
+       &tdmin_a_sclk_pre_en,
+       &tdmin_b_sclk_pre_en,
+       &tdmin_c_sclk_pre_en,
+       &tdmin_lb_sclk_pre_en,
+       &tdmout_a_sclk_pre_en,
+       &tdmout_b_sclk_pre_en,
+       &tdmout_c_sclk_pre_en,
+       &tdmin_a_sclk_post_en,
+       &tdmin_b_sclk_post_en,
+       &tdmin_c_sclk_post_en,
+       &tdmin_lb_sclk_post_en,
+       &tdmout_a_sclk_post_en,
+       &tdmout_b_sclk_post_en,
+       &tdmout_c_sclk_post_en,
+       &tdmin_a_sclk,
+       &tdmin_b_sclk,
+       &tdmin_c_sclk,
+       &tdmin_lb_sclk,
+       &axg_tdmout_a_sclk,
+       &axg_tdmout_b_sclk,
+       &axg_tdmout_c_sclk,
+       &tdmin_a_lrclk,
+       &tdmin_b_lrclk,
+       &tdmin_c_lrclk,
+       &tdmin_lb_lrclk,
+       &tdmout_a_lrclk,
+       &tdmout_b_lrclk,
+       &tdmout_c_lrclk,
+};
+
+static struct clk_regmap *const g12a_clk_regmaps[] = {
        &ddr_arb,
        &pdm,
        &tdmin_a,
@@ -1328,9 +1482,9 @@ static struct clk_regmap *const axg_clk_regmaps[] = {
        &tdmin_b_sclk,
        &tdmin_c_sclk,
        &tdmin_lb_sclk,
-       &tdmout_a_sclk,
-       &tdmout_b_sclk,
-       &tdmout_c_sclk,
+       &g12a_tdmout_a_sclk,
+       &g12a_tdmout_b_sclk,
+       &g12a_tdmout_c_sclk,
        &tdmin_a_lrclk,
        &tdmin_b_lrclk,
        &tdmin_c_lrclk,
@@ -1465,9 +1619,9 @@ static struct clk_regmap *const sm1_clk_regmaps[] = {
        &tdmin_b_sclk,
        &tdmin_c_sclk,
        &tdmin_lb_sclk,
-       &tdmout_a_sclk,
-       &tdmout_b_sclk,
-       &tdmout_c_sclk,
+       &g12a_tdmout_a_sclk,
+       &g12a_tdmout_b_sclk,
+       &g12a_tdmout_c_sclk,
        &tdmin_a_lrclk,
        &tdmin_b_lrclk,
        &tdmin_c_lrclk,
@@ -1713,8 +1867,8 @@ static const struct audioclk_data axg_audioclk_data = {
 };
 
 static const struct audioclk_data g12a_audioclk_data = {
-       .regmap_clks = axg_clk_regmaps,
-       .regmap_clk_num = ARRAY_SIZE(axg_clk_regmaps),
+       .regmap_clks = g12a_clk_regmaps,
+       .regmap_clk_num = ARRAY_SIZE(g12a_clk_regmaps),
        .hw_onecell_data = &g12a_audio_hw_onecell_data,
        .reset_offset = AUDIO_SW_RESET,
        .reset_num = 26,
index fe22e17..a676343 100644 (file)
@@ -125,6 +125,62 @@ const struct clk_ops meson_clk_triphase_ops = {
 };
 EXPORT_SYMBOL_GPL(meson_clk_triphase_ops);
 
+/*
+ * This is a special clock for the audio controller.
+ * This drive a bit clock inverter for which the
+ * opposite value of the inverter bit needs to be manually
+ * set into another bit
+ */
+static inline struct meson_sclk_ws_inv_data *
+meson_sclk_ws_inv_data(struct clk_regmap *clk)
+{
+       return (struct meson_sclk_ws_inv_data *)clk->data;
+}
+
+static int meson_sclk_ws_inv_sync(struct clk_hw *hw)
+{
+       struct clk_regmap *clk = to_clk_regmap(hw);
+       struct meson_sclk_ws_inv_data *tph = meson_sclk_ws_inv_data(clk);
+       unsigned int val;
+
+       /* Get phase and sync the inverted value to ws */
+       val = meson_parm_read(clk->map, &tph->ph);
+       meson_parm_write(clk->map, &tph->ws, val ? 0 : 1);
+
+       return 0;
+}
+
+static int meson_sclk_ws_inv_get_phase(struct clk_hw *hw)
+{
+       struct clk_regmap *clk = to_clk_regmap(hw);
+       struct meson_sclk_ws_inv_data *tph = meson_sclk_ws_inv_data(clk);
+       unsigned int val;
+
+       val = meson_parm_read(clk->map, &tph->ph);
+
+       return meson_clk_degrees_from_val(val, tph->ph.width);
+}
+
+static int meson_sclk_ws_inv_set_phase(struct clk_hw *hw, int degrees)
+{
+       struct clk_regmap *clk = to_clk_regmap(hw);
+       struct meson_sclk_ws_inv_data *tph = meson_sclk_ws_inv_data(clk);
+       unsigned int val;
+
+       val = meson_clk_degrees_to_val(degrees, tph->ph.width);
+       meson_parm_write(clk->map, &tph->ph, val);
+       meson_parm_write(clk->map, &tph->ws, val ? 0 : 1);
+       return 0;
+}
+
+const struct clk_ops meson_sclk_ws_inv_ops = {
+       .init           = meson_sclk_ws_inv_sync,
+       .get_phase      = meson_sclk_ws_inv_get_phase,
+       .set_phase      = meson_sclk_ws_inv_set_phase,
+};
+EXPORT_SYMBOL_GPL(meson_sclk_ws_inv_ops);
+
+
 MODULE_DESCRIPTION("Amlogic phase driver");
 MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>");
 MODULE_LICENSE("GPL v2");
index 5579f9c..b637b9b 100644 (file)
@@ -20,7 +20,13 @@ struct meson_clk_triphase_data {
        struct parm ph2;
 };
 
+struct meson_sclk_ws_inv_data {
+       struct parm ph;
+       struct parm ws;
+};
+
 extern const struct clk_ops meson_clk_phase_ops;
 extern const struct clk_ops meson_clk_triphase_ops;
+extern const struct clk_ops meson_sclk_ws_inv_ops;
 
 #endif /* __MESON_CLK_PHASE_H */
index 9803d44..b814d44 100644 (file)
@@ -298,6 +298,17 @@ static struct clk_regmap g12a_fclk_div2 = {
                        &g12a_fclk_div2_div.hw
                },
                .num_parents = 1,
+               /*
+                * Similar to fclk_div3, it seems that this clock is used by
+                * the resident firmware and is required by the platform to
+                * operate correctly.
+                * Until the following condition are met, we need this clock to
+                * be marked as critical:
+                * a) Mark the clock used by a firmware resource, if possible
+                * b) CCF has a clock hand-off mechanism to make the sure the
+                *    clock stays on until the proper driver comes along
+                */
+               .flags = CLK_IS_CRITICAL,
        },
 };
 
index bf8bea6..3a6d84c 100644 (file)
@@ -57,7 +57,7 @@ int meson_aoclkc_probe(struct platform_device *pdev)
        rstc->data = data;
        rstc->regmap = regmap;
        rstc->reset.ops = &meson_aoclk_reset_ops;
-       rstc->reset.nr_resets = data->num_reset,
+       rstc->reset.nr_resets = data->num_reset;
        rstc->reset.of_node = dev->of_node;
        ret = devm_reset_controller_register(dev, &rstc->reset);
        if (ret) {
index 67208ae..0839fb2 100644 (file)
@@ -347,9 +347,9 @@ static struct mmp_param_mux_clk mmp3_apmu_mux_clks[] = {
 };
 
 static struct mmp_param_div_clk apmu_div_clks[] = {
-       {0, "disp0_div", "disp0_mux", CLK_SET_RATE_PARENT, APMU_DISP0, 8, 4, 0, &disp0_lock},
+       {0, "disp0_div", "disp0_mux", CLK_SET_RATE_PARENT, APMU_DISP0, 8, 4, CLK_DIVIDER_ONE_BASED, &disp0_lock},
        {0, "disp0_sphy_div", "disp0_mux", CLK_SET_RATE_PARENT, APMU_DISP0, 15, 5, 0, &disp0_lock},
-       {0, "disp1_div", "disp1_mux", CLK_SET_RATE_PARENT, APMU_DISP1, 8, 4, 0, &disp1_lock},
+       {0, "disp1_div", "disp1_mux", CLK_SET_RATE_PARENT, APMU_DISP1, 8, 4, CLK_DIVIDER_ONE_BASED, &disp1_lock},
        {0, "ccic0_sphy_div", "ccic0_mix_clk", CLK_SET_RATE_PARENT, APMU_CCIC0, 10, 5, 0, &ccic0_lock},
        {0, "ccic1_sphy_div", "ccic1_mix_clk", CLK_SET_RATE_PARENT, APMU_CCIC1, 10, 5, 0, &ccic1_lock},
 };
index cede7b4..998fc42 100644 (file)
@@ -68,7 +68,6 @@ static struct mmp_clk_factor_tbl uart_factor_tbl[] = {
 
 static void pxa1928_pll_init(struct pxa1928_clk_unit *pxa_unit)
 {
-       struct clk *clk;
        struct mmp_clk_unit *unit = &pxa_unit->unit;
 
        mmp_register_fixed_rate_clks(unit, fixed_rate_clks,
@@ -77,7 +76,7 @@ static void pxa1928_pll_init(struct pxa1928_clk_unit *pxa_unit)
        mmp_register_fixed_factor_clks(unit, fixed_factor_clks,
                                        ARRAY_SIZE(fixed_factor_clks));
 
-       clk = mmp_clk_register_factor("uart_pll", "pll1_416",
+       mmp_clk_register_factor("uart_pll", "pll1_416",
                                CLK_SET_RATE_PARENT,
                                pxa_unit->mpmu_base + MPMU_UART_PLL,
                                &uart_factor_masks, uart_factor_tbl,
index 6b39430..b4259b6 100644 (file)
@@ -197,7 +197,7 @@ static int ap_cpu_clk_set_rate(struct clk_hw *hw, unsigned long rate,
 
        stable_bit = BIT(clk->pll_regs->ratio_state_offset +
                         clk->cluster *
-                        clk->pll_regs->ratio_state_cluster_offset),
+                        clk->pll_regs->ratio_state_cluster_offset);
        ret = regmap_read_poll_timeout(clk->pll_cr_base,
                                       clk->pll_regs->ratio_state_reg, reg,
                                       reg & stable_bit, STATUS_POLL_PERIOD_US,
index f131d28..5768e0f 100644 (file)
 #define MUX_RO_RATE_RO_OPS(name, clk_name)                     \
        static struct clk_hw name ## _mux_hw;                   \
        static struct clk_hw name ## _rate_hw;                  \
-       static struct clk_ops name ## _mux_ops = {              \
+       static const struct clk_ops name ## _mux_ops = {        \
                .get_parent = name ## _get_parent,              \
                .set_parent = dummy_clk_set_parent,             \
        };                                                      \
-       static struct clk_ops name ## _rate_ops = {             \
+       static const struct clk_ops name ## _rate_ops = {       \
                .recalc_rate = name ## _get_rate,               \
        };                                                      \
        static struct clk * __init clk_register_ ## name(void)  \
@@ -38,7 +38,7 @@
 
 #define RATE_RO_OPS(name, clk_name)                            \
        static struct clk_hw name ## _rate_hw;                  \
-       static const struct clk_ops name ## _rate_ops = {               \
+       static const struct clk_ops name ## _rate_ops = {       \
                .recalc_rate = name ## _get_rate,               \
        };                                                      \
        static struct clk * __init clk_register_ ## name(void)  \
@@ -53,7 +53,7 @@
 
 #define RATE_OPS(name, clk_name)                               \
        static struct clk_hw name ## _rate_hw;                  \
-       static struct clk_ops name ## _rate_ops = {             \
+       static const struct clk_ops name ## _rate_ops = {       \
                .recalc_rate = name ## _get_rate,               \
                .set_rate = name ## _set_rate,                  \
                .determine_rate = name ## _determine_rate,      \
index 28e8730..18915d6 100644 (file)
@@ -30,6 +30,7 @@ config CLK_RENESAS
        select CLK_R8A77980 if ARCH_R8A77980
        select CLK_R8A77990 if ARCH_R8A77990
        select CLK_R8A77995 if ARCH_R8A77995
+       select CLK_R8A779A0 if ARCH_R8A779A0
        select CLK_R9A06G032 if ARCH_R9A06G032
        select CLK_SH73A0 if ARCH_SH73A0
 
@@ -145,6 +146,10 @@ config CLK_R8A77995
        bool "R-Car D3 clock support" if COMPILE_TEST
        select CLK_RCAR_GEN3_CPG
 
+config CLK_R8A779A0
+       bool "R-Car V3U clock support" if COMPILE_TEST
+       select CLK_RENESAS_CPG_MSSR
+
 config CLK_R9A06G032
        bool "Renesas R9A06G032 clock driver"
        help
@@ -162,7 +167,7 @@ config CLK_RCAR_GEN2_CPG
        select CLK_RENESAS_CPG_MSSR
 
 config CLK_RCAR_GEN3_CPG
-       bool "R-Car Gen3 CPG clock support" if COMPILE_TEST
+       bool "R-Car Gen3 and RZ/G2 CPG clock support" if COMPILE_TEST
        select CLK_RENESAS_CPG_MSSR
 
 config CLK_RCAR_USB2_CLOCK_SEL
index c7c03ab..c803912 100644 (file)
@@ -27,6 +27,7 @@ obj-$(CONFIG_CLK_R8A77970)            += r8a77970-cpg-mssr.o
 obj-$(CONFIG_CLK_R8A77980)             += r8a77980-cpg-mssr.o
 obj-$(CONFIG_CLK_R8A77990)             += r8a77990-cpg-mssr.o
 obj-$(CONFIG_CLK_R8A77995)             += r8a77995-cpg-mssr.o
+obj-$(CONFIG_CLK_R8A779A0)             += r8a779a0-cpg-mssr.o
 obj-$(CONFIG_CLK_R9A06G032)            += r9a06g032-clocks.o
 obj-$(CONFIG_CLK_SH73A0)               += clk-sh73a0.o
 
index 443bff0..a85227c 100644 (file)
@@ -214,7 +214,7 @@ const struct cpg_mssr_info r7s9210_cpg_mssr_info __initconst = {
        .cpg_clk_register = rza2_cpg_clk_register,
 
        /* RZ/A2 has Standby Control Registers */
-       .stbyctrl = true,
+       .reg_layout = CLK_REG_LAYOUT_RZ_A,
 };
 
 static void __init r7s9210_cpg_mssr_early_init(struct device_node *np)
index e919828..e541489 100644 (file)
@@ -97,7 +97,8 @@ static const struct mssr_mod_clk r8a7742_mod_clks[] __initconst = {
        DEF_MOD("tmu0",                  125,   R8A7742_CLK_CP),
        DEF_MOD("vsp1du1",               127,   R8A7742_CLK_ZS),
        DEF_MOD("vsp1du0",               128,   R8A7742_CLK_ZS),
-       DEF_MOD("vsp1-sy",               131,   R8A7742_CLK_ZS),
+       DEF_MOD("vspr",                  130,   R8A7742_CLK_ZS),
+       DEF_MOD("vsps",                  131,   R8A7742_CLK_ZS),
        DEF_MOD("scifa2",                202,   R8A7742_CLK_MP),
        DEF_MOD("scifa1",                203,   R8A7742_CLK_MP),
        DEF_MOD("scifa0",                204,   R8A7742_CLK_MP),
index c01d9af..0bba12a 100644 (file)
@@ -92,7 +92,7 @@ static const struct mssr_mod_clk r8a7743_mod_clks[] __initconst = {
        DEF_MOD("tmu0",                  125,   R8A7743_CLK_CP),
        DEF_MOD("vsp1du1",               127,   R8A7743_CLK_ZS),
        DEF_MOD("vsp1du0",               128,   R8A7743_CLK_ZS),
-       DEF_MOD("vsp1-sy",               131,   R8A7743_CLK_ZS),
+       DEF_MOD("vsps",                  131,   R8A7743_CLK_ZS),
        DEF_MOD("scifa2",                202,   R8A7743_CLK_MP),
        DEF_MOD("scifa1",                203,   R8A7743_CLK_MP),
        DEF_MOD("scifa0",                204,   R8A7743_CLK_MP),
index 493874e..dc4a64e 100644 (file)
@@ -90,7 +90,7 @@ static const struct mssr_mod_clk r8a7745_mod_clks[] __initconst = {
        DEF_MOD("cmt0",                  124,   R8A7745_CLK_R),
        DEF_MOD("tmu0",                  125,   R8A7745_CLK_CP),
        DEF_MOD("vsp1du0",               128,   R8A7745_CLK_ZS),
-       DEF_MOD("vsp1-sy",               131,   R8A7745_CLK_ZS),
+       DEF_MOD("vsps",                  131,   R8A7745_CLK_ZS),
        DEF_MOD("scifa2",                202,   R8A7745_CLK_MP),
        DEF_MOD("scifa1",                203,   R8A7745_CLK_MP),
        DEF_MOD("scifa0",                204,   R8A7745_CLK_MP),
index d81ae65..f3d6e65 100644 (file)
@@ -85,7 +85,7 @@ static const struct mssr_mod_clk r8a77470_mod_clks[] __initconst = {
        DEF_MOD("tmu2",                  122,   R8A77470_CLK_P),
        DEF_MOD("cmt0",                  124,   R8A77470_CLK_R),
        DEF_MOD("vsp1du0",               128,   R8A77470_CLK_ZS),
-       DEF_MOD("vsp1-sy",               131,   R8A77470_CLK_ZS),
+       DEF_MOD("vsps",                  131,   R8A77470_CLK_ZS),
        DEF_MOD("msiof2",                205,   R8A77470_CLK_MP),
        DEF_MOD("msiof1",                208,   R8A77470_CLK_MP),
        DEF_MOD("sys-dmac1",             218,   R8A77470_CLK_ZS),
index c57cb93..f7d233e 100644 (file)
@@ -108,8 +108,8 @@ static const struct mssr_mod_clk r8a7790_mod_clks[] __initconst = {
        DEF_MOD("tmu0",                  125,   R8A7790_CLK_CP),
        DEF_MOD("vsp1du1",               127,   R8A7790_CLK_ZS),
        DEF_MOD("vsp1du0",               128,   R8A7790_CLK_ZS),
-       DEF_MOD("vsp1-rt",               130,   R8A7790_CLK_ZS),
-       DEF_MOD("vsp1-sy",               131,   R8A7790_CLK_ZS),
+       DEF_MOD("vspr",                  130,   R8A7790_CLK_ZS),
+       DEF_MOD("vsps",                  131,   R8A7790_CLK_ZS),
        DEF_MOD("scifa2",                202,   R8A7790_CLK_MP),
        DEF_MOD("scifa1",                203,   R8A7790_CLK_MP),
        DEF_MOD("scifa0",                204,   R8A7790_CLK_MP),
index 65702de..a0de784 100644 (file)
@@ -102,7 +102,7 @@ static const struct mssr_mod_clk r8a7791_mod_clks[] __initconst = {
        DEF_MOD("tmu0",                  125,   R8A7791_CLK_CP),
        DEF_MOD("vsp1du1",               127,   R8A7791_CLK_ZS),
        DEF_MOD("vsp1du0",               128,   R8A7791_CLK_ZS),
-       DEF_MOD("vsp1-sy",               131,   R8A7791_CLK_ZS),
+       DEF_MOD("vsps",                  131,   R8A7791_CLK_ZS),
        DEF_MOD("scifa2",                202,   R8A7791_CLK_MP),
        DEF_MOD("scifa1",                203,   R8A7791_CLK_MP),
        DEF_MOD("scifa0",                204,   R8A7791_CLK_MP),
index cf8b84a..77af250 100644 (file)
@@ -88,7 +88,7 @@ static const struct mssr_mod_clk r8a7792_mod_clks[] __initconst = {
        DEF_MOD("tmu0",                  125,   R8A7792_CLK_CP),
        DEF_MOD("vsp1du1",               127,   R8A7792_CLK_ZS),
        DEF_MOD("vsp1du0",               128,   R8A7792_CLK_ZS),
-       DEF_MOD("vsp1-sy",               131,   R8A7792_CLK_ZS),
+       DEF_MOD("vsps",                  131,   R8A7792_CLK_ZS),
        DEF_MOD("msiof1",                208,   R8A7792_CLK_MP),
        DEF_MOD("sys-dmac1",             218,   R8A7792_CLK_ZS),
        DEF_MOD("sys-dmac0",             219,   R8A7792_CLK_ZS),
index c194869..4d7fa26 100644 (file)
@@ -97,7 +97,7 @@ static const struct mssr_mod_clk r8a7794_mod_clks[] __initconst = {
        DEF_MOD("cmt0",                  124,   R8A7794_CLK_R),
        DEF_MOD("tmu0",                  125,   R8A7794_CLK_CP),
        DEF_MOD("vsp1du0",               128,   R8A7794_CLK_ZS),
-       DEF_MOD("vsp1-sy",               131,   R8A7794_CLK_ZS),
+       DEF_MOD("vsps",                  131,   R8A7794_CLK_ZS),
        DEF_MOD("scifa2",                202,   R8A7794_CLK_MP),
        DEF_MOD("scifa1",                203,   R8A7794_CLK_MP),
        DEF_MOD("scifa0",                204,   R8A7794_CLK_MP),
diff --git a/drivers/clk/renesas/r8a779a0-cpg-mssr.c b/drivers/clk/renesas/r8a779a0-cpg-mssr.c
new file mode 100644 (file)
index 0000000..17ebbac
--- /dev/null
@@ -0,0 +1,276 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * r8a779a0 Clock Pulse Generator / Module Standby and Software Reset
+ *
+ * Copyright (C) 2020 Renesas Electronics Corp.
+ *
+ * Based on r8a7795-cpg-mssr.c
+ *
+ * Copyright (C) 2015 Glider bvba
+ * Copyright (C) 2015 Renesas Electronics Corp.
+ */
+
+#include <linux/bug.h>
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/pm.h>
+#include <linux/slab.h>
+#include <linux/soc/renesas/rcar-rst.h>
+
+#include <dt-bindings/clock/r8a779a0-cpg-mssr.h>
+
+#include "renesas-cpg-mssr.h"
+#include "rcar-gen3-cpg.h"
+
+enum rcar_r8a779a0_clk_types {
+       CLK_TYPE_R8A779A0_MAIN = CLK_TYPE_CUSTOM,
+       CLK_TYPE_R8A779A0_PLL1,
+       CLK_TYPE_R8A779A0_PLL2X_3X,     /* PLL[23][01] */
+       CLK_TYPE_R8A779A0_PLL5,
+       CLK_TYPE_R8A779A0_MDSEL,        /* Select parent/divider using mode pin */
+       CLK_TYPE_R8A779A0_OSC,  /* OSC EXTAL predivider and fixed divider */
+};
+
+struct rcar_r8a779a0_cpg_pll_config {
+       u8 extal_div;
+       u8 pll1_mult;
+       u8 pll1_div;
+       u8 pll5_mult;
+       u8 pll5_div;
+       u8 osc_prediv;
+};
+
+enum clk_ids {
+       /* Core Clock Outputs exported to DT */
+       LAST_DT_CORE_CLK = R8A779A0_CLK_OSC,
+
+       /* External Input Clocks */
+       CLK_EXTAL,
+       CLK_EXTALR,
+
+       /* Internal Core Clocks */
+       CLK_MAIN,
+       CLK_PLL1,
+       CLK_PLL20,
+       CLK_PLL21,
+       CLK_PLL30,
+       CLK_PLL31,
+       CLK_PLL5,
+       CLK_PLL1_DIV2,
+       CLK_PLL20_DIV2,
+       CLK_PLL21_DIV2,
+       CLK_PLL30_DIV2,
+       CLK_PLL31_DIV2,
+       CLK_PLL5_DIV2,
+       CLK_PLL5_DIV4,
+       CLK_S1,
+       CLK_S2,
+       CLK_S3,
+       CLK_SDSRC,
+       CLK_RPCSRC,
+       CLK_OCO,
+
+       /* Module Clocks */
+       MOD_CLK_BASE
+};
+
+#define DEF_PLL(_name, _id, _offset)   \
+       DEF_BASE(_name, _id, CLK_TYPE_R8A779A0_PLL2X_3X, CLK_MAIN, \
+                .offset = _offset)
+
+static const struct cpg_core_clk r8a779a0_core_clks[] __initconst = {
+       /* External Clock Inputs */
+       DEF_INPUT("extal",  CLK_EXTAL),
+       DEF_INPUT("extalr", CLK_EXTALR),
+
+       /* Internal Core Clocks */
+       DEF_BASE(".main", CLK_MAIN,     CLK_TYPE_R8A779A0_MAIN, CLK_EXTAL),
+       DEF_BASE(".pll1", CLK_PLL1,     CLK_TYPE_R8A779A0_PLL1, CLK_MAIN),
+       DEF_BASE(".pll5", CLK_PLL5,     CLK_TYPE_R8A779A0_PLL5, CLK_MAIN),
+       DEF_PLL(".pll20", CLK_PLL20,    0x0834),
+       DEF_PLL(".pll21", CLK_PLL21,    0x0838),
+       DEF_PLL(".pll30", CLK_PLL30,    0x083c),
+       DEF_PLL(".pll31", CLK_PLL31,    0x0840),
+
+       DEF_FIXED(".pll1_div2",         CLK_PLL1_DIV2,  CLK_PLL1,       2, 1),
+       DEF_FIXED(".pll20_div2",        CLK_PLL20_DIV2, CLK_PLL20,      2, 1),
+       DEF_FIXED(".pll21_div2",        CLK_PLL21_DIV2, CLK_PLL21,      2, 1),
+       DEF_FIXED(".pll30_div2",        CLK_PLL30_DIV2, CLK_PLL30,      2, 1),
+       DEF_FIXED(".pll31_div2",        CLK_PLL31_DIV2, CLK_PLL31,      2, 1),
+       DEF_FIXED(".pll5_div2",         CLK_PLL5_DIV2,  CLK_PLL5,       2, 1),
+       DEF_FIXED(".pll5_div4",         CLK_PLL5_DIV4,  CLK_PLL5_DIV2,  2, 1),
+       DEF_FIXED(".s1",                CLK_S1,         CLK_PLL1_DIV2,  2, 1),
+       DEF_FIXED(".s3",                CLK_S3,         CLK_PLL1_DIV2,  4, 1),
+       DEF_RATE(".oco",                CLK_OCO,        32768),
+
+       /* Core Clock Outputs */
+       DEF_FIXED("zx",         R8A779A0_CLK_ZX,        CLK_PLL20_DIV2, 2, 1),
+       DEF_FIXED("s1d1",       R8A779A0_CLK_S1D1,      CLK_S1,         1, 1),
+       DEF_FIXED("s1d2",       R8A779A0_CLK_S1D2,      CLK_S1,         2, 1),
+       DEF_FIXED("s1d4",       R8A779A0_CLK_S1D4,      CLK_S1,         4, 1),
+       DEF_FIXED("s1d8",       R8A779A0_CLK_S1D8,      CLK_S1,         8, 1),
+       DEF_FIXED("s1d12",      R8A779A0_CLK_S1D12,     CLK_S1,         12, 1),
+       DEF_FIXED("s3d1",       R8A779A0_CLK_S3D1,      CLK_S3,         1, 1),
+       DEF_FIXED("s3d2",       R8A779A0_CLK_S3D2,      CLK_S3,         2, 1),
+       DEF_FIXED("s3d4",       R8A779A0_CLK_S3D4,      CLK_S3,         4, 1),
+       DEF_FIXED("zs",         R8A779A0_CLK_ZS,        CLK_PLL1_DIV2,  4, 1),
+       DEF_FIXED("zt",         R8A779A0_CLK_ZT,        CLK_PLL1_DIV2,  2, 1),
+       DEF_FIXED("ztr",        R8A779A0_CLK_ZTR,       CLK_PLL1_DIV2,  2, 1),
+       DEF_FIXED("zr",         R8A779A0_CLK_ZR,        CLK_PLL1_DIV2,  1, 1),
+       DEF_FIXED("dsi",        R8A779A0_CLK_DSI,       CLK_PLL5_DIV4,  1, 1),
+       DEF_FIXED("cnndsp",     R8A779A0_CLK_CNNDSP,    CLK_PLL5_DIV4,  1, 1),
+       DEF_FIXED("vip",        R8A779A0_CLK_VIP,       CLK_PLL5,       5, 1),
+       DEF_FIXED("adgh",       R8A779A0_CLK_ADGH,      CLK_PLL5_DIV4,  1, 1),
+       DEF_FIXED("icu",        R8A779A0_CLK_ICU,       CLK_PLL5_DIV4,  2, 1),
+       DEF_FIXED("icud2",      R8A779A0_CLK_ICUD2,     CLK_PLL5_DIV4,  4, 1),
+       DEF_FIXED("vcbus",      R8A779A0_CLK_VCBUS,     CLK_PLL5_DIV4,  1, 1),
+       DEF_FIXED("cbfusa",     R8A779A0_CLK_CBFUSA,    CLK_MAIN,       2, 1),
+
+       DEF_DIV6P1("mso",       R8A779A0_CLK_MSO,       CLK_PLL5_DIV4,  0x87c),
+       DEF_DIV6P1("canfd",     R8A779A0_CLK_CANFD,     CLK_PLL5_DIV4,  0x878),
+       DEF_DIV6P1("csi0",      R8A779A0_CLK_CSI0,      CLK_PLL5_DIV4,  0x880),
+
+       DEF_GEN3_OSC("osc",     R8A779A0_CLK_OSC,       CLK_EXTAL,      8),
+       DEF_GEN3_MDSEL("r",     R8A779A0_CLK_R, 29, CLK_EXTALR, 1, CLK_OCO, 1),
+};
+
+static const struct mssr_mod_clk r8a779a0_mod_clks[] __initconst = {
+       DEF_MOD("scif0",        702,    R8A779A0_CLK_S1D8),
+       DEF_MOD("scif1",        703,    R8A779A0_CLK_S1D8),
+       DEF_MOD("scif3",        704,    R8A779A0_CLK_S1D8),
+       DEF_MOD("scif4",        705,    R8A779A0_CLK_S1D8),
+};
+
+static spinlock_t cpg_lock;
+
+static const struct rcar_r8a779a0_cpg_pll_config *cpg_pll_config __initdata;
+static unsigned int cpg_clk_extalr __initdata;
+static u32 cpg_mode __initdata;
+
+struct clk * __init rcar_r8a779a0_cpg_clk_register(struct device *dev,
+       const struct cpg_core_clk *core, const struct cpg_mssr_info *info,
+       struct clk **clks, void __iomem *base,
+       struct raw_notifier_head *notifiers)
+{
+       const struct clk *parent;
+       unsigned int mult = 1;
+       unsigned int div = 1;
+       u32 value;
+
+       parent = clks[core->parent & 0xffff];   /* some types use high bits */
+       if (IS_ERR(parent))
+               return ERR_CAST(parent);
+
+       switch (core->type) {
+       case CLK_TYPE_R8A779A0_MAIN:
+               div = cpg_pll_config->extal_div;
+               break;
+
+       case CLK_TYPE_R8A779A0_PLL1:
+               mult = cpg_pll_config->pll1_mult;
+               div = cpg_pll_config->pll1_div;
+               break;
+
+       case CLK_TYPE_R8A779A0_PLL2X_3X:
+               value = readl(base + core->offset);
+               mult = (((value >> 24) & 0x7f) + 1) * 2;
+               break;
+
+       case CLK_TYPE_R8A779A0_PLL5:
+               mult = cpg_pll_config->pll5_mult;
+               div = cpg_pll_config->pll5_div;
+               break;
+
+       case CLK_TYPE_R8A779A0_MDSEL:
+               /*
+                * Clock selectable between two parents and two fixed dividers
+                * using a mode pin
+                */
+               if (cpg_mode & BIT(core->offset)) {
+                       div = core->div & 0xffff;
+               } else {
+                       parent = clks[core->parent >> 16];
+                       if (IS_ERR(parent))
+                               return ERR_CAST(parent);
+                       div = core->div >> 16;
+               }
+               mult = 1;
+               break;
+
+       case CLK_TYPE_R8A779A0_OSC:
+               /*
+                * Clock combining OSC EXTAL predivider and a fixed divider
+                */
+               div = cpg_pll_config->osc_prediv * core->div;
+               break;
+
+       default:
+               return ERR_PTR(-EINVAL);
+       }
+
+       return clk_register_fixed_factor(NULL, core->name,
+                                        __clk_get_name(parent), 0, mult, div);
+}
+
+/*
+ * CPG Clock Data
+ */
+/*
+ *   MD         EXTAL          PLL1    PLL20   PLL30   PLL4    PLL5    OSC
+ * 14 13 (MHz)                    21      31
+ * --------------------------------------------------------
+ * 0  0         16.66 x 1      x128    x216    x128    x144    x192    /16
+ * 0  1         20    x 1      x106    x180    x106    x120    x160    /19
+ * 1  0         Prohibited setting
+ * 1  1         33.33 / 2      x128    x216    x128    x144    x192    /32
+ */
+#define CPG_PLL_CONFIG_INDEX(md)       ((((md) & BIT(14)) >> 13) | \
+                                        (((md) & BIT(13)) >> 13))
+
+static const struct rcar_r8a779a0_cpg_pll_config cpg_pll_configs[4] = {
+       /* EXTAL div    PLL1 mult/div   PLL5 mult/div   OSC prediv */
+       { 1,            128,    1,      192,    1,      16,     },
+       { 1,            106,    1,      160,    1,      19,     },
+       { 0,            0,      0,      0,      0,      0,      },
+       { 2,            128,    1,      192,    1,      32,     },
+};
+
+static int __init r8a779a0_cpg_mssr_init(struct device *dev)
+{
+       int error;
+
+       error = rcar_rst_read_mode_pins(&cpg_mode);
+       if (error)
+               return error;
+
+       cpg_pll_config = &cpg_pll_configs[CPG_PLL_CONFIG_INDEX(cpg_mode)];
+       cpg_clk_extalr = CLK_EXTALR;
+       spin_lock_init(&cpg_lock);
+
+       return 0;
+}
+
+const struct cpg_mssr_info r8a779a0_cpg_mssr_info __initconst = {
+       /* Core Clocks */
+       .core_clks = r8a779a0_core_clks,
+       .num_core_clks = ARRAY_SIZE(r8a779a0_core_clks),
+       .last_dt_core_clk = LAST_DT_CORE_CLK,
+       .num_total_core_clks = MOD_CLK_BASE,
+
+       /* Module Clocks */
+       .mod_clks = r8a779a0_mod_clks,
+       .num_mod_clks = ARRAY_SIZE(r8a779a0_mod_clks),
+       .num_hw_mod_clks = 15 * 32,
+
+       /* Callbacks */
+       .init = r8a779a0_cpg_mssr_init,
+       .cpg_clk_register = rcar_r8a779a0_cpg_clk_register,
+
+       .reg_layout = CLK_REG_LAYOUT_RCAR_V3U,
+};
index 5a306d2..94db883 100644 (file)
@@ -57,8 +57,10 @@ static const u16 mstpsr[] = {
        0x9A0, 0x9A4, 0x9A8, 0x9AC,
 };
 
-#define        MSTPSR(i)       mstpsr[i]
-
+static const u16 mstpsr_for_v3u[] = {
+       0x2E00, 0x2E04, 0x2E08, 0x2E0C, 0x2E10, 0x2E14, 0x2E18, 0x2E1C,
+       0x2E20, 0x2E24, 0x2E28, 0x2E2C, 0x2E30, 0x2E34, 0x2E38,
+};
 
 /*
  * System Module Stop Control Register offsets
@@ -69,7 +71,10 @@ static const u16 smstpcr[] = {
        0x990, 0x994, 0x998, 0x99C,
 };
 
-#define        SMSTPCR(i)      smstpcr[i]
+static const u16 mstpcr_for_v3u[] = {
+       0x2D00, 0x2D04, 0x2D08, 0x2D0C, 0x2D10, 0x2D14, 0x2D18, 0x2D1C,
+       0x2D20, 0x2D24, 0x2D28, 0x2D2C, 0x2D30, 0x2D34, 0x2D38,
+};
 
 /*
  * Standby Control Register offsets (RZ/A)
@@ -81,8 +86,6 @@ static const u16 stbcr[] = {
        0x424, 0x428, 0x42C,
 };
 
-#define        STBCR(i)        stbcr[i]
-
 /*
  * Software Reset Register offsets
  */
@@ -92,8 +95,10 @@ static const u16 srcr[] = {
        0x920, 0x924, 0x928, 0x92C,
 };
 
-#define        SRCR(i)         srcr[i]
-
+static const u16 srcr_for_v3u[] = {
+       0x2C00, 0x2C04, 0x2C08, 0x2C0C, 0x2C10, 0x2C14, 0x2C18, 0x2C1C,
+       0x2C20, 0x2C24, 0x2C28, 0x2C2C, 0x2C30, 0x2C34, 0x2C38,
+};
 
 /* Realtime Module Stop Control Register offsets */
 #define RMSTPCR(i)     (smstpcr[i] - 0x20)
@@ -102,8 +107,16 @@ static const u16 srcr[] = {
 #define MMSTPCR(i)     (smstpcr[i] + 0x20)
 
 /* Software Reset Clearing Register offsets */
-#define        SRSTCLR(i)      (0x940 + (i) * 4)
 
+static const u16 srstclr[] = {
+       0x940, 0x944, 0x948, 0x94C, 0x950, 0x954, 0x958, 0x95C,
+       0x960, 0x964, 0x968, 0x96C,
+};
+
+static const u16 srstclr_for_v3u[] = {
+       0x2C80, 0x2C84, 0x2C88, 0x2C8C, 0x2C90, 0x2C94, 0x2C98, 0x2C9C,
+       0x2CA0, 0x2CA4, 0x2CA8, 0x2CAC, 0x2CB0, 0x2CB4, 0x2CB8,
+};
 
 /**
  * Clock Pulse Generator / Module Standby and Software Reset Private Data
@@ -111,13 +124,17 @@ static const u16 srcr[] = {
  * @rcdev: Optional reset controller entity
  * @dev: CPG/MSSR device
  * @base: CPG/MSSR register block base address
+ * @reg_layout: CPG/MSSR register layout
  * @rmw_lock: protects RMW register accesses
  * @np: Device node in DT for this CPG/MSSR module
  * @num_core_clks: Number of Core Clocks in clks[]
  * @num_mod_clks: Number of Module Clocks in clks[]
  * @last_dt_core_clk: ID of the last Core Clock exported to DT
- * @stbyctrl: This device has Standby Control Registers
  * @notifiers: Notifier chain to save/restore clock state for system resume
+ * @status_regs: Pointer to status registers array
+ * @control_regs: Pointer to control registers array
+ * @reset_regs: Pointer to reset registers array
+ * @reset_clear_regs:  Pointer to reset clearing registers array
  * @smstpcr_saved[].mask: Mask of SMSTPCR[] bits under our control
  * @smstpcr_saved[].val: Saved values of SMSTPCR[]
  * @clks: Array containing all Core and Module Clocks
@@ -128,19 +145,23 @@ struct cpg_mssr_priv {
 #endif
        struct device *dev;
        void __iomem *base;
+       enum clk_reg_layout reg_layout;
        spinlock_t rmw_lock;
        struct device_node *np;
 
        unsigned int num_core_clks;
        unsigned int num_mod_clks;
        unsigned int last_dt_core_clk;
-       bool stbyctrl;
 
        struct raw_notifier_head notifiers;
+       const u16 *status_regs;
+       const u16 *control_regs;
+       const u16 *reset_regs;
+       const u16 *reset_clear_regs;
        struct {
                u32 mask;
                u32 val;
-       } smstpcr_saved[ARRAY_SIZE(smstpcr)];
+       } smstpcr_saved[ARRAY_SIZE(mstpsr_for_v3u)];
 
        struct clk *clks[];
 };
@@ -177,40 +198,40 @@ static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable)
                enable ? "ON" : "OFF");
        spin_lock_irqsave(&priv->rmw_lock, flags);
 
-       if (priv->stbyctrl) {
-               value = readb(priv->base + STBCR(reg));
+       if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A) {
+               value = readb(priv->base + priv->control_regs[reg]);
                if (enable)
                        value &= ~bitmask;
                else
                        value |= bitmask;
-               writeb(value, priv->base + STBCR(reg));
+               writeb(value, priv->base + priv->control_regs[reg]);
 
                /* dummy read to ensure write has completed */
-               readb(priv->base + STBCR(reg));
-               barrier_data(priv->base + STBCR(reg));
+               readb(priv->base + priv->control_regs[reg]);
+               barrier_data(priv->base + priv->control_regs[reg]);
        } else {
-               value = readl(priv->base + SMSTPCR(reg));
+               value = readl(priv->base + priv->control_regs[reg]);
                if (enable)
                        value &= ~bitmask;
                else
                        value |= bitmask;
-               writel(value, priv->base + SMSTPCR(reg));
+               writel(value, priv->base + priv->control_regs[reg]);
        }
 
        spin_unlock_irqrestore(&priv->rmw_lock, flags);
 
-       if (!enable || priv->stbyctrl)
+       if (!enable || priv->reg_layout == CLK_REG_LAYOUT_RZ_A)
                return 0;
 
        for (i = 1000; i > 0; --i) {
-               if (!(readl(priv->base + MSTPSR(reg)) & bitmask))
+               if (!(readl(priv->base + priv->status_regs[reg]) & bitmask))
                        break;
                cpu_relax();
        }
 
        if (!i) {
                dev_err(dev, "Failed to enable SMSTP %p[%d]\n",
-                       priv->base + SMSTPCR(reg), bit);
+                       priv->base + priv->control_regs[reg], bit);
                return -ETIMEDOUT;
        }
 
@@ -233,10 +254,10 @@ static int cpg_mstp_clock_is_enabled(struct clk_hw *hw)
        struct cpg_mssr_priv *priv = clock->priv;
        u32 value;
 
-       if (priv->stbyctrl)
-               value = readb(priv->base + STBCR(clock->index / 32));
+       if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A)
+               value = readb(priv->base + priv->control_regs[clock->index / 32]);
        else
-               value = readl(priv->base + MSTPSR(clock->index / 32));
+               value = readl(priv->base + priv->status_regs[clock->index / 32]);
 
        return !(value & BIT(clock->index % 32));
 }
@@ -272,7 +293,7 @@ struct clk *cpg_mssr_clk_src_twocell_get(struct of_phandle_args *clkspec,
 
        case CPG_MOD:
                type = "module";
-               if (priv->stbyctrl) {
+               if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A) {
                        idx = MOD_CLK_PACK_10(clkidx);
                        range_check = 7 - (clkidx % 10);
                } else {
@@ -578,13 +599,13 @@ static int cpg_mssr_reset(struct reset_controller_dev *rcdev,
        dev_dbg(priv->dev, "reset %u%02u\n", reg, bit);
 
        /* Reset module */
-       writel(bitmask, priv->base + SRCR(reg));
+       writel(bitmask, priv->base + priv->reset_regs[reg]);
 
        /* Wait for at least one cycle of the RCLK clock (@ ca. 32 kHz) */
        udelay(35);
 
        /* Release module from reset state */
-       writel(bitmask, priv->base + SRSTCLR(reg));
+       writel(bitmask, priv->base + priv->reset_clear_regs[reg]);
 
        return 0;
 }
@@ -598,7 +619,7 @@ static int cpg_mssr_assert(struct reset_controller_dev *rcdev, unsigned long id)
 
        dev_dbg(priv->dev, "assert %u%02u\n", reg, bit);
 
-       writel(bitmask, priv->base + SRCR(reg));
+       writel(bitmask, priv->base + priv->reset_regs[reg]);
        return 0;
 }
 
@@ -612,7 +633,7 @@ static int cpg_mssr_deassert(struct reset_controller_dev *rcdev,
 
        dev_dbg(priv->dev, "deassert %u%02u\n", reg, bit);
 
-       writel(bitmask, priv->base + SRSTCLR(reg));
+       writel(bitmask, priv->base + priv->reset_clear_regs[reg]);
        return 0;
 }
 
@@ -624,7 +645,7 @@ static int cpg_mssr_status(struct reset_controller_dev *rcdev,
        unsigned int bit = id % 32;
        u32 bitmask = BIT(bit);
 
-       return !!(readl(priv->base + SRCR(reg)) & bitmask);
+       return !!(readl(priv->base + priv->reset_regs[reg]) & bitmask);
 }
 
 static const struct reset_control_ops cpg_mssr_reset_ops = {
@@ -803,6 +824,12 @@ static const struct of_device_id cpg_mssr_match[] = {
                .compatible = "renesas,r8a77995-cpg-mssr",
                .data = &r8a77995_cpg_mssr_info,
        },
+#endif
+#ifdef CONFIG_CLK_R8A779A0
+       {
+               .compatible = "renesas,r8a779a0-cpg-mssr",
+               .data = &r8a779a0_cpg_mssr_info,
+       },
 #endif
        { /* sentinel */ }
 };
@@ -825,9 +852,10 @@ static int cpg_mssr_suspend_noirq(struct device *dev)
        /* Save module registers with bits under our control */
        for (reg = 0; reg < ARRAY_SIZE(priv->smstpcr_saved); reg++) {
                if (priv->smstpcr_saved[reg].mask)
-                       priv->smstpcr_saved[reg].val = priv->stbyctrl ?
-                               readb(priv->base + STBCR(reg)) :
-                               readl(priv->base + SMSTPCR(reg));
+                       priv->smstpcr_saved[reg].val =
+                               priv->reg_layout == CLK_REG_LAYOUT_RZ_A ?
+                               readb(priv->base + priv->control_regs[reg]) :
+                               readl(priv->base + priv->control_regs[reg]);
        }
 
        /* Save core clocks */
@@ -855,23 +883,23 @@ static int cpg_mssr_resume_noirq(struct device *dev)
                if (!mask)
                        continue;
 
-               if (priv->stbyctrl)
-                       oldval = readb(priv->base + STBCR(reg));
+               if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A)
+                       oldval = readb(priv->base + priv->control_regs[reg]);
                else
-                       oldval = readl(priv->base + SMSTPCR(reg));
+                       oldval = readl(priv->base + priv->control_regs[reg]);
                newval = oldval & ~mask;
                newval |= priv->smstpcr_saved[reg].val & mask;
                if (newval == oldval)
                        continue;
 
-               if (priv->stbyctrl) {
-                       writeb(newval, priv->base + STBCR(reg));
+               if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A) {
+                       writeb(newval, priv->base + priv->control_regs[reg]);
                        /* dummy read to ensure write has completed */
-                       readb(priv->base + STBCR(reg));
-                       barrier_data(priv->base + STBCR(reg));
+                       readb(priv->base + priv->control_regs[reg]);
+                       barrier_data(priv->base + priv->control_regs[reg]);
                        continue;
                } else
-                       writel(newval, priv->base + SMSTPCR(reg));
+                       writel(newval, priv->base + priv->control_regs[reg]);
 
                /* Wait until enabled clocks are really enabled */
                mask &= ~priv->smstpcr_saved[reg].val;
@@ -879,7 +907,7 @@ static int cpg_mssr_resume_noirq(struct device *dev)
                        continue;
 
                for (i = 1000; i > 0; --i) {
-                       oldval = readl(priv->base + MSTPSR(reg));
+                       oldval = readl(priv->base + priv->status_regs[reg]);
                        if (!(oldval & mask))
                                break;
                        cpu_relax();
@@ -887,8 +915,8 @@ static int cpg_mssr_resume_noirq(struct device *dev)
 
                if (!i)
                        dev_warn(dev, "Failed to enable %s%u[0x%x]\n",
-                                priv->stbyctrl ? "STB" : "SMSTP", reg,
-                                oldval & mask);
+                                priv->reg_layout == CLK_REG_LAYOUT_RZ_A ?
+                                "STB" : "SMSTP", reg, oldval & mask);
        }
 
        return 0;
@@ -937,7 +965,23 @@ static int __init cpg_mssr_common_init(struct device *dev,
        priv->num_mod_clks = info->num_hw_mod_clks;
        priv->last_dt_core_clk = info->last_dt_core_clk;
        RAW_INIT_NOTIFIER_HEAD(&priv->notifiers);
-       priv->stbyctrl = info->stbyctrl;
+       priv->reg_layout = info->reg_layout;
+       if (priv->reg_layout == CLK_REG_LAYOUT_RCAR_GEN2_AND_GEN3) {
+               priv->status_regs = mstpsr;
+               priv->control_regs = smstpcr;
+               priv->reset_regs = srcr;
+               priv->reset_clear_regs = srstclr;
+       } else if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A) {
+               priv->control_regs = stbcr;
+       } else if (priv->reg_layout == CLK_REG_LAYOUT_RCAR_V3U) {
+               priv->status_regs = mstpsr_for_v3u;
+               priv->control_regs = mstpcr_for_v3u;
+               priv->reset_regs = srcr_for_v3u;
+               priv->reset_clear_regs = srstclr_for_v3u;
+       } else {
+               error = -EINVAL;
+               goto out_err;
+       }
 
        for (i = 0; i < nclks; i++)
                priv->clks[i] = ERR_PTR(-ENOENT);
@@ -1015,7 +1059,7 @@ static int __init cpg_mssr_probe(struct platform_device *pdev)
                return error;
 
        /* Reset Controller not supported for Standby Control SoCs */
-       if (info->stbyctrl)
+       if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A)
                return 0;
 
        error = cpg_mssr_reset_controller_register(priv);
index 1cc5694..6b2a0ad 100644 (file)
@@ -85,6 +85,12 @@ struct mssr_mod_clk {
 
 struct device_node;
 
+enum clk_reg_layout {
+       CLK_REG_LAYOUT_RCAR_GEN2_AND_GEN3 = 0,
+       CLK_REG_LAYOUT_RZ_A,
+       CLK_REG_LAYOUT_RCAR_V3U,
+};
+
     /**
      * SoC-specific CPG/MSSR Description
      *
@@ -105,6 +111,7 @@ struct device_node;
      * @crit_mod_clks: Array with Module Clock IDs of critical clocks that
      *                 should not be disabled without a knowledgeable driver
      * @num_crit_mod_clks: Number of entries in crit_mod_clks[]
+     * @reg_layout: CPG/MSSR register layout from enum clk_reg_layout
      *
      * @core_pm_clks: Array with IDs of Core Clocks that are suitable for Power
      *                Management, in addition to Module Clocks
@@ -112,10 +119,6 @@ struct device_node;
      *
      * @init: Optional callback to perform SoC-specific initialization
      * @cpg_clk_register: Optional callback to handle special Core Clock types
-     *
-     * @stbyctrl: This device has Standby Control Registers which are 8-bits
-     *            wide, no status registers (MSTPSR) and have different address
-     *            offsets.
      */
 
 struct cpg_mssr_info {
@@ -130,7 +133,7 @@ struct cpg_mssr_info {
        unsigned int num_core_clks;
        unsigned int last_dt_core_clk;
        unsigned int num_total_core_clks;
-       bool stbyctrl;
+       enum clk_reg_layout reg_layout;
 
        /* Module Clocks */
        const struct mssr_mod_clk *mod_clks;
@@ -174,6 +177,7 @@ extern const struct cpg_mssr_info r8a77970_cpg_mssr_info;
 extern const struct cpg_mssr_info r8a77980_cpg_mssr_info;
 extern const struct cpg_mssr_info r8a77990_cpg_mssr_info;
 extern const struct cpg_mssr_info r8a77995_cpg_mssr_info;
+extern const struct cpg_mssr_info r8a779a0_cpg_mssr_info;
 
 void __init cpg_mssr_early_init(struct device_node *np,
                                const struct cpg_mssr_info *info);
diff --git a/drivers/clk/rockchip/Kconfig b/drivers/clk/rockchip/Kconfig
new file mode 100644 (file)
index 0000000..47cd6c5
--- /dev/null
@@ -0,0 +1,78 @@
+# SPDX-License-Identifier: GPL-2.0
+# common clock support for ROCKCHIP SoC family.
+
+config COMMON_CLK_ROCKCHIP
+       bool "Rockchip clock controller common support"
+       depends on ARCH_ROCKCHIP
+       default ARCH_ROCKCHIP
+       help
+         Say y here to enable common clock controller for Rockchip platforms.
+
+if COMMON_CLK_ROCKCHIP
+config CLK_PX30
+       bool "Rockchip PX30 clock controller support"
+       default y
+       help
+         Build the driver for PX30 Clock Driver.
+
+config CLK_RV110X
+       bool "Rockchip RV110x clock controller support"
+       default y
+       help
+         Build the driver for RV110x Clock Driver.
+
+config CLK_RK3036
+       bool "Rockchip RK3036 clock controller support"
+       default y
+       help
+         Build the driver for RK3036 Clock Driver.
+
+config CLK_RK312X
+       bool "Rockchip RK312x clock controller support"
+       default y
+       help
+         Build the driver for RK312x Clock Driver.
+
+config CLK_RK3188
+       bool "Rockchip RK3188 clock controller support"
+       default y
+       help
+         Build the driver for RK3188 Clock Driver.
+
+config CLK_RK322X
+       bool "Rockchip RK322x clock controller support"
+       default y
+       help
+         Build the driver for RK322x Clock Driver.
+
+config CLK_RK3288
+       bool "Rockchip RK3288 clock controller support"
+       depends on ARM
+       default y
+       help
+         Build the driver for RK3288 Clock Driver.
+
+config CLK_RK3308
+       bool "Rockchip RK3308 clock controller support"
+       default y
+       help
+         Build the driver for RK3308 Clock Driver.
+
+config CLK_RK3328
+       bool "Rockchip RK3328 clock controller support"
+       default y
+       help
+         Build the driver for RK3328 Clock Driver.
+
+config CLK_RK3368
+       bool "Rockchip RK3368 clock controller support"
+       default y
+       help
+         Build the driver for RK3368 Clock Driver.
+
+config CLK_RK3399
+       tristate "Rockchip RK3399 clock controller support"
+       default y
+       help
+         Build the driver for RK3399 Clock Driver.
+endif
index 7c5b581..a99e4d9 100644 (file)
@@ -3,24 +3,26 @@
 # Rockchip Clock specific Makefile
 #
 
-obj-y  += clk.o
-obj-y  += clk-pll.o
-obj-y  += clk-cpu.o
-obj-y  += clk-half-divider.o
-obj-y  += clk-inverter.o
-obj-y  += clk-mmc-phase.o
-obj-y  += clk-muxgrf.o
-obj-y  += clk-ddr.o
-obj-$(CONFIG_RESET_CONTROLLER) += softrst.o
+obj-$(CONFIG_COMMON_CLK_ROCKCHIP) += clk-rockchip.o
 
-obj-y  += clk-px30.o
-obj-y  += clk-rv1108.o
-obj-y  += clk-rk3036.o
-obj-y  += clk-rk3128.o
-obj-y  += clk-rk3188.o
-obj-y  += clk-rk3228.o
-obj-y  += clk-rk3288.o
-obj-y  += clk-rk3308.o
-obj-y  += clk-rk3328.o
-obj-y  += clk-rk3368.o
-obj-y  += clk-rk3399.o
+clk-rockchip-y += clk.o
+clk-rockchip-y += clk-pll.o
+clk-rockchip-y += clk-cpu.o
+clk-rockchip-y += clk-half-divider.o
+clk-rockchip-y += clk-inverter.o
+clk-rockchip-y += clk-mmc-phase.o
+clk-rockchip-y += clk-muxgrf.o
+clk-rockchip-y += clk-ddr.o
+clk-rockchip-$(CONFIG_RESET_CONTROLLER) += softrst.o
+
+obj-$(CONFIG_CLK_PX30)          += clk-px30.o
+obj-$(CONFIG_CLK_RV110X)        += clk-rv1108.o
+obj-$(CONFIG_CLK_RK3036)        += clk-rk3036.o
+obj-$(CONFIG_CLK_RK312X)        += clk-rk3128.o
+obj-$(CONFIG_CLK_RK3188)        += clk-rk3188.o
+obj-$(CONFIG_CLK_RK322X)        += clk-rk3228.o
+obj-$(CONFIG_CLK_RK3288)        += clk-rk3288.o
+obj-$(CONFIG_CLK_RK3308)        += clk-rk3308.o
+obj-$(CONFIG_CLK_RK3328)        += clk-rk3328.o
+obj-$(CONFIG_CLK_RK3368)        += clk-rk3368.o
+obj-$(CONFIG_CLK_RK3399)        += clk-rk3399.o
index 9273bce..86718c5 100644 (file)
@@ -136,3 +136,4 @@ struct clk *rockchip_clk_register_ddrclk(const char *name, int flags,
 
        return clk;
 }
+EXPORT_SYMBOL_GPL(rockchip_clk_register_ddrclk);
index b333fc2..ccd5c27 100644 (file)
@@ -166,7 +166,7 @@ struct clk *rockchip_clk_register_halfdiv(const char *name,
                                          unsigned long flags,
                                          spinlock_t *lock)
 {
-       struct clk *clk;
+       struct clk_hw *hw = ERR_PTR(-ENOMEM);
        struct clk_mux *mux = NULL;
        struct clk_gate *gate = NULL;
        struct clk_divider *div = NULL;
@@ -212,16 +212,18 @@ struct clk *rockchip_clk_register_halfdiv(const char *name,
                div_ops = &clk_half_divider_ops;
        }
 
-       clk = clk_register_composite(NULL, name, parent_names, num_parents,
-                                    mux ? &mux->hw : NULL, mux_ops,
-                                    div ? &div->hw : NULL, div_ops,
-                                    gate ? &gate->hw : NULL, gate_ops,
-                                    flags);
+       hw = clk_hw_register_composite(NULL, name, parent_names, num_parents,
+                                      mux ? &mux->hw : NULL, mux_ops,
+                                      div ? &div->hw : NULL, div_ops,
+                                      gate ? &gate->hw : NULL, gate_ops,
+                                      flags);
+       if (IS_ERR(hw))
+               goto err_div;
 
-       return clk;
+       return hw->clk;
 err_div:
        kfree(gate);
 err_gate:
        kfree(mux);
-       return ERR_PTR(-ENOMEM);
+       return ERR_CAST(hw);
 }
index b0baf87..5bf15f2 100644 (file)
@@ -133,7 +133,6 @@ PNAME(mux_uart1_p)          = { "clk_uart1_src", "dummy", "clk_uart1_frac" };
 PNAME(mux_uart2_p)             = { "clk_uart2_src", "dummy", "clk_uart2_frac" };
 PNAME(mux_uart3_p)             = { "clk_uart3_src", "dummy", "clk_uart3_frac" };
 PNAME(mux_uart4_p)             = { "clk_uart4_src", "dummy", "clk_uart4_frac" };
-PNAME(mux_timer_src_p)         = { "xin24m", "clk_rtc32k" };
 PNAME(mux_dclk_vop_p)          = { "dclk_vop_src", "dclk_vop_frac", "xin24m" };
 PNAME(mux_nandc_p)             = { "clk_nandc_div", "clk_nandc_div50" };
 PNAME(mux_sdmmc_p)             = { "clk_sdmmc_div", "clk_sdmmc_div50" };
index ce1d244..7df2f1e 100644 (file)
@@ -5,9 +5,11 @@
  */
 
 #include <linux/clk-provider.h>
+#include <linux/module.h>
 #include <linux/io.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
+#include <linux/of_device.h>
 #include <linux/platform_device.h>
 #include <linux/regmap.h>
 #include <dt-bindings/clock/rk3399-cru.h>
@@ -1600,3 +1602,57 @@ static void __init rk3399_pmu_clk_init(struct device_node *np)
        rockchip_clk_of_add_provider(np, ctx);
 }
 CLK_OF_DECLARE(rk3399_cru_pmu, "rockchip,rk3399-pmucru", rk3399_pmu_clk_init);
+
+struct clk_rk3399_inits {
+       void (*inits)(struct device_node *np);
+};
+
+static const struct clk_rk3399_inits clk_rk3399_pmucru_init = {
+       .inits = rk3399_pmu_clk_init,
+};
+
+static const struct clk_rk3399_inits clk_rk3399_cru_init = {
+       .inits = rk3399_clk_init,
+};
+
+static const struct of_device_id clk_rk3399_match_table[] = {
+       {
+               .compatible = "rockchip,rk3399-cru",
+               .data = &clk_rk3399_cru_init,
+       },  {
+               .compatible = "rockchip,rk3399-pmucru",
+               .data = &clk_rk3399_pmucru_init,
+       },
+       { }
+};
+MODULE_DEVICE_TABLE(of, clk_rk3399_match_table);
+
+static int __init clk_rk3399_probe(struct platform_device *pdev)
+{
+       struct device_node *np = pdev->dev.of_node;
+       const struct of_device_id *match;
+       const struct clk_rk3399_inits *init_data;
+
+       match = of_match_device(clk_rk3399_match_table, &pdev->dev);
+       if (!match || !match->data)
+               return -EINVAL;
+
+       init_data = match->data;
+       if (init_data->inits)
+               init_data->inits(np);
+
+       return 0;
+}
+
+static struct platform_driver clk_rk3399_driver = {
+       .driver         = {
+               .name   = "clk-rk3399",
+               .of_match_table = clk_rk3399_match_table,
+               .suppress_bind_attrs = true,
+       },
+};
+builtin_platform_driver_probe(clk_rk3399_driver, clk_rk3399_probe);
+
+MODULE_DESCRIPTION("Rockchip RK3399 Clock Driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:clk-rk3399");
index 546e810..b443169 100644 (file)
@@ -43,7 +43,7 @@ static struct clk *rockchip_clk_register_branch(const char *name,
                u8 gate_shift, u8 gate_flags, unsigned long flags,
                spinlock_t *lock)
 {
-       struct clk *clk;
+       struct clk_hw *hw;
        struct clk_mux *mux = NULL;
        struct clk_gate *gate = NULL;
        struct clk_divider *div = NULL;
@@ -100,20 +100,18 @@ static struct clk *rockchip_clk_register_branch(const char *name,
                                                : &clk_divider_ops;
        }
 
-       clk = clk_register_composite(NULL, name, parent_names, num_parents,
-                                    mux ? &mux->hw : NULL, mux_ops,
-                                    div ? &div->hw : NULL, div_ops,
-                                    gate ? &gate->hw : NULL, gate_ops,
-                                    flags);
-
-       if (IS_ERR(clk)) {
-               ret = PTR_ERR(clk);
-               goto err_composite;
+       hw = clk_hw_register_composite(NULL, name, parent_names, num_parents,
+                                      mux ? &mux->hw : NULL, mux_ops,
+                                      div ? &div->hw : NULL, div_ops,
+                                      gate ? &gate->hw : NULL, gate_ops,
+                                      flags);
+       if (IS_ERR(hw)) {
+               kfree(div);
+               kfree(gate);
+               return ERR_CAST(hw);
        }
 
-       return clk;
-err_composite:
-       kfree(div);
+       return hw->clk;
 err_div:
        kfree(gate);
 err_gate:
@@ -214,8 +212,8 @@ static struct clk *rockchip_clk_register_frac_branch(
                unsigned long flags, struct rockchip_clk_branch *child,
                spinlock_t *lock)
 {
+       struct clk_hw *hw;
        struct rockchip_clk_frac *frac;
-       struct clk *clk;
        struct clk_gate *gate = NULL;
        struct clk_fractional_divider *div = NULL;
        const struct clk_ops *div_ops = NULL, *gate_ops = NULL;
@@ -255,14 +253,14 @@ static struct clk *rockchip_clk_register_frac_branch(
        div->approximation = rockchip_fractional_approximation;
        div_ops = &clk_fractional_divider_ops;
 
-       clk = clk_register_composite(NULL, name, parent_names, num_parents,
-                                    NULL, NULL,
-                                    &div->hw, div_ops,
-                                    gate ? &gate->hw : NULL, gate_ops,
-                                    flags | CLK_SET_RATE_UNGATE);
-       if (IS_ERR(clk)) {
+       hw = clk_hw_register_composite(NULL, name, parent_names, num_parents,
+                                      NULL, NULL,
+                                      &div->hw, div_ops,
+                                      gate ? &gate->hw : NULL, gate_ops,
+                                      flags | CLK_SET_RATE_UNGATE);
+       if (IS_ERR(hw)) {
                kfree(frac);
-               return clk;
+               return ERR_CAST(hw);
        }
 
        if (child) {
@@ -292,7 +290,7 @@ static struct clk *rockchip_clk_register_frac_branch(
                mux_clk = clk_register(NULL, &frac_mux->hw);
                if (IS_ERR(mux_clk)) {
                        kfree(frac);
-                       return clk;
+                       return mux_clk;
                }
 
                rockchip_clk_add_lookup(ctx, mux_clk, child->id);
@@ -301,7 +299,7 @@ static struct clk *rockchip_clk_register_frac_branch(
                if (frac->mux_frac_idx >= 0) {
                        pr_debug("%s: found fractional parent in mux at pos %d\n",
                                 __func__, frac->mux_frac_idx);
-                       ret = clk_notifier_register(clk, &frac->clk_nb);
+                       ret = clk_notifier_register(hw->clk, &frac->clk_nb);
                        if (ret)
                                pr_err("%s: failed to register clock notifier for %s\n",
                                                __func__, name);
@@ -311,7 +309,7 @@ static struct clk *rockchip_clk_register_frac_branch(
                }
        }
 
-       return clk;
+       return hw->clk;
 }
 
 static struct clk *rockchip_clk_register_factor_branch(const char *name,
@@ -320,7 +318,7 @@ static struct clk *rockchip_clk_register_factor_branch(const char *name,
                int gate_offset, u8 gate_shift, u8 gate_flags,
                unsigned long flags, spinlock_t *lock)
 {
-       struct clk *clk;
+       struct clk_hw *hw;
        struct clk_gate *gate = NULL;
        struct clk_fixed_factor *fix = NULL;
 
@@ -349,20 +347,22 @@ static struct clk *rockchip_clk_register_factor_branch(const char *name,
        fix->mult = mult;
        fix->div = div;
 
-       clk = clk_register_composite(NULL, name, parent_names, num_parents,
-                                    NULL, NULL,
-                                    &fix->hw, &clk_fixed_factor_ops,
-                                    &gate->hw, &clk_gate_ops, flags);
-       if (IS_ERR(clk)) {
+       hw = clk_hw_register_composite(NULL, name, parent_names, num_parents,
+                                      NULL, NULL,
+                                      &fix->hw, &clk_fixed_factor_ops,
+                                      &gate->hw, &clk_gate_ops, flags);
+       if (IS_ERR(hw)) {
                kfree(fix);
                kfree(gate);
+               return ERR_CAST(hw);
        }
 
-       return clk;
+       return hw->clk;
 }
 
-struct rockchip_clk_provider * __init rockchip_clk_init(struct device_node *np,
-                       void __iomem *base, unsigned long nr_clks)
+struct rockchip_clk_provider *rockchip_clk_init(struct device_node *np,
+                                               void __iomem *base,
+                                               unsigned long nr_clks)
 {
        struct rockchip_clk_provider *ctx;
        struct clk **clk_table;
@@ -394,14 +394,16 @@ err_free:
        kfree(ctx);
        return ERR_PTR(-ENOMEM);
 }
+EXPORT_SYMBOL_GPL(rockchip_clk_init);
 
-void __init rockchip_clk_of_add_provider(struct device_node *np,
-                               struct rockchip_clk_provider *ctx)
+void rockchip_clk_of_add_provider(struct device_node *np,
+                                 struct rockchip_clk_provider *ctx)
 {
        if (of_clk_add_provider(np, of_clk_src_onecell_get,
                                &ctx->clk_data))
                pr_err("%s: could not register clk provider\n", __func__);
 }
+EXPORT_SYMBOL_GPL(rockchip_clk_of_add_provider);
 
 void rockchip_clk_add_lookup(struct rockchip_clk_provider *ctx,
                             struct clk *clk, unsigned int id)
@@ -409,8 +411,9 @@ void rockchip_clk_add_lookup(struct rockchip_clk_provider *ctx,
        if (ctx->clk_data.clks && id)
                ctx->clk_data.clks[id] = clk;
 }
+EXPORT_SYMBOL_GPL(rockchip_clk_add_lookup);
 
-void __init rockchip_clk_register_plls(struct rockchip_clk_provider *ctx,
+void rockchip_clk_register_plls(struct rockchip_clk_provider *ctx,
                                struct rockchip_pll_clock *list,
                                unsigned int nr_pll, int grf_lock_offset)
 {
@@ -433,11 +436,11 @@ void __init rockchip_clk_register_plls(struct rockchip_clk_provider *ctx,
                rockchip_clk_add_lookup(ctx, clk, list->id);
        }
 }
+EXPORT_SYMBOL_GPL(rockchip_clk_register_plls);
 
-void __init rockchip_clk_register_branches(
-                                     struct rockchip_clk_provider *ctx,
-                                     struct rockchip_clk_branch *list,
-                                     unsigned int nr_clk)
+void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx,
+                                   struct rockchip_clk_branch *list,
+                                   unsigned int nr_clk)
 {
        struct clk *clk = NULL;
        unsigned int idx;
@@ -566,14 +569,15 @@ void __init rockchip_clk_register_branches(
                rockchip_clk_add_lookup(ctx, clk, list->id);
        }
 }
-
-void __init rockchip_clk_register_armclk(struct rockchip_clk_provider *ctx,
-                       unsigned int lookup_id,
-                       const char *name, const char *const *parent_names,
-                       u8 num_parents,
-                       const struct rockchip_cpuclk_reg_data *reg_data,
-                       const struct rockchip_cpuclk_rate_table *rates,
-                       int nrates)
+EXPORT_SYMBOL_GPL(rockchip_clk_register_branches);
+
+void rockchip_clk_register_armclk(struct rockchip_clk_provider *ctx,
+                                 unsigned int lookup_id,
+                                 const char *name, const char *const *parent_names,
+                                 u8 num_parents,
+                                 const struct rockchip_cpuclk_reg_data *reg_data,
+                                 const struct rockchip_cpuclk_rate_table *rates,
+                                 int nrates)
 {
        struct clk *clk;
 
@@ -588,9 +592,10 @@ void __init rockchip_clk_register_armclk(struct rockchip_clk_provider *ctx,
 
        rockchip_clk_add_lookup(ctx, clk, lookup_id);
 }
+EXPORT_SYMBOL_GPL(rockchip_clk_register_armclk);
 
-void __init rockchip_clk_protect_critical(const char *const clocks[],
-                                         int nclocks)
+void rockchip_clk_protect_critical(const char *const clocks[],
+                                  int nclocks)
 {
        int i;
 
@@ -602,6 +607,7 @@ void __init rockchip_clk_protect_critical(const char *const clocks[],
                        clk_prepare_enable(clk);
        }
 }
+EXPORT_SYMBOL_GPL(rockchip_clk_protect_critical);
 
 static void __iomem *rst_base;
 static unsigned int reg_restart;
@@ -621,10 +627,10 @@ static struct notifier_block rockchip_restart_handler = {
        .priority = 128,
 };
 
-void __init
+void
 rockchip_register_restart_notifier(struct rockchip_clk_provider *ctx,
-                                              unsigned int reg,
-                                              void (*cb)(void))
+                                  unsigned int reg,
+                                  void (*cb)(void))
 {
        int ret;
 
@@ -636,3 +642,4 @@ rockchip_register_restart_notifier(struct rockchip_clk_provider *ctx,
                pr_err("%s: cannot register restart handler, %d\n",
                       __func__, ret);
 }
+EXPORT_SYMBOL_GPL(rockchip_register_restart_notifier);
index 5f1ff5e..5d07266 100644 (file)
@@ -77,9 +77,9 @@ static const struct reset_control_ops rockchip_softrst_ops = {
        .deassert       = rockchip_softrst_deassert,
 };
 
-void __init rockchip_register_softrst(struct device_node *np,
-                                     unsigned int num_regs,
-                                     void __iomem *base, u8 flags)
+void rockchip_register_softrst(struct device_node *np,
+                              unsigned int num_regs,
+                              void __iomem *base, u8 flags)
 {
        struct rockchip_softrst *softrst;
        int ret;
@@ -107,3 +107,4 @@ void __init rockchip_register_softrst(struct device_node *np,
                kfree(softrst);
        }
 };
+EXPORT_SYMBOL_GPL(rockchip_register_softrst);
index efc4fa6..00ef4d1 100644 (file)
@@ -401,26 +401,34 @@ static int exynos5433_cpuclk_notifier_cb(struct notifier_block *nb,
 
 /* helper function to register a CPU clock */
 int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx,
-               unsigned int lookup_id, const char *name, const char *parent,
-               const char *alt_parent, unsigned long offset,
-               const struct exynos_cpuclk_cfg_data *cfg,
+               unsigned int lookup_id, const char *name,
+               const struct clk_hw *parent, const struct clk_hw *alt_parent,
+               unsigned long offset, const struct exynos_cpuclk_cfg_data *cfg,
                unsigned long num_cfgs, unsigned long flags)
 {
        struct exynos_cpuclk *cpuclk;
        struct clk_init_data init;
-       struct clk *parent_clk;
+       const char *parent_name;
        int ret = 0;
 
+       if (IS_ERR(parent) || IS_ERR(alt_parent)) {
+               pr_err("%s: invalid parent clock(s)\n", __func__);
+               return -EINVAL;
+       }
+
        cpuclk = kzalloc(sizeof(*cpuclk), GFP_KERNEL);
        if (!cpuclk)
                return -ENOMEM;
 
+       parent_name = clk_hw_get_name(parent);
+
        init.name = name;
        init.flags = CLK_SET_RATE_PARENT;
-       init.parent_names = &parent;
+       init.parent_names = &parent_name;
        init.num_parents = 1;
        init.ops = &exynos_cpuclk_clk_ops;
 
+       cpuclk->alt_parent = alt_parent;
        cpuclk->hw.init = &init;
        cpuclk->ctrl_base = ctx->reg_base + offset;
        cpuclk->lock = &ctx->lock;
@@ -430,23 +438,8 @@ int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx,
        else
                cpuclk->clk_nb.notifier_call = exynos_cpuclk_notifier_cb;
 
-       cpuclk->alt_parent = __clk_get_hw(__clk_lookup(alt_parent));
-       if (!cpuclk->alt_parent) {
-               pr_err("%s: could not lookup alternate parent %s\n",
-                               __func__, alt_parent);
-               ret = -EINVAL;
-               goto free_cpuclk;
-       }
-
-       parent_clk = __clk_lookup(parent);
-       if (!parent_clk) {
-               pr_err("%s: could not lookup parent clock %s\n",
-                               __func__, parent);
-               ret = -EINVAL;
-               goto free_cpuclk;
-       }
 
-       ret = clk_notifier_register(parent_clk, &cpuclk->clk_nb);
+       ret = clk_notifier_register(parent->clk, &cpuclk->clk_nb);
        if (ret) {
                pr_err("%s: failed to register clock notifier for %s\n",
                                __func__, name);
@@ -471,7 +464,7 @@ int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx,
 free_cpuclk_data:
        kfree(cpuclk->cfg);
 unregister_clk_nb:
-       clk_notifier_unregister(parent_clk, &cpuclk->clk_nb);
+       clk_notifier_unregister(parent->clk, &cpuclk->clk_nb);
 free_cpuclk:
        kfree(cpuclk);
        return ret;
index ad38cc2..af74686 100644 (file)
@@ -46,7 +46,7 @@ struct exynos_cpuclk_cfg_data {
  */
 struct exynos_cpuclk {
        struct clk_hw                           hw;
-       struct clk_hw                           *alt_parent;
+       const struct clk_hw                     *alt_parent;
        void __iomem                            *ctrl_base;
        spinlock_t                              *lock;
        const struct exynos_cpuclk_cfg_data     *cfg;
@@ -62,9 +62,9 @@ struct exynos_cpuclk {
 #define CLK_CPU_HAS_E5433_REGS_LAYOUT  (1 << 2)
 };
 
-extern int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx,
+int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx,
                        unsigned int lookup_id, const char *name,
-                       const char *parent, const char *alt_parent,
+                       const struct clk_hw *parent, const struct clk_hw *alt_parent,
                        unsigned long offset,
                        const struct exynos_cpuclk_cfg_data *cfg,
                        unsigned long num_cfgs, unsigned long flags);
index 17897c7..17df7f9 100644 (file)
@@ -808,14 +808,16 @@ static const struct exynos_cpuclk_cfg_data e3250_armclk_d[] __initconst = {
 static void __init exynos3250_cmu_init(struct device_node *np)
 {
        struct samsung_clk_provider *ctx;
+       struct clk_hw **hws;
 
        ctx = samsung_cmu_register_one(np, &cmu_info);
        if (!ctx)
                return;
 
+       hws = ctx->clk_data.hws;
        exynos_register_cpu_clock(ctx, CLK_ARM_CLK, "armclk",
-                       mout_core_p[0], mout_core_p[1], 0x14200,
-                       e3250_armclk_d, ARRAY_SIZE(e3250_armclk_d),
+                       hws[CLK_MOUT_APLL], hws[CLK_MOUT_MPLL_USER_C],
+                       0x14200, e3250_armclk_d, ARRAY_SIZE(e3250_armclk_d),
                        CLK_CPU_HAS_DIV1);
 
        exynos3_core_down_clock(ctx->reg_base);
index 51564fc..436fcd2 100644 (file)
@@ -1233,6 +1233,8 @@ static void __init exynos4_clk_init(struct device_node *np,
                                    enum exynos4_soc soc)
 {
        struct samsung_clk_provider *ctx;
+       struct clk_hw **hws;
+
        exynos4_soc = soc;
 
        reg_base = of_iomap(np, 0);
@@ -1240,6 +1242,7 @@ static void __init exynos4_clk_init(struct device_node *np,
                panic("%s: failed to map registers\n", __func__);
 
        ctx = samsung_clk_init(np, reg_base, CLK_NR_CLKS);
+       hws = ctx->clk_data.hws;
 
        samsung_clk_of_register_fixed_ext(ctx, exynos4_fixed_rate_ext_clks,
                        ARRAY_SIZE(exynos4_fixed_rate_ext_clks),
@@ -1302,7 +1305,7 @@ static void __init exynos4_clk_init(struct device_node *np,
                        exynos4210_fixed_factor_clks,
                        ARRAY_SIZE(exynos4210_fixed_factor_clks));
                exynos_register_cpu_clock(ctx, CLK_ARM_CLK, "armclk",
-                       mout_core_p4210[0], mout_core_p4210[1], 0x14200,
+                       hws[CLK_MOUT_APLL], hws[CLK_SCLK_MPLL], 0x14200,
                        e4210_armclk_d, ARRAY_SIZE(e4210_armclk_d),
                        CLK_CPU_NEEDS_DEBUG_ALT_DIV | CLK_CPU_HAS_DIV1);
        } else {
@@ -1317,7 +1320,7 @@ static void __init exynos4_clk_init(struct device_node *np,
                        ARRAY_SIZE(exynos4x12_fixed_factor_clks));
 
                exynos_register_cpu_clock(ctx, CLK_ARM_CLK, "armclk",
-                       mout_core_p4x12[0], mout_core_p4x12[1], 0x14200,
+                       hws[CLK_MOUT_APLL], hws[CLK_MOUT_MPLL_USER_C], 0x14200,
                        e4412_armclk_d, ARRAY_SIZE(e4412_armclk_d),
                        CLK_CPU_NEEDS_DEBUG_ALT_DIV | CLK_CPU_HAS_DIV1);
        }
index 931c70a..06588fa 100644 (file)
@@ -253,14 +253,14 @@ static const struct samsung_mux_clock exynos5250_mux_clks[] __initconst = {
        /*
         * CMU_CPU
         */
-       MUX_F(0, "mout_apll", mout_apll_p, SRC_CPU, 0, 1,
+       MUX_F(CLK_MOUT_APLL, "mout_apll", mout_apll_p, SRC_CPU, 0, 1,
                                        CLK_SET_RATE_PARENT, 0),
        MUX(0, "mout_cpu", mout_cpu_p, SRC_CPU, 16, 1),
 
        /*
         * CMU_CORE
         */
-       MUX(0, "mout_mpll", mout_mpll_p, SRC_CORE1, 8, 1),
+       MUX(CLK_MOUT_MPLL, "mout_mpll", mout_mpll_p, SRC_CORE1, 8, 1),
 
        /*
         * CMU_TOP
@@ -782,6 +782,7 @@ static void __init exynos5250_clk_init(struct device_node *np)
 {
        struct samsung_clk_provider *ctx;
        unsigned int tmp;
+       struct clk_hw **hws;
 
        if (np) {
                reg_base = of_iomap(np, 0);
@@ -792,6 +793,7 @@ static void __init exynos5250_clk_init(struct device_node *np)
        }
 
        ctx = samsung_clk_init(np, reg_base, CLK_NR_CLKS);
+       hws = ctx->clk_data.hws;
 
        samsung_clk_of_register_fixed_ext(ctx, exynos5250_fixed_rate_ext_clks,
                        ARRAY_SIZE(exynos5250_fixed_rate_ext_clks),
@@ -821,7 +823,7 @@ static void __init exynos5250_clk_init(struct device_node *np)
        samsung_clk_register_gate(ctx, exynos5250_gate_clks,
                        ARRAY_SIZE(exynos5250_gate_clks));
        exynos_register_cpu_clock(ctx, CLK_ARM_CLK, "armclk",
-                       mout_cpu_p[0], mout_cpu_p[1], 0x200,
+                       hws[CLK_MOUT_APLL], hws[CLK_MOUT_MPLL], 0x200,
                        exynos5250_armclk_d, ARRAY_SIZE(exynos5250_armclk_d),
                        CLK_CPU_HAS_DIV1);
 
index fea3339..3ccd4ea 100644 (file)
@@ -596,13 +596,14 @@ static const struct samsung_gate_clock exynos5420_gate_clks[] __initconst = {
 static const struct samsung_mux_clock exynos5x_mux_clks[] __initconst = {
        MUX(0, "mout_user_pclk66_gpio", mout_user_pclk66_gpio_p,
                        SRC_TOP7, 4, 1),
-       MUX(0, "mout_mspll_kfc", mout_mspll_cpu_p, SRC_TOP7, 8, 2),
-       MUX(0, "mout_mspll_cpu", mout_mspll_cpu_p, SRC_TOP7, 12, 2),
-
-       MUX_F(0, "mout_apll", mout_apll_p, SRC_CPU, 0, 1,
+       MUX(CLK_MOUT_MSPLL_KFC, "mout_mspll_kfc", mout_mspll_cpu_p,
+           SRC_TOP7, 8, 2),
+       MUX(CLK_MOUT_MSPLL_CPU, "mout_mspll_cpu", mout_mspll_cpu_p,
+           SRC_TOP7, 12, 2),
+       MUX_F(CLK_MOUT_APLL, "mout_apll", mout_apll_p, SRC_CPU, 0, 1,
              CLK_SET_RATE_PARENT | CLK_RECALC_NEW_RATES, 0),
        MUX(0, "mout_cpu", mout_cpu_p, SRC_CPU, 16, 1),
-       MUX_F(0, "mout_kpll", mout_kpll_p, SRC_KFC, 0, 1,
+       MUX_F(CLK_MOUT_KPLL, "mout_kpll", mout_kpll_p, SRC_KFC, 0, 1,
              CLK_SET_RATE_PARENT | CLK_RECALC_NEW_RATES, 0),
        MUX(0, "mout_kfc", mout_kfc_p, SRC_KFC, 16, 1),
 
@@ -712,8 +713,8 @@ static const struct samsung_mux_clock exynos5x_mux_clks[] __initconst = {
                        SRC_TOP12, 8, 1),
        MUX(0, "mout_sw_aclk266_g2d", mout_sw_aclk266_g2d_p,
                        SRC_TOP12, 12, 1),
-       MUX_F(0, "mout_sw_aclk_g3d", mout_sw_aclk_g3d_p, SRC_TOP12, 16, 1,
-             CLK_SET_RATE_PARENT, 0),
+       MUX_F(CLK_MOUT_SW_ACLK_G3D, "mout_sw_aclk_g3d", mout_sw_aclk_g3d_p,
+                       SRC_TOP12, 16, 1, CLK_SET_RATE_PARENT, 0),
        MUX(0, "mout_sw_aclk300_jpeg", mout_sw_aclk300_jpeg_p,
                        SRC_TOP12, 20, 1),
        MUX(CLK_MOUT_SW_ACLK300, "mout_sw_aclk300_disp1",
@@ -1560,6 +1561,7 @@ static void __init exynos5x_clk_init(struct device_node *np,
                enum exynos5x_soc soc)
 {
        struct samsung_clk_provider *ctx;
+       struct clk_hw **hws;
 
        if (np) {
                reg_base = of_iomap(np, 0);
@@ -1572,6 +1574,7 @@ static void __init exynos5x_clk_init(struct device_node *np,
        exynos5x_soc = soc;
 
        ctx = samsung_clk_init(np, reg_base, CLK_NR_CLKS);
+       hws = ctx->clk_data.hws;
 
        samsung_clk_of_register_fixed_ext(ctx, exynos5x_fixed_rate_ext_clks,
                        ARRAY_SIZE(exynos5x_fixed_rate_ext_clks),
@@ -1623,15 +1626,15 @@ static void __init exynos5x_clk_init(struct device_node *np,
 
        if (soc == EXYNOS5420) {
                exynos_register_cpu_clock(ctx, CLK_ARM_CLK, "armclk",
-                       mout_cpu_p[0], mout_cpu_p[1], 0x200,
+                       hws[CLK_MOUT_APLL], hws[CLK_MOUT_MSPLL_CPU], 0x200,
                        exynos5420_eglclk_d, ARRAY_SIZE(exynos5420_eglclk_d), 0);
        } else {
                exynos_register_cpu_clock(ctx, CLK_ARM_CLK, "armclk",
-                       mout_cpu_p[0], mout_cpu_p[1], 0x200,
+                       hws[CLK_MOUT_APLL], hws[CLK_MOUT_MSPLL_CPU], 0x200,
                        exynos5800_eglclk_d, ARRAY_SIZE(exynos5800_eglclk_d), 0);
        }
        exynos_register_cpu_clock(ctx, CLK_KFC_CLK, "kfcclk",
-               mout_kfc_p[0], mout_kfc_p[1], 0x28200,
+               hws[CLK_MOUT_KPLL], hws[CLK_MOUT_MSPLL_KFC],  0x28200,
                exynos5420_kfcclk_d, ARRAY_SIZE(exynos5420_kfcclk_d), 0);
 
        samsung_clk_extended_sleep_init(reg_base,
@@ -1654,7 +1657,12 @@ static void __init exynos5x_clk_init(struct device_node *np,
         * that the internal busses get their clock regardless of the
         * main G3D clock enablement status.
         */
-       clk_prepare_enable(__clk_lookup("mout_sw_aclk_g3d"));
+       clk_prepare_enable(hws[CLK_MOUT_SW_ACLK_G3D]->clk);
+       /*
+        * Keep top BPLL mux enabled permanently to ensure that DRAM operates
+        * properly.
+        */
+       clk_prepare_enable(hws[CLK_MOUT_BPLL]->clk);
 
        samsung_clk_of_add_provider(np, ctx);
 }
index 6f29ecd..f203074 100644 (file)
@@ -3679,6 +3679,7 @@ static void __init exynos5433_cmu_apollo_init(struct device_node *np)
 {
        void __iomem *reg_base;
        struct samsung_clk_provider *ctx;
+       struct clk_hw **hws;
 
        reg_base = of_iomap(np, 0);
        if (!reg_base) {
@@ -3701,8 +3702,10 @@ static void __init exynos5433_cmu_apollo_init(struct device_node *np)
        samsung_clk_register_gate(ctx, apollo_gate_clks,
                                  ARRAY_SIZE(apollo_gate_clks));
 
+       hws = ctx->clk_data.hws;
+
        exynos_register_cpu_clock(ctx, CLK_SCLK_APOLLO, "apolloclk",
-               mout_apollo_p[0], mout_apollo_p[1], 0x200,
+               hws[CLK_MOUT_APOLLO_PLL], hws[CLK_MOUT_BUS_PLL_APOLLO_USER], 0x200,
                exynos5433_apolloclk_d, ARRAY_SIZE(exynos5433_apolloclk_d),
                CLK_CPU_HAS_E5433_REGS_LAYOUT);
 
@@ -3933,6 +3936,7 @@ static void __init exynos5433_cmu_atlas_init(struct device_node *np)
 {
        void __iomem *reg_base;
        struct samsung_clk_provider *ctx;
+       struct clk_hw **hws;
 
        reg_base = of_iomap(np, 0);
        if (!reg_base) {
@@ -3955,8 +3959,10 @@ static void __init exynos5433_cmu_atlas_init(struct device_node *np)
        samsung_clk_register_gate(ctx, atlas_gate_clks,
                                  ARRAY_SIZE(atlas_gate_clks));
 
+       hws = ctx->clk_data.hws;
+
        exynos_register_cpu_clock(ctx, CLK_SCLK_ATLAS, "atlasclk",
-               mout_atlas_p[0], mout_atlas_p[1], 0x200,
+               hws[CLK_MOUT_ATLAS_PLL], hws[CLK_MOUT_BUS_PLL_ATLAS_USER], 0x200,
                exynos5433_atlasclk_d, ARRAY_SIZE(exynos5433_atlasclk_d),
                CLK_CPU_HAS_E5433_REGS_LAYOUT);
 
index 45dcbc9..d17b345 100644 (file)
@@ -134,7 +134,7 @@ static void __init prima2_clk_init(struct device_node *np)
 
        for (i = pll1; i < maxclk; i++) {
                prima2_clks[i] = clk_register(NULL, prima2_clk_hw_array[i]);
-               BUG_ON(!prima2_clks[i]);
+               BUG_ON(IS_ERR(prima2_clks[i]));
        }
        clk_register_clkdev(prima2_clks[cpu], NULL, "cpu");
        clk_register_clkdev(prima2_clks[io],  NULL, "io");
index 8fb12cb..bb3e809 100644 (file)
@@ -21,19 +21,6 @@ static const struct clk_parent_data pll_mux[] = {
          .name = "f2s-free-clk", },
 };
 
-static const struct clk_parent_data cntr_mux[] = {
-       { .fw_name = "main_pll",
-         .name = "main_pll", },
-       { .fw_name = "periph_pll",
-         .name = "periph_pll", },
-       { .fw_name = "osc1",
-         .name = "osc1", },
-       { .fw_name = "cb-intosc-hs-div2-clk",
-         .name = "cb-intosc-hs-div2-clk", },
-       { .fw_name = "f2s-free-clk",
-         .name = "f2s-free-clk", },
-};
-
 static const struct clk_parent_data boot_mux[] = {
        { .fw_name = "osc1",
          .name = "osc1", },
index cdf3330..ce5f584 100644 (file)
@@ -17,6 +17,16 @@ config SUN50I_A64_CCU
        default ARM64 && ARCH_SUNXI
        depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST
 
+config SUN50I_A100_CCU
+       bool "Support for the Allwinner A100 CCU"
+       default ARM64 && ARCH_SUNXI
+       depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST
+
+config SUN50I_A100_R_CCU
+       bool "Support for the Allwinner A100 PRCM CCU"
+       default ARM64 && ARCH_SUNXI
+       depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST
+
 config SUN50I_H6_CCU
        bool "Support for the Allwinner H6 CCU"
        default ARM64 && ARCH_SUNXI
index 4c7bee8..3eb5cff 100644 (file)
@@ -23,6 +23,8 @@ obj-y                         += ccu_mp.o
 # SoC support
 obj-$(CONFIG_SUNIV_F1C100S_CCU)        += ccu-suniv-f1c100s.o
 obj-$(CONFIG_SUN50I_A64_CCU)   += ccu-sun50i-a64.o
+obj-$(CONFIG_SUN50I_A100_CCU)  += ccu-sun50i-a100.o
+obj-$(CONFIG_SUN50I_A100_R_CCU)        += ccu-sun50i-a100-r.o
 obj-$(CONFIG_SUN50I_H6_CCU)    += ccu-sun50i-h6.o
 obj-$(CONFIG_SUN50I_H6_R_CCU)  += ccu-sun50i-h6-r.o
 obj-$(CONFIG_SUN4I_A10_CCU)    += ccu-sun4i-a10.o
diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a100-r.c b/drivers/clk/sunxi-ng/ccu-sun50i-a100-r.c
new file mode 100644 (file)
index 0000000..a56142b
--- /dev/null
@@ -0,0 +1,214 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2020 Yangtao Li <frank@allwinnertech.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+
+#include "ccu_common.h"
+#include "ccu_reset.h"
+
+#include "ccu_div.h"
+#include "ccu_gate.h"
+#include "ccu_mp.h"
+#include "ccu_nm.h"
+
+#include "ccu-sun50i-a100-r.h"
+
+static const char * const cpus_r_apb2_parents[] = { "dcxo24M", "osc32k",
+                                                    "iosc", "pll-periph0" };
+static const struct ccu_mux_var_prediv cpus_r_apb2_predivs[] = {
+       { .index = 3, .shift = 0, .width = 5 },
+};
+
+static struct ccu_div r_cpus_clk = {
+       .div            = _SUNXI_CCU_DIV_FLAGS(8, 2, CLK_DIVIDER_POWER_OF_TWO),
+
+       .mux            = {
+               .shift  = 24,
+               .width  = 2,
+
+               .var_predivs    = cpus_r_apb2_predivs,
+               .n_var_predivs  = ARRAY_SIZE(cpus_r_apb2_predivs),
+       },
+
+       .common         = {
+               .reg            = 0x000,
+               .features       = CCU_FEATURE_VARIABLE_PREDIV,
+               .hw.init        = CLK_HW_INIT_PARENTS("cpus",
+                                                     cpus_r_apb2_parents,
+                                                     &ccu_div_ops,
+                                                     0),
+       },
+};
+
+static CLK_FIXED_FACTOR_HW(r_ahb_clk, "r-ahb", &r_cpus_clk.common.hw, 1, 1, 0);
+
+static struct ccu_div r_apb1_clk = {
+       .div            = _SUNXI_CCU_DIV(0, 2),
+
+       .common         = {
+               .reg            = 0x00c,
+               .hw.init        = CLK_HW_INIT("r-apb1",
+                                             "r-ahb",
+                                             &ccu_div_ops,
+                                             0),
+       },
+};
+
+static struct ccu_div r_apb2_clk = {
+       .div            = _SUNXI_CCU_DIV_FLAGS(8, 2, CLK_DIVIDER_POWER_OF_TWO),
+
+       .mux            = {
+               .shift  = 24,
+               .width  = 2,
+
+               .var_predivs    = cpus_r_apb2_predivs,
+               .n_var_predivs  = ARRAY_SIZE(cpus_r_apb2_predivs),
+       },
+
+       .common         = {
+               .reg            = 0x010,
+               .features       = CCU_FEATURE_VARIABLE_PREDIV,
+               .hw.init        = CLK_HW_INIT_PARENTS("r-apb2",
+                                                     cpus_r_apb2_parents,
+                                                     &ccu_div_ops,
+                                                     0),
+       },
+};
+
+static const struct clk_parent_data clk_parent_r_apb1[] = {
+       { .hw = &r_apb1_clk.common.hw },
+};
+
+static const struct clk_parent_data clk_parent_r_apb2[] = {
+       { .hw = &r_apb2_clk.common.hw },
+};
+
+static SUNXI_CCU_GATE_DATA(r_apb1_timer_clk, "r-apb1-timer", clk_parent_r_apb1,
+                          0x11c, BIT(0), 0);
+
+static SUNXI_CCU_GATE_DATA(r_apb1_twd_clk, "r-apb1-twd", clk_parent_r_apb1,
+                          0x12c, BIT(0), 0);
+
+static const char * const r_apb1_pwm_clk_parents[] = { "dcxo24M", "osc32k",
+                                                      "iosc" };
+static SUNXI_CCU_MUX(r_apb1_pwm_clk, "r-apb1-pwm", r_apb1_pwm_clk_parents,
+                    0x130, 24, 2, 0);
+
+static SUNXI_CCU_GATE_DATA(r_apb1_bus_pwm_clk, "r-apb1-bus-pwm",
+                          clk_parent_r_apb1, 0x13c, BIT(0), 0);
+
+static SUNXI_CCU_GATE_DATA(r_apb1_ppu_clk, "r-apb1-ppu", clk_parent_r_apb1,
+                          0x17c, BIT(0), 0);
+
+static SUNXI_CCU_GATE_DATA(r_apb2_uart_clk, "r-apb2-uart", clk_parent_r_apb2,
+                          0x18c, BIT(0), 0);
+
+static SUNXI_CCU_GATE_DATA(r_apb2_i2c0_clk, "r-apb2-i2c0", clk_parent_r_apb2,
+                          0x19c, BIT(0), 0);
+
+static SUNXI_CCU_GATE_DATA(r_apb2_i2c1_clk, "r-apb2-i2c1", clk_parent_r_apb2,
+                          0x19c, BIT(1), 0);
+
+static const char * const r_apb1_ir_rx_parents[] = { "osc32k", "dcxo24M" };
+static SUNXI_CCU_MP_WITH_MUX_GATE(r_apb1_ir_rx_clk, "r-apb1-ir-rx",
+                                 r_apb1_ir_rx_parents, 0x1c0,
+                                 0, 5,         /* M */
+                                 8, 2,         /* P */
+                                 24, 1,        /* mux */
+                                 BIT(31),      /* gate */
+                                 0);
+
+static SUNXI_CCU_GATE_DATA(r_apb1_bus_ir_rx_clk, "r-apb1-bus-ir-rx",
+                          clk_parent_r_apb1, 0x1cc, BIT(0), 0);
+
+static SUNXI_CCU_GATE(r_ahb_bus_rtc_clk, "r-ahb-rtc", "r-ahb",
+                     0x20c, BIT(0), 0);
+
+static struct ccu_common *sun50i_a100_r_ccu_clks[] = {
+       &r_cpus_clk.common,
+       &r_apb1_clk.common,
+       &r_apb2_clk.common,
+       &r_apb1_timer_clk.common,
+       &r_apb1_twd_clk.common,
+       &r_apb1_pwm_clk.common,
+       &r_apb1_bus_pwm_clk.common,
+       &r_apb1_ppu_clk.common,
+       &r_apb2_uart_clk.common,
+       &r_apb2_i2c0_clk.common,
+       &r_apb2_i2c1_clk.common,
+       &r_apb1_ir_rx_clk.common,
+       &r_apb1_bus_ir_rx_clk.common,
+       &r_ahb_bus_rtc_clk.common,
+};
+
+static struct clk_hw_onecell_data sun50i_a100_r_hw_clks = {
+       .hws    = {
+               [CLK_R_CPUS]            = &r_cpus_clk.common.hw,
+               [CLK_R_AHB]             = &r_ahb_clk.hw,
+               [CLK_R_APB1]            = &r_apb1_clk.common.hw,
+               [CLK_R_APB2]            = &r_apb2_clk.common.hw,
+               [CLK_R_APB1_TIMER]      = &r_apb1_timer_clk.common.hw,
+               [CLK_R_APB1_TWD]        = &r_apb1_twd_clk.common.hw,
+               [CLK_R_APB1_PWM]        = &r_apb1_pwm_clk.common.hw,
+               [CLK_R_APB1_BUS_PWM]    = &r_apb1_bus_pwm_clk.common.hw,
+               [CLK_R_APB1_PPU]        = &r_apb1_ppu_clk.common.hw,
+               [CLK_R_APB2_UART]       = &r_apb2_uart_clk.common.hw,
+               [CLK_R_APB2_I2C0]       = &r_apb2_i2c0_clk.common.hw,
+               [CLK_R_APB2_I2C1]       = &r_apb2_i2c1_clk.common.hw,
+               [CLK_R_APB1_IR]         = &r_apb1_ir_rx_clk.common.hw,
+               [CLK_R_APB1_BUS_IR]     = &r_apb1_bus_ir_rx_clk.common.hw,
+               [CLK_R_AHB_BUS_RTC]     = &r_ahb_bus_rtc_clk.common.hw,
+       },
+       .num    = CLK_NUMBER,
+};
+
+static struct ccu_reset_map sun50i_a100_r_ccu_resets[] = {
+       [RST_R_APB1_TIMER]      =  { 0x11c, BIT(16) },
+       [RST_R_APB1_BUS_PWM]    =  { 0x13c, BIT(16) },
+       [RST_R_APB1_PPU]        =  { 0x17c, BIT(16) },
+       [RST_R_APB2_UART]       =  { 0x18c, BIT(16) },
+       [RST_R_APB2_I2C0]       =  { 0x19c, BIT(16) },
+       [RST_R_APB2_I2C1]       =  { 0x19c, BIT(17) },
+       [RST_R_APB1_BUS_IR]     =  { 0x1cc, BIT(16) },
+       [RST_R_AHB_BUS_RTC]     =  { 0x20c, BIT(16) },
+};
+
+static const struct sunxi_ccu_desc sun50i_a100_r_ccu_desc = {
+       .ccu_clks       = sun50i_a100_r_ccu_clks,
+       .num_ccu_clks   = ARRAY_SIZE(sun50i_a100_r_ccu_clks),
+
+       .hw_clks        = &sun50i_a100_r_hw_clks,
+
+       .resets         = sun50i_a100_r_ccu_resets,
+       .num_resets     = ARRAY_SIZE(sun50i_a100_r_ccu_resets),
+};
+
+static int sun50i_a100_r_ccu_probe(struct platform_device *pdev)
+{
+       void __iomem *reg;
+
+       reg = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(reg))
+               return PTR_ERR(reg);
+
+       return sunxi_ccu_probe(pdev->dev.of_node, reg, &sun50i_a100_r_ccu_desc);
+}
+
+static const struct of_device_id sun50i_a100_r_ccu_ids[] = {
+       { .compatible = "allwinner,sun50i-a100-r-ccu" },
+       { }
+};
+
+static struct platform_driver sun50i_a100_r_ccu_driver = {
+       .probe  = sun50i_a100_r_ccu_probe,
+       .driver = {
+               .name   = "sun50i-a100-r-ccu",
+               .of_match_table = sun50i_a100_r_ccu_ids,
+       },
+};
+module_platform_driver(sun50i_a100_r_ccu_driver);
diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a100-r.h b/drivers/clk/sunxi-ng/ccu-sun50i-a100-r.h
new file mode 100644 (file)
index 0000000..3a8f187
--- /dev/null
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2020 Yangtao Li <frank@allwinnertech.com>
+ */
+
+#ifndef _CCU_SUN50I_A100_R_H
+#define _CCU_SUN50I_A100_R_H
+
+#include <dt-bindings/clock/sun50i-a100-r-ccu.h>
+#include <dt-bindings/reset/sun50i-a100-r-ccu.h>
+
+#define CLK_R_CPUS             0
+#define CLK_R_AHB              1
+
+/* exported except APB1 for R_PIO */
+
+#define CLK_R_APB2             3
+
+#define CLK_NUMBER     (CLK_R_AHB_BUS_RTC + 1)
+
+#endif /* _CCU_SUN50I_A100_R_H */
diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a100.c b/drivers/clk/sunxi-ng/ccu-sun50i-a100.c
new file mode 100644 (file)
index 0000000..81b48c7
--- /dev/null
@@ -0,0 +1,1276 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2020 Yangtao Li <frank@allwinnertech.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+
+#include "ccu_common.h"
+#include "ccu_reset.h"
+
+#include "ccu_div.h"
+#include "ccu_gate.h"
+#include "ccu_mp.h"
+#include "ccu_mult.h"
+#include "ccu_nk.h"
+#include "ccu_nkm.h"
+#include "ccu_nkmp.h"
+#include "ccu_nm.h"
+
+#include "ccu-sun50i-a100.h"
+
+#define SUN50I_A100_PLL_SDM_ENABLE             BIT(24)
+#define SUN50I_A100_PLL_OUTPUT_ENABLE          BIT(27)
+#define SUN50I_A100_PLL_LOCK                   BIT(28)
+#define SUN50I_A100_PLL_LOCK_ENABLE            BIT(29)
+#define SUN50I_A100_PLL_ENABLE                 BIT(31)
+
+#define SUN50I_A100_PLL_PERIPH1_PATTERN0       0xd1303333
+
+/*
+ * The CPU PLL is actually NP clock, with P being /1, /2 or /4. However
+ * P should only be used for output frequencies lower than 288 MHz.
+ *
+ * For now we can just model it as a multiplier clock, and force P to /1.
+ *
+ * The M factor is present in the register's description, but not in the
+ * frequency formula, and it's documented as "M is only used for backdoor
+ * testing", so it's not modelled and then force to 0.
+ */
+#define SUN50I_A100_PLL_CPUX_REG               0x000
+static struct ccu_mult pll_cpux_clk = {
+       .enable         = SUN50I_A100_PLL_OUTPUT_ENABLE,
+       .lock           = SUN50I_A100_PLL_LOCK,
+       .mult           = _SUNXI_CCU_MULT_MIN(8, 8, 12),
+       .common         = {
+               .reg            = 0x000,
+               .hw.init        = CLK_HW_INIT("pll-cpux", "dcxo24M",
+                                             &ccu_mult_ops,
+                                             CLK_SET_RATE_UNGATE),
+       },
+};
+
+/* Some PLLs are input * N / div1 / P. Model them as NKMP with no K */
+#define SUN50I_A100_PLL_DDR0_REG               0x010
+static struct ccu_nkmp pll_ddr0_clk = {
+       .enable         = SUN50I_A100_PLL_OUTPUT_ENABLE,
+       .lock           = SUN50I_A100_PLL_LOCK,
+       .n              = _SUNXI_CCU_MULT_MIN(8, 8, 12),
+       .m              = _SUNXI_CCU_DIV(1, 1), /* input divider */
+       .p              = _SUNXI_CCU_DIV(0, 1), /* output divider */
+       .common         = {
+               .reg            = 0x010,
+               .hw.init        = CLK_HW_INIT("pll-ddr0", "dcxo24M",
+                                             &ccu_nkmp_ops,
+                                             CLK_SET_RATE_UNGATE |
+                                             CLK_IS_CRITICAL),
+       },
+};
+
+#define SUN50I_A100_PLL_PERIPH0_REG    0x020
+static struct ccu_nkmp pll_periph0_clk = {
+       .enable         = SUN50I_A100_PLL_OUTPUT_ENABLE,
+       .lock           = SUN50I_A100_PLL_LOCK,
+       .n              = _SUNXI_CCU_MULT_MIN(8, 8, 12),
+       .m              = _SUNXI_CCU_DIV(1, 1), /* input divider */
+       .p              = _SUNXI_CCU_DIV(0, 1), /* output divider */
+       .fixed_post_div = 2,
+       .common         = {
+               .reg            = 0x020,
+               .features       = CCU_FEATURE_FIXED_POSTDIV,
+               .hw.init        = CLK_HW_INIT("pll-periph0", "dcxo24M",
+                                             &ccu_nkmp_ops,
+                                             CLK_SET_RATE_UNGATE),
+       },
+};
+
+#define SUN50I_A100_PLL_PERIPH1_REG    0x028
+static struct ccu_nkmp pll_periph1_clk = {
+       .enable         = SUN50I_A100_PLL_OUTPUT_ENABLE,
+       .lock           = SUN50I_A100_PLL_LOCK,
+       .n              = _SUNXI_CCU_MULT_MIN(8, 8, 12),
+       .m              = _SUNXI_CCU_DIV(1, 1), /* input divider */
+       .p              = _SUNXI_CCU_DIV(0, 1), /* output divider */
+       .fixed_post_div = 2,
+       .common         = {
+               .reg            = 0x028,
+               .features       = CCU_FEATURE_FIXED_POSTDIV,
+               .hw.init        = CLK_HW_INIT("pll-periph1", "dcxo24M",
+                                             &ccu_nkmp_ops,
+                                             CLK_SET_RATE_UNGATE),
+       },
+};
+#define SUN50I_A100_PLL_PERIPH1_PATTERN0_REG   0x128
+
+#define SUN50I_A100_PLL_GPU_REG                0x030
+static struct ccu_nkmp pll_gpu_clk = {
+       .enable         = SUN50I_A100_PLL_OUTPUT_ENABLE,
+       .lock           = SUN50I_A100_PLL_LOCK,
+       .n              = _SUNXI_CCU_MULT_MIN(8, 8, 12),
+       .m              = _SUNXI_CCU_DIV(1, 1), /* input divider */
+       .p              = _SUNXI_CCU_DIV(0, 1), /* output divider */
+       .common         = {
+               .reg            = 0x030,
+               .hw.init        = CLK_HW_INIT("pll-gpu", "dcxo24M",
+                                             &ccu_nkmp_ops,
+                                             CLK_SET_RATE_UNGATE),
+       },
+};
+
+/*
+ * For Video PLLs, the output divider is described as "used for testing"
+ * in the user manual. So it's not modelled and forced to 0.
+ */
+#define SUN50I_A100_PLL_VIDEO0_REG     0x040
+static struct ccu_nm pll_video0_clk = {
+       .enable         = SUN50I_A100_PLL_OUTPUT_ENABLE,
+       .lock           = SUN50I_A100_PLL_LOCK,
+       .n              = _SUNXI_CCU_MULT_MIN(8, 8, 12),
+       .m              = _SUNXI_CCU_DIV(1, 1), /* input divider */
+       .fixed_post_div = 4,
+       .common         = {
+               .reg            = 0x040,
+               .features       = CCU_FEATURE_FIXED_POSTDIV,
+               .hw.init        = CLK_HW_INIT("pll-video0", "dcxo24M",
+                                             &ccu_nm_ops,
+                                             CLK_SET_RATE_UNGATE),
+       },
+};
+
+#define SUN50I_A100_PLL_VIDEO1_REG     0x048
+static struct ccu_nm pll_video1_clk = {
+       .enable         = SUN50I_A100_PLL_OUTPUT_ENABLE,
+       .lock           = SUN50I_A100_PLL_LOCK,
+       .n              = _SUNXI_CCU_MULT_MIN(8, 8, 12),
+       .m              = _SUNXI_CCU_DIV(1, 1), /* input divider */
+       .fixed_post_div = 4,
+       .common         = {
+               .reg            = 0x048,
+               .features       = CCU_FEATURE_FIXED_POSTDIV,
+               .hw.init        = CLK_HW_INIT("pll-video1", "dcxo24M",
+                                             &ccu_nm_ops,
+                                             CLK_SET_RATE_UNGATE),
+       },
+};
+
+#define SUN50I_A100_PLL_VIDEO2_REG     0x050
+static struct ccu_nm pll_video2_clk = {
+       .enable         = SUN50I_A100_PLL_OUTPUT_ENABLE,
+       .lock           = SUN50I_A100_PLL_LOCK,
+       .n              = _SUNXI_CCU_MULT_MIN(8, 8, 12),
+       .m              = _SUNXI_CCU_DIV(1, 1), /* input divider */
+       .fixed_post_div = 4,
+       .common         = {
+               .reg            = 0x050,
+               .features       = CCU_FEATURE_FIXED_POSTDIV,
+               .hw.init        = CLK_HW_INIT("pll-video2", "dcxo24M",
+                                             &ccu_nm_ops,
+                                             CLK_SET_RATE_UNGATE),
+       },
+};
+
+#define SUN50I_A100_PLL_VE_REG         0x058
+static struct ccu_nkmp pll_ve_clk = {
+       .enable         = SUN50I_A100_PLL_OUTPUT_ENABLE,
+       .lock           = SUN50I_A100_PLL_LOCK,
+       .n              = _SUNXI_CCU_MULT_MIN(8, 8, 12),
+       .m              = _SUNXI_CCU_DIV(1, 1), /* input divider */
+       .p              = _SUNXI_CCU_DIV(0, 1), /* output divider */
+       .common         = {
+               .reg            = 0x058,
+               .hw.init        = CLK_HW_INIT("pll-ve", "dcxo24M",
+                                             &ccu_nkmp_ops,
+                                             CLK_SET_RATE_UNGATE),
+       },
+};
+
+/*
+ * The COM PLL has m0 dividers in addition to the usual N, M
+ * factors. Since we only need 1 frequencies from this PLL: 45.1584 MHz,
+ * ignore it for now.
+ */
+#define SUN50I_A100_PLL_COM_REG                0x060
+static struct ccu_sdm_setting pll_com_sdm_table[] = {
+       { .rate = 451584000, .pattern = 0xc0014396, .m = 2, .n = 37 },
+};
+
+static struct ccu_nm pll_com_clk = {
+       .enable         = SUN50I_A100_PLL_OUTPUT_ENABLE,
+       .lock           = SUN50I_A100_PLL_LOCK,
+       .n              = _SUNXI_CCU_MULT_MIN(8, 8, 12),
+       .m              = _SUNXI_CCU_DIV(0, 1),
+       .sdm            = _SUNXI_CCU_SDM(pll_com_sdm_table, BIT(24),
+                                        0x160, BIT(31)),
+       .common         = {
+               .reg            = 0x060,
+               .features       = CCU_FEATURE_SIGMA_DELTA_MOD,
+               .hw.init        = CLK_HW_INIT("pll-com", "dcxo24M",
+                                             &ccu_nm_ops,
+                                             CLK_SET_RATE_UNGATE),
+       },
+};
+
+#define SUN50I_A100_PLL_VIDEO3_REG     0x068
+static struct ccu_nm pll_video3_clk = {
+       .enable         = SUN50I_A100_PLL_OUTPUT_ENABLE,
+       .lock           = SUN50I_A100_PLL_LOCK,
+       .n              = _SUNXI_CCU_MULT_MIN(8, 8, 12),
+       .m              = _SUNXI_CCU_DIV(1, 1), /* input divider */
+       .fixed_post_div = 4,
+       .common         = {
+               .reg            = 0x068,
+               .features       = CCU_FEATURE_FIXED_POSTDIV,
+               .hw.init        = CLK_HW_INIT("pll-video3", "dcxo24M",
+                                             &ccu_nm_ops,
+                                             CLK_SET_RATE_UNGATE),
+       },
+};
+
+/*
+ * The Audio PLL has m0, m1 dividers in addition to the usual N, M
+ * factors. Since we only need 4 frequencies from this PLL: 22.5792 MHz,
+ * 24.576 MHz, 90.3168MHz and 98.304MHz ignore them for now.
+ * Enforce the default for them, which is m0 = 1, m1 = 0.
+ */
+#define SUN50I_A100_PLL_AUDIO_REG              0x078
+static struct ccu_sdm_setting pll_audio_sdm_table[] = {
+       { .rate = 45158400, .pattern = 0xc001bcd3, .m = 18, .n = 33 },
+       { .rate = 49152000, .pattern = 0xc001eb85, .m = 20, .n = 40 },
+       { .rate = 180633600, .pattern = 0xc001288d, .m = 3, .n = 22 },
+       { .rate = 196608000, .pattern = 0xc001eb85, .m = 5, .n = 40 },
+};
+
+static struct ccu_nm pll_audio_clk = {
+       .enable         = SUN50I_A100_PLL_OUTPUT_ENABLE,
+       .lock           = SUN50I_A100_PLL_LOCK,
+       .n              = _SUNXI_CCU_MULT_MIN(8, 8, 12),
+       .m              = _SUNXI_CCU_DIV(16, 6),
+       .fixed_post_div = 2,
+       .sdm            = _SUNXI_CCU_SDM(pll_audio_sdm_table, BIT(24),
+                                        0x178, BIT(31)),
+       .common         = {
+               .reg            = 0x078,
+               .features       = CCU_FEATURE_FIXED_POSTDIV |
+                                 CCU_FEATURE_SIGMA_DELTA_MOD,
+               .hw.init        = CLK_HW_INIT("pll-audio", "dcxo24M",
+                                             &ccu_nm_ops,
+                                             CLK_SET_RATE_UNGATE),
+       },
+};
+
+static const char * const cpux_parents[] = { "dcxo24M", "osc32k",
+                                            "iosc", "pll-cpux",
+                                             "pll-periph0" };
+static SUNXI_CCU_MUX(cpux_clk, "cpux", cpux_parents,
+                    0x500, 24, 3, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL);
+static SUNXI_CCU_M(axi_clk, "axi", "cpux", 0x500, 0, 2, 0);
+static SUNXI_CCU_M(cpux_apb_clk, "cpux-apb", "cpux", 0x500, 8, 2, 0);
+
+static const char * const psi_ahb1_ahb2_parents[] = { "dcxo24M", "osc32k",
+                                                     "iosc", "pll-periph0",
+                                                     "pll-periph0-2x" };
+static SUNXI_CCU_MP_WITH_MUX(psi_ahb1_ahb2_clk, "psi-ahb1-ahb2",
+                            psi_ahb1_ahb2_parents, 0x510,
+                            0, 2,      /* M */
+                            8, 2,      /* P */
+                            24, 3,     /* mux */
+                            0);
+
+static const char * const ahb3_apb1_apb2_parents[] = { "dcxo24M", "osc32k",
+                                                      "psi-ahb1-ahb2",
+                                                      "pll-periph0",
+                                                      "pll-periph0-2x" };
+static SUNXI_CCU_MP_WITH_MUX(ahb3_clk, "ahb3", ahb3_apb1_apb2_parents, 0x51c,
+                            0, 2,      /* M */
+                            8, 2,      /* P */
+                            24, 3,     /* mux */
+                            0);
+
+static SUNXI_CCU_MP_WITH_MUX(apb1_clk, "apb1", ahb3_apb1_apb2_parents, 0x520,
+                            0, 2,      /* M */
+                            8, 2,      /* P */
+                            24, 3,     /* mux */
+                            0);
+
+static SUNXI_CCU_MP_WITH_MUX(apb2_clk, "apb2", ahb3_apb1_apb2_parents, 0x524,
+                            0, 2,      /* M */
+                            8, 2,      /* P */
+                            24, 3,     /* mux */
+                            0);
+
+static const char * const mbus_parents[] = { "dcxo24M", "pll-ddr0",
+                                            "pll-periph0",
+                                            "pll-periph0-2x" };
+static SUNXI_CCU_M_WITH_MUX_GATE(mbus_clk, "mbus", mbus_parents, 0x540,
+                                0, 3,          /* M */
+                                24, 2,         /* mux */
+                                BIT(31),       /* gate */
+                                CLK_IS_CRITICAL);
+
+static const char * const de_parents[] = { "pll-com", "pll-periph0-2x" };
+static SUNXI_CCU_M_WITH_MUX_GATE(de_clk, "de0", de_parents, 0x600,
+                                0, 4,          /* M */
+                                24, 1,         /* mux */
+                                BIT(31),       /* gate */
+                                CLK_SET_RATE_PARENT);
+
+static SUNXI_CCU_GATE(bus_de_clk, "bus-de", "psi-ahb1-ahb2",
+                     0x60c, BIT(0), 0);
+
+static const char * const g2d_parents[] = { "pll-com", "pll-periph0-2x",
+                                            "pll-video0-2x", "pll-video1-2x",
+                                            "pll-video2-2x"};
+static SUNXI_CCU_M_WITH_MUX_GATE(g2d_clk, "g2d",
+                                g2d_parents,
+                                0x630,
+                                0, 4,          /* M */
+                                24, 3,         /* mux */
+                                BIT(31),       /* gate */
+                                0);
+
+static SUNXI_CCU_GATE(bus_g2d_clk, "bus-g2d", "psi-ahb1-ahb2",
+                     0x63c, BIT(0), 0);
+
+static const char * const gpu_parents[] = { "pll-gpu" };
+static SUNXI_CCU_M_WITH_MUX_GATE(gpu_clk, "gpu", gpu_parents, 0x670,
+                                      0, 2,    /* M */
+                                      24, 1,   /* mux */
+                                      BIT(31), /* gate */
+                                      0);
+
+static SUNXI_CCU_GATE(bus_gpu_clk, "bus-gpu", "psi-ahb1-ahb2",
+                     0x67c, BIT(0), 0);
+
+static const char * const ce_parents[] = { "dcxo24M", "pll-periph0-2x" };
+static SUNXI_CCU_MP_WITH_MUX_GATE(ce_clk, "ce", ce_parents, 0x680,
+                                 0, 4,         /* M */
+                                 8, 2,         /* P */
+                                 24, 1,        /* mux */
+                                 BIT(31),      /* gate */
+                                 0);
+
+static SUNXI_CCU_GATE(bus_ce_clk, "bus-ce", "psi-ahb1-ahb2",
+                     0x68c, BIT(0), 0);
+
+static const char * const ve_parents[] = { "pll-ve" };
+static SUNXI_CCU_M_WITH_MUX_GATE(ve_clk, "ve", ve_parents, 0x690,
+                                0, 3,          /* M */
+                                24, 1,         /* mux */
+                                BIT(31),       /* gate */
+                                CLK_SET_RATE_PARENT);
+
+static SUNXI_CCU_GATE(bus_ve_clk, "bus-ve", "psi-ahb1-ahb2",
+                     0x69c, BIT(0), 0);
+
+static SUNXI_CCU_GATE(bus_dma_clk, "bus-dma", "psi-ahb1-ahb2",
+                     0x70c, BIT(0), 0);
+
+static SUNXI_CCU_GATE(bus_msgbox_clk, "bus-msgbox", "psi-ahb1-ahb2",
+                     0x71c, BIT(0), 0);
+
+static SUNXI_CCU_GATE(bus_spinlock_clk, "bus-spinlock", "psi-ahb1-ahb2",
+                     0x72c, BIT(0), 0);
+
+static SUNXI_CCU_GATE(bus_hstimer_clk, "bus-hstimer", "psi-ahb1-ahb2",
+                     0x73c, BIT(0), 0);
+
+static SUNXI_CCU_GATE(avs_clk, "avs", "dcxo24M", 0x740, BIT(31), 0);
+
+static SUNXI_CCU_GATE(bus_dbg_clk, "bus-dbg", "psi-ahb1-ahb2",
+                     0x78c, BIT(0), 0);
+
+static SUNXI_CCU_GATE(bus_psi_clk, "bus-psi", "psi-ahb1-ahb2",
+                     0x79c, BIT(0), 0);
+
+static SUNXI_CCU_GATE(bus_pwm_clk, "bus-pwm", "apb1", 0x7ac, BIT(0), 0);
+
+static SUNXI_CCU_GATE(bus_iommu_clk, "bus-iommu", "apb1", 0x7bc, BIT(0), 0);
+
+static SUNXI_CCU_GATE(mbus_dma_clk, "mbus-dma", "mbus",
+                     0x804, BIT(0), 0);
+static SUNXI_CCU_GATE(mbus_ve_clk, "mbus-ve", "mbus",
+                     0x804, BIT(1), 0);
+static SUNXI_CCU_GATE(mbus_ce_clk, "mbus-ce", "mbus",
+                     0x804, BIT(2), 0);
+static SUNXI_CCU_GATE(mbus_nand_clk, "mbus-nand", "mbus",
+                     0x804, BIT(5), 0);
+static SUNXI_CCU_GATE(mbus_csi_clk, "mbus-csi", "mbus",
+                     0x804, BIT(8), 0);
+static SUNXI_CCU_GATE(mbus_isp_clk, "mbus-isp", "mbus",
+                     0x804, BIT(9), 0);
+static SUNXI_CCU_GATE(mbus_g2d_clk, "mbus-g2d", "mbus",
+                     0x804, BIT(10), 0);
+
+static SUNXI_CCU_GATE(bus_dram_clk, "bus-dram", "psi-ahb1-ahb2",
+                     0x80c, BIT(0), CLK_IS_CRITICAL);
+
+static const char * const nand_spi_parents[] = { "dcxo24M",
+                                                "pll-periph0",
+                                                "pll-periph1",
+                                                "pll-periph0-2x",
+                                                "pll-periph1-2x" };
+static SUNXI_CCU_MP_WITH_MUX_GATE(nand0_clk, "nand0", nand_spi_parents, 0x810,
+                                 0, 4,         /* M */
+                                 8, 2,         /* P */
+                                 24, 3,        /* mux */
+                                 BIT(31),      /* gate */
+                                 0);
+
+static SUNXI_CCU_MP_WITH_MUX_GATE(nand1_clk, "nand1", nand_spi_parents, 0x814,
+                                 0, 4,         /* M */
+                                 8, 2,         /* P */
+                                 24, 3,        /* mux */
+                                 BIT(31),      /* gate */
+                                 0);
+
+static SUNXI_CCU_GATE(bus_nand_clk, "bus-nand", "ahb3", 0x82c, BIT(0), 0);
+
+static const char * const mmc_parents[] = { "dcxo24M", "pll-periph0-2x",
+                                           "pll-periph1-2x" };
+static SUNXI_CCU_MP_WITH_MUX_GATE_POSTDIV(mmc0_clk, "mmc0", mmc_parents, 0x830,
+                                         0, 4,         /* M */
+                                         8, 2,         /* P */
+                                         24, 2,        /* mux */
+                                         BIT(31),      /* gate */
+                                         2,            /* post-div */
+                                         CLK_SET_RATE_NO_REPARENT);
+
+static SUNXI_CCU_MP_WITH_MUX_GATE_POSTDIV(mmc1_clk, "mmc1", mmc_parents, 0x834,
+                                         0, 4,         /* M */
+                                         8, 2,         /* P */
+                                         24, 2,        /* mux */
+                                         BIT(31),      /* gate */
+                                         2,            /* post-div */
+                                         CLK_SET_RATE_NO_REPARENT);
+
+static SUNXI_CCU_MP_WITH_MUX_GATE_POSTDIV(mmc2_clk, "mmc2", mmc_parents, 0x838,
+                                         0, 4,         /* M */
+                                         8, 2,         /* P */
+                                         24, 2,        /* mux */
+                                         BIT(31),      /* gate */
+                                         2,            /* post-div */
+                                         CLK_SET_RATE_NO_REPARENT);
+
+static SUNXI_CCU_GATE(bus_mmc0_clk, "bus-mmc0", "ahb3", 0x84c, BIT(0), 0);
+static SUNXI_CCU_GATE(bus_mmc1_clk, "bus-mmc1", "ahb3", 0x84c, BIT(1), 0);
+static SUNXI_CCU_GATE(bus_mmc2_clk, "bus-mmc2", "ahb3", 0x84c, BIT(2), 0);
+
+static SUNXI_CCU_GATE(bus_uart0_clk, "bus-uart0", "apb2", 0x90c, BIT(0), 0);
+static SUNXI_CCU_GATE(bus_uart1_clk, "bus-uart1", "apb2", 0x90c, BIT(1), 0);
+static SUNXI_CCU_GATE(bus_uart2_clk, "bus-uart2", "apb2", 0x90c, BIT(2), 0);
+static SUNXI_CCU_GATE(bus_uart3_clk, "bus-uart3", "apb2", 0x90c, BIT(3), 0);
+static SUNXI_CCU_GATE(bus_uart4_clk, "bus-uart4", "apb2", 0x90c, BIT(4), 0);
+
+static SUNXI_CCU_GATE(bus_i2c0_clk, "bus-i2c0", "apb2", 0x91c, BIT(0), 0);
+static SUNXI_CCU_GATE(bus_i2c1_clk, "bus-i2c1", "apb2", 0x91c, BIT(1), 0);
+static SUNXI_CCU_GATE(bus_i2c2_clk, "bus-i2c2", "apb2", 0x91c, BIT(2), 0);
+static SUNXI_CCU_GATE(bus_i2c3_clk, "bus-i2c3", "apb2", 0x91c, BIT(3), 0);
+
+static SUNXI_CCU_MP_WITH_MUX_GATE(spi0_clk, "spi0", nand_spi_parents, 0x940,
+                                 0, 4,         /* M */
+                                 8, 2,         /* P */
+                                 24, 3,        /* mux */
+                                 BIT(31),      /* gate */
+                                 0);
+
+static SUNXI_CCU_MP_WITH_MUX_GATE(spi1_clk, "spi1", nand_spi_parents, 0x944,
+                                 0, 4,         /* M */
+                                 8, 2,         /* P */
+                                 24, 3,        /* mux */
+                                 BIT(31),      /* gate */
+                                 0);
+
+static SUNXI_CCU_MP_WITH_MUX_GATE(spi2_clk, "spi2", nand_spi_parents, 0x948,
+                                 0, 4,         /* M */
+                                 8, 2,         /* P */
+                                 24, 3,        /* mux */
+                                 BIT(31),      /* gate */
+                                 0);
+
+static SUNXI_CCU_GATE(bus_spi0_clk, "bus-spi0", "ahb3", 0x96c, BIT(0), 0);
+static SUNXI_CCU_GATE(bus_spi1_clk, "bus-spi1", "ahb3", 0x96c, BIT(1), 0);
+static SUNXI_CCU_GATE(bus_spi2_clk, "bus-spi2", "ahb3", 0x96c, BIT(2), 0);
+
+static SUNXI_CCU_GATE(emac_25m_clk, "emac-25m", "ahb3", 0x970,
+                     BIT(31) | BIT(30), 0);
+
+static SUNXI_CCU_GATE(bus_emac_clk, "bus-emac", "ahb3", 0x97c, BIT(0), 0);
+
+static const char * const ir_parents[] = { "osc32k", "iosc",
+                                          "pll-periph0", "pll-periph1" };
+static SUNXI_CCU_MP_WITH_MUX_GATE(ir_rx_clk, "ir-rx", ir_parents, 0x990,
+                                 0, 4,         /* M */
+                                 8, 2,         /* P */
+                                 24, 3,        /* mux */
+                                 BIT(31),      /* gate */
+                                 0);
+
+static SUNXI_CCU_GATE(bus_ir_rx_clk, "bus-ir-rx", "ahb3", 0x99c, BIT(0), 0);
+
+static SUNXI_CCU_MP_WITH_MUX_GATE(ir_tx_clk, "ir-tx", ir_parents, 0x9c0,
+                                 0, 4,         /* M */
+                                 8, 2,         /* P */
+                                 24, 3,        /* mux */
+                                 BIT(31),      /* gate */
+                                 0);
+
+static SUNXI_CCU_GATE(bus_ir_tx_clk, "bus-ir-tx", "apb1", 0x9cc, BIT(0), 0);
+
+static SUNXI_CCU_GATE(bus_gpadc_clk, "bus-gpadc", "apb1", 0x9ec, BIT(0), 0);
+
+static SUNXI_CCU_GATE(bus_ths_clk, "bus-ths", "apb1", 0x9fc, BIT(0), 0);
+
+static const char * const audio_parents[] = { "pll-audio", "pll-com-audio" };
+static struct ccu_div i2s0_clk = {
+       .enable         = BIT(31),
+       .div            = _SUNXI_CCU_DIV_FLAGS(8, 2, CLK_DIVIDER_POWER_OF_TWO),
+       .mux            = _SUNXI_CCU_MUX(24, 2),
+       .common         = {
+               .reg            = 0xa10,
+               .hw.init        = CLK_HW_INIT_PARENTS("i2s0",
+                                                     audio_parents,
+                                                     &ccu_div_ops,
+                                                     CLK_SET_RATE_PARENT),
+       },
+};
+
+static struct ccu_div i2s1_clk = {
+       .enable         = BIT(31),
+       .div            = _SUNXI_CCU_DIV_FLAGS(8, 2, CLK_DIVIDER_POWER_OF_TWO),
+       .mux            = _SUNXI_CCU_MUX(24, 2),
+       .common         = {
+               .reg            = 0xa14,
+               .hw.init        = CLK_HW_INIT_PARENTS("i2s1",
+                                                     audio_parents,
+                                                     &ccu_div_ops,
+                                                     CLK_SET_RATE_PARENT),
+       },
+};
+
+static struct ccu_div i2s2_clk = {
+       .enable         = BIT(31),
+       .div            = _SUNXI_CCU_DIV_FLAGS(8, 2, CLK_DIVIDER_POWER_OF_TWO),
+       .mux            = _SUNXI_CCU_MUX(24, 2),
+       .common         = {
+               .reg            = 0xa18,
+               .hw.init        = CLK_HW_INIT_PARENTS("i2s2",
+                                                     audio_parents,
+                                                     &ccu_div_ops,
+                                                     CLK_SET_RATE_PARENT),
+       },
+};
+
+static struct ccu_div i2s3_clk = {
+       .enable         = BIT(31),
+       .div            = _SUNXI_CCU_DIV_FLAGS(8, 2, CLK_DIVIDER_POWER_OF_TWO),
+       .mux            = _SUNXI_CCU_MUX(24, 2),
+       .common         = {
+               .reg            = 0xa1c,
+               .hw.init        = CLK_HW_INIT_PARENTS("i2s3",
+                                                     audio_parents,
+                                                     &ccu_div_ops,
+                                                     CLK_SET_RATE_PARENT),
+       },
+};
+
+static SUNXI_CCU_GATE(bus_i2s0_clk, "bus-i2s0", "apb1", 0xa20, BIT(0), 0);
+static SUNXI_CCU_GATE(bus_i2s1_clk, "bus-i2s1", "apb1", 0xa20, BIT(1), 0);
+static SUNXI_CCU_GATE(bus_i2s2_clk, "bus-i2s2", "apb1", 0xa20, BIT(2), 0);
+static SUNXI_CCU_GATE(bus_i2s3_clk, "bus-i2s3", "apb1", 0xa20, BIT(3), 0);
+
+static struct ccu_div spdif_clk = {
+       .enable         = BIT(31),
+       .div            = _SUNXI_CCU_DIV_FLAGS(8, 2, CLK_DIVIDER_POWER_OF_TWO),
+       .mux            = _SUNXI_CCU_MUX(24, 2),
+       .common         = {
+               .reg            = 0xa24,
+               .hw.init        = CLK_HW_INIT_PARENTS("spdif",
+                                                     audio_parents,
+                                                     &ccu_div_ops,
+                                                     0),
+       },
+};
+
+static SUNXI_CCU_GATE(bus_spdif_clk, "bus-spdif", "apb1", 0xa2c, BIT(0), 0);
+
+static struct ccu_div dmic_clk = {
+       .enable         = BIT(31),
+       .div            = _SUNXI_CCU_DIV_FLAGS(8, 2, CLK_DIVIDER_POWER_OF_TWO),
+       .mux            = _SUNXI_CCU_MUX(24, 2),
+       .common         = {
+               .reg            = 0xa40,
+               .hw.init        = CLK_HW_INIT_PARENTS("dmic",
+                                                     audio_parents,
+                                                     &ccu_div_ops,
+                                                     0),
+       },
+};
+
+static SUNXI_CCU_GATE(bus_dmic_clk, "bus-dmic", "apb1", 0xa4c, BIT(0), 0);
+
+static SUNXI_CCU_M_WITH_MUX_GATE(audio_codec_dac_clk, "audio-codec-dac",
+                                audio_parents, 0xa50,
+                                0, 4,          /* M */
+                                24, 2,         /* mux */
+                                BIT(31),       /* gate */
+                                0);
+
+static SUNXI_CCU_M_WITH_MUX_GATE(audio_codec_adc_clk, "audio-codec-adc",
+                                audio_parents, 0xa54,
+                                0, 4,          /* M */
+                                24, 2,         /* mux */
+                                BIT(31),       /* gate */
+                                0);
+
+static SUNXI_CCU_M_WITH_MUX_GATE(audio_codec_4x_clk, "audio-codec-4x",
+                                audio_parents, 0xa58,
+                                0, 4,          /* M */
+                                24, 2,         /* mux */
+                                BIT(31),       /* gate */
+                                0);
+
+static SUNXI_CCU_GATE(bus_audio_codec_clk, "bus-audio-codec", "apb1", 0xa5c,
+                     BIT(0), 0);
+
+/*
+ * There are OHCI 12M clock source selection bits for 2 USB 2.0 ports.
+ * We will force them to 0 (12M divided from 48M).
+ */
+#define SUN50I_A100_USB0_CLK_REG               0xa70
+#define SUN50I_A100_USB1_CLK_REG               0xa74
+
+static SUNXI_CCU_GATE(usb_ohci0_clk, "usb-ohci0", "osc12M", 0xa70, BIT(31), 0);
+static SUNXI_CCU_GATE(usb_phy0_clk, "usb-phy0", "dcxo24M", 0xa70, BIT(29), 0);
+
+static SUNXI_CCU_GATE(usb_ohci1_clk, "usb-ohci1", "osc12M", 0xa74, BIT(31), 0);
+static SUNXI_CCU_GATE(usb_phy1_clk, "usb-phy1", "dcxo24M", 0xa74, BIT(29), 0);
+
+static SUNXI_CCU_GATE(bus_ohci0_clk, "bus-ohci0", "ahb3", 0xa8c, BIT(0), 0);
+static SUNXI_CCU_GATE(bus_ohci1_clk, "bus-ohci1", "ahb3", 0xa8c, BIT(1), 0);
+static SUNXI_CCU_GATE(bus_ehci0_clk, "bus-ehci0", "ahb3", 0xa8c, BIT(4), 0);
+static SUNXI_CCU_GATE(bus_ehci1_clk, "bus-ehci1", "ahb3", 0xa8c, BIT(5), 0);
+static SUNXI_CCU_GATE(bus_otg_clk, "bus-otg", "ahb3", 0xa8c, BIT(8), 0);
+
+static SUNXI_CCU_GATE(bus_lradc_clk, "bus-lradc", "ahb3", 0xa9c, BIT(0), 0);
+
+static SUNXI_CCU_GATE(bus_dpss_top0_clk, "bus-dpss-top0", "ahb3",
+                     0xabc, BIT(0), 0);
+
+static SUNXI_CCU_GATE(bus_dpss_top1_clk, "bus-dpss-top1", "ahb3",
+                     0xacc, BIT(0), 0);
+
+static const char * const mipi_dsi_parents[] = { "dcxo24M", "pll-periph0-2x",
+                                                "pll-periph0" };
+static SUNXI_CCU_M_WITH_MUX_GATE(mipi_dsi_clk, "mipi-dsi",
+                                mipi_dsi_parents,
+                                0xb24,
+                                0, 4,          /* M */
+                                24, 2,         /* mux */
+                                BIT(31),       /* gate */
+                                0);
+
+static SUNXI_CCU_GATE(bus_mipi_dsi_clk, "bus-mipi-dsi", "ahb3",
+                     0xb4c, BIT(0), 0);
+
+static const char * const tcon_lcd_parents[] = { "pll-video0-4x",
+                                                 "pll-video1-4x",
+                                                 "pll-video2-4x",
+                                                 "pll-video3-4x",
+                                                 "pll-periph0-2x" };
+static SUNXI_CCU_MP_WITH_MUX_GATE(tcon_lcd_clk, "tcon-lcd0",
+                                 tcon_lcd_parents, 0xb60,
+                                 0, 4,         /* M */
+                                 8, 2,         /* P */
+                                 24, 3,        /* mux */
+                                 BIT(31),      /* gate */
+                                 0);
+
+static SUNXI_CCU_GATE(bus_tcon_lcd_clk, "bus-tcon-lcd0", "ahb3",
+                     0xb7c, BIT(0), 0);
+
+static const char * const ledc_parents[] = { "dcxo24M",
+                                            "pll-periph0" };
+static SUNXI_CCU_MP_WITH_MUX_GATE(ledc_clk, "ledc",
+                                 ledc_parents, 0xbf0,
+                                 0, 4,         /* M */
+                                 8, 2,         /* P */
+                                 24, 3,        /* mux */
+                                 BIT(31),      /* gate */
+                                 0);
+
+static SUNXI_CCU_GATE(bus_ledc_clk, "bus-ledc", "ahb3", 0xbfc, BIT(0), 0);
+
+static const char * const csi_top_parents[] = { "pll-periph0-2x",
+                                               "pll-video0-2x",
+                                               "pll-video1-2x",
+                                               "pll-video2-2x",
+                                               "pll-video3-2x" };
+static SUNXI_CCU_M_WITH_MUX_GATE(csi_top_clk, "csi-top",
+                                csi_top_parents, 0xc04,
+                                0, 4,          /* M */
+                                24, 3,         /* mux */
+                                BIT(31),       /* gate */
+                                0);
+
+static const char * const csi0_mclk_parents[] = { "dcxo24M", "pll-video2",
+                                                 "pll-video3", "pll-video0",
+                                                 "pll-video1" };
+static SUNXI_CCU_M_WITH_MUX_GATE(csi0_mclk_clk, "csi0-mclk",
+                                csi0_mclk_parents, 0xc08,
+                                0, 5,          /* M */
+                                24, 3,         /* mux */
+                                BIT(31),       /* gate */
+                                0);
+
+static const char * const csi1_mclk_parents[] = { "dcxo24M", "pll-video3",
+                                                 "pll-video0", "pll-video1",
+                                                 "pll-video2" };
+static SUNXI_CCU_M_WITH_MUX_GATE(csi1_mclk_clk, "csi1-mclk",
+                                csi1_mclk_parents, 0xc0c,
+                                0, 5,          /* M */
+                                24, 3,         /* mux */
+                                BIT(31),       /* gate */
+                                0);
+
+static SUNXI_CCU_GATE(bus_csi_clk, "bus-csi", "ahb3", 0xc1c, BIT(0), 0);
+
+static const char * const csi_isp_parents[] = { "pll-periph0-2x",
+                                               "pll-video0-2x",
+                                               "pll-video1-2x",
+                                               "pll-video2-2x",
+                                               "pll-video3-2x" };
+static SUNXI_CCU_M_WITH_MUX_GATE(csi_isp_clk, "csi-isp",
+                                csi_isp_parents, 0xc20,
+                                0, 5,          /* M */
+                                24, 3,         /* mux */
+                                BIT(31),       /* gate */
+                                0);
+
+/* Fixed factor clocks */
+static CLK_FIXED_FACTOR_FW_NAME(osc12M_clk, "osc12M", "hosc", 2, 1, 0);
+
+static CLK_FIXED_FACTOR_HW(pll_com_audio_clk, "pll-com-audio",
+                          &pll_com_clk.common.hw,
+                          5, 1, CLK_SET_RATE_PARENT);
+
+static CLK_FIXED_FACTOR_HW(pll_periph0_2x_clk, "pll-periph0-2x",
+                          &pll_periph0_clk.common.hw,
+                          1, 2, 0);
+
+static CLK_FIXED_FACTOR_HW(pll_periph1_2x_clk, "pll-periph1-2x",
+                          &pll_periph1_clk.common.hw,
+                          1, 2, 0);
+
+static const struct clk_hw *pll_video0_parents[] = {
+       &pll_video0_clk.common.hw
+};
+static CLK_FIXED_FACTOR_HWS(pll_video0_4x_clk, "pll-video0-4x",
+                           pll_video0_parents,
+                           1, 4, CLK_SET_RATE_PARENT);
+static CLK_FIXED_FACTOR_HWS(pll_video0_2x_clk, "pll-video0-2x",
+                           pll_video0_parents,
+                           1, 2, CLK_SET_RATE_PARENT);
+
+static const struct clk_hw *pll_video1_parents[] = {
+       &pll_video1_clk.common.hw
+};
+static CLK_FIXED_FACTOR_HWS(pll_video1_4x_clk, "pll-video1-4x",
+                           pll_video1_parents,
+                           1, 4, CLK_SET_RATE_PARENT);
+static CLK_FIXED_FACTOR_HWS(pll_video1_2x_clk, "pll-video1-2x",
+                           pll_video1_parents,
+                           1, 2, CLK_SET_RATE_PARENT);
+
+static const struct clk_hw *pll_video2_parents[] = {
+       &pll_video2_clk.common.hw
+};
+static CLK_FIXED_FACTOR_HWS(pll_video2_4x_clk, "pll-video2-4x",
+                           pll_video2_parents,
+                           1, 4, CLK_SET_RATE_PARENT);
+static CLK_FIXED_FACTOR_HWS(pll_video2_2x_clk, "pll-video2-2x",
+                           pll_video2_parents,
+                           1, 2, CLK_SET_RATE_PARENT);
+
+static const struct clk_hw *pll_video3_parents[] = {
+       &pll_video3_clk.common.hw
+};
+static CLK_FIXED_FACTOR_HWS(pll_video3_4x_clk, "pll-video3-4x",
+                           pll_video3_parents,
+                           1, 4, CLK_SET_RATE_PARENT);
+static CLK_FIXED_FACTOR_HWS(pll_video3_2x_clk, "pll-video3-2x",
+                           pll_video3_parents,
+                           1, 2, CLK_SET_RATE_PARENT);
+
+static struct ccu_common *sun50i_a100_ccu_clks[] = {
+       &pll_cpux_clk.common,
+       &pll_ddr0_clk.common,
+       &pll_periph0_clk.common,
+       &pll_periph1_clk.common,
+       &pll_gpu_clk.common,
+       &pll_video0_clk.common,
+       &pll_video1_clk.common,
+       &pll_video2_clk.common,
+       &pll_video3_clk.common,
+       &pll_ve_clk.common,
+       &pll_com_clk.common,
+       &pll_audio_clk.common,
+       &cpux_clk.common,
+       &axi_clk.common,
+       &cpux_apb_clk.common,
+       &psi_ahb1_ahb2_clk.common,
+       &ahb3_clk.common,
+       &apb1_clk.common,
+       &apb2_clk.common,
+       &mbus_clk.common,
+       &de_clk.common,
+       &bus_de_clk.common,
+       &g2d_clk.common,
+       &bus_g2d_clk.common,
+       &gpu_clk.common,
+       &bus_gpu_clk.common,
+       &ce_clk.common,
+       &bus_ce_clk.common,
+       &ve_clk.common,
+       &bus_ve_clk.common,
+       &bus_dma_clk.common,
+       &bus_msgbox_clk.common,
+       &bus_spinlock_clk.common,
+       &bus_hstimer_clk.common,
+       &avs_clk.common,
+       &bus_dbg_clk.common,
+       &bus_psi_clk.common,
+       &bus_pwm_clk.common,
+       &bus_iommu_clk.common,
+       &mbus_dma_clk.common,
+       &mbus_ve_clk.common,
+       &mbus_ce_clk.common,
+       &mbus_nand_clk.common,
+       &mbus_csi_clk.common,
+       &mbus_isp_clk.common,
+       &mbus_g2d_clk.common,
+       &bus_dram_clk.common,
+       &nand0_clk.common,
+       &nand1_clk.common,
+       &bus_nand_clk.common,
+       &mmc0_clk.common,
+       &mmc1_clk.common,
+       &mmc2_clk.common,
+       &bus_mmc0_clk.common,
+       &bus_mmc1_clk.common,
+       &bus_mmc2_clk.common,
+       &bus_uart0_clk.common,
+       &bus_uart1_clk.common,
+       &bus_uart2_clk.common,
+       &bus_uart3_clk.common,
+       &bus_uart4_clk.common,
+       &bus_i2c0_clk.common,
+       &bus_i2c1_clk.common,
+       &bus_i2c2_clk.common,
+       &bus_i2c3_clk.common,
+       &spi0_clk.common,
+       &spi1_clk.common,
+       &spi2_clk.common,
+       &bus_spi0_clk.common,
+       &bus_spi1_clk.common,
+       &bus_spi2_clk.common,
+       &emac_25m_clk.common,
+       &bus_emac_clk.common,
+       &ir_rx_clk.common,
+       &bus_ir_rx_clk.common,
+       &ir_tx_clk.common,
+       &bus_ir_tx_clk.common,
+       &bus_gpadc_clk.common,
+       &bus_ths_clk.common,
+       &i2s0_clk.common,
+       &i2s1_clk.common,
+       &i2s2_clk.common,
+       &i2s3_clk.common,
+       &bus_i2s0_clk.common,
+       &bus_i2s1_clk.common,
+       &bus_i2s2_clk.common,
+       &bus_i2s3_clk.common,
+       &spdif_clk.common,
+       &bus_spdif_clk.common,
+       &dmic_clk.common,
+       &bus_dmic_clk.common,
+       &audio_codec_dac_clk.common,
+       &audio_codec_adc_clk.common,
+       &audio_codec_4x_clk.common,
+       &bus_audio_codec_clk.common,
+       &usb_ohci0_clk.common,
+       &usb_phy0_clk.common,
+       &usb_ohci1_clk.common,
+       &usb_phy1_clk.common,
+       &bus_ohci0_clk.common,
+       &bus_ohci1_clk.common,
+       &bus_ehci0_clk.common,
+       &bus_ehci1_clk.common,
+       &bus_otg_clk.common,
+       &bus_lradc_clk.common,
+       &bus_dpss_top0_clk.common,
+       &bus_dpss_top1_clk.common,
+       &mipi_dsi_clk.common,
+       &bus_mipi_dsi_clk.common,
+       &tcon_lcd_clk.common,
+       &bus_tcon_lcd_clk.common,
+       &ledc_clk.common,
+       &bus_ledc_clk.common,
+       &csi_top_clk.common,
+       &csi0_mclk_clk.common,
+       &csi1_mclk_clk.common,
+       &bus_csi_clk.common,
+       &csi_isp_clk.common,
+};
+
+static struct clk_hw_onecell_data sun50i_a100_hw_clks = {
+       .hws    = {
+               [CLK_OSC12M]            = &osc12M_clk.hw,
+               [CLK_PLL_CPUX]          = &pll_cpux_clk.common.hw,
+               [CLK_PLL_DDR0]          = &pll_ddr0_clk.common.hw,
+               [CLK_PLL_PERIPH0]       = &pll_periph0_clk.common.hw,
+               [CLK_PLL_PERIPH0_2X]    = &pll_periph0_2x_clk.hw,
+               [CLK_PLL_PERIPH1]       = &pll_periph1_clk.common.hw,
+               [CLK_PLL_PERIPH1_2X]    = &pll_periph1_2x_clk.hw,
+               [CLK_PLL_GPU]           = &pll_gpu_clk.common.hw,
+               [CLK_PLL_VIDEO0]        = &pll_video0_clk.common.hw,
+               [CLK_PLL_VIDEO0_2X]     = &pll_video0_2x_clk.hw,
+               [CLK_PLL_VIDEO0_4X]     = &pll_video0_4x_clk.hw,
+               [CLK_PLL_VIDEO1]        = &pll_video1_clk.common.hw,
+               [CLK_PLL_VIDEO1_2X]     = &pll_video1_2x_clk.hw,
+               [CLK_PLL_VIDEO1_4X]     = &pll_video1_4x_clk.hw,
+               [CLK_PLL_VIDEO2]        = &pll_video2_clk.common.hw,
+               [CLK_PLL_VIDEO2_2X]     = &pll_video2_2x_clk.hw,
+               [CLK_PLL_VIDEO2_4X]     = &pll_video2_4x_clk.hw,
+               [CLK_PLL_VIDEO3]        = &pll_video3_clk.common.hw,
+               [CLK_PLL_VIDEO3_2X]     = &pll_video3_2x_clk.hw,
+               [CLK_PLL_VIDEO3_4X]     = &pll_video3_4x_clk.hw,
+               [CLK_PLL_VE]            = &pll_ve_clk.common.hw,
+               [CLK_PLL_COM]           = &pll_com_clk.common.hw,
+               [CLK_PLL_COM_AUDIO]     = &pll_com_audio_clk.hw,
+               [CLK_PLL_AUDIO]         = &pll_audio_clk.common.hw,
+               [CLK_CPUX]              = &cpux_clk.common.hw,
+               [CLK_AXI]               = &axi_clk.common.hw,
+               [CLK_CPUX_APB]          = &cpux_apb_clk.common.hw,
+               [CLK_PSI_AHB1_AHB2]     = &psi_ahb1_ahb2_clk.common.hw,
+               [CLK_AHB3]              = &ahb3_clk.common.hw,
+               [CLK_APB1]              = &apb1_clk.common.hw,
+               [CLK_APB2]              = &apb2_clk.common.hw,
+               [CLK_MBUS]              = &mbus_clk.common.hw,
+               [CLK_DE]                = &de_clk.common.hw,
+               [CLK_BUS_DE]            = &bus_de_clk.common.hw,
+               [CLK_G2D]               = &g2d_clk.common.hw,
+               [CLK_BUS_G2D]           = &bus_g2d_clk.common.hw,
+               [CLK_GPU]               = &gpu_clk.common.hw,
+               [CLK_BUS_GPU]           = &bus_gpu_clk.common.hw,
+               [CLK_CE]                = &ce_clk.common.hw,
+               [CLK_BUS_CE]            = &bus_ce_clk.common.hw,
+               [CLK_VE]                = &ve_clk.common.hw,
+               [CLK_BUS_VE]            = &bus_ve_clk.common.hw,
+               [CLK_BUS_DMA]           = &bus_dma_clk.common.hw,
+               [CLK_BUS_MSGBOX]        = &bus_msgbox_clk.common.hw,
+               [CLK_BUS_SPINLOCK]      = &bus_spinlock_clk.common.hw,
+               [CLK_BUS_HSTIMER]       = &bus_hstimer_clk.common.hw,
+               [CLK_AVS]               = &avs_clk.common.hw,
+               [CLK_BUS_DBG]           = &bus_dbg_clk.common.hw,
+               [CLK_BUS_PSI]           = &bus_psi_clk.common.hw,
+               [CLK_BUS_PWM]           = &bus_pwm_clk.common.hw,
+               [CLK_BUS_IOMMU]         = &bus_iommu_clk.common.hw,
+               [CLK_MBUS_DMA]          = &mbus_dma_clk.common.hw,
+               [CLK_MBUS_VE]           = &mbus_ve_clk.common.hw,
+               [CLK_MBUS_CE]           = &mbus_ce_clk.common.hw,
+               [CLK_MBUS_NAND]         = &mbus_nand_clk.common.hw,
+               [CLK_MBUS_CSI]          = &mbus_csi_clk.common.hw,
+               [CLK_MBUS_ISP]          = &mbus_isp_clk.common.hw,
+               [CLK_MBUS_G2D]          = &mbus_g2d_clk.common.hw,
+               [CLK_BUS_DRAM]          = &bus_dram_clk.common.hw,
+               [CLK_NAND0]             = &nand0_clk.common.hw,
+               [CLK_NAND1]             = &nand1_clk.common.hw,
+               [CLK_BUS_NAND]          = &bus_nand_clk.common.hw,
+               [CLK_MMC0]              = &mmc0_clk.common.hw,
+               [CLK_MMC1]              = &mmc1_clk.common.hw,
+               [CLK_MMC2]              = &mmc2_clk.common.hw,
+               [CLK_BUS_MMC0]          = &bus_mmc0_clk.common.hw,
+               [CLK_BUS_MMC1]          = &bus_mmc1_clk.common.hw,
+               [CLK_BUS_MMC2]          = &bus_mmc2_clk.common.hw,
+               [CLK_BUS_UART0]         = &bus_uart0_clk.common.hw,
+               [CLK_BUS_UART1]         = &bus_uart1_clk.common.hw,
+               [CLK_BUS_UART2]         = &bus_uart2_clk.common.hw,
+               [CLK_BUS_UART3]         = &bus_uart3_clk.common.hw,
+               [CLK_BUS_UART4]         = &bus_uart4_clk.common.hw,
+               [CLK_BUS_I2C0]          = &bus_i2c0_clk.common.hw,
+               [CLK_BUS_I2C1]          = &bus_i2c1_clk.common.hw,
+               [CLK_BUS_I2C2]          = &bus_i2c2_clk.common.hw,
+               [CLK_BUS_I2C3]          = &bus_i2c3_clk.common.hw,
+               [CLK_SPI0]              = &spi0_clk.common.hw,
+               [CLK_SPI1]              = &spi1_clk.common.hw,
+               [CLK_SPI2]              = &spi2_clk.common.hw,
+               [CLK_BUS_SPI0]          = &bus_spi0_clk.common.hw,
+               [CLK_BUS_SPI1]          = &bus_spi1_clk.common.hw,
+               [CLK_BUS_SPI2]          = &bus_spi2_clk.common.hw,
+               [CLK_EMAC_25M]          = &emac_25m_clk.common.hw,
+               [CLK_BUS_EMAC]          = &bus_emac_clk.common.hw,
+               [CLK_IR_RX]             = &ir_rx_clk.common.hw,
+               [CLK_BUS_IR_RX]         = &bus_ir_rx_clk.common.hw,
+               [CLK_IR_TX]             = &ir_tx_clk.common.hw,
+               [CLK_BUS_IR_TX]         = &bus_ir_tx_clk.common.hw,
+               [CLK_BUS_GPADC]         = &bus_gpadc_clk.common.hw,
+               [CLK_BUS_THS]           = &bus_ths_clk.common.hw,
+               [CLK_I2S0]              = &i2s0_clk.common.hw,
+               [CLK_I2S1]              = &i2s1_clk.common.hw,
+               [CLK_I2S2]              = &i2s2_clk.common.hw,
+               [CLK_I2S3]              = &i2s3_clk.common.hw,
+               [CLK_BUS_I2S0]          = &bus_i2s0_clk.common.hw,
+               [CLK_BUS_I2S1]          = &bus_i2s1_clk.common.hw,
+               [CLK_BUS_I2S2]          = &bus_i2s2_clk.common.hw,
+               [CLK_BUS_I2S3]          = &bus_i2s3_clk.common.hw,
+               [CLK_SPDIF]             = &spdif_clk.common.hw,
+               [CLK_BUS_SPDIF]         = &bus_spdif_clk.common.hw,
+               [CLK_DMIC]              = &dmic_clk.common.hw,
+               [CLK_BUS_DMIC]          = &bus_dmic_clk.common.hw,
+               [CLK_AUDIO_DAC]         = &audio_codec_dac_clk.common.hw,
+               [CLK_AUDIO_ADC]         = &audio_codec_adc_clk.common.hw,
+               [CLK_AUDIO_4X]          = &audio_codec_4x_clk.common.hw,
+               [CLK_BUS_AUDIO_CODEC]   = &bus_audio_codec_clk.common.hw,
+               [CLK_USB_OHCI0]         = &usb_ohci0_clk.common.hw,
+               [CLK_USB_PHY0]          = &usb_phy0_clk.common.hw,
+               [CLK_USB_OHCI1]         = &usb_ohci1_clk.common.hw,
+               [CLK_USB_PHY1]          = &usb_phy1_clk.common.hw,
+               [CLK_BUS_OHCI0]         = &bus_ohci0_clk.common.hw,
+               [CLK_BUS_OHCI1]         = &bus_ohci1_clk.common.hw,
+               [CLK_BUS_EHCI0]         = &bus_ehci0_clk.common.hw,
+               [CLK_BUS_EHCI1]         = &bus_ehci1_clk.common.hw,
+               [CLK_BUS_OTG]           = &bus_otg_clk.common.hw,
+               [CLK_BUS_LRADC]         = &bus_lradc_clk.common.hw,
+               [CLK_BUS_DPSS_TOP0]     = &bus_dpss_top0_clk.common.hw,
+               [CLK_BUS_DPSS_TOP1]     = &bus_dpss_top1_clk.common.hw,
+               [CLK_MIPI_DSI]          = &mipi_dsi_clk.common.hw,
+               [CLK_BUS_MIPI_DSI]      = &bus_mipi_dsi_clk.common.hw,
+               [CLK_TCON_LCD]          = &tcon_lcd_clk.common.hw,
+               [CLK_BUS_TCON_LCD]      = &bus_tcon_lcd_clk.common.hw,
+               [CLK_LEDC]              = &ledc_clk.common.hw,
+               [CLK_BUS_LEDC]          = &bus_ledc_clk.common.hw,
+               [CLK_CSI_TOP]           = &csi_top_clk.common.hw,
+               [CLK_CSI0_MCLK]         = &csi0_mclk_clk.common.hw,
+               [CLK_CSI1_MCLK]         = &csi1_mclk_clk.common.hw,
+               [CLK_BUS_CSI]           = &bus_csi_clk.common.hw,
+               [CLK_CSI_ISP]           = &csi_isp_clk.common.hw,
+       },
+       .num = CLK_NUMBER,
+};
+
+static struct ccu_reset_map sun50i_a100_ccu_resets[] = {
+       [RST_MBUS]              = { 0x540, BIT(30) },
+
+       [RST_BUS_DE]            = { 0x60c, BIT(16) },
+       [RST_BUS_G2D]           = { 0x63c, BIT(16) },
+       [RST_BUS_GPU]           = { 0x67c, BIT(16) },
+       [RST_BUS_CE]            = { 0x68c, BIT(16) },
+       [RST_BUS_VE]            = { 0x69c, BIT(16) },
+       [RST_BUS_DMA]           = { 0x70c, BIT(16) },
+       [RST_BUS_MSGBOX]        = { 0x71c, BIT(16) },
+       [RST_BUS_SPINLOCK]      = { 0x72c, BIT(16) },
+       [RST_BUS_HSTIMER]       = { 0x73c, BIT(16) },
+       [RST_BUS_DBG]           = { 0x78c, BIT(16) },
+       [RST_BUS_PSI]           = { 0x79c, BIT(16) },
+       [RST_BUS_PWM]           = { 0x7ac, BIT(16) },
+       [RST_BUS_DRAM]          = { 0x80c, BIT(16) },
+       [RST_BUS_NAND]          = { 0x82c, BIT(16) },
+       [RST_BUS_MMC0]          = { 0x84c, BIT(16) },
+       [RST_BUS_MMC1]          = { 0x84c, BIT(17) },
+       [RST_BUS_MMC2]          = { 0x84c, BIT(18) },
+       [RST_BUS_UART0]         = { 0x90c, BIT(16) },
+       [RST_BUS_UART1]         = { 0x90c, BIT(17) },
+       [RST_BUS_UART2]         = { 0x90c, BIT(18) },
+       [RST_BUS_UART3]         = { 0x90c, BIT(19) },
+       [RST_BUS_UART4]         = { 0x90c, BIT(20) },
+       [RST_BUS_I2C0]          = { 0x91c, BIT(16) },
+       [RST_BUS_I2C1]          = { 0x91c, BIT(17) },
+       [RST_BUS_I2C2]          = { 0x91c, BIT(18) },
+       [RST_BUS_I2C3]          = { 0x91c, BIT(19) },
+       [RST_BUS_SPI0]          = { 0x96c, BIT(16) },
+       [RST_BUS_SPI1]          = { 0x96c, BIT(17) },
+       [RST_BUS_SPI2]          = { 0x96c, BIT(18) },
+       [RST_BUS_EMAC]          = { 0x97c, BIT(16) },
+       [RST_BUS_IR_RX]         = { 0x99c, BIT(16) },
+       [RST_BUS_IR_TX]         = { 0x9cc, BIT(16) },
+       [RST_BUS_GPADC]         = { 0x9ec, BIT(16) },
+       [RST_BUS_THS]           = { 0x9fc, BIT(16) },
+       [RST_BUS_I2S0]          = { 0xa20, BIT(16) },
+       [RST_BUS_I2S1]          = { 0xa20, BIT(17) },
+       [RST_BUS_I2S2]          = { 0xa20, BIT(18) },
+       [RST_BUS_I2S3]          = { 0xa20, BIT(19) },
+       [RST_BUS_SPDIF]         = { 0xa2c, BIT(16) },
+       [RST_BUS_DMIC]          = { 0xa4c, BIT(16) },
+       [RST_BUS_AUDIO_CODEC]   = { 0xa5c, BIT(16) },
+
+       [RST_USB_PHY0]          = { 0xa70, BIT(30) },
+       [RST_USB_PHY1]          = { 0xa74, BIT(30) },
+
+       [RST_BUS_OHCI0]         = { 0xa8c, BIT(16) },
+       [RST_BUS_OHCI1]         = { 0xa8c, BIT(17) },
+       [RST_BUS_EHCI0]         = { 0xa8c, BIT(20) },
+       [RST_BUS_EHCI1]         = { 0xa8c, BIT(21) },
+       [RST_BUS_OTG]           = { 0xa8c, BIT(24) },
+
+       [RST_BUS_LRADC]         = { 0xa9c, BIT(16) },
+       [RST_BUS_DPSS_TOP0]     = { 0xabc, BIT(16) },
+       [RST_BUS_DPSS_TOP1]     = { 0xacc, BIT(16) },
+       [RST_BUS_MIPI_DSI]      = { 0xb4c, BIT(16) },
+       [RST_BUS_TCON_LCD]      = { 0xb7c, BIT(16) },
+       [RST_BUS_LVDS]          = { 0xbac, BIT(16) },
+       [RST_BUS_LEDC]          = { 0xbfc, BIT(16) },
+       [RST_BUS_CSI]           = { 0xc1c, BIT(16) },
+       [RST_BUS_CSI_ISP]       = { 0xc2c, BIT(16) },
+};
+
+static const struct sunxi_ccu_desc sun50i_a100_ccu_desc = {
+       .ccu_clks       = sun50i_a100_ccu_clks,
+       .num_ccu_clks   = ARRAY_SIZE(sun50i_a100_ccu_clks),
+
+       .hw_clks        = &sun50i_a100_hw_clks,
+
+       .resets         = sun50i_a100_ccu_resets,
+       .num_resets     = ARRAY_SIZE(sun50i_a100_ccu_resets),
+};
+
+static const u32 sun50i_a100_pll_regs[] = {
+       SUN50I_A100_PLL_CPUX_REG,
+       SUN50I_A100_PLL_DDR0_REG,
+       SUN50I_A100_PLL_PERIPH0_REG,
+       SUN50I_A100_PLL_PERIPH1_REG,
+       SUN50I_A100_PLL_GPU_REG,
+       SUN50I_A100_PLL_VIDEO0_REG,
+       SUN50I_A100_PLL_VIDEO1_REG,
+       SUN50I_A100_PLL_VIDEO2_REG,
+       SUN50I_A100_PLL_VIDEO3_REG,
+       SUN50I_A100_PLL_VE_REG,
+       SUN50I_A100_PLL_COM_REG,
+       SUN50I_A100_PLL_AUDIO_REG,
+};
+
+static const u32 sun50i_a100_pll_video_regs[] = {
+       SUN50I_A100_PLL_VIDEO0_REG,
+       SUN50I_A100_PLL_VIDEO1_REG,
+       SUN50I_A100_PLL_VIDEO2_REG,
+       SUN50I_A100_PLL_VIDEO3_REG,
+};
+
+static const u32 sun50i_a100_usb2_clk_regs[] = {
+       SUN50I_A100_USB0_CLK_REG,
+       SUN50I_A100_USB1_CLK_REG,
+};
+
+static struct ccu_pll_nb sun50i_a100_pll_cpu_nb = {
+       .common = &pll_cpux_clk.common,
+       /* copy from pll_cpux_clk */
+       .enable = BIT(27),
+       .lock   = BIT(28),
+};
+
+static struct ccu_mux_nb sun50i_a100_cpu_nb = {
+       .common         = &cpux_clk.common,
+       .cm             = &cpux_clk.mux,
+       .delay_us       = 1,
+       .bypass_index   = 4, /* index of pll periph0 */
+};
+
+static int sun50i_a100_ccu_probe(struct platform_device *pdev)
+{
+       void __iomem *reg;
+       u32 val;
+       int i, ret;
+
+       reg = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(reg))
+               return PTR_ERR(reg);
+
+       /*
+        * Enable lock and enable bits on all PLLs.
+        *
+        * Due to the current design, multiple PLLs share one power switch,
+        * so switching PLL is easy to cause stability problems.
+        * When initializing, we enable them by default. When disable,
+        * we only turn off the output of PLL.
+        */
+       for (i = 0; i < ARRAY_SIZE(sun50i_a100_pll_regs); i++) {
+               val = readl(reg + sun50i_a100_pll_regs[i]);
+               val |= SUN50I_A100_PLL_LOCK_ENABLE | SUN50I_A100_PLL_ENABLE;
+               writel(val, reg + sun50i_a100_pll_regs[i]);
+       }
+
+       /*
+        * In order to pass the EMI certification, the SDM function of
+        * the peripheral 1 bus is enabled, and the frequency is still
+        * calculated using the previous division factor.
+        */
+       writel(SUN50I_A100_PLL_PERIPH1_PATTERN0,
+              reg + SUN50I_A100_PLL_PERIPH1_PATTERN0_REG);
+
+       val = readl(reg + SUN50I_A100_PLL_PERIPH1_REG);
+       val |= SUN50I_A100_PLL_SDM_ENABLE;
+       writel(val, reg + SUN50I_A100_PLL_PERIPH1_REG);
+
+       /*
+        * Force the output divider of video PLLs to 0.
+        *
+        * See the comment before pll-video0 definition for the reason.
+        */
+       for (i = 0; i < ARRAY_SIZE(sun50i_a100_pll_video_regs); i++) {
+               val = readl(reg + sun50i_a100_pll_video_regs[i]);
+               val &= ~BIT(0);
+               writel(val, reg + sun50i_a100_pll_video_regs[i]);
+       }
+
+       /*
+        * Enforce m1 = 0, m0 = 1 for Audio PLL
+        *
+        * See the comment before pll-audio definition for the reason.
+        */
+       val = readl(reg + SUN50I_A100_PLL_AUDIO_REG);
+       val &= ~BIT(1);
+       val |= BIT(0);
+       writel(val, reg + SUN50I_A100_PLL_AUDIO_REG);
+
+       /*
+        * Force OHCI 12M clock sources to 00 (12MHz divided from 48MHz)
+        *
+        * This clock mux is still mysterious, and the code just enforces
+        * it to have a valid clock parent.
+        */
+       for (i = 0; i < ARRAY_SIZE(sun50i_a100_usb2_clk_regs); i++) {
+               val = readl(reg + sun50i_a100_usb2_clk_regs[i]);
+               val &= ~GENMASK(25, 24);
+               writel(val, reg + sun50i_a100_usb2_clk_regs[i]);
+       }
+
+       ret = sunxi_ccu_probe(pdev->dev.of_node, reg, &sun50i_a100_ccu_desc);
+       if (ret)
+               return ret;
+
+       /* Gate then ungate PLL CPU after any rate changes */
+       ccu_pll_notifier_register(&sun50i_a100_pll_cpu_nb);
+
+       /* Reparent CPU during PLL CPU rate changes */
+       ccu_mux_notifier_register(pll_cpux_clk.common.hw.clk,
+                                 &sun50i_a100_cpu_nb);
+
+       return 0;
+}
+
+static const struct of_device_id sun50i_a100_ccu_ids[] = {
+       { .compatible = "allwinner,sun50i-a100-ccu" },
+       { }
+};
+
+static struct platform_driver sun50i_a100_ccu_driver = {
+       .probe  = sun50i_a100_ccu_probe,
+       .driver = {
+               .name   = "sun50i-a100-ccu",
+               .of_match_table = sun50i_a100_ccu_ids,
+       },
+};
+module_platform_driver(sun50i_a100_ccu_driver);
diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a100.h b/drivers/clk/sunxi-ng/ccu-sun50i-a100.h
new file mode 100644 (file)
index 0000000..21ce92b
--- /dev/null
@@ -0,0 +1,56 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2020 Yangtao Li <frank@allwinnertech.com>
+ */
+
+#ifndef _CCU_SUN50I_A100_H_
+#define _CCU_SUN50I_A100_H_
+
+#include <dt-bindings/clock/sun50i-a100-ccu.h>
+#include <dt-bindings/reset/sun50i-a100-ccu.h>
+
+#define CLK_OSC12M             0
+#define CLK_PLL_CPUX           1
+#define CLK_PLL_DDR0           2
+
+/* PLL_PERIPH0 exported for PRCM */
+
+#define CLK_PLL_PERIPH0_2X     4
+#define CLK_PLL_PERIPH1                5
+#define CLK_PLL_PERIPH1_2X     6
+#define CLK_PLL_GPU            7
+#define CLK_PLL_VIDEO0         8
+#define CLK_PLL_VIDEO0_2X      9
+#define CLK_PLL_VIDEO0_4X      10
+#define CLK_PLL_VIDEO1         11
+#define CLK_PLL_VIDEO1_2X      12
+#define CLK_PLL_VIDEO1_4X      13
+#define CLK_PLL_VIDEO2         14
+#define CLK_PLL_VIDEO2_2X      15
+#define CLK_PLL_VIDEO2_4X      16
+#define CLK_PLL_VIDEO3         17
+#define CLK_PLL_VIDEO3_2X      18
+#define CLK_PLL_VIDEO3_4X      19
+#define CLK_PLL_VE             20
+#define CLK_PLL_COM            21
+#define CLK_PLL_COM_AUDIO      22
+#define CLK_PLL_AUDIO          23
+
+/* CPUX clock exported for DVFS */
+
+#define CLK_AXI                        25
+#define CLK_CPUX_APB           26
+#define CLK_PSI_AHB1_AHB2      27
+#define CLK_AHB3               28
+
+/* APB1 clock exported for PIO */
+
+#define CLK_APB2               30
+
+/* All module clocks and bus gates are exported except DRAM */
+
+#define CLK_BUS_DRAM           58
+
+#define CLK_NUMBER             (CLK_CSI_ISP + 1)
+
+#endif /* _CCU_SUN50I_A100_H_ */
index 23bfe1d..8415341 100644 (file)
@@ -45,18 +45,29 @@ static struct ccu_nkmp pll_cpu_clk = {
  * the base (2x, 4x and 8x), and one variable divider (the one true
  * pll audio).
  *
- * We don't have any need for the variable divider for now, so we just
- * hardcode it to match with the clock names
+ * With sigma-delta modulation for fractional-N on the audio PLL,
+ * we have to use specific dividers. This means the variable divider
+ * can no longer be used, as the audio codec requests the exact clock
+ * rates we support through this mechanism. So we now hard code the
+ * variable divider to 1. This means the clock rates will no longer
+ * match the clock names.
  */
 #define SUN8I_R40_PLL_AUDIO_REG        0x008
 
-static SUNXI_CCU_NM_WITH_GATE_LOCK(pll_audio_base_clk, "pll-audio-base",
-                                  "osc24M", 0x008,
-                                  8, 7,        /* N */
-                                  0, 5,        /* M */
-                                  BIT(31),     /* gate */
-                                  BIT(28),     /* lock */
-                                  CLK_SET_RATE_UNGATE);
+static struct ccu_sdm_setting pll_audio_sdm_table[] = {
+       { .rate = 22579200, .pattern = 0xc0010d84, .m = 8, .n = 7 },
+       { .rate = 24576000, .pattern = 0xc000ac02, .m = 14, .n = 14 },
+};
+
+static SUNXI_CCU_NM_WITH_SDM_GATE_LOCK(pll_audio_base_clk, "pll-audio-base",
+                                      "osc24M", 0x008,
+                                      8, 7,    /* N */
+                                      0, 5,    /* M */
+                                      pll_audio_sdm_table, BIT(24),
+                                      0x284, BIT(31),
+                                      BIT(31), /* gate */
+                                      BIT(28), /* lock */
+                                      CLK_SET_RATE_UNGATE);
 
 static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX(pll_video0_clk, "pll-video0",
                                                "osc24M", 0x0010,
@@ -952,10 +963,10 @@ static const struct clk_hw *clk_parent_pll_audio[] = {
        &pll_audio_base_clk.common.hw
 };
 
-/* We hardcode the divider to 4 for now */
+/* We hardcode the divider to 1 for now */
 static CLK_FIXED_FACTOR_HWS(pll_audio_clk, "pll-audio",
                            clk_parent_pll_audio,
-                           4, 1, CLK_SET_RATE_PARENT);
+                           1, 1, CLK_SET_RATE_PARENT);
 static CLK_FIXED_FACTOR_HWS(pll_audio_2x_clk, "pll-audio-2x",
                            clk_parent_pll_audio,
                            2, 1, CLK_SET_RATE_PARENT);
@@ -1307,10 +1318,10 @@ static int sun8i_r40_ccu_probe(struct platform_device *pdev)
        if (IS_ERR(reg))
                return PTR_ERR(reg);
 
-       /* Force the PLL-Audio-1x divider to 4 */
+       /* Force the PLL-Audio-1x divider to 1 */
        val = readl(reg + SUN8I_R40_PLL_AUDIO_REG);
        val &= ~GENMASK(19, 16);
-       writel(val | (3 << 16), reg + SUN8I_R40_PLL_AUDIO_REG);
+       writel(val | (0 << 16), reg + SUN8I_R40_PLL_AUDIO_REG);
 
        /* Force PLL-MIPI to MIPI mode */
        val = readl(reg + SUN8I_R40_PLL_MIPI_REG);
index 352a2c3..971c919 100644 (file)
@@ -126,7 +126,7 @@ static int tegra210_clk_emc_set_rate(struct clk_hw *hw, unsigned long rate,
        unsigned int i;
        int err;
 
-       if (!provider || !provider->configs || provider->num_configs == 0)
+       if (!provider->configs || provider->num_configs == 0)
                return -EINVAL;
 
        for (i = 0; i < provider->num_configs; i++) {
index 1cae226..f6f8a40 100644 (file)
@@ -82,7 +82,12 @@ static int _omap2_clk_allow_idle(struct clk_hw_omap *clk)
  */
 int omap2_clk_deny_idle(struct clk *clk)
 {
-       struct clk_hw *hw = __clk_get_hw(clk);
+       struct clk_hw *hw;
+
+       if (!clk)
+               return -EINVAL;
+
+       hw = __clk_get_hw(clk);
 
        if (omap2_clk_is_hw_omap(hw)) {
                struct clk_hw_omap *c = to_clk_hw_omap(hw);
@@ -101,7 +106,12 @@ int omap2_clk_deny_idle(struct clk *clk)
  */
 int omap2_clk_allow_idle(struct clk *clk)
 {
-       struct clk_hw *hw = __clk_get_hw(clk);
+       struct clk_hw *hw;
+
+       if (!clk)
+               return -EINVAL;
+
+       hw = __clk_get_hw(clk);
 
        if (omap2_clk_is_hw_omap(hw)) {
                struct clk_hw_omap *c = to_clk_hw_omap(hw);
index b4cf578..4e27f88 100644 (file)
@@ -637,6 +637,7 @@ static const struct omap_clkctrl_reg_data dra7_l4sec_clkctrl_regs[] __initconst
        { DRA7_L4SEC_DES_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" },
        { DRA7_L4SEC_RNG_CLKCTRL, NULL, CLKF_HW_SUP | CLKF_SOC_NONSEC, "l4_root_clk_div" },
        { DRA7_L4SEC_SHAM_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" },
+       { DRA7_L4SEC_SHAM2_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" },
        { 0 },
 };
 
index ee56306..700b7f4 100644 (file)
@@ -148,10 +148,12 @@ static void __init of_ti_clockdomain_setup(struct device_node *node)
                if (!omap2_clk_is_hw_omap(clk_hw)) {
                        pr_warn("can't setup clkdm for basic clk %s\n",
                                __clk_get_name(clk));
+                       clk_put(clk);
                        continue;
                }
                to_clk_hw_omap(clk_hw)->clkdm_name = clkdm_name;
                omap2_init_clk_clkdm(clk_hw);
+               clk_put(clk);
        }
 }
 
index 1a33a08..a2f01a4 100644 (file)
@@ -90,7 +90,7 @@ struct clk_hw *uniphier_clk_register_cpugear(struct device *dev,
        init.ops = &uniphier_clk_cpugear_ops;
        init.flags = CLK_SET_RATE_PARENT;
        init.parent_names = data->parent_names;
-       init.num_parents = data->num_parents,
+       init.num_parents = data->num_parents;
 
        gear->regmap = regmap;
        gear->regbase = data->regbase;
index c0f4631..462c843 100644 (file)
@@ -70,7 +70,7 @@ struct clk_hw *uniphier_clk_register_mux(struct device *dev,
        init.ops = &uniphier_clk_mux_ops;
        init.flags = CLK_SET_RATE_PARENT;
        init.parent_names = data->parent_names;
-       init.num_parents = data->num_parents,
+       init.num_parents = data->num_parents;
 
        mux->regmap = regmap;
        mux->reg = data->reg;
index 8cec5a1..5ec4137 100644 (file)
 #define DRA7_L4SEC_DES_CLKCTRL DRA7_L4SEC_CLKCTRL_INDEX(0x1b0)
 #define DRA7_L4SEC_RNG_CLKCTRL DRA7_L4SEC_CLKCTRL_INDEX(0x1c0)
 #define DRA7_L4SEC_SHAM_CLKCTRL        DRA7_L4SEC_CLKCTRL_INDEX(0x1c8)
+#define DRA7_L4SEC_SHAM2_CLKCTRL DRA7_L4SEC_CLKCTRL_INDEX(0x1f8)
 
 /* l4per2 clocks */
 #define DRA7_L4PER2_CLKCTRL_OFFSET     0xc
index bc8a3c5..e259cc0 100644 (file)
 #define CLK_MOUT_GPLL          1025
 #define CLK_MOUT_ACLK200_DISP1_SUB     1026
 #define CLK_MOUT_ACLK300_DISP1_SUB     1027
+#define CLK_MOUT_APLL          1028
+#define CLK_MOUT_MPLL          1029
 
 /* must be greater than maximal clock id */
-#define CLK_NR_CLKS            1028
+#define CLK_NR_CLKS            1030
 
 #endif /* _DT_BINDINGS_CLOCK_EXYNOS_5250_H */
index 02d5ac4..9fffc6c 100644 (file)
 #define CLK_MOUT_USER_MAU_EPLL 659
 #define CLK_MOUT_SCLK_SPLL     660
 #define CLK_MOUT_MX_MSPLL_CCORE_PHY    661
+#define CLK_MOUT_SW_ACLK_G3D   662
+#define CLK_MOUT_APLL          663
+#define CLK_MOUT_MSPLL_CPU     664
+#define CLK_MOUT_KPLL          665
+#define CLK_MOUT_MSPLL_KFC     666
+
 
 /* divider clocks */
 #define CLK_DOUT_PIXEL         768
index 7a23f28..e8d68fb 100644 (file)
 #define IMX8MP_CLK_MEDIA_MIPI_PHY1_REF         171
 #define IMX8MP_CLK_MEDIA_DISP1_PIX             172
 #define IMX8MP_CLK_MEDIA_CAM2_PIX              173
-#define IMX8MP_CLK_MEDIA_MIPI_PHY2_REF         174
+#define IMX8MP_CLK_MEDIA_LDB                   174
 #define IMX8MP_CLK_MEDIA_MIPI_CSI2_ESC         175
 #define IMX8MP_CLK_PCIE2_CTRL                  176
 #define IMX8MP_CLK_PCIE2_PHY                   177
diff --git a/include/dt-bindings/clock/mt8167-clk.h b/include/dt-bindings/clock/mt8167-clk.h
new file mode 100644 (file)
index 0000000..a96158e
--- /dev/null
@@ -0,0 +1,131 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2020 MediaTek Inc.
+ * Copyright (c) 2020 BayLibre, SAS.
+ * Author: James Liao <jamesjj.liao@mediatek.com>
+ *         Fabien Parent <fparent@baylibre.com>
+ */
+
+#ifndef _DT_BINDINGS_CLK_MT8167_H
+#define _DT_BINDINGS_CLK_MT8167_H
+
+/* MT8167 is based on MT8516 */
+#include <dt-bindings/clock/mt8516-clk.h>
+
+/* APMIXEDSYS */
+
+#define CLK_APMIXED_TVDPLL             (CLK_APMIXED_NR_CLK + 0)
+#define CLK_APMIXED_LVDSPLL            (CLK_APMIXED_NR_CLK + 1)
+#define CLK_APMIXED_HDMI_REF           (CLK_APMIXED_NR_CLK + 2)
+#define MT8167_CLK_APMIXED_NR_CLK      (CLK_APMIXED_NR_CLK + 3)
+
+/* TOPCKGEN */
+
+#define CLK_TOP_DSI0_LNTC_DSICK                (CLK_TOP_NR_CLK + 0)
+#define CLK_TOP_VPLL_DPIX              (CLK_TOP_NR_CLK + 1)
+#define CLK_TOP_LVDSTX_CLKDIG_CTS      (CLK_TOP_NR_CLK + 2)
+#define CLK_TOP_HDMTX_CLKDIG_CTS       (CLK_TOP_NR_CLK + 3)
+#define CLK_TOP_LVDSPLL                        (CLK_TOP_NR_CLK + 4)
+#define CLK_TOP_LVDSPLL_D2             (CLK_TOP_NR_CLK + 5)
+#define CLK_TOP_LVDSPLL_D4             (CLK_TOP_NR_CLK + 6)
+#define CLK_TOP_LVDSPLL_D8             (CLK_TOP_NR_CLK + 7)
+#define CLK_TOP_MIPI_26M               (CLK_TOP_NR_CLK + 8)
+#define CLK_TOP_TVDPLL                 (CLK_TOP_NR_CLK + 9)
+#define CLK_TOP_TVDPLL_D2              (CLK_TOP_NR_CLK + 10)
+#define CLK_TOP_TVDPLL_D4              (CLK_TOP_NR_CLK + 11)
+#define CLK_TOP_TVDPLL_D8              (CLK_TOP_NR_CLK + 12)
+#define CLK_TOP_TVDPLL_D16             (CLK_TOP_NR_CLK + 13)
+#define CLK_TOP_PWM_MM                 (CLK_TOP_NR_CLK + 14)
+#define CLK_TOP_CAM_MM                 (CLK_TOP_NR_CLK + 15)
+#define CLK_TOP_MFG_MM                 (CLK_TOP_NR_CLK + 16)
+#define CLK_TOP_SPM_52M                        (CLK_TOP_NR_CLK + 17)
+#define CLK_TOP_MIPI_26M_DBG           (CLK_TOP_NR_CLK + 18)
+#define CLK_TOP_SCAM_MM                        (CLK_TOP_NR_CLK + 19)
+#define CLK_TOP_SMI_MM                 (CLK_TOP_NR_CLK + 20)
+#define CLK_TOP_26M_HDMI_SIFM          (CLK_TOP_NR_CLK + 21)
+#define CLK_TOP_26M_CEC                        (CLK_TOP_NR_CLK + 22)
+#define CLK_TOP_32K_CEC                        (CLK_TOP_NR_CLK + 23)
+#define CLK_TOP_GCPU_B                 (CLK_TOP_NR_CLK + 24)
+#define CLK_TOP_RG_VDEC                        (CLK_TOP_NR_CLK + 25)
+#define CLK_TOP_RG_FDPI0               (CLK_TOP_NR_CLK + 26)
+#define CLK_TOP_RG_FDPI1               (CLK_TOP_NR_CLK + 27)
+#define CLK_TOP_RG_AXI_MFG             (CLK_TOP_NR_CLK + 28)
+#define CLK_TOP_RG_SLOW_MFG            (CLK_TOP_NR_CLK + 29)
+#define CLK_TOP_GFMUX_EMI1X_SEL                (CLK_TOP_NR_CLK + 30)
+#define CLK_TOP_CSW_MUX_MFG_SEL                (CLK_TOP_NR_CLK + 31)
+#define CLK_TOP_CAMTG_MM_SEL           (CLK_TOP_NR_CLK + 32)
+#define CLK_TOP_PWM_MM_SEL             (CLK_TOP_NR_CLK + 33)
+#define CLK_TOP_SPM_52M_SEL            (CLK_TOP_NR_CLK + 34)
+#define CLK_TOP_MFG_MM_SEL             (CLK_TOP_NR_CLK + 35)
+#define CLK_TOP_SMI_MM_SEL             (CLK_TOP_NR_CLK + 36)
+#define CLK_TOP_SCAM_MM_SEL            (CLK_TOP_NR_CLK + 37)
+#define CLK_TOP_VDEC_MM_SEL            (CLK_TOP_NR_CLK + 38)
+#define CLK_TOP_DPI0_MM_SEL            (CLK_TOP_NR_CLK + 39)
+#define CLK_TOP_DPI1_MM_SEL            (CLK_TOP_NR_CLK + 40)
+#define CLK_TOP_AXI_MFG_IN_SEL         (CLK_TOP_NR_CLK + 41)
+#define CLK_TOP_SLOW_MFG_SEL           (CLK_TOP_NR_CLK + 42)
+#define MT8167_CLK_TOP_NR_CLK          (CLK_TOP_NR_CLK + 43)
+
+/* MFGCFG */
+
+#define CLK_MFG_BAXI                   0
+#define CLK_MFG_BMEM                   1
+#define CLK_MFG_BG3D                   2
+#define CLK_MFG_B26M                   3
+#define CLK_MFG_NR_CLK                 4
+
+/* MMSYS */
+
+#define CLK_MM_SMI_COMMON              0
+#define CLK_MM_SMI_LARB0               1
+#define CLK_MM_CAM_MDP                 2
+#define CLK_MM_MDP_RDMA                        3
+#define CLK_MM_MDP_RSZ0                        4
+#define CLK_MM_MDP_RSZ1                        5
+#define CLK_MM_MDP_TDSHP               6
+#define CLK_MM_MDP_WDMA                        7
+#define CLK_MM_MDP_WROT                        8
+#define CLK_MM_FAKE_ENG                        9
+#define CLK_MM_DISP_OVL0               10
+#define CLK_MM_DISP_RDMA0              11
+#define CLK_MM_DISP_RDMA1              12
+#define CLK_MM_DISP_WDMA               13
+#define CLK_MM_DISP_COLOR              14
+#define CLK_MM_DISP_CCORR              15
+#define CLK_MM_DISP_AAL                        16
+#define CLK_MM_DISP_GAMMA              17
+#define CLK_MM_DISP_DITHER             18
+#define CLK_MM_DISP_UFOE               19
+#define CLK_MM_DISP_PWM_MM             20
+#define CLK_MM_DISP_PWM_26M            21
+#define CLK_MM_DSI_ENGINE              22
+#define CLK_MM_DSI_DIGITAL             23
+#define CLK_MM_DPI0_ENGINE             24
+#define CLK_MM_DPI0_PXL                        25
+#define CLK_MM_LVDS_PXL                        26
+#define CLK_MM_LVDS_CTS                        27
+#define CLK_MM_DPI1_ENGINE             28
+#define CLK_MM_DPI1_PXL                        29
+#define CLK_MM_HDMI_PXL                        30
+#define CLK_MM_HDMI_SPDIF              31
+#define CLK_MM_HDMI_ADSP_BCK           32
+#define CLK_MM_HDMI_PLL                        33
+#define CLK_MM_NR_CLK                  34
+
+/* IMGSYS */
+
+#define CLK_IMG_LARB1_SMI              0
+#define CLK_IMG_CAM_SMI                        1
+#define CLK_IMG_CAM_CAM                        2
+#define CLK_IMG_SEN_TG                 3
+#define CLK_IMG_SEN_CAM                        4
+#define CLK_IMG_VENC                   5
+#define CLK_IMG_NR_CLK                 6
+
+/* VDECSYS */
+
+#define CLK_VDEC_CKEN                  0
+#define CLK_VDEC_LARB1_CKEN            1
+#define CLK_VDEC_NR_CLK                        2
+
+#endif /* _DT_BINDINGS_CLK_MT8167_H */
diff --git a/include/dt-bindings/clock/r8a779a0-cpg-mssr.h b/include/dt-bindings/clock/r8a779a0-cpg-mssr.h
new file mode 100644 (file)
index 0000000..f1d737c
--- /dev/null
@@ -0,0 +1,55 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2020 Renesas Electronics Corp.
+ */
+#ifndef __DT_BINDINGS_CLOCK_R8A779A0_CPG_MSSR_H__
+#define __DT_BINDINGS_CLOCK_R8A779A0_CPG_MSSR_H__
+
+#include <dt-bindings/clock/renesas-cpg-mssr.h>
+
+/* r8a779A0 CPG Core Clocks */
+#define R8A779A0_CLK_Z0                        0
+#define R8A779A0_CLK_ZX                        1
+#define R8A779A0_CLK_Z1                        2
+#define R8A779A0_CLK_ZR                        3
+#define R8A779A0_CLK_ZS                        4
+#define R8A779A0_CLK_ZT                        5
+#define R8A779A0_CLK_ZTR               6
+#define R8A779A0_CLK_S1D1              7
+#define R8A779A0_CLK_S1D2              8
+#define R8A779A0_CLK_S1D4              9
+#define R8A779A0_CLK_S1D8              10
+#define R8A779A0_CLK_S1D12             11
+#define R8A779A0_CLK_S3D1              12
+#define R8A779A0_CLK_S3D2              13
+#define R8A779A0_CLK_S3D4              14
+#define R8A779A0_CLK_LB                        15
+#define R8A779A0_CLK_CP                        16
+#define R8A779A0_CLK_CL                        17
+#define R8A779A0_CLK_CL16MCK           18
+#define R8A779A0_CLK_ZB30              19
+#define R8A779A0_CLK_ZB30D2            20
+#define R8A779A0_CLK_ZB30D4            21
+#define R8A779A0_CLK_ZB31              22
+#define R8A779A0_CLK_ZB31D2            23
+#define R8A779A0_CLK_ZB31D4            24
+#define R8A779A0_CLK_SD0H              25
+#define R8A779A0_CLK_SD0               26
+#define R8A779A0_CLK_RPC               27
+#define R8A779A0_CLK_RPCD2             28
+#define R8A779A0_CLK_MSO               29
+#define R8A779A0_CLK_CANFD             30
+#define R8A779A0_CLK_CSI0              31
+#define R8A779A0_CLK_FRAY              32
+#define R8A779A0_CLK_DSI               33
+#define R8A779A0_CLK_VIP               34
+#define R8A779A0_CLK_ADGH              35
+#define R8A779A0_CLK_CNNDSP            36
+#define R8A779A0_CLK_ICU               37
+#define R8A779A0_CLK_ICUD2             38
+#define R8A779A0_CLK_VCBUS             39
+#define R8A779A0_CLK_CBFUSA            40
+#define R8A779A0_CLK_R                 41
+#define R8A779A0_CLK_OSC               42
+
+#endif /* __DT_BINDINGS_CLOCK_R8A779A0_CPG_MSSR_H__ */
diff --git a/include/dt-bindings/clock/sun50i-a100-ccu.h b/include/dt-bindings/clock/sun50i-a100-ccu.h
new file mode 100644 (file)
index 0000000..28dc36e
--- /dev/null
@@ -0,0 +1,116 @@
+/* SPDX-License-Identifier: (GPL-2.0+ or MIT) */
+/*
+ * Copyright (c) 2020 Yangtao Li <frank@allwinnertech.com>
+ */
+
+#ifndef _DT_BINDINGS_CLK_SUN50I_A100_H_
+#define _DT_BINDINGS_CLK_SUN50I_A100_H_
+
+#define CLK_PLL_PERIPH0                3
+
+#define CLK_CPUX               24
+
+#define CLK_APB1               29
+
+#define CLK_MBUS               31
+#define CLK_DE                 32
+#define CLK_BUS_DE             33
+#define CLK_G2D                        34
+#define CLK_BUS_G2D            35
+#define CLK_GPU                        36
+#define CLK_BUS_GPU            37
+#define CLK_CE                 38
+#define CLK_BUS_CE             39
+#define CLK_VE                 40
+#define CLK_BUS_VE             41
+#define CLK_BUS_DMA            42
+#define CLK_BUS_MSGBOX         43
+#define CLK_BUS_SPINLOCK       44
+#define CLK_BUS_HSTIMER                45
+#define CLK_AVS                        46
+#define CLK_BUS_DBG            47
+#define CLK_BUS_PSI            48
+#define CLK_BUS_PWM            49
+#define CLK_BUS_IOMMU          50
+#define CLK_MBUS_DMA           51
+#define CLK_MBUS_VE            52
+#define CLK_MBUS_CE            53
+#define CLK_MBUS_NAND          54
+#define CLK_MBUS_CSI           55
+#define CLK_MBUS_ISP           56
+#define CLK_MBUS_G2D           57
+
+#define CLK_NAND0              59
+#define CLK_NAND1              60
+#define CLK_BUS_NAND           61
+#define CLK_MMC0               62
+#define CLK_MMC1               63
+#define CLK_MMC2               64
+#define CLK_MMC3               65
+#define CLK_BUS_MMC0           66
+#define CLK_BUS_MMC1           67
+#define CLK_BUS_MMC2           68
+#define CLK_BUS_UART0          69
+#define CLK_BUS_UART1          70
+#define CLK_BUS_UART2          71
+#define CLK_BUS_UART3          72
+#define CLK_BUS_UART4          73
+#define CLK_BUS_I2C0           74
+#define CLK_BUS_I2C1           75
+#define CLK_BUS_I2C2           76
+#define CLK_BUS_I2C3           77
+#define CLK_SPI0               78
+#define CLK_SPI1               79
+#define CLK_SPI2               80
+#define CLK_BUS_SPI0           81
+#define CLK_BUS_SPI1           82
+#define CLK_BUS_SPI2           83
+#define CLK_EMAC_25M           84
+#define CLK_BUS_EMAC           85
+#define CLK_IR_RX              86
+#define CLK_BUS_IR_RX          87
+#define CLK_IR_TX              88
+#define CLK_BUS_IR_TX          89
+#define CLK_BUS_GPADC          90
+#define CLK_BUS_THS            91
+#define CLK_I2S0               92
+#define CLK_I2S1               93
+#define CLK_I2S2               94
+#define CLK_I2S3               95
+#define CLK_BUS_I2S0           96
+#define CLK_BUS_I2S1           97
+#define CLK_BUS_I2S2           98
+#define CLK_BUS_I2S3           99
+#define CLK_SPDIF              100
+#define CLK_BUS_SPDIF          101
+#define CLK_DMIC               102
+#define CLK_BUS_DMIC           103
+#define CLK_AUDIO_DAC          104
+#define CLK_AUDIO_ADC          105
+#define CLK_AUDIO_4X           106
+#define CLK_BUS_AUDIO_CODEC    107
+#define CLK_USB_OHCI0          108
+#define CLK_USB_PHY0           109
+#define CLK_USB_OHCI1          110
+#define CLK_USB_PHY1           111
+#define CLK_BUS_OHCI0          112
+#define CLK_BUS_OHCI1          113
+#define CLK_BUS_EHCI0          114
+#define CLK_BUS_EHCI1          115
+#define CLK_BUS_OTG            116
+#define CLK_BUS_LRADC          117
+#define CLK_BUS_DPSS_TOP0      118
+#define CLK_BUS_DPSS_TOP1      119
+#define CLK_MIPI_DSI           120
+#define CLK_BUS_MIPI_DSI       121
+#define CLK_TCON_LCD           122
+#define CLK_BUS_TCON_LCD       123
+#define CLK_LEDC               124
+#define CLK_BUS_LEDC           125
+#define CLK_CSI_TOP            126
+#define CLK_CSI0_MCLK          127
+#define CLK_CSI1_MCLK          128
+#define CLK_BUS_CSI            129
+#define CLK_CSI_ISP            130
+
+#endif /* _DT_BINDINGS_CLK_SUN50I_A100_H_ */
diff --git a/include/dt-bindings/clock/sun50i-a100-r-ccu.h b/include/dt-bindings/clock/sun50i-a100-r-ccu.h
new file mode 100644 (file)
index 0000000..07312e7
--- /dev/null
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2020 Yangtao Li <frank@allwinnertech.com>
+ */
+
+#ifndef _DT_BINDINGS_CLK_SUN50I_A100_R_CCU_H_
+#define _DT_BINDINGS_CLK_SUN50I_A100_R_CCU_H_
+
+#define CLK_R_APB1             2
+
+#define CLK_R_APB1_TIMER       4
+#define CLK_R_APB1_TWD         5
+#define CLK_R_APB1_PWM         6
+#define CLK_R_APB1_BUS_PWM     7
+#define CLK_R_APB1_PPU         8
+#define CLK_R_APB2_UART                9
+#define CLK_R_APB2_I2C0                10
+#define CLK_R_APB2_I2C1                11
+#define CLK_R_APB1_IR          12
+#define CLK_R_APB1_BUS_IR      13
+#define CLK_R_AHB_BUS_RTC      14
+
+#endif /* _DT_BINDINGS_CLK_SUN50I_A100_R_CCU_H_ */
index 0f2d60e..373644e 100644 (file)
 #define VF610_CLK_TCON0                        187
 #define VF610_CLK_TCON1                        188
 #define VF610_CLK_CAAM                 189
-#define VF610_CLK_END                  190
+#define VF610_CLK_CRC                  190
+#define VF610_CLK_END                  191
 
 #endif /* __DT_BINDINGS_CLOCK_VF610_H */
diff --git a/include/dt-bindings/power/r8a779a0-sysc.h b/include/dt-bindings/power/r8a779a0-sysc.h
new file mode 100644 (file)
index 0000000..57929e4
--- /dev/null
@@ -0,0 +1,59 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2020 Renesas Electronics Corp.
+ */
+#ifndef __DT_BINDINGS_POWER_R8A779A0_SYSC_H__
+#define __DT_BINDINGS_POWER_R8A779A0_SYSC_H__
+
+/*
+ * These power domain indices match the Power Domain Register Numbers (PDR)
+ */
+
+#define R8A779A0_PD_A1E0D0C0           0
+#define R8A779A0_PD_A1E0D0C1           1
+#define R8A779A0_PD_A1E0D1C0           2
+#define R8A779A0_PD_A1E0D1C1           3
+#define R8A779A0_PD_A1E1D0C0           4
+#define R8A779A0_PD_A1E1D0C1           5
+#define R8A779A0_PD_A1E1D1C0           6
+#define R8A779A0_PD_A1E1D1C1           7
+#define R8A779A0_PD_A2E0D0             16
+#define R8A779A0_PD_A2E0D1             17
+#define R8A779A0_PD_A2E1D0             18
+#define R8A779A0_PD_A2E1D1             19
+#define R8A779A0_PD_A3E0               20
+#define R8A779A0_PD_A3E1               21
+#define R8A779A0_PD_3DG_A              24
+#define R8A779A0_PD_3DG_B              25
+#define R8A779A0_PD_A1CNN2             32
+#define R8A779A0_PD_A1DSP0             33
+#define R8A779A0_PD_A2IMP01            34
+#define R8A779A0_PD_A2DP0              35
+#define R8A779A0_PD_A2CV0              36
+#define R8A779A0_PD_A2CV1              37
+#define R8A779A0_PD_A2CV4              38
+#define R8A779A0_PD_A2CV6              39
+#define R8A779A0_PD_A2CN2              40
+#define R8A779A0_PD_A1CNN0             41
+#define R8A779A0_PD_A2CN0              42
+#define R8A779A0_PD_A3IR               43
+#define R8A779A0_PD_A1CNN1             44
+#define R8A779A0_PD_A1DSP1             45
+#define R8A779A0_PD_A2IMP23            46
+#define R8A779A0_PD_A2DP1              47
+#define R8A779A0_PD_A2CV2              48
+#define R8A779A0_PD_A2CV3              49
+#define R8A779A0_PD_A2CV5              50
+#define R8A779A0_PD_A2CV7              51
+#define R8A779A0_PD_A2CN1              52
+#define R8A779A0_PD_A3VIP0             56
+#define R8A779A0_PD_A3VIP1             57
+#define R8A779A0_PD_A3VIP2             58
+#define R8A779A0_PD_A3VIP3             59
+#define R8A779A0_PD_A3ISP01            60
+#define R8A779A0_PD_A3ISP23            61
+
+/* Always-on power area */
+#define R8A779A0_PD_ALWAYS_ON          64
+
+#endif /* __DT_BINDINGS_POWER_R8A779A0_SYSC_H__ */
diff --git a/include/dt-bindings/reset/sun50i-a100-ccu.h b/include/dt-bindings/reset/sun50i-a100-ccu.h
new file mode 100644 (file)
index 0000000..55c0ada
--- /dev/null
@@ -0,0 +1,68 @@
+/* SPDX-License-Identifier: (GPL-2.0+ or MIT) */
+/*
+ * Copyright (c) 2020 Yangtao Li <frank@allwinnertech.com>
+ */
+
+#ifndef _DT_BINDINGS_RESET_SUN50I_A100_H_
+#define _DT_BINDINGS_RESET_SUN50I_A100_H_
+
+#define RST_MBUS               0
+#define RST_BUS_DE             1
+#define RST_BUS_G2D            2
+#define RST_BUS_GPU            3
+#define RST_BUS_CE             4
+#define RST_BUS_VE             5
+#define RST_BUS_DMA            6
+#define RST_BUS_MSGBOX         7
+#define RST_BUS_SPINLOCK       8
+#define RST_BUS_HSTIMER                9
+#define RST_BUS_DBG            10
+#define RST_BUS_PSI            11
+#define RST_BUS_PWM            12
+#define RST_BUS_DRAM           13
+#define RST_BUS_NAND           14
+#define RST_BUS_MMC0           15
+#define RST_BUS_MMC1           16
+#define RST_BUS_MMC2           17
+#define RST_BUS_UART0          18
+#define RST_BUS_UART1          19
+#define RST_BUS_UART2          20
+#define RST_BUS_UART3          21
+#define RST_BUS_UART4          22
+#define RST_BUS_I2C0           23
+#define RST_BUS_I2C1           24
+#define RST_BUS_I2C2           25
+#define RST_BUS_I2C3           26
+#define RST_BUS_SPI0           27
+#define RST_BUS_SPI1           28
+#define RST_BUS_SPI2           29
+#define RST_BUS_EMAC           30
+#define RST_BUS_IR_RX          31
+#define RST_BUS_IR_TX          32
+#define RST_BUS_GPADC          33
+#define RST_BUS_THS            34
+#define RST_BUS_I2S0           35
+#define RST_BUS_I2S1           36
+#define RST_BUS_I2S2           37
+#define RST_BUS_I2S3           38
+#define RST_BUS_SPDIF          39
+#define RST_BUS_DMIC           40
+#define RST_BUS_AUDIO_CODEC    41
+#define RST_USB_PHY0           42
+#define RST_USB_PHY1           43
+#define RST_BUS_OHCI0          44
+#define RST_BUS_OHCI1          45
+#define RST_BUS_EHCI0          46
+#define RST_BUS_EHCI1          47
+#define RST_BUS_OTG            48
+#define RST_BUS_LRADC          49
+#define RST_BUS_DPSS_TOP0      50
+#define RST_BUS_DPSS_TOP1      51
+#define RST_BUS_MIPI_DSI       52
+#define RST_BUS_TCON_LCD       53
+#define RST_BUS_LVDS           54
+#define RST_BUS_LEDC           55
+#define RST_BUS_CSI            56
+#define RST_BUS_CSI_ISP                57
+
+#endif /* _DT_BINDINGS_RESET_SUN50I_A100_H_ */
diff --git a/include/dt-bindings/reset/sun50i-a100-r-ccu.h b/include/dt-bindings/reset/sun50i-a100-r-ccu.h
new file mode 100644 (file)
index 0000000..737bf6f
--- /dev/null
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: (GPL-2.0+ or MIT) */
+/*
+ * Copyright (c) 2020 Yangtao Li <frank@allwinnertech.com>
+ */
+
+#ifndef _DT_BINDINGS_RST_SUN50I_A100_R_CCU_H_
+#define _DT_BINDINGS_RST_SUN50I_A100_R_CCU_H_
+
+#define RST_R_APB1_TIMER       0
+#define RST_R_APB1_BUS_PWM     1
+#define RST_R_APB1_PPU         2
+#define RST_R_APB2_UART                3
+#define RST_R_APB2_I2C0                4
+#define RST_R_APB2_I2C1                5
+#define RST_R_APB1_BUS_IR      6
+#define RST_R_AHB_BUS_RTC      7
+
+#endif /* _DT_BINDINGS_RST_SUN50I_A100_R_CCU_H_ */