On Fri, Jan 26, 2018 at 4:35 AM, Lyude Paul <lyude@xxxxxxxxxx> wrote: > This adds support for enabling automatic clockgating on nvidia GPUs for > Kepler1. While this is not technically a clockgating level, it does > enable clockgating using the clockgating values initially set by the > vbios (which should be safe to use). > > This introduces two therm helpers for controlling basic clockgating: > nvkm_therm_clkgate_enable() - enables clockgating through > CG_CTRL, done after initializing the GPU fully > nvkm_therm_clkgate_fini() - prepares clockgating for suspend or > driver unload > > As well, we add the nouveau kernel config parameter NvPmEnableGating, > which can be toggled on or off in order to enable/disable clockgating. > Since we've only had limited testing on this thus far, we disable this > by default. > > A lot of this code was originally going to be based off of fermi; > however it turns out that while Fermi's the first line of GPUs that > introduced this kind of power saving, Fermi requires more fine tuned > control of the CG_CTRL registers from the driver while reclocking that > we don't entirely understand yet. > > For the simple parts we will be sharing with Fermi for certain however, > we at least add those into a new subdev/therm/gf100.h header. > > Signed-off-by: Lyude Paul <lyude@xxxxxxxxxx> > --- > .../gpu/drm/nouveau/include/nvkm/subdev/therm.h | 5 + > drivers/gpu/drm/nouveau/nvkm/engine/device/base.c | 17 +-- > drivers/gpu/drm/nouveau/nvkm/subdev/therm/Kbuild | 1 + > drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c | 60 +++++++-- > drivers/gpu/drm/nouveau/nvkm/subdev/therm/gf100.h | 35 ++++++ > drivers/gpu/drm/nouveau/nvkm/subdev/therm/gf119.c | 8 +- > drivers/gpu/drm/nouveau/nvkm/subdev/therm/gk104.c | 135 +++++++++++++++++++++ > drivers/gpu/drm/nouveau/nvkm/subdev/therm/gk104.h | 48 ++++++++ > drivers/gpu/drm/nouveau/nvkm/subdev/therm/priv.h | 15 ++- > 9 files changed, 303 insertions(+), 21 deletions(-) > create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/therm/gf100.h > create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/therm/gk104.c > create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/therm/gk104.h > > diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/therm.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/therm.h > index b1ac47eb786e..240b19bb4667 100644 > --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/therm.h > +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/therm.h > @@ -85,17 +85,22 @@ struct nvkm_therm { > > int (*attr_get)(struct nvkm_therm *, enum nvkm_therm_attr_type); > int (*attr_set)(struct nvkm_therm *, enum nvkm_therm_attr_type, int); > + > + bool clkgating_enabled; > }; > > int nvkm_therm_temp_get(struct nvkm_therm *); > int nvkm_therm_fan_sense(struct nvkm_therm *); > int nvkm_therm_cstate(struct nvkm_therm *, int, int); > +void nvkm_therm_clkgate_enable(struct nvkm_therm *); > +void nvkm_therm_clkgate_fini(struct nvkm_therm *, bool); > > int nv40_therm_new(struct nvkm_device *, int, struct nvkm_therm **); > int nv50_therm_new(struct nvkm_device *, int, struct nvkm_therm **); > int g84_therm_new(struct nvkm_device *, int, struct nvkm_therm **); > int gt215_therm_new(struct nvkm_device *, int, struct nvkm_therm **); > int gf119_therm_new(struct nvkm_device *, int, struct nvkm_therm **); > +int gk104_therm_new(struct nvkm_device *, int, struct nvkm_therm **); > int gm107_therm_new(struct nvkm_device *, int, struct nvkm_therm **); > int gm200_therm_new(struct nvkm_device *, int, struct nvkm_therm **); > int gp100_therm_new(struct nvkm_device *, int, struct nvkm_therm **); > diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c > index 08e77cd55e6e..74bd09b1c893 100644 > --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c > +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c > @@ -28,6 +28,7 @@ > #include <core/option.h> > > #include <subdev/bios.h> > +#include <subdev/therm.h> > > static DEFINE_MUTEX(nv_devices_mutex); > static LIST_HEAD(nv_devices); > @@ -1682,7 +1683,7 @@ nve4_chipset = { > .mxm = nv50_mxm_new, > .pci = gk104_pci_new, > .pmu = gk104_pmu_new, > - .therm = gf119_therm_new, > + .therm = gk104_therm_new, > .timer = nv41_timer_new, > .top = gk104_top_new, > .volt = gk104_volt_new, > @@ -1721,7 +1722,7 @@ nve6_chipset = { > .mxm = nv50_mxm_new, > .pci = gk104_pci_new, > .pmu = gk104_pmu_new, > - .therm = gf119_therm_new, > + .therm = gk104_therm_new, > .timer = nv41_timer_new, > .top = gk104_top_new, > .volt = gk104_volt_new, > @@ -1760,7 +1761,7 @@ nve7_chipset = { > .mxm = nv50_mxm_new, > .pci = gk104_pci_new, > .pmu = gk104_pmu_new, > - .therm = gf119_therm_new, > + .therm = gk104_therm_new, > .timer = nv41_timer_new, > .top = gk104_top_new, > .volt = gk104_volt_new, > @@ -1824,7 +1825,7 @@ nvf0_chipset = { > .mxm = nv50_mxm_new, > .pci = gk104_pci_new, > .pmu = gk110_pmu_new, > - .therm = gf119_therm_new, > + .therm = gk104_therm_new, > .timer = nv41_timer_new, > .top = gk104_top_new, > .volt = gk104_volt_new, > @@ -1862,7 +1863,7 @@ nvf1_chipset = { > .mxm = nv50_mxm_new, > .pci = gk104_pci_new, > .pmu = gk110_pmu_new, > - .therm = gf119_therm_new, > + .therm = gk104_therm_new, > .timer = nv41_timer_new, > .top = gk104_top_new, > .volt = gk104_volt_new, > @@ -1900,7 +1901,7 @@ nv106_chipset = { > .mxm = nv50_mxm_new, > .pci = gk104_pci_new, > .pmu = gk208_pmu_new, > - .therm = gf119_therm_new, > + .therm = gk104_therm_new, > .timer = nv41_timer_new, > .top = gk104_top_new, > .volt = gk104_volt_new, > @@ -1938,7 +1939,7 @@ nv108_chipset = { > .mxm = nv50_mxm_new, > .pci = gk104_pci_new, > .pmu = gk208_pmu_new, > - .therm = gf119_therm_new, > + .therm = gk104_therm_new, > .timer = nv41_timer_new, > .top = gk104_top_new, > .volt = gk104_volt_new, > @@ -2508,6 +2509,7 @@ nvkm_device_fini(struct nvkm_device *device, bool suspend) > } > } > > + nvkm_therm_clkgate_fini(device->therm, suspend); > > if (device->func->fini) > device->func->fini(device, suspend); > @@ -2597,6 +2599,7 @@ nvkm_device_init(struct nvkm_device *device) > } > > nvkm_acpi_init(device); > + nvkm_therm_clkgate_enable(device->therm); > > time = ktime_to_us(ktime_get()) - time; > nvdev_trace(device, "init completed in %lldus\n", time); > diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/Kbuild > index 7ba56b12badd..4bac4772d8ed 100644 > --- a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/Kbuild > +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/Kbuild > @@ -10,6 +10,7 @@ nvkm-y += nvkm/subdev/therm/nv50.o > nvkm-y += nvkm/subdev/therm/g84.o > nvkm-y += nvkm/subdev/therm/gt215.o > nvkm-y += nvkm/subdev/therm/gf119.o > +nvkm-y += nvkm/subdev/therm/gk104.o > nvkm-y += nvkm/subdev/therm/gm107.o > nvkm-y += nvkm/subdev/therm/gm200.o > nvkm-y += nvkm/subdev/therm/gp100.o > diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c > index f27fc6d0d4c6..e4c96e46db8f 100644 > --- a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c > +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c > @@ -21,6 +21,7 @@ > * > * Authors: Martin Peres > */ > +#include <nvkm/core/option.h> > #include "priv.h" > > int > @@ -297,6 +298,38 @@ nvkm_therm_attr_set(struct nvkm_therm *therm, > return -EINVAL; > } > > +void > +nvkm_therm_clkgate_enable(struct nvkm_therm *therm) > +{ > + if (!therm->func->clkgate_enable || !therm->clkgating_enabled) > + return; > + > + nvkm_debug(&therm->subdev, > + "Enabling clockgating\n"); > + therm->func->clkgate_enable(therm); > +} > + > +void > +nvkm_therm_clkgate_fini(struct nvkm_therm *therm, bool suspend) > +{ > + if (!therm->func->clkgate_fini || !therm->clkgating_enabled) > + return; > + > + nvkm_debug(&therm->subdev, > + "Preparing clockgating for %s\n", > + suspend ? "suspend" : "fini"); > + therm->func->clkgate_fini(therm, suspend); > +} > + > +static void > +nvkm_therm_clkgate_oneinit(struct nvkm_therm *therm) > +{ > + if (!therm->func->clkgate_enable || !therm->clkgating_enabled) > + return; > + > + nvkm_info(&therm->subdev, "Clockgating enabled\n"); > +} > + > static void > nvkm_therm_intr(struct nvkm_subdev *subdev) > { > @@ -333,6 +366,7 @@ nvkm_therm_oneinit(struct nvkm_subdev *subdev) > nvkm_therm_fan_ctor(therm); > nvkm_therm_fan_mode(therm, NVKM_THERM_CTRL_AUTO); > nvkm_therm_sensor_preinit(therm); > + nvkm_therm_clkgate_oneinit(therm); > return 0; > } > > @@ -374,15 +408,10 @@ nvkm_therm = { > .intr = nvkm_therm_intr, > }; > > -int > -nvkm_therm_new_(const struct nvkm_therm_func *func, struct nvkm_device *device, > - int index, struct nvkm_therm **ptherm) > +void > +nvkm_therm_ctor(struct nvkm_therm *therm, struct nvkm_device *device, > + int index, const struct nvkm_therm_func *func) > { > - struct nvkm_therm *therm; > - > - if (!(therm = *ptherm = kzalloc(sizeof(*therm), GFP_KERNEL))) > - return -ENOMEM; > - > nvkm_subdev_ctor(&nvkm_therm, device, index, &therm->subdev); > therm->func = func; > > @@ -395,5 +424,20 @@ nvkm_therm_new_(const struct nvkm_therm_func *func, struct nvkm_device *device, > therm->attr_get = nvkm_therm_attr_get; > therm->attr_set = nvkm_therm_attr_set; > therm->mode = therm->suspend = -1; /* undefined */ > + > + therm->clkgating_enabled = nvkm_boolopt(device->cfgopt, > + "NvPmEnableGating", false); > +} > + > +int > +nvkm_therm_new_(const struct nvkm_therm_func *func, struct nvkm_device *device, > + int index, struct nvkm_therm **ptherm) > +{ > + struct nvkm_therm *therm; > + > + if (!(therm = *ptherm = kzalloc(sizeof(*therm), GFP_KERNEL))) > + return -ENOMEM; > + > + nvkm_therm_ctor(therm, device, index, func); > return 0; > } > diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gf100.h b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gf100.h > new file mode 100644 > index 000000000000..cfb25af77c60 > --- /dev/null > +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gf100.h > @@ -0,0 +1,35 @@ > +/* > + * Copyright 2018 Red Hat Inc. > + * > + * Permission is hereby granted, free of charge, to any person obtaining a > + * copy of this software and associated documentation files (the "Software"), > + * to deal in the Software without restriction, including without limitation > + * the rights to use, copy, modify, merge, publish, distribute, sublicense, > + * and/or sell copies of the Software, and to permit persons to whom the > + * Software is furnished to do so, subject to the following conditions: > + * > + * The above copyright notice and this permission notice shall be included in > + * all copies or substantial portions of the Software. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR > + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, > + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR > + * OTHER DEALINGS IN THE SOFTWARE. > + * > + * Authors: Lyude Paul > + */ > + > +#ifndef __GF100_THERM_H__ > +#define __GF100_THERM_H__ > + > +#include <core/device.h> > + > +struct gf100_idle_filter { > + u32 fecs; > + u32 hubmmu; > +}; > + > +#endif > diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gf119.c b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gf119.c > index 06dcfd6ee966..0981b02790e2 100644 > --- a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gf119.c > +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gf119.c > @@ -49,7 +49,7 @@ pwm_info(struct nvkm_therm *therm, int line) > return -ENODEV; > } > > -static int > +int > gf119_fan_pwm_ctrl(struct nvkm_therm *therm, int line, bool enable) > { > struct nvkm_device *device = therm->subdev.device; > @@ -63,7 +63,7 @@ gf119_fan_pwm_ctrl(struct nvkm_therm *therm, int line, bool enable) > return 0; > } > > -static int > +int > gf119_fan_pwm_get(struct nvkm_therm *therm, int line, u32 *divs, u32 *duty) > { > struct nvkm_device *device = therm->subdev.device; > @@ -85,7 +85,7 @@ gf119_fan_pwm_get(struct nvkm_therm *therm, int line, u32 *divs, u32 *duty) > return -EINVAL; > } > > -static int > +int > gf119_fan_pwm_set(struct nvkm_therm *therm, int line, u32 divs, u32 duty) > { > struct nvkm_device *device = therm->subdev.device; > @@ -102,7 +102,7 @@ gf119_fan_pwm_set(struct nvkm_therm *therm, int line, u32 divs, u32 duty) > return 0; > } > > -static int > +int > gf119_fan_pwm_clock(struct nvkm_therm *therm, int line) > { > struct nvkm_device *device = therm->subdev.device; > diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gk104.c b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gk104.c > new file mode 100644 > index 000000000000..79806a757893 > --- /dev/null > +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gk104.c > @@ -0,0 +1,135 @@ > +/* > + * Copyright 2018 Red Hat Inc. > + * > + * Permission is hereby granted, free of charge, to any person obtaining a > + * copy of this software and associated documentation files (the "Software"), > + * to deal in the Software without restriction, including without limitation > + * the rights to use, copy, modify, merge, publish, distribute, sublicense, > + * and/or sell copies of the Software, and to permit persons to whom the > + * Software is furnished to do so, subject to the following conditions: > + * > + * The above copyright notice and this permission notice shall be included in > + * all copies or substantial portions of the Software. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR > + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, > + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR > + * OTHER DEALINGS IN THE SOFTWARE. > + * > + * Authors: Lyude Paul > + */ > +#include <core/device.h> > + > +#include "priv.h" > +#include "gk104.h" > + > +void > +gk104_clkgate_enable(struct nvkm_therm *base) > +{ > + struct gk104_therm *therm = gk104_therm(base); > + struct nvkm_device *dev = therm->base.subdev.device; > + const struct gk104_clkgate_engine_info *order = therm->clkgate_order; > + int i; > + > + /* Program ENG_MANT, ENG_FILTER */ > + for (i = 0; order[i].engine != NVKM_SUBDEV_NR; i++) { > + if (!nvkm_device_subdev(dev, order[i].engine)) > + continue; > + > + nvkm_mask(dev, 0x20200 + order[i].offset, 0xff00, 0x4500); > + } > + > + /* magic */ > + nvkm_wr32(dev, 0x020288, therm->idle_filter->fecs); > + nvkm_wr32(dev, 0x02028c, therm->idle_filter->hubmmu); > + > + /* Enable clockgating (ENG_CLK = RUN->AUTO) */ > + for (i = 0; order[i].engine != NVKM_SUBDEV_NR; i++) { > + if (!nvkm_device_subdev(dev, order[i].engine)) > + continue; > + > + nvkm_mask(dev, 0x20200 + order[i].offset, 0x00ff, 0x0045); > + } > +} > + > +void > +gk104_clkgate_fini(struct nvkm_therm *base, bool suspend) > +{ > + struct gk104_therm *therm = gk104_therm(base); > + struct nvkm_device *dev = therm->base.subdev.device; > + const struct gk104_clkgate_engine_info *order = therm->clkgate_order; > + int i; > + > + /* ENG_CLK = AUTO->RUN, ENG_PWR = RUN->AUTO */ > + for (i = 0; order[i].engine != NVKM_SUBDEV_NR; i++) { > + if (!nvkm_device_subdev(dev, order[i].engine)) > + continue; > + > + nvkm_mask(dev, 0x20200 + order[i].offset, 0xff, 0x54); > + } shouldn't that be 0x44? Or does nvidia actually set it to that value? That would be a little odd, because it sets the mode for ENG_PWR from ON to AUTO and I am sure GPUs boot usually with 0x44. > +} > + > +const struct gk104_clkgate_engine_info gk104_clkgate_engine_info[] = { > + { NVKM_ENGINE_GR, 0x00 }, > + { NVKM_ENGINE_MSPDEC, 0x04 }, > + { NVKM_ENGINE_MSPPP, 0x08 }, > + { NVKM_ENGINE_MSVLD, 0x0c }, > + { NVKM_ENGINE_CE0, 0x10 }, > + { NVKM_ENGINE_CE1, 0x14 }, > + { NVKM_ENGINE_MSENC, 0x18 }, > + { NVKM_ENGINE_CE2, 0x1c }, > + { NVKM_SUBDEV_NR, 0 }, > +}; > + > +const struct gf100_idle_filter gk104_idle_filter = { > + .fecs = 0x00001000, > + .hubmmu = 0x00001000, > +}; > + > +static const struct nvkm_therm_func > +gk104_therm_func = { > + .init = gf119_therm_init, > + .fini = g84_therm_fini, > + .pwm_ctrl = gf119_fan_pwm_ctrl, > + .pwm_get = gf119_fan_pwm_get, > + .pwm_set = gf119_fan_pwm_set, > + .pwm_clock = gf119_fan_pwm_clock, > + .temp_get = g84_temp_get, > + .fan_sense = gt215_therm_fan_sense, > + .program_alarms = nvkm_therm_program_alarms_polling, > + .clkgate_enable = gk104_clkgate_enable, > + .clkgate_fini = gk104_clkgate_fini, > +}; > + > +static int > +gk104_therm_new_(const struct nvkm_therm_func *func, > + struct nvkm_device *device, > + int index, > + const struct gk104_clkgate_engine_info *clkgate_order, > + const struct gf100_idle_filter *idle_filter, > + struct nvkm_therm **ptherm) > +{ > + struct gk104_therm *therm = kzalloc(sizeof(*therm), GFP_KERNEL); > + > + if (!therm) > + return -ENOMEM; > + > + nvkm_therm_ctor(&therm->base, device, index, func); > + *ptherm = &therm->base; > + therm->clkgate_order = clkgate_order; > + therm->idle_filter = idle_filter; > + > + return 0; > +} > + > +int > +gk104_therm_new(struct nvkm_device *device, > + int index, struct nvkm_therm **ptherm) > +{ > + return gk104_therm_new_(&gk104_therm_func, device, index, > + gk104_clkgate_engine_info, &gk104_idle_filter, > + ptherm); > +} > diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gk104.h b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gk104.h > new file mode 100644 > index 000000000000..293e7743b19b > --- /dev/null > +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gk104.h > @@ -0,0 +1,48 @@ > +/* > + * Copyright 2018 Red Hat Inc. > + * > + * Permission is hereby granted, free of charge, to any person obtaining a > + * copy of this software and associated documentation files (the "Software"), > + * to deal in the Software without restriction, including without limitation > + * the rights to use, copy, modify, merge, publish, distribute, sublicense, > + * and/or sell copies of the Software, and to permit persons to whom the > + * Software is furnished to do so, subject to the following conditions: > + * > + * The above copyright notice and this permission notice shall be included in > + * all copies or substantial portions of the Software. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR > + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, > + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR > + * OTHER DEALINGS IN THE SOFTWARE. > + * > + * Authors: Lyude Paul > + */ > + > +#ifndef __GK104_THERM_H__ > +#define __GK104_THERM_H__ > +#define gk104_therm(p) (container_of((p), struct gk104_therm, base)) > + > +#include <subdev/therm.h> > +#include "priv.h" > +#include "gf100.h" > + > +struct gk104_clkgate_engine_info { > + enum nvkm_devidx engine; > + u8 offset; > +}; > + > +struct gk104_therm { > + struct nvkm_therm base; > + > + const struct gk104_clkgate_engine_info *clkgate_order; > + const struct gf100_idle_filter *idle_filter; > +}; > + > +extern const struct gk104_clkgate_engine_info gk104_clkgate_engine_info[]; > +extern const struct gf100_idle_filter gk104_idle_filter; > + > +#endif > diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/priv.h > index 1f46e371d7c4..f30202dd88e7 100644 > --- a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/priv.h > +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/priv.h > @@ -32,6 +32,8 @@ > > int nvkm_therm_new_(const struct nvkm_therm_func *, struct nvkm_device *, > int index, struct nvkm_therm **); > +void nvkm_therm_ctor(struct nvkm_therm *therm, struct nvkm_device *device, > + int index, const struct nvkm_therm_func *func); > > struct nvkm_fan { > struct nvkm_therm *parent; > @@ -66,8 +68,6 @@ int nvkm_therm_fan_set(struct nvkm_therm *, bool now, int percent); > int nvkm_therm_fan_user_get(struct nvkm_therm *); > int nvkm_therm_fan_user_set(struct nvkm_therm *, int percent); > > -int nvkm_therm_preinit(struct nvkm_therm *); > - > int nvkm_therm_sensor_init(struct nvkm_therm *); > int nvkm_therm_sensor_fini(struct nvkm_therm *, bool suspend); > void nvkm_therm_sensor_preinit(struct nvkm_therm *); > @@ -96,6 +96,9 @@ struct nvkm_therm_func { > int (*fan_sense)(struct nvkm_therm *); > > void (*program_alarms)(struct nvkm_therm *); > + > + void (*clkgate_enable)(struct nvkm_therm *); > + void (*clkgate_fini)(struct nvkm_therm *, bool); > }; > > void nv40_therm_intr(struct nvkm_therm *); > @@ -112,8 +115,16 @@ void g84_therm_fini(struct nvkm_therm *); > int gt215_therm_fan_sense(struct nvkm_therm *); > > void g84_therm_init(struct nvkm_therm *); > + > +int gf119_fan_pwm_ctrl(struct nvkm_therm *, int, bool); > +int gf119_fan_pwm_get(struct nvkm_therm *, int, u32 *, u32 *); > +int gf119_fan_pwm_set(struct nvkm_therm *, int, u32, u32); > +int gf119_fan_pwm_clock(struct nvkm_therm *, int); > void gf119_therm_init(struct nvkm_therm *); > > +void gk104_clkgate_enable(struct nvkm_therm *); > +void gk104_clkgate_fini(struct nvkm_therm *, bool); > + > int nvkm_fanpwm_create(struct nvkm_therm *, struct dcb_gpio_func *); > int nvkm_fantog_create(struct nvkm_therm *, struct dcb_gpio_func *); > int nvkm_fannil_create(struct nvkm_therm *); > -- > 2.14.3 > > _______________________________________________ > Nouveau mailing list > Nouveau@xxxxxxxxxxxxxxxxxxxxx > https://lists.freedesktop.org/mailman/listinfo/nouveau _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/dri-devel