clock: clock tree for G12A
authorQiufang Dai <qiufang.dai@amlogic.com>
Sat, 23 Dec 2017 09:32:27 +0000 (17:32 +0800)
committerYixun Lan <yixun.lan@amlogic.com>
Fri, 2 Mar 2018 06:52:26 +0000 (14:52 +0800)
PD#156734: base clock tree for G12A,
include clk81, ee gate, sdemmc clock, fix/hifi/syspll/pcie plls, mpll, clkmsr

Change-Id: I9fe7c1d64d9db5d384070f5dcefdc69f5f60dbd2
Signed-off-by: Qiufang Dai <qiufang.dai@amlogic.com>
13 files changed:
Documentation/devicetree/bindings/clock/amlogic,meson-clkc.txt
MAINTAINERS
arch/arm64/boot/dts/amlogic/mesong12a.dtsi
drivers/amlogic/clk/Makefile
drivers/amlogic/clk/clk_measure.c
drivers/amlogic/clk/clkc.h
drivers/amlogic/clk/g12a/Makefile [new file with mode: 0644]
drivers/amlogic/clk/g12a/g12a.c [new file with mode: 0644]
drivers/amlogic/clk/g12a/g12a.h [new file with mode: 0644]
drivers/amlogic/clk/g12a/g12a_clk-mpll.c [new file with mode: 0644]
drivers/amlogic/clk/g12a/g12a_clk-pll.c [new file with mode: 0644]
drivers/amlogic/clk/g12a/g12a_clk_sdemmc.c [new file with mode: 0644]
include/dt-bindings/clock/amlogic,g12a-clkc.h

index ae2fa0c..6b91cc2 100644 (file)
@@ -12,6 +12,7 @@ Required Properties:
        "amlogic,axg-aoclkc"    - for axg ao clock
        "amlogic,txlx-clkc"     - for txlx ee clock
        "amlogic,txlx-aoclkc"    - for txlx ao clock
+       "amlogic,g12a-clkc"     - for g12a ee clock
 
 - reg: physical base address of the clock controller and length of memory
        mapped region.
index 3273c09..f148cc5 100644 (file)
@@ -14277,3 +14277,6 @@ F: arch/arm64/boot/dts/amlogic/mesong12a.dtsi
 F: arch/arm64/boot/dts/amlogic/g12a_pxp.dts
 F: include/dt-bindings/clock/amlogic,g12a-audio-clk.h
 F: include/dt-bindings/clock/amlogic,g12a-clkc.h
+F: drivers/amlogic/clk/g12a/*
+F: drivers/amlogic/clk/clkc.h
+
index 3c1106a..68e820f 100644 (file)
                        ranges = <0x0 0x0 0x0 0xff63c000 0x0 0x2000>;
 
                        clkc: clock-controller@0 {
-                               compatible = "amlogic,axg-clkc";
+                               compatible = "amlogic,g12a-clkc";
                                #clock-cells = <1>;
                                reg = <0x0 0x0 0x0 0x320>;
                        };
index cc0e619..66aad27 100644 (file)
@@ -14,5 +14,6 @@ obj-$(CONFIG_AMLOGIC_GX_CLK) += clk-cpu.o clk-mpll.o clk_test.o
 obj-$(CONFIG_AMLOGIC_GX_CLK) += gxl/
 obj-$(CONFIG_AMLOGIC_GX_CLK) += axg/
 obj-$(CONFIG_AMLOGIC_GX_CLK) += txlx/
+obj-$(CONFIG_AMLOGIC_GX_CLK) += g12a/
 
 obj-$(CONFIG_AMLOGIC_M8B_CLK) += m8b/
index 1fe16b5..3bfc764 100644 (file)
@@ -145,6 +145,7 @@ static unsigned int axg_clk_util_clk_msr(unsigned int clk_mux)
        }
        return 0;
 }
+
 int m8b_clk_measure(struct seq_file *s, void *what, unsigned int index)
 {
        static const char * const clk_table[] = {
@@ -694,6 +695,149 @@ int txlx_clk_measure(struct seq_file *s, void *what, unsigned int index)
        return 0;
 }
 
+int g12a_clk_measure(struct seq_file *s, void *what, unsigned int index)
+{
+       static const char * const clk_table[] = {
+               [122] = "mod_audio_pdm_dclk_o       ",
+               [121] = "audio_spdifin_mst_clk      ",
+               [120] = "audio_spdifout_mst_clk     ",
+               [119] = "audio_spdifout_b_mst_clk   ",
+               [118] = "audio_pdm_sysclk           ",
+               [117] = "audio_resample_clk         ",
+               [116] = "audio_tdmin_a_sclk         ",
+               [115] = "audio_tdmin_b_sclk         ",
+               [114] = "audio_tdmin_c_sclk         ",
+               [113] = "audio_tdmin_lb_sclk        ",
+               [112] = "audio_tdmout_a_sclk        ",
+               [111] = "audio_tdmout_b_sclk        ",
+               [110] = "audio_tdmout_c_sclk        ",
+               [109] = "c_alocker_out_clk          ",
+               [108] = "c_alocker_in_clk           ",
+               [107] = "au_dac_clk_g128x           ",
+               [106] = "ephy_test_clk              ",
+               [105] = "am_ring_osc_clk_out_ee[9]  ",
+               [104] = "am_ring_osc_clk_out_ee[8]  ",
+               [103] = "am_ring_osc_clk_out_ee[7]  ",
+               [102] = "am_ring_osc_clk_out_ee[6]  ",
+               [101] = "am_ring_osc_clk_out_ee[5]  ",
+               [100] = "am_ring_osc_clk_out_ee[4]  ",
+               [99] = "am_ring_osc_clk_out_ee[3]   ",
+               [98] = "cts_ts_clk                 ",
+               [97] = "cts_vpu_clkb_tmp           ",
+               [96] = "cts_vpu_clkb               ",
+               [95] = "eth_phy_plltxclk           ",
+               [94] = "eth_phy_rxclk              ",
+               [93] = "1'b0                       ",
+               [92] = "1'b0                       ",
+               [91] = "1'b0                       ",
+               [90] = "cts_hdmitx_sys_clk         ",
+               [89] = "HDMI_CLK_TODIG             ",
+               [88] = "1'b0                       ",
+               [87] = "1'b0                       ",
+               [86] = "1'b0                       ",
+               [85] = "1'b0                       ",
+               [84] = "co_tx_clk                  ",
+               [83] = "co_rx_clk                  ",
+               [82] = "cts_ge2d_clk               ",
+               [81] = "cts_vapbclk                ",
+               [80] = "rng_ring_osc_clk[3]        ",
+               [79] = "rng_ring_osc_clk[2]        ",
+               [78] = "rng_ring_osc_clk[1]        ",
+               [77] = "rng_ring_osc_clk[0]        ",
+               [76] = "1'b0                       ",
+               [75] = "cts_hevcf_clk              ",
+               [74] = "1'b0                       ",
+               [73] = "cts_pwm_C_clk              ",
+               [72] = "cts_pwm_D_clk              ",
+               [71] = "cts_pwm_E_clk              ",
+               [70] = "cts_pwm_F_clk              ",
+               [69] = "cts_hdcp22_skpclk          ",
+               [68] = "cts_hdcp22_esmclk          ",
+               [67] = "cts_dsi_phy_clk            ",
+               [66] = "cts_vid_lock_clk           ",
+               [65] = "cts_spicc_0_clk            ",
+               [64] = "cts_spicc_1_clk            ",
+               [63] = "cts_dsi_meas_clk           ",
+               [62] = "cts_hevcb_clk              ",
+               [61] = "gpio_clk_msr               ",
+               [60] = "1'b0                       ",
+               [59] = "cts_hcodec_clk             ",
+               [58] = "cts_wave420l_bclk          ",
+               [57] = "cts_wave420l_cclk          ",
+               [56] = "cts_wave420l_aclk          ",
+               [55] = "vid_pll_div_clk_out        ",
+               [54] = "cts_vpu_clkc               ",
+               [53] = "cts_sd_emmc_clk_A          ",
+               [52] = "cts_sd_emmc_clk_B          ",
+               [51] = "cts_sd_emmc_clk_C          ",
+               [50] = "mp3_clk_out                ",
+               [49] = "mp2_clk_out                ",
+               [48] = "mp1_clk_out                ",
+               [47] = "ddr_dpll_pt_clk            ",
+               [46] = "cts_vpu_clk                ",
+               [45] = "cts_pwm_A_clk              ",
+               [44] = "cts_pwm_B_clk              ",
+               [43] = "fclk_div5                  ",
+               [42] = "mp0_clk_out                ",
+               [41] = "mac_eth_rx_clk_rmii        ",
+               [40] = "1'b0                       ",
+               [39] = "cts_bt656_clk0             ",
+               [38] = "cts_vdin_meas_clk          ",
+               [37] = "cts_cdac_clk_c             ",
+               [36] = "cts_hdmi_tx_pixel_clk      ",
+               [35] = "cts_mali_clk               ",
+               [34] = "eth_mppll_50m_ckout        ",
+               [33] = "sys_cpu_ring_osc_clk[1]    ",
+               [32] = "cts_vdec_clk               ",
+               [31] = "mpll_clk_test_out          ",
+               [30] = "pcie_clk_inn               ",
+               [29] = "pcie_clk_inp               ",
+               [28] = "cts_sar_adc_clk            ",
+               [27] = "co_clkin_to_mac            ",
+               [26] = "sc_clk_int                 ",
+               [25] = "cts_eth_clk_rmii           ",
+               [24] = "cts_eth_clk125Mhz          ",
+               [23] = "mpll_clk_50m               ",
+               [22] = "mac_eth_phy_ref_clk        ",
+               [21] = "lcd_an_clk_ph3             ",
+               [20] = "rtc_osc_clk_out            ",
+               [19] = "lcd_an_clk_ph2             ",
+               [18] = "sys_cpu_clk_div16          ",
+               [17] = "sys_pll_div16              ",
+               [16] = "cts_FEC_CLK_2              ",
+               [15] = "cts_FEC_CLK_1              ",
+               [14] = "cts_FEC_CLK_0              ",
+               [13] = "mod_tcon_clko              ",
+               [12] = "hifi_pll_clk               ",
+               [11] = "mac_eth_tx_clk             ",
+               [10] = "cts_vdac_clk               ",
+               [9] = "cts_encl_clk             ",
+               [8] = "cts_encp_clk             ",
+               [7] = "clk81                    ",
+               [6] = "cts_enci_clk             ",
+               [5] = "1'b0                     ",
+               [4] = "gp0_pll_clk              ",
+               [3] = "sys_cpu_ring_osc_clk[0]  ",
+               [2] = "am_ring_osc_clk_out_ee[2]",
+               [1] = "am_ring_osc_clk_out_ee[1]",
+               [0] = "am_ring_osc_clk_out_ee[0]",
+       };
+       int  i;
+       int len = sizeof(clk_table)/sizeof(char *);
+
+       if (index  == 0xff) {
+               for (i = 0; i < len; i++)
+                       seq_printf(s, "[%2d][%10d]%s\n",
+                                  i, gxbb_clk_util_clk_msr(i),
+                                       clk_table[i]);
+               return 0;
+       }
+       seq_printf(s, "[%10d]%s\n", gxbb_clk_util_clk_msr(index),
+                  clk_table[index]);
+       clk_msr_index = 0xff;
+       return 0;
+}
+
 int  meson_clk_measure(unsigned int clk_mux)
 {
        int clk_val;
@@ -705,6 +849,7 @@ int  meson_clk_measure(unsigned int clk_mux)
        case MESON_CPU_MAJOR_ID_GXL:
        case MESON_CPU_MAJOR_ID_GXM:
        case MESON_CPU_MAJOR_ID_TXLX:
+       case MESON_CPU_MAJOR_ID_G12A:
                clk_val = gxbb_clk_util_clk_msr(clk_mux);
                break;
        case MESON_CPU_MAJOR_ID_AXG:
@@ -732,6 +877,8 @@ static int dump_clk(struct seq_file *s, void *what)
                axg_clk_measure(s, what, clk_msr_index);
        else if (get_cpu_type() == MESON_CPU_MAJOR_ID_TXLX)
                txlx_clk_measure(s, what, clk_msr_index);
+       else if (get_cpu_type() == MESON_CPU_MAJOR_ID_G12A)
+               g12a_clk_measure(s, what, clk_msr_index);
        return 0;
 }
 
index 79e7a8a..e28d9bf 100644 (file)
@@ -107,6 +107,7 @@ struct meson_clk_mpll {
        u8 en_dds;
        u16 top_misc_reg; /*after txlx*/
        u16 top_misc_bit;
+       u16 mpll_cntl0_reg;
        spinlock_t *lock;
 };
 
@@ -211,6 +212,10 @@ extern const struct clk_ops meson_clk_mpll_ops;
 extern const struct clk_ops meson_clk_mux_ops;
 extern const struct clk_ops meson_axg_pll_ro_ops;
 extern const struct clk_ops meson_axg_pll_ops;
