Add support for the DSI IP found in the MT8189 SoC: this one is
similar to the IPs found in the most recent already supported SoCs
with the only difference being that it supports a higher link rate
of 2.5Gbps instead of 1.5Gbps.

To support the higher rate, add a new "max_link_rate_mbps" member
to the mtk_dsi_driver_data, assign the correct one to all of the
supported SoCs, other than to the newly introduced MT8189, and
use it in the .mode_valid() callback in place of the hardcoded
1.5Gbps value.

Since .mode_valid() is supposed to run just for resolution changes
the link rate was expressed in Mbps and gets multiplied on the fly
to save some bits.

Signed-off-by: AngeloGioacchino Del Regno 
<[email protected]>
---
 drivers/gpu/drm/mediatek/mtk_dsi.c | 26 +++++++++++++++++++++++++-
 1 file changed, 25 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c 
b/drivers/gpu/drm/mediatek/mtk_dsi.c
index 37c34413130b..ba96c12a8ceb 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -235,6 +235,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;
@@ -1066,13 +1068,20 @@ 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 * 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) {
@@ -1499,28 +1508,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,
@@ -1532,6 +1555,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.54.0

Reply via email to