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@xxxxxxxxx> --- drivers/memory/renesas-rpc-if.c | 56 +++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) 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 -- 2.17.1