"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.
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
+
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>;
};
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/
}
return 0;
}
+
int m8b_clk_measure(struct seq_file *s, void *what, unsigned int index)
{
static const char * const clk_table[] = {
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;
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:
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;
}
u8 en_dds;
u16 top_misc_reg; /*after txlx*/
u16 top_misc_bit;
+ u16 mpll_cntl0_reg;
spinlock_t *lock;
};
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,
void meson_txlx_media_init(void);
void meson_init_gpu(void);
+void meson_g12a_sdemmc_init(void);
+
#endif /* __CLKC_H */
--- /dev/null
+#
+# 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
--- /dev/null
+/*
+ * 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);
+
+
--- /dev/null
+/*
+ * 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 */
--- /dev/null
+/*
+ * 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,
+};
--- /dev/null
+/*
+ * 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,
+};
+
--- /dev/null
+/*
+ * 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__);
+}
* 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 */