1 /* $NetBSD: rtc.c,v 1.2 2017/07/24 09:56:45 mrg Exp $ */ 2 3 /* 4 * Copyright 2002 Wasabi Systems, Inc. 5 * All rights reserved. 6 * 7 * Written by Simon Burge for Wasabi Systems, Inc. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. All advertising materials mentioning features or use of this software 18 * must display the following acknowledgement: 19 * This product includes software developed for the NetBSD Project by 20 * Wasabi Systems, Inc. 21 * 4. The name of Wasabi Systems, Inc. may not be used to endorse 22 * or promote products derived from this software without specific prior 23 * written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND 26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 27 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 28 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC 29 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35 * POSSIBILITY OF SUCH DAMAGE. 36 */ 37 38 #include <sys/cdefs.h> 39 __KERNEL_RCSID(0, "$NetBSD: rtc.c,v 1.2 2017/07/24 09:56:45 mrg Exp $"); 40 41 #include <sys/param.h> 42 #include <sys/device.h> 43 #include <sys/kernel.h> 44 #include <sys/systm.h> 45 #include <sys/cpu.h> 46 47 #include <dev/clock_subr.h> 48 49 #include <evbmips/sbmips/swarm.h> 50 #include <evbmips/sbmips/systemsw.h> 51 52 #include <mips/locore.h> 53 #include <mips/sibyte/dev/sbsmbusvar.h> 54 55 #include <dev/smbus/m41t81reg.h> 56 #include <dev/smbus/x1241reg.h> 57 58 struct rtc_softc { 59 device_t sc_dev; 60 int sc_smbus_chan; 61 int sc_smbus_addr; 62 int sc_type; 63 struct todr_chip_handle sc_ct; 64 }; 65 66 /* "types" for RTCs we support */ 67 #define SMB_1BYTE_ADDR 1 68 #define SMB_2BYTE_ADDR 2 69 70 static int xirtc_match(device_t, cfdata_t , void *); 71 static void xirtc_attach(device_t, device_t, void *); 72 static int xirtc_gettime(todr_chip_handle_t, struct clock_ymdhms *); 73 static int xirtc_settime(todr_chip_handle_t, struct clock_ymdhms *); 74 75 static int strtc_match(device_t, cfdata_t , void *); 76 static void strtc_attach(device_t, device_t, void *); 77 static int strtc_gettime(todr_chip_handle_t, struct clock_ymdhms *); 78 static int strtc_settime(todr_chip_handle_t, struct clock_ymdhms *); 79 80 static void rtc_cal_timer(void); 81 82 static void time_smbus_init(int); 83 static int time_waitready(int); 84 static int time_readrtc(int, int, int, int); 85 static int time_writertc(int, int, int, int, int); 86 87 #define WRITERTC(sc, dev, val) \ 88 time_writertc((sc)->sc_smbus_chan, (sc)->sc_smbus_addr, (dev), (sc)->sc_type, (val)) 89 #define READRTC(sc, dev) \ 90 time_readrtc((sc)->sc_smbus_chan, (sc)->sc_smbus_addr, (dev), (sc)->sc_type) 91 92 93 CFATTACH_DECL_NEW(xirtc, sizeof(struct rtc_softc), 94 xirtc_match, xirtc_attach, NULL, NULL); 95 96 CFATTACH_DECL_NEW(m41t81rtc, sizeof(struct rtc_softc), 97 strtc_match, strtc_attach, NULL, NULL); 98 99 static int rtcfound = 0; 100 struct rtc_softc *the_rtc; 101 102 /* 103 * Xicor X1241 RTC support. 104 */ 105 static int 106 xirtc_match(device_t parent, cfdata_t cf, void *aux) 107 { 108 struct smbus_attach_args *sa = aux; 109 int ret; 110 111 time_smbus_init(sa->sa_interface); 112 113 if ((sa->sa_interface != X1241_SMBUS_CHAN) || 114 (sa->sa_device != X1241_RTC_SLAVEADDR)) 115 return (0); 116 117 ret = time_readrtc(sa->sa_interface, sa->sa_device, SMB_2BYTE_ADDR, X1241REG_SC); 118 if (ret < 0) 119 return (0); 120 121 return (!rtcfound); 122 } 123 124 static void 125 xirtc_attach(device_t parent, device_t self, void *aux) 126 { 127 struct smbus_attach_args *sa = aux; 128 struct rtc_softc *sc = device_private(self); 129 130 rtcfound = 1; 131 the_rtc = sc; 132 133 sc->sc_dev = self; 134 sc->sc_smbus_chan = sa->sa_interface; 135 sc->sc_smbus_addr = sa->sa_device; 136 sc->sc_type = SMB_2BYTE_ADDR; /* Two-byte register addresses on the Xicor */ 137 138 139 /* Set up MI todr(9) stuff */ 140 sc->sc_ct.cookie = sc; 141 sc->sc_ct.todr_settime_ymdhms = xirtc_settime; 142 sc->sc_ct.todr_gettime_ymdhms = xirtc_gettime; 143 144 todr_attach(&sc->sc_ct); 145 146 aprint_normal("\n"); 147 rtc_cal_timer(); /* XXX */ 148 } 149 150 static int 151 xirtc_settime(todr_chip_handle_t handle, struct clock_ymdhms *ymdhms) 152 { 153 struct rtc_softc *sc = handle->cookie; 154 uint8_t year, y2k; 155 156 time_smbus_init(sc->sc_smbus_chan); 157 158 /* unlock writes to the CCR */ 159 WRITERTC(sc, X1241REG_SR, X1241REG_SR_WEL); 160 WRITERTC(sc, X1241REG_SR, X1241REG_SR_WEL | X1241REG_SR_RWEL); 161 162 /* set the time */ 163 WRITERTC(sc, X1241REG_HR, bintobcd(ymdhms->dt_hour) | X1241REG_HR_MIL); 164 WRITERTC(sc, X1241REG_MN, bintobcd(ymdhms->dt_min)); 165 WRITERTC(sc, X1241REG_SC, bintobcd(ymdhms->dt_sec)); 166 167 /* set the date */ 168 y2k = (ymdhms->dt_year >= 2000) ? 0x20 : 0x19; 169 year = ymdhms->dt_year % 100; 170 171 WRITERTC(sc, X1241REG_MO, bintobcd(ymdhms->dt_mon)); 172 WRITERTC(sc, X1241REG_DT, bintobcd(ymdhms->dt_day)); 173 WRITERTC(sc, X1241REG_YR, bintobcd(year)); 174 WRITERTC(sc, X1241REG_Y2K, bintobcd(y2k)); 175 176 /* lock writes again */ 177 WRITERTC(sc, X1241REG_SR, 0); 178 179 return (0); 180 } 181 182 static int 183 xirtc_gettime(todr_chip_handle_t handle, struct clock_ymdhms *ymdhms) 184 { 185 struct rtc_softc *sc = handle->cookie; 186 uint8_t hour, year, y2k; 187 uint8_t status; 188 189 time_smbus_init(sc->sc_smbus_chan); 190 ymdhms->dt_day = bcdtobin(READRTC(sc, X1241REG_DT)); 191 ymdhms->dt_mon = bcdtobin(READRTC(sc, X1241REG_MO)); 192 year = READRTC(sc, X1241REG_YR); 193 y2k = READRTC(sc, X1241REG_Y2K); 194 ymdhms->dt_year = bcdtobin(y2k) * 100 + bcdtobin(year); 195 196 197 ymdhms->dt_sec = bcdtobin(READRTC(sc, X1241REG_SC)); 198 ymdhms->dt_min = bcdtobin(READRTC(sc, X1241REG_MN)); 199 hour = READRTC(sc, X1241REG_HR); 200 ymdhms->dt_hour = bcdtobin(hour & ~X1241REG_HR_MIL); 201 202 status = READRTC(sc, X1241REG_SR); 203 204 if (status & X1241REG_SR_RTCF) { 205 printf("%s: battery has failed, clock setting is not accurate\n", 206 device_xname(sc->sc_dev)); 207 return (EIO); 208 } 209 210 return (0); 211 } 212 213 /* 214 * ST M41T81 RTC support. 215 */ 216 static int 217 strtc_match(device_t parent, cfdata_t cf, void *aux) 218 { 219 struct smbus_attach_args *sa = aux; 220 int ret; 221 222 if ((sa->sa_interface != M41T81_SMBUS_CHAN) || 223 (sa->sa_device != M41T81_SLAVEADDR)) 224 return (0); 225 226 time_smbus_init(sa->sa_interface); 227 228 ret = time_readrtc(sa->sa_interface, sa->sa_device, SMB_1BYTE_ADDR, M41T81_SEC); 229 if (ret < 0) 230 return (0); 231 232 return (!rtcfound); 233 } 234 235 static void 236 strtc_attach(device_t parent, device_t self, void *aux) 237 { 238 struct smbus_attach_args *sa = aux; 239 struct rtc_softc *sc = device_private(self); 240 241 rtcfound = 1; 242 the_rtc = sc; 243 244 sc->sc_dev = self; 245 sc->sc_smbus_chan = sa->sa_interface; 246 sc->sc_smbus_addr = sa->sa_device; 247 sc->sc_type = SMB_1BYTE_ADDR; /* One-byte register addresses on the ST */ 248 249 /* Set up MI todr(9) stuff */ 250 sc->sc_ct.cookie = sc; 251 sc->sc_ct.todr_settime_ymdhms = strtc_settime; 252 sc->sc_ct.todr_gettime_ymdhms = strtc_gettime; 253 254 todr_attach(&sc->sc_ct); 255 256 aprint_normal("\n"); 257 rtc_cal_timer(); /* XXX */ 258 } 259 260 static int 261 strtc_settime(todr_chip_handle_t handle, struct clock_ymdhms *ymdhms) 262 { 263 struct rtc_softc *sc = handle->cookie; 264 uint8_t hour; 265 266 time_smbus_init(sc->sc_smbus_chan); 267 268 hour = bintobcd(ymdhms->dt_hour); 269 if (ymdhms->dt_year >= 2000) /* Should be always true! */ 270 hour |= M41T81_HOUR_CB | M41T81_HOUR_CEB; 271 272 /* set the time */ 273 WRITERTC(sc, M41T81_SEC, bintobcd(ymdhms->dt_sec)); 274 WRITERTC(sc, M41T81_MIN, bintobcd(ymdhms->dt_min)); 275 WRITERTC(sc, M41T81_HOUR, hour); 276 277 /* set the date */ 278 WRITERTC(sc, M41T81_DATE, bintobcd(ymdhms->dt_day)); 279 WRITERTC(sc, M41T81_MON, bintobcd(ymdhms->dt_mon)); 280 WRITERTC(sc, M41T81_YEAR, bintobcd(ymdhms->dt_year % 100)); 281 282 return (0); 283 } 284 285 static int 286 strtc_gettime(todr_chip_handle_t handle, struct clock_ymdhms *ymdhms) 287 { 288 struct rtc_softc *sc = handle->cookie; 289 uint8_t hour; 290 291 time_smbus_init(sc->sc_smbus_chan); 292 293 ymdhms->dt_sec = bcdtobin(READRTC(sc, M41T81_SEC)); 294 ymdhms->dt_min = bcdtobin(READRTC(sc, M41T81_MIN)); 295 hour = READRTC(sc, M41T81_HOUR & M41T81_HOUR_MASK); 296 ymdhms->dt_hour = bcdtobin(hour & M41T81_HOUR_MASK); 297 298 ymdhms->dt_day = bcdtobin(READRTC(sc, M41T81_DATE)); 299 ymdhms->dt_mon = bcdtobin(READRTC(sc, M41T81_MON)); 300 ymdhms->dt_year = 1900 + bcdtobin(READRTC(sc, M41T81_YEAR)); 301 if (hour & M41T81_HOUR_CB) 302 ymdhms->dt_year += 100; 303 304 return (0); 305 } 306 307 #define NITERS 3 308 #define RTC_SECONDS(rtc) bcdtobin(READRTC((rtc), X1241REG_SC)) 309 310 /* 311 * Since it takes so long to read the complete time/date values from 312 * the RTC over the SMBus, we only read the seconds value. 313 * Later versions of the SWARM will hopefully have the RTC interrupt 314 * attached so we can do the clock calibration much more quickly and 315 * with a higher resolution. 316 */ 317 static void 318 rtc_cal_timer(void) 319 { 320 uint32_t ctrdiff[NITERS], startctr, endctr; 321 int sec, lastsec, i; 322 323 if (rtcfound == 0) { 324 printf("rtc_cal_timer before rtc attached\n"); 325 return; 326 } 327 return; /* XXX XXX */ 328 329 printf("%s: calibrating CPU clock", device_xname(the_rtc->sc_dev)); 330 331 /* 332 * Run the loop an extra time to wait for the second to tick over 333 * and to prime the cache. 334 */ 335 time_smbus_init(the_rtc->sc_smbus_chan); 336 sec = RTC_SECONDS(the_rtc); 337 endctr = mips3_cp0_count_read(); 338 339 for (i = 0; i < NITERS; i++) { 340 int diff; 341 342 again: 343 lastsec = sec; 344 startctr = endctr; 345 346 /* Wait for the timer to tick over. */ 347 do { 348 // time_smbus_init(the_rtc->sc_smbus_chan); 349 sec = RTC_SECONDS(the_rtc); 350 } while (lastsec == sec); 351 endctr = mips3_cp0_count_read(); 352 353 diff = sec - lastsec; 354 if (diff < 0) 355 diff += 60; 356 357 /* Sometimes we appear to skip a second. Clock jitter? */ 358 if (diff > 1) 359 goto again; 360 361 if (endctr < startctr) 362 ctrdiff[i] = 0xffffffff - startctr + endctr; 363 else 364 ctrdiff[i] = endctr - startctr; 365 } 366 printf("\n"); 367 368 /* Compute the number of cycles per second. */ 369 curcpu()->ci_cpu_freq = ((ctrdiff[1] + ctrdiff[2]) / 2); 370 371 /* Compute the delay divisor. */ 372 curcpu()->ci_divisor_delay = curcpu()->ci_cpu_freq / 1000000; 373 374 /* Compute clock cycles per hz */ 375 curcpu()->ci_cycles_per_hz = curcpu()->ci_cpu_freq / hz; 376 377 printf("%s: timer calibration: %lu cycles/sec [(%u, %u)]\n", 378 device_xname(the_rtc->sc_dev), curcpu()->ci_cpu_freq, 379 ctrdiff[1], ctrdiff[2]); 380 } 381 #undef RTC_SECONDS 382 383 /* XXX eville direct-access-to-the-device code follows... */ 384 385 /* 386 * Copyright 2000,2001 387 * Broadcom Corporation. All rights reserved. 388 * 389 * This software is furnished under license and may be used and copied only 390 * in accordance with the following terms and conditions. Subject to these 391 * conditions, you may download, copy, install, use, modify and distribute 392 * modified or unmodified copies of this software in source and/or binary 393 * form. No title or ownership is transferred hereby. 394 * 395 * 1) Any source code used, modified or distributed must reproduce and 396 * retain this copyright notice and list of conditions as they appear in 397 * the source file. 398 * 399 * 2) No right is granted to use any trade name, trademark, or logo of 400 * Broadcom Corporation. The "Broadcom Corporation" name may not be 401 * used to endorse or promote products derived from this software 402 * without the prior written permission of Broadcom Corporation. 403 * 404 * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR IMPLIED 405 * WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED WARRANTIES OF 406 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR 407 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM BE LIABLE 408 * FOR ANY DAMAGES WHATSOEVER, AND IN PARTICULAR, BROADCOM SHALL NOT BE 409 * LIABLE FOR DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 410 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 411 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 412 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 413 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 414 * OR OTHERWISE), EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 415 */ 416 417 #include <mips/sibyte/include/sb1250_regs.h> 418 #include <mips/sibyte/include/sb1250_smbus.h> 419 420 #define READ_REG(rp) mips3_ld((register_t)(MIPS_PHYS_TO_KSEG1(rp))) 421 #define WRITE_REG(rp, val) mips3_sd((register_t)(MIPS_PHYS_TO_KSEG1(rp)), (val)) 422 423 static void 424 time_smbus_init(int chan) 425 { 426 uint32_t reg; 427 428 reg = A_SMB_REGISTER(chan, R_SMB_FREQ); 429 WRITE_REG(reg, K_SMB_FREQ_100KHZ); 430 reg = A_SMB_REGISTER(chan, R_SMB_CONTROL); 431 WRITE_REG(reg, 0); /* not in direct mode, no interrupts, will poll */ 432 } 433 434 static int 435 time_waitready(int chan) 436 { 437 uint32_t reg; 438 uint64_t status; 439 440 reg = A_SMB_REGISTER(chan, R_SMB_STATUS); 441 442 for (;;) { 443 status = READ_REG(reg); 444 if (status & M_SMB_BUSY) 445 continue; 446 break; 447 } 448 449 if (status & M_SMB_ERROR) { 450 WRITE_REG(reg, (status & M_SMB_ERROR)); 451 return (-1); 452 } 453 return (0); 454 } 455 456 static int 457 time_readrtc(int chan, int slaveaddr, int devaddr, int type) 458 { 459 uint32_t reg; 460 int err; 461 462 /* 463 * Make sure the bus is idle (probably should 464 * ignore error here) 465 */ 466 467 if (time_waitready(chan) < 0) 468 return (-1); 469 470 if (type == SMB_2BYTE_ADDR) { 471 /* 472 * Write the device address to the controller. There are two 473 * parts, the high part goes in the "CMD" field, and the 474 * low part is the data field. 475 */ 476 477 reg = A_SMB_REGISTER(chan, R_SMB_CMD); 478 WRITE_REG(reg, (devaddr >> 8) & 0x7); 479 480 /* 481 * Write the data to the controller 482 */ 483 484 reg = A_SMB_REGISTER(chan, R_SMB_DATA); 485 WRITE_REG(reg, (devaddr & 0xff) & 0xff); 486 } else { /* SMB_1BYTE_ADDR */ 487 /* 488 * Write the device address to the controller. 489 */ 490 491 reg = A_SMB_REGISTER(chan, R_SMB_CMD); 492 WRITE_REG(reg, devaddr & 0xff); 493 } 494 495 /* 496 * Start the command 497 */ 498 499 reg = A_SMB_REGISTER(chan, R_SMB_START); 500 if (type == SMB_2BYTE_ADDR) 501 WRITE_REG(reg, V_SMB_TT(K_SMB_TT_WR2BYTE) | V_SMB_ADDR(slaveaddr)); 502 else /* SMB_1BYTE_ADDR */ 503 WRITE_REG(reg, V_SMB_TT(K_SMB_TT_WR1BYTE) | V_SMB_ADDR(slaveaddr)); 504 505 /* 506 * Wait till done 507 */ 508 509 err = time_waitready(chan); 510 if (err < 0) 511 return (err); 512 513 /* 514 * Read the data byte 515 */ 516 517 WRITE_REG(reg, V_SMB_TT(K_SMB_TT_RD1BYTE) | V_SMB_ADDR(slaveaddr)); 518 519 err = time_waitready(chan); 520 if (err < 0) 521 return (err); 522 523 reg = A_SMB_REGISTER(chan, R_SMB_DATA); 524 err = READ_REG(reg); 525 526 return (err & 0xff); 527 } 528 529 static int 530 time_writertc(int chan, int slaveaddr, int devaddr, int type, int b) 531 { 532 uint32_t reg; 533 int err, timer; 534 535 /* 536 * Make sure the bus is idle (probably should 537 * ignore error here) 538 */ 539 540 if (time_waitready(chan) < 0) 541 return (-1); 542 543 /* 544 * Write the device address to the controller. There are two 545 * parts, the high part goes in the "CMD" field, and the 546 * low part is the data field. 547 */ 548 549 reg = A_SMB_REGISTER(chan, R_SMB_CMD); 550 if (type == SMB_2BYTE_ADDR) 551 WRITE_REG(reg, (devaddr >> 8) & 0x7); 552 else /* SMB_1BYTE_ADDR */ 553 WRITE_REG(reg, devaddr & 0xff); 554 555 /* 556 * Write the data to the controller 557 */ 558 559 reg = A_SMB_REGISTER(chan, R_SMB_DATA); 560 if (type == SMB_2BYTE_ADDR) 561 WRITE_REG(reg, (devaddr & 0xff) | ((b & 0xff) << 8)); 562 else /* SMB_1BYTE_ADDR */ 563 WRITE_REG(reg, b & 0xff); 564 565 /* 566 * Start the command. Keep pounding on the device until it 567 * submits or the timer expires, whichever comes first. The 568 * datasheet says writes can take up to 10ms, so we'll give it 500. 569 */ 570 571 reg = A_SMB_REGISTER(chan, R_SMB_START); 572 if (type == SMB_2BYTE_ADDR) 573 WRITE_REG(reg, V_SMB_TT(K_SMB_TT_WR3BYTE) | V_SMB_ADDR(slaveaddr)); 574 else /* SMB_1BYTE_ADDR */ 575 WRITE_REG(reg, V_SMB_TT(K_SMB_TT_WR2BYTE) | V_SMB_ADDR(slaveaddr)); 576 577 /* 578 * Wait till the SMBus interface is done 579 */ 580 581 err = time_waitready(chan); 582 if (err < 0) 583 return (err); 584 585 /* 586 * Pound on the device with a current address read 587 * to poll for the write complete 588 */ 589 590 err = -1; 591 timer = 100000000; /* XXX */ 592 593 while (timer-- > 0) { 594 WRITE_REG(reg, V_SMB_TT(K_SMB_TT_RD1BYTE) | V_SMB_ADDR(slaveaddr)); 595 596 err = time_waitready(chan); 597 if (err == 0) 598 break; 599 } 600 601 return (err); 602 } 603