summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShengjiu Wang <shengjiu.wang@nxp.com>2019-09-12 10:16:55 +0800
committerDong Aisheng <aisheng.dong@nxp.com>2019-11-25 15:48:51 +0800
commite5b7fd131b892dc52049640eadc8accaadf41f7f (patch)
treec81023e5071ae7f10c928ed57deffc51d30c546c
parent2e30be00cd2bf7ce2cd3b814b6777cd749012b47 (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> (cherry picked from commit 5a15d81a1c19c07846cc394d935524566bcfb298)
-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 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);
diff --git a/sound/soc/fsl/fsl_easrc.h b/sound/soc/fsl/fsl_easrc.h
index 529c3c4e2ee0..93ee99725afb 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 {