141d272d1SHeiko Schocher /* 241d272d1SHeiko Schocher * (C) Copyright 2011 DENX Software Engineering GmbH 341d272d1SHeiko Schocher * Heiko Schocher <hs@denx.de> 441d272d1SHeiko Schocher * 51a459660SWolfgang Denk * SPDX-License-Identifier: GPL-2.0+ 641d272d1SHeiko Schocher */ 741d272d1SHeiko Schocher #include <common.h> 841d272d1SHeiko Schocher #include <command.h> 941d272d1SHeiko Schocher #include <rtc.h> 1041d272d1SHeiko Schocher #include <asm/io.h> 11*155d424aSTom Rini #include <asm/davinci_rtc.h> 1241d272d1SHeiko Schocher 1341d272d1SHeiko Schocher #if defined(CONFIG_CMD_DATE) 1441d272d1SHeiko Schocher int rtc_get(struct rtc_time *tmp) 1541d272d1SHeiko Schocher { 165d4d38d1STom Rini struct davinci_rtc *rtc = (struct davinci_rtc *)DAVINCI_RTC_BASE; 1741d272d1SHeiko Schocher unsigned long sec, min, hour, mday, wday, mon_cent, year; 1841d272d1SHeiko Schocher unsigned long status; 1941d272d1SHeiko Schocher 2041d272d1SHeiko Schocher status = readl(&rtc->status); 2141d272d1SHeiko Schocher if ((status & RTC_STATE_RUN) != RTC_STATE_RUN) { 2241d272d1SHeiko Schocher printf("RTC doesn't run\n"); 2341d272d1SHeiko Schocher return -1; 2441d272d1SHeiko Schocher } 2541d272d1SHeiko Schocher if ((status & RTC_STATE_BUSY) == RTC_STATE_BUSY) 2641d272d1SHeiko Schocher udelay(20); 2741d272d1SHeiko Schocher 2841d272d1SHeiko Schocher sec = readl(&rtc->second); 2941d272d1SHeiko Schocher min = readl(&rtc->minutes); 3041d272d1SHeiko Schocher hour = readl(&rtc->hours); 3141d272d1SHeiko Schocher mday = readl(&rtc->day); 3241d272d1SHeiko Schocher wday = readl(&rtc->dotw); 3341d272d1SHeiko Schocher mon_cent = readl(&rtc->month); 3441d272d1SHeiko Schocher year = readl(&rtc->year); 3541d272d1SHeiko Schocher 3641d272d1SHeiko Schocher debug("Get RTC year: %02lx mon/cent: %02lx mday: %02lx wday: %02lx " 3741d272d1SHeiko Schocher "hr: %02lx min: %02lx sec: %02lx\n", 3841d272d1SHeiko Schocher year, mon_cent, mday, wday, 3941d272d1SHeiko Schocher hour, min, sec); 4041d272d1SHeiko Schocher 4141d272d1SHeiko Schocher tmp->tm_sec = bcd2bin(sec & 0x7F); 4241d272d1SHeiko Schocher tmp->tm_min = bcd2bin(min & 0x7F); 4341d272d1SHeiko Schocher tmp->tm_hour = bcd2bin(hour & 0x3F); 4441d272d1SHeiko Schocher tmp->tm_mday = bcd2bin(mday & 0x3F); 4541d272d1SHeiko Schocher tmp->tm_mon = bcd2bin(mon_cent & 0x1F); 4641d272d1SHeiko Schocher tmp->tm_year = bcd2bin(year) + 2000; 4741d272d1SHeiko Schocher tmp->tm_wday = bcd2bin(wday & 0x07); 4841d272d1SHeiko Schocher tmp->tm_yday = 0; 4941d272d1SHeiko Schocher tmp->tm_isdst = 0; 5041d272d1SHeiko Schocher 5141d272d1SHeiko Schocher debug("Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", 5241d272d1SHeiko Schocher tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, 5341d272d1SHeiko Schocher tmp->tm_hour, tmp->tm_min, tmp->tm_sec); 5441d272d1SHeiko Schocher 5541d272d1SHeiko Schocher return 0; 5641d272d1SHeiko Schocher } 5741d272d1SHeiko Schocher 5841d272d1SHeiko Schocher int rtc_set(struct rtc_time *tmp) 5941d272d1SHeiko Schocher { 605d4d38d1STom Rini struct davinci_rtc *rtc = (struct davinci_rtc *)DAVINCI_RTC_BASE; 6141d272d1SHeiko Schocher 6241d272d1SHeiko Schocher debug("Set DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", 6341d272d1SHeiko Schocher tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, 6441d272d1SHeiko Schocher tmp->tm_hour, tmp->tm_min, tmp->tm_sec); 6541d272d1SHeiko Schocher writel(bin2bcd(tmp->tm_year % 100), &rtc->year); 6641d272d1SHeiko Schocher writel(bin2bcd(tmp->tm_mon), &rtc->month); 6741d272d1SHeiko Schocher 6841d272d1SHeiko Schocher writel(bin2bcd(tmp->tm_wday), &rtc->dotw); 6941d272d1SHeiko Schocher writel(bin2bcd(tmp->tm_mday), &rtc->day); 7041d272d1SHeiko Schocher writel(bin2bcd(tmp->tm_hour), &rtc->hours); 7141d272d1SHeiko Schocher writel(bin2bcd(tmp->tm_min), &rtc->minutes); 7241d272d1SHeiko Schocher writel(bin2bcd(tmp->tm_sec), &rtc->second); 7341d272d1SHeiko Schocher return 0; 7441d272d1SHeiko Schocher } 7541d272d1SHeiko Schocher 7641d272d1SHeiko Schocher void rtc_reset(void) 7741d272d1SHeiko Schocher { 785d4d38d1STom Rini struct davinci_rtc *rtc = (struct davinci_rtc *)DAVINCI_RTC_BASE; 7941d272d1SHeiko Schocher 8041d272d1SHeiko Schocher /* run RTC counter */ 8141d272d1SHeiko Schocher writel(0x01, &rtc->ctrl); 8241d272d1SHeiko Schocher } 8341d272d1SHeiko Schocher #endif 84