Commit a8970743 authored by Alastair Bridgewater's avatar Alastair Bridgewater Committed by Ben Skeggs

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: default avatarAlastair Bridgewater <alastair.bridgewater@gmail.com>
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 2709b275
...@@ -37,6 +37,8 @@ gk104_hdmi_ctrl(NV50_DISP_MTHD_V1) ...@@ -37,6 +37,8 @@ gk104_hdmi_ctrl(NV50_DISP_MTHD_V1)
union { union {
struct nv50_disp_sor_hdmi_pwr_v0 v0; struct nv50_disp_sor_hdmi_pwr_v0 v0;
} *args = data; } *args = data;
struct packed_hdmi_infoframe avi_infoframe;
struct packed_hdmi_infoframe vendor_infoframe;
u32 ctrl; u32 ctrl;
int ret = -ENOSYS; int ret = -ENOSYS;
...@@ -61,8 +63,17 @@ gk104_hdmi_ctrl(NV50_DISP_MTHD_V1) ...@@ -61,8 +63,17 @@ gk104_hdmi_ctrl(NV50_DISP_MTHD_V1)
+ args->v0.vendor_infoframe_length) < size) + args->v0.vendor_infoframe_length) < size)
return -E2BIG; 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)) { if (!(ctrl & 0x40000000)) {
nvkm_mask(device, 0x616798 + hoff, 0x40000000, 0x00000000); nvkm_mask(device, 0x616798 + hoff, 0x40000000, 0x00000000);
nvkm_mask(device, 0x690100 + hdmi, 0x00000001, 0x00000000);
nvkm_mask(device, 0x6900c0 + hdmi, 0x00000001, 0x00000000); nvkm_mask(device, 0x6900c0 + hdmi, 0x00000001, 0x00000000);
nvkm_mask(device, 0x690000 + hdmi, 0x00000001, 0x00000000); nvkm_mask(device, 0x690000 + hdmi, 0x00000001, 0x00000000);
return 0; return 0;
...@@ -70,12 +81,25 @@ gk104_hdmi_ctrl(NV50_DISP_MTHD_V1) ...@@ -70,12 +81,25 @@ gk104_hdmi_ctrl(NV50_DISP_MTHD_V1)
/* AVI InfoFrame */ /* AVI InfoFrame */
nvkm_mask(device, 0x690000 + hdmi, 0x00000001, 0x00000000); nvkm_mask(device, 0x690000 + hdmi, 0x00000001, 0x00000000);
nvkm_wr32(device, 0x690008 + hdmi, 0x000d0282); if (args->v0.avi_infoframe_length) {
nvkm_wr32(device, 0x69000c + hdmi, 0x0000006f); nvkm_wr32(device, 0x690008 + hdmi, avi_infoframe.header);
nvkm_wr32(device, 0x690010 + hdmi, 0x00000000); nvkm_wr32(device, 0x69000c + hdmi, avi_infoframe.subpack0_low);
nvkm_wr32(device, 0x690014 + hdmi, 0x00000000); nvkm_wr32(device, 0x690010 + hdmi, avi_infoframe.subpack0_high);
nvkm_wr32(device, 0x690018 + hdmi, 0x00000000); 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); 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? */ /* ??? InfoFrame? */
nvkm_mask(device, 0x6900c0 + hdmi, 0x00000001, 0x00000000); nvkm_mask(device, 0x6900c0 + hdmi, 0x00000001, 0x00000000);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment