diff options
Diffstat (limited to 'drivers/spi')
-rw-r--r-- | drivers/spi/bcm63xx_hsspi.c | 2 | ||||
-rw-r--r-- | drivers/spi/cadence_qspi.c | 12 | ||||
-rw-r--r-- | drivers/spi/cadence_qspi.h | 1 | ||||
-rw-r--r-- | drivers/spi/cadence_qspi_apb.c | 3 | ||||
-rw-r--r-- | drivers/spi/fsl_dspi.c | 5 | ||||
-rw-r--r-- | drivers/spi/meson_spifc_a1.c | 7 | ||||
-rw-r--r-- | drivers/spi/npcm_pspi.c | 2 | ||||
-rw-r--r-- | drivers/spi/spi-mem-nodm.c | 1 | ||||
-rw-r--r-- | drivers/spi/xilinx_spi.c | 68 |
9 files changed, 70 insertions, 31 deletions
diff --git a/drivers/spi/bcm63xx_hsspi.c b/drivers/spi/bcm63xx_hsspi.c index a24bb430cbb..19d9a5ae23c 100644 --- a/drivers/spi/bcm63xx_hsspi.c +++ b/drivers/spi/bcm63xx_hsspi.c @@ -295,7 +295,7 @@ static int bcm63xx_hsspi_xfer_dummy_cs(struct udevice *dev, unsigned int data_by /* transfer loop */ while (data_bytes > 0) { - size_t curr_step = min(step_size, data_bytes); + size_t curr_step = min(step_size, (size_t)data_bytes); int ret; /* copy tx data */ diff --git a/drivers/spi/cadence_qspi.c b/drivers/spi/cadence_qspi.c index cc3a54f2958..dfc74c882d2 100644 --- a/drivers/spi/cadence_qspi.c +++ b/drivers/spi/cadence_qspi.c @@ -7,7 +7,6 @@ #include <common.h> #include <clk.h> #include <log.h> -#include <asm-generic/io.h> #include <dm.h> #include <fdtdec.h> #include <malloc.h> @@ -17,13 +16,13 @@ #include <dm/device_compat.h> #include <linux/err.h> #include <linux/errno.h> +#include <linux/io.h> #include <linux/sizes.h> +#include <linux/time.h> #include <zynqmp_firmware.h> #include "cadence_qspi.h" #include <dt-bindings/power/xlnx-versal-power.h> -#define NSEC_PER_SEC 1000000000L - #define CQSPI_STIG_READ 0 #define CQSPI_STIG_WRITE 1 #define CQSPI_READ 2 @@ -40,6 +39,11 @@ __weak int cadence_qspi_versal_flash_reset(struct udevice *dev) return 0; } +__weak ofnode cadence_qspi_get_subnode(struct udevice *dev) +{ + return dev_read_first_subnode(dev); +} + static int cadence_spi_write_speed(struct udevice *bus, uint hz) { struct cadence_spi_priv *priv = dev_get_priv(bus); @@ -401,7 +405,7 @@ static int cadence_spi_of_to_plat(struct udevice *bus) plat->is_dma = dev_read_bool(bus, "cdns,is-dma"); /* All other parameters are embedded in the child node */ - subnode = dev_read_first_subnode(bus); + subnode = cadence_qspi_get_subnode(bus); if (!ofnode_valid(subnode)) { printf("Error: subnode with SPI flash config missing!\n"); return -ENODEV; diff --git a/drivers/spi/cadence_qspi.h b/drivers/spi/cadence_qspi.h index 1c59d1a9d9a..12825f8911c 100644 --- a/drivers/spi/cadence_qspi.h +++ b/drivers/spi/cadence_qspi.h @@ -304,6 +304,7 @@ int cadence_qspi_apb_dma_read(struct cadence_spi_priv *priv, int cadence_qspi_apb_wait_for_dma_cmplt(struct cadence_spi_priv *priv); int cadence_qspi_apb_exec_flash_cmd(void *reg_base, unsigned int reg); int cadence_qspi_versal_flash_reset(struct udevice *dev); +ofnode cadence_qspi_get_subnode(struct udevice *dev); void cadence_qspi_apb_enable_linear_mode(bool enable); #endif /* __CADENCE_QSPI_H__ */ diff --git a/drivers/spi/cadence_qspi_apb.c b/drivers/spi/cadence_qspi_apb.c index 9ce2c0f254f..d033184aa46 100644 --- a/drivers/spi/cadence_qspi_apb.c +++ b/drivers/spi/cadence_qspi_apb.c @@ -171,8 +171,7 @@ static unsigned int cadence_qspi_wait_idle(void *reg_base) } /* Timeout, still in busy mode. */ - printf("QSPI: QSPI is still busy after poll for %d times.\n", - CQSPI_REG_RETRY); + printf("QSPI: QSPI is still busy after poll for %d ms.\n", timeout); return 0; } diff --git a/drivers/spi/fsl_dspi.c b/drivers/spi/fsl_dspi.c index f8ec268812c..9b3d5a94817 100644 --- a/drivers/spi/fsl_dspi.c +++ b/drivers/spi/fsl_dspi.c @@ -14,7 +14,6 @@ #include <common.h> #include <dm.h> #include <errno.h> -#include <common.h> #include <log.h> #include <spi.h> #include <malloc.h> @@ -27,9 +26,7 @@ #include <linux/bitops.h> #include <linux/delay.h> #include <linux/printk.h> - -/* linux/include/time.h */ -#define NSEC_PER_SEC 1000000000L +#include <linux/time.h> DECLARE_GLOBAL_DATA_PTR; diff --git a/drivers/spi/meson_spifc_a1.c b/drivers/spi/meson_spifc_a1.c index 099c4c037dd..cca4debb412 100644 --- a/drivers/spi/meson_spifc_a1.c +++ b/drivers/spi/meson_spifc_a1.c @@ -16,6 +16,7 @@ #include <spi-mem.h> #include <asm/io.h> #include <linux/log2.h> +#include <linux/time.h> #include <linux/iopoll.h> #include <linux/bitfield.h> @@ -117,7 +118,7 @@ static int amlogic_spifc_a1_request(struct amlogic_spifc_a1 *spifc, bool read) return readl_poll_timeout(spifc->base + SPIFC_A1_USER_CTRL0_REG, val, (val & mask) == mask, - 200 * 1000); + 200 * USEC_PER_MSEC); } static void amlogic_spifc_a1_drain_buffer(struct amlogic_spifc_a1 *spifc, @@ -129,7 +130,7 @@ static void amlogic_spifc_a1_drain_buffer(struct amlogic_spifc_a1 *spifc, writel(SPIFC_A1_DBUF_AUTO_UPDATE_ADDR, spifc->base + SPIFC_A1_DBUF_CTRL_REG); - readsl(spifc->base + SPIFC_A1_DBUF_DATA_REG, buf, count); + ioread32_rep(spifc->base + SPIFC_A1_DBUF_DATA_REG, buf, count); if (pad) { data = readl(spifc->base + SPIFC_A1_DBUF_DATA_REG); @@ -146,7 +147,7 @@ static void amlogic_spifc_a1_fill_buffer(struct amlogic_spifc_a1 *spifc, writel(SPIFC_A1_DBUF_DIR | SPIFC_A1_DBUF_AUTO_UPDATE_ADDR, spifc->base + SPIFC_A1_DBUF_CTRL_REG); - writesl(spifc->base + SPIFC_A1_DBUF_DATA_REG, buf, count); + iowrite32_rep(spifc->base + SPIFC_A1_DBUF_DATA_REG, buf, count); if (pad) { memcpy(&data, buf + len - pad, pad); diff --git a/drivers/spi/npcm_pspi.c b/drivers/spi/npcm_pspi.c index 37bab709672..eb14185273e 100644 --- a/drivers/spi/npcm_pspi.c +++ b/drivers/spi/npcm_pspi.c @@ -144,7 +144,7 @@ static int npcm_pspi_set_speed(struct udevice *bus, uint speed) if (speed > priv->max_hz) speed = priv->max_hz; - divisor = DIV_ROUND_CLOSEST(apb_clock, (2 * speed) - 1); + divisor = DIV_ROUND_CLOSEST(apb_clock, (2 * speed)) - 1; if (divisor > MAX_DIV) divisor = MAX_DIV; diff --git a/drivers/spi/spi-mem-nodm.c b/drivers/spi/spi-mem-nodm.c index 6ee841358b3..6d9ab61769a 100644 --- a/drivers/spi/spi-mem-nodm.c +++ b/drivers/spi/spi-mem-nodm.c @@ -3,6 +3,7 @@ * Copyright (C) 2018 Texas Instruments Incorporated - https://www.ti.com/ */ +#include <errno.h> #include <log.h> #include <malloc.h> #include <spi.h> diff --git a/drivers/spi/xilinx_spi.c b/drivers/spi/xilinx_spi.c index b58a3f632a4..94ddf4967ea 100644 --- a/drivers/spi/xilinx_spi.c +++ b/drivers/spi/xilinx_spi.c @@ -67,7 +67,7 @@ /* SPI Slave Select Register (spissr), [1] p13, [2] p13 */ #define SPISSR_MASK(cs) (1 << (cs)) #define SPISSR_ACT(cs) ~SPISSR_MASK(cs) -#define SPISSR_OFF ~0UL +#define SPISSR_OFF (~0U) /* SPI Software Reset Register (ssr) */ #define SPISSR_RESET_VALUE 0x0a @@ -109,6 +109,27 @@ struct xilinx_spi_priv { u8 startup; }; +static int xilinx_spi_find_buffer_size(struct xilinx_spi_regs *regs) +{ + u8 sr; + int n_words = 0; + + /* + * Before the buffer_size detection reset the core + * to make sure to start with a clean state. + */ + writel(SPISSR_RESET_VALUE, ®s->srr); + + /* Fill the Tx FIFO with as many words as possible */ + do { + writel(0, ®s->spidtr); + sr = readl(®s->spisr); + n_words++; + } while (!(sr & SPISR_TX_FULL)); + + return n_words; +} + static int xilinx_spi_probe(struct udevice *bus) { struct xilinx_spi_priv *priv = dev_get_priv(bus); @@ -116,6 +137,8 @@ static int xilinx_spi_probe(struct udevice *bus) regs = priv->regs = dev_read_addr_ptr(bus); priv->fifo_depth = dev_read_u32_default(bus, "fifo-size", 0); + if (!priv->fifo_depth) + priv->fifo_depth = xilinx_spi_find_buffer_size(regs); writel(SPISSR_RESET_VALUE, ®s->srr); @@ -217,9 +240,9 @@ static u32 xilinx_spi_read_rxfifo(struct udevice *bus, u8 *rxp, u32 rxbytes) return i; } -static int start_transfer(struct spi_slave *spi, const void *dout, void *din, u32 len) +static int start_transfer(struct udevice *dev, const void *dout, void *din, u32 len) { - struct udevice *bus = spi->dev->parent; + struct udevice *bus = dev->parent; struct xilinx_spi_priv *priv = dev_get_priv(bus); struct xilinx_spi_regs *regs = priv->regs; u32 count, txbytes, rxbytes; @@ -259,10 +282,9 @@ static int start_transfer(struct spi_slave *spi, const void *dout, void *din, u3 return 0; } -static void xilinx_spi_startup_block(struct spi_slave *spi) +static void xilinx_spi_startup_block(struct udevice *dev) { - struct dm_spi_slave_plat *slave_plat = - dev_get_parent_plat(spi->dev); + struct dm_spi_slave_plat *slave_plat = dev_get_parent_plat(dev); unsigned char txp; unsigned char rxp[8]; @@ -270,13 +292,25 @@ static void xilinx_spi_startup_block(struct spi_slave *spi) * Perform a dummy read as a work around for * the startup block issue. */ - spi_cs_activate(spi->dev, slave_plat->cs); + spi_cs_activate(dev, slave_plat->cs); txp = 0x9f; - start_transfer(spi, (void *)&txp, NULL, 1); + start_transfer(dev, (void *)&txp, NULL, 1); - start_transfer(spi, NULL, (void *)rxp, 6); + start_transfer(dev, NULL, (void *)rxp, 6); - spi_cs_deactivate(spi->dev); + spi_cs_deactivate(dev); +} + +static int xilinx_spi_xfer(struct udevice *dev, unsigned int bitlen, + const void *dout, void *din, unsigned long flags) +{ + struct dm_spi_slave_plat *slave_plat = dev_get_parent_plat(dev); + int ret; + + spi_cs_activate(dev, slave_plat->cs); + ret = start_transfer(dev, dout, din, bitlen / 8); + spi_cs_deactivate(dev); + return ret; } static int xilinx_spi_mem_exec_op(struct spi_slave *spi, @@ -294,14 +328,15 @@ static int xilinx_spi_mem_exec_op(struct spi_slave *spi, * as QSPI provides command. So first command fails. */ if (!startup) { - xilinx_spi_startup_block(spi); + xilinx_spi_startup_block(spi->dev); startup++; } spi_cs_activate(spi->dev, slave_plat->cs); if (op->cmd.opcode) { - ret = start_transfer(spi, (void *)&op->cmd.opcode, NULL, 1); + ret = start_transfer(spi->dev, (void *)&op->cmd.opcode, + NULL, 1); if (ret) goto done; } @@ -313,7 +348,7 @@ static int xilinx_spi_mem_exec_op(struct spi_slave *spi, addr_buf[i] = op->addr.val >> (8 * (op->addr.nbytes - i - 1)); - ret = start_transfer(spi, (void *)addr_buf, NULL, + ret = start_transfer(spi->dev, (void *)addr_buf, NULL, op->addr.nbytes); if (ret) goto done; @@ -322,16 +357,16 @@ static int xilinx_spi_mem_exec_op(struct spi_slave *spi, dummy_len = (op->dummy.nbytes * op->data.buswidth) / op->dummy.buswidth; - ret = start_transfer(spi, NULL, NULL, dummy_len); + ret = start_transfer(spi->dev, NULL, NULL, dummy_len); if (ret) goto done; } if (op->data.nbytes) { if (op->data.dir == SPI_MEM_DATA_IN) { - ret = start_transfer(spi, NULL, + ret = start_transfer(spi->dev, NULL, op->data.buf.in, op->data.nbytes); } else { - ret = start_transfer(spi, op->data.buf.out, + ret = start_transfer(spi->dev, op->data.buf.out, NULL, op->data.nbytes); } if (ret) @@ -427,6 +462,7 @@ static const struct spi_controller_mem_ops xilinx_spi_mem_ops = { static const struct dm_spi_ops xilinx_spi_ops = { .claim_bus = xilinx_spi_claim_bus, .release_bus = xilinx_spi_release_bus, + .xfer = xilinx_spi_xfer, .set_speed = xilinx_spi_set_speed, .set_mode = xilinx_spi_set_mode, .mem_ops = &xilinx_spi_mem_ops, |