From 6db41ed53292167d1c1efaf394981bd044fd808b Mon Sep 17 00:00:00 2001 From: Abhinav Kumar Date: Fri, 24 Jul 2020 14:06:47 -0400 Subject: [PATCH] disp: msm: dp: add support for continuous PPS command Add support to send PPS command with every frame for DP. This is needed to satisfy the requirement of certain bridge chips which need the PPS to be sent every frame. Change-Id: I8711dff41e60d8b1e1c515a5d34a370a2409ce14 Signed-off-by: Abhinav Kumar Signed-off-by: Sudarsan Ramesh --- msm/dp/dp_catalog.c | 7 +++++++ msm/dp/dp_catalog.h | 1 + msm/dp/dp_display.c | 1 + msm/dp/dp_display.h | 1 + msm/dp/dp_drm.c | 4 ++++ msm/dp/dp_mst_drm.c | 19 +++++++++++++++++-- msm/dp/dp_panel.c | 4 +++- msm/dp/dp_panel.h | 1 + msm/dp/dp_parser.c | 5 +++++ msm/dp/dp_parser.h | 2 ++ 10 files changed, 42 insertions(+), 3 deletions(-) diff --git a/msm/dp/dp_catalog.c b/msm/dp/dp_catalog.c index 40086d43f2..b3b7c59f02 100644 --- a/msm/dp/dp_catalog.c +++ b/msm/dp/dp_catalog.c @@ -1534,6 +1534,7 @@ static void dp_catalog_panel_dp_flush(struct dp_catalog_panel *panel, struct dp_catalog_private *catalog; struct dp_io_data *io_data; u32 dp_flush, offset; + struct dp_dsc_cfg_data *dsc; if (!panel) { DP_ERR("invalid input\n"); @@ -1547,6 +1548,7 @@ static void dp_catalog_panel_dp_flush(struct dp_catalog_panel *panel, catalog = dp_catalog_get_priv(panel); io_data = catalog->io.dp_link; + dsc = &panel->dsc; if (panel->stream_id == DP_STREAM_0) offset = 0; @@ -1554,6 +1556,11 @@ static void dp_catalog_panel_dp_flush(struct dp_catalog_panel *panel, offset = MMSS_DP1_FLUSH - MMSS_DP_FLUSH; dp_flush = dp_read(MMSS_DP_FLUSH + offset); + + if ((flush_bit == DP_PPS_FLUSH) && + dsc->continuous_pps) + dp_flush &= ~BIT(2); + dp_flush |= BIT(flush_bit); dp_write(MMSS_DP_FLUSH + offset, dp_flush); } diff --git a/msm/dp/dp_catalog.h b/msm/dp/dp_catalog.h index 65e8f2b8e1..f73a1713ff 100644 --- a/msm/dp/dp_catalog.h +++ b/msm/dp/dp_catalog.h @@ -149,6 +149,7 @@ struct dp_catalog_audio { struct dp_dsc_cfg_data { bool dsc_en; + bool continuous_pps; char pps[128]; u32 pps_len; u32 pps_word[32]; diff --git a/msm/dp/dp_display.c b/msm/dp/dp_display.c index 014e8bb920..34e5e71bfa 100644 --- a/msm/dp/dp_display.c +++ b/msm/dp/dp_display.c @@ -1883,6 +1883,7 @@ static int dp_init_sub_modules(struct dp_display_private *dp) } g_dp_display->is_mst_supported = dp->parser->has_mst; + g_dp_display->dsc_cont_pps = dp->parser->dsc_continuous_pps; dp->catalog = dp_catalog_get(dev, dp->parser); if (IS_ERR(dp->catalog)) { diff --git a/msm/dp/dp_display.h b/msm/dp/dp_display.h index d73740b28c..eda860c74c 100644 --- a/msm/dp/dp_display.h +++ b/msm/dp/dp_display.h @@ -70,6 +70,7 @@ struct dp_display { void *base_dp_panel; bool is_sst_connected; bool is_mst_supported; + bool dsc_cont_pps; u32 max_pclk_khz; void *dp_mst_prv_info; u32 max_mixer_count; diff --git a/msm/dp/dp_drm.c b/msm/dp/dp_drm.c index 3abe14e916..f1e870af08 100644 --- a/msm/dp/dp_drm.c +++ b/msm/dp/dp_drm.c @@ -366,6 +366,10 @@ int dp_connector_post_init(struct drm_connector *connector, void *display) dp_display->bridge->dp_panel = sde_conn->drv_panel; rc = dp_mst_init(dp_display); + + if (dp_display->dsc_cont_pps) + sde_conn->ops.update_pps = NULL; + end: return rc; } diff --git a/msm/dp/dp_mst_drm.c b/msm/dp/dp_mst_drm.c index 13c660146d..e1ccf47b38 100644 --- a/msm/dp/dp_mst_drm.c +++ b/msm/dp/dp_mst_drm.c @@ -1768,6 +1768,21 @@ static void dp_mst_connector_pre_destroy(struct drm_connector *connector, SDE_EVT32_EXTERNAL(SDE_EVTLOG_FUNC_EXIT, conn_id); } +static int dp_mst_connector_post_init(struct drm_connector *connector, + void *display) +{ + struct dp_display *dp_display = display; + struct sde_connector *sde_conn = to_sde_connector(connector); + + if (!dp_display || !connector) + return -EINVAL; + + if (dp_display->dsc_cont_pps) + sde_conn->ops.update_pps = NULL; + + return 0; +} + /* DRM MST callbacks */ static struct drm_connector * @@ -1775,7 +1790,7 @@ dp_mst_add_connector(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port, const char *pathprop) { static const struct sde_connector_ops dp_mst_connector_ops = { - .post_init = NULL, + .post_init = dp_mst_connector_post_init, .detect = dp_mst_connector_detect, .get_modes = dp_mst_connector_get_modes, .mode_valid = dp_mst_connector_mode_valid, @@ -2120,7 +2135,7 @@ dp_mst_drm_fixed_connector_init(struct dp_display *dp_display, struct drm_encoder *encoder) { static const struct sde_connector_ops dp_mst_connector_ops = { - .post_init = NULL, + .post_init = dp_mst_connector_post_init, .detect = dp_mst_fixed_connector_detect, .get_modes = dp_mst_connector_get_modes, .mode_valid = dp_mst_connector_mode_valid, diff --git a/msm/dp/dp_panel.c b/msm/dp/dp_panel.c index 3937eda85b..5fd9d8f9bc 100644 --- a/msm/dp/dp_panel.c +++ b/msm/dp/dp_panel.c @@ -2202,7 +2202,7 @@ static void dp_panel_config_dsc(struct dp_panel *dp_panel, bool enable) dsc->be_in_lane = _dp_panel_calc_be_in_lane(dp_panel); dsc->dsc_en = true; dsc->dto_en = true; - + dsc->continuous_pps = dp_panel->dsc_continuous_pps; dp_panel_get_dto_params(comp_info->comp_ratio, &dsc->dto_n, &dsc->dto_d, pinfo->bpp); } else { @@ -2210,6 +2210,7 @@ static void dp_panel_config_dsc(struct dp_panel *dp_panel, bool enable) dsc->dto_en = false; dsc->dto_n = 0; dsc->dto_d = 0; + dsc->continuous_pps = false; } catalog->stream_id = dp_panel->stream_id; @@ -3007,6 +3008,7 @@ struct dp_panel *dp_panel_get(struct dp_panel_in *in) dp_panel->dsc_feature_enable = panel->parser->dsc_feature_enable; dp_panel->fec_feature_enable = panel->parser->fec_feature_enable; + dp_panel->dsc_continuous_pps = panel->parser->dsc_continuous_pps; if (in->base_panel) { memcpy(dp_panel->dpcd, in->base_panel->dpcd, diff --git a/msm/dp/dp_panel.h b/msm/dp/dp_panel.h index 78fd81fc4f..f3b4ac9233 100644 --- a/msm/dp/dp_panel.h +++ b/msm/dp/dp_panel.h @@ -133,6 +133,7 @@ struct dp_panel { bool dsc_en; bool fec_en; bool widebus_en; + bool dsc_continuous_pps; bool mst_state; s64 fec_overhead_fp; diff --git a/msm/dp/dp_parser.c b/msm/dp/dp_parser.c index dbe11c37a0..b94133b5e0 100644 --- a/msm/dp/dp_parser.c +++ b/msm/dp/dp_parser.c @@ -727,8 +727,13 @@ static void dp_parser_dsc(struct dp_parser *parser) parser->dsc_feature_enable = of_property_read_bool(dev->of_node, "qcom,dsc-feature-enable"); + parser->dsc_continuous_pps = of_property_read_bool(dev->of_node, + "qcom,dsc-continuous-pps"); + DP_DEBUG("dsc parsing successful. dsc:%d\n", parser->dsc_feature_enable); + DP_DEBUG("cont_pps:%d\n", + parser->dsc_continuous_pps); } static void dp_parser_fec(struct dp_parser *parser) diff --git a/msm/dp/dp_parser.h b/msm/dp/dp_parser.h index 8ba2e5dc7e..678185705f 100644 --- a/msm/dp/dp_parser.h +++ b/msm/dp/dp_parser.h @@ -195,6 +195,7 @@ static inline char *dp_phy_aux_config_type_to_string(u32 cfg_type) * @gpio_aux_switch: presence GPIO AUX switch status * @dsc_feature_enable: DSC feature enable status * @fec_feature_enable: FEC feature enable status + * @dsc_continuous_pps: PPS sent every frame by HW * @has_widebus: widebus (2PPC) feature eanble status *@mst_fixed_port: mst port_num reserved for fixed topology * @parse: function to be called by client to parse device tree. @@ -221,6 +222,7 @@ struct dp_parser { bool no_aux_switch; bool dsc_feature_enable; bool fec_feature_enable; + bool dsc_continuous_pps; bool has_widebus; bool gpio_aux_switch; bool lphw_hpd;