diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2014-08-09 14:10:25 -0400 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2014-08-09 15:28:04 -0400 |
commit | a532da976f17234375d3b34633ff5d48f71f62bc (patch) | |
tree | 5cad4e7ae3f469bcaf7c38b778e440159fcb7f7b /drivers/gpu | |
parent | 96af8222cef78ab4d92186d5e10880dc78395415 (diff) |
drm/nouveau/device: audit and version NVIF_CONTROL class and methods
The full object interfaces are about to be exposed to userspace, so we
need to check for any security-related issues and version the structs
to make it easier to handle any changes we may need in the future.
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/nouveau/core/core/object.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/device/ctrl.c | 161 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/include/core/class.h | 43 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/include/core/object.h | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_sysfs.c | 27 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvif/class.h | 48 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvif/ioctl.h | 1 |
7 files changed, 174 insertions, 112 deletions
diff --git a/drivers/gpu/drm/nouveau/core/core/object.c b/drivers/gpu/drm/nouveau/core/core/object.c index d6fea944a5a7..b08630577c82 100644 --- a/drivers/gpu/drm/nouveau/core/core/object.c +++ b/drivers/gpu/drm/nouveau/core/core/object.c | |||
@@ -58,7 +58,7 @@ nouveau_object_create_(struct nouveau_object *parent, | |||
58 | return 0; | 58 | return 0; |
59 | } | 59 | } |
60 | 60 | ||
61 | static int | 61 | int |
62 | _nouveau_object_ctor(struct nouveau_object *parent, | 62 | _nouveau_object_ctor(struct nouveau_object *parent, |
63 | struct nouveau_object *engine, | 63 | struct nouveau_object *engine, |
64 | struct nouveau_oclass *oclass, void *data, u32 size, | 64 | struct nouveau_oclass *oclass, void *data, u32 size, |
diff --git a/drivers/gpu/drm/nouveau/core/engine/device/ctrl.c b/drivers/gpu/drm/nouveau/core/engine/device/ctrl.c index fb546f3a1af0..e34101a3490e 100644 --- a/drivers/gpu/drm/nouveau/core/engine/device/ctrl.c +++ b/drivers/gpu/drm/nouveau/core/engine/device/ctrl.c | |||
@@ -22,59 +22,82 @@ | |||
22 | * Authors: Ben Skeggs <bskeggs@redhat.com> | 22 | * Authors: Ben Skeggs <bskeggs@redhat.com> |
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include <core/client.h> | ||
25 | #include <core/object.h> | 26 | #include <core/object.h> |
26 | #include <core/class.h> | 27 | #include <nvif/unpack.h> |
28 | #include <nvif/class.h> | ||
29 | #include <nvif/ioctl.h> | ||
27 | 30 | ||
28 | #include <subdev/clock.h> | 31 | #include <subdev/clock.h> |
29 | 32 | ||
30 | #include "priv.h" | 33 | #include "priv.h" |
31 | 34 | ||
32 | static int | 35 | static int |
33 | nouveau_control_mthd_pstate_info(struct nouveau_object *object, u32 mthd, | 36 | nouveau_control_mthd_pstate_info(struct nouveau_object *object, |
34 | void *data, u32 size) | 37 | void *data, u32 size) |
35 | { | 38 | { |
39 | union { | ||
40 | struct nvif_control_pstate_info_v0 v0; | ||
41 | } *args = data; | ||
36 | struct nouveau_clock *clk = nouveau_clock(object); | 42 | struct nouveau_clock *clk = nouveau_clock(object); |
37 | struct nv_control_pstate_info *args = data; | 43 | int ret; |
38 | 44 | ||
39 | if (size < sizeof(*args)) | 45 | nv_ioctl(object, "control pstate info size %d\n", size); |
40 | return -EINVAL; | 46 | if (nvif_unpack(args->v0, 0, 0, false)) { |
47 | nv_ioctl(object, "control pstate info vers %d\n", | ||
48 | args->v0.version); | ||
49 | } else | ||
50 | return ret; | ||
41 | 51 | ||
42 | if (clk) { | 52 | if (clk) { |
43 | args->count = clk->state_nr; | 53 | args->v0.count = clk->state_nr; |
44 | args->ustate_ac = clk->ustate_ac; | 54 | args->v0.ustate_ac = clk->ustate_ac; |
45 | args->ustate_dc = clk->ustate_dc; | 55 | args->v0.ustate_dc = clk->ustate_dc; |
46 | args->pwrsrc = clk->pwrsrc; | 56 | args->v0.pwrsrc = clk->pwrsrc; |
47 | args->pstate = clk->pstate; | 57 | args->v0.pstate = clk->pstate; |
48 | } else { | 58 | } else { |
49 | args->count = 0; | 59 | args->v0.count = 0; |
50 | args->ustate_ac = NV_CONTROL_PSTATE_INFO_USTATE_DISABLE; | 60 | args->v0.ustate_ac = NVIF_CONTROL_PSTATE_INFO_V0_USTATE_DISABLE; |
51 | args->ustate_dc = NV_CONTROL_PSTATE_INFO_USTATE_DISABLE; | 61 | args->v0.ustate_dc = NVIF_CONTROL_PSTATE_INFO_V0_USTATE_DISABLE; |
52 | args->pwrsrc = -ENOSYS; | 62 | args->v0.pwrsrc = -ENOSYS; |
53 | args->pstate = NV_CONTROL_PSTATE_INFO_PSTATE_UNKNOWN; | 63 | args->v0.pstate = NVIF_CONTROL_PSTATE_INFO_V0_PSTATE_UNKNOWN; |
54 | } | 64 | } |
55 | 65 | ||
56 | return 0; | 66 | return 0; |
57 | } | 67 | } |
58 | 68 | ||
59 | static int | 69 | static int |
60 | nouveau_control_mthd_pstate_attr(struct nouveau_object *object, u32 mthd, | 70 | nouveau_control_mthd_pstate_attr(struct nouveau_object *object, |
61 | void *data, u32 size) | 71 | void *data, u32 size) |
62 | { | 72 | { |
73 | union { | ||
74 | struct nvif_control_pstate_attr_v0 v0; | ||
75 | } *args = data; | ||
63 | struct nouveau_clock *clk = nouveau_clock(object); | 76 | struct nouveau_clock *clk = nouveau_clock(object); |
64 | struct nv_control_pstate_attr *args = data; | ||
65 | struct nouveau_clocks *domain; | 77 | struct nouveau_clocks *domain; |
66 | struct nouveau_pstate *pstate; | 78 | struct nouveau_pstate *pstate; |
67 | struct nouveau_cstate *cstate; | 79 | struct nouveau_cstate *cstate; |
68 | int i = 0, j = -1; | 80 | int i = 0, j = -1; |
69 | u32 lo, hi; | 81 | u32 lo, hi; |
70 | 82 | int ret; | |
71 | if ((size < sizeof(*args)) || !clk || | 83 | |
72 | (args->state >= 0 && args->state >= clk->state_nr)) | 84 | nv_ioctl(object, "control pstate attr size %d\n", size); |
73 | return -EINVAL; | 85 | if (nvif_unpack(args->v0, 0, 0, false)) { |
86 | nv_ioctl(object, "control pstate attr vers %d state %d " | ||
87 | "index %d\n", | ||
88 | args->v0.version, args->v0.state, args->v0.index); | ||
89 | if (!clk) | ||
90 | return -ENODEV; | ||
91 | if (args->v0.state < NVIF_CONTROL_PSTATE_ATTR_V0_STATE_CURRENT) | ||
92 | return -EINVAL; | ||
93 | if (args->v0.state >= clk->state_nr) | ||
94 | return -EINVAL; | ||
95 | } else | ||
96 | return ret; | ||
74 | domain = clk->domains; | 97 | domain = clk->domains; |
75 | 98 | ||
76 | while (domain->name != nv_clk_src_max) { | 99 | while (domain->name != nv_clk_src_max) { |
77 | if (domain->mname && ++j == args->index) | 100 | if (domain->mname && ++j == args->v0.index) |
78 | break; | 101 | break; |
79 | domain++; | 102 | domain++; |
80 | } | 103 | } |
@@ -82,9 +105,9 @@ nouveau_control_mthd_pstate_attr(struct nouveau_object *object, u32 mthd, | |||
82 | if (domain->name == nv_clk_src_max) | 105 | if (domain->name == nv_clk_src_max) |
83 | return -EINVAL; | 106 | return -EINVAL; |
84 | 107 | ||
85 | if (args->state != NV_CONTROL_PSTATE_ATTR_STATE_CURRENT) { | 108 | if (args->v0.state != NVIF_CONTROL_PSTATE_ATTR_V0_STATE_CURRENT) { |
86 | list_for_each_entry(pstate, &clk->states, head) { | 109 | list_for_each_entry(pstate, &clk->states, head) { |
87 | if (i++ == args->state) | 110 | if (i++ == args->v0.state) |
88 | break; | 111 | break; |
89 | } | 112 | } |
90 | 113 | ||
@@ -95,21 +118,21 @@ nouveau_control_mthd_pstate_attr(struct nouveau_object *object, u32 mthd, | |||
95 | hi = max(hi, cstate->domain[domain->name]); | 118 | hi = max(hi, cstate->domain[domain->name]); |
96 | } | 119 | } |
97 | 120 | ||
98 | args->state = pstate->pstate; | 121 | args->v0.state = pstate->pstate; |
99 | } else { | 122 | } else { |
100 | lo = max(clk->read(clk, domain->name), 0); | 123 | lo = max(clk->read(clk, domain->name), 0); |
101 | hi = lo; | 124 | hi = lo; |
102 | } | 125 | } |
103 | 126 | ||
104 | snprintf(args->name, sizeof(args->name), "%s", domain->mname); | 127 | snprintf(args->v0.name, sizeof(args->v0.name), "%s", domain->mname); |
105 | snprintf(args->unit, sizeof(args->unit), "MHz"); | 128 | snprintf(args->v0.unit, sizeof(args->v0.unit), "MHz"); |
106 | args->min = lo / domain->mdiv; | 129 | args->v0.min = lo / domain->mdiv; |
107 | args->max = hi / domain->mdiv; | 130 | args->v0.max = hi / domain->mdiv; |
108 | 131 | ||
109 | args->index = 0; | 132 | args->v0.index = 0; |
110 | while ((++domain)->name != nv_clk_src_max) { | 133 | while ((++domain)->name != nv_clk_src_max) { |
111 | if (domain->mname) { | 134 | if (domain->mname) { |
112 | args->index = ++j; | 135 | args->v0.index = ++j; |
113 | break; | 136 | break; |
114 | } | 137 | } |
115 | } | 138 | } |
@@ -118,39 +141,65 @@ nouveau_control_mthd_pstate_attr(struct nouveau_object *object, u32 mthd, | |||
118 | } | 141 | } |
119 | 142 | ||
120 | static int | 143 | static int |
121 | nouveau_control_mthd_pstate_user(struct nouveau_object *object, u32 mthd, | 144 | nouveau_control_mthd_pstate_user(struct nouveau_object *object, |
122 | void *data, u32 size) | 145 | void *data, u32 size) |
123 | { | 146 | { |
147 | union { | ||
148 | struct nvif_control_pstate_user_v0 v0; | ||
149 | } *args = data; | ||
124 | struct nouveau_clock *clk = nouveau_clock(object); | 150 | struct nouveau_clock *clk = nouveau_clock(object); |
125 | struct nv_control_pstate_user *args = data; | 151 | int ret; |
126 | int ret = 0; | 152 | |
127 | 153 | nv_ioctl(object, "control pstate user size %d\n", size); | |
128 | if (size < sizeof(*args) || !clk) | 154 | if (nvif_unpack(args->v0, 0, 0, false)) { |
129 | return -EINVAL; | 155 | nv_ioctl(object, "control pstate user vers %d ustate %d " |
130 | 156 | "pwrsrc %d\n", args->v0.version, | |
131 | if (args->pwrsrc >= 0) { | 157 | args->v0.ustate, args->v0.pwrsrc); |
132 | ret |= nouveau_clock_ustate(clk, args->ustate, args->pwrsrc); | 158 | if (!clk) |
159 | return -ENODEV; | ||
160 | } else | ||
161 | return ret; | ||
162 | |||
163 | if (args->v0.pwrsrc >= 0) { | ||
164 | ret |= nouveau_clock_ustate(clk, args->v0.ustate, args->v0.pwrsrc); | ||
133 | } else { | 165 | } else { |
134 | ret |= nouveau_clock_ustate(clk, args->ustate, 0); | 166 | ret |= nouveau_clock_ustate(clk, args->v0.ustate, 0); |
135 | ret |= nouveau_clock_ustate(clk, args->ustate, 1); | 167 | ret |= nouveau_clock_ustate(clk, args->v0.ustate, 1); |
136 | } | 168 | } |
137 | 169 | ||
138 | return ret; | 170 | return ret; |
139 | } | 171 | } |
140 | 172 | ||
173 | static int | ||
174 | nouveau_control_mthd(struct nouveau_object *object, u32 mthd, | ||
175 | void *data, u32 size) | ||
176 | { | ||
177 | switch (mthd) { | ||
178 | case NVIF_CONTROL_PSTATE_INFO: | ||
179 | return nouveau_control_mthd_pstate_info(object, data, size); | ||
180 | case NVIF_CONTROL_PSTATE_ATTR: | ||
181 | return nouveau_control_mthd_pstate_attr(object, data, size); | ||
182 | case NVIF_CONTROL_PSTATE_USER: | ||
183 | return nouveau_control_mthd_pstate_user(object, data, size); | ||
184 | default: | ||
185 | break; | ||
186 | } | ||
187 | return -EINVAL; | ||
188 | } | ||
189 | |||
190 | static struct nouveau_ofuncs | ||
191 | nouveau_control_ofuncs = { | ||
192 | .ctor = _nouveau_object_ctor, | ||
193 | .dtor = nouveau_object_destroy, | ||
194 | .init = nouveau_object_init, | ||
195 | .fini = nouveau_object_fini, | ||
196 | .mthd = nouveau_control_mthd, | ||
197 | }; | ||
198 | |||
141 | struct nouveau_oclass | 199 | struct nouveau_oclass |
142 | nouveau_control_oclass[] = { | 200 | nouveau_control_oclass[] = { |
143 | { .handle = NV_CONTROL_CLASS, | 201 | { .handle = NVIF_IOCTL_NEW_V0_CONTROL, |
144 | .ofuncs = &nouveau_object_ofuncs, | 202 | .ofuncs = &nouveau_control_ofuncs |
145 | .omthds = (struct nouveau_omthds[]) { | ||
146 | { NV_CONTROL_PSTATE_INFO, | ||
147 | NV_CONTROL_PSTATE_INFO, nouveau_control_mthd_pstate_info }, | ||
148 | { NV_CONTROL_PSTATE_ATTR, | ||
149 | NV_CONTROL_PSTATE_ATTR, nouveau_control_mthd_pstate_attr }, | ||
150 | { NV_CONTROL_PSTATE_USER, | ||
151 | NV_CONTROL_PSTATE_USER, nouveau_control_mthd_pstate_user }, | ||
152 | {}, | ||
153 | }, | ||
154 | }, | 203 | }, |
155 | {} | 204 | {} |
156 | }; | 205 | }; |
diff --git a/drivers/gpu/drm/nouveau/core/include/core/class.h b/drivers/gpu/drm/nouveau/core/include/core/class.h index 3df23606eb02..79de03bdff96 100644 --- a/drivers/gpu/drm/nouveau/core/include/core/class.h +++ b/drivers/gpu/drm/nouveau/core/include/core/class.h | |||
@@ -3,49 +3,6 @@ | |||
3 | 3 | ||
4 | #include <nvif/class.h> | 4 | #include <nvif/class.h> |
5 | 5 | ||
6 | /* Device control class | ||
7 | * | ||
8 | * XXXX: NV_CONTROL | ||
9 | */ | ||
10 | #define NV_CONTROL_CLASS 0x0000fffe | ||
11 | |||
12 | #define NV_CONTROL_PSTATE_INFO 0x00000000 | ||
13 | #define NV_CONTROL_PSTATE_INFO_USTATE_DISABLE (-1) | ||
14 | #define NV_CONTROL_PSTATE_INFO_USTATE_PERFMON (-2) | ||
15 | #define NV_CONTROL_PSTATE_INFO_PSTATE_UNKNOWN (-1) | ||
16 | #define NV_CONTROL_PSTATE_INFO_PSTATE_PERFMON (-2) | ||
17 | #define NV_CONTROL_PSTATE_ATTR 0x00000001 | ||
18 | #define NV_CONTROL_PSTATE_ATTR_STATE_CURRENT (-1) | ||
19 | #define NV_CONTROL_PSTATE_USER 0x00000002 | ||
20 | #define NV_CONTROL_PSTATE_USER_STATE_UNKNOWN (-1) | ||
21 | #define NV_CONTROL_PSTATE_USER_STATE_PERFMON (-2) | ||
22 | |||
23 | struct nv_control_pstate_info { | ||
24 | u32 count; /* out: number of power states */ | ||
25 | s32 ustate_ac; /* out: target pstate index */ | ||
26 | s32 ustate_dc; /* out: target pstate index */ | ||
27 | s32 pwrsrc; /* out: current power source */ | ||
28 | u32 pstate; /* out: current pstate index */ | ||
29 | }; | ||
30 | |||
31 | struct nv_control_pstate_attr { | ||
32 | s32 state; /* in: index of pstate to query | ||
33 | * out: pstate identifier | ||
34 | */ | ||
35 | u32 index; /* in: index of attribute to query | ||
36 | * out: index of next attribute, or 0 if no more | ||
37 | */ | ||
38 | char name[32]; | ||
39 | char unit[16]; | ||
40 | u32 min; | ||
41 | u32 max; | ||
42 | }; | ||
43 | |||
44 | struct nv_control_pstate_user { | ||
45 | s32 ustate; /* in: pstate identifier */ | ||
46 | s32 pwrsrc; /* in: target power source */ | ||
47 | }; | ||
48 | |||
49 | /* DMA FIFO channel classes | 6 | /* DMA FIFO channel classes |
50 | * | 7 | * |
51 | * 006b: NV03_CHANNEL_DMA | 8 | * 006b: NV03_CHANNEL_DMA |
diff --git a/drivers/gpu/drm/nouveau/core/include/core/object.h b/drivers/gpu/drm/nouveau/core/include/core/object.h index b22e8fd4005e..d7039482d6fd 100644 --- a/drivers/gpu/drm/nouveau/core/include/core/object.h +++ b/drivers/gpu/drm/nouveau/core/include/core/object.h | |||
@@ -48,6 +48,10 @@ void nouveau_object_destroy(struct nouveau_object *); | |||
48 | int nouveau_object_init(struct nouveau_object *); | 48 | int nouveau_object_init(struct nouveau_object *); |
49 | int nouveau_object_fini(struct nouveau_object *, bool suspend); | 49 | int nouveau_object_fini(struct nouveau_object *, bool suspend); |
50 | 50 | ||
51 | int _nouveau_object_ctor(struct nouveau_object *, struct nouveau_object *, | ||
52 | struct nouveau_oclass *, void *, u32, | ||
53 | struct nouveau_object **); | ||
54 | |||
51 | extern struct nouveau_ofuncs nouveau_object_ofuncs; | 55 | extern struct nouveau_ofuncs nouveau_object_ofuncs; |
52 | 56 | ||
53 | /* Don't allocate dynamically, because lockdep needs lock_class_keys to be in | 57 | /* Don't allocate dynamically, because lockdep needs lock_class_keys to be in |
diff --git a/drivers/gpu/drm/nouveau/nouveau_sysfs.c b/drivers/gpu/drm/nouveau/nouveau_sysfs.c index d14e6ef93a48..32a23895abd5 100644 --- a/drivers/gpu/drm/nouveau/nouveau_sysfs.c +++ b/drivers/gpu/drm/nouveau/nouveau_sysfs.c | |||
@@ -24,6 +24,7 @@ | |||
24 | 24 | ||
25 | #include <nvif/os.h> | 25 | #include <nvif/os.h> |
26 | #include <nvif/class.h> | 26 | #include <nvif/class.h> |
27 | #include <nvif/ioctl.h> | ||
27 | 28 | ||
28 | #include "nouveau_sysfs.h" | 29 | #include "nouveau_sysfs.h" |
29 | 30 | ||
@@ -43,25 +44,25 @@ static ssize_t | |||
43 | nouveau_sysfs_pstate_get(struct device *d, struct device_attribute *a, char *b) | 44 | nouveau_sysfs_pstate_get(struct device *d, struct device_attribute *a, char *b) |
44 | { | 45 | { |
45 | struct nouveau_sysfs *sysfs = nouveau_sysfs(drm_device(d)); | 46 | struct nouveau_sysfs *sysfs = nouveau_sysfs(drm_device(d)); |
46 | struct nv_control_pstate_info info; | 47 | struct nvif_control_pstate_info_v0 info = {}; |
47 | size_t cnt = PAGE_SIZE; | 48 | size_t cnt = PAGE_SIZE; |
48 | char *buf = b; | 49 | char *buf = b; |
49 | int ret, i; | 50 | int ret, i; |
50 | 51 | ||
51 | ret = nvif_exec(&sysfs->ctrl, NV_CONTROL_PSTATE_INFO, | 52 | ret = nvif_mthd(&sysfs->ctrl, NVIF_CONTROL_PSTATE_INFO, |
52 | &info, sizeof(info)); | 53 | &info, sizeof(info)); |
53 | if (ret) | 54 | if (ret) |
54 | return ret; | 55 | return ret; |
55 | 56 | ||
56 | for (i = 0; i < info.count + 1; i++) { | 57 | for (i = 0; i < info.count + 1; i++) { |
57 | const s32 state = i < info.count ? i : | 58 | const s32 state = i < info.count ? i : |
58 | NV_CONTROL_PSTATE_ATTR_STATE_CURRENT; | 59 | NVIF_CONTROL_PSTATE_ATTR_V0_STATE_CURRENT; |
59 | struct nv_control_pstate_attr attr = { | 60 | struct nvif_control_pstate_attr_v0 attr = { |
60 | .state = state, | 61 | .state = state, |
61 | .index = 0, | 62 | .index = 0, |
62 | }; | 63 | }; |
63 | 64 | ||
64 | ret = nvif_exec(&sysfs->ctrl, NV_CONTROL_PSTATE_ATTR, | 65 | ret = nvif_mthd(&sysfs->ctrl, NVIF_CONTROL_PSTATE_ATTR, |
65 | &attr, sizeof(attr)); | 66 | &attr, sizeof(attr)); |
66 | if (ret) | 67 | if (ret) |
67 | return ret; | 68 | return ret; |
@@ -76,7 +77,8 @@ nouveau_sysfs_pstate_get(struct device *d, struct device_attribute *a, char *b) | |||
76 | attr.index = 0; | 77 | attr.index = 0; |
77 | do { | 78 | do { |
78 | attr.state = state; | 79 | attr.state = state; |
79 | ret = nvif_exec(&sysfs->ctrl, NV_CONTROL_PSTATE_ATTR, | 80 | ret = nvif_mthd(&sysfs->ctrl, |
81 | NVIF_CONTROL_PSTATE_ATTR, | ||
80 | &attr, sizeof(attr)); | 82 | &attr, sizeof(attr)); |
81 | if (ret) | 83 | if (ret) |
82 | return ret; | 84 | return ret; |
@@ -112,7 +114,7 @@ nouveau_sysfs_pstate_set(struct device *d, struct device_attribute *a, | |||
112 | const char *buf, size_t count) | 114 | const char *buf, size_t count) |
113 | { | 115 | { |
114 | struct nouveau_sysfs *sysfs = nouveau_sysfs(drm_device(d)); | 116 | struct nouveau_sysfs *sysfs = nouveau_sysfs(drm_device(d)); |
115 | struct nv_control_pstate_user args = { .pwrsrc = -EINVAL }; | 117 | struct nvif_control_pstate_user_v0 args = { .pwrsrc = -EINVAL }; |
116 | long value, ret; | 118 | long value, ret; |
117 | char *tmp; | 119 | char *tmp; |
118 | 120 | ||
@@ -129,10 +131,10 @@ nouveau_sysfs_pstate_set(struct device *d, struct device_attribute *a, | |||
129 | } | 131 | } |
130 | 132 | ||
131 | if (!strcasecmp(buf, "none")) | 133 | if (!strcasecmp(buf, "none")) |
132 | args.ustate = NV_CONTROL_PSTATE_USER_STATE_UNKNOWN; | 134 | args.ustate = NVIF_CONTROL_PSTATE_USER_V0_STATE_UNKNOWN; |
133 | else | 135 | else |
134 | if (!strcasecmp(buf, "auto")) | 136 | if (!strcasecmp(buf, "auto")) |
135 | args.ustate = NV_CONTROL_PSTATE_USER_STATE_PERFMON; | 137 | args.ustate = NVIF_CONTROL_PSTATE_USER_V0_STATE_PERFMON; |
136 | else { | 138 | else { |
137 | ret = kstrtol(buf, 16, &value); | 139 | ret = kstrtol(buf, 16, &value); |
138 | if (ret) | 140 | if (ret) |
@@ -140,7 +142,7 @@ nouveau_sysfs_pstate_set(struct device *d, struct device_attribute *a, | |||
140 | args.ustate = value; | 142 | args.ustate = value; |
141 | } | 143 | } |
142 | 144 | ||
143 | ret = nvif_exec(&sysfs->ctrl, NV_CONTROL_PSTATE_USER, | 145 | ret = nvif_mthd(&sysfs->ctrl, NVIF_CONTROL_PSTATE_USER, |
144 | &args, sizeof(args)); | 146 | &args, sizeof(args)); |
145 | if (ret < 0) | 147 | if (ret < 0) |
146 | return ret; | 148 | return ret; |
@@ -179,8 +181,9 @@ nouveau_sysfs_init(struct drm_device *dev) | |||
179 | if (!sysfs) | 181 | if (!sysfs) |
180 | return -ENOMEM; | 182 | return -ENOMEM; |
181 | 183 | ||
182 | ret = nvif_object_init(nvif_object(&drm->device), NULL, NVDRM_CONTROL, | 184 | ret = nvif_object_init(nvif_object(device), NULL, NVDRM_CONTROL, |
183 | NV_CONTROL_CLASS, NULL, 0, &sysfs->ctrl); | 185 | NVIF_IOCTL_NEW_V0_CONTROL, NULL, 0, |
186 | &sysfs->ctrl); | ||
184 | if (ret == 0) | 187 | if (ret == 0) |
185 | device_create_file(nv_device_base(nvkm_device(device)), &dev_attr_pstate); | 188 | device_create_file(nv_device_base(nvkm_device(device)), &dev_attr_pstate); |
186 | 189 | ||
diff --git a/drivers/gpu/drm/nouveau/nvif/class.h b/drivers/gpu/drm/nouveau/nvif/class.h index decca22ea528..7d6c13026855 100644 --- a/drivers/gpu/drm/nouveau/nvif/class.h +++ b/drivers/gpu/drm/nouveau/nvif/class.h | |||
@@ -185,4 +185,52 @@ struct nvif_perfctr_read_v0 { | |||
185 | __u32 clk; | 185 | __u32 clk; |
186 | }; | 186 | }; |
187 | 187 | ||
188 | |||
189 | /******************************************************************************* | ||
190 | * device control | ||
191 | ******************************************************************************/ | ||
192 | |||
193 | #define NVIF_CONTROL_PSTATE_INFO 0x00 | ||
194 | #define NVIF_CONTROL_PSTATE_ATTR 0x01 | ||
195 | #define NVIF_CONTROL_PSTATE_USER 0x02 | ||
196 | |||
197 | struct nvif_control_pstate_info_v0 { | ||
198 | __u8 version; | ||
199 | __u8 count; /* out: number of power states */ | ||
200 | #define NVIF_CONTROL_PSTATE_INFO_V0_USTATE_DISABLE (-1) | ||
201 | #define NVIF_CONTROL_PSTATE_INFO_V0_USTATE_PERFMON (-2) | ||
202 | __s8 ustate_ac; /* out: target pstate index */ | ||
203 | __s8 ustate_dc; /* out: target pstate index */ | ||
204 | __s8 pwrsrc; /* out: current power source */ | ||
205 | #define NVIF_CONTROL_PSTATE_INFO_V0_PSTATE_UNKNOWN (-1) | ||
206 | #define NVIF_CONTROL_PSTATE_INFO_V0_PSTATE_PERFMON (-2) | ||
207 | __s8 pstate; /* out: current pstate index */ | ||
208 | __u8 pad06[2]; | ||
209 | }; | ||
210 | |||
211 | struct nvif_control_pstate_attr_v0 { | ||
212 | __u8 version; | ||
213 | #define NVIF_CONTROL_PSTATE_ATTR_V0_STATE_CURRENT (-1) | ||
214 | __s8 state; /* in: index of pstate to query | ||
215 | * out: pstate identifier | ||
216 | */ | ||
217 | __u8 index; /* in: index of attribute to query | ||
218 | * out: index of next attribute, or 0 if no more | ||
219 | */ | ||
220 | __u8 pad03[5]; | ||
221 | __u32 min; | ||
222 | __u32 max; | ||
223 | char name[32]; | ||
224 | char unit[16]; | ||
225 | }; | ||
226 | |||
227 | struct nvif_control_pstate_user_v0 { | ||
228 | __u8 version; | ||
229 | #define NVIF_CONTROL_PSTATE_USER_V0_STATE_UNKNOWN (-1) | ||
230 | #define NVIF_CONTROL_PSTATE_USER_V0_STATE_PERFMON (-2) | ||
231 | __s8 ustate; /* in: pstate identifier */ | ||
232 | __s8 pwrsrc; /* in: target power source */ | ||
233 | __u8 pad03[5]; | ||
234 | }; | ||
235 | |||
188 | #endif | 236 | #endif |
diff --git a/drivers/gpu/drm/nouveau/nvif/ioctl.h b/drivers/gpu/drm/nouveau/nvif/ioctl.h index 67a56711b18c..4cd8e323b23d 100644 --- a/drivers/gpu/drm/nouveau/nvif/ioctl.h +++ b/drivers/gpu/drm/nouveau/nvif/ioctl.h | |||
@@ -50,6 +50,7 @@ struct nvif_ioctl_new_v0 { | |||
50 | __u32 handle; | 50 | __u32 handle; |
51 | /* these class numbers are made up by us, and not nvidia-assigned */ | 51 | /* these class numbers are made up by us, and not nvidia-assigned */ |
52 | #define NVIF_IOCTL_NEW_V0_PERFCTR 0x0000ffff | 52 | #define NVIF_IOCTL_NEW_V0_PERFCTR 0x0000ffff |
53 | #define NVIF_IOCTL_NEW_V0_CONTROL 0x0000fffe | ||
53 | __u32 oclass; | 54 | __u32 oclass; |
54 | __u8 data[]; /* class data (class.h) */ | 55 | __u8 data[]; /* class data (class.h) */ |
55 | }; | 56 | }; |