GNU Linux-libre 6.8.9-gnu
[releases.git] / drivers / accel / habanalabs / common / sysfs.c
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
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
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
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
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
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
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
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
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\n",
146                         le32_to_cpu(hdev->asic_prop.cpucp_info.cpld_version));
147 }
148
149 static ssize_t cpucp_kernel_ver_show(struct device *dev,
150                                 struct device_attribute *attr, char *buf)
151 {
152         struct hl_device *hdev = dev_get_drvdata(dev);
153
154         return sprintf(buf, "%s", hdev->asic_prop.cpucp_info.kernel_version);
155 }
156
157 static ssize_t cpucp_ver_show(struct device *dev, struct device_attribute *attr,
158                                 char *buf)
159 {
160         struct hl_device *hdev = dev_get_drvdata(dev);
161
162         return sprintf(buf, "%s\n", hdev->asic_prop.cpucp_info.cpucp_version);
163 }
164
165 static ssize_t fuse_ver_show(struct device *dev, struct device_attribute *attr,
166                                 char *buf)
167 {
168         struct hl_device *hdev = dev_get_drvdata(dev);
169
170         return sprintf(buf, "%s\n", hdev->asic_prop.cpucp_info.fuse_version);
171 }
172
173 static ssize_t thermal_ver_show(struct device *dev,
174                                 struct device_attribute *attr, char *buf)
175 {
176         struct hl_device *hdev = dev_get_drvdata(dev);
177
178         return sprintf(buf, "%s", hdev->asic_prop.cpucp_info.thermal_version);
179 }
180
181 static ssize_t fw_os_ver_show(struct device *dev,
182                                 struct device_attribute *attr, char *buf)
183 {
184         struct hl_device *hdev = dev_get_drvdata(dev);
185
186         return sprintf(buf, "%s", hdev->asic_prop.cpucp_info.fw_os_version);
187 }
188
189 static ssize_t preboot_btl_ver_show(struct device *dev,
190                                 struct device_attribute *attr, char *buf)
191 {
192         struct hl_device *hdev = dev_get_drvdata(dev);
193
194         return sprintf(buf, "%s\n", hdev->asic_prop.preboot_ver);
195 }
196
197 static ssize_t soft_reset_store(struct device *dev,
198                                 struct device_attribute *attr, const char *buf,
199                                 size_t count)
200 {
201         struct hl_device *hdev = dev_get_drvdata(dev);
202         long value;
203         int rc;
204
205         rc = kstrtoul(buf, 0, &value);
206
207         if (rc) {
208                 count = -EINVAL;
209                 goto out;
210         }
211
212         if (!hdev->asic_prop.allow_inference_soft_reset) {
213                 dev_err(hdev->dev, "Device does not support inference soft-reset\n");
214                 goto out;
215         }
216
217         dev_warn(hdev->dev, "Inference Soft-Reset requested through sysfs\n");
218
219         hl_device_reset(hdev, 0);
220
221 out:
222         return count;
223 }
224
225 static ssize_t hard_reset_store(struct device *dev,
226                                 struct device_attribute *attr,
227                                 const char *buf, size_t count)
228 {
229         struct hl_device *hdev = dev_get_drvdata(dev);
230         long value;
231         int rc;
232
233         rc = kstrtoul(buf, 0, &value);
234
235         if (rc) {
236                 count = -EINVAL;
237                 goto out;
238         }
239
240         dev_warn(hdev->dev, "Hard-Reset requested through sysfs\n");
241
242         hl_device_reset(hdev, HL_DRV_RESET_HARD);
243
244 out:
245         return count;
246 }
247
248 static ssize_t device_type_show(struct device *dev,
249                 struct device_attribute *attr, char *buf)
250 {
251         struct hl_device *hdev = dev_get_drvdata(dev);
252         char *str;
253
254         switch (hdev->asic_type) {
255         case ASIC_GOYA:
256                 str = "GOYA";
257                 break;
258         case ASIC_GAUDI:
259                 str = "GAUDI";
260                 break;
261         case ASIC_GAUDI_SEC:
262                 str = "GAUDI SEC";
263                 break;
264         case ASIC_GAUDI2:
265                 str = "GAUDI2";
266                 break;
267         case ASIC_GAUDI2B:
268                 str = "GAUDI2B";
269                 break;
270         case ASIC_GAUDI2C:
271                 str = "GAUDI2C";
272                 break;
273         default:
274                 dev_err(hdev->dev, "Unrecognized ASIC type %d\n",
275                                 hdev->asic_type);
276                 return -EINVAL;
277         }
278
279         return sprintf(buf, "%s\n", str);
280 }
281
282 static ssize_t pci_addr_show(struct device *dev, struct device_attribute *attr,
283                                 char *buf)
284 {
285         struct hl_device *hdev = dev_get_drvdata(dev);
286
287         return sprintf(buf, "%04x:%02x:%02x.%x\n",
288                         pci_domain_nr(hdev->pdev->bus),
289                         hdev->pdev->bus->number,
290                         PCI_SLOT(hdev->pdev->devfn),
291                         PCI_FUNC(hdev->pdev->devfn));
292 }
293
294 static ssize_t status_show(struct device *dev, struct device_attribute *attr,
295                                 char *buf)
296 {
297         struct hl_device *hdev = dev_get_drvdata(dev);
298         char str[HL_STR_MAX];
299
300         strscpy(str, hdev->status[hl_device_status(hdev)], HL_STR_MAX);
301
302         /* use uppercase for backward compatibility */
303         str[0] = 'A' + (str[0] - 'a');
304
305         return sprintf(buf, "%s\n", str);
306 }
307
308 static ssize_t soft_reset_cnt_show(struct device *dev,
309                 struct device_attribute *attr, char *buf)
310 {
311         struct hl_device *hdev = dev_get_drvdata(dev);
312
313         return sprintf(buf, "%d\n", hdev->reset_info.compute_reset_cnt);
314 }
315
316 static ssize_t hard_reset_cnt_show(struct device *dev,
317                 struct device_attribute *attr, char *buf)
318 {
319         struct hl_device *hdev = dev_get_drvdata(dev);
320
321         return sprintf(buf, "%d\n", hdev->reset_info.hard_reset_cnt);
322 }
323
324 static ssize_t max_power_show(struct device *dev, struct device_attribute *attr,
325                                 char *buf)
326 {
327         struct hl_device *hdev = dev_get_drvdata(dev);
328         long val;
329
330         if (!hl_device_operational(hdev, NULL))
331                 return -ENODEV;
332
333         val = hl_fw_get_max_power(hdev);
334         if (val < 0)
335                 return val;
336
337         return sprintf(buf, "%lu\n", val);
338 }
339
340 static ssize_t max_power_store(struct device *dev,
341                 struct device_attribute *attr, const char *buf, size_t count)
342 {
343         struct hl_device *hdev = dev_get_drvdata(dev);
344         unsigned long value;
345         int rc;
346
347         if (!hl_device_operational(hdev, NULL)) {
348                 count = -ENODEV;
349                 goto out;
350         }
351
352         rc = kstrtoul(buf, 0, &value);
353
354         if (rc) {
355                 count = -EINVAL;
356                 goto out;
357         }
358
359         hdev->max_power = value;
360         hl_fw_set_max_power(hdev);
361
362 out:
363         return count;
364 }
365
366 static ssize_t eeprom_read_handler(struct file *filp, struct kobject *kobj,
367                         struct bin_attribute *attr, char *buf, loff_t offset,
368                         size_t max_size)
369 {
370         struct device *dev = kobj_to_dev(kobj);
371         struct hl_device *hdev = dev_get_drvdata(dev);
372         char *data;
373         int rc;
374
375         if (!hl_device_operational(hdev, NULL))
376                 return -ENODEV;
377
378         if (!max_size)
379                 return -EINVAL;
380
381         data = kzalloc(max_size, GFP_KERNEL);
382         if (!data)
383                 return -ENOMEM;
384
385         rc = hdev->asic_funcs->get_eeprom_data(hdev, data, max_size);
386         if (rc)
387                 goto out;
388
389         memcpy(buf, data, max_size);
390
391 out:
392         kfree(data);
393
394         return max_size;
395 }
396
397 static ssize_t security_enabled_show(struct device *dev,
398                                 struct device_attribute *attr, char *buf)
399 {
400         struct hl_device *hdev = dev_get_drvdata(dev);
401
402         return sprintf(buf, "%d\n", hdev->asic_prop.fw_security_enabled);
403 }
404
405 static ssize_t module_id_show(struct device *dev,
406                                 struct device_attribute *attr, char *buf)
407 {
408         struct hl_device *hdev = dev_get_drvdata(dev);
409
410         return sprintf(buf, "%u\n", le32_to_cpu(hdev->asic_prop.cpucp_info.card_location));
411 }
412
413 static ssize_t parent_device_show(struct device *dev, struct device_attribute *attr, char *buf)
414 {
415         struct hl_device *hdev = dev_get_drvdata(dev);
416
417         return sprintf(buf, "%s\n", HL_DEV_NAME(hdev));
418 }
419
420 static DEVICE_ATTR_RO(armcp_kernel_ver);
421 static DEVICE_ATTR_RO(armcp_ver);
422 static DEVICE_ATTR_RO(cpld_ver);
423 static DEVICE_ATTR_RO(cpucp_kernel_ver);
424 static DEVICE_ATTR_RO(cpucp_ver);
425 static DEVICE_ATTR_RO(device_type);
426 static DEVICE_ATTR_RO(fuse_ver);
427 static DEVICE_ATTR_WO(hard_reset);
428 static DEVICE_ATTR_RO(hard_reset_cnt);
429 static DEVICE_ATTR_RW(max_power);
430 static DEVICE_ATTR_RO(pci_addr);
431 static DEVICE_ATTR_RO(preboot_btl_ver);
432 static DEVICE_ATTR_WO(soft_reset);
433 static DEVICE_ATTR_RO(soft_reset_cnt);
434 static DEVICE_ATTR_RO(status);
435 static DEVICE_ATTR_RO(thermal_ver);
436 static DEVICE_ATTR_RO(uboot_ver);
437 static DEVICE_ATTR_RO(fw_os_ver);
438 static DEVICE_ATTR_RO(security_enabled);
439 static DEVICE_ATTR_RO(module_id);
440 static DEVICE_ATTR_RO(parent_device);
441
442 static struct bin_attribute bin_attr_eeprom = {
443         .attr = {.name = "eeprom", .mode = (0444)},
444         .size = PAGE_SIZE,
445         .read = eeprom_read_handler
446 };
447
448 static struct attribute *hl_dev_attrs[] = {
449         &dev_attr_armcp_kernel_ver.attr,
450         &dev_attr_armcp_ver.attr,
451         &dev_attr_cpld_ver.attr,
452         &dev_attr_cpucp_kernel_ver.attr,
453         &dev_attr_cpucp_ver.attr,
454         &dev_attr_device_type.attr,
455         &dev_attr_fuse_ver.attr,
456         &dev_attr_hard_reset.attr,
457         &dev_attr_hard_reset_cnt.attr,
458         &dev_attr_max_power.attr,
459         &dev_attr_pci_addr.attr,
460         &dev_attr_preboot_btl_ver.attr,
461         &dev_attr_status.attr,
462         &dev_attr_thermal_ver.attr,
463         &dev_attr_uboot_ver.attr,
464         &dev_attr_fw_os_ver.attr,
465         &dev_attr_security_enabled.attr,
466         &dev_attr_module_id.attr,
467         &dev_attr_parent_device.attr,
468         NULL,
469 };
470
471 static struct bin_attribute *hl_dev_bin_attrs[] = {
472         &bin_attr_eeprom,
473         NULL
474 };
475
476 static struct attribute_group hl_dev_attr_group = {
477         .attrs = hl_dev_attrs,
478         .bin_attrs = hl_dev_bin_attrs,
479 };
480
481 static struct attribute_group hl_dev_clks_attr_group;
482 static struct attribute_group hl_dev_vrm_attr_group;
483
484 static const struct attribute_group *hl_dev_attr_groups[] = {
485         &hl_dev_attr_group,
486         &hl_dev_clks_attr_group,
487         &hl_dev_vrm_attr_group,
488         NULL,
489 };
490
491 static struct attribute *hl_dev_inference_attrs[] = {
492         &dev_attr_soft_reset.attr,
493         &dev_attr_soft_reset_cnt.attr,
494         NULL,
495 };
496
497 static struct attribute_group hl_dev_inference_attr_group = {
498         .attrs = hl_dev_inference_attrs,
499 };
500
501 static const struct attribute_group *hl_dev_inference_attr_groups[] = {
502         &hl_dev_inference_attr_group,
503         NULL,
504 };
505
506 void hl_sysfs_add_dev_clk_attr(struct hl_device *hdev, struct attribute_group *dev_clk_attr_grp)
507 {
508         dev_clk_attr_grp->attrs = hl_dev_clk_attrs;
509 }
510
511 void hl_sysfs_add_dev_vrm_attr(struct hl_device *hdev, struct attribute_group *dev_vrm_attr_grp)
512 {
513         dev_vrm_attr_grp->attrs = hl_dev_vrm_attrs;
514 }
515
516 int hl_sysfs_init(struct hl_device *hdev)
517 {
518         int rc;
519
520         hdev->max_power = hdev->asic_prop.max_power_default;
521
522         hdev->asic_funcs->add_device_attr(hdev, &hl_dev_clks_attr_group, &hl_dev_vrm_attr_group);
523
524         rc = device_add_groups(hdev->dev, hl_dev_attr_groups);
525         if (rc) {
526                 dev_err(hdev->dev,
527                         "Failed to add groups to device, error %d\n", rc);
528                 return rc;
529         }
530
531         if (!hdev->asic_prop.allow_inference_soft_reset)
532                 return 0;
533
534         rc = device_add_groups(hdev->dev, hl_dev_inference_attr_groups);
535         if (rc) {
536                 dev_err(hdev->dev,
537                         "Failed to add groups to device, error %d\n", rc);
538                 goto remove_groups;
539         }
540
541         return 0;
542
543 remove_groups:
544         device_remove_groups(hdev->dev, hl_dev_attr_groups);
545         return rc;
546 }
547
548 void hl_sysfs_fini(struct hl_device *hdev)
549 {
550         device_remove_groups(hdev->dev, hl_dev_attr_groups);
551
552         if (!hdev->asic_prop.allow_inference_soft_reset)
553                 return;
554
555         device_remove_groups(hdev->dev, hl_dev_inference_attr_groups);
556 }