summaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorShengjiu Wang <shengjiu.wang@nxp.com>2019-09-12 10:16:55 +0800
committerShengjiu Wang <shengjiu.wang@nxp.com>2019-09-14 13:43:31 +0800
commit5a15d81a1c19c07846cc394d935524566bcfb298 (patch)
tree763583b4decced1f809dc3ca5eeac6dcf8e7c70a /sound
parentbd0df48e7a3a78311974ba4523eba3ce368ada2a (diff)
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 <shengjiu.wang@nxp.com>
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/fsl/fsl_easrc.c64
-rw-r--r--sound/soc/fsl/fsl_easrc.h1
2 files changed, 56 insertions, 9 deletions
diff --git a/sound/soc/fsl/fsl_easrc.c b/sound/soc/fsl/fsl_easrc.c
index f260f3fb4d3f..af20f0b3f850 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);
diff --git a/sound/soc/fsl/fsl_easrc.h b/sound/soc/fsl/fsl_easrc.h
index 09b50e06e433..289a98c374d1 100644
--- a/sound/soc/fsl/fsl_easrc.h
+++ b/sound/soc/fsl/fsl_easrc.h
@@ -607,6 +607,7 @@ struct fsl_easrc_slot {
int num_channel; /*maximum is 8*/
int min_channel;
int max_channel;
+ int pf_mem_used;
};
struct fsl_easrc_context {