dma/cavs_hda: Adds link in/link out compatibles

Adds hda link in and out drivers. The link in and link
out channels of HDA have small differences
with the host channels. Updates the existing
cavs_hda drivers and code to account for these
differences.

Signed-off-by: Tom Burdick <thomas.burdick@intel.com>
This commit is contained in:
Tom Burdick 2022-04-06 17:26:33 -05:00 committed by Anas Nashif
commit 2f320730a1
9 changed files with 225 additions and 12 deletions

View file

@ -98,6 +98,81 @@ int cavs_hda_dma_host_out_config(const struct device *dev,
return res;
}
int cavs_hda_dma_link_in_config(const struct device *dev,
uint32_t channel,
struct dma_config *dma_cfg)
{
const struct cavs_hda_dma_cfg *const cfg = dev->config;
struct dma_block_config *blk_cfg;
uint8_t *buf;
int res;
__ASSERT(channel < cfg->dma_channels, "Channel does not exist");
__ASSERT(dma_cfg->block_count == 1,
"HDA does not support scatter gather or chained "
"block transfers.");
__ASSERT(dma_cfg->channel_direction == cfg->direction,
"Unexpected channel direction, HDA link in supports "
"PERIPHERAL_TO_MEMORY");
blk_cfg = dma_cfg->head_block;
buf = (uint8_t *)(uintptr_t)(blk_cfg->source_address);
res = cavs_hda_set_buffer(cfg->base, channel, buf,
blk_cfg->block_size);
if (res == 0 && dma_cfg->source_data_size <= 3) {
/* set the sample container set bit to 16bits */
*DGCS(cfg->base, channel) |= DGCS_SCS;
}
return res;
}
int cavs_hda_dma_link_out_config(const struct device *dev,
uint32_t channel,
struct dma_config *dma_cfg)
{
const struct cavs_hda_dma_cfg *const cfg = dev->config;
struct dma_block_config *blk_cfg;
uint8_t *buf;
int res;
__ASSERT(channel < cfg->dma_channels, "Channel does not exist");
__ASSERT(dma_cfg->block_count == 1,
"HDA does not support scatter gather or chained "
"block transfers.");
__ASSERT(dma_cfg->channel_direction == cfg->direction,
"Unexpected channel direction, HDA link out supports "
"MEMORY_TO_PERIPHERAL");
blk_cfg = dma_cfg->head_block;
buf = (uint8_t *)(uintptr_t)(blk_cfg->dest_address);
res = cavs_hda_set_buffer(cfg->base, channel, buf,
blk_cfg->block_size);
if (res == 0 && dma_cfg->dest_data_size <= 3) {
/* set the sample container set bit to 16bits */
*DGCS(cfg->base, channel) |= DGCS_SCS;
}
return res;
}
int cavs_hda_dma_link_reload(const struct device *dev, uint32_t channel,
uint32_t src, uint32_t dst, size_t size)
{
const struct cavs_hda_dma_cfg *const cfg = dev->config;
__ASSERT(channel < cfg->dma_channels, "Channel does not exist");
cavs_hda_link_commit(cfg->base, channel, size);
return 0;
}
int cavs_hda_dma_host_reload(const struct device *dev, uint32_t channel,
uint32_t src, uint32_t dst, size_t size)
{
@ -105,7 +180,7 @@ int cavs_hda_dma_host_reload(const struct device *dev, uint32_t channel,
__ASSERT(channel < cfg->dma_channels, "Channel does not exist");
cavs_hda_commit(cfg->base, channel, size);
cavs_hda_host_commit(cfg->base, channel, size);
return 0;
}

View file

@ -7,7 +7,7 @@
#ifndef ZEPHYR_DRIVERS_DMA_DMA_CAVS_HDA_COMMON_H_
#define ZEPHYR_DRIVERS_DMA_DMA_CAVS_HDA_COMMON_H_
#define CAVS_HDA_MAX_CHANNELS 32
#define CAVS_HDA_MAX_CHANNELS DT_PROP(DT_NODELABEL(hda_host_out), dma_channels)
#include <drivers/dma.h>
@ -31,6 +31,17 @@ int cavs_hda_dma_host_out_config(const struct device *dev,
uint32_t channel,
struct dma_config *dma_cfg);
int cavs_hda_dma_link_in_config(const struct device *dev,
uint32_t channel,
struct dma_config *dma_cfg);
int cavs_hda_dma_link_out_config(const struct device *dev,
uint32_t channel,
struct dma_config *dma_cfg);
int cavs_hda_dma_link_reload(const struct device *dev, uint32_t channel,
uint32_t src, uint32_t dst, size_t size);
int cavs_hda_dma_host_reload(const struct device *dev, uint32_t channel,
uint32_t src, uint32_t dst, size_t size);

View file

@ -0,0 +1,38 @@
/*
* Copyright (c) 2022 Intel Corporation.
*
* SPDX-License-Identifier: Apache-2.0
*/
#define DT_DRV_COMPAT intel_cavs_hda_link_in
#include <drivers/dma.h>
#include "dma_cavs_hda.h"
#define LOG_LEVEL CONFIG_DMA_LOG_LEVEL
#include <logging/log.h>
LOG_MODULE_REGISTER(dma_cavs_hda_dma_link_in);
static const struct dma_driver_api cavs_hda_dma_link_in_api = {
.config = cavs_hda_dma_link_in_config,
.reload = cavs_hda_dma_link_reload,
.start = cavs_hda_dma_start,
.stop = cavs_hda_dma_stop,
.get_status = cavs_hda_dma_status,
.chan_filter = cavs_hda_dma_chan_filter,
};
#define CAVS_HDA_DMA_LINK_IN_INIT(inst) \
static const struct cavs_hda_dma_cfg cavs_hda_dma##inst##_config = { \
.base = DT_INST_REG_ADDR(inst), \
.dma_channels = DT_INST_PROP(inst, dma_channels), \
.direction = MEMORY_TO_HOST \
}; \
\
static struct cavs_hda_dma_data cavs_hda_dma##inst##_data = {}; \
\
DEVICE_DT_INST_DEFINE(inst, &cavs_hda_dma_init, NULL, &cavs_hda_dma##inst##_data, \
&cavs_hda_dma##inst##_config, POST_KERNEL, CONFIG_DMA_INIT_PRIORITY, \
&cavs_hda_dma_link_in_api);
DT_INST_FOREACH_STATUS_OKAY(CAVS_HDA_DMA_LINK_IN_INIT)

