linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/10] mtd: st_spi_fsm: Add new device
@ 2013-11-14 14:22 Lee Jones
  2013-11-14 14:22 ` [PATCH 01/10] mtd: st_spi_fsm: Allocate resources and register with MTD framework Lee Jones
                   ` (9 more replies)
  0 siblings, 10 replies; 25+ messages in thread
From: Lee Jones @ 2013-11-14 14:22 UTC (permalink / raw)
  To: linux-arm-kernel

First stab at getting this thing Mainlined. It doesn't do a great deal
yet, but we are able to initialise the device and dynamically set it up
correctly based on an extracted JEDEC ID.

 arch/arm/boot/dts/stih416-b2105.dts    |  10 ++
 arch/arm/boot/dts/stih416-pinctrl.dtsi |  12 +++
 drivers/mtd/devices/Kconfig            |   7 ++
 drivers/mtd/devices/Makefile           |   1 +
 drivers/mtd/devices/st_spi_fsm.c       | 605 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 drivers/mtd/devices/st_spi_fsm.h       | 187 ++++++++++++++++++++++++++++++++
 6 files changed, 822 insertions(+)

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH 01/10] mtd: st_spi_fsm: Allocate resources and register with MTD framework
  2013-11-14 14:22 [PATCH 00/10] mtd: st_spi_fsm: Add new device Lee Jones
@ 2013-11-14 14:22 ` Lee Jones
  2013-11-14 14:22 ` [PATCH 02/10] mtd: st_spi_fsm: Supply all register address and bit logic defines Lee Jones
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 25+ messages in thread
From: Lee Jones @ 2013-11-14 14:22 UTC (permalink / raw)
  To: linux-arm-kernel

This is a new driver. It's used to communicate with a special type of
optimised Serial Flash Controller called the FSM. The FSM uses a subset
of the SPI protocol to communicate with supported NOR-Flash devices.

Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
 drivers/mtd/devices/Kconfig      |   7 +++
 drivers/mtd/devices/Makefile     |   1 +
 drivers/mtd/devices/st_spi_fsm.c | 119 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 127 insertions(+)
 create mode 100644 drivers/mtd/devices/st_spi_fsm.c

diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig
index 74ab4b7..d977281 100644
--- a/drivers/mtd/devices/Kconfig
+++ b/drivers/mtd/devices/Kconfig
@@ -217,6 +217,13 @@ config MTD_DOCG3
 	  M-Systems and now Sandisk. The support is very experimental,
 	  and doesn't give access to any write operations.
 
+config MTD_ST_SPI_FSM
+	tristate "ST Microelectronics SPI FSM Serial Flash Controller"
+	help
+	  This provides an MTD device driver for the ST Microelectronics
+	  SPI FSM Serial Flash Controller and support for a subset of
+	  connected Serial Flash devices.
+
 if MTD_DOCG3
 config BCH_CONST_M
 	default 14
diff --git a/drivers/mtd/devices/Makefile b/drivers/mtd/devices/Makefile
index d83bd73..c68868f 100644
--- a/drivers/mtd/devices/Makefile
+++ b/drivers/mtd/devices/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_MTD_NAND_OMAP_BCH)	+= elm.o
 obj-$(CONFIG_MTD_SPEAR_SMI)	+= spear_smi.o
 obj-$(CONFIG_MTD_SST25L)	+= sst25l.o
 obj-$(CONFIG_MTD_BCM47XXSFLASH)	+= bcm47xxsflash.o
+obj-$(CONFIG_MTD_ST_SPI_FSM)    += st_spi_fsm.o
 
 
 CFLAGS_docg3.o			+= -I$(src)
