diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mtd/spi-nor/fsl-quadspi.c | 30 |
1 files changed, 27 insertions, 3 deletions
diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c index ea371b0f56ab..47f675098d63 100644 --- a/drivers/mtd/spi-nor/fsl-quadspi.c +++ b/drivers/mtd/spi-nor/fsl-quadspi.c @@ -41,6 +41,8 @@ #define QUADSPI_QUIRK_TKT253890 (1 << 2) /* Controller cannot wake up from wait mode, TKT245618 */ #define QUADSPI_QUIRK_TKT245618 (1 << 3) +/* Need low level code to control the clock */ +#define QUADSPI_QUIRK_LL_CLK (1 << 4) /* The registers */ #define QUADSPI_MCR 0x00 @@ -220,7 +222,7 @@ #define SEQID_DYNAMIC_CMD0 14 #define SEQID_DYNAMIC_CMD1 15 -#define QUADSPI_MIN_IOMAP SZ_4M +#define QUADSPI_MIN_IOMAP SZ_4M /* dynamic lut configs */ #define MAX_LUT_REGS 4 @@ -255,6 +257,7 @@ enum fsl_qspi_devtype { FSL_QUADSPI_IMX7D, FSL_QUADSPI_IMX6UL, FSL_QUADSPI_LS1021A, + FSL_QUADSPI_IMX7ULP, }; struct fsl_qspi_devtype_data { @@ -308,6 +311,15 @@ static struct fsl_qspi_devtype_data ls1021a_data = { .driver_data = 0, }; +static struct fsl_qspi_devtype_data imx7ulp_data = { + .devtype = FSL_QUADSPI_IMX7ULP, + .rxfifo = 64, + .txfifo = 64, + .ahb_buf_size = 128, + .driver_data = QUADSPI_QUIRK_LL_CLK + | QUADSPI_QUIRK_TKT253890 +}; + #define FSL_QSPI_MAX_CHIP 4 struct fsl_qspi { struct spi_nor nor[FSL_QSPI_MAX_CHIP]; @@ -351,6 +363,11 @@ static inline int needs_wakeup_wait_mode(struct fsl_qspi *q) return q->devtype_data->driver_data & QUADSPI_QUIRK_TKT245618; } +static inline int needs_ll_handle_clock(struct fsl_qspi *q) +{ + return q->devtype_data->driver_data & QUADSPI_QUIRK_LL_CLK; +} + /* * R/W functions for big- or little-endian registers: * The qSPI controller's endian is independent of the CPU core's endian. @@ -441,6 +458,11 @@ static void fsl_qspi_init_lut(struct fsl_qspi *q) } else { dev_err(nor->dev, "Unsupported opcode : 0x%.2x\n", op); } + } else if (nor->flash_read == SPI_NOR_NORMAL) { + writel(LUT0(CMD, PAD1, op) | LUT1(ADDR, PAD1, addrlen), + base + QUADSPI_LUT(lut_base)); + writel(LUT0(FSL_READ, PAD1, rxfifo) | LUT1(JMP_ON_CS, PAD1, 0), + base + QUADSPI_LUT(lut_base + 1)); } else if (nor->flash_read == SPI_NOR_DDR_QUAD) { if (op == SPINOR_OP_READ_1_4_4_D || op == SPINOR_OP_READ4_1_4_4_D) { @@ -612,6 +634,7 @@ static int fsl_qspi_get_seqid(struct fsl_qspi *q, u8 cmd) case SPINOR_OP_READ4_1_4_4_D: case SPINOR_OP_READ4_1_1_4: case SPINOR_OP_READ_1_1_4: + case SPINOR_OP_READ: return SEQID_QUAD_READ; case SPINOR_OP_WREN: return SEQID_WREN; @@ -919,7 +942,7 @@ static int fsl_qspi_nor_setup(struct fsl_qspi *q) /* the default frequency, we will change it in the future. */ ret = clk_set_rate(q->clk, 66000000); - if (ret) + if (ret && !needs_ll_handle_clock(q)) return ret; ret = fsl_qspi_clk_prep_enable(q); @@ -977,7 +1000,7 @@ static int fsl_qspi_nor_setup_last(struct fsl_qspi *q) fsl_qspi_clk_disable_unprep(q); ret = clk_set_rate(q->clk, rate); - if (ret) + if (ret && !needs_ll_handle_clock(q)) return ret; ret = fsl_qspi_clk_prep_enable(q); @@ -1001,6 +1024,7 @@ static const struct of_device_id fsl_qspi_dt_ids[] = { { .compatible = "fsl,imx6ul-qspi", .data = (void *)&imx6ul_data, }, { .compatible = "fsl,ls1021a-qspi", .data = (void *)&ls1021a_data, }, { .compatible = "fsl,imx6ull-qspi", .data = (void *)&imx6ul_data, }, + { .compatible = "fsl,imx7ulp-qspi", .data = (void *)&imx7ulp_data, }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, fsl_qspi_dt_ids); |