Merge tag 'drm-intel-next-2021-07-08' of git://anongit.freedesktop.org/drm/drm-intel...
[linux-2.6-microblaze.git] / drivers / misc / habanalabs / common / hwmon.c
1 // SPDX-License-Identifier: GPL-2.0
2
3 /*
4  * Copyright 2016-2019 HabanaLabs, Ltd.
5  * All Rights Reserved.
6  */
7
8 #include "habanalabs.h"
9
10 #include <linux/pci.h>
11 #include <linux/hwmon.h>
12
13 #define HWMON_NR_SENSOR_TYPES           (hwmon_pwm + 1)
14
15 int hl_build_hwmon_channel_info(struct hl_device *hdev,
16                                 struct cpucp_sensor *sensors_arr)
17 {
18         u32 counts[HWMON_NR_SENSOR_TYPES] = {0};
19         u32 *sensors_by_type[HWMON_NR_SENSOR_TYPES] = {NULL};
20         u32 sensors_by_type_next_index[HWMON_NR_SENSOR_TYPES] = {0};
21         struct hwmon_channel_info **channels_info;
22         u32 num_sensors_for_type, num_active_sensor_types = 0,
23                         arr_size = 0, *curr_arr;
24         enum hwmon_sensor_types type;
25         int rc, i, j;
26
27         for (i = 0 ; i < CPUCP_MAX_SENSORS ; i++) {
28                 type = le32_to_cpu(sensors_arr[i].type);
29
30                 if ((type == 0) && (sensors_arr[i].flags == 0))
31                         break;
32
33                 if (type >= HWMON_NR_SENSOR_TYPES) {
34                         dev_err(hdev->dev,
35                                 "Got wrong sensor type %d from device\n", type);
36                         return -EINVAL;
37                 }
38
39                 counts[type]++;
40                 arr_size++;
41         }
42
43         for (i = 0 ; i < HWMON_NR_SENSOR_TYPES ; i++) {
44                 if (counts[i] == 0)
45                         continue;
46
47                 num_sensors_for_type = counts[i] + 1;
48                 curr_arr = kcalloc(num_sensors_for_type, sizeof(*curr_arr),
49                                 GFP_KERNEL);
50                 if (!curr_arr) {
51                         rc = -ENOMEM;
52                         goto sensors_type_err;
53                 }
54
55                 num_active_sensor_types++;
56                 sensors_by_type[i] = curr_arr;
57         }
58
59         for (i = 0 ; i < arr_size ; i++) {
60                 type = le32_to_cpu(sensors_arr[i].type);
61                 curr_arr = sensors_by_type[type];
62                 curr_arr[sensors_by_type_next_index[type]++] =
63                                 le32_to_cpu(sensors_arr[i].flags);
64         }
65
66         channels_info = kcalloc(num_active_sensor_types + 1,
67                         sizeof(*channels_info), GFP_KERNEL);
68         if (!channels_info) {
69                 rc = -ENOMEM;
70                 goto channels_info_array_err;
71         }
72
73         for (i = 0 ; i < num_active_sensor_types ; i++) {
74                 channels_info[i] = kzalloc(sizeof(*channels_info[i]),
75                                 GFP_KERNEL);
76                 if (!channels_info[i]) {
77                         rc = -ENOMEM;
78                         goto channel_info_err;
79                 }
80         }
81
82         for (i = 0, j = 0 ; i < HWMON_NR_SENSOR_TYPES ; i++) {
83                 if (!sensors_by_type[i])
84                         continue;
85
86                 channels_info[j]->type = i;
87                 channels_info[j]->config = sensors_by_type[i];
88                 j++;
89         }
90
91         hdev->hl_chip_info->info =
92                         (const struct hwmon_channel_info **)channels_info;
93
94         return 0;
95
96 channel_info_err:
97         for (i = 0 ; i < num_active_sensor_types ; i++)
98                 if (channels_info[i]) {
99                         kfree(channels_info[i]->config);
100                         kfree(channels_info[i]);
101                 }
102         kfree(channels_info);
103 channels_info_array_err:
104 sensors_type_err:
105         for (i = 0 ; i < HWMON_NR_SENSOR_TYPES ; i++)
106                 kfree(sensors_by_type[i]);
107
108         return rc;
109 }
110
111 static int hl_read(struct device *dev, enum hwmon_sensor_types type,
112                         u32 attr, int channel, long *val)
113 {
114         struct hl_device *hdev = dev_get_drvdata(dev);
115         int rc;
116
117         if (!hl_device_operational(hdev, NULL))
118                 return -ENODEV;
119
120         switch (type) {
121         case hwmon_temp:
122                 switch (attr) {
123                 case hwmon_temp_input:
124                 case hwmon_temp_max:
125                 case hwmon_temp_crit:
126                 case hwmon_temp_max_hyst:
127                 case hwmon_temp_crit_hyst:
128                 case hwmon_temp_offset:
129                 case hwmon_temp_highest:
130                         break;
131                 default:
132                         return -EINVAL;
133                 }
134
135                 rc = hl_get_temperature(hdev, channel, attr, val);
136                 break;
137         case hwmon_in:
138                 switch (attr) {
139                 case hwmon_in_input:
140                 case hwmon_in_min:
141                 case hwmon_in_max:
142                 case hwmon_in_highest:
143                         break;
144                 default:
145                         return -EINVAL;
146                 }
147
148                 rc = hl_get_voltage(hdev, channel, attr, val);
149                 break;
150         case hwmon_curr:
151                 switch (attr) {
152                 case hwmon_curr_input:
153                 case hwmon_curr_min:
154                 case hwmon_curr_max:
155                 case hwmon_curr_highest:
156                         break;
157                 default:
158                         return -EINVAL;
159                 }
160
161                 rc = hl_get_current(hdev, channel, attr, val);
162                 break;
163         case hwmon_fan:
164                 switch (attr) {
165                 case hwmon_fan_input:
166                 case hwmon_fan_min:
167                 case hwmon_fan_max:
168                         break;
169                 default:
170                         return -EINVAL;
171                 }
172                 rc = hl_get_fan_speed(hdev, channel, attr, val);
173                 break;
174         case hwmon_pwm:
175                 switch (attr) {
176                 case hwmon_pwm_input:
177                 case hwmon_pwm_enable:
178                         break;
179                 default:
180                         return -EINVAL;
181                 }
182                 rc = hl_get_pwm_info(hdev, channel, attr, val);
183                 break;
184         default:
185                 return -EINVAL;
186         }
187         return rc;
188 }
189
190 static int hl_write(struct device *dev, enum hwmon_sensor_types type,
191                         u32 attr, int channel, long val)
192 {
193         struct hl_device *hdev = dev_get_drvdata(dev);
194
195         if (!hl_device_operational(hdev, NULL))
196                 return -ENODEV;
197
198         switch (type) {
199         case hwmon_temp:
200                 switch (attr) {
201                 case hwmon_temp_offset:
202                 case hwmon_temp_reset_history:
203                         break;
204                 default:
205                         return -EINVAL;
206                 }
207                 hl_set_temperature(hdev, channel, attr, val);
208                 break;
209         case hwmon_pwm:
210                 switch (attr) {
211                 case hwmon_pwm_input:
212                 case hwmon_pwm_enable:
213                         break;
214                 default:
215                         return -EINVAL;
216                 }
217                 hl_set_pwm_info(hdev, channel, attr, val);
218                 break;
219         case hwmon_in:
220                 switch (attr) {
221                 case hwmon_in_reset_history:
222                         break;
223                 default:
224                         return -EINVAL;
225                 }
226                 hl_set_voltage(hdev, channel, attr, val);
227                 break;
228         case hwmon_curr:
229                 switch (attr) {
230                 case hwmon_curr_reset_history:
231                         break;
232                 default:
233                         return -EINVAL;
234                 }
235                 hl_set_current(hdev, channel, attr, val);
236                 break;
237         default:
238                 return -EINVAL;
239         }
240         return 0;
241 }
242
243 static umode_t hl_is_visible(const void *data, enum hwmon_sensor_types type,
244                                 u32 attr, int channel)
245 {
246         switch (type) {
247         case hwmon_temp:
248                 switch (attr) {
249                 case hwmon_temp_input:
250                 case hwmon_temp_max:
251                 case hwmon_temp_max_hyst:
252                 case hwmon_temp_crit:
253                 case hwmon_temp_crit_hyst:
254                 case hwmon_temp_highest:
255                         return 0444;
256                 case hwmon_temp_offset:
257                         return 0644;
258                 case hwmon_temp_reset_history:
259                         return 0200;
260                 }
261                 break;
262         case hwmon_in:
263                 switch (attr) {
264                 case hwmon_in_input:
265                 case hwmon_in_min:
266                 case hwmon_in_max:
267                 case hwmon_in_highest:
268                         return 0444;
269                 case hwmon_in_reset_history:
270                         return 0200;
271                 }
272                 break;
273         case hwmon_curr:
274                 switch (attr) {
275                 case hwmon_curr_input:
276                 case hwmon_curr_min:
277                 case hwmon_curr_max:
278                 case hwmon_curr_highest:
279                         return 0444;
280                 case hwmon_curr_reset_history:
281                         return 0200;
282                 }
283                 break;
284         case hwmon_fan:
285                 switch (attr) {
286                 case hwmon_fan_input:
287                 case hwmon_fan_min:
288                 case hwmon_fan_max:
289                         return 0444;
290                 }
291                 break;
292         case hwmon_pwm:
293                 switch (attr) {
294                 case hwmon_pwm_input:
295                 case hwmon_pwm_enable:
296                         return 0644;
297                 }
298                 break;
299         default:
300                 break;
301         }
302         return 0;
303 }
304
305 static const struct hwmon_ops hl_hwmon_ops = {
306         .is_visible = hl_is_visible,
307         .read = hl_read,
308         .write = hl_write
309 };
310
311 int hl_get_temperature(struct hl_device *hdev,
312                         int sensor_index, u32 attr, long *value)
313 {
314         struct cpucp_packet pkt;
315         u64 result;
316         int rc;
317
318         memset(&pkt, 0, sizeof(pkt));
319
320         pkt.ctl = cpu_to_le32(CPUCP_PACKET_TEMPERATURE_GET <<
321                                 CPUCP_PKT_CTL_OPCODE_SHIFT);
322         pkt.sensor_index = __cpu_to_le16(sensor_index);
323         pkt.type = __cpu_to_le16(attr);
324
325         rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
326                                                 0, &result);
327
328         *value = (long) result;
329
330         if (rc) {
331                 dev_err(hdev->dev,
332                         "Failed to get temperature from sensor %d, error %d\n",
333                         sensor_index, rc);
334                 *value = 0;
335         }
336
337         return rc;
338 }
339
340 int hl_set_temperature(struct hl_device *hdev,
341                         int sensor_index, u32 attr, long value)
342 {
343         struct cpucp_packet pkt;
344         int rc;
345
346         memset(&pkt, 0, sizeof(pkt));
347
348         pkt.ctl = cpu_to_le32(CPUCP_PACKET_TEMPERATURE_SET <<
349                                 CPUCP_PKT_CTL_OPCODE_SHIFT);
350         pkt.sensor_index = __cpu_to_le16(sensor_index);
351         pkt.type = __cpu_to_le16(attr);
352         pkt.value = __cpu_to_le64(value);
353
354         rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
355                                                 0, NULL);
356
357         if (rc)
358                 dev_err(hdev->dev,
359                         "Failed to set temperature of sensor %d, error %d\n",
360                         sensor_index, rc);
361
362         return rc;
363 }
364
365 int hl_get_voltage(struct hl_device *hdev,
366                         int sensor_index, u32 attr, long *value)
367 {
368         struct cpucp_packet pkt;
369         u64 result;
370         int rc;
371
372         memset(&pkt, 0, sizeof(pkt));
373
374         pkt.ctl = cpu_to_le32(CPUCP_PACKET_VOLTAGE_GET <<
375                                 CPUCP_PKT_CTL_OPCODE_SHIFT);
376         pkt.sensor_index = __cpu_to_le16(sensor_index);
377         pkt.type = __cpu_to_le16(attr);
378
379         rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
380                                                 0, &result);
381
382         *value = (long) result;
383
384         if (rc) {
385                 dev_err(hdev->dev,
386                         "Failed to get voltage from sensor %d, error %d\n",
387                         sensor_index, rc);
388                 *value = 0;
389         }
390
391         return rc;
392 }
393
394 int hl_get_current(struct hl_device *hdev,
395                         int sensor_index, u32 attr, long *value)
396 {
397         struct cpucp_packet pkt;
398         u64 result;
399         int rc;
400
401         memset(&pkt, 0, sizeof(pkt));
402
403         pkt.ctl = cpu_to_le32(CPUCP_PACKET_CURRENT_GET <<
404                                 CPUCP_PKT_CTL_OPCODE_SHIFT);
405         pkt.sensor_index = __cpu_to_le16(sensor_index);
406         pkt.type = __cpu_to_le16(attr);
407
408         rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
409                                                 0, &result);
410
411         *value = (long) result;
412
413         if (rc) {
414                 dev_err(hdev->dev,
415                         "Failed to get current from sensor %d, error %d\n",
416                         sensor_index, rc);
417                 *value = 0;
418         }
419
420         return rc;
421 }
422
423 int hl_get_fan_speed(struct hl_device *hdev,
424                         int sensor_index, u32 attr, long *value)
425 {
426         struct cpucp_packet pkt;
427         u64 result;
428         int rc;
429
430         memset(&pkt, 0, sizeof(pkt));
431
432         pkt.ctl = cpu_to_le32(CPUCP_PACKET_FAN_SPEED_GET <<
433                                 CPUCP_PKT_CTL_OPCODE_SHIFT);
434         pkt.sensor_index = __cpu_to_le16(sensor_index);
435         pkt.type = __cpu_to_le16(attr);
436
437         rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
438                                                 0, &result);
439
440         *value = (long) result;
441
442         if (rc) {
443                 dev_err(hdev->dev,
444                         "Failed to get fan speed from sensor %d, error %d\n",
445                         sensor_index, rc);
446                 *value = 0;
447         }
448
449         return rc;
450 }
451
452 int hl_get_pwm_info(struct hl_device *hdev,
453                         int sensor_index, u32 attr, long *value)
454 {
455         struct cpucp_packet pkt;
456         u64 result;
457         int rc;
458
459         memset(&pkt, 0, sizeof(pkt));
460
461         pkt.ctl = cpu_to_le32(CPUCP_PACKET_PWM_GET <<
462                                 CPUCP_PKT_CTL_OPCODE_SHIFT);
463         pkt.sensor_index = __cpu_to_le16(sensor_index);
464         pkt.type = __cpu_to_le16(attr);
465
466         rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
467                                                 0, &result);
468
469         *value = (long) result;
470
471         if (rc) {
472                 dev_err(hdev->dev,
473                         "Failed to get pwm info from sensor %d, error %d\n",
474                         sensor_index, rc);
475                 *value = 0;
476         }
477
478         return rc;
479 }
480
481 void hl_set_pwm_info(struct hl_device *hdev, int sensor_index, u32 attr,
482                         long value)
483 {
484         struct cpucp_packet pkt;
485         int rc;
486
487         memset(&pkt, 0, sizeof(pkt));
488
489         pkt.ctl = cpu_to_le32(CPUCP_PACKET_PWM_SET <<
490                                 CPUCP_PKT_CTL_OPCODE_SHIFT);
491         pkt.sensor_index = __cpu_to_le16(sensor_index);
492         pkt.type = __cpu_to_le16(attr);
493         pkt.value = cpu_to_le64(value);
494
495         rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
496                                                 0, NULL);
497
498         if (rc)
499                 dev_err(hdev->dev,
500                         "Failed to set pwm info to sensor %d, error %d\n",
501                         sensor_index, rc);
502 }
503
504 int hl_set_voltage(struct hl_device *hdev,
505                         int sensor_index, u32 attr, long value)
506 {
507         struct cpucp_packet pkt;
508         int rc;
509
510         memset(&pkt, 0, sizeof(pkt));
511
512         pkt.ctl = cpu_to_le32(CPUCP_PACKET_VOLTAGE_SET <<
513                                 CPUCP_PKT_CTL_OPCODE_SHIFT);
514         pkt.sensor_index = __cpu_to_le16(sensor_index);
515         pkt.type = __cpu_to_le16(attr);
516         pkt.value = __cpu_to_le64(value);
517
518         rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
519                                                 0, NULL);
520
521         if (rc)
522                 dev_err(hdev->dev,
523                         "Failed to set voltage of sensor %d, error %d\n",
524                         sensor_index, rc);
525
526         return rc;
527 }
528
529 int hl_set_current(struct hl_device *hdev,
530                         int sensor_index, u32 attr, long value)
531 {
532         struct cpucp_packet pkt;
533         int rc;
534
535         memset(&pkt, 0, sizeof(pkt));
536
537         pkt.ctl = cpu_to_le32(CPUCP_PACKET_CURRENT_SET <<
538                                 CPUCP_PKT_CTL_OPCODE_SHIFT);
539         pkt.sensor_index = __cpu_to_le16(sensor_index);
540         pkt.type = __cpu_to_le16(attr);
541         pkt.value = __cpu_to_le64(value);
542
543         rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
544                                                 0, NULL);
545
546         if (rc)
547                 dev_err(hdev->dev,
548                         "Failed to set current of sensor %d, error %d\n",
549                         sensor_index, rc);
550
551         return rc;
552 }
553
554 int hl_hwmon_init(struct hl_device *hdev)
555 {
556         struct device *dev = hdev->pdev ? &hdev->pdev->dev : hdev->dev;
557         struct asic_fixed_properties *prop = &hdev->asic_prop;
558         int rc;
559
560         if ((hdev->hwmon_initialized) || !(hdev->cpu_queues_enable))
561                 return 0;
562
563         if (hdev->hl_chip_info->info) {
564                 hdev->hl_chip_info->ops = &hl_hwmon_ops;
565
566                 hdev->hwmon_dev = hwmon_device_register_with_info(dev,
567                                         prop->cpucp_info.card_name, hdev,
568                                         hdev->hl_chip_info, NULL);
569                 if (IS_ERR(hdev->hwmon_dev)) {
570                         rc = PTR_ERR(hdev->hwmon_dev);
571                         dev_err(hdev->dev,
572                                 "Unable to register hwmon device: %d\n", rc);
573                         return rc;
574                 }
575
576                 dev_info(hdev->dev, "%s: add sensors information\n",
577                         dev_name(hdev->hwmon_dev));
578
579                 hdev->hwmon_initialized = true;
580         } else {
581                 dev_info(hdev->dev, "no available sensors\n");
582         }
583
584         return 0;
585 }
586
587 void hl_hwmon_fini(struct hl_device *hdev)
588 {
589         if (!hdev->hwmon_initialized)
590                 return;
591
592         hwmon_device_unregister(hdev->hwmon_dev);
593 }