From f61149b7323b8025f5822104dcd5ad38ca5e1db8 Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Wed, 25 Nov 2020 20:13:55 +0100 Subject: [PATCH] video: meson: Add fallback to default timings for QHD/UHD monitors The HDMI driver currently supports only up to 1920x1200 resolutions and QHD/UHD monitors might not specify detailed timings in EDID other than those for their maximum resolution, even though they work with lower resolutions like full HD. In such cases display_read_timings() will fail breaking the video output driver initialization. As a workaround fallback to full HD timings is added for QHD or UHD monitors. The default timing will only be used when "hdmimode" environment variable is set to "1080p60hz", otherwise the driver switches to CVBS mode as before, when display timings are unsupported/could not be read. The proper solution would be to implement support for 2K/4K HDMI modes, which are also not supported yet by driver in the kernel. Change-Id: I407228392a6b1b6e8b0c55a6962235111df0c69c Signed-off-by: Sylwester Nawrocki --- drivers/video/meson/meson_vpu.c | 46 +++++++++++++++++++++++++++++++---------- 1 file changed, 35 insertions(+), 11 deletions(-) diff --git a/drivers/video/meson/meson_vpu.c b/drivers/video/meson/meson_vpu.c index 67d4ce7..6fb6241 100644 --- a/drivers/video/meson/meson_vpu.c +++ b/drivers/video/meson/meson_vpu.c @@ -34,6 +34,20 @@ static struct meson_framebuffer { bool is_cvbs; } meson_fb = { 0 }; + +static struct display_timing default_timing_1920x1080 = { + .pixelclock = { .typ = 148500000 }, + .hactive = { .typ = 1920 }, + .hfront_porch = { .typ = 88 }, + .hback_porch = { .typ = 148 }, + .hsync_len = { .typ = 44 }, + .vactive = { .typ = 1080 }, + .vfront_porch = { .typ = 4 }, + .vback_porch = { .typ = 36 }, + .vsync_len = { .typ = 5 }, + .flags = DISPLAY_FLAGS_DE_LOW, +}; + bool meson_vpu_is_compatible(struct meson_vpu_priv *priv, enum vpu_compatible family) { @@ -46,28 +60,38 @@ static int meson_vpu_setup_mode(struct udevice *dev, struct udevice *disp) { struct video_uc_plat *uc_plat = dev_get_uclass_plat(dev); struct video_priv *uc_priv = dev_get_uclass_priv(dev); - struct display_timing timing; + struct display_timing disp_timing; + struct display_timing *timing = &disp_timing; bool is_cvbs = false; int ret = 0; if (disp) { - ret = display_read_timing(disp, &timing); + ret = display_read_timing(disp, timing); if (ret) { - debug("%s: Failed to read timings\n", __func__); - goto cvbs; + char *env; + + printf("%s: Unsupported display timings\n", __func__); + + env = env_get("hdmimode"); + if (!env || strcmp(env, "1080p60hz")) + goto cvbs; + + printf("%s: Using default full HD timings\n", __func__); + + timing = &default_timing_1920x1080; } - uc_priv->xsize = timing.hactive.typ; - uc_priv->ysize = timing.vactive.typ; + uc_priv->xsize = timing->hactive.typ; + uc_priv->ysize = timing->vactive.typ; - ret = display_enable(disp, 0, &timing); + ret = display_enable(disp, 0, timing); if (ret) goto cvbs; } else { cvbs: /* CVBS has a fixed 720x480i (NTSC) and 720x576i (PAL) */ is_cvbs = true; - timing.flags = DISPLAY_FLAGS_INTERLACED; + timing->flags = DISPLAY_FLAGS_INTERLACED; uc_priv->xsize = 720; uc_priv->ysize = 576; } @@ -88,9 +112,9 @@ cvbs: /* Override the framebuffer address */ uc_plat->base = meson_fb.base; - meson_vpu_setup_plane(dev, timing.flags & DISPLAY_FLAGS_INTERLACED); - meson_vpu_setup_venc(dev, &timing, is_cvbs); - meson_vpu_setup_vclk(dev, &timing, is_cvbs); + meson_vpu_setup_plane(dev, timing->flags & DISPLAY_FLAGS_INTERLACED); + meson_vpu_setup_venc(dev, timing, is_cvbs); + meson_vpu_setup_vclk(dev, timing, is_cvbs); video_set_flush_dcache(dev, 1); -- 2.7.4