linux-spi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v6 0/2] spi: Add Renesas R-Car Gen3 RPC-IF SPI driver
@ 2019-01-18  5:54 Mason Yang
  2019-01-18  5:54 ` [PATCH v6 1/2] spi: Add Renesas R-Car Gen3 RPC-IF SPI controller driver Mason Yang
  2019-01-18  5:54 ` [PATCH v6 2/2] dt-bindings: spi: Document Renesas R-Car Gen3 RPC-IF controller bindings Mason Yang
  0 siblings, 2 replies; 15+ messages in thread
From: Mason Yang @ 2019-01-18  5:54 UTC (permalink / raw)
  To: broonie, marek.vasut, linux-kernel, linux-spi, bbrezillon,
	linux-renesas-soc, Geert Uytterhoeven, sergei.shtylyov
  Cc: juliensu, Simon Horman, zhengxunli, Mason Yang

Hi Mark,

v6 patch is accroding to Geert, Marek and Sergei's comments:
1) spi_controller for new code. 
2) "renesas,rcar-gen3-rpc" instead of "renesas,r8a77995-rpc".
3) patch external address read mode w/o u64 readq().
4) patch dts for write buffer & drop "renesas,rpc-mode".
5) coding style and so on.

v5 patch is accroding to Sergei's comments:
1) Read 6 bytes ID from Sergei's patch.
2) regmap_update_bits()
3) C++ style comment

v4 patch is according to Sergei's comments including:
1) Drop soc_device_match()
2) Drop unused RPC registers
3) Use ilog2() instead of fls()
4) Patch read 6 bytes ID w/ one command.
5) Coding style and so on.

v3 patch is according to Marek and Geert's comments including:
1) soc_device_mach() to set up RPC_PHYCNT_STRTIM.
2) get_unaligned()
3) rpc-mode for rpi-spi-flash or rpc-hyperflash.
4) coding style and so on.

v2 patch including:
1) remove RPC clock enable/dis-able control,
2) patch run time PM,
3) add RPC module software reset,
4) add regmap,
5) other coding style and so on.

thanks for your review.

best regards,
Mason

Mason Yang (2):
  spi: Add Renesas R-Car Gen3 RPC-IF SPI controller driver
  dt-bindings: spi: Document Renesas R-Car Gen3 RPC-IF controller
    bindings

 .../devicetree/bindings/spi/spi-renesas-rpc.txt    |  37 +
 drivers/spi/Kconfig                                |   6 +
 drivers/spi/Makefile                               |   1 +
 drivers/spi/spi-renesas-rpc.c                      | 800 +++++++++++++++++++++
 4 files changed, 844 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/spi/spi-renesas-rpc.txt
 create mode 100644 drivers/spi/spi-renesas-rpc.c

-- 
1.9.1

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

* [PATCH v6 1/2] spi: Add Renesas R-Car Gen3 RPC-IF SPI controller driver
  2019-01-18  5:54 [PATCH v6 0/2] spi: Add Renesas R-Car Gen3 RPC-IF SPI driver Mason Yang
@ 2019-01-18  5:54 ` Mason Yang
  2019-01-18  8:25   ` Geert Uytterhoeven
  2019-01-18 19:43   ` Sergei Shtylyov
  2019-01-18  5:54 ` [PATCH v6 2/2] dt-bindings: spi: Document Renesas R-Car Gen3 RPC-IF controller bindings Mason Yang
  1 sibling, 2 replies; 15+ messages in thread
From: Mason Yang @ 2019-01-18  5:54 UTC (permalink / raw)
  To: broonie, marek.vasut, linux-kernel, linux-spi, bbrezillon,
	linux-renesas-soc, Geert Uytterhoeven, sergei.shtylyov
  Cc: juliensu, Simon Horman, zhengxunli, Mason Yang

Add a driver for Renesas R-Car Gen3 RPC-IF SPI controller.

Signed-off-by: Mason Yang <masonccyang@mxic.com.tw>
Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
---
 drivers/spi/Kconfig           |   6 +
 drivers/spi/Makefile          |   1 +
 drivers/spi/spi-renesas-rpc.c | 800 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 807 insertions(+)
 create mode 100644 drivers/spi/spi-renesas-rpc.c

diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 9f89cb1..6ad1782 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -544,6 +544,12 @@ config SPI_RSPI
 	help
 	  SPI driver for Renesas RSPI and QSPI blocks.
 
+config SPI_RENESAS_RPC
+	tristate "Renesas R-Car Gen3 RPC-IF controller"
+	depends on ARCH_RENESAS || COMPILE_TEST
+	help
+	  SPI driver for Renesas R-Car Gen3 RPC-IF.
+
 config SPI_QCOM_QSPI
 	tristate "QTI QSPI controller"
 	depends on ARCH_QCOM
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index f296270..9150732 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -84,6 +84,7 @@ obj-$(CONFIG_SPI_QUP)			+= spi-qup.o
 obj-$(CONFIG_SPI_ROCKCHIP)		+= spi-rockchip.o
 obj-$(CONFIG_SPI_RB4XX)			+= spi-rb4xx.o
 obj-$(CONFIG_SPI_RSPI)			+= spi-rspi.o
+obj-$(CONFIG_SPI_RENESAS_RPC)		+= spi-renesas-rpc.o
 obj-$(CONFIG_SPI_S3C24XX)		+= spi-s3c24xx-hw.o
 spi-s3c24xx-hw-y			:= spi-s3c24xx.o
 spi-s3c24xx-hw-$(CONFIG_SPI_S3C24XX_FIQ) += spi-s3c24xx-fiq.o
