Message ID | 20231212103644.768460-5-suma.hegde@amd.com (mailing list archive) |
---|---|
State | Changes Requested, archived |
Headers | show |
Series | platform/x86: Add ACPI probing support for HSMP | expand |
Hi, On 12/12/23 11:36, Suma Hegde wrote: > Define struct hsmp_mbaddr_info with register offsets and populate > them during probe, which avoids the usage of macros in core functions. > > During ACPI probe, the same fields can be populated from ACPI table. > > Also move plat dev init to a static function. > > Signed-off-by: Suma Hegde <suma.hegde@amd.com> > Co-developed-by: Naveen Krishna Chatradhi <naveenkrishna.chatradhi@amd.com> > Signed-off-by: Naveen Krishna Chatradhi <naveenkrishna.chatradhi@amd.com> This changes behavior before this change hsmp_test() was run on all sockets, now it is only run on a single socket. If that is deliberate then this change needs to be made in a separate patch before this patch. If that change is accidental then please fix it in the next version. Regards, Hans > --- > drivers/platform/x86/amd/hsmp.c | 80 ++++++++++++++++++++++----------- > 1 file changed, 54 insertions(+), 26 deletions(-) > > diff --git a/drivers/platform/x86/amd/hsmp.c b/drivers/platform/x86/amd/hsmp.c > index f0db7a480ace..44b15c1fab6a 100644 > --- a/drivers/platform/x86/amd/hsmp.c > +++ b/drivers/platform/x86/amd/hsmp.c > @@ -40,9 +40,10 @@ > * register into the SMN_INDEX register, and reads/writes the SMN_DATA reg. > * Below are required SMN address for HSMP Mailbox register offsets in SMU address space > */ > -#define SMN_HSMP_MSG_ID 0x3B10534 > -#define SMN_HSMP_MSG_RESP 0x3B10980 > -#define SMN_HSMP_MSG_DATA 0x3B109E0 > +#define SMN_HSMP_BASE 0x3B00000 > +#define SMN_HSMP_MSG_ID 0x0010534 > +#define SMN_HSMP_MSG_RESP 0x0010980 > +#define SMN_HSMP_MSG_DATA 0x00109E0 > > #define HSMP_INDEX_REG 0xc4 > #define HSMP_DATA_REG 0xc8 > @@ -53,8 +54,17 @@ > > #define HSMP_ATTR_GRP_NAME_SIZE 10 > > +struct hsmp_mbaddr_info { > + u32 base_addr; > + u32 msg_id_off; > + u32 msg_resp_off; > + u32 msg_arg_off; > + u32 size; > +}; > + > struct hsmp_socket { > struct bin_attribute hsmp_attr; > + struct hsmp_mbaddr_info mbinfo; > void __iomem *metric_tbl_addr; > struct semaphore hsmp_sem; > char name[HSMP_ATTR_GRP_NAME_SIZE]; > @@ -72,7 +82,7 @@ struct hsmp_plat_device { > > static struct hsmp_plat_device plat_dev; > > -static int amd_hsmp_rdwr(struct hsmp_socket *sock, u32 address, > +static int amd_hsmp_rdwr(struct hsmp_socket *sock, u32 offset, > u32 *value, bool write) > { > int ret; > @@ -80,7 +90,8 @@ static int amd_hsmp_rdwr(struct hsmp_socket *sock, u32 address, > if (!sock->root) > return -ENODEV; > > - ret = pci_write_config_dword(sock->root, HSMP_INDEX_REG, address); > + ret = pci_write_config_dword(sock->root, HSMP_INDEX_REG, > + sock->mbinfo.base_addr + offset); > if (ret) > return ret; > > @@ -101,14 +112,17 @@ static int amd_hsmp_rdwr(struct hsmp_socket *sock, u32 address, > */ > static int __hsmp_send_message(struct hsmp_socket *sock, struct hsmp_message *msg) > { > + struct hsmp_mbaddr_info *mbinfo; > unsigned long timeout, short_sleep; > u32 mbox_status; > u32 index; > int ret; > > + mbinfo = &sock->mbinfo; > + > /* Clear the status register */ > mbox_status = HSMP_STATUS_NOT_READY; > - ret = amd_hsmp_rdwr(sock, SMN_HSMP_MSG_RESP, &mbox_status, HSMP_WR); > + ret = amd_hsmp_rdwr(sock, mbinfo->msg_resp_off, &mbox_status, HSMP_WR); > if (ret) { > pr_err("Error %d clearing mailbox status register\n", ret); > return ret; > @@ -117,7 +131,7 @@ static int __hsmp_send_message(struct hsmp_socket *sock, struct hsmp_message *ms > index = 0; > /* Write any message arguments */ > while (index < msg->num_args) { > - ret = amd_hsmp_rdwr(sock, SMN_HSMP_MSG_DATA + (index << 2), > + ret = amd_hsmp_rdwr(sock, mbinfo->msg_arg_off + (index << 2), > &msg->args[index], HSMP_WR); > if (ret) { > pr_err("Error %d writing message argument %d\n", ret, index); > @@ -127,7 +141,7 @@ static int __hsmp_send_message(struct hsmp_socket *sock, struct hsmp_message *ms > } > > /* Write the message ID which starts the operation */ > - ret = amd_hsmp_rdwr(sock, SMN_HSMP_MSG_ID, &msg->msg_id, HSMP_WR); > + ret = amd_hsmp_rdwr(sock, mbinfo->msg_id_off, &msg->msg_id, HSMP_WR); > if (ret) { > pr_err("Error %d writing message ID %u\n", ret, msg->msg_id); > return ret; > @@ -144,7 +158,7 @@ static int __hsmp_send_message(struct hsmp_socket *sock, struct hsmp_message *ms > timeout = jiffies + msecs_to_jiffies(HSMP_MSG_TIMEOUT); > > while (time_before(jiffies, timeout)) { > - ret = amd_hsmp_rdwr(sock, SMN_HSMP_MSG_RESP, &mbox_status, HSMP_RD); > + ret = amd_hsmp_rdwr(sock, mbinfo->msg_resp_off, &mbox_status, HSMP_RD); > if (ret) { > pr_err("Error %d reading mailbox status\n", ret); > return ret; > @@ -179,7 +193,7 @@ static int __hsmp_send_message(struct hsmp_socket *sock, struct hsmp_message *ms > */ > index = 0; > while (index < msg->response_sz) { > - ret = amd_hsmp_rdwr(sock, SMN_HSMP_MSG_DATA + (index << 2), > + ret = amd_hsmp_rdwr(sock, mbinfo->msg_arg_off + (index << 2), > &msg->args[index], HSMP_RD); > if (ret) { > pr_err("Error %d reading response %u for message ID:%u\n", > @@ -488,9 +502,28 @@ static int hsmp_cache_proto_ver(void) > return ret; > } > > +static int initialize_platdev(void) > +{ > + int i; > + > + for (i = 0; i < plat_dev.num_sockets; i++) { > + if (!node_to_amd_nb(i)) > + return -ENODEV; > + plat_dev.sock[i].root = node_to_amd_nb(i)->root; > + plat_dev.sock[i].sock_ind = i; > + plat_dev.sock[i].mbinfo.base_addr = SMN_HSMP_BASE; > + plat_dev.sock[i].mbinfo.msg_id_off = SMN_HSMP_MSG_ID; > + plat_dev.sock[i].mbinfo.msg_resp_off = SMN_HSMP_MSG_RESP; > + plat_dev.sock[i].mbinfo.msg_arg_off = SMN_HSMP_MSG_DATA; > + sema_init(&plat_dev.sock[i].hsmp_sem, 1); > + } > + > + return 0; > +} > + > static int hsmp_pltdrv_probe(struct platform_device *pdev) > { > - int ret, i; > + int ret; > > plat_dev.sock = devm_kzalloc(&pdev->dev, > (plat_dev.num_sockets * sizeof(struct hsmp_socket)), > @@ -499,22 +532,17 @@ static int hsmp_pltdrv_probe(struct platform_device *pdev) > return -ENOMEM; > plat_dev.dev = &pdev->dev; > > - for (i = 0; i < plat_dev.num_sockets; i++) { > - sema_init(&plat_dev.sock[i].hsmp_sem, 1); > - plat_dev.sock[i].sock_ind = i; > - > - if (!node_to_amd_nb(i)) > - return -ENODEV; > - plat_dev.sock[i].root = node_to_amd_nb(i)->root; > + ret = initialize_platdev(); > + if (ret) > + return ret; > > - /* Test the hsmp interface on each socket */ > - ret = hsmp_test(i, 0xDEADBEEF); > - if (ret) { > - pr_err("HSMP test message failed on Fam:%x model:%x\n", > - boot_cpu_data.x86, boot_cpu_data.x86_model); > - pr_err("Is HSMP disabled in BIOS ?\n"); > - return ret; > - } > + /* Test the hsmp interface */ > + ret = hsmp_test(0, 0xDEADBEEF); > + if (ret) { > + pr_err("HSMP test message failed on Fam:%x model:%x\n", > + boot_cpu_data.x86, boot_cpu_data.x86_model); > + pr_err("Is HSMP disabled in BIOS ?\n"); > + return ret; > } > > plat_dev.hsmp_device.name = HSMP_CDEV_NAME;
diff --git a/drivers/platform/x86/amd/hsmp.c b/drivers/platform/x86/amd/hsmp.c index f0db7a480ace..44b15c1fab6a 100644 --- a/drivers/platform/x86/amd/hsmp.c +++ b/drivers/platform/x86/amd/hsmp.c @@ -40,9 +40,10 @@ * register into the SMN_INDEX register, and reads/writes the SMN_DATA reg. * Below are required SMN address for HSMP Mailbox register offsets in SMU address space */ -#define SMN_HSMP_MSG_ID 0x3B10534 -#define SMN_HSMP_MSG_RESP 0x3B10980 -#define SMN_HSMP_MSG_DATA 0x3B109E0 +#define SMN_HSMP_BASE 0x3B00000 +#define SMN_HSMP_MSG_ID 0x0010534 +#define SMN_HSMP_MSG_RESP 0x0010980 +#define SMN_HSMP_MSG_DATA 0x00109E0 #define HSMP_INDEX_REG 0xc4 #define HSMP_DATA_REG 0xc8 @@ -53,8 +54,17 @@ #define HSMP_ATTR_GRP_NAME_SIZE 10 +struct hsmp_mbaddr_info { + u32 base_addr; + u32 msg_id_off; + u32 msg_resp_off; + u32 msg_arg_off; + u32 size; +}; + struct hsmp_socket { struct bin_attribute hsmp_attr; + struct hsmp_mbaddr_info mbinfo; void __iomem *metric_tbl_addr; struct semaphore hsmp_sem; char name[HSMP_ATTR_GRP_NAME_SIZE]; @@ -72,7 +82,7 @@ struct hsmp_plat_device { static struct hsmp_plat_device plat_dev; -static int amd_hsmp_rdwr(struct hsmp_socket *sock, u32 address, +static int amd_hsmp_rdwr(struct hsmp_socket *sock, u32 offset, u32 *value, bool write) { int ret; @@ -80,7 +90,8 @@ static int amd_hsmp_rdwr(struct hsmp_socket *sock, u32 address, if (!sock->root) return -ENODEV; - ret = pci_write_config_dword(sock->root, HSMP_INDEX_REG, address); + ret = pci_write_config_dword(sock->root, HSMP_INDEX_REG, + sock->mbinfo.base_addr + offset); if (ret) return ret; @@ -101,14 +112,17 @@ static int amd_hsmp_rdwr(struct hsmp_socket *sock, u32 address, */ static int __hsmp_send_message(struct hsmp_socket *sock, struct hsmp_message *msg) { + struct hsmp_mbaddr_info *mbinfo; unsigned long timeout, short_sleep; u32 mbox_status; u32 index; int ret; + mbinfo = &sock->mbinfo; + /* Clear the status register */ mbox_status = HSMP_STATUS_NOT_READY; - ret = amd_hsmp_rdwr(sock, SMN_HSMP_MSG_RESP, &mbox_status, HSMP_WR); + ret = amd_hsmp_rdwr(sock, mbinfo->msg_resp_off, &mbox_status, HSMP_WR); if (ret) { pr_err("Error %d clearing mailbox status register\n", ret); return ret; @@ -117,7 +131,7 @@ static int __hsmp_send_message(struct hsmp_socket *sock, struct hsmp_message *ms index = 0; /* Write any message arguments */ while (index < msg->num_args) { - ret = amd_hsmp_rdwr(sock, SMN_HSMP_MSG_DATA + (index << 2), + ret = amd_hsmp_rdwr(sock, mbinfo->msg_arg_off + (index << 2), &msg->args[index], HSMP_WR); if (ret) { pr_err("Error %d writing message argument %d\n", ret, index); @@ -127,7 +141,7 @@ static int __hsmp_send_message(struct hsmp_socket *sock, struct hsmp_message *ms } /* Write the message ID which starts the operation */ - ret = amd_hsmp_rdwr(sock, SMN_HSMP_MSG_ID, &msg->msg_id, HSMP_WR); + ret = amd_hsmp_rdwr(sock, mbinfo->msg_id_off, &msg->msg_id, HSMP_WR); if (ret) { pr_err("Error %d writing message ID %u\n", ret, msg->msg_id); return ret; @@ -144,7 +158,7 @@ static int __hsmp_send_message(struct hsmp_socket *sock, struct hsmp_message *ms timeout = jiffies + msecs_to_jiffies(HSMP_MSG_TIMEOUT); while (time_before(jiffies, timeout)) { - ret = amd_hsmp_rdwr(sock, SMN_HSMP_MSG_RESP, &mbox_status, HSMP_RD); + ret = amd_hsmp_rdwr(sock, mbinfo->msg_resp_off, &mbox_status, HSMP_RD); if (ret) { pr_err("Error %d reading mailbox status\n", ret); return ret; @@ -179,7 +193,7 @@ static int __hsmp_send_message(struct hsmp_socket *sock, struct hsmp_message *ms */ index = 0; while (index < msg->response_sz) { - ret = amd_hsmp_rdwr(sock, SMN_HSMP_MSG_DATA + (index << 2), + ret = amd_hsmp_rdwr(sock, mbinfo->msg_arg_off + (index << 2), &msg->args[index], HSMP_RD); if (ret) { pr_err("Error %d reading response %u for message ID:%u\n", @@ -488,9 +502,28 @@ static int hsmp_cache_proto_ver(void) return ret; } +static int initialize_platdev(void) +{ + int i; + + for (i = 0; i < plat_dev.num_sockets; i++) { + if (!node_to_amd_nb(i)) + return -ENODEV; + plat_dev.sock[i].root = node_to_amd_nb(i)->root; + plat_dev.sock[i].sock_ind = i; + plat_dev.sock[i].mbinfo.base_addr = SMN_HSMP_BASE; + plat_dev.sock[i].mbinfo.msg_id_off = SMN_HSMP_MSG_ID; + plat_dev.sock[i].mbinfo.msg_resp_off = SMN_HSMP_MSG_RESP; + plat_dev.sock[i].mbinfo.msg_arg_off = SMN_HSMP_MSG_DATA; + sema_init(&plat_dev.sock[i].hsmp_sem, 1); + } + + return 0; +} + static int hsmp_pltdrv_probe(struct platform_device *pdev) { - int ret, i; + int ret; plat_dev.sock = devm_kzalloc(&pdev->dev, (plat_dev.num_sockets * sizeof(struct hsmp_socket)), @@ -499,22 +532,17 @@ static int hsmp_pltdrv_probe(struct platform_device *pdev) return -ENOMEM; plat_dev.dev = &pdev->dev; - for (i = 0; i < plat_dev.num_sockets; i++) { - sema_init(&plat_dev.sock[i].hsmp_sem, 1); - plat_dev.sock[i].sock_ind = i; - - if (!node_to_amd_nb(i)) - return -ENODEV; - plat_dev.sock[i].root = node_to_amd_nb(i)->root; + ret = initialize_platdev(); + if (ret) + return ret; - /* Test the hsmp interface on each socket */ - ret = hsmp_test(i, 0xDEADBEEF); - if (ret) { - pr_err("HSMP test message failed on Fam:%x model:%x\n", - boot_cpu_data.x86, boot_cpu_data.x86_model); - pr_err("Is HSMP disabled in BIOS ?\n"); - return ret; - } + /* Test the hsmp interface */ + ret = hsmp_test(0, 0xDEADBEEF); + if (ret) { + pr_err("HSMP test message failed on Fam:%x model:%x\n", + boot_cpu_data.x86, boot_cpu_data.x86_model); + pr_err("Is HSMP disabled in BIOS ?\n"); + return ret; } plat_dev.hsmp_device.name = HSMP_CDEV_NAME;