From nobody Thu Jul 23 21:13:38 2026 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7781F270EDF for ; Thu, 16 Jul 2026 09:01:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784192497; cv=none; b=hSgupbe6SsembhlT0qIclnvaMxSpPSqughE/n17F/2uK4ph3sfqXQjPgjNVrZ4vhq7x89LqAlAmiJR4KmfB9dGFthDjQ2QPcEY1H45a59kpNj/+iXjUjY9BmsMQkCDlRkTY0kpITab2LI+/pMGrIDDL4s046nhurPyFkMitgIq8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784192497; c=relaxed/simple; bh=3hp4tO1y0oFcpTWWTyITDwR1ZTZoHpK33hppfnXMd+4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:To:Cc; b=rE8EmA43Cmq1juu9pAYFiawnZjzAk5MtxarTlIUWQV0vnQHfTyOrcJ+BtOQowKreAlPTGE+0jEDrNURhtC+FcSap5icS/tPh9HS0PYWYu7JD64t7LzSySOJfulgslrflOknlFp5CDdyakE+SfFzKjH76u521GaMtjaF28bJyhR4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=nmOsfkrz; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=ewKgIfJm; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="nmOsfkrz"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="ewKgIfJm" Received: from pps.filterd (m0279869.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 66G7Xc7w2176731 for ; Thu, 16 Jul 2026 09:01:25 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:message-id :mime-version:subject:to; s=qcppdkim1; bh=aHe2m5cGxo06ZLsxAqpXbg szTtwdgYS+yspxkNVpATQ=; b=nmOsfkrzgYk8dE7WGEHfC+v/aGl7NlojS+X5/m H8DLO/nPbeNCHL8dp+qoSQYz938QVV9Qbvcy/+gtd5IJrDzxmpiA9m3+O6Y3nh32 GpV1JFzfBh1eXTSehRUBXTrWx/eT1hJA2JB09q6mA1obCYbp5GiaZP92oSUA6NPZ u9qFB+pj8R3c04MnbEPArseQpipLubQZxDJLlVJS36zJcUxkITNj49E45ss4dK2O mlh42d/g+tfaVjsslxG2Oz6hsv3CFqj6Skz7lpUXRQru7yr61Qfu4SCWztYOv8sP 6S+6bErqhsvIzOjBc67gs9amgTGdFgT1LKfXNY0aNj84/ndA== Received: from mail-pf1-f199.google.com (mail-pf1-f199.google.com [209.85.210.199]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4feu108a5r-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Thu, 16 Jul 2026 09:01:25 +0000 (GMT) Received: by mail-pf1-f199.google.com with SMTP id d2e1a72fcca58-84a3514f912so7743972b3a.3 for ; Thu, 16 Jul 2026 02:01:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1784192485; x=1784797285; darn=vger.kernel.org; h=cc:to:message-id:content-transfer-encoding:content-type :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to:content-type; bh=aHe2m5cGxo06ZLsxAqpXbgszTtwdgYS+yspxkNVpATQ=; b=ewKgIfJmH1XfCc2BNh3JJ7+wYRVmvKk2WfCfTxWKrcYn2M7IxuuglAd5KEf/hxAa1S cgYZQ0CWq4ZTxYh2eN8w755JsmAscg1XwNdRA6VDoFzK9mjYh3CpCj5GAjNpoPrW53LE QsedWwZ0W/HnJo19+aTPt/61g9LQVbJfkcfF6k/jyyXxXJa96B87sLvEeH+sK1CUyKUT RUhk54wQtucXmA8xTGVfqBZYDccTU0i0UUv+sy9C0skxrCemFihT9NXzDoGPNuBUIqU3 K8E0MpijuinZU3mISaeC62PbG6lLARC6WhXY5ELrzOr0NeRDQsb6Z3Zs/YXx3k/nuQD3 Klsg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1784192485; x=1784797285; h=cc:to:message-id:content-transfer-encoding:content-type :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to:content-type; bh=aHe2m5cGxo06ZLsxAqpXbgszTtwdgYS+yspxkNVpATQ=; b=mYQ9qLqG01cP/nkRwfFJVezWHSb2YWk5vfnpPfUx1lRukNXzh+aCYiGZv48oZQF8V9 VqiYDaX0mUWEiBnSTBwXYXwEV4eDtXl4UgkpGGtr5jnH+qfoWJpsc6eQvgFZnc1KPYDL XCNJWrUWlU+eSwf0RSRIn3VLqv5cPtAsqXnGjJBKJZfbANYWQD7cDqtJCpSLyIHeqWqj h84jqY9GrGx316UwqKo69NyrXP+s3ToPpc/WCDUOzDKxCDm/MZDNQo75m7HNE/4fWBIp f4hjqEWvDGmPLkiRsfoHBfrfdnLbaK9AcLE2yqFoXJAVDda2tA+VhzPCjLFv3ECw1jaE R1HA== X-Forwarded-Encrypted: i=1; AHgh+RqZn25hOnKlCpkDjv3ZgAFmHqqW96vWxFQPeLGulQdzgtivKGED1eq+meq+IjImPxSzazFjKwwb7Cp8dXU=@vger.kernel.org X-Gm-Message-State: AOJu0YwDWP0FZePdAIALGg+CGSA0UKQCPS79HKqwWEiZT7A9duE3r9be TsC/e/d481JsE3J+EqgVg/KFJYXH4aPLNmHHXwpLd111nh883TogJNdNcMO3NK2RTiQ3PEcck6D UXUv0RbgQ9zc4wl69JmuShZ/uuknq5zq5NQpjgtfgjQRUaTrYVckxcFYWl1gE9vnCuMU= X-Gm-Gg: AfdE7cmscDJpOvkFVNxWQjfeViGdgL0+8gCvRI5yM//ISY2cHLO6GvkpglCUjf7rP2D jfpTrSKetWC35jWJpluo1rC1i0MmWkbUoxA/5e/r6T7hEyXSEIuAfI8JnSEnC7rrenERkjIYVQf N+bGk+jZIQWRgHmzkbsfGRkW70rqJWb4H2ta7c+Tdnh7eJA1A1h0u8eSwLFeXKX0pGXcSWWHeRI l2DSMK/QBxubjKY0lvTbsB9ALpaXvtHGcwXP/onEQjPAnv2hxBoDDk7vdj99GY3Qy3qNvPe4u5i VxVb3TpN5bFJlSVfYzzzp0Xk2bisWPnqkqOSv+LxBOlcXfkHqYwvGsxKt6gfq6bHDkaZ8Rn6olu gRKfOqyGDfu8bDwXTC28q X-Received: by 2002:a05:6a00:1943:b0:848:2f73:9000 with SMTP id d2e1a72fcca58-84a5165c6b1mr10202988b3a.73.1784192484353; Thu, 16 Jul 2026 02:01:24 -0700 (PDT) X-Received: by 2002:a05:6a00:1943:b0:848:2f73:9000 with SMTP id d2e1a72fcca58-84a5165c6b1mr10202941b3a.73.1784192483796; Thu, 16 Jul 2026 02:01:23 -0700 (PDT) Received: from le-cd01-lnx.qualcomm.com ([114.94.8.21]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-84a4ff2ea4csm4440058b3a.23.2026.07.16.02.01.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 16 Jul 2026 02:01:23 -0700 (PDT) From: Ze Huang Date: Thu, 16 Jul 2026 17:00:55 +0800 Subject: [PATCH v2] drm/imx: replace struct drm_simple_display_pipe with regular atomic helpers 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: <20260716-drm-simple-kms-removal-v2-1-7e4a6b8528e6@oss.qualcomm.com> X-B4-Tracking: v=1; b=H4sIAMedWGoC/3WOwQ6CMBBEf4Xs2TVtUYye/A/jodRVq5RitxAM4 d9t0auXSSaZmTcTMAVLDIdigkCDZevbZNSqAHPX7Y3QXpIHJVQldmKDl+CQresawqdjDOT8oBs UUotSmkpLtYdU7gJd7bgMn85fz339IBPz2i8R6NUnYvzGoNZMaLxzNh6KzGlpjJjJKCpUO8hDd 8vRh/dyeJBL7/dt++/bIFFgvSFptNiWlSqPnnn96nWTYeskcJ7n+QMga11FDAEAAA== X-Change-ID: 20260704-drm-simple-kms-removal-01a031c6a129 To: Alexey Brodkin , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Joel Stanley , Andrew Jeffery , Frank Li , Sascha Hauer , Pengutronix Kernel Team , Fabio Estevam , Linus Walleij , Hans de Goede , Alex Lanzano , Oleksandr Andrushchenko Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-aspeed@lists.ozlabs.org, linux-arm-kernel@lists.infradead.org, imx@lists.linux.dev, xen-devel@lists.xenproject.org, Ze Huang X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1784192476; l=16288; i=ze.huang@oss.qualcomm.com; s=20260716; h=from:subject:message-id; bh=3hp4tO1y0oFcpTWWTyITDwR1ZTZoHpK33hppfnXMd+4=; b=ygE4iQN91kshn1fAtLPBD1T04zXm+5QGjsvBJpjxYZR+XTulSruGaQl49D910M0pnIHV5qe0y 4P9ah08N3WoBO3SE/69g2+APQJ0bdr+26XKTTrtiC+asfnaDiwJMyWs X-Developer-Key: i=ze.huang@oss.qualcomm.com; a=ed25519; pk=8uGhlZHInA8NXq7G6u/g59qEcwXwuMRI7nBSnT/ijtY= X-Proofpoint-ORIG-GUID: wcRINgyfzr83M9ItiIXWF4e6LEvHSAvT X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzE2MDA5MSBTYWx0ZWRfXwFXa4jLHdJ1Z bVR1/3tBCQiOydKHBWtzl3ouT/fJo9QQF8ARQToKY7l6yXWDaOb/NHh4K9RHBojKHVI1O+7vOnK eH5Wm5zzgLtjUQ4EVvjL8FTEa3cC1IvN9PZbeIy/G4UNyOBnveOgLRORPksGvzn+9FWrvfsfAsk 7EW9LI3TDxneBZiGkyAgVGdjQVObIJZoapAiWWs/KVxjL8Lk8/hmWlr5GxL/OvdFkSehn0Vb4ZI /vSOJw5MTzhr1euLWIdZMkaaxXwnfYAj9OZ6NblCl3YfOlAh0wqHwc4hpFusZoEro7IA9v84x8S 8WA7ws0cHfhKmlMtf+BSIjYWZQ8BNOW9bpAjqhSIjOdA/UiFXj/61DRZz3RR/W7S4qyg3DrM2f6 ELV8q16MoTJlm/Y68wuhk9+lF0TSudzYi9O0SlUyaIgGdsk2ekFI58gOyBI64kCHLnObIfnHLoN XX8Vt1weuooVz03B/5w== X-Proofpoint-GUID: wcRINgyfzr83M9ItiIXWF4e6LEvHSAvT X-Authority-Analysis: v=2.4 cv=BPODalQG c=1 sm=1 tr=0 ts=6a589de5 cx=c_pps a=WW5sKcV1LcKqjgzy2JUPuA==:117 a=Uz3yg00KUFJ2y2WijEJ4bw==:17 a=IkcTkHD0fZMA:10 a=RAioF0-LDSMA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=_glEPmIy2e8OvE2BGh3C:22 a=bC-a23v3AAAA:8 a=EUspDBNiAAAA:8 a=vJQh6MS5x5Z9w99ZfooA:9 a=QEXdDO2ut3YA:10 a=OpyuDcXvxspvyRM73sMx:22 a=FO4_E8m0qiDe52t0p3_H:22 X-Proofpoint-Spam-Info: AW1haW4tMjYwNzE2MDA5MSBTYWx0ZWRfX3JlSLZyCyOEc 2jslG2qTsUn/LvIgwSQwI+8dswHlfTlEPJ4zpo6K5TehI9i1R5MPj42Ga3krwnKZCGJB1FMMcCa Pv7LjyfvoCnINsiac+WjTfVklvOdN94= X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-07-16_03,2026-07-15_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 suspectscore=0 lowpriorityscore=0 adultscore=0 malwarescore=0 priorityscore=1501 phishscore=0 bulkscore=0 spamscore=0 impostorscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2607160091 Convert i.MX LCDC to explicit primary plane, CRTC and encoder objects. Keep no-scaling plane check and GEM framebuffer prepare callback from simple-KMS path. Wire the vblank lifecycle explicitly with CRTC vblank callbacks and drm_crtc_vblank_on()/drm_crtc_vblank_off(). Use the old CRTC state in the disable path for clock unwinding so the clock reference count remains paired with the previous active state. Signed-off-by: Ze Huang --- struct drm_simple_display_pipe was meant to simplify simple DRM drivers, but instead adds an extra wrapper around normal DRM atomic helper setup. As noted in Documentation/gpu/todo.rst, remaining users should be converted to regular atomic helpers and stop depending on the simple-KMS interfaces. Each patch replaces drm_simple_display_pipe_init() with explicit primary plane, CRTC and encoder setup, and moves the old simple-pipe callbacks into regular plane and CRTC helper callbacks named according to local driver conventions. The conversions preserve helper behavior that used to be implicit in drm_simple_kms_helper.c, including plane-state validation, CRTC primary-plane checks, affected-plane propagation, framebuffer prepare handling, and existing event/vblank flow where applicable. Result is less helper indirection and more explicit driver-side atomic wiring, with no remaining simple-KMS dependency in these drivers. Changes are build-tested only. No hardware testing has been performed. This patch is based on drm-next-2026-06-27. AI usage disclosure: - AI tools were also used to review the code and suggest code changes for the DRM atomic conversion. Thanks, Ze Huang --- Changes in v2: - use 'commit' as name of struct drm_atomic_commit in atomic helpers - improve control flow in *_crtc_helper_atomic_check() and *_plane_helper_atomic_check() - Moved page-flip/vblank event handling out of plane update paths and into CRTC atomic_flush(), using atomic_flush and disable paths - decide clock disable by old crtc state - add calls to drm_crtc_vblank_on() and drm_crtc_vblank_off() in crtc atomic_enable() and atomic_disbale() - test crtc_state->enable before mode size check - Link to v1: https://patch.msgid.link/20260705-drm-simple-kms-removal-v1-0= -b4e1ca053623@oss.qualcomm.com --- drivers/gpu/drm/imx/lcdc/imx-lcdc.c | 217 ++++++++++++++++++++++++++------= ---- 1 file changed, 159 insertions(+), 58 deletions(-) diff --git a/drivers/gpu/drm/imx/lcdc/imx-lcdc.c b/drivers/gpu/drm/imx/lcdc= /imx-lcdc.c index f52832b43aca..78eac2c4a54c 100644 --- a/drivers/gpu/drm/imx/lcdc/imx-lcdc.c +++ b/drivers/gpu/drm/imx/lcdc/imx-lcdc.c @@ -14,9 +14,9 @@ #include #include #include +#include #include #include -#include #include #include #include @@ -102,7 +102,9 @@ =20 struct imx_lcdc { struct drm_device drm; - struct drm_simple_display_pipe pipe; + struct drm_plane plane; + struct drm_crtc crtc; + struct drm_encoder encoder; struct drm_connector *connector; void __iomem *base; =20 @@ -135,14 +137,13 @@ static unsigned int imx_lcdc_get_format(unsigned int = drm_format) } } =20 -static void imx_lcdc_update_hw_registers(struct drm_simple_display_pipe *p= ipe, +static void imx_lcdc_update_hw_registers(struct drm_crtc *crtc, struct drm_plane_state *old_state, bool mode_set) { - struct drm_crtc *crtc =3D &pipe->crtc; - struct drm_plane_state *new_state =3D pipe->plane.state; + struct imx_lcdc *lcdc =3D imx_lcdc_from_drmdev(crtc->dev); + struct drm_plane_state *new_state =3D lcdc->plane.state; struct drm_framebuffer *fb =3D new_state->fb; - struct imx_lcdc *lcdc =3D imx_lcdc_from_drmdev(pipe->crtc.dev); u32 lpcr, lvcr, lhcr; u32 framesize; dma_addr_t addr; @@ -188,15 +189,16 @@ static void imx_lcdc_update_hw_registers(struct drm_s= imple_display_pipe *pipe, clk_prepare_enable(lcdc->clk_per); } =20 -static void imx_lcdc_pipe_enable(struct drm_simple_display_pipe *pipe, - struct drm_crtc_state *crtc_state, - struct drm_plane_state *plane_state) +static void imx_lcdc_crtc_helper_atomic_enable(struct drm_crtc *crtc, + struct drm_atomic_commit *commit) { int ret; int clk_div; int bpp; - struct imx_lcdc *lcdc =3D imx_lcdc_from_drmdev(pipe->crtc.dev); - struct drm_display_mode *mode =3D &pipe->crtc.mode; + struct imx_lcdc *lcdc =3D imx_lcdc_from_drmdev(crtc->dev); + struct drm_crtc_state *cstate =3D drm_atomic_get_new_crtc_state(commit, c= rtc); + struct drm_plane_state *plane_state =3D lcdc->plane.state; + struct drm_display_mode *mode =3D &cstate->mode; struct drm_display_info *disp_info =3D &lcdc->connector->display_info; const int hsync_pol =3D (mode->flags & DRM_MODE_FLAG_PHSYNC) ? 0 : 1; const int vsync_pol =3D (mode->flags & DRM_MODE_FLAG_PVSYNC) ? 0 : 1; @@ -231,40 +233,46 @@ static void imx_lcdc_pipe_enable(struct drm_simple_di= splay_pipe *pipe, =20 ret =3D clk_prepare_enable(lcdc->clk_ipg); if (ret) { - dev_err(pipe->crtc.dev->dev, "Cannot enable ipg clock: %pe\n", ERR_PTR(r= et)); + dev_err(crtc->dev->dev, "Cannot enable ipg clock: %pe\n", ERR_PTR(ret)); return; } ret =3D clk_prepare_enable(lcdc->clk_ahb); if (ret) { - dev_err(pipe->crtc.dev->dev, "Cannot enable ahb clock: %pe\n", ERR_PTR(r= et)); + dev_err(crtc->dev->dev, "Cannot enable ahb clock: %pe\n", ERR_PTR(ret)); =20 clk_disable_unprepare(lcdc->clk_ipg); =20 return; } =20 - imx_lcdc_update_hw_registers(pipe, NULL, true); + imx_lcdc_update_hw_registers(crtc, NULL, true); =20 /* Enable VBLANK Interrupt */ writel(INTR_EOF, lcdc->base + IMX21LCDC_LIER); + + drm_crtc_vblank_on(crtc); } =20 -static void imx_lcdc_pipe_disable(struct drm_simple_display_pipe *pipe) +static void imx_lcdc_crtc_helper_atomic_disable(struct drm_crtc *crtc, + struct drm_atomic_commit *commit) { - struct imx_lcdc *lcdc =3D imx_lcdc_from_drmdev(pipe->crtc.dev); - struct drm_crtc *crtc =3D &lcdc->pipe.crtc; + struct drm_crtc_state *old_crtc_state =3D drm_atomic_get_old_crtc_state(c= ommit, crtc); + struct drm_crtc_state *new_crtc_state =3D drm_atomic_get_new_crtc_state(c= ommit, crtc); + struct imx_lcdc *lcdc =3D imx_lcdc_from_drmdev(crtc->dev); struct drm_pending_vblank_event *event; =20 + drm_crtc_vblank_off(crtc); + clk_disable_unprepare(lcdc->clk_ahb); clk_disable_unprepare(lcdc->clk_ipg); =20 - if (pipe->crtc.enabled) + if (old_crtc_state->enable) clk_disable_unprepare(lcdc->clk_per); =20 spin_lock_irq(&lcdc->drm.event_lock); - event =3D crtc->state->event; + event =3D new_crtc_state->event; if (event) { - crtc->state->event =3D NULL; + new_crtc_state->event =3D NULL; drm_crtc_send_vblank_event(crtc, event); } spin_unlock_irq(&lcdc->drm.event_lock); @@ -273,17 +281,20 @@ static void imx_lcdc_pipe_disable(struct drm_simple_d= isplay_pipe *pipe) writel(0, lcdc->base + IMX21LCDC_LIER); } =20 -static int imx_lcdc_pipe_check(struct drm_simple_display_pipe *pipe, - struct drm_plane_state *plane_state, - struct drm_crtc_state *crtc_state) +static int imx_lcdc_crtc_helper_atomic_check(struct drm_crtc *crtc, + struct drm_atomic_commit *commit) { + struct drm_crtc_state *crtc_state =3D drm_atomic_get_new_crtc_state(commi= t, crtc); + struct drm_crtc_state *old_crtc_state =3D drm_atomic_get_old_crtc_state(c= ommit, crtc); const struct drm_display_mode *mode =3D &crtc_state->mode; - const struct drm_display_mode *old_mode =3D &pipe->crtc.state->mode; + const struct drm_display_mode *old_mode =3D &old_crtc_state->mode; + int ret; =20 - if (mode->hdisplay < LCDC_MIN_XRES || mode->hdisplay > LCDC_MAX_XRES || - mode->vdisplay < LCDC_MIN_YRES || mode->vdisplay > LCDC_MAX_YRES || - mode->hdisplay % 0x10) { /* must be multiple of 16 */ - drm_err(pipe->crtc.dev, "unsupported display mode (%u x %u)\n", + if (crtc_state->enable && + (mode->hdisplay < LCDC_MIN_XRES || mode->hdisplay > LCDC_MAX_XRES || + mode->vdisplay < LCDC_MIN_YRES || mode->vdisplay > LCDC_MAX_YRES || + mode->hdisplay % 0x10)) { /* must be multiple of 16 */ + drm_err(crtc->dev, "unsupported display mode (%u x %u)\n", mode->hdisplay, mode->vdisplay); return -EINVAL; } @@ -292,46 +303,116 @@ static int imx_lcdc_pipe_check(struct drm_simple_dis= play_pipe *pipe, old_mode->hdisplay !=3D mode->hdisplay || old_mode->vdisplay !=3D mode->vdisplay; =20 - return 0; + if (crtc_state->enable) { + ret =3D drm_atomic_helper_check_crtc_primary_plane(crtc_state); + if (ret) + return ret; + } + + return drm_atomic_add_affected_planes(commit, crtc); } =20 -static void imx_lcdc_pipe_update(struct drm_simple_display_pipe *pipe, - struct drm_plane_state *old_state) +static void imx_lcdc_plane_helper_atomic_update(struct drm_plane *plane, + struct drm_atomic_commit *commit) { - struct drm_crtc *crtc =3D &pipe->crtc; - struct drm_pending_vblank_event *event =3D crtc->state->event; - struct drm_plane_state *new_state =3D pipe->plane.state; + struct drm_plane_state *old_state =3D drm_atomic_get_old_plane_state(comm= it, plane); + struct drm_plane_state *new_state =3D drm_atomic_get_new_plane_state(comm= it, plane); + struct drm_crtc *crtc =3D new_state->crtc ?: old_state->crtc; struct drm_framebuffer *fb =3D new_state->fb; struct drm_framebuffer *old_fb =3D old_state->fb; struct drm_crtc *old_crtc =3D old_state->crtc; bool mode_changed =3D false; =20 + if (!fb) + return; + if (old_fb && old_fb->format !=3D fb->format) mode_changed =3D true; else if (old_crtc !=3D crtc) mode_changed =3D true; =20 - imx_lcdc_update_hw_registers(pipe, old_state, mode_changed); + imx_lcdc_update_hw_registers(crtc, old_state, mode_changed); +} =20 - if (event) { - crtc->state->event =3D NULL; +static int imx_lcdc_plane_helper_atomic_check(struct drm_plane *plane, + struct drm_atomic_commit *commit) +{ + struct drm_plane_state *plane_state =3D drm_atomic_get_new_plane_state(co= mmit, plane); + struct drm_crtc *crtc =3D plane_state->crtc; + struct drm_crtc_state *crtc_state =3D NULL; =20 - spin_lock_irq(&crtc->dev->event_lock); + if (crtc) + crtc_state =3D drm_atomic_get_new_crtc_state(commit, crtc); =20 - if (crtc->state->active && drm_crtc_vblank_get(crtc) =3D=3D 0) - drm_crtc_arm_vblank_event(crtc, event); - else - drm_crtc_send_vblank_event(crtc, event); + return drm_atomic_helper_check_plane_state(plane_state, crtc_state, + DRM_PLANE_NO_SCALING, + DRM_PLANE_NO_SCALING, + false, false); +} =20 - spin_unlock_irq(&crtc->dev->event_lock); - } +static const struct drm_plane_helper_funcs imx_lcdc_plane_helper_funcs =3D= { + .prepare_fb =3D drm_gem_plane_helper_prepare_fb, + .atomic_check =3D imx_lcdc_plane_helper_atomic_check, + .atomic_update =3D imx_lcdc_plane_helper_atomic_update, +}; + +static const struct drm_plane_funcs imx_lcdc_plane_funcs =3D { + .update_plane =3D drm_atomic_helper_update_plane, + .disable_plane =3D drm_atomic_helper_disable_plane, + .destroy =3D drm_plane_cleanup, + .reset =3D drm_atomic_helper_plane_reset, + .atomic_duplicate_state =3D drm_atomic_helper_plane_duplicate_state, + .atomic_destroy_state =3D drm_atomic_helper_plane_destroy_state, +}; + +static void imx_lcdc_crtc_helper_atomic_flush(struct drm_crtc *crtc, + struct drm_atomic_commit *commit) +{ + struct drm_crtc_state *new_crtc_state =3D drm_atomic_get_new_crtc_state(c= ommit, crtc); + struct drm_pending_vblank_event *event =3D new_crtc_state->event; + + if (!event) + return; + + new_crtc_state->event =3D NULL; + + spin_lock_irq(&crtc->dev->event_lock); + if (new_crtc_state->active && drm_crtc_vblank_get(crtc) =3D=3D 0) + drm_crtc_arm_vblank_event(crtc, event); + else + drm_crtc_send_vblank_event(crtc, event); + spin_unlock_irq(&crtc->dev->event_lock); } =20 -static const struct drm_simple_display_pipe_funcs imx_lcdc_pipe_funcs =3D { - .enable =3D imx_lcdc_pipe_enable, - .disable =3D imx_lcdc_pipe_disable, - .check =3D imx_lcdc_pipe_check, - .update =3D imx_lcdc_pipe_update, +static const struct drm_crtc_helper_funcs imx_lcdc_crtc_helper_funcs =3D { + .atomic_check =3D imx_lcdc_crtc_helper_atomic_check, + .atomic_enable =3D imx_lcdc_crtc_helper_atomic_enable, + .atomic_disable =3D imx_lcdc_crtc_helper_atomic_disable, + .atomic_flush =3D imx_lcdc_crtc_helper_atomic_flush, +}; + +static int imx_lcdc_crtc_enable_vblank(struct drm_crtc *crtc) +{ + return 0; +} + +static void imx_lcdc_crtc_disable_vblank(struct drm_crtc *crtc) +{ +} + +static const struct drm_crtc_funcs imx_lcdc_crtc_funcs =3D { + .reset =3D drm_atomic_helper_crtc_reset, + .destroy =3D drm_crtc_cleanup, + .set_config =3D drm_atomic_helper_set_config, + .page_flip =3D drm_atomic_helper_page_flip, + .atomic_duplicate_state =3D drm_atomic_helper_crtc_duplicate_state, + .atomic_destroy_state =3D drm_atomic_helper_crtc_destroy_state, + .enable_vblank =3D imx_lcdc_crtc_enable_vblank, + .disable_vblank =3D imx_lcdc_crtc_disable_vblank, +}; + +static const struct drm_encoder_funcs imx_lcdc_encoder_funcs =3D { + .destroy =3D drm_encoder_cleanup, }; =20 static const struct drm_mode_config_funcs imx_lcdc_mode_config_funcs =3D { @@ -369,7 +450,7 @@ MODULE_DEVICE_TABLE(of, imx_lcdc_of_dev_id); static irqreturn_t imx_lcdc_irq_handler(int irq, void *arg) { struct imx_lcdc *lcdc =3D arg; - struct drm_crtc *crtc =3D &lcdc->pipe.crtc; + struct drm_crtc *crtc =3D &lcdc->crtc; unsigned int status; =20 status =3D readl(lcdc->base + IMX21LCDC_LISR); @@ -387,6 +468,9 @@ static int imx_lcdc_probe(struct platform_device *pdev) struct imx_lcdc *lcdc; struct drm_device *drm; struct drm_bridge *bridge; + struct drm_plane *plane; + struct drm_crtc *crtc; + struct drm_encoder *encoder; int irq; int ret; struct device *dev =3D &pdev->dev; @@ -428,23 +512,40 @@ static int imx_lcdc_probe(struct platform_device *pde= v) if (ret) return dev_err_probe(dev, ret, "Cannot initialize mode configuration str= ucture\n"); =20 - /* CRTC, Plane, Encoder */ - ret =3D drm_simple_display_pipe_init(drm, &lcdc->pipe, - &imx_lcdc_pipe_funcs, - imx_lcdc_formats, - ARRAY_SIZE(imx_lcdc_formats), NULL, NULL); + plane =3D &lcdc->plane; + ret =3D drm_universal_plane_init(drm, plane, 0, + &imx_lcdc_plane_funcs, + imx_lcdc_formats, + ARRAY_SIZE(imx_lcdc_formats), + NULL, + DRM_PLANE_TYPE_PRIMARY, NULL); + if (ret < 0) + return dev_err_probe(drm->dev, ret, "Cannot initialize primary plane\n"); + drm_plane_helper_add(plane, &imx_lcdc_plane_helper_funcs); + + crtc =3D &lcdc->crtc; + ret =3D drm_crtc_init_with_planes(drm, crtc, plane, NULL, + &imx_lcdc_crtc_funcs, NULL); + if (ret < 0) + return dev_err_probe(drm->dev, ret, "Cannot initialize CRTC\n"); + drm_crtc_helper_add(crtc, &imx_lcdc_crtc_helper_funcs); + + encoder =3D &lcdc->encoder; + ret =3D drm_encoder_init(drm, encoder, &imx_lcdc_encoder_funcs, + DRM_MODE_ENCODER_NONE, NULL); if (ret < 0) - return dev_err_probe(drm->dev, ret, "Cannot setup simple display pipe\n"= ); + return dev_err_probe(drm->dev, ret, "Cannot initialize encoder\n"); + encoder->possible_crtcs =3D drm_crtc_mask(crtc); =20 ret =3D drm_vblank_init(drm, drm->mode_config.num_crtc); if (ret < 0) return dev_err_probe(drm->dev, ret, "Failed to initialize vblank\n"); =20 - ret =3D drm_bridge_attach(&lcdc->pipe.encoder, bridge, NULL, DRM_BRIDGE_A= TTACH_NO_CONNECTOR); + ret =3D drm_bridge_attach(encoder, bridge, NULL, DRM_BRIDGE_ATTACH_NO_CON= NECTOR); if (ret) return dev_err_probe(drm->dev, ret, "Cannot attach bridge\n"); =20 - lcdc->connector =3D drm_bridge_connector_init(drm, &lcdc->pipe.encoder); + lcdc->connector =3D drm_bridge_connector_init(drm, encoder); if (IS_ERR(lcdc->connector)) return dev_err_probe(drm->dev, PTR_ERR(lcdc->connector), "Cannot init br= idge connector\n"); =20 --- base-commit: 3696d07837d1df13a5603d77f667685e7dfb3c53 change-id: 20260704-drm-simple-kms-removal-01a031c6a129 Best regards, --=20 Ze Huang