dts: bindings: dma: gd32: split gd,gd32-dma-v1 for support F4xx feature

Split gd,gd32-dma-v1 from gd,gd32-dma to support F4xx specific features.

Signed-off-by: TOKITA Hiroshi <tokita.hiroshi@gmail.com>
This commit is contained in:
TOKITA Hiroshi 2022-12-08 18:41:18 +09:00 committed by Carles Cufí
parent 498ef65242
commit 1690326268
4 changed files with 121 additions and 19 deletions

View file

@ -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.

View file

@ -4,8 +4,6 @@
* SPDX-License-Identifier: Apache-2.0
*/
#define DT_DRV_COMPAT gd_gd32_dma
#include <zephyr/device.h>
#include <zephyr/drivers/clock_control.h>
#include <zephyr/drivers/clock_control/gd32.h>
@ -16,7 +14,13 @@
#include <gd32_dma.h>
#include <zephyr/irq.h>
#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)
@ -59,7 +63,7 @@ struct dma_gd32_config {
uint32_t channels;
uint16_t clkid;
bool mem2mem;
#ifdef CONFIG_SOC_SERIES_GD32F4XX
#if DT_HAS_COMPAT_STATUS_OKAY(gd_gd32_dma_v1)
struct reset_dt_spec reset;
#endif
void (*irq_configure)(void);
@ -190,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)
@ -212,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;
@ -234,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 {
@ -248,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 {
@ -262,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 {
@ -280,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) {
@ -409,7 +413,7 @@ static int dma_gd32_config(const struct device *dev, uint32_t channel,
return -ENOTSUP;
}
#ifdef CONFIG_SOC_SERIES_GD32F4XX
#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);
@ -468,7 +472,7 @@ 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->dma_slot);
@ -600,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
@ -674,7 +678,7 @@ static const struct dma_driver_api dma_gd32_driver_api = {
.channels = DT_INST_PROP(inst, dma_channels), \
.clkid = DT_INST_CLOCKS_CELL(inst, id), \
.mem2mem = DT_INST_PROP(inst, gd_mem2mem), \
IF_ENABLED(CONFIG_SOC_SERIES_GD32F4XX, \
IF_ENABLED(DT_HAS_COMPAT_STATUS_OKAY(gd_gd32_dma_v1), \
(.reset = RESET_DT_SPEC_INST_GET(inst),)) \
.irq_configure = dma_gd32##inst##_irq_configure, \
}; \

View file

@ -618,7 +618,7 @@
};
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>;
@ -626,12 +626,12 @@
resets = <&rctl GD32_RESET_DMA0>;
dma-channels = <8>;
gd,mem2mem;
#dma-cells = <2>;
#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>;
@ -639,7 +639,7 @@
resets = <&rctl GD32_RESET_DMA1>;
dma-channels = <8>;
gd,mem2mem;
#dma-cells = <2>;
#dma-cells = <4>;
status = "disabled";
};
};

View file

@ -0,0 +1,98 @@
# Copyright (c) 2022, TOKITA Hiroshi <tokita.hiroshi@gmail.com>
# 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