1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * STM32MP25 video codec driver |
4 | * |
5 | * Copyright (C) STMicroelectronics SA 2024 |
6 | * Authors: Hugues Fruchet <hugues.fruchet@foss.st.com> |
7 | * for STMicroelectronics. |
8 | * |
9 | */ |
10 | |
11 | #include "hantro.h" |
12 | #include "hantro_jpeg.h" |
13 | #include "hantro_h1_regs.h" |
14 | |
15 | /* |
16 | * Supported formats. |
17 | */ |
18 | |
19 | static const struct hantro_fmt stm32mp25_vdec_fmts[] = { |
20 | { |
21 | .fourcc = V4L2_PIX_FMT_NV12, |
22 | .codec_mode = HANTRO_MODE_NONE, |
23 | .frmsize = { |
24 | .min_width = FMT_MIN_WIDTH, |
25 | .max_width = FMT_FHD_WIDTH, |
26 | .step_width = MB_DIM, |
27 | .min_height = FMT_MIN_HEIGHT, |
28 | .max_height = FMT_FHD_HEIGHT, |
29 | .step_height = MB_DIM, |
30 | }, |
31 | }, |
32 | { |
33 | .fourcc = V4L2_PIX_FMT_VP8_FRAME, |
34 | .codec_mode = HANTRO_MODE_VP8_DEC, |
35 | .max_depth = 2, |
36 | .frmsize = { |
37 | .min_width = FMT_MIN_WIDTH, |
38 | .max_width = FMT_FHD_WIDTH, |
39 | .step_width = MB_DIM, |
40 | .min_height = FMT_MIN_HEIGHT, |
41 | .max_height = FMT_FHD_HEIGHT, |
42 | .step_height = MB_DIM, |
43 | }, |
44 | }, |
45 | { |
46 | .fourcc = V4L2_PIX_FMT_H264_SLICE, |
47 | .codec_mode = HANTRO_MODE_H264_DEC, |
48 | .max_depth = 2, |
49 | .frmsize = { |
50 | .min_width = FMT_MIN_WIDTH, |
51 | .max_width = FMT_FHD_WIDTH, |
52 | .step_width = MB_DIM, |
53 | .min_height = FMT_MIN_HEIGHT, |
54 | .max_height = FMT_FHD_HEIGHT, |
55 | .step_height = MB_DIM, |
56 | }, |
57 | }, |
58 | }; |
59 | |
60 | static const struct hantro_fmt stm32mp25_venc_fmts[] = { |
61 | { |
62 | .fourcc = V4L2_PIX_FMT_YUV420M, |
63 | .codec_mode = HANTRO_MODE_NONE, |
64 | .enc_fmt = ROCKCHIP_VPU_ENC_FMT_YUV420P, |
65 | }, |
66 | { |
67 | .fourcc = V4L2_PIX_FMT_NV12M, |
68 | .codec_mode = HANTRO_MODE_NONE, |
69 | .enc_fmt = ROCKCHIP_VPU_ENC_FMT_YUV420SP, |
70 | }, |
71 | { |
72 | .fourcc = V4L2_PIX_FMT_YUYV, |
73 | .codec_mode = HANTRO_MODE_NONE, |
74 | .enc_fmt = ROCKCHIP_VPU_ENC_FMT_YUYV422, |
75 | }, |
76 | { |
77 | .fourcc = V4L2_PIX_FMT_UYVY, |
78 | .codec_mode = HANTRO_MODE_NONE, |
79 | .enc_fmt = ROCKCHIP_VPU_ENC_FMT_UYVY422, |
80 | }, |
81 | { |
82 | .fourcc = V4L2_PIX_FMT_JPEG, |
83 | .codec_mode = HANTRO_MODE_JPEG_ENC, |
84 | .max_depth = 2, |
85 | .header_size = JPEG_HEADER_SIZE, |
86 | .frmsize = { |
87 | .min_width = 96, |
88 | .max_width = FMT_4K_WIDTH, |
89 | .step_width = MB_DIM, |
90 | .min_height = 96, |
91 | .max_height = FMT_4K_HEIGHT, |
92 | .step_height = MB_DIM, |
93 | }, |
94 | }, |
95 | }; |
96 | |
97 | static irqreturn_t stm32mp25_venc_irq(int irq, void *dev_id) |
98 | { |
99 | struct hantro_dev *vpu = dev_id; |
100 | enum vb2_buffer_state state; |
101 | u32 status; |
102 | |
103 | status = vepu_read(vpu, H1_REG_INTERRUPT); |
104 | state = (status & H1_REG_INTERRUPT_FRAME_RDY) ? |
105 | VB2_BUF_STATE_DONE : VB2_BUF_STATE_ERROR; |
106 | |
107 | vepu_write(vpu, H1_REG_INTERRUPT_BIT, H1_REG_INTERRUPT); |
108 | |
109 | hantro_irq_done(vpu, result: state); |
110 | |
111 | return IRQ_HANDLED; |
112 | } |
113 | |
114 | static void stm32mp25_venc_reset(struct hantro_ctx *ctx) |
115 | { |
116 | struct hantro_dev *vpu = ctx->dev; |
117 | |
118 | reset_control_reset(rstc: vpu->resets); |
119 | } |
120 | |
121 | /* |
122 | * Supported codec ops. |
123 | */ |
124 | |
125 | static const struct hantro_codec_ops stm32mp25_vdec_codec_ops[] = { |
126 | [HANTRO_MODE_VP8_DEC] = { |
127 | .run = hantro_g1_vp8_dec_run, |
128 | .reset = hantro_g1_reset, |
129 | .init = hantro_vp8_dec_init, |
130 | .exit = hantro_vp8_dec_exit, |
131 | }, |
132 | [HANTRO_MODE_H264_DEC] = { |
133 | .run = hantro_g1_h264_dec_run, |
134 | .reset = hantro_g1_reset, |
135 | .init = hantro_h264_dec_init, |
136 | .exit = hantro_h264_dec_exit, |
137 | }, |
138 | }; |
139 | |
140 | static const struct hantro_codec_ops stm32mp25_venc_codec_ops[] = { |
141 | [HANTRO_MODE_JPEG_ENC] = { |
142 | .run = hantro_h1_jpeg_enc_run, |
143 | .reset = stm32mp25_venc_reset, |
144 | .done = hantro_h1_jpeg_enc_done, |
145 | }, |
146 | }; |
147 | |
148 | /* |
149 | * Variants. |
150 | */ |
151 | |
152 | static const struct hantro_irq stm32mp25_vdec_irqs[] = { |
153 | { "vdec" , hantro_g1_irq }, |
154 | }; |
155 | |
156 | static const char * const stm32mp25_vdec_clk_names[] = { "vdec-clk" }; |
157 | |
158 | const struct hantro_variant stm32mp25_vdec_variant = { |
159 | .dec_fmts = stm32mp25_vdec_fmts, |
160 | .num_dec_fmts = ARRAY_SIZE(stm32mp25_vdec_fmts), |
161 | .codec = HANTRO_VP8_DECODER | HANTRO_H264_DECODER, |
162 | .codec_ops = stm32mp25_vdec_codec_ops, |
163 | .irqs = stm32mp25_vdec_irqs, |
164 | .num_irqs = ARRAY_SIZE(stm32mp25_vdec_irqs), |
165 | .clk_names = stm32mp25_vdec_clk_names, |
166 | .num_clocks = ARRAY_SIZE(stm32mp25_vdec_clk_names), |
167 | }; |
168 | |
169 | static const struct hantro_irq stm32mp25_venc_irqs[] = { |
170 | { "venc" , stm32mp25_venc_irq }, |
171 | }; |
172 | |
173 | static const char * const stm32mp25_venc_clk_names[] = { |
174 | "venc-clk" |
175 | }; |
176 | |
177 | const struct hantro_variant stm32mp25_venc_variant = { |
178 | .enc_fmts = stm32mp25_venc_fmts, |
179 | .num_enc_fmts = ARRAY_SIZE(stm32mp25_venc_fmts), |
180 | .codec = HANTRO_JPEG_ENCODER, |
181 | .codec_ops = stm32mp25_venc_codec_ops, |
182 | .irqs = stm32mp25_venc_irqs, |
183 | .num_irqs = ARRAY_SIZE(stm32mp25_venc_irqs), |
184 | .clk_names = stm32mp25_venc_clk_names, |
185 | .num_clocks = ARRAY_SIZE(stm32mp25_venc_clk_names) |
186 | }; |
187 | |