diff --git a/drivers/mtd/devices/st_spi_fsm.c b/drivers/mtd/devices/st_spi_fsm.c
new file mode 100644
index 0000000..689f059
--- /dev/null
+++ b/drivers/mtd/devices/st_spi_fsm.c
@@ -0,0 +1,119 @@
+/*
+ * st_spi_fsm.c	Support for ST Serial Flash Controller
+ *
+ * Author: Angus Clark <angus.clark@st.com>
+ *
+ * Copyright (C) 2010-2013 STicroelectronics Limited
+ *
+ * JEDEC probe based on drivers/mtd/devices/m25p80.c
+ *
+ * This code is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/of.h>
+
+#include <asm/io.h>
+
+#include "st_spi_fsm.h"
+
+struct stfsm {
+	struct device		*dev;
+	void __iomem		*base;
+	struct resource		*region;
+	struct mtd_info		mtd;
+	struct mutex		lock;
+};
+
+static int stfsm_probe(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct resource *res;
+	struct stfsm *fsm;
+
+	if (!np) {
+		dev_err(&pdev->dev, "No DT found\n");
+		return -EINVAL;
+	}
+
+	fsm = devm_kzalloc(&pdev->dev, sizeof(*fsm), GFP_KERNEL);
+	if (!fsm)
+		return -ENOMEM;
+
+	fsm->dev = &pdev->dev;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(&pdev->dev, "Resource not found\n");
+		return -ENODEV;
+	}
+
+	fsm->region = devm_request_mem_region(&pdev->dev, res->start,
+					      resource_size(res), pdev->name);
+	if (!fsm->region) {
+		dev_err(&pdev->dev,
+			"Failed to reserve memory region [0x%08x-0x%08x]\n",
+			res->start, res->end);
+		return -EBUSY;
+	}
+
+	fsm->base = devm_ioremap_nocache(&pdev->dev,
+					 res->start, resource_size(res));
+	if (!fsm->base) {
+		dev_err(&pdev->dev, "Failed to ioremap [0x%08x]\n", res->start);
+		return -EINVAL;
+	}
+
+	mutex_init(&fsm->lock);
+
+	platform_set_drvdata(pdev, fsm);
+
+	fsm->mtd.dev.parent   = &pdev->dev;
+	fsm->mtd.type         = MTD_NORFLASH;
+	fsm->mtd.writesize    = 4;
+	fsm->mtd.writebufsize = fsm->mtd.writesize;
+	fsm->mtd.flags        = MTD_CAP_NORFLASH;
+
+	return mtd_device_parse_register(&fsm->mtd, NULL, NULL, NULL, 0);
+}
+
+static int __exit stfsm_remove(struct platform_device *pdev)
+{
+	struct stfsm *fsm = platform_get_drvdata(pdev);
+	int err;
+
+	err = mtd_device_unregister(&fsm->mtd);
+	if (err)
+		return err;
+
+	return 0;
+}
+
+static struct of_device_id stfsm_match[] = {
+	{ .compatible = "st,spi-fsm", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, spi_fsm_match);
+
+static struct platform_driver stfsm_driver = {
+	.probe		= stfsm_probe,
+	.remove		= stfsm_remove,
+	.driver		= {
+		.name	= "st-spi-fsm",
+		.owner	= THIS_MODULE,
+		.of_match_table = stfsm_match,
+	},
+};
+module_platform_driver(stfsm_driver);
+
+MODULE_AUTHOR("Angus Clark <angus.clark@st.com>");
+MODULE_DESCRIPTION("ST SPI FSM driver");
+MODULE_LICENSE("GPL");
-- 
1.8.1.2

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 02/10] mtd: st_spi_fsm: Supply all register address and bit logic defines
  2013-11-14 14:22 [PATCH 00/10] mtd: st_spi_fsm: Add new device Lee Jones
  2013-11-14 14:22 ` [PATCH 01/10] mtd: st_spi_fsm: Allocate resources and register with MTD framework Lee Jones
@ 2013-11-14 14:22 ` Lee Jones
  2013-11-18  9:15   ` Linus Walleij
  2013-11-14 14:22 ` [PATCH 03/10] mtd: st_spi_fsm: Initialise and configure the FSM for normal working conditions Lee Jones
                   ` (7 subsequent siblings)
  9 siblings, 1 reply; 25+ messages in thread
From: Lee Jones @ 2013-11-14 14:22 UTC (permalink / raw)
  To: linux-arm-kernel

Here we provide the FSM's register addresses, register bit names/offsets
and some commands which will prove useful as we start bulk the FMS's
driver out with functionality.

Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
 drivers/mtd/devices/st_spi_fsm.h | 183 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 183 insertions(+)
 create mode 100644 drivers/mtd/devices/st_spi_fsm.h

diff --git a/drivers/mtd/devices/st_spi_fsm.h b/drivers/mtd/devices/st_spi_fsm.h
new file mode 100644
index 0000000..11ca33a
--- /dev/null
+++ b/drivers/mtd/devices/st_spi_fsm.h
@@ -0,0 +1,183 @@
+/*
+ * st_spi_fsm.c	Support for ST Serial Flash Controller
+ *
+ * Author: Angus Clark <angus.clark@st.com>
+ *
+ * Copyright (C) 2010-2013 STicroelectronics Limited
+ *
+ * JEDEC probe based on drivers/mtd/devices/m25p80.c
+ *
+ * This code is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef ST_SPI_FSM_H
+#define ST_SPI_FSM_H
+
+/*
+ * FSM SPI Controller Registers
+ */
+#define SPI_CLOCKDIV			0x0010
+#define SPI_MODESELECT			0x0018
+#define SPI_CONFIGDATA			0x0020
+#define SPI_STA_MODE_CHANGE		0x0028
+#define SPI_FAST_SEQ_TRANSFER_SIZE	0x0100
+#define SPI_FAST_SEQ_ADD1		0x0104
+#define SPI_FAST_SEQ_ADD2		0x0108
+#define SPI_FAST_SEQ_ADD_CFG		0x010c
+#define SPI_FAST_SEQ_OPC1		0x0110
+#define SPI_FAST_SEQ_OPC2		0x0114
+#define SPI_FAST_SEQ_OPC3		0x0118
+#define SPI_FAST_SEQ_OPC4		0x011c
+#define SPI_FAST_SEQ_OPC5		0x0120
+#define SPI_MODE_BITS			0x0124
+#define SPI_DUMMY_BITS			0x0128
+#define SPI_FAST_SEQ_FLASH_STA_DATA	0x012c
+#define SPI_FAST_SEQ_1			0x0130
+#define SPI_FAST_SEQ_2			0x0134
+#define SPI_FAST_SEQ_3			0x0138
+#define SPI_FAST_SEQ_4			0x013c
+#define SPI_FAST_SEQ_CFG		0x0140
+#define SPI_FAST_SEQ_STA		0x0144
+#define SPI_QUAD_BOOT_SEQ_INIT_1	0x0148
+#define SPI_QUAD_BOOT_SEQ_INIT_2	0x014c
+#define SPI_QUAD_BOOT_READ_SEQ_1	0x0150
+#define SPI_QUAD_BOOT_READ_SEQ_2	0x0154
+#define SPI_PROGRAM_ERASE_TIME		0x0158
+#define SPI_MULT_PAGE_REPEAT_SEQ_1	0x015c
+#define SPI_MULT_PAGE_REPEAT_SEQ_2	0x0160
+#define SPI_STATUS_WR_TIME_REG		0x0164
+#define SPI_FAST_SEQ_DATA_REG		0x0300
+
+/*
+ * Register: SPI_MODESELECT
+ */
+#define SPI_MODESELECT_CONTIG		0x01
+#define SPI_MODESELECT_FASTREAD		0x02
+#define SPI_MODESELECT_DUALIO		0x04
+#define SPI_MODESELECT_FSM		0x08
+#define SPI_MODESELECT_QUADBOOT		0x10
+
+/*
+ * Register: SPI_CONFIGDATA
+ */
+#define SPI_CFG_DEVICE_ST		0x1
+#define SPI_CFG_DEVICE_ATMEL		0x4
+#define SPI_CFG_MIN_CS_HIGH(x)		(((x) & 0xfff) << 4)
+#define SPI_CFG_CS_SETUPHOLD(x)		(((x) & 0xff) << 16)
+#define SPI_CFG_DATA_HOLD(x)		(((x) & 0xff) << 24)
+
+/*
+ * Register: SPI_FAST_SEQ_TRANSFER_SIZE
+ */
+#define TRANSFER_SIZE(x)		((x) * 8)
+
+/*
+ * Register: SPI_FAST_SEQ_ADD_CFG
+ */
+#define ADR_CFG_CYCLES_ADD1(x)		((x) << 0)
+#define ADR_CFG_PADS_1_ADD1		(0x0 << 6)
+#define ADR_CFG_PADS_2_ADD1		(0x1 << 6)
+#define ADR_CFG_PADS_4_ADD1		(0x3 << 6)
+#define ADR_CFG_CSDEASSERT_ADD1		(1   << 8)
+#define ADR_CFG_CYCLES_ADD2(x)		((x) << (0+16))
+#define ADR_CFG_PADS_1_ADD2		(0x0 << (6+16))
+#define ADR_CFG_PADS_2_ADD2		(0x1 << (6+16))
+#define ADR_CFG_PADS_4_ADD2		(0x3 << (6+16))
+#define ADR_CFG_CSDEASSERT_ADD2		(1   << (8+16))
+
+/*
+ * Register: SPI_FAST_SEQ_n
+ */
+#define SEQ_OPC_OPCODE(x)		((x) << 0)
+#define SEQ_OPC_CYCLES(x)		((x) << 8)
+#define SEQ_OPC_PADS_1			(0x0 << 14)
+#define SEQ_OPC_PADS_2			(0x1 << 14)
+#define SEQ_OPC_PADS_4			(0x3 << 14)
+#define SEQ_OPC_CSDEASSERT		(1   << 16)
+
+/*
+ * Register: SPI_FAST_SEQ_CFG
+ */
+#define SEQ_CFG_STARTSEQ		(1 << 0)
+#define SEQ_CFG_SWRESET			(1 << 5)
+#define SEQ_CFG_CSDEASSERT		(1 << 6)
+#define SEQ_CFG_READNOTWRITE		(1 << 7)
+#define SEQ_CFG_ERASE			(1 << 8)
+#define SEQ_CFG_PADS_1			(0x0 << 16)
+#define SEQ_CFG_PADS_2			(0x1 << 16)
+#define SEQ_CFG_PADS_4			(0x3 << 16)
+
+/*
+ * Register: SPI_MODE_BITS
+ */
+#define MODE_DATA(x)			(x & 0xff)
+#define MODE_CYCLES(x)			((x & 0x3f) << 16)
+#define MODE_PADS_1			(0x0 << 22)
+#define MODE_PADS_2			(0x1 << 22)
+#define MODE_PADS_4			(0x3 << 22)
+#define DUMMY_CSDEASSERT		(1   << 24)
+
+/*
+ * Register: SPI_DUMMY_BITS
+ */
+#define DUMMY_CYCLES(x)			((x & 0x3f) << 16)
+#define DUMMY_PADS_1			(0x0 << 22)
+#define DUMMY_PADS_2			(0x1 << 22)
+#define DUMMY_PADS_4			(0x3 << 22)
+#define DUMMY_CSDEASSERT		(1   << 24)
+
+/*
+ * Register: SPI_FAST_SEQ_FLASH_STA_DATA
+ */
+#define STA_DATA_BYTE1(x)		((x & 0xff) << 0)
+#define STA_DATA_BYTE2(x)		((x & 0xff) << 8)
+#define STA_PADS_1			(0x0 << 16)
+#define STA_PADS_2			(0x1 << 16)
+#define STA_PADS_4			(0x3 << 16)
+#define STA_CSDEASSERT			(0x1 << 20)
+#define STA_RDNOTWR			(0x1 << 21)
+
+/*
+ * FSM SPI Instruction Opcodes
+ */
+#define STFSM_OPC_CMD			0x1
+#define STFSM_OPC_ADD			0x2
+#define STFSM_OPC_STA			0x3
+#define STFSM_OPC_MODE			0x4
+#define STFSM_OPC_DUMMY		0x5
+#define STFSM_OPC_DATA			0x6
+#define STFSM_OPC_WAIT			0x7
+#define STFSM_OPC_JUMP			0x8
+#define STFSM_OPC_GOTO			0x9
+#define STFSM_OPC_STOP			0xF
+
+/*
+ * FSM SPI Instructions (== opcode + operand).
+ */
+#define STFSM_INSTR(cmd, op)		((cmd) | ((op) << 4))
+
+#define STFSM_INST_CMD1			STFSM_INSTR(STFSM_OPC_CMD,	1)
+#define STFSM_INST_CMD2			STFSM_INSTR(STFSM_OPC_CMD,	2)
+#define STFSM_INST_CMD3			STFSM_INSTR(STFSM_OPC_CMD,	3)
+#define STFSM_INST_CMD4			STFSM_INSTR(STFSM_OPC_CMD,	4)
+#define STFSM_INST_CMD5			STFSM_INSTR(STFSM_OPC_CMD,	5)
+#define STFSM_INST_ADD1			STFSM_INSTR(STFSM_OPC_ADD,	1)
+#define STFSM_INST_ADD2			STFSM_INSTR(STFSM_OPC_ADD,	2)
+
+#define STFSM_INST_DATA_WRITE		STFSM_INSTR(STFSM_OPC_DATA,	1)
+#define STFSM_INST_DATA_READ		STFSM_INSTR(STFSM_OPC_DATA,	2)
+
+#define STFSM_INST_STA_RD1		STFSM_INSTR(STFSM_OPC_STA,	0x1)
+#define STFSM_INST_STA_WR1		STFSM_INSTR(STFSM_OPC_STA,	0x1)
+#define STFSM_INST_STA_RD2		STFSM_INSTR(STFSM_OPC_STA,	0x2)
+#define STFSM_INST_STA_WR1_2		STFSM_INSTR(STFSM_OPC_STA,	0x3)
+
+#define STFSM_INST_MODE			STFSM_INSTR(STFSM_OPC_MODE,	0)
+#define STFSM_INST_DUMMY		STFSM_INSTR(STFSM_OPC_DUMMY,	0)
+#define STFSM_INST_WAIT			STFSM_INSTR(STFSM_OPC_WAIT,	0)
+#define STFSM_INST_STOP			STFSM_INSTR(STFSM_OPC_STOP,	0)
+
+#endif	/* ST_SPI_FSM_H */
-- 
1.8.1.2

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 03/10] mtd: st_spi_fsm: Initialise and configure the FSM for normal working conditions
  2013-11-14 14:22 [PATCH 00/10] mtd: st_spi_fsm: Add new device Lee Jones
  2013-11-14 14:22 ` [PATCH 01/10] mtd: st_spi_fsm: Allocate resources and register with MTD framework Lee Jones
  2013-11-14 14:22 ` [PATCH 02/10] mtd: st_spi_fsm: Supply all register address and bit logic defines Lee Jones
@ 2013-11-14 14:22 ` Lee Jones
  2013-11-14 14:22 ` [PATCH 04/10] mtd: st_spi_fsm: Supply framework for device requests Lee Jones
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 25+ messages in thread
From: Lee Jones @ 2013-11-14 14:22 UTC (permalink / raw)
  To: linux-arm-kernel

This patch uses default values to initialise a connected flash chip. This
includes; a device soft reset, setting of a safe working frequency, a
switch into Fast Sequencing Mode, configuring of timing data and a purge
of the FIFO.

Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
 drivers/mtd/devices/st_spi_fsm.c | 123 +++++++++++++++++++++++++++++++++++++++
 drivers/mtd/devices/st_spi_fsm.h |   4 ++
 2 files changed, 127 insertions(+)

diff --git a/drivers/mtd/devices/st_spi_fsm.c b/drivers/mtd/devices/st_spi_fsm.c
index 689f059..f560343 100644
--- a/drivers/mtd/devices/st_spi_fsm.c
+++ b/drivers/mtd/devices/st_spi_fsm.c
@@ -25,19 +25,136 @@
 
 #include "st_spi_fsm.h"
 
+#define STFSM_DEFAULT_EMI_FREQ	100000000UL                        /* 100 MHz */
+#define STFSM_DEFAULT_WR_TIME	STFSM_DEFAULT_EMI_FREQ * (15/1000) /* 15ms */
+
+#define FLASH_SAFE_FREQ		10000000UL                         /* 10 MHz */
+
 struct stfsm {
 	struct device		*dev;
 	void __iomem		*base;
 	struct resource		*region;
 	struct mtd_info		mtd;
 	struct mutex		lock;
+
+	uint32_t		fifo_dir_delay;
 };
 
