Message ID | 1611908018-29937-3-git-send-email-zhengxunli@mxic.com.tw |
---|---|
State | Not Applicable |
Headers | show |
Series | Add octal DTR support for Macronix flash | expand |
Hello, zhengxunli <zhengxunli@mxic.com.tw> wrote on Fri, 29 Jan 2021 16:13:37 +0800: > Driver patch for octal 8D-8D-8D mode support. > > Signed-off-by: zhengxunli <zhengxunli@mxic.com.tw> > --- > drivers/spi/spi-mxic.c | 33 ++++++++++++++++++++++----------- > 1 file changed, 22 insertions(+), 11 deletions(-) > > diff --git a/drivers/spi/spi-mxic.c b/drivers/spi/spi-mxic.c > index 96b4182..821328a 100644 > --- a/drivers/spi/spi-mxic.c > +++ b/drivers/spi/spi-mxic.c > @@ -335,8 +335,8 @@ static int mxic_spi_data_xfer(struct mxic_spi *mxic, const void *txbuf, > static bool mxic_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) > + if (op->data.buswidth > 8 || op->addr.buswidth > 8 || > + op->dummy.buswidth > 8 || op->cmd.buswidth > 8) > return false; > > if (op->data.nbytes && op->dummy.nbytes && > @@ -346,7 +346,7 @@ static bool mxic_spi_mem_supports_op(struct spi_mem *mem, > if (op->addr.nbytes > 7) > return false; > > - return spi_mem_default_supports_op(mem, op); > + return true; Does not seem correct. Why would you drop this check? > } > > static int mxic_spi_mem_exec_op(struct spi_mem *mem, > @@ -355,14 +355,15 @@ static int mxic_spi_mem_exec_op(struct spi_mem *mem, > struct mxic_spi *mxic = spi_master_get_devdata(mem->spi->master); > int nio = 1, i, ret; > u32 ss_ctrl; > - u8 addr[8]; > - u8 opcode = op->cmd.opcode; > + u8 addr[8], cmd[2]; > > ret = mxic_spi_set_freq(mxic, mem->spi->max_speed_hz); > if (ret) > return ret; > > - if (mem->spi->mode & (SPI_TX_QUAD | SPI_RX_QUAD)) > + if (mem->spi->mode & (SPI_TX_OCTAL | SPI_RX_OCTAL)) > + nio = 8; > + else if (mem->spi->mode & (SPI_TX_QUAD | SPI_RX_QUAD)) > nio = 4; > else if (mem->spi->mode & (SPI_TX_DUAL | SPI_RX_DUAL)) > nio = 2; > @@ -374,19 +375,25 @@ static int mxic_spi_mem_exec_op(struct spi_mem *mem, > mxic->regs + HC_CFG); > writel(HC_EN_BIT, mxic->regs + HC_EN); > > - ss_ctrl = OP_CMD_BYTES(1) | OP_CMD_BUSW(fls(op->cmd.buswidth) - 1); > + ss_ctrl = OP_CMD_BYTES(op->cmd.nbytes) | > + OP_CMD_BUSW(fls(op->cmd.buswidth) - 1) | > + (op->cmd.dtr ? OP_CMD_DDR : 0); > > if (op->addr.nbytes) > ss_ctrl |= OP_ADDR_BYTES(op->addr.nbytes) | > - OP_ADDR_BUSW(fls(op->addr.buswidth) - 1); > + OP_ADDR_BUSW(fls(op->addr.buswidth) - 1) | > + (op->addr.dtr ? OP_ADDR_DDR : 0); > > if (op->dummy.nbytes) > ss_ctrl |= OP_DUMMY_CYC(op->dummy.nbytes); > > if (op->data.nbytes) { > - ss_ctrl |= OP_DATA_BUSW(fls(op->data.buswidth) - 1); > + ss_ctrl |= OP_DATA_BUSW(fls(op->data.buswidth) - 1) | > + (op->data.dtr ? OP_DATA_DDR : 0); > if (op->data.dir == SPI_MEM_DATA_IN) > ss_ctrl |= OP_READ; > + if (op->data.dtr) > + ss_ctrl |= OP_DQS_EN; > } > > writel(ss_ctrl, mxic->regs + SS_CTRL(mem->spi->chip_select)); > @@ -394,7 +401,10 @@ static int mxic_spi_mem_exec_op(struct spi_mem *mem, > writel(readl(mxic->regs + HC_CFG) | HC_CFG_MAN_CS_ASSERT, > mxic->regs + HC_CFG); > > - ret = mxic_spi_data_xfer(mxic, &opcode, NULL, 1); > + for (i = 0; i < op->cmd.nbytes; i++) Can we add a check in mxic_spi_mem_check_op to ensure nbytes is never > 2 ? > + cmd[i] = op->cmd.opcode >> (8 * (op->cmd.nbytes - i - 1)); > + > + ret = mxic_spi_data_xfer(mxic, cmd, NULL, op->cmd.nbytes); > if (ret) > goto out; > > @@ -567,7 +577,8 @@ static int mxic_spi_probe(struct platform_device *pdev) > master->bits_per_word_mask = SPI_BPW_MASK(8); > master->mode_bits = SPI_CPOL | SPI_CPHA | > SPI_RX_DUAL | SPI_TX_DUAL | > - SPI_RX_QUAD | SPI_TX_QUAD; > + SPI_RX_QUAD | SPI_TX_QUAD | > + SPI_RX_OCTAL | SPI_TX_OCTAL; > > mxic_spi_hw_init(mxic); > Otherwise looks fine. Thanks, Miquèl
On 01/02/21 03:49PM, Miquel Raynal wrote: > Hello, > > zhengxunli <zhengxunli@mxic.com.tw> wrote on Fri, 29 Jan 2021 16:13:37 > +0800: > > > Driver patch for octal 8D-8D-8D mode support. > > > > Signed-off-by: zhengxunli <zhengxunli@mxic.com.tw> > > --- > > drivers/spi/spi-mxic.c | 33 ++++++++++++++++++++++----------- > > 1 file changed, 22 insertions(+), 11 deletions(-) > > > > diff --git a/drivers/spi/spi-mxic.c b/drivers/spi/spi-mxic.c > > index 96b4182..821328a 100644 > > --- a/drivers/spi/spi-mxic.c > > +++ b/drivers/spi/spi-mxic.c > > @@ -335,8 +335,8 @@ static int mxic_spi_data_xfer(struct mxic_spi *mxic, const void *txbuf, > > static bool mxic_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) > > + if (op->data.buswidth > 8 || op->addr.buswidth > 8 || > > + op->dummy.buswidth > 8 || op->cmd.buswidth > 8) > > return false; Can the controller support mixed DTR modes? For example, can it support 4S-4D-4D operations? If no, then please add a check for that here. See cqspi_supports_mem_op() for an example. > > > > if (op->data.nbytes && op->dummy.nbytes && > > @@ -346,7 +346,7 @@ static bool mxic_spi_mem_supports_op(struct spi_mem *mem, > > if (op->addr.nbytes > 7) > > return false; > > > > - return spi_mem_default_supports_op(mem, op); > > + return true; > > Does not seem correct. Why would you drop this check? spi_mem_default_supports_op() rejects DTR ops for backward compatibility. But skipping that would mean skipping the spi_check_buswidth_req() calls [0]. Maybe we should export that part as a library function so controllers can use it and not have to roll their own logic? [0] They are not _technically_ needed. Not calling them would mean the spi-{rx,tx}-bus-width DT properties would be ignored. The negotiation for supported opcodes will happen on what the controller _actually_ supports and what SPI NOR says the flash supports. So for example you can't force a octal capable flash to use quad mode. Not sure if that is a good thing or a bad thing. > > } > > > > static int mxic_spi_mem_exec_op(struct spi_mem *mem, > > @@ -355,14 +355,15 @@ static int mxic_spi_mem_exec_op(struct spi_mem *mem, > > struct mxic_spi *mxic = spi_master_get_devdata(mem->spi->master); > > int nio = 1, i, ret; > > u32 ss_ctrl; > > - u8 addr[8]; > > - u8 opcode = op->cmd.opcode; > > + u8 addr[8], cmd[2]; > > > > ret = mxic_spi_set_freq(mxic, mem->spi->max_speed_hz); > > if (ret) > > return ret; > > > > - if (mem->spi->mode & (SPI_TX_QUAD | SPI_RX_QUAD)) > > + if (mem->spi->mode & (SPI_TX_OCTAL | SPI_RX_OCTAL)) > > + nio = 8; > > + else if (mem->spi->mode & (SPI_TX_QUAD | SPI_RX_QUAD)) Hmm, shouldn't you be looking at op->*.buswidth? > > nio = 4; > > else if (mem->spi->mode & (SPI_TX_DUAL | SPI_RX_DUAL)) > > nio = 2; > > @@ -374,19 +375,25 @@ static int mxic_spi_mem_exec_op(struct spi_mem *mem, > > mxic->regs + HC_CFG); > > writel(HC_EN_BIT, mxic->regs + HC_EN); > > > > - ss_ctrl = OP_CMD_BYTES(1) | OP_CMD_BUSW(fls(op->cmd.buswidth) - 1); > > + ss_ctrl = OP_CMD_BYTES(op->cmd.nbytes) | > > + OP_CMD_BUSW(fls(op->cmd.buswidth) - 1) | > > + (op->cmd.dtr ? OP_CMD_DDR : 0); > > > > if (op->addr.nbytes) > > ss_ctrl |= OP_ADDR_BYTES(op->addr.nbytes) | > > - OP_ADDR_BUSW(fls(op->addr.buswidth) - 1); > > + OP_ADDR_BUSW(fls(op->addr.buswidth) - 1) | > > + (op->addr.dtr ? OP_ADDR_DDR : 0); > > > > if (op->dummy.nbytes) > > ss_ctrl |= OP_DUMMY_CYC(op->dummy.nbytes); > > > > if (op->data.nbytes) { > > - ss_ctrl |= OP_DATA_BUSW(fls(op->data.buswidth) - 1); > > + ss_ctrl |= OP_DATA_BUSW(fls(op->data.buswidth) - 1) | > > + (op->data.dtr ? OP_DATA_DDR : 0); > > if (op->data.dir == SPI_MEM_DATA_IN) > > ss_ctrl |= OP_READ; > > + if (op->data.dtr) > > + ss_ctrl |= OP_DQS_EN; > > } > > > > writel(ss_ctrl, mxic->regs + SS_CTRL(mem->spi->chip_select)); > > @@ -394,7 +401,10 @@ static int mxic_spi_mem_exec_op(struct spi_mem *mem, > > writel(readl(mxic->regs + HC_CFG) | HC_CFG_MAN_CS_ASSERT, > > mxic->regs + HC_CFG); > > > > - ret = mxic_spi_data_xfer(mxic, &opcode, NULL, 1); > > + for (i = 0; i < op->cmd.nbytes; i++) > > Can we add a check in mxic_spi_mem_check_op to ensure nbytes is never > > 2 ? > > > + cmd[i] = op->cmd.opcode >> (8 * (op->cmd.nbytes - i - 1)); > > + > > + ret = mxic_spi_data_xfer(mxic, cmd, NULL, op->cmd.nbytes); > > if (ret) > > goto out; > > > > @@ -567,7 +577,8 @@ static int mxic_spi_probe(struct platform_device *pdev) > > master->bits_per_word_mask = SPI_BPW_MASK(8); > > master->mode_bits = SPI_CPOL | SPI_CPHA | > > SPI_RX_DUAL | SPI_TX_DUAL | > > - SPI_RX_QUAD | SPI_TX_QUAD; > > + SPI_RX_QUAD | SPI_TX_QUAD | > > + SPI_RX_OCTAL | SPI_TX_OCTAL; > > > > mxic_spi_hw_init(mxic); > > > > Otherwise looks fine. > > Thanks, > Miquèl >
Hi Pratyush, Pratyush Yadav <p.yadav@ti.com> wrote on Tue, 2 Feb 2021 01:40:30 +0530: > On 01/02/21 03:49PM, Miquel Raynal wrote: > > Hello, > > > > zhengxunli <zhengxunli@mxic.com.tw> wrote on Fri, 29 Jan 2021 16:13:37 > > +0800: > > > > > Driver patch for octal 8D-8D-8D mode support. > > > > > > Signed-off-by: zhengxunli <zhengxunli@mxic.com.tw> > > > --- > > > drivers/spi/spi-mxic.c | 33 ++++++++++++++++++++++----------- > > > 1 file changed, 22 insertions(+), 11 deletions(-) > > > > > > diff --git a/drivers/spi/spi-mxic.c b/drivers/spi/spi-mxic.c > > > index 96b4182..821328a 100644 > > > --- a/drivers/spi/spi-mxic.c > > > +++ b/drivers/spi/spi-mxic.c > > > @@ -335,8 +335,8 @@ static int mxic_spi_data_xfer(struct mxic_spi *mxic, const void *txbuf, > > > static bool mxic_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) > > > + if (op->data.buswidth > 8 || op->addr.buswidth > 8 || > > > + op->dummy.buswidth > 8 || op->cmd.buswidth > 8) > > > return false; > > Can the controller support mixed DTR modes? For example, can it support > 4S-4D-4D operations? If no, then please add a check for that here. See > cqspi_supports_mem_op() for an example. > > > > > > > if (op->data.nbytes && op->dummy.nbytes && > > > @@ -346,7 +346,7 @@ static bool mxic_spi_mem_supports_op(struct spi_mem *mem, > > > if (op->addr.nbytes > 7) > > > return false; > > > > > > - return spi_mem_default_supports_op(mem, op); > > > + return true; > > > > Does not seem correct. Why would you drop this check? > > spi_mem_default_supports_op() rejects DTR ops for backward > compatibility. > > But skipping that would mean skipping the spi_check_buswidth_req() calls > [0]. Maybe we should export that part as a library function so > controllers can use it and not have to roll their own logic? > > [0] They are not _technically_ needed. Not calling them would mean the > spi-{rx,tx}-bus-width DT properties would be ignored. The negotiation > for supported opcodes will happen on what the controller _actually_ > supports and what SPI NOR says the flash supports. So for example you > can't force a octal capable flash to use quad mode. Not sure if that is > a good thing or a bad thing. I don't think is a good idea to ignore the user inputs. If these properties are populated one will not understand why, in this particular case, they won't get parsed. Perhaps having a spi_mem_dtr_supports_op() or something alike which calls a common helper (eg. spi_mem_generic_supports_op()) shared with spi_mem_default_supports_op() would make sense. > > > > } > > > > > > static int mxic_spi_mem_exec_op(struct spi_mem *mem, > > > @@ -355,14 +355,15 @@ static int mxic_spi_mem_exec_op(struct spi_mem *mem, > > > struct mxic_spi *mxic = spi_master_get_devdata(mem->spi->master); > > > int nio = 1, i, ret; > > > u32 ss_ctrl; > > > - u8 addr[8]; > > > - u8 opcode = op->cmd.opcode; > > > + u8 addr[8], cmd[2]; > > > > > > ret = mxic_spi_set_freq(mxic, mem->spi->max_speed_hz); > > > if (ret) > > > return ret; > > > > > > - if (mem->spi->mode & (SPI_TX_QUAD | SPI_RX_QUAD)) > > > + if (mem->spi->mode & (SPI_TX_OCTAL | SPI_RX_OCTAL)) > > > + nio = 8; > > > + else if (mem->spi->mode & (SPI_TX_QUAD | SPI_RX_QUAD)) > > Hmm, shouldn't you be looking at op->*.buswidth? > > > > nio = 4; > > > else if (mem->spi->mode & (SPI_TX_DUAL | SPI_RX_DUAL)) > > > nio = 2; > > > @@ -374,19 +375,25 @@ static int mxic_spi_mem_exec_op(struct spi_mem *mem, > > > mxic->regs + HC_CFG); > > > writel(HC_EN_BIT, mxic->regs + HC_EN); > > > > > > - ss_ctrl = OP_CMD_BYTES(1) | OP_CMD_BUSW(fls(op->cmd.buswidth) - 1); > > > + ss_ctrl = OP_CMD_BYTES(op->cmd.nbytes) | > > > + OP_CMD_BUSW(fls(op->cmd.buswidth) - 1) | > > > + (op->cmd.dtr ? OP_CMD_DDR : 0); > > > > > > if (op->addr.nbytes) > > > ss_ctrl |= OP_ADDR_BYTES(op->addr.nbytes) | > > > - OP_ADDR_BUSW(fls(op->addr.buswidth) - 1); > > > + OP_ADDR_BUSW(fls(op->addr.buswidth) - 1) | > > > + (op->addr.dtr ? OP_ADDR_DDR : 0); > > > > > > if (op->dummy.nbytes) > > > ss_ctrl |= OP_DUMMY_CYC(op->dummy.nbytes); > > > > > > if (op->data.nbytes) { > > > - ss_ctrl |= OP_DATA_BUSW(fls(op->data.buswidth) - 1); > > > + ss_ctrl |= OP_DATA_BUSW(fls(op->data.buswidth) - 1) | > > > + (op->data.dtr ? OP_DATA_DDR : 0); > > > if (op->data.dir == SPI_MEM_DATA_IN) > > > ss_ctrl |= OP_READ; > > > + if (op->data.dtr) > > > + ss_ctrl |= OP_DQS_EN; > > > } > > > > > > writel(ss_ctrl, mxic->regs + SS_CTRL(mem->spi->chip_select)); > > > @@ -394,7 +401,10 @@ static int mxic_spi_mem_exec_op(struct spi_mem *mem, > > > writel(readl(mxic->regs + HC_CFG) | HC_CFG_MAN_CS_ASSERT, > > > mxic->regs + HC_CFG); > > > > > > - ret = mxic_spi_data_xfer(mxic, &opcode, NULL, 1); > > > + for (i = 0; i < op->cmd.nbytes; i++) > > > > Can we add a check in mxic_spi_mem_check_op to ensure nbytes is never > > > 2 ? > > > > > + cmd[i] = op->cmd.opcode >> (8 * (op->cmd.nbytes - i - 1)); > > > + > > > + ret = mxic_spi_data_xfer(mxic, cmd, NULL, op->cmd.nbytes); > > > if (ret) > > > goto out; > > > > > > @@ -567,7 +577,8 @@ static int mxic_spi_probe(struct platform_device *pdev) > > > master->bits_per_word_mask = SPI_BPW_MASK(8); > > > master->mode_bits = SPI_CPOL | SPI_CPHA | > > > SPI_RX_DUAL | SPI_TX_DUAL | > > > - SPI_RX_QUAD | SPI_TX_QUAD; > > > + SPI_RX_QUAD | SPI_TX_QUAD | > > > + SPI_RX_OCTAL | SPI_TX_OCTAL; > > > > > > mxic_spi_hw_init(mxic); > > > > > > > Otherwise looks fine. > > > > Thanks, > > Miquèl > > > Thanks, Miquèl
Hello, zhengxunli@mxic.com.tw wrote on Tue, 2 Feb 2021 13:37:22 +0800: > Hi, > > > > Driver patch for octal 8D-8D-8D mode support. > > > > > > Signed-off-by: zhengxunli <zhengxunli@mxic.com.tw> > > > --- > > > drivers/spi/spi-mxic.c | 33 ++++++++++++++++++++++----------- > > > 1 file changed, 22 insertions(+), 11 deletions(-) > > > > > > diff --git a/drivers/spi/spi-mxic.c b/drivers/spi/spi-mxic.c > > > index 96b4182..821328a 100644 > > > --- a/drivers/spi/spi-mxic.c > > > +++ b/drivers/spi/spi-mxic.c > > > @@ -335,8 +335,8 @@ static int mxic_spi_data_xfer(struct mxic_spi > > *mxic, const void *txbuf, > > > static bool mxic_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) > > > + if (op->data.buswidth > 8 || op->addr.buswidth > 8 || > > > + op->dummy.buswidth > 8 || op->cmd.buswidth > 8) > > > return false; > > > > > > if (op->data.nbytes && op->dummy.nbytes && > > > @@ -346,7 +346,7 @@ static bool mxic_spi_mem_supports_op(struct > > spi_mem *mem, > > > if (op->addr.nbytes > 7) > > > return false; > > > > > > - return spi_mem_default_supports_op(mem, op); > > > + return true; > > > > Does not seem correct. Why would you drop this check? > > Same as Pratyush's reply. spi_mem_default_supports_op() does not support > dtr. As I said: spi_mem_default_supports_op() do many checks, I don't think it's worth giving up these checks and having a complementary helper for DTR operations is needed. Thanks, Miquèl
diff --git a/drivers/spi/spi-mxic.c b/drivers/spi/spi-mxic.c index 96b4182..821328a 100644 --- a/drivers/spi/spi-mxic.c +++ b/drivers/spi/spi-mxic.c @@ -335,8 +335,8 @@ static int mxic_spi_data_xfer(struct mxic_spi *mxic, const void *txbuf, static bool mxic_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) + if (op->data.buswidth > 8 || op->addr.buswidth > 8 || + op->dummy.buswidth > 8 || op->cmd.buswidth > 8) return false; if (op->data.nbytes && op->dummy.nbytes && @@ -346,7 +346,7 @@ static bool mxic_spi_mem_supports_op(struct spi_mem *mem, if (op->addr.nbytes > 7) return false; - return spi_mem_default_supports_op(mem, op); + return true; } static int mxic_spi_mem_exec_op(struct spi_mem *mem, @@ -355,14 +355,15 @@ static int mxic_spi_mem_exec_op(struct spi_mem *mem, struct mxic_spi *mxic = spi_master_get_devdata(mem->spi->master); int nio = 1, i, ret; u32 ss_ctrl; - u8 addr[8]; - u8 opcode = op->cmd.opcode; + u8 addr[8], cmd[2]; ret = mxic_spi_set_freq(mxic, mem->spi->max_speed_hz); if (ret) return ret; - if (mem->spi->mode & (SPI_TX_QUAD | SPI_RX_QUAD)) + if (mem->spi->mode & (SPI_TX_OCTAL | SPI_RX_OCTAL)) + nio = 8; + else if (mem->spi->mode & (SPI_TX_QUAD | SPI_RX_QUAD)) nio = 4; else if (mem->spi->mode & (SPI_TX_DUAL | SPI_RX_DUAL)) nio = 2; @@ -374,19 +375,25 @@ static int mxic_spi_mem_exec_op(struct spi_mem *mem, mxic->regs + HC_CFG); writel(HC_EN_BIT, mxic->regs + HC_EN); - ss_ctrl = OP_CMD_BYTES(1) | OP_CMD_BUSW(fls(op->cmd.buswidth) - 1); + ss_ctrl = OP_CMD_BYTES(op->cmd.nbytes) | + OP_CMD_BUSW(fls(op->cmd.buswidth) - 1) | + (op->cmd.dtr ? OP_CMD_DDR : 0); if (op->addr.nbytes) ss_ctrl |= OP_ADDR_BYTES(op->addr.nbytes) | - OP_ADDR_BUSW(fls(op->addr.buswidth) - 1); + OP_ADDR_BUSW(fls(op->addr.buswidth) - 1) | + (op->addr.dtr ? OP_ADDR_DDR : 0); if (op->dummy.nbytes) ss_ctrl |= OP_DUMMY_CYC(op->dummy.nbytes); if (op->data.nbytes) { - ss_ctrl |= OP_DATA_BUSW(fls(op->data.buswidth) - 1); + ss_ctrl |= OP_DATA_BUSW(fls(op->data.buswidth) - 1) | + (op->data.dtr ? OP_DATA_DDR : 0); if (op->data.dir == SPI_MEM_DATA_IN) ss_ctrl |= OP_READ; + if (op->data.dtr) + ss_ctrl |= OP_DQS_EN; } writel(ss_ctrl, mxic->regs + SS_CTRL(mem->spi->chip_select)); @@ -394,7 +401,10 @@ static int mxic_spi_mem_exec_op(struct spi_mem *mem, writel(readl(mxic->regs + HC_CFG) | HC_CFG_MAN_CS_ASSERT, mxic->regs + HC_CFG); - ret = mxic_spi_data_xfer(mxic, &opcode, NULL, 1); + for (i = 0; i < op->cmd.nbytes; i++) + cmd[i] = op->cmd.opcode >> (8 * (op->cmd.nbytes - i - 1)); + + ret = mxic_spi_data_xfer(mxic, cmd, NULL, op->cmd.nbytes); if (ret) goto out; @@ -567,7 +577,8 @@ static int mxic_spi_probe(struct platform_device *pdev) master->bits_per_word_mask = SPI_BPW_MASK(8); master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_RX_DUAL | SPI_TX_DUAL | - SPI_RX_QUAD | SPI_TX_QUAD; + SPI_RX_QUAD | SPI_TX_QUAD | + SPI_RX_OCTAL | SPI_TX_OCTAL; mxic_spi_hw_init(mxic);
Driver patch for octal 8D-8D-8D mode support. Signed-off-by: zhengxunli <zhengxunli@mxic.com.tw> --- drivers/spi/spi-mxic.c | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-)