todc.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392
  1. /*
  2. * Time of Day Clock support for the M48T35, M48T37, M48T59, and MC146818
  3. * Real Time Clocks/Timekeepers.
  4. *
  5. * Author: Mark A. Greer <mgreer@mvista.com>
  6. *
  7. * 2001-2004 (c) MontaVista, Software, Inc. This file is licensed under
  8. * the terms of the GNU General Public License version 2. This program
  9. * is licensed "as is" without any warranty of any kind, whether express
  10. * or implied.
  11. */
  12. #include <linux/errno.h>
  13. #include <linux/init.h>
  14. #include <linux/kernel.h>
  15. #include <linux/time.h>
  16. #include <linux/timex.h>
  17. #include <linux/bcd.h>
  18. #include <linux/mc146818rtc.h>
  19. #include <asm/machdep.h>
  20. #include <asm/io.h>
  21. #include <asm/time.h>
  22. #include <asm/todc.h>
  23. /*
  24. * Depending on the hardware on your board and your board design, the
  25. * RTC/NVRAM may be accessed either directly (like normal memory) or via
  26. * address/data registers. If your board uses the direct method, set
  27. * 'nvram_data' to the base address of your nvram and leave 'nvram_as0' and
  28. * 'nvram_as1' NULL. If your board uses address/data regs to access nvram,
  29. * set 'nvram_as0' to the address of the lower byte, set 'nvram_as1' to the
  30. * address of the upper byte (leave NULL if using mc146818), and set
  31. * 'nvram_data' to the address of the 8-bit data register.
  32. *
  33. * Note: Even though the documentation for the various RTC chips say that it
  34. * take up to a second before it starts updating once the 'R' bit is
  35. * cleared, they always seem to update even though we bang on it many
  36. * times a second. This is true, except for the Dallas Semi 1746/1747
  37. * (possibly others). Those chips seem to have a real problem whenever
  38. * we set the 'R' bit before reading them, they basically stop counting.
  39. * --MAG
  40. */
  41. /*
  42. * 'todc_info' should be initialized in your *_setup.c file to
  43. * point to a fully initialized 'todc_info_t' structure.
  44. * This structure holds all the register offsets for your particular
  45. * TODC/RTC chip.
  46. * TODC_ALLOC()/TODC_INIT() will allocate and initialize this table for you.
  47. */
  48. #ifdef RTC_FREQ_SELECT
  49. #undef RTC_FREQ_SELECT
  50. #define RTC_FREQ_SELECT control_b /* Register A */
  51. #endif
  52. #ifdef RTC_CONTROL
  53. #undef RTC_CONTROL
  54. #define RTC_CONTROL control_a /* Register B */
  55. #endif
  56. #ifdef RTC_INTR_FLAGS
  57. #undef RTC_INTR_FLAGS
  58. #define RTC_INTR_FLAGS watchdog /* Register C */
  59. #endif
  60. #ifdef RTC_VALID
  61. #undef RTC_VALID
  62. #define RTC_VALID interrupts /* Register D */
  63. #endif
  64. /* Access routines when RTC accessed directly (like normal memory) */
  65. u_char
  66. todc_direct_read_val(int addr)
  67. {
  68. return readb((void __iomem *)(todc_info->nvram_data + addr));
  69. }
  70. void
  71. todc_direct_write_val(int addr, unsigned char val)
  72. {
  73. writeb(val, (void __iomem *)(todc_info->nvram_data + addr));
  74. return;
  75. }
  76. /* Access routines for accessing m48txx type chips via addr/data regs */
  77. u_char
  78. todc_m48txx_read_val(int addr)
  79. {
  80. outb(addr, todc_info->nvram_as0);
  81. outb(addr>>todc_info->as0_bits, todc_info->nvram_as1);
  82. return inb(todc_info->nvram_data);
  83. }
  84. void
  85. todc_m48txx_write_val(int addr, unsigned char val)
  86. {
  87. outb(addr, todc_info->nvram_as0);
  88. outb(addr>>todc_info->as0_bits, todc_info->nvram_as1);
  89. outb(val, todc_info->nvram_data);
  90. return;
  91. }
  92. /* Access routines for accessing mc146818 type chips via addr/data regs */
  93. u_char
  94. todc_mc146818_read_val(int addr)
  95. {
  96. outb_p(addr, todc_info->nvram_as0);
  97. return inb_p(todc_info->nvram_data);
  98. }
  99. void
  100. todc_mc146818_write_val(int addr, unsigned char val)
  101. {
  102. outb_p(addr, todc_info->nvram_as0);
  103. outb_p(val, todc_info->nvram_data);
  104. }
  105. /*
  106. * Routines to make RTC chips with NVRAM buried behind an addr/data pair
  107. * have the NVRAM and clock regs appear at the same level.
  108. * The NVRAM will appear to start at addr 0 and the clock regs will appear
  109. * to start immediately after the NVRAM (actually, start at offset
  110. * todc_info->nvram_size).
  111. */
  112. static inline u_char
  113. todc_read_val(int addr)
  114. {
  115. u_char val;
  116. if (todc_info->sw_flags & TODC_FLAG_2_LEVEL_NVRAM) {
  117. if (addr < todc_info->nvram_size) { /* NVRAM */
  118. ppc_md.rtc_write_val(todc_info->nvram_addr_reg, addr);
  119. val = ppc_md.rtc_read_val(todc_info->nvram_data_reg);
  120. } else { /* Clock Reg */
  121. addr -= todc_info->nvram_size;
  122. val = ppc_md.rtc_read_val(addr);
  123. }
  124. } else
  125. val = ppc_md.rtc_read_val(addr);
  126. return val;
  127. }
  128. static inline void
  129. todc_write_val(int addr, u_char val)
  130. {
  131. if (todc_info->sw_flags & TODC_FLAG_2_LEVEL_NVRAM) {
  132. if (addr < todc_info->nvram_size) { /* NVRAM */
  133. ppc_md.rtc_write_val(todc_info->nvram_addr_reg, addr);
  134. ppc_md.rtc_write_val(todc_info->nvram_data_reg, val);
  135. } else { /* Clock Reg */
  136. addr -= todc_info->nvram_size;
  137. ppc_md.rtc_write_val(addr, val);
  138. }
  139. } else
  140. ppc_md.rtc_write_val(addr, val);
  141. }
  142. /*
  143. * TODC routines
  144. *
  145. * There is some ugly stuff in that there are assumptions for the mc146818.
  146. *
  147. * Assumptions:
  148. * - todc_info->control_a has the offset as mc146818 Register B reg
  149. * - todc_info->control_b has the offset as mc146818 Register A reg
  150. * - m48txx control reg's write enable or 'W' bit is same as
  151. * mc146818 Register B 'SET' bit (i.e., 0x80)
  152. *
  153. * These assumptions were made to make the code simpler.
  154. */
  155. long __init
  156. todc_time_init(void)
  157. {
  158. u_char cntl_b;
  159. if (!ppc_md.rtc_read_val)
  160. ppc_md.rtc_read_val = ppc_md.nvram_read_val;
  161. if (!ppc_md.rtc_write_val)
  162. ppc_md.rtc_write_val = ppc_md.nvram_write_val;
  163. cntl_b = todc_read_val(todc_info->control_b);
  164. if (todc_info->rtc_type == TODC_TYPE_MC146818) {
  165. if ((cntl_b & 0x70) != 0x20) {
  166. printk(KERN_INFO "TODC real-time-clock was stopped."
  167. " Now starting...");
  168. cntl_b &= ~0x70;
  169. cntl_b |= 0x20;
  170. }
  171. todc_write_val(todc_info->control_b, cntl_b);
  172. } else if (todc_info->rtc_type == TODC_TYPE_DS17285) {
  173. u_char mode;
  174. mode = todc_read_val(TODC_TYPE_DS17285_CNTL_A);
  175. /* Make sure countdown clear is not set */
  176. mode &= ~0x40;
  177. /* Enable oscillator, extended register set */
  178. mode |= 0x30;
  179. todc_write_val(TODC_TYPE_DS17285_CNTL_A, mode);
  180. } else if (todc_info->rtc_type == TODC_TYPE_DS1501) {
  181. u_char month;
  182. todc_info->enable_read = TODC_DS1501_CNTL_B_TE;
  183. todc_info->enable_write = TODC_DS1501_CNTL_B_TE;
  184. month = todc_read_val(todc_info->month);
  185. if ((month & 0x80) == 0x80) {
  186. printk(KERN_INFO "TODC %s %s\n",
  187. "real-time-clock was stopped.",
  188. "Now starting...");
  189. month &= ~0x80;
  190. todc_write_val(todc_info->month, month);
  191. }
  192. cntl_b &= ~TODC_DS1501_CNTL_B_TE;
  193. todc_write_val(todc_info->control_b, cntl_b);
  194. } else { /* must be a m48txx type */
  195. u_char cntl_a;
  196. todc_info->enable_read = TODC_MK48TXX_CNTL_A_R;
  197. todc_info->enable_write = TODC_MK48TXX_CNTL_A_W;
  198. cntl_a = todc_read_val(todc_info->control_a);
  199. /* Check & clear STOP bit in control B register */
  200. if (cntl_b & TODC_MK48TXX_DAY_CB) {
  201. printk(KERN_INFO "TODC %s %s\n",
  202. "real-time-clock was stopped.",
  203. "Now starting...");
  204. cntl_a |= todc_info->enable_write;
  205. cntl_b &= ~TODC_MK48TXX_DAY_CB;/* Start Oscil */
  206. todc_write_val(todc_info->control_a, cntl_a);
  207. todc_write_val(todc_info->control_b, cntl_b);
  208. }
  209. /* Make sure READ & WRITE bits are cleared. */
  210. cntl_a &= ~(todc_info->enable_write | todc_info->enable_read);
  211. todc_write_val(todc_info->control_a, cntl_a);
  212. }
  213. return 0;
  214. }
  215. /*
  216. * There is some ugly stuff in that there are assumptions that for a mc146818,
  217. * the todc_info->control_a has the offset of the mc146818 Register B reg and
  218. * that the register'ss 'SET' bit is the same as the m48txx's write enable
  219. * bit in the control register of the m48txx (i.e., 0x80).
  220. *
  221. * It was done to make the code look simpler.
  222. */
  223. void
  224. todc_get_rtc_time(struct rtc_time *tm)
  225. {
  226. uint year = 0, mon = 0, mday = 0, hour = 0, min = 0, sec = 0;
  227. uint limit, i;
  228. u_char save_control, uip = 0;
  229. extern void GregorianDay(struct rtc_time *);
  230. spin_lock(&rtc_lock);
  231. save_control = todc_read_val(todc_info->control_a);
  232. if (todc_info->rtc_type != TODC_TYPE_MC146818) {
  233. limit = 1;
  234. switch (todc_info->rtc_type) {
  235. case TODC_TYPE_DS1553:
  236. case TODC_TYPE_DS1557:
  237. case TODC_TYPE_DS1743:
  238. case TODC_TYPE_DS1746: /* XXXX BAD HACK -> FIX */
  239. case TODC_TYPE_DS1747:
  240. case TODC_TYPE_DS17285:
  241. break;
  242. default:
  243. todc_write_val(todc_info->control_a,
  244. (save_control | todc_info->enable_read));
  245. }
  246. } else
  247. limit = 100000000;
  248. for (i=0; i<limit; i++) {
  249. if (todc_info->rtc_type == TODC_TYPE_MC146818)
  250. uip = todc_read_val(todc_info->RTC_FREQ_SELECT);
  251. sec = todc_read_val(todc_info->seconds) & 0x7f;
  252. min = todc_read_val(todc_info->minutes) & 0x7f;
  253. hour = todc_read_val(todc_info->hours) & 0x3f;
  254. mday = todc_read_val(todc_info->day_of_month) & 0x3f;
  255. mon = todc_read_val(todc_info->month) & 0x1f;
  256. year = todc_read_val(todc_info->year) & 0xff;
  257. if (todc_info->rtc_type == TODC_TYPE_MC146818) {
  258. uip |= todc_read_val(todc_info->RTC_FREQ_SELECT);
  259. if ((uip & RTC_UIP) == 0)
  260. break;
  261. }
  262. }
  263. if (todc_info->rtc_type != TODC_TYPE_MC146818) {
  264. switch (todc_info->rtc_type) {
  265. case TODC_TYPE_DS1553:
  266. case TODC_TYPE_DS1557:
  267. case TODC_TYPE_DS1743:
  268. case TODC_TYPE_DS1746: /* XXXX BAD HACK -> FIX */
  269. case TODC_TYPE_DS1747:
  270. case TODC_TYPE_DS17285:
  271. break;
  272. default:
  273. save_control &= ~(todc_info->enable_read);
  274. todc_write_val(todc_info->control_a, save_control);
  275. }
  276. }
  277. spin_unlock(&rtc_lock);
  278. if ((todc_info->rtc_type != TODC_TYPE_MC146818)
  279. || ((save_control & RTC_DM_BINARY) == 0)
  280. || RTC_ALWAYS_BCD) {
  281. BCD_TO_BIN(sec);
  282. BCD_TO_BIN(min);
  283. BCD_TO_BIN(hour);
  284. BCD_TO_BIN(mday);
  285. BCD_TO_BIN(mon);
  286. BCD_TO_BIN(year);
  287. }
  288. if ((year + 1900) < 1970) {
  289. year += 100;
  290. }
  291. tm->tm_sec = sec;
  292. tm->tm_min = min;
  293. tm->tm_hour = hour;
  294. tm->tm_mday = mday;
  295. tm->tm_mon = mon;
  296. tm->tm_year = year;
  297. GregorianDay(tm);
  298. }
  299. int
  300. todc_set_rtc_time(struct rtc_time *tm)
  301. {
  302. u_char save_control, save_freq_select = 0;
  303. spin_lock(&rtc_lock);
  304. save_control = todc_read_val(todc_info->control_a);
  305. /* Assuming MK48T59_RTC_CA_WRITE & RTC_SET are equal */
  306. todc_write_val(todc_info->control_a,
  307. (save_control | todc_info->enable_write));
  308. save_control &= ~(todc_info->enable_write); /* in case it was set */
  309. if (todc_info->rtc_type == TODC_TYPE_MC146818) {
  310. save_freq_select = todc_read_val(todc_info->RTC_FREQ_SELECT);
  311. todc_write_val(todc_info->RTC_FREQ_SELECT,
  312. save_freq_select | RTC_DIV_RESET2);
  313. }
  314. if ((todc_info->rtc_type != TODC_TYPE_MC146818)
  315. || ((save_control & RTC_DM_BINARY) == 0)
  316. || RTC_ALWAYS_BCD) {
  317. BIN_TO_BCD(tm->tm_sec);
  318. BIN_TO_BCD(tm->tm_min);
  319. BIN_TO_BCD(tm->tm_hour);
  320. BIN_TO_BCD(tm->tm_mon);
  321. BIN_TO_BCD(tm->tm_mday);
  322. BIN_TO_BCD(tm->tm_year);
  323. }
  324. todc_write_val(todc_info->seconds, tm->tm_sec);
  325. todc_write_val(todc_info->minutes, tm->tm_min);
  326. todc_write_val(todc_info->hours, tm->tm_hour);
  327. todc_write_val(todc_info->month, tm->tm_mon);
  328. todc_write_val(todc_info->day_of_month, tm->tm_mday);
  329. todc_write_val(todc_info->year, tm->tm_year);
  330. todc_write_val(todc_info->control_a, save_control);
  331. if (todc_info->rtc_type == TODC_TYPE_MC146818)
  332. todc_write_val(todc_info->RTC_FREQ_SELECT, save_freq_select);
  333. spin_unlock(&rtc_lock);
  334. return 0;
  335. }