rtc: improve WA for RTC incorrect read

	- Improved WA for RTC read failure
	- According to FE-3124064:
	- Description:
	    The device supports CPU write and read access to the RTC Time register.
	    However, due to this erratum, Read from RTC TIME register may fail.
	  Workaround:
	    RTC TIME register should be read 100 times, return a the value which appears
	    most frequently as a proper value.

Change-Id: I05b20d633220bb8043f176fbb7d3c68c671b368a
Signed-off-by: Shaker Daibes <shaker@marvell.com>
Reviewed-on: http://vgitil04.il.marvell.com:8080/24986
Tested-by: Star_Automation <star@marvell.com>
Reviewed-by: Ofer Heifetz <oferh@marvell.com>
diff --git a/board/mv_ebu/common/USP/mv_rtc2.c b/board/mv_ebu/common/USP/mv_rtc2.c
index 53a321e..c61b405 100644
--- a/board/mv_ebu/common/USP/mv_rtc2.c
+++ b/board/mv_ebu/common/USP/mv_rtc2.c
@@ -70,9 +70,11 @@
 #include "mv_rtc2.h"
 
 #if defined(CONFIG_CMD_DATE)
-
+/* This define for WA in rtc read */
+#define SAMPLE_NR 100
 static int rtc_ready = -1;
 
+
 /*******************************************************/
 void rtc_init(void)
 {
@@ -97,38 +99,71 @@
 	rtc_ready = 1;
 }
 
+#ifdef ERRATA_FE_3124064
+struct _strTime2Freq {
+	unsigned long nTime;
+	unsigned int  nFreq;
+
+};
+#endif
+
 /*******************************************************/
 int rtc_get(struct rtc_time *tm)
 {
-	unsigned long time, time_check;
+#ifdef ERRATA_FE_3124064
+	/* Functional Errata Ref #: FE-3124064 - WA for failing time read attempts.
+	 * Description:
+	 *      The device supports CPU write and read access to the RTC Time register.
+	 *	However, due to this erratum, Write to RTC TIME register may fail.
+	 *	Read from RTC TIME register may fail.
+	 * Workaround:
+	 *	Before writing to RTC TIME register, issue a dummy write of 0x0 twice to
+	 *	RTC Status register.
+	 *	Configure maximum value (0x3FF) in write clock period in RTC Mbus Bridge
+	 *	Timing Control register.
+	 *	Before writing to RTC TIME register, issue a dummy write of 0x0 twice to
+	 *	RTC Status register.
+	 *      RTC TIME register should be read 100 times, then find the result
+	 *	that appear most frequently, use this result as the correct value.
+	 */
+	unsigned long nTimeArray[SAMPLE_NR], i, j, nTime, nMax = 0, indexMax = SAMPLE_NR - 1;
+	struct _strTime2Freq sTimeToFreq[SAMPLE_NR];
+#endif
 
 	if (rtc_ready != 1)
 		rtc_init();
-
-	time = RTC_READ_REG(RTC_TIME_REG_OFFS);
 #ifdef ERRATA_FE_3124064
-	/* Functional Errata Ref #: FE-3124064 -  WA for failing time read attempts.
-	 * Description:
-	 * 	The device supports CPU write and read access to the RTC Time register.
-	 * 	However, due to this erratum, Write to RTC TIME register may fail.
-	 * 	Read from RTC TIME register may fail.
-	 * Workaround:
-	 * 	Before writing to RTC TIME register, issue a dummy write of 0x0 twice to RTC Status register.
-	 * 	RTC TIME register should be read twice, the second read will return a proper value.
-	 * 	Configure maximum value (0x3FF) in write clock period in RTC Mbus Bridge Timing Control register.
-	 * Functional Impact After Workaround is applied:
-	 * 	No functional impact after WA is applied
-	 */
-	time_check = RTC_READ_REG(RTC_TIME_REG_OFFS);
-	if ((time_check - time) > 1)
-		time_check = RTC_READ_REG(RTC_TIME_REG_OFFS);
+	/* read RTC TIME register 100 times and save the values in array,
+	   initialize the counters to zero */
+	for (i = 0; i < SAMPLE_NR; i++) {
+		sTimeToFreq[i].nFreq = 0;
+		nTimeArray[i] = RTC_READ_REG(RTC_TIME_REG_OFFS);
+	}
+	for (i = 0; i < SAMPLE_NR; i++) {
+		nTime = nTimeArray[i];
+		/* if nTime appears in sTimeToFreq array so add the counter of nTime value,
+		   if didn't appear yet in counters array then allocate new member of
+		   sTimeToFreq array with counter = 1 */
+		for (j = 0; j < SAMPLE_NR; j++) {
+			if (sTimeToFreq[j].nFreq == 0 || sTimeToFreq[j].nTime == nTime)
+				break;
+		}
+		if (sTimeToFreq[j].nFreq == 0)
+			sTimeToFreq[j].nTime = nTime;
+		sTimeToFreq[j].nFreq++;
+		/*find the most common result*/
+		if (nMax < sTimeToFreq[j].nFreq) {
+			indexMax = j;
+			nMax = sTimeToFreq[j].nFreq;
+		}
+	}
+
+	to_tm(sTimeToFreq[indexMax].nTime, tm);
+#else
+	to_tm(RTC_READ_REG(RTC_TIME_REG_OFFS), tm);
 #endif
-
-	to_tm(time_check, tm);
-
 	return 0;
 }
-
 /*******************************************************/
 int rtc_set(struct rtc_time *tm)
 {