3 * Reinhard Meyer, EMK Elektronik GmbH
4 * r.meyer@emk-elektronik.de
5 * www.emk-elektronik.de
7 * SPDX-License-Identifier: GPL-2.0+
10 /*****************************************************************************
11 * Date & Time support for internal RTC of MPC52xx
12 *****************************************************************************/
19 #if defined(CONFIG_CMD_DATE)
21 /*****************************************************************************
22 * this structure should be defined in mpc5200.h ...
23 *****************************************************************************/
24 typedef struct rtc5200 {
25 volatile ulong tsr; /* MBAR+0x800: time set register */
26 volatile ulong dsr; /* MBAR+0x804: data set register */
27 volatile ulong nysr; /* MBAR+0x808: new year and stopwatch register */
28 volatile ulong aier; /* MBAR+0x80C: alarm and interrupt enable register */
29 volatile ulong ctr; /* MBAR+0x810: current time register */
30 volatile ulong cdr; /* MBAR+0x814: current data register */
31 volatile ulong asir; /* MBAR+0x818: alarm and stopwatch interrupt register */
32 volatile ulong piber; /* MBAR+0x81C: periodic interrupt and bus error register */
33 volatile ulong trdr; /* MBAR+0x820: test register/divides register */
36 #define RTC_SET 0x02000000
37 #define RTC_PAUSE 0x01000000
39 /*****************************************************************************
41 *****************************************************************************/
42 int rtc_get (struct rtc_time *tmp)
44 RTC5200 *rtc = (RTC5200 *) (CONFIG_SYS_MBAR+0x800);
45 ulong time, date, time2;
47 /* read twice to avoid getting a funny time when the second is just changing */
52 } while (time != time2);
54 tmp->tm_year = date & 0xfff;
55 tmp->tm_mon = (date >> 24) & 0xf;
56 tmp->tm_mday = (date >> 16) & 0x1f;
57 tmp->tm_wday = (date >> 21) & 7;
58 /* sunday is 7 in 5200 but 0 in rtc_time */
59 if (tmp->tm_wday == 7)
61 tmp->tm_hour = (time >> 16) & 0x1f;
62 tmp->tm_min = (time >> 8) & 0x3f;
63 tmp->tm_sec = time & 0x3f;
65 debug ( "Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n",
66 tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
67 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
72 /*****************************************************************************
74 *****************************************************************************/
75 int rtc_set (struct rtc_time *tmp)
77 RTC5200 *rtc = (RTC5200 *) (CONFIG_SYS_MBAR+0x800);
78 ulong time, date, year;
80 debug ( "Set DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n",
81 tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
82 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
84 time = (tmp->tm_hour << 16) | (tmp->tm_min << 8) | tmp->tm_sec;
85 date = (tmp->tm_mon << 16) | tmp->tm_mday;
86 if (tmp->tm_wday == 0)
89 date |= (tmp->tm_wday << 8);
92 /* mask unwanted bits that might show up when rtc_time is corrupt */
97 /* pause and set the RTC */
99 rtc->dsr = date | RTC_PAUSE;
101 rtc->dsr = date | RTC_PAUSE | RTC_SET;
103 rtc->dsr = date | RTC_PAUSE;
108 rtc->tsr = time | RTC_PAUSE;
110 rtc->tsr = time | RTC_PAUSE | RTC_SET;
112 rtc->tsr = time | RTC_PAUSE;
120 /*****************************************************************************
122 *****************************************************************************/
123 void rtc_reset (void)
125 return; /* nothing to do */