diff options
-rw-r--r-- | Documentation/devicetree/bindings/spi/fsl,dspi.yaml | 18 | ||||
-rw-r--r-- | Documentation/devicetree/bindings/spi/mediatek,spi-mt65xx.yaml | 5 | ||||
-rw-r--r-- | Documentation/devicetree/bindings/spi/mxs-spi.yaml | 3 | ||||
-rw-r--r-- | drivers/spi/Kconfig | 4 | ||||
-rw-r--r-- | drivers/spi/spi-falcon.c | 5 | ||||
-rw-r--r-- | drivers/spi/spi-fsl-dspi.c | 356 | ||||
-rw-r--r-- | drivers/spi/spi-mt65xx.c | 11 | ||||
-rw-r--r-- | drivers/spi/spi-pci1xxxx.c | 9 | ||||
-rw-r--r-- | drivers/spi/spi-qpic-snand.c | 37 |
9 files changed, 291 insertions, 157 deletions
diff --git a/Documentation/devicetree/bindings/spi/fsl,dspi.yaml b/Documentation/devicetree/bindings/spi/fsl,dspi.yaml index bf9cce53c48d..8dbda1ffb5eb 100644 --- a/Documentation/devicetree/bindings/spi/fsl,dspi.yaml +++ b/Documentation/devicetree/bindings/spi/fsl,dspi.yaml @@ -23,6 +23,7 @@ properties: - fsl,ls2080a-dspi - fsl,ls2085a-dspi - fsl,lx2160a-dspi + - nxp,s32g2-dspi - items: - enum: - fsl,ls1012a-dspi @@ -37,6 +38,9 @@ properties: - items: - const: fsl,lx2160a-dspi - const: fsl,ls2085a-dspi + - items: + - const: nxp,s32g3-dspi + - const: nxp,s32g2-dspi reg: maxItems: 1 @@ -114,3 +118,17 @@ examples: spi-cs-hold-delay-ns = <50>; }; }; + # S32G3 in target mode + - | + spi@401d4000 { + compatible = "nxp,s32g3-dspi", "nxp,s32g2-dspi"; + reg = <0x401d4000 0x1000>; + interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clks 26>; + clock-names = "dspi"; + spi-num-chipselects = <8>; + bus-num = <0>; + dmas = <&edma0 0 7>, <&edma0 0 8>; + dma-names = "tx", "rx"; + spi-slave; + }; diff --git a/Documentation/devicetree/bindings/spi/mediatek,spi-mt65xx.yaml b/Documentation/devicetree/bindings/spi/mediatek,spi-mt65xx.yaml index ed17815263a8..3bf3eb1f8728 100644 --- a/Documentation/devicetree/bindings/spi/mediatek,spi-mt65xx.yaml +++ b/Documentation/devicetree/bindings/spi/mediatek,spi-mt65xx.yaml @@ -41,11 +41,16 @@ properties: - const: mediatek,spi-ipm - items: - enum: + - mediatek,mt8196-spi + - const: mediatek,mt6991-spi + - items: + - enum: - mediatek,mt2701-spi - mediatek,mt2712-spi - mediatek,mt6589-spi - mediatek,mt6765-spi - mediatek,mt6893-spi + - mediatek,mt6991-spi - mediatek,mt7622-spi - mediatek,mt8135-spi - mediatek,mt8173-spi diff --git a/Documentation/devicetree/bindings/spi/mxs-spi.yaml b/Documentation/devicetree/bindings/spi/mxs-spi.yaml index e2512166c1cd..0cf8e7269ba9 100644 --- a/Documentation/devicetree/bindings/spi/mxs-spi.yaml +++ b/Documentation/devicetree/bindings/spi/mxs-spi.yaml @@ -24,6 +24,9 @@ properties: interrupts: maxItems: 1 + clocks: + maxItems: 1 + dmas: maxItems: 1 diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index c51da3fc3604..f2d2295a5501 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -647,10 +647,10 @@ config SPI_FSL_SPI config SPI_FSL_DSPI tristate "Freescale DSPI controller" select REGMAP_MMIO - depends on SOC_VF610 || SOC_LS1021A || ARCH_LAYERSCAPE || M5441x || COMPILE_TEST + depends on ARCH_MXC || ARCH_NXP || M5441x || COMPILE_TEST help This enables support for the Freescale DSPI controller in master - mode. VF610, LS1021A and ColdFire platforms uses the controller. + mode. S32, VF610, LS1021A and ColdFire platforms uses the controller. config SPI_FSL_ESPI tristate "Freescale eSPI controller" diff --git a/drivers/spi/spi-falcon.c b/drivers/spi/spi-falcon.c index 84279058f0f1..faa893f83dc5 100644 --- a/drivers/spi/spi-falcon.c +++ b/drivers/spi/spi-falcon.c @@ -94,8 +94,9 @@ struct falcon_sflash { struct spi_controller *host; }; -int falcon_sflash_xfer(struct spi_device *spi, struct spi_transfer *t, - unsigned long flags) +static int +falcon_sflash_xfer(struct spi_device *spi, struct spi_transfer *t, + unsigned long flags) { struct device *dev = &spi->dev; struct falcon_sflash *priv = spi_controller_get_devdata(spi->controller); diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c index 863781ba6c16..04c88d090c4d 100644 --- a/drivers/spi/spi-fsl-dspi.c +++ b/drivers/spi/spi-fsl-dspi.c @@ -24,6 +24,7 @@ #define SPI_MCR 0x00 #define SPI_MCR_HOST BIT(31) +#define SPI_MCR_MTFE BIT(26) #define SPI_MCR_PCSIS(x) ((x) << 16) #define SPI_MCR_CLR_TXF BIT(11) #define SPI_MCR_CLR_RXF BIT(10) @@ -35,8 +36,9 @@ #define SPI_TCR 0x08 #define SPI_TCR_GET_TCNT(x) (((x) & GENMASK(31, 16)) >> 16) -#define SPI_CTAR(x) (0x0c + (((x) & GENMASK(1, 0)) * 4)) +#define SPI_CTAR(x) (0x0c + (((x) & GENMASK(2, 0)) * 4)) #define SPI_CTAR_FMSZ(x) (((x) << 27) & GENMASK(30, 27)) +#define SPI_CTAR_DBR BIT(31) #define SPI_CTAR_CPOL BIT(26) #define SPI_CTAR_CPHA BIT(25) #define SPI_CTAR_LSBFE BIT(24) @@ -93,12 +95,14 @@ #define SPI_TXFR1 0x40 #define SPI_TXFR2 0x44 #define SPI_TXFR3 0x48 +#define SPI_TXFR4 0x4C #define SPI_RXFR0 0x7c #define SPI_RXFR1 0x80 #define SPI_RXFR2 0x84 #define SPI_RXFR3 0x88 +#define SPI_RXFR4 0x8C -#define SPI_CTARE(x) (0x11c + (((x) & GENMASK(1, 0)) * 4)) +#define SPI_CTARE(x) (0x11c + (((x) & GENMASK(2, 0)) * 4)) #define SPI_CTARE_FMSZE(x) (((x) & 0x1) << 16) #define SPI_CTARE_DTCP(x) ((x) & 0x7ff) @@ -109,6 +113,8 @@ #define DMA_COMPLETION_TIMEOUT msecs_to_jiffies(3000) +#define SPI_25MHZ 25000000 + struct chip_data { u32 ctar_val; }; @@ -122,6 +128,7 @@ struct fsl_dspi_devtype_data { enum dspi_trans_mode trans_mode; u8 max_clock_factor; int fifo_size; + const struct regmap_config *regmap; }; enum { @@ -135,6 +142,102 @@ enum { LX2160A, MCF5441X, VF610, + S32G, + S32G_TARGET, +}; + +static const struct regmap_range dspi_yes_ranges[] = { + regmap_reg_range(SPI_MCR, SPI_MCR), + regmap_reg_range(SPI_TCR, SPI_CTAR(3)), + regmap_reg_range(SPI_SR, SPI_TXFR3), + regmap_reg_range(SPI_RXFR0, SPI_RXFR3), + regmap_reg_range(SPI_CTARE(0), SPI_CTARE(3)), + regmap_reg_range(SPI_SREX, SPI_SREX), +}; + +static const struct regmap_range s32g_dspi_yes_ranges[] = { + regmap_reg_range(SPI_MCR, SPI_MCR), + regmap_reg_range(SPI_TCR, SPI_CTAR(5)), + regmap_reg_range(SPI_SR, SPI_TXFR4), + regmap_reg_range(SPI_RXFR0, SPI_RXFR4), + regmap_reg_range(SPI_CTARE(0), SPI_CTARE(5)), + regmap_reg_range(SPI_SREX, SPI_SREX), +}; + +static const struct regmap_access_table dspi_access_table = { + .yes_ranges = dspi_yes_ranges, + .n_yes_ranges = ARRAY_SIZE(dspi_yes_ranges), +}; + +static const struct regmap_access_table s32g_dspi_access_table = { + .yes_ranges = s32g_dspi_yes_ranges, + .n_yes_ranges = ARRAY_SIZE(s32g_dspi_yes_ranges), +}; + +static const struct regmap_range dspi_volatile_ranges[] = { + regmap_reg_range(SPI_MCR, SPI_TCR), + regmap_reg_range(SPI_SR, SPI_SR), + regmap_reg_range(SPI_PUSHR, SPI_RXFR4), + regmap_reg_range(SPI_SREX, SPI_SREX), +}; + +static const struct regmap_access_table dspi_volatile_table = { + .yes_ranges = dspi_volatile_ranges, + .n_yes_ranges = ARRAY_SIZE(dspi_volatile_ranges), +}; + +enum { + DSPI_REGMAP, + S32G_DSPI_REGMAP, + DSPI_XSPI_REGMAP, + S32G_DSPI_XSPI_REGMAP, + DSPI_PUSHR, +}; + +static const struct regmap_config dspi_regmap_config[] = { + [DSPI_REGMAP] = { + .reg_bits = 32, + .val_bits = 32, + .reg_stride = 4, + .max_register = SPI_RXFR3, + .volatile_table = &dspi_volatile_table, + .rd_table = &dspi_access_table, + .wr_table = &dspi_access_table, + }, + [S32G_DSPI_REGMAP] = { + .reg_bits = 32, + .val_bits = 32, + .reg_stride = 4, + .max_register = SPI_RXFR4, + .volatile_table = &dspi_volatile_table, + .wr_table = &s32g_dspi_access_table, + .rd_table = &s32g_dspi_access_table, + }, + [DSPI_XSPI_REGMAP] = { + .reg_bits = 32, + .val_bits = 32, + .reg_stride = 4, + .max_register = SPI_SREX, + .volatile_table = &dspi_volatile_table, + .rd_table = &dspi_access_table, + .wr_table = &dspi_access_table, + }, + [S32G_DSPI_XSPI_REGMAP] = { + .reg_bits = 32, + .val_bits = 32, + .reg_stride = 4, + .max_register = SPI_SREX, + .volatile_table = &dspi_volatile_table, + .wr_table = &s32g_dspi_access_table, + .rd_table = &s32g_dspi_access_table, + }, + [DSPI_PUSHR] = { + .name = "pushr", + .reg_bits = 16, + .val_bits = 16, + .reg_stride = 2, + .max_register = 0x2, + }, }; static const struct fsl_dspi_devtype_data devtype_data[] = { @@ -142,55 +245,77 @@ static const struct fsl_dspi_devtype_data devtype_data[] = { .trans_mode = DSPI_DMA_MODE, .max_clock_factor = 2, .fifo_size = 4, + .regmap = &dspi_regmap_config[DSPI_REGMAP], }, [LS1021A] = { /* Has A-011218 DMA erratum */ .trans_mode = DSPI_XSPI_MODE, .max_clock_factor = 8, .fifo_size = 4, + .regmap = &dspi_regmap_config[DSPI_XSPI_REGMAP], }, [LS1012A] = { /* Has A-011218 DMA erratum */ .trans_mode = DSPI_XSPI_MODE, .max_clock_factor = 8, .fifo_size = 16, + .regmap = &dspi_regmap_config[DSPI_XSPI_REGMAP], }, [LS1028A] = { .trans_mode = DSPI_XSPI_MODE, .max_clock_factor = 8, .fifo_size = 4, + .regmap = &dspi_regmap_config[DSPI_XSPI_REGMAP], }, [LS1043A] = { /* Has A-011218 DMA erratum */ .trans_mode = DSPI_XSPI_MODE, .max_clock_factor = 8, .fifo_size = 16, + .regmap = &dspi_regmap_config[DSPI_XSPI_REGMAP], }, [LS1046A] = { /* Has A-011218 DMA erratum */ .trans_mode = DSPI_XSPI_MODE, .max_clock_factor = 8, .fifo_size = 16, + .regmap = &dspi_regmap_config[DSPI_XSPI_REGMAP], }, [LS2080A] = { .trans_mode = DSPI_XSPI_MODE, .max_clock_factor = 8, .fifo_size = 4, + .regmap = &dspi_regmap_config[DSPI_XSPI_REGMAP], }, [LS2085A] = { .trans_mode = DSPI_XSPI_MODE, .max_clock_factor = 8, .fifo_size = 4, + .regmap = &dspi_regmap_config[DSPI_XSPI_REGMAP], }, [LX2160A] = { .trans_mode = DSPI_XSPI_MODE, .max_clock_factor = 8, .fifo_size = 4, + .regmap = &dspi_regmap_config[DSPI_XSPI_REGMAP], }, [MCF5441X] = { .trans_mode = DSPI_DMA_MODE, .max_clock_factor = 8, .fifo_size = 16, + .regmap = &dspi_regmap_config[DSPI_REGMAP], + }, + [S32G] = { + .trans_mode = DSPI_XSPI_MODE, + .max_clock_factor = 1, + .fifo_size = 5, + .regmap = &dspi_regmap_config[S32G_DSPI_XSPI_REGMAP], + }, + [S32G_TARGET] = { + .trans_mode = DSPI_DMA_MODE, + .max_clock_factor = 1, + .fifo_size = 5, + .regmap = &dspi_regmap_config[S32G_DSPI_REGMAP], }, }; @@ -225,6 +350,7 @@ struct fsl_dspi { const void *tx; void *rx; u16 tx_cmd; + bool mtf_enabled; const struct fsl_dspi_devtype_data *devtype_data; struct completion xfer_done; @@ -247,6 +373,12 @@ struct fsl_dspi { void (*dev_to_host)(struct fsl_dspi *dspi, u32 rxdata); }; +static bool is_s32g_dspi(struct fsl_dspi *data) +{ + return data->devtype_data == &devtype_data[S32G] || + data->devtype_data == &devtype_data[S32G_TARGET]; +} + static void dspi_native_host_to_dev(struct fsl_dspi *dspi, u32 *txdata) { switch (dspi->oper_word_size) { @@ -595,7 +727,7 @@ static void dspi_release_dma(struct fsl_dspi *dspi) } static void hz_to_spi_baud(char *pbr, char *br, int speed_hz, - unsigned long clkrate) + unsigned long clkrate, bool mtf_enabled) { /* Valid baud rate pre-scaler values */ int pbr_tbl[4] = {2, 3, 5, 7}; @@ -612,7 +744,13 @@ static void hz_to_spi_baud(char *pbr, char *br, int speed_hz, for (i = 0; i < ARRAY_SIZE(brs); i++) for (j = 0; j < ARRAY_SIZE(pbr_tbl); j++) { - scale = brs[i] * pbr_tbl[j]; + if (mtf_enabled) { + /* In MTF mode DBR=1 so frequency is doubled */ + scale = (brs[i] * pbr_tbl[j]) / 2; + } else { + scale = brs[i] * pbr_tbl[j]; + } + if (scale >= scale_needed) { if (scale < minscale) { minscale = scale; @@ -746,8 +884,12 @@ static void dspi_setup_accel(struct fsl_dspi *dspi) struct spi_transfer *xfer = dspi->cur_transfer; bool odd = !!(dspi->len & 1); - /* No accel for frames not multiple of 8 bits at the moment */ - if (xfer->bits_per_word % 8) + /* + * No accel for DMA transfers or frames not multiples of 8 bits at the + * moment. + */ + if (dspi->devtype_data->trans_mode == DSPI_DMA_MODE || + xfer->bits_per_word % 8) goto no_accel; if (!odd && dspi->len <= dspi->devtype_data->fifo_size * 2) { @@ -756,10 +898,7 @@ static void dspi_setup_accel(struct fsl_dspi *dspi) dspi->oper_bits_per_word = 8; } else { /* Start off with maximum supported by hardware */ - if (dspi->devtype_data->trans_mode == DSPI_XSPI_MODE) - dspi->oper_bits_per_word = 32; - else - dspi->oper_bits_per_word = 16; + dspi->oper_bits_per_word = 32; /* * And go down only if the buffer can't be sent with @@ -1018,6 +1157,20 @@ static int dspi_transfer_one_message(struct spi_controller *ctlr, return status; } +static int dspi_set_mtf(struct fsl_dspi *dspi) +{ + if (spi_controller_is_target(dspi->ctlr)) + return 0; + + if (dspi->mtf_enabled) + regmap_update_bits(dspi->regmap, SPI_MCR, SPI_MCR_MTFE, + SPI_MCR_MTFE); + else + regmap_update_bits(dspi->regmap, SPI_MCR, SPI_MCR_MTFE, 0); + + return 0; +} + static int dspi_setup(struct spi_device *spi) { struct fsl_dspi *dspi = spi_controller_get_devdata(spi->controller); @@ -1076,7 +1229,16 @@ static int dspi_setup(struct spi_device *spi) cs_sck_delay, sck_cs_delay); clkrate = clk_get_rate(dspi->clk); - hz_to_spi_baud(&pbr, &br, spi->max_speed_hz, clkrate); + + if (is_s32g_dspi(dspi) && spi->max_speed_hz > SPI_25MHZ) + dspi->mtf_enabled = true; + else + dspi->mtf_enabled = false; + + dspi_set_mtf(dspi); + + hz_to_spi_baud(&pbr, &br, spi->max_speed_hz, clkrate, + dspi->mtf_enabled); /* Set PCS to SCK delay scale values */ ns_delay_scale(&pcssck, &cssck, cs_sck_delay, clkrate); @@ -1098,6 +1260,9 @@ static int dspi_setup(struct spi_device *spi) SPI_CTAR_PBR(pbr) | SPI_CTAR_BR(br); + if (dspi->mtf_enabled) + chip->ctar_val |= SPI_CTAR_DBR; + if (spi->mode & SPI_LSB_FIRST) chip->ctar_val |= SPI_CTAR_LSBFE; } @@ -1151,112 +1316,14 @@ static const struct of_device_id fsl_dspi_dt_ids[] = { }, { .compatible = "fsl,lx2160a-dspi", .data = &devtype_data[LX2160A], + }, { + .compatible = "nxp,s32g2-dspi", + .data = &devtype_data[S32G], }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, fsl_dspi_dt_ids); -#ifdef CONFIG_PM_SLEEP -static int dspi_suspend(struct device *dev) -{ - struct fsl_dspi *dspi = dev_get_drvdata(dev); - - if (dspi->irq) - disable_irq(dspi->irq); - spi_controller_suspend(dspi->ctlr); - clk_disable_unprepare(dspi->clk); - - pinctrl_pm_select_sleep_state(dev); - - return 0; -} - -static int dspi_resume(struct device *dev) -{ - struct fsl_dspi *dspi = dev_get_drvdata(dev); - int ret; - - pinctrl_pm_select_default_state(dev); - - ret = clk_prepare_enable(dspi->clk); - if (ret) - return ret; - spi_controller_resume(dspi->ctlr); - if (dspi->irq) - enable_irq(dspi->irq); - - return 0; -} -#endif /* CONFIG_PM_SLEEP */ - -static SIMPLE_DEV_PM_OPS(dspi_pm, dspi_suspend, dspi_resume); - -static const struct regmap_range dspi_yes_ranges[] = { - regmap_reg_range(SPI_MCR, SPI_MCR), - regmap_reg_range(SPI_TCR, SPI_CTAR(3)), - regmap_reg_range(SPI_SR, SPI_TXFR3), - regmap_reg_range(SPI_RXFR0, SPI_RXFR3), - regmap_reg_range(SPI_CTARE(0), SPI_CTARE(3)), - regmap_reg_range(SPI_SREX, SPI_SREX), -}; - -static const struct regmap_access_table dspi_access_table = { - .yes_ranges = dspi_yes_ranges, - .n_yes_ranges = ARRAY_SIZE(dspi_yes_ranges), -}; - -static const struct regmap_range dspi_volatile_ranges[] = { - regmap_reg_range(SPI_MCR, SPI_TCR), - regmap_reg_range(SPI_SR, SPI_SR), - regmap_reg_range(SPI_PUSHR, SPI_RXFR3), -}; - -static const struct regmap_access_table dspi_volatile_table = { - .yes_ranges = dspi_volatile_ranges, - .n_yes_ranges = ARRAY_SIZE(dspi_volatile_ranges), -}; - -static const struct regmap_config dspi_regmap_config = { - .reg_bits = 32, - .val_bits = 32, - .reg_stride = 4, - .max_register = 0x88, - .volatile_table = &dspi_volatile_table, - .rd_table = &dspi_access_table, - .wr_table = &dspi_access_table, -}; - -static const struct regmap_range dspi_xspi_volatile_ranges[] = { - regmap_reg_range(SPI_MCR, SPI_TCR), - regmap_reg_range(SPI_SR, SPI_SR), - regmap_reg_range(SPI_PUSHR, SPI_RXFR3), - regmap_reg_range(SPI_SREX, SPI_SREX), -}; - -static const struct regmap_access_table dspi_xspi_volatile_table = { - .yes_ranges = dspi_xspi_volatile_ranges, - .n_yes_ranges = ARRAY_SIZE(dspi_xspi_volatile_ranges), -}; - -static const struct regmap_config dspi_xspi_regmap_config[] = { - { - .reg_bits = 32, - .val_bits = 32, - .reg_stride = 4, - .max_register = 0x13c, - .volatile_table = &dspi_xspi_volatile_table, - .rd_table = &dspi_access_table, - .wr_table = &dspi_access_table, - }, - { - .name = "pushr", - .reg_bits = 16, - .val_bits = 16, - .reg_stride = 2, - .max_register = 0x2, - }, -}; - static int dspi_init(struct fsl_dspi *dspi) { unsigned int mcr; @@ -1292,6 +1359,50 @@ static int dspi_init(struct fsl_dspi *dspi) return 0; } +#ifdef CONFIG_PM_SLEEP +static int dspi_suspend(struct device *dev) +{ + struct fsl_dspi *dspi = dev_get_drvdata(dev); + + if (dspi->irq) + disable_irq(dspi->irq); + spi_controller_suspend(dspi->ctlr); + clk_disable_unprepare(dspi->clk); + + pinctrl_pm_select_sleep_state(dev); + + return 0; +} + +static int dspi_resume(struct device *dev) +{ + struct fsl_dspi *dspi = dev_get_drvdata(dev); + int ret; + + pinctrl_pm_select_default_state(dev); + + ret = clk_prepare_enable(dspi->clk); + if (ret) + return ret; + spi_controller_resume(dspi->ctlr); + + ret = dspi_init(dspi); + if (ret) { + dev_err(dev, "failed to initialize dspi during resume\n"); + return ret; + } + + dspi_set_mtf(dspi); + + if (dspi->irq) + enable_irq(dspi->irq); + + return 0; +} +#endif /* CONFIG_PM_SLEEP */ + +static SIMPLE_DEV_PM_OPS(dspi_pm, dspi_suspend, dspi_resume); + static int dspi_target_abort(struct spi_controller *host) { struct fsl_dspi *dspi = spi_controller_get_devdata(host); @@ -1316,7 +1427,6 @@ static int dspi_target_abort(struct spi_controller *host) static int dspi_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; - const struct regmap_config *regmap_config; struct fsl_dspi_platform_data *pdata; struct spi_controller *ctlr; int ret, cs_num, bus_num = -1; @@ -1329,7 +1439,10 @@ static int dspi_probe(struct platform_device *pdev) if (!dspi) return -ENOMEM; - ctlr = spi_alloc_host(&pdev->dev, 0); + if (of_property_read_bool(np, "spi-slave")) + ctlr = spi_alloc_target(&pdev->dev, 0); + else + ctlr = spi_alloc_host(&pdev->dev, 0); if (!ctlr) return -ENOMEM; @@ -1368,9 +1481,6 @@ static int dspi_probe(struct platform_device *pdev) of_property_read_u32(np, "bus-num", &bus_num); ctlr->bus_num = bus_num; - if (of_property_read_bool(np, "spi-slave")) - ctlr->target = true; - dspi->devtype_data = of_device_get_match_data(&pdev->dev); if (!dspi->devtype_data) { dev_err(&pdev->dev, "can't get devtype_data\n"); @@ -1388,6 +1498,9 @@ static int dspi_probe(struct platform_device *pdev) dspi->pushr_tx = 0; } + if (spi_controller_is_target(ctlr) && is_s32g_dspi(dspi)) + dspi->devtype_data = &devtype_data[S32G_TARGET]; + if (dspi->devtype_data->trans_mode == DSPI_XSPI_MODE) ctlr->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32); else @@ -1399,11 +1512,8 @@ static int dspi_probe(struct platform_device *pdev) goto out_ctlr_put; } - if (dspi->devtype_data->trans_mode == DSPI_XSPI_MODE) - regmap_config = &dspi_xspi_regmap_config[0]; - else - regmap_config = &dspi_regmap_config; - dspi->regmap = devm_regmap_init_mmio(&pdev->dev, base, regmap_config); + dspi->regmap = devm_regmap_init_mmio(&pdev->dev, base, + dspi->devtype_data->regmap); if (IS_ERR(dspi->regmap)) { dev_err(&pdev->dev, "failed to init regmap: %ld\n", PTR_ERR(dspi->regmap)); @@ -1414,7 +1524,7 @@ static int dspi_probe(struct platform_device *pdev) if (dspi->devtype_data->trans_mode == DSPI_XSPI_MODE) { dspi->regmap_pushr = devm_regmap_init_mmio( &pdev->dev, base + SPI_PUSHR, - &dspi_xspi_regmap_config[1]); + &dspi_regmap_config[DSPI_PUSHR]); if (IS_ERR(dspi->regmap_pushr)) { dev_err(&pdev->dev, "failed to init pushr regmap: %ld\n", diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c index 4b0a1c0db041..a6032d44771b 100644 --- a/drivers/spi/spi-mt65xx.c +++ b/drivers/spi/spi-mt65xx.c @@ -220,6 +220,14 @@ static const struct mtk_spi_compatible mt6893_compat = { .no_need_unprepare = true, }; +static const struct mtk_spi_compatible mt6991_compat = { + .need_pad_sel = true, + .must_tx = true, + .enhance_timing = true, + .dma_ext = true, + .ipm_design = true, +}; + /* * A piece of default chip info unless the platform * supplies it. @@ -245,6 +253,9 @@ static const struct of_device_id mtk_spi_of_match[] = { { .compatible = "mediatek,mt6765-spi", .data = (void *)&mt6765_compat, }, + { .compatible = "mediatek,mt6991-spi", + .data = (void *)&mt6991_compat, + }, { .compatible = "mediatek,mt7622-spi", .data = (void *)&mt7622_compat, }, diff --git a/drivers/spi/spi-pci1xxxx.c b/drivers/spi/spi-pci1xxxx.c index e27642c4dea4..a6c8bf228288 100644 --- a/drivers/spi/spi-pci1xxxx.c +++ b/drivers/spi/spi-pci1xxxx.c @@ -23,6 +23,7 @@ #define SYS_FREQ_DEFAULT (62500000) #define PCI1XXXX_SPI_MAX_CLOCK_HZ (30000000) +#define PCI1XXXX_SPI_CLK_25MHZ (25000000) #define PCI1XXXX_SPI_CLK_20MHZ (20000000) #define PCI1XXXX_SPI_CLK_15MHZ (15000000) #define PCI1XXXX_SPI_CLK_12MHZ (12000000) @@ -318,12 +319,14 @@ static void pci1xxxx_spi_set_cs(struct spi_device *spi, bool enable) writel(regval, par->reg_base + SPI_MST_CTL_REG_OFFSET(p->hw_inst)); } -static u8 pci1xxxx_get_clock_div(u32 hz) +static u8 pci1xxxx_get_clock_div(struct pci1xxxx_spi *par, u32 hz) { u8 val = 0; if (hz >= PCI1XXXX_SPI_MAX_CLOCK_HZ) val = 2; + else if (par->dev_rev >= 0xC0 && hz >= PCI1XXXX_SPI_CLK_25MHZ) + val = 1; else if ((hz < PCI1XXXX_SPI_MAX_CLOCK_HZ) && (hz >= PCI1XXXX_SPI_CLK_20MHZ)) val = 3; else if ((hz < PCI1XXXX_SPI_CLK_20MHZ) && (hz >= PCI1XXXX_SPI_CLK_15MHZ)) @@ -423,7 +426,7 @@ static int pci1xxxx_spi_transfer_with_io(struct spi_controller *spi_ctlr, p->spi_xfer_in_progress = true; p->bytes_recvd = 0; - clkdiv = pci1xxxx_get_clock_div(xfer->speed_hz); + clkdiv = pci1xxxx_get_clock_div(par, xfer->speed_hz); tx_buf = xfer->tx_buf; rx_buf = xfer->rx_buf; transfer_len = xfer->len; @@ -492,7 +495,7 @@ static int pci1xxxx_spi_transfer_with_dma(struct spi_controller *spi_ctlr, } p->xfer = xfer; p->mode = spi->mode; - p->clkdiv = pci1xxxx_get_clock_div(xfer->speed_hz); + p->clkdiv = pci1xxxx_get_clock_div(par, xfer->speed_hz); p->bytes_recvd = 0; p->rx_buf = xfer->rx_buf; regval = readl(par->reg_base + SPI_MST_EVENT_REG_OFFSET(p->hw_inst)); diff --git a/drivers/spi/spi-qpic-snand.c b/drivers/spi/spi-qpic-snand.c index 77d9cc65477a..ca55f9bcd17b 100644 --- a/drivers/spi/spi-qpic-snand.c +++ b/drivers/spi/spi-qpic-snand.c @@ -59,12 +59,6 @@ #define OOB_BUF_SIZE 128 #define ecceng_to_qspi(eng) container_of(eng, struct qpic_spi_nand, ecc_eng) -struct qpic_snand_op { - u32 cmd_reg; - u32 addr1_reg; - u32 addr2_reg; -}; - struct snandc_read_status { __le32 snandc_flash; __le32 snandc_buffer; @@ -835,7 +829,7 @@ static int qcom_spi_read_page_ecc(struct qcom_nand_controller *snandc, int data_size, oob_size; if (i == (num_cw - 1)) { - data_size = 512 - ((num_cw - 1) << 2); + data_size = NANDC_STEP_SIZE - ((num_cw - 1) << 2); oob_size = (num_cw << 2) + ecc_cfg->ecc_bytes_hw + ecc_cfg->spare_bytes; } else { @@ -1294,7 +1288,6 @@ static int qcom_spi_write_page(struct qcom_nand_controller *snandc, static int qcom_spi_send_cmdaddr(struct qcom_nand_controller *snandc, const struct spi_mem_op *op) { - struct qpic_snand_op s_op = {}; u32 cmd; int ret, opcode; @@ -1302,34 +1295,24 @@ static int qcom_spi_send_cmdaddr(struct qcom_nand_controller *snandc, if (ret < 0) return ret; - s_op.cmd_reg = cmd; - s_op.addr1_reg = op->addr.val; - s_op.addr2_reg = 0; - opcode = op->cmd.opcode; switch (opcode) { case SPINAND_WRITE_EN: return 0; case SPINAND_PROGRAM_EXECUTE: - s_op.addr1_reg = op->addr.val << 16; - s_op.addr2_reg = op->addr.val >> 16 & 0xff; - snandc->qspi->addr1 = cpu_to_le32(s_op.addr1_reg); - snandc->qspi->addr2 = cpu_to_le32(s_op.addr2_reg); + snandc->qspi->addr1 = cpu_to_le32(op->addr.val << 16); + snandc->qspi->addr2 = cpu_to_le32(op->addr.val >> 16 & 0xff); snandc->qspi->cmd = cpu_to_le32(cmd); return qcom_spi_program_execute(snandc, op); case SPINAND_READ: - s_op.addr1_reg = (op->addr.val << 16); - s_op.addr2_reg = op->addr.val >> 16 & 0xff; - snandc->qspi->addr1 = cpu_to_le32(s_op.addr1_reg); - snandc->qspi->addr2 = cpu_to_le32(s_op.addr2_reg); + snandc->qspi->addr1 = cpu_to_le32(op->addr.val << 16); + snandc->qspi->addr2 = cpu_to_le32(op->addr.val >> 16 & 0xff); snandc->qspi->cmd = cpu_to_le32(cmd); return 0; case SPINAND_ERASE: - s_op.addr2_reg = (op->addr.val >> 16) & 0xffff; - s_op.addr1_reg = op->addr.val; - snandc->qspi->addr1 = cpu_to_le32(s_op.addr1_reg << 16); - snandc->qspi->addr2 = cpu_to_le32(s_op.addr2_reg); + snandc->qspi->addr1 = cpu_to_le32(op->addr.val << 16); + snandc->qspi->addr2 = cpu_to_le32(op->addr.val >> 16 & 0xffff); snandc->qspi->cmd = cpu_to_le32(cmd); return qcom_spi_block_erase(snandc); default: @@ -1341,10 +1324,10 @@ static int qcom_spi_send_cmdaddr(struct qcom_nand_controller *snandc, qcom_clear_read_regs(snandc); qcom_clear_bam_transaction(snandc); - snandc->regs->cmd = cpu_to_le32(s_op.cmd_reg); + snandc->regs->cmd = cpu_to_le32(cmd); snandc->regs->exec = cpu_to_le32(1); - snandc->regs->addr0 = cpu_to_le32(s_op.addr1_reg); - snandc->regs->addr1 = cpu_to_le32(s_op.addr2_reg); + snandc->regs->addr0 = cpu_to_le32(op->addr.val); + snandc->regs->addr1 = cpu_to_le32(0); qcom_write_reg_dma(snandc, &snandc->regs->cmd, NAND_FLASH_CMD, 3, NAND_BAM_NEXT_SGL); qcom_write_reg_dma(snandc, &snandc->regs->exec, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL); |