1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 /* 29 * tod driver module for TI BQ4802 part 30 * 31 * Note: The way to access the bq4802's RTC registers is different than 32 * the previous RTC devices (m5823, m5819p, ds1287, etc) that we used. 33 * The address returns from OBP is mapped directly to the bq4802's RTC 34 * registers. To read/write the data from/to the bq4802 registers, one 35 * just add the register offset to the base address. 36 * To access the previous RTC devices, we write the register index to 37 * the address port (v_rtc_addr_reg) then read/write the data from/to 38 * the data port (v_rtc_data_reg). 39 */ 40 41 #include <sys/types.h> 42 #include <sys/conf.h> 43 #include <sys/kmem.h> 44 #include <sys/open.h> 45 #include <sys/ddi.h> 46 #include <sys/sunddi.h> 47 #include <sys/sysmacros.h> 48 49 #include <sys/todbq4802.h> 50 #include <sys/modctl.h> 51 #include <sys/stat.h> 52 #include <sys/clock.h> 53 #include <sys/reboot.h> 54 #include <sys/machsystm.h> 55 56 /* 57 * tod_ops entry routines 58 */ 59 static timestruc_t todbq4802_get(void); 60 static void todbq4802_set(timestruc_t); 61 static uint_t todbq4802_set_watchdog_timer(uint_t); 62 static uint_t todbq4802_clear_watchdog_timer(void); 63 static void todbq4802_set_power_alarm(timestruc_t); 64 static void todbq4802_clear_power_alarm(void); 65 static uint64_t todbq4802_get_cpufrequency(void); 66 67 extern uint64_t find_cpufrequency(volatile uint8_t *); 68 69 /* 70 * External variables 71 */ 72 extern int watchdog_enable; 73 extern int watchdog_available; 74 extern int boothowto; 75 76 /* 77 * Global variables 78 */ 79 int bq4802_debug_flags; 80 uint_t bq4802_hrestime_count = 0; 81 uint_t bq4802_uip_count = 0; 82 83 /* 84 * Module linkage information for the kernel. 85 */ 86 static struct modlmisc modlmisc = { 87 &mod_miscops, "tod module for TI BQ4802" 88 }; 89 90 static struct modlinkage modlinkage = { 91 MODREV_1, (void *)&modlmisc, NULL 92 }; 93 94 static void read_rtc(struct rtc_t *); 95 static void write_rtc_time(struct rtc_t *); 96 static void write_rtc_alarm(struct rtc_t *); 97 98 int 99 _init(void) 100 { 101 if (strcmp(tod_module_name, "todbq4802") == 0) { 102 if (v_rtc_addr_reg == NULL) 103 cmn_err(CE_PANIC, "addr not set, cannot read RTC\n"); 104 105 BQ4802_DATA_REG(RTC_CNTRL) = (RTC_HM | RTC_STOP_N); 106 107 /* Clear AF flag by reading reg Flags (D) */ 108 (void) BQ4802_DATA_REG(RTC_FLAGS); 109 110 tod_ops.tod_get = todbq4802_get; 111 tod_ops.tod_set = todbq4802_set; 112 tod_ops.tod_set_watchdog_timer = 113 todbq4802_set_watchdog_timer; 114 tod_ops.tod_clear_watchdog_timer = 115 todbq4802_clear_watchdog_timer; 116 tod_ops.tod_set_power_alarm = todbq4802_set_power_alarm; 117 tod_ops.tod_clear_power_alarm = todbq4802_clear_power_alarm; 118 tod_ops.tod_get_cpufrequency = todbq4802_get_cpufrequency; 119 120 /* 121 * check if hardware watchdog timer is available and user 122 * enabled it. 123 */ 124 if (watchdog_enable) { 125 if (!watchdog_available) { 126 cmn_err(CE_WARN, "bq4802: Hardware watchdog " 127 "unavailable"); 128 } else if (boothowto & RB_DEBUG) { 129 cmn_err(CE_WARN, "bq4802: Hardware watchdog" 130 " disabled [debugger]"); 131 } 132 } 133 } 134 135 return (mod_install(&modlinkage)); 136 } 137 138 int 139 _fini(void) 140 { 141 if (strcmp(tod_module_name, "todbq4802") == 0) 142 return (EBUSY); 143 144 return (mod_remove(&modlinkage)); 145 } 146 147 /* 148 * The loadable-module _info(9E) entry point 149 */ 150 int 151 _info(struct modinfo *modinfop) 152 { 153 return (mod_info(&modlinkage, modinfop)); 154 } 155 156 /* 157 * Read the current time from the clock chip and convert to UNIX form. 158 * Assumes that the year in the clock chip is valid. 159 * Must be called with tod_lock held. 160 */ 161 static timestruc_t 162 todbq4802_get(void) 163 { 164 timestruc_t ts; 165 todinfo_t tod; 166 struct rtc_t rtc; 167 168 ASSERT(MUTEX_HELD(&tod_lock)); 169 170 read_rtc(&rtc); 171 DPRINTF("todbq4802_get: century=%d year=%d dom=%d hrs=%d min=%d" 172 " sec=%d\n", rtc.rtc_century, rtc.rtc_year, rtc.rtc_dom, 173 rtc.rtc_hrs, rtc.rtc_min, rtc.rtc_sec); 174 175 /* 176 * tod_year is base 1900 so this code needs to adjust the true 177 * year retrieved from the rtc's century and year fields. 178 */ 179 tod.tod_year = rtc.rtc_year + (rtc.rtc_century * 100) - 1900; 180 tod.tod_month = rtc.rtc_mon; 181 tod.tod_day = rtc.rtc_dom; 182 tod.tod_dow = rtc.rtc_dow; 183 tod.tod_hour = rtc.rtc_hrs; 184 tod.tod_min = rtc.rtc_min; 185 tod.tod_sec = rtc.rtc_sec; 186 187 ts.tv_sec = tod_to_utc(tod); 188 ts.tv_nsec = 0; 189 return (ts); 190 } 191 192 /* 193 * Once every second, the user-accessible clock/calendar 194 * locations are updated simultaneously from the internal 195 * real-time counters. To prevent reading data in transition, 196 * updates to the bq4802 clock registers should be halted. 197 * Updating is halted by setting the Update Transfer Inhibit 198 * (UTI) bit D3 of the control register E. As long as the 199 * UTI bit is 1, updates to user-accessible clock locations are 200 * inhibited. Once the frozen clock information is retrieved by 201 * reading the appropriate clock memory locations, the UTI 202 * bit should be reset to 0 in order to allow updates to occur 203 * from the internal counters. Because the internal counters 204 * are not halted by setting the UTI bit, reading the clock 205 * locations has no effect on clock accuracy. Once the UTI bit 206 * is reset to 0, the internal registers update within one 207 * second the user-accessible registers with the correct time. 208 * A halt command issued during a clock update allows the 209 * update to occur before freezing the data. 210 */ 211 static void 212 read_rtc(struct rtc_t *rtc) 213 { 214 uint8_t reg_cntrl; 215 216 /* 217 * Freeze 218 */ 219 reg_cntrl = BQ4802_DATA_REG(RTC_CNTRL); 220 BQ4802_DATA_REG(RTC_CNTRL) = (reg_cntrl | RTC_UTI); 221 222 rtc->rtc_sec = BCD_TO_BYTE(BQ4802_DATA_REG(RTC_SEC)); 223 rtc->rtc_asec = BCD_TO_BYTE(BQ4802_DATA_REG(RTC_ASEC)); 224 rtc->rtc_min = BCD_TO_BYTE(BQ4802_DATA_REG(RTC_MIN)); 225 rtc->rtc_amin = BCD_TO_BYTE(BQ4802_DATA_REG(RTC_AMIN)); 226 rtc->rtc_hrs = BCD_TO_BYTE(BQ4802_DATA_REG(RTC_HRS)); 227 rtc->rtc_ahrs = BCD_TO_BYTE(BQ4802_DATA_REG(RTC_AHRS)); 228 rtc->rtc_dom = BCD_TO_BYTE(BQ4802_DATA_REG(RTC_DOM)); 229 rtc->rtc_adom = BCD_TO_BYTE(BQ4802_DATA_REG(RTC_ADOM)); 230 rtc->rtc_dow = BCD_TO_BYTE(BQ4802_DATA_REG(RTC_DOW)); 231 rtc->rtc_mon = BCD_TO_BYTE(BQ4802_DATA_REG(RTC_MON)); 232 rtc->rtc_year = BCD_TO_BYTE(BQ4802_DATA_REG(RTC_YEAR)); 233 rtc->rtc_century = BCD_TO_BYTE(BQ4802_DATA_REG(RTC_CENTURY)); 234 235 /* 236 * Unfreeze 237 */ 238 BQ4802_DATA_REG(RTC_CNTRL) = reg_cntrl; 239 } 240 241 /* 242 * Write the specified time into the clock chip. 243 * Must be called with tod_lock held. 244 */ 245 static void 246 todbq4802_set(timestruc_t ts) 247 { 248 struct rtc_t rtc; 249 todinfo_t tod = utc_to_tod(ts.tv_sec); 250 int year; 251 252 ASSERT(MUTEX_HELD(&tod_lock)); 253 254 /* tod_year is base 1900 so this code needs to adjust */ 255 year = 1900 + tod.tod_year; 256 rtc.rtc_year = year % 100; 257 rtc.rtc_century = year / 100; 258 rtc.rtc_mon = (uint8_t)tod.tod_month; 259 rtc.rtc_dom = (uint8_t)tod.tod_day; 260 rtc.rtc_dow = (uint8_t)tod.tod_dow; 261 rtc.rtc_hrs = (uint8_t)tod.tod_hour; 262 rtc.rtc_min = (uint8_t)tod.tod_min; 263 rtc.rtc_sec = (uint8_t)tod.tod_sec; 264 DPRINTF("todbq4802_set: year=%d dom=%d hrs=%d min=%d sec=%d\n", 265 rtc.rtc_year, rtc.rtc_dom, rtc.rtc_hrs, rtc.rtc_min, rtc.rtc_sec); 266 267 write_rtc_time(&rtc); 268 } 269 270 /* 271 * The UTI bit must be used to set the bq4802 clock. 272 * Once set, the locations can be written with the desired 273 * information in BCD format. Resetting the UTI bit to 0 causes 274 * the written values to be transferred to the internal clock 275 * counters and allows updates to the user-accessible registers 276 * to resume within one second. 277 */ 278 void 279 write_rtc_time(struct rtc_t *rtc) 280 { 281 uint8_t reg_cntrl; 282 283 /* 284 * Freeze 285 */ 286 reg_cntrl = BQ4802_DATA_REG(RTC_CNTRL); 287 BQ4802_DATA_REG(RTC_CNTRL) = (reg_cntrl | RTC_UTI); 288 289 BQ4802_DATA_REG(RTC_SEC) = BYTE_TO_BCD(rtc->rtc_sec); 290 BQ4802_DATA_REG(RTC_MIN) = BYTE_TO_BCD(rtc->rtc_min); 291 BQ4802_DATA_REG(RTC_HRS) = BYTE_TO_BCD(rtc->rtc_hrs); 292 BQ4802_DATA_REG(RTC_DOM) = BYTE_TO_BCD(rtc->rtc_dom); 293 BQ4802_DATA_REG(RTC_DOW) = BYTE_TO_BCD(rtc->rtc_dow); 294 BQ4802_DATA_REG(RTC_MON) = BYTE_TO_BCD(rtc->rtc_mon); 295 BQ4802_DATA_REG(RTC_YEAR) = BYTE_TO_BCD(rtc->rtc_year); 296 BQ4802_DATA_REG(RTC_CENTURY) = BYTE_TO_BCD(rtc->rtc_century); 297 298 /* 299 * Unfreeze 300 */ 301 BQ4802_DATA_REG(RTC_CNTRL) = reg_cntrl; 302 } 303 304 void 305 write_rtc_alarm(struct rtc_t *rtc) 306 { 307 BQ4802_DATA_REG(RTC_ASEC) = BYTE_TO_BCD(rtc->rtc_asec); 308 BQ4802_DATA_REG(RTC_AMIN) = BYTE_TO_BCD(rtc->rtc_amin); 309 BQ4802_DATA_REG(RTC_AHRS) = BYTE_TO_BCD(rtc->rtc_ahrs); 310 BQ4802_DATA_REG(RTC_ADOM) = BYTE_TO_BCD(rtc->rtc_adom); 311 } 312 313 /* 314 * program the rtc registers for alarm to go off at the specified time 315 */ 316 static void 317 todbq4802_set_power_alarm(timestruc_t ts) 318 { 319 todinfo_t tod; 320 uint8_t regc; 321 struct rtc_t rtc; 322 323 ASSERT(MUTEX_HELD(&tod_lock)); 324 tod = utc_to_tod(ts.tv_sec); 325 326 /* 327 * disable alarms and clear AF flag by reading reg Flags (D) 328 */ 329 regc = BQ4802_DATA_REG(RTC_ENABLES); 330 BQ4802_DATA_REG(RTC_ENABLES) = regc & ~(RTC_AIE | RTC_ABE); 331 (void) BQ4802_DATA_REG(RTC_FLAGS); 332 333 rtc.rtc_asec = (uint8_t)tod.tod_sec; 334 rtc.rtc_amin = (uint8_t)tod.tod_min; 335 rtc.rtc_ahrs = (uint8_t)tod.tod_hour; 336 rtc.rtc_adom = (uint8_t)tod.tod_day; 337 DPRINTF("todbq4802_set_alarm: dom=%d hrs=%d min=%d sec=%d\n", 338 rtc.rtc_adom, rtc.rtc_ahrs, rtc.rtc_amin, rtc.rtc_asec); 339 340 /* 341 * Write alarm values and enable alarm 342 */ 343 write_rtc_alarm(&rtc); 344 345 BQ4802_DATA_REG(RTC_ENABLES) = regc | RTC_AIE | RTC_ABE; 346 } 347 348 /* 349 * clear alarm interrupt 350 */ 351 static void 352 todbq4802_clear_power_alarm(void) 353 { 354 uint8_t regc; 355 356 ASSERT(MUTEX_HELD(&tod_lock)); 357 358 regc = BQ4802_DATA_REG(RTC_ENABLES); 359 BQ4802_DATA_REG(RTC_ENABLES) = regc & ~(RTC_AIE | RTC_ABE); 360 } 361 362 /* 363 * Determine the cpu frequency by watching the TOD chip rollover twice. 364 * Cpu clock rate is determined by computing the ticks added (in tick register) 365 * during one second interval on TOD. 366 */ 367 uint64_t 368 todbq4802_get_cpufrequency(void) 369 { 370 ASSERT(MUTEX_HELD(&tod_lock)); 371 return (find_cpufrequency((volatile uint8_t *)v_rtc_addr_reg)); 372 } 373 374 /*ARGSUSED*/ 375 static uint_t 376 todbq4802_set_watchdog_timer(uint_t timeoutval) 377 { 378 ASSERT(MUTEX_HELD(&tod_lock)); 379 return (0); 380 } 381 382 static uint_t 383 todbq4802_clear_watchdog_timer(void) 384 { 385 ASSERT(MUTEX_HELD(&tod_lock)); 386 return (0); 387 } 388