diff options
Diffstat (limited to 'arch/arm/mach-omap1/clock.c')
-rw-r--r-- | arch/arm/mach-omap1/clock.c | 407 |
1 files changed, 238 insertions, 169 deletions
diff --git a/arch/arm/mach-omap1/clock.c b/arch/arm/mach-omap1/clock.c index 5fba20731710..dafe4f71d15f 100644 --- a/arch/arm/mach-omap1/clock.c +++ b/arch/arm/mach-omap1/clock.c | |||
@@ -20,41 +20,161 @@ | |||
20 | #include <linux/io.h> | 20 | #include <linux/io.h> |
21 | 21 | ||
22 | #include <asm/mach-types.h> | 22 | #include <asm/mach-types.h> |
23 | #include <asm/clkdev.h> | ||
23 | 24 | ||
24 | #include <mach/cpu.h> | 25 | #include <mach/cpu.h> |
25 | #include <mach/usb.h> | 26 | #include <mach/usb.h> |
26 | #include <mach/clock.h> | 27 | #include <mach/clock.h> |
27 | #include <mach/sram.h> | 28 | #include <mach/sram.h> |
28 | 29 | ||
30 | static const struct clkops clkops_generic; | ||
31 | static const struct clkops clkops_uart; | ||
32 | static const struct clkops clkops_dspck; | ||
33 | |||
29 | #include "clock.h" | 34 | #include "clock.h" |
30 | 35 | ||
36 | static int clk_omap1_dummy_enable(struct clk *clk) | ||
37 | { | ||
38 | return 0; | ||
39 | } | ||
40 | |||
41 | static void clk_omap1_dummy_disable(struct clk *clk) | ||
42 | { | ||
43 | } | ||
44 | |||
45 | static const struct clkops clkops_dummy = { | ||
46 | .enable = clk_omap1_dummy_enable, | ||
47 | .disable = clk_omap1_dummy_disable, | ||
48 | }; | ||
49 | |||
50 | static struct clk dummy_ck = { | ||
51 | .name = "dummy", | ||
52 | .ops = &clkops_dummy, | ||
53 | .flags = RATE_FIXED, | ||
54 | }; | ||
55 | |||
56 | struct omap_clk { | ||
57 | u32 cpu; | ||
58 | struct clk_lookup lk; | ||
59 | }; | ||
60 | |||
61 | #define CLK(dev, con, ck, cp) \ | ||
62 | { \ | ||
63 | .cpu = cp, \ | ||
64 | .lk = { \ | ||
65 | .dev_id = dev, \ | ||
66 | .con_id = con, \ | ||
67 | .clk = ck, \ | ||
68 | }, \ | ||
69 | } | ||
70 | |||
71 | #define CK_310 (1 << 0) | ||
72 | #define CK_730 (1 << 1) | ||
73 | #define CK_1510 (1 << 2) | ||
74 | #define CK_16XX (1 << 3) | ||
75 | |||
76 | static struct omap_clk omap_clks[] = { | ||
77 | /* non-ULPD clocks */ | ||
78 | CLK(NULL, "ck_ref", &ck_ref, CK_16XX | CK_1510 | CK_310), | ||
79 | CLK(NULL, "ck_dpll1", &ck_dpll1, CK_16XX | CK_1510 | CK_310), | ||
80 | /* CK_GEN1 clocks */ | ||
81 | CLK(NULL, "ck_dpll1out", &ck_dpll1out.clk, CK_16XX), | ||
82 | CLK(NULL, "ck_sossi", &sossi_ck, CK_16XX), | ||
83 | CLK(NULL, "arm_ck", &arm_ck, CK_16XX | CK_1510 | CK_310), | ||
84 | CLK(NULL, "armper_ck", &armper_ck.clk, CK_16XX | CK_1510 | CK_310), | ||
85 | CLK(NULL, "arm_gpio_ck", &arm_gpio_ck, CK_1510 | CK_310), | ||
86 | CLK(NULL, "armxor_ck", &armxor_ck.clk, CK_16XX | CK_1510 | CK_310), | ||
87 | CLK(NULL, "armtim_ck", &armtim_ck.clk, CK_16XX | CK_1510 | CK_310), | ||
88 | CLK("omap_wdt", "fck", &armwdt_ck.clk, CK_16XX | CK_1510 | CK_310), | ||
89 | CLK("omap_wdt", "ick", &armper_ck.clk, CK_16XX), | ||
90 | CLK("omap_wdt", "ick", &dummy_ck, CK_1510 | CK_310), | ||
91 | CLK(NULL, "arminth_ck", &arminth_ck1510, CK_1510 | CK_310), | ||
92 | CLK(NULL, "arminth_ck", &arminth_ck16xx, CK_16XX), | ||
93 | /* CK_GEN2 clocks */ | ||
94 | CLK(NULL, "dsp_ck", &dsp_ck, CK_16XX | CK_1510 | CK_310), | ||
95 | CLK(NULL, "dspmmu_ck", &dspmmu_ck, CK_16XX | CK_1510 | CK_310), | ||
96 | CLK(NULL, "dspper_ck", &dspper_ck, CK_16XX | CK_1510 | CK_310), | ||
97 | CLK(NULL, "dspxor_ck", &dspxor_ck, CK_16XX | CK_1510 | CK_310), | ||
98 | CLK(NULL, "dsptim_ck", &dsptim_ck, CK_16XX | CK_1510 | CK_310), | ||
99 | /* CK_GEN3 clocks */ | ||
100 | CLK(NULL, "tc_ck", &tc_ck.clk, CK_16XX | CK_1510 | CK_310 | CK_730), | ||
101 | CLK(NULL, "tipb_ck", &tipb_ck, CK_1510 | CK_310), | ||
102 | CLK(NULL, "l3_ocpi_ck", &l3_ocpi_ck, CK_16XX), | ||
103 | CLK(NULL, "tc1_ck", &tc1_ck, CK_16XX), | ||
104 | CLK(NULL, "tc2_ck", &tc2_ck, CK_16XX), | ||
105 | CLK(NULL, "dma_ck", &dma_ck, CK_16XX | CK_1510 | CK_310), | ||
106 | CLK(NULL, "dma_lcdfree_ck", &dma_lcdfree_ck, CK_16XX), | ||
107 | CLK(NULL, "api_ck", &api_ck.clk, CK_16XX | CK_1510 | CK_310), | ||
108 | CLK(NULL, "lb_ck", &lb_ck.clk, CK_1510 | CK_310), | ||
109 | CLK(NULL, "rhea1_ck", &rhea1_ck, CK_16XX), | ||
110 | CLK(NULL, "rhea2_ck", &rhea2_ck, CK_16XX), | ||
111 | CLK(NULL, "lcd_ck", &lcd_ck_16xx, CK_16XX | CK_730), | ||
112 | CLK(NULL, "lcd_ck", &lcd_ck_1510.clk, CK_1510 | CK_310), | ||
113 | /* ULPD clocks */ | ||
114 | CLK(NULL, "uart1_ck", &uart1_1510, CK_1510 | CK_310), | ||
115 | CLK(NULL, "uart1_ck", &uart1_16xx.clk, CK_16XX), | ||
116 | CLK(NULL, "uart2_ck", &uart2_ck, CK_16XX | CK_1510 | CK_310), | ||
117 | CLK(NULL, "uart3_ck", &uart3_1510, CK_1510 | CK_310), | ||
118 | CLK(NULL, "uart3_ck", &uart3_16xx.clk, CK_16XX), | ||
119 | CLK(NULL, "usb_clko", &usb_clko, CK_16XX | CK_1510 | CK_310), | ||
120 | CLK(NULL, "usb_hhc_ck", &usb_hhc_ck1510, CK_1510 | CK_310), | ||
121 | CLK(NULL, "usb_hhc_ck", &usb_hhc_ck16xx, CK_16XX), | ||
122 | CLK(NULL, "usb_dc_ck", &usb_dc_ck, CK_16XX), | ||
123 | CLK(NULL, "mclk", &mclk_1510, CK_1510 | CK_310), | ||
124 | CLK(NULL, "mclk", &mclk_16xx, CK_16XX), | ||
125 | CLK(NULL, "bclk", &bclk_1510, CK_1510 | CK_310), | ||
126 | CLK(NULL, "bclk", &bclk_16xx, CK_16XX), | ||
127 | CLK("mmci-omap.0", "fck", &mmc1_ck, CK_16XX | CK_1510 | CK_310), | ||
128 | CLK("mmci-omap.0", "ick", &armper_ck.clk, CK_16XX | CK_1510 | CK_310), | ||
129 | CLK("mmci-omap.1", "fck", &mmc2_ck, CK_16XX), | ||
130 | CLK("mmci-omap.1", "ick", &armper_ck.clk, CK_16XX), | ||
131 | /* Virtual clocks */ | ||
132 | CLK(NULL, "mpu", &virtual_ck_mpu, CK_16XX | CK_1510 | CK_310), | ||
133 | CLK("i2c_omap.1", "fck", &i2c_fck, CK_16XX | CK_1510 | CK_310), | ||
134 | CLK("i2c_omap.1", "ick", &i2c_ick, CK_16XX), | ||
135 | CLK("i2c_omap.1", "ick", &dummy_ck, CK_1510 | CK_310), | ||
136 | CLK("omap_uwire", "fck", &armxor_ck.clk, CK_16XX | CK_1510 | CK_310), | ||
137 | CLK("omap-mcbsp.1", "ick", &dspper_ck, CK_16XX), | ||
138 | CLK("omap-mcbsp.1", "ick", &dummy_ck, CK_1510 | CK_310), | ||
139 | CLK("omap-mcbsp.2", "ick", &armper_ck.clk, CK_16XX), | ||
140 | CLK("omap-mcbsp.2", "ick", &dummy_ck, CK_1510 | CK_310), | ||
141 | CLK("omap-mcbsp.3", "ick", &dspper_ck, CK_16XX), | ||
142 | CLK("omap-mcbsp.3", "ick", &dummy_ck, CK_1510 | CK_310), | ||
143 | CLK("omap-mcbsp.1", "fck", &dspxor_ck, CK_16XX | CK_1510 | CK_310), | ||
144 | CLK("omap-mcbsp.2", "fck", &armper_ck.clk, CK_16XX | CK_1510 | CK_310), | ||
145 | CLK("omap-mcbsp.3", "fck", &dspxor_ck, CK_16XX | CK_1510 | CK_310), | ||
146 | }; | ||
147 | |||
148 | static int omap1_clk_enable_generic(struct clk * clk); | ||
149 | static int omap1_clk_enable(struct clk *clk); | ||
150 | static void omap1_clk_disable_generic(struct clk * clk); | ||
151 | static void omap1_clk_disable(struct clk *clk); | ||
152 | |||
31 | __u32 arm_idlect1_mask; | 153 | __u32 arm_idlect1_mask; |
32 | 154 | ||
33 | /*------------------------------------------------------------------------- | 155 | /*------------------------------------------------------------------------- |
34 | * Omap1 specific clock functions | 156 | * Omap1 specific clock functions |
35 | *-------------------------------------------------------------------------*/ | 157 | *-------------------------------------------------------------------------*/ |
36 | 158 | ||
37 | static void omap1_watchdog_recalc(struct clk * clk) | 159 | static unsigned long omap1_watchdog_recalc(struct clk *clk) |
38 | { | 160 | { |
39 | clk->rate = clk->parent->rate / 14; | 161 | return clk->parent->rate / 14; |
40 | } | 162 | } |
41 | 163 | ||
42 | static void omap1_uart_recalc(struct clk * clk) | 164 | static unsigned long omap1_uart_recalc(struct clk *clk) |
43 | { | 165 | { |
44 | unsigned int val = omap_readl(clk->enable_reg); | 166 | unsigned int val = __raw_readl(clk->enable_reg); |
45 | if (val & clk->enable_bit) | 167 | return val & clk->enable_bit ? 48000000 : 12000000; |
46 | clk->rate = 48000000; | ||
47 | else | ||
48 | clk->rate = 12000000; | ||
49 | } | 168 | } |
50 | 169 | ||
51 | static void omap1_sossi_recalc(struct clk *clk) | 170 | static unsigned long omap1_sossi_recalc(struct clk *clk) |
52 | { | 171 | { |
53 | u32 div = omap_readl(MOD_CONF_CTRL_1); | 172 | u32 div = omap_readl(MOD_CONF_CTRL_1); |
54 | 173 | ||
55 | div = (div >> 17) & 0x7; | 174 | div = (div >> 17) & 0x7; |
56 | div++; | 175 | div++; |
57 | clk->rate = clk->parent->rate / div; | 176 | |
177 | return clk->parent->rate / div; | ||
58 | } | 178 | } |
59 | 179 | ||
60 | static int omap1_clk_enable_dsp_domain(struct clk *clk) | 180 | static int omap1_clk_enable_dsp_domain(struct clk *clk) |
@@ -78,6 +198,11 @@ static void omap1_clk_disable_dsp_domain(struct clk *clk) | |||
78 | } | 198 | } |
79 | } | 199 | } |
80 | 200 | ||
201 | static const struct clkops clkops_dspck = { | ||
202 | .enable = &omap1_clk_enable_dsp_domain, | ||
203 | .disable = &omap1_clk_disable_dsp_domain, | ||
204 | }; | ||
205 | |||
81 | static int omap1_clk_enable_uart_functional(struct clk *clk) | 206 | static int omap1_clk_enable_uart_functional(struct clk *clk) |
82 | { | 207 | { |
83 | int ret; | 208 | int ret; |
@@ -105,6 +230,11 @@ static void omap1_clk_disable_uart_functional(struct clk *clk) | |||
105 | omap1_clk_disable_generic(clk); | 230 | omap1_clk_disable_generic(clk); |
106 | } | 231 | } |
107 | 232 | ||
233 | static const struct clkops clkops_uart = { | ||
234 | .enable = &omap1_clk_enable_uart_functional, | ||
235 | .disable = &omap1_clk_disable_uart_functional, | ||
236 | }; | ||
237 | |||
108 | static void omap1_clk_allow_idle(struct clk *clk) | 238 | static void omap1_clk_allow_idle(struct clk *clk) |
109 | { | 239 | { |
110 | struct arm_idlect1_clk * iclk = (struct arm_idlect1_clk *)clk; | 240 | struct arm_idlect1_clk * iclk = (struct arm_idlect1_clk *)clk; |
@@ -197,9 +327,6 @@ static int calc_dsor_exp(struct clk *clk, unsigned long rate) | |||
197 | struct clk * parent; | 327 | struct clk * parent; |
198 | unsigned dsor_exp; | 328 | unsigned dsor_exp; |
199 | 329 | ||
200 | if (unlikely(!(clk->flags & RATE_CKCTL))) | ||
201 | return -EINVAL; | ||
202 | |||
203 | parent = clk->parent; | 330 | parent = clk->parent; |
204 | if (unlikely(parent == NULL)) | 331 | if (unlikely(parent == NULL)) |
205 | return -EIO; | 332 | return -EIO; |
@@ -215,22 +342,15 @@ static int calc_dsor_exp(struct clk *clk, unsigned long rate) | |||
215 | return dsor_exp; | 342 | return dsor_exp; |
216 | } | 343 | } |
217 | 344 | ||
218 | static void omap1_ckctl_recalc(struct clk * clk) | 345 | static unsigned long omap1_ckctl_recalc(struct clk *clk) |
219 | { | 346 | { |
220 | int dsor; | ||
221 | |||
222 | /* Calculate divisor encoded as 2-bit exponent */ | 347 | /* Calculate divisor encoded as 2-bit exponent */ |
223 | dsor = 1 << (3 & (omap_readw(ARM_CKCTL) >> clk->rate_offset)); | 348 | int dsor = 1 << (3 & (omap_readw(ARM_CKCTL) >> clk->rate_offset)); |
224 | 349 | ||
225 | if (unlikely(clk->rate == clk->parent->rate / dsor)) | 350 | return clk->parent->rate / dsor; |
226 | return; /* No change, quick exit */ | ||
227 | clk->rate = clk->parent->rate / dsor; | ||
228 | |||
229 | if (unlikely(clk->flags & RATE_PROPAGATES)) | ||
230 | propagate_rate(clk); | ||
231 | } | 351 | } |
232 | 352 | ||
233 | static void omap1_ckctl_recalc_dsp_domain(struct clk * clk) | 353 | static unsigned long omap1_ckctl_recalc_dsp_domain(struct clk *clk) |
234 | { | 354 | { |
235 | int dsor; | 355 | int dsor; |
236 | 356 | ||
@@ -245,12 +365,7 @@ static void omap1_ckctl_recalc_dsp_domain(struct clk * clk) | |||
245 | dsor = 1 << (3 & (__raw_readw(DSP_CKCTL) >> clk->rate_offset)); | 365 | dsor = 1 << (3 & (__raw_readw(DSP_CKCTL) >> clk->rate_offset)); |
246 | omap1_clk_disable(&api_ck.clk); | 366 | omap1_clk_disable(&api_ck.clk); |
247 | 367 | ||
248 | if (unlikely(clk->rate == clk->parent->rate / dsor)) | 368 | return clk->parent->rate / dsor; |
249 | return; /* No change, quick exit */ | ||
250 | clk->rate = clk->parent->rate / dsor; | ||
251 | |||
252 | if (unlikely(clk->flags & RATE_PROPAGATES)) | ||
253 | propagate_rate(clk); | ||
254 | } | 369 | } |
255 | 370 | ||
256 | /* MPU virtual clock functions */ | 371 | /* MPU virtual clock functions */ |
@@ -289,35 +404,57 @@ static int omap1_select_table_rate(struct clk * clk, unsigned long rate) | |||
289 | omap_sram_reprogram_clock(ptr->dpllctl_val, ptr->ckctl_val); | 404 | omap_sram_reprogram_clock(ptr->dpllctl_val, ptr->ckctl_val); |
290 | 405 | ||
291 | ck_dpll1.rate = ptr->pll_rate; | 406 | ck_dpll1.rate = ptr->pll_rate; |
292 | propagate_rate(&ck_dpll1); | ||
293 | return 0; | 407 | return 0; |
294 | } | 408 | } |
295 | 409 | ||
296 | static int omap1_clk_set_rate_dsp_domain(struct clk *clk, unsigned long rate) | 410 | static int omap1_clk_set_rate_dsp_domain(struct clk *clk, unsigned long rate) |
297 | { | 411 | { |
298 | int ret = -EINVAL; | 412 | int dsor_exp; |
299 | int dsor_exp; | 413 | u16 regval; |
300 | __u16 regval; | ||
301 | |||
302 | if (clk->flags & RATE_CKCTL) { | ||
303 | dsor_exp = calc_dsor_exp(clk, rate); | ||
304 | if (dsor_exp > 3) | ||
305 | dsor_exp = -EINVAL; | ||
306 | if (dsor_exp < 0) | ||
307 | return dsor_exp; | ||
308 | |||
309 | regval = __raw_readw(DSP_CKCTL); | ||
310 | regval &= ~(3 << clk->rate_offset); | ||
311 | regval |= dsor_exp << clk->rate_offset; | ||
312 | __raw_writew(regval, DSP_CKCTL); | ||
313 | clk->rate = clk->parent->rate / (1 << dsor_exp); | ||
314 | ret = 0; | ||
315 | } | ||
316 | 414 | ||
317 | if (unlikely(ret == 0 && (clk->flags & RATE_PROPAGATES))) | 415 | dsor_exp = calc_dsor_exp(clk, rate); |
318 | propagate_rate(clk); | 416 | if (dsor_exp > 3) |
417 | dsor_exp = -EINVAL; | ||
418 | if (dsor_exp < 0) | ||
419 | return dsor_exp; | ||
319 | 420 | ||
320 | return ret; | 421 | regval = __raw_readw(DSP_CKCTL); |
422 | regval &= ~(3 << clk->rate_offset); | ||
423 | regval |= dsor_exp << clk->rate_offset; | ||
424 | __raw_writew(regval, DSP_CKCTL); | ||
425 | clk->rate = clk->parent->rate / (1 << dsor_exp); | ||
426 | |||
427 | return 0; | ||
428 | } | ||
429 | |||
430 | static long omap1_clk_round_rate_ckctl_arm(struct clk *clk, unsigned long rate) | ||
431 | { | ||
432 | int dsor_exp = calc_dsor_exp(clk, rate); | ||
433 | if (dsor_exp < 0) | ||
434 | return dsor_exp; | ||
435 | if (dsor_exp > 3) | ||
436 | dsor_exp = 3; | ||
437 | return clk->parent->rate / (1 << dsor_exp); | ||
438 | } | ||
439 | |||
440 | static int omap1_clk_set_rate_ckctl_arm(struct clk *clk, unsigned long rate) | ||
441 | { | ||
442 | int dsor_exp; | ||
443 | u16 regval; | ||
444 | |||
445 | dsor_exp = calc_dsor_exp(clk, rate); | ||
446 | if (dsor_exp > 3) | ||
447 | dsor_exp = -EINVAL; | ||
448 | if (dsor_exp < 0) | ||
449 | return dsor_exp; | ||
450 | |||
451 | regval = omap_readw(ARM_CKCTL); | ||
452 | regval &= ~(3 << clk->rate_offset); | ||
453 | regval |= dsor_exp << clk->rate_offset; | ||
454 | regval = verify_ckctl_value(regval); | ||
455 | omap_writew(regval, ARM_CKCTL); | ||
456 | clk->rate = clk->parent->rate / (1 << dsor_exp); | ||
457 | return 0; | ||
321 | } | 458 | } |
322 | 459 | ||
323 | static long omap1_round_to_table_rate(struct clk * clk, unsigned long rate) | 460 | static long omap1_round_to_table_rate(struct clk * clk, unsigned long rate) |
@@ -372,14 +509,14 @@ static int omap1_set_uart_rate(struct clk * clk, unsigned long rate) | |||
372 | { | 509 | { |
373 | unsigned int val; | 510 | unsigned int val; |
374 | 511 | ||
375 | val = omap_readl(clk->enable_reg); | 512 | val = __raw_readl(clk->enable_reg); |
376 | if (rate == 12000000) | 513 | if (rate == 12000000) |
377 | val &= ~(1 << clk->enable_bit); | 514 | val &= ~(1 << clk->enable_bit); |
378 | else if (rate == 48000000) | 515 | else if (rate == 48000000) |
379 | val |= (1 << clk->enable_bit); | 516 | val |= (1 << clk->enable_bit); |
380 | else | 517 | else |
381 | return -EINVAL; | 518 | return -EINVAL; |
382 | omap_writel(val, clk->enable_reg); | 519 | __raw_writel(val, clk->enable_reg); |
383 | clk->rate = rate; | 520 | clk->rate = rate; |
384 | 521 | ||
385 | return 0; | 522 | return 0; |
@@ -398,8 +535,8 @@ static int omap1_set_ext_clk_rate(struct clk * clk, unsigned long rate) | |||
398 | else | 535 | else |
399 | ratio_bits = (dsor - 2) << 2; | 536 | ratio_bits = (dsor - 2) << 2; |
400 | 537 | ||
401 | ratio_bits |= omap_readw(clk->enable_reg) & ~0xfd; | 538 | ratio_bits |= __raw_readw(clk->enable_reg) & ~0xfd; |
402 | omap_writew(ratio_bits, clk->enable_reg); | 539 | __raw_writew(ratio_bits, clk->enable_reg); |
403 | 540 | ||
404 | return 0; | 541 | return 0; |
405 | } | 542 | } |
@@ -423,8 +560,6 @@ static int omap1_set_sossi_rate(struct clk *clk, unsigned long rate) | |||
423 | omap_writel(l, MOD_CONF_CTRL_1); | 560 | omap_writel(l, MOD_CONF_CTRL_1); |
424 | 561 | ||
425 | clk->rate = p_rate / (div + 1); | 562 | clk->rate = p_rate / (div + 1); |
426 | if (unlikely(clk->flags & RATE_PROPAGATES)) | ||
427 | propagate_rate(clk); | ||
428 | 563 | ||
429 | return 0; | 564 | return 0; |
430 | } | 565 | } |
@@ -440,8 +575,8 @@ static void omap1_init_ext_clk(struct clk * clk) | |||
440 | __u16 ratio_bits; | 575 | __u16 ratio_bits; |
441 | 576 | ||
442 | /* Determine current rate and ensure clock is based on 96MHz APLL */ | 577 | /* Determine current rate and ensure clock is based on 96MHz APLL */ |
443 | ratio_bits = omap_readw(clk->enable_reg) & ~1; | 578 | ratio_bits = __raw_readw(clk->enable_reg) & ~1; |
444 | omap_writew(ratio_bits, clk->enable_reg); | 579 | __raw_writew(ratio_bits, clk->enable_reg); |
445 | 580 | ||
446 | ratio_bits = (ratio_bits & 0xfc) >> 2; | 581 | ratio_bits = (ratio_bits & 0xfc) >> 2; |
447 | if (ratio_bits > 6) | 582 | if (ratio_bits > 6) |
@@ -468,7 +603,7 @@ static int omap1_clk_enable(struct clk *clk) | |||
468 | omap1_clk_deny_idle(clk->parent); | 603 | omap1_clk_deny_idle(clk->parent); |
469 | } | 604 | } |
470 | 605 | ||
471 | ret = clk->enable(clk); | 606 | ret = clk->ops->enable(clk); |
472 | 607 | ||
473 | if (unlikely(ret != 0) && clk->parent) { | 608 | if (unlikely(ret != 0) && clk->parent) { |
474 | omap1_clk_disable(clk->parent); | 609 | omap1_clk_disable(clk->parent); |
@@ -482,7 +617,7 @@ static int omap1_clk_enable(struct clk *clk) | |||
482 | static void omap1_clk_disable(struct clk *clk) | 617 | static void omap1_clk_disable(struct clk *clk) |
483 | { | 618 | { |
484 | if (clk->usecount > 0 && !(--clk->usecount)) { | 619 | if (clk->usecount > 0 && !(--clk->usecount)) { |
485 | clk->disable(clk); | 620 | clk->ops->disable(clk); |
486 | if (likely(clk->parent)) { | 621 | if (likely(clk->parent)) { |
487 | omap1_clk_disable(clk->parent); | 622 | omap1_clk_disable(clk->parent); |
488 | if (clk->flags & CLOCK_NO_IDLE_PARENT) | 623 | if (clk->flags & CLOCK_NO_IDLE_PARENT) |
@@ -496,9 +631,6 @@ static int omap1_clk_enable_generic(struct clk *clk) | |||
496 | __u16 regval16; | 631 | __u16 regval16; |
497 | __u32 regval32; | 632 | __u32 regval32; |
498 | 633 | ||
499 | if (clk->flags & ALWAYS_ENABLED) | ||
500 | return 0; | ||
501 | |||
502 | if (unlikely(clk->enable_reg == NULL)) { | 634 | if (unlikely(clk->enable_reg == NULL)) { |
503 | printk(KERN_ERR "clock.c: Enable for %s without enable code\n", | 635 | printk(KERN_ERR "clock.c: Enable for %s without enable code\n", |
504 | clk->name); | 636 | clk->name); |
@@ -506,25 +638,13 @@ static int omap1_clk_enable_generic(struct clk *clk) | |||
506 | } | 638 | } |
507 | 639 | ||
508 | if (clk->flags & ENABLE_REG_32BIT) { | 640 | if (clk->flags & ENABLE_REG_32BIT) { |
509 | if (clk->flags & VIRTUAL_IO_ADDRESS) { | 641 | regval32 = __raw_readl(clk->enable_reg); |
510 | regval32 = __raw_readl(clk->enable_reg); | 642 | regval32 |= (1 << clk->enable_bit); |
511 | regval32 |= (1 << clk->enable_bit); | 643 | __raw_writel(regval32, clk->enable_reg); |
512 | __raw_writel(regval32, clk->enable_reg); | ||
513 | } else { | ||
514 | regval32 = omap_readl(clk->enable_reg); | ||
515 | regval32 |= (1 << clk->enable_bit); | ||
516 | omap_writel(regval32, clk->enable_reg); | ||
517 | } | ||
518 | } else { | 644 | } else { |
519 | if (clk->flags & VIRTUAL_IO_ADDRESS) { | 645 | regval16 = __raw_readw(clk->enable_reg); |
520 | regval16 = __raw_readw(clk->enable_reg); | 646 | regval16 |= (1 << clk->enable_bit); |
521 | regval16 |= (1 << clk->enable_bit); | 647 | __raw_writew(regval16, clk->enable_reg); |
522 | __raw_writew(regval16, clk->enable_reg); | ||
523 | } else { | ||
524 | regval16 = omap_readw(clk->enable_reg); | ||
525 | regval16 |= (1 << clk->enable_bit); | ||
526 | omap_writew(regval16, clk->enable_reg); | ||
527 | } | ||
528 | } | 648 | } |
529 | 649 | ||
530 | return 0; | 650 | return 0; |
@@ -539,44 +659,26 @@ static void omap1_clk_disable_generic(struct clk *clk) | |||
539 | return; | 659 | return; |
540 | 660 | ||
541 | if (clk->flags & ENABLE_REG_32BIT) { | 661 | if (clk->flags & ENABLE_REG_32BIT) { |
542 | if (clk->flags & VIRTUAL_IO_ADDRESS) { | 662 | regval32 = __raw_readl(clk->enable_reg); |
543 | regval32 = __raw_readl(clk->enable_reg); | 663 | regval32 &= ~(1 << clk->enable_bit); |
544 | regval32 &= ~(1 << clk->enable_bit); | 664 | __raw_writel(regval32, clk->enable_reg); |
545 | __raw_writel(regval32, clk->enable_reg); | ||
546 | } else { | ||
547 | regval32 = omap_readl(clk->enable_reg); | ||
548 | regval32 &= ~(1 << clk->enable_bit); | ||
549 | omap_writel(regval32, clk->enable_reg); | ||
550 | } | ||
551 | } else { | 665 | } else { |
552 | if (clk->flags & VIRTUAL_IO_ADDRESS) { | 666 | regval16 = __raw_readw(clk->enable_reg); |
553 | regval16 = __raw_readw(clk->enable_reg); | 667 | regval16 &= ~(1 << clk->enable_bit); |
554 | regval16 &= ~(1 << clk->enable_bit); | 668 | __raw_writew(regval16, clk->enable_reg); |
555 | __raw_writew(regval16, clk->enable_reg); | ||
556 | } else { | ||
557 | regval16 = omap_readw(clk->enable_reg); | ||
558 | regval16 &= ~(1 << clk->enable_bit); | ||
559 | omap_writew(regval16, clk->enable_reg); | ||
560 | } | ||
561 | } | 669 | } |
562 | } | 670 | } |
563 | 671 | ||
672 | static const struct clkops clkops_generic = { | ||
673 | .enable = &omap1_clk_enable_generic, | ||
674 | .disable = &omap1_clk_disable_generic, | ||
675 | }; | ||
676 | |||
564 | static long omap1_clk_round_rate(struct clk *clk, unsigned long rate) | 677 | static long omap1_clk_round_rate(struct clk *clk, unsigned long rate) |
565 | { | 678 | { |
566 | int dsor_exp; | ||
567 | |||
568 | if (clk->flags & RATE_FIXED) | 679 | if (clk->flags & RATE_FIXED) |
569 | return clk->rate; | 680 | return clk->rate; |
570 | 681 | ||
571 | if (clk->flags & RATE_CKCTL) { | ||
572 | dsor_exp = calc_dsor_exp(clk, rate); | ||
573 | if (dsor_exp < 0) | ||
574 | return dsor_exp; | ||
575 | if (dsor_exp > 3) | ||
576 | dsor_exp = 3; | ||
577 | return clk->parent->rate / (1 << dsor_exp); | ||
578 | } | ||
579 | |||
580 | if (clk->round_rate != NULL) | 682 | if (clk->round_rate != NULL) |
581 | return clk->round_rate(clk, rate); | 683 | return clk->round_rate(clk, rate); |
582 | 684 | ||
@@ -586,30 +688,9 @@ static long omap1_clk_round_rate(struct clk *clk, unsigned long rate) | |||
586 | static int omap1_clk_set_rate(struct clk *clk, unsigned long rate) | 688 | static int omap1_clk_set_rate(struct clk *clk, unsigned long rate) |
587 | { | 689 | { |
588 | int ret = -EINVAL; | 690 | int ret = -EINVAL; |
589 | int dsor_exp; | ||
590 | __u16 regval; | ||
591 | 691 | ||
592 | if (clk->set_rate) | 692 | if (clk->set_rate) |
593 | ret = clk->set_rate(clk, rate); | 693 | ret = clk->set_rate(clk, rate); |
594 | else if (clk->flags & RATE_CKCTL) { | ||
595 | dsor_exp = calc_dsor_exp(clk, rate); | ||
596 | if (dsor_exp > 3) | ||
597 | dsor_exp = -EINVAL; | ||
598 | if (dsor_exp < 0) | ||
599 | return dsor_exp; | ||
600 | |||
601 | regval = omap_readw(ARM_CKCTL); | ||
602 | regval &= ~(3 << clk->rate_offset); | ||
603 | regval |= dsor_exp << clk->rate_offset; | ||
604 | regval = verify_ckctl_value(regval); | ||
605 | omap_writew(regval, ARM_CKCTL); | ||
606 | clk->rate = clk->parent->rate / (1 << dsor_exp); | ||
607 | ret = 0; | ||
608 | } | ||
609 | |||
610 | if (unlikely(ret == 0 && (clk->flags & RATE_PROPAGATES))) | ||
611 | propagate_rate(clk); | ||
612 | |||
613 | return ret; | 694 | return ret; |
614 | } | 695 | } |
615 | 696 | ||
@@ -632,17 +713,10 @@ static void __init omap1_clk_disable_unused(struct clk *clk) | |||
632 | } | 713 | } |
633 | 714 | ||
634 | /* Is the clock already disabled? */ | 715 | /* Is the clock already disabled? */ |
635 | if (clk->flags & ENABLE_REG_32BIT) { | 716 | if (clk->flags & ENABLE_REG_32BIT) |
636 | if (clk->flags & VIRTUAL_IO_ADDRESS) | 717 | regval32 = __raw_readl(clk->enable_reg); |
637 | regval32 = __raw_readl(clk->enable_reg); | 718 | else |
638 | else | 719 | regval32 = __raw_readw(clk->enable_reg); |
639 | regval32 = omap_readl(clk->enable_reg); | ||
640 | } else { | ||
641 | if (clk->flags & VIRTUAL_IO_ADDRESS) | ||
642 | regval32 = __raw_readw(clk->enable_reg); | ||
643 | else | ||
644 | regval32 = omap_readw(clk->enable_reg); | ||
645 | } | ||
646 | 720 | ||
647 | if ((regval32 & (1 << clk->enable_bit)) == 0) | 721 | if ((regval32 & (1 << clk->enable_bit)) == 0) |
648 | return; | 722 | return; |
@@ -659,7 +733,7 @@ static void __init omap1_clk_disable_unused(struct clk *clk) | |||
659 | } | 733 | } |
660 | 734 | ||
661 | printk(KERN_INFO "Disabling unused clock \"%s\"... ", clk->name); | 735 | printk(KERN_INFO "Disabling unused clock \"%s\"... ", clk->name); |
662 | clk->disable(clk); | 736 | clk->ops->disable(clk); |
663 | printk(" done\n"); | 737 | printk(" done\n"); |
664 | } | 738 | } |
665 | 739 | ||
@@ -677,10 +751,10 @@ static struct clk_functions omap1_clk_functions = { | |||
677 | 751 | ||
678 | int __init omap1_clk_init(void) | 752 | int __init omap1_clk_init(void) |
679 | { | 753 | { |
680 | struct clk ** clkp; | 754 | struct omap_clk *c; |
681 | const struct omap_clock_config *info; | 755 | const struct omap_clock_config *info; |
682 | int crystal_type = 0; /* Default 12 MHz */ | 756 | int crystal_type = 0; /* Default 12 MHz */ |
683 | u32 reg; | 757 | u32 reg, cpu_mask; |
684 | 758 | ||
685 | #ifdef CONFIG_DEBUG_LL | 759 | #ifdef CONFIG_DEBUG_LL |
686 | /* Resets some clocks that may be left on from bootloader, | 760 | /* Resets some clocks that may be left on from bootloader, |
@@ -700,27 +774,24 @@ int __init omap1_clk_init(void) | |||
700 | /* By default all idlect1 clocks are allowed to idle */ | 774 | /* By default all idlect1 clocks are allowed to idle */ |
701 | arm_idlect1_mask = ~0; | 775 | arm_idlect1_mask = ~0; |
702 | 776 | ||
703 | for (clkp = onchip_clks; clkp < onchip_clks+ARRAY_SIZE(onchip_clks); clkp++) { | 777 | for (c = omap_clks; c < omap_clks + ARRAY_SIZE(omap_clks); c++) |
704 | if (((*clkp)->flags &CLOCK_IN_OMAP1510) && cpu_is_omap1510()) { | 778 | clk_init_one(c->lk.clk); |
705 | clk_register(*clkp); | ||
706 | continue; | ||
707 | } | ||
708 | |||
709 | if (((*clkp)->flags &CLOCK_IN_OMAP16XX) && cpu_is_omap16xx()) { | ||
710 | clk_register(*clkp); | ||
711 | continue; | ||
712 | } | ||
713 | |||
714 | if (((*clkp)->flags &CLOCK_IN_OMAP730) && cpu_is_omap730()) { | ||
715 | clk_register(*clkp); | ||
716 | continue; | ||
717 | } | ||
718 | 779 | ||
719 | if (((*clkp)->flags &CLOCK_IN_OMAP310) && cpu_is_omap310()) { | 780 | cpu_mask = 0; |
720 | clk_register(*clkp); | 781 | if (cpu_is_omap16xx()) |
721 | continue; | 782 | cpu_mask |= CK_16XX; |
783 | if (cpu_is_omap1510()) | ||
784 | cpu_mask |= CK_1510; | ||
785 | if (cpu_is_omap730()) | ||
786 | cpu_mask |= CK_730; | ||
787 | if (cpu_is_omap310()) | ||
788 | cpu_mask |= CK_310; | ||
789 | |||
790 | for (c = omap_clks; c < omap_clks + ARRAY_SIZE(omap_clks); c++) | ||
791 | if (c->cpu & cpu_mask) { | ||
792 | clkdev_add(&c->lk); | ||
793 | clk_register(c->lk.clk); | ||
722 | } | 794 | } |
723 | } | ||
724 | 795 | ||
725 | info = omap_get_config(OMAP_TAG_CLOCK, struct omap_clock_config); | 796 | info = omap_get_config(OMAP_TAG_CLOCK, struct omap_clock_config); |
726 | if (info != NULL) { | 797 | if (info != NULL) { |
@@ -769,7 +840,6 @@ int __init omap1_clk_init(void) | |||
769 | } | 840 | } |
770 | } | 841 | } |
771 | } | 842 | } |
772 | propagate_rate(&ck_dpll1); | ||
773 | #else | 843 | #else |
774 | /* Find the highest supported frequency and enable it */ | 844 | /* Find the highest supported frequency and enable it */ |
775 | if (omap1_select_table_rate(&virtual_ck_mpu, ~0)) { | 845 | if (omap1_select_table_rate(&virtual_ck_mpu, ~0)) { |
@@ -778,9 +848,9 @@ int __init omap1_clk_init(void) | |||
778 | omap_writew(0x2290, DPLL_CTL); | 848 | omap_writew(0x2290, DPLL_CTL); |
779 | omap_writew(cpu_is_omap730() ? 0x3005 : 0x1005, ARM_CKCTL); | 849 | omap_writew(cpu_is_omap730() ? 0x3005 : 0x1005, ARM_CKCTL); |
780 | ck_dpll1.rate = 60000000; | 850 | ck_dpll1.rate = 60000000; |
781 | propagate_rate(&ck_dpll1); | ||
782 | } | 851 | } |
783 | #endif | 852 | #endif |
853 | propagate_rate(&ck_dpll1); | ||
784 | /* Cache rates for clocks connected to ck_ref (not dpll1) */ | 854 | /* Cache rates for clocks connected to ck_ref (not dpll1) */ |
785 | propagate_rate(&ck_ref); | 855 | propagate_rate(&ck_ref); |
786 | printk(KERN_INFO "Clocking rate (xtal/DPLL1/MPU): " | 856 | printk(KERN_INFO "Clocking rate (xtal/DPLL1/MPU): " |
@@ -832,4 +902,3 @@ int __init omap1_clk_init(void) | |||
832 | 902 | ||
833 | return 0; | 903 | return 0; |
834 | } | 904 | } |
835 | |||