Newer MediaTek DSI IPs, found in newer SoCs like MT8189 and others can support a higher link rate up to 2.5Gbps, while older ones are limited to 1.5Gbps.
In preparation for adding support for those, move the maximum link rate parameter from being a magic number in mtk_dsi's .mode_valid() callback to platform data, declared for each SoC. Note that said number was previously expressed in Kbps but, in the platform data member, it is now expressed in Mbps instead in order to keep the mtk_dsi_driver_data structure footprint smaller: for this, the calculation in mtk_dsi_bridge_mode_valid() was changed to multiply the max_link_rate_mbps parameter by KILO (1000), which brings the value back to Kbps. Also, since now higher maximum pixel clock rates are achievable, make sure that calculations are not overflowing by casting to u64 where needed. In terms of wasted cycles, this is fine, because this callback is executed only once during display IF enablement (at boot, after a resume from suspend, or during runtime display resolution changes). Signed-off-by: AngeloGioacchino Del Regno <[email protected]> --- drivers/gpu/drm/mediatek/mtk_dsi.c | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c index fa0f404bc7ad..6e92e4e1586f 100644 --- a/drivers/gpu/drm/mediatek/mtk_dsi.c +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c @@ -234,6 +234,8 @@ struct mtk_dsi_driver_data { const u16 *reg_main; const u16 *reg_adv; + const u16 max_link_rate_mbps; + bool has_size_ctl; bool cmdq_long_packet_ctl; bool support_per_frame_lp; @@ -921,7 +923,7 @@ static int mtk_dsi_poweron(struct mtk_dsi *dsi) } bit_per_pixel = ret; - dsi->data_rate = DIV_ROUND_UP_ULL(dsi->vm.pixelclock * bit_per_pixel, + dsi->data_rate = DIV_ROUND_UP_ULL((u64)dsi->vm.pixelclock * bit_per_pixel, dsi->lanes); ret = clk_set_rate(dsi->hs_clk, dsi->data_rate); @@ -1097,13 +1099,21 @@ mtk_dsi_bridge_mode_valid(struct drm_bridge *bridge, const struct drm_display_mode *mode) { struct mtk_dsi *dsi = bridge_to_dsi(bridge); + const struct mtk_dsi_driver_data *data = dsi->driver_data; + u64 wanted_link_rate, max_link_rate; int bpp; bpp = mipi_dsi_pixel_format_to_bpp(dsi->format); if (bpp < 0) return MODE_ERROR; - if (mode->clock * bpp / dsi->lanes > 1500000) + wanted_link_rate = mode->clock; + wanted_link_rate *= bpp; + max_link_rate = data->max_link_rate_mbps; + max_link_rate *= dsi->lanes; + max_link_rate *= KILO; + + if (wanted_link_rate > max_link_rate) return MODE_CLOCK_HIGH; if (dsi->dsc) { @@ -1547,28 +1557,42 @@ static void mtk_dsi_remove(struct platform_device *pdev) static const struct mtk_dsi_driver_data mt8173_dsi_driver_data = { .reg_main = mtk_dsi_regs_main_v1, .reg_adv = mtk_dsi_regs_mt8173, + .max_link_rate_mbps = 1500, }; static const struct mtk_dsi_driver_data mt2701_dsi_driver_data = { .reg_main = mtk_dsi_regs_main_v1, .reg_adv = mtk_dsi_regs_mt2701, + .max_link_rate_mbps = 1500, }; static const struct mtk_dsi_driver_data mt8183_dsi_driver_data = { .reg_main = mtk_dsi_regs_main_v1, .reg_adv = mtk_dsi_regs_mt8183, + .max_link_rate_mbps = 1500, .has_size_ctl = true, }; static const struct mtk_dsi_driver_data mt8186_dsi_driver_data = { .reg_main = mtk_dsi_regs_main_v1, .reg_adv = mtk_dsi_regs_mt8186, + .max_link_rate_mbps = 1500, .has_size_ctl = true, }; static const struct mtk_dsi_driver_data mt8188_dsi_driver_data = { .reg_main = mtk_dsi_regs_main_v1, .reg_adv = mtk_dsi_regs_mt8186, + .max_link_rate_mbps = 1500, + .has_size_ctl = true, + .cmdq_long_packet_ctl = true, + .support_per_frame_lp = true, +}; + +static const struct mtk_dsi_driver_data mt8189_dsi_driver_data = { + .reg_main = mtk_dsi_regs_main_v1, + .reg_adv = mtk_dsi_regs_mt8186, + .max_link_rate_mbps = 2500, .has_size_ctl = true, .cmdq_long_packet_ctl = true, .support_per_frame_lp = true, @@ -1581,6 +1605,7 @@ static const struct of_device_id mtk_dsi_of_match[] = { { .compatible = "mediatek,mt8183-dsi", .data = &mt8183_dsi_driver_data }, { .compatible = "mediatek,mt8186-dsi", .data = &mt8186_dsi_driver_data }, { .compatible = "mediatek,mt8188-dsi", .data = &mt8188_dsi_driver_data }, + { .compatible = "mediatek,mt8189-dsi", .data = &mt8189_dsi_driver_data }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, mtk_dsi_of_match); -- 2.55.0
