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:09 -0400 |
commit | e00f2235386484cc1920dd99d17beac2a8dc4a95 (patch) | |
tree | fe61b4a6bd6c44ba668dcb3687b6a7e6049c7bae | |
parent | 120b0c39c75688864e4a25e71cf3ed40e8e18651 (diff) |
drm/nv50-/disp: audit and version SOR_HDMI_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/hdminv84.c | 31 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/disp/hdminva3.c | 33 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/disp/hdminvd0.c | 30 | ||||
-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 | 8 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/disp/nv84.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/disp/nv94.c | 1 | ||||
-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 | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nv50_display.c | 39 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvif/class.h | 8 |
13 files changed, 121 insertions, 45 deletions
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/hdminv84.c b/drivers/gpu/drm/nouveau/core/engine/disp/hdminv84.c index 7fdade6e604d..fa276dede9cd 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/hdminv84.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/hdminv84.c | |||
@@ -22,17 +22,38 @@ | |||
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 | nv84_hdmi_ctrl(struct nv50_disp_priv *priv, int head, int or, u32 data) | 32 | nv84_hdmi_ctrl(NV50_DISP_MTHD_V1) |
32 | { | 33 | { |
33 | const u32 hoff = (head * 0x800); | 34 | const u32 hoff = (head * 0x800); |
35 | union { | ||
36 | struct nv50_disp_sor_hdmi_pwr_v0 v0; | ||
37 | } *args = data; | ||
38 | u32 ctrl; | ||
39 | int ret; | ||
34 | 40 | ||
35 | if (!(data & NV84_DISP_SOR_HDMI_PWR_STATE_ON)) { | 41 | nv_ioctl(object, "disp sor hdmi ctrl size %d\n", size); |
42 | if (nvif_unpack(args->v0, 0, 0, false)) { | ||
43 | nv_ioctl(object, "disp sor hdmi ctrl vers %d state %d " | ||
44 | "max_ac_packet %d rekey %d\n", | ||
45 | args->v0.version, args->v0.state, | ||
46 | args->v0.max_ac_packet, args->v0.rekey); | ||
47 | if (args->v0.max_ac_packet > 0x1f || args->v0.rekey > 0x7f) | ||
48 | return -EINVAL; | ||
49 | ctrl = 0x40000000 * !!args->v0.state; | ||
50 | ctrl |= args->v0.max_ac_packet << 16; | ||
51 | ctrl |= args->v0.rekey; | ||
52 | ctrl |= 0x1f000000; /* ??? */ | ||
53 | } else | ||
54 | return ret; | ||
55 | |||
56 | if (!(ctrl & 0x40000000)) { | ||
36 | nv_mask(priv, 0x6165a4 + hoff, 0x40000000, 0x00000000); | 57 | nv_mask(priv, 0x6165a4 + hoff, 0x40000000, 0x00000000); |
37 | nv_mask(priv, 0x616520 + hoff, 0x00000001, 0x00000000); | 58 | nv_mask(priv, 0x616520 + hoff, 0x00000001, 0x00000000); |
38 | nv_mask(priv, 0x616500 + hoff, 0x00000001, 0x00000000); | 59 | nv_mask(priv, 0x616500 + hoff, 0x00000001, 0x00000000); |
@@ -65,6 +86,6 @@ nv84_hdmi_ctrl(struct nv50_disp_priv *priv, int head, int or, u32 data) | |||
65 | nv_mask(priv, 0x61733c, 0x00100000, 0x00000000); /* !RESETF */ | 86 | nv_mask(priv, 0x61733c, 0x00100000, 0x00000000); /* !RESETF */ |
66 | 87 | ||
67 | /* HDMI_CTRL */ | 88 | /* HDMI_CTRL */ |
68 | nv_mask(priv, 0x6165a4 + hoff, 0x5f1f007f, data | 0x1f000000 /* ??? */); | 89 | nv_mask(priv, 0x6165a4 + hoff, 0x5f1f007f, ctrl); |
69 | return 0; | 90 | return 0; |
70 | } | 91 | } |
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/hdminva3.c b/drivers/gpu/drm/nouveau/core/engine/disp/hdminva3.c index db8c6fd46278..57eeed1d1942 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/hdminva3.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/hdminva3.c | |||
@@ -22,17 +22,38 @@ | |||
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_hdmi_ctrl(struct nv50_disp_priv *priv, int head, int or, u32 data) | 32 | nva3_hdmi_ctrl(NV50_DISP_MTHD_V1) |
32 | { | 33 | { |
33 | const u32 soff = (or * 0x800); | 34 | const u32 soff = outp->or * 0x800; |
35 | union { | ||
36 | struct nv50_disp_sor_hdmi_pwr_v0 v0; | ||
37 | } *args = data; | ||
38 | u32 ctrl; | ||
39 | int ret; | ||
34 | 40 | ||
35 | if (!(data & NV84_DISP_SOR_HDMI_PWR_STATE_ON)) { | 41 | nv_ioctl(object, "disp sor hdmi ctrl size %d\n", size); |
42 | if (nvif_unpack(args->v0, 0, 0, false)) { | ||
43 | nv_ioctl(object, "disp sor hdmi ctrl vers %d state %d " | ||
44 | "max_ac_packet %d rekey %d\n", | ||
45 | args->v0.version, args->v0.state, | ||
46 | args->v0.max_ac_packet, args->v0.rekey); | ||
47 | if (args->v0.max_ac_packet > 0x1f || args->v0.rekey > 0x7f) | ||
48 | return -EINVAL; | ||
49 | ctrl = 0x40000000 * !!args->v0.state; | ||
50 | ctrl |= args->v0.max_ac_packet << 16; | ||
51 | ctrl |= args->v0.rekey; | ||
52 | ctrl |= 0x1f000000; /* ??? */ | ||
53 | } else | ||
54 | return ret; | ||
55 | |||
56 | if (!(ctrl & 0x40000000)) { | ||
36 | nv_mask(priv, 0x61c5a4 + soff, 0x40000000, 0x00000000); | 57 | nv_mask(priv, 0x61c5a4 + soff, 0x40000000, 0x00000000); |
37 | nv_mask(priv, 0x61c520 + soff, 0x00000001, 0x00000000); | 58 | nv_mask(priv, 0x61c520 + soff, 0x00000001, 0x00000000); |
38 | nv_mask(priv, 0x61c500 + soff, 0x00000001, 0x00000000); | 59 | nv_mask(priv, 0x61c500 + soff, 0x00000001, 0x00000000); |
@@ -65,6 +86,6 @@ nva3_hdmi_ctrl(struct nv50_disp_priv *priv, int head, int or, u32 data) | |||
65 | nv_mask(priv, 0x61733c, 0x00100000, 0x00000000); /* !RESETF */ | 86 | nv_mask(priv, 0x61733c, 0x00100000, 0x00000000); /* !RESETF */ |
66 | 87 | ||
67 | /* HDMI_CTRL */ | 88 | /* HDMI_CTRL */ |
68 | nv_mask(priv, 0x61c5a4 + soff, 0x5f1f007f, data | 0x1f000000 /* ??? */); | 89 | nv_mask(priv, 0x61c5a4 + soff, 0x5f1f007f, ctrl); |
69 | return 0; | 90 | return 0; |
70 | } | 91 | } |
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/hdminvd0.c b/drivers/gpu/drm/nouveau/core/engine/disp/hdminvd0.c index 5151bb261832..3106d295b48d 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/hdminvd0.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/hdminvd0.c | |||
@@ -22,17 +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 | nvd0_hdmi_ctrl(struct nv50_disp_priv *priv, int head, int or, u32 data) | 32 | nvd0_hdmi_ctrl(NV50_DISP_MTHD_V1) |
32 | { | 33 | { |
33 | const u32 hoff = (head * 0x800); | 34 | const u32 hoff = (head * 0x800); |
35 | union { | ||
36 | struct nv50_disp_sor_hdmi_pwr_v0 v0; | ||
37 | } *args = data; | ||
38 | u32 ctrl; | ||
39 | int ret; | ||
34 | 40 | ||
35 | if (!(data & NV84_DISP_SOR_HDMI_PWR_STATE_ON)) { | 41 | nv_ioctl(object, "disp sor hdmi ctrl size %d\n", size); |
42 | if (nvif_unpack(args->v0, 0, 0, false)) { | ||
43 | nv_ioctl(object, "disp sor hdmi ctrl vers %d state %d " | ||
44 | "max_ac_packet %d rekey %d\n", | ||
45 | args->v0.version, args->v0.state, | ||
46 | args->v0.max_ac_packet, args->v0.rekey); | ||
47 | if (args->v0.max_ac_packet > 0x1f || args->v0.rekey > 0x7f) | ||
48 | return -EINVAL; | ||
49 | ctrl = 0x40000000 * !!args->v0.state; | ||
50 | ctrl |= args->v0.max_ac_packet << 16; | ||
51 | ctrl |= args->v0.rekey; | ||
52 | } else | ||
53 | return ret; | ||
54 | |||
55 | if (!(ctrl & 0x40000000)) { | ||
36 | nv_mask(priv, 0x616798 + hoff, 0x40000000, 0x00000000); | 56 | nv_mask(priv, 0x616798 + hoff, 0x40000000, 0x00000000); |
37 | nv_mask(priv, 0x6167a4 + hoff, 0x00000001, 0x00000000); | 57 | nv_mask(priv, 0x6167a4 + hoff, 0x00000001, 0x00000000); |
38 | nv_mask(priv, 0x616714 + hoff, 0x00000001, 0x00000000); | 58 | nv_mask(priv, 0x616714 + hoff, 0x00000001, 0x00000000); |
@@ -54,7 +74,7 @@ nvd0_hdmi_ctrl(struct nv50_disp_priv *priv, int head, int or, u32 data) | |||
54 | nv_mask(priv, 0x6167a4 + hoff, 0x00000001, 0x00000001); | 74 | nv_mask(priv, 0x6167a4 + hoff, 0x00000001, 0x00000001); |
55 | 75 | ||
56 | /* HDMI_CTRL */ | 76 | /* HDMI_CTRL */ |
57 | nv_mask(priv, 0x616798 + hoff, 0x401f007f, data); | 77 | nv_mask(priv, 0x616798 + hoff, 0x401f007f, ctrl); |
58 | 78 | ||
59 | /* NFI, audio doesn't work without it though.. */ | 79 | /* NFI, audio doesn't work without it though.. */ |
60 | nv_mask(priv, 0x616548 + hoff, 0x00000070, 0x00000000); | 80 | nv_mask(priv, 0x616548 + hoff, 0x00000070, 0x00000000); |
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c index 9381b161f309..bb5caa7e2176 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c | |||
@@ -909,6 +909,10 @@ nv50_disp_base_mthd(struct nouveau_object *object, u32 mthd, | |||
909 | if (!priv->sor.hda_eld) | 909 | if (!priv->sor.hda_eld) |
910 | return -ENODEV; | 910 | return -ENODEV; |
911 | return priv->sor.hda_eld(object, priv, data, size, head, outp); | 911 | return priv->sor.hda_eld(object, priv, data, size, head, outp); |
912 | case NV50_DISP_MTHD_V1_SOR_HDMI_PWR: | ||
913 | if (!priv->sor.hdmi) | ||
914 | return -ENODEV; | ||
915 | return priv->sor.hdmi(object, priv, data, size, head, outp); | ||
912 | default: | 916 | default: |
913 | break; | 917 | break; |
914 | } | 918 | } |
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.h b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.h index a09875fedcf8..a9c8e19d0e2b 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.h +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.h | |||
@@ -48,7 +48,7 @@ struct nv50_disp_priv { | |||
48 | int nr; | 48 | int nr; |
49 | int (*power)(NV50_DISP_MTHD_V1); | 49 | int (*power)(NV50_DISP_MTHD_V1); |
50 | int (*hda_eld)(NV50_DISP_MTHD_V1); | 50 | int (*hda_eld)(NV50_DISP_MTHD_V1); |
51 | int (*hdmi)(struct nv50_disp_priv *, int head, int sor, u32); | 51 | int (*hdmi)(NV50_DISP_MTHD_V1); |
52 | u32 lvdsconf; | 52 | u32 lvdsconf; |
53 | } sor; | 53 | } sor; |
54 | struct { | 54 | struct { |
@@ -73,9 +73,9 @@ int nv50_dac_sense(NV50_DISP_MTHD_V1); | |||
73 | int nva3_hda_eld(NV50_DISP_MTHD_V1); | 73 | int nva3_hda_eld(NV50_DISP_MTHD_V1); |
74 | int nvd0_hda_eld(NV50_DISP_MTHD_V1); | 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(NV50_DISP_MTHD_V1); |
77 | int nva3_hdmi_ctrl(struct nv50_disp_priv *, int, int, u32); | 77 | int nva3_hdmi_ctrl(NV50_DISP_MTHD_V1); |
78 | int nvd0_hdmi_ctrl(struct nv50_disp_priv *, int, int, u32); | 78 | int nvd0_hdmi_ctrl(NV50_DISP_MTHD_V1); |
79 | 79 | ||
80 | int nv50_sor_mthd(struct nouveau_object *, u32, void *, u32); | 80 | int nv50_sor_mthd(struct nouveau_object *, u32, void *, u32); |
81 | int nv50_sor_power(NV50_DISP_MTHD_V1); | 81 | int nv50_sor_power(NV50_DISP_MTHD_V1); |
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv84.c b/drivers/gpu/drm/nouveau/core/engine/disp/nv84.c index 81a0e8d6c848..49cbecf981e6 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nv84.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv84.c | |||
@@ -215,7 +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 | { SOR_MTHD(NV84_DISP_SOR_HDMI_PWR) , nv50_sor_mthd }, | ||
219 | { SOR_MTHD(NV50_DISP_SOR_LVDS_SCRIPT) , nv50_sor_mthd }, | 218 | { SOR_MTHD(NV50_DISP_SOR_LVDS_SCRIPT) , nv50_sor_mthd }, |
220 | { PIOR_MTHD(NV50_DISP_PIOR_PWR) , nv50_pior_mthd }, | 219 | { PIOR_MTHD(NV50_DISP_PIOR_PWR) , nv50_pior_mthd }, |
221 | { PIOR_MTHD(NV50_DISP_PIOR_TMDS_PWR) , nv50_pior_mthd }, | 220 | { PIOR_MTHD(NV50_DISP_PIOR_TMDS_PWR) , nv50_pior_mthd }, |
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv94.c b/drivers/gpu/drm/nouveau/core/engine/disp/nv94.c index ca8bab4844c1..7234237f4031 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nv94.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv94.c | |||
@@ -74,7 +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 | { SOR_MTHD(NV84_DISP_SOR_HDMI_PWR) , nv50_sor_mthd }, | ||
78 | { SOR_MTHD(NV50_DISP_SOR_LVDS_SCRIPT) , nv50_sor_mthd }, | 77 | { SOR_MTHD(NV50_DISP_SOR_LVDS_SCRIPT) , nv50_sor_mthd }, |
79 | { SOR_MTHD(NV94_DISP_SOR_DP_PWR) , nv50_sor_mthd }, | 78 | { SOR_MTHD(NV94_DISP_SOR_DP_PWR) , nv50_sor_mthd }, |
80 | { PIOR_MTHD(NV50_DISP_PIOR_PWR) , nv50_pior_mthd }, | 79 | { PIOR_MTHD(NV50_DISP_PIOR_PWR) , nv50_pior_mthd }, |
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nva3.c b/drivers/gpu/drm/nouveau/core/engine/disp/nva3.c index ca42d7913f4e..488623386cba 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(NV84_DISP_SOR_HDMI_PWR) , nv50_sor_mthd }, | ||
50 | { SOR_MTHD(NV50_DISP_SOR_LVDS_SCRIPT) , nv50_sor_mthd }, | 49 | { SOR_MTHD(NV50_DISP_SOR_LVDS_SCRIPT) , nv50_sor_mthd }, |
51 | { SOR_MTHD(NV94_DISP_SOR_DP_PWR) , nv50_sor_mthd }, | 50 | { SOR_MTHD(NV94_DISP_SOR_DP_PWR) , nv50_sor_mthd }, |
52 | { PIOR_MTHD(NV50_DISP_PIOR_PWR) , nv50_pior_mthd }, | 51 | { PIOR_MTHD(NV50_DISP_PIOR_PWR) , nv50_pior_mthd }, |
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c b/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c index 77fe8cc633c7..7f035f33f25e 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(NV84_DISP_SOR_HDMI_PWR) , nv50_sor_mthd }, | ||
716 | { SOR_MTHD(NV50_DISP_SOR_LVDS_SCRIPT) , nv50_sor_mthd }, | 715 | { SOR_MTHD(NV50_DISP_SOR_LVDS_SCRIPT) , nv50_sor_mthd }, |
717 | { SOR_MTHD(NV94_DISP_SOR_DP_PWR) , nv50_sor_mthd }, | 716 | { SOR_MTHD(NV94_DISP_SOR_DP_PWR) , nv50_sor_mthd }, |
718 | { PIOR_MTHD(NV50_DISP_PIOR_PWR) , nv50_pior_mthd }, | 717 | { PIOR_MTHD(NV50_DISP_PIOR_PWR) , nv50_pior_mthd }, |
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c b/drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c index be7e235e9553..5f2d71c3f71e 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 NV84_DISP_SOR_HDMI_PWR: | ||
88 | ret = priv->sor.hdmi(priv, head, or, data); | ||
89 | break; | ||
90 | case NV50_DISP_SOR_LVDS_SCRIPT: | 87 | case NV50_DISP_SOR_LVDS_SCRIPT: |
91 | priv->sor.lvdsconf = data & NV50_DISP_SOR_LVDS_SCRIPT_ID; | 88 | priv->sor.lvdsconf = data & NV50_DISP_SOR_LVDS_SCRIPT_ID; |
92 | ret = 0; | 89 | ret = 0; |
diff --git a/drivers/gpu/drm/nouveau/core/include/core/class.h b/drivers/gpu/drm/nouveau/core/include/core/class.h index 234e1175f038..e54d9cc54887 100644 --- a/drivers/gpu/drm/nouveau/core/include/core/class.h +++ b/drivers/gpu/drm/nouveau/core/include/core/class.h | |||
@@ -59,12 +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 NV84_DISP_SOR_HDMI_PWR 0x00012000 | ||
63 | #define NV84_DISP_SOR_HDMI_PWR_STATE 0x40000000 | ||
64 | #define NV84_DISP_SOR_HDMI_PWR_STATE_OFF 0x00000000 | ||
65 | #define NV84_DISP_SOR_HDMI_PWR_STATE_ON 0x40000000 | ||
66 | #define NV84_DISP_SOR_HDMI_PWR_MAX_AC_PACKET 0x001f0000 | ||
67 | #define NV84_DISP_SOR_HDMI_PWR_REKEY 0x0000007f | ||
68 | #define NV50_DISP_SOR_LVDS_SCRIPT 0x00013000 | 62 | #define NV50_DISP_SOR_LVDS_SCRIPT 0x00013000 |
69 | #define NV50_DISP_SOR_LVDS_SCRIPT_ID 0x0000ffff | 63 | #define NV50_DISP_SOR_LVDS_SCRIPT_ID 0x0000ffff |
70 | #define NV94_DISP_SOR_DP_PWR 0x00016000 | 64 | #define NV94_DISP_SOR_DP_PWR 0x00016000 |
diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index 543ddb96feef..e83ed52da239 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c | |||
@@ -1717,25 +1717,32 @@ nv50_hdmi_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode) | |||
1717 | { | 1717 | { |
1718 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); | 1718 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); |
1719 | struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc); | 1719 | struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc); |
1720 | struct nouveau_connector *nv_connector; | ||
1721 | struct nv50_disp *disp = nv50_disp(encoder->dev); | 1720 | struct nv50_disp *disp = nv50_disp(encoder->dev); |
1722 | const u32 moff = (nv_crtc->index << 3) | nv_encoder->or; | 1721 | struct { |
1723 | u32 rekey = 56; /* binary driver, and tegra constant */ | 1722 | struct nv50_disp_mthd_v1 base; |
1723 | struct nv50_disp_sor_hdmi_pwr_v0 pwr; | ||
1724 | } args = { | ||
1725 | .base.version = 1, | ||
1726 | .base.method = NV50_DISP_MTHD_V1_SOR_HDMI_PWR, | ||
1727 | .base.hasht = nv_encoder->dcb->hasht, | ||
1728 | .base.hashm = (0xf0ff & nv_encoder->dcb->hashm) | | ||
1729 | (0x0100 << nv_crtc->index), | ||
1730 | .pwr.state = 1, | ||
1731 | .pwr.rekey = 56, /* binary driver, and tegra, constant */ | ||
1732 | }; | ||
1733 | struct nouveau_connector *nv_connector; | ||
1724 | u32 max_ac_packet; | 1734 | u32 max_ac_packet; |
1725 | u32 data; | ||
1726 | 1735 | ||
1727 | nv_connector = nouveau_encoder_connector_get(nv_encoder); | 1736 | nv_connector = nouveau_encoder_connector_get(nv_encoder); |
1728 | if (!drm_detect_hdmi_monitor(nv_connector->edid)) | 1737 | if (!drm_detect_hdmi_monitor(nv_connector->edid)) |
1729 | return; | 1738 | return; |
1730 | 1739 | ||
1731 | max_ac_packet = mode->htotal - mode->hdisplay; | 1740 | max_ac_packet = mode->htotal - mode->hdisplay; |
1732 | max_ac_packet -= rekey; | 1741 | max_ac_packet -= args.pwr.rekey; |
1733 | max_ac_packet -= 18; /* constant from tegra */ | 1742 | max_ac_packet -= 18; /* constant from tegra */ |
1734 | max_ac_packet /= 32; | 1743 | args.pwr.max_ac_packet = max_ac_packet / 32; |
1735 | |||
1736 | data = NV84_DISP_SOR_HDMI_PWR_STATE_ON | (max_ac_packet << 16) | rekey; | ||
1737 | nvif_exec(disp->disp, NV84_DISP_SOR_HDMI_PWR + moff, &data, sizeof(data)); | ||
1738 | 1744 | ||
1745 | nvif_mthd(disp->disp, 0, &args, sizeof(args)); | ||
1739 | nv50_audio_mode_set(encoder, mode); | 1746 | nv50_audio_mode_set(encoder, mode); |
1740 | } | 1747 | } |
1741 | 1748 | ||
@@ -1744,12 +1751,20 @@ nv50_hdmi_disconnect(struct drm_encoder *encoder, struct nouveau_crtc *nv_crtc) | |||
1744 | { | 1751 | { |
1745 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); | 1752 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); |
1746 | struct nv50_disp *disp = nv50_disp(encoder->dev); | 1753 | struct nv50_disp *disp = nv50_disp(encoder->dev); |
1747 | const u32 moff = (nv_crtc->index << 3) | nv_encoder->or; | 1754 | struct { |
1748 | u32 data = 0; | 1755 | struct nv50_disp_mthd_v1 base; |
1756 | struct nv50_disp_sor_hdmi_pwr_v0 pwr; | ||
1757 | } args = { | ||
1758 | .base.version = 1, | ||
1759 | .base.method = NV50_DISP_MTHD_V1_SOR_HDMI_PWR, | ||
1760 | .base.hasht = nv_encoder->dcb->hasht, | ||
1761 | .base.hashm = (0xf0ff & nv_encoder->dcb->hashm) | | ||
1762 | (0x0100 << nv_crtc->index), | ||
1763 | }; | ||
1749 | 1764 | ||
1750 | nv50_audio_disconnect(encoder); | 1765 | nv50_audio_disconnect(encoder); |
1751 | 1766 | ||
1752 | nvif_exec(disp->disp, NV84_DISP_SOR_HDMI_PWR + moff, &data, sizeof(data)); | 1767 | nvif_mthd(disp->disp, 0, &args, sizeof(args)); |
1753 | } | 1768 | } |
1754 | 1769 | ||
1755 | /****************************************************************************** | 1770 | /****************************************************************************** |
diff --git a/drivers/gpu/drm/nouveau/nvif/class.h b/drivers/gpu/drm/nouveau/nvif/class.h index 84d2926dd069..abc6efab5dc6 100644 --- a/drivers/gpu/drm/nouveau/nvif/class.h +++ b/drivers/gpu/drm/nouveau/nvif/class.h | |||
@@ -352,4 +352,12 @@ struct nv50_disp_sor_hda_eld_v0 { | |||
352 | __u8 data[]; | 352 | __u8 data[]; |
353 | }; | 353 | }; |
354 | 354 | ||
355 | struct nv50_disp_sor_hdmi_pwr_v0 { | ||
356 | __u8 version; | ||
357 | __u8 state; | ||
358 | __u8 max_ac_packet; | ||
359 | __u8 rekey; | ||
360 | __u8 pad04[4]; | ||
361 | }; | ||
362 | |||
355 | #endif | 363 | #endif |