1 // SPDX-License-Identifier: GPL-2.0
3 * Hantro VPU codec driver
5 * Copyright (C) 2018 Rockchip Electronics Co., Ltd.
6 * Jeffy Chen <jeffy.chen@rock-chips.com>
12 #include "hantro_jpeg.h"
13 #include "hantro_g1_regs.h"
14 #include "hantro_h1_regs.h"
15 #include "rockchip_vpu2_regs.h"
17 #define RK3066_ACLK_MAX_FREQ (300 * 1000 * 1000)
18 #define RK3288_ACLK_MAX_FREQ (400 * 1000 * 1000)
24 static const struct hantro_fmt rockchip_vpu_enc_fmts[] = {
26 .fourcc = V4L2_PIX_FMT_YUV420M,
27 .codec_mode = HANTRO_MODE_NONE,
28 .enc_fmt = ROCKCHIP_VPU_ENC_FMT_YUV420P,
31 .fourcc = V4L2_PIX_FMT_NV12M,
32 .codec_mode = HANTRO_MODE_NONE,
33 .enc_fmt = ROCKCHIP_VPU_ENC_FMT_YUV420SP,
36 .fourcc = V4L2_PIX_FMT_YUYV,
37 .codec_mode = HANTRO_MODE_NONE,
38 .enc_fmt = ROCKCHIP_VPU_ENC_FMT_YUYV422,
41 .fourcc = V4L2_PIX_FMT_UYVY,
42 .codec_mode = HANTRO_MODE_NONE,
43 .enc_fmt = ROCKCHIP_VPU_ENC_FMT_UYVY422,
46 .fourcc = V4L2_PIX_FMT_JPEG,
47 .codec_mode = HANTRO_MODE_JPEG_ENC,
49 .header_size = JPEG_HEADER_SIZE,
56 .step_height = MB_DIM,
61 static const struct hantro_fmt rockchip_vpu1_postproc_fmts[] = {
63 .fourcc = V4L2_PIX_FMT_YUYV,
64 .codec_mode = HANTRO_MODE_NONE,
65 .postprocessed = true,
69 static const struct hantro_fmt rk3066_vpu_dec_fmts[] = {
71 .fourcc = V4L2_PIX_FMT_NV12,
72 .codec_mode = HANTRO_MODE_NONE,
75 .fourcc = V4L2_PIX_FMT_H264_SLICE,
76 .codec_mode = HANTRO_MODE_H264_DEC,
84 .step_height = MB_DIM,
88 .fourcc = V4L2_PIX_FMT_MPEG2_SLICE,
89 .codec_mode = HANTRO_MODE_MPEG2_DEC,
97 .step_height = MB_DIM,
101 .fourcc = V4L2_PIX_FMT_VP8_FRAME,
102 .codec_mode = HANTRO_MODE_VP8_DEC,
107 .step_width = MB_DIM,
110 .step_height = MB_DIM,
115 static const struct hantro_fmt rk3288_vpu_dec_fmts[] = {
117 .fourcc = V4L2_PIX_FMT_NV12,
118 .codec_mode = HANTRO_MODE_NONE,
121 .fourcc = V4L2_PIX_FMT_H264_SLICE,
122 .codec_mode = HANTRO_MODE_H264_DEC,
127 .step_width = MB_DIM,
130 .step_height = MB_DIM,
134 .fourcc = V4L2_PIX_FMT_MPEG2_SLICE,
135 .codec_mode = HANTRO_MODE_MPEG2_DEC,
140 .step_width = MB_DIM,
143 .step_height = MB_DIM,
147 .fourcc = V4L2_PIX_FMT_VP8_FRAME,
148 .codec_mode = HANTRO_MODE_VP8_DEC,
153 .step_width = MB_DIM,
156 .step_height = MB_DIM,
161 static const struct hantro_fmt rk3399_vpu_dec_fmts[] = {
163 .fourcc = V4L2_PIX_FMT_NV12,
164 .codec_mode = HANTRO_MODE_NONE,
167 .fourcc = V4L2_PIX_FMT_H264_SLICE,
168 .codec_mode = HANTRO_MODE_H264_DEC,
173 .step_width = MB_DIM,
176 .step_height = MB_DIM,
180 .fourcc = V4L2_PIX_FMT_MPEG2_SLICE,
181 .codec_mode = HANTRO_MODE_MPEG2_DEC,
186 .step_width = MB_DIM,
189 .step_height = MB_DIM,
193 .fourcc = V4L2_PIX_FMT_VP8_FRAME,
194 .codec_mode = HANTRO_MODE_VP8_DEC,
199 .step_width = MB_DIM,
202 .step_height = MB_DIM,
207 static irqreturn_t rockchip_vpu1_vepu_irq(int irq, void *dev_id)
209 struct hantro_dev *vpu = dev_id;
210 enum vb2_buffer_state state;
213 status = vepu_read(vpu, H1_REG_INTERRUPT);
214 state = (status & H1_REG_INTERRUPT_FRAME_RDY) ?
215 VB2_BUF_STATE_DONE : VB2_BUF_STATE_ERROR;
217 vepu_write(vpu, 0, H1_REG_INTERRUPT);
218 vepu_write(vpu, 0, H1_REG_AXI_CTRL);
220 hantro_irq_done(vpu, state);
225 static irqreturn_t rockchip_vpu2_vdpu_irq(int irq, void *dev_id)
227 struct hantro_dev *vpu = dev_id;
228 enum vb2_buffer_state state;
231 status = vdpu_read(vpu, VDPU_REG_INTERRUPT);
232 state = (status & VDPU_REG_INTERRUPT_DEC_IRQ) ?
233 VB2_BUF_STATE_DONE : VB2_BUF_STATE_ERROR;
235 vdpu_write(vpu, 0, VDPU_REG_INTERRUPT);
236 vdpu_write(vpu, 0, VDPU_REG_AXI_CTRL);
238 hantro_irq_done(vpu, state);
243 static irqreturn_t rockchip_vpu2_vepu_irq(int irq, void *dev_id)
245 struct hantro_dev *vpu = dev_id;
246 enum vb2_buffer_state state;
249 status = vepu_read(vpu, VEPU_REG_INTERRUPT);
250 state = (status & VEPU_REG_INTERRUPT_FRAME_READY) ?
251 VB2_BUF_STATE_DONE : VB2_BUF_STATE_ERROR;
253 vepu_write(vpu, 0, VEPU_REG_INTERRUPT);
254 vepu_write(vpu, 0, VEPU_REG_AXI_CTRL);
256 hantro_irq_done(vpu, state);
261 static int rk3036_vpu_hw_init(struct hantro_dev *vpu)
263 /* Bump ACLK to max. possible freq. to improve performance. */
264 clk_set_rate(vpu->clocks[0].clk, RK3066_ACLK_MAX_FREQ);
268 static int rk3066_vpu_hw_init(struct hantro_dev *vpu)
270 /* Bump ACLKs to max. possible freq. to improve performance. */
271 clk_set_rate(vpu->clocks[0].clk, RK3066_ACLK_MAX_FREQ);
272 clk_set_rate(vpu->clocks[2].clk, RK3066_ACLK_MAX_FREQ);
276 static int rockchip_vpu_hw_init(struct hantro_dev *vpu)
278 /* Bump ACLK to max. possible freq. to improve performance. */
279 clk_set_rate(vpu->clocks[0].clk, RK3288_ACLK_MAX_FREQ);
283 static void rk3066_vpu_dec_reset(struct hantro_ctx *ctx)
285 struct hantro_dev *vpu = ctx->dev;
287 vdpu_write(vpu, G1_REG_INTERRUPT_DEC_IRQ_DIS, G1_REG_INTERRUPT);
288 vdpu_write(vpu, G1_REG_CONFIG_DEC_CLK_GATE_E, G1_REG_CONFIG);
291 static void rockchip_vpu1_enc_reset(struct hantro_ctx *ctx)
293 struct hantro_dev *vpu = ctx->dev;
295 vepu_write(vpu, H1_REG_INTERRUPT_DIS_BIT, H1_REG_INTERRUPT);
296 vepu_write(vpu, 0, H1_REG_ENC_CTRL);
297 vepu_write(vpu, 0, H1_REG_AXI_CTRL);
300 static void rockchip_vpu2_dec_reset(struct hantro_ctx *ctx)
302 struct hantro_dev *vpu = ctx->dev;
304 vdpu_write(vpu, VDPU_REG_INTERRUPT_DEC_IRQ_DIS, VDPU_REG_INTERRUPT);
305 vdpu_write(vpu, 0, VDPU_REG_EN_FLAGS);
306 vdpu_write(vpu, 1, VDPU_REG_SOFT_RESET);
309 static void rockchip_vpu2_enc_reset(struct hantro_ctx *ctx)
311 struct hantro_dev *vpu = ctx->dev;
313 vepu_write(vpu, VEPU_REG_INTERRUPT_DIS_BIT, VEPU_REG_INTERRUPT);
314 vepu_write(vpu, 0, VEPU_REG_ENCODE_START);
315 vepu_write(vpu, 0, VEPU_REG_AXI_CTRL);
319 * Supported codec ops.
321 static const struct hantro_codec_ops rk3036_vpu_codec_ops[] = {
322 [HANTRO_MODE_H264_DEC] = {
323 .run = hantro_g1_h264_dec_run,
324 .reset = hantro_g1_reset,
325 .init = hantro_h264_dec_init,
326 .exit = hantro_h264_dec_exit,
328 [HANTRO_MODE_MPEG2_DEC] = {
329 .run = hantro_g1_mpeg2_dec_run,
330 .reset = hantro_g1_reset,
331 .init = hantro_mpeg2_dec_init,
332 .exit = hantro_mpeg2_dec_exit,
334 [HANTRO_MODE_VP8_DEC] = {
335 .run = hantro_g1_vp8_dec_run,
336 .reset = hantro_g1_reset,
337 .init = hantro_vp8_dec_init,
338 .exit = hantro_vp8_dec_exit,
342 static const struct hantro_codec_ops rk3066_vpu_codec_ops[] = {
343 [HANTRO_MODE_JPEG_ENC] = {
344 .run = hantro_h1_jpeg_enc_run,
345 .reset = rockchip_vpu1_enc_reset,
346 .done = hantro_h1_jpeg_enc_done,
348 [HANTRO_MODE_H264_DEC] = {
349 .run = hantro_g1_h264_dec_run,
350 .reset = rk3066_vpu_dec_reset,
351 .init = hantro_h264_dec_init,
352 .exit = hantro_h264_dec_exit,
354 [HANTRO_MODE_MPEG2_DEC] = {
355 .run = hantro_g1_mpeg2_dec_run,
356 .reset = rk3066_vpu_dec_reset,
357 .init = hantro_mpeg2_dec_init,
358 .exit = hantro_mpeg2_dec_exit,
360 [HANTRO_MODE_VP8_DEC] = {
361 .run = hantro_g1_vp8_dec_run,
362 .reset = rk3066_vpu_dec_reset,
363 .init = hantro_vp8_dec_init,
364 .exit = hantro_vp8_dec_exit,
368 static const struct hantro_codec_ops rk3288_vpu_codec_ops[] = {
369 [HANTRO_MODE_JPEG_ENC] = {
370 .run = hantro_h1_jpeg_enc_run,
371 .reset = rockchip_vpu1_enc_reset,
372 .done = hantro_h1_jpeg_enc_done,
374 [HANTRO_MODE_H264_DEC] = {
375 .run = hantro_g1_h264_dec_run,
376 .reset = hantro_g1_reset,
377 .init = hantro_h264_dec_init,
378 .exit = hantro_h264_dec_exit,
380 [HANTRO_MODE_MPEG2_DEC] = {
381 .run = hantro_g1_mpeg2_dec_run,
382 .reset = hantro_g1_reset,
383 .init = hantro_mpeg2_dec_init,
384 .exit = hantro_mpeg2_dec_exit,
386 [HANTRO_MODE_VP8_DEC] = {
387 .run = hantro_g1_vp8_dec_run,
388 .reset = hantro_g1_reset,
389 .init = hantro_vp8_dec_init,
390 .exit = hantro_vp8_dec_exit,
394 static const struct hantro_codec_ops rk3399_vpu_codec_ops[] = {
395 [HANTRO_MODE_JPEG_ENC] = {
396 .run = rockchip_vpu2_jpeg_enc_run,
397 .reset = rockchip_vpu2_enc_reset,
398 .done = rockchip_vpu2_jpeg_enc_done,
400 [HANTRO_MODE_H264_DEC] = {
401 .run = rockchip_vpu2_h264_dec_run,
402 .reset = rockchip_vpu2_dec_reset,
403 .init = hantro_h264_dec_init,
404 .exit = hantro_h264_dec_exit,
406 [HANTRO_MODE_MPEG2_DEC] = {
407 .run = rockchip_vpu2_mpeg2_dec_run,
408 .reset = rockchip_vpu2_dec_reset,
409 .init = hantro_mpeg2_dec_init,
410 .exit = hantro_mpeg2_dec_exit,
412 [HANTRO_MODE_VP8_DEC] = {
413 .run = rockchip_vpu2_vp8_dec_run,
414 .reset = rockchip_vpu2_dec_reset,
415 .init = hantro_vp8_dec_init,
416 .exit = hantro_vp8_dec_exit,
424 static const struct hantro_irq rockchip_vdpu1_irqs[] = {
425 { "vdpu", hantro_g1_irq },
428 static const struct hantro_irq rockchip_vpu1_irqs[] = {
429 { "vepu", rockchip_vpu1_vepu_irq },
430 { "vdpu", hantro_g1_irq },
433 static const struct hantro_irq rockchip_vdpu2_irqs[] = {
434 { "vdpu", rockchip_vpu2_vdpu_irq },
437 static const struct hantro_irq rockchip_vpu2_irqs[] = {
438 { "vepu", rockchip_vpu2_vepu_irq },
439 { "vdpu", rockchip_vpu2_vdpu_irq },
442 static const char * const rk3066_vpu_clk_names[] = {
443 "aclk_vdpu", "hclk_vdpu",
444 "aclk_vepu", "hclk_vepu"
447 static const char * const rockchip_vpu_clk_names[] = {
453 const struct hantro_variant rk3036_vpu_variant = {
455 .dec_fmts = rk3066_vpu_dec_fmts,
456 .num_dec_fmts = ARRAY_SIZE(rk3066_vpu_dec_fmts),
457 .postproc_fmts = rockchip_vpu1_postproc_fmts,
458 .num_postproc_fmts = ARRAY_SIZE(rockchip_vpu1_postproc_fmts),
459 .postproc_ops = &hantro_g1_postproc_ops,
460 .codec = HANTRO_MPEG2_DECODER | HANTRO_VP8_DECODER |
462 .codec_ops = rk3036_vpu_codec_ops,
463 .irqs = rockchip_vdpu1_irqs,
464 .num_irqs = ARRAY_SIZE(rockchip_vdpu1_irqs),
465 .init = rk3036_vpu_hw_init,
466 .clk_names = rockchip_vpu_clk_names,
467 .num_clocks = ARRAY_SIZE(rockchip_vpu_clk_names)
471 * Despite this variant has separate clocks for decoder and encoder,
472 * it's still required to enable all four of them for either decoding
473 * or encoding and we can't split it in separate g1/h1 variants.
475 const struct hantro_variant rk3066_vpu_variant = {
477 .enc_fmts = rockchip_vpu_enc_fmts,
478 .num_enc_fmts = ARRAY_SIZE(rockchip_vpu_enc_fmts),
480 .dec_fmts = rk3066_vpu_dec_fmts,
481 .num_dec_fmts = ARRAY_SIZE(rk3066_vpu_dec_fmts),
482 .postproc_fmts = rockchip_vpu1_postproc_fmts,
483 .num_postproc_fmts = ARRAY_SIZE(rockchip_vpu1_postproc_fmts),
484 .postproc_ops = &hantro_g1_postproc_ops,
485 .codec = HANTRO_JPEG_ENCODER | HANTRO_MPEG2_DECODER |
486 HANTRO_VP8_DECODER | HANTRO_H264_DECODER,
487 .codec_ops = rk3066_vpu_codec_ops,
488 .irqs = rockchip_vpu1_irqs,
489 .num_irqs = ARRAY_SIZE(rockchip_vpu1_irqs),
490 .init = rk3066_vpu_hw_init,
491 .clk_names = rk3066_vpu_clk_names,
492 .num_clocks = ARRAY_SIZE(rk3066_vpu_clk_names)
495 const struct hantro_variant rk3288_vpu_variant = {
497 .enc_fmts = rockchip_vpu_enc_fmts,
498 .num_enc_fmts = ARRAY_SIZE(rockchip_vpu_enc_fmts),
500 .dec_fmts = rk3288_vpu_dec_fmts,
501 .num_dec_fmts = ARRAY_SIZE(rk3288_vpu_dec_fmts),
502 .postproc_fmts = rockchip_vpu1_postproc_fmts,
503 .num_postproc_fmts = ARRAY_SIZE(rockchip_vpu1_postproc_fmts),
504 .postproc_ops = &hantro_g1_postproc_ops,
505 .codec = HANTRO_JPEG_ENCODER | HANTRO_MPEG2_DECODER |
506 HANTRO_VP8_DECODER | HANTRO_H264_DECODER,
507 .codec_ops = rk3288_vpu_codec_ops,
508 .irqs = rockchip_vpu1_irqs,
509 .num_irqs = ARRAY_SIZE(rockchip_vpu1_irqs),
510 .init = rockchip_vpu_hw_init,
511 .clk_names = rockchip_vpu_clk_names,
512 .num_clocks = ARRAY_SIZE(rockchip_vpu_clk_names)
517 const struct hantro_variant rk3328_vpu_variant = {
519 .dec_fmts = rk3399_vpu_dec_fmts,
520 .num_dec_fmts = ARRAY_SIZE(rk3399_vpu_dec_fmts),
521 .codec = HANTRO_MPEG2_DECODER | HANTRO_VP8_DECODER |
523 .codec_ops = rk3399_vpu_codec_ops,
524 .irqs = rockchip_vdpu2_irqs,
525 .num_irqs = ARRAY_SIZE(rockchip_vdpu2_irqs),
526 .init = rockchip_vpu_hw_init,
527 .clk_names = rockchip_vpu_clk_names,
528 .num_clocks = ARRAY_SIZE(rockchip_vpu_clk_names),
531 const struct hantro_variant rk3399_vpu_variant = {
533 .enc_fmts = rockchip_vpu_enc_fmts,
534 .num_enc_fmts = ARRAY_SIZE(rockchip_vpu_enc_fmts),
536 .dec_fmts = rk3399_vpu_dec_fmts,
537 .num_dec_fmts = ARRAY_SIZE(rk3399_vpu_dec_fmts),
538 .codec = HANTRO_JPEG_ENCODER | HANTRO_MPEG2_DECODER |
540 .codec_ops = rk3399_vpu_codec_ops,
541 .irqs = rockchip_vpu2_irqs,
542 .num_irqs = ARRAY_SIZE(rockchip_vpu2_irqs),
543 .init = rockchip_vpu_hw_init,
544 .clk_names = rockchip_vpu_clk_names,
545 .num_clocks = ARRAY_SIZE(rockchip_vpu_clk_names)
548 const struct hantro_variant rk3568_vpu_variant = {
550 .dec_fmts = rk3399_vpu_dec_fmts,
551 .num_dec_fmts = ARRAY_SIZE(rk3399_vpu_dec_fmts),
552 .codec = HANTRO_MPEG2_DECODER |
553 HANTRO_VP8_DECODER | HANTRO_H264_DECODER,
554 .codec_ops = rk3399_vpu_codec_ops,
555 .irqs = rockchip_vdpu2_irqs,
556 .num_irqs = ARRAY_SIZE(rockchip_vdpu2_irqs),
557 .init = rockchip_vpu_hw_init,
558 .clk_names = rockchip_vpu_clk_names,
559 .num_clocks = ARRAY_SIZE(rockchip_vpu_clk_names)
562 const struct hantro_variant px30_vpu_variant = {
564 .enc_fmts = rockchip_vpu_enc_fmts,
565 .num_enc_fmts = ARRAY_SIZE(rockchip_vpu_enc_fmts),
567 .dec_fmts = rk3399_vpu_dec_fmts,
568 .num_dec_fmts = ARRAY_SIZE(rk3399_vpu_dec_fmts),
569 .codec = HANTRO_JPEG_ENCODER | HANTRO_MPEG2_DECODER |
570 HANTRO_VP8_DECODER | HANTRO_H264_DECODER,
571 .codec_ops = rk3399_vpu_codec_ops,
572 .irqs = rockchip_vpu2_irqs,
573 .num_irqs = ARRAY_SIZE(rockchip_vpu2_irqs),
574 .init = rk3036_vpu_hw_init,
575 .clk_names = rockchip_vpu_clk_names,
576 .num_clocks = ARRAY_SIZE(rockchip_vpu_clk_names)