+static inline uint32_t stfsm_fifo_available(struct stfsm *fsm)
+{
+	return (readl(fsm->base + SPI_FAST_SEQ_STA) >> 5) & 0x7f;
+}
+
+static void stfsm_clear_fifo(struct stfsm *fsm)
+{
+	uint32_t avail;
+
+	for (;;) {
+		avail = stfsm_fifo_available(fsm);
+		if (!avail)
+			break;
+
+		while (avail) {
+			readl(fsm->base + SPI_FAST_SEQ_DATA_REG);
+			avail--;
+		}
+	}
+}
+
+static int stfsm_set_mode(struct stfsm *fsm, uint32_t mode)
+{
+	int ret, timeout = 10;
+
+	/* Wait for controller to accept mode change */
+	while(--timeout) {
+		ret = readl(fsm->base + SPI_STA_MODE_CHANGE);
+		if (ret & 0x1)
+			break;
+		udelay(1);
+	}
+
+	if (!timeout)
+		return -EBUSY;
+
+	writel(mode, fsm->base + SPI_MODESELECT);
+
+	return 0;
+}
+
+static void stfsm_set_freq(struct stfsm *fsm, uint32_t spi_freq)
+{
+	uint32_t emi_freq;
+	uint32_t clk_div;
+
+	/* TODO: Make this dynamic */
+	emi_freq = STFSM_DEFAULT_EMI_FREQ;
+
+	/*
+	 * Calculate clk_div - values between 2 and 128
+	 * Multiple of 2, rounded up
+	 */
+	clk_div = 2*((emi_freq + (2*spi_freq - 1))/(2*spi_freq));
+	if (clk_div < 2)
+		clk_div = 2;
+	else if (clk_div > 128)
+		clk_div = 128;
+
+	/*
+	 * Determine a suitable delay for the IP to complete a change of
+	 * direction of the FIFO. The required delay is related to the clock
+	 * divider used. The following heuristics are based on empirical tests,
+	 * using a 100MHz EMI clock.
+	 */
+	if (clk_div <= 4)
+		fsm->fifo_dir_delay = 0;
+	else if (clk_div <= 10)
+		fsm->fifo_dir_delay = 1;
+	else
+		fsm->fifo_dir_delay = (clk_div + 9) / 10;
+
+	dev_dbg(fsm->dev, "emi_clk = %uHZ, spi_freq = %uHZ, clk_div = %u\n",
+		emi_freq, spi_freq, clk_div);
+
+	writel(clk_div, fsm->base + SPI_CLOCKDIV);
+}
+
+static int stfsm_init(struct stfsm *fsm)
+{
+	int ret;
+
+	/* Perform a soft reset of the FSM controller */
+	writel(SEQ_CFG_SWRESET, fsm->base + SPI_FAST_SEQ_CFG);
+	udelay(1);
+	writel(0, fsm->base + SPI_FAST_SEQ_CFG);
+
+	/* Set clock to 'safe' frequency initially */
+	stfsm_set_freq(fsm, FLASH_SAFE_FREQ);
+
+	/* Switch to FSM */
+	ret = stfsm_set_mode(fsm, SPI_MODESELECT_FSM);
+	if (ret)
+		return ret;
+
+	/* Set timing parameters */
+	writel(SPI_CFG_DEVICE_ST            |
+	       SPI_CFG_DEFAULT_MIN_CS_HIGH  |
+	       SPI_CFG_DEFAULT_CS_SETUPHOLD |
+	       SPI_CFG_DEFAULT_DATA_HOLD,
+	       fsm->base + SPI_CONFIGDATA);
+	writel(STFSM_DEFAULT_WR_TIME, fsm->base + SPI_STATUS_WR_TIME_REG);
+
+	/* Clear FIFO, just in case */
+	stfsm_clear_fifo(fsm);
+
+	return 0;
+}
+
 static int stfsm_probe(struct platform_device *pdev)
 {
 	struct device_node *np = pdev->dev.of_node;
 	struct resource *res;
 	struct stfsm *fsm;
+	int ret;
 
 	if (!np) {
 		dev_err(&pdev->dev, "No DT found\n");
@@ -74,6 +191,12 @@ static int stfsm_probe(struct platform_device *pdev)
 
 	mutex_init(&fsm->lock);
 
+	ret = stfsm_init(fsm);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to initialise FSM Controller\n");
+		return ret;
+	}
+
 	platform_set_drvdata(pdev, fsm);
 
 	fsm->mtd.dev.parent   = &pdev->dev;
diff --git a/drivers/mtd/devices/st_spi_fsm.h b/drivers/mtd/devices/st_spi_fsm.h
index 11ca33a..7a8f1eb 100644
--- a/drivers/mtd/devices/st_spi_fsm.h
+++ b/drivers/mtd/devices/st_spi_fsm.h
@@ -69,6 +69,10 @@
 #define SPI_CFG_CS_SETUPHOLD(x)		(((x) & 0xff) << 16)
 #define SPI_CFG_DATA_HOLD(x)		(((x) & 0xff) << 24)
 
+#define SPI_CFG_DEFAULT_MIN_CS_HIGH	SPI_CFG_MIN_CS_HIGH(0x0AA)
+#define SPI_CFG_DEFAULT_CS_SETUPHOLD	SPI_CFG_CS_SETUPHOLD(0xA0)
+#define SPI_CFG_DEFAULT_DATA_HOLD	SPI_CFG_DATA_HOLD(0x00)
+
 /*
  * Register: SPI_FAST_SEQ_TRANSFER_SIZE
  */
-- 
1.8.1.2

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 04/10] mtd: st_spi_fsm: Supply framework for device requests
  2013-11-14 14:22 [PATCH 00/10] mtd: st_spi_fsm: Add new device Lee Jones
                   ` (2 preceding siblings ...)
  2013-11-14 14:22 ` [PATCH 03/10] mtd: st_spi_fsm: Initialise and configure the FSM for normal working conditions Lee Jones
@ 2013-11-14 14:22 ` Lee Jones
  2013-11-14 14:22 ` [PATCH 05/10] mtd: st_spi_fsm: Supply a method to read from the FSM's FIFO Lee Jones
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 25+ messages in thread
From: Lee Jones @ 2013-11-14 14:22 UTC (permalink / raw)
  To: linux-arm-kernel

The FSM hardware works by setting a predetermined sequence of register
writes. Rather than open coding them inside each functional block we're
going to define them in a series of formatted 'sequence structures'.
This patch provides the framework which shall be used for every action.

Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
 drivers/mtd/devices/st_spi_fsm.c | 49 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 49 insertions(+)

diff --git a/drivers/mtd/devices/st_spi_fsm.c b/drivers/mtd/devices/st_spi_fsm.c
index f560343..02619ee 100644
--- a/drivers/mtd/devices/st_spi_fsm.c
+++ b/drivers/mtd/devices/st_spi_fsm.c
@@ -40,11 +40,60 @@ struct stfsm {
 	uint32_t		fifo_dir_delay;
 };
 
+struct stfsm_seq {
+	uint32_t data_size;
+	uint32_t addr1;
+	uint32_t addr2;
+	uint32_t addr_cfg;
+	uint32_t seq_opc[5];
+	uint32_t mode;
+	uint32_t dummy;
+	uint32_t status;
+	uint8_t  seq[16];
+	uint32_t seq_cfg;
+} __attribute__((__packed__, aligned(4)));
+#define STFSM_SEQ_SIZE sizeof(struct stfsm_seq)
+
+static inline int stfsm_is_idle(struct stfsm *fsm)
+{
+	return readl(fsm->base + SPI_FAST_SEQ_STA) & 0x10;
+}
+
 static inline uint32_t stfsm_fifo_available(struct stfsm *fsm)
 {
 	return (readl(fsm->base + SPI_FAST_SEQ_STA) >> 5) & 0x7f;
 }
 
+static inline void stfsm_load_seq(struct stfsm *fsm,
+				  const struct stfsm_seq *seq)
+{
+	void __iomem *dst = fsm->base + SPI_FAST_SEQ_TRANSFER_SIZE;
+	const uint32_t *src = (const uint32_t *)seq;
+	int words = STFSM_SEQ_SIZE / sizeof(uint32_t);
+
+	BUG_ON(!stfsm_is_idle(fsm));
+
+	while (words--) {
+		writel(*src, dst);
+		src++;
+		dst += 4;
+	}
+}
+
+static void stfsm_wait_seq(struct stfsm *fsm)
+{
+	unsigned long timeo = jiffies + HZ;
+
+	while (time_before(jiffies, timeo)) {
+		if (stfsm_is_idle(fsm))
+			return;
+
+		cond_resched();
+	}
+
+	dev_err(fsm->dev, "timeout on sequence completion\n");
+}
+
 static void stfsm_clear_fifo(struct stfsm *fsm)
 {
 	uint32_t avail;
-- 
1.8.1.2

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 05/10] mtd: st_spi_fsm: Supply a method to read from the FSM's FIFO
  2013-11-14 14:22 [PATCH 00/10] mtd: st_spi_fsm: Add new device Lee Jones
                   ` (3 preceding siblings ...)
  2013-11-14 14:22 ` [PATCH 04/10] mtd: st_spi_fsm: Supply framework for device requests Lee Jones
@ 2013-11-14 14:22 ` Lee Jones
  2013-11-14 14:22 ` [PATCH 06/10] mtd: st_spi_fsm: Supply defines for the possible flash command opcodes Lee Jones
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 25+ messages in thread
From: Lee Jones @ 2013-11-14 14:22 UTC (permalink / raw)
  To: linux-arm-kernel

When invoked the driver will attempt to read any available data from
the FSM's data register. Any data collected from this FIFO would have
originated from the flash chip.

Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
 drivers/mtd/devices/st_spi_fsm.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/drivers/mtd/devices/st_spi_fsm.c b/drivers/mtd/devices/st_spi_fsm.c
index 02619ee..a1c2857 100644
--- a/drivers/mtd/devices/st_spi_fsm.c
+++ b/drivers/mtd/devices/st_spi_fsm.c
@@ -94,6 +94,32 @@ static void stfsm_wait_seq(struct stfsm *fsm)
 	dev_err(fsm->dev, "timeout on sequence completion\n");
 }
 
+static void stfsm_read_fifo(struct stfsm *fsm, uint32_t *buf,
+			    const uint32_t size)
+{
+	uint32_t remaining = size >> 2;
+	uint32_t avail;
+	uint32_t words;
+
+	dev_dbg(fsm->dev, "Reading %d bytes from FIFO\n", size);
+
+	BUG_ON((((uint32_t)buf) & 0x3) || (size & 0x3));
+
+	while (remaining) {
+		for (;;) {
+			avail = stfsm_fifo_available(fsm);
+			if (avail)
+				break;
+			udelay(1);
+		}
+		words = min(avail, remaining);
+		remaining -= words;
+
+		readsl(fsm->base + SPI_FAST_SEQ_DATA_REG, buf, words);
+		buf += words;
+	}
+}
+
 static void stfsm_clear_fifo(struct stfsm *fsm)
 {
 	uint32_t avail;
-- 
1.8.1.2

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 06/10] mtd: st_spi_fsm: Supply defines for the possible flash command opcodes
  2013-11-14 14:22 [PATCH 00/10] mtd: st_spi_fsm: Add new device Lee Jones
                   ` (4 preceding siblings ...)
  2013-11-14 14:22 ` [PATCH 05/10] mtd: st_spi_fsm: Supply a method to read from the FSM's FIFO Lee Jones
