* [PATCH v4 1/4] drm/bridge: nwl-dsi: Cleanup endpoint mux control selection
2026-08-31 13:27 ` [PATCH v4 0/4] drm/bridge: nwl-dsi: Various fixes Esben Haabendal
@ 2026-08-31 13:27 ` Esben Haabendal
2026-08-31 13:27 ` [PATCH v4 2/4] drm/bridge: nwl-dsi: Limit LCDIF specific sync override Esben Haabendal
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Esben Haabendal @ 2026-08-31 13:27 UTC (permalink / raw)
To: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Luca Ceresoli, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Guido Günther, Fabio Estevam, Robert Chiras, Sam Ravnborg
Cc: Esben Haabendal, dri-devel, linux-kernel, stable
Using the endpoint define values makes it more clear that the argument to
mux_control_try_select() must be valid state integers, and not something
that looks like a boolean.
The endpoint value is kept, as it will be used in a following patch that
changes behavior slightly based on which endpoint is selected.
Cc: stable@vger.kernel.org
Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
Signed-off-by: Esben Haabendal <esben@geanix.com>
---
drivers/gpu/drm/bridge/nwl-dsi.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c b/drivers/gpu/drm/bridge/nwl-dsi.c
index 09992529f3d8..80e26a947ae6 100644
--- a/drivers/gpu/drm/bridge/nwl-dsi.c
+++ b/drivers/gpu/drm/bridge/nwl-dsi.c
@@ -110,6 +110,8 @@ struct nwl_dsi {
int error;
struct nwl_dsi_transfer *xfer;
+
+ unsigned int endpoint;
};
static const struct regmap_config nwl_dsi_regmap_config = {
@@ -1088,13 +1090,12 @@ static int nwl_dsi_parse_dt(struct nwl_dsi *dsi)
static int nwl_dsi_select_input(struct nwl_dsi *dsi)
{
struct device_node *remote;
- u32 use_dcss = 1;
int ret;
remote = of_graph_get_remote_node(dsi->dev->of_node, 0,
NWL_DSI_ENDPOINT_LCDIF);
if (remote) {
- use_dcss = 0;
+ dsi->endpoint = NWL_DSI_ENDPOINT_LCDIF;
} else {
remote = of_graph_get_remote_node(dsi->dev->of_node, 0,
NWL_DSI_ENDPOINT_DCSS);
@@ -1103,11 +1104,12 @@ static int nwl_dsi_select_input(struct nwl_dsi *dsi)
"No valid input endpoint found\n");
return -EINVAL;
}
+ dsi->endpoint = NWL_DSI_ENDPOINT_DCSS;
}
DRM_DEV_INFO(dsi->dev, "Using %s as input source\n",
- (use_dcss) ? "DCSS" : "LCDIF");
- ret = mux_control_try_select(dsi->mux, use_dcss);
+ (dsi->endpoint == NWL_DSI_ENDPOINT_DCSS) ? "DCSS" : "LCDIF");
+ ret = mux_control_try_select(dsi->mux, dsi->endpoint);
if (ret < 0)
DRM_DEV_ERROR(dsi->dev, "Failed to select input: %d\n", ret);
--
2.55.0
^ permalink raw reply [flat|nested] 6+ messages in thread* [PATCH v4 2/4] drm/bridge: nwl-dsi: Limit LCDIF specific sync override
2026-08-31 13:27 ` [PATCH v4 0/4] drm/bridge: nwl-dsi: Various fixes Esben Haabendal
2026-08-31 13:27 ` [PATCH v4 1/4] drm/bridge: nwl-dsi: Cleanup endpoint mux control selection Esben Haabendal
@ 2026-08-31 13:27 ` Esben Haabendal
2026-08-31 13:27 ` [PATCH v4 3/4] drm/bridge: nwl-dsi: Correct auto-insert EOTP behavior Esben Haabendal
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Esben Haabendal @ 2026-08-31 13:27 UTC (permalink / raw)
To: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Luca Ceresoli, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Guido Günther, Fabio Estevam, Robert Chiras, Sam Ravnborg
Cc: Esben Haabendal, dri-devel, linux-kernel, stable
When using DCSS with NWL, overriding the mode flags to enforce active high
sync is preventing the use of active low with downstream bridges, such as
ti-sn65dsi83, which will not see such mode flags set by the panel.
Fixes: 44cfc6233447 ("drm/bridge: Add NWL MIPI DSI host controller support")
Cc: stable@vger.kernel.org
Signed-off-by: Esben Haabendal <esben@geanix.com>
---
drivers/gpu/drm/bridge/nwl-dsi.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c b/drivers/gpu/drm/bridge/nwl-dsi.c
index 80e26a947ae6..1aab46e1a168 100644
--- a/drivers/gpu/drm/bridge/nwl-dsi.c
+++ b/drivers/gpu/drm/bridge/nwl-dsi.c
@@ -823,10 +823,13 @@ static int nwl_dsi_bridge_atomic_check(struct drm_bridge *bridge,
struct drm_connector_state *conn_state)
{
struct drm_display_mode *adjusted_mode = &crtc_state->adjusted_mode;
+ struct nwl_dsi *dsi = bridge_to_dsi(bridge);
/* At least LCDIF + NWL needs active high sync */
- adjusted_mode->flags |= (DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC);
- adjusted_mode->flags &= ~(DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC);
+ if (dsi->endpoint == NWL_DSI_ENDPOINT_LCDIF) {
+ adjusted_mode->flags |= (DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC);
+ adjusted_mode->flags &= ~(DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC);
+ }
/*
* Do a full modeset if crtc_state->active is changed to be true.
--
2.55.0
^ permalink raw reply [flat|nested] 6+ messages in thread* [PATCH v4 3/4] drm/bridge: nwl-dsi: Correct auto-insert EOTP behavior
2026-08-31 13:27 ` [PATCH v4 0/4] drm/bridge: nwl-dsi: Various fixes Esben Haabendal
2026-08-31 13:27 ` [PATCH v4 1/4] drm/bridge: nwl-dsi: Cleanup endpoint mux control selection Esben Haabendal
2026-08-31 13:27 ` [PATCH v4 2/4] drm/bridge: nwl-dsi: Limit LCDIF specific sync override Esben Haabendal
@ 2026-08-31 13:27 ` Esben Haabendal
2026-08-31 13:27 ` [PATCH v4 4/4] drm/bridge: nwl-dsi: Correct MIPI DSI horizontal sync timing Esben Haabendal
2026-09-28 8:20 ` [PATCH v4 0/4] drm/bridge: nwl-dsi: Various fixes Esben Haabendal
4 siblings, 0 replies; 6+ messages in thread
From: Esben Haabendal @ 2026-08-31 13:27 UTC (permalink / raw)
To: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Luca Ceresoli, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Guido Günther, Fabio Estevam, Robert Chiras, Sam Ravnborg
Cc: Esben Haabendal, dri-devel, linux-kernel, stable, Laurentiu Palcu
From: Robert Chiras <robert.chiras@nxp.com>
In order to respect the DSI protocol, make sure that auto-insert EOTP is
enabled according to the NO_EOT_PACKET flag instead of the
CLOCK_NON_CONTINUOUS flag.
Fixes: 44cfc6233447 ("drm/bridge: Add NWL MIPI DSI host controller support")
Cc: stable@vger.kernel.org
Signed-off-by: Esben Haabendal <esben@geanix.com>
Cc: Robert Chiras <robert.chiras@nxp.com>
Cc: Laurentiu Palcu <laurentiu.palcu@oss.nxp.com>
---
drivers/gpu/drm/bridge/nwl-dsi.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c b/drivers/gpu/drm/bridge/nwl-dsi.c
index 1aab46e1a168..f3f4334136c0 100644
--- a/drivers/gpu/drm/bridge/nwl-dsi.c
+++ b/drivers/gpu/drm/bridge/nwl-dsi.c
@@ -222,13 +222,15 @@ static int nwl_dsi_config_host(struct nwl_dsi *dsi)
DRM_DEV_DEBUG_DRIVER(dsi->dev, "DSI Lanes %d\n", dsi->lanes);
nwl_dsi_write(dsi, NWL_DSI_CFG_NUM_LANES, dsi->lanes - 1);
- if (dsi->dsi_mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS) {
+ if (dsi->dsi_mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS)
nwl_dsi_write(dsi, NWL_DSI_CFG_NONCONTINUOUS_CLK, 0x01);
- nwl_dsi_write(dsi, NWL_DSI_CFG_AUTOINSERT_EOTP, 0x01);
- } else {
+ else
nwl_dsi_write(dsi, NWL_DSI_CFG_NONCONTINUOUS_CLK, 0x00);
+
+ if (dsi->dsi_mode_flags & MIPI_DSI_MODE_NO_EOT_PACKET)
nwl_dsi_write(dsi, NWL_DSI_CFG_AUTOINSERT_EOTP, 0x00);
- }
+ else
+ nwl_dsi_write(dsi, NWL_DSI_CFG_AUTOINSERT_EOTP, 0x01);
/* values in byte clock cycles */
cycles = ui2bc(cfg->clk_pre);
--
2.55.0
^ permalink raw reply [flat|nested] 6+ messages in thread* [PATCH v4 4/4] drm/bridge: nwl-dsi: Correct MIPI DSI horizontal sync timing
2026-08-31 13:27 ` [PATCH v4 0/4] drm/bridge: nwl-dsi: Various fixes Esben Haabendal
` (2 preceding siblings ...)
2026-08-31 13:27 ` [PATCH v4 3/4] drm/bridge: nwl-dsi: Correct auto-insert EOTP behavior Esben Haabendal
@ 2026-08-31 13:27 ` Esben Haabendal
2026-09-28 8:20 ` [PATCH v4 0/4] drm/bridge: nwl-dsi: Various fixes Esben Haabendal
4 siblings, 0 replies; 6+ messages in thread
From: Esben Haabendal @ 2026-08-31 13:27 UTC (permalink / raw)
To: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Luca Ceresoli, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Guido Günther, Fabio Estevam, Robert Chiras, Sam Ravnborg
Cc: Esben Haabendal, dri-devel, linux-kernel, Oliver F. Brown
The NWL MIPI Host controller registers specifies the horizontal front
porch, sync pulse, and back porch in DSI packet payload size in bytes (ie.
not in pixel clocks).
The calculation for this is (mostly) described in section 13.6.3.5.1.2 of
the i.MX 8M Dual/8M QuadLite/8M Quad Applications Processors Reference
Manual (rev. 3.1). The formula shown there does not take packet header size
into account though.
The formula implemented here converts the hfp, hsa, and hbp to DSI packet
bytes and then subtracts the number of packet header bytes.
It is worth noting that these values only needs to match approximately,
according to the reference manual.
Based on commit in NXP vendor tree
commit f2a61699749d ("LF-7981-4: drm/bridge: nwl-dsi: Correct MIPI DSI horizontal sync timing")
Signed-off-by: Esben Haabendal <esben@geanix.com>
Cc: Robert Chiras <robert.chiras@nxp.com>
Cc: Oliver F. Brown <oliver.brown@oss.nxp.com>
---
drivers/gpu/drm/bridge/nwl-dsi.c | 60 ++++++++++++++++++++++++++++++++++++++--
1 file changed, 57 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c b/drivers/gpu/drm/bridge/nwl-dsi.c
index f3f4334136c0..eb604733eea0 100644
--- a/drivers/gpu/drm/bridge/nwl-dsi.c
+++ b/drivers/gpu/drm/bridge/nwl-dsi.c
@@ -22,6 +22,7 @@
#include <linux/reset.h>
#include <linux/sys_soc.h>
#include <linux/time64.h>
+#include <linux/math64.h>
#include <drm/drm_atomic_state_helper.h>
#include <drm/drm_bridge.h>
@@ -264,6 +265,9 @@ 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;
+ u64 hs_clk_rate, pclk_rate;
+ int h_blank, pkt_hdr_len, pkt_len;
hfront_porch = dsi->mode.hsync_start - dsi->mode.hdisplay;
hsync_len = dsi->mode.hsync_end - dsi->mode.hsync_start;
@@ -317,9 +321,59 @@ static int nwl_dsi_config_dpi(struct nwl_dsi *dsi)
dsi->mode.hdisplay);
}
- 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);
+ hs_clk_rate = dsi->phy_cfg.mipi_dphy.hs_clk_rate;
+ pclk_rate = (u64)dsi->mode.clock * 1000;
+ DRM_DEV_DEBUG_DRIVER(dsi->dev, "hs_clk_rate: %llu Hz\n", hs_clk_rate);
+
+ /*
+ * Calculate the bytes needed, according to the RM formula:
+ * Time of DPI event = time to transmit x number of bytes on the DSI interface
+ * dpi_event_size * dpi_pclk_period = dsi_bytes * 8 * hs_bit_period / num_lanes
+ * ===>
+ * dsi_bytes = dpi_event_size * dpi_pclk_period * num_lanes / (8 * hs_bit_period)
+ * ===> (substituting period = 1 / rate)
+ * dsi_bytes = dpi_event_size * num_lanes * hs_clk_rate / (8 * dpi_pclk_rate)
+ */
+ hfp = DIV64_U64_ROUND_UP((u64)hfront_porch * dsi->lanes * hs_clk_rate, 8 * pclk_rate);
+ hbp = DIV64_U64_ROUND_UP((u64)hback_porch * dsi->lanes * hs_clk_rate, 8 * pclk_rate);
+ hsa = DIV64_U64_ROUND_UP((u64)hsync_len * dsi->lanes * hs_clk_rate, 8 * pclk_rate);
+
+ /* Make sure horizontal blankins are even numbers */
+ hfp = roundup(hfp, 2);
+ hbp = roundup(hbp, 2);
+ hsa = 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 = hfp + hbp + hsa;
+
+ if (h_blank) {
+ pkt_len = min(hfp, roundup(((hfp * 100 / h_blank) * 32) / 100, 2));
+ pkt_hdr_len = pkt_len;
+ hfp -= pkt_len;
+
+ pkt_len = min(hbp, roundup(((hbp * 100 / h_blank) * 32) / 100, 2));
+ pkt_hdr_len += pkt_len;
+ hbp -= pkt_len;
+
+ pkt_len = min(hsa, 32 - pkt_hdr_len);
+ pkt_hdr_len += pkt_len;
+ hsa -= pkt_len;
+ if (pkt_hdr_len != 32)
+ dev_warn(dsi->dev,
+ "Unable to subtract packet header length fully: %d left\n",
+ 32 - pkt_hdr_len);
+ }
+
+ DRM_DEV_DEBUG_DRIVER(dsi->dev, "Register values: hfp=%d hbp=%d hsa=%d\n", hfp, hbp, 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);
nwl_dsi_write(dsi, NWL_DSI_ENABLE_MULT_PKTS, 0x0);
nwl_dsi_write(dsi, NWL_DSI_BLLP_MODE, 0x1);
--
2.55.0
^ permalink raw reply [flat|nested] 6+ messages in thread* Re: [PATCH v4 0/4] drm/bridge: nwl-dsi: Various fixes
2026-08-31 13:27 ` [PATCH v4 0/4] drm/bridge: nwl-dsi: Various fixes Esben Haabendal
` (3 preceding siblings ...)
2026-08-31 13:27 ` [PATCH v4 4/4] drm/bridge: nwl-dsi: Correct MIPI DSI horizontal sync timing Esben Haabendal
@ 2026-09-28 8:20 ` Esben Haabendal
4 siblings, 0 replies; 6+ messages in thread
From: Esben Haabendal @ 2026-09-28 8:20 UTC (permalink / raw)
To: Andrzej Hajda, Neil Armstrong, Robert Foss, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter
Cc: Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Luca Ceresoli,
Guido Günther, Fabio Estevam, Robert Chiras, Sam Ravnborg,
dri-devel, linux-kernel, Laurentiu Palcu, Oliver F. Brown
"Esben Haabendal" <esben@geanix.com> writes:
> This series brings a few patches fixing horizontal sync timing, EOTP packet
> behavior and hsync/vsync polarity selection when using DCSS endpoint, as
> well as a small fix to properly handle if/when nwl_dsi_mode_set() fails.
>
> The 3rd commit ("Correct auto-insert EOTP behavior") is taken directly from
> NXP vendor tree, so I have kept Author unchanged, although I have modified
> the commit message. Let me know if I should change Author for that.
>
> Signed-off-by: Esben Haabendal <esben@geanix.com>
Is there anything I can or should do to get this patch series merged or
at least some review feedback that I can work on?
/Esben
> ---
> Changes in v4:
> - Change calculation of hfp/hbp/hsa to use the raw clock rates directly to
> eliminate intermediate rounding errors.
> - Drop patch 4 (will be included in follow-up patch series, together with
> a patch addressing the unblanced resource teardown and PM runtime
> underflow problems in the error path).
> - Link to v3: https://patch.msgid.link/20260810-nwl-dsi-fixes-v3-0-256da9d672e1@geanix.com
>
> Changes in v3:
> - Added Fixes and Cc: stable tags.
> - Split patch 1 into two, with change of endpoint mux control in a separate
> patch.
> - Fixed mux_control_try_select() state argument.
> - Link to v2: https://patch.msgid.link/20260803-nwl-dsi-fixes-v2-0-1809a0ac453f@geanix.com
>
> Changes in v2:
> - Added safeguard against small horizontal sync timings, protecting against
> division by zero and integer underflow.
> - Added error handling of nwl_dsi_mode_set() call.
> - Link to v1: https://patch.msgid.link/20260710-nwl-dsi-fixes-v1-0-927d918a86ad@geanix.com
>
> To: Andrzej Hajda <andrzej.hajda@intel.com>
> To: Neil Armstrong <neil.armstrong@linaro.org>
> To: Robert Foss <rfoss@kernel.org>
> To: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
> To: Jonas Karlman <jonas@kwiboo.se>
> To: Jernej Skrabec <jernej.skrabec@gmail.com>
> To: Luca Ceresoli <luca.ceresoli@bootlin.com>
> To: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> To: Maxime Ripard <mripard@kernel.org>
> To: Thomas Zimmermann <tzimmermann@suse.de>
> To: David Airlie <airlied@gmail.com>
> To: Simona Vetter <simona@ffwll.ch>
> To: Guido Günther <agx@sigxcpu.org>
> To: Fabio Estevam <festevam@gmail.com>
> To: Robert Chiras <robert.chiras@nxp.com>
> To: Sam Ravnborg <sam@ravnborg.org>
> Cc: dri-devel@lists.freedesktop.org
> Cc: linux-kernel@vger.kernel.org
>
> ---
> Esben Haabendal (3):
> drm/bridge: nwl-dsi: Cleanup endpoint mux control selection
> drm/bridge: nwl-dsi: Limit LCDIF specific sync override
> drm/bridge: nwl-dsi: Correct MIPI DSI horizontal sync timing
>
> Robert Chiras (1):
> drm/bridge: nwl-dsi: Correct auto-insert EOTP behavior
>
> drivers/gpu/drm/bridge/nwl-dsi.c | 87 ++++++++++++++++++++++++++++++++++------
> 1 file changed, 74 insertions(+), 13 deletions(-)
> ---
> base-commit: cee9395acd8043be0644b25c34bfa86623f2b935
> change-id: 20260710-nwl-dsi-fixes-c148b0adb685
>
> Best regards,
> --
> Esben Haabendal <esben@geanix.com>
^ permalink raw reply [flat|nested] 6+ messages in thread