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