@ 2013-11-14 14:22 ` Lee Jones
  2013-11-14 14:22 ` [PATCH 07/10] mtd: st_spi_fsm: Add support for JEDEC ID extraction Lee Jones
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 25+ messages in thread
From: Lee Jones @ 2013-11-14 14:22 UTC (permalink / raw)
  To: linux-arm-kernel

Flash chip commands are issued using a set of predefined opcodes. These
are mostly the same for all flash devices, but do differ on occasion.
This patch supplies the majority of the key ones which will be used in
this driver.

Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
 drivers/mtd/devices/st_spi_fsm.c | 38 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/drivers/mtd/devices/st_spi_fsm.c b/drivers/mtd/devices/st_spi_fsm.c
index a1c2857..6691eaf 100644
--- a/drivers/mtd/devices/st_spi_fsm.c
+++ b/drivers/mtd/devices/st_spi_fsm.c
@@ -30,6 +30,44 @@
 
 #define FLASH_SAFE_FREQ		10000000UL                         /* 10 MHz */
 
+/* Flash Commands */
+#define FLASH_CMD_WREN		0x06
+#define FLASH_CMD_WRDI		0x04
+#define FLASH_CMD_RDID		0x9f
+#define FLASH_CMD_RDSR		0x05
+#define FLASH_CMD_RDSR2		0x35
+#define FLASH_CMD_WRSR		0x01
+#define FLASH_CMD_SE_4K		0x20
+#define FLASH_CMD_SE_32K	0x52
+#define FLASH_CMD_SE		0xd8
+#define FLASH_CMD_CHIPERASE	0xc7
+#define FLASH_CMD_WRVCR		0x81
+#define FLASH_CMD_RDVCR		0x85
+
+#define FLASH_CMD_READ		0x03	/* READ */
+#define FLASH_CMD_READ_FAST	0x0b	/* FAST READ */
+#define FLASH_CMD_READ_1_1_2	0x3b	/* DUAL OUTPUT READ */
+#define FLASH_CMD_READ_1_2_2	0xbb	/* DUAL I/O READ */
+#define FLASH_CMD_READ_1_1_4	0x6b	/* QUAD OUTPUT READ */
+#define FLASH_CMD_READ_1_4_4	0xeb	/* QUAD I/O READ */
+
+#define FLASH_CMD_WRITE		0x02	/* PAGE PROGRAM */
+#define FLASH_CMD_WRITE_1_1_2	0xa2	/* DUAL INPUT PROGRAM */
+#define FLASH_CMD_WRITE_1_2_2	0xd2	/* DUAL INPUT EXT PROGRAM */
+#define FLASH_CMD_WRITE_1_1_4	0x32	/* QUAD INPUT PROGRAM */
+#define FLASH_CMD_WRITE_1_4_4	0x12	/* QUAD INPUT EXT PROGRAM */
+
+#define FLASH_CMD_EN4B_ADDR	0xb7	/* Enter 4-byte address mode */
+#define FLASH_CMD_EX4B_ADDR	0xe9	/* Exit 4-byte address mode */
+
+/* READ commands with 32-bit addressing (N25Q256 and S25FLxxxS) */
+#define FLASH_CMD_READ4		0x13
+#define FLASH_CMD_READ4_FAST	0x0c
+#define FLASH_CMD_READ4_1_1_2	0x3c
+#define FLASH_CMD_READ4_1_2_2	0xbc
+#define FLASH_CMD_READ4_1_1_4	0x6c
+#define FLASH_CMD_READ4_1_4_4	0xec
+
 struct stfsm {
 	struct device		*dev;
 	void __iomem		*base;
-- 
1.8.1.2

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 07/10] mtd: st_spi_fsm: Add support for JEDEC ID extraction
  2013-11-14 14:22 [PATCH 00/10] mtd: st_spi_fsm: Add new device Lee Jones
                   ` (5 preceding siblings ...)
  2013-11-14 14:22 ` [PATCH 06/10] mtd: st_spi_fsm: Supply defines for the possible flash command opcodes Lee Jones
@ 2013-11-14 14:22 ` Lee Jones
  2013-11-14 14:22 ` [PATCH 08/10] mtd: st_spi_fsm: Provide device look-up table Lee Jones
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 25+ messages in thread
From: Lee Jones @ 2013-11-14 14:22 UTC (permalink / raw)
  To: linux-arm-kernel

Once we start supporting devices it will be handy go detect them
dynamically. This will be done using the chip's unique JEDEC ID. This
patch allows us to extract a device's JEDEC ID using the a predefined
FSM register write sequence.

Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
 drivers/mtd/devices/st_spi_fsm.c | 63 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 63 insertions(+)

diff --git a/drivers/mtd/devices/st_spi_fsm.c b/drivers/mtd/devices/st_spi_fsm.c
index 6691eaf..2899e0f 100644
--- a/drivers/mtd/devices/st_spi_fsm.c
+++ b/drivers/mtd/devices/st_spi_fsm.c
@@ -92,6 +92,22 @@ struct stfsm_seq {
 } __attribute__((__packed__, aligned(4)));
 #define STFSM_SEQ_SIZE sizeof(struct stfsm_seq)
 
+static struct stfsm_seq stfsm_seq_read_jedec = {
+	.data_size = TRANSFER_SIZE(8),
+	.seq_opc[0] = (SEQ_OPC_PADS_1 |
+		       SEQ_OPC_CYCLES(8) |
+		       SEQ_OPC_OPCODE(FLASH_CMD_RDID)),
+	.seq = {
+		STFSM_INST_CMD1,
+		STFSM_INST_DATA_READ,
+		STFSM_INST_STOP,
+	},
+	.seq_cfg = (SEQ_CFG_PADS_1 |
+		    SEQ_CFG_READNOTWRITE |
+		    SEQ_CFG_CSDEASSERT |
+		    SEQ_CFG_STARTSEQ),
+};
+
 static inline int stfsm_is_idle(struct stfsm *fsm)
 {
 	return readl(fsm->base + SPI_FAST_SEQ_STA) & 0x10;
@@ -158,6 +174,50 @@ static void stfsm_read_fifo(struct stfsm *fsm, uint32_t *buf,
 	}
 }
 
+static int stfsm_read_jedec(struct stfsm *fsm, uint8_t *const jedec)
+{
+	const struct stfsm_seq *seq = &stfsm_seq_read_jedec;
+	uint32_t tmp[2];
+
+	stfsm_load_seq(fsm, seq);
+
+	stfsm_read_fifo(fsm, tmp, 8);
+
+	memcpy(jedec, tmp, 5);
+
+	stfsm_wait_seq(fsm);
+
+	return 0;
+}
+
+static struct flash_info * stfsm_jedec_probe(struct stfsm *fsm)
+{
+	u16                     ext_jedec;
+	u32			jedec;
+	u8			id[5];
+	int			ret;
+
+	/*
+	 * JEDEC also defines an optional "extended device information"
+	 * string for after vendor-specific data, after the three bytes
+	 * we use here. Supporting some chips might require using it.
+	 */
+
+	ret = stfsm_read_jedec(fsm, id);
+	if (ret) {
+		dev_info(fsm->dev, "Error reading JEDEC ID\n");
+		return NULL;
+	}
+
+	jedec     = id[0] << 16 | id[1] << 8 | id[2];
+	ext_jedec = id[3] << 8  | id[4];
+
+	dev_dbg(fsm->dev, "JEDEC =  0x%08x [%02x %02x %02x %02x %02x]\n",
+		jedec, id[0], id[1], id[2], id[3], id[4]);
+
+	return NULL;
+}
+
 static void stfsm_clear_fifo(struct stfsm *fsm)
 {
 	uint32_t avail;
@@ -310,6 +370,9 @@ static int stfsm_probe(struct platform_device *pdev)
 		return ret;
 	}
 
+	/* Detect SPI FLASH device */
+	stfsm_jedec_probe(fsm);
+
 	platform_set_drvdata(pdev, fsm);
 
 	fsm->mtd.dev.parent   = &pdev->dev;
-- 
1.8.1.2

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 08/10] mtd: st_spi_fsm: Provide device look-up table
  2013-11-14 14:22 [PATCH 00/10] mtd: st_spi_fsm: Add new device Lee Jones
                   ` (6 preceding siblings ...)
  2013-11-14 14:22 ` [PATCH 07/10] mtd: st_spi_fsm: Add support for JEDEC ID extraction Lee Jones
