diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2014-08-09 14:10:27 -0400 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2014-08-09 15:28:10 -0400 |
commit | 67cb49c45feba4141ed4b962855249d30302cd7d (patch) | |
tree | 41f99dde4a3f0b798485e7b47450659845f3a1d5 | |
parent | c02ed2bf98a682c477640c782d1e6a94525b2123 (diff) |
drm/nv50-/disp: audit and version PIOR_PWR method
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>
-rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/disp/nv50.c | 7 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/disp/nv50.h | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/disp/nv84.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/disp/nv94.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/disp/nva3.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/disp/piornv50.c | 56 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/include/core/class.h | 17 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nv50_display.c | 16 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvif/class.h | 7 |
10 files changed, 50 insertions, 70 deletions
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c index ed55cc296fb4..d83d3efe8253 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c | |||
@@ -952,6 +952,10 @@ nv50_disp_base_mthd(struct nouveau_object *object, u32 mthd, | |||
952 | return ret; | 952 | return ret; |
953 | } | 953 | } |
954 | break; | 954 | break; |
955 | case NV50_DISP_MTHD_V1_PIOR_PWR: | ||
956 | if (!priv->pior.power) | ||
957 | return -ENODEV; | ||
958 | return priv->pior.power(object, priv, data, size, head, outp); | ||
955 | default: | 959 | default: |
956 | break; | 960 | break; |
957 | } | 961 | } |
@@ -1080,9 +1084,6 @@ nv50_disp_base_ofuncs = { | |||
1080 | static struct nouveau_omthds | 1084 | static struct nouveau_omthds |
1081 | nv50_disp_base_omthds[] = { | 1085 | nv50_disp_base_omthds[] = { |
1082 | { HEAD_MTHD(NV50_DISP_SCANOUTPOS) , nv50_disp_base_scanoutpos }, | 1086 | { HEAD_MTHD(NV50_DISP_SCANOUTPOS) , nv50_disp_base_scanoutpos }, |
1083 | { PIOR_MTHD(NV50_DISP_PIOR_PWR) , nv50_pior_mthd }, | ||
1084 | { PIOR_MTHD(NV50_DISP_PIOR_TMDS_PWR) , nv50_pior_mthd }, | ||
1085 | { PIOR_MTHD(NV50_DISP_PIOR_DP_PWR) , nv50_pior_mthd }, | ||
1086 | {}, | 1087 | {}, |
1087 | }; | 1088 | }; |
1088 | 1089 | ||
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.h b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.h index ec623b7314b4..62a38b5f0024 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.h +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.h | |||
@@ -53,7 +53,7 @@ struct nv50_disp_priv { | |||
53 | } sor; | 53 | } sor; |
54 | struct { | 54 | struct { |
55 | int nr; | 55 | int nr; |
56 | int (*power)(struct nv50_disp_priv *, int ext, u32 data); | 56 | int (*power)(NV50_DISP_MTHD_V1); |
57 | u8 type[3]; | 57 | u8 type[3]; |
58 | } pior; | 58 | } pior; |
59 | }; | 59 | }; |
@@ -99,8 +99,7 @@ int nvd0_sor_dp_drvctl(struct nv50_disp_priv *, int, int, int, u16, u16, u32, | |||
99 | 99 | ||
100 | #define PIOR_MTHD(n) (n), (n) + 0x03 | 100 | #define PIOR_MTHD(n) (n), (n) + 0x03 |
101 | 101 | ||
102 | int nv50_pior_mthd(struct nouveau_object *, u32, void *, u32); | 102 | int nv50_pior_power(NV50_DISP_MTHD_V1); |
103 | int nv50_pior_power(struct nv50_disp_priv *, int, u32); | ||
104 | 103 | ||
105 | struct nv50_disp_base { | 104 | struct nv50_disp_base { |
106 | struct nouveau_parent base; | 105 | struct nouveau_parent base; |
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv84.c b/drivers/gpu/drm/nouveau/core/engine/disp/nv84.c index 006ccec6be23..c0012d8a450a 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nv84.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv84.c | |||
@@ -215,9 +215,6 @@ nv84_disp_sclass[] = { | |||
215 | struct nouveau_omthds | 215 | struct nouveau_omthds |
216 | nv84_disp_base_omthds[] = { | 216 | nv84_disp_base_omthds[] = { |
217 | { HEAD_MTHD(NV50_DISP_SCANOUTPOS) , nv50_disp_base_scanoutpos }, | 217 | { HEAD_MTHD(NV50_DISP_SCANOUTPOS) , nv50_disp_base_scanoutpos }, |
218 | { PIOR_MTHD(NV50_DISP_PIOR_PWR) , nv50_pior_mthd }, | ||
219 | { PIOR_MTHD(NV50_DISP_PIOR_TMDS_PWR) , nv50_pior_mthd }, | ||
220 | { PIOR_MTHD(NV50_DISP_PIOR_DP_PWR) , nv50_pior_mthd }, | ||
221 | {}, | 218 | {}, |
222 | }; | 219 | }; |
223 | 220 | ||
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv94.c b/drivers/gpu/drm/nouveau/core/engine/disp/nv94.c index 821084da766a..192c8085a1dc 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nv94.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv94.c | |||
@@ -74,9 +74,6 @@ nv94_disp_sclass[] = { | |||
74 | static struct nouveau_omthds | 74 | static struct nouveau_omthds |
75 | nv94_disp_base_omthds[] = { | 75 | nv94_disp_base_omthds[] = { |
76 | { HEAD_MTHD(NV50_DISP_SCANOUTPOS) , nv50_disp_base_scanoutpos }, | 76 | { HEAD_MTHD(NV50_DISP_SCANOUTPOS) , nv50_disp_base_scanoutpos }, |
77 | { PIOR_MTHD(NV50_DISP_PIOR_PWR) , nv50_pior_mthd }, | ||
78 | { PIOR_MTHD(NV50_DISP_PIOR_TMDS_PWR) , nv50_pior_mthd }, | ||
79 | { PIOR_MTHD(NV50_DISP_PIOR_DP_PWR) , nv50_pior_mthd }, | ||
80 | {}, | 77 | {}, |
81 | }; | 78 | }; |
82 | 79 | ||
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nva3.c b/drivers/gpu/drm/nouveau/core/engine/disp/nva3.c index cd887166f630..38a79a0e358f 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nva3.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nva3.c | |||
@@ -46,9 +46,6 @@ nva3_disp_sclass[] = { | |||
46 | static struct nouveau_omthds | 46 | static struct nouveau_omthds |
47 | nva3_disp_base_omthds[] = { | 47 | nva3_disp_base_omthds[] = { |
48 | { HEAD_MTHD(NV50_DISP_SCANOUTPOS) , nv50_disp_base_scanoutpos }, | 48 | { HEAD_MTHD(NV50_DISP_SCANOUTPOS) , nv50_disp_base_scanoutpos }, |
49 | { PIOR_MTHD(NV50_DISP_PIOR_PWR) , nv50_pior_mthd }, | ||
50 | { PIOR_MTHD(NV50_DISP_PIOR_TMDS_PWR) , nv50_pior_mthd }, | ||
51 | { PIOR_MTHD(NV50_DISP_PIOR_DP_PWR) , nv50_pior_mthd }, | ||
52 | {}, | 49 | {}, |
53 | }; | 50 | }; |
54 | 51 | ||
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c b/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c index c9a3b5803faa..5aa44eca8056 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c | |||
@@ -712,9 +712,6 @@ nvd0_disp_base_ofuncs = { | |||
712 | struct nouveau_omthds | 712 | struct nouveau_omthds |
713 | nvd0_disp_base_omthds[] = { | 713 | nvd0_disp_base_omthds[] = { |
714 | { HEAD_MTHD(NV50_DISP_SCANOUTPOS) , nvd0_disp_base_scanoutpos }, | 714 | { HEAD_MTHD(NV50_DISP_SCANOUTPOS) , nvd0_disp_base_scanoutpos }, |
715 | { PIOR_MTHD(NV50_DISP_PIOR_PWR) , nv50_pior_mthd }, | ||
716 | { PIOR_MTHD(NV50_DISP_PIOR_TMDS_PWR) , nv50_pior_mthd }, | ||
717 | { PIOR_MTHD(NV50_DISP_PIOR_DP_PWR) , nv50_pior_mthd }, | ||
718 | {}, | 715 | {}, |
719 | }; | 716 | }; |
720 | 717 | ||
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/piornv50.c b/drivers/gpu/drm/nouveau/core/engine/disp/piornv50.c index fe0f256f11bf..d00f89a468a7 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/piornv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/piornv50.c | |||
@@ -22,8 +22,9 @@ | |||
22 | * Authors: Ben Skeggs | 22 | * Authors: Ben Skeggs |
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include <core/os.h> | 25 | #include <core/client.h> |
26 | #include <core/class.h> | 26 | #include <nvif/unpack.h> |
27 | #include <nvif/class.h> | ||
27 | 28 | ||
28 | #include <subdev/bios.h> | 29 | #include <subdev/bios.h> |
29 | #include <subdev/bios/dcb.h> | 30 | #include <subdev/bios/dcb.h> |
@@ -143,38 +144,29 @@ nv50_pior_dp_impl = { | |||
143 | *****************************************************************************/ | 144 | *****************************************************************************/ |
144 | 145 | ||
145 | int | 146 | int |
146 | nv50_pior_power(struct nv50_disp_priv *priv, int or, u32 data) | 147 | nv50_pior_power(NV50_DISP_MTHD_V1) |
147 | { | 148 | { |
148 | const u32 stat = data & NV50_DISP_PIOR_PWR_STATE; | 149 | const u32 soff = outp->or * 0x800; |
149 | const u32 soff = (or * 0x800); | 150 | union { |
151 | struct nv50_disp_pior_pwr_v0 v0; | ||
152 | } *args = data; | ||
153 | u32 ctrl, type; | ||
154 | int ret; | ||
155 | |||
156 | nv_ioctl(object, "disp pior pwr size %d\n", size); | ||
157 | if (nvif_unpack(args->v0, 0, 0, false)) { | ||
158 | nv_ioctl(object, "disp pior pwr vers %d state %d type %x\n", | ||
159 | args->v0.version, args->v0.state, args->v0.type); | ||
160 | if (args->v0.type > 0x0f) | ||
161 | return -EINVAL; | ||
162 | ctrl = !!args->v0.state; | ||
163 | type = args->v0.type; | ||
164 | } else | ||
165 | return ret; | ||
166 | |||
150 | nv_wait(priv, 0x61e004 + soff, 0x80000000, 0x00000000); | 167 | nv_wait(priv, 0x61e004 + soff, 0x80000000, 0x00000000); |
151 | nv_mask(priv, 0x61e004 + soff, 0x80000101, 0x80000000 | stat); | 168 | nv_mask(priv, 0x61e004 + soff, 0x80000101, 0x80000000 | ctrl); |
152 | nv_wait(priv, 0x61e004 + soff, 0x80000000, 0x00000000); | 169 | nv_wait(priv, 0x61e004 + soff, 0x80000000, 0x00000000); |
170 | priv->pior.type[outp->or] = type; | ||
153 | return 0; | 171 | return 0; |
154 | } | 172 | } |
155 | |||
156 | int | ||
157 | nv50_pior_mthd(struct nouveau_object *object, u32 mthd, void *args, u32 size) | ||
158 | { | ||
159 | struct nv50_disp_priv *priv = (void *)object->engine; | ||
160 | const u8 type = (mthd & NV50_DISP_PIOR_MTHD_TYPE) >> 12; | ||
161 | const u8 or = (mthd & NV50_DISP_PIOR_MTHD_OR); | ||
162 | u32 *data = args; | ||
163 | int ret; | ||
164 | |||
165 | if (size < sizeof(u32)) | ||
166 | return -EINVAL; | ||
167 | |||
168 | mthd &= ~NV50_DISP_PIOR_MTHD_TYPE; | ||
169 | mthd &= ~NV50_DISP_PIOR_MTHD_OR; | ||
170 | switch (mthd) { | ||
171 | case NV50_DISP_PIOR_PWR: | ||
172 | ret = priv->pior.power(priv, or, data[0]); | ||
173 | priv->pior.type[or] = type; | ||
174 | break; | ||
175 | default: | ||
176 | return -EINVAL; | ||
177 | } | ||
178 | |||
179 | return ret; | ||
180 | } | ||
diff --git a/drivers/gpu/drm/nouveau/core/include/core/class.h b/drivers/gpu/drm/nouveau/core/include/core/class.h index 89dd80e50dcb..9f8066d252f0 100644 --- a/drivers/gpu/drm/nouveau/core/include/core/class.h +++ b/drivers/gpu/drm/nouveau/core/include/core/class.h | |||
@@ -53,23 +53,6 @@ struct nv04_display_scanoutpos { | |||
53 | 53 | ||
54 | #define NV50_DISP_SCANOUTPOS 0x00000000 | 54 | #define NV50_DISP_SCANOUTPOS 0x00000000 |
55 | 55 | ||
56 | #define NV50_DISP_PIOR_MTHD 0x00030000 | ||
57 | #define NV50_DISP_PIOR_MTHD_TYPE 0x0000f000 | ||
58 | #define NV50_DISP_PIOR_MTHD_OR 0x00000003 | ||
59 | |||
60 | #define NV50_DISP_PIOR_PWR 0x00030000 | ||
61 | #define NV50_DISP_PIOR_PWR_STATE 0x00000001 | ||
62 | #define NV50_DISP_PIOR_PWR_STATE_ON 0x00000001 | ||
63 | #define NV50_DISP_PIOR_PWR_STATE_OFF 0x00000000 | ||
64 | #define NV50_DISP_PIOR_TMDS_PWR 0x00032000 | ||
65 | #define NV50_DISP_PIOR_TMDS_PWR_STATE 0x00000001 | ||
66 | #define NV50_DISP_PIOR_TMDS_PWR_STATE_ON 0x00000001 | ||
67 | #define NV50_DISP_PIOR_TMDS_PWR_STATE_OFF 0x00000000 | ||
68 | #define NV50_DISP_PIOR_DP_PWR 0x00036000 | ||
69 | #define NV50_DISP_PIOR_DP_PWR_STATE 0x00000001 | ||
70 | #define NV50_DISP_PIOR_DP_PWR_STATE_ON 0x00000001 | ||
71 | #define NV50_DISP_PIOR_DP_PWR_STATE_OFF 0x00000000 | ||
72 | |||
73 | struct nv50_display_class { | 56 | struct nv50_display_class { |
74 | }; | 57 | }; |
75 | 58 | ||
diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index 844fc4ee72bb..bd85026ee067 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c | |||
@@ -2079,9 +2079,19 @@ nv50_pior_dpms(struct drm_encoder *encoder, int mode) | |||
2079 | { | 2079 | { |
2080 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); | 2080 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); |
2081 | struct nv50_disp *disp = nv50_disp(encoder->dev); | 2081 | struct nv50_disp *disp = nv50_disp(encoder->dev); |
2082 | u32 mthd = (nv_encoder->dcb->type << 12) | nv_encoder->or; | 2082 | struct { |
2083 | u32 ctrl = (mode == DRM_MODE_DPMS_ON); | 2083 | struct nv50_disp_mthd_v1 base; |
2084 | nvif_exec(disp->disp, NV50_DISP_PIOR_PWR + mthd, &ctrl, sizeof(ctrl)); | 2084 | struct nv50_disp_pior_pwr_v0 pwr; |
2085 | } args = { | ||
2086 | .base.version = 1, | ||
2087 | .base.method = NV50_DISP_MTHD_V1_PIOR_PWR, | ||
2088 | .base.hasht = nv_encoder->dcb->hasht, | ||
2089 | .base.hashm = nv_encoder->dcb->hashm, | ||
2090 | .pwr.state = mode == DRM_MODE_DPMS_ON, | ||
2091 | .pwr.type = nv_encoder->dcb->type, | ||
2092 | }; | ||
2093 | |||
2094 | nvif_mthd(disp->disp, 0, &args, sizeof(args)); | ||
2085 | } | 2095 | } |
2086 | 2096 | ||
2087 | static bool | 2097 | static bool |
diff --git a/drivers/gpu/drm/nouveau/nvif/class.h b/drivers/gpu/drm/nouveau/nvif/class.h index e0d45faa46d4..f869f94d41c1 100644 --- a/drivers/gpu/drm/nouveau/nvif/class.h +++ b/drivers/gpu/drm/nouveau/nvif/class.h | |||
@@ -373,4 +373,11 @@ struct nv50_disp_sor_dp_pwr_v0 { | |||
373 | __u8 pad02[6]; | 373 | __u8 pad02[6]; |
374 | }; | 374 | }; |
375 | 375 | ||
376 | struct nv50_disp_pior_pwr_v0 { | ||
377 | __u8 version; | ||
378 | __u8 state; | ||
379 | __u8 type; | ||
380 | __u8 pad03[5]; | ||
381 | }; | ||
382 | |||
376 | #endif | 383 | #endif |