CHROMIUM: [media] rockchip-vpu: Specify frame size ranges per coded format

For some operating modes (namely VP8 decode on RK3399 VPU and VP9 decode
on RK3399 VDEC) the supported frame size range is different than currently
globally hardcoded limits. Let's include the ranges in rockchip_vpu_fmt
struct and specify them for each coded format separately.

BUG=chrome-os-partner:62115
TEST=1080p VP8 stream uses HW decode, 2160p falls back to SW on Kevin.

Change-Id: Ie0274e33535271726ee19021a10850932efd4d66
Signed-off-by: Tomasz Figa <tfiga@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/435059
Reviewed-by: Pawel Osciak <posciak@chromium.org>
(cherry picked from commit 04546ccde2f9fa90c269ca0938f84529e713ba94)
Reviewed-on: https://chromium-review.googlesource.com/435873
Reviewed-by: Douglas Anderson <dianders@chromium.org>
Tested-by: Douglas Anderson <dianders@chromium.org>
diff --git a/drivers/media/platform/rockchip-vpu/rk3288_vpu_hw.c b/drivers/media/platform/rockchip-vpu/rk3288_vpu_hw.c
index bbea708..948aea2 100644
--- a/drivers/media/platform/rockchip-vpu/rk3288_vpu_hw.c
+++ b/drivers/media/platform/rockchip-vpu/rk3288_vpu_hw.c
@@ -64,12 +64,28 @@
 		.fourcc = V4L2_PIX_FMT_VP8,
 		.codec_mode = RK_VPU_CODEC_VP8E,
 		.num_planes = 1,
+		.frmsize = {
+			.min_width = 96,
+			.max_width = 1920,
+			.step_width = MB_DIM,
+			.min_height = 96,
+			.max_height = 1088,
+			.step_height = MB_DIM,
+		},
 	},
 	{
 		.name = "H264 Encoded Stream",
 		.fourcc = V4L2_PIX_FMT_H264,
 		.codec_mode = RK_VPU_CODEC_H264E,
 		.num_planes = 1,
+		.frmsize = {
+			.min_width = 96,
+			.max_width = 1920,
+			.step_width = MB_DIM,
+			.min_height = 96,
+			.max_height = 1088,
+			.step_height = MB_DIM,
+		},
 	},
 };
 
@@ -86,12 +102,28 @@
 		.fourcc = V4L2_PIX_FMT_H264_SLICE,
 		.codec_mode = RK_VPU_CODEC_H264D,
 		.num_planes = 1,
+		.frmsize = {
+			.min_width = 48,
+			.max_width = 3840,
+			.step_width = MB_DIM,
+			.min_height = 48,
+			.max_height = 2160,
+			.step_height = MB_DIM,
+		},
 	},
 	{
 		.name = "Frames of VP8 Encoded Stream",
 		.fourcc = V4L2_PIX_FMT_VP8_FRAME,
 		.codec_mode = RK_VPU_CODEC_VP8D,
 		.num_planes = 1,
+		.frmsize = {
+			.min_width = 48,
+			.max_width = 3840,
+			.step_width = MB_DIM,
+			.min_height = 48,
+			.max_height = 2160,
+			.step_height = MB_DIM,
+		},
 	},
 };
 
diff --git a/drivers/media/platform/rockchip-vpu/rk3399_vdec_hw.c b/drivers/media/platform/rockchip-vpu/rk3399_vdec_hw.c
index 6f4779b..18f3ba4 100644
--- a/drivers/media/platform/rockchip-vpu/rk3399_vdec_hw.c
+++ b/drivers/media/platform/rockchip-vpu/rk3399_vdec_hw.c
@@ -37,12 +37,28 @@
 		.fourcc = V4L2_PIX_FMT_H264_SLICE,
 		.codec_mode = RK_VPU_CODEC_H264D,
 		.num_planes = 1,
+		.frmsize = {
+			.min_width = 48,
+			.max_width = 3840,
+			.step_width = MB_DIM,
+			.min_height = 48,
+			.max_height = 2160,
+			.step_height = MB_DIM,
+		},
 	},
 	{
 		.name = "Frames of VP9 Encoded Stream",
 		.fourcc = V4L2_PIX_FMT_VP9_FRAME,
 		.codec_mode = RK_VPU_CODEC_VP9D,
 		.num_planes = 1,
+		.frmsize = {
+			.min_width = 48,
+			.max_width = 3840,
+			.step_width = SB_DIM,
+			.min_height = 48,
+			.max_height = 2176,
+			.step_height = SB_DIM,
+		},
 	},
 };
 
