* [PATCH v3 0/3] DSI Controller improvements for Rockchip platforms
@ 2026-08-10 3:41 Chaoyi Chen
2026-08-10 3:41 ` [PATCH v3 1/3] drm/rockchip: dsi: Add maximum per lane bit rate calculation Chaoyi Chen
` (2 more replies)
0 siblings, 3 replies; 7+ messages in thread
From: Chaoyi Chen @ 2026-08-10 3:41 UTC (permalink / raw)
To: Sandy Huang, Heiko Stübner, Andy Yan, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter
Cc: dri-devel, linux-arm-kernel, linux-rockchip, linux-kernel,
Chaoyi Chen
From: Chaoyi Chen <chaoyi.chen@rock-chips.com>
This series is dedicated to enhancing the DSI controller and PHY timing
interaction, refining the lane rate calculation, and addressing the
associated hardware limitations.
Changes in v3:
- Link to v2: https://lore.kernel.org/all/20260603033532.164-1-kernel@airkyi.com/
- Rebase to Linux v7.2
Changes in v2:
- Link to v1: https://lore.kernel.org/all/20260324085838.90-1-kernel@airkyi.com/
- Fix the unit conversion for max_mbps.
- Split the lane rate calculation into a separate patch.
- Add more comment about timing config.
Chaoyi Chen (3):
drm/rockchip: dsi: Add maximum per lane bit rate calculation
drm/rockchip: dsi: Add dphy_get_timing support for multiple PHY types
drm/rockchip: dsi: Relax the lane rate margin requirements
.../gpu/drm/rockchip/dw-mipi-dsi-rockchip.c | 66 +++++++++++++++++--
1 file changed, 60 insertions(+), 6 deletions(-)
--
2.53.0
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v3 1/3] drm/rockchip: dsi: Add maximum per lane bit rate calculation
2026-08-10 3:41 [PATCH v3 0/3] DSI Controller improvements for Rockchip platforms Chaoyi Chen
@ 2026-08-10 3:41 ` Chaoyi Chen
2026-08-10 3:55 ` sashiko-bot
2026-08-10 3:41 ` [PATCH v3 2/3] drm/rockchip: dsi: Add dphy_get_timing support for multiple PHY types Chaoyi Chen
2026-08-10 3:41 ` [PATCH v3 3/3] drm/rockchip: dsi: Relax the lane rate margin requirements Chaoyi Chen
2 siblings, 1 reply; 7+ messages in thread
From: Chaoyi Chen @ 2026-08-10 3:41 UTC (permalink / raw)
To: Sandy Huang, Heiko Stübner, Andy Yan, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter
Cc: dri-devel, linux-arm-kernel, linux-rockchip, linux-kernel,
Chaoyi Chen
From: Chaoyi Chen <chaoyi.chen@rock-chips.com>
Different chips have varying support for the maximum bit rate per lane.
Add calculation for the maximum per lane bit rate for various chip
platforms.
Signed-off-by: Chaoyi Chen <chaoyi.chen@rock-chips.com>
---
Changes in v3:
- Rebase to Linux v7.2
Changes in v2:
- Fix the unit conversion for max_mbps.
- Split the lane rate calculation into a separate patch.
---
drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
index 3547d91b25d3..1060abec9f29 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
@@ -268,6 +268,7 @@ struct rockchip_dw_dsi_chip_data {
unsigned int flags;
unsigned int max_data_lanes;
+ unsigned long max_bit_rate_per_lane;
};
struct dw_mipi_dsi_rockchip {
@@ -565,7 +566,7 @@ dw_mipi_dsi_get_lane_mbps(void *priv_data, const struct drm_display_mode *mode,
int bpp;
unsigned long mpclk, tmp;
unsigned int target_mbps = 1000;
- unsigned int max_mbps = dppa_map[ARRAY_SIZE(dppa_map) - 1].max_mbps;
+ unsigned int max_mbps;
unsigned long best_freq = 0;
unsigned long fvco_min, fvco_max, fin, fout;
unsigned int min_prediv, max_prediv;
@@ -573,6 +574,7 @@ dw_mipi_dsi_get_lane_mbps(void *priv_data, const struct drm_display_mode *mode,
unsigned long _fbdiv, best_fbdiv;
unsigned long min_delta = ULONG_MAX;
+ max_mbps = dsi->cdata->max_bit_rate_per_lane / USEC_PER_SEC;
dsi->format = format;
bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
if (bpp < 0) {
@@ -1503,6 +1505,7 @@ static const struct rockchip_dw_dsi_chip_data px30_chip_data[] = {
PX30_DSI_FORCETXSTOPMODE), 0),
.max_data_lanes = 4,
+ .max_bit_rate_per_lane = 1000000000UL,
},
{ /* sentinel */ }
};
@@ -1515,6 +1518,7 @@ static const struct rockchip_dw_dsi_chip_data rk3128_chip_data[] = {
RK3128_DSI_FORCERXMODE |
RK3128_DSI_FORCETXSTOPMODE), 0),
.max_data_lanes = 4,
+ .max_bit_rate_per_lane = 1000000000UL,
},
{ /* sentinel */ }
};
@@ -1527,6 +1531,7 @@ static const struct rockchip_dw_dsi_chip_data rk3288_chip_data[] = {
.lcdsel_lit = FIELD_PREP_WM16_CONST(RK3288_DSI0_LCDC_SEL, 1),
.max_data_lanes = 4,
+ .max_bit_rate_per_lane = 1500000000UL,
},
{
.reg = 0xff964000,
@@ -1535,6 +1540,7 @@ static const struct rockchip_dw_dsi_chip_data rk3288_chip_data[] = {
.lcdsel_lit = FIELD_PREP_WM16_CONST(RK3288_DSI1_LCDC_SEL, 1),
.max_data_lanes = 4,
+ .max_bit_rate_per_lane = 1500000000UL,
},
{ /* sentinel */ }
};
@@ -1547,6 +1553,7 @@ static const struct rockchip_dw_dsi_chip_data rk3368_chip_data[] = {
RK3368_DSI_FORCETXSTOPMODE |
RK3368_DSI_FORCERXMODE), 0),
.max_data_lanes = 4,
+ .max_bit_rate_per_lane = 1500000000UL,
},
{ /* sentinel */ }
};
@@ -1634,6 +1641,7 @@ static const struct rockchip_dw_dsi_chip_data rk3399_chip_data[] = {
.flags = DW_MIPI_NEEDS_PHY_CFG_CLK | DW_MIPI_NEEDS_GRF_CLK,
.max_data_lanes = 4,
+ .max_bit_rate_per_lane = 1500000000UL,
},
{
.reg = 0xff968000,
@@ -1658,6 +1666,7 @@ static const struct rockchip_dw_dsi_chip_data rk3399_chip_data[] = {
.flags = DW_MIPI_NEEDS_PHY_CFG_CLK | DW_MIPI_NEEDS_GRF_CLK,
.max_data_lanes = 4,
+ .max_bit_rate_per_lane = 1500000000UL,
.dphy_rx_init = rk3399_dphy_tx1rx1_init,
.dphy_rx_power_on = rk3399_dphy_tx1rx1_power_on,
@@ -1674,6 +1683,7 @@ static const struct rockchip_dw_dsi_chip_data rk3506_chip_data[] = {
FIELD_PREP_WM16_CONST(RK3506_DSI_FORCERXMODE, 0) |
FIELD_PREP_WM16_CONST(RK3506_DSI_FORCETXSTOPMODE, 0)),
.max_data_lanes = 2,
+ .max_bit_rate_per_lane = 1500000000UL,
},
{ /* sentinel */ }
};
@@ -1687,6 +1697,7 @@ static const struct rockchip_dw_dsi_chip_data rk3568_chip_data[] = {
FIELD_PREP_WM16_CONST(RK3568_DSI0_TURNDISABLE, 0) |
FIELD_PREP_WM16_CONST(RK3568_DSI0_FORCERXMODE, 0)),
.max_data_lanes = 4,
+ .max_bit_rate_per_lane = 1200000000UL,
},
{
.reg = 0xfe070000,
@@ -1696,6 +1707,7 @@ static const struct rockchip_dw_dsi_chip_data rk3568_chip_data[] = {
FIELD_PREP_WM16_CONST(RK3568_DSI1_TURNDISABLE, 0) |
FIELD_PREP_WM16_CONST(RK3568_DSI1_FORCERXMODE, 0)),
.max_data_lanes = 4,
+ .max_bit_rate_per_lane = 1200000000UL,
},
{ /* sentinel */ }
};
@@ -1708,6 +1720,7 @@ static const struct rockchip_dw_dsi_chip_data rv1126_chip_data[] = {
FIELD_PREP_WM16_CONST(RV1126_DSI_FORCERXMODE, 0) |
FIELD_PREP_WM16_CONST(RV1126_DSI_FORCETXSTOPMODE, 0)),
.max_data_lanes = 4,
+ .max_bit_rate_per_lane = 1000000000UL,
},
{ /* sentinel */ }
};
--
2.53.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v3 2/3] drm/rockchip: dsi: Add dphy_get_timing support for multiple PHY types
2026-08-10 3:41 [PATCH v3 0/3] DSI Controller improvements for Rockchip platforms Chaoyi Chen
2026-08-10 3:41 ` [PATCH v3 1/3] drm/rockchip: dsi: Add maximum per lane bit rate calculation Chaoyi Chen
@ 2026-08-10 3:41 ` Chaoyi Chen
2026-08-10 3:59 ` sashiko-bot
2026-08-10 3:41 ` [PATCH v3 3/3] drm/rockchip: dsi: Relax the lane rate margin requirements Chaoyi Chen
2 siblings, 1 reply; 7+ messages in thread
From: Chaoyi Chen @ 2026-08-10 3:41 UTC (permalink / raw)
To: Sandy Huang, Heiko Stübner, Andy Yan, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter
Cc: dri-devel, linux-arm-kernel, linux-rockchip, linux-kernel,
Chaoyi Chen
From: Chaoyi Chen <chaoyi.chen@rock-chips.com>
Currently, there are generally two types of DPHY for Rockchip. One is
the DPHY used by RK3288/RK3399, whose timing is described by Table A-3
High-Speed Transition Times in the databook. The other is the DPHY used
by PX30 and its successors. If its timing is still described using
RK3288/RK3399, it may not perform correctly on some DSI panel.
Add dphy_get_timing for different D-PHY types to adapt to timing
differences. The configuration details are as follows:
- RK3288/RK3399: Select the corresponding entry from the timing table based
on the data rate.
- PX30 and later platforms: Use a fixed timing configuration.
Signed-off-by: Chaoyi Chen <chaoyi.chen@rock-chips.com>
---
Changes in v3:
- Rebase to Linux v7.2
Changes in v2:
- Add more comment about timing config.
---
.../gpu/drm/rockchip/dw-mipi-dsi-rockchip.c | 45 ++++++++++++++++++-
1 file changed, 43 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
index 1060abec9f29..e64dfc327891 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
@@ -247,6 +247,7 @@ enum {
BIASEXTR_127_7,
};
+struct dw_mipi_dsi_rockchip;
struct rockchip_dw_dsi_chip_data {
u32 reg;
@@ -262,6 +263,9 @@ struct rockchip_dw_dsi_chip_data {
u32 lanecfg2_grf_reg;
u32 lanecfg2;
+ int (*dphy_get_timing)(struct dw_mipi_dsi_rockchip *dsi, unsigned int lane_mbps,
+ struct dw_mipi_dsi_dphy_timing *timing);
+
int (*dphy_rx_init)(struct phy *phy);
int (*dphy_rx_power_on)(struct phy *phy);
int (*dphy_rx_power_off)(struct phy *phy);
@@ -721,8 +725,9 @@ static struct hstt hstt_table[] = {
};
static int
-dw_mipi_dsi_phy_get_timing(void *priv_data, unsigned int lane_mbps,
- struct dw_mipi_dsi_dphy_timing *timing)
+dw_mipi_dsi_phy_rk3288_get_timing(struct dw_mipi_dsi_rockchip *dsi,
+ unsigned int lane_mbps,
+ struct dw_mipi_dsi_dphy_timing *timing)
{
int i;
@@ -738,6 +743,32 @@ dw_mipi_dsi_phy_get_timing(void *priv_data, unsigned int lane_mbps,
return 0;
}
+static const struct dw_mipi_dsi_dphy_timing dphy_timing_px30 = {
+ .clk_lp2hs = 0x40,
+ .clk_hs2lp = 0x40,
+ .data_lp2hs = 0x10,
+ .data_hs2lp = 0x14,
+};
+
+static int
+dw_mipi_dsi_phy_px30_get_timing(struct dw_mipi_dsi_rockchip *dsi,
+ unsigned int lane_mbps,
+ struct dw_mipi_dsi_dphy_timing *timing)
+{
+ *timing = dphy_timing_px30;
+
+ return 0;
+}
+
+static int
+dw_mipi_dsi_phy_get_timing(void *priv_data, unsigned int lane_mbps,
+ struct dw_mipi_dsi_dphy_timing *timing)
+{
+ struct dw_mipi_dsi_rockchip *dsi = priv_data;
+
+ return dsi->cdata->dphy_get_timing(dsi, lane_mbps, timing);
+}
+
static const struct dw_mipi_dsi_phy_ops dw_mipi_dsi_rockchip_phy_ops = {
.init = dw_mipi_dsi_phy_init,
.power_on = dw_mipi_dsi_phy_power_on,
@@ -1506,6 +1537,7 @@ static const struct rockchip_dw_dsi_chip_data px30_chip_data[] = {
.max_data_lanes = 4,
.max_bit_rate_per_lane = 1000000000UL,
+ .dphy_get_timing = dw_mipi_dsi_phy_px30_get_timing,
},
{ /* sentinel */ }
};
@@ -1519,6 +1551,7 @@ static const struct rockchip_dw_dsi_chip_data rk3128_chip_data[] = {
RK3128_DSI_FORCETXSTOPMODE), 0),
.max_data_lanes = 4,
.max_bit_rate_per_lane = 1000000000UL,
+ .dphy_get_timing = dw_mipi_dsi_phy_px30_get_timing,
},
{ /* sentinel */ }
};
@@ -1532,6 +1565,7 @@ static const struct rockchip_dw_dsi_chip_data rk3288_chip_data[] = {
.max_data_lanes = 4,
.max_bit_rate_per_lane = 1500000000UL,
+ .dphy_get_timing = dw_mipi_dsi_phy_rk3288_get_timing,
},
{
.reg = 0xff964000,
@@ -1541,6 +1575,7 @@ static const struct rockchip_dw_dsi_chip_data rk3288_chip_data[] = {
.max_data_lanes = 4,
.max_bit_rate_per_lane = 1500000000UL,
+ .dphy_get_timing = dw_mipi_dsi_phy_rk3288_get_timing,
},
{ /* sentinel */ }
};
@@ -1554,6 +1589,7 @@ static const struct rockchip_dw_dsi_chip_data rk3368_chip_data[] = {
RK3368_DSI_FORCERXMODE), 0),
.max_data_lanes = 4,
.max_bit_rate_per_lane = 1500000000UL,
+ .dphy_get_timing = dw_mipi_dsi_phy_px30_get_timing,
},
{ /* sentinel */ }
};
@@ -1642,6 +1678,7 @@ static const struct rockchip_dw_dsi_chip_data rk3399_chip_data[] = {
.flags = DW_MIPI_NEEDS_PHY_CFG_CLK | DW_MIPI_NEEDS_GRF_CLK,
.max_data_lanes = 4,
.max_bit_rate_per_lane = 1500000000UL,
+ .dphy_get_timing = dw_mipi_dsi_phy_rk3288_get_timing,
},
{
.reg = 0xff968000,
@@ -1671,6 +1708,7 @@ static const struct rockchip_dw_dsi_chip_data rk3399_chip_data[] = {
.dphy_rx_init = rk3399_dphy_tx1rx1_init,
.dphy_rx_power_on = rk3399_dphy_tx1rx1_power_on,
.dphy_rx_power_off = rk3399_dphy_tx1rx1_power_off,
+ .dphy_get_timing = dw_mipi_dsi_phy_rk3288_get_timing,
},
{ /* sentinel */ }
};
@@ -1698,6 +1736,7 @@ static const struct rockchip_dw_dsi_chip_data rk3568_chip_data[] = {
FIELD_PREP_WM16_CONST(RK3568_DSI0_FORCERXMODE, 0)),
.max_data_lanes = 4,
.max_bit_rate_per_lane = 1200000000UL,
+ .dphy_get_timing = dw_mipi_dsi_phy_px30_get_timing,
},
{
.reg = 0xfe070000,
@@ -1708,6 +1747,7 @@ static const struct rockchip_dw_dsi_chip_data rk3568_chip_data[] = {
FIELD_PREP_WM16_CONST(RK3568_DSI1_FORCERXMODE, 0)),
.max_data_lanes = 4,
.max_bit_rate_per_lane = 1200000000UL,
+ .dphy_get_timing = dw_mipi_dsi_phy_px30_get_timing,
},
{ /* sentinel */ }
};
@@ -1721,6 +1761,7 @@ static const struct rockchip_dw_dsi_chip_data rv1126_chip_data[] = {
FIELD_PREP_WM16_CONST(RV1126_DSI_FORCETXSTOPMODE, 0)),
.max_data_lanes = 4,
.max_bit_rate_per_lane = 1000000000UL,
+ .dphy_get_timing = dw_mipi_dsi_phy_px30_get_timing,
},
{ /* sentinel */ }
};
--
2.53.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v3 3/3] drm/rockchip: dsi: Relax the lane rate margin requirements
2026-08-10 3:41 [PATCH v3 0/3] DSI Controller improvements for Rockchip platforms Chaoyi Chen
2026-08-10 3:41 ` [PATCH v3 1/3] drm/rockchip: dsi: Add maximum per lane bit rate calculation Chaoyi Chen
2026-08-10 3:41 ` [PATCH v3 2/3] drm/rockchip: dsi: Add dphy_get_timing support for multiple PHY types Chaoyi Chen
@ 2026-08-10 3:41 ` Chaoyi Chen
2026-08-10 3:53 ` sashiko-bot
2 siblings, 1 reply; 7+ messages in thread
From: Chaoyi Chen @ 2026-08-10 3:41 UTC (permalink / raw)
To: Sandy Huang, Heiko Stübner, Andy Yan, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter
Cc: dri-devel, linux-arm-kernel, linux-rockchip, linux-kernel,
Chaoyi Chen
From: Chaoyi Chen <chaoyi.chen@rock-chips.com>
The lane rate is calculated as follows:
Lane_Rate = Pixel_Clk * BPP / lanes * Overhead
The overhead factor is set to 1/0.8, equivalent to a 25% overhead.
Now let's consider the case of RGB888 (BPP24) with a pclk of 148.5MHz.
The lane rate equals 148.5M * 24 / 4 * 1.25 = 1113.75 Mbps.
However, this is beyond the capability of certain platforms limited to a
1Gbps lane rate. On the other hand, we have observed that some DSI panel
actually perform worse with higher overhead.
So we are considering relaxing the bandwidth margin requirements.
According to the downstream test results, adopting 1/0.9 seems to
be a sound approach, corresponding to an overhead of about 11%.
Signed-off-by: Chaoyi Chen <chaoyi.chen@rock-chips.com>
---
Changes in v3:
- Rebase to Linux v7.2
---
drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
index e64dfc327891..8af9d6934d27 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
@@ -590,8 +590,8 @@ dw_mipi_dsi_get_lane_mbps(void *priv_data, const struct drm_display_mode *mode,
mpclk = DIV_ROUND_UP(mode->clock, MSEC_PER_SEC);
if (mpclk) {
- /* take 1 / 0.8, since mbps must big than bandwidth of RGB */
- tmp = mpclk * (bpp / lanes) * 10 / 8;
+ /* take 1 / 0.9, since mbps must big than bandwidth of RGB */
+ tmp = mpclk * (bpp / lanes) * 10 / 9;
if (tmp < max_mbps)
target_mbps = tmp;
else
@@ -601,7 +601,7 @@ dw_mipi_dsi_get_lane_mbps(void *priv_data, const struct drm_display_mode *mode,
/* for external phy only a the mipi_dphy_config is necessary */
if (dsi->phy) {
- phy_mipi_dphy_get_default_config(mode->clock * 1000 * 10 / 8,
+ phy_mipi_dphy_get_default_config(mode->clock * 1000 * 10 / 9,
bpp, lanes,
&dsi->phy_opts.mipi_dphy);
dsi->lane_mbps = target_mbps;
--
2.53.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH v3 3/3] drm/rockchip: dsi: Relax the lane rate margin requirements
2026-08-10 3:41 ` [PATCH v3 3/3] drm/rockchip: dsi: Relax the lane rate margin requirements Chaoyi Chen
@ 2026-08-10 3:53 ` sashiko-bot
0 siblings, 0 replies; 7+ messages in thread
From: sashiko-bot @ 2026-08-10 3:53 UTC (permalink / raw)
To: Chaoyi Chen; +Cc: dri-devel
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
New issues:
- [High] Integer division truncation in bandwidth calculation causes DSI link underflow when combined with the newly reduced margin.
Pre-existing issues:
- [High] 32-bit signed integer overflow in PHY pixel clock calculation for displays with high pixel clocks (> 214.7 MHz).
- [High] Unsigned long overflow on 32-bit platforms within the core PHY configuration calculation.
--
--- Patch [3]: [PATCH v3 3/3] drm/rockchip: dsi: Relax the lane rate margin requirements ---
commit 93b5a610ac5007bdda923b4d779bc2ab6fd40792
Author: Chaoyi Chen <chaoyi.chen@rock-chips.com>
drm/rockchip: dsi: Relax the lane rate margin requirements
The commit reduces the DSI lane rate margin from 25% to about 11% to
accommodate platforms limited to 1Gbps lane rates. It updates the lane rate
calculation in dw_mipi_dsi_get_lane_mbps() and adjusts the PHY configuration
parameter accordingly.
> diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
> index 557708bc4faa4..bb2b35571af73 100644
> --- a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
> +++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
> @@ -589,8 +589,8 @@ dw_mipi_dsi_get_lane_mbps(void *priv_data, const struct drm_display_mode *mode,
>
> mpclk = DIV_ROUND_UP(mode->clock, MSEC_PER_SEC);
> if (mpclk) {
> - /* take 1 / 0.8, since mbps must big than bandwidth of RGB */
> - tmp = mpclk * (bpp / lanes) * 10 / 8;
> + /* take 1 / 0.9, since mbps must big than bandwidth of RGB */
> + tmp = mpclk * (bpp / lanes) * 10 / 9;
[Severity: High]
Does the integer division (bpp / lanes) cause a truncation that leads to DSI
link underflow with this new reduced margin?
For example, with a panel using RGB666 (18 bpp) over 4 lanes, (18 / 4)
evaluates to 4 instead of 4.5.
With the old margin (10 / 8), the multiplier was 4 * 1.25 = 5.0, which safely
exceeded the 4.5 raw multiplier requirement.
With the new margin (10 / 9), the allocated bandwidth calculation becomes
4 * 10 / 9 = 4.44. Since 4.44 is strictly less than 4.5, the configured lane
rate provides less bandwidth than the raw pixel payload requires, which could
lead to FIFO underflows.
[ ... ]
> @@ -600,7 +600,7 @@ dw_mipi_dsi_get_lane_mbps(void *priv_data, const struct drm_display_mode *mode,
>
> /* for external phy only a the mipi_dphy_config is necessary */
> if (dsi->phy) {
> - phy_mipi_dphy_get_default_config(mode->clock * 1000 * 10 / 8,
> + phy_mipi_dphy_get_default_config(mode->clock * 1000 * 10 / 9,
[Severity: High]
This isn't a bug introduced by this patch, but does mode->clock * 1000 * 10
silently overflow 32-bit signed integers for high pixel clocks?
Because mode->clock is a signed 32-bit integer (representing kHz) and the
literals are also 32-bit signed ints, the intermediate product overflows
INT_MAX (2,147,483,647) for any pixel clock exceeding ~214.7 MHz. The result
would wrap to a negative value.
[Severity: High]
This is a pre-existing issue, but does passing this margined pixel clock
to phy_mipi_dphy_get_default_config() overflow on 32-bit platforms?
When the inflated pixel clock reaches phy_mipi_dphy_calc_config() in
drivers/phy/phy-core-mipi-dphy.c, it computes:
hs_clk_rate = pixel_clock * bpp;
On 32-bit architectures, pixel_clock is a 32-bit unsigned long. If
mode->clock is roughly 165 MHz, pixel_clock becomes
165,000 * 1000 * 10 / 9 = 183,333,333. Multiplying by bpp (e.g., 24) gives
4,400,000,000, which silently overflows the 32-bit ULONG_MAX before the
result is assigned to the 64-bit hs_clk_rate.
> bpp, lanes,
> &dsi->phy_opts.mipi_dphy);
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260810034139.148-1-kernel@airkyi.com?part=3
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v3 1/3] drm/rockchip: dsi: Add maximum per lane bit rate calculation
2026-08-10 3:41 ` [PATCH v3 1/3] drm/rockchip: dsi: Add maximum per lane bit rate calculation Chaoyi Chen
@ 2026-08-10 3:55 ` sashiko-bot
0 siblings, 0 replies; 7+ messages in thread
From: sashiko-bot @ 2026-08-10 3:55 UTC (permalink / raw)
To: Chaoyi Chen; +Cc: dri-devel
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [High] Potential divide-by-zero kernel panic if the PLL reference clock returns a rate of 0 Hz.
--
--- Patch [1]: [PATCH v3 1/3] drm/rockchip: dsi: Add maximum per lane bit rate calculation ---
commit d9f1ff11296ed644cdf72ac949c279cf1d55f770
Author: Chaoyi Chen <chaoyi.chen@rock-chips.com>
drm/rockchip: dsi: Add maximum per lane bit rate calculation
This commit adds calculations for the maximum per-lane bit rate across
various rockchip platforms. It introduces a new max_bit_rate_per_lane field
to the chip data and uses it to determine the max_mbps dynamically.
> diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
> index 268d4993a04fd..fd91343d0f6d5 100644
> --- a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
> +++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
[ ... ]
> @@ -572,6 +573,7 @@ dw_mipi_dsi_get_lane_mbps(void *priv_data, const struct drm_display_mode *mode,
> unsigned long _fbdiv, best_fbdiv;
> unsigned long min_delta = ULONG_MAX;
>
> + max_mbps = dsi->cdata->max_bit_rate_per_lane / USEC_PER_SEC;
> dsi->format = format;
> bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
> if (bpp < 0) {
[Severity: High]
This is a pre-existing issue, but while reviewing this function, I noticed
a potential divide-by-zero vulnerability further down in
dw_mipi_dsi_get_lane_mbps().
If clk_get_rate(dsi->pllref_clk) returns 0, which could occur if the clock
provider is uninitialized, disabled, or misconfigured in the device tree,
fin becomes 0. The calculations for min_prediv and max_prediv would then
both evaluate to 0.
This would cause the subsequent loop to execute once with _prediv = 0:
for (_prediv = min_prediv; _prediv <= max_prediv; _prediv++) {
u64 tmp;
u32 delta;
/* Fvco = Fref * M / N */
tmp = (u64)fout * _prediv;
do_div(tmp, fin);
Could this do_div(tmp, fin) trigger a kernel panic due to division by zero?
Would it make sense to add a check validating that fin is greater than zero
before proceeding with the calculation?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260810034139.148-1-kernel@airkyi.com?part=1
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v3 2/3] drm/rockchip: dsi: Add dphy_get_timing support for multiple PHY types
2026-08-10 3:41 ` [PATCH v3 2/3] drm/rockchip: dsi: Add dphy_get_timing support for multiple PHY types Chaoyi Chen
@ 2026-08-10 3:59 ` sashiko-bot
0 siblings, 0 replies; 7+ messages in thread
From: sashiko-bot @ 2026-08-10 3:59 UTC (permalink / raw)
To: Chaoyi Chen; +Cc: dri-devel
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] Missing `dphy_get_timing` callback initialization in `rk3506_chip_data` causes a NULL pointer dereference on the RK3506 platform.
--
--- Patch [2]: [PATCH v3 2/3] drm/rockchip: dsi: Add dphy_get_timing support for multiple PHY types ---
commit 266dcada14f6495a40e461eefa6793e6e1dcb8ca
Author: Chaoyi Chen <chaoyi.chen@rock-chips.com>
drm/rockchip: dsi: Add dphy_get_timing support for multiple PHY types
This commit introduces platform-specific D-PHY timing callbacks to handle
timing differences between older and newer Rockchip platforms.
> diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
> index fd91343d0f6d5..557708bc4faa4 100644
> --- a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
> +++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
[ ... ]
> @@ -737,6 +742,32 @@ dw_mipi_dsi_phy_get_timing(void *priv_data, unsigned int lane_mbps,
> return 0;
> }
>
> +static const struct dw_mipi_dsi_dphy_timing dphy_timing_px30 = {
> + .clk_lp2hs = 0x40,
> + .clk_hs2lp = 0x40,
> + .data_lp2hs = 0x10,
> + .data_hs2lp = 0x14,
> +};
> +
> +static int
> +dw_mipi_dsi_phy_px30_get_timing(struct dw_mipi_dsi_rockchip *dsi,
> + unsigned int lane_mbps,
> + struct dw_mipi_dsi_dphy_timing *timing)
> +{
> + *timing = dphy_timing_px30;
> +
> + return 0;
> +}
> +
> +static int
> +dw_mipi_dsi_phy_get_timing(void *priv_data, unsigned int lane_mbps,
> + struct dw_mipi_dsi_dphy_timing *timing)
> +{
> + struct dw_mipi_dsi_rockchip *dsi = priv_data;
> +
> + return dsi->cdata->dphy_get_timing(dsi, lane_mbps, timing);
[Severity: High]
Will this cause a NULL pointer dereference on the RK3506 platform?
The patch updates multiple platform definitions to set the .dphy_get_timing
callback, but it appears to have missed rk3506_chip_data, leaving its
callback as NULL.
When dw_mipi_dsi_phy_get_timing() is called during modeset on RK3506, it
unconditionally dereferences dsi->cdata->dphy_get_timing, which will lead
to an immediate crash.
Should a NULL check be added here, or should rk3506_chip_data be updated to
include a timing callback?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260810034139.148-1-kernel@airkyi.com?part=2
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-08-10 3:59 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-10 3:41 [PATCH v3 0/3] DSI Controller improvements for Rockchip platforms Chaoyi Chen
2026-08-10 3:41 ` [PATCH v3 1/3] drm/rockchip: dsi: Add maximum per lane bit rate calculation Chaoyi Chen
2026-08-10 3:55 ` sashiko-bot
2026-08-10 3:41 ` [PATCH v3 2/3] drm/rockchip: dsi: Add dphy_get_timing support for multiple PHY types Chaoyi Chen
2026-08-10 3:59 ` sashiko-bot
2026-08-10 3:41 ` [PATCH v3 3/3] drm/rockchip: dsi: Relax the lane rate margin requirements Chaoyi Chen
2026-08-10 3:53 ` sashiko-bot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).