mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 03:40:35 +09:00
audio: optimize parameters of HW resample [1/1]
PD#SWPL-16157 Problem: THD+N test fail of 88.2KHz and 176.4KHz from hdmiin Solution: 1) optimize parameters of resampleB 2) disable AA filter for resampleA Verify: TM2 AB301 Change-Id: If3ef1e283acc8dbb38590f6ae7270b8f59ef83b8 Signed-off-by: Zhe Wang <Zhe.Wang@amlogic.com>
This commit is contained in:
@@ -1242,6 +1242,8 @@
|
||||
clock-names = "resample_pll", "resample_src", "resample_clk";
|
||||
|
||||
/*this resample is only used for loopback_A.*/
|
||||
/*only support 16000 or 48000Hz for capture*/
|
||||
capture_sample_rate = <16000>;
|
||||
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
@@ -666,8 +666,11 @@ static void aml_resample_enable(
|
||||
}
|
||||
|
||||
if (p_attach_resample->resample_version == 1) {
|
||||
new_resample_set_format(p_attach_resample->id,
|
||||
if (p_attach_resample->id == RESAMPLE_A) {
|
||||
new_resampleA_set_format(
|
||||
p_attach_resample->id,
|
||||
to->channels, bitwidth);
|
||||
}
|
||||
new_resample_src_select(p_attach_resample->id,
|
||||
to->fifo_id);
|
||||
} else if (p_attach_resample->resample_version == 0) {
|
||||
|
||||
@@ -69,6 +69,8 @@ struct audioresample {
|
||||
/* sync with auge_resample_texts */
|
||||
enum samplerate_index asrc_in_sr_idx;
|
||||
|
||||
int capture_sample_rate;
|
||||
|
||||
bool enable;
|
||||
};
|
||||
|
||||
@@ -512,23 +514,20 @@ static int new_resample_init(struct audioresample *p_resample)
|
||||
|
||||
p_resample->enable = 1;
|
||||
new_resample_init_param(p_resample->id);
|
||||
resample_clk_set(p_resample, DEFAULT_SPK_SAMPLERATE);
|
||||
|
||||
if (p_resample->id == RESAMPLE_A) {
|
||||
/* default resample A for tv input source */
|
||||
new_resample_set_ratio(p_resample->id,
|
||||
DEFAULT_SPK_SAMPLERATE,
|
||||
DEFAULT_SPK_SAMPLERATE);
|
||||
/*set resample clk to default 256fs mclk.*/
|
||||
/*the same clk source with tdm*/
|
||||
resample_clk_set(p_resample, DEFAULT_SPK_SAMPLERATE);
|
||||
} else if (p_resample->id == RESAMPLE_B) {
|
||||
/* default resample B for loopback downsample */
|
||||
new_resample_set_ratio(p_resample->id,
|
||||
DEFAULT_SPK_SAMPLERATE,
|
||||
DEFAULT_MIC_SAMPLERATE);
|
||||
/*set resample clk to default 256fs mclk.*/
|
||||
/*the same clk source with TDMINLB*/
|
||||
resample_clk_set(p_resample, DEFAULT_MIC_SAMPLERATE);
|
||||
p_resample->capture_sample_rate);
|
||||
new_resampleB_set_format(p_resample->id,
|
||||
p_resample->capture_sample_rate);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -632,6 +631,14 @@ static int resample_platform_probe(struct platform_device *pdev)
|
||||
}
|
||||
} else {
|
||||
resample_module = LOOPBACK_A;
|
||||
ret = of_property_read_u32(pdev->dev.of_node,
|
||||
"capture_sample_rate",
|
||||
&p_resample->capture_sample_rate);
|
||||
if (ret < 0 ||
|
||||
p_resample->capture_sample_rate != DEFAULT_SPK_SAMPLERATE) {
|
||||
p_resample->capture_sample_rate =
|
||||
DEFAULT_MIC_SAMPLERATE;
|
||||
}
|
||||
}
|
||||
|
||||
/* config from dts */
|
||||
|
||||
@@ -45,6 +45,7 @@ static u32 resample_coef_parameters_table[7][5] = {
|
||||
{0x00800000, 0x0, 0x0, 0x0, 0x0},
|
||||
};
|
||||
|
||||
#ifdef AA_FILTER_DEBUG
|
||||
void new_resample_set_ram_coeff_aa(enum resample_idx id, int len,
|
||||
unsigned int *params)
|
||||
{
|
||||
@@ -55,6 +56,7 @@ void new_resample_set_ram_coeff_aa(enum resample_idx id, int len,
|
||||
for (i = 0; i < len; i++, p++)
|
||||
new_resample_write(id, AUDIO_RSAMP_AA_COEF_DATA, *p);
|
||||
}
|
||||
#endif
|
||||
|
||||
void new_resample_set_ram_coeff_sinc(enum resample_idx id, int len,
|
||||
unsigned int *params)
|
||||
@@ -85,10 +87,6 @@ void new_resample_init_param(enum resample_idx id)
|
||||
/*write resample A filter in ram*/
|
||||
new_resample_set_ram_coeff_sinc(id, SINC8_FILTER_COEF_SIZE,
|
||||
&sinc8_coef[0]);
|
||||
} else {
|
||||
/*write resample B filter in ram*/
|
||||
new_resample_set_ram_coeff_sinc(id, SINC8_FILTER_COEF_SIZE,
|
||||
&sinc_coef[0]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,19 +125,29 @@ static int new_resample_status_check(enum resample_idx id)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void new_resample_set_format(enum resample_idx id, int channel, int bits)
|
||||
static void new_resample_adjust_enable(enum resample_idx id,
|
||||
int mclk_ratio, int enable)
|
||||
{
|
||||
/* enable auto adjust module */
|
||||
new_resample_update_bits(id, AUDIO_RSAMP_CTRL0, 0x1 << 2,
|
||||
0x1 << 2);
|
||||
new_resample_update_bits(id, AUDIO_RSAMP_ADJ_CTRL1, 0xffff << 16,
|
||||
(mclk_ratio) << 16);
|
||||
new_resample_write(id, AUDIO_RSAMP_ADJ_SFT, 0x1f020604);
|
||||
new_resample_write(id, AUDIO_RSAMP_ADJ_IDET_LEN, 0x22710);
|
||||
new_resample_write(id, AUDIO_RSAMP_ADJ_FORCE, 0x0);
|
||||
new_resample_write(id, AUDIO_RSAMP_ADJ_CTRL0, enable);
|
||||
new_resample_update_bits(id, AUDIO_RSAMP_CTRL0, 0x1 << 2, 0x0 << 2);
|
||||
}
|
||||
|
||||
void new_resampleA_set_format(enum resample_idx id, int channel, int bits)
|
||||
{
|
||||
int reg_val = bits - 1;
|
||||
int mclk_ratio = 256 / channel;
|
||||
|
||||
if (channel > 8 || channel == 0 || bits < 16)
|
||||
return;
|
||||
|
||||
/* resample B is always 2 channel for loopback */
|
||||
if (id == RESAMPLE_B) {
|
||||
channel = 2;
|
||||
reg_val = 31;
|
||||
}
|
||||
|
||||
new_resample_enable(id, false);
|
||||
new_resample_status_check(id);
|
||||
|
||||
@@ -151,22 +159,43 @@ void new_resample_set_format(enum resample_idx id, int channel, int bits)
|
||||
new_resample_update_bits(id, AUDIO_RSAMP_CTRL1, 0x1f << 13,
|
||||
reg_val << 13);
|
||||
|
||||
/* enable auto adjust module */
|
||||
new_resample_update_bits(id, AUDIO_RSAMP_CTRL0, 0x1 << 2,
|
||||
0x1 << 2);
|
||||
new_resample_update_bits(id, AUDIO_RSAMP_ADJ_CTRL1, 0xffff << 16,
|
||||
(256 / channel) << 16);
|
||||
new_resample_write(id, AUDIO_RSAMP_ADJ_SFT, 0x1f020604);
|
||||
new_resample_write(id, AUDIO_RSAMP_ADJ_IDET_LEN, 0x22710);
|
||||
new_resample_write(id, AUDIO_RSAMP_ADJ_FORCE, 0x0);
|
||||
new_resample_write(id, AUDIO_RSAMP_ADJ_CTRL0, 0x1);
|
||||
new_resample_update_bits(id, AUDIO_RSAMP_CTRL0, 0x1 << 2, 0x0 << 2);
|
||||
new_resample_adjust_enable(id, mclk_ratio, 1);
|
||||
|
||||
new_resample_enable(id, true);
|
||||
|
||||
pr_info("%s(), channel = %d, bits = %d", __func__, channel, bits);
|
||||
}
|
||||
|
||||
void new_resampleB_set_format(enum resample_idx id, int output_sr)
|
||||
{
|
||||
/*MCLK/output_sr/channel_num*/
|
||||
int mclk_ratio = 6144000 / output_sr;
|
||||
|
||||
/*write resample B filter in ram*/
|
||||
if (output_sr == DEFAULT_MIC_SAMPLERATE) {
|
||||
new_resample_set_ram_coeff_sinc(id, SINC8_FILTER_COEF_SIZE,
|
||||
&sinc_coef[0]);
|
||||
} else {
|
||||
new_resample_set_ram_coeff_sinc(id, SINC8_FILTER_COEF_SIZE,
|
||||
&sinc8_coef[0]);
|
||||
}
|
||||
|
||||
new_resample_enable(id, false);
|
||||
new_resample_status_check(id);
|
||||
|
||||
new_resample_write(id, AUDIO_RSAMP_PHSINIT, 0x0);
|
||||
/* channel num */
|
||||
new_resample_update_bits(id, AUDIO_RSAMP_CTRL2, 0x3f << 24,
|
||||
2 << 24); /* always two channel for loopback */
|
||||
/* bit width */
|
||||
new_resample_update_bits(id, AUDIO_RSAMP_CTRL1, 0x1f << 13,
|
||||
31 << 13); /* tdmin_lb is always 32bit */
|
||||
|
||||
new_resample_adjust_enable(id, mclk_ratio, 1);
|
||||
|
||||
new_resample_enable(id, true);
|
||||
}
|
||||
|
||||
void new_resample_src_select(enum resample_idx id, enum resample_src src)
|
||||
{
|
||||
/* resample B is always for loopbackA */
|
||||
@@ -184,7 +213,6 @@ void new_resample_src_select(enum resample_idx id, enum resample_src src)
|
||||
|
||||
void new_resample_set_ratio(enum resample_idx id, int input_sr, int output_sr)
|
||||
{
|
||||
u32 down_ratio = 1;
|
||||
u32 input_sample_rate = (u32)input_sr;
|
||||
u32 output_sample_rate = (u32)output_sr;
|
||||
u64 phase_step = (u64)input_sample_rate;
|
||||
@@ -192,44 +220,6 @@ void new_resample_set_ratio(enum resample_idx id, int input_sr, int output_sr)
|
||||
new_resample_enable(id, false);
|
||||
new_resample_status_check(id);
|
||||
|
||||
if (input_sample_rate <= output_sample_rate) { /* upsample*/
|
||||
new_resample_update_bits(id, AUDIO_RSAMP_CTRL2, 0x3 << 16,
|
||||
0 << 16);
|
||||
/* disable AA filter */
|
||||
new_resample_update_bits(id, AUDIO_RSAMP_CTRL1, 0x1 << 10,
|
||||
0 << 10);
|
||||
} else { /* downsample*/
|
||||
int rate = input_sample_rate * 10 / output_sample_rate;
|
||||
/* enable AA filter */
|
||||
new_resample_update_bits(id, AUDIO_RSAMP_CTRL1, 0x1 << 10,
|
||||
1 << 10);
|
||||
if (id == RESAMPLE_A) {
|
||||
if (rate <= 30) {
|
||||
new_resample_set_ram_coeff_aa(
|
||||
id, AA_FILTER_COEF_SIZE,
|
||||
&aa_coef_a_half[0]);
|
||||
new_resample_update_bits(id, AUDIO_RSAMP_CTRL2,
|
||||
0x3 << 16, 1 << 16);
|
||||
down_ratio = 2;
|
||||
} else {
|
||||
new_resample_set_ram_coeff_aa(
|
||||
id, AA_FILTER_COEF_SIZE,
|
||||
&aa_coef_a_quarter[0]);
|
||||
new_resample_update_bits(id, AUDIO_RSAMP_CTRL2,
|
||||
0x3 << 16, 2 << 16);
|
||||
down_ratio = 4;
|
||||
}
|
||||
} else {
|
||||
new_resample_set_ram_coeff_aa(
|
||||
id, AA_FILTER_COEF_SIZE,
|
||||
&aa_coef_one_third[0]);
|
||||
new_resample_update_bits(id, AUDIO_RSAMP_CTRL2,
|
||||
0x3 << 16, 0 << 16);
|
||||
down_ratio = 3;
|
||||
}
|
||||
}
|
||||
|
||||
output_sample_rate *= down_ratio;
|
||||
phase_step *= (1 << 28);
|
||||
phase_step = div_u64(phase_step, output_sample_rate);
|
||||
|
||||
@@ -237,8 +227,8 @@ void new_resample_set_ratio(enum resample_idx id, int input_sr, int output_sr)
|
||||
|
||||
new_resample_enable(id, true);
|
||||
|
||||
pr_info("%s(), down_ratio = %d, phase_step = 0x%x", __func__,
|
||||
down_ratio, (u32)phase_step);
|
||||
pr_info("%s(), id = %d, phase_step = 0x%x, input_sr = %d, output_sr = %d",
|
||||
__func__, id, (u32)phase_step, input_sr, output_sr);
|
||||
}
|
||||
|
||||
void resample_enable(enum resample_idx id, bool enable)
|
||||
|
||||
@@ -53,7 +53,8 @@ void new_resample_set_ram_coeff_sinc(enum resample_idx id, int len,
|
||||
unsigned int *params);
|
||||
void new_resample_init_param(enum resample_idx id);
|
||||
void new_resample_enable(enum resample_idx id, bool enable);
|
||||
void new_resample_set_format(enum resample_idx id, int source, int channel);
|
||||
void new_resampleA_set_format(enum resample_idx id, int source, int channel);
|
||||
void new_resampleB_set_format(enum resample_idx id, int output_sr);
|
||||
void new_resample_set_ratio(enum resample_idx id, int input_sr, int output_sr);
|
||||
bool new_resample_get_status(enum resample_idx id);
|
||||
void new_resample_src_select(enum resample_idx id, enum resample_src src);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user