From bb32df9ef0c72794d2f01033bf1eecf03ec080e5 Mon Sep 17 00:00:00 2001 From: Xing Wang Date: Fri, 8 Mar 2019 16:19:51 +0800 Subject: [PATCH] audio: auge: modify share buffer can be occupied by later module [1/2] PD#SWPL-5300 Problem: share buffer is not alaway used for tdm and spdif, but raw data needs to output by spdif. this would lead to spk silence for dual output Solution: share buffer can be occupied by later module. when tdm and spdif output in share buffer, then play spdif, spdif will release from share buffer, only frddr is only used for tdm, another new frddr is used for spdif. Verify: x301 Change-Id: Ib0c2e02e575f496c0b0911d347857ede0d0cfa14 Signed-off-by: Xing Wang --- sound/soc/amlogic/auge/ddr_mngr.c | 226 ++++++++++++++++++------------ sound/soc/amlogic/auge/ddr_mngr.h | 5 + 2 files changed, 145 insertions(+), 86 deletions(-) diff --git a/sound/soc/amlogic/auge/ddr_mngr.c b/sound/soc/amlogic/auge/ddr_mngr.c index 3652ace2690a..69d96f45c661 100644 --- a/sound/soc/amlogic/auge/ddr_mngr.c +++ b/sound/soc/amlogic/auge/ddr_mngr.c @@ -921,33 +921,6 @@ struct frddr *fetch_frddr_by_src(int frddr_src) return NULL; } -/* - * check frddr_src is used by other frddr for sharebuffer - * if used, disabled the other share frddr src, the module would - * for current frddr, and the checked frddr - */ -int aml_check_sharebuffer_valid(struct frddr *fr, int ss_sel) -{ - int current_fifo_id = fr->fifo_id; - unsigned int i; - int ret = 1; - - for (i = 0; i < DDRMAX; i++) { - if (frddrs[i].in_use - && (frddrs[i].fifo_id != current_fifo_id) - && (frddrs[i].dest == ss_sel)) { - - pr_info("%s, ss_sel:%d used, not for share buffer at same time\n", - __func__, - ss_sel); - ret = 0; - break; - } - } - - return ret; -} - struct frddr *aml_audio_register_frddr(struct device *dev, struct aml_audio_controller *actrl, irq_handler_t handler, void *data) @@ -976,6 +949,137 @@ static inline unsigned int return base + reg - EE_AUDIO_FRDDR_A_CTRL0; } +/* + * check frddr_src is used by other frddr for sharebuffer + * if used, disabled the other share frddr src, the module would + * for current frddr, and the checked frddr + */ +int aml_check_sharebuffer_valid(struct frddr *fr, int ss_sel) +{ + int current_fifo_id = fr->fifo_id; + unsigned int i; + int ret = 1; + + for (i = 0; i < DDRMAX; i++) { + if (frddrs[i].in_use + && (frddrs[i].fifo_id != current_fifo_id) + && (frddrs[i].dest == ss_sel)) { + + pr_debug("%s, ss_sel:%d used, not for share buffer at same time\n", + __func__, + ss_sel); + ret = 0; + break; + } + } + + return ret; +} + +/* select dst for same source + * sel: share buffer req_sel 1~2 + * sel 0 is aleardy used for reg_frddr_src_sel1 + * sel 1 is for reg_frddr_src_sel2 + * sel 2 is for reg_frddr_src_sel3 + */ +static void frddr_set_sharebuffer_enable( + struct frddr *fr, int dst, int sel, bool enable) +{ + struct aml_audio_controller *actrl = fr->actrl; + unsigned int reg_base = fr->reg_base; + unsigned int reg; + int s_v = 0, s_m = 0; + + if (fr->chipinfo + && fr->chipinfo->src_sel_ctrl) { + reg = calc_frddr_address(EE_AUDIO_FRDDR_A_CTRL2, + reg_base); + + switch (sel) { + case 1: + s_m = 0x17 << 8; + s_v = enable ? + (dst << 8 | 1 << 12) : 0 << 8; + break; + case 2: + s_m = 0x17 << 16; + s_v = enable ? + (dst << 16 | 1 << 20) : 0 << 16; + break; + default: + pr_warn_once("sel :%d is not supported for same source\n", + sel); + break; + } + s_m |= 0xff << 24; + if (enable) + s_v |= (fr->channels - 1) << 24; + else + s_v |= 0x0 << 24; + } else { + reg = calc_frddr_address(EE_AUDIO_FRDDR_A_CTRL0, + reg_base); + + switch (sel) { + case 1: + s_m = 0xf << 4; + s_v = enable ? + (dst << 4 | 1 << 7) : 0 << 4; + break; + case 2: + s_m = 0xf << 8; + s_v = enable ? + (dst << 8 | 1 << 11) : 0 << 8; + break; + default: + pr_warn_once("sel :%d is not supported for same source\n", + sel); + break; + } + } + pr_debug("%s sel:%d, dst_src:%d\n", + __func__, sel, dst); + fr->ss_dest = enable ? dst : 0; + fr->ss_en = enable; + + aml_audiobus_update_bits(actrl, reg, s_m, s_v); +} + +/* + * check frddr_src is used by other frddr for sharebuffer + * if used for share frddr src, release from sharebuffer + * and used for new frddr + */ +static int aml_check_and_release_sharebuffer(struct frddr *fr, int ss_sel) +{ + int current_fifo_id = fr->fifo_id; + unsigned int i; + int ret = 1; + + for (i = 0; i < DDRMAX; i++) { + struct frddr *from = &frddrs[i]; + + if (from->in_use + && (from->fifo_id != current_fifo_id) + && from->ss_en + && (from->ss_dest == ss_sel)) { + + frddr_set_sharebuffer_enable(from, + ss_sel, + 1, + false); + + pr_debug("%s, ss_sel:%d release from share buffer, use for new playback\n", + __func__, + ss_sel); + ret = 0; + break; + } + } + + return ret; +} + int aml_frddr_set_buf(struct frddr *fr, unsigned int start, unsigned int end) { @@ -1066,6 +1170,11 @@ void aml_frddr_select_dst(struct frddr *fr, enum frddr_dest dst) src_sel_en = 3; } + /* if sharebuffer in use, release it */ + if (fr->chipinfo + && fr->chipinfo->same_src_fn) + aml_check_and_release_sharebuffer(fr, dst); + aml_audiobus_update_bits(actrl, reg, 0x7, dst & 0x7); /* same source en */ @@ -1085,69 +1194,14 @@ void aml_frddr_select_dst(struct frddr *fr, enum frddr_dest dst) void aml_frddr_select_dst_ss(struct frddr *fr, enum frddr_dest dst, int sel, bool enable) { - struct aml_audio_controller *actrl = fr->actrl; - unsigned int reg_base = fr->reg_base; - unsigned int reg, ss_valid; - - ss_valid = aml_check_sharebuffer_valid(fr, dst); + unsigned int ss_valid = aml_check_sharebuffer_valid(fr, dst); /* same source en */ if (fr->chipinfo && fr->chipinfo->same_src_fn - && ss_valid) { - int s_v = 0, s_m = 0; - - if (fr->chipinfo - && fr->chipinfo->src_sel_ctrl) { - reg = calc_frddr_address(EE_AUDIO_FRDDR_A_CTRL2, - reg_base); - - switch (sel) { - case 1: - s_m = 0x17 << 8; - s_v = enable ? - (dst << 8 | 1 << 12) : 0 << 8; - break; - case 2: - s_m = 0x17 << 16; - s_v = enable ? - (dst << 16 | 1 << 20) : 0 << 16; - break; - default: - pr_warn_once("sel :%d is not supported for same source\n", - sel); - break; - } - s_m |= 0xff << 24; - if (enable) - s_v |= (fr->channels - 1) << 24; - else - s_v |= 0x0 << 24; - } else { - reg = calc_frddr_address(EE_AUDIO_FRDDR_A_CTRL0, - reg_base); - - switch (sel) { - case 1: - s_m = 0xf << 4; - s_v = enable ? - (dst << 4 | 1 << 7) : 0 << 4; - break; - case 2: - s_m = 0xf << 8; - s_v = enable ? - (dst << 8 | 1 << 11) : 0 << 8; - break; - default: - pr_warn_once("sel :%d is not supported for same source\n", - sel); - break; - } - } - pr_debug("%s sel:%d, dst_src:%d\n", - __func__, sel, dst); - aml_audiobus_update_bits(actrl, reg, s_m, s_v); - } + && ss_valid + ) + frddr_set_sharebuffer_enable(fr, dst, sel, enable); } void aml_frddr_set_fifos(struct frddr *fr, diff --git a/sound/soc/amlogic/auge/ddr_mngr.h b/sound/soc/amlogic/auge/ddr_mngr.h index ab1c795b64b1..7f3131b9663b 100644 --- a/sound/soc/amlogic/auge/ddr_mngr.h +++ b/sound/soc/amlogic/auge/ddr_mngr.h @@ -214,6 +214,11 @@ struct frddr { //struct ddr_desc dscrpt; struct device *dev; enum frddr_dest dest; + + /* dest for same source, whether enable */ + enum frddr_dest ss_dest; + bool ss_en; + struct aml_audio_controller *actrl; unsigned int reg_base; unsigned int fifo_id;