aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Ujfalusi <peter.ujfalusi@ti.com>2016-05-09 06:42:32 -0400
committerMark Brown <broonie@kernel.org>2016-05-09 11:55:16 -0400
commitddecd1492de476488a92493510fb86c6ffe9acbd (patch)
tree2dc09ed782ab53866be2e5ddecf54bca01e9f903
parent3e9bee11d83190b852d428b3e35a942c6e2293cd (diff)
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>
-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,
1003 unsigned int bclk_freq, bool set) 1003 unsigned int bclk_freq, bool set)
1004{ 1004{
1005 int error_ppm; 1005 int error_ppm;
1006 int div = mcasp->sysclk_freq / bclk_freq; 1006 unsigned int sysclk_freq = mcasp->sysclk_freq;
1007 int rem = mcasp->sysclk_freq % bclk_freq; 1007 u32 reg = mcasp_get_reg(mcasp, DAVINCI_MCASP_AHCLKXCTL_REG);
1008 int div = sysclk_freq / bclk_freq;
1009 int rem = sysclk_freq % bclk_freq;
1010 int aux_div = 1;
1011
1012 if (div > (ACLKXDIV_MASK + 1)) {
1013 if (reg & AHCLKXE) {
1014 aux_div = div / (ACLKXDIV_MASK + 1);
1015 if (div % (ACLKXDIV_MASK + 1))
1016 aux_div++;
1017
1018 sysclk_freq /= aux_div;
1019 div = sysclk_freq / bclk_freq;
1020 rem = sysclk_freq % bclk_freq;
1021 } else if (set) {
1022 dev_warn(mcasp->dev, "Too fast reference clock (%u)\n",
1023 sysclk_freq);
1024 }
1025 }
1008 1026
1009 if (rem != 0) { 1027 if (rem != 0) {
1010 if (div == 0 || 1028 if (div == 0 ||
1011 ((mcasp->sysclk_freq / div) - bclk_freq) > 1029 ((sysclk_freq / div) - bclk_freq) >
1012 (bclk_freq - (mcasp->sysclk_freq / (div+1)))) { 1030 (bclk_freq - (sysclk_freq / (div+1)))) {
1013 div++; 1031 div++;
1014 rem = rem - bclk_freq; 1032 rem = rem - bclk_freq;
1015 } 1033 }
@@ -1023,6 +1041,9 @@ static int davinci_mcasp_calc_clk_div(struct davinci_mcasp *mcasp,
1023 error_ppm); 1041 error_ppm);
1024 1042
1025 __davinci_mcasp_set_clkdiv(mcasp, MCASP_CLKDIV_BCLK, div, 0); 1043 __davinci_mcasp_set_clkdiv(mcasp, MCASP_CLKDIV_BCLK, div, 0);
1044 if (reg & AHCLKXE)
1045 __davinci_mcasp_set_clkdiv(mcasp, MCASP_CLKDIV_AUXCLK,
1046 aux_div, 0);
1026 } 1047 }
1027 1048
1028 return error_ppm; 1049 return error_ppm;