Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/horms/ipvs-2.6
[pandora-kernel.git] / arch / arm / plat-s5p / clock.c
index b5e2552..02af235 100644 (file)
@@ -21,6 +21,8 @@
 #include <linux/io.h>
 #include <asm/div64.h>
 
+#include <mach/regs-clock.h>
+
 #include <plat/clock.h>
 #include <plat/clock-clksrc.h>
 #include <plat/s5p-clock.h>
@@ -74,19 +76,18 @@ struct clk clk_fout_epll = {
        .ctrlbit        = (1 << 31),
 };
 
-/* VPLL clock output */
-struct clk clk_fout_vpll = {
-       .name           = "fout_vpll",
+/* DPLL clock output */
+struct clk clk_fout_dpll = {
+       .name           = "fout_dpll",
        .id             = -1,
        .ctrlbit        = (1 << 31),
 };
 
-/* ARM clock */
-struct clk clk_arm = {
-       .name           = "armclk",
+/* VPLL clock output */
+struct clk clk_fout_vpll = {
+       .name           = "fout_vpll",
        .id             = -1,
-       .rate           = 0,
-       .ctrlbit        = 0,
+       .ctrlbit        = (1 << 31),
 };
 
 /* Possible clock sources for APLL Mux */
@@ -122,6 +123,17 @@ struct clksrc_sources clk_src_epll = {
        .nr_sources     = ARRAY_SIZE(clk_src_epll_list),
 };
 
+/* Possible clock sources for DPLL Mux */
+static struct clk *clk_src_dpll_list[] = {
+       [0] = &clk_fin_dpll,
+       [1] = &clk_fout_dpll,
+};
+
+struct clksrc_sources clk_src_dpll = {
+       .sources        = clk_src_dpll_list,
+       .nr_sources     = ARRAY_SIZE(clk_src_dpll_list),
+};
+
 struct clk clk_vpll = {
        .name           = "vpll",
        .id             = -1,
@@ -138,6 +150,59 @@ int s5p_gatectrl(void __iomem *reg, struct clk *clk, int enable)
        return 0;
 }
 
+int s5p_epll_enable(struct clk *clk, int enable)
+{
+       unsigned int ctrlbit = clk->ctrlbit;
+       unsigned int epll_con = __raw_readl(S5P_EPLL_CON) & ~ctrlbit;
+
+       if (enable)
+               __raw_writel(epll_con | ctrlbit, S5P_EPLL_CON);
+       else
+               __raw_writel(epll_con, S5P_EPLL_CON);
+
+       return 0;
+}
+
+unsigned long s5p_epll_get_rate(struct clk *clk)
+{
+       return clk->rate;
+}
+
+int s5p_spdif_set_rate(struct clk *clk, unsigned long rate)
+{
+       struct clk *pclk;
+       int ret;
+
+       pclk = clk_get_parent(clk);
+       if (IS_ERR(pclk))
+               return -EINVAL;
+
+       ret = pclk->ops->set_rate(pclk, rate);
+       clk_put(pclk);
+
+       return ret;
+}
+
+unsigned long s5p_spdif_get_rate(struct clk *clk)
+{
+       struct clk *pclk;
+       int rate;
+
+       pclk = clk_get_parent(clk);
+       if (IS_ERR(pclk))
+               return -EINVAL;
+
+       rate = pclk->ops->get_rate(clk);
+       clk_put(pclk);
+
+       return rate;
+}
+
+struct clk_ops s5p_sclk_spdif_ops = {
+       .set_rate       = s5p_spdif_set_rate,
+       .get_rate       = s5p_spdif_get_rate,
+};
+
 static struct clk *s5p_clks[] __initdata = {
        &clk_ext_xtal_mux,
        &clk_48m,
@@ -145,8 +210,8 @@ static struct clk *s5p_clks[] __initdata = {
        &clk_fout_apll,
        &clk_fout_mpll,
        &clk_fout_epll,
+       &clk_fout_dpll,
        &clk_fout_vpll,
-       &clk_arm,
        &clk_vpll,
        &clk_xusbxti,
 };