todc_time.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511
  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
  6. * mgreer@mvista.com
  7. *
  8. * 2001-2004 (c) MontaVista, Software, Inc. This file is licensed under
  9. * the terms of the GNU General Public License version 2. This program
  10. * is licensed "as is" without any warranty of any kind, whether express
  11. * or implied.
  12. */
  13. #include <linux/errno.h>
  14. #include <linux/init.h>
  15. #include <linux/kernel.h>
  16. #include <linux/time.h>
  17. #include <linux/timex.h>
  18. #include <linux/bcd.h>
  19. #include <linux/mc146818rtc.h>
  20. #include <asm/machdep.h>
  21. #include <asm/io.h>
  22. #include <asm/time.h>
  23. #include <asm/todc.h>
  24. /*
  25. * Depending on the hardware on your board and your board design, the
  26. * RTC/NVRAM may be accessed either directly (like normal memory) or via
  27. * address/data registers. If your board uses the direct method, set
  28. * 'nvram_data' to the base address of your nvram and leave 'nvram_as0' and
  29. * 'nvram_as1' NULL. If your board uses address/data regs to access nvram,
  30. * set 'nvram_as0' to the address of the lower byte, set 'nvram_as1' to the
  31. * address of the upper byte (leave NULL if using mc146818), and set
  32. * 'nvram_data' to the address of the 8-bit data register.
  33. *
  34. * In order to break the assumption that the RTC and NVRAM are accessed by
  35. * the same mechanism, you need to explicitly set 'ppc_md.rtc_read_val' and
  36. * 'ppc_md.rtc_write_val', otherwise the values of 'ppc_md.rtc_read_val'
  37. * and 'ppc_md.rtc_write_val' will be used.
  38. *
  39. * Note: Even though the documentation for the various RTC chips say that it
  40. * take up to a second before it starts updating once the 'R' bit is
  41. * cleared, they always seem to update even though we bang on it many
  42. * times a second. This is true, except for the Dallas Semi 1746/1747
  43. * (possibly others). Those chips seem to have a real problem whenever
  44. * we set the 'R' bit before reading them, they basically stop counting.
  45. * --MAG
  46. */
  47. /*
  48. * 'todc_info' should be initialized in your *_setup.c file to
  49. * point to a fully initialized 'todc_info_t' structure.
  50. * This structure holds all the register offsets for your particular
  51. * TODC/RTC chip.
  52. * TODC_ALLOC()/TODC_INIT() will allocate and initialize this table for you.
  53. */
  54. #ifdef RTC_FREQ_SELECT
  55. #undef RTC_FREQ_SELECT
  56. #define RTC_FREQ_SELECT control_b /* Register A */
  57. #endif
  58. #ifdef RTC_CONTROL
  59. #undef RTC_CONTROL
  60. #define RTC_CONTROL control_a /* Register B */
  61. #endif
  62. #ifdef RTC_INTR_FLAGS
  63. #undef RTC_INTR_FLAGS
  64. #define RTC_INTR_FLAGS watchdog /* Register C */
  65. #endif
  66. #ifdef RTC_VALID
  67. #undef RTC_VALID
  68. #define RTC_VALID interrupts /* Register D */
  69. #endif
  70. /* Access routines when RTC accessed directly (like normal memory) */
  71. u_char
  72. todc_direct_read_val(int addr)
  73. {
  74. return readb((void __iomem *)(todc_info->nvram_data + addr));
  75. }
  76. void
  77. todc_direct_write_val(int addr, unsigned char val)
  78. {
  79. writeb(val, (void __iomem *)(todc_info->nvram_data + addr));
  80. return;
  81. }
  82. /* Access routines for accessing m48txx type chips via addr/data regs */
  83. u_char
  84. todc_m48txx_read_val(int addr)
  85. {
  86. outb(addr, todc_info->nvram_as0);
  87. outb(addr>>todc_info->as0_bits, todc_info->nvram_as1);
  88. return inb(todc_info->nvram_data);
  89. }
  90. void
  91. todc_m48txx_write_val(int addr, unsigned char val)
  92. {
  93. outb(addr, todc_info->nvram_as0);
  94. outb(addr>>todc_info->as0_bits, todc_info->nvram_as1);
  95. outb(val, todc_info->nvram_data);
  96. return;
  97. }
  98. /* Access routines for accessing mc146818 type chips via addr/data regs */
  99. u_char
  100. todc_mc146818_read_val(int addr)
  101. {
  102. outb_p(addr, todc_info->nvram_as0);
  103. return inb_p(todc_info->nvram_data);
  104. }
  105. void
  106. todc_mc146818_write_val(int addr, unsigned char val)
  107. {
  108. outb_p(addr, todc_info->nvram_as0);
  109. outb_p(val, todc_info->nvram_data);
  110. }
  111. /*
  112. * Routines to make RTC chips with NVRAM buried behind an addr/data pair
  113. * have the NVRAM and clock regs appear at the same level.
  114. * The NVRAM will appear to start at addr 0 and the clock regs will appear
  115. * to start immediately after the NVRAM (actually, start at offset
  116. * todc_info->nvram_size).
  117. */
  118. static inline u_char
  119. todc_read_val(int addr)
  120. {
  121. u_char val;
  122. if (todc_info->sw_flags & TODC_FLAG_2_LEVEL_NVRAM) {
  123. if (addr < todc_info->nvram_size) { /* NVRAM */
  124. ppc_md.rtc_write_val(todc_info->nvram_addr_reg, addr);
  125. val = ppc_md.rtc_read_val(todc_info->nvram_data_reg);
  126. }
  127. else { /* Clock Reg */
  128. addr -= todc_info->nvram_size;
  129. val = ppc_md.rtc_read_val(addr);
  130. }
  131. }
  132. else {
  133. val = ppc_md.rtc_read_val(addr);
  134. }
  135. return val;
  136. }
  137. static inline void
  138. todc_write_val(int addr, u_char val)
  139. {
  140. if (todc_info->sw_flags & TODC_FLAG_2_LEVEL_NVRAM) {
  141. if (addr < todc_info->nvram_size) { /* NVRAM */
  142. ppc_md.rtc_write_val(todc_info->nvram_addr_reg, addr);
  143. ppc_md.rtc_write_val(todc_info->nvram_data_reg, val);
  144. }
  145. else { /* Clock Reg */
  146. addr -= todc_info->nvram_size;
  147. ppc_md.rtc_write_val(addr, val);
  148. }
  149. }
  150. else {
  151. ppc_md.rtc_write_val(addr, val);
  152. }
  153. }
  154. /*
  155. * TODC routines
  156. *
  157. * There is some ugly stuff in that there are assumptions for the mc146818.
  158. *
  159. * Assumptions:
  160. * - todc_info->control_a has the offset as mc146818 Register B reg
  161. * - todc_info->control_b has the offset as mc146818 Register A reg
  162. * - m48txx control reg's write enable or 'W' bit is same as
  163. * mc146818 Register B 'SET' bit (i.e., 0x80)
  164. *
  165. * These assumptions were made to make the code simpler.
  166. */
  167. long __init
  168. todc_time_init(void)
  169. {
  170. u_char cntl_b;
  171. if (!ppc_md.rtc_read_val)
  172. ppc_md.rtc_read_val = ppc_md.nvram_read_val;
  173. if (!ppc_md.rtc_write_val)
  174. ppc_md.rtc_write_val = ppc_md.nvram_write_val;
  175. cntl_b = todc_read_val(todc_info->control_b);
  176. if (todc_info->rtc_type == TODC_TYPE_MC146818) {
  177. if ((cntl_b & 0x70) != 0x20) {
  178. printk(KERN_INFO "TODC %s %s\n",
  179. "real-time-clock was stopped.",
  180. "Now starting...");
  181. cntl_b &= ~0x70;
  182. cntl_b |= 0x20;
  183. }
  184. todc_write_val(todc_info->control_b, cntl_b);
  185. } else if (todc_info->rtc_type == TODC_TYPE_DS17285) {
  186. u_char mode;
  187. mode = todc_read_val(TODC_TYPE_DS17285_CNTL_A);
  188. /* Make sure countdown clear is not set */
  189. mode &= ~0x40;
  190. /* Enable oscillator, extended register set */
  191. mode |= 0x30;
  192. todc_write_val(TODC_TYPE_DS17285_CNTL_A, mode);
  193. } else if (todc_info->rtc_type == TODC_TYPE_DS1501) {
  194. u_char month;
  195. todc_info->enable_read = TODC_DS1501_CNTL_B_TE;
  196. todc_info->enable_write = TODC_DS1501_CNTL_B_TE;
  197. month = todc_read_val(todc_info->month);
  198. if ((month & 0x80) == 0x80) {
  199. printk(KERN_INFO "TODC %s %s\n",
  200. "real-time-clock was stopped.",
  201. "Now starting...");
  202. month &= ~0x80;
  203. todc_write_val(todc_info->month, month);
  204. }
  205. cntl_b &= ~TODC_DS1501_CNTL_B_TE;
  206. todc_write_val(todc_info->control_b, cntl_b);
  207. } else { /* must be a m48txx type */
  208. u_char cntl_a;
  209. todc_info->enable_read = TODC_MK48TXX_CNTL_A_R;
  210. todc_info->enable_write = TODC_MK48TXX_CNTL_A_W;
  211. cntl_a = todc_read_val(todc_info->control_a);
  212. /* Check & clear STOP bit in control B register */
  213. if (cntl_b & TODC_MK48TXX_DAY_CB) {
  214. printk(KERN_INFO "TODC %s %s\n",
  215. "real-time-clock was stopped.",
  216. "Now starting...");
  217. cntl_a |= todc_info->enable_write;
  218. cntl_b &= ~TODC_MK48TXX_DAY_CB;/* Start Oscil */
  219. todc_write_val(todc_info->control_a, cntl_a);
  220. todc_write_val(todc_info->control_b, cntl_b);
  221. }
  222. /* Make sure READ & WRITE bits are cleared. */
  223. cntl_a &= ~(todc_info->enable_write |
  224. todc_info->enable_read);
  225. todc_write_val(todc_info->control_a, cntl_a);
  226. }
  227. return 0;
  228. }
  229. /*
  230. * There is some ugly stuff in that there are assumptions that for a mc146818,
  231. * the todc_info->control_a has the offset of the mc146818 Register B reg and
  232. * that the register'ss 'SET' bit is the same as the m48txx's write enable
  233. * bit in the control register of the m48txx (i.e., 0x80).
  234. *
  235. * It was done to make the code look simpler.
  236. */
  237. ulong
  238. todc_get_rtc_time(void)
  239. {
  240. uint year = 0, mon = 0, day = 0, hour = 0, min = 0, sec = 0;
  241. uint limit, i;
  242. u_char save_control, uip = 0;
  243. spin_lock(&rtc_lock);
  244. save_control = todc_read_val(todc_info->control_a);
  245. if (todc_info->rtc_type != TODC_TYPE_MC146818) {
  246. limit = 1;
  247. switch (todc_info->rtc_type) {
  248. case TODC_TYPE_DS1553:
  249. case TODC_TYPE_DS1557:
  250. case TODC_TYPE_DS1743:
  251. case TODC_TYPE_DS1746: /* XXXX BAD HACK -> FIX */
  252. case TODC_TYPE_DS1747:
  253. case TODC_TYPE_DS17285:
  254. break;
  255. default:
  256. todc_write_val(todc_info->control_a,
  257. (save_control | todc_info->enable_read));
  258. }
  259. }
  260. else {
  261. limit = 100000000;
  262. }
  263. for (i=0; i<limit; i++) {
  264. if (todc_info->rtc_type == TODC_TYPE_MC146818) {
  265. uip = todc_read_val(todc_info->RTC_FREQ_SELECT);
  266. }
  267. sec = todc_read_val(todc_info->seconds) & 0x7f;
  268. min = todc_read_val(todc_info->minutes) & 0x7f;
  269. hour = todc_read_val(todc_info->hours) & 0x3f;
  270. day = todc_read_val(todc_info->day_of_month) & 0x3f;
  271. mon = todc_read_val(todc_info->month) & 0x1f;
  272. year = todc_read_val(todc_info->year) & 0xff;
  273. if (todc_info->rtc_type == TODC_TYPE_MC146818) {
  274. uip |= todc_read_val(todc_info->RTC_FREQ_SELECT);
  275. if ((uip & RTC_UIP) == 0) break;
  276. }
  277. }
  278. if (todc_info->rtc_type != TODC_TYPE_MC146818) {
  279. switch (todc_info->rtc_type) {
  280. case TODC_TYPE_DS1553:
  281. case TODC_TYPE_DS1557:
  282. case TODC_TYPE_DS1743:
  283. case TODC_TYPE_DS1746: /* XXXX BAD HACK -> FIX */
  284. case TODC_TYPE_DS1747:
  285. case TODC_TYPE_DS17285:
  286. break;
  287. default:
  288. save_control &= ~(todc_info->enable_read);
  289. todc_write_val(todc_info->control_a,
  290. save_control);
  291. }
  292. }
  293. spin_unlock(&rtc_lock);
  294. if ((todc_info->rtc_type != TODC_TYPE_MC146818) ||
  295. ((save_control & RTC_DM_BINARY) == 0) ||
  296. RTC_ALWAYS_BCD) {
  297. BCD_TO_BIN(sec);
  298. BCD_TO_BIN(min);
  299. BCD_TO_BIN(hour);
  300. BCD_TO_BIN(day);
  301. BCD_TO_BIN(mon);
  302. BCD_TO_BIN(year);
  303. }
  304. year = year + 1900;
  305. if (year < 1970) {
  306. year += 100;
  307. }
  308. return mktime(year, mon, day, hour, min, sec);
  309. }
  310. int
  311. todc_set_rtc_time(unsigned long nowtime)
  312. {
  313. struct rtc_time tm;
  314. u_char save_control, save_freq_select = 0;
  315. spin_lock(&rtc_lock);
  316. to_tm(nowtime, &tm);
  317. save_control = todc_read_val(todc_info->control_a);
  318. /* Assuming MK48T59_RTC_CA_WRITE & RTC_SET are equal */
  319. todc_write_val(todc_info->control_a,
  320. (save_control | todc_info->enable_write));
  321. save_control &= ~(todc_info->enable_write); /* in case it was set */
  322. if (todc_info->rtc_type == TODC_TYPE_MC146818) {
  323. save_freq_select = todc_read_val(todc_info->RTC_FREQ_SELECT);
  324. todc_write_val(todc_info->RTC_FREQ_SELECT,
  325. save_freq_select | RTC_DIV_RESET2);
  326. }
  327. tm.tm_year = (tm.tm_year - 1900) % 100;
  328. if ((todc_info->rtc_type != TODC_TYPE_MC146818) ||
  329. ((save_control & RTC_DM_BINARY) == 0) ||
  330. RTC_ALWAYS_BCD) {
  331. BIN_TO_BCD(tm.tm_sec);
  332. BIN_TO_BCD(tm.tm_min);
  333. BIN_TO_BCD(tm.tm_hour);
  334. BIN_TO_BCD(tm.tm_mon);
  335. BIN_TO_BCD(tm.tm_mday);
  336. BIN_TO_BCD(tm.tm_year);
  337. }
  338. todc_write_val(todc_info->seconds, tm.tm_sec);
  339. todc_write_val(todc_info->minutes, tm.tm_min);
  340. todc_write_val(todc_info->hours, tm.tm_hour);
  341. todc_write_val(todc_info->month, tm.tm_mon);
  342. todc_write_val(todc_info->day_of_month, tm.tm_mday);
  343. todc_write_val(todc_info->year, tm.tm_year);
  344. todc_write_val(todc_info->control_a, save_control);
  345. if (todc_info->rtc_type == TODC_TYPE_MC146818) {
  346. todc_write_val(todc_info->RTC_FREQ_SELECT, save_freq_select);
  347. }
  348. spin_unlock(&rtc_lock);
  349. return 0;
  350. }
  351. /*
  352. * Manipulates read bit to reliably read seconds at a high rate.
  353. */
  354. static unsigned char __init todc_read_timereg(int addr)
  355. {
  356. unsigned char save_control = 0, val;
  357. switch (todc_info->rtc_type) {
  358. case TODC_TYPE_DS1553:
  359. case TODC_TYPE_DS1557:
  360. case TODC_TYPE_DS1746: /* XXXX BAD HACK -> FIX */
  361. case TODC_TYPE_DS1747:
  362. case TODC_TYPE_DS17285:
  363. case TODC_TYPE_MC146818:
  364. break;
  365. default:
  366. save_control = todc_read_val(todc_info->control_a);
  367. todc_write_val(todc_info->control_a,
  368. (save_control | todc_info->enable_read));
  369. }
  370. val = todc_read_val(addr);
  371. switch (todc_info->rtc_type) {
  372. case TODC_TYPE_DS1553:
  373. case TODC_TYPE_DS1557:
  374. case TODC_TYPE_DS1746: /* XXXX BAD HACK -> FIX */
  375. case TODC_TYPE_DS1747:
  376. case TODC_TYPE_DS17285:
  377. case TODC_TYPE_MC146818:
  378. break;
  379. default:
  380. save_control &= ~(todc_info->enable_read);
  381. todc_write_val(todc_info->control_a, save_control);
  382. }
  383. return val;
  384. }
  385. /*
  386. * This was taken from prep_setup.c
  387. * Use the NVRAM RTC to time a second to calibrate the decrementer.
  388. */
  389. void __init
  390. todc_calibrate_decr(void)
  391. {
  392. ulong freq;
  393. ulong tbl, tbu;
  394. long i, loop_count;
  395. u_char sec;
  396. todc_time_init();
  397. /*
  398. * Actually this is bad for precision, we should have a loop in
  399. * which we only read the seconds counter. todc_read_val writes
  400. * the address bytes on every call and this takes a lot of time.
  401. * Perhaps an nvram_wait_change method returning a time
  402. * stamp with a loop count as parameter would be the solution.
  403. */
  404. /*
  405. * Need to make sure the tbl doesn't roll over so if tbu increments
  406. * during this test, we need to do it again.
  407. */
  408. loop_count = 0;
  409. sec = todc_read_timereg(todc_info->seconds) & 0x7f;
  410. do {
  411. tbu = get_tbu();
  412. for (i = 0 ; i < 10000000 ; i++) {/* may take up to 1 second */
  413. tbl = get_tbl();
  414. if ((todc_read_timereg(todc_info->seconds) & 0x7f) != sec) {
  415. break;
  416. }
  417. }
  418. sec = todc_read_timereg(todc_info->seconds) & 0x7f;
  419. for (i = 0 ; i < 10000000 ; i++) { /* Should take 1 second */
  420. freq = get_tbl();
  421. if ((todc_read_timereg(todc_info->seconds) & 0x7f) != sec) {
  422. break;
  423. }
  424. }
  425. freq -= tbl;
  426. } while ((get_tbu() != tbu) && (++loop_count < 2));
  427. printk("time_init: decrementer frequency = %lu.%.6lu MHz\n",
  428. freq/1000000, freq%1000000);
  429. tb_ticks_per_jiffy = freq / HZ;
  430. tb_to_us = mulhwu_scale_factor(freq, 1000000);
  431. return;
  432. }