drivers: imx: edma: parameterize iteration size on FIFO size

various interfaces e.g. SAI or ESAI have different
FIFO size: EDMA has to take into account this when
programming the iteration size

Signed-off-by: Guido Roncarolo <guido.roncarolo@nxp.com>
Signed-off-by: Jerome Laclavere <jerome.laclavere@nxp.com>
This commit is contained in:
Guido Roncarolo 2019-10-16 17:06:26 +02:00 committed by Daniel Baluta
parent 61b0b58865
commit 830ecf323c
3 changed files with 24 additions and 6 deletions

View File

@ -796,6 +796,10 @@ static int dai_config(struct comp_dev *dev, struct sof_ipc_dai_config *config)
trace_dai_with_ids(dev, "dai_config(), channel = %d",
channel);
break;
case SOF_DAI_IMX_SAI:
dd->config.burst_elems =
dd->dai->plat_data.fifo[dev->params.direction].depth;
break;
default:
/* other types of DAIs not handled for now */
trace_dai_error_with_ids(dev, "dai_config() error: Handling of "

View File

@ -260,10 +260,10 @@ static int edma_validate_nonsg_config(struct dma_sg_elem_array *sgelems,
static int edma_setup_tcd(struct dma_chan_data *channel, uint16_t soff,
uint16_t doff, bool cyclic, bool sg, bool irqoff,
struct dma_sg_elem_array *sgelems, int src_width,
int dest_width)
int dest_width, uint32_t burst_elems)
{
int rc;
uint32_t sbase, dbase, total_size, elem_count, elem_size;
uint32_t sbase, dbase, total_size, elem_count, elem_size, size;
assert(!sg);
assert(cyclic);
@ -293,6 +293,13 @@ static int edma_setup_tcd(struct dma_chan_data *channel, uint16_t soff,
elem_count = 2;
elem_size = total_size / elem_count;
size = MIN(elem_size, burst_elems);
while (size >= 4U) {
if ((elem_size % size) == 0UL)
break;
size -= 1U;
}
assert(size >= 4U);
rc = edma_encode_tcd_attr(src_width, dest_width);
if (rc < 0)
return rc;
@ -301,14 +308,14 @@ static int edma_setup_tcd(struct dma_chan_data *channel, uint16_t soff,
dma_chan_reg_write(channel, EDMA_TCD_SADDR, sbase);
dma_chan_reg_write16(channel, EDMA_TCD_SOFF, soff);
dma_chan_reg_write16(channel, EDMA_TCD_ATTR, rc);
dma_chan_reg_write(channel, EDMA_TCD_NBYTES, elem_size);
dma_chan_reg_write(channel, EDMA_TCD_NBYTES, size);
dma_chan_reg_write(channel, EDMA_TCD_SLAST, -total_size * SGN(soff));
dma_chan_reg_write(channel, EDMA_TCD_DADDR, dbase);
dma_chan_reg_write16(channel, EDMA_TCD_DOFF, doff);
dma_chan_reg_write16(channel, EDMA_TCD_CITER, elem_count);
dma_chan_reg_write16(channel, EDMA_TCD_CITER, total_size / size);
dma_chan_reg_write(channel, EDMA_TCD_DLAST_SGA,
-total_size * SGN(doff));
dma_chan_reg_write16(channel, EDMA_TCD_BITER, elem_count);
dma_chan_reg_write16(channel, EDMA_TCD_BITER, total_size / size);
dma_chan_reg_write16(channel, EDMA_TCD_CSR, 0);
channel->status = COMP_STATE_PREPARE;
@ -361,7 +368,7 @@ static int edma_set_config(struct dma_chan_data *channel,
return edma_setup_tcd(channel, soff, doff, config->cyclic,
config->scatter, config->irq_disabled,
&config->elem_array, config->src_width,
config->dest_width);
config->dest_width, config->burst_elems);
}
/* restore DMA context after leaving D3 */

View File

@ -31,11 +31,18 @@ static struct dai sai[] = {
.base = SAI_1_BASE,
.fifo[SOF_IPC_STREAM_PLAYBACK] = {
.offset = SAI_1_BASE + REG_SAI_TDR0,
/* use depth to model the HW FIFO size:
* each channel includes a 64 x 32 bit FIFO
* that can be accessed using Transmit or
* Receive Data Registers
*/
.depth = 64, /* in 4 bytes words */
.handshake = EDMA_HANDSHAKE(EDMA0_SAI_CHAN_TX_IRQ,
EDMA0_SAI_CHAN_TX),
},
.fifo[SOF_IPC_STREAM_CAPTURE] = {
.offset = SAI_1_BASE + REG_SAI_RDR0,
.depth = 64, /* in 4 bytes words */
.handshake = EDMA_HANDSHAKE(EDMA0_SAI_CHAN_RX_IRQ,
EDMA0_SAI_CHAN_RX),
},