From a00d72b1762205a285d8dc79dffae8254d7e6999 Mon Sep 17 00:00:00 2001 From: Xing Wang Date: Sat, 29 Dec 2018 19:14:23 +0800 Subject: [PATCH] audio: auge: fix sharebuffer channel map [1/1] PD#SWPL-2645 Problem: play ddp source, then play pcm source, no sound Solution: 1. fix same source control and channel map issue 2. i2s 8ch, spdif 2ch, channels are not mapped, make spdif 8 channel mask 3. when same source used, keep mpll use same mpll Verify: x301 Change-Id: I2fe4bbcbcbfff0a1c1a6cebf61d1da5aba9b7a9d Signed-off-by: Xing Wang --- arch/arm/boot/dts/amlogic/tl1_t962x2_t309.dts | 2 +- arch/arm/boot/dts/amlogic/tl1_t962x2_x301.dts | 2 +- .../boot/dts/amlogic/tl1_t962x2_t309.dts | 2 +- .../boot/dts/amlogic/tl1_t962x2_x301.dts | 2 +- sound/soc/amlogic/auge/ddr_mngr.c | 83 ++++++++++++++----- sound/soc/amlogic/auge/ddr_mngr.h | 5 +- sound/soc/amlogic/auge/sharebuffer.c | 11 ++- sound/soc/amlogic/auge/spdif.c | 4 +- sound/soc/amlogic/auge/spdif_hw.c | 17 ++-- sound/soc/amlogic/auge/spdif_hw.h | 2 +- sound/soc/amlogic/auge/tdm.c | 4 +- 11 files changed, 98 insertions(+), 36 deletions(-) diff --git a/arch/arm/boot/dts/amlogic/tl1_t962x2_t309.dts b/arch/arm/boot/dts/amlogic/tl1_t962x2_t309.dts index c202e31175a0..f66adf66bce3 100644 --- a/arch/arm/boot/dts/amlogic/tl1_t962x2_t309.dts +++ b/arch/arm/boot/dts/amlogic/tl1_t962x2_t309.dts @@ -1227,7 +1227,7 @@ clocks = <&clkaudio CLKID_AUDIO_MCLK_A &clkc CLKID_MPLL0 - &clkc CLKID_MPLL1>; + &clkc CLKID_MPLL0>; clock-names = "mclk", "clk_srcpll", "samesource_sysclk"; pinctrl-names = "tdm_pins"; diff --git a/arch/arm/boot/dts/amlogic/tl1_t962x2_x301.dts b/arch/arm/boot/dts/amlogic/tl1_t962x2_x301.dts index ab777dc3651b..3f76bb2366f8 100644 --- a/arch/arm/boot/dts/amlogic/tl1_t962x2_x301.dts +++ b/arch/arm/boot/dts/amlogic/tl1_t962x2_x301.dts @@ -1230,7 +1230,7 @@ clocks = <&clkaudio CLKID_AUDIO_MCLK_A &clkc CLKID_MPLL0 - &clkc CLKID_MPLL1>; + &clkc CLKID_MPLL0>; clock-names = "mclk", "clk_srcpll", "samesource_sysclk"; pinctrl-names = "tdm_pins"; diff --git a/arch/arm64/boot/dts/amlogic/tl1_t962x2_t309.dts b/arch/arm64/boot/dts/amlogic/tl1_t962x2_t309.dts index fff3ee0cfcab..6d524a08cef4 100644 --- a/arch/arm64/boot/dts/amlogic/tl1_t962x2_t309.dts +++ b/arch/arm64/boot/dts/amlogic/tl1_t962x2_t309.dts @@ -1225,7 +1225,7 @@ clocks = <&clkaudio CLKID_AUDIO_MCLK_A &clkc CLKID_MPLL0 - &clkc CLKID_MPLL1>; + &clkc CLKID_MPLL0>; clock-names = "mclk", "clk_srcpll", "samesource_sysclk"; pinctrl-names = "tdm_pins"; diff --git a/arch/arm64/boot/dts/amlogic/tl1_t962x2_x301.dts b/arch/arm64/boot/dts/amlogic/tl1_t962x2_x301.dts index d38ca7ae42ce..b03a5d3851d3 100644 --- a/arch/arm64/boot/dts/amlogic/tl1_t962x2_x301.dts +++ b/arch/arm64/boot/dts/amlogic/tl1_t962x2_x301.dts @@ -1225,7 +1225,7 @@ clocks = <&clkaudio CLKID_AUDIO_MCLK_A &clkc CLKID_MPLL0 - &clkc CLKID_MPLL1>; + &clkc CLKID_MPLL0>; clock-names = "mclk", "clk_srcpll", "samesource_sysclk"; pinctrl-names = "tdm_pins"; diff --git a/sound/soc/amlogic/auge/ddr_mngr.c b/sound/soc/amlogic/auge/ddr_mngr.c index 5de6bab42f97..968ec445b86d 100644 --- a/sound/soc/amlogic/auge/ddr_mngr.c +++ b/sound/soc/amlogic/auge/ddr_mngr.c @@ -709,7 +709,8 @@ void aml_pwrdet_enable(bool enable, int pwrdet_module) if (attach_pwrdet.status == RUNNING) { struct toddr *to = fetch_toddr_by_src(pwrdet_module); - aml_set_pwrdet(to, enable); + if (to) + aml_set_pwrdet(to, enable); } attach_pwrdet.status = DISABLED; } @@ -941,7 +942,8 @@ int aml_check_sharebuffer_valid(struct frddr *fr, int ss_sel) && (frddrs[i].fifo_id != current_fifo_id) && (frddrs[i].dest == ss_sel)) { - pr_info("ss_sel:%d used, invalid for share buffer\n", + pr_info(" frddr:%d, ss_sel:%d used, invalid for share buffer\n", + i, ss_sel); ret = 0; break; @@ -1035,9 +1037,18 @@ void aml_frddr_enable(struct frddr *fr, bool enable) /* ensure disable before enable frddr */ aml_audiobus_update_bits(actrl, reg, 1<<31, enable<<31); - if (!enable) + if (!enable) { aml_audiobus_write(actrl, reg, 0x0); + /* clr src sel and its en */ + if (fr->chipinfo + && fr->chipinfo->src_sel_ctrl) { + reg = calc_frddr_address(EE_AUDIO_FRDDR_A_CTRL2, + reg_base); + aml_audiobus_write(actrl, reg, 0x0); + } + } + /* check for Audio EQ/DRC */ if (aml_check_aed_module(fr->dest)) aml_check_aed(enable, fr->dest); @@ -1083,8 +1094,6 @@ void aml_frddr_select_dst_ss(struct frddr *fr, unsigned int reg_base = fr->reg_base; unsigned int reg, ss_valid; - reg = calc_frddr_address(EE_AUDIO_FRDDR_A_CTRL0, reg_base); - ss_valid = aml_check_sharebuffer_valid(fr, dst); /* same source en */ @@ -1093,19 +1102,52 @@ void aml_frddr_select_dst_ss(struct frddr *fr, && ss_valid) { int s_v = 0, s_m = 0; - 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; + 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); @@ -1137,8 +1179,11 @@ unsigned int aml_frddr_get_fifo_id(struct frddr *fr) } void aml_frddr_set_format(struct frddr *fr, - unsigned int msb, unsigned int frddr_type) + unsigned int chnum, + unsigned int msb, + unsigned int frddr_type) { + fr->channels = chnum; fr->msb = msb; fr->type = frddr_type; } diff --git a/sound/soc/amlogic/auge/ddr_mngr.h b/sound/soc/amlogic/auge/ddr_mngr.h index 9074faf8dfab..ab1c795b64b1 100644 --- a/sound/soc/amlogic/auge/ddr_mngr.h +++ b/sound/soc/amlogic/auge/ddr_mngr.h @@ -218,6 +218,7 @@ struct frddr { unsigned int reg_base; unsigned int fifo_id; + unsigned int channels; unsigned int msb; unsigned int type; @@ -281,7 +282,9 @@ void aml_frddr_set_fifos(struct frddr *fr, unsigned int depth, unsigned int thresh); unsigned int aml_frddr_get_fifo_id(struct frddr *fr); void aml_frddr_set_format(struct frddr *fr, - unsigned int msb, unsigned int frddr_type); + unsigned int chnum, + unsigned int msb, + unsigned int frddr_type); /* audio eq drc */ void aml_set_aed(bool enable, int aed_module); diff --git a/sound/soc/amlogic/auge/sharebuffer.c b/sound/soc/amlogic/auge/sharebuffer.c index 1ca66ad386fb..f94fd2a03b0c 100644 --- a/sound/soc/amlogic/auge/sharebuffer.c +++ b/sound/soc/amlogic/auge/sharebuffer.c @@ -34,7 +34,9 @@ static int sharebuffer_spdifout_prepare(struct snd_pcm_substream *substream, spdifout_samesource_set(spdif_id, aml_frddr_get_fifo_id(fr), - bit_depth, true); + bit_depth, + runtime->channels, + true); /* spdif to hdmitx */ spdifout_to_hdmitx_ctrl(spdif_id); @@ -59,7 +61,9 @@ static int sharebuffer_spdifout_free(struct snd_pcm_substream *substream, if (spdif_id != 1) spdifout_samesource_set(spdif_id, aml_frddr_get_fifo_id(fr), - bit_depth, false); + bit_depth, + runtime->channels, + false); return 0; } @@ -90,7 +94,8 @@ int sharebuffer_prepare(struct snd_pcm_substream *substream, // TODO: same with tdm } else if (samesource_sel < 5) { /* same source with spdif a/b */ - sharebuffer_spdifout_prepare(substream, fr, samesource_sel - 3); + sharebuffer_spdifout_prepare(substream, + fr, samesource_sel - 3); } /* frddr, share buffer, src_sel1 */ diff --git a/sound/soc/amlogic/auge/spdif.c b/sound/soc/amlogic/auge/spdif.c index 5e79c6fc87e6..6886c170ee64 100644 --- a/sound/soc/amlogic/auge/spdif.c +++ b/sound/soc/amlogic/auge/spdif.c @@ -1038,7 +1038,9 @@ static int aml_dai_spdif_prepare( } fifo_id = aml_frddr_get_fifo_id(fr); - aml_frddr_set_format(fr, bit_depth - 1, + aml_frddr_set_format(fr, + runtime->channels, + bit_depth - 1, spdifout_get_frddr_type(bit_depth)); aml_frddr_select_dst(fr, dst); aml_frddr_set_fifos(fr, 0x40, 0x20); diff --git a/sound/soc/amlogic/auge/spdif_hw.c b/sound/soc/amlogic/auge/spdif_hw.c index 386b68be0bd9..65b4d4703950 100644 --- a/sound/soc/amlogic/auge/spdif_hw.c +++ b/sound/soc/amlogic/auge/spdif_hw.c @@ -403,10 +403,14 @@ void spdifout_clk_ctrl(int spdif_id, bool is_enable) audiobus_write(reg, is_enable << 31 | 0x0 << 24 | 0x3 << 0); } -void spdifout_fifo_ctrl(int spdif_id, int fifo_id, int bitwidth) +static void spdifout_fifo_ctrl(int spdif_id, + int fifo_id, int bitwidth, int channels) { unsigned int frddr_type = spdifout_get_frddr_type(bitwidth); - unsigned int offset, reg; + unsigned int offset, reg, i, chmask = 0; + + for (i = 0; i < channels; i++) + chmask |= (1 << i); pr_debug("spdif_%s fifo ctrl, frddr:%d type:%d, %d bits\n", (spdif_id == 0) ? "a":"b", @@ -419,7 +423,7 @@ void spdifout_fifo_ctrl(int spdif_id, int fifo_id, int bitwidth) reg = EE_AUDIO_SPDIFOUT_CTRL0 + offset * spdif_id; audiobus_update_bits(reg, 0x3<<21|0x1<<20|0x1<<19|0xff<<4, - 0x0<<21|0<<20|0<<19|0x3<<4); + 0x0<<21|0<<20|0<<19|chmask<<4); offset = EE_AUDIO_SPDIFOUT_B_CTRL1 - EE_AUDIO_SPDIFOUT_CTRL1; reg = EE_AUDIO_SPDIFOUT_CTRL1 + offset * spdif_id; @@ -471,7 +475,7 @@ void spdifout_enable(int spdif_id, bool is_enable) } void spdifout_samesource_set(int spdif_index, int fifo_id, - int bitwidth, bool is_enable) + int bitwidth, int channels, bool is_enable) { int spdif_id; @@ -485,7 +489,7 @@ void spdifout_samesource_set(int spdif_index, int fifo_id, spdifout_clk_ctrl(spdif_id, /*is_enable*/true); if (is_enable) - spdifout_fifo_ctrl(spdif_id, fifo_id, bitwidth); + spdifout_fifo_ctrl(spdif_id, fifo_id, bitwidth, channels); } int spdifin_get_sample_rate(void) @@ -624,7 +628,8 @@ void spdifout_play_with_zerodata(unsigned int spdif_id) spdifout_to_hdmitx_ctrl(spdif_id); /* spdif ctrl */ - spdifout_fifo_ctrl(spdif_id, frddr_index, bitwidth); + spdifout_fifo_ctrl(spdif_id, + frddr_index, bitwidth, runtime.channels); /* channel status info */ spdif_get_channel_status_info(&chsts, sample_rate); diff --git a/sound/soc/amlogic/auge/spdif_hw.h b/sound/soc/amlogic/auge/spdif_hw.h index 9d25eaaa2648..3e133f620fba 100644 --- a/sound/soc/amlogic/auge/spdif_hw.h +++ b/sound/soc/amlogic/auge/spdif_hw.h @@ -74,7 +74,7 @@ extern void aml_spdifout_get_aed_info(int spdifout_id, extern void spdifout_to_hdmitx_ctrl(int spdif_index); extern void spdifout_samesource_set(int spdif_index, int fifo_id, - int bitwidth, bool is_enable); + int bitwidth, int channels, bool is_enable); extern void spdifout_enable(int spdif_id, bool is_enable); extern int spdifin_get_sample_rate(void); diff --git a/sound/soc/amlogic/auge/tdm.c b/sound/soc/amlogic/auge/tdm.c index 064a581a35cd..d0afc9a68e91 100644 --- a/sound/soc/amlogic/auge/tdm.c +++ b/sound/soc/amlogic/auge/tdm.c @@ -448,7 +448,9 @@ static int aml_dai_tdm_prepare(struct snd_pcm_substream *substream, p_tdm->id); return -EINVAL; } - aml_frddr_set_format(fr, bit_depth - 1, + aml_frddr_set_format(fr, + runtime->channels, + bit_depth - 1, tdmout_get_frddr_type(bit_depth)); aml_frddr_select_dst(fr, dst); aml_frddr_set_fifos(fr, 0x40, 0x20);