summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c')
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c110
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;