Blame view
drivers/rtc/mpc5xxx.c
4.5 KB
1c43771ba
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
/* * (C) Copyright 2004 * Reinhard Meyer, EMK Elektronik GmbH * r.meyer@emk-elektronik.de * www.emk-elektronik.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 as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */ /***************************************************************************** * Date & Time support for internal RTC of MPC52xx *****************************************************************************/ /*#define DEBUG*/ #include <common.h> #include <command.h> #include <rtc.h> |
871c18dd3
|
34 |
#if defined(CONFIG_CMD_DATE) |
1c43771ba
|
35 36 37 38 39 40 41 42 43 44 45 |
/***************************************************************************** * 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 */ |
162630879
|
46 |
volatile ulong asir; /* MBAR+0x818: alarm and stopwatch interrupt register */ |
1c43771ba
|
47 48 49 50 51 52 53 54 55 56 |
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 *****************************************************************************/ |
b73a19e16
|
57 |
int rtc_get (struct rtc_time *tmp) |
1c43771ba
|
58 |
{ |
6d0f6bcf3
|
59 |
RTC5200 *rtc = (RTC5200 *) (CONFIG_SYS_MBAR+0x800); |
1c43771ba
|
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
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 ", tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, tmp->tm_hour, tmp->tm_min, tmp->tm_sec); |
b73a19e16
|
84 85 |
return 0; |
1c43771ba
|
86 87 88 89 90 |
} /***************************************************************************** * set time *****************************************************************************/ |
d1e231941
|
91 |
int rtc_set (struct rtc_time *tmp) |
1c43771ba
|
92 |
{ |
6d0f6bcf3
|
93 |
RTC5200 *rtc = (RTC5200 *) (CONFIG_SYS_MBAR+0x800); |
1c43771ba
|
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
ulong time, date, year; debug ( "Set DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d ", 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); |
d1e231941
|
133 134 |
return 0; |
1c43771ba
|
135 136 137 138 139 140 141 142 143 |
} /***************************************************************************** * reset rtc circuit *****************************************************************************/ void rtc_reset (void) { return; /* nothing to do */ } |
068b60a0e
|
144 |
#endif |