123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157 |
- From a7b221d8f0d75511c5f959584712a5dd35f88a86 Mon Sep 17 00:00:00 2001
- From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
- Date: Mon, 18 Apr 2016 14:39:30 +0200
- Subject: [PATCH] spi: bcm53xx: add spi_flash_read callback for MMIO-based
- reads
- MIME-Version: 1.0
- Content-Type: text/plain; charset=UTF-8
- Content-Transfer-Encoding: 8bit
- This implements more efficient reads of SPI-attached flash content.
- Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
- Signed-off-by: Mark Brown <broonie@kernel.org>
- ---
- --- a/drivers/spi/spi-bcm53xx.c
- +++ b/drivers/spi/spi-bcm53xx.c
- @@ -10,6 +10,7 @@
- #include "spi-bcm53xx.h"
-
- #define BCM53XXSPI_MAX_SPI_BAUD 13500000 /* 216 MHz? */
- +#define BCM53XXSPI_FLASH_WINDOW SZ_32M
-
- /* The longest observed required wait was 19 ms */
- #define BCM53XXSPI_SPE_TIMEOUT_MS 80
- @@ -17,8 +18,10 @@
- struct bcm53xxspi {
- struct bcma_device *core;
- struct spi_master *master;
- + void __iomem *mmio_base;
-
- size_t read_offset;
- + bool bspi; /* Boot SPI mode with memory mapping */
- };
-
- static inline u32 bcm53xxspi_read(struct bcm53xxspi *b53spi, u16 offset)
- @@ -32,6 +35,50 @@ static inline void bcm53xxspi_write(stru
- bcma_write32(b53spi->core, offset, value);
- }
-
- +static void bcm53xxspi_disable_bspi(struct bcm53xxspi *b53spi)
- +{
- + struct device *dev = &b53spi->core->dev;
- + unsigned long deadline;
- + u32 tmp;
- +
- + if (!b53spi->bspi)
- + return;
- +
- + tmp = bcm53xxspi_read(b53spi, B53SPI_BSPI_MAST_N_BOOT_CTRL);
- + if (tmp & 0x1)
- + return;
- +
- + deadline = jiffies + usecs_to_jiffies(200);
- + do {
- + tmp = bcm53xxspi_read(b53spi, B53SPI_BSPI_BUSY_STATUS);
- + if (!(tmp & 0x1)) {
- + bcm53xxspi_write(b53spi, B53SPI_BSPI_MAST_N_BOOT_CTRL,
- + 0x1);
- + ndelay(200);
- + b53spi->bspi = false;
- + return;
- + }
- + udelay(1);
- + } while (!time_after_eq(jiffies, deadline));
- +
- + dev_warn(dev, "Timeout disabling BSPI\n");
- +}
- +
- +static void bcm53xxspi_enable_bspi(struct bcm53xxspi *b53spi)
- +{
- + u32 tmp;
- +
- + if (b53spi->bspi)
- + return;
- +
- + tmp = bcm53xxspi_read(b53spi, B53SPI_BSPI_MAST_N_BOOT_CTRL);
- + if (!(tmp & 0x1))
- + return;
- +
- + bcm53xxspi_write(b53spi, B53SPI_BSPI_MAST_N_BOOT_CTRL, 0x0);
- + b53spi->bspi = true;
- +}
- +
- static inline unsigned int bcm53xxspi_calc_timeout(size_t len)
- {
- /* Do some magic calculation based on length and buad. Add 10% and 1. */
- @@ -176,6 +223,8 @@ static int bcm53xxspi_transfer_one(struc
- u8 *buf;
- size_t left;
-
- + bcm53xxspi_disable_bspi(b53spi);
- +
- if (t->tx_buf) {
- buf = (u8 *)t->tx_buf;
- left = t->len;
- @@ -206,6 +255,22 @@ static int bcm53xxspi_transfer_one(struc
- return 0;
- }
-
- +static int bcm53xxspi_flash_read(struct spi_device *spi,
- + struct spi_flash_read_message *msg)
- +{
- + struct bcm53xxspi *b53spi = spi_master_get_devdata(spi->master);
- + int ret = 0;
- +
- + if (msg->from + msg->len > BCM53XXSPI_FLASH_WINDOW)
- + return -EINVAL;
- +
- + bcm53xxspi_enable_bspi(b53spi);
- + memcpy_fromio(msg->buf, b53spi->mmio_base + msg->from, msg->len);
- + msg->retlen = msg->len;
- +
- + return ret;
- +}
- +
- /**************************************************
- * BCMA
- **************************************************/
- @@ -222,6 +287,7 @@ MODULE_DEVICE_TABLE(bcma, bcm53xxspi_bcm
-
- static int bcm53xxspi_bcma_probe(struct bcma_device *core)
- {
- + struct device *dev = &core->dev;
- struct bcm53xxspi *b53spi;
- struct spi_master *master;
- int err;
- @@ -231,7 +297,7 @@ static int bcm53xxspi_bcma_probe(struct
- return -ENOTSUPP;
- }
-
- - master = spi_alloc_master(&core->dev, sizeof(*b53spi));
- + master = spi_alloc_master(dev, sizeof(*b53spi));
- if (!master)
- return -ENOMEM;
-
- @@ -239,11 +305,19 @@ static int bcm53xxspi_bcma_probe(struct
- b53spi->master = master;
- b53spi->core = core;
-
- + if (core->addr_s[0])
- + b53spi->mmio_base = devm_ioremap(dev, core->addr_s[0],
- + BCM53XXSPI_FLASH_WINDOW);
- + b53spi->bspi = true;
- + bcm53xxspi_disable_bspi(b53spi);
- +
- master->transfer_one = bcm53xxspi_transfer_one;
- + if (b53spi->mmio_base)
- + master->spi_flash_read = bcm53xxspi_flash_read;
-
- bcma_set_drvdata(core, b53spi);
-
- - err = devm_spi_register_master(&core->dev, master);
- + err = devm_spi_register_master(dev, master);
- if (err) {
- spi_master_put(master);
- bcma_set_drvdata(core, NULL);
|