From 67a47445ebf0a53652ec0ce5f0e97fb26bbb382b Mon Sep 17 00:00:00 2001 From: Andy Ross Date: Sat, 28 Aug 2021 12:10:14 -0600 Subject: [PATCH] soc: intel_adsp: Fix IDC masking & state issues Fix various bugs with the new IDC layer that show up in edge cases where code relies on correct timing of IPIs (unsurprisingly there is a lot of code that recovers anyway even if the IPI doesn't arrive promptly). Leaving this as a separate patch because the prior code in the PR has already been reviewed and it "mostly" worked: The unmasking of the L2 interrupt bit (remember there are three layers of masking of the IDC interrupt) was always operating on CPU0 at CPU startup because the code had been copied blindly. Unmask the CPU we're actually launching. It turns out cAVS 2.x re-masks this on CPU launch automatically. The global init code to unmask all these interrupts at startup had the same bug, even though it turned out to be needless (the initialization state has it unmasked until it turns it back off). Do it right anyway. Similarly add code to clear out existing interrupt latch state by ACKing all IDC interrupts at startup. Seems needless, but behavior isn't documented so let's be safe. Flag CPU0 as always "active" for the purposes of IPIs. Forgot to do this earlier, oops. Signed-off-by: Andy Ross --- soc/xtensa/intel_adsp/common/soc_mp.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/soc/xtensa/intel_adsp/common/soc_mp.c b/soc/xtensa/intel_adsp/common/soc_mp.c index 1d10d77f868..4997bfba999 100644 --- a/soc/xtensa/intel_adsp/common/soc_mp.c +++ b/soc/xtensa/intel_adsp/common/soc_mp.c @@ -421,7 +421,7 @@ void idc_isr(void *param) * CPU". */ for (int i = 0; i < CONFIG_MP_NUM_CPUS; i++) { - IDC[start_rec.cpu].core[i].tfc = BIT(31); + IDC[prid()].core[i].tfc = BIT(31); } } @@ -456,6 +456,15 @@ void soc_idc_init(void) CAVS_INTCTRL[core].l2.clear = CAVS_L2_IDC; } + + /* Clear out any existing pending interrupts that might be present */ + for (int i = 0; i < CONFIG_MP_NUM_CPUS; i++) { + for (int j = 0; j < CONFIG_MP_NUM_CPUS; j++) { + IDC[i].core[j].tfc = BIT(31); + } + } + + cpus_active[0] = true; } /**