6b13f685e
김민수
BSP 최초 추가
|
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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
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
|
/*
* (C) Copyright 2004
* Reinhard Meyer, EMK Elektronik GmbH
* r.meyer@emk-elektronik.de
* www.emk-elektronik.de
*
* SPDX-License-Identifier: GPL-2.0+
*/
/*****************************************************************************
* Date & Time support for internal RTC of MPC52xx
*****************************************************************************/
/*#define DEBUG*/
#include <common.h>
#include <command.h>
#include <rtc.h>
#if defined(CONFIG_CMD_DATE)
/*****************************************************************************
* 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 */
volatile ulong asir; /* MBAR+0x818: alarm and stopwatch interrupt register */
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
*****************************************************************************/
int rtc_get (struct rtc_time *tmp)
{
RTC5200 *rtc = (RTC5200 *) (CONFIG_SYS_MBAR+0x800);
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);
return 0;
}
/*****************************************************************************
* set time
*****************************************************************************/
int rtc_set (struct rtc_time *tmp)
{
RTC5200 *rtc = (RTC5200 *) (CONFIG_SYS_MBAR+0x800);
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);
return 0;
}
/*****************************************************************************
* reset rtc circuit
*****************************************************************************/
void rtc_reset (void)
{
return; /* nothing to do */
}
#endif
|