audio: Fix audio stuck [1/1]

PD#SWPL-9142

Problem:
Audio stuck in stress test.

Solution:
Work around:
Wait until the fifo stops and then stop toddr.

Verify:
Tl1.

Change-Id: I8ce50732a7e23124b4b37374aa4505d79cd68cfe
Signed-off-by: Shuai Li <shuai.li@amlogic.com>
This commit is contained in:
Shuai Li
2019-06-12 16:13:45 +08:00
committed by Tao Zeng
parent ba96cba144
commit a424d39cf5
2 changed files with 40 additions and 3 deletions

View File

@@ -446,6 +446,11 @@ unsigned int aml_toddr_get_status(struct toddr *to)
return aml_audiobus_read(actrl, reg);
}
unsigned int aml_toddr_get_fifo_cnt(struct toddr *to)
{
return (aml_toddr_get_status(to) & TODDR_FIFO_CNT) >> 8;
}
void aml_toddr_ack_irq(struct toddr *to, int status)
{
struct aml_audio_controller *actrl = to->actrl;
@@ -529,6 +534,31 @@ bool aml_toddr_burst_finished(struct toddr *to)
struct aml_audio_controller *actrl = to->actrl;
unsigned int reg_base = to->reg_base;
unsigned int reg;
bool fifo_stop = false;
/* This is a SW workaround.
* If not wait until the fifo stops,
* DDR will stuck and could not recover unless reboot.
*/
for (i = 0; i < 10; i++) {
unsigned int cnt0, cnt1, cnt2;
cnt0 = aml_toddr_get_fifo_cnt(to);
udelay(10);
cnt1 = aml_toddr_get_fifo_cnt(to);
udelay(10);
cnt2 = aml_toddr_get_fifo_cnt(to);
pr_debug("i: %d, fifo cnt:[%d] cnt1:[%d] cnt2:[%d]\n",
i, cnt0, cnt1, cnt2);
/* fifo stopped */
if ((cnt0 == cnt1) && (cnt0 == cnt2) && (cnt0 < (0x40 - 2))) {
pr_info("%s(), i (%d) cnt(%d) break out\n",
__func__, i, cnt2);
fifo_stop = true;
break;
}
}
/* max 200us delay */
for (i = 0; i < 200; i++) {
@@ -540,12 +570,15 @@ bool aml_toddr_burst_finished(struct toddr *to)
aml_audiobus_update_bits(actrl, reg, 0xf << 8, 0x2 << 8);
addr_reply = aml_toddr_get_position(to);
if (addr_request == addr_reply)
if (addr_request == addr_reply) {
pr_info("%s(), fifo_stop %d\n", __func__, fifo_stop);
return true;
}
udelay(1);
pr_debug("delay:[%dus]; FRDDR_STATUS2: [0x%x] [0x%x]\n",
i, addr_request, addr_reply);
if ((i % 20) == 0)
pr_info("delay:[%dus]; FRDDR_STATUS2: [0x%x] [0x%x]\n",
i, addr_request, addr_reply);
}
pr_err("Error: 200us time out, TODDR_STATUS2: [0x%x] [0x%x]\n",
addr_request, addr_reply);

View File

@@ -31,6 +31,9 @@
#define MEMIF_INT_FIFO_DEPTH BIT(5)
#define MEMIF_INT_MASK GENMASK(7, 0)
#define TODDR_FIFO_CNT GENMASK(19, 8)
#define FRDDR_FIFO_CNT GENMASK(17, 8)
enum ddr_num {
DDR_A,
DDR_B,
@@ -252,6 +255,7 @@ void aml_toddr_force_finish(struct toddr *to);
void aml_toddr_set_format(struct toddr *to, struct toddr_fmt *fmt);
unsigned int aml_toddr_get_status(struct toddr *to);
unsigned int aml_toddr_get_fifo_cnt(struct toddr *to);
void aml_toddr_ack_irq(struct toddr *to, int status);
void aml_toddr_insert_chanum(struct toddr *to);