diff --git a/drivers/media/platform/rockchip-vpu/rk3399_vpu_hw.c b/drivers/media/platform/rockchip-vpu/rk3399_vpu_hw.c
index f097354..79d2b55 100644
--- a/drivers/media/platform/rockchip-vpu/rk3399_vpu_hw.c
+++ b/drivers/media/platform/rockchip-vpu/rk3399_vpu_hw.c
@@ -64,12 +64,28 @@
 		.fourcc = V4L2_PIX_FMT_VP8,
 		.codec_mode = RK_VPU_CODEC_VP8E,
 		.num_planes = 1,
+		.frmsize = {
+			.min_width = 96,
+			.max_width = 1920,
+			.step_width = MB_DIM,
+			.min_height = 96,
+			.max_height = 1088,
+			.step_height = MB_DIM,
+		},
 	},
 	{
 		.name = "H264 Encoded Stream",
 		.fourcc = V4L2_PIX_FMT_H264,
 		.codec_mode = RK_VPU_CODEC_H264E,
 		.num_planes = 1,
+		.frmsize = {
+			.min_width = 96,
+			.max_width = 1920,
+			.step_width = MB_DIM,
+			.min_height = 96,
+			.max_height = 1088,
+			.step_height = MB_DIM,
+		},
 	},
 };
 
@@ -86,6 +102,14 @@
 		.fourcc = V4L2_PIX_FMT_VP8_FRAME,
 		.codec_mode = RK_VPU_CODEC_VP8D,
 		.num_planes = 1,
+		.frmsize = {
+			.min_width = 48,
+			.max_width = 1920,
+			.step_width = MB_DIM,
+			.min_height = 48,
+			.max_height = 1088,
+			.step_height = MB_DIM,
+		},
 	},
 };
 
diff --git a/drivers/media/platform/rockchip-vpu/rockchip_vpu_common.h b/drivers/media/platform/rockchip-vpu/rockchip_vpu_common.h
index bbdbc35..ef60143 100644
--- a/drivers/media/platform/rockchip-vpu/rockchip_vpu_common.h
+++ b/drivers/media/platform/rockchip-vpu/rockchip_vpu_common.h
@@ -401,6 +401,7 @@
  * @num_planes:	Number of planes used by this format.
  * @depth:	Depth of each plane in bits per pixel.
  * @enc_fmt:	Format identifier for encoder registers.
