OSDN Git Service

spi: dw: Introduce Synopsys IP-core versions interface
authorSerge Semin <Sergey.Semin@baikalelectronics.ru>
Mon, 15 Nov 2021 18:19:15 +0000 (21:19 +0300)
committerMark Brown <broonie@kernel.org>
Tue, 16 Nov 2021 14:30:07 +0000 (14:30 +0000)
The driver currently supports two IP-core versions. It's DW APB SSI which
is older version of the controller with APB system bus interface, and DW
SSI controller with AHB bus interface. The later one is supposed to be a
new generation high-speed SSI. Even though both of these IP-cores have got
an almost identical registers space there are some differences. The driver
differentiates these distinctions by the DW_SPI_CAP_DWC_HSSI capability
flag. In addition to that each DW SSI IP-core is equipped with a Synopsys
Component version register, which encodes the IP-core release ID the has
been synthesized from. Seeing we are going to need the later one to
differentiate some controller peculiarities it would be better to have a
unified interface for both IP-core line and release versions instead of
using each of them separately.

Introduced here IP-core versioning interface consists of two parts:
1) IDs of the IP-core (virtual) and component versions.
2) a set of macro helpers to identify current IP-core and component
versions.

So the platform code is supposed to assign a proper IP-core version based
on it's platform -knowledge. The main driver initialization method reads
the IP-core release ID from the SSI component version register. That data
is used by the helpers to distinguish one IP-core release from another.
Thus the rest of the driver can use these macros to implement the
conditional code execution based on the specified IP-core and version IDs.

Collect the IP-core versions interface and the defined capabilities at the
top of the header file since they represent a common device description
data and so to immediately available for the driver hackers.

Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>
Suggested-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Link: https://lore.kernel.org/r/20211115181917.7521-6-Sergey.Semin@baikalelectronics.ru
Signed-off-by: Mark Brown <broonie@kernel.org>
drivers/spi/spi-dw-core.c
drivers/spi/spi-dw.h

index b9f8099..42536b4 100644 (file)
@@ -824,6 +824,20 @@ static void dw_spi_hw_init(struct device *dev, struct dw_spi *dws)
        dw_spi_reset_chip(dws);
 
        /*
+        * Retrieve the Synopsys component version if it hasn't been specified
+        * by the platform. CoreKit version ID is encoded as a 3-chars ASCII
+        * code enclosed with '*' (typical for the most of Synopsys IP-cores).
+        */
+       if (!dws->ver) {
+               dws->ver = dw_readl(dws, DW_SPI_VERSION);
+
+               dev_dbg(dev, "Synopsys DWC%sSSI v%c.%c%c\n",
+                       (dws->caps & DW_SPI_CAP_DWC_HSSI) ? " " : " APB ",
+                       DW_SPI_GET_BYTE(dws->ver, 3), DW_SPI_GET_BYTE(dws->ver, 2),
+                       DW_SPI_GET_BYTE(dws->ver, 1));
+       }
+
+       /*
         * Try to detect the FIFO depth if not set by interface driver,
         * the depth could be from 2 to 256 from HW spec
         */
index 634085e..2f7d770 100644 (file)
 #include <linux/spi/spi-mem.h>
 #include <linux/bitfield.h>
 
+/* Synopsys DW SSI IP-core virtual IDs */
+#define DW_PSSI_ID                     0
+#define DW_HSSI_ID                     1
+
+/* Synopsys DW SSI component versions (FourCC sequence) */
+#define DW_HSSI_102A                   0x3130322a
+
+/* DW SSI IP-core ID and version check helpers */
+#define dw_spi_ip_is(_dws, _ip) \
+       ((_dws)->ip == DW_ ## _ip ## _ID)
+
+#define __dw_spi_ver_cmp(_dws, _ip, _ver, _op) \
+       (dw_spi_ip_is(_dws, _ip) && (_dws)->ver _op DW_ ## _ip ## _ver)
+
+#define dw_spi_ver_is(_dws, _ip, _ver) __dw_spi_ver_cmp(_dws, _ip, _ver, ==)
+
+#define dw_spi_ver_is_ge(_dws, _ip, _ver) __dw_spi_ver_cmp(_dws, _ip, _ver, >=)
+
+/* DW SPI controller capabilities */
+#define DW_SPI_CAP_CS_OVERRIDE         BIT(0)
+#define DW_SPI_CAP_KEEMBAY_MST         BIT(1)
+#define DW_SPI_CAP_DWC_HSSI            BIT(2)
+#define DW_SPI_CAP_DFS32               BIT(3)
+
 /* Register offsets (Generic for both DWC APB SSI and DWC SSI IP-cores) */
 #define DW_SPI_CTRLR0                  0x00
 #define DW_SPI_CTRLR1                  0x04
 #define DW_SPI_GET_BYTE(_val, _idx) \
        ((_val) >> (BITS_PER_BYTE * (_idx)) & 0xff)
 
-/* DW SPI capabilities */
-#define DW_SPI_CAP_CS_OVERRIDE         BIT(0)
-#define DW_SPI_CAP_KEEMBAY_MST         BIT(1)
-#define DW_SPI_CAP_DWC_HSSI            BIT(2)
-#define DW_SPI_CAP_DFS32               BIT(3)
-
 /* Slave spi_transfer/spi_mem_op related */
 struct dw_spi_cfg {
        u8 tmode;
@@ -141,6 +159,10 @@ struct dw_spi_dma_ops {
 struct dw_spi {
        struct spi_controller   *master;
 
+       u32                     ip;             /* Synopsys DW SSI IP-core ID */
+       u32                     ver;            /* Synopsys component version */
+       u32                     caps;           /* DW SPI capabilities */
+
        void __iomem            *regs;
        unsigned long           paddr;
        int                     irq;
@@ -149,8 +171,6 @@ struct dw_spi {
        u32                     max_mem_freq;   /* max mem-ops bus freq */
        u32                     max_freq;       /* max bus freq supported */
 
-       u32                     caps;           /* DW SPI capabilities */
-
        u32                     reg_io_width;   /* DR I/O width in bytes */
        u16                     bus_num;
        u16                     num_cs;         /* supported slave numbers */