u32 sccr1_reg;
sccr1_reg = pxa2xx_spi_read(drv_data, SSCR1) & ~drv_data->int_cr1;
----- sccr1_reg &= ~SSCR1_RFT;
+++++ switch (drv_data->ssp_type) {
+++++ case QUARK_X1000_SSP:
+++++ sccr1_reg &= ~QUARK_X1000_SSCR1_RFT;
+++++ break;
+++++ default:
+++++ sccr1_reg &= ~SSCR1_RFT;
+++++ break;
+++++ }
sccr1_reg |= chip->threshold;
pxa2xx_spi_write(drv_data, SSCR1, sccr1_reg);
}
return clk_div << 8;
}
+ ++++static bool pxa2xx_spi_can_dma(struct spi_master *master,
+ ++++ struct spi_device *spi,
+ ++++ struct spi_transfer *xfer)
+ ++++{
+ ++++ struct chip_data *chip = spi_get_ctldata(spi);
+ ++++
+ ++++ return chip->enable_dma &&
+ ++++ xfer->len <= MAX_DMA_LEN &&
+ ++++ xfer->len >= chip->dma_burst_size;
+ ++++}
+ ++++
static void pump_transfers(unsigned long data)
{
struct driver_data *drv_data = (struct driver_data *)data;
+ ++++ struct spi_master *master = drv_data->master;
struct spi_message *message = NULL;
struct spi_transfer *transfer = NULL;
struct spi_transfer *previous = NULL;
u32 dma_burst = drv_data->cur_chip->dma_burst_size;
u32 change_mask = pxa2xx_spi_get_ssrc1_change_mask(drv_data);
int err;
+ ++++ int dma_mapped;
/* Get current state information */
message = drv_data->cur_msg;
}
/* Check if we can DMA this transfer */
- ---- if (!pxa2xx_spi_dma_is_possible(transfer->len) && chip->enable_dma) {
+ ++++ if (transfer->len > MAX_DMA_LEN && chip->enable_dma) {
/* reject already-mapped transfers; PIO won't always work */
if (message->is_dma_mapped
message->state = RUNNING_STATE;
- ---- drv_data->dma_mapped = 0;
- ---- if (pxa2xx_spi_dma_is_possible(drv_data->len))
- ---- drv_data->dma_mapped = pxa2xx_spi_map_dma_buffers(drv_data);
- ---- if (drv_data->dma_mapped) {
+ ++++ dma_mapped = master->can_dma &&
+ ++++ master->can_dma(master, message->spi, transfer) &&
+ ++++ master->cur_msg_mapped;
+ ++++ if (dma_mapped) {
/* Ensure we have the correct interrupt handler */
drv_data->transfer_handler = pxa2xx_spi_dma_transfer;
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",
- ---- drv_data->master->max_speed_hz
+ ++++ master->max_speed_hz
/ (1 + ((cr0 & SSCR0_SCR(0xfff)) >> 8)),
- ---- drv_data->dma_mapped ? "DMA" : "PIO");
+ ++++ dma_mapped ? "DMA" : "PIO");
else
dev_dbg(&message->spi->dev, "%u Hz actual, %s\n",
- ---- drv_data->master->max_speed_hz / 2
+ ++++ master->max_speed_hz / 2
/ (1 + ((cr0 & SSCR0_SCR(0x0ff)) >> 8)),
- ---- drv_data->dma_mapped ? "DMA" : "PIO");
+ ++++ dma_mapped ? "DMA" : "PIO");
if (is_lpss_ssp(drv_data)) {
if ((pxa2xx_spi_read(drv_data, SSIRF) & 0xff)
chip->frm = spi->chip_select;
} else
chip->gpio_cs = -1;
- ---- chip->enable_dma = 0;
+ ++++ chip->enable_dma = drv_data->master_info->enable_dma;
chip->timeout = TIMOUT_DFLT;
}
tx_hi_thres = chip_info->tx_hi_threshold;
if (chip_info->rx_threshold)
rx_thres = chip_info->rx_threshold;
- ---- chip->enable_dma = drv_data->master_info->enable_dma;
chip->dma_threshold = 0;
if (chip_info->enable_loopback)
chip->cr1 = SSCR1_LBM;
- ---- } else if (ACPI_HANDLE(&spi->dev)) {
- ---- /*
- ---- * Slave devices enumerated from ACPI namespace don't
- ---- * usually have chip_info but we still might want to use
- ---- * DMA with them.
- ---- */
- ---- chip->enable_dma = drv_data->master_info->enable_dma;
}
chip->lpss_rx_threshold = SSIRF_RxThresh(rx_thres);
/* SPT-H */
{ PCI_VDEVICE(INTEL, 0xa129), LPSS_SPT_SSP },
{ PCI_VDEVICE(INTEL, 0xa12a), LPSS_SPT_SSP },
+ ++++ /* KBL-H */
+ ++++ { PCI_VDEVICE(INTEL, 0xa2a9), LPSS_SPT_SSP },
+ ++++ { PCI_VDEVICE(INTEL, 0xa2aa), LPSS_SPT_SSP },
/* BXT A-Step */
{ PCI_VDEVICE(INTEL, 0x0ac2), LPSS_BXT_SSP },
{ PCI_VDEVICE(INTEL, 0x0ac4), LPSS_BXT_SSP },
if (status) {
dev_dbg(dev, "no DMA channels available, using PIO\n");
platform_info->enable_dma = false;
+ ++++ } else {
+ ++++ master->can_dma = pxa2xx_spi_can_dma;
}
}
/* sclk_out: spi master internal logic in rk3x can support 50Mhz */
#define MAX_SCLK_OUT 50000000
+++++/*
+++++ * SPI_CTRLR1 is 16-bits, so we should support lengths of 0xffff + 1. However,
+++++ * the controller seems to hang when given 0x10000, so stick with this for now.
+++++ */
+++++#define ROCKCHIP_SPI_MAX_TRANLEN 0xffff
+++++
enum rockchip_ssi_type {
SSI_MOTO_SPI = 0,
SSI_TI_SSP,
dev_dbg(rs->dev, "cr0 0x%x, div %d\n", cr0, div);
}
+++++static size_t rockchip_spi_max_transfer_size(struct spi_device *spi)
+++++{
+++++ return ROCKCHIP_SPI_MAX_TRANLEN;
+++++}
+++++
static int rockchip_spi_transfer_one(
struct spi_master *master,
struct spi_device *spi,
struct spi_transfer *xfer)
{
----- int ret = 1;
+++++ int ret = 0;
struct rockchip_spi *rs = spi_master_get_devdata(master);
WARN_ON(readl_relaxed(rs->regs + ROCKCHIP_SPI_SSIENR) &&
return -EINVAL;
}
+++++ if (xfer->len > ROCKCHIP_SPI_MAX_TRANLEN) {
+++++ dev_err(rs->dev, "Transfer is too long (%d)\n", xfer->len);
+++++ return -EINVAL;
+++++ }
+++++
rs->speed = xfer->speed_hz;
rs->bpw = xfer->bits_per_word;
rs->n_bytes = rs->bpw >> 3;
spi_enable_chip(rs, 1);
ret = rockchip_spi_prepare_dma(rs);
}
+++++ /* successful DMA prepare means the transfer is in progress */
+++++ ret = ret ? ret : 1;
} else {
spi_enable_chip(rs, 1);
ret = rockchip_spi_pio_transfer(rs);
master->prepare_message = rockchip_spi_prepare_message;
master->unprepare_message = rockchip_spi_unprepare_message;
master->transfer_one = rockchip_spi_transfer_one;
+++++ master->max_transfer_size = rockchip_spi_max_transfer_size;
master->handle_err = rockchip_spi_handle_err;
rs->dma_tx.ch = dma_request_chan(rs->dev, "tx");
};
static const struct of_device_id rockchip_spi_dt_match[] = {
++ +++ { .compatible = "rockchip,rk3036-spi", },
{ .compatible = "rockchip,rk3066-spi", },
{ .compatible = "rockchip,rk3188-spi", },
++ +++ { .compatible = "rockchip,rk3228-spi", },
{ .compatible = "rockchip,rk3288-spi", },
++ +++ { .compatible = "rockchip,rk3368-spi", },
{ .compatible = "rockchip,rk3399-spi", },
{ },
};