Loading Documentation/devicetree/bindings/spi/spi-rockchip.txt +7 −4 Original line number Diff line number Diff line Loading @@ -6,10 +6,13 @@ and display controllers using the SPI communication interface. Required Properties: - compatible: should be one of the following. "rockchip,rk3066-spi" for rk3066. "rockchip,rk3188-spi", "rockchip,rk3066-spi" for rk3188. "rockchip,rk3288-spi", "rockchip,rk3066-spi" for rk3288. "rockchip,rk3399-spi", "rockchip,rk3066-spi" for rk3399. "rockchip,rk3036-spi" for rk3036 SoCS. "rockchip,rk3066-spi" for rk3066 SoCs. "rockchip,rk3188-spi" for rk3188 SoCs. "rockchip,rk3228-spi" for rk3228 SoCS. "rockchip,rk3288-spi" for rk3288 SoCs. "rockchip,rk3368-spi" for rk3368 SoCs. "rockchip,rk3399-spi" for rk3399 SoCs. - reg: physical base address of the controller and length of memory mapped region. - interrupts: The interrupt number to the cpu. The interrupt specifier format Loading Documentation/devicetree/bindings/spi/spi-samsung.txt +14 −1 Original line number Diff line number Diff line Loading @@ -9,7 +9,8 @@ Required SoC Specific Properties: - samsung,s3c2443-spi: for s3c2443, s3c2416 and s3c2450 platforms - samsung,s3c6410-spi: for s3c6410 platforms - samsung,s5pv210-spi: for s5pv210 and s5pc110 platforms - samsung,exynos7-spi: for exynos7 platforms - samsung,exynos5433-spi: for exynos5433 compatible controllers - samsung,exynos7-spi: for exynos7 platforms <DEPRECATED> - reg: physical base address of the controller and length of memory mapped region. Loading @@ -23,6 +24,15 @@ Required SoC Specific Properties: - dma-names: Names for the dma channels. There must be at least one channel named "tx" for transmit and named "rx" for receive. - clocks: specifies the clock IDs provided to the SPI controller; they are required for interacting with the controller itself, for synchronizing the bus and as I/O clock (the latter is required by exynos5433 and exynos7). - clock-names: string names of the clocks in the 'clocks' property; for all the the devices the names must be "spi", "spi_busclkN" (where N is determined by "samsung,spi-src-clk"), while Exynos5433 should specify a third clock "spi_ioclk" for the I/O clock. Required Board Specific Properties: - #address-cells: should be 1. Loading @@ -40,6 +50,9 @@ Optional Board Specific Properties: - cs-gpios: should specify GPIOs used for chipselects (see spi-bus.txt) - no-cs-readback: the CS line is disconnected, therefore the device should not operate based on CS signalling. SPI Controller specific data in SPI slave nodes: - The spi slave nodes should provide the following information which is required Loading drivers/spi/spi-pxa2xx-dma.c +29 −141 Original line number Diff line number Diff line Loading @@ -20,79 +20,6 @@ #include "spi-pxa2xx.h" static int pxa2xx_spi_map_dma_buffer(struct driver_data *drv_data, enum dma_data_direction dir) { int i, nents, len = drv_data->len; struct scatterlist *sg; struct device *dmadev; struct sg_table *sgt; void *buf, *pbuf; if (dir == DMA_TO_DEVICE) { dmadev = drv_data->tx_chan->device->dev; sgt = &drv_data->tx_sgt; buf = drv_data->tx; } else { dmadev = drv_data->rx_chan->device->dev; sgt = &drv_data->rx_sgt; buf = drv_data->rx; } nents = DIV_ROUND_UP(len, SZ_2K); if (nents != sgt->nents) { int ret; sg_free_table(sgt); ret = sg_alloc_table(sgt, nents, GFP_ATOMIC); if (ret) return ret; } pbuf = buf; for_each_sg(sgt->sgl, sg, sgt->nents, i) { size_t bytes = min_t(size_t, len, SZ_2K); sg_set_buf(sg, pbuf, bytes); pbuf += bytes; len -= bytes; } nents = dma_map_sg(dmadev, sgt->sgl, sgt->nents, dir); if (!nents) return -ENOMEM; return nents; } static void pxa2xx_spi_unmap_dma_buffer(struct driver_data *drv_data, enum dma_data_direction dir) { struct device *dmadev; struct sg_table *sgt; if (dir == DMA_TO_DEVICE) { dmadev = drv_data->tx_chan->device->dev; sgt = &drv_data->tx_sgt; } else { dmadev = drv_data->rx_chan->device->dev; sgt = &drv_data->rx_sgt; } dma_unmap_sg(dmadev, sgt->sgl, sgt->nents, dir); } static void pxa2xx_spi_unmap_dma_buffers(struct driver_data *drv_data) { if (!drv_data->dma_mapped) return; pxa2xx_spi_unmap_dma_buffer(drv_data, DMA_FROM_DEVICE); pxa2xx_spi_unmap_dma_buffer(drv_data, DMA_TO_DEVICE); drv_data->dma_mapped = 0; } static void pxa2xx_spi_dma_transfer_complete(struct driver_data *drv_data, bool error) { Loading Loading @@ -125,8 +52,6 @@ static void pxa2xx_spi_dma_transfer_complete(struct driver_data *drv_data, pxa2xx_spi_write(drv_data, SSTO, 0); if (!error) { pxa2xx_spi_unmap_dma_buffers(drv_data); msg->actual_length += drv_data->len; msg->state = pxa2xx_spi_next_transfer(drv_data); } else { Loading @@ -152,11 +77,12 @@ pxa2xx_spi_dma_prepare_one(struct driver_data *drv_data, enum dma_transfer_direction dir) { struct chip_data *chip = drv_data->cur_chip; struct spi_transfer *xfer = drv_data->cur_transfer; enum dma_slave_buswidth width; struct dma_slave_config cfg; struct dma_chan *chan; struct sg_table *sgt; int nents, ret; int ret; switch (drv_data->n_bytes) { case 1: Loading @@ -178,17 +104,15 @@ pxa2xx_spi_dma_prepare_one(struct driver_data *drv_data, cfg.dst_addr_width = width; cfg.dst_maxburst = chip->dma_burst_size; sgt = &drv_data->tx_sgt; nents = drv_data->tx_nents; chan = drv_data->tx_chan; sgt = &xfer->tx_sg; chan = drv_data->master->dma_tx; } else { cfg.src_addr = drv_data->ssdr_physical; cfg.src_addr_width = width; cfg.src_maxburst = chip->dma_burst_size; sgt = &drv_data->rx_sgt; nents = drv_data->rx_nents; chan = drv_data->rx_chan; sgt = &xfer->rx_sg; chan = drv_data->master->dma_rx; } ret = dmaengine_slave_config(chan, &cfg); Loading @@ -197,46 +121,10 @@ pxa2xx_spi_dma_prepare_one(struct driver_data *drv_data, return NULL; } return dmaengine_prep_slave_sg(chan, sgt->sgl, nents, dir, return dmaengine_prep_slave_sg(chan, sgt->sgl, sgt->nents, dir, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); } bool pxa2xx_spi_dma_is_possible(size_t len) { return len <= MAX_DMA_LEN; } int pxa2xx_spi_map_dma_buffers(struct driver_data *drv_data) { const struct chip_data *chip = drv_data->cur_chip; int ret; if (!chip->enable_dma) return 0; /* Don't bother with DMA if we can't do even a single burst */ if (drv_data->len < chip->dma_burst_size) return 0; ret = pxa2xx_spi_map_dma_buffer(drv_data, DMA_TO_DEVICE); if (ret <= 0) { dev_warn(&drv_data->pdev->dev, "failed to DMA map TX\n"); return 0; } drv_data->tx_nents = ret; ret = pxa2xx_spi_map_dma_buffer(drv_data, DMA_FROM_DEVICE); if (ret <= 0) { pxa2xx_spi_unmap_dma_buffer(drv_data, DMA_TO_DEVICE); dev_warn(&drv_data->pdev->dev, "failed to DMA map RX\n"); return 0; } drv_data->rx_nents = ret; return 1; } irqreturn_t pxa2xx_spi_dma_transfer(struct driver_data *drv_data) { u32 status; Loading @@ -245,8 +133,8 @@ irqreturn_t pxa2xx_spi_dma_transfer(struct driver_data *drv_data) if (status & SSSR_ROR) { dev_err(&drv_data->pdev->dev, "FIFO overrun\n"); dmaengine_terminate_async(drv_data->rx_chan); dmaengine_terminate_async(drv_data->tx_chan); dmaengine_terminate_async(drv_data->master->dma_rx); dmaengine_terminate_async(drv_data->master->dma_tx); pxa2xx_spi_dma_transfer_complete(drv_data, true); return IRQ_HANDLED; Loading Loading @@ -285,16 +173,15 @@ int pxa2xx_spi_dma_prepare(struct driver_data *drv_data, u32 dma_burst) return 0; err_rx: dmaengine_terminate_async(drv_data->tx_chan); dmaengine_terminate_async(drv_data->master->dma_tx); err_tx: pxa2xx_spi_unmap_dma_buffers(drv_data); return err; } void pxa2xx_spi_dma_start(struct driver_data *drv_data) { dma_async_issue_pending(drv_data->rx_chan); dma_async_issue_pending(drv_data->tx_chan); dma_async_issue_pending(drv_data->master->dma_rx); dma_async_issue_pending(drv_data->master->dma_tx); atomic_set(&drv_data->dma_running, 1); } Loading @@ -303,21 +190,22 @@ int pxa2xx_spi_dma_setup(struct driver_data *drv_data) { struct pxa2xx_spi_master *pdata = drv_data->master_info; struct device *dev = &drv_data->pdev->dev; struct spi_master *master = drv_data->master; dma_cap_mask_t mask; dma_cap_zero(mask); dma_cap_set(DMA_SLAVE, mask); drv_data->tx_chan = dma_request_slave_channel_compat(mask, master->dma_tx = dma_request_slave_channel_compat(mask, pdata->dma_filter, pdata->tx_param, dev, "tx"); if (!drv_data->tx_chan) if (!master->dma_tx) return -ENODEV; drv_data->rx_chan = dma_request_slave_channel_compat(mask, master->dma_rx = dma_request_slave_channel_compat(mask, pdata->dma_filter, pdata->rx_param, dev, "rx"); if (!drv_data->rx_chan) { dma_release_channel(drv_data->tx_chan); drv_data->tx_chan = NULL; if (!master->dma_rx) { dma_release_channel(master->dma_tx); master->dma_tx = NULL; return -ENODEV; } Loading @@ -326,17 +214,17 @@ int pxa2xx_spi_dma_setup(struct driver_data *drv_data) void pxa2xx_spi_dma_release(struct driver_data *drv_data) { if (drv_data->rx_chan) { dmaengine_terminate_sync(drv_data->rx_chan); dma_release_channel(drv_data->rx_chan); sg_free_table(&drv_data->rx_sgt); drv_data->rx_chan = NULL; struct spi_master *master = drv_data->master; if (master->dma_rx) { dmaengine_terminate_sync(master->dma_rx); dma_release_channel(master->dma_rx); master->dma_rx = NULL; } if (drv_data->tx_chan) { dmaengine_terminate_sync(drv_data->tx_chan); dma_release_channel(drv_data->tx_chan); sg_free_table(&drv_data->tx_sgt); drv_data->tx_chan = NULL; if (master->dma_tx) { dmaengine_terminate_sync(master->dma_tx); dma_release_channel(master->dma_tx); master->dma_tx = NULL; } } Loading drivers/spi/spi-pxa2xx-pci.c +82 −46 Original line number Diff line number Diff line /* * CE4100's SPI device is more or less the same one as found on PXA * * Copyright (C) 2016, Intel Corporation */ #include <linux/clk-provider.h> #include <linux/module.h> #include <linux/of_device.h> #include <linux/pci.h> #include <linux/platform_device.h> #include <linux/of_device.h> #include <linux/module.h> #include <linux/spi/pxa2xx_spi.h> #include <linux/clk-provider.h> #include <linux/dmaengine.h> #include <linux/platform_data/dma-dw.h> enum { PORT_CE4100, PORT_QUARK_X1000, PORT_BYT, PORT_MRFLD, PORT_BSW0, PORT_BSW1, PORT_BSW2, PORT_QUARK_X1000, PORT_CE4100, PORT_LPT, }; Loading @@ -29,8 +31,11 @@ struct pxa_spi_info { unsigned long max_clk_rate; /* DMA channel request parameters */ bool (*dma_filter)(struct dma_chan *chan, void *param); void *tx_param; void *rx_param; int (*setup)(struct pci_dev *pdev, struct pxa_spi_info *c); }; static struct dw_dma_slave byt_tx_param = { .dst_id = 0 }; Loading @@ -57,6 +62,56 @@ static bool lpss_dma_filter(struct dma_chan *chan, void *param) return true; } static int lpss_spi_setup(struct pci_dev *dev, struct pxa_spi_info *c) { struct pci_dev *dma_dev; c->num_chipselect = 1; c->max_clk_rate = 50000000; dma_dev = pci_get_slot(dev->bus, PCI_DEVFN(PCI_SLOT(dev->devfn), 0)); if (c->tx_param) { struct dw_dma_slave *slave = c->tx_param; slave->dma_dev = &dma_dev->dev; slave->m_master = 0; slave->p_master = 1; } if (c->rx_param) { struct dw_dma_slave *slave = c->rx_param; slave->dma_dev = &dma_dev->dev; slave->m_master = 0; slave->p_master = 1; } c->dma_filter = lpss_dma_filter; return 0; } static int mrfld_spi_setup(struct pci_dev *dev, struct pxa_spi_info *c) { switch (PCI_FUNC(dev->devfn)) { case 0: c->port_id = 3; c->num_chipselect = 1; break; case 1: c->port_id = 5; c->num_chipselect = 4; break; case 2: c->port_id = 6; c->num_chipselect = 1; break; default: return -ENODEV; } return 0; } static struct pxa_spi_info spi_info_configs[] = { [PORT_CE4100] = { .type = PXA25x_SSP, Loading @@ -67,35 +122,36 @@ static struct pxa_spi_info spi_info_configs[] = { [PORT_BYT] = { .type = LPSS_BYT_SSP, .port_id = 0, .num_chipselect = 1, .max_clk_rate = 50000000, .setup = lpss_spi_setup, .tx_param = &byt_tx_param, .rx_param = &byt_rx_param, }, [PORT_BSW0] = { .type = LPSS_BYT_SSP, .type = LPSS_BSW_SSP, .port_id = 0, .num_chipselect = 1, .max_clk_rate = 50000000, .setup = lpss_spi_setup, .tx_param = &bsw0_tx_param, .rx_param = &bsw0_rx_param, }, [PORT_BSW1] = { .type = LPSS_BYT_SSP, .type = LPSS_BSW_SSP, .port_id = 1, .num_chipselect = 1, .max_clk_rate = 50000000, .setup = lpss_spi_setup, .tx_param = &bsw1_tx_param, .rx_param = &bsw1_rx_param, }, [PORT_BSW2] = { .type = LPSS_BYT_SSP, .type = LPSS_BSW_SSP, .port_id = 2, .num_chipselect = 1, .max_clk_rate = 50000000, .setup = lpss_spi_setup, .tx_param = &bsw2_tx_param, .rx_param = &bsw2_rx_param, }, [PORT_MRFLD] = { .type = PXA27x_SSP, .max_clk_rate = 25000000, .setup = mrfld_spi_setup, }, [PORT_QUARK_X1000] = { .type = QUARK_X1000_SSP, .port_id = -1, Loading @@ -105,8 +161,7 @@ static struct pxa_spi_info spi_info_configs[] = { [PORT_LPT] = { .type = LPSS_LPT_SSP, .port_id = 0, .num_chipselect = 1, .max_clk_rate = 50000000, .setup = lpss_spi_setup, .tx_param = &lpt_tx_param, .rx_param = &lpt_rx_param, }, Loading @@ -122,7 +177,6 @@ static int pxa2xx_spi_pci_probe(struct pci_dev *dev, struct ssp_device *ssp; struct pxa_spi_info *c; char buf[40]; struct pci_dev *dma_dev; ret = pcim_enable_device(dev); if (ret) Loading @@ -133,30 +187,15 @@ static int pxa2xx_spi_pci_probe(struct pci_dev *dev, return ret; c = &spi_info_configs[ent->driver_data]; memset(&spi_pdata, 0, sizeof(spi_pdata)); spi_pdata.num_chipselect = (c->num_chipselect > 0) ? c->num_chipselect : dev->devfn; dma_dev = pci_get_slot(dev->bus, PCI_DEVFN(PCI_SLOT(dev->devfn), 0)); if (c->tx_param) { struct dw_dma_slave *slave = c->tx_param; slave->dma_dev = &dma_dev->dev; slave->m_master = 0; slave->p_master = 1; } if (c->rx_param) { struct dw_dma_slave *slave = c->rx_param; slave->dma_dev = &dma_dev->dev; slave->m_master = 0; slave->p_master = 1; if (c->setup) { ret = c->setup(dev, c); if (ret) return ret; } spi_pdata.dma_filter = lpss_dma_filter; memset(&spi_pdata, 0, sizeof(spi_pdata)); spi_pdata.num_chipselect = (c->num_chipselect > 0) ? c->num_chipselect : dev->devfn; spi_pdata.dma_filter = c->dma_filter; spi_pdata.tx_param = c->tx_param; spi_pdata.rx_param = c->rx_param; spi_pdata.enable_dma = c->rx_param && c->tx_param; Loading @@ -164,10 +203,6 @@ static int pxa2xx_spi_pci_probe(struct pci_dev *dev, ssp = &spi_pdata.ssp; ssp->phys_base = pci_resource_start(dev, 0); ssp->mmio_base = pcim_iomap_table(dev)[0]; if (!ssp->mmio_base) { dev_err(&dev->dev, "failed to ioremap() registers\n"); return -EIO; } ssp->irq = dev->irq; ssp->port_id = (c->port_id >= 0) ? c->port_id : dev->devfn; ssp->type = c->type; Loading Loading @@ -208,12 +243,13 @@ static void pxa2xx_spi_pci_remove(struct pci_dev *dev) } static const struct pci_device_id pxa2xx_spi_pci_devices[] = { { PCI_VDEVICE(INTEL, 0x2e6a), PORT_CE4100 }, { PCI_VDEVICE(INTEL, 0x0935), PORT_QUARK_X1000 }, { PCI_VDEVICE(INTEL, 0x0f0e), PORT_BYT }, { PCI_VDEVICE(INTEL, 0x1194), PORT_MRFLD }, { PCI_VDEVICE(INTEL, 0x228e), PORT_BSW0 }, { PCI_VDEVICE(INTEL, 0x2290), PORT_BSW1 }, { PCI_VDEVICE(INTEL, 0x22ac), PORT_BSW2 }, { PCI_VDEVICE(INTEL, 0x2e6a), PORT_CE4100 }, { PCI_VDEVICE(INTEL, 0x9ce6), PORT_LPT }, { }, }; Loading drivers/spi/spi-pxa2xx.c +28 −18 Original line number Diff line number Diff line Loading @@ -919,9 +919,21 @@ static unsigned int pxa2xx_ssp_get_clk_div(struct driver_data *drv_data, 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; Loading @@ -935,6 +947,7 @@ static void pump_transfers(unsigned long data) 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; Loading Loading @@ -969,7 +982,7 @@ static void pump_transfers(unsigned long data) } /* 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 Loading Loading @@ -1046,10 +1059,10 @@ static void pump_transfers(unsigned long data) 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; Loading Loading @@ -1079,14 +1092,14 @@ static void pump_transfers(unsigned long data) 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) Loading Loading @@ -1247,7 +1260,7 @@ static int setup(struct spi_device *spi) 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; } Loading @@ -1266,17 +1279,9 @@ static int setup(struct spi_device *spi) 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); Loading Loading @@ -1396,6 +1401,9 @@ static const struct pci_device_id pxa2xx_spi_pci_compound_match[] = { /* 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 }, Loading Loading @@ -1608,6 +1616,8 @@ static int pxa2xx_spi_probe(struct platform_device *pdev) 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; } } Loading Loading
Documentation/devicetree/bindings/spi/spi-rockchip.txt +7 −4 Original line number Diff line number Diff line Loading @@ -6,10 +6,13 @@ and display controllers using the SPI communication interface. Required Properties: - compatible: should be one of the following. "rockchip,rk3066-spi" for rk3066. "rockchip,rk3188-spi", "rockchip,rk3066-spi" for rk3188. "rockchip,rk3288-spi", "rockchip,rk3066-spi" for rk3288. "rockchip,rk3399-spi", "rockchip,rk3066-spi" for rk3399. "rockchip,rk3036-spi" for rk3036 SoCS. "rockchip,rk3066-spi" for rk3066 SoCs. "rockchip,rk3188-spi" for rk3188 SoCs. "rockchip,rk3228-spi" for rk3228 SoCS. "rockchip,rk3288-spi" for rk3288 SoCs. "rockchip,rk3368-spi" for rk3368 SoCs. "rockchip,rk3399-spi" for rk3399 SoCs. - reg: physical base address of the controller and length of memory mapped region. - interrupts: The interrupt number to the cpu. The interrupt specifier format Loading
Documentation/devicetree/bindings/spi/spi-samsung.txt +14 −1 Original line number Diff line number Diff line Loading @@ -9,7 +9,8 @@ Required SoC Specific Properties: - samsung,s3c2443-spi: for s3c2443, s3c2416 and s3c2450 platforms - samsung,s3c6410-spi: for s3c6410 platforms - samsung,s5pv210-spi: for s5pv210 and s5pc110 platforms - samsung,exynos7-spi: for exynos7 platforms - samsung,exynos5433-spi: for exynos5433 compatible controllers - samsung,exynos7-spi: for exynos7 platforms <DEPRECATED> - reg: physical base address of the controller and length of memory mapped region. Loading @@ -23,6 +24,15 @@ Required SoC Specific Properties: - dma-names: Names for the dma channels. There must be at least one channel named "tx" for transmit and named "rx" for receive. - clocks: specifies the clock IDs provided to the SPI controller; they are required for interacting with the controller itself, for synchronizing the bus and as I/O clock (the latter is required by exynos5433 and exynos7). - clock-names: string names of the clocks in the 'clocks' property; for all the the devices the names must be "spi", "spi_busclkN" (where N is determined by "samsung,spi-src-clk"), while Exynos5433 should specify a third clock "spi_ioclk" for the I/O clock. Required Board Specific Properties: - #address-cells: should be 1. Loading @@ -40,6 +50,9 @@ Optional Board Specific Properties: - cs-gpios: should specify GPIOs used for chipselects (see spi-bus.txt) - no-cs-readback: the CS line is disconnected, therefore the device should not operate based on CS signalling. SPI Controller specific data in SPI slave nodes: - The spi slave nodes should provide the following information which is required Loading
drivers/spi/spi-pxa2xx-dma.c +29 −141 Original line number Diff line number Diff line Loading @@ -20,79 +20,6 @@ #include "spi-pxa2xx.h" static int pxa2xx_spi_map_dma_buffer(struct driver_data *drv_data, enum dma_data_direction dir) { int i, nents, len = drv_data->len; struct scatterlist *sg; struct device *dmadev; struct sg_table *sgt; void *buf, *pbuf; if (dir == DMA_TO_DEVICE) { dmadev = drv_data->tx_chan->device->dev; sgt = &drv_data->tx_sgt; buf = drv_data->tx; } else { dmadev = drv_data->rx_chan->device->dev; sgt = &drv_data->rx_sgt; buf = drv_data->rx; } nents = DIV_ROUND_UP(len, SZ_2K); if (nents != sgt->nents) { int ret; sg_free_table(sgt); ret = sg_alloc_table(sgt, nents, GFP_ATOMIC); if (ret) return ret; } pbuf = buf; for_each_sg(sgt->sgl, sg, sgt->nents, i) { size_t bytes = min_t(size_t, len, SZ_2K); sg_set_buf(sg, pbuf, bytes); pbuf += bytes; len -= bytes; } nents = dma_map_sg(dmadev, sgt->sgl, sgt->nents, dir); if (!nents) return -ENOMEM; return nents; } static void pxa2xx_spi_unmap_dma_buffer(struct driver_data *drv_data, enum dma_data_direction dir) { struct device *dmadev; struct sg_table *sgt; if (dir == DMA_TO_DEVICE) { dmadev = drv_data->tx_chan->device->dev; sgt = &drv_data->tx_sgt; } else { dmadev = drv_data->rx_chan->device->dev; sgt = &drv_data->rx_sgt; } dma_unmap_sg(dmadev, sgt->sgl, sgt->nents, dir); } static void pxa2xx_spi_unmap_dma_buffers(struct driver_data *drv_data) { if (!drv_data->dma_mapped) return; pxa2xx_spi_unmap_dma_buffer(drv_data, DMA_FROM_DEVICE); pxa2xx_spi_unmap_dma_buffer(drv_data, DMA_TO_DEVICE); drv_data->dma_mapped = 0; } static void pxa2xx_spi_dma_transfer_complete(struct driver_data *drv_data, bool error) { Loading Loading @@ -125,8 +52,6 @@ static void pxa2xx_spi_dma_transfer_complete(struct driver_data *drv_data, pxa2xx_spi_write(drv_data, SSTO, 0); if (!error) { pxa2xx_spi_unmap_dma_buffers(drv_data); msg->actual_length += drv_data->len; msg->state = pxa2xx_spi_next_transfer(drv_data); } else { Loading @@ -152,11 +77,12 @@ pxa2xx_spi_dma_prepare_one(struct driver_data *drv_data, enum dma_transfer_direction dir) { struct chip_data *chip = drv_data->cur_chip; struct spi_transfer *xfer = drv_data->cur_transfer; enum dma_slave_buswidth width; struct dma_slave_config cfg; struct dma_chan *chan; struct sg_table *sgt; int nents, ret; int ret; switch (drv_data->n_bytes) { case 1: Loading @@ -178,17 +104,15 @@ pxa2xx_spi_dma_prepare_one(struct driver_data *drv_data, cfg.dst_addr_width = width; cfg.dst_maxburst = chip->dma_burst_size; sgt = &drv_data->tx_sgt; nents = drv_data->tx_nents; chan = drv_data->tx_chan; sgt = &xfer->tx_sg; chan = drv_data->master->dma_tx; } else { cfg.src_addr = drv_data->ssdr_physical; cfg.src_addr_width = width; cfg.src_maxburst = chip->dma_burst_size; sgt = &drv_data->rx_sgt; nents = drv_data->rx_nents; chan = drv_data->rx_chan; sgt = &xfer->rx_sg; chan = drv_data->master->dma_rx; } ret = dmaengine_slave_config(chan, &cfg); Loading @@ -197,46 +121,10 @@ pxa2xx_spi_dma_prepare_one(struct driver_data *drv_data, return NULL; } return dmaengine_prep_slave_sg(chan, sgt->sgl, nents, dir, return dmaengine_prep_slave_sg(chan, sgt->sgl, sgt->nents, dir, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); } bool pxa2xx_spi_dma_is_possible(size_t len) { return len <= MAX_DMA_LEN; } int pxa2xx_spi_map_dma_buffers(struct driver_data *drv_data) { const struct chip_data *chip = drv_data->cur_chip; int ret; if (!chip->enable_dma) return 0; /* Don't bother with DMA if we can't do even a single burst */ if (drv_data->len < chip->dma_burst_size) return 0; ret = pxa2xx_spi_map_dma_buffer(drv_data, DMA_TO_DEVICE); if (ret <= 0) { dev_warn(&drv_data->pdev->dev, "failed to DMA map TX\n"); return 0; } drv_data->tx_nents = ret; ret = pxa2xx_spi_map_dma_buffer(drv_data, DMA_FROM_DEVICE); if (ret <= 0) { pxa2xx_spi_unmap_dma_buffer(drv_data, DMA_TO_DEVICE); dev_warn(&drv_data->pdev->dev, "failed to DMA map RX\n"); return 0; } drv_data->rx_nents = ret; return 1; } irqreturn_t pxa2xx_spi_dma_transfer(struct driver_data *drv_data) { u32 status; Loading @@ -245,8 +133,8 @@ irqreturn_t pxa2xx_spi_dma_transfer(struct driver_data *drv_data) if (status & SSSR_ROR) { dev_err(&drv_data->pdev->dev, "FIFO overrun\n"); dmaengine_terminate_async(drv_data->rx_chan); dmaengine_terminate_async(drv_data->tx_chan); dmaengine_terminate_async(drv_data->master->dma_rx); dmaengine_terminate_async(drv_data->master->dma_tx); pxa2xx_spi_dma_transfer_complete(drv_data, true); return IRQ_HANDLED; Loading Loading @@ -285,16 +173,15 @@ int pxa2xx_spi_dma_prepare(struct driver_data *drv_data, u32 dma_burst) return 0; err_rx: dmaengine_terminate_async(drv_data->tx_chan); dmaengine_terminate_async(drv_data->master->dma_tx); err_tx: pxa2xx_spi_unmap_dma_buffers(drv_data); return err; } void pxa2xx_spi_dma_start(struct driver_data *drv_data) { dma_async_issue_pending(drv_data->rx_chan); dma_async_issue_pending(drv_data->tx_chan); dma_async_issue_pending(drv_data->master->dma_rx); dma_async_issue_pending(drv_data->master->dma_tx); atomic_set(&drv_data->dma_running, 1); } Loading @@ -303,21 +190,22 @@ int pxa2xx_spi_dma_setup(struct driver_data *drv_data) { struct pxa2xx_spi_master *pdata = drv_data->master_info; struct device *dev = &drv_data->pdev->dev; struct spi_master *master = drv_data->master; dma_cap_mask_t mask; dma_cap_zero(mask); dma_cap_set(DMA_SLAVE, mask); drv_data->tx_chan = dma_request_slave_channel_compat(mask, master->dma_tx = dma_request_slave_channel_compat(mask, pdata->dma_filter, pdata->tx_param, dev, "tx"); if (!drv_data->tx_chan) if (!master->dma_tx) return -ENODEV; drv_data->rx_chan = dma_request_slave_channel_compat(mask, master->dma_rx = dma_request_slave_channel_compat(mask, pdata->dma_filter, pdata->rx_param, dev, "rx"); if (!drv_data->rx_chan) { dma_release_channel(drv_data->tx_chan); drv_data->tx_chan = NULL; if (!master->dma_rx) { dma_release_channel(master->dma_tx); master->dma_tx = NULL; return -ENODEV; } Loading @@ -326,17 +214,17 @@ int pxa2xx_spi_dma_setup(struct driver_data *drv_data) void pxa2xx_spi_dma_release(struct driver_data *drv_data) { if (drv_data->rx_chan) { dmaengine_terminate_sync(drv_data->rx_chan); dma_release_channel(drv_data->rx_chan); sg_free_table(&drv_data->rx_sgt); drv_data->rx_chan = NULL; struct spi_master *master = drv_data->master; if (master->dma_rx) { dmaengine_terminate_sync(master->dma_rx); dma_release_channel(master->dma_rx); master->dma_rx = NULL; } if (drv_data->tx_chan) { dmaengine_terminate_sync(drv_data->tx_chan); dma_release_channel(drv_data->tx_chan); sg_free_table(&drv_data->tx_sgt); drv_data->tx_chan = NULL; if (master->dma_tx) { dmaengine_terminate_sync(master->dma_tx); dma_release_channel(master->dma_tx); master->dma_tx = NULL; } } Loading
drivers/spi/spi-pxa2xx-pci.c +82 −46 Original line number Diff line number Diff line /* * CE4100's SPI device is more or less the same one as found on PXA * * Copyright (C) 2016, Intel Corporation */ #include <linux/clk-provider.h> #include <linux/module.h> #include <linux/of_device.h> #include <linux/pci.h> #include <linux/platform_device.h> #include <linux/of_device.h> #include <linux/module.h> #include <linux/spi/pxa2xx_spi.h> #include <linux/clk-provider.h> #include <linux/dmaengine.h> #include <linux/platform_data/dma-dw.h> enum { PORT_CE4100, PORT_QUARK_X1000, PORT_BYT, PORT_MRFLD, PORT_BSW0, PORT_BSW1, PORT_BSW2, PORT_QUARK_X1000, PORT_CE4100, PORT_LPT, }; Loading @@ -29,8 +31,11 @@ struct pxa_spi_info { unsigned long max_clk_rate; /* DMA channel request parameters */ bool (*dma_filter)(struct dma_chan *chan, void *param); void *tx_param; void *rx_param; int (*setup)(struct pci_dev *pdev, struct pxa_spi_info *c); }; static struct dw_dma_slave byt_tx_param = { .dst_id = 0 }; Loading @@ -57,6 +62,56 @@ static bool lpss_dma_filter(struct dma_chan *chan, void *param) return true; } static int lpss_spi_setup(struct pci_dev *dev, struct pxa_spi_info *c) { struct pci_dev *dma_dev; c->num_chipselect = 1; c->max_clk_rate = 50000000; dma_dev = pci_get_slot(dev->bus, PCI_DEVFN(PCI_SLOT(dev->devfn), 0)); if (c->tx_param) { struct dw_dma_slave *slave = c->tx_param; slave->dma_dev = &dma_dev->dev; slave->m_master = 0; slave->p_master = 1; } if (c->rx_param) { struct dw_dma_slave *slave = c->rx_param; slave->dma_dev = &dma_dev->dev; slave->m_master = 0; slave->p_master = 1; } c->dma_filter = lpss_dma_filter; return 0; } static int mrfld_spi_setup(struct pci_dev *dev, struct pxa_spi_info *c) { switch (PCI_FUNC(dev->devfn)) { case 0: c->port_id = 3; c->num_chipselect = 1; break; case 1: c->port_id = 5; c->num_chipselect = 4; break; case 2: c->port_id = 6; c->num_chipselect = 1; break; default: return -ENODEV; } return 0; } static struct pxa_spi_info spi_info_configs[] = { [PORT_CE4100] = { .type = PXA25x_SSP, Loading @@ -67,35 +122,36 @@ static struct pxa_spi_info spi_info_configs[] = { [PORT_BYT] = { .type = LPSS_BYT_SSP, .port_id = 0, .num_chipselect = 1, .max_clk_rate = 50000000, .setup = lpss_spi_setup, .tx_param = &byt_tx_param, .rx_param = &byt_rx_param, }, [PORT_BSW0] = { .type = LPSS_BYT_SSP, .type = LPSS_BSW_SSP, .port_id = 0, .num_chipselect = 1, .max_clk_rate = 50000000, .setup = lpss_spi_setup, .tx_param = &bsw0_tx_param, .rx_param = &bsw0_rx_param, }, [PORT_BSW1] = { .type = LPSS_BYT_SSP, .type = LPSS_BSW_SSP, .port_id = 1, .num_chipselect = 1, .max_clk_rate = 50000000, .setup = lpss_spi_setup, .tx_param = &bsw1_tx_param, .rx_param = &bsw1_rx_param, }, [PORT_BSW2] = { .type = LPSS_BYT_SSP, .type = LPSS_BSW_SSP, .port_id = 2, .num_chipselect = 1, .max_clk_rate = 50000000, .setup = lpss_spi_setup, .tx_param = &bsw2_tx_param, .rx_param = &bsw2_rx_param, }, [PORT_MRFLD] = { .type = PXA27x_SSP, .max_clk_rate = 25000000, .setup = mrfld_spi_setup, }, [PORT_QUARK_X1000] = { .type = QUARK_X1000_SSP, .port_id = -1, Loading @@ -105,8 +161,7 @@ static struct pxa_spi_info spi_info_configs[] = { [PORT_LPT] = { .type = LPSS_LPT_SSP, .port_id = 0, .num_chipselect = 1, .max_clk_rate = 50000000, .setup = lpss_spi_setup, .tx_param = &lpt_tx_param, .rx_param = &lpt_rx_param, }, Loading @@ -122,7 +177,6 @@ static int pxa2xx_spi_pci_probe(struct pci_dev *dev, struct ssp_device *ssp; struct pxa_spi_info *c; char buf[40]; struct pci_dev *dma_dev; ret = pcim_enable_device(dev); if (ret) Loading @@ -133,30 +187,15 @@ static int pxa2xx_spi_pci_probe(struct pci_dev *dev, return ret; c = &spi_info_configs[ent->driver_data]; memset(&spi_pdata, 0, sizeof(spi_pdata)); spi_pdata.num_chipselect = (c->num_chipselect > 0) ? c->num_chipselect : dev->devfn; dma_dev = pci_get_slot(dev->bus, PCI_DEVFN(PCI_SLOT(dev->devfn), 0)); if (c->tx_param) { struct dw_dma_slave *slave = c->tx_param; slave->dma_dev = &dma_dev->dev; slave->m_master = 0; slave->p_master = 1; } if (c->rx_param) { struct dw_dma_slave *slave = c->rx_param; slave->dma_dev = &dma_dev->dev; slave->m_master = 0; slave->p_master = 1; if (c->setup) { ret = c->setup(dev, c); if (ret) return ret; } spi_pdata.dma_filter = lpss_dma_filter; memset(&spi_pdata, 0, sizeof(spi_pdata)); spi_pdata.num_chipselect = (c->num_chipselect > 0) ? c->num_chipselect : dev->devfn; spi_pdata.dma_filter = c->dma_filter; spi_pdata.tx_param = c->tx_param; spi_pdata.rx_param = c->rx_param; spi_pdata.enable_dma = c->rx_param && c->tx_param; Loading @@ -164,10 +203,6 @@ static int pxa2xx_spi_pci_probe(struct pci_dev *dev, ssp = &spi_pdata.ssp; ssp->phys_base = pci_resource_start(dev, 0); ssp->mmio_base = pcim_iomap_table(dev)[0]; if (!ssp->mmio_base) { dev_err(&dev->dev, "failed to ioremap() registers\n"); return -EIO; } ssp->irq = dev->irq; ssp->port_id = (c->port_id >= 0) ? c->port_id : dev->devfn; ssp->type = c->type; Loading Loading @@ -208,12 +243,13 @@ static void pxa2xx_spi_pci_remove(struct pci_dev *dev) } static const struct pci_device_id pxa2xx_spi_pci_devices[] = { { PCI_VDEVICE(INTEL, 0x2e6a), PORT_CE4100 }, { PCI_VDEVICE(INTEL, 0x0935), PORT_QUARK_X1000 }, { PCI_VDEVICE(INTEL, 0x0f0e), PORT_BYT }, { PCI_VDEVICE(INTEL, 0x1194), PORT_MRFLD }, { PCI_VDEVICE(INTEL, 0x228e), PORT_BSW0 }, { PCI_VDEVICE(INTEL, 0x2290), PORT_BSW1 }, { PCI_VDEVICE(INTEL, 0x22ac), PORT_BSW2 }, { PCI_VDEVICE(INTEL, 0x2e6a), PORT_CE4100 }, { PCI_VDEVICE(INTEL, 0x9ce6), PORT_LPT }, { }, }; Loading
drivers/spi/spi-pxa2xx.c +28 −18 Original line number Diff line number Diff line Loading @@ -919,9 +919,21 @@ static unsigned int pxa2xx_ssp_get_clk_div(struct driver_data *drv_data, 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; Loading @@ -935,6 +947,7 @@ static void pump_transfers(unsigned long data) 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; Loading Loading @@ -969,7 +982,7 @@ static void pump_transfers(unsigned long data) } /* 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 Loading Loading @@ -1046,10 +1059,10 @@ static void pump_transfers(unsigned long data) 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; Loading Loading @@ -1079,14 +1092,14 @@ static void pump_transfers(unsigned long data) 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) Loading Loading @@ -1247,7 +1260,7 @@ static int setup(struct spi_device *spi) 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; } Loading @@ -1266,17 +1279,9 @@ static int setup(struct spi_device *spi) 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); Loading Loading @@ -1396,6 +1401,9 @@ static const struct pci_device_id pxa2xx_spi_pci_compound_match[] = { /* 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 }, Loading Loading @@ -1608,6 +1616,8 @@ static int pxa2xx_spi_probe(struct platform_device *pdev) 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; } } Loading