Commit c8e15fb9 authored by Tony Lindgren's avatar Tony Lindgren

ARM: OMAP: Fix dsp clocks in clock framework

OMAP DSP control registers DSP_CKCTL, DSP_IDLECT1, etc
are not in the IO area, so omap_readw() and omap_writew()
cannot be used with these registers.

Instead __raw_readw() and __raw_writew() must be used.
The DSP virt addr = phys addr.

This fixes audio problems in the recent kernels as pointed
out by Nishant Menon.
parent 613beee4
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/err.h> #include <linux/err.h>
#include <asm/io.h>
#include <asm/semaphore.h> #include <asm/semaphore.h>
#include <asm/hardware/clock.h> #include <asm/hardware/clock.h>
#include <asm/arch/board.h> #include <asm/arch/board.h>
...@@ -220,7 +221,7 @@ static struct clk dspper_ck = { ...@@ -220,7 +221,7 @@ static struct clk dspper_ck = {
.name = "dspper_ck", .name = "dspper_ck",
.parent = &ck_dpll1, .parent = &ck_dpll1,
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
RATE_CKCTL | DSP_DOMAIN_CLOCK, RATE_CKCTL | DSP_DOMAIN_CLOCK | VIRTUAL_IO_ADDRESS,
.enable_reg = DSP_IDLECT2, .enable_reg = DSP_IDLECT2,
.enable_bit = EN_PERCK, .enable_bit = EN_PERCK,
.rate_offset = CKCTL_PERDIV_OFFSET, .rate_offset = CKCTL_PERDIV_OFFSET,
...@@ -232,7 +233,7 @@ static struct clk dspxor_ck = { ...@@ -232,7 +233,7 @@ static struct clk dspxor_ck = {
.name = "dspxor_ck", .name = "dspxor_ck",
.parent = &ck_ref, .parent = &ck_ref,
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
DSP_DOMAIN_CLOCK, DSP_DOMAIN_CLOCK | VIRTUAL_IO_ADDRESS,
.enable_reg = DSP_IDLECT2, .enable_reg = DSP_IDLECT2,
.enable_bit = EN_XORPCK, .enable_bit = EN_XORPCK,
.recalc = &followparent_recalc, .recalc = &followparent_recalc,
...@@ -242,7 +243,7 @@ static struct clk dsptim_ck = { ...@@ -242,7 +243,7 @@ static struct clk dsptim_ck = {
.name = "dsptim_ck", .name = "dsptim_ck",
.parent = &ck_ref, .parent = &ck_ref,
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
DSP_DOMAIN_CLOCK, DSP_DOMAIN_CLOCK | VIRTUAL_IO_ADDRESS,
.enable_reg = DSP_IDLECT2, .enable_reg = DSP_IDLECT2,
.enable_bit = EN_DSPTIMCK, .enable_bit = EN_DSPTIMCK,
.recalc = &followparent_recalc, .recalc = &followparent_recalc,
...@@ -605,13 +606,25 @@ int __clk_enable(struct clk *clk) ...@@ -605,13 +606,25 @@ int __clk_enable(struct clk *clk)
} }
if (clk->flags & ENABLE_REG_32BIT) { if (clk->flags & ENABLE_REG_32BIT) {
regval32 = omap_readl(clk->enable_reg); if (clk->flags & VIRTUAL_IO_ADDRESS) {
regval32 |= (1 << clk->enable_bit); regval32 = __raw_readl(clk->enable_reg);
omap_writel(regval32, clk->enable_reg); regval32 |= (1 << clk->enable_bit);
__raw_writel(regval32, clk->enable_reg);
} else {
regval32 = omap_readl(clk->enable_reg);
regval32 |= (1 << clk->enable_bit);
omap_writel(regval32, clk->enable_reg);
}
} else { } else {
regval16 = omap_readw(clk->enable_reg); if (clk->flags & VIRTUAL_IO_ADDRESS) {
regval16 |= (1 << clk->enable_bit); regval16 = __raw_readw(clk->enable_reg);
omap_writew(regval16, clk->enable_reg); regval16 |= (1 << clk->enable_bit);
__raw_writew(regval16, clk->enable_reg);
} else {
regval16 = omap_readw(clk->enable_reg);
regval16 |= (1 << clk->enable_bit);
omap_writew(regval16, clk->enable_reg);
}
} }
if (clk->flags & DSP_DOMAIN_CLOCK) { if (clk->flags & DSP_DOMAIN_CLOCK) {
...@@ -635,13 +648,25 @@ void __clk_disable(struct clk *clk) ...@@ -635,13 +648,25 @@ void __clk_disable(struct clk *clk)
} }
if (clk->flags & ENABLE_REG_32BIT) { if (clk->flags & ENABLE_REG_32BIT) {
regval32 = omap_readl(clk->enable_reg); if (clk->flags & VIRTUAL_IO_ADDRESS) {
regval32 &= ~(1 << clk->enable_bit); regval32 = __raw_readl(clk->enable_reg);
omap_writel(regval32, clk->enable_reg); regval32 &= ~(1 << clk->enable_bit);
__raw_writel(regval32, clk->enable_reg);
} else {
regval32 = omap_readl(clk->enable_reg);
regval32 &= ~(1 << clk->enable_bit);
omap_writel(regval32, clk->enable_reg);
}
} else { } else {
regval16 = omap_readw(clk->enable_reg); if (clk->flags & VIRTUAL_IO_ADDRESS) {
regval16 &= ~(1 << clk->enable_bit); regval16 = __raw_readw(clk->enable_reg);
omap_writew(regval16, clk->enable_reg); regval16 &= ~(1 << clk->enable_bit);
__raw_writew(regval16, clk->enable_reg);
} else {
regval16 = omap_readw(clk->enable_reg);
regval16 &= ~(1 << clk->enable_bit);
omap_writew(regval16, clk->enable_reg);
}
} }
if (clk->flags & DSP_DOMAIN_CLOCK) { if (clk->flags & DSP_DOMAIN_CLOCK) {
...@@ -843,10 +868,12 @@ static void ckctl_recalc(struct clk * clk) ...@@ -843,10 +868,12 @@ static void ckctl_recalc(struct clk * clk)
/* Calculate divisor encoded as 2-bit exponent */ /* Calculate divisor encoded as 2-bit exponent */
if (clk->flags & DSP_DOMAIN_CLOCK) { if (clk->flags & DSP_DOMAIN_CLOCK) {
/* The clock control bits are in DSP domain, /* The clock control bits are in DSP domain,
* so api_ck is needed for access * so api_ck is needed for access.
* Note that DSP_CKCTL virt addr = phys addr, so
* we must use __raw_readw() instead of omap_readw().
*/ */
__clk_use(&api_ck); __clk_use(&api_ck);
dsor = 1 << (3 & (omap_readw(DSP_CKCTL) >> clk->rate_offset)); dsor = 1 << (3 & (__raw_readw(DSP_CKCTL) >> clk->rate_offset));
__clk_unuse(&api_ck); __clk_unuse(&api_ck);
} else { } else {
dsor = 1 << (3 & (omap_readw(ARM_CKCTL) >> clk->rate_offset)); dsor = 1 << (3 & (omap_readw(ARM_CKCTL) >> clk->rate_offset));
...@@ -1248,10 +1275,17 @@ static int __init omap_clk_reset(void) ...@@ -1248,10 +1275,17 @@ static int __init omap_clk_reset(void)
continue; continue;
/* Is the clock already disabled? */ /* Is the clock already disabled? */
if (p->flags & ENABLE_REG_32BIT) if (p->flags & ENABLE_REG_32BIT) {
regval32 = omap_readl(p->enable_reg); if (p->flags & VIRTUAL_IO_ADDRESS)
else regval32 = __raw_readl(p->enable_reg);
regval32 = omap_readw(p->enable_reg); else
regval32 = omap_readl(p->enable_reg);
} else {
if (p->flags & VIRTUAL_IO_ADDRESS)
regval32 = __raw_readw(p->enable_reg);
else
regval32 = omap_readw(p->enable_reg);
}
if ((regval32 & (1 << p->enable_bit)) == 0) if ((regval32 & (1 << p->enable_bit)) == 0)
continue; continue;
......
...@@ -53,6 +53,7 @@ struct mpu_rate { ...@@ -53,6 +53,7 @@ struct mpu_rate {
#define CLOCK_IN_OMAP1510 128 #define CLOCK_IN_OMAP1510 128
#define CLOCK_IN_OMAP730 256 #define CLOCK_IN_OMAP730 256
#define DSP_DOMAIN_CLOCK 512 #define DSP_DOMAIN_CLOCK 512
#define VIRTUAL_IO_ADDRESS 1024
/* ARM_CKCTL bit shifts */ /* ARM_CKCTL bit shifts */
#define CKCTL_PERDIV_OFFSET 0 #define CKCTL_PERDIV_OFFSET 0
......
...@@ -188,9 +188,6 @@ static int omap_mcbsp_check(unsigned int id) ...@@ -188,9 +188,6 @@ static int omap_mcbsp_check(unsigned int id)
return -1; return -1;
} }
#define EN_XORPCK 1
#define DSP_RSTCT2 0xe1008014
static void omap_mcbsp_dsp_request(void) static void omap_mcbsp_dsp_request(void)
{ {
if (cpu_is_omap1510() || cpu_is_omap16xx()) { if (cpu_is_omap1510() || cpu_is_omap16xx()) {
...@@ -200,6 +197,11 @@ static void omap_mcbsp_dsp_request(void) ...@@ -200,6 +197,11 @@ static void omap_mcbsp_dsp_request(void)
/* enable 12MHz clock to mcbsp 1 & 3 */ /* enable 12MHz clock to mcbsp 1 & 3 */
clk_use(mcbsp_dspxor_ck); clk_use(mcbsp_dspxor_ck);
/*
* DSP external peripheral reset
* FIXME: This should be moved to dsp code
*/
__raw_writew(__raw_readw(DSP_RSTCT2) | 1 | 1 << 1, __raw_writew(__raw_readw(DSP_RSTCT2) | 1 | 1 << 1,
DSP_RSTCT2); DSP_RSTCT2);
} }
......
...@@ -89,11 +89,12 @@ ...@@ -89,11 +89,12 @@
/* DPLL control registers */ /* DPLL control registers */
#define DPLL_CTL (0xfffecf00) #define DPLL_CTL (0xfffecf00)
/* DSP clock control */ /* DSP clock control. Must use __raw_readw() and __raw_writew() with these */
#define DSP_CONFIG_REG_BASE (0xe1008000) #define DSP_CONFIG_REG_BASE (0xe1008000)
#define DSP_CKCTL (DSP_CONFIG_REG_BASE + 0x0) #define DSP_CKCTL (DSP_CONFIG_REG_BASE + 0x0)
#define DSP_IDLECT1 (DSP_CONFIG_REG_BASE + 0x4) #define DSP_IDLECT1 (DSP_CONFIG_REG_BASE + 0x4)
#define DSP_IDLECT2 (DSP_CONFIG_REG_BASE + 0x8) #define DSP_IDLECT2 (DSP_CONFIG_REG_BASE + 0x8)
#define DSP_RSTCT2 (DSP_CONFIG_REG_BASE + 0x14)
/* /*
* --------------------------------------------------------------------------- * ---------------------------------------------------------------------------
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment