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

Horatiu Vultur horatiu.vultur at microchip.com
Wed Jan 16 12:07:54 UTC 2019


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 at amarulasolutions.com>
Signed-off-by: Horatiu Vultur <horatiu.vultur at 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 --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,
+};
-- 
2.7.4



More information about the U-Boot mailing list