drm/msm/sde: detect ppdone timeouts and issue ctl reset

Add mechanism to detect pingpong done irq timeouts and report
back to CRTC that errors occurred. On reception of a max count
report panel dead event to the CRTC, which currently logs it.
If panic is enabled, ppdone timeout will trigger a register dump
and panic, if panic is not enabled, we try to recover by issuing
a CTL reset before the next kickoff.

CRs-Fixed: 2005394
Change-Id: I375c18da40754b879829df50c28ed56e4775cb38
Signed-off-by: Lloyd Atkinson <latkinso@codeaurora.org>
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c
index cc8485b..e9fe5c0 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c
@@ -1685,6 +1685,19 @@
 	return rc;
 }
 
+int dsi_ctrl_soft_reset(struct dsi_ctrl *dsi_ctrl)
+{
+	if (!dsi_ctrl)
+		return -EINVAL;
+
+	mutex_lock(&dsi_ctrl->ctrl_lock);
+	dsi_ctrl->hw.ops.soft_reset(&dsi_ctrl->hw);
+	mutex_unlock(&dsi_ctrl->ctrl_lock);
+
+	pr_debug("[DSI_%d]Soft reset complete\n", dsi_ctrl->index);
+	return 0;
+}
+
 /**
  * dsi_ctrl_host_deinit() - De-Initialize DSI host hardware.
  * @dsi_ctrl:        DSI controller handle.
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.h b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.h
index 1df09b4..fc95a9a 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.h
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.h
@@ -329,6 +329,21 @@
 int dsi_ctrl_phy_reset_config(struct dsi_ctrl *dsi_ctrl, bool enable);
 
 /**
+ * dsi_ctrl_soft_reset() - perform a soft reset on DSI controller
+ * @dsi_ctrl:         DSI controller handle.
+ *
+ * The video, command and controller engines will be disabled before the
+ * reset is triggered. After, the engines will be re-enabled to the same state
+ * as before the reset.
+ *
+ * If the reset is done while MDP timing engine is turned on, the video
+ * engine should be re-enabled only during the vertical blanking time.
+ *
+ * Return: error code
+ */
+int dsi_ctrl_soft_reset(struct dsi_ctrl *dsi_ctrl);
+
+/**
  * dsi_ctrl_host_init() - Initialize DSI host hardware.
  * @dsi_ctrl:        DSI controller handle.
  *
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw.h b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw.h
index 009795a..89c5cda 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw.h
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw.h
@@ -346,12 +346,12 @@
 	 * soft_reset() - perform a soft reset on DSI controller
 	 * @ctrl:          Pointer to the controller host hardware.
 	 *
-	 * The video, command and controller engines will be disable before the
-	 * reset is triggered. These engines will not be enabled after the reset
-	 * is complete. Caller must re-enable the engines.
+	 * The video, command and controller engines will be disabled before the
+	 * reset is triggered. After, the engines will be re-enabled to the same
+	 * state as before the reset.
 	 *
 	 * If the reset is done while MDP timing engine is turned on, the video
-	 * enigne should be re-enabled only during the vertical blanking time.
+	 * engine should be re-enabled only during the vertical blanking time.
 	 */
 	void (*soft_reset)(struct dsi_ctrl_hw *ctrl);
 
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_display.c b/drivers/gpu/drm/msm/dsi-staging/dsi_display.c
index e87c3d3..9b2e3a7 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_display.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_display.c
@@ -56,6 +56,30 @@
 	return rc;
 }
 
+int dsi_display_soft_reset(void *display)
+{
+	struct dsi_display *dsi_display;
+	struct dsi_display_ctrl *ctrl;
+	int rc = 0;
+	int i;
+
+	if (!display)
+		return -EINVAL;
+
+	dsi_display = display;
+
+	for (i = 0 ; i < dsi_display->ctrl_count; i++) {
+		ctrl = &dsi_display->ctrl[i];
+		rc = dsi_ctrl_soft_reset(ctrl->ctrl);
+		if (rc) {
+			pr_err("[%s] failed to soft reset host_%d, rc=%d\n",
+					dsi_display->name, i, rc);
+			break;
+		}
+	}
+
+	return rc;
+}
 static ssize_t debugfs_dump_info_read(struct file *file,
 				      char __user *buff,
 				      size_t count,
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_display.h b/drivers/gpu/drm/msm/dsi-staging/dsi_display.h
index 563c525..642ea40 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_display.h
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_display.h
@@ -391,4 +391,19 @@
 int dsi_dispaly_static_frame(struct dsi_display *display, bool enable);
 
 int dsi_display_set_backlight(void *display, u32 bl_lvl);
+
+/**
+ * dsi_display_soft_reset() - perform a soft reset on DSI controller
+ * @display:         Handle to display
+ *
+ * The video, command and controller engines will be disabled before the
+ * reset is triggered. After, the engines will be re-enabled to the same state
+ * as before the reset.
+ *
+ * If the reset is done while MDP timing engine is turned on, the video
+ * engine should be re-enabled only during the vertical blanking time.
+ *
+ * Return: error code
+ */
+int dsi_display_soft_reset(void *display);
 #endif /* _DSI_DISPLAY_H_ */