diff options
Diffstat (limited to 'drivers/gpu/drm/mediatek/mtk_dsi.c')
-rw-r--r-- | drivers/gpu/drm/mediatek/mtk_dsi.c | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c index 290f328c6a..a2fdfc8ddb 100644 --- a/drivers/gpu/drm/mediatek/mtk_dsi.c +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c @@ -86,6 +86,7 @@ #define DSI_CMDQ_SIZE 0x60 #define CMDQ_SIZE 0x3f +#define CMDQ_SIZE_SEL BIT(15) #define DSI_HSTX_CKL_WC 0x64 @@ -178,6 +179,7 @@ struct mtk_dsi_driver_data { const u32 reg_cmdq_off; bool has_shadow_ctl; bool has_size_ctl; + bool cmdq_long_packet_ctl; }; struct mtk_dsi { @@ -806,6 +808,25 @@ static void mtk_dsi_bridge_atomic_post_disable(struct drm_bridge *bridge, mtk_dsi_poweroff(dsi); } +static enum drm_mode_status +mtk_dsi_bridge_mode_valid(struct drm_bridge *bridge, + const struct drm_display_info *info, + const struct drm_display_mode *mode) +{ + struct mtk_dsi *dsi = bridge_to_dsi(bridge); + u32 bpp; + + if (dsi->format == MIPI_DSI_FMT_RGB565) + bpp = 16; + else + bpp = 24; + + if (mode->clock * bpp / dsi->lanes > 1500000) + return MODE_CLOCK_HIGH; + + return MODE_OK; +} + static const struct drm_bridge_funcs mtk_dsi_bridge_funcs = { .attach = mtk_dsi_bridge_attach, .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, @@ -815,6 +836,7 @@ static const struct drm_bridge_funcs mtk_dsi_bridge_funcs = { .atomic_pre_enable = mtk_dsi_bridge_atomic_pre_enable, .atomic_post_disable = mtk_dsi_bridge_atomic_post_disable, .atomic_reset = drm_atomic_helper_bridge_reset, + .mode_valid = mtk_dsi_bridge_mode_valid, .mode_set = mtk_dsi_bridge_mode_set, }; @@ -865,6 +887,15 @@ err_cleanup_encoder: return ret; } +unsigned int mtk_dsi_encoder_index(struct device *dev) +{ + struct mtk_dsi *dsi = dev_get_drvdata(dev); + unsigned int encoder_index = drm_encoder_index(&dsi->encoder); + + dev_dbg(dev, "encoder index:%d\n", encoder_index); + return encoder_index; +} + static int mtk_dsi_bind(struct device *dev, struct device *master, void *data) { int ret; @@ -996,6 +1027,10 @@ static void mtk_dsi_cmdq(struct mtk_dsi *dsi, const struct mipi_dsi_msg *msg) mtk_dsi_mask(dsi, reg_cmdq_off, cmdq_mask, reg_val); mtk_dsi_mask(dsi, DSI_CMDQ_SIZE, CMDQ_SIZE, cmdq_size); + if (dsi->driver_data->cmdq_long_packet_ctl) { + /* Disable setting cmdq_size automatically for long packets */ + mtk_dsi_mask(dsi, DSI_CMDQ_SIZE, CMDQ_SIZE_SEL, CMDQ_SIZE_SEL); + } } static ssize_t mtk_dsi_host_send_cmd(struct mtk_dsi *dsi, @@ -1206,6 +1241,13 @@ static const struct mtk_dsi_driver_data mt8186_dsi_driver_data = { .has_size_ctl = true, }; +static const struct mtk_dsi_driver_data mt8188_dsi_driver_data = { + .reg_cmdq_off = 0xd00, + .has_shadow_ctl = true, + .has_size_ctl = true, + .cmdq_long_packet_ctl = true, +}; + static const struct of_device_id mtk_dsi_of_match[] = { { .compatible = "mediatek,mt2701-dsi", .data = &mt2701_dsi_driver_data }, @@ -1215,6 +1257,8 @@ static const struct of_device_id mtk_dsi_of_match[] = { .data = &mt8183_dsi_driver_data }, { .compatible = "mediatek,mt8186-dsi", .data = &mt8186_dsi_driver_data }, + { .compatible = "mediatek,mt8188-dsi", + .data = &mt8188_dsi_driver_data }, { }, }; MODULE_DEVICE_TABLE(of, mtk_dsi_of_match); |