diff --git a/drivers/spi/spi-renesas-rpc.c b/drivers/spi/spi-renesas-rpc.c
new file mode 100644
index 0000000..692c760
--- /dev/null
+++ b/drivers/spi/spi-renesas-rpc.c
@@ -0,0 +1,800 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (C) 2018 ~ 2019 Renesas Solutions Corp.
+// Copyright (C) 2018 Macronix International Co., Ltd.
+//
+// R-Car Gen3 RPC-IF SPI/QSPI/Octa driver
+//
+// Authors:
+//	Mason Yang <masonccyang@mxic.com.tw>
+//
+
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/log2.h>
+#include <linux/iopoll.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/of.h>
+#include <linux/regmap.h>
+#include <linux/reset.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/spi-mem.h>
+
+#include <asm/unaligned.h>
+
+#define RPC_CMNCR		0x0000	// R/W
+#define RPC_CMNCR_MD		BIT(31)
+#define RPC_CMNCR_SFDE		BIT(24) // undocumented bit but must be set
+#define RPC_CMNCR_MOIIO3(val)	(((val) & 0x3) << 22)
+#define RPC_CMNCR_MOIIO2(val)	(((val) & 0x3) << 20)
+#define RPC_CMNCR_MOIIO1(val)	(((val) & 0x3) << 18)
+#define RPC_CMNCR_MOIIO0(val)	(((val) & 0x3) << 16)
+#define RPC_CMNCR_MOIIO_HIZ	(RPC_CMNCR_MOIIO0(3) | RPC_CMNCR_MOIIO1(3) | \
+				 RPC_CMNCR_MOIIO2(3) | RPC_CMNCR_MOIIO3(3))
+#define RPC_CMNCR_IO3FV(val)	(((val) & 0x3) << 14) // undocumented
+#define RPC_CMNCR_IO2FV(val)	(((val) & 0x3) << 12) // undocumented
+#define RPC_CMNCR_IO0FV(val)	(((val) & 0x3) << 8)
+#define RPC_CMNCR_IOFV_HIZ	(RPC_CMNCR_IO0FV(3) | RPC_CMNCR_IO2FV(3) | \
+				 RPC_CMNCR_IO3FV(3))
+#define RPC_CMNCR_BSZ(val)	(((val) & 0x3) << 0)
+
+#define RPC_SSLDR		0x0004	// R/W
+#define RPC_SSLDR_SPNDL(d)	(((d) & 0x7) << 16)
+#define RPC_SSLDR_SLNDL(d)	(((d) & 0x7) << 8)
+#define RPC_SSLDR_SCKDL(d)	(((d) & 0x7) << 0)
+
+#define RPC_DRCR		0x000C	// R/W
+#define RPC_DRCR_SSLN		BIT(24)
+#define RPC_DRCR_RBURST(v)	((((v) - 1) & 0x1F) << 16)
+#define RPC_DRCR_RCF		BIT(9)
+#define RPC_DRCR_RBE		BIT(8)
+#define RPC_DRCR_SSLE		BIT(0)
+
+#define RPC_DRCMR		0x0010	// R/W
+#define RPC_DRCMR_CMD(c)	(((c) & 0xFF) << 16)
+#define RPC_DRCMR_OCMD(c)	(((c) & 0xFF) << 0)
+
+#define RPC_DREAR		0x0014	// R/W
+#define RPC_DREAR_EAC(c)	(((c) & 0x7) << 0)
+
+#define RPC_DROPR		0x0018	// R/W
+
+#define RPC_DRENR		0x001C	// R/W
+#define RPC_DRENR_CDB(o)	(u32)((((o) & 0x3) << 30))
+#define RPC_DRENR_OCDB(o)	(((o) & 0x3) << 28)
+#define RPC_DRENR_ADB(o)	(((o) & 0x3) << 24)
+#define RPC_DRENR_OPDB(o)	(((o) & 0x3) << 20)
+#define RPC_DRENR_SPIDB(o)	(((o) & 0x3) << 16)
+#define RPC_DRENR_DME		BIT(15)
+#define RPC_DRENR_CDE		BIT(14)
+#define RPC_DRENR_OCDE		BIT(12)
+#define RPC_DRENR_ADE(v)	(((v) & 0xF) << 8)
+#define RPC_DRENR_OPDE(v)	(((v) & 0xF) << 4)
+
+#define RPC_SMCR		0x0020	// R/W
+#define RPC_SMCR_SSLKP		BIT(8)
+#define RPC_SMCR_SPIRE		BIT(2)
+#define RPC_SMCR_SPIWE		BIT(1)
+#define RPC_SMCR_SPIE		BIT(0)
+
+#define RPC_SMCMR		0x0024	// R/W
+#define RPC_SMCMR_CMD(c)	(((c) & 0xFF) << 16)
+#define RPC_SMCMR_OCMD(c)	(((c) & 0xFF) << 0)
+
+#define RPC_SMADR		0x0028	// R/W
+#define RPC_SMOPR		0x002C	// R/W
+#define RPC_SMOPR_OPD3(o)	(((o) & 0xFF) << 24)
+#define RPC_SMOPR_OPD2(o)	(((o) & 0xFF) << 16)
+#define RPC_SMOPR_OPD1(o)	(((o) & 0xFF) << 8)
+#define RPC_SMOPR_OPD0(o)	(((o) & 0xFF) << 0)
+
+#define RPC_SMENR		0x0030	// R/W
+#define RPC_SMENR_CDB(o)	(((o) & 0x2) << 30)
+#define RPC_SMENR_OCDB(o)	(((o) & 0x2) << 28)
+#define RPC_SMENR_ADB(o)	(((o) & 0x2) << 24)
+#define RPC_SMENR_OPDB(o)	(((o) & 0x2) << 20)
+#define RPC_SMENR_SPIDB(o)	(((o) & 0x2) << 16)
+#define RPC_SMENR_DME		BIT(15)
+#define RPC_SMENR_CDE		BIT(14)
+#define RPC_SMENR_OCDE		BIT(12)
+#define RPC_SMENR_ADE(v)	(((v) & 0xF) << 8)
+#define RPC_SMENR_OPDE(v)	(((v) & 0xF) << 4)
+#define RPC_SMENR_SPIDE(v)	(((v) & 0xF) << 0)
+
+#define RPC_SMRDR0		0x0038	// R
+#define RPC_SMRDR1		0x003C	// R
+#define RPC_SMWDR0		0x0040	// W
+#define RPC_SMWDR1		0x0044	// W
+
+#define RPC_CMNSR		0x0048	// R
+#define RPC_CMNSR_SSLF		BIT(1)
+#define RPC_CMNSR_TEND		BIT(0)
+
+#define RPC_DRDMCR		0x0058	// R/W
+#define RPC_DRDRENR		0x005C	// R/W
+
+#define RPC_SMDMCR		0x0060	// R/W
+#define RPC_SMDMCR_DMCYC(v)	((((v) - 1) & 0x1F) << 0)
+
+#define RPC_SMDRENR		0x0064	// R/W
+#define RPC_SMDRENR_HYPE	(0x5 << 12)
+#define RPC_SMDRENR_ADDRE	BIT(8)
+#define RPC_SMDRENR_OPDRE	BIT(4)
+#define RPC_SMDRENR_SPIDRE	BIT(0)
+
+#define RPC_PHYCNT		0x007C	// R/W
+#define RPC_PHYCNT_CAL		BIT(31)
+#define PRC_PHYCNT_OCTA_AA	BIT(22)
+#define PRC_PHYCNT_OCTA_SA	BIT(23)
+#define PRC_PHYCNT_EXDS		BIT(21)
+#define RPC_PHYCNT_OCT		BIT(20)
+#define RPC_PHYCNT_STRTIM(v)	(((v) & 0x7) << 15)
+#define RPC_PHYCNT_WBUF2	BIT(4)
+#define RPC_PHYCNT_WBUF		BIT(2)
+#define RPC_PHYCNT_PHYMEM(v)	(((v) & 0x3) << 0)
+
+#define RPC_PHYOFFSET1		0x0080	// R/W
+#define RPC_PHYOFFSET1_DDRTMG(v) (((v) & 0x3) << 28)
+#define RPC_PHYOFFSET2		0x0084	// R/W
+#define RPC_PHYOFFSET2_OCTTMG(v) (((v) & 0x7) << 8)
+
+#define RPC_WBUF_SIZE		256	// Write Buffer size
+
+struct rpc_spi {
+	struct clk *clk_rpc;
+	void __iomem *base;
+	void __iomem *dirmap;
+	void __iomem *wbuf;
+	struct regmap *regmap;
+	u32 cur_speed_hz;
+	u32 cmd;
+	u32 addr;
+	u32 dummy;
+	u32 smcr;
+	u32 smenr;
+	u32 xferlen;
+	u32 totalxferlen;
+	enum spi_mem_data_dir xfer_dir;
+	struct reset_control *rstc;
+};
+
+static int rpc_spi_set_freq(struct rpc_spi *rpc, unsigned long freq)
+{
+	int ret;
+
+	if (rpc->cur_speed_hz == freq)
+		return 0;
+
+	ret = clk_set_rate(rpc->clk_rpc, freq);
+	if (ret)
+		return ret;
+
+	rpc->cur_speed_hz = freq;
+	return ret;
+}
+
+static void rpc_spi_hw_init(struct rpc_spi *rpc)
+{
+	//
+	// NOTE: The 0x260 are undocumented bits, but they must be set.
+	//	RPC_PHYCNT_STRTIM is strobe timing adjustment bit,
+	//	0x0 : the delay is biggest,
+	//	0x1 : the delay is 2nd biggest,
+	//	On H3 ES1.x, the value should be 0, while on others,
+	//	the value should be 6.
+	//
+	regmap_write(rpc->regmap, RPC_PHYCNT, RPC_PHYCNT_CAL |
+				  RPC_PHYCNT_STRTIM(6) | 0x260);
+
+	//
+	// NOTE: The 0x1511144 are undocumented bits, but they must be set
+	//       for RPC_PHYOFFSET1.
+	//	 The 0x31 are undocumented bits, but they must be set
+	//	 for RPC_PHYOFFSET2.
+	//
+	regmap_write(rpc->regmap, RPC_PHYOFFSET1, RPC_PHYOFFSET1_DDRTMG(3) |
+		     0x1511144);
+	regmap_write(rpc->regmap, RPC_PHYOFFSET2, 0x31 |
+		     RPC_PHYOFFSET2_OCTTMG(4));
+	regmap_write(rpc->regmap, RPC_SSLDR, RPC_SSLDR_SPNDL(7) |
+		     RPC_SSLDR_SLNDL(7) | RPC_SSLDR_SCKDL(7));
+	regmap_write(rpc->regmap, RPC_CMNCR, RPC_CMNCR_MD | RPC_CMNCR_SFDE |
+		     RPC_CMNCR_MOIIO_HIZ | RPC_CMNCR_IOFV_HIZ |
+		     RPC_CMNCR_BSZ(0));
+}
+
+static int wait_msg_xfer_end(struct rpc_spi *rpc)
+{
+	u32 sts;
+
+	return regmap_read_poll_timeout(rpc->regmap, RPC_CMNSR, sts,
+					sts & RPC_CMNSR_TEND, 0, USEC_PER_SEC);
+}
+
+static u8 rpc_bits_set(u32 nbytes)
+{
+	nbytes = clamp(nbytes, 1U, 4U);
+
+	return GENMASK(3, 4 - nbytes);
+}
+
+static int rpc_spi_io_xfer(struct rpc_spi *rpc,
+			   const void *tx_buf, void *rx_buf)
+{
+	u32 smenr, smcr, data, pos = 0;
+	int ret;
+
+	regmap_update_bits(rpc->regmap, RPC_CMNCR, RPC_CMNCR_MD, RPC_CMNCR_MD);
+	regmap_write(rpc->regmap, RPC_SMDRENR, 0);
+	regmap_write(rpc->regmap, RPC_SMCMR, rpc->cmd);
+	regmap_write(rpc->regmap, RPC_SMDMCR, rpc->dummy);
+	regmap_write(rpc->regmap, RPC_SMADR, rpc->addr);
+	smenr = rpc->smenr;
+
+	if (tx_buf) {
+		while (pos < rpc->xferlen) {
+			u32 nbytes = rpc->xferlen - pos;
+
+			regmap_write(rpc->regmap, RPC_SMWDR0,
+				     get_unaligned((u32 *)(tx_buf + pos)));
+
+			smcr = rpc->smcr | RPC_SMCR_SPIE;
+
+			if (nbytes > 4) {
+				nbytes = 4;
+				smcr |= RPC_SMCR_SSLKP;
+			}
+
+			regmap_write(rpc->regmap, RPC_SMENR, smenr);
+			regmap_write(rpc->regmap, RPC_SMCR, smcr);
+			ret = wait_msg_xfer_end(rpc);
+			if (ret)
+				goto err_out;
+
+			pos += nbytes;
+			smenr = rpc->smenr & ~RPC_SMENR_CDE &
+					     ~RPC_SMENR_ADE(0xf);
+		}
+	} else if (rx_buf) {
+		//
+		// RPC-IF spoils the data for the commands without an address
+		// phase (like RDID) in the manual mode, so we'll have to work
+		// around this issue by using the external address space read
+		// mode instead.
+		//
+		if (!(smenr & RPC_SMENR_ADE(0xf))) {
+			regmap_update_bits(rpc->regmap, RPC_CMNCR,
+					   RPC_CMNCR_MD, 0);
+			regmap_write(rpc->regmap, RPC_DRCR,
+				     RPC_DRCR_RBURST(32) | RPC_DRCR_RBE);
+			regmap_write(rpc->regmap, RPC_DREAR, RPC_DREAR_EAC(1));
+			regmap_write(rpc->regmap, RPC_DRCMR, rpc->cmd);
+			regmap_write(rpc->regmap, RPC_DRDMCR, rpc->dummy);
+			regmap_write(rpc->regmap, RPC_DROPR, 0);
+			regmap_write(rpc->regmap, RPC_DRENR, smenr);
+			memcpy_fromio(rx_buf, rpc->dirmap, rpc->xferlen);
+			regmap_write(rpc->regmap, RPC_DRCR, RPC_DRCR_RCF);
+		} else {
+			while (pos < rpc->xferlen) {
+				u32 nbytes = rpc->xferlen - pos;
+
+				if (nbytes > 4)
+					nbytes = 4;
+
+				regmap_write(rpc->regmap, RPC_SMENR, smenr);
+				regmap_write(rpc->regmap, RPC_SMCR, rpc->smcr |
+					     RPC_SMCR_SPIE);
+				ret = wait_msg_xfer_end(rpc);
+				if (ret)
+					goto err_out;
+
+				regmap_read(rpc->regmap, RPC_SMRDR0, &data);
+				memcpy(rx_buf + pos, &data, nbytes);
+				pos += nbytes;
+
+				regmap_write(rpc->regmap, RPC_SMADR,
+					     rpc->addr + pos);
+			}
+		}
+	} else {
+		regmap_write(rpc->regmap, RPC_SMENR, rpc->smenr);
+		regmap_write(rpc->regmap, RPC_SMCR, rpc->smcr | RPC_SMCR_SPIE);
+		ret = wait_msg_xfer_end(rpc);
+		if (ret)
+			goto err_out;
+	}
+
+	return 0;
+
+err_out:
+	return reset_control_reset(rpc->rstc);
+}
+
+static void rpc_spi_mem_set_prep_op_cfg(struct spi_device *spi,
+					const struct spi_mem_op *op,
+					u64 *offs, size_t *len)
+{
+	struct rpc_spi *rpc = spi_controller_get_devdata(spi->controller);
+
+	rpc->cmd = RPC_SMCMR_CMD(op->cmd.opcode);
+	rpc->smenr = RPC_SMENR_CDE |
+		     RPC_SMENR_CDB(ilog2(op->cmd.buswidth));
+	rpc->totalxferlen = 1;
+	rpc->xfer_dir = SPI_MEM_NO_DATA;
+	rpc->xferlen = 0;
+	rpc->addr = 0;
+
+	if (op->addr.nbytes) {
+		rpc->smenr |= RPC_SMENR_ADB(ilog2(op->addr.buswidth));
+		if (op->addr.nbytes == 4)
+			rpc->smenr |= RPC_SMENR_ADE(0xf);
+		else
+			rpc->smenr |= RPC_SMENR_ADE(0x7);
+
+		if (offs && len)
+			rpc->addr = *offs;
+		else
+			rpc->addr = op->addr.val;
+		rpc->totalxferlen += op->addr.nbytes;
+	}
+
+	if (op->dummy.nbytes) {
+		rpc->smenr |= RPC_SMENR_DME;
+		rpc->dummy = RPC_SMDMCR_DMCYC(op->dummy.nbytes);
+		rpc->totalxferlen += op->dummy.nbytes;
+	}
+
+	if (op->data.nbytes || (offs && len)) {
+		switch (op->data.dir) {
+		case SPI_MEM_DATA_IN:
+			rpc->smcr = RPC_SMCR_SPIRE;
+			rpc->xfer_dir = SPI_MEM_DATA_IN;
+			break;
+		case SPI_MEM_DATA_OUT:
+			rpc->smcr = RPC_SMCR_SPIWE;
+			rpc->xfer_dir = SPI_MEM_DATA_OUT;
+			break;
+		default:
+			break;
+		}
+
+		if (offs && len) {
+			rpc->smenr |= RPC_SMENR_SPIDE(rpc_bits_set(*len)) |
+				      RPC_SMENR_SPIDB(ilog2(op->data.buswidth));
+			rpc->xferlen = *len;
+			rpc->totalxferlen += *len;
+		} else {
+			rpc->smenr |=
+				RPC_SMENR_SPIDE(rpc_bits_set(op->data.nbytes)) |
+				RPC_SMENR_SPIDB(ilog2(op->data.buswidth));
+			rpc->xferlen = op->data.nbytes;
+			rpc->totalxferlen += op->data.nbytes;
+		}
+	}
+}
+
+static bool rpc_spi_mem_supports_op(struct spi_mem *mem,
+				    const struct spi_mem_op *op)
+{
+	if (op->data.buswidth > 4 || op->addr.buswidth > 4 ||
+	    op->dummy.buswidth > 4 || op->cmd.buswidth > 4 ||
+	    op->addr.nbytes > 4)
+		return false;
+
+	return true;
+}
+
+static ssize_t rpc_spi_mem_dirmap_read(struct spi_mem_dirmap_desc *desc,
+				       u64 offs, size_t len, void *buf)
+{
+	struct rpc_spi *rpc =
+			spi_controller_get_devdata(desc->mem->spi->controller);
+	int ret;
+
+	if (offs + desc->info.offset + len > U32_MAX)
+		return -EINVAL;
+
+	if (len > 0x4000000)
+		len = 0x4000000;
+
+	ret = rpc_spi_set_freq(rpc, desc->mem->spi->max_speed_hz);
+	if (ret)
+		return ret;
+
+	rpc_spi_mem_set_prep_op_cfg(desc->mem->spi,
+				    &desc->info.op_tmpl, &offs, &len);
+
+	regmap_update_bits(rpc->regmap, RPC_CMNCR, RPC_CMNCR_MD, 0);
+	regmap_write(rpc->regmap, RPC_DRCR, RPC_DRCR_RBURST(32) |
+		     RPC_DRCR_RBE);
+
+	regmap_write(rpc->regmap, RPC_DRCMR, rpc->cmd);
+	regmap_write(rpc->regmap, RPC_DREAR, RPC_DREAR_EAC(1));
+	regmap_write(rpc->regmap, RPC_DROPR, 0);
+	regmap_write(rpc->regmap, RPC_DRENR, rpc->smenr);
+	regmap_write(rpc->regmap, RPC_DRDMCR, rpc->dummy);
+	regmap_write(rpc->regmap, RPC_DRDRENR, 0);
+
+	memcpy_fromio(buf, rpc->dirmap + desc->info.offset + offs, len);
+
+	return len;
+}
+
+static ssize_t rpc_spi_mem_dirmap_write(struct spi_mem_dirmap_desc *desc,
+					u64 offs, size_t len, const void *buf)
+{
+	struct rpc_spi *rpc =
+			spi_controller_get_devdata(desc->mem->spi->controller);
+	int ret;
+
+	if (offs + desc->info.offset + len > U32_MAX)
+		return -EINVAL;
+
+	if (len > RPC_WBUF_SIZE)
+		len = RPC_WBUF_SIZE;
+
+	ret = rpc_spi_set_freq(rpc, desc->mem->spi->max_speed_hz);
+	if (ret)
+		return ret;
+
+	rpc_spi_mem_set_prep_op_cfg(desc->mem->spi,
+				    &desc->info.op_tmpl, &offs, &len);
+
+	regmap_update_bits(rpc->regmap, RPC_CMNCR, RPC_CMNCR_MD, RPC_CMNCR_MD);
+
+	regmap_write(rpc->regmap, RPC_SMDRENR, 0);
+
+	regmap_update_bits(rpc->regmap, RPC_PHYCNT, RPC_PHYCNT_STRTIM(7) |
+			   RPC_PHYCNT_WBUF2 | RPC_PHYCNT_WBUF,
+			   RPC_PHYCNT_WBUF2 | RPC_PHYCNT_WBUF);
+
+	memcpy_toio(rpc->wbuf, buf, len);
+
+	regmap_write(rpc->regmap, RPC_SMCMR, rpc->cmd);
+	regmap_write(rpc->regmap, RPC_SMADR, offs);
+	regmap_write(rpc->regmap, RPC_SMENR, rpc->smenr);
+	regmap_write(rpc->regmap, RPC_SMCR, rpc->smcr | RPC_SMCR_SPIE);
+	ret = wait_msg_xfer_end(rpc);
+	if (ret)
+		goto err_out;
+
+	regmap_write(rpc->regmap, RPC_DRCR, RPC_DRCR_RCF);
+
+	regmap_update_bits(rpc->regmap, RPC_PHYCNT, RPC_PHYCNT_STRTIM(7) |
+			   RPC_PHYCNT_WBUF2 | RPC_PHYCNT_WBUF,
+			   RPC_PHYCNT_STRTIM(6));
+
+	return len;
+
+err_out:
+	return reset_control_reset(rpc->rstc);
+}
+
+static int rpc_spi_mem_dirmap_create(struct spi_mem_dirmap_desc *desc)
+{
+	struct rpc_spi *rpc =
+			spi_controller_get_devdata(desc->mem->spi->controller);
+
+	if (desc->info.offset + desc->info.length > U32_MAX)
+		return -ENOTSUPP;
+
+	if (!rpc_spi_mem_supports_op(desc->mem, &desc->info.op_tmpl))
+		return -ENOTSUPP;
+
+	if (!rpc->dirmap &&
+	    desc->info.op_tmpl.data.dir == SPI_MEM_DATA_IN)
+		return -ENOTSUPP;
+
+	if (!rpc->wbuf &&
+	    desc->info.op_tmpl.data.dir == SPI_MEM_DATA_OUT)
+		return -ENOTSUPP;
+
+	return 0;
+}
+
+static int rpc_spi_mem_exec_op(struct spi_mem *mem,
+			       const struct spi_mem_op *op)
+{
+	struct rpc_spi *rpc = spi_controller_get_devdata(mem->spi->controller);
+	int ret;
+
+	ret = rpc_spi_set_freq(rpc, mem->spi->max_speed_hz);
+	if (ret)
+		return ret;
+
+	rpc_spi_mem_set_prep_op_cfg(mem->spi, op, NULL, NULL);
+
+	ret = rpc_spi_io_xfer(rpc,
+			      op->data.dir == SPI_MEM_DATA_OUT ?
+			      op->data.buf.out : NULL,
+			      op->data.dir == SPI_MEM_DATA_IN ?
+			      op->data.buf.in : NULL);
+
+	return ret;
+}
+
+static const struct spi_controller_mem_ops rpc_spi_mem_ops = {
+	.supports_op = rpc_spi_mem_supports_op,
+	.exec_op = rpc_spi_mem_exec_op,
+	.dirmap_create = rpc_spi_mem_dirmap_create,
+	.dirmap_read = rpc_spi_mem_dirmap_read,
+	.dirmap_write = rpc_spi_mem_dirmap_write,
+};
+
+static void rpc_spi_transfer_setup(struct rpc_spi *rpc,
+				   struct spi_message *msg)
+{
+	struct spi_transfer *t, xfer[4] = { };
+	u32 i, xfercnt, xferpos = 0;
+
+	rpc->totalxferlen = 0;
+	rpc->xfer_dir = SPI_MEM_NO_DATA;
+
+	list_for_each_entry(t, &msg->transfers, transfer_list) {
+		if (t->tx_buf) {
+			xfer[xferpos].tx_buf = t->tx_buf;
+			xfer[xferpos].tx_nbits = t->tx_nbits;
+		}
+
+		if (t->rx_buf) {
+			xfer[xferpos].rx_buf = t->rx_buf;
+			xfer[xferpos].rx_nbits = t->rx_nbits;
+		}
+
+		if (t->len) {
+			xfer[xferpos++].len = t->len;
+			rpc->totalxferlen += t->len;
+		}
+
+		if (list_is_last(&t->transfer_list, &msg->transfers)) {
+			if (xferpos > 1) {
+				if (t->rx_buf) {
+					rpc->xfer_dir = SPI_MEM_DATA_IN;
+					rpc->smcr = RPC_SMCR_SPIRE;
+				} else if (t->tx_buf) {
+					rpc->xfer_dir = SPI_MEM_DATA_OUT;
+					rpc->smcr = RPC_SMCR_SPIWE;
+				}
+			}
+		}
+	}
+
+	xfercnt = xferpos;
+	rpc->xferlen = xfer[--xferpos].len;
+	rpc->cmd = RPC_SMCMR_CMD(((u8 *)xfer[0].tx_buf)[0]);
+	rpc->smenr = RPC_SMENR_CDE |
+		     RPC_SMENR_CDB(ilog2((unsigned int)xfer[0].tx_nbits));
+	rpc->addr = 0;
+
+	if (xfercnt > 2 && xfer[1].len && xfer[1].tx_buf) {
+		rpc->smenr |=
+			RPC_SMENR_ADB(ilog2((unsigned int)xfer[1].tx_nbits));
+
+		for (i = 0; i < xfer[1].len; i++)
+			rpc->addr |= ((u8 *)xfer[1].tx_buf)[i] <<
+				     (8 * (xfer[1].len - i - 1));
+
+		if (xfer[1].len == 4)
+			rpc->smenr |= RPC_SMENR_ADE(0xf);
+		else
+			rpc->smenr |= RPC_SMENR_ADE(0x7);
+	}
+
+	if (xfercnt > 3 && xfer[2].len && xfer[2].tx_buf) {
+		rpc->smenr |= RPC_SMENR_DME;
+		rpc->dummy = RPC_SMDMCR_DMCYC(xfer[2].len);
+	}
+
+	for (i = xfercnt - 1; i < xfercnt && xfercnt > 1; i++) {
+		if (xfer[i].rx_buf) {
+			rpc->smenr |=
+				RPC_SMENR_SPIDE(rpc_bits_set(xfer[i].len)) |
+				RPC_SMENR_SPIDB(ilog2
+					((unsigned int)xfer[i].rx_nbits));
+		} else if (xfer[i].tx_buf) {
+			rpc->smenr |=
+				RPC_SMENR_SPIDE(rpc_bits_set(xfer[i].len)) |
+				RPC_SMENR_SPIDB(ilog2
+					((unsigned int)xfer[i].tx_nbits));
+		}
+	}
+}
+
+static int rpc_spi_xfer_message(struct rpc_spi *rpc,
+				struct spi_transfer *t)
+{
+	int ret;
+
+	ret = rpc_spi_set_freq(rpc, t->speed_hz);
+	if (ret)
+		return ret;
+
+	ret = rpc_spi_io_xfer(rpc,
+			      rpc->xfer_dir == SPI_MEM_DATA_OUT ?
+			      t->tx_buf : NULL,
+			      rpc->xfer_dir == SPI_MEM_DATA_IN ?
+			      t->rx_buf : NULL);
+
+	return ret;
+}
+
+static int rpc_spi_transfer_one_message(struct spi_controller *ctlr,
+					struct spi_message *msg)
+{
+	struct rpc_spi *rpc = spi_controller_get_devdata(ctlr);
+	struct spi_transfer *t;
+	int ret;
+
+	rpc_spi_transfer_setup(rpc, msg);
+
+	t = list_last_entry(&msg->transfers, struct spi_transfer,
+			    transfer_list);
+
+	ret = rpc_spi_xfer_message(rpc, t);
+	if (ret)
+		goto out;
+
+	msg->status = 0;
+	msg->actual_length = rpc->totalxferlen;
+out:
+	spi_finalize_current_message(ctlr);
+	return 0;
+}
+
+static const struct regmap_range rpc_spi_volatile_ranges[] = {
+	regmap_reg_range(RPC_SMRDR0, RPC_SMRDR0),
+	regmap_reg_range(RPC_SMWDR0, RPC_SMWDR0),
+	regmap_reg_range(RPC_CMNSR, RPC_CMNSR),
+};
+
+static const struct regmap_access_table rpc_spi_volatile_table = {
+	.yes_ranges	= rpc_spi_volatile_ranges,
+	.n_yes_ranges	= ARRAY_SIZE(rpc_spi_volatile_ranges),
+};
+
+static const struct regmap_config rpc_spi_regmap_config = {
+	.reg_bits = 32,
+	.val_bits = 32,
+	.reg_stride = 4,
+	.fast_io = true,
+	.max_register = RPC_PHYOFFSET2,
+	.volatile_table = &rpc_spi_volatile_table,
+};
+
+static int rpc_spi_probe(struct platform_device *pdev)
+{
+	struct spi_controller *ctlr;
+	struct resource *res;
+	struct rpc_spi *rpc;
+	const struct regmap_config *regmap_config;
+	struct device_node *rpc_if;
+	int ret;
+
+	rpc_if = of_find_compatible_node(pdev->dev.of_node, NULL,
+					 "jedec,spi-nor");
+	if (!rpc_if) {
+		dev_warn(&pdev->dev, "no spi-nor device found\n");
+		return -ENODEV;
+	}
+
+	ctlr = spi_alloc_master(&pdev->dev, sizeof(*rpc));
+	if (!ctlr)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, ctlr);
+
+	rpc = spi_controller_get_devdata(ctlr);
+
+	ctlr->dev.of_node = pdev->dev.of_node;
+
+	rpc->clk_rpc = devm_clk_get(&pdev->dev, "rpc");
+	if (IS_ERR(rpc->clk_rpc))
+		return PTR_ERR(rpc->clk_rpc);
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs");
+	rpc->base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(rpc->base))
+		return PTR_ERR(rpc->base);
+
+	regmap_config = &rpc_spi_regmap_config;
+	rpc->regmap = devm_regmap_init_mmio(&pdev->dev, rpc->base,
+					    regmap_config);
+	if (IS_ERR(rpc->regmap)) {
+		dev_err(&pdev->dev, "failed to init regmap %ld for rpc-spi\n",
+			PTR_ERR(rpc->regmap));
+		return PTR_ERR(rpc->regmap);
+	}
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dirmap");
+	rpc->dirmap = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(rpc->dirmap))
+		rpc->dirmap = NULL;
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "wbuf");
+	rpc->wbuf = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(rpc->wbuf))
+		rpc->wbuf = NULL;
+
+	rpc->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL);
+	if (IS_ERR(rpc->rstc))
+		return PTR_ERR(rpc->rstc);
+
+	pm_runtime_enable(&pdev->dev);
+	ctlr->auto_runtime_pm = true;
+
+	ctlr->num_chipselect = 1;
+	ctlr->mem_ops = &rpc_spi_mem_ops;
+	ctlr->transfer_one_message = rpc_spi_transfer_one_message;
+
+	ctlr->bits_per_word_mask = SPI_BPW_MASK(8);
+	ctlr->mode_bits = SPI_CPOL | SPI_CPHA | SPI_TX_QUAD | SPI_RX_QUAD;
+
+	rpc_spi_hw_init(rpc);
+
+	ret = spi_register_controller(ctlr);
+	if (ret) {
+		dev_err(&pdev->dev, "spi_register_master failed\n");
+		goto err_put_ctlr;
+	}
+	return 0;
+
+err_put_ctlr:
+	spi_controller_put(ctlr);
+	pm_runtime_disable(&pdev->dev);
+
+	return ret;
+}
+
+static int rpc_spi_remove(struct platform_device *pdev)
+{
+	struct spi_controller *ctlr = platform_get_drvdata(pdev);
+
+	pm_runtime_disable(&pdev->dev);
+	spi_unregister_controller(ctlr);
+
+	return 0;
+}
+
+static const struct of_device_id rpc_spi_of_ids[] = {
+	{ .compatible = "renesas,rcar-gen3-rpc", },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, rpc_spi_of_ids);
+
+#ifdef CONFIG_PM_SLEEP
+static int rpc_spi_suspend(struct device *dev)
+{
+	struct spi_controller *ctlr = dev_get_drvdata(dev);
+
+	return spi_controller_suspend(ctlr);
+}
+
+static int rpc_spi_resume(struct device *dev)
+{
+	struct spi_controller *ctlr = dev_get_drvdata(dev);
+
+	return spi_controller_resume(ctlr);
+}
+
+static SIMPLE_DEV_PM_OPS(rpc_spi_pm_ops, rpc_spi_suspend, rpc_spi_resume);
+#define DEV_PM_OPS	(&rpc_spi_pm_ops)
+#else
+#define DEV_PM_OPS	NULL
+#endif
+
+static struct platform_driver rpc_spi_driver = {
+	.probe = rpc_spi_probe,
+	.remove = rpc_spi_remove,
+	.driver = {
+		.name = "rpc-spi",
+		.of_match_table = rpc_spi_of_ids,
+		.pm = DEV_PM_OPS,
+	},
+};
+module_platform_driver(rpc_spi_driver);
+
+MODULE_AUTHOR("Mason Yang <masonccyang@mxic.com.tw>");
+MODULE_DESCRIPTION("Renesas R-Car Gen3 RPC-IF SPI controller driver");
+MODULE_LICENSE("GPL v2");
-- 
1.9.1

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

