Loading msm/sde/sde_encoder.c +18 −0 Original line number Diff line number Diff line Loading @@ -4044,6 +4044,24 @@ void sde_encoder_helper_get_pp_line_count(struct drm_encoder *drm_enc, } } void sde_encoder_helper_get_transfer_time(struct drm_encoder *drm_enc, u32 *transfer_time_us) { struct sde_encoder_virt *sde_enc; struct msm_mode_info *info; if (!drm_enc || !transfer_time_us) { SDE_ERROR("bad arg: encoder:%d transfer_time:%d\n", !drm_enc, !transfer_time_us); return; } sde_enc = to_sde_encoder_virt(drm_enc); info = &sde_enc->mode_info; *transfer_time_us = info->mdp_transfer_time_us; } int sde_encoder_helper_reset_mixers(struct sde_encoder_phys *phys_enc, struct drm_framebuffer *fb) { Loading msm/sde/sde_encoder_phys.h +8 −0 Original line number Diff line number Diff line Loading @@ -539,6 +539,14 @@ void sde_encoder_phys_setup_cdm(struct sde_encoder_phys *phys_enc, void sde_encoder_helper_get_pp_line_count(struct drm_encoder *drm_enc, struct sde_hw_pp_vsync_info *info); /** * sde_encoder_helper_get_transfer_time - get the mdp transfer time in usecs * @drm_enc: Pointer to drm encoder structure * @transfer_time_us: Pointer to store the output value */ void sde_encoder_helper_get_transfer_time(struct drm_encoder *drm_enc, u32 *transfer_time_us); /** * sde_encoder_helper_trigger_flush - control flush helper function * This helper function may be optionally specified by physical Loading msm/sde/sde_encoder_phys_cmd.c +19 −21 Original line number Diff line number Diff line Loading @@ -926,17 +926,15 @@ void sde_encoder_phys_cmd_irq_control(struct sde_encoder_phys *phys_enc, } } static int _get_tearcheck_threshold(struct sde_encoder_phys *phys_enc, u32 *extra_frame_trigger_time) static int _get_tearcheck_threshold(struct sde_encoder_phys *phys_enc) { struct drm_connector *conn = phys_enc->connector; u32 qsync_mode; struct drm_display_mode *mode; u32 threshold_lines = 0; u32 threshold_lines = DEFAULT_TEARCHECK_SYNC_THRESH_START; struct sde_encoder_phys_cmd *cmd_enc = to_sde_encoder_phys_cmd(phys_enc); *extra_frame_trigger_time = 0; if (!conn || !conn->state) return 0; Loading @@ -950,8 +948,9 @@ static int _get_tearcheck_threshold(struct sde_encoder_phys *phys_enc, u32 slow_time_ns; u32 default_time_ns; u32 extra_time_ns; u32 total_extra_lines; u32 default_line_time_ns; u32 idle_time_ns = 0; u32 transfer_time_us = 0; if (phys_enc->parent_ops.get_qsync_fps) phys_enc->parent_ops.get_qsync_fps( Loading @@ -974,27 +973,29 @@ static int _get_tearcheck_threshold(struct sde_encoder_phys *phys_enc, /* Calculate the number of extra lines*/ slow_time_ns = (1 * 1000000000) / qsync_min_fps; default_time_ns = (1 * 1000000000) / default_fps; extra_time_ns = slow_time_ns - default_time_ns; sde_encoder_helper_get_transfer_time(phys_enc->parent, &transfer_time_us); if (transfer_time_us) idle_time_ns = default_time_ns - (1000 * transfer_time_us); extra_time_ns = slow_time_ns - default_time_ns + idle_time_ns; default_line_time_ns = (1 * 1000000000) / (default_fps * yres); total_extra_lines = extra_time_ns / default_line_time_ns; threshold_lines += total_extra_lines; threshold_lines = extra_time_ns / default_line_time_ns; SDE_DEBUG_CMDENC(cmd_enc, "slow:%d default:%d extra:%d(ns)\n", slow_time_ns, default_time_ns, extra_time_ns); SDE_DEBUG_CMDENC(cmd_enc, "extra_lines:%d threshold:%d\n", total_extra_lines, threshold_lines); SDE_DEBUG_CMDENC(cmd_enc, "xfer:%d(us) idle:%d(ns) lines:%d\n", transfer_time_us, idle_time_ns, threshold_lines); SDE_DEBUG_CMDENC(cmd_enc, "min_fps:%d fps:%d yres:%d\n", qsync_min_fps, default_fps, yres); SDE_EVT32(qsync_mode, qsync_min_fps, extra_time_ns, default_fps, yres, threshold_lines); *extra_frame_trigger_time = extra_time_ns; yres, transfer_time_us, threshold_lines); } exit: threshold_lines += DEFAULT_TEARCHECK_SYNC_THRESH_START; return threshold_lines; } Loading @@ -1007,7 +1008,7 @@ static void sde_encoder_phys_cmd_tearcheck_config( struct sde_hw_tear_check tc_cfg = { 0 }; struct drm_display_mode *mode; bool tc_enable = true; u32 vsync_hz, extra_frame_trigger_time; u32 vsync_hz; struct msm_drm_private *priv; struct sde_kms *sde_kms; Loading Loading @@ -1071,8 +1072,7 @@ static void sde_encoder_phys_cmd_tearcheck_config( */ tc_cfg.sync_cfg_height = 0xFFF0; tc_cfg.vsync_init_val = mode->vdisplay; tc_cfg.sync_threshold_start = _get_tearcheck_threshold(phys_enc, &extra_frame_trigger_time); tc_cfg.sync_threshold_start = _get_tearcheck_threshold(phys_enc); tc_cfg.sync_threshold_continue = DEFAULT_TEARCHECK_SYNC_THRESH_CONTINUE; tc_cfg.start_pos = mode->vdisplay; tc_cfg.rd_ptr_irq = mode->vdisplay + 1; Loading Loading @@ -1388,7 +1388,6 @@ static int sde_encoder_phys_cmd_prepare_for_kickoff( struct sde_encoder_phys_cmd *cmd_enc = to_sde_encoder_phys_cmd(phys_enc); int ret = 0; u32 extra_frame_trigger_time; bool recovery_events; if (!phys_enc || !phys_enc->hw_pp) { Loading Loading @@ -1432,9 +1431,8 @@ static int sde_encoder_phys_cmd_prepare_for_kickoff( } if (sde_connector_is_qsync_updated(phys_enc->connector)) { tc_cfg.sync_threshold_start = _get_tearcheck_threshold(phys_enc, &extra_frame_trigger_time); tc_cfg.sync_threshold_start = _get_tearcheck_threshold( phys_enc); if (phys_enc->has_intf_te && phys_enc->hw_intf->ops.update_tearcheck) phys_enc->hw_intf->ops.update_tearcheck( Loading Loading
msm/sde/sde_encoder.c +18 −0 Original line number Diff line number Diff line Loading @@ -4044,6 +4044,24 @@ void sde_encoder_helper_get_pp_line_count(struct drm_encoder *drm_enc, } } void sde_encoder_helper_get_transfer_time(struct drm_encoder *drm_enc, u32 *transfer_time_us) { struct sde_encoder_virt *sde_enc; struct msm_mode_info *info; if (!drm_enc || !transfer_time_us) { SDE_ERROR("bad arg: encoder:%d transfer_time:%d\n", !drm_enc, !transfer_time_us); return; } sde_enc = to_sde_encoder_virt(drm_enc); info = &sde_enc->mode_info; *transfer_time_us = info->mdp_transfer_time_us; } int sde_encoder_helper_reset_mixers(struct sde_encoder_phys *phys_enc, struct drm_framebuffer *fb) { Loading
msm/sde/sde_encoder_phys.h +8 −0 Original line number Diff line number Diff line Loading @@ -539,6 +539,14 @@ void sde_encoder_phys_setup_cdm(struct sde_encoder_phys *phys_enc, void sde_encoder_helper_get_pp_line_count(struct drm_encoder *drm_enc, struct sde_hw_pp_vsync_info *info); /** * sde_encoder_helper_get_transfer_time - get the mdp transfer time in usecs * @drm_enc: Pointer to drm encoder structure * @transfer_time_us: Pointer to store the output value */ void sde_encoder_helper_get_transfer_time(struct drm_encoder *drm_enc, u32 *transfer_time_us); /** * sde_encoder_helper_trigger_flush - control flush helper function * This helper function may be optionally specified by physical Loading
msm/sde/sde_encoder_phys_cmd.c +19 −21 Original line number Diff line number Diff line Loading @@ -926,17 +926,15 @@ void sde_encoder_phys_cmd_irq_control(struct sde_encoder_phys *phys_enc, } } static int _get_tearcheck_threshold(struct sde_encoder_phys *phys_enc, u32 *extra_frame_trigger_time) static int _get_tearcheck_threshold(struct sde_encoder_phys *phys_enc) { struct drm_connector *conn = phys_enc->connector; u32 qsync_mode; struct drm_display_mode *mode; u32 threshold_lines = 0; u32 threshold_lines = DEFAULT_TEARCHECK_SYNC_THRESH_START; struct sde_encoder_phys_cmd *cmd_enc = to_sde_encoder_phys_cmd(phys_enc); *extra_frame_trigger_time = 0; if (!conn || !conn->state) return 0; Loading @@ -950,8 +948,9 @@ static int _get_tearcheck_threshold(struct sde_encoder_phys *phys_enc, u32 slow_time_ns; u32 default_time_ns; u32 extra_time_ns; u32 total_extra_lines; u32 default_line_time_ns; u32 idle_time_ns = 0; u32 transfer_time_us = 0; if (phys_enc->parent_ops.get_qsync_fps) phys_enc->parent_ops.get_qsync_fps( Loading @@ -974,27 +973,29 @@ static int _get_tearcheck_threshold(struct sde_encoder_phys *phys_enc, /* Calculate the number of extra lines*/ slow_time_ns = (1 * 1000000000) / qsync_min_fps; default_time_ns = (1 * 1000000000) / default_fps; extra_time_ns = slow_time_ns - default_time_ns; sde_encoder_helper_get_transfer_time(phys_enc->parent, &transfer_time_us); if (transfer_time_us) idle_time_ns = default_time_ns - (1000 * transfer_time_us); extra_time_ns = slow_time_ns - default_time_ns + idle_time_ns; default_line_time_ns = (1 * 1000000000) / (default_fps * yres); total_extra_lines = extra_time_ns / default_line_time_ns; threshold_lines += total_extra_lines; threshold_lines = extra_time_ns / default_line_time_ns; SDE_DEBUG_CMDENC(cmd_enc, "slow:%d default:%d extra:%d(ns)\n", slow_time_ns, default_time_ns, extra_time_ns); SDE_DEBUG_CMDENC(cmd_enc, "extra_lines:%d threshold:%d\n", total_extra_lines, threshold_lines); SDE_DEBUG_CMDENC(cmd_enc, "xfer:%d(us) idle:%d(ns) lines:%d\n", transfer_time_us, idle_time_ns, threshold_lines); SDE_DEBUG_CMDENC(cmd_enc, "min_fps:%d fps:%d yres:%d\n", qsync_min_fps, default_fps, yres); SDE_EVT32(qsync_mode, qsync_min_fps, extra_time_ns, default_fps, yres, threshold_lines); *extra_frame_trigger_time = extra_time_ns; yres, transfer_time_us, threshold_lines); } exit: threshold_lines += DEFAULT_TEARCHECK_SYNC_THRESH_START; return threshold_lines; } Loading @@ -1007,7 +1008,7 @@ static void sde_encoder_phys_cmd_tearcheck_config( struct sde_hw_tear_check tc_cfg = { 0 }; struct drm_display_mode *mode; bool tc_enable = true; u32 vsync_hz, extra_frame_trigger_time; u32 vsync_hz; struct msm_drm_private *priv; struct sde_kms *sde_kms; Loading Loading @@ -1071,8 +1072,7 @@ static void sde_encoder_phys_cmd_tearcheck_config( */ tc_cfg.sync_cfg_height = 0xFFF0; tc_cfg.vsync_init_val = mode->vdisplay; tc_cfg.sync_threshold_start = _get_tearcheck_threshold(phys_enc, &extra_frame_trigger_time); tc_cfg.sync_threshold_start = _get_tearcheck_threshold(phys_enc); tc_cfg.sync_threshold_continue = DEFAULT_TEARCHECK_SYNC_THRESH_CONTINUE; tc_cfg.start_pos = mode->vdisplay; tc_cfg.rd_ptr_irq = mode->vdisplay + 1; Loading Loading @@ -1388,7 +1388,6 @@ static int sde_encoder_phys_cmd_prepare_for_kickoff( struct sde_encoder_phys_cmd *cmd_enc = to_sde_encoder_phys_cmd(phys_enc); int ret = 0; u32 extra_frame_trigger_time; bool recovery_events; if (!phys_enc || !phys_enc->hw_pp) { Loading Loading @@ -1432,9 +1431,8 @@ static int sde_encoder_phys_cmd_prepare_for_kickoff( } if (sde_connector_is_qsync_updated(phys_enc->connector)) { tc_cfg.sync_threshold_start = _get_tearcheck_threshold(phys_enc, &extra_frame_trigger_time); tc_cfg.sync_threshold_start = _get_tearcheck_threshold( phys_enc); if (phys_enc->has_intf_te && phys_enc->hw_intf->ops.update_tearcheck) phys_enc->hw_intf->ops.update_tearcheck( Loading