From 4dbd82fde8dde03d7921d630ceecd74bdda62692 Mon Sep 17 00:00:00 2001 From: Alexey Sheplyakov Date: Thu, 10 Mar 2022 04:33:35 +0400 Subject: [PATCH 615/634] baikal_vdu: et101 display port support LVDS is connected via a bridge on et101, and current code (baikal_vdu_crtc_helper_mode_set_nofb, baikal_vdu_crtc_helper_enable) assumes that LVDS is connected directly to a panel. To solve the problem - check for output type instead of checking for panel - adjust hsync/vsync parameters calculation (in baikal_vdu_crtc_helper_mode_set_nofb) Note: due to hardware peculiarities using HDMI and DP is possible only with some constraints: - Resolution of both displays should be exactly the same - HDMI viewport must be above or below the display port one --- drivers/gpu/drm/baikal/baikal_vdu_crtc.c | 32 +++++++++++++++--------- drivers/gpu/drm/baikal/baikal_vdu_drv.c | 5 ++-- 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/baikal/baikal_vdu_crtc.c b/drivers/gpu/drm/baikal/baikal_vdu_crtc.c index 039150c59..e338ff8b3 100644 --- a/drivers/gpu/drm/baikal/baikal_vdu_crtc.c +++ b/drivers/gpu/drm/baikal/baikal_vdu_crtc.c @@ -134,14 +134,15 @@ static void baikal_vdu_crtc_helper_mode_set_nofb(struct drm_crtc *crtc) drm_mode_debug_printmodeline(mode); ppl = mode->hdisplay / 16; - if (priv->panel) { + if (priv->type == VDU_TYPE_LVDS) { hsw = mode->hsync_end - mode->hsync_start; hfp = mode->hsync_start - mode->hdisplay - 1; + hbp = mode->htotal - mode->hsync_end; } else { hsw = mode->hsync_end - mode->hsync_start - 1; hfp = mode->hsync_start - mode->hdisplay; + hbp = mode->htotal - mode->hsync_end - 1; } - hbp = mode->htotal - mode->hsync_end; lpp = mode->vdisplay; vsw = mode->vsync_end - mode->vsync_start; @@ -194,13 +195,13 @@ static void baikal_vdu_crtc_helper_enable(struct drm_crtc *crtc, { struct baikal_vdu_private *priv = crtc->dev->dev_private; struct drm_panel *panel = priv->panel; - struct device_node *panel_node; - const char *data_mapping; + const char *data_mapping = NULL; u32 cntl, gpio; + DRM_DEV_DEBUG_DRIVER(crtc->dev->dev, "priv = %px\n", priv); DRM_DEV_DEBUG_DRIVER(crtc->dev->dev, "enabling pixel clock\n"); clk_prepare_enable(priv->clk); - + DRM_DEV_DEBUG_DRIVER(crtc->dev->dev, "panel = %px\n", panel); drm_panel_prepare(panel); writel(ISCR_VSC_VFP, priv->regs + ISCR); @@ -217,17 +218,24 @@ static void baikal_vdu_crtc_helper_enable(struct drm_crtc *crtc, cntl |= CR1_LCE + CR1_FDW_16_WORDS; if (priv->type == VDU_TYPE_LVDS) { - panel_node = panel->dev->of_node; - if (of_property_read_string(panel_node, "data-mapping", &data_mapping)) { + if (panel) { + of_property_read_string(panel->dev->of_node, + "data-mapping", &data_mapping); + } + if (!data_mapping) { cntl |= CR1_OPS_LCD18; - } else if (strncmp(data_mapping, "vesa-24", 7)) + dev_dbg(crtc->dev->dev, "data mapping not specified, using jeida-18"); + } else if (!strncmp(data_mapping, "vesa-24", 7)) { cntl |= CR1_OPS_LCD24; - else if (strncmp(data_mapping, "jeida-18", 8)) - cntl |= CR1_OPS_LCD18; - else { - dev_warn(crtc->dev->dev, "%s data mapping is not supported, vesa-24 is set\n", data_mapping); + dev_dbg(crtc->dev->dev, "using vesa-24 mapping\n"); + } else if (!strncmp(data_mapping, "jeida-18", 8)) { + cntl |= CR1_OPS_LCD18; + dev_dbg(crtc->dev->dev, "using jeida-18 mapping\n"); + } else { + dev_warn(crtc->dev->dev, "unsupported data mapping '%s', using vesa-24\n", data_mapping); cntl |= CR1_OPS_LCD24; } + gpio = GPIOR_UHD_ENB; if (priv->ep_count == 4) gpio |= GPIOR_UHD_QUAD_PORT; diff --git a/drivers/gpu/drm/baikal/baikal_vdu_drv.c b/drivers/gpu/drm/baikal/baikal_vdu_drv.c index af0e0ca19..cedf7962d 100644 --- a/drivers/gpu/drm/baikal/baikal_vdu_drv.c +++ b/drivers/gpu/drm/baikal/baikal_vdu_drv.c @@ -95,9 +95,9 @@ static int vdu_modeset_init(struct drm_device *dev) mode_config = &dev->mode_config; mode_config->funcs = &mode_config_funcs; mode_config->min_width = 1; - mode_config->max_width = 4096; + mode_config->max_width = 4095; mode_config->min_height = 1; - mode_config->max_height = 4096; + mode_config->max_height = 4095; ret = baikal_vdu_primary_plane_init(dev); if (ret != 0) { @@ -124,6 +124,7 @@ static int vdu_modeset_init(struct drm_device *dev) goto out_config; } priv->ep_count = ep_count; + dev_dbg(dev->dev, "panel/bridge has %d endpoints\n", priv->ep_count); if (priv->bridge) { struct drm_encoder *encoder = &priv->encoder; -- 2.33.2