spi: pxa2xx: Introduce special type for Merrifield SPIs

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>
This commit is contained in:
Andy Shevchenko 2021-05-10 15:41:34 +03:00 committed by Mark Brown
parent eca32c3974
commit 3fdb59cf10
No known key found for this signature in database
GPG key ID: 24D68B725D5487D0
3 changed files with 46 additions and 4 deletions

View 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,
},

View 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

View 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,