From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 46A09FC72CB for ; Sun, 22 Mar 2026 17:02:31 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id A13BD10E2CD; Sun, 22 Mar 2026 17:02:30 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; secure) header.d=disroot.org header.i=@disroot.org header.b="J627CRo5"; dkim-atps=neutral Received: from layka.disroot.org (layka.disroot.org [178.21.23.139]) by gabe.freedesktop.org (Postfix) with ESMTPS id 60D1310E2CD for ; Sun, 22 Mar 2026 17:02:29 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by disroot.org (Postfix) with ESMTP id 3AA1B26F6F; Sun, 22 Mar 2026 18:02:28 +0100 (CET) X-Virus-Scanned: SPAM Filter at disroot.org Received: from layka.disroot.org ([127.0.0.1]) by localhost (disroot.org [127.0.0.1]) (amavis, port 10024) with ESMTP id VMgIJGJVi2Y4; Sun, 22 Mar 2026 18:02:27 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=disroot.org; s=mail; t=1774198947; bh=3sJl0Qt09rxEYSVKVcG7DazowGZnxFL0i9HaOoCC1Zk=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=J627CRo5rJ/kANo8cUjAofAzB0QIFI1ADKBXA5ytq9UVNEtD06pzxlWCPDNKhkUmW +AAqJQRZ1aJetfKSu7oJTHO0pZkwxAQ/zy05LqOFTYJerr+j1fPSmOC4PsQKiFJq7d 2DMuHDNrsQ1e/dF0a/pwX7pFqSxkr5uFhgdeeU3KXne/RdLVOUMb6ds15w4wFmUjZy YpZBsL/M5TjCUmvId7nUgMT+M+M3DV6oGXyGNluw7Jw0QpgForCNqKbdjvZxUTg1lJ WKbcBzFzbl0MBpPYxGckecNgaIjyN/ZyUTHpWjbRUKCepDAnc4gycCeMECSmj4EmSA TfkQAkFhkdj6w== From: Kaustabh Chakraborty Date: Sun, 22 Mar 2026 22:32:07 +0530 Subject: [PATCH RESEND v2 2/2] drm/bridge: samsung-dsim: use DSIM interrupt to wait for PLL stability MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Message-Id: <20260322-exynos-dsim-fixes-v2-2-0069c9e1d9bf@disroot.org> References: <20260322-exynos-dsim-fixes-v2-0-0069c9e1d9bf@disroot.org> In-Reply-To: <20260322-exynos-dsim-fixes-v2-0-0069c9e1d9bf@disroot.org> To: Inki Dae , Jagan Teki , Marek Szyprowski , Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, Kaustabh Chakraborty X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Stabilizing PLL needs to be waited for. This is done using a loop, checking the PLL_STABLE bit in the status register. DSIM fires an interrupt when the PLL is stabilized. Rely on this functionality for stabilization wait, getting rid of the implicit loop. This has been tested on a Galaxy J6 (Exynos 7870). Unfortunately, since testing on all supported devices is less feasible, introduce a stop-gap measure where the timeout has a gracious lower bound of 100 microseconds. This will (hopefully) prevent regressions due to timeout on other devices. Suggested-by: Inki Dae Link: https://lore.kernel.org/r/CAAQKjZMLMbwDVZRb5+Xb_5yz3AEP4uuzFJMuuZy9NFDu13VU5w@mail.gmail.com Tested-by: Marek Szyprowski Signed-off-by: Kaustabh Chakraborty --- drivers/gpu/drm/bridge/samsung-dsim.c | 41 +++++++++++++++++++++++------------ include/drm/bridge/samsung-dsim.h | 1 + 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/bridge/samsung-dsim.c b/drivers/gpu/drm/bridge/samsung-dsim.c index 70f8946ad3b24..0ca6c6484c9a6 100644 --- a/drivers/gpu/drm/bridge/samsung-dsim.c +++ b/drivers/gpu/drm/bridge/samsung-dsim.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -788,7 +789,7 @@ static unsigned long samsung_dsim_set_pll(struct samsung_dsim *dsi, { const struct samsung_dsim_driver_data *driver_data = dsi->driver_data; unsigned long fin, fout; - int timeout; + unsigned int timeout; u8 p, s; u16 m; u32 reg; @@ -849,19 +850,26 @@ static unsigned long samsung_dsim_set_pll(struct samsung_dsim *dsi, if (dsi->swap_dn_dp_data) reg |= DSIM_PLL_DPDNSWAP_DAT; + /* + * The PLL_TIMER value is the product of the timeout delay and the APB + * bus clock rate. Calcutate the timeout delay on-the-fly here. + * It is assumed that the bus clock is the first clock in the provided + * bulk clock data. + */ + timeout = 100; + fin = clk_get_rate(dsi->driver_data->clk_data[0].clk) / HZ_PER_MHZ; + if (fin) + timeout = max(dsi->driver_data->reg_values[PLL_TIMER] / fin, + timeout); + + reinit_completion(&dsi->pll_stabilized); samsung_dsim_write(dsi, DSIM_PLLCTRL_REG, reg); - timeout = 3000; - do { - if (timeout-- == 0) { - dev_err(dsi->dev, "PLL failed to stabilize\n"); - return 0; - } - if (driver_data->has_legacy_status_reg) - reg = samsung_dsim_read(dsi, DSIM_STATUS_REG); - else - reg = samsung_dsim_read(dsi, DSIM_LINK_STATUS_REG); - } while ((reg & BIT(driver_data->pll_stable_bit)) == 0); + if (wait_for_completion_timeout(&dsi->pll_stabilized, + usecs_to_jiffies(timeout))) { + dev_err(dsi->dev, "PLL failed to stabilize\n"); + return 0; + } dsi->hs_clock = fout; @@ -1596,8 +1604,12 @@ static irqreturn_t samsung_dsim_irq(int irq, void *dev_id) return IRQ_HANDLED; } - if (!(status & (DSIM_INT_RX_DONE | DSIM_INT_SFR_FIFO_EMPTY | - DSIM_INT_PLL_STABLE))) + if (status & DSIM_INT_PLL_STABLE) { + complete(&dsi->pll_stabilized); + return IRQ_HANDLED; + } + + if (!(status & (DSIM_INT_RX_DONE | DSIM_INT_SFR_FIFO_EMPTY))) return IRQ_HANDLED; if (samsung_dsim_transfer_finish(dsi)) @@ -2146,6 +2158,7 @@ int samsung_dsim_probe(struct platform_device *pdev) return PTR_ERR(dsi); init_completion(&dsi->completed); + init_completion(&dsi->pll_stabilized); spin_lock_init(&dsi->transfer_lock); INIT_LIST_HEAD(&dsi->transfer_list); diff --git a/include/drm/bridge/samsung-dsim.h b/include/drm/bridge/samsung-dsim.h index 03005e474704b..e3433da21ad08 100644 --- a/include/drm/bridge/samsung-dsim.h +++ b/include/drm/bridge/samsung-dsim.h @@ -123,6 +123,7 @@ struct samsung_dsim { int state; struct drm_property *brightness; struct completion completed; + struct completion pll_stabilized; spinlock_t transfer_lock; /* protects transfer_list */ struct list_head transfer_list; -- 2.53.0