From 6d18ca52dd5a11e9048a1e049bf2151abfa1433f Mon Sep 17 00:00:00 2001 From: Kai Vehmanen Date: Wed, 9 Oct 2024 15:17:06 +0300 Subject: [PATCH] zephyr: sof/lib: split dma.h to dma.h and dma-legacy.h Move parts of the dma.h interface only needed by XTOS drivers to a separate dma-legacy.h file. Use of non-native drivers is a transitory tool and used by a subset of targets. To make the code easier to read and maintain, the main dma.h should only require definitions needed when building SOF Zephyr with native Zephyr drivers (CONFIG_ZEPHYR_NATIVE_DRIVERS). This is especially important for DMA as there is lot of similarly named definitions and interfaces related to DMA in Zephyr and SOF. Signed-off-by: Kai Vehmanen --- zephyr/include/sof/lib/dma-legacy.h | 286 +++++++++++++++++++++++++++ zephyr/include/sof/lib/dma.h | 296 ++-------------------------- 2 files changed, 299 insertions(+), 283 deletions(-) create mode 100644 zephyr/include/sof/lib/dma-legacy.h diff --git a/zephyr/include/sof/lib/dma-legacy.h b/zephyr/include/sof/lib/dma-legacy.h new file mode 100644 index 000000000000..a9cec37ab0d5 --- /dev/null +++ b/zephyr/include/sof/lib/dma-legacy.h @@ -0,0 +1,286 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2024 Intel Corporation. + */ + +#ifndef __SOF_LIB_DMA_LEGACY_H__ +#define __SOF_LIB_DMA_LEGACY_H__ + +/* DMA attributes */ +#define DMA_ATTR_BUFFER_ALIGNMENT 0 +#define DMA_ATTR_COPY_ALIGNMENT 1 +#define DMA_ATTR_BUFFER_ADDRESS_ALIGNMENT 2 +#define DMA_ATTR_BUFFER_PERIOD_COUNT 3 + +/* DMA interrupt commands */ +enum dma_irq_cmd { + DMA_IRQ_STATUS_GET = 0, + DMA_IRQ_CLEAR, + DMA_IRQ_MASK, + DMA_IRQ_UNMASK +}; + +/* DMA operations */ +struct dma_ops { + + struct dma_chan_data *(*channel_get)(struct dma *dma, + unsigned int req_channel); + void (*channel_put)(struct dma_chan_data *channel); + + int (*start)(struct dma_chan_data *channel); + int (*stop)(struct dma_chan_data *channel); + int (*stop_delayed)(struct dma_chan_data *channel); + int (*copy)(struct dma_chan_data *channel, int bytes, uint32_t flags); + int (*pause)(struct dma_chan_data *channel); + int (*release)(struct dma_chan_data *channel); + int (*status)(struct dma_chan_data *channel, + struct dma_chan_status *status, uint8_t direction); + + int (*set_config)(struct dma_chan_data *channel, + struct dma_sg_config *config); + + int (*probe)(struct dma *dma); + int (*remove)(struct dma *dma); + + int (*get_data_size)(struct dma_chan_data *channel, uint32_t *avail, + uint32_t *free); + + int (*get_attribute)(struct dma *dma, uint32_t type, uint32_t *value); + + int (*interrupt)(struct dma_chan_data *channel, enum dma_irq_cmd cmd); +}; + +/* DMA API + * Programming flow is :- + * + * 1) dma_channel_get() + * 2) notifier_register() + * 3) dma_set_config() + * 4) dma_start() + * ... DMA now running ... + * 5) dma_stop() + * 6) dma_stop_delayed() + * 7) dma_channel_put() + */ + +static inline struct dma_chan_data *dma_channel_get_legacy(struct dma *dma, + int req_channel) +{ + if (!dma || !dma->ops || !dma->ops->channel_get) + return NULL; + + struct dma_chan_data *chan = dma->ops->channel_get(dma, req_channel); + + return chan; +} + +static inline void dma_channel_put_legacy(struct dma_chan_data *channel) +{ + channel->dma->ops->channel_put(channel); +} + +static inline int dma_start_legacy(struct dma_chan_data *channel) +{ + return channel->dma->ops->start(channel); +} + +static inline int dma_stop_legacy(struct dma_chan_data *channel) +{ + if (channel->dma->ops->stop) + return channel->dma->ops->stop(channel); + + return 0; +} + +static inline int dma_stop_delayed_legacy(struct dma_chan_data *channel) +{ + if (channel->dma->ops->stop_delayed) + return channel->dma->ops->stop_delayed(channel); + + return 0; +} + +/** \defgroup sof_dma_copy_func static int dma_copy (struct dma_chan_data * channel, int bytes, uint32_t flags) + * + * This function is in a separate subgroup to solve a name clash with + * struct dma_copy {} + * @{ + */ +static inline int dma_copy_legacy(struct dma_chan_data *channel, int bytes, + uint32_t flags) +{ + return channel->dma->ops->copy(channel, bytes, flags); +} +/** @} */ + +static inline int dma_pause_legacy(struct dma_chan_data *channel) +{ + if (channel->dma->ops->pause) + return channel->dma->ops->pause(channel); + + return 0; +} + +static inline int dma_release_legacy(struct dma_chan_data *channel) +{ + if (channel->dma->ops->release) + return channel->dma->ops->release(channel); + + return 0; +} + +static inline int dma_status_legacy(struct dma_chan_data *channel, + struct dma_chan_status *status, uint8_t direction) +{ + return channel->dma->ops->status(channel, status, direction); +} + +static inline int dma_set_config_legacy(struct dma_chan_data *channel, + struct dma_sg_config *config) +{ + return channel->dma->ops->set_config(channel, config); +} + +static inline int dma_probe_legacy(struct dma *dma) +{ + return dma->ops->probe(dma); +} + +static inline int dma_remove_legacy(struct dma *dma) +{ + return dma->ops->remove(dma); +} + +static inline int dma_get_data_size_legacy(struct dma_chan_data *channel, + uint32_t *avail, uint32_t *free) +{ + return channel->dma->ops->get_data_size(channel, avail, free); +} + +static inline int dma_get_attribute_legacy(struct dma *dma, uint32_t type, + uint32_t *value) +{ + return dma->ops->get_attribute(dma, type, value); +} + +static inline int dma_interrupt_legacy(struct dma_chan_data *channel, + enum dma_irq_cmd cmd) +{ + return channel->dma->ops->interrupt(channel, cmd); +} + +#define dma_set_drvdata(dma, data) \ + (dma->priv_data = data) +#define dma_get_drvdata(dma) \ + dma->priv_data +#define dma_base(dma) \ + dma->plat_data.base +#define dma_irq(dma) \ + dma->plat_data.irq +#define dma_irq_name(dma) \ + dma->plat_data.irq_name +#define dma_chan_size(dma) \ + dma->plat_data.chan_size +#define dma_chan_base(dma, chan) \ + (dma->plat_data.base + chan * dma->plat_data.chan_size) +#define dma_chan_get_data(chan) \ + ((chan)->priv_data) +#define dma_chan_set_data(chan, data) \ + ((chan)->priv_data = data) + +/* DMA hardware register operations */ +static inline uint32_t dma_reg_read(struct dma *dma, uint32_t reg) +{ + return io_reg_read(dma_base(dma) + reg); +} + +static inline uint16_t dma_reg_read16(struct dma *dma, uint32_t reg) +{ + return io_reg_read16(dma_base(dma) + reg); +} + +static inline void dma_reg_write(struct dma *dma, uint32_t reg, uint32_t value) +{ + io_reg_write(dma_base(dma) + reg, value); +} + +static inline void dma_reg_write16(struct dma *dma, uint32_t reg, + uint16_t value) +{ + io_reg_write16(dma_base(dma) + reg, value); +} + +static inline void dma_reg_update_bits(struct dma *dma, uint32_t reg, + uint32_t mask, uint32_t value) +{ + io_reg_update_bits(dma_base(dma) + reg, mask, value); +} + +static inline uint32_t dma_chan_reg_read(struct dma_chan_data *channel, + uint32_t reg) +{ + return io_reg_read(dma_chan_base(channel->dma, channel->index) + reg); +} + +static inline uint16_t dma_chan_reg_read16(struct dma_chan_data *channel, + uint32_t reg) +{ + return io_reg_read16(dma_chan_base(channel->dma, channel->index) + reg); +} + +static inline void dma_chan_reg_write(struct dma_chan_data *channel, + uint32_t reg, uint32_t value) +{ + io_reg_write(dma_chan_base(channel->dma, channel->index) + reg, value); +} + +static inline void dma_chan_reg_write16(struct dma_chan_data *channel, + uint32_t reg, uint16_t value) +{ + io_reg_write16(dma_chan_base(channel->dma, channel->index) + reg, + value); +} + +static inline void dma_chan_reg_update_bits(struct dma_chan_data *channel, + uint32_t reg, uint32_t mask, + uint32_t value) +{ + io_reg_update_bits(dma_chan_base(channel->dma, channel->index) + reg, + mask, value); +} + +static inline void dma_chan_reg_update_bits16(struct dma_chan_data *channel, + uint32_t reg, uint16_t mask, + uint16_t value) +{ + io_reg_update_bits16(dma_chan_base(channel->dma, channel->index) + reg, + mask, value); +} + +/* init dma copy context */ +int dma_copy_new(struct dma_copy *dc); + +/* free dma copy context resources */ +static inline void dma_copy_free(struct dma_copy *dc) +{ + dma_channel_put_legacy(dc->chan); +} + +/* DMA copy data from host to DSP */ +int dma_copy_from_host(struct dma_copy *dc, struct dma_sg_config *host_sg, + int32_t host_offset, void *local_ptr, int32_t size); +int dma_copy_from_host_nowait(struct dma_copy *dc, + struct dma_sg_config *host_sg, + int32_t host_offset, void *local_ptr, + int32_t size); + +/* DMA copy data from DSP to host */ +int dma_copy_to_host(struct dma_copy *dc, struct dma_sg_config *host_sg, + int32_t host_offset, void *local_ptr, int32_t size); +int dma_copy_to_host_nowait(struct dma_copy *dc, struct dma_sg_config *host_sg, + int32_t host_offset, void *local_ptr, int32_t size); + + +int dma_copy_set_stream_tag(struct dma_copy *dc, uint32_t stream_tag); + +#endif /* __SOF_LIB_DMA_LEGACY_H__ */ diff --git a/zephyr/include/sof/lib/dma.h b/zephyr/include/sof/lib/dma.h index 6a25c81321ac..99e8cda67a8b 100644 --- a/zephyr/include/sof/lib/dma.h +++ b/zephyr/include/sof/lib/dma.h @@ -115,28 +115,12 @@ enum dma_cb_status { DMA_CB_STATUS_END, }; -/* DMA interrupt commands */ -enum dma_irq_cmd { - DMA_IRQ_STATUS_GET = 0, - DMA_IRQ_CLEAR, - DMA_IRQ_MASK, - DMA_IRQ_UNMASK -}; - #define DMA_CHAN_INVALID 0xFFFFFFFF #define DMA_CORE_INVALID 0xFFFFFFFF /* Attributes have been ported to Zephyr. This condition is necessary until full support of * CONFIG_SOF_ZEPHYR_STRICT_HEADERS. */ -#ifndef CONFIG_ZEPHYR_NATIVE_DRIVERS -/* DMA attributes */ -#define DMA_ATTR_BUFFER_ALIGNMENT 0 -#define DMA_ATTR_COPY_ALIGNMENT 1 -#define DMA_ATTR_BUFFER_ADDRESS_ALIGNMENT 2 -#define DMA_ATTR_BUFFER_PERIOD_COUNT 3 -#endif - struct dma; /** @@ -193,36 +177,7 @@ struct dma_chan_status { void *ipc_posn_data; }; -/* DMA operations */ -struct dma_ops { - - struct dma_chan_data *(*channel_get)(struct dma *dma, - unsigned int req_channel); - void (*channel_put)(struct dma_chan_data *channel); - - int (*start)(struct dma_chan_data *channel); - int (*stop)(struct dma_chan_data *channel); - int (*stop_delayed)(struct dma_chan_data *channel); - int (*copy)(struct dma_chan_data *channel, int bytes, uint32_t flags); - int (*pause)(struct dma_chan_data *channel); - int (*release)(struct dma_chan_data *channel); - int (*status)(struct dma_chan_data *channel, - struct dma_chan_status *status, uint8_t direction); - - int (*set_config)(struct dma_chan_data *channel, - struct dma_sg_config *config); - - int (*probe)(struct dma *dma); - int (*remove)(struct dma *dma); - - int (*get_data_size)(struct dma_chan_data *channel, uint32_t *avail, - uint32_t *free); - - int (*get_attribute)(struct dma *dma, uint32_t type, uint32_t *value); - - int (*interrupt)(struct dma_chan_data *channel, enum dma_irq_cmd cmd); -}; - +struct dma_ops; /* DMA platform data */ struct dma_plat_data { uint32_t id; @@ -272,6 +227,12 @@ struct dma_info { size_t num_dmas; }; +/* generic DMA DSP <-> Host copier */ +struct dma_copy { + struct dma_chan_data *chan; + struct dma *dmac; +}; + struct audio_stream; typedef int (*dma_process_func)(const struct audio_stream *source, uint32_t ioffset, struct audio_stream *sink, @@ -301,217 +262,18 @@ struct dma *dma_get(uint32_t dir, uint32_t caps, uint32_t dev, uint32_t flags); */ void dma_put(struct dma *dma); -#define dma_set_drvdata(dma, data) \ - (dma->priv_data = data) -#define dma_get_drvdata(dma) \ - dma->priv_data -#define dma_base(dma) \ - dma->plat_data.base -#define dma_irq(dma) \ - dma->plat_data.irq -#define dma_irq_name(dma) \ - dma->plat_data.irq_name -#define dma_chan_size(dma) \ - dma->plat_data.chan_size -#define dma_chan_base(dma, chan) \ - (dma->plat_data.base + chan * dma->plat_data.chan_size) -#define dma_chan_get_data(chan) \ - ((chan)->priv_data) -#define dma_chan_set_data(chan, data) \ - ((chan)->priv_data = data) - -/* DMA API - * Programming flow is :- - * - * 1) dma_channel_get() - * 2) notifier_register() - * 3) dma_set_config() - * 4) dma_start() - * ... DMA now running ... - * 5) dma_stop() - * 6) dma_stop_delayed() - * 7) dma_channel_put() - */ - -static inline struct dma_chan_data *dma_channel_get_legacy(struct dma *dma, - int req_channel) -{ - if (!dma || !dma->ops || !dma->ops->channel_get) - return NULL; - - struct dma_chan_data *chan = dma->ops->channel_get(dma, req_channel); - - return chan; -} - -static inline void dma_channel_put_legacy(struct dma_chan_data *channel) -{ - channel->dma->ops->channel_put(channel); -} - -static inline int dma_start_legacy(struct dma_chan_data *channel) -{ - return channel->dma->ops->start(channel); -} - -static inline int dma_stop_legacy(struct dma_chan_data *channel) -{ - if (channel->dma->ops->stop) - return channel->dma->ops->stop(channel); - - return 0; -} - -static inline int dma_stop_delayed_legacy(struct dma_chan_data *channel) -{ - if (channel->dma->ops->stop_delayed) - return channel->dma->ops->stop_delayed(channel); - - return 0; -} - -/** \defgroup sof_dma_copy_func static int dma_copy (struct dma_chan_data * channel, int bytes, uint32_t flags) - * - * This function is in a separate subgroup to solve a name clash with - * struct dma_copy {} - * @{ - */ -static inline int dma_copy_legacy(struct dma_chan_data *channel, int bytes, - uint32_t flags) -{ - return channel->dma->ops->copy(channel, bytes, flags); -} -/** @} */ - -static inline int dma_pause_legacy(struct dma_chan_data *channel) -{ - if (channel->dma->ops->pause) - return channel->dma->ops->pause(channel); - - return 0; -} - -static inline int dma_release_legacy(struct dma_chan_data *channel) -{ - if (channel->dma->ops->release) - return channel->dma->ops->release(channel); - - return 0; -} - -static inline int dma_status_legacy(struct dma_chan_data *channel, - struct dma_chan_status *status, uint8_t direction) -{ - return channel->dma->ops->status(channel, status, direction); -} - -static inline int dma_set_config_legacy(struct dma_chan_data *channel, - struct dma_sg_config *config) -{ - return channel->dma->ops->set_config(channel, config); -} - -static inline int dma_probe_legacy(struct dma *dma) -{ - return dma->ops->probe(dma); -} - -static inline int dma_remove_legacy(struct dma *dma) -{ - return dma->ops->remove(dma); -} - -static inline int dma_get_data_size_legacy(struct dma_chan_data *channel, - uint32_t *avail, uint32_t *free) -{ - return channel->dma->ops->get_data_size(channel, avail, free); -} - -static inline int dma_get_attribute_legacy(struct dma *dma, uint32_t type, - uint32_t *value) -{ - return dma->ops->get_attribute(dma, type, value); -} - -static inline int dma_interrupt_legacy(struct dma_chan_data *channel, - enum dma_irq_cmd cmd) -{ - return channel->dma->ops->interrupt(channel, cmd); -} - -/* DMA hardware register operations */ -static inline uint32_t dma_reg_read(struct dma *dma, uint32_t reg) -{ - return io_reg_read(dma_base(dma) + reg); -} - -static inline uint16_t dma_reg_read16(struct dma *dma, uint32_t reg) -{ - return io_reg_read16(dma_base(dma) + reg); -} - -static inline void dma_reg_write(struct dma *dma, uint32_t reg, uint32_t value) -{ - io_reg_write(dma_base(dma) + reg, value); -} - -static inline void dma_reg_write16(struct dma *dma, uint32_t reg, - uint16_t value) -{ - io_reg_write16(dma_base(dma) + reg, value); -} - -static inline void dma_reg_update_bits(struct dma *dma, uint32_t reg, - uint32_t mask, uint32_t value) -{ - io_reg_update_bits(dma_base(dma) + reg, mask, value); -} - -static inline uint32_t dma_chan_reg_read(struct dma_chan_data *channel, - uint32_t reg) -{ - return io_reg_read(dma_chan_base(channel->dma, channel->index) + reg); -} - -static inline uint16_t dma_chan_reg_read16(struct dma_chan_data *channel, - uint32_t reg) -{ - return io_reg_read16(dma_chan_base(channel->dma, channel->index) + reg); -} - -static inline void dma_chan_reg_write(struct dma_chan_data *channel, - uint32_t reg, uint32_t value) -{ - io_reg_write(dma_chan_base(channel->dma, channel->index) + reg, value); -} - -static inline void dma_chan_reg_write16(struct dma_chan_data *channel, - uint32_t reg, uint16_t value) -{ - io_reg_write16(dma_chan_base(channel->dma, channel->index) + reg, - value); -} - -static inline void dma_chan_reg_update_bits(struct dma_chan_data *channel, - uint32_t reg, uint32_t mask, - uint32_t value) -{ - io_reg_update_bits(dma_chan_base(channel->dma, channel->index) + reg, - mask, value); -} +#ifndef CONFIG_ZEPHYR_NATIVE_DRIVERS +#include "dma-legacy.h" +#endif /* !CONFIG_ZEPHYR_NATIVE_DRIVERS */ -static inline void dma_chan_reg_update_bits16(struct dma_chan_data *channel, - uint32_t reg, uint16_t mask, - uint16_t value) -{ - io_reg_update_bits16(dma_chan_base(channel->dma, channel->index) + reg, - mask, value); -} +#if defined(CONFIG_SCHEDULE_DMA_MULTI_CHANNEL) || \ + defined(CONFIG_SCHEDULE_DMA_SINGLE_CHANNEL) static inline bool dma_is_scheduling_source(struct dma_chan_data *channel) { return channel->is_scheduling_source; } +#endif static inline void dma_sg_init(struct dma_sg_elem_array *ea) { @@ -564,38 +326,6 @@ int dma_buffer_copy_to(struct comp_buffer *source, struct comp_buffer *sink, dma_process_func process, uint32_t sink_bytes, uint32_t chmap); -/* generic DMA DSP <-> Host copier */ - -struct dma_copy { - struct dma_chan_data *chan; - struct dma *dmac; -}; - -/* init dma copy context */ -int dma_copy_new(struct dma_copy *dc); - -/* free dma copy context resources */ -static inline void dma_copy_free(struct dma_copy *dc) -{ - dma_channel_put_legacy(dc->chan); -} - -/* DMA copy data from host to DSP */ -int dma_copy_from_host(struct dma_copy *dc, struct dma_sg_config *host_sg, - int32_t host_offset, void *local_ptr, int32_t size); -int dma_copy_from_host_nowait(struct dma_copy *dc, - struct dma_sg_config *host_sg, - int32_t host_offset, void *local_ptr, - int32_t size); - -/* DMA copy data from DSP to host */ -int dma_copy_to_host(struct dma_copy *dc, struct dma_sg_config *host_sg, - int32_t host_offset, void *local_ptr, int32_t size); -int dma_copy_to_host_nowait(struct dma_copy *dc, struct dma_sg_config *host_sg, - int32_t host_offset, void *local_ptr, int32_t size); - - -int dma_copy_set_stream_tag(struct dma_copy *dc, uint32_t stream_tag); static inline const struct dma_info *dma_info_get(void) {