This patch adds a new dma op for retreiving the number of channels in use in a given DMAC. This will be useful in providing basic and primitive QoS while allocating DMAC for various users.
Signed-off-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com --- src/drivers/dw-dma.c | 19 +++++++++++++++++++ src/drivers/hda-dma.c | 20 ++++++++++++++++++++ src/include/sof/dma.h | 7 +++++++ 3 files changed, 46 insertions(+)
diff --git a/src/drivers/dw-dma.c b/src/drivers/dw-dma.c index c064330..0ed742f 100644 --- a/src/drivers/dw-dma.c +++ b/src/drivers/dw-dma.c @@ -289,6 +289,24 @@ static inline void dw_update_bits(struct dma *dma, uint32_t reg, uint32_t mask, io_reg_update_bits(dma_base(dma) + reg, mask, value); }
+/* get the number of DMA channels in use */ +static int dw_dma_channel_status(struct dma *dma) +{ + struct dma_pdata *p = dma_get_drvdata(dma); + int i, count = 0; + + trace_dma("Dct"); + + for (i = 0; i < DW_MAX_CHAN; i++) { + + /* find channels in use */ + if (p->chan[i].status != COMP_STATE_INIT) + count++; + } + + return count; +} + /* allocate next free DMA channel */ static int dw_dma_channel_get(struct dma *dma, int req_chan) { @@ -1177,6 +1195,7 @@ static int dw_dma_probe(struct dma *dma) const struct dma_ops dw_dma_ops = { .channel_get = dw_dma_channel_get, .channel_put = dw_dma_channel_put, + .channel_status = dw_dma_channel_status, .start = dw_dma_start, .stop = dw_dma_stop, .pause = dw_dma_pause, diff --git a/src/drivers/hda-dma.c b/src/drivers/hda-dma.c index 97ea0ef..0e88a35 100644 --- a/src/drivers/hda-dma.c +++ b/src/drivers/hda-dma.c @@ -131,6 +131,24 @@ static int hda_dma_copy(struct dma *dma, int channel, int bytes) return 0; }
+/* get the number of DMA channels in use */ +static int hda_dma_channel_status(struct dma *dma) +{ + struct dma_pdata *p = dma_get_drvdata(dma); + int i, count = 0; + + trace_host("Dct"); + + for (i = 0; i < HDA_DMA_MAX_CHANS; i++) { + + /* find channels in use */ + if (p->chan[i].status != COMP_STATE_INIT) + count++; + } + + return count; +} + /* acquire the specific DMA channel */ static int hda_dma_channel_get(struct dma *dma, int channel) { @@ -406,6 +424,7 @@ static int hda_dma_probe(struct dma *dma) const struct dma_ops hda_host_dma_ops = { .channel_get = hda_dma_channel_get, .channel_put = hda_dma_channel_put, + .channel_status = hda_dma_channel_status, .start = hda_dma_start, .stop = hda_dma_stop, .copy = hda_dma_copy, @@ -422,6 +441,7 @@ const struct dma_ops hda_host_dma_ops = { const struct dma_ops hda_link_dma_ops = { .channel_get = hda_dma_channel_get, .channel_put = hda_dma_channel_put, + .channel_status = hda_dma_channel_status, .start = hda_dma_start, .stop = hda_dma_stop, .copy = hda_dma_copy, diff --git a/src/include/sof/dma.h b/src/include/sof/dma.h index 80ca880..1de9efc 100644 --- a/src/include/sof/dma.h +++ b/src/include/sof/dma.h @@ -93,6 +93,7 @@ struct dma_ops {
int (*channel_get)(struct dma *dma, int req_channel); void (*channel_put)(struct dma *dma, int channel); + int (*channel_status)(struct dma *dma);
int (*start)(struct dma *dma, int channel); int (*stop)(struct dma *dma, int channel); @@ -178,6 +179,12 @@ static inline void dma_channel_put(struct dma *dma, int channel) dma->ops->channel_put(dma, channel); }
+/* get the number of DMA channels in use */ +static inline int dma_channel_status(struct dma *dma) +{ + return dma->ops->channel_status(dma); +} + static inline int dma_set_cb(struct dma *dma, int channel, int type, void (*cb)(void *data, uint32_t type, struct dma_sg_elem *next), void *data) {