162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright 2020-2021 NXP
462306a36Sopenharmony_ci */
562306a36Sopenharmony_ci
662306a36Sopenharmony_ci#include <linux/init.h>
762306a36Sopenharmony_ci#include <linux/interconnect.h>
862306a36Sopenharmony_ci#include <linux/ioctl.h>
962306a36Sopenharmony_ci#include <linux/list.h>
1062306a36Sopenharmony_ci#include <linux/kernel.h>
1162306a36Sopenharmony_ci#include <linux/module.h>
1262306a36Sopenharmony_ci#include <linux/platform_device.h>
1362306a36Sopenharmony_ci#include "vpu.h"
1462306a36Sopenharmony_ci#include "vpu_defs.h"
1562306a36Sopenharmony_ci#include "vpu_core.h"
1662306a36Sopenharmony_ci#include "vpu_rpc.h"
1762306a36Sopenharmony_ci#include "vpu_helpers.h"
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ciint vpu_helper_find_in_array_u8(const u8 *array, u32 size, u32 x)
2062306a36Sopenharmony_ci{
2162306a36Sopenharmony_ci	int i;
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_ci	for (i = 0; i < size; i++) {
2462306a36Sopenharmony_ci		if (array[i] == x)
2562306a36Sopenharmony_ci			return i;
2662306a36Sopenharmony_ci	}
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_ci	return 0;
2962306a36Sopenharmony_ci}
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_cibool vpu_helper_check_type(struct vpu_inst *inst, u32 type)
3262306a36Sopenharmony_ci{
3362306a36Sopenharmony_ci	const struct vpu_format *pfmt;
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_ci	for (pfmt = inst->formats; pfmt->pixfmt; pfmt++) {
3662306a36Sopenharmony_ci		if (!vpu_iface_check_format(inst, pfmt->pixfmt))
3762306a36Sopenharmony_ci			continue;
3862306a36Sopenharmony_ci		if (pfmt->type == type)
3962306a36Sopenharmony_ci			return true;
4062306a36Sopenharmony_ci	}
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_ci	return false;
4362306a36Sopenharmony_ci}
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_ciconst struct vpu_format *vpu_helper_find_format(struct vpu_inst *inst, u32 type, u32 pixelfmt)
4662306a36Sopenharmony_ci{
4762306a36Sopenharmony_ci	const struct vpu_format *pfmt;
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_ci	if (!inst || !inst->formats)
5062306a36Sopenharmony_ci		return NULL;
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_ci	if (!vpu_iface_check_format(inst, pixelfmt))
5362306a36Sopenharmony_ci		return NULL;
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_ci	for (pfmt = inst->formats; pfmt->pixfmt; pfmt++) {
5662306a36Sopenharmony_ci		if (pfmt->pixfmt == pixelfmt && (!type || type == pfmt->type))
5762306a36Sopenharmony_ci			return pfmt;
5862306a36Sopenharmony_ci	}
5962306a36Sopenharmony_ci
6062306a36Sopenharmony_ci	return NULL;
6162306a36Sopenharmony_ci}
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_ciconst struct vpu_format *vpu_helper_find_sibling(struct vpu_inst *inst, u32 type, u32 pixelfmt)
6462306a36Sopenharmony_ci{
6562306a36Sopenharmony_ci	const struct vpu_format *fmt;
6662306a36Sopenharmony_ci	const struct vpu_format *sibling;
6762306a36Sopenharmony_ci
6862306a36Sopenharmony_ci	fmt = vpu_helper_find_format(inst, type, pixelfmt);
6962306a36Sopenharmony_ci	if (!fmt || !fmt->sibling)
7062306a36Sopenharmony_ci		return NULL;
7162306a36Sopenharmony_ci
7262306a36Sopenharmony_ci	sibling = vpu_helper_find_format(inst, type, fmt->sibling);
7362306a36Sopenharmony_ci	if (!sibling || sibling->sibling != fmt->pixfmt ||
7462306a36Sopenharmony_ci	    sibling->comp_planes != fmt->comp_planes)
7562306a36Sopenharmony_ci		return NULL;
7662306a36Sopenharmony_ci
7762306a36Sopenharmony_ci	return sibling;
7862306a36Sopenharmony_ci}
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_cibool vpu_helper_match_format(struct vpu_inst *inst, u32 type, u32 fmta, u32 fmtb)
8162306a36Sopenharmony_ci{
8262306a36Sopenharmony_ci	const struct vpu_format *sibling;
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_ci	if (fmta == fmtb)
8562306a36Sopenharmony_ci		return true;
8662306a36Sopenharmony_ci
8762306a36Sopenharmony_ci	sibling = vpu_helper_find_sibling(inst, type, fmta);
8862306a36Sopenharmony_ci	if (sibling && sibling->pixfmt == fmtb)
8962306a36Sopenharmony_ci		return true;
9062306a36Sopenharmony_ci	return false;
9162306a36Sopenharmony_ci}
9262306a36Sopenharmony_ci
9362306a36Sopenharmony_ciconst struct vpu_format *vpu_helper_enum_format(struct vpu_inst *inst, u32 type, int index)
9462306a36Sopenharmony_ci{
9562306a36Sopenharmony_ci	const struct vpu_format *pfmt;
9662306a36Sopenharmony_ci	int i = 0;
9762306a36Sopenharmony_ci
9862306a36Sopenharmony_ci	if (!inst || !inst->formats)
9962306a36Sopenharmony_ci		return NULL;
10062306a36Sopenharmony_ci
10162306a36Sopenharmony_ci	for (pfmt = inst->formats; pfmt->pixfmt; pfmt++) {
10262306a36Sopenharmony_ci		if (!vpu_iface_check_format(inst, pfmt->pixfmt))
10362306a36Sopenharmony_ci			continue;
10462306a36Sopenharmony_ci
10562306a36Sopenharmony_ci		if (pfmt->type == type) {
10662306a36Sopenharmony_ci			if (index == i)
10762306a36Sopenharmony_ci				return pfmt;
10862306a36Sopenharmony_ci			i++;
10962306a36Sopenharmony_ci		}
11062306a36Sopenharmony_ci	}
11162306a36Sopenharmony_ci
11262306a36Sopenharmony_ci	return NULL;
11362306a36Sopenharmony_ci}
11462306a36Sopenharmony_ci
11562306a36Sopenharmony_ciu32 vpu_helper_valid_frame_width(struct vpu_inst *inst, u32 width)
11662306a36Sopenharmony_ci{
11762306a36Sopenharmony_ci	const struct vpu_core_resources *res;
11862306a36Sopenharmony_ci
11962306a36Sopenharmony_ci	if (!inst)
12062306a36Sopenharmony_ci		return width;
12162306a36Sopenharmony_ci
12262306a36Sopenharmony_ci	res = vpu_get_resource(inst);
12362306a36Sopenharmony_ci	if (!res)
12462306a36Sopenharmony_ci		return width;
12562306a36Sopenharmony_ci	if (res->max_width)
12662306a36Sopenharmony_ci		width = clamp(width, res->min_width, res->max_width);
12762306a36Sopenharmony_ci	if (res->step_width)
12862306a36Sopenharmony_ci		width = ALIGN(width, res->step_width);
12962306a36Sopenharmony_ci
13062306a36Sopenharmony_ci	return width;
13162306a36Sopenharmony_ci}
13262306a36Sopenharmony_ci
13362306a36Sopenharmony_ciu32 vpu_helper_valid_frame_height(struct vpu_inst *inst, u32 height)
13462306a36Sopenharmony_ci{
13562306a36Sopenharmony_ci	const struct vpu_core_resources *res;
13662306a36Sopenharmony_ci
13762306a36Sopenharmony_ci	if (!inst)
13862306a36Sopenharmony_ci		return height;
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_ci	res = vpu_get_resource(inst);
14162306a36Sopenharmony_ci	if (!res)
14262306a36Sopenharmony_ci		return height;
14362306a36Sopenharmony_ci	if (res->max_height)
14462306a36Sopenharmony_ci		height = clamp(height, res->min_height, res->max_height);
14562306a36Sopenharmony_ci	if (res->step_height)
14662306a36Sopenharmony_ci		height = ALIGN(height, res->step_height);
14762306a36Sopenharmony_ci
14862306a36Sopenharmony_ci	return height;
14962306a36Sopenharmony_ci}
15062306a36Sopenharmony_ci
15162306a36Sopenharmony_cistatic u32 get_nv12_plane_size(u32 width, u32 height, int plane_no,
15262306a36Sopenharmony_ci			       u32 stride, u32 interlaced, u32 *pbl)
15362306a36Sopenharmony_ci{
15462306a36Sopenharmony_ci	u32 bytesperline;
15562306a36Sopenharmony_ci	u32 size = 0;
15662306a36Sopenharmony_ci
15762306a36Sopenharmony_ci	bytesperline = width;
15862306a36Sopenharmony_ci	if (pbl)
15962306a36Sopenharmony_ci		bytesperline = max(bytesperline, *pbl);
16062306a36Sopenharmony_ci	bytesperline = ALIGN(bytesperline, stride);
16162306a36Sopenharmony_ci	height = ALIGN(height, 2);
16262306a36Sopenharmony_ci	if (plane_no == 0)
16362306a36Sopenharmony_ci		size = bytesperline * height;
16462306a36Sopenharmony_ci	else if (plane_no == 1)
16562306a36Sopenharmony_ci		size = bytesperline * height >> 1;
16662306a36Sopenharmony_ci	if (pbl)
16762306a36Sopenharmony_ci		*pbl = bytesperline;
16862306a36Sopenharmony_ci
16962306a36Sopenharmony_ci	return size;
17062306a36Sopenharmony_ci}
17162306a36Sopenharmony_ci
17262306a36Sopenharmony_cistatic u32 get_tiled_8l128_plane_size(u32 fmt, u32 width, u32 height, int plane_no,
17362306a36Sopenharmony_ci				      u32 stride, u32 interlaced, u32 *pbl)
17462306a36Sopenharmony_ci{
17562306a36Sopenharmony_ci	u32 ws = 3;
17662306a36Sopenharmony_ci	u32 hs = 7;
17762306a36Sopenharmony_ci	u32 bitdepth = 8;
17862306a36Sopenharmony_ci	u32 bytesperline;
17962306a36Sopenharmony_ci	u32 size = 0;
18062306a36Sopenharmony_ci
18162306a36Sopenharmony_ci	if (interlaced)
18262306a36Sopenharmony_ci		hs++;
18362306a36Sopenharmony_ci	if (fmt == V4L2_PIX_FMT_NV12M_10BE_8L128 || fmt == V4L2_PIX_FMT_NV12_10BE_8L128)
18462306a36Sopenharmony_ci		bitdepth = 10;
18562306a36Sopenharmony_ci	bytesperline = DIV_ROUND_UP(width * bitdepth, BITS_PER_BYTE);
18662306a36Sopenharmony_ci	if (pbl)
18762306a36Sopenharmony_ci		bytesperline = max(bytesperline, *pbl);
18862306a36Sopenharmony_ci	bytesperline = ALIGN(bytesperline, 1 << ws);
18962306a36Sopenharmony_ci	bytesperline = ALIGN(bytesperline, stride);
19062306a36Sopenharmony_ci	height = ALIGN(height, 1 << hs);
19162306a36Sopenharmony_ci	if (plane_no == 0)
19262306a36Sopenharmony_ci		size = bytesperline * height;
19362306a36Sopenharmony_ci	else if (plane_no == 1)
19462306a36Sopenharmony_ci		size = (bytesperline * ALIGN(height, 1 << (hs + 1))) >> 1;
19562306a36Sopenharmony_ci	if (pbl)
19662306a36Sopenharmony_ci		*pbl = bytesperline;
19762306a36Sopenharmony_ci
19862306a36Sopenharmony_ci	return size;
19962306a36Sopenharmony_ci}
20062306a36Sopenharmony_ci
20162306a36Sopenharmony_cistatic u32 get_default_plane_size(u32 width, u32 height, int plane_no,
20262306a36Sopenharmony_ci				  u32 stride, u32 interlaced, u32 *pbl)
20362306a36Sopenharmony_ci{
20462306a36Sopenharmony_ci	u32 bytesperline;
20562306a36Sopenharmony_ci	u32 size = 0;
20662306a36Sopenharmony_ci
20762306a36Sopenharmony_ci	bytesperline = width;
20862306a36Sopenharmony_ci	if (pbl)
20962306a36Sopenharmony_ci		bytesperline = max(bytesperline, *pbl);
21062306a36Sopenharmony_ci	bytesperline = ALIGN(bytesperline, stride);
21162306a36Sopenharmony_ci	if (plane_no == 0)
21262306a36Sopenharmony_ci		size = bytesperline * height;
21362306a36Sopenharmony_ci	if (pbl)
21462306a36Sopenharmony_ci		*pbl = bytesperline;
21562306a36Sopenharmony_ci
21662306a36Sopenharmony_ci	return size;
21762306a36Sopenharmony_ci}
21862306a36Sopenharmony_ci
21962306a36Sopenharmony_ciu32 vpu_helper_get_plane_size(u32 fmt, u32 w, u32 h, int plane_no,
22062306a36Sopenharmony_ci			      u32 stride, u32 interlaced, u32 *pbl)
22162306a36Sopenharmony_ci{
22262306a36Sopenharmony_ci	switch (fmt) {
22362306a36Sopenharmony_ci	case V4L2_PIX_FMT_NV12:
22462306a36Sopenharmony_ci	case V4L2_PIX_FMT_NV12M:
22562306a36Sopenharmony_ci		return get_nv12_plane_size(w, h, plane_no, stride, interlaced, pbl);
22662306a36Sopenharmony_ci	case V4L2_PIX_FMT_NV12_8L128:
22762306a36Sopenharmony_ci	case V4L2_PIX_FMT_NV12M_8L128:
22862306a36Sopenharmony_ci	case V4L2_PIX_FMT_NV12_10BE_8L128:
22962306a36Sopenharmony_ci	case V4L2_PIX_FMT_NV12M_10BE_8L128:
23062306a36Sopenharmony_ci		return get_tiled_8l128_plane_size(fmt, w, h, plane_no, stride, interlaced, pbl);
23162306a36Sopenharmony_ci	default:
23262306a36Sopenharmony_ci		return get_default_plane_size(w, h, plane_no, stride, interlaced, pbl);
23362306a36Sopenharmony_ci	}
23462306a36Sopenharmony_ci}
23562306a36Sopenharmony_ci
23662306a36Sopenharmony_ciint vpu_helper_copy_from_stream_buffer(struct vpu_buffer *stream_buffer,
23762306a36Sopenharmony_ci				       u32 *rptr, u32 size, void *dst)
23862306a36Sopenharmony_ci{
23962306a36Sopenharmony_ci	u32 offset;
24062306a36Sopenharmony_ci	u32 start;
24162306a36Sopenharmony_ci	u32 end;
24262306a36Sopenharmony_ci	void *virt;
24362306a36Sopenharmony_ci
24462306a36Sopenharmony_ci	if (!stream_buffer || !rptr || !dst)
24562306a36Sopenharmony_ci		return -EINVAL;
24662306a36Sopenharmony_ci
24762306a36Sopenharmony_ci	if (!size)
24862306a36Sopenharmony_ci		return 0;
24962306a36Sopenharmony_ci
25062306a36Sopenharmony_ci	offset = *rptr;
25162306a36Sopenharmony_ci	start = stream_buffer->phys;
25262306a36Sopenharmony_ci	end = start + stream_buffer->length;
25362306a36Sopenharmony_ci	virt = stream_buffer->virt;
25462306a36Sopenharmony_ci
25562306a36Sopenharmony_ci	if (offset < start || offset > end)
25662306a36Sopenharmony_ci		return -EINVAL;
25762306a36Sopenharmony_ci
25862306a36Sopenharmony_ci	if (offset + size <= end) {
25962306a36Sopenharmony_ci		memcpy(dst, virt + (offset - start), size);
26062306a36Sopenharmony_ci	} else {
26162306a36Sopenharmony_ci		memcpy(dst, virt + (offset - start), end - offset);
26262306a36Sopenharmony_ci		memcpy(dst + end - offset, virt, size + offset - end);
26362306a36Sopenharmony_ci	}
26462306a36Sopenharmony_ci
26562306a36Sopenharmony_ci	*rptr = vpu_helper_step_walk(stream_buffer, offset, size);
26662306a36Sopenharmony_ci
26762306a36Sopenharmony_ci	return 0;
26862306a36Sopenharmony_ci}
26962306a36Sopenharmony_ci
27062306a36Sopenharmony_ciint vpu_helper_copy_to_stream_buffer(struct vpu_buffer *stream_buffer,
27162306a36Sopenharmony_ci				     u32 *wptr, u32 size, void *src)
27262306a36Sopenharmony_ci{
27362306a36Sopenharmony_ci	u32 offset;
27462306a36Sopenharmony_ci	u32 start;
27562306a36Sopenharmony_ci	u32 end;
27662306a36Sopenharmony_ci	void *virt;
27762306a36Sopenharmony_ci
27862306a36Sopenharmony_ci	if (!stream_buffer || !wptr || !src)
27962306a36Sopenharmony_ci		return -EINVAL;
28062306a36Sopenharmony_ci
28162306a36Sopenharmony_ci	if (!size)
28262306a36Sopenharmony_ci		return 0;
28362306a36Sopenharmony_ci
28462306a36Sopenharmony_ci	offset = *wptr;
28562306a36Sopenharmony_ci	start = stream_buffer->phys;
28662306a36Sopenharmony_ci	end = start + stream_buffer->length;
28762306a36Sopenharmony_ci	virt = stream_buffer->virt;
28862306a36Sopenharmony_ci	if (offset < start || offset > end)
28962306a36Sopenharmony_ci		return -EINVAL;
29062306a36Sopenharmony_ci
29162306a36Sopenharmony_ci	if (offset + size <= end) {
29262306a36Sopenharmony_ci		memcpy(virt + (offset - start), src, size);
29362306a36Sopenharmony_ci	} else {
29462306a36Sopenharmony_ci		memcpy(virt + (offset - start), src, end - offset);
29562306a36Sopenharmony_ci		memcpy(virt, src + end - offset, size + offset - end);
29662306a36Sopenharmony_ci	}
29762306a36Sopenharmony_ci
29862306a36Sopenharmony_ci	*wptr = vpu_helper_step_walk(stream_buffer, offset, size);
29962306a36Sopenharmony_ci
30062306a36Sopenharmony_ci	return 0;
30162306a36Sopenharmony_ci}
30262306a36Sopenharmony_ci
30362306a36Sopenharmony_ciint vpu_helper_memset_stream_buffer(struct vpu_buffer *stream_buffer,
30462306a36Sopenharmony_ci				    u32 *wptr, u8 val, u32 size)
30562306a36Sopenharmony_ci{
30662306a36Sopenharmony_ci	u32 offset;
30762306a36Sopenharmony_ci	u32 start;
30862306a36Sopenharmony_ci	u32 end;
30962306a36Sopenharmony_ci	void *virt;
31062306a36Sopenharmony_ci
31162306a36Sopenharmony_ci	if (!stream_buffer || !wptr)
31262306a36Sopenharmony_ci		return -EINVAL;
31362306a36Sopenharmony_ci
31462306a36Sopenharmony_ci	if (!size)
31562306a36Sopenharmony_ci		return 0;
31662306a36Sopenharmony_ci
31762306a36Sopenharmony_ci	offset = *wptr;
31862306a36Sopenharmony_ci	start = stream_buffer->phys;
31962306a36Sopenharmony_ci	end = start + stream_buffer->length;
32062306a36Sopenharmony_ci	virt = stream_buffer->virt;
32162306a36Sopenharmony_ci	if (offset < start || offset > end)
32262306a36Sopenharmony_ci		return -EINVAL;
32362306a36Sopenharmony_ci
32462306a36Sopenharmony_ci	if (offset + size <= end) {
32562306a36Sopenharmony_ci		memset(virt + (offset - start), val, size);
32662306a36Sopenharmony_ci	} else {
32762306a36Sopenharmony_ci		memset(virt + (offset - start), val, end - offset);
32862306a36Sopenharmony_ci		memset(virt, val, size + offset - end);
32962306a36Sopenharmony_ci	}
33062306a36Sopenharmony_ci
33162306a36Sopenharmony_ci	offset += size;
33262306a36Sopenharmony_ci	if (offset >= end)
33362306a36Sopenharmony_ci		offset -= stream_buffer->length;
33462306a36Sopenharmony_ci
33562306a36Sopenharmony_ci	*wptr = offset;
33662306a36Sopenharmony_ci
33762306a36Sopenharmony_ci	return 0;
33862306a36Sopenharmony_ci}
33962306a36Sopenharmony_ci
34062306a36Sopenharmony_ciu32 vpu_helper_get_free_space(struct vpu_inst *inst)
34162306a36Sopenharmony_ci{
34262306a36Sopenharmony_ci	struct vpu_rpc_buffer_desc desc;
34362306a36Sopenharmony_ci
34462306a36Sopenharmony_ci	if (vpu_iface_get_stream_buffer_desc(inst, &desc))
34562306a36Sopenharmony_ci		return 0;
34662306a36Sopenharmony_ci
34762306a36Sopenharmony_ci	if (desc.rptr > desc.wptr)
34862306a36Sopenharmony_ci		return desc.rptr - desc.wptr;
34962306a36Sopenharmony_ci	else if (desc.rptr < desc.wptr)
35062306a36Sopenharmony_ci		return (desc.end - desc.start + desc.rptr - desc.wptr);
35162306a36Sopenharmony_ci	else
35262306a36Sopenharmony_ci		return desc.end - desc.start;
35362306a36Sopenharmony_ci}
35462306a36Sopenharmony_ci
35562306a36Sopenharmony_ciu32 vpu_helper_get_used_space(struct vpu_inst *inst)
35662306a36Sopenharmony_ci{
35762306a36Sopenharmony_ci	struct vpu_rpc_buffer_desc desc;
35862306a36Sopenharmony_ci
35962306a36Sopenharmony_ci	if (vpu_iface_get_stream_buffer_desc(inst, &desc))
36062306a36Sopenharmony_ci		return 0;
36162306a36Sopenharmony_ci
36262306a36Sopenharmony_ci	if (desc.wptr > desc.rptr)
36362306a36Sopenharmony_ci		return desc.wptr - desc.rptr;
36462306a36Sopenharmony_ci	else if (desc.wptr < desc.rptr)
36562306a36Sopenharmony_ci		return (desc.end - desc.start + desc.wptr - desc.rptr);
36662306a36Sopenharmony_ci	else
36762306a36Sopenharmony_ci		return 0;
36862306a36Sopenharmony_ci}
36962306a36Sopenharmony_ci
37062306a36Sopenharmony_ciint vpu_helper_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
37162306a36Sopenharmony_ci{
37262306a36Sopenharmony_ci	struct vpu_inst *inst = ctrl_to_inst(ctrl);
37362306a36Sopenharmony_ci
37462306a36Sopenharmony_ci	switch (ctrl->id) {
37562306a36Sopenharmony_ci	case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE:
37662306a36Sopenharmony_ci		ctrl->val = inst->min_buffer_cap;
37762306a36Sopenharmony_ci		break;
37862306a36Sopenharmony_ci	case V4L2_CID_MIN_BUFFERS_FOR_OUTPUT:
37962306a36Sopenharmony_ci		ctrl->val = inst->min_buffer_out;
38062306a36Sopenharmony_ci		break;
38162306a36Sopenharmony_ci	default:
38262306a36Sopenharmony_ci		return -EINVAL;
38362306a36Sopenharmony_ci	}
38462306a36Sopenharmony_ci
38562306a36Sopenharmony_ci	return 0;
38662306a36Sopenharmony_ci}
38762306a36Sopenharmony_ci
38862306a36Sopenharmony_ciint vpu_helper_find_startcode(struct vpu_buffer *stream_buffer,
38962306a36Sopenharmony_ci			      u32 pixelformat, u32 offset, u32 bytesused)
39062306a36Sopenharmony_ci{
39162306a36Sopenharmony_ci	u32 start_code;
39262306a36Sopenharmony_ci	int start_code_size;
39362306a36Sopenharmony_ci	u32 val = 0;
39462306a36Sopenharmony_ci	int i;
39562306a36Sopenharmony_ci	int ret = -EINVAL;
39662306a36Sopenharmony_ci
39762306a36Sopenharmony_ci	if (!stream_buffer || !stream_buffer->virt)
39862306a36Sopenharmony_ci		return -EINVAL;
39962306a36Sopenharmony_ci
40062306a36Sopenharmony_ci	switch (pixelformat) {
40162306a36Sopenharmony_ci	case V4L2_PIX_FMT_H264:
40262306a36Sopenharmony_ci		start_code_size = 4;
40362306a36Sopenharmony_ci		start_code = 0x00000001;
40462306a36Sopenharmony_ci		break;
40562306a36Sopenharmony_ci	default:
40662306a36Sopenharmony_ci		return 0;
40762306a36Sopenharmony_ci	}
40862306a36Sopenharmony_ci
40962306a36Sopenharmony_ci	for (i = 0; i < bytesused; i++) {
41062306a36Sopenharmony_ci		val = (val << 8) | vpu_helper_read_byte(stream_buffer, offset + i);
41162306a36Sopenharmony_ci		if (i < start_code_size - 1)
41262306a36Sopenharmony_ci			continue;
41362306a36Sopenharmony_ci		if (val == start_code) {
41462306a36Sopenharmony_ci			ret = i + 1 - start_code_size;
41562306a36Sopenharmony_ci			break;
41662306a36Sopenharmony_ci		}
41762306a36Sopenharmony_ci	}
41862306a36Sopenharmony_ci
41962306a36Sopenharmony_ci	return ret;
42062306a36Sopenharmony_ci}
42162306a36Sopenharmony_ci
42262306a36Sopenharmony_ciint vpu_find_dst_by_src(struct vpu_pair *pairs, u32 cnt, u32 src)
42362306a36Sopenharmony_ci{
42462306a36Sopenharmony_ci	u32 i;
42562306a36Sopenharmony_ci
42662306a36Sopenharmony_ci	if (!pairs || !cnt)
42762306a36Sopenharmony_ci		return -EINVAL;
42862306a36Sopenharmony_ci
42962306a36Sopenharmony_ci	for (i = 0; i < cnt; i++) {
43062306a36Sopenharmony_ci		if (pairs[i].src == src)
43162306a36Sopenharmony_ci			return pairs[i].dst;
43262306a36Sopenharmony_ci	}
43362306a36Sopenharmony_ci
43462306a36Sopenharmony_ci	return -EINVAL;
43562306a36Sopenharmony_ci}
43662306a36Sopenharmony_ci
43762306a36Sopenharmony_ciint vpu_find_src_by_dst(struct vpu_pair *pairs, u32 cnt, u32 dst)
43862306a36Sopenharmony_ci{
43962306a36Sopenharmony_ci	u32 i;
44062306a36Sopenharmony_ci
44162306a36Sopenharmony_ci	if (!pairs || !cnt)
44262306a36Sopenharmony_ci		return -EINVAL;
44362306a36Sopenharmony_ci
44462306a36Sopenharmony_ci	for (i = 0; i < cnt; i++) {
44562306a36Sopenharmony_ci		if (pairs[i].dst == dst)
44662306a36Sopenharmony_ci			return pairs[i].src;
44762306a36Sopenharmony_ci	}
44862306a36Sopenharmony_ci
44962306a36Sopenharmony_ci	return -EINVAL;
45062306a36Sopenharmony_ci}
45162306a36Sopenharmony_ci
45262306a36Sopenharmony_ciconst char *vpu_id_name(u32 id)
45362306a36Sopenharmony_ci{
45462306a36Sopenharmony_ci	switch (id) {
45562306a36Sopenharmony_ci	case VPU_CMD_ID_NOOP: return "noop";
45662306a36Sopenharmony_ci	case VPU_CMD_ID_CONFIGURE_CODEC: return "configure codec";
45762306a36Sopenharmony_ci	case VPU_CMD_ID_START: return "start";
45862306a36Sopenharmony_ci	case VPU_CMD_ID_STOP: return "stop";
45962306a36Sopenharmony_ci	case VPU_CMD_ID_ABORT: return "abort";
46062306a36Sopenharmony_ci	case VPU_CMD_ID_RST_BUF: return "reset buf";
46162306a36Sopenharmony_ci	case VPU_CMD_ID_SNAPSHOT: return "snapshot";
46262306a36Sopenharmony_ci	case VPU_CMD_ID_FIRM_RESET: return "reset firmware";
46362306a36Sopenharmony_ci	case VPU_CMD_ID_UPDATE_PARAMETER: return "update parameter";
46462306a36Sopenharmony_ci	case VPU_CMD_ID_FRAME_ENCODE: return "encode frame";
46562306a36Sopenharmony_ci	case VPU_CMD_ID_SKIP: return "skip";
46662306a36Sopenharmony_ci	case VPU_CMD_ID_FS_ALLOC: return "alloc fb";
46762306a36Sopenharmony_ci	case VPU_CMD_ID_FS_RELEASE: return "release fb";
46862306a36Sopenharmony_ci	case VPU_CMD_ID_TIMESTAMP: return "timestamp";
46962306a36Sopenharmony_ci	case VPU_CMD_ID_DEBUG: return "debug";
47062306a36Sopenharmony_ci	case VPU_MSG_ID_RESET_DONE: return "reset done";
47162306a36Sopenharmony_ci	case VPU_MSG_ID_START_DONE: return "start done";
47262306a36Sopenharmony_ci	case VPU_MSG_ID_STOP_DONE: return "stop done";
47362306a36Sopenharmony_ci	case VPU_MSG_ID_ABORT_DONE: return "abort done";
47462306a36Sopenharmony_ci	case VPU_MSG_ID_BUF_RST: return "buf reset done";
47562306a36Sopenharmony_ci	case VPU_MSG_ID_MEM_REQUEST: return "mem request";
47662306a36Sopenharmony_ci	case VPU_MSG_ID_PARAM_UPD_DONE: return "param upd done";
47762306a36Sopenharmony_ci	case VPU_MSG_ID_FRAME_INPUT_DONE: return "frame input done";
47862306a36Sopenharmony_ci	case VPU_MSG_ID_ENC_DONE: return "encode done";
47962306a36Sopenharmony_ci	case VPU_MSG_ID_DEC_DONE: return "frame display";
48062306a36Sopenharmony_ci	case VPU_MSG_ID_FRAME_REQ: return "fb request";
48162306a36Sopenharmony_ci	case VPU_MSG_ID_FRAME_RELEASE: return "fb release";
48262306a36Sopenharmony_ci	case VPU_MSG_ID_SEQ_HDR_FOUND: return "seq hdr found";
48362306a36Sopenharmony_ci	case VPU_MSG_ID_RES_CHANGE: return "resolution change";
48462306a36Sopenharmony_ci	case VPU_MSG_ID_PIC_HDR_FOUND: return "pic hdr found";
48562306a36Sopenharmony_ci	case VPU_MSG_ID_PIC_DECODED: return "picture decoded";
48662306a36Sopenharmony_ci	case VPU_MSG_ID_PIC_EOS: return "eos";
48762306a36Sopenharmony_ci	case VPU_MSG_ID_FIFO_LOW: return "fifo low";
48862306a36Sopenharmony_ci	case VPU_MSG_ID_BS_ERROR: return "bs error";
48962306a36Sopenharmony_ci	case VPU_MSG_ID_UNSUPPORTED: return "unsupported";
49062306a36Sopenharmony_ci	case VPU_MSG_ID_FIRMWARE_XCPT: return "exception";
49162306a36Sopenharmony_ci	case VPU_MSG_ID_PIC_SKIPPED: return "skipped";
49262306a36Sopenharmony_ci	case VPU_MSG_ID_DBG_MSG: return "debug msg";
49362306a36Sopenharmony_ci	}
49462306a36Sopenharmony_ci	return "<unknown>";
49562306a36Sopenharmony_ci}
49662306a36Sopenharmony_ci
49762306a36Sopenharmony_ciconst char *vpu_codec_state_name(enum vpu_codec_state state)
49862306a36Sopenharmony_ci{
49962306a36Sopenharmony_ci	switch (state) {
50062306a36Sopenharmony_ci	case VPU_CODEC_STATE_DEINIT: return "initialization";
50162306a36Sopenharmony_ci	case VPU_CODEC_STATE_CONFIGURED: return "configured";
50262306a36Sopenharmony_ci	case VPU_CODEC_STATE_START: return "start";
50362306a36Sopenharmony_ci	case VPU_CODEC_STATE_STARTED: return "started";
50462306a36Sopenharmony_ci	case VPU_CODEC_STATE_ACTIVE: return "active";
50562306a36Sopenharmony_ci	case VPU_CODEC_STATE_SEEK: return "seek";
50662306a36Sopenharmony_ci	case VPU_CODEC_STATE_STOP: return "stop";
50762306a36Sopenharmony_ci	case VPU_CODEC_STATE_DRAIN: return "drain";
50862306a36Sopenharmony_ci	case VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE: return "resolution change";
50962306a36Sopenharmony_ci	}
51062306a36Sopenharmony_ci	return "<unknown>";
51162306a36Sopenharmony_ci}
512