1 /*- 2 * SPDX-License-Identifier: Beerware 3 * 4 * ---------------------------------------------------------------------------- 5 * "THE BEER-WARE LICENSE" (Revision 42): 6 * <phk@FreeBSD.org> wrote this file. As long as you retain this notice you 7 * can do whatever you want with this stuff. If we meet some day, and you think 8 * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp 9 * ---------------------------------------------------------------------------- 10 * 11 * 12 * The AMD Elan sc520 is a system-on-chip gadget which is used in embedded 13 * kind of things, see www.soekris.com for instance, and it has a few quirks 14 * we need to deal with. 15 * Unfortunately we cannot identify the gadget by CPUID output because it 16 * depends on strapping options and only the stepping field may be useful 17 * and those are undocumented from AMDs side. 18 * 19 * So instead we recognize the on-chip host-PCI bridge and call back from 20 * sys/i386/pci/pci_bus.c to here if we find it. 21 * 22 * #ifdef CPU_ELAN_PPS 23 * The Elan has three general purpose counters, and when two of these 24 * are used just right they can hardware timestamp external events with 25 * approx 125 nsec resolution and +/- 125 nsec precision. 26 * 27 * Connect the signal to TMR1IN and a GPIO pin, and configure the GPIO pin 28 * with a 'P' in sysctl machdep.elan_gpio_config. 29 * 30 * The rising edge of the signal will start timer 1 counting up from 31 * zero, and when the timecounter polls for PPS, both counter 1 & 2 is 32 * read, as well as the GPIO bit. If a rising edge has happened, the 33 * contents of timer 1 which is how long time ago the edge happened, 34 * is subtracted from timer 2 to give us a "true time stamp". 35 * 36 * Echoing the PPS signal on any GPIO pin is supported (set it to 'e' 37 * or 'E' (inverted) in the sysctl) The echo signal should only be 38 * used as a visual indication, not for calibration since it suffers 39 * from 1/hz (or more) jitter which the timestamps are compensated for. 40 * #endif CPU_ELAN_PPS 41 */ 42 43 #include <sys/cdefs.h> 44 __FBSDID("$FreeBSD$"); 45 46 #include "opt_cpu.h" 47 #include <sys/param.h> 48 #include <sys/systm.h> 49 #include <sys/kernel.h> 50 #include <sys/conf.h> 51 #include <sys/eventhandler.h> 52 #include <sys/sysctl.h> 53 #include <sys/syslog.h> 54 #include <sys/timetc.h> 55 #include <sys/proc.h> 56 #include <sys/uio.h> 57 #include <sys/lock.h> 58 #include <sys/mutex.h> 59 #include <sys/malloc.h> 60 #include <sys/sysctl.h> 61 #include <sys/timepps.h> 62 #include <sys/watchdog.h> 63 64 #include <dev/led/led.h> 65 #include <machine/md_var.h> 66 #include <machine/elan_mmcr.h> 67 #include <machine/pc/bios.h> 68 69 #include <vm/vm.h> 70 #include <vm/pmap.h> 71 72 static char gpio_config[33]; 73 74 static volatile uint16_t *mmcrptr; 75 volatile struct elan_mmcr *elan_mmcr; 76 77 #ifdef CPU_ELAN_PPS 78 static struct pps_state elan_pps; 79 static volatile uint16_t *pps_ap[3]; 80 static u_int pps_a, pps_d; 81 static u_int echo_a, echo_d; 82 #endif /* CPU_ELAN_PPS */ 83 84 #ifdef CPU_SOEKRIS 85 86 static struct bios_oem bios_soekris = { 87 { 0xf0000, 0xf1000 }, 88 { 89 { "Soekris", 0, 8 }, /* Soekris Engineering. */ 90 { "net4", 0, 8 }, /* net45xx */ 91 { "comBIOS", 0, 54 }, /* comBIOS ver. 1.26a 20040819 ... */ 92 { NULL, 0, 0 }, 93 } 94 }; 95 96 #endif 97 98 static u_int led_cookie[32]; 99 static struct cdev *led_dev[32]; 100 101 static void 102 gpio_led(void *cookie, int state) 103 { 104 u_int u, v; 105 106 u = *(int *)cookie; 107 v = u & 0xffff; 108 u >>= 16; 109 if (!state) 110 v ^= 0xc; 111 mmcrptr[v / 2] = u; 112 } 113 114 static int 115 sysctl_machdep_elan_gpio_config(SYSCTL_HANDLER_ARGS) 116 { 117 u_int u, v; 118 int i, np, ne; 119 int error; 120 char buf[32]; 121 char tmp[10]; 122 123 error = SYSCTL_OUT(req, gpio_config, 33); 124 if (error != 0 || req->newptr == NULL) 125 return (error); 126 if (req->newlen != 32) 127 return (EINVAL); 128 error = SYSCTL_IN(req, buf, 32); 129 if (error != 0) 130 return (error); 131 /* Disallow any disabled pins and count pps and echo */ 132 np = ne = 0; 133 for (i = 0; i < 32; i++) { 134 if (gpio_config[i] == '-' && buf[i] == '.') 135 buf[i] = gpio_config[i]; 136 if (gpio_config[i] == '-' && buf[i] != '-') 137 return (EPERM); 138 if (buf[i] == 'P') { 139 np++; 140 if (np > 1) 141 return (EINVAL); 142 } 143 if (buf[i] == 'e' || buf[i] == 'E') { 144 ne++; 145 if (ne > 1) 146 return (EINVAL); 147 } 148 if (buf[i] != 'L' && buf[i] != 'l' 149 #ifdef CPU_ELAN_PPS 150 && buf[i] != 'P' && buf[i] != 'E' && buf[i] != 'e' 151 #endif /* CPU_ELAN_PPS */ 152 && buf[i] != '.' && buf[i] != '-') 153 return (EINVAL); 154 } 155 #ifdef CPU_ELAN_PPS 156 if (np == 0) 157 pps_a = pps_d = 0; 158 if (ne == 0) 159 echo_a = echo_d = 0; 160 #endif 161 for (i = 0; i < 32; i++) { 162 u = 1 << (i & 0xf); 163 if (i >= 16) 164 v = 2; 165 else 166 v = 0; 167 #ifdef CPU_SOEKRIS 168 if (i == 9) 169 ; 170 else 171 #endif 172 if (buf[i] != 'l' && buf[i] != 'L' && led_dev[i] != NULL) { 173 led_destroy(led_dev[i]); 174 led_dev[i] = NULL; 175 mmcrptr[(0xc2a + v) / 2] &= ~u; 176 } 177 switch (buf[i]) { 178 #ifdef CPU_ELAN_PPS 179 case 'P': 180 pps_d = u; 181 pps_a = 0xc30 + v; 182 pps_ap[0] = &mmcrptr[pps_a / 2]; 183 pps_ap[1] = &elan_mmcr->GPTMR2CNT; 184 pps_ap[2] = &elan_mmcr->GPTMR1CNT; 185 mmcrptr[(0xc2a + v) / 2] &= ~u; 186 gpio_config[i] = buf[i]; 187 break; 188 case 'e': 189 case 'E': 190 echo_d = u; 191 if (buf[i] == 'E') 192 echo_a = 0xc34 + v; 193 else 194 echo_a = 0xc38 + v; 195 mmcrptr[(0xc2a + v) / 2] |= u; 196 gpio_config[i] = buf[i]; 197 break; 198 #endif /* CPU_ELAN_PPS */ 199 case 'l': 200 case 'L': 201 if (buf[i] == 'L') 202 led_cookie[i] = (0xc34 + v) | (u << 16); 203 else 204 led_cookie[i] = (0xc38 + v) | (u << 16); 205 if (led_dev[i]) 206 break; 207 sprintf(tmp, "gpio%d", i); 208 mmcrptr[(0xc2a + v) / 2] |= u; 209 gpio_config[i] = buf[i]; 210 led_dev[i] = 211 led_create(gpio_led, &led_cookie[i], tmp); 212 break; 213 case '.': 214 gpio_config[i] = buf[i]; 215 break; 216 case '-': 217 default: 218 break; 219 } 220 } 221 return (0); 222 } 223 224 SYSCTL_OID(_machdep, OID_AUTO, elan_gpio_config, 225 CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_NEEDGIANT, NULL, 0, 226 sysctl_machdep_elan_gpio_config, "A", 227 "Elan CPU GPIO pin config"); 228 229 #ifdef CPU_ELAN_PPS 230 static void 231 elan_poll_pps(struct timecounter *tc) 232 { 233 static int state; 234 int i; 235 uint16_t u, x, y, z; 236 register_t saveintr; 237 238 /* 239 * Grab the HW state as quickly and compactly as we can. Disable 240 * interrupts to avoid measuring our interrupt service time on 241 * hw with quality clock sources. 242 */ 243 saveintr = intr_disable(); 244 x = *pps_ap[0]; /* state, must be first, see below */ 245 y = *pps_ap[1]; /* timer2 */ 246 z = *pps_ap[2]; /* timer1 */ 247 intr_restore(saveintr); 248 249 /* 250 * Order is important here. We need to check the state of the GPIO 251 * pin first, in order to avoid reading timer 1 right before the 252 * state change. Technically pps_a may be zero in which case we 253 * harmlessly read the REVID register and the contents of pps_d is 254 * of no concern. 255 */ 256 257 i = x & pps_d; 258 259 /* If state did not change or we don't have a GPIO pin, return */ 260 if (i == state || pps_a == 0) 261 return; 262 263 state = i; 264 265 /* If the state is "low", flip the echo GPIO and return. */ 266 if (!i) { 267 if (echo_a) 268 mmcrptr[(echo_a ^ 0xc) / 2] = echo_d; 269 return; 270 } 271 272 /* 273 * Subtract timer1 from timer2 to compensate for time from the 274 * edge until we read the counters. 275 */ 276 u = y - z; 277 278 pps_capture(&elan_pps); 279 elan_pps.capcount = u; 280 pps_event(&elan_pps, PPS_CAPTUREASSERT); 281 282 /* Twiddle echo bit */ 283 if (echo_a) 284 mmcrptr[echo_a / 2] = echo_d; 285 } 286 #endif /* CPU_ELAN_PPS */ 287 288 static unsigned 289 elan_get_timecount(struct timecounter *tc) 290 { 291 292 /* Read timer2, end of story */ 293 return (elan_mmcr->GPTMR2CNT); 294 } 295 296 /* 297 * The Elan CPU can be run from a number of clock frequencies, this 298 * allows you to override the default 33.3 MHZ. 299 */ 300 #ifndef CPU_ELAN_XTAL 301 #define CPU_ELAN_XTAL 33333333 302 #endif 303 304 static struct timecounter elan_timecounter = { 305 elan_get_timecount, 306 NULL, 307 0xffff, 308 CPU_ELAN_XTAL / 4, 309 "ELAN", 310 1000 311 }; 312 313 static int 314 sysctl_machdep_elan_freq(SYSCTL_HANDLER_ARGS) 315 { 316 u_int f; 317 int error; 318 319 f = elan_timecounter.tc_frequency * 4; 320 error = sysctl_handle_int(oidp, &f, 0, req); 321 if (error == 0 && req->newptr != NULL) 322 elan_timecounter.tc_frequency = (f + 3) / 4; 323 return (error); 324 } 325 326 SYSCTL_PROC(_machdep, OID_AUTO, elan_freq, 327 CTLTYPE_UINT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, 0, sizeof (u_int), 328 sysctl_machdep_elan_freq, "IU", 329 ""); 330 331 /* 332 * Positively identifying the Elan can only be done through the PCI id of 333 * the host-bridge, this function is called from i386/pci/pci_bus.c. 334 */ 335 void 336 init_AMD_Elan_sc520(void) 337 { 338 u_int new; 339 int i; 340 341 mmcrptr = pmap_mapdev(0xfffef000, 0x1000); 342 elan_mmcr = (volatile struct elan_mmcr *)mmcrptr; 343 344 /*- 345 * The i8254 is driven with a nonstandard frequency which is 346 * derived thusly: 347 * f = 32768 * 45 * 25 / 31 = 1189161.29... 348 * We use the sysctl to get the i8254 (timecounter etc) into whack. 349 */ 350 351 new = 1189161; 352 i = kernel_sysctlbyname(&thread0, "machdep.i8254_freq", 353 NULL, 0, &new, sizeof new, NULL, 0); 354 if (bootverbose || 1) 355 printf("sysctl machdep.i8254_freq=%d returns %d\n", new, i); 356 357 /* Start GP timer #2 and use it as timecounter, hz permitting */ 358 elan_mmcr->GPTMR2MAXCMPA = 0; 359 elan_mmcr->GPTMR2CTL = 0xc001; 360 361 #ifdef CPU_ELAN_PPS 362 /* Set up GP timer #1 as pps counter */ 363 elan_mmcr->CSPFS &= ~0x10; 364 elan_mmcr->GPTMR1CTL = 0x8000 | 0x4000 | 0x10 | 0x1; 365 elan_mmcr->GPTMR1MAXCMPA = 0x0; 366 elan_mmcr->GPTMR1MAXCMPB = 0x0; 367 elan_pps.ppscap |= PPS_CAPTUREASSERT; 368 pps_init(&elan_pps); 369 #endif 370 tc_init(&elan_timecounter); 371 } 372 373 static void 374 elan_watchdog(void *foo __unused, u_int spec, int *error) 375 { 376 u_int u, v, w; 377 static u_int cur; 378 379 u = spec & WD_INTERVAL; 380 if (u > 0 && u <= 35) { 381 u = imax(u - 5, 24); 382 v = 2 << (u - 24); 383 v |= 0xc000; 384 385 /* 386 * There is a bug in some silicon which prevents us from 387 * writing to the WDTMRCTL register if the GP echo mode is 388 * enabled. GP echo mode on the other hand is desirable 389 * for other reasons. Save and restore the GP echo mode 390 * around our hardware tom-foolery. 391 */ 392 w = elan_mmcr->GPECHO; 393 elan_mmcr->GPECHO = 0; 394 if (v != cur) { 395 /* Clear the ENB bit */ 396 elan_mmcr->WDTMRCTL = 0x3333; 397 elan_mmcr->WDTMRCTL = 0xcccc; 398 elan_mmcr->WDTMRCTL = 0; 399 400 /* Set new value */ 401 elan_mmcr->WDTMRCTL = 0x3333; 402 elan_mmcr->WDTMRCTL = 0xcccc; 403 elan_mmcr->WDTMRCTL = v; 404 cur = v; 405 } else { 406 /* Just reset timer */ 407 elan_mmcr->WDTMRCTL = 0xaaaa; 408 elan_mmcr->WDTMRCTL = 0x5555; 409 } 410 elan_mmcr->GPECHO = w; 411 *error = 0; 412 } else { 413 w = elan_mmcr->GPECHO; 414 elan_mmcr->GPECHO = 0; 415 elan_mmcr->WDTMRCTL = 0x3333; 416 elan_mmcr->WDTMRCTL = 0xcccc; 417 elan_mmcr->WDTMRCTL = 0x4080; 418 elan_mmcr->WDTMRCTL = w; /* XXX What does this statement do? */ 419 elan_mmcr->GPECHO = w; 420 cur = 0; 421 } 422 } 423 424 static int 425 elan_mmap(struct cdev *dev, vm_ooffset_t offset, vm_paddr_t *paddr, 426 int nprot, vm_memattr_t *memattr) 427 { 428 429 if (offset >= 0x1000) 430 return (-1); 431 *paddr = 0xfffef000; 432 return (0); 433 } 434 static int 435 elan_ioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flag, struct thread *tdr) 436 { 437 int error; 438 439 error = ENOIOCTL; 440 441 #ifdef CPU_ELAN_PPS 442 if (pps_a != 0) 443 error = pps_ioctl(cmd, arg, &elan_pps); 444 /* 445 * We only want to incur the overhead of the PPS polling if we 446 * are actually asked to timestamp. 447 */ 448 if (elan_pps.ppsparam.mode & PPS_CAPTUREASSERT) { 449 elan_timecounter.tc_poll_pps = elan_poll_pps; 450 } else { 451 elan_timecounter.tc_poll_pps = NULL; 452 } 453 if (error != ENOIOCTL) 454 return (error); 455 #endif 456 457 return(error); 458 } 459 460 static struct cdevsw elan_cdevsw = { 461 .d_version = D_VERSION, 462 .d_flags = D_NEEDGIANT, 463 .d_ioctl = elan_ioctl, 464 .d_mmap = elan_mmap, 465 .d_name = "elan", 466 }; 467 468 static void 469 elan_drvinit(void) 470 { 471 472 #ifdef CPU_SOEKRIS 473 #define BIOS_OEM_MAXLEN 72 474 static u_char bios_oem[BIOS_OEM_MAXLEN] = "\0"; 475 #endif /* CPU_SOEKRIS */ 476 477 /* If no elan found, just return */ 478 if (mmcrptr == NULL) 479 return; 480 481 printf("Elan-mmcr driver: MMCR at %p.%s\n", 482 mmcrptr, 483 #ifdef CPU_ELAN_PPS 484 " PPS support." 485 #else 486 "" 487 #endif 488 ); 489 490 make_dev(&elan_cdevsw, 0, 491 UID_ROOT, GID_WHEEL, 0600, "elan-mmcr"); 492 493 #ifdef CPU_SOEKRIS 494 if ( bios_oem_strings(&bios_soekris, bios_oem, BIOS_OEM_MAXLEN) > 0 ) 495 printf("Elan-mmcr %s\n", bios_oem); 496 497 /* Create the error LED on GPIO9 */ 498 led_cookie[9] = 0x02000c34; 499 led_dev[9] = led_create(gpio_led, &led_cookie[9], "error"); 500 501 /* Disable the unavailable GPIO pins */ 502 strcpy(gpio_config, "-----....--..--------..---------"); 503 #else /* !CPU_SOEKRIS */ 504 /* We don't know which pins are available so enable them all */ 505 strcpy(gpio_config, "................................"); 506 #endif /* CPU_SOEKRIS */ 507 508 EVENTHANDLER_REGISTER(watchdog_list, elan_watchdog, NULL, 0); 509 } 510 511 SYSINIT(elan, SI_SUB_PSEUDO, SI_ORDER_MIDDLE, elan_drvinit, NULL); 512