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