]> git.sur5r.net Git - u-boot/blob - drivers/rtc/mpc5xxx.c
arm: mvebu: Disable L2 cache before enabling d-cache
[u-boot] / 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