1 /* $OpenBSD: glx.c,v 1.10 2015/08/15 22:25:22 miod Exp $ */ 2 3 /* 4 * Copyright (c) 2009 Miodrag Vallat. 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 /* 20 * AMD CS5536 PCI Mess 21 * XXX too many hardcoded numbers... need to expand glxreg.h 22 */ 23 24 #include <sys/param.h> 25 #include <sys/systm.h> 26 #include <sys/device.h> 27 #include <sys/kernel.h> 28 29 #include <machine/bus.h> 30 31 #include <dev/pci/pcireg.h> 32 #include <dev/pci/pcivar.h> 33 #include <dev/pci/pcidevs.h> 34 35 #include <dev/pci/pciidereg.h> 36 #include <dev/pci/pciide_amd_reg.h> 37 #include <dev/usb/ehcireg.h> 38 #include <dev/usb/ohcireg.h> 39 40 #include <dev/pci/glxreg.h> 41 #include <dev/pci/glxvar.h> 42 43 #include <loongson/dev/bonitovar.h> 44 45 /* 46 * Since the purpose of this code is to present a different view of the 47 * PCI configuration space, it can not attach as a real device. 48 * (well it could, and then we'd have to attach a fake pci to it, 49 * and fake the configuration space accesses anyways - is it worth doing?) 50 * 51 * We just keep the `would-be softc' structure as global variables. 52 */ 53 54 static pci_chipset_tag_t glxbase_pc; 55 static pcitag_t glxbase_tag; 56 static int glxbase_dev; 57 58 /* MSR access through PCI configuration space */ 59 #define PCI_MSR_CTRL 0x00f0 60 #define PCI_MSR_ADDR 0x00f4 61 #define PCI_MSR_LO32 0x00f8 62 #define PCI_MSR_HI32 0x00fc 63 64 int glx_pci_read_hook(void *, pci_chipset_tag_t, pcitag_t, int, pcireg_t *); 65 int glx_pci_write_hook(void *, pci_chipset_tag_t, pcitag_t, int, pcireg_t); 66 67 pcireg_t glx_get_status(void); 68 pcireg_t glx_fn0_read(int); 69 void glx_fn0_write(int, pcireg_t); 70 pcireg_t glx_fn2_read(int); 71 void glx_fn2_write(int, pcireg_t); 72 pcireg_t glx_fn3_read(int); 73 void glx_fn3_write(int, pcireg_t); 74 pcireg_t glx_fn4_read(int); 75 void glx_fn4_write(int, pcireg_t); 76 pcireg_t glx_fn5_read(int); 77 void glx_fn5_write(int, pcireg_t); 78 pcireg_t glx_fn6_read(int); 79 void glx_fn6_write(int, pcireg_t); 80 pcireg_t glx_fn7_read(int); 81 void glx_fn7_write(int, pcireg_t); 82 83 void 84 glx_init(pci_chipset_tag_t pc, pcitag_t tag, int dev) 85 { 86 uint64_t msr; 87 88 glxbase_pc = pc; 89 glxbase_dev = dev; 90 glxbase_tag = tag; 91 92 /* 93 * Register PCI configuration hooks to make the various 94 * embedded devices visible as PCI subfunctions. 95 */ 96 97 bonito_pci_hook(pc, NULL, glx_pci_read_hook, glx_pci_write_hook); 98 99 /* 100 * Perform some Geode initialization. 101 */ 102 103 msr = rdmsr(DIVIL_BALL_OPTS); /* 0x71 */ 104 wrmsr(DIVIL_BALL_OPTS, msr | 0x01); 105 106 /* 107 * Route usb, audio and serial interrupts 108 */ 109 110 msr = rdmsr(PIC_YSEL_LOW); 111 msr &= ~(0xfUL << 8); 112 msr &= ~(0xfUL << 16); 113 msr |= 11 << 8; 114 msr |= 9 << 16; 115 wrmsr(PIC_YSEL_LOW, msr); 116 117 msr = rdmsr(PIC_YSEL_HIGH); 118 msr &= ~(0xfUL << 24); 119 msr &= ~(0xfUL << 28); 120 msr |= 4 << 24; 121 msr |= 3 << 28; 122 wrmsr(PIC_YSEL_HIGH, msr); 123 124 /* 125 * MFGPT runs on powers of two, adjust the hz value accordingly. 126 */ 127 stathz = hz = 128; 128 } 129 130 uint64_t 131 rdmsr(uint msr) 132 { 133 uint64_t lo, hi; 134 register_t sr; 135 136 #ifdef DIAGNOSTIC 137 if (glxbase_tag == 0) 138 panic("rdmsr invoked before glx initialization"); 139 #endif 140 141 sr = disableintr(); 142 pci_conf_write(glxbase_pc, glxbase_tag, PCI_MSR_ADDR, msr); 143 lo = (uint32_t)pci_conf_read(glxbase_pc, glxbase_tag, PCI_MSR_LO32); 144 hi = (uint32_t)pci_conf_read(glxbase_pc, glxbase_tag, PCI_MSR_HI32); 145 setsr(sr); 146 return (hi << 32) | lo; 147 } 148 149 void 150 wrmsr(uint msr, uint64_t value) 151 { 152 register_t sr; 153 154 #ifdef DIAGNOSTIC 155 if (glxbase_tag == 0) 156 panic("wrmsr invoked before glx initialization"); 157 #endif 158 159 sr = disableintr(); 160 pci_conf_write(glxbase_pc, glxbase_tag, PCI_MSR_ADDR, msr); 161 pci_conf_write(glxbase_pc, glxbase_tag, PCI_MSR_LO32, (uint32_t)value); 162 pci_conf_write(glxbase_pc, glxbase_tag, PCI_MSR_HI32, value >> 32); 163 setsr(sr); 164 } 165 166 int 167 glx_pci_read_hook(void *v, pci_chipset_tag_t pc, pcitag_t tag, 168 int offset, pcireg_t *data) 169 { 170 int bus, dev, fn; 171 172 /* 173 * Do not get in the way of MSR programming 174 */ 175 if (tag == glxbase_tag && offset >= PCI_MSR_CTRL) 176 return 0; 177 178 pci_decompose_tag(pc, tag, &bus, &dev, &fn); 179 if (bus != 0 || dev != glxbase_dev) 180 return 0; 181 182 *data = 0; 183 184 switch (fn) { 185 case 0: /* PCI-ISA bridge */ 186 *data = glx_fn0_read(offset); 187 break; 188 case 1: /* Flash memory */ 189 break; 190 case 2: /* IDE controller */ 191 *data = glx_fn2_read(offset); 192 break; 193 case 3: /* AC97 codec */ 194 *data = glx_fn3_read(offset); 195 break; 196 case 4: /* OHCI controller */ 197 *data = glx_fn4_read(offset); 198 break; 199 case 5: /* EHCI controller */ 200 *data = glx_fn5_read(offset); 201 break; 202 case 6: /* UDC */ 203 break; 204 case 7: /* OTG */ 205 break; 206 } 207 208 return 1; 209 } 210 211 int 212 glx_pci_write_hook(void *v, pci_chipset_tag_t pc, pcitag_t tag, 213 int offset, pcireg_t data) 214 { 215 int bus, dev, fn; 216 217 /* 218 * Do not get in the way of MSR programming 219 */ 220 if (tag == glxbase_tag && offset >= PCI_MSR_CTRL) 221 return 0; 222 223 pci_decompose_tag(pc, tag, &bus, &dev, &fn); 224 if (bus != 0 || dev != glxbase_dev) 225 return 0; 226 227 switch (fn) { 228 case 0: /* PCI-ISA bridge */ 229 glx_fn0_write(offset, data); 230 break; 231 case 1: /* Flash memory */ 232 break; 233 case 2: /* IDE controller */ 234 glx_fn2_write(offset, data); 235 break; 236 case 3: /* AC97 codec */ 237 glx_fn3_write(offset, data); 238 break; 239 case 4: /* OHCI controller */ 240 glx_fn4_write(offset, data); 241 break; 242 case 5: /* EHCI controller */ 243 glx_fn5_write(offset, data); 244 break; 245 case 6: /* USB UDC */ 246 break; 247 case 7: /* USB OTG */ 248 break; 249 } 250 251 return 1; 252 } 253 254 pcireg_t 255 glx_get_status() 256 { 257 uint64_t msr; 258 pcireg_t data; 259 260 data = 0; 261 msr = rdmsr(GLPCI_GLD_MSR_ERROR); 262 if (msr & (1UL << 5)) 263 data |= PCI_COMMAND_PARITY_ENABLE; 264 data |= PCI_STATUS_66MHZ_SUPPORT | 265 PCI_STATUS_BACKTOBACK_SUPPORT | PCI_STATUS_DEVSEL_MEDIUM; 266 if (msr & (1UL << 21)) 267 data |= PCI_STATUS_PARITY_DETECT; 268 if (msr & (1UL << 20)) 269 data |= PCI_STATUS_TARGET_TARGET_ABORT; 270 if (msr & (1UL << 17)) 271 data |= PCI_STATUS_MASTER_TARGET_ABORT; 272 if (msr & (1UL << 16)) 273 data |= PCI_STATUS_MASTER_ABORT; 274 275 return data; 276 } 277 278 /* 279 * Function 0: PCI-ISA bridge 280 */ 281 282 static pcireg_t pcib_bar_sizes[(4 + PCI_MAPREG_END - PCI_MAPREG_START) / 4] = { 283 0x008, 284 0x100, 285 0x040, 286 0x020, 287 0x080, 288 0x020 289 }; 290 291 static pcireg_t pcib_bar_values[(4 + PCI_MAPREG_END - PCI_MAPREG_START) / 4]; 292 293 static uint64_t pcib_bar_msr[(4 + PCI_MAPREG_END - PCI_MAPREG_START) / 4] = { 294 DIVIL_LBAR_SMB, 295 DIVIL_LBAR_GPIO, 296 DIVIL_LBAR_MFGPT, 297 DIVIL_LBAR_IRQ, 298 DIVIL_LBAR_PMS, 299 DIVIL_LBAR_ACPI 300 }; 301 302 pcireg_t 303 glx_fn0_read(int reg) 304 { 305 uint64_t msr; 306 pcireg_t data; 307 int index; 308 309 switch (reg) { 310 case PCI_ID_REG: 311 case PCI_SUBSYS_ID_REG: 312 data = PCI_ID_CODE(PCI_VENDOR_AMD, PCI_PRODUCT_AMD_CS5536_PCIB); 313 break; 314 case PCI_COMMAND_STATUS_REG: 315 data = glx_get_status(); 316 data |= PCI_COMMAND_MASTER_ENABLE; 317 msr = rdmsr(DIVIL_LBAR_SMB); 318 if (msr & (1UL << 32)) 319 data |= PCI_COMMAND_IO_ENABLE; 320 break; 321 case PCI_CLASS_REG: 322 msr = rdmsr(GLCP_CHIP_REV_ID); 323 data = (PCI_CLASS_BRIDGE << PCI_CLASS_SHIFT) | 324 (PCI_SUBCLASS_BRIDGE_ISA << PCI_SUBCLASS_SHIFT) | 325 (msr & PCI_REVISION_MASK); 326 break; 327 case PCI_BHLC_REG: 328 msr = rdmsr(GLPCI_CTRL); 329 data = (0x80 << PCI_HDRTYPE_SHIFT) | 330 (((msr & 0xff00000000UL) >> 32) << PCI_LATTIMER_SHIFT) | 331 (0x08 << PCI_CACHELINE_SHIFT); 332 break; 333 case PCI_MAPREG_START + 0x00: 334 case PCI_MAPREG_START + 0x04: 335 case PCI_MAPREG_START + 0x08: 336 case PCI_MAPREG_START + 0x0c: 337 case PCI_MAPREG_START + 0x10: 338 case PCI_MAPREG_START + 0x14: 339 case PCI_MAPREG_START + 0x18: 340 index = (reg - PCI_MAPREG_START) / 4; 341 if (pcib_bar_msr[index] == 0) 342 data = 0; 343 else { 344 data = pcib_bar_values[index]; 345 if (data == 0xffffffff) 346 data = PCI_MAPREG_IO_ADDR_MASK; 347 else 348 data = (pcireg_t)rdmsr(pcib_bar_msr[index]); 349 data &= ~(pcib_bar_sizes[index] - 1); 350 if (data != 0) 351 data |= PCI_MAPREG_TYPE_IO; 352 } 353 break; 354 case PCI_INTERRUPT_REG: 355 data = (0x40 << PCI_MAX_LAT_SHIFT) | 356 (PCI_INTERRUPT_PIN_NONE << PCI_INTERRUPT_PIN_SHIFT); 357 break; 358 default: 359 data = 0; 360 break; 361 } 362 363 return data; 364 } 365 366 void 367 glx_fn0_write(int reg, pcireg_t data) 368 { 369 uint64_t msr; 370 int index; 371 372 switch (reg) { 373 case PCI_COMMAND_STATUS_REG: 374 for (index = 0; index < nitems(pcib_bar_msr); index++) { 375 if (pcib_bar_msr[index] == 0) 376 continue; 377 msr = rdmsr(pcib_bar_msr[index]); 378 if (data & PCI_COMMAND_IO_ENABLE) 379 msr |= 1UL << 32; 380 else 381 msr &= ~(1UL << 32); 382 wrmsr(pcib_bar_msr[index], msr); 383 } 384 385 msr = rdmsr(GLPCI_GLD_MSR_ERROR); 386 if (data & PCI_COMMAND_PARITY_ENABLE) 387 msr |= 1UL << 5; 388 else 389 msr &= ~(1UL << 5); 390 wrmsr(GLPCI_GLD_MSR_ERROR, msr); 391 break; 392 case PCI_BHLC_REG: 393 msr = rdmsr(GLPCI_CTRL); 394 msr &= 0xff00000000UL; 395 msr |= ((uint64_t)PCI_LATTIMER(data)) << 32; 396 break; 397 case PCI_MAPREG_START + 0x00: 398 case PCI_MAPREG_START + 0x04: 399 case PCI_MAPREG_START + 0x08: 400 case PCI_MAPREG_START + 0x0c: 401 case PCI_MAPREG_START + 0x10: 402 case PCI_MAPREG_START + 0x14: 403 case PCI_MAPREG_START + 0x18: 404 index = (reg - PCI_MAPREG_START) / 4; 405 if (data == 0xffffffff) { 406 pcib_bar_values[index] = data; 407 } else if (pcib_bar_msr[index] != 0) { 408 if ((data & PCI_MAPREG_TYPE_MASK) == 409 PCI_MAPREG_TYPE_IO) { 410 data &= PCI_MAPREG_IO_ADDR_MASK; 411 data &= ~(pcib_bar_sizes[index] - 1); 412 wrmsr(pcib_bar_msr[index], 413 (0x0000f000UL << 32) | (1UL << 32) | data); 414 } else { 415 wrmsr(pcib_bar_msr[index], 0UL); 416 } 417 pcib_bar_values[index] = 0; 418 } 419 break; 420 } 421 } 422 423 /* 424 * Function 2: IDE Controller 425 */ 426 427 static pcireg_t pciide_bar_size = 0x10; 428 static pcireg_t pciide_bar_value; 429 430 pcireg_t 431 glx_fn2_read(int reg) 432 { 433 uint64_t msr; 434 pcireg_t data; 435 436 switch (reg) { 437 case PCI_ID_REG: 438 case PCI_SUBSYS_ID_REG: 439 data = PCI_ID_CODE(PCI_VENDOR_AMD, PCI_PRODUCT_AMD_CS5536_IDE); 440 break; 441 case PCI_COMMAND_STATUS_REG: 442 data = glx_get_status(); 443 data |= PCI_COMMAND_IO_ENABLE; 444 msr = rdmsr(GLIU_PAE); 445 if ((msr & (0x3 << 4)) == (0x03 << 4)) 446 data |= PCI_COMMAND_MASTER_ENABLE; 447 break; 448 case PCI_CLASS_REG: 449 msr = rdmsr(IDE_GLD_MSR_CAP); 450 data = (PCI_CLASS_MASS_STORAGE << PCI_CLASS_SHIFT) | 451 (PCI_SUBCLASS_MASS_STORAGE_IDE << PCI_SUBCLASS_SHIFT) | 452 (PCIIDE_INTERFACE_BUS_MASTER_DMA << PCI_INTERFACE_SHIFT) | 453 (msr & PCI_REVISION_MASK); 454 break; 455 case PCI_BHLC_REG: 456 msr = rdmsr(GLPCI_CTRL); 457 data = (0x00 << PCI_HDRTYPE_SHIFT) | 458 (((msr & 0xff00000000UL) >> 32) << PCI_LATTIMER_SHIFT) | 459 (0x08 << PCI_CACHELINE_SHIFT); 460 break; 461 case PCI_MAPREG_START + 0x10: 462 data = pciide_bar_value; 463 if (data == 0xffffffff) 464 data = PCI_MAPREG_IO_ADDR_MASK & ~(pciide_bar_size - 1); 465 else { 466 msr = rdmsr(IDE_IO_BAR); 467 data = msr & 0xfffffff0; 468 } 469 if (data != 0) 470 data |= PCI_MAPREG_TYPE_IO; 471 break; 472 case PCI_INTERRUPT_REG: 473 /* compat mode */ 474 data = (0x40 << PCI_MAX_LAT_SHIFT) | 475 (PCI_INTERRUPT_PIN_NONE << PCI_INTERRUPT_PIN_SHIFT); 476 break; 477 /* 478 * The following registers are used by pciide(4) 479 */ 480 case AMD756_CHANSTATUS_EN: 481 data = rdmsr(IDE_CFG); 482 break; 483 case AMD756_DATATIM: 484 data = rdmsr(IDE_DTC); 485 break; 486 case AMD756_UDMA: 487 data = rdmsr(IDE_ETC); 488 break; 489 default: 490 data = 0; 491 break; 492 } 493 494 return data; 495 } 496 497 void 498 glx_fn2_write(int reg, pcireg_t data) 499 { 500 uint64_t msr; 501 502 switch (reg) { 503 case PCI_COMMAND_STATUS_REG: 504 msr = rdmsr(GLIU_PAE); 505 if (data & PCI_COMMAND_MASTER_ENABLE) 506 msr |= 0x03 << 4; 507 else 508 msr &= ~(0x03 << 4); 509 wrmsr(GLIU_PAE, msr); 510 break; 511 case PCI_BHLC_REG: 512 msr = rdmsr(GLPCI_CTRL); 513 msr &= 0xff00000000UL; 514 msr |= ((uint64_t)PCI_LATTIMER(data)) << 32; 515 break; 516 case PCI_MAPREG_START + 0x10: 517 if (data == 0xffffffff) { 518 pciide_bar_value = data; 519 } else { 520 if ((data & PCI_MAPREG_TYPE_MASK) == 521 PCI_MAPREG_TYPE_IO) { 522 data &= PCI_MAPREG_IO_ADDR_MASK; 523 msr = (uint32_t)data & 0xfffffff0; 524 wrmsr(IDE_IO_BAR, msr); 525 } else { 526 wrmsr(IDE_IO_BAR, 0); 527 } 528 pciide_bar_value = 0; 529 } 530 break; 531 /* 532 * The following registers are used by pciide(4) 533 */ 534 case AMD756_CHANSTATUS_EN: 535 wrmsr(IDE_CFG, (uint32_t)data); 536 break; 537 case AMD756_DATATIM: 538 wrmsr(IDE_DTC, (uint32_t)data); 539 break; 540 case AMD756_UDMA: 541 wrmsr(IDE_ETC, (uint32_t)data); 542 break; 543 } 544 } 545 546 /* 547 * Function 3: AC97 Codec 548 */ 549 550 static pcireg_t ac97_bar_size = 0x80; 551 static pcireg_t ac97_bar_value; 552 553 pcireg_t 554 glx_fn3_read(int reg) 555 { 556 uint64_t msr; 557 pcireg_t data; 558 559 switch (reg) { 560 case PCI_ID_REG: 561 case PCI_SUBSYS_ID_REG: 562 data = PCI_ID_CODE(PCI_VENDOR_AMD, 563 PCI_PRODUCT_AMD_CS5536_AUDIO); 564 break; 565 case PCI_COMMAND_STATUS_REG: 566 data = glx_get_status(); 567 data |= PCI_COMMAND_IO_ENABLE; 568 msr = rdmsr(GLIU_PAE); 569 if ((msr & (0x3 << 8)) == (0x03 << 8)) 570 data |= PCI_COMMAND_MASTER_ENABLE; 571 break; 572 case PCI_CLASS_REG: 573 msr = rdmsr(ACC_GLD_MSR_CAP); 574 data = (PCI_CLASS_MULTIMEDIA << PCI_CLASS_SHIFT) | 575 (PCI_SUBCLASS_MULTIMEDIA_AUDIO << PCI_SUBCLASS_SHIFT) | 576 (msr & PCI_REVISION_MASK); 577 break; 578 case PCI_BHLC_REG: 579 msr = rdmsr(GLPCI_CTRL); 580 data = (0x00 << PCI_HDRTYPE_SHIFT) | 581 (((msr & 0xff00000000UL) >> 32) << PCI_LATTIMER_SHIFT) | 582 (0x08 << PCI_CACHELINE_SHIFT); 583 break; 584 case PCI_MAPREG_START: 585 data = ac97_bar_value; 586 if (data == 0xffffffff) 587 data = PCI_MAPREG_IO_ADDR_MASK & ~(ac97_bar_size - 1); 588 else { 589 msr = rdmsr(GLIU_IOD_BM1); 590 data = (msr >> 20) & 0x000fffff; 591 data &= (msr & 0x000fffff); 592 } 593 if (data != 0) 594 data |= PCI_MAPREG_TYPE_IO; 595 break; 596 case PCI_INTERRUPT_REG: 597 data = (0x40 << PCI_MAX_LAT_SHIFT) | 598 (PCI_INTERRUPT_PIN_A << PCI_INTERRUPT_PIN_SHIFT); 599 break; 600 default: 601 data = 0; 602 break; 603 } 604 605 return data; 606 } 607 608 void 609 glx_fn3_write(int reg, pcireg_t data) 610 { 611 uint64_t msr; 612 613 switch (reg) { 614 case PCI_COMMAND_STATUS_REG: 615 msr = rdmsr(GLIU_PAE); 616 if (data & PCI_COMMAND_MASTER_ENABLE) 617 msr |= 0x03 << 8; 618 else 619 msr &= ~(0x03 << 8); 620 wrmsr(GLIU_PAE, msr); 621 break; 622 case PCI_BHLC_REG: 623 msr = rdmsr(GLPCI_CTRL); 624 msr &= 0xff00000000UL; 625 msr |= ((uint64_t)PCI_LATTIMER(data)) << 32; 626 break; 627 case PCI_MAPREG_START: 628 if (data == 0xffffffff) { 629 ac97_bar_value = data; 630 } else { 631 if ((data & PCI_MAPREG_TYPE_MASK) == 632 PCI_MAPREG_TYPE_IO) { 633 data &= PCI_MAPREG_IO_ADDR_MASK; 634 msr = rdmsr(GLIU_IOD_BM1); 635 msr &= 0x0fffff0000000000UL; 636 msr |= 5UL << 61; /* AC97 */ 637 msr |= ((uint64_t)data & 0xfffff) << 20; 638 msr |= 0x000fffff & ~(ac97_bar_size - 1); 639 wrmsr(GLIU_IOD_BM1, msr); 640 } else { 641 wrmsr(GLIU_IOD_BM1, 0); 642 } 643 ac97_bar_value = 0; 644 } 645 break; 646 } 647 } 648 649 /* 650 * Function 4: OHCI Controller 651 */ 652 653 static pcireg_t ohci_bar_size = 0x1000; 654 static pcireg_t ohci_bar_value; 655 656 pcireg_t 657 glx_fn4_read(int reg) 658 { 659 uint64_t msr; 660 pcireg_t data; 661 662 switch (reg) { 663 case PCI_ID_REG: 664 case PCI_SUBSYS_ID_REG: 665 data = PCI_ID_CODE(PCI_VENDOR_AMD, PCI_PRODUCT_AMD_CS5536_OHCI); 666 break; 667 case PCI_COMMAND_STATUS_REG: 668 data = glx_get_status(); 669 msr = rdmsr(USB_MSR_OHCB); 670 if (msr & (1UL << 34)) 671 data |= PCI_COMMAND_MASTER_ENABLE; 672 if (msr & (1UL << 33)) 673 data |= PCI_COMMAND_MEM_ENABLE; 674 break; 675 case PCI_CLASS_REG: 676 msr = rdmsr(USB_GLD_MSR_CAP); 677 data = (PCI_CLASS_SERIALBUS << PCI_CLASS_SHIFT) | 678 (PCI_SUBCLASS_SERIALBUS_USB << PCI_SUBCLASS_SHIFT) | 679 (PCI_INTERFACE_OHCI << PCI_INTERFACE_SHIFT) | 680 (msr & PCI_REVISION_MASK); 681 break; 682 case PCI_BHLC_REG: 683 msr = rdmsr(GLPCI_CTRL); 684 data = (0x00 << PCI_HDRTYPE_SHIFT) | 685 (((msr & 0xff00000000UL) >> 32) << PCI_LATTIMER_SHIFT) | 686 (0x08 << PCI_CACHELINE_SHIFT); 687 break; 688 case PCI_MAPREG_START + 0x00: 689 data = ohci_bar_value; 690 if (data == 0xffffffff) 691 data = PCI_MAPREG_MEM_ADDR_MASK & ~(ohci_bar_size - 1); 692 else { 693 msr = rdmsr(USB_MSR_OHCB); 694 data = msr & 0xffffff00; 695 } 696 if (data != 0) 697 data |= PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT; 698 break; 699 case PCI_CAPLISTPTR_REG: 700 data = 0x40; 701 break; 702 case PCI_INTERRUPT_REG: 703 data = (0x40 << PCI_MAX_LAT_SHIFT) | 704 (PCI_INTERRUPT_PIN_A << PCI_INTERRUPT_PIN_SHIFT); 705 break; 706 case 0x40: /* USB capability pointer */ 707 data = 0; 708 break; 709 default: 710 data = 0; 711 break; 712 } 713 714 return data; 715 } 716 717 void 718 glx_fn4_write(int reg, pcireg_t data) 719 { 720 uint64_t msr; 721 722 switch (reg) { 723 case PCI_COMMAND_STATUS_REG: 724 msr = rdmsr(USB_MSR_OHCB); 725 if (data & PCI_COMMAND_MASTER_ENABLE) 726 msr |= 1UL << 34; 727 else 728 msr &= ~(1UL << 34); 729 if (data & PCI_COMMAND_MEM_ENABLE) 730 msr |= 1UL << 33; 731 else 732 msr &= ~(1UL << 33); 733 wrmsr(USB_MSR_OHCB, msr); 734 break; 735 case PCI_BHLC_REG: 736 msr = rdmsr(GLPCI_CTRL); 737 msr &= 0xff00000000UL; 738 msr |= ((uint64_t)PCI_LATTIMER(data)) << 32; 739 break; 740 case PCI_MAPREG_START + 0x00: 741 if (data == 0xffffffff) { 742 ohci_bar_value = data; 743 } else { 744 if ((data & PCI_MAPREG_TYPE_MASK) == 745 PCI_MAPREG_TYPE_MEM) { 746 data &= PCI_MAPREG_MEM_ADDR_MASK; 747 msr = rdmsr(GLIU_P2D_BM3); 748 msr &= 0x0fffff0000000000UL; 749 msr |= 2UL << 61; /* USB */ 750 msr |= (((uint64_t)data) >> 12) << 20; 751 msr |= 0x000fffff; 752 wrmsr(GLIU_P2D_BM3, msr); 753 754 msr = rdmsr(USB_MSR_OHCB); 755 msr &= ~0xffffff00UL; 756 msr |= data; 757 } else { 758 msr = rdmsr(USB_MSR_OHCB); 759 msr &= ~0xffffff00UL; 760 } 761 wrmsr(USB_MSR_OHCB, msr); 762 ohci_bar_value = 0; 763 } 764 break; 765 default: 766 break; 767 } 768 } 769 770 /* 771 * Function 5: EHCI Controller 772 */ 773 774 static pcireg_t ehci_bar_size = 0x1000; 775 static pcireg_t ehci_bar_value; 776 777 pcireg_t 778 glx_fn5_read(int reg) 779 { 780 uint64_t msr; 781 pcireg_t data; 782 783 switch (reg) { 784 case PCI_ID_REG: 785 case PCI_SUBSYS_ID_REG: 786 data = PCI_ID_CODE(PCI_VENDOR_AMD, PCI_PRODUCT_AMD_CS5536_EHCI); 787 break; 788 case PCI_COMMAND_STATUS_REG: 789 data = glx_get_status(); 790 msr = rdmsr(USB_MSR_EHCB); 791 if (msr & (1UL << 34)) 792 data |= PCI_COMMAND_MASTER_ENABLE; 793 if (msr & (1UL << 33)) 794 data |= PCI_COMMAND_MEM_ENABLE; 795 break; 796 case PCI_CLASS_REG: 797 msr = rdmsr(USB_GLD_MSR_CAP); 798 data = (PCI_CLASS_SERIALBUS << PCI_CLASS_SHIFT) | 799 (PCI_SUBCLASS_SERIALBUS_USB << PCI_SUBCLASS_SHIFT) | 800 (PCI_INTERFACE_EHCI << PCI_INTERFACE_SHIFT) | 801 (msr & PCI_REVISION_MASK); 802 break; 803 case PCI_BHLC_REG: 804 msr = rdmsr(GLPCI_CTRL); 805 data = (0x00 << PCI_HDRTYPE_SHIFT) | 806 (((msr & 0xff00000000UL) >> 32) << PCI_LATTIMER_SHIFT) | 807 (0x08 << PCI_CACHELINE_SHIFT); 808 break; 809 case PCI_MAPREG_START + 0x00: 810 data = ehci_bar_value; 811 if (data == 0xffffffff) 812 data = PCI_MAPREG_MEM_ADDR_MASK & ~(ehci_bar_size - 1); 813 else { 814 msr = rdmsr(USB_MSR_EHCB); 815 data = msr & 0xffffff00; 816 } 817 if (data != 0) 818 data |= PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT; 819 break; 820 case PCI_CAPLISTPTR_REG: 821 data = 0x40; 822 break; 823 case PCI_INTERRUPT_REG: 824 data = (0x40 << PCI_MAX_LAT_SHIFT) | 825 (PCI_INTERRUPT_PIN_A << PCI_INTERRUPT_PIN_SHIFT); 826 break; 827 case 0x40: /* USB capability pointer */ 828 data = 0; 829 break; 830 case PCI_USBREV: 831 msr = rdmsr(USB_MSR_EHCB); 832 data = PCI_USBREV_2_0; 833 data |= ((msr >> 40) & 0x3f) << 8; /* PCI_EHCI_FLADJ */ 834 break; 835 default: 836 data = 0; 837 break; 838 } 839 840 return data; 841 } 842 843 void 844 glx_fn5_write(int reg, pcireg_t data) 845 { 846 uint64_t msr; 847 848 switch (reg) { 849 case PCI_COMMAND_STATUS_REG: 850 msr = rdmsr(USB_MSR_EHCB); 851 if (data & PCI_COMMAND_MASTER_ENABLE) 852 msr |= 1UL << 34; 853 else 854 msr &= ~(1UL << 34); 855 if (data & PCI_COMMAND_MEM_ENABLE) 856 msr |= 1UL << 33; 857 else 858 msr &= ~(1UL << 33); 859 wrmsr(USB_MSR_EHCB, msr); 860 break; 861 case PCI_BHLC_REG: 862 msr = rdmsr(GLPCI_CTRL); 863 msr &= 0xff00000000UL; 864 msr |= ((uint64_t)PCI_LATTIMER(data)) << 32; 865 break; 866 case PCI_MAPREG_START + 0x00: 867 if (data == 0xffffffff) { 868 ehci_bar_value = data; 869 } else { 870 if ((data & PCI_MAPREG_TYPE_MASK) == 871 PCI_MAPREG_TYPE_MEM) { 872 data &= PCI_MAPREG_MEM_ADDR_MASK; 873 msr = rdmsr(GLIU_P2D_BM4); 874 msr &= 0x0fffff0000000000UL; 875 msr |= 2UL << 61; /* USB */ 876 msr |= (((uint64_t)data) >> 12) << 20; 877 msr |= 0x000fffff; 878 wrmsr(GLIU_P2D_BM4, msr); 879 880 msr = rdmsr(USB_MSR_EHCB); 881 msr &= ~0xffffff00UL; 882 msr |= data; 883 } else { 884 msr = rdmsr(USB_MSR_EHCB); 885 msr &= ~0xffffff00UL; 886 } 887 wrmsr(USB_MSR_EHCB, msr); 888 ehci_bar_value = 0; 889 } 890 break; 891 default: 892 break; 893 } 894 } 895