]> git.ipfire.org Git - thirdparty/u-boot.git/commitdiff
spi: cadence_qspi: Add support for ospi dual stacked
authorAshok Reddy Soma <ashok.reddy.soma@xilinx.com>
Tue, 4 May 2021 07:45:19 +0000 (01:45 -0600)
committerMichal Simek <michal.simek@xilinx.com>
Tue, 1 Jun 2021 11:38:24 +0000 (13:38 +0200)
Add support for ospi dual stacked flash configuration.
Read "is-stacked" property from dt and export it to spi-nor framework
via slave->option. Based on the address/offset spi-nor framework will
populate CS through flags for read, write and erase functions.
configure chip select in cadence_qspi driver based on the flags
received from spi-nor framework.

Signed-off-by: Ashok Reddy Soma <ashok.reddy.soma@xilinx.com>
drivers/spi/cadence_qspi.c
drivers/spi/cadence_qspi.h

index 2a1946cd4c2a93723505e99e5367fa1aac2deffd..87b5e31665d24452b0b465f2b99b220d0890132b 100644 (file)
@@ -124,7 +124,7 @@ static int spi_calibration(struct udevice *bus, uint hz)
 
        /* just to ensure we do once only when speed or chip select change */
        priv->qspi_calibrated_hz = hz;
-       priv->qspi_calibrated_cs = spi_chip_select(bus);
+       priv->qspi_calibrated_cs = priv->cs;
 
        return 0;
 }
@@ -147,7 +147,7 @@ static int cadence_spi_set_speed(struct udevice *bus, uint hz)
         */
        if (priv->previous_hz != hz ||
            priv->qspi_calibrated_hz != hz ||
-           priv->qspi_calibrated_cs != spi_chip_select(bus)) {
+           priv->qspi_calibrated_cs != priv->cs) {
                err = spi_calibration(bus, hz);
                if (err)
                        return err;
@@ -167,8 +167,10 @@ static int cadence_spi_set_speed(struct udevice *bus, uint hz)
 static int cadence_spi_child_pre_probe(struct udevice *bus)
 {
        struct spi_slave *slave = dev_get_parent_priv(bus);
+       struct cadence_spi_priv *priv = dev_get_priv(bus->parent);
 
        slave->bytemode = SPI_4BYTE_MODE;
+       slave->option = priv->is_dual;
 
        return 0;
 }
@@ -187,6 +189,7 @@ static int cadence_spi_probe(struct udevice *bus)
 
        priv->regbase = plat->regbase;
        priv->ahbbase = plat->ahbbase;
+       priv->is_dual = plat->is_dual;
 
        xilinx_pm_request(PM_REQUEST_NODE, DEV_OSPI, PM_CAPABILITY_ACCESS,
                          PM_MAX_QOS, PM_REQUEST_ACK_NO, NULL);
@@ -260,9 +263,13 @@ static int cadence_spi_mem_exec_op(struct spi_slave *spi,
        int err = 0;
        u32 mode;
 
+       if (spi->flags & SPI_XFER_U_PAGE)
+               priv->cs = CQSPI_CS1;
+       else
+               priv->cs = CQSPI_CS0;
+
        /* Set Chip select */
-       cadence_qspi_apb_chipselect(base, spi_chip_select(spi->dev),
-                                   plat->is_decoded_cs);
+       cadence_qspi_apb_chipselect(base, priv->cs, plat->is_decoded_cs);
 
        if (op->data.dir == SPI_MEM_DATA_IN && op->data.buf.in) {
                if (!op->addr.nbytes)
@@ -338,6 +345,11 @@ static int cadence_spi_ofdata_to_platdata(struct udevice *bus)
        plat->max_hz = ofnode_read_u32_default(subnode, "spi-max-frequency",
                                               500000);
 
+       if (dev_read_u32_default(bus, "is-stacked", -1) == 1)
+               plat->is_dual = CQSPI_DUAL_STACKED_FLASH;
+       else
+               plat->is_dual = CQSPI_SINGLE_FLASH;
+
        /* Read other parameters from DT */
        plat->page_size = ofnode_read_u32_default(subnode, "page-size", 256);
        plat->block_size = ofnode_read_u32_default(subnode, "block-size", 16);
index 49666cca821321f1de994f49004dba69d2588ca5..1e3b93eb7c718a4380cf4a7413ccc9544f0c48f8 100644 (file)
 #define CQSPI_DECODER_MAX_CS           16
 #define CQSPI_READ_CAPTURE_MAX_DELAY   16
 
+#define CQSPI_SINGLE_FLASH                     0
+#define CQSPI_DUAL_STACKED_FLASH               1
+
+#define CQSPI_CS0                              0
+#define CQSPI_CS1                              1
+
 #define CQSPI_REG_POLL_US                       1 /* 1us */
 #define CQSPI_REG_RETRY                         10000
 #define CQSPI_POLL_IDLE_RETRY                   3
@@ -205,6 +211,7 @@ struct cadence_spi_platdata {
        u32             tchsh_ns;
        u32             tslch_ns;
        bool            is_dma;
+       int             is_dual;
 };
 
 struct cadence_spi_priv {
@@ -214,7 +221,9 @@ struct cadence_spi_priv {
        u8              cmd_buf[32];
        size_t          data_len;
 
+       int             is_dual;
        int             qspi_is_init;
+       unsigned int    cs;
        unsigned int    qspi_calibrated_hz;
        unsigned int    qspi_calibrated_cs;
        unsigned int    previous_hz;