aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi/spi-pxa2xx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/spi/spi-pxa2xx.c')
-rw-r--r--drivers/spi/spi-pxa2xx.c38
1 files changed, 26 insertions, 12 deletions
diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c
index b6ddba833d02..e59c8b27b155 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,
@@ -925,7 +929,7 @@ static int pxa2xx_spi_transfer_one(struct spi_controller *controller,
{
struct driver_data *drv_data = spi_controller_get_devdata(controller);
struct spi_message *message = controller->cur_msg;
- struct chip_data *chip = spi_get_ctldata(message->spi);
+ struct chip_data *chip = spi_get_ctldata(spi);
u32 dma_thresh = chip->dma_threshold;
u32 dma_burst = chip->dma_burst_size;
u32 change_mask = pxa2xx_spi_get_ssrc1_change_mask(drv_data);
@@ -943,21 +947,21 @@ static int pxa2xx_spi_transfer_one(struct spi_controller *controller,
/* reject already-mapped transfers; PIO won't always work */
if (message->is_dma_mapped
|| transfer->rx_dma || transfer->tx_dma) {
- dev_err(&drv_data->pdev->dev,
+ dev_err(&spi->dev,
"Mapped transfer length of %u is greater than %d\n",
transfer->len, MAX_DMA_LEN);
return -EINVAL;
}
/* warn ... we force this to PIO mode */
- dev_warn_ratelimited(&message->spi->dev,
+ dev_warn_ratelimited(&spi->dev,
"DMA disabled for transfer length %ld greater than %d\n",
(long)transfer->len, MAX_DMA_LEN);
}
/* Setup the transfer state based on the type of transfer */
if (pxa2xx_spi_flush(drv_data) == 0) {
- dev_err(&drv_data->pdev->dev, "Flush failed\n");
+ dev_err(&spi->dev, "Flush failed\n");
return -EIO;
}
drv_data->n_bytes = chip->n_bytes;
@@ -999,15 +1003,15 @@ static int pxa2xx_spi_transfer_one(struct spi_controller *controller,
*/
if (chip->enable_dma) {
if (pxa2xx_spi_set_dma_burst_and_threshold(chip,
- message->spi,
+ spi,
bits, &dma_burst,
&dma_thresh))
- dev_warn_ratelimited(&message->spi->dev,
+ dev_warn_ratelimited(&spi->dev,
"DMA burst size reduced to match bits_per_word\n");
}
dma_mapped = controller->can_dma &&
- controller->can_dma(controller, message->spi, transfer) &&
+ controller->can_dma(controller, spi, transfer) &&
controller->cur_msg_mapped;
if (dma_mapped) {
@@ -1035,12 +1039,12 @@ static int pxa2xx_spi_transfer_one(struct spi_controller *controller,
/* NOTE: PXA25x_SSP _could_ use external clocking ... */
cr0 = pxa2xx_configure_sscr0(drv_data, clk_div, bits);
if (!pxa25x_ssp_comp(drv_data))
- dev_dbg(&message->spi->dev, "%u Hz actual, %s\n",
+ dev_dbg(&spi->dev, "%u Hz actual, %s\n",
controller->max_speed_hz
/ (1 + ((cr0 & SSCR0_SCR(0xfff)) >> 8)),
dma_mapped ? "DMA" : "PIO");
else
- dev_dbg(&message->spi->dev, "%u Hz actual, %s\n",
+ dev_dbg(&spi->dev, "%u Hz actual, %s\n",
controller->max_speed_hz / 2
/ (1 + ((cr0 & SSCR0_SCR(0x0ff)) >> 8)),
dma_mapped ? "DMA" : "PIO");
@@ -1333,6 +1337,9 @@ static int setup(struct spi_device *spi)
dev_warn(&spi->dev,
"in setup: DMA burst size reduced to match bits_per_word\n");
}
+ dev_dbg(&spi->dev,
+ "in setup: DMA burst size set to %u\n",
+ chip->dma_burst_size);
}
switch (drv_data->ssp_type) {
@@ -1451,6 +1458,10 @@ static const struct pci_device_id pxa2xx_spi_pci_compound_match[] = {
{ PCI_VDEVICE(INTEL, 0xa32a), LPSS_CNL_SSP },
{ PCI_VDEVICE(INTEL, 0xa32b), LPSS_CNL_SSP },
{ PCI_VDEVICE(INTEL, 0xa37b), LPSS_CNL_SSP },
+ /* CML-LP */
+ { PCI_VDEVICE(INTEL, 0x02aa), LPSS_CNL_SSP },
+ { PCI_VDEVICE(INTEL, 0x02ab), LPSS_CNL_SSP },
+ { PCI_VDEVICE(INTEL, 0x02fb), LPSS_CNL_SSP },
{ },
};
@@ -1564,6 +1575,7 @@ pxa2xx_spi_init_pdata(struct platform_device *pdev)
pdata->is_slave = of_property_read_bool(pdev->dev.of_node, "spi-slave");
pdata->num_chipselect = 1;
pdata->enable_dma = true;
+ pdata->dma_burst_size = 1;
return pdata;
}
@@ -1692,7 +1704,7 @@ static int pxa2xx_spi_probe(struct platform_device *pdev)
if (platform_info->enable_dma) {
status = pxa2xx_spi_dma_setup(drv_data);
if (status) {
- dev_dbg(dev, "no DMA channels available, using PIO\n");
+ dev_warn(dev, "no DMA channels available, using PIO\n");
platform_info->enable_dma = false;
} else {
controller->can_dma = pxa2xx_spi_can_dma;
@@ -1953,3 +1965,5 @@ static void __exit pxa2xx_spi_exit(void)
platform_driver_unregister(&driver);
}
module_exit(pxa2xx_spi_exit);
+
+MODULE_SOFTDEP("pre: dw_dmac");