summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/soc/davinci/davinci-mcasp.c29
1 files changed, 25 insertions, 4 deletions
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
index 58fe112c5335..f390bb449c48 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -1003,13 +1003,31 @@ static int davinci_mcasp_calc_clk_div(struct davinci_mcasp *mcasp,
unsigned int bclk_freq, bool set)
{
int error_ppm;
- int div = mcasp->sysclk_freq / bclk_freq;
- int rem = mcasp->sysclk_freq % bclk_freq;
+ unsigned int sysclk_freq = mcasp->sysclk_freq;
+ u32 reg = mcasp_get_reg(mcasp, DAVINCI_MCASP_AHCLKXCTL_REG);
+ int div = sysclk_freq / bclk_freq;
+ int rem = sysclk_freq % bclk_freq;
+ int aux_div = 1;
+
+ if (div > (ACLKXDIV_MASK + 1)) {
+ if (reg & AHCLKXE) {
+ aux_div = div / (ACLKXDIV_MASK + 1);
+ if (div % (ACLKXDIV_MASK + 1))
+ aux_div++;
+
+ sysclk_freq /= aux_div;
+ div = sysclk_freq / bclk_freq;
+ rem = sysclk_freq % bclk_freq;
+ } else if (set) {
+ dev_warn(mcasp->dev, "Too fast reference clock (%u)\n",
+ sysclk_freq);
+ }
+ }
if (rem != 0) {
if (div == 0 ||
- ((mcasp->sysclk_freq / div) - bclk_freq) >
- (bclk_freq - (mcasp->sysclk_freq / (div+1)))) {
+ ((sysclk_freq / div) - bclk_freq) >
+ (bclk_freq - (sysclk_freq / (div+1)))) {
div++;
rem = rem - bclk_freq;
}
@@ -1023,6 +1041,9 @@ static int davinci_mcasp_calc_clk_div(struct davinci_mcasp *mcasp,
error_ppm);
__davinci_mcasp_set_clkdiv(mcasp, MCASP_CLKDIV_BCLK, div, 0);
+ if (reg & AHCLKXE)
+ __davinci_mcasp_set_clkdiv(mcasp, MCASP_CLKDIV_AUXCLK,
+ aux_div, 0);
}
return error_ppm;