Mention branches and keyring.
[releases.git] / hantro / imx8m_vpu_hw.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Hantro VPU codec driver
4  *
5  * Copyright (C) 2019 Pengutronix, Philipp Zabel <kernel@pengutronix.de>
6  */
7
8 #include <linux/clk.h>
9 #include <linux/delay.h>
10
11 #include "hantro.h"
12 #include "hantro_jpeg.h"
13 #include "hantro_g1_regs.h"
14 #include "hantro_g2_regs.h"
15
16 #define CTRL_SOFT_RESET         0x00
17 #define RESET_G1                BIT(1)
18 #define RESET_G2                BIT(0)
19
20 #define CTRL_CLOCK_ENABLE       0x04
21 #define CLOCK_G1                BIT(1)
22 #define CLOCK_G2                BIT(0)
23
24 #define CTRL_G1_DEC_FUSE        0x08
25 #define CTRL_G1_PP_FUSE         0x0c
26 #define CTRL_G2_DEC_FUSE        0x10
27
28 static void imx8m_soft_reset(struct hantro_dev *vpu, u32 reset_bits)
29 {
30         u32 val;
31
32         /* Assert */
33         val = readl(vpu->ctrl_base + CTRL_SOFT_RESET);
34         val &= ~reset_bits;
35         writel(val, vpu->ctrl_base + CTRL_SOFT_RESET);
36
37         udelay(2);
38
39         /* Release */
40         val = readl(vpu->ctrl_base + CTRL_SOFT_RESET);
41         val |= reset_bits;
42         writel(val, vpu->ctrl_base + CTRL_SOFT_RESET);
43 }
44
45 static void imx8m_clk_enable(struct hantro_dev *vpu, u32 clock_bits)
46 {
47         u32 val;
48
49         val = readl(vpu->ctrl_base + CTRL_CLOCK_ENABLE);
50         val |= clock_bits;
51         writel(val, vpu->ctrl_base + CTRL_CLOCK_ENABLE);
52 }
53
54 static int imx8mq_runtime_resume(struct hantro_dev *vpu)
55 {
56         int ret;
57
58         ret = clk_bulk_prepare_enable(vpu->variant->num_clocks, vpu->clocks);
59         if (ret) {
60                 dev_err(vpu->dev, "Failed to enable clocks\n");
61                 return ret;
62         }
63
64         imx8m_soft_reset(vpu, RESET_G1 | RESET_G2);
65         imx8m_clk_enable(vpu, CLOCK_G1 | CLOCK_G2);
66
67         /* Set values of the fuse registers */
68         writel(0xffffffff, vpu->ctrl_base + CTRL_G1_DEC_FUSE);
69         writel(0xffffffff, vpu->ctrl_base + CTRL_G1_PP_FUSE);
70         writel(0xffffffff, vpu->ctrl_base + CTRL_G2_DEC_FUSE);
71
72         clk_bulk_disable_unprepare(vpu->variant->num_clocks, vpu->clocks);
73
74         return 0;
75 }
76
77 /*
78  * Supported formats.
79  */
80
81 static const struct hantro_fmt imx8m_vpu_postproc_fmts[] = {
82         {
83                 .fourcc = V4L2_PIX_FMT_YUYV,
84                 .codec_mode = HANTRO_MODE_NONE,
85                 .postprocessed = true,
86         },
87 };
88
89 static const struct hantro_fmt imx8m_vpu_dec_fmts[] = {
90         {
91                 .fourcc = V4L2_PIX_FMT_NV12,
92                 .codec_mode = HANTRO_MODE_NONE,
93         },
94         {
95                 .fourcc = V4L2_PIX_FMT_MPEG2_SLICE,
96                 .codec_mode = HANTRO_MODE_MPEG2_DEC,
97                 .max_depth = 2,
98                 .frmsize = {
99                         .min_width = 48,
100                         .max_width = 1920,
101                         .step_width = MB_DIM,
102                         .min_height = 48,
103                         .max_height = 1088,
104                         .step_height = MB_DIM,
105                 },
106         },
107         {
108                 .fourcc = V4L2_PIX_FMT_VP8_FRAME,
109                 .codec_mode = HANTRO_MODE_VP8_DEC,
110                 .max_depth = 2,
111                 .frmsize = {
112                         .min_width = 48,
113                         .max_width = 3840,
114                         .step_width = MB_DIM,
115                         .min_height = 48,
116                         .max_height = 2160,
117                         .step_height = MB_DIM,
118                 },
119         },
120         {
121                 .fourcc = V4L2_PIX_FMT_H264_SLICE,
122                 .codec_mode = HANTRO_MODE_H264_DEC,
123                 .max_depth = 2,
124                 .frmsize = {
125                         .min_width = 48,
126                         .max_width = 3840,
127                         .step_width = MB_DIM,
128                         .min_height = 48,
129                         .max_height = 2160,
130                         .step_height = MB_DIM,
131                 },
132         },
133 };
134
135 static const struct hantro_fmt imx8m_vpu_g2_postproc_fmts[] = {
136         {
137                 .fourcc = V4L2_PIX_FMT_NV12,
138                 .codec_mode = HANTRO_MODE_NONE,
139                 .postprocessed = true,
140         },
141 };
142
143 static const struct hantro_fmt imx8m_vpu_g2_dec_fmts[] = {
144         {
145                 .fourcc = V4L2_PIX_FMT_NV12_4L4,
146                 .codec_mode = HANTRO_MODE_NONE,
147         },
148         {
149                 .fourcc = V4L2_PIX_FMT_HEVC_SLICE,
150                 .codec_mode = HANTRO_MODE_HEVC_DEC,
151                 .max_depth = 2,
152                 .frmsize = {
153                         .min_width = 48,
154                         .max_width = 3840,
155                         .step_width = MB_DIM,
156                         .min_height = 48,
157                         .max_height = 2160,
158                         .step_height = MB_DIM,
159                 },
160         },
161         {
162                 .fourcc = V4L2_PIX_FMT_VP9_FRAME,
163                 .codec_mode = HANTRO_MODE_VP9_DEC,
164                 .max_depth = 2,
165                 .frmsize = {
166                         .min_width = 48,
167                         .max_width = 3840,
168                         .step_width = MB_DIM,
169                         .min_height = 48,
170                         .max_height = 2160,
171                         .step_height = MB_DIM,
172                 },
173         },
174 };
175
176 static irqreturn_t imx8m_vpu_g1_irq(int irq, void *dev_id)
177 {
178         struct hantro_dev *vpu = dev_id;
179         enum vb2_buffer_state state;
180         u32 status;
181
182         status = vdpu_read(vpu, G1_REG_INTERRUPT);
183         state = (status & G1_REG_INTERRUPT_DEC_RDY_INT) ?
184                  VB2_BUF_STATE_DONE : VB2_BUF_STATE_ERROR;
185
186         vdpu_write(vpu, 0, G1_REG_INTERRUPT);
187         vdpu_write(vpu, G1_REG_CONFIG_DEC_CLK_GATE_E, G1_REG_CONFIG);
188
189         hantro_irq_done(vpu, state);
190
191         return IRQ_HANDLED;
192 }
193
194 static int imx8mq_vpu_hw_init(struct hantro_dev *vpu)
195 {
196         vpu->ctrl_base = vpu->reg_bases[vpu->variant->num_regs - 1];
197
198         return 0;
199 }
200
201 static void imx8m_vpu_g1_reset(struct hantro_ctx *ctx)
202 {
203         struct hantro_dev *vpu = ctx->dev;
204
205         imx8m_soft_reset(vpu, RESET_G1);
206 }
207
208 /*
209  * Supported codec ops.
210  */
211
212 static const struct hantro_codec_ops imx8mq_vpu_codec_ops[] = {
213         [HANTRO_MODE_MPEG2_DEC] = {
214                 .run = hantro_g1_mpeg2_dec_run,
215                 .reset = imx8m_vpu_g1_reset,
216                 .init = hantro_mpeg2_dec_init,
217                 .exit = hantro_mpeg2_dec_exit,
218         },
219         [HANTRO_MODE_VP8_DEC] = {
220                 .run = hantro_g1_vp8_dec_run,
221                 .reset = imx8m_vpu_g1_reset,
222                 .init = hantro_vp8_dec_init,
223                 .exit = hantro_vp8_dec_exit,
224         },
225         [HANTRO_MODE_H264_DEC] = {
226                 .run = hantro_g1_h264_dec_run,
227                 .reset = imx8m_vpu_g1_reset,
228                 .init = hantro_h264_dec_init,
229                 .exit = hantro_h264_dec_exit,
230         },
231 };
232
233 static const struct hantro_codec_ops imx8mq_vpu_g1_codec_ops[] = {
234         [HANTRO_MODE_MPEG2_DEC] = {
235                 .run = hantro_g1_mpeg2_dec_run,
236                 .init = hantro_mpeg2_dec_init,
237                 .exit = hantro_mpeg2_dec_exit,
238         },
239         [HANTRO_MODE_VP8_DEC] = {
240                 .run = hantro_g1_vp8_dec_run,
241                 .init = hantro_vp8_dec_init,
242                 .exit = hantro_vp8_dec_exit,
243         },
244         [HANTRO_MODE_H264_DEC] = {
245                 .run = hantro_g1_h264_dec_run,
246                 .init = hantro_h264_dec_init,
247                 .exit = hantro_h264_dec_exit,
248         },
249 };
250
251 static const struct hantro_codec_ops imx8mq_vpu_g2_codec_ops[] = {
252         [HANTRO_MODE_HEVC_DEC] = {
253                 .run = hantro_g2_hevc_dec_run,
254                 .init = hantro_hevc_dec_init,
255                 .exit = hantro_hevc_dec_exit,
256         },
257         [HANTRO_MODE_VP9_DEC] = {
258                 .run = hantro_g2_vp9_dec_run,
259                 .done = hantro_g2_vp9_dec_done,
260                 .init = hantro_vp9_dec_init,
261                 .exit = hantro_vp9_dec_exit,
262         },
263 };
264
265 /*
266  * VPU variants.
267  */
268
269 static const struct hantro_irq imx8mq_irqs[] = {
270         { "g1", imx8m_vpu_g1_irq },
271 };
272
273 static const struct hantro_irq imx8mq_g2_irqs[] = {
274         { "g2", hantro_g2_irq },
275 };
276
277 static const char * const imx8mq_clk_names[] = { "g1", "g2", "bus" };
278 static const char * const imx8mq_reg_names[] = { "g1", "g2", "ctrl" };
279 static const char * const imx8mq_g1_clk_names[] = { "g1" };
280 static const char * const imx8mq_g2_clk_names[] = { "g2" };
281
282 const struct hantro_variant imx8mq_vpu_variant = {
283         .dec_fmts = imx8m_vpu_dec_fmts,
284         .num_dec_fmts = ARRAY_SIZE(imx8m_vpu_dec_fmts),
285         .postproc_fmts = imx8m_vpu_postproc_fmts,
286         .num_postproc_fmts = ARRAY_SIZE(imx8m_vpu_postproc_fmts),
287         .postproc_ops = &hantro_g1_postproc_ops,
288         .codec = HANTRO_MPEG2_DECODER | HANTRO_VP8_DECODER |
289                  HANTRO_H264_DECODER,
290         .codec_ops = imx8mq_vpu_codec_ops,
291         .init = imx8mq_vpu_hw_init,
292         .runtime_resume = imx8mq_runtime_resume,
293         .irqs = imx8mq_irqs,
294         .num_irqs = ARRAY_SIZE(imx8mq_irqs),
295         .clk_names = imx8mq_clk_names,
296         .num_clocks = ARRAY_SIZE(imx8mq_clk_names),
297         .reg_names = imx8mq_reg_names,
298         .num_regs = ARRAY_SIZE(imx8mq_reg_names)
299 };
300
301 const struct hantro_variant imx8mq_vpu_g1_variant = {
302         .dec_fmts = imx8m_vpu_dec_fmts,
303         .num_dec_fmts = ARRAY_SIZE(imx8m_vpu_dec_fmts),
304         .postproc_fmts = imx8m_vpu_postproc_fmts,
305         .num_postproc_fmts = ARRAY_SIZE(imx8m_vpu_postproc_fmts),
306         .postproc_ops = &hantro_g1_postproc_ops,
307         .codec = HANTRO_MPEG2_DECODER | HANTRO_VP8_DECODER |
308                  HANTRO_H264_DECODER,
309         .codec_ops = imx8mq_vpu_g1_codec_ops,
310         .irqs = imx8mq_irqs,
311         .num_irqs = ARRAY_SIZE(imx8mq_irqs),
312         .clk_names = imx8mq_g1_clk_names,
313         .num_clocks = ARRAY_SIZE(imx8mq_g1_clk_names),
314 };
315
316 const struct hantro_variant imx8mq_vpu_g2_variant = {
317         .dec_offset = 0x0,
318         .dec_fmts = imx8m_vpu_g2_dec_fmts,
319         .num_dec_fmts = ARRAY_SIZE(imx8m_vpu_g2_dec_fmts),
320         .postproc_fmts = imx8m_vpu_g2_postproc_fmts,
321         .num_postproc_fmts = ARRAY_SIZE(imx8m_vpu_g2_postproc_fmts),
322         .postproc_ops = &hantro_g2_postproc_ops,
323         .codec = HANTRO_HEVC_DECODER | HANTRO_VP9_DECODER,
324         .codec_ops = imx8mq_vpu_g2_codec_ops,
325         .irqs = imx8mq_g2_irqs,
326         .num_irqs = ARRAY_SIZE(imx8mq_g2_irqs),
327         .clk_names = imx8mq_g2_clk_names,
328         .num_clocks = ARRAY_SIZE(imx8mq_g2_clk_names),
329 };
330
331 const struct hantro_variant imx8mm_vpu_g1_variant = {
332         .dec_fmts = imx8m_vpu_dec_fmts,
333         .num_dec_fmts = ARRAY_SIZE(imx8m_vpu_dec_fmts),
334         .codec = HANTRO_MPEG2_DECODER | HANTRO_VP8_DECODER |
335                  HANTRO_H264_DECODER,
336         .codec_ops = imx8mq_vpu_g1_codec_ops,
337         .irqs = imx8mq_irqs,
338         .num_irqs = ARRAY_SIZE(imx8mq_irqs),
339         .clk_names = imx8mq_g1_clk_names,
340         .num_clocks = ARRAY_SIZE(imx8mq_g1_clk_names),
341 };