+extern const struct clk_ops meson_g12a_pll_ro_ops;
+extern const struct clk_ops meson_g12a_pll_ops;
+extern const struct clk_ops meson_g12a_mpll_ro_ops;
+extern const struct clk_ops meson_g12a_mpll_ops;
 
 extern void meson_clk_register_composite(struct clk **soc_clks,
                        struct meson_composite *composite,
@@ -235,4 +240,6 @@ void meson_txlx_sdemmc_init(void);
 void meson_txlx_media_init(void);
 void meson_init_gpu(void);
 
+void meson_g12a_sdemmc_init(void);
+
 #endif /* __CLKC_H */
diff --git a/drivers/amlogic/clk/g12a/Makefile b/drivers/amlogic/clk/g12a/Makefile
new file mode 100644 (file)
index 0000000..f485a97
--- /dev/null
@@ -0,0 +1,9 @@
+#
+# Makefile for Meson G12A clk
+#
+
+obj-$(CONFIG_AMLOGIC_GX_CLK) += g12a.o g12a_clk-pll.o g12a_clk_sdemmc.o g12a_clk-mpll.o
+
+# g12a_ao.o\
+       g12a_clk-pll.o \
+       g12a_clk_sdemmc.o g12a_clk_media.o g12a_clk_misc.o
diff --git a/drivers/amlogic/clk/g12a/g12a.c b/drivers/amlogic/clk/g12a/g12a.c
new file mode 100644 (file)
index 0000000..a531da6
--- /dev/null
@@ -0,0 +1,958 @@
+/*
+ * drivers/amlogic/clk/g12a/g12a.c
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <dt-bindings/clock/amlogic,g12a-clkc.h>
+
+#include "../clkc.h"
+#include "g12a.h"
+
+static struct clk_onecell_data clk_data;
+/* #undef pr_debug */
+/* #define pr_debug pr_info */
+
+static const struct clk_div_table cpu_div_table[] = {
+       { .val = 1, .div = 1 },
+       { .val = 2, .div = 2 },
+       { .val = 3, .div = 3 },
+       { .val = 2, .div = 4 },
+       { .val = 3, .div = 6 },
+       { .val = 4, .div = 8 },
+       { .val = 5, .div = 10 },
+       { .val = 6, .div = 12 },
+       { .val = 7, .div = 14 },
+       { .val = 8, .div = 16 },
+       { /* sentinel */ },
+};
+
+static struct meson_clk_pll g12a_fixed_pll = {
+       .m = {
+               .reg_off = HHI_FIX_PLL_CNTL0,
+               .shift   = 0,
+               .width   = 9,
+       },
+       .n = {
+               .reg_off = HHI_FIX_PLL_CNTL0,
+               .shift   = 10,
+               .width   = 5,
+       },
+       .od = {
+               .reg_off = HHI_FIX_PLL_CNTL0,
+               .shift   = 16,
+               .width   = 2,
+       },
+       .frac = {
+               .reg_off = HHI_FIX_PLL_CNTL1,
+               .shift   = 0,
+               .width   = 19,
+       },
+       .lock = &clk_lock,
+       .hw.init = &(struct clk_init_data){
+               .name = "fixed_pll",
+               .ops = &meson_g12a_pll_ro_ops,
+               .parent_names = (const char *[]){ "xtal" },
+               .num_parents = 1,
+               .flags = CLK_IS_CRITICAL | CLK_GET_RATE_NOCACHE,
+       },
+};
+
+static struct meson_clk_pll g12a_sys_pll = {
+       .m = {
+               .reg_off = HHI_SYS_PLL_CNTL0,
+               .shift   = 0,
+               .width   = 9,
+       },
+       .n = {
+               .reg_off = HHI_SYS_PLL_CNTL0,
+               .shift   = 10,
+               .width   = 5,
+       },
+       .od = {
+               .reg_off = HHI_SYS_PLL_CNTL0,
+               .shift   = 16,
+               .width   = 3,
+       },
+       .rate_table = g12a_pll_rate_table,
+       .rate_count = ARRAY_SIZE(g12a_pll_rate_table),
+       .lock = &clk_lock,
+       .hw.init = &(struct clk_init_data){
+               .name = "sys_pll",
+               .ops = &meson_g12a_pll_ops,
+               .parent_names = (const char *[]){ "xtal" },
+               .num_parents = 1,
+               .flags = CLK_GET_RATE_NOCACHE,
+       },
+};
+
+static struct meson_clk_pll g12a_gp0_pll = {
+       .m = {
+               .reg_off = HHI_GP0_PLL_CNTL0,
+               .shift   = 0,
+               .width   = 9,
+       },
+       .n = {
+               .reg_off = HHI_GP0_PLL_CNTL0,
+               .shift   = 10,
+               .width   = 5,
+       },
+       .od = {
+               .reg_off = HHI_GP0_PLL_CNTL0,
+               .shift   = 16,
+               .width   = 3,
+       },
+       .rate_table = g12a_pll_rate_table,
+       .rate_count = ARRAY_SIZE(g12a_pll_rate_table),
+       .lock = &clk_lock,
+       .hw.init = &(struct clk_init_data){
+               .name = "gp0_pll",
+               .ops = &meson_g12a_pll_ops,
+               .parent_names = (const char *[]){ "xtal" },
+               .num_parents = 1,
+               .flags = CLK_GET_RATE_NOCACHE,
+       },
+};
+
+static struct meson_clk_pll g12a_hifi_pll = {
+       .m = {
+               .reg_off = HHI_HIFI_PLL_CNTL0,
+               .shift   = 0,
+               .width   = 9,
+       },
+       .n = {
+               .reg_off = HHI_HIFI_PLL_CNTL0,
+               .shift   = 10,
+               .width   = 5,
+       },
+       .od = {
+               .reg_off = HHI_HIFI_PLL_CNTL0,
+               .shift   = 16,
+               .width   = 2,
+       },
+       .rate_table = g12a_pll_rate_table,
+       .rate_count = ARRAY_SIZE(g12a_pll_rate_table),
+       .lock = &clk_lock,
+       .hw.init = &(struct clk_init_data){
+               .name = "hifi_pll",
+               .ops = &meson_g12a_pll_ops,
+               .parent_names = (const char *[]){ "xtal" },
+               .num_parents = 1,
+               .flags = CLK_GET_RATE_NOCACHE,
+       },
+};
+
+static struct meson_clk_pll g12a_pcie_pll = {
+       .m = {
+               .reg_off = HHI_PCIE_PLL_CNTL0,
+               .shift   = 0,
+               .width   = 8,
+       },
+       .n = {
+               .reg_off = HHI_PCIE_PLL_CNTL0,
+               .shift   = 10,
+               .width   = 5,
+       },
+       .od = {
+               .reg_off = HHI_PCIE_PLL_CNTL0,
+               .shift   = 16,
+               .width   = 5,
+       },
+
+       .frac = {
+               .reg_off = HHI_PCIE_PLL_CNTL1,
+               .shift   = 0,
+               .width   = 12,
+       },
+       .rate_table = g12a_pcie_pll_rate_table,
+       .rate_count = ARRAY_SIZE(g12a_pcie_pll_rate_table),
+       .lock = &clk_lock,
+       .hw.init = &(struct clk_init_data){
+               .name = "pcie_pll",
+               .ops = &meson_g12a_pll_ops,
+               .parent_names = (const char *[]){ "xtal" },
+               .num_parents = 1,
+               .flags = CLK_GET_RATE_NOCACHE,
+       },
+};
+
+static struct clk_fixed_factor g12a_fclk_div2 = {
+       .mult = 1,
+       .div = 2,
+       .hw.init = &(struct clk_init_data){
+               .name = "fclk_div2",
+               .ops = &clk_fixed_factor_ops,
+               .parent_names = (const char *[]){ "fixed_pll" },
+               .num_parents = 1,
+       },
+};
+
+static struct clk_fixed_factor g12a_fclk_div3 = {
+       .mult = 1,
+       .div = 3,
+       .hw.init = &(struct clk_init_data){
+               .name = "fclk_div3",
+               .ops = &clk_fixed_factor_ops,
+               .parent_names = (const char *[]){ "fixed_pll" },
+               .num_parents = 1,
+       },
+};
+
+static struct clk_fixed_factor g12a_fclk_div4 = {
+       .mult = 1,
+       .div = 4,
+       .hw.init = &(struct clk_init_data){
+               .name = "fclk_div4",
+               .ops = &clk_fixed_factor_ops,
+               .parent_names = (const char *[]){ "fixed_pll" },
+               .num_parents = 1,
+       },
+};
+
+static struct clk_fixed_factor g12a_fclk_div5 = {
+       .mult = 1,
+       .div = 5,
+       .hw.init = &(struct clk_init_data){
+               .name = "fclk_div5",
+               .ops = &clk_fixed_factor_ops,
+               .parent_names = (const char *[]){ "fixed_pll" },
+               .num_parents = 1,
+       },
+};
+
+static struct clk_fixed_factor g12a_fclk_div7 = {
+       .mult = 1,
+       .div = 7,
+       .hw.init = &(struct clk_init_data){
+               .name = "fclk_div7",
+               .ops = &clk_fixed_factor_ops,
+               .parent_names = (const char *[]){ "fixed_pll" },
+               .num_parents = 1,
+       },
+};
+
+static struct clk_fixed_factor g12a_fclk_div2p5 = {
+       .mult = 2,
+       .div = 5,
+       .hw.init = &(struct clk_init_data){
+               .name = "fclk_div2p5",
+               .ops = &clk_fixed_factor_ops,
+               .parent_names = (const char *[]){ "fixed_pll" },
+               .num_parents = 1,
+       },
+};
+
+static struct meson_clk_mpll g12a_mpll0 = {
+       .sdm = {
+               .reg_off = HHI_MPLL_CNTL1,
+               .shift   = 0,
+               .width   = 14,
+       },
+       .n2 = {
+               .reg_off = HHI_MPLL_CNTL1,
+               .shift   = 20,
+               .width   = 9,
+       },
+       .sdm_en = 30,
+       .en_dds = 31,
+       .mpll_cntl0_reg = HHI_MPLL_CNTL0,
+       .lock = &clk_lock,
+       .hw.init = &(struct clk_init_data){
+               .name = "mpll0",
+               .ops = &meson_g12a_mpll_ops,
+               .parent_names = (const char *[]){ "fixed_pll" },
+               .num_parents = 1,
+       },
+};
+
+static struct meson_clk_mpll g12a_mpll1 = {
+       .sdm = {
+               .reg_off = HHI_MPLL_CNTL3,
+               .shift   = 0,
+               .width   = 14,
+       },
+       .n2 = {
+               .reg_off = HHI_MPLL_CNTL3,
+               .shift   = 20,
+               .width   = 9,
+       },
+       .sdm_en = 30,
+       .en_dds = 31,
+       .mpll_cntl0_reg = HHI_MPLL_CNTL0,
+       .lock = &clk_lock,
+       .hw.init = &(struct clk_init_data){
+               .name = "mpll1",
+               .ops = &meson_g12a_mpll_ops,
+               .parent_names = (const char *[]){ "fixed_pll" },
+               .num_parents = 1,
+       },
+};
+
+static struct meson_clk_mpll g12a_mpll2 = {
+       .sdm = {
+               .reg_off = HHI_MPLL_CNTL5,
+               .shift   = 0,
+               .width   = 14,
+       },
+       .n2 = {
+               .reg_off = HHI_MPLL_CNTL5,
+               .shift   = 20,
+               .width   = 9,
+       },
+       .sdm_en = 30,
+       .en_dds = 31,
+       .mpll_cntl0_reg = HHI_MPLL_CNTL0,
+       .lock = &clk_lock,
+       .hw.init = &(struct clk_init_data){
+               .name = "mpll2",
+               .ops = &meson_g12a_mpll_ops,
+               .parent_names = (const char *[]){ "fixed_pll" },
+               .num_parents = 1,
+       },
+};
+
+static struct meson_clk_mpll g12a_mpll3 = {
+       .sdm = {
+               .reg_off = HHI_MPLL_CNTL7,
+               .shift   = 0,
+               .width   = 14,
+       },
+       .n2 = {
+               .reg_off = HHI_MPLL_CNTL7,
+               .shift   = 20,
+               .width   = 9,
+       },
+       .sdm_en = 30,
+       .en_dds = 31,
+       .mpll_cntl0_reg = HHI_MPLL_CNTL0,
+       .lock = &clk_lock,
+       .hw.init = &(struct clk_init_data){
+               .name = "mpll3",
+               .ops = &meson_g12a_mpll_ops,
+               .parent_names = (const char *[]){ "fixed_pll" },
+               .num_parents = 1,
+       },
+};
+
+#if 0
+static struct clk_mux g12a_pcie_mux = {
+       .reg = (void *)HHI_PCIE_PLL_CNTL6,
+       .mask = 0x1,
+       .shift = 2,
+       .lock = &clk_lock,
+       .hw.init = &(struct clk_init_data){
+               .name = "g12a_pcie_mux",
+               .ops = &clk_mux_ops,
+               .parent_names = (const char *[]){ "mpll3", "pcie_pll" },
+               .num_parents = 2,
+               .flags = (CLK_GET_RATE_NOCACHE | CLK_IGNORE_UNUSED),
+       },
+};
+
+static struct clk_mux g12a_pcie_ref = {
+       .reg = (void *)HHI_PCIE_PLL_CNTL6,
+       .mask = 0x1,
+       .shift = 1,
+       .lock = &clk_lock,
+       .hw.init = &(struct clk_init_data){
+               .name = "g12a_pcie_ref",
+               .ops = &clk_mux_ops,
+               //.parent_names = (const char *[]){ "g12a_pcie_input_gate",
+               .parent_names = (const char *[]){ "NULL",
+                       "g12a_pcie_mux" },
+               .num_parents = 2,
+               .flags = (CLK_GET_RATE_NOCACHE | CLK_IGNORE_UNUSED),
+       },
+};
+
+static struct clk_gate g12a_pcie_cml_en0 = {
+       .reg = (void *)HHI_PCIE_PLL_CNTL6,
+       .bit_idx = 4,
+       .lock = &clk_lock,
+       .hw.init = &(struct clk_init_data) {
+               .name = "g12a_pcie_cml_en0",
+               .ops = &clk_gate_ops,
+               .parent_names = (const char *[]){ "g12a_pcie_ref" },
+               .num_parents = 1,
+               .flags = (CLK_GET_RATE_NOCACHE | CLK_IGNORE_UNUSED),
+       },
+};
+
+static struct clk_gate g12a_pcie_cml_en1 = {
+       .reg = (void *)HHI_PCIE_PLL_CNTL6,
+       .bit_idx = 3,
+       .lock = &clk_lock,
+       .hw.init = &(struct clk_init_data) {
+               .name = "g12a_pcie_cml_en1",
+               .ops = &clk_gate_ops,
+               .parent_names = (const char *[]){ "g12a_pcie_ref" },
+               .num_parents = 1,
+               .flags = (CLK_GET_RATE_NOCACHE | CLK_IGNORE_UNUSED),
+       },
+};
+
+static struct clk_gate g12a_mipi_enable_gate = {
+       .reg = (void *)HHI_MIPI_CNTL0,
+       .bit_idx = 29,
+       .lock = &clk_lock,
+       .hw.init = &(struct clk_init_data) {
+               .name = "g12a_mipi_enable_gate",
+               .ops = &clk_gate_ops,
+               .parent_names = (const char *[]){ "NULL" },
+               .num_parents = 0,
+               .flags = (CLK_GET_RATE_NOCACHE | CLK_IGNORE_UNUSED),
+       },
+};
+
+static struct clk_gate g12a_mipi_bandgap_gate = {
+       .reg = (void *)HHI_MIPI_CNTL0,
+       .bit_idx = 26,
+       .lock = &clk_lock,
+       .hw.init = &(struct clk_init_data) {
+               .name = "g12a_mipi_bandgap_gate",
+               .ops = &clk_gate_ops,
+               .parent_names = (const char *[]){ "NULL" },
+               .num_parents = 0,
+               .flags = (CLK_GET_RATE_NOCACHE | CLK_IGNORE_UNUSED),
+       },
+};
+#endif
+/*
+ * FIXME cpu clocks and the legacy composite clocks (e.g. clk81) are both PLL
+ * post-dividers and should be modelled with their respective PLLs via the
+ * forthcoming coordinated clock rates feature
+ */
+static u32 mux_table_cpu_px0[] = { 0, 1, 2 };
+static u32 mux_table_cpu_px[]  = { 0, 1 };
+
+static struct clk_mux g12a_cpu_fixedpll_p00 = {
+       .reg = (void *)HHI_SYS_CPU_CLK_CNTL0,
+       .mask = 0x3,
+       .shift = 0,
+       .table = mux_table_cpu_px0,
+       .lock = &clk_lock,
+       .hw.init = &(struct clk_init_data){
+               .name = "cpu_fixedpll_p00",
+               .ops = &meson_clk_cpu_ops,
+               .parent_names = (const char *[]){ "xtal", "fclk_div2",
+                       "fclk_div3"},
+               .num_parents = 3,
+               .flags = CLK_GET_RATE_NOCACHE,
+       },
+};
+
+static struct clk_divider g12a_cpu_fixedpll_p01 = {
+       .reg = (void *)HHI_SYS_CPU_CLK_CNTL0,
+       .shift = 4,
+       .width = 6,
+       .lock = &clk_lock,
+       .hw.init = &(struct clk_init_data){
+               .name = "cpu_fixedpll_p01",
+               .ops = &clk_divider_ops,
+               .parent_names = (const char *[]){ "cpu_fixedpll_p00" },
+               .num_parents = 1,
+               .flags = CLK_GET_RATE_NOCACHE,
+       },
+};
+
+static struct clk_mux g12a_cpu_fixedpll_p0 = {
+       .reg = (void *)HHI_SYS_CPU_CLK_CNTL0,
+       .mask = 0x1,
+       .shift = 2,
+       .table = mux_table_cpu_px,
+       .lock = &clk_lock,
+       .hw.init = &(struct clk_init_data){
+               .name = "cpu_fixedpll_p0",
+               .ops = &meson_clk_cpu_ops,
+               .parent_names = (const char *[]){ "cpu_fixedpll_p00",
+                       "cpu_fixedpll_p01"},
+               .num_parents = 2,
+               .flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT),
+       },
+};
+
+static struct clk_mux g12a_cpu_fixedpll_p10 = {
+       .reg = (void *)HHI_SYS_CPU_CLK_CNTL0,
+       .mask = 0x3,
+       .shift = 16,
+       .table = mux_table_cpu_px0,
+       .lock = &clk_lock,
+       .hw.init = &(struct clk_init_data){
+               .name = "cpu_fixedpll_p10",
+               .ops = &meson_clk_cpu_ops,
+               .parent_names = (const char *[]){ "xtal", "fclk_div2",
+                       "fclk_div3"},
+               .num_parents = 3,
+               .flags = CLK_GET_RATE_NOCACHE,
+       },
+};
+
+static struct clk_divider g12a_cpu_fixedpll_p11 = {
+       .reg = (void *)HHI_SYS_CPU_CLK_CNTL0,
+       .shift = 20,
+       .width = 6,
+       .lock = &clk_lock,
+       .hw.init = &(struct clk_init_data){
+               .name = "cpu_fixedpll_p11",
+               .ops = &clk_divider_ops,
+               .parent_names = (const char *[]){ "cpu_fixedpll_p10" },
+               .num_parents = 1,
+               .flags = CLK_GET_RATE_NOCACHE,
+       },
+};
+
+static struct clk_mux g12a_cpu_fixedpll_p1 = {
+       .reg = (void *)HHI_SYS_CPU_CLK_CNTL0,
+       .mask = 0x1,
+       .shift = 18,
+       .table = mux_table_cpu_px,
+       .lock = &clk_lock,
+       .hw.init = &(struct clk_init_data){
+               .name = "cpu_fixedpll_p1",
+               .ops = &meson_clk_cpu_ops,
+               .parent_names = (const char *[]){ "cpu_fixedpll_p10",
+                       "cpu_fixedpll_p11"},
+               .num_parents = 2,
+               .flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT),
+       },
+};
+
+static struct clk_mux g12a_cpu_fixedpll_p = {
+       .reg = (void *)HHI_SYS_CPU_CLK_CNTL0,
+       .mask = 0x1,
+       .shift = 10,
+       .table = mux_table_cpu_px,
+       .lock = &clk_lock,
+       .hw.init = &(struct clk_init_data){
+               .name = "cpu_fixedpll_p",
+               .ops = &meson_clk_cpu_ops,
+               .parent_names = (const char *[]){ "cpu_fixedpll_p0",
+                       "cpu_fixedpll_p1"},
+               .num_parents = 2,
+               .flags = CLK_GET_RATE_NOCACHE,
+       },
+};
+
+static struct meson_clk_cpu g12a_cpu_clk = {
+       .reg_off = HHI_SYS_CPU_CLK_CNTL0,
+       .clk_nb.notifier_call = meson_clk_cpu_notifier_cb,
+       .mux.reg = (void *)HHI_SYS_CPU_CLK_CNTL0,
+       .mux.shift = 11,
+       .mux.mask = 0x1,
+       .mux.lock = &clk_lock,
+       .mux.table = mux_table_cpu_px,
+       .mux.hw.init = &(struct clk_init_data){
+               .name = "cpu_clk",
+               .ops = &meson_clk_cpu_ops,
+               .parent_names = (const char *[]){ "cpu_fixedpll_p", "sys_pll"},
+               .num_parents = 2,
+               .flags = CLK_GET_RATE_NOCACHE,
+       },
+};
+
+static u32 mux_table_clk81[] = { 6, 5, 7 };
+
+static struct clk_mux g12a_mpeg_clk_sel = {
+       .reg = (void *)HHI_MPEG_CLK_CNTL,
+       .mask = 0x7,
+       .shift = 12,
+       .flags = CLK_MUX_READ_ONLY,
+       .table = mux_table_clk81,
+       .lock = &clk_lock,
+       .hw.init = &(struct clk_init_data){
+               .name = "mpeg_clk_sel",
+               .ops = &clk_mux_ro_ops,
+               /*
+                * FIXME bits 14:12 selects from 8 possible parents:
+                * xtal, 1'b0 (wtf), fclk_div7, mpll_clkout1, mpll_clkout2,
+                * fclk_div4, fclk_div3, fclk_div5
+                */
+               .parent_names = (const char *[]){ "fclk_div3", "fclk_div4",
+                       "fclk_div5" },
+               .num_parents = 3,
+               .flags = CLK_SET_RATE_NO_REPARENT,
+       },
+};
+
+static struct clk_divider g12a_mpeg_clk_div = {
+       .reg = (void *)HHI_MPEG_CLK_CNTL,
+       .shift = 0,
+       .width = 7,
+       .lock = &clk_lock,
+       .hw.init = &(struct clk_init_data){
+               .name = "mpeg_clk_div",
+               .ops = &clk_divider_ops,
+               .parent_names = (const char *[]){ "mpeg_clk_sel" },
+               .num_parents = 1,
+               .flags = CLK_SET_RATE_PARENT,
+       },
+};
+
+/* the mother of dragons^W gates */
+static struct clk_gate g12a_clk81 = {
+       .reg = (void *)HHI_MPEG_CLK_CNTL,
+       .bit_idx = 7,
+       .lock = &clk_lock,
+       .hw.init = &(struct clk_init_data){
+               .name = "clk81",
+               .ops = &clk_gate_ops,
+               .parent_names = (const char *[]){ "mpeg_clk_div" },
+               .num_parents = 1,
+               .flags = (CLK_SET_RATE_PARENT | CLK_IS_CRITICAL),
+       },
+};
+
+
+/* Everything Else (EE) domain gates */
+static MESON_GATE(g12a_ddr, HHI_GCLK_MPEG0, 0);
+static MESON_GATE(g12a_dos, HHI_GCLK_MPEG0, 1);
+static MESON_GATE(g12a_alocker, HHI_GCLK_MPEG0, 2);
+static MESON_GATE(g12a_mipi_dsi_host, HHI_GCLK_MPEG0, 3);
+static MESON_GATE(g12a_eth_phy, HHI_GCLK_MPEG0, 4);
+static MESON_GATE(g12a_isa, HHI_GCLK_MPEG0, 5);
+static MESON_GATE(g12a_pl301, HHI_GCLK_MPEG0, 6);
+static MESON_GATE(g12a_periphs, HHI_GCLK_MPEG0, 7);
+static MESON_GATE(g12a_spicc_0, HHI_GCLK_MPEG0, 8);
+static MESON_GATE(g12a_i2c, HHI_GCLK_MPEG0, 9);
+static MESON_GATE(g12a_sana, HHI_GCLK_MPEG0, 10);
+static MESON_GATE(g12a_sd, HHI_GCLK_MPEG0, 11);
+static MESON_GATE(g12a_rng0, HHI_GCLK_MPEG0, 12);
+static MESON_GATE(g12a_uart0, HHI_GCLK_MPEG0, 13);
+static MESON_GATE(g12a_spicc_1, HHI_GCLK_MPEG0, 14);
+static MESON_GATE(g12a_hiu_reg, HHI_GCLK_MPEG0, 19);
+static MESON_GATE(g12a_mipi_dsi_phy, HHI_GCLK_MPEG0, 20);
+static MESON_GATE(g12a_assist_misc, HHI_GCLK_MPEG0, 23);
+static MESON_GATE(g12a_emmc_a, HHI_GCLK_MPEG0, 24);
+static MESON_GATE(g12a_emmc_b, HHI_GCLK_MPEG0, 25);
+static MESON_GATE(g12a_emmc_c, HHI_GCLK_MPEG0, 26);
+static MESON_GATE(g12a_acodec, HHI_GCLK_MPEG0, 28);
+
+static MESON_GATE(g12a_audio, HHI_GCLK_MPEG1, 0);
+static MESON_GATE(g12a_eth_core, HHI_GCLK_MPEG1, 3);
+static MESON_GATE(g12a_u_stp_top, HHI_GCLK_MPEG1, 4);
+static MESON_GATE(g12a_aififo, HHI_GCLK_MPEG1, 11);
+static MESON_GATE(g12a_adc, HHI_GCLK_MPEG1, 13);
+static MESON_GATE(g12a_uart1, HHI_GCLK_MPEG1, 16);
+static MESON_GATE(g12a_g2d, HHI_GCLK_MPEG1, 20);
+static MESON_GATE(g12a_reset, HHI_GCLK_MPEG1, 23);
+static MESON_GATE(g12a_pcie_comb, HHI_GCLK_MPEG1, 24);
+static MESON_GATE(g12a_parser, HHI_GCLK_MPEG1, 25);
+static MESON_GATE(g12a_usb_general, HHI_GCLK_MPEG1, 26);
+static MESON_GATE(g12a_pcie_phy, HHI_GCLK_MPEG1, 27);
+static MESON_GATE(g12a_ahb_arb0, HHI_GCLK_MPEG1, 29);
+
+static MESON_GATE(g12a_ahb_data_bus, HHI_GCLK_MPEG2, 1);
+static MESON_GATE(g12a_ahb_ctrl_bus, HHI_GCLK_MPEG2, 2);
+static MESON_GATE(g12a_htx_hdcp22, HHI_GCLK_MPEG2, 3);
+static MESON_GATE(g12a_htx_pclk, HHI_GCLK_MPEG2, 4);
+static MESON_GATE(g12a_bt656, HHI_GCLK_MPEG2, 6);
+static MESON_GATE(g12a_usb1_to_ddr, HHI_GCLK_MPEG2, 8);
+static MESON_GATE(g12a_mmc_pclk, HHI_GCLK_MPEG2, 11);
+static MESON_GATE(g12a_uart2, HHI_GCLK_MPEG2, 15);
+static MESON_GATE(g12a_vpu_intr, HHI_GCLK_MPEG2, 25);
+static MESON_GATE(g12a_gic, HHI_GCLK_MPEG2, 30);
+
+/* Always On (AO) domain gates */
+#if 0
+static MESON_GATE(g12a_ao_media_cpu, HHI_GCLK_AO, 0);
+static MESON_GATE(g12a_ao_ahb_sram, HHI_GCLK_AO, 1);
+static MESON_GATE(g12a_ao_ahb_bus, HHI_GCLK_AO, 2);
+static MESON_GATE(g12a_ao_iface, HHI_GCLK_AO, 3);
+static MESON_GATE(g12a_ao_i2c, HHI_GCLK_AO, 4);
+#endif
+/* Array of all clocks provided by this provider */
+
+static struct clk_hw *g12a_clk_hws[] = {
+       [CLKID_SYS_PLL]         = &g12a_sys_pll.hw,
+       [CLKID_FIXED_PLL]       = &g12a_fixed_pll.hw,
+       [CLKID_GP0_PLL]         = &g12a_gp0_pll.hw,
+       [CLKID_HIFI_PLL]        = &g12a_hifi_pll.hw,
+       [CLKID_PCIE_PLL]        = &g12a_pcie_pll.hw,
+       [CLKID_FCLK_DIV2]       = &g12a_fclk_div2.hw,
+       [CLKID_FCLK_DIV3]       = &g12a_fclk_div3.hw,
+       [CLKID_FCLK_DIV4]       = &g12a_fclk_div4.hw,
+       [CLKID_FCLK_DIV5]       = &g12a_fclk_div5.hw,
+       [CLKID_FCLK_DIV7]       = &g12a_fclk_div7.hw,
+       [CLKID_FCLK_DIV2P5]     = &g12a_fclk_div2p5.hw,
+       [CLKID_MPEG_SEL]        = &g12a_mpeg_clk_sel.hw,
+       [CLKID_MPEG_DIV]        = &g12a_mpeg_clk_div.hw,
+       [CLKID_CLK81]           = &g12a_clk81.hw,
+
+       [CLKID_MPLL0]           = &g12a_mpll0.hw,
+       [CLKID_MPLL1]           = &g12a_mpll1.hw,
+       [CLKID_MPLL2]           = &g12a_mpll2.hw,
+       [CLKID_MPLL3]           = &g12a_mpll3.hw,
+
+       [CLKID_DDR]             = &g12a_ddr.hw,
+       [CLKID_DOS]             = &g12a_dos.hw,
+       [CLKID_AUDIO_LOCKER]    = &g12a_alocker.hw,
+       [CLKID_MIPI_DSI_HOST]   = &g12a_mipi_dsi_host.hw,
+       [CLKID_ETH_PHY]         = &g12a_eth_phy.hw,
+       [CLKID_ISA]             = &g12a_isa.hw,
+       [CLKID_PL301]           = &g12a_pl301.hw,
+       [CLKID_PERIPHS]         = &g12a_periphs.hw,
+       [CLKID_SPICC0]          = &g12a_spicc_0.hw,
+       [CLKID_I2C]             = &g12a_i2c.hw,
+       [CLKID_SANA]            = &g12a_sana.hw,
+       [CLKID_SD]              = &g12a_sd.hw,
+       [CLKID_RNG0]            = &g12a_rng0.hw,
+       [CLKID_UART0]           = &g12a_uart0.hw,
+       [CLKID_SPICC1]          = &g12a_spicc_1.hw,
+       [CLKID_HIU_REG]         = &g12a_hiu_reg.hw,
+       [CLKID_MIPI_DSI_PHY]    = &g12a_mipi_dsi_phy.hw,
+       [CLKID_ASSIST_MISC]     = &g12a_assist_misc.hw,
+       [CLKID_SD_EMMC_A]       = &g12a_emmc_a.hw,
+       [CLKID_SD_EMMC_B]       = &g12a_emmc_b.hw,
+       [CLKID_SD_EMMC_C]       = &g12a_emmc_c.hw,
+       [CLKID_ACODEC]          = &g12a_acodec.hw,
+       [CLKID_AUDIO]           = &g12a_audio.hw,
+       [CLKID_ETH_CORE]        = &g12a_eth_core.hw,
+       [CLKID_U_STP_TOP]       = &g12a_u_stp_top.hw,
+       [CLKID_AIFIFO]          = &g12a_aififo.hw,
+       [CLKID_ADC]             = &g12a_adc.hw,
+       [CLKID_UART1]           = &g12a_uart1.hw,
+       [CLKID_G2D]             = &g12a_g2d.hw,
+       [CLKID_RESET]           = &g12a_reset.hw,
+       [CLKID_PCIE_COMB]       = &g12a_pcie_comb.hw,
+       [CLKID_PARSER]          = &g12a_parser.hw,
+       [CLKID_USB_GENERAL]     = &g12a_usb_general.hw,
+       [CLKID_PCIE_PHY]        = &g12a_pcie_phy.hw,
+       [CLKID_AHB_ARB0]        = &g12a_ahb_arb0.hw,
+       [CLKID_AHB_DATA_BUS]    = &g12a_ahb_data_bus.hw,
+       [CLKID_AHB_CTRL_BUS]    = &g12a_ahb_ctrl_bus.hw,
+       [CLKID_HTX_HDCP22]      = &g12a_htx_hdcp22.hw,
+       [CLKID_HTX_PCLK]        = &g12a_htx_pclk.hw,
+       [CLKID_BT656]           = &g12a_bt656.hw,
+       [CLKID_USB1_TO_DDR]     = &g12a_usb1_to_ddr.hw,
+       [CLKID_MMC_PCLK]        = &g12a_mmc_pclk.hw,
+       [CLKID_UART2]           = &g12a_uart2.hw,
+       [CLKID_VPU_INTR]        = &g12a_vpu_intr.hw,
+       [CLKID_GIC]             = &g12a_gic.hw,
+
+#if 0
+       [CLKID_AO_MEDIA_CPU]    = &g12a_ao_media_cpu.hw,
+       [CLKID_AO_AHB_SRAM]     = &g12a_ao_ahb_sram.hw,
+       [CLKID_AO_AHB_BUS]      = &g12a_ao_ahb_bus.hw,
+       [CLKID_AO_IFACE]        = &g12a_ao_iface.hw,
+       [CLKID_AO_I2C]          = &g12a_ao_i2c.hw,
+#endif
+       [CLKID_CPU_FCLK_P00]    = &g12a_cpu_fixedpll_p00.hw,
+       [CLKID_CPU_FCLK_P01]    = &g12a_cpu_fixedpll_p01.hw,
+       [CLKID_CPU_FCLK_P0]     = &g12a_cpu_fixedpll_p0.hw,
+       [CLKID_CPU_FCLK_P10]    = &g12a_cpu_fixedpll_p10.hw,
+       [CLKID_CPU_FCLK_P11]    = &g12a_cpu_fixedpll_p11.hw,
+       [CLKID_CPU_FCLK_P1]     = &g12a_cpu_fixedpll_p1.hw,
+       [CLKID_CPU_FCLK_P]      = &g12a_cpu_fixedpll_p.hw,
+       [CLKID_CPU_CLK]         = &g12a_cpu_clk.mux.hw,
+
+       [CLKID_PCIE_PLL]        = &g12a_pcie_pll.hw,
+};
+/* Convenience tables to populate base addresses in .probe */
+
+static struct meson_clk_pll *const g12a_clk_plls[] = {
+       &g12a_fixed_pll,
+       &g12a_sys_pll,
+       &g12a_gp0_pll,
+       &g12a_hifi_pll,
+       &g12a_pcie_pll,
+};
+
+static struct meson_clk_mpll *const g12a_clk_mplls[] = {
+       &g12a_mpll0,
+       &g12a_mpll1,
+       &g12a_mpll2,
+       &g12a_mpll3,
+};
+
+static struct clk_gate *g12a_clk_gates[] = {
+       &g12a_clk81,
+       &g12a_ddr,
+       &g12a_dos,
+       &g12a_alocker,
+       &g12a_mipi_dsi_host,
+       &g12a_eth_phy,
+       &g12a_isa,
+       &g12a_pl301,
+       &g12a_periphs,
+       &g12a_spicc_0,
+       &g12a_i2c,
+       &g12a_sana,
+       &g12a_sd,
+       &g12a_rng0,
+       &g12a_uart0,
+       &g12a_spicc_1,
+       &g12a_hiu_reg,
+       &g12a_mipi_dsi_phy,
+       &g12a_assist_misc,
+       &g12a_emmc_a,
+       &g12a_emmc_b,
+       &g12a_emmc_c,
+       &g12a_acodec,
+       &g12a_audio,
+       &g12a_eth_core,
+       &g12a_u_stp_top,
+       &g12a_aififo,
+       &g12a_adc,
+       &g12a_uart1,
+       &g12a_g2d,
+       &g12a_reset,
+       &g12a_pcie_comb,
+       &g12a_parser,
+       &g12a_usb_general,
+       &g12a_pcie_phy,
+       &g12a_ahb_arb0,
+       &g12a_ahb_data_bus,
+       &g12a_ahb_ctrl_bus,
+       &g12a_htx_hdcp22,
+       &g12a_htx_pclk,
+       &g12a_bt656,
+       &g12a_usb1_to_ddr,
+       &g12a_mmc_pclk,
+       &g12a_uart2,
+       &g12a_vpu_intr,
+       &g12a_gic,
+#if 0
+       &g12a_ao_media_cpu,
+       &g12a_ao_ahb_sram,
+       &g12a_ao_ahb_bus,
+       &g12a_ao_iface,
+       &g12a_ao_i2c,
+       &g12a_mipi_enable_gate,
+       &g12a_mipi_bandgap_gate,
+#endif
+};
+
+static void __init g12a_clkc_init(struct device_node *np)
+{
+       int ret = 0, clkid, i;
+       struct clk_hw *parent_hw;
+       struct clk *parent_clk;
+
+       /*  Generic clocks and PLLs */
+       clk_base = of_iomap(np, 0);
+       if (!clk_base) {
+               pr_err("%s: Unable to map clk base\n", __func__);
+               /* return -ENXIO; */
+               return;
+       }
+       /* pr_debug("%s: iomap clk_base ok!", __func__); */
+       /* Populate base address for PLLs */
+       for (i = 0; i < ARRAY_SIZE(g12a_clk_plls); i++)
+               g12a_clk_plls[i]->base = clk_base;
+
+       /* Populate base address for MPLLs */
+       for (i = 0; i < ARRAY_SIZE(g12a_clk_mplls); i++)
+               g12a_clk_mplls[i]->base = clk_base;
+
+       /* Populate the base address for CPU clk */
+       g12a_cpu_clk.mux.reg = clk_base + (u64)g12a_cpu_clk.mux.reg;
+       g12a_cpu_fixedpll_p00.reg = clk_base + (u64)g12a_cpu_fixedpll_p00.reg;
+       g12a_cpu_fixedpll_p01.reg = clk_base + (u64)g12a_cpu_fixedpll_p01.reg;
+       g12a_cpu_fixedpll_p10.reg = clk_base + (u64)g12a_cpu_fixedpll_p10.reg;
+       g12a_cpu_fixedpll_p11.reg = clk_base + (u64)g12a_cpu_fixedpll_p11.reg;
+       g12a_cpu_fixedpll_p0.reg = clk_base + (u64)g12a_cpu_fixedpll_p0.reg;
+       g12a_cpu_fixedpll_p1.reg = clk_base + (u64)g12a_cpu_fixedpll_p1.reg;
+       g12a_cpu_fixedpll_p.reg = clk_base + (u64)g12a_cpu_fixedpll_p.reg;
+
+       /* Populate the base address for the MPEG clks */
+       g12a_mpeg_clk_sel.reg = clk_base + (u64)g12a_mpeg_clk_sel.reg;
+       g12a_mpeg_clk_div.reg = clk_base + (u64)g12a_mpeg_clk_div.reg;
+
+       /* Populate base address for gates */
+       for (i = 0; i < ARRAY_SIZE(g12a_clk_gates); i++)
+               g12a_clk_gates[i]->reg = clk_base +
+                       (u64)g12a_clk_gates[i]->reg;
+
+       if (!clks) {
+               clks = kzalloc(NR_CLKS*sizeof(struct clk *), GFP_KERNEL);
+               if (!clks) {
+                       /* pr_err("%s: alloc clks fail!", __func__); */
+                       /* return -ENOMEM; */
+                       return;
+               }
+       }
+
+       if (clks == NULL) {
+               pr_err("%s: error: not kzalloc clks in aoclk!", __func__);
+               return;
+       }
+
+       clk_data.clks = clks;
+       clk_data.clk_num = NR_CLKS;
+       /*
+        * register all clks
+        */
+
+       for (clkid = 0; clkid < ARRAY_SIZE(g12a_clk_hws); clkid++) {
+               if (g12a_clk_hws[clkid]) {
+                       clks[clkid] = clk_register(NULL, g12a_clk_hws[clkid]);
+                       if (IS_ERR(clks[clkid])) {
+                               pr_err("%s: failed to register %s\n", __func__,
+                                       clk_hw_get_name(g12a_clk_hws[clkid]));
+                               goto iounmap;
+                       }
+               }
+       }
+
+       meson_g12a_sdemmc_init();
+       /*g12a_amlogic_init_misc();*/
+
+       pr_debug("%s: register all clk ok!", __func__);
+       /*
+        * Register CPU clk notifier
+        *
+        * FIXME this is wrong for a lot of reasons. First, the muxes should be
+        * struct clk_hw objects. Second, we shouldn't program the muxes in
+        * notifier handlers. The tricky programming sequence will be handled
+        * by the forthcoming coordinated clock rates mechanism once that
+        * feature is released.
+        *
+        * Furthermore, looking up the parent this way is terrible. At some
+        * point we will stop allocating a default struct clk when registering
+        * a new clk_hw, and this hack will no longer work. Releasing the ccr
+        * feature before that time solves the problem :-)
+        */
+       parent_hw = clk_hw_get_parent(&g12a_cpu_clk.mux.hw);
+       parent_clk = parent_hw->clk;
+       ret = clk_notifier_register(parent_clk, &g12a_cpu_clk.clk_nb);
+       if (ret) {
+               pr_err("%s: failed to register clock notifier for cpu_clk\n",
+                               __func__);
+               goto iounmap;
+       }
+       pr_debug("%s: cpu clk register notifier ok!", __func__);
+
+       ret = of_clk_add_provider(np, of_clk_src_onecell_get,
+                       &clk_data);
+       if (ret < 0)
+               pr_err("%s fail ret: %d\n", __func__, ret);
+       else
+               pr_info("%s initialization complete\n", __func__);
+       return;
+
+iounmap:
+       iounmap(clk_base);
+       pr_info("%s: %d: ret: %d\n", __func__, __LINE__, ret);
+       /* return; */
+}
+
+CLK_OF_DECLARE(g12a, "amlogic,g12a-clkc", g12a_clkc_init);
+
+
diff --git a/drivers/amlogic/clk/g12a/g12a.h b/drivers/amlogic/clk/g12a/g12a.h
new file mode 100644 (file)
index 0000000..2a0e36e
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ * drivers/amlogic/clk/g12a/g12a.h
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#ifndef __G12A_H
+#define __G12A_H
+
+/*
+ * Clock controller register offsets
+ *
+ * Register offsets from the data sheet are listed in comment blocks below.
+ * Those offsets must be multiplied by 4 before adding them to the base address
+ * to get the right value
+ */
+
+#define HHI_MIPI_CNTL0                 0x0 /* 0x0 offset in data sheet */
+#define HHI_MIPI_CNTL1                 0x4 /* 0x1 offset in data sheet */
+#define HHI_MIPI_CNTL2                 0x8 /* 0x2 offset in data sheet */
+
+#define HHI_GP0_PLL_CNTL0              0x40 /* 0x10 offset in data sheet */
+
+
+#define HHI_PCIE_PLL_CNTL0             0x98 /* 0x26 offset in data sheet */
+#define HHI_PCIE_PLL_CNTL1             0x9c /* 0x27 offset in data sheet */
+//#define HHI_PCIE_PLL_CNTL6   0xf0 /* 0x3c offset in data sheet */
+
+#define HHI_HIFI_PLL_CNTL0             0xD8 /* 0x36 offset in data sheet */
+
+#define HHI_GCLK_MPEG0                 0x140 /* 0x50 offset in data sheet */
+#define HHI_GCLK_MPEG1                 0x144 /* 0x51 offset in data sheet */
+#define HHI_GCLK_MPEG2                 0x148 /* 0x52 offset in data sheet */
+#if 0
+#define HHI_GCLK_AO                    0x154 /* 0x55 offset in data sheet */
+
+#define HHI_VID_CLK_DIV                0x164 /* 0x59 offset in data sheet */
+#define HHI_SPICC_HCLK_CNTL 0x168 /* 0x5a offset in data sheet */
+#endif
+#define HHI_MPEG_CLK_CNTL              0x174 /* 0x5d offset in data sheet */
+#define HHI_AUD_CLK_CNTL               0x178 /* 0x5e offset in data sheet */
+#define HHI_VID_CLK_CNTL               0x17c /* 0x5f offset in data sheet */
+//#define HHI_AUD_CLK_CNTL2            0x190 /* 0x64 offset in data sheet */
+#define HHI_VID_CLK_CNTL2              0x194 /* 0x65 offset in data sheet */
+#define HHI_SYS_CPU_CLK_CNTL0  0x19c /* 0x67 offset in data sheet */
+
+#define HHI_MALI_CLK_CNTL              0x1b0 /* 0x6c offset in data sheet */
+#define HHI_VPU_CLK_CNTL               0x1bC /* 0x6f offset in data sheet */
+
+#define HHI_HDMI_CLK_CNTL              0x1CC /* 0x73 offset in data sheet */
+
+#define HHI_VDEC_CLK_CNTL              0x1E0 /* 0x78 offset in data sheet */
+#define HHI_VDEC2_CLK_CNTL             0x1E4 /* 0x79 offset in data sheet */
+#define HHI_VDEC3_CLK_CNTL             0x1E8 /* 0x7a offset in data sheet */
+#define HHI_VDEC4_CLK_CNTL             0x1EC /* 0x7b offset in data sheet */
+#define HHI_HDCP22_CLK_CNTL            0x1F0 /* 0x7c offset in data sheet */
+#define HHI_VAPBCLK_CNTL               0x1F4 /* 0x7d offset in data sheet */
+
+#define HHI_VPU_CLKB_CNTL              0x20C /* 0x83 offset in data sheet */
+#define HHI_GEN_CLK_CNTL               0x228 /* 0x8a offset in data sheet */
+
+
+#define HHI_VDIN_MEAS_CLK_CNTL         0x250 /* 0x94 offset in data sheet */
+#define HHI_MIPIDSI_PHY_CLK_CNTL       0x254 /* 0x95 offset in data sheet */
+#define HHI_NAND_CLK_CNTL              0x25C /* 0x97 offset in data sheet */
+#define HHI_SD_EMMC_CLK_CNTL           0x264 /* 0x99 offset in data sheet */
+
+#define HHI_MPLL_CNTL0                 0x278 /* 0x9e offset in data sheet */
+#define HHI_MPLL_CNTL1                 0x27C /* 0x9f offset in data sheet */
+#define HHI_MPLL_CNTL2                 0x280 /* 0xa0 offset in data sheet */
+#define HHI_MPLL_CNTL3                 0x284 /* 0xa1 offset in data sheet */
+#define HHI_MPLL_CNTL4                 0x288 /* 0xa2 offset in data sheet */
+#define HHI_MPLL_CNTL5                 0x28c /* 0xa3 offset in data sheet */
+#define HHI_MPLL_CNTL6                 0x290 /* 0xa4 offset in data sheet */
+#define HHI_MPLL_CNTL7                 0x294 /* 0xa5 offset in data sheet */
+#define HHI_MPLL_CNTL8                 0x298 /* 0xa6 offset in data sheet */
+
+#define HHI_FIX_PLL_CNTL0              0x2A0 /* 0xa8 offset in data sheet */
+#define HHI_FIX_PLL_CNTL1              0x2A4 /* 0xa9 offset in data sheet */
+
+#if 0
+#define HHI_MPLL3_CNTL0                        0x2E0 /* 0xb8 offset in data sheet */
+#define HHI_MPLL3_CNTL1                        0x2E4 /* 0xb9 offset in data sheet */
+#define HHI_PLL_TOP_MISC               0x2E8 /* 0xba offset in data sheet */
+#endif
+#define HHI_SYS_PLL_CNTL0              0x2f4 /* 0xbd offset in data sheet */
+#define HHI_SYS_PLL_CNTL1              0x2f8 /* 0xbe offset in data sheet */
+#define HHI_SYS_PLL_CNTL2              0x2fc /* 0xbf offset in data sheet */
+#define HHI_SYS_PLL_CNTL3              0x300 /* 0xc0 offset in data sheet */
+#define HHI_SYS_PLL_CNTL4              0x304 /* 0xc1 offset in data sheet */
+#define HHI_SYS_PLL_CNTL5              0x308 /* 0xc2 offset in data sheet */
+#define HHI_SYS_PLL_CNTL6              0x30c /* 0xc3 offset in data sheet */
+
+/*G12A: pll: FDCO: 3G~6G FDCO = 24*(M+frac)/N
+ *N: recommend is 1
+ *clk_out = FDCO >> OD
+ */
+static const struct pll_rate_table g12a_pll_rate_table[] = {
+       PLL_RATE(24000000,  128, 1, 7), /*DCO=3072M*/
+       PLL_RATE(48000000,  128, 1, 6), /*DCO=3072M*/
+       PLL_RATE(96000000,  128, 1, 5), /*DCO=3072M*/
+       PLL_RATE(192000000,  128, 1, 4), /*DCO=3072M*/
+       PLL_RATE(312000000,  208, 1, 4), /*DCO=4992M*/
+       PLL_RATE(408000000,  136, 1, 3), /*DCO=3264M*/
+       PLL_RATE(600000000,  200, 1, 3), /*DCO=4800M*/
+       PLL_RATE(696000000,  232, 1, 3), /*DCO=5568M*/
+       PLL_RATE(792000000,  132, 1, 2), /*DCO=3168M*/
+       PLL_RATE(912000000,  152, 1, 2), /*DCO=3648M*/
+
+       { /* sentinel */ },
+};
+
+/*PCIE clk_out = 24M*m/2/2/OD*/
+static const struct pll_rate_table g12a_pcie_pll_rate_table[] = {
+       PLL_RATE(100000000, 150, 0, 9),
+       { /* sentinel */ },
+};
+#endif /* __G12A_H */
diff --git a/drivers/amlogic/clk/g12a/g12a_clk-mpll.c b/drivers/amlogic/clk/g12a/g12a_clk-mpll.c
new file mode 100644 (file)
index 0000000..4ba61d7
--- /dev/null
@@ -0,0 +1,170 @@
+/*
+ * drivers/amlogic/clk/g12a/g12a_clk-mpll.c
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+/*
+ * MultiPhase Locked Loops are outputs from a PLL with additional frequency
+ * scaling capabilities. MPLL rates are calculated as:
+ *
+ * f(N2_integer, SDM_IN ) = 2.0G/(N2_integer + SDM_IN/16384)
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+
+#include "../clkc.h"
+/* #undef pr_debug */
+/* #define pr_debug pr_info */
+#define SDM_MAX 16384
+#define MAX_RATE       500000000
+#define MIN_RATE       7830000
+
+#define G12A_MPLL_CNTL0 0x00000543
+#define G12A_MPLL_CNTL2 0x40000033
+
+
+#define to_meson_clk_mpll(_hw) container_of(_hw, struct meson_clk_mpll, hw)
+
+static unsigned long mpll_recalc_rate(struct clk_hw *hw,
+               unsigned long parent_rate)
+{
+       struct meson_clk_mpll *mpll = to_meson_clk_mpll(hw);
+       struct parm *p;
+       unsigned long rate = 0;
+       unsigned long reg, sdm, n2;
+
+       p = &mpll->sdm;
+       reg = readl(mpll->base + p->reg_off);
+       sdm = PARM_GET(p->width, p->shift, reg);
+
+       p = &mpll->n2;
+       reg = readl(mpll->base + p->reg_off);
+       n2 = PARM_GET(p->width, p->shift, reg);
+
+       rate = (parent_rate * SDM_MAX) / ((SDM_MAX * n2) + sdm);
+
+       return rate;
+}
+
+static long meson_clk_pll_round_rate(struct clk_hw *hw, unsigned long rate,
+                                    unsigned long *parent_rate)
+{
+       unsigned long rate_val = rate;
+
+       if (rate_val < MIN_RATE)
+               rate = MIN_RATE;
+       if (rate_val > MAX_RATE)
+               rate = MAX_RATE;
+
+       return rate_val;
+}
+
+
+static int mpll_set_rate(struct clk_hw *hw, unsigned long rate,
+                               unsigned long parent_rate)
+{
+       struct meson_clk_mpll *mpll = to_meson_clk_mpll(hw);
+       struct parm *p;
+       unsigned long reg, sdm, n2;
+       unsigned long flags = 0;
+
+       if ((rate > MAX_RATE) || (rate < MIN_RATE)) {
+               pr_err("Err: can not set rate to %lu!\n", rate);
+               pr_err("Range[5000000 - 500000000]\n");
+               return -1;
+       }
+
+       if (mpll->lock)
+               spin_lock_irqsave(mpll->lock, flags);
+
+       /* calculate new n2 and sdm */
+       n2 = parent_rate / rate;
+       sdm = DIV_ROUND_UP((parent_rate - n2 * rate) * SDM_MAX, rate);
+       if (sdm >= SDM_MAX)
+               sdm = SDM_MAX - 1;
+
+       pr_debug("%s: sdm: %lu n2: %lu rate: %lu parent_rate: %lu\n",
+               __func__, sdm, n2, rate, parent_rate);
+
+       writel(G12A_MPLL_CNTL0, mpll->base + mpll->mpll_cntl0_reg);
+
+       p = &mpll->sdm;
+       writel(G12A_MPLL_CNTL2, mpll->base + p->reg_off + (u64)(1*4));
+       reg = readl(mpll->base + p->reg_off);
+       reg = PARM_SET(p->width, p->shift, reg, sdm);
+       p = &mpll->n2;
+       reg = PARM_SET(p->width, p->shift, reg, n2);
+       reg = PARM_SET(1, mpll->sdm_en, reg, 1);
+       reg = PARM_SET(1, mpll->en_dds, reg, 1);
+       writel(reg, mpll->base + p->reg_off);
+
+       if (mpll->lock)
+               spin_unlock_irqrestore(mpll->lock, flags);
+
+       return 0;
+}
+
+static int mpll_enable(struct clk_hw *hw)
+{
+       struct meson_clk_mpll *mpll = to_meson_clk_mpll(hw);
+       struct parm *p = &mpll->sdm;
+       unsigned long reg;
+       unsigned long flags = 0;
+
+       if (mpll->lock)
+               spin_lock_irqsave(mpll->lock, flags);
+
+       reg = readl(mpll->base + p->reg_off);
+       reg = PARM_SET(1, mpll->sdm_en, reg, 1);
+       reg = PARM_SET(1, mpll->en_dds, reg, 1);
+       writel(reg, mpll->base + p->reg_off);
+
+       if (mpll->lock)
+               spin_unlock_irqrestore(mpll->lock, flags);
+
+       return 0;
+}
+
+static void mpll_disable(struct clk_hw *hw)
+{
+       struct meson_clk_mpll *mpll = to_meson_clk_mpll(hw);
+       struct parm *p = &mpll->sdm;
+       unsigned long reg;
+       unsigned long flags = 0;
+
+       if (mpll->lock)
+               spin_lock_irqsave(mpll->lock, flags);
+
+       reg = readl(mpll->base + p->reg_off);
+       reg = PARM_SET(1, mpll->sdm_en, reg, 0);
+       reg = PARM_SET(1, mpll->en_dds, reg, 0);
+       writel(reg, mpll->base + p->reg_off);
+
+       if (mpll->lock)
+               spin_unlock_irqrestore(mpll->lock, flags);
+}
+
+const struct clk_ops meson_g12a_mpll_ops = {
+       .recalc_rate = mpll_recalc_rate,
+       .round_rate     = meson_clk_pll_round_rate,
+       .set_rate = mpll_set_rate,
+       .enable = mpll_enable,
+       .disable = mpll_disable,
+};
+
+const struct clk_ops meson_g12a_mpll_ro_ops = {
+       .recalc_rate = mpll_recalc_rate,
+};
diff --git a/drivers/amlogic/clk/g12a/g12a_clk-pll.c b/drivers/amlogic/clk/g12a/g12a_clk-pll.c
new file mode 100644 (file)
index 0000000..e000115
--- /dev/null
@@ -0,0 +1,392 @@
+/*
+ * drivers/amlogic/clk/g12a/g12a_clk-pll.c
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+/*
+ * In the most basic form, a Meson PLL is composed as follows:
+ *
+ *                     PLL
+ *      +------------------------------+
+ *      |                              |
+ * in -----[ /N ]---[ *M ]---[ >>OD ]----->> out
+ *      |         ^        ^           |
+ *      +------------------------------+
+ *                |        |
+ *               FREF     VCO
+ *
+ * out = (in * M / N) >> OD
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/amlogic/cpu_version.h>
+#include <dt-bindings/clock/amlogic,g12a-clkc.h>
+
+#include "../clkc.h"
+
+#define MESON_PLL_RESET                                BIT(29)
+#define MESON_PLL_ENABLE                       BIT(28)
+#define MESON_PLL_LOCK                         BIT(31)
+
+/* G12A */
+
+//#define G12A_PCIE_PLL_CNTL 0x400106c8
+#define G12A_PCIE_PLL_CNTL1  0x00000000
+#define G12A_PCIE_PLL_CNTL2  0x00001000
+#define G12A_PCIE_PLL_CNTL3  0x10058e00
+#define G12A_PCIE_PLL_CNTL4  0x000100c0
+#define G12A_PCIE_PLL_CNTL4_ 0x008100c0
+#define G12A_PCIE_PLL_CNTL5  0x28000048
+#define G12A_PCIE_PLL_CNTL5_ 0x28000068
+
+#define G12A_PLL_CNTL1 0x00000000
+#define G12A_PLL_CNTL2 0x00000000
+#define G12A_PLL_CNTL3 0x0a691c20
+#define G12A_PLL_CNTL4 0x33071290
+#define G12A_PLL_CNTL5 0x39270000
+#define G12A_PLL_CNTL6 0x50540000
+
+
+#define to_meson_clk_pll(_hw) container_of(_hw, struct meson_clk_pll, hw)
+
+static unsigned long meson_g12a_pll_recalc_rate(struct clk_hw *hw,
+                                               unsigned long parent_rate)
+{
+       struct meson_clk_pll *pll = to_meson_clk_pll(hw);
+       struct parm *p;
+       unsigned long parent_rate_mhz = parent_rate;
+       unsigned long rate_mhz;
+       u16 n, m, od, od2 = 0;
+       u32 reg, frac = 0;
+
+       p = &pll->n;
+       reg = readl(pll->base + p->reg_off);
+       n = PARM_GET(p->width, p->shift, reg);
+
+       p = &pll->m;
+       reg = readl(pll->base + p->reg_off);
+       m = PARM_GET(p->width, p->shift, reg);
+
+       p = &pll->od;
+       reg = readl(pll->base + p->reg_off);
+       od = PARM_GET(p->width, p->shift, reg);
+
+       p = &pll->od2;
+       if (p->width) {
+               reg = readl(pll->base + p->reg_off);
+               od2 = PARM_GET(p->width, p->shift, reg);
+       }
+
+       p = &pll->frac;
+
+       if (p->width) {
+               reg = readl(pll->base + p->reg_off);
+               frac = PARM_GET(p->width - 1, p->shift, reg);
+
+               if (reg & (1 << (p->width - 1)))
+                       rate_mhz = (parent_rate_mhz * m -
+                               ((parent_rate_mhz * frac)
+                               >> (p->width - 2))) / n;
+               else
+                       rate_mhz = (parent_rate_mhz * m +
+                               ((parent_rate_mhz * frac)
+                               >> (p->width - 2))) / n;
+
+               if (!strcmp(clk_hw_get_name(hw), "pcie_pll"))
+                       rate_mhz = rate_mhz/4/od;
+               else
+                       rate_mhz = rate_mhz >> od;
+       } else {
+               if (!strcmp(clk_hw_get_name(hw), "pcie_pll"))
+                       rate_mhz = (parent_rate_mhz * m / n) / 4 / od;
+               else
+                       rate_mhz = (parent_rate_mhz * m / n) >> od >> od2;
+       }
+
+       return rate_mhz;
+}
+
+static long meson_g12a_pll_round_rate(struct clk_hw *hw, unsigned long rate,
+                                    unsigned long *parent_rate)
+{
+       struct meson_clk_pll *pll = to_meson_clk_pll(hw);
+       const struct pll_rate_table *rate_table = pll->rate_table;
+       int i;
+
+       for (i = 0; i < pll->rate_count; i++) {
+               if (rate <= rate_table[i].rate)
+                       return rate_table[i].rate;
+       }
+
+       /* else return the smallest value */
+       return rate_table[0].rate;
+}
+
+static const struct pll_rate_table *meson_g12a_get_pll_settings
+       (struct meson_clk_pll *pll, unsigned long rate)
+{
+       const struct pll_rate_table *rate_table = pll->rate_table;
+       int i;
+
+       for (i = 0; i < pll->rate_count; i++) {
+               if (rate == rate_table[i].rate)
+                       return &rate_table[i];
+       }
+       return NULL;
+}
+
+static int meson_g12a_pll_wait_lock(struct meson_clk_pll *pll,
+                                  struct parm *p_n)
+{
+       int delay = 24000000;
+       u32 reg;
+
+       while (delay > 0) {
+               reg = readl(pll->base + p_n->reg_off);
+
+               if (reg & MESON_PLL_LOCK)
+                       return 0;
+               delay--;
+       }
+       return -ETIMEDOUT;
+}
+
+static int meson_g12a_pll_set_rate(struct clk_hw *hw, unsigned long rate,
+                                 unsigned long parent_rate)
+{
+       struct meson_clk_pll *pll = to_meson_clk_pll(hw);
+       struct parm *p;
+       const struct pll_rate_table *rate_set;
+       unsigned long old_rate;
+       int ret = 0;
+       u32 reg;
+       unsigned long flags = 0;
+
+       if (parent_rate == 0 || rate == 0)
+               return -EINVAL;
+
+       old_rate = rate;
+
+       rate_set = meson_g12a_get_pll_settings(pll, rate);
+       if (!rate_set)
+               return -EINVAL;
+
+       p = &pll->n;
+
+       if (pll->lock)
+               spin_lock_irqsave(pll->lock, flags);
+
+       if (readl(pll->base + p->reg_off) & MESON_PLL_ENABLE) {
+               old_rate = meson_g12a_pll_recalc_rate(hw, parent_rate);
+               old_rate = meson_g12a_pll_round_rate(hw, old_rate, NULL);
+
+               if (old_rate == rate) {
+                       if (pll->lock)
+                               spin_unlock_irqrestore(pll->lock, flags);
+                       return ret;
+               }
+       }
+
+       if (!strcmp(clk_hw_get_name(hw), "gp0_pll")
+               || !strcmp(clk_hw_get_name(hw), "hifi_pll")
+               || !strcmp(clk_hw_get_name(hw), "pcie_pll")
+               || !strcmp(clk_hw_get_name(hw), "sys_pll")) {
+               void *cntlbase = pll->base + p->reg_off;
+
+               writel((readl(cntlbase) | MESON_PLL_RESET)
+                       & (~MESON_PLL_ENABLE), cntlbase);
+
+               if (!strcmp(clk_hw_get_name(hw), "pcie_pll")) {
+                       writel(G12A_PCIE_PLL_CNTL1, cntlbase + (u64)(1*4));
+                       writel(G12A_PCIE_PLL_CNTL2, cntlbase + (u64)(2*4));
+                       writel(G12A_PCIE_PLL_CNTL3, cntlbase + (u64)(3*4));
+                       writel(G12A_PCIE_PLL_CNTL4, cntlbase + (u64)(4*4));
+                       writel(G12A_PCIE_PLL_CNTL5, cntlbase + (u64)(5*4));
+                       writel(G12A_PCIE_PLL_CNTL5_, cntlbase + (u64)(5*4));
+                       udelay(20);
+                       writel(G12A_PCIE_PLL_CNTL4_, cntlbase + (u64)(4*4));
+                       udelay(10);
+                       /*set pcie_apll_afc_start bit*/
+                       writel(readl(cntlbase) | (1 << 26), cntlbase);
+                       udelay(10);
+               } else {
+                       writel(G12A_PLL_CNTL1, cntlbase + (u64)1*4);
+                       writel(G12A_PLL_CNTL2, cntlbase + (u64)2*4);
+                       writel(G12A_PLL_CNTL3, cntlbase + (u64)3*4);
+                       writel(G12A_PLL_CNTL4, cntlbase + (u64)4*4);
+                       writel(G12A_PLL_CNTL5, cntlbase + (u64)5*4);
+                       writel(G12A_PLL_CNTL6, cntlbase + (u64)6*4);
+                       udelay(10);
+               }
+       } else {
+               pr_err("%s: %s pll not found!!!\n",
+                       __func__, clk_hw_get_name(hw));
+               return -EINVAL;
+       }
+
+       reg = readl(pll->base + p->reg_off);
+
+       reg = PARM_SET(p->width, p->shift, reg, rate_set->n);
+       writel(reg, pll->base + p->reg_off);
+
+       p = &pll->m;
+       reg = readl(pll->base + p->reg_off);
+       reg = PARM_SET(p->width, p->shift, reg, rate_set->m);
+       writel(reg, pll->base + p->reg_off);
+
+       p = &pll->od;
+       /*check OD width*/
+       if (rate_set->od >> p->width) {
+               ret = -EINVAL;
+               pr_warn("%s: OD width is wrong at rate %lu !!\n",
+                       __func__, rate);
+               goto OUT;
+       }
+       reg = readl(pll->base + p->reg_off);
+       reg = PARM_SET(p->width, p->shift, reg, rate_set->od);
+       writel(reg, pll->base + p->reg_off);
+
+       p = &pll->od2;
+       if (p->width) {
+               reg = readl(pll->base + p->reg_off);
+               reg = PARM_SET(p->width, p->shift, reg, rate_set->od2);
+               writel(reg, pll->base + p->reg_off);
+       }
+
+       p = &pll->frac;
+       if (p->width) {
+               reg = readl(pll->base + p->reg_off);
+               reg = PARM_SET(p->width, p->shift, reg, rate_set->frac);
+               writel(reg, pll->base + p->reg_off);
+       }
+
+       p = &pll->n;
+
+       /* PLL reset */
+       writel(readl(pll->base + p->reg_off) | MESON_PLL_ENABLE,
+               pll->base + p->reg_off);
+       udelay(10);
+       writel(readl(pll->base + p->reg_off) & (~MESON_PLL_RESET),
+               pll->base + p->reg_off);
+       ret = meson_g12a_pll_wait_lock(pll, p);
+
+OUT:
+       if (pll->lock)
+               spin_unlock_irqrestore(pll->lock, flags);
+
+       if (ret) {
+               pr_warn("%s: pll did not lock, trying to lock rate %lu again\n",
+                       __func__, rate);
+               meson_g12a_pll_set_rate(hw, rate, parent_rate);
+       }
+
+       return ret;
+}
+
+static int meson_g12a_pll_enable(struct clk_hw *hw)
+{
+       struct meson_clk_pll *pll = to_meson_clk_pll(hw);
+       struct parm *p;
+       int ret = 0;
+       unsigned long flags = 0;
+       unsigned long first_set = 1;
+       struct clk *parent;
+       unsigned long rate;
+
+       p = &pll->n;
+
+       if (pll->lock)
+               spin_lock_irqsave(pll->lock, flags);
+
+       if (readl(pll->base + p->reg_off) & MESON_PLL_ENABLE) {
+               if (pll->lock)
+                       spin_unlock_irqrestore(pll->lock, flags);
+               return ret;
+       }
+
+       if (!strcmp(clk_hw_get_name(hw), "gp0_pll")
+               || !strcmp(clk_hw_get_name(hw), "hifi_pll")
+               || !strcmp(clk_hw_get_name(hw), "pcie_pll")
+               || !strcmp(clk_hw_get_name(hw), "sys_pll")) {
+               void *cntlbase = pll->base + p->reg_off;
+
+               if (!strcmp(clk_hw_get_name(hw), "pcie_pll")) {
+                       if (readl(cntlbase + (u64)(3*4)) == G12A_PCIE_PLL_CNTL3)
+                               first_set = 0;
+               } else {
+                       if (readl(cntlbase + (u64)(6*4)) == G12A_PLL_CNTL6)
+                               first_set = 0;
+               }
+       }
+
+       parent = clk_get_parent(hw->clk);
+
+       /*First init, just set minimal rate.*/
+       if (first_set)
+               rate = pll->rate_table[0].rate;
+       else {
+               rate = meson_g12a_pll_recalc_rate(hw, clk_get_rate(parent));
+               rate = meson_g12a_pll_round_rate(hw, rate, NULL);
+       }
+
+       if (pll->lock)
+               spin_unlock_irqrestore(pll->lock, flags);
+
+       ret = meson_g12a_pll_set_rate(hw, rate, clk_get_rate(parent));
+
+       return ret;
+}
+
+static void meson_g12a_pll_disable(struct clk_hw *hw)
+{
+       struct meson_clk_pll *pll = to_meson_clk_pll(hw);
+       struct parm *p = &pll->n;
+       unsigned long flags = 0;
+
+       if (!strcmp(clk_hw_get_name(hw), "gp0_pll")
+                       || !strcmp(clk_hw_get_name(hw), "hifi_pll")
+                       || !strcmp(clk_hw_get_name(hw), "pcie_pll")) {
+               if (pll->lock)
+                       spin_lock_irqsave(pll->lock, flags);
+
+               writel(readl(pll->base + p->reg_off) & (~MESON_PLL_ENABLE),
+                       pll->base + p->reg_off);
+
+               if (pll->lock)
+                       spin_unlock_irqrestore(pll->lock, flags);
+       }
+
+}
+
+const struct clk_ops meson_g12a_pll_ops = {
+       .recalc_rate    = meson_g12a_pll_recalc_rate,
+       .round_rate     = meson_g12a_pll_round_rate,
+       .set_rate       = meson_g12a_pll_set_rate,
+       .enable         = meson_g12a_pll_enable,
+       .disable        = meson_g12a_pll_disable,
+};
+
+const struct clk_ops meson_g12a_pll_ro_ops = {
+       .recalc_rate    = meson_g12a_pll_recalc_rate,
+};
+
diff --git a/drivers/amlogic/clk/g12a/g12a_clk_sdemmc.c b/drivers/amlogic/clk/g12a/g12a_clk_sdemmc.c
new file mode 100644 (file)
index 0000000..acd96e0
--- /dev/null
@@ -0,0 +1,169 @@
+/*
+ * drivers/amlogic/clk/g12a/g12a_clk_sdemmc.c
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <dt-bindings/clock/amlogic,g12a-clkc.h>
+
+#include "../clkc.h"
+#include "g12a.h"
+
+static const char * const sd_emmc_parent_names[] = { "xtal", "fclk_div2",
+       "fclk_div3", "fclk_div5", "fclk_div7", "mpll2", "mpll3", "gp0" };
+
+static struct clk_mux sd_emmc_p0_mux_B = {
+       .reg = (void *)HHI_SD_EMMC_CLK_CNTL,
+       .mask = 0x7,
+       .shift = 25,
+       .lock = &clk_lock,
+       .hw.init = &(struct clk_init_data){
+               .name = "sd_emmc_p0_mux_B",
+               .ops = &clk_mux_ops,
+               .parent_names = sd_emmc_parent_names,
+               .num_parents = 8,
+               .flags = (CLK_GET_RATE_NOCACHE | CLK_IGNORE_UNUSED),
+       },
+};
+
+static struct clk_divider sd_emmc_p0_div_B = {
+       .reg = (void *)HHI_SD_EMMC_CLK_CNTL,
+       .shift = 16,
+       .width = 7,
+       .lock = &clk_lock,
+       .hw.init = &(struct clk_init_data){
+               .name = "sd_emmc_p0_div_B",
+               .ops = &clk_divider_ops,
+               .parent_names = (const char *[]){ "sd_emmc_p0_mux_B" },
+               .num_parents = 1,
+               .flags = (CLK_GET_RATE_NOCACHE | CLK_IGNORE_UNUSED),
+       },
+};
+
+static struct clk_gate sd_emmc_p0_gate_B = {
+       .reg = (void *)HHI_SD_EMMC_CLK_CNTL,
+       .bit_idx = 23,
+       .lock = &clk_lock,
+       .hw.init = &(struct clk_init_data) {
+               .name = "sd_emmc_p0_gate_B",
+               .ops = &clk_gate_ops,
+               .parent_names = (const char *[]){ "sd_emmc_p0_div_B" },
+               .num_parents = 1,
+               .flags = (CLK_GET_RATE_NOCACHE | CLK_IGNORE_UNUSED),
+       },
+};
+
+static struct clk_mux sd_emmc_p0_mux_C = {
+       .reg = (void *)HHI_NAND_CLK_CNTL,
+       .mask = 0x7,
+       .shift = 9,
+       .lock = &clk_lock,
+       .hw.init = &(struct clk_init_data){
+               .name = "sd_emmc_p0_mux_C",
+               .ops = &clk_mux_ops,
+               .parent_names = sd_emmc_parent_names,
+               .num_parents = 8,
+               .flags = (CLK_GET_RATE_NOCACHE | CLK_IGNORE_UNUSED),
+       },
+};
+
+static struct clk_divider sd_emmc_p0_div_C = {
+       .reg = (void *)HHI_NAND_CLK_CNTL,
+       .shift = 0,
+       .width = 7,
+       .lock = &clk_lock,
+       .hw.init = &(struct clk_init_data){
+               .name = "sd_emmc_p0_div_C",
+               .ops = &clk_divider_ops,
+               .parent_names = (const char *[]){ "sd_emmc_p0_mux_C" },
+               .num_parents = 1,
+               .flags = (CLK_GET_RATE_NOCACHE | CLK_IGNORE_UNUSED),
+       },
+};
+
+static struct clk_gate sd_emmc_p0_gate_C = {
+       .reg = (void *)HHI_NAND_CLK_CNTL,
+       .bit_idx = 7,
+       .lock = &clk_lock,
+       .hw.init = &(struct clk_init_data) {
+               .name = "sd_emmc_p0_gate_C",
+               .ops = &clk_gate_ops,
+               .parent_names = (const char *[]){ "sd_emmc_p0_div_C" },
+               .num_parents = 1,
+               .flags = (CLK_GET_RATE_NOCACHE | CLK_IGNORE_UNUSED),
+       },
+};
+
+static struct clk_hw *sd_emmc_clk_hws[] = {
+       [CLKID_SD_EMMC_B_P0_MUX - CLKID_SD_EMMC_B_P0_MUX]
+               = &sd_emmc_p0_mux_B.hw,
+       [CLKID_SD_EMMC_B_P0_DIV - CLKID_SD_EMMC_B_P0_MUX]
+               = &sd_emmc_p0_div_B.hw,
+       [CLKID_SD_EMMC_B_P0_GATE - CLKID_SD_EMMC_B_P0_MUX]
+               = &sd_emmc_p0_gate_B.hw,
+       [CLKID_SD_EMMC_C_P0_MUX - CLKID_SD_EMMC_B_P0_MUX]
+               = &sd_emmc_p0_mux_C.hw,
+       [CLKID_SD_EMMC_C_P0_DIV - CLKID_SD_EMMC_B_P0_MUX]
+               = &sd_emmc_p0_div_C.hw,
+       [CLKID_SD_EMMC_C_P0_GATE - CLKID_SD_EMMC_B_P0_MUX]
+               = &sd_emmc_p0_gate_C.hw,
+};
+
+
+void meson_g12a_sdemmc_init(void)
+{
+       /* Populate base address for reg */
+       pr_info("%s: register amlogic sdemmc clk\n", __func__);
+
+       sd_emmc_p0_mux_B.reg = clk_base + (u64)(sd_emmc_p0_mux_B.reg);
+       sd_emmc_p0_div_B.reg = clk_base + (u64)(sd_emmc_p0_div_B.reg);
+       sd_emmc_p0_gate_B.reg = clk_base + (u64)(sd_emmc_p0_gate_B.reg);
+       sd_emmc_p0_mux_C.reg = clk_base + (u64)(sd_emmc_p0_mux_C.reg);
+       sd_emmc_p0_div_C.reg = clk_base + (u64)(sd_emmc_p0_div_C.reg);
+       sd_emmc_p0_gate_C.reg = clk_base + (u64)(sd_emmc_p0_gate_C.reg);
+
+       clks[CLKID_SD_EMMC_B_P0_COMP] = clk_register_composite(NULL,
+               "sd_emmc_p0_B_comp",
+           sd_emmc_parent_names, 8,
+           sd_emmc_clk_hws[CLKID_SD_EMMC_B_P0_MUX - CLKID_SD_EMMC_B_P0_MUX],
+           &clk_mux_ops,
+           sd_emmc_clk_hws[CLKID_SD_EMMC_B_P0_DIV - CLKID_SD_EMMC_B_P0_MUX],
+           &clk_divider_ops,
+           sd_emmc_clk_hws[CLKID_SD_EMMC_B_P0_GATE - CLKID_SD_EMMC_B_P0_MUX],
+           &clk_gate_ops, 0);
+       if (IS_ERR(clks[CLKID_SD_EMMC_B_P0_COMP]))
+               pr_err("%s: %d clk_register_composite sd_emmc_p0_B_comp error\n",
+                       __func__, __LINE__);
+
+       clks[CLKID_SD_EMMC_C_P0_COMP] = clk_register_composite(NULL,
+               "sd_emmc_p0_C_comp",
+           sd_emmc_parent_names, 8,
+           sd_emmc_clk_hws[CLKID_SD_EMMC_C_P0_MUX - CLKID_SD_EMMC_B_P0_MUX],
+           &clk_mux_ops,
+           sd_emmc_clk_hws[CLKID_SD_EMMC_C_P0_DIV - CLKID_SD_EMMC_B_P0_MUX],
+           &clk_divider_ops,
+           sd_emmc_clk_hws[CLKID_SD_EMMC_C_P0_GATE - CLKID_SD_EMMC_B_P0_MUX],
+            &clk_gate_ops, 0);
+       if (IS_ERR(clks[CLKID_SD_EMMC_C_P0_COMP]))
+               pr_err("%s: %d clk_register_composite sd_emmc_p0_C_comp error\n",
+                       __func__, __LINE__);
+
+       pr_info("%s: register amlogic sdemmc clk\n", __func__);
+}
index 406a34b..4197d36 100644 (file)
  * CLKID index values
  */
 
