From 6c6f965aa6f867a5f3d8103df3734bcae9d18bd3 Mon Sep 17 00:00:00 2001 From: John Garry Date: Fri, 28 Feb 2020 23:18:50 +0800 Subject: [PATCH 27/39] spi: HiSilicon v3xx: Properly set CMD_CONFIG for Dual/Quad modes mainline inclusion from mainline-v5.7-rc1 commit 8fe21d6b347247227c349c9b2f7c462fae362af4 category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I8CSBP CVE: NA Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=8fe21d6b347247227c349c9b2f7c462fae362af4 ---------------------------------------------------------------------------- The CMD_CONFIG register memory interface type field is not set configured for Dual and Quad modes, so set appropriately. This was not detected previously as we only ever operated in standard SPI mode. Signed-off-by: John Garry Link: https://lore.kernel.org/r/1582903131-160033-3-git-send-email-john.garry@huawei.com Signed-off-by: Mark Brown Signed-off-by: YunYi Yang --- drivers/spi/spi-hisi-sfc-v3xx.c | 39 +++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/drivers/spi/spi-hisi-sfc-v3xx.c b/drivers/spi/spi-hisi-sfc-v3xx.c index 4cf8fc80a7b7..8c2eea439d5b 100644 --- a/drivers/spi/spi-hisi-sfc-v3xx.c +++ b/drivers/spi/spi-hisi-sfc-v3xx.c @@ -17,6 +17,12 @@ #define HISI_SFC_V3XX_VERSION (0x1f8) #define HISI_SFC_V3XX_CMD_CFG (0x300) +#define HISI_SFC_V3XX_CMD_CFG_DUAL_IN_DUAL_OUT (1 << 17) +#define HISI_SFC_V3XX_CMD_CFG_DUAL_IO (2 << 17) +#define HISI_SFC_V3XX_CMD_CFG_FULL_DIO (3 << 17) +#define HISI_SFC_V3XX_CMD_CFG_QUAD_IN_QUAD_OUT (5 << 17) +#define HISI_SFC_V3XX_CMD_CFG_QUAD_IO (6 << 17) +#define HISI_SFC_V3XX_CMD_CFG_FULL_QIO (7 << 17) #define HISI_SFC_V3XX_CMD_CFG_DATA_CNT_OFF 9 #define HISI_SFC_V3XX_CMD_CFG_RW_MSK BIT(8) #define HISI_SFC_V3XX_CMD_CFG_DATA_EN_MSK BIT(7) @@ -161,6 +167,39 @@ static int hisi_sfc_v3xx_generic_exec_op(struct hisi_sfc_v3xx_host *host, if (op->addr.nbytes) config |= HISI_SFC_V3XX_CMD_CFG_ADDR_EN_MSK; + switch (op->data.buswidth) { + case 0 ... 1: + break; + case 2: + if (op->addr.buswidth <= 1) { + config |= HISI_SFC_V3XX_CMD_CFG_DUAL_IN_DUAL_OUT; + } else if (op->addr.buswidth == 2) { + if (op->cmd.buswidth <= 1) + config |= HISI_SFC_V3XX_CMD_CFG_DUAL_IO; + else if (op->cmd.buswidth == 2) + config |= HISI_SFC_V3XX_CMD_CFG_FULL_DIO; + else + return -EIO; + } else + return -EIO; + break; + case 4: + if (op->addr.buswidth <= 1) { + config |= HISI_SFC_V3XX_CMD_CFG_QUAD_IN_QUAD_OUT; + } else if (op->addr.buswidth == 4) { + if (op->cmd.buswidth <= 1) + config |= HISI_SFC_V3XX_CMD_CFG_QUAD_IO; + else if (op->cmd.buswidth == 4) + config |= HISI_SFC_V3XX_CMD_CFG_FULL_QIO; + else + return -EIO; + } else + return -EIO; + break; + default: + return -EOPNOTSUPP; + } + if (op->data.dir != SPI_MEM_NO_DATA) { config |= (len - 1) << HISI_SFC_V3XX_CMD_CFG_DATA_CNT_OFF; config |= HISI_SFC_V3XX_CMD_CFG_DATA_EN_MSK; -- 2.27.0