From e5b7fd131b892dc52049640eadc8accaadf41f7f Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Thu, 12 Sep 2019 10:16:55 +0800 Subject: MLK-22575-1: ASoC: fsl_easrc: configure slot according to pf memory size The maximum prefilter memory size is 6144 entry, it is not allowed to require memory size exceed this size. When we calculate the available channel in the context processer, we need to consider if the prefilter memory is not enough for the maxmum channels, then we need to reduce the channels in this context processor, move the left channel to another context processor. Signed-off-by: Shengjiu Wang (cherry picked from commit 5a15d81a1c19c07846cc394d935524566bcfb298) --- sound/soc/fsl/fsl_easrc.c | 64 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 55 insertions(+), 9 deletions(-) (limited to 'sound/soc/fsl/fsl_easrc.c') diff --git a/sound/soc/fsl/fsl_easrc.c b/sound/soc/fsl/fsl_easrc.c index 057a2664b6a0..d45f4cc75065 100644 --- a/sound/soc/fsl/fsl_easrc.c +++ b/sound/soc/fsl/fsl_easrc.c @@ -753,6 +753,38 @@ ctx_error: return ret; } +static int fsl_easrc_max_ch_for_slot(struct fsl_easrc_context *ctx, + struct fsl_easrc_slot *slot) +{ + int st1_mem_alloc = 0, st2_mem_alloc = 0; + int pf_mem_alloc = 0; + int max_channels = 8 - slot->num_channel; + int channels = 0; + + if (ctx->st1_num_taps > 0) { + if (ctx->st2_num_taps > 0) + st1_mem_alloc = + (ctx->st1_num_taps - 1) * ctx->st1_num_exp + 1; + else + st1_mem_alloc = ctx->st1_num_taps; + } + + if (ctx->st2_num_taps > 0) + st2_mem_alloc = ctx->st2_num_taps; + + pf_mem_alloc = st1_mem_alloc + st2_mem_alloc; + + if (pf_mem_alloc != 0) + channels = (6144 - slot->pf_mem_used) / pf_mem_alloc; + else + channels = 8; + + if (channels < max_channels) + max_channels = channels; + + return max_channels; +} + /* fsl_easrc_config_slot * * A single context can be split amongst any of the 4 context processing pipes @@ -784,7 +816,11 @@ static int fsl_easrc_config_slot(struct fsl_easrc *easrc, unsigned int ctx_id) continue; if (!slot0->busy && !slot1->busy) { - if (req_channels <= 8) { + avail_channel = fsl_easrc_max_ch_for_slot(ctx, slot1); + if (avail_channel <= 0) + continue; + + if (req_channels <= avail_channel) { slot0->num_channel = req_channels; slot0->min_channel = start_channel; slot0->max_channel = @@ -795,13 +831,14 @@ static int fsl_easrc_config_slot(struct fsl_easrc *easrc, unsigned int ctx_id) req_channels = 0; continue_loop = false; } else { - slot0->num_channel = 8; + slot0->num_channel = avail_channel; slot0->min_channel = start_channel; - slot0->max_channel = start_channel + 7; + slot0->max_channel = + start_channel + avail_channel - 1; slot0->ctx_index = ctx->index; slot0->busy = true; - start_channel += 8; - req_channels -= 8; + start_channel += avail_channel; + req_channels -= avail_channel; continue_loop = true; } @@ -844,6 +881,7 @@ static int fsl_easrc_config_slot(struct fsl_easrc *easrc, unsigned int ctx_id) st1_mem_alloc = ctx->st1_num_taps * slot0->num_channel; + slot0->pf_mem_used = st1_mem_alloc; ret = regmap_update_bits(easrc->regmap, REG_EASRC_DPCS0R2(i), EASRC_DPCS0R2_ST1_MA_MASK, @@ -873,6 +911,7 @@ static int fsl_easrc_config_slot(struct fsl_easrc *easrc, unsigned int ctx_id) st2_mem_alloc = slot0->num_channel * ctx->st2_num_taps; + slot0->pf_mem_used += st2_mem_alloc; ret = regmap_update_bits(easrc->regmap, REG_EASRC_DPCS0R3(i), EASRC_DPCS0R3_ST2_MA_MASK, @@ -905,8 +944,7 @@ static int fsl_easrc_config_slot(struct fsl_easrc *easrc, unsigned int ctx_id) if (slot0->ctx_index == ctx->index) continue; - avail_channel = 8 - slot0->num_channel; - + avail_channel = fsl_easrc_max_ch_for_slot(ctx, slot0); if (avail_channel <= 0) continue; @@ -971,6 +1009,7 @@ static int fsl_easrc_config_slot(struct fsl_easrc *easrc, unsigned int ctx_id) st1_mem_alloc = ctx->st1_num_taps * slot1->num_channel; + slot1->pf_mem_used = st1_mem_alloc; ret = regmap_update_bits(easrc->regmap, REG_EASRC_DPCS1R2(i), EASRC_DPCS0R2_ST1_MA_MASK, @@ -1001,6 +1040,7 @@ static int fsl_easrc_config_slot(struct fsl_easrc *easrc, unsigned int ctx_id) st2_mem_alloc = slot1->num_channel * ctx->st2_num_taps; + slot1->pf_mem_used += st2_mem_alloc; ret = regmap_update_bits(easrc->regmap, REG_EASRC_DPCS1R3(i), EASRC_DPCS0R3_ST2_MA_MASK, @@ -1035,7 +1075,7 @@ static int fsl_easrc_config_slot(struct fsl_easrc *easrc, unsigned int ctx_id) if (slot1->ctx_index == ctx->index) continue; - avail_channel = 8 - slot1->num_channel; + avail_channel = fsl_easrc_max_ch_for_slot(ctx, slot1); if (avail_channel <= 0) continue; @@ -1101,6 +1141,7 @@ static int fsl_easrc_config_slot(struct fsl_easrc *easrc, unsigned int ctx_id) st1_mem_alloc = ctx->st1_num_taps * slot0->num_channel; + slot0->pf_mem_used = st1_mem_alloc; ret = regmap_update_bits(easrc->regmap, REG_EASRC_DPCS0R2(i), EASRC_DPCS0R2_ST1_MA_MASK, @@ -1130,6 +1171,7 @@ static int fsl_easrc_config_slot(struct fsl_easrc *easrc, unsigned int ctx_id) st2_mem_alloc = slot0->num_channel * ctx->st2_num_taps; + slot0->pf_mem_used += st2_mem_alloc; ret = regmap_update_bits(easrc->regmap, REG_EASRC_DPCS0R3(i), EASRC_DPCS0R3_ST2_MA_MASK, @@ -1160,7 +1202,7 @@ static int fsl_easrc_config_slot(struct fsl_easrc *easrc, unsigned int ctx_id) } if (req_channels > 0) { - dev_err(&easrc->pdev->dev, "no avail slot, should not happen\n"); + dev_err(&easrc->pdev->dev, "no avail slot.\n"); return -EINVAL; } @@ -1180,6 +1222,8 @@ static int fsl_easrc_release_slot(struct fsl_easrc *easrc, unsigned int ctx_id) if (easrc->slot[i][0].busy && easrc->slot[i][0].ctx_index == ctx->index) { easrc->slot[i][0].busy = false; + easrc->slot[i][0].num_channel = 0; + easrc->slot[i][0].pf_mem_used = 0; /* set registers */ ret = regmap_write(easrc->regmap, REG_EASRC_DPCS0R0(i), 0); @@ -1205,6 +1249,8 @@ static int fsl_easrc_release_slot(struct fsl_easrc *easrc, unsigned int ctx_id) if (easrc->slot[i][1].busy && easrc->slot[i][1].ctx_index == ctx->index) { easrc->slot[i][1].busy = false; + easrc->slot[i][1].num_channel = 0; + easrc->slot[i][1].pf_mem_used = 0; /* set registers */ ret = regmap_write(easrc->regmap, REG_EASRC_DPCS1R0(i), 0); -- cgit v1.2.3