summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c')
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c75
1 files changed, 26 insertions, 49 deletions
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
index be185fe69793..a301e2833177 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
@@ -13,6 +13,8 @@
#include "dpu_trace.h"
#include "disp/msm_disp_snapshot.h"
+#include <drm/drm_managed.h>
+
#define DPU_DEBUG_CMDENC(e, fmt, ...) DPU_DEBUG("enc%d intf%d " fmt, \
(e) && (e)->base.parent ? \
(e)->base.parent->base.id : -1, \
@@ -244,7 +246,8 @@ static int dpu_encoder_phys_cmd_control_vblank_irq(
return -EINVAL;
}
- refcount = atomic_read(&phys_enc->vblank_refcount);
+ mutex_lock(&phys_enc->vblank_ctl_lock);
+ refcount = phys_enc->vblank_refcount;
/* Slave encoders don't report vblank */
if (!dpu_encoder_phys_cmd_is_master(phys_enc))
@@ -260,16 +263,24 @@ static int dpu_encoder_phys_cmd_control_vblank_irq(
phys_enc->hw_pp->idx - PINGPONG_0,
enable ? "true" : "false", refcount);
- if (enable && atomic_inc_return(&phys_enc->vblank_refcount) == 1)
- ret = dpu_core_irq_register_callback(phys_enc->dpu_kms,
- phys_enc->irq[INTR_IDX_RDPTR],
- dpu_encoder_phys_cmd_te_rd_ptr_irq,
- phys_enc);
- else if (!enable && atomic_dec_return(&phys_enc->vblank_refcount) == 0)
- ret = dpu_core_irq_unregister_callback(phys_enc->dpu_kms,
- phys_enc->irq[INTR_IDX_RDPTR]);
+ if (enable) {
+ if (phys_enc->vblank_refcount == 0)
+ ret = dpu_core_irq_register_callback(phys_enc->dpu_kms,
+ phys_enc->irq[INTR_IDX_RDPTR],
+ dpu_encoder_phys_cmd_te_rd_ptr_irq,
+ phys_enc);
+ if (!ret)
+ phys_enc->vblank_refcount++;
+ } else if (!enable) {
+ if (phys_enc->vblank_refcount == 1)
+ ret = dpu_core_irq_unregister_callback(phys_enc->dpu_kms,
+ phys_enc->irq[INTR_IDX_RDPTR]);
+ if (!ret)
+ phys_enc->vblank_refcount--;
+ }
end:
+ mutex_unlock(&phys_enc->vblank_ctl_lock);
if (ret) {
DRM_ERROR("vblank irq err id:%u pp:%d ret:%d, enable %s/%d\n",
DRMID(phys_enc->parent),
@@ -285,7 +296,7 @@ static void dpu_encoder_phys_cmd_irq_control(struct dpu_encoder_phys *phys_enc,
{
trace_dpu_enc_phys_cmd_irq_ctrl(DRMID(phys_enc->parent),
phys_enc->hw_pp->idx - PINGPONG_0,
- enable, atomic_read(&phys_enc->vblank_refcount));
+ enable, phys_enc->vblank_refcount);
if (enable) {
dpu_core_irq_register_callback(phys_enc->dpu_kms,
@@ -558,14 +569,6 @@ static void dpu_encoder_phys_cmd_disable(struct dpu_encoder_phys *phys_enc)
phys_enc->enable_state = DPU_ENC_DISABLED;
}
-static void dpu_encoder_phys_cmd_destroy(struct dpu_encoder_phys *phys_enc)
-{
- struct dpu_encoder_phys_cmd *cmd_enc =
- to_dpu_encoder_phys_cmd(phys_enc);
-
- kfree(cmd_enc);
-}
-
static void dpu_encoder_phys_cmd_prepare_for_kickoff(
struct dpu_encoder_phys *phys_enc)
{
@@ -681,33 +684,6 @@ static int dpu_encoder_phys_cmd_wait_for_commit_done(
return _dpu_encoder_phys_cmd_wait_for_ctl_start(phys_enc);
}
-static int dpu_encoder_phys_cmd_wait_for_vblank(
- struct dpu_encoder_phys *phys_enc)
-{
- int rc = 0;
- struct dpu_encoder_phys_cmd *cmd_enc;
- struct dpu_encoder_wait_info wait_info;
-
- cmd_enc = to_dpu_encoder_phys_cmd(phys_enc);
-
- /* only required for master controller */
- if (!dpu_encoder_phys_cmd_is_master(phys_enc))
- return rc;
-
- wait_info.wq = &cmd_enc->pending_vblank_wq;
- wait_info.atomic_cnt = &cmd_enc->pending_vblank_cnt;
- wait_info.timeout_ms = KICKOFF_TIMEOUT_MS;
-
- atomic_inc(&cmd_enc->pending_vblank_cnt);
-
- rc = dpu_encoder_helper_wait_for_irq(phys_enc,
- phys_enc->irq[INTR_IDX_RDPTR],
- dpu_encoder_phys_cmd_te_rd_ptr_irq,
- &wait_info);
-
- return rc;
-}
-
static void dpu_encoder_phys_cmd_handle_post_kickoff(
struct dpu_encoder_phys *phys_enc)
{
@@ -731,12 +707,10 @@ static void dpu_encoder_phys_cmd_init_ops(
ops->atomic_mode_set = dpu_encoder_phys_cmd_atomic_mode_set;
ops->enable = dpu_encoder_phys_cmd_enable;
ops->disable = dpu_encoder_phys_cmd_disable;
- ops->destroy = dpu_encoder_phys_cmd_destroy;
ops->control_vblank_irq = dpu_encoder_phys_cmd_control_vblank_irq;
ops->wait_for_commit_done = dpu_encoder_phys_cmd_wait_for_commit_done;
ops->prepare_for_kickoff = dpu_encoder_phys_cmd_prepare_for_kickoff;
ops->wait_for_tx_complete = dpu_encoder_phys_cmd_wait_for_tx_complete;
- ops->wait_for_vblank = dpu_encoder_phys_cmd_wait_for_vblank;
ops->trigger_start = dpu_encoder_phys_cmd_trigger_start;
ops->needs_single_flush = dpu_encoder_phys_cmd_needs_single_flush;
ops->irq_control = dpu_encoder_phys_cmd_irq_control;
@@ -746,7 +720,7 @@ static void dpu_encoder_phys_cmd_init_ops(
ops->get_line_count = dpu_encoder_phys_cmd_get_line_count;
}
-struct dpu_encoder_phys *dpu_encoder_phys_cmd_init(
+struct dpu_encoder_phys *dpu_encoder_phys_cmd_init(struct drm_device *dev,
struct dpu_enc_phys_init_params *p)
{
struct dpu_encoder_phys *phys_enc = NULL;
@@ -754,7 +728,7 @@ struct dpu_encoder_phys *dpu_encoder_phys_cmd_init(
DPU_DEBUG("intf\n");
- cmd_enc = kzalloc(sizeof(*cmd_enc), GFP_KERNEL);
+ cmd_enc = drmm_kzalloc(dev, sizeof(*cmd_enc), GFP_KERNEL);
if (!cmd_enc) {
DPU_ERROR("failed to allocate\n");
return ERR_PTR(-ENOMEM);
@@ -763,6 +737,9 @@ struct dpu_encoder_phys *dpu_encoder_phys_cmd_init(
dpu_encoder_phys_init(phys_enc, p);
+ mutex_init(&phys_enc->vblank_ctl_lock);
+ phys_enc->vblank_refcount = 0;
+
dpu_encoder_phys_cmd_init_ops(&phys_enc->ops);
phys_enc->intf_mode = INTF_MODE_CMD;
cmd_enc->stream_sel = 0;