diff options
author | David Lechner <david@lechnology.com> | 2016-04-14 15:13:36 -0400 |
---|---|---|
committer | Sekhar Nori <nsekhar@ti.com> | 2016-04-27 06:34:41 -0400 |
commit | 3f2a09d57bb12ca55f92209b3ef0c0684cdb20b0 (patch) | |
tree | b929d1c6e9025d9200217f0aaceff297b9270321 | |
parent | 6fc9ebbdeb75197df780c52f5ebcc3eeffb9cd91 (diff) |
ARM: davinci: da850: use clk->set_parent for async3
The da850 family of processors has an async3 clock domain that can be
muxed to either pll0_sysclk2 or pll1_sysclk2. Now that the davinci clocks
have a set_parent callback, we can use this to control the async3 mux
instead of a stand-alone function.
This adds a new async3_clk and sets the appropriate child clocks. The
default is use to pll1_sysclk2 since it is not affected by processor
frequency scaling.
Signed-off-by: David Lechner <david@lechnology.com>
[nsekhar@ti.com: drop unnecessary comment]
Signed-off-by: Sekhar Nori <nsekhar@ti.com>
-rw-r--r-- | arch/arm/mach-davinci/da850.c | 81 |
1 files changed, 33 insertions, 48 deletions
diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c index 1f85bbca2e55..239886299968 100644 --- a/arch/arm/mach-davinci/da850.c +++ b/arch/arm/mach-davinci/da850.c | |||
@@ -34,9 +34,6 @@ | |||
34 | #include "clock.h" | 34 | #include "clock.h" |
35 | #include "mux.h" | 35 | #include "mux.h" |
36 | 36 | ||
37 | /* SoC specific clock flags */ | ||
38 | #define DA850_CLK_ASYNC3 BIT(16) | ||
39 | |||
40 | #define DA850_PLL1_BASE 0x01e1a000 | 37 | #define DA850_PLL1_BASE 0x01e1a000 |
41 | #define DA850_TIMER64P2_BASE 0x01f0c000 | 38 | #define DA850_TIMER64P2_BASE 0x01f0c000 |
42 | #define DA850_TIMER64P3_BASE 0x01f0d000 | 39 | #define DA850_TIMER64P3_BASE 0x01f0d000 |
@@ -161,6 +158,32 @@ static struct clk pll1_sysclk3 = { | |||
161 | .div_reg = PLLDIV3, | 158 | .div_reg = PLLDIV3, |
162 | }; | 159 | }; |
163 | 160 | ||
161 | static int da850_async3_set_parent(struct clk *clk, struct clk *parent) | ||
162 | { | ||
163 | u32 val; | ||
164 | |||
165 | val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG)); | ||
166 | |||
167 | if (parent == &pll0_sysclk2) { | ||
168 | val &= ~CFGCHIP3_ASYNC3_CLKSRC; | ||
169 | } else if (parent == &pll1_sysclk2) { | ||
170 | val |= CFGCHIP3_ASYNC3_CLKSRC; | ||
171 | } else { | ||
172 | pr_err("Bad parent on async3 clock mux\n"); | ||
173 | return -EINVAL; | ||
174 | } | ||
175 | |||
176 | writel(val, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG)); | ||
177 | |||
178 | return 0; | ||
179 | } | ||
180 | |||
181 | static struct clk async3_clk = { | ||
182 | .name = "async3", | ||
183 | .parent = &pll1_sysclk2, | ||
184 | .set_parent = da850_async3_set_parent, | ||
185 | }; | ||
186 | |||
164 | static struct clk i2c0_clk = { | 187 | static struct clk i2c0_clk = { |
165 | .name = "i2c0", | 188 | .name = "i2c0", |
166 | .parent = &pll0_aux_clk, | 189 | .parent = &pll0_aux_clk, |
@@ -234,18 +257,16 @@ static struct clk uart0_clk = { | |||
234 | 257 | ||
235 | static struct clk uart1_clk = { | 258 | static struct clk uart1_clk = { |
236 | .name = "uart1", | 259 | .name = "uart1", |
237 | .parent = &pll0_sysclk2, | 260 | .parent = &async3_clk, |
238 | .lpsc = DA8XX_LPSC1_UART1, | 261 | .lpsc = DA8XX_LPSC1_UART1, |
239 | .gpsc = 1, | 262 | .gpsc = 1, |
240 | .flags = DA850_CLK_ASYNC3, | ||
241 | }; | 263 | }; |
242 | 264 | ||
243 | static struct clk uart2_clk = { | 265 | static struct clk uart2_clk = { |
244 | .name = "uart2", | 266 | .name = "uart2", |
245 | .parent = &pll0_sysclk2, | 267 | .parent = &async3_clk, |
246 | .lpsc = DA8XX_LPSC1_UART2, | 268 | .lpsc = DA8XX_LPSC1_UART2, |
247 | .gpsc = 1, | 269 | .gpsc = 1, |
248 | .flags = DA850_CLK_ASYNC3, | ||
249 | }; | 270 | }; |
250 | 271 | ||
251 | static struct clk aintc_clk = { | 272 | static struct clk aintc_clk = { |
@@ -300,10 +321,9 @@ static struct clk emac_clk = { | |||
300 | 321 | ||
301 | static struct clk mcasp_clk = { | 322 | static struct clk mcasp_clk = { |
302 | .name = "mcasp", | 323 | .name = "mcasp", |
303 | .parent = &pll0_sysclk2, | 324 | .parent = &async3_clk, |
304 | .lpsc = DA8XX_LPSC1_McASP0, | 325 | .lpsc = DA8XX_LPSC1_McASP0, |
305 | .gpsc = 1, | 326 | .gpsc = 1, |
306 | .flags = DA850_CLK_ASYNC3, | ||
307 | }; | 327 | }; |
308 | 328 | ||
309 | static struct clk lcdc_clk = { | 329 | static struct clk lcdc_clk = { |
@@ -355,10 +375,9 @@ static struct clk spi0_clk = { | |||
355 | 375 | ||
356 | static struct clk spi1_clk = { | 376 | static struct clk spi1_clk = { |
357 | .name = "spi1", | 377 | .name = "spi1", |
358 | .parent = &pll0_sysclk2, | 378 | .parent = &async3_clk, |
359 | .lpsc = DA8XX_LPSC1_SPI1, | 379 | .lpsc = DA8XX_LPSC1_SPI1, |
360 | .gpsc = 1, | 380 | .gpsc = 1, |
361 | .flags = DA850_CLK_ASYNC3, | ||
362 | }; | 381 | }; |
363 | 382 | ||
364 | static struct clk vpif_clk = { | 383 | static struct clk vpif_clk = { |
@@ -386,10 +405,9 @@ static struct clk dsp_clk = { | |||
386 | 405 | ||
387 | static struct clk ehrpwm_clk = { | 406 | static struct clk ehrpwm_clk = { |
388 | .name = "ehrpwm", | 407 | .name = "ehrpwm", |
389 | .parent = &pll0_sysclk2, | 408 | .parent = &async3_clk, |
390 | .lpsc = DA8XX_LPSC1_PWM, | 409 | .lpsc = DA8XX_LPSC1_PWM, |
391 | .gpsc = 1, | 410 | .gpsc = 1, |
392 | .flags = DA850_CLK_ASYNC3, | ||
393 | }; | 411 | }; |
394 | 412 | ||
395 | #define DA8XX_EHRPWM_TBCLKSYNC BIT(12) | 413 | #define DA8XX_EHRPWM_TBCLKSYNC BIT(12) |
@@ -421,10 +439,9 @@ static struct clk ehrpwm_tbclk = { | |||
421 | 439 | ||
422 | static struct clk ecap_clk = { | 440 | static struct clk ecap_clk = { |
423 | .name = "ecap", | 441 | .name = "ecap", |
424 | .parent = &pll0_sysclk2, | 442 | .parent = &async3_clk, |
425 | .lpsc = DA8XX_LPSC1_ECAP, | 443 | .lpsc = DA8XX_LPSC1_ECAP, |
426 | .gpsc = 1, | 444 | .gpsc = 1, |
427 | .flags = DA850_CLK_ASYNC3, | ||
428 | }; | 445 | }; |
429 | 446 | ||
430 | static struct clk_lookup da850_clks[] = { | 447 | static struct clk_lookup da850_clks[] = { |
@@ -442,6 +459,7 @@ static struct clk_lookup da850_clks[] = { | |||
442 | CLK(NULL, "pll1_aux", &pll1_aux_clk), | 459 | CLK(NULL, "pll1_aux", &pll1_aux_clk), |
443 | CLK(NULL, "pll1_sysclk2", &pll1_sysclk2), | 460 | CLK(NULL, "pll1_sysclk2", &pll1_sysclk2), |
444 | CLK(NULL, "pll1_sysclk3", &pll1_sysclk3), | 461 | CLK(NULL, "pll1_sysclk3", &pll1_sysclk3), |
462 | CLK(NULL, "async3", &async3_clk), | ||
445 | CLK("i2c_davinci.1", NULL, &i2c0_clk), | 463 | CLK("i2c_davinci.1", NULL, &i2c0_clk), |
446 | CLK(NULL, "timer0", &timerp64_0_clk), | 464 | CLK(NULL, "timer0", &timerp64_0_clk), |
447 | CLK("davinci-wdt", NULL, &timerp64_1_clk), | 465 | CLK("davinci-wdt", NULL, &timerp64_1_clk), |
@@ -909,30 +927,6 @@ static struct davinci_timer_info da850_timer_info = { | |||
909 | .clocksource_id = T0_TOP, | 927 | .clocksource_id = T0_TOP, |
910 | }; | 928 | }; |
911 | 929 | ||
912 | static void da850_set_async3_src(int pllnum) | ||
913 | { | ||
914 | struct clk *clk, *newparent = pllnum ? &pll1_sysclk2 : &pll0_sysclk2; | ||
915 | struct clk_lookup *c; | ||
916 | unsigned int v; | ||
917 | int ret; | ||
918 | |||
919 | for (c = da850_clks; c->clk; c++) { | ||
920 | clk = c->clk; | ||
921 | if (clk->flags & DA850_CLK_ASYNC3) { | ||
922 | ret = clk_set_parent(clk, newparent); | ||
923 | WARN(ret, "DA850: unable to re-parent clock %s", | ||
924 | clk->name); | ||
925 | } | ||
926 | } | ||
927 | |||
928 | v = __raw_readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG)); | ||
929 | if (pllnum) | ||
930 | v |= CFGCHIP3_ASYNC3_CLKSRC; | ||
931 | else | ||
932 | v &= ~CFGCHIP3_ASYNC3_CLKSRC; | ||
933 | __raw_writel(v, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG)); | ||
934 | } | ||
935 | |||
936 | #ifdef CONFIG_CPU_FREQ | 930 | #ifdef CONFIG_CPU_FREQ |
937 | /* | 931 | /* |
938 | * Notes: | 932 | * Notes: |
@@ -1328,15 +1322,6 @@ void __init da850_init(void) | |||
1328 | if (WARN(!da8xx_syscfg1_base, "Unable to map syscfg1 module")) | 1322 | if (WARN(!da8xx_syscfg1_base, "Unable to map syscfg1 module")) |
1329 | return; | 1323 | return; |
1330 | 1324 | ||
1331 | /* | ||
1332 | * Move the clock source of Async3 domain to PLL1 SYSCLK2. | ||
1333 | * This helps keeping the peripherals on this domain insulated | ||
1334 | * from CPU frequency changes caused by DVFS. The firmware sets | ||
1335 | * both PLL0 and PLL1 to the same frequency so, there should not | ||
1336 | * be any noticeable change even in non-DVFS use cases. | ||
1337 | */ | ||
1338 | da850_set_async3_src(1); | ||
1339 | |||
1340 | /* Unlock writing to PLL0 registers */ | 1325 | /* Unlock writing to PLL0 registers */ |
1341 | v = __raw_readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP0_REG)); | 1326 | v = __raw_readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP0_REG)); |
1342 | v &= ~CFGCHIP0_PLL_MASTER_LOCK; | 1327 | v &= ~CFGCHIP0_PLL_MASTER_LOCK; |