reg_script.c
1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 3 #include <device/mmio.h> 4 #include <device/pci_ops.h> 5 #include <console/console.h> 6 #include <delay.h> 7 #include <device/device.h> 8 #include <device/pci.h> 9 #include <stdint.h> 10 #include <reg_script.h> 11 12 #if ENV_X86 13 #include <cpu/x86/msr.h> 14 #endif 15 16 #if ENV_X86 17 #include <arch/io.h> 18 #define HAS_ARCH_IO 1 19 #else 20 #define HAS_ARCH_IO 0 21 #endif 22 23 #define HAS_IOSF (CONFIG(SOC_INTEL_BAYTRAIL)) 24 25 #if HAS_IOSF 26 #include <soc/iosf.h> /* TODO: wrap in <soc/reg_script.h, remove #ifdef? */ 27 #endif 28 29 #define POLL_DELAY 100 /* 100us */ 30 31 #ifdef __SIMPLE_DEVICE__ 32 #define EMPTY_DEV 0 33 #else 34 #define EMPTY_DEV NULL 35 #endif 36 37 #ifdef __SIMPLE_DEVICE__ 38 static inline void reg_script_set_dev(struct reg_script_context *ctx, 39 pci_devfn_t dev) 40 #else 41 static inline void reg_script_set_dev(struct reg_script_context *ctx, 42 struct device *dev) 43 #endif 44 { 45 ctx->dev = dev; 46 ctx->res = NULL; 47 } 48 49 static inline void reg_script_set_step(struct reg_script_context *ctx, 50 const struct reg_script *step) 51 { 52 ctx->step = step; 53 } 54 55 static inline const struct reg_script * 56 reg_script_get_step(struct reg_script_context *ctx) 57 { 58 return ctx->step; 59 } 60 61 static struct resource *reg_script_get_resource(struct reg_script_context *ctx) 62 { 63 #ifdef __SIMPLE_DEVICE__ 64 return NULL; 65 #else 66 struct resource *res; 67 const struct reg_script *step = reg_script_get_step(ctx); 68 69 res = ctx->res; 70 71 if (res != NULL && res->index == step->res_index) 72 return res; 73 74 res = find_resource(ctx->dev, step->res_index); 75 ctx->res = res; 76 return res; 77 #endif 78 } 79 80 static uint32_t reg_script_read_pci(struct reg_script_context *ctx) 81 { 82 const struct reg_script *step = reg_script_get_step(ctx); 83 84 switch (step->size) { 85 case REG_SCRIPT_SIZE_8: 86 return pci_read_config8(ctx->dev, step->reg); 87 case REG_SCRIPT_SIZE_16: 88 return pci_read_config16(ctx->dev, step->reg); 89 case REG_SCRIPT_SIZE_32: 90 return pci_read_config32(ctx->dev, step->reg); 91 } 92 return 0; 93 } 94 95 static void reg_script_write_pci(struct reg_script_context *ctx) 96 { 97 const struct reg_script *step = reg_script_get_step(ctx); 98 99 switch (step->size) { 100 case REG_SCRIPT_SIZE_8: 101 pci_write_config8(ctx->dev, step->reg, step->value); 102 break; 103 case REG_SCRIPT_SIZE_16: 104 pci_write_config16(ctx->dev, step->reg, step->value); 105 break; 106 case REG_SCRIPT_SIZE_32: 107 pci_write_config32(ctx->dev, step->reg, step->value); 108 break; 109 } 110 } 111 112 #if HAS_ARCH_IO 113 static uint32_t reg_script_read_io(struct reg_script_context *ctx) 114 { 115 const struct reg_script *step = reg_script_get_step(ctx); 116 117 switch (step->size) { 118 case REG_SCRIPT_SIZE_8: 119 return inb(step->reg); 120 case REG_SCRIPT_SIZE_16: 121 return inw(step->reg); 122 case REG_SCRIPT_SIZE_32: 123 return inl(step->reg); 124 } 125 return 0; 126 } 127 128 static void reg_script_write_io(struct reg_script_context *ctx) 129 { 130 const struct reg_script *step = reg_script_get_step(ctx); 131 132 switch (step->size) { 133 case REG_SCRIPT_SIZE_8: 134 outb(step->value, step->reg); 135 break; 136 case REG_SCRIPT_SIZE_16: 137 outw(step->value, step->reg); 138 break; 139 case REG_SCRIPT_SIZE_32: 140 outl(step->value, step->reg); 141 break; 142 } 143 } 144 #endif 145 146 static uint32_t reg_script_read_mmio(struct reg_script_context *ctx) 147 { 148 const struct reg_script *step = reg_script_get_step(ctx); 149 150 switch (step->size) { 151 case REG_SCRIPT_SIZE_8: 152 return read8((u8 *)(uintptr_t)step->reg); 153 case REG_SCRIPT_SIZE_16: 154 return read16((u16 *)(uintptr_t)step->reg); 155 case REG_SCRIPT_SIZE_32: 156 return read32((u32 *)(uintptr_t)step->reg); 157 } 158 return 0; 159 } 160 161 static void reg_script_write_mmio(struct reg_script_context *ctx) 162 { 163 const struct reg_script *step = reg_script_get_step(ctx); 164 165 switch (step->size) { 166 case REG_SCRIPT_SIZE_8: 167 write8((u8 *)(uintptr_t)step->reg, step->value); 168 break; 169 case REG_SCRIPT_SIZE_16: 170 write16((u16 *)(uintptr_t)step->reg, step->value); 171 break; 172 case REG_SCRIPT_SIZE_32: 173 write32((u32 *)(uintptr_t)step->reg, step->value); 174 break; 175 } 176 } 177 178 static uint32_t reg_script_read_res(struct reg_script_context *ctx) 179 { 180 struct resource *res; 181 uint32_t val = 0; 182 const struct reg_script *step = reg_script_get_step(ctx); 183 184 res = reg_script_get_resource(ctx); 185 186 if (res == NULL) 187 return val; 188 189 if (res->flags & IORESOURCE_IO) { 190 const struct reg_script io_step = { 191 .size = step->size, 192 .reg = res->base + step->reg, 193 }; 194 reg_script_set_step(ctx, &io_step); 195 val = reg_script_read_io(ctx); 196 } else if (res->flags & IORESOURCE_MEM) { 197 const struct reg_script mmio_step = { 198 .size = step->size, 199 .reg = res->base + step->reg, 200 }; 201 reg_script_set_step(ctx, &mmio_step); 202 val = reg_script_read_mmio(ctx); 203 } 204 reg_script_set_step(ctx, step); 205 return val; 206 } 207 208 static void reg_script_write_res(struct reg_script_context *ctx) 209 { 210 struct resource *res; 211 const struct reg_script *step = reg_script_get_step(ctx); 212 213 res = reg_script_get_resource(ctx); 214 215 if (res == NULL) 216 return; 217 218 if (res->flags & IORESOURCE_IO) { 219 const struct reg_script io_step = { 220 .size = step->size, 221 .reg = res->base + step->reg, 222 .value = step->value, 223 }; 224 reg_script_set_step(ctx, &io_step); 225 reg_script_write_io(ctx); 226 } else if (res->flags & IORESOURCE_MEM) { 227 const struct reg_script mmio_step = { 228 .size = step->size, 229 .reg = res->base + step->reg, 230 .value = step->value, 231 }; 232 reg_script_set_step(ctx, &mmio_step); 233 reg_script_write_mmio(ctx); 234 } 235 reg_script_set_step(ctx, step); 236 } 237 238 #if HAS_IOSF 239 static uint32_t reg_script_read_iosf(struct reg_script_context *ctx) 240 { 241 const struct reg_script *step = reg_script_get_step(ctx); 242 243 switch (step->id) { 244 case IOSF_PORT_AUNIT: 245 return iosf_aunit_read(step->reg); 246 case IOSF_PORT_CPU_BUS: 247 return iosf_cpu_bus_read(step->reg); 248 case IOSF_PORT_BUNIT: 249 return iosf_bunit_read(step->reg); 250 case IOSF_PORT_DUNIT_CH0: 251 return iosf_dunit_ch0_read(step->reg); 252 case IOSF_PORT_PMC: 253 return iosf_punit_read(step->reg); 254 case IOSF_PORT_USBPHY: 255 return iosf_usbphy_read(step->reg); 256 case IOSF_PORT_SEC: 257 return iosf_sec_read(step->reg); 258 case IOSF_PORT_0x45: 259 return iosf_port45_read(step->reg); 260 case IOSF_PORT_0x46: 261 return iosf_port46_read(step->reg); 262 case IOSF_PORT_0x47: 263 return iosf_port47_read(step->reg); 264 case IOSF_PORT_SCORE: 265 return iosf_score_read(step->reg); 266 case IOSF_PORT_0x55: 267 return iosf_port55_read(step->reg); 268 case IOSF_PORT_0x58: 269 return iosf_port58_read(step->reg); 270 case IOSF_PORT_0x59: 271 return iosf_port59_read(step->reg); 272 case IOSF_PORT_0x5a: 273 return iosf_port5a_read(step->reg); 274 case IOSF_PORT_USHPHY: 275 return iosf_ushphy_read(step->reg); 276 case IOSF_PORT_SCC: 277 return iosf_scc_read(step->reg); 278 case IOSF_PORT_LPSS: 279 return iosf_lpss_read(step->reg); 280 case IOSF_PORT_0xa2: 281 return iosf_porta2_read(step->reg); 282 case IOSF_PORT_CCU: 283 return iosf_ccu_read(step->reg); 284 case IOSF_PORT_SSUS: 285 return iosf_ssus_read(step->reg); 286 default: 287 printk(BIOS_DEBUG, "No read support for IOSF port 0x%x.\n", 288 step->id); 289 break; 290 } 291 return 0; 292 } 293 294 static void reg_script_write_iosf(struct reg_script_context *ctx) 295 { 296 const struct reg_script *step = reg_script_get_step(ctx); 297 298 switch (step->id) { 299 case IOSF_PORT_AUNIT: 300 iosf_aunit_write(step->reg, step->value); 301 break; 302 case IOSF_PORT_CPU_BUS: 303 iosf_cpu_bus_write(step->reg, step->value); 304 break; 305 case IOSF_PORT_BUNIT: 306 iosf_bunit_write(step->reg, step->value); 307 break; 308 case IOSF_PORT_DUNIT_CH0: 309 iosf_dunit_write(step->reg, step->value); 310 break; 311 case IOSF_PORT_PMC: 312 iosf_punit_write(step->reg, step->value); 313 break; 314 case IOSF_PORT_USBPHY: 315 iosf_usbphy_write(step->reg, step->value); 316 break; 317 case IOSF_PORT_SEC: 318 iosf_sec_write(step->reg, step->value); 319 break; 320 case IOSF_PORT_0x45: 321 iosf_port45_write(step->reg, step->value); 322 break; 323 case IOSF_PORT_0x46: 324 iosf_port46_write(step->reg, step->value); 325 break; 326 case IOSF_PORT_0x47: 327 iosf_port47_write(step->reg, step->value); 328 break; 329 case IOSF_PORT_SCORE: 330 iosf_score_write(step->reg, step->value); 331 break; 332 case IOSF_PORT_0x55: 333 iosf_port55_write(step->reg, step->value); 334 break; 335 case IOSF_PORT_0x58: 336 iosf_port58_write(step->reg, step->value); 337 break; 338 case IOSF_PORT_0x59: 339 iosf_port59_write(step->reg, step->value); 340 break; 341 case IOSF_PORT_0x5a: 342 iosf_port5a_write(step->reg, step->value); 343 break; 344 case IOSF_PORT_USHPHY: 345 iosf_ushphy_write(step->reg, step->value); 346 break; 347 case IOSF_PORT_SCC: 348 iosf_scc_write(step->reg, step->value); 349 break; 350 case IOSF_PORT_LPSS: 351 iosf_lpss_write(step->reg, step->value); 352 break; 353 case IOSF_PORT_0xa2: 354 iosf_porta2_write(step->reg, step->value); 355 break; 356 case IOSF_PORT_CCU: 357 iosf_ccu_write(step->reg, step->value); 358 break; 359 case IOSF_PORT_SSUS: 360 iosf_ssus_write(step->reg, step->value); 361 break; 362 default: 363 printk(BIOS_DEBUG, "No write support for IOSF port 0x%x.\n", 364 step->id); 365 break; 366 } 367 } 368 #endif /* HAS_IOSF */ 369 370 371 static uint64_t reg_script_read_msr(struct reg_script_context *ctx) 372 { 373 #if ENV_X86 374 const struct reg_script *step = reg_script_get_step(ctx); 375 msr_t msr = rdmsr(step->reg); 376 uint64_t value = msr.hi; 377 value <<= 32; 378 value |= msr.lo; 379 return value; 380 #endif 381 } 382 383 static void reg_script_write_msr(struct reg_script_context *ctx) 384 { 385 #if ENV_X86 386 const struct reg_script *step = reg_script_get_step(ctx); 387 msr_t msr; 388 msr.hi = step->value >> 32; 389 msr.lo = step->value & 0xffffffff; 390 wrmsr(step->reg, msr); 391 #endif 392 } 393 394 /* Locate the structure containing the platform specific bus access routines */ 395 static const struct reg_script_bus_entry 396 *find_bus(const struct reg_script *step) 397 { 398 extern const struct reg_script_bus_entry *_rsbe_init_begin[]; 399 extern const struct reg_script_bus_entry *_ersbe_init_begin[]; 400 const struct reg_script_bus_entry * const *bus; 401 size_t table_entries; 402 size_t i; 403 404 /* Locate the platform specific bus */ 405 bus = _rsbe_init_begin; 406 table_entries = &_ersbe_init_begin[0] - &_rsbe_init_begin[0]; 407 for (i = 0; i < table_entries; i++) { 408 if (bus[i]->type == step->type) 409 return bus[i]; 410 } 411 412 /* Bus not found */ 413 return NULL; 414 } 415 416 static void reg_script_display(struct reg_script_context *ctx, 417 const struct reg_script *step, const char *arrow, uint64_t value) 418 { 419 /* Display the register address and data */ 420 if (ctx->display_prefix != NULL) 421 printk(BIOS_INFO, "%s: ", ctx->display_prefix); 422 if (ctx->display_features & REG_SCRIPT_DISPLAY_REGISTER) 423 printk(BIOS_INFO, "0x%08x %s ", step->reg, arrow); 424 if (ctx->display_features & REG_SCRIPT_DISPLAY_VALUE) 425 switch (step->size) { 426 case REG_SCRIPT_SIZE_8: 427 printk(BIOS_INFO, "0x%02x\n", (uint8_t)value); 428 break; 429 case REG_SCRIPT_SIZE_16: 430 printk(BIOS_INFO, "0x%04x\n", (int16_t)value); 431 break; 432 case REG_SCRIPT_SIZE_32: 433 printk(BIOS_INFO, "0x%08x\n", (uint32_t)value); 434 break; 435 default: 436 printk(BIOS_INFO, "0x%016llx\n", value); 437 break; 438 } 439 } 440 441 static uint64_t reg_script_read(struct reg_script_context *ctx) 442 { 443 const struct reg_script *step = reg_script_get_step(ctx); 444 uint64_t value = 0; 445 446 switch (step->type) { 447 case REG_SCRIPT_TYPE_PCI: 448 ctx->display_prefix = "PCI"; 449 value = reg_script_read_pci(ctx); 450 break; 451 #if HAS_ARCH_IO 452 case REG_SCRIPT_TYPE_IO: 453 ctx->display_prefix = "IO"; 454 value = reg_script_read_io(ctx); 455 break; 456 #endif 457 case REG_SCRIPT_TYPE_MMIO: 458 ctx->display_prefix = "MMIO"; 459 value = reg_script_read_mmio(ctx); 460 break; 461 case REG_SCRIPT_TYPE_RES: 462 ctx->display_prefix = "RES"; 463 value = reg_script_read_res(ctx); 464 break; 465 case REG_SCRIPT_TYPE_MSR: 466 ctx->display_prefix = "MSR"; 467 value = reg_script_read_msr(ctx); 468 break; 469 #if HAS_IOSF 470 case REG_SCRIPT_TYPE_IOSF: 471 ctx->display_prefix = "IOSF"; 472 value = reg_script_read_iosf(ctx); 473 break; 474 #endif /* HAS_IOSF */ 475 default: 476 { 477 const struct reg_script_bus_entry *bus; 478 479 /* Read from the platform specific bus */ 480 bus = find_bus(step); 481 if (bus != NULL) { 482 value = bus->reg_script_read(ctx); 483 break; 484 } 485 } 486 printk(BIOS_ERR, 487 "Unsupported read type (0x%x) for this device!\n", 488 step->type); 489 return 0; 490 } 491 492 /* Display the register address and data */ 493 if (ctx->display_features) 494 reg_script_display(ctx, step, "-->", value); 495 return value; 496 } 497 498 static void reg_script_write(struct reg_script_context *ctx) 499 { 500 const struct reg_script *step = reg_script_get_step(ctx); 501 502 switch (step->type) { 503 case REG_SCRIPT_TYPE_PCI: 504 ctx->display_prefix = "PCI"; 505 reg_script_write_pci(ctx); 506 break; 507 #if HAS_ARCH_IO 508 case REG_SCRIPT_TYPE_IO: 509 ctx->display_prefix = "IO"; 510 reg_script_write_io(ctx); 511 break; 512 #endif 513 case REG_SCRIPT_TYPE_MMIO: 514 ctx->display_prefix = "MMIO"; 515 reg_script_write_mmio(ctx); 516 break; 517 case REG_SCRIPT_TYPE_RES: 518 ctx->display_prefix = "RES"; 519 reg_script_write_res(ctx); 520 break; 521 case REG_SCRIPT_TYPE_MSR: 522 ctx->display_prefix = "MSR"; 523 reg_script_write_msr(ctx); 524 break; 525 #if HAS_IOSF 526 case REG_SCRIPT_TYPE_IOSF: 527 ctx->display_prefix = "IOSF"; 528 reg_script_write_iosf(ctx); 529 break; 530 #endif /* HAS_IOSF */ 531 default: 532 { 533 const struct reg_script_bus_entry *bus; 534 535 /* Write to the platform specific bus */ 536 bus = find_bus(step); 537 if (bus != NULL) { 538 bus->reg_script_write(ctx); 539 break; 540 } 541 } 542 printk(BIOS_ERR, 543 "Unsupported write type (0x%x) for this device!\n", 544 step->type); 545 return; 546 } 547 548 /* Display the register address and data */ 549 if (ctx->display_features) 550 reg_script_display(ctx, step, "<--", step->value); 551 } 552 553 static void reg_script_rmw(struct reg_script_context *ctx) 554 { 555 uint64_t value; 556 const struct reg_script *step = reg_script_get_step(ctx); 557 struct reg_script write_step = *step; 558 559 value = reg_script_read(ctx); 560 value &= step->mask; 561 value |= step->value; 562 write_step.value = value; 563 reg_script_set_step(ctx, &write_step); 564 reg_script_write(ctx); 565 reg_script_set_step(ctx, step); 566 } 567 568 static void reg_script_rxw(struct reg_script_context *ctx) 569 { 570 uint64_t value; 571 const struct reg_script *step = reg_script_get_step(ctx); 572 struct reg_script write_step = *step; 573 574 /* 575 * XOR logic table 576 * Input XOR Value 577 * 0 0 0 578 * 0 1 1 579 * 1 0 1 580 * 1 1 0 581 * 582 * Supported operations 583 * 584 * Input Mask Temp XOR Value Operation 585 * 0 0 0 0 0 Clear bit 586 * 1 0 0 0 0 587 * 0 0 0 1 1 Set bit 588 * 1 0 0 1 1 589 * 0 1 0 0 0 Preserve bit 590 * 1 1 1 0 1 591 * 0 1 0 1 1 Toggle bit 592 * 1 1 1 1 0 593 */ 594 value = reg_script_read(ctx); 595 value &= step->mask; 596 value ^= step->value; 597 write_step.value = value; 598 reg_script_set_step(ctx, &write_step); 599 reg_script_write(ctx); 600 reg_script_set_step(ctx, step); 601 } 602 603 /* In order to easily chain scripts together handle the REG_SCRIPT_COMMAND_NEXT 604 * as recursive call with a new context that has the same dev and resource 605 * as the previous one. That will run to completion and then move on to the 606 * next step of the previous context. */ 607 static void reg_script_run_next(struct reg_script_context *ctx, 608 const struct reg_script *step); 609 610 611 static void reg_script_run_step(struct reg_script_context *ctx, 612 const struct reg_script *step) 613 { 614 uint64_t value = 0, try; 615 616 ctx->display_features = ctx->display_state; 617 ctx->display_prefix = NULL; 618 switch (step->command) { 619 case REG_SCRIPT_COMMAND_READ: 620 (void)reg_script_read(ctx); 621 break; 622 case REG_SCRIPT_COMMAND_WRITE: 623 reg_script_write(ctx); 624 break; 625 case REG_SCRIPT_COMMAND_RMW: 626 reg_script_rmw(ctx); 627 break; 628 case REG_SCRIPT_COMMAND_RXW: 629 reg_script_rxw(ctx); 630 break; 631 case REG_SCRIPT_COMMAND_POLL: 632 for (try = 0; try < step->timeout; try += POLL_DELAY) { 633 value = reg_script_read(ctx) & step->mask; 634 if (value == step->value) 635 break; 636 udelay(POLL_DELAY); 637 } 638 if (try >= step->timeout) 639 printk(BIOS_WARNING, "%s: POLL timeout waiting for " 640 "0x%x to be 0x%lx, got 0x%lx\n", __func__, 641 step->reg, (unsigned long)step->value, 642 (unsigned long)value); 643 break; 644 case REG_SCRIPT_COMMAND_SET_DEV: 645 reg_script_set_dev(ctx, step->dev); 646 break; 647 case REG_SCRIPT_COMMAND_NEXT: 648 reg_script_run_next(ctx, step->next); 649 break; 650 case REG_SCRIPT_COMMAND_DISPLAY: 651 ctx->display_state = step->value; 652 break; 653 654 default: 655 printk(BIOS_WARNING, "Invalid command: %08x\n", 656 step->command); 657 break; 658 } 659 } 660 661 static void reg_script_run_with_context(struct reg_script_context *ctx) 662 { 663 while (1) { 664 const struct reg_script *step = reg_script_get_step(ctx); 665 666 if (step->command == REG_SCRIPT_COMMAND_END) 667 break; 668 669 reg_script_run_step(ctx, step); 670 reg_script_set_step(ctx, step + 1); 671 } 672 } 673 674 static void reg_script_run_next(struct reg_script_context *prev_ctx, 675 const struct reg_script *step) 676 { 677 struct reg_script_context ctx; 678 679 /* Use prev context as a basis but start at a new step. */ 680 ctx = *prev_ctx; 681 reg_script_set_step(&ctx, step); 682 reg_script_run_with_context(&ctx); 683 } 684 685 #ifdef __SIMPLE_DEVICE__ 686 void reg_script_run_on_dev(pci_devfn_t dev, const struct reg_script *step) 687 #else 688 void reg_script_run_on_dev(struct device *dev, const struct reg_script *step) 689 #endif 690 { 691 struct reg_script_context ctx; 692 693 ctx.display_state = REG_SCRIPT_DISPLAY_NOTHING; 694 reg_script_set_dev(&ctx, dev); 695 reg_script_set_step(&ctx, step); 696 reg_script_run_with_context(&ctx); 697 } 698 699 void reg_script_run(const struct reg_script *step) 700 { 701 reg_script_run_on_dev(EMPTY_DEV, step); 702 }