From nobody Thu Dec 18 22:47:27 2025 Received: from mail-lf1-f43.google.com (mail-lf1-f43.google.com [209.85.167.43]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 208FD1F4734 for ; Thu, 20 Feb 2025 11:15:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.43 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740050115; cv=none; b=bAP512lNMl+8zCwLwndsQe2PaU87rR6I4SXQuP8Efzwq50HE5pPISgejLkGxibqt3Sf+qfUCtASFvDizmb3fKLu/0y/jXDPLw5sgL23XjBfEyKwGH8s/G+udlG3o9LzYOA6xj3uoMphoNCACozHoUqUD+UUCKOAl6TcXp7SV2Bw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740050115; c=relaxed/simple; bh=90eJnitNHrEK/bHG/5dquibI/K0ZaJ2fO88HjDQ4Cno=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=rtSh13YHvYPKN2sQCinP9QD7D/V+n5SraOBYovRn+MV/niwzWCe6IF+bi0FrOTElNgOX8nRuqZnWb415XSlrwUuao5QyhUqxx4qQoRvvBLSzx1XICzXWqczhfU/uyMsap1QYGpFpZe27dudNmMEetfmWXKFU3H0RZ4LXQjH/HB4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linaro.org; spf=pass smtp.mailfrom=linaro.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b=ZGsrWDiE; arc=none smtp.client-ip=209.85.167.43 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linaro.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="ZGsrWDiE" Received: by mail-lf1-f43.google.com with SMTP id 2adb3069b0e04-546210287c1so935881e87.2 for ; Thu, 20 Feb 2025 03:15:11 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1740050110; x=1740654910; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=B+FSEAZwM3JMz4x3mQU5rxG2ANMYWACSorMBKNolQMw=; b=ZGsrWDiENORAxlUPtjS7NvG1WDP5OGA3sPoO1pk/zZk1P3tvlr8atT66yDm1PKILt4 P/dwEokIa13VwmOzRfKZSsZUnS/B2pb0phCrp7SYKmZ3OrcJoOVGsbDxBUBua9F2wU+M adasMSafMXPoxkDVWLbfpvABjb8hle2lFM+USUqFwS7hv1R4OVHHFfi0Foue6M5ZIBvC c9zSFRtAIs1fwSD2Rx9EwhMjnSKSZejUTxSf1oSbizdsLpqfE9mt4A6qVi3YGH39JQ9K wPKamOyS2cxnFJFYR6jxe0BwA/k9JxBjhusfSIsfHZMwjJ9e2vzrWT440aZG3FyQSrI2 HwTQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1740050110; x=1740654910; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=B+FSEAZwM3JMz4x3mQU5rxG2ANMYWACSorMBKNolQMw=; b=Q2aOqaiupfklSJAedyWlCS1m12YPx85KjKTFu+SRvslohegRcZVBcZXShK7vKMYGtr rOqdZMMTpwZLAMmBRYTSO+KWz58bv0doD86byE/wLIPi9gO3MiMBAuMRBXzwfMMraOGO j+EZircOchWbVjkZZOxO7Hns/cjT474rUhsTq1dVDtjap5HrbALiMJmd0tAX0bBWgawY EPFAyku7zmNwfyJMVkvUwfncKyylEbuzyF7tns8GcNWYSh2YBY7cZhapp1jykv3oJATl 2PKMsVnjgyxSbkdqIau5XDiT781jC8NohvxgAgnF/VgBwJycYGoJm6qFr5sbKfeXvKOc n6rw== X-Forwarded-Encrypted: i=1; AJvYcCWdW7NAbIYMuGrtkUlasLEojGhghXUEz2y+z033b69tV/vmvy8ZtfMbqcbpvFVCTKkTDtIqN7HXdr7IsqM=@vger.kernel.org X-Gm-Message-State: AOJu0YzvAaNlUJpepY1vcgm2hZjb1isBrmHcgbHGK7iyS5XzRvRKnkd7 fn7t+/bM4Uz9NIFeLwnhvHRENXZuvBV8uJJbTBZV5XAj57Diq8cuZH/+USgS+yBsbCn2rOraEgu 8 X-Gm-Gg: ASbGncuAkJ0xnAKDfUZeOvNEbAe3yq2qaI0ZQnReWM8LrU5+PWXfXJn8f4QwQQ8zJYe IVxiObAX6K2nKwrp+ZfcCZN0pgfBW7grmPzoEVbnq7GU0urcHxii43We6IDyeKYdRHxj2vEhCbc A4NOrK1jp+o/9683EF5gQtKazbmELZ1bk1APkAvmLzrJ7edMHpiG8iJ1IU+bfpM378gVaq3VnT6 fH/NwoPuqZEjxWLmcAvlhk8aAJrdUcedSRA8cycjXBaLleDgovv83j8HmdrHKWS1CFqXzByetC2 6XjyyWXxBDvbSAZAM0DBaJw= X-Google-Smtp-Source: AGHT+IFLmuofJZAPPdn/voaRPjKCsN8RM7jaAav41hPT/JRZmj1CezRyZIpCTJVK79XnKgaiPolXoQ== X-Received: by 2002:a05:6512:304d:b0:546:3052:4202 with SMTP id 2adb3069b0e04-546305242bamr2422240e87.27.1740050109865; Thu, 20 Feb 2025 03:15:09 -0800 (PST) Received: from umbar.lan ([192.130.178.90]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-545297856c6sm2056164e87.142.2025.02.20.03.15.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Feb 2025 03:15:08 -0800 (PST) From: Dmitry Baryshkov Date: Thu, 20 Feb 2025 13:14:48 +0200 Subject: [PATCH v2 6/7] drm/msm/mdp4: switch LVDS to use drm_bridge/_connector Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250220-fd-mdp4-lvds-v2-6-15afe5578a31@linaro.org> References: <20250220-fd-mdp4-lvds-v2-0-15afe5578a31@linaro.org> In-Reply-To: <20250220-fd-mdp4-lvds-v2-0-15afe5578a31@linaro.org> To: Rob Clark , Abhinav Kumar , Sean Paul , Marijn Suijten , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Bjorn Andersson , Konrad Dybcio Cc: linux-arm-msm@vger.kernel.org, dri-devel@lists.freedesktop.org, freedreno@lists.freedesktop.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=10669; i=dmitry.baryshkov@linaro.org; h=from:subject:message-id; bh=90eJnitNHrEK/bHG/5dquibI/K0ZaJ2fO88HjDQ4Cno=; b=owEBbQGS/pANAwAKAYs8ij4CKSjVAcsmYgBntw6rtOhBVgnhA1cDBrmo3nWNRXGCQYlsACeFE SrvA3JYiRaJATMEAAEKAB0WIQRMcISVXLJjVvC4lX+LPIo+Aiko1QUCZ7cOqwAKCRCLPIo+Aiko 1WB+B/sGNxABjeQAlXGWahE6pllJa60BD2dJK6JoWb6ygju1p7TpDAMrrzrN/Hhu6UpsgF2b0Vp xBkGYh5ze/VPFoiEWAJBfAFybO7frnetNtDUDHdAs7pV+QgKYpQ+xBZJMs/AnNAMvm+5UUaQajN /6GiFhzpK1zS9XxmXpxo9/eq1D/wK20M0GJPd4ZycQXPsEw7eLxUFwLdBBAtky6eoBWRRrh8q76 9raK63egGli8/RYgC0hXKk0kKYhQpyP/FmvHJcl/O9KK/2DkclMrwi54uXNTf3chpDvSUevQcZ4 aB9FW9iG3kZL6VNh67QhnSwTkfVMnBUcmdhCV9CAFBL5DuCM X-Developer-Key: i=dmitry.baryshkov@linaro.org; a=openpgp; fpr=8F88381DD5C873E4AE487DA5199BF1243632046A LVDS support in MDP4 driver makes use of drm_connector directly. However LCDC encoder and LVDS connector are wrappers around drm_panel. Switch them to use drm_panel_bridge/drm_bridge_connector. This allows using standard interface for the drm_panel and also inserting additional bridges between encoder and panel. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/Makefile | 1 - drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c | 34 +++++-- drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.h | 6 +- drivers/gpu/drm/msm/disp/mdp4/mdp4_lcdc_encoder.c | 20 +---- .../gpu/drm/msm/disp/mdp4/mdp4_lvds_connector.c | 100 -----------------= ---- 5 files changed, 28 insertions(+), 133 deletions(-) diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile index 5df20cbeafb8bf07c825a1fd72719d5a56c38613..7a2ada6e2d74a902879e4f12a78= ed475e5209ec2 100644 --- a/drivers/gpu/drm/msm/Makefile +++ b/drivers/gpu/drm/msm/Makefile @@ -48,7 +48,6 @@ msm-display-$(CONFIG_DRM_MSM_MDP4) +=3D \ disp/mdp4/mdp4_dsi_encoder.o \ disp/mdp4/mdp4_dtv_encoder.o \ disp/mdp4/mdp4_lcdc_encoder.o \ - disp/mdp4/mdp4_lvds_connector.o \ disp/mdp4/mdp4_lvds_pll.o \ disp/mdp4/mdp4_irq.o \ disp/mdp4/mdp4_kms.o \ diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c b/drivers/gpu/drm/msm= /disp/mdp4/mdp4_kms.c index 689e210660a5218ed1e2d116073723215af5a187..93c9411eb422bc67b7fedb5ffce= 4c330310b520f 100644 --- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c +++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c @@ -6,6 +6,8 @@ =20 #include =20 +#include +#include #include =20 #include "msm_drv.h" @@ -189,7 +191,7 @@ static int mdp4_modeset_init_intf(struct mdp4_kms *mdp4= _kms, struct msm_drm_private *priv =3D dev->dev_private; struct drm_encoder *encoder; struct drm_connector *connector; - struct device_node *panel_node; + struct drm_bridge *next_bridge; int dsi_id; int ret; =20 @@ -199,27 +201,43 @@ static int mdp4_modeset_init_intf(struct mdp4_kms *md= p4_kms, * bail out early if there is no panel node (no need to * initialize LCDC encoder and LVDS connector) */ - panel_node =3D of_graph_get_remote_node(dev->dev->of_node, 0, 0); - if (!panel_node) - return 0; + next_bridge =3D devm_drm_of_get_bridge(dev->dev, dev->dev->of_node, 0, 0= ); + if (IS_ERR(next_bridge)) { + ret =3D PTR_ERR(next_bridge); + if (ret =3D=3D -ENODEV) + return 0; + return ret; + } =20 - encoder =3D mdp4_lcdc_encoder_init(dev, panel_node); + encoder =3D mdp4_lcdc_encoder_init(dev); if (IS_ERR(encoder)) { DRM_DEV_ERROR(dev->dev, "failed to construct LCDC encoder\n"); - of_node_put(panel_node); return PTR_ERR(encoder); } =20 /* LCDC can be hooked to DMA_P (TODO: Add DMA_S later?) */ encoder->possible_crtcs =3D 1 << DMA_P; =20 - connector =3D mdp4_lvds_connector_init(dev, panel_node, encoder); + ret =3D drm_bridge_attach(encoder, next_bridge, NULL, DRM_BRIDGE_ATTACH_= NO_CONNECTOR); + if (ret) { + DRM_DEV_ERROR(dev->dev, "failed to attach LVDS panel/bridge: %d\n", ret= ); + + return ret; + } + + connector =3D drm_bridge_connector_init(dev, encoder); if (IS_ERR(connector)) { DRM_DEV_ERROR(dev->dev, "failed to initialize LVDS connector\n"); - of_node_put(panel_node); return PTR_ERR(connector); } =20 + ret =3D drm_connector_attach_encoder(connector, encoder); + if (ret) { + DRM_DEV_ERROR(dev->dev, "failed to attach LVDS connector: %d\n", ret); + + return ret; + } + break; case DRM_MODE_ENCODER_TMDS: encoder =3D mdp4_dtv_encoder_init(dev); diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.h b/drivers/gpu/drm/msm= /disp/mdp4/mdp4_kms.h index e0380d3b7e0cee99c4c376bf6369887106f44ede..306f5ca8f810aaeecea56e74065= 933bbffcb67ec 100644 --- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.h +++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.h @@ -191,11 +191,7 @@ struct drm_crtc *mdp4_crtc_init(struct drm_device *dev, long mdp4_dtv_round_pixclk(struct drm_encoder *encoder, unsigned long rate= ); struct drm_encoder *mdp4_dtv_encoder_init(struct drm_device *dev); =20 -struct drm_encoder *mdp4_lcdc_encoder_init(struct drm_device *dev, - struct device_node *panel_node); - -struct drm_connector *mdp4_lvds_connector_init(struct drm_device *dev, - struct device_node *panel_node, struct drm_encoder *encoder); +struct drm_encoder *mdp4_lcdc_encoder_init(struct drm_device *dev); =20 #ifdef CONFIG_DRM_MSM_DSI struct drm_encoder *mdp4_dsi_encoder_init(struct drm_device *dev); diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_lcdc_encoder.c b/drivers/gp= u/drm/msm/disp/mdp4/mdp4_lcdc_encoder.c index cfcedd8a635cf0297365e845ef415a8f0d553183..a4f3edabefbd06286bfb8fbcd7f= 8c0a4281e5ef1 100644 --- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_lcdc_encoder.c +++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_lcdc_encoder.c @@ -14,7 +14,6 @@ =20 struct mdp4_lcdc_encoder { struct drm_encoder base; - struct device_node *panel_node; struct drm_panel *panel; struct clk *lcdc_clk; unsigned long int pixclock; @@ -262,19 +261,12 @@ static void mdp4_lcdc_encoder_disable(struct drm_enco= der *encoder) struct mdp4_lcdc_encoder *mdp4_lcdc_encoder =3D to_mdp4_lcdc_encoder(encoder); struct mdp4_kms *mdp4_kms =3D get_kms(encoder); - struct drm_panel *panel; =20 if (WARN_ON(!mdp4_lcdc_encoder->enabled)) return; =20 mdp4_write(mdp4_kms, REG_MDP4_LCDC_ENABLE, 0); =20 - panel =3D of_drm_find_panel(mdp4_lcdc_encoder->panel_node); - if (!IS_ERR(panel)) { - drm_panel_disable(panel); - drm_panel_unprepare(panel); - } - /* * Wait for a vsync so we know the ENABLE=3D0 latched before * the (connector) source of the vsync's gets disabled, @@ -300,7 +292,6 @@ static void mdp4_lcdc_encoder_enable(struct drm_encoder= *encoder) to_mdp4_lcdc_encoder(encoder); unsigned long pc =3D mdp4_lcdc_encoder->pixclock; struct mdp4_kms *mdp4_kms =3D get_kms(encoder); - struct drm_panel *panel; uint32_t config; int ret; =20 @@ -335,12 +326,6 @@ static void mdp4_lcdc_encoder_enable(struct drm_encode= r *encoder) if (ret) DRM_DEV_ERROR(dev->dev, "failed to enable lcdc_clk: %d\n", ret); =20 - panel =3D of_drm_find_panel(mdp4_lcdc_encoder->panel_node); - if (!IS_ERR(panel)) { - drm_panel_prepare(panel); - drm_panel_enable(panel); - } - setup_phy(encoder); =20 mdp4_write(mdp4_kms, REG_MDP4_LCDC_ENABLE, 1); @@ -375,8 +360,7 @@ static const struct drm_encoder_helper_funcs mdp4_lcdc_= encoder_helper_funcs =3D { }; =20 /* initialize encoder */ -struct drm_encoder *mdp4_lcdc_encoder_init(struct drm_device *dev, - struct device_node *panel_node) +struct drm_encoder *mdp4_lcdc_encoder_init(struct drm_device *dev) { struct drm_encoder *encoder; struct mdp4_lcdc_encoder *mdp4_lcdc_encoder; @@ -387,8 +371,6 @@ struct drm_encoder *mdp4_lcdc_encoder_init(struct drm_d= evice *dev, if (IS_ERR(mdp4_lcdc_encoder)) return ERR_CAST(mdp4_lcdc_encoder); =20 - mdp4_lcdc_encoder->panel_node =3D panel_node; - encoder =3D &mdp4_lcdc_encoder->base; =20 drm_encoder_helper_add(encoder, &mdp4_lcdc_encoder_helper_funcs); diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_lvds_connector.c b/drivers/= gpu/drm/msm/disp/mdp4/mdp4_lvds_connector.c deleted file mode 100644 index 4755eb13ef79f313d2be088145c8cd2e615226fe..000000000000000000000000000= 0000000000000 --- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_lvds_connector.c +++ /dev/null @@ -1,100 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2014 Red Hat - * Author: Rob Clark - * Author: Vinay Simha - */ - -#include "mdp4_kms.h" - -struct mdp4_lvds_connector { - struct drm_connector base; - struct drm_encoder *encoder; - struct device_node *panel_node; - struct drm_panel *panel; -}; -#define to_mdp4_lvds_connector(x) container_of(x, struct mdp4_lvds_connect= or, base) - -static enum drm_connector_status mdp4_lvds_connector_detect( - struct drm_connector *connector, bool force) -{ - struct mdp4_lvds_connector *mdp4_lvds_connector =3D - to_mdp4_lvds_connector(connector); - - if (!mdp4_lvds_connector->panel) { - mdp4_lvds_connector->panel =3D - of_drm_find_panel(mdp4_lvds_connector->panel_node); - if (IS_ERR(mdp4_lvds_connector->panel)) - mdp4_lvds_connector->panel =3D NULL; - } - - return mdp4_lvds_connector->panel ? - connector_status_connected : - connector_status_disconnected; -} - -static void mdp4_lvds_connector_destroy(struct drm_connector *connector) -{ - struct mdp4_lvds_connector *mdp4_lvds_connector =3D - to_mdp4_lvds_connector(connector); - - drm_connector_cleanup(connector); - - kfree(mdp4_lvds_connector); -} - -static int mdp4_lvds_connector_get_modes(struct drm_connector *connector) -{ - struct mdp4_lvds_connector *mdp4_lvds_connector =3D - to_mdp4_lvds_connector(connector); - struct drm_panel *panel =3D mdp4_lvds_connector->panel; - int ret =3D 0; - - if (panel) - ret =3D drm_panel_get_modes(panel, connector); - - return ret; -} - -static const struct drm_connector_funcs mdp4_lvds_connector_funcs =3D { - .detect =3D mdp4_lvds_connector_detect, - .fill_modes =3D drm_helper_probe_single_connector_modes, - .destroy =3D mdp4_lvds_connector_destroy, - .reset =3D drm_atomic_helper_connector_reset, - .atomic_duplicate_state =3D drm_atomic_helper_connector_duplicate_state, - .atomic_destroy_state =3D drm_atomic_helper_connector_destroy_state, -}; - -static const struct drm_connector_helper_funcs mdp4_lvds_connector_helper_= funcs =3D { - .get_modes =3D mdp4_lvds_connector_get_modes, -}; - -/* initialize connector */ -struct drm_connector *mdp4_lvds_connector_init(struct drm_device *dev, - struct device_node *panel_node, struct drm_encoder *encoder) -{ - struct drm_connector *connector =3D NULL; - struct mdp4_lvds_connector *mdp4_lvds_connector; - - mdp4_lvds_connector =3D kzalloc(sizeof(*mdp4_lvds_connector), GFP_KERNEL); - if (!mdp4_lvds_connector) - return ERR_PTR(-ENOMEM); - - mdp4_lvds_connector->encoder =3D encoder; - mdp4_lvds_connector->panel_node =3D panel_node; - - connector =3D &mdp4_lvds_connector->base; - - drm_connector_init(dev, connector, &mdp4_lvds_connector_funcs, - DRM_MODE_CONNECTOR_LVDS); - drm_connector_helper_add(connector, &mdp4_lvds_connector_helper_funcs); - - connector->polled =3D 0; - - connector->interlace_allowed =3D 0; - connector->doublescan_allowed =3D 0; - - drm_connector_attach_encoder(connector, encoder); - - return connector; -} --=20 2.39.5