edid: add edid_get_timing_validate() variant to filter out edid modes
authorNeil Armstrong <narmstrong@baylibre.com>
Thu, 4 Jul 2019 13:52:06 +0000 (15:52 +0200)
committerAnatolij Gustschin <agust@denx.de>
Sun, 28 Jul 2019 22:21:40 +0000 (00:21 +0200)
The original edid_get_timing() function returns the first valid timing,
but on some plaforms, we could only supports a subset of the listed
monitot's navite timing.

Let's introduce a edid_get_timing_validate() adding a mode_valid callback
including a private cookie pointer.

If the callback returns false, the current timing is discared and the next
one is checked. If no valid & supported timings are found, the function
would return an error.

Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
common/edid.c
include/edid.h

index 90d1167f6eee9d2191dc4f8e3f4361ecaa235716..f244d26e04be491f71cf912a9aba8c9b848c0a0f 100644 (file)
@@ -168,8 +168,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;
@@ -193,7 +197,11 @@ 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;
+                       if (mode_valid)
+                               timing_done = mode_valid(mode_valid_priv,
+                                                        timing);
+                       else
+                               timing_done = true;
                        break;
                }
        }
@@ -225,6 +233,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.
  *
index f05d2b82f24494eca9b837d71d2c6a496dcf5387..2562733061c0a4e2103ad0557c80047882ce16cf 100644 (file)
@@ -306,6 +306,28 @@ int edid_get_ranges(struct edid1_info *edid, unsigned int *hmin,
 
 struct display_timing;
 
+/**
+ * edid_get_timing_validate() - Get basic digital display parameters with
+ * mode selection callback
+ *
+ * @param buf          Buffer containing EDID data
+ * @param buf_size     Size of buffer in bytes
+ * @param timing       Place to put preferring timing information
+ * @param panel_bits_per_colourp       Place to put the number of bits per
+ *                     colour supported by the panel. This will be set to
+ *                     -1 if not available
+ * @param mode_valid   Callback validating mode, returning true is mode is
+ *                     supported, false otherwise.
+ * @parem valid_priv   Pointer to private data for mode_valid callback
+ * @return 0 if timings are OK, -ve on error
+ */
+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);
+
 /**
  * edid_get_timing() - Get basic digital display parameters
  *