1/* MN10300 RTC management 2 * 3 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. 4 * Written by David Howells (dhowells@redhat.com) 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public Licence 8 * as published by the Free Software Foundation; either version 9 * 2 of the Licence, or (at your option) any later version. 10 */ 11#include <linux/kernel.h> 12#include <linux/module.h> 13#include <linux/init.h> 14#include <linux/mc146818rtc.h> 15#include <linux/bcd.h> 16#include <linux/timex.h> 17#include <asm/rtc-regs.h> 18#include <asm/rtc.h> 19 20DEFINE_SPINLOCK(rtc_lock); 21EXPORT_SYMBOL(rtc_lock); 22 23/* time for RTC to update itself in ioclks */ 24static unsigned long mn10300_rtc_update_period; 25 26void read_persistent_clock(struct timespec *ts) 27{ 28 struct rtc_time tm; 29 30 get_rtc_time(&tm); 31 32 ts->tv_sec = mktime(tm.tm_year, tm.tm_mon, tm.tm_mday, 33 tm.tm_hour, tm.tm_min, tm.tm_sec); 34 ts->tv_nsec = 0; 35} 36 37/* 38 * In order to set the CMOS clock precisely, set_rtc_mmss has to be called 500 39 * ms after the second nowtime has started, because when nowtime is written 40 * into the registers of the CMOS clock, it will jump to the next second 41 * precisely 500 ms later. Check the Motorola MC146818A or Dallas DS12887 data 42 * sheet for details. 43 * 44 * BUG: This routine does not handle hour overflow properly; it just 45 * sets the minutes. Usually you'll only notice that after reboot! 46 */ 47static int set_rtc_mmss(unsigned long nowtime) 48{ 49 unsigned char save_control, save_freq_select; 50 int retval = 0; 51 int real_seconds, real_minutes, cmos_minutes; 52 53 /* gets recalled with irq locally disabled */ 54 spin_lock(&rtc_lock); 55 save_control = CMOS_READ(RTC_CONTROL); /* tell the clock it's being 56 * set */ 57 CMOS_WRITE(save_control | RTC_SET, RTC_CONTROL); 58 59 save_freq_select = CMOS_READ(RTC_FREQ_SELECT); /* stop and reset 60 * prescaler */ 61 CMOS_WRITE(save_freq_select | RTC_DIV_RESET2, RTC_FREQ_SELECT); 62 63 cmos_minutes = CMOS_READ(RTC_MINUTES); 64 if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) 65 cmos_minutes = bcd2bin(cmos_minutes); 66 67 /* 68 * since we're only adjusting minutes and seconds, 69 * don't interfere with hour overflow. This avoids 70 * messing with unknown time zones but requires your 71 * RTC not to be off by more than 15 minutes 72 */ 73 real_seconds = nowtime % 60; 74 real_minutes = nowtime / 60; 75 if (((abs(real_minutes - cmos_minutes) + 15) / 30) & 1) 76 /* correct for half hour time zone */ 77 real_minutes += 30; 78 real_minutes %= 60; 79 80 if (abs(real_minutes - cmos_minutes) < 30) { 81 if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { 82 real_seconds = bin2bcd(real_seconds); 83 real_minutes = bin2bcd(real_minutes); 84 } 85 CMOS_WRITE(real_seconds, RTC_SECONDS); 86 CMOS_WRITE(real_minutes, RTC_MINUTES); 87 } else { 88 printk(KERN_WARNING 89 "set_rtc_mmss: can't update from %d to %d\n", 90 cmos_minutes, real_minutes); 91 retval = -1; 92 } 93 94 /* The following flags have to be released exactly in this order, 95 * otherwise the DS12887 (popular MC146818A clone with integrated 96 * battery and quartz) will not reset the oscillator and will not 97 * update precisely 500 ms later. You won't find this mentioned in 98 * the Dallas Semiconductor data sheets, but who believes data 99 * sheets anyway ... -- Markus Kuhn 100 */ 101 CMOS_WRITE(save_control, RTC_CONTROL); 102 CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT); 103 spin_unlock(&rtc_lock); 104 105 return retval; 106} 107 108int update_persistent_clock(struct timespec now) 109{ 110 return set_rtc_mmss(now.tv_sec); 111} 112 113/* 114 * calibrate the TSC clock against the RTC 115 */ 116void __init calibrate_clock(void) 117{ 118 unsigned long count0, counth, count1; 119 unsigned char status; 120 121 /* make sure the RTC is running and is set to operate in 24hr mode */ 122 status = RTSRC; 123 RTCRB |= RTCRB_SET; 124 RTCRB |= RTCRB_TM_24HR; 125 RTCRA |= RTCRA_DVR; 126 RTCRA &= ~RTCRA_DVR; 127 RTCRB &= ~RTCRB_SET; 128 129 /* work out the clock speed by counting clock cycles between ends of 130 * the RTC update cycle - track the RTC through one complete update 131 * cycle (1 second) 132 */ 133 startup_timestamp_counter(); 134 135 while (!(RTCRA & RTCRA_UIP)) {} 136 while ((RTCRA & RTCRA_UIP)) {} 137 138 count0 = TMTSCBC; 139 140 while (!(RTCRA & RTCRA_UIP)) {} 141 142 counth = TMTSCBC; 143 144 while ((RTCRA & RTCRA_UIP)) {} 145 146 count1 = TMTSCBC; 147 148 shutdown_timestamp_counter(); 149 150 MN10300_TSCCLK = count0 - count1; /* the timers count down */ 151 mn10300_rtc_update_period = counth - count1; 152 MN10300_TSC_PER_HZ = MN10300_TSCCLK / HZ; 153} 154