-#define CLKID_SYS_PLL       0
-#define CLKID_FIXED_PLL                  1
-#define CLKID_FCLK_DIV2     2
-#define CLKID_FCLK_DIV3     3
-#define CLKID_FCLK_DIV4     4
-#define CLKID_FCLK_DIV5                  5
-#define CLKID_FCLK_DIV7                  6
-#define CLKID_GP0_PLL       7
-#define CLKID_HIFI_PLL      8
-#define CLKID_MPEG_SEL           9
-#define CLKID_MPEG_DIV           10
-#define CLKID_CLK81         11
-#define CLKID_MPLL0              12
-#define CLKID_MPLL1              13
-#define CLKID_MPLL2     14
-#define CLKID_MPLL3              15
-#define CLKID_CPU_FCLK_P00     16
-#define CLKID_CPU_FCLK_P01     17
-#define CLKID_CPU_FCLK_P0      18
-#define CLKID_CPU_FCLK_P10     19
-#define CLKID_CPU_FCLK_P11     20
-#define CLKID_CPU_FCLK_P1      21
-#define CLKID_CPU_FCLK_P       22
-#define CLKID_CPU_CLK          23
-#define CLKID_PCIE_PLL 24
-#define CLKID_PCIE_MUX 25
-#define CLKID_PCIE_REF 26
-#define CLKID_PCIE_INPUT_GATE 27
-#define CLKID_PCIE_CML_EN0 28
-#define CLKID_PCIE_CML_EN1 29
-#define CLKID_MIPI_ENABLE_GATE 30
+#define CLKID_SYS_PLL           0
+#define CLKID_FIXED_PLL         1
+#define CLKID_FCLK_DIV2         2
+#define CLKID_FCLK_DIV3         3
+#define CLKID_FCLK_DIV4         4
+#define CLKID_FCLK_DIV5         5
+#define CLKID_FCLK_DIV7         6
+#define CLKID_GP0_PLL           7
+#define CLKID_HIFI_PLL          8
+#define CLKID_MPEG_SEL          9
+#define CLKID_MPEG_DIV          10
+#define CLKID_CLK81             11
+#define CLKID_MPLL0             12
+#define CLKID_MPLL1             13
+#define CLKID_MPLL2             14
+#define CLKID_MPLL3             15
+#define CLKID_CPU_FCLK_P00      16
+#define CLKID_CPU_FCLK_P01      17
+#define CLKID_CPU_FCLK_P0       18
+#define CLKID_CPU_FCLK_P10      19
+#define CLKID_CPU_FCLK_P11      20
+#define CLKID_CPU_FCLK_P1       21
+#define CLKID_CPU_FCLK_P        22
+#define CLKID_CPU_CLK           23
+#define CLKID_PCIE_PLL          24
+#define CLKID_PCIE_MUX          25
+#define CLKID_PCIE_REF          26
+#define CLKID_PCIE_INPUT_GATE   27
+#define CLKID_PCIE_CML_EN0      28
+#define CLKID_PCIE_CML_EN1      29
+#define CLKID_MIPI_ENABLE_GATE  30
 #define CLKID_MIPI_BANDGAP_GATE 31
