Loading arch/arm64/boot/dts/qcom/sm8150-sde.dtsi +5 −0 Original line number Diff line number Diff line Loading @@ -67,6 +67,9 @@ qcom,sde-mixer-display-pref = "primary", "primary", "none", "none", "none", "none"; qcom,sde-mixer-cwb-pref = "none", "none", "cwb", "cwb", "cwb", "cwb"; qcom,sde-dspp-top-off = <0x1300>; qcom,sde-dspp-top-size = <0x80>; qcom,sde-dspp-off = <0x55000 0x57000 0x59000 0x5b000>; Loading Loading @@ -638,6 +641,8 @@ qcom,max-pclk-frequency-khz = <675000>; qcom,mst-enable; qcom,dsc-feature-enable; qcom,fec-feature-enable; qcom,ctrl-supply-entries { #address-cells = <1>; Loading drivers/gpu/drm/msm/dp/dp_catalog.c +144 −1 Original line number Diff line number Diff line Loading @@ -779,6 +779,7 @@ static void dp_catalog_panel_config_dto(struct dp_catalog_panel *panel, { struct dp_catalog_private *catalog; struct dp_io_data *io_data; u32 dsc_dto; if (!panel) { pr_err("invalid input\n"); Loading @@ -805,7 +806,12 @@ static void dp_catalog_panel_config_dto(struct dp_catalog_panel *panel, return; } dp_write(catalog->exe_mode, io_data, MMSS_DP_DSC_DTO, ack << 1); dsc_dto = dp_read(catalog->exe_mode, io_data, MMSS_DP_DSC_DTO); if (ack) dsc_dto = BIT(1); else dsc_dto &= ~BIT(1); dp_write(catalog->exe_mode, io_data, MMSS_DP_DSC_DTO, dsc_dto); } static void dp_catalog_ctrl_lane_mapping(struct dp_catalog_ctrl *ctrl, Loading Loading @@ -1126,6 +1132,107 @@ static void dp_catalog_panel_tpg_cfg(struct dp_catalog_panel *panel, wmb(); /* ensure Timing generator is turned on */ } static void dp_catalog_panel_dsc_cfg(struct dp_catalog_panel *panel) { struct dp_catalog_private *catalog; struct dp_io_data *io_data; u32 reg, offset; int i; if (!panel) { pr_err("invalid input\n"); return; } if (panel->stream_id >= DP_STREAM_MAX) { pr_err("invalid stream_id:%d\n", panel->stream_id); return; } catalog = dp_catalog_get_priv(panel); if (panel->stream_id == DP_STREAM_0) io_data = catalog->io.dp_p0; else io_data = catalog->io.dp_p1; dp_write(catalog->exe_mode, io_data, MMSS_DP_DSC_DTO_COUNT, panel->dsc.dto_count); reg = dp_read(catalog->exe_mode, io_data, MMSS_DP_DSC_DTO); if (panel->dsc.dto_en) { reg |= BIT(0); reg |= (panel->dsc.dto_n << 8); reg |= (panel->dsc.dto_d << 16); } dp_write(catalog->exe_mode, io_data, MMSS_DP_DSC_DTO, reg); io_data = catalog->io.dp_link; if (panel->stream_id == DP_STREAM_0) offset = 0; else offset = DP1_COMPRESSION_MODE_CTRL - DP_COMPRESSION_MODE_CTRL; dp_write(catalog->exe_mode, io_data, DP_PPS_HB_0_3 + offset, 0x7F1000); dp_write(catalog->exe_mode, io_data, DP_PPS_PB_0_3 + offset, 0xA22300); for (i = 0; i < panel->dsc.parity_word_len; i++) dp_write(catalog->exe_mode, io_data, DP_PPS_PB_4_7 + (i << 2) + offset, panel->dsc.parity_word[i]); for (i = 0; i < panel->dsc.pps_word_len; i++) dp_write(catalog->exe_mode, io_data, DP_PPS_PPS_0_3 + (i << 2) + offset, panel->dsc.pps_word[i]); reg = 0; if (panel->dsc.dsc_en) { reg = BIT(0); reg |= (panel->dsc.eol_byte_num << 3); reg |= (panel->dsc.slice_per_pkt << 5); reg |= (panel->dsc.bytes_per_pkt << 16); reg |= (panel->dsc.be_in_lane << 10); } dp_write(catalog->exe_mode, io_data, DP_COMPRESSION_MODE_CTRL + offset, reg); pr_debug("compression:0x%x for stream:%d\n", reg, panel->stream_id); } static void dp_catalog_panel_pps_flush(struct dp_catalog_panel *panel) { struct dp_catalog_private *catalog; struct dp_io_data *io_data; u32 dp_flush, offset; if (!panel) { pr_err("invalid input\n"); return; } if (panel->stream_id >= DP_STREAM_MAX) { pr_err("invalid stream_id:%d\n", panel->stream_id); return; } catalog = dp_catalog_get_priv(panel); io_data = catalog->io.dp_link; if (panel->stream_id == DP_STREAM_0) offset = 0; else offset = MMSS_DP1_FLUSH - MMSS_DP_FLUSH; dp_flush = dp_read(catalog->exe_mode, io_data, MMSS_DP_FLUSH + offset); dp_flush |= BIT(0); dp_write(catalog->exe_mode, io_data, MMSS_DP_FLUSH + offset, dp_flush); pr_debug("pps flush for stream:%d\n", panel->stream_id); } static void dp_catalog_ctrl_reset(struct dp_catalog_ctrl *ctrl) { u32 sw_reset; Loading Loading @@ -1457,6 +1564,39 @@ static u32 dp_catalog_ctrl_read_phy_pattern(struct dp_catalog_ctrl *ctrl) return dp_read(catalog->exe_mode, io_data, DP_MAINLINK_READY); } static void dp_catalog_ctrl_fec_config(struct dp_catalog_ctrl *ctrl, bool enable) { struct dp_catalog_private *catalog; struct dp_io_data *io_data = NULL; u32 reg; if (!ctrl) { pr_err("invalid input\n"); return; } catalog = dp_catalog_get_priv(ctrl); io_data = catalog->io.dp_link; reg = dp_read(catalog->exe_mode, io_data, DP_MAINLINK_CTRL); /* * fec_en = BIT(12) * fec_seq_mode = BIT(22) * sde_flush = BIT(23) | BIT(24) * fb_boundary_sel = BIT(25) */ if (enable) reg |= BIT(12) | BIT(22) | BIT(23) | BIT(24) | BIT(25); else reg &= ~BIT(12); dp_write(catalog->exe_mode, io_data, DP_MAINLINK_CTRL, reg); /* make sure mainlink configuration is updated with fec sequence */ wmb(); } static int dp_catalog_reg_dump(struct dp_catalog *dp_catalog, char *name, u8 **out_buf, u32 *out_buf_len) { Loading Loading @@ -2276,6 +2416,7 @@ struct dp_catalog *dp_catalog_get(struct device *dev, struct dp_parser *parser) .channel_alloc = dp_catalog_ctrl_channel_alloc, .update_rg = dp_catalog_ctrl_update_rg, .channel_dealloc = dp_catalog_ctrl_channel_dealloc, .fec_config = dp_catalog_ctrl_fec_config, }; struct dp_catalog_audio audio = { .init = dp_catalog_audio_init, Loading @@ -2296,6 +2437,8 @@ struct dp_catalog *dp_catalog_get(struct device *dev, struct dp_parser *parser) .update_transfer_unit = dp_catalog_panel_update_transfer_unit, .config_ctrl = dp_catalog_panel_config_ctrl, .config_dto = dp_catalog_panel_config_dto, .dsc_cfg = dp_catalog_panel_dsc_cfg, .pps_flush = dp_catalog_panel_pps_flush, }; if (!dev || !parser) { Loading drivers/gpu/drm/msm/dp/dp_catalog.h +25 −1 Original line number Diff line number Diff line Loading @@ -128,6 +128,7 @@ struct dp_catalog_ctrl { u32 y_frac_enum); void (*channel_dealloc)(struct dp_catalog_ctrl *ctrl, u32 ch, u32 ch_start_timeslot, u32 tot_ch_cnt); void (*fec_config)(struct dp_catalog_ctrl *ctrl, bool enable); }; #define HEADER_BYTE_2_BIT 0 Loading Loading @@ -169,6 +170,26 @@ struct dp_catalog_audio { void (*safe_to_exit_level)(struct dp_catalog_audio *audio); }; struct dp_dsc_cfg_data { bool dsc_en; char pps[128]; u32 pps_len; u32 pps_word[32]; u32 pps_word_len; u8 parity[32]; u8 parity_len; u32 parity_word[8]; u32 parity_word_len; u32 slice_per_pkt; u32 bytes_per_pkt; u32 eol_byte_num; u32 be_in_lane; u32 dto_en; u32 dto_n; u32 dto_d; u32 dto_count; }; struct dp_catalog_panel { u32 total; u32 sync_start; Loading Loading @@ -198,6 +219,7 @@ struct dp_catalog_panel { enum dp_stream_id stream_id; bool widebus_en; struct dp_dsc_cfg_data dsc; int (*timing_cfg)(struct dp_catalog_panel *panel); void (*config_hdr)(struct dp_catalog_panel *panel, bool en); Loading @@ -209,6 +231,8 @@ struct dp_catalog_panel { void (*update_transfer_unit)(struct dp_catalog_panel *panel); void (*config_ctrl)(struct dp_catalog_panel *panel, u32 cfg); void (*config_dto)(struct dp_catalog_panel *panel, bool ack); void (*dsc_cfg)(struct dp_catalog_panel *panel); void (*pps_flush)(struct dp_catalog_panel *panel); }; struct dp_catalog; Loading Loading @@ -281,7 +305,7 @@ static inline u8 dp_header_get_parity(u32 data) u8 iData = 0; u8 i = 0; u8 parity_byte; u8 num_byte = (data & 0xFF00) > 0 ? 8 : 2; u8 num_byte = (data > 0xFF) ? 8 : 2; for (i = 0; i < num_byte; i++) { iData = (data >> i*4) & 0xF; Loading drivers/gpu/drm/msm/dp/dp_ctrl.c +38 −2 Original line number Diff line number Diff line Loading @@ -76,6 +76,7 @@ struct dp_ctrl_private { bool orientation; bool power_on; bool mst_mode; bool fec_mode; atomic_t aborted; Loading Loading @@ -502,6 +503,7 @@ 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 @@ -513,6 +515,9 @@ 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); ret = dp_ctrl_link_train(ctrl); end: Loading Loading @@ -801,7 +806,8 @@ 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, false); ret = ctrl->dp_ctrl.on(&ctrl->dp_ctrl, ctrl->mst_mode, ctrl->fec_mode, false); if (ret) pr_err("failed to enable DP controller\n"); Loading Loading @@ -991,6 +997,30 @@ static void dp_ctrl_mst_stream_setup(struct dp_ctrl_private *ctrl, lanes, bw_code, x_int, y_frac_enum); } 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) 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); pr_debug("sink fec status:%d\n", fec_sts); dsc_enable = ctrl->fec_mode ? 1 : 0; rlen = drm_dp_dpcd_writeb(ctrl->aux->drm_aux, DP_DSC_ENABLE, dsc_enable); if (rlen < 1) pr_debug("failed to enable sink dsc\n"); } static int dp_ctrl_stream_on(struct dp_ctrl *dp_ctrl, struct dp_panel *panel) { int rc = 0; Loading Loading @@ -1026,6 +1056,8 @@ 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); Loading Loading @@ -1098,7 +1130,8 @@ static void dp_ctrl_stream_off(struct dp_ctrl *dp_ctrl, struct dp_panel *panel) ctrl->stream_count--; } static int dp_ctrl_on(struct dp_ctrl *dp_ctrl, bool mst_mode, bool shallow) static int dp_ctrl_on(struct dp_ctrl *dp_ctrl, bool mst_mode, bool fec_mode, bool shallow) { int rc = 0; struct dp_ctrl_private *ctrl; Loading @@ -1120,6 +1153,7 @@ static int dp_ctrl_on(struct dp_ctrl *dp_ctrl, bool mst_mode, bool shallow) } ctrl->mst_mode = mst_mode; ctrl->fec_mode = fec_mode; rate = ctrl->panel->link_info.rate; if (ctrl->link->sink_request & DP_TEST_LINK_PHY_TEST_PATTERN) { Loading Loading @@ -1165,6 +1199,7 @@ static void dp_ctrl_off(struct dp_ctrl *dp_ctrl) dp_ctrl_disable_link_clock(ctrl); ctrl->mst_mode = false; ctrl->fec_mode = false; ctrl->power_on = false; memset(&ctrl->mst_ch_info, 0, sizeof(ctrl->mst_ch_info)); pr_debug("DP off done\n"); Loading Loading @@ -1242,6 +1277,7 @@ struct dp_ctrl *dp_ctrl_get(struct dp_ctrl_in *in) ctrl->catalog = in->catalog; ctrl->dev = in->dev; ctrl->mst_mode = false; ctrl->fec_mode = false; dp_ctrl = &ctrl->dp_ctrl; Loading drivers/gpu/drm/msm/dp/dp_ctrl.h +2 −1 Original line number Diff line number Diff line Loading @@ -25,7 +25,8 @@ 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 shallow); int (*on)(struct dp_ctrl *dp_ctrl, bool mst_mode, bool fec_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 Loading
arch/arm64/boot/dts/qcom/sm8150-sde.dtsi +5 −0 Original line number Diff line number Diff line Loading @@ -67,6 +67,9 @@ qcom,sde-mixer-display-pref = "primary", "primary", "none", "none", "none", "none"; qcom,sde-mixer-cwb-pref = "none", "none", "cwb", "cwb", "cwb", "cwb"; qcom,sde-dspp-top-off = <0x1300>; qcom,sde-dspp-top-size = <0x80>; qcom,sde-dspp-off = <0x55000 0x57000 0x59000 0x5b000>; Loading Loading @@ -638,6 +641,8 @@ qcom,max-pclk-frequency-khz = <675000>; qcom,mst-enable; qcom,dsc-feature-enable; qcom,fec-feature-enable; qcom,ctrl-supply-entries { #address-cells = <1>; Loading
drivers/gpu/drm/msm/dp/dp_catalog.c +144 −1 Original line number Diff line number Diff line Loading @@ -779,6 +779,7 @@ static void dp_catalog_panel_config_dto(struct dp_catalog_panel *panel, { struct dp_catalog_private *catalog; struct dp_io_data *io_data; u32 dsc_dto; if (!panel) { pr_err("invalid input\n"); Loading @@ -805,7 +806,12 @@ static void dp_catalog_panel_config_dto(struct dp_catalog_panel *panel, return; } dp_write(catalog->exe_mode, io_data, MMSS_DP_DSC_DTO, ack << 1); dsc_dto = dp_read(catalog->exe_mode, io_data, MMSS_DP_DSC_DTO); if (ack) dsc_dto = BIT(1); else dsc_dto &= ~BIT(1); dp_write(catalog->exe_mode, io_data, MMSS_DP_DSC_DTO, dsc_dto); } static void dp_catalog_ctrl_lane_mapping(struct dp_catalog_ctrl *ctrl, Loading Loading @@ -1126,6 +1132,107 @@ static void dp_catalog_panel_tpg_cfg(struct dp_catalog_panel *panel, wmb(); /* ensure Timing generator is turned on */ } static void dp_catalog_panel_dsc_cfg(struct dp_catalog_panel *panel) { struct dp_catalog_private *catalog; struct dp_io_data *io_data; u32 reg, offset; int i; if (!panel) { pr_err("invalid input\n"); return; } if (panel->stream_id >= DP_STREAM_MAX) { pr_err("invalid stream_id:%d\n", panel->stream_id); return; } catalog = dp_catalog_get_priv(panel); if (panel->stream_id == DP_STREAM_0) io_data = catalog->io.dp_p0; else io_data = catalog->io.dp_p1; dp_write(catalog->exe_mode, io_data, MMSS_DP_DSC_DTO_COUNT, panel->dsc.dto_count); reg = dp_read(catalog->exe_mode, io_data, MMSS_DP_DSC_DTO); if (panel->dsc.dto_en) { reg |= BIT(0); reg |= (panel->dsc.dto_n << 8); reg |= (panel->dsc.dto_d << 16); } dp_write(catalog->exe_mode, io_data, MMSS_DP_DSC_DTO, reg); io_data = catalog->io.dp_link; if (panel->stream_id == DP_STREAM_0) offset = 0; else offset = DP1_COMPRESSION_MODE_CTRL - DP_COMPRESSION_MODE_CTRL; dp_write(catalog->exe_mode, io_data, DP_PPS_HB_0_3 + offset, 0x7F1000); dp_write(catalog->exe_mode, io_data, DP_PPS_PB_0_3 + offset, 0xA22300); for (i = 0; i < panel->dsc.parity_word_len; i++) dp_write(catalog->exe_mode, io_data, DP_PPS_PB_4_7 + (i << 2) + offset, panel->dsc.parity_word[i]); for (i = 0; i < panel->dsc.pps_word_len; i++) dp_write(catalog->exe_mode, io_data, DP_PPS_PPS_0_3 + (i << 2) + offset, panel->dsc.pps_word[i]); reg = 0; if (panel->dsc.dsc_en) { reg = BIT(0); reg |= (panel->dsc.eol_byte_num << 3); reg |= (panel->dsc.slice_per_pkt << 5); reg |= (panel->dsc.bytes_per_pkt << 16); reg |= (panel->dsc.be_in_lane << 10); } dp_write(catalog->exe_mode, io_data, DP_COMPRESSION_MODE_CTRL + offset, reg); pr_debug("compression:0x%x for stream:%d\n", reg, panel->stream_id); } static void dp_catalog_panel_pps_flush(struct dp_catalog_panel *panel) { struct dp_catalog_private *catalog; struct dp_io_data *io_data; u32 dp_flush, offset; if (!panel) { pr_err("invalid input\n"); return; } if (panel->stream_id >= DP_STREAM_MAX) { pr_err("invalid stream_id:%d\n", panel->stream_id); return; } catalog = dp_catalog_get_priv(panel); io_data = catalog->io.dp_link; if (panel->stream_id == DP_STREAM_0) offset = 0; else offset = MMSS_DP1_FLUSH - MMSS_DP_FLUSH; dp_flush = dp_read(catalog->exe_mode, io_data, MMSS_DP_FLUSH + offset); dp_flush |= BIT(0); dp_write(catalog->exe_mode, io_data, MMSS_DP_FLUSH + offset, dp_flush); pr_debug("pps flush for stream:%d\n", panel->stream_id); } static void dp_catalog_ctrl_reset(struct dp_catalog_ctrl *ctrl) { u32 sw_reset; Loading Loading @@ -1457,6 +1564,39 @@ static u32 dp_catalog_ctrl_read_phy_pattern(struct dp_catalog_ctrl *ctrl) return dp_read(catalog->exe_mode, io_data, DP_MAINLINK_READY); } static void dp_catalog_ctrl_fec_config(struct dp_catalog_ctrl *ctrl, bool enable) { struct dp_catalog_private *catalog; struct dp_io_data *io_data = NULL; u32 reg; if (!ctrl) { pr_err("invalid input\n"); return; } catalog = dp_catalog_get_priv(ctrl); io_data = catalog->io.dp_link; reg = dp_read(catalog->exe_mode, io_data, DP_MAINLINK_CTRL); /* * fec_en = BIT(12) * fec_seq_mode = BIT(22) * sde_flush = BIT(23) | BIT(24) * fb_boundary_sel = BIT(25) */ if (enable) reg |= BIT(12) | BIT(22) | BIT(23) | BIT(24) | BIT(25); else reg &= ~BIT(12); dp_write(catalog->exe_mode, io_data, DP_MAINLINK_CTRL, reg); /* make sure mainlink configuration is updated with fec sequence */ wmb(); } static int dp_catalog_reg_dump(struct dp_catalog *dp_catalog, char *name, u8 **out_buf, u32 *out_buf_len) { Loading Loading @@ -2276,6 +2416,7 @@ struct dp_catalog *dp_catalog_get(struct device *dev, struct dp_parser *parser) .channel_alloc = dp_catalog_ctrl_channel_alloc, .update_rg = dp_catalog_ctrl_update_rg, .channel_dealloc = dp_catalog_ctrl_channel_dealloc, .fec_config = dp_catalog_ctrl_fec_config, }; struct dp_catalog_audio audio = { .init = dp_catalog_audio_init, Loading @@ -2296,6 +2437,8 @@ struct dp_catalog *dp_catalog_get(struct device *dev, struct dp_parser *parser) .update_transfer_unit = dp_catalog_panel_update_transfer_unit, .config_ctrl = dp_catalog_panel_config_ctrl, .config_dto = dp_catalog_panel_config_dto, .dsc_cfg = dp_catalog_panel_dsc_cfg, .pps_flush = dp_catalog_panel_pps_flush, }; if (!dev || !parser) { Loading
drivers/gpu/drm/msm/dp/dp_catalog.h +25 −1 Original line number Diff line number Diff line Loading @@ -128,6 +128,7 @@ struct dp_catalog_ctrl { u32 y_frac_enum); void (*channel_dealloc)(struct dp_catalog_ctrl *ctrl, u32 ch, u32 ch_start_timeslot, u32 tot_ch_cnt); void (*fec_config)(struct dp_catalog_ctrl *ctrl, bool enable); }; #define HEADER_BYTE_2_BIT 0 Loading Loading @@ -169,6 +170,26 @@ struct dp_catalog_audio { void (*safe_to_exit_level)(struct dp_catalog_audio *audio); }; struct dp_dsc_cfg_data { bool dsc_en; char pps[128]; u32 pps_len; u32 pps_word[32]; u32 pps_word_len; u8 parity[32]; u8 parity_len; u32 parity_word[8]; u32 parity_word_len; u32 slice_per_pkt; u32 bytes_per_pkt; u32 eol_byte_num; u32 be_in_lane; u32 dto_en; u32 dto_n; u32 dto_d; u32 dto_count; }; struct dp_catalog_panel { u32 total; u32 sync_start; Loading Loading @@ -198,6 +219,7 @@ struct dp_catalog_panel { enum dp_stream_id stream_id; bool widebus_en; struct dp_dsc_cfg_data dsc; int (*timing_cfg)(struct dp_catalog_panel *panel); void (*config_hdr)(struct dp_catalog_panel *panel, bool en); Loading @@ -209,6 +231,8 @@ struct dp_catalog_panel { void (*update_transfer_unit)(struct dp_catalog_panel *panel); void (*config_ctrl)(struct dp_catalog_panel *panel, u32 cfg); void (*config_dto)(struct dp_catalog_panel *panel, bool ack); void (*dsc_cfg)(struct dp_catalog_panel *panel); void (*pps_flush)(struct dp_catalog_panel *panel); }; struct dp_catalog; Loading Loading @@ -281,7 +305,7 @@ static inline u8 dp_header_get_parity(u32 data) u8 iData = 0; u8 i = 0; u8 parity_byte; u8 num_byte = (data & 0xFF00) > 0 ? 8 : 2; u8 num_byte = (data > 0xFF) ? 8 : 2; for (i = 0; i < num_byte; i++) { iData = (data >> i*4) & 0xF; Loading
drivers/gpu/drm/msm/dp/dp_ctrl.c +38 −2 Original line number Diff line number Diff line Loading @@ -76,6 +76,7 @@ struct dp_ctrl_private { bool orientation; bool power_on; bool mst_mode; bool fec_mode; atomic_t aborted; Loading Loading @@ -502,6 +503,7 @@ 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 @@ -513,6 +515,9 @@ 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); ret = dp_ctrl_link_train(ctrl); end: Loading Loading @@ -801,7 +806,8 @@ 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, false); ret = ctrl->dp_ctrl.on(&ctrl->dp_ctrl, ctrl->mst_mode, ctrl->fec_mode, false); if (ret) pr_err("failed to enable DP controller\n"); Loading Loading @@ -991,6 +997,30 @@ static void dp_ctrl_mst_stream_setup(struct dp_ctrl_private *ctrl, lanes, bw_code, x_int, y_frac_enum); } 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) 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); pr_debug("sink fec status:%d\n", fec_sts); dsc_enable = ctrl->fec_mode ? 1 : 0; rlen = drm_dp_dpcd_writeb(ctrl->aux->drm_aux, DP_DSC_ENABLE, dsc_enable); if (rlen < 1) pr_debug("failed to enable sink dsc\n"); } static int dp_ctrl_stream_on(struct dp_ctrl *dp_ctrl, struct dp_panel *panel) { int rc = 0; Loading Loading @@ -1026,6 +1056,8 @@ 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); Loading Loading @@ -1098,7 +1130,8 @@ static void dp_ctrl_stream_off(struct dp_ctrl *dp_ctrl, struct dp_panel *panel) ctrl->stream_count--; } static int dp_ctrl_on(struct dp_ctrl *dp_ctrl, bool mst_mode, bool shallow) static int dp_ctrl_on(struct dp_ctrl *dp_ctrl, bool mst_mode, bool fec_mode, bool shallow) { int rc = 0; struct dp_ctrl_private *ctrl; Loading @@ -1120,6 +1153,7 @@ static int dp_ctrl_on(struct dp_ctrl *dp_ctrl, bool mst_mode, bool shallow) } ctrl->mst_mode = mst_mode; ctrl->fec_mode = fec_mode; rate = ctrl->panel->link_info.rate; if (ctrl->link->sink_request & DP_TEST_LINK_PHY_TEST_PATTERN) { Loading Loading @@ -1165,6 +1199,7 @@ static void dp_ctrl_off(struct dp_ctrl *dp_ctrl) dp_ctrl_disable_link_clock(ctrl); ctrl->mst_mode = false; ctrl->fec_mode = false; ctrl->power_on = false; memset(&ctrl->mst_ch_info, 0, sizeof(ctrl->mst_ch_info)); pr_debug("DP off done\n"); Loading Loading @@ -1242,6 +1277,7 @@ struct dp_ctrl *dp_ctrl_get(struct dp_ctrl_in *in) ctrl->catalog = in->catalog; ctrl->dev = in->dev; ctrl->mst_mode = false; ctrl->fec_mode = false; dp_ctrl = &ctrl->dp_ctrl; Loading
drivers/gpu/drm/msm/dp/dp_ctrl.h +2 −1 Original line number Diff line number Diff line Loading @@ -25,7 +25,8 @@ 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 shallow); int (*on)(struct dp_ctrl *dp_ctrl, bool mst_mode, bool fec_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