diff --git a/drivers/spi/spi_dw.c b/drivers/spi/spi_dw.c index 98904fbc26..7126cac00a 100644 --- a/drivers/spi/spi_dw.c +++ b/drivers/spi/spi_dw.c @@ -113,12 +113,10 @@ static void push_data(const struct device *dev) data = UNALIGNED_GET((uint16_t *) (spi->ctx.tx_buf)); break; -#ifndef CONFIG_ARC case 4: data = UNALIGNED_GET((uint32_t *) (spi->ctx.tx_buf)); break; -#endif } } else if (spi_context_rx_on(&spi->ctx)) { /* No need to push more than necessary */ @@ -164,11 +162,9 @@ static void pull_data(const struct device *dev) case 2: UNALIGNED_PUT(data, (uint16_t *)spi->ctx.rx_buf); break; -#ifndef CONFIG_ARC case 4: UNALIGNED_PUT(data, (uint32_t *)spi->ctx.rx_buf); break; -#endif } } @@ -222,8 +218,18 @@ static int spi_dw_configure(const struct spi_dw_config *info, return -EINVAL; } + if (info->max_xfer_size < SPI_WORD_SIZE_GET(config->operation)) { + LOG_ERR("Max xfer size is %u, word size of %u not allowed", + info->max_xfer_size, SPI_WORD_SIZE_GET(config->operation)); + return -ENOTSUP; + } + /* Word size */ - ctrlr0 |= DW_SPI_CTRLR0_DFS(SPI_WORD_SIZE_GET(config->operation)); + if (info->max_xfer_size == 32) { + ctrlr0 |= DW_SPI_CTRLR0_DFS_32(SPI_WORD_SIZE_GET(config->operation)); + } else { + ctrlr0 |= DW_SPI_CTRLR0_DFS_16(SPI_WORD_SIZE_GET(config->operation)); + } /* Determine how many bytes are required per-frame */ spi->dfs = SPI_WS_TO_DFS(SPI_WORD_SIZE_GET(config->operation)); @@ -597,6 +603,7 @@ COND_CODE_1(IS_EQ(DT_NUM_IRQS(DT_DRV_INST(inst)), 1), \ .config_func = spi_dw_irq_config_##inst, \ .serial_target = DT_INST_PROP(inst, serial_target), \ .fifo_depth = DT_INST_PROP(inst, fifo_depth), \ + .max_xfer_size = DT_INST_PROP(inst, max_xfer_size), \ IF_ENABLED(CONFIG_PINCTRL, (.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(inst),)) \ COND_CODE_1(DT_INST_PROP(inst, aux_reg), \ (.read_func = aux_reg_read, \ diff --git a/drivers/spi/spi_dw.h b/drivers/spi/spi_dw.h index 54724dea0e..54eeaa1ece 100644 --- a/drivers/spi/spi_dw.h +++ b/drivers/spi/spi_dw.h @@ -33,6 +33,7 @@ struct spi_dw_config { spi_dw_config_t config_func; bool serial_target; uint8_t fifo_depth; + uint8_t max_xfer_size; #ifdef CONFIG_PINCTRL const struct pinctrl_dev_config *pcfg; #endif @@ -193,12 +194,6 @@ static int reg_test_bit(uint8_t bit, uint32_t addr, uint32_t off) #define DW_SPI_CTRLR0_DFS_16(__bpw) ((__bpw) - 1) #define DW_SPI_CTRLR0_DFS_32(__bpw) (((__bpw) - 1) << 16) -#if defined(CONFIG_ARC) -#define DW_SPI_CTRLR0_DFS DW_SPI_CTRLR0_DFS_16 -#else -#define DW_SPI_CTRLR0_DFS DW_SPI_CTRLR0_DFS_32 -#endif - /* 0x38 represents the bits 8, 16 and 32. Knowing that 24 is bits 8 and 16 * These are the bits were when you divide by 8, you keep the result as it is. * For all the other ones, 4 to 7, 9 to 15, etc... you need a +1, diff --git a/dts/arc/synopsys/arc_hs4xd.dtsi b/dts/arc/synopsys/arc_hs4xd.dtsi index 18a555cfbd..d6650e651a 100644 --- a/dts/arc/synopsys/arc_hs4xd.dtsi +++ b/dts/arc/synopsys/arc_hs4xd.dtsi @@ -185,6 +185,7 @@ reg = <0xf0020000 0x100>; interrupts = <40 1>; fifo-depth = <32>; + max-xfer-size = <16>; status = "disabled"; }; @@ -195,6 +196,7 @@ reg = <0xf0021000 0x100>; interrupts = <41 1>; fifo-depth = <32>; + max-xfer-size = <16>; status = "disabled"; }; @@ -205,6 +207,7 @@ reg = <0xf0022000 0x100>; interrupts = <42 1>; fifo-depth = <32>; + max-xfer-size = <16>; status = "disabled"; }; }; diff --git a/dts/arc/synopsys/arc_hsdk.dtsi b/dts/arc/synopsys/arc_hsdk.dtsi index bb127594e2..6388db825a 100644 --- a/dts/arc/synopsys/arc_hsdk.dtsi +++ b/dts/arc/synopsys/arc_hsdk.dtsi @@ -185,6 +185,7 @@ reg = <0xf0020000 0x1000>; interrupts = <40 1>; fifo-depth = <32>; + max-xfer-size = <16>; status = "disabled"; }; @@ -195,6 +196,7 @@ reg = <0xf0021000 0x1000>; interrupts = <41 1>; fifo-depth = <32>; + max-xfer-size = <16>; status = "disabled"; }; @@ -205,6 +207,7 @@ reg = <0xf0022000 0x1000>; interrupts = <42 1>; fifo-depth = <32>; + max-xfer-size = <16>; status = "disabled"; }; diff --git a/dts/arc/synopsys/arc_iot.dtsi b/dts/arc/synopsys/arc_iot.dtsi index 7d04321e0e..1c809d1b0f 100644 --- a/dts/arc/synopsys/arc_iot.dtsi +++ b/dts/arc/synopsys/arc_iot.dtsi @@ -233,6 +233,7 @@ #address-cells = <1>; #size-cells = <0>; reg = <0x80010000 0x100>; + max-xfer-size = <16>; clocks = <&sysclk>; interrupts = <70 2>, <71 2>, <72 2>; interrupt-names = "err-int", "rx-avail", "tx-req"; @@ -245,6 +246,7 @@ #address-cells = <1>; #size-cells = <0>; reg = <0x80010100 0x100>; + max-xfer-size = <16>; clocks = <&sysclk>; interrupts = <74 2>, <75 2>, <76 2>; interrupt-names = "err-int", "rx-avail", "tx-req"; @@ -257,6 +259,7 @@ #address-cells = <1>; #size-cells = <0>; reg = <0x80010200 0x100>; + max-xfer-size = <16>; clocks = <&sysclk>; interrupts = <78 2>, <79 2>, <80 2>; interrupt-names = "err-int", "rx-avail", "tx-req"; diff --git a/dts/arc/synopsys/emsdp.dtsi b/dts/arc/synopsys/emsdp.dtsi index 2db3d3422f..1d7c4cf238 100644 --- a/dts/arc/synopsys/emsdp.dtsi +++ b/dts/arc/synopsys/emsdp.dtsi @@ -95,6 +95,7 @@ reg = <0xf0008000 0x1000>; clocks = <&spiclk>; fifo-depth = <32>; + max-xfer-size = <16>; interrupt-parent = <&intc>; #address-cells = <1>; #size-cells = <0>; @@ -112,6 +113,7 @@ reg = <0xf1000000 0x1000>; clocks = <&spiclk>; fifo-depth = <32>; + max-xfer-size = <16>; interrupt-parent = <&intc>; #address-cells = <1>; #size-cells = <0>; @@ -137,6 +139,7 @@ interrupt-parent = <&intc>; aux-reg; fifo-depth = <16>; + max-xfer-size = <16>; }; /* DFSS-SPI1 */ @@ -151,6 +154,7 @@ interrupt-parent = <&intc>; aux-reg; fifo-depth = <16>; + max-xfer-size = <16>; }; }; }; diff --git a/dts/arc/synopsys/emsk.dtsi b/dts/arc/synopsys/emsk.dtsi index a701d2412e..117421c228 100644 --- a/dts/arc/synopsys/emsk.dtsi +++ b/dts/arc/synopsys/emsk.dtsi @@ -148,6 +148,7 @@ clocks = <&sysclk>; interrupt-parent = <&intc>; fifo-depth = <32>; + max-xfer-size = <16>; #address-cells = <1>; #size-cells = <0>; @@ -159,6 +160,7 @@ clocks = <&sysclk>; interrupt-parent = <&intc>; fifo-depth = <32>; + max-xfer-size = <16>; #address-cells = <1>; #size-cells = <0>; diff --git a/dts/arm/intel_socfpga_std/socfpga.dtsi b/dts/arm/intel_socfpga_std/socfpga.dtsi index e2e852a479..7e1f37267d 100644 --- a/dts/arm/intel_socfpga_std/socfpga.dtsi +++ b/dts/arm/intel_socfpga_std/socfpga.dtsi @@ -244,6 +244,7 @@ #size-cells = <0>; reg = <0xfff00000 0x1000>; fifo-depth = <256>; + max-xfer-size = <32>; interrupts = <0 154 4 IRQ_DEFAULT_PRIORITY>; clock-frequency = <200000000>; status = "okay"; @@ -255,6 +256,7 @@ #size-cells = <0>; reg = <0xfff01000 0x1000>; fifo-depth = <256>; + max-xfer-size = <32>; interrupts = <0 155 4 IRQ_DEFAULT_PRIORITY>; clock-frequency = <200000000>; status = "disabled"; diff --git a/dts/bindings/spi/snps,designware-spi.yaml b/dts/bindings/spi/snps,designware-spi.yaml index 822cb8d508..01073f8d00 100644 --- a/dts/bindings/spi/snps,designware-spi.yaml +++ b/dts/bindings/spi/snps,designware-spi.yaml @@ -34,3 +34,13 @@ properties: True if it is a Serial Target. False if it is a Serial Master. Corresponds to SSI_IS_MASTER of the Designware Synchronous Serial Interface. + + max-xfer-size: + type: int + description: | + Maximum transfer size. Corresponds to SPI_MAX_XFER_SIZE + of the DesignWare Synchronous Serial Interface. Only + values of 16 and 32 are supported. + enum: + - 16 + - 32