+#define CLKID_FCLK_DIV2P5       32
 
 /*HHI_GCLK_MPEG0: 0x50*/
-#define GATE_BASE0    32
-#define CLKID_DDR    (GATE_BASE0 + 0)
-#define CLKID_AUDIO_LOCKER     (GATE_BASE0 + 1)
-#define CLKID_MIPI_DSI_HOST              (GATE_BASE0 + 2)
-#define CLKID_ISA                (GATE_BASE0 + 3)
-#define CLKID_PL301              (GATE_BASE0 + 4)
-#define CLKID_PERIPHS           (GATE_BASE0 + 5)
-#define CLKID_SPICC0             (GATE_BASE0 + 6)
-#define CLKID_I2C         (GATE_BASE0 + 7)
-#define CLKID_RNG0               (GATE_BASE0 + 8)
-#define CLKID_UART0              (GATE_BASE0 + 9)
-#define CLKID_MIPI_DSI_PHY               (GATE_BASE0 + 10)
-#define CLKID_SPICC1             (GATE_BASE0 + 11)
-#define CLKID_PCIE_A     (GATE_BASE0 + 12)
-#define CLKID_PCIE_B             (GATE_BASE0 + 13)
-#define CLKID_HIU_REG            (GATE_BASE0 + 14)
-#define CLKID_ASSIST_MISC        (GATE_BASE0 + 15)
-#define CLKID_SD_EMMC_B        (GATE_BASE0 + 16)
-#define CLKID_SD_EMMC_C        (GATE_BASE0 + 17)
-#define CLKID_DMA      (GATE_BASE0 + 18)
-#define CLKID_SPI (GATE_BASE0 + 19)
+#define GATE_BASE0              33
+#define CLKID_DDR               (GATE_BASE0 + 0)
+#define CLKID_DOS               (GATE_BASE0 + 1)
+#define CLKID_AUDIO_LOCKER      (GATE_BASE0 + 2)
+#define CLKID_MIPI_DSI_HOST     (GATE_BASE0 + 3)
+#define CLKID_ETH_PHY           (GATE_BASE0 + 4)
+#define CLKID_ISA               (GATE_BASE0 + 5)
+#define CLKID_PL301             (GATE_BASE0 + 6)
+#define CLKID_PERIPHS           (GATE_BASE0 + 7)
+#define CLKID_SPICC0            (GATE_BASE0 + 8)
+#define CLKID_I2C               (GATE_BASE0 + 9)
+#define CLKID_SANA              (GATE_BASE0 + 10)
+#define CLKID_SD                (GATE_BASE0 + 11)
+#define CLKID_RNG0              (GATE_BASE0 + 12)
+#define CLKID_UART0             (GATE_BASE0 + 13)
+#define CLKID_SPICC1            (GATE_BASE0 + 14)
+#define CLKID_HIU_REG           (GATE_BASE0 + 15)
+#define CLKID_MIPI_DSI_PHY      (GATE_BASE0 + 16)
+#define CLKID_ASSIST_MISC       (GATE_BASE0 + 17)
+#define CLKID_SD_EMMC_A         (GATE_BASE0 + 18)
+#define CLKID_SD_EMMC_B         (GATE_BASE0 + 19)
+#define CLKID_SD_EMMC_C         (GATE_BASE0 + 20)
+#define CLKID_ACODEC            (GATE_BASE0 + 21)
+
 /*HHI_GCLK_MPEG1: 0x51*/
