mtd: spi-nor: cadence-quadspi: add a delay in write sequence
[linux-2.6-block.git] / drivers / mtd / spi-nor / cadence-quadspi.c
index 53c7d8e0327aa4376bdbb3cb00d78babf70349a4..5cd5d6f7303f33d751cd9ff8084bb32e85f0286b 100644 (file)
@@ -38,6 +38,9 @@
 #define CQSPI_NAME                     "cadence-qspi"
 #define CQSPI_MAX_CHIPSELECT           16
 
+/* Quirks */
+#define CQSPI_NEEDS_WR_DELAY           BIT(0)
+
 struct cqspi_st;
 
 struct cqspi_flash_pdata {
@@ -76,6 +79,7 @@ struct cqspi_st {
        u32                     fifo_depth;
        u32                     fifo_width;
        u32                     trigger_address;
+       u32                     wr_delay;
        struct cqspi_flash_pdata f_pdata[CQSPI_MAX_CHIPSELECT];
 };
 
@@ -608,6 +612,15 @@ static int cqspi_indirect_write_execute(struct spi_nor *nor,
        reinit_completion(&cqspi->transfer_complete);
        writel(CQSPI_REG_INDIRECTWR_START_MASK,
               reg_base + CQSPI_REG_INDIRECTWR);
+       /*
+        * As per 66AK2G02 TRM SPRUHY8F section 11.15.5.3 Indirect Access
+        * Controller programming sequence, couple of cycles of
+        * QSPI_REF_CLK delay is required for the above bit to
+        * be internally synchronized by the QSPI module. Provide 5
+        * cycles of delay.
+        */
+       if (cqspi->wr_delay)
+               ndelay(cqspi->wr_delay);
 
        while (remaining > 0) {
                write_bytes = remaining > page_size ? page_size : remaining;
@@ -1156,6 +1169,7 @@ static int cqspi_probe(struct platform_device *pdev)
        struct cqspi_st *cqspi;
        struct resource *res;
        struct resource *res_ahb;
+       unsigned long data;
        int ret;
        int irq;
 
@@ -1213,6 +1227,10 @@ static int cqspi_probe(struct platform_device *pdev)
        }
 
        cqspi->master_ref_clk_hz = clk_get_rate(cqspi->clk);
+       data  = (unsigned long)of_device_get_match_data(dev);
+       if (data & CQSPI_NEEDS_WR_DELAY)
+               cqspi->wr_delay = 5 * DIV_ROUND_UP(NSEC_PER_SEC,
+                                                  cqspi->master_ref_clk_hz);
 
        ret = devm_request_irq(dev, irq, cqspi_irq_handler, 0,
                               pdev->name, cqspi);
@@ -1284,7 +1302,14 @@ static const struct dev_pm_ops cqspi__dev_pm_ops = {
 #endif
 
 static const struct of_device_id cqspi_dt_ids[] = {
-       {.compatible = "cdns,qspi-nor",},
+       {
+               .compatible = "cdns,qspi-nor",
+               .data = (void *)0,
+       },
+       {
+               .compatible = "ti,k2g-qspi",
+               .data = (void *)CQSPI_NEEDS_WR_DELAY,
+       },
        { /* end of table */ }
 };