Loading msm/dp/dp_ctrl.c +18 −11 Original line number Diff line number Diff line Loading @@ -69,6 +69,7 @@ struct dp_ctrl_private { bool power_on; bool mst_mode; bool fec_mode; bool dsc_mode; atomic_t aborted; Loading Loading @@ -575,7 +576,6 @@ static int dp_ctrl_link_train(struct dp_ctrl_private *ctrl) static int dp_ctrl_setup_main_link(struct dp_ctrl_private *ctrl) { int ret = 0; const unsigned int fec_cfg_dpcd = 0x120; if (ctrl->link->sink_request & DP_TEST_LINK_PHY_TEST_PATTERN) goto end; Loading @@ -588,7 +588,8 @@ static int dp_ctrl_setup_main_link(struct dp_ctrl_private *ctrl) ctrl->catalog->reset(ctrl->catalog); if (ctrl->fec_mode) drm_dp_dpcd_writeb(ctrl->aux->drm_aux, fec_cfg_dpcd, 0x01); drm_dp_dpcd_writeb(ctrl->aux->drm_aux, DP_FEC_CONFIGURATION, 0x01); ret = dp_ctrl_link_train(ctrl); Loading Loading @@ -926,7 +927,7 @@ static void dp_ctrl_process_phy_test_request(struct dp_ctrl *dp_ctrl) ctrl->aux->init(ctrl->aux, ctrl->parser->aux_cfg); ret = ctrl->dp_ctrl.on(&ctrl->dp_ctrl, ctrl->mst_mode, ctrl->fec_mode, false); ctrl->fec_mode, ctrl->dsc_mode, false); if (ret) DP_ERR("failed to enable DP controller\n"); Loading Loading @@ -1138,19 +1139,18 @@ static void dp_ctrl_fec_dsc_setup(struct dp_ctrl_private *ctrl) u8 fec_sts = 0; int rlen; u32 dsc_enable; const unsigned int fec_sts_dpcd = 0x280; if (ctrl->stream_count || !ctrl->fec_mode) if (!ctrl->fec_mode) return; ctrl->catalog->fec_config(ctrl->catalog, ctrl->fec_mode); /* wait for controller to start fec sequence */ usleep_range(900, 1000); drm_dp_dpcd_readb(ctrl->aux->drm_aux, fec_sts_dpcd, &fec_sts); drm_dp_dpcd_readb(ctrl->aux->drm_aux, DP_FEC_STATUS, &fec_sts); DP_DEBUG("sink fec status:%d\n", fec_sts); dsc_enable = ctrl->fec_mode ? 1 : 0; dsc_enable = ctrl->dsc_mode ? 1 : 0; rlen = drm_dp_dpcd_writeb(ctrl->aux->drm_aux, DP_DSC_ENABLE, dsc_enable); if (rlen < 1) Loading Loading @@ -1191,13 +1191,14 @@ static int dp_ctrl_stream_on(struct dp_ctrl *dp_ctrl, struct dp_panel *panel) dp_ctrl_wait4video_ready(ctrl); dp_ctrl_fec_dsc_setup(ctrl); ctrl->stream_count++; link_ready = ctrl->catalog->mainlink_ready(ctrl->catalog); DP_DEBUG("mainlink %s\n", link_ready ? "READY" : "NOT READY"); /* wait for link training completion before fec config as per spec */ dp_ctrl_fec_dsc_setup(ctrl); return rc; } Loading Loading @@ -1266,7 +1267,7 @@ static void dp_ctrl_stream_off(struct dp_ctrl *dp_ctrl, struct dp_panel *panel) } static int dp_ctrl_on(struct dp_ctrl *dp_ctrl, bool mst_mode, bool fec_mode, bool shallow) bool fec_mode, bool dsc_mode, bool shallow) { int rc = 0; struct dp_ctrl_private *ctrl; Loading @@ -1285,7 +1286,11 @@ static int dp_ctrl_on(struct dp_ctrl *dp_ctrl, bool mst_mode, goto end; ctrl->mst_mode = mst_mode; if (fec_mode) { ctrl->fec_mode = fec_mode; ctrl->dsc_mode = dsc_mode; } rate = ctrl->panel->link_info.rate; if (ctrl->link->sink_request & DP_TEST_LINK_PHY_TEST_PATTERN) { Loading Loading @@ -1323,6 +1328,7 @@ static void dp_ctrl_off(struct dp_ctrl *dp_ctrl) if (!ctrl->power_on) return; ctrl->catalog->fec_config(ctrl->catalog, false); dp_ctrl_configure_source_link_params(ctrl, false); ctrl->catalog->reset(ctrl->catalog); Loading @@ -1333,6 +1339,7 @@ static void dp_ctrl_off(struct dp_ctrl *dp_ctrl) ctrl->mst_mode = false; ctrl->fec_mode = false; ctrl->dsc_mode = false; ctrl->power_on = false; memset(&ctrl->mst_ch_info, 0, sizeof(ctrl->mst_ch_info)); DP_DEBUG("DP off done\n"); Loading msm/dp/dp_ctrl.h +1 −1 Original line number Diff line number Diff line Loading @@ -17,7 +17,7 @@ struct dp_ctrl { int (*init)(struct dp_ctrl *dp_ctrl, bool flip, bool reset); void (*deinit)(struct dp_ctrl *dp_ctrl); int (*on)(struct dp_ctrl *dp_ctrl, bool mst_mode, bool fec_en, bool shallow); bool dsc_en, bool shallow); void (*off)(struct dp_ctrl *dp_ctrl); void (*abort)(struct dp_ctrl *dp_ctrl); void (*isr)(struct dp_ctrl *dp_ctrl); Loading msm/dp/dp_display.c +3 −2 Original line number Diff line number Diff line Loading @@ -884,7 +884,7 @@ static int dp_display_process_hpd_high(struct dp_display_private *dp) dp_display_process_mst_hpd_high(dp, false); rc = dp->ctrl->on(dp->ctrl, dp->mst.mst_active, dp->panel->fec_en, false); dp->panel->fec_en, dp->panel->dsc_en, false); if (rc) { dp_display_state_remove(DP_STATE_CONNECTED); goto end; Loading Loading @@ -1665,7 +1665,8 @@ static int dp_display_prepare(struct dp_display *dp_display, void *panel) * So, we execute in shallow mode here to do only minimal * and required things. */ rc = dp->ctrl->on(dp->ctrl, dp->mst.mst_active, dp_panel->fec_en, true); rc = dp->ctrl->on(dp->ctrl, dp->mst.mst_active, dp_panel->fec_en, dp_panel->dsc_en, true); if (rc) goto end; Loading msm/dp/dp_panel.c +46 −30 Original line number Diff line number Diff line Loading @@ -2019,14 +2019,7 @@ static int dp_panel_read_edid(struct dp_panel *dp_panel, static void dp_panel_decode_dsc_dpcd(struct dp_panel *dp_panel) { s64 fec_overhead_fp = drm_fixp_from_fraction(1, 1); if (!dp_panel->dsc_feature_enable || !dp_panel->fec_feature_enable) { DP_DEBUG("source dsc is not supported\n"); return; } if (dp_panel->dsc_dpcd[0] && dp_panel->fec_dpcd) { if (dp_panel->dsc_dpcd[0]) { dp_panel->sink_dsc_caps.dsc_capable = true; dp_panel->sink_dsc_caps.version = dp_panel->dsc_dpcd[1]; dp_panel->sink_dsc_caps.block_pred_en = Loading @@ -2039,21 +2032,13 @@ static void dp_panel_decode_dsc_dpcd(struct dp_panel *dp_panel) dp_panel->dsc_en = false; } dp_panel->fec_en = dp_panel->dsc_en; dp_panel->widebus_en = dp_panel->dsc_en; /* fec_overhead = 1.00 / 0.97582 */ if (dp_panel->fec_en) fec_overhead_fp = drm_fixp_from_fraction(100000, 97582); dp_panel->fec_overhead_fp = fec_overhead_fp; } static void dp_panel_read_sink_dsc_caps(struct dp_panel *dp_panel) { int rlen; struct dp_panel_private *panel; const int fec_cap = 0x90; int dpcd_rev; if (!dp_panel) { Loading @@ -2061,14 +2046,9 @@ static void dp_panel_read_sink_dsc_caps(struct dp_panel *dp_panel) return; } dp_panel->dsc_en = false; dp_panel->fec_en = false; dpcd_rev = dp_panel->dpcd[DP_DPCD_REV]; panel = container_of(dp_panel, struct dp_panel_private, dp_panel); dp_panel->fec_overhead_fp = 0; if (panel->parser->dsc_feature_enable && dpcd_rev >= 0x14) { rlen = drm_dp_dpcd_read(panel->aux->drm_aux, DP_DSC_SUPPORT, dp_panel->dsc_dpcd, (DP_RECEIVER_DSC_CAP_SIZE + 1)); Loading @@ -2081,15 +2061,36 @@ static void dp_panel_read_sink_dsc_caps(struct dp_panel *dp_panel) DUMP_PREFIX_NONE, 8, 1, dp_panel->dsc_dpcd, rlen, false); rlen = drm_dp_dpcd_read(panel->aux->drm_aux, fec_cap, &dp_panel->fec_dpcd, 1); if (rlen < 1) { DP_ERR("fec dpcd read failed, rlen=%d\n", rlen); dp_panel_decode_dsc_dpcd(dp_panel); } } static void dp_panel_read_sink_fec_caps(struct dp_panel *dp_panel) { int rlen; struct dp_panel_private *panel; s64 fec_overhead_fp = drm_fixp_from_fraction(1, 1); if (!dp_panel) { DP_ERR("invalid input\n"); return; } dp_panel_decode_dsc_dpcd(dp_panel); panel = container_of(dp_panel, struct dp_panel_private, dp_panel); rlen = drm_dp_dpcd_readb(panel->aux->drm_aux, DP_FEC_CAPABILITY, &dp_panel->fec_dpcd); if (rlen < 1) { DP_ERR("fec capability read failed, rlen=%d\n", rlen); return; } dp_panel->fec_en = dp_panel->fec_dpcd & DP_FEC_CAPABLE; if (dp_panel->fec_en) fec_overhead_fp = drm_fixp_from_fraction(100000, 97582); dp_panel->fec_overhead_fp = fec_overhead_fp; return; } static int dp_panel_read_sink_caps(struct dp_panel *dp_panel, Loading Loading @@ -2148,7 +2149,18 @@ static int dp_panel_read_sink_caps(struct dp_panel *dp_panel, dp_panel->dsc_feature_enable = panel->parser->dsc_feature_enable; dp_panel->fec_feature_enable = panel->parser->fec_feature_enable; dp_panel->fec_en = false; dp_panel->dsc_en = false; if (dp_panel->fec_feature_enable) { dp_panel_read_sink_fec_caps(dp_panel); if (dp_panel->dsc_feature_enable && dp_panel->fec_en) dp_panel_read_sink_dsc_caps(dp_panel); } DP_INFO("fec_en=%d, dsc_en=%d, widebus_en=%d\n", dp_panel->fec_en, dp_panel->dsc_en, dp_panel->widebus_en); end: return rc; } Loading @@ -2157,9 +2169,13 @@ static u32 dp_panel_get_supported_bpp(struct dp_panel *dp_panel, u32 mode_edid_bpp, u32 mode_pclk_khz) { struct drm_dp_link *link_info; const u32 max_supported_bpp = 30, min_supported_bpp = 18; const u32 max_supported_bpp = 30; u32 min_supported_bpp = 18; u32 bpp = 0, data_rate_khz = 0; if (dp_panel->dsc_en) min_supported_bpp = 24; bpp = min_t(u32, mode_edid_bpp, max_supported_bpp); link_info = &dp_panel->link_info; Loading Loading
msm/dp/dp_ctrl.c +18 −11 Original line number Diff line number Diff line Loading @@ -69,6 +69,7 @@ struct dp_ctrl_private { bool power_on; bool mst_mode; bool fec_mode; bool dsc_mode; atomic_t aborted; Loading Loading @@ -575,7 +576,6 @@ static int dp_ctrl_link_train(struct dp_ctrl_private *ctrl) static int dp_ctrl_setup_main_link(struct dp_ctrl_private *ctrl) { int ret = 0; const unsigned int fec_cfg_dpcd = 0x120; if (ctrl->link->sink_request & DP_TEST_LINK_PHY_TEST_PATTERN) goto end; Loading @@ -588,7 +588,8 @@ static int dp_ctrl_setup_main_link(struct dp_ctrl_private *ctrl) ctrl->catalog->reset(ctrl->catalog); if (ctrl->fec_mode) drm_dp_dpcd_writeb(ctrl->aux->drm_aux, fec_cfg_dpcd, 0x01); drm_dp_dpcd_writeb(ctrl->aux->drm_aux, DP_FEC_CONFIGURATION, 0x01); ret = dp_ctrl_link_train(ctrl); Loading Loading @@ -926,7 +927,7 @@ static void dp_ctrl_process_phy_test_request(struct dp_ctrl *dp_ctrl) ctrl->aux->init(ctrl->aux, ctrl->parser->aux_cfg); ret = ctrl->dp_ctrl.on(&ctrl->dp_ctrl, ctrl->mst_mode, ctrl->fec_mode, false); ctrl->fec_mode, ctrl->dsc_mode, false); if (ret) DP_ERR("failed to enable DP controller\n"); Loading Loading @@ -1138,19 +1139,18 @@ static void dp_ctrl_fec_dsc_setup(struct dp_ctrl_private *ctrl) u8 fec_sts = 0; int rlen; u32 dsc_enable; const unsigned int fec_sts_dpcd = 0x280; if (ctrl->stream_count || !ctrl->fec_mode) if (!ctrl->fec_mode) return; ctrl->catalog->fec_config(ctrl->catalog, ctrl->fec_mode); /* wait for controller to start fec sequence */ usleep_range(900, 1000); drm_dp_dpcd_readb(ctrl->aux->drm_aux, fec_sts_dpcd, &fec_sts); drm_dp_dpcd_readb(ctrl->aux->drm_aux, DP_FEC_STATUS, &fec_sts); DP_DEBUG("sink fec status:%d\n", fec_sts); dsc_enable = ctrl->fec_mode ? 1 : 0; dsc_enable = ctrl->dsc_mode ? 1 : 0; rlen = drm_dp_dpcd_writeb(ctrl->aux->drm_aux, DP_DSC_ENABLE, dsc_enable); if (rlen < 1) Loading Loading @@ -1191,13 +1191,14 @@ static int dp_ctrl_stream_on(struct dp_ctrl *dp_ctrl, struct dp_panel *panel) dp_ctrl_wait4video_ready(ctrl); dp_ctrl_fec_dsc_setup(ctrl); ctrl->stream_count++; link_ready = ctrl->catalog->mainlink_ready(ctrl->catalog); DP_DEBUG("mainlink %s\n", link_ready ? "READY" : "NOT READY"); /* wait for link training completion before fec config as per spec */ dp_ctrl_fec_dsc_setup(ctrl); return rc; } Loading Loading @@ -1266,7 +1267,7 @@ static void dp_ctrl_stream_off(struct dp_ctrl *dp_ctrl, struct dp_panel *panel) } static int dp_ctrl_on(struct dp_ctrl *dp_ctrl, bool mst_mode, bool fec_mode, bool shallow) bool fec_mode, bool dsc_mode, bool shallow) { int rc = 0; struct dp_ctrl_private *ctrl; Loading @@ -1285,7 +1286,11 @@ static int dp_ctrl_on(struct dp_ctrl *dp_ctrl, bool mst_mode, goto end; ctrl->mst_mode = mst_mode; if (fec_mode) { ctrl->fec_mode = fec_mode; ctrl->dsc_mode = dsc_mode; } rate = ctrl->panel->link_info.rate; if (ctrl->link->sink_request & DP_TEST_LINK_PHY_TEST_PATTERN) { Loading Loading @@ -1323,6 +1328,7 @@ static void dp_ctrl_off(struct dp_ctrl *dp_ctrl) if (!ctrl->power_on) return; ctrl->catalog->fec_config(ctrl->catalog, false); dp_ctrl_configure_source_link_params(ctrl, false); ctrl->catalog->reset(ctrl->catalog); Loading @@ -1333,6 +1339,7 @@ static void dp_ctrl_off(struct dp_ctrl *dp_ctrl) ctrl->mst_mode = false; ctrl->fec_mode = false; ctrl->dsc_mode = false; ctrl->power_on = false; memset(&ctrl->mst_ch_info, 0, sizeof(ctrl->mst_ch_info)); DP_DEBUG("DP off done\n"); Loading
msm/dp/dp_ctrl.h +1 −1 Original line number Diff line number Diff line Loading @@ -17,7 +17,7 @@ struct dp_ctrl { int (*init)(struct dp_ctrl *dp_ctrl, bool flip, bool reset); void (*deinit)(struct dp_ctrl *dp_ctrl); int (*on)(struct dp_ctrl *dp_ctrl, bool mst_mode, bool fec_en, bool shallow); bool dsc_en, bool shallow); void (*off)(struct dp_ctrl *dp_ctrl); void (*abort)(struct dp_ctrl *dp_ctrl); void (*isr)(struct dp_ctrl *dp_ctrl); Loading
msm/dp/dp_display.c +3 −2 Original line number Diff line number Diff line Loading @@ -884,7 +884,7 @@ static int dp_display_process_hpd_high(struct dp_display_private *dp) dp_display_process_mst_hpd_high(dp, false); rc = dp->ctrl->on(dp->ctrl, dp->mst.mst_active, dp->panel->fec_en, false); dp->panel->fec_en, dp->panel->dsc_en, false); if (rc) { dp_display_state_remove(DP_STATE_CONNECTED); goto end; Loading Loading @@ -1665,7 +1665,8 @@ static int dp_display_prepare(struct dp_display *dp_display, void *panel) * So, we execute in shallow mode here to do only minimal * and required things. */ rc = dp->ctrl->on(dp->ctrl, dp->mst.mst_active, dp_panel->fec_en, true); rc = dp->ctrl->on(dp->ctrl, dp->mst.mst_active, dp_panel->fec_en, dp_panel->dsc_en, true); if (rc) goto end; Loading
msm/dp/dp_panel.c +46 −30 Original line number Diff line number Diff line Loading @@ -2019,14 +2019,7 @@ static int dp_panel_read_edid(struct dp_panel *dp_panel, static void dp_panel_decode_dsc_dpcd(struct dp_panel *dp_panel) { s64 fec_overhead_fp = drm_fixp_from_fraction(1, 1); if (!dp_panel->dsc_feature_enable || !dp_panel->fec_feature_enable) { DP_DEBUG("source dsc is not supported\n"); return; } if (dp_panel->dsc_dpcd[0] && dp_panel->fec_dpcd) { if (dp_panel->dsc_dpcd[0]) { dp_panel->sink_dsc_caps.dsc_capable = true; dp_panel->sink_dsc_caps.version = dp_panel->dsc_dpcd[1]; dp_panel->sink_dsc_caps.block_pred_en = Loading @@ -2039,21 +2032,13 @@ static void dp_panel_decode_dsc_dpcd(struct dp_panel *dp_panel) dp_panel->dsc_en = false; } dp_panel->fec_en = dp_panel->dsc_en; dp_panel->widebus_en = dp_panel->dsc_en; /* fec_overhead = 1.00 / 0.97582 */ if (dp_panel->fec_en) fec_overhead_fp = drm_fixp_from_fraction(100000, 97582); dp_panel->fec_overhead_fp = fec_overhead_fp; } static void dp_panel_read_sink_dsc_caps(struct dp_panel *dp_panel) { int rlen; struct dp_panel_private *panel; const int fec_cap = 0x90; int dpcd_rev; if (!dp_panel) { Loading @@ -2061,14 +2046,9 @@ static void dp_panel_read_sink_dsc_caps(struct dp_panel *dp_panel) return; } dp_panel->dsc_en = false; dp_panel->fec_en = false; dpcd_rev = dp_panel->dpcd[DP_DPCD_REV]; panel = container_of(dp_panel, struct dp_panel_private, dp_panel); dp_panel->fec_overhead_fp = 0; if (panel->parser->dsc_feature_enable && dpcd_rev >= 0x14) { rlen = drm_dp_dpcd_read(panel->aux->drm_aux, DP_DSC_SUPPORT, dp_panel->dsc_dpcd, (DP_RECEIVER_DSC_CAP_SIZE + 1)); Loading @@ -2081,15 +2061,36 @@ static void dp_panel_read_sink_dsc_caps(struct dp_panel *dp_panel) DUMP_PREFIX_NONE, 8, 1, dp_panel->dsc_dpcd, rlen, false); rlen = drm_dp_dpcd_read(panel->aux->drm_aux, fec_cap, &dp_panel->fec_dpcd, 1); if (rlen < 1) { DP_ERR("fec dpcd read failed, rlen=%d\n", rlen); dp_panel_decode_dsc_dpcd(dp_panel); } } static void dp_panel_read_sink_fec_caps(struct dp_panel *dp_panel) { int rlen; struct dp_panel_private *panel; s64 fec_overhead_fp = drm_fixp_from_fraction(1, 1); if (!dp_panel) { DP_ERR("invalid input\n"); return; } dp_panel_decode_dsc_dpcd(dp_panel); panel = container_of(dp_panel, struct dp_panel_private, dp_panel); rlen = drm_dp_dpcd_readb(panel->aux->drm_aux, DP_FEC_CAPABILITY, &dp_panel->fec_dpcd); if (rlen < 1) { DP_ERR("fec capability read failed, rlen=%d\n", rlen); return; } dp_panel->fec_en = dp_panel->fec_dpcd & DP_FEC_CAPABLE; if (dp_panel->fec_en) fec_overhead_fp = drm_fixp_from_fraction(100000, 97582); dp_panel->fec_overhead_fp = fec_overhead_fp; return; } static int dp_panel_read_sink_caps(struct dp_panel *dp_panel, Loading Loading @@ -2148,7 +2149,18 @@ static int dp_panel_read_sink_caps(struct dp_panel *dp_panel, dp_panel->dsc_feature_enable = panel->parser->dsc_feature_enable; dp_panel->fec_feature_enable = panel->parser->fec_feature_enable; dp_panel->fec_en = false; dp_panel->dsc_en = false; if (dp_panel->fec_feature_enable) { dp_panel_read_sink_fec_caps(dp_panel); if (dp_panel->dsc_feature_enable && dp_panel->fec_en) dp_panel_read_sink_dsc_caps(dp_panel); } DP_INFO("fec_en=%d, dsc_en=%d, widebus_en=%d\n", dp_panel->fec_en, dp_panel->dsc_en, dp_panel->widebus_en); end: return rc; } Loading @@ -2157,9 +2169,13 @@ static u32 dp_panel_get_supported_bpp(struct dp_panel *dp_panel, u32 mode_edid_bpp, u32 mode_pclk_khz) { struct drm_dp_link *link_info; const u32 max_supported_bpp = 30, min_supported_bpp = 18; const u32 max_supported_bpp = 30; u32 min_supported_bpp = 18; u32 bpp = 0, data_rate_khz = 0; if (dp_panel->dsc_en) min_supported_bpp = 24; bpp = min_t(u32, mode_edid_bpp, max_supported_bpp); link_info = &dp_panel->link_info; Loading