Hi Wolfram, On Wed, Sep 22, 2021 at 11:10 AM Wolfram Sang <wsa+renesas@xxxxxxxxxxxxxxxxxxxx> wrote: > This patch fixes 2 problems: > [1] The output warning logs and data loss when performing > mount/umount then remount the device with jffs2 format. > [2] The access width of SMWDR[0:1]/SMRDR[0:1] register is wrong. Revisiting commit fff53a551db50f5e ("memory: renesas-rpc-if: Correct QSPI data transfer in Manual mode") in v5.16-rc1... > --- a/drivers/memory/renesas-rpc-if.c > +++ b/drivers/memory/renesas-rpc-if.c > int rpcif_manual_xfer(struct rpcif *rpc) > { > - u32 smenr, smcr, pos = 0, max = 4; > + u32 smenr, smcr, pos = 0, max = rpc->bus_size == 2 ? 8 : 4; > int ret = 0; > > - if (rpc->bus_size == 2) > - max = 8; > - > pm_runtime_get_sync(rpc->dev); > > regmap_update_bits(rpc->regmap, RPCIF_PHYCNT, > @@ -378,37 +424,36 @@ int rpcif_manual_xfer(struct rpcif *rpc) > regmap_write(rpc->regmap, RPCIF_SMOPR, rpc->option); > regmap_write(rpc->regmap, RPCIF_SMDMCR, rpc->dummy); > regmap_write(rpc->regmap, RPCIF_SMDRENR, rpc->ddr); > + regmap_write(rpc->regmap, RPCIF_SMADR, rpc->smadr); > smenr = rpc->enable; > > switch (rpc->dir) { > case RPCIF_DATA_OUT: > while (pos < rpc->xferlen) { > - u32 nbytes = rpc->xferlen - pos; > - u32 data[2]; > + u32 bytes_left = rpc->xferlen - pos; > + u32 nbytes, data[2]; > > smcr = rpc->smcr | RPCIF_SMCR_SPIE; > - if (nbytes > max) { > - nbytes = max; > + > + /* nbytes may only be 1, 2, 4, or 8 */ > + nbytes = bytes_left >= max ? max : (1 << ilog2(bytes_left)); > + if (bytes_left > nbytes) > smcr |= RPCIF_SMCR_SSLKP; > - } > + > + smenr |= RPCIF_SMENR_SPIDE(rpcif_bits_set(rpc, nbytes)); > + regmap_write(rpc->regmap, RPCIF_SMENR, smenr); > > memcpy(data, rpc->buffer + pos, nbytes); > - if (nbytes > 4) { > + if (nbytes == 8) { > regmap_write(rpc->regmap, RPCIF_SMWDR1, > data[0]); > regmap_write(rpc->regmap, RPCIF_SMWDR0, > data[1]); > - } else if (nbytes > 2) { > + } else { > regmap_write(rpc->regmap, RPCIF_SMWDR0, > data[0]); > - } else { > - regmap_write(rpc->regmap, RPCIF_SMWDR0, > - data[0] << 16); > } > > - regmap_write(rpc->regmap, RPCIF_SMADR, > - rpc->smadr + pos); Removing this implies SMADR is auto-incrementing for writes... > - regmap_write(rpc->regmap, RPCIF_SMENR, smenr); > regmap_write(rpc->regmap, RPCIF_SMCR, smcr); > ret = wait_msg_xfer_end(rpc); > if (ret) > @@ -448,14 +493,16 @@ int rpcif_manual_xfer(struct rpcif *rpc) > break; > } > while (pos < rpc->xferlen) { > - u32 nbytes = rpc->xferlen - pos; > - u32 data[2]; > + u32 bytes_left = rpc->xferlen - pos; > + u32 nbytes, data[2]; > > - if (nbytes > max) > - nbytes = max; > + /* nbytes may only be 1, 2, 4, or 8 */ > + nbytes = bytes_left >= max ? max : (1 << ilog2(bytes_left)); > > regmap_write(rpc->regmap, RPCIF_SMADR, > rpc->smadr + pos); ... while keeping this assumes SMADR is not auto-incrementing for reads? Figure 62.17 "Example of Data Transfer Setting Flow in Manual Operating Mode" does show writing SMADR in each loop iteration. I cannot find anything about auto-incrementing in the documentation, except for Figure 62.28 "Write Buffer Usage Sequence", which does not apply as Linux does not support the write buffer yet. Given you tested this, and the BSP commit 0d37f69cacb33435 ("memory: renesas-rpc-if: Correct QSPI data transfer in Manual mode") does the same, I assume it's working fine? Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@xxxxxxxxxxxxxx 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