* [PATCH v4 0/3] DSI Controller improvements for Rockchip platforms
@ 2026-08-12 7:29 ` Chaoyi Chen
0 siblings, 0 replies; 10+ messages in thread
From: Chaoyi Chen @ 2026-08-12 7:29 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 v4:
- Link to v3: https://lore.kernel.org/all/20260810034139.148-1-kernel@airkyi.com/
- Add missing RK3506 timing and the fallback path for get_timing
(sashiko).
- Fix potential overflow and underflow issues in bandwidth
calculation(sashiko).
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 | 70 +++++++++++++++++--
1 file changed, 64 insertions(+), 6 deletions(-)
--
2.53.0
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v4 0/3] DSI Controller improvements for Rockchip platforms
@ 2026-08-12 7:29 ` Chaoyi Chen
0 siblings, 0 replies; 10+ messages in thread
From: Chaoyi Chen @ 2026-08-12 7:29 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 v4:
- Link to v3: https://lore.kernel.org/all/20260810034139.148-1-kernel@airkyi.com/
- Add missing RK3506 timing and the fallback path for get_timing
(sashiko).
- Fix potential overflow and underflow issues in bandwidth
calculation(sashiko).
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 | 70 +++++++++++++++++--
1 file changed, 64 insertions(+), 6 deletions(-)
--
2.53.0
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v4 1/3] drm/rockchip: dsi: Add maximum per lane bit rate calculation
2026-08-12 7:29 ` Chaoyi Chen
@ 2026-08-12 7:30 ` Chaoyi Chen
-1 siblings, 0 replies; 10+ messages in thread
From: Chaoyi Chen @ 2026-08-12 7:30 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>
---
(no changes since v4)
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
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v4 1/3] drm/rockchip: dsi: Add maximum per lane bit rate calculation
@ 2026-08-12 7:30 ` Chaoyi Chen
0 siblings, 0 replies; 10+ messages in thread
From: Chaoyi Chen @ 2026-08-12 7:30 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>
---
(no changes since v4)
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] 10+ messages in thread
* [PATCH v4 2/3] drm/rockchip: dsi: Add dphy_get_timing support for multiple PHY types
2026-08-12 7:29 ` Chaoyi Chen
@ 2026-08-12 7:30 ` Chaoyi Chen
-1 siblings, 0 replies; 10+ messages in thread
From: Chaoyi Chen @ 2026-08-12 7:30 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 v4:
- Add missing RK3506 timing and the fallback path for get_timing
(sashiko).
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 | 49 ++++++++++++++++++-
1 file changed, 47 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..d183c82ef9bc 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,35 @@ 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;
+
+ if (dsi->cdata->dphy_get_timing)
+ return dsi->cdata->dphy_get_timing(dsi, lane_mbps, timing);
+
+ return dw_mipi_dsi_phy_px30_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 +1540,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 +1554,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 +1568,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 +1578,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 +1592,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 +1681,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 +1711,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 */ }
};
@@ -1684,6 +1725,7 @@ static const struct rockchip_dw_dsi_chip_data rk3506_chip_data[] = {
FIELD_PREP_WM16_CONST(RK3506_DSI_FORCETXSTOPMODE, 0)),
.max_data_lanes = 2,
.max_bit_rate_per_lane = 1500000000UL,
+ .dphy_get_timing = dw_mipi_dsi_phy_px30_get_timing,
},
{ /* sentinel */ }
};
@@ -1698,6 +1740,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 +1751,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 +1765,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] 10+ messages in thread
* [PATCH v4 2/3] drm/rockchip: dsi: Add dphy_get_timing support for multiple PHY types
@ 2026-08-12 7:30 ` Chaoyi Chen
0 siblings, 0 replies; 10+ messages in thread
From: Chaoyi Chen @ 2026-08-12 7:30 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 v4:
- Add missing RK3506 timing and the fallback path for get_timing
(sashiko).
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 | 49 ++++++++++++++++++-
1 file changed, 47 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..d183c82ef9bc 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,35 @@ 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;
+
+ if (dsi->cdata->dphy_get_timing)
+ return dsi->cdata->dphy_get_timing(dsi, lane_mbps, timing);
+
+ return dw_mipi_dsi_phy_px30_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 +1540,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 +1554,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 +1568,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 +1578,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 +1592,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 +1681,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 +1711,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 */ }
};
@@ -1684,6 +1725,7 @@ static const struct rockchip_dw_dsi_chip_data rk3506_chip_data[] = {
FIELD_PREP_WM16_CONST(RK3506_DSI_FORCETXSTOPMODE, 0)),
.max_data_lanes = 2,
.max_bit_rate_per_lane = 1500000000UL,
+ .dphy_get_timing = dw_mipi_dsi_phy_px30_get_timing,
},
{ /* sentinel */ }
};
@@ -1698,6 +1740,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 +1751,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 +1765,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
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v4 3/3] drm/rockchip: dsi: Relax the lane rate margin requirements
2026-08-12 7:29 ` Chaoyi Chen
@ 2026-08-12 7:30 ` Chaoyi Chen
-1 siblings, 0 replies; 10+ messages in thread
From: Chaoyi Chen @ 2026-08-12 7:30 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 v4:
- Fix potential overflow and underflow issues in bandwidth
calculation(sashiko).
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 d183c82ef9bc..77f9c5883987 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 = DIV_ROUND_UP(mpclk * bpp * 10, lanes * 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((u32)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] 10+ messages in thread
* [PATCH v4 3/3] drm/rockchip: dsi: Relax the lane rate margin requirements
@ 2026-08-12 7:30 ` Chaoyi Chen
0 siblings, 0 replies; 10+ messages in thread
From: Chaoyi Chen @ 2026-08-12 7:30 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 v4:
- Fix potential overflow and underflow issues in bandwidth
calculation(sashiko).
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 d183c82ef9bc..77f9c5883987 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 = DIV_ROUND_UP(mpclk * bpp * 10, lanes * 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((u32)mode->clock * 1000 * 10 / 9,
bpp, lanes,
&dsi->phy_opts.mipi_dphy);
dsi->lane_mbps = target_mbps;
--
2.53.0
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH v4 1/3] drm/rockchip: dsi: Add maximum per lane bit rate calculation
2026-08-12 7:30 ` Chaoyi Chen
(?)
@ 2026-08-12 7:39 ` sashiko-bot
-1 siblings, 0 replies; 10+ messages in thread
From: sashiko-bot @ 2026-08-12 7:39 UTC (permalink / raw)
To: Chaoyi Chen; +Cc: dri-devel
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] Strict inequality check for maximum lane bit rate incorrectly rejects exact boundary values, causing valid display modes to fail.
--
--- Patch [1]: [PATCH v4 1/3] drm/rockchip: dsi: Add maximum per lane bit rate calculation ---
commit c849fa328462e27e823555ae008f52416cbc0bb9
Author: Chaoyi Chen <chaoyi.chen@rock-chips.com>
drm/rockchip: dsi: Add maximum per lane bit rate calculation
This commit introduces chip-specific maximum lane bit rate boundaries for the
Rockchip DW MIPI DSI driver. This allows varying maximums per platform rather
than using a hardcoded 1500 Mbps default.
> 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;
[Severity: Medium]
Will this cause display modes that exactly match the new lower max_mbps
to fail?
In dw_mipi_dsi_get_lane_mbps(), there is a strict inequality check shortly
after this assignment:
/* take 1 / 0.9, since mbps must big than bandwidth of RGB */
tmp = DIV_ROUND_UP(mpclk * bpp * 10, lanes * 9);
if (tmp < max_mbps)
target_mbps = tmp;
else
DRM_DEV_ERROR(dsi->dev, "DPHY clock frequency is out of range\n");
Because this patch lowers the boundary to 1000 Mbps or 1200 Mbps for several
chips, display modes that yield a bandwidth exactly matching the chip's
maximum will now be rejected.
For example, a mode needing exactly 1000 Mbps would have previously passed
because 1000 < 1500, but will now fail since 1000 is not < 1000. Should the
check be updated to allow exact boundary values by using <= max_mbps?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260812073002.328-1-kernel@airkyi.com?part=1
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v4 3/3] drm/rockchip: dsi: Relax the lane rate margin requirements
2026-08-12 7:30 ` Chaoyi Chen
(?)
@ 2026-08-12 7:42 ` sashiko-bot
-1 siblings, 0 replies; 10+ messages in thread
From: sashiko-bot @ 2026-08-12 7:42 UTC (permalink / raw)
To: Chaoyi Chen; +Cc: dri-devel
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] Incomplete fix: Integer overflow in external D-PHY pixel clock calculation
--
--- Patch [3]: [PATCH v4 3/3] drm/rockchip: dsi: Relax the lane rate margin requirements ---
commit 6f9a68488ce9227bbef69a3b1f33676d60dad2a4
Author: Chaoyi Chen <chaoyi.chen@rock-chips.com>
drm/rockchip: dsi: Relax the lane rate margin requirements
This commit adjusts the DSI lane rate calculation to reduce the bandwidth
overhead from 25% to about 11%. It updates both the target_mbps calculation
and the parameter passed to phy_mipi_dphy_get_default_config().
> diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
> index ddb3a441787e6..c4de442675b79 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 = DIV_ROUND_UP(mpclk * bpp * 10, lanes * 9);
> if (tmp < max_mbps)
> target_mbps = tmp;
> else
> @@ -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((u32)mode->clock * 1000 * 10 / 9,
[Severity: Medium]
Will this (u32) cast still cause an integer overflow for high pixel clocks?
If userspace requests a display mode with a pixel clock exceeding ~429.5 MHz
(e.g., 594 MHz for 4K@60Hz), the intermediate product in
dw_mipi_dsi_get_lane_mbps() will be:
((u32)594000 * 1000 * 10 = 5,940,000,000)
This overflows 32-bit unsigned arithmetic and wraps around to 1,645,032,704.
As a result, the PHY is incorrectly configured with ~182 MHz instead
of 660 MHz, leading to insufficient bandwidth and display failures.
Could we use a 64-bit cast like (u64) to fully prevent overflow during the
intermediate calculation here?
> bpp, lanes,
> &dsi->phy_opts.mipi_dphy);
> dsi->lane_mbps = target_mbps;
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260812073002.328-1-kernel@airkyi.com?part=3
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2026-08-12 7:42 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-12 7:29 [PATCH v4 0/3] DSI Controller improvements for Rockchip platforms Chaoyi Chen
2026-08-12 7:29 ` Chaoyi Chen
2026-08-12 7:30 ` [PATCH v4 1/3] drm/rockchip: dsi: Add maximum per lane bit rate calculation Chaoyi Chen
2026-08-12 7:30 ` Chaoyi Chen
2026-08-12 7:39 ` sashiko-bot
2026-08-12 7:30 ` [PATCH v4 2/3] drm/rockchip: dsi: Add dphy_get_timing support for multiple PHY types Chaoyi Chen
2026-08-12 7:30 ` Chaoyi Chen
2026-08-12 7:30 ` [PATCH v4 3/3] drm/rockchip: dsi: Relax the lane rate margin requirements Chaoyi Chen
2026-08-12 7:30 ` Chaoyi Chen
2026-08-12 7:42 ` sashiko-bot
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.