X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=common%2Fedid.c;h=3d0809ad11c2d2e1ca615a9cac681233cb1e6dd5;hb=baefb63a13d106458577704ca4586b3f414c9520;hp=e08e4209202e0ffa852ea75c2848ba0fc5a28238;hpb=00cf1167bb8f7c08825262ee83e77274ff034f0a;p=u-boot diff --git a/common/edid.c b/common/edid.c index e08e420920..3d0809ad11 100644 --- a/common/edid.c +++ b/common/edid.c @@ -85,6 +85,7 @@ static void decode_timing(u8 *buf, struct display_timing *timing) uint x_mm, y_mm; unsigned int ha, hbl, hso, hspw, hborder; unsigned int va, vbl, vso, vspw, vborder; + struct edid_detailed_timing *t = (struct edid_detailed_timing *)buf; /* Edid contains pixel clock in terms of 10KHz */ set_entry(&timing->pixelclock, (buf[0] + (buf[1] << 8)) * 10000); @@ -111,6 +112,19 @@ static void decode_timing(u8 *buf, struct display_timing *timing) set_entry(&timing->vback_porch, vbl - vso - vspw); set_entry(&timing->vsync_len, vspw); + timing->flags = 0; + if (EDID_DETAILED_TIMING_FLAG_HSYNC_POLARITY(*t)) + timing->flags |= DISPLAY_FLAGS_HSYNC_HIGH; + else + timing->flags |= DISPLAY_FLAGS_HSYNC_LOW; + if (EDID_DETAILED_TIMING_FLAG_VSYNC_POLARITY(*t)) + timing->flags |= DISPLAY_FLAGS_VSYNC_HIGH; + else + timing->flags |= DISPLAY_FLAGS_VSYNC_LOW; + + if (EDID_DETAILED_TIMING_FLAG_INTERLACED(*t)) + timing->flags = DISPLAY_FLAGS_INTERLACED; + debug("Detailed mode clock %u Hz, %d mm x %d mm\n" " %04x %04x %04x %04x hborder %x\n" " %04x %04x %04x %04x vborder %x\n", @@ -122,6 +136,39 @@ static void decode_timing(u8 *buf, struct display_timing *timing) va + vbl, vborder); } +/** + * Check if HDMI vendor specific data block is present in CEA block + * @param info CEA extension block + * @return true if block is found + */ +static bool cea_is_hdmi_vsdb_present(struct edid_cea861_info *info) +{ + u8 end, i = 0; + + /* check for end of data block */ + end = info->dtd_offset; + if (end == 0) + end = sizeof(info->data); + if (end < 4 || end > sizeof(info->data)) + return false; + end -= 4; + + while (i < end) { + /* Look for vendor specific data block of appropriate size */ + if ((EDID_CEA861_DB_TYPE(*info, i) == EDID_CEA861_DB_VENDOR) && + (EDID_CEA861_DB_LEN(*info, i) >= 5)) { + u8 *db = &info->data[i + 1]; + u32 oui = db[0] | (db[1] << 8) | (db[2] << 16); + + if (oui == HDMI_IEEE_OUI) + return true; + } + i += EDID_CEA861_DB_LEN(*info, i) + 1; + } + + return false; +} + int edid_get_timing(u8 *buf, int buf_size, struct display_timing *timing, int *panel_bits_per_colourp) { @@ -167,6 +214,15 @@ int edid_get_timing(u8 *buf, int buf_size, struct display_timing *timing, ((edid->video_input_definition & 0x70) >> 3) + 4; } + timing->hdmi_monitor = false; + if (edid->extension_flag && (buf_size >= EDID_EXT_SIZE)) { + struct edid_cea861_info *info = + (struct edid_cea861_info *)(buf + sizeof(*edid)); + + if (info->extension_tag == EDID_CEA861_EXTENSION_TAG) + timing->hdmi_monitor = cea_is_hdmi_vsdb_present(info); + } + return 0; } @@ -239,7 +295,7 @@ static void edid_print_dtd(struct edid_monitor_descriptor *monitor, h_total = h_active + h_blanking; v_total = v_active + v_blanking; - if (v_total * h_total) + if (v_total > 0 && h_total > 0) vfreq = pixclock / (v_total * h_total); else vfreq = 1; /* Error case */