Linux Audio

Check our new training course

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