All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH u-boot v3 0/3] Add Amlogic Meson SPI Flash Controller driver
@ 2018-11-14 10:25 ` Neil Armstrong
  0 siblings, 0 replies; 23+ messages in thread
From: Neil Armstrong @ 2018-11-14 10:25 UTC (permalink / raw)
  To: u-boot

The Amlogic Meson SoCs embeds a Flash oriented SPI Controller name SPIFC.

This patchset add the driver ported from linux, but also import the regmap
regmap_read_poll_timeout() to implify the register polling in the driver.

Neil Armstrong (3):
  regmap: add regmap_read_poll_timeout() helper
  test: regmap: add regmap_read_poll_timeout test
  spi: Add Amlogic Meson SPI Flash Controller driver

 drivers/spi/Kconfig       |   8 +
 drivers/spi/Makefile      |   1 +
 drivers/spi/meson_spifc.c | 330 ++++++++++++++++++++++++++++++++++++++
 include/regmap.h          |  38 +++++
 test/dm/regmap.c          |  26 +++
 5 files changed, 403 insertions(+)
 create mode 100644 drivers/spi/meson_spifc.c

-- 
2.19.1

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

* [PATCH u-boot v3 0/3] Add Amlogic Meson SPI Flash Controller driver
@ 2018-11-14 10:25 ` Neil Armstrong
  0 siblings, 0 replies; 23+ messages in thread
From: Neil Armstrong @ 2018-11-14 10:25 UTC (permalink / raw)
  To: linus-amlogic

The Amlogic Meson SoCs embeds a Flash oriented SPI Controller name SPIFC.

This patchset add the driver ported from linux, but also import the regmap
regmap_read_poll_timeout() to implify the register polling in the driver.

Neil Armstrong (3):
  regmap: add regmap_read_poll_timeout() helper
  test: regmap: add regmap_read_poll_timeout test
  spi: Add Amlogic Meson SPI Flash Controller driver

 drivers/spi/Kconfig       |   8 +
 drivers/spi/Makefile      |   1 +
 drivers/spi/meson_spifc.c | 330 ++++++++++++++++++++++++++++++++++++++
 include/regmap.h          |  38 +++++
 test/dm/regmap.c          |  26 +++
 5 files changed, 403 insertions(+)
 create mode 100644 drivers/spi/meson_spifc.c

-- 
2.19.1

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

* [U-Boot] [PATCH u-boot v3 1/3] regmap: add regmap_read_poll_timeout() helper
  2018-11-14 10:25 ` Neil Armstrong
@ 2018-11-14 10:25   ` Neil Armstrong
  -1 siblings, 0 replies; 23+ messages in thread
From: Neil Armstrong @ 2018-11-14 10:25 UTC (permalink / raw)
  To: u-boot

Add the regmap_read_poll_timeout() macro based on the Linux implementation
to simplify register polling with configurable timeout and sleep.

Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
 include/regmap.h | 38 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/include/regmap.h b/include/regmap.h
index 6a574eaa41..cf795c455f 100644
--- a/include/regmap.h
+++ b/include/regmap.h
@@ -42,6 +42,44 @@ int regmap_read(struct regmap *map, uint offset, uint *valp);
 #define regmap_read32(map, ptr, member, valp) \
 	regmap_read(map, (uint32_t *)(ptr)->member - (uint32_t *)(ptr), valp)
 
+/**
+ * regmap_read_poll_timeout - Poll until a condition is met or a timeout occurs
+ *
+ * @map:	Regmap to read from
+ * @addr:	Offset to poll
+ * @val:	Unsigned integer variable to read the value into
+ * @cond:	Break condition (usually involving @val)
+ * @sleep_us:	Maximum time to sleep between reads in us (0 tight-loops).
+ * @timeout_ms:	Timeout in ms, 0 means never timeout
+ *
+ * Returns 0 on success and -ETIMEDOUT upon a timeout or the regmap_read
+ * error return value in case of a error read. In the two former cases,
+ * the last read value at @addr is stored in @val. Must not be called
+ * from atomic context if sleep_us or timeout_us are used.
+ *
+ * This is modelled after the regmap_read_poll_timeout macros in linux but
+ * with millisecond timeout.
+ */
+#define regmap_read_poll_timeout(map, addr, val, cond, sleep_us, timeout_ms) \
+({ \
+	unsigned long __start = get_timer(0); \
+	int __ret; \
+	for (;;) { \
+		__ret = regmap_read((map), (addr), &(val)); \
+		if (__ret) \
+			break; \
+		if (cond) \
+			break; \
+		if ((timeout_ms) && get_timer(__start) > (timeout_ms)) { \
+			__ret = regmap_read((map), (addr), &(val)); \
+			break; \
+		} \
+		if ((sleep_us)) \
+			udelay((sleep_us)); \
+	} \
+	__ret ?: ((cond) ? 0 : -ETIMEDOUT); \
+})
+
 /**
  * regmap_update_bits() - Perform a read/modify/write using a mask
  *
-- 
2.19.1

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

* [PATCH u-boot v3 1/3] regmap: add regmap_read_poll_timeout() helper
@ 2018-11-14 10:25   ` Neil Armstrong
  0 siblings, 0 replies; 23+ messages in thread
From: Neil Armstrong @ 2018-11-14 10:25 UTC (permalink / raw)
  To: linus-amlogic

Add the regmap_read_poll_timeout() macro based on the Linux implementation
to simplify register polling with configurable timeout and sleep.

Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
 include/regmap.h | 38 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/include/regmap.h b/include/regmap.h
index 6a574eaa41..cf795c455f 100644
--- a/include/regmap.h
+++ b/include/regmap.h
@@ -42,6 +42,44 @@ int regmap_read(struct regmap *map, uint offset, uint *valp);
 #define regmap_read32(map, ptr, member, valp) \
 	regmap_read(map, (uint32_t *)(ptr)->member - (uint32_t *)(ptr), valp)
 
+/**
+ * regmap_read_poll_timeout - Poll until a condition is met or a timeout occurs
+ *
+ * @map:	Regmap to read from
+ * @addr:	Offset to poll
+ * @val:	Unsigned integer variable to read the value into
+ * @cond:	Break condition (usually involving @val)
+ * @sleep_us:	Maximum time to sleep between reads in us (0 tight-loops).
+ * @timeout_ms:	Timeout in ms, 0 means never timeout
+ *
+ * Returns 0 on success and -ETIMEDOUT upon a timeout or the regmap_read
+ * error return value in case of a error read. In the two former cases,
+ * the last read value at @addr is stored in @val. Must not be called
+ * from atomic context if sleep_us or timeout_us are used.
+ *
+ * This is modelled after the regmap_read_poll_timeout macros in linux but
+ * with millisecond timeout.
+ */
+#define regmap_read_poll_timeout(map, addr, val, cond, sleep_us, timeout_ms) \
+({ \
+	unsigned long __start = get_timer(0); \
+	int __ret; \
+	for (;;) { \
+		__ret = regmap_read((map), (addr), &(val)); \
+		if (__ret) \
+			break; \
+		if (cond) \
+			break; \
+		if ((timeout_ms) && get_timer(__start) > (timeout_ms)) { \
+			__ret = regmap_read((map), (addr), &(val)); \
+			break; \
+		} \
+		if ((sleep_us)) \
+			udelay((sleep_us)); \
+	} \
+	__ret ?: ((cond) ? 0 : -ETIMEDOUT); \
+})
+
 /**
  * regmap_update_bits() - Perform a read/modify/write using a mask
  *
-- 
2.19.1

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

* [U-Boot] [PATCH u-boot v3 2/3] test: regmap: add regmap_read_poll_timeout test
  2018-11-14 10:25 ` Neil Armstrong
@ 2018-11-14 10:25   ` Neil Armstrong
  -1 siblings, 0 replies; 23+ messages in thread
From: Neil Armstrong @ 2018-11-14 10:25 UTC (permalink / raw)
  To: u-boot

Add test to regmap_read_poll_timeout() helper to check the timeout works
properly but cannot test proper condition matching since read/write calls
are not executed in sandbox.

Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
 test/dm/regmap.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/test/dm/regmap.c b/test/dm/regmap.c
index d4b86b3b03..00d61fe38c 100644
--- a/test/dm/regmap.c
+++ b/test/dm/regmap.c
@@ -116,3 +116,29 @@ static int dm_test_regmap_rw(struct unit_test_state *uts)
 }
 
 DM_TEST(dm_test_regmap_rw, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+/* Read polling test */
