diff options
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_sysfs.c')
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_sysfs.c | 88 |
1 files changed, 61 insertions, 27 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_sysfs.c b/drivers/gpu/drm/nouveau/nouveau_sysfs.c index 75dda2b07176..3c6962d15b26 100644 --- a/drivers/gpu/drm/nouveau/nouveau_sysfs.c +++ b/drivers/gpu/drm/nouveau/nouveau_sysfs.c @@ -22,10 +22,15 @@ * Authors: Ben Skeggs <bskeggs@redhat.com> */ +#include <nvif/os.h> +#include <nvif/class.h> +#include <nvif/ioctl.h> + #include "nouveau_sysfs.h" -#include <core/object.h> -#include <core/class.h> +MODULE_PARM_DESC(pstate, "enable sysfs pstate file, which will be moved in the future"); +static int nouveau_pstate; +module_param_named(pstate, nouveau_pstate, int, 0400); static inline struct drm_device * drm_device(struct device *d) @@ -43,38 +48,42 @@ static ssize_t nouveau_sysfs_pstate_get(struct device *d, struct device_attribute *a, char *b) { struct nouveau_sysfs *sysfs = nouveau_sysfs(drm_device(d)); - struct nv_control_pstate_info info; + struct nvif_control_pstate_info_v0 info = {}; size_t cnt = PAGE_SIZE; char *buf = b; int ret, i; - ret = nv_exec(sysfs->ctrl, NV_CONTROL_PSTATE_INFO, &info, sizeof(info)); + ret = nvif_mthd(&sysfs->ctrl, NVIF_CONTROL_PSTATE_INFO, + &info, sizeof(info)); if (ret) return ret; for (i = 0; i < info.count + 1; i++) { const s32 state = i < info.count ? i : - NV_CONTROL_PSTATE_ATTR_STATE_CURRENT; - struct nv_control_pstate_attr attr = { + NVIF_CONTROL_PSTATE_ATTR_V0_STATE_CURRENT; + struct nvif_control_pstate_attr_v0 attr = { .state = state, .index = 0, }; - ret = nv_exec(sysfs->ctrl, NV_CONTROL_PSTATE_ATTR, - &attr, sizeof(attr)); + ret = nvif_mthd(&sysfs->ctrl, NVIF_CONTROL_PSTATE_ATTR, + &attr, sizeof(attr)); if (ret) return ret; if (i < info.count) snappendf(buf, cnt, "%02x:", attr.state); else - snappendf(buf, cnt, "--:"); + snappendf(buf, cnt, "%s:", info.pwrsrc == 0 ? "DC" : + info.pwrsrc == 1 ? "AC" : + "--"); attr.index = 0; do { attr.state = state; - ret = nv_exec(sysfs->ctrl, NV_CONTROL_PSTATE_ATTR, - &attr, sizeof(attr)); + ret = nvif_mthd(&sysfs->ctrl, + NVIF_CONTROL_PSTATE_ATTR, + &attr, sizeof(attr)); if (ret) return ret; @@ -84,9 +93,20 @@ nouveau_sysfs_pstate_get(struct device *d, struct device_attribute *a, char *b) snappendf(buf, cnt, " %s", attr.unit); } while (attr.index); - if ((state >= 0 && info.pstate == state) || - (state < 0 && info.ustate < 0)) - snappendf(buf, cnt, " *"); + if (state >= 0) { + if (info.ustate_ac == state) + snappendf(buf, cnt, " AC"); + if (info.ustate_dc == state) + snappendf(buf, cnt, " DC"); + if (info.pstate == state) + snappendf(buf, cnt, " *"); + } else { + if (info.ustate_ac < -1) + snappendf(buf, cnt, " AC"); + if (info.ustate_dc < -1) + snappendf(buf, cnt, " DC"); + } + snappendf(buf, cnt, "\n"); } @@ -98,26 +118,36 @@ nouveau_sysfs_pstate_set(struct device *d, struct device_attribute *a, const char *buf, size_t count) { struct nouveau_sysfs *sysfs = nouveau_sysfs(drm_device(d)); - struct nv_control_pstate_user args; + struct nvif_control_pstate_user_v0 args = { .pwrsrc = -EINVAL }; long value, ret; char *tmp; if ((tmp = strchr(buf, '\n'))) *tmp = '\0'; + if (!strncasecmp(buf, "dc:", 3)) { + args.pwrsrc = 0; + buf += 3; + } else + if (!strncasecmp(buf, "ac:", 3)) { + args.pwrsrc = 1; + buf += 3; + } + if (!strcasecmp(buf, "none")) - args.state = NV_CONTROL_PSTATE_USER_STATE_UNKNOWN; + args.ustate = NVIF_CONTROL_PSTATE_USER_V0_STATE_UNKNOWN; else if (!strcasecmp(buf, "auto")) - args.state = NV_CONTROL_PSTATE_USER_STATE_PERFMON; + args.ustate = NVIF_CONTROL_PSTATE_USER_V0_STATE_PERFMON; else { ret = kstrtol(buf, 16, &value); if (ret) return ret; - args.state = value; + args.ustate = value; } - ret = nv_exec(sysfs->ctrl, NV_CONTROL_PSTATE_USER, &args, sizeof(args)); + ret = nvif_mthd(&sysfs->ctrl, NVIF_CONTROL_PSTATE_USER, + &args, sizeof(args)); if (ret < 0) return ret; @@ -132,11 +162,11 @@ nouveau_sysfs_fini(struct drm_device *dev) { struct nouveau_sysfs *sysfs = nouveau_sysfs(dev); struct nouveau_drm *drm = nouveau_drm(dev); - struct nouveau_device *device = nv_device(drm->device); + struct nvif_device *device = &drm->device; - if (sysfs->ctrl) { - device_remove_file(nv_device_base(device), &dev_attr_pstate); - nouveau_object_del(nv_object(drm), NVDRM_DEVICE, NVDRM_CONTROL); + if (sysfs && sysfs->ctrl.priv) { + device_remove_file(nv_device_base(nvkm_device(device)), &dev_attr_pstate); + nvif_object_fini(&sysfs->ctrl); } drm->sysfs = NULL; @@ -147,18 +177,22 @@ int nouveau_sysfs_init(struct drm_device *dev) { struct nouveau_drm *drm = nouveau_drm(dev); - struct nouveau_device *device = nv_device(drm->device); + struct nvif_device *device = &drm->device; struct nouveau_sysfs *sysfs; int ret; + if (!nouveau_pstate) + return 0; + sysfs = drm->sysfs = kzalloc(sizeof(*sysfs), GFP_KERNEL); if (!sysfs) return -ENOMEM; - ret = nouveau_object_new(nv_object(drm), NVDRM_DEVICE, NVDRM_CONTROL, - NV_CONTROL_CLASS, NULL, 0, &sysfs->ctrl); + ret = nvif_object_init(nvif_object(device), NULL, NVDRM_CONTROL, + NVIF_IOCTL_NEW_V0_CONTROL, NULL, 0, + &sysfs->ctrl); if (ret == 0) - device_create_file(nv_device_base(device), &dev_attr_pstate); + device_create_file(nv_device_base(nvkm_device(device)), &dev_attr_pstate); return 0; } |