ARM: shmobile: r8a73a4: add div4 clocks
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Fri, 5 Apr 2013 04:22:16 +0000 (21:22 -0700)
committerSimon Horman <horms+renesas@verge.net.au>
Fri, 7 Jun 2013 05:24:45 +0000 (14:24 +0900)
DIV4 clocks control each core clocks.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
arch/arm/mach-shmobile/clock-r8a73a4.c

index 2be592f6dbc079402224b2907bdef04217d23900..147314ac6a14b13684a37e7c996a2ab55b8b4735 100644 (file)
@@ -32,6 +32,8 @@
 #define SMSTPCR2 0xe6150138
 #define SMSTPCR5 0xe6150144
 
+#define FRQCRA         0xE6150000
+#define FRQCRB         0xE6150004
 #define CKSCR          0xE61500C0
 #define PLLECR         0xE61500D0
 #define PLL1CR         0xE6150028
@@ -175,6 +177,46 @@ static struct clk *main_clks[] = {
        &pll2h_clk,
 };
 
+/* DIV4 */
+static void div4_kick(struct clk *clk)
+{
+       unsigned long value;
+
+       /* set KICK bit in FRQCRB to update hardware setting */
+       value = ioread32(CPG_MAP(FRQCRB));
+       value |= (1 << 31);
+       iowrite32(value, CPG_MAP(FRQCRB));
+}
+
+static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18, 24, 0, 36, 48, 10};
+
+static struct clk_div_mult_table div4_div_mult_table = {
+       .divisors       = divisors,
+       .nr_divisors    = ARRAY_SIZE(divisors),
+};
+
+static struct clk_div4_table div4_table = {
+       .div_mult_table = &div4_div_mult_table,
+       .kick           = div4_kick,
+};
+
+enum {
+       DIV4_I, DIV4_M3, DIV4_B, DIV4_M1, DIV4_M2,
+       DIV4_ZX, DIV4_ZS, DIV4_HP,
+       DIV4_NR };
+
+static struct clk div4_clks[DIV4_NR] = {
+       [DIV4_I]        = SH_CLK_DIV4(&pll1_clk, FRQCRA, 20, 0x0dff, CLK_ENABLE_ON_INIT),
+       [DIV4_M3]       = SH_CLK_DIV4(&pll1_clk, FRQCRA, 12, 0x1dff, CLK_ENABLE_ON_INIT),
+       [DIV4_B]        = SH_CLK_DIV4(&pll1_clk, FRQCRA,  8, 0x0dff, CLK_ENABLE_ON_INIT),
+       [DIV4_M1]       = SH_CLK_DIV4(&pll1_clk, FRQCRA,  4, 0x1dff, 0),
+       [DIV4_M2]       = SH_CLK_DIV4(&pll1_clk, FRQCRA,  0, 0x1dff, 0),
+       [DIV4_ZX]       = SH_CLK_DIV4(&pll1_clk, FRQCRB, 12, 0x0dff, 0),
+       [DIV4_ZS]       = SH_CLK_DIV4(&pll1_clk, FRQCRB,  8, 0x0dff, 0),
+       [DIV4_HP]       = SH_CLK_DIV4(&pll1_clk, FRQCRB,  4, 0x0dff, 0),
+};
+
+/* MSTP */
 enum {
        MSTP217, MSTP216, MSTP207, MSTP206, MSTP204, MSTP203,
        MSTP522,
@@ -257,6 +299,9 @@ void __init r8a73a4_clock_init(void)
        for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
                ret = clk_register(main_clks[k]);
 
+       if (!ret)
+               ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
+
        if (!ret)
                ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);