Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

platform/x86: amd-pmc: Add support for AMD Spill to DRAM STB feature

Spill to DRAM functionality is a feature that allows STB (Smart Trace
Buffer) to spill data from SRAM into DRAM on some future AMD ASICs. The
size allocated for STB is more than the earlier SoC's which helps to
collect more tracing and telemetry data.

Co-developed-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
Signed-off-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
Signed-off-by: Sanket Goswami <Sanket.Goswami@amd.com>
Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
Link: https://lore.kernel.org/r/20220204122527.3873552-1-Sanket.Goswami@amd.com
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>

authored by

Sanket Goswami and committed by
Hans de Goede
3d7d407d dbce412a

+130 -14
+130 -14
drivers/platform/x86/amd-pmc.c
··· 41 41 #define AMD_PMC_STB_PMI_0 0x03E30600 42 42 #define AMD_PMC_STB_PREDEF 0xC6000001 43 43 44 + /* STB S2D(Spill to DRAM) has different message port offset */ 45 + #define STB_SPILL_TO_DRAM 0xBE 46 + #define AMD_S2D_REGISTER_MESSAGE 0xA20 47 + #define AMD_S2D_REGISTER_RESPONSE 0xA80 48 + #define AMD_S2D_REGISTER_ARGUMENT 0xA88 49 + 50 + /* STB Spill to DRAM Parameters */ 51 + #define S2D_TELEMETRY_BYTES_MAX 0x100000 52 + #define S2D_TELEMETRY_DRAMBYTES_MAX 0x1000000 53 + 44 54 /* Base address of SMU for mapping physical address to virtual address */ 45 55 #define AMD_PMC_SMU_INDEX_ADDRESS 0xB8 46 56 #define AMD_PMC_SMU_INDEX_DATA 0xBC ··· 105 95 MSG_OS_HINT_RN, 106 96 }; 107 97 98 + enum s2d_arg { 99 + S2D_TELEMETRY_SIZE = 0x01, 100 + S2D_PHYS_ADDR_LOW, 101 + S2D_PHYS_ADDR_HIGH, 102 + }; 103 + 108 104 struct amd_pmc_bit_map { 109 105 const char *name; 110 106 u32 bit_mask; ··· 135 119 struct amd_pmc_dev { 136 120 void __iomem *regbase; 137 121 void __iomem *smu_virt_addr; 122 + void __iomem *stb_virt_addr; 138 123 void __iomem *fch_virt_addr; 124 + bool msg_port; 139 125 u32 base_addr; 140 126 u32 cpu_id; 141 127 u32 active_ips; ··· 254 236 .release = amd_pmc_stb_debugfs_release, 255 237 }; 256 238 239 + static int amd_pmc_stb_debugfs_open_v2(struct inode *inode, struct file *filp) 240 + { 241 + struct amd_pmc_dev *dev = filp->f_inode->i_private; 242 + u32 *buf; 243 + 244 + buf = kzalloc(S2D_TELEMETRY_BYTES_MAX, GFP_KERNEL); 245 + if (!buf) 246 + return -ENOMEM; 247 + 248 + memcpy_fromio(buf, dev->stb_virt_addr, S2D_TELEMETRY_BYTES_MAX); 249 + filp->private_data = buf; 250 + 251 + return 0; 252 + } 253 + 254 + static ssize_t amd_pmc_stb_debugfs_read_v2(struct file *filp, char __user *buf, size_t size, 255 + loff_t *pos) 256 + { 257 + if (!filp->private_data) 258 + return -EINVAL; 259 + 260 + return simple_read_from_buffer(buf, size, pos, filp->private_data, 261 + S2D_TELEMETRY_BYTES_MAX); 262 + } 263 + 264 + static int amd_pmc_stb_debugfs_release_v2(struct inode *inode, struct file *filp) 265 + { 266 + kfree(filp->private_data); 267 + return 0; 268 + } 269 + 270 + static const struct file_operations amd_pmc_stb_debugfs_fops_v2 = { 271 + .owner = THIS_MODULE, 272 + .open = amd_pmc_stb_debugfs_open_v2, 273 + .read = amd_pmc_stb_debugfs_read_v2, 274 + .release = amd_pmc_stb_debugfs_release_v2, 275 + }; 276 + 257 277 static int amd_pmc_idlemask_read(struct amd_pmc_dev *pdev, struct device *dev, 258 278 struct seq_file *s) 259 279 { ··· 406 350 debugfs_create_file("amd_pmc_idlemask", 0644, dev->dbgfs_dir, dev, 407 351 &amd_pmc_idlemask_fops); 408 352 /* Enable STB only when the module_param is set */ 409 - if (enable_stb) 410 - debugfs_create_file("stb_read", 0644, dev->dbgfs_dir, dev, 411 - &amd_pmc_stb_debugfs_fops); 353 + if (enable_stb) { 354 + if (dev->cpu_id == AMD_CPU_ID_YC) 355 + debugfs_create_file("stb_read", 0644, dev->dbgfs_dir, dev, 356 + &amd_pmc_stb_debugfs_fops_v2); 357 + else 358 + debugfs_create_file("stb_read", 0644, dev->dbgfs_dir, dev, 359 + &amd_pmc_stb_debugfs_fops); 360 + } 412 361 } 413 362 #else 414 363 static inline void amd_pmc_dbgfs_register(struct amd_pmc_dev *dev) ··· 453 392 454 393 static void amd_pmc_dump_registers(struct amd_pmc_dev *dev) 455 394 { 456 - u32 value; 395 + u32 value, message, argument, response; 457 396 458 - value = amd_pmc_reg_read(dev, AMD_PMC_REGISTER_RESPONSE); 397 + if (dev->msg_port) { 398 + message = AMD_S2D_REGISTER_MESSAGE; 399 + argument = AMD_S2D_REGISTER_ARGUMENT; 400 + response = AMD_S2D_REGISTER_RESPONSE; 401 + } else { 402 + message = AMD_PMC_REGISTER_MESSAGE; 403 + argument = AMD_PMC_REGISTER_ARGUMENT; 404 + response = AMD_PMC_REGISTER_RESPONSE; 405 + } 406 + 407 + value = amd_pmc_reg_read(dev, response); 459 408 dev_dbg(dev->dev, "AMD_PMC_REGISTER_RESPONSE:%x\n", value); 460 409 461 - value = amd_pmc_reg_read(dev, AMD_PMC_REGISTER_ARGUMENT); 410 + value = amd_pmc_reg_read(dev, argument); 462 411 dev_dbg(dev->dev, "AMD_PMC_REGISTER_ARGUMENT:%x\n", value); 463 412 464 - value = amd_pmc_reg_read(dev, AMD_PMC_REGISTER_MESSAGE); 413 + value = amd_pmc_reg_read(dev, message); 465 414 dev_dbg(dev->dev, "AMD_PMC_REGISTER_MESSAGE:%x\n", value); 466 415 } 467 416 468 417 static int amd_pmc_send_cmd(struct amd_pmc_dev *dev, u32 arg, u32 *data, u8 msg, bool ret) 469 418 { 470 419 int rc; 471 - u32 val; 420 + u32 val, message, argument, response; 472 421 473 422 mutex_lock(&dev->lock); 423 + 424 + if (dev->msg_port) { 425 + message = AMD_S2D_REGISTER_MESSAGE; 426 + argument = AMD_S2D_REGISTER_ARGUMENT; 427 + response = AMD_S2D_REGISTER_RESPONSE; 428 + } else { 429 + message = AMD_PMC_REGISTER_MESSAGE; 430 + argument = AMD_PMC_REGISTER_ARGUMENT; 431 + response = AMD_PMC_REGISTER_RESPONSE; 432 + } 433 + 474 434 /* Wait until we get a valid response */ 475 - rc = readx_poll_timeout(ioread32, dev->regbase + AMD_PMC_REGISTER_RESPONSE, 435 + rc = readx_poll_timeout(ioread32, dev->regbase + response, 476 436 val, val != 0, PMC_MSG_DELAY_MIN_US, 477 437 PMC_MSG_DELAY_MIN_US * RESPONSE_REGISTER_LOOP_MAX); 478 438 if (rc) { ··· 502 420 } 503 421 504 422 /* Write zero to response register */ 505 - amd_pmc_reg_write(dev, AMD_PMC_REGISTER_RESPONSE, 0); 423 + amd_pmc_reg_write(dev, response, 0); 506 424 507 425 /* Write argument into response register */ 508 - amd_pmc_reg_write(dev, AMD_PMC_REGISTER_ARGUMENT, arg); 426 + amd_pmc_reg_write(dev, argument, arg); 509 427 510 428 /* Write message ID to message ID register */ 511 - amd_pmc_reg_write(dev, AMD_PMC_REGISTER_MESSAGE, msg); 429 + amd_pmc_reg_write(dev, message, msg); 512 430 513 431 /* Wait until we get a valid response */ 514 - rc = readx_poll_timeout(ioread32, dev->regbase + AMD_PMC_REGISTER_RESPONSE, 432 + rc = readx_poll_timeout(ioread32, dev->regbase + response, 515 433 val, val != 0, PMC_MSG_DELAY_MIN_US, 516 434 PMC_MSG_DELAY_MIN_US * RESPONSE_REGISTER_LOOP_MAX); 517 435 if (rc) { ··· 524 442 if (ret) { 525 443 /* PMFW may take longer time to return back the data */ 526 444 usleep_range(DELAY_MIN_US, 10 * DELAY_MAX_US); 527 - *data = amd_pmc_reg_read(dev, AMD_PMC_REGISTER_ARGUMENT); 445 + *data = amd_pmc_reg_read(dev, argument); 528 446 } 529 447 break; 530 448 case AMD_PMC_RESULT_CMD_REJECT_BUSY: ··· 683 601 { } 684 602 }; 685 603 604 + static int amd_pmc_s2d_init(struct amd_pmc_dev *dev) 605 + { 606 + u32 size, phys_addr_low, phys_addr_hi; 607 + u64 stb_phys_addr; 608 + 609 + /* Spill to DRAM feature uses separate SMU message port */ 610 + dev->msg_port = 1; 611 + 612 + amd_pmc_send_cmd(dev, S2D_TELEMETRY_SIZE, &size, STB_SPILL_TO_DRAM, 1); 613 + if (size != S2D_TELEMETRY_BYTES_MAX) 614 + return -EIO; 615 + 616 + /* Get STB DRAM address */ 617 + amd_pmc_send_cmd(dev, S2D_PHYS_ADDR_LOW, &phys_addr_low, STB_SPILL_TO_DRAM, 1); 618 + amd_pmc_send_cmd(dev, S2D_PHYS_ADDR_HIGH, &phys_addr_hi, STB_SPILL_TO_DRAM, 1); 619 + 620 + stb_phys_addr = ((u64)phys_addr_hi << 32 | phys_addr_low); 621 + 622 + /* Clear msg_port for other SMU operation */ 623 + dev->msg_port = 0; 624 + 625 + dev->stb_virt_addr = devm_ioremap(dev->dev, stb_phys_addr, S2D_TELEMETRY_DRAMBYTES_MAX); 626 + if (!dev->stb_virt_addr) 627 + return -ENOMEM; 628 + 629 + return 0; 630 + } 631 + 686 632 static int amd_pmc_write_stb(struct amd_pmc_dev *dev, u32 data) 687 633 { 688 634 int err; ··· 828 718 err = amd_pmc_setup_smu_logging(dev); 829 719 if (err) 830 720 dev_err(dev->dev, "SMU debugging info not supported on this platform\n"); 721 + 722 + if (enable_stb && dev->cpu_id == AMD_CPU_ID_YC) { 723 + err = amd_pmc_s2d_init(dev); 724 + if (err) 725 + return err; 726 + } 831 727 832 728 amd_pmc_get_smu_version(dev); 833 729 platform_set_drvdata(pdev, dev);