diff options
Diffstat (limited to 'drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c')
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c | 70 |
1 files changed, 62 insertions, 8 deletions
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c index f27fc6d0d4c6..bf62303571b3 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; } @@ -357,6 +391,16 @@ nvkm_therm_init(struct nvkm_subdev *subdev) return 0; } +void +nvkm_therm_clkgate_init(struct nvkm_therm *therm, + const struct nvkm_therm_clkgate_pack *p) +{ + if (!therm->func->clkgate_init || !therm->clkgating_enabled) + return; + + therm->func->clkgate_init(therm, p); +} + static void * nvkm_therm_dtor(struct nvkm_subdev *subdev) { @@ -374,15 +418,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 +434,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; } |