ARM platforms: enable GICv3 state save/restore

Provides GICv3 save/restore feature to arm_system_pwr_domain_resume and
arm_system_pwr_domain_save functions.

Introduce FVP PSCI power level 3 (System level) support. This is solely
done to provide example code on how to use the GICv3 save and restore
helpers.

Also make CSS GICv3 platforms power off the Redistributor on SYSTEM
SUSPEND as its state is saved and restored.

Change-Id: I0d852f3af8824edee1a17c085cf593ddd33a4e77
Signed-off-by: Soby Mathew <soby.mathew@arm.com>
Co-Authored-by: Douglas Raillard <douglas.raillard@arm.com>
diff --git a/plat/arm/css/common/css_pm.c b/plat/arm/css/common/css_pm.c
index 93d51fe..cf4e666 100644
--- a/plat/arm/css/common/css_pm.c
+++ b/plat/arm/css/common/css_pm.c
@@ -74,6 +74,9 @@
 {
 	assert(CSS_CORE_PWR_STATE(target_state) == ARM_LOCAL_STATE_OFF);
 
+	/* Enable the gic cpu interface */
+	plat_arm_gic_cpuif_enable();
+
 	/*
 	 * Perform the common cluster specific operations i.e enable coherency
 	 * if this cluster was off.
@@ -95,13 +98,10 @@
 	/* Assert that the system power domain need not be initialized */
 	assert(CSS_SYSTEM_PWR_STATE(target_state) == ARM_LOCAL_STATE_RUN);
 
-	css_pwr_domain_on_finisher_common(target_state);
-
 	/* Program the gic per-cpu distributor or re-distributor interface */
 	plat_arm_gic_pcpu_init();
 
-	/* Enable the gic cpu interface */
-	plat_arm_gic_cpuif_enable();
+	css_pwr_domain_on_finisher_common(target_state);
 }
 
 /*******************************************************************************
@@ -144,8 +144,18 @@
 	if (CSS_CORE_PWR_STATE(target_state) == ARM_LOCAL_STATE_RET)
 		return;
 
+
 	assert(CSS_CORE_PWR_STATE(target_state) == ARM_LOCAL_STATE_OFF);
 	css_power_down_common(target_state);
+
+	/* Perform system domain state saving if issuing system suspend */
+	if (CSS_SYSTEM_PWR_STATE(target_state) == ARM_LOCAL_STATE_OFF) {
+		arm_system_pwr_domain_save();
+
+		/* Power off the Redistributor after having saved its context */
+		plat_arm_gic_redistif_off();
+	}
+
 	css_scp_suspend(target_state);
 }
 
@@ -165,10 +175,12 @@
 
 	/* Perform system domain restore if woken up from system suspend */
 	if (CSS_SYSTEM_PWR_STATE(target_state) == ARM_LOCAL_STATE_OFF)
+		/*
+		 * At this point, the Distributor must be powered on to be ready
+		 * to have its state restored. The Redistributor will be powered
+		 * on as part of gicv3_rdistif_init_restore.
+		 */
 		arm_system_pwr_domain_resume();
-	else
-		/* Enable the gic cpu interface */
-		plat_arm_gic_cpuif_enable();
 
 	css_pwr_domain_on_finisher_common(target_state);
 }