123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 |
- From 16eb35ceea5b43e6f64c1a869721ea86c0da5260 Mon Sep 17 00:00:00 2001
- From: Yunhui Cui <yunhui.cui@nxp.com>
- Date: Thu, 25 Feb 2016 10:19:15 +0800
- Subject: [PATCH 106/113] mtd: fsl-quadspi: add DDR quad read for Spansion
- Add the DDR quad read support for the fsl-quadspi driver.
- And, add the Spansion s25fl128s NOR flash ddr quad mode
- support.
- Signed-off-by: Yunhui Cui <yunhui.cui@nxp.com>
- ---
- drivers/mtd/spi-nor/fsl-quadspi.c | 57 +++++++++++++++++++++++++++++++++++++
- 1 file changed, 57 insertions(+)
- --- a/drivers/mtd/spi-nor/fsl-quadspi.c
- +++ b/drivers/mtd/spi-nor/fsl-quadspi.c
- @@ -296,6 +296,7 @@ struct fsl_qspi {
- u32 nor_size;
- u32 nor_num;
- u32 clk_rate;
- + u32 ddr_smp;
- unsigned int chip_base_addr; /* We may support two chips. */
- bool has_second_chip;
- bool big_endian;
- @@ -423,6 +424,19 @@ static void fsl_qspi_init_lut(struct fsl
- qspi_writel(q, LUT0(DUMMY, PAD1, read_dm) |
- LUT1(FSL_READ, PAD4, rxfifo),
- base + QUADSPI_LUT(lut_base + 1));
- + } else if (nor->flash_read == SPI_NOR_DDR_QUAD) {
- + /* read mode : 1-4-4, such as Spansion s25fl128s. */
- + qspi_writel(q, LUT0(CMD, PAD1, read_op)
- + | LUT1(ADDR_DDR, PAD4, addrlen),
- + base + QUADSPI_LUT(lut_base));
- +
- + qspi_writel(q, LUT0(MODE_DDR, PAD4, 0xff)
- + | LUT1(DUMMY, PAD1, read_dm),
- + base + QUADSPI_LUT(lut_base + 1));
- +
- + qspi_writel(q, LUT0(FSL_READ_DDR, PAD4, rxfifo)
- + | LUT1(JMP_ON_CS, PAD1, 0),
- + base + QUADSPI_LUT(lut_base + 2));
- }
-
- /* Write enable */
- @@ -534,6 +548,8 @@ static void fsl_qspi_init_lut(struct fsl
- static int fsl_qspi_get_seqid(struct fsl_qspi *q, u8 cmd)
- {
- switch (cmd) {
- + case SPINOR_OP_READ_1_4_4_D:
- + 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_FAST:
- @@ -736,6 +752,32 @@ static void fsl_qspi_set_map_addr(struct
- }
-
- /*
- + * enable controller ddr quad mode to support different
- + * vender flashes ddr quad mode.
- + */
- +static void set_ddr_quad_mode(struct fsl_qspi *q)
- +{
- + u32 reg, reg2;
- +
- + reg = qspi_readl(q, q->iobase + QUADSPI_MCR);
- +
- + /* Firstly, disable the module */
- + qspi_writel(q, reg | QUADSPI_MCR_MDIS_MASK, q->iobase + QUADSPI_MCR);
- +
- + /* Set the Sampling Register for DDR */
- + reg2 = qspi_readl(q, q->iobase + QUADSPI_SMPR);
- + reg2 &= ~QUADSPI_SMPR_DDRSMP_MASK;
- + reg2 |= (((q->ddr_smp) << QUADSPI_SMPR_DDRSMP_SHIFT) &
- + QUADSPI_SMPR_DDRSMP_MASK);
- + qspi_writel(q, reg2, q->iobase + QUADSPI_SMPR);
- +
- + /* Enable the module again (enable the DDR too) */
- + reg |= QUADSPI_MCR_DDR_EN_MASK;
- + qspi_writel(q, reg, q->iobase + QUADSPI_MCR);
- +
- +}
- +
- +/*
- * There are two different ways to read out the data from the flash:
- * the "IP Command Read" and the "AHB Command Read".
- *
- @@ -775,6 +817,11 @@ static void fsl_qspi_init_abh_read(struc
- seqid = fsl_qspi_get_seqid(q, q->nor[0].read_opcode);
- qspi_writel(q, seqid << QUADSPI_BFGENCR_SEQID_SHIFT,
- q->iobase + QUADSPI_BFGENCR);
- +
- + /* enable the DDR quad read */
- + if (q->nor->flash_read == SPI_NOR_DDR_QUAD)
- + set_ddr_quad_mode(q);
- +
- }
-
- /* This function was used to prepare and enable QSPI clock */
- @@ -1108,6 +1155,12 @@ static int fsl_qspi_probe(struct platfor
- goto clk_failed;
- }
-
- + /* find ddrsmp value */
- + ret = of_property_read_u32(dev->of_node, "fsl,ddr-sampling-point",
- + &q->ddr_smp);
- + if (ret)
- + q->ddr_smp = 0;
- +
- /* find the irq */
- ret = platform_get_irq(pdev, 0);
- if (ret < 0) {
- @@ -1164,6 +1217,10 @@ static int fsl_qspi_probe(struct platfor
-
- ret = of_property_read_bool(np, "m25p,fast-read");
- mode = (ret) ? SPI_NOR_FAST : SPI_NOR_QUAD;
- + /* Can we enable the DDR Quad Read? */
- + ret = of_property_read_bool(np, "ddr-quad-read");
- + if (ret)
- + mode = SPI_NOR_DDR_QUAD;
-
- ret = spi_nor_scan(nor, NULL, mode);
- if (ret)
|