aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMurali Karicheri <m-karicheri2@ti.com>2013-11-23 16:26:52 -0500
committerSantosh Shilimkar <santosh.shilimkar@ti.com>2013-12-10 11:08:20 -0500
commitdbb4e67fe7088f963007453ee07e453c4e1fab28 (patch)
treea5e0fc1fbb0ad4f659f2acc47b00d35cbe7a5506
parent6ce4eac1f600b34f2f7f58f9cd8f0503d79e42ae (diff)
clk: keystone: use clkod register bits for postdiv
DDR3A/B, ARM and PA PLL controllers have clkod register bits for configuring postdiv values. So use it instead of using fixed post dividers for these pll controllers. Assume that if fixed-postdiv attribute is not present, use clkod register value for pistdiv. Also update the Documentation of bindings to reflect the same. Cc: Mike Turquette <mturquette@linaro.org Signed-off-by: Murali Karicheri <m-karicheri2@ti.com> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
-rw-r--r--Documentation/devicetree/bindings/clock/keystone-pll.txt8
-rw-r--r--drivers/clk/keystone/pll.c24
2 files changed, 24 insertions, 8 deletions
diff --git a/Documentation/devicetree/bindings/clock/keystone-pll.txt b/Documentation/devicetree/bindings/clock/keystone-pll.txt
index 12bd72605a31..225990f79b7c 100644
--- a/Documentation/devicetree/bindings/clock/keystone-pll.txt
+++ b/Documentation/devicetree/bindings/clock/keystone-pll.txt
@@ -17,13 +17,14 @@ Required properties:
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 and multiplier. The multiplier is applicable only for
19 main pll clock 19 main pll clock
20- fixed-postdiv : fixed post divider value 20- fixed-postdiv : fixed post divider value. If absent, use clkod register bits
21 for postdiv
21 22
22Example: 23Example:
23 mainpllclk: mainpllclk@2310110 { 24 mainpllclk: mainpllclk@2310110 {
24 #clock-cells = <0>; 25 #clock-cells = <0>;
25 compatible = "ti,keystone,main-pll-clock"; 26 compatible = "ti,keystone,main-pll-clock";
26 clocks = <&refclkmain>; 27 clocks = <&refclksys>;
27 reg = <0x02620350 4>, <0x02310110 4>; 28 reg = <0x02620350 4>, <0x02310110 4>;
28 reg-names = "control", "multiplier"; 29 reg-names = "control", "multiplier";
29 fixed-postdiv = <2>; 30 fixed-postdiv = <2>;
@@ -32,11 +33,10 @@ Example:
32 papllclk: papllclk@2620358 { 33 papllclk: papllclk@2620358 {
33 #clock-cells = <0>; 34 #clock-cells = <0>;
34 compatible = "ti,keystone,pll-clock"; 35 compatible = "ti,keystone,pll-clock";
35 clocks = <&refclkmain>; 36 clocks = <&refclkpass>;
36 clock-output-names = "pa-pll-clk"; 37 clock-output-names = "pa-pll-clk";
37 reg = <0x02620358 4>; 38 reg = <0x02620358 4>;
38 reg-names = "control"; 39 reg-names = "control";
39 fixed-postdiv = <6>;
40 }; 40 };
41 41
42Required properties: 42Required properties:
diff --git a/drivers/clk/keystone/pll.c b/drivers/clk/keystone/pll.c
index 47a1bd9f1726..0dd8a4b12747 100644
--- a/drivers/clk/keystone/pll.c
+++ b/drivers/clk/keystone/pll.c
@@ -24,6 +24,8 @@
24#define MAIN_PLLM_HIGH_MASK 0x7f000 24#define MAIN_PLLM_HIGH_MASK 0x7f000
25#define PLLM_HIGH_SHIFT 6 25#define PLLM_HIGH_SHIFT 6
26#define PLLD_MASK 0x3f 26#define PLLD_MASK 0x3f
27#define CLKOD_MASK 0x780000
28#define CLKOD_SHIFT 19
27 29
28/** 30/**
29 * struct clk_pll_data - pll data structure 31 * struct clk_pll_data - pll data structure
@@ -41,7 +43,10 @@
41 * @pllm_upper_mask: multiplier upper mask 43 * @pllm_upper_mask: multiplier upper mask
42 * @pllm_upper_shift: multiplier upper shift 44 * @pllm_upper_shift: multiplier upper shift
43 * @plld_mask: divider mask 45 * @plld_mask: divider mask
44 * @postdiv: Post divider 46 * @clkod_mask: output divider mask
47 * @clkod_shift: output divider shift
48 * @plld_mask: divider mask
49 * @postdiv: Fixed post divider
45 */ 50 */
46struct clk_pll_data { 51struct clk_pll_data {
47 bool has_pllctrl; 52 bool has_pllctrl;
@@ -53,6 +58,8 @@ struct clk_pll_data {
53 u32 pllm_upper_mask; 58 u32 pllm_upper_mask;
54 u32 pllm_upper_shift; 59 u32 pllm_upper_shift;
55 u32 plld_mask; 60 u32 plld_mask;
61 u32 clkod_mask;
62 u32 clkod_shift;
56 u32 postdiv; 63 u32 postdiv;
57}; 64};
58 65
@@ -90,7 +97,13 @@ static unsigned long clk_pllclk_recalc(struct clk_hw *hw,
90 mult |= ((val & pll_data->pllm_upper_mask) 97 mult |= ((val & pll_data->pllm_upper_mask)
91 >> pll_data->pllm_upper_shift); 98 >> pll_data->pllm_upper_shift);
92 prediv = (val & pll_data->plld_mask); 99 prediv = (val & pll_data->plld_mask);
93 postdiv = pll_data->postdiv; 100
101 if (!pll_data->has_pllctrl)
102 /* read post divider from od bits*/
103 postdiv = ((val & pll_data->clkod_mask) >>
104 pll_data->clkod_shift) + 1;
105 else
106 postdiv = pll_data->postdiv;
94 107
95 rate /= (prediv + 1); 108 rate /= (prediv + 1);
96 rate = (rate * (mult + 1)); 109 rate = (rate * (mult + 1));
@@ -155,8 +168,11 @@ static void __init _of_pll_clk_init(struct device_node *node, bool pllctrl)
155 } 168 }
156 169
157 parent_name = of_clk_get_parent_name(node, 0); 170 parent_name = of_clk_get_parent_name(node, 0);
158 if (of_property_read_u32(node, "fixed-postdiv", &pll_data->postdiv)) 171 if (of_property_read_u32(node, "fixed-postdiv", &pll_data->postdiv)) {
159 goto out; 172 /* assume the PLL has output divider register bits */
173 pll_data->clkod_mask = CLKOD_MASK;
174 pll_data->clkod_shift = CLKOD_SHIFT;
175 }
160 176
161 i = of_property_match_string(node, "reg-names", "control"); 177 i = of_property_match_string(node, "reg-names", "control");
162 pll_data->pll_ctl0 = of_iomap(node, i); 178 pll_data->pll_ctl0 = of_iomap(node, i);