@ 2013-11-14 14:22 ` Lee Jones
  2013-11-14 14:22 ` [PATCH 09/10] mtd: st_spi_fsm: Dynamically setup flash device based on JEDEC ID Lee Jones
  2013-11-14 14:22 ` [PATCH 10/10] ARM: STi: Add support for the FSM Serial Flash Controller Lee Jones
  9 siblings, 0 replies; 25+ messages in thread
From: Lee Jones @ 2013-11-14 14:22 UTC (permalink / raw)
  To: linux-arm-kernel

Supply a lookup table of all the devices we intend to support. This table
is used to store device information such as; a human readable device name,
their JEDEC ID (plus the extended version), sector size and amount, a bit
store of a device's capabilities, its maximum running frequency and
possible use of a per-device configuration call-back.

Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
 drivers/mtd/devices/st_spi_fsm.c | 165 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 165 insertions(+)

diff --git a/drivers/mtd/devices/st_spi_fsm.c b/drivers/mtd/devices/st_spi_fsm.c
index 2899e0f..230024c 100644
--- a/drivers/mtd/devices/st_spi_fsm.c
+++ b/drivers/mtd/devices/st_spi_fsm.c
@@ -68,6 +68,33 @@
 #define FLASH_CMD_READ4_1_1_4	0x6c
 #define FLASH_CMD_READ4_1_4_4	0xec
 
+/* Capabilities */
+#define FLASH_CAPS_SINGLE	0x000000ff
+#define FLASH_CAPS_READ_WRITE	0x00000001
+#define FLASH_CAPS_READ_FAST	0x00000002
+#define FLASH_CAPS_SE_4K	0x00000004
+#define FLASH_CAPS_SE_32K	0x00000008
+#define FLASH_CAPS_CE		0x00000010
+#define FLASH_CAPS_32BITADDR	0x00000020
+#define FLASH_CAPS_RESET	0x00000040
+#define FLASH_CAPS_DYB_LOCKING	0x00000080
+
+#define FLASH_CAPS_DUAL		0x0000ff00
+#define FLASH_CAPS_READ_1_1_2	0x00000100
+#define FLASH_CAPS_READ_1_2_2	0x00000200
+#define FLASH_CAPS_READ_2_2_2	0x00000400
+#define FLASH_CAPS_WRITE_1_1_2	0x00001000
+#define FLASH_CAPS_WRITE_1_2_2	0x00002000
+#define FLASH_CAPS_WRITE_2_2_2	0x00004000
+
+#define FLASH_CAPS_QUAD		0x00ff0000
+#define FLASH_CAPS_READ_1_1_4	0x00010000
+#define FLASH_CAPS_READ_1_4_4	0x00020000
+#define FLASH_CAPS_READ_4_4_4	0x00040000
+#define FLASH_CAPS_WRITE_1_1_4	0x00100000
+#define FLASH_CAPS_WRITE_1_4_4	0x00200000
+#define FLASH_CAPS_WRITE_4_4_4	0x00400000
+
 struct stfsm {
 	struct device		*dev;
 	void __iomem		*base;
@@ -92,6 +119,31 @@ struct stfsm_seq {
 } __attribute__((__packed__, aligned(4)));
 #define STFSM_SEQ_SIZE sizeof(struct stfsm_seq)
 
+/* SPI Flash Device Table */
+struct flash_info {
+	char		*name;
+	/*
+	 * JEDEC id zero means "no ID" (most older chips); otherwise it has
+	 * a high byte of zero plus three data bytes: the manufacturer id,
+	 * then a two byte device id.
+	 */
+	u32		jedec_id;
+	u16             ext_id;
+	/*
+	 * The size listed here is what works with FLASH_CMD_SE, which isn't
+	 * necessarily called a "sector" by the vendor.
+	 */
+	unsigned	sector_size;
+	u16		n_sectors;
+	u32		capabilities;
+	/*
+	 * Note, where FAST_READ is supported, freq_max specifies the
+	 * FAST_READ frequency, not the READ frequency.
+	 */
+	u32		max_freq;
+	int		(*config)(struct stfsm *, struct flash_info *);
+};
+
 static struct stfsm_seq stfsm_seq_read_jedec = {
 	.data_size = TRANSFER_SIZE(8),
 	.seq_opc[0] = (SEQ_OPC_PADS_1 |
@@ -108,6 +160,119 @@ static struct stfsm_seq stfsm_seq_read_jedec = {
 		    SEQ_CFG_STARTSEQ),
 };
 
+static struct flash_info __initdata flash_types[] = {
+
+	/*
+	 * ST Microelectronics/Numonyx --
+	 * (newer production versions may have feature updates
+	 * (eg faster operating frequency)
+	 */
+#define M25P_CAPS (FLASH_CAPS_READ_WRITE | FLASH_CAPS_READ_FAST)
+	{ "m25p40",  0x202013, 0,  64 * 1024,   8, M25P_CAPS, 25, NULL },
+	{ "m25p80",  0x202014, 0,  64 * 1024,  16, M25P_CAPS, 25, NULL },
+	{ "m25p16",  0x202015, 0,  64 * 1024,  32, M25P_CAPS, 25, NULL },
+	{ "m25p32",  0x202016, 0,  64 * 1024,  64, M25P_CAPS, 50, NULL },
+	{ "m25p64",  0x202017, 0,  64 * 1024, 128, M25P_CAPS, 50, NULL },
+	{ "m25p128", 0x202018, 0, 256 * 1024,  64, M25P_CAPS, 50, NULL },
+
+#define M25PX_CAPS (FLASH_CAPS_READ_WRITE	| \
+		    FLASH_CAPS_READ_FAST	| \
+		    FLASH_CAPS_READ_1_1_2	| \
+		    FLASH_CAPS_WRITE_1_1_2)
+	{ "m25px32", 0x207116, 0,  64 * 1024,  64, M25PX_CAPS, 75, NULL },
+	{ "m25px64", 0x207117, 0,  64 * 1024, 128, M25PX_CAPS, 75, NULL },
+
+#define MX25_CAPS (FLASH_CAPS_READ_WRITE	| \
+		   FLASH_CAPS_READ_FAST		| \
+		   FLASH_CAPS_READ_1_1_2	| \
+		   FLASH_CAPS_READ_1_2_2	| \
+		   FLASH_CAPS_READ_1_1_4	| \
+		   FLASH_CAPS_READ_1_4_4	| \
+		   FLASH_CAPS_WRITE_1_4_4	| \
+		   FLASH_CAPS_SE_4K		| \
+		   FLASH_CAPS_SE_32K)
+	{ "mx25l25635e", 0xc22019, 0, 64*1024, 512,
+	  (MX25_CAPS | FLASH_CAPS_32BITADDR | FLASH_CAPS_RESET), 70, NULL },
+
+#define N25Q_CAPS (FLASH_CAPS_READ_WRITE	| \
+		   FLASH_CAPS_READ_FAST		| \
+		   FLASH_CAPS_READ_1_1_2	| \
+		   FLASH_CAPS_READ_1_2_2	| \
+		   FLASH_CAPS_READ_1_1_4	| \
+		   FLASH_CAPS_READ_1_4_4	| \
+		   FLASH_CAPS_WRITE_1_1_2	| \
+		   FLASH_CAPS_WRITE_1_2_2	| \
+		   FLASH_CAPS_WRITE_1_1_4	| \
+		   FLASH_CAPS_WRITE_1_4_4)
+	{ "n25q128", 0x20ba18, 0, 64 * 1024,  256, N25Q_CAPS, 108, NULL },
+	{ "n25q256", 0x20ba19, 0, 64 * 1024,  512,
+	  N25Q_CAPS | FLASH_CAPS_32BITADDR, 108, NULL },
+
+	/*
+	 * Spansion S25FLxxxP
+	 *     - 256KiB and 64KiB sector variants (identified by ext. JEDEC)
+	 */
+#define S25FLXXXP_CAPS (FLASH_CAPS_READ_WRITE	| \
+			FLASH_CAPS_READ_1_1_2	| \
+			FLASH_CAPS_READ_1_2_2	| \
+			FLASH_CAPS_READ_1_1_4	| \
+			FLASH_CAPS_READ_1_4_4	| \
+			FLASH_CAPS_WRITE_1_1_4	| \
+			FLASH_CAPS_READ_FAST)
+	{ "s25fl129p0", 0x012018, 0x4d00, 256 * 1024,  64, S25FLXXXP_CAPS, 80,
+	  NULL },
+	{ "s25fl129p1", 0x012018, 0x4d01,  64 * 1024, 256, S25FLXXXP_CAPS, 80,
+	  NULL },
+
+	/*
+	 * Spansion S25FLxxxS
+	 *     - 256KiB and 64KiB sector variants (identified by ext. JEDEC)
+	 *     - RESET# signal supported by die but not bristled out on all
+	 *       package types.  The package type is a function of board design,
+	 *       so this information is captured in the board's capabilities.
+	 *     - Supports 'DYB' sector protection. Depending on variant, sectors
+	 *       may default to locked state on power-on.
+	 */
+#define S25FLXXXS_CAPS (S25FLXXXP_CAPS		| \
+			FLASH_CAPS_RESET	| \
+			FLASH_CAPS_DYB_LOCKING)
+	{ "s25fl128s0", 0x012018, 0x0300,  256 * 1024, 64, S25FLXXXS_CAPS, 80,
+	  NULL },
+	{ "s25fl128s1", 0x012018, 0x0301,  64 * 1024, 256, S25FLXXXS_CAPS, 80,
+	  NULL },
+	{ "s25fl256s0", 0x010219, 0x4d00, 256 * 1024, 128,
+	  S25FLXXXS_CAPS | FLASH_CAPS_32BITADDR, 80, NULL },
+	{ "s25fl256s1", 0x010219, 0x4d01,  64 * 1024, 512,
+	  S25FLXXXS_CAPS | FLASH_CAPS_32BITADDR, 80, NULL },
+
+	/* Winbond -- w25x "blocks" are 64K, "sectors" are 4KiB */
+#define W25X_CAPS (FLASH_CAPS_READ_WRITE	| \
+		   FLASH_CAPS_READ_FAST		| \
+		   FLASH_CAPS_READ_1_1_2	| \
+		   FLASH_CAPS_WRITE_1_1_2)
+	{ "w25x40",  0xef3013, 0,  64 * 1024,   8, W25X_CAPS, 75, NULL },
+	{ "w25x80",  0xef3014, 0,  64 * 1024,  16, W25X_CAPS, 75, NULL },
+	{ "w25x16",  0xef3015, 0,  64 * 1024,  32, W25X_CAPS, 75, NULL },
+	{ "w25x32",  0xef3016, 0,  64 * 1024,  64, W25X_CAPS, 75, NULL },
+	{ "w25x64",  0xef3017, 0,  64 * 1024, 128, W25X_CAPS, 75, NULL },
+
+	/* Winbond -- w25q "blocks" are 64K, "sectors" are 4KiB */
+#define W25Q_CAPS (FLASH_CAPS_READ_WRITE	| \
+		   FLASH_CAPS_READ_FAST		| \
+		   FLASH_CAPS_READ_1_1_2	| \
+		   FLASH_CAPS_READ_1_2_2	| \
+		   FLASH_CAPS_READ_1_1_4	| \
+		   FLASH_CAPS_READ_1_4_4	| \
+		   FLASH_CAPS_WRITE_1_1_4)
+	{ "w25q80",  0xef4014, 0,  64 * 1024,  16, W25Q_CAPS, 80, NULL },
+	{ "w25q16",  0xef4015, 0,  64 * 1024,  32, W25Q_CAPS, 80, NULL },
+	{ "w25q32",  0xef4016, 0,  64 * 1024,  64, W25Q_CAPS, 80, NULL },
+	{ "w25q64",  0xef4017, 0,  64 * 1024, 128, W25Q_CAPS, 80, NULL },
+
+	/* Sentinel */
+	{ NULL, 0x000000, 0, 0, 0, 0, 0, NULL },
+};
+
 static inline int stfsm_is_idle(struct stfsm *fsm)
 {
 	return readl(fsm->base + SPI_FAST_SEQ_STA) & 0x10;
-- 
1.8.1.2

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 09/10] mtd: st_spi_fsm: Dynamically setup flash device based on JEDEC ID
  2013-11-14 14:22 [PATCH 00/10] mtd: st_spi_fsm: Add new device Lee Jones
                   ` (7 preceding siblings ...)
  2013-11-14 14:22 ` [PATCH 08/10] mtd: st_spi_fsm: Provide device look-up table Lee Jones
@ 2013-11-14 14:22 ` Lee Jones
  2013-11-14 14:22 ` [PATCH 10/10] ARM: STi: Add support for the FSM Serial Flash Controller Lee Jones
  9 siblings, 0 replies; 25+ messages in thread
From: Lee Jones @ 2013-11-14 14:22 UTC (permalink / raw)
  To: linux-arm-kernel

Using previously added infrastructure we can now extract a device's JEDEC
ID, compare it to a list of known and supported devices and make assumptions
based on known characteristics of a given chip.

Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
 drivers/mtd/devices/st_spi_fsm.c | 24 +++++++++++++++++++++++-
 1 file changed, 23 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/devices/st_spi_fsm.c b/drivers/mtd/devices/st_spi_fsm.c
index 230024c..42dd4d9 100644
--- a/drivers/mtd/devices/st_spi_fsm.c
+++ b/drivers/mtd/devices/st_spi_fsm.c
@@ -357,6 +357,7 @@ static int stfsm_read_jedec(struct stfsm *fsm, uint8_t *const jedec)
 
 static struct flash_info * stfsm_jedec_probe(struct stfsm *fsm)
 {
+	struct flash_info	*info;
 	u16                     ext_jedec;
 	u32			jedec;
 	u8			id[5];
@@ -380,6 +381,15 @@ static struct flash_info * stfsm_jedec_probe(struct stfsm *fsm)
 	dev_dbg(fsm->dev, "JEDEC =  0x%08x [%02x %02x %02x %02x %02x]\n",
 		jedec, id[0], id[1], id[2], id[3], id[4]);
 
+	for (info = flash_types; info->name; info++) {
+		if (info->jedec_id == jedec) {
+			if (info->ext_id && info->ext_id != ext_jedec)
+				continue;
+			return info;
+		}
+	}
+	dev_err(fsm->dev, "Unrecognized JEDEC id %06x\n", jedec);
+
 	return NULL;
 }
 
@@ -490,6 +500,7 @@ static int stfsm_init(struct stfsm *fsm)
 static int stfsm_probe(struct platform_device *pdev)
 {
 	struct device_node *np = pdev->dev.of_node;
+	struct flash_info *info;
 	struct resource *res;
 	struct stfsm *fsm;
 	int ret;
@@ -536,7 +547,9 @@ static int stfsm_probe(struct platform_device *pdev)
 	}
 
 	/* Detect SPI FLASH device */
-	stfsm_jedec_probe(fsm);
+	info = stfsm_jedec_probe(fsm);
+	if (!info)
+		return -ENODEV;
 
 	platform_set_drvdata(pdev, fsm);
 
@@ -545,6 +558,15 @@ static int stfsm_probe(struct platform_device *pdev)
 	fsm->mtd.writesize    = 4;
 	fsm->mtd.writebufsize = fsm->mtd.writesize;
 	fsm->mtd.flags        = MTD_CAP_NORFLASH;
+	fsm->mtd.size         = info->sector_size * info->n_sectors;
+	fsm->mtd.erasesize    = info->sector_size;
+
+	dev_err(&pdev->dev,
+		"Found serial flash device: %s\n"
+		" size = %llx (%lldMiB) erasesize = 0x%08x (%uKiB)\n",
+		info->name,
+		(long long)fsm->mtd.size, (long long)(fsm->mtd.size >> 20),
+		fsm->mtd.erasesize, (fsm->mtd.erasesize >> 10));
 
 	return mtd_device_parse_register(&fsm->mtd, NULL, NULL, NULL, 0);
 }
-- 
1.8.1.2

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 10/10] ARM: STi: Add support for the FSM Serial Flash Controller
  2013-11-14 14:22 [PATCH 00/10] mtd: st_spi_fsm: Add new device Lee Jones
                   ` (8 preceding siblings ...)
  2013-11-14 14:22 ` [PATCH 09/10] mtd: st_spi_fsm: Dynamically setup flash device based on JEDEC ID Lee Jones
@ 2013-11-14 14:22 ` Lee Jones
  9 siblings, 0 replies; 25+ messages in thread
