* [PATCH 1/2] drm/rockchip: dsi: Add maximum per lane bit rate calculation
@ 2026-03-24 8:58 Chaoyi Chen
2026-03-24 8:58 ` [PATCH 2/2] drm/rockchip: dsi: Add dphy_get_timing support for multiple PHY types Chaoyi Chen
` (2 more replies)
0 siblings, 3 replies; 5+ messages in thread
From: Chaoyi Chen @ 2026-03-24 8:58 UTC (permalink / raw)
To: Sandy Huang, Heiko Stübner, Andy Yan, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Guochun Huang
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, and relax the bandwidth margin requirements.
Signed-off-by: Chaoyi Chen <chaoyi.chen@rock-chips.com>
---
.../gpu/drm/rockchip/dw-mipi-dsi-rockchip.c | 21 +++++++++++++++----
1 file changed, 17 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
index 3547d91b25d3..d3bacfae174e 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;
dsi->format = format;
bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
if (bpp < 0) {
@@ -584,8 +586,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
@@ -595,7 +597,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;
@@ -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.51.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 2/2] drm/rockchip: dsi: Add dphy_get_timing support for multiple PHY types
2026-03-24 8:58 [PATCH 1/2] drm/rockchip: dsi: Add maximum per lane bit rate calculation Chaoyi Chen
@ 2026-03-24 8:58 ` Chaoyi Chen
2026-06-02 21:02 ` Heiko Stuebner
2026-05-12 1:07 ` [PATCH 1/2] drm/rockchip: dsi: Add maximum per lane bit rate calculation Chaoyi Chen
2026-06-02 20:59 ` Heiko Stuebner
2 siblings, 1 reply; 5+ messages in thread
From: Chaoyi Chen @ 2026-03-24 8:58 UTC (permalink / raw)
To: Sandy Huang, Heiko Stübner, Andy Yan, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Guochun Huang
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.
Signed-off-by: Chaoyi Chen <chaoyi.chen@rock-chips.com>
---
.../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 d3bacfae174e..2d1c9e54ff85 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.51.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH 1/2] drm/rockchip: dsi: Add maximum per lane bit rate calculation
2026-03-24 8:58 [PATCH 1/2] drm/rockchip: dsi: Add maximum per lane bit rate calculation Chaoyi Chen
2026-03-24 8:58 ` [PATCH 2/2] drm/rockchip: dsi: Add dphy_get_timing support for multiple PHY types Chaoyi Chen
@ 2026-05-12 1:07 ` Chaoyi Chen
2026-06-02 20:59 ` Heiko Stuebner
2 siblings, 0 replies; 5+ messages in thread
From: Chaoyi Chen @ 2026-05-12 1:07 UTC (permalink / raw)
To: Heiko Stübner
Cc: Chaoyi Chen, Sandy Huang, Andy Yan, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Guochun Huang, dri-devel, linux-arm-kernel, linux-rockchip,
linux-kernel
Hi,
On 3/24/2026 4:58 PM, Chaoyi Chen wrote:
> 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, and relax the bandwidth margin requirements.
>
> Signed-off-by: Chaoyi Chen <chaoyi.chen@rock-chips.com>
> ---
> .../gpu/drm/rockchip/dw-mipi-dsi-rockchip.c | 21 +++++++++++++++----
> 1 file changed, 17 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
> index 3547d91b25d3..d3bacfae174e 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;
> dsi->format = format;
> bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
> if (bpp < 0) {
> @@ -584,8 +586,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
> @@ -595,7 +597,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;
> @@ -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 */ }
> };
Gentle ping about this.
Thanks!
--
Best,
Chaoyi
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 1/2] drm/rockchip: dsi: Add maximum per lane bit rate calculation
2026-03-24 8:58 [PATCH 1/2] drm/rockchip: dsi: Add maximum per lane bit rate calculation Chaoyi Chen
2026-03-24 8:58 ` [PATCH 2/2] drm/rockchip: dsi: Add dphy_get_timing support for multiple PHY types Chaoyi Chen
2026-05-12 1:07 ` [PATCH 1/2] drm/rockchip: dsi: Add maximum per lane bit rate calculation Chaoyi Chen
@ 2026-06-02 20:59 ` Heiko Stuebner
2 siblings, 0 replies; 5+ messages in thread
From: Heiko Stuebner @ 2026-06-02 20:59 UTC (permalink / raw)
To: Sandy Huang, Andy Yan, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Guochun Huang,
Chaoyi Chen
Cc: dri-devel, linux-arm-kernel, linux-rockchip, linux-kernel,
Chaoyi Chen
Am Dienstag, 24. März 2026, 09:58:37 Mitteleuropäische Sommerzeit schrieb 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, and relax the bandwidth margin requirements.
>
> Signed-off-by: Chaoyi Chen <chaoyi.chen@rock-chips.com>
> ---
> .../gpu/drm/rockchip/dw-mipi-dsi-rockchip.c | 21 +++++++++++++++----
> 1 file changed, 17 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
> index 3547d91b25d3..d3bacfae174e 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;
I may be blind, but how do the values come together?
In the dppa_map table we have mbps values of 89 to 1500
(MHz)
While below the values set are
.max_bit_rate_per_lane = 1500000000UL,
in Hz I guess
And I don't see the needed conversion somehow.
> dsi->format = format;
> bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
> if (bpp < 0) {
> @@ -584,8 +586,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;
Please do this in a separate patch, especially as I would expect some
sort of explanation on why this is ok to do.
Thanks
Heiko
> if (tmp < max_mbps)
> target_mbps = tmp;
> else
> @@ -595,7 +597,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;
> @@ -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 */ }
> };
>
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 2/2] drm/rockchip: dsi: Add dphy_get_timing support for multiple PHY types
2026-03-24 8:58 ` [PATCH 2/2] drm/rockchip: dsi: Add dphy_get_timing support for multiple PHY types Chaoyi Chen
@ 2026-06-02 21:02 ` Heiko Stuebner
0 siblings, 0 replies; 5+ messages in thread
From: Heiko Stuebner @ 2026-06-02 21:02 UTC (permalink / raw)
To: Sandy Huang, Andy Yan, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Guochun Huang,
Chaoyi Chen
Cc: dri-devel, linux-arm-kernel, linux-rockchip, linux-kernel,
Chaoyi Chen
Am Dienstag, 24. März 2026, 09:58:38 Mitteleuropäische Sommerzeit schrieb 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.
>
> Signed-off-by: Chaoyi Chen <chaoyi.chen@rock-chips.com>
> ---
> .../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 d3bacfae174e..2d1c9e54ff85 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,
> +};
so just to make sure, the timing on the px30 (and later) variant is the
same for all lane speeds?
Please include that bit in the commit description
Thanks
Heiko
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-06-02 21:02 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-24 8:58 [PATCH 1/2] drm/rockchip: dsi: Add maximum per lane bit rate calculation Chaoyi Chen
2026-03-24 8:58 ` [PATCH 2/2] drm/rockchip: dsi: Add dphy_get_timing support for multiple PHY types Chaoyi Chen
2026-06-02 21:02 ` Heiko Stuebner
2026-05-12 1:07 ` [PATCH 1/2] drm/rockchip: dsi: Add maximum per lane bit rate calculation Chaoyi Chen
2026-06-02 20:59 ` Heiko Stuebner
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox