aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/sh/clk
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2012-04-12 06:50:40 -0400
committerPaul Mundt <lethal@linux-sh.org>2012-04-12 06:50:40 -0400
commit104fa61a7dd83197160d5cafedc0e94ad9cd7fcc (patch)
treefb450f850e0a92e6017d6343671c55e97639ad18 /drivers/sh/clk
parent4d6ddb08acc48368c5b7ac431f9d00db7227d2ed (diff)
sh: clkfwk: Support variable size accesses for div4/div6 clocks.
This follows the MSTP clock change and implements variable access size support for the rest of the CPG clocks, too. Upcoming SH-2A support has need of this for 16-bit div4 clocks, while others will follow. Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'drivers/sh/clk')
-rw-r--r--drivers/sh/clk/cpg.c71
1 files changed, 37 insertions, 34 deletions
diff --git a/drivers/sh/clk/cpg.c b/drivers/sh/clk/cpg.c
index 6cbda4841589..f0d015dd0fef 100644
--- a/drivers/sh/clk/cpg.c
+++ b/drivers/sh/clk/cpg.c
@@ -14,32 +14,35 @@
14#include <linux/io.h> 14#include <linux/io.h>
15#include <linux/sh_clk.h> 15#include <linux/sh_clk.h>
16 16
17static int sh_clk_mstp_enable(struct clk *clk) 17static unsigned int sh_clk_read(struct clk *clk)
18{ 18{
19 if (clk->flags & CLK_ENABLE_REG_8BIT) 19 if (clk->flags & CLK_ENABLE_REG_8BIT)
20 iowrite8(ioread8(clk->mapped_reg) & ~(1 << clk->enable_bit), 20 return ioread8(clk->mapped_reg);
21 clk->mapped_reg);
22 else if (clk->flags & CLK_ENABLE_REG_16BIT) 21 else if (clk->flags & CLK_ENABLE_REG_16BIT)
23 iowrite16(ioread16(clk->mapped_reg) & ~(1 << clk->enable_bit), 22 return ioread16(clk->mapped_reg);
24 clk->mapped_reg);
25 else
26 iowrite32(ioread32(clk->mapped_reg) & ~(1 << clk->enable_bit),
27 clk->mapped_reg);
28 23
29 return 0; 24 return ioread32(clk->mapped_reg);
30} 25}
31 26
32static void sh_clk_mstp_disable(struct clk *clk) 27static void sh_clk_write(int value, struct clk *clk)
33{ 28{
34 if (clk->flags & CLK_ENABLE_REG_8BIT) 29 if (clk->flags & CLK_ENABLE_REG_8BIT)
35 iowrite8(ioread8(clk->mapped_reg) | (1 << clk->enable_bit), 30 iowrite8(value, clk->mapped_reg);
36 clk->mapped_reg);
37 else if (clk->flags & CLK_ENABLE_REG_16BIT) 31 else if (clk->flags & CLK_ENABLE_REG_16BIT)
38 iowrite16(ioread16(clk->mapped_reg) | (1 << clk->enable_bit), 32 iowrite16(value, clk->mapped_reg);
39 clk->mapped_reg);
40 else 33 else
41 iowrite32(ioread32(clk->mapped_reg) | (1 << clk->enable_bit), 34 iowrite32(value, clk->mapped_reg);
42 clk->mapped_reg); 35}
36
37static int sh_clk_mstp_enable(struct clk *clk)
38{
39 sh_clk_write(sh_clk_read(clk) & ~(1 << clk->enable_bit), clk);
40 return 0;
41}
42
43static void sh_clk_mstp_disable(struct clk *clk)
44{
45 sh_clk_write(sh_clk_read(clk) | (1 << clk->enable_bit), clk);
43} 46}
44 47
45static struct sh_clk_ops sh_clk_mstp_clk_ops = { 48static struct sh_clk_ops sh_clk_mstp_clk_ops = {
@@ -88,7 +91,7 @@ static unsigned long sh_clk_div6_recalc(struct clk *clk)
88 clk_rate_table_build(clk, clk->freq_table, table->nr_divisors, 91 clk_rate_table_build(clk, clk->freq_table, table->nr_divisors,
89 table, NULL); 92 table, NULL);
90 93
91 idx = ioread32(clk->mapped_reg) & 0x003f; 94 idx = sh_clk_read(clk) & 0x003f;
92 95
93 return clk->freq_table[idx].frequency; 96 return clk->freq_table[idx].frequency;
94} 97}
@@ -114,10 +117,10 @@ static int sh_clk_div6_set_parent(struct clk *clk, struct clk *parent)
114 if (ret < 0) 117 if (ret < 0)
115 return ret; 118 return ret;
116 119
117 value = ioread32(clk->mapped_reg) & 120 value = sh_clk_read(clk) &
118 ~(((1 << clk->src_width) - 1) << clk->src_shift); 121 ~(((1 << clk->src_width) - 1) << clk->src_shift);
119 122
120 iowrite32(value | (i << clk->src_shift), clk->mapped_reg); 123 sh_clk_write(value | (i << clk->src_shift), clk);
121 124
122 /* Rebuild the frequency table */ 125 /* Rebuild the frequency table */
123 clk_rate_table_build(clk, clk->freq_table, table->nr_divisors, 126 clk_rate_table_build(clk, clk->freq_table, table->nr_divisors,
@@ -135,10 +138,10 @@ static int sh_clk_div6_set_rate(struct clk *clk, unsigned long rate)
135 if (idx < 0) 138 if (idx < 0)
136 return idx; 139 return idx;
137 140
138 value = ioread32(clk->mapped_reg); 141 value = sh_clk_read(clk);
139 value &= ~0x3f; 142 value &= ~0x3f;
140 value |= idx; 143 value |= idx;
141 iowrite32(value, clk->mapped_reg); 144 sh_clk_write(value, clk);
142 return 0; 145 return 0;
143} 146}
144 147
@@ -149,9 +152,9 @@ static int sh_clk_div6_enable(struct clk *clk)
149 152
150 ret = sh_clk_div6_set_rate(clk, clk->rate); 153 ret = sh_clk_div6_set_rate(clk, clk->rate);
151 if (ret == 0) { 154 if (ret == 0) {
152 value = ioread32(clk->mapped_reg); 155 value = sh_clk_read(clk);
153 value &= ~0x100; /* clear stop bit to enable clock */ 156 value &= ~0x100; /* clear stop bit to enable clock */
154 iowrite32(value, clk->mapped_reg); 157 sh_clk_write(value, clk);
155 } 158 }
156 return ret; 159 return ret;
157} 160}
@@ -160,10 +163,10 @@ static void sh_clk_div6_disable(struct clk *clk)
160{ 163{
161 unsigned long value; 164 unsigned long value;
162 165
163 value = ioread32(clk->mapped_reg); 166 value = sh_clk_read(clk);
164 value |= 0x100; /* stop clock */ 167 value |= 0x100; /* stop clock */
165 value |= 0x3f; /* VDIV bits must be non-zero, overwrite divider */ 168 value |= 0x3f; /* VDIV bits must be non-zero, overwrite divider */
166 iowrite32(value, clk->mapped_reg); 169 sh_clk_write(value, clk);
167} 170}
168 171
169static struct sh_clk_ops sh_clk_div6_clk_ops = { 172static struct sh_clk_ops sh_clk_div6_clk_ops = {
@@ -198,7 +201,7 @@ static int __init sh_clk_init_parent(struct clk *clk)
198 return -EINVAL; 201 return -EINVAL;
199 } 202 }
200 203
201 val = (ioread32(clk->mapped_reg) >> clk->src_shift); 204 val = (sh_clk_read(clk) >> clk->src_shift);
202 val &= (1 << clk->src_width) - 1; 205 val &= (1 << clk->src_width) - 1;
203 206
204 if (val >= clk->parent_num) { 207 if (val >= clk->parent_num) {
@@ -268,7 +271,7 @@ static unsigned long sh_clk_div4_recalc(struct clk *clk)
268 clk_rate_table_build(clk, clk->freq_table, table->nr_divisors, 271 clk_rate_table_build(clk, clk->freq_table, table->nr_divisors,
269 table, &clk->arch_flags); 272 table, &clk->arch_flags);
270 273
271 idx = (ioread32(clk->mapped_reg) >> clk->enable_bit) & 0x000f; 274 idx = (sh_clk_read(clk) >> clk->enable_bit) & 0x000f;
272 275
273 return clk->freq_table[idx].frequency; 276 return clk->freq_table[idx].frequency;
274} 277}
@@ -286,15 +289,15 @@ static int sh_clk_div4_set_parent(struct clk *clk, struct clk *parent)
286 */ 289 */
287 290
288 if (parent->flags & CLK_ENABLE_ON_INIT) 291 if (parent->flags & CLK_ENABLE_ON_INIT)
289 value = ioread32(clk->mapped_reg) & ~(1 << 7); 292 value = sh_clk_read(clk) & ~(1 << 7);
290 else 293 else
291 value = ioread32(clk->mapped_reg) | (1 << 7); 294 value = sh_clk_read(clk) | (1 << 7);
292 295
293 ret = clk_reparent(clk, parent); 296 ret = clk_reparent(clk, parent);
294 if (ret < 0) 297 if (ret < 0)
295 return ret; 298 return ret;
296 299
297 iowrite32(value, clk->mapped_reg); 300 sh_clk_write(value, clk);
298 301
299 /* Rebiuld the frequency table */ 302 /* Rebiuld the frequency table */
300 clk_rate_table_build(clk, clk->freq_table, table->nr_divisors, 303 clk_rate_table_build(clk, clk->freq_table, table->nr_divisors,
@@ -311,10 +314,10 @@ static int sh_clk_div4_set_rate(struct clk *clk, unsigned long rate)
311 if (idx < 0) 314 if (idx < 0)
312 return idx; 315 return idx;
313 316
314 value = ioread32(clk->mapped_reg); 317 value = sh_clk_read(clk);
315 value &= ~(0xf << clk->enable_bit); 318 value &= ~(0xf << clk->enable_bit);
316 value |= (idx << clk->enable_bit); 319 value |= (idx << clk->enable_bit);
317 iowrite32(value, clk->mapped_reg); 320 sh_clk_write(value, clk);
318 321
319 if (d4t->kick) 322 if (d4t->kick)
320 d4t->kick(clk); 323 d4t->kick(clk);
@@ -324,13 +327,13 @@ static int sh_clk_div4_set_rate(struct clk *clk, unsigned long rate)
324 327
325static int sh_clk_div4_enable(struct clk *clk) 328static int sh_clk_div4_enable(struct clk *clk)
326{ 329{
327 iowrite32(ioread32(clk->mapped_reg) & ~(1 << 8), clk->mapped_reg); 330 sh_clk_write(sh_clk_read(clk) & ~(1 << 8), clk);
328 return 0; 331 return 0;
329} 332}
330 333
331static void sh_clk_div4_disable(struct clk *clk) 334static void sh_clk_div4_disable(struct clk *clk)
332{ 335{
333 iowrite32(ioread32(clk->mapped_reg) | (1 << 8), clk->mapped_reg); 336 sh_clk_write(sh_clk_read(clk) | (1 << 8), clk);
334} 337}
335 338
336static struct sh_clk_ops sh_clk_div4_clk_ops = { 339static struct sh_clk_ops sh_clk_div4_clk_ops = {