+static int dm_test_regmap_poll(struct unit_test_state *uts)
+{
+	struct udevice *dev;
+	struct regmap *map;
+	uint reg;
+	unsigned long start;
+
+	ut_assertok(uclass_get_device(UCLASS_SYSCON, 0, &dev));
+	map = syscon_get_regmap(dev);
+	ut_assertok_ptr(map);
+
+	start = get_timer(0);
+
+	ut_asserteq(-ETIMEDOUT,
+		    regmap_read_poll_timeout(map, 0, reg,
+					     (reg == 0xcacafafa),
+					     1, 5 * CONFIG_SYS_HZ));
+
+	ut_assert(get_timer(start) > (5 * CONFIG_SYS_HZ));
+
+	return 0;
+}
+
+DM_TEST(dm_test_regmap_poll, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
-- 
2.19.1

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

* [PATCH u-boot v3 2/3] test: regmap: add regmap_read_poll_timeout test
@ 2018-11-14 10:25   ` Neil Armstrong
  0 siblings, 0 replies; 23+ messages in thread
From: Neil Armstrong @ 2018-11-14 10:25 UTC (permalink / raw)
  To: linus-amlogic

Add test to regmap_read_poll_timeout() helper to check the timeout works
properly but cannot test proper condition matching since read/write calls
are not executed in sandbox.

Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
 test/dm/regmap.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/test/dm/regmap.c b/test/dm/regmap.c
index d4b86b3b03..00d61fe38c 100644
--- a/test/dm/regmap.c
+++ b/test/dm/regmap.c
@@ -116,3 +116,29 @@ static int dm_test_regmap_rw(struct unit_test_state *uts)
 }
 
 DM_TEST(dm_test_regmap_rw, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+/* Read polling test */
+static int dm_test_regmap_poll(struct unit_test_state *uts)
+{
+	struct udevice *dev;
+	struct regmap *map;
+	uint reg;
+	unsigned long start;
+
+	ut_assertok(uclass_get_device(UCLASS_SYSCON, 0, &dev));
+	map = syscon_get_regmap(dev);
+	ut_assertok_ptr(map);
+
+	start = get_timer(0);
+
+	ut_asserteq(-ETIMEDOUT,
+		    regmap_read_poll_timeout(map, 0, reg,
+					     (reg == 0xcacafafa),
+					     1, 5 * CONFIG_SYS_HZ));
+
+	ut_assert(get_timer(start) > (5 * CONFIG_SYS_HZ));
+
+	return 0;
+}
+
+DM_TEST(dm_test_regmap_poll, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
-- 
2.19.1

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

* [U-Boot] [PATCH u-boot v3 3/3] spi: Add Amlogic Meson SPI Flash Controller driver
  2018-11-14 10:25 ` Neil Armstrong
@ 2018-11-14 10:25   ` Neil Armstrong
  -1 siblings, 0 replies; 23+ messages in thread
From: Neil Armstrong @ 2018-11-14 10:25 UTC (permalink / raw)
  To: u-boot

The Amlogic Meson SoCs embeds a Flash oriented SPI Controller name SPIFC.
This driver, ported from the Linux meson-spi-spifc driver, add support
for this controller on the Amlogic Meson GX SoCs in U-Boot.

Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
 drivers/spi/Kconfig       |   8 +
 drivers/spi/Makefile      |   1 +
 drivers/spi/meson_spifc.c | 330 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 339 insertions(+)
 create mode 100644 drivers/spi/meson_spifc.c

diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 516188ea88..6085788481 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -116,6 +116,14 @@ config ICH_SPI
 	  access the SPI NOR flash on platforms embedding this Intel
 	  ICH IP core.
 
+config MESON_SPIFC
+	bool "Amlogic Meson SPI Flash Controller driver"
+	depends on ARCH_MESON
+	help
+	  Enable the Amlogic Meson SPI Flash Controller SPIFC) driver.
+	  This driver can be used to access the SPI NOR flash chips on
+	  Amlogic Meson SoCs.
+
 config MT7621_SPI
 	bool "MediaTek MT7621 SPI driver"
 	depends on ARCH_MT7620
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 7242ea7e40..67b42daf4e 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -31,6 +31,7 @@ obj-$(CONFIG_FSL_QSPI) += fsl_qspi.o
 obj-$(CONFIG_ICH_SPI) +=  ich.o
 obj-$(CONFIG_KIRKWOOD_SPI) += kirkwood_spi.o
 obj-$(CONFIG_LPC32XX_SSP) += lpc32xx_ssp.o
+obj-$(CONFIG_MESON_SPIFC) += meson_spifc.o
 obj-$(CONFIG_MPC8XX_SPI) += mpc8xx_spi.o
 obj-$(CONFIG_MPC8XXX_SPI) += mpc8xxx_spi.o
 obj-$(CONFIG_MT7621_SPI) += mt7621_spi.o
diff --git a/drivers/spi/meson_spifc.c b/drivers/spi/meson_spifc.c
new file mode 100644
index 0000000000..936806ea0c
--- /dev/null
+++ b/drivers/spi/meson_spifc.c
@@ -0,0 +1,330 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2014 Beniamino Galvani <b.galvani@gmail.com>
+ * Copyright (C) 2018 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ *
+ * Amlogic Meson SPI Flash Controller driver
+ */
+
+#include <common.h>
+#include <spi.h>
+#include <clk.h>
+#include <dm.h>
+#include <regmap.h>
+#include <errno.h>
+#include <asm/io.h>
+#include <linux/bitfield.h>
+
+/* register map */
+#define REG_CMD			0x00
+#define REG_ADDR		0x04
+#define REG_CTRL		0x08
+#define REG_CTRL1		0x0c
+#define REG_STATUS		0x10
+#define REG_CTRL2		0x14
+#define REG_CLOCK		0x18
+#define REG_USER		0x1c
+#define REG_USER1		0x20
+#define REG_USER2		0x24
+#define REG_USER3		0x28
+#define REG_USER4		0x2c
+#define REG_SLAVE		0x30
+#define REG_SLAVE1		0x34
+#define REG_SLAVE2		0x38
+#define REG_SLAVE3		0x3c
+#define REG_C0			0x40
+#define REG_B8			0x60
+#define REG_MAX			0x7c
+
+/* register fields */
+#define CMD_USER		BIT(18)
+#define CTRL_ENABLE_AHB		BIT(17)
+#define CLOCK_SOURCE		BIT(31)
+#define CLOCK_DIV_SHIFT		12
+#define CLOCK_DIV_MASK		(0x3f << CLOCK_DIV_SHIFT)
+#define CLOCK_CNT_HIGH_SHIFT	6
+#define CLOCK_CNT_HIGH_MASK	(0x3f << CLOCK_CNT_HIGH_SHIFT)
+#define CLOCK_CNT_LOW_SHIFT	0
+#define CLOCK_CNT_LOW_MASK	(0x3f << CLOCK_CNT_LOW_SHIFT)
+#define USER_DIN_EN_MS		BIT(0)
+#define USER_CMP_MODE		BIT(2)
+#define USER_CLK_NOT_INV	BIT(7)
+#define USER_UC_DOUT_SEL	BIT(27)
+#define USER_UC_DIN_SEL		BIT(28)
+#define USER_UC_MASK		((BIT(5) - 1) << 27)
+#define USER1_BN_UC_DOUT_SHIFT	17
+#define USER1_BN_UC_DOUT_MASK	(0xff << 16)
+#define USER1_BN_UC_DIN_SHIFT	8
+#define USER1_BN_UC_DIN_MASK	(0xff << 8)
+#define USER4_CS_POL_HIGH	BIT(23)
+#define USER4_IDLE_CLK_HIGH	BIT(29)
+#define USER4_CS_ACT		BIT(30)
+#define SLAVE_TRST_DONE		BIT(4)
+#define SLAVE_OP_MODE		BIT(30)
+#define SLAVE_SW_RST		BIT(31)
+
+#define SPIFC_BUFFER_SIZE	64
+
+struct meson_spifc_priv {
+	struct regmap			*regmap;
+	struct clk			clk;
+};
+
+/**
+ * meson_spifc_wait_ready() - wait for the current operation to terminate
+ * @spifc:	the Meson SPI device
+ * Return:	0 on success, a negative value on error
+ */
+static int meson_spifc_wait_ready(struct meson_spifc_priv *spifc)
+{
+	u32 data;
+
+	return regmap_read_poll_timeout(spifc->regmap, REG_SLAVE, data,
+					(data & SLAVE_TRST_DONE),
+					0, 5 * CONFIG_SYS_HZ);
+}
+
+/**
+ * meson_spifc_drain_buffer() - copy data from device buffer to memory
+ * @spifc:	the Meson SPI device
+ * @buf:	the destination buffer
+ * @len:	number of bytes to copy
+ */
+static void meson_spifc_drain_buffer(struct meson_spifc_priv *spifc,
+				     u8 *buf, int len)
+{
+	u32 data;
+	int i = 0;
+
+	while (i < len) {
+		regmap_read(spifc->regmap, REG_C0 + i, &data);
+
+		if (len - i >= 4) {
+			*((u32 *)buf) = data;
+			buf += 4;
+		} else {
+			memcpy(buf, &data, len - i);
+			break;
+		}
+		i += 4;
+	}
+}
+
+/**
+ * meson_spifc_fill_buffer() - copy data from memory to device buffer
+ * @spifc:	the Meson SPI device
+ * @buf:	the source buffer
+ * @len:	number of bytes to copy
+ */
+static void meson_spifc_fill_buffer(struct meson_spifc_priv *spifc,
+				    const u8 *buf, int len)
+{
+	u32 data = 0;
+	int i = 0;
+
+	while (i < len) {
+		if (len - i >= 4)
+			data = *(u32 *)buf;
+		else
+			memcpy(&data, buf, len - i);
+
+		regmap_write(spifc->regmap, REG_C0 + i, data);
+
+		buf += 4;
+		i += 4;
+	}
+}
+
+/**
+ * meson_spifc_txrx() - transfer a chunk of data
+ * @spifc:	the Meson SPI device
+ * @dout:	data buffer for TX
+ * @din:	data buffer for RX
+ * @offset:	offset of the data to transfer
+ * @len:	length of the data to transfer
+ * @last_xfer:	whether this is the last transfer of the message
+ * @last_chunk:	whether this is the last chunk of the transfer
+ * Return:	0 on success, a negative value on error
+ */
+static int meson_spifc_txrx(struct meson_spifc_priv *spifc,
+			    const u8 *dout, u8 *din, int offset,
+			    int len, bool last_xfer, bool last_chunk)
+{
+	bool keep_cs = true;
+	int ret;
+
+	if (dout)
+		meson_spifc_fill_buffer(spifc, dout + offset, len);
+
+	/* enable DOUT stage */
+	regmap_update_bits(spifc->regmap, REG_USER, USER_UC_MASK,
+			   USER_UC_DOUT_SEL);
+	regmap_write(spifc->regmap, REG_USER1,
+		     (8 * len - 1) << USER1_BN_UC_DOUT_SHIFT);
+
+	/* enable data input during DOUT */
+	regmap_update_bits(spifc->regmap, REG_USER, USER_DIN_EN_MS,
+			   USER_DIN_EN_MS);
+
+	if (last_chunk && last_xfer)
+		keep_cs = false;
+
+	regmap_update_bits(spifc->regmap, REG_USER4, USER4_CS_ACT,
+			   keep_cs ? USER4_CS_ACT : 0);
+
+	/* clear transition done bit */
+	regmap_update_bits(spifc->regmap, REG_SLAVE, SLAVE_TRST_DONE, 0);
+	/* start transfer */
+	regmap_update_bits(spifc->regmap, REG_CMD, CMD_USER, CMD_USER);
+
+	ret = meson_spifc_wait_ready(spifc);
+
+	if (!ret && din)
+		meson_spifc_drain_buffer(spifc, din + offset, len);
+
+	return ret;
+}
+
+/**
+ * meson_spifc_xfer() - perform a single transfer
+ * @dev:	the SPI controller device
+ * @bitlen:	length of the transfer
+ * @dout:	data buffer for TX
+ * @din:	data buffer for RX
+ * @flags:	transfer flags
+ * Return:	0 on success, a negative value on error
+ */
+static int meson_spifc_xfer(struct udevice *slave, unsigned int bitlen,
+			    const void *dout, void *din, unsigned long flags)
+{
+	struct meson_spifc_priv *spifc = dev_get_priv(slave->parent);
+	int blen = bitlen / 8;
+	int len, done = 0, ret = 0;
+
+	if (bitlen % 8)
+		return -EINVAL;
+
+	debug("xfer len %d (%d) dout %p din %p\n", bitlen, blen, dout, din);
+
+	regmap_update_bits(spifc->regmap, REG_CTRL, CTRL_ENABLE_AHB, 0);
+
+	while (done < blen && !ret) {
+		len = min_t(int, blen - done, SPIFC_BUFFER_SIZE);
+		ret = meson_spifc_txrx(spifc, dout, din, done, len,
+				       flags & SPI_XFER_END,
+				       done + len >= blen);
+		done += len;
+	}
+
+	regmap_update_bits(spifc->regmap, REG_CTRL, CTRL_ENABLE_AHB,
+			   CTRL_ENABLE_AHB);
+
+	return ret;
+}
+
+/**
+ * meson_spifc_set_speed() - program the clock divider
+ * @dev:	the SPI controller device
+ * @speed:	desired speed in Hz
+ */
+static int meson_spifc_set_speed(struct udevice *dev, uint speed)
+{
+	struct meson_spifc_priv *spifc = dev_get_priv(dev);
+	unsigned long parent, value;
+	int n;
+
+	parent = clk_get_rate(&spifc->clk);
+	n = max_t(int, parent / speed - 1, 1);
+
+	debug("parent %lu, speed %u, n %d\n", parent, speed, n);
+
+	value = (n << CLOCK_DIV_SHIFT) & CLOCK_DIV_MASK;
+	value |= (n << CLOCK_CNT_LOW_SHIFT) & CLOCK_CNT_LOW_MASK;
+	value |= (((n + 1) / 2 - 1) << CLOCK_CNT_HIGH_SHIFT) &
+		CLOCK_CNT_HIGH_MASK;
+
+	regmap_write(spifc->regmap, REG_CLOCK, value);
+
+	return 0;
+}
+
+/**
+ * meson_spifc_set_mode() - setups the SPI bus mode
+ * @dev:	the SPI controller device
+ * @mode:	desired mode bitfield
+ * Return:	0 on success, -ENODEV on error
+ */
+static int meson_spifc_set_mode(struct udevice *dev, uint mode)
+{
+	struct meson_spifc_priv *spifc = dev_get_priv(dev);
+
+	if (mode & (SPI_CPHA | SPI_RX_QUAD | SPI_RX_DUAL |
+		    SPI_TX_QUAD | SPI_TX_DUAL))
+		return -ENODEV;
+
+	regmap_update_bits(spifc->regmap, REG_USER, USER_CLK_NOT_INV,
+			   mode & SPI_CPOL ? USER_CLK_NOT_INV : 0);
+
+	regmap_update_bits(spifc->regmap, REG_USER4, USER4_CS_POL_HIGH,
+			   mode & SPI_CS_HIGH ? USER4_CS_POL_HIGH : 0);
+
+	return 0;
+}
+
+/**
+ * meson_spifc_hw_init() - reset and initialize the SPI controller
+ * @spifc:	the Meson SPI device
+ */
+static void meson_spifc_hw_init(struct meson_spifc_priv *spifc)
+{
+	/* reset device */
+	regmap_update_bits(spifc->regmap, REG_SLAVE, SLAVE_SW_RST,
+			   SLAVE_SW_RST);
+	/* disable compatible mode */
+	regmap_update_bits(spifc->regmap, REG_USER, USER_CMP_MODE, 0);
+	/* set master mode */
+	regmap_update_bits(spifc->regmap, REG_SLAVE, SLAVE_OP_MODE, 0);
+}
+
+static const struct dm_spi_ops meson_spifc_ops = {
+	.xfer		= meson_spifc_xfer,
+	.set_speed	= meson_spifc_set_speed,
+	.set_mode	= meson_spifc_set_mode,
+};
+
+static int meson_spifc_probe(struct udevice *dev)
+{
+	struct meson_spifc_priv *priv = dev_get_priv(dev);
+	int ret;
+
+	ret = regmap_init_mem(dev_ofnode(dev), &priv->regmap);
+	if (ret)
+		return ret;
+
+	ret = clk_get_by_index(dev, 0, &priv->clk);
+	if (ret)
+		return ret;
+
+	ret = clk_enable(&priv->clk);
+	if (ret)
+		return ret;
+
+	meson_spifc_hw_init(priv);
+
+	return 0;
+}
+
+static const struct udevice_id meson_spifc_ids[] = {
+	{ .compatible = "amlogic,meson-gxbb-spifc", },
+	{ }
+};
+
+U_BOOT_DRIVER(meson_spifc) = {
+	.name		= "meson_spifc",
+	.id		= UCLASS_SPI,
+	.of_match	= meson_spifc_ids,
+	.ops		= &meson_spifc_ops,
+	.probe		= meson_spifc_probe,
+	.priv_auto_alloc_size = sizeof(struct meson_spifc_priv),
+};
-- 
2.19.1

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

* [PATCH u-boot v3 3/3] spi: Add Amlogic Meson SPI Flash Controller driver
@ 2018-11-14 10:25   ` Neil Armstrong
  0 siblings, 0 replies; 23+ messages in thread
From: Neil Armstrong @ 2018-11-14 10:25 UTC (permalink / raw)
  To: linus-amlogic

The Amlogic Meson SoCs embeds a Flash oriented SPI Controller name SPIFC.
This driver, ported from the Linux meson-spi-spifc driver, add support
for this controller on the Amlogic Meson GX SoCs in U-Boot.

Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
 drivers/spi/Kconfig       |   8 +
 drivers/spi/Makefile      |   1 +
 drivers/spi/meson_spifc.c | 330 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 339 insertions(+)
 create mode 100644 drivers/spi/meson_spifc.c

diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 516188ea88..6085788481 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -116,6 +116,14 @@ config ICH_SPI
 	  access the SPI NOR flash on platforms embedding this Intel
 	  ICH IP core.
 
+config MESON_SPIFC
+	bool "Amlogic Meson SPI Flash Controller driver"
+	depends on ARCH_MESON
+	help
+	  Enable the Amlogic Meson SPI Flash Controller SPIFC) driver.
+	  This driver can be used to access the SPI NOR flash chips on
+	  Amlogic Meson SoCs.
+
 config MT7621_SPI
 	bool "MediaTek MT7621 SPI driver"
 	depends on ARCH_MT7620
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 7242ea7e40..67b42daf4e 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -31,6 +31,7 @@ obj-$(CONFIG_FSL_QSPI) += fsl_qspi.o
 obj-$(CONFIG_ICH_SPI) +=  ich.o
 obj-$(CONFIG_KIRKWOOD_SPI) += kirkwood_spi.o
 obj-$(CONFIG_LPC32XX_SSP) += lpc32xx_ssp.o
