Skip to content

Commit 50cb86f

Browse files
AlvinZhou97ambarus
authored andcommitted
spi: mxic: Add support for swapping byte
Some SPI-NOR flash swap the bytes on a 16-bit boundary when configured in Octal DTR mode. It means data format D0 D1 D2 D3 would be swapped to D1 D0 D3 D2. So that whether controller support swapping bytes should be checked before enable Octal DTR mode. Add swap byte support on a 16-bit boundary when configured in Octal DTR mode for Macronix xSPI host controller driver. According dtr_swab in operation to enable/disable Macronix xSPI host controller swap byte feature. To make sure swap byte feature is working well, program data in 1S-1S-1S mode then read back and compare read data in 8D-8D-8D mode. This feature have been validated on byte-swap flash and non-byte-swap flash. Macronix xSPI host controller bit "HC_CFG_DATA_PASS" determine the byte swap feature disabled/enabled and swap byte feature is working on 8D-8D-8D mode only. Suggested-by: Michael Walle <mwalle@kernel.org> Signed-off-by: JaimeLiao <jaimeliao@mxic.com.tw> Signed-off-by: AlvinZhou <alvinzhou@mxic.com.tw> Acked-by: Mark Brown <broonie@kernel.org> Link: https://lore.kernel.org/r/20240926141956.2386374-6-alvinzhou.tw@gmail.com Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org>
1 parent 030ace4 commit 50cb86f

File tree

1 file changed

+13
-4
lines changed

1 file changed

+13
-4
lines changed

drivers/spi/spi-mxic.c

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,8 @@ static void mxic_spi_hw_init(struct mxic_spi *mxic)
294294
mxic->regs + HC_CFG);
295295
}
296296

297-
static u32 mxic_spi_prep_hc_cfg(struct spi_device *spi, u32 flags)
297+
static u32 mxic_spi_prep_hc_cfg(struct spi_device *spi, u32 flags,
298+
bool swap16)
298299
{
299300
int nio = 1;
300301

@@ -305,6 +306,11 @@ static u32 mxic_spi_prep_hc_cfg(struct spi_device *spi, u32 flags)
305306
else if (spi->mode & (SPI_TX_DUAL | SPI_RX_DUAL))
306307
nio = 2;
307308

309+
if (swap16)
310+
flags &= ~HC_CFG_DATA_PASS;
311+
else
312+
flags |= HC_CFG_DATA_PASS;
313+
308314
return flags | HC_CFG_NIO(nio) |
309315
HC_CFG_TYPE(spi_get_chipselect(spi, 0), HC_CFG_TYPE_SPI_NOR) |
310316
HC_CFG_SLV_ACT(spi_get_chipselect(spi, 0)) | HC_CFG_IDLE_SIO_LVL(1);
@@ -397,7 +403,8 @@ static ssize_t mxic_spi_mem_dirmap_read(struct spi_mem_dirmap_desc *desc,
397403
if (WARN_ON(offs + desc->info.offset + len > U32_MAX))
398404
return -EINVAL;
399405

400-
writel(mxic_spi_prep_hc_cfg(desc->mem->spi, 0), mxic->regs + HC_CFG);
406+
writel(mxic_spi_prep_hc_cfg(desc->mem->spi, 0, desc->info.op_tmpl.data.swap16),
407+
mxic->regs + HC_CFG);
401408

402409
writel(mxic_spi_mem_prep_op_cfg(&desc->info.op_tmpl, len),
403410
mxic->regs + LRD_CFG);
@@ -441,7 +448,8 @@ static ssize_t mxic_spi_mem_dirmap_write(struct spi_mem_dirmap_desc *desc,
441448
if (WARN_ON(offs + desc->info.offset + len > U32_MAX))
442449
return -EINVAL;
443450

444-
writel(mxic_spi_prep_hc_cfg(desc->mem->spi, 0), mxic->regs + HC_CFG);
451+
writel(mxic_spi_prep_hc_cfg(desc->mem->spi, 0, desc->info.op_tmpl.data.swap16),
452+
mxic->regs + HC_CFG);
445453

446454
writel(mxic_spi_mem_prep_op_cfg(&desc->info.op_tmpl, len),
447455
mxic->regs + LWR_CFG);
@@ -518,7 +526,7 @@ static int mxic_spi_mem_exec_op(struct spi_mem *mem,
518526
if (ret)
519527
return ret;
520528

521-
writel(mxic_spi_prep_hc_cfg(mem->spi, HC_CFG_MAN_CS_EN),
529+
writel(mxic_spi_prep_hc_cfg(mem->spi, HC_CFG_MAN_CS_EN, op->data.swap16),
522530
mxic->regs + HC_CFG);
523531

524532
writel(HC_EN_BIT, mxic->regs + HC_EN);
@@ -573,6 +581,7 @@ static const struct spi_controller_mem_ops mxic_spi_mem_ops = {
573581
static const struct spi_controller_mem_caps mxic_spi_mem_caps = {
574582
.dtr = true,
575583
.ecc = true,
584+
.swap16 = true,
576585
};
577586

578587
static void mxic_spi_set_cs(struct spi_device *spi, bool lvl)

0 commit comments

Comments
 (0)