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