GNU Linux-libre 4.19.264-gnu1
[releases.git] / drivers / net / ethernet / mellanox / mlxsw / core_thermal.c
1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2 /* Copyright (c) 2016-2018 Mellanox Technologies. All rights reserved
3  * Copyright (c) 2016 Ivan Vecera <cera@cera.cz>
4  */
5
6 #include <linux/kernel.h>
7 #include <linux/types.h>
8 #include <linux/device.h>
9 #include <linux/sysfs.h>
10 #include <linux/thermal.h>
11 #include <linux/err.h>
12
13 #include "core.h"
14
15 #define MLXSW_THERMAL_POLL_INT  1000    /* ms */
16 #define MLXSW_THERMAL_MAX_TEMP  110000  /* 110C */
17 #define MLXSW_THERMAL_MAX_STATE 10
18 #define MLXSW_THERMAL_MAX_DUTY  255
19
20 struct mlxsw_thermal_trip {
21         int     type;
22         int     temp;
23         int     min_state;
24         int     max_state;
25 };
26
27 static const struct mlxsw_thermal_trip default_thermal_trips[] = {
28         {       /* In range - 0-40% PWM */
29                 .type           = THERMAL_TRIP_ACTIVE,
30                 .temp           = 75000,
31                 .min_state      = 0,
32                 .max_state      = (4 * MLXSW_THERMAL_MAX_STATE) / 10,
33         },
34         {       /* High - 40-100% PWM */
35                 .type           = THERMAL_TRIP_ACTIVE,
36                 .temp           = 80000,
37                 .min_state      = (4 * MLXSW_THERMAL_MAX_STATE) / 10,
38                 .max_state      = MLXSW_THERMAL_MAX_STATE,
39         },
40         {
41                 /* Very high - 100% PWM */
42                 .type           = THERMAL_TRIP_ACTIVE,
43                 .temp           = 85000,
44                 .min_state      = MLXSW_THERMAL_MAX_STATE,
45                 .max_state      = MLXSW_THERMAL_MAX_STATE,
46         },
47         {       /* Warning */
48                 .type           = THERMAL_TRIP_HOT,
49                 .temp           = 105000,
50                 .min_state      = MLXSW_THERMAL_MAX_STATE,
51                 .max_state      = MLXSW_THERMAL_MAX_STATE,
52         },
53         {       /* Critical - soft poweroff */
54                 .type           = THERMAL_TRIP_CRITICAL,
55                 .temp           = MLXSW_THERMAL_MAX_TEMP,
56                 .min_state      = MLXSW_THERMAL_MAX_STATE,
57                 .max_state      = MLXSW_THERMAL_MAX_STATE,
58         }
59 };
60
61 #define MLXSW_THERMAL_NUM_TRIPS ARRAY_SIZE(default_thermal_trips)
62
63 /* Make sure all trips are writable */
64 #define MLXSW_THERMAL_TRIP_MASK (BIT(MLXSW_THERMAL_NUM_TRIPS) - 1)
65
66 struct mlxsw_thermal {
67         struct mlxsw_core *core;
68         const struct mlxsw_bus_info *bus_info;
69         struct thermal_zone_device *tzdev;
70         struct thermal_cooling_device *cdevs[MLXSW_MFCR_PWMS_MAX];
71         struct mlxsw_thermal_trip trips[MLXSW_THERMAL_NUM_TRIPS];
72         enum thermal_device_mode mode;
73 };
74
75 static inline u8 mlxsw_state_to_duty(int state)
76 {
77         return DIV_ROUND_CLOSEST(state * MLXSW_THERMAL_MAX_DUTY,
78                                  MLXSW_THERMAL_MAX_STATE);
79 }
80
81 static inline int mlxsw_duty_to_state(u8 duty)
82 {
83         return DIV_ROUND_CLOSEST(duty * MLXSW_THERMAL_MAX_STATE,
84                                  MLXSW_THERMAL_MAX_DUTY);
85 }
86
87 static int mlxsw_get_cooling_device_idx(struct mlxsw_thermal *thermal,
88                                         struct thermal_cooling_device *cdev)
89 {
90         int i;
91
92         for (i = 0; i < MLXSW_MFCR_PWMS_MAX; i++)
93                 if (thermal->cdevs[i] == cdev)
94                         return i;
95
96         return -ENODEV;
97 }
98
99 static int mlxsw_thermal_bind(struct thermal_zone_device *tzdev,
100                               struct thermal_cooling_device *cdev)
101 {
102         struct mlxsw_thermal *thermal = tzdev->devdata;
103         struct device *dev = thermal->bus_info->dev;
104         int i, err;
105
106         /* If the cooling device is one of ours bind it */
107         if (mlxsw_get_cooling_device_idx(thermal, cdev) < 0)
108                 return 0;
109
110         for (i = 0; i < MLXSW_THERMAL_NUM_TRIPS; i++) {
111                 const struct mlxsw_thermal_trip *trip = &thermal->trips[i];
112
113                 err = thermal_zone_bind_cooling_device(tzdev, i, cdev,
114                                                        trip->max_state,
115                                                        trip->min_state,
116                                                        THERMAL_WEIGHT_DEFAULT);
117                 if (err < 0) {
118                         dev_err(dev, "Failed to bind cooling device to trip %d\n", i);
119                         return err;
120                 }
121         }
122         return 0;
123 }
124
125 static int mlxsw_thermal_unbind(struct thermal_zone_device *tzdev,
126                                 struct thermal_cooling_device *cdev)
127 {
128         struct mlxsw_thermal *thermal = tzdev->devdata;
129         struct device *dev = thermal->bus_info->dev;
130         int i;
131         int err;
132
133         /* If the cooling device is our one unbind it */
134         if (mlxsw_get_cooling_device_idx(thermal, cdev) < 0)
135                 return 0;
136
137         for (i = 0; i < MLXSW_THERMAL_NUM_TRIPS; i++) {
138                 err = thermal_zone_unbind_cooling_device(tzdev, i, cdev);
139                 if (err < 0) {
140                         dev_err(dev, "Failed to unbind cooling device\n");
141                         return err;
142                 }
143         }
144         return 0;
145 }
146
147 static int mlxsw_thermal_get_mode(struct thermal_zone_device *tzdev,
148                                   enum thermal_device_mode *mode)
149 {
150         struct mlxsw_thermal *thermal = tzdev->devdata;
151
152         *mode = thermal->mode;
153
154         return 0;
155 }
156
157 static int mlxsw_thermal_set_mode(struct thermal_zone_device *tzdev,
158                                   enum thermal_device_mode mode)
159 {
160         struct mlxsw_thermal *thermal = tzdev->devdata;
161
162         mutex_lock(&tzdev->lock);
163
164         if (mode == THERMAL_DEVICE_ENABLED)
165                 tzdev->polling_delay = MLXSW_THERMAL_POLL_INT;
166         else
167                 tzdev->polling_delay = 0;
168
169         mutex_unlock(&tzdev->lock);
170
171         thermal->mode = mode;
172         thermal_zone_device_update(tzdev, THERMAL_EVENT_UNSPECIFIED);
173
174         return 0;
175 }
176
177 static int mlxsw_thermal_get_temp(struct thermal_zone_device *tzdev,
178                                   int *p_temp)
179 {
180         struct mlxsw_thermal *thermal = tzdev->devdata;
181         struct device *dev = thermal->bus_info->dev;
182         char mtmp_pl[MLXSW_REG_MTMP_LEN];
183         unsigned int temp;
184         int err;
185
186         mlxsw_reg_mtmp_pack(mtmp_pl, 0, false, false);
187
188         err = mlxsw_reg_query(thermal->core, MLXSW_REG(mtmp), mtmp_pl);
189         if (err) {
190                 dev_err(dev, "Failed to query temp sensor\n");
191                 return err;
192         }
193         mlxsw_reg_mtmp_unpack(mtmp_pl, &temp, NULL, NULL);
194
195         *p_temp = (int) temp;
196         return 0;
197 }
198
199 static int mlxsw_thermal_get_trip_type(struct thermal_zone_device *tzdev,
200                                        int trip,
201                                        enum thermal_trip_type *p_type)
202 {
203         struct mlxsw_thermal *thermal = tzdev->devdata;
204
205         if (trip < 0 || trip >= MLXSW_THERMAL_NUM_TRIPS)
206                 return -EINVAL;
207
208         *p_type = thermal->trips[trip].type;
209         return 0;
210 }
211
212 static int mlxsw_thermal_get_trip_temp(struct thermal_zone_device *tzdev,
213                                        int trip, int *p_temp)
214 {
215         struct mlxsw_thermal *thermal = tzdev->devdata;
216
217         if (trip < 0 || trip >= MLXSW_THERMAL_NUM_TRIPS)
218                 return -EINVAL;
219
220         *p_temp = thermal->trips[trip].temp;
221         return 0;
222 }
223
224 static int mlxsw_thermal_set_trip_temp(struct thermal_zone_device *tzdev,
225                                        int trip, int temp)
226 {
227         struct mlxsw_thermal *thermal = tzdev->devdata;
228
229         if (trip < 0 || trip >= MLXSW_THERMAL_NUM_TRIPS ||
230             temp > MLXSW_THERMAL_MAX_TEMP)
231                 return -EINVAL;
232
233         thermal->trips[trip].temp = temp;
234         return 0;
235 }
236
237 static struct thermal_zone_device_ops mlxsw_thermal_ops = {
238         .bind = mlxsw_thermal_bind,
239         .unbind = mlxsw_thermal_unbind,
240         .get_mode = mlxsw_thermal_get_mode,
241         .set_mode = mlxsw_thermal_set_mode,
242         .get_temp = mlxsw_thermal_get_temp,
243         .get_trip_type  = mlxsw_thermal_get_trip_type,
244         .get_trip_temp  = mlxsw_thermal_get_trip_temp,
245         .set_trip_temp  = mlxsw_thermal_set_trip_temp,
246 };
247
248 static int mlxsw_thermal_get_max_state(struct thermal_cooling_device *cdev,
249                                        unsigned long *p_state)
250 {
251         *p_state = MLXSW_THERMAL_MAX_STATE;
252         return 0;
253 }
254
255 static int mlxsw_thermal_get_cur_state(struct thermal_cooling_device *cdev,
256                                        unsigned long *p_state)
257
258 {
259         struct mlxsw_thermal *thermal = cdev->devdata;
260         struct device *dev = thermal->bus_info->dev;
261         char mfsc_pl[MLXSW_REG_MFSC_LEN];
262         int err, idx;
263         u8 duty;
264
265         idx = mlxsw_get_cooling_device_idx(thermal, cdev);
266         if (idx < 0)
267                 return idx;
268
269         mlxsw_reg_mfsc_pack(mfsc_pl, idx, 0);
270         err = mlxsw_reg_query(thermal->core, MLXSW_REG(mfsc), mfsc_pl);
271         if (err) {
272                 dev_err(dev, "Failed to query PWM duty\n");
273                 return err;
274         }
275
276         duty = mlxsw_reg_mfsc_pwm_duty_cycle_get(mfsc_pl);
277         *p_state = mlxsw_duty_to_state(duty);
278         return 0;
279 }
280
281 static int mlxsw_thermal_set_cur_state(struct thermal_cooling_device *cdev,
282                                        unsigned long state)
283
284 {
285         struct mlxsw_thermal *thermal = cdev->devdata;
286         struct device *dev = thermal->bus_info->dev;
287         char mfsc_pl[MLXSW_REG_MFSC_LEN];
288         int err, idx;
289
290         idx = mlxsw_get_cooling_device_idx(thermal, cdev);
291         if (idx < 0)
292                 return idx;
293
294         mlxsw_reg_mfsc_pack(mfsc_pl, idx, mlxsw_state_to_duty(state));
295         err = mlxsw_reg_write(thermal->core, MLXSW_REG(mfsc), mfsc_pl);
296         if (err) {
297                 dev_err(dev, "Failed to write PWM duty\n");
298                 return err;
299         }
300         return 0;
301 }
302
303 static const struct thermal_cooling_device_ops mlxsw_cooling_ops = {
304         .get_max_state  = mlxsw_thermal_get_max_state,
305         .get_cur_state  = mlxsw_thermal_get_cur_state,
306         .set_cur_state  = mlxsw_thermal_set_cur_state,
307 };
308
309 int mlxsw_thermal_init(struct mlxsw_core *core,
310                        const struct mlxsw_bus_info *bus_info,
311                        struct mlxsw_thermal **p_thermal)
312 {
313         char mfcr_pl[MLXSW_REG_MFCR_LEN] = { 0 };
314         enum mlxsw_reg_mfcr_pwm_frequency freq;
315         struct device *dev = bus_info->dev;
316         struct mlxsw_thermal *thermal;
317         u16 tacho_active;
318         u8 pwm_active;
319         int err, i;
320
321         thermal = devm_kzalloc(dev, sizeof(*thermal),
322                                GFP_KERNEL);
323         if (!thermal)
324                 return -ENOMEM;
325
326         thermal->core = core;
327         thermal->bus_info = bus_info;
328         memcpy(thermal->trips, default_thermal_trips, sizeof(thermal->trips));
329
330         err = mlxsw_reg_query(thermal->core, MLXSW_REG(mfcr), mfcr_pl);
331         if (err) {
332                 dev_err(dev, "Failed to probe PWMs\n");
333                 goto err_free_thermal;
334         }
335         mlxsw_reg_mfcr_unpack(mfcr_pl, &freq, &tacho_active, &pwm_active);
336
337         for (i = 0; i < MLXSW_MFCR_TACHOS_MAX; i++) {
338                 if (tacho_active & BIT(i)) {
339                         char mfsl_pl[MLXSW_REG_MFSL_LEN];
340
341                         mlxsw_reg_mfsl_pack(mfsl_pl, i, 0, 0);
342
343                         /* We need to query the register to preserve maximum */
344                         err = mlxsw_reg_query(thermal->core, MLXSW_REG(mfsl),
345                                               mfsl_pl);
346                         if (err)
347                                 goto err_free_thermal;
348
349                         /* set the minimal RPMs to 0 */
350                         mlxsw_reg_mfsl_tach_min_set(mfsl_pl, 0);
351                         err = mlxsw_reg_write(thermal->core, MLXSW_REG(mfsl),
352                                               mfsl_pl);
353                         if (err)
354                                 goto err_free_thermal;
355                 }
356         }
357         for (i = 0; i < MLXSW_MFCR_PWMS_MAX; i++) {
358                 if (pwm_active & BIT(i)) {
359                         struct thermal_cooling_device *cdev;
360
361                         cdev = thermal_cooling_device_register("Fan", thermal,
362                                                         &mlxsw_cooling_ops);
363                         if (IS_ERR(cdev)) {
364                                 err = PTR_ERR(cdev);
365                                 dev_err(dev, "Failed to register cooling device\n");
366                                 goto err_unreg_cdevs;
367                         }
368                         thermal->cdevs[i] = cdev;
369                 }
370         }
371
372         thermal->tzdev = thermal_zone_device_register("mlxsw",
373                                                       MLXSW_THERMAL_NUM_TRIPS,
374                                                       MLXSW_THERMAL_TRIP_MASK,
375                                                       thermal,
376                                                       &mlxsw_thermal_ops,
377                                                       NULL, 0,
378                                                       MLXSW_THERMAL_POLL_INT);
379         if (IS_ERR(thermal->tzdev)) {
380                 err = PTR_ERR(thermal->tzdev);
381                 dev_err(dev, "Failed to register thermal zone\n");
382                 goto err_unreg_cdevs;
383         }
384
385         thermal->mode = THERMAL_DEVICE_ENABLED;
386         *p_thermal = thermal;
387         return 0;
388 err_unreg_cdevs:
389         for (i = 0; i < MLXSW_MFCR_PWMS_MAX; i++)
390                 if (thermal->cdevs[i])
391                         thermal_cooling_device_unregister(thermal->cdevs[i]);
392 err_free_thermal:
393         devm_kfree(dev, thermal);
394         return err;
395 }
396
397 void mlxsw_thermal_fini(struct mlxsw_thermal *thermal)
398 {
399         int i;
400
401         if (thermal->tzdev) {
402                 thermal_zone_device_unregister(thermal->tzdev);
403                 thermal->tzdev = NULL;
404         }
405
406         for (i = 0; i < MLXSW_MFCR_PWMS_MAX; i++) {
407                 if (thermal->cdevs[i]) {
408                         thermal_cooling_device_unregister(thermal->cdevs[i]);
409                         thermal->cdevs[i] = NULL;
410                 }
411         }
412
413         devm_kfree(thermal->bus_info->dev, thermal);
414 }