diff mbox series

[v1,2/2] memory: renesas-rpc-if: Add Octal DTR mode support

Message ID 20221124073957.22471-3-jaimeliao.tw@gmail.com
State New
Headers show
Series Add Octal DTR support on RPC driver | expand

Commit Message

Jaime Liao Nov. 24, 2022, 7:39 a.m. UTC
1. Support Octal DTR manual mode (Program & Erase & register)
2. Support diramap read (enable external address space read mode)

Signed-off-by: JaimeLiao <jaimeliao.tw@gmail.com>
---
 drivers/memory/renesas-rpc-if.c | 56 +++++++++++++++++++++++++++++++++
 1 file changed, 56 insertions(+)

Comments

kernel test robot Nov. 30, 2022, 2:34 p.m. UTC | #1
Hi JaimeLiao,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on broonie-spi/for-next]
[also build test WARNING on krzk-mem-ctrl/for-next linus/master v6.1-rc7 next-20221130]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/JaimeLiao/Add-Octal-DTR-support-on-RPC-driver/20221124-154211
base:   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next
patch link:    https://lore.kernel.org/r/20221124073957.22471-3-jaimeliao.tw%40gmail.com
patch subject: [PATCH v1 2/2] memory: renesas-rpc-if: Add Octal DTR mode support
config: hexagon-randconfig-r004-20221128
compiler: clang version 16.0.0 (https://github.com/llvm/llvm-project 6e4cea55f0d1104408b26ac574566a0e4de48036)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/intel-lab-lkp/linux/commit/61bae8cb17ad5715386ee18a1d06549843775cd0
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review JaimeLiao/Add-Octal-DTR-support-on-RPC-driver/20221124-154211
        git checkout 61bae8cb17ad5715386ee18a1d06549843775cd0
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=hexagon SHELL=/bin/bash drivers/memory/

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

   In file included from drivers/memory/renesas-rpc-if.c:11:
   In file included from include/linux/io.h:13:
   In file included from arch/hexagon/include/asm/io.h:334:
   include/asm-generic/io.h:547:31: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           val = __raw_readb(PCI_IOBASE + addr);
                             ~~~~~~~~~~ ^
   include/asm-generic/io.h:560:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           val = __le16_to_cpu((__le16 __force)__raw_readw(PCI_IOBASE + addr));
                                                           ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/little_endian.h:37:51: note: expanded from macro '__le16_to_cpu'
   #define __le16_to_cpu(x) ((__force __u16)(__le16)(x))
                                                     ^
   In file included from drivers/memory/renesas-rpc-if.c:11:
   In file included from include/linux/io.h:13:
   In file included from arch/hexagon/include/asm/io.h:334:
   include/asm-generic/io.h:573:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr));
                                                           ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/little_endian.h:35:51: note: expanded from macro '__le32_to_cpu'
   #define __le32_to_cpu(x) ((__force __u32)(__le32)(x))
                                                     ^
   In file included from drivers/memory/renesas-rpc-if.c:11:
   In file included from include/linux/io.h:13:
   In file included from arch/hexagon/include/asm/io.h:334:
   include/asm-generic/io.h:584:33: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           __raw_writeb(value, PCI_IOBASE + addr);
                               ~~~~~~~~~~ ^
   include/asm-generic/io.h:594:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           __raw_writew((u16 __force)cpu_to_le16(value), PCI_IOBASE + addr);
                                                         ~~~~~~~~~~ ^
   include/asm-generic/io.h:604:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           __raw_writel((u32 __force)cpu_to_le32(value), PCI_IOBASE + addr);
                                                         ~~~~~~~~~~ ^
