1/* 2 * Copyright (C) 2000, 2001 Broadcom Corporation 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License 6 * as published by the Free Software Foundation; either version 2 7 * of the License, or (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 */ 18 19/* 20 * Time routines for the swarm board. We pass all the hard stuff 21 * through to the sb1250 handling code. Only thing we really keep 22 * track of here is what time of day we think it is. And we don't 23 * really even do a good job of that... 24 */ 25 26 27#include <linux/bcd.h> 28#include <linux/init.h> 29#include <linux/time.h> 30#include <linux/sched.h> 31#include <linux/spinlock.h> 32#include <asm/system.h> 33#include <asm/addrspace.h> 34#include <asm/io.h> 35 36#include <asm/sibyte/sb1250.h> 37#include <asm/sibyte/sb1250_regs.h> 38#include <asm/sibyte/sb1250_smbus.h> 39 40static unsigned long long sec_bias = 0; 41static unsigned int usec_bias = 0; 42 43/* Xicor 1241 definitions */ 44 45/* 46 * Register bits 47 */ 48 49#define X1241REG_SR_BAT 0x80 /* currently on battery power */ 50#define X1241REG_SR_RWEL 0x04 /* r/w latch is enabled, can write RTC */ 51#define X1241REG_SR_WEL 0x02 /* r/w latch is unlocked, can enable r/w now */ 52#define X1241REG_SR_RTCF 0x01 /* clock failed */ 53#define X1241REG_BL_BP2 0x80 /* block protect 2 */ 54#define X1241REG_BL_BP1 0x40 /* block protect 1 */ 55#define X1241REG_BL_BP0 0x20 /* block protect 0 */ 56#define X1241REG_BL_WD1 0x10 57#define X1241REG_BL_WD0 0x08 58#define X1241REG_HR_MIL 0x80 /* military time format */ 59 60/* 61 * Register numbers 62 */ 63 64#define X1241REG_BL 0x10 /* block protect bits */ 65#define X1241REG_INT 0x11 /* */ 66#define X1241REG_SC 0x30 /* Seconds */ 67#define X1241REG_MN 0x31 /* Minutes */ 68#define X1241REG_HR 0x32 /* Hours */ 69#define X1241REG_DT 0x33 /* Day of month */ 70#define X1241REG_MO 0x34 /* Month */ 71#define X1241REG_YR 0x35 /* Year */ 72#define X1241REG_DW 0x36 /* Day of Week */ 73#define X1241REG_Y2K 0x37 /* Year 2K */ 74#define X1241REG_SR 0x3F /* Status register */ 75 76#define X1241_CCR_ADDRESS 0x6F 77 78#define SMB_CSR(reg) (IOADDR(A_SMB_REGISTER(1, reg))) 79 80static int xicor_read(uint8_t addr) 81{ 82 while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY) 83 ; 84 85 __raw_writeq((addr >> 8) & 0x7, SMB_CSR(R_SMB_CMD)); 86 __raw_writeq(addr & 0xff, SMB_CSR(R_SMB_DATA)); 87 __raw_writeq(V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR2BYTE, 88 SMB_CSR(R_SMB_START)); 89 90 while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY) 91 ; 92 93 __raw_writeq(V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_RD1BYTE, 94 SMB_CSR(R_SMB_START)); 95 96 while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY) 97 ; 98 99 if (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) { 100 /* Clear error bit by writing a 1 */ 101 __raw_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS)); 102 return -1; 103 } 104 105 return (__raw_readq(SMB_CSR(R_SMB_DATA)) & 0xff); 106} 107 108static int xicor_write(uint8_t addr, int b) 109{ 110 while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY) 111 ; 112 113 __raw_writeq(addr, SMB_CSR(R_SMB_CMD)); 114 __raw_writeq((addr & 0xff) | ((b & 0xff) << 8), SMB_CSR(R_SMB_DATA)); 115 __raw_writeq(V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR3BYTE, 116 SMB_CSR(R_SMB_START)); 117 118 while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY) 119 ; 120 121 if (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) { 122 /* Clear error bit by writing a 1 */ 123 __raw_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS)); 124 return -1; 125 } else { 126 return 0; 127 } 128} 129 130/* 131 * In order to set the CMOS clock precisely, set_rtc_mmss has to be 132 * called 500 ms after the second nowtime has started, because when 133 * nowtime is written into the registers of the CMOS clock, it will 134 * jump to the next second precisely 500 ms later. Check the Motorola 135 * MC146818A or Dallas DS12887 data sheet for details. 136 * 137 * BUG: This routine does not handle hour overflow properly; it just 138 * sets the minutes. Usually you'll only notice that after reboot! 139 */ 140int set_rtc_mmss(unsigned long nowtime) 141{ 142 int retval = 0; 143 int real_seconds, real_minutes, cmos_minutes; 144 145 cmos_minutes = xicor_read(X1241REG_MN); 146 cmos_minutes = BCD2BIN(cmos_minutes); 147 148 /* 149 * since we're only adjusting minutes and seconds, 150 * don't interfere with hour overflow. This avoids 151 * messing with unknown time zones but requires your 152 * RTC not to be off by more than 15 minutes 153 */ 154 real_seconds = nowtime % 60; 155 real_minutes = nowtime / 60; 156 if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1) 157 real_minutes += 30; /* correct for half hour time zone */ 158 real_minutes %= 60; 159 160 /* unlock writes to the CCR */ 161 xicor_write(X1241REG_SR, X1241REG_SR_WEL); 162 xicor_write(X1241REG_SR, X1241REG_SR_WEL | X1241REG_SR_RWEL); 163 164 if (abs(real_minutes - cmos_minutes) < 30) { 165 real_seconds = BIN2BCD(real_seconds); 166 real_minutes = BIN2BCD(real_minutes); 167 xicor_write(X1241REG_SC, real_seconds); 168 xicor_write(X1241REG_MN, real_minutes); 169 } else { 170 printk(KERN_WARNING 171 "set_rtc_mmss: can't update from %d to %d\n", 172 cmos_minutes, real_minutes); 173 retval = -1; 174 } 175 176 xicor_write(X1241REG_SR, 0); 177 178 printk("set_rtc_mmss: %02d:%02d\n", real_minutes, real_seconds); 179 180 return retval; 181} 182 183static unsigned long __init get_swarm_time(void) 184{ 185 unsigned int year, mon, day, hour, min, sec, y2k; 186 187 sec = xicor_read(X1241REG_SC); 188 min = xicor_read(X1241REG_MN); 189 hour = xicor_read(X1241REG_HR); 190 191 if (hour & X1241REG_HR_MIL) { 192 hour &= 0x3f; 193 } else { 194 if (hour & 0x20) 195 hour = (hour & 0xf) + 0x12; 196 } 197 198 sec = BCD2BIN(sec); 199 min = BCD2BIN(min); 200 hour = BCD2BIN(hour); 201 202 day = xicor_read(X1241REG_DT); 203 mon = xicor_read(X1241REG_MO); 204 year = xicor_read(X1241REG_YR); 205 y2k = xicor_read(X1241REG_Y2K); 206 207 day = BCD2BIN(day); 208 mon = BCD2BIN(mon); 209 year = BCD2BIN(year); 210 y2k = BCD2BIN(y2k); 211 212 year += (y2k * 100); 213 214 return mktime(year, mon, day, hour, min, sec); 215} 216 217/* 218 * Bring up the timer at 100 Hz. 219 */ 220void __init swarm_time_init(void) 221{ 222 unsigned int flags; 223 int status; 224 225 /* Set up the scd general purpose timer 0 to cpu 0 */ 226 sb1250_time_init(); 227 228 /* Establish communication with the Xicor 1241 RTC */ 229 /* XXXKW how do I share the SMBus with the I2C subsystem? */ 230 231 __raw_writeq(K_SMB_FREQ_400KHZ, SMB_CSR(R_SMB_FREQ)); 232 __raw_writeq(0, SMB_CSR(R_SMB_CONTROL)); 233 234 if ((status = xicor_read(X1241REG_SR_RTCF)) < 0) { 235 printk("x1241: couldn't detect on SWARM SMBus 1\n"); 236 } else { 237 if (status & X1241REG_SR_RTCF) 238 printk("x1241: battery failed -- time is probably wrong\n"); 239 write_seqlock_irqsave(&xtime_lock, flags); 240 xtime.tv_sec = get_swarm_time(); 241 xtime.tv_nsec = 0; 242 write_sequnlock_irqrestore(&xtime_lock, flags); 243 } 244} 245