fix(cpus): workaround for Neoverse N2 erratum 2009478

Neoverse N2 erratum 2009478 is a Cat B erratum that applies to
revision r0p0 and is fixed in r0p1. The workaround is to clear
the ED bit for all core error records before setting the PWRDN_EN
bit in CPUPWRCTLR_EL1 to request a power down.

SDEN documentation:
https://developer.arm.com/documentation/SDEN1982442/latest

Signed-off-by: Bipin Ravi <bipin.ravi@arm.com>
Change-Id: Ic5ef58c9e795b90026af1d2b09edc0eea3ceee51
diff --git a/lib/cpus/aarch64/neoverse_n2.S b/lib/cpus/aarch64/neoverse_n2.S
index acf8dee..ead3908 100644
--- a/lib/cpus/aarch64/neoverse_n2.S
+++ b/lib/cpus/aarch64/neoverse_n2.S
@@ -68,6 +68,22 @@
 
 check_erratum_ls neoverse_n2, ERRATUM(2067956), CPU_REV(0, 0)
 
+workaround_runtime_start neoverse_n2, ERRATUM(2009478), ERRATA_N2_2009478
+	/* Stash ERRSELR_EL1 in x2 */
+	mrs     x2, ERRSELR_EL1
+
+	/* Select error record 0 and clear ED bit */
+	msr     ERRSELR_EL1, xzr
+	mrs     x1, ERXCTLR_EL1
+	bfi     x1, xzr, #ERXCTLR_ED_SHIFT, #1
+	msr     ERXCTLR_EL1, x1
+
+	/* Restore ERRSELR_EL1 from x2 */
+	msr     ERRSELR_EL1, x2
+workaround_runtime_end neoverse_n2, ERRATUM(2009478), NO_ISB
+
+check_erratum_ls neoverse_n2, ERRATUM(2009478), CPU_REV(0, 0)
+
 workaround_reset_start neoverse_n2, ERRATUM(2138953), ERRATA_N2_2138953
 	/* Apply instruction patching sequence */
 	mrs	x1, NEOVERSE_N2_CPUECTLR2_EL1
@@ -233,7 +249,9 @@
 
 func neoverse_n2_core_pwr_dwn
 
-	apply_erratum neoverse_n2, ERRATUM(2326639), ERRATA_N2_2326639
+	apply_erratum neoverse_n2, ERRATUM(2009478), ERRATA_N2_2009478
+	apply_erratum neoverse_n2, ERRATUM(2326639), ERRATA_N2_2326639, NO_GET_CPU_REV
+
 	/* ---------------------------------------------------
 	 * Enable CPU power down bit in power control register
 	 * No need to do cache maintenance here.