disp: msm: sde: enable support to get accurate vsync timestamp

From MDSS 8.x, vsync timestamp counter register is added in all the
interfaces. Add interface to get the vsync counter and use the global
qtmr reference counter to get the counter delta. This can be used
with reference to the curret ktime to deduce the accurate vsync
timestamp. This utility is intended to be used for setting the vblank
and retire fence timestamps which would be notified to user-mode.

Change-Id: I608a284c035cda50053eedbb311f1f54b3d3d557
Signed-off-by: Veera Sundaram Sankaran <veeras@codeaurora.org>
This commit is contained in:
Veera Sundaram Sankaran
2020-09-21 12:52:04 -07:00
父節點 9ad90a834d
當前提交 b554f01a10
共有 6 個文件被更改,包括 113 次插入0 次删除

查看文件

@@ -61,6 +61,9 @@
#define INTF_MISR_CTRL 0x180
#define INTF_MISR_SIGNATURE 0x184
#define INTF_VSYNC_TIMESTAMP_CTRL 0x210
#define INTF_VSYNC_TIMESTAMP0 0x214
#define INTF_VSYNC_TIMESTAMP1 0x218
#define INTF_WD_TIMER_0_CTL 0x230
#define INTF_WD_TIMER_0_CTL2 0x234
#define INTF_WD_TIMER_0_LOAD_VALUE 0x238
@@ -199,6 +202,20 @@ static void sde_hw_intf_reset_counter(struct sde_hw_intf *ctx)
SDE_REG_WRITE(c, INTF_LINE_COUNT, BIT(31));
}
static u64 sde_hw_intf_get_vsync_timestamp(struct sde_hw_intf *ctx)
{
struct sde_hw_blk_reg_map *c = &ctx->hw;
u32 timestamp_lo, timestamp_hi;
u64 timestamp = 0;
timestamp_hi = SDE_REG_READ(c, INTF_VSYNC_TIMESTAMP1);
timestamp_lo = SDE_REG_READ(c, INTF_VSYNC_TIMESTAMP0);
timestamp = timestamp_hi;
timestamp = (timestamp << 32) | timestamp_lo;
return timestamp;
}
static void sde_hw_intf_setup_timing_engine(struct sde_hw_intf *ctx,
const struct intf_timing_params *p,
const struct sde_format *fmt)
@@ -378,8 +395,12 @@ static void sde_hw_intf_enable_timing_engine(
u8 enable)
{
struct sde_hw_blk_reg_map *c = &intf->hw;
/* Note: Display interface select is handled in top block hw layer */
SDE_REG_WRITE(c, INTF_TIMING_ENGINE_EN, enable != 0);
if (enable && (intf->cap->features & BIT(SDE_INTF_VSYNC_TIMESTAMP)))
SDE_REG_WRITE(c, INTF_VSYNC_TIMESTAMP_CTRL, BIT(0));
}
static void sde_hw_intf_setup_prg_fetch(
@@ -479,6 +500,7 @@ static void sde_hw_intf_v1_get_status(
struct sde_hw_blk_reg_map *c = &intf->hw;
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->line_count = SDE_REG_READ(c, INTF_LINE_COUNT) & 0xffff;
@@ -669,6 +691,10 @@ static int sde_hw_intf_enable_te(struct sde_hw_intf *intf, bool enable)
c = &intf->hw;
SDE_REG_WRITE(c, INTF_TEAR_TEAR_CHECK_EN, enable);
if (enable && (intf->cap->features & BIT(SDE_INTF_VSYNC_TIMESTAMP)))
SDE_REG_WRITE(c, INTF_VSYNC_TIMESTAMP_CTRL, BIT(0));
return 0;
}
@@ -857,6 +883,9 @@ static void _setup_intf_ops(struct sde_hw_intf_ops *ops,
if (cap & BIT(SDE_INTF_RESET_COUNTER))
ops->reset_counter = sde_hw_intf_reset_counter;
if (cap & BIT(SDE_INTF_VSYNC_TIMESTAMP))
ops->get_vsync_timestamp = sde_hw_intf_get_vsync_timestamp;
}
static struct sde_hw_blk_ops sde_hw_ops = {