kernel-5.15/0615-baikal_vdu-et101-display-port-support.patch

122 lines
4.5 KiB
Diff
Raw Permalink Normal View History

From 4dbd82fde8dde03d7921d630ceecd74bdda62692 Mon Sep 17 00:00:00 2001
From: Alexey Sheplyakov <asheplyakov@altlinux.org>
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