Skip to content

Commit

Permalink
zephyr: sof/lib: split dma.h to dma.h and dma-legacy.h
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
kv2019i committed Dec 13, 2024
1 parent 0afc8ac commit 6d18ca5
Show file tree
Hide file tree
Showing 2 changed files with 299 additions and 283 deletions.
286 changes: 286 additions & 0 deletions zephyr/include/sof/lib/dma-legacy.h
Original file line number Diff line number Diff line change
@@ -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__ */
Loading

0 comments on commit 6d18ca5

Please sign in to comment.