aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi/spi-imx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/spi/spi-imx.c')
-rw-r--r--drivers/spi/spi-imx.c31
1 files changed, 27 insertions, 4 deletions
diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c
index b80f2f70fef7..47f15d97e7fa 100644
--- a/drivers/spi/spi-imx.c
+++ b/drivers/spi/spi-imx.c
@@ -206,7 +206,8 @@ static unsigned int spi_imx_clkdiv_2(unsigned int fin,
206#define MX51_ECSPI_STAT_RR (1 << 3) 206#define MX51_ECSPI_STAT_RR (1 << 3)
207 207
208/* MX51 eCSPI */ 208/* MX51 eCSPI */
209static unsigned int mx51_ecspi_clkdiv(unsigned int fin, unsigned int fspi) 209static unsigned int mx51_ecspi_clkdiv(unsigned int fin, unsigned int fspi,
210 unsigned int *fres)
210{ 211{
211 /* 212 /*
212 * there are two 4-bit dividers, the pre-divider divides by 213 * there are two 4-bit dividers, the pre-divider divides by
@@ -234,6 +235,10 @@ static unsigned int mx51_ecspi_clkdiv(unsigned int fin, unsigned int fspi)
234 235
235 pr_debug("%s: fin: %u, fspi: %u, post: %u, pre: %u\n", 236 pr_debug("%s: fin: %u, fspi: %u, post: %u, pre: %u\n",
236 __func__, fin, fspi, post, pre); 237 __func__, fin, fspi, post, pre);
238
239 /* Resulting frequency for the SCLK line. */
240 *fres = (fin / (pre + 1)) >> post;
241
237 return (pre << MX51_ECSPI_CTRL_PREDIV_OFFSET) | 242 return (pre << MX51_ECSPI_CTRL_PREDIV_OFFSET) |
238 (post << MX51_ECSPI_CTRL_POSTDIV_OFFSET); 243 (post << MX51_ECSPI_CTRL_POSTDIV_OFFSET);
239} 244}
@@ -264,6 +269,7 @@ static int __maybe_unused mx51_ecspi_config(struct spi_imx_data *spi_imx,
264 struct spi_imx_config *config) 269 struct spi_imx_config *config)
265{ 270{
266 u32 ctrl = MX51_ECSPI_CTRL_ENABLE, cfg = 0; 271 u32 ctrl = MX51_ECSPI_CTRL_ENABLE, cfg = 0;
272 u32 clk = config->speed_hz, delay;
267 273
268 /* 274 /*
269 * The hardware seems to have a race condition when changing modes. The 275 * The hardware seems to have a race condition when changing modes. The
@@ -275,7 +281,7 @@ static int __maybe_unused mx51_ecspi_config(struct spi_imx_data *spi_imx,
275 ctrl |= MX51_ECSPI_CTRL_MODE_MASK; 281 ctrl |= MX51_ECSPI_CTRL_MODE_MASK;
276 282
277 /* set clock speed */ 283 /* set clock speed */
278 ctrl |= mx51_ecspi_clkdiv(spi_imx->spi_clk, config->speed_hz); 284 ctrl |= mx51_ecspi_clkdiv(spi_imx->spi_clk, config->speed_hz, &clk);
279 285
280 /* set chip select to use */ 286 /* set chip select to use */
281 ctrl |= MX51_ECSPI_CTRL_CS(config->cs); 287 ctrl |= MX51_ECSPI_CTRL_CS(config->cs);
@@ -297,6 +303,23 @@ static int __maybe_unused mx51_ecspi_config(struct spi_imx_data *spi_imx,
297 writel(ctrl, spi_imx->base + MX51_ECSPI_CTRL); 303 writel(ctrl, spi_imx->base + MX51_ECSPI_CTRL);
298 writel(cfg, spi_imx->base + MX51_ECSPI_CONFIG); 304 writel(cfg, spi_imx->base + MX51_ECSPI_CONFIG);
299 305
306 /*
307 * Wait until the changes in the configuration register CONFIGREG
308 * propagate into the hardware. It takes exactly one tick of the
309 * SCLK clock, but we will wait two SCLK clock just to be sure. The
310 * effect of the delay it takes for the hardware to apply changes
311 * is noticable if the SCLK clock run very slow. In such a case, if
312 * the polarity of SCLK should be inverted, the GPIO ChipSelect might
313 * be asserted before the SCLK polarity changes, which would disrupt
314 * the SPI communication as the device on the other end would consider
315 * the change of SCLK polarity as a clock tick already.
316 */
317 delay = (2 * 1000000) / clk;
318 if (likely(delay < 10)) /* SCLK is faster than 100 kHz */
319 udelay(delay);
320 else /* SCLK is _very_ slow */
321 usleep_range(delay, delay + 10);
322
300 return 0; 323 return 0;
301} 324}
302 325
@@ -925,8 +948,8 @@ static int spi_imx_remove(struct platform_device *pdev)
925 spi_bitbang_stop(&spi_imx->bitbang); 948 spi_bitbang_stop(&spi_imx->bitbang);
926 949
927 writel(0, spi_imx->base + MXC_CSPICTRL); 950 writel(0, spi_imx->base + MXC_CSPICTRL);
928 clk_disable_unprepare(spi_imx->clk_ipg); 951 clk_unprepare(spi_imx->clk_ipg);
929 clk_disable_unprepare(spi_imx->clk_per); 952 clk_unprepare(spi_imx->clk_per);
930 spi_master_put(master); 953 spi_master_put(master);
931 954
932 return 0; 955 return 0;