diff --git a/boards/arm/gd32e103v_eval/gd32e103v_eval.yaml b/boards/arm/gd32e103v_eval/gd32e103v_eval.yaml index fc4d2e0354186..e52c8c18d39cb 100644 --- a/boards/arm/gd32e103v_eval/gd32e103v_eval.yaml +++ b/boards/arm/gd32e103v_eval/gd32e103v_eval.yaml @@ -14,3 +14,4 @@ toolchain: supported: - counter - watchdog + - dma diff --git a/boards/arm/gd32e507v_start/gd32e507v_start.yaml b/boards/arm/gd32e507v_start/gd32e507v_start.yaml index 52d2b4a922f6c..8801a73c6c60a 100644 --- a/boards/arm/gd32e507v_start/gd32e507v_start.yaml +++ b/boards/arm/gd32e507v_start/gd32e507v_start.yaml @@ -16,3 +16,4 @@ supported: - gpio - watchdog - counter + - dma diff --git a/boards/arm/gd32f350r_eval/gd32f350r_eval.yaml b/boards/arm/gd32f350r_eval/gd32f350r_eval.yaml index 002ecd59d29c8..b8c508f98ae53 100644 --- a/boards/arm/gd32f350r_eval/gd32f350r_eval.yaml +++ b/boards/arm/gd32f350r_eval/gd32f350r_eval.yaml @@ -13,3 +13,4 @@ toolchain: - xtools supported: - watchdog + - dma diff --git a/boards/arm/gd32f403z_eval/gd32f403z_eval.yaml b/boards/arm/gd32f403z_eval/gd32f403z_eval.yaml index 75bc4cf14c3cc..1dc415b1239da 100644 --- a/boards/arm/gd32f403z_eval/gd32f403z_eval.yaml +++ b/boards/arm/gd32f403z_eval/gd32f403z_eval.yaml @@ -15,3 +15,4 @@ supported: - counter - pwm - watchdog + - dma diff --git a/boards/arm/gd32f407v_start/gd32f407v_start.yaml b/boards/arm/gd32f407v_start/gd32f407v_start.yaml index ff8dc9bb0ec6d..09539d23ea85c 100644 --- a/boards/arm/gd32f407v_start/gd32f407v_start.yaml +++ b/boards/arm/gd32f407v_start/gd32f407v_start.yaml @@ -15,3 +15,4 @@ supported: - pwm - gpio - counter + - dma diff --git a/boards/arm/gd32f450i_eval/gd32f450i_eval.yaml b/boards/arm/gd32f450i_eval/gd32f450i_eval.yaml index f68beb97d2a33..4ade0537fa686 100644 --- a/boards/arm/gd32f450i_eval/gd32f450i_eval.yaml +++ b/boards/arm/gd32f450i_eval/gd32f450i_eval.yaml @@ -15,3 +15,4 @@ supported: - pwm - watchdog - counter + - dma diff --git a/boards/arm/gd32f450v_start/gd32f450v_start.yaml b/boards/arm/gd32f450v_start/gd32f450v_start.yaml index 2555cb2cf4c23..bfaaa1ed2f91c 100644 --- a/boards/arm/gd32f450v_start/gd32f450v_start.yaml +++ b/boards/arm/gd32f450v_start/gd32f450v_start.yaml @@ -15,3 +15,4 @@ supported: - pwm - gpio - counter + - dma diff --git a/boards/arm/gd32f450z_eval/gd32f450z_eval.yaml b/boards/arm/gd32f450z_eval/gd32f450z_eval.yaml index 45eeca694a24b..f8091bd1b33ab 100644 --- a/boards/arm/gd32f450z_eval/gd32f450z_eval.yaml +++ b/boards/arm/gd32f450z_eval/gd32f450z_eval.yaml @@ -20,3 +20,4 @@ supported: - spi - uart - watchdog + - dma diff --git a/boards/arm/gd32f470i_eval/gd32f470i_eval.yaml b/boards/arm/gd32f470i_eval/gd32f470i_eval.yaml index 4a6a3da50971e..634e95ce864d6 100644 --- a/boards/arm/gd32f470i_eval/gd32f470i_eval.yaml +++ b/boards/arm/gd32f470i_eval/gd32f470i_eval.yaml @@ -20,3 +20,4 @@ supported: - spi - uart - watchdog + - dma diff --git a/boards/riscv/gd32vf103c_starter/gd32vf103c_starter.yaml b/boards/riscv/gd32vf103c_starter/gd32vf103c_starter.yaml index b88dab1712df0..aca35195f729b 100644 --- a/boards/riscv/gd32vf103c_starter/gd32vf103c_starter.yaml +++ b/boards/riscv/gd32vf103c_starter/gd32vf103c_starter.yaml @@ -14,3 +14,4 @@ supported: - gpio - pwm - watchdog + - dma diff --git a/boards/riscv/gd32vf103v_eval/gd32vf103v_eval.yaml b/boards/riscv/gd32vf103v_eval/gd32vf103v_eval.yaml index 101557c1cbd81..10a8c42aedd05 100644 --- a/boards/riscv/gd32vf103v_eval/gd32vf103v_eval.yaml +++ b/boards/riscv/gd32vf103v_eval/gd32vf103v_eval.yaml @@ -14,3 +14,4 @@ supported: - gpio - pwm - watchdog + - dma diff --git a/boards/riscv/longan_nano/longan_nano.yaml b/boards/riscv/longan_nano/longan_nano.yaml index 60dbda2bc8488..15a8e8163dbf6 100644 --- a/boards/riscv/longan_nano/longan_nano.yaml +++ b/boards/riscv/longan_nano/longan_nano.yaml @@ -9,3 +9,4 @@ flash: 128 ram: 32 supported: - watchdog + - dma diff --git a/boards/riscv/longan_nano/longan_nano_lite.yaml b/boards/riscv/longan_nano/longan_nano_lite.yaml index ab36fb4ca495f..b7a4244e963cb 100644 --- a/boards/riscv/longan_nano/longan_nano_lite.yaml +++ b/boards/riscv/longan_nano/longan_nano_lite.yaml @@ -9,3 +9,4 @@ flash: 64 ram: 20 supported: - watchdog + - dma diff --git a/drivers/dma/Kconfig.gd32 b/drivers/dma/Kconfig.gd32 index a095e1a33f57e..b5659459c2504 100644 --- a/drivers/dma/Kconfig.gd32 +++ b/drivers/dma/Kconfig.gd32 @@ -4,7 +4,7 @@ config DMA_GD32 bool "Gigadevice GD32 DMA driver" default y - depends on DT_HAS_GD_GD32_DMA_ENABLED + depends on DT_HAS_GD_GD32_DMA_ENABLED || DT_HAS_GD_GD32_DMA_V1_ENABLED select USE_GD32_DMA help DMA driver for GigaDevice GD32 series MCUs. diff --git a/drivers/dma/dma_gd32.c b/drivers/dma/dma_gd32.c index 6724e4e5102ff..a44f233e46164 100644 --- a/drivers/dma/dma_gd32.c +++ b/drivers/dma/dma_gd32.c @@ -4,8 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#define DT_DRV_COMPAT gd_gd32_dma - #include #include #include @@ -16,7 +14,13 @@ #include #include -#ifdef CONFIG_SOC_SERIES_GD32F4XX +#if DT_HAS_COMPAT_STATUS_OKAY(gd_gd32_dma_v1) +#define DT_DRV_COMPAT gd_gd32_dma_v1 +#elif DT_HAS_COMPAT_STATUS_OKAY(gd_gd32_dma) +#define DT_DRV_COMPAT gd_gd32_dma +#endif + +#if DT_HAS_COMPAT_STATUS_OKAY(gd_gd32_dma_v1) #define CHXCTL_PERIEN_OFFSET ((uint32_t)25U) #define GD32_DMA_CHXCTL_DIR BIT(6) #define GD32_DMA_CHXCTL_M2M BIT(7) @@ -58,7 +62,8 @@ struct dma_gd32_config { uint32_t reg; uint32_t channels; uint16_t clkid; -#ifdef CONFIG_SOC_SERIES_GD32F4XX + bool mem2mem; +#if DT_HAS_COMPAT_STATUS_OKAY(gd_gd32_dma_v1) struct reset_dt_spec reset; #endif void (*irq_configure)(void); @@ -189,7 +194,7 @@ gd32_dma_periph_width_config(uint32_t reg, dma_channel_enum ch, uint32_t pwidth) GD32_DMA_CHCTL(reg, ch) = (ctl & (~DMA_CHXCTL_PWIDTH)) | pwidth; } -#ifdef CONFIG_SOC_SERIES_GD32F4XX +#if DT_HAS_COMPAT_STATUS_OKAY(gd_gd32_dma_v1) static inline void gd32_dma_channel_subperipheral_select(uint32_t reg, dma_channel_enum ch, dma_subperipheral_enum sub_periph) @@ -211,7 +216,7 @@ gd32_dma_periph_address_config(uint32_t reg, dma_channel_enum ch, uint32_t addr) static inline void gd32_dma_memory_address_config(uint32_t reg, dma_channel_enum ch, uint32_t addr) { -#ifdef CONFIG_SOC_SERIES_GD32F4XX +#if DT_HAS_COMPAT_STATUS_OKAY(gd_gd32_dma_v1) DMA_CHM0ADDR(reg, ch) = addr; #else GD32_DMA_CHMADDR(reg, ch) = addr; @@ -233,7 +238,7 @@ gd32_dma_transfer_number_get(uint32_t reg, dma_channel_enum ch) static inline void gd32_dma_interrupt_flag_clear(uint32_t reg, dma_channel_enum ch, uint32_t flag) { -#ifdef CONFIG_SOC_SERIES_GD32F4XX +#if DT_HAS_COMPAT_STATUS_OKAY(gd_gd32_dma_v1) if (ch < DMA_CH4) { DMA_INTC0(reg) |= DMA_FLAG_ADD(flag, ch); } else { @@ -247,7 +252,7 @@ gd32_dma_interrupt_flag_clear(uint32_t reg, dma_channel_enum ch, uint32_t flag) static inline void gd32_dma_flag_clear(uint32_t reg, dma_channel_enum ch, uint32_t flag) { -#ifdef CONFIG_SOC_SERIES_GD32F4XX +#if DT_HAS_COMPAT_STATUS_OKAY(gd_gd32_dma_v1) if (ch < DMA_CH4) { DMA_INTC0(reg) |= DMA_FLAG_ADD(flag, ch); } else { @@ -261,7 +266,7 @@ gd32_dma_flag_clear(uint32_t reg, dma_channel_enum ch, uint32_t flag) static inline uint32_t gd32_dma_interrupt_flag_get(uint32_t reg, dma_channel_enum ch, uint32_t flag) { -#ifdef CONFIG_SOC_SERIES_GD32F4XX +#if DT_HAS_COMPAT_STATUS_OKAY(gd_gd32_dma_v1) if (ch < DMA_CH4) { return (DMA_INTF0(reg) & DMA_FLAG_ADD(flag, ch)); } else { @@ -279,7 +284,7 @@ static inline void gd32_dma_deinit(uint32_t reg, dma_channel_enum ch) GD32_DMA_CHCTL(reg, ch) = DMA_CHCTL_RESET_VALUE; GD32_DMA_CHCNT(reg, ch) = DMA_CHCNT_RESET_VALUE; GD32_DMA_CHPADDR(reg, ch) = DMA_CHPADDR_RESET_VALUE; -#ifdef CONFIG_SOC_SERIES_GD32F4XX +#if DT_HAS_COMPAT_STATUS_OKAY(gd_gd32_dma_v1) DMA_CHM0ADDR(reg, ch) = DMA_CHMADDR_RESET_VALUE; DMA_CHFCTL(reg, ch) = DMA_CHFCTL_RESET_VALUE; if (ch < DMA_CH4) { @@ -403,10 +408,15 @@ static int dma_gd32_config(const struct device *dev, uint32_t channel, return -ENOTSUP; } -#ifdef CONFIG_SOC_SERIES_GD32F4XX - if (dma_cfg->linked_channel > 0xF) { - LOG_ERR("linked_channel must be <7 (%" PRIu32 ")", - dma_cfg->linked_channel); + if (dma_cfg->channel_direction == MEMORY_TO_MEMORY && !cfg->mem2mem) { + LOG_ERR("not supporting MEMORY_TO_MEMORY"); + return -ENOTSUP; + } + +#if DT_HAS_COMPAT_STATUS_OKAY(gd_gd32_dma_v1) + if (dma_cfg->dma_slot > 0xF) { + LOG_ERR("dma_slot must be <7 (%" PRIu32 ")", + dma_cfg->dma_slot); return -EINVAL; } #endif @@ -462,10 +472,10 @@ static int dma_gd32_config(const struct device *dev, uint32_t channel, gd32_dma_periph_width_config(cfg->reg, channel, dma_gd32_periph_width(periph_cfg->width)); gd32_dma_circulation_disable(cfg->reg, channel); -#ifdef CONFIG_SOC_SERIES_GD32F4XX +#if DT_HAS_COMPAT_STATUS_OKAY(gd_gd32_dma_v1) if (dma_cfg->channel_direction != MEMORY_TO_MEMORY) { gd32_dma_channel_subperipheral_select(cfg->reg, channel, - dma_cfg->linked_channel); + dma_cfg->dma_slot); } #endif @@ -594,7 +604,7 @@ static int dma_gd32_init(const struct device *dev) (void)clock_control_on(GD32_CLOCK_CONTROLLER, (clock_control_subsys_t *)&cfg->clkid); -#ifdef CONFIG_SOC_SERIES_GD32F4XX +#if DT_HAS_COMPAT_STATUS_OKAY(gd_gd32_dma_v1) (void)reset_line_toggle_dt(&cfg->reset); #endif @@ -665,10 +675,11 @@ static const struct dma_driver_api dma_gd32_driver_api = { } \ static const struct dma_gd32_config dma_gd32##inst##_config = { \ .reg = DT_INST_REG_ADDR(inst), \ + .channels = DT_INST_PROP(inst, dma_channels), \ .clkid = DT_INST_CLOCKS_CELL(inst, id), \ - IF_ENABLED(CONFIG_SOC_SERIES_GD32F4XX, \ + .mem2mem = DT_INST_PROP(inst, gd_mem2mem), \ + IF_ENABLED(DT_HAS_COMPAT_STATUS_OKAY(gd_gd32_dma_v1), \ (.reset = RESET_DT_SPEC_INST_GET(inst),)) \ - .channels = DT_INST_PROP(inst, dma_channels), \ .irq_configure = dma_gd32##inst##_irq_configure, \ }; \ \ diff --git a/dts/arm/gigadevice/gd32e10x/gd32e10x.dtsi b/dts/arm/gigadevice/gd32e10x/gd32e10x.dtsi index 0d6748c0a90de..45da7efadcb5b 100644 --- a/dts/arm/gigadevice/gd32e10x/gd32e10x.dtsi +++ b/dts/arm/gigadevice/gd32e10x/gd32e10x.dtsi @@ -472,7 +472,7 @@ <15 0>, <16 0>, <17 0>; clocks = <&cctl GD32_CLOCK_DMA0>; dma-channels = <7>; - #dma-cells = <1>; + #dma-cells = <2>; status = "disabled"; }; @@ -483,7 +483,7 @@ <60 0>; clocks = <&cctl GD32_CLOCK_DMA1>; dma-channels = <5>; - #dma-cells = <1>; + #dma-cells = <2>; status = "disabled"; }; diff --git a/dts/arm/gigadevice/gd32e50x/gd32e50x.dtsi b/dts/arm/gigadevice/gd32e50x/gd32e50x.dtsi index ec1e49b293dca..e073dd8ff4e37 100644 --- a/dts/arm/gigadevice/gd32e50x/gd32e50x.dtsi +++ b/dts/arm/gigadevice/gd32e50x/gd32e50x.dtsi @@ -411,7 +411,8 @@ <15 0>, <16 0>, <17 0>; clocks = <&cctl GD32_CLOCK_DMA0>; dma-channels = <7>; - #dma-cells = <1>; + gd,mem2mem; + #dma-cells = <2>; status = "disabled"; }; @@ -422,7 +423,8 @@ <60 0>; clocks = <&cctl GD32_CLOCK_DMA1>; dma-channels = <5>; - #dma-cells = <1>; + gd,mem2mem; + #dma-cells = <2>; status = "disabled"; }; }; diff --git a/dts/arm/gigadevice/gd32f3x0/gd32f3x0.dtsi b/dts/arm/gigadevice/gd32f3x0/gd32f3x0.dtsi index f90179b711c75..e8d35968d87e2 100644 --- a/dts/arm/gigadevice/gd32f3x0/gd32f3x0.dtsi +++ b/dts/arm/gigadevice/gd32f3x0/gd32f3x0.dtsi @@ -97,7 +97,7 @@ interrupts = <9 0>, <10 0>, <11 0>, <48 0>; clocks = <&cctl GD32_CLOCK_DMA>; dma-channels = <7>; - #dma-cells = <1>; + #dma-cells = <2>; status = "disabled"; }; diff --git a/dts/arm/gigadevice/gd32f403/gd32f403.dtsi b/dts/arm/gigadevice/gd32f403/gd32f403.dtsi index a253057c2125f..b1440eb541d79 100644 --- a/dts/arm/gigadevice/gd32f403/gd32f403.dtsi +++ b/dts/arm/gigadevice/gd32f403/gd32f403.dtsi @@ -496,7 +496,8 @@ <15 0>, <16 0>, <17 0>; clocks = <&cctl GD32_CLOCK_DMA0>; dma-channels = <7>; - #dma-cells = <1>; + gd,mem2mem; + #dma-cells = <2>; status = "disabled"; }; @@ -507,7 +508,8 @@ <60 0>; clocks = <&cctl GD32_CLOCK_DMA1>; dma-channels = <5>; - #dma-cells = <1>; + gd,mem2mem; + #dma-cells = <2>; status = "disabled"; }; }; diff --git a/dts/arm/gigadevice/gd32f4xx/gd32f4xx.dtsi b/dts/arm/gigadevice/gd32f4xx/gd32f4xx.dtsi index 259dffbe20728..4e35c5207f570 100644 --- a/dts/arm/gigadevice/gd32f4xx/gd32f4xx.dtsi +++ b/dts/arm/gigadevice/gd32f4xx/gd32f4xx.dtsi @@ -618,26 +618,28 @@ }; dma0: dma@40026000 { - compatible = "gd,gd32-dma"; + compatible = "gd,gd32-dma-v1"; reg = <0x40026000 0x400>; interrupts = <11 0>, <12 0>, <13 0>, <14 0>, <15 0>, <16 0>, <17 0>, <47 0>; clocks = <&cctl GD32_CLOCK_DMA0>; resets = <&rctl GD32_RESET_DMA0>; dma-channels = <8>; - #dma-cells = <1>; + gd,mem2mem; + #dma-cells = <4>; status = "disabled"; }; dma1: dma@40026400 { - compatible = "gd,gd32-dma"; + compatible = "gd,gd32-dma-v1"; reg = <0x40026400 0x400>; interrupts = <56 0>, <57 0>, <58 0>, <59 0>, <60 0>, <68 0>, <69 0>, <70 0>; clocks = <&cctl GD32_CLOCK_DMA1>; resets = <&rctl GD32_RESET_DMA1>; dma-channels = <8>; - #dma-cells = <1>; + gd,mem2mem; + #dma-cells = <4>; status = "disabled"; }; }; diff --git a/dts/bindings/dma/gd,gd32-dma-base.yaml b/dts/bindings/dma/gd,gd32-dma-base.yaml new file mode 100644 index 0000000000000..36c12a4505d1c --- /dev/null +++ b/dts/bindings/dma/gd,gd32-dma-base.yaml @@ -0,0 +1,21 @@ +# Copyright (c) 2022, TOKITA Hiroshi +# SPDX-License-Identifier: Apache-2.0 + +include: dma-controller.yaml + +properties: + reg: + required: true + + interrupts: + required: true + + dma-channels: + required: true + + clocks: + required: true + + gd,mem2mem: + type: boolean + description: The DMA controller supporting memory to memory transfer diff --git a/dts/bindings/dma/gd,gd32-dma-v1.yaml b/dts/bindings/dma/gd,gd32-dma-v1.yaml new file mode 100644 index 0000000000000..6374f1671469f --- /dev/null +++ b/dts/bindings/dma/gd,gd32-dma-v1.yaml @@ -0,0 +1,98 @@ +# Copyright (c) 2022, TOKITA Hiroshi +# SPDX-License-Identifier: Apache-2.0 + +description: | + GD32 DMA controller with FIFO + + channel: Select channel for data transmitting + + slot: Select peripheral to connect DMA + + config: A 32bit mask specifying the DMA channel configuration + - bit 6-7: Direction (see dma.h) + - 0x0: MEMORY to MEMORY + - 0x1: MEMORY to PERIPH + - 0x2: PERIPH to MEMORY + - 0x3: reserved for PERIPH to PERIPH + + - bit 9: Peripheral address increase + - 0x0: no address increment between transfers + - 0x1: increment address between transfers + + - bit 10: Memory address increase + - 0x0: no address increase between transfers + - 0x1: increase address between transfers + + - bit 11-12: Peripheral data width + - 0x0: 8 bits + - 0x1: 16 bits + - 0x2: 32 bits + - 0x3: reserved + + - bit 13-14: Memory data width + - 0x0: 8 bits + - 0x1: 16 bits + - 0x2: 32 bits + - 0x3: reserved + + - bit 15: Peripheral Increment Offset Size + - 0x0: offset size is linked to the peripheral bus width + - 0x1: offset size is fixed to 4 (32-bit alignment) + + - bit 16-17: Priority + - 0x0: low + - 0x1: medium + - 0x2: high + - 0x3: very high + + fifo-threshold: A 32bit bitfield value specifying FIFO threshold + - bit 0-1: Depth of DMA's FIFO used by burst-transfer. + - 0x0: 1 word + - 0x1: 2 word + - 0x2: 3 word + - 0x3: 4 word + + + Example of devicetree configuration + + &spi0 { + status = "okay"; + pinctrl-0 = <&spi0_default>; + pinctrl-names = "default"; + cs-gpios = <&gpioa 4 GPIO_ACTIVE_LOW>; + + dmas = <&dma1 0 3 0 0>, <&dma1 5 3 GD32_DMA_PRIORITY_HIGH 0> + dma-names = "rx", "tx"; + }; + + "spi0" uses dma1 for transmitting and receiving in the example. + Each is named "rx" and "tx". + The first cell assigns channel 0 to receive and channel 5 to transmit. + The second cell is slot. Both channels select 3. + What the slot number '3' means depends on the DMA controller and channel. + See the Hardware manual. + The config that places on the third can take various configs. + But the setting used depends on each driver implementation. + Set the priority for the transmitting channel as HIGH, LOW(the default) for receive channel. + The fifo-threshold cell that places the fourth is configuring FIFO threshold. + The behavior of burst transfer determines by data-width in the config cell, + burst-length in the dma_config struct, and fifo-threshold. + A single burst transfer transfers [ (4 * fifo-threshold) ] bytes using with DMA's FIFO. + Where (data-width * burst-length) must be multiple numbers of burst transfer size. + For example, In the case of data-width is 'byte' and burst-length is 8. + If the fifo-threshold is a 2-word case, it runs one burst transfer to transfer 8 bytes. + Or the fifo-threshold is a 4-word case, runs two times burst transfer to transferring 8 bytes each time. + +compatible: "gd,gd32-dma-v1" + +include: [ "reset-device.yaml", "gd,gd32-dma-base.yaml" ] + +properties: + "#dma-cells": + const: 4 + +dma-cells: + - channel + - slot + - config + - fifo-threshold diff --git a/dts/bindings/dma/gd,gd32-dma.yaml b/dts/bindings/dma/gd,gd32-dma.yaml index 8ed7bf7d0ba3a..bc9eb3eb043c0 100644 --- a/dts/bindings/dma/gd,gd32-dma.yaml +++ b/dts/bindings/dma/gd,gd32-dma.yaml @@ -4,25 +4,72 @@ description: | GD32 DMA controller -compatible: "gd,gd32-dma" + channel: Select channel for data transmitting -include: [dma-controller.yaml, reset-device.yaml] + config: A 32bit mask specifying the DMA channel configuration + - bit 6-7: Direction (see dma.h) + - 0x0: MEMORY to MEMORY + - 0x1: MEMORY to PERIPH + - 0x2: PERIPH to MEMORY + - 0x3: reserved for PERIPH to PERIPH -properties: - reg: - required: true + - bit 9: Peripheral address increase + - 0x0: no address increment between transfers + - 0x1: increment address between transfers + + - bit 10: Memory address increase + - 0x0: no address increase between transfers + - 0x1: increase address between transfers + + - bit 11-12: Peripheral data width + - 0x0: 8 bits + - 0x1: 16 bits + - 0x2: 32 bits + - 0x3: reserved + + - bit 13-14: Memory data width + - 0x0: 8 bits + - 0x1: 16 bits + - 0x2: 32 bits + - 0x3: reserved + + - bit 15: Peripheral Increment Offset Size + - 0x0: offset size is linked to the peripheral bus width + - 0x1: offset size is fixed to 4 (32-bit alignment) - interrupts: - required: true + - bit 16-17: Priority + - 0x0: low + - 0x1: medium + - 0x2: high + - 0x3: very high - dma-channels: - required: true + Example of devicetree configuration - clocks: - required: true + &spi0 { + status = "okay"; + pinctrl-0 = <&spi0_default>; + pinctrl-names = "default"; + cs-gpios = <&gpioa 4 GPIO_ACTIVE_LOW>; + dmas = <&dma0 3 0>, <&dma0 5 GD32_DMA_PRIORITY_HIGH>; + dma-names = "rx", "tx"; + }; + + "spi0" uses dma0 for transmitting and receiving in the example. + Each is named "rx" and "tx". + The channel cell assigns channel 3 to receive and channel 5 to transmit. + The config cell can take various configs. + But the setting used depends on each driver implementation. + Set the priority for the transmitting channel as HIGH, LOW(the default) for receive channel. + +compatible: "gd,gd32-dma" + +include: [ "gd,gd32-dma-base.yaml" ] + +properties: "#dma-cells": - const: 1 + const: 2 dma-cells: - channel + - config diff --git a/dts/riscv/gigadevice/gd32vf103.dtsi b/dts/riscv/gigadevice/gd32vf103.dtsi index a2f679132d7e6..1b1401bda1d92 100644 --- a/dts/riscv/gigadevice/gd32vf103.dtsi +++ b/dts/riscv/gigadevice/gd32vf103.dtsi @@ -392,7 +392,8 @@ <34 0>, <35 0>, <36 0>; clocks = <&cctl GD32_CLOCK_DMA0>; dma-channels = <7>; - #dma-cells = <1>; + gd,mem2mem; + #dma-cells = <2>; status = "disabled"; }; @@ -403,7 +404,8 @@ <79 0>; clocks = <&cctl GD32_CLOCK_DMA0>; dma-channels = <5>; - #dma-cells = <1>; + gd,mem2mem; + #dma-cells = <2>; status = "disabled"; }; }; diff --git a/include/zephyr/drivers/dma/dma_gd32.h b/include/zephyr/drivers/dma/dma_gd32.h new file mode 100644 index 0000000000000..70cd5f3d05ae2 --- /dev/null +++ b/include/zephyr/drivers/dma/dma_gd32.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2022 TOKITA Hiroshi + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_DMA_GD32_H_ +#define ZEPHYR_INCLUDE_DRIVERS_DMA_GD32_H_ + +#define GD32_DMA_CONFIG_DIRECTION(config) ((config >> 6) & 0x3) +#define GD32_DMA_CONFIG_PERIPH_ADDR_INC(config) ((config >> 9) & 0x1) +#define GD32_DMA_CONFIG_MEMORY_ADDR_INC(config) ((config >> 10) & 0x1) +#define GD32_DMA_CONFIG_PERIPH_WIDTH(config) ((config >> 11) & 0x3) +#define GD32_DMA_CONFIG_MEMORY_WIDTH(config) ((config >> 13) & 0x3) +#define GD32_DMA_CONFIG_PERIPHERAL_INC_FIXED(config) ((config >> 15) & 0x1) +#define GD32_DMA_CONFIG_PRIORITY(config) ((config >> 16) & 0x3) + +#define GD32_DMA_FEATURES_FIFO_THRESHOLD(threshold) (threshold & 0x3) + +#endif /* ZEPHYR_INCLUDE_DRIVERS_DMA_GD32_H_ */ diff --git a/include/zephyr/dt-bindings/dma/gd32_dma.h b/include/zephyr/dt-bindings/dma/gd32_dma.h new file mode 100644 index 0000000000000..0f71fa1e7e42d --- /dev/null +++ b/include/zephyr/dt-bindings/dma/gd32_dma.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2022 TOKITA Hiroshi + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_GD32_DMA_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_GD32_DMA_H_ + +/* macros for channel-cfg */ + +/* direction defined on bits 6-7 */ +#define GD32_DMA_CH_CFG_DIRECTION(val) ((val & 0x3) << 6) +#define GD32_DMA_MEMORY_TO_MEMORY GD32_DMA_CH_CFG_DIRECTION(0) +#define GD32_DMA_MEMORY_TO_PERIPH GD32_DMA_CH_CFG_DIRECTION(1) +#define GD32_DMA_PERIPH_TO_MEMORY GD32_DMA_CH_CFG_DIRECTION(2) + +/* periph increase defined on bit 9 as true/false */ +#define GD32_DMA_CH_CFG_PERIPH_ADDR_INC(val) ((val & 0x1) << 9) +#define GD32_DMA_NO_PERIPH_ADDR_INC GD32_DMA_CH_CFG_PERIPH_ADDR_INC(0) +#define GD32_DMA_PERIPH_ADDR_INC GD32_DMA_CH_CFG_PERIPH_ADDR_INC(1) + +/* memory increase defined on bit 10 as true/false */ +#define GD32_DMA_CH_CFG_MEMORY_ADDR_INC(val) ((val & 0x1) << 10) +#define GD32_DMA_NO_MEMORY_ADDR_INC GD32_DMA_CH_CFG_MEMORY_ADDR_INC(0) +#define GD32_DMA_MEMORY_ADDR_INC GD32_DMA_CH_CFG_MEMORY_ADDR_INC(1) + +/* periph data size defined on bits 11-12 */ +#define GD32_DMA_CH_CFG_PERIPH_WIDTH(val) ((val & 0x3) << 11) +#define GD32_DMA_PERIPH_WIDTH_8BIT GD32_DMA_CH_CFG_PERIPH_WIDTH(0) +#define GD32_DMA_PERIPH_WIDTH_16BIT GD32_DMA_CH_CFG_PERIPH_WIDTH(1) +#define GD32_DMA_PERIPH_WIDTH_32BIT GD32_DMA_CH_CFG_PERIPH_WIDTH(2) + +/* memory data size defined on bits 13-14 */ +#define GD32_DMA_CH_CFG_MEMORY_WIDTH(val) ((val & 0x3) << 13) +#define GD32_DMA_MEMORY_WIDTH_8BIT GD32_DMA_CH_CFG_PERIPH_WIDTH(0) +#define GD32_DMA_MEMORY_WIDTH_16BIT GD32_DMA_CH_CFG_PERIPH_WIDTH(1) +#define GD32_DMA_MEMORY_WIDTH_32BIT GD32_DMA_CH_CFG_PERIPH_WIDTH(2) + +/* priority increment offset defined on bit 15 */ +#define GD32_DMA_CH_CFG_PERIPH_INC_FIXED(val) ((val & 0x1) << 15) + +/* priority defined on bits 16-17 as 0, 1, 2, 3 */ +#define GD32_DMA_CH_CFG_PRIORITY(val) ((val & 0x3) << 16) +#define GD32_DMA_PRIORITY_LOW GD32_DMA_CH_CFG_PRIORITY(0) +#define GD32_DMA_PRIORITY_MEDIUM GD32_DMA_CH_CFG_PRIORITY(1) +#define GD32_DMA_PRIORITY_HIGH GD32_DMA_CH_CFG_PRIORITY(2) +#define GD32_DMA_PRIORITY_VERY_HIGH GD32_DMA_CH_CFG_PRIORITY(3) + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_GD32_DMA_H_ */ diff --git a/tests/drivers/dma/loop_transfer/boards/gd32e507v_start.overlay b/tests/drivers/dma/loop_transfer/boards/gd32e507v_start.overlay new file mode 100644 index 0000000000000..f9de4d577ad6a --- /dev/null +++ b/tests/drivers/dma/loop_transfer/boards/gd32e507v_start.overlay @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2022 Tokita, Hiroshi + * + * SPDX-License-Identifier: Apache-2.0 + */ + +test_dma: &dma0 { + status = "okay"; +}; diff --git a/tests/drivers/dma/loop_transfer/boards/gd32e507z_eval.overlay b/tests/drivers/dma/loop_transfer/boards/gd32e507z_eval.overlay new file mode 100644 index 0000000000000..f9de4d577ad6a --- /dev/null +++ b/tests/drivers/dma/loop_transfer/boards/gd32e507z_eval.overlay @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2022 Tokita, Hiroshi + * + * SPDX-License-Identifier: Apache-2.0 + */ + +test_dma: &dma0 { + status = "okay"; +}; diff --git a/tests/drivers/dma/loop_transfer/boards/gd32f350r_eval.overlay b/tests/drivers/dma/loop_transfer/boards/gd32f350r_eval.overlay index f9de4d577ad6a..b8449ec7d11dc 100644 --- a/tests/drivers/dma/loop_transfer/boards/gd32f350r_eval.overlay +++ b/tests/drivers/dma/loop_transfer/boards/gd32f350r_eval.overlay @@ -4,6 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -test_dma: &dma0 { +test_dma: &dma { status = "okay"; }; diff --git a/tests/drivers/dma/loop_transfer/boards/gd32f407v_start.overlay b/tests/drivers/dma/loop_transfer/boards/gd32f407v_start.overlay new file mode 100644 index 0000000000000..013d737700297 --- /dev/null +++ b/tests/drivers/dma/loop_transfer/boards/gd32f407v_start.overlay @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2022 Tokita, Hiroshi + * + * SPDX-License-Identifier: Apache-2.0 + */ + +test_dma: &dma1 { + status = "okay"; +}; diff --git a/tests/drivers/dma/loop_transfer/boards/gd32f450v_start.overlay b/tests/drivers/dma/loop_transfer/boards/gd32f450v_start.overlay new file mode 100644 index 0000000000000..013d737700297 --- /dev/null +++ b/tests/drivers/dma/loop_transfer/boards/gd32f450v_start.overlay @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2022 Tokita, Hiroshi + * + * SPDX-License-Identifier: Apache-2.0 + */ + +test_dma: &dma1 { + status = "okay"; +}; diff --git a/tests/drivers/dma/loop_transfer/boards/gd32vf103c_starter.overlay b/tests/drivers/dma/loop_transfer/boards/gd32vf103c_starter.overlay new file mode 100644 index 0000000000000..f9de4d577ad6a --- /dev/null +++ b/tests/drivers/dma/loop_transfer/boards/gd32vf103c_starter.overlay @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2022 Tokita, Hiroshi + * + * SPDX-License-Identifier: Apache-2.0 + */ + +test_dma: &dma0 { + status = "okay"; +}; diff --git a/tests/drivers/dma/loop_transfer/boards/longan_nano_lite.overlay b/tests/drivers/dma/loop_transfer/boards/longan_nano_lite.overlay new file mode 100644 index 0000000000000..f9de4d577ad6a --- /dev/null +++ b/tests/drivers/dma/loop_transfer/boards/longan_nano_lite.overlay @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2022 Tokita, Hiroshi + * + * SPDX-License-Identifier: Apache-2.0 + */ + +test_dma: &dma0 { + status = "okay"; +};