View file

@ -0,0 +1,38 @@
/*
* Copyright (c) 2022 Intel Corporation.
*
* SPDX-License-Identifier: Apache-2.0
*/
#define DT_DRV_COMPAT intel_cavs_hda_link_out
#include <drivers/dma.h>
#include "dma_cavs_hda.h"
#define LOG_LEVEL CONFIG_DMA_LOG_LEVEL
#include <logging/log.h>
LOG_MODULE_REGISTER(dma_cavs_hda_dma_link_out);
static const struct dma_driver_api cavs_hda_dma_link_out_api = {
.config = cavs_hda_dma_link_out_config,
.reload = cavs_hda_dma_link_reload,
.start = cavs_hda_dma_start,
.stop = cavs_hda_dma_stop,
.get_status = cavs_hda_dma_status,
.chan_filter = cavs_hda_dma_chan_filter,
};
#define CAVS_HDA_DMA_LINK_OUT_INIT(inst) \
static const struct cavs_hda_dma_cfg cavs_hda_dma##inst##_config = { \
.base = DT_INST_REG_ADDR(inst), \
.dma_channels = DT_INST_PROP(inst, dma_channels), \
.direction = MEMORY_TO_HOST \
}; \
\
static struct cavs_hda_dma_data cavs_hda_dma##inst##_data = {}; \
\
DEVICE_DT_INST_DEFINE(inst, &cavs_hda_dma_init, NULL, &cavs_hda_dma##inst##_data, \
&cavs_hda_dma##inst##_config, POST_KERNEL, CONFIG_DMA_INIT_PRIORITY, \
&cavs_hda_dma_link_out_api);
DT_INST_FOREACH_STATUS_OKAY(CAVS_HDA_DMA_LINK_OUT_INIT)