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