|
@@ -61,6 +61,9 @@
|
|
#define INTF_MISR_CTRL 0x180
|
|
#define INTF_MISR_CTRL 0x180
|
|
#define INTF_MISR_SIGNATURE 0x184
|
|
#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_CTL 0x230
|
|
#define INTF_WD_TIMER_0_CTL2 0x234
|
|
#define INTF_WD_TIMER_0_CTL2 0x234
|
|
#define INTF_WD_TIMER_0_LOAD_VALUE 0x238
|
|
#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));
|
|
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,
|
|
static void sde_hw_intf_setup_timing_engine(struct sde_hw_intf *ctx,
|
|
const struct intf_timing_params *p,
|
|
const struct intf_timing_params *p,
|
|
const struct sde_format *fmt)
|
|
const struct sde_format *fmt)
|
|
@@ -378,8 +395,12 @@ static void sde_hw_intf_enable_timing_engine(
|
|
u8 enable)
|
|
u8 enable)
|
|
{
|
|
{
|
|
struct sde_hw_blk_reg_map *c = &intf->hw;
|
|
struct sde_hw_blk_reg_map *c = &intf->hw;
|
|
|
|
+
|
|
/* Note: Display interface select is handled in top block hw layer */
|
|
/* Note: Display interface select is handled in top block hw layer */
|
|
SDE_REG_WRITE(c, INTF_TIMING_ENGINE_EN, enable != 0);
|
|
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(
|
|
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;
|
|
struct sde_hw_blk_reg_map *c = &intf->hw;
|
|
|
|
|
|
s->is_en = SDE_REG_READ(c, INTF_STATUS) & BIT(0);
|
|
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) {
|
|
if (s->is_en) {
|
|
s->frame_count = SDE_REG_READ(c, INTF_FRAME_COUNT);
|
|
s->frame_count = SDE_REG_READ(c, INTF_FRAME_COUNT);
|
|
s->line_count = SDE_REG_READ(c, INTF_LINE_COUNT) & 0xffff;
|
|
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;
|
|
c = &intf->hw;
|
|
SDE_REG_WRITE(c, INTF_TEAR_TEAR_CHECK_EN, enable);
|
|
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;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -857,6 +883,9 @@ static void _setup_intf_ops(struct sde_hw_intf_ops *ops,
|
|
|
|
|
|
if (cap & BIT(SDE_INTF_RESET_COUNTER))
|
|
if (cap & BIT(SDE_INTF_RESET_COUNTER))
|
|
ops->reset_counter = sde_hw_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 = {
|
|
static struct sde_hw_blk_ops sde_hw_ops = {
|