disp: msm: sde: enable mdp vsync frame count

Currently, the driver uses the panel frame count along with
mdp vsync timestamp which can be unreliable if there are any
latencies. This change adds support to use mdp vsync frame
count, if the hardware supports it.

Change-Id: I784d4f4e525212269371a40071bcb912181cba9f
Signed-off-by: Nilaan Gunabalachandran <quic_ngunabal@quicinc.com>
This commit is contained in:
Nilaan Gunabalachandran
2022-05-12 10:09:05 -04:00
committed by Gerrit - the friendly Code Review server
parent 875db134b3
commit 00369e3266
3 changed files with 26 additions and 2 deletions

View File

@@ -2380,6 +2380,9 @@ static int sde_intf_parse_dt(struct device_node *np,
set_bit(SDE_INTF_MDP_VSYNC_TS, &intf->features);
set_bit(SDE_INTF_WD_JITTER, &intf->features);
}
if (SDE_HW_MAJOR(sde_cfg->hw_rev) >= SDE_HW_MAJOR(SDE_HW_VER_A00))
set_bit(SDE_INTF_MDP_VSYNC_FC, &intf->features);
}
end:

View File

@@ -584,6 +584,7 @@ enum {
* @SDE_INTF_RESET_COUNTER INTF block has frame/line counter reset support
* @SDE_INTF_PANEL_VSYNC_TS INTF block has panel vsync timestamp logged
* @SDE_INTF_MDP_VSYNC_TS INTF block has mdp vsync timestamp logged
* @SDE_INTF_MDP_VSYNC_FC INTF block has mdp vsync frame counter
* @SDE_INTF_AVR_STATUS INTF block has AVR_STATUS field in AVR_CONTROL register
* @SDE_INTF_WD_JITTER INTF block has WD timer jitter support
* @SDE_INTF_MAX
@@ -597,6 +598,7 @@ enum {
SDE_INTF_RESET_COUNTER,
SDE_INTF_PANEL_VSYNC_TS,
SDE_INTF_MDP_VSYNC_TS,
SDE_INTF_MDP_VSYNC_FC,
SDE_INTF_AVR_STATUS,
SDE_INTF_WD_JITTER,
SDE_INTF_MAX

View File

@@ -40,6 +40,7 @@
#define INTF_DISPLAY_DATA_HCTL 0x064
#define INTF_ACTIVE_DATA_HCTL 0x068
#define INTF_FRAME_LINE_COUNT_EN 0x0A8
#define INTF_MDP_FRAME_COUNT 0x0A4
#define INTF_FRAME_COUNT 0x0AC
#define INTF_LINE_COUNT 0x0B0
@@ -541,6 +542,24 @@ static void sde_hw_intf_bind_pingpong_blk(
SDE_REG_WRITE(c, INTF_MUX, mux_cfg);
}
static u32 sde_hw_intf_get_frame_count(struct sde_hw_intf *intf)
{
struct sde_hw_blk_reg_map *c = &intf->hw;
bool en;
/*
* MDP VSync Frame Count is enabled with programmable fetch
* or with auto-refresh enabled.
*/
en = (SDE_REG_READ(c, INTF_TEAR_AUTOREFRESH_CONFIG) & BIT(31)) |
(SDE_REG_READ(c, INTF_CONFIG) & BIT(31));
if (en && (intf->cap->features & BIT(SDE_INTF_MDP_VSYNC_FC)))
return SDE_REG_READ(c, INTF_MDP_FRAME_COUNT);
else
return SDE_REG_READ(c, INTF_FRAME_COUNT);
}
static void sde_hw_intf_get_status(
struct sde_hw_intf *intf,
struct intf_status *s)
@@ -566,7 +585,7 @@ static void sde_hw_intf_v1_get_status(
s->is_en = SDE_REG_READ(c, INTF_STATUS) & BIT(0);
s->is_prog_fetch_en = (SDE_REG_READ(c, INTF_CONFIG) & BIT(31));
if (s->is_en) {
s->frame_count = SDE_REG_READ(c, INTF_FRAME_COUNT);
s->frame_count = sde_hw_intf_get_frame_count(intf);
s->line_count = SDE_REG_READ(c, INTF_LINE_COUNT) & 0xffff;
} else {
s->line_count = 0;
@@ -826,7 +845,7 @@ static int sde_hw_intf_get_vsync_info(struct sde_hw_intf *intf,
val = SDE_REG_READ(c, INTF_TEAR_LINE_COUNT);
info->wr_ptr_line_count = val & 0xffff;
val = SDE_REG_READ(c, INTF_FRAME_COUNT);
val = sde_hw_intf_get_frame_count(intf);
info->intf_frame_count = val;
return 0;