FILE
rcar_jpu.c
File preview with syntax highlighting.
linux-6.19.14/drivers/media/platform/renesas/rcar_jpu.c
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Author: Mikhail Ulyanov 4 * Copyright (C) 2014-2015 Cogent Embedded, Inc. <source@cogentembedded.com> 5 * Copyright (C) 2014-2015 Renesas Electronics Corporation 6 * 7 * This is based on the drivers/media/platform/samsung/s5p-jpeg driver by 8 * Andrzej Pietrasiewicz and Jacek Anaszewski. 9 * Some portions of code inspired by VSP1 driver by Laurent Pinchart. 10 * 11 * TODO in order of priority: 12 * 1) Rotation 13 * 2) Cropping 14 * 3) V4L2_CID_JPEG_ACTIVE_MARKER 15 */ 16 17#include <linux/unaligned.h> 18#include <linux/clk.h> 19#include <linux/err.h> 20#include <linux/interrupt.h> 21#include <linux/io.h> 22#include <linux/kernel.h> 23#include <linux/module.h> 24#include <linux/of.h> 25#include <linux/platform_device.h> 26#include <linux/slab.h> 27#include <linux/spinlock.h> 28#include <linux/string.h> 29#include <linux/videodev2.h> 30#include <media/jpeg.h> 31#include <media/v4l2-ctrls.h> 32#include <media/v4l2-device.h> 33#include <media/v4l2-event.h> 34#include <media/v4l2-fh.h> 35#include <media/v4l2-mem2mem.h> 36#include <media/v4l2-ioctl.h> 37#include <media/videobuf2-v4l2.h> 38#include <media/videobuf2-dma-contig.h> 39 40 41#define DRV_NAME "rcar_jpu" 42 43/* 44 * Align JPEG header end to cache line to make sure we will not have any issues 45 * with cache; additionally to requirement (33.3.27 R01UH0501EJ0100 Rev.1.00) 46 */ 47#define JPU_JPEG_HDR_SIZE (ALIGN(0x258, L1_CACHE_BYTES)) 48#define JPU_JPEG_MAX_BYTES_PER_PIXEL 2 /* 16 bit precision format */ 49#define JPU_JPEG_MIN_SIZE 25 /* SOI + SOF + EOI */ 50#define JPU_JPEG_QTBL_SIZE 0x40 51#define JPU_JPEG_HDCTBL_SIZE 0x1c 52#define JPU_JPEG_HACTBL_SIZE 0xb2 53#define JPU_JPEG_HEIGHT_OFFSET 0x91 54#define JPU_JPEG_WIDTH_OFFSET 0x93 55#define JPU_JPEG_SUBS_OFFSET 0x97 56#define JPU_JPEG_QTBL_LUM_OFFSET 0x07 57#define JPU_JPEG_QTBL_CHR_OFFSET 0x4c 58#define JPU_JPEG_HDCTBL_LUM_OFFSET 0xa4 59#define JPU_JPEG_HACTBL_LUM_OFFSET 0xc5 60#define JPU_JPEG_HDCTBL_CHR_OFFSET 0x17c 61#define JPU_JPEG_HACTBL_CHR_OFFSET 0x19d 62#define JPU_JPEG_PADDING_OFFSET 0x24f 63#define JPU_JPEG_LUM 0x00 64#define JPU_JPEG_CHR 0x01 65#define JPU_JPEG_DC 0x00 66#define JPU_JPEG_AC 0x10 67 68#define JPU_JPEG_422 0x21 69#define JPU_JPEG_420 0x22 70 71#define JPU_JPEG_DEFAULT_422_PIX_FMT V4L2_PIX_FMT_NV16M 72#define JPU_JPEG_DEFAULT_420_PIX_FMT V4L2_PIX_FMT_NV12M 73 74#define JPU_RESET_TIMEOUT 100 /* ms */ 75#define JPU_JOB_TIMEOUT 300 /* ms */ 76#define JPU_MAX_QUALITY 4 77#define JPU_WIDTH_MIN 16 78#define JPU_HEIGHT_MIN 16 79#define JPU_WIDTH_MAX 4096 80#define JPU_HEIGHT_MAX 4096 81#define JPU_MEMALIGN 8 82 83/* Flags that indicate a format can be used for capture/output */ 84#define JPU_FMT_TYPE_OUTPUT 0 85#define JPU_FMT_TYPE_CAPTURE 1 86#define JPU_ENC_CAPTURE (1 << 0) 87#define JPU_ENC_OUTPUT (1 << 1) 88#define JPU_DEC_CAPTURE (1 << 2) 89#define JPU_DEC_OUTPUT (1 << 3) 90 91/* 92 * JPEG registers and bits 93 */ 94 95/* JPEG code mode register */ 96#define JCMOD 0x00 97#define JCMOD_PCTR (1 << 7) 98#define JCMOD_MSKIP_ENABLE (1 << 5) 99#define JCMOD_DSP_ENC (0 << 3) 100#define JCMOD_DSP_DEC (1 << 3) 101#define JCMOD_REDU (7 << 0) 102#define JCMOD_REDU_422 (1 << 0) 103#define JCMOD_REDU_420 (2 << 0) 104 105/* JPEG code command register */ 106#define JCCMD 0x04 107#define JCCMD_SRST (1 << 12) 108#define JCCMD_JEND (1 << 2) 109#define JCCMD_JSRT (1 << 0) 110 111/* JPEG code quantization table number register */ 112#define JCQTN 0x0c 113#define JCQTN_SHIFT(t) (((t) - 1) << 1) 114 115/* JPEG code Huffman table number register */ 116#define JCHTN 0x10 117#define JCHTN_AC_SHIFT(t) (((t) << 1) - 1) 118#define JCHTN_DC_SHIFT(t) (((t) - 1) << 1) 119 120#define JCVSZU 0x1c /* JPEG code vertical size upper register */ 121#define JCVSZD 0x20 /* JPEG code vertical size lower register */ 122#define JCHSZU 0x24 /* JPEG code horizontal size upper register */ 123#define JCHSZD 0x28 /* JPEG code horizontal size lower register */ 124#define JCSZ_MASK 0xff /* JPEG code h/v size register contains only 1 byte*/ 125 126#define JCDTCU 0x2c /* JPEG code data count upper register */ 127#define JCDTCM 0x30 /* JPEG code data count middle register */ 128#define JCDTCD 0x34 /* JPEG code data count lower register */ 129 130/* JPEG interrupt enable register */ 131#define JINTE 0x38 132#define JINTE_ERR (7 << 5) /* INT5 + INT6 + INT7 */ 133#define JINTE_TRANSF_COMPL (1 << 10) 134 135/* JPEG interrupt status register */ 136#define JINTS 0x3c 137#define JINTS_MASK 0x7c68 138#define JINTS_ERR (1 << 5) 139#define JINTS_PROCESS_COMPL (1 << 6) 140#define JINTS_TRANSF_COMPL (1 << 10) 141 142#define JCDERR 0x40 /* JPEG code decode error register */ 143#define JCDERR_MASK 0xf /* JPEG code decode error register mask*/ 144 145/* JPEG interface encoding */ 146#define JIFECNT 0x70 147#define JIFECNT_INFT_422 0 148#define JIFECNT_INFT_420 1 149#define JIFECNT_SWAP_WB (3 << 4) /* to JPU */ 150 151#define JIFESYA1 0x74 /* encode source Y address register 1 */ 152#define JIFESCA1 0x78 /* encode source C address register 1 */ 153#define JIFESYA2 0x7c /* encode source Y address register 2 */ 154#define JIFESCA2 0x80 /* encode source C address register 2 */ 155#define JIFESMW 0x84 /* encode source memory width register */ 156#define JIFESVSZ 0x88 /* encode source vertical size register */ 157#define JIFESHSZ 0x8c /* encode source horizontal size register */ 158#define JIFEDA1 0x90 /* encode destination address register 1 */ 159#define JIFEDA2 0x94 /* encode destination address register 2 */ 160 161/* JPEG decoding control register */ 162#define JIFDCNT 0xa0 163#define JIFDCNT_SWAP_WB (3 << 1) /* from JPU */ 164 165#define JIFDSA1 0xa4 /* decode source address register 1 */ 166#define JIFDDMW 0xb0 /* decode destination memory width register */ 167#define JIFDDVSZ 0xb4 /* decode destination vert. size register */ 168#define JIFDDHSZ 0xb8 /* decode destination horiz. size register */ 169#define JIFDDYA1 0xbc /* decode destination Y address register 1 */ 170#define JIFDDCA1 0xc0 /* decode destination C address register 1 */ 171 172#define JCQTBL(n) (0x10000 + (n) * 0x40) /* quantization tables regs */ 173#define JCHTBD(n) (0x10100 + (n) * 0x100) /* Huffman table DC regs */ 174#define JCHTBA(n) (0x10120 + (n) * 0x100) /* Huffman table AC regs */ 175 176/** 177 * struct jpu - JPEG IP abstraction 178 * @mutex: the mutex protecting this structure 179 * @lock: spinlock protecting the device contexts 180 * @v4l2_dev: v4l2 device for mem2mem mode 181 * @vfd_encoder: video device node for encoder mem2mem mode 182 * @vfd_decoder: video device node for decoder mem2mem mode 183 * @m2m_dev: v4l2 mem2mem device data 184 * @curr: pointer to current context 185 * @regs: JPEG IP registers mapping 186 * @irq: JPEG IP irq 187 * @clk: JPEG IP clock 188 * @dev: JPEG IP struct device 189 * @ref_count: reference counter 190 */ 191struct jpu { 192 struct mutex mutex; 193 spinlock_t lock; 194 struct v4l2_device v4l2_dev; 195 struct video_device vfd_encoder; 196 struct video_device vfd_decoder; 197 struct v4l2_m2m_dev *m2m_dev; 198 struct jpu_ctx *curr; 199 200 void __iomem *regs; 201 unsigned int irq; 202 struct clk *clk; 203 struct device *dev; 204 int ref_count; 205}; 206 207/** 208 * struct jpu_buffer - driver's specific video buffer 209 * @buf: m2m buffer 210 * @compr_quality: destination image quality in compression mode 211 * @subsampling: source image subsampling in decompression mode 212 */ 213struct jpu_buffer { 214 struct v4l2_m2m_buffer buf; 215 unsigned short compr_quality; 216 unsigned char subsampling; 217}; 218 219/** 220 * struct jpu_fmt - driver's internal format data 221 * @fourcc: the fourcc code, 0 if not applicable 222 * @colorspace: the colorspace specifier 223 * @bpp: number of bits per pixel per plane 224 * @h_align: horizontal alignment order (align to 2^h_align) 225 * @v_align: vertical alignment order (align to 2^v_align) 226 * @subsampling: (horizontal:4 | vertical:4) subsampling factor 227 * @num_planes: number of planes 228 * @types: types of queue this format is applicable to 229 */ 230struct jpu_fmt { 231 u32 fourcc; 232 u32 colorspace; 233 u8 bpp[2]; 234 u8 h_align; 235 u8 v_align; 236 u8 subsampling; 237 u8 num_planes; 238 u16 types; 239}; 240 241/** 242 * struct jpu_q_data - parameters of one queue 243 * @fmtinfo: driver-specific format of this queue 244 * @format: multiplanar format of this queue 245 * @sequence: sequence number 246 */ 247struct jpu_q_data { 248 struct jpu_fmt *fmtinfo; 249 struct v4l2_pix_format_mplane format; 250 unsigned int sequence; 251}; 252 253/** 254 * struct jpu_ctx - the device context data 255 * @jpu: JPEG IP device for this context 256 * @encoder: compression (encode) operation or decompression (decode) 257 * @compr_quality: destination image quality in compression (encode) mode 258 * @out_q: source (output) queue information 259 * @cap_q: destination (capture) queue information 260 * @fh: file handler 261 * @ctrl_handler: controls handler 262 */ 263struct jpu_ctx { 264 struct jpu *jpu; 265 bool encoder; 266 unsigned short compr_quality; 267 struct jpu_q_data out_q; 268 struct jpu_q_data cap_q; 269 struct v4l2_fh fh; 270 struct v4l2_ctrl_handler ctrl_handler; 271}; 272 273 /** 274 * jpeg_buffer - description of memory containing input JPEG data 275 * @end: end position in the buffer 276 * @curr: current position in the buffer 277 */ 278struct jpeg_buffer { 279 void *end; 280 void *curr; 281}; 282 283static struct jpu_fmt jpu_formats[] = { 284 { V4L2_PIX_FMT_JPEG, V4L2_COLORSPACE_JPEG, 285 {0, 0}, 0, 0, 0, 1, JPU_ENC_CAPTURE | JPU_DEC_OUTPUT }, 286 { V4L2_PIX_FMT_NV16M, V4L2_COLORSPACE_SRGB, 287 {8, 8}, 2, 2, JPU_JPEG_422, 2, JPU_ENC_OUTPUT | JPU_DEC_CAPTURE }, 288 { V4L2_PIX_FMT_NV12M, V4L2_COLORSPACE_SRGB, 289 {8, 4}, 2, 2, JPU_JPEG_420, 2, JPU_ENC_OUTPUT | JPU_DEC_CAPTURE }, 290 { V4L2_PIX_FMT_NV16, V4L2_COLORSPACE_SRGB, 291 {16, 0}, 2, 2, JPU_JPEG_422, 1, JPU_ENC_OUTPUT | JPU_DEC_CAPTURE }, 292 { V4L2_PIX_FMT_NV12, V4L2_COLORSPACE_SRGB, 293 {12, 0}, 2, 2, JPU_JPEG_420, 1, JPU_ENC_OUTPUT | JPU_DEC_CAPTURE }, 294}; 295 296static const u8 zigzag[] = { 297 0x03, 0x02, 0x0b, 0x13, 0x0a, 0x01, 0x00, 0x09, 298 0x12, 0x1b, 0x23, 0x1a, 0x11, 0x08, 0x07, 0x06, 299 0x0f, 0x10, 0x19, 0x22, 0x2b, 0x33, 0x2a, 0x21, 300 0x18, 0x17, 0x0e, 0x05, 0x04, 0x0d, 0x16, 0x1f, 301 0x20, 0x29, 0x32, 0x3b, 0x3a, 0x31, 0x28, 0x27, 302 0x1e, 0x15, 0x0e, 0x14, 0x10, 0x26, 0x2f, 0x30, 303 0x39, 0x38, 0x37, 0x2e, 0x25, 0x1c, 0x24, 0x2b, 304 0x36, 0x3f, 0x3e, 0x35, 0x2c, 0x34, 0x3d, 0x3c 305}; 306 307#define QTBL_SIZE (ALIGN(JPU_JPEG_QTBL_SIZE, \ 308 sizeof(unsigned int)) / sizeof(unsigned int)) 309#define HDCTBL_SIZE (ALIGN(JPU_JPEG_HDCTBL_SIZE, \ 310 sizeof(unsigned int)) / sizeof(unsigned int)) 311#define HACTBL_SIZE (ALIGN(JPU_JPEG_HACTBL_SIZE, \ 312 sizeof(unsigned int)) / sizeof(unsigned int)) 313/* 314 * Start of image; Quantization tables 315 * SOF0 (17 bytes payload) is Baseline DCT - Sample precision, height, width, 316 * Number of image components, (Ci:8 - Hi:4 - Vi:4 - Tq:8) * 3 - Y,Cb,Cr; 317 * Huffman tables; Padding with 0xff (33.3.27 R01UH0501EJ0100 Rev.1.00) 318 */ 319#define JPU_JPEG_HDR_BLOB { \ 320 0xff, JPEG_MARKER_SOI, 0xff, JPEG_MARKER_DQT, 0x00, \ 321 JPU_JPEG_QTBL_SIZE + 0x3, JPU_JPEG_LUM, \ 322 [JPU_JPEG_QTBL_LUM_OFFSET ... \ 323 JPU_JPEG_QTBL_LUM_OFFSET + JPU_JPEG_QTBL_SIZE - 1] = 0x00, \ 324 0xff, JPEG_MARKER_DQT, 0x00, JPU_JPEG_QTBL_SIZE + 0x3, JPU_JPEG_CHR, \ 325 [JPU_JPEG_QTBL_CHR_OFFSET ... JPU_JPEG_QTBL_CHR_OFFSET + \ 326 JPU_JPEG_QTBL_SIZE - 1] = 0x00, \ 327 0xff, JPEG_MARKER_SOF0, 0x00, 0x11, 0x08, \ 328 [JPU_JPEG_HEIGHT_OFFSET ... JPU_JPEG_HEIGHT_OFFSET + 1] = 0x00, \ 329 [JPU_JPEG_WIDTH_OFFSET ... JPU_JPEG_WIDTH_OFFSET + 1] = 0x00, \ 330 0x03, 0x01, [JPU_JPEG_SUBS_OFFSET] = 0x00, JPU_JPEG_LUM, \ 331 0x02, 0x11, JPU_JPEG_CHR, 0x03, 0x11, JPU_JPEG_CHR, \ 332 0xff, JPEG_MARKER_DHT, 0x00, JPU_JPEG_HDCTBL_SIZE + 0x3, \ 333 JPU_JPEG_LUM | JPU_JPEG_DC, \ 334 [JPU_JPEG_HDCTBL_LUM_OFFSET ... \ 335 JPU_JPEG_HDCTBL_LUM_OFFSET + JPU_JPEG_HDCTBL_SIZE - 1] = 0x00, \ 336 0xff, JPEG_MARKER_DHT, 0x00, JPU_JPEG_HACTBL_SIZE + 0x3, \ 337 JPU_JPEG_LUM | JPU_JPEG_AC, \ 338 [JPU_JPEG_HACTBL_LUM_OFFSET ... \ 339 JPU_JPEG_HACTBL_LUM_OFFSET + JPU_JPEG_HACTBL_SIZE - 1] = 0x00, \ 340 0xff, JPEG_MARKER_DHT, 0x00, JPU_JPEG_HDCTBL_SIZE + 0x3, \ 341 JPU_JPEG_CHR | JPU_JPEG_DC, \ 342 [JPU_JPEG_HDCTBL_CHR_OFFSET ... \ 343 JPU_JPEG_HDCTBL_CHR_OFFSET + JPU_JPEG_HDCTBL_SIZE - 1] = 0x00, \ 344 0xff, JPEG_MARKER_DHT, 0x00, JPU_JPEG_HACTBL_SIZE + 0x3, \ 345 JPU_JPEG_CHR | JPU_JPEG_AC, \ 346 [JPU_JPEG_HACTBL_CHR_OFFSET ... \ 347 JPU_JPEG_HACTBL_CHR_OFFSET + JPU_JPEG_HACTBL_SIZE - 1] = 0x00, \ 348 [JPU_JPEG_PADDING_OFFSET ... JPU_JPEG_HDR_SIZE - 1] = 0xff \ 349} 350 351static unsigned char jpeg_hdrs[JPU_MAX_QUALITY][JPU_JPEG_HDR_SIZE] = { 352 [0 ... JPU_MAX_QUALITY - 1] = JPU_JPEG_HDR_BLOB 353}; 354 355static const unsigned int qtbl_lum[JPU_MAX_QUALITY][QTBL_SIZE] = { 356 { 357 0x14101927, 0x322e3e44, 0x10121726, 0x26354144, 358 0x19171f26, 0x35414444, 0x27262635, 0x41444444, 359 0x32263541, 0x44444444, 0x2e354144, 0x44444444, 360 0x3e414444, 0x44444444, 0x44444444, 0x44444444 361 }, 362 { 363 0x100b0b10, 0x171b1f1e, 0x0b0c0c0f, 0x1417171e, 364 0x0b0c0d10, 0x171a232f, 0x100f1017, 0x1a252f40, 365 0x1714171a, 0x27334040, 0x1b171a25, 0x33404040, 366 0x1f17232f, 0x40404040, 0x1e1e2f40, 0x40404040 367 }, 368 { 369 0x0c08080c, 0x11151817, 0x0809090b, 0x0f131217, 370 0x08090a0c, 0x13141b24, 0x0c0b0c15, 0x141c2435, 371 0x110f1314, 0x1e27333b, 0x1513141c, 0x27333b3b, 372 0x18121b24, 0x333b3b3b, 0x17172435, 0x3b3b3b3b 373 }, 374 { 375 0x08060608, 0x0c0e1011, 0x06060608, 0x0a0d0c0f, 376 0x06060708, 0x0d0e1218, 0x0808080e, 0x0d131823, 377 0x0c0a0d0d, 0x141a2227, 0x0e0d0e13, 0x1a222727, 378 0x100c1318, 0x22272727, 0x110f1823, 0x27272727 379 } 380}; 381 382static const unsigned int qtbl_chr[JPU_MAX_QUALITY][QTBL_SIZE] = { 383 { 384 0x15192026, 0x36444444, 0x191c1826, 0x36444444, 385 0x2018202b, 0x42444444, 0x26262b35, 0x44444444, 386 0x36424444, 0x44444444, 0x44444444, 0x44444444, 387 0x44444444, 0x44444444, 0x44444444, 0x44444444 388 }, 389 { 390 0x110f1115, 0x141a2630, 0x0f131211, 0x141a232b, 391 0x11121416, 0x1a1e2e35, 0x1511161c, 0x1e273540, 392 0x14141a1e, 0x27304040, 0x1a1a1e27, 0x303f4040, 393 0x26232e35, 0x40404040, 0x302b3540, 0x40404040 394 }, 395 { 396 0x0d0b0d10, 0x14141d25, 0x0b0e0e0e, 0x10141a20, 397 0x0d0e0f11, 0x14172328, 0x100e1115, 0x171e2832, 398 0x14101417, 0x1e25323b, 0x1414171e, 0x25303b3b, 399 0x1d1a2328, 0x323b3b3b, 0x25202832, 0x3b3b3b3b 400 }, 401 { 402 0x0908090b, 0x0e111318, 0x080a090b, 0x0e0d1116, 403 0x09090d0e, 0x0d0f171a, 0x0b0b0e0e, 0x0f141a21, 404 0x0e0e0d0f, 0x14182127, 0x110d0f14, 0x18202727, 405 0x1311171a, 0x21272727, 0x18161a21, 0x27272727 406 } 407}; 408 409static const unsigned int hdctbl_lum[HDCTBL_SIZE] = { 410 0x00010501, 0x01010101, 0x01000000, 0x00000000, 411 0x00010203, 0x04050607, 0x08090a0b 412}; 413 414static const unsigned int hdctbl_chr[HDCTBL_SIZE] = { 415 0x00010501, 0x01010101, 0x01000000, 0x00000000, 416 0x00010203, 0x04050607, 0x08090a0b 417}; 418 419static const unsigned int hactbl_lum[HACTBL_SIZE] = { 420 0x00020103, 0x03020403, 0x05050404, 0x0000017d, 0x01020300, 0x04110512, 421 0x21314106, 0x13516107, 0x22711432, 0x8191a108, 0x2342b1c1, 0x1552d1f0, 422 0x24336272, 0x82090a16, 0x1718191a, 0x25262728, 0x292a3435, 0x36373839, 423 0x3a434445, 0x46474849, 0x4a535455, 0x56575859, 0x5a636465, 0x66676869, 424 0x6a737475, 0x76777879, 0x7a838485, 0x86878889, 0x8a929394, 0x95969798, 425 0x999aa2a3, 0xa4a5a6a7, 0xa8a9aab2, 0xb3b4b5b6, 0xb7b8b9ba, 0xc2c3c4c5, 426 0xc6c7c8c9, 0xcad2d3d4, 0xd5d6d7d8, 0xd9dae1e2, 0xe3e4e5e6, 0xe7e8e9ea, 427 0xf1f2f3f4, 0xf5f6f7f8, 0xf9fa0000 428}; 429 430static const unsigned int hactbl_chr[HACTBL_SIZE] = { 431 0x00020103, 0x03020403, 0x05050404, 0x0000017d, 0x01020300, 0x04110512, 432 0x21314106, 0x13516107, 0x22711432, 0x8191a108, 0x2342b1c1, 0x1552d1f0, 433 0x24336272, 0x82090a16, 0x1718191a, 0x25262728, 0x292a3435, 0x36373839, 434 0x3a434445, 0x46474849, 0x4a535455, 0x56575859, 0x5a636465, 0x66676869, 435 0x6a737475, 0x76777879, 0x7a838485, 0x86878889, 0x8a929394, 0x95969798, 436 0x999aa2a3, 0xa4a5a6a7, 0xa8a9aab2, 0xb3b4b5b6, 0xb7b8b9ba, 0xc2c3c4c5, 437 0xc6c7c8c9, 0xcad2d3d4, 0xd5d6d7d8, 0xd9dae1e2, 0xe3e4e5e6, 0xe7e8e9ea, 438 0xf1f2f3f4, 0xf5f6f7f8, 0xf9fa0000 439}; 440 441static const char *error_to_text[16] = { 442 "Normal", 443 "SOI not detected", 444 "SOF1 to SOFF detected", 445 "Subsampling not detected", 446 "SOF accuracy error", 447 "DQT accuracy error", 448 "Component error 1", 449 "Component error 2", 450 "SOF0, DQT, and DHT not detected when SOS detected", 451 "SOS not detected", 452 "EOI not detected", 453 "Restart interval data number error detected", 454 "Image size error", 455 "Last MCU data number error", 456 "Block data number error", 457 "Unknown" 458}; 459 460static struct jpu_buffer *vb2_to_jpu_buffer(struct vb2_v4l2_buffer *vb) 461{ 462 struct v4l2_m2m_buffer *b = 463 container_of(vb, struct v4l2_m2m_buffer, vb); 464 465 return container_of(b, struct jpu_buffer, buf); 466} 467 468static u32 jpu_read(struct jpu *jpu, unsigned int reg) 469{ 470 return ioread32(jpu->regs + reg); 471} 472 473static void jpu_write(struct jpu *jpu, u32 val, unsigned int reg) 474{ 475 iowrite32(val, jpu->regs + reg); 476} 477 478static struct jpu_ctx *ctrl_to_ctx(struct v4l2_ctrl *c) 479{ 480 return container_of(c->handler, struct jpu_ctx, ctrl_handler); 481} 482 483static struct jpu_ctx *file_to_ctx(struct file *filp) 484{ 485 return container_of(file_to_v4l2_fh(filp), struct jpu_ctx, fh); 486} 487 488static void jpu_set_tbl(struct jpu *jpu, u32 reg, const unsigned int *tbl, 489 unsigned int len) { 490 unsigned int i; 491 492 for (i = 0; i < len; i++) 493 jpu_write(jpu, tbl[i], reg + (i << 2)); 494} 495 496static void jpu_set_qtbl(struct jpu *jpu, unsigned short quality) 497{ 498 jpu_set_tbl(jpu, JCQTBL(0), qtbl_lum[quality], QTBL_SIZE); 499 jpu_set_tbl(jpu, JCQTBL(1), qtbl_chr[quality], QTBL_SIZE); 500} 501 502static void jpu_set_htbl(struct jpu *jpu) 503{ 504 jpu_set_tbl(jpu, JCHTBD(0), hdctbl_lum, HDCTBL_SIZE); 505 jpu_set_tbl(jpu, JCHTBA(0), hactbl_lum, HACTBL_SIZE); 506 jpu_set_tbl(jpu, JCHTBD(1), hdctbl_chr, HDCTBL_SIZE); 507 jpu_set_tbl(jpu, JCHTBA(1), hactbl_chr, HACTBL_SIZE); 508} 509 510static int jpu_wait_reset(struct jpu *jpu) 511{ 512 unsigned long timeout; 513 514 timeout = jiffies + msecs_to_jiffies(JPU_RESET_TIMEOUT); 515 516 while (jpu_read(jpu, JCCMD) & JCCMD_SRST) { 517 if (time_after(jiffies, timeout)) { 518 dev_err(jpu->dev, "timed out in reset\n"); 519 return -ETIMEDOUT; 520 } 521 schedule(); 522 } 523 524 return 0; 525} 526 527static int jpu_reset(struct jpu *jpu) 528{ 529 jpu_write(jpu, JCCMD_SRST, JCCMD); 530 return jpu_wait_reset(jpu); 531} 532 533/* 534 * ============================================================================ 535 * video ioctl operations 536 * ============================================================================ 537 */ 538static void put_qtbl(u8 *p, const u8 *qtbl) 539{ 540 unsigned int i; 541 542 for (i = 0; i < ARRAY_SIZE(zigzag); i++) 543 p[i] = *(qtbl + zigzag[i]); 544} 545 546static void put_htbl(u8 *p, const u8 *htbl, unsigned int len) 547{ 548 unsigned int i, j; 549 550 for (i = 0; i < len; i += 4) 551 for (j = 0; j < 4 && (i + j) < len; ++j) 552 p[i + j] = htbl[i + 3 - j]; 553} 554 555static void jpu_generate_hdr(unsigned short quality, unsigned char *p) 556{ 557 put_qtbl(p + JPU_JPEG_QTBL_LUM_OFFSET, (const u8 *)qtbl_lum[quality]); 558 put_qtbl(p + JPU_JPEG_QTBL_CHR_OFFSET, (const u8 *)qtbl_chr[quality]); 559 560 put_htbl(p + JPU_JPEG_HDCTBL_LUM_OFFSET, (const u8 *)hdctbl_lum, 561 JPU_JPEG_HDCTBL_SIZE); 562 put_htbl(p + JPU_JPEG_HACTBL_LUM_OFFSET, (const u8 *)hactbl_lum, 563 JPU_JPEG_HACTBL_SIZE); 564 565 put_htbl(p + JPU_JPEG_HDCTBL_CHR_OFFSET, (const u8 *)hdctbl_chr, 566 JPU_JPEG_HDCTBL_SIZE); 567 put_htbl(p + JPU_JPEG_HACTBL_CHR_OFFSET, (const u8 *)hactbl_chr, 568 JPU_JPEG_HACTBL_SIZE); 569} 570 571static int get_byte(struct jpeg_buffer *buf) 572{ 573 if (buf->curr >= buf->end) 574 return -1; 575 576 return *(u8 *)buf->curr++; 577} 578 579static int get_word_be(struct jpeg_buffer *buf, unsigned int *word) 580{ 581 if (buf->end - buf->curr < 2) 582 return -1; 583 584 *word = get_unaligned_be16(buf->curr); 585 buf->curr += 2; 586 587 return 0; 588} 589 590static void skip(struct jpeg_buffer *buf, unsigned long len) 591{ 592 buf->curr += min((unsigned long)(buf->end - buf->curr), len); 593} 594 595static u8 jpu_parse_hdr(void *buffer, unsigned long size, unsigned int *width, 596 unsigned int *height) 597{ 598 struct jpeg_buffer jpeg_buffer; 599 unsigned int word; 600 bool soi = false; 601 602 jpeg_buffer.end = buffer + size; 603 jpeg_buffer.curr = buffer; 604 605 /* 606 * basic size check and EOI - we don't want to let JPU cross 607 * buffer bounds in any case. Hope it's stopping by EOI. 608 */ 609 if (size < JPU_JPEG_MIN_SIZE || 610 *(u8 *)(buffer + size - 1) != JPEG_MARKER_EOI) 611 return 0; 612 613 for (;;) { 614 int c; 615 616 /* skip preceding filler bytes */ 617 do 618 c = get_byte(&jpeg_buffer); 619 while (c == 0xff || c == 0); 620 621 if (!soi && c == JPEG_MARKER_SOI) { 622 soi = true; 623 continue; 624 } else if (soi != (c != JPEG_MARKER_SOI)) 625 return 0; 626 627 switch (c) { 628 case JPEG_MARKER_SOF0: /* SOF0: baseline JPEG */ 629 skip(&jpeg_buffer, 3); /* segment length and bpp */ 630 if (get_word_be(&jpeg_buffer, height) || 631 get_word_be(&jpeg_buffer, width) || 632 get_byte(&jpeg_buffer) != 3) /* YCbCr only */ 633 return 0; 634 635 skip(&jpeg_buffer, 1); 636 return get_byte(&jpeg_buffer); 637 case JPEG_MARKER_DHT: 638 case JPEG_MARKER_DQT: 639 case JPEG_MARKER_COM: 640 case JPEG_MARKER_DRI: 641 case JPEG_MARKER_APP0 ... JPEG_MARKER_APP0 + 0x0f: 642 if (get_word_be(&jpeg_buffer, &word)) 643 return 0; 644 skip(&jpeg_buffer, (long)word - 2); 645 break; 646 case 0: 647 break; 648 default: 649 return 0; 650 } 651 } 652 653 return 0; 654} 655 656static int jpu_querycap(struct file *file, void *priv, 657 struct v4l2_capability *cap) 658{ 659 struct jpu_ctx *ctx = file_to_ctx(file); 660 661 if (ctx->encoder) 662 strscpy(cap->card, DRV_NAME " encoder", sizeof(cap->card)); 663 else 664 strscpy(cap->card, DRV_NAME " decoder", sizeof(cap->card)); 665 666 strscpy(cap->driver, DRV_NAME, sizeof(cap->driver)); 667 memset(cap->reserved, 0, sizeof(cap->reserved)); 668 669 return 0; 670} 671 672static struct jpu_fmt *jpu_find_format(bool encoder, u32 pixelformat, 673 unsigned int fmt_type) 674{ 675 unsigned int i, fmt_flag; 676 677 if (encoder) 678 fmt_flag = fmt_type == JPU_FMT_TYPE_OUTPUT ? JPU_ENC_OUTPUT : 679 JPU_ENC_CAPTURE; 680 else 681 fmt_flag = fmt_type == JPU_FMT_TYPE_OUTPUT ? JPU_DEC_OUTPUT : 682 JPU_DEC_CAPTURE; 683 684 for (i = 0; i < ARRAY_SIZE(jpu_formats); i++) { 685 struct jpu_fmt *fmt = &jpu_formats[i]; 686 687 if (fmt->fourcc == pixelformat && fmt->types & fmt_flag) 688 return fmt; 689 } 690 691 return NULL; 692} 693 694static int jpu_enum_fmt(struct v4l2_fmtdesc *f, u32 type) 695{ 696 unsigned int i, num = 0; 697 698 for (i = 0; i < ARRAY_SIZE(jpu_formats); ++i) { 699 if (jpu_formats[i].types & type) { 700 if (num == f->index) 701 break; 702 ++num; 703 } 704 } 705 706 if (i >= ARRAY_SIZE(jpu_formats)) 707 return -EINVAL; 708 709 f->pixelformat = jpu_formats[i].fourcc; 710 711 return 0; 712} 713 714static int jpu_enum_fmt_cap(struct file *file, void *priv, 715 struct v4l2_fmtdesc *f) 716{ 717 struct jpu_ctx *ctx = file_to_ctx(file); 718 719 return jpu_enum_fmt(f, ctx->encoder ? JPU_ENC_CAPTURE : 720 JPU_DEC_CAPTURE); 721} 722 723static int jpu_enum_fmt_out(struct file *file, void *priv, 724 struct v4l2_fmtdesc *f) 725{ 726 struct jpu_ctx *ctx = file_to_ctx(file); 727 728 return jpu_enum_fmt(f, ctx->encoder ? JPU_ENC_OUTPUT : JPU_DEC_OUTPUT); 729} 730 731static struct jpu_q_data *jpu_get_q_data(struct jpu_ctx *ctx, 732 enum v4l2_buf_type type) 733{ 734 if (V4L2_TYPE_IS_OUTPUT(type)) 735 return &ctx->out_q; 736 else 737 return &ctx->cap_q; 738} 739 740static void jpu_bound_align_image(u32 *w, unsigned int w_min, 741 unsigned int w_max, unsigned int w_align, 742 u32 *h, unsigned int h_min, 743 unsigned int h_max, unsigned int h_align) 744{ 745 unsigned int width, height, w_step, h_step; 746 747 width = *w; 748 height = *h; 749 750 w_step = 1U << w_align; 751 h_step = 1U << h_align; 752 v4l_bound_align_image(w, w_min, w_max, w_align, h, h_min, h_max, 753 h_align, 3); 754 755 if (*w < width && *w + w_step < w_max) 756 *w += w_step; 757 if (*h < height && *h + h_step < h_max) 758 *h += h_step; 759} 760 761static int __jpu_try_fmt(struct jpu_ctx *ctx, struct jpu_fmt **fmtinfo, 762 struct v4l2_pix_format_mplane *pix, 763 enum v4l2_buf_type type) 764{ 765 struct jpu_fmt *fmt; 766 unsigned int f_type, w, h; 767 768 f_type = V4L2_TYPE_IS_OUTPUT(type) ? JPU_FMT_TYPE_OUTPUT : 769 JPU_FMT_TYPE_CAPTURE; 770 771 fmt = jpu_find_format(ctx->encoder, pix->pixelformat, f_type); 772 if (!fmt) { 773 unsigned int pixelformat; 774 775 dev_dbg(ctx->jpu->dev, "unknown format; set default format\n"); 776 if (ctx->encoder) 777 pixelformat = f_type == JPU_FMT_TYPE_OUTPUT ? 778 V4L2_PIX_FMT_NV16M : V4L2_PIX_FMT_JPEG; 779 else 780 pixelformat = f_type == JPU_FMT_TYPE_CAPTURE ? 781 V4L2_PIX_FMT_NV16M : V4L2_PIX_FMT_JPEG; 782 fmt = jpu_find_format(ctx->encoder, pixelformat, f_type); 783 } 784 785 pix->pixelformat = fmt->fourcc; 786 pix->colorspace = fmt->colorspace; 787 pix->field = V4L2_FIELD_NONE; 788 pix->num_planes = fmt->num_planes; 789 790 jpu_bound_align_image(&pix->width, JPU_WIDTH_MIN, JPU_WIDTH_MAX, 791 fmt->h_align, &pix->height, JPU_HEIGHT_MIN, 792 JPU_HEIGHT_MAX, fmt->v_align); 793 794 w = pix->width; 795 h = pix->height; 796 797 if (fmt->fourcc == V4L2_PIX_FMT_JPEG) { 798 /* ignore userspaces's sizeimage for encoding */ 799 if (pix->plane_fmt[0].sizeimage <= 0 || ctx->encoder) 800 pix->plane_fmt[0].sizeimage = JPU_JPEG_HDR_SIZE + 801 (JPU_JPEG_MAX_BYTES_PER_PIXEL * w * h); 802 pix->plane_fmt[0].bytesperline = 0; 803 } else { 804 unsigned int i, bpl = 0; 805 806 for (i = 0; i < pix->num_planes; ++i) 807 bpl = max(bpl, pix->plane_fmt[i].bytesperline); 808 809 bpl = clamp_t(unsigned int, bpl, w, JPU_WIDTH_MAX); 810 bpl = round_up(bpl, JPU_MEMALIGN); 811 812 for (i = 0; i < pix->num_planes; ++i) { 813 pix->plane_fmt[i].bytesperline = bpl; 814 pix->plane_fmt[i].sizeimage = bpl * h * fmt->bpp[i] / 8; 815 } 816 } 817 818 if (fmtinfo) 819 *fmtinfo = fmt; 820 821 return 0; 822} 823 824static int jpu_try_fmt(struct file *file, void *priv, struct v4l2_format *f) 825{ 826 struct jpu_ctx *ctx = file_to_ctx(file); 827 828 return __jpu_try_fmt(ctx, NULL, &f->fmt.pix_mp, f->type); 829} 830 831static int jpu_s_fmt(struct file *file, void *priv, struct v4l2_format *f) 832{ 833 struct vb2_queue *vq; 834 struct jpu_ctx *ctx = file_to_ctx(file); 835 struct v4l2_m2m_ctx *m2m_ctx = ctx->fh.m2m_ctx; 836 struct jpu_fmt *fmtinfo; 837 struct jpu_q_data *q_data; 838 int ret; 839 840 vq = v4l2_m2m_get_vq(m2m_ctx, f->type); 841 842 if (vb2_is_busy(vq)) { 843 v4l2_err(&ctx->jpu->v4l2_dev, "%s queue busy\n", __func__); 844 return -EBUSY; 845 } 846 847 ret = __jpu_try_fmt(ctx, &fmtinfo, &f->fmt.pix_mp, f->type); 848 if (ret < 0) 849 return ret; 850 851 q_data = jpu_get_q_data(ctx, f->type); 852 853 q_data->format = f->fmt.pix_mp; 854 q_data->fmtinfo = fmtinfo; 855 856 return 0; 857} 858 859static int jpu_g_fmt(struct file *file, void *priv, struct v4l2_format *f) 860{ 861 struct jpu_ctx *ctx = file_to_ctx(file); 862 struct jpu_q_data *q_data; 863 864 q_data = jpu_get_q_data(ctx, f->type); 865 f->fmt.pix_mp = q_data->format; 866 867 return 0; 868} 869 870/* 871 * V4L2 controls 872 */ 873static int jpu_s_ctrl(struct v4l2_ctrl *ctrl) 874{ 875 struct jpu_ctx *ctx = ctrl_to_ctx(ctrl); 876 unsigned long flags; 877 878 spin_lock_irqsave(&ctx->jpu->lock, flags); 879 if (ctrl->id == V4L2_CID_JPEG_COMPRESSION_QUALITY) 880 ctx->compr_quality = ctrl->val; 881 spin_unlock_irqrestore(&ctx->jpu->lock, flags); 882 883 return 0; 884} 885 886static const struct v4l2_ctrl_ops jpu_ctrl_ops = { 887 .s_ctrl = jpu_s_ctrl, 888}; 889 890static int jpu_streamon(struct file *file, void *priv, enum v4l2_buf_type type) 891{ 892 struct jpu_q_data *src_q_data, *dst_q_data, *orig, adj, *ref; 893 struct jpu_ctx *ctx = file_to_ctx(file); 894 enum v4l2_buf_type adj_type; 895 896 src_q_data = jpu_get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 897 dst_q_data = jpu_get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 898 899 if (ctx->encoder) { 900 adj = *src_q_data; 901 orig = src_q_data; 902 ref = dst_q_data; 903 adj_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 904 } else { 905 adj = *dst_q_data; 906 orig = dst_q_data; 907 ref = src_q_data; 908 adj_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 909 } 910 911 adj.format.width = ref->format.width; 912 adj.format.height = ref->format.height; 913 914 __jpu_try_fmt(ctx, NULL, &adj.format, adj_type); 915 916 if (adj.format.width != orig->format.width || 917 adj.format.height != orig->format.height) { 918 dev_err(ctx->jpu->dev, "src and dst formats do not match.\n"); 919 /* maybe we can return -EPIPE here? */ 920 return -EINVAL; 921 } 922 923 return v4l2_m2m_streamon(file, ctx->fh.m2m_ctx, type); 924} 925 926static const struct v4l2_ioctl_ops jpu_ioctl_ops = { 927 .vidioc_querycap = jpu_querycap, 928 929 .vidioc_enum_fmt_vid_cap = jpu_enum_fmt_cap, 930 .vidioc_enum_fmt_vid_out = jpu_enum_fmt_out, 931 .vidioc_g_fmt_vid_cap_mplane = jpu_g_fmt, 932 .vidioc_g_fmt_vid_out_mplane = jpu_g_fmt, 933 .vidioc_try_fmt_vid_cap_mplane = jpu_try_fmt, 934 .vidioc_try_fmt_vid_out_mplane = jpu_try_fmt, 935 .vidioc_s_fmt_vid_cap_mplane = jpu_s_fmt, 936 .vidioc_s_fmt_vid_out_mplane = jpu_s_fmt, 937 938 .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs, 939 .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs, 940 .vidioc_querybuf = v4l2_m2m_ioctl_querybuf, 941 .vidioc_qbuf = v4l2_m2m_ioctl_qbuf, 942 .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf, 943 .vidioc_expbuf = v4l2_m2m_ioctl_expbuf, 944 945 .vidioc_streamon = jpu_streamon, 946 .vidioc_streamoff = v4l2_m2m_ioctl_streamoff, 947 948 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, 949 .vidioc_unsubscribe_event = v4l2_event_unsubscribe 950}; 951 952static int jpu_controls_create(struct jpu_ctx *ctx) 953{ 954 struct v4l2_ctrl *ctrl; 955 int ret; 956 957 v4l2_ctrl_handler_init(&ctx->ctrl_handler, 1); 958 959 ctrl = v4l2_ctrl_new_std(&ctx->ctrl_handler, &jpu_ctrl_ops, 960 V4L2_CID_JPEG_COMPRESSION_QUALITY, 961 0, JPU_MAX_QUALITY - 1, 1, 0); 962 963 if (ctx->ctrl_handler.error) { 964 ret = ctx->ctrl_handler.error; 965 goto error_free; 966 } 967 968 if (!ctx->encoder) 969 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE | 970 V4L2_CTRL_FLAG_READ_ONLY; 971 972 ret = v4l2_ctrl_handler_setup(&ctx->ctrl_handler); 973 if (ret < 0) 974 goto error_free; 975 976 return 0; 977 978error_free: 979 v4l2_ctrl_handler_free(&ctx->ctrl_handler); 980 return ret; 981} 982 983/* 984 * ============================================================================ 985 * Queue operations 986 * ============================================================================ 987 */ 988static int jpu_queue_setup(struct vb2_queue *vq, 989 unsigned int *nbuffers, unsigned int *nplanes, 990 unsigned int sizes[], struct device *alloc_devs[]) 991{ 992 struct jpu_ctx *ctx = vb2_get_drv_priv(vq); 993 struct jpu_q_data *q_data; 994 unsigned int i; 995 996 q_data = jpu_get_q_data(ctx, vq->type); 997 998 if (*nplanes) { 999 if (*nplanes != q_data->format.num_planes) 1000 return -EINVAL; 1001 1002 for (i = 0; i < *nplanes; i++) { 1003 unsigned int q_size = q_data->format.plane_fmt[i].sizeimage; 1004 1005 if (sizes[i] < q_size) 1006 return -EINVAL; 1007 } 1008 return 0; 1009 } 1010 1011 *nplanes = q_data->format.num_planes; 1012 1013 for (i = 0; i < *nplanes; i++) 1014 sizes[i] = q_data->format.plane_fmt[i].sizeimage; 1015 1016 return 0; 1017} 1018 1019static int jpu_buf_prepare(struct vb2_buffer *vb) 1020{ 1021 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); 1022 struct jpu_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); 1023 struct jpu_q_data *q_data; 1024 unsigned int i; 1025 1026 q_data = jpu_get_q_data(ctx, vb->vb2_queue->type); 1027 1028 if (V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) { 1029 if (vbuf->field == V4L2_FIELD_ANY) 1030 vbuf->field = V4L2_FIELD_NONE; 1031 if (vbuf->field != V4L2_FIELD_NONE) { 1032 dev_err(ctx->jpu->dev, "%s field isn't supported\n", 1033 __func__); 1034 return -EINVAL; 1035 } 1036 } 1037 1038 for (i = 0; i < q_data->format.num_planes; i++) { 1039 unsigned long size = q_data->format.plane_fmt[i].sizeimage; 1040 1041 if (vb2_plane_size(vb, i) < size) { 1042 dev_err(ctx->jpu->dev, 1043 "%s: data will not fit into plane (%lu < %lu)\n", 1044 __func__, vb2_plane_size(vb, i), size); 1045 return -EINVAL; 1046 } 1047 1048 /* decoder capture queue */ 1049 if (!ctx->encoder && V4L2_TYPE_IS_CAPTURE(vb->vb2_queue->type)) 1050 vb2_set_plane_payload(vb, i, size); 1051 } 1052 1053 return 0; 1054} 1055 1056static void jpu_buf_queue(struct vb2_buffer *vb) 1057{ 1058 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); 1059 struct jpu_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); 1060 1061 if (!ctx->encoder && V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) { 1062 struct jpu_buffer *jpu_buf = vb2_to_jpu_buffer(vbuf); 1063 struct jpu_q_data *q_data, adjust; 1064 void *buffer = vb2_plane_vaddr(vb, 0); 1065 unsigned long buf_size = vb2_get_plane_payload(vb, 0); 1066 unsigned int width, height; 1067 1068 u8 subsampling = jpu_parse_hdr(buffer, buf_size, &width, 1069 &height); 1070 1071 /* check if JPEG data basic parsing was successful */ 1072 if (subsampling != JPU_JPEG_422 && subsampling != JPU_JPEG_420) 1073 goto format_error; 1074 1075 q_data = &ctx->out_q; 1076 1077 adjust = *q_data; 1078 adjust.format.width = width; 1079 adjust.format.height = height; 1080 1081 __jpu_try_fmt(ctx, &adjust.fmtinfo, &adjust.format, 1082 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 1083 1084 if (adjust.format.width != q_data->format.width || 1085 adjust.format.height != q_data->format.height) 1086 goto format_error; 1087 1088 /* 1089 * keep subsampling in buffer to check it 1090 * for compatibility in device_run 1091 */ 1092 jpu_buf->subsampling = subsampling; 1093 } 1094 1095 if (ctx->fh.m2m_ctx) 1096 v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf); 1097 1098 return; 1099 1100format_error: 1101 dev_err(ctx->jpu->dev, "incompatible or corrupted JPEG data\n"); 1102 vb2_buffer_done(vb, VB2_BUF_STATE_ERROR); 1103} 1104 1105static void jpu_buf_finish(struct vb2_buffer *vb) 1106{ 1107 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); 1108 struct jpu_buffer *jpu_buf = vb2_to_jpu_buffer(vbuf); 1109 struct jpu_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); 1110 struct jpu_q_data *q_data = &ctx->out_q; 1111 enum v4l2_buf_type type = vb->vb2_queue->type; 1112 u8 *buffer; 1113 1114 if (vb->state == VB2_BUF_STATE_DONE) 1115 vbuf->sequence = jpu_get_q_data(ctx, type)->sequence++; 1116 1117 if (!ctx->encoder || vb->state != VB2_BUF_STATE_DONE || 1118 V4L2_TYPE_IS_OUTPUT(type)) 1119 return; 1120 1121 buffer = vb2_plane_vaddr(vb, 0); 1122 1123 memcpy(buffer, jpeg_hdrs[jpu_buf->compr_quality], JPU_JPEG_HDR_SIZE); 1124 *(__be16 *)(buffer + JPU_JPEG_HEIGHT_OFFSET) = 1125 cpu_to_be16(q_data->format.height); 1126 *(__be16 *)(buffer + JPU_JPEG_WIDTH_OFFSET) = 1127 cpu_to_be16(q_data->format.width); 1128 *(buffer + JPU_JPEG_SUBS_OFFSET) = q_data->fmtinfo->subsampling; 1129} 1130 1131static int jpu_start_streaming(struct vb2_queue *vq, unsigned count) 1132{ 1133 struct jpu_ctx *ctx = vb2_get_drv_priv(vq); 1134 struct jpu_q_data *q_data = jpu_get_q_data(ctx, vq->type); 1135 1136 q_data->sequence = 0; 1137 return 0; 1138} 1139 1140static void jpu_stop_streaming(struct vb2_queue *vq) 1141{ 1142 struct jpu_ctx *ctx = vb2_get_drv_priv(vq); 1143 struct vb2_v4l2_buffer *vb; 1144 unsigned long flags; 1145 1146 for (;;) { 1147 if (V4L2_TYPE_IS_OUTPUT(vq->type)) 1148 vb = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); 1149 else 1150 vb = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); 1151 if (vb == NULL) 1152 return; 1153 spin_lock_irqsave(&ctx->jpu->lock, flags); 1154 v4l2_m2m_buf_done(vb, VB2_BUF_STATE_ERROR); 1155 spin_unlock_irqrestore(&ctx->jpu->lock, flags); 1156 } 1157} 1158 1159static const struct vb2_ops jpu_qops = { 1160 .queue_setup = jpu_queue_setup, 1161 .buf_prepare = jpu_buf_prepare, 1162 .buf_queue = jpu_buf_queue, 1163 .buf_finish = jpu_buf_finish, 1164 .start_streaming = jpu_start_streaming, 1165 .stop_streaming = jpu_stop_streaming, 1166}; 1167 1168static int jpu_queue_init(void *priv, struct vb2_queue *src_vq, 1169 struct vb2_queue *dst_vq) 1170{ 1171 struct jpu_ctx *ctx = priv; 1172 int ret; 1173 1174 memset(src_vq, 0, sizeof(*src_vq)); 1175 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1176 src_vq->io_modes = VB2_MMAP | VB2_DMABUF; 1177 src_vq->drv_priv = ctx; 1178 src_vq->buf_struct_size = sizeof(struct jpu_buffer); 1179 src_vq->ops = &jpu_qops; 1180 src_vq->mem_ops = &vb2_dma_contig_memops; 1181 src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; 1182 src_vq->lock = &ctx->jpu->mutex; 1183 src_vq->dev = ctx->jpu->v4l2_dev.dev; 1184 1185 ret = vb2_queue_init(src_vq); 1186 if (ret) 1187 return ret; 1188 1189 memset(dst_vq, 0, sizeof(*dst_vq)); 1190 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1191 dst_vq->io_modes = VB2_MMAP | VB2_DMABUF; 1192 dst_vq->drv_priv = ctx; 1193 dst_vq->buf_struct_size = sizeof(struct jpu_buffer); 1194 dst_vq->ops = &jpu_qops; 1195 dst_vq->mem_ops = &vb2_dma_contig_memops; 1196 dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; 1197 dst_vq->lock = &ctx->jpu->mutex; 1198 dst_vq->dev = ctx->jpu->v4l2_dev.dev; 1199 1200 return vb2_queue_init(dst_vq); 1201} 1202 1203/* 1204 * ============================================================================ 1205 * Device file operations 1206 * ============================================================================ 1207 */ 1208static int jpu_open(struct file *file) 1209{ 1210 struct jpu *jpu = video_drvdata(file); 1211 struct video_device *vfd = video_devdata(file); 1212 struct jpu_ctx *ctx; 1213 int ret; 1214 1215 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); 1216 if (!ctx) 1217 return -ENOMEM; 1218 1219 v4l2_fh_init(&ctx->fh, vfd); 1220 ctx->fh.ctrl_handler = &ctx->ctrl_handler; 1221 v4l2_fh_add(&ctx->fh, file); 1222 1223 ctx->jpu = jpu; 1224 ctx->encoder = vfd == &jpu->vfd_encoder; 1225 1226 __jpu_try_fmt(ctx, &ctx->out_q.fmtinfo, &ctx->out_q.format, 1227 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 1228 __jpu_try_fmt(ctx, &ctx->cap_q.fmtinfo, &ctx->cap_q.format, 1229 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 1230 1231 ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(jpu->m2m_dev, ctx, jpu_queue_init); 1232 if (IS_ERR(ctx->fh.m2m_ctx)) { 1233 ret = PTR_ERR(ctx->fh.m2m_ctx); 1234 goto v4l_prepare_rollback; 1235 } 1236 1237 ret = jpu_controls_create(ctx); 1238 if (ret < 0) 1239 goto v4l_prepare_rollback; 1240 1241 if (mutex_lock_interruptible(&jpu->mutex)) { 1242 ret = -ERESTARTSYS; 1243 goto v4l_prepare_rollback; 1244 } 1245 1246 if (jpu->ref_count == 0) { 1247 ret = clk_prepare_enable(jpu->clk); 1248 if (ret < 0) 1249 goto device_prepare_rollback; 1250 /* ...issue software reset */ 1251 ret = jpu_reset(jpu); 1252 if (ret) 1253 goto jpu_reset_rollback; 1254 } 1255 1256 jpu->ref_count++; 1257 1258 mutex_unlock(&jpu->mutex); 1259 return 0; 1260 1261jpu_reset_rollback: 1262 clk_disable_unprepare(jpu->clk); 1263device_prepare_rollback: 1264 mutex_unlock(&jpu->mutex); 1265v4l_prepare_rollback: 1266 v4l2_fh_del(&ctx->fh, file); 1267 v4l2_fh_exit(&ctx->fh); 1268 kfree(ctx); 1269 return ret; 1270} 1271 1272static int jpu_release(struct file *file) 1273{ 1274 struct jpu_ctx *ctx = file_to_ctx(file); 1275 struct jpu *jpu = video_drvdata(file); 1276 1277 v4l2_m2m_ctx_release(ctx->fh.m2m_ctx); 1278 v4l2_ctrl_handler_free(&ctx->ctrl_handler); 1279 v4l2_fh_del(&ctx->fh, file); 1280 v4l2_fh_exit(&ctx->fh); 1281 kfree(ctx); 1282 1283 mutex_lock(&jpu->mutex); 1284 if (--jpu->ref_count == 0) 1285 clk_disable_unprepare(jpu->clk); 1286 mutex_unlock(&jpu->mutex); 1287 1288 return 0; 1289} 1290 1291static const struct v4l2_file_operations jpu_fops = { 1292 .owner = THIS_MODULE, 1293 .open = jpu_open, 1294 .release = jpu_release, 1295 .unlocked_ioctl = video_ioctl2, 1296 .poll = v4l2_m2m_fop_poll, 1297 .mmap = v4l2_m2m_fop_mmap, 1298}; 1299 1300/* 1301 * ============================================================================ 1302 * mem2mem callbacks 1303 * ============================================================================ 1304 */ 1305static void jpu_cleanup(struct jpu_ctx *ctx, bool reset) 1306{ 1307 /* remove current buffers and finish job */ 1308 struct vb2_v4l2_buffer *src_buf, *dst_buf; 1309 unsigned long flags; 1310 1311 spin_lock_irqsave(&ctx->jpu->lock, flags); 1312 1313 src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); 1314 dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); 1315 1316 v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_ERROR); 1317 v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_ERROR); 1318 1319 /* ...and give it a chance on next run */ 1320 if (reset) 1321 jpu_write(ctx->jpu, JCCMD_SRST, JCCMD); 1322 1323 spin_unlock_irqrestore(&ctx->jpu->lock, flags); 1324 1325 v4l2_m2m_job_finish(ctx->jpu->m2m_dev, ctx->fh.m2m_ctx); 1326} 1327 1328static void jpu_device_run(void *priv) 1329{ 1330 struct jpu_ctx *ctx = priv; 1331 struct jpu *jpu = ctx->jpu; 1332 struct jpu_buffer *jpu_buf; 1333 struct jpu_q_data *q_data; 1334 struct vb2_v4l2_buffer *src_buf, *dst_buf; 1335 unsigned int w, h, bpl; 1336 unsigned char num_planes, subsampling; 1337 unsigned long flags; 1338 1339 /* ...wait until module reset completes; we have mutex locked here */ 1340 if (jpu_wait_reset(jpu)) { 1341 jpu_cleanup(ctx, true); 1342 return; 1343 } 1344 1345 spin_lock_irqsave(&ctx->jpu->lock, flags); 1346 1347 jpu->curr = ctx; 1348 1349 src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); 1350 dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); 1351 1352 if (ctx->encoder) { 1353 jpu_buf = vb2_to_jpu_buffer(dst_buf); 1354 q_data = &ctx->out_q; 1355 } else { 1356 jpu_buf = vb2_to_jpu_buffer(src_buf); 1357 q_data = &ctx->cap_q; 1358 } 1359 1360 w = q_data->format.width; 1361 h = q_data->format.height; 1362 bpl = q_data->format.plane_fmt[0].bytesperline; 1363 num_planes = q_data->fmtinfo->num_planes; 1364 subsampling = q_data->fmtinfo->subsampling; 1365 1366 if (ctx->encoder) { 1367 unsigned long src_1_addr, src_2_addr, dst_addr; 1368 unsigned int redu, inft; 1369 1370 dst_addr = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0); 1371 src_1_addr = 1372 vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0); 1373 if (num_planes > 1) 1374 src_2_addr = vb2_dma_contig_plane_dma_addr( 1375 &src_buf->vb2_buf, 1); 1376 else 1377 src_2_addr = src_1_addr + w * h; 1378 1379 jpu_buf->compr_quality = ctx->compr_quality; 1380 1381 if (subsampling == JPU_JPEG_420) { 1382 redu = JCMOD_REDU_420; 1383 inft = JIFECNT_INFT_420; 1384 } else { 1385 redu = JCMOD_REDU_422; 1386 inft = JIFECNT_INFT_422; 1387 } 1388 1389 /* only no marker mode works for encoding */ 1390 jpu_write(jpu, JCMOD_DSP_ENC | JCMOD_PCTR | redu | 1391 JCMOD_MSKIP_ENABLE, JCMOD); 1392 1393 jpu_write(jpu, JIFECNT_SWAP_WB | inft, JIFECNT); 1394 jpu_write(jpu, JIFDCNT_SWAP_WB, JIFDCNT); 1395 jpu_write(jpu, JINTE_TRANSF_COMPL, JINTE); 1396 1397 /* Y and C components source addresses */ 1398 jpu_write(jpu, src_1_addr, JIFESYA1); 1399 jpu_write(jpu, src_2_addr, JIFESCA1); 1400 1401 /* memory width */ 1402 jpu_write(jpu, bpl, JIFESMW); 1403 1404 jpu_write(jpu, (w >> 8) & JCSZ_MASK, JCHSZU); 1405 jpu_write(jpu, w & JCSZ_MASK, JCHSZD); 1406 1407 jpu_write(jpu, (h >> 8) & JCSZ_MASK, JCVSZU); 1408 jpu_write(jpu, h & JCSZ_MASK, JCVSZD); 1409 1410 jpu_write(jpu, w, JIFESHSZ); 1411 jpu_write(jpu, h, JIFESVSZ); 1412 1413 jpu_write(jpu, dst_addr + JPU_JPEG_HDR_SIZE, JIFEDA1); 1414 1415 jpu_write(jpu, 0 << JCQTN_SHIFT(1) | 1 << JCQTN_SHIFT(2) | 1416 1 << JCQTN_SHIFT(3), JCQTN); 1417 1418 jpu_write(jpu, 0 << JCHTN_AC_SHIFT(1) | 0 << JCHTN_DC_SHIFT(1) | 1419 1 << JCHTN_AC_SHIFT(2) | 1 << JCHTN_DC_SHIFT(2) | 1420 1 << JCHTN_AC_SHIFT(3) | 1 << JCHTN_DC_SHIFT(3), 1421 JCHTN); 1422 1423 jpu_set_qtbl(jpu, ctx->compr_quality); 1424 jpu_set_htbl(jpu); 1425 } else { 1426 unsigned long src_addr, dst_1_addr, dst_2_addr; 1427 1428 if (jpu_buf->subsampling != subsampling) { 1429 dev_err(ctx->jpu->dev, 1430 "src and dst formats do not match.\n"); 1431 spin_unlock_irqrestore(&ctx->jpu->lock, flags); 1432 jpu_cleanup(ctx, false); 1433 return; 1434 } 1435 1436 src_addr = vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0); 1437 dst_1_addr = 1438 vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0); 1439 if (q_data->fmtinfo->num_planes > 1) 1440 dst_2_addr = vb2_dma_contig_plane_dma_addr( 1441 &dst_buf->vb2_buf, 1); 1442 else 1443 dst_2_addr = dst_1_addr + w * h; 1444 1445 /* ...set up decoder operation */ 1446 jpu_write(jpu, JCMOD_DSP_DEC | JCMOD_PCTR, JCMOD); 1447 jpu_write(jpu, JIFECNT_SWAP_WB, JIFECNT); 1448 jpu_write(jpu, JIFDCNT_SWAP_WB, JIFDCNT); 1449 1450 /* ...enable interrupts on transfer completion and d-g error */ 1451 jpu_write(jpu, JINTE_TRANSF_COMPL | JINTE_ERR, JINTE); 1452 1453 /* ...set source/destination addresses of encoded data */ 1454 jpu_write(jpu, src_addr, JIFDSA1); 1455 jpu_write(jpu, dst_1_addr, JIFDDYA1); 1456 jpu_write(jpu, dst_2_addr, JIFDDCA1); 1457 1458 jpu_write(jpu, bpl, JIFDDMW); 1459 } 1460 1461 /* ...start encoder/decoder operation */ 1462 jpu_write(jpu, JCCMD_JSRT, JCCMD); 1463 1464 spin_unlock_irqrestore(&ctx->jpu->lock, flags); 1465} 1466 1467static const struct v4l2_m2m_ops jpu_m2m_ops = { 1468 .device_run = jpu_device_run, 1469}; 1470 1471/* 1472 * ============================================================================ 1473 * IRQ handler 1474 * ============================================================================ 1475 */ 1476static irqreturn_t jpu_irq_handler(int irq, void *dev_id) 1477{ 1478 struct jpu *jpu = dev_id; 1479 struct jpu_ctx *curr_ctx; 1480 struct vb2_v4l2_buffer *src_buf, *dst_buf; 1481 unsigned int int_status; 1482 1483 int_status = jpu_read(jpu, JINTS); 1484 1485 /* ...spurious interrupt */ 1486 if (!((JINTS_TRANSF_COMPL | JINTS_PROCESS_COMPL | JINTS_ERR) & 1487 int_status)) 1488 return IRQ_NONE; 1489 1490 /* ...clear interrupts */ 1491 jpu_write(jpu, ~(int_status & JINTS_MASK), JINTS); 1492 if (int_status & (JINTS_ERR | JINTS_PROCESS_COMPL)) 1493 jpu_write(jpu, JCCMD_JEND, JCCMD); 1494 1495 spin_lock(&jpu->lock); 1496 1497 if ((int_status & JINTS_PROCESS_COMPL) && 1498 !(int_status & JINTS_TRANSF_COMPL)) 1499 goto handled; 1500 1501 curr_ctx = v4l2_m2m_get_curr_priv(jpu->m2m_dev); 1502 if (!curr_ctx) { 1503 /* ...instance is not running */ 1504 dev_err(jpu->dev, "no active context for m2m\n"); 1505 goto handled; 1506 } 1507 1508 src_buf = v4l2_m2m_src_buf_remove(curr_ctx->fh.m2m_ctx); 1509 dst_buf = v4l2_m2m_dst_buf_remove(curr_ctx->fh.m2m_ctx); 1510 1511 if (int_status & JINTS_TRANSF_COMPL) { 1512 if (curr_ctx->encoder) { 1513 unsigned long payload_size = jpu_read(jpu, JCDTCU) << 16 1514 | jpu_read(jpu, JCDTCM) << 8 1515 | jpu_read(jpu, JCDTCD); 1516 vb2_set_plane_payload(&dst_buf->vb2_buf, 0, 1517 payload_size + JPU_JPEG_HDR_SIZE); 1518 } 1519 1520 dst_buf->field = src_buf->field; 1521 dst_buf->vb2_buf.timestamp = src_buf->vb2_buf.timestamp; 1522 if (src_buf->flags & V4L2_BUF_FLAG_TIMECODE) 1523 dst_buf->timecode = src_buf->timecode; 1524 dst_buf->flags = src_buf->flags & 1525 (V4L2_BUF_FLAG_TIMECODE | V4L2_BUF_FLAG_KEYFRAME | 1526 V4L2_BUF_FLAG_PFRAME | V4L2_BUF_FLAG_BFRAME | 1527 V4L2_BUF_FLAG_TSTAMP_SRC_MASK); 1528 1529 v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE); 1530 v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_DONE); 1531 } else if (int_status & JINTS_ERR) { 1532 unsigned char error = jpu_read(jpu, JCDERR) & JCDERR_MASK; 1533 1534 dev_dbg(jpu->dev, "processing error: %#X: %s\n", error, 1535 error_to_text[error]); 1536 1537 v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_ERROR); 1538 v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_ERROR); 1539 } 1540 1541 jpu->curr = NULL; 1542 1543 /* ...reset JPU after completion */ 1544 jpu_write(jpu, JCCMD_SRST, JCCMD); 1545 spin_unlock(&jpu->lock); 1546 1547 v4l2_m2m_job_finish(jpu->m2m_dev, curr_ctx->fh.m2m_ctx); 1548 1549 return IRQ_HANDLED; 1550 1551handled: 1552 spin_unlock(&jpu->lock); 1553 return IRQ_HANDLED; 1554} 1555 1556/* 1557 * ============================================================================ 1558 * Driver basic infrastructure 1559 * ============================================================================ 1560 */ 1561static const struct of_device_id jpu_dt_ids[] = { 1562 { .compatible = "renesas,jpu-r8a7790" }, /* H2 */ 1563 { .compatible = "renesas,jpu-r8a7791" }, /* M2-W */ 1564 { .compatible = "renesas,jpu-r8a7792" }, /* V2H */ 1565 { .compatible = "renesas,jpu-r8a7793" }, /* M2-N */ 1566 { .compatible = "renesas,rcar-gen2-jpu" }, 1567 { }, 1568}; 1569MODULE_DEVICE_TABLE(of, jpu_dt_ids); 1570 1571static int jpu_probe(struct platform_device *pdev) 1572{ 1573 struct jpu *jpu; 1574 int ret; 1575 unsigned int i; 1576 1577 jpu = devm_kzalloc(&pdev->dev, sizeof(*jpu), GFP_KERNEL); 1578 if (!jpu) 1579 return -ENOMEM; 1580 1581 mutex_init(&jpu->mutex); 1582 spin_lock_init(&jpu->lock); 1583 jpu->dev = &pdev->dev; 1584 1585 /* memory-mapped registers */ 1586 jpu->regs = devm_platform_ioremap_resource(pdev, 0); 1587 if (IS_ERR(jpu->regs)) 1588 return PTR_ERR(jpu->regs); 1589 1590 /* interrupt service routine registration */ 1591 jpu->irq = ret = platform_get_irq(pdev, 0); 1592 if (ret < 0) 1593 return ret; 1594 1595 ret = devm_request_irq(&pdev->dev, jpu->irq, jpu_irq_handler, 0, 1596 dev_name(&pdev->dev), jpu); 1597 if (ret) { 1598 dev_err(&pdev->dev, "cannot claim IRQ %d\n", jpu->irq); 1599 return ret; 1600 } 1601 1602 /* clocks */ 1603 jpu->clk = devm_clk_get(&pdev->dev, NULL); 1604 if (IS_ERR(jpu->clk)) { 1605 dev_err(&pdev->dev, "cannot get clock\n"); 1606 return PTR_ERR(jpu->clk); 1607 } 1608 1609 /* v4l2 device */ 1610 ret = v4l2_device_register(&pdev->dev, &jpu->v4l2_dev); 1611 if (ret) { 1612 dev_err(&pdev->dev, "Failed to register v4l2 device\n"); 1613 return ret; 1614 } 1615 1616 /* mem2mem device */ 1617 jpu->m2m_dev = v4l2_m2m_init(&jpu_m2m_ops); 1618 if (IS_ERR(jpu->m2m_dev)) { 1619 v4l2_err(&jpu->v4l2_dev, "Failed to init mem2mem device\n"); 1620 ret = PTR_ERR(jpu->m2m_dev); 1621 goto device_register_rollback; 1622 } 1623 1624 /* fill in quantization and Huffman tables for encoder */ 1625 for (i = 0; i < JPU_MAX_QUALITY; i++) 1626 jpu_generate_hdr(i, (unsigned char *)jpeg_hdrs[i]); 1627 1628 strscpy(jpu->vfd_encoder.name, DRV_NAME, sizeof(jpu->vfd_encoder.name)); 1629 jpu->vfd_encoder.fops = &jpu_fops; 1630 jpu->vfd_encoder.ioctl_ops = &jpu_ioctl_ops; 1631 jpu->vfd_encoder.minor = -1; 1632 jpu->vfd_encoder.release = video_device_release_empty; 1633 jpu->vfd_encoder.lock = &jpu->mutex; 1634 jpu->vfd_encoder.v4l2_dev = &jpu->v4l2_dev; 1635 jpu->vfd_encoder.vfl_dir = VFL_DIR_M2M; 1636 jpu->vfd_encoder.device_caps = V4L2_CAP_STREAMING | 1637 V4L2_CAP_VIDEO_M2M_MPLANE; 1638 1639 ret = video_register_device(&jpu->vfd_encoder, VFL_TYPE_VIDEO, -1); 1640 if (ret) { 1641 v4l2_err(&jpu->v4l2_dev, "Failed to register video device\n"); 1642 goto m2m_init_rollback; 1643 } 1644 1645 video_set_drvdata(&jpu->vfd_encoder, jpu); 1646 1647 strscpy(jpu->vfd_decoder.name, DRV_NAME, sizeof(jpu->vfd_decoder.name)); 1648 jpu->vfd_decoder.fops = &jpu_fops; 1649 jpu->vfd_decoder.ioctl_ops = &jpu_ioctl_ops; 1650 jpu->vfd_decoder.minor = -1; 1651 jpu->vfd_decoder.release = video_device_release_empty; 1652 jpu->vfd_decoder.lock = &jpu->mutex; 1653 jpu->vfd_decoder.v4l2_dev = &jpu->v4l2_dev; 1654 jpu->vfd_decoder.vfl_dir = VFL_DIR_M2M; 1655 jpu->vfd_decoder.device_caps = V4L2_CAP_STREAMING | 1656 V4L2_CAP_VIDEO_M2M_MPLANE; 1657 1658 ret = video_register_device(&jpu->vfd_decoder, VFL_TYPE_VIDEO, -1); 1659 if (ret) { 1660 v4l2_err(&jpu->v4l2_dev, "Failed to register video device\n"); 1661 goto enc_vdev_register_rollback; 1662 } 1663 1664 video_set_drvdata(&jpu->vfd_decoder, jpu); 1665 platform_set_drvdata(pdev, jpu); 1666 1667 v4l2_info(&jpu->v4l2_dev, "encoder device registered as /dev/video%d\n", 1668 jpu->vfd_encoder.num); 1669 v4l2_info(&jpu->v4l2_dev, "decoder device registered as /dev/video%d\n", 1670 jpu->vfd_decoder.num); 1671 1672 return 0; 1673 1674enc_vdev_register_rollback: 1675 video_unregister_device(&jpu->vfd_encoder); 1676 1677m2m_init_rollback: 1678 v4l2_m2m_release(jpu->m2m_dev); 1679 1680device_register_rollback: 1681 v4l2_device_unregister(&jpu->v4l2_dev); 1682 1683 return ret; 1684} 1685 1686static void jpu_remove(struct platform_device *pdev) 1687{ 1688 struct jpu *jpu = platform_get_drvdata(pdev); 1689 1690 video_unregister_device(&jpu->vfd_decoder); 1691 video_unregister_device(&jpu->vfd_encoder); 1692 v4l2_m2m_release(jpu->m2m_dev); 1693 v4l2_device_unregister(&jpu->v4l2_dev); 1694} 1695 1696static int jpu_suspend(struct device *dev) 1697{ 1698 struct jpu *jpu = dev_get_drvdata(dev); 1699 1700 if (jpu->ref_count == 0) 1701 return 0; 1702 1703 clk_disable_unprepare(jpu->clk); 1704 1705 return 0; 1706} 1707 1708static int jpu_resume(struct device *dev) 1709{ 1710 struct jpu *jpu = dev_get_drvdata(dev); 1711 1712 if (jpu->ref_count == 0) 1713 return 0; 1714 1715 clk_prepare_enable(jpu->clk); 1716 1717 return 0; 1718} 1719 1720static DEFINE_SIMPLE_DEV_PM_OPS(jpu_pm_ops, jpu_suspend, jpu_resume); 1721 1722static struct platform_driver jpu_driver = { 1723 .probe = jpu_probe, 1724 .remove = jpu_remove, 1725 .driver = { 1726 .of_match_table = jpu_dt_ids, 1727 .name = DRV_NAME, 1728 .pm = pm_sleep_ptr(&jpu_pm_ops), 1729 }, 1730}; 1731 1732module_platform_driver(jpu_driver); 1733 1734MODULE_ALIAS("platform:" DRV_NAME); 1735MODULE_AUTHOR("Mikhail Ulianov"); 1736MODULE_DESCRIPTION("Renesas R-Car JPEG processing unit driver"); 1737MODULE_LICENSE("GPL v2");
~/
Read-only file preview.