Skip to content

Commit a421ce0

Browse files
mellanoxbmcdavem330
authored andcommitted
mlxsw: core: Extend cooling device with cooling levels
Extend cooling device with cooling levels vector to allow more flexibility of PWM setting. Thermal zone algorithm operates with the numerical states for PWM setting. Each state is the index, defined in range from 0 to 10 and it's mapped to the relevant duty cycle value, which is written to PWM controller. With the current definition fan speed is set to 0% for state 0, 10% for state 1, and so on up to 100% for the maximum state 10. Some systems have limitation for the PWM speed minimum. For such systems PWM setting speed to 0% will just disable the ability to increase speed anymore and such device will be stall on zero speed. Cooling levels allow to configure state vector according to the particular system requirements. For example, if PWM speed is not allowed to be below 30%, cooling levels could be configured as 30%, 30%, 30%, 30%, 40%, 50% and so on. Signed-off-by: Vadim Pasternak <[email protected]> Reviewed-by: Jiri Pirko <[email protected]> Signed-off-by: Ido Schimmel <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent b539ea6 commit a421ce0

File tree

1 file changed

+55
-1
lines changed

1 file changed

+55
-1
lines changed

drivers/net/ethernet/mellanox/mlxsw/core_thermal.c

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,15 @@
1616
#define MLXSW_THERMAL_MAX_TEMP 110000 /* 110C */
1717
#define MLXSW_THERMAL_MAX_STATE 10
1818
#define MLXSW_THERMAL_MAX_DUTY 255
19+
/* Minimum and maximum fan allowed speed in percent: from 20% to 100%. Values
20+
* MLXSW_THERMAL_MAX_STATE + x, where x is between 2 and 10 are used for
21+
* setting fan speed dynamic minimum. For example, if value is set to 14 (40%)
22+
* cooling levels vector will be set to 4, 4, 4, 4, 4, 5, 6, 7, 8, 9, 10 to
23+
* introduce PWM speed in percent: 40, 40, 40, 40, 40, 50, 60. 70, 80, 90, 100.
24+
*/
25+
#define MLXSW_THERMAL_SPEED_MIN (MLXSW_THERMAL_MAX_STATE + 2)
26+
#define MLXSW_THERMAL_SPEED_MAX (MLXSW_THERMAL_MAX_STATE * 2)
27+
#define MLXSW_THERMAL_SPEED_MIN_LEVEL 2 /* 20% */
1928

2029
struct mlxsw_thermal_trip {
2130
int type;
@@ -68,6 +77,7 @@ struct mlxsw_thermal {
6877
const struct mlxsw_bus_info *bus_info;
6978
struct thermal_zone_device *tzdev;
7079
struct thermal_cooling_device *cdevs[MLXSW_MFCR_PWMS_MAX];
80+
u8 cooling_levels[MLXSW_THERMAL_MAX_STATE + 1];
7181
struct mlxsw_thermal_trip trips[MLXSW_THERMAL_NUM_TRIPS];
7282
enum thermal_device_mode mode;
7383
};
@@ -285,12 +295,51 @@ static int mlxsw_thermal_set_cur_state(struct thermal_cooling_device *cdev,
285295
struct mlxsw_thermal *thermal = cdev->devdata;
286296
struct device *dev = thermal->bus_info->dev;
287297
char mfsc_pl[MLXSW_REG_MFSC_LEN];
288-
int err, idx;
298+
unsigned long cur_state, i;
299+
int idx;
300+
u8 duty;
301+
int err;
289302

290303
idx = mlxsw_get_cooling_device_idx(thermal, cdev);
291304
if (idx < 0)
292305
return idx;
293306

307+
/* Verify if this request is for changing allowed fan dynamical
308+
* minimum. If it is - update cooling levels accordingly and update
309+
* state, if current state is below the newly requested minimum state.
310+
* For example, if current state is 5, and minimal state is to be
311+
* changed from 4 to 6, thermal->cooling_levels[0 to 5] will be changed
312+
* all from 4 to 6. And state 5 (thermal->cooling_levels[4]) should be
313+
* overwritten.
314+
*/
315+
if (state >= MLXSW_THERMAL_SPEED_MIN &&
316+
state <= MLXSW_THERMAL_SPEED_MAX) {
317+
state -= MLXSW_THERMAL_MAX_STATE;
318+
for (i = 0; i <= MLXSW_THERMAL_MAX_STATE; i++)
319+
thermal->cooling_levels[i] = max(state, i);
320+
321+
mlxsw_reg_mfsc_pack(mfsc_pl, idx, 0);
322+
err = mlxsw_reg_query(thermal->core, MLXSW_REG(mfsc), mfsc_pl);
323+
if (err)
324+
return err;
325+
326+
duty = mlxsw_reg_mfsc_pwm_duty_cycle_get(mfsc_pl);
327+
cur_state = mlxsw_duty_to_state(duty);
328+
329+
/* If current fan state is lower than requested dynamical
330+
* minimum, increase fan speed up to dynamical minimum.
331+
*/
332+
if (state < cur_state)
333+
return 0;
334+
335+
state = cur_state;
336+
}
337+
338+
if (state > MLXSW_THERMAL_MAX_STATE)
339+
return -EINVAL;
340+
341+
/* Normalize the state to the valid speed range. */
342+
state = thermal->cooling_levels[state];
294343
mlxsw_reg_mfsc_pack(mfsc_pl, idx, mlxsw_state_to_duty(state));
295344
err = mlxsw_reg_write(thermal->core, MLXSW_REG(mfsc), mfsc_pl);
296345
if (err) {
@@ -369,6 +418,11 @@ int mlxsw_thermal_init(struct mlxsw_core *core,
369418
}
370419
}
371420

421+
/* Initialize cooling levels per PWM state. */
422+
for (i = 0; i < MLXSW_THERMAL_MAX_STATE; i++)
423+
thermal->cooling_levels[i] = max(MLXSW_THERMAL_SPEED_MIN_LEVEL,
424+
i);
425+
372426
thermal->tzdev = thermal_zone_device_register("mlxsw",
373427
MLXSW_THERMAL_NUM_TRIPS,
374428
MLXSW_THERMAL_TRIP_MASK,

0 commit comments

Comments
 (0)