+obj-$(CONFIG_MESON_SPIFC) += meson_spifc.o
 obj-$(CONFIG_MPC8XX_SPI) += mpc8xx_spi.o
 obj-$(CONFIG_MPC8XXX_SPI) += mpc8xxx_spi.o
 obj-$(CONFIG_MT7621_SPI) += mt7621_spi.o
diff --git a/drivers/spi/meson_spifc.c b/drivers/spi/meson_spifc.c
new file mode 100644
index 0000000000..936806ea0c
--- /dev/null
+++ b/drivers/spi/meson_spifc.c
@@ -0,0 +1,330 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2014 Beniamino Galvani <b.galvani@gmail.com>
+ * Copyright (C) 2018 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ *
+ * Amlogic Meson SPI Flash Controller driver
+ */
+
+#include <common.h>
+#include <spi.h>
+#include <clk.h>
+#include <dm.h>
+#include <regmap.h>
+#include <errno.h>
+#include <asm/io.h>
+#include <linux/bitfield.h>
+
+/* register map */
+#define REG_CMD			0x00
+#define REG_ADDR		0x04
+#define REG_CTRL		0x08
+#define REG_CTRL1		0x0c
+#define REG_STATUS		0x10
+#define REG_CTRL2		0x14
+#define REG_CLOCK		0x18
+#define REG_USER		0x1c
+#define REG_USER1		0x20
+#define REG_USER2		0x24
+#define REG_USER3		0x28
+#define REG_USER4		0x2c
+#define REG_SLAVE		0x30
+#define REG_SLAVE1		0x34
+#define REG_SLAVE2		0x38
+#define REG_SLAVE3		0x3c
+#define REG_C0			0x40
+#define REG_B8			0x60
+#define REG_MAX			0x7c
+
+/* register fields */
+#define CMD_USER		BIT(18)
+#define CTRL_ENABLE_AHB		BIT(17)
+#define CLOCK_SOURCE		BIT(31)
+#define CLOCK_DIV_SHIFT		12
+#define CLOCK_DIV_MASK		(0x3f << CLOCK_DIV_SHIFT)
+#define CLOCK_CNT_HIGH_SHIFT	6
+#define CLOCK_CNT_HIGH_MASK	(0x3f << CLOCK_CNT_HIGH_SHIFT)
+#define CLOCK_CNT_LOW_SHIFT	0
+#define CLOCK_CNT_LOW_MASK	(0x3f << CLOCK_CNT_LOW_SHIFT)
+#define USER_DIN_EN_MS		BIT(0)
+#define USER_CMP_MODE		BIT(2)
+#define USER_CLK_NOT_INV	BIT(7)
+#define USER_UC_DOUT_SEL	BIT(27)
+#define USER_UC_DIN_SEL		BIT(28)
+#define USER_UC_MASK		((BIT(5) - 1) << 27)
+#define USER1_BN_UC_DOUT_SHIFT	17
+#define USER1_BN_UC_DOUT_MASK	(0xff << 16)
+#define USER1_BN_UC_DIN_SHIFT	8
+#define USER1_BN_UC_DIN_MASK	(0xff << 8)
+#define USER4_CS_POL_HIGH	BIT(23)
+#define USER4_IDLE_CLK_HIGH	BIT(29)
+#define USER4_CS_ACT		BIT(30)
+#define SLAVE_TRST_DONE		BIT(4)
+#define SLAVE_OP_MODE		BIT(30)
+#define SLAVE_SW_RST		BIT(31)
+
+#define SPIFC_BUFFER_SIZE	64
+
+struct meson_spifc_priv {
+	struct regmap			*regmap;
+	struct clk			clk;
+};
+
+/**
+ * meson_spifc_wait_ready() - wait for the current operation to terminate
+ * @spifc:	the Meson SPI device
+ * Return:	0 on success, a negative value on error
+ */
+static int meson_spifc_wait_ready(struct meson_spifc_priv *spifc)
+{
+	u32 data;
+
+	return regmap_read_poll_timeout(spifc->regmap, REG_SLAVE, data,
+					(data & SLAVE_TRST_DONE),
+					0, 5 * CONFIG_SYS_HZ);
+}
+
+/**
+ * meson_spifc_drain_buffer() - copy data from device buffer to memory
+ * @spifc:	the Meson SPI device
+ * @buf:	the destination buffer
+ * @len:	number of bytes to copy
+ */
+static void meson_spifc_drain_buffer(struct meson_spifc_priv *spifc,
+				     u8 *buf, int len)
+{
+	u32 data;
+	int i = 0;
+
+	while (i < len) {
+		regmap_read(spifc->regmap, REG_C0 + i, &data);
+
+		if (len - i >= 4) {
+			*((u32 *)buf) = data;
+			buf += 4;
+		} else {
+			memcpy(buf, &data, len - i);
+			break;
+		}
+		i += 4;
+	}
+}
+
+/**
+ * meson_spifc_fill_buffer() - copy data from memory to device buffer
+ * @spifc:	the Meson SPI device
+ * @buf:	the source buffer
+ * @len:	number of bytes to copy
+ */
+static void meson_spifc_fill_buffer(struct meson_spifc_priv *spifc,
+				    const u8 *buf, int len)
+{
+	u32 data = 0;
+	int i = 0;
+
+	while (i < len) {
+		if (len - i >= 4)
+			data = *(u32 *)buf;
+		else
+			memcpy(&data, buf, len - i);
+
+		regmap_write(spifc->regmap, REG_C0 + i, data);
+
+		buf += 4;
+		i += 4;
+	}
+}
+
+/**
+ * meson_spifc_txrx() - transfer a chunk of data
+ * @spifc:	the Meson SPI device
+ * @dout:	data buffer for TX
+ * @din:	data buffer for RX
+ * @offset:	offset of the data to transfer
+ * @len:	length of the data to transfer
+ * @last_xfer:	whether this is the last transfer of the message
+ * @last_chunk:	whether this is the last chunk of the transfer
+ * Return:	0 on success, a negative value on error
+ */
+static int meson_spifc_txrx(struct meson_spifc_priv *spifc,
+			    const u8 *dout, u8 *din, int offset,
+			    int len, bool last_xfer, bool last_chunk)
+{
+	bool keep_cs = true;
+	int ret;
+
+	if (dout)
+		meson_spifc_fill_buffer(spifc, dout + offset, len);
+
+	/* enable DOUT stage */
+	regmap_update_bits(spifc->regmap, REG_USER, USER_UC_MASK,
+			   USER_UC_DOUT_SEL);
+	regmap_write(spifc->regmap, REG_USER1,
+		     (8 * len - 1) << USER1_BN_UC_DOUT_SHIFT);
+
+	/* enable data input during DOUT */
+	regmap_update_bits(spifc->regmap, REG_USER, USER_DIN_EN_MS,
+			   USER_DIN_EN_MS);
+
+	if (last_chunk && last_xfer)
+		keep_cs = false;
+
+	regmap_update_bits(spifc->regmap, REG_USER4, USER4_CS_ACT,
+			   keep_cs ? USER4_CS_ACT : 0);
+
+	/* clear transition done bit */
+	regmap_update_bits(spifc->regmap, REG_SLAVE, SLAVE_TRST_DONE, 0);
+	/* start transfer */
+	regmap_update_bits(spifc->regmap, REG_CMD, CMD_USER, CMD_USER);
+
+	ret = meson_spifc_wait_ready(spifc);
+
+	if (!ret && din)
+		meson_spifc_drain_buffer(spifc, din + offset, len);
+
+	return ret;
+}
+
+/**
+ * meson_spifc_xfer() - perform a single transfer
+ * @dev:	the SPI controller device
+ * @bitlen:	length of the transfer
+ * @dout:	data buffer for TX
+ * @din:	data buffer for RX
+ * @flags:	transfer flags
+ * Return:	0 on success, a negative value on error
+ */
+static int meson_spifc_xfer(struct udevice *slave, unsigned int bitlen,
+			    const void *dout, void *din, unsigned long flags)
+{
+	struct meson_spifc_priv *spifc = dev_get_priv(slave->parent);
+	int blen = bitlen / 8;
+	int len, done = 0, ret = 0;
+
+	if (bitlen % 8)
+		return -EINVAL;
+
+	debug("xfer len %d (%d) dout %p din %p\n", bitlen, blen, dout, din);
+
+	regmap_update_bits(spifc->regmap, REG_CTRL, CTRL_ENABLE_AHB, 0);
+
+	while (done < blen && !ret) {
+		len = min_t(int, blen - done, SPIFC_BUFFER_SIZE);
+		ret = meson_spifc_txrx(spifc, dout, din, done, len,
+				       flags & SPI_XFER_END,
+				       done + len >= blen);
+		done += len;
+	}
+
+	regmap_update_bits(spifc->regmap, REG_CTRL, CTRL_ENABLE_AHB,
+			   CTRL_ENABLE_AHB);
+
+	return ret;
+}
+
+/**
+ * meson_spifc_set_speed() - program the clock divider
+ * @dev:	the SPI controller device
+ * @speed:	desired speed in Hz
+ */
+static int meson_spifc_set_speed(struct udevice *dev, uint speed)
+{
+	struct meson_spifc_priv *spifc = dev_get_priv(dev);
+	unsigned long parent, value;
+	int n;
+
+	parent = clk_get_rate(&spifc->clk);
+	n = max_t(int, parent / speed - 1, 1);
+
+	debug("parent %lu, speed %u, n %d\n", parent, speed, n);
+
+	value = (n << CLOCK_DIV_SHIFT) & CLOCK_DIV_MASK;
+	value |= (n << CLOCK_CNT_LOW_SHIFT) & CLOCK_CNT_LOW_MASK;
+	value |= (((n + 1) / 2 - 1) << CLOCK_CNT_HIGH_SHIFT) &
+		CLOCK_CNT_HIGH_MASK;
+
+	regmap_write(spifc->regmap, REG_CLOCK, value);
+
+	return 0;
+}
+
+/**
+ * meson_spifc_set_mode() - setups the SPI bus mode
+ * @dev:	the SPI controller device
+ * @mode:	desired mode bitfield
+ * Return:	0 on success, -ENODEV on error
+ */
+static int meson_spifc_set_mode(struct udevice *dev, uint mode)
+{
+	struct meson_spifc_priv *spifc = dev_get_priv(dev);
+
+	if (mode & (SPI_CPHA | SPI_RX_QUAD | SPI_RX_DUAL |
+		    SPI_TX_QUAD | SPI_TX_DUAL))
+		return -ENODEV;
+
+	regmap_update_bits(spifc->regmap, REG_USER, USER_CLK_NOT_INV,
+			   mode & SPI_CPOL ? USER_CLK_NOT_INV : 0);
+
+	regmap_update_bits(spifc->regmap, REG_USER4, USER4_CS_POL_HIGH,
+			   mode & SPI_CS_HIGH ? USER4_CS_POL_HIGH : 0);
+
+	return 0;
+}
+
+/**
+ * meson_spifc_hw_init() - reset and initialize the SPI controller
+ * @spifc:	the Meson SPI device
+ */
+static void meson_spifc_hw_init(struct meson_spifc_priv *spifc)
+{
+	/* reset device */
+	regmap_update_bits(spifc->regmap, REG_SLAVE, SLAVE_SW_RST,
+			   SLAVE_SW_RST);
+	/* disable compatible mode */
+	regmap_update_bits(spifc->regmap, REG_USER, USER_CMP_MODE, 0);
+	/* set master mode */
+	regmap_update_bits(spifc->regmap, REG_SLAVE, SLAVE_OP_MODE, 0);
+}
+
+static const struct dm_spi_ops meson_spifc_ops = {
+	.xfer		= meson_spifc_xfer,
+	.set_speed	= meson_spifc_set_speed,
+	.set_mode	= meson_spifc_set_mode,
+};
+
+static int meson_spifc_probe(struct udevice *dev)
+{
+	struct meson_spifc_priv *priv = dev_get_priv(dev);
+	int ret;
+
+	ret = regmap_init_mem(dev_ofnode(dev), &priv->regmap);
+	if (ret)
+		return ret;
+
+	ret = clk_get_by_index(dev, 0, &priv->clk);
+	if (ret)
+		return ret;
+
+	ret = clk_enable(&priv->clk);
+	if (ret)
+		return ret;
+
+	meson_spifc_hw_init(priv);
+
+	return 0;
+}
+
+static const struct udevice_id meson_spifc_ids[] = {
+	{ .compatible = "amlogic,meson-gxbb-spifc", },
+	{ }
+};
+
+U_BOOT_DRIVER(meson_spifc) = {
+	.name		= "meson_spifc",
+	.id		= UCLASS_SPI,
+	.of_match	= meson_spifc_ids,
+	.ops		= &meson_spifc_ops,
+	.probe		= meson_spifc_probe,
+	.priv_auto_alloc_size = sizeof(struct meson_spifc_priv),
+};
-- 
2.19.1

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

* [U-Boot] [PATCH u-boot v3 1/3] regmap: add regmap_read_poll_timeout() helper
  2018-11-14 10:25   ` Neil Armstrong
@ 2018-11-14 13:09     ` Jagan Teki
  -1 siblings, 0 replies; 23+ messages in thread
From: Jagan Teki @ 2018-11-14 13:09 UTC (permalink / raw)
  To: u-boot

On Wed, Nov 14, 2018 at 3:57 PM Neil Armstrong <narmstrong@baylibre.com> wrote:
>
> Add the regmap_read_poll_timeout() macro based on the Linux implementation
> to simplify register polling with configurable timeout and sleep.
>
> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
> ---

Acked-by: Jagan Teki <jagan@openedev.com>

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

* [U-Boot] [PATCH u-boot v3 1/3] regmap: add regmap_read_poll_timeout() helper
@ 2018-11-14 13:09     ` Jagan Teki
  0 siblings, 0 replies; 23+ messages in thread
From: Jagan Teki @ 2018-11-14 13:09 UTC (permalink / raw)
  To: linus-amlogic

On Wed, Nov 14, 2018 at 3:57 PM Neil Armstrong <narmstrong@baylibre.com> wrote:
>
> Add the regmap_read_poll_timeout() macro based on the Linux implementation
> to simplify register polling with configurable timeout and sleep.
>
> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
> ---

Acked-by: Jagan Teki <jagan@openedev.com>

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

* [U-Boot] [PATCH u-boot v3 2/3] test: regmap: add regmap_read_poll_timeout test
  2018-11-14 10:25   ` Neil Armstrong
@ 2018-11-14 13:09     ` Jagan Teki
  -1 siblings, 0 replies; 23+ messages in thread
From: Jagan Teki @ 2018-11-14 13:09 UTC (permalink / raw)
  To: u-boot

On Wed, Nov 14, 2018 at 3:57 PM Neil Armstrong <narmstrong@baylibre.com> wrote:
>
> Add test to regmap_read_poll_timeout() helper to check the timeout works
> properly but cannot test proper condition matching since read/write calls
> are not executed in sandbox.
>
> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
> ---

Acked-by: Jagan Teki <jagan@openedev.com>

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

* [U-Boot] [PATCH u-boot v3 2/3] test: regmap: add regmap_read_poll_timeout test
@ 2018-11-14 13:09     ` Jagan Teki
  0 siblings, 0 replies; 23+ messages in thread
From: Jagan Teki @ 2018-11-14 13:09 UTC (permalink / raw)
  To: linus-amlogic

On Wed, Nov 14, 2018 at 3:57 PM Neil Armstrong <narmstrong@baylibre.com> wrote:
>
> Add test to regmap_read_poll_timeout() helper to check the timeout works
> properly but cannot test proper condition matching since read/write calls
> are not executed in sandbox.
>
> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
> ---

Acked-by: Jagan Teki <jagan@openedev.com>

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

* [U-Boot] [PATCH u-boot v3 3/3] spi: Add Amlogic Meson SPI Flash Controller driver
  2018-11-14 10:25   ` Neil Armstrong
@ 2018-11-14 13:11     ` Jagan Teki
  -1 siblings, 0 replies; 23+ messages in thread
From: Jagan Teki @ 2018-11-14 13:11 UTC (permalink / raw)
  To: u-boot

On Wed, Nov 14, 2018 at 3:57 PM Neil Armstrong <narmstrong@baylibre.com> wrote:
>
> The Amlogic Meson SoCs embeds a Flash oriented SPI Controller name SPIFC.
> This driver, ported from the Linux meson-spi-spifc driver, add support
> for this controller on the Amlogic Meson GX SoCs in U-Boot.
>
> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
> ---
>  drivers/spi/Kconfig       |   8 +
>  drivers/spi/Makefile      |   1 +
>  drivers/spi/meson_spifc.c | 330 ++++++++++++++++++++++++++++++++++++++
>  3 files changed, 339 insertions(+)
>  create mode 100644 drivers/spi/meson_spifc.c
>
> diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
> index 516188ea88..6085788481 100644
> --- a/drivers/spi/Kconfig
> +++ b/drivers/spi/Kconfig
> @@ -116,6 +116,14 @@ config ICH_SPI
>           access the SPI NOR flash on platforms embedding this Intel
>           ICH IP core.
>
> +config MESON_SPIFC
> +       bool "Amlogic Meson SPI Flash Controller driver"
> +       depends on ARCH_MESON
> +       help
> +         Enable the Amlogic Meson SPI Flash Controller SPIFC) driver.
> +         This driver can be used to access the SPI NOR flash chips on
> +         Amlogic Meson SoCs.
> +
>  config MT7621_SPI
>         bool "MediaTek MT7621 SPI driver"
>         depends on ARCH_MT7620
> diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
> index 7242ea7e40..67b42daf4e 100644
> --- a/drivers/spi/Makefile
> +++ b/drivers/spi/Makefile
> @@ -31,6 +31,7 @@ obj-$(CONFIG_FSL_QSPI) += fsl_qspi.o
>  obj-$(CONFIG_ICH_SPI) +=  ich.o
>  obj-$(CONFIG_KIRKWOOD_SPI) += kirkwood_spi.o
>  obj-$(CONFIG_LPC32XX_SSP) += lpc32xx_ssp.o
> +obj-$(CONFIG_MESON_SPIFC) += meson_spifc.o
>  obj-$(CONFIG_MPC8XX_SPI) += mpc8xx_spi.o
>  obj-$(CONFIG_MPC8XXX_SPI) += mpc8xxx_spi.o
>  obj-$(CONFIG_MT7621_SPI) += mt7621_spi.o
> diff --git a/drivers/spi/meson_spifc.c b/drivers/spi/meson_spifc.c
> new file mode 100644
> index 0000000000..936806ea0c
> --- /dev/null
> +++ b/drivers/spi/meson_spifc.c
> @@ -0,0 +1,330 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2014 Beniamino Galvani <b.galvani@gmail.com>
> + * Copyright (C) 2018 BayLibre, SAS
> + * Author: Neil Armstrong <narmstrong@baylibre.com>
> + *
> + * Amlogic Meson SPI Flash Controller driver
> + */
> +
> +#include <common.h>
> +#include <spi.h>
> +#include <clk.h>
> +#include <dm.h>
> +#include <regmap.h>
> +#include <errno.h>
> +#include <asm/io.h>
> +#include <linux/bitfield.h>
> +
> +/* register map */
> +#define REG_CMD                        0x00
> +#define REG_ADDR               0x04
> +#define REG_CTRL               0x08
> +#define REG_CTRL1              0x0c
> +#define REG_STATUS             0x10
> +#define REG_CTRL2              0x14
> +#define REG_CLOCK              0x18
> +#define REG_USER               0x1c
> +#define REG_USER1              0x20
> +#define REG_USER2              0x24
> +#define REG_USER3              0x28
> +#define REG_USER4              0x2c
> +#define REG_SLAVE              0x30
> +#define REG_SLAVE1             0x34
> +#define REG_SLAVE2             0x38
> +#define REG_SLAVE3             0x3c
> +#define REG_C0                 0x40
> +#define REG_B8                 0x60
> +#define REG_MAX                        0x7c
> +
> +/* register fields */
> +#define CMD_USER               BIT(18)
> +#define CTRL_ENABLE_AHB                BIT(17)
> +#define CLOCK_SOURCE           BIT(31)
> +#define CLOCK_DIV_SHIFT                12
> +#define CLOCK_DIV_MASK         (0x3f << CLOCK_DIV_SHIFT)
> +#define CLOCK_CNT_HIGH_SHIFT   6
> +#define CLOCK_CNT_HIGH_MASK    (0x3f << CLOCK_CNT_HIGH_SHIFT)
> +#define CLOCK_CNT_LOW_SHIFT    0
> +#define CLOCK_CNT_LOW_MASK     (0x3f << CLOCK_CNT_LOW_SHIFT)
> +#define USER_DIN_EN_MS         BIT(0)
> +#define USER_CMP_MODE          BIT(2)
> +#define USER_CLK_NOT_INV       BIT(7)
> +#define USER_UC_DOUT_SEL       BIT(27)
> +#define USER_UC_DIN_SEL                BIT(28)
> +#define USER_UC_MASK           ((BIT(5) - 1) << 27)
> +#define USER1_BN_UC_DOUT_SHIFT 17
> +#define USER1_BN_UC_DOUT_MASK  (0xff << 16)
> +#define USER1_BN_UC_DIN_SHIFT  8
> +#define USER1_BN_UC_DIN_MASK   (0xff << 8)
> +#define USER4_CS_POL_HIGH      BIT(23)
> +#define USER4_IDLE_CLK_HIGH    BIT(29)
> +#define USER4_CS_ACT           BIT(30)
> +#define SLAVE_TRST_DONE                BIT(4)
> +#define SLAVE_OP_MODE          BIT(30)
> +#define SLAVE_SW_RST           BIT(31)
> +
> +#define SPIFC_BUFFER_SIZE      64
> +
> +struct meson_spifc_priv {
> +       struct regmap                   *regmap;
> +       struct clk                      clk;
> +};
> +
> +/**
> + * meson_spifc_wait_ready() - wait for the current operation to terminate
> + * @spifc:     the Meson SPI device
> + * Return:     0 on success, a negative value on error
> + */
> +static int meson_spifc_wait_ready(struct meson_spifc_priv *spifc)
> +{
> +       u32 data;
> +
> +       return regmap_read_poll_timeout(spifc->regmap, REG_SLAVE, data,
> +                                       (data & SLAVE_TRST_DONE),
> +                                       0, 5 * CONFIG_SYS_HZ);
> +}

We can call poll_timeout directly w/o separate function, since we have
only one call. I can do that while applying if you are OK?

Reviewed-by: Jagan Teki <jagan@openedev.com>

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

* [U-Boot] [PATCH u-boot v3 3/3] spi: Add Amlogic Meson SPI Flash Controller driver
@ 2018-11-14 13:11     ` Jagan Teki
  0 siblings, 0 replies; 23+ messages in thread
From: Jagan Teki @ 2018-11-14 13:11 UTC (permalink / raw)
  To: linus-amlogic

On Wed, Nov 14, 2018 at 3:57 PM Neil Armstrong <narmstrong@baylibre.com> wrote:
>
> The Amlogic Meson SoCs embeds a Flash oriented SPI Controller name SPIFC.
> This driver, ported from the Linux meson-spi-spifc driver, add support
> for this controller on the Amlogic Meson GX SoCs in U-Boot.
>
> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
> ---
>  drivers/spi/Kconfig       |   8 +
>  drivers/spi/Makefile      |   1 +
>  drivers/spi/meson_spifc.c | 330 ++++++++++++++++++++++++++++++++++++++
>  3 files changed, 339 insertions(+)
>  create mode 100644 drivers/spi/meson_spifc.c
>
> diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
> index 516188ea88..6085788481 100644
> --- a/drivers/spi/Kconfig
> +++ b/drivers/spi/Kconfig
> @@ -116,6 +116,14 @@ config ICH_SPI
>           access the SPI NOR flash on platforms embedding this Intel
>           ICH IP core.
>
> +config MESON_SPIFC
> +       bool "Amlogic Meson SPI Flash Controller driver"
> +       depends on ARCH_MESON
> +       help
> +         Enable the Amlogic Meson SPI Flash Controller SPIFC) driver.
> +         This driver can be used to access the SPI NOR flash chips on
> +         Amlogic Meson SoCs.
> +
>  config MT7621_SPI
>         bool "MediaTek MT7621 SPI driver"
>         depends on ARCH_MT7620
> diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
> index 7242ea7e40..67b42daf4e 100644
> --- a/drivers/spi/Makefile
> +++ b/drivers/spi/Makefile
> @@ -31,6 +31,7 @@ obj-$(CONFIG_FSL_QSPI) += fsl_qspi.o
>  obj-$(CONFIG_ICH_SPI) +=  ich.o
>  obj-$(CONFIG_KIRKWOOD_SPI) += kirkwood_spi.o
>  obj-$(CONFIG_LPC32XX_SSP) += lpc32xx_ssp.o
> +obj-$(CONFIG_MESON_SPIFC) += meson_spifc.o
>  obj-$(CONFIG_MPC8XX_SPI) += mpc8xx_spi.o
>  obj-$(CONFIG_MPC8XXX_SPI) += mpc8xxx_spi.o
>  obj-$(CONFIG_MT7621_SPI) += mt7621_spi.o
> diff --git a/drivers/spi/meson_spifc.c b/drivers/spi/meson_spifc.c
> new file mode 100644
> index 0000000000..936806ea0c
> --- /dev/null
> +++ b/drivers/spi/meson_spifc.c
> @@ -0,0 +1,330 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2014 Beniamino Galvani <b.galvani@gmail.com>
> + * Copyright (C) 2018 BayLibre, SAS
> + * Author: Neil Armstrong <narmstrong@baylibre.com>
> + *
> + * Amlogic Meson SPI Flash Controller driver
> + */
> +
> +#include <common.h>
> +#include <spi.h>
> +#include <clk.h>
> +#include <dm.h>
> +#include <regmap.h>
> +#include <errno.h>
> +#include <asm/io.h>
> +#include <linux/bitfield.h>
> +
> +/* register map */
> +#define REG_CMD                        0x00
> +#define REG_ADDR               0x04
> +#define REG_CTRL               0x08
> +#define REG_CTRL1              0x0c
> +#define REG_STATUS             0x10
> +#define REG_CTRL2              0x14
> +#define REG_CLOCK              0x18
> +#define REG_USER               0x1c
> +#define REG_USER1              0x20
> +#define REG_USER2              0x24
> +#define REG_USER3              0x28
> +#define REG_USER4              0x2c
> +#define REG_SLAVE              0x30
> +#define REG_SLAVE1             0x34
> +#define REG_SLAVE2             0x38
> +#define REG_SLAVE3             0x3c
> +#define REG_C0                 0x40
> +#define REG_B8                 0x60
> +#define REG_MAX                        0x7c
> +
> +/* register fields */
> +#define CMD_USER               BIT(18)
> +#define CTRL_ENABLE_AHB                BIT(17)
> +#define CLOCK_SOURCE           BIT(31)
> +#define CLOCK_DIV_SHIFT                12
> +#define CLOCK_DIV_MASK         (0x3f << CLOCK_DIV_SHIFT)
> +#define CLOCK_CNT_HIGH_SHIFT   6
> +#define CLOCK_CNT_HIGH_MASK    (0x3f << CLOCK_CNT_HIGH_SHIFT)
> +#define CLOCK_CNT_LOW_SHIFT    0
> +#define CLOCK_CNT_LOW_MASK     (0x3f << CLOCK_CNT_LOW_SHIFT)
> +#define USER_DIN_EN_MS         BIT(0)
> +#define USER_CMP_MODE          BIT(2)
> +#define USER_CLK_NOT_INV       BIT(7)
> +#define USER_UC_DOUT_SEL       BIT(27)
> +#define USER_UC_DIN_SEL                BIT(28)
> +#define USER_UC_MASK           ((BIT(5) - 1) << 27)
> +#define USER1_BN_UC_DOUT_SHIFT 17
> +#define USER1_BN_UC_DOUT_MASK  (0xff << 16)
> +#define USER1_BN_UC_DIN_SHIFT  8
> +#define USER1_BN_UC_DIN_MASK   (0xff << 8)
> +#define USER4_CS_POL_HIGH      BIT(23)
> +#define USER4_IDLE_CLK_HIGH    BIT(29)
> +#define USER4_CS_ACT           BIT(30)
> +#define SLAVE_TRST_DONE                BIT(4)
> +#define SLAVE_OP_MODE          BIT(30)
> +#define SLAVE_SW_RST           BIT(31)
> +
> +#define SPIFC_BUFFER_SIZE      64
> +
> +struct meson_spifc_priv {
> +       struct regmap                   *regmap;
> +       struct clk                      clk;
> +};
> +
> +/**
> + * meson_spifc_wait_ready() - wait for the current operation to terminate
> + * @spifc:     the Meson SPI device
> + * Return:     0 on success, a negative value on error
> + */
> +static int meson_spifc_wait_ready(struct meson_spifc_priv *spifc)
> +{
> +       u32 data;
> +
> +       return regmap_read_poll_timeout(spifc->regmap, REG_SLAVE, data,
> +                                       (data & SLAVE_TRST_DONE),
> +                                       0, 5 * CONFIG_SYS_HZ);
> +}

We can call poll_timeout directly w/o separate function, since we have
only one call. I can do that while applying if you are OK?

Reviewed-by: Jagan Teki <jagan@openedev.com>

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

* [U-Boot] [PATCH u-boot v3 3/3] spi: Add Amlogic Meson SPI Flash Controller driver
  2018-11-14 13:11     ` Jagan Teki
@ 2018-11-14 13:12       ` Neil Armstrong
  -1 siblings, 0 replies; 23+ messages in thread
From: Neil Armstrong @ 2018-11-14 13:12 UTC (permalink / raw)
  To: u-boot

On 14/11/2018 14:11, Jagan Teki wrote:
> On Wed, Nov 14, 2018 at 3:57 PM Neil Armstrong <narmstrong@baylibre.com> wrote:
>>
>> The Amlogic Meson SoCs embeds a Flash oriented SPI Controller name SPIFC.
>> This driver, ported from the Linux meson-spi-spifc driver, add support
>> for this controller on the Amlogic Meson GX SoCs in U-Boot.
>>
>> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
>> ---
>>  drivers/spi/Kconfig       |   8 +
>>  drivers/spi/Makefile      |   1 +
>>  drivers/spi/meson_spifc.c | 330 ++++++++++++++++++++++++++++++++++++++
>>  3 files changed, 339 insertions(+)
>>  create mode 100644 drivers/spi/meson_spifc.c
>>
>> diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
>> index 516188ea88..6085788481 100644
>> --- a/drivers/spi/Kconfig
>> +++ b/drivers/spi/Kconfig
>> @@ -116,6 +116,14 @@ config ICH_SPI
>>           access the SPI NOR flash on platforms embedding this Intel
>>           ICH IP core.
>>
>> +config MESON_SPIFC
>> +       bool "Amlogic Meson SPI Flash Controller driver"
>> +       depends on ARCH_MESON
>> +       help
>> +         Enable the Amlogic Meson SPI Flash Controller SPIFC) driver.
>> +         This driver can be used to access the SPI NOR flash chips on
>> +         Amlogic Meson SoCs.
>> +
>>  config MT7621_SPI
>>         bool "MediaTek MT7621 SPI driver"
>>         depends on ARCH_MT7620
>> diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
>> index 7242ea7e40..67b42daf4e 100644
>> --- a/drivers/spi/Makefile
>> +++ b/drivers/spi/Makefile
>> @@ -31,6 +31,7 @@ obj-$(CONFIG_FSL_QSPI) += fsl_qspi.o
>>  obj-$(CONFIG_ICH_SPI) +=  ich.o
>>  obj-$(CONFIG_KIRKWOOD_SPI) += kirkwood_spi.o
>>  obj-$(CONFIG_LPC32XX_SSP) += lpc32xx_ssp.o
>> +obj-$(CONFIG_MESON_SPIFC) += meson_spifc.o
>>  obj-$(CONFIG_MPC8XX_SPI) += mpc8xx_spi.o
>>  obj-$(CONFIG_MPC8XXX_SPI) += mpc8xxx_spi.o
>>  obj-$(CONFIG_MT7621_SPI) += mt7621_spi.o
>> diff --git a/drivers/spi/meson_spifc.c b/drivers/spi/meson_spifc.c
>> new file mode 100644
>> index 0000000000..936806ea0c
>> --- /dev/null
>> +++ b/drivers/spi/meson_spifc.c
>> @@ -0,0 +1,330 @@
>> +// SPDX-License-Identifier: GPL-2.0+
>> +/*
>> + * Copyright (C) 2014 Beniamino Galvani <b.galvani@gmail.com>
>> + * Copyright (C) 2018 BayLibre, SAS
>> + * Author: Neil Armstrong <narmstrong@baylibre.com>
>> + *
>> + * Amlogic Meson SPI Flash Controller driver
>> + */
>> +
>> +#include <common.h>
>> +#include <spi.h>
>> +#include <clk.h>
>> +#include <dm.h>
>> +#include <regmap.h>
>> +#include <errno.h>
>> +#include <asm/io.h>
>> +#include <linux/bitfield.h>
>> +
>> +/* register map */
>> +#define REG_CMD                        0x00
>> +#define REG_ADDR               0x04
>> +#define REG_CTRL               0x08
>> +#define REG_CTRL1              0x0c
>> +#define REG_STATUS             0x10
>> +#define REG_CTRL2              0x14
>> +#define REG_CLOCK              0x18
>> +#define REG_USER               0x1c
>> +#define REG_USER1              0x20
>> +#define REG_USER2              0x24
>> +#define REG_USER3              0x28
>> +#define REG_USER4              0x2c
>> +#define REG_SLAVE              0x30
>> +#define REG_SLAVE1             0x34
>> +#define REG_SLAVE2             0x38
>> +#define REG_SLAVE3             0x3c
>> +#define REG_C0                 0x40
>> +#define REG_B8                 0x60
>> +#define REG_MAX                        0x7c
>> +
>> +/* register fields */
>> +#define CMD_USER               BIT(18)
>> +#define CTRL_ENABLE_AHB                BIT(17)
>> +#define CLOCK_SOURCE           BIT(31)
>> +#define CLOCK_DIV_SHIFT                12
>> +#define CLOCK_DIV_MASK         (0x3f << CLOCK_DIV_SHIFT)
>> +#define CLOCK_CNT_HIGH_SHIFT   6
>> +#define CLOCK_CNT_HIGH_MASK    (0x3f << CLOCK_CNT_HIGH_SHIFT)
>> +#define CLOCK_CNT_LOW_SHIFT    0
>> +#define CLOCK_CNT_LOW_MASK     (0x3f << CLOCK_CNT_LOW_SHIFT)
>> +#define USER_DIN_EN_MS         BIT(0)
>> +#define USER_CMP_MODE          BIT(2)
>> +#define USER_CLK_NOT_INV       BIT(7)
>> +#define USER_UC_DOUT_SEL       BIT(27)
>> +#define USER_UC_DIN_SEL                BIT(28)
>> +#define USER_UC_MASK           ((BIT(5) - 1) << 27)
>> +#define USER1_BN_UC_DOUT_SHIFT 17
>> +#define USER1_BN_UC_DOUT_MASK  (0xff << 16)
>> +#define USER1_BN_UC_DIN_SHIFT  8
>> +#define USER1_BN_UC_DIN_MASK   (0xff << 8)
>> +#define USER4_CS_POL_HIGH      BIT(23)
>> +#define USER4_IDLE_CLK_HIGH    BIT(29)
>> +#define USER4_CS_ACT           BIT(30)
>> +#define SLAVE_TRST_DONE                BIT(4)
>> +#define SLAVE_OP_MODE          BIT(30)
>> +#define SLAVE_SW_RST           BIT(31)
>> +
>> +#define SPIFC_BUFFER_SIZE      64
>> +
>> +struct meson_spifc_priv {
>> +       struct regmap                   *regmap;
>> +       struct clk                      clk;
>> +};
>> +
>> +/**
>> + * meson_spifc_wait_ready() - wait for the current operation to terminate
>> + * @spifc:     the Meson SPI device
>> + * Return:     0 on success, a negative value on error
>> + */
>> +static int meson_spifc_wait_ready(struct meson_spifc_priv *spifc)
>> +{
>> +       u32 data;
>> +
>> +       return regmap_read_poll_timeout(spifc->regmap, REG_SLAVE, data,
>> +                                       (data & SLAVE_TRST_DONE),
>> +                                       0, 5 * CONFIG_SYS_HZ);
>> +}
> 
> We can call poll_timeout directly w/o separate function, since we have
> only one call. I can do that while applying if you are OK?
> 
> Reviewed-by: Jagan Teki <jagan@openedev.com>
> 

Sure, no problem.

Tell me when applied so I can test it before you send the PR to tom.

Neil

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

* [U-Boot] [PATCH u-boot v3 3/3] spi: Add Amlogic Meson SPI Flash Controller driver
@ 2018-11-14 13:12       ` Neil Armstrong
  0 siblings, 0 replies; 23+ messages in thread
From: Neil Armstrong @ 2018-11-14 13:12 UTC (permalink / raw)
  To: linus-amlogic

On 14/11/2018 14:11, Jagan Teki wrote:
> On Wed, Nov 14, 2018 at 3:57 PM Neil Armstrong <narmstrong@baylibre.com> wrote:
>>
>> The Amlogic Meson SoCs embeds a Flash oriented SPI Controller name SPIFC.
>> This driver, ported from the Linux meson-spi-spifc driver, add support
>> for this controller on the Amlogic Meson GX SoCs in U-Boot.
>>
>> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
>> ---
>>  drivers/spi/Kconfig       |   8 +
>>  drivers/spi/Makefile      |   1 +
>>  drivers/spi/meson_spifc.c | 330 ++++++++++++++++++++++++++++++++++++++
>>  3 files changed, 339 insertions(+)
>>  create mode 100644 drivers/spi/meson_spifc.c
>>
>> diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
>> index 516188ea88..6085788481 100644
>> --- a/drivers/spi/Kconfig
>> +++ b/drivers/spi/Kconfig
>> @@ -116,6 +116,14 @@ config ICH_SPI
>>           access the SPI NOR flash on platforms embedding this Intel
>>           ICH IP core.
>>
>> +config MESON_SPIFC
>> +       bool "Amlogic Meson SPI Flash Controller driver"
>> +       depends on ARCH_MESON
>> +       help
>> +         Enable the Amlogic Meson SPI Flash Controller SPIFC) driver.
>> +         This driver can be used to access the SPI NOR flash chips on
>> +         Amlogic Meson SoCs.
>> +
>>  config MT7621_SPI
>>         bool "MediaTek MT7621 SPI driver"
>>         depends on ARCH_MT7620
>> diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
>> index 7242ea7e40..67b42daf4e 100644
>> --- a/drivers/spi/Makefile
>> +++ b/drivers/spi/Makefile
>> @@ -31,6 +31,7 @@ obj-$(CONFIG_FSL_QSPI) += fsl_qspi.o
>>  obj-$(CONFIG_ICH_SPI) +=  ich.o
>>  obj-$(CONFIG_KIRKWOOD_SPI) += kirkwood_spi.o
>>  obj-$(CONFIG_LPC32XX_SSP) += lpc32xx_ssp.o
>> +obj-$(CONFIG_MESON_SPIFC) += meson_spifc.o
>>  obj-$(CONFIG_MPC8XX_SPI) += mpc8xx_spi.o
>>  obj-$(CONFIG_MPC8XXX_SPI) += mpc8xxx_spi.o
>>  obj-$(CONFIG_MT7621_SPI) += mt7621_spi.o
>> diff --git a/drivers/spi/meson_spifc.c b/drivers/spi/meson_spifc.c
>> new file mode 100644
>> index 0000000000..936806ea0c
>> --- /dev/null
>> +++ b/drivers/spi/meson_spifc.c
>> @@ -0,0 +1,330 @@
>> +// SPDX-License-Identifier: GPL-2.0+
>> +/*
>> + * Copyright (C) 2014 Beniamino Galvani <b.galvani@gmail.com>
>> + * Copyright (C) 2018 BayLibre, SAS
>> + * Author: Neil Armstrong <narmstrong@baylibre.com>
>> + *
>> + * Amlogic Meson SPI Flash Controller driver
>> + */
>> +
>> +#include <common.h>
>> +#include <spi.h>
>> +#include <clk.h>
>> +#include <dm.h>
>> +#include <regmap.h>
>> +#include <errno.h>
>> +#include <asm/io.h>
>> +#include <linux/bitfield.h>
>> +
>> +/* register map */
>> +#define REG_CMD                        0x00
>> +#define REG_ADDR               0x04
>> +#define REG_CTRL               0x08
>> +#define REG_CTRL1              0x0c
>> +#define REG_STATUS             0x10
>> +#define REG_CTRL2              0x14
>> +#define REG_CLOCK              0x18
>> +#define REG_USER               0x1c
>> +#define REG_USER1              0x20
>> +#define REG_USER2              0x24
>> +#define REG_USER3              0x28
>> +#define REG_USER4              0x2c
>> +#define REG_SLAVE              0x30
>> +#define REG_SLAVE1             0x34
>> +#define REG_SLAVE2             0x38
>> +#define REG_SLAVE3             0x3c
>> +#define REG_C0                 0x40
>> +#define REG_B8                 0x60
>> +#define REG_MAX                        0x7c
>> +
>> +/* register fields */
>> +#define CMD_USER               BIT(18)
>> +#define CTRL_ENABLE_AHB                BIT(17)
>> +#define CLOCK_SOURCE           BIT(31)
>> +#define CLOCK_DIV_SHIFT                12
>> +#define CLOCK_DIV_MASK         (0x3f << CLOCK_DIV_SHIFT)
>> +#define CLOCK_CNT_HIGH_SHIFT   6
>> +#define CLOCK_CNT_HIGH_MASK    (0x3f << CLOCK_CNT_HIGH_SHIFT)
>> +#define CLOCK_CNT_LOW_SHIFT    0
>> +#define CLOCK_CNT_LOW_MASK     (0x3f << CLOCK_CNT_LOW_SHIFT)
>> +#define USER_DIN_EN_MS         BIT(0)
>> +#define USER_CMP_MODE          BIT(2)
>> +#define USER_CLK_NOT_INV       BIT(7)
>> +#define USER_UC_DOUT_SEL       BIT(27)
>> +#define USER_UC_DIN_SEL                BIT(28)
>> +#define USER_UC_MASK           ((BIT(5) - 1) << 27)
>> +#define USER1_BN_UC_DOUT_SHIFT 17
>> +#define USER1_BN_UC_DOUT_MASK  (0xff << 16)
>> +#define USER1_BN_UC_DIN_SHIFT  8
>> +#define USER1_BN_UC_DIN_MASK   (0xff << 8)
>> +#define USER4_CS_POL_HIGH      BIT(23)
>> +#define USER4_IDLE_CLK_HIGH    BIT(29)
>> +#define USER4_CS_ACT           BIT(30)
>> +#define SLAVE_TRST_DONE                BIT(4)
>> +#define SLAVE_OP_MODE          BIT(30)
>> +#define SLAVE_SW_RST           BIT(31)
>> +
>> +#define SPIFC_BUFFER_SIZE      64
>> +
>> +struct meson_spifc_priv {
>> +       struct regmap                   *regmap;
>> +       struct clk                      clk;
>> +};
>> +
>> +/**
>> + * meson_spifc_wait_ready() - wait for the current operation to terminate
>> + * @spifc:     the Meson SPI device
>> + * Return:     0 on success, a negative value on error
>> + */
>> +static int meson_spifc_wait_ready(struct meson_spifc_priv *spifc)
>> +{
>> +       u32 data;
>> +
>> +       return regmap_read_poll_timeout(spifc->regmap, REG_SLAVE, data,
>> +                                       (data & SLAVE_TRST_DONE),
>> +                                       0, 5 * CONFIG_SYS_HZ);
>> +}
> 
> We can call poll_timeout directly w/o separate function, since we have
> only one call. I can do that while applying if you are OK?
> 
> Reviewed-by: Jagan Teki <jagan@openedev.com>
> 

Sure, no problem.

Tell me when applied so I can test it before you send the PR to tom.

Neil

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

* [U-Boot] [PATCH u-boot v3 0/3] Add Amlogic Meson SPI Flash Controller driver
  2018-11-14 10:25 ` Neil Armstrong
@ 2018-11-15 15:41   ` Jerome Brunet
  -1 siblings, 0 replies; 23+ messages in thread
From: Jerome Brunet @ 2018-11-15 15:41 UTC (permalink / raw)
  To: u-boot

