diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2014-08-09 14:10:26 -0400 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2014-08-09 15:28:08 -0400 |
commit | 120b0c39c75688864e4a25e71cf3ed40e8e18651 (patch) | |
tree | e4b92228177cf74ef73c75493aa314cc4594e111 /drivers/gpu | |
parent | d55b4af909bc16f7982c2b8b8656f0898158627b (diff) |
drm/nv50-/disp: audit and version SOR_HDA_ELD 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>
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/disp/hdanva3.c | 28 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/disp/hdanvd0.c | 28 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/disp/nv50.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/disp/nv50.h | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/disp/nva3.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/include/core/class.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nv50_display.c | 26 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvif/class.h | 6 |
10 files changed, 75 insertions, 29 deletions
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/hdanva3.c b/drivers/gpu/drm/nouveau/core/engine/disp/hdanva3.c index a19e7d79b847..8b4e06abe533 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/hdanva3.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/hdanva3.c | |||
@@ -22,25 +22,37 @@ | |||
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 "nv50.h" | 29 | #include "nv50.h" |
29 | 30 | ||
30 | int | 31 | int |
31 | nva3_hda_eld(struct nv50_disp_priv *priv, int or, u8 *data, u32 size) | 32 | nva3_hda_eld(NV50_DISP_MTHD_V1) |
32 | { | 33 | { |
33 | const u32 soff = (or * 0x800); | 34 | union { |
34 | int i; | 35 | struct nv50_disp_sor_hda_eld_v0 v0; |
36 | } *args = data; | ||
37 | const u32 soff = outp->or * 0x800; | ||
38 | int ret, i; | ||
35 | 39 | ||
36 | if (data && data[0]) { | 40 | nv_ioctl(object, "disp sor hda eld size %d\n", size); |
41 | if (nvif_unpack(args->v0, 0, 0, true)) { | ||
42 | nv_ioctl(object, "disp sor hda eld vers %d\n", args->v0.version); | ||
43 | if (size > 0x60) | ||
44 | return -E2BIG; | ||
45 | } else | ||
46 | return ret; | ||
47 | |||
48 | if (size && args->v0.data[0]) { | ||
37 | for (i = 0; i < size; i++) | 49 | for (i = 0; i < size; i++) |
38 | nv_wr32(priv, 0x61c440 + soff, (i << 8) | data[i]); | 50 | nv_wr32(priv, 0x61c440 + soff, (i << 8) | args->v0.data[0]); |
39 | for (; i < 0x60; i++) | 51 | for (; i < 0x60; i++) |
40 | nv_wr32(priv, 0x61c440 + soff, (i << 8)); | 52 | nv_wr32(priv, 0x61c440 + soff, (i << 8)); |
41 | nv_mask(priv, 0x61c448 + soff, 0x80000003, 0x80000003); | 53 | nv_mask(priv, 0x61c448 + soff, 0x80000003, 0x80000003); |
42 | } else | 54 | } else |
43 | if (data) { | 55 | if (size) { |
44 | nv_mask(priv, 0x61c448 + soff, 0x80000003, 0x80000001); | 56 | nv_mask(priv, 0x61c448 + soff, 0x80000003, 0x80000001); |
45 | } else { | 57 | } else { |
46 | nv_mask(priv, 0x61c448 + soff, 0x80000003, 0x80000000); | 58 | nv_mask(priv, 0x61c448 + soff, 0x80000003, 0x80000000); |
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/hdanvd0.c b/drivers/gpu/drm/nouveau/core/engine/disp/hdanvd0.c index 717639386ced..baf558fc12fb 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/hdanvd0.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/hdanvd0.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> |
@@ -33,19 +34,30 @@ | |||
33 | #include "nv50.h" | 34 | #include "nv50.h" |
34 | 35 | ||
35 | int | 36 | int |
36 | nvd0_hda_eld(struct nv50_disp_priv *priv, int or, u8 *data, u32 size) | 37 | nvd0_hda_eld(NV50_DISP_MTHD_V1) |
37 | { | 38 | { |
38 | const u32 soff = (or * 0x030); | 39 | union { |
39 | int i; | 40 | struct nv50_disp_sor_hda_eld_v0 v0; |
41 | } *args = data; | ||
42 | const u32 soff = outp->or * 0x030; | ||
43 | int ret, i; | ||
40 | 44 | ||
41 | if (data && data[0]) { | 45 | nv_ioctl(object, "disp sor hda eld size %d\n", size); |
46 | if (nvif_unpack(args->v0, 0, 0, true)) { | ||
47 | nv_ioctl(object, "disp sor hda eld vers %d\n", args->v0.version); | ||
48 | if (size > 0x60) | ||
49 | return -E2BIG; | ||
50 | } else | ||
51 | return ret; | ||
52 | |||
53 | if (size && args->v0.data[0]) { | ||
42 | for (i = 0; i < size; i++) | 54 | for (i = 0; i < size; i++) |
43 | nv_wr32(priv, 0x10ec00 + soff, (i << 8) | data[i]); | 55 | nv_wr32(priv, 0x10ec00 + soff, (i << 8) | args->v0.data[i]); |
44 | for (; i < 0x60; i++) | 56 | for (; i < 0x60; i++) |
45 | nv_wr32(priv, 0x10ec00 + soff, (i << 8)); | 57 | nv_wr32(priv, 0x10ec00 + soff, (i << 8)); |
46 | nv_mask(priv, 0x10ec10 + soff, 0x80000003, 0x80000003); | 58 | nv_mask(priv, 0x10ec10 + soff, 0x80000003, 0x80000003); |
47 | } else | 59 | } else |
48 | if (data) { | 60 | if (size) { |
49 | nv_mask(priv, 0x10ec10 + soff, 0x80000003, 0x80000001); | 61 | nv_mask(priv, 0x10ec10 + soff, 0x80000003, 0x80000001); |
50 | } else { | 62 | } else { |
51 | nv_mask(priv, 0x10ec10 + soff, 0x80000003, 0x80000000); | 63 | nv_mask(priv, 0x10ec10 + soff, 0x80000003, 0x80000000); |
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c index 869789ff8ea3..9381b161f309 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c | |||
@@ -905,6 +905,10 @@ nv50_disp_base_mthd(struct nouveau_object *object, u32 mthd, | |||
905 | return priv->dac.sense(object, priv, data, size, head, outp); | 905 | return priv->dac.sense(object, priv, data, size, head, outp); |
906 | case NV50_DISP_MTHD_V1_SOR_PWR: | 906 | case NV50_DISP_MTHD_V1_SOR_PWR: |
907 | return priv->sor.power(object, priv, data, size, head, outp); | 907 | return priv->sor.power(object, priv, data, size, head, outp); |
908 | case NV50_DISP_MTHD_V1_SOR_HDA_ELD: | ||
909 | if (!priv->sor.hda_eld) | ||
910 | return -ENODEV; | ||
911 | return priv->sor.hda_eld(object, priv, data, size, head, outp); | ||
908 | default: | 912 | default: |
909 | break; | 913 | break; |
910 | } | 914 | } |
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.h b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.h index ea9f37d1cb27..a09875fedcf8 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.h +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.h | |||
@@ -47,7 +47,7 @@ struct nv50_disp_priv { | |||
47 | struct { | 47 | struct { |
48 | int nr; | 48 | int nr; |
49 | int (*power)(NV50_DISP_MTHD_V1); | 49 | int (*power)(NV50_DISP_MTHD_V1); |
50 | int (*hda_eld)(struct nv50_disp_priv *, int sor, u8 *, u32); | 50 | int (*hda_eld)(NV50_DISP_MTHD_V1); |
51 | int (*hdmi)(struct nv50_disp_priv *, int head, int sor, u32); | 51 | int (*hdmi)(struct nv50_disp_priv *, int head, int sor, u32); |
52 | u32 lvdsconf; | 52 | u32 lvdsconf; |
53 | } sor; | 53 | } sor; |
@@ -70,8 +70,8 @@ int nv50_dac_sense(NV50_DISP_MTHD_V1); | |||
70 | 70 | ||
71 | #define SOR_MTHD(n) (n), (n) + 0x3f | 71 | #define SOR_MTHD(n) (n), (n) + 0x3f |
72 | 72 | ||
73 | int nva3_hda_eld(struct nv50_disp_priv *, int, u8 *, u32); | 73 | int nva3_hda_eld(NV50_DISP_MTHD_V1); |
74 | int nvd0_hda_eld(struct nv50_disp_priv *, int, u8 *, u32); | 74 | int nvd0_hda_eld(NV50_DISP_MTHD_V1); |
75 | 75 | ||
76 | int nv84_hdmi_ctrl(struct nv50_disp_priv *, int, int, u32); | 76 | int nv84_hdmi_ctrl(struct nv50_disp_priv *, int, int, u32); |
77 | int nva3_hdmi_ctrl(struct nv50_disp_priv *, int, int, u32); | 77 | int nva3_hdmi_ctrl(struct nv50_disp_priv *, int, int, u32); |
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nva3.c b/drivers/gpu/drm/nouveau/core/engine/disp/nva3.c index 92a54bdae6e0..ca42d7913f4e 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nva3.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nva3.c | |||
@@ -46,7 +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 | { SOR_MTHD(NVA3_DISP_SOR_HDA_ELD) , nv50_sor_mthd }, | ||
50 | { SOR_MTHD(NV84_DISP_SOR_HDMI_PWR) , nv50_sor_mthd }, | 49 | { SOR_MTHD(NV84_DISP_SOR_HDMI_PWR) , nv50_sor_mthd }, |
51 | { SOR_MTHD(NV50_DISP_SOR_LVDS_SCRIPT) , nv50_sor_mthd }, | 50 | { SOR_MTHD(NV50_DISP_SOR_LVDS_SCRIPT) , nv50_sor_mthd }, |
52 | { SOR_MTHD(NV94_DISP_SOR_DP_PWR) , nv50_sor_mthd }, | 51 | { SOR_MTHD(NV94_DISP_SOR_DP_PWR) , nv50_sor_mthd }, |
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c b/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c index 27c9e9ee5291..77fe8cc633c7 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c | |||
@@ -712,7 +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 | { SOR_MTHD(NVA3_DISP_SOR_HDA_ELD) , nv50_sor_mthd }, | ||
716 | { SOR_MTHD(NV84_DISP_SOR_HDMI_PWR) , nv50_sor_mthd }, | 715 | { SOR_MTHD(NV84_DISP_SOR_HDMI_PWR) , nv50_sor_mthd }, |
717 | { SOR_MTHD(NV50_DISP_SOR_LVDS_SCRIPT) , nv50_sor_mthd }, | 716 | { SOR_MTHD(NV50_DISP_SOR_LVDS_SCRIPT) , nv50_sor_mthd }, |
718 | { SOR_MTHD(NV94_DISP_SOR_DP_PWR) , nv50_sor_mthd }, | 717 | { SOR_MTHD(NV94_DISP_SOR_DP_PWR) , nv50_sor_mthd }, |
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c b/drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c index 16b19d47b40e..be7e235e9553 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c | |||
@@ -84,9 +84,6 @@ nv50_sor_mthd(struct nouveau_object *object, u32 mthd, void *args, u32 size) | |||
84 | } | 84 | } |
85 | 85 | ||
86 | switch (mthd & ~0x3f) { | 86 | switch (mthd & ~0x3f) { |
87 | case NVA3_DISP_SOR_HDA_ELD: | ||
88 | ret = priv->sor.hda_eld(priv, or, args, size); | ||
89 | break; | ||
90 | case NV84_DISP_SOR_HDMI_PWR: | 87 | case NV84_DISP_SOR_HDMI_PWR: |
91 | ret = priv->sor.hdmi(priv, head, or, data); | 88 | ret = priv->sor.hdmi(priv, head, or, data); |
92 | break; | 89 | break; |
diff --git a/drivers/gpu/drm/nouveau/core/include/core/class.h b/drivers/gpu/drm/nouveau/core/include/core/class.h index 98733df661b0..234e1175f038 100644 --- a/drivers/gpu/drm/nouveau/core/include/core/class.h +++ b/drivers/gpu/drm/nouveau/core/include/core/class.h | |||
@@ -59,7 +59,6 @@ struct nv04_display_scanoutpos { | |||
59 | #define NV50_DISP_SOR_MTHD_LINK 0x00000004 | 59 | #define NV50_DISP_SOR_MTHD_LINK 0x00000004 |
60 | #define NV50_DISP_SOR_MTHD_OR 0x00000003 | 60 | #define NV50_DISP_SOR_MTHD_OR 0x00000003 |
61 | 61 | ||
62 | #define NVA3_DISP_SOR_HDA_ELD 0x00010100 | ||
63 | #define NV84_DISP_SOR_HDMI_PWR 0x00012000 | 62 | #define NV84_DISP_SOR_HDMI_PWR 0x00012000 |
64 | #define NV84_DISP_SOR_HDMI_PWR_STATE 0x40000000 | 63 | #define NV84_DISP_SOR_HDMI_PWR_STATE 0x40000000 |
65 | #define NV84_DISP_SOR_HDMI_PWR_STATE_OFF 0x00000000 | 64 | #define NV84_DISP_SOR_HDMI_PWR_STATE_OFF 0x00000000 |
diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index dc7f63f0177c..543ddb96feef 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c | |||
@@ -1670,16 +1670,25 @@ nv50_audio_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode) | |||
1670 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); | 1670 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); |
1671 | struct nouveau_connector *nv_connector; | 1671 | struct nouveau_connector *nv_connector; |
1672 | struct nv50_disp *disp = nv50_disp(encoder->dev); | 1672 | struct nv50_disp *disp = nv50_disp(encoder->dev); |
1673 | struct { | ||
1674 | struct nv50_disp_mthd_v1 base; | ||
1675 | struct nv50_disp_sor_hda_eld_v0 eld; | ||
1676 | u8 data[sizeof(nv_connector->base.eld)]; | ||
1677 | } args = { | ||
1678 | .base.version = 1, | ||
1679 | .base.method = NV50_DISP_MTHD_V1_SOR_HDA_ELD, | ||
1680 | .base.hasht = nv_encoder->dcb->hasht, | ||
1681 | .base.hashm = nv_encoder->dcb->hashm, | ||
1682 | }; | ||
1673 | 1683 | ||
1674 | nv_connector = nouveau_encoder_connector_get(nv_encoder); | 1684 | nv_connector = nouveau_encoder_connector_get(nv_encoder); |
1675 | if (!drm_detect_monitor_audio(nv_connector->edid)) | 1685 | if (!drm_detect_monitor_audio(nv_connector->edid)) |
1676 | return; | 1686 | return; |
1677 | 1687 | ||
1678 | drm_edid_to_eld(&nv_connector->base, nv_connector->edid); | 1688 | drm_edid_to_eld(&nv_connector->base, nv_connector->edid); |
1689 | memcpy(args.data, nv_connector->base.eld, sizeof(args.data)); | ||
1679 | 1690 | ||
1680 | nvif_exec(disp->disp, NVA3_DISP_SOR_HDA_ELD + nv_encoder->or, | 1691 | nvif_mthd(disp->disp, 0, &args, sizeof(args)); |
1681 | nv_connector->base.eld, | ||
1682 | nv_connector->base.eld[2] * 4); | ||
1683 | } | 1692 | } |
1684 | 1693 | ||
1685 | static void | 1694 | static void |
@@ -1687,8 +1696,17 @@ nv50_audio_disconnect(struct drm_encoder *encoder) | |||
1687 | { | 1696 | { |
1688 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); | 1697 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); |
1689 | struct nv50_disp *disp = nv50_disp(encoder->dev); | 1698 | struct nv50_disp *disp = nv50_disp(encoder->dev); |
1699 | struct { | ||
1700 | struct nv50_disp_mthd_v1 base; | ||
1701 | struct nv50_disp_sor_hda_eld_v0 eld; | ||
1702 | } args = { | ||
1703 | .base.version = 1, | ||
1704 | .base.method = NV50_DISP_MTHD_V1_SOR_HDA_ELD, | ||
1705 | .base.hasht = nv_encoder->dcb->hasht, | ||
1706 | .base.hashm = nv_encoder->dcb->hashm, | ||
1707 | }; | ||
1690 | 1708 | ||
1691 | nvif_exec(disp->disp, NVA3_DISP_SOR_HDA_ELD + nv_encoder->or, NULL, 0); | 1709 | nvif_mthd(disp->disp, 0, &args, sizeof(args)); |
1692 | } | 1710 | } |
1693 | 1711 | ||
1694 | /****************************************************************************** | 1712 | /****************************************************************************** |
diff --git a/drivers/gpu/drm/nouveau/nvif/class.h b/drivers/gpu/drm/nouveau/nvif/class.h index 4afc264bab73..84d2926dd069 100644 --- a/drivers/gpu/drm/nouveau/nvif/class.h +++ b/drivers/gpu/drm/nouveau/nvif/class.h | |||
@@ -346,4 +346,10 @@ struct nv50_disp_sor_pwr_v0 { | |||
346 | __u8 pad02[6]; | 346 | __u8 pad02[6]; |
347 | }; | 347 | }; |
348 | 348 | ||
349 | struct nv50_disp_sor_hda_eld_v0 { | ||
350 | __u8 version; | ||
351 | __u8 pad01[7]; | ||
352 | __u8 data[]; | ||
353 | }; | ||
354 | |||
349 | #endif | 355 | #endif |