File Index
Files and directories
Sign in
FILE

mtk_jpeg_core.c

File preview with syntax highlighting.

linux-6.19.14/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c C
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Copyright (c) 2016 MediaTek Inc.
   4 * Author: Ming Hsiu Tsai <minghsiu.tsai@mediatek.com>
   5 *         Rick Chang <rick.chang@mediatek.com>
   6 *         Xia Jiang <xia.jiang@mediatek.com>
   7 */
   8
   9#include <linux/clk.h>
  10#include <linux/err.h>
  11#include <linux/interrupt.h>
  12#include <linux/io.h>
  13#include <linux/kernel.h>
  14#include <linux/module.h>
  15#include <linux/of_platform.h>
  16#include <linux/platform_device.h>
  17#include <linux/pm_runtime.h>
  18#include <linux/slab.h>
  19#include <linux/spinlock.h>
  20#include <media/v4l2-event.h>
  21#include <media/v4l2-mem2mem.h>
  22#include <media/v4l2-ioctl.h>
  23#include <media/videobuf2-core.h>
  24#include <media/videobuf2-dma-contig.h>
  25
  26#include "mtk_jpeg_enc_hw.h"
  27#include "mtk_jpeg_dec_hw.h"
  28#include "mtk_jpeg_core.h"
  29#include "mtk_jpeg_dec_parse.h"
  30
  31static struct mtk_jpeg_fmt mtk_jpeg_enc_formats[] = {
  32	{
  33		.fourcc		= V4L2_PIX_FMT_JPEG,
  34		.colplanes	= 1,
  35		.flags		= MTK_JPEG_FMT_FLAG_CAPTURE,
  36	},
  37	{
  38		.fourcc		= V4L2_PIX_FMT_NV12M,
  39		.hw_format	= JPEG_ENC_YUV_FORMAT_NV12,
  40		.h_sample	= {4, 4},
  41		.v_sample	= {4, 2},
  42		.colplanes	= 2,
  43		.h_align	= 4,
  44		.v_align	= 4,
  45		.flags		= MTK_JPEG_FMT_FLAG_OUTPUT,
  46	},
  47	{
  48		.fourcc		= V4L2_PIX_FMT_NV21M,
  49		.hw_format	= JEPG_ENC_YUV_FORMAT_NV21,
  50		.h_sample	= {4, 4},
  51		.v_sample	= {4, 2},
  52		.colplanes	= 2,
  53		.h_align	= 4,
  54		.v_align	= 4,
  55		.flags		= MTK_JPEG_FMT_FLAG_OUTPUT,
  56	},
  57	{
  58		.fourcc		= V4L2_PIX_FMT_YUYV,
  59		.hw_format	= JPEG_ENC_YUV_FORMAT_YUYV,
  60		.h_sample	= {8},
  61		.v_sample	= {4},
  62		.colplanes	= 1,
  63		.h_align	= 5,
  64		.v_align	= 3,
  65		.flags		= MTK_JPEG_FMT_FLAG_OUTPUT,
  66	},
  67	{
  68		.fourcc		= V4L2_PIX_FMT_YVYU,
  69		.hw_format	= JPEG_ENC_YUV_FORMAT_YVYU,
  70		.h_sample	= {8},
  71		.v_sample	= {4},
  72		.colplanes	= 1,
  73		.h_align	= 5,
  74		.v_align	= 3,
  75		.flags		= MTK_JPEG_FMT_FLAG_OUTPUT,
  76	},
  77};
  78
  79static struct mtk_jpeg_fmt mtk_jpeg_dec_formats[] = {
  80	{
  81		.fourcc		= V4L2_PIX_FMT_JPEG,
  82		.colplanes	= 1,
  83		.flags		= MTK_JPEG_FMT_FLAG_OUTPUT,
  84	},
  85	{
  86		.fourcc		= V4L2_PIX_FMT_YUV420M,
  87		.h_sample	= {4, 2, 2},
  88		.v_sample	= {4, 2, 2},
  89		.colplanes	= 3,
  90		.h_align	= 5,
  91		.v_align	= 4,
  92		.flags		= MTK_JPEG_FMT_FLAG_CAPTURE,
  93	},
  94	{
  95		.fourcc		= V4L2_PIX_FMT_YUV422M,
  96		.h_sample	= {4, 2, 2},
  97		.v_sample	= {4, 4, 4},
  98		.colplanes	= 3,
  99		.h_align	= 5,
 100		.v_align	= 3,
 101		.flags		= MTK_JPEG_FMT_FLAG_CAPTURE,
 102	},
 103};
 104
 105#define MTK_JPEG_ENC_NUM_FORMATS ARRAY_SIZE(mtk_jpeg_enc_formats)
 106#define MTK_JPEG_DEC_NUM_FORMATS ARRAY_SIZE(mtk_jpeg_dec_formats)
 107#define MTK_JPEG_MAX_RETRY_TIME 5000
 108
 109enum {
 110	MTK_JPEG_BUF_FLAGS_INIT			= 0,
 111	MTK_JPEG_BUF_FLAGS_LAST_FRAME		= 1,
 112};
 113
 114static int debug;
 115module_param(debug, int, 0644);
 116
 117static inline struct mtk_jpeg_ctx *ctrl_to_ctx(struct v4l2_ctrl *ctrl)
 118{
 119	return container_of(ctrl->handler, struct mtk_jpeg_ctx, ctrl_hdl);
 120}
 121
 122static inline struct mtk_jpeg_ctx *mtk_jpeg_file_to_ctx(struct file *filp)
 123{
 124	return container_of(file_to_v4l2_fh(filp), struct mtk_jpeg_ctx, fh);
 125}
 126
 127static inline struct mtk_jpeg_src_buf *mtk_jpeg_vb2_to_srcbuf(
 128							struct vb2_buffer *vb)
 129{
 130	return container_of(to_vb2_v4l2_buffer(vb), struct mtk_jpeg_src_buf, b);
 131}
 132
 133static int mtk_jpeg_querycap(struct file *file, void *priv,
 134			     struct v4l2_capability *cap)
 135{
 136	struct mtk_jpeg_dev *jpeg = video_drvdata(file);
 137
 138	strscpy(cap->driver, jpeg->variant->dev_name, sizeof(cap->driver));
 139	strscpy(cap->card, jpeg->variant->dev_name, sizeof(cap->card));
 140
 141	return 0;
 142}
 143
 144static int vidioc_jpeg_enc_s_ctrl(struct v4l2_ctrl *ctrl)
 145{
 146	struct mtk_jpeg_ctx *ctx = ctrl_to_ctx(ctrl);
 147
 148	switch (ctrl->id) {
 149	case V4L2_CID_JPEG_RESTART_INTERVAL:
 150		ctx->restart_interval = ctrl->val;
 151		break;
 152	case V4L2_CID_JPEG_COMPRESSION_QUALITY:
 153		ctx->enc_quality = ctrl->val;
 154		break;
 155	case V4L2_CID_JPEG_ACTIVE_MARKER:
 156		ctx->enable_exif = ctrl->val & V4L2_JPEG_ACTIVE_MARKER_APP1;
 157		break;
 158	}
 159
 160	return 0;
 161}
 162
 163static const struct v4l2_ctrl_ops mtk_jpeg_enc_ctrl_ops = {
 164	.s_ctrl = vidioc_jpeg_enc_s_ctrl,
 165};
 166
 167static int mtk_jpeg_enc_ctrls_setup(struct mtk_jpeg_ctx *ctx)
 168{
 169	const struct v4l2_ctrl_ops *ops = &mtk_jpeg_enc_ctrl_ops;
 170	struct v4l2_ctrl_handler *handler = &ctx->ctrl_hdl;
 171
 172	v4l2_ctrl_handler_init(handler, 3);
 173
 174	v4l2_ctrl_new_std(handler, ops, V4L2_CID_JPEG_RESTART_INTERVAL, 0, 100,
 175			  1, 0);
 176	v4l2_ctrl_new_std(handler, ops, V4L2_CID_JPEG_COMPRESSION_QUALITY, 48,
 177			  100, 1, 90);
 178	v4l2_ctrl_new_std(handler, ops, V4L2_CID_JPEG_ACTIVE_MARKER, 0,
 179			  V4L2_JPEG_ACTIVE_MARKER_APP1, 0, 0);
 180
 181	if (handler->error) {
 182		v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
 183		return handler->error;
 184	}
 185
 186	v4l2_ctrl_handler_setup(&ctx->ctrl_hdl);
 187
 188	return 0;
 189}
 190
 191static int mtk_jpeg_enum_fmt(struct mtk_jpeg_fmt *mtk_jpeg_formats, int n,
 192			     struct v4l2_fmtdesc *f, u32 type)
 193{
 194	int i, num = 0;
 195
 196	for (i = 0; i < n; ++i) {
 197		if (mtk_jpeg_formats[i].flags & type) {
 198			if (num == f->index)
 199				break;
 200			++num;
 201		}
 202	}
 203
 204	if (i >= n)
 205		return -EINVAL;
 206
 207	f->pixelformat = mtk_jpeg_formats[i].fourcc;
 208
 209	return 0;
 210}
 211
 212static int mtk_jpeg_enum_fmt_vid_cap(struct file *file, void *priv,
 213				     struct v4l2_fmtdesc *f)
 214{
 215	struct mtk_jpeg_ctx *ctx = mtk_jpeg_file_to_ctx(file);
 216	struct mtk_jpeg_dev *jpeg = ctx->jpeg;
 217
 218	return mtk_jpeg_enum_fmt(jpeg->variant->formats,
 219				 jpeg->variant->num_formats, f,
 220				 MTK_JPEG_FMT_FLAG_CAPTURE);
 221}
 222
 223static int mtk_jpeg_enum_fmt_vid_out(struct file *file, void *priv,
 224				     struct v4l2_fmtdesc *f)
 225{
 226	struct mtk_jpeg_ctx *ctx = mtk_jpeg_file_to_ctx(file);
 227	struct mtk_jpeg_dev *jpeg = ctx->jpeg;
 228
 229	return mtk_jpeg_enum_fmt(jpeg->variant->formats,
 230				 jpeg->variant->num_formats, f,
 231				 MTK_JPEG_FMT_FLAG_OUTPUT);
 232}
 233
 234static struct mtk_jpeg_q_data *mtk_jpeg_get_q_data(struct mtk_jpeg_ctx *ctx,
 235						   enum v4l2_buf_type type)
 236{
 237	if (V4L2_TYPE_IS_OUTPUT(type))
 238		return &ctx->out_q;
 239	return &ctx->cap_q;
 240}
 241
 242static struct mtk_jpeg_fmt *
 243mtk_jpeg_find_format(struct mtk_jpeg_fmt *mtk_jpeg_formats, int num_formats,
 244		     u32 pixelformat, unsigned int fmt_type)
 245{
 246	unsigned int k;
 247	struct mtk_jpeg_fmt *fmt;
 248
 249	for (k = 0; k < num_formats; k++) {
 250		fmt = &mtk_jpeg_formats[k];
 251
 252		if (fmt->fourcc == pixelformat && fmt->flags & fmt_type)
 253			return fmt;
 254	}
 255
 256	return NULL;
 257}
 258
 259static int mtk_jpeg_try_fmt_mplane(struct v4l2_pix_format_mplane *pix_mp,
 260				   struct mtk_jpeg_fmt *fmt)
 261{
 262	int i;
 263
 264	pix_mp->field = V4L2_FIELD_NONE;
 265
 266	pix_mp->num_planes = fmt->colplanes;
 267	pix_mp->pixelformat = fmt->fourcc;
 268
 269	if (fmt->fourcc == V4L2_PIX_FMT_JPEG) {
 270		struct v4l2_plane_pix_format *pfmt = &pix_mp->plane_fmt[0];
 271
 272		pix_mp->height = clamp(pix_mp->height, MTK_JPEG_MIN_HEIGHT,
 273				       MTK_JPEG_MAX_HEIGHT);
 274		pix_mp->width = clamp(pix_mp->width, MTK_JPEG_MIN_WIDTH,
 275				      MTK_JPEG_MAX_WIDTH);
 276
 277		pfmt->bytesperline = 0;
 278		/* Source size must be aligned to 128 */
 279		pfmt->sizeimage = round_up(pfmt->sizeimage, 128);
 280		if (pfmt->sizeimage == 0)
 281			pfmt->sizeimage = MTK_JPEG_DEFAULT_SIZEIMAGE;
 282		return 0;
 283	}
 284
 285	/* other fourcc */
 286	pix_mp->height = clamp(round_up(pix_mp->height, fmt->v_align),
 287			       MTK_JPEG_MIN_HEIGHT, MTK_JPEG_MAX_HEIGHT);
 288	pix_mp->width = clamp(round_up(pix_mp->width, fmt->h_align),
 289			      MTK_JPEG_MIN_WIDTH, MTK_JPEG_MAX_WIDTH);
 290
 291	for (i = 0; i < fmt->colplanes; i++) {
 292		struct v4l2_plane_pix_format *pfmt = &pix_mp->plane_fmt[i];
 293		u32 stride = pix_mp->width * fmt->h_sample[i] / 4;
 294		u32 h = pix_mp->height * fmt->v_sample[i] / 4;
 295
 296		pfmt->bytesperline = stride;
 297		pfmt->sizeimage = stride * h;
 298	}
 299	return 0;
 300}
 301
 302static int mtk_jpeg_g_fmt_vid_mplane(struct file *file, void *priv,
 303				     struct v4l2_format *f)
 304{
 305	struct mtk_jpeg_q_data *q_data = NULL;
 306	struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
 307	struct mtk_jpeg_ctx *ctx = mtk_jpeg_file_to_ctx(file);
 308	struct mtk_jpeg_dev *jpeg = ctx->jpeg;
 309	int i;
 310
 311	q_data = mtk_jpeg_get_q_data(ctx, f->type);
 312
 313	pix_mp->width = q_data->pix_mp.width;
 314	pix_mp->height = q_data->pix_mp.height;
 315	pix_mp->field = V4L2_FIELD_NONE;
 316	pix_mp->pixelformat = q_data->fmt->fourcc;
 317	pix_mp->num_planes = q_data->fmt->colplanes;
 318	pix_mp->colorspace = q_data->pix_mp.colorspace;
 319	pix_mp->ycbcr_enc = q_data->pix_mp.ycbcr_enc;
 320	pix_mp->xfer_func = q_data->pix_mp.xfer_func;
 321	pix_mp->quantization = q_data->pix_mp.quantization;
 322
 323	v4l2_dbg(1, debug, &jpeg->v4l2_dev, "(%d) g_fmt:%c%c%c%c wxh:%ux%u\n",
 324		 f->type,
 325		 (pix_mp->pixelformat & 0xff),
 326		 (pix_mp->pixelformat >>  8 & 0xff),
 327		 (pix_mp->pixelformat >> 16 & 0xff),
 328		 (pix_mp->pixelformat >> 24 & 0xff),
 329		 pix_mp->width, pix_mp->height);
 330
 331	for (i = 0; i < pix_mp->num_planes; i++) {
 332		struct v4l2_plane_pix_format *pfmt = &pix_mp->plane_fmt[i];
 333
 334		pfmt->bytesperline = q_data->pix_mp.plane_fmt[i].bytesperline;
 335		pfmt->sizeimage = q_data->pix_mp.plane_fmt[i].sizeimage;
 336
 337		v4l2_dbg(1, debug, &jpeg->v4l2_dev,
 338			 "plane[%d] bpl=%u, size=%u\n",
 339			 i,
 340			 pfmt->bytesperline,
 341			 pfmt->sizeimage);
 342	}
 343	return 0;
 344}
 345
 346static int mtk_jpeg_try_fmt_vid_cap_mplane(struct file *file, void *priv,
 347					   struct v4l2_format *f)
 348{
 349	struct mtk_jpeg_ctx *ctx = mtk_jpeg_file_to_ctx(file);
 350	struct mtk_jpeg_dev *jpeg = ctx->jpeg;
 351	struct mtk_jpeg_fmt *fmt;
 352
 353	fmt = mtk_jpeg_find_format(jpeg->variant->formats,
 354				   jpeg->variant->num_formats,
 355				   f->fmt.pix_mp.pixelformat,
 356				   MTK_JPEG_FMT_FLAG_CAPTURE);
 357	if (!fmt)
 358		fmt = ctx->cap_q.fmt;
 359
 360	v4l2_dbg(2, debug, &ctx->jpeg->v4l2_dev, "(%d) try_fmt:%c%c%c%c\n",
 361		 f->type,
 362		 (fmt->fourcc & 0xff),
 363		 (fmt->fourcc >>  8 & 0xff),
 364		 (fmt->fourcc >> 16 & 0xff),
 365		 (fmt->fourcc >> 24 & 0xff));
 366
 367	if (ctx->state != MTK_JPEG_INIT) {
 368		mtk_jpeg_g_fmt_vid_mplane(file, priv, f);
 369		return 0;
 370	}
 371
 372	return mtk_jpeg_try_fmt_mplane(&f->fmt.pix_mp, fmt);
 373}
 374
 375static int mtk_jpeg_try_fmt_vid_out_mplane(struct file *file, void *priv,
 376					   struct v4l2_format *f)
 377{
 378	struct mtk_jpeg_ctx *ctx = mtk_jpeg_file_to_ctx(file);
 379	struct mtk_jpeg_dev *jpeg = ctx->jpeg;
 380	struct mtk_jpeg_fmt *fmt;
 381
 382	fmt = mtk_jpeg_find_format(jpeg->variant->formats,
 383				   jpeg->variant->num_formats,
 384				   f->fmt.pix_mp.pixelformat,
 385				   MTK_JPEG_FMT_FLAG_OUTPUT);
 386	if (!fmt)
 387		fmt = ctx->out_q.fmt;
 388
 389	v4l2_dbg(2, debug, &ctx->jpeg->v4l2_dev, "(%d) try_fmt:%c%c%c%c\n",
 390		 f->type,
 391		 (fmt->fourcc & 0xff),
 392		 (fmt->fourcc >>  8 & 0xff),
 393		 (fmt->fourcc >> 16 & 0xff),
 394		 (fmt->fourcc >> 24 & 0xff));
 395
 396	if (ctx->state != MTK_JPEG_INIT) {
 397		mtk_jpeg_g_fmt_vid_mplane(file, priv, f);
 398		return 0;
 399	}
 400
 401	return mtk_jpeg_try_fmt_mplane(&f->fmt.pix_mp, fmt);
 402}
 403
 404static int mtk_jpeg_s_fmt_mplane(struct mtk_jpeg_ctx *ctx,
 405				 struct v4l2_format *f, unsigned int fmt_type)
 406{
 407	struct vb2_queue *vq;
 408	struct mtk_jpeg_q_data *q_data = NULL;
 409	struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
 410	struct mtk_jpeg_dev *jpeg = ctx->jpeg;
 411	int i;
 412
 413	vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
 414
 415	q_data = mtk_jpeg_get_q_data(ctx, f->type);
 416
 417	if (vb2_is_busy(vq)) {
 418		v4l2_err(&jpeg->v4l2_dev, "queue busy\n");
 419		return -EBUSY;
 420	}
 421
 422	q_data->fmt = mtk_jpeg_find_format(jpeg->variant->formats,
 423					   jpeg->variant->num_formats,
 424					   pix_mp->pixelformat, fmt_type);
 425	q_data->pix_mp.width = pix_mp->width;
 426	q_data->pix_mp.height = pix_mp->height;
 427	q_data->enc_crop_rect.width = pix_mp->width;
 428	q_data->enc_crop_rect.height = pix_mp->height;
 429	q_data->pix_mp.colorspace = V4L2_COLORSPACE_SRGB;
 430	q_data->pix_mp.ycbcr_enc = V4L2_YCBCR_ENC_601;
 431	q_data->pix_mp.xfer_func = V4L2_XFER_FUNC_SRGB;
 432	q_data->pix_mp.quantization = V4L2_QUANTIZATION_FULL_RANGE;
 433
 434	v4l2_dbg(1, debug, &jpeg->v4l2_dev, "(%d) s_fmt:%c%c%c%c wxh:%ux%u\n",
 435		 f->type,
 436		 (q_data->fmt->fourcc & 0xff),
 437		 (q_data->fmt->fourcc >>  8 & 0xff),
 438		 (q_data->fmt->fourcc >> 16 & 0xff),
 439		 (q_data->fmt->fourcc >> 24 & 0xff),
 440		 q_data->pix_mp.width, q_data->pix_mp.height);
 441
 442	for (i = 0; i < q_data->fmt->colplanes; i++) {
 443		q_data->pix_mp.plane_fmt[i].bytesperline =
 444					pix_mp->plane_fmt[i].bytesperline;
 445		q_data->pix_mp.plane_fmt[i].sizeimage =
 446					pix_mp->plane_fmt[i].sizeimage;
 447
 448		v4l2_dbg(1, debug, &jpeg->v4l2_dev,
 449			 "plane[%d] bpl=%u, size=%u\n",
 450			 i, q_data->pix_mp.plane_fmt[i].bytesperline,
 451			 q_data->pix_mp.plane_fmt[i].sizeimage);
 452	}
 453
 454	return 0;
 455}
 456
 457static int mtk_jpeg_s_fmt_vid_out_mplane(struct file *file, void *priv,
 458					 struct v4l2_format *f)
 459{
 460	int ret;
 461
 462	ret = mtk_jpeg_try_fmt_vid_out_mplane(file, priv, f);
 463	if (ret)
 464		return ret;
 465
 466	return mtk_jpeg_s_fmt_mplane(mtk_jpeg_file_to_ctx(file), f,
 467				     MTK_JPEG_FMT_FLAG_OUTPUT);
 468}
 469
 470static int mtk_jpeg_s_fmt_vid_cap_mplane(struct file *file, void *priv,
 471					 struct v4l2_format *f)
 472{
 473	int ret;
 474
 475	ret = mtk_jpeg_try_fmt_vid_cap_mplane(file, priv, f);
 476	if (ret)
 477		return ret;
 478
 479	return mtk_jpeg_s_fmt_mplane(mtk_jpeg_file_to_ctx(file), f,
 480				     MTK_JPEG_FMT_FLAG_CAPTURE);
 481}
 482
 483static void mtk_jpeg_queue_src_chg_event(struct mtk_jpeg_ctx *ctx)
 484{
 485	static const struct v4l2_event ev_src_ch = {
 486		.type = V4L2_EVENT_SOURCE_CHANGE,
 487		.u.src_change.changes =
 488		V4L2_EVENT_SRC_CH_RESOLUTION,
 489	};
 490
 491	v4l2_event_queue_fh(&ctx->fh, &ev_src_ch);
 492}
 493
 494static int mtk_jpeg_subscribe_event(struct v4l2_fh *fh,
 495				    const struct v4l2_event_subscription *sub)
 496{
 497	switch (sub->type) {
 498	case V4L2_EVENT_SOURCE_CHANGE:
 499		return v4l2_src_change_event_subscribe(fh, sub);
 500	}
 501
 502	return v4l2_ctrl_subscribe_event(fh, sub);
 503}
 504
 505static int mtk_jpeg_enc_g_selection(struct file *file, void *priv,
 506				    struct v4l2_selection *s)
 507{
 508	struct mtk_jpeg_ctx *ctx = mtk_jpeg_file_to_ctx(file);
 509
 510	if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
 511		return -EINVAL;
 512
 513	switch (s->target) {
 514	case V4L2_SEL_TGT_CROP:
 515		s->r = ctx->out_q.enc_crop_rect;
 516		break;
 517	case V4L2_SEL_TGT_CROP_BOUNDS:
 518	case V4L2_SEL_TGT_CROP_DEFAULT:
 519		s->r.width = ctx->out_q.pix_mp.width;
 520		s->r.height = ctx->out_q.pix_mp.height;
 521		s->r.left = 0;
 522		s->r.top = 0;
 523		break;
 524	default:
 525		return -EINVAL;
 526	}
 527	return 0;
 528}
 529
 530static int mtk_jpeg_dec_g_selection(struct file *file, void *priv,
 531				    struct v4l2_selection *s)
 532{
 533	struct mtk_jpeg_ctx *ctx = mtk_jpeg_file_to_ctx(file);
 534
 535	if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
 536		return -EINVAL;
 537
 538	switch (s->target) {
 539	case V4L2_SEL_TGT_COMPOSE:
 540	case V4L2_SEL_TGT_COMPOSE_DEFAULT:
 541		s->r.width = ctx->out_q.pix_mp.width;
 542		s->r.height = ctx->out_q.pix_mp.height;
 543		s->r.left = 0;
 544		s->r.top = 0;
 545		break;
 546	case V4L2_SEL_TGT_COMPOSE_BOUNDS:
 547	case V4L2_SEL_TGT_COMPOSE_PADDED:
 548		s->r.width = ctx->cap_q.pix_mp.width;
 549		s->r.height = ctx->cap_q.pix_mp.height;
 550		s->r.left = 0;
 551		s->r.top = 0;
 552		break;
 553	default:
 554		return -EINVAL;
 555	}
 556	return 0;
 557}
 558
 559static int mtk_jpeg_enc_s_selection(struct file *file, void *priv,
 560				    struct v4l2_selection *s)
 561{
 562	struct mtk_jpeg_ctx *ctx = mtk_jpeg_file_to_ctx(file);
 563
 564	if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
 565		return -EINVAL;
 566
 567	switch (s->target) {
 568	case V4L2_SEL_TGT_CROP:
 569		s->r.left = 0;
 570		s->r.top = 0;
 571		s->r.width = min(s->r.width, ctx->out_q.pix_mp.width);
 572		s->r.height = min(s->r.height, ctx->out_q.pix_mp.height);
 573		ctx->out_q.enc_crop_rect = s->r;
 574		break;
 575	default:
 576		return -EINVAL;
 577	}
 578
 579	return 0;
 580}
 581
 582static int mtk_jpeg_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
 583{
 584	struct v4l2_fh *fh = file_to_v4l2_fh(file);
 585	struct mtk_jpeg_ctx *ctx = mtk_jpeg_file_to_ctx(file);
 586	struct vb2_queue *vq;
 587	struct vb2_buffer *vb;
 588	struct mtk_jpeg_src_buf *jpeg_src_buf;
 589
 590	if (buf->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
 591		goto end;
 592
 593	vq = v4l2_m2m_get_vq(fh->m2m_ctx, buf->type);
 594	vb = vb2_get_buffer(vq, buf->index);
 595	if (!vb) {
 596		dev_err(ctx->jpeg->dev, "buffer not found\n");
 597		return -EINVAL;
 598	}
 599	jpeg_src_buf = mtk_jpeg_vb2_to_srcbuf(vb);
 600	jpeg_src_buf->bs_size = buf->m.planes[0].bytesused;
 601
 602end:
 603	return v4l2_m2m_qbuf(file, fh->m2m_ctx, buf);
 604}
 605
 606static const struct v4l2_ioctl_ops mtk_jpeg_enc_ioctl_ops = {
 607	.vidioc_querycap                = mtk_jpeg_querycap,
 608	.vidioc_enum_fmt_vid_cap	= mtk_jpeg_enum_fmt_vid_cap,
 609	.vidioc_enum_fmt_vid_out	= mtk_jpeg_enum_fmt_vid_out,
 610	.vidioc_try_fmt_vid_cap_mplane	= mtk_jpeg_try_fmt_vid_cap_mplane,
 611	.vidioc_try_fmt_vid_out_mplane	= mtk_jpeg_try_fmt_vid_out_mplane,
 612	.vidioc_g_fmt_vid_cap_mplane    = mtk_jpeg_g_fmt_vid_mplane,
 613	.vidioc_g_fmt_vid_out_mplane    = mtk_jpeg_g_fmt_vid_mplane,
 614	.vidioc_s_fmt_vid_cap_mplane    = mtk_jpeg_s_fmt_vid_cap_mplane,
 615	.vidioc_s_fmt_vid_out_mplane    = mtk_jpeg_s_fmt_vid_out_mplane,
 616	.vidioc_qbuf                    = v4l2_m2m_ioctl_qbuf,
 617	.vidioc_subscribe_event         = mtk_jpeg_subscribe_event,
 618	.vidioc_g_selection		= mtk_jpeg_enc_g_selection,
 619	.vidioc_s_selection		= mtk_jpeg_enc_s_selection,
 620
 621	.vidioc_create_bufs		= v4l2_m2m_ioctl_create_bufs,
 622	.vidioc_prepare_buf		= v4l2_m2m_ioctl_prepare_buf,
 623	.vidioc_reqbufs                 = v4l2_m2m_ioctl_reqbufs,
 624	.vidioc_querybuf                = v4l2_m2m_ioctl_querybuf,
 625	.vidioc_dqbuf                   = v4l2_m2m_ioctl_dqbuf,
 626	.vidioc_expbuf                  = v4l2_m2m_ioctl_expbuf,
 627	.vidioc_streamon                = v4l2_m2m_ioctl_streamon,
 628	.vidioc_streamoff               = v4l2_m2m_ioctl_streamoff,
 629
 630	.vidioc_unsubscribe_event	= v4l2_event_unsubscribe,
 631
 632	.vidioc_encoder_cmd		= v4l2_m2m_ioctl_encoder_cmd,
 633	.vidioc_try_encoder_cmd		= v4l2_m2m_ioctl_try_encoder_cmd,
 634};
 635
 636static const struct v4l2_ioctl_ops mtk_jpeg_dec_ioctl_ops = {
 637	.vidioc_querycap                = mtk_jpeg_querycap,
 638	.vidioc_enum_fmt_vid_cap	= mtk_jpeg_enum_fmt_vid_cap,
 639	.vidioc_enum_fmt_vid_out	= mtk_jpeg_enum_fmt_vid_out,
 640	.vidioc_try_fmt_vid_cap_mplane	= mtk_jpeg_try_fmt_vid_cap_mplane,
 641	.vidioc_try_fmt_vid_out_mplane	= mtk_jpeg_try_fmt_vid_out_mplane,
 642	.vidioc_g_fmt_vid_cap_mplane    = mtk_jpeg_g_fmt_vid_mplane,
 643	.vidioc_g_fmt_vid_out_mplane    = mtk_jpeg_g_fmt_vid_mplane,
 644	.vidioc_s_fmt_vid_cap_mplane    = mtk_jpeg_s_fmt_vid_cap_mplane,
 645	.vidioc_s_fmt_vid_out_mplane    = mtk_jpeg_s_fmt_vid_out_mplane,
 646	.vidioc_qbuf                    = mtk_jpeg_qbuf,
 647	.vidioc_subscribe_event         = mtk_jpeg_subscribe_event,
 648	.vidioc_g_selection		= mtk_jpeg_dec_g_selection,
 649
 650	.vidioc_create_bufs		= v4l2_m2m_ioctl_create_bufs,
 651	.vidioc_prepare_buf		= v4l2_m2m_ioctl_prepare_buf,
 652	.vidioc_reqbufs                 = v4l2_m2m_ioctl_reqbufs,
 653	.vidioc_querybuf                = v4l2_m2m_ioctl_querybuf,
 654	.vidioc_dqbuf                   = v4l2_m2m_ioctl_dqbuf,
 655	.vidioc_expbuf                  = v4l2_m2m_ioctl_expbuf,
 656	.vidioc_streamon                = v4l2_m2m_ioctl_streamon,
 657	.vidioc_streamoff               = v4l2_m2m_ioctl_streamoff,
 658
 659	.vidioc_unsubscribe_event	= v4l2_event_unsubscribe,
 660
 661	.vidioc_decoder_cmd = v4l2_m2m_ioctl_decoder_cmd,
 662	.vidioc_try_decoder_cmd = v4l2_m2m_ioctl_try_decoder_cmd,
 663};
 664
 665static int mtk_jpeg_queue_setup(struct vb2_queue *q,
 666				unsigned int *num_buffers,
 667				unsigned int *num_planes,
 668				unsigned int sizes[],
 669				struct device *alloc_ctxs[])
 670{
 671	struct mtk_jpeg_ctx *ctx = vb2_get_drv_priv(q);
 672	struct mtk_jpeg_q_data *q_data = NULL;
 673	struct mtk_jpeg_dev *jpeg = ctx->jpeg;
 674	int i;
 675
 676	v4l2_dbg(1, debug, &jpeg->v4l2_dev, "(%d) buf_req count=%u\n",
 677		 q->type, *num_buffers);
 678
 679	q_data = mtk_jpeg_get_q_data(ctx, q->type);
 680	if (!q_data)
 681		return -EINVAL;
 682
 683	if (*num_planes) {
 684		for (i = 0; i < *num_planes; i++)
 685			if (sizes[i] < q_data->pix_mp.plane_fmt[i].sizeimage)
 686				return -EINVAL;
 687		return 0;
 688	}
 689
 690	*num_planes = q_data->fmt->colplanes;
 691	for (i = 0; i < q_data->fmt->colplanes; i++) {
 692		sizes[i] =  q_data->pix_mp.plane_fmt[i].sizeimage;
 693		v4l2_dbg(1, debug, &jpeg->v4l2_dev, "sizeimage[%d]=%u\n",
 694			 i, sizes[i]);
 695	}
 696
 697	return 0;
 698}
 699
 700static int mtk_jpeg_buf_prepare(struct vb2_buffer *vb)
 701{
 702	struct mtk_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
 703	struct mtk_jpeg_q_data *q_data = NULL;
 704	struct v4l2_plane_pix_format plane_fmt = {};
 705	int i;
 706
 707	q_data = mtk_jpeg_get_q_data(ctx, vb->vb2_queue->type);
 708	if (!q_data)
 709		return -EINVAL;
 710
 711	for (i = 0; i < q_data->fmt->colplanes; i++) {
 712		plane_fmt = q_data->pix_mp.plane_fmt[i];
 713		if (ctx->enable_exif &&
 714		    q_data->fmt->fourcc == V4L2_PIX_FMT_JPEG)
 715			vb2_set_plane_payload(vb, i, plane_fmt.sizeimage +
 716					      MTK_JPEG_MAX_EXIF_SIZE);
 717		else
 718			vb2_set_plane_payload(vb, i,  plane_fmt.sizeimage);
 719	}
 720
 721	return 0;
 722}
 723
 724static bool mtk_jpeg_check_resolution_change(struct mtk_jpeg_ctx *ctx,
 725					     struct mtk_jpeg_dec_param *param)
 726{
 727	struct mtk_jpeg_dev *jpeg = ctx->jpeg;
 728	struct mtk_jpeg_q_data *q_data;
 729
 730	q_data = &ctx->out_q;
 731	if (q_data->pix_mp.width != param->pic_w ||
 732	    q_data->pix_mp.height != param->pic_h) {
 733		v4l2_dbg(1, debug, &jpeg->v4l2_dev, "Picture size change\n");
 734		return true;
 735	}
 736
 737	q_data = &ctx->cap_q;
 738	if (q_data->fmt !=
 739	    mtk_jpeg_find_format(jpeg->variant->formats,
 740				 jpeg->variant->num_formats, param->dst_fourcc,
 741				 MTK_JPEG_FMT_FLAG_CAPTURE)) {
 742		v4l2_dbg(1, debug, &jpeg->v4l2_dev, "format change\n");
 743		return true;
 744	}
 745	return false;
 746}
 747
 748static void mtk_jpeg_set_queue_data(struct mtk_jpeg_ctx *ctx,
 749				    struct mtk_jpeg_dec_param *param)
 750{
 751	struct mtk_jpeg_dev *jpeg = ctx->jpeg;
 752	struct mtk_jpeg_q_data *q_data;
 753	int i;
 754
 755	q_data = &ctx->out_q;
 756	q_data->pix_mp.width = param->pic_w;
 757	q_data->pix_mp.height = param->pic_h;
 758
 759	q_data = &ctx->cap_q;
 760	q_data->pix_mp.width = param->dec_w;
 761	q_data->pix_mp.height = param->dec_h;
 762	q_data->fmt = mtk_jpeg_find_format(jpeg->variant->formats,
 763					   jpeg->variant->num_formats,
 764					   param->dst_fourcc,
 765					   MTK_JPEG_FMT_FLAG_CAPTURE);
 766
 767	for (i = 0; i < q_data->fmt->colplanes; i++) {
 768		q_data->pix_mp.plane_fmt[i].bytesperline = param->mem_stride[i];
 769		q_data->pix_mp.plane_fmt[i].sizeimage = param->comp_size[i];
 770	}
 771
 772	v4l2_dbg(1, debug, &jpeg->v4l2_dev,
 773		 "set_parse cap:%c%c%c%c pic(%u, %u), buf(%u, %u)\n",
 774		 (param->dst_fourcc & 0xff),
 775		 (param->dst_fourcc >>  8 & 0xff),
 776		 (param->dst_fourcc >> 16 & 0xff),
 777		 (param->dst_fourcc >> 24 & 0xff),
 778		 param->pic_w, param->pic_h,
 779		 param->dec_w, param->dec_h);
 780}
 781
 782static void mtk_jpeg_enc_buf_queue(struct vb2_buffer *vb)
 783{
 784	struct mtk_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
 785	struct mtk_jpeg_dev *jpeg = ctx->jpeg;
 786
 787	v4l2_dbg(2, debug, &jpeg->v4l2_dev, "(%d) buf_q id=%d, vb=%p\n",
 788		 vb->vb2_queue->type, vb->index, vb);
 789
 790	v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, to_vb2_v4l2_buffer(vb));
 791}
 792
 793static void mtk_jpeg_dec_buf_queue(struct vb2_buffer *vb)
 794{
 795	struct mtk_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
 796	struct mtk_jpeg_dec_param *param;
 797	struct mtk_jpeg_dev *jpeg = ctx->jpeg;
 798	struct mtk_jpeg_src_buf *jpeg_src_buf;
 799	bool header_valid;
 800
 801	v4l2_dbg(2, debug, &jpeg->v4l2_dev, "(%d) buf_q id=%d, vb=%p\n",
 802		 vb->vb2_queue->type, vb->index, vb);
 803
 804	if (vb->vb2_queue->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
 805		goto end;
 806
 807	jpeg_src_buf = mtk_jpeg_vb2_to_srcbuf(vb);
 808	param = &jpeg_src_buf->dec_param;
 809	memset(param, 0, sizeof(*param));
 810
 811	header_valid = mtk_jpeg_parse(param, (u8 *)vb2_plane_vaddr(vb, 0),
 812				      vb2_get_plane_payload(vb, 0));
 813	if (!header_valid) {
 814		v4l2_err(&jpeg->v4l2_dev, "Header invalid.\n");
 815		vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
 816		return;
 817	}
 818
 819	if (ctx->state == MTK_JPEG_INIT) {
 820		struct vb2_queue *dst_vq = v4l2_m2m_get_vq(
 821			ctx->fh.m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
 822
 823		mtk_jpeg_queue_src_chg_event(ctx);
 824		mtk_jpeg_set_queue_data(ctx, param);
 825		ctx->state = vb2_is_streaming(dst_vq) ?
 826				MTK_JPEG_SOURCE_CHANGE : MTK_JPEG_RUNNING;
 827	}
 828end:
 829	v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, to_vb2_v4l2_buffer(vb));
 830}
 831
 832static struct vb2_v4l2_buffer *mtk_jpeg_buf_remove(struct mtk_jpeg_ctx *ctx,
 833				 enum v4l2_buf_type type)
 834{
 835	if (V4L2_TYPE_IS_OUTPUT(type))
 836		return v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
 837	else
 838		return v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
 839}
 840
 841static void mtk_jpeg_enc_stop_streaming(struct vb2_queue *q)
 842{
 843	struct mtk_jpeg_ctx *ctx = vb2_get_drv_priv(q);
 844	struct vb2_v4l2_buffer *vb;
 845
 846	while ((vb = mtk_jpeg_buf_remove(ctx, q->type)))
 847		v4l2_m2m_buf_done(vb, VB2_BUF_STATE_ERROR);
 848}
 849
 850static void mtk_jpeg_dec_stop_streaming(struct vb2_queue *q)
 851{
 852	struct mtk_jpeg_ctx *ctx = vb2_get_drv_priv(q);
 853	struct vb2_v4l2_buffer *vb;
 854
 855	/*
 856	 * STREAMOFF is an acknowledgment for source change event.
 857	 * Before STREAMOFF, we still have to return the old resolution and
 858	 * subsampling. Update capture queue when the stream is off.
 859	 */
 860	if (ctx->state == MTK_JPEG_SOURCE_CHANGE &&
 861	    V4L2_TYPE_IS_CAPTURE(q->type)) {
 862		struct mtk_jpeg_src_buf *src_buf;
 863
 864		vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
 865		src_buf = mtk_jpeg_vb2_to_srcbuf(&vb->vb2_buf);
 866		mtk_jpeg_set_queue_data(ctx, &src_buf->dec_param);
 867		ctx->state = MTK_JPEG_RUNNING;
 868	} else if (V4L2_TYPE_IS_OUTPUT(q->type)) {
 869		ctx->state = MTK_JPEG_INIT;
 870	}
 871
 872	while ((vb = mtk_jpeg_buf_remove(ctx, q->type)))
 873		v4l2_m2m_buf_done(vb, VB2_BUF_STATE_ERROR);
 874}
 875
 876static const struct vb2_ops mtk_jpeg_dec_qops = {
 877	.queue_setup        = mtk_jpeg_queue_setup,
 878	.buf_prepare        = mtk_jpeg_buf_prepare,
 879	.buf_queue          = mtk_jpeg_dec_buf_queue,
 880	.stop_streaming     = mtk_jpeg_dec_stop_streaming,
 881};
 882
 883static const struct vb2_ops mtk_jpeg_enc_qops = {
 884	.queue_setup        = mtk_jpeg_queue_setup,
 885	.buf_prepare        = mtk_jpeg_buf_prepare,
 886	.buf_queue          = mtk_jpeg_enc_buf_queue,
 887	.stop_streaming     = mtk_jpeg_enc_stop_streaming,
 888};
 889
 890static void mtk_jpeg_set_dec_src(struct mtk_jpeg_ctx *ctx,
 891				 struct vb2_buffer *src_buf,
 892				 struct mtk_jpeg_bs *bs)
 893{
 894	bs->str_addr = vb2_dma_contig_plane_dma_addr(src_buf, 0);
 895	bs->end_addr = bs->str_addr +
 896		       round_up(vb2_get_plane_payload(src_buf, 0), 16);
 897	bs->size = round_up(vb2_plane_size(src_buf, 0), 128);
 898}
 899
 900static int mtk_jpeg_set_dec_dst(struct mtk_jpeg_ctx *ctx,
 901				struct mtk_jpeg_dec_param *param,
 902				struct vb2_buffer *dst_buf,
 903				struct mtk_jpeg_fb *fb)
 904{
 905	int i;
 906
 907	if (param->comp_num != dst_buf->num_planes) {
 908		dev_err(ctx->jpeg->dev, "plane number mismatch (%u != %u)\n",
 909			param->comp_num, dst_buf->num_planes);
 910		return -EINVAL;
 911	}
 912
 913	for (i = 0; i < dst_buf->num_planes; i++) {
 914		if (vb2_plane_size(dst_buf, i) < param->comp_size[i]) {
 915			dev_err(ctx->jpeg->dev,
 916				"buffer size is underflow (%lu < %u)\n",
 917				vb2_plane_size(dst_buf, 0),
 918				param->comp_size[i]);
 919			return -EINVAL;
 920		}
 921		fb->plane_addr[i] = vb2_dma_contig_plane_dma_addr(dst_buf, i);
 922	}
 923
 924	return 0;
 925}
 926
 927static void mtk_jpeg_enc_device_run(void *priv)
 928{
 929	struct mtk_jpeg_ctx *ctx = priv;
 930	struct mtk_jpeg_dev *jpeg = ctx->jpeg;
 931	struct vb2_v4l2_buffer *src_buf, *dst_buf;
 932	enum vb2_buffer_state buf_state = VB2_BUF_STATE_ERROR;
 933	unsigned long flags;
 934	int ret;
 935
 936	src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
 937	dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
 938
 939	ret = pm_runtime_resume_and_get(jpeg->dev);
 940	if (ret < 0)
 941		goto enc_end;
 942
 943	schedule_delayed_work(&jpeg->job_timeout_work,
 944			msecs_to_jiffies(MTK_JPEG_HW_TIMEOUT_MSEC));
 945
 946	spin_lock_irqsave(&jpeg->hw_lock, flags);
 947
 948	/*
 949	 * Resetting the hardware every frame is to ensure that all the
 950	 * registers are cleared. This is a hardware requirement.
 951	 */
 952	mtk_jpeg_enc_reset(jpeg->reg_base);
 953
 954	mtk_jpeg_set_enc_src(ctx, jpeg->reg_base, &src_buf->vb2_buf);
 955	mtk_jpeg_set_enc_dst(ctx, jpeg->reg_base, &dst_buf->vb2_buf);
 956	mtk_jpeg_set_enc_params(ctx, jpeg->reg_base);
 957	mtk_jpeg_enc_start(jpeg->reg_base);
 958	spin_unlock_irqrestore(&jpeg->hw_lock, flags);
 959	return;
 960
 961enc_end:
 962	v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
 963	v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
 964	v4l2_m2m_buf_done(src_buf, buf_state);
 965	v4l2_m2m_buf_done(dst_buf, buf_state);
 966	v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx);
 967}
 968
 969static void mtk_jpeg_multicore_enc_device_run(void *priv)
 970{
 971	struct mtk_jpeg_ctx *ctx = priv;
 972	struct mtk_jpeg_dev *jpeg = ctx->jpeg;
 973
 974	queue_work(jpeg->workqueue, &ctx->jpeg_work);
 975}
 976
 977static void mtk_jpeg_multicore_dec_device_run(void *priv)
 978{
 979	struct mtk_jpeg_ctx *ctx = priv;
 980	struct mtk_jpeg_dev *jpeg = ctx->jpeg;
 981
 982	queue_work(jpeg->workqueue, &ctx->jpeg_work);
 983}
 984
 985static void mtk_jpeg_dec_device_run(void *priv)
 986{
 987	struct mtk_jpeg_ctx *ctx = priv;
 988	struct mtk_jpeg_dev *jpeg = ctx->jpeg;
 989	struct vb2_v4l2_buffer *src_buf, *dst_buf;
 990	enum vb2_buffer_state buf_state = VB2_BUF_STATE_ERROR;
 991	unsigned long flags;
 992	struct mtk_jpeg_src_buf *jpeg_src_buf;
 993	struct mtk_jpeg_bs bs;
 994	struct mtk_jpeg_fb fb;
 995	int ret;
 996
 997	src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
 998	dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
 999	jpeg_src_buf = mtk_jpeg_vb2_to_srcbuf(&src_buf->vb2_buf);
1000
1001	if (mtk_jpeg_check_resolution_change(ctx, &jpeg_src_buf->dec_param)) {
1002		mtk_jpeg_queue_src_chg_event(ctx);
1003		ctx->state = MTK_JPEG_SOURCE_CHANGE;
1004		v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx);
1005		return;
1006	}
1007
1008	ret = pm_runtime_resume_and_get(jpeg->dev);
1009	if (ret < 0)
1010		goto dec_end;
1011
1012	mtk_jpeg_set_dec_src(ctx, &src_buf->vb2_buf, &bs);
1013	if (mtk_jpeg_set_dec_dst(ctx, &jpeg_src_buf->dec_param, &dst_buf->vb2_buf, &fb))
1014		goto dec_end;
1015
1016	schedule_delayed_work(&jpeg->job_timeout_work,
1017			      msecs_to_jiffies(MTK_JPEG_HW_TIMEOUT_MSEC));
1018
1019	spin_lock_irqsave(&jpeg->hw_lock, flags);
1020	mtk_jpeg_dec_reset(jpeg->reg_base);
1021	mtk_jpeg_dec_set_config(jpeg->reg_base,
1022				jpeg->variant->support_34bit,
1023				&jpeg_src_buf->dec_param,
1024				jpeg_src_buf->bs_size,
1025				&bs,
1026				&fb);
1027	mtk_jpeg_dec_start(jpeg->reg_base);
1028	spin_unlock_irqrestore(&jpeg->hw_lock, flags);
1029	return;
1030
1031dec_end:
1032	v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
1033	v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
1034	v4l2_m2m_buf_done(src_buf, buf_state);
1035	v4l2_m2m_buf_done(dst_buf, buf_state);
1036	v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx);
1037}
1038
1039static int mtk_jpeg_dec_job_ready(void *priv)
1040{
1041	struct mtk_jpeg_ctx *ctx = priv;
1042
1043	return (ctx->state == MTK_JPEG_RUNNING) ? 1 : 0;
1044}
1045
1046static const struct v4l2_m2m_ops mtk_jpeg_enc_m2m_ops = {
1047	.device_run = mtk_jpeg_enc_device_run,
1048};
1049
1050static const struct v4l2_m2m_ops mtk_jpeg_multicore_enc_m2m_ops = {
1051	.device_run = mtk_jpeg_multicore_enc_device_run,
1052};
1053
1054static const struct v4l2_m2m_ops mtk_jpeg_multicore_dec_m2m_ops = {
1055	.device_run = mtk_jpeg_multicore_dec_device_run,
1056};
1057
1058static const struct v4l2_m2m_ops mtk_jpeg_dec_m2m_ops = {
1059	.device_run = mtk_jpeg_dec_device_run,
1060	.job_ready  = mtk_jpeg_dec_job_ready,
1061};
1062
1063static int mtk_jpeg_queue_init(void *priv, struct vb2_queue *src_vq,
1064			       struct vb2_queue *dst_vq)
1065{
1066	struct mtk_jpeg_ctx *ctx = priv;
1067	struct mtk_jpeg_dev *jpeg = ctx->jpeg;
1068	int ret;
1069
1070	src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1071	src_vq->io_modes = VB2_DMABUF | VB2_MMAP;
1072	src_vq->drv_priv = ctx;
1073	src_vq->buf_struct_size = sizeof(struct mtk_jpeg_src_buf);
1074	src_vq->ops = jpeg->variant->qops;
1075	src_vq->mem_ops = &vb2_dma_contig_memops;
1076	src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
1077	src_vq->lock = &ctx->jpeg->lock;
1078	src_vq->dev = ctx->jpeg->dev;
1079	ret = vb2_queue_init(src_vq);
1080	if (ret)
1081		return ret;
1082
1083	dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1084	dst_vq->io_modes = VB2_DMABUF | VB2_MMAP;
1085	dst_vq->drv_priv = ctx;
1086	dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
1087	dst_vq->ops = jpeg->variant->qops;
1088	dst_vq->mem_ops = &vb2_dma_contig_memops;
1089	dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
1090	dst_vq->lock = &ctx->jpeg->lock;
1091	dst_vq->dev = ctx->jpeg->dev;
1092	ret = vb2_queue_init(dst_vq);
1093
1094	return ret;
1095}
1096
1097static void mtk_jpeg_clk_on(struct mtk_jpeg_dev *jpeg)
1098{
1099	int ret;
1100
1101	ret = clk_bulk_prepare_enable(jpeg->variant->num_clks,
1102				      jpeg->variant->clks);
1103	if (ret)
1104		dev_err(jpeg->dev, "Failed to open jpeg clk: %d\n", ret);
1105}
1106
1107static void mtk_jpeg_clk_off(struct mtk_jpeg_dev *jpeg)
1108{
1109	clk_bulk_disable_unprepare(jpeg->variant->num_clks,
1110				   jpeg->variant->clks);
1111}
1112
1113static void mtk_jpeg_set_default_params(struct mtk_jpeg_ctx *ctx)
1114{
1115	struct mtk_jpeg_q_data *q = &ctx->out_q;
1116	struct mtk_jpeg_dev *jpeg = ctx->jpeg;
1117
1118	ctx->fh.ctrl_handler = &ctx->ctrl_hdl;
1119	q->pix_mp.colorspace = V4L2_COLORSPACE_SRGB;
1120	q->pix_mp.ycbcr_enc = V4L2_YCBCR_ENC_601;
1121	q->pix_mp.quantization = V4L2_QUANTIZATION_FULL_RANGE;
1122	q->pix_mp.xfer_func = V4L2_XFER_FUNC_SRGB;
1123
1124	q->fmt = mtk_jpeg_find_format(jpeg->variant->formats,
1125				      jpeg->variant->num_formats,
1126				      jpeg->variant->out_q_default_fourcc,
1127				      MTK_JPEG_FMT_FLAG_OUTPUT);
1128	q->pix_mp.width = MTK_JPEG_MIN_WIDTH;
1129	q->pix_mp.height = MTK_JPEG_MIN_HEIGHT;
1130	mtk_jpeg_try_fmt_mplane(&q->pix_mp, q->fmt);
1131
1132	q = &ctx->cap_q;
1133	q->fmt = mtk_jpeg_find_format(jpeg->variant->formats,
1134				      jpeg->variant->num_formats,
1135				      jpeg->variant->cap_q_default_fourcc,
1136				      MTK_JPEG_FMT_FLAG_CAPTURE);
1137	q->pix_mp.colorspace = V4L2_COLORSPACE_SRGB;
1138	q->pix_mp.ycbcr_enc = V4L2_YCBCR_ENC_601;
1139	q->pix_mp.quantization = V4L2_QUANTIZATION_FULL_RANGE;
1140	q->pix_mp.xfer_func = V4L2_XFER_FUNC_SRGB;
1141	q->pix_mp.width = MTK_JPEG_MIN_WIDTH;
1142	q->pix_mp.height = MTK_JPEG_MIN_HEIGHT;
1143
1144	mtk_jpeg_try_fmt_mplane(&q->pix_mp, q->fmt);
1145}
1146
1147static int mtk_jpeg_open(struct file *file)
1148{
1149	struct mtk_jpeg_dev *jpeg = video_drvdata(file);
1150	struct video_device *vfd = video_devdata(file);
1151	struct mtk_jpeg_ctx *ctx;
1152	int ret = 0;
1153
1154	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
1155	if (!ctx)
1156		return -ENOMEM;
1157
1158	if (mutex_lock_interruptible(&jpeg->lock)) {
1159		ret = -ERESTARTSYS;
1160		goto free;
1161	}
1162
1163	INIT_WORK(&ctx->jpeg_work, jpeg->variant->jpeg_worker);
1164	INIT_LIST_HEAD(&ctx->dst_done_queue);
1165	spin_lock_init(&ctx->done_queue_lock);
1166	v4l2_fh_init(&ctx->fh, vfd);
1167	v4l2_fh_add(&ctx->fh, file);
1168
1169	ctx->jpeg = jpeg;
1170	ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(jpeg->m2m_dev, ctx,
1171					    mtk_jpeg_queue_init);
1172	if (IS_ERR(ctx->fh.m2m_ctx)) {
1173		ret = PTR_ERR(ctx->fh.m2m_ctx);
1174		goto error;
1175	}
1176
1177	if (jpeg->variant->cap_q_default_fourcc == V4L2_PIX_FMT_JPEG) {
1178		ret = mtk_jpeg_enc_ctrls_setup(ctx);
1179		if (ret) {
1180			v4l2_err(&jpeg->v4l2_dev, "Failed to setup jpeg enc controls\n");
1181			goto error;
1182		}
1183	} else {
1184		v4l2_ctrl_handler_init(&ctx->ctrl_hdl, 0);
1185	}
1186
1187	mtk_jpeg_set_default_params(ctx);
1188	mutex_unlock(&jpeg->lock);
1189	return 0;
1190
1191error:
1192	v4l2_fh_del(&ctx->fh, file);
1193	v4l2_fh_exit(&ctx->fh);
1194	mutex_unlock(&jpeg->lock);
1195free:
1196	kfree(ctx);
1197	return ret;
1198}
1199
1200static int mtk_jpeg_release(struct file *file)
1201{
1202	struct mtk_jpeg_dev *jpeg = video_drvdata(file);
1203	struct mtk_jpeg_ctx *ctx = mtk_jpeg_file_to_ctx(file);
1204
1205	mutex_lock(&jpeg->lock);
1206	v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
1207	v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
1208	v4l2_fh_del(&ctx->fh, file);
1209	v4l2_fh_exit(&ctx->fh);
1210	kfree(ctx);
1211	mutex_unlock(&jpeg->lock);
1212	return 0;
1213}
1214
1215static const struct v4l2_file_operations mtk_jpeg_fops = {
1216	.owner          = THIS_MODULE,
1217	.open           = mtk_jpeg_open,
1218	.release        = mtk_jpeg_release,
1219	.poll           = v4l2_m2m_fop_poll,
1220	.unlocked_ioctl = video_ioctl2,
1221	.mmap           = v4l2_m2m_fop_mmap,
1222};
1223
1224static void mtk_jpeg_job_timeout_work(struct work_struct *work)
1225{
1226	struct mtk_jpeg_dev *jpeg = container_of(work, struct mtk_jpeg_dev,
1227						 job_timeout_work.work);
1228	struct mtk_jpeg_ctx *ctx;
1229	struct vb2_v4l2_buffer *src_buf, *dst_buf;
1230
1231	ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
1232	src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
1233	dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
1234
1235	jpeg->variant->hw_reset(jpeg->reg_base);
1236
1237	pm_runtime_put(jpeg->dev);
1238
1239	v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_ERROR);
1240	v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_ERROR);
1241	v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx);
1242}
1243
1244static int mtk_jpeg_single_core_init(struct platform_device *pdev,
1245				     struct mtk_jpeg_dev *jpeg_dev)
1246{
1247	struct mtk_jpeg_dev *jpeg = jpeg_dev;
1248	int jpeg_irq, ret;
1249
1250	INIT_DELAYED_WORK(&jpeg->job_timeout_work,
1251			  mtk_jpeg_job_timeout_work);
1252
1253	jpeg->reg_base = devm_platform_ioremap_resource(pdev, 0);
1254	if (IS_ERR(jpeg->reg_base)) {
1255		ret = PTR_ERR(jpeg->reg_base);
1256		return ret;
1257	}
1258
1259	jpeg_irq = platform_get_irq(pdev, 0);
1260	if (jpeg_irq < 0)
1261		return jpeg_irq;
1262
1263	ret = devm_request_irq(&pdev->dev,
1264			       jpeg_irq,
1265			       jpeg->variant->irq_handler,
1266			       0,
1267			       pdev->name, jpeg);
1268	if (ret) {
1269		dev_err(&pdev->dev, "Failed to request jpeg_irq %d (%d)\n",
1270			jpeg_irq, ret);
1271		return ret;
1272	}
1273
1274	ret = devm_clk_bulk_get(jpeg->dev,
1275				jpeg->variant->num_clks,
1276				jpeg->variant->clks);
1277	if (ret) {
1278		dev_err(&pdev->dev, "Failed to init clk\n");
1279		return ret;
1280	}
1281
1282	return 0;
1283}
1284
1285static void mtk_jpeg_destroy_workqueue(void *data)
1286{
1287	destroy_workqueue(data);
1288}
1289
1290static int mtk_jpeg_probe(struct platform_device *pdev)
1291{
1292	struct mtk_jpeg_dev *jpeg;
1293	struct device_node *child;
1294	int num_child = 0;
1295	int ret;
1296
1297	jpeg = devm_kzalloc(&pdev->dev, sizeof(*jpeg), GFP_KERNEL);
1298	if (!jpeg)
1299		return -ENOMEM;
1300
1301	mutex_init(&jpeg->lock);
1302	spin_lock_init(&jpeg->hw_lock);
1303	jpeg->dev = &pdev->dev;
1304	jpeg->variant = of_device_get_match_data(jpeg->dev);
1305
1306	platform_set_drvdata(pdev, jpeg);
1307
1308	ret = devm_of_platform_populate(&pdev->dev);
1309	if (ret) {
1310		v4l2_err(&jpeg->v4l2_dev, "Master of platform populate failed.");
1311		return -EINVAL;
1312	}
1313
1314	if (!jpeg->variant->multi_core) {
1315		ret = mtk_jpeg_single_core_init(pdev, jpeg);
1316		if (ret) {
1317			v4l2_err(&jpeg->v4l2_dev, "mtk_jpeg_single_core_init failed.");
1318			return -EINVAL;
1319		}
1320	} else {
1321		init_waitqueue_head(&jpeg->hw_wq);
1322
1323		for_each_child_of_node(pdev->dev.of_node, child)
1324			num_child++;
1325
1326		atomic_set(&jpeg->hw_rdy, num_child);
1327		atomic_set(&jpeg->hw_index, 0);
1328
1329		jpeg->workqueue = alloc_ordered_workqueue(MTK_JPEG_NAME,
1330							  WQ_MEM_RECLAIM
1331							  | WQ_FREEZABLE);
1332		if (!jpeg->workqueue)
1333			return -EINVAL;
1334		ret = devm_add_action_or_reset(&pdev->dev,
1335					       mtk_jpeg_destroy_workqueue,
1336					       jpeg->workqueue);
1337		if (ret)
1338			return ret;
1339	}
1340
1341	ret = v4l2_device_register(&pdev->dev, &jpeg->v4l2_dev);
1342	if (ret) {
1343		dev_err(&pdev->dev, "Failed to register v4l2 device\n");
1344		return -EINVAL;
1345	}
1346
1347	jpeg->m2m_dev = v4l2_m2m_init(jpeg->variant->m2m_ops);
1348
1349	if (IS_ERR(jpeg->m2m_dev)) {
1350		v4l2_err(&jpeg->v4l2_dev, "Failed to init mem2mem device\n");
1351		ret = PTR_ERR(jpeg->m2m_dev);
1352		goto err_m2m_init;
1353	}
1354
1355	jpeg->vdev = video_device_alloc();
1356	if (!jpeg->vdev) {
1357		ret = -ENOMEM;
1358		goto err_vfd_jpeg_alloc;
1359	}
1360	snprintf(jpeg->vdev->name, sizeof(jpeg->vdev->name),
1361		 "%s", jpeg->variant->dev_name);
1362	jpeg->vdev->fops = &mtk_jpeg_fops;
1363	jpeg->vdev->ioctl_ops = jpeg->variant->ioctl_ops;
1364	jpeg->vdev->minor = -1;
1365	jpeg->vdev->release = video_device_release;
1366	jpeg->vdev->lock = &jpeg->lock;
1367	jpeg->vdev->v4l2_dev = &jpeg->v4l2_dev;
1368	jpeg->vdev->vfl_dir = VFL_DIR_M2M;
1369	jpeg->vdev->device_caps = V4L2_CAP_STREAMING |
1370				  V4L2_CAP_VIDEO_M2M_MPLANE;
1371
1372	ret = video_register_device(jpeg->vdev, VFL_TYPE_VIDEO, -1);
1373	if (ret) {
1374		v4l2_err(&jpeg->v4l2_dev, "Failed to register video device\n");
1375		goto err_vfd_jpeg_register;
1376	}
1377
1378	video_set_drvdata(jpeg->vdev, jpeg);
1379	v4l2_info(&jpeg->v4l2_dev,
1380		  "%s device registered as /dev/video%d (%d,%d)\n",
1381		  jpeg->variant->dev_name, jpeg->vdev->num,
1382		  VIDEO_MAJOR, jpeg->vdev->minor);
1383
1384	pm_runtime_enable(&pdev->dev);
1385
1386	return 0;
1387
1388err_vfd_jpeg_register:
1389	video_device_release(jpeg->vdev);
1390
1391err_vfd_jpeg_alloc:
1392	v4l2_m2m_release(jpeg->m2m_dev);
1393
1394err_m2m_init:
1395	v4l2_device_unregister(&jpeg->v4l2_dev);
1396
1397	return ret;
1398}
1399
1400static void mtk_jpeg_remove(struct platform_device *pdev)
1401{
1402	struct mtk_jpeg_dev *jpeg = platform_get_drvdata(pdev);
1403
1404	pm_runtime_disable(&pdev->dev);
1405	video_unregister_device(jpeg->vdev);
1406	v4l2_m2m_release(jpeg->m2m_dev);
1407	v4l2_device_unregister(&jpeg->v4l2_dev);
1408}
1409
1410static __maybe_unused int mtk_jpeg_pm_suspend(struct device *dev)
1411{
1412	struct mtk_jpeg_dev *jpeg = dev_get_drvdata(dev);
1413
1414	mtk_jpeg_clk_off(jpeg);
1415
1416	return 0;
1417}
1418
1419static __maybe_unused int mtk_jpeg_pm_resume(struct device *dev)
1420{
1421	struct mtk_jpeg_dev *jpeg = dev_get_drvdata(dev);
1422
1423	mtk_jpeg_clk_on(jpeg);
1424
1425	return 0;
1426}
1427
1428static __maybe_unused int mtk_jpeg_suspend(struct device *dev)
1429{
1430	struct mtk_jpeg_dev *jpeg = dev_get_drvdata(dev);
1431
1432	v4l2_m2m_suspend(jpeg->m2m_dev);
1433	return pm_runtime_force_suspend(dev);
1434}
1435
1436static __maybe_unused int mtk_jpeg_resume(struct device *dev)
1437{
1438	struct mtk_jpeg_dev *jpeg = dev_get_drvdata(dev);
1439	int ret;
1440
1441	ret = pm_runtime_force_resume(dev);
1442	if (ret < 0)
1443		return ret;
1444
1445	v4l2_m2m_resume(jpeg->m2m_dev);
1446	return ret;
1447}
1448
1449static const struct dev_pm_ops mtk_jpeg_pm_ops = {
1450	SET_SYSTEM_SLEEP_PM_OPS(mtk_jpeg_suspend, mtk_jpeg_resume)
1451	SET_RUNTIME_PM_OPS(mtk_jpeg_pm_suspend, mtk_jpeg_pm_resume, NULL)
1452};
1453
1454static int mtk_jpegenc_get_hw(struct mtk_jpeg_ctx *ctx)
1455{
1456	struct mtk_jpegenc_comp_dev *comp_jpeg;
1457	struct mtk_jpeg_dev *jpeg = ctx->jpeg;
1458	unsigned long flags;
1459	int hw_id = -1;
1460	int i;
1461
1462	spin_lock_irqsave(&jpeg->hw_lock, flags);
1463	for (i = 0; i < MTK_JPEGENC_HW_MAX; i++) {
1464		comp_jpeg = jpeg->enc_hw_dev[i];
1465		if (comp_jpeg->hw_state == MTK_JPEG_HW_IDLE) {
1466			hw_id = i;
1467			comp_jpeg->hw_state = MTK_JPEG_HW_BUSY;
1468			break;
1469		}
1470	}
1471	spin_unlock_irqrestore(&jpeg->hw_lock, flags);
1472
1473	return hw_id;
1474}
1475
1476static int mtk_jpegenc_set_hw_param(struct mtk_jpeg_ctx *ctx,
1477				    int hw_id,
1478				    struct vb2_v4l2_buffer *src_buf,
1479				    struct vb2_v4l2_buffer *dst_buf)
1480{
1481	struct mtk_jpegenc_comp_dev *jpeg = ctx->jpeg->enc_hw_dev[hw_id];
1482
1483	jpeg->hw_param.curr_ctx = ctx;
1484	jpeg->hw_param.src_buffer = src_buf;
1485	jpeg->hw_param.dst_buffer = dst_buf;
1486
1487	return 0;
1488}
1489
1490static int mtk_jpegenc_put_hw(struct mtk_jpeg_dev *jpeg, int hw_id)
1491{
1492	unsigned long flags;
1493
1494	spin_lock_irqsave(&jpeg->hw_lock, flags);
1495	jpeg->enc_hw_dev[hw_id]->hw_state = MTK_JPEG_HW_IDLE;
1496	spin_unlock_irqrestore(&jpeg->hw_lock, flags);
1497
1498	return 0;
1499}
1500
1501static int mtk_jpegdec_get_hw(struct mtk_jpeg_ctx *ctx)
1502{
1503	struct mtk_jpegdec_comp_dev *comp_jpeg;
1504	struct mtk_jpeg_dev *jpeg = ctx->jpeg;
1505	unsigned long flags;
1506	int hw_id = -1;
1507	int i;
1508
1509	spin_lock_irqsave(&jpeg->hw_lock, flags);
1510	for (i = 0; i < MTK_JPEGDEC_HW_MAX; i++) {
1511		comp_jpeg = jpeg->dec_hw_dev[i];
1512		if (comp_jpeg->hw_state == MTK_JPEG_HW_IDLE) {
1513			hw_id = i;
1514			comp_jpeg->hw_state = MTK_JPEG_HW_BUSY;
1515			break;
1516		}
1517	}
1518	spin_unlock_irqrestore(&jpeg->hw_lock, flags);
1519
1520	return hw_id;
1521}
1522
1523static int mtk_jpegdec_put_hw(struct mtk_jpeg_dev *jpeg, int hw_id)
1524{
1525	unsigned long flags;
1526
1527	spin_lock_irqsave(&jpeg->hw_lock, flags);
1528	jpeg->dec_hw_dev[hw_id]->hw_state =
1529		MTK_JPEG_HW_IDLE;
1530	spin_unlock_irqrestore(&jpeg->hw_lock, flags);
1531
1532	return 0;
1533}
1534
1535static int mtk_jpegdec_set_hw_param(struct mtk_jpeg_ctx *ctx,
1536				    int hw_id,
1537				    struct vb2_v4l2_buffer *src_buf,
1538				    struct vb2_v4l2_buffer *dst_buf)
1539{
1540	struct mtk_jpegdec_comp_dev *jpeg =
1541		ctx->jpeg->dec_hw_dev[hw_id];
1542
1543	jpeg->hw_param.curr_ctx = ctx;
1544	jpeg->hw_param.src_buffer = src_buf;
1545	jpeg->hw_param.dst_buffer = dst_buf;
1546
1547	return 0;
1548}
1549
1550static irqreturn_t mtk_jpeg_enc_done(struct mtk_jpeg_dev *jpeg)
1551{
1552	struct mtk_jpeg_ctx *ctx;
1553	struct vb2_v4l2_buffer *src_buf, *dst_buf;
1554	enum vb2_buffer_state buf_state = VB2_BUF_STATE_ERROR;
1555	u32 result_size;
1556
1557	ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
1558	if (!ctx) {
1559		v4l2_err(&jpeg->v4l2_dev, "Context is NULL\n");
1560		return IRQ_HANDLED;
1561	}
1562
1563	src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
1564	dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
1565
1566	result_size = mtk_jpeg_enc_get_file_size(jpeg->reg_base,
1567						 jpeg->variant->support_34bit);
1568	vb2_set_plane_payload(&dst_buf->vb2_buf, 0, result_size);
1569
1570	buf_state = VB2_BUF_STATE_DONE;
1571
1572	v4l2_m2m_buf_done(src_buf, buf_state);
1573	v4l2_m2m_buf_done(dst_buf, buf_state);
1574	v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx);
1575	pm_runtime_put(ctx->jpeg->dev);
1576	return IRQ_HANDLED;
1577}
1578
1579static void mtk_jpegenc_worker(struct work_struct *work)
1580{
1581	struct mtk_jpegenc_comp_dev *comp_jpeg[MTK_JPEGENC_HW_MAX];
1582	enum vb2_buffer_state buf_state = VB2_BUF_STATE_ERROR;
1583	struct mtk_jpeg_src_buf *jpeg_dst_buf;
1584	struct vb2_v4l2_buffer *src_buf, *dst_buf;
1585	int ret, i, hw_id = 0;
1586	unsigned long flags;
1587
1588	struct mtk_jpeg_ctx *ctx = container_of(work,
1589		struct mtk_jpeg_ctx,
1590		jpeg_work);
1591	struct mtk_jpeg_dev *jpeg = ctx->jpeg;
1592
1593	for (i = 0; i < MTK_JPEGENC_HW_MAX; i++)
1594		comp_jpeg[i] = jpeg->enc_hw_dev[i];
1595	i = 0;
1596
1597retry_select:
1598	hw_id = mtk_jpegenc_get_hw(ctx);
1599	if (hw_id < 0) {
1600		ret = wait_event_interruptible(jpeg->hw_wq,
1601					       atomic_read(&jpeg->hw_rdy) > 0);
1602		if (ret != 0 || (i++ > MTK_JPEG_MAX_RETRY_TIME)) {
1603			dev_err(jpeg->dev, "%s : %d, all HW are busy\n",
1604				__func__, __LINE__);
1605			v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx);
1606			return;
1607		}
1608
1609		goto retry_select;
1610	}
1611
1612	atomic_dec(&jpeg->hw_rdy);
1613	src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
1614	if (!src_buf)
1615		goto getbuf_fail;
1616
1617	dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
1618	if (!dst_buf)
1619		goto getbuf_fail;
1620
1621	v4l2_m2m_buf_copy_metadata(src_buf, dst_buf);
1622
1623	mtk_jpegenc_set_hw_param(ctx, hw_id, src_buf, dst_buf);
1624	ret = pm_runtime_get_sync(comp_jpeg[hw_id]->dev);
1625	if (ret < 0) {
1626		dev_err(jpeg->dev, "%s : %d, pm_runtime_get_sync fail !!!\n",
1627			__func__, __LINE__);
1628		goto enc_end;
1629	}
1630
1631	ret = clk_prepare_enable(comp_jpeg[hw_id]->venc_clk.clks->clk);
1632	if (ret) {
1633		dev_err(jpeg->dev, "%s : %d, jpegenc clk_prepare_enable fail\n",
1634			__func__, __LINE__);
1635		goto enc_end;
1636	}
1637
1638	v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
1639	v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
1640
1641	schedule_delayed_work(&comp_jpeg[hw_id]->job_timeout_work,
1642			      msecs_to_jiffies(MTK_JPEG_HW_TIMEOUT_MSEC));
1643
1644	spin_lock_irqsave(&comp_jpeg[hw_id]->hw_lock, flags);
1645	jpeg_dst_buf = mtk_jpeg_vb2_to_srcbuf(&dst_buf->vb2_buf);
1646	jpeg_dst_buf->curr_ctx = ctx;
1647	jpeg_dst_buf->frame_num = ctx->total_frame_num;
1648	ctx->total_frame_num++;
1649	mtk_jpeg_enc_reset(comp_jpeg[hw_id]->reg_base);
1650	mtk_jpeg_set_enc_dst(ctx,
1651			     comp_jpeg[hw_id]->reg_base,
1652			     &dst_buf->vb2_buf);
1653	mtk_jpeg_set_enc_src(ctx,
1654			     comp_jpeg[hw_id]->reg_base,
1655			     &src_buf->vb2_buf);
1656	mtk_jpeg_set_enc_params(ctx, comp_jpeg[hw_id]->reg_base);
1657	mtk_jpeg_enc_start(comp_jpeg[hw_id]->reg_base);
1658	v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx);
1659	spin_unlock_irqrestore(&comp_jpeg[hw_id]->hw_lock, flags);
1660
1661	return;
1662
1663enc_end:
1664	v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
1665	v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
1666	v4l2_m2m_buf_done(src_buf, buf_state);
1667	v4l2_m2m_buf_done(dst_buf, buf_state);
1668getbuf_fail:
1669	atomic_inc(&jpeg->hw_rdy);
1670	mtk_jpegenc_put_hw(jpeg, hw_id);
1671	v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx);
1672}
1673
1674static void mtk_jpegdec_worker(struct work_struct *work)
1675{
1676	struct mtk_jpeg_ctx *ctx = container_of(work, struct mtk_jpeg_ctx,
1677		jpeg_work);
1678	struct mtk_jpegdec_comp_dev *comp_jpeg[MTK_JPEGDEC_HW_MAX];
1679	enum vb2_buffer_state buf_state = VB2_BUF_STATE_ERROR;
1680	struct mtk_jpeg_src_buf *jpeg_src_buf, *jpeg_dst_buf;
1681	struct vb2_v4l2_buffer *src_buf, *dst_buf;
1682	struct mtk_jpeg_dev *jpeg = ctx->jpeg;
1683	int ret, i, hw_id = 0;
1684	struct mtk_jpeg_bs bs;
1685	struct mtk_jpeg_fb fb;
1686	unsigned long flags;
1687
1688	for (i = 0; i < MTK_JPEGDEC_HW_MAX; i++)
1689		comp_jpeg[i] = jpeg->dec_hw_dev[i];
1690	i = 0;
1691
1692retry_select:
1693	hw_id = mtk_jpegdec_get_hw(ctx);
1694	if (hw_id < 0) {
1695		ret = wait_event_interruptible_timeout(jpeg->hw_wq,
1696						       atomic_read(&jpeg->hw_rdy) > 0,
1697						       MTK_JPEG_HW_TIMEOUT_MSEC);
1698		if (ret != 0 || (i++ > MTK_JPEG_MAX_RETRY_TIME)) {
1699			dev_err(jpeg->dev, "%s : %d, all HW are busy\n",
1700				__func__, __LINE__);
1701			v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx);
1702			return;
1703		}
1704
1705		goto retry_select;
1706	}
1707
1708	atomic_dec(&jpeg->hw_rdy);
1709	src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
1710	if (!src_buf)
1711		goto getbuf_fail;
1712
1713	dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
1714	if (!dst_buf)
1715		goto getbuf_fail;
1716
1717	v4l2_m2m_buf_copy_metadata(src_buf, dst_buf);
1718	jpeg_src_buf = mtk_jpeg_vb2_to_srcbuf(&src_buf->vb2_buf);
1719	jpeg_dst_buf = mtk_jpeg_vb2_to_srcbuf(&dst_buf->vb2_buf);
1720
1721	if (mtk_jpeg_check_resolution_change(ctx,
1722					     &jpeg_src_buf->dec_param)) {
1723		mtk_jpeg_queue_src_chg_event(ctx);
1724		ctx->state = MTK_JPEG_SOURCE_CHANGE;
1725		goto getbuf_fail;
1726	}
1727
1728	jpeg_src_buf->curr_ctx = ctx;
1729	jpeg_src_buf->frame_num = ctx->total_frame_num;
1730	jpeg_dst_buf->curr_ctx = ctx;
1731	jpeg_dst_buf->frame_num = ctx->total_frame_num;
1732
1733	mtk_jpegdec_set_hw_param(ctx, hw_id, src_buf, dst_buf);
1734	ret = pm_runtime_get_sync(comp_jpeg[hw_id]->dev);
1735	if (ret < 0) {
1736		dev_err(jpeg->dev, "%s : %d, pm_runtime_get_sync fail !!!\n",
1737			__func__, __LINE__);
1738		goto dec_end;
1739	}
1740
1741	ret = clk_prepare_enable(comp_jpeg[hw_id]->jdec_clk.clks->clk);
1742	if (ret) {
1743		dev_err(jpeg->dev, "%s : %d, jpegdec clk_prepare_enable fail\n",
1744			__func__, __LINE__);
1745		goto clk_end;
1746	}
1747
1748	v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
1749	v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
1750
1751	mtk_jpeg_set_dec_src(ctx, &src_buf->vb2_buf, &bs);
1752	if (mtk_jpeg_set_dec_dst(ctx,
1753				 &jpeg_src_buf->dec_param,
1754				 &dst_buf->vb2_buf, &fb)) {
1755		dev_err(jpeg->dev, "%s : %d, mtk_jpeg_set_dec_dst fail\n",
1756			__func__, __LINE__);
1757		goto setdst_end;
1758	}
1759
1760	schedule_delayed_work(&comp_jpeg[hw_id]->job_timeout_work,
1761			      msecs_to_jiffies(MTK_JPEG_HW_TIMEOUT_MSEC));
1762
1763	spin_lock_irqsave(&comp_jpeg[hw_id]->hw_lock, flags);
1764	ctx->total_frame_num++;
1765	mtk_jpeg_dec_reset(comp_jpeg[hw_id]->reg_base);
1766	mtk_jpeg_dec_set_config(comp_jpeg[hw_id]->reg_base,
1767				jpeg->variant->support_34bit,
1768				&jpeg_src_buf->dec_param,
1769				jpeg_src_buf->bs_size,
1770				&bs,
1771				&fb);
1772	mtk_jpeg_dec_start(comp_jpeg[hw_id]->reg_base);
1773	v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx);
1774	spin_unlock_irqrestore(&comp_jpeg[hw_id]->hw_lock, flags);
1775
1776	return;
1777
1778setdst_end:
1779	clk_disable_unprepare(comp_jpeg[hw_id]->jdec_clk.clks->clk);
1780clk_end:
1781	pm_runtime_put(comp_jpeg[hw_id]->dev);
1782dec_end:
1783	v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
1784	v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
1785	v4l2_m2m_buf_done(src_buf, buf_state);
1786	v4l2_m2m_buf_done(dst_buf, buf_state);
1787getbuf_fail:
1788	atomic_inc(&jpeg->hw_rdy);
1789	mtk_jpegdec_put_hw(jpeg, hw_id);
1790	v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx);
1791}
1792
1793static irqreturn_t mtk_jpeg_enc_irq(int irq, void *priv)
1794{
1795	struct mtk_jpeg_dev *jpeg = priv;
1796	u32 irq_status;
1797	irqreturn_t ret = IRQ_NONE;
1798
1799	cancel_delayed_work(&jpeg->job_timeout_work);
1800
1801	irq_status = readl(jpeg->reg_base + JPEG_ENC_INT_STS) &
1802		     JPEG_ENC_INT_STATUS_MASK_ALLIRQ;
1803	if (irq_status)
1804		writel(0, jpeg->reg_base + JPEG_ENC_INT_STS);
1805
1806	if (!(irq_status & JPEG_ENC_INT_STATUS_DONE))
1807		return ret;
1808
1809	ret = mtk_jpeg_enc_done(jpeg);
1810	return ret;
1811}
1812
1813static irqreturn_t mtk_jpeg_dec_irq(int irq, void *priv)
1814{
1815	struct mtk_jpeg_dev *jpeg = priv;
1816	struct mtk_jpeg_ctx *ctx;
1817	struct vb2_v4l2_buffer *src_buf, *dst_buf;
1818	struct mtk_jpeg_src_buf *jpeg_src_buf;
1819	enum vb2_buffer_state buf_state = VB2_BUF_STATE_ERROR;
1820	u32	dec_irq_ret;
1821	u32 dec_ret;
1822	int i;
1823
1824	cancel_delayed_work(&jpeg->job_timeout_work);
1825
1826	dec_ret = mtk_jpeg_dec_get_int_status(jpeg->reg_base);
1827	dec_irq_ret = mtk_jpeg_dec_enum_result(dec_ret);
1828	ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
1829	if (!ctx) {
1830		v4l2_err(&jpeg->v4l2_dev, "Context is NULL\n");
1831		return IRQ_HANDLED;
1832	}
1833
1834	src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
1835	dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
1836	jpeg_src_buf = mtk_jpeg_vb2_to_srcbuf(&src_buf->vb2_buf);
1837
1838	if (dec_irq_ret >= MTK_JPEG_DEC_RESULT_UNDERFLOW)
1839		mtk_jpeg_dec_reset(jpeg->reg_base);
1840
1841	if (dec_irq_ret != MTK_JPEG_DEC_RESULT_EOF_DONE) {
1842		dev_err(jpeg->dev, "decode failed\n");
1843		goto dec_end;
1844	}
1845
1846	for (i = 0; i < dst_buf->vb2_buf.num_planes; i++)
1847		vb2_set_plane_payload(&dst_buf->vb2_buf, i,
1848				      jpeg_src_buf->dec_param.comp_size[i]);
1849
1850	buf_state = VB2_BUF_STATE_DONE;
1851
1852dec_end:
1853	v4l2_m2m_buf_done(src_buf, buf_state);
1854	v4l2_m2m_buf_done(dst_buf, buf_state);
1855	v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx);
1856	pm_runtime_put(ctx->jpeg->dev);
1857	return IRQ_HANDLED;
1858}
1859
1860static struct clk_bulk_data mtk_jpeg_clocks[] = {
1861	{ .id = "jpgenc" },
1862};
1863
1864static struct clk_bulk_data mt8173_jpeg_dec_clocks[] = {
1865	{ .id = "jpgdec-smi" },
1866	{ .id = "jpgdec" },
1867};
1868
1869static const struct mtk_jpeg_variant mt8173_jpeg_drvdata = {
1870	.clks = mt8173_jpeg_dec_clocks,
1871	.num_clks = ARRAY_SIZE(mt8173_jpeg_dec_clocks),
1872	.formats = mtk_jpeg_dec_formats,
1873	.num_formats = MTK_JPEG_DEC_NUM_FORMATS,
1874	.qops = &mtk_jpeg_dec_qops,
1875	.irq_handler = mtk_jpeg_dec_irq,
1876	.hw_reset = mtk_jpeg_dec_reset,
1877	.m2m_ops = &mtk_jpeg_dec_m2m_ops,
1878	.dev_name = "mtk-jpeg-dec",
1879	.ioctl_ops = &mtk_jpeg_dec_ioctl_ops,
1880	.out_q_default_fourcc = V4L2_PIX_FMT_JPEG,
1881	.cap_q_default_fourcc = V4L2_PIX_FMT_YUV420M,
1882};
1883
1884static const struct mtk_jpeg_variant mtk_jpeg_drvdata = {
1885	.clks = mtk_jpeg_clocks,
1886	.num_clks = ARRAY_SIZE(mtk_jpeg_clocks),
1887	.formats = mtk_jpeg_enc_formats,
1888	.num_formats = MTK_JPEG_ENC_NUM_FORMATS,
1889	.qops = &mtk_jpeg_enc_qops,
1890	.irq_handler = mtk_jpeg_enc_irq,
1891	.hw_reset = mtk_jpeg_enc_reset,
1892	.m2m_ops = &mtk_jpeg_enc_m2m_ops,
1893	.dev_name = "mtk-jpeg-enc",
1894	.ioctl_ops = &mtk_jpeg_enc_ioctl_ops,
1895	.out_q_default_fourcc = V4L2_PIX_FMT_YUYV,
1896	.cap_q_default_fourcc = V4L2_PIX_FMT_JPEG,
1897	.multi_core = false,
1898};
1899
1900static struct mtk_jpeg_variant mtk8195_jpegenc_drvdata = {
1901	.formats = mtk_jpeg_enc_formats,
1902	.num_formats = MTK_JPEG_ENC_NUM_FORMATS,
1903	.qops = &mtk_jpeg_enc_qops,
1904	.m2m_ops = &mtk_jpeg_multicore_enc_m2m_ops,
1905	.dev_name = "mtk-jpeg-enc",
1906	.ioctl_ops = &mtk_jpeg_enc_ioctl_ops,
1907	.out_q_default_fourcc = V4L2_PIX_FMT_YUYV,
1908	.cap_q_default_fourcc = V4L2_PIX_FMT_JPEG,
1909	.multi_core = true,
1910	.jpeg_worker = mtk_jpegenc_worker,
1911};
1912
1913static const struct mtk_jpeg_variant mtk8195_jpegdec_drvdata = {
1914	.formats = mtk_jpeg_dec_formats,
1915	.num_formats = MTK_JPEG_DEC_NUM_FORMATS,
1916	.qops = &mtk_jpeg_dec_qops,
1917	.m2m_ops = &mtk_jpeg_multicore_dec_m2m_ops,
1918	.dev_name = "mtk-jpeg-dec",
1919	.ioctl_ops = &mtk_jpeg_dec_ioctl_ops,
1920	.out_q_default_fourcc = V4L2_PIX_FMT_JPEG,
1921	.cap_q_default_fourcc = V4L2_PIX_FMT_YUV420M,
1922	.multi_core = true,
1923	.jpeg_worker = mtk_jpegdec_worker,
1924};
1925
1926static const struct of_device_id mtk_jpeg_match[] = {
1927	{
1928		.compatible = "mediatek,mt8173-jpgdec",
1929		.data = &mt8173_jpeg_drvdata,
1930	},
1931	{
1932		.compatible = "mediatek,mt2701-jpgdec",
1933		.data = &mt8173_jpeg_drvdata,
1934	},
1935	{
1936		.compatible = "mediatek,mtk-jpgenc",
1937		.data = &mtk_jpeg_drvdata,
1938	},
1939	{
1940		.compatible = "mediatek,mt8195-jpgenc",
1941		.data = &mtk8195_jpegenc_drvdata,
1942	},
1943	{
1944		.compatible = "mediatek,mt8195-jpgdec",
1945		.data = &mtk8195_jpegdec_drvdata,
1946	},
1947	{},
1948};
1949
1950MODULE_DEVICE_TABLE(of, mtk_jpeg_match);
1951
1952static struct platform_driver mtk_jpeg_driver = {
1953	.probe = mtk_jpeg_probe,
1954	.remove = mtk_jpeg_remove,
1955	.driver = {
1956		.name           = MTK_JPEG_NAME,
1957		.of_match_table = mtk_jpeg_match,
1958		.pm             = &mtk_jpeg_pm_ops,
1959	},
1960};
1961
1962module_platform_driver(mtk_jpeg_driver);
1963
1964MODULE_DESCRIPTION("MediaTek JPEG codec driver");
1965MODULE_LICENSE("GPL v2");
~/ Read-only file preview.