diff --git a/msm/sde/sde_encoder.c b/msm/sde/sde_encoder.c index 3191e06a37..0608ec3d61 100644 --- a/msm/sde/sde_encoder.c +++ b/msm/sde/sde_encoder.c @@ -66,8 +66,6 @@ #define MAX_PHYS_ENCODERS_PER_VIRTUAL \ (MAX_H_TILES_PER_DISPLAY * NUM_PHYS_ENCODER_TYPES) -#define MAX_CHANNELS_PER_ENC 2 - #define MISR_BUFF_SIZE 256 #define IDLE_SHORT_TIMEOUT 1 @@ -4784,6 +4782,32 @@ void sde_encoder_kickoff(struct drm_encoder *drm_enc, bool is_error) SDE_ATRACE_END("encoder_kickoff"); } +void sde_encoder_helper_get_pp_line_count(struct drm_encoder *drm_enc, + struct sde_hw_pp_vsync_info *info) +{ + struct sde_encoder_virt *sde_enc; + struct sde_encoder_phys *phys; + int i, ret; + + if (!drm_enc || !info) + return; + + sde_enc = to_sde_encoder_virt(drm_enc); + + for (i = 0; i < sde_enc->num_phys_encs; i++) { + phys = sde_enc->phys_encs[i]; + if (phys && phys->hw_intf && phys->hw_pp + && phys->hw_intf->ops.get_vsync_info) { + ret = phys->hw_intf->ops.get_vsync_info( + phys->hw_intf, &info[i]); + if (!ret) { + info[i].pp_idx = phys->hw_pp->idx - PINGPONG_0; + info[i].intf_idx = phys->hw_intf->idx - INTF_0; + } + } + } +} + int sde_encoder_helper_reset_mixers(struct sde_encoder_phys *phys_enc, struct drm_framebuffer *fb) { diff --git a/msm/sde/sde_encoder.h b/msm/sde/sde_encoder.h index 83c43d5b6d..098ccf088c 100644 --- a/msm/sde/sde_encoder.h +++ b/msm/sde/sde_encoder.h @@ -25,6 +25,8 @@ #include "sde_hw_mdss.h" #include "sde_kms.h" +#define MAX_CHANNELS_PER_ENC 2 + #define SDE_ENCODER_FRAME_EVENT_DONE BIT(0) #define SDE_ENCODER_FRAME_EVENT_ERROR BIT(1) #define SDE_ENCODER_FRAME_EVENT_PANEL_DEAD BIT(2) diff --git a/msm/sde/sde_encoder_phys.h b/msm/sde/sde_encoder_phys.h index 619d3d2343..4f5383a537 100644 --- a/msm/sde/sde_encoder_phys.h +++ b/msm/sde/sde_encoder_phys.h @@ -508,6 +508,14 @@ void sde_encoder_phys_setup_cdm(struct sde_encoder_phys *phys_enc, struct drm_framebuffer *fb, const struct sde_format *format, struct sde_rect *wb_roi); +/** + * sde_encoder_helper_get_pp_line_count - pingpong linecount helper function + * @drm_enc: Pointer to drm encoder structure + * @info: structure used to populate the pp line count information + */ +void sde_encoder_helper_get_pp_line_count(struct drm_encoder *drm_enc, + struct sde_hw_pp_vsync_info *info); + /** * sde_encoder_helper_trigger_flush - control flush helper function * This helper function may be optionally specified by physical diff --git a/msm/sde/sde_encoder_phys_cmd.c b/msm/sde/sde_encoder_phys_cmd.c index 599d268cdc..37bd33e2ed 100644 --- a/msm/sde/sde_encoder_phys_cmd.c +++ b/msm/sde/sde_encoder_phys_cmd.c @@ -256,6 +256,7 @@ static void sde_encoder_phys_cmd_te_rd_ptr_irq(void *arg, int irq_idx) struct sde_encoder_phys_cmd *cmd_enc; u32 event = 0, scheduler_status = INVALID_CTL_STATUS; struct sde_hw_ctl *ctl; + struct sde_hw_pp_vsync_info info[MAX_CHANNELS_PER_ENC] = {{0}}; if (!phys_enc || !phys_enc->hw_pp || !phys_enc->hw_intf) return; @@ -282,10 +283,11 @@ static void sde_encoder_phys_cmd_te_rd_ptr_irq(void *arg, int irq_idx) if (ctl && ctl->ops.get_scheduler_status) scheduler_status = ctl->ops.get_scheduler_status(ctl); + sde_encoder_helper_get_pp_line_count(phys_enc->parent, info); SDE_EVT32_IRQ(DRMID(phys_enc->parent), - phys_enc->hw_pp->idx - PINGPONG_0, - phys_enc->hw_intf->idx - INTF_0, - event, scheduler_status, 0xfff); + info[0].pp_idx, info[0].intf_idx, info[0].wr_ptr_line_count, + event, scheduler_status, + info[1].pp_idx, info[1].intf_idx, info[1].wr_ptr_line_count); if (phys_enc->parent_ops.handle_vblank_virt) phys_enc->parent_ops.handle_vblank_virt(phys_enc->parent, @@ -305,6 +307,7 @@ static void sde_encoder_phys_cmd_ctl_start_irq(void *arg, int irq_idx) struct sde_hw_ctl *ctl; u32 event = 0; s64 time_diff_us; + struct sde_hw_pp_vsync_info info[MAX_CHANNELS_PER_ENC] = {{0}}; if (!phys_enc || !phys_enc->hw_ctl) return; @@ -348,8 +351,11 @@ static void sde_encoder_phys_cmd_ctl_start_irq(void *arg, int irq_idx) } } - SDE_EVT32_IRQ(DRMID(phys_enc->parent), ctl->idx - CTL_0, - time_diff_us, event, 0xfff); + sde_encoder_helper_get_pp_line_count(phys_enc->parent, info); + SDE_EVT32_IRQ(DRMID(phys_enc->parent), + ctl->idx - CTL_0, time_diff_us, event, + info[0].pp_idx, info[0].intf_idx, info[0].wr_ptr_line_count, + info[1].pp_idx, info[1].intf_idx, info[1].wr_ptr_line_count); /* Signal any waiting ctl start interrupt */ wake_up_all(&phys_enc->pending_kickoff_wq); diff --git a/msm/sde/sde_hw_mdss.h b/msm/sde/sde_hw_mdss.h index b5d6c1c6e8..8fa8a82c2e 100644 --- a/msm/sde/sde_hw_mdss.h +++ b/msm/sde/sde_hw_mdss.h @@ -667,12 +667,16 @@ struct sde_hw_autorefresh { /** * struct sde_hw_pp_vsync_info - Struct contains parameters to configure * read and write pointers for command mode panels + * @pp_idx: Ping-pong block index + * @intf_idx: Interface block index * @rd_ptr_init_val: Value of rd pointer at vsync edge * @rd_ptr_frame_count: num frames sent since enabling interface * @rd_ptr_line_count: current line on panel (rd ptr) * @wr_ptr_line_count: current line within pp fifo (wr ptr) */ struct sde_hw_pp_vsync_info { + u32 pp_idx; + u32 intf_idx; u32 rd_ptr_init_val; u32 rd_ptr_frame_count; u32 rd_ptr_line_count;