+ * @frmsize:	Supported range of frame sizes (only for bitstream formats).
  */
 struct rockchip_vpu_fmt {
 	char *name;
@@ -409,6 +410,7 @@
 	int num_planes;
 	u8 depth[VIDEO_MAX_PLANES];
 	enum rk3288_vpu_enc_fmt enc_fmt;
+	struct v4l2_frmsize_stepwise frmsize;
 };
 
 /**
diff --git a/drivers/media/platform/rockchip-vpu/rockchip_vpu_dec.c b/drivers/media/platform/rockchip-vpu/rockchip_vpu_dec.c
index 623302c..aa57b28 100644
--- a/drivers/media/platform/rockchip-vpu/rockchip_vpu_dec.c
+++ b/drivers/media/platform/rockchip-vpu/rockchip_vpu_dec.c
@@ -38,11 +38,6 @@
 #define DEF_SRC_FMT_DEC				V4L2_PIX_FMT_H264_SLICE
 #define DEF_DST_FMT_DEC				V4L2_PIX_FMT_NV12
 
-#define ROCKCHIP_DEC_MIN_WIDTH			48U
-#define ROCKCHIP_DEC_MAX_WIDTH			3840U
-#define ROCKCHIP_DEC_MIN_HEIGHT			48U
-#define ROCKCHIP_DEC_MAX_HEIGHT			2160U
-
 #define ROCKCHIP_H264_MAX_SLICES_PER_FRAME	16
 
 static const struct rockchip_vpu_fmt *find_format(struct rockchip_vpu_dev *dev,
@@ -187,7 +182,6 @@
 				  struct v4l2_frmsizeenum *fsize)
 {
 	struct rockchip_vpu_dev *dev = video_drvdata(file);
-	struct v4l2_frmsize_stepwise *s = &fsize->stepwise;
 	const struct rockchip_vpu_fmt *fmt;
 
 	if (fsize->index != 0) {
@@ -204,13 +198,7 @@
 	}
 
 	fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
-
-	s->min_width = ROCKCHIP_DEC_MIN_WIDTH;
-	s->max_width = ROCKCHIP_DEC_MAX_WIDTH;
-	s->step_width = MB_DIM;
-	s->min_height = ROCKCHIP_DEC_MIN_HEIGHT;
-	s->max_height = ROCKCHIP_DEC_MAX_HEIGHT;
-	s->step_height = MB_DIM;
+	fsize->stepwise = fmt->frmsize;
 
 	return 0;
 }
@@ -336,11 +324,11 @@
 
 		/* Limit to hardware min/max. */
 		pix_fmt_mp->width = clamp(pix_fmt_mp->width,
-				ROCKCHIP_DEC_MIN_WIDTH,
-				ROCKCHIP_DEC_MAX_WIDTH);
+				ctx->vpu_src_fmt->frmsize.min_width,
+				ctx->vpu_src_fmt->frmsize.max_width);
 		pix_fmt_mp->height = clamp(pix_fmt_mp->height,
-				ROCKCHIP_DEC_MIN_HEIGHT,
-				ROCKCHIP_DEC_MAX_HEIGHT);
+				ctx->vpu_src_fmt->frmsize.min_height,
+				ctx->vpu_src_fmt->frmsize.max_height);
 
 		/* Round up to macroblocks. */
 		if (ctx->vpu_src_fmt->fourcc == V4L2_PIX_FMT_VP9_FRAME) {
diff --git a/drivers/media/platform/rockchip-vpu/rockchip_vpu_enc.c b/drivers/media/platform/rockchip-vpu/rockchip_vpu_enc.c
index eafe84a..f1d47c8f 100644
--- a/drivers/media/platform/rockchip-vpu/rockchip_vpu_enc.c
+++ b/drivers/media/platform/rockchip-vpu/rockchip_vpu_enc.c
@@ -44,11 +44,6 @@
 #define DEF_SRC_FMT_ENC				V4L2_PIX_FMT_NV12
 #define DEF_DST_FMT_ENC				V4L2_PIX_FMT_VP8
 
-#define ROCKCHIP_ENC_MIN_WIDTH			96U
-#define ROCKCHIP_ENC_MAX_WIDTH			1920U
-#define ROCKCHIP_ENC_MIN_HEIGHT			96U
-#define ROCKCHIP_ENC_MAX_HEIGHT			1088U
-
 #define V4L2_CID_PRIVATE_ROCKCHIP_HEADER	(V4L2_CID_CUSTOM_BASE + 0)
 #define V4L2_CID_PRIVATE_ROCKCHIP_REG_PARAMS	(V4L2_CID_CUSTOM_BASE + 1)
 #define V4L2_CID_PRIVATE_ROCKCHIP_HW_PARAMS	(V4L2_CID_CUSTOM_BASE + 2)
@@ -326,7 +321,6 @@
 				  struct v4l2_frmsizeenum *fsize)
 {
 	struct rockchip_vpu_dev *dev = video_drvdata(file);
-	struct v4l2_frmsize_stepwise *s = &fsize->stepwise;
 	const struct rockchip_vpu_fmt *fmt;
 
 	if (fsize->index != 0) {
@@ -343,13 +337,7 @@
 	}
 
 	fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
-
-	s->min_width = ROCKCHIP_ENC_MIN_WIDTH;
-	s->max_width = ROCKCHIP_ENC_MAX_WIDTH;
-	s->step_width = MB_DIM;
-	s->min_height = ROCKCHIP_ENC_MIN_HEIGHT;
-	s->max_height = ROCKCHIP_ENC_MAX_HEIGHT;
-	s->step_height = MB_DIM;
+	fsize->stepwise = fmt->frmsize;
 
 	return 0;
 }
@@ -453,6 +441,7 @@
 static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f)
 {
 	struct rockchip_vpu_dev *dev = video_drvdata(file);
+	struct rockchip_vpu_ctx *ctx = fh_to_ctx(priv);
 	const struct rockchip_vpu_fmt *fmt;
 	struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;
 	char str[5];
@@ -496,11 +485,11 @@
 
 		/* Limit to hardware min/max. */
 		pix_fmt_mp->width = clamp(pix_fmt_mp->width,
-				ROCKCHIP_ENC_MIN_WIDTH,
-				ROCKCHIP_ENC_MAX_WIDTH);
+				ctx->vpu_dst_fmt->frmsize.min_width,
+				ctx->vpu_dst_fmt->frmsize.max_width);
 		pix_fmt_mp->height = clamp(pix_fmt_mp->height,
-				ROCKCHIP_ENC_MIN_HEIGHT,
-				ROCKCHIP_ENC_MAX_HEIGHT);
+				ctx->vpu_dst_fmt->frmsize.min_height,
+				ctx->vpu_dst_fmt->frmsize.max_height);
 		/* Round up to macroblocks. */
 		pix_fmt_mp->width = round_up(pix_fmt_mp->width, MB_DIM);
 		pix_fmt_mp->height = round_up(pix_fmt_mp->height, MB_DIM);