]> git.karo-electronics.de Git - linux-beck.git/commitdiff
BECK: Add support for QPSI flash, ported from 4.1.15 fsl kernel
authorOle Reinhardt <ole.reinhardt@kernelconcepts.de>
Wed, 8 Mar 2017 15:03:50 +0000 (16:03 +0100)
committerOle Reinhardt <ole.reinhardt@kernelconcepts.de>
Mon, 13 Mar 2017 13:25:57 +0000 (14:25 +0100)
drivers/mtd/spi-nor/fsl-quadspi.c
drivers/mtd/spi-nor/spi-nor.c

index 5c82e4ef1904b3bebcdd6fae8fc23bb37768df52..6ace528f8c0dacce7da914bc499743b332bca21f 100644 (file)
 #define QUADSPI_MCR_SWRSTSD_SHIFT      0
 #define QUADSPI_MCR_SWRSTSD_MASK       (1 << QUADSPI_MCR_SWRSTSD_SHIFT)
 
+/* BECK: added from Freescale kernel 4.1.15 */
+#define QUADSPI_FLSHCR                 0x0c
+#define QUADSPI_FLSHCR_TDH_SHIFT       16
+#define QUADSPI_FLSHCR_TDH_MASK                (3 << QUADSPI_FLSHCR_TDH_SHIFT)
+#define QUADSPI_FLSHCR_TDH_DDR_EN      (1 << QUADSPI_FLSHCR_TDH_SHIFT)
+
 #define QUADSPI_IPCR                   0x08
 #define QUADSPI_IPCR_SEQID_SHIFT       24
 #define QUADSPI_IPCR_SEQID_MASK                (0xF << QUADSPI_IPCR_SEQID_SHIFT)
@@ -285,6 +291,8 @@ struct fsl_qspi {
        unsigned int chip_base_addr; /* We may support two chips. */
        bool has_second_chip;
        bool big_endian;
+       /* BECK: added from Freescale kernel 4.1.15 */
+       u32 ddr_smp;
        struct mutex lock;
        struct pm_qos_request pm_qos_req;
 };
@@ -704,6 +712,33 @@ static void fsl_qspi_init_abh_read(struct fsl_qspi *q)
        seqid = fsl_qspi_get_seqid(q, q->nor[0].read_opcode);
        qspi_writel(q, seqid << QUADSPI_BFGENCR_SEQID_SHIFT,
                q->iobase + QUADSPI_BFGENCR);
+
+       /* BECK: added from Freescale kernel 4.1.15 */
+       if ((q->devtype_data->devtype == FSL_QUADSPI_IMX6UL) ||
+               (q->devtype_data->devtype == FSL_QUADSPI_IMX7D)) {
+               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);
+
+               reg = qspi_readl(q, q->iobase + QUADSPI_FLSHCR);
+               reg &= ~QUADSPI_FLSHCR_TDH_MASK;
+               reg |= QUADSPI_FLSHCR_TDH_DDR_EN;
+               qspi_writel(q, reg, q->iobase + QUADSPI_FLSHCR);
+       }
 }
 
 /* This function was used to prepare and enable QSPI clock */
@@ -757,6 +792,15 @@ static int fsl_qspi_nor_setup(struct fsl_qspi *q)
        if (ret)
                return ret;
 
+       /* BECK: added from Freescale kernel 4.1.15 */
+       if ((q->devtype_data->devtype == FSL_QUADSPI_IMX6UL) ||
+               (q->devtype_data->devtype == FSL_QUADSPI_IMX7D)) {
+               /* clear the DDR_EN bit for 6UL and 7D */
+               reg = qspi_readl(q, base + QUADSPI_MCR);
+               qspi_writel(q, ~(QUADSPI_MCR_DDR_EN_MASK) & reg, base + QUADSPI_MCR);
+               udelay(1);
+       }
+
        /* Reset the module */
        qspi_writel(q, QUADSPI_MCR_SWRSTSD_MASK | QUADSPI_MCR_SWRSTHD_MASK,
                base + QUADSPI_MCR);
@@ -1021,6 +1065,13 @@ static int fsl_qspi_probe(struct platform_device *pdev)
        if (IS_ERR(q->clk))
                return PTR_ERR(q->clk);
 
+       /* BECK: added from Freescale kernel 4.1.15 */
+       /* find ddrsmp value */
+       ret = of_property_read_u32(dev->of_node, "ddrsmp",
+                               &q->ddr_smp);
+       if (ret)
+               q->ddr_smp = 0;
+
        ret = fsl_qspi_clk_prep_enable(q);
        if (ret) {
                dev_err(dev, "can not enable the clock\n");
index d0fc165d7d666cac0ffc69b6c68fbdd49bc2b29c..a9f4d54190d82baf282d59557dd15df715a5d78f 100644 (file)
@@ -885,7 +885,8 @@ static const struct flash_info spi_nor_ids[] = {
        { "n25q128a13",  INFO(0x20ba18, 0, 64 * 1024,  256, SECT_4K | SPI_NOR_QUAD_READ) },
        { "n25q256a",    INFO(0x20ba19, 0, 64 * 1024,  512, SECT_4K | SPI_NOR_QUAD_READ) },
        { "n25q512a",    INFO(0x20bb20, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
-       { "n25q512ax3",  INFO(0x20ba20, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
+       /* BECK: removed the USE_FSR option as this is not supported by the Freescale QSPI driver */
+       { "n25q512ax3",  INFO(0x20ba20, 0, 64 * 1024, 1024, SECT_4K | SPI_NOR_QUAD_READ) },
        { "n25q00",      INFO(0x20ba21, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
        { "n25q00a",     INFO(0x20bb21, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
 
@@ -1172,9 +1173,12 @@ static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len,
                ssize_t written;
 
                page_offset = (to + i) & (nor->page_size - 1);
+#if 0          
+               /* BECK: removed warning as this message always appears when UBIFS is used */
                WARN_ONCE(page_offset,
                          "Writing at offset %zu into a NOR page. Writing partial pages may decrease reliability and increase wear of NOR flash.",
                          page_offset);
+#endif                   
                /* the size of data remaining on the first page */
                page_remain = min_t(size_t,
                                    nor->page_size - page_offset, len - i);