-#define GATE_BASE1    (GATE_BASE0 + 20) /*28+20*/
-#define CLKID_AUDIO    (GATE_BASE1 + 0)
-#define CLKID_ETH_CORE           (GATE_BASE1 + 1)
-#define CLKID_UART1              (GATE_BASE1 + 2)
-#define CLKID_G2D                (GATE_BASE1 + 3)
-#define CLKID_USB0    (GATE_BASE1 + 4)
-#define CLKID_USB1    (GATE_BASE1 + 5)
-#define CLKID_RESET              (GATE_BASE1 + 6)
-#define CLKID_USB_GENERAL      (GATE_BASE1 + 7)
-#define CLKID_AHB_ARB0           (GATE_BASE1 + 8)
-#define CLKID_EFUSE              (GATE_BASE1 + 9)
-#define CLKID_BOOT_ROM           (GATE_BASE1 + 10)
+#define GATE_BASE1              (GATE_BASE0 + 22)
+#define CLKID_AUDIO             (GATE_BASE1 + 0)
+#define CLKID_ETH_CORE          (GATE_BASE1 + 1)
+#define CLKID_U_STP_TOP         (GATE_BASE1 + 2)
+#define CLKID_AIFIFO            (GATE_BASE1 + 3)
+#define CLKID_ADC               (GATE_BASE1 + 4)
+#define CLKID_UART1             (GATE_BASE1 + 5)
+#define CLKID_G2D               (GATE_BASE1 + 6)
+#define CLKID_RESET             (GATE_BASE1 + 7)
+#define CLKID_PCIE_COMB         (GATE_BASE1 + 8)
+#define CLKID_PARSER            (GATE_BASE1 + 9)
+#define CLKID_USB_GENERAL       (GATE_BASE1 + 10)
+#define CLKID_PCIE_PHY          (GATE_BASE1 + 11)
+#define CLKID_AHB_ARB0          (GATE_BASE1 + 12)
+
 /*HHI_GCLK_MPEG2: 0x52*/
