|
@@ -1703,11 +1703,6 @@ static int _sde_encoder_rc_stop(struct drm_encoder *drm_enc,
|
|
|
{
|
|
|
int ret = 0;
|
|
|
|
|
|
- /* cancel vsync event work and timer */
|
|
|
- kthread_cancel_work_sync(&sde_enc->vsync_event_work);
|
|
|
- if (sde_enc->disp_info.intf_type == DRM_MODE_CONNECTOR_DSI)
|
|
|
- del_timer_sync(&sde_enc->vsync_event_timer);
|
|
|
-
|
|
|
mutex_lock(&sde_enc->rc_lock);
|
|
|
/* return if the resource control is already in OFF state */
|
|
|
if (sde_enc->rc_state == SDE_ENC_RC_STATE_OFF) {
|
|
@@ -3653,103 +3648,6 @@ void sde_encoder_trigger_kickoff_pending(struct drm_encoder *drm_enc)
|
|
|
sde_enc->idle_pc_restore = false;
|
|
|
}
|
|
|
|
|
|
-static int _sde_encoder_wakeup_time(struct drm_encoder *drm_enc,
|
|
|
- ktime_t *wakeup_time)
|
|
|
-{
|
|
|
- struct drm_display_mode *mode;
|
|
|
- struct sde_encoder_virt *sde_enc;
|
|
|
- u32 cur_line, lines_left;
|
|
|
- u32 line_time, mdp_transfer_time_us;
|
|
|
- u32 vtotal, time_to_vsync_us, threshold_time_us = 0;
|
|
|
- ktime_t cur_time;
|
|
|
-
|
|
|
- sde_enc = to_sde_encoder_virt(drm_enc);
|
|
|
- if (!sde_enc || !sde_enc->cur_master) {
|
|
|
- SDE_ERROR("invalid sde encoder/master\n");
|
|
|
- return -EINVAL;
|
|
|
- }
|
|
|
-
|
|
|
- mode = &sde_enc->cur_master->cached_mode;
|
|
|
- mdp_transfer_time_us = sde_enc->mode_info.mdp_transfer_time_us;
|
|
|
-
|
|
|
- vtotal = mode->vtotal;
|
|
|
- if (!mdp_transfer_time_us) {
|
|
|
- /* mdp_transfer_time set to 0 for video mode */
|
|
|
- line_time = (1000000 / sde_enc->mode_info.frame_rate) / vtotal;
|
|
|
- } else {
|
|
|
- line_time = mdp_transfer_time_us / vtotal;
|
|
|
- threshold_time_us = ((1000000 / sde_enc->mode_info.frame_rate)
|
|
|
- - mdp_transfer_time_us);
|
|
|
- }
|
|
|
-
|
|
|
- if (!sde_enc->cur_master->ops.get_line_count) {
|
|
|
- SDE_DEBUG_ENC(sde_enc, "can't get master line count\n");
|
|
|
- return -EINVAL;
|
|
|
- }
|
|
|
-
|
|
|
- cur_line = sde_enc->cur_master->ops.get_line_count(sde_enc->cur_master);
|
|
|
-
|
|
|
- lines_left = (cur_line >= vtotal) ? vtotal : (vtotal - cur_line);
|
|
|
-
|
|
|
- time_to_vsync_us = line_time * lines_left;
|
|
|
-
|
|
|
- if (!time_to_vsync_us) {
|
|
|
- SDE_ERROR("time to vsync should not be zero, vtotal=%d\n",
|
|
|
- vtotal);
|
|
|
- return -EINVAL;
|
|
|
- }
|
|
|
-
|
|
|
- cur_time = ktime_get();
|
|
|
- *wakeup_time = ktime_add_us(cur_time, time_to_vsync_us);
|
|
|
- if (threshold_time_us)
|
|
|
- *wakeup_time = ktime_add_us(*wakeup_time, threshold_time_us);
|
|
|
-
|
|
|
- SDE_DEBUG_ENC(sde_enc,
|
|
|
- "cur_line=%u vtotal=%u time_to_vsync=%u, cur_time=%lld, wakeup_time=%lld\n",
|
|
|
- cur_line, vtotal, time_to_vsync_us,
|
|
|
- ktime_to_ms(cur_time),
|
|
|
- ktime_to_ms(*wakeup_time));
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-static void sde_encoder_vsync_event_handler(struct timer_list *t)
|
|
|
-{
|
|
|
- struct drm_encoder *drm_enc;
|
|
|
- struct sde_encoder_virt *sde_enc =
|
|
|
- from_timer(sde_enc, t, vsync_event_timer);
|
|
|
- struct msm_drm_private *priv;
|
|
|
- struct msm_drm_thread *event_thread;
|
|
|
-
|
|
|
- if (!sde_enc || !sde_enc->crtc) {
|
|
|
- SDE_ERROR("invalid encoder parameters %d\n", !sde_enc);
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- drm_enc = &sde_enc->base;
|
|
|
-
|
|
|
- if (!drm_enc || !drm_enc->dev || !drm_enc->dev->dev_private) {
|
|
|
- SDE_ERROR("invalid encoder parameters\n");
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- priv = drm_enc->dev->dev_private;
|
|
|
-
|
|
|
- if (sde_enc->crtc->index >= ARRAY_SIZE(priv->event_thread)) {
|
|
|
- SDE_ERROR("invalid crtc index:%u\n",
|
|
|
- sde_enc->crtc->index);
|
|
|
- return;
|
|
|
- }
|
|
|
- event_thread = &priv->event_thread[sde_enc->crtc->index];
|
|
|
- if (!event_thread) {
|
|
|
- SDE_ERROR("event_thread not found for crtc:%d\n",
|
|
|
- sde_enc->crtc->index);
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- kthread_queue_work(&event_thread->worker,
|
|
|
- &sde_enc->vsync_event_work);
|
|
|
-}
|
|
|
-
|
|
|
static void sde_encoder_esd_trigger_work_handler(struct kthread_work *work)
|
|
|
{
|
|
|
struct sde_encoder_virt *sde_enc = container_of(work,
|
|
@@ -3778,49 +3676,6 @@ static void sde_encoder_input_event_work_handler(struct kthread_work *work)
|
|
|
SDE_ENC_RC_EVENT_EARLY_WAKEUP);
|
|
|
}
|
|
|
|
|
|
-static void sde_encoder_vsync_event_work_handler(struct kthread_work *work)
|
|
|
-{
|
|
|
- struct sde_encoder_virt *sde_enc = container_of(work,
|
|
|
- struct sde_encoder_virt, vsync_event_work);
|
|
|
- bool autorefresh_enabled = false;
|
|
|
- int rc = 0;
|
|
|
- ktime_t wakeup_time;
|
|
|
- struct drm_encoder *drm_enc;
|
|
|
-
|
|
|
- if (!sde_enc) {
|
|
|
- SDE_ERROR("invalid sde encoder\n");
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- drm_enc = &sde_enc->base;
|
|
|
- rc = pm_runtime_get_sync(drm_enc->dev->dev);
|
|
|
- if (rc < 0) {
|
|
|
- SDE_ERROR_ENC(sde_enc, "sde enc power enabled failed:%d\n", rc);
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- if (sde_enc->cur_master &&
|
|
|
- sde_enc->cur_master->ops.is_autorefresh_enabled)
|
|
|
- autorefresh_enabled =
|
|
|
- sde_enc->cur_master->ops.is_autorefresh_enabled(
|
|
|
- sde_enc->cur_master);
|
|
|
-
|
|
|
- /* Update timer if autorefresh is enabled else return */
|
|
|
- if (!autorefresh_enabled)
|
|
|
- goto exit;
|
|
|
-
|
|
|
- rc = _sde_encoder_wakeup_time(&sde_enc->base, &wakeup_time);
|
|
|
- if (rc)
|
|
|
- goto exit;
|
|
|
-
|
|
|
- SDE_EVT32_VERBOSE(ktime_to_ms(wakeup_time));
|
|
|
- mod_timer(&sde_enc->vsync_event_timer,
|
|
|
- nsecs_to_jiffies(ktime_to_ns(wakeup_time)));
|
|
|
-
|
|
|
-exit:
|
|
|
- pm_runtime_put_sync(drm_enc->dev->dev);
|
|
|
-}
|
|
|
-
|
|
|
int sde_encoder_poll_line_counts(struct drm_encoder *drm_enc)
|
|
|
{
|
|
|
static const uint64_t timeout_us = 50000;
|
|
@@ -4126,7 +3981,6 @@ void sde_encoder_kickoff(struct drm_encoder *drm_enc, bool is_error)
|
|
|
{
|
|
|
struct sde_encoder_virt *sde_enc;
|
|
|
struct sde_encoder_phys *phys;
|
|
|
- ktime_t wakeup_time;
|
|
|
unsigned int i;
|
|
|
|
|
|
if (!drm_enc) {
|
|
@@ -4152,13 +4006,6 @@ void sde_encoder_kickoff(struct drm_encoder *drm_enc, bool is_error)
|
|
|
phys->ops.handle_post_kickoff(phys);
|
|
|
}
|
|
|
|
|
|
- if (sde_enc->disp_info.intf_type == DRM_MODE_CONNECTOR_DSI &&
|
|
|
- !_sde_encoder_wakeup_time(drm_enc, &wakeup_time)) {
|
|
|
- SDE_EVT32_VERBOSE(ktime_to_ms(wakeup_time));
|
|
|
- mod_timer(&sde_enc->vsync_event_timer,
|
|
|
- nsecs_to_jiffies(ktime_to_ns(wakeup_time)));
|
|
|
- }
|
|
|
-
|
|
|
SDE_ATRACE_END("encoder_kickoff");
|
|
|
}
|
|
|
|
|
@@ -4898,10 +4745,6 @@ struct drm_encoder *sde_encoder_init_with_ops(
|
|
|
drm_encoder_init(dev, drm_enc, &sde_encoder_funcs, drm_enc_mode, NULL);
|
|
|
drm_encoder_helper_add(drm_enc, &sde_encoder_helper_funcs);
|
|
|
|
|
|
- if (disp_info->intf_type == DRM_MODE_CONNECTOR_DSI)
|
|
|
- timer_setup(&sde_enc->vsync_event_timer,
|
|
|
- sde_encoder_vsync_event_handler, 0);
|
|
|
-
|
|
|
for (i = 0; i < sde_enc->num_phys_encs; i++) {
|
|
|
phys = sde_enc->phys_encs[i];
|
|
|
if (!phys)
|
|
@@ -4933,9 +4776,6 @@ struct drm_encoder *sde_encoder_init_with_ops(
|
|
|
sde_enc->vblank_enabled = false;
|
|
|
sde_enc->qdss_status = false;
|
|
|
|
|
|
- kthread_init_work(&sde_enc->vsync_event_work,
|
|
|
- sde_encoder_vsync_event_work_handler);
|
|
|
-
|
|
|
kthread_init_work(&sde_enc->input_event_work,
|
|
|
sde_encoder_input_event_work_handler);
|
|
|
|