>> drivers/memory/renesas-rpc-if.c:484:30: warning: use of logical '&&' with constant operand [-Wconstant-logical-operand]
                   if (op->ocmd.buswidth == 8 && RPCIF_SMENR_OCDE)
                                              ^  ~~~~~~~~~~~~~~~~
   drivers/memory/renesas-rpc-if.c:484:30: note: use '&' for a bitwise operation
                   if (op->ocmd.buswidth == 8 && RPCIF_SMENR_OCDE)
                                              ^~
                                              &
   drivers/memory/renesas-rpc-if.c:484:30: note: remove constant to silence this warning
                   if (op->ocmd.buswidth == 8 && RPCIF_SMENR_OCDE)
                                             ~^~~~~~~~~~~~~~~~~~~
   7 warnings generated.


vim +484 drivers/memory/renesas-rpc-if.c

   381	
   382	void rpcif_prepare(struct rpcif *rpc, const struct rpcif_op *op, u64 *offs,
   383			   size_t *len)
   384	{
   385		rpc->smcr = 0;
   386		rpc->smadr = 0;
   387		rpc->enable = 0;
   388		rpc->command = 0;
   389		rpc->option = 0;
   390		rpc->dummy = 0;
   391		rpc->ddr = 0;
   392		rpc->xferlen = 0;
   393	
   394		if (op->cmd.buswidth) {
   395			rpc->enable  = RPCIF_SMENR_CDE |
   396				RPCIF_SMENR_CDB(rpcif_bit_size(op->cmd.buswidth));
   397			rpc->command = RPCIF_SMCMR_CMD(op->cmd.opcode);
   398			if (op->cmd.ddr)
   399				rpc->ddr = RPCIF_SMDRENR_HYPE(0x5);
   400		}
   401		if (op->ocmd.buswidth) {
   402			rpc->enable  |= RPCIF_SMENR_OCDE |
   403				RPCIF_SMENR_OCDB(rpcif_bit_size(op->ocmd.buswidth));
   404			rpc->command |= RPCIF_SMCMR_OCMD(op->ocmd.opcode);
   405		}
   406	
   407		if (op->addr.buswidth) {
   408			rpc->enable |=
   409				RPCIF_SMENR_ADB(rpcif_bit_size(op->addr.buswidth));
   410			if (op->addr.nbytes == 4)
   411				rpc->enable |= RPCIF_SMENR_ADE(0xF);
   412			else
   413				rpc->enable |= RPCIF_SMENR_ADE(GENMASK(
   414							2, 3 - op->addr.nbytes));
   415			if (op->addr.ddr)
   416				rpc->ddr |= RPCIF_SMDRENR_ADDRE;
   417	
   418			if (offs && len)
   419				rpc->smadr = *offs;
   420			else
   421				rpc->smadr = op->addr.val;
   422		}
   423	
   424		if (op->dummy.buswidth) {
   425			rpc->enable |= RPCIF_SMENR_DME;
   426			rpc->dummy = RPCIF_SMDMCR_DMCYC(op->dummy.ncycles /
   427							op->dummy.buswidth);
   428		}
   429	
   430		if (op->option.buswidth) {
   431			rpc->enable |= RPCIF_SMENR_OPDE(
   432				rpcif_bits_set(rpc, op->option.nbytes)) |
   433				RPCIF_SMENR_OPDB(rpcif_bit_size(op->option.buswidth));
   434			if (op->option.ddr)
   435				rpc->ddr |= RPCIF_SMDRENR_OPDRE;
   436			rpc->option = op->option.val;
   437		}
   438	
   439		rpc->dir = op->data.dir;
   440		if (op->data.buswidth) {
   441			u32 nbytes;
   442	
   443			rpc->buffer = op->data.buf.in;
   444			switch (op->data.dir) {
   445			case RPCIF_DATA_IN:
   446				rpc->smcr = RPCIF_SMCR_SPIRE;
   447				break;
   448			case RPCIF_DATA_OUT:
   449				rpc->smcr = RPCIF_SMCR_SPIWE;
   450				break;
   451			default:
   452				break;
   453			}
   454			if (op->data.ddr)
   455				rpc->ddr |= RPCIF_SMDRENR_SPIDRE;
   456	
   457			if (offs && len)
   458				nbytes = *len;
   459			else
   460				nbytes = op->data.nbytes;
   461			rpc->xferlen = nbytes;
   462	
   463			rpc->enable |= RPCIF_SMENR_SPIDB(rpcif_bit_size(op->data.buswidth));
   464		}
   465	       /* Fixup in Octal DTR mode */
   466		if (op->cmd.buswidth == 8 && op->cmd.ddr) {
   467			rpc->bus_size = 2;
   468	
   469			regmap_update_bits(rpc->regmap, RPCIF_PHYCNT,
   470					   RPCIF_PHYCNT_OCTA(0x2) | RPCIF_PHYCNT_OCT |
   471					   RPCIF_PHYCNT_PHYMEM(0x1) ,
   472					   RPCIF_PHYCNT_OCTA(0x2) | RPCIF_PHYCNT_OCT |
   473					   RPCIF_PHYCNT_PHYMEM(0x1));
   474			regmap_update_bits(rpc->regmap, RPCIF_CMNCR, RPCIF_CMNCR_BSZ(1),
   475					   RPCIF_CMNCR_BSZ(1));
   476	
   477			regmap_update_bits(rpc->regmap, RPCIF_PHYOFFSET1,
   478					   RPCIF_PHYOFFSET1_DDRTMG(3),
   479					   RPCIF_PHYOFFSET1_DDRTMG(2));
   480			regmap_update_bits(rpc->regmap, RPCIF_PHYOFFSET2,
   481					   RPCIF_PHYOFFSET2_OCTTMG(7),
   482					   RPCIF_PHYOFFSET2_OCTTMG(3));
   483	
 > 484			if (op->ocmd.buswidth == 8 && RPCIF_SMENR_OCDE)
   485				rpc->enable &= ~RPCIF_SMENR_OCDE;
   486	
   487			if (op->addr.ddr)
   488				rpc->enable &= ~RPCIF_SMENR_ADE(0xF) |
   489						RPCIF_SMENR_ADE(0xc);
   490	
   491			if (op->dummy.buswidth == 8)
   492				rpc->dummy =
   493					RPCIF_SMDMCR_DMCYC(op->dummy.ncycles / 2);
   494	
   495			if (op->data.dir == RPCIF_DATA_IN)
   496				/* Set Extenal Address space Read mode */
   497				if (op->data.buswidth == 8 && op->data.ddr) {
   498					regmap_update_bits(rpc->regmap, RPCIF_PHYCNT,
   499						RPCIF_PHYCNT_EXDS, RPCIF_PHYCNT_EXDS);
   500				}
   501		}
   502	}
   503	EXPORT_SYMBOL(rpcif_prepare);
   504
