Skip to content

Commit 2f32073

Browse files
teburdnashif
authored andcommitted
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 <[email protected]>
1 parent 98f1a98 commit 2f32073

File tree

9 files changed

+225
-12
lines changed

9 files changed

+225
-12
lines changed

drivers/dma/dma_cavs_hda.c

Lines changed: 76 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,14 +98,89 @@ int cavs_hda_dma_host_out_config(const struct device *dev,
9898
return res;
9999
}
100100

101+
int cavs_hda_dma_link_in_config(const struct device *dev,
102+
uint32_t channel,
103+
struct dma_config *dma_cfg)
104+
{
105+
const struct cavs_hda_dma_cfg *const cfg = dev->config;
106+
struct dma_block_config *blk_cfg;
107+
uint8_t *buf;
108+
int res;
109+
110+
__ASSERT(channel < cfg->dma_channels, "Channel does not exist");
111+
__ASSERT(dma_cfg->block_count == 1,
112+
"HDA does not support scatter gather or chained "
113+
"block transfers.");
114+
__ASSERT(dma_cfg->channel_direction == cfg->direction,
115+
"Unexpected channel direction, HDA link in supports "
116+
"PERIPHERAL_TO_MEMORY");
117+
118+
blk_cfg = dma_cfg->head_block;
119+
buf = (uint8_t *)(uintptr_t)(blk_cfg->source_address);
120+
res = cavs_hda_set_buffer(cfg->base, channel, buf,
121+
blk_cfg->block_size);
122+
123+
if (res == 0 && dma_cfg->source_data_size <= 3) {
124+
/* set the sample container set bit to 16bits */
125+
*DGCS(cfg->base, channel) |= DGCS_SCS;
126+
}
127+
128+
return res;
129+
}
130+
131+
132+
int cavs_hda_dma_link_out_config(const struct device *dev,
133+
uint32_t channel,
134+
struct dma_config *dma_cfg)
135+
{
136+
const struct cavs_hda_dma_cfg *const cfg = dev->config;
137+
struct dma_block_config *blk_cfg;
138+
uint8_t *buf;
139+
int res;
140+
141+
__ASSERT(channel < cfg->dma_channels, "Channel does not exist");
142+
__ASSERT(dma_cfg->block_count == 1,
143+
"HDA does not support scatter gather or chained "
144+
"block transfers.");
145+
__ASSERT(dma_cfg->channel_direction == cfg->direction,
146+
"Unexpected channel direction, HDA link out supports "
147+
"MEMORY_TO_PERIPHERAL");
148+
149+
blk_cfg = dma_cfg->head_block;
150+
buf = (uint8_t *)(uintptr_t)(blk_cfg->dest_address);
151+
152+
res = cavs_hda_set_buffer(cfg->base, channel, buf,
153+
blk_cfg->block_size);
154+
155+
if (res == 0 && dma_cfg->dest_data_size <= 3) {
156+
/* set the sample container set bit to 16bits */
157+
*DGCS(cfg->base, channel) |= DGCS_SCS;
158+
}
159+
160+
return res;
161+
}
162+
163+
164+
int cavs_hda_dma_link_reload(const struct device *dev, uint32_t channel,
165+
uint32_t src, uint32_t dst, size_t size)
166+
{
167+
const struct cavs_hda_dma_cfg *const cfg = dev->config;
168+
169+
__ASSERT(channel < cfg->dma_channels, "Channel does not exist");
170+
171+
cavs_hda_link_commit(cfg->base, channel, size);
172+
173+
return 0;
174+
}
175+
101176
int cavs_hda_dma_host_reload(const struct device *dev, uint32_t channel,
102177
uint32_t src, uint32_t dst, size_t size)
103178
{
104179
const struct cavs_hda_dma_cfg *const cfg = dev->config;
105180

106181
__ASSERT(channel < cfg->dma_channels, "Channel does not exist");
107182

108-
cavs_hda_commit(cfg->base, channel, size);
183+
cavs_hda_host_commit(cfg->base, channel, size);
109184

110185
return 0;
111186
}

drivers/dma/dma_cavs_hda.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
#ifndef ZEPHYR_DRIVERS_DMA_DMA_CAVS_HDA_COMMON_H_
88
#define ZEPHYR_DRIVERS_DMA_DMA_CAVS_HDA_COMMON_H_
99

10-
#define CAVS_HDA_MAX_CHANNELS 32
10+
#define CAVS_HDA_MAX_CHANNELS DT_PROP(DT_NODELABEL(hda_host_out), dma_channels)
1111

1212
#include <drivers/dma.h>
1313

@@ -31,6 +31,17 @@ int cavs_hda_dma_host_out_config(const struct device *dev,
3131
uint32_t channel,
3232
struct dma_config *dma_cfg);
3333

