--- drivers/gpu/drm/radeon/r600_hdmi.c | 81 ++++++----------------------------- drivers/gpu/drm/radeon/radeon.h | 41 ++++++++++++++++++ 2 files changed, 55 insertions(+), 67 deletions(-) diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c index c308432..b14c90a 100644 --- a/drivers/gpu/drm/radeon/r600_hdmi.c +++ b/drivers/gpu/drm/radeon/r600_hdmi.c @@ -134,78 +134,22 @@ static void r600_hdmi_infoframe_checksum(uint8_t packetType, } /* - * build a HDMI Video Info Frame + * Upload a HDMI AVI Infoframe */ -static void r600_hdmi_videoinfoframe( - struct drm_encoder *encoder, - enum r600_hdmi_color_format color_format, - int active_information_present, - uint8_t active_format_aspect_ratio, - uint8_t scan_information, - uint8_t colorimetry, - uint8_t ex_colorimetry, - uint8_t quantization, - int ITC, - uint8_t picture_aspect_ratio, - uint8_t video_format_identification, - uint8_t pixel_repetition, - uint8_t non_uniform_picture_scaling, - uint8_t bar_info_data_valid, - uint16_t top_bar, - uint16_t bottom_bar, - uint16_t left_bar, - uint16_t right_bar -) +static void r600_hdmi_avi_infoframe(struct drm_encoder *encoder, + struct radeon_avi_infoframe infoframe) { struct drm_device *dev = encoder->dev; struct radeon_device *rdev = dev->dev_private; uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset; - uint8_t frame[14]; - - frame[0x0] = 0; - frame[0x1] = - (scan_information & 0x3) | - ((bar_info_data_valid & 0x3) << 2) | - ((active_information_present & 0x1) << 4) | - ((color_format & 0x3) << 5); - frame[0x2] = - (active_format_aspect_ratio & 0xF) | - ((picture_aspect_ratio & 0x3) << 4) | - ((colorimetry & 0x3) << 6); - frame[0x3] = - (non_uniform_picture_scaling & 0x3) | - ((quantization & 0x3) << 2) | - ((ex_colorimetry & 0x7) << 4) | - ((ITC & 0x1) << 7); - frame[0x4] = (video_format_identification & 0x7F); - frame[0x5] = (pixel_repetition & 0xF); - frame[0x6] = (top_bar & 0xFF); - frame[0x7] = (top_bar >> 8); - frame[0x8] = (bottom_bar & 0xFF); - frame[0x9] = (bottom_bar >> 8); - frame[0xA] = (left_bar & 0xFF); - frame[0xB] = (left_bar >> 8); - frame[0xC] = (right_bar & 0xFF); - frame[0xD] = (right_bar >> 8); + /* Standard says about 0x82 0x02 but radeon uses 0x81 0x01...? */ + r600_hdmi_infoframe_checksum(0x81, 0x01, 13, (u8 *)&infoframe); - r600_hdmi_infoframe_checksum(0x82, 0x02, 0x0D, frame); - /* Our header values (type, version, length) should be alright, Intel - * is using the same. Checksum function also seems to be OK, it works - * fine for audio infoframe. However calculated value is always lower - * by 2 in comparison to fglrx. It breaks displaying anything in case - * of TVs that strictly check the checksum. Hack it manually here to - * workaround this issue. */ - frame[0x0] += 2; - - WREG32(HDMI0_AVI_INFO0 + offset, - frame[0x0] | (frame[0x1] << 8) | (frame[0x2] << 16) | (frame[0x3] << 24)); - WREG32(HDMI0_AVI_INFO1 + offset, - frame[0x4] | (frame[0x5] << 8) | (frame[0x6] << 16) | (frame[0x7] << 24)); - WREG32(HDMI0_AVI_INFO2 + offset, - frame[0x8] | (frame[0x9] << 8) | (frame[0xA] << 16) | (frame[0xB] << 24)); - WREG32(HDMI0_AVI_INFO3 + offset, - frame[0xC] | (frame[0xD] << 8)); + WREG32(HDMI0_AVI_INFO0 + offset, ((u32 *)&infoframe)[0]); + WREG32(HDMI0_AVI_INFO1 + offset, ((u32 *)&infoframe)[1]); + WREG32(HDMI0_AVI_INFO2 + offset, ((u32 *)&infoframe)[2]); + WREG32(HDMI0_AVI_INFO3 + offset, ((u32 *)&infoframe)[3]); } /* @@ -316,6 +260,10 @@ void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mod struct radeon_device *rdev = dev->dev_private; uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset; + /* TODO: fill in more avi info */ + struct radeon_avi_infoframe infoframe = { }; + infoframe.color_format = 0; + if (ASIC_IS_DCE5(rdev)) return; @@ -367,8 +315,7 @@ void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mod WREG32(HDMI0_GC + offset, 0); /* unset HDMI0_GC_AVMUTE */ - r600_hdmi_videoinfoframe(encoder, RGB, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + r600_hdmi_avi_infoframe(encoder, infoframe); r600_hdmi_update_ACR(encoder, mode->clock); diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index a7ae4ca..5a5c76f 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -1874,6 +1874,47 @@ struct radeon_hdmi_acr { }; +struct radeon_avi_infoframe { + unsigned checksum: 8; + + unsigned scan_information: 2; + unsigned bar_info_data_valid: 2; + unsigned active_information_present: 1; + unsigned color_format: 2; + unsigned :1; + + unsigned active_format_aspect_ratio:4; + unsigned picture_aspect_ratio:2; + unsigned colorimetry:2; + + unsigned non_uniform_picture_scaling:2; + unsigned quantization:2; + unsigned ex_colorimetry:3; + unsigned ITC:1; + + unsigned video_format_identification: 7; + unsigned :1; + + unsigned pixel_repetition: 4; + unsigned :4; + + unsigned top_bar_lo: 8; + + unsigned top_bar_hi: 8; + + unsigned bottom_bar_lo: 8; + + unsigned bottom_bar_hi: 8; + + unsigned left_bar_lo: 8; + + unsigned left_bar_hi: 8; + + unsigned right_bar_lo: 8; + + unsigned right_bar_hi: 8; +} __packed; + extern struct radeon_hdmi_acr r600_hdmi_acr(uint32_t clock); extern void r600_hdmi_enable(struct drm_encoder *encoder); -- 1.7.7 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel