mirror of https://github.com/thesofproject/sof.git
drivers: sdma: Set watermark level for PDM
In order to enable PDM we need to use Multi-fifo support and mcu_2_sai RAM script. This script defines watermark level as follows: r7 = Watermark bit0~11: watermark level(wml*fifo_number) bit15~12: to do-fifo number bit16~19: fifo offset bit27~24: sw done selector bit28~31: # audio channels in one frame, 0: 1 channel,1: 2 channels bit23: sw done enabled Configuration parameters should come from DAI (PDM in our specific case) but there is no easy way to forward such information so we just make use of some default configuration, 4 fifos, 1 channel per fifo, sw done enabled. Signed-off-by: Daniel Baluta <daniel.baluta@nxp.com>
This commit is contained in:
parent
5f0d6222e7
commit
4c7b69b1c4
|
@ -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 */
|
||||
|
@ -603,6 +606,47 @@ 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; /* number of HW fifos used */
|
||||
unsigned int words_per_fifo = 1; /* number of audio channels per frame */
|
||||
|
||||
/* sw_done_sel mimics software done configuration from Linux
|
||||
* see Documentation/devicetree/bindings/fsl-imx-sdma.txt
|
||||
*/
|
||||
unsigned int sw_done_sel = 0;
|
||||
|
||||
/* sw_done_sel configuration
|
||||
* - bit31: sw_done
|
||||
* - bit15:8 selector
|
||||
* - bit7-0 priority
|
||||
*/
|
||||
sw_done_sel |= BIT(31);
|
||||
|
||||
/* watermark level:
|
||||
* bit0~11: wartermark level(wml*fifo_number)
|
||||
* bit15~12: to do-fifo number
|
||||
* bit16~19: fifo offset
|
||||
* bit27~24: sw done selector
|
||||
* bit28~31: numbers of audio channels in one frame, 0: 1 channel,1: 2 channels
|
||||
* bit23: sw done enable
|
||||
*/
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -779,6 +823,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;
|
||||
|
||||
|
|
|
@ -89,6 +89,12 @@
|
|||
#define SDMA_DONE0_CONFIG 0x1000
|
||||
#define SDMA_DONE1_CONFIG 0x1004
|
||||
|
||||
#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)
|
||||
|
|
Loading…
Reference in New Issue