34+
int cavs_hda_dma_link_in_config(const struct device *dev,
35+
uint32_t channel,
36+
struct dma_config *dma_cfg);
37+
38+
int cavs_hda_dma_link_out_config(const struct device *dev,
39+
uint32_t channel,
40+
struct dma_config *dma_cfg);
41+
42+
int cavs_hda_dma_link_reload(const struct device *dev, uint32_t channel,
43+
uint32_t src, uint32_t dst, size_t size);
44+
3445
int cavs_hda_dma_host_reload(const struct device *dev, uint32_t channel,
3546
uint32_t src, uint32_t dst, size_t size);
3647

drivers/dma/dma_cavs_hda_link_in.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Copyright (c) 2022 Intel Corporation.
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#define DT_DRV_COMPAT intel_cavs_hda_link_in
8+
9+
#include <drivers/dma.h>
10+
#include "dma_cavs_hda.h"
11+
12+
#define LOG_LEVEL CONFIG_DMA_LOG_LEVEL
13+
#include <logging/log.h>
14+
LOG_MODULE_REGISTER(dma_cavs_hda_dma_link_in);
15+
16+
static const struct dma_driver_api cavs_hda_dma_link_in_api = {
17+
.config = cavs_hda_dma_link_in_config,
18+
.reload = cavs_hda_dma_link_reload,
19+
.start = cavs_hda_dma_start,
20+
.stop = cavs_hda_dma_stop,
21+
.get_status = cavs_hda_dma_status,
22+
.chan_filter = cavs_hda_dma_chan_filter,
23+
};
24+
25+
#define CAVS_HDA_DMA_LINK_IN_INIT(inst) \
26+
static const struct cavs_hda_dma_cfg cavs_hda_dma##inst##_config = { \
27+
.base = DT_INST_REG_ADDR(inst), \
28+
.dma_channels = DT_INST_PROP(inst, dma_channels), \
29+
.direction = MEMORY_TO_HOST \
30+
}; \
31+
\
32+
static struct cavs_hda_dma_data cavs_hda_dma##inst##_data = {}; \
33+
\
34+
DEVICE_DT_INST_DEFINE(inst, &cavs_hda_dma_init, NULL, &cavs_hda_dma##inst##_data, \
35+
&cavs_hda_dma##inst##_config, POST_KERNEL, CONFIG_DMA_INIT_PRIORITY, \
36+
&cavs_hda_dma_link_in_api);
37+
38+
DT_INST_FOREACH_STATUS_OKAY(CAVS_HDA_DMA_LINK_IN_INIT)
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Copyright (c) 2022 Intel Corporation.
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#define DT_DRV_COMPAT intel_cavs_hda_link_out
8+
9+
#include <drivers/dma.h>
10+
#include "dma_cavs_hda.h"
11+
12+
#define LOG_LEVEL CONFIG_DMA_LOG_LEVEL
13+
#include <logging/log.h>
14+
LOG_MODULE_REGISTER(dma_cavs_hda_dma_link_out);
15+
16+
static const struct dma_driver_api cavs_hda_dma_link_out_api = {
17+
.config = cavs_hda_dma_link_out_config,
18+
.reload = cavs_hda_dma_link_reload,
19+
.start = cavs_hda_dma_start,
20+
.stop = cavs_hda_dma_stop,
21+
.get_status = cavs_hda_dma_status,
22+
.chan_filter = cavs_hda_dma_chan_filter,
23+
};
24+
25+
#define CAVS_HDA_DMA_LINK_OUT_INIT(inst) \
26+
static const struct cavs_hda_dma_cfg cavs_hda_dma##inst##_config = { \
27+
.base = DT_INST_REG_ADDR(inst), \
28+
.dma_channels = DT_INST_PROP(inst, dma_channels), \
29+
.direction = MEMORY_TO_HOST \
30+
}; \
31+
\
32+
static struct cavs_hda_dma_data cavs_hda_dma##inst##_data = {}; \
33+
\
34+
DEVICE_DT_INST_DEFINE(inst, &cavs_hda_dma_init, NULL, &cavs_hda_dma##inst##_data, \
35+
&cavs_hda_dma##inst##_config, POST_KERNEL, CONFIG_DMA_INIT_PRIORITY, \
36+
&cavs_hda_dma_link_out_api);
37+
38+
DT_INST_FOREACH_STATUS_OKAY(CAVS_HDA_DMA_LINK_OUT_INIT)
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Copyright (c) 2022 Intel Corporation. All rights reserved.
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
description: Intel cAVS HDA Link In controller
5+
6+
compatible: "intel,cavs-hda-link-in"
7+
8+
include: intel,cavs-hda.yaml
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Copyright (c) 2022 Intel Corporation. All rights reserved.
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
description: Intel cAVS HDA Link Out controller
5+
6+
compatible: "intel,cavs-hda-link-out"
7+
8+
include: intel,cavs-hda.yaml

dts/xtensa/intel/intel_cavs.dtsi

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,25 @@
3131

