colibri_imx6: fix video stdout in default environment
[oweals/u-boot.git] / common / edid.c
index 19410aa4fcc52c3ff993dfe8d64a5b470d419c1b..553ab8fd01a12b76a9c9733cd9d9ef85b6598cf3 100644 (file)
@@ -1,11 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * Copyright (c) 2012 The Chromium OS Authors.
  *
  * (C) Copyright 2010
  * Petr Stetiar <ynezz@true.cz>
  *
- * SPDX-License-Identifier:    GPL-2.0+
- *
  * Contains stolen code from ddcprobe project which is:
  * Copyright (C) Nalin Dahyabhai <bigfun@pobox.com>
  */
@@ -14,6 +13,7 @@
 #include <edid.h>
 #include <errno.h>
 #include <fdtdec.h>
+#include <log.h>
 #include <linux/ctype.h>
 #include <linux/string.h>
 
@@ -148,8 +148,8 @@ static bool cea_is_hdmi_vsdb_present(struct edid_cea861_info *info)
        /* check for end of data block */
        end = info->dtd_offset;
        if (end == 0)
-               end = 127;
-       if (end < 4 || end > 127)
+               end = sizeof(info->data);
+       if (end < 4 || end > sizeof(info->data))
                return false;
        end -= 4;
 
@@ -169,8 +169,12 @@ static bool cea_is_hdmi_vsdb_present(struct edid_cea861_info *info)
        return false;
 }
 
-int edid_get_timing(u8 *buf, int buf_size, struct display_timing *timing,
-                   int *panel_bits_per_colourp)
+int edid_get_timing_validate(u8 *buf, int buf_size,
+                            struct display_timing *timing,
+                            int *panel_bits_per_colourp,
+                            bool (*mode_valid)(void *priv,
+                                       const struct display_timing *timing),
+                            void *mode_valid_priv)
 {
        struct edid1_info *edid = (struct edid1_info *)buf;
        bool timing_done;
@@ -194,8 +198,14 @@ int edid_get_timing(u8 *buf, int buf_size, struct display_timing *timing,
                desc = &edid->monitor_details.descriptor[i];
                if (desc->zero_flag_1 != 0) {
                        decode_timing((u8 *)desc, timing);
-                       timing_done = true;
-                       break;
+                       if (mode_valid)
+                               timing_done = mode_valid(mode_valid_priv,
+                                                        timing);
+                       else
+                               timing_done = true;
+
+                       if (timing_done)
+                               break;
                }
        }
        if (!timing_done)
@@ -226,6 +236,14 @@ int edid_get_timing(u8 *buf, int buf_size, struct display_timing *timing,
        return 0;
 }
 
+int edid_get_timing(u8 *buf, int buf_size, struct display_timing *timing,
+                   int *panel_bits_per_colourp)
+{
+       return edid_get_timing_validate(buf, buf_size, timing,
+                                       panel_bits_per_colourp, NULL, NULL);
+}
+
+
 /**
  * Snip the tailing whitespace/return of a string.
  *
@@ -295,7 +313,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 */