Fix PSCI STAT time stamp collection

This patch includes various fixes for PSCI STAT functionality
relating to timestamp collection:

1. The PSCI stat accounting for retention states for higher level
power domains were done outside the locks which could lead to
spurious values in some race conditions. This is moved inside
the locks. Also, the call to start the stat accounting was redundant
which is now removed.

2. The timestamp wrap-around case when calculating residency did
not cater for AArch32. This is now fixed.

3. In the warm boot path, `plat_psci_stat_accounting_stop()` was
getting invoked prior to population of target power states. This
is now corrected.

Change-Id: I851526455304fb74ff0a724f4d5318cd89e19589
Signed-off-by: Soby Mathew <soby.mathew@arm.com>
diff --git a/lib/psci/psci_common.c b/lib/psci/psci_common.c
index 4502c24..2220a74 100644
--- a/lib/psci/psci_common.c
+++ b/lib/psci/psci_common.c
@@ -767,12 +767,12 @@
 	psci_acquire_pwr_domain_locks(end_pwrlvl,
 				      cpu_idx);
 
+	psci_get_target_local_pwr_states(end_pwrlvl, &state_info);
+
 #if ENABLE_PSCI_STAT
 	plat_psci_stat_accounting_stop(&state_info);
 #endif
 
-	psci_get_target_local_pwr_states(end_pwrlvl, &state_info);
-
 	/*
 	 * This CPU could be resuming from suspend or it could have just been
 	 * turned on. To distinguish between these 2 cases, we examine the
diff --git a/lib/psci/psci_suspend.c b/lib/psci/psci_suspend.c
index 40ecdee..d949067 100644
--- a/lib/psci/psci_suspend.c
+++ b/lib/psci/psci_suspend.c
@@ -37,6 +37,11 @@
 	 */
 	psci_get_target_local_pwr_states(end_pwrlvl, &state_info);
 
+#if ENABLE_PSCI_STAT
+	plat_psci_stat_accounting_stop(&state_info);
+	psci_stats_update_pwr_up(end_pwrlvl, &state_info);
+#endif
+
 	/*
 	 * Plat. management: Allow the platform to do operations
 	 * on waking up from retention.
@@ -236,10 +241,6 @@
 	    PMF_NO_CACHE_MAINT);
 #endif
 
-#if ENABLE_PSCI_STAT
-	plat_psci_stat_accounting_start(state_info);
-#endif
-
 	/*
 	 * We will reach here if only retention/standby states have been
 	 * requested at multiple power levels. This means that the cpu
@@ -247,11 +248,6 @@
 	 */
 	wfi();
 
-#if ENABLE_PSCI_STAT
-	plat_psci_stat_accounting_stop(state_info);
-	psci_stats_update_pwr_up(end_pwrlvl, state_info);
-#endif
-
 #if ENABLE_RUNTIME_INSTRUMENTATION
 	PMF_CAPTURE_TIMESTAMP(rt_instr_svc,
 	    RT_INSTR_EXIT_HW_LOW_PWR,
diff --git a/plat/common/plat_psci_common.c b/plat/common/plat_psci_common.c
index 95adb05..0e818d0 100644
--- a/plat/common/plat_psci_common.c
+++ b/plat/common/plat_psci_common.c
@@ -18,6 +18,13 @@
 /* Ticks elapsed in one second by a signal of 1 MHz */
 #define MHZ_TICKS_PER_SEC 1000000
 
+/* Maximum time-stamp value read from architectural counters */
+#ifdef AARCH32
+#define MAX_TS	UINT32_MAX
+#else
+#define MAX_TS	UINT64_MAX
+#endif
+
 /* Following are used as ID's to capture time-stamp */
 #define PSCI_STAT_ID_ENTER_LOW_PWR		0
 #define PSCI_STAT_ID_EXIT_LOW_PWR		1
@@ -45,7 +52,7 @@
 	assert(residency_div);
 
 	if (pwrupts < pwrdnts)
-		res = UINT64_MAX - pwrdnts + pwrupts;
+		res = MAX_TS - pwrdnts + pwrupts;
 	else
 		res = pwrupts - pwrdnts;