diff --git a/src/include/edid.h b/src/include/edid.h index 924f0f2d1c..f013832d6a 100644 --- a/src/include/edid.h +++ b/src/include/edid.h @@ -95,7 +95,7 @@ struct edid { }; /* Defined in src/lib/edid.c */ -int decode_edid(unsigned char *edid, int size, struct edid *out); +int decode_edid(unsigned char *edid, int size, struct edid *out, int max_khz); void set_vbe_mode_info_valid(struct edid *edid, uintptr_t fb_addr); int set_display_mode(struct edid *edid, enum edid_modes mode); diff --git a/src/lib/edid.c b/src/lib/edid.c index 22c342e8aa..910a990a8d 100644 --- a/src/lib/edid.c +++ b/src/lib/edid.c @@ -67,6 +67,7 @@ struct edid_context { int warning_excessive_dotclock_correction; int warning_zero_preferred_refresh; int conformant; + int max_khz; }; /* Stuff that isn't used anywhere but is nice to pretty-print while @@ -545,6 +546,11 @@ detailed_block(struct edid *result_edid, unsigned char *x, int in_extension, extra_info.syncmethod, x[17] & 0x80 ?" interlaced" : "", extra_info.stereo); + if (c->max_khz && out->mode.pixel_clock > c->max_khz) { + printk(BIOS_SPEW, "Skipping %d\n", out->mode.pixel_clock); + return 1; + } + if (! c->did_detailed_timing) { printk(BIOS_SPEW, "Did detailed timing\n"); c->did_detailed_timing = 1; @@ -1041,8 +1047,10 @@ int set_display_mode(struct edid *edid, enum edid_modes mode) * required to be 128 bytes long, per the standard, * but we have no way of checking this minimum length. * We accept what we are given. + * + * We'll filter out modes > max_khz; 0 for no filter */ -int decode_edid(unsigned char *edid, int size, struct edid *out) +int decode_edid(unsigned char *edid, int size, struct edid *out, int max_khz) { int analog, i, j; struct edid_context c = { @@ -1055,6 +1063,7 @@ int decode_edid(unsigned char *edid, int size, struct edid *out) .has_valid_max_dotclock = 1, .has_valid_string_termination = 1, .conformant = 1, + .max_khz = max_khz, }; dump_breakdown(edid); diff --git a/src/mainboard/google/falco/gma.c b/src/mainboard/google/falco/gma.c index ec26e4418d..8e47ed6d00 100644 --- a/src/mainboard/google/falco/gma.c +++ b/src/mainboard/google/falco/gma.c @@ -227,7 +227,7 @@ int panel_lightup(struct intel_dp *dp, unsigned int init_fb) dp->edidlen++; } - edid_ok = decode_edid(dp->rawedid, dp->edidlen, &dp->edid); + edid_ok = decode_edid(dp->rawedid, dp->edidlen, &dp->edid, 0); printk(BIOS_SPEW, "decode edid returns %d\n", edid_ok); compute_display_params(dp); diff --git a/src/mainboard/google/link/i915.c b/src/mainboard/google/link/i915.c index 042cd80f1d..c06f19f27d 100644 --- a/src/mainboard/google/link/i915.c +++ b/src/mainboard/google/link/i915.c @@ -259,7 +259,7 @@ int i915lightup(unsigned int pphysbase, unsigned int piobase, edid_ok = decode_edid((unsigned char *)&link_edid_data, - sizeof(link_edid_data), &edid); + sizeof(link_edid_data), &edid, 0); printk(BIOS_SPEW, "decode edid returns %d\n", edid_ok); edid.framebuffer_bits_per_pixel = 32; diff --git a/src/mainboard/google/peppy/gma.c b/src/mainboard/google/peppy/gma.c index 189da7e9ee..c86f9de0d8 100644 --- a/src/mainboard/google/peppy/gma.c +++ b/src/mainboard/google/peppy/gma.c @@ -242,7 +242,7 @@ int panel_lightup(struct intel_dp *dp, unsigned int init_fb) dp->edidlen++; } - edid_ok = decode_edid(dp->rawedid, dp->edidlen, &dp->edid); + edid_ok = decode_edid(dp->rawedid, dp->edidlen, &dp->edid, 0); printk(BIOS_SPEW, "decode edid returns %d\n", edid_ok); diff --git a/src/soc/nvidia/tegra124/dp.c b/src/soc/nvidia/tegra124/dp.c index 3a3bce8b15..1e125f6ad0 100644 --- a/src/soc/nvidia/tegra124/dp.c +++ b/src/soc/nvidia/tegra124/dp.c @@ -1322,7 +1322,7 @@ static void tegra_dp_update_config(struct tegra_dc_dp_data *dp, return; } - if (decode_edid(buf, sizeof(buf), &edid)) { + if (decode_edid(buf, sizeof(buf), &edid, 0)) { printk(BIOS_ERR, "%s: Failed to decode EDID. Use defaults.\n", __func__); return; diff --git a/src/soc/rockchip/rk3288/edp.c b/src/soc/rockchip/rk3288/edp.c index 3f27195199..0636cf2f35 100644 --- a/src/soc/rockchip/rk3288/edp.c +++ b/src/soc/rockchip/rk3288/edp.c @@ -789,7 +789,7 @@ static int rk_edp_read_edid(struct rk_edp *edp, struct edid *edid) } } - if (decode_edid(buf, edid_size, edid)) { + if (decode_edid(buf, edid_size, edid, 0)) { printk(BIOS_ERR, "%s: Failed to decode EDID.\n", __func__); return -1; diff --git a/src/soc/rockchip/rk3288/hdmi.c b/src/soc/rockchip/rk3288/hdmi.c index 388a9cfa41..6820d8cac4 100644 --- a/src/soc/rockchip/rk3288/hdmi.c +++ b/src/soc/rockchip/rk3288/hdmi.c @@ -805,7 +805,7 @@ int rk_hdmi_get_edid(struct edid *edid) /* Assume usage of HDMI implies an external display in which case * we should be lenient about errors that the EDID decoder finds. */ - if (decode_edid(edid_buf, edid_size, edid)) + if (decode_edid(edid_buf, edid_size, edid, 165000)) hdmi_debug("failed to decode edid.\n"); /* Try 480p for best compatibility. */