From: Lee Jones @ 2013-11-14 14:22 UTC (permalink / raw)
  To: linux-arm-kernel

Here we add the necessary device nodes required for successful device
probing and Pinctrl setup for the FSM.

Cc: Srinivas Kandagatla <srinivas.kandagatla@st.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
 arch/arm/boot/dts/stih416-b2105.dts    | 10 ++++++++++
 arch/arm/boot/dts/stih416-pinctrl.dtsi | 12 ++++++++++++
 2 files changed, 22 insertions(+)

diff --git a/arch/arm/boot/dts/stih416-b2105.dts b/arch/arm/boot/dts/stih416-b2105.dts
index f14eec3..29b09ab 100644
--- a/arch/arm/boot/dts/stih416-b2105.dts
+++ b/arch/arm/boot/dts/stih416-b2105.dts
@@ -32,6 +32,16 @@
 			status = "okay";
 		};
 
+		/* FSM */
+		spifsm: spifsm at fe902000{
+		        compatible      = "st,spi-fsm", "simple-bus";
+		        reg             =  <0xfe902000 0x1000>;
+		        reg-names       = "spi-fsm";
+		        pinctrl-0       = <&pinctrl_fsm>;
+
+		        status = "okay";
+		};
+
 		leds {
 			compatible	= "gpio-leds";
 			fp_led {
diff --git a/arch/arm/boot/dts/stih416-pinctrl.dtsi b/arch/arm/boot/dts/stih416-pinctrl.dtsi
index eb426a1..3106ea2 100644
--- a/arch/arm/boot/dts/stih416-pinctrl.dtsi
+++ b/arch/arm/boot/dts/stih416-pinctrl.dtsi
@@ -235,6 +235,18 @@
 				};
 			};
 
+			fsm {
+				pinctrl_fsm: fsm {
+					st,pins {
+						spi-fsm-clk     = <&PIO12 2     OUT     ALT1>;
+						spi-fsm-cs      = <&PIO12 3     OUT     ALT1>;
+						spi-fsm-mosi    = <&PIO12 4     OUT     ALT1>;
+						spi-fsm-miso    = <&PIO12 5     IN      ALT1>;
+						spi-fsm-hol     = <&PIO12 6     OUT     ALT1>;
+						spi-fsm-wp      = <&PIO12 7     OUT     ALT1>;
+					};
+				};
+			};
 		};
 
 		pin-controller-rear {
-- 
1.8.1.2

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 02/10] mtd: st_spi_fsm: Supply all register address and bit logic defines
  2013-11-14 14:22 ` [PATCH 02/10] mtd: st_spi_fsm: Supply all register address and bit logic defines Lee Jones
@ 2013-11-18  9:15   ` Linus Walleij
  2013-11-18  9:32     ` Lee Jones
  0 siblings, 1 reply; 25+ messages in thread
From: Linus Walleij @ 2013-11-18  9:15 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Nov 14, 2013 at 3:22 PM, Lee Jones <lee.jones@linaro.org> wrote:

> Here we provide the FSM's register addresses, register bit names/offsets
> and some commands which will prove useful as we start bulk the FMS's
> driver out with functionality.
>
> Signed-off-by: Lee Jones <lee.jones@linaro.org>

OK...

> +/*
> + * FSM SPI Controller Registers
> + */
> +#define SPI_CLOCKDIV                   0x0010
> +#define SPI_MODESELECT                 0x0018
> +#define SPI_CONFIGDATA                 0x0020
(...)

So what we want to know here is whether this is a general-purpose
SPI block, or if it's a special-purpose SPI block that can only be
used for accessing flashes.

If it's the former that part should be broken out into drivers/spi
of course...

But the register map seems a bit special-purpose so it could
very well be that this is for flash control only. So maybe you can
spill some beans from a datasheet here?

A clock divider at offset 0x10 already tells us that this is probably
a PL022 derivate, just that we don't know how much it has
been hacked with... does this thing contain AMBA identifiers
at the end of the IO-region, usually at 0x0fe0 thru 0x0fff?

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH 02/10] mtd: st_spi_fsm: Supply all register address and bit logic defines
  2013-11-18  9:15   ` Linus Walleij
@ 2013-11-18  9:32     ` Lee Jones
  2013-11-18 13:39       ` Mark Brown
  0 siblings, 1 reply; 25+ messages in thread
From: Lee Jones @ 2013-11-18  9:32 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, 18 Nov 2013, Linus Walleij wrote:

> On Thu, Nov 14, 2013 at 3:22 PM, Lee Jones <lee.jones@linaro.org> wrote:
> 
> > Here we provide the FSM's register addresses, register bit names/offsets
> > and some commands which will prove useful as we start bulk the FMS's
> > driver out with functionality.
> >
> > Signed-off-by: Lee Jones <lee.jones@linaro.org>
> 
> OK...
> 
> > +/*
> > + * FSM SPI Controller Registers
> > + */
> > +#define SPI_CLOCKDIV                   0x0010
> > +#define SPI_MODESELECT                 0x0018
> > +#define SPI_CONFIGDATA                 0x0020
> (...)
> 
> So what we want to know here is whether this is a general-purpose
> SPI block, or if it's a special-purpose SPI block that can only be
> used for accessing flashes.
> 
> If it's the former that part should be broken out into drivers/spi
> of course...
> 
> But the register map seems a bit special-purpose so it could
> very well be that this is for flash control only. So maybe you can
> spill some beans from a datasheet here?
> 
> A clock divider at offset 0x10 already tells us that this is probably
> a PL022 derivate, just that we don't know how much it has
> been hacked with... does this thing contain AMBA identifiers
> at the end of the IO-region, usually at 0x0fe0 thru 0x0fff?

You've just opened a massive can of worms. Let me try to catch and put
them all back as quickly as possible.

The FSM Controller is a derivative of an SPI controller, but it's so
highly specialised that it can't do anything else but talk to Serial
Flash devices.

I've actually travelled down the route of separating the SPI
Controller parts to drivers/spi. It's possible to do that and perhaps
we could then use the generic m25p80 Serial Flash driver as the
back-end, but it would be incredibly complicated and would mean we'd
need to duplicate almost all of the m25p80 driver into the SPI
Controller. The Falcon SPI driver tried to do something similar, but
now looks broken due to some incompatible changes in m25p80. We also
want to avoid putting ourselves in that position of fragility.

