firmware/br-ext-chip-ingenic/board/t40/kernel/patches/00000-drivers_clk_ingenic_c...

370 lines
17 KiB
Diff

diff -drupN a/drivers/clk/ingenic/clk-t40.c b/drivers/clk/ingenic/clk-t40.c
--- a/drivers/clk/ingenic/clk-t40.c 1970-01-01 03:00:00.000000000 +0300
+++ b/drivers/clk/ingenic/clk-t40.c 2022-06-09 05:02:28.000000000 +0300
@@ -0,0 +1,365 @@
+#include <linux/slab.h>
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/syscore_ops.h>
+#include <linux/module.h>
+#include <linux/clk.h>
+#include <linux/seq_file.h>
+#include <linux/proc_fs.h>
+#include <soc/cpm.h>
+#include <soc/base.h>
+#include <dt-bindings/clock/ingenic-t40.h>
+
+#include <jz_proc.h>
+#include "clk.h"
+
+#define CLK_FLG_ENABLE BIT(1)
+static struct ingenic_clk_provider *ctx;
+
+
+/*******************************************************************************
+ * FIXED CLK
+ ********************************************************************************/
+static struct ingenic_fixed_rate_clock t40_fixed_rate_ext_clks[] __initdata = {
+ FRATE(CLK_EXT, "ext", NULL, CLK_IS_ROOT, 24000000),
+ FRATE(CLK_RTC_EXT, "rtc_ext", NULL, CLK_IS_ROOT, 32768),
+};
+
+
+
+/*******************************************************************************
+ * PLL
+ ********************************************************************************/
+
+static struct ingenic_pll_rate_table t40_pll_rate_table[] = {
+ PLL_RATE(1800000000, 150, 1, 2, 1),
+ PLL_RATE(1608000000, 134, 1, 2, 1),
+ PLL_RATE(1500000000, 125, 1, 2, 1),
+ PLL_RATE(1404000000, 117, 1, 2, 1),
+ PLL_RATE(1400000000, 350, 3, 2, 1),
+ PLL_RATE(1392000000, 116, 1, 2, 1),
+ PLL_RATE(1308000000, 109, 1, 2, 1),
+ PLL_RATE(1296000000, 108, 1, 2, 1),
+ PLL_RATE(1200000000, 100, 1, 2, 1),
+ PLL_RATE(1104000000, 92, 1, 2, 1),
+ PLL_RATE(1100000000, 275, 2, 3, 1),
+ PLL_RATE(1080000000, 90, 1, 2, 1),
+ PLL_RATE(1008000000, 84, 1, 2, 1),
+ PLL_RATE(1000000000, 125, 1, 3, 1),
+ PLL_RATE(900000000, 75, 1, 2, 1),
+ PLL_RATE(891000000, 297, 4, 2, 1),
+ PLL_RATE(864000000, 72, 1, 2, 1),
+ PLL_RATE(600000000, 75, 1, 3, 1),
+};
+
+
+
+/*PLL HWDESC*/
+static struct ingenic_pll_hwdesc apll_hwdesc = \
+ PLL_DESC(CPM_CPAPCR, 20, 12, 14, 6, 11, 3, 8, 3, 3, 0, 2);
+
+static struct ingenic_pll_hwdesc mpll_hwdesc = \
+ PLL_DESC(CPM_CPMPCR, 20, 12, 14, 6, 11, 3, 8, 3, 3, 0, 2);
+
+static struct ingenic_pll_hwdesc vpll_hwdesc = \
+ PLL_DESC(CPM_CPVPCR, 20, 12, 14, 6, 11, 3, 8, 3, 3, 0, 2);
+
+static struct ingenic_pll_hwdesc epll_hwdesc = \
+ PLL_DESC(CPM_CPEPCR, 20, 12, 14, 6, 11, 3, 8, 3, 3, 0, 2);
+
+
+
+static struct ingenic_pll_clock t40_pll_clks[] __initdata = {
+ PLL(CLK_PLL_APLL, "apll", "ext", &apll_hwdesc, t40_pll_rate_table),
+ PLL(CLK_PLL_MPLL, "mpll", "ext", &mpll_hwdesc, t40_pll_rate_table),
+ PLL(CLK_PLL_VPLL, "vpll", "ext", &vpll_hwdesc, t40_pll_rate_table),
+ PLL(CLK_PLL_EPLL, "epll", "ext", &epll_hwdesc, t40_pll_rate_table),
+};
+
+
+/*******************************************************************************
+ * MUX
+ ********************************************************************************/
+PNAME(mux_table_0) = {"stop", "ext", "apll"};
+PNAME(mux_table_1) = {"stop", "sclka", "mpll"};
+PNAME(mux_table_2) = {"sclka", "mpll", "vpll", "epll"};
+PNAME(mux_table_3) = {"sclka", "mpll", "epll", "ext"};
+PNAME(mux_table_4) = {"sclka", "vpll", "ext"};
+PNAME(mux_table_5) = {"mux_ahb2", "ext"};
+
+static unsigned int ingenic_mux_table[] = {0, 1, 2, 3};
+
+
+static struct ingenic_mux_clock t40_mux_clks[] __initdata = {
+ MUX(CLK_MUX_SCLKA, "sclka", ingenic_mux_table, mux_table_0, CPM_CPCCR, 30, 2, 0),
+ MUX(CLK_MUX_CPU_L2C, "mux_cpu_l2c", ingenic_mux_table, mux_table_1, CPM_CPCCR, 28, 2, 0),
+ MUX(CLK_MUX_AHB0, "mux_ahb0", ingenic_mux_table, mux_table_1, CPM_CPCCR, 26, 2, 0),
+ MUX(CLK_MUX_AHB2, "mux_ahb2", ingenic_mux_table, mux_table_1, CPM_CPCCR, 24, 2, 0),
+
+ MUX(CLK_MUX_DDR, "mux_ddr", ingenic_mux_table, mux_table_1, CPM_DDRCDR, 30, 2, 0),
+ MUX(CLK_MUX_EL150, "mux_el150", ingenic_mux_table, mux_table_2, CPM_EL150CDR, 30, 2, 0),
+ MUX(CLK_MUX_RSA, "mux_rsa", ingenic_mux_table, mux_table_2, CPM_RSACDR, 30, 2, 0),
+ MUX(CLK_MUX_MACPHY, "mux_macphy", ingenic_mux_table, mux_table_2, CPM_MACCDR, 30, 2, 0),
+ MUX(CLK_MUX_SFC, "mux_sfc", ingenic_mux_table, mux_table_2, CPM_SFCCDR, 30, 2, 0),
+ MUX(CLK_MUX_LCD, "mux_lcd", ingenic_mux_table, mux_table_2, CPM_LPCDR, 30, 2, 0),
+ MUX(CLK_MUX_MSC0, "mux_msc0", ingenic_mux_table, mux_table_2, CPM_MSC0CDR, 30, 2, 0),
+ MUX(CLK_MUX_MSC1, "mux_msc1", ingenic_mux_table, mux_table_2, CPM_MSC1CDR, 30, 2, 0),
+ MUX(CLK_MUX_SSI, "mux_ssi", ingenic_mux_table, mux_table_2, CPM_SSICDR, 30, 2, 0),
+ MUX(CLK_MUX_I2ST, "mux_i2st", ingenic_mux_table, mux_table_2, CPM_I2STCDR, 30, 2, 0),
+ MUX(CLK_MUX_ISP, "mux_isp", ingenic_mux_table, mux_table_2, CPM_ISPCDR, 30, 2, 0),
+ MUX(CLK_MUX_I2SR, "mux_i2sr", ingenic_mux_table, mux_table_2, CPM_I2STCDR, 30, 2, 0),
+ MUX(CLK_MUX_CIM0, "mux_cim0", ingenic_mux_table, mux_table_2, CPM_CIM0CDR, 30, 2, 0),
+ MUX(CLK_MUX_CIM1, "mux_cim1", ingenic_mux_table, mux_table_2, CPM_CIM1CDR, 30, 2, 0),
+ MUX(CLK_MUX_CIM2, "mux_cim2", ingenic_mux_table, mux_table_2, CPM_CIM2CDR, 30, 2, 0),
+ MUX(CLK_MUX_BSCALER, "mux_bscaler", ingenic_mux_table, mux_table_2, CPM_BSCALERCDR, 30, 2, 0),
+ MUX(CLK_MUX_BT0, "mux_bt0", ingenic_mux_table, mux_table_2, CPM_BT0CDR, 30, 2, 0),
+
+};
+
+/*******************************************************************************
+ * DIV BUS
+ ********************************************************************************/
+
+static struct ingenic_bus_clock t40_bus_div_clks[] __initdata = {
+ BUS_DIV(CLK_DIV_CPU, "div_cpu", "mux_cpu_l2c", CPM_CPCCR, 0, 4, 0, 0, CPM_CPCSR, 0, 22, BUS_DIV_SELF),
+ BUS_DIV(CLK_DIV_L2C, "div_l2c", "mux_cpu_l2c", CPM_CPCCR, 4, 4, 0, 0, CPM_CPCSR, 0, 22, BUS_DIV_SELF),
+ BUS_DIV(CLK_DIV_AHB0, "div_ahb0", "mux_ahb0", CPM_CPCCR, 8, 4, 0, 0, CPM_CPCSR, 1, 21, BUS_DIV_SELF),
+ BUS_DIV(CLK_DIV_AHB2, "div_ahb2", "mux_ahb2", CPM_CPCCR, 12, 4, 0, 0, CPM_CPCSR, 2, 20, BUS_DIV_SELF),
+ BUS_DIV(CLK_DIV_APB, "div_apb", "mux_ahb2", CPM_CPCCR, 16, 4, 0, 0, CPM_CPCSR, 2, 20, BUS_DIV_SELF),
+ BUS_DIV(CLK_DIV_CPU_L2C_X1, "div_cpu_l2c_x1", "mux_cpu_l2c", CPM_CPCCR, 0, 4, 4, 4, CPM_CPCSR, 0, 22, BUS_DIV_ONE),
+ BUS_DIV(CLK_DIV_CPU_L2C_X2, "div_cpu_l2c_x2", "mux_cpu_l2c", CPM_CPCCR, 0, 4, 4, 4, CPM_CPCSR, 0, 22, BUS_DIV_TWO),
+};
+
+
+/*******************************************************************************
+ * DIV
+ ********************************************************************************/
+
+static struct clk_div_table t40_clk_div_table[256] = {};
+
+static struct ingenic_div_clock t40_div_clks[] __initdata = {
+ DIV(CLK_DIV_DDR, "div_ddr", "mux_ddr", CPM_DDRCDR, 4, 0, NULL),
+ DIV(CLK_DIV_MACPHY, "div_macphy", "mux_macphy", CPM_MACCDR, 8, 0, NULL),
+ DIV(CLK_DIV_LCD, "div_lcd", "mux_lcd", CPM_LPCDR, 8, 0, NULL),
+ DIV(CLK_DIV_MSC0, "div_msc0", "mux_msc0", CPM_MSC0CDR, 8, 0, t40_clk_div_table),
+ DIV(CLK_DIV_MSC1, "div_msc1", "mux_msc1", CPM_MSC1CDR, 8, 0, t40_clk_div_table),
+ DIV(CLK_DIV_SFC, "div_sfc", "mux_sfc", CPM_SFCCDR, 8, 0, NULL),
+ DIV(CLK_DIV_SSI, "div_ssi", "mux_ssi", CPM_SSICDR, 8, 0, NULL),
+ DIV(CLK_DIV_CIM0, "div_cim0", "mux_cim0", CPM_CIM0CDR, 8, 0, NULL),
+ DIV(CLK_DIV_CIM1, "div_cim1", "mux_cim1", CPM_CIM1CDR, 8, 0, NULL),
+ DIV(CLK_DIV_CIM2, "div_cim2", "mux_cim2", CPM_CIM2CDR, 8, 0, NULL),
+ DIV(CLK_DIV_ISP, "div_isp", "mux_isp", CPM_ISPCDR, 4, 0, NULL),
+ DIV(CLK_DIV_RSA, "div_rsa", "mux_rsa", CPM_RSACDR, 4, 0, NULL),
+ DIV(CLK_DIV_EL150, "div_el150", "mux_el150", CPM_EL150CDR, 4, 0, NULL),
+ DIV(CLK_DIV_BSCALER, "div_bscaler", "mux_bscaler", CPM_BSCALERCDR, 4, 0, NULL),
+ DIV(CLK_DIV_BT0, "div_bt0", "mux_bt0", CPM_BT0CDR, 8, 0, NULL),
+
+};
+
+/*******************************************************************************
+ * FRACTIONAL-DIVIDER
+ ********************************************************************************/
+
+static struct ingenic_fra_div_clock t40_fdiv_clks[] __initdata = {
+ FRA_DIV(CLK_DIV_I2ST, "div_i2st", "mux_i2st", CPM_I2STCDR, 20, 9, 0, 20),
+ FRA_DIV(CLK_DIV_I2SR, "div_i2sr", "mux_i2sr", CPM_I2SRCDR, 20, 9, 0, 20),
+};
+
+/*******************************************************************************
+ * GATE
+ ********************************************************************************/
+static struct ingenic_gate_clock t40_gate_clks[] __initdata = {
+
+ GATE(CLK_GATE_DDR, "gate_ddr", "div_ddr", CPM_CLKGR, 31, CLK_IGNORE_UNUSED, CLK_GATE_SET_TO_DISABLE),
+ GATE(CLK_GATE_TCU, "gate_tcu", "div_apb", CPM_CLKGR, 30, 0, CLK_GATE_SET_TO_DISABLE),
+ GATE(CLK_GATE_DES, "gate_des", "div_apb", CPM_CLKGR, 28, 0, CLK_GATE_SET_TO_DISABLE),
+ GATE(CLK_GATE_RSA, "gate_rsa", "div_rsa", CPM_CLKGR, 27, 0, CLK_GATE_SET_TO_DISABLE),
+ GATE(CLK_GATE_MIPI_CSI, "gate_csi", "div_ahb0", CPM_CLKGR, 25, 0, CLK_GATE_SET_TO_DISABLE),
+ GATE(CLK_GATE_LCD, "gate_lcd", "div_lcd", CPM_CLKGR, 24, 0, CLK_GATE_SET_TO_DISABLE),
+ GATE(CLK_GATE_ISP, "gate_isp", "div_isp", CPM_CLKGR, 23, 0, CLK_GATE_SET_TO_DISABLE),
+ GATE(CLK_GATE_PDMA, "gate_pdma", "div_ahb2", CPM_CLKGR, 22, 0, CLK_GATE_SET_TO_DISABLE),
+ GATE(CLK_GATE_SFC, "gate_sfc", "div_sfc", CPM_CLKGR, 21, 0, CLK_GATE_SET_TO_DISABLE),
+ GATE(CLK_GATE_SSI1, "gate_ssi1", "div_ssi", CPM_CLKGR, 20, 0, CLK_GATE_SET_TO_DISABLE),
+ GATE(CLK_GATE_HASH, "gate_hash", "div_ahb2", CPM_CLKGR, 19, 0, CLK_GATE_SET_TO_DISABLE),
+ GATE(CLK_GATE_SLV, "gate_slv", "div_apb", CPM_CLKGR, 18, 0, CLK_GATE_SET_TO_DISABLE),
+ GATE(CLK_GATE_UART3, "gate_uart3", "div_apb", CPM_CLKGR, 17, 0, CLK_GATE_SET_TO_DISABLE),
+ GATE(CLK_GATE_UART2, "gate_uart2", "div_apb", CPM_CLKGR, 16, 0, CLK_GATE_SET_TO_DISABLE),
+ GATE(CLK_GATE_UART1, "gate_uart1", "div_apb", CPM_CLKGR, 15, 0, CLK_GATE_SET_TO_DISABLE),
+ GATE(CLK_GATE_UART0, "gate_uart0", "div_apb", CPM_CLKGR, 14, 0, CLK_GATE_SET_TO_DISABLE),
+ GATE(CLK_GATE_SADC, "gate_sadc", "div_apb", CPM_CLKGR, 13, 0, CLK_GATE_SET_TO_DISABLE),
+ GATE(CLK_GATE_DMIC, "gate_dmic", "mux_apb", CPM_CLKGR, 12, 0, CLK_GATE_SET_TO_DISABLE),
+ GATE(CLK_GATE_AIC, "gate_aic", "div_i2st", CPM_CLKGR, 11, 0, CLK_GATE_SET_TO_DISABLE),
+ GATE(CLK_GATE_SMB3, "gate_i2c3", "div_apb", CPM_CLKGR, 10, 0, CLK_GATE_SET_TO_DISABLE),
+ GATE(CLK_GATE_SMB2, "gate_i2c2", "div_apb", CPM_CLKGR, 9, 0, CLK_GATE_SET_TO_DISABLE),
+ GATE(CLK_GATE_SMB1, "gate_i2c1", "div_apb", CPM_CLKGR, 8, 0, CLK_GATE_SET_TO_DISABLE),
+ GATE(CLK_GATE_SMB0, "gate_i2c0", "div_apb", CPM_CLKGR, 7, 0, CLK_GATE_SET_TO_DISABLE),
+ GATE(CLK_GATE_SSI0, "gate_ssi0", "div_ssi", CPM_CLKGR, 6, 0, CLK_GATE_SET_TO_DISABLE),
+ GATE(CLK_GATE_MSC1, "gate_msc1", "div_msc1", CPM_CLKGR, 5, 0, CLK_GATE_SET_TO_DISABLE),
+ GATE(CLK_GATE_MSC0, "gate_msc0", "div_msc0", CPM_CLKGR, 4, 0, CLK_GATE_SET_TO_DISABLE),
+ GATE(CLK_GATE_OTG, "gate_otg", "div_ahb2", CPM_CLKGR, 3, 0, CLK_GATE_SET_TO_DISABLE),
+ GATE(CLK_GATE_BSCALER, "gate_bscaler", "div_bscaler", CPM_CLKGR, 2, 0, CLK_GATE_SET_TO_DISABLE),
+ GATE(CLK_GATE_EFUSE, "gate_efuse", "div_ahb2", CPM_CLKGR, 1, 0, CLK_GATE_HIWORD_MASK),
+ GATE(CLK_GATE_NEMC, "gate_nemc", "div_ahb2", CPM_CLKGR, 0, 0, CLK_GATE_SET_TO_DISABLE),
+ GATE(CLK_GATE_CPU, "gate_cpu", "div_cpu", CPM_CLKGR1, 15, 0, CLK_GATE_SET_TO_DISABLE),
+ GATE(CLK_GATE_APB0, "gate_apb0", "div_ahb0", CPM_CLKGR1, 14, CLK_IGNORE_UNUSED, CLK_GATE_SET_TO_DISABLE),
+ GATE(CLK_GATE_OST, "gate_ost", "ext", CPM_CLKGR1, 11, CLK_IGNORE_UNUSED, CLK_GATE_SET_TO_DISABLE),
+ GATE(CLK_GATE_AHB0, "gate_ahb0", "div_ahb0", CPM_CLKGR1, 10, CLK_IGNORE_UNUSED, CLK_GATE_SET_TO_DISABLE),
+ GATE(CLK_GATE_MONITOR, "gate_monitor", "div_ahb0", CPM_CLKGR1, 9, 0, CLK_GATE_SET_TO_DISABLE),
+ GATE(CLK_GATE_I2D, "gate_i2d", "div_ahb0", CPM_CLKGR1, 8, 0, CLK_GATE_SET_TO_DISABLE),
+ GATE(CLK_GATE_MIPI_DSI, "gate_dsi", "div_ahb0", CPM_CLKGR1, 7, 0, CLK_GATE_SET_TO_DISABLE),
+ GATE(CLK_GATE_DRAWBOX, "gate_drawbox", "div_ahb0", CPM_CLKGR1, 6, 0, CLK_GATE_SET_TO_DISABLE),
+ GATE(CLK_GATE_AES, "gate_aes", "div_ahb2", CPM_CLKGR1, 5, 0, CLK_GATE_SET_TO_DISABLE),
+ GATE(CLK_GATE_GMAC, "gate_gmac", "div_macphy", CPM_CLKGR1, 4, 0, CLK_GATE_SET_TO_DISABLE),
+ GATE(CLK_GATE_AHB1, "gate_ahb1", "div_ahb2", CPM_CLKGR1, 3, 0, CLK_GATE_SET_TO_DISABLE),
+ GATE(CLK_GATE_IPU, "gate_ipu", "div_ahb0", CPM_CLKGR1, 2, 0, CLK_GATE_SET_TO_DISABLE),
+ GATE(CLK_GATE_DTRNG, "gate_dtrng", "div_apb", CPM_CLKGR1, 1, 0, CLK_GATE_SET_TO_DISABLE),
+ GATE(CLK_GATE_EL150, "gate_el150", "div_el150", CPM_CLKGR1, 0, 0, CLK_GATE_SET_TO_DISABLE),
+ GATE(CLK_CE_I2ST, "ce_i2st", "div_i2st", CPM_I2STCDR, 29, 0, 0),
+ GATE(CLK_CE_I2SR, "ce_i2sr", "div_i2sr", CPM_I2SRCDR, 29, 0, 0),
+ GATE(CLK_GATE_USBPHY, "gate_usbphy", "div_apb", CPM_OPCR, 23, 0, CLK_GATE_SET_TO_DISABLE)
+};
+
+static void clk_div_table_generate(void)
+{
+ int i;
+ for (i = 0; i < ARRAY_SIZE(t40_clk_div_table); i++) {
+ t40_clk_div_table[i].val = i;
+ t40_clk_div_table[i].div = (i + 1) * 4;
+ }
+
+}
+
+static const struct of_device_id ext_clk_match[] __initconst = {
+ { .compatible = "ingenic,fixed-clock", .data = (void *)0, },
+ {},
+};
+
+static int clocks_show(struct seq_file *m, void *v)
+{
+ int i = 0;
+ struct clk_onecell_data * clk_data = NULL;
+ struct clk *clk = NULL;
+
+ if(m->private != NULL) {
+ seq_printf(m, "CLKGR\t: %08x\n", cpm_inl(CPM_CLKGR));
+ seq_printf(m, "CLKGR1\t: %08x\n", cpm_inl(CPM_CLKGR1));
+ seq_printf(m, "LCR1\t: %08x\n", cpm_inl(CPM_LCR));
+ } else {
+ seq_printf(m, " ID NAME FRE sta count parent\n");
+ clk_data = &ctx->clk_data;
+ for(i = 0; i < clk_data->clk_num; i++) {
+ clk = clk_data->clks[i];
+ if (clk != ERR_PTR(-ENOENT)) {
+ if (__clk_get_name(clk) == NULL) {
+ seq_printf(m, "--------------------------------------------------------\n");
+ } else {
+ unsigned int mhz = _get_rate(__clk_get_name(clk)) / 1000;
+ seq_printf(m, "%3d %-15s %4d.%03dMHz %7sable %d %10s\n", i, __clk_get_name(clk)
+ , mhz/1000, mhz%1000
+ , __clk_get_flags(clk) & CLK_FLG_ENABLE? "en": "dis"
+ , __clk_get_enable_count(clk)
+ , clk_get_parent(clk)? __clk_get_name(clk_get_parent(clk)): "root");
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int clocks_open(struct inode *inode, struct file *file)
+{
+ return single_open_size(file, clocks_show, PDE_DATA(inode),8192);
+}
+
+static const struct file_operations clocks_proc_fops ={
+ .read = seq_read,
+ .open = clocks_open,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+/* Register t40 clocks. */
+static void __init t40_clk_init(struct device_node *np, void __iomem *base)
+{
+ void __iomem *reg_base;
+
+ printk("t40 Clock Power Management Unit init!\n");
+
+ reg_base = base;
+
+ if (np) {
+ reg_base = of_iomap(np, 0);
+ if (!reg_base)
+ panic("%s: failed to map registers\n", __func__);
+ }
+
+
+ ctx = ingenic_clk_init(np, reg_base, NR_CLKS);
+ if (!ctx)
+ panic("%s: unable to allocate context.\n", __func__);
+
+ /* Register Ext Clocks From DT */
+ ingenic_clk_of_register_fixed_ext(ctx, t40_fixed_rate_ext_clks,
+ ARRAY_SIZE(t40_fixed_rate_ext_clks), ext_clk_match);
+
+ /* Register PLLs. */
+ ingenic_clk_register_pll(ctx, t40_pll_clks,
+ ARRAY_SIZE(t40_pll_clks), reg_base);
+
+
+ /* Register Muxs */
+ ingenic_clk_register_mux(ctx, t40_mux_clks, ARRAY_SIZE(t40_mux_clks));
+
+ /* Register Bus Divs */
+ ingenic_clk_register_bus_div(ctx, t40_bus_div_clks, ARRAY_SIZE(t40_bus_div_clks));
+
+ /* Register Divs */
+ clk_div_table_generate();
+ ingenic_clk_register_cgu_div(ctx, t40_div_clks, ARRAY_SIZE(t40_div_clks));
+
+ /* Register Fractional Divs */
+ ingenic_clk_register_fra_div(ctx, t40_fdiv_clks, ARRAY_SIZE(t40_fdiv_clks));
+
+ /* Register Gates */
+ ingenic_clk_register_gate(ctx, t40_gate_clks, ARRAY_SIZE(t40_gate_clks));
+
+ /* Register Powers */
+// ingenic_power_register_gate(ctx, t40_gate_power, ARRAY_SIZE(t40_gate_power));
+
+ ingenic_clk_of_add_provider(np, ctx);
+
+
+ //ingenic_clk_of_dump(ctx);
+
+
+ pr_info("=========== t40 clocks: =============\n"
+ "\tapll = %lu , mpll = %lu\n"
+ "\tcpu_clk = %lu , l2c_clk = %lu\n"
+ "\tahb0_clk = %lu , ahb2_clk = %lu\n"
+ "\tapb_clk = %lu , ext_clk = %lu\n\n",
+ _get_rate("apll"), _get_rate("mpll"),
+ _get_rate("div_cpu"), _get_rate("div_l2c"),
+ _get_rate("div_ahb0"), _get_rate("div_ahb2"),
+ _get_rate("div_apb"), _get_rate("ext"));
+
+}
+
+CLK_OF_DECLARE(t40_clk, "ingenic,t40-clocks", t40_clk_init);
+
+static int __init init_clk_proc(void)
+{
+ struct proc_dir_entry *p;
+
+ p = jz_proc_mkdir("clock");
+ if (!p) {
+ pr_warning("create_proc_entry for common clock failed!\n");
+ } else {
+ proc_create_data("clocks", 0600, p, &clocks_proc_fops, 0);
+ proc_create_data("misc", 0600, p, &clocks_proc_fops, (void *)1);
+ }
+ return 0;
+}
+
+module_init(init_clk_proc);