ASR_BASE

Change-Id: Icf3719cc0afe3eeb3edc7fa80a2eb5199ca9dda1
diff --git a/marvell/uboot/drivers/rtc/Makefile b/marvell/uboot/drivers/rtc/Makefile
new file mode 100644
index 0000000..d5a2725
--- /dev/null
+++ b/marvell/uboot/drivers/rtc/Makefile
@@ -0,0 +1,52 @@
+#
+# (C) Copyright 2001-2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+#CFLAGS += -DDEBUG
+
+obj-$(CONFIG_RTC_AT91SAM9_RTT) += at91sam9_rtt.o
+obj-$(CONFIG_RTC_BFIN) += bfin_rtc.o
+obj-y += date.o
+obj-$(CONFIG_RTC_DAVINCI) += davinci.o
+obj-$(CONFIG_RTC_DS12887) += ds12887.o
+obj-$(CONFIG_RTC_DS1302) += ds1302.o
+obj-$(CONFIG_RTC_DS1306) += ds1306.o
+obj-$(CONFIG_RTC_DS1307) += ds1307.o
+obj-$(CONFIG_RTC_DS1338) += ds1307.o
+obj-$(CONFIG_RTC_DS1337) += ds1337.o
+obj-$(CONFIG_RTC_DS1374) += ds1374.o
+obj-$(CONFIG_RTC_DS1388) += ds1337.o
+obj-$(CONFIG_RTC_DS1556) += ds1556.o
+obj-$(CONFIG_RTC_DS164x) += ds164x.o
+obj-$(CONFIG_RTC_DS174x) += ds174x.o
+obj-$(CONFIG_RTC_DS3231) += ds3231.o
+obj-$(CONFIG_RTC_FTRTC010) += ftrtc010.o
+obj-$(CONFIG_RTC_IMXDI) += imxdi.o
+obj-$(CONFIG_RTC_ISL1208) += isl1208.o
+obj-$(CONFIG_RTC_M41T11) += m41t11.o
+obj-$(CONFIG_RTC_M41T60) += m41t60.o
+obj-$(CONFIG_RTC_M41T62) += m41t62.o
+obj-$(CONFIG_RTC_M41T94) += m41t94.o
+obj-$(CONFIG_RTC_M48T35A) += m48t35ax.o
+obj-$(CONFIG_RTC_MAX6900) += max6900.o
+obj-$(CONFIG_RTC_MC13XXX) += mc13xxx-rtc.o
+obj-$(CONFIG_RTC_MC146818) += mc146818.o
+obj-$(CONFIG_MCFRTC) += mcfrtc.o
+obj-$(CONFIG_RTC_MK48T59) += mk48t59.o
+obj-$(CONFIG_RTC_MPC5200) += mpc5xxx.o
+obj-$(CONFIG_RTC_MPC8xx) += mpc8xx.o
+obj-$(CONFIG_RTC_MV) += mvrtc.o
+obj-$(CONFIG_RTC_MX27) += mx27rtc.o
+obj-$(CONFIG_RTC_MXS) += mxsrtc.o
+obj-$(CONFIG_RTC_PCF8563) += pcf8563.o
+obj-$(CONFIG_RTC_PL031) += pl031.o
+obj-$(CONFIG_RTC_PT7C4338) += pt7c4338.o
+obj-$(CONFIG_RTC_RS5C372A) += rs5c372.o
+obj-$(CONFIG_RTC_RTC4543) += rtc4543.o
+obj-$(CONFIG_RTC_RV3029) += rv3029.o
+obj-$(CONFIG_RTC_RX8025) += rx8025.o
+obj-$(CONFIG_RTC_S3C24X0) += s3c24x0_rtc.o
+obj-$(CONFIG_RTC_X1205) += x1205.o
diff --git a/marvell/uboot/drivers/rtc/at91sam9_rtt.c b/marvell/uboot/drivers/rtc/at91sam9_rtt.c
new file mode 100644
index 0000000..714dd2a
--- /dev/null
+++ b/marvell/uboot/drivers/rtc/at91sam9_rtt.c
@@ -0,0 +1,84 @@
+/*
+ * (C) Copyright 2010
+ * Reinhard Meyer, reinhard.meyer@emk-elektronik.de
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+/*
+ * Date & Time support for the internal Real-time Timer
+ * of AT91SAM9260 and compatibles.
+ * Compatible with the LinuX rtc driver workaround:
+ * The RTT cannot be written to, but only reset.
+ * The actual time is the sum of RTT and one of
+ * the four GPBR registers.
+ *
+ * The at91sam9260 has 4 GPBR (0-3).
+ * For their typical use see at91_gpbr.h !
+ *
+ * make sure u-boot and kernel use the same GPBR !
+ */
+
+#include <common.h>
+#include <command.h>
+#include <rtc.h>
+#include <asm/io.h>
+#include <asm/errno.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/at91_rtt.h>
+#include <asm/arch/at91_gpbr.h>
+
+#if defined(CONFIG_CMD_DATE)
+
+int rtc_get (struct rtc_time *tmp)
+{
+	at91_rtt_t *rtt = (at91_rtt_t *) ATMEL_BASE_RTT;
+	at91_gpbr_t *gpbr = (at91_gpbr_t *) ATMEL_BASE_GPBR;
+	ulong tim;
+	ulong tim2;
+	ulong off;
+
+	do {
+		tim = readl(&rtt->vr);
+		tim2 = readl(&rtt->vr);
+	} while (tim!=tim2);
+	off = readl(&gpbr->reg[AT91_GPBR_INDEX_TIMEOFF]);
+	/* off==0 means time is invalid, but we ignore that */
+	to_tm (tim+off, tmp);
+	return 0;
+}
+
+int rtc_set (struct rtc_time *tmp)
+{
+	at91_rtt_t *rtt = (at91_rtt_t *) ATMEL_BASE_RTT;
+	at91_gpbr_t *gpbr = (at91_gpbr_t *) ATMEL_BASE_GPBR;
+	ulong tim;
+
+	tim = mktime (tmp->tm_year, tmp->tm_mon, tmp->tm_mday,
+		      tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+	/* clear alarm, set prescaler to 32768, clear counter */
+	writel(32768+AT91_RTT_RTTRST, &rtt->mr);
+	writel(~0, &rtt->ar);
+	writel(tim, &gpbr->reg[AT91_GPBR_INDEX_TIMEOFF]);
+	/* wait for counter clear to happen, takes less than a 1/32768th second */
+	while (readl(&rtt->vr) != 0)
+		;
+	return 0;
+}
+
+void rtc_reset (void)
+{
+	at91_rtt_t *rtt = (at91_rtt_t *) ATMEL_BASE_RTT;
+	at91_gpbr_t *gpbr = (at91_gpbr_t *) ATMEL_BASE_GPBR;
+
+	/* clear alarm, set prescaler to 32768, clear counter */
+	writel(32768+AT91_RTT_RTTRST, &rtt->mr);
+	writel(~0, &rtt->ar);
+	writel(0, &gpbr->reg[AT91_GPBR_INDEX_TIMEOFF]);
+	/* wait for counter clear to happen, takes less than a 1/32768th second */
+	while (readl(&rtt->vr) != 0)
+		;
+}
+
+#endif
diff --git a/marvell/uboot/drivers/rtc/bfin_rtc.c b/marvell/uboot/drivers/rtc/bfin_rtc.c
new file mode 100644
index 0000000..21a2189
--- /dev/null
+++ b/marvell/uboot/drivers/rtc/bfin_rtc.c
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2004-2008 Analog Devices Inc.
+ *
+ * (C) Copyright 2001
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <common.h>
+#include <command.h>
+#include <rtc.h>
+
+#if defined(CONFIG_CMD_DATE)
+
+#include <asm/blackfin.h>
+#include <asm/mach-common/bits/rtc.h>
+
+#define pr_stamp() debug("%s:%s:%i: here i am\n", __FILE__, __func__, __LINE__)
+
+#define MIN_TO_SECS(x)    (60 * (x))
+#define HRS_TO_SECS(x)    (60 * MIN_TO_SECS(x))
+#define DAYS_TO_SECS(x)   (24 * HRS_TO_SECS(x))
+
+#define NUM_SECS_IN_MIN   MIN_TO_SECS(1)
+#define NUM_SECS_IN_HR    HRS_TO_SECS(1)
+#define NUM_SECS_IN_DAY   DAYS_TO_SECS(1)
+
+/* Enable the RTC prescaler enable register */
+static void rtc_init(void)
+{
+	if (!(bfin_read_RTC_PREN() & 0x1))
+		bfin_write_RTC_PREN(0x1);
+}
+
+/* Our on-chip RTC has no notion of "reset" */
+void rtc_reset(void)
+{
+	rtc_init();
+}
+
+/* Wait for pending writes to complete */
+static void wait_for_complete(void)
+{
+	pr_stamp();
+	while (!(bfin_read_RTC_ISTAT() & WRITE_COMPLETE))
+		if (!(bfin_read_RTC_ISTAT() & WRITE_PENDING))
+			break;
+	bfin_write_RTC_ISTAT(WRITE_COMPLETE);
+}
+
+/* Set the time. Get the time_in_secs which is the number of seconds since Jan 1970 and set the RTC registers
+ * based on this value.
+ */
+int rtc_set(struct rtc_time *tmp)
+{
+	unsigned long remain, days, hrs, mins, secs;
+
+	pr_stamp();
+
+	if (tmp == NULL) {
+		puts("Error setting the date/time\n");
+		return -1;
+	}
+
+	rtc_init();
+	wait_for_complete();
+
+	/* Calculate number of seconds this incoming time represents */
+	remain = mktime(tmp->tm_year, tmp->tm_mon, tmp->tm_mday,
+			tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+	/* Figure out how many days since epoch */
+	days = remain / NUM_SECS_IN_DAY;
+
+	/* From the remaining secs, compute the hrs(0-23), mins(0-59) and secs(0-59) */
+	remain = remain % NUM_SECS_IN_DAY;
+	hrs = remain / NUM_SECS_IN_HR;
+	remain = remain % NUM_SECS_IN_HR;
+	mins = remain / NUM_SECS_IN_MIN;
+	secs = remain % NUM_SECS_IN_MIN;
+
+	/* Encode these time values into our RTC_STAT register */
+	bfin_write_RTC_STAT(SET_ALARM(days, hrs, mins, secs));
+
+	return 0;
+}
+
+/* Read the time from the RTC_STAT. time_in_seconds is seconds since Jan 1970 */
+int rtc_get(struct rtc_time *tmp)
+{
+	uint32_t cur_rtc_stat;
+	int time_in_sec;
+	int tm_sec, tm_min, tm_hr, tm_day;
+
+	pr_stamp();
+
+	if (tmp == NULL) {
+		puts("Error getting the date/time\n");
+		return -1;
+	}
+
+	rtc_init();
+	wait_for_complete();
+
+	/* Read the RTC_STAT register */
+	cur_rtc_stat = bfin_read_RTC_STAT();
+
+	/* Convert our encoded format into actual time values */
+	tm_sec = (cur_rtc_stat & RTC_SEC) >> RTC_SEC_P;
+	tm_min = (cur_rtc_stat & RTC_MIN) >> RTC_MIN_P;
+	tm_hr  = (cur_rtc_stat & RTC_HR ) >> RTC_HR_P;
+	tm_day = (cur_rtc_stat & RTC_DAY) >> RTC_DAY_P;
+
+	/* Calculate the total number of seconds since epoch */
+	time_in_sec = (tm_sec) + MIN_TO_SECS(tm_min) + HRS_TO_SECS(tm_hr) + DAYS_TO_SECS(tm_day);
+	to_tm(time_in_sec, tmp);
+
+	return 0;
+}
+
+#endif
diff --git a/marvell/uboot/drivers/rtc/date.c b/marvell/uboot/drivers/rtc/date.c
new file mode 100644
index 0000000..15e6db0
--- /dev/null
+++ b/marvell/uboot/drivers/rtc/date.c
@@ -0,0 +1,140 @@
+/*
+ * (C) Copyright 2001
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+/*
+ * Date & Time support for Philips PCF8563 RTC
+ */
+
+#include <common.h>
+#include <command.h>
+#include <rtc.h>
+
+#if defined(CONFIG_CMD_DATE) || defined(CONFIG_TIMESTAMP)
+
+#define FEBRUARY		2
+#define	STARTOFTIME		1970
+#define SECDAY			86400L
+#define SECYR			(SECDAY * 365)
+#define	leapyear(year)		((year) % 4 == 0)
+#define	days_in_year(a)		(leapyear(a) ? 366 : 365)
+#define	days_in_month(a)	(month_days[(a) - 1])
+
+static int month_days[12] = {
+	31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
+};
+
+/*
+ * This only works for the Gregorian calendar - i.e. after 1752 (in the UK)
+ */
+void GregorianDay(struct rtc_time * tm)
+{
+	int leapsToDate;
+	int lastYear;
+	int day;
+	int MonthOffset[] = { 0,31,59,90,120,151,181,212,243,273,304,334 };
+
+	lastYear=tm->tm_year-1;
+
+	/*
+	 * Number of leap corrections to apply up to end of last year
+	 */
+	leapsToDate = lastYear/4 - lastYear/100 + lastYear/400;
+
+	/*
+	 * This year is a leap year if it is divisible by 4 except when it is
+	 * divisible by 100 unless it is divisible by 400
+	 *
+	 * e.g. 1904 was a leap year, 1900 was not, 1996 is, and 2000 will be
+	 */
+	if((tm->tm_year%4==0) &&
+	   ((tm->tm_year%100!=0) || (tm->tm_year%400==0)) &&
+	   (tm->tm_mon>2)) {
+		/*
+		 * We are past Feb. 29 in a leap year
+		 */
+		day=1;
+	} else {
+		day=0;
+	}
+
+	day += lastYear*365 + leapsToDate + MonthOffset[tm->tm_mon-1] + tm->tm_mday;
+
+	tm->tm_wday=day%7;
+}
+
+void to_tm(int tim, struct rtc_time * tm)
+{
+	register int    i;
+	register long   hms, day;
+
+	day = tim / SECDAY;
+	hms = tim % SECDAY;
+
+	/* Hours, minutes, seconds are easy */
+	tm->tm_hour = hms / 3600;
+	tm->tm_min = (hms % 3600) / 60;
+	tm->tm_sec = (hms % 3600) % 60;
+
+	/* Number of years in days */
+	for (i = STARTOFTIME; day >= days_in_year(i); i++) {
+		day -= days_in_year(i);
+	}
+	tm->tm_year = i;
+
+	/* Number of months in days left */
+	if (leapyear(tm->tm_year)) {
+		days_in_month(FEBRUARY) = 29;
+	}
+	for (i = 1; day >= days_in_month(i); i++) {
+		day -= days_in_month(i);
+	}
+	days_in_month(FEBRUARY) = 28;
+	tm->tm_mon = i;
+
+	/* Days are what is left over (+1) from all that. */
+	tm->tm_mday = day + 1;
+
+	/*
+	 * Determine the day of week
+	 */
+	GregorianDay(tm);
+}
+
+/* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
+ * Assumes input in normal date format, i.e. 1980-12-31 23:59:59
+ * => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
+ *
+ * [For the Julian calendar (which was used in Russia before 1917,
+ * Britain & colonies before 1752, anywhere else before 1582,
+ * and is still in use by some communities) leave out the
+ * -year/100+year/400 terms, and add 10.]
+ *
+ * This algorithm was first published by Gauss (I think).
+ *
+ * WARNING: this function will overflow on 2106-02-07 06:28:16 on
+ * machines were long is 32-bit! (However, as time_t is signed, we
+ * will already get problems at other places on 2038-01-19 03:14:08)
+ */
+unsigned long
+mktime (unsigned int year, unsigned int mon,
+	unsigned int day, unsigned int hour,
+	unsigned int min, unsigned int sec)
+{
+	if (0 >= (int) (mon -= 2)) {	/* 1..12 -> 11,12,1..10 */
+		mon += 12;		/* Puts Feb last since it has leap day */
+		year -= 1;
+	}
+
+	return (((
+		(unsigned long) (year/4 - year/100 + year/400 + 367*mon/12 + day) +
+			year*365 - 719499
+	    )*24 + hour /* now have hours */
+	  )*60 + min /* now have minutes */
+	)*60 + sec; /* finally seconds */
+}
+
+#endif
diff --git a/marvell/uboot/drivers/rtc/davinci.c b/marvell/uboot/drivers/rtc/davinci.c
new file mode 100644
index 0000000..f862e2f
--- /dev/null
+++ b/marvell/uboot/drivers/rtc/davinci.c
@@ -0,0 +1,83 @@
+/*
+ * (C) Copyright 2011 DENX Software Engineering GmbH
+ * Heiko Schocher <hs@denx.de>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#include <common.h>
+#include <command.h>
+#include <rtc.h>
+#include <asm/io.h>
+#include <asm/davinci_rtc.h>
+
+#if defined(CONFIG_CMD_DATE)
+int rtc_get(struct rtc_time *tmp)
+{
+	struct davinci_rtc *rtc = (struct davinci_rtc *)DAVINCI_RTC_BASE;
+	unsigned long sec, min, hour, mday, wday, mon_cent, year;
+	unsigned long status;
+
+	status = readl(&rtc->status);
+	if ((status & RTC_STATE_RUN) != RTC_STATE_RUN) {
+		printf("RTC doesn't run\n");
+		return -1;
+	}
+	if ((status & RTC_STATE_BUSY) == RTC_STATE_BUSY)
+		udelay(20);
+
+	sec	= readl(&rtc->second);
+	min	= readl(&rtc->minutes);
+	hour	= readl(&rtc->hours);
+	mday	= readl(&rtc->day);
+	wday	= readl(&rtc->dotw);
+	mon_cent = readl(&rtc->month);
+	year	= readl(&rtc->year);
+
+	debug("Get RTC year: %02lx mon/cent: %02lx mday: %02lx wday: %02lx "
+		"hr: %02lx min: %02lx sec: %02lx\n",
+		year, mon_cent, mday, wday,
+		hour, min, sec);
+
+	tmp->tm_sec  = bcd2bin(sec  & 0x7F);
+	tmp->tm_min  = bcd2bin(min  & 0x7F);
+	tmp->tm_hour = bcd2bin(hour & 0x3F);
+	tmp->tm_mday = bcd2bin(mday & 0x3F);
+	tmp->tm_mon  = bcd2bin(mon_cent & 0x1F);
+	tmp->tm_year = bcd2bin(year) + 2000;
+	tmp->tm_wday = bcd2bin(wday & 0x07);
+	tmp->tm_yday = 0;
+	tmp->tm_isdst = 0;
+
+	debug("Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+	return 0;
+}
+
+int rtc_set(struct rtc_time *tmp)
+{
+	struct davinci_rtc *rtc = (struct davinci_rtc *)DAVINCI_RTC_BASE;
+
+	debug("Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+	writel(bin2bcd(tmp->tm_year % 100), &rtc->year);
+	writel(bin2bcd(tmp->tm_mon), &rtc->month);
+
+	writel(bin2bcd(tmp->tm_wday), &rtc->dotw);
+	writel(bin2bcd(tmp->tm_mday), &rtc->day);
+	writel(bin2bcd(tmp->tm_hour), &rtc->hours);
+	writel(bin2bcd(tmp->tm_min), &rtc->minutes);
+	writel(bin2bcd(tmp->tm_sec), &rtc->second);
+	return 0;
+}
+
+void rtc_reset(void)
+{
+	struct davinci_rtc *rtc = (struct davinci_rtc *)DAVINCI_RTC_BASE;
+
+	/* run RTC counter */
+	writel(0x01, &rtc->ctrl);
+}
+#endif
diff --git a/marvell/uboot/drivers/rtc/ds12887.c b/marvell/uboot/drivers/rtc/ds12887.c
new file mode 100644
index 0000000..d8a519b
--- /dev/null
+++ b/marvell/uboot/drivers/rtc/ds12887.c
@@ -0,0 +1,217 @@
+/*
+ * (C) Copyright 2003
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+/*
+ * Date & Time support for the DS12887 RTC
+ */
+
+#undef	RTC_DEBUG
+
+#include <common.h>
+#include <command.h>
+#include <config.h>
+#include <rtc.h>
+
+#if defined(CONFIG_CMD_DATE)
+
+#define RTC_SECONDS			0x00
+#define RTC_SECONDS_ALARM		0x01
+#define RTC_MINUTES			0x02
+#define RTC_MINUTES_ALARM		0x03
+#define RTC_HOURS			0x04
+#define RTC_HOURS_ALARM			0x05
+#define RTC_DAY_OF_WEEK			0x06
+#define RTC_DATE_OF_MONTH		0x07
+#define RTC_MONTH			0x08
+#define RTC_YEAR			0x09
+#define RTC_CONTROL_A			0x0A
+#define RTC_CONTROL_B			0x0B
+#define RTC_CONTROL_C			0x0C
+#define RTC_CONTROL_D			0x0D
+
+#define RTC_CA_UIP			0x80
+#define RTC_CB_DM			0x04
+#define RTC_CB_24_12			0x02
+#define RTC_CB_SET			0x80
+
+#if defined(CONFIG_ATC)
+
+static uchar rtc_read (uchar reg)
+{
+	uchar val;
+
+	*(volatile unsigned char*)(RTC_PORT_ADDR) = reg;
+	__asm__ __volatile__ ("sync");
+
+	val = *(volatile unsigned char*)(RTC_PORT_DATA);
+	return (val);
+}
+
+static void rtc_write (uchar reg, uchar val)
+{
+	*(volatile unsigned char*)(RTC_PORT_ADDR) = reg;
+	__asm__ __volatile__ ("sync");
+
+	*(volatile unsigned char*)(RTC_PORT_DATA) = val;
+	__asm__ __volatile__ ("sync");
+}
+
+#else
+# error Board specific rtc access functions should be supplied
+#endif
+
+int rtc_get (struct rtc_time *tmp)
+{
+	uchar sec, min, hour, mday, wday, mon, year;
+
+	/* check if rtc is available for access */
+	while( rtc_read(RTC_CONTROL_A) & RTC_CA_UIP)
+		;
+
+	sec  = rtc_read(RTC_SECONDS);
+	min  = rtc_read(RTC_MINUTES);
+	hour = rtc_read(RTC_HOURS);
+	mday = rtc_read(RTC_DATE_OF_MONTH);
+	wday = rtc_read(RTC_DAY_OF_WEEK);
+	mon  = rtc_read(RTC_MONTH);
+	year = rtc_read(RTC_YEAR);
+
+#ifdef RTC_DEBUG
+	printf( "Get RTC year: %d; mon: %d; mday: %d; wday: %d; "
+		"hr: %d; min: %d; sec: %d\n",
+		year, mon, mday, wday, hour, min, sec );
+
+	printf ( "Alarms: hour: %02x min: %02x sec: %02x\n",
+		 rtc_read (RTC_HOURS_ALARM),
+		 rtc_read (RTC_MINUTES_ALARM),
+		 rtc_read (RTC_SECONDS_ALARM) );
+#endif
+
+	if( !(rtc_read(RTC_CONTROL_B) & RTC_CB_DM))
+	{	    /* Information is in BCD format */
+printf(" Get: Convert BSD to BIN\n");
+		tmp->tm_sec  = bcd2bin (sec  & 0x7F);
+		tmp->tm_min  = bcd2bin (min  & 0x7F);
+		tmp->tm_hour = bcd2bin (hour & 0x3F);
+		tmp->tm_mday = bcd2bin (mday & 0x3F);
+		tmp->tm_mon  = bcd2bin (mon & 0x1F);
+		tmp->tm_year = bcd2bin (year);
+		tmp->tm_wday = bcd2bin (wday & 0x07);
+	}
+else
+	{
+		tmp->tm_sec  = sec  & 0x7F;
+		tmp->tm_min  = min  & 0x7F;
+		tmp->tm_hour = hour & 0x3F;
+		tmp->tm_mday = mday & 0x3F;
+		tmp->tm_mon  = mon & 0x1F;
+		tmp->tm_year = year;
+		tmp->tm_wday = wday & 0x07;
+	}
+
+
+	if(tmp->tm_year<70)
+		tmp->tm_year+=2000;
+	else
+		tmp->tm_year+=1900;
+
+	tmp->tm_yday = 0;
+	tmp->tm_isdst= 0;
+#ifdef RTC_DEBUG
+	printf ( "Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+#endif
+
+	return 0;
+}
+
+int rtc_set (struct rtc_time *tmp)
+{
+	uchar save_ctrl_b;
+	uchar sec, min, hour, mday, wday, mon, year;
+
+#ifdef RTC_DEBUG
+	printf ( "Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+#endif
+
+	if( !(rtc_read(RTC_CONTROL_B) & RTC_CB_DM))
+	{	    /* Information is in BCD format */
+		year = bin2bcd(tmp->tm_year % 100);
+		mon  = bin2bcd(tmp->tm_mon);
+		wday = bin2bcd(tmp->tm_wday);
+		mday = bin2bcd(tmp->tm_mday);
+		hour = bin2bcd(tmp->tm_hour);
+		min  = bin2bcd(tmp->tm_min);
+		sec  = bin2bcd(tmp->tm_sec);
+	}
+	else
+	{
+		year = tmp->tm_year % 100;
+		mon  = tmp->tm_mon;
+		wday = tmp->tm_wday;
+		mday = tmp->tm_mday;
+		hour = tmp->tm_hour;
+		min  = tmp->tm_min;
+		sec  = tmp->tm_sec;
+	}
+
+	/* disables the RTC to update the regs */
+	save_ctrl_b = rtc_read(RTC_CONTROL_B);
+	save_ctrl_b |= RTC_CB_SET;
+	rtc_write(RTC_CONTROL_B, save_ctrl_b);
+
+	rtc_write (RTC_YEAR, year);
+	rtc_write (RTC_MONTH, mon);
+	rtc_write (RTC_DAY_OF_WEEK, wday);
+	rtc_write (RTC_DATE_OF_MONTH, mday);
+	rtc_write (RTC_HOURS, hour);
+	rtc_write (RTC_MINUTES, min);
+	rtc_write (RTC_SECONDS, sec);
+
+	/* enables the RTC to update the regs */
+	save_ctrl_b &= ~RTC_CB_SET;
+	rtc_write(RTC_CONTROL_B, save_ctrl_b);
+
+	return 0;
+}
+
+void rtc_reset (void)
+{
+	struct rtc_time tmp;
+	uchar ctrl_rg;
+
+	ctrl_rg = RTC_CB_SET;
+	rtc_write(RTC_CONTROL_B,ctrl_rg);
+
+	tmp.tm_year = 1970 % 100;
+	tmp.tm_mon = 1;
+	tmp.tm_mday= 1;
+	tmp.tm_hour = 0;
+	tmp.tm_min = 0;
+	tmp.tm_sec = 0;
+
+#ifdef RTC_DEBUG
+	printf ( "RTC:   %4d-%02d-%02d %2d:%02d:%02d UTC\n",
+		    tmp.tm_year, tmp.tm_mon, tmp.tm_mday,
+		    tmp.tm_hour, tmp.tm_min, tmp.tm_sec);
+#endif
+
+	ctrl_rg = RTC_CB_SET | RTC_CB_24_12 | RTC_CB_DM;
+	rtc_write(RTC_CONTROL_B,ctrl_rg);
+	rtc_set(&tmp);
+
+	rtc_write(RTC_HOURS_ALARM, 0),
+	rtc_write(RTC_MINUTES_ALARM, 0),
+	rtc_write(RTC_SECONDS_ALARM, 0);
+
+	ctrl_rg = RTC_CB_24_12 | RTC_CB_DM;
+	rtc_write(RTC_CONTROL_B,ctrl_rg);
+}
+
+#endif
diff --git a/marvell/uboot/drivers/rtc/ds1302.c b/marvell/uboot/drivers/rtc/ds1302.c
new file mode 100644
index 0000000..87ddd01
--- /dev/null
+++ b/marvell/uboot/drivers/rtc/ds1302.c
@@ -0,0 +1,332 @@
+/*
+ * ds1302.c - Support for the Dallas Semiconductor DS1302 Timekeeping Chip
+ *
+ * Rex G. Feany <rfeany@zumanetworks.com>
+ *
+ */
+
+#include <common.h>
+#include <command.h>
+#include <rtc.h>
+
+#if defined(CONFIG_CMD_DATE)
+
+/* GPP Pins */
+#define DATA		0x200
+#define SCLK		0x400
+#define RST		0x800
+
+/* Happy Fun Defines(tm) */
+#define RESET		rtc_go_low(RST), rtc_go_low(SCLK)
+#define N_RESET		rtc_go_high(RST), rtc_go_low(SCLK)
+
+#define CLOCK_HIGH	rtc_go_high(SCLK)
+#define CLOCK_LOW	rtc_go_low(SCLK)
+
+#define DATA_HIGH	rtc_go_high(DATA)
+#define DATA_LOW	rtc_go_low(DATA)
+#define DATA_READ	(GTREGREAD(GPP_VALUE) & DATA)
+
+#undef RTC_DEBUG
+
+#ifdef RTC_DEBUG
+#  define DPRINTF(x,args...)	printf("ds1302: " x , ##args)
+static inline void DUMP(const char *ptr, int num)
+{
+	while (num--) printf("%x ", *ptr++);
+	printf("]\n");
+}
+#else
+#  define DPRINTF(x,args...)
+#  define DUMP(ptr, num)
+#endif
+
+/* time data format for DS1302 */
+struct ds1302_st
+{
+	unsigned char CH:1;		/* clock halt 1=stop 0=start */
+	unsigned char sec10:3;
+	unsigned char sec:4;
+
+	unsigned char zero0:1;
+	unsigned char min10:3;
+	unsigned char min:4;
+
+	unsigned char fmt:1;		/* 1=12 hour 0=24 hour */
+	unsigned char zero1:1;
+	unsigned char hr10:2;	/* 10 (0-2) or am/pm (am/pm, 0-1) */
+	unsigned char hr:4;
+
+	unsigned char zero2:2;
+	unsigned char date10:2;
+	unsigned char date:4;
+
+	unsigned char zero3:3;
+	unsigned char month10:1;
+	unsigned char month:4;
+
+	unsigned char zero4:5;
+	unsigned char day:3;		/* day of week */
+
+	unsigned char year10:4;
+	unsigned char year:4;
+
+	unsigned char WP:1;		/* write protect 1=protect 0=unprot */
+	unsigned char zero5:7;
+};
+
+static int ds1302_initted=0;
+
+/* Pin control */
+static inline void
+rtc_go_high(unsigned int mask)
+{
+	unsigned int f = GTREGREAD(GPP_VALUE) | mask;
+
+	GT_REG_WRITE(GPP_VALUE, f);
+}
+
+static inline void
+rtc_go_low(unsigned int mask)
+{
+	unsigned int f = GTREGREAD(GPP_VALUE) & ~mask;
+
+	GT_REG_WRITE(GPP_VALUE, f);
+}
+
+static inline void
+rtc_go_input(unsigned int mask)
+{
+	unsigned int f = GTREGREAD(GPP_IO_CONTROL) & ~mask;
+
+	GT_REG_WRITE(GPP_IO_CONTROL, f);
+}
+
+static inline void
+rtc_go_output(unsigned int mask)
+{
+	unsigned int f = GTREGREAD(GPP_IO_CONTROL) | mask;
+
+	GT_REG_WRITE(GPP_IO_CONTROL, f);
+}
+
+/* Access data in RTC */
+
+static void
+write_byte(unsigned char b)
+{
+	int i;
+	unsigned char mask=1;
+
+	for(i=0;i<8;i++) {
+		CLOCK_LOW;			/* Lower clock */
+		(b&mask)?DATA_HIGH:DATA_LOW;	/* set data */
+		udelay(1);
+		CLOCK_HIGH;		/* latch data with rising clock */
+		udelay(1);
+		mask=mask<<1;
+	}
+}
+
+static unsigned char
+read_byte(void)
+{
+	int i;
+	unsigned char mask=1;
+	unsigned char b=0;
+
+	for(i=0;i<8;i++) {
+		CLOCK_LOW;
+		udelay(1);
+		if (DATA_READ) b|=mask;	/* if this bit is high, set in b */
+		CLOCK_HIGH;		/* clock out next bit */
+		udelay(1);
+		mask=mask<<1;
+	}
+	return b;
+}
+
+static void
+read_ser_drv(unsigned char addr, unsigned char *buf, int count)
+{
+	int i;
+#ifdef RTC_DEBUG
+	char *foo = buf;
+#endif
+
+	DPRINTF("READ 0x%x bytes @ 0x%x [ ", count, addr);
+
+	addr|=1;	/* READ */
+	N_RESET;
+	udelay(4);
+	write_byte(addr);
+	rtc_go_input(DATA); /* Put gpp pin into input mode */
+	udelay(1);
+	for(i=0;i<count;i++) *(buf++)=read_byte();
+	RESET;
+	rtc_go_output(DATA);/* Reset gpp for output */
+	udelay(4);
+
+	DUMP(foo, count);
+}
+
+static void
+write_ser_drv(unsigned char addr, unsigned char *buf, int count)
+{
+	int i;
+
+	DPRINTF("WRITE 0x%x bytes @ 0x%x [ ", count, addr);
+	DUMP(buf, count);
+
+	addr&=~1;	/* WRITE */
+	N_RESET;
+	udelay(4);
+	write_byte(addr);
+	for(i=0;i<count;i++) write_byte(*(buf++));
+	RESET;
+	udelay(4);
+
+}
+
+void
+rtc_init(void)
+{
+	struct ds1302_st bbclk;
+	unsigned char b;
+	int mod;
+
+	DPRINTF("init\n");
+
+	rtc_go_output(DATA|SCLK|RST);
+
+	/* disable write protect */
+	b = 0;
+	write_ser_drv(0x8e,&b,1);
+
+	/* enable trickle */
+	b = 0xa5;	/* 1010.0101 */
+	write_ser_drv(0x90,&b,1);
+
+	/* read burst */
+	read_ser_drv(0xbe, (unsigned char *)&bbclk, 8);
+
+	/* Sanity checks */
+	mod = 0;
+	if (bbclk.CH) {
+		printf("ds1302: Clock was halted, starting clock\n");
+		bbclk.CH=0;
+		mod=1;
+	}
+
+	if (bbclk.fmt) {
+		printf("ds1302: Clock was in 12 hour mode, fixing\n");
+		bbclk.fmt=0;
+		mod=1;
+	}
+
+	if (bbclk.year>9) {
+		printf("ds1302: Year was corrupted, fixing\n");
+		bbclk.year10=100/10;	/* 2000 - why not? ;) */
+		bbclk.year=0;
+		mod=1;
+	}
+
+	/* Write out the changes if needed */
+	if (mod) {
+		/* enable write protect */
+		bbclk.WP = 1;
+		write_ser_drv(0xbe,(unsigned char *)&bbclk,8);
+	} else {
+		/* Else just turn write protect on */
+		b = 0x80;
+		write_ser_drv(0x8e,&b,1);
+	}
+	DPRINTF("init done\n");
+
+	ds1302_initted=1;
+}
+
+void
+rtc_reset(void)
+{
+	if(!ds1302_initted) rtc_init();
+	/* TODO */
+}
+
+int
+rtc_get(struct rtc_time *tmp)
+{
+	int rel = 0;
+	struct ds1302_st bbclk;
+
+	if(!ds1302_initted) rtc_init();
+
+	read_ser_drv(0xbe,(unsigned char *)&bbclk, 8);      /* read burst */
+
+	if (bbclk.CH) {
+		printf("ds1302: rtc_get: Clock was halted, clock probably "
+			"corrupt\n");
+		rel = -1;
+	}
+
+	tmp->tm_sec=10*bbclk.sec10+bbclk.sec;
+	tmp->tm_min=10*bbclk.min10+bbclk.min;
+	tmp->tm_hour=10*bbclk.hr10+bbclk.hr;
+	tmp->tm_wday=bbclk.day;
+	tmp->tm_mday=10*bbclk.date10+bbclk.date;
+	tmp->tm_mon=10*bbclk.month10+bbclk.month;
+	tmp->tm_year=10*bbclk.year10+bbclk.year + 1900;
+
+	tmp->tm_yday = 0;
+	tmp->tm_isdst= 0;
+
+	DPRINTF("Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec );
+
+	return rel;
+}
+
+int rtc_set(struct rtc_time *tmp)
+{
+	struct ds1302_st bbclk;
+	unsigned char b=0;
+
+	if(!ds1302_initted) rtc_init();
+
+	DPRINTF("Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+	memset(&bbclk,0,sizeof(bbclk));
+	bbclk.CH=0; /* dont halt */
+	bbclk.WP=1; /* write protect when we're done */
+
+	bbclk.sec10=tmp->tm_sec/10;
+	bbclk.sec=tmp->tm_sec%10;
+
+	bbclk.min10=tmp->tm_min/10;
+	bbclk.min=tmp->tm_min%10;
+
+	bbclk.hr10=tmp->tm_hour/10;
+	bbclk.hr=tmp->tm_hour%10;
+
+	bbclk.day=tmp->tm_wday;
+
+	bbclk.date10=tmp->tm_mday/10;
+	bbclk.date=tmp->tm_mday%10;
+
+	bbclk.month10=tmp->tm_mon/10;
+	bbclk.month=tmp->tm_mon%10;
+
+	tmp->tm_year -= 1900;
+	bbclk.year10=tmp->tm_year/10;
+	bbclk.year=tmp->tm_year%10;
+
+	write_ser_drv(0x8e,&b,1);           /* disable write protect */
+	write_ser_drv(0xbe,(unsigned char *)&bbclk, 8);     /* write burst */
+
+	return 0;
+}
+
+#endif
diff --git a/marvell/uboot/drivers/rtc/ds1306.c b/marvell/uboot/drivers/rtc/ds1306.c
new file mode 100644
index 0000000..1ec1837
--- /dev/null
+++ b/marvell/uboot/drivers/rtc/ds1306.c
@@ -0,0 +1,443 @@
+/*
+ * (C) Copyright 2002 SIXNET, dge@sixnetio.com.
+ *
+ * (C) Copyright 2004, Li-Pro.Net <www.li-pro.net>
+ * Stephan Linz <linz@li-pro.net>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+/*
+ * Date & Time support for DS1306 RTC using SPI:
+ *
+ *    - SXNI855T:    it uses its own soft SPI here in this file
+ *    - all other:   use the external spi_xfer() function
+ *                   (see include/spi.h)
+ */
+
+#include <common.h>
+#include <command.h>
+#include <rtc.h>
+#include <spi.h>
+
+#if defined(CONFIG_CMD_DATE)
+
+#define	RTC_SECONDS		0x00
+#define	RTC_MINUTES		0x01
+#define	RTC_HOURS		0x02
+#define	RTC_DAY_OF_WEEK		0x03
+#define	RTC_DATE_OF_MONTH	0x04
+#define	RTC_MONTH		0x05
+#define	RTC_YEAR		0x06
+
+#define	RTC_SECONDS_ALARM0	0x07
+#define	RTC_MINUTES_ALARM0	0x08
+#define	RTC_HOURS_ALARM0	0x09
+#define	RTC_DAY_OF_WEEK_ALARM0	0x0a
+
+#define	RTC_SECONDS_ALARM1	0x0b
+#define	RTC_MINUTES_ALARM1	0x0c
+#define	RTC_HOURS_ALARM1	0x0d
+#define	RTC_DAY_OF_WEEK_ALARM1	0x0e
+
+#define	RTC_CONTROL		0x0f
+#define	RTC_STATUS		0x10
+#define	RTC_TRICKLE_CHARGER	0x11
+
+#define	RTC_USER_RAM_BASE	0x20
+
+/* ************************************************************************* */
+#ifdef CONFIG_SXNI855T		/* !!! SHOULD BE CHANGED TO NEW CODE !!! */
+
+static void soft_spi_send (unsigned char n);
+static unsigned char soft_spi_read (void);
+static void init_spi (void);
+
+/*-----------------------------------------------------------------------
+ * Definitions
+ */
+
+#define	PB_SPISCK	0x00000002	/* PB 30 */
+#define PB_SPIMOSI	0x00000004	/* PB 29 */
+#define PB_SPIMISO	0x00000008	/* PB 28 */
+#define PB_SPI_CE	0x00010000	/* PB 15 */
+
+/* ------------------------------------------------------------------------- */
+
+/* read clock time from DS1306 and return it in *tmp */
+int rtc_get (struct rtc_time *tmp)
+{
+	volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
+	unsigned char spi_byte;	/* Data Byte */
+
+	init_spi ();		/* set port B for software SPI */
+
+	/* Now we can enable the DS1306 RTC */
+	immap->im_cpm.cp_pbdat |= PB_SPI_CE;
+	udelay (10);
+
+	/* Shift out the address (0) of the time in the Clock Chip */
+	soft_spi_send (0);
+
+	/* Put the clock readings into the rtc_time structure */
+	tmp->tm_sec = bcd2bin (soft_spi_read ());	/* Read seconds */
+	tmp->tm_min = bcd2bin (soft_spi_read ());	/* Read minutes */
+
+	/* Hours are trickier */
+	spi_byte = soft_spi_read ();	/* Read Hours into temporary value */
+	if (spi_byte & 0x40) {
+		/* 12 hour mode bit is set (time is in 1-12 format) */
+		if (spi_byte & 0x20) {
+			/* since PM we add 11 to get 0-23 for hours */
+			tmp->tm_hour = (bcd2bin (spi_byte & 0x1F)) + 11;
+		} else {
+			/* since AM we subtract 1 to get 0-23 for hours */
+			tmp->tm_hour = (bcd2bin (spi_byte & 0x1F)) - 1;
+		}
+	} else {
+		/* Otherwise, 0-23 hour format */
+		tmp->tm_hour = (bcd2bin (spi_byte & 0x3F));
+	}
+
+	soft_spi_read ();	/* Read and discard Day of week */
+	tmp->tm_mday = bcd2bin (soft_spi_read ());	/* Read Day of the Month */
+	tmp->tm_mon = bcd2bin (soft_spi_read ());	/* Read Month */
+
+	/* Read Year and convert to this century */
+	tmp->tm_year = bcd2bin (soft_spi_read ()) + 2000;
+
+	/* Now we can disable the DS1306 RTC */
+	immap->im_cpm.cp_pbdat &= ~PB_SPI_CE;	/* Disable DS1306 Chip */
+	udelay (10);
+
+	GregorianDay (tmp);	/* Determine the day of week */
+
+	debug ("Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+	       tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+	       tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+	return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+
+/* set clock time in DS1306 RTC and in MPC8xx RTC */
+int rtc_set (struct rtc_time *tmp)
+{
+	volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
+
+	init_spi ();		/* set port B for software SPI */
+
+	/* Now we can enable the DS1306 RTC */
+	immap->im_cpm.cp_pbdat |= PB_SPI_CE;	/* Enable DS1306 Chip */
+	udelay (10);
+
+	/* First disable write protect in the clock chip control register */
+	soft_spi_send (0x8F);	/* send address of the control register */
+	soft_spi_send (0x00);	/* send control register contents */
+
+	/* Now disable the DS1306 to terminate the write */
+	immap->im_cpm.cp_pbdat &= ~PB_SPI_CE;
+	udelay (10);
+
+	/* Now enable the DS1306 to initiate a new write */
+	immap->im_cpm.cp_pbdat |= PB_SPI_CE;
+	udelay (10);
+
+	/* Next, send the address of the clock time write registers */
+	soft_spi_send (0x80);	/* send address of the first time register */
+
+	/* Use Burst Mode to send all of the time data to the clock */
+	bin2bcd (tmp->tm_sec);
+	soft_spi_send (bin2bcd (tmp->tm_sec));	/* Send Seconds */
+	soft_spi_send (bin2bcd (tmp->tm_min));	/* Send Minutes */
+	soft_spi_send (bin2bcd (tmp->tm_hour));	/* Send Hour */
+	soft_spi_send (bin2bcd (tmp->tm_wday));	/* Send Day of the Week */
+	soft_spi_send (bin2bcd (tmp->tm_mday));	/* Send Day of Month */
+	soft_spi_send (bin2bcd (tmp->tm_mon));	/* Send Month */
+	soft_spi_send (bin2bcd (tmp->tm_year - 2000));	/* Send Year */
+
+	/* Now we can disable the Clock chip to terminate the burst write */
+	immap->im_cpm.cp_pbdat &= ~PB_SPI_CE;	/* Disable DS1306 Chip */
+	udelay (10);
+
+	/* Now we can enable the Clock chip to initiate a new write */
+	immap->im_cpm.cp_pbdat |= PB_SPI_CE;	/* Enable DS1306 Chip */
+	udelay (10);
+
+	/* First we Enable write protect in the clock chip control register */
+	soft_spi_send (0x8F);	/* send address of the control register */
+	soft_spi_send (0x40);	/* send out Control Register contents */
+
+	/* Now disable the DS1306 */
+	immap->im_cpm.cp_pbdat &= ~PB_SPI_CE;	/*  Disable DS1306 Chip */
+	udelay (10);
+
+	/* Set standard MPC8xx clock to the same time so Linux will
+	 * see the time even if it doesn't have a DS1306 clock driver.
+	 * This helps with experimenting with standard kernels.
+	 */
+	{
+		ulong tim;
+
+		tim = mktime (tmp->tm_year, tmp->tm_mon, tmp->tm_mday,
+			      tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+		immap->im_sitk.sitk_rtck = KAPWR_KEY;
+		immap->im_sit.sit_rtc = tim;
+	}
+
+	debug ("Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+	       tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+	       tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+	return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+
+/* Initialize Port B for software SPI */
+static void init_spi (void)
+{
+	volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
+
+	/* Force output pins to begin at logic 0 */
+	immap->im_cpm.cp_pbdat &= ~(PB_SPI_CE | PB_SPIMOSI | PB_SPISCK);
+
+	/* Set these 3 signals as outputs */
+	immap->im_cpm.cp_pbdir |= (PB_SPIMOSI | PB_SPI_CE | PB_SPISCK);
+
+	immap->im_cpm.cp_pbdir &= ~PB_SPIMISO;	/* Make MISO pin an input */
+	udelay (10);
+}
+
+/* ------------------------------------------------------------------------- */
+
+/* NOTE: soft_spi_send() assumes that the I/O lines are configured already */
+static void soft_spi_send (unsigned char n)
+{
+	volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
+	unsigned char bitpos;	/* bit position to receive */
+	unsigned char i;	/* Loop Control */
+
+	/* bit position to send, start with most significant bit */
+	bitpos = 0x80;
+
+	/* Send 8 bits to software SPI */
+	for (i = 0; i < 8; i++) {	/* Loop for 8 bits */
+		immap->im_cpm.cp_pbdat |= PB_SPISCK;	/* Raise SCK */
+
+		if (n & bitpos)
+			immap->im_cpm.cp_pbdat |= PB_SPIMOSI;	/* Set MOSI to 1 */
+		else
+			immap->im_cpm.cp_pbdat &= ~PB_SPIMOSI;	/* Set MOSI to 0 */
+		udelay (10);
+
+		immap->im_cpm.cp_pbdat &= ~PB_SPISCK;	/* Lower SCK */
+		udelay (10);
+
+		bitpos >>= 1;	/* Shift for next bit position */
+	}
+}
+
+/* ------------------------------------------------------------------------- */
+
+/* NOTE: soft_spi_read() assumes that the I/O lines are configured already */
+static unsigned char soft_spi_read (void)
+{
+	volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
+
+	unsigned char spi_byte = 0;	/* Return value, assume success */
+	unsigned char bitpos;	/* bit position to receive */
+	unsigned char i;	/* Loop Control */
+
+	/* bit position to receive, start with most significant bit */
+	bitpos = 0x80;
+
+	/* Read 8 bits here */
+	for (i = 0; i < 8; i++) {	/* Do 8 bits in loop */
+		immap->im_cpm.cp_pbdat |= PB_SPISCK;	/* Raise SCK */
+		udelay (10);
+		if (immap->im_cpm.cp_pbdat & PB_SPIMISO)	/* Get a bit of data */
+			spi_byte |= bitpos;	/* Set data accordingly */
+		immap->im_cpm.cp_pbdat &= ~PB_SPISCK;	/* Lower SCK */
+		udelay (10);
+		bitpos >>= 1;	/* Shift for next bit position */
+	}
+
+	return spi_byte;	/* Return the byte read */
+}
+
+/* ------------------------------------------------------------------------- */
+
+void rtc_reset (void)
+{
+	return;			/* nothing to do */
+}
+
+#else  /* not CONFIG_SXNI855T */
+/* ************************************************************************* */
+
+static unsigned char rtc_read (unsigned char reg);
+static void rtc_write (unsigned char reg, unsigned char val);
+
+static struct spi_slave *slave;
+
+/* read clock time from DS1306 and return it in *tmp */
+int rtc_get (struct rtc_time *tmp)
+{
+	unsigned char sec, min, hour, mday, wday, mon, year;
+
+	/*
+	 * Assuming Vcc = 2.0V (lowest speed)
+	 *
+	 * REVISIT: If we add an rtc_init() function we can do this
+	 * step just once.
+	 */
+	if (!slave) {
+		slave = spi_setup_slave(0, CONFIG_SYS_SPI_RTC_DEVID, 600000,
+				SPI_MODE_3 | SPI_CS_HIGH);
+		if (!slave)
+			return;
+	}
+
+	if (spi_claim_bus(slave))
+		return;
+
+	sec = rtc_read (RTC_SECONDS);
+	min = rtc_read (RTC_MINUTES);
+	hour = rtc_read (RTC_HOURS);
+	mday = rtc_read (RTC_DATE_OF_MONTH);
+	wday = rtc_read (RTC_DAY_OF_WEEK);
+	mon = rtc_read (RTC_MONTH);
+	year = rtc_read (RTC_YEAR);
+
+	spi_release_bus(slave);
+
+	debug ("Get RTC year: %02x mon: %02x mday: %02x wday: %02x "
+	       "hr: %02x min: %02x sec: %02x\n",
+	       year, mon, mday, wday, hour, min, sec);
+	debug ("Alarms[0]: wday: %02x hour: %02x min: %02x sec: %02x\n",
+	       rtc_read (RTC_DAY_OF_WEEK_ALARM0),
+	       rtc_read (RTC_HOURS_ALARM0),
+	       rtc_read (RTC_MINUTES_ALARM0), rtc_read (RTC_SECONDS_ALARM0));
+	debug ("Alarms[1]: wday: %02x hour: %02x min: %02x sec: %02x\n",
+	       rtc_read (RTC_DAY_OF_WEEK_ALARM1),
+	       rtc_read (RTC_HOURS_ALARM1),
+	       rtc_read (RTC_MINUTES_ALARM1), rtc_read (RTC_SECONDS_ALARM1));
+
+	tmp->tm_sec = bcd2bin (sec & 0x7F);	/* convert Seconds */
+	tmp->tm_min = bcd2bin (min & 0x7F);	/* convert Minutes */
+
+	/* convert Hours */
+	tmp->tm_hour = (hour & 0x40)
+		? ((hour & 0x20)	/* 12 hour mode */
+		   ? bcd2bin (hour & 0x1F) + 11	/* PM */
+		   : bcd2bin (hour & 0x1F) - 1	/* AM */
+		)
+		: bcd2bin (hour & 0x3F);	/* 24 hour mode */
+
+	tmp->tm_mday = bcd2bin (mday & 0x3F);	/* convert Day of the Month */
+	tmp->tm_mon = bcd2bin (mon & 0x1F);	/* convert Month */
+	tmp->tm_year = bcd2bin (year) + 2000;	/* convert Year */
+	tmp->tm_wday = bcd2bin (wday & 0x07) - 1;	/* convert Day of the Week */
+	tmp->tm_yday = 0;
+	tmp->tm_isdst = 0;
+
+	debug ("Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+	       tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+	       tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+	return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+
+/* set clock time from *tmp in DS1306 RTC */
+int rtc_set (struct rtc_time *tmp)
+{
+	/* Assuming Vcc = 2.0V (lowest speed) */
+	if (!slave) {
+		slave = spi_setup_slave(0, CONFIG_SYS_SPI_RTC_DEVID, 600000,
+				SPI_MODE_3 | SPI_CS_HIGH);
+		if (!slave)
+			return;
+	}
+
+	if (spi_claim_bus(slave))
+		return;
+
+	debug ("Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+	       tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+	       tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+	rtc_write (RTC_SECONDS, bin2bcd (tmp->tm_sec));
+	rtc_write (RTC_MINUTES, bin2bcd (tmp->tm_min));
+	rtc_write (RTC_HOURS, bin2bcd (tmp->tm_hour));
+	rtc_write (RTC_DAY_OF_WEEK, bin2bcd (tmp->tm_wday + 1));
+	rtc_write (RTC_DATE_OF_MONTH, bin2bcd (tmp->tm_mday));
+	rtc_write (RTC_MONTH, bin2bcd (tmp->tm_mon));
+	rtc_write (RTC_YEAR, bin2bcd (tmp->tm_year - 2000));
+
+	spi_release_bus(slave);
+}
+
+/* ------------------------------------------------------------------------- */
+
+/* reset the DS1306 */
+void rtc_reset (void)
+{
+	/* Assuming Vcc = 2.0V (lowest speed) */
+	if (!slave) {
+		slave = spi_setup_slave(0, CONFIG_SYS_SPI_RTC_DEVID, 600000,
+				SPI_MODE_3 | SPI_CS_HIGH);
+		if (!slave)
+			return;
+	}
+
+	if (spi_claim_bus(slave))
+		return;
+
+	/* clear the control register */
+	rtc_write (RTC_CONTROL, 0x00);	/* 1st step: reset WP */
+	rtc_write (RTC_CONTROL, 0x00);	/* 2nd step: reset 1Hz, AIE1, AIE0 */
+
+	/* reset all alarms */
+	rtc_write (RTC_SECONDS_ALARM0, 0x00);
+	rtc_write (RTC_SECONDS_ALARM1, 0x00);
+	rtc_write (RTC_MINUTES_ALARM0, 0x00);
+	rtc_write (RTC_MINUTES_ALARM1, 0x00);
+	rtc_write (RTC_HOURS_ALARM0, 0x00);
+	rtc_write (RTC_HOURS_ALARM1, 0x00);
+	rtc_write (RTC_DAY_OF_WEEK_ALARM0, 0x00);
+	rtc_write (RTC_DAY_OF_WEEK_ALARM1, 0x00);
+
+	spi_release_bus(slave);
+}
+
+/* ------------------------------------------------------------------------- */
+
+static unsigned char rtc_read (unsigned char reg)
+{
+	int ret;
+
+	ret = spi_w8r8(slave, reg);
+	return ret < 0 ? 0 : ret;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static void rtc_write (unsigned char reg, unsigned char val)
+{
+	unsigned char dout[2];	/* SPI Output Data Bytes */
+	unsigned char din[2];	/* SPI Input Data Bytes */
+
+	dout[0] = 0x80 | reg;
+	dout[1] = val;
+
+	spi_xfer (slave, 16, dout, din, SPI_XFER_BEGIN | SPI_XFER_END);
+}
+
+#endif /* end of code exclusion (see #ifdef CONFIG_SXNI855T above) */
+
+#endif
diff --git a/marvell/uboot/drivers/rtc/ds1307.c b/marvell/uboot/drivers/rtc/ds1307.c
new file mode 100644
index 0000000..1a2bad3
--- /dev/null
+++ b/marvell/uboot/drivers/rtc/ds1307.c
@@ -0,0 +1,180 @@
+/*
+ * (C) Copyright 2001, 2002, 2003
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ * Keith Outwater, keith_outwater@mvis.com`
+ * Steven Scholz, steven.scholz@imc-berlin.de
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+/*
+ * Date & Time support (no alarms) for Dallas Semiconductor (now Maxim)
+ * DS1307 and DS1338 Real Time Clock (RTC).
+ *
+ * based on ds1337.c
+ */
+
+#include <common.h>
+#include <command.h>
+#include <rtc.h>
+#include <i2c.h>
+
+#if defined(CONFIG_CMD_DATE)
+
+/*---------------------------------------------------------------------*/
+#undef DEBUG_RTC
+
+#ifdef DEBUG_RTC
+#define DEBUGR(fmt,args...) printf(fmt ,##args)
+#else
+#define DEBUGR(fmt,args...)
+#endif
+/*---------------------------------------------------------------------*/
+
+#ifndef CONFIG_SYS_I2C_RTC_ADDR
+# define CONFIG_SYS_I2C_RTC_ADDR	0x68
+#endif
+
+#if defined(CONFIG_RTC_DS1307) && (CONFIG_SYS_I2C_SPEED > 100000)
+# error The DS1307 is specified only up to 100kHz!
+#endif
+
+/*
+ * RTC register addresses
+ */
+#define RTC_SEC_REG_ADDR	0x00
+#define RTC_MIN_REG_ADDR	0x01
+#define RTC_HR_REG_ADDR		0x02
+#define RTC_DAY_REG_ADDR	0x03
+#define RTC_DATE_REG_ADDR	0x04
+#define RTC_MON_REG_ADDR	0x05
+#define RTC_YR_REG_ADDR		0x06
+#define RTC_CTL_REG_ADDR	0x07
+
+#define RTC_SEC_BIT_CH		0x80	/* Clock Halt (in Register 0)   */
+
+#define RTC_CTL_BIT_RS0		0x01	/* Rate select 0                */
+#define RTC_CTL_BIT_RS1		0x02	/* Rate select 1                */
+#define RTC_CTL_BIT_SQWE	0x10	/* Square Wave Enable           */
+#define RTC_CTL_BIT_OUT		0x80	/* Output Control               */
+
+static uchar rtc_read (uchar reg);
+static void rtc_write (uchar reg, uchar val);
+
+/*
+ * Get the current time from the RTC
+ */
+int rtc_get (struct rtc_time *tmp)
+{
+	int rel = 0;
+	uchar sec, min, hour, mday, wday, mon, year;
+
+	sec = rtc_read (RTC_SEC_REG_ADDR);
+	min = rtc_read (RTC_MIN_REG_ADDR);
+	hour = rtc_read (RTC_HR_REG_ADDR);
+	wday = rtc_read (RTC_DAY_REG_ADDR);
+	mday = rtc_read (RTC_DATE_REG_ADDR);
+	mon = rtc_read (RTC_MON_REG_ADDR);
+	year = rtc_read (RTC_YR_REG_ADDR);
+
+	DEBUGR ("Get RTC year: %02x mon: %02x mday: %02x wday: %02x "
+		"hr: %02x min: %02x sec: %02x\n",
+		year, mon, mday, wday, hour, min, sec);
+
+	if (sec & RTC_SEC_BIT_CH) {
+		printf ("### Warning: RTC oscillator has stopped\n");
+		/* clear the CH flag */
+		rtc_write (RTC_SEC_REG_ADDR,
+			   rtc_read (RTC_SEC_REG_ADDR) & ~RTC_SEC_BIT_CH);
+		rel = -1;
+	}
+
+	tmp->tm_sec  = bcd2bin (sec & 0x7F);
+	tmp->tm_min  = bcd2bin (min & 0x7F);
+	tmp->tm_hour = bcd2bin (hour & 0x3F);
+	tmp->tm_mday = bcd2bin (mday & 0x3F);
+	tmp->tm_mon  = bcd2bin (mon & 0x1F);
+	tmp->tm_year = bcd2bin (year) + ( bcd2bin (year) >= 70 ? 1900 : 2000);
+	tmp->tm_wday = bcd2bin ((wday - 1) & 0x07);
+	tmp->tm_yday = 0;
+	tmp->tm_isdst= 0;
+
+	DEBUGR ("Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+	return rel;
+}
+
+
+/*
+ * Set the RTC
+ */
+int rtc_set (struct rtc_time *tmp)
+{
+	DEBUGR ("Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+	if (tmp->tm_year < 1970 || tmp->tm_year > 2069)
+		printf("WARNING: year should be between 1970 and 2069!\n");
+
+	rtc_write (RTC_YR_REG_ADDR, bin2bcd (tmp->tm_year % 100));
+	rtc_write (RTC_MON_REG_ADDR, bin2bcd (tmp->tm_mon));
+	rtc_write (RTC_DAY_REG_ADDR, bin2bcd (tmp->tm_wday + 1));
+	rtc_write (RTC_DATE_REG_ADDR, bin2bcd (tmp->tm_mday));
+	rtc_write (RTC_HR_REG_ADDR, bin2bcd (tmp->tm_hour));
+	rtc_write (RTC_MIN_REG_ADDR, bin2bcd (tmp->tm_min));
+	rtc_write (RTC_SEC_REG_ADDR, bin2bcd (tmp->tm_sec));
+
+	return 0;
+}
+
+
+/*
+ * Reset the RTC. We setting the date back to 1970-01-01.
+ * We also enable the oscillator output on the SQW/OUT pin and program
+ * it for 32,768 Hz output. Note that according to the datasheet, turning
+ * on the square wave output increases the current drain on the backup
+ * battery to something between 480nA and 800nA.
+ */
+void rtc_reset (void)
+{
+	struct rtc_time tmp;
+
+	rtc_write (RTC_SEC_REG_ADDR, 0x00);	/* clearing Clock Halt	*/
+	rtc_write (RTC_CTL_REG_ADDR, RTC_CTL_BIT_SQWE | RTC_CTL_BIT_RS1 | RTC_CTL_BIT_RS0);
+
+	tmp.tm_year = 1970;
+	tmp.tm_mon = 1;
+	tmp.tm_mday= 1;
+	tmp.tm_hour = 0;
+	tmp.tm_min = 0;
+	tmp.tm_sec = 0;
+
+	rtc_set(&tmp);
+
+	printf ( "RTC:   %4d-%02d-%02d %2d:%02d:%02d UTC\n",
+		tmp.tm_year, tmp.tm_mon, tmp.tm_mday,
+		tmp.tm_hour, tmp.tm_min, tmp.tm_sec);
+
+	return;
+}
+
+
+/*
+ * Helper functions
+ */
+
+static
+uchar rtc_read (uchar reg)
+{
+	return (i2c_reg_read (CONFIG_SYS_I2C_RTC_ADDR, reg));
+}
+
+
+static void rtc_write (uchar reg, uchar val)
+{
+	i2c_reg_write (CONFIG_SYS_I2C_RTC_ADDR, reg, val);
+}
+#endif
diff --git a/marvell/uboot/drivers/rtc/ds1337.c b/marvell/uboot/drivers/rtc/ds1337.c
new file mode 100644
index 0000000..dae1b3c
--- /dev/null
+++ b/marvell/uboot/drivers/rtc/ds1337.c
@@ -0,0 +1,195 @@
+/*
+ * (C) Copyright 2001-2008
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ * Keith Outwater, keith_outwater@mvis.com`
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+/*
+ * Date & Time support (no alarms) for Dallas Semiconductor (now Maxim)
+ * DS1337 Real Time Clock (RTC).
+ */
+
+#include <common.h>
+#include <command.h>
+#include <rtc.h>
+#include <i2c.h>
+
+#if defined(CONFIG_CMD_DATE)
+
+/*
+ * RTC register addresses
+ */
+#if defined CONFIG_RTC_DS1337
+#define RTC_SEC_REG_ADDR	0x0
+#define RTC_MIN_REG_ADDR	0x1
+#define RTC_HR_REG_ADDR		0x2
+#define RTC_DAY_REG_ADDR	0x3
+#define RTC_DATE_REG_ADDR	0x4
+#define RTC_MON_REG_ADDR	0x5
+#define RTC_YR_REG_ADDR		0x6
+#define RTC_CTL_REG_ADDR	0x0e
+#define RTC_STAT_REG_ADDR	0x0f
+#define RTC_TC_REG_ADDR		0x10
+#elif defined CONFIG_RTC_DS1388
+#define RTC_SEC_REG_ADDR	0x1
+#define RTC_MIN_REG_ADDR	0x2
+#define RTC_HR_REG_ADDR		0x3
+#define RTC_DAY_REG_ADDR	0x4
+#define RTC_DATE_REG_ADDR	0x5
+#define RTC_MON_REG_ADDR	0x6
+#define RTC_YR_REG_ADDR		0x7
+#define RTC_CTL_REG_ADDR	0x0c
+#define RTC_STAT_REG_ADDR	0x0b
+#define RTC_TC_REG_ADDR		0x0a
+#endif
+
+/*
+ * RTC control register bits
+ */
+#define RTC_CTL_BIT_A1IE	0x1	/* Alarm 1 interrupt enable	*/
+#define RTC_CTL_BIT_A2IE	0x2	/* Alarm 2 interrupt enable	*/
+#define RTC_CTL_BIT_INTCN	0x4	/* Interrupt control		*/
+#define RTC_CTL_BIT_RS1		0x8	/* Rate select 1		*/
+#define RTC_CTL_BIT_RS2		0x10	/* Rate select 2		*/
+#define RTC_CTL_BIT_DOSC	0x80	/* Disable Oscillator		*/
+
+/*
+ * RTC status register bits
+ */
+#define RTC_STAT_BIT_A1F	0x1	/* Alarm 1 flag			*/
+#define RTC_STAT_BIT_A2F	0x2	/* Alarm 2 flag			*/
+#define RTC_STAT_BIT_OSF	0x80	/* Oscillator stop flag		*/
+
+
+static uchar rtc_read (uchar reg);
+static void rtc_write (uchar reg, uchar val);
+
+/*
+ * Get the current time from the RTC
+ */
+int rtc_get (struct rtc_time *tmp)
+{
+	int rel = 0;
+	uchar sec, min, hour, mday, wday, mon_cent, year, control, status;
+
+	control = rtc_read (RTC_CTL_REG_ADDR);
+	status = rtc_read (RTC_STAT_REG_ADDR);
+	sec = rtc_read (RTC_SEC_REG_ADDR);
+	min = rtc_read (RTC_MIN_REG_ADDR);
+	hour = rtc_read (RTC_HR_REG_ADDR);
+	wday = rtc_read (RTC_DAY_REG_ADDR);
+	mday = rtc_read (RTC_DATE_REG_ADDR);
+	mon_cent = rtc_read (RTC_MON_REG_ADDR);
+	year = rtc_read (RTC_YR_REG_ADDR);
+
+	/* No century bit, assume year 2000 */
+#ifdef CONFIG_RTC_DS1388
+	mon_cent |= 0x80;
+#endif
+
+	debug("Get RTC year: %02x mon/cent: %02x mday: %02x wday: %02x "
+		"hr: %02x min: %02x sec: %02x control: %02x status: %02x\n",
+		year, mon_cent, mday, wday, hour, min, sec, control, status);
+
+	if (status & RTC_STAT_BIT_OSF) {
+		printf ("### Warning: RTC oscillator has stopped\n");
+		/* clear the OSF flag */
+		rtc_write (RTC_STAT_REG_ADDR,
+			   rtc_read (RTC_STAT_REG_ADDR) & ~RTC_STAT_BIT_OSF);
+		rel = -1;
+	}
+
+	tmp->tm_sec  = bcd2bin (sec & 0x7F);
+	tmp->tm_min  = bcd2bin (min & 0x7F);
+	tmp->tm_hour = bcd2bin (hour & 0x3F);
+	tmp->tm_mday = bcd2bin (mday & 0x3F);
+	tmp->tm_mon  = bcd2bin (mon_cent & 0x1F);
+	tmp->tm_year = bcd2bin (year) + ((mon_cent & 0x80) ? 2000 : 1900);
+	tmp->tm_wday = bcd2bin ((wday - 1) & 0x07);
+	tmp->tm_yday = 0;
+	tmp->tm_isdst= 0;
+
+	debug("Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+	return rel;
+}
+
+
+/*
+ * Set the RTC
+ */
+int rtc_set (struct rtc_time *tmp)
+{
+	uchar century;
+
+	debug("Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+	rtc_write (RTC_YR_REG_ADDR, bin2bcd (tmp->tm_year % 100));
+
+	century = (tmp->tm_year >= 2000) ? 0x80 : 0;
+	rtc_write (RTC_MON_REG_ADDR, bin2bcd (tmp->tm_mon) | century);
+
+	rtc_write (RTC_DAY_REG_ADDR, bin2bcd (tmp->tm_wday + 1));
+	rtc_write (RTC_DATE_REG_ADDR, bin2bcd (tmp->tm_mday));
+	rtc_write (RTC_HR_REG_ADDR, bin2bcd (tmp->tm_hour));
+	rtc_write (RTC_MIN_REG_ADDR, bin2bcd (tmp->tm_min));
+	rtc_write (RTC_SEC_REG_ADDR, bin2bcd (tmp->tm_sec));
+
+	return 0;
+}
+
+
+/*
+ * Reset the RTC.  We also enable the oscillator output on the
+ * SQW/INTB* pin and program it for 32,768 Hz output. Note that
+ * according to the datasheet, turning on the square wave output
+ * increases the current drain on the backup battery from about
+ * 600 nA to 2uA. Define CONFIG_SYS_RTC_DS1337_NOOSC if you wish to turn
+ * off the OSC output.
+ */
+
+#ifdef CONFIG_SYS_RTC_DS1337_NOOSC
+ #define RTC_DS1337_RESET_VAL \
+	(RTC_CTL_BIT_INTCN | RTC_CTL_BIT_RS1 | RTC_CTL_BIT_RS2)
+#else
+ #define RTC_DS1337_RESET_VAL (RTC_CTL_BIT_RS1 | RTC_CTL_BIT_RS2)
+#endif
+void rtc_reset (void)
+{
+#ifdef CONFIG_SYS_RTC_DS1337
+	rtc_write (RTC_CTL_REG_ADDR, RTC_DS1337_RESET_VAL);
+#elif defined CONFIG_SYS_RTC_DS1388
+	rtc_write(RTC_CTL_REG_ADDR, 0x0); /* hw default */
+#endif
+#ifdef CONFIG_SYS_DS1339_TCR_VAL
+	rtc_write (RTC_TC_REG_ADDR, CONFIG_SYS_DS1339_TCR_VAL);
+#endif
+#ifdef CONFIG_SYS_DS1388_TCR_VAL
+	rtc_write(RTC_TC_REG_ADDR, CONFIG_SYS_DS1388_TCR_VAL);
+#endif
+}
+
+
+/*
+ * Helper functions
+ */
+
+static
+uchar rtc_read (uchar reg)
+{
+	return (i2c_reg_read (CONFIG_SYS_I2C_RTC_ADDR, reg));
+}
+
+
+static void rtc_write (uchar reg, uchar val)
+{
+	i2c_reg_write (CONFIG_SYS_I2C_RTC_ADDR, reg, val);
+}
+
+#endif
diff --git a/marvell/uboot/drivers/rtc/ds1374.c b/marvell/uboot/drivers/rtc/ds1374.c
new file mode 100644
index 0000000..427b1eb
--- /dev/null
+++ b/marvell/uboot/drivers/rtc/ds1374.c
@@ -0,0 +1,235 @@
+/*
+ * (C) Copyright 2001, 2002, 2003
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ * Keith Outwater, keith_outwater@mvis.com`
+ * Steven Scholz, steven.scholz@imc-berlin.de
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+/*
+ * Date & Time support (no alarms) for Dallas Semiconductor (now Maxim)
+ * DS1374 Real Time Clock (RTC).
+ *
+ * based on ds1337.c
+ */
+
+#include <common.h>
+#include <command.h>
+#include <rtc.h>
+#include <i2c.h>
+
+#if defined(CONFIG_CMD_DATE)
+
+/*---------------------------------------------------------------------*/
+#undef DEBUG_RTC
+#define DEBUG_RTC
+
+#ifdef DEBUG_RTC
+#define DEBUGR(fmt,args...) printf(fmt ,##args)
+#else
+#define DEBUGR(fmt,args...)
+#endif
+/*---------------------------------------------------------------------*/
+
+#ifndef CONFIG_SYS_I2C_RTC_ADDR
+# define CONFIG_SYS_I2C_RTC_ADDR	0x68
+#endif
+
+#if defined(CONFIG_RTC_DS1374) && (CONFIG_SYS_I2C_SPEED > 400000)
+# error The DS1374 is specified up to 400kHz in fast mode!
+#endif
+
+/*
+ * RTC register addresses
+ */
+#define RTC_TOD_CNT_BYTE0_ADDR		0x00 /* TimeOfDay */
+#define RTC_TOD_CNT_BYTE1_ADDR		0x01
+#define RTC_TOD_CNT_BYTE2_ADDR		0x02
+#define RTC_TOD_CNT_BYTE3_ADDR		0x03
+
+#define RTC_WD_ALM_CNT_BYTE0_ADDR	0x04
+#define RTC_WD_ALM_CNT_BYTE1_ADDR	0x05
+#define RTC_WD_ALM_CNT_BYTE2_ADDR	0x06
+
+#define RTC_CTL_ADDR			0x07 /* RTC-CoNTrol-register */
+#define RTC_SR_ADDR			0x08 /* RTC-StatusRegister */
+#define RTC_TCS_DS_ADDR			0x09 /* RTC-TrickleChargeSelect DiodeSelect-register */
+
+#define RTC_CTL_BIT_AIE			(1<<0) /* Bit 0 - Alarm Interrupt enable */
+#define RTC_CTL_BIT_RS1			(1<<1) /* Bit 1/2 - Rate Select square wave output */
+#define RTC_CTL_BIT_RS2			(1<<2) /* Bit 2/2 - Rate Select square wave output */
+#define RTC_CTL_BIT_WDSTR		(1<<3) /* Bit 3 - Watchdog Reset Steering */
+#define RTC_CTL_BIT_BBSQW		(1<<4) /* Bit 4 - Battery-Backed Square-Wave */
+#define RTC_CTL_BIT_WD_ALM		(1<<5) /* Bit 5 - Watchdoc/Alarm Counter Select */
+#define RTC_CTL_BIT_WACE		(1<<6) /* Bit 6 - Watchdog/Alarm Counter Enable WACE*/
+#define RTC_CTL_BIT_EN_OSC		(1<<7) /* Bit 7 - Enable Oscilator */
+
+#define RTC_SR_BIT_AF			0x01 /* Bit 0 = Alarm Flag */
+#define RTC_SR_BIT_OSF			0x80 /* Bit 7 - Osc Stop Flag */
+
+const char RtcTodAddr[] = {
+	RTC_TOD_CNT_BYTE0_ADDR,
+	RTC_TOD_CNT_BYTE1_ADDR,
+	RTC_TOD_CNT_BYTE2_ADDR,
+	RTC_TOD_CNT_BYTE3_ADDR
+};
+
+static uchar rtc_read (uchar reg);
+static void rtc_write(uchar reg, uchar val, bool set);
+static void rtc_write_raw (uchar reg, uchar val);
+
+/*
+ * Get the current time from the RTC
+ */
+int rtc_get (struct rtc_time *tm){
+	int rel = 0;
+	unsigned long time1, time2;
+	unsigned int limit;
+	unsigned char tmp;
+	unsigned int i;
+
+	/*
+	 * Since the reads are being performed one byte at a time,
+	 * there is a chance that a carry will occur during the read.
+	 * To detect this, 2 reads are performed and compared.
+	 */
+	limit = 10;
+	do {
+		i = 4;
+		time1 = 0;
+		while (i--) {
+			tmp = rtc_read(RtcTodAddr[i]);
+			time1 = (time1 << 8) | (tmp & 0xff);
+		}
+
+		i = 4;
+		time2 = 0;
+		while (i--) {
+			tmp = rtc_read(RtcTodAddr[i]);
+			time2 = (time2 << 8) | (tmp & 0xff);
+		}
+	} while ((time1 != time2) && limit--);
+
+	if (time1 != time2) {
+		printf("can't get consistent time from rtc chip\n");
+		rel = -1;
+	}
+
+	DEBUGR ("Get RTC s since 1.1.1970: %ld\n", time1);
+
+	to_tm(time1, tm); /* To Gregorian Date */
+
+	if (rtc_read(RTC_SR_ADDR) & RTC_SR_BIT_OSF) {
+		printf ("### Warning: RTC oscillator has stopped\n");
+		rel = -1;
+	}
+
+	DEBUGR ("Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_wday,
+		tm->tm_hour, tm->tm_min, tm->tm_sec);
+
+	return rel;
+}
+
+/*
+ * Set the RTC
+ */
+int rtc_set (struct rtc_time *tmp){
+
+	unsigned long time;
+	unsigned i;
+
+	DEBUGR ("Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+	if (tmp->tm_year < 1970 || tmp->tm_year > 2069)
+		printf("WARNING: year should be between 1970 and 2069!\n");
+
+	time = mktime(tmp->tm_year, tmp->tm_mon,
+			tmp->tm_mday, tmp->tm_hour,
+			tmp->tm_min, tmp->tm_sec);
+
+	DEBUGR ("Set RTC s since 1.1.1970: %ld (0x%02lx)\n", time, time);
+
+	/* write to RTC_TOD_CNT_BYTEn_ADDR */
+	for (i = 0; i <= 3; i++) {
+		rtc_write_raw(RtcTodAddr[i], (unsigned char)(time & 0xff));
+		time = time >> 8;
+	}
+
+	/* Start clock */
+	rtc_write(RTC_CTL_ADDR, RTC_CTL_BIT_EN_OSC, false);
+
+	return 0;
+}
+
+/*
+ * Reset the RTC. We setting the date back to 1970-01-01.
+ * We also enable the oscillator output on the SQW/OUT pin and program
+ * it for 32,768 Hz output. Note that according to the datasheet, turning
+ * on the square wave output increases the current drain on the backup
+ * battery to something between 480nA and 800nA.
+ */
+void rtc_reset (void){
+
+	struct rtc_time tmp;
+
+	/* clear status flags */
+	rtc_write(RTC_SR_ADDR, (RTC_SR_BIT_AF|RTC_SR_BIT_OSF), false); /* clearing OSF and AF */
+
+	/* Initialise DS1374 oriented to MPC8349E-ADS */
+	rtc_write (RTC_CTL_ADDR, (RTC_CTL_BIT_EN_OSC
+				 |RTC_CTL_BIT_WACE
+				 |RTC_CTL_BIT_AIE), false);/* start osc, disable WACE, clear AIE
+							      - set to 0 */
+	rtc_write (RTC_CTL_ADDR, (RTC_CTL_BIT_WD_ALM
+				|RTC_CTL_BIT_WDSTR
+				|RTC_CTL_BIT_RS1
+				|RTC_CTL_BIT_RS2
+				|RTC_CTL_BIT_BBSQW), true);/* disable WD/ALM, WDSTR set to INT-pin,
+							      set BBSQW and SQW to 32k
+							      - set to 1 */
+	tmp.tm_year = 1970;
+	tmp.tm_mon = 1;
+	tmp.tm_mday= 1;
+	tmp.tm_hour = 0;
+	tmp.tm_min = 0;
+	tmp.tm_sec = 0;
+
+	rtc_set(&tmp);
+
+	printf("RTC:   %4d-%02d-%02d %2d:%02d:%02d UTC\n",
+		tmp.tm_year, tmp.tm_mon, tmp.tm_mday,
+		tmp.tm_hour, tmp.tm_min, tmp.tm_sec);
+
+	rtc_write(RTC_WD_ALM_CNT_BYTE2_ADDR, 0xAC, true);
+	rtc_write(RTC_WD_ALM_CNT_BYTE1_ADDR, 0xDE, true);
+	rtc_write(RTC_WD_ALM_CNT_BYTE2_ADDR, 0xAD, true);
+}
+
+/*
+ * Helper functions
+ */
+static uchar rtc_read (uchar reg)
+{
+	return (i2c_reg_read (CONFIG_SYS_I2C_RTC_ADDR, reg));
+}
+
+static void rtc_write(uchar reg, uchar val, bool set)
+{
+	if (set == true) {
+		val |= i2c_reg_read (CONFIG_SYS_I2C_RTC_ADDR, reg);
+		i2c_reg_write (CONFIG_SYS_I2C_RTC_ADDR, reg, val);
+	} else {
+		val = i2c_reg_read (CONFIG_SYS_I2C_RTC_ADDR, reg) & ~val;
+		i2c_reg_write (CONFIG_SYS_I2C_RTC_ADDR, reg, val);
+	}
+}
+
+static void rtc_write_raw (uchar reg, uchar val)
+{
+		i2c_reg_write (CONFIG_SYS_I2C_RTC_ADDR, reg, val);
+}
+#endif
diff --git a/marvell/uboot/drivers/rtc/ds1556.c b/marvell/uboot/drivers/rtc/ds1556.c
new file mode 100644
index 0000000..5b8d5ef
--- /dev/null
+++ b/marvell/uboot/drivers/rtc/ds1556.c
@@ -0,0 +1,180 @@
+/*
+ * (C) Copyright 2002
+ * ARIO Data Networks, Inc. dchiu@ariodata.com
+ *
+ * modified for DS1556:
+ * Frank Panno <fpanno@delphintech.com>, Delphin Technology AG
+ *
+ * Based on MontaVista DS1743 code and U-Boot mc146818 code
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+/*
+ * Date & Time support for the DS1556 RTC
+ */
+
+/*#define	RTC_DEBUG */
+
+#include <common.h>
+#include <command.h>
+#include <rtc.h>
+
+#if defined(CONFIG_CMD_DATE)
+
+static uchar rtc_read( unsigned int addr );
+static void  rtc_write( unsigned int addr, uchar val);
+
+#define RTC_BASE		( CONFIG_SYS_NVRAM_SIZE + CONFIG_SYS_NVRAM_BASE_ADDR )
+
+#define RTC_YEAR		( RTC_BASE + 0xf )
+#define RTC_MONTH		( RTC_BASE + 0xe )
+#define RTC_DAY_OF_MONTH	( RTC_BASE + 0xd )
+#define RTC_DAY_OF_WEEK		( RTC_BASE + 0xc )
+#define RTC_HOURS		( RTC_BASE + 0xb )
+#define RTC_MINUTES		( RTC_BASE + 0xa )
+#define RTC_SECONDS		( RTC_BASE + 0x9 )
+#define RTC_CENTURY		( RTC_BASE + 0x8 )
+
+#define RTC_CONTROLA		RTC_CENTURY
+#define RTC_CONTROLB		RTC_SECONDS
+#define RTC_CONTROLC		RTC_BASE
+
+#define RTC_CA_WRITE		0x80
+#define RTC_CA_READ		0x40
+
+#define RTC_CB_OSC_DISABLE	0x80
+
+#define RTC_CC_BATTERY_FLAG	0x10
+#define RTC_CC_FREQ_TEST	0x40
+
+/* ------------------------------------------------------------------------- */
+
+int rtc_get( struct rtc_time *tmp )
+{
+	uchar sec, min, hour;
+	uchar mday, wday, mon, year;
+
+	int century;
+
+	uchar reg_a;
+
+	reg_a = rtc_read( RTC_CONTROLA );
+	/* lock clock registers for read */
+	rtc_write( RTC_CONTROLA, ( reg_a | RTC_CA_READ ));
+
+	sec     = rtc_read( RTC_SECONDS );
+	min     = rtc_read( RTC_MINUTES );
+	hour    = rtc_read( RTC_HOURS );
+	mday    = rtc_read( RTC_DAY_OF_MONTH );
+	wday    = rtc_read( RTC_DAY_OF_WEEK );
+	mon     = rtc_read( RTC_MONTH );
+	year    = rtc_read( RTC_YEAR );
+	century = rtc_read( RTC_CENTURY );
+
+	/* unlock clock registers after read */
+	rtc_write( RTC_CONTROLA, ( reg_a & ~RTC_CA_READ ));
+
+#ifdef RTC_DEBUG
+	printf( "Get RTC year: %02x mon/cent: %02x mon: %02x mday: %02x wday: %02x "
+		"hr: %02x min: %02x sec: %02x\n",
+		year, century, mon, mday, wday,
+		hour, min, sec );
+#endif
+	tmp->tm_sec  = bcd2bin( sec  & 0x7F );
+	tmp->tm_min  = bcd2bin( min  & 0x7F );
+	tmp->tm_hour = bcd2bin( hour & 0x3F );
+	tmp->tm_mday = bcd2bin( mday & 0x3F );
+	tmp->tm_mon  = bcd2bin( mon & 0x1F );
+	tmp->tm_wday = bcd2bin( wday & 0x07 );
+
+	/* glue year from century and year in century */
+	tmp->tm_year = bcd2bin( year ) +
+		( bcd2bin( century & 0x3F ) * 100 );
+
+	tmp->tm_yday = 0;
+	tmp->tm_isdst= 0;
+#ifdef RTC_DEBUG
+	printf( "Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec );
+#endif
+	return 0;
+}
+
+int rtc_set( struct rtc_time *tmp )
+{
+	uchar reg_a;
+#ifdef RTC_DEBUG
+	printf( "Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+#endif
+	/* lock clock registers for write */
+	reg_a = rtc_read( RTC_CONTROLA );
+	rtc_write( RTC_CONTROLA, ( reg_a | RTC_CA_WRITE ));
+
+	rtc_write( RTC_MONTH, bin2bcd( tmp->tm_mon ));
+
+	rtc_write( RTC_DAY_OF_WEEK, bin2bcd( tmp->tm_wday ));
+	rtc_write( RTC_DAY_OF_MONTH, bin2bcd( tmp->tm_mday ));
+	rtc_write( RTC_HOURS, bin2bcd( tmp->tm_hour ));
+	rtc_write( RTC_MINUTES, bin2bcd( tmp->tm_min ));
+	rtc_write( RTC_SECONDS, bin2bcd( tmp->tm_sec ));
+
+	/* break year up into century and year in century */
+	rtc_write( RTC_YEAR, bin2bcd( tmp->tm_year % 100 ));
+	rtc_write( RTC_CENTURY, bin2bcd( tmp->tm_year / 100 ));
+
+	/* unlock clock registers after read */
+	rtc_write( RTC_CONTROLA, ( reg_a  & ~RTC_CA_WRITE ));
+
+	return 0;
+}
+
+void rtc_reset (void)
+{
+	uchar reg_a, reg_b, reg_c;
+
+	reg_a = rtc_read( RTC_CONTROLA );
+	reg_b = rtc_read( RTC_CONTROLB );
+
+	if ( reg_b & RTC_CB_OSC_DISABLE )
+	{
+		printf( "real-time-clock was stopped. Now starting...\n" );
+		reg_a |= RTC_CA_WRITE;
+		reg_b &= ~RTC_CB_OSC_DISABLE;
+
+		rtc_write( RTC_CONTROLA, reg_a );
+		rtc_write( RTC_CONTROLB, reg_b );
+	}
+
+	/* make sure read/write clock register bits are cleared */
+	reg_a &= ~( RTC_CA_WRITE | RTC_CA_READ );
+	rtc_write( RTC_CONTROLA, reg_a );
+
+	reg_c = rtc_read( RTC_CONTROLC );
+	if (( reg_c & RTC_CC_BATTERY_FLAG ) == 0 )
+		printf( "RTC battery low. Clock setting may not be reliable.\n" );
+}
+
+/* ------------------------------------------------------------------------- */
+
+static uchar rtc_read( unsigned int addr )
+{
+	uchar val = *(volatile unsigned char*)(addr);
+#ifdef RTC_DEBUG
+	printf( "rtc_read: %x:%x\n", addr, val );
+#endif
+	return( val );
+}
+
+static void rtc_write( unsigned int addr, uchar val )
+{
+#ifdef RTC_DEBUG
+	printf( "rtc_write: %x:%x\n", addr, val );
+#endif
+	*(volatile unsigned char*)(addr) = val;
+}
+
+#endif
diff --git a/marvell/uboot/drivers/rtc/ds164x.c b/marvell/uboot/drivers/rtc/ds164x.c
new file mode 100644
index 0000000..b913354
--- /dev/null
+++ b/marvell/uboot/drivers/rtc/ds164x.c
@@ -0,0 +1,176 @@
+/*
+ * (C) Copyright 2002
+ * ARIO Data Networks, Inc. dchiu@ariodata.com
+ *
+ * modified for DS164x:
+ * The LEOX team <team@leox.org>, http://www.leox.org
+ *
+ * Based on MontaVista DS1743 code and U-Boot mc146818 code
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+/*
+ * Date & Time support for the DS164x RTC
+ */
+
+/* #define	RTC_DEBUG */
+
+#include <common.h>
+#include <command.h>
+#include <rtc.h>
+
+
+#if defined(CONFIG_CMD_DATE)
+
+static uchar    rtc_read(unsigned int addr );
+static void     rtc_write(unsigned int addr, uchar val);
+
+#define RTC_EPOCH                 2000	/* century */
+
+/*
+ * DS164x registers layout
+ */
+#define RTC_BASE		( CONFIG_SYS_NVRAM_BASE_ADDR + CONFIG_SYS_NVRAM_SIZE )
+
+#define RTC_YEAR		( RTC_BASE + 0x07 )
+#define RTC_MONTH		( RTC_BASE + 0x06 )
+#define RTC_DAY_OF_MONTH	( RTC_BASE + 0x05 )
+#define RTC_DAY_OF_WEEK		( RTC_BASE + 0x04 )
+#define RTC_HOURS		( RTC_BASE + 0x03 )
+#define RTC_MINUTES		( RTC_BASE + 0x02 )
+#define RTC_SECONDS		( RTC_BASE + 0x01 )
+#define RTC_CONTROL		( RTC_BASE + 0x00 )
+
+#define RTC_CONTROLA		RTC_CONTROL	/* W=bit6, R=bit5 */
+#define   RTC_CA_WRITE		  0x80
+#define   RTC_CA_READ		  0x40
+#define RTC_CONTROLB		RTC_SECONDS	/* OSC=bit7       */
+#define   RTC_CB_OSC_DISABLE	  0x80
+#define RTC_CONTROLC		RTC_DAY_OF_WEEK	/* FT=bit6        */
+#define   RTC_CC_FREQ_TEST	  0x40
+
+/* ------------------------------------------------------------------------- */
+
+int rtc_get( struct rtc_time *tmp )
+{
+	uchar sec, min, hour;
+	uchar mday, wday, mon, year;
+
+	uchar reg_a;
+
+	reg_a = rtc_read( RTC_CONTROLA );
+	/* lock clock registers for read */
+	rtc_write( RTC_CONTROLA, ( reg_a | RTC_CA_READ ));
+
+	sec     = rtc_read( RTC_SECONDS );
+	min     = rtc_read( RTC_MINUTES );
+	hour    = rtc_read( RTC_HOURS );
+	mday    = rtc_read( RTC_DAY_OF_MONTH );
+	wday    = rtc_read( RTC_DAY_OF_WEEK );
+	mon     = rtc_read( RTC_MONTH );
+	year    = rtc_read( RTC_YEAR );
+
+	/* unlock clock registers after read */
+	rtc_write( RTC_CONTROLA, ( reg_a & ~RTC_CA_READ ));
+
+#ifdef RTC_DEBUG
+	printf( "Get RTC year: %02x mon: %02x mday: %02x wday: %02x "
+		"hr: %02x min: %02x sec: %02x\n",
+		year, mon, mday, wday,
+		hour, min, sec );
+#endif
+	tmp->tm_sec  = bcd2bin( sec  & 0x7F );
+	tmp->tm_min  = bcd2bin( min  & 0x7F );
+	tmp->tm_hour = bcd2bin( hour & 0x3F );
+	tmp->tm_mday = bcd2bin( mday & 0x3F );
+	tmp->tm_mon  = bcd2bin( mon  & 0x1F );
+	tmp->tm_wday = bcd2bin( wday & 0x07 );
+
+	/* glue year in century (2000) */
+	tmp->tm_year = bcd2bin( year ) + RTC_EPOCH;
+
+	tmp->tm_yday = 0;
+	tmp->tm_isdst= 0;
+#ifdef RTC_DEBUG
+	printf( "Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec );
+#endif
+
+	return 0;
+}
+
+int rtc_set( struct rtc_time *tmp )
+{
+	uchar reg_a;
+
+#ifdef RTC_DEBUG
+	printf( "Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+#endif
+	/* lock clock registers for write */
+	reg_a = rtc_read( RTC_CONTROLA );
+	rtc_write( RTC_CONTROLA, ( reg_a | RTC_CA_WRITE ));
+
+	rtc_write( RTC_MONTH, bin2bcd( tmp->tm_mon ));
+
+	rtc_write( RTC_DAY_OF_WEEK, bin2bcd( tmp->tm_wday ));
+	rtc_write( RTC_DAY_OF_MONTH, bin2bcd( tmp->tm_mday ));
+	rtc_write( RTC_HOURS, bin2bcd( tmp->tm_hour ));
+	rtc_write( RTC_MINUTES, bin2bcd( tmp->tm_min ));
+	rtc_write( RTC_SECONDS, bin2bcd( tmp->tm_sec ));
+
+	/* break year in century */
+	rtc_write( RTC_YEAR, bin2bcd( tmp->tm_year % 100 ));
+
+	/* unlock clock registers after read */
+	rtc_write( RTC_CONTROLA, ( reg_a  & ~RTC_CA_WRITE ));
+
+	return 0;
+}
+
+void rtc_reset (void)
+{
+	uchar reg_a, reg_b;
+
+	reg_a = rtc_read( RTC_CONTROLA );
+	reg_b = rtc_read( RTC_CONTROLB );
+
+	if ( reg_b & RTC_CB_OSC_DISABLE )
+	{
+		printf( "real-time-clock was stopped. Now starting...\n" );
+		reg_a |= RTC_CA_WRITE;
+		reg_b &= ~RTC_CB_OSC_DISABLE;
+
+		rtc_write( RTC_CONTROLA, reg_a );
+		rtc_write( RTC_CONTROLB, reg_b );
+	}
+
+	/* make sure read/write clock register bits are cleared */
+	reg_a &= ~( RTC_CA_WRITE | RTC_CA_READ );
+	rtc_write( RTC_CONTROLA, reg_a );
+}
+
+/* ------------------------------------------------------------------------- */
+
+static uchar rtc_read( unsigned int addr )
+{
+	uchar val = *(volatile unsigned char*)(addr);
+
+#ifdef RTC_DEBUG
+	printf( "rtc_read: %x:%x\n", addr, val );
+#endif
+	return( val );
+}
+
+static void rtc_write( unsigned int addr, uchar val )
+{
+#ifdef RTC_DEBUG
+	printf( "rtc_write: %x:%x\n", addr, val );
+#endif
+	*(volatile unsigned char*)(addr) = val;
+}
+
+#endif
diff --git a/marvell/uboot/drivers/rtc/ds174x.c b/marvell/uboot/drivers/rtc/ds174x.c
new file mode 100644
index 0000000..fc073e0
--- /dev/null
+++ b/marvell/uboot/drivers/rtc/ds174x.c
@@ -0,0 +1,177 @@
+/*
+ * (C) Copyright 2001
+ * ARIO Data Networks, Inc. dchiu@ariodata.com
+ *
+ * Based on MontaVista DS1743 code and U-Boot mc146818 code
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+/*
+ * Date & Time support for the DS174x RTC
+ */
+
+/*#define	DEBUG*/
+
+#include <common.h>
+#include <command.h>
+#include <rtc.h>
+
+#if defined(CONFIG_CMD_DATE)
+
+static uchar rtc_read( unsigned int addr );
+static void  rtc_write( unsigned int addr, uchar val);
+
+#define RTC_BASE		( CONFIG_SYS_NVRAM_SIZE + CONFIG_SYS_NVRAM_BASE_ADDR )
+
+#define RTC_YEAR		( RTC_BASE + 7 )
+#define RTC_MONTH		( RTC_BASE + 6 )
+#define RTC_DAY_OF_MONTH	( RTC_BASE + 5 )
+#define RTC_DAY_OF_WEEK		( RTC_BASE + 4 )
+#define RTC_HOURS		( RTC_BASE + 3 )
+#define RTC_MINUTES		( RTC_BASE + 2 )
+#define RTC_SECONDS		( RTC_BASE + 1 )
+#define RTC_CENTURY		( RTC_BASE + 0 )
+
+#define RTC_CONTROLA		RTC_CENTURY
+#define RTC_CONTROLB		RTC_SECONDS
+#define RTC_CONTROLC		RTC_DAY_OF_WEEK
+
+#define RTC_CA_WRITE		0x80
+#define RTC_CA_READ		0x40
+
+#define RTC_CB_OSC_DISABLE	0x80
+
+#define RTC_CC_BATTERY_FLAG	0x80
+#define RTC_CC_FREQ_TEST	0x40
+
+/* ------------------------------------------------------------------------- */
+
+int rtc_get( struct rtc_time *tmp )
+{
+	uchar sec, min, hour;
+	uchar mday, wday, mon, year;
+
+	int century;
+
+	uchar reg_a;
+
+	reg_a = rtc_read( RTC_CONTROLA );
+	/* lock clock registers for read */
+	rtc_write( RTC_CONTROLA, ( reg_a | RTC_CA_READ ));
+
+	sec     = rtc_read( RTC_SECONDS );
+	min     = rtc_read( RTC_MINUTES );
+	hour    = rtc_read( RTC_HOURS );
+	mday    = rtc_read( RTC_DAY_OF_MONTH );
+	wday    = rtc_read( RTC_DAY_OF_WEEK );
+	mon     = rtc_read( RTC_MONTH );
+	year    = rtc_read( RTC_YEAR );
+	century = rtc_read( RTC_CENTURY );
+
+	/* unlock clock registers after read */
+	rtc_write( RTC_CONTROLA, ( reg_a & ~RTC_CA_READ ));
+
+#ifdef RTC_DEBUG
+	printf( "Get RTC year: %02x mon/cent: %02x mday: %02x wday: %02x "
+		"hr: %02x min: %02x sec: %02x\n",
+		year, mon_cent, mday, wday,
+		hour, min, sec );
+#endif
+	tmp->tm_sec  = bcd2bin( sec  & 0x7F );
+	tmp->tm_min  = bcd2bin( min  & 0x7F );
+	tmp->tm_hour = bcd2bin( hour & 0x3F );
+	tmp->tm_mday = bcd2bin( mday & 0x3F );
+	tmp->tm_mon  = bcd2bin( mon & 0x1F );
+	tmp->tm_wday = bcd2bin( wday & 0x07 );
+
+	/* glue year from century and year in century */
+	tmp->tm_year = bcd2bin( year ) +
+		( bcd2bin( century & 0x3F ) * 100 );
+
+	tmp->tm_yday = 0;
+	tmp->tm_isdst= 0;
+#ifdef RTC_DEBUG
+	printf( "Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec );
+#endif
+	return 0;
+}
+
+int rtc_set( struct rtc_time *tmp )
+{
+	uchar reg_a;
+#ifdef RTC_DEBUG
+	printf( "Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+#endif
+	/* lock clock registers for write */
+	reg_a = rtc_read( RTC_CONTROLA );
+	rtc_write( RTC_CONTROLA, ( reg_a | RTC_CA_WRITE ));
+
+	rtc_write( RTC_MONTH, bin2bcd( tmp->tm_mon ));
+
+	rtc_write( RTC_DAY_OF_WEEK, bin2bcd( tmp->tm_wday ));
+	rtc_write( RTC_DAY_OF_MONTH, bin2bcd( tmp->tm_mday ));
+	rtc_write( RTC_HOURS, bin2bcd( tmp->tm_hour ));
+	rtc_write( RTC_MINUTES, bin2bcd( tmp->tm_min ));
+	rtc_write( RTC_SECONDS, bin2bcd( tmp->tm_sec ));
+
+	/* break year up into century and year in century */
+	rtc_write( RTC_YEAR, bin2bcd( tmp->tm_year % 100 ));
+	rtc_write( RTC_CENTURY, bin2bcd( tmp->tm_year / 100 ));
+
+	/* unlock clock registers after read */
+	rtc_write( RTC_CONTROLA, ( reg_a  & ~RTC_CA_WRITE ));
+
+	return 0;
+}
+
+void rtc_reset (void)
+{
+	uchar reg_a, reg_b, reg_c;
+
+	reg_a = rtc_read( RTC_CONTROLA );
+	reg_b = rtc_read( RTC_CONTROLB );
+
+	if ( reg_b & RTC_CB_OSC_DISABLE )
+	{
+		printf( "real-time-clock was stopped. Now starting...\n" );
+		reg_a |= RTC_CA_WRITE;
+		reg_b &= ~RTC_CB_OSC_DISABLE;
+
+		rtc_write( RTC_CONTROLA, reg_a );
+		rtc_write( RTC_CONTROLB, reg_b );
+	}
+
+	/* make sure read/write clock register bits are cleared */
+	reg_a &= ~( RTC_CA_WRITE | RTC_CA_READ );
+	rtc_write( RTC_CONTROLA, reg_a );
+
+	reg_c = rtc_read( RTC_CONTROLC );
+	if (( reg_c & RTC_CC_BATTERY_FLAG ) == 0 )
+		printf( "RTC battery low. Clock setting may not be reliable.\n" );
+}
+
+/* ------------------------------------------------------------------------- */
+
+static uchar rtc_read( unsigned int addr )
+{
+	uchar val = in8( addr );
+#ifdef RTC_DEBUG
+	printf( "rtc_read: %x:%x\n", addr, val );
+#endif
+	return( val );
+}
+
+static void rtc_write( unsigned int addr, uchar val )
+{
+#ifdef RTC_DEBUG
+	printf( "rtc_write: %x:%x\n", addr, val );
+#endif
+	out8( addr, val );
+}
+
+#endif
diff --git a/marvell/uboot/drivers/rtc/ds3231.c b/marvell/uboot/drivers/rtc/ds3231.c
new file mode 100644
index 0000000..c84bbc6
--- /dev/null
+++ b/marvell/uboot/drivers/rtc/ds3231.c
@@ -0,0 +1,161 @@
+/*
+ * (C) Copyright 2006
+ * Markus Klotzbuecher, mk@denx.de
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+/*
+ * Date & Time support (no alarms) for Dallas Semiconductor (now Maxim)
+ * Extremly Accurate DS3231 Real Time Clock (RTC).
+ *
+ * copied from ds1337.c
+ */
+
+#include <common.h>
+#include <command.h>
+#include <rtc.h>
+#include <i2c.h>
+
+#if defined(CONFIG_CMD_DATE)
+
+/*
+ * RTC register addresses
+ */
+#define RTC_SEC_REG_ADDR	0x0
+#define RTC_MIN_REG_ADDR	0x1
+#define RTC_HR_REG_ADDR		0x2
+#define RTC_DAY_REG_ADDR	0x3
+#define RTC_DATE_REG_ADDR	0x4
+#define RTC_MON_REG_ADDR	0x5
+#define RTC_YR_REG_ADDR		0x6
+#define RTC_CTL_REG_ADDR	0x0e
+#define RTC_STAT_REG_ADDR	0x0f
+
+
+/*
+ * RTC control register bits
+ */
+#define RTC_CTL_BIT_A1IE	0x1	/* Alarm 1 interrupt enable     */
+#define RTC_CTL_BIT_A2IE	0x2	/* Alarm 2 interrupt enable     */
+#define RTC_CTL_BIT_INTCN	0x4	/* Interrupt control            */
+#define RTC_CTL_BIT_RS1		0x8	/* Rate select 1                */
+#define RTC_CTL_BIT_RS2		0x10	/* Rate select 2                */
+#define RTC_CTL_BIT_DOSC	0x80	/* Disable Oscillator           */
+
+/*
+ * RTC status register bits
+ */
+#define RTC_STAT_BIT_A1F	0x1	/* Alarm 1 flag                 */
+#define RTC_STAT_BIT_A2F	0x2	/* Alarm 2 flag                 */
+#define RTC_STAT_BIT_OSF	0x80	/* Oscillator stop flag         */
+
+
+static uchar rtc_read (uchar reg);
+static void rtc_write (uchar reg, uchar val);
+
+
+/*
+ * Get the current time from the RTC
+ */
+int rtc_get (struct rtc_time *tmp)
+{
+	int rel = 0;
+	uchar sec, min, hour, mday, wday, mon_cent, year, control, status;
+
+	control = rtc_read (RTC_CTL_REG_ADDR);
+	status = rtc_read (RTC_STAT_REG_ADDR);
+	sec = rtc_read (RTC_SEC_REG_ADDR);
+	min = rtc_read (RTC_MIN_REG_ADDR);
+	hour = rtc_read (RTC_HR_REG_ADDR);
+	wday = rtc_read (RTC_DAY_REG_ADDR);
+	mday = rtc_read (RTC_DATE_REG_ADDR);
+	mon_cent = rtc_read (RTC_MON_REG_ADDR);
+	year = rtc_read (RTC_YR_REG_ADDR);
+
+	debug("Get RTC year: %02x mon/cent: %02x mday: %02x wday: %02x "
+		"hr: %02x min: %02x sec: %02x control: %02x status: %02x\n",
+		year, mon_cent, mday, wday, hour, min, sec, control, status);
+
+	if (status & RTC_STAT_BIT_OSF) {
+		printf ("### Warning: RTC oscillator has stopped\n");
+		/* clear the OSF flag */
+		rtc_write (RTC_STAT_REG_ADDR,
+			   rtc_read (RTC_STAT_REG_ADDR) & ~RTC_STAT_BIT_OSF);
+		rel = -1;
+	}
+
+	tmp->tm_sec  = bcd2bin (sec & 0x7F);
+	tmp->tm_min  = bcd2bin (min & 0x7F);
+	tmp->tm_hour = bcd2bin (hour & 0x3F);
+	tmp->tm_mday = bcd2bin (mday & 0x3F);
+	tmp->tm_mon  = bcd2bin (mon_cent & 0x1F);
+	tmp->tm_year = bcd2bin (year) + ((mon_cent & 0x80) ? 2000 : 1900);
+	tmp->tm_wday = bcd2bin ((wday - 1) & 0x07);
+	tmp->tm_yday = 0;
+	tmp->tm_isdst= 0;
+
+	debug("Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+	return rel;
+}
+
+
+/*
+ * Set the RTC
+ */
+int rtc_set (struct rtc_time *tmp)
+{
+	uchar century;
+
+	debug("Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+	rtc_write (RTC_YR_REG_ADDR, bin2bcd (tmp->tm_year % 100));
+
+	century = (tmp->tm_year >= 2000) ? 0x80 : 0;
+	rtc_write (RTC_MON_REG_ADDR, bin2bcd (tmp->tm_mon) | century);
+
+	rtc_write (RTC_DAY_REG_ADDR, bin2bcd (tmp->tm_wday + 1));
+	rtc_write (RTC_DATE_REG_ADDR, bin2bcd (tmp->tm_mday));
+	rtc_write (RTC_HR_REG_ADDR, bin2bcd (tmp->tm_hour));
+	rtc_write (RTC_MIN_REG_ADDR, bin2bcd (tmp->tm_min));
+	rtc_write (RTC_SEC_REG_ADDR, bin2bcd (tmp->tm_sec));
+
+	return 0;
+}
+
+
+/*
+ * Reset the RTC.  We also enable the oscillator output on the
+ * SQW/INTB* pin and program it for 32,768 Hz output. Note that
+ * according to the datasheet, turning on the square wave output
+ * increases the current drain on the backup battery from about
+ * 600 nA to 2uA.
+ */
+void rtc_reset (void)
+{
+	rtc_write (RTC_CTL_REG_ADDR, RTC_CTL_BIT_RS1 | RTC_CTL_BIT_RS2);
+}
+
+
+/*
+ * Helper functions
+ */
+
+static
+uchar rtc_read (uchar reg)
+{
+	return (i2c_reg_read (CONFIG_SYS_I2C_RTC_ADDR, reg));
+}
+
+
+static void rtc_write (uchar reg, uchar val)
+{
+	i2c_reg_write (CONFIG_SYS_I2C_RTC_ADDR, reg, val);
+}
+
+#endif
diff --git a/marvell/uboot/drivers/rtc/ftrtc010.c b/marvell/uboot/drivers/rtc/ftrtc010.c
new file mode 100644
index 0000000..713dad2
--- /dev/null
+++ b/marvell/uboot/drivers/rtc/ftrtc010.c
@@ -0,0 +1,123 @@
+/*
+ * Faraday FTRTC010 Real Time Clock
+ *
+ * (C) Copyright 2009 Faraday Technology
+ * Po-Yu Chuang <ratbert@faraday-tech.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <config.h>
+#include <common.h>
+#include <rtc.h>
+#include <asm/io.h>
+
+struct ftrtc010 {
+	unsigned int sec;		/* 0x00 */
+	unsigned int min;		/* 0x04 */
+	unsigned int hour;		/* 0x08 */
+	unsigned int day;		/* 0x0c */
+	unsigned int alarm_sec;		/* 0x10 */
+	unsigned int alarm_min;		/* 0x14 */
+	unsigned int alarm_hour;	/* 0x18 */
+	unsigned int record;		/* 0x1c */
+	unsigned int cr;		/* 0x20 */
+	unsigned int wsec;		/* 0x24 */
+	unsigned int wmin;		/* 0x28 */
+	unsigned int whour;		/* 0x2c */
+	unsigned int wday;		/* 0x30 */
+	unsigned int intr;		/* 0x34 */
+	unsigned int div;		/* 0x38 */
+	unsigned int rev;		/* 0x3c */
+};
+
+/*
+ * RTC Control Register
+ */
+#define FTRTC010_CR_ENABLE		(1 << 0)
+#define FTRTC010_CR_INTERRUPT_SEC	(1 << 1)	/* per second irq */
+#define FTRTC010_CR_INTERRUPT_MIN	(1 << 2)	/* per minute irq */
+#define FTRTC010_CR_INTERRUPT_HR	(1 << 3)	/* per hour   irq */
+#define FTRTC010_CR_INTERRUPT_DAY	(1 << 4)	/* per day    irq */
+
+static struct ftrtc010 *rtc = (struct ftrtc010 *)CONFIG_FTRTC010_BASE;
+
+static void ftrtc010_enable(void)
+{
+	writel(FTRTC010_CR_ENABLE, &rtc->cr);
+}
+
+/*
+ * return current time in seconds
+ */
+static unsigned long ftrtc010_time(void)
+{
+	unsigned long day;
+	unsigned long hour;
+	unsigned long minute;
+	unsigned long second;
+	unsigned long second2;
+
+	do {
+		second	= readl(&rtc->sec);
+		day	= readl(&rtc->day);
+		hour	= readl(&rtc->hour);
+		minute	= readl(&rtc->min);
+		second2	= readl(&rtc->sec);
+	} while (second != second2);
+
+	return day * 24 * 60 * 60 + hour * 60 * 60 + minute * 60 + second;
+}
+
+/*
+ * Get the current time from the RTC
+ */
+
+int rtc_get(struct rtc_time *tmp)
+{
+	unsigned long now;
+
+	debug("%s(): record register: %x\n",
+	      __func__, readl(&rtc->record));
+
+#ifdef CONFIG_FTRTC010_PCLK
+	now = (ftrtc010_time() + readl(&rtc->record)) / RTC_DIV_COUNT;
+#else /* CONFIG_FTRTC010_EXTCLK */
+	now = ftrtc010_time() + readl(&rtc->record);
+#endif
+
+	to_tm(now, tmp);
+
+	return 0;
+}
+
+/*
+ * Set the RTC
+ */
+int rtc_set(struct rtc_time *tmp)
+{
+	unsigned long new;
+	unsigned long now;
+
+	debug("%s(): DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+	      __func__,
+	      tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+	      tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+	new = mktime(tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_hour,
+		     tmp->tm_min, tmp->tm_sec);
+
+	now = ftrtc010_time();
+
+	debug("%s(): write %lx to record register\n", __func__, new - now);
+
+	writel(new - now, &rtc->record);
+
+	return 0;
+}
+
+void rtc_reset(void)
+{
+	debug("%s()\n", __func__);
+	ftrtc010_enable();
+}
diff --git a/marvell/uboot/drivers/rtc/imxdi.c b/marvell/uboot/drivers/rtc/imxdi.c
new file mode 100644
index 0000000..0d7d736
--- /dev/null
+++ b/marvell/uboot/drivers/rtc/imxdi.c
@@ -0,0 +1,228 @@
+/*
+ * (C) Copyright 2009-2012 ADVANSEE
+ * Benoît Thébaudeau <benoit.thebaudeau@advansee.com>
+ *
+ * Based on the Linux rtc-imxdi.c driver, which is:
+ * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2010 Orex Computed Radiography
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+/*
+ * Date & Time support for Freescale i.MX DryIce RTC
+ */
+
+#include <common.h>
+#include <command.h>
+#include <linux/compat.h>
+#include <rtc.h>
+
+#if defined(CONFIG_CMD_DATE)
+
+#include <asm/io.h>
+#include <asm/arch/imx-regs.h>
+
+/* DryIce Register Definitions */
+
+struct imxdi_regs {
+	u32 dtcmr;			/* Time Counter MSB Reg */
+	u32 dtclr;			/* Time Counter LSB Reg */
+	u32 dcamr;			/* Clock Alarm MSB Reg */
+	u32 dcalr;			/* Clock Alarm LSB Reg */
+	u32 dcr;			/* Control Reg */
+	u32 dsr;			/* Status Reg */
+	u32 dier;			/* Interrupt Enable Reg */
+};
+
+#define DCAMR_UNSET	0xFFFFFFFF	/* doomsday - 1 sec */
+
+#define DCR_TCE		(1 << 3)	/* Time Counter Enable */
+
+#define DSR_WBF		(1 << 10)	/* Write Busy Flag */
+#define DSR_WNF		(1 << 9)	/* Write Next Flag */
+#define DSR_WCF		(1 << 8)	/* Write Complete Flag */
+#define DSR_WEF		(1 << 7)	/* Write Error Flag */
+#define DSR_CAF		(1 << 4)	/* Clock Alarm Flag */
+#define DSR_NVF		(1 << 1)	/* Non-Valid Flag */
+#define DSR_SVF		(1 << 0)	/* Security Violation Flag */
+
+#define DIER_WNIE	(1 << 9)	/* Write Next Interrupt Enable */
+#define DIER_WCIE	(1 << 8)	/* Write Complete Interrupt Enable */
+#define DIER_WEIE	(1 << 7)	/* Write Error Interrupt Enable */
+#define DIER_CAIE	(1 << 4)	/* Clock Alarm Interrupt Enable */
+
+/* Driver Private Data */
+
+struct imxdi_data {
+	struct imxdi_regs __iomem	*regs;
+	int				init_done;
+};
+
+static struct imxdi_data data;
+
+/*
+ * This function attempts to clear the dryice write-error flag.
+ *
+ * A dryice write error is similar to a bus fault and should not occur in
+ * normal operation.  Clearing the flag requires another write, so the root
+ * cause of the problem may need to be fixed before the flag can be cleared.
+ */
+static void clear_write_error(void)
+{
+	int cnt;
+
+	puts("### Warning: RTC - Register write error!\n");
+
+	/* clear the write error flag */
+	__raw_writel(DSR_WEF, &data.regs->dsr);
+
+	/* wait for it to take effect */
+	for (cnt = 0; cnt < 1000; cnt++) {
+		if ((__raw_readl(&data.regs->dsr) & DSR_WEF) == 0)
+			return;
+		udelay(10);
+	}
+	puts("### Error: RTC - Cannot clear write-error flag!\n");
+}
+
+/*
+ * Write a dryice register and wait until it completes.
+ *
+ * Use interrupt flags to determine when the write has completed.
+ */
+#define DI_WRITE_WAIT(val, reg)						\
+(									\
+	/* do the register write */					\
+	__raw_writel((val), &data.regs->reg),				\
+									\
+	di_write_wait((val), #reg)					\
+)
+static int di_write_wait(u32 val, const char *reg)
+{
+	int cnt;
+	int ret = 0;
+	int rc = 0;
+
+	/* wait for the write to finish */
+	for (cnt = 0; cnt < 100; cnt++) {
+		if ((__raw_readl(&data.regs->dsr) & (DSR_WCF | DSR_WEF)) != 0) {
+			ret = 1;
+			break;
+		}
+		udelay(10);
+	}
+	if (ret == 0)
+		printf("### Warning: RTC - Write-wait timeout "
+				"val = 0x%.8x reg = %s\n", val, reg);
+
+	/* check for write error */
+	if (__raw_readl(&data.regs->dsr) & DSR_WEF) {
+		clear_write_error();
+		rc = -1;
+	}
+
+	return rc;
+}
+
+/*
+ * Initialize dryice hardware
+ */
+static int di_init(void)
+{
+	int rc = 0;
+
+	data.regs = (struct imxdi_regs __iomem *)IMX_DRYICE_BASE;
+
+	/* mask all interrupts */
+	__raw_writel(0, &data.regs->dier);
+
+	/* put dryice into valid state */
+	if (__raw_readl(&data.regs->dsr) & DSR_NVF) {
+		rc = DI_WRITE_WAIT(DSR_NVF | DSR_SVF, dsr);
+		if (rc)
+			goto err;
+	}
+
+	/* initialize alarm */
+	rc = DI_WRITE_WAIT(DCAMR_UNSET, dcamr);
+	if (rc)
+		goto err;
+	rc = DI_WRITE_WAIT(0, dcalr);
+	if (rc)
+		goto err;
+
+	/* clear alarm flag */
+	if (__raw_readl(&data.regs->dsr) & DSR_CAF) {
+		rc = DI_WRITE_WAIT(DSR_CAF, dsr);
+		if (rc)
+			goto err;
+	}
+
+	/* the timer won't count if it has never been written to */
+	if (__raw_readl(&data.regs->dtcmr) == 0) {
+		rc = DI_WRITE_WAIT(0, dtcmr);
+		if (rc)
+			goto err;
+	}
+
+	/* start keeping time */
+	if (!(__raw_readl(&data.regs->dcr) & DCR_TCE)) {
+		rc = DI_WRITE_WAIT(__raw_readl(&data.regs->dcr) | DCR_TCE, dcr);
+		if (rc)
+			goto err;
+	}
+
+	data.init_done = 1;
+	return 0;
+
+err:
+	return rc;
+}
+
+int rtc_get(struct rtc_time *tmp)
+{
+	unsigned long now;
+	int rc = 0;
+
+	if (!data.init_done) {
+		rc = di_init();
+		if (rc)
+			goto err;
+	}
+
+	now = __raw_readl(&data.regs->dtcmr);
+	to_tm(now, tmp);
+
+err:
+	return rc;
+}
+
+int rtc_set(struct rtc_time *tmp)
+{
+	unsigned long now;
+	int rc;
+
+	if (!data.init_done) {
+		rc = di_init();
+		if (rc)
+			goto err;
+	}
+
+	now = mktime(tmp->tm_year, tmp->tm_mon, tmp->tm_mday,
+		     tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+	/* zero the fractional part first */
+	rc = DI_WRITE_WAIT(0, dtclr);
+	if (rc == 0)
+		rc = DI_WRITE_WAIT(now, dtcmr);
+
+err:
+	return rc;
+}
+
+void rtc_reset(void)
+{
+	di_init();
+}
+
+#endif
diff --git a/marvell/uboot/drivers/rtc/isl1208.c b/marvell/uboot/drivers/rtc/isl1208.c
new file mode 100644
index 0000000..807e2e4
--- /dev/null
+++ b/marvell/uboot/drivers/rtc/isl1208.c
@@ -0,0 +1,147 @@
+/*
+ * (C) Copyright 2008
+ * Tor Krill, Excito Elektronik i Skåne , tor@excito.com
+ *
+ * Modelled after the ds1337 driver
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+/*
+ * Date & Time support (no alarms) for Intersil
+ * ISL1208 Real Time Clock (RTC).
+ */
+
+#include <common.h>
+#include <command.h>
+#include <rtc.h>
+#include <i2c.h>
+
+/*---------------------------------------------------------------------*/
+#ifdef DEBUG_RTC
+#define DEBUGR(fmt,args...) printf(fmt ,##args)
+#else
+#define DEBUGR(fmt,args...)
+#endif
+/*---------------------------------------------------------------------*/
+
+/*
+ * RTC register addresses
+ */
+
+#define RTC_SEC_REG_ADDR	0x0
+#define RTC_MIN_REG_ADDR	0x1
+#define RTC_HR_REG_ADDR		0x2
+#define RTC_DATE_REG_ADDR	0x3
+#define RTC_MON_REG_ADDR	0x4
+#define RTC_YR_REG_ADDR		0x5
+#define RTC_DAY_REG_ADDR	0x6
+#define RTC_STAT_REG_ADDR	0x7
+/*
+ * RTC control register bits
+ */
+
+/*
+ * RTC status register bits
+ */
+#define RTC_STAT_BIT_ARST	0x80	/* AUTO RESET ENABLE BIT */
+#define RTC_STAT_BIT_XTOSCB	0x40	/* CRYSTAL OSCILLATOR ENABLE BIT */
+#define RTC_STAT_BIT_WRTC	0x10	/* WRITE RTC ENABLE BIT */
+#define RTC_STAT_BIT_ALM	0x04	/* ALARM BIT */
+#define RTC_STAT_BIT_BAT	0x02	/* BATTERY BIT */
+#define RTC_STAT_BIT_RTCF	0x01	/* REAL TIME CLOCK FAIL BIT */
+
+static uchar rtc_read (uchar reg);
+static void rtc_write (uchar reg, uchar val);
+
+/*
+ * Get the current time from the RTC
+ */
+
+int rtc_get (struct rtc_time *tmp)
+{
+	int rel = 0;
+	uchar sec, min, hour, mday, wday, mon, year, status;
+
+	status = rtc_read (RTC_STAT_REG_ADDR);
+	sec = rtc_read (RTC_SEC_REG_ADDR);
+	min = rtc_read (RTC_MIN_REG_ADDR);
+	hour = rtc_read (RTC_HR_REG_ADDR);
+	wday = rtc_read (RTC_DAY_REG_ADDR);
+	mday = rtc_read (RTC_DATE_REG_ADDR);
+	mon = rtc_read (RTC_MON_REG_ADDR);
+	year = rtc_read (RTC_YR_REG_ADDR);
+
+	DEBUGR ("Get RTC year: %02x mon: %02x mday: %02x wday: %02x "
+		"hr: %02x min: %02x sec: %02x status: %02x\n",
+		year, mon, mday, wday, hour, min, sec, status);
+
+	if (status & RTC_STAT_BIT_RTCF) {
+		printf ("### Warning: RTC oscillator has stopped\n");
+		rtc_write(RTC_STAT_REG_ADDR,
+			rtc_read(RTC_STAT_REG_ADDR) &~ (RTC_STAT_BIT_BAT|RTC_STAT_BIT_RTCF));
+		rel = -1;
+	}
+
+	tmp->tm_sec  = bcd2bin (sec & 0x7F);
+	tmp->tm_min  = bcd2bin (min & 0x7F);
+	tmp->tm_hour = bcd2bin (hour & 0x3F);
+	tmp->tm_mday = bcd2bin (mday & 0x3F);
+	tmp->tm_mon  = bcd2bin (mon & 0x1F);
+	tmp->tm_year = bcd2bin (year)+2000;
+	tmp->tm_wday = bcd2bin (wday & 0x07);
+	tmp->tm_yday = 0;
+	tmp->tm_isdst= 0;
+
+	DEBUGR ("Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+	return rel;
+}
+
+/*
+ * Set the RTC
+ */
+int rtc_set (struct rtc_time *tmp)
+{
+	DEBUGR ("Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+	/* enable write */
+	rtc_write(RTC_STAT_REG_ADDR,
+		rtc_read(RTC_STAT_REG_ADDR) | RTC_STAT_BIT_WRTC);
+
+	rtc_write (RTC_YR_REG_ADDR, bin2bcd (tmp->tm_year % 100));
+	rtc_write (RTC_MON_REG_ADDR, bin2bcd (tmp->tm_mon));
+	rtc_write (RTC_DAY_REG_ADDR, bin2bcd (tmp->tm_wday));
+	rtc_write (RTC_DATE_REG_ADDR, bin2bcd (tmp->tm_mday));
+	rtc_write (RTC_HR_REG_ADDR, bin2bcd (tmp->tm_hour) | 0x80 ); /* 24h clock */
+	rtc_write (RTC_MIN_REG_ADDR, bin2bcd (tmp->tm_min));
+	rtc_write (RTC_SEC_REG_ADDR, bin2bcd (tmp->tm_sec));
+
+	/* disable write */
+	rtc_write(RTC_STAT_REG_ADDR,
+		rtc_read(RTC_STAT_REG_ADDR) & ~RTC_STAT_BIT_WRTC);
+
+	return 0;
+}
+
+void rtc_reset (void)
+{
+}
+
+/*
+ * Helper functions
+ */
+
+static uchar rtc_read (uchar reg)
+{
+	return (i2c_reg_read (CONFIG_SYS_I2C_RTC_ADDR, reg));
+}
+
+static void rtc_write (uchar reg, uchar val)
+{
+	i2c_reg_write (CONFIG_SYS_I2C_RTC_ADDR, reg, val);
+}
diff --git a/marvell/uboot/drivers/rtc/m41t11.c b/marvell/uboot/drivers/rtc/m41t11.c
new file mode 100644
index 0000000..fe0b5fb
--- /dev/null
+++ b/marvell/uboot/drivers/rtc/m41t11.c
@@ -0,0 +1,171 @@
+/*
+ * (C) Copyright 2002
+ * Andrew May, Viasat Inc, amay@viasat.com
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+/*
+ * M41T11 Serial Access Timekeeper(R) SRAM
+ * can you believe a trademark on that?
+ */
+
+/* #define DEBUG 1 */
+
+#include <common.h>
+#include <command.h>
+#include <rtc.h>
+#include <i2c.h>
+
+/*
+	I Don't have an example config file but this
+	is what should be done.
+
+#define CONFIG_RTC_M41T11 1
+#define CONFIG_SYS_I2C_RTC_ADDR 0x68
+#if 0
+#define CONFIG_SYS_M41T11_EXT_CENTURY_DATA
+#else
+#define CONFIG_SYS_M41T11_BASE_YEAR 2000
+#endif
+*/
+
+#if defined(CONFIG_SYS_I2C_RTC_ADDR) && defined(CONFIG_CMD_DATE)
+
+/* ------------------------------------------------------------------------- */
+/*
+  these are simple defines for the chip local to here so they aren't too
+  verbose
+  DAY/DATE aren't nice but that is how they are on the data sheet
+*/
+#define RTC_SEC_ADDR       0x0
+#define RTC_MIN_ADDR       0x1
+#define RTC_HOUR_ADDR      0x2
+#define RTC_DAY_ADDR       0x3
+#define RTC_DATE_ADDR      0x4
+#define RTC_MONTH_ADDR     0x5
+#define RTC_YEARS_ADDR     0x6
+
+#define RTC_REG_CNT        7
+
+#define RTC_CONTROL_ADDR   0x7
+
+
+#ifndef CONFIG_SYS_M41T11_EXT_CENTURY_DATA
+
+#define REG_CNT            (RTC_REG_CNT+1)
+
+/*
+  you only get 00-99 for the year we will asume you
+  want from the year 2000 if you don't set the config
+*/
+#ifndef CONFIG_SYS_M41T11_BASE_YEAR
+#define CONFIG_SYS_M41T11_BASE_YEAR 2000
+#endif
+
+#else
+/* we will store extra year info in byte 9*/
+#define M41T11_YEAR_DATA   0x8
+#define M41T11_YEAR_SIZE   1
+#define REG_CNT            (RTC_REG_CNT+1+M41T11_YEAR_SIZE)
+#endif
+
+#define M41T11_STORAGE_SZ  (64-REG_CNT)
+
+int rtc_get (struct rtc_time *tmp)
+{
+	int rel = 0;
+	uchar data[RTC_REG_CNT];
+
+	i2c_read(CONFIG_SYS_I2C_RTC_ADDR, RTC_SEC_ADDR, 1, data, RTC_REG_CNT);
+
+	if( data[RTC_SEC_ADDR] & 0x80 ){
+		printf( "m41t11 RTC Clock stopped!!!\n" );
+		rel = -1;
+	}
+	tmp->tm_sec  = bcd2bin (data[RTC_SEC_ADDR]  & 0x7F);
+	tmp->tm_min  = bcd2bin (data[RTC_MIN_ADDR]  & 0x7F);
+	tmp->tm_hour = bcd2bin (data[RTC_HOUR_ADDR] & 0x3F);
+	tmp->tm_mday = bcd2bin (data[RTC_DATE_ADDR] & 0x3F);
+	tmp->tm_mon  = bcd2bin (data[RTC_MONTH_ADDR]& 0x1F);
+#ifndef CONFIG_SYS_M41T11_EXT_CENTURY_DATA
+	tmp->tm_year = CONFIG_SYS_M41T11_BASE_YEAR
+		+ bcd2bin(data[RTC_YEARS_ADDR])
+		+ ((data[RTC_HOUR_ADDR]&0x40) ? 100 : 0);
+#else
+	{
+		unsigned char cent;
+		i2c_read(CONFIG_SYS_I2C_RTC_ADDR, M41T11_YEAR_DATA, 1, &cent, M41T11_YEAR_SIZE);
+		if( !(data[RTC_HOUR_ADDR] & 0x80) ){
+			printf( "m41t11 RTC: cann't keep track of years without CEB set\n" );
+			rel = -1;
+		}
+		if( (cent & 0x1) != ((data[RTC_HOUR_ADDR]&0x40)>>7) ){
+			/*century flip store off new year*/
+			cent += 1;
+			i2c_write(CONFIG_SYS_I2C_RTC_ADDR, M41T11_YEAR_DATA, 1, &cent, M41T11_YEAR_SIZE);
+		}
+		tmp->tm_year =((int)cent*100)+bcd2bin(data[RTC_YEARS_ADDR]);
+	}
+#endif
+	tmp->tm_wday = bcd2bin (data[RTC_DAY_ADDR]  & 0x07);
+	tmp->tm_yday = 0;
+	tmp->tm_isdst= 0;
+
+	debug ( "Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+	return rel;
+}
+
+int rtc_set (struct rtc_time *tmp)
+{
+	uchar data[RTC_REG_CNT];
+
+	debug ( "Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+	data[RTC_SEC_ADDR]    = bin2bcd(tmp->tm_sec) &  0x7F;/*just in case*/
+	data[RTC_MIN_ADDR]    = bin2bcd(tmp->tm_min);
+	data[RTC_HOUR_ADDR]   = bin2bcd(tmp->tm_hour) & 0x3F;/*handle cent stuff later*/
+	data[RTC_DATE_ADDR]   = bin2bcd(tmp->tm_mday) & 0x3F;
+	data[RTC_MONTH_ADDR]  = bin2bcd(tmp->tm_mon);
+	data[RTC_DAY_ADDR]    = bin2bcd(tmp->tm_wday) & 0x07;
+
+	data[RTC_HOUR_ADDR]   |= 0x80;/*we will always use CEB*/
+
+	data[RTC_YEARS_ADDR]  = bin2bcd(tmp->tm_year%100);/*same thing either way*/
+#ifndef CONFIG_SYS_M41T11_EXT_CENTURY_DATA
+	if( ((tmp->tm_year - CONFIG_SYS_M41T11_BASE_YEAR) > 200) ||
+	    (tmp->tm_year < CONFIG_SYS_M41T11_BASE_YEAR) ){
+		printf( "m41t11 RTC setting year out of range!!need recompile\n" );
+	}
+	data[RTC_HOUR_ADDR] |= (tmp->tm_year - CONFIG_SYS_M41T11_BASE_YEAR) > 100 ? 0x40 : 0;
+#else
+	{
+		unsigned char cent;
+		cent = tmp->tm_year ? tmp->tm_year / 100 : 0;
+		data[RTC_HOUR_ADDR] |= (cent & 0x1) ? 0x40 : 0;
+		i2c_write(CONFIG_SYS_I2C_RTC_ADDR, M41T11_YEAR_DATA, 1, &cent, M41T11_YEAR_SIZE);
+	}
+#endif
+	i2c_write(CONFIG_SYS_I2C_RTC_ADDR, RTC_SEC_ADDR, 1, data, RTC_REG_CNT);
+
+	return 0;
+}
+
+void rtc_reset (void)
+{
+	unsigned char val;
+	/* clear all control & status registers */
+	i2c_read(CONFIG_SYS_I2C_RTC_ADDR, RTC_SEC_ADDR, 1, &val, 1);
+	val = val & 0x7F;/*make sure we are running*/
+	i2c_write(CONFIG_SYS_I2C_RTC_ADDR, RTC_SEC_ADDR, 1, &val, RTC_REG_CNT);
+
+	i2c_read(CONFIG_SYS_I2C_RTC_ADDR, RTC_CONTROL_ADDR, 1, &val, 1);
+	val = val & 0x3F;/*turn off freq test keep calibration*/
+	i2c_write(CONFIG_SYS_I2C_RTC_ADDR, RTC_CONTROL_ADDR, 1, &val, 1);
+}
+#endif
diff --git a/marvell/uboot/drivers/rtc/m41t60.c b/marvell/uboot/drivers/rtc/m41t60.c
new file mode 100644
index 0000000..95083f0
--- /dev/null
+++ b/marvell/uboot/drivers/rtc/m41t60.c
@@ -0,0 +1,241 @@
+/*
+ * (C) Copyright 2007
+ * Larry Johnson, lrj@acm.org
+ *
+ * based on rtc/m41t11.c which is ...
+ *
+ * (C) Copyright 2002
+ * Andrew May, Viasat Inc, amay@viasat.com
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+/*
+ * STMicroelectronics M41T60 serial access real-time clock
+ */
+
+/* #define DEBUG 1 */
+
+#include <common.h>
+#include <command.h>
+#include <rtc.h>
+#include <i2c.h>
+
+#if defined(CONFIG_SYS_I2C_RTC_ADDR) && defined(CONFIG_CMD_DATE)
+
+/*
+ * Convert between century and "century bits" (CB1 and CB0).  These routines
+ * assume years are in the range 1900 - 2299.
+ */
+
+static unsigned char year2cb(unsigned const year)
+{
+	if (year < 1900 || year >= 2300)
+		printf("M41T60 RTC: year %d out of range\n", year);
+
+	return (year / 100) & 0x3;
+}
+
+static unsigned cb2year(unsigned const cb)
+{
+	return 1900 + 100 * ((cb + 1) & 0x3);
+}
+
+/*
+ * These are simple defines for the chip local to here so they aren't too
+ * verbose.  DAY/DATE aren't nice but that is how they are on the data sheet.
+ */
+#define RTC_SEC		0x0
+#define RTC_MIN		0x1
+#define RTC_HOUR	0x2
+#define RTC_DAY		0x3
+#define RTC_DATE	0x4
+#define RTC_MONTH	0x5
+#define RTC_YEAR	0x6
+
+#define RTC_REG_CNT	7
+
+#define RTC_CTRL	0x7
+
+#if defined(DEBUG)
+static void rtc_dump(char const *const label)
+{
+	uchar data[8];
+
+	if (i2c_read(CONFIG_SYS_I2C_RTC_ADDR, 0, 1, data, sizeof(data))) {
+		printf("I2C read failed in rtc_dump()\n");
+		return;
+	}
+	printf("RTC dump %s: %02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X\n",
+	       label, data[0], data[1], data[2], data[3],
+	       data[4], data[5], data[6], data[7]);
+}
+#else
+#define rtc_dump(label)
+#endif
+
+static uchar *rtc_validate(void)
+{
+	/*
+	 * This routine uses the OUT bit and the validity of the time values to
+	 * determine whether there has been an initial power-up since the last
+	 * time the routine was run.  It assumes that the OUT bit is not being
+	 * used for any other purpose.
+	 */
+	static const uchar daysInMonth[0x13] = {
+		0x00, 0x31, 0x29, 0x31, 0x30, 0x31, 0x30, 0x31,
+		0x31, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x31, 0x30, 0x31
+	};
+	static uchar data[8];
+	uchar min, date, month, years;
+
+	rtc_dump("begin validate");
+	if (i2c_read(CONFIG_SYS_I2C_RTC_ADDR, 0, 1, data, sizeof(data))) {
+		printf("I2C read failed in rtc_validate()\n");
+		return 0;
+	}
+	/*
+	 * If the OUT bit is "1", there has been a loss of power, so stop the
+	 * oscillator so it can be "kick-started" as per data sheet.
+	 */
+	if (0x00 != (data[RTC_CTRL] & 0x80)) {
+		printf("M41T60 RTC clock lost power.\n");
+		data[RTC_SEC] = 0x80;
+		if (i2c_write(CONFIG_SYS_I2C_RTC_ADDR, RTC_SEC, 1, data, 1)) {
+			printf("I2C write failed in rtc_validate()\n");
+			return 0;
+		}
+	}
+	/*
+	 * If the oscillator is stopped or the date is invalid, then reset the
+	 * OUT bit to "0", reset the date registers, and start the oscillator.
+	 */
+	min = data[RTC_MIN] & 0x7F;
+	date = data[RTC_DATE];
+	month = data[RTC_MONTH] & 0x3F;
+	years = data[RTC_YEAR];
+	if (0x59 < data[RTC_SEC] || 0x09 < (data[RTC_SEC] & 0x0F) ||
+	    0x59 < min || 0x09 < (min & 0x0F) ||
+	    0x23 < data[RTC_HOUR] || 0x09 < (data[RTC_HOUR] & 0x0F) ||
+	    0x07 < data[RTC_DAY] || 0x00 == data[RTC_DAY] ||
+	    0x12 < month ||
+	    0x99 < years || 0x09 < (years & 0x0F) ||
+	    daysInMonth[month] < date || 0x09 < (date & 0x0F) || 0x00 == date ||
+	    (0x29 == date && 0x02 == month &&
+	     ((0x00 != (years & 0x03)) ||
+	      (0x00 == years && 0x00 != (data[RTC_MONTH] & 0xC0))))) {
+		printf("Resetting M41T60 RTC clock.\n");
+		/*
+		 * Set to 00:00:00 1900-01-01 (Monday)
+		 */
+		data[RTC_SEC] = 0x00;
+		data[RTC_MIN] &= 0x80;	/* preserve OFIE bit */
+		data[RTC_HOUR] = 0x00;
+		data[RTC_DAY] = 0x02;
+		data[RTC_DATE] = 0x01;
+		data[RTC_MONTH] = 0xC1;
+		data[RTC_YEAR] = 0x00;
+		data[RTC_CTRL] &= 0x7F;	/* reset OUT bit */
+
+		if (i2c_write(CONFIG_SYS_I2C_RTC_ADDR, 0, 1, data, sizeof(data))) {
+			printf("I2C write failed in rtc_validate()\n");
+			return 0;
+		}
+	}
+	return data;
+}
+
+int rtc_get(struct rtc_time *tmp)
+{
+	uchar const *const data = rtc_validate();
+
+	if (!data)
+		return -1;
+
+	tmp->tm_sec = bcd2bin(data[RTC_SEC] & 0x7F);
+	tmp->tm_min = bcd2bin(data[RTC_MIN] & 0x7F);
+	tmp->tm_hour = bcd2bin(data[RTC_HOUR] & 0x3F);
+	tmp->tm_mday = bcd2bin(data[RTC_DATE] & 0x3F);
+	tmp->tm_mon = bcd2bin(data[RTC_MONTH] & 0x1F);
+	tmp->tm_year = cb2year(data[RTC_MONTH] >> 6) + bcd2bin(data[RTC_YEAR]);
+	tmp->tm_wday = bcd2bin(data[RTC_DAY] & 0x07) - 1;
+	tmp->tm_yday = 0;
+	tmp->tm_isdst = 0;
+
+	debug("Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+	      tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+	      tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+	return 0;
+}
+
+int rtc_set(struct rtc_time *tmp)
+{
+	uchar *const data = rtc_validate();
+
+	if (!data)
+		return -1;
+
+	debug("Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+	      tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+	      tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+	data[RTC_SEC] = (data[RTC_SEC] & 0x80) | (bin2bcd(tmp->tm_sec) & 0x7F);
+	data[RTC_MIN] = (data[RTC_MIN] & 0X80) | (bin2bcd(tmp->tm_min) & 0X7F);
+	data[RTC_HOUR] = bin2bcd(tmp->tm_hour) & 0x3F;
+	data[RTC_DATE] = bin2bcd(tmp->tm_mday) & 0x3F;
+	data[RTC_MONTH] = bin2bcd(tmp->tm_mon) & 0x1F;
+	data[RTC_YEAR] = bin2bcd(tmp->tm_year % 100);
+	data[RTC_MONTH] |= year2cb(tmp->tm_year) << 6;
+	data[RTC_DAY] = bin2bcd(tmp->tm_wday + 1) & 0x07;
+	if (i2c_write(CONFIG_SYS_I2C_RTC_ADDR, 0, 1, data, RTC_REG_CNT)) {
+		printf("I2C write failed in rtc_set()\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+void rtc_reset(void)
+{
+	uchar *const data = rtc_validate();
+	char const *const s = getenv("rtccal");
+
+	if (!data)
+		return;
+
+	rtc_dump("begin reset");
+	/*
+	 * If environmental variable "rtccal" is present, it must be a hex value
+	 * between 0x00 and 0x3F, inclusive.  The five least-significan bits
+	 * represent the calibration magnitude, and the sixth bit the sign bit.
+	 * If these do not match the contents of the hardware register, that
+	 * register is updated.  The value 0x00 imples no correction.  Consult
+	 * the M41T60 documentation for further details.
+	 */
+	if (s) {
+		unsigned long const l = simple_strtoul(s, 0, 16);
+
+		if (l <= 0x3F) {
+			if ((data[RTC_CTRL] & 0x3F) != l) {
+				printf("Setting RTC calibration to 0x%02lX\n",
+				       l);
+				data[RTC_CTRL] &= 0xC0;
+				data[RTC_CTRL] |= (uchar) l;
+			}
+		} else
+			printf("environment parameter \"rtccal\" not valid: "
+			       "ignoring\n");
+	}
+	/*
+	 * Turn off frequency test.
+	 */
+	data[RTC_CTRL] &= 0xBF;
+	if (i2c_write(CONFIG_SYS_I2C_RTC_ADDR, RTC_CTRL, 1, data + RTC_CTRL, 1)) {
+		printf("I2C write failed in rtc_reset()\n");
+		return;
+	}
+	rtc_dump("end reset");
+}
+#endif /* CONFIG_RTC_M41T60 && CONFIG_SYS_I2C_RTC_ADDR && CONFIG_CMD_DATE */
diff --git a/marvell/uboot/drivers/rtc/m41t62.c b/marvell/uboot/drivers/rtc/m41t62.c
new file mode 100644
index 0000000..3829bc5
--- /dev/null
+++ b/marvell/uboot/drivers/rtc/m41t62.c
@@ -0,0 +1,135 @@
+/*
+ * (C) Copyright 2008
+ * Stefan Roese, DENX Software Engineering, sr@denx.de.
+ *
+ * based on a the Linux rtc-m41t80.c driver which is:
+ *   Alexander Bigga <ab@mycable.de>, 2006 (c) mycable GmbH
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+/*
+ * Date & Time support for STMicroelectronics M41T62
+ */
+
+/* #define	DEBUG	*/
+
+#include <common.h>
+#include <command.h>
+#include <rtc.h>
+#include <i2c.h>
+
+#if defined(CONFIG_CMD_DATE)
+
+#define M41T62_REG_SSEC	0
+#define M41T62_REG_SEC	1
+#define M41T62_REG_MIN	2
+#define M41T62_REG_HOUR	3
+#define M41T62_REG_WDAY	4
+#define M41T62_REG_DAY	5
+#define M41T62_REG_MON	6
+#define M41T62_REG_YEAR	7
+#define M41T62_REG_ALARM_MON	0xa
+#define M41T62_REG_ALARM_DAY	0xb
+#define M41T62_REG_ALARM_HOUR	0xc
+#define M41T62_REG_ALARM_MIN	0xd
+#define M41T62_REG_ALARM_SEC	0xe
+#define M41T62_REG_FLAGS	0xf
+
+#define M41T62_DATETIME_REG_SIZE	(M41T62_REG_YEAR + 1)
+#define M41T62_ALARM_REG_SIZE	\
+	(M41T62_REG_ALARM_SEC + 1 - M41T62_REG_ALARM_MON)
+
+#define M41T62_SEC_ST		(1 << 7)	/* ST: Stop Bit */
+#define M41T62_ALMON_AFE	(1 << 7)	/* AFE: AF Enable Bit */
+#define M41T62_ALMON_SQWE	(1 << 6)	/* SQWE: SQW Enable Bit */
+#define M41T62_ALHOUR_HT	(1 << 6)	/* HT: Halt Update Bit */
+#define M41T62_FLAGS_AF		(1 << 6)	/* AF: Alarm Flag Bit */
+#define M41T62_FLAGS_BATT_LOW	(1 << 4)	/* BL: Battery Low Bit */
+
+#define M41T62_FEATURE_HT	(1 << 0)
+#define M41T62_FEATURE_BL	(1 << 1)
+
+#define M41T80_ALHOUR_HT	(1 << 6)	/* HT: Halt Update Bit */
+
+int rtc_get(struct rtc_time *tm)
+{
+	u8 buf[M41T62_DATETIME_REG_SIZE];
+
+	i2c_read(CONFIG_SYS_I2C_RTC_ADDR, 0, 1, buf, M41T62_DATETIME_REG_SIZE);
+
+	debug("%s: raw read data - sec=%02x, min=%02x, hr=%02x, "
+	      "mday=%02x, mon=%02x, year=%02x, wday=%02x, y2k=%02x\n",
+	      __FUNCTION__,
+	      buf[0], buf[1], buf[2], buf[3],
+	      buf[4], buf[5], buf[6], buf[7]);
+
+	tm->tm_sec = bcd2bin(buf[M41T62_REG_SEC] & 0x7f);
+	tm->tm_min = bcd2bin(buf[M41T62_REG_MIN] & 0x7f);
+	tm->tm_hour = bcd2bin(buf[M41T62_REG_HOUR] & 0x3f);
+	tm->tm_mday = bcd2bin(buf[M41T62_REG_DAY] & 0x3f);
+	tm->tm_wday = buf[M41T62_REG_WDAY] & 0x07;
+	tm->tm_mon = bcd2bin(buf[M41T62_REG_MON] & 0x1f);
+
+	/* assume 20YY not 19YY, and ignore the Century Bit */
+	/* U-Boot needs to add 1900 here */
+	tm->tm_year = bcd2bin(buf[M41T62_REG_YEAR]) + 100 + 1900;
+
+	debug("%s: tm is secs=%d, mins=%d, hours=%d, "
+	      "mday=%d, mon=%d, year=%d, wday=%d\n",
+	      __FUNCTION__,
+	      tm->tm_sec, tm->tm_min, tm->tm_hour,
+	      tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
+
+	return 0;
+}
+
+int rtc_set(struct rtc_time *tm)
+{
+	u8 buf[M41T62_DATETIME_REG_SIZE];
+
+	debug("Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+	      tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_wday,
+	      tm->tm_hour, tm->tm_min, tm->tm_sec);
+
+	i2c_read(CONFIG_SYS_I2C_RTC_ADDR, 0, 1, buf, M41T62_DATETIME_REG_SIZE);
+
+	/* Merge time-data and register flags into buf[0..7] */
+	buf[M41T62_REG_SSEC] = 0;
+	buf[M41T62_REG_SEC] =
+		bin2bcd(tm->tm_sec) | (buf[M41T62_REG_SEC] & ~0x7f);
+	buf[M41T62_REG_MIN] =
+		bin2bcd(tm->tm_min) | (buf[M41T62_REG_MIN] & ~0x7f);
+	buf[M41T62_REG_HOUR] =
+		bin2bcd(tm->tm_hour) | (buf[M41T62_REG_HOUR] & ~0x3f) ;
+	buf[M41T62_REG_WDAY] =
+		(tm->tm_wday & 0x07) | (buf[M41T62_REG_WDAY] & ~0x07);
+	buf[M41T62_REG_DAY] =
+		bin2bcd(tm->tm_mday) | (buf[M41T62_REG_DAY] & ~0x3f);
+	buf[M41T62_REG_MON] =
+		bin2bcd(tm->tm_mon) | (buf[M41T62_REG_MON] & ~0x1f);
+	/* assume 20YY not 19YY */
+	buf[M41T62_REG_YEAR] = bin2bcd(tm->tm_year % 100);
+
+	if (i2c_write(CONFIG_SYS_I2C_RTC_ADDR, 0, 1, buf, M41T62_DATETIME_REG_SIZE)) {
+		printf("I2C write failed in %s()\n", __func__);
+		return -1;
+	}
+
+	return 0;
+}
+
+void rtc_reset(void)
+{
+	u8 val;
+
+	/*
+	 * M41T82: Make sure HT (Halt Update) bit is cleared.
+	 * This bit is 0 in M41T62 so its save to clear it always.
+	 */
+	i2c_read(CONFIG_SYS_I2C_RTC_ADDR, M41T62_REG_ALARM_HOUR, 1, &val, 1);
+	val &= ~M41T80_ALHOUR_HT;
+	i2c_write(CONFIG_SYS_I2C_RTC_ADDR, M41T62_REG_ALARM_HOUR, 1, &val, 1);
+}
+
+#endif
diff --git a/marvell/uboot/drivers/rtc/m41t94.c b/marvell/uboot/drivers/rtc/m41t94.c
new file mode 100644
index 0000000..5b665bb
--- /dev/null
+++ b/marvell/uboot/drivers/rtc/m41t94.c
@@ -0,0 +1,123 @@
+/*
+ * Driver for ST M41T94 SPI RTC
+ *
+ * Taken from the Linux kernel drivier:
+ * Copyright (C) 2008 Kim B. Heino
+ *
+ * Adaptation for U-Boot:
+ * Copyright (C) 2009
+ * Albin Tonnerre, Free Electrons <albin.tonnerre@free-electrons.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <common.h>
+#include <rtc.h>
+#include <spi.h>
+
+static struct spi_slave *slave;
+
+#define M41T94_REG_SECONDS	0x01
+#define M41T94_REG_MINUTES	0x02
+#define M41T94_REG_HOURS	0x03
+#define M41T94_REG_WDAY		0x04
+#define M41T94_REG_DAY		0x05
+#define M41T94_REG_MONTH	0x06
+#define M41T94_REG_YEAR		0x07
+#define M41T94_REG_HT		0x0c
+
+#define M41T94_BIT_HALT		0x40
+#define M41T94_BIT_STOP		0x80
+#define M41T94_BIT_CB		0x40
+#define M41T94_BIT_CEB		0x80
+
+int rtc_set(struct rtc_time *tm)
+{
+	u8 buf[8]; /* write cmd + 7 registers */
+	int ret;
+
+	if (!slave) {
+		slave = spi_setup_slave(CONFIG_M41T94_SPI_BUS,
+					CONFIG_M41T94_SPI_CS, 1000000,
+					SPI_MODE_3);
+		if (!slave)
+			return -1;
+	}
+	spi_claim_bus(slave);
+
+	buf[0] = 0x80 | M41T94_REG_SECONDS; /* write time + date */
+	buf[M41T94_REG_SECONDS] = bin2bcd(tm->tm_sec);
+	buf[M41T94_REG_MINUTES] = bin2bcd(tm->tm_min);
+	buf[M41T94_REG_HOURS]   = bin2bcd(tm->tm_hour);
+	buf[M41T94_REG_WDAY]    = bin2bcd(tm->tm_wday + 1);
+	buf[M41T94_REG_DAY]     = bin2bcd(tm->tm_mday);
+	buf[M41T94_REG_MONTH]   = bin2bcd(tm->tm_mon + 1);
+
+	buf[M41T94_REG_HOURS] |= M41T94_BIT_CEB;
+	if (tm->tm_year >= 100)
+		buf[M41T94_REG_HOURS] |= M41T94_BIT_CB;
+	buf[M41T94_REG_YEAR] = bin2bcd(tm->tm_year % 100);
+
+	ret = spi_xfer(slave, 64, buf, NULL, SPI_XFER_BEGIN | SPI_XFER_END);
+	spi_release_bus(slave);
+	return ret;
+}
+
+int rtc_get(struct rtc_time *tm)
+{
+	u8 buf[2];
+	int ret, hour;
+
+	if (!slave) {
+		slave = spi_setup_slave(CONFIG_M41T94_SPI_BUS,
+					CONFIG_M41T94_SPI_CS, 1000000,
+					SPI_MODE_3);
+		if (!slave)
+			return -1;
+	}
+	spi_claim_bus(slave);
+
+	/* clear halt update bit */
+	ret = spi_w8r8(slave, M41T94_REG_HT);
+	if (ret < 0)
+		return ret;
+	if (ret & M41T94_BIT_HALT) {
+		buf[0] = 0x80 | M41T94_REG_HT;
+		buf[1] = ret & ~M41T94_BIT_HALT;
+		spi_xfer(slave, 16, buf, NULL, SPI_XFER_BEGIN | SPI_XFER_END);
+	}
+
+	/* clear stop bit */
+	ret = spi_w8r8(slave, M41T94_REG_SECONDS);
+	if (ret < 0)
+		return ret;
+	if (ret & M41T94_BIT_STOP) {
+		buf[0] = 0x80 | M41T94_REG_SECONDS;
+		buf[1] = ret & ~M41T94_BIT_STOP;
+		spi_xfer(slave, 16, buf, NULL, SPI_XFER_BEGIN | SPI_XFER_END);
+	}
+
+	tm->tm_sec  = bcd2bin(spi_w8r8(slave, M41T94_REG_SECONDS));
+	tm->tm_min  = bcd2bin(spi_w8r8(slave, M41T94_REG_MINUTES));
+	hour = spi_w8r8(slave, M41T94_REG_HOURS);
+	tm->tm_hour = bcd2bin(hour & 0x3f);
+	tm->tm_wday = bcd2bin(spi_w8r8(slave, M41T94_REG_WDAY)) - 1;
+	tm->tm_mday = bcd2bin(spi_w8r8(slave, M41T94_REG_DAY));
+	tm->tm_mon  = bcd2bin(spi_w8r8(slave, M41T94_REG_MONTH)) - 1;
+	tm->tm_year = bcd2bin(spi_w8r8(slave, M41T94_REG_YEAR));
+	if ((hour & M41T94_BIT_CB) || !(hour & M41T94_BIT_CEB))
+		tm->tm_year += 100;
+
+	spi_release_bus(slave);
+	return 0;
+}
+
+void rtc_reset(void)
+{
+	/*
+	 * Could not be tested as the reset pin is not wired on
+	 * the sbc35-ag20 board
+	 */
+}
diff --git a/marvell/uboot/drivers/rtc/m48t35ax.c b/marvell/uboot/drivers/rtc/m48t35ax.c
new file mode 100644
index 0000000..021b91f
--- /dev/null
+++ b/marvell/uboot/drivers/rtc/m48t35ax.c
@@ -0,0 +1,142 @@
+/*
+ * (C) Copyright 2001
+ * Erik Theisen,  Wave 7 Optics, etheisen@mindspring.com.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+/*
+ * Date & Time support for ST Electronics M48T35Ax RTC
+ */
+
+/*#define       DEBUG */
+
+
+#include <common.h>
+#include <command.h>
+#include <rtc.h>
+#include <config.h>
+
+#if defined(CONFIG_CMD_DATE)
+
+static uchar rtc_read  (uchar reg);
+static void  rtc_write (uchar reg, uchar val);
+
+/* ------------------------------------------------------------------------- */
+
+int rtc_get (struct rtc_time *tmp)
+{
+	uchar sec, min, hour, cent_day, date, month, year;
+	uchar ccr;			/* Clock control register */
+
+	/* Lock RTC for read using clock control register */
+	ccr = rtc_read(0);
+	ccr = ccr | 0x40;
+	rtc_write(0, ccr);
+
+	sec	= rtc_read (0x1);
+	min	= rtc_read (0x2);
+	hour	= rtc_read (0x3);
+	cent_day= rtc_read (0x4);
+	date	= rtc_read (0x5);
+	month   = rtc_read (0x6);
+	year	= rtc_read (0x7);
+
+	/* UNLock RTC */
+	ccr = rtc_read(0);
+	ccr = ccr & 0xBF;
+	rtc_write(0, ccr);
+
+	debug ( "Get RTC year: %02x month: %02x date: %02x cent_day: %02x "
+		"hr: %02x min: %02x sec: %02x\n",
+		year, month, date, cent_day,
+		hour, min, sec );
+
+	tmp->tm_sec  = bcd2bin (sec  & 0x7F);
+	tmp->tm_min  = bcd2bin (min  & 0x7F);
+	tmp->tm_hour = bcd2bin (hour & 0x3F);
+	tmp->tm_mday = bcd2bin (date & 0x3F);
+	tmp->tm_mon  = bcd2bin (month & 0x1F);
+	tmp->tm_year = bcd2bin (year) + ((cent_day & 0x10) ? 2000 : 1900);
+	tmp->tm_wday = bcd2bin (cent_day & 0x07);
+	tmp->tm_yday = 0;
+	tmp->tm_isdst= 0;
+
+	debug ( "Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+	return 0;
+}
+
+int rtc_set (struct rtc_time *tmp)
+{
+	uchar ccr;			/* Clock control register */
+	uchar century;
+
+	debug ( "Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+	/* Lock RTC for write using clock control register */
+	ccr = rtc_read(0);
+	ccr = ccr | 0x80;
+	rtc_write(0, ccr);
+
+	rtc_write (0x07, bin2bcd(tmp->tm_year % 100));
+	rtc_write (0x06, bin2bcd(tmp->tm_mon));
+	rtc_write (0x05, bin2bcd(tmp->tm_mday));
+
+	century = ((tmp->tm_year >= 2000) ? 0x10 : 0) | 0x20;
+	rtc_write (0x04, bin2bcd(tmp->tm_wday) | century);
+
+	rtc_write (0x03, bin2bcd(tmp->tm_hour));
+	rtc_write (0x02, bin2bcd(tmp->tm_min ));
+	rtc_write (0x01, bin2bcd(tmp->tm_sec ));
+
+	/* UNLock RTC */
+	ccr = rtc_read(0);
+	ccr = ccr & 0x7F;
+	rtc_write(0, ccr);
+
+	return 0;
+}
+
+void rtc_reset (void)
+{
+	uchar val;
+
+	/* Clear all clock control registers */
+	rtc_write (0x0, 0x80);		/* No Read Lock or calibration */
+
+	/* Clear stop bit */
+	val = rtc_read (0x1);
+	val &= 0x7f;
+	rtc_write(0x1, val);
+
+	/* Enable century / disable frequency test */
+	val = rtc_read (0x4);
+	val = (val & 0xBF) | 0x20;
+	rtc_write(0x4, val);
+
+	/* Clear write lock */
+	rtc_write(0x0, 0);
+}
+
+/* ------------------------------------------------------------------------- */
+
+static uchar rtc_read (uchar reg)
+{
+	uchar val;
+	val = *(unsigned char *)
+		((CONFIG_SYS_NVRAM_BASE_ADDR + CONFIG_SYS_NVRAM_SIZE - 8) + reg);
+	return val;
+}
+
+static void rtc_write (uchar reg, uchar val)
+{
+	*(unsigned char *)
+		((CONFIG_SYS_NVRAM_BASE_ADDR + CONFIG_SYS_NVRAM_SIZE - 8) + reg) = val;
+}
+
+#endif
diff --git a/marvell/uboot/drivers/rtc/max6900.c b/marvell/uboot/drivers/rtc/max6900.c
new file mode 100644
index 0000000..48ad0a0
--- /dev/null
+++ b/marvell/uboot/drivers/rtc/max6900.c
@@ -0,0 +1,109 @@
+/*
+ * (C) Copyright 2004
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+/*
+ * Date & Time support for MAXIM MAX6900 RTC
+ */
+
+/* #define	DEBUG	*/
+
+#include <common.h>
+#include <command.h>
+#include <rtc.h>
+#include <i2c.h>
+
+#if defined(CONFIG_CMD_DATE)
+
+#ifndef	CONFIG_SYS_I2C_RTC_ADDR
+#define	CONFIG_SYS_I2C_RTC_ADDR	0x50
+#endif
+
+/* ------------------------------------------------------------------------- */
+
+static uchar rtc_read (uchar reg)
+{
+	return (i2c_reg_read (CONFIG_SYS_I2C_RTC_ADDR, reg));
+}
+
+static void rtc_write (uchar reg, uchar val)
+{
+	i2c_reg_write (CONFIG_SYS_I2C_RTC_ADDR, reg, val);
+	udelay(2500);
+}
+
+/* ------------------------------------------------------------------------- */
+
+int rtc_get (struct rtc_time *tmp)
+{
+	uchar sec, min, hour, mday, wday, mon, cent, year;
+	int retry = 1;
+
+	do {
+		sec	= rtc_read (0x80);
+		min	= rtc_read (0x82);
+		hour	= rtc_read (0x84);
+		mday	= rtc_read (0x86);
+		mon	= rtc_read (0x88);
+		wday	= rtc_read (0x8a);
+		year	= rtc_read (0x8c);
+		cent	= rtc_read (0x92);
+		/*
+		 * Check for seconds rollover
+		 */
+		if ((sec != 59) || (rtc_read(0x80) == sec)){
+			retry = 0;
+		}
+	} while (retry);
+
+	debug ( "Get RTC year: %02x mon: %02x cent: %02x mday: %02x wday: %02x "
+		"hr: %02x min: %02x sec: %02x\n",
+		year, mon, cent, mday, wday,
+		hour, min, sec );
+
+	tmp->tm_sec  = bcd2bin (sec  & 0x7F);
+	tmp->tm_min  = bcd2bin (min  & 0x7F);
+	tmp->tm_hour = bcd2bin (hour & 0x3F);
+	tmp->tm_mday = bcd2bin (mday & 0x3F);
+	tmp->tm_mon  = bcd2bin (mon & 0x1F);
+	tmp->tm_year = bcd2bin (year) + bcd2bin(cent) * 100;
+	tmp->tm_wday = bcd2bin (wday & 0x07);
+	tmp->tm_yday = 0;
+	tmp->tm_isdst= 0;
+
+	debug ( "Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+	return 0;
+}
+
+int rtc_set (struct rtc_time *tmp)
+{
+
+	debug ( "Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+	rtc_write (0x9E, 0x00);
+	rtc_write (0x80, 0);	/* Clear seconds to ensure no rollover */
+	rtc_write (0x92, bin2bcd(tmp->tm_year / 100));
+	rtc_write (0x8c, bin2bcd(tmp->tm_year % 100));
+	rtc_write (0x8a, bin2bcd(tmp->tm_wday));
+	rtc_write (0x88, bin2bcd(tmp->tm_mon));
+	rtc_write (0x86, bin2bcd(tmp->tm_mday));
+	rtc_write (0x84, bin2bcd(tmp->tm_hour));
+	rtc_write (0x82, bin2bcd(tmp->tm_min ));
+	rtc_write (0x80, bin2bcd(tmp->tm_sec ));
+
+	return 0;
+}
+
+void rtc_reset (void)
+{
+}
+
+#endif
diff --git a/marvell/uboot/drivers/rtc/mc13xxx-rtc.c b/marvell/uboot/drivers/rtc/mc13xxx-rtc.c
new file mode 100644
index 0000000..528247a
--- /dev/null
+++ b/marvell/uboot/drivers/rtc/mc13xxx-rtc.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2008, Guennadi Liakhovetski <lg@denx.de>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <rtc.h>
+#include <spi.h>
+#include <power/pmic.h>
+#include <fsl_pmic.h>
+
+int rtc_get(struct rtc_time *rtc)
+{
+	u32 day1, day2, time;
+	int tim, i = 0;
+	struct pmic *p = pmic_get("FSL_PMIC");
+	int ret;
+
+	if (!p)
+		return -1;
+	do {
+		ret = pmic_reg_read(p, REG_RTC_DAY, &day1);
+		if (ret < 0)
+			return -1;
+
+		ret = pmic_reg_read(p, REG_RTC_TIME, &time);
+		if (ret < 0)
+			return -1;
+
+		ret = pmic_reg_read(p, REG_RTC_DAY, &day2);
+		if (ret < 0)
+			return -1;
+
+	} while (day1 != day2 && i++ < 3);
+
+	tim = day1 * 86400 + time;
+
+	to_tm(tim, rtc);
+
+	rtc->tm_yday = 0;
+	rtc->tm_isdst = 0;
+
+	return 0;
+}
+
+int rtc_set(struct rtc_time *rtc)
+{
+	u32 time, day;
+	struct pmic *p = pmic_get("FSL_PMIC");
+	if (!p)
+		return -1;
+
+	time = mktime(rtc->tm_year, rtc->tm_mon, rtc->tm_mday,
+		      rtc->tm_hour, rtc->tm_min, rtc->tm_sec);
+	day = time / 86400;
+	time %= 86400;
+
+	pmic_reg_write(p, REG_RTC_DAY, day);
+	pmic_reg_write(p, REG_RTC_TIME, time);
+
+	return 0;
+}
+
+void rtc_reset(void)
+{
+}
diff --git a/marvell/uboot/drivers/rtc/mc146818.c b/marvell/uboot/drivers/rtc/mc146818.c
new file mode 100644
index 0000000..f7cf106
--- /dev/null
+++ b/marvell/uboot/drivers/rtc/mc146818.c
@@ -0,0 +1,152 @@
+/*
+ * (C) Copyright 2001
+ * Denis Peter MPL AG Switzerland. d.peter@mpl.ch
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+/*
+ * Date & Time support for the MC146818 (PIXX4) RTC
+ */
+
+/*#define	DEBUG*/
+
+#include <common.h>
+#include <command.h>
+#include <rtc.h>
+
+#if defined(__I386__) || defined(CONFIG_MALTA)
+#include <asm/io.h>
+#define in8(p) inb(p)
+#define out8(p, v) outb(v, p)
+#endif
+
+#if defined(CONFIG_CMD_DATE)
+
+static uchar rtc_read  (uchar reg);
+static void  rtc_write (uchar reg, uchar val);
+
+#define RTC_PORT_MC146818	CONFIG_SYS_ISA_IO_BASE_ADDRESS +  0x70
+#define RTC_SECONDS		0x00
+#define RTC_SECONDS_ALARM	0x01
+#define RTC_MINUTES		0x02
+#define RTC_MINUTES_ALARM	0x03
+#define RTC_HOURS		0x04
+#define RTC_HOURS_ALARM		0x05
+#define RTC_DAY_OF_WEEK		0x06
+#define RTC_DATE_OF_MONTH	0x07
+#define RTC_MONTH		0x08
+#define RTC_YEAR		0x09
+#define RTC_CONFIG_A		0x0A
+#define RTC_CONFIG_B		0x0B
+#define RTC_CONFIG_C		0x0C
+#define RTC_CONFIG_D		0x0D
+
+
+/* ------------------------------------------------------------------------- */
+
+int rtc_get (struct rtc_time *tmp)
+{
+	uchar sec, min, hour, mday, wday, mon, year;
+  /* here check if rtc can be accessed */
+	while((rtc_read(RTC_CONFIG_A)&0x80)==0x80);
+	sec	= rtc_read (RTC_SECONDS);
+	min	= rtc_read (RTC_MINUTES);
+	hour	= rtc_read (RTC_HOURS);
+	mday	= rtc_read (RTC_DATE_OF_MONTH);
+	wday	= rtc_read (RTC_DAY_OF_WEEK);
+	mon	= rtc_read (RTC_MONTH);
+	year	= rtc_read (RTC_YEAR);
+#ifdef RTC_DEBUG
+	printf ( "Get RTC year: %02x mon/cent: %02x mday: %02x wday: %02x "
+		"hr: %02x min: %02x sec: %02x\n",
+		year, mon, mday, wday,
+		hour, min, sec );
+	printf ( "Alarms: month: %02x hour: %02x min: %02x sec: %02x\n",
+		rtc_read (RTC_CONFIG_D) & 0x3F,
+		rtc_read (RTC_HOURS_ALARM),
+		rtc_read (RTC_MINUTES_ALARM),
+		rtc_read (RTC_SECONDS_ALARM) );
+#endif
+	tmp->tm_sec  = bcd2bin (sec  & 0x7F);
+	tmp->tm_min  = bcd2bin (min  & 0x7F);
+	tmp->tm_hour = bcd2bin (hour & 0x3F);
+	tmp->tm_mday = bcd2bin (mday & 0x3F);
+	tmp->tm_mon  = bcd2bin (mon & 0x1F);
+	tmp->tm_year = bcd2bin (year);
+	tmp->tm_wday = bcd2bin (wday & 0x07);
+	if(tmp->tm_year<70)
+		tmp->tm_year+=2000;
+	else
+		tmp->tm_year+=1900;
+	tmp->tm_yday = 0;
+	tmp->tm_isdst= 0;
+#ifdef RTC_DEBUG
+	printf ( "Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+#endif
+
+	return 0;
+}
+
+int rtc_set (struct rtc_time *tmp)
+{
+#ifdef RTC_DEBUG
+	printf ( "Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+#endif
+	rtc_write(RTC_CONFIG_B,0x82); /* disables the RTC to update the regs */
+
+	rtc_write (RTC_YEAR, bin2bcd(tmp->tm_year % 100));
+	rtc_write (RTC_MONTH, bin2bcd(tmp->tm_mon));
+	rtc_write (RTC_DAY_OF_WEEK, bin2bcd(tmp->tm_wday));
+	rtc_write (RTC_DATE_OF_MONTH, bin2bcd(tmp->tm_mday));
+	rtc_write (RTC_HOURS, bin2bcd(tmp->tm_hour));
+	rtc_write (RTC_MINUTES, bin2bcd(tmp->tm_min ));
+	rtc_write (RTC_SECONDS, bin2bcd(tmp->tm_sec ));
+	rtc_write(RTC_CONFIG_B,0x02); /* enables the RTC to update the regs */
+
+	return 0;
+}
+
+void rtc_reset (void)
+{
+	rtc_write(RTC_CONFIG_B,0x82); /* disables the RTC to update the regs */
+	rtc_write(RTC_CONFIG_A,0x20); /* Normal OP */
+	rtc_write(RTC_CONFIG_B,0x00);
+	rtc_write(RTC_CONFIG_B,0x00);
+	rtc_write(RTC_CONFIG_B,0x02); /* enables the RTC to update the regs */
+}
+
+/* ------------------------------------------------------------------------- */
+
+#ifdef CONFIG_SYS_RTC_REG_BASE_ADDR
+/*
+ * use direct memory access
+ */
+static uchar rtc_read (uchar reg)
+{
+	return(in8(CONFIG_SYS_RTC_REG_BASE_ADDR+reg));
+}
+
+static void rtc_write (uchar reg, uchar val)
+{
+	out8(CONFIG_SYS_RTC_REG_BASE_ADDR+reg, val);
+}
+#else
+static uchar rtc_read (uchar reg)
+{
+	out8(RTC_PORT_MC146818,reg);
+	return(in8(RTC_PORT_MC146818+1));
+}
+
+static void rtc_write (uchar reg, uchar val)
+{
+	out8(RTC_PORT_MC146818,reg);
+	out8(RTC_PORT_MC146818+1,val);
+}
+#endif
+
+#endif
diff --git a/marvell/uboot/drivers/rtc/mcfrtc.c b/marvell/uboot/drivers/rtc/mcfrtc.c
new file mode 100644
index 0000000..8961ca4
--- /dev/null
+++ b/marvell/uboot/drivers/rtc/mcfrtc.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2004-2007 Freescale Semiconductor, Inc.
+ * TsiChung Liew (Tsi-Chung.Liew@freescale.com)
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+
+#if defined(CONFIG_CMD_DATE)
+
+#include <command.h>
+#include <rtc.h>
+#include <asm/immap.h>
+#include <asm/rtc.h>
+
+#undef RTC_DEBUG
+
+#ifndef CONFIG_SYS_MCFRTC_BASE
+#error RTC_BASE is not defined!
+#endif
+
+#define isleap(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0)
+#define	STARTOFTIME		1970
+
+int rtc_get(struct rtc_time *tmp)
+{
+	volatile rtc_t *rtc = (rtc_t *) (CONFIG_SYS_MCFRTC_BASE);
+
+	int rtc_days, rtc_hrs, rtc_mins;
+	int tim;
+
+	rtc_days = rtc->days;
+	rtc_hrs = rtc->hourmin >> 8;
+	rtc_mins = RTC_HOURMIN_MINUTES(rtc->hourmin);
+
+	tim = (rtc_days * 24) + rtc_hrs;
+	tim = (tim * 60) + rtc_mins;
+	tim = (tim * 60) + rtc->seconds;
+
+	to_tm(tim, tmp);
+
+	tmp->tm_yday = 0;
+	tmp->tm_isdst = 0;
+
+#ifdef RTC_DEBUG
+	printf("Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+	       tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+	       tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+#endif
+
+	return 0;
+}
+
+int rtc_set(struct rtc_time *tmp)
+{
+	volatile rtc_t *rtc = (rtc_t *) (CONFIG_SYS_MCFRTC_BASE);
+
+	static int month_days[12] = {
+		31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
+	};
+	int days, i, months;
+
+	if (tmp->tm_year > 2037) {
+		printf("Unable to handle. Exceeding integer limitation!\n");
+		tmp->tm_year = 2027;
+	}
+#ifdef RTC_DEBUG
+	printf("Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+	       tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+	       tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+#endif
+
+	/* calculate days by years */
+	for (i = STARTOFTIME, days = 0; i < tmp->tm_year; i++) {
+		days += 365 + isleap(i);
+	}
+
+	/* calculate days by months */
+	months = tmp->tm_mon - 1;
+	for (i = 0; i < months; i++) {
+		days += month_days[i];
+
+		if (i == 1)
+			days += isleap(i);
+	}
+
+	days += tmp->tm_mday - 1;
+
+	rtc->days = days;
+	rtc->hourmin = (tmp->tm_hour << 8) | tmp->tm_min;
+	rtc->seconds = tmp->tm_sec;
+
+	return 0;
+}
+
+void rtc_reset(void)
+{
+	volatile rtc_t *rtc = (rtc_t *) (CONFIG_SYS_MCFRTC_BASE);
+
+	if ((rtc->cr & RTC_CR_EN) == 0) {
+		printf("real-time-clock was stopped. Now starting...\n");
+		rtc->cr |= RTC_CR_EN;
+	}
+
+	rtc->cr |= RTC_CR_SWR;
+}
+
+#endif				/* CONFIG_MCFRTC && CONFIG_CMD_DATE */
diff --git a/marvell/uboot/drivers/rtc/mk48t59.c b/marvell/uboot/drivers/rtc/mk48t59.c
new file mode 100644
index 0000000..2164580
--- /dev/null
+++ b/marvell/uboot/drivers/rtc/mk48t59.c
@@ -0,0 +1,180 @@
+/*
+ * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Andreas Heppel <aheppel@sysgo.de>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+/*
+ * Date & Time support for the MK48T59 RTC
+ */
+
+#undef	RTC_DEBUG
+
+#include <common.h>
+#include <command.h>
+#include <config.h>
+#include <rtc.h>
+#include <mk48t59.h>
+
+#if defined(CONFIG_BAB7xx)
+
+static uchar rtc_read (short reg)
+{
+	out8(RTC_PORT_ADDR0, reg & 0xFF);
+	out8(RTC_PORT_ADDR1, (reg>>8) & 0xFF);
+	return in8(RTC_PORT_DATA);
+}
+
+static void rtc_write (short reg, uchar val)
+{
+	out8(RTC_PORT_ADDR0, reg & 0xFF);
+	out8(RTC_PORT_ADDR1, (reg>>8) & 0xFF);
+	out8(RTC_PORT_DATA, val);
+}
+
+#elif defined(CONFIG_EVAL5200)
+
+static uchar rtc_read (short reg)
+{
+	return in8(RTC(reg));
+}
+
+static void rtc_write (short reg, uchar val)
+{
+	out8(RTC(reg),val);
+}
+
+#else
+# error Board specific rtc access functions should be supplied
+#endif
+
+/* ------------------------------------------------------------------------- */
+
+void *nvram_read(void *dest, const short src, size_t count)
+{
+	uchar *d = (uchar *) dest;
+	short s = src;
+
+	while (count--)
+		*d++ = rtc_read(s++);
+
+	return dest;
+}
+
+void nvram_write(short dest, const void *src, size_t count)
+{
+	short d = dest;
+	uchar *s = (uchar *) src;
+
+	while (count--)
+		rtc_write(d++, *s++);
+}
+
+#if defined(CONFIG_CMD_DATE)
+
+/* ------------------------------------------------------------------------- */
+
+int rtc_get (struct rtc_time *tmp)
+{
+	uchar save_ctrl_a;
+	uchar sec, min, hour, mday, wday, mon, year;
+
+	/* Simple: freeze the clock, read it and allow updates again */
+	save_ctrl_a = rtc_read(RTC_CONTROLA);
+
+	/* Set the register to read the value. */
+	save_ctrl_a |= RTC_CA_READ;
+	rtc_write(RTC_CONTROLA, save_ctrl_a);
+
+	sec		= rtc_read (RTC_SECONDS);
+	min		= rtc_read (RTC_MINUTES);
+	hour	= rtc_read (RTC_HOURS);
+	mday	= rtc_read (RTC_DAY_OF_MONTH);
+	wday	= rtc_read (RTC_DAY_OF_WEEK);
+	mon		= rtc_read (RTC_MONTH);
+	year	= rtc_read (RTC_YEAR);
+
+	/* re-enable update */
+	save_ctrl_a &= ~RTC_CA_READ;
+	rtc_write(RTC_CONTROLA, save_ctrl_a);
+
+#ifdef RTC_DEBUG
+	printf ( "Get RTC year: %02x mon/cent: %02x mday: %02x wday: %02x "
+		"hr: %02x min: %02x sec: %02x\n",
+		year, mon, mday, wday,
+		hour, min, sec );
+#endif
+	tmp->tm_sec  = bcd2bin (sec  & 0x7F);
+	tmp->tm_min  = bcd2bin (min  & 0x7F);
+	tmp->tm_hour = bcd2bin (hour & 0x3F);
+	tmp->tm_mday = bcd2bin (mday & 0x3F);
+	tmp->tm_mon  = bcd2bin (mon & 0x1F);
+	tmp->tm_year = bcd2bin (year);
+	tmp->tm_wday = bcd2bin (wday & 0x07);
+	if(tmp->tm_year<70)
+		tmp->tm_year+=2000;
+	else
+		tmp->tm_year+=1900;
+	tmp->tm_yday = 0;
+	tmp->tm_isdst= 0;
+#ifdef RTC_DEBUG
+	printf ( "Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+#endif
+
+	return 0;
+}
+
+int rtc_set (struct rtc_time *tmp)
+{
+	uchar save_ctrl_a;
+
+#ifdef RTC_DEBUG
+	printf ( "Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+#endif
+	save_ctrl_a = rtc_read(RTC_CONTROLA);
+
+	save_ctrl_a |= RTC_CA_WRITE;
+	rtc_write(RTC_CONTROLA, save_ctrl_a); /* disables the RTC to update the regs */
+
+	rtc_write (RTC_YEAR, bin2bcd(tmp->tm_year % 100));
+	rtc_write (RTC_MONTH, bin2bcd(tmp->tm_mon));
+
+	rtc_write (RTC_DAY_OF_WEEK, bin2bcd(tmp->tm_wday));
+	rtc_write (RTC_DAY_OF_MONTH, bin2bcd(tmp->tm_mday));
+	rtc_write (RTC_HOURS, bin2bcd(tmp->tm_hour));
+	rtc_write (RTC_MINUTES, bin2bcd(tmp->tm_min ));
+	rtc_write (RTC_SECONDS, bin2bcd(tmp->tm_sec ));
+
+	save_ctrl_a &= ~RTC_CA_WRITE;
+	rtc_write(RTC_CONTROLA, save_ctrl_a); /* enables the RTC to update the regs */
+
+	return 0;
+}
+
+void rtc_reset (void)
+{
+	uchar control_b;
+
+	/*
+	 * Start oscillator here.
+	 */
+	control_b = rtc_read(RTC_CONTROLB);
+
+	control_b &= ~RTC_CB_STOP;
+	rtc_write(RTC_CONTROLB, control_b);
+}
+
+void rtc_set_watchdog(short multi, short res)
+{
+	uchar wd_value;
+
+	wd_value = RTC_WDS | ((multi & 0x1F) << 2) | (res & 0x3);
+	rtc_write(RTC_WATCHDOG, wd_value);
+}
+
+#endif
diff --git a/marvell/uboot/drivers/rtc/mpc5xxx.c b/marvell/uboot/drivers/rtc/mpc5xxx.c
new file mode 100644
index 0000000..929783e
--- /dev/null
+++ b/marvell/uboot/drivers/rtc/mpc5xxx.c
@@ -0,0 +1,128 @@
+/*
+ * (C) Copyright 2004
+ * Reinhard Meyer, EMK Elektronik GmbH
+ * r.meyer@emk-elektronik.de
+ * www.emk-elektronik.de
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+/*****************************************************************************
+ * Date & Time support for internal RTC of MPC52xx
+ *****************************************************************************/
+/*#define	DEBUG*/
+
+#include <common.h>
+#include <command.h>
+#include <rtc.h>
+
+#if defined(CONFIG_CMD_DATE)
+
+/*****************************************************************************
+ * this structure should be defined in mpc5200.h ...
+ *****************************************************************************/
+typedef struct rtc5200 {
+	volatile ulong	tsr;	/* MBAR+0x800: time set register */
+	volatile ulong	dsr;	/* MBAR+0x804: data set register */
+	volatile ulong	nysr;	/* MBAR+0x808: new year and stopwatch register */
+	volatile ulong	aier;	/* MBAR+0x80C: alarm and interrupt enable register */
+	volatile ulong	ctr;	/* MBAR+0x810: current time register */
+	volatile ulong	cdr;	/* MBAR+0x814: current data register */
+	volatile ulong	asir;	/* MBAR+0x818: alarm and stopwatch interrupt register */
+	volatile ulong	piber;	/* MBAR+0x81C: periodic interrupt and bus error register */
+	volatile ulong	trdr;	/* MBAR+0x820: test register/divides register */
+} RTC5200;
+
+#define	RTC_SET		0x02000000
+#define	RTC_PAUSE	0x01000000
+
+/*****************************************************************************
+ * get time
+ *****************************************************************************/
+int rtc_get (struct rtc_time *tmp)
+{
+	RTC5200	*rtc = (RTC5200 *) (CONFIG_SYS_MBAR+0x800);
+	ulong time, date, time2;
+
+	/* read twice to avoid getting a funny time when the second is just changing */
+	do {
+		time = rtc->ctr;
+		date = rtc->cdr;
+		time2 = rtc->ctr;
+	} while (time != time2);
+
+	tmp->tm_year	= date & 0xfff;
+	tmp->tm_mon		= (date >> 24) & 0xf;
+	tmp->tm_mday	= (date >> 16) & 0x1f;
+	tmp->tm_wday	= (date >> 21) & 7;
+	/* sunday is 7 in 5200 but 0 in rtc_time */
+	if (tmp->tm_wday == 7)
+		tmp->tm_wday = 0;
+	tmp->tm_hour	= (time >> 16) & 0x1f;
+	tmp->tm_min		= (time >> 8) & 0x3f;
+	tmp->tm_sec		= time & 0x3f;
+
+	debug ( "Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+	return 0;
+}
+
+/*****************************************************************************
+ * set time
+ *****************************************************************************/
+int rtc_set (struct rtc_time *tmp)
+{
+	RTC5200	*rtc = (RTC5200 *) (CONFIG_SYS_MBAR+0x800);
+	ulong time, date, year;
+
+	debug ( "Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+	time = (tmp->tm_hour << 16) | (tmp->tm_min << 8) | tmp->tm_sec;
+	date = (tmp->tm_mon << 16) | tmp->tm_mday;
+	if (tmp->tm_wday == 0)
+		date |= (7 << 8);
+	else
+		date |= (tmp->tm_wday << 8);
+	year = tmp->tm_year;
+
+	/* mask unwanted bits that might show up when rtc_time is corrupt */
+	time &= 0x001f3f3f;
+	date &= 0x001f071f;
+	year &= 0x00000fff;
+
+	/* pause and set the RTC */
+	rtc->nysr = year;
+	rtc->dsr = date | RTC_PAUSE;
+	udelay (1000);
+	rtc->dsr = date | RTC_PAUSE | RTC_SET;
+	udelay (1000);
+	rtc->dsr = date | RTC_PAUSE;
+	udelay (1000);
+	rtc->dsr = date;
+	udelay (1000);
+
+	rtc->tsr = time | RTC_PAUSE;
+	udelay (1000);
+	rtc->tsr = time | RTC_PAUSE | RTC_SET;
+	udelay (1000);
+	rtc->tsr = time | RTC_PAUSE;
+	udelay (1000);
+	rtc->tsr = time;
+	udelay (1000);
+
+	return 0;
+}
+
+/*****************************************************************************
+ * reset rtc circuit
+ *****************************************************************************/
+void rtc_reset (void)
+{
+	return;	/* nothing to do */
+}
+
+#endif
diff --git a/marvell/uboot/drivers/rtc/mpc8xx.c b/marvell/uboot/drivers/rtc/mpc8xx.c
new file mode 100644
index 0000000..d239dae
--- /dev/null
+++ b/marvell/uboot/drivers/rtc/mpc8xx.c
@@ -0,0 +1,61 @@
+/*
+ * (C) Copyright 2001
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+/*
+ * Date & Time support for internal RTC of MPC8xx
+ */
+
+/*#define	DEBUG*/
+
+#include <common.h>
+#include <command.h>
+#include <rtc.h>
+
+#if defined(CONFIG_CMD_DATE)
+
+/* ------------------------------------------------------------------------- */
+
+int rtc_get (struct rtc_time *tmp)
+{
+	volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
+	ulong tim;
+
+	tim = immr->im_sit.sit_rtc;
+
+	to_tm (tim, tmp);
+
+	debug ( "Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+	return 0;
+}
+
+int rtc_set (struct rtc_time *tmp)
+{
+	volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
+	ulong tim;
+
+	debug ( "Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+	tim = mktime (tmp->tm_year, tmp->tm_mon, tmp->tm_mday,
+		      tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+	immr->im_sitk.sitk_rtck = KAPWR_KEY;
+	immr->im_sit.sit_rtc = tim;
+
+	return 0;
+}
+
+void rtc_reset (void)
+{
+	return;	/* nothing to do */
+}
+
+#endif
diff --git a/marvell/uboot/drivers/rtc/mvrtc.c b/marvell/uboot/drivers/rtc/mvrtc.c
new file mode 100644
index 0000000..97dadd0
--- /dev/null
+++ b/marvell/uboot/drivers/rtc/mvrtc.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2011
+ * Jason Cooper <u-boot@lakedaemon.net>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+/*
+ * Date & Time support for Marvell Integrated RTC
+ */
+
+#include <common.h>
+#include <command.h>
+#include <rtc.h>
+#include <asm/io.h>
+#include "mvrtc.h"
+
+/* This RTC does not support century, so we assume 20 */
+#define CENTURY 20
+
+int rtc_get(struct rtc_time *t)
+{
+	u32 time;
+	u32 date;
+	struct mvrtc_registers *mvrtc_regs;
+
+	mvrtc_regs = (struct mvrtc_registers *)KW_RTC_BASE;
+
+	/* read the time register */
+	time = readl(&mvrtc_regs->time);
+
+	/* read the date register */
+	date = readl(&mvrtc_regs->date);
+
+	/* test for 12 hour clock (can't tell if it's am/pm) */
+	if (time & MVRTC_HRFMT_MSK) {
+		printf("Error: RTC in 12 hour mode, can't determine AM/PM.\n");
+		return -1;
+	}
+
+	/* time */
+	t->tm_sec  = bcd2bin((time >> MVRTC_SEC_SFT)  & MVRTC_SEC_MSK);
+	t->tm_min  = bcd2bin((time >> MVRTC_MIN_SFT)  & MVRTC_MIN_MSK);
+	t->tm_hour = bcd2bin((time >> MVRTC_HOUR_SFT) & MVRTC_HOUR_MSK);
+	t->tm_wday = bcd2bin((time >> MVRTC_DAY_SFT)  & MVRTC_DAY_MSK);
+	t->tm_wday--;
+
+	/* date */
+	t->tm_mday = bcd2bin((date >> MVRTC_DATE_SFT) & MVRTC_DATE_MSK);
+	t->tm_mon  = bcd2bin((date >> MVRTC_MON_SFT)  & MVRTC_MON_MSK);
+	t->tm_year = bcd2bin((date >> MVRTC_YEAR_SFT) & MVRTC_YEAR_MSK);
+	t->tm_year += CENTURY * 100;
+
+	/* not supported in this RTC */
+	t->tm_yday  = 0;
+	t->tm_isdst = 0;
+
+	return 0;
+}
+
+int rtc_set(struct rtc_time *t)
+{
+	u32 time = 0; /* sets hour format bit to zero, 24hr format. */
+	u32 date = 0;
+	struct mvrtc_registers *mvrtc_regs;
+
+	mvrtc_regs = (struct mvrtc_registers *)KW_RTC_BASE;
+
+	/* check that this code isn't 80+ years old ;-) */
+	if ((t->tm_year / 100) != CENTURY)
+		printf("Warning: Only century %d supported.\n", CENTURY);
+
+	/* time */
+	time |= (bin2bcd(t->tm_sec)      & MVRTC_SEC_MSK)  << MVRTC_SEC_SFT;
+	time |= (bin2bcd(t->tm_min)      & MVRTC_MIN_MSK)  << MVRTC_MIN_SFT;
+	time |= (bin2bcd(t->tm_hour)     & MVRTC_HOUR_MSK) << MVRTC_HOUR_SFT;
+	time |= (bin2bcd(t->tm_wday + 1) & MVRTC_DAY_MSK)  << MVRTC_DAY_SFT;
+
+	/* date */
+	date |= (bin2bcd(t->tm_mday)       & MVRTC_DATE_MSK) << MVRTC_DATE_SFT;
+	date |= (bin2bcd(t->tm_mon)        & MVRTC_MON_MSK)  << MVRTC_MON_SFT;
+	date |= (bin2bcd(t->tm_year % 100) & MVRTC_YEAR_MSK) << MVRTC_YEAR_SFT;
+
+	/* write the time register */
+	writel(time, &mvrtc_regs->time);
+
+	/* write the date register */
+	writel(date, &mvrtc_regs->date);
+
+	return 0;
+}
+
+void rtc_reset(void)
+{
+	u32 time;
+	u32 sec;
+	struct mvrtc_registers *mvrtc_regs;
+
+	mvrtc_regs = (struct mvrtc_registers *)KW_RTC_BASE;
+
+	/* no init routine for this RTC needed, just check that it's working */
+	time = readl(&mvrtc_regs->time);
+	sec  = bcd2bin((time >> MVRTC_SEC_SFT) & MVRTC_SEC_MSK);
+	udelay(1000000);
+	time = readl(&mvrtc_regs->time);
+
+	if (sec == bcd2bin((time >> MVRTC_SEC_SFT) & MVRTC_SEC_MSK))
+		printf("Error: RTC did not increment.\n");
+}
diff --git a/marvell/uboot/drivers/rtc/mvrtc.h b/marvell/uboot/drivers/rtc/mvrtc.h
new file mode 100644
index 0000000..ce7a69b
--- /dev/null
+++ b/marvell/uboot/drivers/rtc/mvrtc.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2011
+ * Jason Cooper <u-boot@lakedaemon.net>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+/*
+ * Date & Time support for Marvell Integrated RTC
+ */
+
+#ifndef _MVRTC_H_
+#define _MVRTC_H_
+
+#include <asm/arch/kirkwood.h>
+#include <compiler.h>
+
+/* RTC registers */
+struct mvrtc_registers {
+	u32 time;
+	u32 date;
+};
+
+/* time register */
+#define MVRTC_SEC_SFT		0
+#define MVRTC_SEC_MSK		0x7f
+#define MVRTC_MIN_SFT		8
+#define MVRTC_MIN_MSK		0x7f
+#define MVRTC_HOUR_SFT		16
+#define MVRTC_HOUR_MSK		0x3f
+#define MVRTC_DAY_SFT		24
+#define MVRTC_DAY_MSK		0x7
+
+/*
+ * Hour format bit
+ *   1 = 12 hour clock
+ *   0 = 24 hour clock
+ */
+#define MVRTC_HRFMT_MSK		0x00400000
+
+/* date register */
+#define MVRTC_DATE_SFT		0
+#define MVRTC_DATE_MSK		0x3f
+#define MVRTC_MON_SFT		8
+#define MVRTC_MON_MSK		0x1f
+#define MVRTC_YEAR_SFT		16
+#define MVRTC_YEAR_MSK		0xff
+
+#endif
diff --git a/marvell/uboot/drivers/rtc/mx27rtc.c b/marvell/uboot/drivers/rtc/mx27rtc.c
new file mode 100644
index 0000000..ae6595b
--- /dev/null
+++ b/marvell/uboot/drivers/rtc/mx27rtc.c
@@ -0,0 +1,70 @@
+/*
+ * Freescale i.MX27 RTC Driver
+ *
+ * Copyright (C) 2012 Philippe Reynes <tremyfr@yahoo.fr>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <rtc.h>
+#include <asm/io.h>
+#include <asm/arch/imx-regs.h>
+
+#define HOUR_SHIFT 8
+#define HOUR_MASK  0x1f
+#define MIN_SHIFT  0
+#define MIN_MASK   0x3f
+
+int rtc_get(struct rtc_time *time)
+{
+	struct rtc_regs *rtc_regs = (struct rtc_regs *)IMX_RTC_BASE;
+	uint32_t day, hour, min, sec;
+
+	day  = readl(&rtc_regs->dayr);
+	hour = readl(&rtc_regs->hourmin);
+	sec  = readl(&rtc_regs->seconds);
+
+	min  = (hour >> MIN_SHIFT) & MIN_MASK;
+	hour = (hour >> HOUR_SHIFT) & HOUR_MASK;
+
+	sec += min * 60 + hour * 3600 + day * 24 * 3600;
+
+	to_tm(sec, time);
+
+	return 0;
+}
+
+int rtc_set(struct rtc_time *time)
+{
+	struct rtc_regs *rtc_regs = (struct rtc_regs *)IMX_RTC_BASE;
+	uint32_t day, hour, min, sec;
+
+	sec = mktime(time->tm_year, time->tm_mon, time->tm_mday,
+		time->tm_hour, time->tm_min, time->tm_sec);
+
+	day  = sec / (24 * 3600);
+	sec  = sec % (24 * 3600);
+	hour = sec / 3600;
+	sec  = sec % 3600;
+	min  = sec / 60;
+	sec  = sec % 60;
+
+	hour  = (hour & HOUR_MASK) << HOUR_SHIFT;
+	hour |= (min & MIN_MASK) << MIN_SHIFT;
+
+	writel(day, &rtc_regs->dayr);
+	writel(hour, &rtc_regs->hourmin);
+	writel(sec, &rtc_regs->seconds);
+
+	return 0;
+}
+
+void rtc_reset(void)
+{
+	struct rtc_regs *rtc_regs = (struct rtc_regs *)IMX_RTC_BASE;
+
+	writel(0, &rtc_regs->dayr);
+	writel(0, &rtc_regs->hourmin);
+	writel(0, &rtc_regs->seconds);
+}
diff --git a/marvell/uboot/drivers/rtc/mxsrtc.c b/marvell/uboot/drivers/rtc/mxsrtc.c
new file mode 100644
index 0000000..32ba8a3
--- /dev/null
+++ b/marvell/uboot/drivers/rtc/mxsrtc.c
@@ -0,0 +1,73 @@
+/*
+ * Freescale i.MX28 RTC Driver
+ *
+ * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
+ * on behalf of DENX Software Engineering GmbH
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <rtc.h>
+#include <asm/io.h>
+#include <asm/arch/imx-regs.h>
+#include <asm/arch/sys_proto.h>
+
+#define	MXS_RTC_MAX_TIMEOUT	1000000
+
+/* Set time in seconds since 1970-01-01 */
+int mxs_rtc_set_time(uint32_t secs)
+{
+	struct mxs_rtc_regs *rtc_regs = (struct mxs_rtc_regs *)MXS_RTC_BASE;
+	int ret;
+
+	writel(secs, &rtc_regs->hw_rtc_seconds);
+
+	/*
+	 * The 0x80 here means seconds were copied to analog. This information
+	 * is taken from the linux kernel driver for the STMP37xx RTC since
+	 * documentation doesn't mention it.
+	 */
+	ret = mxs_wait_mask_clr(&rtc_regs->hw_rtc_stat_reg,
+		0x80 << RTC_STAT_STALE_REGS_OFFSET, MXS_RTC_MAX_TIMEOUT);
+
+	if (ret)
+		printf("MXS RTC: Timeout waiting for update\n");
+
+	return ret;
+}
+
+int rtc_get(struct rtc_time *time)
+{
+	struct mxs_rtc_regs *rtc_regs = (struct mxs_rtc_regs *)MXS_RTC_BASE;
+	uint32_t secs;
+
+	secs = readl(&rtc_regs->hw_rtc_seconds);
+	to_tm(secs, time);
+
+	return 0;
+}
+
+int rtc_set(struct rtc_time *time)
+{
+	uint32_t secs;
+
+	secs = mktime(time->tm_year, time->tm_mon, time->tm_mday,
+		time->tm_hour, time->tm_min, time->tm_sec);
+
+	return mxs_rtc_set_time(secs);
+}
+
+void rtc_reset(void)
+{
+	struct mxs_rtc_regs *rtc_regs = (struct mxs_rtc_regs *)MXS_RTC_BASE;
+	int ret;
+
+	/* Set time to 1970-01-01 */
+	mxs_rtc_set_time(0);
+
+	/* Reset the RTC block */
+	ret = mxs_reset_block(&rtc_regs->hw_rtc_ctrl_reg);
+	if (ret)
+		printf("MXS RTC: Block reset timeout\n");
+}
diff --git a/marvell/uboot/drivers/rtc/pcf8563.c b/marvell/uboot/drivers/rtc/pcf8563.c
new file mode 100644
index 0000000..25fa7c5
--- /dev/null
+++ b/marvell/uboot/drivers/rtc/pcf8563.c
@@ -0,0 +1,122 @@
+/*
+ * (C) Copyright 2001
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+/*
+ * Date & Time support for Philips PCF8563 RTC
+ */
+
+/* #define	DEBUG	*/
+
+#include <common.h>
+#include <command.h>
+#include <rtc.h>
+#include <i2c.h>
+
+#if defined(CONFIG_CMD_DATE)
+
+static uchar rtc_read  (uchar reg);
+static void  rtc_write (uchar reg, uchar val);
+
+/* ------------------------------------------------------------------------- */
+
+int rtc_get (struct rtc_time *tmp)
+{
+	int rel = 0;
+	uchar sec, min, hour, mday, wday, mon_cent, year;
+
+	sec	= rtc_read (0x02);
+	min	= rtc_read (0x03);
+	hour	= rtc_read (0x04);
+	mday	= rtc_read (0x05);
+	wday	= rtc_read (0x06);
+	mon_cent= rtc_read (0x07);
+	year	= rtc_read (0x08);
+
+	debug ( "Get RTC year: %02x mon/cent: %02x mday: %02x wday: %02x "
+		"hr: %02x min: %02x sec: %02x\n",
+		year, mon_cent, mday, wday,
+		hour, min, sec );
+	debug ( "Alarms: wday: %02x day: %02x hour: %02x min: %02x\n",
+		rtc_read (0x0C),
+		rtc_read (0x0B),
+		rtc_read (0x0A),
+		rtc_read (0x09) );
+
+	if (sec & 0x80) {
+		puts ("### Warning: RTC Low Voltage - date/time not reliable\n");
+		rel = -1;
+	}
+
+	tmp->tm_sec  = bcd2bin (sec  & 0x7F);
+	tmp->tm_min  = bcd2bin (min  & 0x7F);
+	tmp->tm_hour = bcd2bin (hour & 0x3F);
+	tmp->tm_mday = bcd2bin (mday & 0x3F);
+	tmp->tm_mon  = bcd2bin (mon_cent & 0x1F);
+	tmp->tm_year = bcd2bin (year) + ((mon_cent & 0x80) ? 1900 : 2000);
+	tmp->tm_wday = bcd2bin (wday & 0x07);
+	tmp->tm_yday = 0;
+	tmp->tm_isdst= 0;
+
+	debug ( "Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+	return rel;
+}
+
+int rtc_set (struct rtc_time *tmp)
+{
+	uchar century;
+
+	debug ( "Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+	rtc_write (0x08, bin2bcd(tmp->tm_year % 100));
+
+	century = (tmp->tm_year >= 2000) ? 0 : 0x80;
+	rtc_write (0x07, bin2bcd(tmp->tm_mon) | century);
+
+	rtc_write (0x06, bin2bcd(tmp->tm_wday));
+	rtc_write (0x05, bin2bcd(tmp->tm_mday));
+	rtc_write (0x04, bin2bcd(tmp->tm_hour));
+	rtc_write (0x03, bin2bcd(tmp->tm_min ));
+	rtc_write (0x02, bin2bcd(tmp->tm_sec ));
+
+	return 0;
+}
+
+void rtc_reset (void)
+{
+	/* clear all control & status registers */
+	rtc_write (0x00, 0x00);
+	rtc_write (0x01, 0x00);
+	rtc_write (0x0D, 0x00);
+
+	/* clear Voltage Low bit */
+	rtc_write (0x02, rtc_read (0x02) & 0x7F);
+
+	/* reset all alarms */
+	rtc_write (0x09, 0x00);
+	rtc_write (0x0A, 0x00);
+	rtc_write (0x0B, 0x00);
+	rtc_write (0x0C, 0x00);
+}
+
+/* ------------------------------------------------------------------------- */
+
+static uchar rtc_read (uchar reg)
+{
+	return (i2c_reg_read (CONFIG_SYS_I2C_RTC_ADDR, reg));
+}
+
+static void rtc_write (uchar reg, uchar val)
+{
+	i2c_reg_write (CONFIG_SYS_I2C_RTC_ADDR, reg, val);
+}
+
+#endif
diff --git a/marvell/uboot/drivers/rtc/pl031.c b/marvell/uboot/drivers/rtc/pl031.c
new file mode 100644
index 0000000..c4d1259
--- /dev/null
+++ b/marvell/uboot/drivers/rtc/pl031.c
@@ -0,0 +1,109 @@
+/*
+ * (C) Copyright 2008
+ * Gururaja Hebbar gururajakr@sanyo.co.in
+ *
+ * reference linux-2.6.20.6/drivers/rtc/rtc-pl031.c
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <command.h>
+#include <rtc.h>
+
+#if defined(CONFIG_CMD_DATE)
+
+#ifndef CONFIG_SYS_RTC_PL031_BASE
+#error CONFIG_SYS_RTC_PL031_BASE is not defined!
+#endif
+
+/*
+ * Register definitions
+ */
+#define	RTC_DR		0x00	/* Data read register */
+#define	RTC_MR		0x04	/* Match register */
+#define	RTC_LR		0x08	/* Data load register */
+#define	RTC_CR		0x0c	/* Control register */
+#define	RTC_IMSC	0x10	/* Interrupt mask and set register */
+#define	RTC_RIS		0x14	/* Raw interrupt status register */
+#define	RTC_MIS		0x18	/* Masked interrupt status register */
+#define	RTC_ICR		0x1c	/* Interrupt clear register */
+
+#define RTC_CR_START	(1 << 0)
+
+#define	RTC_WRITE_REG(addr, val) \
+			(*(volatile unsigned int *)(CONFIG_SYS_RTC_PL031_BASE + (addr)) = (val))
+#define	RTC_READ_REG(addr)	\
+			(*(volatile unsigned int *)(CONFIG_SYS_RTC_PL031_BASE + (addr)))
+
+static int pl031_initted = 0;
+
+/* Enable RTC Start in Control register*/
+void rtc_init(void)
+{
+	RTC_WRITE_REG(RTC_CR, RTC_CR_START);
+
+	pl031_initted = 1;
+}
+
+/*
+ * Reset the RTC. We set the date back to 1970-01-01.
+ */
+void rtc_reset(void)
+{
+	RTC_WRITE_REG(RTC_LR, 0x00);
+	if(!pl031_initted)
+		rtc_init();
+}
+
+/*
+ * Set the RTC
+*/
+int rtc_set(struct rtc_time *tmp)
+{
+	unsigned long tim;
+
+	if(!pl031_initted)
+		rtc_init();
+
+	if (tmp == NULL) {
+		puts("Error setting the date/time\n");
+		return -1;
+	}
+
+	/* Calculate number of seconds this incoming time represents */
+	tim = mktime(tmp->tm_year, tmp->tm_mon, tmp->tm_mday,
+			tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+	RTC_WRITE_REG(RTC_LR, tim);
+
+	return -1;
+}
+
+/*
+ * Get the current time from the RTC
+ */
+int rtc_get(struct rtc_time *tmp)
+{
+	ulong tim;
+
+	if(!pl031_initted)
+		rtc_init();
+
+	if (tmp == NULL) {
+		puts("Error getting the date/time\n");
+		return -1;
+	}
+
+	tim = RTC_READ_REG(RTC_DR);
+
+	to_tm (tim, tmp);
+
+	debug ( "Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+	return 0;
+}
+
+#endif
diff --git a/marvell/uboot/drivers/rtc/pt7c4338.c b/marvell/uboot/drivers/rtc/pt7c4338.c
new file mode 100644
index 0000000..b1eb7d8
--- /dev/null
+++ b/marvell/uboot/drivers/rtc/pt7c4338.c
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2010 Freescale Semiconductor, Inc.
+ *
+ * Author:	Priyanka Jain <Priyanka.Jain@freescale.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+/*
+ * This file provides Date & Time support (no alarms) for PT7C4338 chip.
+ *
+ * This file is based on drivers/rtc/ds1337.c
+ *
+ * PT7C4338 chip is manufactured by Pericom Technology Inc.
+ * It is a serial real-time clock which provides
+ * 1)Low-power clock/calendar.
+ * 2)Programmable square-wave output.
+ * It has 56 bytes of nonvolatile RAM.
+ */
+
+#include <common.h>
+#include <command.h>
+#include <rtc.h>
+#include <i2c.h>
+
+/* RTC register addresses */
+#define RTC_SEC_REG_ADDR        0x0
+#define RTC_MIN_REG_ADDR        0x1
+#define RTC_HR_REG_ADDR         0x2
+#define RTC_DAY_REG_ADDR        0x3
+#define RTC_DATE_REG_ADDR       0x4
+#define RTC_MON_REG_ADDR        0x5
+#define RTC_YR_REG_ADDR         0x6
+#define RTC_CTL_STAT_REG_ADDR   0x7
+
+/* RTC second register address bit */
+#define RTC_SEC_BIT_CH		0x80	/* Clock Halt (in Register 0) */
+
+/* RTC control and status register bits */
+#define RTC_CTL_STAT_BIT_RS0    0x1	/* Rate select 0 */
+#define RTC_CTL_STAT_BIT_RS1    0x2	/* Rate select 1 */
+#define RTC_CTL_STAT_BIT_SQWE   0x10	/* Square Wave Enable */
+#define RTC_CTL_STAT_BIT_OSF    0x20	/* Oscillator Stop Flag */
+#define RTC_CTL_STAT_BIT_OUT    0x80	/* Output Level Control */
+
+/* RTC reset value */
+#define RTC_PT7C4338_RESET_VAL \
+	(RTC_CTL_STAT_BIT_RS0 | RTC_CTL_STAT_BIT_RS1 | RTC_CTL_STAT_BIT_OUT)
+
+/****** Helper functions ****************************************/
+static u8 rtc_read(u8 reg)
+{
+	return i2c_reg_read(CONFIG_SYS_I2C_RTC_ADDR, reg);
+}
+
+static void rtc_write(u8 reg, u8 val)
+{
+	i2c_reg_write(CONFIG_SYS_I2C_RTC_ADDR, reg, val);
+}
+/****************************************************************/
+
+/* Get the current time from the RTC */
+int rtc_get(struct rtc_time *tmp)
+{
+	int ret = 0;
+	u8 sec, min, hour, mday, wday, mon, year, ctl_stat;
+
+	ctl_stat = rtc_read(RTC_CTL_STAT_REG_ADDR);
+	sec = rtc_read(RTC_SEC_REG_ADDR);
+	min = rtc_read(RTC_MIN_REG_ADDR);
+	hour = rtc_read(RTC_HR_REG_ADDR);
+	wday = rtc_read(RTC_DAY_REG_ADDR);
+	mday = rtc_read(RTC_DATE_REG_ADDR);
+	mon = rtc_read(RTC_MON_REG_ADDR);
+	year = rtc_read(RTC_YR_REG_ADDR);
+	debug("Get RTC year: %02x mon: %02x mday: %02x wday: %02x "
+		"hr: %02x min: %02x sec: %02x control_status: %02x\n",
+		year, mon, mday, wday, hour, min, sec, ctl_stat);
+
+	if (ctl_stat & RTC_CTL_STAT_BIT_OSF) {
+		printf("### Warning: RTC oscillator has stopped\n");
+		/* clear the OSF flag */
+		rtc_write(RTC_CTL_STAT_REG_ADDR,
+			rtc_read(RTC_CTL_STAT_REG_ADDR)\
+			& ~RTC_CTL_STAT_BIT_OSF);
+		ret = -1;
+	}
+
+	tmp->tm_sec = bcd2bin(sec & 0x7F);
+	tmp->tm_min = bcd2bin(min & 0x7F);
+	tmp->tm_hour = bcd2bin(hour & 0x3F);
+	tmp->tm_mday = bcd2bin(mday & 0x3F);
+	tmp->tm_mon = bcd2bin(mon & 0x1F);
+	tmp->tm_year = bcd2bin(year) + 2000;
+	tmp->tm_wday = bcd2bin((wday - 1) & 0x07);
+	tmp->tm_yday = 0;
+	tmp->tm_isdst = 0;
+	debug("Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+	return ret;
+}
+
+/* Set the RTC */
+int rtc_set(struct rtc_time *tmp)
+{
+	debug("Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+	rtc_write(RTC_YR_REG_ADDR, bin2bcd(tmp->tm_year % 100));
+	rtc_write(RTC_MON_REG_ADDR, bin2bcd(tmp->tm_mon));
+	rtc_write(RTC_DAY_REG_ADDR, bin2bcd(tmp->tm_wday + 1));
+	rtc_write(RTC_DATE_REG_ADDR, bin2bcd(tmp->tm_mday));
+	rtc_write(RTC_HR_REG_ADDR, bin2bcd(tmp->tm_hour));
+	rtc_write(RTC_MIN_REG_ADDR, bin2bcd(tmp->tm_min));
+	rtc_write(RTC_SEC_REG_ADDR, bin2bcd(tmp->tm_sec));
+
+	return 0;
+}
+
+/* Reset the RTC */
+void rtc_reset(void)
+{
+	rtc_write(RTC_SEC_REG_ADDR, 0x00);	/* clearing Clock Halt	*/
+	rtc_write(RTC_CTL_STAT_REG_ADDR, RTC_PT7C4338_RESET_VAL);
+}
diff --git a/marvell/uboot/drivers/rtc/rs5c372.c b/marvell/uboot/drivers/rtc/rs5c372.c
new file mode 100644
index 0000000..65f45ea
--- /dev/null
+++ b/marvell/uboot/drivers/rtc/rs5c372.c
@@ -0,0 +1,281 @@
+/*
+ * rs5c372.c
+ *
+ * Device driver for Ricoh's Real Time Controller RS5C372A.
+ *
+ * Copyright (C) 2004 Gary Jennejohn garyj@denx.de
+ *
+ * Based in part in ds1307.c -
+ * (C) Copyright 2001, 2002, 2003
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ * Keith Outwater, keith_outwater@mvis.com`
+ * Steven Scholz, steven.scholz@imc-berlin.de
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <common.h>
+#include <command.h>
+#include <rtc.h>
+#include <i2c.h>
+
+#if defined(CONFIG_CMD_DATE)
+/*
+ * Reads are always done starting with register 15, which requires some
+ * jumping-through-hoops to access the data correctly.
+ *
+ * Writes are always done starting with register 0.
+ */
+
+#define DEBUG 0
+
+#if DEBUG
+static unsigned int rtc_debug = DEBUG;
+#else
+#define rtc_debug 0	/* gcc will remove all the debug code for us */
+#endif
+
+#ifndef CONFIG_SYS_I2C_RTC_ADDR
+#define CONFIG_SYS_I2C_RTC_ADDR 0x32
+#endif
+
+#define RS5C372_RAM_SIZE 0x10
+#define RATE_32000HZ	0x80	/* Rate Select 32.000KHz */
+#define RATE_32768HZ	0x00	/* Rate Select 32.768KHz */
+
+#define STATUS_XPT  0x10    /* data invalid because voltage was 0 */
+
+#define USE_24HOUR_MODE 0x20
+#define TWELVE_HOUR_MODE(n) ((((n) >> 5) & 1) == 0)
+#define HOURS_AP(n)	(((n) >> 5) & 1)
+#define HOURS_12(n)	bcd2bin((n) & 0x1F)
+#define HOURS_24(n)	bcd2bin((n) & 0x3F)
+
+
+static int setup_done = 0;
+
+static int
+rs5c372_readram(unsigned char *buf, int len)
+{
+	int ret;
+
+	ret = i2c_read(CONFIG_SYS_I2C_RTC_ADDR, 0, 0, buf, len);
+	if (ret != 0) {
+		printf("%s: failed to read\n", __FUNCTION__);
+		return ret;
+	}
+
+	if (buf[0] & STATUS_XPT)
+		printf("### Warning: RTC lost power\n");
+
+	return ret;
+}
+
+static void
+rs5c372_enable(void)
+{
+	unsigned char buf[RS5C372_RAM_SIZE + 1];
+	int ret;
+
+	/* note that this returns reg. 15 in buf[1] */
+	ret = rs5c372_readram(&buf[1], RS5C372_RAM_SIZE);
+	if (ret != 0) {
+		printf("%s: failed\n", __FUNCTION__);
+		return;
+	}
+
+	buf[0] = 0;
+	/* we want to start writing at register 0 so we have to copy the */
+	/* register contents up one slot */
+	for (ret = 2; ret < 9; ret++)
+		buf[ret - 1] = buf[ret];
+	/* registers 0 to 6 (time values) are not touched */
+	buf[8] = RATE_32768HZ; /* reg. 7 */
+	buf[9] = 0; /* reg. 8 */
+	buf[10] = 0; /* reg. 9 */
+	buf[11] = 0; /* reg. 10 */
+	buf[12] = 0; /* reg. 11 */
+	buf[13] = 0; /* reg. 12 */
+	buf[14] = 0; /* reg. 13 */
+	buf[15] = 0; /* reg. 14 */
+	buf[16] = USE_24HOUR_MODE; /* reg. 15 */
+	ret = i2c_write(CONFIG_SYS_I2C_RTC_ADDR, 0, 0, buf, RS5C372_RAM_SIZE+1);
+	if (ret != 0) {
+		printf("%s: failed\n", __FUNCTION__);
+		return;
+	}
+	setup_done = 1;
+
+	return;
+}
+
+static void
+rs5c372_convert_to_time(struct rtc_time *dt, unsigned char *buf)
+{
+	/* buf[0] is register 15 */
+	dt->tm_sec = bcd2bin(buf[1]);
+	dt->tm_min = bcd2bin(buf[2]);
+
+	if (TWELVE_HOUR_MODE(buf[0])) {
+		dt->tm_hour = HOURS_12(buf[3]);
+		if (HOURS_AP(buf[3])) /* PM */
+			dt->tm_hour += 12;
+	} else /* 24-hour-mode */
+		dt->tm_hour = HOURS_24(buf[3]);
+
+	dt->tm_mday = bcd2bin(buf[5]);
+	dt->tm_mon = bcd2bin(buf[6]);
+	dt->tm_year = bcd2bin(buf[7]);
+	if (dt->tm_year >= 70)
+		dt->tm_year += 1900;
+	else
+		dt->tm_year += 2000;
+	/* 0 is Sunday */
+	dt->tm_wday = bcd2bin(buf[4] & 0x07);
+	dt->tm_yday = 0;
+	dt->tm_isdst= 0;
+
+	if(rtc_debug > 2) {
+		printf("rs5c372_convert_to_time: year = %d\n", dt->tm_year);
+		printf("rs5c372_convert_to_time: mon  = %d\n", dt->tm_mon);
+		printf("rs5c372_convert_to_time: mday = %d\n", dt->tm_mday);
+		printf("rs5c372_convert_to_time: hour = %d\n", dt->tm_hour);
+		printf("rs5c372_convert_to_time: min  = %d\n", dt->tm_min);
+		printf("rs5c372_convert_to_time: sec  = %d\n", dt->tm_sec);
+	}
+}
+
+/*
+ * Get the current time from the RTC
+ */
+int
+rtc_get (struct rtc_time *tmp)
+{
+	unsigned char buf[RS5C372_RAM_SIZE];
+	int ret;
+
+	if (!setup_done)
+		rs5c372_enable();
+
+	if (!setup_done)
+		return -1;
+
+	memset(buf, 0, sizeof(buf));
+
+	/* note that this returns reg. 15 in buf[0] */
+	ret = rs5c372_readram(buf, RS5C372_RAM_SIZE);
+	if (ret != 0) {
+		printf("%s: failed\n", __FUNCTION__);
+		return -1;
+	}
+
+	rs5c372_convert_to_time(tmp, buf);
+
+	return 0;
+}
+
+/*
+ * Set the RTC
+ */
+int rtc_set (struct rtc_time *tmp)
+{
+	unsigned char buf[8], reg15;
+	int ret;
+
+	if (!setup_done)
+		rs5c372_enable();
+
+	if (!setup_done)
+		return -1;
+
+	if(rtc_debug > 2) {
+		printf("rtc_set: tm_year = %d\n", tmp->tm_year);
+		printf("rtc_set: tm_mon	 = %d\n", tmp->tm_mon);
+		printf("rtc_set: tm_mday = %d\n", tmp->tm_mday);
+		printf("rtc_set: tm_hour = %d\n", tmp->tm_hour);
+		printf("rtc_set: tm_min	 = %d\n", tmp->tm_min);
+		printf("rtc_set: tm_sec	 = %d\n", tmp->tm_sec);
+	}
+
+	memset(buf, 0, sizeof(buf));
+
+	/* only read register 15 */
+	ret = i2c_read(CONFIG_SYS_I2C_RTC_ADDR, 0, 0, buf, 1);
+
+	if (ret == 0) {
+		/* need to save register 15 */
+		reg15 = buf[0];
+		buf[0] = 0;	/* register address on RS5C372 */
+		buf[1] = bin2bcd(tmp->tm_sec);
+		buf[2] = bin2bcd(tmp->tm_min);
+		/* need to handle 12 hour mode */
+		if (TWELVE_HOUR_MODE(reg15)) {
+			if (tmp->tm_hour >= 12) { /* PM */
+				/* 12 PM is a special case */
+				if (tmp->tm_hour == 12)
+					buf[3] = bin2bcd(tmp->tm_hour);
+				else
+					buf[3] = bin2bcd(tmp->tm_hour - 12);
+				buf[3] |= 0x20;
+			}
+		} else {
+			buf[3] = bin2bcd(tmp->tm_hour);
+		}
+
+		buf[4] = bin2bcd(tmp->tm_wday);
+		buf[5] = bin2bcd(tmp->tm_mday);
+		buf[6] = bin2bcd(tmp->tm_mon);
+		if (tmp->tm_year < 1970 || tmp->tm_year > 2069)
+			printf("WARNING: year should be between 1970 and 2069!\n");
+		buf[7] = bin2bcd(tmp->tm_year % 100);
+
+		ret = i2c_write(CONFIG_SYS_I2C_RTC_ADDR, 0, 0, buf, 8);
+		if (ret != 0) {
+			printf("rs5c372_set_datetime(), i2c_master_send() returned %d\n",ret);
+			return -1;
+		}
+	} else {
+		return -1;
+	}
+
+	return 0;
+}
+
+/*
+ * Reset the RTC. We set the date back to 1970-01-01.
+ */
+void
+rtc_reset (void)
+{
+	struct rtc_time tmp;
+
+	if (!setup_done)
+		rs5c372_enable();
+
+	if (!setup_done)
+		return;
+
+	tmp.tm_year = 1970;
+	tmp.tm_mon = 1;
+	/* Jan. 1, 1970 was a Thursday */
+	tmp.tm_wday= 4;
+	tmp.tm_mday= 1;
+	tmp.tm_hour = 0;
+	tmp.tm_min = 0;
+	tmp.tm_sec = 0;
+
+	rtc_set(&tmp);
+
+	printf ("RTC:	%4d-%02d-%02d %2d:%02d:%02d UTC\n",
+		tmp.tm_year, tmp.tm_mon, tmp.tm_mday,
+		tmp.tm_hour, tmp.tm_min, tmp.tm_sec);
+
+	return;
+}
+
+#endif
diff --git a/marvell/uboot/drivers/rtc/rtc4543.c b/marvell/uboot/drivers/rtc/rtc4543.c
new file mode 100644
index 0000000..8d36edd
--- /dev/null
+++ b/marvell/uboot/drivers/rtc/rtc4543.c
@@ -0,0 +1,101 @@
+/*
+ * (C) Copyright 2008, 2009
+ * Andreas Pfefferle, DENX Software Engineering, ap@denx.de.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <asm/io.h>
+#include <common.h>
+#include <command.h>
+#include <config.h>
+#include <rtc.h>
+#include <tws.h>
+
+#if defined(CONFIG_CMD_DATE)
+
+/*
+ * Note: The acrobatics below is due to the hideously ingenius idea of
+ * the chip designers.  As the chip does not allow register
+ * addressing, all values need to be read and written in one go.  Sure
+ * enough, the 'wday' field (0-6) is transferred using the economic
+ * number of 4 bits right in the middle of the packet.....
+ */
+
+int rtc_get(struct rtc_time *tm)
+{
+	int rel = 0;
+	uchar buffer[7];
+
+	memset(buffer, 0, 7);
+
+	/* Read 52 bits into our buffer */
+	tws_read(buffer, 52);
+
+	tm->tm_sec  = bcd2bin( buffer[0] & 0x7F);
+	tm->tm_min  = bcd2bin( buffer[1] & 0x7F);
+	tm->tm_hour = bcd2bin( buffer[2] & 0x3F);
+	tm->tm_wday = bcd2bin( buffer[3] & 0x07);
+	tm->tm_mday = bcd2bin((buffer[3] & 0xF0) >> 4 | (buffer[4] & 0x0F) << 4);
+	tm->tm_mon  = bcd2bin((buffer[4] & 0x30) >> 4 | (buffer[5] & 0x0F) << 4);
+	tm->tm_year = bcd2bin((buffer[5] & 0xF0) >> 4 | (buffer[6] & 0x0F) << 4) + 2000;
+	tm->tm_yday = 0;
+	tm->tm_isdst = 0;
+
+	if (tm->tm_sec & 0x80) {
+		puts("### Warning: RTC Low Voltage - date/time not reliable\n");
+		rel = -1;
+	}
+
+	debug("Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_wday,
+		tm->tm_hour, tm->tm_min, tm->tm_sec);
+
+	return rel;
+}
+
+int rtc_set(struct rtc_time *tm)
+{
+	uchar buffer[7];
+	uchar tmp;
+
+	debug("Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_wday,
+		tm->tm_hour, tm->tm_min, tm->tm_sec);
+
+	memset(buffer, 0, 7);
+	buffer[0] = bin2bcd(tm->tm_sec);
+	buffer[1] = bin2bcd(tm->tm_min);
+	buffer[2] = bin2bcd(tm->tm_hour);
+	buffer[3] = bin2bcd(tm->tm_wday);
+	tmp = bin2bcd(tm->tm_mday);
+	buffer[3] |= (tmp & 0x0F) << 4;
+	buffer[4] =  (tmp & 0xF0) >> 4;
+	tmp = bin2bcd(tm->tm_mon);
+	buffer[4] |= (tmp & 0x0F) << 4;
+	buffer[5] =  (tmp & 0xF0) >> 4;
+	tmp = bin2bcd(tm->tm_year  % 100);
+	buffer[5] |= (tmp & 0x0F) << 4;
+	buffer[6] =  (tmp & 0xF0) >> 4;
+
+	/* Write the resulting 52 bits to device */
+	tws_write(buffer, 52);
+
+	return 0;
+}
+
+void rtc_reset(void)
+{
+	struct rtc_time tmp;
+
+	tmp.tm_sec = 0;
+	tmp.tm_min = 0;
+	tmp.tm_hour = 0;
+	tmp.tm_wday = 4;
+	tmp.tm_mday = 1;
+	tmp.tm_mon = 1;
+	tmp.tm_year = 2000;
+	rtc_set(&tmp);
+}
+
+#endif
diff --git a/marvell/uboot/drivers/rtc/rv3029.c b/marvell/uboot/drivers/rtc/rv3029.c
new file mode 100644
index 0000000..f08040a
--- /dev/null
+++ b/marvell/uboot/drivers/rtc/rv3029.c
@@ -0,0 +1,190 @@
+/*
+ * (C) Copyright 2010
+ * Heiko Schocher, DENX Software Engineering, hs@denx.de
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#include <common.h>
+#include <command.h>
+#include <i2c.h>
+#include <rtc.h>
+
+#define RTC_RV3029_CTRL1	0x00
+#define RTC_RV3029_CTRL1_EERE	(1 << 3)
+
+#define RTC_RV3029_CTRL_STATUS	0x03
+#define RTC_RV3029_CTRLS_EEBUSY	(1 << 7)
+
+#define RTC_RV3029_CTRL_RESET	0x04
+#define RTC_RV3029_CTRL_SYS_R	(1 << 4)
+
+#define RTC_RV3029_CLOCK_PAGE	0x08
+#define RTC_RV3029_PAGE_LEN	7
+
+#define RV3029C2_W_SECONDS	0x00
+#define RV3029C2_W_MINUTES	0x01
+#define RV3029C2_W_HOURS	0x02
+#define RV3029C2_W_DATE		0x03
+#define RV3029C2_W_DAYS		0x04
+#define RV3029C2_W_MONTHS	0x05
+#define RV3029C2_W_YEARS	0x06
+
+#define RV3029C2_REG_HR_12_24          (1 << 6)  /* 24h/12h mode */
+#define RV3029C2_REG_HR_PM             (1 << 5)  /* PM/AM bit in 12h mode */
+
+#define RTC_RV3029_EEPROM_CTRL	0x30
+#define RTC_RV3029_TRICKLE_1K	(1 << 4)
+#define RTC_RV3029_TRICKLE_5K	(1 << 5)
+#define RTC_RV3029_TRICKLE_20K	(1 << 6)
+#define RTC_RV3029_TRICKLE_80K	(1 << 7)
+
+int rtc_get( struct rtc_time *tmp )
+{
+	int	ret;
+	unsigned char buf[RTC_RV3029_PAGE_LEN];
+
+	ret = i2c_read(CONFIG_SYS_I2C_RTC_ADDR, RTC_RV3029_CLOCK_PAGE, 1, buf, \
+			RTC_RV3029_PAGE_LEN);
+	if (ret) {
+		printf("%s: error reading RTC: %x\n", __func__, ret);
+		return -1;
+	}
+	tmp->tm_sec  = bcd2bin( buf[RV3029C2_W_SECONDS] & 0x7f);
+	tmp->tm_min  = bcd2bin( buf[RV3029C2_W_MINUTES] & 0x7f);
+	if (buf[RV3029C2_W_HOURS] & RV3029C2_REG_HR_12_24) {
+		/* 12h format */
+		tmp->tm_hour = bcd2bin(buf[RV3029C2_W_HOURS] & 0x1f);
+		if (buf[RV3029C2_W_HOURS] & RV3029C2_REG_HR_PM)
+			/* PM flag set */
+			tmp->tm_hour += 12;
+	} else
+		tmp->tm_hour = bcd2bin(buf[RV3029C2_W_HOURS] & 0x3f);
+
+	tmp->tm_mday = bcd2bin( buf[RV3029C2_W_DATE] & 0x3F );
+	tmp->tm_mon  = bcd2bin( buf[RV3029C2_W_MONTHS] & 0x1F );
+	tmp->tm_wday = bcd2bin( buf[RV3029C2_W_DAYS] & 0x07 );
+	/* RTC supports only years > 1999 */
+	tmp->tm_year = bcd2bin( buf[RV3029C2_W_YEARS]) + 2000;
+	tmp->tm_yday = 0;
+	tmp->tm_isdst = 0;
+
+	debug( "Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec );
+
+	return 0;
+}
+
+int rtc_set( struct rtc_time *tmp )
+{
+	int	ret;
+	unsigned char buf[RTC_RV3029_PAGE_LEN];
+
+	debug( "Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+	if (tmp->tm_year < 2000) {
+		printf("RTC: year %d < 2000 not possible\n", tmp->tm_year);
+		return -1;
+	}
+	buf[RV3029C2_W_SECONDS] = bin2bcd(tmp->tm_sec);
+	buf[RV3029C2_W_MINUTES] = bin2bcd(tmp->tm_min);
+	buf[RV3029C2_W_HOURS] = bin2bcd(tmp->tm_hour);
+	/* set 24h format */
+	buf[RV3029C2_W_HOURS] &= ~RV3029C2_REG_HR_12_24;
+	buf[RV3029C2_W_DATE] = bin2bcd(tmp->tm_mday);
+	buf[RV3029C2_W_DAYS] = bin2bcd(tmp->tm_wday);
+	buf[RV3029C2_W_MONTHS] = bin2bcd(tmp->tm_mon);
+	tmp->tm_year -= 2000;
+	buf[RV3029C2_W_YEARS] = bin2bcd(tmp->tm_year);
+	ret = i2c_write(CONFIG_SYS_I2C_RTC_ADDR, RTC_RV3029_CLOCK_PAGE, 1,
+			buf, RTC_RV3029_PAGE_LEN);
+
+	/* give the RTC some time to update */
+	udelay(1000);
+	return ret;
+}
+
+/* sets EERE-Bit  (automatic EEPROM refresh) */
+static void set_eere_bit(int state)
+{
+	unsigned char reg_ctrl1;
+
+	(void)i2c_read(CONFIG_SYS_I2C_RTC_ADDR, RTC_RV3029_CTRL1, 1,
+			&reg_ctrl1, 1);
+
+	if (state)
+		reg_ctrl1 |= RTC_RV3029_CTRL1_EERE;
+	else
+		reg_ctrl1 &= (~RTC_RV3029_CTRL1_EERE);
+
+	(void)i2c_write(CONFIG_SYS_I2C_RTC_ADDR, RTC_RV3029_CTRL1, 1,
+		&reg_ctrl1, 1);
+}
+
+/* waits until EEPROM page is no longer busy (times out after 10ms*loops) */
+static int wait_eebusy(int loops)
+{
+	int i;
+	unsigned char ctrl_status;
+
+	for (i = 0; i < loops; i++) {
+		(void)i2c_read(CONFIG_SYS_I2C_RTC_ADDR, RTC_RV3029_CTRL_STATUS,
+			1, &ctrl_status, 1);
+
+		if ((ctrl_status & RTC_RV3029_CTRLS_EEBUSY) == 0)
+			break;
+		udelay(10000);
+	}
+	return i;
+}
+
+void rtc_reset (void)
+{
+	unsigned char buf[RTC_RV3029_PAGE_LEN];
+
+	buf[0] = RTC_RV3029_CTRL_SYS_R;
+	(void)i2c_write(CONFIG_SYS_I2C_RTC_ADDR, RTC_RV3029_CTRL_RESET, 1,
+			buf, 1);
+
+#if defined(CONFIG_SYS_RV3029_TCR)
+	/*
+	 * because EEPROM_CTRL register is in EEPROM page it is necessary to
+	 * disable automatic EEPROM refresh and check if EEPROM is busy
+	 * before EEPORM_CTRL register may be accessed
+	 */
+	set_eere_bit(0);
+	wait_eebusy(100);
+	/* read current trickle charger setting */
+	(void)i2c_read(CONFIG_SYS_I2C_RTC_ADDR, RTC_RV3029_EEPROM_CTRL,
+			1, buf, 1);
+	/* enable automatic EEPROM refresh again */
+	set_eere_bit(1);
+
+	/*
+	 * to minimize EEPROM access write trickle charger setting only if it
+	 * differs from current value
+	 */
+	if ((buf[0] & 0xF0) != CONFIG_SYS_RV3029_TCR) {
+		buf[0] = (buf[0] & 0x0F) | CONFIG_SYS_RV3029_TCR;
+		/*
+		 * write trickle charger setting (disable autom. EEPROM
+		 * refresh and wait until EEPROM is idle)
+		 */
+		set_eere_bit(0);
+		wait_eebusy(100);
+		(void)i2c_write(CONFIG_SYS_I2C_RTC_ADDR,
+				RTC_RV3029_EEPROM_CTRL, 1, buf, 1);
+		/*
+		 * it is necessary to wait 10ms before EEBUSY-Bit may be read
+		 * (this is not documented in the data sheet yet, but the
+		 * manufacturer recommends it)
+		 */
+		udelay(10000);
+		/* wait until EEPROM write access is finished */
+		wait_eebusy(100);
+		set_eere_bit(1);
+	}
+#endif
+}
diff --git a/marvell/uboot/drivers/rtc/rx8025.c b/marvell/uboot/drivers/rtc/rx8025.c
new file mode 100644
index 0000000..b4a149b
--- /dev/null
+++ b/marvell/uboot/drivers/rtc/rx8025.c
@@ -0,0 +1,211 @@
+/*
+ * (C) Copyright 2007
+ * Matthias Fuchs, esd gmbh, matthias.fuchs@esd-electronics.com.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+/*
+ * Epson RX8025 RTC driver.
+ */
+
+#include <common.h>
+#include <command.h>
+#include <rtc.h>
+#include <i2c.h>
+
+#if defined(CONFIG_CMD_DATE)
+
+/*---------------------------------------------------------------------*/
+#undef DEBUG_RTC
+
+#ifdef DEBUG_RTC
+#define DEBUGR(fmt,args...) printf(fmt ,##args)
+#else
+#define DEBUGR(fmt,args...)
+#endif
+/*---------------------------------------------------------------------*/
+
+#ifndef CONFIG_SYS_I2C_RTC_ADDR
+# define CONFIG_SYS_I2C_RTC_ADDR	0x32
+#endif
+
+/*
+ * RTC register addresses
+ */
+#define RTC_SEC_REG_ADDR	0x00
+#define RTC_MIN_REG_ADDR	0x01
+#define RTC_HR_REG_ADDR		0x02
+#define RTC_DAY_REG_ADDR	0x03
+#define RTC_DATE_REG_ADDR	0x04
+#define RTC_MON_REG_ADDR	0x05
+#define RTC_YR_REG_ADDR		0x06
+
+#define RTC_CTL1_REG_ADDR	0x0e
+#define RTC_CTL2_REG_ADDR	0x0f
+
+/*
+ * Control register 1 bits
+ */
+#define RTC_CTL1_BIT_2412	0x20
+
+/*
+ * Control register 2 bits
+ */
+#define RTC_CTL2_BIT_PON	0x10
+#define RTC_CTL2_BIT_VDET	0x40
+#define RTC_CTL2_BIT_XST	0x20
+#define RTC_CTL2_BIT_VDSL	0x80
+
+/*
+ * Note: the RX8025 I2C RTC requires register
+ * reads and write to consist of a single bus
+ * cycle. It is not allowed to write the register
+ * address in a first cycle that is terminated by
+ * a STOP condition. The chips needs a 'restart'
+ * sequence (start sequence without a prior stop).
+ * This driver has been written for a 4xx board.
+ * U-Boot's 4xx i2c driver is currently not capable
+ * to generate such cycles to some work arounds
+ * are used.
+ */
+
+/* static uchar rtc_read (uchar reg); */
+#define rtc_read(reg) buf[((reg) + 1) & 0xf]
+
+static void rtc_write (uchar reg, uchar val);
+
+/*
+ * Get the current time from the RTC
+ */
+int rtc_get (struct rtc_time *tmp)
+{
+	int rel = 0;
+	uchar sec, min, hour, mday, wday, mon, year, ctl2;
+	uchar buf[16];
+
+	if (i2c_read(CONFIG_SYS_I2C_RTC_ADDR, 0, 0, buf, 16))
+		printf("Error reading from RTC\n");
+
+	sec = rtc_read(RTC_SEC_REG_ADDR);
+	min = rtc_read(RTC_MIN_REG_ADDR);
+	hour = rtc_read(RTC_HR_REG_ADDR);
+	wday = rtc_read(RTC_DAY_REG_ADDR);
+	mday = rtc_read(RTC_DATE_REG_ADDR);
+	mon = rtc_read(RTC_MON_REG_ADDR);
+	year = rtc_read(RTC_YR_REG_ADDR);
+
+	DEBUGR ("Get RTC year: %02x mon: %02x mday: %02x wday: %02x "
+		"hr: %02x min: %02x sec: %02x\n",
+		year, mon, mday, wday, hour, min, sec);
+
+	/* dump status */
+	ctl2 = rtc_read(RTC_CTL2_REG_ADDR);
+	if (ctl2 & RTC_CTL2_BIT_PON) {
+		printf("RTC: power-on detected\n");
+		rel = -1;
+	}
+
+	if (ctl2 & RTC_CTL2_BIT_VDET) {
+		printf("RTC: voltage drop detected\n");
+		rel = -1;
+	}
+
+	if (!(ctl2 & RTC_CTL2_BIT_XST)) {
+		printf("RTC: oscillator stop detected\n");
+		rel = -1;
+	}
+
+	tmp->tm_sec  = bcd2bin (sec & 0x7F);
+	tmp->tm_min  = bcd2bin (min & 0x7F);
+	if (rtc_read(RTC_CTL1_REG_ADDR) & RTC_CTL1_BIT_2412)
+		tmp->tm_hour = bcd2bin (hour & 0x3F);
+	else
+		tmp->tm_hour = bcd2bin (hour & 0x1F) % 12 +
+			       ((hour & 0x20) ? 12 : 0);
+	tmp->tm_mday = bcd2bin (mday & 0x3F);
+	tmp->tm_mon  = bcd2bin (mon & 0x1F);
+	tmp->tm_year = bcd2bin (year) + ( bcd2bin (year) >= 70 ? 1900 : 2000);
+	tmp->tm_wday = bcd2bin (wday & 0x07);
+	tmp->tm_yday = 0;
+	tmp->tm_isdst= 0;
+
+	DEBUGR ("Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+	return rel;
+}
+
+/*
+ * Set the RTC
+ */
+int rtc_set (struct rtc_time *tmp)
+{
+	DEBUGR ("Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+	if (tmp->tm_year < 1970 || tmp->tm_year > 2069)
+		printf("WARNING: year should be between 1970 and 2069!\n");
+
+	rtc_write (RTC_YR_REG_ADDR, bin2bcd (tmp->tm_year % 100));
+	rtc_write (RTC_MON_REG_ADDR, bin2bcd (tmp->tm_mon));
+	rtc_write (RTC_DAY_REG_ADDR, bin2bcd (tmp->tm_wday));
+	rtc_write (RTC_DATE_REG_ADDR, bin2bcd (tmp->tm_mday));
+	rtc_write (RTC_HR_REG_ADDR, bin2bcd (tmp->tm_hour));
+	rtc_write (RTC_MIN_REG_ADDR, bin2bcd (tmp->tm_min));
+	rtc_write (RTC_SEC_REG_ADDR, bin2bcd (tmp->tm_sec));
+
+	rtc_write (RTC_CTL1_REG_ADDR, RTC_CTL1_BIT_2412);
+
+	return 0;
+}
+
+/*
+ * Reset the RTC. We setting the date back to 1970-01-01.
+ */
+void rtc_reset (void)
+{
+	struct rtc_time tmp;
+	uchar buf[16];
+	uchar ctl2;
+
+	if (i2c_read(CONFIG_SYS_I2C_RTC_ADDR, 0,    0,   buf, 16))
+		printf("Error reading from RTC\n");
+
+	ctl2 = rtc_read(RTC_CTL2_REG_ADDR);
+	ctl2 &= ~(RTC_CTL2_BIT_PON | RTC_CTL2_BIT_VDET);
+	ctl2 |= RTC_CTL2_BIT_XST | RTC_CTL2_BIT_VDSL;
+	rtc_write (RTC_CTL2_REG_ADDR, ctl2);
+
+	tmp.tm_year = 1970;
+	tmp.tm_mon = 1;
+	tmp.tm_mday= 1;
+	tmp.tm_hour = 0;
+	tmp.tm_min = 0;
+	tmp.tm_sec = 0;
+
+	rtc_set(&tmp);
+
+	printf ( "RTC:   %4d-%02d-%02d %2d:%02d:%02d UTC\n",
+		tmp.tm_year, tmp.tm_mon, tmp.tm_mday,
+		tmp.tm_hour, tmp.tm_min, tmp.tm_sec);
+
+	return;
+}
+
+/*
+ * Helper functions
+ */
+static void rtc_write (uchar reg, uchar val)
+{
+	uchar buf[2];
+	buf[0] = reg << 4;
+	buf[1] = val;
+	if (i2c_write(CONFIG_SYS_I2C_RTC_ADDR, 0, 0, buf, 2) != 0)
+		printf("Error writing to RTC\n");
+
+}
+
+#endif /* CONFIG_RTC_RX8025 && CONFIG_CMD_DATE */
diff --git a/marvell/uboot/drivers/rtc/s3c24x0_rtc.c b/marvell/uboot/drivers/rtc/s3c24x0_rtc.c
new file mode 100644
index 0000000..187620a
--- /dev/null
+++ b/marvell/uboot/drivers/rtc/s3c24x0_rtc.c
@@ -0,0 +1,154 @@
+/*
+ * (C) Copyright 2003
+ * David Müller ELSOFT AG Switzerland. d.mueller@elsoft.ch
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+/*
+ * Date & Time support for the built-in Samsung S3C24X0 RTC
+ */
+
+#include <common.h>
+#include <command.h>
+
+#if (defined(CONFIG_CMD_DATE))
+
+#include <asm/arch/s3c24x0_cpu.h>
+
+#include <rtc.h>
+#include <asm/io.h>
+#include <linux/compiler.h>
+
+typedef enum {
+	RTC_ENABLE,
+	RTC_DISABLE
+} RTC_ACCESS;
+
+
+static inline void SetRTC_Access(RTC_ACCESS a)
+{
+	struct s3c24x0_rtc *rtc = s3c24x0_get_base_rtc();
+
+	switch (a) {
+	case RTC_ENABLE:
+		writeb(readb(&rtc->rtccon) | 0x01, &rtc->rtccon);
+		break;
+
+	case RTC_DISABLE:
+		writeb(readb(&rtc->rtccon) & ~0x01, &rtc->rtccon);
+		break;
+	}
+}
+
+/* ------------------------------------------------------------------------- */
+
+int rtc_get(struct rtc_time *tmp)
+{
+	struct s3c24x0_rtc *rtc = s3c24x0_get_base_rtc();
+	uchar sec, min, hour, mday, wday, mon, year;
+	__maybe_unused uchar a_sec, a_min, a_hour, a_date,
+			     a_mon, a_year, a_armed;
+
+	/* enable access to RTC registers */
+	SetRTC_Access(RTC_ENABLE);
+
+	/* read RTC registers */
+	do {
+		sec  = readb(&rtc->bcdsec);
+		min  = readb(&rtc->bcdmin);
+		hour = readb(&rtc->bcdhour);
+		mday = readb(&rtc->bcddate);
+		wday = readb(&rtc->bcdday);
+		mon  = readb(&rtc->bcdmon);
+		year = readb(&rtc->bcdyear);
+	} while (sec != readb(&rtc->bcdsec));
+
+	/* read ALARM registers */
+	a_sec   = readb(&rtc->almsec);
+	a_min   = readb(&rtc->almmin);
+	a_hour  = readb(&rtc->almhour);
+	a_date  = readb(&rtc->almdate);
+	a_mon   = readb(&rtc->almmon);
+	a_year  = readb(&rtc->almyear);
+	a_armed = readb(&rtc->rtcalm);
+
+	/* disable access to RTC registers */
+	SetRTC_Access(RTC_DISABLE);
+
+#ifdef RTC_DEBUG
+	printf("Get RTC year: %02x mon/cent: %02x mday: %02x wday: %02x "
+	       "hr: %02x min: %02x sec: %02x\n",
+	       year, mon, mday, wday, hour, min, sec);
+	printf("Alarms: %02x: year: %02x month: %02x date: %02x hour: "
+	       "%02x min: %02x sec: %02x\n",
+	       a_armed, a_year, a_mon, a_date, a_hour, a_min, a_sec);
+#endif
+
+	tmp->tm_sec  = bcd2bin(sec & 0x7F);
+	tmp->tm_min  = bcd2bin(min & 0x7F);
+	tmp->tm_hour = bcd2bin(hour & 0x3F);
+	tmp->tm_mday = bcd2bin(mday & 0x3F);
+	tmp->tm_mon  = bcd2bin(mon & 0x1F);
+	tmp->tm_year = bcd2bin(year);
+	tmp->tm_wday = bcd2bin(wday & 0x07);
+	if (tmp->tm_year < 70)
+		tmp->tm_year += 2000;
+	else
+		tmp->tm_year += 1900;
+	tmp->tm_yday  = 0;
+	tmp->tm_isdst = 0;
+#ifdef RTC_DEBUG
+	printf("Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+	       tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+	       tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+#endif
+
+	return 0;
+}
+
+int rtc_set(struct rtc_time *tmp)
+{
+	struct s3c24x0_rtc *rtc = s3c24x0_get_base_rtc();
+	uchar sec, min, hour, mday, wday, mon, year;
+
+#ifdef RTC_DEBUG
+	printf("Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+	       tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+	       tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+#endif
+	year = bin2bcd(tmp->tm_year % 100);
+	mon  = bin2bcd(tmp->tm_mon);
+	wday = bin2bcd(tmp->tm_wday);
+	mday = bin2bcd(tmp->tm_mday);
+	hour = bin2bcd(tmp->tm_hour);
+	min  = bin2bcd(tmp->tm_min);
+	sec  = bin2bcd(tmp->tm_sec);
+
+	/* enable access to RTC registers */
+	SetRTC_Access(RTC_ENABLE);
+
+	/* write RTC registers */
+	writeb(sec, &rtc->bcdsec);
+	writeb(min, &rtc->bcdmin);
+	writeb(hour, &rtc->bcdhour);
+	writeb(mday, &rtc->bcddate);
+	writeb(wday, &rtc->bcdday);
+	writeb(mon, &rtc->bcdmon);
+	writeb(year, &rtc->bcdyear);
+
+	/* disable access to RTC registers */
+	SetRTC_Access(RTC_DISABLE);
+
+	return 0;
+}
+
+void rtc_reset(void)
+{
+	struct s3c24x0_rtc *rtc = s3c24x0_get_base_rtc();
+
+	writeb((readb(&rtc->rtccon) & ~0x06) | 0x08, &rtc->rtccon);
+	writeb(readb(&rtc->rtccon) & ~(0x08 | 0x01), &rtc->rtccon);
+}
+
+#endif
diff --git a/marvell/uboot/drivers/rtc/x1205.c b/marvell/uboot/drivers/rtc/x1205.c
new file mode 100644
index 0000000..c499c7a
--- /dev/null
+++ b/marvell/uboot/drivers/rtc/x1205.c
@@ -0,0 +1,165 @@
+/*
+ * (C) Copyright 2007
+ * Stefan Roese, DENX Software Engineering, sr@denx.de.
+ *
+ * based on a the Linux rtc-x1207.c driver which is:
+ *	Copyright 2004 Karen Spearel
+ *	Copyright 2005 Alessandro Zummo
+ *
+ * Information and datasheet:
+ * http://www.intersil.com/cda/deviceinfo/0,1477,X1205,00.html
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+/*
+ * Date & Time support for Xicor/Intersil X1205 RTC
+ */
+
+/* #define	DEBUG	*/
+
+#include <common.h>
+#include <command.h>
+#include <rtc.h>
+#include <i2c.h>
+
+#if defined(CONFIG_CMD_DATE)
+
+#define CCR_SEC			0
+#define CCR_MIN			1
+#define CCR_HOUR		2
+#define CCR_MDAY		3
+#define CCR_MONTH		4
+#define CCR_YEAR		5
+#define CCR_WDAY		6
+#define CCR_Y2K			7
+
+#define X1205_REG_SR		0x3F	/* status register */
+#define X1205_REG_Y2K		0x37
+#define X1205_REG_DW		0x36
+#define X1205_REG_YR		0x35
+#define X1205_REG_MO		0x34
+#define X1205_REG_DT		0x33
+#define X1205_REG_HR		0x32
+#define X1205_REG_MN		0x31
+#define X1205_REG_SC		0x30
+#define X1205_REG_DTR		0x13
+#define X1205_REG_ATR		0x12
+#define X1205_REG_INT		0x11
+#define X1205_REG_0		0x10
+#define X1205_REG_Y2K1		0x0F
+#define X1205_REG_DWA1		0x0E
+#define X1205_REG_YRA1		0x0D
+#define X1205_REG_MOA1		0x0C
+#define X1205_REG_DTA1		0x0B
+#define X1205_REG_HRA1		0x0A
+#define X1205_REG_MNA1		0x09
+#define X1205_REG_SCA1		0x08
+#define X1205_REG_Y2K0		0x07
+#define X1205_REG_DWA0		0x06
+#define X1205_REG_YRA0		0x05
+#define X1205_REG_MOA0		0x04
+#define X1205_REG_DTA0		0x03
+#define X1205_REG_HRA0		0x02
+#define X1205_REG_MNA0		0x01
+#define X1205_REG_SCA0		0x00
+
+#define X1205_CCR_BASE		0x30	/* Base address of CCR */
+#define X1205_ALM0_BASE		0x00	/* Base address of ALARM0 */
+
+#define X1205_SR_RTCF		0x01	/* Clock failure */
+#define X1205_SR_WEL		0x02	/* Write Enable Latch */
+#define X1205_SR_RWEL		0x04	/* Register Write Enable */
+
+#define X1205_DTR_DTR0		0x01
+#define X1205_DTR_DTR1		0x02
+#define X1205_DTR_DTR2		0x04
+
+#define X1205_HR_MIL		0x80	/* Set in ccr.hour for 24 hr mode */
+
+static void rtc_write(int reg, u8 val)
+{
+	i2c_write(CONFIG_SYS_I2C_RTC_ADDR, reg, 2, &val, 1);
+}
+
+/*
+ * In the routines that deal directly with the x1205 hardware, we use
+ * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch
+ * Epoch is initialized as 2000. Time is set to UTC.
+ */
+int rtc_get(struct rtc_time *tm)
+{
+	u8 buf[8];
+
+	i2c_read(CONFIG_SYS_I2C_RTC_ADDR, X1205_CCR_BASE, 2, buf, 8);
+
+	debug("%s: raw read data - sec=%02x, min=%02x, hr=%02x, "
+	      "mday=%02x, mon=%02x, year=%02x, wday=%02x, y2k=%02x\n",
+	      __FUNCTION__,
+	      buf[0], buf[1], buf[2], buf[3],
+	      buf[4], buf[5], buf[6], buf[7]);
+
+	tm->tm_sec = bcd2bin(buf[CCR_SEC]);
+	tm->tm_min = bcd2bin(buf[CCR_MIN]);
+	tm->tm_hour = bcd2bin(buf[CCR_HOUR] & 0x3F); /* hr is 0-23 */
+	tm->tm_mday = bcd2bin(buf[CCR_MDAY]);
+	tm->tm_mon = bcd2bin(buf[CCR_MONTH]); /* mon is 0-11 */
+	tm->tm_year = bcd2bin(buf[CCR_YEAR])
+		+ (bcd2bin(buf[CCR_Y2K]) * 100);
+	tm->tm_wday = buf[CCR_WDAY];
+
+	debug("%s: tm is secs=%d, mins=%d, hours=%d, "
+	      "mday=%d, mon=%d, year=%d, wday=%d\n",
+	      __FUNCTION__,
+	      tm->tm_sec, tm->tm_min, tm->tm_hour,
+	      tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
+
+	return 0;
+}
+
+int rtc_set(struct rtc_time *tm)
+{
+	int i;
+	u8 buf[8];
+
+	debug("Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+	      tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_wday,
+	      tm->tm_hour, tm->tm_min, tm->tm_sec);
+
+	buf[CCR_SEC] = bin2bcd(tm->tm_sec);
+	buf[CCR_MIN] = bin2bcd(tm->tm_min);
+
+	/* set hour and 24hr bit */
+	buf[CCR_HOUR] = bin2bcd(tm->tm_hour) | X1205_HR_MIL;
+
+	buf[CCR_MDAY] = bin2bcd(tm->tm_mday);
+
+	/* month, 1 - 12 */
+	buf[CCR_MONTH] = bin2bcd(tm->tm_mon);
+
+	/* year, since the rtc epoch*/
+	buf[CCR_YEAR] = bin2bcd(tm->tm_year % 100);
+	buf[CCR_WDAY] = tm->tm_wday & 0x07;
+	buf[CCR_Y2K] = bin2bcd(tm->tm_year / 100);
+
+	/* this sequence is required to unlock the chip */
+	rtc_write(X1205_REG_SR, X1205_SR_WEL);
+	rtc_write(X1205_REG_SR, X1205_SR_WEL | X1205_SR_RWEL);
+
+	/* write register's data */
+	for (i = 0; i < 8; i++)
+		rtc_write(X1205_CCR_BASE + i, buf[i]);
+
+	rtc_write(X1205_REG_SR, 0);
+
+	return 0;
+}
+
+void rtc_reset(void)
+{
+	/*
+	 * Nothing to do
+	 */
+}
+
+#endif