From nobody Thu Mar 5 08:15:38 2026 Received: from ms.puri.sm (ms.puri.sm [135.181.196.210]) (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 8EEA318A6A8 for ; Tue, 17 Feb 2026 08:31:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=135.181.196.210 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771317095; cv=none; b=UY1zmqrsbC6lV4gWyyxGwmUzS8zmQcWrscINSkFccpIBoc9CGu70e9i1TzuEhtPMvpJPtc7Nk3MXgguh7iw0cbo87O3ZT6mFKy+kyyrbcG3Pa2zLEC4haVoHnSZvTMCLDr8MWJq1NqXnBJmcJC2K7nSYX1uUADP3Qa8SzjVXtm0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771317095; c=relaxed/simple; bh=yxR5JGJB1T65K6tWKDS6jRiE5806q9CcHo3BP2uS3jU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:To:Cc; b=sUkX8H0GC/Qn2gWRsme1ODQYn/+aEq0uGOV6VGTu2z30Fj9AqoyFqMV8RN8UO3/q3DyDZpqxtDMGvIiR6DUnObkpbNwLmuCJV7hksHzGCRGUpazUcr7WxV3SkFhKqmXZY9mNOKqCtoMkgrLNltG8QQVVtDn0DC90H0bm8m2nkGI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=puri.sm; spf=pass smtp.mailfrom=puri.sm; dkim=pass (2048-bit key) header.d=puri.sm header.i=@puri.sm header.b=aUbiPg23; arc=none smtp.client-ip=135.181.196.210 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=puri.sm Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=puri.sm Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=puri.sm header.i=@puri.sm header.b="aUbiPg23" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=puri.sm; s=smtp2; t=1771317091; bh=yxR5JGJB1T65K6tWKDS6jRiE5806q9CcHo3BP2uS3jU=; h=From:Date:Subject:To:Cc; b=aUbiPg23UK2aE7K8mvCNbJ3hmhHBh0in922MivrvEr2CB8utC93hCaHWROpTEqTwF AktIzpUt39Y2xEVW+iZTjXw8NdUtgLbkWulYAzw8MLIJIFPYPNGYPNHKsXGwdOapPi klJXJUovusNfnoAQcqKHv3PS2EwYI5Fy/5TVnn64efJKEpg5JZ3MIcWzbEFu1Kjk9V 62hoJEmkaWE4LG5pu66OtKkyDUQwzuVbWxcc+SMrHP5RN9ISFfk3FMeOuINWdCjP/z Zx3YSbwQLmU8tqYJUeD7FTZVrVgjEjKiY+dlzt2TsbFOaMWGwkNOnAMkLWJM2Y6NtP uq0478e9HXN9g== Received: from pliszka.localdomain (79.184.40.11.ipv4.supernova.orange.pl [79.184.40.11]) by ms.puri.sm (Postfix) with ESMTPSA id 463241FCBF; Tue, 17 Feb 2026 00:31:29 -0800 (PST) From: Sebastian Krzyszkowiak Date: Tue, 17 Feb 2026 09:31:02 +0100 Subject: [PATCH v2] drm/bridge: nwl-dsi: Correct MIPI DSI horizontal sync timing 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: <20260217-nwl-sync-timing-v2-1-a306c1ef2426@puri.sm> X-B4-Tracking: v=1; b=H4sIAAAAAAAC/3WNQQ6CMBBFr2K6drRtTBVX3sOwaMsUJoFCOoASw t0t7F2+5P/3VsGYCFk8T6tIOBNTHzPo80n4xsYagarMQkttpFYG4qcFXqKHkTqKNdwfhdTWmUK 6SuTXkDDQ9zC+y8zOMoJLNvpm97QUJ752lkdM+7whHvu0HP1Z7af/qVmBAidDMOiDljf7GqZEF +5EuW3bD9a+nWnLAAAA X-Change-ID: 20260216-nwl-sync-timing-78902ab690bd To: Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Sam Ravnborg , =?utf-8?q?Guido_G=C3=BCnther?= , Robert Chiras , Fabio Estevam Cc: kernel@puri.sm, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, "Oliver F. Brown" , Sebastian Krzyszkowiak X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=4577; i=sebastian.krzyszkowiak@puri.sm; h=from:subject:message-id; bh=D9CvC01Y2oerVviwRC3is0xWP25amqh/QDhoJ8mumlk=; b=owEBbQKS/ZANAwAKAejyNc8728P/AcsmYgBplCdgpSWlnJliiuWJbDmRsLDNGpcSw9jh+cceo VHtsxsPFA+JAjMEAAEKAB0WIQQi3Z+uAGoRQ1g2YXzo8jXPO9vD/wUCaZQnYAAKCRDo8jXPO9vD /9zTEAChTJ+O2F/5tZ8/KNepf4BcWznRGCZredHsuAk5iNYo9+vr0ER7UtkL413StHBAo/vrGM7 cXDfqiNIXhmvj8vIUS1zNqWXG5gHwlRhgwGLuySNVvND6TisjBCbKxbWn9X7gmVTBDAbHG4B4Pc vONBVqP5ReyXmOsv0XjHgC3FA+kjdJY/+pHA+2o3sbvL4fwoMhn7co2sn0Bv42xFkFEfkbdmk5T pmIp5H3vEH0fFlwB//48UOPDgGn30JIFtNRLprI8cHquCKnoB0fchVepU8CZa0rUZVYxe6PXM34 ktBbFt6PMIPl44T5avQeP6kbv2TdIB2f8k3Q6JhJva/yssflkseQaev1Ip6wPErn3VpUx73Ik3y 9bsgECZeyqblJLG7ZCQ/zRVKi7VSAMUVQIrjJbdOqqbd+1xudqwOAKIK5wNcYs4gyxK8vP1Saul 84fVsohiaKbjQK6VpZXekuIsI5n3/IHcInI0eCPRl+YreQdt3HEL6/FTL2WFtpHhKXyg8KIT4CT DecMDkdE3O8x2rMRf6SzP8yDvWqw0lfKwK9nlBbtluwLFRVeSkbN5XdX4KGcKYJloQWECCPeHEP 7GhmBPuXet7MFd+jy/laWboc74KPGPZbYjPdYC0ChX8Aw5ox4uyCmOgLSLPUEfSBZmzsyaJftXc QHpfvw49eppkV1Q== X-Developer-Key: i=sebastian.krzyszkowiak@puri.sm; a=openpgp; fpr=22DD9FAE006A11435836617CE8F235CF3BDBC3FF From: Robert Chiras The NWL MIPI Host controller registers set the number of bytes for the horzontal front porch, sync pulse, and back porch, not the number of pixels. The formula converts the hfp, hsa, and hbp to bytes then subtracts the number of packet overhead bytes in the horizontal line which totals 32. The overhead is split into three proportional chunks and subtracted from fp, hsa, and hbp. Signed-off-by: Robert Chiras Signed-off-by: Oliver F. Brown Fixes: 44cfc6233447 ("drm/bridge: Add NWL MIPI DSI host controller support") [SK: Replaced division operator with div64_u64 in 64-bit divisions] Signed-off-by: Sebastian Krzyszkowiak --- Taken from the NXP linux-imx fork. This makes it possible to e.g. correctly drive the Librem 5's internal DSI panel at 60 Hz. --- Changes in v2: - Replaced division operator with div64_u64 to fix build failure on 32-bit archs reported by kernel test robot. - Link to v1: https://lore.kernel.org/r/20260216-nwl-sync-timing-v1-1-b0ff6= ecf204a@puri.sm --- drivers/gpu/drm/bridge/nwl-dsi.c | 66 ++++++++++++++++++++++++++++++++++++= ++-- 1 file changed, 63 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c b/drivers/gpu/drm/bridge/nwl-= dsi.c index 2f7429b24fc2..b99cb841983e 100644 --- a/drivers/gpu/drm/bridge/nwl-dsi.c +++ b/drivers/gpu/drm/bridge/nwl-dsi.c @@ -260,6 +260,10 @@ static int nwl_dsi_config_dpi(struct nwl_dsi *dsi) bool burst_mode; int hfront_porch, hback_porch, vfront_porch, vback_porch; int hsync_len, vsync_len; + int hfp, hbp, hsa; + unsigned long long pclk_period; + unsigned long long hs_period; + int h_blank, pkt_hdr_len, pkt_len; =20 hfront_porch =3D dsi->mode.hsync_start - dsi->mode.hdisplay; hsync_len =3D dsi->mode.hsync_end - dsi->mode.hsync_start; @@ -313,9 +317,65 @@ static int nwl_dsi_config_dpi(struct nwl_dsi *dsi) dsi->mode.hdisplay); } =20 - nwl_dsi_write(dsi, NWL_DSI_HFP, hfront_porch); - nwl_dsi_write(dsi, NWL_DSI_HBP, hback_porch); - nwl_dsi_write(dsi, NWL_DSI_HSA, hsync_len); + pclk_period =3D ALIGN(PSEC_PER_SEC, dsi->mode.clock * 1000); + do_div(pclk_period, dsi->mode.clock * 1000); + DRM_DEV_DEBUG_DRIVER(dsi->dev, "pclk_period: %llu\n", pclk_period); + + hs_period =3D ALIGN(PSEC_PER_SEC, dsi->phy_cfg.mipi_dphy.hs_clk_rate); + do_div(hs_period, dsi->phy_cfg.mipi_dphy.hs_clk_rate); + DRM_DEV_DEBUG_DRIVER(dsi->dev, "hs_period: %llu\n", hs_period); + + /* + * Calculate the bytes needed, according to the RM formula: + * Time of DPI event =3D time to transmit x number of bytes on the DSI + * interface + * dpi_event_size * dpi_pclk_period =3D dsi_bytes * 8 * hs_bit_period / + * num_lanes + * =3D=3D=3D> + * dsi_bytes =3D dpi_event_size * dpi_pclk_period * num_lanes / + * (8 * hs_bit_period) + */ + hfp =3D div64_u64(hfront_porch * pclk_period * dsi->lanes, 8 * hs_period); + hbp =3D div64_u64(hback_porch * pclk_period * dsi->lanes, 8 * hs_period); + hsa =3D div64_u64(hsync_len * pclk_period * dsi->lanes, 8 * hs_period); + + /* Make sure horizontal blankins are even numbers */ + hfp =3D roundup(hfp, 2); + hbp =3D roundup(hbp, 2); + hsa =3D roundup(hsa, 2); + + /* + * We need to subtract the packet header length: 32 + * In order to make sure we don't get negative values, + * subtract a proportional value to the total length of the + * horizontal blanking duration. + */ + h_blank =3D hfp + hbp + hsa; + + pkt_len =3D roundup(((hfp * 100 / h_blank) * 32) / 100, 2); + pkt_hdr_len =3D pkt_len; + hfp -=3D pkt_len; + + pkt_len =3D roundup(((hbp * 100 / h_blank) * 32) / 100, 2); + pkt_hdr_len +=3D pkt_len; + hbp -=3D pkt_len; + + hsa -=3D (32 - pkt_hdr_len); + + if (dsi->dsi_mode_flags & MIPI_DSI_MODE_VIDEO_NO_HFP) + hfp =3D hfront_porch; + if (dsi->dsi_mode_flags & MIPI_DSI_MODE_VIDEO_NO_HBP) + hbp =3D hback_porch; + if (dsi->dsi_mode_flags & MIPI_DSI_MODE_VIDEO_NO_HSA) + hsa =3D hsync_len; + + DRM_DEV_DEBUG_DRIVER(dsi->dev, "Actual hfp: %d\n", hfp); + DRM_DEV_DEBUG_DRIVER(dsi->dev, "Actual hbp: %d\n", hbp); + DRM_DEV_DEBUG_DRIVER(dsi->dev, "Actual hsa: %d\n", hsa); + + nwl_dsi_write(dsi, NWL_DSI_HFP, hfp); + nwl_dsi_write(dsi, NWL_DSI_HBP, hbp); + nwl_dsi_write(dsi, NWL_DSI_HSA, hsa); =20 nwl_dsi_write(dsi, NWL_DSI_ENABLE_MULT_PKTS, 0x0); nwl_dsi_write(dsi, NWL_DSI_BLLP_MODE, 0x1); --- base-commit: 0f2acd3148e0ef42bdacbd477f90e8533f96b2ac change-id: 20260216-nwl-sync-timing-78902ab690bd Best regards, --=20 Sebastian Krzyszkowiak