Merge "disp: msm: sde: override tearcheck rd_ptr_val when qsync is enabled"

This commit is contained in:
qctecmdr
2022-06-07 09:42:49 -07:00
committed by Gerrit - the friendly Code Review server
commit 249b73b0c7
4 muutettua tiedostoa jossa 67 lisäystä ja 4 poistoa

Näytä tiedosto

@@ -415,6 +415,7 @@ struct sde_encoder_phys_cmd_te_timestamp {
* @wr_ptr_wait_success: log wr_ptr_wait success for release fence trigger
* @te_timestamp_list: List head for the TE timestamp list
* @te_timestamp: Array of size MAX_TE_PROFILE_COUNT te_timestamp_list elements
* @qsync_threshold_lines: tearcheck threshold lines calculated based on qsync_min_fps
*/
struct sde_encoder_phys_cmd {
struct sde_encoder_phys base;
@@ -427,6 +428,7 @@ struct sde_encoder_phys_cmd {
struct list_head te_timestamp_list;
struct sde_encoder_phys_cmd_te_timestamp
te_timestamp[MAX_TE_PROFILE_COUNT];
u32 qsync_threshold_lines;
};
/**

Näytä tiedosto

@@ -171,6 +171,37 @@ static void _sde_encoder_phys_cmd_update_intf_cfg(
}
}
static void sde_encoder_override_tearcheck_rd_ptr(struct sde_encoder_phys *phys_enc)
{
struct sde_hw_intf *hw_intf;
struct drm_display_mode *mode;
struct sde_encoder_phys_cmd *cmd_enc;
struct sde_hw_pp_vsync_info info[MAX_CHANNELS_PER_ENC] = {{0}};
u32 adjusted_tear_rd_ptr_line_cnt;
if (!phys_enc || !phys_enc->hw_intf)
return;
cmd_enc = to_sde_encoder_phys_cmd(phys_enc);
hw_intf = phys_enc->hw_intf;
mode = &phys_enc->cached_mode;
/* Configure TE rd_ptr_val to the end of qsync Start Window.
* This ensures next frame trigger_start does not get latched in the current
* vsync window.
*/
adjusted_tear_rd_ptr_line_cnt = mode->vdisplay + cmd_enc->qsync_threshold_lines + 1;
if (hw_intf && hw_intf->ops.override_tear_rd_ptr_val)
hw_intf->ops.override_tear_rd_ptr_val(hw_intf, adjusted_tear_rd_ptr_line_cnt);
sde_encoder_helper_get_pp_line_count(phys_enc->parent, info);
SDE_EVT32_VERBOSE(phys_enc->hw_intf->idx - INTF_0, mode->vdisplay,
cmd_enc->qsync_threshold_lines, info[0].rd_ptr_line_count,
info[0].rd_ptr_frame_count, info[0].wr_ptr_line_count,
info[1].rd_ptr_line_count, info[1].rd_ptr_frame_count, info[1].wr_ptr_line_count);
}
static void _sde_encoder_phys_signal_frame_done(struct sde_encoder_phys *phys_enc)
{
struct sde_encoder_phys_cmd *cmd_enc;
@@ -309,9 +340,9 @@ static void sde_encoder_phys_cmd_te_rd_ptr_irq(void *arg, int irq_idx)
sde_encoder_helper_get_pp_line_count(phys_enc->parent, info);
SDE_EVT32_IRQ(DRMID(phys_enc->parent),
info[0].pp_idx, info[0].intf_idx,
info[0].wr_ptr_line_count, info[0].intf_frame_count,
info[0].wr_ptr_line_count, info[0].intf_frame_count, info[0].rd_ptr_line_count,
info[1].pp_idx, info[1].intf_idx,
info[1].wr_ptr_line_count, info[1].intf_frame_count,
info[1].wr_ptr_line_count, info[1].intf_frame_count, info[1].rd_ptr_line_count,
scheduler_status, fence_ready);
if (phys_enc->parent_ops.handle_vblank_virt)
@@ -327,7 +358,7 @@ static void sde_encoder_phys_cmd_wr_ptr_irq(void *arg, int irq_idx)
{
struct sde_encoder_phys *phys_enc = arg;
struct sde_hw_ctl *ctl;
u32 event = 0;
u32 event = 0, qsync_mode = 0;
struct sde_hw_pp_vsync_info info[MAX_CHANNELS_PER_ENC] = {{0}};
if (!phys_enc || !phys_enc->hw_ctl)
@@ -335,6 +366,7 @@ static void sde_encoder_phys_cmd_wr_ptr_irq(void *arg, int irq_idx)
SDE_ATRACE_BEGIN("wr_ptr_irq");
ctl = phys_enc->hw_ctl;
qsync_mode = sde_connector_get_qsync_mode(phys_enc->connector);
if (atomic_add_unless(&phys_enc->pending_retire_fence_cnt, -1, 0)) {
event = SDE_ENCODER_FRAME_EVENT_SIGNAL_RETIRE_FENCE;
@@ -350,7 +382,10 @@ static void sde_encoder_phys_cmd_wr_ptr_irq(void *arg, int irq_idx)
SDE_EVT32_IRQ(DRMID(phys_enc->parent),
ctl->idx - CTL_0, 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);
info[1].pp_idx, info[1].intf_idx, info[1].wr_ptr_line_count, qsync_mode);
if (qsync_mode)
sde_encoder_override_tearcheck_rd_ptr(phys_enc);
/* Signal any waiting wr_ptr start interrupt */
wake_up_all(&phys_enc->pending_kickoff_wq);
@@ -1092,6 +1127,7 @@ static void sde_encoder_phys_cmd_tearcheck_config(
tc_cfg.start_pos = mode->vdisplay;
tc_cfg.rd_ptr_irq = mode->vdisplay + 1;
tc_cfg.wr_ptr_irq = 1;
cmd_enc->qsync_threshold_lines = tc_cfg.sync_threshold_start;
SDE_DEBUG_CMDENC(cmd_enc,
"tc %d intf %d vsync_clk_speed_hz %u vtotal %u vrefresh %u\n",
@@ -1418,6 +1454,7 @@ static int sde_encoder_phys_cmd_prepare_for_kickoff(
if (sde_connector_is_qsync_updated(phys_enc->connector)) {
tc_cfg.sync_threshold_start = _get_tearcheck_threshold(
phys_enc);
cmd_enc->qsync_threshold_lines = tc_cfg.sync_threshold_start;
if (phys_enc->has_intf_te &&
phys_enc->hw_intf->ops.update_tearcheck)
phys_enc->hw_intf->ops.update_tearcheck(

Näytä tiedosto

@@ -858,6 +858,21 @@ static int sde_hw_intf_v1_check_and_reset_tearcheck(struct sde_hw_intf *intf,
return 0;
}
static void sde_hw_intf_override_tear_rd_ptr_val(struct sde_hw_intf *intf,
u32 adjusted_rd_ptr_val)
{
struct sde_hw_blk_reg_map *c;
if (!intf || !adjusted_rd_ptr_val)
return;
c = &intf->hw;
SDE_REG_WRITE(c, INTF_TEAR_SYNC_WRCOUNT, (adjusted_rd_ptr_val & 0xFFFF));
/* ensure rd_ptr_val is written */
wmb();
}
static void sde_hw_intf_vsync_sel(struct sde_hw_intf *intf,
u32 vsync_source)
{
@@ -956,6 +971,8 @@ static void _setup_intf_ops(struct sde_hw_intf_ops *ops,
ops->vsync_sel = sde_hw_intf_vsync_sel;
ops->check_and_reset_tearcheck =
sde_hw_intf_v1_check_and_reset_tearcheck;
ops->override_tear_rd_ptr_val =
sde_hw_intf_override_tear_rd_ptr_val;
}
if (cap & BIT(SDE_INTF_RESET_COUNTER))

Näytä tiedosto

@@ -247,6 +247,13 @@ struct sde_hw_intf_ops {
* Get the INTF interrupt status
*/
u32 (*get_intr_status)(struct sde_hw_intf *intf);
/**
* Override tear check rd_ptr_val with adjusted_linecnt
* when qsync is enabled.
*/
void (*override_tear_rd_ptr_val)(struct sde_hw_intf *intf,
u32 adjusted_linecnt);
};
struct sde_hw_intf {