]> git.ipfire.org Git - people/ms/u-boot.git/blob - drivers/rtc/mpc5xxx.c
arc: hard-code CONFIG_ARCH_EARLY_INIT_R in asm/config.h
[people/ms/u-boot.git] / drivers / rtc / mpc5xxx.c
1 /*
2 * (C) Copyright 2004
3 * Reinhard Meyer, EMK Elektronik GmbH
4 * r.meyer@emk-elektronik.de
5 * www.emk-elektronik.de
6 *
7 * SPDX-License-Identifier: GPL-2.0+
8 */
9
10 /*****************************************************************************
11 * Date & Time support for internal RTC of MPC52xx
12 *****************************************************************************/
13 /*#define DEBUG*/
14
15 #include <common.h>
16 #include <command.h>
17 #include <rtc.h>
18
19 #if defined(CONFIG_CMD_DATE)
20
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 */
34 } RTC5200;
35
36 #define RTC_SET 0x02000000
37 #define RTC_PAUSE 0x01000000
38
39 /*****************************************************************************
40 * get time
41 *****************************************************************************/
42 int rtc_get (struct rtc_time *tmp)
43 {
44 RTC5200 *rtc = (RTC5200 *) (CONFIG_SYS_MBAR+0x800);
45 ulong time, date, time2;
46
47 /* read twice to avoid getting a funny time when the second is just changing */
48 do {
49 time = rtc->ctr;
50 date = rtc->cdr;
51 time2 = rtc->ctr;
52 } while (time != time2);
53
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)
60 tmp->tm_wday = 0;
61 tmp->tm_hour = (time >> 16) & 0x1f;
62 tmp->tm_min = (time >> 8) & 0x3f;
63 tmp->tm_sec = time & 0x3f;
64
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);
68
69 return 0;
70 }
71
72 /*****************************************************************************
73 * set time
74 *****************************************************************************/
75 int rtc_set (struct rtc_time *tmp)
76 {
77 RTC5200 *rtc = (RTC5200 *) (CONFIG_SYS_MBAR+0x800);
78 ulong time, date, year;
79
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);
83
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)
87 date |= (7 << 8);
88 else
89 date |= (tmp->tm_wday << 8);
90 year = tmp->tm_year;
91
92 /* mask unwanted bits that might show up when rtc_time is corrupt */
93 time &= 0x001f3f3f;
94 date &= 0x001f071f;
95 year &= 0x00000fff;
96
97 /* pause and set the RTC */
98 rtc->nysr = year;
99 rtc->dsr = date | RTC_PAUSE;
100 udelay (1000);
101 rtc->dsr = date | RTC_PAUSE | RTC_SET;
102 udelay (1000);
103 rtc->dsr = date | RTC_PAUSE;
104 udelay (1000);
105 rtc->dsr = date;
106 udelay (1000);
107
108 rtc->tsr = time | RTC_PAUSE;
109 udelay (1000);
110 rtc->tsr = time | RTC_PAUSE | RTC_SET;
111 udelay (1000);
112 rtc->tsr = time | RTC_PAUSE;
113 udelay (1000);
114 rtc->tsr = time;
115 udelay (1000);
116
117 return 0;
118 }
119
120 /*****************************************************************************
121 * reset rtc circuit
122 *****************************************************************************/
123 void rtc_reset (void)
124 {
125 return; /* nothing to do */
126 }
127
128 #endif