msm: sde: cleanup format validation for sbuf mode

Add rotator operating mode to format validation logic
and define h/w version specific format table for each
operating mode. Update base format lookup table for
missing rgb565/rgb ubwc/rgb565 tile to rgb565 tile.

Change-Id: I0146fdd9423114903f40873d4a0e10c19ca8e38a
Signed-off-by: Alan Kwong <akwong@codeaurora.org>
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 9d10b06..f4a771b 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_core.c
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_core.c
@@ -11,7 +11,7 @@
  *
  */
 
-#define pr_fmt(fmt)	"%s: " fmt, __func__
+#define pr_fmt(fmt)	"%s:%d: " fmt, __func__, __LINE__
 
 #include <linux/platform_device.h>
 #include <linux/module.h>
@@ -1652,18 +1652,20 @@
 
 static bool sde_rotator_verify_format(struct sde_rot_mgr *mgr,
 	struct sde_mdp_format_params *in_fmt,
-	struct sde_mdp_format_params *out_fmt, bool rotation)
+	struct sde_mdp_format_params *out_fmt, bool rotation, u32 mode)
 {
 	u8 in_v_subsample, in_h_subsample;
 	u8 out_v_subsample, out_h_subsample;
 
-	if (!sde_rotator_is_valid_pixfmt(mgr, in_fmt->format, true)) {
-		SDEROT_ERR("Invalid input format %x\n", in_fmt->format);
+	if (!sde_rotator_is_valid_pixfmt(mgr, in_fmt->format, true, mode)) {
+		SDEROT_ERR("Invalid input format 0x%x (%4.4s)\n",
+				in_fmt->format, (char *)&in_fmt->format);
 		goto verify_error;
 	}
 
-	if (!sde_rotator_is_valid_pixfmt(mgr, out_fmt->format, false)) {
-		SDEROT_ERR("Invalid output format %x\n", out_fmt->format);
+	if (!sde_rotator_is_valid_pixfmt(mgr, out_fmt->format, false, mode)) {
+		SDEROT_ERR("Invalid output format 0x%x (%4.4s)\n",
+				out_fmt->format, (char *)&out_fmt->format);
 		goto verify_error;
 	}
 
@@ -1712,8 +1714,10 @@
 	return true;
 
 verify_error:
-	SDEROT_ERR("in_fmt=0x%x, out_fmt=0x%x\n",
-			in_fmt->format, out_fmt->format);
+	SDEROT_ERR("in_fmt=0x%x (%4.4s), out_fmt=0x%x (%4.4s), mode=%d\n",
+			in_fmt->format, (char *)&in_fmt->format,
+			out_fmt->format, (char *)&out_fmt->format,
+			mode);
 	return false;
 }
 
@@ -1832,6 +1836,7 @@
 {
 	struct sde_mdp_format_params *in_fmt, *out_fmt;
 	bool rotation;
+	u32 mode;
 
 	if (!mgr || !config) {
 		SDEROT_ERR("null parameters\n");
@@ -1840,6 +1845,9 @@
 
 	rotation = (config->flags & SDE_ROTATION_90) ? true : false;
 
+	mode = config->output.sbuf ? SDE_ROTATOR_MODE_SBUF :
+				SDE_ROTATOR_MODE_OFFLINE;
+
 	in_fmt = __verify_input_config(mgr, config);
 	if (!in_fmt)
 		return -EINVAL;
@@ -1848,7 +1856,7 @@
 	if (!out_fmt)
 		return -EINVAL;
 
-	if (!sde_rotator_verify_format(mgr, in_fmt, out_fmt, rotation)) {
+	if (!sde_rotator_verify_format(mgr, in_fmt, out_fmt, rotation, mode)) {
 		SDEROT_ERR(
 			"Rot format pairing invalid, in_fmt:0x%x, out_fmt:0x%x\n",
 					config->input.format,
diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_core.h b/drivers/media/platform/msm/sde/rotator/sde_rotator_core.h
index 731ff1e..3d368a1 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_core.h
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_core.h
@@ -141,6 +141,12 @@
 	SDE_ROTATOR_TRIGGER_COMMAND,
 };
 
+enum sde_rotator_mode {
+	SDE_ROTATOR_MODE_OFFLINE,
+	SDE_ROTATOR_MODE_SBUF,
+	SDE_ROTATOR_MODE_MAX,
+};
+
 struct sde_rotation_item {
 	/* rotation request flag */
 	uint32_t	flags;
@@ -463,9 +469,9 @@
 	int (*ops_hw_validate_entry)(struct sde_rot_mgr *mgr,
 			struct sde_rot_entry *entry);
 	u32 (*ops_hw_get_pixfmt)(struct sde_rot_mgr *mgr, int index,
-			bool input);
+			bool input, u32 mode);
 	int (*ops_hw_is_valid_pixfmt)(struct sde_rot_mgr *mgr, u32 pixfmt,
-			bool input);
+			bool input, u32 mode);
 	int (*ops_hw_get_downscale_caps)(struct sde_rot_mgr *mgr, char *caps,
 			int len);
 	int (*ops_hw_get_maxlinewidth)(struct sde_rot_mgr *mgr);
@@ -474,19 +480,19 @@
 };
 
 static inline int sde_rotator_is_valid_pixfmt(struct sde_rot_mgr *mgr,
-		u32 pixfmt, bool input)
+		u32 pixfmt, bool input, u32 mode)
 {
 	if (mgr && mgr->ops_hw_is_valid_pixfmt)
-		return mgr->ops_hw_is_valid_pixfmt(mgr, pixfmt, input);
+		return mgr->ops_hw_is_valid_pixfmt(mgr, pixfmt, input, mode);
 
 	return false;
 }
 
 static inline u32 sde_rotator_get_pixfmt(struct sde_rot_mgr *mgr,
-		int index, bool input)
+		int index, bool input, u32 mode)
 {
 	if (mgr && mgr->ops_hw_get_pixfmt)
-		return mgr->ops_hw_get_pixfmt(mgr, index, input);
+		return mgr->ops_hw_get_pixfmt(mgr, index, input, mode);
 
 	return 0;
 }
diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_dev.c b/drivers/media/platform/msm/sde/rotator/sde_rotator_dev.c
index 8727535..2867f21 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_dev.c
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_dev.c
@@ -9,7 +9,7 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  */
-#define pr_fmt(fmt)	"%s: " fmt, __func__
+#define pr_fmt(fmt)	"%s:%d: " fmt, __func__, __LINE__
 
 #include <linux/vmalloc.h>
 #include <linux/kernel.h>
@@ -1390,7 +1390,8 @@
 
 	sde_rot_mgr_lock(rot_dev->mgr);
 	for (i = 0;; i++) {
-		pixfmt = sde_rotator_get_pixfmt(rot_dev->mgr, i, input);
+		pixfmt = sde_rotator_get_pixfmt(rot_dev->mgr, i, input,
+				SDE_ROTATOR_MODE_SBUF);
 		if (!pixfmt)
 			break;
 		if (pixfmts && i < len)
@@ -1568,7 +1569,7 @@
 			ret = sde_rotator_session_config(rot_dev->mgr,
 					ctx->private, &rotcfg);
 			if (ret) {
-				SDEROT_ERR("fail session config s:%d\n",
+				SDEROT_WARN("fail session config s:%d\n",
 						ctx->session_id);
 				goto error_session_config;
 			}
@@ -1579,7 +1580,7 @@
 		ret = sde_rotator_validate_request(rot_dev->mgr, ctx->private,
 				req);
 		if (ret) {
-			SDEROT_ERR("fail validate request s:%d\n",
+			SDEROT_WARN("fail validate request s:%d\n",
 					ctx->session_id);
 			goto error_validate_request;
 		}
@@ -1805,7 +1806,8 @@
 	bool found = false;
 
 	for (i = 0, index = 0; index <= f->index; i++) {
-		pixfmt = sde_rotator_get_pixfmt(rot_dev->mgr, i, false);
+		pixfmt = sde_rotator_get_pixfmt(rot_dev->mgr, i, false,
+				SDE_ROTATOR_MODE_OFFLINE);
 		if (!pixfmt)
 			return -EINVAL;
 
@@ -1849,7 +1851,8 @@
 	bool found = false;
 
 	for (i = 0, index = 0; index <= f->index; i++) {
-		pixfmt = sde_rotator_get_pixfmt(rot_dev->mgr, i, true);
+		pixfmt = sde_rotator_get_pixfmt(rot_dev->mgr, i, true,
+				SDE_ROTATOR_MODE_OFFLINE);
 		if (!pixfmt)
 			return -EINVAL;
 
diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_formats.c b/drivers/media/platform/msm/sde/rotator/sde_rotator_formats.c
index 27e9ba6..7585a6b 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_formats.c
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_formats.c
@@ -850,6 +850,11 @@
 	case SDE_PIX_FMT_Y_CRCB_H2V2_TILE:
 		*dst_pixfmt = SDE_PIX_FMT_Y_CRCB_H2V2_TILE;
 		break;
+	case V4L2_PIX_FMT_RGB565:
+	case SDE_PIX_FMT_RGB_565_UBWC:
+	case SDE_PIX_FMT_RGB_565_TILE:
+		*dst_pixfmt = SDE_PIX_FMT_RGB_565_TILE;
+		break;
 	case SDE_PIX_FMT_RGBA_8888:
 	case SDE_PIX_FMT_RGBA_8888_UBWC:
 	case SDE_PIX_FMT_RGBA_8888_TILE:
diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_formats.h b/drivers/media/platform/msm/sde/rotator/sde_rotator_formats.h
index 5bb6198..545dcfc 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_formats.h
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_formats.h
@@ -37,6 +37,7 @@
 #define SDE_PIX_FMT_RGBA_1010102_TILE	v4l2_fourcc('Q', 'T', '1', '0')
 #define SDE_PIX_FMT_RGBX_1010102_TILE	v4l2_fourcc('Q', 'T', '1', '1')
 #define SDE_PIX_FMT_Y_CBCR_H2V2_P010_TILE	v4l2_fourcc('Q', 'T', '1', '2')
+#define SDE_PIX_FMT_RGB_565_TILE	v4l2_fourcc('Q', 'T', '1', '3')
 
 #define SDE_ROT_MAX_PLANES		4
 
diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_r1.c b/drivers/media/platform/msm/sde/rotator/sde_rotator_r1.c
index 9f4a854..1b4913b 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_r1.c
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_r1.c
@@ -501,9 +501,10 @@
  * @mgr: Pointer to rotator manager
  * @index: index of pixel format
  * @input: true for input port; false for output port
+ * @mode: operating mode
  */
 static u32 sde_hw_rotator_get_pixfmt(struct sde_rot_mgr *mgr,
-		int index, bool input)
+		int index, bool input, u32 mode)
 {
 	if (input) {
 		if (index < ARRAY_SIZE(sde_hw_rotator_input_pixfmts))
@@ -523,9 +524,10 @@
  * @mgr: Pointer to rotator manager
  * @pixfmt: pixel format to be verified
  * @input: true for input port; false for output port
+ * @mode: operating mode
  */
 static int sde_hw_rotator_is_valid_pixfmt(struct sde_rot_mgr *mgr, u32 pixfmt,
-		bool input)
+		bool input, u32 mode)
 {
 	int i;
 
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 205eeef..3c47dd7 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c
@@ -11,7 +11,7 @@
  *
  */
 
-#define pr_fmt(fmt)	"%s: " fmt, __func__
+#define pr_fmt(fmt)	"%s:%d: " fmt, __func__, __LINE__
 
 #include <linux/platform_device.h>
 #include <linux/module.h>
@@ -107,7 +107,7 @@
 #define SDE_ROTREG_READ(base, off) \
 	readl_relaxed(base + (off))
 
-static u32 sde_hw_rotator_v3_inpixfmts[] = {
+static const u32 sde_hw_rotator_v3_inpixfmts[] = {
 	SDE_PIX_FMT_XRGB_8888,
 	SDE_PIX_FMT_ARGB_8888,
 	SDE_PIX_FMT_ABGR_8888,
@@ -167,7 +167,7 @@
 	SDE_PIX_FMT_Y_CBCR_H2V2_TP10_UBWC,
 };
 
-static u32 sde_hw_rotator_v3_outpixfmts[] = {
+static const u32 sde_hw_rotator_v3_outpixfmts[] = {
 	SDE_PIX_FMT_XRGB_8888,
 	SDE_PIX_FMT_ARGB_8888,
 	SDE_PIX_FMT_ABGR_8888,
@@ -227,7 +227,7 @@
 	SDE_PIX_FMT_Y_CBCR_H2V2_TP10_UBWC,
 };
 
-static u32 sde_hw_rotator_v4_inpixfmts[] = {
+static const u32 sde_hw_rotator_v4_inpixfmts[] = {
 	SDE_PIX_FMT_XRGB_8888,
 	SDE_PIX_FMT_ARGB_8888,
 	SDE_PIX_FMT_ABGR_8888,
@@ -307,7 +307,7 @@
 	SDE_PIX_FMT_XBGR_2101010_TILE,
 };
 
-static u32 sde_hw_rotator_v4_outpixfmts[] = {
+static const u32 sde_hw_rotator_v4_outpixfmts[] = {
 	SDE_PIX_FMT_XRGB_8888,
 	SDE_PIX_FMT_ARGB_8888,
 	SDE_PIX_FMT_ABGR_8888,
@@ -387,6 +387,23 @@
 	SDE_PIX_FMT_XBGR_2101010_TILE,
 };
 
+static const u32 sde_hw_rotator_v4_inpixfmts_sbuf[] = {
+	SDE_PIX_FMT_Y_CBCR_H2V2_P010,
+	SDE_PIX_FMT_Y_CBCR_H2V2,
+	SDE_PIX_FMT_Y_CBCR_H2V2_TP10_UBWC,
+	SDE_PIX_FMT_Y_CBCR_H2V2_P010_UBWC,
+	SDE_PIX_FMT_Y_CBCR_H2V2_UBWC,
+	SDE_PIX_FMT_Y_CBCR_H2V2_TP10,
+	SDE_PIX_FMT_Y_CBCR_H2V2_P010_TILE,
+	SDE_PIX_FMT_Y_CBCR_H2V2_TILE,
+};
+
+static const u32 sde_hw_rotator_v4_outpixfmts_sbuf[] = {
+	SDE_PIX_FMT_Y_CBCR_H2V2_TP10,
+	SDE_PIX_FMT_Y_CBCR_H2V2_P010_TILE,
+	SDE_PIX_FMT_Y_CBCR_H2V2_TILE,
+};
+
 static struct sde_rot_vbif_debug_bus nrt_vbif_dbg_bus_r3[] = {
 	{0x214, 0x21c, 16, 1, 0x200}, /* arb clients main */
 	{0x214, 0x21c, 0, 12, 0x13}, /* xin blocks - axi side */
@@ -2637,17 +2654,33 @@
 		set_bit(SDE_CAPS_SBUF_1,  mdata->sde_caps_map);
 		set_bit(SDE_CAPS_UBWC_2,  mdata->sde_caps_map);
 		set_bit(SDE_CAPS_PARTIALWR,  mdata->sde_caps_map);
-		rot->inpixfmts = sde_hw_rotator_v4_inpixfmts;
-		rot->num_inpixfmt = ARRAY_SIZE(sde_hw_rotator_v4_inpixfmts);
-		rot->outpixfmts = sde_hw_rotator_v4_outpixfmts;
-		rot->num_outpixfmt = ARRAY_SIZE(sde_hw_rotator_v4_outpixfmts);
+		rot->inpixfmts[SDE_ROTATOR_MODE_OFFLINE] =
+				sde_hw_rotator_v4_inpixfmts;
+		rot->num_inpixfmt[SDE_ROTATOR_MODE_OFFLINE] =
+				ARRAY_SIZE(sde_hw_rotator_v4_inpixfmts);
+		rot->outpixfmts[SDE_ROTATOR_MODE_OFFLINE] =
+				sde_hw_rotator_v4_outpixfmts;
+		rot->num_outpixfmt[SDE_ROTATOR_MODE_OFFLINE] =
+				ARRAY_SIZE(sde_hw_rotator_v4_outpixfmts);
+		rot->inpixfmts[SDE_ROTATOR_MODE_SBUF] =
+				sde_hw_rotator_v4_inpixfmts_sbuf;
+		rot->num_inpixfmt[SDE_ROTATOR_MODE_SBUF] =
+				ARRAY_SIZE(sde_hw_rotator_v4_inpixfmts_sbuf);
+		rot->outpixfmts[SDE_ROTATOR_MODE_SBUF] =
+				sde_hw_rotator_v4_outpixfmts_sbuf;
+		rot->num_outpixfmt[SDE_ROTATOR_MODE_SBUF] =
+				ARRAY_SIZE(sde_hw_rotator_v4_outpixfmts_sbuf);
 		rot->downscale_caps =
 			"LINEAR/1.5/2/4/8/16/32/64 TILE/1.5/2/4 TP10/1.5/2";
 	} else {
-		rot->inpixfmts = sde_hw_rotator_v3_inpixfmts;
-		rot->num_inpixfmt = ARRAY_SIZE(sde_hw_rotator_v3_inpixfmts);
-		rot->outpixfmts = sde_hw_rotator_v3_outpixfmts;
-		rot->num_outpixfmt = ARRAY_SIZE(sde_hw_rotator_v3_outpixfmts);
+		rot->inpixfmts[SDE_ROTATOR_MODE_OFFLINE] =
+				sde_hw_rotator_v3_inpixfmts;
+		rot->num_inpixfmt[SDE_ROTATOR_MODE_OFFLINE] =
+				ARRAY_SIZE(sde_hw_rotator_v3_inpixfmts);
+		rot->outpixfmts[SDE_ROTATOR_MODE_OFFLINE] =
+				sde_hw_rotator_v3_outpixfmts;
+		rot->num_outpixfmt[SDE_ROTATOR_MODE_OFFLINE] =
+				ARRAY_SIZE(sde_hw_rotator_v3_outpixfmts);
 		rot->downscale_caps = (hw_version == SDE_ROT_TYPE_V1_0) ?
 			"LINEAR/2/4/8/16/32/64 TILE/2/4 TP10/2" :
 			"LINEAR/1.5/2/4/8/16/32/64 TILE/1.5/2/4 TP10/1.5/2";
@@ -3055,9 +3088,10 @@
  * @mgr: Pointer to rotator manager
  * @index: index of pixel format
  * @input: true for input port; false for output port
+ * @mode: operating mode
  */
 static u32 sde_hw_rotator_get_pixfmt(struct sde_rot_mgr *mgr,
-		int index, bool input)
+		int index, bool input, u32 mode)
 {
 	struct sde_hw_rotator *rot;
 
@@ -3068,14 +3102,19 @@
 
 	rot = mgr->hw_data;
 
+	if (mode >= SDE_ROTATOR_MODE_MAX) {
+		SDEROT_ERR("invalid rotator mode %d\n", mode);
+		return 0;
+	}
+
 	if (input) {
-		if ((index < rot->num_inpixfmt) && rot->inpixfmts)
-			return rot->inpixfmts[index];
+		if ((index < rot->num_inpixfmt[mode]) && rot->inpixfmts[mode])
+			return rot->inpixfmts[mode][index];
 		else
 			return 0;
 	} else {
-		if ((index < rot->num_outpixfmt) && rot->outpixfmts)
-			return rot->outpixfmts[index];
+		if ((index < rot->num_outpixfmt[mode]) && rot->outpixfmts[mode])
+			return rot->outpixfmts[mode][index];
 		else
 			return 0;
 	}
@@ -3086,12 +3125,13 @@
  * @mgr: Pointer to rotator manager
  * @pixfmt: pixel format to be verified
  * @input: true for input port; false for output port
+ * @mode: operating mode
  */
 static int sde_hw_rotator_is_valid_pixfmt(struct sde_rot_mgr *mgr, u32 pixfmt,
-		bool input)
+		bool input, u32 mode)
 {
 	struct sde_hw_rotator *rot;
-	u32 *pixfmts;
+	const u32 *pixfmts;
 	u32 num_pixfmt;
 	int i;
 
@@ -3102,12 +3142,17 @@
 
 	rot = mgr->hw_data;
 
+	if (mode >= SDE_ROTATOR_MODE_MAX) {
+		SDEROT_ERR("invalid rotator mode %d\n", mode);
+		return false;
+	}
+
 	if (input) {
-		pixfmts = rot->inpixfmts;
-		num_pixfmt = rot->num_inpixfmt;
+		pixfmts = rot->inpixfmts[mode];
+		num_pixfmt = rot->num_inpixfmt[mode];
 	} else {
-		pixfmts = rot->outpixfmts;
-		num_pixfmt = rot->num_outpixfmt;
+		pixfmts = rot->outpixfmts[mode];
+		num_pixfmt = rot->num_outpixfmt[mode];
 	}
 
 	if (!pixfmts || !num_pixfmt) {
diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_r3_internal.h b/drivers/media/platform/msm/sde/rotator/sde_rotator_r3_internal.h
index 67f7f4b..4c1316c 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_r3_internal.h
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_r3_internal.h
@@ -259,10 +259,10 @@
  * @sbuf_ctx: list of active sbuf context in FIFO order
  * @vid_trigger: video mode trigger select
  * @cmd_trigger: command mode trigger select
- * @inpixfmts: array of supported input pixel formats forucc
- * @num_inpixfmt: size of the supported input pixel format array
- * @outpixfmts: array of supported output pixel formats in fourcc
- * @num_outpixfmt: size of the supported output pixel formats array
+ * @inpixfmts: array of supported input pixel formats fourcc per mode
+ * @num_inpixfmt: size of the supported input pixel format array per mode
+ * @outpixfmts: array of supported output pixel formats in fourcc per mode
+ * @num_outpixfmt: size of the supported output pixel formats array per mode
  * @downscale_caps: capability string of scaling
  * @maxlinewidth: maximum line width supported
  */
@@ -320,10 +320,10 @@
 
 	struct list_head sbuf_ctx[ROT_QUEUE_MAX];
 
-	u32 *inpixfmts;
-	u32 num_inpixfmt;
-	u32 *outpixfmts;
-	u32 num_outpixfmt;
+	const u32 *inpixfmts[SDE_ROTATOR_MODE_MAX];
+	u32 num_inpixfmt[SDE_ROTATOR_MODE_MAX];
+	const u32 *outpixfmts[SDE_ROTATOR_MODE_MAX];
+	u32 num_outpixfmt[SDE_ROTATOR_MODE_MAX];
 	const char *downscale_caps;
 	u32 maxlinewidth;
 };