]>
Commit | Line | Data |
---|---|---|
6cb142fa WD |
1 | /* |
2 | * (C) Copyright 2001 | |
3 | * Wolfgang Denk, DENX Software Engineering, wd@denx.de. | |
4 | * | |
5 | * See file CREDITS for list of people who contributed to this | |
6 | * project. | |
7 | * | |
8 | * This program is free software; you can redistribute it and/or | |
9 | * modify it under the terms of the GNU General Public License as | |
10 | * published by the Free Software Foundation; either version 2 of | |
11 | * the License, or (at your option) any later version. | |
12 | * | |
13 | * This program is distributed in the hope that it will be useful, | |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | * GNU General Public License for more details. | |
17 | * | |
18 | * You should have received a copy of the GNU General Public License | |
19 | * along with this program; if not, write to the Free Software | |
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | |
21 | * MA 02111-1307 USA | |
8e7b703a | 22 | * Real Time Clock interface of ADI21535 (Blackfin) for uCLinux |
6cb142fa WD |
23 | * |
24 | * Copyright (C) 2003 Motorola Corporation. All rights reserved. | |
25 | * Richard Xiao (A2590C@email.mot.com) | |
26 | * | |
27 | * Copyright (C) 1996 Paul Gortmaker | |
28 | * | |
29 | * | |
30 | * Based on other minimal char device drivers, like Alan's | |
31 | * watchdog, Ted's random, etc. etc. | |
32 | * | |
33 | * 1.07 Paul Gortmaker. | |
34 | * 1.08 Miquel van Smoorenburg: disallow certain things on the | |
35 | * DEC Alpha as the CMOS clock is also used for other things. | |
36 | * 1.09 Nikita Schmidt: epoch support and some Alpha cleanup. | |
37 | * 1.09a Pete Zaitcev: Sun SPARC | |
38 | * 1.09b Jeff Garzik: Modularize, init cleanup | |
39 | * 1.09c Jeff Garzik: SMP cleanup | |
40 | * 1.10 Paul Barton-Davis: add support for async I/O | |
41 | * 1.10a Andrea Arcangeli: Alpha updates | |
42 | * 1.10b Andrew Morton: SMP lock fix | |
43 | * 1.10c Cesar Barros: SMP locking fixes and cleanup | |
44 | * 1.10d Paul Gortmaker: delete paranoia check in rtc_exit | |
8e7b703a | 45 | * 1.10e LG Soft India: Register access is different in BF533. |
6cb142fa WD |
46 | */ |
47 | ||
48 | #include <common.h> | |
49 | #include <command.h> | |
50 | #include <rtc.h> | |
51 | ||
a593814f | 52 | #if defined(CONFIG_RTC_BFIN) && defined(CONFIG_CMD_DATE) |
6cb142fa WD |
53 | |
54 | #include <asm/blackfin.h> | |
3f0606ad | 55 | #include <asm/arch/bf5xx_rtc.h> |
6cb142fa | 56 | |
3f0606ad | 57 | void rtc_reset(void) |
6cb142fa WD |
58 | { |
59 | return; /* nothing to do */ | |
60 | } | |
61 | ||
62 | /* Wait for pending writes to complete */ | |
3f0606ad | 63 | void wait_for_complete(void) |
6cb142fa | 64 | { |
3f0606ad AL |
65 | while (!(*(volatile unsigned short *)RTC_ISTAT & 0x8000)) { |
66 | printf(""); | |
6cb142fa | 67 | } |
3f0606ad | 68 | *(volatile unsigned short *)RTC_ISTAT = 0x8000; |
6cb142fa WD |
69 | } |
70 | ||
71 | /* Enable the RTC prescaler enable register */ | |
3f0606ad | 72 | void rtc_init() |
6cb142fa | 73 | { |
3f0606ad AL |
74 | *(volatile unsigned short *)RTC_PREN = 0x1; |
75 | wait_for_complete(); | |
6cb142fa WD |
76 | } |
77 | ||
8e7b703a | 78 | /* Set the time. Get the time_in_secs which is the number of seconds since Jan 1970 and set the RTC registers |
6cb142fa WD |
79 | * based on this value. |
80 | */ | |
3f0606ad | 81 | void rtc_set(struct rtc_time *tmp) |
6cb142fa WD |
82 | { |
83 | unsigned long n_days_1970 = 0; | |
8e7b703a WD |
84 | unsigned long n_secs_rem = 0; |
85 | unsigned long n_hrs = 0; | |
86 | unsigned long n_mins = 0; | |
87 | unsigned long n_secs = 0; | |
6cb142fa WD |
88 | unsigned long time_in_secs; |
89 | ||
8e7b703a | 90 | if (tmp == NULL) { |
3f0606ad | 91 | printf("Error setting the date/time \n"); |
6cb142fa WD |
92 | return; |
93 | } | |
94 | ||
8e7b703a | 95 | time_in_secs = |
3f0606ad AL |
96 | mktime(tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_hour, |
97 | tmp->tm_min, tmp->tm_sec); | |
6cb142fa WD |
98 | |
99 | /* Compute no. of days since 1970 */ | |
3f0606ad | 100 | n_days_1970 = (unsigned long)(time_in_secs / (NUM_SECS_IN_DAY)); |
6cb142fa WD |
101 | |
102 | /* From the remining secs, compute the hrs(0-23), mins(0-59) and secs(0-59) */ | |
3f0606ad | 103 | n_secs_rem = (unsigned long)(time_in_secs % (NUM_SECS_IN_DAY)); |
8e7b703a | 104 | n_hrs = n_secs_rem / (NUM_SECS_IN_HOUR); |
6cb142fa WD |
105 | n_secs_rem = n_secs_rem % (NUM_SECS_IN_HOUR); |
106 | n_mins = n_secs_rem / (NUM_SECS_IN_MIN); | |
107 | n_secs = n_secs_rem % (NUM_SECS_IN_MIN); | |
8e7b703a | 108 | |
6cb142fa | 109 | /* Store the new time in the RTC_STAT register */ |
3f0606ad AL |
110 | *(volatile unsigned long *)RTC_STAT = |
111 | ((n_days_1970 << DAY_BITS_OFF) | (n_hrs << HOUR_BITS_OFF) | | |
112 | (n_mins << MIN_BITS_OFF) | (n_secs << SEC_BITS_OFF)); | |
6cb142fa | 113 | |
3f0606ad | 114 | wait_for_complete(); |
6cb142fa WD |
115 | } |
116 | ||
117 | /* Read the time from the RTC_STAT. time_in_seconds is seconds since Jan 1970 */ | |
3f0606ad | 118 | void rtc_get(struct rtc_time *tmp) |
6cb142fa WD |
119 | { |
120 | unsigned long cur_rtc_stat = 0; | |
121 | unsigned long time_in_sec; | |
8e7b703a | 122 | unsigned long tm_sec = 0, tm_min = 0, tm_hour = 0, tm_day = 0; |
6cb142fa | 123 | |
8e7b703a | 124 | if (tmp == NULL) { |
3f0606ad | 125 | printf("Error getting the date/time \n"); |
6cb142fa WD |
126 | return; |
127 | } | |
128 | ||
129 | /* Read the RTC_STAT register */ | |
3f0606ad | 130 | cur_rtc_stat = *(volatile unsigned long *)RTC_STAT; |
8e7b703a | 131 | |
6cb142fa WD |
132 | /* Get the secs (0-59), mins (0-59), hrs (0-23) and the days since Jan 1970 */ |
133 | tm_sec = (cur_rtc_stat >> SEC_BITS_OFF) & 0x3f; | |
134 | tm_min = (cur_rtc_stat >> MIN_BITS_OFF) & 0x3f; | |
135 | tm_hour = (cur_rtc_stat >> HOUR_BITS_OFF) & 0x1f; | |
136 | tm_day = (cur_rtc_stat >> DAY_BITS_OFF) & 0x7fff; | |
137 | ||
138 | /* Calculate the total number of seconds since Jan 1970 */ | |
8e7b703a | 139 | time_in_sec = (tm_sec) + |
3f0606ad AL |
140 | MIN_TO_SECS(tm_min) + HRS_TO_SECS(tm_hour) + DAYS_TO_SECS(tm_day); |
141 | to_tm(time_in_sec, tmp); | |
6cb142fa | 142 | } |
3f0606ad | 143 | #endif /* CONFIG_RTC_BFIN && CFG_CMD_DATE */ |