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,
54 .step_height = MB_DIM,
59 static const struct hantro_fmt rk3288_vpu_postproc_fmts[] = {
61 .fourcc = V4L2_PIX_FMT_YUYV,
62 .codec_mode = HANTRO_MODE_NONE,
66 static const struct hantro_fmt rk3288_vpu_dec_fmts[] = {
68 .fourcc = V4L2_PIX_FMT_NV12,
69 .codec_mode = HANTRO_MODE_NONE,
72 .fourcc = V4L2_PIX_FMT_H264_SLICE,
73 .codec_mode = HANTRO_MODE_H264_DEC,
81 .step_height = MB_DIM,
85 .fourcc = V4L2_PIX_FMT_MPEG2_SLICE,
86 .codec_mode = HANTRO_MODE_MPEG2_DEC,
94 .step_height = MB_DIM,
98 .fourcc = V4L2_PIX_FMT_VP8_FRAME,
99 .codec_mode = HANTRO_MODE_VP8_DEC,
104 .step_width = MB_DIM,
107 .step_height = MB_DIM,
112 static irqreturn_t rk3288_vepu_irq(int irq, void *dev_id)
114 struct hantro_dev *vpu = dev_id;
115 enum vb2_buffer_state state;
118 status = vepu_read(vpu, H1_REG_INTERRUPT);
119 state = (status & H1_REG_INTERRUPT_FRAME_RDY) ?
120 VB2_BUF_STATE_DONE : VB2_BUF_STATE_ERROR;
122 vepu_write(vpu, 0, H1_REG_INTERRUPT);
123 vepu_write(vpu, 0, H1_REG_AXI_CTRL);
125 hantro_irq_done(vpu, state);
130 static irqreturn_t rk3288_vdpu_irq(int irq, void *dev_id)
132 struct hantro_dev *vpu = dev_id;
133 enum vb2_buffer_state state;
136 status = vdpu_read(vpu, G1_REG_INTERRUPT);
137 state = (status & G1_REG_INTERRUPT_DEC_RDY_INT) ?
138 VB2_BUF_STATE_DONE : VB2_BUF_STATE_ERROR;
140 vdpu_write(vpu, 0, G1_REG_INTERRUPT);
141 vdpu_write(vpu, G1_REG_CONFIG_DEC_CLK_GATE_E, G1_REG_CONFIG);
143 hantro_irq_done(vpu, state);
148 static int rk3288_vpu_hw_init(struct hantro_dev *vpu)
150 /* Bump ACLK to max. possible freq. to improve performance. */
151 clk_set_rate(vpu->clocks[0].clk, RK3288_ACLK_MAX_FREQ);
155 static void rk3288_vpu_enc_reset(struct hantro_ctx *ctx)
157 struct hantro_dev *vpu = ctx->dev;
159 vepu_write(vpu, H1_REG_INTERRUPT_DIS_BIT, H1_REG_INTERRUPT);
160 vepu_write(vpu, 0, H1_REG_ENC_CTRL);
161 vepu_write(vpu, 0, H1_REG_AXI_CTRL);
164 static void rk3288_vpu_dec_reset(struct hantro_ctx *ctx)
166 struct hantro_dev *vpu = ctx->dev;
168 vdpu_write(vpu, G1_REG_INTERRUPT_DEC_IRQ_DIS, G1_REG_INTERRUPT);
169 vdpu_write(vpu, G1_REG_CONFIG_DEC_CLK_GATE_E, G1_REG_CONFIG);
170 vdpu_write(vpu, 1, G1_REG_SOFT_RESET);
174 * Supported codec ops.
177 static const struct hantro_codec_ops rk3288_vpu_codec_ops[] = {
178 [HANTRO_MODE_JPEG_ENC] = {
179 .run = hantro_h1_jpeg_enc_run,
180 .reset = rk3288_vpu_enc_reset,
181 .init = hantro_jpeg_enc_init,
182 .done = hantro_jpeg_enc_done,
183 .exit = hantro_jpeg_enc_exit,
185 [HANTRO_MODE_H264_DEC] = {
186 .run = hantro_g1_h264_dec_run,
187 .reset = rk3288_vpu_dec_reset,
188 .init = hantro_h264_dec_init,
189 .exit = hantro_h264_dec_exit,
191 [HANTRO_MODE_MPEG2_DEC] = {
192 .run = hantro_g1_mpeg2_dec_run,
193 .reset = rk3288_vpu_dec_reset,
194 .init = hantro_mpeg2_dec_init,
195 .exit = hantro_mpeg2_dec_exit,
197 [HANTRO_MODE_VP8_DEC] = {
198 .run = hantro_g1_vp8_dec_run,
199 .reset = rk3288_vpu_dec_reset,
200 .init = hantro_vp8_dec_init,
201 .exit = hantro_vp8_dec_exit,
209 static const struct hantro_irq rk3288_irqs[] = {
210 { "vepu", rk3288_vepu_irq },
211 { "vdpu", rk3288_vdpu_irq },
214 static const char * const rk3288_clk_names[] = {
218 const struct hantro_variant rk3288_vpu_variant = {
220 .enc_fmts = rk3288_vpu_enc_fmts,
221 .num_enc_fmts = ARRAY_SIZE(rk3288_vpu_enc_fmts),
223 .dec_fmts = rk3288_vpu_dec_fmts,
224 .num_dec_fmts = ARRAY_SIZE(rk3288_vpu_dec_fmts),
225 .postproc_fmts = rk3288_vpu_postproc_fmts,
226 .num_postproc_fmts = ARRAY_SIZE(rk3288_vpu_postproc_fmts),
227 .postproc_regs = &hantro_g1_postproc_regs,
228 .codec = HANTRO_JPEG_ENCODER | HANTRO_MPEG2_DECODER |
229 HANTRO_VP8_DECODER | HANTRO_H264_DECODER,
230 .codec_ops = rk3288_vpu_codec_ops,
232 .num_irqs = ARRAY_SIZE(rk3288_irqs),
233 .init = rk3288_vpu_hw_init,
234 .clk_names = rk3288_clk_names,
235 .num_clocks = ARRAY_SIZE(rk3288_clk_names)