aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Turquette <mturquette@linaro.org>2013-12-30 13:58:22 -0500
committerMike Turquette <mturquette@linaro.org>2013-12-30 13:58:22 -0500
commit391e3903e63781debc52a0de73f2e922dcc3f602 (patch)
tree0f06e9555dc43090f265cbe726eb6051bf7a0d51
parent6b71e0d9d6bfd24d2426a4ea7edf3c01d872903f (diff)
parente0c223ec67a98f70770eec85e625015f5af69f10 (diff)
Merge branch 'for_3.14/keystone-clk' of git://git.kernel.org/pub/scm/linux/kernel/git/ssantosh/linux-keystone into clk-next-keystone
-rw-r--r--Documentation/devicetree/bindings/clock/keystone-pll.txt8
-rw-r--r--drivers/clk/keystone/gate.c12
-rw-r--r--drivers/clk/keystone/pll.c24
3 files changed, 32 insertions, 12 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/gate.c b/drivers/clk/keystone/gate.c
index 1f333bcfc22e..17a598398a53 100644
--- a/drivers/clk/keystone/gate.c
+++ b/drivers/clk/keystone/gate.c
@@ -223,8 +223,7 @@ static void __init of_psc_clk_init(struct device_node *node, spinlock_t *lock)
223 data->domain_base = of_iomap(node, i); 223 data->domain_base = of_iomap(node, i);
224 if (!data->domain_base) { 224 if (!data->domain_base) {
225 pr_err("%s: domain ioremap failed\n", __func__); 225 pr_err("%s: domain ioremap failed\n", __func__);
226 iounmap(data->control_base); 226 goto unmap_ctrl;
227 goto out;
228 } 227 }
229 228
230 of_property_read_u32(node, "domain-id", &data->domain_id); 229 of_property_read_u32(node, "domain-id", &data->domain_id);
@@ -237,16 +236,21 @@ static void __init of_psc_clk_init(struct device_node *node, spinlock_t *lock)
237 parent_name = of_clk_get_parent_name(node, 0); 236 parent_name = of_clk_get_parent_name(node, 0);
238 if (!parent_name) { 237 if (!parent_name) {
239 pr_err("%s: Parent clock not found\n", __func__); 238 pr_err("%s: Parent clock not found\n", __func__);
240 goto out; 239 goto unmap_domain;
241 } 240 }
242 241
243 clk = clk_register_psc(NULL, clk_name, parent_name, data, lock); 242 clk = clk_register_psc(NULL, clk_name, parent_name, data, lock);
244 if (clk) { 243 if (!IS_ERR(clk)) {
245 of_clk_add_provider(node, of_clk_src_simple_get, clk); 244 of_clk_add_provider(node, of_clk_src_simple_get, clk);
246 return; 245 return;
247 } 246 }
248 247
249 pr_err("%s: error registering clk %s\n", __func__, node->name); 248 pr_err("%s: error registering clk %s\n", __func__, node->name);
249
250unmap_domain:
251 iounmap(data->domain_base);
252unmap_ctrl:
253 iounmap(data->control_base);
250out: 254out:
251 kfree(data); 255 kfree(data);
252 return; 256 return;
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);