There are a list of other reasons why this wouldn't work well. I have
asked the original author of this driver (whom I've spent quite a few
hours in face-to-face meetings with over the past couple of weeks) to 
jot them all down so I can reply to these kinds of requests, but I
just don't have it yet.

Take my word for it for now and I'll get back to you when I can.

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH 02/10] mtd: st_spi_fsm: Supply all register address and bit logic defines
  2013-11-18  9:32     ` Lee Jones
@ 2013-11-18 13:39       ` Mark Brown
  2013-11-18 14:24         ` Lee Jones
  0 siblings, 1 reply; 25+ messages in thread
From: Mark Brown @ 2013-11-18 13:39 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Nov 18, 2013 at 09:32:29AM +0000, Lee Jones wrote:

> I've actually travelled down the route of separating the SPI
> Controller parts to drivers/spi. It's possible to do that and perhaps
> we could then use the generic m25p80 Serial Flash driver as the
> back-end, but it would be incredibly complicated and would mean we'd
> need to duplicate almost all of the m25p80 driver into the SPI
> Controller. The Falcon SPI driver tried to do something similar, but
> now looks broken due to some incompatible changes in m25p80. We also
> want to avoid putting ourselves in that position of fragility.

What I've said to people doing similar drivers before is that it seems
like there should be an abstraction added in the MTD framework for SPI
flash controllers like this is that if there is genunie flash-specific
stuff going on then the mp25p80 driver ought to be split so that the
code that understands what commands to send to the flash chip is split
out from the code that actually sends those commands to the chip.  The
existing SPI support would then be a function driver for this.  This
would mean we don't need to support the flash chips multiple times.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20131118/d3234a26/attachment.sig>

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH 02/10] mtd: st_spi_fsm: Supply all register address and bit logic defines
  2013-11-18 13:39       ` Mark Brown
@ 2013-11-18 14:24         ` Lee Jones
  2013-11-18 14:45           ` Mark Brown
  0 siblings, 1 reply; 25+ messages in thread
From: Lee Jones @ 2013-11-18 14:24 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, 18 Nov 2013, Mark Brown wrote:

> On Mon, Nov 18, 2013 at 09:32:29AM +0000, Lee Jones wrote:
> 
> > I've actually travelled down the route of separating the SPI
> > Controller parts to drivers/spi. It's possible to do that and perhaps
> > we could then use the generic m25p80 Serial Flash driver as the
> > back-end, but it would be incredibly complicated and would mean we'd
> > need to duplicate almost all of the m25p80 driver into the SPI
> > Controller. The Falcon SPI driver tried to do something similar, but
> > now looks broken due to some incompatible changes in m25p80. We also
> > want to avoid putting ourselves in that position of fragility.
> 
> What I've said to people doing similar drivers before is that it seems
> like there should be an abstraction added in the MTD framework for SPI
> flash controllers like this is that if there is genunie flash-specific
> stuff going on then the mp25p80 driver ought to be split so that the
> code that understands what commands to send to the flash chip is split
> out from the code that actually sends those commands to the chip.  The
> existing SPI support would then be a function driver for this.  This
> would mean we don't need to support the flash chips multiple times.

Actually, there isn't much duplication. We reuse a subset of the
device table, but even that is extended for our use-case. The majority
of the code is setting up the register configs for every given
operation we issue on the controller. There are some parts which
'could' be bent in such a way that they could be abstracted, but not
much.

For example, we have thought about inserting a layer which handles the
type of communication that'll be utilised i.e. true SPI, or our
bespoke FSM implementation for instance. This would enable us to issue
serial_flash_write(), serial_flash_write_then_read(), ... in the m25p80
driver and not care which protocol is used. However, in reality this
won't really save a great deal of code - not in our case at least.

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH 02/10] mtd: st_spi_fsm: Supply all register address and bit logic defines
  2013-11-18 14:24         ` Lee Jones
@ 2013-11-18 14:45           ` Mark Brown
  2013-11-18 14:56             ` Lee Jones
  0 siblings, 1 reply; 25+ messages in thread
From: Mark Brown @ 2013-11-18 14:45 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Nov 18, 2013 at 02:24:47PM +0000, Lee Jones wrote:

> For example, we have thought about inserting a layer which handles the
> type of communication that'll be utilised i.e. true SPI, or our
> bespoke FSM implementation for instance. This would enable us to issue
> serial_flash_write(), serial_flash_write_then_read(), ... in the m25p80
> driver and not care which protocol is used. However, in reality this
> won't really save a great deal of code - not in our case at least.

Right, that's what I'm suggesting.  It's not so much for the code saving
as for the data saving, allowing device trees that just say "flash chip
X is connected" rather than requiring either the flash chip information
in multiple places in the kernel or (worse) have the commands added to
the DTs of individual boards using the flash chip.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20131118/f8f71139/attachment.sig>

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH 02/10] mtd: st_spi_fsm: Supply all register address and bit logic defines
  2013-11-18 14:45           ` Mark Brown
@ 2013-11-18 14:56             ` Lee Jones
  2013-11-18 15:16               ` Mark Brown
  0 siblings, 1 reply; 25+ messages in thread
From: Lee Jones @ 2013-11-18 14:56 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, 18 Nov 2013, Mark Brown wrote:

> On Mon, Nov 18, 2013 at 02:24:47PM +0000, Lee Jones wrote:
> 
> > For example, we have thought about inserting a layer which handles the
> > type of communication that'll be utilised i.e. true SPI, or our
> > bespoke FSM implementation for instance. This would enable us to issue
> > serial_flash_write(), serial_flash_write_then_read(), ... in the m25p80
> > driver and not care which protocol is used. However, in reality this
> > won't really save a great deal of code - not in our case at least.
> 
> Right, that's what I'm suggesting.  It's not so much for the code saving
> as for the data saving, allowing device trees that just say "flash chip
> X is connected" rather than requiring either the flash chip information
> in multiple places in the kernel or (worse) have the commands added to
> the DTs of individual boards using the flash chip.

I think it's a good idea for people using the m25p80, but still
doesn't effect us. All of our chips are dynamically probable. We are
moving completely away from saying anything is connected using DT or
platform data. The FSM will be registered and will dynamically add
devices based on what it can find. We have no plans to use any of the
m25p80 functionality, as it's almost completely different.

I'm keen on the reuse of frameworks and abstracting common code, but
there just isn't any in our case.

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH 02/10] mtd: st_spi_fsm: Supply all register address and bit logic defines
  2013-11-18 14:56             ` Lee Jones
@ 2013-11-18 15:16               ` Mark Brown
  2013-11-18 15:31                 ` Lee Jones
  0 siblings, 1 reply; 25+ messages in thread
From: Mark Brown @ 2013-11-18 15:16 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Nov 18, 2013 at 02:56:14PM +0000, Lee Jones wrote:

> I think it's a good idea for people using the m25p80, but still
> doesn't effect us. All of our chips are dynamically probable. We are

This doesn't seem realistic, you're assuming that system integrators
won't go and use chips you've not heard of and at least in the case of
things like quad read my understanding is that the commands aren't
standardised so the host just has to know what to write.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20131118/e8fe7650/attachment.sig>

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH 02/10] mtd: st_spi_fsm: Supply all register address and bit logic defines
  2013-11-18 15:16               ` Mark Brown
@ 2013-11-18 15:31                 ` Lee Jones
  2013-11-18 15:41                   ` Mark Brown
  0 siblings, 1 reply; 25+ messages in thread
From: Lee Jones @ 2013-11-18 15:31 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, 18 Nov 2013, Mark Brown wrote:

> On Mon, Nov 18, 2013 at 02:56:14PM +0000, Lee Jones wrote:
> 
> > I think it's a good idea for people using the m25p80, but still
> > doesn't effect us. All of our chips are dynamically probable. We are
> 
> This doesn't seem realistic, you're assuming that system integrators
> won't go and use chips you've not heard of and at least in the case of
> things like quad read my understanding is that the commands aren't
> standardised so the host just has to know what to write.

I'm not following? What are you suggesting?

After some analysis we have come to the conclusion that using m25p80
is not feasible. It makes more sense for this to be an
orthogonal/stand-alone driver.

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH 02/10] mtd: st_spi_fsm: Supply all register address and bit logic defines
  2013-11-18 15:31                 ` Lee Jones
@ 2013-11-18 15:41                   ` Mark Brown
  2013-11-18 16:02                     ` Lee Jones
  0 siblings, 1 reply; 25+ messages in thread
From: Mark Brown @ 2013-11-18 15:41 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Nov 18, 2013 at 03:31:10PM +0000, Lee Jones wrote:
> On Mon, 18 Nov 2013, Mark Brown wrote:

> > This doesn't seem realistic, you're assuming that system integrators
> > won't go and use chips you've not heard of and at least in the case of
> > things like quad read my understanding is that the commands aren't
> > standardised so the host just has to know what to write.

> I'm not following? What are you suggesting?

Like I say I'm suggesting that the bit of the code that understands the
flash chip is separate to the bit of code that knows the mechanics of
sending commands and data to the chip.

> After some analysis we have come to the conclusion that using m25p80
> is not feasible. It makes more sense for this to be an
> orthogonal/stand-alone driver.

That seems plausible for the controller side but it seems surprising for
the flash chip side.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20131118/d4aaa61c/attachment-0001.sig>

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH 02/10] mtd: st_spi_fsm: Supply all register address and bit logic defines
  2013-11-18 15:41                   ` Mark Brown
@ 2013-11-18 16:02                     ` Lee Jones
  2013-11-18 17:22                       ` Mark Brown
  0 siblings, 1 reply; 25+ messages in thread
From: Lee Jones @ 2013-11-18 16:02 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, 18 Nov 2013, Mark Brown wrote:

> On Mon, Nov 18, 2013 at 03:31:10PM +0000, Lee Jones wrote:
> > On Mon, 18 Nov 2013, Mark Brown wrote:
> 
> > > This doesn't seem realistic, you're assuming that system integrators
> > > won't go and use chips you've not heard of and at least in the case of
> > > things like quad read my understanding is that the commands aren't
> > > standardised so the host just has to know what to write.
> 
> > I'm not following? What are you suggesting?
> 
> Like I say I'm suggesting that the bit of the code that understands the
> flash chip is separate to the bit of code that knows the mechanics of
> sending commands and data to the chip.
> 
> > After some analysis we have come to the conclusion that using m25p80
> > is not feasible. It makes more sense for this to be an
> > orthogonal/stand-alone driver.
> 
> That seems plausible for the controller side but it seems surprising for
> the flash chip side.

