uboot/drivers/rtc/mvrtc.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2011
   3 * Jason Cooper <u-boot@lakedaemon.net>
   4 *
   5 * See file CREDITS for list of people who contributed to this
   6 * project.
   7 *
   8 * This program is free software; you can redistribute it and/or
   9 * modify it under the terms of the GNU General Public License as
  10 * published by the Free Software Foundation; either version 2 of
  11 * the License, or (at your option) any later version.
  12 *
  13 * This program is distributed in the hope that it will be useful,
  14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16 * GNU General Public License for more details.
  17 *
  18 * You should have received a copy of the GNU General Public License
  19 * along with this program; if not, write to the Free Software
  20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21 * MA 02111-1307 USA
  22 */
  23
  24/*
  25 * Date & Time support for Marvell Integrated RTC
  26 */
  27
  28#include <common.h>
  29#include <command.h>
  30#include <rtc.h>
  31#include <asm/io.h>
  32#include "mvrtc.h"
  33
  34/* This RTC does not support century, so we assume 20 */
  35#define CENTURY 20
  36
  37int rtc_get(struct rtc_time *t)
  38{
  39        u32 time;
  40        u32 date;
  41        struct mvrtc_registers *mvrtc_regs;
  42
  43        mvrtc_regs = (struct mvrtc_registers *)KW_RTC_BASE;
  44
  45        /* read the time register */
  46        time = readl(&mvrtc_regs->time);
  47
  48        /* read the date register */
  49        date = readl(&mvrtc_regs->date);
  50
  51        /* test for 12 hour clock (can't tell if it's am/pm) */
  52        if (time & MVRTC_HRFMT_MSK) {
  53                printf("Error: RTC in 12 hour mode, can't determine AM/PM.\n");
  54                return -1;
  55        }
  56
  57        /* time */
  58        t->tm_sec  = bcd2bin((time >> MVRTC_SEC_SFT)  & MVRTC_SEC_MSK);
  59        t->tm_min  = bcd2bin((time >> MVRTC_MIN_SFT)  & MVRTC_MIN_MSK);
  60        t->tm_hour = bcd2bin((time >> MVRTC_HOUR_SFT) & MVRTC_HOUR_MSK);
  61        t->tm_wday = bcd2bin((time >> MVRTC_DAY_SFT)  & MVRTC_DAY_MSK);
  62        t->tm_wday--;
  63
  64        /* date */
  65        t->tm_mday = bcd2bin((date >> MVRTC_DATE_SFT) & MVRTC_DATE_MSK);
  66        t->tm_mon  = bcd2bin((date >> MVRTC_MON_SFT)  & MVRTC_MON_MSK);
  67        t->tm_year = bcd2bin((date >> MVRTC_YEAR_SFT) & MVRTC_YEAR_MSK);
  68        t->tm_year += CENTURY * 100;
  69
  70        /* not supported in this RTC */
  71        t->tm_yday  = 0;
  72        t->tm_isdst = 0;
  73
  74        return 0;
  75}
  76
  77int rtc_set(struct rtc_time *t)
  78{
  79        u32 time = 0; /* sets hour format bit to zero, 24hr format. */
  80        u32 date = 0;
  81        struct mvrtc_registers *mvrtc_regs;
  82
  83        mvrtc_regs = (struct mvrtc_registers *)KW_RTC_BASE;
  84
  85        /* check that this code isn't 80+ years old ;-) */
  86        if ((t->tm_year / 100) != CENTURY)
  87                printf("Warning: Only century %d supported.\n", CENTURY);
  88
  89        /* time */
  90        time |= (bin2bcd(t->tm_sec)      & MVRTC_SEC_MSK)  << MVRTC_SEC_SFT;
  91        time |= (bin2bcd(t->tm_min)      & MVRTC_MIN_MSK)  << MVRTC_MIN_SFT;
  92        time |= (bin2bcd(t->tm_hour)     & MVRTC_HOUR_MSK) << MVRTC_HOUR_SFT;
  93        time |= (bin2bcd(t->tm_wday + 1) & MVRTC_DAY_MSK)  << MVRTC_DAY_SFT;
  94
  95        /* date */
  96        date |= (bin2bcd(t->tm_mday)       & MVRTC_DATE_MSK) << MVRTC_DATE_SFT;
  97        date |= (bin2bcd(t->tm_mon)        & MVRTC_MON_MSK)  << MVRTC_MON_SFT;
  98        date |= (bin2bcd(t->tm_year % 100) & MVRTC_YEAR_MSK) << MVRTC_YEAR_SFT;
  99
 100        /* write the time register */
 101        writel(time, &mvrtc_regs->time);
 102
 103        /* write the date register */
 104        writel(date, &mvrtc_regs->date);
 105
 106        return 0;
 107}
 108
 109void rtc_reset(void)
 110{
 111        u32 time;
 112        u32 sec;
 113        struct mvrtc_registers *mvrtc_regs;
 114
 115        mvrtc_regs = (struct mvrtc_registers *)KW_RTC_BASE;
 116
 117        /* no init routine for this RTC needed, just check that it's working */
 118        time = readl(&mvrtc_regs->time);
 119        sec  = bcd2bin((time >> MVRTC_SEC_SFT) & MVRTC_SEC_MSK);
 120        udelay(1000000);
 121        time = readl(&mvrtc_regs->time);
 122
 123        if (sec == bcd2bin((time >> MVRTC_SEC_SFT) & MVRTC_SEC_MSK))
 124                printf("Error: RTC did not increment.\n");
 125}
 126