1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * AMD HSMP Platform Driver 4 * Copyright (c) 2022, AMD. 5 * All Rights Reserved. 6 * 7 * This file provides a device implementation for HSMP interface 8 */ 9 10 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 11 12 #include <asm/amd_hsmp.h> 13 #include <asm/amd_nb.h> 14 15 #include <linux/acpi.h> 16 #include <linux/delay.h> 17 #include <linux/device.h> 18 #include <linux/module.h> 19 #include <linux/platform_device.h> 20 #include <linux/semaphore.h> 21 #include <linux/sysfs.h> 22 23 #include "hsmp.h" 24 25 #define DRIVER_NAME "amd_hsmp" 26 #define DRIVER_VERSION "2.2" 27 #define ACPI_HSMP_DEVICE_HID "AMDI0097" 28 29 /* HSMP Status / Error codes */ 30 #define HSMP_STATUS_NOT_READY 0x00 31 #define HSMP_STATUS_OK 0x01 32 #define HSMP_ERR_INVALID_MSG 0xFE 33 #define HSMP_ERR_INVALID_INPUT 0xFF 34 35 /* Timeout in millsec */ 36 #define HSMP_MSG_TIMEOUT 100 37 #define HSMP_SHORT_SLEEP 1 38 39 #define HSMP_WR true 40 #define HSMP_RD false 41 42 struct hsmp_plat_device hsmp_pdev; 43 44 /* 45 * Send a message to the HSMP port via PCI-e config space registers 46 * or by writing to MMIO space. 47 * 48 * The caller is expected to zero out any unused arguments. 49 * If a response is expected, the number of response words should be greater than 0. 50 * 51 * Returns 0 for success and populates the requested number of arguments. 52 * Returns a negative error code for failure. 53 */ 54 static int __hsmp_send_message(struct hsmp_socket *sock, struct hsmp_message *msg) 55 { 56 struct hsmp_mbaddr_info *mbinfo; 57 unsigned long timeout, short_sleep; 58 u32 mbox_status; 59 u32 index; 60 int ret; 61 62 mbinfo = &sock->mbinfo; 63 64 /* Clear the status register */ 65 mbox_status = HSMP_STATUS_NOT_READY; 66 ret = sock->amd_hsmp_rdwr(sock, mbinfo->msg_resp_off, &mbox_status, HSMP_WR); 67 if (ret) { 68 pr_err("Error %d clearing mailbox status register\n", ret); 69 return ret; 70 } 71 72 index = 0; 73 /* Write any message arguments */ 74 while (index < msg->num_args) { 75 ret = sock->amd_hsmp_rdwr(sock, mbinfo->msg_arg_off + (index << 2), 76 &msg->args[index], HSMP_WR); 77 if (ret) { 78 pr_err("Error %d writing message argument %d\n", ret, index); 79 return ret; 80 } 81 index++; 82 } 83 84 /* Write the message ID which starts the operation */ 85 ret = sock->amd_hsmp_rdwr(sock, mbinfo->msg_id_off, &msg->msg_id, HSMP_WR); 86 if (ret) { 87 pr_err("Error %d writing message ID %u\n", ret, msg->msg_id); 88 return ret; 89 } 90 91 /* 92 * Depending on when the trigger write completes relative to the SMU 93 * firmware 1 ms cycle, the operation may take from tens of us to 1 ms 94 * to complete. Some operations may take more. Therefore we will try 95 * a few short duration sleeps and switch to long sleeps if we don't 96 * succeed quickly. 97 */ 98 short_sleep = jiffies + msecs_to_jiffies(HSMP_SHORT_SLEEP); 99 timeout = jiffies + msecs_to_jiffies(HSMP_MSG_TIMEOUT); 100 101 while (time_before(jiffies, timeout)) { 102 ret = sock->amd_hsmp_rdwr(sock, mbinfo->msg_resp_off, &mbox_status, HSMP_RD); 103 if (ret) { 104 pr_err("Error %d reading mailbox status\n", ret); 105 return ret; 106 } 107 108 if (mbox_status != HSMP_STATUS_NOT_READY) 109 break; 110 if (time_before(jiffies, short_sleep)) 111 usleep_range(50, 100); 112 else 113 usleep_range(1000, 2000); 114 } 115 116 if (unlikely(mbox_status == HSMP_STATUS_NOT_READY)) { 117 return -ETIMEDOUT; 118 } else if (unlikely(mbox_status == HSMP_ERR_INVALID_MSG)) { 119 return -ENOMSG; 120 } else if (unlikely(mbox_status == HSMP_ERR_INVALID_INPUT)) { 121 return -EINVAL; 122 } else if (unlikely(mbox_status != HSMP_STATUS_OK)) { 123 pr_err("Message ID %u unknown failure (status = 0x%X)\n", 124 msg->msg_id, mbox_status); 125 return -EIO; 126 } 127 128 /* 129 * SMU has responded OK. Read response data. 130 * SMU reads the input arguments from eight 32 bit registers starting 131 * from SMN_HSMP_MSG_DATA and writes the response data to the same 132 * SMN_HSMP_MSG_DATA address. 133 * We copy the response data if any, back to the args[]. 134 */ 135 index = 0; 136 while (index < msg->response_sz) { 137 ret = sock->amd_hsmp_rdwr(sock, mbinfo->msg_arg_off + (index << 2), 138 &msg->args[index], HSMP_RD); 139 if (ret) { 140 pr_err("Error %d reading response %u for message ID:%u\n", 141 ret, index, msg->msg_id); 142 break; 143 } 144 index++; 145 } 146 147 return ret; 148 } 149 150 static int validate_message(struct hsmp_message *msg) 151 { 152 /* msg_id against valid range of message IDs */ 153 if (msg->msg_id < HSMP_TEST || msg->msg_id >= HSMP_MSG_ID_MAX) 154 return -ENOMSG; 155 156 /* msg_id is a reserved message ID */ 157 if (hsmp_msg_desc_table[msg->msg_id].type == HSMP_RSVD) 158 return -ENOMSG; 159 160 /* num_args and response_sz against the HSMP spec */ 161 if (msg->num_args != hsmp_msg_desc_table[msg->msg_id].num_args || 162 msg->response_sz != hsmp_msg_desc_table[msg->msg_id].response_sz) 163 return -EINVAL; 164 165 return 0; 166 } 167 168 int hsmp_send_message(struct hsmp_message *msg) 169 { 170 struct hsmp_socket *sock; 171 int ret; 172 173 if (!msg) 174 return -EINVAL; 175 ret = validate_message(msg); 176 if (ret) 177 return ret; 178 179 if (!hsmp_pdev.sock || msg->sock_ind >= hsmp_pdev.num_sockets) 180 return -ENODEV; 181 sock = &hsmp_pdev.sock[msg->sock_ind]; 182 183 /* 184 * The time taken by smu operation to complete is between 185 * 10us to 1ms. Sometime it may take more time. 186 * In SMP system timeout of 100 millisecs should 187 * be enough for the previous thread to finish the operation 188 */ 189 ret = down_timeout(&sock->hsmp_sem, msecs_to_jiffies(HSMP_MSG_TIMEOUT)); 190 if (ret < 0) 191 return ret; 192 193 ret = __hsmp_send_message(sock, msg); 194 195 up(&sock->hsmp_sem); 196 197 return ret; 198 } 199 EXPORT_SYMBOL_GPL(hsmp_send_message); 200 201 int hsmp_test(u16 sock_ind, u32 value) 202 { 203 struct hsmp_message msg = { 0 }; 204 int ret; 205 206 /* 207 * Test the hsmp port by performing TEST command. The test message 208 * takes one argument and returns the value of that argument + 1. 209 */ 210 msg.msg_id = HSMP_TEST; 211 msg.num_args = 1; 212 msg.response_sz = 1; 213 msg.args[0] = value; 214 msg.sock_ind = sock_ind; 215 216 ret = hsmp_send_message(&msg); 217 if (ret) 218 return ret; 219 220 /* Check the response value */ 221 if (msg.args[0] != (value + 1)) { 222 dev_err(hsmp_pdev.sock[sock_ind].dev, 223 "Socket %d test message failed, Expected 0x%08X, received 0x%08X\n", 224 sock_ind, (value + 1), msg.args[0]); 225 return -EBADE; 226 } 227 228 return ret; 229 } 230 231 static long hsmp_ioctl(struct file *fp, unsigned int cmd, unsigned long arg) 232 { 233 int __user *arguser = (int __user *)arg; 234 struct hsmp_message msg = { 0 }; 235 int ret; 236 237 if (copy_struct_from_user(&msg, sizeof(msg), arguser, sizeof(struct hsmp_message))) 238 return -EFAULT; 239 240 /* 241 * Check msg_id is within the range of supported msg ids 242 * i.e within the array bounds of hsmp_msg_desc_table 243 */ 244 if (msg.msg_id < HSMP_TEST || msg.msg_id >= HSMP_MSG_ID_MAX) 245 return -ENOMSG; 246 247 switch (fp->f_mode & (FMODE_WRITE | FMODE_READ)) { 248 case FMODE_WRITE: 249 /* 250 * Device is opened in O_WRONLY mode 251 * Execute only set/configure commands 252 */ 253 if (hsmp_msg_desc_table[msg.msg_id].type != HSMP_SET) 254 return -EINVAL; 255 break; 256 case FMODE_READ: 257 /* 258 * Device is opened in O_RDONLY mode 259 * Execute only get/monitor commands 260 */ 261 if (hsmp_msg_desc_table[msg.msg_id].type != HSMP_GET) 262 return -EINVAL; 263 break; 264 case FMODE_READ | FMODE_WRITE: 265 /* 266 * Device is opened in O_RDWR mode 267 * Execute both get/monitor and set/configure commands 268 */ 269 break; 270 default: 271 return -EINVAL; 272 } 273 274 ret = hsmp_send_message(&msg); 275 if (ret) 276 return ret; 277 278 if (hsmp_msg_desc_table[msg.msg_id].response_sz > 0) { 279 /* Copy results back to user for get/monitor commands */ 280 if (copy_to_user(arguser, &msg, sizeof(struct hsmp_message))) 281 return -EFAULT; 282 } 283 284 return 0; 285 } 286 287 static const struct file_operations hsmp_fops = { 288 .owner = THIS_MODULE, 289 .unlocked_ioctl = hsmp_ioctl, 290 .compat_ioctl = hsmp_ioctl, 291 }; 292 293 ssize_t hsmp_metric_tbl_read(struct file *filp, struct kobject *kobj, 294 struct bin_attribute *bin_attr, char *buf, 295 loff_t off, size_t count) 296 { 297 struct hsmp_socket *sock = bin_attr->private; 298 struct hsmp_message msg = { 0 }; 299 int ret; 300 301 if (!sock) 302 return -EINVAL; 303 304 /* Do not support lseek(), reads entire metric table */ 305 if (count < bin_attr->size) { 306 dev_err(sock->dev, "Wrong buffer size\n"); 307 return -EINVAL; 308 } 309 310 msg.msg_id = HSMP_GET_METRIC_TABLE; 311 msg.sock_ind = sock->sock_ind; 312 313 ret = hsmp_send_message(&msg); 314 if (ret) 315 return ret; 316 memcpy_fromio(buf, sock->metric_tbl_addr, bin_attr->size); 317 318 return bin_attr->size; 319 } 320 321 static int hsmp_get_tbl_dram_base(u16 sock_ind) 322 { 323 struct hsmp_socket *sock = &hsmp_pdev.sock[sock_ind]; 324 struct hsmp_message msg = { 0 }; 325 phys_addr_t dram_addr; 326 int ret; 327 328 msg.sock_ind = sock_ind; 329 msg.response_sz = hsmp_msg_desc_table[HSMP_GET_METRIC_TABLE_DRAM_ADDR].response_sz; 330 msg.msg_id = HSMP_GET_METRIC_TABLE_DRAM_ADDR; 331 332 ret = hsmp_send_message(&msg); 333 if (ret) 334 return ret; 335 336 /* 337 * calculate the metric table DRAM address from lower and upper 32 bits 338 * sent from SMU and ioremap it to virtual address. 339 */ 340 dram_addr = msg.args[0] | ((u64)(msg.args[1]) << 32); 341 if (!dram_addr) { 342 dev_err(sock->dev, "Invalid DRAM address for metric table\n"); 343 return -ENOMEM; 344 } 345 sock->metric_tbl_addr = devm_ioremap(sock->dev, dram_addr, 346 sizeof(struct hsmp_metric_table)); 347 if (!sock->metric_tbl_addr) { 348 dev_err(sock->dev, "Failed to ioremap metric table addr\n"); 349 return -ENOMEM; 350 } 351 return 0; 352 } 353 354 umode_t hsmp_is_sock_attr_visible(struct kobject *kobj, 355 struct bin_attribute *battr, int id) 356 { 357 if (hsmp_pdev.proto_ver == HSMP_PROTO_VER6) 358 return battr->attr.mode; 359 else 360 return 0; 361 } 362 363 static int hsmp_init_metric_tbl_bin_attr(struct bin_attribute **hattrs, u16 sock_ind) 364 { 365 struct bin_attribute *hattr = &hsmp_pdev.sock[sock_ind].hsmp_attr; 366 367 sysfs_bin_attr_init(hattr); 368 hattr->attr.name = HSMP_METRICS_TABLE_NAME; 369 hattr->attr.mode = 0444; 370 hattr->read = hsmp_metric_tbl_read; 371 hattr->size = sizeof(struct hsmp_metric_table); 372 hattr->private = &hsmp_pdev.sock[sock_ind]; 373 hattrs[0] = hattr; 374 375 if (hsmp_pdev.proto_ver == HSMP_PROTO_VER6) 376 return hsmp_get_tbl_dram_base(sock_ind); 377 else 378 return 0; 379 } 380 381 /* One bin sysfs for metrics table */ 382 #define NUM_HSMP_ATTRS 1 383 384 int hsmp_create_attr_list(struct attribute_group *attr_grp, 385 struct device *dev, u16 sock_ind) 386 { 387 struct bin_attribute **hsmp_bin_attrs; 388 389 /* Null terminated list of attributes */ 390 hsmp_bin_attrs = devm_kcalloc(dev, NUM_HSMP_ATTRS + 1, 391 sizeof(*hsmp_bin_attrs), 392 GFP_KERNEL); 393 if (!hsmp_bin_attrs) 394 return -ENOMEM; 395 396 attr_grp->bin_attrs = hsmp_bin_attrs; 397 398 return hsmp_init_metric_tbl_bin_attr(hsmp_bin_attrs, sock_ind); 399 } 400 401 int hsmp_cache_proto_ver(u16 sock_ind) 402 { 403 struct hsmp_message msg = { 0 }; 404 int ret; 405 406 msg.msg_id = HSMP_GET_PROTO_VER; 407 msg.sock_ind = sock_ind; 408 msg.response_sz = hsmp_msg_desc_table[HSMP_GET_PROTO_VER].response_sz; 409 410 ret = hsmp_send_message(&msg); 411 if (!ret) 412 hsmp_pdev.proto_ver = msg.args[0]; 413 414 return ret; 415 } 416 417 static const struct acpi_device_id amd_hsmp_acpi_ids[] = { 418 {ACPI_HSMP_DEVICE_HID, 0}, 419 {} 420 }; 421 MODULE_DEVICE_TABLE(acpi, amd_hsmp_acpi_ids); 422 423 static bool check_acpi_support(struct device *dev) 424 { 425 struct acpi_device *adev = ACPI_COMPANION(dev); 426 427 if (adev && !acpi_match_device_ids(adev, amd_hsmp_acpi_ids)) 428 return true; 429 430 return false; 431 } 432 433 static int hsmp_pltdrv_probe(struct platform_device *pdev) 434 { 435 int ret; 436 437 /* 438 * On ACPI supported BIOS, there is an ACPI HSMP device added for 439 * each socket, so the per socket probing, but the memory allocated for 440 * sockets should be contiguous to access it as an array, 441 * Hence allocate memory for all the sockets at once instead of allocating 442 * on each probe. 443 */ 444 if (!hsmp_pdev.is_probed) { 445 hsmp_pdev.sock = devm_kcalloc(&pdev->dev, hsmp_pdev.num_sockets, 446 sizeof(*hsmp_pdev.sock), 447 GFP_KERNEL); 448 if (!hsmp_pdev.sock) 449 return -ENOMEM; 450 } 451 if (check_acpi_support(&pdev->dev)) { 452 ret = init_acpi(&pdev->dev); 453 if (ret) { 454 dev_err(&pdev->dev, "Failed to init HSMP mailbox\n"); 455 return ret; 456 } 457 ret = hsmp_create_acpi_sysfs_if(&pdev->dev); 458 if (ret) 459 dev_err(&pdev->dev, "Failed to create HSMP sysfs interface\n"); 460 } else { 461 ret = init_platform_device(&pdev->dev); 462 if (ret) { 463 dev_err(&pdev->dev, "Failed to init HSMP mailbox\n"); 464 return ret; 465 } 466 ret = hsmp_create_non_acpi_sysfs_if(&pdev->dev); 467 if (ret) 468 dev_err(&pdev->dev, "Failed to create HSMP sysfs interface\n"); 469 } 470 471 if (!hsmp_pdev.is_probed) { 472 hsmp_pdev.mdev.name = HSMP_CDEV_NAME; 473 hsmp_pdev.mdev.minor = MISC_DYNAMIC_MINOR; 474 hsmp_pdev.mdev.fops = &hsmp_fops; 475 hsmp_pdev.mdev.parent = &pdev->dev; 476 hsmp_pdev.mdev.nodename = HSMP_DEVNODE_NAME; 477 hsmp_pdev.mdev.mode = 0644; 478 479 ret = misc_register(&hsmp_pdev.mdev); 480 if (ret) 481 return ret; 482 483 hsmp_pdev.is_probed = true; 484 } 485 486 return 0; 487 488 } 489 490 static void hsmp_pltdrv_remove(struct platform_device *pdev) 491 { 492 /* 493 * We register only one misc_device even on multi socket system. 494 * So, deregister should happen only once. 495 */ 496 if (hsmp_pdev.is_probed) { 497 misc_deregister(&hsmp_pdev.mdev); 498 hsmp_pdev.is_probed = false; 499 } 500 } 501 502 static struct platform_driver amd_hsmp_driver = { 503 .probe = hsmp_pltdrv_probe, 504 .remove = hsmp_pltdrv_remove, 505 .driver = { 506 .name = DRIVER_NAME, 507 .acpi_match_table = amd_hsmp_acpi_ids, 508 }, 509 }; 510 511 static struct platform_device *amd_hsmp_platdev; 512 513 static int hsmp_plat_dev_register(void) 514 { 515 int ret; 516 517 amd_hsmp_platdev = platform_device_alloc(DRIVER_NAME, PLATFORM_DEVID_NONE); 518 if (!amd_hsmp_platdev) 519 return -ENOMEM; 520 521 ret = platform_device_add(amd_hsmp_platdev); 522 if (ret) 523 platform_device_put(amd_hsmp_platdev); 524 525 return ret; 526 } 527 528 /* 529 * This check is only needed for backward compatibility of previous platforms. 530 * All new platforms are expected to support ACPI based probing. 531 */ 532 static bool legacy_hsmp_support(void) 533 { 534 if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD) 535 return false; 536 537 switch (boot_cpu_data.x86) { 538 case 0x19: 539 switch (boot_cpu_data.x86_model) { 540 case 0x00 ... 0x1F: 541 case 0x30 ... 0x3F: 542 case 0x90 ... 0x9F: 543 case 0xA0 ... 0xAF: 544 return true; 545 default: 546 return false; 547 } 548 case 0x1A: 549 switch (boot_cpu_data.x86_model) { 550 case 0x00 ... 0x1F: 551 return true; 552 default: 553 return false; 554 } 555 default: 556 return false; 557 } 558 559 return false; 560 } 561 562 static int __init hsmp_plt_init(void) 563 { 564 int ret = -ENODEV; 565 566 /* 567 * amd_nb_num() returns number of SMN/DF interfaces present in the system 568 * if we have N SMN/DF interfaces that ideally means N sockets 569 */ 570 hsmp_pdev.num_sockets = amd_nb_num(); 571 if (hsmp_pdev.num_sockets == 0 || hsmp_pdev.num_sockets > MAX_AMD_SOCKETS) 572 return ret; 573 574 ret = platform_driver_register(&amd_hsmp_driver); 575 if (ret) 576 return ret; 577 578 if (!hsmp_pdev.is_acpi_device) { 579 if (legacy_hsmp_support()) { 580 /* Not ACPI device, but supports HSMP, register a plat_dev */ 581 ret = hsmp_plat_dev_register(); 582 } else { 583 /* Not ACPI, Does not support HSMP */ 584 pr_info("HSMP is not supported on Family:%x model:%x\n", 585 boot_cpu_data.x86, boot_cpu_data.x86_model); 586 ret = -ENODEV; 587 } 588 if (ret) 589 platform_driver_unregister(&amd_hsmp_driver); 590 } 591 592 return ret; 593 } 594 595 static void __exit hsmp_plt_exit(void) 596 { 597 platform_device_unregister(amd_hsmp_platdev); 598 platform_driver_unregister(&amd_hsmp_driver); 599 } 600 601 device_initcall(hsmp_plt_init); 602 module_exit(hsmp_plt_exit); 603 604 MODULE_DESCRIPTION("AMD HSMP Platform Interface Driver"); 605 MODULE_VERSION(DRIVER_VERSION); 606 MODULE_LICENSE("GPL v2"); 607