xref: /linux/drivers/media/platform/rockchip/rga/rga3-hw.c (revision 67f8bc848ee31831336bd478e57d2f993551902e)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (C) 2025-2026 Pengutronix e.K.
4  * Author: Sven Püschel <s.pueschel@pengutronix.de>
5  */
6 
7 #include <linux/pm_runtime.h>
8 #include <linux/bitfield.h>
9 #include <linux/delay.h>
10 #include <linux/printk.h>
11 
12 #include <media/v4l2-common.h>
13 
14 #include "rga3-hw.h"
15 #include "rga.h"
16 
17 static unsigned int rga3_get_scaling(unsigned int src, unsigned int dst)
18 {
19 	/*
20 	 * RGA3 scaling factor calculation as described in chapter 5.4.7 Resize
21 	 * of the TRM Part 2. The resulting scaling factor is a 16-bit value
22 	 * and therefore normalized with 2^16.
23 	 *
24 	 * While the TRM also mentions (dst-1)/(src-1) for the up-scaling case,
25 	 * it didn't work as the value always exceeds 16 bit. Flipping the
26 	 * factors results in a correct up-scaling. This is possible as the
27 	 * RGA3 has the RGA3_WIN_SCALE_XXX_UP bit to determine if it does
28 	 * an up or downscale.
29 	 *
30 	 * The scaling factor can potentially cause a slightly larger scaling
31 	 * (e.g. 1/2px larger scale and then cropped to the destination size).
32 	 * This can be seen when scaling 128x128px RGBA to 256x256px RGBA.
33 	 * The RGA2 scaling factor calculation (without the various +/-1
34 	 * doesn't work for the RGA3. It's assumed that this is an hardware
35 	 * accuracy limitation, as the vendor kernel driver uses the same
36 	 * scaling factor calculation.
37 	 *
38 	 * With a scaling factor of 1.0 the calculation technically also
39 	 * overflows 16 bit. This isn't relevant, as in this case the
40 	 * RGA3_WIN_SCALE_XXX_BYPASS bit completely skips the scaling operation.
41 	 */
42 	if (dst > src) {
43 		if (((src - 1) << 16) % (dst - 1) == 0)
44 			return ((src - 1) << 16) / (dst - 1) - 1;
45 		else
46 			return ((src - 1) << 16) / (dst - 1);
47 	} else {
48 		return ((dst - 1) << 16) / (src - 1) + 1;
49 	}
50 }
51 
52 /*
53  * Check if the given format can be captured, as the RGA3 doesn't support all
54  * input formats also on it's output.
55  */
56 static bool rga3_can_capture(const struct rga3_fmt *fmt)
57 {
58 	return fmt->hw_format <= RGA3_COLOR_FMT_LAST_OUTPUT;
59 }
60 
61 /*
62  * Map the transformations to the RGA3 command buffer.
63  * Currently this is just the scaling settings and a fixed alpha value.
64  */
65 static void rga3_cmd_set_trans_info(struct rga_ctx *ctx)
66 {
67 	u32 *cmd = ctx->cmdbuf_virt;
68 	unsigned int src_h, src_w, dst_h, dst_w;
69 	unsigned int reg;
70 	u16 hor_scl_fac, ver_scl_fac;
71 	const struct rga3_fmt *in = ctx->in.fmt;
72 
73 	/* Support basic input cropping to support 1088px inputs */
74 	src_h = ctx->in.crop.height;
75 	src_w = ctx->in.crop.width;
76 	dst_h = ctx->out.pix.height;
77 	dst_w = ctx->out.pix.width;
78 
79 	reg = RGA3_WIN0_RD_CTRL - RGA3_FIRST_CMD_REG;
80 	cmd[reg >> 2] |= FIELD_PREP(RGA3_WIN_SCALE_HOR_UP, dst_w > src_w)
81 		      |  FIELD_PREP(RGA3_WIN_SCALE_HOR_BYPASS, dst_w == src_w)
82 		      |  FIELD_PREP(RGA3_WIN_SCALE_VER_UP, dst_h > src_h)
83 		      |  FIELD_PREP(RGA3_WIN_SCALE_VER_BYPASS, dst_h == src_h);
84 
85 	hor_scl_fac = rga3_get_scaling(src_w, dst_w);
86 	ver_scl_fac = rga3_get_scaling(src_h, dst_h);
87 	reg = RGA3_WIN0_SCL_FAC - RGA3_FIRST_CMD_REG;
88 	cmd[reg >> 2] = FIELD_PREP(RGA3_SCALE_HOR_FAC, hor_scl_fac)
89 		      | FIELD_PREP(RGA3_SCALE_VER_FAC, ver_scl_fac);
90 
91 	if (v4l2_format_info(in->fourcc)->has_alpha) {
92 		/* copy alpha from input */
93 		reg = RGA3_OVLP_TOP_ALPHA - RGA3_FIRST_CMD_REG;
94 		cmd[reg >> 2] = FIELD_PREP(RGA3_ALPHA_SELECT_MODE, 1)
95 			      | FIELD_PREP(RGA3_ALPHA_BLEND_MODE, 1);
96 		reg = RGA3_OVLP_BOT_ALPHA - RGA3_FIRST_CMD_REG;
97 		cmd[reg >> 2] = FIELD_PREP(RGA3_ALPHA_SELECT_MODE, 1)
98 			      | FIELD_PREP(RGA3_ALPHA_BLEND_MODE, 1);
99 	} else {
100 		/* just use a 255 alpha value */
101 		reg = RGA3_OVLP_TOP_CTRL - RGA3_FIRST_CMD_REG;
102 		cmd[reg >> 2] = FIELD_PREP(RGA3_OVLP_GLOBAL_ALPHA, 0xff)
103 			      | FIELD_PREP(RGA3_OVLP_COLOR_MODE, 1);
104 		reg = RGA3_OVLP_BOT_CTRL - RGA3_FIRST_CMD_REG;
105 		cmd[reg >> 2] = FIELD_PREP(RGA3_OVLP_GLOBAL_ALPHA, 0xff)
106 			      | FIELD_PREP(RGA3_OVLP_COLOR_MODE, 1);
107 	}
108 }
109 
110 static void rga3_cmd_set_win0_addr(struct rga_ctx *ctx,
111 				   const struct rga_addrs *addrs)
112 {
113 	u32 *cmd = ctx->cmdbuf_virt;
114 	unsigned int reg;
115 
116 	reg = RGA3_WIN0_Y_BASE - RGA3_FIRST_CMD_REG;
117 	cmd[reg >> 2] = addrs->y_addr;
118 	reg = RGA3_WIN0_U_BASE - RGA3_FIRST_CMD_REG;
119 	cmd[reg >> 2] = addrs->u_addr;
120 }
121 
122 static void rga3_cmd_set_wr_addr(struct rga_ctx *ctx,
123 				 const struct rga_addrs *addrs)
124 {
125 	u32 *cmd = ctx->cmdbuf_virt;
126 	unsigned int reg;
127 
128 	reg = RGA3_WR_Y_BASE - RGA3_FIRST_CMD_REG;
129 	cmd[reg >> 2] = addrs->y_addr;
130 	reg = RGA3_WR_U_BASE - RGA3_FIRST_CMD_REG;
131 	cmd[reg >> 2] = addrs->u_addr;
132 }
133 
134 /* Map the input pixel format to win0 of the comamnd buffer. */
135 static void rga3_cmd_set_win0_format(struct rga_ctx *ctx)
136 {
137 	u32 *cmd = ctx->cmdbuf_virt;
138 	const struct rga3_fmt *in = ctx->in.fmt;
139 	const struct rga3_fmt *out = ctx->out.fmt;
140 	const struct v4l2_format_info *in_fmt, *out_fmt;
141 	unsigned int act_h, act_w, src_h, src_w;
142 	bool r2y, y2r;
143 	u8 rd_format;
144 	const struct v4l2_pix_format_mplane *csc_pix;
145 	u8 csc_mode;
146 	unsigned int reg;
147 
148 	act_h = ctx->in.pix.height;
149 	act_w = ctx->in.pix.width;
150 	/* Support basic input cropping to support 1088px inputs */
151 	src_h = ctx->in.crop.height;
152 	src_w = ctx->in.crop.width;
153 
154 	in_fmt = v4l2_format_info(in->fourcc);
155 	out_fmt = v4l2_format_info(out->fourcc);
156 	r2y = v4l2_is_format_rgb(in_fmt) && v4l2_is_format_yuv(out_fmt);
157 	y2r = v4l2_is_format_yuv(in_fmt) && v4l2_is_format_rgb(out_fmt);
158 
159 	/* The Hardware only supports formats with 1/2 planes */
160 	if (in_fmt->comp_planes == 2)
161 		rd_format = RGA3_RDWR_FORMAT_SEMI_PLANAR;
162 	else
163 		rd_format = RGA3_RDWR_FORMAT_INTERLEAVED;
164 
165 	/* set pixel format and CSC */
166 	csc_pix = r2y ? &ctx->out.pix : &ctx->in.pix;
167 	switch (csc_pix->ycbcr_enc) {
168 	case V4L2_YCBCR_ENC_BT2020:
169 		csc_mode = RGA3_WIN_CSC_MODE_BT2020_L;
170 		break;
171 	case V4L2_YCBCR_ENC_709:
172 		csc_mode = RGA3_WIN_CSC_MODE_BT709_L;
173 		break;
174 	default: /* should be fixed to BT601 in adjust_and_map_format */
175 		if (csc_pix->quantization == V4L2_QUANTIZATION_LIM_RANGE)
176 			csc_mode = RGA3_WIN_CSC_MODE_BT601_L;
177 		else
178 			csc_mode = RGA3_WIN_CSC_MODE_BT601_F;
179 		break;
180 	}
181 
182 	reg = RGA3_WIN0_RD_CTRL - RGA3_FIRST_CMD_REG;
183 	cmd[reg >> 2] |= FIELD_PREP(RGA3_WIN_ENABLE, 1)
184 		      |  FIELD_PREP(RGA3_WIN_PIC_FORMAT, in->hw_format)
185 		      |  FIELD_PREP(RGA3_WIN_YC_SWAP, in->yc_swap)
186 		      |  FIELD_PREP(RGA3_WIN_RBUV_SWAP, in->rbuv_swap)
187 		      |  FIELD_PREP(RGA3_WIN_RD_FORMAT, rd_format)
188 		      |  FIELD_PREP(RGA3_WIN_R2Y, r2y)
189 		      |  FIELD_PREP(RGA3_WIN_Y2R, y2r)
190 		      |  FIELD_PREP(RGA3_WIN_CSC_MODE, csc_mode);
191 
192 	/* set stride */
193 	reg = RGA3_WIN0_VIR_STRIDE - RGA3_FIRST_CMD_REG;
194 	/* stride needs to be in words */
195 	cmd[reg >> 2] = ctx->in.pix.plane_fmt[0].bytesperline >> 2;
196 	reg = RGA3_WIN0_UV_VIR_STRIDE - RGA3_FIRST_CMD_REG;
197 	/* The Hardware only supports formats with 1/2 planes */
198 	if (ctx->in.pix.num_planes == 2)
199 		cmd[reg >> 2] = ctx->in.pix.plane_fmt[1].bytesperline >> 2;
200 	else
201 		cmd[reg >> 2] = ctx->in.pix.plane_fmt[0].bytesperline >> 2;
202 
203 	/* set size */
204 	reg = RGA3_WIN0_ACT_SIZE - RGA3_FIRST_CMD_REG;
205 	cmd[reg >> 2] = FIELD_PREP(RGA3_WIDTH, act_w)
206 		      | FIELD_PREP(RGA3_HEIGHT, act_h);
207 	reg = RGA3_WIN0_SRC_SIZE - RGA3_FIRST_CMD_REG;
208 	cmd[reg >> 2] = FIELD_PREP(RGA3_WIDTH, src_w)
209 		      | FIELD_PREP(RGA3_HEIGHT, src_h);
210 }
211 
212 /* Map the output pixel format to the command buffer */
213 static void rga3_cmd_set_wr_format(struct rga_ctx *ctx)
214 {
215 	u32 *cmd = ctx->cmdbuf_virt;
216 	const struct rga3_fmt *out = ctx->out.fmt;
217 	const struct v4l2_format_info *out_fmt;
218 	unsigned int dst_h, dst_w;
219 	u8 wr_format;
220 	unsigned int reg;
221 
222 	dst_h = ctx->out.pix.height;
223 	dst_w = ctx->out.pix.width;
224 
225 	out_fmt = v4l2_format_info(out->fourcc);
226 
227 	/* The Hardware only supports formats with 1/2 planes */
228 	if (out_fmt->comp_planes == 2)
229 		wr_format = RGA3_RDWR_FORMAT_SEMI_PLANAR;
230 	else
231 		wr_format = RGA3_RDWR_FORMAT_INTERLEAVED;
232 
233 	/* set pixel format */
234 	reg = RGA3_WR_CTRL - RGA3_FIRST_CMD_REG;
235 	cmd[reg >> 2] = FIELD_PREP(RGA3_WR_PIC_FORMAT, out->hw_format)
236 		     |  FIELD_PREP(RGA3_WR_YC_SWAP, out->yc_swap)
237 		     |  FIELD_PREP(RGA3_WR_RBUV_SWAP, out->rbuv_swap)
238 		     |  FIELD_PREP(RGA3_WR_FORMAT, wr_format)
239 	/* Use the max value to avoid limiting the write speed */
240 		     |  FIELD_PREP(RGA3_WR_SW_OUTSTANDING_MAX, 63);
241 
242 	/* set stride */
243 	reg = RGA3_WR_VIR_STRIDE - RGA3_FIRST_CMD_REG;
244 	/* stride needs to be in words */
245 	cmd[reg >> 2] = ctx->out.pix.plane_fmt[0].bytesperline >> 2;
246 	reg = RGA3_WR_PL_VIR_STRIDE - RGA3_FIRST_CMD_REG;
247 	/* The Hardware only supports formats with 1/2 planes */
248 	if (ctx->out.pix.num_planes == 2)
249 		cmd[reg >> 2] = ctx->out.pix.plane_fmt[1].bytesperline >> 2;
250 	else
251 		cmd[reg >> 2] = ctx->out.pix.plane_fmt[0].bytesperline >> 2;
252 
253 	/* Set size.
254 	 * As two inputs are not supported, we don't use win1.
255 	 * Therefore only set the size for win0.
256 	 */
257 	reg = RGA3_WIN0_DST_SIZE - RGA3_FIRST_CMD_REG;
258 	cmd[reg >> 2] = FIELD_PREP(RGA3_WIDTH, dst_w)
259 		      | FIELD_PREP(RGA3_HEIGHT, dst_h);
260 }
261 
262 static void rga3_hw_setup_cmdbuf(struct rga_ctx *ctx)
263 {
264 	memset(ctx->cmdbuf_virt, 0, RGA3_CMDBUF_SIZE);
265 
266 	rga3_cmd_set_win0_format(ctx);
267 	rga3_cmd_set_trans_info(ctx);
268 	rga3_cmd_set_wr_format(ctx);
269 }
270 
271 static void rga3_hw_start(struct rockchip_rga *rga,
272 			  struct rga_vb_buffer *src, struct rga_vb_buffer *dst)
273 {
274 	struct rga_ctx *ctx = rga->curr;
275 
276 	rga3_cmd_set_win0_addr(ctx, &src->dma_addrs);
277 	rga3_cmd_set_wr_addr(ctx, &dst->dma_addrs);
278 
279 	rga_write(rga, RGA3_CMD_ADDR, ctx->cmdbuf_phy);
280 
281 	/* sync CMD buf for RGA */
282 	dma_sync_single_for_device(rga->dev, ctx->cmdbuf_phy,
283 				   PAGE_SIZE, DMA_BIDIRECTIONAL);
284 
285 	/* set to master mode and start the conversion */
286 	rga_write(rga, RGA3_SYS_CTRL,
287 		  FIELD_PREP(RGA3_CMD_MODE, RGA3_CMD_MODE_MASTER));
288 	rga_write(rga, RGA3_INT_EN, FIELD_PREP(RGA3_INT_FRM_DONE, 1));
289 	rga_write(rga, RGA3_CMD_CTRL,
290 		  FIELD_PREP(RGA3_CMD_LINE_START_PULSE, 1));
291 }
292 
293 static bool rga3_handle_irq(struct rockchip_rga *rga)
294 {
295 	u32 intr;
296 
297 	intr = rga_read(rga, RGA3_INT_RAW);
298 	/* clear all interrupts */
299 	rga_write(rga, RGA3_INT_CLR, intr);
300 
301 	return FIELD_GET(RGA3_INT_FRM_DONE, intr);
302 }
303 
304 static void rga3_get_version(struct rockchip_rga *rga)
305 {
306 	u32 version = rga_read(rga, RGA3_VERSION_NUM);
307 
308 	rga->version.major = FIELD_GET(RGA3_VERSION_NUM_MAJOR, version);
309 	rga->version.minor = FIELD_GET(RGA3_VERSION_NUM_MINOR, version);
310 }
311 
312 static struct rga3_fmt rga3_formats[] = {
313 	{
314 		.fourcc = V4L2_PIX_FMT_RGB24,
315 		.hw_format = RGA3_COLOR_FMT_BGR888,
316 		.rbuv_swap = 1,
317 	},
318 	{
319 		.fourcc = V4L2_PIX_FMT_BGR24,
320 		.hw_format = RGA3_COLOR_FMT_BGR888,
321 	},
322 	{
323 		.fourcc = V4L2_PIX_FMT_ABGR32,
324 		.hw_format = RGA3_COLOR_FMT_BGRA8888,
325 	},
326 	{
327 		.fourcc = V4L2_PIX_FMT_RGBA32,
328 		.hw_format = RGA3_COLOR_FMT_BGRA8888,
329 		.rbuv_swap = 1,
330 	},
331 	{
332 		.fourcc = V4L2_PIX_FMT_XBGR32,
333 		.hw_format = RGA3_COLOR_FMT_BGRA8888,
334 	},
335 	{
336 		.fourcc = V4L2_PIX_FMT_RGBX32,
337 		.hw_format = RGA3_COLOR_FMT_BGRA8888,
338 		.rbuv_swap = 1,
339 	},
340 	{
341 		.fourcc = V4L2_PIX_FMT_RGB565,
342 		.hw_format = RGA3_COLOR_FMT_BGR565,
343 		.rbuv_swap = 1,
344 	},
345 	{
346 		.fourcc = V4L2_PIX_FMT_NV12M,
347 		.hw_format = RGA3_COLOR_FMT_YUV420,
348 	},
349 	{
350 		.fourcc = V4L2_PIX_FMT_NV12,
351 		.hw_format = RGA3_COLOR_FMT_YUV420,
352 	},
353 	{
354 		.fourcc = V4L2_PIX_FMT_NV21M,
355 		.hw_format = RGA3_COLOR_FMT_YUV420,
356 		.rbuv_swap = 1,
357 	},
358 	{
359 		.fourcc = V4L2_PIX_FMT_NV21,
360 		.hw_format = RGA3_COLOR_FMT_YUV420,
361 		.rbuv_swap = 1,
362 	},
363 	{
364 		.fourcc = V4L2_PIX_FMT_NV16M,
365 		.hw_format = RGA3_COLOR_FMT_YUV422,
366 	},
367 	{
368 		.fourcc = V4L2_PIX_FMT_NV16,
369 		.hw_format = RGA3_COLOR_FMT_YUV422,
370 	},
371 	{
372 		.fourcc = V4L2_PIX_FMT_NV61M,
373 		.hw_format = RGA3_COLOR_FMT_YUV422,
374 		.rbuv_swap = 1,
375 	},
376 	{
377 		.fourcc = V4L2_PIX_FMT_NV61,
378 		.hw_format = RGA3_COLOR_FMT_YUV422,
379 		.rbuv_swap = 1,
380 	},
381 	{
382 		.fourcc = V4L2_PIX_FMT_YUYV,
383 		.hw_format = RGA3_COLOR_FMT_YUV422,
384 		.yc_swap = 1,
385 	},
386 	{
387 		.fourcc = V4L2_PIX_FMT_YVYU,
388 		.hw_format = RGA3_COLOR_FMT_YUV422,
389 		.yc_swap = 1,
390 		.rbuv_swap = 1,
391 	},
392 	{
393 		.fourcc = V4L2_PIX_FMT_UYVY,
394 		.hw_format = RGA3_COLOR_FMT_YUV422,
395 	},
396 	{
397 		.fourcc = V4L2_PIX_FMT_VYUY,
398 		.hw_format = RGA3_COLOR_FMT_YUV422,
399 		.rbuv_swap = 1,
400 	},
401 	/* Input only formats last to keep rga3_enum_format simple */
402 	{
403 		.fourcc = V4L2_PIX_FMT_ARGB32,
404 		.hw_format = RGA3_COLOR_FMT_ABGR8888,
405 		.rbuv_swap = 1,
406 	},
407 	{
408 		.fourcc = V4L2_PIX_FMT_BGRA32,
409 		.hw_format = RGA3_COLOR_FMT_ABGR8888,
410 	},
411 	{
412 		.fourcc = V4L2_PIX_FMT_XRGB32,
413 		.hw_format = RGA3_COLOR_FMT_ABGR8888,
414 		.rbuv_swap = 1,
415 	},
416 	{
417 		.fourcc = V4L2_PIX_FMT_BGRX32,
418 		.hw_format = RGA3_COLOR_FMT_ABGR8888,
419 	},
420 };
421 
422 static int rga3_enum_format(struct v4l2_fmtdesc *f)
423 {
424 	struct rga3_fmt *fmt;
425 
426 	if (f->index >= ARRAY_SIZE(rga3_formats))
427 		return -EINVAL;
428 
429 	fmt = &rga3_formats[f->index];
430 	if (V4L2_TYPE_IS_CAPTURE(f->type) && !rga3_can_capture(fmt))
431 		return -EINVAL;
432 
433 	f->pixelformat = fmt->fourcc;
434 	return 0;
435 }
436 
437 static void *rga3_adjust_and_map_format(struct rga_ctx *ctx,
438 					struct v4l2_pix_format_mplane *format,
439 					bool is_output)
440 {
441 	unsigned int i;
442 	const struct v4l2_format_info *format_info;
443 	const struct v4l2_pix_format_mplane *other_format;
444 	const struct v4l2_format_info *other_format_info;
445 
446 	if (!format)
447 		return &rga3_formats[0];
448 
449 	format_info = v4l2_format_info(format->pixelformat);
450 	other_format = is_output ? &ctx->out.pix : &ctx->in.pix;
451 	other_format_info = v4l2_format_info(other_format->pixelformat);
452 
453 	/*
454 	 * Only apply the quantization restrictions when we need to
455 	 * convert between RGB and YUV. Otherwise there is no point
456 	 * to limit the quantization for operations like scaling or
457 	 * rotations.
458 	 */
459 	if (v4l2_is_format_yuv(format_info) &&
460 	    v4l2_is_format_rgb(other_format_info)) {
461 		/*
462 		 * The RGA3 only supports BT601, BT709 and BT2020 RGB<->YUV conversions
463 		 * Additionally BT709 and BT2020 only support limited range YUV.
464 		 */
465 		switch (format->ycbcr_enc) {
466 		case V4L2_YCBCR_ENC_601:
467 			/* supports full and limited range */
468 			break;
469 		case V4L2_YCBCR_ENC_709:
470 		case V4L2_YCBCR_ENC_BT2020:
471 			format->quantization = V4L2_QUANTIZATION_LIM_RANGE;
472 			break;
473 		default:
474 			format->ycbcr_enc = V4L2_YCBCR_ENC_601;
475 			format->quantization = V4L2_QUANTIZATION_FULL_RANGE;
476 			break;
477 		}
478 	}
479 
480 	for (i = 0; i < ARRAY_SIZE(rga3_formats); i++) {
481 		if (!is_output && !rga3_can_capture(&rga3_formats[i]))
482 			continue;
483 
484 		if (rga3_formats[i].fourcc == format->pixelformat)
485 			return &rga3_formats[i];
486 	}
487 
488 	format->pixelformat = rga3_formats[0].fourcc;
489 	return &rga3_formats[0];
490 }
491 
492 const struct rga_hw rga3_hw = {
493 	.card_type = "rga3",
494 	.has_internal_iommu = false,
495 	.cmdbuf_size = RGA3_CMDBUF_SIZE,
496 	.min_width = RGA3_MIN_WIDTH,
497 	.min_height = RGA3_MIN_HEIGHT,
498 	/* use output size, as it's a bit smaller than the input size */
499 	.max_width = RGA3_MAX_OUTPUT_WIDTH,
500 	.max_height = RGA3_MAX_OUTPUT_HEIGHT,
501 	.max_scaling_factor = RGA3_MAX_SCALING_FACTOR,
502 	.stride_alignment = 16,
503 	.features = 0,
504 
505 	.setup_cmdbuf = rga3_hw_setup_cmdbuf,
506 	.start = rga3_hw_start,
507 	.handle_irq = rga3_handle_irq,
508 	.get_version = rga3_get_version,
509 	.enum_format = rga3_enum_format,
510 	.adjust_and_map_format = rga3_adjust_and_map_format,
511 };
512