-#define GATE_BASE2    (GATE_BASE1 + 11)  /*28+20+11*/
-#define CLKID_AHB_DATA_BUS       (GATE_BASE2 + 0)
-#define CLKID_AHB_CTRL_BUS       (GATE_BASE2 + 1)
-#define CLKID_USB1_TO_DDR (GATE_BASE2 + 2)
-#define CLKID_USB0_TO_DDR (GATE_BASE2 + 3)
-#define CLKID_MMC_PCLK           (GATE_BASE2 + 4)
-#define CLKID_VPU_INTR           (GATE_BASE2 + 5)
-#define CLKID_SEC_AHB_AHB3_BRIDGE (GATE_BASE2 + 6)
-#define CLKID_GIC                (GATE_BASE2 + 7)
+#define GATE_BASE2              (GATE_BASE1 + 13)
+#define CLKID_AHB_DATA_BUS      (GATE_BASE2 + 0)
+#define CLKID_AHB_CTRL_BUS      (GATE_BASE2 + 1)
+#define CLKID_HTX_HDCP22        (GATE_BASE2 + 2)
+#define CLKID_HTX_PCLK          (GATE_BASE2 + 3)
+#define CLKID_BT656             (GATE_BASE2 + 4)
+#define CLKID_USB1_TO_DDR       (GATE_BASE2 + 5)
+#define CLKID_MMC_PCLK          (GATE_BASE2 + 6)
+#define CLKID_UART2             (GATE_BASE2 + 7)
+#define CLKID_VPU_INTR          (GATE_BASE2 + 8)
+#define CLKID_GIC               (GATE_BASE2 + 9)
 