* [PATCH v6 2/2] dt-bindings: spi: Document Renesas R-Car Gen3 RPC-IF controller bindings
  2019-01-18  5:54 [PATCH v6 0/2] spi: Add Renesas R-Car Gen3 RPC-IF SPI driver Mason Yang
  2019-01-18  5:54 ` [PATCH v6 1/2] spi: Add Renesas R-Car Gen3 RPC-IF SPI controller driver Mason Yang
@ 2019-01-18  5:54 ` Mason Yang
  2019-01-18  6:16   ` Marek Vasut
                     ` (2 more replies)
  1 sibling, 3 replies; 15+ messages in thread
From: Mason Yang @ 2019-01-18  5:54 UTC (permalink / raw)
  To: broonie, marek.vasut, linux-kernel, linux-spi, bbrezillon,
	linux-renesas-soc, Geert Uytterhoeven, sergei.shtylyov
  Cc: juliensu, Simon Horman, zhengxunli, Mason Yang

Document the bindings used by the Renesas R-Car Gen3 RPC-IF controller.

Signed-off-by: Mason Yang <masonccyang@mxic.com.tw>
---
 .../devicetree/bindings/spi/spi-renesas-rpc.txt    | 37 ++++++++++++++++++++++
 1 file changed, 37 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/spi/spi-renesas-rpc.txt

