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