On Wed, 2018-11-14 at 11:25 +0100, Neil Armstrong wrote:
> The Amlogic Meson SoCs embeds a Flash oriented SPI Controller name SPIFC.
> 
> This patchset add the driver ported from linux, but also import the regmap
> regmap_read_poll_timeout() to implify the register polling in the driver.
> 
> Neil Armstrong (3):
>   regmap: add regmap_read_poll_timeout() helper
>   test: regmap: add regmap_read_poll_timeout test
>   spi: Add Amlogic Meson SPI Flash Controller driver
> 
>  drivers/spi/Kconfig       |   8 +
>  drivers/spi/Makefile      |   1 +
>  drivers/spi/meson_spifc.c | 330 ++++++++++++++++++++++++++++++++++++++
>  include/regmap.h          |  38 +++++
>  test/dm/regmap.c          |  26 +++
>  5 files changed, 403 insertions(+)
>  create mode 100644 drivers/spi/meson_spifc.c
> 

Tested-by: Jerome Brunet <jbrunet@baylibre.com>

... on the libretech aml-s805x-ac which should be submitted soon.

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

* [PATCH u-boot v3 0/3] Add Amlogic Meson SPI Flash Controller driver
@ 2018-11-15 15:41   ` Jerome Brunet
  0 siblings, 0 replies; 23+ messages in thread
From: Jerome Brunet @ 2018-11-15 15:41 UTC (permalink / raw)
  To: linus-amlogic

On Wed, 2018-11-14 at 11:25 +0100, Neil Armstrong wrote:
> The Amlogic Meson SoCs embeds a Flash oriented SPI Controller name SPIFC.
> 
> This patchset add the driver ported from linux, but also import the regmap
> regmap_read_poll_timeout() to implify the register polling in the driver.
> 
> Neil Armstrong (3):
>   regmap: add regmap_read_poll_timeout() helper
>   test: regmap: add regmap_read_poll_timeout test
>   spi: Add Amlogic Meson SPI Flash Controller driver
> 
>  drivers/spi/Kconfig       |   8 +
>  drivers/spi/Makefile      |   1 +
>  drivers/spi/meson_spifc.c | 330 ++++++++++++++++++++++++++++++++++++++
>  include/regmap.h          |  38 +++++
>  test/dm/regmap.c          |  26 +++
>  5 files changed, 403 insertions(+)
>  create mode 100644 drivers/spi/meson_spifc.c
> 

Tested-by: Jerome Brunet <jbrunet@baylibre.com>

... on the libretech aml-s805x-ac which should be submitted soon.

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

* [U-Boot] [PATCH u-boot v3 0/3] Add Amlogic Meson SPI Flash Controller driver
  2018-11-14 10:25 ` Neil Armstrong
@ 2018-11-22  6:40   ` Jagan Teki
  -1 siblings, 0 replies; 23+ messages in thread
From: Jagan Teki @ 2018-11-22  6:40 UTC (permalink / raw)
  To: u-boot

On Wed, Nov 14, 2018 at 3:55 PM Neil Armstrong <narmstrong@baylibre.com> wrote:
>
> The Amlogic Meson SoCs embeds a Flash oriented SPI Controller name SPIFC.
>
> This patchset add the driver ported from linux, but also import the regmap
> regmap_read_poll_timeout() to implify the register polling in the driver.
>
> Neil Armstrong (3):
>   regmap: add regmap_read_poll_timeout() helper
>   test: regmap: add regmap_read_poll_timeout test
>   spi: Add Amlogic Meson SPI Flash Controller driver

There are few regmap patches upstreamed recently, can you rebase and
the send the series again. take care of direct poll_timeout w/o any
function on driver.

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

* [U-Boot] [PATCH u-boot v3 0/3] Add Amlogic Meson SPI Flash Controller driver
@ 2018-11-22  6:40   ` Jagan Teki
  0 siblings, 0 replies; 23+ messages in thread
From: Jagan Teki @ 2018-11-22  6:40 UTC (permalink / raw)
  To: linus-amlogic

On Wed, Nov 14, 2018 at 3:55 PM Neil Armstrong <narmstrong@baylibre.com> wrote:
>
> The Amlogic Meson SoCs embeds a Flash oriented SPI Controller name SPIFC.
>
> This patchset add the driver ported from linux, but also import the regmap
> regmap_read_poll_timeout() to implify the register polling in the driver.
>
> Neil Armstrong (3):
>   regmap: add regmap_read_poll_timeout() helper
>   test: regmap: add regmap_read_poll_timeout test
>   spi: Add Amlogic Meson SPI Flash Controller driver

There are few regmap patches upstreamed recently, can you rebase and
the send the series again. take care of direct poll_timeout w/o any
function on driver.

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

* [U-Boot] [PATCH u-boot v3 0/3] Add Amlogic Meson SPI Flash Controller driver
  2018-11-22  6:40   ` Jagan Teki
@ 2018-11-22  8:21     ` Neil Armstrong
  -1 siblings, 0 replies; 23+ messages in thread
From: Neil Armstrong @ 2018-11-22  8:21 UTC (permalink / raw)
  To: u-boot

On 22/11/2018 07:40, Jagan Teki wrote:
> On Wed, Nov 14, 2018 at 3:55 PM Neil Armstrong <narmstrong@baylibre.com> wrote:
>>
>> The Amlogic Meson SoCs embeds a Flash oriented SPI Controller name SPIFC.
>>
>> This patchset add the driver ported from linux, but also import the regmap
>> regmap_read_poll_timeout() to implify the register polling in the driver.
>>
>> Neil Armstrong (3):
>>   regmap: add regmap_read_poll_timeout() helper
>>   test: regmap: add regmap_read_poll_timeout test
>>   spi: Add Amlogic Meson SPI Flash Controller driver
> 
> There are few regmap patches upstreamed recently, can you rebase and
> the send the series again. take care of direct poll_timeout w/o any
> function on driver.
> 

Sure,

Neil

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

* [U-Boot] [PATCH u-boot v3 0/3] Add Amlogic Meson SPI Flash Controller driver
@ 2018-11-22  8:21     ` Neil Armstrong
  0 siblings, 0 replies; 23+ messages in thread
From: Neil Armstrong @ 2018-11-22  8:21 UTC (permalink / raw)
  To: linus-amlogic

On 22/11/2018 07:40, Jagan Teki wrote:
> On Wed, Nov 14, 2018 at 3:55 PM Neil Armstrong <narmstrong@baylibre.com> wrote:
>>
>> The Amlogic Meson SoCs embeds a Flash oriented SPI Controller name SPIFC.
>>
>> This patchset add the driver ported from linux, but also import the regmap
>> regmap_read_poll_timeout() to implify the register polling in the driver.
>>
>> Neil Armstrong (3):
>>   regmap: add regmap_read_poll_timeout() helper
>>   test: regmap: add regmap_read_poll_timeout test
>>   spi: Add Amlogic Meson SPI Flash Controller driver
> 
> There are few regmap patches upstreamed recently, can you rebase and
> the send the series again. take care of direct poll_timeout w/o any
> function on driver.
> 

Sure,

Neil

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

* [U-Boot] [PATCH u-boot v3 2/3] test: regmap: add regmap_read_poll_timeout test
  2018-11-22 10:01 Neil Armstrong
@ 2018-11-22 10:01 ` Neil Armstrong
  0 siblings, 0 replies; 23+ messages in thread
From: Neil Armstrong @ 2018-11-22 10:01 UTC (permalink / raw)
  To: u-boot

Add test to regmap_read_poll_timeout() helper to check the timeout works
properly but cannot test proper condition matching since read/write calls
are not executed in sandbox.

Acked-by: Jagan Teki <jagan@openedev.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
 test/dm/regmap.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/test/dm/regmap.c b/test/dm/regmap.c
index a8d7e6829e..9a70c159dd 100644
--- a/test/dm/regmap.c
+++ b/test/dm/regmap.c
@@ -144,3 +144,29 @@ static int dm_test_regmap_getset(struct unit_test_state *uts)
 }
 
 DM_TEST(dm_test_regmap_getset, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+/* Read polling test */
+static int dm_test_regmap_poll(struct unit_test_state *uts)
+{
+	struct udevice *dev;
+	struct regmap *map;
+	uint reg;
+	unsigned long start;
+
+	ut_assertok(uclass_get_device(UCLASS_SYSCON, 0, &dev));
+	map = syscon_get_regmap(dev);
+	ut_assertok_ptr(map);
+
+	start = get_timer(0);
+
+	ut_asserteq(-ETIMEDOUT,
+		    regmap_read_poll_timeout(map, 0, reg,
+					     (reg == 0xcacafafa),
+					     1, 5 * CONFIG_SYS_HZ));
+
+	ut_assert(get_timer(start) > (5 * CONFIG_SYS_HZ));
+
+	return 0;
+}
+
+DM_TEST(dm_test_regmap_poll, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
-- 
2.19.1

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

end of thread, other threads:[~2018-11-22 10:01 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-11-14 10:25 [U-Boot] [PATCH u-boot v3 0/3] Add Amlogic Meson SPI Flash Controller driver Neil Armstrong
2018-11-14 10:25 ` Neil Armstrong
2018-11-14 10:25 ` [U-Boot] [PATCH u-boot v3 1/3] regmap: add regmap_read_poll_timeout() helper Neil Armstrong
2018-11-14 10:25   ` Neil Armstrong
2018-11-14 13:09   ` [U-Boot] " Jagan Teki
2018-11-14 13:09     ` Jagan Teki
2018-11-14 10:25 ` [U-Boot] [PATCH u-boot v3 2/3] test: regmap: add regmap_read_poll_timeout test Neil Armstrong
2018-11-14 10:25   ` Neil Armstrong
2018-11-14 13:09   ` [U-Boot] " Jagan Teki
2018-11-14 13:09     ` Jagan Teki
2018-11-14 10:25 ` [U-Boot] [PATCH u-boot v3 3/3] spi: Add Amlogic Meson SPI Flash Controller driver Neil Armstrong
2018-11-14 10:25   ` Neil Armstrong
2018-11-14 13:11   ` [U-Boot] " Jagan Teki
2018-11-14 13:11     ` Jagan Teki
2018-11-14 13:12     ` Neil Armstrong
2018-11-14 13:12       ` Neil Armstrong
2018-11-15 15:41 ` [U-Boot] [PATCH u-boot v3 0/3] " Jerome Brunet
2018-11-15 15:41   ` Jerome Brunet
2018-11-22  6:40 ` [U-Boot] " Jagan Teki
2018-11-22  6:40   ` Jagan Teki
2018-11-22  8:21   ` Neil Armstrong
2018-11-22  8:21     ` Neil Armstrong
2018-11-22 10:01 Neil Armstrong
2018-11-22 10:01 ` [U-Boot] [PATCH u-boot v3 2/3] test: regmap: add regmap_read_poll_timeout test Neil Armstrong

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.