fix(gic600): workaround for Part 1 of GIC600 erratum 2384374

GIC600 erratum 2384374 is a Category B erratum. Part 1 is fixed
in this patch, and the Part 1 failure mode is described as
'If the packet to be sent is a SET packet, then a higher priority SET
may not be sent when it should be until an unblocking event occurs.'

This is handled by calling gicv3_apply_errata_wa_2384374() in the
ehf_deactivate_priority() path, so that when EHF restores the priority
to the original priority, the interrupt packet buffered
in the GIC can be sent.

gicv3_apply_errata_wa_2384374() is the workaround for
the Part 2 of erratum 2384374 which flush packets from the GIC buffer
and is being used in this patch.

SDEN can be found here:
https://developer.arm.com/documentation/sden892601/latest/

Signed-off-by: Arvind Ram Prakash <arvind.ramprakash@arm.com>
Change-Id: I4bb6dcf86c94125cbc574e0dc5119abe43e84731
(cherry picked from commit 24a4a0a5ec25e179f2e567a6e13a9b5c87db1b81)
diff --git a/drivers/arm/gic/v3/gicv3_main.c b/drivers/arm/gic/v3/gicv3_main.c
index 7a67384..22761fb 100644
--- a/drivers/arm/gic/v3/gicv3_main.c
+++ b/drivers/arm/gic/v3/gicv3_main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2023, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -14,6 +14,7 @@
 #include <drivers/arm/gic600_multichip.h>
 #include <drivers/arm/gicv3.h>
 #include <lib/spinlock.h>
+#include <plat/common/platform.h>
 
 #include "gicv3_private.h"
 
@@ -1296,6 +1297,31 @@
 }
 
 /*******************************************************************************
+ * This function restores the PMR register to old value and also triggers
+ * gicv3_apply_errata_wa_2384374() that flushes the GIC buffer allowing any
+ * pending interrupts to processed. Returns the original PMR.
+ ******************************************************************************/
+unsigned int gicv3_deactivate_priority(unsigned int mask)
+{
+
+	unsigned int old_mask, proc_num;
+	uintptr_t gicr_base;
+
+	old_mask = gicv3_set_pmr(mask);
+
+	proc_num = plat_my_core_pos();
+	gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num];
+	assert(gicr_base != 0UL);
+
+	/* Add DSB to ensure visibility of System register writes */
+	dsb();
+
+	gicv3_apply_errata_wa_2384374(gicr_base);
+
+	return old_mask;
+}
+
+/*******************************************************************************
  * This function delegates the responsibility of discovering the corresponding
  * Redistributor frames to each CPU itself. It is a modified version of
  * gicv3_rdistif_base_addrs_probe() and is executed by each CPU in the platform