aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMurali Karicheri <m-karicheri2@ti.com>2015-05-29 12:04:12 -0400
committerMichael Turquette <mturquette@baylibre.com>2015-06-18 18:36:33 -0400
commit02fdfd708fd252a778709beb6c65d5e7360341ac (patch)
tree1628c7d5e62c8626b2cba578ae1aac20fde1dd73
parent91990d213ca06fdecca19e10514ebec7c89ddca9 (diff)
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>
-rw-r--r--Documentation/devicetree/bindings/clock/keystone-pll.txt8
-rw-r--r--drivers/clk/keystone/pll.c20
2 files changed, 22 insertions, 6 deletions
diff --git a/Documentation/devicetree/bindings/clock/keystone-pll.txt b/Documentation/devicetree/bindings/clock/keystone-pll.txt
index 225990f79b7c..47570d207215 100644
--- a/Documentation/devicetree/bindings/clock/keystone-pll.txt
+++ b/Documentation/devicetree/bindings/clock/keystone-pll.txt
@@ -15,8 +15,8 @@ Required properties:
15- compatible : shall be "ti,keystone,main-pll-clock" or "ti,keystone,pll-clock" 15- compatible : shall be "ti,keystone,main-pll-clock" or "ti,keystone,pll-clock"
16- clocks : parent clock phandle 16- clocks : parent clock phandle
17- reg - pll control0 and pll multipler registers 17- reg - pll control0 and pll multipler registers
18- reg-names : control and multiplier. The multiplier is applicable only for 18- reg-names : control, multiplier and post-divider. The multiplier and
19 main pll clock 19 post-divider registers are applicable only for main pll clock
20- fixed-postdiv : fixed post divider value. If absent, use clkod register bits 20- fixed-postdiv : fixed post divider value. If absent, use clkod register bits
21 for postdiv 21 for postdiv
22 22
@@ -25,8 +25,8 @@ Example:
25 #clock-cells = <0>; 25 #clock-cells = <0>;
26 compatible = "ti,keystone,main-pll-clock"; 26 compatible = "ti,keystone,main-pll-clock";
27 clocks = <&refclksys>; 27 clocks = <&refclksys>;
28 reg = <0x02620350 4>, <0x02310110 4>; 28 reg = <0x02620350 4>, <0x02310110 4>, <0x02310108 4>;
29 reg-names = "control", "multiplier"; 29 reg-names = "control", "multiplier", "post-divider";
30 fixed-postdiv = <2>; 30 fixed-postdiv = <2>;
31 }; 31 };
32 32
diff --git a/drivers/clk/keystone/pll.c b/drivers/clk/keystone/pll.c
index 0dd8a4b12747..4a375ead70e9 100644
--- a/drivers/clk/keystone/pll.c
+++ b/drivers/clk/keystone/pll.c
@@ -37,7 +37,8 @@
37 * Main PLL or any other PLLs in the device such as ARM PLL, DDR PLL 37 * Main PLL or any other PLLs in the device such as ARM PLL, DDR PLL
38 * or PA PLL available on keystone2. These PLLs are controlled by 38 * or PA PLL available on keystone2. These PLLs are controlled by
39 * this register. Main PLL is controlled by a PLL controller. 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 * @pll_ctl0: PLL controller map address 42 * @pll_ctl0: PLL controller map address
42 * @pllm_lower_mask: multiplier lower mask 43 * @pllm_lower_mask: multiplier lower mask
43 * @pllm_upper_mask: multiplier upper mask 44 * @pllm_upper_mask: multiplier upper mask
@@ -53,6 +54,7 @@ struct clk_pll_data {
53 u32 phy_pllm; 54 u32 phy_pllm;
54 u32 phy_pll_ctl0; 55 u32 phy_pll_ctl0;
55 void __iomem *pllm; 56 void __iomem *pllm;
57 void __iomem *pllod;
56 void __iomem *pll_ctl0; 58 void __iomem *pll_ctl0;
57 u32 pllm_lower_mask; 59 u32 pllm_lower_mask;
58 u32 pllm_upper_mask; 60 u32 pllm_upper_mask;
@@ -102,7 +104,11 @@ static unsigned long clk_pllclk_recalc(struct clk_hw *hw,
102 /* read post divider from od bits*/ 104 /* read post divider from od bits*/
103 postdiv = ((val & pll_data->clkod_mask) >> 105 postdiv = ((val & pll_data->clkod_mask) >>
104 pll_data->clkod_shift) + 1; 106 pll_data->clkod_shift) + 1;
105 else 107 else if (pll_data->pllod) {
108 postdiv = readl(pll_data->pllod);
109 postdiv = ((postdiv & pll_data->clkod_mask) >>
110 pll_data->clkod_shift) + 1;
111 } else
106 postdiv = pll_data->postdiv; 112 postdiv = pll_data->postdiv;
107 113
108 rate /= (prediv + 1); 114 rate /= (prediv + 1);
@@ -172,12 +178,21 @@ static void __init _of_pll_clk_init(struct device_node *node, bool pllctrl)
172 /* assume the PLL has output divider register bits */ 178 /* assume the PLL has output divider register bits */
173 pll_data->clkod_mask = CLKOD_MASK; 179 pll_data->clkod_mask = CLKOD_MASK;
174 pll_data->clkod_shift = CLKOD_SHIFT; 180 pll_data->clkod_shift = CLKOD_SHIFT;
181
182 /*
183 * Check if there is an post-divider register. If not
184 * assume od bits are part of control register.
185 */
186 i = of_property_match_string(node, "reg-names",
187 "post-divider");
188 pll_data->pllod = of_iomap(node, i);
175 } 189 }
176 190
177 i = of_property_match_string(node, "reg-names", "control"); 191 i = of_property_match_string(node, "reg-names", "control");
178 pll_data->pll_ctl0 = of_iomap(node, i); 192 pll_data->pll_ctl0 = of_iomap(node, i);
179 if (!pll_data->pll_ctl0) { 193 if (!pll_data->pll_ctl0) {
180 pr_err("%s: ioremap failed\n", __func__); 194 pr_err("%s: ioremap failed\n", __func__);
195 iounmap(pll_data->pllod);
181 goto out; 196 goto out;
182 } 197 }
183 198
@@ -193,6 +208,7 @@ static void __init _of_pll_clk_init(struct device_node *node, bool pllctrl)
193 pll_data->pllm = of_iomap(node, i); 208 pll_data->pllm = of_iomap(node, i);
194 if (!pll_data->pllm) { 209 if (!pll_data->pllm) {
195 iounmap(pll_data->pll_ctl0); 210 iounmap(pll_data->pll_ctl0);
211 iounmap(pll_data->pllod);
196 goto out; 212 goto out;
197 } 213 }
198 } 214 }