diff --git a/Documentation/devicetree/bindings/spi/spi-renesas-rpc.txt b/Documentation/devicetree/bindings/spi/spi-renesas-rpc.txt
new file mode 100644
index 0000000..9b5001e
--- /dev/null
+++ b/Documentation/devicetree/bindings/spi/spi-renesas-rpc.txt
@@ -0,0 +1,37 @@
+Renesas R-Car Gen3 RPC-IF controller Device Tree Bindings
+----------------------------------------------------------
+
+Required properties:
+- compatible: should be "renesas,rcar-gen3-rpc"
+- #address-cells: should be 1
+- #size-cells: should be 0
+- reg: should contain three register areas:
+	first for the base address of rpc-if registers,
+	second for the direct mapping read mode and
+	third for the write buffer area.
+- reg-names: should contain "regs", "dirmap" and "wbuf"
+- clock-names: should contain "rpc"
+- clocks: should contain 1 entries for the module's clock
+
+Example:
+
+	rpc: rpc@ee200000 {
+		compatible = "renesas,rcar-gen3-rpc";
+		reg = <0 0xee200000 0 0x7fff>, <0 0x08000000 0 0x4000000>,
+		      <0 0xee208000 0 0x100>;
+		reg-names = "regs", "dirmap", "<wbuf>;
+		clocks = <&cpg CPG_MOD 917>;
+		power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+		resets = <&cpg 917>;
+		clock-names = "rpc";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		flash@0 {
+			compatible = "jedec,spi-nor";
+			reg = <0>;
+			spi-max-frequency = <40000000>;
+			spi-tx-bus-width = <1>;
+			spi-rx-bus-width = <1>;
+		};
+	};
-- 
1.9.1

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

