]> www.infradead.org Git - nvme.git/commitdiff
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 a259be12d326560a838f96e075d35ec121499694..dce9ade9a4dfba9395a7bb6844bca8878a5acbb5 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 af3f01de8f5b174de4e97731a63d21116f2fec7b..5985b39e2dd60a03e4abc34cef26e8d0540c36ee 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 fdfbe17e15f461a447fb27c997bb67d5a1cd040b..2b21bc1f3c732bce290bc2af63579898565b4fa4 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,