Commit | Line | Data |
---|---|---|
186b250a JM |
1 | /* |
2 | * Coda multi-standard codec IP | |
3 | * | |
4 | * Copyright (C) 2012 Vista Silicon S.L. | |
5 | * Javier Martin, <javier.martin@vista-silicon.com> | |
6 | * Xavier Duret | |
7 | * | |
8 | * This program is free software; you can redistribute it and/or modify | |
9 | * it under the terms of the GNU General Public License as published by | |
10 | * the Free Software Foundation; either version 2 of the License, or | |
11 | * (at your option) any later version. | |
12 | */ | |
13 | ||
14 | #include <linux/clk.h> | |
f61c0b14 | 15 | #include <linux/debugfs.h> |
186b250a JM |
16 | #include <linux/delay.h> |
17 | #include <linux/firmware.h> | |
657eee7d | 18 | #include <linux/genalloc.h> |
186b250a JM |
19 | #include <linux/interrupt.h> |
20 | #include <linux/io.h> | |
21 | #include <linux/irq.h> | |
9082a7c6 | 22 | #include <linux/kfifo.h> |
186b250a JM |
23 | #include <linux/module.h> |
24 | #include <linux/of_device.h> | |
25 | #include <linux/platform_device.h> | |
1e172731 | 26 | #include <linux/pm_runtime.h> |
186b250a JM |
27 | #include <linux/slab.h> |
28 | #include <linux/videodev2.h> | |
29 | #include <linux/of.h> | |
657eee7d | 30 | #include <linux/platform_data/coda.h> |
8f45284c | 31 | #include <linux/reset.h> |
186b250a JM |
32 | |
33 | #include <media/v4l2-ctrls.h> | |
34 | #include <media/v4l2-device.h> | |
918c66fd | 35 | #include <media/v4l2-event.h> |
186b250a JM |
36 | #include <media/v4l2-ioctl.h> |
37 | #include <media/v4l2-mem2mem.h> | |
38 | #include <media/videobuf2-core.h> | |
39 | #include <media/videobuf2-dma-contig.h> | |
40 | ||
41 | #include "coda.h" | |
42 | ||
43 | #define CODA_NAME "coda" | |
44 | ||
0cddc7e9 | 45 | #define CODADX6_MAX_INSTANCES 4 |
186b250a | 46 | |
186b250a JM |
47 | #define CODA_PARA_BUF_SIZE (10 * 1024) |
48 | #define CODA_ISRAM_SIZE (2048 * 2) | |
49 | ||
918c66fd | 50 | #define CODA7_PS_BUF_SIZE 0x28000 |
89548441 | 51 | #define CODA9_PS_SAVE_SIZE (512 * 1024) |
918c66fd PZ |
52 | |
53 | #define CODA_MAX_FRAMEBUFFERS 8 | |
186b250a | 54 | |
b96904e5 | 55 | #define CODA_MAX_FRAME_SIZE 0x100000 |
186b250a JM |
56 | #define FMO_SLICE_SAVE_BUF_SIZE (32) |
57 | #define CODA_DEFAULT_GAMMA 4096 | |
89548441 | 58 | #define CODA9_DEFAULT_GAMMA 24576 /* 0.75 * 32768 */ |
186b250a JM |
59 | |
60 | #define MIN_W 176 | |
61 | #define MIN_H 144 | |
186b250a JM |
62 | |
63 | #define S_ALIGN 1 /* multiple of 2 */ | |
64 | #define W_ALIGN 1 /* multiple of 2 */ | |
65 | #define H_ALIGN 1 /* multiple of 2 */ | |
66 | ||
67 | #define fh_to_ctx(__fh) container_of(__fh, struct coda_ctx, fh) | |
68 | ||
69 | static int coda_debug; | |
c4eb1bfc | 70 | module_param(coda_debug, int, 0644); |
186b250a JM |
71 | MODULE_PARM_DESC(coda_debug, "Debug level (0-1)"); |
72 | ||
73 | enum { | |
74 | V4L2_M2M_SRC = 0, | |
75 | V4L2_M2M_DST = 1, | |
76 | }; | |
77 | ||
186b250a JM |
78 | enum coda_inst_type { |
79 | CODA_INST_ENCODER, | |
80 | CODA_INST_DECODER, | |
81 | }; | |
82 | ||
83 | enum coda_product { | |
84 | CODA_DX6 = 0xf001, | |
df1e74cc | 85 | CODA_7541 = 0xf012, |
89548441 | 86 | CODA_960 = 0xf020, |
186b250a JM |
87 | }; |
88 | ||
89 | struct coda_fmt { | |
90 | char *name; | |
91 | u32 fourcc; | |
b96904e5 PZ |
92 | }; |
93 | ||
94 | struct coda_codec { | |
95 | u32 mode; | |
96 | u32 src_fourcc; | |
97 | u32 dst_fourcc; | |
98 | u32 max_w; | |
99 | u32 max_h; | |
186b250a JM |
100 | }; |
101 | ||
102 | struct coda_devtype { | |
103 | char *firmware; | |
104 | enum coda_product product; | |
b96904e5 PZ |
105 | struct coda_codec *codecs; |
106 | unsigned int num_codecs; | |
186b250a | 107 | size_t workbuf_size; |
5d73fad1 | 108 | size_t tempbuf_size; |
401e972f | 109 | size_t iram_size; |
186b250a JM |
110 | }; |
111 | ||
112 | /* Per-queue, driver-specific private data */ | |
113 | struct coda_q_data { | |
114 | unsigned int width; | |
115 | unsigned int height; | |
2fd6a370 | 116 | unsigned int bytesperline; |
186b250a | 117 | unsigned int sizeimage; |
b96904e5 | 118 | unsigned int fourcc; |
52c41676 | 119 | struct v4l2_rect rect; |
186b250a JM |
120 | }; |
121 | ||
122 | struct coda_aux_buf { | |
123 | void *vaddr; | |
124 | dma_addr_t paddr; | |
125 | u32 size; | |
f61c0b14 PZ |
126 | struct debugfs_blob_wrapper blob; |
127 | struct dentry *dentry; | |
186b250a JM |
128 | }; |
129 | ||
130 | struct coda_dev { | |
131 | struct v4l2_device v4l2_dev; | |
132 | struct video_device vfd; | |
133 | struct platform_device *plat_dev; | |
c06d8752 | 134 | const struct coda_devtype *devtype; |
186b250a JM |
135 | |
136 | void __iomem *regs_base; | |
137 | struct clk *clk_per; | |
138 | struct clk *clk_ahb; | |
8f45284c | 139 | struct reset_control *rstc; |
186b250a JM |
140 | |
141 | struct coda_aux_buf codebuf; | |
5677e3b0 | 142 | struct coda_aux_buf tempbuf; |
186b250a | 143 | struct coda_aux_buf workbuf; |
657eee7d | 144 | struct gen_pool *iram_pool; |
b313bcc9 | 145 | struct coda_aux_buf iram; |
186b250a JM |
146 | |
147 | spinlock_t irqlock; | |
148 | struct mutex dev_mutex; | |
fcb62825 | 149 | struct mutex coda_mutex; |
32b6f206 | 150 | struct workqueue_struct *workqueue; |
186b250a JM |
151 | struct v4l2_m2m_dev *m2m_dev; |
152 | struct vb2_alloc_ctx *alloc_ctx; | |
e11f3e6e PZ |
153 | struct list_head instances; |
154 | unsigned long instance_mask; | |
f61c0b14 | 155 | struct dentry *debugfs_root; |
186b250a JM |
156 | }; |
157 | ||
158 | struct coda_params { | |
8f35c7bc | 159 | u8 rot_mode; |
186b250a JM |
160 | u8 h264_intra_qp; |
161 | u8 h264_inter_qp; | |
1a5567e3 PZ |
162 | u8 h264_min_qp; |
163 | u8 h264_max_qp; | |
de23b1db PZ |
164 | u8 h264_deblk_enabled; |
165 | u8 h264_deblk_alpha; | |
166 | u8 h264_deblk_beta; | |
186b250a JM |
167 | u8 mpeg4_intra_qp; |
168 | u8 mpeg4_inter_qp; | |
169 | u8 gop_size; | |
f38f79d5 | 170 | int intra_refresh; |
186b250a | 171 | int codec_mode; |
5677e3b0 | 172 | int codec_mode_aux; |
186b250a JM |
173 | enum v4l2_mpeg_video_multi_slice_mode slice_mode; |
174 | u32 framerate; | |
175 | u16 bitrate; | |
c566c789 | 176 | u32 slice_max_bits; |
186b250a JM |
177 | u32 slice_max_mb; |
178 | }; | |
179 | ||
c2d2251a PZ |
180 | struct coda_iram_info { |
181 | u32 axi_sram_use; | |
182 | phys_addr_t buf_bit_use; | |
183 | phys_addr_t buf_ip_ac_dc_use; | |
184 | phys_addr_t buf_dbk_y_use; | |
185 | phys_addr_t buf_dbk_c_use; | |
186 | phys_addr_t buf_ovl_use; | |
187 | phys_addr_t buf_btp_use; | |
188 | phys_addr_t search_ram_paddr; | |
189 | int search_ram_size; | |
b313bcc9 PZ |
190 | int remaining; |
191 | phys_addr_t next_paddr; | |
c2d2251a PZ |
192 | }; |
193 | ||
89548441 PZ |
194 | struct gdi_tiled_map { |
195 | int xy2ca_map[16]; | |
196 | int xy2ba_map[16]; | |
197 | int xy2ra_map[16]; | |
198 | int rbc2axi_map[32]; | |
199 | int xy2rbc_config; | |
200 | int map_type; | |
201 | #define GDI_LINEAR_FRAME_MAP 0 | |
202 | }; | |
203 | ||
846ced9c PZ |
204 | struct coda_timestamp { |
205 | struct list_head list; | |
206 | u32 sequence; | |
207 | struct v4l2_timecode timecode; | |
208 | struct timeval timestamp; | |
209 | }; | |
210 | ||
186b250a JM |
211 | struct coda_ctx { |
212 | struct coda_dev *dev; | |
918c66fd | 213 | struct mutex buffer_mutex; |
e11f3e6e | 214 | struct list_head list; |
32b6f206 PZ |
215 | struct work_struct pic_run_work; |
216 | struct work_struct seq_end_work; | |
217 | struct completion completion; | |
186b250a | 218 | int aborting; |
918c66fd | 219 | int initialized; |
b96904e5 PZ |
220 | int streamon_out; |
221 | int streamon_cap; | |
186b250a | 222 | u32 isequence; |
9082a7c6 | 223 | u32 qsequence; |
918c66fd | 224 | u32 osequence; |
cb2c0282 | 225 | u32 sequence_offset; |
186b250a JM |
226 | struct coda_q_data q_data[2]; |
227 | enum coda_inst_type inst_type; | |
b96904e5 | 228 | struct coda_codec *codec; |
186b250a JM |
229 | enum v4l2_colorspace colorspace; |
230 | struct coda_params params; | |
186b250a JM |
231 | struct v4l2_ctrl_handler ctrls; |
232 | struct v4l2_fh fh; | |
186b250a | 233 | int gopcounter; |
918c66fd | 234 | int runcounter; |
186b250a JM |
235 | char vpu_header[3][64]; |
236 | int vpu_header_size[3]; | |
9082a7c6 PZ |
237 | struct kfifo bitstream_fifo; |
238 | struct mutex bitstream_mutex; | |
239 | struct coda_aux_buf bitstream; | |
84e2365d | 240 | bool hold; |
186b250a | 241 | struct coda_aux_buf parabuf; |
918c66fd PZ |
242 | struct coda_aux_buf psbuf; |
243 | struct coda_aux_buf slicebuf; | |
ec25f68d | 244 | struct coda_aux_buf internal_frames[CODA_MAX_FRAMEBUFFERS]; |
1a8b3819 | 245 | u32 frame_types[CODA_MAX_FRAMEBUFFERS]; |
846ced9c | 246 | struct coda_timestamp frame_timestamps[CODA_MAX_FRAMEBUFFERS]; |
410e5e49 | 247 | u32 frame_errors[CODA_MAX_FRAMEBUFFERS]; |
846ced9c | 248 | struct list_head timestamp_list; |
5677e3b0 | 249 | struct coda_aux_buf workbuf; |
ec25f68d | 250 | int num_internal_frames; |
186b250a | 251 | int idx; |
5677e3b0 | 252 | int reg_idx; |
c2d2251a | 253 | struct coda_iram_info iram_info; |
89548441 | 254 | struct gdi_tiled_map tiled_map; |
9082a7c6 | 255 | u32 bit_stream_param; |
918c66fd | 256 | u32 frm_dis_flg; |
89548441 | 257 | u32 frame_mem_ctrl; |
918c66fd | 258 | int display_idx; |
f61c0b14 | 259 | struct dentry *debugfs_entry; |
186b250a JM |
260 | }; |
261 | ||
832fbb5a JM |
262 | static const u8 coda_filler_nal[14] = { 0x00, 0x00, 0x00, 0x01, 0x0c, 0xff, |
263 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80 }; | |
264 | static const u8 coda_filler_size[8] = { 0, 7, 14, 13, 12, 11, 10, 9 }; | |
3f3f5c7f | 265 | |
186b250a JM |
266 | static inline void coda_write(struct coda_dev *dev, u32 data, u32 reg) |
267 | { | |
268 | v4l2_dbg(1, coda_debug, &dev->v4l2_dev, | |
269 | "%s: data=0x%x, reg=0x%x\n", __func__, data, reg); | |
270 | writel(data, dev->regs_base + reg); | |
271 | } | |
272 | ||
273 | static inline unsigned int coda_read(struct coda_dev *dev, u32 reg) | |
274 | { | |
275 | u32 data; | |
276 | data = readl(dev->regs_base + reg); | |
277 | v4l2_dbg(1, coda_debug, &dev->v4l2_dev, | |
278 | "%s: data=0x%x, reg=0x%x\n", __func__, data, reg); | |
279 | return data; | |
280 | } | |
281 | ||
282 | static inline unsigned long coda_isbusy(struct coda_dev *dev) | |
283 | { | |
284 | return coda_read(dev, CODA_REG_BIT_BUSY); | |
285 | } | |
286 | ||
287 | static inline int coda_is_initialized(struct coda_dev *dev) | |
288 | { | |
289 | return (coda_read(dev, CODA_REG_BIT_CUR_PC) != 0); | |
290 | } | |
291 | ||
292 | static int coda_wait_timeout(struct coda_dev *dev) | |
293 | { | |
294 | unsigned long timeout = jiffies + msecs_to_jiffies(1000); | |
295 | ||
296 | while (coda_isbusy(dev)) { | |
297 | if (time_after(jiffies, timeout)) | |
298 | return -ETIMEDOUT; | |
299 | } | |
300 | return 0; | |
301 | } | |
302 | ||
303 | static void coda_command_async(struct coda_ctx *ctx, int cmd) | |
304 | { | |
305 | struct coda_dev *dev = ctx->dev; | |
5677e3b0 | 306 | |
89548441 PZ |
307 | if (dev->devtype->product == CODA_960 || |
308 | dev->devtype->product == CODA_7541) { | |
5677e3b0 | 309 | /* Restore context related registers to CODA */ |
9082a7c6 PZ |
310 | coda_write(dev, ctx->bit_stream_param, |
311 | CODA_REG_BIT_BIT_STREAM_PARAM); | |
918c66fd PZ |
312 | coda_write(dev, ctx->frm_dis_flg, |
313 | CODA_REG_BIT_FRM_DIS_FLG(ctx->reg_idx)); | |
89548441 PZ |
314 | coda_write(dev, ctx->frame_mem_ctrl, |
315 | CODA_REG_BIT_FRAME_MEM_CTRL); | |
5677e3b0 PZ |
316 | coda_write(dev, ctx->workbuf.paddr, CODA_REG_BIT_WORK_BUF_ADDR); |
317 | } | |
318 | ||
89548441 PZ |
319 | if (dev->devtype->product == CODA_960) { |
320 | coda_write(dev, 1, CODA9_GDI_WPROT_ERR_CLR); | |
321 | coda_write(dev, 0, CODA9_GDI_WPROT_RGN_EN); | |
322 | } | |
323 | ||
186b250a JM |
324 | coda_write(dev, CODA_REG_BIT_BUSY_FLAG, CODA_REG_BIT_BUSY); |
325 | ||
326 | coda_write(dev, ctx->idx, CODA_REG_BIT_RUN_INDEX); | |
327 | coda_write(dev, ctx->params.codec_mode, CODA_REG_BIT_RUN_COD_STD); | |
5677e3b0 PZ |
328 | coda_write(dev, ctx->params.codec_mode_aux, CODA7_REG_BIT_RUN_AUX_STD); |
329 | ||
186b250a JM |
330 | coda_write(dev, cmd, CODA_REG_BIT_RUN_COMMAND); |
331 | } | |
332 | ||
333 | static int coda_command_sync(struct coda_ctx *ctx, int cmd) | |
334 | { | |
335 | struct coda_dev *dev = ctx->dev; | |
336 | ||
337 | coda_command_async(ctx, cmd); | |
338 | return coda_wait_timeout(dev); | |
339 | } | |
340 | ||
8f45284c PZ |
341 | static int coda_hw_reset(struct coda_ctx *ctx) |
342 | { | |
343 | struct coda_dev *dev = ctx->dev; | |
344 | unsigned long timeout; | |
345 | unsigned int idx; | |
346 | int ret; | |
347 | ||
348 | if (!dev->rstc) | |
349 | return -ENOENT; | |
350 | ||
351 | idx = coda_read(dev, CODA_REG_BIT_RUN_INDEX); | |
352 | ||
353 | timeout = jiffies + msecs_to_jiffies(100); | |
354 | coda_write(dev, 0x11, CODA9_GDI_BUS_CTRL); | |
355 | while (coda_read(dev, CODA9_GDI_BUS_STATUS) != 0x77) { | |
356 | if (time_after(jiffies, timeout)) | |
357 | return -ETIME; | |
358 | cpu_relax(); | |
359 | } | |
360 | ||
361 | ret = reset_control_reset(dev->rstc); | |
362 | if (ret < 0) | |
363 | return ret; | |
364 | ||
365 | coda_write(dev, 0x00, CODA9_GDI_BUS_CTRL); | |
366 | coda_write(dev, CODA_REG_BIT_BUSY_FLAG, CODA_REG_BIT_BUSY); | |
367 | coda_write(dev, CODA_REG_RUN_ENABLE, CODA_REG_BIT_CODE_RUN); | |
368 | ret = coda_wait_timeout(dev); | |
369 | coda_write(dev, idx, CODA_REG_BIT_RUN_INDEX); | |
370 | ||
371 | return ret; | |
372 | } | |
373 | ||
186b250a JM |
374 | static struct coda_q_data *get_q_data(struct coda_ctx *ctx, |
375 | enum v4l2_buf_type type) | |
376 | { | |
377 | switch (type) { | |
378 | case V4L2_BUF_TYPE_VIDEO_OUTPUT: | |
379 | return &(ctx->q_data[V4L2_M2M_SRC]); | |
380 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | |
381 | return &(ctx->q_data[V4L2_M2M_DST]); | |
382 | default: | |
b9736299 | 383 | return NULL; |
186b250a | 384 | } |
186b250a JM |
385 | } |
386 | ||
387 | /* | |
b96904e5 | 388 | * Array of all formats supported by any version of Coda: |
186b250a | 389 | */ |
b96904e5 | 390 | static struct coda_fmt coda_formats[] = { |
186b250a | 391 | { |
b96904e5 | 392 | .name = "YUV 4:2:0 Planar, YCbCr", |
186b250a | 393 | .fourcc = V4L2_PIX_FMT_YUV420, |
186b250a | 394 | }, |
df1e74cc | 395 | { |
b96904e5 PZ |
396 | .name = "YUV 4:2:0 Planar, YCrCb", |
397 | .fourcc = V4L2_PIX_FMT_YVU420, | |
df1e74cc PZ |
398 | }, |
399 | { | |
400 | .name = "H264 Encoded Stream", | |
401 | .fourcc = V4L2_PIX_FMT_H264, | |
df1e74cc PZ |
402 | }, |
403 | { | |
404 | .name = "MPEG4 Encoded Stream", | |
405 | .fourcc = V4L2_PIX_FMT_MPEG4, | |
df1e74cc PZ |
406 | }, |
407 | }; | |
408 | ||
b96904e5 PZ |
409 | #define CODA_CODEC(mode, src_fourcc, dst_fourcc, max_w, max_h) \ |
410 | { mode, src_fourcc, dst_fourcc, max_w, max_h } | |
411 | ||
412 | /* | |
413 | * Arrays of codecs supported by each given version of Coda: | |
414 | * i.MX27 -> codadx6 | |
415 | * i.MX5x -> coda7 | |
416 | * i.MX6 -> coda960 | |
417 | * Use V4L2_PIX_FMT_YUV420 as placeholder for all supported YUV 4:2:0 variants | |
418 | */ | |
419 | static struct coda_codec codadx6_codecs[] = { | |
420 | CODA_CODEC(CODADX6_MODE_ENCODE_H264, V4L2_PIX_FMT_YUV420, V4L2_PIX_FMT_H264, 720, 576), | |
421 | CODA_CODEC(CODADX6_MODE_ENCODE_MP4, V4L2_PIX_FMT_YUV420, V4L2_PIX_FMT_MPEG4, 720, 576), | |
422 | }; | |
423 | ||
424 | static struct coda_codec coda7_codecs[] = { | |
425 | CODA_CODEC(CODA7_MODE_ENCODE_H264, V4L2_PIX_FMT_YUV420, V4L2_PIX_FMT_H264, 1280, 720), | |
426 | CODA_CODEC(CODA7_MODE_ENCODE_MP4, V4L2_PIX_FMT_YUV420, V4L2_PIX_FMT_MPEG4, 1280, 720), | |
918c66fd PZ |
427 | CODA_CODEC(CODA7_MODE_DECODE_H264, V4L2_PIX_FMT_H264, V4L2_PIX_FMT_YUV420, 1920, 1080), |
428 | CODA_CODEC(CODA7_MODE_DECODE_MP4, V4L2_PIX_FMT_MPEG4, V4L2_PIX_FMT_YUV420, 1920, 1080), | |
b96904e5 PZ |
429 | }; |
430 | ||
89548441 PZ |
431 | static struct coda_codec coda9_codecs[] = { |
432 | CODA_CODEC(CODA9_MODE_ENCODE_H264, V4L2_PIX_FMT_YUV420, V4L2_PIX_FMT_H264, 1920, 1080), | |
433 | CODA_CODEC(CODA9_MODE_ENCODE_MP4, V4L2_PIX_FMT_YUV420, V4L2_PIX_FMT_MPEG4, 1920, 1080), | |
434 | CODA_CODEC(CODA9_MODE_DECODE_H264, V4L2_PIX_FMT_H264, V4L2_PIX_FMT_YUV420, 1920, 1080), | |
435 | CODA_CODEC(CODA9_MODE_DECODE_MP4, V4L2_PIX_FMT_MPEG4, V4L2_PIX_FMT_YUV420, 1920, 1080), | |
436 | }; | |
437 | ||
b96904e5 PZ |
438 | static bool coda_format_is_yuv(u32 fourcc) |
439 | { | |
440 | switch (fourcc) { | |
441 | case V4L2_PIX_FMT_YUV420: | |
442 | case V4L2_PIX_FMT_YVU420: | |
443 | return true; | |
444 | default: | |
445 | return false; | |
446 | } | |
447 | } | |
448 | ||
449 | /* | |
450 | * Normalize all supported YUV 4:2:0 formats to the value used in the codec | |
451 | * tables. | |
452 | */ | |
453 | static u32 coda_format_normalize_yuv(u32 fourcc) | |
454 | { | |
455 | return coda_format_is_yuv(fourcc) ? V4L2_PIX_FMT_YUV420 : fourcc; | |
456 | } | |
457 | ||
458 | static struct coda_codec *coda_find_codec(struct coda_dev *dev, int src_fourcc, | |
459 | int dst_fourcc) | |
186b250a | 460 | { |
b96904e5 PZ |
461 | struct coda_codec *codecs = dev->devtype->codecs; |
462 | int num_codecs = dev->devtype->num_codecs; | |
463 | int k; | |
464 | ||
465 | src_fourcc = coda_format_normalize_yuv(src_fourcc); | |
466 | dst_fourcc = coda_format_normalize_yuv(dst_fourcc); | |
467 | if (src_fourcc == dst_fourcc) | |
468 | return NULL; | |
186b250a | 469 | |
b96904e5 PZ |
470 | for (k = 0; k < num_codecs; k++) { |
471 | if (codecs[k].src_fourcc == src_fourcc && | |
472 | codecs[k].dst_fourcc == dst_fourcc) | |
186b250a JM |
473 | break; |
474 | } | |
475 | ||
b96904e5 | 476 | if (k == num_codecs) |
186b250a JM |
477 | return NULL; |
478 | ||
b96904e5 | 479 | return &codecs[k]; |
186b250a JM |
480 | } |
481 | ||
57625593 PZ |
482 | static void coda_get_max_dimensions(struct coda_dev *dev, |
483 | struct coda_codec *codec, | |
484 | int *max_w, int *max_h) | |
485 | { | |
486 | struct coda_codec *codecs = dev->devtype->codecs; | |
487 | int num_codecs = dev->devtype->num_codecs; | |
488 | unsigned int w, h; | |
489 | int k; | |
490 | ||
491 | if (codec) { | |
492 | w = codec->max_w; | |
493 | h = codec->max_h; | |
494 | } else { | |
495 | for (k = 0, w = 0, h = 0; k < num_codecs; k++) { | |
496 | w = max(w, codecs[k].max_w); | |
497 | h = max(h, codecs[k].max_h); | |
498 | } | |
499 | } | |
500 | ||
501 | if (max_w) | |
502 | *max_w = w; | |
503 | if (max_h) | |
504 | *max_h = h; | |
505 | } | |
506 | ||
927933f7 PZ |
507 | static char *coda_product_name(int product) |
508 | { | |
509 | static char buf[9]; | |
510 | ||
511 | switch (product) { | |
512 | case CODA_DX6: | |
513 | return "CodaDx6"; | |
514 | case CODA_7541: | |
515 | return "CODA7541"; | |
89548441 PZ |
516 | case CODA_960: |
517 | return "CODA960"; | |
927933f7 PZ |
518 | default: |
519 | snprintf(buf, sizeof(buf), "(0x%04x)", product); | |
520 | return buf; | |
521 | } | |
522 | } | |
523 | ||
186b250a JM |
524 | /* |
525 | * V4L2 ioctl() operations. | |
526 | */ | |
2e9e4f11 PZ |
527 | static int coda_querycap(struct file *file, void *priv, |
528 | struct v4l2_capability *cap) | |
186b250a | 529 | { |
927933f7 PZ |
530 | struct coda_ctx *ctx = fh_to_ctx(priv); |
531 | ||
186b250a | 532 | strlcpy(cap->driver, CODA_NAME, sizeof(cap->driver)); |
927933f7 PZ |
533 | strlcpy(cap->card, coda_product_name(ctx->dev->devtype->product), |
534 | sizeof(cap->card)); | |
dad0e1ce | 535 | strlcpy(cap->bus_info, "platform:" CODA_NAME, sizeof(cap->bus_info)); |
c3aac8be SN |
536 | /* |
537 | * This is only a mem-to-mem video device. The capture and output | |
538 | * device capability flags are left only for backward compatibility | |
539 | * and are scheduled for removal. | |
540 | */ | |
541 | cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT | | |
542 | V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING; | |
186b250a JM |
543 | cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; |
544 | ||
545 | return 0; | |
546 | } | |
547 | ||
548 | static int enum_fmt(void *priv, struct v4l2_fmtdesc *f, | |
918c66fd | 549 | enum v4l2_buf_type type, int src_fourcc) |
186b250a JM |
550 | { |
551 | struct coda_ctx *ctx = fh_to_ctx(priv); | |
b96904e5 PZ |
552 | struct coda_codec *codecs = ctx->dev->devtype->codecs; |
553 | struct coda_fmt *formats = coda_formats; | |
186b250a | 554 | struct coda_fmt *fmt; |
b96904e5 PZ |
555 | int num_codecs = ctx->dev->devtype->num_codecs; |
556 | int num_formats = ARRAY_SIZE(coda_formats); | |
557 | int i, k, num = 0; | |
186b250a JM |
558 | |
559 | for (i = 0; i < num_formats; i++) { | |
b96904e5 | 560 | /* Both uncompressed formats are always supported */ |
918c66fd PZ |
561 | if (coda_format_is_yuv(formats[i].fourcc) && |
562 | !coda_format_is_yuv(src_fourcc)) { | |
b96904e5 PZ |
563 | if (num == f->index) |
564 | break; | |
565 | ++num; | |
566 | continue; | |
567 | } | |
568 | /* Compressed formats may be supported, check the codec list */ | |
569 | for (k = 0; k < num_codecs; k++) { | |
918c66fd | 570 | /* if src_fourcc is set, only consider matching codecs */ |
b96904e5 | 571 | if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE && |
918c66fd PZ |
572 | formats[i].fourcc == codecs[k].dst_fourcc && |
573 | (!src_fourcc || src_fourcc == codecs[k].src_fourcc)) | |
b96904e5 PZ |
574 | break; |
575 | if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT && | |
576 | formats[i].fourcc == codecs[k].src_fourcc) | |
577 | break; | |
578 | } | |
579 | if (k < num_codecs) { | |
186b250a JM |
580 | if (num == f->index) |
581 | break; | |
582 | ++num; | |
583 | } | |
584 | } | |
585 | ||
586 | if (i < num_formats) { | |
587 | fmt = &formats[i]; | |
588 | strlcpy(f->description, fmt->name, sizeof(f->description)); | |
589 | f->pixelformat = fmt->fourcc; | |
baf70211 PZ |
590 | if (!coda_format_is_yuv(fmt->fourcc)) |
591 | f->flags |= V4L2_FMT_FLAG_COMPRESSED; | |
186b250a JM |
592 | return 0; |
593 | } | |
594 | ||
595 | /* Format not found */ | |
596 | return -EINVAL; | |
597 | } | |
598 | ||
2e9e4f11 PZ |
599 | static int coda_enum_fmt_vid_cap(struct file *file, void *priv, |
600 | struct v4l2_fmtdesc *f) | |
186b250a | 601 | { |
918c66fd PZ |
602 | struct coda_ctx *ctx = fh_to_ctx(priv); |
603 | struct vb2_queue *src_vq; | |
604 | struct coda_q_data *q_data_src; | |
605 | ||
606 | /* If the source format is already fixed, only list matching formats */ | |
14604e3a | 607 | src_vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT); |
918c66fd PZ |
608 | if (vb2_is_streaming(src_vq)) { |
609 | q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT); | |
610 | ||
611 | return enum_fmt(priv, f, V4L2_BUF_TYPE_VIDEO_CAPTURE, | |
612 | q_data_src->fourcc); | |
613 | } | |
614 | ||
615 | return enum_fmt(priv, f, V4L2_BUF_TYPE_VIDEO_CAPTURE, 0); | |
186b250a JM |
616 | } |
617 | ||
2e9e4f11 PZ |
618 | static int coda_enum_fmt_vid_out(struct file *file, void *priv, |
619 | struct v4l2_fmtdesc *f) | |
186b250a | 620 | { |
918c66fd | 621 | return enum_fmt(priv, f, V4L2_BUF_TYPE_VIDEO_OUTPUT, 0); |
186b250a JM |
622 | } |
623 | ||
2e9e4f11 PZ |
624 | static int coda_g_fmt(struct file *file, void *priv, |
625 | struct v4l2_format *f) | |
186b250a | 626 | { |
186b250a JM |
627 | struct coda_q_data *q_data; |
628 | struct coda_ctx *ctx = fh_to_ctx(priv); | |
629 | ||
186b250a | 630 | q_data = get_q_data(ctx, f->type); |
b9736299 PZ |
631 | if (!q_data) |
632 | return -EINVAL; | |
186b250a JM |
633 | |
634 | f->fmt.pix.field = V4L2_FIELD_NONE; | |
b96904e5 | 635 | f->fmt.pix.pixelformat = q_data->fourcc; |
186b250a JM |
636 | f->fmt.pix.width = q_data->width; |
637 | f->fmt.pix.height = q_data->height; | |
2fd6a370 | 638 | f->fmt.pix.bytesperline = q_data->bytesperline; |
186b250a JM |
639 | |
640 | f->fmt.pix.sizeimage = q_data->sizeimage; | |
641 | f->fmt.pix.colorspace = ctx->colorspace; | |
642 | ||
643 | return 0; | |
644 | } | |
645 | ||
57625593 PZ |
646 | static int coda_try_fmt(struct coda_ctx *ctx, struct coda_codec *codec, |
647 | struct v4l2_format *f) | |
186b250a | 648 | { |
57625593 PZ |
649 | struct coda_dev *dev = ctx->dev; |
650 | struct coda_q_data *q_data; | |
b96904e5 | 651 | unsigned int max_w, max_h; |
186b250a JM |
652 | enum v4l2_field field; |
653 | ||
654 | field = f->fmt.pix.field; | |
655 | if (field == V4L2_FIELD_ANY) | |
656 | field = V4L2_FIELD_NONE; | |
657 | else if (V4L2_FIELD_NONE != field) | |
658 | return -EINVAL; | |
659 | ||
660 | /* V4L2 specification suggests the driver corrects the format struct | |
661 | * if any of the dimensions is unsupported */ | |
662 | f->fmt.pix.field = field; | |
663 | ||
57625593 PZ |
664 | coda_get_max_dimensions(dev, codec, &max_w, &max_h); |
665 | v4l_bound_align_image(&f->fmt.pix.width, MIN_W, max_w, W_ALIGN, | |
666 | &f->fmt.pix.height, MIN_H, max_h, H_ALIGN, | |
667 | S_ALIGN); | |
668 | ||
669 | switch (f->fmt.pix.pixelformat) { | |
670 | case V4L2_PIX_FMT_YUV420: | |
671 | case V4L2_PIX_FMT_YVU420: | |
672 | case V4L2_PIX_FMT_H264: | |
673 | case V4L2_PIX_FMT_MPEG4: | |
674 | case V4L2_PIX_FMT_JPEG: | |
675 | break; | |
676 | default: | |
677 | q_data = get_q_data(ctx, f->type); | |
b9736299 PZ |
678 | if (!q_data) |
679 | return -EINVAL; | |
57625593 | 680 | f->fmt.pix.pixelformat = q_data->fourcc; |
b96904e5 | 681 | } |
b96904e5 | 682 | |
57625593 PZ |
683 | switch (f->fmt.pix.pixelformat) { |
684 | case V4L2_PIX_FMT_YUV420: | |
685 | case V4L2_PIX_FMT_YVU420: | |
451dfe5d PZ |
686 | /* Frame stride must be multiple of 8, but 16 for h.264 */ |
687 | f->fmt.pix.bytesperline = round_up(f->fmt.pix.width, 16); | |
47cf0c61 | 688 | f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * |
451d43ad | 689 | f->fmt.pix.height * 3 / 2; |
57625593 PZ |
690 | break; |
691 | case V4L2_PIX_FMT_H264: | |
692 | case V4L2_PIX_FMT_MPEG4: | |
693 | case V4L2_PIX_FMT_JPEG: | |
186b250a JM |
694 | f->fmt.pix.bytesperline = 0; |
695 | f->fmt.pix.sizeimage = CODA_MAX_FRAME_SIZE; | |
57625593 PZ |
696 | break; |
697 | default: | |
698 | BUG(); | |
186b250a JM |
699 | } |
700 | ||
701 | return 0; | |
702 | } | |
703 | ||
2e9e4f11 PZ |
704 | static int coda_try_fmt_vid_cap(struct file *file, void *priv, |
705 | struct v4l2_format *f) | |
186b250a | 706 | { |
186b250a | 707 | struct coda_ctx *ctx = fh_to_ctx(priv); |
918c66fd PZ |
708 | struct coda_codec *codec; |
709 | struct vb2_queue *src_vq; | |
710 | int ret; | |
711 | ||
712 | /* | |
713 | * If the source format is already fixed, try to find a codec that | |
714 | * converts to the given destination format | |
715 | */ | |
14604e3a | 716 | src_vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT); |
918c66fd PZ |
717 | if (vb2_is_streaming(src_vq)) { |
718 | struct coda_q_data *q_data_src; | |
186b250a | 719 | |
918c66fd PZ |
720 | q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT); |
721 | codec = coda_find_codec(ctx->dev, q_data_src->fourcc, | |
722 | f->fmt.pix.pixelformat); | |
723 | if (!codec) | |
724 | return -EINVAL; | |
725 | } else { | |
726 | /* Otherwise determine codec by encoded format, if possible */ | |
727 | codec = coda_find_codec(ctx->dev, V4L2_PIX_FMT_YUV420, | |
728 | f->fmt.pix.pixelformat); | |
729 | } | |
186b250a JM |
730 | |
731 | f->fmt.pix.colorspace = ctx->colorspace; | |
732 | ||
57625593 | 733 | ret = coda_try_fmt(ctx, codec, f); |
918c66fd PZ |
734 | if (ret < 0) |
735 | return ret; | |
736 | ||
737 | /* The h.264 decoder only returns complete 16x16 macroblocks */ | |
738 | if (codec && codec->src_fourcc == V4L2_PIX_FMT_H264) { | |
1b0ed7be | 739 | f->fmt.pix.width = f->fmt.pix.width; |
918c66fd | 740 | f->fmt.pix.height = round_up(f->fmt.pix.height, 16); |
1b0ed7be | 741 | f->fmt.pix.bytesperline = round_up(f->fmt.pix.width, 16); |
918c66fd PZ |
742 | f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * |
743 | f->fmt.pix.height * 3 / 2; | |
744 | } | |
745 | ||
746 | return 0; | |
186b250a JM |
747 | } |
748 | ||
2e9e4f11 PZ |
749 | static int coda_try_fmt_vid_out(struct file *file, void *priv, |
750 | struct v4l2_format *f) | |
186b250a JM |
751 | { |
752 | struct coda_ctx *ctx = fh_to_ctx(priv); | |
b96904e5 | 753 | struct coda_codec *codec; |
186b250a | 754 | |
b96904e5 PZ |
755 | /* Determine codec by encoded format, returns NULL if raw or invalid */ |
756 | codec = coda_find_codec(ctx->dev, f->fmt.pix.pixelformat, | |
757 | V4L2_PIX_FMT_YUV420); | |
186b250a JM |
758 | |
759 | if (!f->fmt.pix.colorspace) | |
760 | f->fmt.pix.colorspace = V4L2_COLORSPACE_REC709; | |
761 | ||
57625593 | 762 | return coda_try_fmt(ctx, codec, f); |
186b250a JM |
763 | } |
764 | ||
2e9e4f11 | 765 | static int coda_s_fmt(struct coda_ctx *ctx, struct v4l2_format *f) |
186b250a JM |
766 | { |
767 | struct coda_q_data *q_data; | |
768 | struct vb2_queue *vq; | |
186b250a | 769 | |
14604e3a | 770 | vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type); |
186b250a JM |
771 | if (!vq) |
772 | return -EINVAL; | |
773 | ||
774 | q_data = get_q_data(ctx, f->type); | |
775 | if (!q_data) | |
776 | return -EINVAL; | |
777 | ||
778 | if (vb2_is_busy(vq)) { | |
779 | v4l2_err(&ctx->dev->v4l2_dev, "%s queue busy\n", __func__); | |
780 | return -EBUSY; | |
781 | } | |
782 | ||
b96904e5 | 783 | q_data->fourcc = f->fmt.pix.pixelformat; |
186b250a JM |
784 | q_data->width = f->fmt.pix.width; |
785 | q_data->height = f->fmt.pix.height; | |
2fd6a370 | 786 | q_data->bytesperline = f->fmt.pix.bytesperline; |
451d43ad | 787 | q_data->sizeimage = f->fmt.pix.sizeimage; |
52c41676 PZ |
788 | q_data->rect.left = 0; |
789 | q_data->rect.top = 0; | |
790 | q_data->rect.width = f->fmt.pix.width; | |
791 | q_data->rect.height = f->fmt.pix.height; | |
186b250a JM |
792 | |
793 | v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev, | |
794 | "Setting format for type %d, wxh: %dx%d, fmt: %d\n", | |
b96904e5 | 795 | f->type, q_data->width, q_data->height, q_data->fourcc); |
186b250a JM |
796 | |
797 | return 0; | |
798 | } | |
799 | ||
2e9e4f11 PZ |
800 | static int coda_s_fmt_vid_cap(struct file *file, void *priv, |
801 | struct v4l2_format *f) | |
186b250a | 802 | { |
b96904e5 | 803 | struct coda_ctx *ctx = fh_to_ctx(priv); |
186b250a JM |
804 | int ret; |
805 | ||
2e9e4f11 | 806 | ret = coda_try_fmt_vid_cap(file, priv, f); |
186b250a JM |
807 | if (ret) |
808 | return ret; | |
809 | ||
2e9e4f11 | 810 | return coda_s_fmt(ctx, f); |
186b250a JM |
811 | } |
812 | ||
2e9e4f11 PZ |
813 | static int coda_s_fmt_vid_out(struct file *file, void *priv, |
814 | struct v4l2_format *f) | |
186b250a JM |
815 | { |
816 | struct coda_ctx *ctx = fh_to_ctx(priv); | |
817 | int ret; | |
818 | ||
2e9e4f11 | 819 | ret = coda_try_fmt_vid_out(file, priv, f); |
186b250a JM |
820 | if (ret) |
821 | return ret; | |
822 | ||
2e9e4f11 | 823 | ret = coda_s_fmt(ctx, f); |
186b250a JM |
824 | if (ret) |
825 | ctx->colorspace = f->fmt.pix.colorspace; | |
826 | ||
827 | return ret; | |
828 | } | |
829 | ||
2e9e4f11 PZ |
830 | static int coda_qbuf(struct file *file, void *priv, |
831 | struct v4l2_buffer *buf) | |
186b250a JM |
832 | { |
833 | struct coda_ctx *ctx = fh_to_ctx(priv); | |
834 | ||
14604e3a | 835 | return v4l2_m2m_qbuf(file, ctx->fh.m2m_ctx, buf); |
186b250a JM |
836 | } |
837 | ||
918c66fd PZ |
838 | static bool coda_buf_is_end_of_stream(struct coda_ctx *ctx, |
839 | struct v4l2_buffer *buf) | |
840 | { | |
841 | struct vb2_queue *src_vq; | |
842 | ||
14604e3a | 843 | src_vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT); |
918c66fd PZ |
844 | |
845 | return ((ctx->bit_stream_param & CODA_BIT_STREAM_END_FLAG) && | |
846 | (buf->sequence == (ctx->qsequence - 1))); | |
847 | } | |
848 | ||
2e9e4f11 PZ |
849 | static int coda_dqbuf(struct file *file, void *priv, |
850 | struct v4l2_buffer *buf) | |
186b250a JM |
851 | { |
852 | struct coda_ctx *ctx = fh_to_ctx(priv); | |
918c66fd PZ |
853 | int ret; |
854 | ||
14604e3a | 855 | ret = v4l2_m2m_dqbuf(file, ctx->fh.m2m_ctx, buf); |
186b250a | 856 | |
918c66fd PZ |
857 | /* If this is the last capture buffer, emit an end-of-stream event */ |
858 | if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && | |
859 | coda_buf_is_end_of_stream(ctx, buf)) { | |
860 | const struct v4l2_event eos_event = { | |
861 | .type = V4L2_EVENT_EOS | |
862 | }; | |
863 | ||
864 | v4l2_event_queue_fh(&ctx->fh, &eos_event); | |
865 | } | |
866 | ||
867 | return ret; | |
186b250a JM |
868 | } |
869 | ||
52c41676 PZ |
870 | static int coda_g_selection(struct file *file, void *fh, |
871 | struct v4l2_selection *s) | |
872 | { | |
873 | struct coda_ctx *ctx = fh_to_ctx(fh); | |
874 | struct coda_q_data *q_data; | |
875 | struct v4l2_rect r, *rsel; | |
876 | ||
877 | q_data = get_q_data(ctx, s->type); | |
878 | if (!q_data) | |
879 | return -EINVAL; | |
880 | ||
881 | r.left = 0; | |
882 | r.top = 0; | |
883 | r.width = q_data->width; | |
884 | r.height = q_data->height; | |
885 | rsel = &q_data->rect; | |
886 | ||
887 | switch (s->target) { | |
888 | case V4L2_SEL_TGT_CROP_DEFAULT: | |
889 | case V4L2_SEL_TGT_CROP_BOUNDS: | |
890 | rsel = &r; | |
891 | /* fallthrough */ | |
892 | case V4L2_SEL_TGT_CROP: | |
893 | if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) | |
894 | return -EINVAL; | |
895 | break; | |
896 | case V4L2_SEL_TGT_COMPOSE_BOUNDS: | |
897 | case V4L2_SEL_TGT_COMPOSE_PADDED: | |
898 | rsel = &r; | |
899 | /* fallthrough */ | |
900 | case V4L2_SEL_TGT_COMPOSE: | |
901 | case V4L2_SEL_TGT_COMPOSE_DEFAULT: | |
902 | if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | |
903 | return -EINVAL; | |
904 | break; | |
905 | default: | |
906 | return -EINVAL; | |
907 | } | |
908 | ||
909 | s->r = *rsel; | |
910 | ||
911 | return 0; | |
912 | } | |
913 | ||
64ba40ac PZ |
914 | static int coda_try_decoder_cmd(struct file *file, void *fh, |
915 | struct v4l2_decoder_cmd *dc) | |
918c66fd | 916 | { |
918c66fd PZ |
917 | if (dc->cmd != V4L2_DEC_CMD_STOP) |
918 | return -EINVAL; | |
919 | ||
64ba40ac | 920 | if (dc->flags & V4L2_DEC_CMD_STOP_TO_BLACK) |
918c66fd PZ |
921 | return -EINVAL; |
922 | ||
64ba40ac | 923 | if (!(dc->flags & V4L2_DEC_CMD_STOP_IMMEDIATELY) && (dc->stop.pts != 0)) |
918c66fd PZ |
924 | return -EINVAL; |
925 | ||
64ba40ac PZ |
926 | return 0; |
927 | } | |
928 | ||
929 | static int coda_decoder_cmd(struct file *file, void *fh, | |
930 | struct v4l2_decoder_cmd *dc) | |
931 | { | |
932 | struct coda_ctx *ctx = fh_to_ctx(fh); | |
89548441 | 933 | struct coda_dev *dev = ctx->dev; |
64ba40ac PZ |
934 | int ret; |
935 | ||
936 | ret = coda_try_decoder_cmd(file, fh, dc); | |
937 | if (ret < 0) | |
938 | return ret; | |
939 | ||
940 | /* Ignore decoder stop command silently in encoder context */ | |
918c66fd | 941 | if (ctx->inst_type != CODA_INST_DECODER) |
64ba40ac | 942 | return 0; |
918c66fd PZ |
943 | |
944 | /* Set the strem-end flag on this context */ | |
945 | ctx->bit_stream_param |= CODA_BIT_STREAM_END_FLAG; | |
946 | ||
89548441 PZ |
947 | if ((dev->devtype->product == CODA_960) && |
948 | coda_isbusy(dev) && | |
949 | (ctx->idx == coda_read(dev, CODA_REG_BIT_RUN_INDEX))) { | |
950 | /* If this context is currently running, update the hardware flag */ | |
951 | coda_write(dev, ctx->bit_stream_param, CODA_REG_BIT_BIT_STREAM_PARAM); | |
952 | } | |
84e2365d | 953 | ctx->hold = false; |
f3497dad | 954 | v4l2_m2m_try_schedule(ctx->fh.m2m_ctx); |
89548441 | 955 | |
918c66fd PZ |
956 | return 0; |
957 | } | |
958 | ||
2e9e4f11 PZ |
959 | static int coda_subscribe_event(struct v4l2_fh *fh, |
960 | const struct v4l2_event_subscription *sub) | |
918c66fd PZ |
961 | { |
962 | switch (sub->type) { | |
963 | case V4L2_EVENT_EOS: | |
964 | return v4l2_event_subscribe(fh, sub, 0, NULL); | |
965 | default: | |
966 | return v4l2_ctrl_subscribe_event(fh, sub); | |
967 | } | |
186b250a JM |
968 | } |
969 | ||
970 | static const struct v4l2_ioctl_ops coda_ioctl_ops = { | |
2e9e4f11 | 971 | .vidioc_querycap = coda_querycap, |
186b250a | 972 | |
2e9e4f11 PZ |
973 | .vidioc_enum_fmt_vid_cap = coda_enum_fmt_vid_cap, |
974 | .vidioc_g_fmt_vid_cap = coda_g_fmt, | |
975 | .vidioc_try_fmt_vid_cap = coda_try_fmt_vid_cap, | |
976 | .vidioc_s_fmt_vid_cap = coda_s_fmt_vid_cap, | |
186b250a | 977 | |
2e9e4f11 PZ |
978 | .vidioc_enum_fmt_vid_out = coda_enum_fmt_vid_out, |
979 | .vidioc_g_fmt_vid_out = coda_g_fmt, | |
980 | .vidioc_try_fmt_vid_out = coda_try_fmt_vid_out, | |
981 | .vidioc_s_fmt_vid_out = coda_s_fmt_vid_out, | |
186b250a | 982 | |
152ea1c8 PZ |
983 | .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs, |
984 | .vidioc_querybuf = v4l2_m2m_ioctl_querybuf, | |
186b250a | 985 | |
2e9e4f11 | 986 | .vidioc_qbuf = coda_qbuf, |
152ea1c8 | 987 | .vidioc_expbuf = v4l2_m2m_ioctl_expbuf, |
2e9e4f11 | 988 | .vidioc_dqbuf = coda_dqbuf, |
152ea1c8 | 989 | .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs, |
186b250a | 990 | |
152ea1c8 PZ |
991 | .vidioc_streamon = v4l2_m2m_ioctl_streamon, |
992 | .vidioc_streamoff = v4l2_m2m_ioctl_streamoff, | |
918c66fd | 993 | |
52c41676 PZ |
994 | .vidioc_g_selection = coda_g_selection, |
995 | ||
64ba40ac | 996 | .vidioc_try_decoder_cmd = coda_try_decoder_cmd, |
2e9e4f11 | 997 | .vidioc_decoder_cmd = coda_decoder_cmd, |
918c66fd | 998 | |
2e9e4f11 | 999 | .vidioc_subscribe_event = coda_subscribe_event, |
918c66fd | 1000 | .vidioc_unsubscribe_event = v4l2_event_unsubscribe, |
186b250a JM |
1001 | }; |
1002 | ||
918c66fd PZ |
1003 | static int coda_start_decoding(struct coda_ctx *ctx); |
1004 | ||
9082a7c6 PZ |
1005 | static inline int coda_get_bitstream_payload(struct coda_ctx *ctx) |
1006 | { | |
1007 | return kfifo_len(&ctx->bitstream_fifo); | |
1008 | } | |
1009 | ||
1010 | static void coda_kfifo_sync_from_device(struct coda_ctx *ctx) | |
1011 | { | |
1012 | struct __kfifo *kfifo = &ctx->bitstream_fifo.kfifo; | |
1013 | struct coda_dev *dev = ctx->dev; | |
1014 | u32 rd_ptr; | |
1015 | ||
1016 | rd_ptr = coda_read(dev, CODA_REG_BIT_RD_PTR(ctx->reg_idx)); | |
1017 | kfifo->out = (kfifo->in & ~kfifo->mask) | | |
1018 | (rd_ptr - ctx->bitstream.paddr); | |
1019 | if (kfifo->out > kfifo->in) | |
1020 | kfifo->out -= kfifo->mask + 1; | |
1021 | } | |
1022 | ||
1023 | static void coda_kfifo_sync_to_device_full(struct coda_ctx *ctx) | |
1024 | { | |
1025 | struct __kfifo *kfifo = &ctx->bitstream_fifo.kfifo; | |
1026 | struct coda_dev *dev = ctx->dev; | |
1027 | u32 rd_ptr, wr_ptr; | |
1028 | ||
1029 | rd_ptr = ctx->bitstream.paddr + (kfifo->out & kfifo->mask); | |
1030 | coda_write(dev, rd_ptr, CODA_REG_BIT_RD_PTR(ctx->reg_idx)); | |
1031 | wr_ptr = ctx->bitstream.paddr + (kfifo->in & kfifo->mask); | |
1032 | coda_write(dev, wr_ptr, CODA_REG_BIT_WR_PTR(ctx->reg_idx)); | |
1033 | } | |
1034 | ||
1035 | static void coda_kfifo_sync_to_device_write(struct coda_ctx *ctx) | |
1036 | { | |
1037 | struct __kfifo *kfifo = &ctx->bitstream_fifo.kfifo; | |
1038 | struct coda_dev *dev = ctx->dev; | |
1039 | u32 wr_ptr; | |
1040 | ||
1041 | wr_ptr = ctx->bitstream.paddr + (kfifo->in & kfifo->mask); | |
1042 | coda_write(dev, wr_ptr, CODA_REG_BIT_WR_PTR(ctx->reg_idx)); | |
1043 | } | |
1044 | ||
1045 | static int coda_bitstream_queue(struct coda_ctx *ctx, struct vb2_buffer *src_buf) | |
1046 | { | |
1047 | u32 src_size = vb2_get_plane_payload(src_buf, 0); | |
1048 | u32 n; | |
1049 | ||
1050 | n = kfifo_in(&ctx->bitstream_fifo, vb2_plane_vaddr(src_buf, 0), src_size); | |
1051 | if (n < src_size) | |
1052 | return -ENOSPC; | |
1053 | ||
1054 | dma_sync_single_for_device(&ctx->dev->plat_dev->dev, ctx->bitstream.paddr, | |
1055 | ctx->bitstream.size, DMA_TO_DEVICE); | |
1056 | ||
846ced9c | 1057 | src_buf->v4l2_buf.sequence = ctx->qsequence++; |
9082a7c6 PZ |
1058 | |
1059 | return 0; | |
1060 | } | |
1061 | ||
1062 | static bool coda_bitstream_try_queue(struct coda_ctx *ctx, | |
1063 | struct vb2_buffer *src_buf) | |
1064 | { | |
1065 | int ret; | |
1066 | ||
1067 | if (coda_get_bitstream_payload(ctx) + | |
1068 | vb2_get_plane_payload(src_buf, 0) + 512 >= ctx->bitstream.size) | |
1069 | return false; | |
1070 | ||
1071 | if (vb2_plane_vaddr(src_buf, 0) == NULL) { | |
1072 | v4l2_err(&ctx->dev->v4l2_dev, "trying to queue empty buffer\n"); | |
1073 | return true; | |
1074 | } | |
1075 | ||
1076 | ret = coda_bitstream_queue(ctx, src_buf); | |
1077 | if (ret < 0) { | |
1078 | v4l2_err(&ctx->dev->v4l2_dev, "bitstream buffer overflow\n"); | |
1079 | return false; | |
1080 | } | |
1081 | /* Sync read pointer to device */ | |
1082 | if (ctx == v4l2_m2m_get_curr_priv(ctx->dev->m2m_dev)) | |
1083 | coda_kfifo_sync_to_device_write(ctx); | |
1084 | ||
84e2365d | 1085 | ctx->hold = false; |
918c66fd | 1086 | |
9082a7c6 PZ |
1087 | return true; |
1088 | } | |
1089 | ||
1090 | static void coda_fill_bitstream(struct coda_ctx *ctx) | |
1091 | { | |
1092 | struct vb2_buffer *src_buf; | |
846ced9c | 1093 | struct coda_timestamp *ts; |
9082a7c6 | 1094 | |
14604e3a PZ |
1095 | while (v4l2_m2m_num_src_bufs_ready(ctx->fh.m2m_ctx) > 0) { |
1096 | src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); | |
9082a7c6 PZ |
1097 | |
1098 | if (coda_bitstream_try_queue(ctx, src_buf)) { | |
846ced9c PZ |
1099 | /* |
1100 | * Source buffer is queued in the bitstream ringbuffer; | |
1101 | * queue the timestamp and mark source buffer as done | |
1102 | */ | |
14604e3a | 1103 | src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); |
846ced9c PZ |
1104 | |
1105 | ts = kmalloc(sizeof(*ts), GFP_KERNEL); | |
1106 | if (ts) { | |
1107 | ts->sequence = src_buf->v4l2_buf.sequence; | |
1108 | ts->timecode = src_buf->v4l2_buf.timecode; | |
1109 | ts->timestamp = src_buf->v4l2_buf.timestamp; | |
1110 | list_add_tail(&ts->list, &ctx->timestamp_list); | |
1111 | } | |
1112 | ||
9082a7c6 PZ |
1113 | v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE); |
1114 | } else { | |
1115 | break; | |
1116 | } | |
1117 | } | |
1118 | } | |
1119 | ||
89548441 PZ |
1120 | static void coda_set_gdi_regs(struct coda_ctx *ctx) |
1121 | { | |
1122 | struct gdi_tiled_map *tiled_map = &ctx->tiled_map; | |
1123 | struct coda_dev *dev = ctx->dev; | |
1124 | int i; | |
1125 | ||
1126 | for (i = 0; i < 16; i++) | |
1127 | coda_write(dev, tiled_map->xy2ca_map[i], | |
1128 | CODA9_GDI_XY2_CAS_0 + 4 * i); | |
1129 | for (i = 0; i < 4; i++) | |
1130 | coda_write(dev, tiled_map->xy2ba_map[i], | |
1131 | CODA9_GDI_XY2_BA_0 + 4 * i); | |
1132 | for (i = 0; i < 16; i++) | |
1133 | coda_write(dev, tiled_map->xy2ra_map[i], | |
1134 | CODA9_GDI_XY2_RAS_0 + 4 * i); | |
1135 | coda_write(dev, tiled_map->xy2rbc_config, CODA9_GDI_XY2_RBC_CONFIG); | |
1136 | for (i = 0; i < 32; i++) | |
1137 | coda_write(dev, tiled_map->rbc2axi_map[i], | |
1138 | CODA9_GDI_RBC2_AXI_0 + 4 * i); | |
1139 | } | |
1140 | ||
186b250a JM |
1141 | /* |
1142 | * Mem-to-mem operations. | |
1143 | */ | |
918c66fd PZ |
1144 | static int coda_prepare_decode(struct coda_ctx *ctx) |
1145 | { | |
1146 | struct vb2_buffer *dst_buf; | |
1147 | struct coda_dev *dev = ctx->dev; | |
1148 | struct coda_q_data *q_data_dst; | |
1149 | u32 stridey, height; | |
1150 | u32 picture_y, picture_cb, picture_cr; | |
1151 | ||
14604e3a | 1152 | dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); |
918c66fd PZ |
1153 | q_data_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE); |
1154 | ||
1155 | if (ctx->params.rot_mode & CODA_ROT_90) { | |
1156 | stridey = q_data_dst->height; | |
1157 | height = q_data_dst->width; | |
1158 | } else { | |
1159 | stridey = q_data_dst->width; | |
1160 | height = q_data_dst->height; | |
1161 | } | |
1162 | ||
1163 | /* Try to copy source buffer contents into the bitstream ringbuffer */ | |
1164 | mutex_lock(&ctx->bitstream_mutex); | |
1165 | coda_fill_bitstream(ctx); | |
1166 | mutex_unlock(&ctx->bitstream_mutex); | |
1167 | ||
1168 | if (coda_get_bitstream_payload(ctx) < 512 && | |
1169 | (!(ctx->bit_stream_param & CODA_BIT_STREAM_END_FLAG))) { | |
1170 | v4l2_dbg(1, coda_debug, &dev->v4l2_dev, | |
1171 | "bitstream payload: %d, skipping\n", | |
1172 | coda_get_bitstream_payload(ctx)); | |
14604e3a | 1173 | v4l2_m2m_job_finish(ctx->dev->m2m_dev, ctx->fh.m2m_ctx); |
918c66fd PZ |
1174 | return -EAGAIN; |
1175 | } | |
1176 | ||
1177 | /* Run coda_start_decoding (again) if not yet initialized */ | |
1178 | if (!ctx->initialized) { | |
1179 | int ret = coda_start_decoding(ctx); | |
1180 | if (ret < 0) { | |
1181 | v4l2_err(&dev->v4l2_dev, "failed to start decoding\n"); | |
14604e3a | 1182 | v4l2_m2m_job_finish(ctx->dev->m2m_dev, ctx->fh.m2m_ctx); |
918c66fd PZ |
1183 | return -EAGAIN; |
1184 | } else { | |
1185 | ctx->initialized = 1; | |
1186 | } | |
1187 | } | |
1188 | ||
89548441 PZ |
1189 | if (dev->devtype->product == CODA_960) |
1190 | coda_set_gdi_regs(ctx); | |
1191 | ||
918c66fd PZ |
1192 | /* Set rotator output */ |
1193 | picture_y = vb2_dma_contig_plane_dma_addr(dst_buf, 0); | |
1194 | if (q_data_dst->fourcc == V4L2_PIX_FMT_YVU420) { | |
1195 | /* Switch Cr and Cb for YVU420 format */ | |
1196 | picture_cr = picture_y + stridey * height; | |
1197 | picture_cb = picture_cr + stridey / 2 * height / 2; | |
1198 | } else { | |
1199 | picture_cb = picture_y + stridey * height; | |
1200 | picture_cr = picture_cb + stridey / 2 * height / 2; | |
1201 | } | |
89548441 PZ |
1202 | |
1203 | if (dev->devtype->product == CODA_960) { | |
1204 | /* | |
1205 | * The CODA960 seems to have an internal list of buffers with | |
1206 | * 64 entries that includes the registered frame buffers as | |
1207 | * well as the rotator buffer output. | |
1208 | * ROT_INDEX needs to be < 0x40, but > ctx->num_internal_frames. | |
1209 | */ | |
1210 | coda_write(dev, CODA_MAX_FRAMEBUFFERS + dst_buf->v4l2_buf.index, | |
1211 | CODA9_CMD_DEC_PIC_ROT_INDEX); | |
1212 | coda_write(dev, picture_y, CODA9_CMD_DEC_PIC_ROT_ADDR_Y); | |
1213 | coda_write(dev, picture_cb, CODA9_CMD_DEC_PIC_ROT_ADDR_CB); | |
1214 | coda_write(dev, picture_cr, CODA9_CMD_DEC_PIC_ROT_ADDR_CR); | |
1215 | coda_write(dev, stridey, CODA9_CMD_DEC_PIC_ROT_STRIDE); | |
1216 | } else { | |
1217 | coda_write(dev, picture_y, CODA_CMD_DEC_PIC_ROT_ADDR_Y); | |
1218 | coda_write(dev, picture_cb, CODA_CMD_DEC_PIC_ROT_ADDR_CB); | |
1219 | coda_write(dev, picture_cr, CODA_CMD_DEC_PIC_ROT_ADDR_CR); | |
1220 | coda_write(dev, stridey, CODA_CMD_DEC_PIC_ROT_STRIDE); | |
1221 | } | |
918c66fd PZ |
1222 | coda_write(dev, CODA_ROT_MIR_ENABLE | ctx->params.rot_mode, |
1223 | CODA_CMD_DEC_PIC_ROT_MODE); | |
1224 | ||
1225 | switch (dev->devtype->product) { | |
1226 | case CODA_DX6: | |
1227 | /* TBD */ | |
1228 | case CODA_7541: | |
1229 | coda_write(dev, CODA_PRE_SCAN_EN, CODA_CMD_DEC_PIC_OPTION); | |
1230 | break; | |
89548441 PZ |
1231 | case CODA_960: |
1232 | coda_write(dev, (1 << 10), CODA_CMD_DEC_PIC_OPTION); /* 'hardcode to use interrupt disable mode'? */ | |
1233 | break; | |
918c66fd PZ |
1234 | } |
1235 | ||
1236 | coda_write(dev, 0, CODA_CMD_DEC_PIC_SKIP_NUM); | |
1237 | ||
1238 | coda_write(dev, 0, CODA_CMD_DEC_PIC_BB_START); | |
1239 | coda_write(dev, 0, CODA_CMD_DEC_PIC_START_BYTE); | |
1240 | ||
1241 | return 0; | |
1242 | } | |
1243 | ||
477c1cfe | 1244 | static void coda_prepare_encode(struct coda_ctx *ctx) |
186b250a | 1245 | { |
186b250a JM |
1246 | struct coda_q_data *q_data_src, *q_data_dst; |
1247 | struct vb2_buffer *src_buf, *dst_buf; | |
1248 | struct coda_dev *dev = ctx->dev; | |
1249 | int force_ipicture; | |
1250 | int quant_param = 0; | |
1251 | u32 picture_y, picture_cb, picture_cr; | |
1252 | u32 pic_stream_buffer_addr, pic_stream_buffer_size; | |
1253 | u32 dst_fourcc; | |
1254 | ||
14604e3a PZ |
1255 | src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); |
1256 | dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); | |
186b250a JM |
1257 | q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT); |
1258 | q_data_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE); | |
b96904e5 | 1259 | dst_fourcc = q_data_dst->fourcc; |
186b250a | 1260 | |
918c66fd PZ |
1261 | src_buf->v4l2_buf.sequence = ctx->osequence; |
1262 | dst_buf->v4l2_buf.sequence = ctx->osequence; | |
1263 | ctx->osequence++; | |
186b250a JM |
1264 | |
1265 | /* | |
1266 | * Workaround coda firmware BUG that only marks the first | |
1267 | * frame as IDR. This is a problem for some decoders that can't | |
1268 | * recover when a frame is lost. | |
1269 | */ | |
1270 | if (src_buf->v4l2_buf.sequence % ctx->params.gop_size) { | |
1271 | src_buf->v4l2_buf.flags |= V4L2_BUF_FLAG_PFRAME; | |
1272 | src_buf->v4l2_buf.flags &= ~V4L2_BUF_FLAG_KEYFRAME; | |
1273 | } else { | |
1274 | src_buf->v4l2_buf.flags |= V4L2_BUF_FLAG_KEYFRAME; | |
1275 | src_buf->v4l2_buf.flags &= ~V4L2_BUF_FLAG_PFRAME; | |
1276 | } | |
1277 | ||
89548441 PZ |
1278 | if (dev->devtype->product == CODA_960) |
1279 | coda_set_gdi_regs(ctx); | |
1280 | ||
186b250a JM |
1281 | /* |
1282 | * Copy headers at the beginning of the first frame for H.264 only. | |
1283 | * In MPEG4 they are already copied by the coda. | |
1284 | */ | |
1285 | if (src_buf->v4l2_buf.sequence == 0) { | |
1286 | pic_stream_buffer_addr = | |
1287 | vb2_dma_contig_plane_dma_addr(dst_buf, 0) + | |
1288 | ctx->vpu_header_size[0] + | |
1289 | ctx->vpu_header_size[1] + | |
1290 | ctx->vpu_header_size[2]; | |
1291 | pic_stream_buffer_size = CODA_MAX_FRAME_SIZE - | |
1292 | ctx->vpu_header_size[0] - | |
1293 | ctx->vpu_header_size[1] - | |
1294 | ctx->vpu_header_size[2]; | |
1295 | memcpy(vb2_plane_vaddr(dst_buf, 0), | |
1296 | &ctx->vpu_header[0][0], ctx->vpu_header_size[0]); | |
1297 | memcpy(vb2_plane_vaddr(dst_buf, 0) + ctx->vpu_header_size[0], | |
1298 | &ctx->vpu_header[1][0], ctx->vpu_header_size[1]); | |
1299 | memcpy(vb2_plane_vaddr(dst_buf, 0) + ctx->vpu_header_size[0] + | |
1300 | ctx->vpu_header_size[1], &ctx->vpu_header[2][0], | |
1301 | ctx->vpu_header_size[2]); | |
1302 | } else { | |
1303 | pic_stream_buffer_addr = | |
1304 | vb2_dma_contig_plane_dma_addr(dst_buf, 0); | |
1305 | pic_stream_buffer_size = CODA_MAX_FRAME_SIZE; | |
1306 | } | |
1307 | ||
1308 | if (src_buf->v4l2_buf.flags & V4L2_BUF_FLAG_KEYFRAME) { | |
1309 | force_ipicture = 1; | |
1310 | switch (dst_fourcc) { | |
1311 | case V4L2_PIX_FMT_H264: | |
1312 | quant_param = ctx->params.h264_intra_qp; | |
1313 | break; | |
1314 | case V4L2_PIX_FMT_MPEG4: | |
1315 | quant_param = ctx->params.mpeg4_intra_qp; | |
1316 | break; | |
1317 | default: | |
1318 | v4l2_warn(&ctx->dev->v4l2_dev, | |
1319 | "cannot set intra qp, fmt not supported\n"); | |
1320 | break; | |
1321 | } | |
1322 | } else { | |
1323 | force_ipicture = 0; | |
1324 | switch (dst_fourcc) { | |
1325 | case V4L2_PIX_FMT_H264: | |
1326 | quant_param = ctx->params.h264_inter_qp; | |
1327 | break; | |
1328 | case V4L2_PIX_FMT_MPEG4: | |
1329 | quant_param = ctx->params.mpeg4_inter_qp; | |
1330 | break; | |
1331 | default: | |
1332 | v4l2_warn(&ctx->dev->v4l2_dev, | |
1333 | "cannot set inter qp, fmt not supported\n"); | |
1334 | break; | |
1335 | } | |
1336 | } | |
1337 | ||
1338 | /* submit */ | |
8f35c7bc | 1339 | coda_write(dev, CODA_ROT_MIR_ENABLE | ctx->params.rot_mode, CODA_CMD_ENC_PIC_ROT_MODE); |
186b250a JM |
1340 | coda_write(dev, quant_param, CODA_CMD_ENC_PIC_QS); |
1341 | ||
1342 | ||
1343 | picture_y = vb2_dma_contig_plane_dma_addr(src_buf, 0); | |
b96904e5 PZ |
1344 | switch (q_data_src->fourcc) { |
1345 | case V4L2_PIX_FMT_YVU420: | |
1346 | /* Switch Cb and Cr for YVU420 format */ | |
2fd6a370 PZ |
1347 | picture_cr = picture_y + q_data_src->bytesperline * |
1348 | q_data_src->height; | |
1349 | picture_cb = picture_cr + q_data_src->bytesperline / 2 * | |
b96904e5 PZ |
1350 | q_data_src->height / 2; |
1351 | break; | |
1352 | case V4L2_PIX_FMT_YUV420: | |
1353 | default: | |
2fd6a370 PZ |
1354 | picture_cb = picture_y + q_data_src->bytesperline * |
1355 | q_data_src->height; | |
1356 | picture_cr = picture_cb + q_data_src->bytesperline / 2 * | |
b96904e5 PZ |
1357 | q_data_src->height / 2; |
1358 | break; | |
1359 | } | |
186b250a | 1360 | |
89548441 PZ |
1361 | if (dev->devtype->product == CODA_960) { |
1362 | coda_write(dev, 4/*FIXME: 0*/, CODA9_CMD_ENC_PIC_SRC_INDEX); | |
1363 | coda_write(dev, q_data_src->width, CODA9_CMD_ENC_PIC_SRC_STRIDE); | |
1364 | coda_write(dev, 0, CODA9_CMD_ENC_PIC_SUB_FRAME_SYNC); | |
1365 | ||
1366 | coda_write(dev, picture_y, CODA9_CMD_ENC_PIC_SRC_ADDR_Y); | |
1367 | coda_write(dev, picture_cb, CODA9_CMD_ENC_PIC_SRC_ADDR_CB); | |
1368 | coda_write(dev, picture_cr, CODA9_CMD_ENC_PIC_SRC_ADDR_CR); | |
1369 | } else { | |
1370 | coda_write(dev, picture_y, CODA_CMD_ENC_PIC_SRC_ADDR_Y); | |
1371 | coda_write(dev, picture_cb, CODA_CMD_ENC_PIC_SRC_ADDR_CB); | |
1372 | coda_write(dev, picture_cr, CODA_CMD_ENC_PIC_SRC_ADDR_CR); | |
1373 | } | |
186b250a JM |
1374 | coda_write(dev, force_ipicture << 1 & 0x2, |
1375 | CODA_CMD_ENC_PIC_OPTION); | |
1376 | ||
1377 | coda_write(dev, pic_stream_buffer_addr, CODA_CMD_ENC_PIC_BB_START); | |
1378 | coda_write(dev, pic_stream_buffer_size / 1024, | |
1379 | CODA_CMD_ENC_PIC_BB_SIZE); | |
89548441 PZ |
1380 | |
1381 | if (!ctx->streamon_out) { | |
1382 | /* After streamoff on the output side, set the stream end flag */ | |
1383 | ctx->bit_stream_param |= CODA_BIT_STREAM_END_FLAG; | |
1384 | coda_write(dev, ctx->bit_stream_param, CODA_REG_BIT_BIT_STREAM_PARAM); | |
1385 | } | |
477c1cfe PZ |
1386 | } |
1387 | ||
1388 | static void coda_device_run(void *m2m_priv) | |
1389 | { | |
1390 | struct coda_ctx *ctx = m2m_priv; | |
1391 | struct coda_dev *dev = ctx->dev; | |
32b6f206 PZ |
1392 | |
1393 | queue_work(dev->workqueue, &ctx->pic_run_work); | |
1394 | } | |
1395 | ||
1396 | static void coda_free_framebuffers(struct coda_ctx *ctx); | |
1397 | static void coda_free_context_buffers(struct coda_ctx *ctx); | |
1398 | ||
1399 | static void coda_seq_end_work(struct work_struct *work) | |
1400 | { | |
1401 | struct coda_ctx *ctx = container_of(work, struct coda_ctx, seq_end_work); | |
1402 | struct coda_dev *dev = ctx->dev; | |
477c1cfe | 1403 | |
918c66fd | 1404 | mutex_lock(&ctx->buffer_mutex); |
32b6f206 | 1405 | mutex_lock(&dev->coda_mutex); |
477c1cfe | 1406 | |
32b6f206 PZ |
1407 | v4l2_dbg(1, coda_debug, &dev->v4l2_dev, |
1408 | "%d: %s: sent command 'SEQ_END' to coda\n", ctx->idx, __func__); | |
1409 | if (coda_command_sync(ctx, CODA_COMMAND_SEQ_END)) { | |
1410 | v4l2_err(&dev->v4l2_dev, | |
1411 | "CODA_COMMAND_SEQ_END failed\n"); | |
918c66fd | 1412 | } |
1043667b | 1413 | |
32b6f206 PZ |
1414 | kfifo_init(&ctx->bitstream_fifo, |
1415 | ctx->bitstream.vaddr, ctx->bitstream.size); | |
1416 | ||
1417 | coda_free_framebuffers(ctx); | |
1418 | coda_free_context_buffers(ctx); | |
1419 | ||
1420 | mutex_unlock(&dev->coda_mutex); | |
1421 | mutex_unlock(&ctx->buffer_mutex); | |
1422 | } | |
1423 | ||
1424 | static void coda_finish_decode(struct coda_ctx *ctx); | |
1425 | static void coda_finish_encode(struct coda_ctx *ctx); | |
1426 | ||
1427 | static void coda_pic_run_work(struct work_struct *work) | |
1428 | { | |
1429 | struct coda_ctx *ctx = container_of(work, struct coda_ctx, pic_run_work); | |
1430 | struct coda_dev *dev = ctx->dev; | |
1431 | int ret; | |
1432 | ||
1433 | mutex_lock(&ctx->buffer_mutex); | |
918c66fd PZ |
1434 | mutex_lock(&dev->coda_mutex); |
1435 | ||
1436 | if (ctx->inst_type == CODA_INST_DECODER) { | |
1437 | ret = coda_prepare_decode(ctx); | |
1438 | if (ret < 0) { | |
1439 | mutex_unlock(&dev->coda_mutex); | |
1440 | mutex_unlock(&ctx->buffer_mutex); | |
1441 | /* job_finish scheduled by prepare_decode */ | |
1442 | return; | |
1443 | } | |
1444 | } else { | |
1445 | coda_prepare_encode(ctx); | |
1043667b PZ |
1446 | } |
1447 | ||
c2d2251a PZ |
1448 | if (dev->devtype->product != CODA_DX6) |
1449 | coda_write(dev, ctx->iram_info.axi_sram_use, | |
1450 | CODA7_REG_BIT_AXI_SRAM_USE); | |
1451 | ||
918c66fd PZ |
1452 | if (ctx->inst_type == CODA_INST_DECODER) |
1453 | coda_kfifo_sync_to_device_full(ctx); | |
186b250a | 1454 | coda_command_async(ctx, CODA_COMMAND_PIC_RUN); |
32b6f206 PZ |
1455 | |
1456 | if (!wait_for_completion_timeout(&ctx->completion, msecs_to_jiffies(1000))) { | |
1457 | dev_err(&dev->plat_dev->dev, "CODA PIC_RUN timeout\n"); | |
84e2365d PZ |
1458 | |
1459 | ctx->hold = true; | |
8f45284c PZ |
1460 | |
1461 | coda_hw_reset(ctx); | |
32b6f206 PZ |
1462 | } else if (!ctx->aborting) { |
1463 | if (ctx->inst_type == CODA_INST_DECODER) | |
1464 | coda_finish_decode(ctx); | |
1465 | else | |
1466 | coda_finish_encode(ctx); | |
1467 | } | |
1468 | ||
1469 | if (ctx->aborting || (!ctx->streamon_cap && !ctx->streamon_out)) | |
1470 | queue_work(dev->workqueue, &ctx->seq_end_work); | |
1471 | ||
1472 | mutex_unlock(&dev->coda_mutex); | |
1473 | mutex_unlock(&ctx->buffer_mutex); | |
1474 | ||
14604e3a | 1475 | v4l2_m2m_job_finish(ctx->dev->m2m_dev, ctx->fh.m2m_ctx); |
186b250a JM |
1476 | } |
1477 | ||
1478 | static int coda_job_ready(void *m2m_priv) | |
1479 | { | |
1480 | struct coda_ctx *ctx = m2m_priv; | |
1481 | ||
1482 | /* | |
1483 | * For both 'P' and 'key' frame cases 1 picture | |
9082a7c6 PZ |
1484 | * and 1 frame are needed. In the decoder case, |
1485 | * the compressed frame can be in the bitstream. | |
186b250a | 1486 | */ |
14604e3a | 1487 | if (!v4l2_m2m_num_src_bufs_ready(ctx->fh.m2m_ctx) && |
9082a7c6 | 1488 | ctx->inst_type != CODA_INST_DECODER) { |
186b250a JM |
1489 | v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev, |
1490 | "not ready: not enough video buffers.\n"); | |
1491 | return 0; | |
1492 | } | |
1493 | ||
14604e3a | 1494 | if (!v4l2_m2m_num_dst_bufs_ready(ctx->fh.m2m_ctx)) { |
9082a7c6 PZ |
1495 | v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev, |
1496 | "not ready: not enough video capture buffers.\n"); | |
1497 | return 0; | |
1498 | } | |
1499 | ||
84e2365d | 1500 | if (ctx->hold || |
918c66fd PZ |
1501 | ((ctx->inst_type == CODA_INST_DECODER) && |
1502 | (coda_get_bitstream_payload(ctx) < 512) && | |
1503 | !(ctx->bit_stream_param & CODA_BIT_STREAM_END_FLAG))) { | |
1504 | v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev, | |
1505 | "%d: not ready: not enough bitstream data.\n", | |
1506 | ctx->idx); | |
1507 | return 0; | |
1508 | } | |
1509 | ||
3e748268 PZ |
1510 | if (ctx->aborting) { |
1511 | v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev, | |
1512 | "not ready: aborting\n"); | |
1513 | return 0; | |
1514 | } | |
1515 | ||
186b250a JM |
1516 | v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev, |
1517 | "job ready\n"); | |
1518 | return 1; | |
1519 | } | |
1520 | ||
1521 | static void coda_job_abort(void *priv) | |
1522 | { | |
1523 | struct coda_ctx *ctx = priv; | |
186b250a JM |
1524 | |
1525 | ctx->aborting = 1; | |
1526 | ||
1527 | v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev, | |
1528 | "Aborting task\n"); | |
186b250a JM |
1529 | } |
1530 | ||
1531 | static void coda_lock(void *m2m_priv) | |
1532 | { | |
1533 | struct coda_ctx *ctx = m2m_priv; | |
1534 | struct coda_dev *pcdev = ctx->dev; | |
1535 | mutex_lock(&pcdev->dev_mutex); | |
1536 | } | |
1537 | ||
1538 | static void coda_unlock(void *m2m_priv) | |
1539 | { | |
1540 | struct coda_ctx *ctx = m2m_priv; | |
1541 | struct coda_dev *pcdev = ctx->dev; | |
1542 | mutex_unlock(&pcdev->dev_mutex); | |
1543 | } | |
1544 | ||
1545 | static struct v4l2_m2m_ops coda_m2m_ops = { | |
1546 | .device_run = coda_device_run, | |
1547 | .job_ready = coda_job_ready, | |
1548 | .job_abort = coda_job_abort, | |
1549 | .lock = coda_lock, | |
1550 | .unlock = coda_unlock, | |
1551 | }; | |
1552 | ||
89548441 PZ |
1553 | static void coda_set_tiled_map_type(struct coda_ctx *ctx, int tiled_map_type) |
1554 | { | |
1555 | struct gdi_tiled_map *tiled_map = &ctx->tiled_map; | |
1556 | int luma_map, chro_map, i; | |
1557 | ||
1558 | memset(tiled_map, 0, sizeof(*tiled_map)); | |
1559 | ||
1560 | luma_map = 64; | |
1561 | chro_map = 64; | |
1562 | tiled_map->map_type = tiled_map_type; | |
1563 | for (i = 0; i < 16; i++) | |
1564 | tiled_map->xy2ca_map[i] = luma_map << 8 | chro_map; | |
1565 | for (i = 0; i < 4; i++) | |
1566 | tiled_map->xy2ba_map[i] = luma_map << 8 | chro_map; | |
1567 | for (i = 0; i < 16; i++) | |
1568 | tiled_map->xy2ra_map[i] = luma_map << 8 | chro_map; | |
1569 | ||
1570 | if (tiled_map_type == GDI_LINEAR_FRAME_MAP) { | |
1571 | tiled_map->xy2rbc_config = 0; | |
1572 | } else { | |
1573 | dev_err(&ctx->dev->plat_dev->dev, "invalid map type: %d\n", | |
1574 | tiled_map_type); | |
1575 | return; | |
1576 | } | |
1577 | } | |
1578 | ||
186b250a JM |
1579 | static void set_default_params(struct coda_ctx *ctx) |
1580 | { | |
b96904e5 PZ |
1581 | int max_w; |
1582 | int max_h; | |
1583 | ||
1584 | ctx->codec = &ctx->dev->devtype->codecs[0]; | |
1585 | max_w = ctx->codec->max_w; | |
1586 | max_h = ctx->codec->max_h; | |
186b250a JM |
1587 | |
1588 | ctx->params.codec_mode = CODA_MODE_INVALID; | |
1589 | ctx->colorspace = V4L2_COLORSPACE_REC709; | |
1590 | ctx->params.framerate = 30; | |
186b250a JM |
1591 | ctx->aborting = 0; |
1592 | ||
1593 | /* Default formats for output and input queues */ | |
b96904e5 PZ |
1594 | ctx->q_data[V4L2_M2M_SRC].fourcc = ctx->codec->src_fourcc; |
1595 | ctx->q_data[V4L2_M2M_DST].fourcc = ctx->codec->dst_fourcc; | |
1596 | ctx->q_data[V4L2_M2M_SRC].width = max_w; | |
1597 | ctx->q_data[V4L2_M2M_SRC].height = max_h; | |
2fd6a370 | 1598 | ctx->q_data[V4L2_M2M_SRC].bytesperline = max_w; |
b96904e5 PZ |
1599 | ctx->q_data[V4L2_M2M_SRC].sizeimage = (max_w * max_h * 3) / 2; |
1600 | ctx->q_data[V4L2_M2M_DST].width = max_w; | |
1601 | ctx->q_data[V4L2_M2M_DST].height = max_h; | |
2fd6a370 | 1602 | ctx->q_data[V4L2_M2M_DST].bytesperline = 0; |
186b250a | 1603 | ctx->q_data[V4L2_M2M_DST].sizeimage = CODA_MAX_FRAME_SIZE; |
52c41676 PZ |
1604 | ctx->q_data[V4L2_M2M_SRC].rect.width = max_w; |
1605 | ctx->q_data[V4L2_M2M_SRC].rect.height = max_h; | |
1606 | ctx->q_data[V4L2_M2M_DST].rect.width = max_w; | |
1607 | ctx->q_data[V4L2_M2M_DST].rect.height = max_h; | |
89548441 PZ |
1608 | |
1609 | if (ctx->dev->devtype->product == CODA_960) | |
1610 | coda_set_tiled_map_type(ctx, GDI_LINEAR_FRAME_MAP); | |
186b250a JM |
1611 | } |
1612 | ||
1613 | /* | |
1614 | * Queue operations | |
1615 | */ | |
1616 | static int coda_queue_setup(struct vb2_queue *vq, | |
1617 | const struct v4l2_format *fmt, | |
1618 | unsigned int *nbuffers, unsigned int *nplanes, | |
1619 | unsigned int sizes[], void *alloc_ctxs[]) | |
1620 | { | |
1621 | struct coda_ctx *ctx = vb2_get_drv_priv(vq); | |
e34db066 | 1622 | struct coda_q_data *q_data; |
186b250a JM |
1623 | unsigned int size; |
1624 | ||
e34db066 PZ |
1625 | q_data = get_q_data(ctx, vq->type); |
1626 | size = q_data->sizeimage; | |
186b250a JM |
1627 | |
1628 | *nplanes = 1; | |
1629 | sizes[0] = size; | |
1630 | ||
1631 | alloc_ctxs[0] = ctx->dev->alloc_ctx; | |
1632 | ||
1633 | v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev, | |
1634 | "get %d buffer(s) of size %d each.\n", *nbuffers, size); | |
1635 | ||
1636 | return 0; | |
1637 | } | |
1638 | ||
1639 | static int coda_buf_prepare(struct vb2_buffer *vb) | |
1640 | { | |
1641 | struct coda_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); | |
1642 | struct coda_q_data *q_data; | |
1643 | ||
1644 | q_data = get_q_data(ctx, vb->vb2_queue->type); | |
1645 | ||
1646 | if (vb2_plane_size(vb, 0) < q_data->sizeimage) { | |
1647 | v4l2_warn(&ctx->dev->v4l2_dev, | |
1648 | "%s data will not fit into plane (%lu < %lu)\n", | |
1649 | __func__, vb2_plane_size(vb, 0), | |
1650 | (long)q_data->sizeimage); | |
1651 | return -EINVAL; | |
1652 | } | |
1653 | ||
186b250a JM |
1654 | return 0; |
1655 | } | |
1656 | ||
1657 | static void coda_buf_queue(struct vb2_buffer *vb) | |
1658 | { | |
1659 | struct coda_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); | |
89548441 | 1660 | struct coda_dev *dev = ctx->dev; |
918c66fd PZ |
1661 | struct coda_q_data *q_data; |
1662 | ||
1663 | q_data = get_q_data(ctx, vb->vb2_queue->type); | |
1664 | ||
1665 | /* | |
1666 | * In the decoder case, immediately try to copy the buffer into the | |
1667 | * bitstream ringbuffer and mark it as ready to be dequeued. | |
1668 | */ | |
1669 | if (q_data->fourcc == V4L2_PIX_FMT_H264 && | |
1670 | vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { | |
1671 | /* | |
39c1cb2b | 1672 | * For backwards compatibility, queuing an empty buffer marks |
918c66fd PZ |
1673 | * the stream end |
1674 | */ | |
89548441 | 1675 | if (vb2_get_plane_payload(vb, 0) == 0) { |
918c66fd | 1676 | ctx->bit_stream_param |= CODA_BIT_STREAM_END_FLAG; |
89548441 PZ |
1677 | if ((dev->devtype->product == CODA_960) && |
1678 | coda_isbusy(dev) && | |
1679 | (ctx->idx == coda_read(dev, CODA_REG_BIT_RUN_INDEX))) { | |
1680 | /* if this decoder instance is running, set the stream end flag */ | |
1681 | coda_write(dev, ctx->bit_stream_param, CODA_REG_BIT_BIT_STREAM_PARAM); | |
1682 | } | |
1683 | } | |
918c66fd | 1684 | mutex_lock(&ctx->bitstream_mutex); |
14604e3a | 1685 | v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vb); |
918c66fd PZ |
1686 | coda_fill_bitstream(ctx); |
1687 | mutex_unlock(&ctx->bitstream_mutex); | |
1688 | } else { | |
14604e3a | 1689 | v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vb); |
918c66fd | 1690 | } |
186b250a JM |
1691 | } |
1692 | ||
86eda90e PZ |
1693 | static void coda_parabuf_write(struct coda_ctx *ctx, int index, u32 value) |
1694 | { | |
1695 | struct coda_dev *dev = ctx->dev; | |
1696 | u32 *p = ctx->parabuf.vaddr; | |
1697 | ||
1698 | if (dev->devtype->product == CODA_DX6) | |
1699 | p[index] = value; | |
1700 | else | |
1701 | p[index ^ 1] = value; | |
1702 | } | |
1703 | ||
5677e3b0 | 1704 | static int coda_alloc_aux_buf(struct coda_dev *dev, |
f61c0b14 PZ |
1705 | struct coda_aux_buf *buf, size_t size, |
1706 | const char *name, struct dentry *parent) | |
5677e3b0 PZ |
1707 | { |
1708 | buf->vaddr = dma_alloc_coherent(&dev->plat_dev->dev, size, &buf->paddr, | |
1709 | GFP_KERNEL); | |
1710 | if (!buf->vaddr) | |
1711 | return -ENOMEM; | |
1712 | ||
1713 | buf->size = size; | |
1714 | ||
f61c0b14 PZ |
1715 | if (name && parent) { |
1716 | buf->blob.data = buf->vaddr; | |
1717 | buf->blob.size = size; | |
1718 | buf->dentry = debugfs_create_blob(name, 0644, parent, &buf->blob); | |
1719 | if (!buf->dentry) | |
1720 | dev_warn(&dev->plat_dev->dev, | |
1721 | "failed to create debugfs entry %s\n", name); | |
1722 | } | |
1723 | ||
5677e3b0 PZ |
1724 | return 0; |
1725 | } | |
1726 | ||
1727 | static inline int coda_alloc_context_buf(struct coda_ctx *ctx, | |
f61c0b14 PZ |
1728 | struct coda_aux_buf *buf, size_t size, |
1729 | const char *name) | |
5677e3b0 | 1730 | { |
f61c0b14 | 1731 | return coda_alloc_aux_buf(ctx->dev, buf, size, name, ctx->debugfs_entry); |
5677e3b0 PZ |
1732 | } |
1733 | ||
1734 | static void coda_free_aux_buf(struct coda_dev *dev, | |
1735 | struct coda_aux_buf *buf) | |
1736 | { | |
1737 | if (buf->vaddr) { | |
1738 | dma_free_coherent(&dev->plat_dev->dev, buf->size, | |
1739 | buf->vaddr, buf->paddr); | |
1740 | buf->vaddr = NULL; | |
1741 | buf->size = 0; | |
1742 | } | |
f61c0b14 | 1743 | debugfs_remove(buf->dentry); |
5677e3b0 PZ |
1744 | } |
1745 | ||
1746 | static void coda_free_framebuffers(struct coda_ctx *ctx) | |
1747 | { | |
1748 | int i; | |
1749 | ||
1750 | for (i = 0; i < CODA_MAX_FRAMEBUFFERS; i++) | |
1751 | coda_free_aux_buf(ctx->dev, &ctx->internal_frames[i]); | |
1752 | } | |
1753 | ||
ec25f68d PZ |
1754 | static int coda_alloc_framebuffers(struct coda_ctx *ctx, struct coda_q_data *q_data, u32 fourcc) |
1755 | { | |
1756 | struct coda_dev *dev = ctx->dev; | |
7c3df789 | 1757 | int width, height; |
86eda90e PZ |
1758 | dma_addr_t paddr; |
1759 | int ysize; | |
5677e3b0 | 1760 | int ret; |
ec25f68d PZ |
1761 | int i; |
1762 | ||
7c3df789 PZ |
1763 | if (ctx->codec && (ctx->codec->src_fourcc == V4L2_PIX_FMT_H264 || |
1764 | ctx->codec->dst_fourcc == V4L2_PIX_FMT_H264)) { | |
1765 | width = round_up(q_data->width, 16); | |
1766 | height = round_up(q_data->height, 16); | |
1767 | } else { | |
1768 | width = round_up(q_data->width, 8); | |
1769 | height = q_data->height; | |
1770 | } | |
1771 | ysize = width * height; | |
86eda90e | 1772 | |
ec25f68d | 1773 | /* Allocate frame buffers */ |
ec25f68d | 1774 | for (i = 0; i < ctx->num_internal_frames; i++) { |
5677e3b0 | 1775 | size_t size; |
f61c0b14 | 1776 | char *name; |
5677e3b0 | 1777 | |
aed14b0a | 1778 | size = ysize + ysize / 2; |
5677e3b0 PZ |
1779 | if (ctx->codec->src_fourcc == V4L2_PIX_FMT_H264 && |
1780 | dev->devtype->product != CODA_DX6) | |
aed14b0a | 1781 | size += ysize / 4; |
f61c0b14 PZ |
1782 | name = kasprintf(GFP_KERNEL, "fb%d", i); |
1783 | ret = coda_alloc_context_buf(ctx, &ctx->internal_frames[i], | |
1784 | size, name); | |
1785 | kfree(name); | |
5677e3b0 | 1786 | if (ret < 0) { |
ec25f68d | 1787 | coda_free_framebuffers(ctx); |
5677e3b0 | 1788 | return ret; |
ec25f68d PZ |
1789 | } |
1790 | } | |
1791 | ||
1792 | /* Register frame buffers in the parameter buffer */ | |
86eda90e PZ |
1793 | for (i = 0; i < ctx->num_internal_frames; i++) { |
1794 | paddr = ctx->internal_frames[i].paddr; | |
1795 | coda_parabuf_write(ctx, i * 3 + 0, paddr); /* Y */ | |
1796 | coda_parabuf_write(ctx, i * 3 + 1, paddr + ysize); /* Cb */ | |
1797 | coda_parabuf_write(ctx, i * 3 + 2, paddr + ysize + ysize/4); /* Cr */ | |
ec25f68d | 1798 | |
5677e3b0 PZ |
1799 | /* mvcol buffer for h.264 */ |
1800 | if (ctx->codec->src_fourcc == V4L2_PIX_FMT_H264 && | |
1801 | dev->devtype->product != CODA_DX6) | |
1802 | coda_parabuf_write(ctx, 96 + i, | |
1803 | ctx->internal_frames[i].paddr + | |
1804 | ysize + ysize/4 + ysize/4); | |
ec25f68d PZ |
1805 | } |
1806 | ||
5677e3b0 PZ |
1807 | /* mvcol buffer for mpeg4 */ |
1808 | if ((dev->devtype->product != CODA_DX6) && | |
1809 | (ctx->codec->src_fourcc == V4L2_PIX_FMT_MPEG4)) | |
1810 | coda_parabuf_write(ctx, 97, ctx->internal_frames[i].paddr + | |
1811 | ysize + ysize/4 + ysize/4); | |
1812 | ||
ec25f68d PZ |
1813 | return 0; |
1814 | } | |
1815 | ||
3f3f5c7f JM |
1816 | static int coda_h264_padding(int size, char *p) |
1817 | { | |
3f3f5c7f JM |
1818 | int nal_size; |
1819 | int diff; | |
1820 | ||
832fbb5a | 1821 | diff = size - (size & ~0x7); |
3f3f5c7f JM |
1822 | if (diff == 0) |
1823 | return 0; | |
1824 | ||
832fbb5a | 1825 | nal_size = coda_filler_size[diff]; |
3f3f5c7f JM |
1826 | memcpy(p, coda_filler_nal, nal_size); |
1827 | ||
1828 | /* Add rbsp stop bit and trailing at the end */ | |
1829 | *(p + nal_size - 1) = 0x80; | |
1830 | ||
1831 | return nal_size; | |
1832 | } | |
1833 | ||
b313bcc9 PZ |
1834 | static phys_addr_t coda_iram_alloc(struct coda_iram_info *iram, size_t size) |
1835 | { | |
1836 | phys_addr_t ret; | |
1837 | ||
1838 | size = round_up(size, 1024); | |
1839 | if (size > iram->remaining) | |
1840 | return 0; | |
1841 | iram->remaining -= size; | |
1842 | ||
1843 | ret = iram->next_paddr; | |
1844 | iram->next_paddr += size; | |
1845 | ||
1846 | return ret; | |
1847 | } | |
1848 | ||
c2d2251a PZ |
1849 | static void coda_setup_iram(struct coda_ctx *ctx) |
1850 | { | |
1851 | struct coda_iram_info *iram_info = &ctx->iram_info; | |
1852 | struct coda_dev *dev = ctx->dev; | |
c2d2251a | 1853 | int mb_width; |
b313bcc9 PZ |
1854 | int dbk_bits; |
1855 | int bit_bits; | |
1856 | int ip_bits; | |
c2d2251a PZ |
1857 | |
1858 | memset(iram_info, 0, sizeof(*iram_info)); | |
b313bcc9 PZ |
1859 | iram_info->next_paddr = dev->iram.paddr; |
1860 | iram_info->remaining = dev->iram.size; | |
c2d2251a | 1861 | |
b313bcc9 PZ |
1862 | switch (dev->devtype->product) { |
1863 | case CODA_7541: | |
1864 | dbk_bits = CODA7_USE_HOST_DBK_ENABLE | CODA7_USE_DBK_ENABLE; | |
1865 | bit_bits = CODA7_USE_HOST_BIT_ENABLE | CODA7_USE_BIT_ENABLE; | |
1866 | ip_bits = CODA7_USE_HOST_IP_ENABLE | CODA7_USE_IP_ENABLE; | |
1867 | break; | |
89548441 PZ |
1868 | case CODA_960: |
1869 | dbk_bits = CODA9_USE_HOST_DBK_ENABLE | CODA9_USE_DBK_ENABLE; | |
1870 | bit_bits = CODA9_USE_HOST_BIT_ENABLE | CODA7_USE_BIT_ENABLE; | |
1871 | ip_bits = CODA9_USE_HOST_IP_ENABLE | CODA7_USE_IP_ENABLE; | |
1872 | break; | |
b313bcc9 | 1873 | default: /* CODA_DX6 */ |
c2d2251a | 1874 | return; |
b313bcc9 | 1875 | } |
c2d2251a PZ |
1876 | |
1877 | if (ctx->inst_type == CODA_INST_ENCODER) { | |
1878 | struct coda_q_data *q_data_src; | |
1879 | ||
1880 | q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT); | |
1881 | mb_width = DIV_ROUND_UP(q_data_src->width, 16); | |
1882 | ||
1883 | /* Prioritize in case IRAM is too small for everything */ | |
b313bcc9 PZ |
1884 | if (dev->devtype->product == CODA_7541) { |
1885 | iram_info->search_ram_size = round_up(mb_width * 16 * | |
1886 | 36 + 2048, 1024); | |
1887 | iram_info->search_ram_paddr = coda_iram_alloc(iram_info, | |
1888 | iram_info->search_ram_size); | |
1889 | if (!iram_info->search_ram_paddr) { | |
1890 | pr_err("IRAM is smaller than the search ram size\n"); | |
1891 | goto out; | |
1892 | } | |
1893 | iram_info->axi_sram_use |= CODA7_USE_HOST_ME_ENABLE | | |
1894 | CODA7_USE_ME_ENABLE; | |
c2d2251a PZ |
1895 | } |
1896 | ||
1897 | /* Only H.264BP and H.263P3 are considered */ | |
b313bcc9 PZ |
1898 | iram_info->buf_dbk_y_use = coda_iram_alloc(iram_info, 64 * mb_width); |
1899 | iram_info->buf_dbk_c_use = coda_iram_alloc(iram_info, 64 * mb_width); | |
1900 | if (!iram_info->buf_dbk_c_use) | |
c2d2251a | 1901 | goto out; |
b313bcc9 | 1902 | iram_info->axi_sram_use |= dbk_bits; |
c2d2251a | 1903 | |
b313bcc9 PZ |
1904 | iram_info->buf_bit_use = coda_iram_alloc(iram_info, 128 * mb_width); |
1905 | if (!iram_info->buf_bit_use) | |
c2d2251a | 1906 | goto out; |
b313bcc9 | 1907 | iram_info->axi_sram_use |= bit_bits; |
c2d2251a | 1908 | |
b313bcc9 PZ |
1909 | iram_info->buf_ip_ac_dc_use = coda_iram_alloc(iram_info, 128 * mb_width); |
1910 | if (!iram_info->buf_ip_ac_dc_use) | |
1911 | goto out; | |
1912 | iram_info->axi_sram_use |= ip_bits; | |
c2d2251a | 1913 | |
8358e76c PZ |
1914 | /* OVL and BTP disabled for encoder */ |
1915 | } else if (ctx->inst_type == CODA_INST_DECODER) { | |
1916 | struct coda_q_data *q_data_dst; | |
8358e76c PZ |
1917 | |
1918 | q_data_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE); | |
1919 | mb_width = DIV_ROUND_UP(q_data_dst->width, 16); | |
b313bcc9 PZ |
1920 | |
1921 | iram_info->buf_dbk_y_use = coda_iram_alloc(iram_info, 128 * mb_width); | |
1922 | iram_info->buf_dbk_c_use = coda_iram_alloc(iram_info, 128 * mb_width); | |
1923 | if (!iram_info->buf_dbk_c_use) | |
8358e76c | 1924 | goto out; |
b313bcc9 | 1925 | iram_info->axi_sram_use |= dbk_bits; |
8358e76c | 1926 | |
b313bcc9 PZ |
1927 | iram_info->buf_bit_use = coda_iram_alloc(iram_info, 128 * mb_width); |
1928 | if (!iram_info->buf_bit_use) | |
8358e76c | 1929 | goto out; |
b313bcc9 | 1930 | iram_info->axi_sram_use |= bit_bits; |
8358e76c | 1931 | |
b313bcc9 PZ |
1932 | iram_info->buf_ip_ac_dc_use = coda_iram_alloc(iram_info, 128 * mb_width); |
1933 | if (!iram_info->buf_ip_ac_dc_use) | |
8358e76c | 1934 | goto out; |
b313bcc9 | 1935 | iram_info->axi_sram_use |= ip_bits; |
8358e76c | 1936 | |
b313bcc9 | 1937 | /* OVL and BTP unused as there is no VC1 support yet */ |
c2d2251a PZ |
1938 | } |
1939 | ||
1940 | out: | |
c2d2251a PZ |
1941 | if (!(iram_info->axi_sram_use & CODA7_USE_HOST_IP_ENABLE)) |
1942 | v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev, | |
1943 | "IRAM smaller than needed\n"); | |
1944 | ||
1945 | if (dev->devtype->product == CODA_7541) { | |
1946 | /* TODO - Enabling these causes picture errors on CODA7541 */ | |
8358e76c PZ |
1947 | if (ctx->inst_type == CODA_INST_DECODER) { |
1948 | /* fw 1.4.50 */ | |
1949 | iram_info->axi_sram_use &= ~(CODA7_USE_HOST_IP_ENABLE | | |
1950 | CODA7_USE_IP_ENABLE); | |
1951 | } else { | |
1952 | /* fw 13.4.29 */ | |
c2d2251a PZ |
1953 | iram_info->axi_sram_use &= ~(CODA7_USE_HOST_IP_ENABLE | |
1954 | CODA7_USE_HOST_DBK_ENABLE | | |
1955 | CODA7_USE_IP_ENABLE | | |
1956 | CODA7_USE_DBK_ENABLE); | |
1957 | } | |
1958 | } | |
1959 | } | |
1960 | ||
5677e3b0 PZ |
1961 | static void coda_free_context_buffers(struct coda_ctx *ctx) |
1962 | { | |
1963 | struct coda_dev *dev = ctx->dev; | |
1964 | ||
918c66fd PZ |
1965 | coda_free_aux_buf(dev, &ctx->slicebuf); |
1966 | coda_free_aux_buf(dev, &ctx->psbuf); | |
5677e3b0 PZ |
1967 | if (dev->devtype->product != CODA_DX6) |
1968 | coda_free_aux_buf(dev, &ctx->workbuf); | |
1969 | } | |
1970 | ||
1971 | static int coda_alloc_context_buffers(struct coda_ctx *ctx, | |
1972 | struct coda_q_data *q_data) | |
1973 | { | |
1974 | struct coda_dev *dev = ctx->dev; | |
1975 | size_t size; | |
1976 | int ret; | |
1977 | ||
e5b0d1c6 | 1978 | if (dev->devtype->product == CODA_DX6) |
5677e3b0 | 1979 | return 0; |
5677e3b0 | 1980 | |
918c66fd PZ |
1981 | if (ctx->psbuf.vaddr) { |
1982 | v4l2_err(&dev->v4l2_dev, "psmembuf still allocated\n"); | |
1983 | return -EBUSY; | |
1984 | } | |
1985 | if (ctx->slicebuf.vaddr) { | |
1986 | v4l2_err(&dev->v4l2_dev, "slicebuf still allocated\n"); | |
1987 | return -EBUSY; | |
1988 | } | |
5677e3b0 PZ |
1989 | if (ctx->workbuf.vaddr) { |
1990 | v4l2_err(&dev->v4l2_dev, "context buffer still allocated\n"); | |
1991 | ret = -EBUSY; | |
1992 | return -ENOMEM; | |
1993 | } | |
1994 | ||
918c66fd PZ |
1995 | if (q_data->fourcc == V4L2_PIX_FMT_H264) { |
1996 | /* worst case slice size */ | |
1997 | size = (DIV_ROUND_UP(q_data->width, 16) * | |
1998 | DIV_ROUND_UP(q_data->height, 16)) * 3200 / 8 + 512; | |
f61c0b14 | 1999 | ret = coda_alloc_context_buf(ctx, &ctx->slicebuf, size, "slicebuf"); |
918c66fd PZ |
2000 | if (ret < 0) { |
2001 | v4l2_err(&dev->v4l2_dev, "failed to allocate %d byte slice buffer", | |
2002 | ctx->slicebuf.size); | |
2003 | return ret; | |
2004 | } | |
2005 | } | |
2006 | ||
2007 | if (dev->devtype->product == CODA_7541) { | |
f61c0b14 | 2008 | ret = coda_alloc_context_buf(ctx, &ctx->psbuf, CODA7_PS_BUF_SIZE, "psbuf"); |
918c66fd PZ |
2009 | if (ret < 0) { |
2010 | v4l2_err(&dev->v4l2_dev, "failed to allocate psmem buffer"); | |
2011 | goto err; | |
2012 | } | |
2013 | } | |
2014 | ||
e5b0d1c6 PZ |
2015 | size = dev->devtype->workbuf_size; |
2016 | if (dev->devtype->product == CODA_960 && | |
2017 | q_data->fourcc == V4L2_PIX_FMT_H264) | |
2018 | size += CODA9_PS_SAVE_SIZE; | |
f61c0b14 | 2019 | ret = coda_alloc_context_buf(ctx, &ctx->workbuf, size, "workbuf"); |
5677e3b0 PZ |
2020 | if (ret < 0) { |
2021 | v4l2_err(&dev->v4l2_dev, "failed to allocate %d byte context buffer", | |
2022 | ctx->workbuf.size); | |
2023 | goto err; | |
2024 | } | |
2025 | ||
2026 | return 0; | |
2027 | ||
2028 | err: | |
2029 | coda_free_context_buffers(ctx); | |
2030 | return ret; | |
2031 | } | |
2032 | ||
918c66fd PZ |
2033 | static int coda_start_decoding(struct coda_ctx *ctx) |
2034 | { | |
2035 | struct coda_q_data *q_data_src, *q_data_dst; | |
2036 | u32 bitstream_buf, bitstream_size; | |
2037 | struct coda_dev *dev = ctx->dev; | |
2038 | int width, height; | |
2039 | u32 src_fourcc; | |
2040 | u32 val; | |
2041 | int ret; | |
2042 | ||
2043 | /* Start decoding */ | |
2044 | q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT); | |
2045 | q_data_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE); | |
2046 | bitstream_buf = ctx->bitstream.paddr; | |
2047 | bitstream_size = ctx->bitstream.size; | |
2048 | src_fourcc = q_data_src->fourcc; | |
2049 | ||
2050 | coda_write(dev, ctx->parabuf.paddr, CODA_REG_BIT_PARA_BUF_ADDR); | |
2051 | ||
2052 | /* Update coda bitstream read and write pointers from kfifo */ | |
2053 | coda_kfifo_sync_to_device_full(ctx); | |
2054 | ||
2055 | ctx->display_idx = -1; | |
2056 | ctx->frm_dis_flg = 0; | |
2057 | coda_write(dev, 0, CODA_REG_BIT_FRM_DIS_FLG(ctx->reg_idx)); | |
2058 | ||
2059 | coda_write(dev, CODA_BIT_DEC_SEQ_INIT_ESCAPE, | |
2060 | CODA_REG_BIT_BIT_STREAM_PARAM); | |
2061 | ||
2062 | coda_write(dev, bitstream_buf, CODA_CMD_DEC_SEQ_BB_START); | |
2063 | coda_write(dev, bitstream_size / 1024, CODA_CMD_DEC_SEQ_BB_SIZE); | |
2064 | val = 0; | |
89548441 PZ |
2065 | if ((dev->devtype->product == CODA_7541) || |
2066 | (dev->devtype->product == CODA_960)) | |
918c66fd PZ |
2067 | val |= CODA_REORDER_ENABLE; |
2068 | coda_write(dev, val, CODA_CMD_DEC_SEQ_OPTION); | |
2069 | ||
2070 | ctx->params.codec_mode = ctx->codec->mode; | |
89548441 PZ |
2071 | if (dev->devtype->product == CODA_960 && |
2072 | src_fourcc == V4L2_PIX_FMT_MPEG4) | |
2073 | ctx->params.codec_mode_aux = CODA_MP4_AUX_MPEG4; | |
2074 | else | |
2075 | ctx->params.codec_mode_aux = 0; | |
918c66fd PZ |
2076 | if (src_fourcc == V4L2_PIX_FMT_H264) { |
2077 | if (dev->devtype->product == CODA_7541) { | |
2078 | coda_write(dev, ctx->psbuf.paddr, | |
2079 | CODA_CMD_DEC_SEQ_PS_BB_START); | |
2080 | coda_write(dev, (CODA7_PS_BUF_SIZE / 1024), | |
2081 | CODA_CMD_DEC_SEQ_PS_BB_SIZE); | |
2082 | } | |
89548441 PZ |
2083 | if (dev->devtype->product == CODA_960) { |
2084 | coda_write(dev, 0, CODA_CMD_DEC_SEQ_X264_MV_EN); | |
2085 | coda_write(dev, 512, CODA_CMD_DEC_SEQ_SPP_CHUNK_SIZE); | |
2086 | } | |
2087 | } | |
2088 | if (dev->devtype->product != CODA_960) { | |
2089 | coda_write(dev, 0, CODA_CMD_DEC_SEQ_SRC_SIZE); | |
918c66fd PZ |
2090 | } |
2091 | ||
2092 | if (coda_command_sync(ctx, CODA_COMMAND_SEQ_INIT)) { | |
2093 | v4l2_err(&dev->v4l2_dev, "CODA_COMMAND_SEQ_INIT timeout\n"); | |
2094 | coda_write(dev, 0, CODA_REG_BIT_BIT_STREAM_PARAM); | |
2095 | return -ETIMEDOUT; | |
2096 | } | |
2097 | ||
2098 | /* Update kfifo out pointer from coda bitstream read pointer */ | |
2099 | coda_kfifo_sync_from_device(ctx); | |
2100 | ||
2101 | coda_write(dev, 0, CODA_REG_BIT_BIT_STREAM_PARAM); | |
2102 | ||
2103 | if (coda_read(dev, CODA_RET_DEC_SEQ_SUCCESS) == 0) { | |
2104 | v4l2_err(&dev->v4l2_dev, | |
2105 | "CODA_COMMAND_SEQ_INIT failed, error code = %d\n", | |
2106 | coda_read(dev, CODA_RET_DEC_SEQ_ERR_REASON)); | |
2107 | return -EAGAIN; | |
2108 | } | |
2109 | ||
2110 | val = coda_read(dev, CODA_RET_DEC_SEQ_SRC_SIZE); | |
2111 | if (dev->devtype->product == CODA_DX6) { | |
2112 | width = (val >> CODADX6_PICWIDTH_OFFSET) & CODADX6_PICWIDTH_MASK; | |
2113 | height = val & CODADX6_PICHEIGHT_MASK; | |
2114 | } else { | |
2115 | width = (val >> CODA7_PICWIDTH_OFFSET) & CODA7_PICWIDTH_MASK; | |
2116 | height = val & CODA7_PICHEIGHT_MASK; | |
2117 | } | |
2118 | ||
2119 | if (width > q_data_dst->width || height > q_data_dst->height) { | |
2120 | v4l2_err(&dev->v4l2_dev, "stream is %dx%d, not %dx%d\n", | |
2121 | width, height, q_data_dst->width, q_data_dst->height); | |
2122 | return -EINVAL; | |
2123 | } | |
2124 | ||
2125 | width = round_up(width, 16); | |
2126 | height = round_up(height, 16); | |
2127 | ||
2128 | v4l2_dbg(1, coda_debug, &dev->v4l2_dev, "%s instance %d now: %dx%d\n", | |
2129 | __func__, ctx->idx, width, height); | |
2130 | ||
a500a938 | 2131 | ctx->num_internal_frames = coda_read(dev, CODA_RET_DEC_SEQ_FRAME_NEED); |
918c66fd PZ |
2132 | if (ctx->num_internal_frames > CODA_MAX_FRAMEBUFFERS) { |
2133 | v4l2_err(&dev->v4l2_dev, | |
2134 | "not enough framebuffers to decode (%d < %d)\n", | |
2135 | CODA_MAX_FRAMEBUFFERS, ctx->num_internal_frames); | |
2136 | return -EINVAL; | |
2137 | } | |
2138 | ||
52c41676 PZ |
2139 | if (src_fourcc == V4L2_PIX_FMT_H264) { |
2140 | u32 left_right; | |
2141 | u32 top_bottom; | |
2142 | ||
2143 | left_right = coda_read(dev, CODA_RET_DEC_SEQ_CROP_LEFT_RIGHT); | |
2144 | top_bottom = coda_read(dev, CODA_RET_DEC_SEQ_CROP_TOP_BOTTOM); | |
2145 | ||
2146 | q_data_dst->rect.left = (left_right >> 10) & 0x3ff; | |
2147 | q_data_dst->rect.top = (top_bottom >> 10) & 0x3ff; | |
2148 | q_data_dst->rect.width = width - q_data_dst->rect.left - | |
2149 | (left_right & 0x3ff); | |
2150 | q_data_dst->rect.height = height - q_data_dst->rect.top - | |
2151 | (top_bottom & 0x3ff); | |
2152 | } | |
2153 | ||
918c66fd PZ |
2154 | ret = coda_alloc_framebuffers(ctx, q_data_dst, src_fourcc); |
2155 | if (ret < 0) | |
2156 | return ret; | |
2157 | ||
2158 | /* Tell the decoder how many frame buffers we allocated. */ | |
2159 | coda_write(dev, ctx->num_internal_frames, CODA_CMD_SET_FRAME_BUF_NUM); | |
2160 | coda_write(dev, width, CODA_CMD_SET_FRAME_BUF_STRIDE); | |
2161 | ||
2162 | if (dev->devtype->product != CODA_DX6) { | |
2163 | /* Set secondary AXI IRAM */ | |
2164 | coda_setup_iram(ctx); | |
2165 | ||
2166 | coda_write(dev, ctx->iram_info.buf_bit_use, | |
2167 | CODA7_CMD_SET_FRAME_AXI_BIT_ADDR); | |
2168 | coda_write(dev, ctx->iram_info.buf_ip_ac_dc_use, | |
2169 | CODA7_CMD_SET_FRAME_AXI_IPACDC_ADDR); | |
2170 | coda_write(dev, ctx->iram_info.buf_dbk_y_use, | |
2171 | CODA7_CMD_SET_FRAME_AXI_DBKY_ADDR); | |
2172 | coda_write(dev, ctx->iram_info.buf_dbk_c_use, | |
2173 | CODA7_CMD_SET_FRAME_AXI_DBKC_ADDR); | |
2174 | coda_write(dev, ctx->iram_info.buf_ovl_use, | |
2175 | CODA7_CMD_SET_FRAME_AXI_OVL_ADDR); | |
89548441 PZ |
2176 | if (dev->devtype->product == CODA_960) |
2177 | coda_write(dev, ctx->iram_info.buf_btp_use, | |
2178 | CODA9_CMD_SET_FRAME_AXI_BTP_ADDR); | |
2179 | } | |
2180 | ||
2181 | if (dev->devtype->product == CODA_960) { | |
2182 | coda_write(dev, -1, CODA9_CMD_SET_FRAME_DELAY); | |
2183 | ||
2184 | coda_write(dev, 0x20262024, CODA9_CMD_SET_FRAME_CACHE_SIZE); | |
2185 | coda_write(dev, 2 << CODA9_CACHE_PAGEMERGE_OFFSET | | |
2186 | 32 << CODA9_CACHE_LUMA_BUFFER_SIZE_OFFSET | | |
2187 | 8 << CODA9_CACHE_CB_BUFFER_SIZE_OFFSET | | |
2188 | 8 << CODA9_CACHE_CR_BUFFER_SIZE_OFFSET, | |
2189 | CODA9_CMD_SET_FRAME_CACHE_CONFIG); | |
918c66fd PZ |
2190 | } |
2191 | ||
2192 | if (src_fourcc == V4L2_PIX_FMT_H264) { | |
2193 | coda_write(dev, ctx->slicebuf.paddr, | |
2194 | CODA_CMD_SET_FRAME_SLICE_BB_START); | |
2195 | coda_write(dev, ctx->slicebuf.size / 1024, | |
2196 | CODA_CMD_SET_FRAME_SLICE_BB_SIZE); | |
2197 | } | |
2198 | ||
2199 | if (dev->devtype->product == CODA_7541) { | |
2200 | int max_mb_x = 1920 / 16; | |
2201 | int max_mb_y = 1088 / 16; | |
2202 | int max_mb_num = max_mb_x * max_mb_y; | |
89548441 | 2203 | |
918c66fd PZ |
2204 | coda_write(dev, max_mb_num << 16 | max_mb_x << 8 | max_mb_y, |
2205 | CODA7_CMD_SET_FRAME_MAX_DEC_SIZE); | |
89548441 PZ |
2206 | } else if (dev->devtype->product == CODA_960) { |
2207 | int max_mb_x = 1920 / 16; | |
2208 | int max_mb_y = 1088 / 16; | |
2209 | int max_mb_num = max_mb_x * max_mb_y; | |
2210 | ||
2211 | coda_write(dev, max_mb_num << 16 | max_mb_x << 8 | max_mb_y, | |
2212 | CODA9_CMD_SET_FRAME_MAX_DEC_SIZE); | |
918c66fd PZ |
2213 | } |
2214 | ||
2215 | if (coda_command_sync(ctx, CODA_COMMAND_SET_FRAME_BUF)) { | |
2216 | v4l2_err(&ctx->dev->v4l2_dev, | |
2217 | "CODA_COMMAND_SET_FRAME_BUF timeout\n"); | |
2218 | return -ETIMEDOUT; | |
2219 | } | |
2220 | ||
2221 | return 0; | |
2222 | } | |
2223 | ||
d35167a1 PZ |
2224 | static int coda_encode_header(struct coda_ctx *ctx, struct vb2_buffer *buf, |
2225 | int header_code, u8 *header, int *size) | |
2226 | { | |
2227 | struct coda_dev *dev = ctx->dev; | |
89548441 | 2228 | size_t bufsize; |
d35167a1 | 2229 | int ret; |
89548441 PZ |
2230 | int i; |
2231 | ||
2232 | if (dev->devtype->product == CODA_960) | |
2233 | memset(vb2_plane_vaddr(buf, 0), 0, 64); | |
d35167a1 PZ |
2234 | |
2235 | coda_write(dev, vb2_dma_contig_plane_dma_addr(buf, 0), | |
2236 | CODA_CMD_ENC_HEADER_BB_START); | |
89548441 PZ |
2237 | bufsize = vb2_plane_size(buf, 0); |
2238 | if (dev->devtype->product == CODA_960) | |
2239 | bufsize /= 1024; | |
2240 | coda_write(dev, bufsize, CODA_CMD_ENC_HEADER_BB_SIZE); | |
d35167a1 PZ |
2241 | coda_write(dev, header_code, CODA_CMD_ENC_HEADER_CODE); |
2242 | ret = coda_command_sync(ctx, CODA_COMMAND_ENCODE_HEADER); | |
2243 | if (ret < 0) { | |
2244 | v4l2_err(&dev->v4l2_dev, "CODA_COMMAND_ENCODE_HEADER timeout\n"); | |
2245 | return ret; | |
2246 | } | |
89548441 PZ |
2247 | |
2248 | if (dev->devtype->product == CODA_960) { | |
2249 | for (i = 63; i > 0; i--) | |
2250 | if (((char *)vb2_plane_vaddr(buf, 0))[i] != 0) | |
2251 | break; | |
2252 | *size = i + 1; | |
2253 | } else { | |
2254 | *size = coda_read(dev, CODA_REG_BIT_WR_PTR(ctx->reg_idx)) - | |
2255 | coda_read(dev, CODA_CMD_ENC_HEADER_BB_START); | |
2256 | } | |
d35167a1 PZ |
2257 | memcpy(header, vb2_plane_vaddr(buf, 0), *size); |
2258 | ||
2259 | return 0; | |
2260 | } | |
2261 | ||
89548441 PZ |
2262 | static int coda_start_encoding(struct coda_ctx *ctx); |
2263 | ||
186b250a JM |
2264 | static int coda_start_streaming(struct vb2_queue *q, unsigned int count) |
2265 | { | |
2266 | struct coda_ctx *ctx = vb2_get_drv_priv(q); | |
2267 | struct v4l2_device *v4l2_dev = &ctx->dev->v4l2_dev; | |
186b250a JM |
2268 | struct coda_dev *dev = ctx->dev; |
2269 | struct coda_q_data *q_data_src, *q_data_dst; | |
ec25f68d | 2270 | u32 dst_fourcc; |
d35167a1 | 2271 | int ret = 0; |
186b250a | 2272 | |
918c66fd PZ |
2273 | q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT); |
2274 | if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { | |
2275 | if (q_data_src->fourcc == V4L2_PIX_FMT_H264) { | |
2276 | if (coda_get_bitstream_payload(ctx) < 512) | |
2277 | return -EINVAL; | |
2278 | } else { | |
2279 | if (count < 1) | |
2280 | return -EINVAL; | |
2281 | } | |
186b250a | 2282 | |
b96904e5 | 2283 | ctx->streamon_out = 1; |
186b250a | 2284 | |
b96904e5 PZ |
2285 | if (coda_format_is_yuv(q_data_src->fourcc)) |
2286 | ctx->inst_type = CODA_INST_ENCODER; | |
2287 | else | |
2288 | ctx->inst_type = CODA_INST_DECODER; | |
918c66fd PZ |
2289 | } else { |
2290 | if (count < 1) | |
2291 | return -EINVAL; | |
2292 | ||
2293 | ctx->streamon_cap = 1; | |
b96904e5 | 2294 | } |
186b250a | 2295 | |
b96904e5 PZ |
2296 | /* Don't start the coda unless both queues are on */ |
2297 | if (!(ctx->streamon_out & ctx->streamon_cap)) | |
2298 | return 0; | |
186b250a | 2299 | |
eb107516 PZ |
2300 | /* Allow decoder device_run with no new buffers queued */ |
2301 | if (ctx->inst_type == CODA_INST_DECODER) | |
14604e3a | 2302 | v4l2_m2m_set_src_buffered(ctx->fh.m2m_ctx, true); |
918c66fd | 2303 | |
b96904e5 | 2304 | ctx->gopcounter = ctx->params.gop_size - 1; |
186b250a | 2305 | q_data_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE); |
b96904e5 PZ |
2306 | dst_fourcc = q_data_dst->fourcc; |
2307 | ||
2308 | ctx->codec = coda_find_codec(ctx->dev, q_data_src->fourcc, | |
2309 | q_data_dst->fourcc); | |
2310 | if (!ctx->codec) { | |
186b250a JM |
2311 | v4l2_err(v4l2_dev, "couldn't tell instance type.\n"); |
2312 | return -EINVAL; | |
2313 | } | |
2314 | ||
5677e3b0 PZ |
2315 | /* Allocate per-instance buffers */ |
2316 | ret = coda_alloc_context_buffers(ctx, q_data_src); | |
2317 | if (ret < 0) | |
2318 | return ret; | |
2319 | ||
918c66fd PZ |
2320 | if (ctx->inst_type == CODA_INST_DECODER) { |
2321 | mutex_lock(&dev->coda_mutex); | |
2322 | ret = coda_start_decoding(ctx); | |
2323 | mutex_unlock(&dev->coda_mutex); | |
89548441 | 2324 | if (ret == -EAGAIN) |
918c66fd | 2325 | return 0; |
89548441 | 2326 | else if (ret < 0) |
918c66fd | 2327 | return ret; |
89548441 PZ |
2328 | } else { |
2329 | ret = coda_start_encoding(ctx); | |
918c66fd PZ |
2330 | } |
2331 | ||
89548441 PZ |
2332 | ctx->initialized = 1; |
2333 | return ret; | |
2334 | } | |
2335 | ||
2336 | static int coda_start_encoding(struct coda_ctx *ctx) | |
2337 | { | |
2338 | struct coda_dev *dev = ctx->dev; | |
2339 | struct v4l2_device *v4l2_dev = &dev->v4l2_dev; | |
2340 | struct coda_q_data *q_data_src, *q_data_dst; | |
2341 | u32 bitstream_buf, bitstream_size; | |
2342 | struct vb2_buffer *buf; | |
2343 | int gamma, ret, value; | |
2344 | u32 dst_fourcc; | |
2345 | ||
2346 | q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT); | |
2347 | q_data_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE); | |
2348 | dst_fourcc = q_data_dst->fourcc; | |
2349 | ||
14604e3a | 2350 | buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); |
89548441 PZ |
2351 | bitstream_buf = vb2_dma_contig_plane_dma_addr(buf, 0); |
2352 | bitstream_size = q_data_dst->sizeimage; | |
2353 | ||
186b250a JM |
2354 | if (!coda_is_initialized(dev)) { |
2355 | v4l2_err(v4l2_dev, "coda is not initialized.\n"); | |
2356 | return -EFAULT; | |
2357 | } | |
fcb62825 PZ |
2358 | |
2359 | mutex_lock(&dev->coda_mutex); | |
2360 | ||
186b250a | 2361 | coda_write(dev, ctx->parabuf.paddr, CODA_REG_BIT_PARA_BUF_ADDR); |
5677e3b0 PZ |
2362 | coda_write(dev, bitstream_buf, CODA_REG_BIT_RD_PTR(ctx->reg_idx)); |
2363 | coda_write(dev, bitstream_buf, CODA_REG_BIT_WR_PTR(ctx->reg_idx)); | |
186b250a JM |
2364 | switch (dev->devtype->product) { |
2365 | case CODA_DX6: | |
2366 | coda_write(dev, CODADX6_STREAM_BUF_DYNALLOC_EN | | |
2367 | CODADX6_STREAM_BUF_PIC_RESET, CODA_REG_BIT_STREAM_CTRL); | |
2368 | break; | |
89548441 PZ |
2369 | case CODA_960: |
2370 | coda_write(dev, 0, CODA9_GDI_WPROT_RGN_EN); | |
2371 | /* fallthrough */ | |
2372 | case CODA_7541: | |
186b250a JM |
2373 | coda_write(dev, CODA7_STREAM_BUF_DYNALLOC_EN | |
2374 | CODA7_STREAM_BUF_PIC_RESET, CODA_REG_BIT_STREAM_CTRL); | |
89548441 | 2375 | break; |
186b250a JM |
2376 | } |
2377 | ||
89548441 PZ |
2378 | value = coda_read(dev, CODA_REG_BIT_FRAME_MEM_CTRL); |
2379 | value &= ~(1 << 2 | 0x7 << 9); | |
2380 | ctx->frame_mem_ctrl = value; | |
2381 | coda_write(dev, value, CODA_REG_BIT_FRAME_MEM_CTRL); | |
2382 | ||
1043667b PZ |
2383 | if (dev->devtype->product == CODA_DX6) { |
2384 | /* Configure the coda */ | |
b313bcc9 | 2385 | coda_write(dev, dev->iram.paddr, CODADX6_REG_BIT_SEARCH_RAM_BASE_ADDR); |
1043667b | 2386 | } |
186b250a JM |
2387 | |
2388 | /* Could set rotation here if needed */ | |
2389 | switch (dev->devtype->product) { | |
2390 | case CODA_DX6: | |
2391 | value = (q_data_src->width & CODADX6_PICWIDTH_MASK) << CODADX6_PICWIDTH_OFFSET; | |
b96904e5 | 2392 | value |= (q_data_src->height & CODADX6_PICHEIGHT_MASK) << CODA_PICHEIGHT_OFFSET; |
186b250a | 2393 | break; |
7c3df789 PZ |
2394 | case CODA_7541: |
2395 | if (dst_fourcc == V4L2_PIX_FMT_H264) { | |
2396 | value = (round_up(q_data_src->width, 16) & | |
2397 | CODA7_PICWIDTH_MASK) << CODA7_PICWIDTH_OFFSET; | |
2398 | value |= (round_up(q_data_src->height, 16) & | |
2399 | CODA7_PICHEIGHT_MASK) << CODA_PICHEIGHT_OFFSET; | |
2400 | break; | |
2401 | } | |
2402 | /* fallthrough */ | |
2403 | case CODA_960: | |
186b250a | 2404 | value = (q_data_src->width & CODA7_PICWIDTH_MASK) << CODA7_PICWIDTH_OFFSET; |
b96904e5 | 2405 | value |= (q_data_src->height & CODA7_PICHEIGHT_MASK) << CODA_PICHEIGHT_OFFSET; |
186b250a | 2406 | } |
186b250a JM |
2407 | coda_write(dev, value, CODA_CMD_ENC_SEQ_SRC_SIZE); |
2408 | coda_write(dev, ctx->params.framerate, | |
2409 | CODA_CMD_ENC_SEQ_SRC_F_RATE); | |
2410 | ||
b96904e5 | 2411 | ctx->params.codec_mode = ctx->codec->mode; |
186b250a JM |
2412 | switch (dst_fourcc) { |
2413 | case V4L2_PIX_FMT_MPEG4: | |
89548441 PZ |
2414 | if (dev->devtype->product == CODA_960) |
2415 | coda_write(dev, CODA9_STD_MPEG4, CODA_CMD_ENC_SEQ_COD_STD); | |
2416 | else | |
2417 | coda_write(dev, CODA_STD_MPEG4, CODA_CMD_ENC_SEQ_COD_STD); | |
186b250a JM |
2418 | coda_write(dev, 0, CODA_CMD_ENC_SEQ_MP4_PARA); |
2419 | break; | |
2420 | case V4L2_PIX_FMT_H264: | |
89548441 PZ |
2421 | if (dev->devtype->product == CODA_960) |
2422 | coda_write(dev, CODA9_STD_H264, CODA_CMD_ENC_SEQ_COD_STD); | |
2423 | else | |
2424 | coda_write(dev, CODA_STD_H264, CODA_CMD_ENC_SEQ_COD_STD); | |
de23b1db PZ |
2425 | if (ctx->params.h264_deblk_enabled) { |
2426 | value = ((ctx->params.h264_deblk_alpha & | |
2427 | CODA_264PARAM_DEBLKFILTEROFFSETALPHA_MASK) << | |
2428 | CODA_264PARAM_DEBLKFILTEROFFSETALPHA_OFFSET) | | |
2429 | ((ctx->params.h264_deblk_beta & | |
2430 | CODA_264PARAM_DEBLKFILTEROFFSETBETA_MASK) << | |
2431 | CODA_264PARAM_DEBLKFILTEROFFSETBETA_OFFSET); | |
2432 | } else { | |
2433 | value = 1 << CODA_264PARAM_DISABLEDEBLK_OFFSET; | |
2434 | } | |
2435 | coda_write(dev, value, CODA_CMD_ENC_SEQ_264_PARA); | |
186b250a JM |
2436 | break; |
2437 | default: | |
2438 | v4l2_err(v4l2_dev, | |
2439 | "dst format (0x%08x) invalid.\n", dst_fourcc); | |
fcb62825 PZ |
2440 | ret = -EINVAL; |
2441 | goto out; | |
186b250a JM |
2442 | } |
2443 | ||
c566c789 PZ |
2444 | switch (ctx->params.slice_mode) { |
2445 | case V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE: | |
2446 | value = 0; | |
2447 | break; | |
2448 | case V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB: | |
2449 | value = (ctx->params.slice_max_mb & CODA_SLICING_SIZE_MASK) << CODA_SLICING_SIZE_OFFSET; | |
2450 | value |= (1 & CODA_SLICING_UNIT_MASK) << CODA_SLICING_UNIT_OFFSET; | |
2451 | value |= 1 & CODA_SLICING_MODE_MASK; | |
2452 | break; | |
2453 | case V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES: | |
2454 | value = (ctx->params.slice_max_bits & CODA_SLICING_SIZE_MASK) << CODA_SLICING_SIZE_OFFSET; | |
2455 | value |= (0 & CODA_SLICING_UNIT_MASK) << CODA_SLICING_UNIT_OFFSET; | |
186b250a | 2456 | value |= 1 & CODA_SLICING_MODE_MASK; |
c566c789 PZ |
2457 | break; |
2458 | } | |
186b250a | 2459 | coda_write(dev, value, CODA_CMD_ENC_SEQ_SLICE_MODE); |
c566c789 | 2460 | value = ctx->params.gop_size & CODA_GOP_SIZE_MASK; |
186b250a JM |
2461 | coda_write(dev, value, CODA_CMD_ENC_SEQ_GOP_SIZE); |
2462 | ||
2463 | if (ctx->params.bitrate) { | |
2464 | /* Rate control enabled */ | |
2465 | value = (ctx->params.bitrate & CODA_RATECONTROL_BITRATE_MASK) << CODA_RATECONTROL_BITRATE_OFFSET; | |
2466 | value |= 1 & CODA_RATECONTROL_ENABLE_MASK; | |
89548441 PZ |
2467 | if (dev->devtype->product == CODA_960) |
2468 | value |= BIT(31); /* disable autoskip */ | |
186b250a JM |
2469 | } else { |
2470 | value = 0; | |
2471 | } | |
2472 | coda_write(dev, value, CODA_CMD_ENC_SEQ_RC_PARA); | |
2473 | ||
2474 | coda_write(dev, 0, CODA_CMD_ENC_SEQ_RC_BUF_SIZE); | |
f38f79d5 PZ |
2475 | coda_write(dev, ctx->params.intra_refresh, |
2476 | CODA_CMD_ENC_SEQ_INTRA_REFRESH); | |
186b250a JM |
2477 | |
2478 | coda_write(dev, bitstream_buf, CODA_CMD_ENC_SEQ_BB_START); | |
2479 | coda_write(dev, bitstream_size / 1024, CODA_CMD_ENC_SEQ_BB_SIZE); | |
2480 | ||
186b250a | 2481 | |
89548441 PZ |
2482 | value = 0; |
2483 | if (dev->devtype->product == CODA_960) | |
2484 | gamma = CODA9_DEFAULT_GAMMA; | |
2485 | else | |
2486 | gamma = CODA_DEFAULT_GAMMA; | |
2487 | if (gamma > 0) { | |
2488 | coda_write(dev, (gamma & CODA_GAMMA_MASK) << CODA_GAMMA_OFFSET, | |
2489 | CODA_CMD_ENC_SEQ_RC_GAMMA); | |
2490 | } | |
1a5567e3 PZ |
2491 | |
2492 | if (ctx->params.h264_min_qp || ctx->params.h264_max_qp) { | |
2493 | coda_write(dev, | |
2494 | ctx->params.h264_min_qp << CODA_QPMIN_OFFSET | | |
2495 | ctx->params.h264_max_qp << CODA_QPMAX_OFFSET, | |
2496 | CODA_CMD_ENC_SEQ_RC_QP_MIN_MAX); | |
2497 | } | |
89548441 | 2498 | if (dev->devtype->product == CODA_960) { |
1a5567e3 PZ |
2499 | if (ctx->params.h264_max_qp) |
2500 | value |= 1 << CODA9_OPTION_RCQPMAX_OFFSET; | |
89548441 PZ |
2501 | if (CODA_DEFAULT_GAMMA > 0) |
2502 | value |= 1 << CODA9_OPTION_GAMMA_OFFSET; | |
fb1fcf17 | 2503 | } else { |
89548441 PZ |
2504 | if (CODA_DEFAULT_GAMMA > 0) { |
2505 | if (dev->devtype->product == CODA_DX6) | |
2506 | value |= 1 << CODADX6_OPTION_GAMMA_OFFSET; | |
2507 | else | |
2508 | value |= 1 << CODA7_OPTION_GAMMA_OFFSET; | |
2509 | } | |
1a5567e3 PZ |
2510 | if (ctx->params.h264_min_qp) |
2511 | value |= 1 << CODA7_OPTION_RCQPMIN_OFFSET; | |
2512 | if (ctx->params.h264_max_qp) | |
2513 | value |= 1 << CODA7_OPTION_RCQPMAX_OFFSET; | |
fb1fcf17 | 2514 | } |
186b250a JM |
2515 | coda_write(dev, value, CODA_CMD_ENC_SEQ_OPTION); |
2516 | ||
89548441 PZ |
2517 | coda_write(dev, 0, CODA_CMD_ENC_SEQ_RC_INTERVAL_MODE); |
2518 | ||
c2d2251a PZ |
2519 | coda_setup_iram(ctx); |
2520 | ||
186b250a | 2521 | if (dst_fourcc == V4L2_PIX_FMT_H264) { |
89548441 PZ |
2522 | switch (dev->devtype->product) { |
2523 | case CODA_DX6: | |
0fd84dc8 | 2524 | value = FMO_SLICE_SAVE_BUF_SIZE << 7; |
1043667b | 2525 | coda_write(dev, value, CODADX6_CMD_ENC_SEQ_FMO); |
89548441 PZ |
2526 | break; |
2527 | case CODA_7541: | |
c2d2251a PZ |
2528 | coda_write(dev, ctx->iram_info.search_ram_paddr, |
2529 | CODA7_CMD_ENC_SEQ_SEARCH_BASE); | |
2530 | coda_write(dev, ctx->iram_info.search_ram_size, | |
2531 | CODA7_CMD_ENC_SEQ_SEARCH_SIZE); | |
89548441 PZ |
2532 | break; |
2533 | case CODA_960: | |
2534 | coda_write(dev, 0, CODA9_CMD_ENC_SEQ_ME_OPTION); | |
2535 | coda_write(dev, 0, CODA9_CMD_ENC_SEQ_INTRA_WEIGHT); | |
1043667b | 2536 | } |
186b250a JM |
2537 | } |
2538 | ||
fcb62825 PZ |
2539 | ret = coda_command_sync(ctx, CODA_COMMAND_SEQ_INIT); |
2540 | if (ret < 0) { | |
186b250a | 2541 | v4l2_err(v4l2_dev, "CODA_COMMAND_SEQ_INIT timeout\n"); |
fcb62825 | 2542 | goto out; |
186b250a JM |
2543 | } |
2544 | ||
fcb62825 PZ |
2545 | if (coda_read(dev, CODA_RET_ENC_SEQ_SUCCESS) == 0) { |
2546 | v4l2_err(v4l2_dev, "CODA_COMMAND_SEQ_INIT failed\n"); | |
2547 | ret = -EFAULT; | |
2548 | goto out; | |
2549 | } | |
186b250a | 2550 | |
89548441 PZ |
2551 | if (dev->devtype->product == CODA_960) |
2552 | ctx->num_internal_frames = 4; | |
2553 | else | |
2554 | ctx->num_internal_frames = 2; | |
ec25f68d | 2555 | ret = coda_alloc_framebuffers(ctx, q_data_src, dst_fourcc); |
fcb62825 PZ |
2556 | if (ret < 0) { |
2557 | v4l2_err(v4l2_dev, "failed to allocate framebuffers\n"); | |
2558 | goto out; | |
2559 | } | |
186b250a | 2560 | |
ec25f68d | 2561 | coda_write(dev, ctx->num_internal_frames, CODA_CMD_SET_FRAME_BUF_NUM); |
2fd6a370 PZ |
2562 | coda_write(dev, q_data_src->bytesperline, |
2563 | CODA_CMD_SET_FRAME_BUF_STRIDE); | |
2564 | if (dev->devtype->product == CODA_7541) { | |
2565 | coda_write(dev, q_data_src->bytesperline, | |
918c66fd | 2566 | CODA7_CMD_SET_FRAME_SOURCE_BUF_STRIDE); |
2fd6a370 | 2567 | } |
1043667b | 2568 | if (dev->devtype->product != CODA_DX6) { |
c2d2251a PZ |
2569 | coda_write(dev, ctx->iram_info.buf_bit_use, |
2570 | CODA7_CMD_SET_FRAME_AXI_BIT_ADDR); | |
2571 | coda_write(dev, ctx->iram_info.buf_ip_ac_dc_use, | |
2572 | CODA7_CMD_SET_FRAME_AXI_IPACDC_ADDR); | |
2573 | coda_write(dev, ctx->iram_info.buf_dbk_y_use, | |
2574 | CODA7_CMD_SET_FRAME_AXI_DBKY_ADDR); | |
2575 | coda_write(dev, ctx->iram_info.buf_dbk_c_use, | |
2576 | CODA7_CMD_SET_FRAME_AXI_DBKC_ADDR); | |
2577 | coda_write(dev, ctx->iram_info.buf_ovl_use, | |
2578 | CODA7_CMD_SET_FRAME_AXI_OVL_ADDR); | |
89548441 PZ |
2579 | if (dev->devtype->product == CODA_960) { |
2580 | coda_write(dev, ctx->iram_info.buf_btp_use, | |
2581 | CODA9_CMD_SET_FRAME_AXI_BTP_ADDR); | |
2582 | ||
2583 | /* FIXME */ | |
2584 | coda_write(dev, ctx->internal_frames[2].paddr, CODA9_CMD_SET_FRAME_SUBSAMP_A); | |
2585 | coda_write(dev, ctx->internal_frames[3].paddr, CODA9_CMD_SET_FRAME_SUBSAMP_B); | |
2586 | } | |
1043667b | 2587 | } |
89548441 | 2588 | |
fcb62825 PZ |
2589 | ret = coda_command_sync(ctx, CODA_COMMAND_SET_FRAME_BUF); |
2590 | if (ret < 0) { | |
186b250a | 2591 | v4l2_err(v4l2_dev, "CODA_COMMAND_SET_FRAME_BUF timeout\n"); |
fcb62825 | 2592 | goto out; |
186b250a JM |
2593 | } |
2594 | ||
2595 | /* Save stream headers */ | |
14604e3a | 2596 | buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); |
186b250a JM |
2597 | switch (dst_fourcc) { |
2598 | case V4L2_PIX_FMT_H264: | |
2599 | /* | |
2600 | * Get SPS in the first frame and copy it to an | |
2601 | * intermediate buffer. | |
2602 | */ | |
d35167a1 PZ |
2603 | ret = coda_encode_header(ctx, buf, CODA_HEADER_H264_SPS, |
2604 | &ctx->vpu_header[0][0], | |
2605 | &ctx->vpu_header_size[0]); | |
2606 | if (ret < 0) | |
2607 | goto out; | |
186b250a JM |
2608 | |
2609 | /* | |
2610 | * Get PPS in the first frame and copy it to an | |
2611 | * intermediate buffer. | |
2612 | */ | |
d35167a1 PZ |
2613 | ret = coda_encode_header(ctx, buf, CODA_HEADER_H264_PPS, |
2614 | &ctx->vpu_header[1][0], | |
2615 | &ctx->vpu_header_size[1]); | |
2616 | if (ret < 0) | |
2617 | goto out; | |
2618 | ||
3f3f5c7f JM |
2619 | /* |
2620 | * Length of H.264 headers is variable and thus it might not be | |
2621 | * aligned for the coda to append the encoded frame. In that is | |
2622 | * the case a filler NAL must be added to header 2. | |
2623 | */ | |
2624 | ctx->vpu_header_size[2] = coda_h264_padding( | |
2625 | (ctx->vpu_header_size[0] + | |
2626 | ctx->vpu_header_size[1]), | |
2627 | ctx->vpu_header[2]); | |
186b250a JM |
2628 | break; |
2629 | case V4L2_PIX_FMT_MPEG4: | |
2630 | /* | |
2631 | * Get VOS in the first frame and copy it to an | |
2632 | * intermediate buffer | |
2633 | */ | |
d35167a1 PZ |
2634 | ret = coda_encode_header(ctx, buf, CODA_HEADER_MP4V_VOS, |
2635 | &ctx->vpu_header[0][0], | |
2636 | &ctx->vpu_header_size[0]); | |
2637 | if (ret < 0) | |
2638 | goto out; | |
2639 | ||
2640 | ret = coda_encode_header(ctx, buf, CODA_HEADER_MP4V_VIS, | |
2641 | &ctx->vpu_header[1][0], | |
2642 | &ctx->vpu_header_size[1]); | |
2643 | if (ret < 0) | |
2644 | goto out; | |
2645 | ||
2646 | ret = coda_encode_header(ctx, buf, CODA_HEADER_MP4V_VOL, | |
2647 | &ctx->vpu_header[2][0], | |
2648 | &ctx->vpu_header_size[2]); | |
2649 | if (ret < 0) | |
2650 | goto out; | |
186b250a JM |
2651 | break; |
2652 | default: | |
2653 | /* No more formats need to save headers at the moment */ | |
2654 | break; | |
2655 | } | |
2656 | ||
d35167a1 | 2657 | out: |
fcb62825 | 2658 | mutex_unlock(&dev->coda_mutex); |
d35167a1 | 2659 | return ret; |
186b250a JM |
2660 | } |
2661 | ||
e37559b2 | 2662 | static void coda_stop_streaming(struct vb2_queue *q) |
186b250a JM |
2663 | { |
2664 | struct coda_ctx *ctx = vb2_get_drv_priv(q); | |
2fb57f06 | 2665 | struct coda_dev *dev = ctx->dev; |
186b250a JM |
2666 | |
2667 | if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { | |
918c66fd | 2668 | v4l2_dbg(1, coda_debug, &dev->v4l2_dev, |
186b250a | 2669 | "%s: output\n", __func__); |
b96904e5 | 2670 | ctx->streamon_out = 0; |
918c66fd | 2671 | |
89548441 PZ |
2672 | if (ctx->inst_type == CODA_INST_DECODER && |
2673 | coda_isbusy(dev) && ctx->idx == coda_read(dev, CODA_REG_BIT_RUN_INDEX)) { | |
2674 | /* if this decoder instance is running, set the stream end flag */ | |
2675 | if (dev->devtype->product == CODA_960) { | |
2676 | u32 val = coda_read(dev, CODA_REG_BIT_BIT_STREAM_PARAM); | |
2677 | ||
2678 | val |= CODA_BIT_STREAM_END_FLAG; | |
2679 | coda_write(dev, val, CODA_REG_BIT_BIT_STREAM_PARAM); | |
2680 | ctx->bit_stream_param = val; | |
2681 | } | |
2682 | } | |
918c66fd PZ |
2683 | ctx->bit_stream_param |= CODA_BIT_STREAM_END_FLAG; |
2684 | ||
2685 | ctx->isequence = 0; | |
186b250a | 2686 | } else { |
918c66fd | 2687 | v4l2_dbg(1, coda_debug, &dev->v4l2_dev, |
186b250a | 2688 | "%s: capture\n", __func__); |
b96904e5 | 2689 | ctx->streamon_cap = 0; |
2fb57f06 | 2690 | |
918c66fd | 2691 | ctx->osequence = 0; |
cb2c0282 | 2692 | ctx->sequence_offset = 0; |
186b250a JM |
2693 | } |
2694 | ||
918c66fd | 2695 | if (!ctx->streamon_out && !ctx->streamon_cap) { |
846ced9c PZ |
2696 | struct coda_timestamp *ts; |
2697 | ||
2698 | while (!list_empty(&ctx->timestamp_list)) { | |
2699 | ts = list_first_entry(&ctx->timestamp_list, | |
2700 | struct coda_timestamp, list); | |
2701 | list_del(&ts->list); | |
2702 | kfree(ts); | |
2703 | } | |
918c66fd PZ |
2704 | kfifo_init(&ctx->bitstream_fifo, |
2705 | ctx->bitstream.vaddr, ctx->bitstream.size); | |
2706 | ctx->runcounter = 0; | |
2707 | } | |
186b250a JM |
2708 | } |
2709 | ||
2710 | static struct vb2_ops coda_qops = { | |
2711 | .queue_setup = coda_queue_setup, | |
2712 | .buf_prepare = coda_buf_prepare, | |
2713 | .buf_queue = coda_buf_queue, | |
186b250a JM |
2714 | .start_streaming = coda_start_streaming, |
2715 | .stop_streaming = coda_stop_streaming, | |
152ea1c8 PZ |
2716 | .wait_prepare = vb2_ops_wait_prepare, |
2717 | .wait_finish = vb2_ops_wait_finish, | |
186b250a JM |
2718 | }; |
2719 | ||
2720 | static int coda_s_ctrl(struct v4l2_ctrl *ctrl) | |
2721 | { | |
2722 | struct coda_ctx *ctx = | |
2723 | container_of(ctrl->handler, struct coda_ctx, ctrls); | |
2724 | ||
2725 | v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev, | |
2726 | "s_ctrl: id = %d, val = %d\n", ctrl->id, ctrl->val); | |
2727 | ||
2728 | switch (ctrl->id) { | |
8f35c7bc PZ |
2729 | case V4L2_CID_HFLIP: |
2730 | if (ctrl->val) | |
2731 | ctx->params.rot_mode |= CODA_MIR_HOR; | |
2732 | else | |
2733 | ctx->params.rot_mode &= ~CODA_MIR_HOR; | |
2734 | break; | |
2735 | case V4L2_CID_VFLIP: | |
2736 | if (ctrl->val) | |
2737 | ctx->params.rot_mode |= CODA_MIR_VER; | |
2738 | else | |
2739 | ctx->params.rot_mode &= ~CODA_MIR_VER; | |
2740 | break; | |
186b250a JM |
2741 | case V4L2_CID_MPEG_VIDEO_BITRATE: |
2742 | ctx->params.bitrate = ctrl->val / 1000; | |
2743 | break; | |
2744 | case V4L2_CID_MPEG_VIDEO_GOP_SIZE: | |
2745 | ctx->params.gop_size = ctrl->val; | |
2746 | break; | |
2747 | case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP: | |
2748 | ctx->params.h264_intra_qp = ctrl->val; | |
2749 | break; | |
2750 | case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP: | |
2751 | ctx->params.h264_inter_qp = ctrl->val; | |
2752 | break; | |
1a5567e3 PZ |
2753 | case V4L2_CID_MPEG_VIDEO_H264_MIN_QP: |
2754 | ctx->params.h264_min_qp = ctrl->val; | |
2755 | break; | |
2756 | case V4L2_CID_MPEG_VIDEO_H264_MAX_QP: | |
2757 | ctx->params.h264_max_qp = ctrl->val; | |
2758 | break; | |
de23b1db PZ |
2759 | case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA: |
2760 | ctx->params.h264_deblk_alpha = ctrl->val; | |
2761 | break; | |
2762 | case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA: | |
2763 | ctx->params.h264_deblk_beta = ctrl->val; | |
2764 | break; | |
2765 | case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE: | |
2766 | ctx->params.h264_deblk_enabled = (ctrl->val == | |
2767 | V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED); | |
2768 | break; | |
186b250a JM |
2769 | case V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP: |
2770 | ctx->params.mpeg4_intra_qp = ctrl->val; | |
2771 | break; | |
2772 | case V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP: | |
2773 | ctx->params.mpeg4_inter_qp = ctrl->val; | |
2774 | break; | |
2775 | case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE: | |
2776 | ctx->params.slice_mode = ctrl->val; | |
2777 | break; | |
2778 | case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB: | |
2779 | ctx->params.slice_max_mb = ctrl->val; | |
2780 | break; | |
c566c789 PZ |
2781 | case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES: |
2782 | ctx->params.slice_max_bits = ctrl->val * 8; | |
2783 | break; | |
186b250a JM |
2784 | case V4L2_CID_MPEG_VIDEO_HEADER_MODE: |
2785 | break; | |
f38f79d5 PZ |
2786 | case V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB: |
2787 | ctx->params.intra_refresh = ctrl->val; | |
2788 | break; | |
186b250a JM |
2789 | default: |
2790 | v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev, | |
2791 | "Invalid control, id=%d, val=%d\n", | |
2792 | ctrl->id, ctrl->val); | |
2793 | return -EINVAL; | |
2794 | } | |
2795 | ||
2796 | return 0; | |
2797 | } | |
2798 | ||
2799 | static struct v4l2_ctrl_ops coda_ctrl_ops = { | |
2800 | .s_ctrl = coda_s_ctrl, | |
2801 | }; | |
2802 | ||
2803 | static int coda_ctrls_setup(struct coda_ctx *ctx) | |
2804 | { | |
2805 | v4l2_ctrl_handler_init(&ctx->ctrls, 9); | |
2806 | ||
8f35c7bc PZ |
2807 | v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, |
2808 | V4L2_CID_HFLIP, 0, 1, 1, 0); | |
2809 | v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, | |
2810 | V4L2_CID_VFLIP, 0, 1, 1, 0); | |
186b250a JM |
2811 | v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, |
2812 | V4L2_CID_MPEG_VIDEO_BITRATE, 0, 32767000, 1, 0); | |
2813 | v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, | |
2814 | V4L2_CID_MPEG_VIDEO_GOP_SIZE, 1, 60, 1, 16); | |
2815 | v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, | |
594a750b | 2816 | V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP, 0, 51, 1, 25); |
186b250a | 2817 | v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, |
594a750b | 2818 | V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP, 0, 51, 1, 25); |
1a5567e3 PZ |
2819 | if (ctx->dev->devtype->product != CODA_960) { |
2820 | v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, | |
2821 | V4L2_CID_MPEG_VIDEO_H264_MIN_QP, 0, 51, 1, 12); | |
2822 | } | |
2823 | v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, | |
2824 | V4L2_CID_MPEG_VIDEO_H264_MAX_QP, 0, 51, 1, 51); | |
de23b1db PZ |
2825 | v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, |
2826 | V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA, 0, 15, 1, 0); | |
2827 | v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, | |
2828 | V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA, 0, 15, 1, 0); | |
2829 | v4l2_ctrl_new_std_menu(&ctx->ctrls, &coda_ctrl_ops, | |
2830 | V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE, | |
2831 | V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED, 0x0, | |
2832 | V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED); | |
186b250a JM |
2833 | v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, |
2834 | V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP, 1, 31, 1, 2); | |
2835 | v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, | |
2836 | V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP, 1, 31, 1, 2); | |
2837 | v4l2_ctrl_new_std_menu(&ctx->ctrls, &coda_ctrl_ops, | |
2838 | V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE, | |
c566c789 PZ |
2839 | V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES, 0x0, |
2840 | V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE); | |
186b250a JM |
2841 | v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, |
2842 | V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB, 1, 0x3fffffff, 1, 1); | |
c566c789 PZ |
2843 | v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, |
2844 | V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES, 1, 0x3fffffff, 1, 500); | |
186b250a JM |
2845 | v4l2_ctrl_new_std_menu(&ctx->ctrls, &coda_ctrl_ops, |
2846 | V4L2_CID_MPEG_VIDEO_HEADER_MODE, | |
2847 | V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME, | |
2848 | (1 << V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE), | |
2849 | V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME); | |
f38f79d5 PZ |
2850 | v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, |
2851 | V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB, 0, 1920 * 1088 / 256, 1, 0); | |
186b250a JM |
2852 | |
2853 | if (ctx->ctrls.error) { | |
2854 | v4l2_err(&ctx->dev->v4l2_dev, "control initialization error (%d)", | |
2855 | ctx->ctrls.error); | |
2856 | return -EINVAL; | |
2857 | } | |
2858 | ||
2859 | return v4l2_ctrl_handler_setup(&ctx->ctrls); | |
2860 | } | |
2861 | ||
2862 | static int coda_queue_init(void *priv, struct vb2_queue *src_vq, | |
2863 | struct vb2_queue *dst_vq) | |
2864 | { | |
2865 | struct coda_ctx *ctx = priv; | |
2866 | int ret; | |
2867 | ||
186b250a | 2868 | src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; |
419869c8 | 2869 | src_vq->io_modes = VB2_DMABUF | VB2_MMAP | VB2_USERPTR; |
186b250a JM |
2870 | src_vq->drv_priv = ctx; |
2871 | src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); | |
2872 | src_vq->ops = &coda_qops; | |
2873 | src_vq->mem_ops = &vb2_dma_contig_memops; | |
ade48681 | 2874 | src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; |
152ea1c8 | 2875 | src_vq->lock = &ctx->dev->dev_mutex; |
186b250a JM |
2876 | |
2877 | ret = vb2_queue_init(src_vq); | |
2878 | if (ret) | |
2879 | return ret; | |
2880 | ||
186b250a | 2881 | dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
419869c8 | 2882 | dst_vq->io_modes = VB2_DMABUF | VB2_MMAP | VB2_USERPTR; |
186b250a JM |
2883 | dst_vq->drv_priv = ctx; |
2884 | dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); | |
2885 | dst_vq->ops = &coda_qops; | |
2886 | dst_vq->mem_ops = &vb2_dma_contig_memops; | |
ade48681 | 2887 | dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; |
152ea1c8 | 2888 | dst_vq->lock = &ctx->dev->dev_mutex; |
186b250a JM |
2889 | |
2890 | return vb2_queue_init(dst_vq); | |
2891 | } | |
2892 | ||
e11f3e6e PZ |
2893 | static int coda_next_free_instance(struct coda_dev *dev) |
2894 | { | |
0cddc7e9 PZ |
2895 | int idx = ffz(dev->instance_mask); |
2896 | ||
2897 | if ((idx < 0) || | |
2898 | (dev->devtype->product == CODA_DX6 && idx > CODADX6_MAX_INSTANCES)) | |
2899 | return -EBUSY; | |
2900 | ||
2901 | return idx; | |
e11f3e6e PZ |
2902 | } |
2903 | ||
186b250a JM |
2904 | static int coda_open(struct file *file) |
2905 | { | |
2906 | struct coda_dev *dev = video_drvdata(file); | |
2907 | struct coda_ctx *ctx = NULL; | |
f61c0b14 | 2908 | char *name; |
918c66fd | 2909 | int ret; |
e11f3e6e | 2910 | int idx; |
186b250a | 2911 | |
186b250a JM |
2912 | ctx = kzalloc(sizeof *ctx, GFP_KERNEL); |
2913 | if (!ctx) | |
2914 | return -ENOMEM; | |
2915 | ||
f82bc203 | 2916 | idx = coda_next_free_instance(dev); |
0cddc7e9 PZ |
2917 | if (idx < 0) { |
2918 | ret = idx; | |
f82bc203 FE |
2919 | goto err_coda_max; |
2920 | } | |
2921 | set_bit(idx, &dev->instance_mask); | |
2922 | ||
f61c0b14 PZ |
2923 | name = kasprintf(GFP_KERNEL, "context%d", idx); |
2924 | ctx->debugfs_entry = debugfs_create_dir(name, dev->debugfs_root); | |
2925 | kfree(name); | |
2926 | ||
32b6f206 PZ |
2927 | init_completion(&ctx->completion); |
2928 | INIT_WORK(&ctx->pic_run_work, coda_pic_run_work); | |
2929 | INIT_WORK(&ctx->seq_end_work, coda_seq_end_work); | |
186b250a JM |
2930 | v4l2_fh_init(&ctx->fh, video_devdata(file)); |
2931 | file->private_data = &ctx->fh; | |
2932 | v4l2_fh_add(&ctx->fh); | |
2933 | ctx->dev = dev; | |
e11f3e6e | 2934 | ctx->idx = idx; |
5677e3b0 PZ |
2935 | switch (dev->devtype->product) { |
2936 | case CODA_7541: | |
89548441 | 2937 | case CODA_960: |
5677e3b0 PZ |
2938 | ctx->reg_idx = 0; |
2939 | break; | |
2940 | default: | |
2941 | ctx->reg_idx = idx; | |
2942 | } | |
f82bc203 | 2943 | |
1e172731 PZ |
2944 | /* Power up and upload firmware if necessary */ |
2945 | ret = pm_runtime_get_sync(&dev->plat_dev->dev); | |
2946 | if (ret < 0) { | |
2947 | v4l2_err(&dev->v4l2_dev, "failed to power up: %d\n", ret); | |
2948 | goto err_pm_get; | |
2949 | } | |
2950 | ||
79830db2 FE |
2951 | ret = clk_prepare_enable(dev->clk_per); |
2952 | if (ret) | |
2953 | goto err_clk_per; | |
2954 | ||
2955 | ret = clk_prepare_enable(dev->clk_ahb); | |
2956 | if (ret) | |
2957 | goto err_clk_ahb; | |
2958 | ||
186b250a | 2959 | set_default_params(ctx); |
14604e3a | 2960 | ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, ctx, |
186b250a | 2961 | &coda_queue_init); |
14604e3a PZ |
2962 | if (IS_ERR(ctx->fh.m2m_ctx)) { |
2963 | ret = PTR_ERR(ctx->fh.m2m_ctx); | |
186b250a JM |
2964 | |
2965 | v4l2_err(&dev->v4l2_dev, "%s return error (%d)\n", | |
2966 | __func__, ret); | |
f82bc203 | 2967 | goto err_ctx_init; |
186b250a | 2968 | } |
152ea1c8 | 2969 | |
186b250a JM |
2970 | ret = coda_ctrls_setup(ctx); |
2971 | if (ret) { | |
2972 | v4l2_err(&dev->v4l2_dev, "failed to setup coda controls\n"); | |
f82bc203 | 2973 | goto err_ctrls_setup; |
186b250a JM |
2974 | } |
2975 | ||
2976 | ctx->fh.ctrl_handler = &ctx->ctrls; | |
2977 | ||
f61c0b14 PZ |
2978 | ret = coda_alloc_context_buf(ctx, &ctx->parabuf, CODA_PARA_BUF_SIZE, |
2979 | "parabuf"); | |
5677e3b0 | 2980 | if (ret < 0) { |
186b250a | 2981 | v4l2_err(&dev->v4l2_dev, "failed to allocate parabuf"); |
f82bc203 | 2982 | goto err_dma_alloc; |
186b250a JM |
2983 | } |
2984 | ||
9082a7c6 PZ |
2985 | ctx->bitstream.size = CODA_MAX_FRAME_SIZE; |
2986 | ctx->bitstream.vaddr = dma_alloc_writecombine(&dev->plat_dev->dev, | |
2987 | ctx->bitstream.size, &ctx->bitstream.paddr, GFP_KERNEL); | |
2988 | if (!ctx->bitstream.vaddr) { | |
2989 | v4l2_err(&dev->v4l2_dev, "failed to allocate bitstream ringbuffer"); | |
2990 | ret = -ENOMEM; | |
f82bc203 | 2991 | goto err_dma_writecombine; |
9082a7c6 PZ |
2992 | } |
2993 | kfifo_init(&ctx->bitstream_fifo, | |
2994 | ctx->bitstream.vaddr, ctx->bitstream.size); | |
2995 | mutex_init(&ctx->bitstream_mutex); | |
918c66fd | 2996 | mutex_init(&ctx->buffer_mutex); |
846ced9c | 2997 | INIT_LIST_HEAD(&ctx->timestamp_list); |
9082a7c6 | 2998 | |
186b250a | 2999 | coda_lock(ctx); |
e11f3e6e | 3000 | list_add(&ctx->list, &dev->instances); |
186b250a JM |
3001 | coda_unlock(ctx); |
3002 | ||
186b250a JM |
3003 | v4l2_dbg(1, coda_debug, &dev->v4l2_dev, "Created instance %d (%p)\n", |
3004 | ctx->idx, ctx); | |
3005 | ||
3006 | return 0; | |
3007 | ||
f82bc203 FE |
3008 | err_dma_writecombine: |
3009 | coda_free_context_buffers(ctx); | |
3010 | if (ctx->dev->devtype->product == CODA_DX6) | |
3011 | coda_free_aux_buf(dev, &ctx->workbuf); | |
3012 | coda_free_aux_buf(dev, &ctx->parabuf); | |
3013 | err_dma_alloc: | |
3014 | v4l2_ctrl_handler_free(&ctx->ctrls); | |
3015 | err_ctrls_setup: | |
14604e3a | 3016 | v4l2_m2m_ctx_release(ctx->fh.m2m_ctx); |
f82bc203 FE |
3017 | err_ctx_init: |
3018 | clk_disable_unprepare(dev->clk_ahb); | |
79830db2 | 3019 | err_clk_ahb: |
f82bc203 | 3020 | clk_disable_unprepare(dev->clk_per); |
79830db2 | 3021 | err_clk_per: |
1e172731 PZ |
3022 | pm_runtime_put_sync(&dev->plat_dev->dev); |
3023 | err_pm_get: | |
186b250a JM |
3024 | v4l2_fh_del(&ctx->fh); |
3025 | v4l2_fh_exit(&ctx->fh); | |
f82bc203 FE |
3026 | clear_bit(ctx->idx, &dev->instance_mask); |
3027 | err_coda_max: | |
186b250a JM |
3028 | kfree(ctx); |
3029 | return ret; | |
3030 | } | |
3031 | ||
3032 | static int coda_release(struct file *file) | |
3033 | { | |
3034 | struct coda_dev *dev = video_drvdata(file); | |
3035 | struct coda_ctx *ctx = fh_to_ctx(file->private_data); | |
3036 | ||
3037 | v4l2_dbg(1, coda_debug, &dev->v4l2_dev, "Releasing instance %p\n", | |
3038 | ctx); | |
3039 | ||
f61c0b14 PZ |
3040 | debugfs_remove_recursive(ctx->debugfs_entry); |
3041 | ||
918c66fd | 3042 | /* If this instance is running, call .job_abort and wait for it to end */ |
14604e3a | 3043 | v4l2_m2m_ctx_release(ctx->fh.m2m_ctx); |
918c66fd PZ |
3044 | |
3045 | /* In case the instance was not running, we still need to call SEQ_END */ | |
32b6f206 PZ |
3046 | if (ctx->initialized) { |
3047 | queue_work(dev->workqueue, &ctx->seq_end_work); | |
3048 | flush_work(&ctx->seq_end_work); | |
918c66fd | 3049 | } |
918c66fd PZ |
3050 | |
3051 | coda_free_framebuffers(ctx); | |
3052 | ||
186b250a | 3053 | coda_lock(ctx); |
e11f3e6e | 3054 | list_del(&ctx->list); |
186b250a JM |
3055 | coda_unlock(ctx); |
3056 | ||
9082a7c6 PZ |
3057 | dma_free_writecombine(&dev->plat_dev->dev, ctx->bitstream.size, |
3058 | ctx->bitstream.vaddr, ctx->bitstream.paddr); | |
5677e3b0 PZ |
3059 | coda_free_context_buffers(ctx); |
3060 | if (ctx->dev->devtype->product == CODA_DX6) | |
3061 | coda_free_aux_buf(dev, &ctx->workbuf); | |
3062 | ||
3063 | coda_free_aux_buf(dev, &ctx->parabuf); | |
186b250a | 3064 | v4l2_ctrl_handler_free(&ctx->ctrls); |
186b250a | 3065 | clk_disable_unprepare(dev->clk_ahb); |
f82bc203 | 3066 | clk_disable_unprepare(dev->clk_per); |
1e172731 | 3067 | pm_runtime_put_sync(&dev->plat_dev->dev); |
186b250a JM |
3068 | v4l2_fh_del(&ctx->fh); |
3069 | v4l2_fh_exit(&ctx->fh); | |
e11f3e6e | 3070 | clear_bit(ctx->idx, &dev->instance_mask); |
186b250a JM |
3071 | kfree(ctx); |
3072 | ||
3073 | return 0; | |
3074 | } | |
3075 | ||
186b250a JM |
3076 | static const struct v4l2_file_operations coda_fops = { |
3077 | .owner = THIS_MODULE, | |
3078 | .open = coda_open, | |
3079 | .release = coda_release, | |
152ea1c8 | 3080 | .poll = v4l2_m2m_fop_poll, |
186b250a | 3081 | .unlocked_ioctl = video_ioctl2, |
152ea1c8 | 3082 | .mmap = v4l2_m2m_fop_mmap, |
186b250a JM |
3083 | }; |
3084 | ||
918c66fd PZ |
3085 | static void coda_finish_decode(struct coda_ctx *ctx) |
3086 | { | |
3087 | struct coda_dev *dev = ctx->dev; | |
3088 | struct coda_q_data *q_data_src; | |
3089 | struct coda_q_data *q_data_dst; | |
3090 | struct vb2_buffer *dst_buf; | |
846ced9c | 3091 | struct coda_timestamp *ts; |
918c66fd PZ |
3092 | int width, height; |
3093 | int decoded_idx; | |
3094 | int display_idx; | |
3095 | u32 src_fourcc; | |
3096 | int success; | |
410e5e49 | 3097 | u32 err_mb; |
918c66fd PZ |
3098 | u32 val; |
3099 | ||
14604e3a | 3100 | dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); |
918c66fd PZ |
3101 | |
3102 | /* Update kfifo out pointer from coda bitstream read pointer */ | |
3103 | coda_kfifo_sync_from_device(ctx); | |
3104 | ||
3105 | /* | |
3106 | * in stream-end mode, the read pointer can overshoot the write pointer | |
3107 | * by up to 512 bytes | |
3108 | */ | |
3109 | if (ctx->bit_stream_param & CODA_BIT_STREAM_END_FLAG) { | |
3110 | if (coda_get_bitstream_payload(ctx) >= 0x100000 - 512) | |
3111 | kfifo_init(&ctx->bitstream_fifo, | |
3112 | ctx->bitstream.vaddr, ctx->bitstream.size); | |
3113 | } | |
3114 | ||
3115 | q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT); | |
3116 | src_fourcc = q_data_src->fourcc; | |
3117 | ||
3118 | val = coda_read(dev, CODA_RET_DEC_PIC_SUCCESS); | |
3119 | if (val != 1) | |
3120 | pr_err("DEC_PIC_SUCCESS = %d\n", val); | |
3121 | ||
3122 | success = val & 0x1; | |
3123 | if (!success) | |
3124 | v4l2_err(&dev->v4l2_dev, "decode failed\n"); | |
3125 | ||
3126 | if (src_fourcc == V4L2_PIX_FMT_H264) { | |
3127 | if (val & (1 << 3)) | |
3128 | v4l2_err(&dev->v4l2_dev, | |
3129 | "insufficient PS buffer space (%d bytes)\n", | |
3130 | ctx->psbuf.size); | |
3131 | if (val & (1 << 2)) | |
3132 | v4l2_err(&dev->v4l2_dev, | |
3133 | "insufficient slice buffer space (%d bytes)\n", | |
3134 | ctx->slicebuf.size); | |
3135 | } | |
3136 | ||
3137 | val = coda_read(dev, CODA_RET_DEC_PIC_SIZE); | |
3138 | width = (val >> 16) & 0xffff; | |
3139 | height = val & 0xffff; | |
3140 | ||
3141 | q_data_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE); | |
3142 | ||
52c41676 PZ |
3143 | /* frame crop information */ |
3144 | if (src_fourcc == V4L2_PIX_FMT_H264) { | |
3145 | u32 left_right; | |
3146 | u32 top_bottom; | |
3147 | ||
3148 | left_right = coda_read(dev, CODA_RET_DEC_PIC_CROP_LEFT_RIGHT); | |
3149 | top_bottom = coda_read(dev, CODA_RET_DEC_PIC_CROP_TOP_BOTTOM); | |
3150 | ||
3151 | if (left_right == 0xffffffff && top_bottom == 0xffffffff) { | |
3152 | /* Keep current crop information */ | |
3153 | } else { | |
3154 | struct v4l2_rect *rect = &q_data_dst->rect; | |
3155 | ||
3156 | rect->left = left_right >> 16 & 0xffff; | |
3157 | rect->top = top_bottom >> 16 & 0xffff; | |
3158 | rect->width = width - rect->left - | |
3159 | (left_right & 0xffff); | |
3160 | rect->height = height - rect->top - | |
3161 | (top_bottom & 0xffff); | |
3162 | } | |
3163 | } else { | |
3164 | /* no cropping */ | |
3165 | } | |
3166 | ||
410e5e49 PZ |
3167 | err_mb = coda_read(dev, CODA_RET_DEC_PIC_ERR_MB); |
3168 | if (err_mb > 0) | |
918c66fd | 3169 | v4l2_err(&dev->v4l2_dev, |
410e5e49 | 3170 | "errors in %d macroblocks\n", err_mb); |
918c66fd PZ |
3171 | |
3172 | if (dev->devtype->product == CODA_7541) { | |
3173 | val = coda_read(dev, CODA_RET_DEC_PIC_OPTION); | |
3174 | if (val == 0) { | |
3175 | /* not enough bitstream data */ | |
3176 | v4l2_dbg(1, coda_debug, &dev->v4l2_dev, | |
3177 | "prescan failed: %d\n", val); | |
84e2365d | 3178 | ctx->hold = true; |
918c66fd PZ |
3179 | return; |
3180 | } | |
3181 | } | |
3182 | ||
3183 | ctx->frm_dis_flg = coda_read(dev, CODA_REG_BIT_FRM_DIS_FLG(ctx->reg_idx)); | |
3184 | ||
3185 | /* | |
3186 | * The previous display frame was copied out by the rotator, | |
3187 | * now it can be overwritten again | |
3188 | */ | |
3189 | if (ctx->display_idx >= 0 && | |
3190 | ctx->display_idx < ctx->num_internal_frames) { | |
3191 | ctx->frm_dis_flg &= ~(1 << ctx->display_idx); | |
3192 | coda_write(dev, ctx->frm_dis_flg, | |
3193 | CODA_REG_BIT_FRM_DIS_FLG(ctx->reg_idx)); | |
3194 | } | |
3195 | ||
3196 | /* | |
3197 | * The index of the last decoded frame, not necessarily in | |
3198 | * display order, and the index of the next display frame. | |
3199 | * The latter could have been decoded in a previous run. | |
3200 | */ | |
3201 | decoded_idx = coda_read(dev, CODA_RET_DEC_PIC_CUR_IDX); | |
3202 | display_idx = coda_read(dev, CODA_RET_DEC_PIC_FRAME_IDX); | |
3203 | ||
3204 | if (decoded_idx == -1) { | |
3205 | /* no frame was decoded, but we might have a display frame */ | |
cb2c0282 PZ |
3206 | if (display_idx >= 0 && display_idx < ctx->num_internal_frames) |
3207 | ctx->sequence_offset++; | |
3208 | else if (ctx->display_idx < 0) | |
84e2365d | 3209 | ctx->hold = true; |
918c66fd PZ |
3210 | } else if (decoded_idx == -2) { |
3211 | /* no frame was decoded, we still return the remaining buffers */ | |
3212 | } else if (decoded_idx < 0 || decoded_idx >= ctx->num_internal_frames) { | |
3213 | v4l2_err(&dev->v4l2_dev, | |
3214 | "decoded frame index out of range: %d\n", decoded_idx); | |
1a8b3819 | 3215 | } else { |
846ced9c PZ |
3216 | ts = list_first_entry(&ctx->timestamp_list, |
3217 | struct coda_timestamp, list); | |
3218 | list_del(&ts->list); | |
3219 | val = coda_read(dev, CODA_RET_DEC_PIC_FRAME_NUM) - 1; | |
cb2c0282 PZ |
3220 | val -= ctx->sequence_offset; |
3221 | if (val != (ts->sequence & 0xffff)) { | |
846ced9c | 3222 | v4l2_err(&dev->v4l2_dev, |
cb2c0282 PZ |
3223 | "sequence number mismatch (%d(%d) != %d)\n", |
3224 | val, ctx->sequence_offset, ts->sequence); | |
846ced9c PZ |
3225 | } |
3226 | ctx->frame_timestamps[decoded_idx] = *ts; | |
3227 | kfree(ts); | |
3228 | ||
1a8b3819 PZ |
3229 | val = coda_read(dev, CODA_RET_DEC_PIC_TYPE) & 0x7; |
3230 | if (val == 0) | |
3231 | ctx->frame_types[decoded_idx] = V4L2_BUF_FLAG_KEYFRAME; | |
3232 | else if (val == 1) | |
3233 | ctx->frame_types[decoded_idx] = V4L2_BUF_FLAG_PFRAME; | |
3234 | else | |
3235 | ctx->frame_types[decoded_idx] = V4L2_BUF_FLAG_BFRAME; | |
410e5e49 PZ |
3236 | |
3237 | ctx->frame_errors[decoded_idx] = err_mb; | |
918c66fd PZ |
3238 | } |
3239 | ||
3240 | if (display_idx == -1) { | |
3241 | /* | |
3242 | * no more frames to be decoded, but there could still | |
3243 | * be rotator output to dequeue | |
3244 | */ | |
84e2365d | 3245 | ctx->hold = true; |
918c66fd PZ |
3246 | } else if (display_idx == -3) { |
3247 | /* possibly prescan failure */ | |
3248 | } else if (display_idx < 0 || display_idx >= ctx->num_internal_frames) { | |
3249 | v4l2_err(&dev->v4l2_dev, | |
3250 | "presentation frame index out of range: %d\n", | |
3251 | display_idx); | |
3252 | } | |
3253 | ||
3254 | /* If a frame was copied out, return it */ | |
3255 | if (ctx->display_idx >= 0 && | |
3256 | ctx->display_idx < ctx->num_internal_frames) { | |
14604e3a | 3257 | dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); |
918c66fd PZ |
3258 | dst_buf->v4l2_buf.sequence = ctx->osequence++; |
3259 | ||
1a8b3819 PZ |
3260 | dst_buf->v4l2_buf.flags &= ~(V4L2_BUF_FLAG_KEYFRAME | |
3261 | V4L2_BUF_FLAG_PFRAME | | |
3262 | V4L2_BUF_FLAG_BFRAME); | |
3263 | dst_buf->v4l2_buf.flags |= ctx->frame_types[ctx->display_idx]; | |
846ced9c PZ |
3264 | ts = &ctx->frame_timestamps[ctx->display_idx]; |
3265 | dst_buf->v4l2_buf.timecode = ts->timecode; | |
3266 | dst_buf->v4l2_buf.timestamp = ts->timestamp; | |
1a8b3819 | 3267 | |
918c66fd PZ |
3268 | vb2_set_plane_payload(dst_buf, 0, width * height * 3 / 2); |
3269 | ||
410e5e49 PZ |
3270 | v4l2_m2m_buf_done(dst_buf, ctx->frame_errors[display_idx] ? |
3271 | VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE); | |
918c66fd PZ |
3272 | |
3273 | v4l2_dbg(1, coda_debug, &dev->v4l2_dev, | |
3274 | "job finished: decoding frame (%d) (%s)\n", | |
3275 | dst_buf->v4l2_buf.sequence, | |
3276 | (dst_buf->v4l2_buf.flags & V4L2_BUF_FLAG_KEYFRAME) ? | |
3277 | "KEYFRAME" : "PFRAME"); | |
3278 | } else { | |
3279 | v4l2_dbg(1, coda_debug, &dev->v4l2_dev, | |
3280 | "job finished: no frame decoded\n"); | |
3281 | } | |
3282 | ||
3283 | /* The rotator will copy the current display frame next time */ | |
3284 | ctx->display_idx = display_idx; | |
3285 | } | |
3286 | ||
3287 | static void coda_finish_encode(struct coda_ctx *ctx) | |
186b250a | 3288 | { |
ec25f68d | 3289 | struct vb2_buffer *src_buf, *dst_buf; |
477c1cfe | 3290 | struct coda_dev *dev = ctx->dev; |
186b250a | 3291 | u32 wr_ptr, start_ptr; |
186b250a | 3292 | |
14604e3a PZ |
3293 | src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); |
3294 | dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); | |
186b250a JM |
3295 | |
3296 | /* Get results from the coda */ | |
186b250a | 3297 | start_ptr = coda_read(dev, CODA_CMD_ENC_PIC_BB_START); |
5677e3b0 PZ |
3298 | wr_ptr = coda_read(dev, CODA_REG_BIT_WR_PTR(ctx->reg_idx)); |
3299 | ||
186b250a JM |
3300 | /* Calculate bytesused field */ |
3301 | if (dst_buf->v4l2_buf.sequence == 0) { | |
366108f0 PZ |
3302 | vb2_set_plane_payload(dst_buf, 0, wr_ptr - start_ptr + |
3303 | ctx->vpu_header_size[0] + | |
3304 | ctx->vpu_header_size[1] + | |
3305 | ctx->vpu_header_size[2]); | |
186b250a | 3306 | } else { |
366108f0 | 3307 | vb2_set_plane_payload(dst_buf, 0, wr_ptr - start_ptr); |
186b250a JM |
3308 | } |
3309 | ||
3310 | v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev, "frame size = %u\n", | |
3311 | wr_ptr - start_ptr); | |
3312 | ||
3313 | coda_read(dev, CODA_RET_ENC_PIC_SLICE_NUM); | |
3314 | coda_read(dev, CODA_RET_ENC_PIC_FLAG); | |
3315 | ||
5166028d | 3316 | if (coda_read(dev, CODA_RET_ENC_PIC_TYPE) == 0) { |
186b250a JM |
3317 | dst_buf->v4l2_buf.flags |= V4L2_BUF_FLAG_KEYFRAME; |
3318 | dst_buf->v4l2_buf.flags &= ~V4L2_BUF_FLAG_PFRAME; | |
3319 | } else { | |
3320 | dst_buf->v4l2_buf.flags |= V4L2_BUF_FLAG_PFRAME; | |
3321 | dst_buf->v4l2_buf.flags &= ~V4L2_BUF_FLAG_KEYFRAME; | |
3322 | } | |
3323 | ||
ccd571cb | 3324 | dst_buf->v4l2_buf.timestamp = src_buf->v4l2_buf.timestamp; |
309f4d62 SA |
3325 | dst_buf->v4l2_buf.flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK; |
3326 | dst_buf->v4l2_buf.flags |= | |
3327 | src_buf->v4l2_buf.flags & V4L2_BUF_FLAG_TSTAMP_SRC_MASK; | |
ccd571cb KD |
3328 | dst_buf->v4l2_buf.timecode = src_buf->v4l2_buf.timecode; |
3329 | ||
ec25f68d | 3330 | v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE); |
89548441 | 3331 | |
14604e3a | 3332 | dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); |
186b250a JM |
3333 | v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_DONE); |
3334 | ||
3335 | ctx->gopcounter--; | |
3336 | if (ctx->gopcounter < 0) | |
3337 | ctx->gopcounter = ctx->params.gop_size - 1; | |
3338 | ||
3339 | v4l2_dbg(1, coda_debug, &dev->v4l2_dev, | |
3340 | "job finished: encoding frame (%d) (%s)\n", | |
3341 | dst_buf->v4l2_buf.sequence, | |
3342 | (dst_buf->v4l2_buf.flags & V4L2_BUF_FLAG_KEYFRAME) ? | |
3343 | "KEYFRAME" : "PFRAME"); | |
477c1cfe PZ |
3344 | } |
3345 | ||
3346 | static irqreturn_t coda_irq_handler(int irq, void *data) | |
3347 | { | |
3348 | struct coda_dev *dev = data; | |
3349 | struct coda_ctx *ctx; | |
3350 | ||
477c1cfe PZ |
3351 | /* read status register to attend the IRQ */ |
3352 | coda_read(dev, CODA_REG_BIT_INT_STATUS); | |
3353 | coda_write(dev, CODA_REG_BIT_INT_CLEAR_SET, | |
3354 | CODA_REG_BIT_INT_CLEAR); | |
3355 | ||
3356 | ctx = v4l2_m2m_get_curr_priv(dev->m2m_dev); | |
3357 | if (ctx == NULL) { | |
3358 | v4l2_err(&dev->v4l2_dev, "Instance released before the end of transaction\n"); | |
3359 | mutex_unlock(&dev->coda_mutex); | |
3360 | return IRQ_HANDLED; | |
3361 | } | |
3362 | ||
3363 | if (ctx->aborting) { | |
3364 | v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev, | |
3365 | "task has been aborted\n"); | |
477c1cfe PZ |
3366 | } |
3367 | ||
3368 | if (coda_isbusy(ctx->dev)) { | |
3369 | v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev, | |
3370 | "coda is still busy!!!!\n"); | |
3371 | return IRQ_NONE; | |
3372 | } | |
3373 | ||
32b6f206 | 3374 | complete(&ctx->completion); |
186b250a JM |
3375 | |
3376 | return IRQ_HANDLED; | |
3377 | } | |
3378 | ||
3379 | static u32 coda_supported_firmwares[] = { | |
3380 | CODA_FIRMWARE_VERNUM(CODA_DX6, 2, 2, 5), | |
5677e3b0 | 3381 | CODA_FIRMWARE_VERNUM(CODA_7541, 1, 4, 50), |
89548441 | 3382 | CODA_FIRMWARE_VERNUM(CODA_960, 2, 1, 5), |
186b250a JM |
3383 | }; |
3384 | ||
3385 | static bool coda_firmware_supported(u32 vernum) | |
3386 | { | |
3387 | int i; | |
3388 | ||
3389 | for (i = 0; i < ARRAY_SIZE(coda_supported_firmwares); i++) | |
3390 | if (vernum == coda_supported_firmwares[i]) | |
3391 | return true; | |
3392 | return false; | |
3393 | } | |
3394 | ||
87048bb4 | 3395 | static int coda_hw_init(struct coda_dev *dev) |
186b250a | 3396 | { |
186b250a JM |
3397 | u32 data; |
3398 | u16 *p; | |
79830db2 FE |
3399 | int i, ret; |
3400 | ||
3401 | ret = clk_prepare_enable(dev->clk_per); | |
3402 | if (ret) | |
1e172731 | 3403 | goto err_clk_per; |
186b250a | 3404 | |
79830db2 FE |
3405 | ret = clk_prepare_enable(dev->clk_ahb); |
3406 | if (ret) | |
3407 | goto err_clk_ahb; | |
186b250a | 3408 | |
8f45284c PZ |
3409 | if (dev->rstc) |
3410 | reset_control_reset(dev->rstc); | |
3411 | ||
186b250a JM |
3412 | /* |
3413 | * Copy the first CODA_ISRAM_SIZE in the internal SRAM. | |
87048bb4 PZ |
3414 | * The 16-bit chars in the code buffer are in memory access |
3415 | * order, re-sort them to CODA order for register download. | |
186b250a JM |
3416 | * Data in this SRAM survives a reboot. |
3417 | */ | |
87048bb4 PZ |
3418 | p = (u16 *)dev->codebuf.vaddr; |
3419 | if (dev->devtype->product == CODA_DX6) { | |
3420 | for (i = 0; i < (CODA_ISRAM_SIZE / 2); i++) { | |
3421 | data = CODA_DOWN_ADDRESS_SET(i) | | |
3422 | CODA_DOWN_DATA_SET(p[i ^ 1]); | |
3423 | coda_write(dev, data, CODA_REG_BIT_CODE_DOWN); | |
3424 | } | |
3425 | } else { | |
3426 | for (i = 0; i < (CODA_ISRAM_SIZE / 2); i++) { | |
3427 | data = CODA_DOWN_ADDRESS_SET(i) | | |
3428 | CODA_DOWN_DATA_SET(p[round_down(i, 4) + | |
3429 | 3 - (i % 4)]); | |
3430 | coda_write(dev, data, CODA_REG_BIT_CODE_DOWN); | |
3431 | } | |
186b250a | 3432 | } |
186b250a | 3433 | |
9acf7693 PZ |
3434 | /* Clear registers */ |
3435 | for (i = 0; i < 64; i++) | |
3436 | coda_write(dev, 0, CODA_REG_BIT_CODE_BUF_ADDR + i * 4); | |
3437 | ||
186b250a | 3438 | /* Tell the BIT where to find everything it needs */ |
89548441 PZ |
3439 | if (dev->devtype->product == CODA_960 || |
3440 | dev->devtype->product == CODA_7541) { | |
5677e3b0 PZ |
3441 | coda_write(dev, dev->tempbuf.paddr, |
3442 | CODA_REG_BIT_TEMP_BUF_ADDR); | |
918c66fd | 3443 | coda_write(dev, 0, CODA_REG_BIT_BIT_STREAM_PARAM); |
5677e3b0 PZ |
3444 | } else { |
3445 | coda_write(dev, dev->workbuf.paddr, | |
3446 | CODA_REG_BIT_WORK_BUF_ADDR); | |
3447 | } | |
186b250a JM |
3448 | coda_write(dev, dev->codebuf.paddr, |
3449 | CODA_REG_BIT_CODE_BUF_ADDR); | |
3450 | coda_write(dev, 0, CODA_REG_BIT_CODE_RUN); | |
3451 | ||
3452 | /* Set default values */ | |
3453 | switch (dev->devtype->product) { | |
3454 | case CODA_DX6: | |
3455 | coda_write(dev, CODADX6_STREAM_BUF_PIC_FLUSH, CODA_REG_BIT_STREAM_CTRL); | |
3456 | break; | |
3457 | default: | |
3458 | coda_write(dev, CODA7_STREAM_BUF_PIC_FLUSH, CODA_REG_BIT_STREAM_CTRL); | |
3459 | } | |
89548441 PZ |
3460 | if (dev->devtype->product == CODA_960) |
3461 | coda_write(dev, 1 << 12, CODA_REG_BIT_FRAME_MEM_CTRL); | |
3462 | else | |
3463 | coda_write(dev, 0, CODA_REG_BIT_FRAME_MEM_CTRL); | |
1043667b PZ |
3464 | |
3465 | if (dev->devtype->product != CODA_DX6) | |
3466 | coda_write(dev, 0, CODA7_REG_BIT_AXI_SRAM_USE); | |
3467 | ||
186b250a JM |
3468 | coda_write(dev, CODA_INT_INTERRUPT_ENABLE, |
3469 | CODA_REG_BIT_INT_ENABLE); | |
3470 | ||
3471 | /* Reset VPU and start processor */ | |
3472 | data = coda_read(dev, CODA_REG_BIT_CODE_RESET); | |
3473 | data |= CODA_REG_RESET_ENABLE; | |
3474 | coda_write(dev, data, CODA_REG_BIT_CODE_RESET); | |
3475 | udelay(10); | |
3476 | data &= ~CODA_REG_RESET_ENABLE; | |
3477 | coda_write(dev, data, CODA_REG_BIT_CODE_RESET); | |
3478 | coda_write(dev, CODA_REG_RUN_ENABLE, CODA_REG_BIT_CODE_RUN); | |
3479 | ||
fe7554e6 PZ |
3480 | clk_disable_unprepare(dev->clk_ahb); |
3481 | clk_disable_unprepare(dev->clk_per); | |
3482 | ||
3483 | return 0; | |
3484 | ||
3485 | err_clk_ahb: | |
3486 | clk_disable_unprepare(dev->clk_per); | |
3487 | err_clk_per: | |
3488 | return ret; | |
3489 | } | |
3490 | ||
3491 | static int coda_check_firmware(struct coda_dev *dev) | |
3492 | { | |
3493 | u16 product, major, minor, release; | |
3494 | u32 data; | |
3495 | int ret; | |
3496 | ||
3497 | ret = clk_prepare_enable(dev->clk_per); | |
3498 | if (ret) | |
3499 | goto err_clk_per; | |
3500 | ||
3501 | ret = clk_prepare_enable(dev->clk_ahb); | |
3502 | if (ret) | |
3503 | goto err_clk_ahb; | |
3504 | ||
186b250a JM |
3505 | coda_write(dev, 0, CODA_CMD_FIRMWARE_VERNUM); |
3506 | coda_write(dev, CODA_REG_BIT_BUSY_FLAG, CODA_REG_BIT_BUSY); | |
3507 | coda_write(dev, 0, CODA_REG_BIT_RUN_INDEX); | |
3508 | coda_write(dev, 0, CODA_REG_BIT_RUN_COD_STD); | |
3509 | coda_write(dev, CODA_COMMAND_FIRMWARE_GET, CODA_REG_BIT_RUN_COMMAND); | |
3510 | if (coda_wait_timeout(dev)) { | |
186b250a | 3511 | v4l2_err(&dev->v4l2_dev, "firmware get command error\n"); |
fe7554e6 PZ |
3512 | ret = -EIO; |
3513 | goto err_run_cmd; | |
186b250a JM |
3514 | } |
3515 | ||
89548441 PZ |
3516 | if (dev->devtype->product == CODA_960) { |
3517 | data = coda_read(dev, CODA9_CMD_FIRMWARE_CODE_REV); | |
3518 | v4l2_info(&dev->v4l2_dev, "Firmware code revision: %d\n", | |
3519 | data); | |
3520 | } | |
3521 | ||
186b250a JM |
3522 | /* Check we are compatible with the loaded firmware */ |
3523 | data = coda_read(dev, CODA_CMD_FIRMWARE_VERNUM); | |
3524 | product = CODA_FIRMWARE_PRODUCT(data); | |
3525 | major = CODA_FIRMWARE_MAJOR(data); | |
3526 | minor = CODA_FIRMWARE_MINOR(data); | |
3527 | release = CODA_FIRMWARE_RELEASE(data); | |
3528 | ||
3529 | clk_disable_unprepare(dev->clk_per); | |
3530 | clk_disable_unprepare(dev->clk_ahb); | |
3531 | ||
3532 | if (product != dev->devtype->product) { | |
3533 | v4l2_err(&dev->v4l2_dev, "Wrong firmware. Hw: %s, Fw: %s," | |
3534 | " Version: %u.%u.%u\n", | |
3535 | coda_product_name(dev->devtype->product), | |
3536 | coda_product_name(product), major, minor, release); | |
3537 | return -EINVAL; | |
3538 | } | |
3539 | ||
3540 | v4l2_info(&dev->v4l2_dev, "Initialized %s.\n", | |
3541 | coda_product_name(product)); | |
3542 | ||
3543 | if (coda_firmware_supported(data)) { | |
3544 | v4l2_info(&dev->v4l2_dev, "Firmware version: %u.%u.%u\n", | |
3545 | major, minor, release); | |
3546 | } else { | |
3547 | v4l2_warn(&dev->v4l2_dev, "Unsupported firmware version: " | |
3548 | "%u.%u.%u\n", major, minor, release); | |
3549 | } | |
3550 | ||
3551 | return 0; | |
79830db2 | 3552 | |
fe7554e6 PZ |
3553 | err_run_cmd: |
3554 | clk_disable_unprepare(dev->clk_ahb); | |
79830db2 FE |
3555 | err_clk_ahb: |
3556 | clk_disable_unprepare(dev->clk_per); | |
1e172731 | 3557 | err_clk_per: |
79830db2 | 3558 | return ret; |
186b250a JM |
3559 | } |
3560 | ||
3561 | static void coda_fw_callback(const struct firmware *fw, void *context) | |
3562 | { | |
3563 | struct coda_dev *dev = context; | |
3564 | struct platform_device *pdev = dev->plat_dev; | |
3565 | int ret; | |
3566 | ||
3567 | if (!fw) { | |
3568 | v4l2_err(&dev->v4l2_dev, "firmware request failed\n"); | |
3569 | return; | |
3570 | } | |
3571 | ||
3572 | /* allocate auxiliary per-device code buffer for the BIT processor */ | |
f61c0b14 PZ |
3573 | ret = coda_alloc_aux_buf(dev, &dev->codebuf, fw->size, "codebuf", |
3574 | dev->debugfs_root); | |
5677e3b0 | 3575 | if (ret < 0) { |
186b250a JM |
3576 | dev_err(&pdev->dev, "failed to allocate code buffer\n"); |
3577 | return; | |
3578 | } | |
3579 | ||
87048bb4 PZ |
3580 | /* Copy the whole firmware image to the code buffer */ |
3581 | memcpy(dev->codebuf.vaddr, fw->data, fw->size); | |
3582 | release_firmware(fw); | |
3583 | ||
1e172731 PZ |
3584 | if (pm_runtime_enabled(&pdev->dev) && pdev->dev.pm_domain) { |
3585 | /* | |
3586 | * Enabling power temporarily will cause coda_hw_init to be | |
3587 | * called via coda_runtime_resume by the pm domain. | |
3588 | */ | |
3589 | ret = pm_runtime_get_sync(&dev->plat_dev->dev); | |
3590 | if (ret < 0) { | |
3591 | v4l2_err(&dev->v4l2_dev, "failed to power on: %d\n", | |
3592 | ret); | |
3593 | return; | |
3594 | } | |
3595 | ||
fe7554e6 PZ |
3596 | ret = coda_check_firmware(dev); |
3597 | if (ret < 0) | |
3598 | return; | |
3599 | ||
1e172731 PZ |
3600 | pm_runtime_put_sync(&dev->plat_dev->dev); |
3601 | } else { | |
3602 | /* | |
3603 | * If runtime pm is disabled or pm_domain is not set, | |
3604 | * initialize once manually. | |
3605 | */ | |
3606 | ret = coda_hw_init(dev); | |
3607 | if (ret < 0) { | |
3608 | v4l2_err(&dev->v4l2_dev, "HW initialization failed\n"); | |
3609 | return; | |
3610 | } | |
fe7554e6 PZ |
3611 | |
3612 | ret = coda_check_firmware(dev); | |
3613 | if (ret < 0) | |
3614 | return; | |
186b250a JM |
3615 | } |
3616 | ||
3617 | dev->vfd.fops = &coda_fops, | |
3618 | dev->vfd.ioctl_ops = &coda_ioctl_ops; | |
3619 | dev->vfd.release = video_device_release_empty, | |
3620 | dev->vfd.lock = &dev->dev_mutex; | |
3621 | dev->vfd.v4l2_dev = &dev->v4l2_dev; | |
954f340f | 3622 | dev->vfd.vfl_dir = VFL_DIR_M2M; |
186b250a JM |
3623 | snprintf(dev->vfd.name, sizeof(dev->vfd.name), "%s", CODA_NAME); |
3624 | video_set_drvdata(&dev->vfd, dev); | |
3625 | ||
3626 | dev->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev); | |
3627 | if (IS_ERR(dev->alloc_ctx)) { | |
3628 | v4l2_err(&dev->v4l2_dev, "Failed to alloc vb2 context\n"); | |
3629 | return; | |
3630 | } | |
3631 | ||
3632 | dev->m2m_dev = v4l2_m2m_init(&coda_m2m_ops); | |
3633 | if (IS_ERR(dev->m2m_dev)) { | |
3634 | v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem device\n"); | |
3635 | goto rel_ctx; | |
3636 | } | |
3637 | ||
3638 | ret = video_register_device(&dev->vfd, VFL_TYPE_GRABBER, 0); | |
3639 | if (ret) { | |
3640 | v4l2_err(&dev->v4l2_dev, "Failed to register video device\n"); | |
3641 | goto rel_m2m; | |
3642 | } | |
3643 | v4l2_info(&dev->v4l2_dev, "codec registered as /dev/video%d\n", | |
3644 | dev->vfd.num); | |
3645 | ||
3646 | return; | |
3647 | ||
3648 | rel_m2m: | |
3649 | v4l2_m2m_release(dev->m2m_dev); | |
3650 | rel_ctx: | |
3651 | vb2_dma_contig_cleanup_ctx(dev->alloc_ctx); | |
3652 | } | |
3653 | ||
3654 | static int coda_firmware_request(struct coda_dev *dev) | |
3655 | { | |
3656 | char *fw = dev->devtype->firmware; | |
3657 | ||
3658 | dev_dbg(&dev->plat_dev->dev, "requesting firmware '%s' for %s\n", fw, | |
3659 | coda_product_name(dev->devtype->product)); | |
3660 | ||
3661 | return request_firmware_nowait(THIS_MODULE, true, | |
3662 | fw, &dev->plat_dev->dev, GFP_KERNEL, dev, coda_fw_callback); | |
3663 | } | |
3664 | ||
3665 | enum coda_platform { | |
3666 | CODA_IMX27, | |
df1e74cc | 3667 | CODA_IMX53, |
89548441 PZ |
3668 | CODA_IMX6Q, |
3669 | CODA_IMX6DL, | |
186b250a JM |
3670 | }; |
3671 | ||
c06d8752 | 3672 | static const struct coda_devtype coda_devdata[] = { |
186b250a | 3673 | [CODA_IMX27] = { |
e5b0d1c6 PZ |
3674 | .firmware = "v4l-codadx6-imx27.bin", |
3675 | .product = CODA_DX6, | |
3676 | .codecs = codadx6_codecs, | |
3677 | .num_codecs = ARRAY_SIZE(codadx6_codecs), | |
3678 | .workbuf_size = 288 * 1024 + FMO_SLICE_SAVE_BUF_SIZE * 8 * 1024, | |
401e972f | 3679 | .iram_size = 0xb000, |
186b250a | 3680 | }, |
df1e74cc | 3681 | [CODA_IMX53] = { |
e5b0d1c6 PZ |
3682 | .firmware = "v4l-coda7541-imx53.bin", |
3683 | .product = CODA_7541, | |
3684 | .codecs = coda7_codecs, | |
3685 | .num_codecs = ARRAY_SIZE(coda7_codecs), | |
3686 | .workbuf_size = 128 * 1024, | |
5d73fad1 | 3687 | .tempbuf_size = 304 * 1024, |
401e972f | 3688 | .iram_size = 0x14000, |
df1e74cc | 3689 | }, |
89548441 | 3690 | [CODA_IMX6Q] = { |
e5b0d1c6 PZ |
3691 | .firmware = "v4l-coda960-imx6q.bin", |
3692 | .product = CODA_960, | |
3693 | .codecs = coda9_codecs, | |
3694 | .num_codecs = ARRAY_SIZE(coda9_codecs), | |
3695 | .workbuf_size = 80 * 1024, | |
5d73fad1 | 3696 | .tempbuf_size = 204 * 1024, |
401e972f | 3697 | .iram_size = 0x21000, |
89548441 PZ |
3698 | }, |
3699 | [CODA_IMX6DL] = { | |
e5b0d1c6 PZ |
3700 | .firmware = "v4l-coda960-imx6dl.bin", |
3701 | .product = CODA_960, | |
3702 | .codecs = coda9_codecs, | |
3703 | .num_codecs = ARRAY_SIZE(coda9_codecs), | |
3704 | .workbuf_size = 80 * 1024, | |
5d73fad1 | 3705 | .tempbuf_size = 204 * 1024, |
401e972f | 3706 | .iram_size = 0x20000, |
89548441 | 3707 | }, |
186b250a JM |
3708 | }; |
3709 | ||
3710 | static struct platform_device_id coda_platform_ids[] = { | |
3711 | { .name = "coda-imx27", .driver_data = CODA_IMX27 }, | |
4e44cd08 | 3712 | { .name = "coda-imx53", .driver_data = CODA_IMX53 }, |
186b250a JM |
3713 | { /* sentinel */ } |
3714 | }; | |
3715 | MODULE_DEVICE_TABLE(platform, coda_platform_ids); | |
3716 | ||
3717 | #ifdef CONFIG_OF | |
3718 | static const struct of_device_id coda_dt_ids[] = { | |
7b0dd9e6 | 3719 | { .compatible = "fsl,imx27-vpu", .data = &coda_devdata[CODA_IMX27] }, |
df1e74cc | 3720 | { .compatible = "fsl,imx53-vpu", .data = &coda_devdata[CODA_IMX53] }, |
89548441 PZ |
3721 | { .compatible = "fsl,imx6q-vpu", .data = &coda_devdata[CODA_IMX6Q] }, |
3722 | { .compatible = "fsl,imx6dl-vpu", .data = &coda_devdata[CODA_IMX6DL] }, | |
186b250a JM |
3723 | { /* sentinel */ } |
3724 | }; | |
3725 | MODULE_DEVICE_TABLE(of, coda_dt_ids); | |
3726 | #endif | |
3727 | ||
4c62e976 | 3728 | static int coda_probe(struct platform_device *pdev) |
186b250a JM |
3729 | { |
3730 | const struct of_device_id *of_id = | |
3731 | of_match_device(of_match_ptr(coda_dt_ids), &pdev->dev); | |
3732 | const struct platform_device_id *pdev_id; | |
657eee7d PZ |
3733 | struct coda_platform_data *pdata = pdev->dev.platform_data; |
3734 | struct device_node *np = pdev->dev.of_node; | |
3735 | struct gen_pool *pool; | |
186b250a JM |
3736 | struct coda_dev *dev; |
3737 | struct resource *res; | |
3738 | int ret, irq; | |
3739 | ||
3740 | dev = devm_kzalloc(&pdev->dev, sizeof *dev, GFP_KERNEL); | |
3741 | if (!dev) { | |
3742 | dev_err(&pdev->dev, "Not enough memory for %s\n", | |
3743 | CODA_NAME); | |
3744 | return -ENOMEM; | |
3745 | } | |
3746 | ||
3747 | spin_lock_init(&dev->irqlock); | |
e11f3e6e | 3748 | INIT_LIST_HEAD(&dev->instances); |
186b250a JM |
3749 | |
3750 | dev->plat_dev = pdev; | |
3751 | dev->clk_per = devm_clk_get(&pdev->dev, "per"); | |
3752 | if (IS_ERR(dev->clk_per)) { | |
3753 | dev_err(&pdev->dev, "Could not get per clock\n"); | |
3754 | return PTR_ERR(dev->clk_per); | |
3755 | } | |
3756 | ||
3757 | dev->clk_ahb = devm_clk_get(&pdev->dev, "ahb"); | |
3758 | if (IS_ERR(dev->clk_ahb)) { | |
3759 | dev_err(&pdev->dev, "Could not get ahb clock\n"); | |
3760 | return PTR_ERR(dev->clk_ahb); | |
3761 | } | |
3762 | ||
3763 | /* Get memory for physical registers */ | |
3764 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
611cbbfe PZ |
3765 | dev->regs_base = devm_ioremap_resource(&pdev->dev, res); |
3766 | if (IS_ERR(dev->regs_base)) | |
3767 | return PTR_ERR(dev->regs_base); | |
186b250a JM |
3768 | |
3769 | /* IRQ */ | |
3770 | irq = platform_get_irq(pdev, 0); | |
3771 | if (irq < 0) { | |
3772 | dev_err(&pdev->dev, "failed to get irq resource\n"); | |
7d37743a | 3773 | return irq; |
186b250a JM |
3774 | } |
3775 | ||
08c8d14e FE |
3776 | ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, coda_irq_handler, |
3777 | IRQF_ONESHOT, dev_name(&pdev->dev), dev); | |
3778 | if (ret < 0) { | |
3779 | dev_err(&pdev->dev, "failed to request irq: %d\n", ret); | |
3780 | return ret; | |
186b250a JM |
3781 | } |
3782 | ||
ee27aa90 | 3783 | dev->rstc = devm_reset_control_get_optional(&pdev->dev, NULL); |
8f45284c PZ |
3784 | if (IS_ERR(dev->rstc)) { |
3785 | ret = PTR_ERR(dev->rstc); | |
ee27aa90 | 3786 | if (ret == -ENOENT || ret == -ENOSYS) { |
8f45284c PZ |
3787 | dev->rstc = NULL; |
3788 | } else { | |
3789 | dev_err(&pdev->dev, "failed get reset control: %d\n", ret); | |
3790 | return ret; | |
3791 | } | |
3792 | } | |
3793 | ||
657eee7d PZ |
3794 | /* Get IRAM pool from device tree or platform data */ |
3795 | pool = of_get_named_gen_pool(np, "iram", 0); | |
3796 | if (!pool && pdata) | |
3797 | pool = dev_get_gen_pool(pdata->iram_dev); | |
3798 | if (!pool) { | |
3799 | dev_err(&pdev->dev, "iram pool not available\n"); | |
3800 | return -ENOMEM; | |
3801 | } | |
3802 | dev->iram_pool = pool; | |
3803 | ||
186b250a JM |
3804 | ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev); |
3805 | if (ret) | |
3806 | return ret; | |
3807 | ||
3808 | mutex_init(&dev->dev_mutex); | |
fcb62825 | 3809 | mutex_init(&dev->coda_mutex); |
186b250a JM |
3810 | |
3811 | pdev_id = of_id ? of_id->data : platform_get_device_id(pdev); | |
3812 | ||
3813 | if (of_id) { | |
3814 | dev->devtype = of_id->data; | |
3815 | } else if (pdev_id) { | |
3816 | dev->devtype = &coda_devdata[pdev_id->driver_data]; | |
3817 | } else { | |
3818 | v4l2_device_unregister(&dev->v4l2_dev); | |
3819 | return -EINVAL; | |
3820 | } | |
3821 | ||
f61c0b14 PZ |
3822 | dev->debugfs_root = debugfs_create_dir("coda", NULL); |
3823 | if (!dev->debugfs_root) | |
3824 | dev_warn(&pdev->dev, "failed to create debugfs root\n"); | |
3825 | ||
186b250a | 3826 | /* allocate auxiliary per-device buffers for the BIT processor */ |
5d73fad1 | 3827 | if (dev->devtype->product == CODA_DX6) { |
5677e3b0 | 3828 | ret = coda_alloc_aux_buf(dev, &dev->workbuf, |
e5b0d1c6 | 3829 | dev->devtype->workbuf_size, "workbuf", |
f61c0b14 | 3830 | dev->debugfs_root); |
5677e3b0 PZ |
3831 | if (ret < 0) { |
3832 | dev_err(&pdev->dev, "failed to allocate work buffer\n"); | |
3833 | v4l2_device_unregister(&dev->v4l2_dev); | |
3834 | return ret; | |
3835 | } | |
186b250a | 3836 | } |
5d73fad1 PZ |
3837 | |
3838 | if (dev->devtype->tempbuf_size) { | |
5677e3b0 | 3839 | ret = coda_alloc_aux_buf(dev, &dev->tempbuf, |
5d73fad1 | 3840 | dev->devtype->tempbuf_size, "tempbuf", |
f61c0b14 | 3841 | dev->debugfs_root); |
5677e3b0 PZ |
3842 | if (ret < 0) { |
3843 | dev_err(&pdev->dev, "failed to allocate temp buffer\n"); | |
3844 | v4l2_device_unregister(&dev->v4l2_dev); | |
3845 | return ret; | |
3846 | } | |
186b250a JM |
3847 | } |
3848 | ||
401e972f | 3849 | dev->iram.size = dev->devtype->iram_size; |
b313bcc9 PZ |
3850 | dev->iram.vaddr = gen_pool_dma_alloc(dev->iram_pool, dev->iram.size, |
3851 | &dev->iram.paddr); | |
3852 | if (!dev->iram.vaddr) { | |
657eee7d PZ |
3853 | dev_err(&pdev->dev, "unable to alloc iram\n"); |
3854 | return -ENOMEM; | |
1043667b PZ |
3855 | } |
3856 | ||
f61c0b14 PZ |
3857 | dev->iram.blob.data = dev->iram.vaddr; |
3858 | dev->iram.blob.size = dev->iram.size; | |
3859 | dev->iram.dentry = debugfs_create_blob("iram", 0644, dev->debugfs_root, | |
3860 | &dev->iram.blob); | |
3861 | ||
32b6f206 PZ |
3862 | dev->workqueue = alloc_workqueue("coda", WQ_UNBOUND | WQ_MEM_RECLAIM, 1); |
3863 | if (!dev->workqueue) { | |
3864 | dev_err(&pdev->dev, "unable to alloc workqueue\n"); | |
3865 | return -ENOMEM; | |
3866 | } | |
3867 | ||
186b250a JM |
3868 | platform_set_drvdata(pdev, dev); |
3869 | ||
1e172731 PZ |
3870 | pm_runtime_enable(&pdev->dev); |
3871 | ||
186b250a JM |
3872 | return coda_firmware_request(dev); |
3873 | } | |
3874 | ||
3875 | static int coda_remove(struct platform_device *pdev) | |
3876 | { | |
3877 | struct coda_dev *dev = platform_get_drvdata(pdev); | |
3878 | ||
3879 | video_unregister_device(&dev->vfd); | |
3880 | if (dev->m2m_dev) | |
3881 | v4l2_m2m_release(dev->m2m_dev); | |
1e172731 | 3882 | pm_runtime_disable(&pdev->dev); |
186b250a JM |
3883 | if (dev->alloc_ctx) |
3884 | vb2_dma_contig_cleanup_ctx(dev->alloc_ctx); | |
3885 | v4l2_device_unregister(&dev->v4l2_dev); | |
32b6f206 | 3886 | destroy_workqueue(dev->workqueue); |
b313bcc9 PZ |
3887 | if (dev->iram.vaddr) |
3888 | gen_pool_free(dev->iram_pool, (unsigned long)dev->iram.vaddr, | |
3889 | dev->iram.size); | |
5677e3b0 PZ |
3890 | coda_free_aux_buf(dev, &dev->codebuf); |
3891 | coda_free_aux_buf(dev, &dev->tempbuf); | |
3892 | coda_free_aux_buf(dev, &dev->workbuf); | |
f61c0b14 | 3893 | debugfs_remove_recursive(dev->debugfs_root); |
186b250a JM |
3894 | return 0; |
3895 | } | |
3896 | ||
1e172731 PZ |
3897 | #ifdef CONFIG_PM_RUNTIME |
3898 | static int coda_runtime_resume(struct device *dev) | |
3899 | { | |
3900 | struct coda_dev *cdev = dev_get_drvdata(dev); | |
3901 | int ret = 0; | |
3902 | ||
3903 | if (dev->pm_domain) { | |
3904 | ret = coda_hw_init(cdev); | |
3905 | if (ret) | |
3906 | v4l2_err(&cdev->v4l2_dev, "HW initialization failed\n"); | |
3907 | } | |
3908 | ||
3909 | return ret; | |
3910 | } | |
3911 | #endif | |
3912 | ||
3913 | static const struct dev_pm_ops coda_pm_ops = { | |
3914 | SET_RUNTIME_PM_OPS(NULL, coda_runtime_resume, NULL) | |
3915 | }; | |
3916 | ||
186b250a JM |
3917 | static struct platform_driver coda_driver = { |
3918 | .probe = coda_probe, | |
4c62e976 | 3919 | .remove = coda_remove, |
186b250a JM |
3920 | .driver = { |
3921 | .name = CODA_NAME, | |
3922 | .owner = THIS_MODULE, | |
3923 | .of_match_table = of_match_ptr(coda_dt_ids), | |
1e172731 | 3924 | .pm = &coda_pm_ops, |
186b250a JM |
3925 | }, |
3926 | .id_table = coda_platform_ids, | |
3927 | }; | |
3928 | ||
3929 | module_platform_driver(coda_driver); | |
3930 | ||
3931 | MODULE_LICENSE("GPL"); | |
3932 | MODULE_AUTHOR("Javier Martin <javier.martin@vista-silicon.com>"); | |
3933 | MODULE_DESCRIPTION("Coda multi-standard codec V4L2 driver"); |