fix(gic600): implement workaround to forward highest priority interrupt

If the interrupt being targeted is released from the CPU before the
CLEAR command is sent to the CPU then a subsequent SET command may not
be delivered in a finite time. To workaround this, issue an unblocking
event by toggling GICR_CTLR.DPG* bits after clearing the cpu group
enable (EnableGrp* bits of GIC CPU interface register)
This fix is implemented as per the errata 2384374-part 2 workaround
mentioned here:
https://developer.arm.com/documentation/sden892601/latest/

Change-Id: I13926ceeb7740fa4c05cc5b43170e7ce49598f70
Signed-off-by: Manish V Badarkhe <Manish.Badarkhe@arm.com>
diff --git a/include/drivers/arm/gicv3.h b/include/drivers/arm/gicv3.h
index 5efefb6..8371dd5 100644
--- a/include/drivers/arm/gicv3.h
+++ b/include/drivers/arm/gicv3.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -76,6 +76,8 @@
 
 #endif	/* GIC_EXT_INTID */
 
+#define GIC_REV(r, p)           ((r << 4) | p)
+
 /*******************************************************************************
  * GICv3 and 3.1 specific Distributor interface register offsets and constants
  ******************************************************************************/
@@ -192,6 +194,15 @@
 #define GICR_CTLR_UWP_SHIFT	31
 #define GICR_CTLR_UWP_MASK	U(0x1)
 #define GICR_CTLR_UWP_BIT	BIT_32(GICR_CTLR_UWP_SHIFT)
+#define GICR_CTLR_DPG1S_SHIFT	26
+#define GICR_CTLR_DPG1S_MASK	U(0x1)
+#define GICR_CTLR_DPG1S_BIT	BIT_32(GICR_CTLR_DPG1S_SHIFT)
+#define GICR_CTLR_DPG1NS_SHIFT	25
+#define GICR_CTLR_DPG1NS_MASK	U(0x1)
+#define GICR_CTLR_DPG1NS_BIT	BIT_32(GICR_CTLR_DPG1NS_SHIFT)
+#define GICR_CTLR_DPG0_SHIFT	24
+#define GICR_CTLR_DPG0_MASK	U(0x1)
+#define GICR_CTLR_DPG0_BIT	BIT_32(GICR_CTLR_DPG0_SHIFT)
 #define GICR_CTLR_RWP_SHIFT	3
 #define GICR_CTLR_RWP_MASK	U(0x1)
 #define GICR_CTLR_RWP_BIT	BIT_32(GICR_CTLR_RWP_SHIFT)
@@ -224,12 +235,40 @@
 #define TYPER_PPI_NUM_MASK	U(0x1f)
 
 /* GICR_IIDR bit definitions */
-#define IIDR_PRODUCT_ID_MASK	U(0xff000000)
-#define IIDR_VARIANT_MASK	U(0x000f0000)
-#define IIDR_REVISION_MASK	U(0x0000f000)
-#define IIDR_IMPLEMENTER_MASK	U(0x00000fff)
-#define IIDR_MODEL_MASK		(IIDR_PRODUCT_ID_MASK | \
-				 IIDR_IMPLEMENTER_MASK)
+#define IIDR_PRODUCT_ID_MASK	U(0xff)
+#define IIDR_VARIANT_MASK	U(0xf)
+#define IIDR_REV_MASK		U(0xf)
+#define IIDR_IMPLEMENTER_MASK	U(0xfff)
+#define IIDR_PRODUCT_ID_SHIFT	24
+#define IIDR_VARIANT_SHIFT	16
+#define IIDR_REV_SHIFT		12
+#define IIDR_IMPLEMENTER_SHIFT	0
+#define IIDR_PRODUCT_ID_BIT	BIT_32(IIDR_PRODUCT_ID_SHIFT)
+#define IIDR_VARIANT_BIT	BIT_32(IIDR_VARIANT_SHIFT)
+#define IIDR_REV_BIT		BIT_32(IIDR_REVISION_SHIFT)
+#define IIDR_IMPLEMENTER_BIT	BIT_32(IIDR_IMPLEMENTER_SHIFT)
+
+#define IIDR_MODEL_MASK		(IIDR_PRODUCT_ID_MASK << IIDR_PRODUCT_ID_SHIFT | \
+				 IIDR_IMPLEMENTER_MASK << IIDR_IMPLEMENTER_SHIFT)
+
+#define GIC_PRODUCT_ID_GIC600	U(0x2)
+#define GIC_PRODUCT_ID_GIC600AE	U(0x3)
+#define GIC_PRODUCT_ID_GIC700	U(0x4)
+
+/*
+ * Note that below revisions and variants definations are as per GIC600/GIC600AE
+ * specification.
+ */
+#define GIC_REV_P0		U(0x1)
+#define GIC_REV_P1		U(0x3)
+#define GIC_REV_P2		U(0x4)
+#define GIC_REV_P3		U(0x5)
+#define GIC_REV_P4		U(0x6)
+#define GIC_REV_P6		U(0x7)
+
+#define GIC_VARIANT_R0		U(0x0)
+#define GIC_VARIANT_R1		U(0x1)
+#define GIC_VARIANT_R2		U(0x2)
 
 /*******************************************************************************
  * GICv3 and 3.1 CPU interface registers & constants
@@ -543,5 +582,17 @@
 void gicv3_clear_interrupt_pending(unsigned int id, unsigned int proc_num);
 unsigned int gicv3_set_pmr(unsigned int mask);
 
+void gicv3_get_component_prodid_rev(const uintptr_t gicd_base,
+				    unsigned int *gic_prod_id,
+				    uint8_t *gic_rev);
+void gicv3_check_erratas_applies(const uintptr_t gicd_base);
+#if GIC600_ERRATA_WA_2384374
+void gicv3_apply_errata_wa_2384374(const uintptr_t gicr_base);
+#else
+static inline void gicv3_apply_errata_wa_2384374(const uintptr_t gicr_base)
+{
+}
+#endif /* GIC600_ERRATA_WA_2384374 */
+
 #endif /* __ASSEMBLER__ */
 #endif /* GICV3_H */