aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlastair Bridgewater <alastair.bridgewater@gmail.com>2017-04-11 13:11:20 -0400
committerBen Skeggs <bskeggs@redhat.com>2017-06-16 14:04:18 +1000
commita45f7908b3ac4691d9abba5fc480ba0f718db3ea (patch)
tree42ece73a8716eddcda92bf501f572414dd13f00a
parentdrm/nouveau/disp: Add mechanism to convert HDMI InfoFrames to hardware format (diff)
downloadlinux-dev-a45f7908b3ac4691d9abba5fc480ba0f718db3ea.tar.xz
linux-dev-a45f7908b3ac4691d9abba5fc480ba0f718db3ea.zip
drm/nouveau/disp/g84-gt200: 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 AVI or Vendor InfoFrame that is not provided, and disable the Vendor InfoFrame when disabling the output. Ignore the Audio InfoFrame: We don't supply it, and altering HDMI audio semantics (for better or worse) on this hardware is out of scope for me at this time. Signed-off-by: Alastair Bridgewater <alastair.bridgewater@gmail.com> Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmig84.c37
1 files changed, 31 insertions, 6 deletions
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmig84.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmig84.c
index 77e5f5a2f3fa..139344eb5b72 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmig84.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmig84.c
@@ -36,6 +36,8 @@ g84_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 @@ g84_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, 0x6165a4 + hoff, 0x40000000, 0x00000000);
+ nvkm_mask(device, 0x61653c + hoff, 0x00000001, 0x00000000);
nvkm_mask(device, 0x616520 + hoff, 0x00000001, 0x00000000);
nvkm_mask(device, 0x616500 + hoff, 0x00000001, 0x00000000);
return 0;
@@ -70,12 +81,14 @@ g84_hdmi_ctrl(NV50_DISP_MTHD_V1)
/* AVI InfoFrame */
nvkm_mask(device, 0x616520 + hoff, 0x00000001, 0x00000000);
- nvkm_wr32(device, 0x616528 + hoff, 0x000d0282);
- nvkm_wr32(device, 0x61652c + hoff, 0x0000006f);
- nvkm_wr32(device, 0x616530 + hoff, 0x00000000);
- nvkm_wr32(device, 0x616534 + hoff, 0x00000000);
- nvkm_wr32(device, 0x616538 + hoff, 0x00000000);
- nvkm_mask(device, 0x616520 + hoff, 0x00000001, 0x00000001);
+ if (args->v0.avi_infoframe_length) {
+ nvkm_wr32(device, 0x616528 + hoff, avi_infoframe.header);
+ nvkm_wr32(device, 0x61652c + hoff, avi_infoframe.subpack0_low);
+ nvkm_wr32(device, 0x616530 + hoff, avi_infoframe.subpack0_high);
+ nvkm_wr32(device, 0x616534 + hoff, avi_infoframe.subpack1_low);
+ nvkm_wr32(device, 0x616538 + hoff, avi_infoframe.subpack1_high);
+ nvkm_mask(device, 0x616520 + hoff, 0x00000001, 0x00000001);
+ }
/* Audio InfoFrame */
nvkm_mask(device, 0x616500 + hoff, 0x00000001, 0x00000000);
@@ -84,6 +97,18 @@ g84_hdmi_ctrl(NV50_DISP_MTHD_V1)
nvkm_wr32(device, 0x616510 + hoff, 0x00000000);
nvkm_mask(device, 0x616500 + hoff, 0x00000001, 0x00000001);
+ /* Vendor InfoFrame */
+ nvkm_mask(device, 0x61653c + hoff, 0x00010001, 0x00010000);
+ if (args->v0.vendor_infoframe_length) {
+ nvkm_wr32(device, 0x616544 + hoff, vendor_infoframe.header);
+ nvkm_wr32(device, 0x616548 + hoff, vendor_infoframe.subpack0_low);
+ nvkm_wr32(device, 0x61654c + hoff, vendor_infoframe.subpack0_high);
+ /* Is there a second (or up to fourth?) set of subpack registers here? */
+ /* nvkm_wr32(device, 0x616550 + hoff, vendor_infoframe->subpack1_low); */
+ /* nvkm_wr32(device, 0x616554 + hoff, vendor_infoframe->subpack1_high); */
+ nvkm_mask(device, 0x61653c + hoff, 0x00010001, 0x00010001);
+ }
+
nvkm_mask(device, 0x6165d0 + hoff, 0x00070001, 0x00010001); /* SPARE, HW_CTS */
nvkm_mask(device, 0x616568 + hoff, 0x00010101, 0x00000000); /* ACR_CTRL, ?? */
nvkm_mask(device, 0x616578 + hoff, 0x80000000, 0x80000000); /* ACR_0441_ENABLE */