-#define GATE_AO_BASE (GATE_BASE2 + 8) /*28+20+11+8*/
-#define CLKID_AO_MEDIA_CPU       (GATE_AO_BASE + 0)
-#define CLKID_AO_AHB_SRAM        (GATE_AO_BASE + 1)
-#define CLKID_AO_AHB_BUS         (GATE_AO_BASE + 2)
-#define CLKID_AO_IFACE           (GATE_AO_BASE + 3)
-#define CLKID_AO_I2C   (GATE_AO_BASE + 4)
+#define GATE_AO_BASE            (GATE_BASE2 + 10)
+#define CLKID_AO_MEDIA_CPU      (GATE_AO_BASE + 0)
+#define CLKID_AO_AHB_SRAM       (GATE_AO_BASE + 1)
+#define CLKID_AO_AHB_BUS        (GATE_AO_BASE + 2)
+#define CLKID_AO_IFACE          (GATE_AO_BASE + 3)
+#define CLKID_AO_I2C            (GATE_AO_BASE + 4)
 
-#define OTHER_BASE (GATE_AO_BASE + 5) /*28+20+11+8+5=72*/
-#define CLKID_SD_EMMC_B_P0_MUX (OTHER_BASE + 0)
-#define CLKID_SD_EMMC_B_P0_DIV (OTHER_BASE + 1)
+#define OTHER_BASE              (GATE_AO_BASE + 5)
+#define CLKID_SD_EMMC_B_P0_MUX  (OTHER_BASE + 0)
+#define CLKID_SD_EMMC_B_P0_DIV  (OTHER_BASE + 1)
 #define CLKID_SD_EMMC_B_P0_GATE (OTHER_BASE + 2)
 #define CLKID_SD_EMMC_B_P0_COMP (OTHER_BASE + 3)