diff mbox series

Patch

diff --git a/drivers/memory/renesas-rpc-if.c b/drivers/memory/renesas-rpc-if.c
index bdf0a7f68ff2..db5019a7190e 100644
--- a/drivers/memory/renesas-rpc-if.c
+++ b/drivers/memory/renesas-rpc-if.c
@@ -462,6 +462,43 @@  void rpcif_prepare(struct rpcif *rpc, const struct rpcif_op *op, u64 *offs,
 
 		rpc->enable |= RPCIF_SMENR_SPIDB(rpcif_bit_size(op->data.buswidth));
 	}
+       /* Fixup in Octal DTR mode */
+	if (op->cmd.buswidth == 8 && op->cmd.ddr) {
+		rpc->bus_size = 2;
+
+		regmap_update_bits(rpc->regmap, RPCIF_PHYCNT,
+				   RPCIF_PHYCNT_OCTA(0x2) | RPCIF_PHYCNT_OCT |
+				   RPCIF_PHYCNT_PHYMEM(0x1) ,
+				   RPCIF_PHYCNT_OCTA(0x2) | RPCIF_PHYCNT_OCT |
+				   RPCIF_PHYCNT_PHYMEM(0x1));
+		regmap_update_bits(rpc->regmap, RPCIF_CMNCR, RPCIF_CMNCR_BSZ(1),
+				   RPCIF_CMNCR_BSZ(1));
+
+		regmap_update_bits(rpc->regmap, RPCIF_PHYOFFSET1,
+				   RPCIF_PHYOFFSET1_DDRTMG(3),
+				   RPCIF_PHYOFFSET1_DDRTMG(2));
+		regmap_update_bits(rpc->regmap, RPCIF_PHYOFFSET2,
+				   RPCIF_PHYOFFSET2_OCTTMG(7),
+				   RPCIF_PHYOFFSET2_OCTTMG(3));
+
+		if (op->ocmd.buswidth == 8 && RPCIF_SMENR_OCDE)
+			rpc->enable &= ~RPCIF_SMENR_OCDE;
+
+		if (op->addr.ddr)
+			rpc->enable &= ~RPCIF_SMENR_ADE(0xF) |
+					RPCIF_SMENR_ADE(0xc);
+
+		if (op->dummy.buswidth == 8)
+			rpc->dummy =
+				RPCIF_SMDMCR_DMCYC(op->dummy.ncycles / 2);
+
+		if (op->data.dir == RPCIF_DATA_IN)
+			/* Set Extenal Address space Read mode */
+			if (op->data.buswidth == 8 && op->data.ddr) {
+				regmap_update_bits(rpc->regmap, RPCIF_PHYCNT,
+					RPCIF_PHYCNT_EXDS, RPCIF_PHYCNT_EXDS);
+			}
+	}
 }
 EXPORT_SYMBOL(rpcif_prepare);
 
