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:
@@ -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 = {
|
||||
|
Reference in New Issue
Block a user