diff mbox series

[U-Boot,2/3] mtd: spi: add MSCC SPI flash driver

Message ID 1547640475-26939-3-git-send-email-horatiu.vultur@microchip.com
State Deferred
Delegated to: Daniel Schwierzeck
Headers show
Series mtd: spi: Add MSCC SPI flash driver | expand

Commit Message

Horatiu Vultur Jan. 16, 2019, 12:07 p.m. UTC
The VCore III SoCs can directly access flash through memory. The SPI
controller takes care of changing a memory access to a flash access.
Therefore the flash can be accessed using memcpy functions.

The direct mapping is supported only by the read functions. All the
other access are going through the SPI driver.

Using this driver improves the read throughput by a factor of 4.75.

Cc: Jagan Teki <jagan@amarulasolutions.com>
Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
---
 MAINTAINERS                     |  1 +
 drivers/mtd/spi/Kconfig         |  8 +++++
 drivers/mtd/spi/Makefile        |  1 +
 drivers/mtd/spi/sf_mscc_flash.c | 76 +++++++++++++++++++++++++++++++++++++++++
 4 files changed, 86 insertions(+)
 create mode 100644 drivers/mtd/spi/sf_mscc_flash.c
diff mbox series

Patch

diff --git a/MAINTAINERS b/MAINTAINERS
index 3fa5d3e..a2b100e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -527,6 +527,7 @@  F:	board/mscc/
 F:	configs/mscc*
 F:	drivers/gpio/mscc_sgpio.c
 F:	drivers/spi/mscc_bb_spi.c
+F:	drivers/mtd/spi/sf_mscc_flash.c
 F:	include/configs/vcoreiii.h
 F:	drivers/pinctrl/mscc/
 
diff --git a/drivers/mtd/spi/Kconfig b/drivers/mtd/spi/Kconfig
index 76d5a1d..0f8db82 100644
--- a/drivers/mtd/spi/Kconfig
+++ b/drivers/mtd/spi/Kconfig
@@ -34,6 +34,14 @@  config SPI_FLASH
 
 	  If unsure, say N
 
+config MSCC_SPI_FLASH
+	bool "MSCC SPI Flash driver"
+	depends on SPI_FLASH
+	help
+	  Enable MSCC SPI flash driver. This driver uses direct mapping
+	  during read operations, regular SPI transfer otherwise. It is
+	  using CONFIG_SPI_FLASH_BAR to access high end of +16MB flash.
+
 config SPI_FLASH_BAR
 	bool "SPI flash Bank/Extended address register support"
 	depends on SPI_FLASH
diff --git a/drivers/mtd/spi/Makefile b/drivers/mtd/spi/Makefile
index b4c7e1c..3ae1860 100644
--- a/drivers/mtd/spi/Makefile
+++ b/drivers/mtd/spi/Makefile
@@ -10,6 +10,7 @@  obj-$(CONFIG_SPL_SPI_BOOT)	+= fsl_espi_spl.o
 endif
 
 obj-$(CONFIG_SPI_FLASH) += sf_probe.o spi_flash.o spi_flash_ids.o sf.o
+obj-$(CONFIG_MSCC_SPI_FLASH) += sf_mscc_flash.o
 obj-$(CONFIG_SPI_FLASH_DATAFLASH) += sf_dataflash.o
 obj-$(CONFIG_SPI_FLASH_MTD) += sf_mtd.o
 obj-$(CONFIG_SPI_FLASH_SANDBOX) += sandbox.o
diff --git a/drivers/mtd/spi/sf_mscc_flash.c b/drivers/mtd/spi/sf_mscc_flash.c
new file mode 100644
index 0000000..4a5376b
--- /dev/null
+++ b/drivers/mtd/spi/sf_mscc_flash.c
@@ -0,0 +1,76 @@ 
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2018 Microsemi Corporation
+ */
+
+#include <common.h>
+#include <spi.h>
+#include <spi_flash.h>
+
+#include "sf_internal.h"
+
+#define MSCC_FLASH_MASK GENMASK(24, 0)
+
+static int mscc_spi_flash_read(struct udevice *dev, u32 offset, size_t len,
+			       void *data)
+{
+	struct spi_flash *flash = dev_get_uclass_priv(dev);
+	struct spi_slave *spi = flash->spi;
+	u32 remain_len, read_len, read_addr;
+	int bank_sel = 0;
+	int ret = -1;
+
+	while (len) {
+		read_addr = offset;
+
+#ifdef CONFIG_SPI_FLASH_BAR
+		ret = write_bar(flash, read_addr);
+		if (ret < 0)
+			return ret;
+		bank_sel = flash->bank_curr;
+#endif
+		remain_len = ((SPI_FLASH_16MB_BOUN << flash->shift) *
+				(bank_sel + 1)) - offset;
+		if (len < remain_len)
+			read_len = len;
+		else
+			read_len = remain_len;
+
+		if (spi->max_read_size)
+			read_len = min(read_len, spi->max_read_size);
+
+		memcpy(data,
+		       flash->memory_map + (read_addr & MSCC_FLASH_MASK),
+		       read_len);
+
+		offset += read_len;
+		len -= read_len;
+		data += read_len;
+	}
+
+#ifdef CONFIG_SPI_FLASH_BAR
+	ret = clean_bar(flash);
+#endif
+
+	return ret;
+}
+
+static const struct dm_spi_flash_ops mscc_spi_flash_ops = {
+	.read = mscc_spi_flash_read,
+	.write = spi_flash_std_write,
+	.erase = spi_flash_std_erase,
+};
+
+static const struct udevice_id mscc_spi_flash_ids[] = {
+	{ .compatible = "mscc,luton-spi-flash" },
+	{ }
+};
+
+U_BOOT_DRIVER(sf_mscc_flash) = {
+	.name		= "sf_mscc_flash",
+	.id		= UCLASS_SPI_FLASH,
+	.of_match	= mscc_spi_flash_ids,
+	.probe		= spi_flash_std_probe,
+	.priv_auto_alloc_size = sizeof(struct spi_flash),
+	.ops		= &mscc_spi_flash_ops,
+};