aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_sdvo.c
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2012-05-12 14:22:00 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2012-05-20 11:11:11 -0400
commit81014b9d0b55fb0b48f26cd2a943359750d532db (patch)
treed3315e5afc1cf4a126278eff0ab1db0fbfc492fd /drivers/gpu/drm/i915/intel_sdvo.c
parent6f13b7b5be500178d5541b69ab911af2a77ec488 (diff)
drm/i915: fixup infoframe support for sdvo
At least the worst offenders: - SDVO specifies that the encoder should compute the ecc. Testing also shows that we must not send the ecc field, so copy the dip_infoframe struct to a temporay place and avoid the ecc field. This way the avi infoframe is exactly 17 bytes long, which agrees with what the spec mandates as a minimal storage capacity (with the ecc field it would be 18 bytes). - Only 17 when sending the avi infoframe. The SDVO spec explicitly says that sending more data than what the device announces results in undefined behaviour. - Add __attribute__((packed)) to the avi and spd infoframes, for otherwise they're wrongly aligned. Noticed because the avi infoframe ended up being 18 bytes large instead of 17. We haven't noticed this yet because we don't use the uint16_t fields yet (which are the only ones that would be wrongly aligned). This regression has been introduce by 3c17fe4b8f40a112a85758a9ab2aebf772bdd647 is the first bad commit commit 3c17fe4b8f40a112a85758a9ab2aebf772bdd647 Author: David Härdeman <david@hardeman.nu> Date: Fri Sep 24 21:44:32 2010 +0200 i915: enable AVI infoframe for intel_hdmi.c [v4] Patch tested on my g33 with a sdvo hdmi adaptor. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=25732 Tested-by: Peter Ross <pross@xvid.org> (G35 SDVO-HDMI) Reviewed-by: Eugeni Dodonov <eugeni.dodonov@intel.com> Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_sdvo.c')
-rw-r--r--drivers/gpu/drm/i915/intel_sdvo.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index 7d3f238e8265..125228e77c50 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -887,17 +887,24 @@ static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo)
887 }; 887 };
888 uint8_t tx_rate = SDVO_HBUF_TX_VSYNC; 888 uint8_t tx_rate = SDVO_HBUF_TX_VSYNC;
889 uint8_t set_buf_index[2] = { 1, 0 }; 889 uint8_t set_buf_index[2] = { 1, 0 };
890 uint64_t *data = (uint64_t *)&avi_if; 890 uint8_t sdvo_data[4 + sizeof(avi_if.body.avi)];
891 uint64_t *data = (uint64_t *)sdvo_data;
891 unsigned i; 892 unsigned i;
892 893
893 intel_dip_infoframe_csum(&avi_if); 894 intel_dip_infoframe_csum(&avi_if);
894 895
896 /* sdvo spec says that the ecc is handled by the hw, and it looks like
897 * we must not send the ecc field, either. */
898 memcpy(sdvo_data, &avi_if, 3);
899 sdvo_data[3] = avi_if.checksum;
900 memcpy(&sdvo_data[4], &avi_if.body, sizeof(avi_if.body.avi));
901
895 if (!intel_sdvo_set_value(intel_sdvo, 902 if (!intel_sdvo_set_value(intel_sdvo,
896 SDVO_CMD_SET_HBUF_INDEX, 903 SDVO_CMD_SET_HBUF_INDEX,
897 set_buf_index, 2)) 904 set_buf_index, 2))
898 return false; 905 return false;
899 906
900 for (i = 0; i < sizeof(avi_if); i += 8) { 907 for (i = 0; i < sizeof(sdvo_data); i += 8) {
901 if (!intel_sdvo_set_value(intel_sdvo, 908 if (!intel_sdvo_set_value(intel_sdvo,
902 SDVO_CMD_SET_HBUF_DATA, 909 SDVO_CMD_SET_HBUF_DATA,
903 data, 8)) 910 data, 8))