Loading drivers/gpu/drm/msm/sde/sde_crtc.c +26 −1 Original line number Diff line number Diff line Loading @@ -757,6 +757,25 @@ static bool sde_crtc_mode_fixup(struct drm_crtc *crtc, return true; } static int _sde_crtc_get_ctlstart_timeout(struct drm_crtc *crtc) { struct drm_encoder *encoder; int rc = 0; if (!crtc || !crtc->dev) return 0; list_for_each_entry(encoder, &crtc->dev->mode_config.encoder_list, head) { if (encoder->crtc != crtc) continue; if (sde_encoder_get_intf_mode(encoder) == INTF_MODE_CMD) rc += sde_encoder_get_ctlstart_timeout_state(encoder); } return rc; } static void _sde_crtc_setup_blend_cfg(struct sde_crtc_mixer *mixer, struct sde_plane_state *pstate, struct sde_format *format) Loading Loading @@ -3184,7 +3203,13 @@ static void sde_crtc_atomic_begin(struct drm_crtc *crtc, if (unlikely(!sde_crtc->num_mixers)) return; if (_sde_crtc_get_ctlstart_timeout(crtc)) { _sde_crtc_blend_setup(crtc, old_state, false); SDE_ERROR("border fill only commit after ctlstart timeout\n"); } else { _sde_crtc_blend_setup(crtc, old_state, true); } _sde_crtc_dest_scaler_setup(crtc); /* cancel the idle notify delayed work */ Loading drivers/gpu/drm/msm/sde/sde_encoder.c +18 −0 Original line number Diff line number Diff line Loading @@ -3229,6 +3229,24 @@ int sde_encoder_idle_request(struct drm_encoder *drm_enc) return 0; } int sde_encoder_get_ctlstart_timeout_state(struct drm_encoder *drm_enc) { struct sde_encoder_virt *sde_enc = NULL; int i, count = 0; if (!drm_enc) return 0; sde_enc = to_sde_encoder_virt(drm_enc); for (i = 0; i < sde_enc->num_phys_encs; i++) { count += atomic_read(&sde_enc->phys_encs[i]->ctlstart_timeout); atomic_set(&sde_enc->phys_encs[i]->ctlstart_timeout, 0); } return count; } /** * _sde_encoder_trigger_flush - trigger flush for a physical encoder * drm_enc: Pointer to drm encoder structure Loading drivers/gpu/drm/msm/sde/sde_encoder.h +7 −0 Original line number Diff line number Diff line Loading @@ -266,4 +266,11 @@ int sde_encoder_in_clone_mode(struct drm_encoder *enc); */ void sde_encoder_control_idle_pc(struct drm_encoder *enc, bool enable); /** * sde_encoder_get_ctlstart_timeout_state - checks if ctl start timeout happened * @drm_enc: Pointer to drm encoder structure * @Return: non zero value if ctl start timeout occurred */ int sde_encoder_get_ctlstart_timeout_state(struct drm_encoder *enc); #endif /* __SDE_ENCODER_H__ */ drivers/gpu/drm/msm/sde/sde_encoder_phys.h +2 −0 Original line number Diff line number Diff line Loading @@ -267,6 +267,7 @@ struct sde_encoder_irq { * @pending_retire_fence_cnt: Atomic counter tracking the pending retire * fences that have to be signalled. * @pending_kickoff_wq: Wait queue for blocking until kickoff completes * @ctlstart_timeout: Indicates if ctl start timeout occurred * @irq: IRQ tracking structures * @cont_splash_single_flush Variable to check if single flush is enabled. * @cont_splash_settings Variable to store continuous splash settings. Loading Loading @@ -301,6 +302,7 @@ struct sde_encoder_phys { atomic_t pending_kickoff_cnt; atomic_t pending_retire_fence_cnt; wait_queue_head_t pending_kickoff_wq; atomic_t ctlstart_timeout; struct sde_encoder_irq irq[INTR_IDX_MAX]; u32 cont_splash_single_flush; bool cont_splash_settings; Loading drivers/gpu/drm/msm/sde/sde_encoder_phys_cmd.c +8 −1 Original line number Diff line number Diff line /* * Copyright (c) 2015-2018 The Linux Foundation. All rights reserved. * Copyright (c) 2015-2019 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -193,6 +193,7 @@ static void sde_encoder_phys_cmd_pp_tx_done_irq(void *arg, int irq_idx) phys_enc, SDE_ENCODER_FRAME_EVENT_SIGNAL_RETIRE_FENCE); atomic_add_unless(&phys_enc->pending_ctlstart_cnt, -1, 0); atomic_set(&phys_enc->ctlstart_timeout, 0); } /* notify all synchronous clients first, then asynchronous clients */ Loading Loading @@ -292,6 +293,7 @@ static void sde_encoder_phys_cmd_ctl_start_irq(void *arg, int irq_idx) ctl = phys_enc->hw_ctl; atomic_add_unless(&phys_enc->pending_ctlstart_cnt, -1, 0); atomic_set(&phys_enc->ctlstart_timeout, 0); time_diff_us = ktime_us_delta(ktime_get(), cmd_enc->rd_ptr_timestamp); Loading Loading @@ -1054,6 +1056,7 @@ static void sde_encoder_phys_cmd_disable(struct sde_encoder_phys *phys_enc) SDE_ERROR("invalid encoder\n"); return; } atomic_set(&phys_enc->ctlstart_timeout, 0); SDE_DEBUG_CMDENC(cmd_enc, "pp %d state %d\n", phys_enc->hw_pp->idx - PINGPONG_0, phys_enc->enable_state); Loading Loading @@ -1176,6 +1179,9 @@ static int _sde_encoder_phys_cmd_wait_for_ctl_start( "ctl start interrupt wait failed\n"); else ret = 0; if (sde_encoder_phys_cmd_is_master(phys_enc)) atomic_inc_return(&phys_enc->ctlstart_timeout); } return ret; Loading Loading @@ -1476,6 +1482,7 @@ struct sde_encoder_phys *sde_encoder_phys_cmd_init( atomic_set(&phys_enc->pending_retire_fence_cnt, 0); atomic_set(&cmd_enc->pending_rd_ptr_cnt, 0); atomic_set(&cmd_enc->pending_vblank_cnt, 0); atomic_set(&phys_enc->ctlstart_timeout, 0); init_waitqueue_head(&phys_enc->pending_kickoff_wq); init_waitqueue_head(&cmd_enc->pending_vblank_wq); atomic_set(&cmd_enc->autorefresh.kickoff_cnt, 0); Loading Loading
drivers/gpu/drm/msm/sde/sde_crtc.c +26 −1 Original line number Diff line number Diff line Loading @@ -757,6 +757,25 @@ static bool sde_crtc_mode_fixup(struct drm_crtc *crtc, return true; } static int _sde_crtc_get_ctlstart_timeout(struct drm_crtc *crtc) { struct drm_encoder *encoder; int rc = 0; if (!crtc || !crtc->dev) return 0; list_for_each_entry(encoder, &crtc->dev->mode_config.encoder_list, head) { if (encoder->crtc != crtc) continue; if (sde_encoder_get_intf_mode(encoder) == INTF_MODE_CMD) rc += sde_encoder_get_ctlstart_timeout_state(encoder); } return rc; } static void _sde_crtc_setup_blend_cfg(struct sde_crtc_mixer *mixer, struct sde_plane_state *pstate, struct sde_format *format) Loading Loading @@ -3184,7 +3203,13 @@ static void sde_crtc_atomic_begin(struct drm_crtc *crtc, if (unlikely(!sde_crtc->num_mixers)) return; if (_sde_crtc_get_ctlstart_timeout(crtc)) { _sde_crtc_blend_setup(crtc, old_state, false); SDE_ERROR("border fill only commit after ctlstart timeout\n"); } else { _sde_crtc_blend_setup(crtc, old_state, true); } _sde_crtc_dest_scaler_setup(crtc); /* cancel the idle notify delayed work */ Loading
drivers/gpu/drm/msm/sde/sde_encoder.c +18 −0 Original line number Diff line number Diff line Loading @@ -3229,6 +3229,24 @@ int sde_encoder_idle_request(struct drm_encoder *drm_enc) return 0; } int sde_encoder_get_ctlstart_timeout_state(struct drm_encoder *drm_enc) { struct sde_encoder_virt *sde_enc = NULL; int i, count = 0; if (!drm_enc) return 0; sde_enc = to_sde_encoder_virt(drm_enc); for (i = 0; i < sde_enc->num_phys_encs; i++) { count += atomic_read(&sde_enc->phys_encs[i]->ctlstart_timeout); atomic_set(&sde_enc->phys_encs[i]->ctlstart_timeout, 0); } return count; } /** * _sde_encoder_trigger_flush - trigger flush for a physical encoder * drm_enc: Pointer to drm encoder structure Loading
drivers/gpu/drm/msm/sde/sde_encoder.h +7 −0 Original line number Diff line number Diff line Loading @@ -266,4 +266,11 @@ int sde_encoder_in_clone_mode(struct drm_encoder *enc); */ void sde_encoder_control_idle_pc(struct drm_encoder *enc, bool enable); /** * sde_encoder_get_ctlstart_timeout_state - checks if ctl start timeout happened * @drm_enc: Pointer to drm encoder structure * @Return: non zero value if ctl start timeout occurred */ int sde_encoder_get_ctlstart_timeout_state(struct drm_encoder *enc); #endif /* __SDE_ENCODER_H__ */
drivers/gpu/drm/msm/sde/sde_encoder_phys.h +2 −0 Original line number Diff line number Diff line Loading @@ -267,6 +267,7 @@ struct sde_encoder_irq { * @pending_retire_fence_cnt: Atomic counter tracking the pending retire * fences that have to be signalled. * @pending_kickoff_wq: Wait queue for blocking until kickoff completes * @ctlstart_timeout: Indicates if ctl start timeout occurred * @irq: IRQ tracking structures * @cont_splash_single_flush Variable to check if single flush is enabled. * @cont_splash_settings Variable to store continuous splash settings. Loading Loading @@ -301,6 +302,7 @@ struct sde_encoder_phys { atomic_t pending_kickoff_cnt; atomic_t pending_retire_fence_cnt; wait_queue_head_t pending_kickoff_wq; atomic_t ctlstart_timeout; struct sde_encoder_irq irq[INTR_IDX_MAX]; u32 cont_splash_single_flush; bool cont_splash_settings; Loading
drivers/gpu/drm/msm/sde/sde_encoder_phys_cmd.c +8 −1 Original line number Diff line number Diff line /* * Copyright (c) 2015-2018 The Linux Foundation. All rights reserved. * Copyright (c) 2015-2019 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -193,6 +193,7 @@ static void sde_encoder_phys_cmd_pp_tx_done_irq(void *arg, int irq_idx) phys_enc, SDE_ENCODER_FRAME_EVENT_SIGNAL_RETIRE_FENCE); atomic_add_unless(&phys_enc->pending_ctlstart_cnt, -1, 0); atomic_set(&phys_enc->ctlstart_timeout, 0); } /* notify all synchronous clients first, then asynchronous clients */ Loading Loading @@ -292,6 +293,7 @@ static void sde_encoder_phys_cmd_ctl_start_irq(void *arg, int irq_idx) ctl = phys_enc->hw_ctl; atomic_add_unless(&phys_enc->pending_ctlstart_cnt, -1, 0); atomic_set(&phys_enc->ctlstart_timeout, 0); time_diff_us = ktime_us_delta(ktime_get(), cmd_enc->rd_ptr_timestamp); Loading Loading @@ -1054,6 +1056,7 @@ static void sde_encoder_phys_cmd_disable(struct sde_encoder_phys *phys_enc) SDE_ERROR("invalid encoder\n"); return; } atomic_set(&phys_enc->ctlstart_timeout, 0); SDE_DEBUG_CMDENC(cmd_enc, "pp %d state %d\n", phys_enc->hw_pp->idx - PINGPONG_0, phys_enc->enable_state); Loading Loading @@ -1176,6 +1179,9 @@ static int _sde_encoder_phys_cmd_wait_for_ctl_start( "ctl start interrupt wait failed\n"); else ret = 0; if (sde_encoder_phys_cmd_is_master(phys_enc)) atomic_inc_return(&phys_enc->ctlstart_timeout); } return ret; Loading Loading @@ -1476,6 +1482,7 @@ struct sde_encoder_phys *sde_encoder_phys_cmd_init( atomic_set(&phys_enc->pending_retire_fence_cnt, 0); atomic_set(&cmd_enc->pending_rd_ptr_cnt, 0); atomic_set(&cmd_enc->pending_vblank_cnt, 0); atomic_set(&phys_enc->ctlstart_timeout, 0); init_waitqueue_head(&phys_enc->pending_kickoff_wq); init_waitqueue_head(&cmd_enc->pending_vblank_wq); atomic_set(&cmd_enc->autorefresh.kickoff_cnt, 0); Loading