3232
status = "okay";
3333
};
34+
hda_link_out: dma@72400 {
35+
compatible = "intel,cavs-hda-link-out";
36+
#dma-cells = <1>;
37+
reg = <0x00072400 0x40>;
38+
dma-channels = <7>;
39+
label = "HDA_LINK_OUT";
40+
41+
status = "okay";
42+
};
43+
44+
hda_link_in: dma@72600 {
45+
compatible = "intel,cavs-hda-link-in";
46+
#dma-cells = <1>;
47+
reg = <0x00072600 0x40>;
48+
dma-channels = <7>;
49+
label = "HDA_LINK_IN";
50+
51+
status = "okay";
52+
};
3453

3554
hda_host_out: dma@72800 {
3655
compatible = "intel,cavs-hda-host-out";
@@ -51,5 +70,7 @@
5170

5271
status = "okay";
5372
};
73+
74+
5475
};
5576
};

soc/xtensa/intel_adsp/common/include/cavs_hda.h

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ static inline uint32_t cavs_hda_unused(uint32_t base, uint32_t sid)
241241
}
242242

243243
/**
244-
* @brief Commit a number of bytes that have been transferred
244+
* @brief Commit a number of bytes that have been transferred to/from host
245245
*
246246
* Writes the length to BFPI. For host transfers LLPI and LPIB are
247247
* also written to with the given length.
@@ -259,13 +259,27 @@ static inline uint32_t cavs_hda_unused(uint32_t base, uint32_t sid)
259259
* @param sid Stream ID within the register block
260260
* @param len Len to increment postion by
261261
*/
262-
static inline void cavs_hda_commit(uint32_t base, uint32_t sid, uint32_t len)
262+
static inline void cavs_hda_host_commit(uint32_t base, uint32_t sid, uint32_t len)
263+
{
264+
*DGBFPI(base, sid) = len;
265+
*DGLLPI(base, sid) = len;
266+
*DGLPIBI(base, sid) = len;
267+
}
268+
269+
/**
270+
* @brief Commit a number of bytes that have been transferred to/from link
271+
*
272+
* Writes the length to BFPI.
273+
*
274+
* @seealso cavs_hda_host_commit
275+
*
276+
* @param base Base address of the IP register block
277+
* @param sid Stream ID within the register block
278+
* @param len Len to increment postion by
279+
*/
280+
static inline void cavs_hda_link_commit(uint32_t base, uint32_t sid, uint32_t len)
263281
{
264282
*DGBFPI(base, sid) = len;
265-
if (base == HDA_HOST_IN_BASE || base == HDA_HOST_OUT_BASE) {
266-
*DGLLPI(base, sid) = len;
267-
*DGLPIBI(base, sid) = len;
268-
}
269283
}
270284

271285
/**
@@ -287,8 +301,8 @@ static inline bool cavs_hda_buf_full(uint32_t base, uint32_t sid)
287301
* For HDA this does not mean that the buffer is full or empty
288302
* there are bit flags for those cases.
289303
*
290-
* This can let you wait on the hardware to catch up to your
291-
* reads or writes (ex after a cavs_hda_commit)
304+
* Useful for waiting on the hardware to catch up to
305+
* reads or writes (e.g. after a cavs_hda_commit)
292306
*
293307
* @param dev HDA Stream device
294308
* @param sid Stream ID

tests/boards/intel_adsp/hda/src/smoke.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ void test_hda_host_in_smoke(void)
9090
cavs_hda_dbg("host_in", HDA_HOST_IN_BASE, STREAM_ID);
9191

9292
for (uint32_t i = 0; i < TRANSFER_COUNT; i++) {
93-
cavs_hda_commit(HDA_HOST_IN_BASE, STREAM_ID, HDA_BUF_SIZE);
93+
cavs_hda_host_commit(HDA_HOST_IN_BASE, STREAM_ID, HDA_BUF_SIZE);
9494
printk("dsp inc_pos: "); cavs_hda_dbg("host_in", HDA_HOST_IN_BASE, STREAM_ID);
9595

9696
WAIT_FOR(cavs_hda_wp_rp_eq(HDA_HOST_IN_BASE, STREAM_ID), 10000, k_msleep(1));
@@ -186,7 +186,7 @@ void test_hda_host_out_smoke(void)
186186
}
187187
zassert_true(is_ramp, "Expected data to be a ramp");
188188

189-
cavs_hda_commit(HDA_HOST_OUT_BASE, STREAM_ID, HDA_BUF_SIZE);
189+
cavs_hda_host_commit(HDA_HOST_OUT_BASE, STREAM_ID, HDA_BUF_SIZE);
190190
printk("dsp inc pos: "); cavs_hda_dbg("host_out", HDA_HOST_OUT_BASE, STREAM_ID);
191191

192192
}

0 commit comments

Comments
 (0)