The issue is that almost the entire driver is controller side. The
only bits that are the same (and not in all cases) are the OPCODEs,
but they are one liners (21 lines out of 1153). Most of the
controllers which use this stuff could reuse quite a bit of the m25p80
driver as they just write the message containing the OPCODE as the
m25p80 driver sets it up, but that's simply not the case with our
controller. We would have to pull the OPCODE out and based on which
one it is, we'd have to build our own message.

Put it this way, if we tried to use the m25p80 our controller driver
would most likely be twice as large and twice as complex as it is
currently, which is exactly the inverse of what we're trying to
achieve here.

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH 02/10] mtd: st_spi_fsm: Supply all register address and bit logic defines
  2013-11-18 16:02                     ` Lee Jones
@ 2013-11-18 17:22                       ` Mark Brown
  2013-11-18 17:32                         ` Lee Jones
  0 siblings, 1 reply; 25+ messages in thread
From: Mark Brown @ 2013-11-18 17:22 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Nov 18, 2013 at 04:02:26PM +0000, Lee Jones wrote:
> On Mon, 18 Nov 2013, Mark Brown wrote:

> > Like I say I'm suggesting that the bit of the code that understands the
> > flash chip is separate to the bit of code that knows the mechanics of
> > sending commands and data to the chip.

> The issue is that almost the entire driver is controller side. The
> only bits that are the same (and not in all cases) are the OPCODEs,
> but they are one liners (21 lines out of 1153). Most of the
> controllers which use this stuff could reuse quite a bit of the m25p80
> driver as they just write the message containing the OPCODE as the
> m25p80 driver sets it up, but that's simply not the case with our
> controller. We would have to pull the OPCODE out and based on which
> one it is, we'd have to build our own message.

OK, so then perhaps the abstraction here is simply to export the table
with the opcodes from the m25p80 driver so that when someone comes along
and adds a new chip they can just add it there and other drivers will
get the update too.

> Put it this way, if we tried to use the m25p80 our controller driver
> would most likely be twice as large and twice as complex as it is
> currently, which is exactly the inverse of what we're trying to
> achieve here.

If we're having to add new flashes to multiple drivers I'd not say we're
winning.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20131118/36fe5722/attachment.sig>

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH 02/10] mtd: st_spi_fsm: Supply all register address and bit logic defines
  2013-11-18 17:22                       ` Mark Brown
@ 2013-11-18 17:32                         ` Lee Jones
  2013-11-18 17:59                           ` Sourav Poddar
  2013-11-18 18:35                           ` Mark Brown
  0 siblings, 2 replies; 25+ messages in thread
From: Lee Jones @ 2013-11-18 17:32 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, 18 Nov 2013, Mark Brown wrote:

> On Mon, Nov 18, 2013 at 04:02:26PM +0000, Lee Jones wrote:
> > On Mon, 18 Nov 2013, Mark Brown wrote:
> 
> > > Like I say I'm suggesting that the bit of the code that understands the
> > > flash chip is separate to the bit of code that knows the mechanics of
> > > sending commands and data to the chip.
> 
> > The issue is that almost the entire driver is controller side. The
> > only bits that are the same (and not in all cases) are the OPCODEs,
> > but they are one liners (21 lines out of 1153). Most of the
> > controllers which use this stuff could reuse quite a bit of the m25p80
> > driver as they just write the message containing the OPCODE as the
> > m25p80 driver sets it up, but that's simply not the case with our
> > controller. We would have to pull the OPCODE out and based on which
> > one it is, we'd have to build our own message.
> 
> OK, so then perhaps the abstraction here is simply to export the table
> with the opcodes from the m25p80 driver so that when someone comes along
> and adds a new chip they can just add it there and other drivers will
> get the update too.

We could do that, although I'd have to insist on extending the current
framework to add a configuration call-back, as it's the neatest way to
configure chip specific attributes.

I can get a patch out tomorrow if the MTD guys agree. Where are they
by the way? I haven't seen hide nor hair of them since sending out the
patch set.

> > Put it this way, if we tried to use the m25p80 our controller driver
> > would most likely be twice as large and twice as complex as it is
> > currently, which is exactly the inverse of what we're trying to
> > achieve here.
> 
> If we're having to add new flashes to multiple drivers I'd not say we're
> winning.

I agree.

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH 02/10] mtd: st_spi_fsm: Supply all register address and bit logic defines
  2013-11-18 17:32                         ` Lee Jones
@ 2013-11-18 17:59                           ` Sourav Poddar
  2013-11-18 18:35                           ` Mark Brown
  1 sibling, 0 replies; 25+ messages in thread
From: Sourav Poddar @ 2013-11-18 17:59 UTC (permalink / raw)
  To: linux-arm-kernel

On Monday 18 November 2013 11:02 PM, Lee Jones wrote:
> On Mon, 18 Nov 2013, Mark Brown wrote:
>
>> On Mon, Nov 18, 2013 at 04:02:26PM +0000, Lee Jones wrote:
>>> On Mon, 18 Nov 2013, Mark Brown wrote:
>>>> Like I say I'm suggesting that the bit of the code that understands the
>>>> flash chip is separate to the bit of code that knows the mechanics of
>>>> sending commands and data to the chip.
>>> The issue is that almost the entire driver is controller side. The
>>> only bits that are the same (and not in all cases) are the OPCODEs,
>>> but they are one liners (21 lines out of 1153). Most of the
>>> controllers which use this stuff could reuse quite a bit of the m25p80
>>> driver as they just write the message containing the OPCODE as the
>>> m25p80 driver sets it up, but that's simply not the case with our
>>> controller. We would have to pull the OPCODE out and based on which
>>> one it is, we'd have to build our own message.
>> OK, so then perhaps the abstraction here is simply to export the table
>> with the opcodes from the m25p80 driver so that when someone comes along
>> and adds a new chip they can just add it there and other drivers will
>> get the update too.
> We could do that, although I'd have to insist on extending the current
> framework to add a configuration call-back, as it's the neatest way to
> configure chip specific attributes.
>
This looks like the problem which some other controllers(from ti,
freescale) are facing.
I will just summarise the problem with the ti qspi flash controller 
which I am
working on. There is a set of registers which need to be filled with flash
specific commands. One way to deal it with to provide a device tree bindings
for all the requirements(which is really cumbersome.).

Similarly, for freescale there is a LUT registers which has such flash 
requirements.

So, surely we need a way out from m25p80 driver to handle such cases.

drivers/mtd/devices/m25p80.c


int pass_flash_info () {

    u8 info[6];

      info[0] = DUMMY WR;
      info[1] = RD_OPCODE;
      info[2] - DUMMY BITS;
      ......
     .......
    spi_write(flash, info, 6)
}
Then, somehow parse this information to set up the required info.
  This is just a rough idea, and can be implemented in a better way.
>   I can get a patch out tomorrow if the MTD guys agree. Where are they
> by the way? I haven't seen hide nor hair of them since sending out the
> patch set.
>
>>> Put it this way, if we tried to use the m25p80 our controller driver
>>> would most likely be twice as large and twice as complex as it is
>>> currently, which is exactly the inverse of what we're trying to
>>> achieve here.
>> If we're having to add new flashes to multiple drivers I'd not say we're
>> winning.
> I agree.
>

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH 02/10] mtd: st_spi_fsm: Supply all register address and bit logic defines
  2013-11-18 17:32                         ` Lee Jones
  2013-11-18 17:59                           ` Sourav Poddar
@ 2013-11-18 18:35                           ` Mark Brown
  1 sibling, 0 replies; 25+ messages in thread
From: Mark Brown @ 2013-11-18 18:35 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Nov 18, 2013 at 05:32:01PM +0000, Lee Jones wrote:

> I can get a patch out tomorrow if the MTD guys agree. Where are they
> by the way? I haven't seen hide nor hair of them since sending out the
> patch set.

They tend to do big batches of things intermittently AFAICT.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20131118/4f0e1779/attachment-0001.sig>

^ permalink raw reply	[flat|nested] 25+ messages in thread

end of thread, other threads:[~2013-11-18 18:35 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-11-14 14:22 [PATCH 00/10] mtd: st_spi_fsm: Add new device Lee Jones
2013-11-14 14:22 ` [PATCH 01/10] mtd: st_spi_fsm: Allocate resources and register with MTD framework Lee Jones
2013-11-14 14:22 ` [PATCH 02/10] mtd: st_spi_fsm: Supply all register address and bit logic defines Lee Jones
2013-11-18  9:15   ` Linus Walleij
2013-11-18  9:32     ` Lee Jones
2013-11-18 13:39       ` Mark Brown
2013-11-18 14:24         ` Lee Jones
2013-11-18 14:45           ` Mark Brown
2013-11-18 14:56             ` Lee Jones
2013-11-18 15:16               ` Mark Brown
2013-11-18 15:31                 ` Lee Jones
2013-11-18 15:41                   ` Mark Brown
2013-11-18 16:02                     ` Lee Jones
2013-11-18 17:22                       ` Mark Brown
2013-11-18 17:32                         ` Lee Jones
2013-11-18 17:59                           ` Sourav Poddar
2013-11-18 18:35                           ` Mark Brown
2013-11-14 14:22 ` [PATCH 03/10] mtd: st_spi_fsm: Initialise and configure the FSM for normal working conditions Lee Jones
2013-11-14 14:22 ` [PATCH 04/10] mtd: st_spi_fsm: Supply framework for device requests Lee Jones
2013-11-14 14:22 ` [PATCH 05/10] mtd: st_spi_fsm: Supply a method to read from the FSM's FIFO Lee Jones
2013-11-14 14:22 ` [PATCH 06/10] mtd: st_spi_fsm: Supply defines for the possible flash command opcodes Lee Jones
2013-11-14 14:22 ` [PATCH 07/10] mtd: st_spi_fsm: Add support for JEDEC ID extraction Lee Jones
2013-11-14 14:22 ` [PATCH 08/10] mtd: st_spi_fsm: Provide device look-up table Lee Jones
2013-11-14 14:22 ` [PATCH 09/10] mtd: st_spi_fsm: Dynamically setup flash device based on JEDEC ID Lee Jones
2013-11-14 14:22 ` [PATCH 10/10] ARM: STi: Add support for the FSM Serial Flash Controller Lee Jones

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).