Loading drivers/spi/spi-bcm2835.c +29 −9 Original line number Diff line number Diff line Loading @@ -480,7 +480,7 @@ static int bcm2835_spi_transfer_one_poll(struct spi_master *master, struct spi_device *spi, struct spi_transfer *tfr, u32 cs, unsigned long xfer_time_us) unsigned long long xfer_time_us) { struct bcm2835_spi *bs = spi_master_get_devdata(master); unsigned long timeout; Loading Loading @@ -531,7 +531,8 @@ static int bcm2835_spi_transfer_one(struct spi_master *master, { struct bcm2835_spi *bs = spi_master_get_devdata(master); unsigned long spi_hz, clk_hz, cdiv; unsigned long spi_used_hz, xfer_time_us; unsigned long spi_used_hz; unsigned long long xfer_time_us; u32 cs = bcm2835_rd(bs, BCM2835_SPI_CS); /* set clock */ Loading @@ -553,13 +554,11 @@ static int bcm2835_spi_transfer_one(struct spi_master *master, spi_used_hz = cdiv ? (clk_hz / cdiv) : (clk_hz / 65536); bcm2835_wr(bs, BCM2835_SPI_CLK, cdiv); /* handle all the modes */ /* handle all the 3-wire mode */ if ((spi->mode & SPI_3WIRE) && (tfr->rx_buf)) cs |= BCM2835_SPI_CS_REN; if (spi->mode & SPI_CPOL) cs |= BCM2835_SPI_CS_CPOL; if (spi->mode & SPI_CPHA) cs |= BCM2835_SPI_CS_CPHA; else cs &= ~BCM2835_SPI_CS_REN; /* for gpio_cs set dummy CS so that no HW-CS get changed * we can not run this in bcm2835_spi_set_cs, as it does Loading @@ -575,9 +574,10 @@ static int bcm2835_spi_transfer_one(struct spi_master *master, bs->rx_len = tfr->len; /* calculate the estimated time in us the transfer runs */ xfer_time_us = tfr->len xfer_time_us = (unsigned long long)tfr->len * 9 /* clocks/byte - SPI-HW waits 1 clock after each byte */ * 1000000 / spi_used_hz; * 1000000; do_div(xfer_time_us, spi_used_hz); /* for short requests run polling*/ if (xfer_time_us <= BCM2835_SPI_POLLING_LIMIT_US) Loading @@ -592,6 +592,25 @@ static int bcm2835_spi_transfer_one(struct spi_master *master, return bcm2835_spi_transfer_one_irq(master, spi, tfr, cs); } static int bcm2835_spi_prepare_message(struct spi_master *master, struct spi_message *msg) { struct spi_device *spi = msg->spi; struct bcm2835_spi *bs = spi_master_get_devdata(master); u32 cs = bcm2835_rd(bs, BCM2835_SPI_CS); cs &= ~(BCM2835_SPI_CS_CPOL | BCM2835_SPI_CS_CPHA); if (spi->mode & SPI_CPOL) cs |= BCM2835_SPI_CS_CPOL; if (spi->mode & SPI_CPHA) cs |= BCM2835_SPI_CS_CPHA; bcm2835_wr(bs, BCM2835_SPI_CS, cs); return 0; } static void bcm2835_spi_handle_err(struct spi_master *master, struct spi_message *msg) { Loading Loading @@ -739,6 +758,7 @@ static int bcm2835_spi_probe(struct platform_device *pdev) master->set_cs = bcm2835_spi_set_cs; master->transfer_one = bcm2835_spi_transfer_one; master->handle_err = bcm2835_spi_handle_err; master->prepare_message = bcm2835_spi_prepare_message; master->dev.of_node = pdev->dev.of_node; bs = spi_master_get_devdata(master); Loading drivers/spi/spi-bitbang-txrx.h +2 −2 Original line number Diff line number Diff line Loading @@ -49,7 +49,7 @@ bitbang_txrx_be_cpha0(struct spi_device *spi, { /* if (cpol == 0) this is SPI_MODE_0; else this is SPI_MODE_2 */ bool oldbit = !(word & 1); u32 oldbit = (!(word & (1<<(bits-1)))) << 31; /* clock starts at inactive polarity */ for (word <<= (32 - bits); likely(bits); bits--) { Loading Loading @@ -81,7 +81,7 @@ bitbang_txrx_be_cpha1(struct spi_device *spi, { /* if (cpol == 0) this is SPI_MODE_1; else this is SPI_MODE_3 */ bool oldbit = !(word & (1 << 31)); u32 oldbit = (!(word & (1<<(bits-1)))) << 31; /* clock starts at inactive polarity */ for (word <<= (32 - bits); likely(bits); bits--) { Loading drivers/spi/spi-img-spfi.c +46 −13 Original line number Diff line number Diff line Loading @@ -105,6 +105,10 @@ struct img_spfi { bool rx_dma_busy; }; struct img_spfi_device_data { bool gpio_requested; }; static inline u32 spfi_readl(struct img_spfi *spfi, u32 reg) { return readl(spfi->regs + reg); Loading Loading @@ -267,15 +271,15 @@ static int img_spfi_start_pio(struct spi_master *master, cpu_relax(); } ret = spfi_wait_all_done(spfi); if (ret < 0) return ret; if (rx_bytes > 0 || tx_bytes > 0) { dev_err(spfi->dev, "PIO transfer timed out\n"); return -ETIMEDOUT; } ret = spfi_wait_all_done(spfi); if (ret < 0) return ret; return 0; } Loading Loading @@ -440,21 +444,50 @@ static int img_spfi_unprepare(struct spi_master *master, static int img_spfi_setup(struct spi_device *spi) { int ret; int ret = -EINVAL; struct img_spfi_device_data *spfi_data = spi_get_ctldata(spi); ret = gpio_request_one(spi->cs_gpio, (spi->mode & SPI_CS_HIGH) ? if (!spfi_data) { spfi_data = kzalloc(sizeof(*spfi_data), GFP_KERNEL); if (!spfi_data) return -ENOMEM; spfi_data->gpio_requested = false; spi_set_ctldata(spi, spfi_data); } if (!spfi_data->gpio_requested) { ret = gpio_request_one(spi->cs_gpio, (spi->mode & SPI_CS_HIGH) ? GPIOF_OUT_INIT_LOW : GPIOF_OUT_INIT_HIGH, dev_name(&spi->dev)); if (ret) dev_err(&spi->dev, "can't request chipselect gpio %d\n", spi->cs_gpio); else spfi_data->gpio_requested = true; } else { if (gpio_is_valid(spi->cs_gpio)) { int mode = ((spi->mode & SPI_CS_HIGH) ? GPIOF_OUT_INIT_LOW : GPIOF_OUT_INIT_HIGH); ret = gpio_direction_output(spi->cs_gpio, mode); if (ret) dev_err(&spi->dev, "chipselect gpio %d setup failed (%d)\n", spi->cs_gpio, ret); } } return ret; } static void img_spfi_cleanup(struct spi_device *spi) { struct img_spfi_device_data *spfi_data = spi_get_ctldata(spi); if (spfi_data) { if (spfi_data->gpio_requested) gpio_free(spi->cs_gpio); kfree(spfi_data); spi_set_ctldata(spi, NULL); } } static void img_spfi_config(struct spi_master *master, struct spi_device *spi, Loading drivers/spi/spi-omap2-mcspi.c +10 −0 Original line number Diff line number Diff line Loading @@ -245,6 +245,7 @@ static void omap2_mcspi_set_enable(const struct spi_device *spi, int enable) static void omap2_mcspi_set_cs(struct spi_device *spi, bool enable) { struct omap2_mcspi *mcspi = spi_master_get_devdata(spi->master); u32 l; /* The controller handles the inverted chip selects Loading @@ -255,6 +256,12 @@ static void omap2_mcspi_set_cs(struct spi_device *spi, bool enable) enable = !enable; if (spi->controller_state) { int err = pm_runtime_get_sync(mcspi->dev); if (err < 0) { dev_err(mcspi->dev, "failed to get sync: %d\n", err); return; } l = mcspi_cached_chconf0(spi); if (enable) Loading @@ -263,6 +270,9 @@ static void omap2_mcspi_set_cs(struct spi_device *spi, bool enable) l |= OMAP2_MCSPI_CHCONF_FORCE; mcspi_write_chconf0(spi, l); pm_runtime_mark_last_busy(mcspi->dev); pm_runtime_put_autosuspend(mcspi->dev); } } Loading drivers/spi/spi-orion.c +53 −1 Original line number Diff line number Diff line Loading @@ -41,6 +41,11 @@ #define ORION_SPI_DATA_OUT_REG 0x08 #define ORION_SPI_DATA_IN_REG 0x0c #define ORION_SPI_INT_CAUSE_REG 0x10 #define ORION_SPI_TIMING_PARAMS_REG 0x18 #define ORION_SPI_TMISO_SAMPLE_MASK (0x3 << 6) #define ORION_SPI_TMISO_SAMPLE_1 (1 << 6) #define ORION_SPI_TMISO_SAMPLE_2 (2 << 6) #define ORION_SPI_MODE_CPOL (1 << 11) #define ORION_SPI_MODE_CPHA (1 << 12) Loading Loading @@ -70,6 +75,7 @@ struct orion_spi_dev { unsigned int min_divisor; unsigned int max_divisor; u32 prescale_mask; bool is_errata_50mhz_ac; }; struct orion_spi { Loading Loading @@ -195,6 +201,41 @@ orion_spi_mode_set(struct spi_device *spi) writel(reg, spi_reg(orion_spi, ORION_SPI_IF_CONFIG_REG)); } static void orion_spi_50mhz_ac_timing_erratum(struct spi_device *spi, unsigned int speed) { u32 reg; struct orion_spi *orion_spi; orion_spi = spi_master_get_devdata(spi->master); /* * Erratum description: (Erratum NO. FE-9144572) The device * SPI interface supports frequencies of up to 50 MHz. * However, due to this erratum, when the device core clock is * 250 MHz and the SPI interfaces is configured for 50MHz SPI * clock and CPOL=CPHA=1 there might occur data corruption on * reads from the SPI device. * Erratum Workaround: * Work in one of the following configurations: * 1. Set CPOL=CPHA=0 in "SPI Interface Configuration * Register". * 2. Set TMISO_SAMPLE value to 0x2 in "SPI Timing Parameters 1 * Register" before setting the interface. */ reg = readl(spi_reg(orion_spi, ORION_SPI_TIMING_PARAMS_REG)); reg &= ~ORION_SPI_TMISO_SAMPLE_MASK; if (clk_get_rate(orion_spi->clk) == 250000000 && speed == 50000000 && spi->mode & SPI_CPOL && spi->mode & SPI_CPHA) reg |= ORION_SPI_TMISO_SAMPLE_2; else reg |= ORION_SPI_TMISO_SAMPLE_1; /* This is the default value */ writel(reg, spi_reg(orion_spi, ORION_SPI_TIMING_PARAMS_REG)); } /* * called only when no transfer is active on the bus */ Loading @@ -216,6 +257,9 @@ orion_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t) orion_spi_mode_set(spi); if (orion_spi->devdata->is_errata_50mhz_ac) orion_spi_50mhz_ac_timing_erratum(spi, speed); rc = orion_spi_baudrate_set(spi, speed); if (rc) return rc; Loading Loading @@ -413,6 +457,14 @@ static const struct orion_spi_dev armada_375_spi_dev_data = { .prescale_mask = ARMADA_SPI_CLK_PRESCALE_MASK, }; static const struct orion_spi_dev armada_380_spi_dev_data = { .typ = ARMADA_SPI, .max_hz = 50000000, .max_divisor = 1920, .prescale_mask = ARMADA_SPI_CLK_PRESCALE_MASK, .is_errata_50mhz_ac = true, }; static const struct of_device_id orion_spi_of_match_table[] = { { .compatible = "marvell,orion-spi", Loading @@ -428,7 +480,7 @@ static const struct of_device_id orion_spi_of_match_table[] = { }, { .compatible = "marvell,armada-380-spi", .data = &armada_xp_spi_dev_data, .data = &armada_380_spi_dev_data, }, { .compatible = "marvell,armada-390-spi", Loading Loading
drivers/spi/spi-bcm2835.c +29 −9 Original line number Diff line number Diff line Loading @@ -480,7 +480,7 @@ static int bcm2835_spi_transfer_one_poll(struct spi_master *master, struct spi_device *spi, struct spi_transfer *tfr, u32 cs, unsigned long xfer_time_us) unsigned long long xfer_time_us) { struct bcm2835_spi *bs = spi_master_get_devdata(master); unsigned long timeout; Loading Loading @@ -531,7 +531,8 @@ static int bcm2835_spi_transfer_one(struct spi_master *master, { struct bcm2835_spi *bs = spi_master_get_devdata(master); unsigned long spi_hz, clk_hz, cdiv; unsigned long spi_used_hz, xfer_time_us; unsigned long spi_used_hz; unsigned long long xfer_time_us; u32 cs = bcm2835_rd(bs, BCM2835_SPI_CS); /* set clock */ Loading @@ -553,13 +554,11 @@ static int bcm2835_spi_transfer_one(struct spi_master *master, spi_used_hz = cdiv ? (clk_hz / cdiv) : (clk_hz / 65536); bcm2835_wr(bs, BCM2835_SPI_CLK, cdiv); /* handle all the modes */ /* handle all the 3-wire mode */ if ((spi->mode & SPI_3WIRE) && (tfr->rx_buf)) cs |= BCM2835_SPI_CS_REN; if (spi->mode & SPI_CPOL) cs |= BCM2835_SPI_CS_CPOL; if (spi->mode & SPI_CPHA) cs |= BCM2835_SPI_CS_CPHA; else cs &= ~BCM2835_SPI_CS_REN; /* for gpio_cs set dummy CS so that no HW-CS get changed * we can not run this in bcm2835_spi_set_cs, as it does Loading @@ -575,9 +574,10 @@ static int bcm2835_spi_transfer_one(struct spi_master *master, bs->rx_len = tfr->len; /* calculate the estimated time in us the transfer runs */ xfer_time_us = tfr->len xfer_time_us = (unsigned long long)tfr->len * 9 /* clocks/byte - SPI-HW waits 1 clock after each byte */ * 1000000 / spi_used_hz; * 1000000; do_div(xfer_time_us, spi_used_hz); /* for short requests run polling*/ if (xfer_time_us <= BCM2835_SPI_POLLING_LIMIT_US) Loading @@ -592,6 +592,25 @@ static int bcm2835_spi_transfer_one(struct spi_master *master, return bcm2835_spi_transfer_one_irq(master, spi, tfr, cs); } static int bcm2835_spi_prepare_message(struct spi_master *master, struct spi_message *msg) { struct spi_device *spi = msg->spi; struct bcm2835_spi *bs = spi_master_get_devdata(master); u32 cs = bcm2835_rd(bs, BCM2835_SPI_CS); cs &= ~(BCM2835_SPI_CS_CPOL | BCM2835_SPI_CS_CPHA); if (spi->mode & SPI_CPOL) cs |= BCM2835_SPI_CS_CPOL; if (spi->mode & SPI_CPHA) cs |= BCM2835_SPI_CS_CPHA; bcm2835_wr(bs, BCM2835_SPI_CS, cs); return 0; } static void bcm2835_spi_handle_err(struct spi_master *master, struct spi_message *msg) { Loading Loading @@ -739,6 +758,7 @@ static int bcm2835_spi_probe(struct platform_device *pdev) master->set_cs = bcm2835_spi_set_cs; master->transfer_one = bcm2835_spi_transfer_one; master->handle_err = bcm2835_spi_handle_err; master->prepare_message = bcm2835_spi_prepare_message; master->dev.of_node = pdev->dev.of_node; bs = spi_master_get_devdata(master); Loading
drivers/spi/spi-bitbang-txrx.h +2 −2 Original line number Diff line number Diff line Loading @@ -49,7 +49,7 @@ bitbang_txrx_be_cpha0(struct spi_device *spi, { /* if (cpol == 0) this is SPI_MODE_0; else this is SPI_MODE_2 */ bool oldbit = !(word & 1); u32 oldbit = (!(word & (1<<(bits-1)))) << 31; /* clock starts at inactive polarity */ for (word <<= (32 - bits); likely(bits); bits--) { Loading Loading @@ -81,7 +81,7 @@ bitbang_txrx_be_cpha1(struct spi_device *spi, { /* if (cpol == 0) this is SPI_MODE_1; else this is SPI_MODE_3 */ bool oldbit = !(word & (1 << 31)); u32 oldbit = (!(word & (1<<(bits-1)))) << 31; /* clock starts at inactive polarity */ for (word <<= (32 - bits); likely(bits); bits--) { Loading
drivers/spi/spi-img-spfi.c +46 −13 Original line number Diff line number Diff line Loading @@ -105,6 +105,10 @@ struct img_spfi { bool rx_dma_busy; }; struct img_spfi_device_data { bool gpio_requested; }; static inline u32 spfi_readl(struct img_spfi *spfi, u32 reg) { return readl(spfi->regs + reg); Loading Loading @@ -267,15 +271,15 @@ static int img_spfi_start_pio(struct spi_master *master, cpu_relax(); } ret = spfi_wait_all_done(spfi); if (ret < 0) return ret; if (rx_bytes > 0 || tx_bytes > 0) { dev_err(spfi->dev, "PIO transfer timed out\n"); return -ETIMEDOUT; } ret = spfi_wait_all_done(spfi); if (ret < 0) return ret; return 0; } Loading Loading @@ -440,21 +444,50 @@ static int img_spfi_unprepare(struct spi_master *master, static int img_spfi_setup(struct spi_device *spi) { int ret; int ret = -EINVAL; struct img_spfi_device_data *spfi_data = spi_get_ctldata(spi); ret = gpio_request_one(spi->cs_gpio, (spi->mode & SPI_CS_HIGH) ? if (!spfi_data) { spfi_data = kzalloc(sizeof(*spfi_data), GFP_KERNEL); if (!spfi_data) return -ENOMEM; spfi_data->gpio_requested = false; spi_set_ctldata(spi, spfi_data); } if (!spfi_data->gpio_requested) { ret = gpio_request_one(spi->cs_gpio, (spi->mode & SPI_CS_HIGH) ? GPIOF_OUT_INIT_LOW : GPIOF_OUT_INIT_HIGH, dev_name(&spi->dev)); if (ret) dev_err(&spi->dev, "can't request chipselect gpio %d\n", spi->cs_gpio); else spfi_data->gpio_requested = true; } else { if (gpio_is_valid(spi->cs_gpio)) { int mode = ((spi->mode & SPI_CS_HIGH) ? GPIOF_OUT_INIT_LOW : GPIOF_OUT_INIT_HIGH); ret = gpio_direction_output(spi->cs_gpio, mode); if (ret) dev_err(&spi->dev, "chipselect gpio %d setup failed (%d)\n", spi->cs_gpio, ret); } } return ret; } static void img_spfi_cleanup(struct spi_device *spi) { struct img_spfi_device_data *spfi_data = spi_get_ctldata(spi); if (spfi_data) { if (spfi_data->gpio_requested) gpio_free(spi->cs_gpio); kfree(spfi_data); spi_set_ctldata(spi, NULL); } } static void img_spfi_config(struct spi_master *master, struct spi_device *spi, Loading
drivers/spi/spi-omap2-mcspi.c +10 −0 Original line number Diff line number Diff line Loading @@ -245,6 +245,7 @@ static void omap2_mcspi_set_enable(const struct spi_device *spi, int enable) static void omap2_mcspi_set_cs(struct spi_device *spi, bool enable) { struct omap2_mcspi *mcspi = spi_master_get_devdata(spi->master); u32 l; /* The controller handles the inverted chip selects Loading @@ -255,6 +256,12 @@ static void omap2_mcspi_set_cs(struct spi_device *spi, bool enable) enable = !enable; if (spi->controller_state) { int err = pm_runtime_get_sync(mcspi->dev); if (err < 0) { dev_err(mcspi->dev, "failed to get sync: %d\n", err); return; } l = mcspi_cached_chconf0(spi); if (enable) Loading @@ -263,6 +270,9 @@ static void omap2_mcspi_set_cs(struct spi_device *spi, bool enable) l |= OMAP2_MCSPI_CHCONF_FORCE; mcspi_write_chconf0(spi, l); pm_runtime_mark_last_busy(mcspi->dev); pm_runtime_put_autosuspend(mcspi->dev); } } Loading
drivers/spi/spi-orion.c +53 −1 Original line number Diff line number Diff line Loading @@ -41,6 +41,11 @@ #define ORION_SPI_DATA_OUT_REG 0x08 #define ORION_SPI_DATA_IN_REG 0x0c #define ORION_SPI_INT_CAUSE_REG 0x10 #define ORION_SPI_TIMING_PARAMS_REG 0x18 #define ORION_SPI_TMISO_SAMPLE_MASK (0x3 << 6) #define ORION_SPI_TMISO_SAMPLE_1 (1 << 6) #define ORION_SPI_TMISO_SAMPLE_2 (2 << 6) #define ORION_SPI_MODE_CPOL (1 << 11) #define ORION_SPI_MODE_CPHA (1 << 12) Loading Loading @@ -70,6 +75,7 @@ struct orion_spi_dev { unsigned int min_divisor; unsigned int max_divisor; u32 prescale_mask; bool is_errata_50mhz_ac; }; struct orion_spi { Loading Loading @@ -195,6 +201,41 @@ orion_spi_mode_set(struct spi_device *spi) writel(reg, spi_reg(orion_spi, ORION_SPI_IF_CONFIG_REG)); } static void orion_spi_50mhz_ac_timing_erratum(struct spi_device *spi, unsigned int speed) { u32 reg; struct orion_spi *orion_spi; orion_spi = spi_master_get_devdata(spi->master); /* * Erratum description: (Erratum NO. FE-9144572) The device * SPI interface supports frequencies of up to 50 MHz. * However, due to this erratum, when the device core clock is * 250 MHz and the SPI interfaces is configured for 50MHz SPI * clock and CPOL=CPHA=1 there might occur data corruption on * reads from the SPI device. * Erratum Workaround: * Work in one of the following configurations: * 1. Set CPOL=CPHA=0 in "SPI Interface Configuration * Register". * 2. Set TMISO_SAMPLE value to 0x2 in "SPI Timing Parameters 1 * Register" before setting the interface. */ reg = readl(spi_reg(orion_spi, ORION_SPI_TIMING_PARAMS_REG)); reg &= ~ORION_SPI_TMISO_SAMPLE_MASK; if (clk_get_rate(orion_spi->clk) == 250000000 && speed == 50000000 && spi->mode & SPI_CPOL && spi->mode & SPI_CPHA) reg |= ORION_SPI_TMISO_SAMPLE_2; else reg |= ORION_SPI_TMISO_SAMPLE_1; /* This is the default value */ writel(reg, spi_reg(orion_spi, ORION_SPI_TIMING_PARAMS_REG)); } /* * called only when no transfer is active on the bus */ Loading @@ -216,6 +257,9 @@ orion_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t) orion_spi_mode_set(spi); if (orion_spi->devdata->is_errata_50mhz_ac) orion_spi_50mhz_ac_timing_erratum(spi, speed); rc = orion_spi_baudrate_set(spi, speed); if (rc) return rc; Loading Loading @@ -413,6 +457,14 @@ static const struct orion_spi_dev armada_375_spi_dev_data = { .prescale_mask = ARMADA_SPI_CLK_PRESCALE_MASK, }; static const struct orion_spi_dev armada_380_spi_dev_data = { .typ = ARMADA_SPI, .max_hz = 50000000, .max_divisor = 1920, .prescale_mask = ARMADA_SPI_CLK_PRESCALE_MASK, .is_errata_50mhz_ac = true, }; static const struct of_device_id orion_spi_of_match_table[] = { { .compatible = "marvell,orion-spi", Loading @@ -428,7 +480,7 @@ static const struct of_device_id orion_spi_of_match_table[] = { }, { .compatible = "marvell,armada-380-spi", .data = &armada_xp_spi_dev_data, .data = &armada_380_spi_dev_data, }, { .compatible = "marvell,armada-390-spi", Loading