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"
16 #define RK3288_ACLK_MAX_FREQ (400 * 1000 * 1000)
22 static const struct hantro_fmt rk3288_vpu_enc_fmts[] = {
24 .fourcc = V4L2_PIX_FMT_YUV420M,
25 .codec_mode = HANTRO_MODE_NONE,
26 .enc_fmt = RK3288_VPU_ENC_FMT_YUV420P,
29 .fourcc = V4L2_PIX_FMT_NV12M,
30 .codec_mode = HANTRO_MODE_NONE,
31 .enc_fmt = RK3288_VPU_ENC_FMT_YUV420SP,
34 .fourcc = V4L2_PIX_FMT_YUYV,
35 .codec_mode = HANTRO_MODE_NONE,
36 .enc_fmt = RK3288_VPU_ENC_FMT_YUYV422,
39 .fourcc = V4L2_PIX_FMT_UYVY,
40 .codec_mode = HANTRO_MODE_NONE,
41 .enc_fmt = RK3288_VPU_ENC_FMT_UYVY422,
44 .fourcc = V4L2_PIX_FMT_JPEG,
45 .codec_mode = HANTRO_MODE_JPEG_ENC,
47 .header_size = JPEG_HEADER_SIZE,
51 .step_width = JPEG_MB_DIM,
54 .step_height = JPEG_MB_DIM,
59 static const struct hantro_fmt rk3288_vpu_dec_fmts[] = {
61 .fourcc = V4L2_PIX_FMT_NV12,
62 .codec_mode = HANTRO_MODE_NONE,
65 .fourcc = V4L2_PIX_FMT_MPEG2_SLICE,
66 .codec_mode = HANTRO_MODE_MPEG2_DEC,
71 .step_width = MPEG2_MB_DIM,
74 .step_height = MPEG2_MB_DIM,
79 static irqreturn_t rk3288_vepu_irq(int irq, void *dev_id)
81 struct hantro_dev *vpu = dev_id;
82 enum vb2_buffer_state state;
83 u32 status, bytesused;
85 status = vepu_read(vpu, H1_REG_INTERRUPT);
86 bytesused = vepu_read(vpu, H1_REG_STR_BUF_LIMIT) / 8;
87 state = (status & H1_REG_INTERRUPT_FRAME_RDY) ?
88 VB2_BUF_STATE_DONE : VB2_BUF_STATE_ERROR;
90 vepu_write(vpu, 0, H1_REG_INTERRUPT);
91 vepu_write(vpu, 0, H1_REG_AXI_CTRL);
93 hantro_irq_done(vpu, bytesused, state);
98 static irqreturn_t rk3288_vdpu_irq(int irq, void *dev_id)
100 struct hantro_dev *vpu = dev_id;
101 enum vb2_buffer_state state;
104 status = vdpu_read(vpu, G1_REG_INTERRUPT);
105 state = (status & G1_REG_INTERRUPT_DEC_RDY_INT) ?
106 VB2_BUF_STATE_DONE : VB2_BUF_STATE_ERROR;
108 vdpu_write(vpu, 0, G1_REG_INTERRUPT);
109 vdpu_write(vpu, G1_REG_CONFIG_DEC_CLK_GATE_E, G1_REG_CONFIG);
111 hantro_irq_done(vpu, 0, state);
116 static int rk3288_vpu_hw_init(struct hantro_dev *vpu)
118 /* Bump ACLK to max. possible freq. to improve performance. */
119 clk_set_rate(vpu->clocks[0].clk, RK3288_ACLK_MAX_FREQ);
123 static void rk3288_vpu_enc_reset(struct hantro_ctx *ctx)
125 struct hantro_dev *vpu = ctx->dev;
127 vepu_write(vpu, H1_REG_INTERRUPT_DIS_BIT, H1_REG_INTERRUPT);
128 vepu_write(vpu, 0, H1_REG_ENC_CTRL);
129 vepu_write(vpu, 0, H1_REG_AXI_CTRL);
132 static void rk3288_vpu_dec_reset(struct hantro_ctx *ctx)
134 struct hantro_dev *vpu = ctx->dev;
136 vdpu_write(vpu, G1_REG_INTERRUPT_DEC_IRQ_DIS, G1_REG_INTERRUPT);
137 vdpu_write(vpu, G1_REG_CONFIG_DEC_CLK_GATE_E, G1_REG_CONFIG);
138 vdpu_write(vpu, 1, G1_REG_SOFT_RESET);
142 * Supported codec ops.
145 static const struct hantro_codec_ops rk3288_vpu_codec_ops[] = {
146 [HANTRO_MODE_JPEG_ENC] = {
147 .run = hantro_h1_jpeg_enc_run,
148 .reset = rk3288_vpu_enc_reset,
149 .init = hantro_jpeg_enc_init,
150 .exit = hantro_jpeg_enc_exit,
152 [HANTRO_MODE_MPEG2_DEC] = {
153 .run = hantro_g1_mpeg2_dec_run,
154 .reset = rk3288_vpu_dec_reset,
155 .init = hantro_mpeg2_dec_init,
156 .exit = hantro_mpeg2_dec_exit,
164 static const struct hantro_irq rk3288_irqs[] = {
165 { "vepu", rk3288_vepu_irq },
166 { "vdpu", rk3288_vdpu_irq },
169 static const char * const rk3288_clk_names[] = {
173 const struct hantro_variant rk3288_vpu_variant = {
175 .enc_fmts = rk3288_vpu_enc_fmts,
176 .num_enc_fmts = ARRAY_SIZE(rk3288_vpu_enc_fmts),
178 .dec_fmts = rk3288_vpu_dec_fmts,
179 .num_dec_fmts = ARRAY_SIZE(rk3288_vpu_dec_fmts),
180 .codec = HANTRO_JPEG_ENCODER | HANTRO_MPEG2_DECODER,
181 .codec_ops = rk3288_vpu_codec_ops,
183 .num_irqs = ARRAY_SIZE(rk3288_irqs),
184 .init = rk3288_vpu_hw_init,
185 .clk_names = rk3288_clk_names,
186 .num_clocks = ARRAY_SIZE(rk3288_clk_names)