aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi/spi-cadence.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/spi/spi-cadence.c')
-rw-r--r--drivers/spi/spi-cadence.c37
1 files changed, 27 insertions, 10 deletions
diff --git a/drivers/spi/spi-cadence.c b/drivers/spi/spi-cadence.c
index bb758978465d..562ff83debd9 100644
--- a/drivers/spi/spi-cadence.c
+++ b/drivers/spi/spi-cadence.c
@@ -205,18 +205,30 @@ static void cdns_spi_chipselect(struct spi_device *spi, bool is_high)
205static void cdns_spi_config_clock_mode(struct spi_device *spi) 205static void cdns_spi_config_clock_mode(struct spi_device *spi)
206{ 206{
207 struct cdns_spi *xspi = spi_master_get_devdata(spi->master); 207 struct cdns_spi *xspi = spi_master_get_devdata(spi->master);
208 u32 ctrl_reg; 208 u32 ctrl_reg, new_ctrl_reg;
209 209
210 ctrl_reg = cdns_spi_read(xspi, CDNS_SPI_CR_OFFSET); 210 new_ctrl_reg = ctrl_reg = cdns_spi_read(xspi, CDNS_SPI_CR_OFFSET);
211 211
212 /* Set the SPI clock phase and clock polarity */ 212 /* Set the SPI clock phase and clock polarity */
213 ctrl_reg &= ~(CDNS_SPI_CR_CPHA_MASK | CDNS_SPI_CR_CPOL_MASK); 213 new_ctrl_reg &= ~(CDNS_SPI_CR_CPHA_MASK | CDNS_SPI_CR_CPOL_MASK);
214 if (spi->mode & SPI_CPHA) 214 if (spi->mode & SPI_CPHA)
215 ctrl_reg |= CDNS_SPI_CR_CPHA_MASK; 215 new_ctrl_reg |= CDNS_SPI_CR_CPHA_MASK;
216 if (spi->mode & SPI_CPOL) 216 if (spi->mode & SPI_CPOL)
217 ctrl_reg |= CDNS_SPI_CR_CPOL_MASK; 217 new_ctrl_reg |= CDNS_SPI_CR_CPOL_MASK;
218 218
219 cdns_spi_write(xspi, CDNS_SPI_CR_OFFSET, ctrl_reg); 219 if (new_ctrl_reg != ctrl_reg) {
220 /*
221 * Just writing the CR register does not seem to apply the clock
222 * setting changes. This is problematic when changing the clock
223 * polarity as it will cause the SPI slave to see spurious clock
224 * transitions. To workaround the issue toggle the ER register.
225 */
226 cdns_spi_write(xspi, CDNS_SPI_ER_OFFSET,
227 CDNS_SPI_ER_DISABLE_MASK);
228 cdns_spi_write(xspi, CDNS_SPI_CR_OFFSET, new_ctrl_reg);
229 cdns_spi_write(xspi, CDNS_SPI_ER_OFFSET,
230 CDNS_SPI_ER_ENABLE_MASK);
231 }
220} 232}
221 233
222/** 234/**
@@ -370,6 +382,12 @@ static irqreturn_t cdns_spi_irq(int irq, void *dev_id)
370 382
371 return status; 383 return status;
372} 384}
385static int cdns_prepare_message(struct spi_master *master,
386 struct spi_message *msg)
387{
388 cdns_spi_config_clock_mode(msg->spi);
389 return 0;
390}
373 391
374/** 392/**
375 * cdns_transfer_one - Initiates the SPI transfer 393 * cdns_transfer_one - Initiates the SPI transfer
@@ -416,8 +434,6 @@ static int cdns_prepare_transfer_hardware(struct spi_master *master)
416{ 434{
417 struct cdns_spi *xspi = spi_master_get_devdata(master); 435 struct cdns_spi *xspi = spi_master_get_devdata(master);
418 436
419 cdns_spi_config_clock_mode(master->cur_msg->spi);
420
421 cdns_spi_write(xspi, CDNS_SPI_ER_OFFSET, 437 cdns_spi_write(xspi, CDNS_SPI_ER_OFFSET,
422 CDNS_SPI_ER_ENABLE_MASK); 438 CDNS_SPI_ER_ENABLE_MASK);
423 439
@@ -532,6 +548,7 @@ static int cdns_spi_probe(struct platform_device *pdev)
532 xspi->is_decoded_cs = 0; 548 xspi->is_decoded_cs = 0;
533 549
534 master->prepare_transfer_hardware = cdns_prepare_transfer_hardware; 550 master->prepare_transfer_hardware = cdns_prepare_transfer_hardware;
551 master->prepare_message = cdns_prepare_message;
535 master->transfer_one = cdns_transfer_one; 552 master->transfer_one = cdns_transfer_one;
536 master->unprepare_transfer_hardware = cdns_unprepare_transfer_hardware; 553 master->unprepare_transfer_hardware = cdns_unprepare_transfer_hardware;
537 master->set_cs = cdns_spi_chipselect; 554 master->set_cs = cdns_spi_chipselect;
@@ -647,7 +664,7 @@ static int __maybe_unused cdns_spi_resume(struct device *dev)
647static SIMPLE_DEV_PM_OPS(cdns_spi_dev_pm_ops, cdns_spi_suspend, 664static SIMPLE_DEV_PM_OPS(cdns_spi_dev_pm_ops, cdns_spi_suspend,
648 cdns_spi_resume); 665 cdns_spi_resume);
649 666
650static struct of_device_id cdns_spi_of_match[] = { 667static const struct of_device_id cdns_spi_of_match[] = {
651 { .compatible = "xlnx,zynq-spi-r1p6" }, 668 { .compatible = "xlnx,zynq-spi-r1p6" },
652 { .compatible = "cdns,spi-r1p6" }, 669 { .compatible = "cdns,spi-r1p6" },
653 { /* end of table */ } 670 { /* end of table */ }