ASoC: davinci-mcasp: Calculate AUXCLK divider when setting up master clocks

If the McASP is used as clock master and the reference clock is AUXCLK we
can have additional level of divider. The BCLK divider is limited to
maximum 32, if the desired bclk can not be reached with this, the AUXCLK
divider also needs to be used.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
Peter Ujfalusi 2016-05-09 13:42:32 +03:00 committed by Mark Brown
parent 3e9bee11d8
commit ddecd1492d
1 changed files with 25 additions and 4 deletions

View File

@ -1003,13 +1003,31 @@ static int davinci_mcasp_calc_clk_div(struct davinci_mcasp *mcasp,
unsigned int bclk_freq, bool set) unsigned int bclk_freq, bool set)
{ {
int error_ppm; int error_ppm;
int div = mcasp->sysclk_freq / bclk_freq; unsigned int sysclk_freq = mcasp->sysclk_freq;
int rem = mcasp->sysclk_freq % bclk_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 (rem != 0) {
if (div == 0 || if (div == 0 ||
((mcasp->sysclk_freq / div) - bclk_freq) > ((sysclk_freq / div) - bclk_freq) >
(bclk_freq - (mcasp->sysclk_freq / (div+1)))) { (bclk_freq - (sysclk_freq / (div+1)))) {
div++; div++;
rem = rem - bclk_freq; rem = rem - bclk_freq;
} }
@ -1023,6 +1041,9 @@ static int davinci_mcasp_calc_clk_div(struct davinci_mcasp *mcasp,
error_ppm); error_ppm);
__davinci_mcasp_set_clkdiv(mcasp, MCASP_CLKDIV_BCLK, div, 0); __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; return error_ppm;