clock: clock tree for G12A

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>
This commit is contained in:
Qiufang Dai
2017-12-23 17:32:27 +08:00
committed by Yixun Lan
parent bbc834999a
commit 8b5ae71fdf
13 changed files with 2136 additions and 128 deletions

View 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.

View 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

View File

@@ -247,7 +247,7 @@
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>;
};

View 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/

View 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;
}

View 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 */

View File

@@ -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

View File

@@ -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);

View File

@@ -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 */

View File

@@ -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,
};

View File

@@ -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,
};

View File

@@ -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__);
}

View File

@@ -22,147 +22,169 @@
* 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_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_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_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_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_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_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 NR_CLKS (OTHER_BASE + 47)
#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 (CLKID_MISC_BASE + 4)
#endif /* __G12A_CLKC_H */