Loading drivers/gpu/drm/nouveau/nvkm/subdev/therm/g84.c +26 −18 Original line number Diff line number Diff line Loading @@ -29,10 +29,11 @@ int g84_temp_get(struct nvkm_therm *therm) { struct nvkm_device *device = therm->subdev.device; struct nvkm_fuse *fuse = nvkm_fuse(therm); if (nv_ro32(fuse, 0x1a8) == 1) return nv_rd32(therm, 0x20400); return nvkm_rd32(device, 0x20400); else return -ENODEV; } Loading @@ -40,12 +41,13 @@ g84_temp_get(struct nvkm_therm *therm) void g84_sensor_setup(struct nvkm_therm *therm) { struct nvkm_device *device = therm->subdev.device; struct nvkm_fuse *fuse = nvkm_fuse(therm); /* enable temperature reading for cards with insane defaults */ if (nv_ro32(fuse, 0x1a8) == 1) { nv_mask(therm, 0x20008, 0x80008000, 0x80000000); nv_mask(therm, 0x2000c, 0x80000003, 0x00000000); nvkm_mask(device, 0x20008, 0x80008000, 0x80000000); nvkm_mask(device, 0x2000c, 0x80000003, 0x00000000); mdelay(20); /* wait for the temperature to stabilize */ } } Loading @@ -54,26 +56,27 @@ static void g84_therm_program_alarms(struct nvkm_therm *obj) { struct nvkm_therm_priv *therm = container_of(obj, typeof(*therm), base); struct nvkm_device *device = therm->base.subdev.device; struct nvbios_therm_sensor *sensor = &therm->bios_sensor; unsigned long flags; spin_lock_irqsave(&therm->sensor.alarm_program_lock, flags); /* enable RISING and FALLING IRQs for shutdown, THRS 0, 1, 2 and 4 */ nv_wr32(therm, 0x20000, 0x000003ff); nvkm_wr32(device, 0x20000, 0x000003ff); /* shutdown: The computer should be shutdown when reached */ nv_wr32(therm, 0x20484, sensor->thrs_shutdown.hysteresis); nv_wr32(therm, 0x20480, sensor->thrs_shutdown.temp); nvkm_wr32(device, 0x20484, sensor->thrs_shutdown.hysteresis); nvkm_wr32(device, 0x20480, sensor->thrs_shutdown.temp); /* THRS_1 : fan boost*/ nv_wr32(therm, 0x204c4, sensor->thrs_fan_boost.temp); nvkm_wr32(device, 0x204c4, sensor->thrs_fan_boost.temp); /* THRS_2 : critical */ nv_wr32(therm, 0x204c0, sensor->thrs_critical.temp); nvkm_wr32(device, 0x204c0, sensor->thrs_critical.temp); /* THRS_4 : down clock */ nv_wr32(therm, 0x20414, sensor->thrs_down_clock.temp); nvkm_wr32(device, 0x20414, sensor->thrs_down_clock.temp); spin_unlock_irqrestore(&therm->sensor.alarm_program_lock, flags); nv_debug(therm, Loading @@ -93,19 +96,20 @@ g84_therm_threshold_hyst_emulation(struct nvkm_therm *therm, const struct nvbios_therm_threshold *thrs, enum nvkm_therm_thrs thrs_name) { struct nvkm_device *device = therm->subdev.device; enum nvkm_therm_thrs_direction direction; enum nvkm_therm_thrs_state prev_state, new_state; int temp, cur; prev_state = nvkm_therm_sensor_get_threshold_state(therm, thrs_name); temp = nv_rd32(therm, thrs_reg); temp = nvkm_rd32(device, thrs_reg); /* program the next threshold */ if (temp == thrs->temp) { nv_wr32(therm, thrs_reg, thrs->temp - thrs->hysteresis); nvkm_wr32(device, thrs_reg, thrs->temp - thrs->hysteresis); new_state = NVKM_THERM_THRS_HIGHER; } else { nv_wr32(therm, thrs_reg, thrs->temp); nvkm_wr32(device, thrs_reg, thrs->temp); new_state = NVKM_THERM_THRS_LOWER; } Loading Loading @@ -134,13 +138,14 @@ static void g84_therm_intr(struct nvkm_subdev *subdev) { struct nvkm_therm_priv *therm = (void *)subdev; struct nvkm_device *device = therm->base.subdev.device; struct nvbios_therm_sensor *sensor = &therm->bios_sensor; unsigned long flags; uint32_t intr; spin_lock_irqsave(&therm->sensor.alarm_program_lock, flags); intr = nv_rd32(therm, 0x20100) & 0x3ff; intr = nvkm_rd32(device, 0x20100) & 0x3ff; /* THRS_4: downclock */ if (intr & 0x002) { Loading Loading @@ -178,8 +183,8 @@ g84_therm_intr(struct nvkm_subdev *subdev) nv_error(therm, "unhandled intr 0x%08x\n", intr); /* ACK everything */ nv_wr32(therm, 0x20100, 0xffffffff); nv_wr32(therm, 0x1100, 0x10000); /* PBUS */ nvkm_wr32(device, 0x20100, 0xffffffff); nvkm_wr32(device, 0x1100, 0x10000); /* PBUS */ spin_unlock_irqrestore(&therm->sensor.alarm_program_lock, flags); } Loading Loading @@ -239,12 +244,15 @@ g84_therm_ctor(struct nvkm_object *parent, struct nvkm_object *engine, int g84_therm_fini(struct nvkm_object *object, bool suspend) { struct nvkm_therm *therm = (void *)object; struct nvkm_device *device = therm->subdev.device; /* Disable PTherm IRQs */ nv_wr32(object, 0x20000, 0x00000000); nvkm_wr32(device, 0x20000, 0x00000000); /* ACK all PTherm IRQs */ nv_wr32(object, 0x20100, 0xffffffff); nv_wr32(object, 0x1100, 0x10000); /* PBUS */ nvkm_wr32(device, 0x20100, 0xffffffff); nvkm_wr32(device, 0x1100, 0x10000); /* PBUS */ return _nvkm_therm_fini(object, suspend); } Loading drivers/gpu/drm/nouveau/nvkm/subdev/therm/gf110.c +24 −18 Original line number Diff line number Diff line Loading @@ -26,7 +26,8 @@ static int pwm_info(struct nvkm_therm *therm, int line) { u32 gpio = nv_rd32(therm, 0x00d610 + (line * 0x04)); struct nvkm_device *device = therm->subdev.device; u32 gpio = nvkm_rd32(device, 0x00d610 + (line * 0x04)); switch (gpio & 0x000000c0) { case 0x00000000: /* normal mode, possibly pwm forced off by us */ Loading @@ -50,12 +51,13 @@ pwm_info(struct nvkm_therm *therm, int line) static int gf110_fan_pwm_ctrl(struct nvkm_therm *therm, int line, bool enable) { struct nvkm_device *device = therm->subdev.device; u32 data = enable ? 0x00000040 : 0x00000000; int indx = pwm_info(therm, line); if (indx < 0) return indx; else if (indx < 2) nv_mask(therm, 0x00d610 + (line * 0x04), 0x000000c0, data); nvkm_mask(device, 0x00d610 + (line * 0x04), 0x000000c0, data); /* nothing to do for indx == 2, it seems hardwired to PTHERM */ return 0; } Loading @@ -63,18 +65,19 @@ gf110_fan_pwm_ctrl(struct nvkm_therm *therm, int line, bool enable) static int gf110_fan_pwm_get(struct nvkm_therm *therm, int line, u32 *divs, u32 *duty) { struct nvkm_device *device = therm->subdev.device; int indx = pwm_info(therm, line); if (indx < 0) return indx; else if (indx < 2) { if (nv_rd32(therm, 0x00d610 + (line * 0x04)) & 0x00000040) { *divs = nv_rd32(therm, 0x00e114 + (indx * 8)); *duty = nv_rd32(therm, 0x00e118 + (indx * 8)); if (nvkm_rd32(device, 0x00d610 + (line * 0x04)) & 0x00000040) { *divs = nvkm_rd32(device, 0x00e114 + (indx * 8)); *duty = nvkm_rd32(device, 0x00e118 + (indx * 8)); return 0; } } else if (indx == 2) { *divs = nv_rd32(therm, 0x0200d8) & 0x1fff; *duty = nv_rd32(therm, 0x0200dc) & 0x1fff; *divs = nvkm_rd32(device, 0x0200d8) & 0x1fff; *duty = nvkm_rd32(device, 0x0200dc) & 0x1fff; return 0; } Loading @@ -84,15 +87,16 @@ gf110_fan_pwm_get(struct nvkm_therm *therm, int line, u32 *divs, u32 *duty) static int gf110_fan_pwm_set(struct nvkm_therm *therm, int line, u32 divs, u32 duty) { struct nvkm_device *device = therm->subdev.device; int indx = pwm_info(therm, line); if (indx < 0) return indx; else if (indx < 2) { nv_wr32(therm, 0x00e114 + (indx * 8), divs); nv_wr32(therm, 0x00e118 + (indx * 8), duty | 0x80000000); nvkm_wr32(device, 0x00e114 + (indx * 8), divs); nvkm_wr32(device, 0x00e118 + (indx * 8), duty | 0x80000000); } else if (indx == 2) { nv_mask(therm, 0x0200d8, 0x1fff, divs); /* keep the high bits */ nv_wr32(therm, 0x0200dc, duty | 0x40000000); nvkm_mask(device, 0x0200d8, 0x1fff, divs); /* keep the high bits */ nvkm_wr32(device, 0x0200dc, duty | 0x40000000); } return 0; } Loading @@ -100,19 +104,21 @@ gf110_fan_pwm_set(struct nvkm_therm *therm, int line, u32 divs, u32 duty) static int gf110_fan_pwm_clock(struct nvkm_therm *therm, int line) { struct nvkm_device *device = therm->subdev.device; int indx = pwm_info(therm, line); if (indx < 0) return 0; else if (indx < 2) return (nv_device(therm)->crystal * 1000) / 20; return (device->crystal * 1000) / 20; else return nv_device(therm)->crystal * 1000 / 10; return device->crystal * 1000 / 10; } int gf110_therm_init(struct nvkm_object *object) { struct nvkm_therm_priv *therm = (void *)object; struct nvkm_device *device = therm->base.subdev.device; int ret; ret = nvkm_therm_init(&therm->base); Loading @@ -120,13 +126,13 @@ gf110_therm_init(struct nvkm_object *object) return ret; /* enable fan tach, count revolutions per-second */ nv_mask(therm, 0x00e720, 0x00000003, 0x00000002); nvkm_mask(device, 0x00e720, 0x00000003, 0x00000002); if (therm->fan->tach.func != DCB_GPIO_UNUSED) { nv_mask(therm, 0x00d79c, 0x000000ff, therm->fan->tach.line); nv_wr32(therm, 0x00e724, nv_device(therm)->crystal * 1000); nv_mask(therm, 0x00e720, 0x00000001, 0x00000001); nvkm_mask(device, 0x00d79c, 0x000000ff, therm->fan->tach.line); nvkm_wr32(device, 0x00e724, nv_device(therm)->crystal * 1000); nvkm_mask(device, 0x00e720, 0x00000001, 0x00000001); } nv_mask(therm, 0x00e720, 0x00000002, 0x00000000); nvkm_mask(device, 0x00e720, 0x00000002, 0x00000000); return 0; } Loading drivers/gpu/drm/nouveau/nvkm/subdev/therm/gm107.c +7 −5 Original line number Diff line number Diff line Loading @@ -33,23 +33,25 @@ gm107_fan_pwm_ctrl(struct nvkm_therm *therm, int line, bool enable) static int gm107_fan_pwm_get(struct nvkm_therm *therm, int line, u32 *divs, u32 *duty) { *divs = nv_rd32(therm, 0x10eb20) & 0x1fff; *duty = nv_rd32(therm, 0x10eb24) & 0x1fff; struct nvkm_device *device = therm->subdev.device; *divs = nvkm_rd32(device, 0x10eb20) & 0x1fff; *duty = nvkm_rd32(device, 0x10eb24) & 0x1fff; return 0; } static int gm107_fan_pwm_set(struct nvkm_therm *therm, int line, u32 divs, u32 duty) { nv_mask(therm, 0x10eb10, 0x1fff, divs); /* keep the high bits */ nv_wr32(therm, 0x10eb14, duty | 0x80000000); struct nvkm_device *device = therm->subdev.device; nvkm_mask(device, 0x10eb10, 0x1fff, divs); /* keep the high bits */ nvkm_wr32(device, 0x10eb14, duty | 0x80000000); return 0; } static int gm107_fan_pwm_clock(struct nvkm_therm *therm, int line) { return nv_device(therm)->crystal * 1000; return therm->subdev.device->crystal * 1000; } static int Loading drivers/gpu/drm/nouveau/nvkm/subdev/therm/gt215.c +9 −7 Original line number Diff line number Diff line Loading @@ -28,8 +28,9 @@ int gt215_therm_fan_sense(struct nvkm_therm *therm) { u32 tach = nv_rd32(therm, 0x00e728) & 0x0000ffff; u32 ctrl = nv_rd32(therm, 0x00e720); struct nvkm_device *device = therm->subdev.device; u32 tach = nvkm_rd32(device, 0x00e728) & 0x0000ffff; u32 ctrl = nvkm_rd32(device, 0x00e720); if (ctrl & 0x00000001) return tach * 60 / 2; return -ENODEV; Loading @@ -39,6 +40,7 @@ static int gt215_therm_init(struct nvkm_object *object) { struct nvkm_therm_priv *therm = (void *)object; struct nvkm_device *device = therm->base.subdev.device; struct dcb_gpio_func *tach = &therm->fan->tach; int ret; Loading @@ -49,13 +51,13 @@ gt215_therm_init(struct nvkm_object *object) g84_sensor_setup(&therm->base); /* enable fan tach, count revolutions per-second */ nv_mask(therm, 0x00e720, 0x00000003, 0x00000002); nvkm_mask(device, 0x00e720, 0x00000003, 0x00000002); if (tach->func != DCB_GPIO_UNUSED) { nv_wr32(therm, 0x00e724, nv_device(therm)->crystal * 1000); nv_mask(therm, 0x00e720, 0x001f0000, tach->line << 16); nv_mask(therm, 0x00e720, 0x00000001, 0x00000001); nvkm_wr32(device, 0x00e724, nv_device(therm)->crystal * 1000); nvkm_mask(device, 0x00e720, 0x001f0000, tach->line << 16); nvkm_mask(device, 0x00e720, 0x00000001, 0x00000001); } nv_mask(therm, 0x00e720, 0x00000002, 0x00000000); nvkm_mask(device, 0x00e720, 0x00000002, 0x00000000); return 0; } Loading drivers/gpu/drm/nouveau/nvkm/subdev/therm/nv40.c +25 −19 Original line number Diff line number Diff line Loading @@ -55,18 +55,19 @@ nv40_sensor_style(struct nvkm_therm *therm) static int nv40_sensor_setup(struct nvkm_therm *therm) { struct nvkm_device *device = therm->subdev.device; enum nv40_sensor_style style = nv40_sensor_style(therm); /* enable ADC readout and disable the ALARM threshold */ if (style == NEW_STYLE) { nv_mask(therm, 0x15b8, 0x80000000, 0); nv_wr32(therm, 0x15b0, 0x80003fff); nvkm_mask(device, 0x15b8, 0x80000000, 0); nvkm_wr32(device, 0x15b0, 0x80003fff); mdelay(20); /* wait for the temperature to stabilize */ return nv_rd32(therm, 0x15b4) & 0x3fff; return nvkm_rd32(device, 0x15b4) & 0x3fff; } else if (style == OLD_STYLE) { nv_wr32(therm, 0x15b0, 0xff); nvkm_wr32(device, 0x15b0, 0xff); mdelay(20); /* wait for the temperature to stabilize */ return nv_rd32(therm, 0x15b4) & 0xff; return nvkm_rd32(device, 0x15b4) & 0xff; } else return -ENODEV; } Loading @@ -75,16 +76,17 @@ static int nv40_temp_get(struct nvkm_therm *obj) { struct nvkm_therm_priv *therm = container_of(obj, typeof(*therm), base); struct nvkm_device *device = therm->base.subdev.device; struct nvbios_therm_sensor *sensor = &therm->bios_sensor; enum nv40_sensor_style style = nv40_sensor_style(&therm->base); int core_temp; if (style == NEW_STYLE) { nv_wr32(therm, 0x15b0, 0x80003fff); core_temp = nv_rd32(therm, 0x15b4) & 0x3fff; nvkm_wr32(device, 0x15b0, 0x80003fff); core_temp = nvkm_rd32(device, 0x15b4) & 0x3fff; } else if (style == OLD_STYLE) { nv_wr32(therm, 0x15b0, 0xff); core_temp = nv_rd32(therm, 0x15b4) & 0xff; nvkm_wr32(device, 0x15b0, 0xff); core_temp = nvkm_rd32(device, 0x15b4) & 0xff; } else return -ENODEV; Loading @@ -107,9 +109,10 @@ nv40_temp_get(struct nvkm_therm *obj) static int nv40_fan_pwm_ctrl(struct nvkm_therm *therm, int line, bool enable) { struct nvkm_device *device = therm->subdev.device; u32 mask = enable ? 0x80000000 : 0x0000000; if (line == 2) nv_mask(therm, 0x0010f0, 0x80000000, mask); else if (line == 9) nv_mask(therm, 0x0015f4, 0x80000000, mask); if (line == 2) nvkm_mask(device, 0x0010f0, 0x80000000, mask); else if (line == 9) nvkm_mask(device, 0x0015f4, 0x80000000, mask); else { nv_error(therm, "unknown pwm ctrl for gpio %d\n", line); return -ENODEV; Loading @@ -120,8 +123,9 @@ nv40_fan_pwm_ctrl(struct nvkm_therm *therm, int line, bool enable) static int nv40_fan_pwm_get(struct nvkm_therm *therm, int line, u32 *divs, u32 *duty) { struct nvkm_device *device = therm->subdev.device; if (line == 2) { u32 reg = nv_rd32(therm, 0x0010f0); u32 reg = nvkm_rd32(device, 0x0010f0); if (reg & 0x80000000) { *duty = (reg & 0x7fff0000) >> 16; *divs = (reg & 0x00007fff); Loading @@ -129,9 +133,9 @@ nv40_fan_pwm_get(struct nvkm_therm *therm, int line, u32 *divs, u32 *duty) } } else if (line == 9) { u32 reg = nv_rd32(therm, 0x0015f4); u32 reg = nvkm_rd32(device, 0x0015f4); if (reg & 0x80000000) { *divs = nv_rd32(therm, 0x0015f8); *divs = nvkm_rd32(device, 0x0015f8); *duty = (reg & 0x7fffffff); return 0; } Loading @@ -146,12 +150,13 @@ nv40_fan_pwm_get(struct nvkm_therm *therm, int line, u32 *divs, u32 *duty) static int nv40_fan_pwm_set(struct nvkm_therm *therm, int line, u32 divs, u32 duty) { struct nvkm_device *device = therm->subdev.device; if (line == 2) { nv_mask(therm, 0x0010f0, 0x7fff7fff, (duty << 16) | divs); nvkm_mask(device, 0x0010f0, 0x7fff7fff, (duty << 16) | divs); } else if (line == 9) { nv_wr32(therm, 0x0015f8, divs); nv_mask(therm, 0x0015f4, 0x7fffffff, duty); nvkm_wr32(device, 0x0015f8, divs); nvkm_mask(device, 0x0015f4, 0x7fffffff, duty); } else { nv_error(therm, "unknown pwm ctrl for gpio %d\n", line); return -ENODEV; Loading @@ -164,12 +169,13 @@ void nv40_therm_intr(struct nvkm_subdev *subdev) { struct nvkm_therm *therm = nvkm_therm(subdev); uint32_t stat = nv_rd32(therm, 0x1100); struct nvkm_device *device = therm->subdev.device; uint32_t stat = nvkm_rd32(device, 0x1100); /* traitement */ /* ack all IRQs */ nv_wr32(therm, 0x1100, 0x70000); nvkm_wr32(device, 0x1100, 0x70000); nv_error(therm, "THERM received an IRQ: stat = %x\n", stat); } Loading Loading
drivers/gpu/drm/nouveau/nvkm/subdev/therm/g84.c +26 −18 Original line number Diff line number Diff line Loading @@ -29,10 +29,11 @@ int g84_temp_get(struct nvkm_therm *therm) { struct nvkm_device *device = therm->subdev.device; struct nvkm_fuse *fuse = nvkm_fuse(therm); if (nv_ro32(fuse, 0x1a8) == 1) return nv_rd32(therm, 0x20400); return nvkm_rd32(device, 0x20400); else return -ENODEV; } Loading @@ -40,12 +41,13 @@ g84_temp_get(struct nvkm_therm *therm) void g84_sensor_setup(struct nvkm_therm *therm) { struct nvkm_device *device = therm->subdev.device; struct nvkm_fuse *fuse = nvkm_fuse(therm); /* enable temperature reading for cards with insane defaults */ if (nv_ro32(fuse, 0x1a8) == 1) { nv_mask(therm, 0x20008, 0x80008000, 0x80000000); nv_mask(therm, 0x2000c, 0x80000003, 0x00000000); nvkm_mask(device, 0x20008, 0x80008000, 0x80000000); nvkm_mask(device, 0x2000c, 0x80000003, 0x00000000); mdelay(20); /* wait for the temperature to stabilize */ } } Loading @@ -54,26 +56,27 @@ static void g84_therm_program_alarms(struct nvkm_therm *obj) { struct nvkm_therm_priv *therm = container_of(obj, typeof(*therm), base); struct nvkm_device *device = therm->base.subdev.device; struct nvbios_therm_sensor *sensor = &therm->bios_sensor; unsigned long flags; spin_lock_irqsave(&therm->sensor.alarm_program_lock, flags); /* enable RISING and FALLING IRQs for shutdown, THRS 0, 1, 2 and 4 */ nv_wr32(therm, 0x20000, 0x000003ff); nvkm_wr32(device, 0x20000, 0x000003ff); /* shutdown: The computer should be shutdown when reached */ nv_wr32(therm, 0x20484, sensor->thrs_shutdown.hysteresis); nv_wr32(therm, 0x20480, sensor->thrs_shutdown.temp); nvkm_wr32(device, 0x20484, sensor->thrs_shutdown.hysteresis); nvkm_wr32(device, 0x20480, sensor->thrs_shutdown.temp); /* THRS_1 : fan boost*/ nv_wr32(therm, 0x204c4, sensor->thrs_fan_boost.temp); nvkm_wr32(device, 0x204c4, sensor->thrs_fan_boost.temp); /* THRS_2 : critical */ nv_wr32(therm, 0x204c0, sensor->thrs_critical.temp); nvkm_wr32(device, 0x204c0, sensor->thrs_critical.temp); /* THRS_4 : down clock */ nv_wr32(therm, 0x20414, sensor->thrs_down_clock.temp); nvkm_wr32(device, 0x20414, sensor->thrs_down_clock.temp); spin_unlock_irqrestore(&therm->sensor.alarm_program_lock, flags); nv_debug(therm, Loading @@ -93,19 +96,20 @@ g84_therm_threshold_hyst_emulation(struct nvkm_therm *therm, const struct nvbios_therm_threshold *thrs, enum nvkm_therm_thrs thrs_name) { struct nvkm_device *device = therm->subdev.device; enum nvkm_therm_thrs_direction direction; enum nvkm_therm_thrs_state prev_state, new_state; int temp, cur; prev_state = nvkm_therm_sensor_get_threshold_state(therm, thrs_name); temp = nv_rd32(therm, thrs_reg); temp = nvkm_rd32(device, thrs_reg); /* program the next threshold */ if (temp == thrs->temp) { nv_wr32(therm, thrs_reg, thrs->temp - thrs->hysteresis); nvkm_wr32(device, thrs_reg, thrs->temp - thrs->hysteresis); new_state = NVKM_THERM_THRS_HIGHER; } else { nv_wr32(therm, thrs_reg, thrs->temp); nvkm_wr32(device, thrs_reg, thrs->temp); new_state = NVKM_THERM_THRS_LOWER; } Loading Loading @@ -134,13 +138,14 @@ static void g84_therm_intr(struct nvkm_subdev *subdev) { struct nvkm_therm_priv *therm = (void *)subdev; struct nvkm_device *device = therm->base.subdev.device; struct nvbios_therm_sensor *sensor = &therm->bios_sensor; unsigned long flags; uint32_t intr; spin_lock_irqsave(&therm->sensor.alarm_program_lock, flags); intr = nv_rd32(therm, 0x20100) & 0x3ff; intr = nvkm_rd32(device, 0x20100) & 0x3ff; /* THRS_4: downclock */ if (intr & 0x002) { Loading Loading @@ -178,8 +183,8 @@ g84_therm_intr(struct nvkm_subdev *subdev) nv_error(therm, "unhandled intr 0x%08x\n", intr); /* ACK everything */ nv_wr32(therm, 0x20100, 0xffffffff); nv_wr32(therm, 0x1100, 0x10000); /* PBUS */ nvkm_wr32(device, 0x20100, 0xffffffff); nvkm_wr32(device, 0x1100, 0x10000); /* PBUS */ spin_unlock_irqrestore(&therm->sensor.alarm_program_lock, flags); } Loading Loading @@ -239,12 +244,15 @@ g84_therm_ctor(struct nvkm_object *parent, struct nvkm_object *engine, int g84_therm_fini(struct nvkm_object *object, bool suspend) { struct nvkm_therm *therm = (void *)object; struct nvkm_device *device = therm->subdev.device; /* Disable PTherm IRQs */ nv_wr32(object, 0x20000, 0x00000000); nvkm_wr32(device, 0x20000, 0x00000000); /* ACK all PTherm IRQs */ nv_wr32(object, 0x20100, 0xffffffff); nv_wr32(object, 0x1100, 0x10000); /* PBUS */ nvkm_wr32(device, 0x20100, 0xffffffff); nvkm_wr32(device, 0x1100, 0x10000); /* PBUS */ return _nvkm_therm_fini(object, suspend); } Loading
drivers/gpu/drm/nouveau/nvkm/subdev/therm/gf110.c +24 −18 Original line number Diff line number Diff line Loading @@ -26,7 +26,8 @@ static int pwm_info(struct nvkm_therm *therm, int line) { u32 gpio = nv_rd32(therm, 0x00d610 + (line * 0x04)); struct nvkm_device *device = therm->subdev.device; u32 gpio = nvkm_rd32(device, 0x00d610 + (line * 0x04)); switch (gpio & 0x000000c0) { case 0x00000000: /* normal mode, possibly pwm forced off by us */ Loading @@ -50,12 +51,13 @@ pwm_info(struct nvkm_therm *therm, int line) static int gf110_fan_pwm_ctrl(struct nvkm_therm *therm, int line, bool enable) { struct nvkm_device *device = therm->subdev.device; u32 data = enable ? 0x00000040 : 0x00000000; int indx = pwm_info(therm, line); if (indx < 0) return indx; else if (indx < 2) nv_mask(therm, 0x00d610 + (line * 0x04), 0x000000c0, data); nvkm_mask(device, 0x00d610 + (line * 0x04), 0x000000c0, data); /* nothing to do for indx == 2, it seems hardwired to PTHERM */ return 0; } Loading @@ -63,18 +65,19 @@ gf110_fan_pwm_ctrl(struct nvkm_therm *therm, int line, bool enable) static int gf110_fan_pwm_get(struct nvkm_therm *therm, int line, u32 *divs, u32 *duty) { struct nvkm_device *device = therm->subdev.device; int indx = pwm_info(therm, line); if (indx < 0) return indx; else if (indx < 2) { if (nv_rd32(therm, 0x00d610 + (line * 0x04)) & 0x00000040) { *divs = nv_rd32(therm, 0x00e114 + (indx * 8)); *duty = nv_rd32(therm, 0x00e118 + (indx * 8)); if (nvkm_rd32(device, 0x00d610 + (line * 0x04)) & 0x00000040) { *divs = nvkm_rd32(device, 0x00e114 + (indx * 8)); *duty = nvkm_rd32(device, 0x00e118 + (indx * 8)); return 0; } } else if (indx == 2) { *divs = nv_rd32(therm, 0x0200d8) & 0x1fff; *duty = nv_rd32(therm, 0x0200dc) & 0x1fff; *divs = nvkm_rd32(device, 0x0200d8) & 0x1fff; *duty = nvkm_rd32(device, 0x0200dc) & 0x1fff; return 0; } Loading @@ -84,15 +87,16 @@ gf110_fan_pwm_get(struct nvkm_therm *therm, int line, u32 *divs, u32 *duty) static int gf110_fan_pwm_set(struct nvkm_therm *therm, int line, u32 divs, u32 duty) { struct nvkm_device *device = therm->subdev.device; int indx = pwm_info(therm, line); if (indx < 0) return indx; else if (indx < 2) { nv_wr32(therm, 0x00e114 + (indx * 8), divs); nv_wr32(therm, 0x00e118 + (indx * 8), duty | 0x80000000); nvkm_wr32(device, 0x00e114 + (indx * 8), divs); nvkm_wr32(device, 0x00e118 + (indx * 8), duty | 0x80000000); } else if (indx == 2) { nv_mask(therm, 0x0200d8, 0x1fff, divs); /* keep the high bits */ nv_wr32(therm, 0x0200dc, duty | 0x40000000); nvkm_mask(device, 0x0200d8, 0x1fff, divs); /* keep the high bits */ nvkm_wr32(device, 0x0200dc, duty | 0x40000000); } return 0; } Loading @@ -100,19 +104,21 @@ gf110_fan_pwm_set(struct nvkm_therm *therm, int line, u32 divs, u32 duty) static int gf110_fan_pwm_clock(struct nvkm_therm *therm, int line) { struct nvkm_device *device = therm->subdev.device; int indx = pwm_info(therm, line); if (indx < 0) return 0; else if (indx < 2) return (nv_device(therm)->crystal * 1000) / 20; return (device->crystal * 1000) / 20; else return nv_device(therm)->crystal * 1000 / 10; return device->crystal * 1000 / 10; } int gf110_therm_init(struct nvkm_object *object) { struct nvkm_therm_priv *therm = (void *)object; struct nvkm_device *device = therm->base.subdev.device; int ret; ret = nvkm_therm_init(&therm->base); Loading @@ -120,13 +126,13 @@ gf110_therm_init(struct nvkm_object *object) return ret; /* enable fan tach, count revolutions per-second */ nv_mask(therm, 0x00e720, 0x00000003, 0x00000002); nvkm_mask(device, 0x00e720, 0x00000003, 0x00000002); if (therm->fan->tach.func != DCB_GPIO_UNUSED) { nv_mask(therm, 0x00d79c, 0x000000ff, therm->fan->tach.line); nv_wr32(therm, 0x00e724, nv_device(therm)->crystal * 1000); nv_mask(therm, 0x00e720, 0x00000001, 0x00000001); nvkm_mask(device, 0x00d79c, 0x000000ff, therm->fan->tach.line); nvkm_wr32(device, 0x00e724, nv_device(therm)->crystal * 1000); nvkm_mask(device, 0x00e720, 0x00000001, 0x00000001); } nv_mask(therm, 0x00e720, 0x00000002, 0x00000000); nvkm_mask(device, 0x00e720, 0x00000002, 0x00000000); return 0; } Loading
drivers/gpu/drm/nouveau/nvkm/subdev/therm/gm107.c +7 −5 Original line number Diff line number Diff line Loading @@ -33,23 +33,25 @@ gm107_fan_pwm_ctrl(struct nvkm_therm *therm, int line, bool enable) static int gm107_fan_pwm_get(struct nvkm_therm *therm, int line, u32 *divs, u32 *duty) { *divs = nv_rd32(therm, 0x10eb20) & 0x1fff; *duty = nv_rd32(therm, 0x10eb24) & 0x1fff; struct nvkm_device *device = therm->subdev.device; *divs = nvkm_rd32(device, 0x10eb20) & 0x1fff; *duty = nvkm_rd32(device, 0x10eb24) & 0x1fff; return 0; } static int gm107_fan_pwm_set(struct nvkm_therm *therm, int line, u32 divs, u32 duty) { nv_mask(therm, 0x10eb10, 0x1fff, divs); /* keep the high bits */ nv_wr32(therm, 0x10eb14, duty | 0x80000000); struct nvkm_device *device = therm->subdev.device; nvkm_mask(device, 0x10eb10, 0x1fff, divs); /* keep the high bits */ nvkm_wr32(device, 0x10eb14, duty | 0x80000000); return 0; } static int gm107_fan_pwm_clock(struct nvkm_therm *therm, int line) { return nv_device(therm)->crystal * 1000; return therm->subdev.device->crystal * 1000; } static int Loading
drivers/gpu/drm/nouveau/nvkm/subdev/therm/gt215.c +9 −7 Original line number Diff line number Diff line Loading @@ -28,8 +28,9 @@ int gt215_therm_fan_sense(struct nvkm_therm *therm) { u32 tach = nv_rd32(therm, 0x00e728) & 0x0000ffff; u32 ctrl = nv_rd32(therm, 0x00e720); struct nvkm_device *device = therm->subdev.device; u32 tach = nvkm_rd32(device, 0x00e728) & 0x0000ffff; u32 ctrl = nvkm_rd32(device, 0x00e720); if (ctrl & 0x00000001) return tach * 60 / 2; return -ENODEV; Loading @@ -39,6 +40,7 @@ static int gt215_therm_init(struct nvkm_object *object) { struct nvkm_therm_priv *therm = (void *)object; struct nvkm_device *device = therm->base.subdev.device; struct dcb_gpio_func *tach = &therm->fan->tach; int ret; Loading @@ -49,13 +51,13 @@ gt215_therm_init(struct nvkm_object *object) g84_sensor_setup(&therm->base); /* enable fan tach, count revolutions per-second */ nv_mask(therm, 0x00e720, 0x00000003, 0x00000002); nvkm_mask(device, 0x00e720, 0x00000003, 0x00000002); if (tach->func != DCB_GPIO_UNUSED) { nv_wr32(therm, 0x00e724, nv_device(therm)->crystal * 1000); nv_mask(therm, 0x00e720, 0x001f0000, tach->line << 16); nv_mask(therm, 0x00e720, 0x00000001, 0x00000001); nvkm_wr32(device, 0x00e724, nv_device(therm)->crystal * 1000); nvkm_mask(device, 0x00e720, 0x001f0000, tach->line << 16); nvkm_mask(device, 0x00e720, 0x00000001, 0x00000001); } nv_mask(therm, 0x00e720, 0x00000002, 0x00000000); nvkm_mask(device, 0x00e720, 0x00000002, 0x00000000); return 0; } Loading
drivers/gpu/drm/nouveau/nvkm/subdev/therm/nv40.c +25 −19 Original line number Diff line number Diff line Loading @@ -55,18 +55,19 @@ nv40_sensor_style(struct nvkm_therm *therm) static int nv40_sensor_setup(struct nvkm_therm *therm) { struct nvkm_device *device = therm->subdev.device; enum nv40_sensor_style style = nv40_sensor_style(therm); /* enable ADC readout and disable the ALARM threshold */ if (style == NEW_STYLE) { nv_mask(therm, 0x15b8, 0x80000000, 0); nv_wr32(therm, 0x15b0, 0x80003fff); nvkm_mask(device, 0x15b8, 0x80000000, 0); nvkm_wr32(device, 0x15b0, 0x80003fff); mdelay(20); /* wait for the temperature to stabilize */ return nv_rd32(therm, 0x15b4) & 0x3fff; return nvkm_rd32(device, 0x15b4) & 0x3fff; } else if (style == OLD_STYLE) { nv_wr32(therm, 0x15b0, 0xff); nvkm_wr32(device, 0x15b0, 0xff); mdelay(20); /* wait for the temperature to stabilize */ return nv_rd32(therm, 0x15b4) & 0xff; return nvkm_rd32(device, 0x15b4) & 0xff; } else return -ENODEV; } Loading @@ -75,16 +76,17 @@ static int nv40_temp_get(struct nvkm_therm *obj) { struct nvkm_therm_priv *therm = container_of(obj, typeof(*therm), base); struct nvkm_device *device = therm->base.subdev.device; struct nvbios_therm_sensor *sensor = &therm->bios_sensor; enum nv40_sensor_style style = nv40_sensor_style(&therm->base); int core_temp; if (style == NEW_STYLE) { nv_wr32(therm, 0x15b0, 0x80003fff); core_temp = nv_rd32(therm, 0x15b4) & 0x3fff; nvkm_wr32(device, 0x15b0, 0x80003fff); core_temp = nvkm_rd32(device, 0x15b4) & 0x3fff; } else if (style == OLD_STYLE) { nv_wr32(therm, 0x15b0, 0xff); core_temp = nv_rd32(therm, 0x15b4) & 0xff; nvkm_wr32(device, 0x15b0, 0xff); core_temp = nvkm_rd32(device, 0x15b4) & 0xff; } else return -ENODEV; Loading @@ -107,9 +109,10 @@ nv40_temp_get(struct nvkm_therm *obj) static int nv40_fan_pwm_ctrl(struct nvkm_therm *therm, int line, bool enable) { struct nvkm_device *device = therm->subdev.device; u32 mask = enable ? 0x80000000 : 0x0000000; if (line == 2) nv_mask(therm, 0x0010f0, 0x80000000, mask); else if (line == 9) nv_mask(therm, 0x0015f4, 0x80000000, mask); if (line == 2) nvkm_mask(device, 0x0010f0, 0x80000000, mask); else if (line == 9) nvkm_mask(device, 0x0015f4, 0x80000000, mask); else { nv_error(therm, "unknown pwm ctrl for gpio %d\n", line); return -ENODEV; Loading @@ -120,8 +123,9 @@ nv40_fan_pwm_ctrl(struct nvkm_therm *therm, int line, bool enable) static int nv40_fan_pwm_get(struct nvkm_therm *therm, int line, u32 *divs, u32 *duty) { struct nvkm_device *device = therm->subdev.device; if (line == 2) { u32 reg = nv_rd32(therm, 0x0010f0); u32 reg = nvkm_rd32(device, 0x0010f0); if (reg & 0x80000000) { *duty = (reg & 0x7fff0000) >> 16; *divs = (reg & 0x00007fff); Loading @@ -129,9 +133,9 @@ nv40_fan_pwm_get(struct nvkm_therm *therm, int line, u32 *divs, u32 *duty) } } else if (line == 9) { u32 reg = nv_rd32(therm, 0x0015f4); u32 reg = nvkm_rd32(device, 0x0015f4); if (reg & 0x80000000) { *divs = nv_rd32(therm, 0x0015f8); *divs = nvkm_rd32(device, 0x0015f8); *duty = (reg & 0x7fffffff); return 0; } Loading @@ -146,12 +150,13 @@ nv40_fan_pwm_get(struct nvkm_therm *therm, int line, u32 *divs, u32 *duty) static int nv40_fan_pwm_set(struct nvkm_therm *therm, int line, u32 divs, u32 duty) { struct nvkm_device *device = therm->subdev.device; if (line == 2) { nv_mask(therm, 0x0010f0, 0x7fff7fff, (duty << 16) | divs); nvkm_mask(device, 0x0010f0, 0x7fff7fff, (duty << 16) | divs); } else if (line == 9) { nv_wr32(therm, 0x0015f8, divs); nv_mask(therm, 0x0015f4, 0x7fffffff, duty); nvkm_wr32(device, 0x0015f8, divs); nvkm_mask(device, 0x0015f4, 0x7fffffff, duty); } else { nv_error(therm, "unknown pwm ctrl for gpio %d\n", line); return -ENODEV; Loading @@ -164,12 +169,13 @@ void nv40_therm_intr(struct nvkm_subdev *subdev) { struct nvkm_therm *therm = nvkm_therm(subdev); uint32_t stat = nv_rd32(therm, 0x1100); struct nvkm_device *device = therm->subdev.device; uint32_t stat = nvkm_rd32(device, 0x1100); /* traitement */ /* ack all IRQs */ nv_wr32(therm, 0x1100, 0x70000); nvkm_wr32(device, 0x1100, 0x70000); nv_error(therm, "THERM received an IRQ: stat = %x\n", stat); } Loading