summaryrefslogtreecommitdiff
path: root/drivers/media
diff options
context:
space:
mode:
authorBenjamin Chan <bkchan@codeaurora.org>2017-02-14 17:39:32 -0500
committerBenjamin Chan <bkchan@codeaurora.org>2017-02-15 12:00:35 -0500
commit432ea6de2e50c7065ebefb25f5363564b4c310ea (patch)
tree979b9187aa9e96a2abe4e12c5f2ee67038d262da /drivers/media
parent3a7e752617514960c5cecdf84e12b13dc63c04c7 (diff)
msm: sde: Fix SW timestamp initialization when missing power event
Under some cases, the PM event is missing, and rotator driver will not initialize the SW timestamp. This change is to add rotator reset detection logic and auto initialize the SW timestamp register if such happened. CRs-Fixed: 2006856 Change-Id: I8c889435e0be1518a6ec2dd6f9c7b02d140df9f1 Signed-off-by: Benjamin Chan <bkchan@codeaurora.org>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c37
-rw-r--r--drivers/media/platform/msm/sde/rotator/sde_rotator_r3_hwio.h1
2 files changed, 38 insertions, 0 deletions
diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c b/drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c
index d7fb167ab49f..0003fcf8a637 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c
@@ -1602,6 +1602,7 @@ static int sde_hw_rotator_config(struct sde_rot_hw_resource *hw,
u32 danger_lut = 0; /* applicable for realtime client only */
u32 safe_lut = 0; /* applicable for realtime client only */
u32 flags = 0;
+ u32 rststs = 0;
struct sde_rotation_item *item;
if (!hw || !entry) {
@@ -1619,10 +1620,46 @@ static int sde_hw_rotator_config(struct sde_rot_hw_resource *hw,
return -EINVAL;
}
+ /*
+ * if Rotator HW is reset, but missing PM event notification, we
+ * need to init the SW timestamp automatically.
+ */
+ rststs = SDE_ROTREG_READ(rot->mdss_base, REGDMA_RESET_STATUS_REG);
+ if (!rot->reset_hw_ts && rststs) {
+ u32 l_ts, h_ts, swts;
+
+ swts = SDE_ROTREG_READ(rot->mdss_base, REGDMA_TIMESTAMP_REG);
+ h_ts = atomic_read(&rot->timestamp[ROT_QUEUE_HIGH_PRIORITY]);
+ l_ts = atomic_read(&rot->timestamp[ROT_QUEUE_LOW_PRIORITY]);
+ SDEROT_EVTLOG(0xbad0, rststs, swts, h_ts, l_ts);
+
+ if (ctx->q_id == ROT_QUEUE_HIGH_PRIORITY)
+ h_ts = (h_ts - 1) & SDE_REGDMA_SWTS_MASK;
+ else
+ l_ts = (l_ts - 1) & SDE_REGDMA_SWTS_MASK;
+
+ /* construct the combined timstamp */
+ swts = (h_ts & SDE_REGDMA_SWTS_MASK) |
+ ((l_ts & SDE_REGDMA_SWTS_MASK) <<
+ SDE_REGDMA_SWTS_SHIFT);
+
+ SDEROT_DBG("swts:0x%x, h_ts:0x%x, l_ts;0x%x\n",
+ swts, h_ts, l_ts);
+ SDEROT_EVTLOG(0x900d, swts, h_ts, l_ts);
+ rot->last_hw_ts = swts;
+
+ SDE_ROTREG_WRITE(rot->mdss_base, REGDMA_TIMESTAMP_REG,
+ rot->last_hw_ts);
+ SDE_ROTREG_WRITE(rot->mdss_base, REGDMA_RESET_STATUS_REG, 0);
+ /* ensure write is issued to the rotator HW */
+ wmb();
+ }
+
if (rot->reset_hw_ts) {
SDEROT_EVTLOG(rot->last_hw_ts);
SDE_ROTREG_WRITE(rot->mdss_base, REGDMA_TIMESTAMP_REG,
rot->last_hw_ts);
+ SDE_ROTREG_WRITE(rot->mdss_base, REGDMA_RESET_STATUS_REG, 0);
/* ensure write is issued to the rotator HW */
wmb();
rot->reset_hw_ts = false;
diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_r3_hwio.h b/drivers/media/platform/msm/sde/rotator/sde_rotator_r3_hwio.h
index fedade122b88..b721ec54229d 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_r3_hwio.h
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_r3_hwio.h
@@ -277,5 +277,6 @@
#define REGDMA_INT_LOW_MASK 0x00000700
#define REGDMA_INT_ERR_MASK 0x000F0000
#define REGDMA_TIMESTAMP_REG ROT_SSPP_TPG_PATTERN_GEN_INIT_VAL
+#define REGDMA_RESET_STATUS_REG ROT_SSPP_TPG_RGB_MAPPING
#endif /*_SDE_ROTATOR_R3_HWIO_H */