-#define CLKID_SD_EMMC_C_P0_MUX (OTHER_BASE + 4)
-#define CLKID_SD_EMMC_C_P0_DIV (OTHER_BASE + 5)
+#define CLKID_SD_EMMC_C_P0_MUX  (OTHER_BASE + 4)
+#define CLKID_SD_EMMC_C_P0_DIV  (OTHER_BASE + 5)
 #define CLKID_SD_EMMC_C_P0_GATE (OTHER_BASE + 6)
 #define CLKID_SD_EMMC_C_P0_COMP (OTHER_BASE + 7)
-#define CLKID_SD_EMMC_B_MUX     (OTHER_BASE + 8)
-#define CLKID_SD_EMMC_B_DIV     (OTHER_BASE + 9)
-#define CLKID_SD_EMMC_B_GATE    (OTHER_BASE + 10)
-#define CLKID_SD_EMMC_B_COMP  (OTHER_BASE + 11)
-#define CLKID_SD_EMMC_C_MUX     (OTHER_BASE + 12)
-#define CLKID_SD_EMMC_C_DIV     (OTHER_BASE + 13)
-#define CLKID_SD_EMMC_C_GATE    (OTHER_BASE + 14)
-#define CLKID_SD_EMMC_C_COMP  (OTHER_BASE + 15)
+#define CLKID_SD_EMMC_B_MUX     (OTHER_BASE + 8)
+#define CLKID_SD_EMMC_B_DIV     (OTHER_BASE + 9)
+#define CLKID_SD_EMMC_B_GATE    (OTHER_BASE + 10)
+#define CLKID_SD_EMMC_B_COMP    (OTHER_BASE + 11)
+#define CLKID_SD_EMMC_C_MUX     (OTHER_BASE + 12)
+#define CLKID_SD_EMMC_C_DIV     (OTHER_BASE + 13)
+#define CLKID_SD_EMMC_C_GATE    (OTHER_BASE + 14)
+#define CLKID_SD_EMMC_C_COMP    (OTHER_BASE + 15)
+
+#define CLKID_GPU_BASE          (OTHER_BASE + 16)
+#define CLKID_GPU_P0_MUX        (CLKID_GPU_BASE + 0)
+#define CLKID_GPU_P0_DIV        (CLKID_GPU_BASE + 1)
+#define CLKID_GPU_P0_GATE       (CLKID_GPU_BASE + 2)
+#define CLKID_GPU_P0_COMP       (CLKID_GPU_BASE + 3)
+#define CLKID_GPU_P1_MUX        (CLKID_GPU_BASE + 4)
+#define CLKID_GPU_P1_DIV        (CLKID_GPU_BASE + 5)
+#define CLKID_GPU_P1_GATE       (CLKID_GPU_BASE + 6)
+#define CLKID_GPU_P1_COMP       (CLKID_GPU_BASE + 7)
+#define CLKID_GPU_MUX           (CLKID_GPU_BASE + 8)
 
-#define CLKID_MEDIA_BASE (OTHER_BASE + 16) /*28+20+11+8+5+16*/
-#define CLKID_VPU_P0_MUX (CLKID_MEDIA_BASE + 0)
-#define CLKID_VPU_P0_DIV (CLKID_MEDIA_BASE + 1)
-#define CLKID_VPU_P0_GATE (CLKID_MEDIA_BASE + 2)
-#define CLKID_VPU_P0_COMP (CLKID_MEDIA_BASE + 3)
-#define CLKID_VPU_P1_MUX (CLKID_MEDIA_BASE + 4)
-#define CLKID_VPU_P1_DIV (CLKID_MEDIA_BASE + 5)
-#define CLKID_VPU_P1_GATE (CLKID_MEDIA_BASE + 6)
-#define CLKID_VPU_P1_COMP (CLKID_MEDIA_BASE + 7)
-#define CLKID_VPU_MUX (CLKID_MEDIA_BASE + 8)
-#define CLKID_VAPB_P0_MUX (CLKID_MEDIA_BASE + 9)
-#define CLKID_VAPB_P0_DIV (CLKID_MEDIA_BASE + 10)
-#define CLKID_VAPB_P0_GATE (CLKID_MEDIA_BASE + 11)
-#define CLKID_VAPB_P0_COMP (CLKID_MEDIA_BASE + 12)
-#define CLKID_VAPB_P1_MUX (CLKID_MEDIA_BASE + 13)
-#define CLKID_VAPB_P1_DIV (CLKID_MEDIA_BASE + 14)
-#define CLKID_VAPB_P1_GATE (CLKID_MEDIA_BASE + 15)
-#define CLKID_VAPB_P1_COMP (CLKID_MEDIA_BASE + 16)
-#define CLKID_VAPB_MUX (CLKID_MEDIA_BASE + 17)
-#define CLKID_GE2D_GATE (CLKID_MEDIA_BASE + 18)
-#define CLKID_DSI_MEAS_MUX (CLKID_MEDIA_BASE + 19)
-#define CLKID_DSI_MEAS_DIV (CLKID_MEDIA_BASE + 20)
-#define CLKID_DSI_MEAS_GATE (CLKID_MEDIA_BASE + 21)
-#define CLKID_DSI_MEAS_COMP (CLKID_MEDIA_BASE + 22)
+#define CLKID_MEDIA_BASE        (CLKID_GPU_BASE + 9)
+#define CLKID_VPU_P0_MUX        (CLKID_MEDIA_BASE + 0)
+#define CLKID_VPU_P0_DIV        (CLKID_MEDIA_BASE + 1)
+#define CLKID_VPU_P0_GATE       (CLKID_MEDIA_BASE + 2)
+#define CLKID_VPU_P0_COMP       (CLKID_MEDIA_BASE + 3)
+#define CLKID_VPU_P1_MUX        (CLKID_MEDIA_BASE + 4)
+#define CLKID_VPU_P1_DIV        (CLKID_MEDIA_BASE + 5)
+#define CLKID_VPU_P1_GATE       (CLKID_MEDIA_BASE + 6)
+#define CLKID_VPU_P1_COMP       (CLKID_MEDIA_BASE + 7)
+#define CLKID_VPU_MUX           (CLKID_MEDIA_BASE + 8)
+#define CLKID_VAPB_P0_MUX       (CLKID_MEDIA_BASE + 9)
+#define CLKID_VAPB_P0_DIV       (CLKID_MEDIA_BASE + 10)
+#define CLKID_VAPB_P0_GATE      (CLKID_MEDIA_BASE + 11)
+#define CLKID_VAPB_P0_COMP      (CLKID_MEDIA_BASE + 12)
+#define CLKID_VAPB_P1_MUX       (CLKID_MEDIA_BASE + 13)
+#define CLKID_VAPB_P1_DIV       (CLKID_MEDIA_BASE + 14)
+#define CLKID_VAPB_P1_GATE      (CLKID_MEDIA_BASE + 15)
+#define CLKID_VAPB_P1_COMP      (CLKID_MEDIA_BASE + 16)
+#define CLKID_VAPB_MUX          (CLKID_MEDIA_BASE + 17)
+#define CLKID_GE2D_GATE         (CLKID_MEDIA_BASE + 18)
+#define CLKID_DSI_MEAS_MUX      (CLKID_MEDIA_BASE + 19)
+#define CLKID_DSI_MEAS_DIV      (CLKID_MEDIA_BASE + 20)
+#define CLKID_DSI_MEAS_GATE     (CLKID_MEDIA_BASE + 21)
+#define CLKID_DSI_MEAS_COMP     (CLKID_MEDIA_BASE + 22)
+#define CLKID_VPU_CLKB_TMP_COMP (CLKID_MEDIA_BASE + 23)
+#define CLKID_VPU_CLKB_COMP     (CLKID_MEDIA_BASE + 24)
 
-#define CLKID_MISC_BASE (CLKID_MEDIA_BASE + 23) /*28+20+11+8+5+16+23 = 111*/
-#define CLKID_SPICC_MUX (CLKID_MISC_BASE + 0)
-#define CLKID_SPICC_DIV (CLKID_MISC_BASE + 1)
-#define CLKID_SPICC_GATE (CLKID_MISC_BASE + 2)
-#define CLKID_SPICC_COMP (CLKID_MISC_BASE + 3)
+#define CLKID_MISC_BASE         (CLKID_MEDIA_BASE + 25)
+#define CLKID_SPICC_MUX         (CLKID_MISC_BASE + 0)
+#define CLKID_SPICC_DIV         (CLKID_MISC_BASE + 1)
+#define CLKID_SPICC_GATE        (CLKID_MISC_BASE + 2)
+#define CLKID_SPICC_COMP        (CLKID_MISC_BASE + 3)
 
-#define CLKID_AO_BASE (CLKID_MISC_BASE + 4) /*28+20+11+8+5+16+23+4 = 115*/
-#define CLKID_AO_CLK81 (CLKID_AO_BASE + 0)
-#define CLKID_SARADC_MUX (CLKID_AO_BASE + 1)
-#define CLKID_SARADC_DIV (CLKID_AO_BASE + 2)
-#define CLKID_SARADC_GATE (CLKID_AO_BASE + 3)
+#define CLKID_AO_BASE           (CLKID_MISC_BASE + 4)
+#define CLKID_AO_CLK81          (CLKID_AO_BASE + 0)
+#define CLKID_SARADC_MUX        (CLKID_AO_BASE + 1)
+#define CLKID_SARADC_DIV        (CLKID_AO_BASE + 2)
+#define CLKID_SARADC_GATE       (CLKID_AO_BASE + 3)
 
-#define NR_CLKS                                (OTHER_BASE + 47)
+#define NR_CLKS                 (CLKID_MISC_BASE + 4)
 
 #endif /* __G12A_CLKC_H */