aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2014-08-09 14:10:26 -0400
committerBen Skeggs <bskeggs@redhat.com>2014-08-09 15:28:08 -0400
commit120b0c39c75688864e4a25e71cf3ed40e8e18651 (patch)
treee4b92228177cf74ef73c75493aa314cc4594e111 /drivers/gpu
parentd55b4af909bc16f7982c2b8b8656f0898158627b (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.c28
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/disp/hdanvd0.c28
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/disp/nv50.c4
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/disp/nv50.h6
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/disp/nva3.c1
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c1
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c3
-rw-r--r--drivers/gpu/drm/nouveau/core/include/core/class.h1
-rw-r--r--drivers/gpu/drm/nouveau/nv50_display.c26
-rw-r--r--drivers/gpu/drm/nouveau/nvif/class.h6
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
30int 31int
31nva3_hda_eld(struct nv50_disp_priv *priv, int or, u8 *data, u32 size) 32nva3_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
35int 36int
36nvd0_hda_eld(struct nv50_disp_priv *priv, int or, u8 *data, u32 size) 37nvd0_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
73int nva3_hda_eld(struct nv50_disp_priv *, int, u8 *, u32); 73int nva3_hda_eld(NV50_DISP_MTHD_V1);
74int nvd0_hda_eld(struct nv50_disp_priv *, int, u8 *, u32); 74int nvd0_hda_eld(NV50_DISP_MTHD_V1);
75 75
76int nv84_hdmi_ctrl(struct nv50_disp_priv *, int, int, u32); 76int nv84_hdmi_ctrl(struct nv50_disp_priv *, int, int, u32);
77int nva3_hdmi_ctrl(struct nv50_disp_priv *, int, int, u32); 77int 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[] = {
46static struct nouveau_omthds 46static struct nouveau_omthds
47nva3_disp_base_omthds[] = { 47nva3_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 = {
712struct nouveau_omthds 712struct nouveau_omthds
713nvd0_disp_base_omthds[] = { 713nvd0_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
1685static void 1694static 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
349struct nv50_disp_sor_hda_eld_v0 {
350 __u8 version;
351 __u8 pad01[7];
352 __u8 data[];
353};
354
349#endif 355#endif