aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi
diff options
context:
space:
mode:
authorAaron Brice <aaron.brice@datasoft.com>2015-03-30 13:49:15 -0400
committerMark Brown <broonie@kernel.org>2015-03-31 07:13:03 -0400
commit6fd63087d87329a2a84f28d0adec875fd9efb782 (patch)
treec2d173be6b46d751f669d6f5c1f6534dbf35983c /drivers/spi
parentc517d838eb7d07bbe9507871fab3931deccff539 (diff)
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: Aaron Brice <aaron.brice@datasoft.com> Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'drivers/spi')
-rw-r--r--drivers/spi/spi-fsl-dspi.c35
1 files changed, 21 insertions, 14 deletions
diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
index d1a39249704a..96cac87c9f85 100644
--- a/drivers/spi/spi-fsl-dspi.c
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -148,23 +148,30 @@ static void hz_to_spi_baud(char *pbr, char *br, int speed_hz,
148 16, 32, 64, 128, 148 16, 32, 64, 128,
149 256, 512, 1024, 2048, 149 256, 512, 1024, 2048,
150 4096, 8192, 16384, 32768 }; 150 4096, 8192, 16384, 32768 };
151 int temp, i = 0, j = 0; 151 int scale_needed, scale, minscale = INT_MAX;
152 152 int i, j;
153 temp = clkrate / 2 / speed_hz; 153
154 154 scale_needed = clkrate / speed_hz;
155 for (i = 0; i < ARRAY_SIZE(pbr_tbl); i++) 155
156 for (j = 0; j < ARRAY_SIZE(brs); j++) { 156 for (i = 0; i < ARRAY_SIZE(brs); i++)
157 if (pbr_tbl[i] * brs[j] >= temp) { 157 for (j = 0; j < ARRAY_SIZE(pbr_tbl); j++) {
158 *pbr = i; 158 scale = brs[i] * pbr_tbl[j];
159 *br = j; 159 if (scale >= scale_needed) {
160 return; 160 if (scale < minscale) {
161 minscale = scale;
162 *br = i;
163 *pbr = j;
164 }
165 break;
161 } 166 }
162 } 167 }
163 168
164 pr_warn("Can not find valid baud rate,speed_hz is %d,clkrate is %ld\ 169 if (minscale == INT_MAX) {
165 ,we use the max prescaler value.\n", speed_hz, clkrate); 170 pr_warn("Can not find valid baud rate,speed_hz is %d,clkrate is %ld, we use the max prescaler value.\n",
166 *pbr = ARRAY_SIZE(pbr_tbl) - 1; 171 speed_hz, clkrate);
167 *br = ARRAY_SIZE(brs) - 1; 172 *pbr = ARRAY_SIZE(pbr_tbl) - 1;
173 *br = ARRAY_SIZE(brs) - 1;
174 }
168} 175}
169 176
170static int dspi_transfer_write(struct fsl_dspi *dspi) 177static int dspi_transfer_write(struct fsl_dspi *dspi)