[PATCH v2 02/11] spi: dw: update SPI_CTRLR0 register
Changhuang Liang <[email protected]> Mon, 3 Aug 2026 05:40:35 -0700
| Newsgroups | org.kernel.vger.linux-spi,org.kernel.vger.linux-devicetree,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
From: Sudip Mukherjee <[email protected]> If the SPI transfer is being done in enhanced mode then SPI_CTRLR0 register needs to be updated to mention the instruction length, address length, address and instruction transfer format, wait cycles. And, we also need to enable clock stretching. Signed-off-by: Sudip Mukherjee <[email protected]> Co-developed-by: Changhuang Liang <[email protected]> Signed-off-by: Changhuang Liang <[email protected]> --- drivers/spi/spi-dw-core.c | 15 ++++++++++++--- drivers/spi/spi-dw.h | 17 ++++++++++++++++- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/drivers/spi/spi-dw-core.c b/drivers/spi/spi-dw-core.c index 86e3e7487bc7..7601a53d6f34 100644 --- a/drivers/spi/spi-dw-core.c +++ b/drivers/spi/spi-dw-core.c @@ -313,7 +313,7 @@ static u32 dw_spi_prepare_cr0(struct dw_spi *dws, struct spi_device *spi) } void dw_spi_update_config(struct dw_spi *dws, struct spi_device *spi, - struct dw_spi_cfg *cfg) + struct dw_spi_cfg *cfg, struct dw_spi_enh_cfg *enh_cfg) { struct dw_spi_chip_data *chip = spi_get_ctldata(spi); u32 cr0 = chip->cr0; @@ -363,6 +363,15 @@ void dw_spi_update_config(struct dw_spi *dws, struct spi_device *spi, dw_writel(dws, DW_SPI_RX_SAMPLE_DLY, chip->rx_sample_dly); dws->cur_rx_sample_dly = chip->rx_sample_dly; } + + if (enh_cfg) { + cr0 = DW_SPI_ENH_CTRLR0_CLK_STRETCH_EN; + cr0 |= FIELD_PREP(DW_SPI_ENH_CTRLR0_WAIT_CYCLE_MASK, enh_cfg->wait_c); + cr0 |= FIELD_PREP(DW_SPI_ENH_CTRLR0_INST_L_MASK, enh_cfg->inst_l); + cr0 |= FIELD_PREP(DW_SPI_ENH_CTRLR0_ADDR_L_MASK, enh_cfg->addr_l); + cr0 |= FIELD_PREP(DW_SPI_ENH_CTRLR0_TRANS_TYPE_MASK, enh_cfg->trans_t); + dw_writel(dws, DW_SPI_SPI_CTRLR0, cr0); + } } EXPORT_SYMBOL_NS_GPL(dw_spi_update_config, "SPI_DW_CORE"); @@ -448,7 +457,7 @@ static int dw_spi_transfer_one(struct spi_controller *ctlr, dw_spi_enable_chip(dws, 0); - dw_spi_update_config(dws, spi, &cfg); + dw_spi_update_config(dws, spi, &cfg, NULL); transfer->effective_speed_hz = dws->current_freq; @@ -715,7 +724,7 @@ static int dw_spi_exec_mem_op(struct spi_mem *mem, const struct spi_mem_op *op) dw_spi_enable_chip(dws, 0); - dw_spi_update_config(dws, mem->spi, &cfg); + dw_spi_update_config(dws, mem->spi, &cfg, NULL); dw_spi_mask_intr(dws, 0xff); diff --git a/drivers/spi/spi-dw.h b/drivers/spi/spi-dw.h index 19cf1b1a5d4f..16a8c7ab7364 100644 --- a/drivers/spi/spi-dw.h +++ b/drivers/spi/spi-dw.h @@ -63,6 +63,7 @@ #define DW_SPI_VERSION 0x5c #define DW_SPI_DR 0x60 #define DW_SPI_RX_SAMPLE_DLY 0xf0 +#define DW_SPI_SPI_CTRLR0 0xf4 #define DW_SPI_CS_OVERRIDE 0xf4 /* Bit fields in CTRLR0 (DWC APB SSI) */ @@ -127,6 +128,13 @@ #define DW_SPI_DMACR_RDMAE BIT(0) #define DW_SPI_DMACR_TDMAE BIT(1) +/* Bit fields in SPI_CTRLR0 */ +#define DW_SPI_ENH_CTRLR0_CLK_STRETCH_EN BIT(30) +#define DW_SPI_ENH_CTRLR0_WAIT_CYCLE_MASK GENMASK(15, 11) +#define DW_SPI_ENH_CTRLR0_INST_L_MASK GENMASK(9, 8) +#define DW_SPI_ENH_CTRLR0_ADDR_L_MASK GENMASK(5, 2) +#define DW_SPI_ENH_CTRLR0_TRANS_TYPE_MASK GENMASK(1, 0) + /* Mem/DMA operations helpers */ #define DW_SPI_WAIT_RETRIES 5 #define DW_SPI_BUF_SIZE \ @@ -144,6 +152,13 @@ struct dw_spi_cfg { u8 spi_frf; }; +struct dw_spi_enh_cfg { + u8 wait_c; + u8 inst_l; + u8 addr_l; + u8 trans_t; +}; + struct dw_spi; struct dw_spi_dma_ops { int (*dma_init)(struct device *dev, struct dw_spi *dws); @@ -294,7 +309,7 @@ static inline void dw_spi_shutdown_chip(struct dw_spi *dws) extern void dw_spi_set_cs(struct spi_device *spi, bool enable); extern void dw_spi_update_config(struct dw_spi *dws, struct spi_device *spi, - struct dw_spi_cfg *cfg); + struct dw_spi_cfg *cfg, struct dw_spi_enh_cfg *enh_cfg); extern int dw_spi_check_status(struct dw_spi *dws, bool raw); extern int dw_spi_add_controller(struct device *dev, struct dw_spi *dws); extern void dw_spi_remove_controller(struct dw_spi *dws); -- 2.25.1