| From c5ba4bd8277a9c70c2b6ec6034b5541b21c4354a Mon Sep 17 00:00:00 2001 |
| From: Flavio Suligoi <f.suligoi@asem.it> |
| Date: Fri, 12 Apr 2019 09:32:19 +0200 |
| Subject: spi: pxa2xx: fix SCR (divisor) calculation |
| |
| [ Upstream commit 29f2133717c527f492933b0622a4aafe0b3cbe9e ] |
| |
| Calculate the divisor for the SCR (Serial Clock Rate), avoiding |
| that the SSP transmission rate can be greater than the device rate. |
| |
| When the division between the SSP clock and the device rate generates |
| a reminder, we have to increment by one the divisor. |
| In this way the resulting SSP clock will never be greater than the |
| device SPI max frequency. |
| |
| For example, with: |
| |
| - ssp_clk = 50 MHz |
| - dev freq = 15 MHz |
| |
| without this patch the SSP clock will be greater than 15 MHz: |
| |
| - 25 MHz for PXA25x_SSP and CE4100_SSP |
| - 16,56 MHz for the others |
| |
| Instead, with this patch, we have in both case an SSP clock of 12.5MHz, |
| so the max rate of the SPI device clock is respected. |
| |
| Signed-off-by: Flavio Suligoi <f.suligoi@asem.it> |
| Reviewed-by: Jarkko Nikula <jarkko.nikula@linux.intel.com> |
| Reviewed-by: Jarkko Nikula <jarkko.nikula@linux.intel.com> |
| Signed-off-by: Mark Brown <broonie@kernel.org> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/spi/spi-pxa2xx.c | 8 ++++++-- |
| 1 file changed, 6 insertions(+), 2 deletions(-) |
| |
| diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c |
| index b6ddba833d021..d2076f2f468f0 100644 |
| --- a/drivers/spi/spi-pxa2xx.c |
| +++ b/drivers/spi/spi-pxa2xx.c |
| @@ -884,10 +884,14 @@ static unsigned int ssp_get_clk_div(struct driver_data *drv_data, int rate) |
| |
| rate = min_t(int, ssp_clk, rate); |
| |
| + /* |
| + * Calculate the divisor for the SCR (Serial Clock Rate), avoiding |
| + * that the SSP transmission rate can be greater than the device rate |
| + */ |
| if (ssp->type == PXA25x_SSP || ssp->type == CE4100_SSP) |
| - return (ssp_clk / (2 * rate) - 1) & 0xff; |
| + return (DIV_ROUND_UP(ssp_clk, 2 * rate) - 1) & 0xff; |
| else |
| - return (ssp_clk / rate - 1) & 0xfff; |
| + return (DIV_ROUND_UP(ssp_clk, rate) - 1) & 0xfff; |
| } |
| |
| static unsigned int pxa2xx_ssp_get_clk_div(struct driver_data *drv_data, |
| -- |
| 2.20.1 |
| |