Skip to content

Commit

Permalink
drivers: sdma: Set watermark level for PDM script
Browse files Browse the repository at this point in the history
With multi-fifo script watermark bits are defined as follows:

bits:
 31:28, channels per fifo
 27:24, software done cfg
 23:23, software done sel
 19:16, fifo offset
 15:12, number of fifos

Signed-off-by: Daniel Baluta <[email protected]>
  • Loading branch information
dbaluta committed Oct 10, 2023
1 parent b92de4d commit f7cf4bb
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 0 deletions.
43 changes: 43 additions & 0 deletions src/drivers/imx/sdma.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ struct sdma_chan {
int next_bd;
int sdma_chan_type;
int fifo_paddr;

unsigned int watermark_level;
unsigned int sw_done_sel; /* software done selector */
};

/* Private data for the whole controller */
Expand Down Expand Up @@ -438,13 +441,22 @@ static struct dma_chan_data *sdma_channel_get(struct dma *dma,

static void sdma_enable_event(struct dma_chan_data *channel, int eventnum)
{
struct sdma_chan *pdata = dma_chan_get_data(channel);

tr_dbg(&sdma_tr, "sdma_enable_event(%d, %d)", channel->index, eventnum);

if (eventnum < 0 || eventnum > SDMA_HWEVENTS_COUNT)
return; /* No change if request is invalid */

dma_reg_update_bits(channel->dma, SDMA_CHNENBL(eventnum),
BIT(channel->index), BIT(channel->index));

if (pdata->sw_done_sel & BIT(31)) {
unsigned int done0;

done0 = SDMA_DONE0_CONFIG_DONE_SEL | ~SDMA_DONE0_CONFIG_DONE_DIS;
dma_reg_update_bits(channel->dma, SDMA_DONE0_CONFIG, 0xFF, done0);
}
}

static void sdma_disable_event(struct dma_chan_data *channel, int eventnum)
Expand Down Expand Up @@ -603,6 +615,30 @@ static int sdma_status(struct dma_chan_data *channel,
return 0;
}

static void sdma_set_watermarklevel(struct dma_chan_data *chan)
{
struct sdma_chan *pdata = dma_chan_get_data(chan);

/* TODO: retrieve this information from DAI */
unsigned int n_fifos = 4;
unsigned int words_per_fifo = 1;
unsigned int sw_done_sel = 0;

/* enable sw_done_sel */
sw_done_sel |= BIT(31);

pdata->watermark_level |= SDMA_WATERMARK_LEVEL_SW_DONE |
(sw_done_sel & 0xff) << SDMA_WATERMARK_LEVEL_SW_DONE_SEL_OFF;

pdata->watermark_level |=
SDMA_WATERMARK_LEVEL_N_FIFOS(n_fifos);

pdata->watermark_level |=
SDMA_WATERMARK_LEVEL_WORDS_PER_FIFO(words_per_fifo - 1);

pdata->sw_done_sel = sw_done_sel;
}

static int sdma_read_config(struct dma_chan_data *channel,
struct dma_sg_config *config)
{
Expand Down Expand Up @@ -779,6 +815,13 @@ static int sdma_prep_desc(struct dma_chan_data *channel,

watermark = (config->burst_elems * width) / 8;

if (pdata->sdma_chan_type == SDMA_CHAN_TYPE_SAI2MCU) {
sdma_set_watermarklevel(channel);
watermark |= pdata->watermark_level;
} else {
watermark = (config->burst_elems * width) / 8;
}

memset(pdata->ctx, 0, sizeof(*pdata->ctx));
pdata->ctx->pc = sdma_script_addr;

Expand Down
9 changes: 9 additions & 0 deletions src/include/sof/drivers/sdma.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,15 @@
#define SDMA_DONE0_CONFIG 0x1000
#define SDMA_DONE1_CONFIG 0x1004

#define SDMA_DONE0_CONFIG_DONE_SEL BIT(7)
#define SDMA_DONE0_CONFIG_DONE_DIS BIT(6)

#define SDMA_WATERMARK_LEVEL_N_FIFOS(x) SET_BITS(15, 12, x)
#define SDMA_WATERMARK_LEVEL_OFF_FIFOS(x) SET_BITS(19, 16, x)
#define SDMA_WATERMARK_LEVEL_WORDS_PER_FIFO(x) SET_BITS(31, 28, x)
#define SDMA_WATERMARK_LEVEL_SW_DONE BIT(23)
#define SDMA_WATERMARK_LEVEL_SW_DONE_SEL_OFF 24

/* Buffer descriptor first word */
/* Count: Data buffer size, in words */
#define SDMA_BD_COUNT_MASK MASK(15, 0)
Expand Down

0 comments on commit f7cf4bb

Please sign in to comment.