* Re: [PATCH v6 2/2] dt-bindings: spi: Document Renesas R-Car Gen3 RPC-IF controller bindings
  2019-01-18  5:54 ` [PATCH v6 2/2] dt-bindings: spi: Document Renesas R-Car Gen3 RPC-IF controller bindings Mason Yang
@ 2019-01-18  6:16   ` Marek Vasut
       [not found]     ` <OF914E6438.79205FE6-ON48258386.002973E8-48258386.002A41F0@mxic.com.tw>
  2019-01-18  8:23     ` Sergei Shtylyov
  2019-01-18  8:03   ` Geert Uytterhoeven
  2019-01-18  8:18   ` Sergei Shtylyov
  2 siblings, 2 replies; 15+ messages in thread
From: Marek Vasut @ 2019-01-18  6:16 UTC (permalink / raw)
  To: Mason Yang, broonie, linux-kernel, linux-spi, bbrezillon,
	linux-renesas-soc, Geert Uytterhoeven, sergei.shtylyov
  Cc: juliensu, Simon Horman, zhengxunli

On 1/18/19 6:54 AM, Mason Yang wrote:
> Document the bindings used by the Renesas R-Car Gen3 RPC-IF controller.
> 
> Signed-off-by: Mason Yang <masonccyang@mxic.com.tw>
> ---
>  .../devicetree/bindings/spi/spi-renesas-rpc.txt    | 37 ++++++++++++++++++++++
>  1 file changed, 37 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/spi/spi-renesas-rpc.txt
> 
> diff --git a/Documentation/devicetree/bindings/spi/spi-renesas-rpc.txt b/Documentation/devicetree/bindings/spi/spi-renesas-rpc.txt
> new file mode 100644
> index 0000000..9b5001e
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/spi/spi-renesas-rpc.txt
> @@ -0,0 +1,37 @@
> +Renesas R-Car Gen3 RPC-IF controller Device Tree Bindings
> +----------------------------------------------------------
> +
> +Required properties:
> +- compatible: should be "renesas,rcar-gen3-rpc"
> +- #address-cells: should be 1
> +- #size-cells: should be 0
> +- reg: should contain three register areas:
> +	first for the base address of rpc-if registers,
> +	second for the direct mapping read mode and
> +	third for the write buffer area.
> +- reg-names: should contain "regs", "dirmap" and "wbuf"
> +- clock-names: should contain "rpc"
> +- clocks: should contain 1 entries for the module's clock
> +
> +Example:
> +
> +	rpc: rpc@ee200000 {
> +		compatible = "renesas,rcar-gen3-rpc";
> +		reg = <0 0xee200000 0 0x7fff>, <0 0x08000000 0 0x4000000>,

0x7fff should be 0x8000 , right ?

> +		      <0 0xee208000 0 0x100>;

Isn't the write buffer part of the RPC-IF register set ?

> +		reg-names = "regs", "dirmap", "<wbuf>;
> +		clocks = <&cpg CPG_MOD 917>;
> +		power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
> +		resets = <&cpg 917>;
> +		clock-names = "rpc";
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +
> +		flash@0 {
> +			compatible = "jedec,spi-nor";
> +			reg = <0>;
> +			spi-max-frequency = <40000000>;
> +			spi-tx-bus-width = <1>;
> +			spi-rx-bus-width = <1>;
> +		};
> +	};
> 


-- 
Best regards,
Marek Vasut

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

* Re: [PATCH v6 2/2] dt-bindings: spi: Document Renesas R-Car Gen3 RPC-IF controller bindings
       [not found]     ` <OF914E6438.79205FE6-ON48258386.002973E8-48258386.002A41F0@mxic.com.tw>
@ 2019-01-18  7:46       ` Marek Vasut
  0 siblings, 0 replies; 15+ messages in thread
From: Marek Vasut @ 2019-01-18  7:46 UTC (permalink / raw)
  To: masonccyang
  Cc: bbrezillon, broonie, Geert Uytterhoeven, Simon Horman, juliensu,
	linux-kernel, linux-renesas-soc, linux-spi, sergei.shtylyov,
	zhengxunli, Chris Brandt

On 1/18/19 8:41 AM, masonccyang@mxic.com.tw wrote:
> Hi Marek,

Hi,

