Loading drivers/gpu/drm/msm/sde/sde_encoder.c +64 −1 Original line number Diff line number Diff line Loading @@ -44,6 +44,13 @@ /* timeout in frames waiting for frame done */ #define SDE_ENCODER_FRAME_DONE_TIMEOUT 60 /* timeout in msecs */ #define SDE_ENCODER_UNDERRUN_TIMEOUT 200 /* underrun count threshold value */ #define SDE_ENCODER_UNDERRUN_CNT_MAX 10 /* 3 vsync time period in msec, report underrun */ #define SDE_ENCODER_UNDERRUN_DELTA 50 #define MISR_BUFF_SIZE 256 /* Loading Loading @@ -155,6 +162,11 @@ static struct sde_csc_cfg sde_csc_10bit_convert[SDE_MAX_CSC] = { * @crtc_frame_event: callback event * @frame_done_timeout: frame done timeout in Hz * @frame_done_timer: watchdog timer for frame done event * @last_underrun_ts: variable to hold the last occurred underrun * timestamp * @underrun_cnt_dwork: underrun counter for delayed work * @dwork: delayed work for deferring the reporting * of underrun error */ struct sde_encoder_virt { struct drm_encoder base; Loading @@ -181,6 +193,9 @@ struct sde_encoder_virt { u32 crtc_frame_event; atomic_t frame_done_timeout; struct timer_list frame_done_timer; atomic_t last_underrun_ts; atomic_t underrun_cnt_dwork; struct delayed_work dwork; }; #define to_sde_encoder_virt(x) container_of(x, struct sde_encoder_virt, base) Loading Loading @@ -597,14 +612,28 @@ static void sde_encoder_vblank_callback(struct drm_encoder *drm_enc, static void sde_encoder_underrun_callback(struct drm_encoder *drm_enc, struct sde_encoder_phys *phy_enc) { struct sde_encoder_virt *sde_enc = NULL; if (!phy_enc) return; sde_enc = to_sde_encoder_virt(drm_enc); SDE_ATRACE_BEGIN("encoder_underrun_callback"); atomic_inc(&phy_enc->underrun_cnt); SDE_EVT32(DRMID(drm_enc), atomic_read(&phy_enc->underrun_cnt)); sde_recovery_set_events(SDE_UNDERRUN); /* schedule delayed work if it has not scheduled or executed earlier */ if ((!atomic_read(&sde_enc->last_underrun_ts)) && (!atomic_read(&sde_enc->underrun_cnt_dwork))) { schedule_delayed_work(&sde_enc->dwork, msecs_to_jiffies(SDE_ENCODER_UNDERRUN_TIMEOUT)); } /* take snapshot of current underrun and increment the count */ atomic_set(&sde_enc->last_underrun_ts, jiffies); atomic_inc(&sde_enc->underrun_cnt_dwork); trace_sde_encoder_underrun(DRMID(drm_enc), atomic_read(&phy_enc->underrun_cnt)); SDE_DBG_CTRL("stop_ftrace"); Loading Loading @@ -1391,6 +1420,37 @@ static void sde_encoder_frame_done_timeout(unsigned long data) SDE_ENCODER_FRAME_EVENT_ERROR); } static void sde_encoder_underrun_work_func(struct work_struct *work) { struct sde_encoder_virt *sde_enc = container_of(work, struct sde_encoder_virt, dwork.work); unsigned long delta, time; if (!sde_enc) { SDE_ERROR("invalid parameters\n"); return; } delta = jiffies - atomic_read(&sde_enc->last_underrun_ts); time = jiffies_to_msecs(delta); /* * report underrun error when it exceeds the threshold count * and the occurrence of last underrun error is less than 3 * vsync period. */ if (atomic_read(&sde_enc->underrun_cnt_dwork) > SDE_ENCODER_UNDERRUN_CNT_MAX && time < SDE_ENCODER_UNDERRUN_DELTA) { sde_recovery_set_events(SDE_UNDERRUN); } /* reset underrun last timestamp and counter */ atomic_set(&sde_enc->last_underrun_ts, 0); atomic_set(&sde_enc->underrun_cnt_dwork, 0); } struct drm_encoder *sde_encoder_init( struct drm_device *dev, struct msm_display_info *disp_info) Loading Loading @@ -1421,8 +1481,11 @@ struct drm_encoder *sde_encoder_init( drm_encoder_helper_add(drm_enc, &sde_encoder_helper_funcs); atomic_set(&sde_enc->frame_done_timeout, 0); atomic_set(&sde_enc->last_underrun_ts, 0); atomic_set(&sde_enc->underrun_cnt_dwork, 0); setup_timer(&sde_enc->frame_done_timer, sde_encoder_frame_done_timeout, (unsigned long) sde_enc); INIT_DELAYED_WORK(&sde_enc->dwork, sde_encoder_underrun_work_func); _sde_encoder_init_debugfs(drm_enc, sde_enc, sde_kms); Loading Loading
drivers/gpu/drm/msm/sde/sde_encoder.c +64 −1 Original line number Diff line number Diff line Loading @@ -44,6 +44,13 @@ /* timeout in frames waiting for frame done */ #define SDE_ENCODER_FRAME_DONE_TIMEOUT 60 /* timeout in msecs */ #define SDE_ENCODER_UNDERRUN_TIMEOUT 200 /* underrun count threshold value */ #define SDE_ENCODER_UNDERRUN_CNT_MAX 10 /* 3 vsync time period in msec, report underrun */ #define SDE_ENCODER_UNDERRUN_DELTA 50 #define MISR_BUFF_SIZE 256 /* Loading Loading @@ -155,6 +162,11 @@ static struct sde_csc_cfg sde_csc_10bit_convert[SDE_MAX_CSC] = { * @crtc_frame_event: callback event * @frame_done_timeout: frame done timeout in Hz * @frame_done_timer: watchdog timer for frame done event * @last_underrun_ts: variable to hold the last occurred underrun * timestamp * @underrun_cnt_dwork: underrun counter for delayed work * @dwork: delayed work for deferring the reporting * of underrun error */ struct sde_encoder_virt { struct drm_encoder base; Loading @@ -181,6 +193,9 @@ struct sde_encoder_virt { u32 crtc_frame_event; atomic_t frame_done_timeout; struct timer_list frame_done_timer; atomic_t last_underrun_ts; atomic_t underrun_cnt_dwork; struct delayed_work dwork; }; #define to_sde_encoder_virt(x) container_of(x, struct sde_encoder_virt, base) Loading Loading @@ -597,14 +612,28 @@ static void sde_encoder_vblank_callback(struct drm_encoder *drm_enc, static void sde_encoder_underrun_callback(struct drm_encoder *drm_enc, struct sde_encoder_phys *phy_enc) { struct sde_encoder_virt *sde_enc = NULL; if (!phy_enc) return; sde_enc = to_sde_encoder_virt(drm_enc); SDE_ATRACE_BEGIN("encoder_underrun_callback"); atomic_inc(&phy_enc->underrun_cnt); SDE_EVT32(DRMID(drm_enc), atomic_read(&phy_enc->underrun_cnt)); sde_recovery_set_events(SDE_UNDERRUN); /* schedule delayed work if it has not scheduled or executed earlier */ if ((!atomic_read(&sde_enc->last_underrun_ts)) && (!atomic_read(&sde_enc->underrun_cnt_dwork))) { schedule_delayed_work(&sde_enc->dwork, msecs_to_jiffies(SDE_ENCODER_UNDERRUN_TIMEOUT)); } /* take snapshot of current underrun and increment the count */ atomic_set(&sde_enc->last_underrun_ts, jiffies); atomic_inc(&sde_enc->underrun_cnt_dwork); trace_sde_encoder_underrun(DRMID(drm_enc), atomic_read(&phy_enc->underrun_cnt)); SDE_DBG_CTRL("stop_ftrace"); Loading Loading @@ -1391,6 +1420,37 @@ static void sde_encoder_frame_done_timeout(unsigned long data) SDE_ENCODER_FRAME_EVENT_ERROR); } static void sde_encoder_underrun_work_func(struct work_struct *work) { struct sde_encoder_virt *sde_enc = container_of(work, struct sde_encoder_virt, dwork.work); unsigned long delta, time; if (!sde_enc) { SDE_ERROR("invalid parameters\n"); return; } delta = jiffies - atomic_read(&sde_enc->last_underrun_ts); time = jiffies_to_msecs(delta); /* * report underrun error when it exceeds the threshold count * and the occurrence of last underrun error is less than 3 * vsync period. */ if (atomic_read(&sde_enc->underrun_cnt_dwork) > SDE_ENCODER_UNDERRUN_CNT_MAX && time < SDE_ENCODER_UNDERRUN_DELTA) { sde_recovery_set_events(SDE_UNDERRUN); } /* reset underrun last timestamp and counter */ atomic_set(&sde_enc->last_underrun_ts, 0); atomic_set(&sde_enc->underrun_cnt_dwork, 0); } struct drm_encoder *sde_encoder_init( struct drm_device *dev, struct msm_display_info *disp_info) Loading Loading @@ -1421,8 +1481,11 @@ struct drm_encoder *sde_encoder_init( drm_encoder_helper_add(drm_enc, &sde_encoder_helper_funcs); atomic_set(&sde_enc->frame_done_timeout, 0); atomic_set(&sde_enc->last_underrun_ts, 0); atomic_set(&sde_enc->underrun_cnt_dwork, 0); setup_timer(&sde_enc->frame_done_timer, sde_encoder_frame_done_timeout, (unsigned long) sde_enc); INIT_DELAYED_WORK(&sde_enc->dwork, sde_encoder_underrun_work_func); _sde_encoder_init_debugfs(drm_enc, sde_enc, sde_kms); Loading