spi: pxa2xx: Introduce special type for Merrifield SPIs
authorAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Mon, 10 May 2021 12:41:34 +0000 (15:41 +0300)
committerMark Brown <broonie@kernel.org>
Tue, 11 May 2021 08:35:11 +0000 (09:35 +0100)
Intel Merrifield SPI is actually more closer to PXA3xx. It has extended FIFO
(32 bytes) and additional registers to get or set FIFO thresholds.

Introduce new type for Intel Merrifield SPI host controllers and handle bigger
FIFO size.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Link: https://lore.kernel.org/r/20210510124134.24638-15-andriy.shevchenko@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
drivers/spi/spi-pxa2xx-pci.c
drivers/spi/spi-pxa2xx.c
include/linux/pxa2xx_ssp.h

index a259be1..dce9ade 100644 (file)
@@ -179,7 +179,7 @@ static struct pxa_spi_info spi_info_configs[] = {
                .rx_param = &bsw2_rx_param,
        },
        [PORT_MRFLD] = {
-               .type = PXA27x_SSP,
+               .type = MRFLD_SSP,
                .max_clk_rate = 25000000,
                .setup = mrfld_spi_setup,
        },
index af3f01d..5985b39 100644 (file)
@@ -200,6 +200,11 @@ static bool is_mmp2_ssp(const struct driver_data *drv_data)
        return drv_data->ssp_type == MMP2_SSP;
 }
 
+static bool is_mrfld_ssp(const struct driver_data *drv_data)
+{
+       return drv_data->ssp_type == MRFLD_SSP;
+}
+
 static void pxa2xx_spi_update(const struct driver_data *drv_data, u32 reg, u32 mask, u32 value)
 {
        if ((pxa2xx_spi_read(drv_data, reg) & mask) != value)
@@ -1087,6 +1092,15 @@ static int pxa2xx_spi_transfer_one(struct spi_controller *controller,
                pxa2xx_spi_update(drv_data, SSITF, GENMASK(15, 0), chip->lpss_tx_threshold);
        }
 
+       if (is_mrfld_ssp(drv_data)) {
+               u32 thresh = 0;
+
+               thresh |= SFIFOTT_RxThresh(chip->lpss_rx_threshold);
+               thresh |= SFIFOTT_TxThresh(chip->lpss_tx_threshold);
+
+               pxa2xx_spi_update(drv_data, SFIFOTT, 0xffffffff, thresh);
+       }
+
        if (is_quark_x1000_ssp(drv_data))
                pxa2xx_spi_update(drv_data, DDS_RATE, GENMASK(23, 0), chip->dds_rate);
 
@@ -1253,6 +1267,11 @@ static int setup(struct spi_device *spi)
                tx_hi_thres = 0;
                rx_thres = RX_THRESH_QUARK_X1000_DFLT;
                break;
+       case MRFLD_SSP:
+               tx_thres = TX_THRESH_MRFLD_DFLT;
+               tx_hi_thres = 0;
+               rx_thres = RX_THRESH_MRFLD_DFLT;
+               break;
        case CE4100_SSP:
                tx_thres = TX_THRESH_CE4100_DFLT;
                tx_hi_thres = 0;
@@ -1328,9 +1347,16 @@ static int setup(struct spi_device *spi)
                chip->cr1 |= SSCR1_SPH;
        }
 
-       chip->lpss_rx_threshold = SSIRF_RxThresh(rx_thres);
-       chip->lpss_tx_threshold = SSITF_TxLoThresh(tx_thres)
-                               | SSITF_TxHiThresh(tx_hi_thres);
+       if (is_lpss_ssp(drv_data)) {
+               chip->lpss_rx_threshold = SSIRF_RxThresh(rx_thres);
+               chip->lpss_tx_threshold = SSITF_TxLoThresh(tx_thres) |
+                                         SSITF_TxHiThresh(tx_hi_thres);
+       }
+
+       if (is_mrfld_ssp(drv_data)) {
+               chip->lpss_rx_threshold = rx_thres;
+               chip->lpss_tx_threshold = tx_thres;
+       }
 
        /* set dma burst and threshold outside of chip_info path so that if
         * chip_info goes away after setting chip->enable_dma, the
index fdfbe17..2b21bc1 100644 (file)
@@ -183,6 +183,21 @@ struct device_node;
 #define SSACD_ACPS(x)          ((x) << 4)      /* Audio clock PLL select */
 #define SSACD_SCDX8            BIT(7)          /* SYSCLK division ratio select */
 
+/* Intel Merrifield SSP */
+#define SFIFOL                 0x68            /* FIFO level */
+#define SFIFOTT                        0x6c            /* FIFO trigger threshold */
+
+#define RX_THRESH_MRFLD_DFLT   16
+#define TX_THRESH_MRFLD_DFLT   16
+
+#define SFIFOL_TFL_MASK                GENMASK(15, 0)  /* Transmit FIFO Level mask */
+#define SFIFOL_RFL_MASK                GENMASK(31, 16) /* Receive FIFO Level mask */
+
+#define SFIFOTT_TFT            GENMASK(15, 0)  /* Transmit FIFO Threshold (mask) */
+#define SFIFOTT_TxThresh(x)    (((x) - 1) << 0)        /* TX FIFO trigger threshold / level */
+#define SFIFOTT_RFT            GENMASK(31, 16) /* Receive FIFO Threshold (mask) */
+#define SFIFOTT_RxThresh(x)    (((x) - 1) << 16)       /* RX FIFO trigger threshold / level */
+
 /* LPSS SSP */
 #define SSITF                  0x44            /* TX FIFO trigger level */
 #define SSITF_TxHiThresh(x)    (((x) - 1) << 0)
@@ -205,6 +220,7 @@ enum pxa_ssp_type {
        MMP2_SSP,
        PXA910_SSP,
        CE4100_SSP,
+       MRFLD_SSP,
        QUARK_X1000_SSP,
        LPSS_LPT_SSP, /* Keep LPSS types sorted with lpss_platforms[] */
        LPSS_BYT_SSP,