Commit e689d6df authored by Aaron Brice's avatar Aaron Brice Committed by Mark Brown

spi: fsl-dspi: Fix clock rate scale values

Previous algorithm had an outer loop with the values {2,3,5,7} and an
inner loop with {2,4,6,8,16,32,...,32768}, and would pick the first
value over the required scaling value (where the total scale was the two
numbers multiplied).

Since the inner loop went up to 32768 it would always pick a value of 2
for PBR and a much higher than necessary value for BR.  The desired
scale factor was being divided by two I believe to compensate for the
much higher scale factors (the divide by two not specified in the
reference manual).

Updated to check all values and find the smallest scale factor possible
without going over the desired clock rate.
Signed-off-by: default avatarAaron Brice <aaron.brice@datasoft.com>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent c517d838
...@@ -148,23 +148,32 @@ static void hz_to_spi_baud(char *pbr, char *br, int speed_hz, ...@@ -148,23 +148,32 @@ static void hz_to_spi_baud(char *pbr, char *br, int speed_hz,
16, 32, 64, 128, 16, 32, 64, 128,
256, 512, 1024, 2048, 256, 512, 1024, 2048,
4096, 8192, 16384, 32768 }; 4096, 8192, 16384, 32768 };
int temp, i = 0, j = 0; int scale_needed, scale, minscale = INT_MAX;
int i, j;
temp = clkrate / 2 / speed_hz;
scale_needed = clkrate / speed_hz;
for (i = 0; i < ARRAY_SIZE(pbr_tbl); i++) if (clkrate % speed_hz)
for (j = 0; j < ARRAY_SIZE(brs); j++) { scale_needed++;
if (pbr_tbl[i] * brs[j] >= temp) {
*pbr = i; for (i = 0; i < ARRAY_SIZE(brs); i++)
*br = j; for (j = 0; j < ARRAY_SIZE(pbr_tbl); j++) {
return; scale = brs[i] * pbr_tbl[j];
if (scale >= scale_needed) {
if (scale < minscale) {
minscale = scale;
*br = i;
*pbr = j;
}
break;
} }
} }
pr_warn("Can not find valid baud rate,speed_hz is %d,clkrate is %ld\ if (minscale == INT_MAX) {
,we use the max prescaler value.\n", speed_hz, clkrate); pr_warn("Can not find valid baud rate,speed_hz is %d,clkrate is %ld, we use the max prescaler value.\n",
*pbr = ARRAY_SIZE(pbr_tbl) - 1; speed_hz, clkrate);
*br = ARRAY_SIZE(brs) - 1; *pbr = ARRAY_SIZE(pbr_tbl) - 1;
*br = ARRAY_SIZE(brs) - 1;
}
} }
static int dspi_transfer_write(struct fsl_dspi *dspi) static int dspi_transfer_write(struct fsl_dspi *dspi)
......
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