From f300068ddd85914dbec48d9ef2381b6f3ad92fc3 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 20 Dec 2014 14:31:45 +0100 Subject: sunxi: video: When using edid use CEA681 extension blocks to select hdmi output When using edid use CEA681 edid extension blocks to select between dvi and hdmi output formats, so that u-boot will automatically do the right thing. Signed-off-by: Hans de Goede Acked-by: Ian Campbell Acked-by: Anatolij Gustschin --- drivers/video/sunxi_display.c | 43 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 9 deletions(-) (limited to 'drivers/video') diff --git a/drivers/video/sunxi_display.c b/drivers/video/sunxi_display.c index 3048410..795835d 100644 --- a/drivers/video/sunxi_display.c +++ b/drivers/video/sunxi_display.c @@ -155,16 +155,17 @@ static int sunxi_hdmi_edid_get_block(int block, u8 *buf) return r; } -static int sunxi_hdmi_edid_get_mode(struct ctfb_res_modes *mode) +static int sunxi_hdmi_edid_get_mode(struct ctfb_res_modes *mode, char *monitor) { struct edid1_info edid1; + struct edid_cea861_info cea681[4]; struct edid_detailed_timing *t = (struct edid_detailed_timing *)edid1.monitor_details.timing; struct sunxi_hdmi_reg * const hdmi = (struct sunxi_hdmi_reg *)SUNXI_HDMI_BASE; struct sunxi_ccm_reg * const ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; - int i, r; + int i, r, ext_blocks = 0; /* SUNXI_HDMI_CTRL_ENABLE & PAD_CTRL0 are already set by hpd_detect */ writel(SUNXI_HDMI_PAD_CTRL1 | SUNXI_HDMI_PAD_CTRL1_HALVE, @@ -189,6 +190,25 @@ static int sunxi_hdmi_edid_get_mode(struct ctfb_res_modes *mode) #endif r = sunxi_hdmi_edid_get_block(0, (u8 *)&edid1); + if (r == 0) { + r = edid_check_info(&edid1); + if (r) { + printf("EDID: invalid EDID data\n"); + r = -EINVAL; + } + } + if (r == 0) { + ext_blocks = edid1.extension_flag; + if (ext_blocks > 4) + ext_blocks = 4; + for (i = 0; i < ext_blocks; i++) { + if (sunxi_hdmi_edid_get_block(1 + i, + (u8 *)&cea681[i]) != 0) { + ext_blocks = i; + break; + } + } + } /* Disable DDC engine, no longer needed */ clrbits_le32(&hdmi->ddc_ctrl, SUNXI_HMDI_DDC_CTRL_ENABLE); @@ -197,12 +217,6 @@ static int sunxi_hdmi_edid_get_mode(struct ctfb_res_modes *mode) if (r) return r; - r = edid_check_info(&edid1); - if (r) { - printf("EDID: invalid EDID data\n"); - return -EINVAL; - } - /* We want version 1.3 or 1.2 with detailed timing info */ if (edid1.version != 1 || (edid1.revision < 3 && !EDID1_INFO_FEATURE_PREFERRED_TIMING_MODE(edid1))) { @@ -222,6 +236,17 @@ static int sunxi_hdmi_edid_get_mode(struct ctfb_res_modes *mode) return -ENOENT; } + /* Check for basic audio support, if found enable hdmi output */ + strcpy(monitor, "dvi"); + for (i = 0; i < ext_blocks; i++) { + if (cea681[i].extension_tag != EDID_CEA861_EXTENSION_TAG || + cea681[i].revision < 2) + continue; + + if (EDID_CEA861_SUPPORTS_BASIC_AUDIO(cea681[i])) + strcpy(monitor, "hdmi"); + } + return 0; } @@ -597,7 +622,7 @@ void *video_hw_init(void) /* Check edid if requested and we've a cable plugged in */ if (edid && ret) { - if (sunxi_hdmi_edid_get_mode(&edid_mode) == 0) + if (sunxi_hdmi_edid_get_mode(&edid_mode, monitor) == 0) mode = &edid_mode; } -- cgit v1.1