diff --git a/CODEOWNERS b/CODEOWNERS index 8882c87689e..8efb8ca512f 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -237,6 +237,7 @@ /drivers/dma/dma_stm32* @cybertale @lowlander /drivers/dma/*pl330* @raveenp /drivers/dma/*iproc_pax* @raveenp +/drivers/dma/*cavs* @teburd /drivers/ec_host_cmd_periph/ @jettr /drivers/edac/ @finikorg /drivers/eeprom/ @henrikbrixandersen diff --git a/boards/xtensa/intel_adsp_cavs25/Kconfig.defconfig b/boards/xtensa/intel_adsp_cavs25/Kconfig.defconfig index d21aa2710a2..564db9f040b 100644 --- a/boards/xtensa/intel_adsp_cavs25/Kconfig.defconfig +++ b/boards/xtensa/intel_adsp_cavs25/Kconfig.defconfig @@ -35,10 +35,6 @@ config 2ND_LVL_ISR_TBL_OFFSET config CAVS_ISR_TBL_OFFSET default 2ND_LVL_ISR_TBL_OFFSET -config DMA_DW - default y - depends on DMA - config I2S_CAVS default y depends on I2S diff --git a/boards/xtensa/intel_adsp_cavs25/intel_adsp_cavs25.dts b/boards/xtensa/intel_adsp_cavs25/intel_adsp_cavs25.dts index d4c1cac454a..662e93d5296 100644 --- a/boards/xtensa/intel_adsp_cavs25/intel_adsp_cavs25.dts +++ b/boards/xtensa/intel_adsp_cavs25/intel_adsp_cavs25.dts @@ -12,6 +12,10 @@ model = "intel_adsp_cavs25"; compatible = "intel"; + aliases { + dma0 = &lpgpdma0; + }; + chosen { zephyr,sram = &sram0; }; diff --git a/boards/xtensa/intel_adsp_cavs25/intel_adsp_cavs25.yaml b/boards/xtensa/intel_adsp_cavs25/intel_adsp_cavs25.yaml index 381cb61eae9..bce9412071d 100644 --- a/boards/xtensa/intel_adsp_cavs25/intel_adsp_cavs25.yaml +++ b/boards/xtensa/intel_adsp_cavs25/intel_adsp_cavs25.yaml @@ -5,6 +5,8 @@ arch: xtensa toolchain: - xcc - zephyr +supported: + - dma testing: ignore_tags: - net diff --git a/drivers/dma/CMakeLists.txt b/drivers/dma/CMakeLists.txt index 05335367619..9a47043f295 100644 --- a/drivers/dma/CMakeLists.txt +++ b/drivers/dma/CMakeLists.txt @@ -16,3 +16,4 @@ zephyr_library_sources_ifdef(CONFIG_DMA_MCUX_LPC dma_mcux_lpc.c) zephyr_library_sources_ifdef(CONFIG_DMA_PL330 dma_pl330.c) zephyr_library_sources_ifdef(CONFIG_DMA_IPROC_PAX dma_iproc_pax_v1.c) zephyr_library_sources_ifdef(CONFIG_DMA_IPROC_PAX_V2 dma_iproc_pax_v2.c) +zephyr_library_sources_ifdef(CONFIG_DMA_CAVS_GPDMA dma_cavs_gpdma.c dma_dw_common.c) diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index 8e6b047c79e..316f1600097 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -44,4 +44,6 @@ source "drivers/dma/Kconfig.dma_pl330" source "drivers/dma/Kconfig.iproc_pax" +source "drivers/dma/Kconfig.cavs_gpdma" + endif # DMA diff --git a/drivers/dma/Kconfig.cavs_gpdma b/drivers/dma/Kconfig.cavs_gpdma new file mode 100644 index 00000000000..1f41493b7e6 --- /dev/null +++ b/drivers/dma/Kconfig.cavs_gpdma @@ -0,0 +1,9 @@ +# cAVS GPDMA configuration options + +# Copyright (c) 2022 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +config DMA_CAVS_GPDMA + bool "Enable cAVS GPDMA DMA driver" + help + Intel cAVS GPDMA DMA driver. diff --git a/drivers/dma/dma_cavs_gpdma.c b/drivers/dma/dma_cavs_gpdma.c new file mode 100644 index 00000000000..6efcafd4081 --- /dev/null +++ b/drivers/dma/dma_cavs_gpdma.c @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2022 Intel Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT intel_cavs_gpdma + +#define GPDMA_CTL_OFFSET 0x004 +#define GPDMA_CTL_FDCGB BIT(0) + +#include "dma_dw_common.h" + +#define LOG_LEVEL CONFIG_DMA_LOG_LEVEL +#include +LOG_MODULE_REGISTER(dma_cavs_gpdma); + + +/* Device run time data */ +struct cavs_gpdma_data { + struct dw_dma_dev_data dw_data; +}; + +/* Device constant configuration parameters */ +struct cavs_gpdma_cfg { + struct dw_dma_dev_cfg dw_cfg; + uint32_t shim; +}; + +/* Disables automatic clock gating (force disable clock gate) */ +static void cavs_gpdma_clock_enable(const struct device *dev) +{ + const struct cavs_gpdma_cfg *const dev_cfg = dev->config; + uint32_t reg = dev_cfg->shim + GPDMA_CTL_OFFSET; + + sys_write32(GPDMA_CTL_FDCGB, reg); +} + + +int cavs_gpdma_init(const struct device *dev) +{ + const struct cavs_gpdma_cfg *const dev_cfg = dev->config; + + /* Disable dynamic clock gating appropriately before initializing */ + cavs_gpdma_clock_enable(dev); + + /* Disable all channels and Channel interrupts */ + dw_dma_setup(dev); + + /* Configure interrupts */ + dev_cfg->dw_cfg.irq_config(); + + LOG_INF("Device %s initialized", dev->name); + + return 0; +} + + +static const struct dma_driver_api cavs_gpdma_driver_api = { + .config = dw_dma_config, + .reload = dw_dma_reload, + .start = dw_dma_transfer_start, + .stop = dw_dma_transfer_stop, +}; + + +#define CAVS_GPDMA_CHAN_ARB_DATA(inst) \ + static struct dw_drv_plat_data dmac##inst = { \ + .chan[0] = { \ + .class = 6, \ + .weight = 0, \ + }, \ + .chan[1] = { \ + .class = 6, \ + .weight = 0, \ + }, \ + .chan[2] = { \ + .class = 6, \ + .weight = 0, \ + }, \ + .chan[3] = { \ + .class = 6, \ + .weight = 0, \ + }, \ + .chan[4] = { \ + .class = 6, \ + .weight = 0, \ + }, \ + .chan[5] = { \ + .class = 6, \ + .weight = 0, \ + }, \ + .chan[6] = { \ + .class = 6, \ + .weight = 0, \ + }, \ + .chan[7] = { \ + .class = 6, \ + .weight = 0, \ + }, \ + } + +#define CAVS_GPDMA_INIT(inst) \ + CAVS_GPDMA_CHAN_ARB_DATA(inst); \ + static void cavs_gpdma##inst##_irq_config(void); \ + \ + static const struct cavs_gpdma_cfg cavs_gpdma##inst##_config = { \ + .dw_cfg = { \ + .base = DT_INST_REG_ADDR(inst), \ + .irq_config = cavs_gpdma##inst##_irq_config, \ + }, \ + .shim = DT_INST_PROP_BY_IDX(inst, shim, 0), \ + }; \ + \ + static struct cavs_gpdma_data cavs_gpdma##inst##_data = { \ + .dw_data = { \ + .channel_data = &dmac##inst, \ + }, \ + }; \ + \ + \ + DEVICE_DT_INST_DEFINE(inst, \ + &cavs_gpdma_init, \ + NULL, \ + &cavs_gpdma##inst##_data, \ + &cavs_gpdma##inst##_config, POST_KERNEL, \ + CONFIG_DMA_INIT_PRIORITY, \ + &cavs_gpdma_driver_api); \ + \ + static void cavs_gpdma##inst##_irq_config(void) \ + { \ + IRQ_CONNECT(DT_INST_IRQN(inst), \ + DT_INST_IRQ(inst, priority), dw_dma_isr, \ + DEVICE_DT_INST_GET(inst), \ + DT_INST_IRQ(inst, sense)); \ + irq_enable(DT_INST_IRQN(inst)); \ + } + +DT_INST_FOREACH_STATUS_OKAY(CAVS_GPDMA_INIT) diff --git a/dts/bindings/dma/intel,cavs-gpdma.yaml b/dts/bindings/dma/intel,cavs-gpdma.yaml new file mode 100644 index 00000000000..16394058f28 --- /dev/null +++ b/dts/bindings/dma/intel,cavs-gpdma.yaml @@ -0,0 +1,13 @@ +# Copyright (c) 2022 Intel Corporation. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +description: Intel cAVS Designware based General Purpose DMA Controller node + +compatible: "intel,cavs-gpdma" + +include: snps,designware-dma.yaml + +properties: + shim: + type: array + required: true diff --git a/dts/xtensa/intel/intel_cavs25.dtsi b/dts/xtensa/intel/intel_cavs25.dtsi index a6d8acb6d3a..2aab5e60fbd 100644 --- a/dts/xtensa/intel/intel_cavs25.dtsi +++ b/dts/xtensa/intel/intel_cavs25.dtsi @@ -125,5 +125,29 @@ compatible = "intel,adsp-tlb"; reg = <0x3000 0x1000>; }; + + lpgpdma0: dma@7c000 { + compatible = "intel,cavs-gpdma"; + #dma-cells = <1>; + reg = <0x0007c000 0x1000>; + shim = <0x00078400 0x100>; + interrupts = <0x10 0 0>; + interrupt-parent = <&cavs3>; + label = "DMA_0"; + + status = "okay"; + }; + + lpgpdma1: dma@7d000 { + compatible = "intel,cavs-gpdma"; + #dma-cells = <1>; + reg = <0x0007d000 0x1000>; + shim = <0x00078500 0x100>; + interrupts = <0x0F 0 0>; + interrupt-parent = <&cavs3>; + label = "DMA_1"; + + status = "okay"; + }; }; }; diff --git a/soc/xtensa/intel_adsp/cavs_v25/Kconfig.defconfig.series b/soc/xtensa/intel_adsp/cavs_v25/Kconfig.defconfig.series index a9ef25ae126..fbc2841e235 100644 --- a/soc/xtensa/intel_adsp/cavs_v25/Kconfig.defconfig.series +++ b/soc/xtensa/intel_adsp/cavs_v25/Kconfig.defconfig.series @@ -72,4 +72,8 @@ config KERNEL_VM_SIZE endif +config DMA_CAVS_GPDMA + default y + depends on DMA + endif # SOC_SERIES_INTEL_CAVS_V25