diff options
Diffstat (limited to 'drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c')
-rw-r--r-- | drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 110 |
1 files changed, 39 insertions, 71 deletions
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index 8d942052db8a..1c04b7cce43e 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2014-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2018, 2020-2021 The Linux Foundation. All rights reserved. * Copyright (C) 2013 Red Hat * Author: Rob Clark <robdclark@gmail.com> */ @@ -26,14 +26,15 @@ #include "dpu_crtc.h" #include "dpu_trace.h" #include "dpu_core_irq.h" +#include "disp/msm_disp_snapshot.h" -#define DPU_DEBUG_ENC(e, fmt, ...) DPU_DEBUG("enc%d " fmt,\ +#define DPU_DEBUG_ENC(e, fmt, ...) DRM_DEBUG_ATOMIC("enc%d " fmt,\ (e) ? (e)->base.base.id : -1, ##__VA_ARGS__) #define DPU_ERROR_ENC(e, fmt, ...) DPU_ERROR("enc%d " fmt,\ (e) ? (e)->base.base.id : -1, ##__VA_ARGS__) -#define DPU_DEBUG_PHYS(p, fmt, ...) DPU_DEBUG("enc%d intf%d pp%d " fmt,\ +#define DPU_DEBUG_PHYS(p, fmt, ...) DRM_DEBUG_ATOMIC("enc%d intf%d pp%d " fmt,\ (p) ? (p)->parent->base.id : -1, \ (p) ? (p)->intf_idx - INTF_0 : -1, \ (p) ? ((p)->hw_pp ? (p)->hw_pp->idx - PINGPONG_0 : -1) : -1, \ @@ -253,7 +254,7 @@ void dpu_encoder_helper_report_irq_timeout(struct dpu_encoder_phys *phys_enc, } static int dpu_encoder_helper_wait_event_timeout(int32_t drm_id, - int32_t hw_id, struct dpu_encoder_wait_info *info); + u32 irq_idx, struct dpu_encoder_wait_info *info); int dpu_encoder_helper_wait_for_irq(struct dpu_encoder_phys *phys_enc, enum dpu_intr_idx intr_idx, @@ -273,27 +274,27 @@ int dpu_encoder_helper_wait_for_irq(struct dpu_encoder_phys *phys_enc, /* return EWOULDBLOCK since we know the wait isn't necessary */ if (phys_enc->enable_state == DPU_ENC_DISABLED) { - DRM_ERROR("encoder is disabled id=%u, intr=%d, hw=%d, irq=%d", - DRMID(phys_enc->parent), intr_idx, irq->hw_idx, + DRM_ERROR("encoder is disabled id=%u, intr=%d, irq=%d", + DRMID(phys_enc->parent), intr_idx, irq->irq_idx); return -EWOULDBLOCK; } if (irq->irq_idx < 0) { - DRM_DEBUG_KMS("skip irq wait id=%u, intr=%d, hw=%d, irq=%s", - DRMID(phys_enc->parent), intr_idx, irq->hw_idx, + DRM_DEBUG_KMS("skip irq wait id=%u, intr=%d, irq=%s", + DRMID(phys_enc->parent), intr_idx, irq->name); return 0; } - DRM_DEBUG_KMS("id=%u, intr=%d, hw=%d, irq=%d, pp=%d, pending_cnt=%d", - DRMID(phys_enc->parent), intr_idx, irq->hw_idx, + DRM_DEBUG_KMS("id=%u, intr=%d, irq=%d, pp=%d, pending_cnt=%d", + DRMID(phys_enc->parent), intr_idx, irq->irq_idx, phys_enc->hw_pp->idx - PINGPONG_0, atomic_read(wait_info->atomic_cnt)); ret = dpu_encoder_helper_wait_event_timeout( DRMID(phys_enc->parent), - irq->hw_idx, + irq->irq_idx, wait_info); if (ret <= 0) { @@ -303,9 +304,9 @@ int dpu_encoder_helper_wait_for_irq(struct dpu_encoder_phys *phys_enc, unsigned long flags; DRM_DEBUG_KMS("irq not triggered id=%u, intr=%d, " - "hw=%d, irq=%d, pp=%d, atomic_cnt=%d", + "irq=%d, pp=%d, atomic_cnt=%d", DRMID(phys_enc->parent), intr_idx, - irq->hw_idx, irq->irq_idx, + irq->irq_idx, phys_enc->hw_pp->idx - PINGPONG_0, atomic_read(wait_info->atomic_cnt)); local_irq_save(flags); @@ -315,16 +316,16 @@ int dpu_encoder_helper_wait_for_irq(struct dpu_encoder_phys *phys_enc, } else { ret = -ETIMEDOUT; DRM_DEBUG_KMS("irq timeout id=%u, intr=%d, " - "hw=%d, irq=%d, pp=%d, atomic_cnt=%d", + "irq=%d, pp=%d, atomic_cnt=%d", DRMID(phys_enc->parent), intr_idx, - irq->hw_idx, irq->irq_idx, + irq->irq_idx, phys_enc->hw_pp->idx - PINGPONG_0, atomic_read(wait_info->atomic_cnt)); } } else { ret = 0; trace_dpu_enc_irq_wait_success(DRMID(phys_enc->parent), - intr_idx, irq->hw_idx, irq->irq_idx, + intr_idx, irq->irq_idx, phys_enc->hw_pp->idx - PINGPONG_0, atomic_read(wait_info->atomic_cnt)); } @@ -344,19 +345,9 @@ int dpu_encoder_helper_register_irq(struct dpu_encoder_phys *phys_enc, } irq = &phys_enc->irq[intr_idx]; - if (irq->irq_idx >= 0) { - DPU_DEBUG_PHYS(phys_enc, - "skipping already registered irq %s type %d\n", - irq->name, irq->intr_type); - return 0; - } - - irq->irq_idx = dpu_core_irq_idx_lookup(phys_enc->dpu_kms, - irq->intr_type, irq->hw_idx); if (irq->irq_idx < 0) { DPU_ERROR_PHYS(phys_enc, - "failed to lookup IRQ index for %s type:%d\n", - irq->name, irq->intr_type); + "invalid IRQ index:%d\n", irq->irq_idx); return -EINVAL; } @@ -370,19 +361,8 @@ int dpu_encoder_helper_register_irq(struct dpu_encoder_phys *phys_enc, return ret; } - ret = dpu_core_irq_enable(phys_enc->dpu_kms, &irq->irq_idx, 1); - if (ret) { - DRM_ERROR("enable failed id=%u, intr=%d, hw=%d, irq=%d", - DRMID(phys_enc->parent), intr_idx, irq->hw_idx, - irq->irq_idx); - dpu_core_irq_unregister_callback(phys_enc->dpu_kms, - irq->irq_idx, &irq->cb); - irq->irq_idx = -EINVAL; - return ret; - } - trace_dpu_enc_irq_register_success(DRMID(phys_enc->parent), intr_idx, - irq->hw_idx, irq->irq_idx); + irq->irq_idx); return ret; } @@ -397,31 +377,22 @@ int dpu_encoder_helper_unregister_irq(struct dpu_encoder_phys *phys_enc, /* silently skip irqs that weren't registered */ if (irq->irq_idx < 0) { - DRM_ERROR("duplicate unregister id=%u, intr=%d, hw=%d, irq=%d", - DRMID(phys_enc->parent), intr_idx, irq->hw_idx, + DRM_ERROR("duplicate unregister id=%u, intr=%d, irq=%d", + DRMID(phys_enc->parent), intr_idx, irq->irq_idx); return 0; } - ret = dpu_core_irq_disable(phys_enc->dpu_kms, &irq->irq_idx, 1); - if (ret) { - DRM_ERROR("disable failed id=%u, intr=%d, hw=%d, irq=%d ret=%d", - DRMID(phys_enc->parent), intr_idx, irq->hw_idx, - irq->irq_idx, ret); - } - ret = dpu_core_irq_unregister_callback(phys_enc->dpu_kms, irq->irq_idx, &irq->cb); if (ret) { - DRM_ERROR("unreg cb fail id=%u, intr=%d, hw=%d, irq=%d ret=%d", - DRMID(phys_enc->parent), intr_idx, irq->hw_idx, + DRM_ERROR("unreg cb fail id=%u, intr=%d, irq=%d ret=%d", + DRMID(phys_enc->parent), intr_idx, irq->irq_idx, ret); } trace_dpu_enc_irq_unregister_success(DRMID(phys_enc->parent), intr_idx, - irq->hw_idx, irq->irq_idx); - - irq->irq_idx = -EINVAL; + irq->irq_idx); return 0; } @@ -820,13 +791,13 @@ static int dpu_encoder_resource_control(struct drm_encoder *drm_enc, /* return if the resource control is already in ON state */ if (dpu_enc->rc_state == DPU_ENC_RC_STATE_ON) { - DRM_DEBUG_KMS("id;%u, sw_event:%d, rc in ON state\n", + DRM_DEBUG_ATOMIC("id;%u, sw_event:%d, rc in ON state\n", DRMID(drm_enc), sw_event); mutex_unlock(&dpu_enc->rc_lock); return 0; } else if (dpu_enc->rc_state != DPU_ENC_RC_STATE_OFF && dpu_enc->rc_state != DPU_ENC_RC_STATE_IDLE) { - DRM_DEBUG_KMS("id;%u, sw_event:%d, rc in state %d\n", + DRM_DEBUG_ATOMIC("id;%u, sw_event:%d, rc in state %d\n", DRMID(drm_enc), sw_event, dpu_enc->rc_state); mutex_unlock(&dpu_enc->rc_lock); @@ -1336,6 +1307,11 @@ static void dpu_encoder_underrun_callback(struct drm_encoder *drm_enc, DPU_ATRACE_BEGIN("encoder_underrun_callback"); atomic_inc(&phy_enc->underrun_cnt); + + /* trigger dump only on the first underrun */ + if (atomic_read(&phy_enc->underrun_cnt) == 1) + msm_disp_snapshot_state(drm_enc->dev); + trace_dpu_enc_underrun_cb(DRMID(drm_enc), atomic_read(&phy_enc->underrun_cnt)); DPU_ATRACE_END("encoder_underrun_callback"); @@ -1453,11 +1429,6 @@ static void dpu_encoder_off_work(struct work_struct *work) struct dpu_encoder_virt *dpu_enc = container_of(work, struct dpu_encoder_virt, delayed_off_work.work); - if (!dpu_enc) { - DPU_ERROR("invalid dpu encoder\n"); - return; - } - dpu_encoder_resource_control(&dpu_enc->base, DPU_ENC_RC_EVENT_ENTER_IDLE); @@ -1537,7 +1508,7 @@ void dpu_encoder_helper_trigger_start(struct dpu_encoder_phys *phys_enc) static int dpu_encoder_helper_wait_event_timeout( int32_t drm_id, - int32_t hw_id, + u32 irq_idx, struct dpu_encoder_wait_info *info) { int rc = 0; @@ -1550,7 +1521,7 @@ static int dpu_encoder_helper_wait_event_timeout( atomic_read(info->atomic_cnt) == 0, jiffies); time = ktime_to_ms(ktime_get()); - trace_dpu_enc_wait_event_timeout(drm_id, hw_id, rc, time, + trace_dpu_enc_wait_event_timeout(drm_id, irq_idx, rc, time, expected_time, atomic_read(info->atomic_cnt)); /* If we timed out, counter is valid and time is less, wait again */ @@ -1565,19 +1536,23 @@ static void dpu_encoder_helper_hw_reset(struct dpu_encoder_phys *phys_enc) struct dpu_encoder_virt *dpu_enc; struct dpu_hw_ctl *ctl; int rc; + struct drm_encoder *drm_enc; dpu_enc = to_dpu_encoder_virt(phys_enc->parent); ctl = phys_enc->hw_ctl; + drm_enc = phys_enc->parent; if (!ctl->ops.reset) return; - DRM_DEBUG_KMS("id:%u ctl %d reset\n", DRMID(phys_enc->parent), + DRM_DEBUG_KMS("id:%u ctl %d reset\n", DRMID(drm_enc), ctl->idx); rc = ctl->ops.reset(ctl); - if (rc) + if (rc) { DPU_ERROR_ENC(dpu_enc, "ctl %d reset failure\n", ctl->idx); + msm_disp_snapshot_state(drm_enc->dev); + } phys_enc->enable_state = DPU_ENC_ENABLED; } @@ -1797,11 +1772,6 @@ static void dpu_encoder_vsync_event_work_handler(struct kthread_work *work) struct dpu_encoder_virt, vsync_event_work); ktime_t wakeup_time; - if (!dpu_enc) { - DPU_ERROR("invalid dpu encoder\n"); - return; - } - if (dpu_encoder_vsync_time(&dpu_enc->base, &wakeup_time)) return; @@ -2068,8 +2038,6 @@ static int dpu_encoder_setup_display(struct dpu_encoder_virt *dpu_enc, phys_params.parent_ops = &dpu_encoder_parent_ops; phys_params.enc_spinlock = &dpu_enc->enc_spinlock; - DPU_DEBUG("\n"); - switch (disp_info->intf_type) { case DRM_MODE_ENCODER_DSI: intf_type = INTF_DSI; |