diff options
-rw-r--r-- | drivers/spi/spi-dw-mmio.c | 10 | ||||
-rw-r--r-- | drivers/spi/spi-dw.c | 33 | ||||
-rw-r--r-- | drivers/spi/spi-dw.h | 12 |
3 files changed, 55 insertions, 0 deletions
diff --git a/drivers/spi/spi-dw-mmio.c b/drivers/spi/spi-dw-mmio.c index a52f75e22109..1df6f3deee2c 100644 --- a/drivers/spi/spi-dw-mmio.c +++ b/drivers/spi/spi-dw-mmio.c @@ -146,6 +146,15 @@ static int dw_spi_dw_apb_init(struct platform_device *pdev, return 0; } +static int dw_spi_dwc_ssi_init(struct platform_device *pdev, + struct dw_spi_mmio *dwsmmio) +{ + /* Register hook to configure CTRLR0 */ + dwsmmio->dws.update_cr0 = dw_spi_update_cr0_v1_01a; + + return 0; +} + static int dw_spi_mmio_probe(struct platform_device *pdev) { int (*init_func)(struct platform_device *pdev, @@ -244,6 +253,7 @@ static const struct of_device_id dw_spi_mmio_of_match[] = { { .compatible = "mscc,jaguar2-spi", .data = dw_spi_mscc_jaguar2_init}, { .compatible = "amazon,alpine-dw-apb-ssi", .data = dw_spi_alpine_init}, { .compatible = "renesas,rzn1-spi", .data = dw_spi_dw_apb_init}, + { .compatible = "snps,dwc-ssi-1.01a", .data = dw_spi_dwc_ssi_init}, { /* end of table */} }; MODULE_DEVICE_TABLE(of, dw_spi_mmio_of_match); diff --git a/drivers/spi/spi-dw.c b/drivers/spi/spi-dw.c index 4905457641ef..240a61b66a06 100644 --- a/drivers/spi/spi-dw.c +++ b/drivers/spi/spi-dw.c @@ -277,6 +277,39 @@ u32 dw_spi_update_cr0(struct spi_controller *master, struct spi_device *spi, } EXPORT_SYMBOL_GPL(dw_spi_update_cr0); +/* Configure CTRLR0 for DWC_ssi */ +u32 dw_spi_update_cr0_v1_01a(struct spi_controller *master, + struct spi_device *spi, + struct spi_transfer *transfer) +{ + struct dw_spi *dws = spi_controller_get_devdata(master); + struct chip_data *chip = spi_get_ctldata(spi); + u32 cr0; + + /* CTRLR0[ 4: 0] Data Frame Size */ + cr0 = (transfer->bits_per_word - 1); + + /* CTRLR0[ 7: 6] Frame Format */ + cr0 |= chip->type << DWC_SSI_CTRLR0_FRF_OFFSET; + + /* + * SPI mode (SCPOL|SCPH) + * CTRLR0[ 8] Serial Clock Phase + * CTRLR0[ 9] Serial Clock Polarity + */ + cr0 |= ((spi->mode & SPI_CPOL) ? 1 : 0) << DWC_SSI_CTRLR0_SCPOL_OFFSET; + cr0 |= ((spi->mode & SPI_CPHA) ? 1 : 0) << DWC_SSI_CTRLR0_SCPH_OFFSET; + + /* CTRLR0[11:10] Transfer Mode */ + cr0 |= chip->tmode << DWC_SSI_CTRLR0_TMOD_OFFSET; + + /* CTRLR0[13] Shift Register Loop */ + cr0 |= ((spi->mode & SPI_LOOP) ? 1 : 0) << DWC_SSI_CTRLR0_SRL_OFFSET; + + return cr0; +} +EXPORT_SYMBOL_GPL(dw_spi_update_cr0_v1_01a); + static int dw_spi_transfer_one(struct spi_controller *master, struct spi_device *spi, struct spi_transfer *transfer) { diff --git a/drivers/spi/spi-dw.h b/drivers/spi/spi-dw.h index 2745a7e7405c..8fe724279d15 100644 --- a/drivers/spi/spi-dw.h +++ b/drivers/spi/spi-dw.h @@ -57,6 +57,15 @@ #define SPI_SRL_OFFSET 11 #define SPI_CFS_OFFSET 12 +/* Bit fields in CTRLR0 based on DWC_ssi_databook.pdf v1.01a */ +#define DWC_SSI_CTRLR0_SRL_OFFSET 13 +#define DWC_SSI_CTRLR0_TMOD_OFFSET 10 +#define DWC_SSI_CTRLR0_TMOD_MASK GENMASK(11, 10) +#define DWC_SSI_CTRLR0_SCPOL_OFFSET 9 +#define DWC_SSI_CTRLR0_SCPH_OFFSET 8 +#define DWC_SSI_CTRLR0_FRF_OFFSET 6 +#define DWC_SSI_CTRLR0_DFS_OFFSET 0 + /* Bit fields in SR, 7 bits */ #define SR_MASK 0x7f /* cover 7 bits */ #define SR_BUSY (1 << 0) @@ -245,6 +254,9 @@ extern int dw_spi_resume_host(struct dw_spi *dws); extern u32 dw_spi_update_cr0(struct spi_controller *master, struct spi_device *spi, struct spi_transfer *transfer); +extern u32 dw_spi_update_cr0_v1_01a(struct spi_controller *master, + struct spi_device *spi, + struct spi_transfer *transfer); /* platform related setup */ extern int dw_spi_mid_init(struct dw_spi *dws); /* Intel MID platforms */ |