uboot/drivers/rtc/ftrtc010.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Faraday FTRTC010 Real Time Clock
   4 *
   5 * (C) Copyright 2009 Faraday Technology
   6 * Po-Yu Chuang <ratbert@faraday-tech.com>
   7 */
   8
   9#include <config.h>
  10#include <common.h>
  11#include <rtc.h>
  12#include <asm/io.h>
  13
  14struct ftrtc010 {
  15        unsigned int sec;               /* 0x00 */
  16        unsigned int min;               /* 0x04 */
  17        unsigned int hour;              /* 0x08 */
  18        unsigned int day;               /* 0x0c */
  19        unsigned int alarm_sec;         /* 0x10 */
  20        unsigned int alarm_min;         /* 0x14 */
  21        unsigned int alarm_hour;        /* 0x18 */
  22        unsigned int record;            /* 0x1c */
  23        unsigned int cr;                /* 0x20 */
  24        unsigned int wsec;              /* 0x24 */
  25        unsigned int wmin;              /* 0x28 */
  26        unsigned int whour;             /* 0x2c */
  27        unsigned int wday;              /* 0x30 */
  28        unsigned int intr;              /* 0x34 */
  29        unsigned int div;               /* 0x38 */
  30        unsigned int rev;               /* 0x3c */
  31};
  32
  33/*
  34 * RTC Control Register
  35 */
  36#define FTRTC010_CR_ENABLE              (1 << 0)
  37#define FTRTC010_CR_INTERRUPT_SEC       (1 << 1)        /* per second irq */
  38#define FTRTC010_CR_INTERRUPT_MIN       (1 << 2)        /* per minute irq */
  39#define FTRTC010_CR_INTERRUPT_HR        (1 << 3)        /* per hour   irq */
  40#define FTRTC010_CR_INTERRUPT_DAY       (1 << 4)        /* per day    irq */
  41
  42static struct ftrtc010 *rtc = (struct ftrtc010 *)CONFIG_FTRTC010_BASE;
  43
  44static void ftrtc010_enable(void)
  45{
  46        writel(FTRTC010_CR_ENABLE, &rtc->cr);
  47}
  48
  49/*
  50 * return current time in seconds
  51 */
  52static unsigned long ftrtc010_time(void)
  53{
  54        unsigned long day;
  55        unsigned long hour;
  56        unsigned long minute;
  57        unsigned long second;
  58        unsigned long second2;
  59
  60        do {
  61                second  = readl(&rtc->sec);
  62                day     = readl(&rtc->day);
  63                hour    = readl(&rtc->hour);
  64                minute  = readl(&rtc->min);
  65                second2 = readl(&rtc->sec);
  66        } while (second != second2);
  67
  68        return day * 24 * 60 * 60 + hour * 60 * 60 + minute * 60 + second;
  69}
  70
  71/*
  72 * Get the current time from the RTC
  73 */
  74
  75int rtc_get(struct rtc_time *tmp)
  76{
  77        unsigned long now;
  78
  79        debug("%s(): record register: %x\n",
  80              __func__, readl(&rtc->record));
  81
  82#ifdef CONFIG_FTRTC010_PCLK
  83        now = (ftrtc010_time() + readl(&rtc->record)) / RTC_DIV_COUNT;
  84#else /* CONFIG_FTRTC010_EXTCLK */
  85        now = ftrtc010_time() + readl(&rtc->record);
  86#endif
  87
  88        rtc_to_tm(now, tmp);
  89
  90        return 0;
  91}
  92
  93/*
  94 * Set the RTC
  95 */
  96int rtc_set(struct rtc_time *tmp)
  97{
  98        unsigned long new;
  99        unsigned long now;
 100
 101        debug("%s(): DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
 102              __func__,
 103              tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
 104              tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
 105
 106        new = rtc_mktime(tmp);
 107
 108        now = ftrtc010_time();
 109
 110        debug("%s(): write %lx to record register\n", __func__, new - now);
 111
 112        writel(new - now, &rtc->record);
 113
 114        return 0;
 115}
 116
 117void rtc_reset(void)
 118{
 119        debug("%s()\n", __func__);
 120        ftrtc010_enable();
 121}
 122