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/drivers/arm/gic/v3/gicv3_helpers.c b/drivers/arm/gic/v3/gicv3_helpers.c
index 753d995..f3852d2 100644
--- a/drivers/arm/gic/v3/gicv3_helpers.c
+++ b/drivers/arm/gic/v3/gicv3_helpers.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -408,3 +408,34 @@
 
 	return part_id;
 }
+
+/*******************************************************************************
+ * Helper function to return product ID and revision of GIC
+ * @gicd_base:   base address of the GIC distributor
+ * @gic_prod_id: retrieved product id of GIC
+ * @gic_rev:     retrieved revision of GIC
+ ******************************************************************************/
+void gicv3_get_component_prodid_rev(const uintptr_t gicd_base,
+				    unsigned int *gic_prod_id,
+				    uint8_t *gic_rev)
+{
+	unsigned int gicd_iidr;
+	uint8_t gic_variant;
+
+	gicd_iidr = gicd_read_iidr(gicd_base);
+	*gic_prod_id = gicd_iidr >> IIDR_PRODUCT_ID_SHIFT;
+	*gic_prod_id &= IIDR_PRODUCT_ID_MASK;
+
+	gic_variant = gicd_iidr >> IIDR_VARIANT_SHIFT;
+	gic_variant &= IIDR_VARIANT_MASK;
+
+	*gic_rev = gicd_iidr >> IIDR_REV_SHIFT;
+	*gic_rev &= IIDR_REV_MASK;
+
+	/*
+	 * pack gic variant and gic_rev in 1 byte
+	 * gic_rev = gic_variant[7:4] and gic_rev[0:3]
+	 */
+	*gic_rev = *gic_rev | gic_variant << 0x4;
+
+}