>> "Marek Vasut" <marek.vasut@gmail.com>
>> 2019/01/18 下午 03:10
>>
>> > +Renesas R-Car Gen3 RPC-IF controller Device Tree Bindings
>> > +----------------------------------------------------------
>> > +
>> > +Required properties:
>> > +- compatible: should be "renesas,rcar-gen3-rpc"
>> > +- #address-cells: should be 1
>> > +- #size-cells: should be 0
>> > +- reg: should contain three register areas:
>> > +   first for the base address of rpc-if registers,
>> > +   second for the direct mapping read mode and
>> > +   third for the write buffer area.
>> > +- reg-names: should contain "regs", "dirmap" and "wbuf"
>> > +- clock-names: should contain "rpc"
>> > +- clocks: should contain 1 entries for the module's clock
>> > +
>> > +Example:
>> > +
>> > +   rpc: rpc@ee200000 {
>> > +      compatible = "renesas,rcar-gen3-rpc";
>> > +      reg = <0 0xee200000 0 0x7fff>, <0 0x08000000 0 0x4000000>,
>>
>> 0x7fff should be 0x8000 , right ?
> 
> RPC write buffer starts at 0xee208000 w/ 256 bytes size.

The size of the RPC-IF block is 0x8000 though, is it not ?

>> > +            <0 0xee208000 0 0x100>;
>>
>> Isn't the write buffer part of the RPC-IF register set ?
> 
> yep, but by Sergei and Geert's comments, we use a separate reg entry
> for this write buffer.
> ---- copy the replied email from Geert ---------------------------------
>> Maybe Geert or Marek could comment on it, thanks.
> 
> Given the writer buffer is separate from the other registers (it's in
> a different
> 4 KiB page, and thus may be at a different offset on future SoCs), and not
> present on RZ/A1, I think it's a good idea to use a separate reg entry
> for it.
> -----------------------------------------------------------------------

+CC Chris, the RZ/A1 has no write buffer for the RPC ?

-- 
Best regards,
Marek Vasut

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

* Re: [PATCH v6 2/2] dt-bindings: spi: Document Renesas R-Car Gen3 RPC-IF controller bindings
  2019-01-18  5:54 ` [PATCH v6 2/2] dt-bindings: spi: Document Renesas R-Car Gen3 RPC-IF controller bindings Mason Yang
  2019-01-18  6:16   ` Marek Vasut
@ 2019-01-18  8:03   ` Geert Uytterhoeven
  2019-01-18  8:08     ` Marek Vasut
       [not found]     ` <OFBD5366C8.433ADACB-ON48258386.00336667-48258386.00340E20@mxic.com.tw>
  2019-01-18  8:18   ` Sergei Shtylyov
  2 siblings, 2 replies; 15+ messages in thread
From: Geert Uytterhoeven @ 2019-01-18  8:03 UTC (permalink / raw)
  To: Mason Yang
  Cc: Mark Brown, Marek Vasut, Linux Kernel Mailing List, linux-spi,
	Boris Brezillon, Linux-Renesas, Geert Uytterhoeven,
	Sergei Shtylyov, juliensu, Simon Horman, zhengxunli

Hi Mason,

On Fri, Jan 18, 2019 at 6:55 AM Mason Yang <masonccyang@mxic.com.tw> wrote:
> Document the bindings used by the Renesas R-Car Gen3 RPC-IF controller.
>
> Signed-off-by: Mason Yang <masonccyang@mxic.com.tw>

Thanks for the update!

> --- /dev/null
> +++ b/Documentation/devicetree/bindings/spi/spi-renesas-rpc.txt
> @@ -0,0 +1,37 @@
> +Renesas R-Car Gen3 RPC-IF controller Device Tree Bindings
> +----------------------------------------------------------
> +
> +Required properties:
> +- compatible: should be

    compatible: should be an SoC-specific compatible value, followed by
    "renesas,rcar-gen3-rpc" as a fallback.

    Examples of the latter are:
      - "renesas,r8a7795-rpc" (R-Car H3).

This makes it future-proof, in case the RPC on a specific SoC version needs
to be handled specially. We already know that is the case for R-Car V3M.

> +- #address-cells: should be 1
> +- #size-cells: should be 0
> +- reg: should contain three register areas:
> +       first for the base address of rpc-if registers,
> +       second for the direct mapping read mode and
> +       third for the write buffer area.
> +- reg-names: should contain "regs", "dirmap" and "wbuf"
> +- clock-names: should contain "rpc"
> +- clocks: should contain 1 entries for the module's clock
> +
> +Example:
> +
> +       rpc: rpc@ee200000 {
> +               compatible = "renesas,rcar-gen3-rpc";

compatible = "renesas,r8a7795-rpc," renesas,rcar-gen3-rpc";

> +               reg = <0 0xee200000 0 0x7fff>, <0 0x08000000 0 0x4000000>,
> +                     <0 0xee208000 0 0x100>;
> +               reg-names = "regs", "dirmap", "<wbuf>;
> +               clocks = <&cpg CPG_MOD 917>;
> +               power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
> +               resets = <&cpg 917>;
> +               clock-names = "rpc";
> +               #address-cells = <1>;
> +               #size-cells = <0>;
> +
> +               flash@0 {
> +                       compatible = "jedec,spi-nor";
> +                       reg = <0>;
> +                       spi-max-frequency = <40000000>;
> +                       spi-tx-bus-width = <1>;
> +                       spi-rx-bus-width = <1>;
> +               };
> +       };

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

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

* Re: [PATCH v6 2/2] dt-bindings: spi: Document Renesas R-Car Gen3 RPC-IF controller bindings
  2019-01-18  8:03   ` Geert Uytterhoeven
@ 2019-01-18  8:08     ` Marek Vasut
  2019-01-18  8:10       ` Geert Uytterhoeven
       [not found]     ` <OFBD5366C8.433ADACB-ON48258386.00336667-48258386.00340E20@mxic.com.tw>
  1 sibling, 1 reply; 15+ messages in thread
From: Marek Vasut @ 2019-01-18  8:08 UTC (permalink / raw)
  To: Geert Uytterhoeven, Mason Yang
  Cc: Mark Brown, Linux Kernel Mailing List, linux-spi,
	Boris Brezillon, Linux-Renesas, Geert Uytterhoeven,
	Sergei Shtylyov, juliensu, Simon Horman, zhengxunli

On 1/18/19 9:03 AM, Geert Uytterhoeven wrote:
> Hi Mason,
> 
> On Fri, Jan 18, 2019 at 6:55 AM Mason Yang <masonccyang@mxic.com.tw> wrote:
>> Document the bindings used by the Renesas R-Car Gen3 RPC-IF controller.
>>
>> Signed-off-by: Mason Yang <masonccyang@mxic.com.tw>
> 
> Thanks for the update!
> 
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/spi/spi-renesas-rpc.txt
>> @@ -0,0 +1,37 @@
>> +Renesas R-Car Gen3 RPC-IF controller Device Tree Bindings
>> +----------------------------------------------------------
>> +
>> +Required properties:
>> +- compatible: should be
> 
>     compatible: should be an SoC-specific compatible value, followed by
>     "renesas,rcar-gen3-rpc" as a fallback.
> 
>     Examples of the latter are:
>       - "renesas,r8a7795-rpc" (R-Car H3).
> 
> This makes it future-proof, in case the RPC on a specific SoC version needs
> to be handled specially. We already know that is the case for R-Car V3M.
> 
>> +- #address-cells: should be 1
>> +- #size-cells: should be 0
>> +- reg: should contain three register areas:
>> +       first for the base address of rpc-if registers,
>> +       second for the direct mapping read mode and
>> +       third for the write buffer area.
>> +- reg-names: should contain "regs", "dirmap" and "wbuf"
>> +- clock-names: should contain "rpc"
>> +- clocks: should contain 1 entries for the module's clock
>> +
>> +Example:
>> +
>> +       rpc: rpc@ee200000 {
>> +               compatible = "renesas,rcar-gen3-rpc";
> 
> compatible = "renesas,r8a7795-rpc," renesas,rcar-gen3-rpc";

Without the extra comma after r8a7795-rpc, of course ;-)

-- 
Best regards,
Marek Vasut

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

* Re: [PATCH v6 2/2] dt-bindings: spi: Document Renesas R-Car Gen3 RPC-IF controller bindings
  2019-01-18  8:08     ` Marek Vasut
@ 2019-01-18  8:10       ` Geert Uytterhoeven
  2019-01-18  8:12         ` Marek Vasut
  0 siblings, 1 reply; 15+ messages in thread
From: Geert Uytterhoeven @ 2019-01-18  8:10 UTC (permalink / raw)
  To: Marek Vasut
  Cc: Mason Yang, Mark Brown, Linux Kernel Mailing List, linux-spi,
	Boris Brezillon, Linux-Renesas, Geert Uytterhoeven,
	Sergei Shtylyov, juliensu, Simon Horman, zhengxunli

Hi Marek,

On Fri, Jan 18, 2019 at 9:08 AM Marek Vasut <marek.vasut@gmail.com> wrote:
> On 1/18/19 9:03 AM, Geert Uytterhoeven wrote:
> > On Fri, Jan 18, 2019 at 6:55 AM Mason Yang <masonccyang@mxic.com.tw> wrote:
> >> --- /dev/null
> >> +++ b/Documentation/devicetree/bindings/spi/spi-renesas-rpc.txt

> >> +Example:
> >> +
> >> +       rpc: rpc@ee200000 {
> >> +               compatible = "renesas,rcar-gen3-rpc";
> >
> > compatible = "renesas,r8a7795-rpc," renesas,rcar-gen3-rpc";
>
> Without the extra comma after r8a7795-rpc, of course ;-)

Let's move it after the closing double quotes. Would that be OK for you? ^-)

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

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

* Re: [PATCH v6 2/2] dt-bindings: spi: Document Renesas R-Car Gen3 RPC-IF controller bindings
  2019-01-18  8:10       ` Geert Uytterhoeven
@ 2019-01-18  8:12         ` Marek Vasut
  0 siblings, 0 replies; 15+ messages in thread
From: Marek Vasut @ 2019-01-18  8:12 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Mason Yang, Mark Brown, Linux Kernel Mailing List, linux-spi,
	Boris Brezillon, Linux-Renesas, Geert Uytterhoeven,
	Sergei Shtylyov, juliensu, Simon Horman, zhengxunli

On 1/18/19 9:10 AM, Geert Uytterhoeven wrote:
> Hi Marek,
> 
> On Fri, Jan 18, 2019 at 9:08 AM Marek Vasut <marek.vasut@gmail.com> wrote:
>> On 1/18/19 9:03 AM, Geert Uytterhoeven wrote:
>>> On Fri, Jan 18, 2019 at 6:55 AM Mason Yang <masonccyang@mxic.com.tw> wrote:
>>>> --- /dev/null
>>>> +++ b/Documentation/devicetree/bindings/spi/spi-renesas-rpc.txt
> 
>>>> +Example:
>>>> +
>>>> +       rpc: rpc@ee200000 {
>>>> +               compatible = "renesas,rcar-gen3-rpc";
>>>
>>> compatible = "renesas,r8a7795-rpc," renesas,rcar-gen3-rpc";
>>
>> Without the extra comma after r8a7795-rpc, of course ;-)
> 
> Let's move it after the closing double quotes. Would that be OK for you? ^-)

Ack

-- 
Best regards,
Marek Vasut

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

* Re: [PATCH v6 2/2] dt-bindings: spi: Document Renesas R-Car Gen3 RPC-IF controller bindings
  2019-01-18  5:54 ` [PATCH v6 2/2] dt-bindings: spi: Document Renesas R-Car Gen3 RPC-IF controller bindings Mason Yang
  2019-01-18  6:16   ` Marek Vasut
  2019-01-18  8:03   ` Geert Uytterhoeven
@ 2019-01-18  8:18   ` Sergei Shtylyov
  2 siblings, 0 replies; 15+ messages in thread
From: Sergei Shtylyov @ 2019-01-18  8:18 UTC (permalink / raw)
  To: Mason Yang, broonie, marek.vasut, linux-kernel, linux-spi,
	bbrezillon, linux-renesas-soc, Geert Uytterhoeven
  Cc: juliensu, Simon Horman, zhengxunli

Hello!

On 18.01.2019 8:54, Mason Yang wrote:

> Document the bindings used by the Renesas R-Car Gen3 RPC-IF controller.
> 
> Signed-off-by: Mason Yang <masonccyang@mxic.com.tw>
> ---
>   .../devicetree/bindings/spi/spi-renesas-rpc.txt    | 37 ++++++++++++++++++++++
>   1 file changed, 37 insertions(+)
>   create mode 100644 Documentation/devicetree/bindings/spi/spi-renesas-rpc.txt
> 
> diff --git a/Documentation/devicetree/bindings/spi/spi-renesas-rpc.txt b/Documentation/devicetree/bindings/spi/spi-renesas-rpc.txt
> new file mode 100644
> index 0000000..9b5001e
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/spi/spi-renesas-rpc.txt
> @@ -0,0 +1,37 @@
> +Renesas R-Car Gen3 RPC-IF controller Device Tree Bindings
> +----------------------------------------------------------
> +
> +Required properties:
> +- compatible: should be "renesas,rcar-gen3-rpc"
> +- #address-cells: should be 1
> +- #size-cells: should be 0
> +- reg: should contain three register areas:
> +	first for the base address of rpc-if registers,
> +	second for the direct mapping read mode and
> +	third for the write buffer area.
> +- reg-names: should contain "regs", "dirmap" and "wbuf"
> +- clock-names: should contain "rpc"
> +- clocks: should contain 1 entries for the module's clock
> +
> +Example:
> +
> +	rpc: rpc@ee200000 {
> +		compatible = "renesas,rcar-gen3-rpc";
> +		reg = <0 0xee200000 0 0x7fff>, <0 0x08000000 0 0x4000000>,

    s/0x7fff/0x8000/. -- that's size, not limit. But in reality, 0x200 would 
be enough.

> +		      <0 0xee208000 0 0x100>;
> +		reg-names = "regs", "dirmap", "<wbuf>;

    Why <>?

MBR, Sergei

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

* Re: [PATCH v6 2/2] dt-bindings: spi: Document Renesas R-Car Gen3 RPC-IF controller bindings
  2019-01-18  6:16   ` Marek Vasut
       [not found]     ` <OF914E6438.79205FE6-ON48258386.002973E8-48258386.002A41F0@mxic.com.tw>
@ 2019-01-18  8:23     ` Sergei Shtylyov
  1 sibling, 0 replies; 15+ messages in thread
From: Sergei Shtylyov @ 2019-01-18  8:23 UTC (permalink / raw)
  To: Marek Vasut, Mason Yang, broonie, linux-kernel, linux-spi,
	bbrezillon, linux-renesas-soc, Geert Uytterhoeven
  Cc: juliensu, Simon Horman, zhengxunli

Hello!

On 18.01.2019 9:16, Marek Vasut wrote:

>> Document the bindings used by the Renesas R-Car Gen3 RPC-IF controller.
>>
>> Signed-off-by: Mason Yang <masonccyang@mxic.com.tw>
>> ---
>>   .../devicetree/bindings/spi/spi-renesas-rpc.txt    | 37 ++++++++++++++++++++++
>>   1 file changed, 37 insertions(+)
>>   create mode 100644 Documentation/devicetree/bindings/spi/spi-renesas-rpc.txt
>>
>> diff --git a/Documentation/devicetree/bindings/spi/spi-renesas-rpc.txt b/Documentation/devicetree/bindings/spi/spi-renesas-rpc.txt
>> new file mode 100644
>> index 0000000..9b5001e
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/spi/spi-renesas-rpc.txt
>> @@ -0,0 +1,37 @@
>> +Renesas R-Car Gen3 RPC-IF controller Device Tree Bindings
>> +----------------------------------------------------------
>> +
>> +Required properties:
>> +- compatible: should be "renesas,rcar-gen3-rpc"
>> +- #address-cells: should be 1
>> +- #size-cells: should be 0
>> +- reg: should contain three register areas:
>> +	first for the base address of rpc-if registers,
>> +	second for the direct mapping read mode and
>> +	third for the write buffer area.
>> +- reg-names: should contain "regs", "dirmap" and "wbuf"
>> +- clock-names: should contain "rpc"
>> +- clocks: should contain 1 entries for the module's clock
>> +
>> +Example:
>> +
>> +	rpc: rpc@ee200000 {
>> +		compatible = "renesas,rcar-gen3-rpc";
>> +		reg = <0 0xee200000 0 0x7fff>, <0 0x08000000 0 0x4000000>,
> 
> 0x7fff should be 0x8000 , right ?

    Even 0x200.

> 
>> +		      <0 0xee208000 0 0x100>;
> 
> Isn't the write buffer part of the RPC-IF register set ?

    No, if you look into the manual.

MBR, Sergei

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

* Re: [PATCH v6 1/2] spi: Add Renesas R-Car Gen3 RPC-IF SPI controller driver
  2019-01-18  5:54 ` [PATCH v6 1/2] spi: Add Renesas R-Car Gen3 RPC-IF SPI controller driver Mason Yang
@ 2019-01-18  8:25   ` Geert Uytterhoeven
  2019-01-18 19:43   ` Sergei Shtylyov
  1 sibling, 0 replies; 15+ messages in thread
From: Geert Uytterhoeven @ 2019-01-18  8:25 UTC (permalink / raw)
  To: Mason Yang
  Cc: Mark Brown, Marek Vasut, Linux Kernel Mailing List, linux-spi,
	Boris Brezillon, Linux-Renesas, Geert Uytterhoeven,
	Sergei Shtylyov, juliensu, Simon Horman, zhengxunli

Hi Mason,

On Fri, Jan 18, 2019 at 6:55 AM Mason Yang <masonccyang@mxic.com.tw> wrote:
> Add a driver for Renesas R-Car Gen3 RPC-IF SPI controller.
>
> Signed-off-by: Mason Yang <masonccyang@mxic.com.tw>
> Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>

Thanks for the update!


> --- /dev/null
> +++ b/drivers/spi/spi-renesas-rpc.c
> @@ -0,0 +1,800 @@

> +static int rpc_spi_xfer_message(struct rpc_spi *rpc,
> +                               struct spi_transfer *t)

As "t" is not an arbitrary transfer, but the last transfer containing the
actual data, I'd call it "last", or "data_xfer".

> +{
> +       int ret;
> +
> +       ret = rpc_spi_set_freq(rpc, t->speed_hz);
> +       if (ret)
> +               return ret;
> +
> +       ret = rpc_spi_io_xfer(rpc,
> +                             rpc->xfer_dir == SPI_MEM_DATA_OUT ?
> +                             t->tx_buf : NULL,
> +                             rpc->xfer_dir == SPI_MEM_DATA_IN ?
> +                             t->rx_buf : NULL);
> +
> +       return ret;
> +}
> +
> +static int rpc_spi_transfer_one_message(struct spi_controller *ctlr,
> +                                       struct spi_message *msg)
> +{
> +       struct rpc_spi *rpc = spi_controller_get_devdata(ctlr);
> +       struct spi_transfer *t;

Likewise.

> +       int ret;
> +
> +       rpc_spi_transfer_setup(rpc, msg);
> +
> +       t = list_last_entry(&msg->transfers, struct spi_transfer,
> +                           transfer_list);
> +
> +       ret = rpc_spi_xfer_message(rpc, t);

As this function is small, perhaps just inline it here?
IMHO that makes the flow clearer.

> +       if (ret)
> +               goto out;
> +
> +       msg->status = 0;
> +       msg->actual_length = rpc->totalxferlen;
> +out:
> +       spi_finalize_current_message(ctlr);
> +       return 0;
> +}

The rest looks good to me, thanks!

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

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

* Re: [PATCH v6 2/2] dt-bindings: spi: Document Renesas R-Car Gen3 RPC-IF controller bindings
       [not found]     ` <OFBD5366C8.433ADACB-ON48258386.00336667-48258386.00340E20@mxic.com.tw>
@ 2019-01-18 10:39       ` Geert Uytterhoeven
  0 siblings, 0 replies; 15+ messages in thread
From: Geert Uytterhoeven @ 2019-01-18 10:39 UTC (permalink / raw)
  To: Mason Yang
  Cc: Boris Brezillon, Mark Brown, Geert Uytterhoeven, Simon Horman,
	juliensu, Linux Kernel Mailing List, Linux-Renesas, linux-spi,
	Marek Vasut, Sergei Shtylyov, zhengxunli

Hi Mason,

On Fri, Jan 18, 2019 at 10:28 AM <masonccyang@mxic.com.tw> wrote:
> I modified this dts to:
>
> Renesas R-Car Gen3 RPC-IF controller Device Tree Bindings
>  --------------------------------------------------------------------
>
>  Required properties:
>  - compatible: should be an SoC-specific compatible value, followed by
>                "renesas,rcar-gen3-rpc" as a fallback.

Please list the supported SoC-specific compatible values, so
scripts/checkpatch.pl
can validate patches adding RPC device nodes to DTS files.

>  - #address-cells: should be 1
>  - #size-cells: should be 0
>  - reg: should contain three register areas:
>          first for the base address of rpc-if registers,
>          second for the direct mapping read mode and
>          third for the write buffer area.
>  - reg-names: should contain "regs", "dirmap" and "wbuf"
>  - clock-names: should contain "rpc"
>  - clocks: should contain 1 entries for the module's clock

Please revert the order of clocks and clock-names, cfr. reg and reg-names.

>  Example:
>
>          rpc: rpc@ee200000 {
>                  compatible = "renesas,r8a7795-rpc", "renesas,rcar-gen3-rpc";
>                  reg = <0 0xee200000 0 0x200>, <0 0x08000000 0 0x4000000>,
>                        <0 0xee208000 0 0x100>;
>                  reg-names = "regs", "dirmap", "wbuf";
>                  clocks = <&cpg CPG_MOD 917>;
>                  power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
>                  resets = <&cpg 917>;
>                  clock-names = "rpc";

Please move clock-names just below clocks.

>                  #address-cells = <1>;
>                  #size-cells = <0>;
>
>                  flash@0 {
>                          compatible = "jedec,spi-nor";
>                          reg = <0>;
>                          spi-max-frequency = <40000000>;
>                          spi-tx-bus-width = <1>;
>                          spi-rx-bus-width = <1>;
>                  };
>          };
>
>
> If it is ok and I will submit it in [PATCH v7 2/2].

Looks good, with the above changes made.

Thanks!

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

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

* Re: [PATCH v6 1/2] spi: Add Renesas R-Car Gen3 RPC-IF SPI controller driver
  2019-01-18  5:54 ` [PATCH v6 1/2] spi: Add Renesas R-Car Gen3 RPC-IF SPI controller driver Mason Yang
  2019-01-18  8:25   ` Geert Uytterhoeven
@ 2019-01-18 19:43   ` Sergei Shtylyov
       [not found]     ` <OFE50FED81.5C117A38-ON48258389.0012FCE2-48258389.00139BD2@mxic.com.tw>
  1 sibling, 1 reply; 15+ messages in thread
From: Sergei Shtylyov @ 2019-01-18 19:43 UTC (permalink / raw)
  To: Mason Yang, broonie, marek.vasut, linux-kernel, linux-spi,
	bbrezillon, linux-renesas-soc, Geert Uytterhoeven
  Cc: juliensu, Simon Horman, zhengxunli

Hello!

On 01/18/2019 08:54 AM, Mason Yang wrote:

> Add a driver for Renesas R-Car Gen3 RPC-IF SPI controller.
> 
> Signed-off-by: Mason Yang <masonccyang@mxic.com.tw>
> Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
[...]
> diff --git a/drivers/spi/spi-renesas-rpc.c b/drivers/spi/spi-renesas-rpc.c
> new file mode 100644
> index 0000000..692c760
> --- /dev/null
> +++ b/drivers/spi/spi-renesas-rpc.c
> @@ -0,0 +1,800 @@
[...]
> +#define RPC_DRENR		0x001C	// R/W
> +#define RPC_DRENR_CDB(o)	(u32)((((o) & 0x3) << 30))
> +#define RPC_DRENR_OCDB(o)	(((o) & 0x3) << 28)
> +#define RPC_DRENR_ADB(o)	(((o) & 0x3) << 24)
> +#define RPC_DRENR_OPDB(o)	(((o) & 0x3) << 20)
> +#define RPC_DRENR_SPIDB(o)	(((o) & 0x3) << 16)

   Manual v1.00 calls it DRDB, not SPIDB.

[...]
> +#define RPC_SMENR		0x0030	// R/W
> +#define RPC_SMENR_CDB(o)	(((o) & 0x2) << 30)
> +#define RPC_SMENR_OCDB(o)	(((o) & 0x2) << 28)
> +#define RPC_SMENR_ADB(o)	(((o) & 0x2) << 24)
> +#define RPC_SMENR_OPDB(o)	(((o) & 0x2) << 20)
> +#define RPC_SMENR_SPIDB(o)	(((o) & 0x2) << 16)

   Ugh, s/0x2/0x3/! :-/

[...]
> +#define RPC_SMDRENR		0x0064	// R/W
> +#define RPC_SMDRENR_HYPE	(0x5 << 12)

   s/0x5/0x7/, and this is a field, not value.

[...]
> +static int rpc_spi_probe(struct platform_device *pdev)
> +{
> +	struct spi_controller *ctlr;
> +	struct resource *res;
> +	struct rpc_spi *rpc;
> +	const struct regmap_config *regmap_config;
> +	struct device_node *rpc_if;
> +	int ret;
> +
> +	rpc_if = of_find_compatible_node(pdev->dev.of_node, NULL,
> +					 "jedec,spi-nor");

   I doubt that this is a correct function to check for the child node's
"compatible" prop...

[...]
> +	regmap_config = &rpc_spi_regmap_config;

   Doesn't look like this variable is needed...

> +	rpc->regmap = devm_regmap_init_mmio(&pdev->dev, rpc->base,
> +					    regmap_config);
> +	if (IS_ERR(rpc->regmap)) {
> +		dev_err(&pdev->dev, "failed to init regmap %ld for rpc-spi\n",

   How about:

		dev_err(&pdev->dev, "failed to init regmap for rpc-spi, error %ld\n",

[...]
> +	ret = spi_register_controller(ctlr);
> +	if (ret) {
> +		dev_err(&pdev->dev, "spi_register_master failed\n");

   You forgot to update the message. :-)

[...]

MBR, Sergei

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

* Re: [PATCH v6 1/2] spi: Add Renesas R-Car Gen3 RPC-IF SPI controller driver
       [not found]     ` <OFE50FED81.5C117A38-ON48258389.0012FCE2-48258389.00139BD2@mxic.com.tw>
@ 2019-01-21 18:14       ` Sergei Shtylyov
  0 siblings, 0 replies; 15+ messages in thread
From: Sergei Shtylyov @ 2019-01-21 18:14 UTC (permalink / raw)
  To: masonccyang
  Cc: bbrezillon, broonie, Geert Uytterhoeven, Simon Horman, juliensu,
	linux-kernel, linux-renesas-soc, linux-spi, marek.vasut,
	zhengxunli

Hello!

On 01/21/2019 06:34 AM, masonccyang@mxic.com.tw wrote:

>> > +#define RPC_SMENR      0x0030   // R/W
>> > +#define RPC_SMENR_CDB(o)   (((o) & 0x2) << 30)
>> > +#define RPC_SMENR_OCDB(o)   (((o) & 0x2) << 28)
>> > +#define RPC_SMENR_ADB(o)   (((o) & 0x2) << 24)
>> > +#define RPC_SMENR_OPDB(o)   (((o) & 0x2) << 20)
>> > +#define RPC_SMENR_SPIDB(o)   (((o) & 0x2) << 16)
>>
>>    Ugh, s/0x2/0x3/! :-/
>>
>> [...]
>> > +#define RPC_SMDRENR      0x0064   // R/W
>> > +#define RPC_SMDRENR_HYPE   (0x5 << 12)
>>
>>    s/0x5/0x7/, and this is a field, not value.
>>
> 
> okay, both 0x2 and 0x5 are just make sure these registers was
> writing a correct value rather than a prohibited value.
> anyway, I will patch them.

   TIA.

>> [...]
>> > +static int rpc_spi_probe(struct platform_device *pdev)
>> > +{
>> > +   struct spi_controller *ctlr;
>> > +   struct resource *res;
>> > +   struct rpc_spi *rpc;
>> > +   const struct regmap_config *regmap_config;
>> > +   struct device_node *rpc_if;
>> > +   int ret;
>> > +
>> > +   rpc_if = of_find_compatible_node(pdev->dev.of_node, NULL,
>> > +                "jedec,spi-nor");
>>
>>    I doubt that this is a correct function to check for the child node's
>> "compatible" prop...

   You need of_get_next_child() or of_get_next_available_child().

>>
>> [...]
>> > +   regmap_config = &rpc_spi_regmap_config;
>>
>>    Doesn't look like this variable is needed...
> 
> why ?

   Why not just use &rpc_spi_regmap_config below?

>> > +   rpc->regmap = devm_regmap_init_mmio(&pdev->dev, rpc->base,
>> > +                   regmap_config);
[...]

> Mason

MBR, Sergei

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

end of thread, other threads:[~2019-01-21 18:14 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-01-18  5:54 [PATCH v6 0/2] spi: Add Renesas R-Car Gen3 RPC-IF SPI driver Mason Yang
2019-01-18  5:54 ` [PATCH v6 1/2] spi: Add Renesas R-Car Gen3 RPC-IF SPI controller driver Mason Yang
2019-01-18  8:25   ` Geert Uytterhoeven
2019-01-18 19:43   ` Sergei Shtylyov
     [not found]     ` <OFE50FED81.5C117A38-ON48258389.0012FCE2-48258389.00139BD2@mxic.com.tw>
2019-01-21 18:14       ` Sergei Shtylyov
2019-01-18  5:54 ` [PATCH v6 2/2] dt-bindings: spi: Document Renesas R-Car Gen3 RPC-IF controller bindings Mason Yang
2019-01-18  6:16   ` Marek Vasut
     [not found]     ` <OF914E6438.79205FE6-ON48258386.002973E8-48258386.002A41F0@mxic.com.tw>
2019-01-18  7:46       ` Marek Vasut
2019-01-18  8:23     ` Sergei Shtylyov
2019-01-18  8:03   ` Geert Uytterhoeven
2019-01-18  8:08     ` Marek Vasut
2019-01-18  8:10       ` Geert Uytterhoeven
2019-01-18  8:12         ` Marek Vasut
     [not found]     ` <OFBD5366C8.433ADACB-ON48258386.00336667-48258386.00340E20@mxic.com.tw>
2019-01-18 10:39       ` Geert Uytterhoeven
2019-01-18  8:18   ` Sergei Shtylyov

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).