Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

clk: keystone: add support for post divider register for main pll

Main PLL controller has post divider bits in a separate register in
pll controller. Use the value from this register instead of fixed
divider when available.

Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
Signed-off-by: Michael Turquette <mturquette@baylibre.com>

authored by

Murali Karicheri and committed by
Michael Turquette
02fdfd70 91990d21

+22 -6
+4 -4
Documentation/devicetree/bindings/clock/keystone-pll.txt
··· 15 15 - compatible : shall be "ti,keystone,main-pll-clock" or "ti,keystone,pll-clock" 16 16 - clocks : parent clock phandle 17 17 - reg - pll control0 and pll multipler registers 18 - - reg-names : control and multiplier. The multiplier is applicable only for 19 - main pll clock 18 + - reg-names : control, multiplier and post-divider. The multiplier and 19 + post-divider registers are applicable only for main pll clock 20 20 - fixed-postdiv : fixed post divider value. If absent, use clkod register bits 21 21 for postdiv 22 22 ··· 25 25 #clock-cells = <0>; 26 26 compatible = "ti,keystone,main-pll-clock"; 27 27 clocks = <&refclksys>; 28 - reg = <0x02620350 4>, <0x02310110 4>; 29 - reg-names = "control", "multiplier"; 28 + reg = <0x02620350 4>, <0x02310110 4>, <0x02310108 4>; 29 + reg-names = "control", "multiplier", "post-divider"; 30 30 fixed-postdiv = <2>; 31 31 }; 32 32
+18 -2
drivers/clk/keystone/pll.c
··· 37 37 * Main PLL or any other PLLs in the device such as ARM PLL, DDR PLL 38 38 * or PA PLL available on keystone2. These PLLs are controlled by 39 39 * this register. Main PLL is controlled by a PLL controller. 40 - * @pllm: PLL register map address 40 + * @pllm: PLL register map address for multiplier bits 41 + * @pllod: PLL register map address for post divider bits 41 42 * @pll_ctl0: PLL controller map address 42 43 * @pllm_lower_mask: multiplier lower mask 43 44 * @pllm_upper_mask: multiplier upper mask ··· 54 53 u32 phy_pllm; 55 54 u32 phy_pll_ctl0; 56 55 void __iomem *pllm; 56 + void __iomem *pllod; 57 57 void __iomem *pll_ctl0; 58 58 u32 pllm_lower_mask; 59 59 u32 pllm_upper_mask; ··· 104 102 /* read post divider from od bits*/ 105 103 postdiv = ((val & pll_data->clkod_mask) >> 106 104 pll_data->clkod_shift) + 1; 107 - else 105 + else if (pll_data->pllod) { 106 + postdiv = readl(pll_data->pllod); 107 + postdiv = ((postdiv & pll_data->clkod_mask) >> 108 + pll_data->clkod_shift) + 1; 109 + } else 108 110 postdiv = pll_data->postdiv; 109 111 110 112 rate /= (prediv + 1); ··· 178 172 /* assume the PLL has output divider register bits */ 179 173 pll_data->clkod_mask = CLKOD_MASK; 180 174 pll_data->clkod_shift = CLKOD_SHIFT; 175 + 176 + /* 177 + * Check if there is an post-divider register. If not 178 + * assume od bits are part of control register. 179 + */ 180 + i = of_property_match_string(node, "reg-names", 181 + "post-divider"); 182 + pll_data->pllod = of_iomap(node, i); 181 183 } 182 184 183 185 i = of_property_match_string(node, "reg-names", "control"); 184 186 pll_data->pll_ctl0 = of_iomap(node, i); 185 187 if (!pll_data->pll_ctl0) { 186 188 pr_err("%s: ioremap failed\n", __func__); 189 + iounmap(pll_data->pllod); 187 190 goto out; 188 191 } 189 192 ··· 208 193 pll_data->pllm = of_iomap(node, i); 209 194 if (!pll_data->pllm) { 210 195 iounmap(pll_data->pll_ctl0); 196 + iounmap(pll_data->pllod); 211 197 goto out; 212 198 } 213 199 }