Merge "msm: sde: Avoid VBIF programming when SDE rotator is still busy" into msm-4.8
diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_base.c b/drivers/media/platform/msm/sde/rotator/sde_rotator_base.c
index 68d09c6..34243e6 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_base.c
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_base.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, 2015-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012, 2015-2017, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -30,6 +30,7 @@
 #include "sde_rotator_base.h"
 #include "sde_rotator_util.h"
 #include "sde_rotator_trace.h"
+#include "sde_rotator_debug.h"
 
 static inline u64 fudge_factor(u64 val, u32 numer, u32 denom)
 {
@@ -217,6 +218,8 @@ static u32 get_ot_limit(u32 reg_off, u32 bit_off,
 
 exit:
 	SDEROT_DBG("ot_lim=%d\n", ot_lim);
+	SDEROT_EVTLOG(params->width, params->height, params->fmt, params->fps,
+			ot_lim);
 	return ot_lim;
 }
 
@@ -228,6 +231,7 @@ void sde_mdp_set_ot_limit(struct sde_mdp_set_ot_params *params)
 		params->reg_off_vbif_lim_conf;
 	u32 bit_off_vbif_lim_conf = (params->xin_id % 4) * 8;
 	u32 reg_val;
+	u32 sts;
 	bool forced_on;
 
 	ot_lim = get_ot_limit(
@@ -238,6 +242,16 @@ void sde_mdp_set_ot_limit(struct sde_mdp_set_ot_params *params)
 	if (ot_lim == 0)
 		goto exit;
 
+	if (params->rotsts_base && params->rotsts_busy_mask) {
+		sts = readl_relaxed(params->rotsts_base);
+		if (sts & params->rotsts_busy_mask) {
+			SDEROT_ERR(
+				"Rotator still busy, should not modify VBIF\n");
+			SDEROT_EVTLOG_TOUT_HANDLER(
+				"rot", "vbif_dbg_bus", "panic");
+		}
+	}
+
 	trace_rot_perf_set_ot(params->num, params->xin_id, ot_lim);
 
 	forced_on = force_on_xin_clk(params->bit_off_mdp_clk_ctrl,
@@ -263,6 +277,7 @@ void sde_mdp_set_ot_limit(struct sde_mdp_set_ot_params *params)
 		force_on_xin_clk(params->bit_off_mdp_clk_ctrl,
 			params->reg_off_mdp_clk_ctrl, false);
 
+	SDEROT_EVTLOG(params->num, params->xin_id, ot_lim);
 exit:
 	return;
 }
diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_base.h b/drivers/media/platform/msm/sde/rotator/sde_rotator_base.h
index c04e71f..a7c1e89 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_base.h
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_base.h
@@ -39,6 +39,8 @@ struct sde_mdp_set_ot_params {
 	u32 reg_off_vbif_lim_conf;
 	u32 reg_off_mdp_clk_ctrl;
 	u32 bit_off_mdp_clk_ctrl;
+	char __iomem *rotsts_base;
+	u32 rotsts_busy_mask;
 };
 
 enum sde_bus_vote_type {
diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_core.c b/drivers/media/platform/msm/sde/rotator/sde_rotator_core.c
index 6f41c6a..7469178 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_core.c
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_core.c
@@ -1237,14 +1237,16 @@ static int sde_rotator_calc_perf(struct sde_rot_mgr *mgr,
 
 	perf->rdot_limit = sde_mdp_get_ot_limit(
 			config->input.width, config->input.height,
-			config->input.format, max_fps, true);
+			config->input.format, config->frame_rate, true);
 	perf->wrot_limit = sde_mdp_get_ot_limit(
 			config->input.width, config->input.height,
-			config->input.format, max_fps, false);
+			config->input.format, config->frame_rate, false);
 
 	SDEROT_DBG("clk:%lu, rdBW:%d, wrBW:%d, rdOT:%d, wrOT:%d\n",
 			perf->clk_rate, read_bw, write_bw, perf->rdot_limit,
 			perf->wrot_limit);
+	SDEROT_EVTLOG(perf->clk_rate, read_bw, write_bw, perf->rdot_limit,
+			perf->wrot_limit);
 	return 0;
 }
 
diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_r1_pipe.c b/drivers/media/platform/msm/sde/rotator/sde_rotator_r1_pipe.c
index 3d84389..5f886d7 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_r1_pipe.c
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_r1_pipe.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, 2015-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012, 2015-2017, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -350,7 +350,7 @@ static int sde_mdp_src_addr_setup(struct sde_mdp_pipe *pipe,
 
 static void sde_mdp_set_ot_limit_pipe(struct sde_mdp_pipe *pipe)
 {
-	struct sde_mdp_set_ot_params ot_params;
+	struct sde_mdp_set_ot_params ot_params = {0,};
 
 	ot_params.xin_id = pipe->xin_id;
 	ot_params.num = pipe->num;
diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_r1_wb.c b/drivers/media/platform/msm/sde/rotator/sde_rotator_r1_wb.c
index f9dc341..863dfb0 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_r1_wb.c
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_r1_wb.c
@@ -402,7 +402,7 @@ static int sde_mdp_wb_wait4comp(struct sde_mdp_ctl *ctl, void *arg)
 
 static void sde_mdp_set_ot_limit_wb(struct sde_mdp_writeback_ctx *ctx)
 {
-	struct sde_mdp_set_ot_params ot_params;
+	struct sde_mdp_set_ot_params ot_params = {0,};
 
 	ot_params.xin_id = ctx->xin_id;
 	ot_params.num = ctx->wb_num;
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 e8ace9e..04a90e3 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c
@@ -339,6 +339,8 @@ static void sde_hw_rotator_disable_irq(struct sde_hw_rotator *rot)
  */
 static void sde_hw_rotator_dump_status(struct sde_hw_rotator *rot)
 {
+	struct sde_rot_data_type *mdata = sde_rot_get_mdata();
+
 	SDEROT_ERR(
 		"op_mode = %x, int_en = %x, int_status = %x\n",
 		SDE_ROTREG_READ(rot->mdss_base,
@@ -370,6 +372,10 @@ static void sde_hw_rotator_dump_status(struct sde_hw_rotator *rot)
 		"UBWC decode status = %x, UBWC encode status = %x\n",
 		SDE_ROTREG_READ(rot->mdss_base, ROT_SSPP_UBWC_ERROR_STATUS),
 		SDE_ROTREG_READ(rot->mdss_base, ROT_WB_UBWC_ERROR_STATUS));
+
+	SDEROT_ERR("VBIF XIN HALT status = %x VBIF AXI HALT status = %x\n",
+		SDE_VBIF_READ(mdata, MMSS_VBIF_XIN_HALT_CTRL1),
+		SDE_VBIF_READ(mdata, MMSS_VBIF_AXI_HALT_CTRL1));
 }
 
 /**
@@ -1689,7 +1695,8 @@ static int sde_hw_rotator_config(struct sde_rot_hw_resource *hw,
 			item->input.width, item->input.height,
 			item->output.width, item->output.height,
 			entry->src_buf.p[0].addr, entry->dst_buf.p[0].addr,
-			item->input.format, item->output.format);
+			item->input.format, item->output.format,
+			entry->perf->config.frame_rate);
 
 	if (mdata->default_ot_rd_limit) {
 		struct sde_mdp_set_ot_params ot_params;
@@ -1708,6 +1715,8 @@ static int sde_hw_rotator_config(struct sde_rot_hw_resource *hw,
 		ot_params.fmt = ctx->is_traffic_shaping ?
 			SDE_PIX_FMT_ABGR_8888 :
 			entry->perf->config.input.format;
+		ot_params.rotsts_base = rot->mdss_base + ROTTOP_STATUS;
+		ot_params.rotsts_busy_mask = ROT_BUSY_BIT;
 		sde_mdp_set_ot_limit(&ot_params);
 	}
 
@@ -1728,6 +1737,8 @@ static int sde_hw_rotator_config(struct sde_rot_hw_resource *hw,
 		ot_params.fmt = ctx->is_traffic_shaping ?
 			SDE_PIX_FMT_ABGR_8888 :
 			entry->perf->config.input.format;
+		ot_params.rotsts_base = rot->mdss_base + ROTTOP_STATUS;
+		ot_params.rotsts_busy_mask = ROT_BUSY_BIT;
 		sde_mdp_set_ot_limit(&ot_params);
 	}