mirror of
https://github.com/torvalds/linux.git
synced 2024-11-18 18:11:56 +00:00
drm/nouveau/fan: rewrite the fan tachometer driver to get more precision, faster
The previous driver waited for 250ms to accumulate data. This version times a complete fan rotation and extrapolates to RPM. The fan rotational speed should now be read in less than 250ms (worst case) and usually in less 50ms. Signed-off-by: Martin Peres <martin.peres@labri.fr> Reviewed-by: Ben Skeggs <bskeggs@redhat.com> Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
This commit is contained in:
parent
aa1b9b4836
commit
bf6546b421
@ -105,30 +105,37 @@ nouveau_therm_fan_sense(struct nouveau_therm *therm)
|
||||
struct nouveau_gpio *gpio = nouveau_gpio(therm);
|
||||
struct dcb_gpio_func func;
|
||||
u32 cycles, cur, prev;
|
||||
u64 start;
|
||||
u64 start, end, tach;
|
||||
|
||||
if (gpio->find(gpio, 0, DCB_GPIO_FAN_SENSE, 0xff, &func))
|
||||
return -ENODEV;
|
||||
|
||||
/* Monitor the GPIO input 0x3b for 250ms.
|
||||
/* Time a complete rotation and extrapolate to RPM:
|
||||
* When the fan spins, it changes the value of GPIO FAN_SENSE.
|
||||
* We get 4 changes (0 -> 1 -> 0 -> 1 -> [...]) per complete rotation.
|
||||
* We get 4 changes (0 -> 1 -> 0 -> 1) per complete rotation.
|
||||
*/
|
||||
start = ptimer->read(ptimer);
|
||||
prev = gpio->get(gpio, 0, func.func, func.line);
|
||||
cycles = 0;
|
||||
do {
|
||||
usleep_range(500, 1000); /* supports 0 < rpm < 7500 */
|
||||
|
||||
cur = gpio->get(gpio, 0, func.func, func.line);
|
||||
if (prev != cur) {
|
||||
if (!start)
|
||||
start = ptimer->read(ptimer);
|
||||
cycles++;
|
||||
prev = cur;
|
||||
}
|
||||
} while (cycles < 5 && ptimer->read(ptimer) - start < 250000000);
|
||||
end = ptimer->read(ptimer);
|
||||
|
||||
usleep_range(500, 1000); /* supports 0 < rpm < 7500 */
|
||||
} while (ptimer->read(ptimer) - start < 250000000);
|
||||
|
||||
/* interpolate to get rpm */
|
||||
return cycles / 4 * 4 * 60;
|
||||
if (cycles == 5) {
|
||||
tach = (u64)60000000000;
|
||||
do_div(tach, (end - start));
|
||||
return tach;
|
||||
} else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
|
Loading…
Reference in New Issue
Block a user