On 1/31/21 7:34 PM, Sean Anderson wrote:
These capabilities correspond to SSIC_SPI_MODE of 1, 2, or 3, respectively.
This doesn't do much yet, but it does add support for detection and for
disallowing unsupported modes.  Unfortunately, we cannot discriminate
between these modes (only that SSIC_SPI_MODE != 0), so we only assume DUAL
if something sticks to SPI_FRF.

Signed-off-by: Sean Anderson <sean...@gmail.com>
---

  drivers/spi/designware_spi.c | 41 +++++++++++++++++++++++++-----------
  1 file changed, 29 insertions(+), 12 deletions(-)

diff --git a/drivers/spi/designware_spi.c b/drivers/spi/designware_spi.c
index 683394a5a4..1dd83e6ca6 100644
--- a/drivers/spi/designware_spi.c
+++ b/drivers/spi/designware_spi.c
@@ -129,6 +129,9 @@ struct dw_spi_priv {
  #define DW_SPI_CAP_KEEMBAY_MST                BIT(1) /* Unimplemented */
  #define DW_SPI_CAP_DWC_SSI            BIT(2)
  #define DW_SPI_CAP_DFS32              BIT(3)
+#define DW_SPI_CAP_DUAL                        BIT(4)
+#define DW_SPI_CAP_QUAD                        BIT(5)
+#define DW_SPI_CAP_OCTAL               BIT(5)

Looks like these CAPs both use BIT(5). Will fix in next revision.

Actually, it might be better to just have a CAP_EXTENDED and let the SPI
slave determine the bus width...

--Sean

        unsigned long caps;
        unsigned long bus_clk_rate;
        unsigned int freq;              /* Default frequency */
@@ -141,6 +144,7 @@ struct dw_spi_priv {
        u8 cs;                          /* chip select pin */
        u8 tmode;                       /* TR/TO/RO/EEPROM */
        u8 type;                        /* SPI/SSP/MicroWire */
+       u8 spi_frf;                     /* BYTE/DUAL/QUAD/OCTAL */
  };
static inline u32 dw_read(struct dw_spi_priv *priv, u32 offset)
@@ -267,7 +271,6 @@ static void spi_hw_init(struct udevice *bus, struct 
dw_spi_priv *priv)
                priv->fifo_len = (fifo == 1) ? 0 : fifo;
                dw_write(priv, DW_SPI_TXFTLR, 0);
        }
-       dev_dbg(bus, "fifo_len=%d\n", priv->fifo_len);
  }
/*
@@ -351,22 +354,21 @@ static int dw_spi_probe(struct udevice *bus)
        if (ret)
                return ret;
- priv->caps = dev_get_driver_data(bus);
-       dw_spi_detect_caps(bus, priv);
-
-       version = dw_read(priv, DW_SPI_VERSION);
-       dev_dbg(bus, "ssi_version_id=%c.%c%c%c ssi_max_xfer_size=%u\n",
-               version >> 24, version >> 16, version >> 8, version,
-               priv->caps & DW_SPI_CAP_DFS32 ? 32 : 16);
-
        /* Currently only bits_per_word == 8 supported */
        priv->bits_per_word = 8;
priv->tmode = 0; /* Tx & Rx */ /* Basic HW init */
+       priv->caps = dev_get_driver_data(bus);
        spi_hw_init(bus, priv);
+ version = dw_read(priv, DW_SPI_VERSION);
+       dev_dbg(bus,
+               "ssi_version_id=%c.%c%c%c ssi_rx_fifo_depth=%u 
ssi_max_xfer_size=%u\n",
+               version >> 24, version >> 16, version >> 8, version,
+               priv->fifo_len, priv->caps & DW_SPI_CAP_DFS32 ? 32 : 16);
+
        return 0;
  }
@@ -748,13 +750,25 @@ static int dw_spi_set_mode(struct udevice *bus, uint mode)
  {
        struct dw_spi_priv *priv = dev_get_priv(bus);
+ if (!(priv->caps & DW_SPI_CAP_DUAL) &&
+           (mode & (SPI_RX_DUAL | SPI_TX_DUAL)))
+               return -EINVAL;
+
+       if (!(priv->caps & DW_SPI_CAP_QUAD) &&
+           (mode & (SPI_RX_QUAD | SPI_TX_QUAD)))
+               return -EINVAL;
+
+       if (!(priv->caps & DW_SPI_CAP_OCTAL) &&
+           (mode & (SPI_RX_OCTAL | SPI_TX_OCTAL)))
+               return -EINVAL;
+
        /*
         * Can't set mode yet. Since this depends on if rx, tx, or
         * rx & tx is requested. So we have to defer this to the
         * real transfer function.
         */
        priv->mode = mode;
-       dev_dbg(bus, "mode=%d\n", priv->mode);
+       dev_dbg(bus, "mode=%x\n", mode);
return 0;
  }
@@ -813,10 +827,13 @@ static const struct udevice_id dw_spi_ids[] = {
         */
        { .compatible = "altr,socfpga-spi" },
        { .compatible = "altr,socfpga-arria10-spi" },
-       { .compatible = "canaan,kendryte-k210-spi" },
+       {
+               .compatible = "canaan,kendryte-k210-spi",
+               .data = DW_SPI_CAP_QUAD | DW_SPI_CAP_OCTAL,
+       },
        {
                .compatible = "canaan,kendryte-k210-ssi",
-               .data = DW_SPI_CAP_DWC_SSI,
+               .data = DW_SPI_CAP_DWC_SSI | DW_SPI_CAP_QUAD,
        },
        { .compatible = "intel,stratix10-spi" },
        { .compatible = "intel,agilex-spi" },


Reply via email to