1 /* $NetBSD: glx.c,v 1.5 2015/10/02 05:22:50 msaitoh 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.5 2015/10/02 05:22:50 msaitoh 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 intialization. 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 ((data & PCI_MAPREG_TYPE_MASK) == 464 PCI_MAPREG_TYPE_IO) { 465 data &= PCI_MAPREG_IO_ADDR_MASK; 466 data &= ~(pcib_bar_sizes[index] - 1); 467 wrmsr(pcib_bar_msr[index], 468 (0x0000f000ULL << 32) | (1ULL << 32) | data); 469 } else { 470 wrmsr(pcib_bar_msr[index], 0ULL); 471 } 472 pcib_bar_values[index] = 0; 473 } 474 break; 475 } 476 } 477 478 /* 479 * Function 2: IDE Controller 480 */ 481 482 static pcireg_t pciide_bar_size = 0x10; 483 static pcireg_t pciide_bar_value; 484 485 pcireg_t 486 glx_fn2_read(int reg) 487 { 488 uint64_t msr; 489 pcireg_t data; 490 491 switch (reg) { 492 case PCI_ID_REG: 493 case PCI_SUBSYS_ID_REG: 494 data = PCI_ID_CODE(PCI_VENDOR_AMD, PCI_PRODUCT_AMD_CS5536_IDE); 495 break; 496 case PCI_COMMAND_STATUS_REG: 497 data = glx_get_status(); 498 data |= PCI_COMMAND_IO_ENABLE; 499 msr = rdmsr(GCSC_GLIU_PAE); 500 if ((msr & (0x3 << 4)) == (0x3 << 4)) 501 data |= PCI_COMMAND_MASTER_ENABLE; 502 break; 503 case PCI_CLASS_REG: 504 msr = rdmsr(GCSC_IDE_GLD_MSR_CAP); 505 data = (PCI_CLASS_MASS_STORAGE << PCI_CLASS_SHIFT) | 506 (PCI_SUBCLASS_MASS_STORAGE_IDE << PCI_SUBCLASS_SHIFT) | 507 (PCIIDE_INTERFACE_BUS_MASTER_DMA << PCI_INTERFACE_SHIFT) | 508 (msr & PCI_REVISION_MASK); 509 break; 510 case PCI_BHLC_REG: 511 msr = rdmsr(GCSC_GLPCI_CTRL); 512 data = (0x00 << PCI_HDRTYPE_SHIFT) | 513 (((msr & 0xff00000000ULL) >> 32) << PCI_LATTIMER_SHIFT) | 514 (0x08 << PCI_CACHELINE_SHIFT); 515 break; 516 case PCI_MAPREG_START + 0x10: 517 data = pciide_bar_value; 518 if (data == 0xffffffff) 519 data = PCI_MAPREG_IO_ADDR_MASK & ~(pciide_bar_size - 1); 520 else { 521 msr = rdmsr(GCSC_IDE_IO_BAR); 522 data = msr & 0xfffffff0; 523 } 524 if (data != 0) 525 data |= PCI_MAPREG_TYPE_IO; 526 break; 527 case PCI_INTERRUPT_REG: 528 /* compat mode */ 529 data = (0x40 << PCI_MAX_LAT_SHIFT) | 530 (PCI_INTERRUPT_PIN_NONE << PCI_INTERRUPT_PIN_SHIFT); 531 break; 532 /* 533 * The following registers are used by pciide(4) 534 */ 535 case PCIIDE_CHANSTATUS_EN: 536 data = rdmsr(GCSC_IDE_CFG); 537 break; 538 case /* AMD756_DATATIM XXX */ 0x48: 539 data = rdmsr(GCSC_IDE_DTC); 540 break; 541 case /* AMD756_UDMA XXX*/ 0x50: 542 data = rdmsr(GCSC_IDE_ETC); 543 break; 544 default: 545 DPRINTF(("unimplemented pciide reg 0x%x\n", reg)); 546 data = 0; 547 break; 548 } 549 550 return data; 551 } 552 553 void 554 glx_fn2_write(int reg, pcireg_t data) 555 { 556 uint64_t msr; 557 558 switch (reg) { 559 case PCI_COMMAND_STATUS_REG: 560 msr = rdmsr(GCSC_GLIU_PAE); 561 if (data & PCI_COMMAND_MASTER_ENABLE) 562 msr |= 0x03 << 4; 563 else 564 msr &= ~(0x03 << 4); 565 wrmsr(GCSC_GLIU_PAE, msr); 566 break; 567 case PCI_BHLC_REG: 568 msr = rdmsr(GCSC_GLPCI_CTRL); 569 msr &= 0xff00000000ULL; 570 msr |= ((uint64_t)PCI_LATTIMER(data)) << 32; 571 break; 572 case PCI_MAPREG_START + 0x10: 573 if (data == 0xffffffff) { 574 pciide_bar_value = data; 575 } else { 576 if ((data & PCI_MAPREG_TYPE_MASK) == 577 PCI_MAPREG_TYPE_IO) { 578 data &= PCI_MAPREG_IO_ADDR_MASK; 579 msr = (uint32_t)data & 0xfffffff0; 580 wrmsr(GCSC_IDE_IO_BAR, msr); 581 } else { 582 wrmsr(GCSC_IDE_IO_BAR, 0); 583 } 584 pciide_bar_value = 0; 585 } 586 break; 587 /* 588 * The following registers are used by pciide(4) 589 */ 590 case PCIIDE_CHANSTATUS_EN: 591 wrmsr(GCSC_IDE_CFG, (uint32_t)data); 592 break; 593 case /* AMD756_DATATIM XXX */ 0x48: 594 wrmsr(GCSC_IDE_DTC, (uint32_t)data); 595 break; 596 case /* AMD756_UDMA XXX*/ 0x50: 597 wrmsr(GCSC_IDE_ETC, (uint32_t)data); 598 break; 599 default: 600 DPRINTF(("unimplemented pciide reg 0x%x\n", reg)); 601 } 602 } 603 604 /* 605 * Function 3: AC97 Codec 606 */ 607 608 static pcireg_t ac97_bar_size = 0x80; 609 static pcireg_t ac97_bar_value; 610 611 pcireg_t 612 glx_fn3_read(int reg) 613 { 614 uint64_t msr; 615 pcireg_t data; 616 617 switch (reg) { 618 case PCI_ID_REG: 619 case PCI_SUBSYS_ID_REG: 620 data = PCI_ID_CODE(PCI_VENDOR_AMD, 621 PCI_PRODUCT_AMD_CS5536_AUDIO); 622 break; 623 case PCI_COMMAND_STATUS_REG: 624 data = glx_get_status(); 625 data |= PCI_COMMAND_IO_ENABLE; 626 msr = rdmsr(GCSC_GLIU_PAE); 627 if ((msr & (0x3 << 8)) == (0x3 << 8)) 628 data |= PCI_COMMAND_MASTER_ENABLE; 629 break; 630 case PCI_CLASS_REG: 631 msr = rdmsr(GCSC_ACC_GLD_MSR_CAP); 632 data = (PCI_CLASS_MULTIMEDIA << PCI_CLASS_SHIFT) | 633 (PCI_SUBCLASS_MULTIMEDIA_AUDIO << PCI_SUBCLASS_SHIFT) | 634 (msr & PCI_REVISION_MASK); 635 break; 636 case PCI_BHLC_REG: 637 msr = rdmsr(GCSC_GLPCI_CTRL); 638 data = (0x00 << PCI_HDRTYPE_SHIFT) | 639 (((msr & 0xff00000000ULL) >> 32) << PCI_LATTIMER_SHIFT) | 640 (0x08 << PCI_CACHELINE_SHIFT); 641 break; 642 case PCI_MAPREG_START: 643 data = ac97_bar_value; 644 if (data == 0xffffffff) 645 data = PCI_MAPREG_IO_ADDR_MASK & ~(ac97_bar_size - 1); 646 else { 647 msr = rdmsr(GCSC_GLIU_IOD_BM1); 648 data = (msr >> 20) & 0x000fffff; 649 data &= (msr & 0x000fffff); 650 } 651 if (data != 0) 652 data |= PCI_MAPREG_TYPE_IO; 653 break; 654 case PCI_INTERRUPT_REG: 655 data = (0x40 << PCI_MAX_LAT_SHIFT) | 656 (PCI_INTERRUPT_PIN_A << PCI_INTERRUPT_PIN_SHIFT); 657 break; 658 default: 659 data = 0; 660 break; 661 } 662 663 return data; 664 } 665 666 void 667 glx_fn3_write(int reg, pcireg_t data) 668 { 669 uint64_t msr; 670 671 switch (reg) { 672 case PCI_COMMAND_STATUS_REG: 673 msr = rdmsr(GCSC_GLIU_PAE); 674 if (data & PCI_COMMAND_MASTER_ENABLE) 675 msr |= 0x03 << 8; 676 else 677 msr &= ~(0x03 << 8); 678 wrmsr(GCSC_GLIU_PAE, msr); 679 break; 680 case PCI_BHLC_REG: 681 msr = rdmsr(GCSC_GLPCI_CTRL); 682 msr &= 0xff00000000ULL; 683 msr |= ((uint64_t)PCI_LATTIMER(data)) << 32; 684 break; 685 case PCI_MAPREG_START: 686 if (data == 0xffffffff) { 687 ac97_bar_value = data; 688 } else { 689 if ((data & PCI_MAPREG_TYPE_MASK) == 690 PCI_MAPREG_TYPE_IO) { 691 data &= PCI_MAPREG_IO_ADDR_MASK; 692 msr = rdmsr(GCSC_GLIU_IOD_BM1); 693 msr &= 0x0fffff0000000000ULL; 694 msr |= 5ULL << 61; /* AC97 */ 695 msr |= ((uint64_t)data & 0xfffff) << 20; 696 msr |= 0x000fffff & ~(ac97_bar_size - 1); 697 wrmsr(GCSC_GLIU_IOD_BM1, msr); 698 } else { 699 wrmsr(GCSC_GLIU_IOD_BM1, 0); 700 } 701 ac97_bar_value = 0; 702 } 703 break; 704 } 705 } 706 707 /* 708 * Function 4: OHCI Controller 709 */ 710 711 static pcireg_t ohci_bar_size = 0x1000; 712 static pcireg_t ohci_bar_value; 713 714 pcireg_t 715 glx_fn4_read(int reg) 716 { 717 uint64_t msr; 718 pcireg_t data; 719 720 switch (reg) { 721 case PCI_ID_REG: 722 case PCI_SUBSYS_ID_REG: 723 data = PCI_ID_CODE(PCI_VENDOR_AMD, PCI_PRODUCT_AMD_CS5536_OHCI); 724 break; 725 case PCI_COMMAND_STATUS_REG: 726 data = glx_get_status(); 727 msr = rdmsr(GCSC_USB_MSR_OHCB); 728 if (msr & (1ULL << 34)) 729 data |= PCI_COMMAND_MASTER_ENABLE; 730 if (msr & (1ULL << 33)) 731 data |= PCI_COMMAND_MEM_ENABLE; 732 break; 733 case PCI_CLASS_REG: 734 msr = rdmsr(GCSC_USB_GLD_MSR_CAP); 735 data = (PCI_CLASS_SERIALBUS << PCI_CLASS_SHIFT) | 736 (PCI_SUBCLASS_SERIALBUS_USB << PCI_SUBCLASS_SHIFT) | 737 (PCI_INTERFACE_OHCI << PCI_INTERFACE_SHIFT) | 738 (msr & PCI_REVISION_MASK); 739 break; 740 case PCI_BHLC_REG: 741 msr = rdmsr(GCSC_GLPCI_CTRL); 742 data = (0x00 << PCI_HDRTYPE_SHIFT) | 743 (((msr & 0xff00000000ULL) >> 32) << PCI_LATTIMER_SHIFT) | 744 (0x08 << PCI_CACHELINE_SHIFT); 745 break; 746 case PCI_MAPREG_START + 0x00: 747 data = ohci_bar_value; 748 if (data == 0xffffffff) 749 data = PCI_MAPREG_MEM_ADDR_MASK & ~(ohci_bar_size - 1); 750 else { 751 msr = rdmsr(GCSC_USB_MSR_OHCB); 752 data = msr & 0xffffff00; 753 } 754 if (data != 0) 755 data |= PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT; 756 break; 757 case PCI_CAPLISTPTR_REG: 758 data = 0x40; 759 break; 760 case PCI_INTERRUPT_REG: 761 data = (0x40 << PCI_MAX_LAT_SHIFT) | 762 (PCI_INTERRUPT_PIN_A << PCI_INTERRUPT_PIN_SHIFT); 763 break; 764 case 0x40: /* USB capability pointer */ 765 data = 0; 766 break; 767 default: 768 data = 0; 769 break; 770 } 771 772 return data; 773 } 774 775 void 776 glx_fn4_write(int reg, pcireg_t data) 777 { 778 uint64_t msr; 779 780 switch (reg) { 781 case PCI_COMMAND_STATUS_REG: 782 msr = rdmsr(GCSC_USB_MSR_OHCB); 783 if (data & PCI_COMMAND_MASTER_ENABLE) 784 msr |= 1ULL << 34; 785 else 786 msr &= ~(1ULL << 34); 787 if (data & PCI_COMMAND_MEM_ENABLE) 788 msr |= 1ULL << 33; 789 else 790 msr &= ~(1ULL << 33); 791 wrmsr(GCSC_USB_MSR_OHCB, msr); 792 break; 793 case PCI_BHLC_REG: 794 msr = rdmsr(GCSC_GLPCI_CTRL); 795 msr &= 0xff00000000ULL; 796 msr |= ((uint64_t)PCI_LATTIMER(data)) << 32; 797 break; 798 case PCI_MAPREG_START + 0x00: 799 if (data == 0xffffffff) { 800 ohci_bar_value = data; 801 } else { 802 if ((data & PCI_MAPREG_TYPE_MASK) == 803 PCI_MAPREG_TYPE_MEM) { 804 data &= PCI_MAPREG_MEM_ADDR_MASK; 805 msr = rdmsr(GCSC_GLIU_P2D_BM3); 806 msr &= 0x0fffff0000000000ULL; 807 msr |= 2ULL << 61; /* USB */ 808 msr |= (((uint64_t)data) >> 12) << 20; 809 msr |= 0x000fffff; 810 wrmsr(GCSC_GLIU_P2D_BM3, msr); 811 812 msr = rdmsr(GCSC_USB_MSR_OHCB); 813 msr &= ~0xffffff00ULL; 814 msr |= data; 815 } else { 816 msr = rdmsr(GCSC_USB_MSR_OHCB); 817 msr &= ~0xffffff00ULL; 818 } 819 wrmsr(GCSC_USB_MSR_OHCB, msr); 820 ohci_bar_value = 0; 821 } 822 break; 823 default: 824 break; 825 } 826 } 827 828 /* 829 * Function 5: EHCI Controller 830 */ 831 832 static pcireg_t ehci_bar_size = 0x1000; 833 static pcireg_t ehci_bar_value; 834 835 pcireg_t 836 glx_fn5_read(int reg) 837 { 838 uint64_t msr; 839 pcireg_t data; 840 841 switch (reg) { 842 case PCI_ID_REG: 843 case PCI_SUBSYS_ID_REG: 844 data = PCI_ID_CODE(PCI_VENDOR_AMD, PCI_PRODUCT_AMD_CS5536_EHCI); 845 break; 846 case PCI_COMMAND_STATUS_REG: 847 data = glx_get_status(); 848 msr = rdmsr(GCSC_USB_MSR_EHCB); 849 if (msr & (1ULL << 34)) 850 data |= PCI_COMMAND_MASTER_ENABLE; 851 if (msr & (1ULL << 33)) 852 data |= PCI_COMMAND_MEM_ENABLE; 853 break; 854 case PCI_CLASS_REG: 855 msr = rdmsr(GCSC_USB_GLD_MSR_CAP); 856 data = (PCI_CLASS_SERIALBUS << PCI_CLASS_SHIFT) | 857 (PCI_SUBCLASS_SERIALBUS_USB << PCI_SUBCLASS_SHIFT) | 858 (PCI_INTERFACE_EHCI << PCI_INTERFACE_SHIFT) | 859 (msr & PCI_REVISION_MASK); 860 break; 861 case PCI_BHLC_REG: 862 msr = rdmsr(GCSC_GLPCI_CTRL); 863 data = (0x00 << PCI_HDRTYPE_SHIFT) | 864 (((msr & 0xff00000000ULL) >> 32) << PCI_LATTIMER_SHIFT) | 865 (0x08 << PCI_CACHELINE_SHIFT); 866 break; 867 case PCI_MAPREG_START + 0x00: 868 data = ehci_bar_value; 869 if (data == 0xffffffff) 870 data = PCI_MAPREG_MEM_ADDR_MASK & ~(ehci_bar_size - 1); 871 else { 872 msr = rdmsr(GCSC_USB_MSR_EHCB); 873 data = msr & 0xffffff00; 874 } 875 if (data != 0) 876 data |= PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT; 877 break; 878 case PCI_CAPLISTPTR_REG: 879 data = 0x40; 880 break; 881 case PCI_INTERRUPT_REG: 882 data = (0x40 << PCI_MAX_LAT_SHIFT) | 883 (PCI_INTERRUPT_PIN_A << PCI_INTERRUPT_PIN_SHIFT); 884 break; 885 case 0x40: /* USB capability pointer */ 886 data = 0; 887 break; 888 case PCI_USBREV: 889 msr = rdmsr(GCSC_USB_MSR_EHCB); 890 data = PCI_USBREV_2_0; 891 data |= ((msr >> 40) & 0x3f) << 8; /* PCI_EHCI_FLADJ */ 892 break; 893 default: 894 data = 0; 895 break; 896 } 897 898 return data; 899 } 900 901 void 902 glx_fn5_write(int reg, pcireg_t data) 903 { 904 uint64_t msr; 905 906 switch (reg) { 907 case PCI_COMMAND_STATUS_REG: 908 msr = rdmsr(GCSC_USB_MSR_EHCB); 909 if (data & PCI_COMMAND_MASTER_ENABLE) 910 msr |= 1ULL << 34; 911 else 912 msr &= ~(1ULL << 34); 913 if (data & PCI_COMMAND_MEM_ENABLE) 914 msr |= 1ULL << 33; 915 else 916 msr &= ~(1ULL << 33); 917 wrmsr(GCSC_USB_MSR_EHCB, msr); 918 break; 919 case PCI_BHLC_REG: 920 msr = rdmsr(GCSC_GLPCI_CTRL); 921 msr &= 0xff00000000ULL; 922 msr |= ((uint64_t)PCI_LATTIMER(data)) << 32; 923 break; 924 case PCI_MAPREG_START + 0x00: 925 if (data == 0xffffffff) { 926 ehci_bar_value = data; 927 } else { 928 if ((data & PCI_MAPREG_TYPE_MASK) == 929 PCI_MAPREG_TYPE_MEM) { 930 data &= PCI_MAPREG_MEM_ADDR_MASK; 931 msr = rdmsr(GCSC_GLIU_P2D_BM4); 932 msr &= 0x0fffff0000000000ULL; 933 msr |= 2ULL << 61; /* USB */ 934 msr |= (((uint64_t)data) >> 12) << 20; 935 msr |= 0x000fffff; 936 wrmsr(GCSC_GLIU_P2D_BM4, msr); 937 938 msr = rdmsr(GCSC_USB_MSR_EHCB); 939 msr &= ~0xffffff00ULL; 940 msr |= data; 941 } else { 942 msr = rdmsr(GCSC_USB_MSR_EHCB); 943 msr &= ~0xffffff00ULL; 944 } 945 wrmsr(GCSC_USB_MSR_EHCB, msr); 946 ehci_bar_value = 0; 947 } 948 break; 949 default: 950 break; 951 } 952 } 953