clk: renesas: rcar-gen2: Fix PLL0 on R-Car V2H and E2
authorGeert Uytterhoeven <geert+renesas@glider.be>
Wed, 29 Mar 2017 15:22:44 +0000 (17:22 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 13 Apr 2018 17:47:57 +0000 (19:47 +0200)
[ Upstream commit b7c563c489e94417efbad68d057ea5d2030ae44c ]

R-Car V2H and E2 do not have the PLL0CR register, but use a fixed
multiplier (depending on mode pins) and divider.

This corrects the clock rate of "pll0" (PLL0 VCO after post divider) on
R-Car V2H and E2 from 1.5 GHz to 1 GHz.

Inspired by Sergei Shtylyov's work for the common R-Car Gen2 and RZ/G
Clock Pulse Generator support core.

Fixes: 7c4163aae3d8e5b9 ("ARM: dts: r8a7792: initial SoC device tree")
Fixes: 0dce5454d5c25858 ("ARM: shmobile: Initial r8a7794 SoC device tree")
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Sasha Levin <alexander.levin@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/clk/renesas/clk-rcar-gen2.c

index 00e6aba4b9c095960e7bd635d62eefdd33033da5..c55d5fe116d6ca748b757fc7db886c9019b0a8d7 100644 (file)
@@ -271,11 +271,14 @@ struct cpg_pll_config {
        unsigned int extal_div;
        unsigned int pll1_mult;
        unsigned int pll3_mult;
+       unsigned int pll0_mult;         /* For R-Car V2H and E2 only */
 };
 
 static const struct cpg_pll_config cpg_pll_configs[8] __initconst = {
-       { 1, 208, 106 }, { 1, 208,  88 }, { 1, 156,  80 }, { 1, 156,  66 },
-       { 2, 240, 122 }, { 2, 240, 102 }, { 2, 208, 106 }, { 2, 208,  88 },
+       { 1, 208, 106, 200 }, { 1, 208,  88, 200 },
+       { 1, 156,  80, 150 }, { 1, 156,  66, 150 },
+       { 2, 240, 122, 230 }, { 2, 240, 102, 230 },
+       { 2, 208, 106, 200 }, { 2, 208,  88, 200 },
 };
 
 /* SDHI divisors */
@@ -297,6 +300,12 @@ static const struct clk_div_table cpg_sd01_div_table[] = {
 
 static u32 cpg_mode __initdata;
 
+static const char * const pll0_mult_match[] = {
+       "renesas,r8a7792-cpg-clocks",
+       "renesas,r8a7794-cpg-clocks",
+       NULL
+};
+
 static struct clk * __init
 rcar_gen2_cpg_register_clock(struct device_node *np, struct rcar_gen2_cpg *cpg,
                             const struct cpg_pll_config *config,
@@ -317,9 +326,15 @@ rcar_gen2_cpg_register_clock(struct device_node *np, struct rcar_gen2_cpg *cpg,
                 * clock implementation and we currently have no need to change
                 * the multiplier value.
                 */
-               u32 value = clk_readl(cpg->reg + CPG_PLL0CR);
+               if (of_device_compatible_match(np, pll0_mult_match)) {
+                       /* R-Car V2H and E2 do not have PLL0CR */
+                       mult = config->pll0_mult;
+                       div = 3;
+               } else {
+                       u32 value = clk_readl(cpg->reg + CPG_PLL0CR);
+                       mult = ((value >> 24) & ((1 << 7) - 1)) + 1;
+               }
                parent_name = "main";
-               mult = ((value >> 24) & ((1 << 7) - 1)) + 1;
        } else if (!strcmp(name, "pll1")) {
                parent_name = "main";
                mult = config->pll1_mult / 2;