xref: /linux/drivers/media/platform/verisilicon/stm32mp25_vpu_hw.c (revision 79790b6818e96c58fe2bffee1b418c16e64e7b80)
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 
stm32mp25_venc_irq(int irq,void * dev_id)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, state);
110 
111 	return IRQ_HANDLED;
112 }
113 
stm32mp25_venc_reset(struct hantro_ctx * ctx)114 static void stm32mp25_venc_reset(struct hantro_ctx *ctx)
115 {
116 	struct hantro_dev *vpu = ctx->dev;
117 
118 	reset_control_reset(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