aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-ep93xx/clock.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-ep93xx/clock.c')
-rw-r--r--arch/arm/mach-ep93xx/clock.c67
1 files changed, 66 insertions, 1 deletions
diff --git a/arch/arm/mach-ep93xx/clock.c b/arch/arm/mach-ep93xx/clock.c
index 7f3039761d9..8bf3cec98cf 100644
--- a/arch/arm/mach-ep93xx/clock.c
+++ b/arch/arm/mach-ep93xx/clock.c
@@ -43,7 +43,8 @@ static unsigned long get_uart_rate(struct clk *clk);
43 43
44static int set_keytchclk_rate(struct clk *clk, unsigned long rate); 44static int set_keytchclk_rate(struct clk *clk, unsigned long rate);
45static int set_div_rate(struct clk *clk, unsigned long rate); 45static int set_div_rate(struct clk *clk, unsigned long rate);
46 46static int set_i2s_sclk_rate(struct clk *clk, unsigned long rate);
47static int set_i2s_lrclk_rate(struct clk *clk, unsigned long rate);
47 48
48static struct clk clk_xtali = { 49static struct clk clk_xtali = {
49 .rate = EP93XX_EXT_CLK_RATE, 50 .rate = EP93XX_EXT_CLK_RATE,
@@ -112,6 +113,29 @@ static struct clk clk_video = {
112 .set_rate = set_div_rate, 113 .set_rate = set_div_rate,
113}; 114};
114 115
116static struct clk clk_i2s_mclk = {
117 .sw_locked = 1,
118 .enable_reg = EP93XX_SYSCON_I2SCLKDIV,
119 .enable_mask = EP93XX_SYSCON_CLKDIV_ENABLE,
120 .set_rate = set_div_rate,
121};
122
123static struct clk clk_i2s_sclk = {
124 .sw_locked = 1,
125 .parent = &clk_i2s_mclk,
126 .enable_reg = EP93XX_SYSCON_I2SCLKDIV,
127 .enable_mask = EP93XX_SYSCON_I2SCLKDIV_SENA,
128 .set_rate = set_i2s_sclk_rate,
129};
130
131static struct clk clk_i2s_lrclk = {
132 .sw_locked = 1,
133 .parent = &clk_i2s_sclk,
134 .enable_reg = EP93XX_SYSCON_I2SCLKDIV,
135 .enable_mask = EP93XX_SYSCON_I2SCLKDIV_SENA,
136 .set_rate = set_i2s_lrclk_rate,
137};
138
115/* DMA Clocks */ 139/* DMA Clocks */
116static struct clk clk_m2p0 = { 140static struct clk clk_m2p0 = {
117 .parent = &clk_h, 141 .parent = &clk_h,
@@ -191,6 +215,9 @@ static struct clk_lookup clocks[] = {
191 INIT_CK("ep93xx-keypad", NULL, &clk_keypad), 215 INIT_CK("ep93xx-keypad", NULL, &clk_keypad),
192 INIT_CK("ep93xx-fb", NULL, &clk_video), 216 INIT_CK("ep93xx-fb", NULL, &clk_video),
193 INIT_CK("ep93xx-spi.0", NULL, &clk_spi), 217 INIT_CK("ep93xx-spi.0", NULL, &clk_spi),
218 INIT_CK("ep93xx-i2s", "mclk", &clk_i2s_mclk),
219 INIT_CK("ep93xx-i2s", "sclk", &clk_i2s_sclk),
220 INIT_CK("ep93xx-i2s", "lrclk", &clk_i2s_lrclk),
194 INIT_CK(NULL, "pwm_clk", &clk_pwm), 221 INIT_CK(NULL, "pwm_clk", &clk_pwm),
195 INIT_CK(NULL, "m2p0", &clk_m2p0), 222 INIT_CK(NULL, "m2p0", &clk_m2p0),
196 INIT_CK(NULL, "m2p1", &clk_m2p1), 223 INIT_CK(NULL, "m2p1", &clk_m2p1),
@@ -401,6 +428,44 @@ static int set_div_rate(struct clk *clk, unsigned long rate)
401 return 0; 428 return 0;
402} 429}
403 430
431static int set_i2s_sclk_rate(struct clk *clk, unsigned long rate)
432{
433 unsigned val = __raw_readl(clk->enable_reg);
434
435 if (rate == clk_i2s_mclk.rate / 2)
436 ep93xx_syscon_swlocked_write(val & ~EP93XX_I2SCLKDIV_SDIV,
437 clk->enable_reg);
438 else if (rate == clk_i2s_mclk.rate / 4)
439 ep93xx_syscon_swlocked_write(val | EP93XX_I2SCLKDIV_SDIV,
440 clk->enable_reg);
441 else
442 return -EINVAL;
443
444 clk_i2s_sclk.rate = rate;
445 return 0;
446}
447
448static int set_i2s_lrclk_rate(struct clk *clk, unsigned long rate)
449{
450 unsigned val = __raw_readl(clk->enable_reg) &
451 ~EP93XX_I2SCLKDIV_LRDIV_MASK;
452
453 if (rate == clk_i2s_sclk.rate / 32)
454 ep93xx_syscon_swlocked_write(val | EP93XX_I2SCLKDIV_LRDIV32,
455 clk->enable_reg);
456 else if (rate == clk_i2s_sclk.rate / 64)
457 ep93xx_syscon_swlocked_write(val | EP93XX_I2SCLKDIV_LRDIV64,
458 clk->enable_reg);
459 else if (rate == clk_i2s_sclk.rate / 128)
460 ep93xx_syscon_swlocked_write(val | EP93XX_I2SCLKDIV_LRDIV128,
461 clk->enable_reg);
462 else
463 return -EINVAL;
464
465 clk_i2s_lrclk.rate = rate;
466 return 0;
467}
468
404int clk_set_rate(struct clk *clk, unsigned long rate) 469int clk_set_rate(struct clk *clk, unsigned long rate)
405{ 470{
406 if (clk->set_rate) 471 if (clk->set_rate)