@@ -501,10 +538,24 @@  int rpcif_manual_xfer(struct rpcif *rpc)
 			rpc->xfer_size = nbytes;
 
 			memcpy(data, rpc->buffer + pos, nbytes);
+			if (rpc->bus_size == 2) {
+				data[0] = (data[0] & 0x00f000f0) << 8 |
+					  (data[0] & 0xf000f000) >> 4 |
+					  (data[0] & 0x000f000f) << 4 |
+					  (data[0] & 0x0f000f00) >> 8;
+
+				data[1] = (data[1] & 0x00f000f0) << 8 |
+					  (data[1] & 0xf000f000) >> 4 |
+					  (data[1] & 0x000f000f) << 4 |
+					  (data[1] & 0x0f000f00) >> 8;
+			}
 			if (nbytes == 8)
 				regmap_write(rpc->regmap, RPCIF_SMWDR1, *p++);
 			regmap_write(rpc->regmap, RPCIF_SMWDR0, *p);
 
+			regmap_write(rpc->regmap, RPCIF_SMADR,
+				     rpc->smadr + pos);
+			regmap_write(rpc->regmap, RPCIF_SMENR, smenr);
 			regmap_write(rpc->regmap, RPCIF_SMCR, smcr);
 			ret = wait_msg_xfer_end(rpc);
 			if (ret)
@@ -652,9 +703,14 @@  ssize_t rpcif_dirmap_read(struct rpcif *rpc, u64 offs, size_t len, void *buf)
 	regmap_write(rpc->regmap, RPCIF_DROPR, rpc->option);
 	regmap_write(rpc->regmap, RPCIF_DRENR,
 		     rpc->enable & ~RPCIF_SMENR_SPIDE(0xF));
+	regmap_write(rpc->regmap, RPCIF_SMENR,
+		     rpc->enable & ~RPCIF_SMENR_SPIDE(0xF));
 	regmap_write(rpc->regmap, RPCIF_DRDMCR, rpc->dummy);
 	regmap_write(rpc->regmap, RPCIF_DRDRENR, rpc->ddr);
 
+	regmap_update_bits(rpc->regmap, RPCIF_DRENR, RPCIF_DRENR_ADE(0xF),
+			   RPCIF_DRENR_ADE(0xF));
+
 	if (rpc->bus_size == 2)
 		memcpy_fromio_readw(buf, rpc->dirmap + from, len);
 	else