dma: cavs: Add gpdma derivative of dw dma for cavs

Intel's adsp needs to set, at a minimum, a clocking bit before the driver
can initialize the designware dma controller. In many ways it is the
designware dmac IP but with additional registers and functionality added
on top of it. So the code structure here follows how the hardware
appears to be designed, layered on top of the designware driver.

Signed-off-by: Tom Burdick <thomas.burdick@intel.com>
This commit is contained in:
Tom Burdick 2022-02-01 11:35:13 -06:00 committed by Anas Nashif
parent f9acacfd11
commit 1e9ada4eb9
11 changed files with 199 additions and 4 deletions

View File

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

View File

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

View File

@ -12,6 +12,10 @@
model = "intel_adsp_cavs25";
compatible = "intel";
aliases {
dma0 = &lpgpdma0;
};
chosen {
zephyr,sram = &sram0;
};

View File

@ -5,6 +5,8 @@ arch: xtensa
toolchain:
- xcc
- zephyr
supported:
- dma
testing:
ignore_tags:
- net

View File

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

View File

@ -44,4 +44,6 @@ source "drivers/dma/Kconfig.dma_pl330"
source "drivers/dma/Kconfig.iproc_pax"
source "drivers/dma/Kconfig.cavs_gpdma"
endif # DMA

View File

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

View File

@ -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 <logging/log.h>
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)

View File

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

View File

@ -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";
};
};
};

View File

@ -72,4 +72,8 @@ config KERNEL_VM_SIZE
endif
config DMA_CAVS_GPDMA
default y
depends on DMA
endif # SOC_SERIES_INTEL_CAVS_V25