1 /* $NetBSD: glx.c,v 1.4 2012/03/11 00:02:04 mrg 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.4 2012/03/11 00:02:04 mrg 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 /* 219 * Do not get in the way of MSR programming 220 */ 221 if (tag == glxbase_tag && offset >= PCI_MSR_CTRL) 222 return gen_pci_conf_read(v, tag, offset); 223 224 pci_decompose_tag(glxbase_pc, tag, &bus, &dev, &fn); 225 if (bus != 0 || dev != glxbase_dev) 226 return gen_pci_conf_read(v, tag, offset); 227 228 data = 0; 229 230 switch (fn) { 231 case 0: /* PCI-ISA bridge */ 232 data = glx_fn0_read(offset); 233 break; 234 case 1: /* Flash memory */ 235 break; 236 case 2: /* IDE controller */ 237 data = glx_fn2_read(offset); 238 break; 239 case 3: /* AC97 codec */ 240 data = glx_fn3_read(offset); 241 break; 242 case 4: /* OHCI controller */ 243 data = glx_fn4_read(offset); 244 break; 245 case 5: /* EHCI controller */ 246 data = glx_fn5_read(offset); 247 break; 248 case 6: /* UDC */ 249 break; 250 case 7: /* OTG */ 251 break; 252 } 253 254 return data; 255 } 256 257 void 258 glx_pci_write_hook(void *v, pcitag_t tag, 259 int offset, pcireg_t data) 260 { 261 int bus, dev, fn; 262 263 /* 264 * Do not get in the way of MSR programming 265 */ 266 if (tag == glxbase_tag && offset >= PCI_MSR_CTRL) { 267 gen_pci_conf_write(v, tag, offset, data); 268 return; 269 } 270 271 272 pci_decompose_tag(glxbase_pc, tag, &bus, &dev, &fn); 273 if (bus != 0 || dev != glxbase_dev) { 274 gen_pci_conf_write(v, tag, offset, data); 275 return; 276 } 277 278 switch (fn) { 279 case 0: /* PCI-ISA bridge */ 280 glx_fn0_write(offset, data); 281 break; 282 case 1: /* Flash memory */ 283 break; 284 case 2: /* IDE controller */ 285 glx_fn2_write(offset, data); 286 break; 287 case 3: /* AC97 codec */ 288 glx_fn3_write(offset, data); 289 break; 290 case 4: /* OHCI controller */ 291 glx_fn4_write(offset, data); 292 break; 293 case 5: /* EHCI controller */ 294 glx_fn5_write(offset, data); 295 break; 296 case 6: /* USB UDC */ 297 break; 298 case 7: /* USB OTG */ 299 break; 300 } 301 } 302 303 pcireg_t 304 glx_get_status(void) 305 { 306 uint64_t msr; 307 pcireg_t data; 308 309 data = 0; 310 msr = rdmsr(GCSC_GLPCI_GLD_MSR_ERROR); 311 if (msr & (1UL << 5)) 312 data |= PCI_COMMAND_PARITY_ENABLE; 313 data |= PCI_STATUS_66MHZ_SUPPORT | 314 PCI_STATUS_BACKTOBACK_SUPPORT | PCI_STATUS_DEVSEL_MEDIUM; 315 if (msr & (1UL << 21)) 316 data |= PCI_STATUS_PARITY_DETECT; 317 if (msr & (1UL << 20)) 318 data |= PCI_STATUS_TARGET_TARGET_ABORT; 319 if (msr & (1UL << 17)) 320 data |= PCI_STATUS_MASTER_TARGET_ABORT; 321 if (msr & (1UL << 16)) 322 data |= PCI_STATUS_MASTER_ABORT; 323 324 return data; 325 } 326 327 /* 328 * Function 0: PCI-ISA bridge 329 */ 330 331 static const pcireg_t pcib_bar_sizes[(4 + PCI_MAPREG_END - PCI_MAPREG_START) / 4] = { 332 0x008, 333 0x100, 334 0x040, 335 0x020, 336 0x080, 337 0x020 338 }; 339 340 static pcireg_t pcib_bar_values[(4 + PCI_MAPREG_END - PCI_MAPREG_START) / 4]; 341 342 static const uint64_t pcib_bar_msr[(4 + PCI_MAPREG_END - PCI_MAPREG_START) / 4] = { 343 GCSC_DIVIL_LBAR_SMB, 344 GCSC_DIVIL_LBAR_GPIO, 345 GCSC_DIVIL_LBAR_MFGPT, 346 GCSC_DIVIL_LBAR_IRQ, 347 GCSC_DIVIL_LBAR_PMS, 348 GCSC_DIVIL_LBAR_ACPI 349 }; 350 351 pcireg_t 352 glx_fn0_read(int reg) 353 { 354 uint64_t msr; 355 pcireg_t data; 356 int index; 357 358 switch (reg) { 359 case PCI_ID_REG: 360 case PCI_SUBSYS_ID_REG: 361 data = PCI_ID_CODE(PCI_VENDOR_AMD, PCI_PRODUCT_AMD_CS5536_PCIB); 362 break; 363 case PCI_COMMAND_STATUS_REG: 364 data = glx_get_status(); 365 data |= PCI_COMMAND_MASTER_ENABLE; 366 msr = rdmsr(GCSC_DIVIL_LBAR_SMB); 367 if (msr & (1ULL << 32)) 368 data |= PCI_COMMAND_IO_ENABLE; 369 break; 370 case PCI_CLASS_REG: 371 msr = rdmsr(GCSC_GLCP_CHIP_REV_ID); 372 data = (PCI_CLASS_BRIDGE << PCI_CLASS_SHIFT) | 373 (PCI_SUBCLASS_BRIDGE_ISA << PCI_SUBCLASS_SHIFT) | 374 (msr & PCI_REVISION_MASK); 375 break; 376 case PCI_BHLC_REG: 377 msr = rdmsr(GCSC_GLPCI_CTRL); 378 data = (0x80 << PCI_HDRTYPE_SHIFT) | 379 (((msr & 0xff00000000UL) >> 32) << PCI_LATTIMER_SHIFT) | 380 (0x08 << PCI_CACHELINE_SHIFT); 381 break; 382 case PCI_MAPREG_START + 0x00: 383 case PCI_MAPREG_START + 0x04: 384 case PCI_MAPREG_START + 0x08: 385 case PCI_MAPREG_START + 0x0c: 386 case PCI_MAPREG_START + 0x10: 387 case PCI_MAPREG_START + 0x14: 388 case PCI_MAPREG_START + 0x18: 389 index = (reg - PCI_MAPREG_START) / 4; 390 if (pcib_bar_msr[index] == 0) 391 data = 0; 392 else { 393 data = pcib_bar_values[index]; 394 if (data == 0xffffffff) 395 data = PCI_MAPREG_IO_ADDR_MASK; 396 else 397 data = (pcireg_t)rdmsr(pcib_bar_msr[index]); 398 data &= ~(pcib_bar_sizes[index] - 1); 399 if (data != 0) 400 data |= PCI_MAPREG_TYPE_IO; 401 } 402 break; 403 case PCI_INTERRUPT_REG: 404 data = (0x40 << PCI_MAX_LAT_SHIFT) | 405 (PCI_INTERRUPT_PIN_NONE << PCI_INTERRUPT_PIN_SHIFT); 406 break; 407 default: 408 data = 0; 409 break; 410 } 411 412 return data; 413 } 414 415 void 416 glx_fn0_write(int reg, pcireg_t data) 417 { 418 uint64_t msr; 419 int index; 420 421 switch (reg) { 422 case PCI_COMMAND_STATUS_REG: 423 for (index = 0; index < __arraycount(pcib_bar_msr); index++) { 424 if (pcib_bar_msr[index] == 0) 425 continue; 426 msr = rdmsr(pcib_bar_msr[index]); 427 if (data & PCI_COMMAND_IO_ENABLE) 428 msr |= 1ULL << 32; 429 else 430 msr &= ~(1ULL << 32); 431 wrmsr(pcib_bar_msr[index], msr); 432 } 433 434 msr = rdmsr(GCSC_GLPCI_GLD_MSR_ERROR); 435 if (data & PCI_COMMAND_PARITY_ENABLE) 436 msr |= 1ULL << 5; 437 else 438 msr &= ~(1ULL << 5); 439 wrmsr(GCSC_GLPCI_GLD_MSR_ERROR, msr); 440 break; 441 case PCI_BHLC_REG: 442 msr = rdmsr(GCSC_GLPCI_CTRL); 443 msr &= 0xff00000000ULL; 444 msr |= ((uint64_t)PCI_LATTIMER(data)) << 32; 445 break; 446 case PCI_MAPREG_START + 0x00: 447 case PCI_MAPREG_START + 0x04: 448 case PCI_MAPREG_START + 0x08: 449 case PCI_MAPREG_START + 0x0c: 450 case PCI_MAPREG_START + 0x10: 451 case PCI_MAPREG_START + 0x14: 452 case PCI_MAPREG_START + 0x18: 453 index = (reg - PCI_MAPREG_START) / 4; 454 if (data == 0xffffffff) { 455 pcib_bar_values[index] = data; 456 } else if (pcib_bar_msr[index] != 0) { 457 if ((data & PCI_MAPREG_TYPE_MASK) == 458 PCI_MAPREG_TYPE_IO) { 459 data &= PCI_MAPREG_IO_ADDR_MASK; 460 data &= ~(pcib_bar_sizes[index] - 1); 461 wrmsr(pcib_bar_msr[index], 462 (0x0000f000ULL << 32) | (1ULL << 32) | data); 463 } else { 464 wrmsr(pcib_bar_msr[index], 0ULL); 465 } 466 pcib_bar_values[index] = 0; 467 } 468 break; 469 } 470 } 471 472 /* 473 * Function 2: IDE Controller 474 */ 475 476 static pcireg_t pciide_bar_size = 0x10; 477 static pcireg_t pciide_bar_value; 478 479 pcireg_t 480 glx_fn2_read(int reg) 481 { 482 uint64_t msr; 483 pcireg_t data; 484 485 switch (reg) { 486 case PCI_ID_REG: 487 case PCI_SUBSYS_ID_REG: 488 data = PCI_ID_CODE(PCI_VENDOR_AMD, PCI_PRODUCT_AMD_CS5536_IDE); 489 break; 490 case PCI_COMMAND_STATUS_REG: 491 data = glx_get_status(); 492 data |= PCI_COMMAND_IO_ENABLE; 493 msr = rdmsr(GCSC_GLIU_PAE); 494 if ((msr & (0x3 << 4)) == (0x3 << 4)) 495 data |= PCI_COMMAND_MASTER_ENABLE; 496 break; 497 case PCI_CLASS_REG: 498 msr = rdmsr(GCSC_IDE_GLD_MSR_CAP); 499 data = (PCI_CLASS_MASS_STORAGE << PCI_CLASS_SHIFT) | 500 (PCI_SUBCLASS_MASS_STORAGE_IDE << PCI_SUBCLASS_SHIFT) | 501 (PCIIDE_INTERFACE_BUS_MASTER_DMA << PCI_INTERFACE_SHIFT) | 502 (msr & PCI_REVISION_MASK); 503 break; 504 case PCI_BHLC_REG: 505 msr = rdmsr(GCSC_GLPCI_CTRL); 506 data = (0x00 << PCI_HDRTYPE_SHIFT) | 507 (((msr & 0xff00000000ULL) >> 32) << PCI_LATTIMER_SHIFT) | 508 (0x08 << PCI_CACHELINE_SHIFT); 509 break; 510 case PCI_MAPREG_START + 0x10: 511 data = pciide_bar_value; 512 if (data == 0xffffffff) 513 data = PCI_MAPREG_IO_ADDR_MASK & ~(pciide_bar_size - 1); 514 else { 515 msr = rdmsr(GCSC_IDE_IO_BAR); 516 data = msr & 0xfffffff0; 517 } 518 if (data != 0) 519 data |= PCI_MAPREG_TYPE_IO; 520 break; 521 case PCI_INTERRUPT_REG: 522 /* compat mode */ 523 data = (0x40 << PCI_MAX_LAT_SHIFT) | 524 (PCI_INTERRUPT_PIN_NONE << PCI_INTERRUPT_PIN_SHIFT); 525 break; 526 /* 527 * The following registers are used by pciide(4) 528 */ 529 case PCIIDE_CHANSTATUS_EN: 530 data = rdmsr(GCSC_IDE_CFG); 531 break; 532 case /* AMD756_DATATIM XXX */ 0x48: 533 data = rdmsr(GCSC_IDE_DTC); 534 break; 535 case /* AMD756_UDMA XXX*/ 0x50: 536 data = rdmsr(GCSC_IDE_ETC); 537 break; 538 default: 539 DPRINTF(("unimplemented pciide reg 0x%x\n", reg)); 540 data = 0; 541 break; 542 } 543 544 return data; 545 } 546 547 void 548 glx_fn2_write(int reg, pcireg_t data) 549 { 550 uint64_t msr; 551 552 switch (reg) { 553 case PCI_COMMAND_STATUS_REG: 554 msr = rdmsr(GCSC_GLIU_PAE); 555 if (data & PCI_COMMAND_MASTER_ENABLE) 556 msr |= 0x03 << 4; 557 else 558 msr &= ~(0x03 << 4); 559 wrmsr(GCSC_GLIU_PAE, msr); 560 break; 561 case PCI_BHLC_REG: 562 msr = rdmsr(GCSC_GLPCI_CTRL); 563 msr &= 0xff00000000ULL; 564 msr |= ((uint64_t)PCI_LATTIMER(data)) << 32; 565 break; 566 case PCI_MAPREG_START + 0x10: 567 if (data == 0xffffffff) { 568 pciide_bar_value = data; 569 } else { 570 if ((data & PCI_MAPREG_TYPE_MASK) == 571 PCI_MAPREG_TYPE_IO) { 572 data &= PCI_MAPREG_IO_ADDR_MASK; 573 msr = (uint32_t)data & 0xfffffff0; 574 wrmsr(GCSC_IDE_IO_BAR, msr); 575 } else { 576 wrmsr(GCSC_IDE_IO_BAR, 0); 577 } 578 pciide_bar_value = 0; 579 } 580 break; 581 /* 582 * The following registers are used by pciide(4) 583 */ 584 case PCIIDE_CHANSTATUS_EN: 585 wrmsr(GCSC_IDE_CFG, (uint32_t)data); 586 break; 587 case /* AMD756_DATATIM XXX */ 0x48: 588 wrmsr(GCSC_IDE_DTC, (uint32_t)data); 589 break; 590 case /* AMD756_UDMA XXX*/ 0x50: 591 wrmsr(GCSC_IDE_ETC, (uint32_t)data); 592 break; 593 default: 594 DPRINTF(("unimplemented pciide reg 0x%x\n", reg)); 595 } 596 } 597 598 /* 599 * Function 3: AC97 Codec 600 */ 601 602 static pcireg_t ac97_bar_size = 0x80; 603 static pcireg_t ac97_bar_value; 604 605 pcireg_t 606 glx_fn3_read(int reg) 607 { 608 uint64_t msr; 609 pcireg_t data; 610 611 switch (reg) { 612 case PCI_ID_REG: 613 case PCI_SUBSYS_ID_REG: 614 data = PCI_ID_CODE(PCI_VENDOR_AMD, 615 PCI_PRODUCT_AMD_CS5536_AUDIO); 616 break; 617 case PCI_COMMAND_STATUS_REG: 618 data = glx_get_status(); 619 data |= PCI_COMMAND_IO_ENABLE; 620 msr = rdmsr(GCSC_GLIU_PAE); 621 if ((msr & (0x3 << 8)) == (0x3 << 8)) 622 data |= PCI_COMMAND_MASTER_ENABLE; 623 break; 624 case PCI_CLASS_REG: 625 msr = rdmsr(GCSC_ACC_GLD_MSR_CAP); 626 data = (PCI_CLASS_MULTIMEDIA << PCI_CLASS_SHIFT) | 627 (PCI_SUBCLASS_MULTIMEDIA_AUDIO << PCI_SUBCLASS_SHIFT) | 628 (msr & PCI_REVISION_MASK); 629 break; 630 case PCI_BHLC_REG: 631 msr = rdmsr(GCSC_GLPCI_CTRL); 632 data = (0x00 << PCI_HDRTYPE_SHIFT) | 633 (((msr & 0xff00000000ULL) >> 32) << PCI_LATTIMER_SHIFT) | 634 (0x08 << PCI_CACHELINE_SHIFT); 635 break; 636 case PCI_MAPREG_START: 637 data = ac97_bar_value; 638 if (data == 0xffffffff) 639 data = PCI_MAPREG_IO_ADDR_MASK & ~(ac97_bar_size - 1); 640 else { 641 msr = rdmsr(GCSC_GLIU_IOD_BM1); 642 data = (msr >> 20) & 0x000fffff; 643 data &= (msr & 0x000fffff); 644 } 645 if (data != 0) 646 data |= PCI_MAPREG_TYPE_IO; 647 break; 648 case PCI_INTERRUPT_REG: 649 data = (0x40 << PCI_MAX_LAT_SHIFT) | 650 (PCI_INTERRUPT_PIN_A << PCI_INTERRUPT_PIN_SHIFT); 651 break; 652 default: 653 data = 0; 654 break; 655 } 656 657 return data; 658 } 659 660 void 661 glx_fn3_write(int reg, pcireg_t data) 662 { 663 uint64_t msr; 664 665 switch (reg) { 666 case PCI_COMMAND_STATUS_REG: 667 msr = rdmsr(GCSC_GLIU_PAE); 668 if (data & PCI_COMMAND_MASTER_ENABLE) 669 msr |= 0x03 << 8; 670 else 671 msr &= ~(0x03 << 8); 672 wrmsr(GCSC_GLIU_PAE, msr); 673 break; 674 case PCI_BHLC_REG: 675 msr = rdmsr(GCSC_GLPCI_CTRL); 676 msr &= 0xff00000000ULL; 677 msr |= ((uint64_t)PCI_LATTIMER(data)) << 32; 678 break; 679 case PCI_MAPREG_START: 680 if (data == 0xffffffff) { 681 ac97_bar_value = data; 682 } else { 683 if ((data & PCI_MAPREG_TYPE_MASK) == 684 PCI_MAPREG_TYPE_IO) { 685 data &= PCI_MAPREG_IO_ADDR_MASK; 686 msr = rdmsr(GCSC_GLIU_IOD_BM1); 687 msr &= 0x0fffff0000000000ULL; 688 msr |= 5ULL << 61; /* AC97 */ 689 msr |= ((uint64_t)data & 0xfffff) << 20; 690 msr |= 0x000fffff & ~(ac97_bar_size - 1); 691 wrmsr(GCSC_GLIU_IOD_BM1, msr); 692 } else { 693 wrmsr(GCSC_GLIU_IOD_BM1, 0); 694 } 695 ac97_bar_value = 0; 696 } 697 break; 698 } 699 } 700 701 /* 702 * Function 4: OHCI Controller 703 */ 704 705 static pcireg_t ohci_bar_size = 0x1000; 706 static pcireg_t ohci_bar_value; 707 708 pcireg_t 709 glx_fn4_read(int reg) 710 { 711 uint64_t msr; 712 pcireg_t data; 713 714 switch (reg) { 715 case PCI_ID_REG: 716 case PCI_SUBSYS_ID_REG: 717 data = PCI_ID_CODE(PCI_VENDOR_AMD, PCI_PRODUCT_AMD_CS5536_OHCI); 718 break; 719 case PCI_COMMAND_STATUS_REG: 720 data = glx_get_status(); 721 msr = rdmsr(GCSC_USB_MSR_OHCB); 722 if (msr & (1ULL << 34)) 723 data |= PCI_COMMAND_MASTER_ENABLE; 724 if (msr & (1ULL << 33)) 725 data |= PCI_COMMAND_MEM_ENABLE; 726 break; 727 case PCI_CLASS_REG: 728 msr = rdmsr(GCSC_USB_GLD_MSR_CAP); 729 data = (PCI_CLASS_SERIALBUS << PCI_CLASS_SHIFT) | 730 (PCI_SUBCLASS_SERIALBUS_USB << PCI_SUBCLASS_SHIFT) | 731 (PCI_INTERFACE_OHCI << PCI_INTERFACE_SHIFT) | 732 (msr & PCI_REVISION_MASK); 733 break; 734 case PCI_BHLC_REG: 735 msr = rdmsr(GCSC_GLPCI_CTRL); 736 data = (0x00 << PCI_HDRTYPE_SHIFT) | 737 (((msr & 0xff00000000ULL) >> 32) << PCI_LATTIMER_SHIFT) | 738 (0x08 << PCI_CACHELINE_SHIFT); 739 break; 740 case PCI_MAPREG_START + 0x00: 741 data = ohci_bar_value; 742 if (data == 0xffffffff) 743 data = PCI_MAPREG_MEM_ADDR_MASK & ~(ohci_bar_size - 1); 744 else { 745 msr = rdmsr(GCSC_USB_MSR_OHCB); 746 data = msr & 0xffffff00; 747 } 748 if (data != 0) 749 data |= PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT; 750 break; 751 case PCI_CAPLISTPTR_REG: 752 data = 0x40; 753 break; 754 case PCI_INTERRUPT_REG: 755 data = (0x40 << PCI_MAX_LAT_SHIFT) | 756 (PCI_INTERRUPT_PIN_A << PCI_INTERRUPT_PIN_SHIFT); 757 break; 758 case 0x40: /* USB capability pointer */ 759 data = 0; 760 break; 761 default: 762 data = 0; 763 break; 764 } 765 766 return data; 767 } 768 769 void 770 glx_fn4_write(int reg, pcireg_t data) 771 { 772 uint64_t msr; 773 774 switch (reg) { 775 case PCI_COMMAND_STATUS_REG: 776 msr = rdmsr(GCSC_USB_MSR_OHCB); 777 if (data & PCI_COMMAND_MASTER_ENABLE) 778 msr |= 1ULL << 34; 779 else 780 msr &= ~(1ULL << 34); 781 if (data & PCI_COMMAND_MEM_ENABLE) 782 msr |= 1ULL << 33; 783 else 784 msr &= ~(1ULL << 33); 785 wrmsr(GCSC_USB_MSR_OHCB, msr); 786 break; 787 case PCI_BHLC_REG: 788 msr = rdmsr(GCSC_GLPCI_CTRL); 789 msr &= 0xff00000000ULL; 790 msr |= ((uint64_t)PCI_LATTIMER(data)) << 32; 791 break; 792 case PCI_MAPREG_START + 0x00: 793 if (data == 0xffffffff) { 794 ohci_bar_value = data; 795 } else { 796 if ((data & PCI_MAPREG_TYPE_MASK) == 797 PCI_MAPREG_TYPE_MEM) { 798 data &= PCI_MAPREG_MEM_ADDR_MASK; 799 msr = rdmsr(GCSC_GLIU_P2D_BM3); 800 msr &= 0x0fffff0000000000ULL; 801 msr |= 2ULL << 61; /* USB */ 802 msr |= (((uint64_t)data) >> 12) << 20; 803 msr |= 0x000fffff; 804 wrmsr(GCSC_GLIU_P2D_BM3, msr); 805 806 msr = rdmsr(GCSC_USB_MSR_OHCB); 807 msr &= ~0xffffff00ULL; 808 msr |= data; 809 } else { 810 msr = rdmsr(GCSC_USB_MSR_OHCB); 811 msr &= ~0xffffff00ULL; 812 } 813 wrmsr(GCSC_USB_MSR_OHCB, msr); 814 ohci_bar_value = 0; 815 } 816 break; 817 default: 818 break; 819 } 820 } 821 822 /* 823 * Function 5: EHCI Controller 824 */ 825 826 static pcireg_t ehci_bar_size = 0x1000; 827 static pcireg_t ehci_bar_value; 828 829 pcireg_t 830 glx_fn5_read(int reg) 831 { 832 uint64_t msr; 833 pcireg_t data; 834 835 switch (reg) { 836 case PCI_ID_REG: 837 case PCI_SUBSYS_ID_REG: 838 data = PCI_ID_CODE(PCI_VENDOR_AMD, PCI_PRODUCT_AMD_CS5536_EHCI); 839 break; 840 case PCI_COMMAND_STATUS_REG: 841 data = glx_get_status(); 842 msr = rdmsr(GCSC_USB_MSR_EHCB); 843 if (msr & (1ULL << 34)) 844 data |= PCI_COMMAND_MASTER_ENABLE; 845 if (msr & (1ULL << 33)) 846 data |= PCI_COMMAND_MEM_ENABLE; 847 break; 848 case PCI_CLASS_REG: 849 msr = rdmsr(GCSC_USB_GLD_MSR_CAP); 850 data = (PCI_CLASS_SERIALBUS << PCI_CLASS_SHIFT) | 851 (PCI_SUBCLASS_SERIALBUS_USB << PCI_SUBCLASS_SHIFT) | 852 (PCI_INTERFACE_EHCI << PCI_INTERFACE_SHIFT) | 853 (msr & PCI_REVISION_MASK); 854 break; 855 case PCI_BHLC_REG: 856 msr = rdmsr(GCSC_GLPCI_CTRL); 857 data = (0x00 << PCI_HDRTYPE_SHIFT) | 858 (((msr & 0xff00000000ULL) >> 32) << PCI_LATTIMER_SHIFT) | 859 (0x08 << PCI_CACHELINE_SHIFT); 860 break; 861 case PCI_MAPREG_START + 0x00: 862 data = ehci_bar_value; 863 if (data == 0xffffffff) 864 data = PCI_MAPREG_MEM_ADDR_MASK & ~(ehci_bar_size - 1); 865 else { 866 msr = rdmsr(GCSC_USB_MSR_EHCB); 867 data = msr & 0xffffff00; 868 } 869 if (data != 0) 870 data |= PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT; 871 break; 872 case PCI_CAPLISTPTR_REG: 873 data = 0x40; 874 break; 875 case PCI_INTERRUPT_REG: 876 data = (0x40 << PCI_MAX_LAT_SHIFT) | 877 (PCI_INTERRUPT_PIN_A << PCI_INTERRUPT_PIN_SHIFT); 878 break; 879 case 0x40: /* USB capability pointer */ 880 data = 0; 881 break; 882 case PCI_USBREV: 883 msr = rdmsr(GCSC_USB_MSR_EHCB); 884 data = PCI_USBREV_2_0; 885 data |= ((msr >> 40) & 0x3f) << 8; /* PCI_EHCI_FLADJ */ 886 break; 887 default: 888 data = 0; 889 break; 890 } 891 892 return data; 893 } 894 895 void 896 glx_fn5_write(int reg, pcireg_t data) 897 { 898 uint64_t msr; 899 900 switch (reg) { 901 case PCI_COMMAND_STATUS_REG: 902 msr = rdmsr(GCSC_USB_MSR_EHCB); 903 if (data & PCI_COMMAND_MASTER_ENABLE) 904 msr |= 1ULL << 34; 905 else 906 msr &= ~(1ULL << 34); 907 if (data & PCI_COMMAND_MEM_ENABLE) 908 msr |= 1ULL << 33; 909 else 910 msr &= ~(1ULL << 33); 911 wrmsr(GCSC_USB_MSR_EHCB, msr); 912 break; 913 case PCI_BHLC_REG: 914 msr = rdmsr(GCSC_GLPCI_CTRL); 915 msr &= 0xff00000000ULL; 916 msr |= ((uint64_t)PCI_LATTIMER(data)) << 32; 917 break; 918 case PCI_MAPREG_START + 0x00: 919 if (data == 0xffffffff) { 920 ehci_bar_value = data; 921 } else { 922 if ((data & PCI_MAPREG_TYPE_MASK) == 923 PCI_MAPREG_TYPE_MEM) { 924 data &= PCI_MAPREG_MEM_ADDR_MASK; 925 msr = rdmsr(GCSC_GLIU_P2D_BM4); 926 msr &= 0x0fffff0000000000ULL; 927 msr |= 2ULL << 61; /* USB */ 928 msr |= (((uint64_t)data) >> 12) << 20; 929 msr |= 0x000fffff; 930 wrmsr(GCSC_GLIU_P2D_BM4, msr); 931 932 msr = rdmsr(GCSC_USB_MSR_EHCB); 933 msr &= ~0xffffff00ULL; 934 msr |= data; 935 } else { 936 msr = rdmsr(GCSC_USB_MSR_EHCB); 937 msr &= ~0xffffff00ULL; 938 } 939 wrmsr(GCSC_USB_MSR_EHCB, msr); 940 ehci_bar_value = 0; 941 } 942 break; 943 default: 944 break; 945 } 946 } 947