From nobody Thu Mar 5 06:33:52 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 4A7A138D for ; Mon, 16 Feb 2026 17:52:26 +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=1771264348; cv=none; b=iU/yfwfGqoJ5ZQ2qhQAWxz0CotN/vCIoD0kY5463Qy+RSLrKvDIf+RcV7YJAyYeQLqfWGLoMLX1ybrMnwCPnyiijgl3WsTxDlehk8MWiXaejHNWu2uz0kihfqVV9SUBv6NrTm4SUWJW0eHziVVmUeQpa9P0aJKiPOFBJTrrR8g8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771264348; c=relaxed/simple; bh=QDjI7MxDc9tNLfe2Zf6+1XD5ktYd7ry15WkQWujbde0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:To:Cc; b=Ym9mZMsbKOav/g/o0awvSXPD0pMzUrsEE1H7y+MS57poU7pdAxGG2QS7DqfTlTacpjCAVuAOpZ3gh8gPdmKrfXsYlQAIxr/XeMgbnFT1jZQwnduvoPH/qswcuCBIH6JszhJqReAQzu69nmL+blGnyDQB6dFMUsg/YZlEym/o0xo= 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=cDrcZ4li; 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="cDrcZ4li" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=puri.sm; s=smtp2; t=1771263935; bh=QDjI7MxDc9tNLfe2Zf6+1XD5ktYd7ry15WkQWujbde0=; h=From:Date:Subject:To:Cc; b=cDrcZ4liqruMeKDh7O1bIU+SKY+EJQtaWn9vcFszWwqGoWw48claQtfx4An++GZZJ Lvg40uwXGahM31QoTJL+hrir2Ku/rSvHddwEp4A8TTECrO/qbmaHlDIdTBi4FXuPfc 5AAH8hRuWoPFmJ7leMimVkQiQqwzDBaeZRSuogWKehFRUJ0b3PSAwOigkMrg2BomRK Sk4pQf5fE6QoD8Gz4+TOYkv45N+k4Vq1MVi1jXE54fG2beXJma/xYja/p8m0gN+v11 X9cffY/FWxA4dYsFNJJYbBH3M25qnkPDp3vyQZEZjpaR8lx/4f/N+F2g1lgz+axuGR P52uO5XT5kbfA== Received: from pliszka.localdomain (83.24.23.188.ipv4.supernova.orange.pl [83.24.23.188]) by ms.puri.sm (Postfix) with ESMTPSA id BD1F41FCC3; Mon, 16 Feb 2026 09:45:34 -0800 (PST) From: Sebastian Krzyszkowiak Date: Mon, 16 Feb 2026 18:45:30 +0100 Subject: [PATCH] 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: <20260216-nwl-sync-timing-v1-1-b0ff6ecf204a@puri.sm> X-B4-Tracking: v=1; b=H4sIAAAAAAAC/x3MPQ7CMAxA4atUnrFIMwTKVRCDk5rWUmuQXf5U9 e4Exm94bwVnE3Y4NSsYP8XlphXtroEykg6M0ldDDDGF2CbU14T+0YKLzKIDHo5diJRTF3IPtbo bX+X9P54v1ZmcMRtpGX+fSfTh+5l8YYNt+wKq0K7agAAAAA== 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=4255; i=sebastian.krzyszkowiak@puri.sm; h=from:subject:message-id; bh=R/VUS2MGXIFHdl7AHx/nvlpF7bfgL1M4MGRy5oiKxmo=; b=owEBbQKS/ZANAwAKAejyNc8728P/AcsmYgBpk1e+46JRX5i48E5ybVOU9AqkvGT4NiXfS9fIk dPdggOc7YGJAjMEAAEKAB0WIQQi3Z+uAGoRQ1g2YXzo8jXPO9vD/wUCaZNXvgAKCRDo8jXPO9vD //DaD/9ikR/bRJqHyVg0AC2B4Tz7eJeu4ugfoaX/tHvnNV+UazMHCTYVGQL6Mm1VuqMZfRkUrlF cbvhLwUwhnlZWWf0cNtKEIuXcrFLA3uMhfMbRVjfKO9vS1n883yzHVkBUBgR/jDr+iKG9tVvF+l YIEwuZWtrsH9syPlVFOPvTjeQaKA5awNU2SAfelRzskX0R/ONr52ryJkHAb4HKU0Au776mtunAD fKoFiMT6UxJQGafj5jf+RAZInvFHXW6+PT/UbxF/Bw+rdOVAM1otgSGIgwlPvgEu+IfJBaJqD/J JmDc8vTar7qZzX/6cfg6Ag04vbLcVu1xj1bgo3wq43iXv84ziqSFV4mpY5BBYle/MQ0zkAyz8HC 0idv8sCB8EwG+at2a/vtTsDUYgIvwbhdjo8upmeuZH/R1XQXBz2G28biQqvL+eXKhFoQOUokUnc sAzmQv3Ad7208KRkqZstEzGr34eoPg4l5aJ8KEeDS6LrxTFRrbhCV6O6o7HeJnIzZ92SsBBoAiI F2blbT3GNa6rSRu/EbYRcHcUHHvJDbcdAePHSyj25fhksw7ClhrFSorML/vcuX18eNeBjpXx+Qh MWVoxrS1Kkmu8V3EVLFuE3I6laBXxfcK6o0HfDB3qjHCO8lrIakNus8LT6DYQwxRa0+rmvUtXpl HumRG/DWTeMgQXA== 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") 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. --- 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..18e4bfe66b4b 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 hfront_porch * pclk_period * dsi->lanes / (8 * hs_period); + hbp =3D hback_porch * pclk_period * dsi->lanes / (8 * hs_period); + hsa =3D 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