platform: msm_shared: optimize MDP3 panic Lut setting

Program panic Lut values based on panel resolution.
This will improve UI response time on low resolution devices.

Change-Id: Ic98454ad138dc98fa3af06d3f22ccebdc9744102
diff --git a/platform/msm8909/include/platform/iomap.h b/platform/msm8909/include/platform/iomap.h
index bca7c54..2f0ca98 100644
--- a/platform/msm8909/include/platform/iomap.h
+++ b/platform/msm8909/include/platform/iomap.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2015, 2017, The Linux Foundation. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -206,6 +206,7 @@
 #define MDP_DMA_P_WATERMARK_2       REG_MDP(0x9009C)
 #define MDP_PANIC_ROBUST_CTRL       REG_MDP(0x900A0)
 #define MDP_PANIC_LUT0              REG_MDP(0x900A4)
+#define MDP_PANIC_LUT1              REG_MDP(0x900A8)
 #define MDP_ROBUST_LUT              REG_MDP(0x900AC)
 
 #define MDP_DSI_VIDEO_EN                 REG_MDP(0xF0000)
diff --git a/platform/msm_shared/mdp3.c b/platform/msm_shared/mdp3.c
index 5a8a848..1014b45 100644
--- a/platform/msm_shared/mdp3.c
+++ b/platform/msm_shared/mdp3.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2015, 2017, The Linux Foundation. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -35,8 +35,48 @@
 #include <platform/timer.h>
 #include <platform/iomap.h>
 
+#define BIT(bit) (1 << (bit))
 static int mdp_rev;
 
+/**
+ * mdp3_get_panic_lut_cfg() - calculate panic and robust lut mask
+ * @panel_width: Panel width
+ *
+ * DMA buffer has 16 fill levels. Which needs to configured as safe
+ * and panic levels based on panel resolutions.
+ * No. of fill levels used = ((panel active width * 8) / 512).
+ * Roundoff the use fill levels if needed.
+ * half of the total fill levels used will be treated as panic levels.
+ * Roundoff panic levels if total used fill levels are odd.
+ *
+ * Sample calculation for 720p display:
+ * Fill levels used = (720 * 8) / 512 = 12.5 after round off 13.
+ * panic levels = 13 / 2 = 6.5 after roundoff 7.
+ * Panic mask = 0x3FFF  (2 bits per level)
+ * Robust mask = 0xFF80 (1 bit per level)
+ */
+unsigned long long mdp3_get_panic_lut_cfg(int panel_width)
+{
+	unsigned int fill_levels = (((panel_width * 8) / 512) + 1);
+	unsigned int panic_mask = 0;
+	unsigned int robust_mask = 0;
+	int i = 0;
+	unsigned long long panic_config = 0;
+	int panic_levels = 0;
+
+	panic_levels = fill_levels/2;
+	if (fill_levels % 2)
+		panic_levels++;
+	for (i = 0; i < panic_levels; i++) {
+		panic_mask |= (BIT((i * 2) + 1) | BIT(i * 2));
+		robust_mask |= BIT(i);
+	}
+	panic_config = (~robust_mask);
+	panic_config = panic_config << 32;
+	panic_config |= panic_mask;
+	return panic_config;
+}
+
 int mdp_dsi_video_config(struct msm_panel_info *pinfo,
 		struct fbcon_config *fb)
 {
@@ -46,6 +86,7 @@
 	struct lcdc_panel_info *lcdc = NULL;
 	int ystride = 3;
 	int mdp_rev = mdp_get_revision();
+	unsigned long long panic_config = mdp3_get_panic_lut_cfg(pinfo->xres);
 
 	if (pinfo == NULL)
 		return ERR_INVALID_ARGS;
@@ -71,16 +112,14 @@
 	writel(0x0, MDP_DMA_P_WATERMARK_0);
 	writel(0x0, MDP_DMA_P_WATERMARK_1);
 	writel(0x0, MDP_DMA_P_WATERMARK_2);
-	if (pinfo->xres >= 720) {
-		writel(0xFFFF, MDP_PANIC_LUT0);
-		writel(0xFF00, MDP_ROBUST_LUT);
-	} else {
-		writel(0x00FF, MDP_PANIC_LUT0);
-		writel(0xFFF0, MDP_ROBUST_LUT);
-	}
-	writel(0x1, MDP_PANIC_ROBUST_CTRL);
-	writel(0xFF00, MDP_ROBUST_LUT);
 
+	writel((panic_config & 0xFFFF), MDP_PANIC_LUT0);
+	writel(((panic_config >> 16) & 0xFFFF) , MDP_PANIC_LUT1);
+	writel(((panic_config >> 32) & 0xFFFF), MDP_ROBUST_LUT);
+	writel(0x1, MDP_PANIC_ROBUST_CTRL);
+	dprintf(INFO, "Panic Lut0 %x Lut1 %x Robest %x\n",
+		(panic_config & 0xFFFF), ((panic_config >> 16) & 0xFFFF),
+		((panic_config >> 32) & 0xFFFF));
 	// ------------- programming MDP_DMA_P_CONFIG ---------------------
 	writel(0x1800bf, MDP_DMA_P_CONFIG);	// rgb888
 
@@ -124,18 +163,25 @@
 	int ret = 0;
 	unsigned short pack_pattern = 0x21;
 	unsigned char ystride = 3;
+	unsigned long long panic_config = 0;
+
+	if (pinfo == NULL)
+		return ERR_INVALID_ARGS;
 
 	/* Program QOS remapper settings */
 	writel(0x1A9, MDP_DMA_P_QOS_REMAPPER);
 	writel(0x0, MDP_DMA_P_WATERMARK_0);
 	writel(0x0, MDP_DMA_P_WATERMARK_1);
 	writel(0x0, MDP_DMA_P_WATERMARK_2);
-	if (pinfo->xres >= 720)
-		writel(0xFFFF, MDP_PANIC_LUT0);
-	else
-		writel(0x00FF, MDP_PANIC_LUT0);
+
+	panic_config = mdp3_get_panic_lut_cfg(pinfo->xres);
+	writel((panic_config & 0xFFFF), MDP_PANIC_LUT0);
+	writel(((panic_config >> 16) & 0xFFFF) , MDP_PANIC_LUT1);
+	writel(((panic_config >> 32) & 0xFFFF), MDP_ROBUST_LUT);
 	writel(0x1, MDP_PANIC_ROBUST_CTRL);
-	writel(0xFF00, MDP_ROBUST_LUT);
+	dprintf(INFO, "Panic Lut0 %x Lut1 %x Robest %x\n",
+		(panic_config & 0xFFFF), ((panic_config >> 16) & 0xFFFF),
+		((panic_config >> 32) & 0xFFFF));
 
 	writel(0x03ffffff, MDP_INTR_ENABLE);