summaryrefslogtreecommitdiff
path: root/drivers/gpu
diff options
context:
space:
mode:
authorAlastair Bridgewater <alastair.bridgewater@gmail.com>2017-04-11 13:11:23 -0400
committerBen Skeggs <bskeggs@redhat.com>2017-06-16 14:04:18 +1000
commita8970743502f6e52297fca4181ae524041119106 (patch)
tree1683f05a8500a9ff1a4225889a36f07058412caf /drivers/gpu
parent2709b275c5d7ad01ae08cad004587f479aa3ea95 (diff)
drm/nouveau/disp/gk104-: Use supplied HDMI InfoFrames
Now that we have the InfoFrame data being provided, for the most part, program the hardware to use it. While we're here, and since the functionality will come in handy for supporting 3D stereoscopy, implement setting the Vendor ("generic"?) InfoFrame. Also don't enable any InfoFrame that is not provided, and disable the Vendor InfoFrame when disabling the output. Signed-off-by: Alastair Bridgewater <alastair.bridgewater@gmail.com> Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigk104.c36
1 files changed, 30 insertions, 6 deletions
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigk104.c
index 3c8c26a44f56..99d27314b511 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigk104.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigk104.c
@@ -37,6 +37,8 @@ gk104_hdmi_ctrl(NV50_DISP_MTHD_V1)
union {
struct nv50_disp_sor_hdmi_pwr_v0 v0;
} *args = data;
+ struct packed_hdmi_infoframe avi_infoframe;
+ struct packed_hdmi_infoframe vendor_infoframe;
u32 ctrl;
int ret = -ENOSYS;
@@ -61,8 +63,17 @@ gk104_hdmi_ctrl(NV50_DISP_MTHD_V1)
+ args->v0.vendor_infoframe_length) < size)
return -E2BIG;
+ pack_hdmi_infoframe(&avi_infoframe,
+ data,
+ args->v0.avi_infoframe_length);
+
+ pack_hdmi_infoframe(&vendor_infoframe,
+ data + args->v0.avi_infoframe_length,
+ args->v0.vendor_infoframe_length);
+
if (!(ctrl & 0x40000000)) {
nvkm_mask(device, 0x616798 + hoff, 0x40000000, 0x00000000);
+ nvkm_mask(device, 0x690100 + hdmi, 0x00000001, 0x00000000);
nvkm_mask(device, 0x6900c0 + hdmi, 0x00000001, 0x00000000);
nvkm_mask(device, 0x690000 + hdmi, 0x00000001, 0x00000000);
return 0;
@@ -70,12 +81,25 @@ gk104_hdmi_ctrl(NV50_DISP_MTHD_V1)
/* AVI InfoFrame */
nvkm_mask(device, 0x690000 + hdmi, 0x00000001, 0x00000000);
- nvkm_wr32(device, 0x690008 + hdmi, 0x000d0282);
- nvkm_wr32(device, 0x69000c + hdmi, 0x0000006f);
- nvkm_wr32(device, 0x690010 + hdmi, 0x00000000);
- nvkm_wr32(device, 0x690014 + hdmi, 0x00000000);
- nvkm_wr32(device, 0x690018 + hdmi, 0x00000000);
- nvkm_mask(device, 0x690000 + hdmi, 0x00000001, 0x00000001);
+ if (args->v0.avi_infoframe_length) {
+ nvkm_wr32(device, 0x690008 + hdmi, avi_infoframe.header);
+ nvkm_wr32(device, 0x69000c + hdmi, avi_infoframe.subpack0_low);
+ nvkm_wr32(device, 0x690010 + hdmi, avi_infoframe.subpack0_high);
+ nvkm_wr32(device, 0x690014 + hdmi, avi_infoframe.subpack1_low);
+ nvkm_wr32(device, 0x690018 + hdmi, avi_infoframe.subpack1_high);
+ nvkm_mask(device, 0x690000 + hdmi, 0x00000001, 0x00000001);
+ }
+
+ /* GENERIC(?) / Vendor InfoFrame? */
+ nvkm_mask(device, 0x690100 + hdmi, 0x00010001, 0x00000000);
+ if (args->v0.vendor_infoframe_length) {
+ nvkm_wr32(device, 0x690108 + hdmi, vendor_infoframe.header);
+ nvkm_wr32(device, 0x69010c + hdmi, vendor_infoframe.subpack0_low);
+ nvkm_wr32(device, 0x690110 + hdmi, vendor_infoframe.subpack0_high);
+ /* Is there a second (or further?) set of subpack registers here? */
+ nvkm_mask(device, 0x690100 + hdmi, 0x00000001, 0x00000001);
+ }
+
/* ??? InfoFrame? */
nvkm_mask(device, 0x6900c0 + hdmi, 0x00000001, 0x00000000);