xref: /linux/drivers/accel/habanalabs/common/sysfs.c (revision a1ff5a7d78a036d6c2178ee5acd6ba4946243800)
1 // SPDX-License-Identifier: GPL-2.0
2 
3 /*
4  * Copyright 2016-2022 HabanaLabs, Ltd.
5  * All Rights Reserved.
6  */
7 
8 #include "habanalabs.h"
9 
10 #include <linux/pci.h>
11 #include <linux/types.h>
12 
clk_max_freq_mhz_show(struct device * dev,struct device_attribute * attr,char * buf)13 static ssize_t clk_max_freq_mhz_show(struct device *dev, struct device_attribute *attr, char *buf)
14 {
15 	struct hl_device *hdev = dev_get_drvdata(dev);
16 	long value;
17 
18 	if (!hl_device_operational(hdev, NULL))
19 		return -ENODEV;
20 
21 	value = hl_fw_get_frequency(hdev, hdev->asic_prop.clk_pll_index, false);
22 	if (value < 0)
23 		return value;
24 
25 	hdev->asic_prop.max_freq_value = value;
26 
27 	return sprintf(buf, "%lu\n", (value / 1000 / 1000));
28 }
29 
clk_max_freq_mhz_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)30 static ssize_t clk_max_freq_mhz_store(struct device *dev, struct device_attribute *attr,
31 					const char *buf, size_t count)
32 {
33 	struct hl_device *hdev = dev_get_drvdata(dev);
34 	int rc;
35 	u64 value;
36 
37 	if (!hl_device_operational(hdev, NULL)) {
38 		count = -ENODEV;
39 		goto fail;
40 	}
41 
42 	rc = kstrtoull(buf, 0, &value);
43 	if (rc) {
44 		count = -EINVAL;
45 		goto fail;
46 	}
47 
48 	hdev->asic_prop.max_freq_value = value * 1000 * 1000;
49 
50 	hl_fw_set_frequency(hdev, hdev->asic_prop.clk_pll_index, hdev->asic_prop.max_freq_value);
51 
52 fail:
53 	return count;
54 }
55 
clk_cur_freq_mhz_show(struct device * dev,struct device_attribute * attr,char * buf)56 static ssize_t clk_cur_freq_mhz_show(struct device *dev, struct device_attribute *attr, char *buf)
57 {
58 	struct hl_device *hdev = dev_get_drvdata(dev);
59 	long value;
60 
61 	if (!hl_device_operational(hdev, NULL))
62 		return -ENODEV;
63 
64 	value = hl_fw_get_frequency(hdev, hdev->asic_prop.clk_pll_index, true);
65 	if (value < 0)
66 		return value;
67 
68 	return sprintf(buf, "%lu\n", (value / 1000 / 1000));
69 }
70 
71 static DEVICE_ATTR_RW(clk_max_freq_mhz);
72 static DEVICE_ATTR_RO(clk_cur_freq_mhz);
73 
74 static struct attribute *hl_dev_clk_attrs[] = {
75 	&dev_attr_clk_max_freq_mhz.attr,
76 	&dev_attr_clk_cur_freq_mhz.attr,
77 	NULL,
78 };
79 
vrm_ver_show(struct device * dev,struct device_attribute * attr,char * buf)80 static ssize_t vrm_ver_show(struct device *dev, struct device_attribute *attr, char *buf)
81 {
82 	struct hl_device *hdev = dev_get_drvdata(dev);
83 	struct cpucp_info *cpucp_info;
84 	u32 infineon_second_stage_version;
85 	u32 infineon_second_stage_first_instance;
86 	u32 infineon_second_stage_second_instance;
87 	u32 infineon_second_stage_third_instance;
88 	u32 mask = 0xff;
89 
90 	cpucp_info = &hdev->asic_prop.cpucp_info;
91 
92 	infineon_second_stage_version = le32_to_cpu(cpucp_info->infineon_second_stage_version);
93 	infineon_second_stage_first_instance = infineon_second_stage_version & mask;
94 	infineon_second_stage_second_instance =
95 					(infineon_second_stage_version >> 8) & mask;
96 	infineon_second_stage_third_instance =
97 					(infineon_second_stage_version >> 16) & mask;
98 
99 	if (cpucp_info->infineon_second_stage_version)
100 		return sprintf(buf, "%#04x %#04x:%#04x:%#04x\n",
101 				le32_to_cpu(cpucp_info->infineon_version),
102 				infineon_second_stage_first_instance,
103 				infineon_second_stage_second_instance,
104 				infineon_second_stage_third_instance);
105 	else
106 		return sprintf(buf, "%#04x\n", le32_to_cpu(cpucp_info->infineon_version));
107 }
108 
109 static DEVICE_ATTR_RO(vrm_ver);
110 
111 static struct attribute *hl_dev_vrm_attrs[] = {
112 	&dev_attr_vrm_ver.attr,
113 	NULL,
114 };
115 
uboot_ver_show(struct device * dev,struct device_attribute * attr,char * buf)116 static ssize_t uboot_ver_show(struct device *dev, struct device_attribute *attr,
117 				char *buf)
118 {
119 	struct hl_device *hdev = dev_get_drvdata(dev);
120 
121 	return sprintf(buf, "%s\n", hdev->asic_prop.uboot_ver);
122 }
123 
armcp_kernel_ver_show(struct device * dev,struct device_attribute * attr,char * buf)124 static ssize_t armcp_kernel_ver_show(struct device *dev,
125 				struct device_attribute *attr, char *buf)
126 {
127 	struct hl_device *hdev = dev_get_drvdata(dev);
128 
129 	return sprintf(buf, "%s", hdev->asic_prop.cpucp_info.kernel_version);
130 }
131 
armcp_ver_show(struct device * dev,struct device_attribute * attr,char * buf)132 static ssize_t armcp_ver_show(struct device *dev, struct device_attribute *attr,
133 				char *buf)
134 {
135 	struct hl_device *hdev = dev_get_drvdata(dev);
136 
137 	return sprintf(buf, "%s\n", hdev->asic_prop.cpucp_info.cpucp_version);
138 }
139 
cpld_ver_show(struct device * dev,struct device_attribute * attr,char * buf)140 static ssize_t cpld_ver_show(struct device *dev, struct device_attribute *attr,
141 				char *buf)
142 {
143 	struct hl_device *hdev = dev_get_drvdata(dev);
144 
145 	return sprintf(buf, "0x%08x%08x\n",
146 		le32_to_cpu(hdev->asic_prop.cpucp_info.cpld_timestamp),
147 		le32_to_cpu(hdev->asic_prop.cpucp_info.cpld_version));
148 }
149 
cpucp_kernel_ver_show(struct device * dev,struct device_attribute * attr,char * buf)150 static ssize_t cpucp_kernel_ver_show(struct device *dev,
151 				struct device_attribute *attr, char *buf)
152 {
153 	struct hl_device *hdev = dev_get_drvdata(dev);
154 
155 	return sprintf(buf, "%s", hdev->asic_prop.cpucp_info.kernel_version);
156 }
157 
cpucp_ver_show(struct device * dev,struct device_attribute * attr,char * buf)158 static ssize_t cpucp_ver_show(struct device *dev, struct device_attribute *attr,
159 				char *buf)
160 {
161 	struct hl_device *hdev = dev_get_drvdata(dev);
162 
163 	return sprintf(buf, "%s\n", hdev->asic_prop.cpucp_info.cpucp_version);
164 }
165 
fuse_ver_show(struct device * dev,struct device_attribute * attr,char * buf)166 static ssize_t fuse_ver_show(struct device *dev, struct device_attribute *attr,
167 				char *buf)
168 {
169 	struct hl_device *hdev = dev_get_drvdata(dev);
170 
171 	return sprintf(buf, "%s\n", hdev->asic_prop.cpucp_info.fuse_version);
172 }
173 
thermal_ver_show(struct device * dev,struct device_attribute * attr,char * buf)174 static ssize_t thermal_ver_show(struct device *dev,
175 				struct device_attribute *attr, char *buf)
176 {
177 	struct hl_device *hdev = dev_get_drvdata(dev);
178 
179 	return sprintf(buf, "%s", hdev->asic_prop.cpucp_info.thermal_version);
180 }
181 
fw_os_ver_show(struct device * dev,struct device_attribute * attr,char * buf)182 static ssize_t fw_os_ver_show(struct device *dev,
183 				struct device_attribute *attr, char *buf)
184 {
185 	struct hl_device *hdev = dev_get_drvdata(dev);
186 
187 	return sprintf(buf, "%s", hdev->asic_prop.cpucp_info.fw_os_version);
188 }
189 
preboot_btl_ver_show(struct device * dev,struct device_attribute * attr,char * buf)190 static ssize_t preboot_btl_ver_show(struct device *dev,
191 				struct device_attribute *attr, char *buf)
192 {
193 	struct hl_device *hdev = dev_get_drvdata(dev);
194 
195 	return sprintf(buf, "%s\n", hdev->asic_prop.preboot_ver);
196 }
197 
soft_reset_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)198 static ssize_t soft_reset_store(struct device *dev,
199 				struct device_attribute *attr, const char *buf,
200 				size_t count)
201 {
202 	struct hl_device *hdev = dev_get_drvdata(dev);
203 	long value;
204 	int rc;
205 
206 	rc = kstrtoul(buf, 0, &value);
207 
208 	if (rc) {
209 		count = -EINVAL;
210 		goto out;
211 	}
212 
213 	if (!hdev->asic_prop.allow_inference_soft_reset) {
214 		dev_err(hdev->dev, "Device does not support inference soft-reset\n");
215 		goto out;
216 	}
217 
218 	dev_warn(hdev->dev, "Inference Soft-Reset requested through sysfs\n");
219 
220 	hl_device_reset(hdev, 0);
221 
222 out:
223 	return count;
224 }
225 
hard_reset_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)226 static ssize_t hard_reset_store(struct device *dev,
227 				struct device_attribute *attr,
228 				const char *buf, size_t count)
229 {
230 	struct hl_device *hdev = dev_get_drvdata(dev);
231 	long value;
232 	int rc;
233 
234 	rc = kstrtoul(buf, 0, &value);
235 
236 	if (rc) {
237 		count = -EINVAL;
238 		goto out;
239 	}
240 
241 	dev_warn(hdev->dev, "Hard-Reset requested through sysfs\n");
242 
243 	hl_device_reset(hdev, HL_DRV_RESET_HARD);
244 
245 out:
246 	return count;
247 }
248 
device_type_show(struct device * dev,struct device_attribute * attr,char * buf)249 static ssize_t device_type_show(struct device *dev,
250 		struct device_attribute *attr, char *buf)
251 {
252 	struct hl_device *hdev = dev_get_drvdata(dev);
253 	char *str;
254 
255 	switch (hdev->asic_type) {
256 	case ASIC_GOYA:
257 		str = "GOYA";
258 		break;
259 	case ASIC_GAUDI:
260 		str = "GAUDI";
261 		break;
262 	case ASIC_GAUDI_SEC:
263 		str = "GAUDI SEC";
264 		break;
265 	case ASIC_GAUDI2:
266 		str = "GAUDI2";
267 		break;
268 	case ASIC_GAUDI2B:
269 		str = "GAUDI2B";
270 		break;
271 	case ASIC_GAUDI2C:
272 		str = "GAUDI2C";
273 		break;
274 	case ASIC_GAUDI2D:
275 		str = "GAUDI2D";
276 		break;
277 	default:
278 		dev_err(hdev->dev, "Unrecognized ASIC type %d\n",
279 				hdev->asic_type);
280 		return -EINVAL;
281 	}
282 
283 	return sprintf(buf, "%s\n", str);
284 }
285 
pci_addr_show(struct device * dev,struct device_attribute * attr,char * buf)286 static ssize_t pci_addr_show(struct device *dev, struct device_attribute *attr,
287 				char *buf)
288 {
289 	struct hl_device *hdev = dev_get_drvdata(dev);
290 
291 	return sprintf(buf, "%04x:%02x:%02x.%x\n",
292 			pci_domain_nr(hdev->pdev->bus),
293 			hdev->pdev->bus->number,
294 			PCI_SLOT(hdev->pdev->devfn),
295 			PCI_FUNC(hdev->pdev->devfn));
296 }
297 
status_show(struct device * dev,struct device_attribute * attr,char * buf)298 static ssize_t status_show(struct device *dev, struct device_attribute *attr,
299 				char *buf)
300 {
301 	struct hl_device *hdev = dev_get_drvdata(dev);
302 	char str[HL_STR_MAX];
303 
304 	strscpy(str, hdev->status[hl_device_status(hdev)], HL_STR_MAX);
305 
306 	/* use uppercase for backward compatibility */
307 	str[0] = 'A' + (str[0] - 'a');
308 
309 	return sprintf(buf, "%s\n", str);
310 }
311 
soft_reset_cnt_show(struct device * dev,struct device_attribute * attr,char * buf)312 static ssize_t soft_reset_cnt_show(struct device *dev,
313 		struct device_attribute *attr, char *buf)
314 {
315 	struct hl_device *hdev = dev_get_drvdata(dev);
316 
317 	return sprintf(buf, "%d\n", hdev->reset_info.compute_reset_cnt);
318 }
319 
hard_reset_cnt_show(struct device * dev,struct device_attribute * attr,char * buf)320 static ssize_t hard_reset_cnt_show(struct device *dev,
321 		struct device_attribute *attr, char *buf)
322 {
323 	struct hl_device *hdev = dev_get_drvdata(dev);
324 
325 	return sprintf(buf, "%d\n", hdev->reset_info.hard_reset_cnt);
326 }
327 
max_power_show(struct device * dev,struct device_attribute * attr,char * buf)328 static ssize_t max_power_show(struct device *dev, struct device_attribute *attr,
329 				char *buf)
330 {
331 	struct hl_device *hdev = dev_get_drvdata(dev);
332 	long val;
333 
334 	if (!hl_device_operational(hdev, NULL))
335 		return -ENODEV;
336 
337 	val = hl_fw_get_max_power(hdev);
338 	if (val < 0)
339 		return val;
340 
341 	return sprintf(buf, "%lu\n", val);
342 }
343 
max_power_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)344 static ssize_t max_power_store(struct device *dev,
345 		struct device_attribute *attr, const char *buf, size_t count)
346 {
347 	struct hl_device *hdev = dev_get_drvdata(dev);
348 	unsigned long value;
349 	int rc;
350 
351 	if (!hl_device_operational(hdev, NULL)) {
352 		count = -ENODEV;
353 		goto out;
354 	}
355 
356 	rc = kstrtoul(buf, 0, &value);
357 
358 	if (rc) {
359 		count = -EINVAL;
360 		goto out;
361 	}
362 
363 	hdev->max_power = value;
364 	hl_fw_set_max_power(hdev);
365 
366 out:
367 	return count;
368 }
369 
eeprom_read_handler(struct file * filp,struct kobject * kobj,struct bin_attribute * attr,char * buf,loff_t offset,size_t max_size)370 static ssize_t eeprom_read_handler(struct file *filp, struct kobject *kobj,
371 			struct bin_attribute *attr, char *buf, loff_t offset,
372 			size_t max_size)
373 {
374 	struct device *dev = kobj_to_dev(kobj);
375 	struct hl_device *hdev = dev_get_drvdata(dev);
376 	char *data;
377 	int rc;
378 
379 	if (!hl_device_operational(hdev, NULL))
380 		return -ENODEV;
381 
382 	if (!max_size)
383 		return -EINVAL;
384 
385 	data = kzalloc(max_size, GFP_KERNEL);
386 	if (!data)
387 		return -ENOMEM;
388 
389 	rc = hdev->asic_funcs->get_eeprom_data(hdev, data, max_size);
390 	if (rc)
391 		goto out;
392 
393 	memcpy(buf, data, max_size);
394 
395 out:
396 	kfree(data);
397 
398 	return max_size;
399 }
400 
security_enabled_show(struct device * dev,struct device_attribute * attr,char * buf)401 static ssize_t security_enabled_show(struct device *dev,
402 				struct device_attribute *attr, char *buf)
403 {
404 	struct hl_device *hdev = dev_get_drvdata(dev);
405 
406 	return sprintf(buf, "%d\n", hdev->asic_prop.fw_security_enabled);
407 }
408 
module_id_show(struct device * dev,struct device_attribute * attr,char * buf)409 static ssize_t module_id_show(struct device *dev,
410 				struct device_attribute *attr, char *buf)
411 {
412 	struct hl_device *hdev = dev_get_drvdata(dev);
413 
414 	return sprintf(buf, "%u\n", le32_to_cpu(hdev->asic_prop.cpucp_info.card_location));
415 }
416 
parent_device_show(struct device * dev,struct device_attribute * attr,char * buf)417 static ssize_t parent_device_show(struct device *dev, struct device_attribute *attr, char *buf)
418 {
419 	struct hl_device *hdev = dev_get_drvdata(dev);
420 
421 	return sprintf(buf, "%s\n", HL_DEV_NAME(hdev));
422 }
423 
424 static DEVICE_ATTR_RO(armcp_kernel_ver);
425 static DEVICE_ATTR_RO(armcp_ver);
426 static DEVICE_ATTR_RO(cpld_ver);
427 static DEVICE_ATTR_RO(cpucp_kernel_ver);
428 static DEVICE_ATTR_RO(cpucp_ver);
429 static DEVICE_ATTR_RO(device_type);
430 static DEVICE_ATTR_RO(fuse_ver);
431 static DEVICE_ATTR_WO(hard_reset);
432 static DEVICE_ATTR_RO(hard_reset_cnt);
433 static DEVICE_ATTR_RW(max_power);
434 static DEVICE_ATTR_RO(pci_addr);
435 static DEVICE_ATTR_RO(preboot_btl_ver);
436 static DEVICE_ATTR_WO(soft_reset);
437 static DEVICE_ATTR_RO(soft_reset_cnt);
438 static DEVICE_ATTR_RO(status);
439 static DEVICE_ATTR_RO(thermal_ver);
440 static DEVICE_ATTR_RO(uboot_ver);
441 static DEVICE_ATTR_RO(fw_os_ver);
442 static DEVICE_ATTR_RO(security_enabled);
443 static DEVICE_ATTR_RO(module_id);
444 static DEVICE_ATTR_RO(parent_device);
445 
446 static struct bin_attribute bin_attr_eeprom = {
447 	.attr = {.name = "eeprom", .mode = (0444)},
448 	.size = PAGE_SIZE,
449 	.read = eeprom_read_handler
450 };
451 
452 static struct attribute *hl_dev_attrs[] = {
453 	&dev_attr_armcp_kernel_ver.attr,
454 	&dev_attr_armcp_ver.attr,
455 	&dev_attr_cpld_ver.attr,
456 	&dev_attr_cpucp_kernel_ver.attr,
457 	&dev_attr_cpucp_ver.attr,
458 	&dev_attr_device_type.attr,
459 	&dev_attr_fuse_ver.attr,
460 	&dev_attr_hard_reset.attr,
461 	&dev_attr_hard_reset_cnt.attr,
462 	&dev_attr_max_power.attr,
463 	&dev_attr_pci_addr.attr,
464 	&dev_attr_preboot_btl_ver.attr,
465 	&dev_attr_status.attr,
466 	&dev_attr_thermal_ver.attr,
467 	&dev_attr_uboot_ver.attr,
468 	&dev_attr_fw_os_ver.attr,
469 	&dev_attr_security_enabled.attr,
470 	&dev_attr_module_id.attr,
471 	&dev_attr_parent_device.attr,
472 	NULL,
473 };
474 
475 static struct bin_attribute *hl_dev_bin_attrs[] = {
476 	&bin_attr_eeprom,
477 	NULL
478 };
479 
480 static struct attribute_group hl_dev_attr_group = {
481 	.attrs = hl_dev_attrs,
482 	.bin_attrs = hl_dev_bin_attrs,
483 };
484 
485 static struct attribute_group hl_dev_clks_attr_group;
486 static struct attribute_group hl_dev_vrm_attr_group;
487 
488 static const struct attribute_group *hl_dev_attr_groups[] = {
489 	&hl_dev_attr_group,
490 	&hl_dev_clks_attr_group,
491 	&hl_dev_vrm_attr_group,
492 	NULL,
493 };
494 
495 static struct attribute *hl_dev_inference_attrs[] = {
496 	&dev_attr_soft_reset.attr,
497 	&dev_attr_soft_reset_cnt.attr,
498 	NULL,
499 };
500 
501 static struct attribute_group hl_dev_inference_attr_group = {
502 	.attrs = hl_dev_inference_attrs,
503 };
504 
505 static const struct attribute_group *hl_dev_inference_attr_groups[] = {
506 	&hl_dev_inference_attr_group,
507 	NULL,
508 };
509 
hl_sysfs_add_dev_clk_attr(struct hl_device * hdev,struct attribute_group * dev_clk_attr_grp)510 void hl_sysfs_add_dev_clk_attr(struct hl_device *hdev, struct attribute_group *dev_clk_attr_grp)
511 {
512 	dev_clk_attr_grp->attrs = hl_dev_clk_attrs;
513 }
514 
hl_sysfs_add_dev_vrm_attr(struct hl_device * hdev,struct attribute_group * dev_vrm_attr_grp)515 void hl_sysfs_add_dev_vrm_attr(struct hl_device *hdev, struct attribute_group *dev_vrm_attr_grp)
516 {
517 	dev_vrm_attr_grp->attrs = hl_dev_vrm_attrs;
518 }
519 
hl_sysfs_init(struct hl_device * hdev)520 int hl_sysfs_init(struct hl_device *hdev)
521 {
522 	int rc;
523 
524 	hdev->max_power = hdev->asic_prop.max_power_default;
525 
526 	hdev->asic_funcs->add_device_attr(hdev, &hl_dev_clks_attr_group, &hl_dev_vrm_attr_group);
527 
528 	rc = device_add_groups(hdev->dev, hl_dev_attr_groups);
529 	if (rc) {
530 		dev_err(hdev->dev,
531 			"Failed to add groups to device, error %d\n", rc);
532 		return rc;
533 	}
534 
535 	if (!hdev->asic_prop.allow_inference_soft_reset)
536 		return 0;
537 
538 	rc = device_add_groups(hdev->dev, hl_dev_inference_attr_groups);
539 	if (rc) {
540 		dev_err(hdev->dev,
541 			"Failed to add groups to device, error %d\n", rc);
542 		goto remove_groups;
543 	}
544 
545 	return 0;
546 
547 remove_groups:
548 	device_remove_groups(hdev->dev, hl_dev_attr_groups);
549 	return rc;
550 }
551 
hl_sysfs_fini(struct hl_device * hdev)552 void hl_sysfs_fini(struct hl_device *hdev)
553 {
554 	device_remove_groups(hdev->dev, hl_dev_attr_groups);
555 
556 	if (!hdev->asic_prop.allow_inference_soft_reset)
557 		return;
558 
559 	device_remove_groups(hdev->dev, hl_dev_inference_attr_groups);
560 }
561