From 83c298cd32f779d371fd207816e588be5ba4e949 Mon Sep 17 00:00:00 2001 From: Ryan McClelland Date: Thu, 9 Nov 2023 15:27:21 -0800 Subject: [PATCH] drivers: spi: dw: define max-xfer-size The max size was determined by looking at the ARCH of the cpu. This really comes from the ip configuration when generated. Add `max-xfer-size` property to the devicetree. Signed-off-by: Ryan McClelland --- drivers/spi/spi_dw.c | 17 ++++++++++++----- drivers/spi/spi_dw.h | 7 +------ dts/arc/synopsys/arc_hs4xd.dtsi | 3 +++ dts/arc/synopsys/arc_hsdk.dtsi | 3 +++ dts/arc/synopsys/arc_iot.dtsi | 3 +++ dts/arc/synopsys/emsdp.dtsi | 4 ++++ dts/arc/synopsys/emsk.dtsi | 2 ++ dts/arm/intel_socfpga_std/socfpga.dtsi | 2 ++ dts/bindings/spi/snps,designware-spi.yaml | 10 ++++++++++ 9 files changed, 40 insertions(+), 11 deletions(-) diff --git a/drivers/spi/spi_dw.c b/drivers/spi/spi_dw.c index 98904fbc267..7126cac00a8 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 54724dea0e7..54eeaa1ece1 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 18a555cfbd4..d6650e651a9 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 bb127594e2e..6388db825a0 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 7d04321e0ee..1c809d1b0f8 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 2db3d3422f4..1d7c4cf238c 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 a701d2412ee..117421c228f 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 e2e852a4791..7e1f37267d5 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 822cb8d508b..01073f8d003 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