ARM: S5PV210: Add new system clocks
[safe/jmp/linux-2.6] / arch / arm / mach-s5pv210 / clock.c
index 315955d..2c7be15 100644 (file)
@@ -173,6 +173,72 @@ static int s5pv210_clk_ip3_ctrl(struct clk *clk, int enable)
        return s5p_gatectrl(S5P_CLKGATE_IP3, clk, enable);
 }
 
+static int s5pv210_clk_mask0_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(S5P_CLK_SRC_MASK0, clk, enable);
+}
+
+static struct clk clk_sclk_hdmi27m = {
+       .name           = "sclk_hdmi27m",
+       .id             = -1,
+       .rate           = 27000000,
+};
+
+static struct clk clk_sclk_hdmiphy = {
+       .name           = "sclk_hdmiphy",
+       .id             = -1,
+};
+
+static struct clk clk_sclk_usbphy0 = {
+       .name           = "sclk_usbphy0",
+       .id             = -1,
+};
+
+static struct clk clk_sclk_usbphy1 = {
+       .name           = "sclk_usbphy1",
+       .id             = -1,
+};
+
+static struct clk *clkset_vpllsrc_list[] = {
+       [0] = &clk_fin_vpll,
+       [1] = &clk_sclk_hdmi27m,
+};
+
+static struct clksrc_sources clkset_vpllsrc = {
+       .sources        = clkset_vpllsrc_list,
+       .nr_sources     = ARRAY_SIZE(clkset_vpllsrc_list),
+};
+
+static struct clksrc_clk clk_vpllsrc = {
+       .clk    = {
+               .name           = "vpll_src",
+               .id             = -1,
+               .enable         = s5pv210_clk_mask0_ctrl,
+               .ctrlbit        = (1 << 7),
+       },
+       .sources        = &clkset_vpllsrc,
+       .reg_src        = { .reg = S5P_CLK_SRC1, .shift = 28, .size = 1 },
+};
+
+static struct clk *clkset_sclk_vpll_list[] = {
+       [0] = &clk_vpllsrc.clk,
+       [1] = &clk_fout_vpll,
+};
+
+static struct clksrc_sources clkset_sclk_vpll = {
+       .sources        = clkset_sclk_vpll_list,
+       .nr_sources     = ARRAY_SIZE(clkset_sclk_vpll_list),
+};
+
+static struct clksrc_clk clk_sclk_vpll = {
+       .clk    = {
+               .name           = "sclk_vpll",
+               .id             = -1,
+       },
+       .sources        = &clkset_sclk_vpll,
+       .reg_src        = { .reg = S5P_CLK_SRC0, .shift = 12, .size = 1 },
+};
+
 static unsigned long s5pv210_clk_imem_get_rate(struct clk *clk)
 {
        return clk_get_rate(clk->parent) / 2;
@@ -375,9 +441,47 @@ static struct clksrc_sources clkset_uart = {
        .nr_sources     = ARRAY_SIZE(clkset_uart_list),
 };
 
+static struct clk *clkset_group1_list[] = {
+       [0] = &clk_sclk_a2m.clk,
+       [1] = &clk_mout_mpll.clk,
+       [2] = &clk_mout_epll.clk,
+       [3] = &clk_sclk_vpll.clk,
+};
+
+static struct clksrc_sources clkset_group1 = {
+       .sources        = clkset_group1_list,
+       .nr_sources     = ARRAY_SIZE(clkset_group1_list),
+};
+
+static struct clk *clkset_sclk_onenand_list[] = {
+       [0] = &clk_hclk_psys.clk,
+       [1] = &clk_hclk_dsys.clk,
+};
+
+static struct clksrc_sources clkset_sclk_onenand = {
+       .sources        = clkset_sclk_onenand_list,
+       .nr_sources     = ARRAY_SIZE(clkset_sclk_onenand_list),
+};
+
 static struct clksrc_clk clksrcs[] = {
        {
                .clk    = {
+                       .name           = "sclk_dmc",
+                       .id             = -1,
+               },
+               .sources = &clkset_group1,
+               .reg_src = { .reg = S5P_CLK_SRC6, .shift = 24, .size = 2 },
+               .reg_div = { .reg = S5P_CLK_DIV6, .shift = 28, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_onenand",
+                       .id             = -1,
+               },
+               .sources = &clkset_sclk_onenand,
+               .reg_src = { .reg = S5P_CLK_SRC0, .shift = 28, .size = 1 },
+               .reg_div = { .reg = S5P_CLK_DIV6, .shift = 12, .size = 3 },
+       }, {
+               .clk    = {
                        .name           = "uclk1",
                        .id             = -1,
                        .ctrlbit        = (1<<17),
@@ -402,12 +506,15 @@ static struct clksrc_clk *sysclks[] = {
        &clk_pclk_msys,
        &clk_pclk_dsys,
        &clk_pclk_psys,
+       &clk_vpllsrc,
+       &clk_sclk_vpll,
 };
 
 void __init_or_cpufreq s5pv210_setup_clocks(void)
 {
        struct clk *xtal_clk;
        unsigned long xtal;
+       unsigned long vpllsrc;
        unsigned long armclk;
        unsigned long hclk_msys;
        unsigned long hclk_dsys;
@@ -418,6 +525,7 @@ void __init_or_cpufreq s5pv210_setup_clocks(void)
        unsigned long apll;
        unsigned long mpll;
        unsigned long epll;
+       unsigned long vpll;
        unsigned int ptr;
        u32 clkdiv0, clkdiv1;
 
@@ -440,13 +548,16 @@ void __init_or_cpufreq s5pv210_setup_clocks(void)
        apll = s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON), pll_4508);
        mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P_MPLL_CON), pll_4502);
        epll = s5p_get_pll45xx(xtal, __raw_readl(S5P_EPLL_CON), pll_4500);
+       vpllsrc = clk_get_rate(&clk_vpllsrc.clk);
+       vpll = s5p_get_pll45xx(vpllsrc, __raw_readl(S5P_VPLL_CON), pll_4502);
 
        clk_fout_apll.rate = apll;
        clk_fout_mpll.rate = mpll;
        clk_fout_epll.rate = epll;
+       clk_fout_vpll.rate = vpll;
 
-       printk(KERN_INFO "S5PV210: PLL settings, A=%ld, M=%ld, E=%ld",
-                       apll, mpll, epll);
+       printk(KERN_INFO "S5PV210: PLL settings, A=%ld, M=%ld, E=%ld V=%ld",
+                       apll, mpll, epll, vpll);
 
        armclk = clk_get_rate(&clk_armclk.clk);
        hclk_msys = clk_get_rate(&clk_hclk_msys.clk);
@@ -470,6 +581,10 @@ void __init_or_cpufreq s5pv210_setup_clocks(void)
 }
 
 static struct clk *clks[] __initdata = {
+       &clk_sclk_hdmi27m,
+       &clk_sclk_hdmiphy,
+       &clk_sclk_usbphy0,
+       &clk_sclk_usbphy1,
 };
 
 void __init s5pv210_register_clocks(void)