FILE
mxc-jpeg.c
File preview with syntax highlighting.
linux-6.19.14/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * V4L2 driver for the JPEG encoder/decoder from i.MX8QXP/i.MX8QM application 4 * processors. 5 * 6 * The multi-planar buffers API is used. 7 * 8 * Baseline and extended sequential jpeg decoding is supported. 9 * Progressive jpeg decoding is not supported by the IP. 10 * Supports encode and decode of various formats: 11 * YUV444, YUV422, YUV420, BGR, ABGR, Gray 12 * YUV420 is the only multi-planar format supported. 13 * Minimum resolution is 64 x 64, maximum 8192 x 8192. 14 * To achieve 8192 x 8192, modify in defconfig: CONFIG_CMA_SIZE_MBYTES=320 15 * The alignment requirements for the resolution depend on the format, 16 * multiple of 16 resolutions should work for all formats. 17 * Special workarounds are made in the driver to support NV12 1080p. 18 * When decoding, the driver detects image resolution and pixel format 19 * from the jpeg stream, by parsing the jpeg markers. 20 * 21 * The IP has 4 slots available for context switching, but only slot 0 22 * was fully tested to work. Context switching is not used by the driver. 23 * Each driver instance (context) allocates a slot for itself, but this 24 * is postponed until device_run, to allow unlimited opens. 25 * 26 * The driver submits jobs to the IP by setting up a descriptor for the 27 * used slot, and then validating it. The encoder has an additional descriptor 28 * for the configuration phase. The driver expects FRM_DONE interrupt from 29 * IP to mark the job as finished. 30 * 31 * The decoder IP has some limitations regarding the component ID's, 32 * but the driver works around this by replacing them in the jpeg stream. 33 * 34 * A module parameter is available for debug purpose (jpeg_tracing), to enable 35 * it, enable dynamic debug for this module and: 36 * echo 1 > /sys/module/mxc_jpeg_encdec/parameters/jpeg_tracing 37 * 38 * This is inspired by the drivers/media/platform/samsung/s5p-jpeg driver 39 * 40 * Copyright 2018-2019 NXP 41 */ 42 43#include <linux/kernel.h> 44#include <linux/module.h> 45#include <linux/io.h> 46#include <linux/clk.h> 47#include <linux/of_platform.h> 48#include <linux/platform_device.h> 49#include <linux/slab.h> 50#include <linux/irqreturn.h> 51#include <linux/interrupt.h> 52#include <linux/pm_runtime.h> 53#include <linux/pm_domain.h> 54#include <linux/string.h> 55 56#include <media/v4l2-jpeg.h> 57#include <media/v4l2-mem2mem.h> 58#include <media/v4l2-ioctl.h> 59#include <media/v4l2-common.h> 60#include <media/v4l2-event.h> 61#include <media/videobuf2-dma-contig.h> 62 63#include "mxc-jpeg-hw.h" 64#include "mxc-jpeg.h" 65 66static const struct mxc_jpeg_fmt mxc_formats[] = { 67 { 68 .name = "JPEG", 69 .fourcc = V4L2_PIX_FMT_JPEG, 70 .subsampling = -1, 71 .nc = -1, 72 .mem_planes = 1, 73 .comp_planes = 1, 74 .flags = MXC_JPEG_FMT_TYPE_ENC, 75 }, 76 { 77 .name = "BGR", /*BGR packed format*/ 78 .fourcc = V4L2_PIX_FMT_BGR24, 79 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444, 80 .nc = 3, 81 .depth = 24, 82 .mem_planes = 1, 83 .comp_planes = 1, 84 .h_align = 3, 85 .v_align = 3, 86 .flags = MXC_JPEG_FMT_TYPE_RAW, 87 .precision = 8, 88 .is_rgb = 1, 89 }, 90 { 91 .name = "BGR 12bit", /*12-bit BGR packed format*/ 92 .fourcc = V4L2_PIX_FMT_BGR48_12, 93 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444, 94 .nc = 3, 95 .depth = 36, 96 .mem_planes = 1, 97 .comp_planes = 1, 98 .h_align = 3, 99 .v_align = 3, 100 .flags = MXC_JPEG_FMT_TYPE_RAW, 101 .precision = 12, 102 .is_rgb = 1, 103 }, 104 { 105 .name = "ABGR", /* ABGR packed format */ 106 .fourcc = V4L2_PIX_FMT_ABGR32, 107 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444, 108 .nc = 4, 109 .depth = 32, 110 .mem_planes = 1, 111 .comp_planes = 1, 112 .h_align = 3, 113 .v_align = 3, 114 .flags = MXC_JPEG_FMT_TYPE_RAW, 115 .precision = 8, 116 .is_rgb = 1, 117 }, 118 { 119 .name = "ABGR 12bit", /* 12-bit ABGR packed format */ 120 .fourcc = V4L2_PIX_FMT_ABGR64_12, 121 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444, 122 .nc = 4, 123 .depth = 48, 124 .mem_planes = 1, 125 .comp_planes = 1, 126 .h_align = 3, 127 .v_align = 3, 128 .flags = MXC_JPEG_FMT_TYPE_RAW, 129 .precision = 12, 130 .is_rgb = 1, 131 }, 132 { 133 .name = "YUV420", /* 1st plane = Y, 2nd plane = UV */ 134 .fourcc = V4L2_PIX_FMT_NV12M, 135 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420, 136 .nc = 3, 137 .depth = 12, /* 6 bytes (4Y + UV) for 4 pixels */ 138 .mem_planes = 2, 139 .comp_planes = 2, /* 1 plane Y, 1 plane UV interleaved */ 140 .h_align = 4, 141 .v_align = 4, 142 .flags = MXC_JPEG_FMT_TYPE_RAW, 143 .precision = 8, 144 }, 145 { 146 .name = "YUV420", /* 1st plane = Y, 2nd plane = UV */ 147 .fourcc = V4L2_PIX_FMT_NV12, 148 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420, 149 .nc = 3, 150 .depth = 12, /* 6 bytes (4Y + UV) for 4 pixels */ 151 .mem_planes = 1, 152 .comp_planes = 2, /* 1 plane Y, 1 plane UV interleaved */ 153 .h_align = 4, 154 .v_align = 4, 155 .flags = MXC_JPEG_FMT_TYPE_RAW, 156 .precision = 8, 157 }, 158 { 159 .name = "YUV420 12bit", /* 1st plane = Y, 2nd plane = UV */ 160 .fourcc = V4L2_PIX_FMT_P012M, 161 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420, 162 .nc = 3, 163 .depth = 18, /* 6 x 12 bits (4Y + UV) for 4 pixels */ 164 .mem_planes = 2, 165 .comp_planes = 2, /* 1 plane Y, 1 plane UV interleaved */ 166 .h_align = 4, 167 .v_align = 4, 168 .flags = MXC_JPEG_FMT_TYPE_RAW, 169 .precision = 12, 170 }, 171 { 172 .name = "YUV420 12bit", /* 1st plane = Y, 2nd plane = UV */ 173 .fourcc = V4L2_PIX_FMT_P012, 174 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420, 175 .nc = 3, 176 .depth = 18, /* 6 x 12 bits (4Y + UV) for 4 pixels */ 177 .mem_planes = 1, 178 .comp_planes = 2, /* 1 plane Y, 1 plane UV interleaved */ 179 .h_align = 4, 180 .v_align = 4, 181 .flags = MXC_JPEG_FMT_TYPE_RAW, 182 .precision = 12, 183 }, 184 { 185 .name = "YUV422", /* YUYV */ 186 .fourcc = V4L2_PIX_FMT_YUYV, 187 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422, 188 .nc = 3, 189 .depth = 16, 190 .mem_planes = 1, 191 .comp_planes = 1, 192 .h_align = 4, 193 .v_align = 3, 194 .flags = MXC_JPEG_FMT_TYPE_RAW, 195 .precision = 8, 196 }, 197 { 198 .name = "YUV422 12bit", /* YUYV */ 199 .fourcc = V4L2_PIX_FMT_Y212, 200 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422, 201 .nc = 3, 202 .depth = 24, 203 .mem_planes = 1, 204 .comp_planes = 1, 205 .h_align = 4, 206 .v_align = 3, 207 .flags = MXC_JPEG_FMT_TYPE_RAW, 208 .precision = 12, 209 }, 210 { 211 .name = "YUV444", /* YUVYUV */ 212 .fourcc = V4L2_PIX_FMT_YUV24, 213 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444, 214 .nc = 3, 215 .depth = 24, 216 .mem_planes = 1, 217 .comp_planes = 1, 218 .h_align = 3, 219 .v_align = 3, 220 .flags = MXC_JPEG_FMT_TYPE_RAW, 221 .precision = 8, 222 }, 223 { 224 .name = "YUV444 12bit", /* YUVYUV */ 225 .fourcc = V4L2_PIX_FMT_YUV48_12, 226 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444, 227 .nc = 3, 228 .depth = 36, 229 .mem_planes = 1, 230 .comp_planes = 1, 231 .h_align = 3, 232 .v_align = 3, 233 .flags = MXC_JPEG_FMT_TYPE_RAW, 234 .precision = 12, 235 }, 236 { 237 .name = "Gray", /* Gray (Y8/Y12) or Single Comp */ 238 .fourcc = V4L2_PIX_FMT_GREY, 239 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY, 240 .nc = 1, 241 .depth = 8, 242 .mem_planes = 1, 243 .comp_planes = 1, 244 .h_align = 3, 245 .v_align = 3, 246 .flags = MXC_JPEG_FMT_TYPE_RAW, 247 .precision = 8, 248 }, 249 { 250 .name = "Gray 12bit", /* Gray (Y8/Y12) or Single Comp */ 251 .fourcc = V4L2_PIX_FMT_Y012, 252 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY, 253 .nc = 1, 254 .depth = 12, 255 .mem_planes = 1, 256 .comp_planes = 1, 257 .h_align = 3, 258 .v_align = 3, 259 .flags = MXC_JPEG_FMT_TYPE_RAW, 260 .precision = 12, 261 }, 262}; 263 264#define MXC_JPEG_NUM_FORMATS ARRAY_SIZE(mxc_formats) 265 266static const int mxc_decode_mode = MXC_JPEG_DECODE; 267static const int mxc_encode_mode = MXC_JPEG_ENCODE; 268 269static const struct of_device_id mxc_jpeg_match[] = { 270 { 271 .compatible = "nxp,imx8qxp-jpgdec", 272 .data = &mxc_decode_mode, 273 }, 274 { 275 .compatible = "nxp,imx8qxp-jpgenc", 276 .data = &mxc_encode_mode, 277 }, 278 { }, 279}; 280 281/* 282 * default configuration stream, 64x64 yuv422 283 * split by JPEG marker, so it's easier to modify & use 284 */ 285static const unsigned char jpeg_soi[] = { 286 0xFF, 0xD8 287}; 288 289static const unsigned char jpeg_app0[] = { 290 0xFF, 0xE0, 291 0x00, 0x10, 0x4A, 0x46, 0x49, 0x46, 0x00, 292 0x01, 0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 293 0x00, 0x00 294}; 295 296static const unsigned char jpeg_app14[] = { 297 0xFF, 0xEE, 298 0x00, 0x0E, 0x41, 0x64, 0x6F, 0x62, 0x65, 299 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00 300}; 301 302static const unsigned char jpeg_dqt[] = { 303 0xFF, 0xDB, 304 0x00, 0x84, 0x00, 0x10, 0x0B, 0x0C, 0x0E, 305 0x0C, 0x0A, 0x10, 0x0E, 0x0D, 0x0E, 0x12, 306 0x11, 0x10, 0x13, 0x18, 0x28, 0x1A, 0x18, 307 0x16, 0x16, 0x18, 0x31, 0x23, 0x25, 0x1D, 308 0x28, 0x3A, 0x33, 0x3D, 0x3C, 0x39, 0x33, 309 0x38, 0x37, 0x40, 0x48, 0x5C, 0x4E, 0x40, 310 0x44, 0x57, 0x45, 0x37, 0x38, 0x50, 0x6D, 311 0x51, 0x57, 0x5F, 0x62, 0x67, 0x68, 0x67, 312 0x3E, 0x4D, 0x71, 0x79, 0x70, 0x64, 0x78, 313 0x5C, 0x65, 0x67, 0x63, 0x01, 0x11, 0x12, 314 0x12, 0x18, 0x15, 0x18, 0x2F, 0x1A, 0x1A, 315 0x2F, 0x63, 0x42, 0x38, 0x42, 0x63, 0x63, 316 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 317 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 318 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 319 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 320 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 321 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 322 0x63, 0x63, 0x63, 0x63, 0x63, 0x63 323}; 324 325static const unsigned char jpeg_dqt_extseq[] = { 326 0xFF, 0xDB, 327 0x01, 0x04, 328 0x10, 329 0x00, 0x80, 0x00, 0x58, 0x00, 0x60, 0x00, 0x70, 330 0x00, 0x60, 0x00, 0x50, 0x00, 0x80, 0x00, 0x70, 331 0x00, 0x68, 0x00, 0x70, 0x00, 0x90, 0x00, 0x88, 332 0x00, 0x80, 0x00, 0x98, 0x00, 0xC0, 0x01, 0x40, 333 0x00, 0xD0, 0x00, 0xC0, 0x00, 0xB0, 0x00, 0xB0, 334 0x00, 0xC0, 0x01, 0x88, 0x01, 0x18, 0x01, 0x28, 335 0x00, 0xE8, 0x01, 0x40, 0x01, 0xD0, 0x01, 0x98, 336 0x01, 0xE8, 0x01, 0xE0, 0x01, 0xC8, 0x01, 0x98, 337 0x01, 0xC0, 0x01, 0xB8, 0x02, 0x00, 0x02, 0x40, 338 0x02, 0xE0, 0x02, 0x70, 0x02, 0x00, 0x02, 0x20, 339 0x02, 0xB8, 0x02, 0x28, 0x01, 0xB8, 0x01, 0xC0, 340 0x02, 0x80, 0x03, 0x68, 0x02, 0x88, 0x02, 0xB8, 341 0x02, 0xF8, 0x03, 0x10, 0x03, 0x38, 0x03, 0x40, 342 0x03, 0x38, 0x01, 0xF0, 0x02, 0x68, 0x03, 0x88, 343 0x03, 0xC8, 0x03, 0x80, 0x03, 0x20, 0x03, 0xC0, 344 0x02, 0xE0, 0x03, 0x28, 0x03, 0x38, 0x03, 0x18, 345 0x11, 346 0x00, 0x88, 0x00, 0x90, 0x00, 0x90, 0x00, 0xC0, 347 0x00, 0xA8, 0x00, 0xC0, 0x01, 0x78, 0x00, 0xD0, 348 0x00, 0xD0, 0x01, 0x78, 0x03, 0x18, 0x02, 0x10, 349 0x01, 0xC0, 0x02, 0x10, 0x03, 0x18, 0x03, 0x18, 350 0x03, 0x18, 0x03, 0x18, 0x03, 0x18, 0x03, 0x18, 351 0x03, 0x18, 0x03, 0x18, 0x03, 0x18, 0x03, 0x18, 352 0x03, 0x18, 0x03, 0x18, 0x03, 0x18, 0x03, 0x18, 353 0x03, 0x18, 0x03, 0x18, 0x03, 0x18, 0x03, 0x18, 354 0x03, 0x18, 0x03, 0x18, 0x03, 0x18, 0x03, 0x18, 355 0x03, 0x18, 0x03, 0x18, 0x03, 0x18, 0x03, 0x18, 356 0x03, 0x18, 0x03, 0x18, 0x03, 0x18, 0x03, 0x18, 357 0x03, 0x18, 0x03, 0x18, 0x03, 0x18, 0x03, 0x18, 358 0x03, 0x18, 0x03, 0x18, 0x03, 0x18, 0x03, 0x18, 359 0x03, 0x18, 0x03, 0x18, 0x03, 0x18, 0x03, 0x18, 360 0x03, 0x18, 0x03, 0x18, 0x03, 0x18, 0x03, 0x18, 361 0x03, 0x18, 0x03, 0x18, 0x03, 0x18, 0x03, 0x18, 362}; 363 364static const unsigned char jpeg_sof_maximal[] = { 365 0xFF, 0xC0, 366 0x00, 0x14, 0x08, 0x00, 0x40, 0x00, 0x40, 367 0x04, 0x01, 0x11, 0x00, 0x02, 0x11, 0x01, 368 0x03, 0x11, 0x01, 0x04, 0x11, 0x01 369}; 370 371static const unsigned char jpeg_sof_extseq[] = { 372 0xFF, 0xC1, 373 0x00, 0x14, 0x08, 0x00, 0x40, 0x00, 0x40, 374 0x04, 0x01, 0x11, 0x00, 0x02, 0x11, 0x01, 375 0x03, 0x11, 0x01, 0x04, 0x11, 0x01 376}; 377 378static const unsigned char jpeg_dht[] = { 379 0xFF, 0xC4, 380 0x01, 0xA2, 0x00, 0x00, 0x01, 0x05, 0x01, 381 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 382 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 383 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 384 0x09, 0x0A, 0x0B, 0x10, 0x00, 0x02, 0x01, 385 0x03, 0x03, 0x02, 0x04, 0x03, 0x05, 0x05, 386 0x04, 0x04, 0x00, 0x00, 0x01, 0x7D, 0x01, 387 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 388 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 389 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 390 0xA1, 0x08, 0x23, 0x42, 0xB1, 0xC1, 0x15, 391 0x52, 0xD1, 0xF0, 0x24, 0x33, 0x62, 0x72, 392 0x82, 0x09, 0x0A, 0x16, 0x17, 0x18, 0x19, 393 0x1A, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 394 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 395 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 396 0x4A, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 397 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66, 0x67, 398 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 399 0x77, 0x78, 0x79, 0x7A, 0x83, 0x84, 0x85, 400 0x86, 0x87, 0x88, 0x89, 0x8A, 0x92, 0x93, 401 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 402 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 403 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 404 0xB7, 0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 405 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xD2, 406 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 407 0xDA, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 408 0xE7, 0xE8, 0xE9, 0xEA, 0xF1, 0xF2, 0xF3, 409 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 410 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 411 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 412 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 413 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 414 0x0B, 0x11, 0x00, 0x02, 0x01, 0x02, 0x04, 415 0x04, 0x03, 0x04, 0x07, 0x05, 0x04, 0x04, 416 0x00, 0x01, 0x02, 0x77, 0x00, 0x01, 0x02, 417 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 418 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, 0x13, 419 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 420 0xA1, 0xB1, 0xC1, 0x09, 0x23, 0x33, 0x52, 421 0xF0, 0x15, 0x62, 0x72, 0xD1, 0x0A, 0x16, 422 0x24, 0x34, 0xE1, 0x25, 0xF1, 0x17, 0x18, 423 0x19, 0x1A, 0x26, 0x27, 0x28, 0x29, 0x2A, 424 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 425 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 426 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 427 0x5A, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 428 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 429 0x78, 0x79, 0x7A, 0x82, 0x83, 0x84, 0x85, 430 0x86, 0x87, 0x88, 0x89, 0x8A, 0x92, 0x93, 431 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 432 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 433 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 434 0xB7, 0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 435 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xD2, 436 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 437 0xDA, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 438 0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4, 0xF5, 439 0xF6, 0xF7, 0xF8, 0xF9, 0xFA 440}; 441 442static const unsigned char jpeg_dht_extseq[] = { 443 0xFF, 0xC4, 444 0x02, 0x2a, 0x00, 0x00, 0x01, 0x05, 0x01, 445 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 446 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 447 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 448 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 449 0x10, 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 450 0x04, 0x03, 0x05, 0x05, 0x02, 0x03, 0x02, 451 0x00, 0x00, 0xbf, 0x01, 0x02, 0x03, 0x00, 452 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 453 0x06, 0x13, 0x51, 0x61, 0x07, 0x22, 0x71, 454 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, 0x23, 455 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, 456 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 457 0x16, 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 458 0x27, 0x28, 0x29, 0x2a, 0x34, 0x35, 0x36, 459 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 460 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 461 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 462 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 463 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 464 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 465 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 466 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 467 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 468 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 469 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 470 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 471 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, 472 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 473 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 474 0xf7, 0xf8, 0xf9, 0xfa, 0x0b, 0x0c, 0x0d, 475 0x0e, 0x1b, 0x1c, 0x1d, 0x1e, 0x2b, 0x2c, 476 0x2d, 0x2e, 0x3b, 0x3c, 0x3d, 0x3e, 0x4b, 477 0x4c, 0x4d, 0x4e, 0x5b, 0x5c, 0x5d, 0x5e, 478 0x6b, 0x6c, 0x6d, 0x6e, 0x7b, 0x7c, 0x7d, 479 0x7e, 0x8b, 0x8c, 0x8d, 0x8e, 0x9b, 0x9c, 480 0x9d, 0x9e, 0xab, 0xac, 0xad, 0xae, 0xbb, 481 0xbc, 0xbd, 0xbe, 0xcb, 0xcc, 0xcd, 0xce, 482 0xdb, 0xdc, 0xdd, 0xde, 0xeb, 0xec, 0xed, 483 0xee, 0xfb, 0xfc, 0xfd, 0xfe, 0x01, 0x00, 484 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 485 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 486 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 487 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 488 0x0d, 0x0e, 0x0f, 0x11, 0x00, 0x02, 0x01, 489 0x03, 0x03, 0x02, 0x04, 0x03, 0x05, 0x05, 490 0x02, 0x03, 0x02, 0x00, 0x00, 0xbf, 0x01, 491 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 492 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 493 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 494 0xa1, 0x08, 0x23, 0x42, 0xb1, 0xc1, 0x15, 495 0x52, 0xd1, 0xf0, 0x24, 0x33, 0x62, 0x72, 496 0x82, 0x09, 0x0a, 0x16, 0x17, 0x18, 0x19, 497 0x1a, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 498 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 499 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 500 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 501 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 502 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 503 0x77, 0x78, 0x79, 0x7a, 0x83, 0x84, 0x85, 504 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 505 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 506 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 507 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 508 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 509 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 510 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 511 0xda, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 512 0xe7, 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 513 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 514 0x0b, 0x0c, 0x0d, 0x0e, 0x1b, 0x1c, 0x1d, 515 0x1e, 0x2b, 0x2c, 0x2d, 0x2e, 0x3b, 0x3c, 516 0x3d, 0x3e, 0x4b, 0x4c, 0x4d, 0x4e, 0x5b, 517 0x5c, 0x5d, 0x5e, 0x6b, 0x6c, 0x6d, 0x6e, 518 0x7b, 0x7c, 0x7d, 0x7e, 0x8b, 0x8c, 0x8d, 519 0x8e, 0x9b, 0x9c, 0x9d, 0x9e, 0xab, 0xac, 520 0xad, 0xae, 0xbb, 0xbc, 0xbd, 0xbe, 0xcb, 521 0xcc, 0xcd, 0xce, 0xdb, 0xdc, 0xdd, 0xde, 522 0xeb, 0xec, 0xed, 0xee, 0xfb, 0xfc, 0xfd, 523 0xfe, 524}; 525 526static const unsigned char jpeg_dri[] = { 527 0xFF, 0xDD, 528 0x00, 0x04, 0x00, 0x20 529}; 530 531static const unsigned char jpeg_sos_maximal[] = { 532 0xFF, 0xDA, 533 0x00, 0x0C, 0x04, 0x01, 0x00, 0x02, 0x11, 0x03, 534 0x11, 0x04, 0x11, 0x00, 0x3F, 0x00 535}; 536 537static const unsigned char jpeg_image_red[] = { 538 0xF9, 0xFE, 0x8A, 0xFC, 0x34, 0xFD, 0xC4, 0x28, 539 0xA0, 0x02, 0x8A, 0x00, 0x28, 0xA0, 0x02, 0x8A, 540 0x00, 0x28, 0xA0, 0x02, 0x8A, 0x00, 0x28, 0xA0, 541 0x02, 0x8A, 0x00, 0x28, 0xA0, 0x02, 0x8A, 0x00, 542 0x28, 0xA0, 0x02, 0x8A, 0x00, 0x28, 0xA0, 0x02, 543 0x8A, 0x00, 0x28, 0xA0, 0x02, 0x8A, 0x00, 0x28, 544 0xA0, 0x02, 0x8A, 0x00, 0x28, 0xA0, 0x02, 0x8A, 545 0x00, 0x28, 0xA0, 0x02, 0x8A, 0x00, 0x28, 0xA0, 546 0x02, 0x8A, 0x00, 0x28, 0xA0, 0x02, 0x8A, 0x00, 547 0x28, 0xA0, 0x02, 0x8A, 0x00, 0x28, 0xA0, 0x02, 548 0x8A, 0x00, 0x28, 0xA0, 0x0F, 0xFF, 0xD0, 0xF9, 549 0xFE, 0x8A, 0xFC, 0x34, 0xFD, 0xC4, 0x28, 0xA0, 550 0x02, 0x8A, 0x00, 0x28, 0xA0, 0x02, 0x8A, 0x00, 551 0x28, 0xA0, 0x02, 0x8A, 0x00, 0x28, 0xA0, 0x02, 552 0x8A, 0x00, 0x28, 0xA0, 0x02, 0x8A, 0x00, 0x28, 553 0xA0, 0x02, 0x8A, 0x00, 0x28, 0xA0, 0x02, 0x8A, 554 0x00, 0x28, 0xA0, 0x02, 0x8A, 0x00, 0x28, 0xA0, 555 0x02, 0x8A, 0x00, 0x28, 0xA0, 0x02, 0x8A, 0x00, 556 0x28, 0xA0, 0x02, 0x8A, 0x00, 0x28, 0xA0, 0x02, 557 0x8A, 0x00, 0x28, 0xA0, 0x02, 0x8A, 0x00, 0x28, 558 0xA0, 0x02, 0x8A, 0x00, 0x28, 0xA0, 0x02, 0x8A, 559 0x00, 0x28, 0xA0, 0x0F 560}; 561 562static const unsigned char jpeg_eoi[] = { 563 0xFF, 0xD9 564}; 565 566struct mxc_jpeg_src_buf { 567 /* common v4l buffer stuff -- must be first */ 568 struct vb2_v4l2_buffer b; 569 struct list_head list; 570 571 /* mxc-jpeg specific */ 572 bool dht_needed; 573 bool jpeg_parse_error; 574 const struct mxc_jpeg_fmt *fmt; 575 int w; 576 int h; 577}; 578 579static inline struct mxc_jpeg_src_buf *vb2_to_mxc_buf(struct vb2_buffer *vb) 580{ 581 return container_of(to_vb2_v4l2_buffer(vb), 582 struct mxc_jpeg_src_buf, b); 583} 584 585static unsigned int debug; 586module_param(debug, int, 0644); 587MODULE_PARM_DESC(debug, "Debug level (0-3)"); 588 589static unsigned int hw_timeout = 2000; 590module_param(hw_timeout, int, 0644); 591MODULE_PARM_DESC(hw_timeout, "MXC JPEG hw timeout, the number of milliseconds"); 592 593static void mxc_jpeg_bytesperline(struct mxc_jpeg_q_data *q, u32 precision); 594static void mxc_jpeg_sizeimage(struct mxc_jpeg_q_data *q); 595 596static void _bswap16(u16 *a) 597{ 598 *a = ((*a & 0x00FF) << 8) | ((*a & 0xFF00) >> 8); 599} 600 601static dma_addr_t mxc_jpeg_get_plane_dma_addr(struct vb2_buffer *buf, unsigned int plane_no) 602{ 603 if (plane_no >= buf->num_planes) 604 return 0; 605 return vb2_dma_contig_plane_dma_addr(buf, plane_no) + buf->planes[plane_no].data_offset; 606} 607 608static void *mxc_jpeg_get_plane_vaddr(struct vb2_buffer *buf, unsigned int plane_no) 609{ 610 if (plane_no >= buf->num_planes) 611 return NULL; 612 return vb2_plane_vaddr(buf, plane_no) + buf->planes[plane_no].data_offset; 613} 614 615static unsigned long mxc_jpeg_get_plane_payload(struct vb2_buffer *buf, unsigned int plane_no) 616{ 617 if (plane_no >= buf->num_planes) 618 return 0; 619 return vb2_get_plane_payload(buf, plane_no) - buf->planes[plane_no].data_offset; 620} 621 622static void print_mxc_buf(struct mxc_jpeg_dev *jpeg, struct vb2_buffer *buf, 623 unsigned long len) 624{ 625 unsigned int plane_no; 626 u32 dma_addr; 627 void *vaddr; 628 unsigned long payload; 629 630 if (debug < 3) 631 return; 632 633 for (plane_no = 0; plane_no < buf->num_planes; plane_no++) { 634 payload = mxc_jpeg_get_plane_payload(buf, plane_no); 635 if (len == 0) 636 len = payload; 637 dma_addr = mxc_jpeg_get_plane_dma_addr(buf, plane_no); 638 vaddr = mxc_jpeg_get_plane_vaddr(buf, plane_no); 639 v4l2_dbg(3, debug, &jpeg->v4l2_dev, 640 "plane %d (vaddr=%p dma_addr=%x payload=%ld):", 641 plane_no, vaddr, dma_addr, payload); 642 print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, 643 vaddr, len, false); 644 } 645} 646 647static inline struct mxc_jpeg_ctx *mxc_jpeg_file_to_ctx(struct file *filp) 648{ 649 return container_of(file_to_v4l2_fh(filp), struct mxc_jpeg_ctx, fh); 650} 651 652static int enum_fmt(const struct mxc_jpeg_fmt *mxc_formats, int n, 653 struct v4l2_fmtdesc *f, u32 type) 654{ 655 int i, num = 0; 656 657 for (i = 0; i < n; ++i) { 658 if (mxc_formats[i].flags == type) { 659 /* index-th format of searched type found ? */ 660 if (num == f->index) 661 break; 662 /* Correct type but haven't reached our index yet, 663 * just increment per-type index 664 */ 665 ++num; 666 } 667 } 668 669 /* Format not found */ 670 if (i >= n) 671 return -EINVAL; 672 673 f->pixelformat = mxc_formats[i].fourcc; 674 675 return 0; 676} 677 678static const struct mxc_jpeg_fmt *mxc_jpeg_find_format(u32 pixelformat) 679{ 680 unsigned int k; 681 682 for (k = 0; k < MXC_JPEG_NUM_FORMATS; k++) { 683 const struct mxc_jpeg_fmt *fmt = &mxc_formats[k]; 684 685 if (fmt->fourcc == pixelformat) 686 return fmt; 687 } 688 return NULL; 689} 690 691static enum mxc_jpeg_image_format mxc_jpeg_fourcc_to_imgfmt(u32 fourcc) 692{ 693 switch (fourcc) { 694 case V4L2_PIX_FMT_GREY: 695 case V4L2_PIX_FMT_Y012: 696 return MXC_JPEG_GRAY; 697 case V4L2_PIX_FMT_YUYV: 698 case V4L2_PIX_FMT_Y212: 699 return MXC_JPEG_YUV422; 700 case V4L2_PIX_FMT_NV12: 701 case V4L2_PIX_FMT_NV12M: 702 case V4L2_PIX_FMT_P012: 703 case V4L2_PIX_FMT_P012M: 704 return MXC_JPEG_YUV420; 705 case V4L2_PIX_FMT_YUV24: 706 case V4L2_PIX_FMT_YUV48_12: 707 return MXC_JPEG_YUV444; 708 case V4L2_PIX_FMT_BGR24: 709 case V4L2_PIX_FMT_BGR48_12: 710 return MXC_JPEG_BGR; 711 case V4L2_PIX_FMT_ABGR32: 712 case V4L2_PIX_FMT_ABGR64_12: 713 return MXC_JPEG_ABGR; 714 default: 715 return MXC_JPEG_INVALID; 716 } 717} 718 719static struct mxc_jpeg_q_data *mxc_jpeg_get_q_data(struct mxc_jpeg_ctx *ctx, 720 enum v4l2_buf_type type) 721{ 722 if (V4L2_TYPE_IS_OUTPUT(type)) 723 return &ctx->out_q; 724 return &ctx->cap_q; 725} 726 727static void mxc_jpeg_addrs(struct mxc_jpeg_desc *desc, 728 struct vb2_buffer *raw_buf, 729 struct vb2_buffer *jpeg_buf, int offset) 730{ 731 int img_fmt = desc->stm_ctrl & STM_CTRL_IMAGE_FORMAT_MASK; 732 struct mxc_jpeg_ctx *ctx = vb2_get_drv_priv(raw_buf->vb2_queue); 733 struct mxc_jpeg_q_data *q_data; 734 735 q_data = mxc_jpeg_get_q_data(ctx, raw_buf->type); 736 desc->buf_base0 = mxc_jpeg_get_plane_dma_addr(raw_buf, 0); 737 desc->buf_base1 = 0; 738 if (img_fmt == STM_CTRL_IMAGE_FORMAT(MXC_JPEG_YUV420)) { 739 if (raw_buf->num_planes == 2) 740 desc->buf_base1 = mxc_jpeg_get_plane_dma_addr(raw_buf, 1); 741 else 742 desc->buf_base1 = desc->buf_base0 + q_data->sizeimage[0]; 743 } 744 desc->stm_bufbase = mxc_jpeg_get_plane_dma_addr(jpeg_buf, 0) + offset; 745} 746 747static bool mxc_jpeg_is_extended_sequential(const struct mxc_jpeg_fmt *fmt) 748{ 749 if (!fmt || !(fmt->flags & MXC_JPEG_FMT_TYPE_RAW)) 750 return false; 751 752 if (fmt->precision > 8) 753 return true; 754 755 return false; 756} 757 758static void notify_eos(struct mxc_jpeg_ctx *ctx) 759{ 760 const struct v4l2_event ev = { 761 .type = V4L2_EVENT_EOS 762 }; 763 764 dev_dbg(ctx->mxc_jpeg->dev, "Notify app event EOS reached"); 765 v4l2_event_queue_fh(&ctx->fh, &ev); 766} 767 768static void notify_src_chg(struct mxc_jpeg_ctx *ctx) 769{ 770 const struct v4l2_event ev = { 771 .type = V4L2_EVENT_SOURCE_CHANGE, 772 .u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION, 773 }; 774 775 dev_dbg(ctx->mxc_jpeg->dev, "Notify app event SRC_CH_RESOLUTION"); 776 v4l2_event_queue_fh(&ctx->fh, &ev); 777} 778 779static int mxc_get_free_slot(struct mxc_jpeg_slot_data *slot_data) 780{ 781 if (!slot_data->used) 782 return slot_data->slot; 783 return -1; 784} 785 786static void mxc_jpeg_free_slot_data(struct mxc_jpeg_dev *jpeg) 787{ 788 /* free descriptor for decoding/encoding phase */ 789 dma_free_coherent(jpeg->dev, sizeof(struct mxc_jpeg_desc), 790 jpeg->slot_data.desc, 791 jpeg->slot_data.desc_handle); 792 jpeg->slot_data.desc = NULL; 793 jpeg->slot_data.desc_handle = 0; 794 795 /* free descriptor for encoder configuration phase / decoder DHT */ 796 dma_free_coherent(jpeg->dev, sizeof(struct mxc_jpeg_desc), 797 jpeg->slot_data.cfg_desc, 798 jpeg->slot_data.cfg_desc_handle); 799 jpeg->slot_data.cfg_desc_handle = 0; 800 jpeg->slot_data.cfg_desc = NULL; 801 802 /* free configuration stream */ 803 dma_free_coherent(jpeg->dev, MXC_JPEG_MAX_CFG_STREAM, 804 jpeg->slot_data.cfg_stream_vaddr, 805 jpeg->slot_data.cfg_stream_handle); 806 jpeg->slot_data.cfg_stream_vaddr = NULL; 807 jpeg->slot_data.cfg_stream_handle = 0; 808 809 dma_free_coherent(jpeg->dev, jpeg->slot_data.cfg_dec_size, 810 jpeg->slot_data.cfg_dec_vaddr, 811 jpeg->slot_data.cfg_dec_daddr); 812 jpeg->slot_data.cfg_dec_size = 0; 813 jpeg->slot_data.cfg_dec_vaddr = NULL; 814 jpeg->slot_data.cfg_dec_daddr = 0; 815 816 jpeg->slot_data.used = false; 817} 818 819static bool mxc_jpeg_alloc_slot_data(struct mxc_jpeg_dev *jpeg) 820{ 821 struct mxc_jpeg_desc *desc; 822 struct mxc_jpeg_desc *cfg_desc; 823 void *cfg_stm; 824 825 if (jpeg->slot_data.desc) 826 goto skip_alloc; /* already allocated, reuse it */ 827 828 /* allocate descriptor for decoding/encoding phase */ 829 desc = dma_alloc_coherent(jpeg->dev, 830 sizeof(struct mxc_jpeg_desc), 831 &jpeg->slot_data.desc_handle, 832 GFP_ATOMIC); 833 if (!desc) 834 goto err; 835 jpeg->slot_data.desc = desc; 836 837 /* allocate descriptor for configuration phase (encoder only) */ 838 cfg_desc = dma_alloc_coherent(jpeg->dev, 839 sizeof(struct mxc_jpeg_desc), 840 &jpeg->slot_data.cfg_desc_handle, 841 GFP_ATOMIC); 842 if (!cfg_desc) 843 goto err; 844 jpeg->slot_data.cfg_desc = cfg_desc; 845 846 /* allocate configuration stream */ 847 cfg_stm = dma_alloc_coherent(jpeg->dev, 848 MXC_JPEG_MAX_CFG_STREAM, 849 &jpeg->slot_data.cfg_stream_handle, 850 GFP_ATOMIC); 851 if (!cfg_stm) 852 goto err; 853 jpeg->slot_data.cfg_stream_vaddr = cfg_stm; 854 855 jpeg->slot_data.cfg_dec_size = MXC_JPEG_PATTERN_WIDTH * MXC_JPEG_PATTERN_HEIGHT * 2; 856 jpeg->slot_data.cfg_dec_vaddr = dma_alloc_coherent(jpeg->dev, 857 jpeg->slot_data.cfg_dec_size, 858 &jpeg->slot_data.cfg_dec_daddr, 859 GFP_ATOMIC); 860 if (!jpeg->slot_data.cfg_dec_vaddr) 861 goto err; 862 863skip_alloc: 864 jpeg->slot_data.used = true; 865 866 return true; 867err: 868 dev_err(jpeg->dev, "Could not allocate descriptors for slot %d", jpeg->slot_data.slot); 869 mxc_jpeg_free_slot_data(jpeg); 870 871 return false; 872} 873 874static void mxc_jpeg_check_and_set_last_buffer(struct mxc_jpeg_ctx *ctx, 875 struct vb2_v4l2_buffer *src_buf, 876 struct vb2_v4l2_buffer *dst_buf) 877{ 878 if (v4l2_m2m_is_last_draining_src_buf(ctx->fh.m2m_ctx, src_buf)) { 879 dst_buf->flags |= V4L2_BUF_FLAG_LAST; 880 v4l2_m2m_mark_stopped(ctx->fh.m2m_ctx); 881 notify_eos(ctx); 882 ctx->header_parsed = false; 883 } 884} 885 886static void mxc_jpeg_job_finish(struct mxc_jpeg_ctx *ctx, enum vb2_buffer_state state, bool reset) 887{ 888 struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg; 889 void __iomem *reg = jpeg->base_reg; 890 struct vb2_v4l2_buffer *src_buf, *dst_buf; 891 892 dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); 893 src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); 894 mxc_jpeg_check_and_set_last_buffer(ctx, src_buf, dst_buf); 895 v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); 896 v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); 897 v4l2_m2m_buf_done(src_buf, state); 898 v4l2_m2m_buf_done(dst_buf, state); 899 900 mxc_jpeg_disable_irq(reg, ctx->slot); 901 jpeg->slot_data.used = false; 902 if (reset) 903 mxc_jpeg_sw_reset(reg); 904} 905 906static u32 mxc_jpeg_get_plane_size(struct mxc_jpeg_q_data *q_data, u32 plane_no) 907{ 908 const struct mxc_jpeg_fmt *fmt = q_data->fmt; 909 u32 size; 910 int i; 911 912 if (plane_no >= fmt->mem_planes) 913 return 0; 914 915 if (fmt->mem_planes == fmt->comp_planes) 916 return q_data->sizeimage[plane_no]; 917 918 if (plane_no < fmt->mem_planes - 1) 919 return q_data->sizeimage[plane_no]; 920 921 size = q_data->sizeimage[fmt->mem_planes - 1]; 922 923 /* Should be impossible given mxc_formats. */ 924 if (WARN_ON_ONCE(fmt->comp_planes > ARRAY_SIZE(q_data->sizeimage))) 925 return size; 926 927 for (i = fmt->mem_planes; i < fmt->comp_planes; i++) 928 size += q_data->sizeimage[i]; 929 930 return size; 931} 932 933static bool mxc_dec_is_ongoing(struct mxc_jpeg_ctx *ctx) 934{ 935 struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg; 936 u32 curr_desc; 937 u32 slot_status; 938 939 curr_desc = readl(jpeg->base_reg + MXC_SLOT_OFFSET(ctx->slot, SLOT_CUR_DESCPT_PTR)); 940 if (curr_desc == jpeg->slot_data.cfg_desc_handle) 941 return true; 942 943 slot_status = readl(jpeg->base_reg + MXC_SLOT_OFFSET(ctx->slot, SLOT_STATUS)); 944 if (slot_status & SLOT_STATUS_ONGOING) 945 return true; 946 947 /* 948 * The curr_desc register is updated when next_descpt_ptr is loaded, 949 * the ongoing bit of slot_status is set when the 32 bytes descriptor is loaded. 950 * So there will be a short time interval in between, which may cause fake false. 951 * Consider read register is quite slow compared with IP read 32byte from memory, 952 * read twice slot_status can avoid this situation. 953 */ 954 slot_status = readl(jpeg->base_reg + MXC_SLOT_OFFSET(ctx->slot, SLOT_STATUS)); 955 if (slot_status & SLOT_STATUS_ONGOING) 956 return true; 957 958 return false; 959} 960 961static irqreturn_t mxc_jpeg_dec_irq(int irq, void *priv) 962{ 963 struct mxc_jpeg_dev *jpeg = priv; 964 struct mxc_jpeg_ctx *ctx; 965 void __iomem *reg = jpeg->base_reg; 966 struct device *dev = jpeg->dev; 967 struct vb2_v4l2_buffer *src_buf, *dst_buf; 968 struct mxc_jpeg_src_buf *jpeg_src_buf; 969 enum vb2_buffer_state buf_state; 970 u32 dec_ret, com_status; 971 unsigned long payload; 972 struct mxc_jpeg_q_data *q_data; 973 enum v4l2_buf_type cap_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 974 unsigned int slot; 975 976 spin_lock(&jpeg->hw_lock); 977 978 com_status = readl(reg + COM_STATUS); 979 slot = COM_STATUS_CUR_SLOT(com_status); 980 dev_dbg(dev, "Irq %d on slot %d.\n", irq, slot); 981 982 ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev); 983 if (WARN_ON(!ctx)) 984 goto job_unlock; 985 986 if (slot != ctx->slot) { 987 /* TODO investigate when adding multi-instance support */ 988 dev_warn(dev, "IRQ slot %d != context slot %d.\n", 989 slot, ctx->slot); 990 goto job_unlock; 991 } 992 993 if (!jpeg->slot_data.used) 994 goto job_unlock; 995 996 dec_ret = readl(reg + MXC_SLOT_OFFSET(slot, SLOT_STATUS)); 997 writel(dec_ret, reg + MXC_SLOT_OFFSET(slot, SLOT_STATUS)); /* w1c */ 998 999 dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); 1000 src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); 1001 if (!dst_buf || !src_buf) { 1002 dev_err(dev, "No source or destination buffer.\n"); 1003 goto job_unlock; 1004 } 1005 jpeg_src_buf = vb2_to_mxc_buf(&src_buf->vb2_buf); 1006 1007 if (dec_ret & SLOT_STATUS_ENC_CONFIG_ERR) { 1008 u32 ret = readl(reg + CAST_STATUS12); 1009 1010 dev_err(dev, "Encoder/decoder error, dec_ret = 0x%08x, status=0x%08x", 1011 dec_ret, ret); 1012 mxc_jpeg_clr_desc(reg, slot); 1013 mxc_jpeg_sw_reset(reg); 1014 buf_state = VB2_BUF_STATE_ERROR; 1015 goto buffers_done; 1016 } 1017 1018 if (!(dec_ret & SLOT_STATUS_FRMDONE)) 1019 goto job_unlock; 1020 1021 if (jpeg->mode == MXC_JPEG_ENCODE && 1022 ctx->enc_state == MXC_JPEG_ENC_CONF) { 1023 q_data = mxc_jpeg_get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 1024 ctx->enc_state = MXC_JPEG_ENCODING; 1025 dev_dbg(dev, "Encoder config finished. Start encoding...\n"); 1026 mxc_jpeg_enc_set_quality(dev, reg, ctx->jpeg_quality); 1027 mxc_jpeg_enc_mode_go(dev, reg, mxc_jpeg_is_extended_sequential(q_data->fmt)); 1028 goto job_unlock; 1029 } 1030 if (jpeg->mode == MXC_JPEG_DECODE && jpeg_src_buf->dht_needed && 1031 mxc_dec_is_ongoing(ctx)) { 1032 jpeg_src_buf->dht_needed = false; 1033 dev_dbg(dev, "Decoder DHT cfg finished. Start decoding...\n"); 1034 goto job_unlock; 1035 } 1036 1037 if (jpeg->mode == MXC_JPEG_ENCODE) { 1038 payload = readl(reg + MXC_SLOT_OFFSET(slot, SLOT_BUF_PTR)); 1039 vb2_set_plane_payload(&dst_buf->vb2_buf, 0, payload); 1040 dev_dbg(dev, "Encoding finished, payload size: %ld\n", 1041 payload); 1042 } else { 1043 q_data = mxc_jpeg_get_q_data(ctx, cap_type); 1044 payload = mxc_jpeg_get_plane_size(q_data, 0); 1045 vb2_set_plane_payload(&dst_buf->vb2_buf, 0, payload); 1046 vb2_set_plane_payload(&dst_buf->vb2_buf, 1, 0); 1047 if (q_data->fmt->mem_planes == 2) { 1048 payload = mxc_jpeg_get_plane_size(q_data, 1); 1049 vb2_set_plane_payload(&dst_buf->vb2_buf, 1, payload); 1050 } 1051 dev_dbg(dev, "Decoding finished, payload size: %ld + %ld\n", 1052 mxc_jpeg_get_plane_payload(&dst_buf->vb2_buf, 0), 1053 mxc_jpeg_get_plane_payload(&dst_buf->vb2_buf, 1)); 1054 } 1055 1056 /* short preview of the results */ 1057 dev_dbg(dev, "src_buf preview: "); 1058 print_mxc_buf(jpeg, &src_buf->vb2_buf, 32); 1059 dev_dbg(dev, "dst_buf preview: "); 1060 print_mxc_buf(jpeg, &dst_buf->vb2_buf, 32); 1061 buf_state = VB2_BUF_STATE_DONE; 1062 1063buffers_done: 1064 mxc_jpeg_job_finish(ctx, buf_state, false); 1065 spin_unlock(&jpeg->hw_lock); 1066 cancel_delayed_work(&ctx->task_timer); 1067 v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx); 1068 return IRQ_HANDLED; 1069job_unlock: 1070 spin_unlock(&jpeg->hw_lock); 1071 return IRQ_HANDLED; 1072} 1073 1074static int mxc_jpeg_fixup_sof(struct mxc_jpeg_sof *sof, 1075 u32 fourcc, 1076 u16 w, u16 h) 1077{ 1078 int sof_length; 1079 const struct mxc_jpeg_fmt *fmt = mxc_jpeg_find_format(fourcc); 1080 1081 if (fmt) 1082 sof->precision = fmt->precision; 1083 else 1084 sof->precision = 8; /* TODO allow 8/12 bit precision*/ 1085 sof->height = h; 1086 _bswap16(&sof->height); 1087 sof->width = w; 1088 _bswap16(&sof->width); 1089 1090 switch (fourcc) { 1091 case V4L2_PIX_FMT_NV12: 1092 case V4L2_PIX_FMT_NV12M: 1093 case V4L2_PIX_FMT_P012: 1094 case V4L2_PIX_FMT_P012M: 1095 sof->components_no = 3; 1096 sof->comp[0].v = 0x2; 1097 sof->comp[0].h = 0x2; 1098 break; 1099 case V4L2_PIX_FMT_YUYV: 1100 case V4L2_PIX_FMT_Y212: 1101 sof->components_no = 3; 1102 sof->comp[0].v = 0x1; 1103 sof->comp[0].h = 0x2; 1104 break; 1105 case V4L2_PIX_FMT_YUV24: 1106 case V4L2_PIX_FMT_YUV48_12: 1107 case V4L2_PIX_FMT_BGR24: 1108 case V4L2_PIX_FMT_BGR48_12: 1109 default: 1110 sof->components_no = 3; 1111 break; 1112 case V4L2_PIX_FMT_ABGR32: 1113 case V4L2_PIX_FMT_ABGR64_12: 1114 sof->components_no = 4; 1115 break; 1116 case V4L2_PIX_FMT_GREY: 1117 case V4L2_PIX_FMT_Y012: 1118 sof->components_no = 1; 1119 break; 1120 } 1121 sof_length = 8 + 3 * sof->components_no; 1122 sof->length = sof_length; 1123 _bswap16(&sof->length); 1124 1125 return sof_length; /* not swaped */ 1126} 1127 1128static int mxc_jpeg_fixup_sos(struct mxc_jpeg_sos *sos, 1129 u32 fourcc) 1130{ 1131 int sos_length; 1132 u8 *sof_u8 = (u8 *)sos; 1133 1134 switch (fourcc) { 1135 case V4L2_PIX_FMT_NV12: 1136 case V4L2_PIX_FMT_NV12M: 1137 case V4L2_PIX_FMT_P012: 1138 case V4L2_PIX_FMT_P012M: 1139 sos->components_no = 3; 1140 break; 1141 case V4L2_PIX_FMT_YUYV: 1142 case V4L2_PIX_FMT_Y212: 1143 sos->components_no = 3; 1144 break; 1145 case V4L2_PIX_FMT_YUV24: 1146 case V4L2_PIX_FMT_YUV48_12: 1147 case V4L2_PIX_FMT_BGR24: 1148 case V4L2_PIX_FMT_BGR48_12: 1149 default: 1150 sos->components_no = 3; 1151 break; 1152 case V4L2_PIX_FMT_ABGR32: 1153 case V4L2_PIX_FMT_ABGR64_12: 1154 sos->components_no = 4; 1155 break; 1156 case V4L2_PIX_FMT_GREY: 1157 case V4L2_PIX_FMT_Y012: 1158 sos->components_no = 1; 1159 break; 1160 } 1161 sos_length = 6 + 2 * sos->components_no; 1162 sos->length = sos_length; 1163 _bswap16(&sos->length); 1164 1165 /* SOS ignorable bytes, not so ignorable after all */ 1166 sof_u8[sos_length - 1] = 0x0; 1167 sof_u8[sos_length - 2] = 0x3f; 1168 sof_u8[sos_length - 3] = 0x0; 1169 1170 return sos_length; /* not swaped */ 1171} 1172 1173static unsigned int mxc_jpeg_setup_cfg_stream(void *cfg_stream_vaddr, 1174 u32 fourcc, 1175 u16 w, u16 h) 1176{ 1177 /* 1178 * There is a hardware issue that first 128 bytes of configuration data 1179 * can't be loaded correctly. 1180 * To avoid this issue, we need to write the configuration from 1181 * an offset which should be no less than 0x80 (128 bytes). 1182 */ 1183 unsigned int offset = 0x80; 1184 u8 *cfg = (u8 *)cfg_stream_vaddr; 1185 struct mxc_jpeg_sof *sof; 1186 struct mxc_jpeg_sos *sos; 1187 const struct mxc_jpeg_fmt *fmt = mxc_jpeg_find_format(fourcc); 1188 1189 if (!fmt) 1190 return 0; 1191 1192 memcpy(cfg + offset, jpeg_soi, ARRAY_SIZE(jpeg_soi)); 1193 offset += ARRAY_SIZE(jpeg_soi); 1194 1195 if (fmt->is_rgb) { 1196 memcpy(cfg + offset, jpeg_app14, sizeof(jpeg_app14)); 1197 offset += sizeof(jpeg_app14); 1198 } else { 1199 memcpy(cfg + offset, jpeg_app0, sizeof(jpeg_app0)); 1200 offset += sizeof(jpeg_app0); 1201 } 1202 1203 if (mxc_jpeg_is_extended_sequential(fmt)) { 1204 memcpy(cfg + offset, jpeg_dqt_extseq, sizeof(jpeg_dqt_extseq)); 1205 offset += sizeof(jpeg_dqt_extseq); 1206 1207 memcpy(cfg + offset, jpeg_sof_extseq, sizeof(jpeg_sof_extseq)); 1208 } else { 1209 memcpy(cfg + offset, jpeg_dqt, sizeof(jpeg_dqt)); 1210 offset += sizeof(jpeg_dqt); 1211 1212 memcpy(cfg + offset, jpeg_sof_maximal, sizeof(jpeg_sof_maximal)); 1213 } 1214 offset += 2; /* skip marker ID */ 1215 sof = (struct mxc_jpeg_sof *)(cfg + offset); 1216 offset += mxc_jpeg_fixup_sof(sof, fourcc, w, h); 1217 1218 if (mxc_jpeg_is_extended_sequential(fmt)) { 1219 memcpy(cfg + offset, jpeg_dht_extseq, sizeof(jpeg_dht_extseq)); 1220 offset += sizeof(jpeg_dht_extseq); 1221 } else { 1222 memcpy(cfg + offset, jpeg_dht, sizeof(jpeg_dht)); 1223 offset += sizeof(jpeg_dht); 1224 } 1225 1226 memcpy(cfg + offset, jpeg_dri, sizeof(jpeg_dri)); 1227 offset += sizeof(jpeg_dri); 1228 1229 memcpy(cfg + offset, jpeg_sos_maximal, sizeof(jpeg_sos_maximal)); 1230 offset += 2; /* skip marker ID */ 1231 sos = (struct mxc_jpeg_sos *)(cfg + offset); 1232 offset += mxc_jpeg_fixup_sos(sos, fourcc); 1233 1234 memcpy(cfg + offset, jpeg_image_red, sizeof(jpeg_image_red)); 1235 offset += sizeof(jpeg_image_red); 1236 1237 memcpy(cfg + offset, jpeg_eoi, sizeof(jpeg_eoi)); 1238 offset += sizeof(jpeg_eoi); 1239 1240 return offset; 1241} 1242 1243static void mxc_jpeg_config_dec_desc(struct vb2_buffer *out_buf, 1244 struct mxc_jpeg_ctx *ctx, 1245 struct vb2_buffer *src_buf, 1246 struct vb2_buffer *dst_buf) 1247{ 1248 enum v4l2_buf_type cap_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1249 struct mxc_jpeg_q_data *q_data_cap; 1250 enum mxc_jpeg_image_format img_fmt; 1251 struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg; 1252 void __iomem *reg = jpeg->base_reg; 1253 unsigned int slot = ctx->slot; 1254 struct mxc_jpeg_desc *desc = jpeg->slot_data.desc; 1255 struct mxc_jpeg_desc *cfg_desc = jpeg->slot_data.cfg_desc; 1256 dma_addr_t desc_handle = jpeg->slot_data.desc_handle; 1257 dma_addr_t cfg_desc_handle = jpeg->slot_data.cfg_desc_handle; 1258 dma_addr_t cfg_stream_handle = jpeg->slot_data.cfg_stream_handle; 1259 unsigned int *cfg_size = &jpeg->slot_data.cfg_stream_size; 1260 void *cfg_stream_vaddr = jpeg->slot_data.cfg_stream_vaddr; 1261 struct mxc_jpeg_src_buf *jpeg_src_buf; 1262 1263 jpeg_src_buf = vb2_to_mxc_buf(src_buf); 1264 1265 /* setup the decoding descriptor */ 1266 desc->next_descpt_ptr = 0; /* end of chain */ 1267 q_data_cap = mxc_jpeg_get_q_data(ctx, cap_type); 1268 desc->imgsize = q_data_cap->w_adjusted << 16 | q_data_cap->h_adjusted; 1269 img_fmt = mxc_jpeg_fourcc_to_imgfmt(q_data_cap->fmt->fourcc); 1270 desc->stm_ctrl &= ~STM_CTRL_IMAGE_FORMAT(0xF); /* clear image format */ 1271 desc->stm_ctrl |= STM_CTRL_IMAGE_FORMAT(img_fmt); 1272 desc->stm_ctrl |= STM_CTRL_BITBUF_PTR_CLR(1); 1273 if (mxc_jpeg_is_extended_sequential(jpeg_src_buf->fmt)) 1274 desc->stm_ctrl |= STM_CTRL_PIXEL_PRECISION; 1275 else 1276 desc->stm_ctrl &= ~STM_CTRL_PIXEL_PRECISION; 1277 desc->line_pitch = q_data_cap->bytesperline[0]; 1278 mxc_jpeg_addrs(desc, dst_buf, src_buf, 0); 1279 mxc_jpeg_set_bufsize(desc, ALIGN(vb2_plane_size(src_buf, 0), 1024)); 1280 print_descriptor_info(jpeg->dev, desc); 1281 1282 if (!jpeg_src_buf->dht_needed) { 1283 /* validate the decoding descriptor */ 1284 mxc_jpeg_set_desc(desc_handle, reg, slot); 1285 return; 1286 } 1287 1288 /* 1289 * if a default huffman table is needed, use the config descriptor to 1290 * inject a DHT, by chaining it before the decoding descriptor 1291 */ 1292 *cfg_size = mxc_jpeg_setup_cfg_stream(cfg_stream_vaddr, 1293 V4L2_PIX_FMT_YUYV, 1294 MXC_JPEG_PATTERN_WIDTH, 1295 MXC_JPEG_PATTERN_HEIGHT); 1296 cfg_desc->next_descpt_ptr = desc_handle | MXC_NXT_DESCPT_EN; 1297 cfg_desc->buf_base0 = jpeg->slot_data.cfg_dec_daddr; 1298 cfg_desc->buf_base1 = 0; 1299 cfg_desc->imgsize = MXC_JPEG_PATTERN_WIDTH << 16; 1300 cfg_desc->imgsize |= MXC_JPEG_PATTERN_HEIGHT; 1301 cfg_desc->line_pitch = MXC_JPEG_PATTERN_WIDTH * 2; 1302 cfg_desc->stm_ctrl = STM_CTRL_IMAGE_FORMAT(MXC_JPEG_YUV422); 1303 cfg_desc->stm_ctrl |= STM_CTRL_BITBUF_PTR_CLR(1); 1304 cfg_desc->stm_bufbase = cfg_stream_handle; 1305 cfg_desc->stm_bufsize = ALIGN(*cfg_size, 1024); 1306 print_descriptor_info(jpeg->dev, cfg_desc); 1307 1308 /* validate the configuration descriptor */ 1309 mxc_jpeg_set_desc(cfg_desc_handle, reg, slot); 1310} 1311 1312static void mxc_jpeg_config_enc_desc(struct vb2_buffer *out_buf, 1313 struct mxc_jpeg_ctx *ctx, 1314 struct vb2_buffer *src_buf, 1315 struct vb2_buffer *dst_buf) 1316{ 1317 struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg; 1318 void __iomem *reg = jpeg->base_reg; 1319 unsigned int slot = ctx->slot; 1320 struct mxc_jpeg_desc *desc = jpeg->slot_data.desc; 1321 struct mxc_jpeg_desc *cfg_desc = jpeg->slot_data.cfg_desc; 1322 dma_addr_t desc_handle = jpeg->slot_data.desc_handle; 1323 dma_addr_t cfg_desc_handle = jpeg->slot_data.cfg_desc_handle; 1324 void *cfg_stream_vaddr = jpeg->slot_data.cfg_stream_vaddr; 1325 struct mxc_jpeg_q_data *q_data; 1326 enum mxc_jpeg_image_format img_fmt; 1327 int w, h; 1328 1329 q_data = mxc_jpeg_get_q_data(ctx, src_buf->vb2_queue->type); 1330 1331 jpeg->slot_data.cfg_stream_size = 1332 mxc_jpeg_setup_cfg_stream(cfg_stream_vaddr, 1333 q_data->fmt->fourcc, 1334 q_data->crop.width, 1335 q_data->crop.height); 1336 1337 /* chain the config descriptor with the encoding descriptor */ 1338 cfg_desc->next_descpt_ptr = desc_handle | MXC_NXT_DESCPT_EN; 1339 1340 cfg_desc->buf_base0 = jpeg->slot_data.cfg_stream_handle; 1341 cfg_desc->buf_base1 = 0; 1342 cfg_desc->line_pitch = 0; 1343 cfg_desc->stm_bufbase = 0; /* no output expected */ 1344 cfg_desc->stm_bufsize = 0x0; 1345 cfg_desc->imgsize = 0; 1346 cfg_desc->stm_ctrl = STM_CTRL_CONFIG_MOD(1); 1347 cfg_desc->stm_ctrl |= STM_CTRL_BITBUF_PTR_CLR(1); 1348 1349 desc->next_descpt_ptr = 0; /* end of chain */ 1350 1351 /* use adjusted resolution for CAST IP job */ 1352 w = q_data->crop.width; 1353 h = q_data->crop.height; 1354 v4l_bound_align_image(&w, w, MXC_JPEG_MAX_WIDTH, q_data->fmt->h_align, 1355 &h, h, MXC_JPEG_MAX_HEIGHT, q_data->fmt->v_align, 0); 1356 mxc_jpeg_set_res(desc, w, h); 1357 mxc_jpeg_set_line_pitch(desc, q_data->bytesperline[0]); 1358 mxc_jpeg_set_bufsize(desc, ALIGN(vb2_plane_size(dst_buf, 0), 1024)); 1359 img_fmt = mxc_jpeg_fourcc_to_imgfmt(q_data->fmt->fourcc); 1360 if (img_fmt == MXC_JPEG_INVALID) 1361 dev_err(jpeg->dev, "No valid image format detected\n"); 1362 desc->stm_ctrl = STM_CTRL_CONFIG_MOD(0) | 1363 STM_CTRL_IMAGE_FORMAT(img_fmt); 1364 desc->stm_ctrl |= STM_CTRL_BITBUF_PTR_CLR(1); 1365 if (mxc_jpeg_is_extended_sequential(q_data->fmt)) 1366 desc->stm_ctrl |= STM_CTRL_PIXEL_PRECISION; 1367 else 1368 desc->stm_ctrl &= ~STM_CTRL_PIXEL_PRECISION; 1369 mxc_jpeg_addrs(desc, src_buf, dst_buf, 0); 1370 dev_dbg(jpeg->dev, "cfg_desc:\n"); 1371 print_descriptor_info(jpeg->dev, cfg_desc); 1372 dev_dbg(jpeg->dev, "enc desc:\n"); 1373 print_descriptor_info(jpeg->dev, desc); 1374 print_wrapper_info(jpeg->dev, reg); 1375 print_cast_status(jpeg->dev, reg, MXC_JPEG_ENCODE); 1376 1377 /* validate the configuration descriptor */ 1378 mxc_jpeg_set_desc(cfg_desc_handle, reg, slot); 1379} 1380 1381static const struct mxc_jpeg_fmt *mxc_jpeg_get_sibling_format(const struct mxc_jpeg_fmt *fmt) 1382{ 1383 int i; 1384 1385 for (i = 0; i < MXC_JPEG_NUM_FORMATS; i++) { 1386 if (mxc_formats[i].subsampling == fmt->subsampling && 1387 mxc_formats[i].nc == fmt->nc && 1388 mxc_formats[i].precision == fmt->precision && 1389 mxc_formats[i].is_rgb == fmt->is_rgb && 1390 mxc_formats[i].fourcc != fmt->fourcc) 1391 return &mxc_formats[i]; 1392 } 1393 1394 return NULL; 1395} 1396 1397static bool mxc_jpeg_compare_format(const struct mxc_jpeg_fmt *fmt1, 1398 const struct mxc_jpeg_fmt *fmt2) 1399{ 1400 if (fmt1 == fmt2) 1401 return true; 1402 if (mxc_jpeg_get_sibling_format(fmt1) == fmt2) 1403 return true; 1404 return false; 1405} 1406 1407static void mxc_jpeg_set_last_buffer(struct mxc_jpeg_ctx *ctx) 1408{ 1409 struct vb2_v4l2_buffer *next_dst_buf; 1410 1411 next_dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); 1412 if (!next_dst_buf) { 1413 ctx->fh.m2m_ctx->is_draining = true; 1414 ctx->fh.m2m_ctx->next_buf_last = true; 1415 return; 1416 } 1417 1418 v4l2_m2m_last_buffer_done(ctx->fh.m2m_ctx, next_dst_buf); 1419} 1420 1421static bool mxc_jpeg_source_change(struct mxc_jpeg_ctx *ctx, 1422 struct mxc_jpeg_src_buf *jpeg_src_buf) 1423{ 1424 struct device *dev = ctx->mxc_jpeg->dev; 1425 struct mxc_jpeg_q_data *q_data_cap; 1426 1427 if (!jpeg_src_buf->fmt) 1428 return false; 1429 1430 q_data_cap = mxc_jpeg_get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE); 1431 if (mxc_jpeg_compare_format(q_data_cap->fmt, jpeg_src_buf->fmt)) 1432 jpeg_src_buf->fmt = q_data_cap->fmt; 1433 if (ctx->need_initial_source_change_evt || 1434 q_data_cap->fmt != jpeg_src_buf->fmt || 1435 q_data_cap->w != jpeg_src_buf->w || 1436 q_data_cap->h != jpeg_src_buf->h) { 1437 dev_dbg(dev, "Detected jpeg res=(%dx%d)->(%dx%d), pixfmt=%c%c%c%c\n", 1438 q_data_cap->w, q_data_cap->h, 1439 jpeg_src_buf->w, jpeg_src_buf->h, 1440 (jpeg_src_buf->fmt->fourcc & 0xff), 1441 (jpeg_src_buf->fmt->fourcc >> 8) & 0xff, 1442 (jpeg_src_buf->fmt->fourcc >> 16) & 0xff, 1443 (jpeg_src_buf->fmt->fourcc >> 24) & 0xff); 1444 1445 /* 1446 * set-up the capture queue with the pixelformat and resolution 1447 * detected from the jpeg output stream 1448 */ 1449 q_data_cap->w = jpeg_src_buf->w; 1450 q_data_cap->h = jpeg_src_buf->h; 1451 q_data_cap->fmt = jpeg_src_buf->fmt; 1452 q_data_cap->w_adjusted = q_data_cap->w; 1453 q_data_cap->h_adjusted = q_data_cap->h; 1454 q_data_cap->crop.left = 0; 1455 q_data_cap->crop.top = 0; 1456 q_data_cap->crop.width = jpeg_src_buf->w; 1457 q_data_cap->crop.height = jpeg_src_buf->h; 1458 q_data_cap->bytesperline[0] = 0; 1459 q_data_cap->bytesperline[1] = 0; 1460 1461 /* 1462 * align up the resolution for CAST IP, 1463 * but leave the buffer resolution unchanged 1464 */ 1465 v4l_bound_align_image(&q_data_cap->w_adjusted, 1466 q_data_cap->w_adjusted, /* adjust up */ 1467 MXC_JPEG_MAX_WIDTH, 1468 q_data_cap->fmt->h_align, 1469 &q_data_cap->h_adjusted, 1470 q_data_cap->h_adjusted, /* adjust up */ 1471 MXC_JPEG_MAX_HEIGHT, 1472 q_data_cap->fmt->v_align, 1473 0); 1474 1475 /* setup bytesperline/sizeimage for capture queue */ 1476 mxc_jpeg_bytesperline(q_data_cap, jpeg_src_buf->fmt->precision); 1477 mxc_jpeg_sizeimage(q_data_cap); 1478 notify_src_chg(ctx); 1479 ctx->source_change = 1; 1480 ctx->need_initial_source_change_evt = false; 1481 if (vb2_is_streaming(v4l2_m2m_get_dst_vq(ctx->fh.m2m_ctx))) 1482 mxc_jpeg_set_last_buffer(ctx); 1483 } 1484 1485 return ctx->source_change ? true : false; 1486} 1487 1488static int mxc_jpeg_job_ready(void *priv) 1489{ 1490 struct mxc_jpeg_ctx *ctx = priv; 1491 1492 return ctx->source_change ? 0 : 1; 1493} 1494 1495static void mxc_jpeg_device_run_timeout(struct work_struct *work) 1496{ 1497 struct delayed_work *dwork = to_delayed_work(work); 1498 struct mxc_jpeg_ctx *ctx = container_of(dwork, struct mxc_jpeg_ctx, task_timer); 1499 struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg; 1500 unsigned long flags; 1501 1502 spin_lock_irqsave(&ctx->mxc_jpeg->hw_lock, flags); 1503 if (ctx->mxc_jpeg->slot_data.used) { 1504 dev_warn(jpeg->dev, "%s timeout, cancel it\n", 1505 ctx->mxc_jpeg->mode == MXC_JPEG_DECODE ? "decode" : "encode"); 1506 mxc_jpeg_job_finish(ctx, VB2_BUF_STATE_ERROR, true); 1507 v4l2_m2m_job_finish(ctx->mxc_jpeg->m2m_dev, ctx->fh.m2m_ctx); 1508 } 1509 spin_unlock_irqrestore(&ctx->mxc_jpeg->hw_lock, flags); 1510} 1511 1512static void mxc_jpeg_device_run(void *priv) 1513{ 1514 struct mxc_jpeg_ctx *ctx = priv; 1515 struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg; 1516 void __iomem *reg = jpeg->base_reg; 1517 struct device *dev = jpeg->dev; 1518 struct vb2_v4l2_buffer *src_buf, *dst_buf; 1519 unsigned long flags; 1520 struct mxc_jpeg_q_data *q_data_cap, *q_data_out; 1521 struct mxc_jpeg_src_buf *jpeg_src_buf; 1522 1523 spin_lock_irqsave(&ctx->mxc_jpeg->hw_lock, flags); 1524 src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); 1525 dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); 1526 if (!src_buf || !dst_buf) { 1527 dev_err(dev, "Null src or dst buf\n"); 1528 goto end; 1529 } 1530 1531 q_data_cap = mxc_jpeg_get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE); 1532 if (!q_data_cap) 1533 goto end; 1534 q_data_out = mxc_jpeg_get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT); 1535 if (!q_data_out) 1536 goto end; 1537 src_buf->sequence = q_data_out->sequence++; 1538 dst_buf->sequence = q_data_cap->sequence++; 1539 1540 v4l2_m2m_buf_copy_metadata(src_buf, dst_buf); 1541 1542 jpeg_src_buf = vb2_to_mxc_buf(&src_buf->vb2_buf); 1543 if (q_data_cap->fmt->mem_planes != dst_buf->vb2_buf.num_planes) { 1544 dev_err(dev, "Capture format %s has %d planes, but capture buffer has %d planes\n", 1545 q_data_cap->fmt->name, q_data_cap->fmt->mem_planes, 1546 dst_buf->vb2_buf.num_planes); 1547 jpeg_src_buf->jpeg_parse_error = true; 1548 } 1549 if (jpeg_src_buf->jpeg_parse_error) { 1550 mxc_jpeg_check_and_set_last_buffer(ctx, src_buf, dst_buf); 1551 v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); 1552 v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); 1553 v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_ERROR); 1554 v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_ERROR); 1555 spin_unlock_irqrestore(&ctx->mxc_jpeg->hw_lock, flags); 1556 v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx); 1557 1558 return; 1559 } 1560 if (ctx->mxc_jpeg->mode == MXC_JPEG_DECODE) { 1561 if (ctx->source_change || mxc_jpeg_source_change(ctx, jpeg_src_buf)) { 1562 spin_unlock_irqrestore(&ctx->mxc_jpeg->hw_lock, flags); 1563 v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx); 1564 return; 1565 } 1566 } 1567 1568 mxc_jpeg_enable(reg); 1569 mxc_jpeg_set_l_endian(reg, 1); 1570 1571 ctx->slot = mxc_get_free_slot(&jpeg->slot_data); 1572 if (ctx->slot < 0) { 1573 dev_err(dev, "No more free slots\n"); 1574 goto end; 1575 } 1576 if (!mxc_jpeg_alloc_slot_data(jpeg)) { 1577 dev_err(dev, "Cannot allocate slot data\n"); 1578 goto end; 1579 } 1580 1581 mxc_jpeg_enable_slot(reg, ctx->slot); 1582 mxc_jpeg_enable_irq(reg, ctx->slot); 1583 1584 if (jpeg->mode == MXC_JPEG_ENCODE) { 1585 dev_dbg(dev, "Encoding on slot %d\n", ctx->slot); 1586 ctx->enc_state = MXC_JPEG_ENC_CONF; 1587 mxc_jpeg_config_enc_desc(&dst_buf->vb2_buf, ctx, 1588 &src_buf->vb2_buf, &dst_buf->vb2_buf); 1589 /* start config phase */ 1590 mxc_jpeg_enc_mode_conf(dev, reg, 1591 mxc_jpeg_is_extended_sequential(q_data_out->fmt)); 1592 } else { 1593 dev_dbg(dev, "Decoding on slot %d\n", ctx->slot); 1594 print_mxc_buf(jpeg, &src_buf->vb2_buf, 0); 1595 mxc_jpeg_config_dec_desc(&dst_buf->vb2_buf, ctx, 1596 &src_buf->vb2_buf, &dst_buf->vb2_buf); 1597 mxc_jpeg_dec_mode_go(dev, reg); 1598 } 1599 schedule_delayed_work(&ctx->task_timer, msecs_to_jiffies(hw_timeout)); 1600end: 1601 spin_unlock_irqrestore(&ctx->mxc_jpeg->hw_lock, flags); 1602} 1603 1604static int mxc_jpeg_decoder_cmd(struct file *file, void *priv, 1605 struct v4l2_decoder_cmd *cmd) 1606{ 1607 struct v4l2_fh *fh = file_to_v4l2_fh(file); 1608 struct mxc_jpeg_ctx *ctx = mxc_jpeg_file_to_ctx(file); 1609 unsigned long flags; 1610 int ret; 1611 1612 ret = v4l2_m2m_ioctl_try_decoder_cmd(file, fh, cmd); 1613 if (ret < 0) 1614 return ret; 1615 1616 if (!vb2_is_streaming(v4l2_m2m_get_src_vq(fh->m2m_ctx))) 1617 return 0; 1618 1619 spin_lock_irqsave(&ctx->mxc_jpeg->hw_lock, flags); 1620 ret = v4l2_m2m_ioctl_decoder_cmd(file, priv, cmd); 1621 spin_unlock_irqrestore(&ctx->mxc_jpeg->hw_lock, flags); 1622 if (ret < 0) 1623 return ret; 1624 1625 if (cmd->cmd == V4L2_DEC_CMD_STOP && 1626 v4l2_m2m_has_stopped(fh->m2m_ctx)) { 1627 notify_eos(ctx); 1628 ctx->header_parsed = false; 1629 } 1630 1631 if (cmd->cmd == V4L2_DEC_CMD_START && 1632 v4l2_m2m_has_stopped(fh->m2m_ctx)) 1633 vb2_clear_last_buffer_dequeued(&fh->m2m_ctx->cap_q_ctx.q); 1634 return 0; 1635} 1636 1637static int mxc_jpeg_encoder_cmd(struct file *file, void *priv, 1638 struct v4l2_encoder_cmd *cmd) 1639{ 1640 struct v4l2_fh *fh = file_to_v4l2_fh(file); 1641 struct mxc_jpeg_ctx *ctx = mxc_jpeg_file_to_ctx(file); 1642 unsigned long flags; 1643 int ret; 1644 1645 ret = v4l2_m2m_ioctl_try_encoder_cmd(file, fh, cmd); 1646 if (ret < 0) 1647 return ret; 1648 1649 if (!vb2_is_streaming(v4l2_m2m_get_src_vq(fh->m2m_ctx)) || 1650 !vb2_is_streaming(v4l2_m2m_get_dst_vq(fh->m2m_ctx))) 1651 return 0; 1652 1653 spin_lock_irqsave(&ctx->mxc_jpeg->hw_lock, flags); 1654 ret = v4l2_m2m_ioctl_encoder_cmd(file, fh, cmd); 1655 spin_unlock_irqrestore(&ctx->mxc_jpeg->hw_lock, flags); 1656 if (ret < 0) 1657 return 0; 1658 1659 if (cmd->cmd == V4L2_ENC_CMD_STOP && 1660 v4l2_m2m_has_stopped(fh->m2m_ctx)) 1661 notify_eos(ctx); 1662 1663 if (cmd->cmd == V4L2_ENC_CMD_START && 1664 v4l2_m2m_has_stopped(fh->m2m_ctx)) 1665 vb2_clear_last_buffer_dequeued(&fh->m2m_ctx->cap_q_ctx.q); 1666 1667 return 0; 1668} 1669 1670static int mxc_jpeg_queue_setup(struct vb2_queue *q, 1671 unsigned int *nbuffers, 1672 unsigned int *nplanes, 1673 unsigned int sizes[], 1674 struct device *alloc_ctxs[]) 1675{ 1676 struct mxc_jpeg_ctx *ctx = vb2_get_drv_priv(q); 1677 struct mxc_jpeg_q_data *q_data = NULL; 1678 int i; 1679 1680 q_data = mxc_jpeg_get_q_data(ctx, q->type); 1681 if (!q_data) 1682 return -EINVAL; 1683 1684 /* Handle CREATE_BUFS situation - *nplanes != 0 */ 1685 if (*nplanes) { 1686 if (*nplanes != q_data->fmt->mem_planes) 1687 return -EINVAL; 1688 for (i = 0; i < *nplanes; i++) { 1689 if (sizes[i] < mxc_jpeg_get_plane_size(q_data, i)) 1690 return -EINVAL; 1691 } 1692 return 0; 1693 } 1694 1695 /* Handle REQBUFS situation */ 1696 *nplanes = q_data->fmt->mem_planes; 1697 for (i = 0; i < *nplanes; i++) 1698 sizes[i] = mxc_jpeg_get_plane_size(q_data, i); 1699 1700 if (V4L2_TYPE_IS_OUTPUT(q->type)) 1701 ctx->need_initial_source_change_evt = true; 1702 1703 return 0; 1704} 1705 1706static int mxc_jpeg_start_streaming(struct vb2_queue *q, unsigned int count) 1707{ 1708 struct mxc_jpeg_ctx *ctx = vb2_get_drv_priv(q); 1709 struct mxc_jpeg_q_data *q_data = mxc_jpeg_get_q_data(ctx, q->type); 1710 int ret; 1711 1712 v4l2_m2m_update_start_streaming_state(ctx->fh.m2m_ctx, q); 1713 1714 if (ctx->mxc_jpeg->mode == MXC_JPEG_DECODE && V4L2_TYPE_IS_CAPTURE(q->type)) 1715 ctx->source_change = 0; 1716 dev_dbg(ctx->mxc_jpeg->dev, "Start streaming ctx=%p", ctx); 1717 q_data->sequence = 0; 1718 1719 if (V4L2_TYPE_IS_CAPTURE(q->type)) 1720 ctx->need_initial_source_change_evt = false; 1721 1722 ret = pm_runtime_resume_and_get(ctx->mxc_jpeg->dev); 1723 if (ret < 0) { 1724 dev_err(ctx->mxc_jpeg->dev, "Failed to power up jpeg\n"); 1725 return ret; 1726 } 1727 1728 return 0; 1729} 1730 1731static void mxc_jpeg_stop_streaming(struct vb2_queue *q) 1732{ 1733 struct mxc_jpeg_ctx *ctx = vb2_get_drv_priv(q); 1734 struct vb2_v4l2_buffer *vbuf; 1735 1736 dev_dbg(ctx->mxc_jpeg->dev, "Stop streaming ctx=%p", ctx); 1737 1738 /* Release all active buffers */ 1739 for (;;) { 1740 if (V4L2_TYPE_IS_OUTPUT(q->type)) 1741 vbuf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); 1742 else 1743 vbuf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); 1744 if (!vbuf) 1745 break; 1746 v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR); 1747 } 1748 1749 v4l2_m2m_update_stop_streaming_state(ctx->fh.m2m_ctx, q); 1750 /* if V4L2_DEC_CMD_STOP is sent before the source change triggered, 1751 * restore the is_draining flag 1752 */ 1753 if (V4L2_TYPE_IS_CAPTURE(q->type) && ctx->source_change && ctx->fh.m2m_ctx->last_src_buf) 1754 ctx->fh.m2m_ctx->is_draining = true; 1755 1756 if (V4L2_TYPE_IS_OUTPUT(q->type) && 1757 v4l2_m2m_has_stopped(ctx->fh.m2m_ctx)) { 1758 notify_eos(ctx); 1759 ctx->header_parsed = false; 1760 } 1761 1762 pm_runtime_put_sync(&ctx->mxc_jpeg->pdev->dev); 1763} 1764 1765static int mxc_jpeg_valid_comp_id(struct device *dev, 1766 struct mxc_jpeg_sof *sof, 1767 struct mxc_jpeg_sos *sos) 1768{ 1769 int valid = 1; 1770 int i; 1771 1772 /* 1773 * there's a limitation in the IP that the component IDs must be 1774 * between 0..4, if they are not, let's patch them 1775 */ 1776 for (i = 0; i < sof->components_no; i++) 1777 if (sof->comp[i].id > MXC_JPEG_MAX_COMPONENTS) { 1778 valid = 0; 1779 dev_err(dev, "Component %d has invalid ID: %d", 1780 i, sof->comp[i].id); 1781 } 1782 if (!valid) 1783 /* patch all comp IDs if at least one is invalid */ 1784 for (i = 0; i < sof->components_no; i++) { 1785 dev_warn(dev, "Component %d ID patched to: %d", 1786 i, i + 1); 1787 sof->comp[i].id = i + 1; 1788 sos->comp[i].id = i + 1; 1789 } 1790 1791 return valid; 1792} 1793 1794static bool mxc_jpeg_match_image_format(const struct mxc_jpeg_fmt *fmt, 1795 const struct v4l2_jpeg_header *header) 1796{ 1797 if (fmt->subsampling != header->frame.subsampling || 1798 fmt->nc != header->frame.num_components || 1799 fmt->precision != header->frame.precision) 1800 return false; 1801 1802 /* 1803 * If the transform flag from APP14 marker is 0, images that are 1804 * encoded with 3 components have RGB colorspace, see Recommendation 1805 * ITU-T T.872 chapter 6.5.3 APP14 marker segment for colour encoding 1806 */ 1807 if (header->frame.subsampling == V4L2_JPEG_CHROMA_SUBSAMPLING_444) { 1808 u8 is_rgb = header->app14_tf == V4L2_JPEG_APP14_TF_CMYK_RGB ? 1 : 0; 1809 1810 if (is_rgb != fmt->is_rgb) 1811 return false; 1812 } 1813 return true; 1814} 1815 1816static u32 mxc_jpeg_get_image_format(struct device *dev, 1817 const struct v4l2_jpeg_header *header) 1818{ 1819 int i; 1820 u32 fourcc = 0; 1821 1822 for (i = 0; i < MXC_JPEG_NUM_FORMATS; i++) { 1823 if (mxc_jpeg_match_image_format(&mxc_formats[i], header)) { 1824 fourcc = mxc_formats[i].fourcc; 1825 break; 1826 } 1827 } 1828 if (fourcc == 0) { 1829 dev_err(dev, 1830 "Could not identify image format nc=%d, subsampling=%d, precision=%d\n", 1831 header->frame.num_components, 1832 header->frame.subsampling, 1833 header->frame.precision); 1834 return fourcc; 1835 } 1836 1837 return fourcc; 1838} 1839 1840static void mxc_jpeg_bytesperline(struct mxc_jpeg_q_data *q, u32 precision) 1841{ 1842 u32 bytesperline[2]; 1843 1844 bytesperline[0] = q->bytesperline[0]; 1845 bytesperline[1] = q->bytesperline[0]; /*imx-jpeg only support the same line pitch*/ 1846 v4l_bound_align_image(&bytesperline[0], 0, MXC_JPEG_MAX_LINE, 2, 1847 &bytesperline[1], 0, MXC_JPEG_MAX_LINE, 2, 1848 0); 1849 1850 /* Bytes distance between the leftmost pixels in two adjacent lines */ 1851 if (q->fmt->fourcc == V4L2_PIX_FMT_JPEG) { 1852 /* bytesperline unused for compressed formats */ 1853 q->bytesperline[0] = 0; 1854 q->bytesperline[1] = 0; 1855 } else if (q->fmt->subsampling == V4L2_JPEG_CHROMA_SUBSAMPLING_420) { 1856 /* When the image format is planar the bytesperline value 1857 * applies to the first plane and is divided by the same factor 1858 * as the width field for the other planes 1859 */ 1860 q->bytesperline[0] = q->w_adjusted * DIV_ROUND_UP(precision, 8); 1861 q->bytesperline[1] = q->bytesperline[0]; 1862 } else if (q->fmt->subsampling == V4L2_JPEG_CHROMA_SUBSAMPLING_422) { 1863 q->bytesperline[0] = q->w_adjusted * DIV_ROUND_UP(precision, 8) * 2; 1864 q->bytesperline[1] = 0; 1865 } else if (q->fmt->subsampling == V4L2_JPEG_CHROMA_SUBSAMPLING_444) { 1866 q->bytesperline[0] = q->w_adjusted * DIV_ROUND_UP(precision, 8) * q->fmt->nc; 1867 q->bytesperline[1] = 0; 1868 } else { 1869 /* grayscale */ 1870 q->bytesperline[0] = q->w_adjusted * DIV_ROUND_UP(precision, 8); 1871 q->bytesperline[1] = 0; 1872 } 1873 1874 if (q->fmt->fourcc != V4L2_PIX_FMT_JPEG) { 1875 q->bytesperline[0] = max(q->bytesperline[0], bytesperline[0]); 1876 if (q->fmt->mem_planes > 1) 1877 q->bytesperline[1] = max(q->bytesperline[1], bytesperline[1]); 1878 } 1879} 1880 1881static void mxc_jpeg_sizeimage(struct mxc_jpeg_q_data *q) 1882{ 1883 if (q->fmt->fourcc == V4L2_PIX_FMT_JPEG) { 1884 /* if no sizeimage from user, assume worst jpeg compression */ 1885 if (!q->sizeimage[0]) 1886 q->sizeimage[0] = 6 * q->w * q->h; 1887 q->sizeimage[1] = 0; 1888 1889 if (q->sizeimage[0] > MXC_JPEG_MAX_SIZEIMAGE) 1890 q->sizeimage[0] = MXC_JPEG_MAX_SIZEIMAGE; 1891 1892 /* jpeg stream size must be multiple of 1K */ 1893 q->sizeimage[0] = ALIGN(q->sizeimage[0], 1024); 1894 } else { 1895 q->sizeimage[0] = q->bytesperline[0] * q->h_adjusted; 1896 q->sizeimage[1] = 0; 1897 if (q->fmt->subsampling == V4L2_JPEG_CHROMA_SUBSAMPLING_420) 1898 q->sizeimage[1] = q->sizeimage[0] / 2; 1899 } 1900} 1901 1902static int mxc_jpeg_parse(struct mxc_jpeg_ctx *ctx, struct vb2_buffer *vb) 1903{ 1904 struct device *dev = ctx->mxc_jpeg->dev; 1905 struct mxc_jpeg_q_data *q_data_out; 1906 struct mxc_jpeg_q_data *q_data_cap; 1907 u32 fourcc; 1908 struct v4l2_jpeg_header header; 1909 struct mxc_jpeg_sof *psof = NULL; 1910 struct mxc_jpeg_sos *psos = NULL; 1911 struct mxc_jpeg_src_buf *jpeg_src_buf = vb2_to_mxc_buf(vb); 1912 u8 *src_addr = (u8 *)mxc_jpeg_get_plane_vaddr(vb, 0); 1913 u32 size = mxc_jpeg_get_plane_payload(vb, 0); 1914 int ret; 1915 1916 memset(&header, 0, sizeof(header)); 1917 ret = v4l2_jpeg_parse_header((void *)src_addr, size, &header); 1918 if (ret < 0) { 1919 dev_err(dev, "Error parsing JPEG stream markers\n"); 1920 return ret; 1921 } 1922 1923 /* if DHT marker present, no need to inject default one */ 1924 jpeg_src_buf->dht_needed = (header.num_dht == 0); 1925 1926 q_data_out = mxc_jpeg_get_q_data(ctx, 1927 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 1928 q_data_out->w = header.frame.width; 1929 q_data_out->h = header.frame.height; 1930 if (header.frame.width > MXC_JPEG_MAX_WIDTH || 1931 header.frame.height > MXC_JPEG_MAX_HEIGHT) { 1932 dev_err(dev, "JPEG width or height should be <= 8192: %dx%d\n", 1933 header.frame.width, header.frame.height); 1934 return -EINVAL; 1935 } 1936 if (header.frame.width < MXC_JPEG_MIN_WIDTH || 1937 header.frame.height < MXC_JPEG_MIN_HEIGHT) { 1938 dev_err(dev, "JPEG width or height should be > 64: %dx%d\n", 1939 header.frame.width, header.frame.height); 1940 return -EINVAL; 1941 } 1942 if (header.frame.num_components > V4L2_JPEG_MAX_COMPONENTS) { 1943 dev_err(dev, "JPEG number of components should be <=%d", 1944 V4L2_JPEG_MAX_COMPONENTS); 1945 return -EINVAL; 1946 } 1947 /* check and, if necessary, patch component IDs*/ 1948 psof = (struct mxc_jpeg_sof *)header.sof.start; 1949 psos = (struct mxc_jpeg_sos *)header.sos.start; 1950 if (!mxc_jpeg_valid_comp_id(dev, psof, psos)) 1951 dev_warn(dev, "JPEG component ids should be 0-3 or 1-4"); 1952 1953 q_data_cap = mxc_jpeg_get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 1954 if (q_data_cap->fmt && mxc_jpeg_match_image_format(q_data_cap->fmt, &header)) 1955 fourcc = q_data_cap->fmt->fourcc; 1956 else 1957 fourcc = mxc_jpeg_get_image_format(dev, &header); 1958 if (fourcc == 0) 1959 return -EINVAL; 1960 1961 jpeg_src_buf->fmt = mxc_jpeg_find_format(fourcc); 1962 jpeg_src_buf->w = header.frame.width; 1963 jpeg_src_buf->h = header.frame.height; 1964 ctx->header_parsed = true; 1965 1966 if (!v4l2_m2m_num_src_bufs_ready(ctx->fh.m2m_ctx)) 1967 mxc_jpeg_source_change(ctx, jpeg_src_buf); 1968 1969 return 0; 1970} 1971 1972static void mxc_jpeg_buf_queue(struct vb2_buffer *vb) 1973{ 1974 int ret; 1975 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); 1976 struct mxc_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); 1977 struct mxc_jpeg_src_buf *jpeg_src_buf; 1978 1979 if (V4L2_TYPE_IS_CAPTURE(vb->vb2_queue->type) && 1980 vb2_is_streaming(vb->vb2_queue) && 1981 v4l2_m2m_dst_buf_is_last(ctx->fh.m2m_ctx)) { 1982 struct mxc_jpeg_q_data *q_data; 1983 1984 q_data = mxc_jpeg_get_q_data(ctx, vb->vb2_queue->type); 1985 vbuf->field = V4L2_FIELD_NONE; 1986 vbuf->sequence = q_data->sequence++; 1987 v4l2_m2m_last_buffer_done(ctx->fh.m2m_ctx, vbuf); 1988 notify_eos(ctx); 1989 ctx->header_parsed = false; 1990 return; 1991 } 1992 1993 if (vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) 1994 goto end; 1995 1996 /* for V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE */ 1997 if (ctx->mxc_jpeg->mode != MXC_JPEG_DECODE) 1998 goto end; 1999 2000 jpeg_src_buf = vb2_to_mxc_buf(vb); 2001 jpeg_src_buf->jpeg_parse_error = false; 2002 ret = mxc_jpeg_parse(ctx, vb); 2003 if (ret) { 2004 jpeg_src_buf->jpeg_parse_error = true; 2005 2006 /* 2007 * if the capture queue is not setup, the device_run() won't be scheduled, 2008 * need to drop the error buffer, so that the decoding can continue 2009 */ 2010 if (!vb2_is_streaming(v4l2_m2m_get_dst_vq(ctx->fh.m2m_ctx))) { 2011 v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR); 2012 return; 2013 } 2014 } 2015 2016end: 2017 v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf); 2018} 2019 2020static int mxc_jpeg_buf_out_validate(struct vb2_buffer *vb) 2021{ 2022 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); 2023 2024 vbuf->field = V4L2_FIELD_NONE; 2025 2026 return 0; 2027} 2028 2029static int mxc_jpeg_buf_prepare(struct vb2_buffer *vb) 2030{ 2031 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); 2032 struct mxc_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); 2033 struct mxc_jpeg_q_data *q_data = NULL; 2034 struct device *dev = ctx->mxc_jpeg->dev; 2035 unsigned long sizeimage; 2036 int i; 2037 2038 vbuf->field = V4L2_FIELD_NONE; 2039 2040 q_data = mxc_jpeg_get_q_data(ctx, vb->vb2_queue->type); 2041 if (!q_data) 2042 return -EINVAL; 2043 for (i = 0; i < q_data->fmt->mem_planes; i++) { 2044 sizeimage = mxc_jpeg_get_plane_size(q_data, i); 2045 if (!ctx->source_change && vb2_plane_size(vb, i) < sizeimage) { 2046 dev_err(dev, "plane %d too small (%lu < %lu)", 2047 i, vb2_plane_size(vb, i), sizeimage); 2048 return -EINVAL; 2049 } 2050 if (!IS_ALIGNED(mxc_jpeg_get_plane_dma_addr(vb, i), MXC_JPEG_ADDR_ALIGNMENT)) { 2051 dev_err(dev, "planes[%d] address is not %d aligned\n", 2052 i, MXC_JPEG_ADDR_ALIGNMENT); 2053 return -EINVAL; 2054 } 2055 } 2056 if (V4L2_TYPE_IS_CAPTURE(vb->vb2_queue->type)) { 2057 vb2_set_plane_payload(vb, 0, 0); 2058 vb2_set_plane_payload(vb, 1, 0); 2059 } 2060 return 0; 2061} 2062 2063static const struct vb2_ops mxc_jpeg_qops = { 2064 .queue_setup = mxc_jpeg_queue_setup, 2065 .buf_out_validate = mxc_jpeg_buf_out_validate, 2066 .buf_prepare = mxc_jpeg_buf_prepare, 2067 .start_streaming = mxc_jpeg_start_streaming, 2068 .stop_streaming = mxc_jpeg_stop_streaming, 2069 .buf_queue = mxc_jpeg_buf_queue, 2070}; 2071 2072static int mxc_jpeg_queue_init(void *priv, struct vb2_queue *src_vq, 2073 struct vb2_queue *dst_vq) 2074{ 2075 struct mxc_jpeg_ctx *ctx = priv; 2076 int ret; 2077 2078 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 2079 src_vq->io_modes = VB2_MMAP | VB2_DMABUF; 2080 src_vq->drv_priv = ctx; 2081 src_vq->buf_struct_size = sizeof(struct mxc_jpeg_src_buf); 2082 src_vq->ops = &mxc_jpeg_qops; 2083 src_vq->mem_ops = &vb2_dma_contig_memops; 2084 src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; 2085 src_vq->lock = &ctx->mxc_jpeg->lock; 2086 src_vq->dev = ctx->mxc_jpeg->dev; 2087 2088 ret = vb2_queue_init(src_vq); 2089 if (ret) 2090 return ret; 2091 2092 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 2093 dst_vq->io_modes = VB2_MMAP | VB2_DMABUF; 2094 dst_vq->drv_priv = ctx; 2095 dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); 2096 dst_vq->ops = &mxc_jpeg_qops; 2097 dst_vq->mem_ops = &vb2_dma_contig_memops; 2098 dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; 2099 dst_vq->lock = &ctx->mxc_jpeg->lock; 2100 dst_vq->dev = ctx->mxc_jpeg->dev; 2101 2102 ret = vb2_queue_init(dst_vq); 2103 return ret; 2104} 2105 2106static void mxc_jpeg_set_default_params(struct mxc_jpeg_ctx *ctx) 2107{ 2108 struct mxc_jpeg_q_data *out_q = &ctx->out_q; 2109 struct mxc_jpeg_q_data *cap_q = &ctx->cap_q; 2110 struct mxc_jpeg_q_data *q[2] = {out_q, cap_q}; 2111 int i; 2112 2113 if (ctx->mxc_jpeg->mode == MXC_JPEG_ENCODE) { 2114 out_q->fmt = mxc_jpeg_find_format(MXC_JPEG_DEFAULT_PFMT); 2115 cap_q->fmt = mxc_jpeg_find_format(V4L2_PIX_FMT_JPEG); 2116 } else { 2117 out_q->fmt = mxc_jpeg_find_format(V4L2_PIX_FMT_JPEG); 2118 cap_q->fmt = mxc_jpeg_find_format(MXC_JPEG_DEFAULT_PFMT); 2119 } 2120 2121 for (i = 0; i < 2; i++) { 2122 q[i]->w = MXC_JPEG_DEFAULT_WIDTH; 2123 q[i]->h = MXC_JPEG_DEFAULT_HEIGHT; 2124 q[i]->w_adjusted = MXC_JPEG_DEFAULT_WIDTH; 2125 q[i]->h_adjusted = MXC_JPEG_DEFAULT_HEIGHT; 2126 q[i]->crop.left = 0; 2127 q[i]->crop.top = 0; 2128 q[i]->crop.width = MXC_JPEG_DEFAULT_WIDTH; 2129 q[i]->crop.height = MXC_JPEG_DEFAULT_HEIGHT; 2130 mxc_jpeg_bytesperline(q[i], q[i]->fmt->precision); 2131 mxc_jpeg_sizeimage(q[i]); 2132 } 2133} 2134 2135static int mxc_jpeg_s_ctrl(struct v4l2_ctrl *ctrl) 2136{ 2137 struct mxc_jpeg_ctx *ctx = 2138 container_of(ctrl->handler, struct mxc_jpeg_ctx, ctrl_handler); 2139 2140 switch (ctrl->id) { 2141 case V4L2_CID_JPEG_COMPRESSION_QUALITY: 2142 ctx->jpeg_quality = ctrl->val; 2143 break; 2144 default: 2145 dev_err(ctx->mxc_jpeg->dev, "Invalid control, id = %d, val = %d\n", 2146 ctrl->id, ctrl->val); 2147 return -EINVAL; 2148 } 2149 2150 return 0; 2151} 2152 2153static const struct v4l2_ctrl_ops mxc_jpeg_ctrl_ops = { 2154 .s_ctrl = mxc_jpeg_s_ctrl, 2155}; 2156 2157static void mxc_jpeg_encode_ctrls(struct mxc_jpeg_ctx *ctx) 2158{ 2159 v4l2_ctrl_new_std(&ctx->ctrl_handler, &mxc_jpeg_ctrl_ops, 2160 V4L2_CID_JPEG_COMPRESSION_QUALITY, 1, 100, 1, 75); 2161} 2162 2163static int mxc_jpeg_ctrls_setup(struct mxc_jpeg_ctx *ctx) 2164{ 2165 int err; 2166 2167 v4l2_ctrl_handler_init(&ctx->ctrl_handler, 2); 2168 2169 if (ctx->mxc_jpeg->mode == MXC_JPEG_ENCODE) 2170 mxc_jpeg_encode_ctrls(ctx); 2171 2172 if (ctx->ctrl_handler.error) { 2173 err = ctx->ctrl_handler.error; 2174 2175 v4l2_ctrl_handler_free(&ctx->ctrl_handler); 2176 return err; 2177 } 2178 2179 err = v4l2_ctrl_handler_setup(&ctx->ctrl_handler); 2180 if (err) 2181 v4l2_ctrl_handler_free(&ctx->ctrl_handler); 2182 return err; 2183} 2184 2185static int mxc_jpeg_open(struct file *file) 2186{ 2187 struct mxc_jpeg_dev *mxc_jpeg = video_drvdata(file); 2188 struct video_device *mxc_vfd = video_devdata(file); 2189 struct device *dev = mxc_jpeg->dev; 2190 struct mxc_jpeg_ctx *ctx; 2191 int ret = 0; 2192 2193 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); 2194 if (!ctx) 2195 return -ENOMEM; 2196 2197 if (mutex_lock_interruptible(&mxc_jpeg->lock)) { 2198 ret = -ERESTARTSYS; 2199 goto free; 2200 } 2201 2202 v4l2_fh_init(&ctx->fh, mxc_vfd); 2203 v4l2_fh_add(&ctx->fh, file); 2204 2205 ctx->mxc_jpeg = mxc_jpeg; 2206 2207 ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(mxc_jpeg->m2m_dev, ctx, 2208 mxc_jpeg_queue_init); 2209 2210 if (IS_ERR(ctx->fh.m2m_ctx)) { 2211 ret = PTR_ERR(ctx->fh.m2m_ctx); 2212 goto error; 2213 } 2214 2215 ret = mxc_jpeg_ctrls_setup(ctx); 2216 if (ret) { 2217 dev_err(ctx->mxc_jpeg->dev, "failed to setup mxc jpeg controls\n"); 2218 goto err_ctrls_setup; 2219 } 2220 ctx->fh.ctrl_handler = &ctx->ctrl_handler; 2221 mxc_jpeg_set_default_params(ctx); 2222 ctx->slot = -1; /* slot not allocated yet */ 2223 INIT_DELAYED_WORK(&ctx->task_timer, mxc_jpeg_device_run_timeout); 2224 2225 if (mxc_jpeg->mode == MXC_JPEG_DECODE) 2226 dev_dbg(dev, "Opened JPEG decoder instance %p\n", ctx); 2227 else 2228 dev_dbg(dev, "Opened JPEG encoder instance %p\n", ctx); 2229 mutex_unlock(&mxc_jpeg->lock); 2230 2231 return 0; 2232 2233err_ctrls_setup: 2234 v4l2_m2m_ctx_release(ctx->fh.m2m_ctx); 2235error: 2236 v4l2_fh_del(&ctx->fh, file); 2237 v4l2_fh_exit(&ctx->fh); 2238 mutex_unlock(&mxc_jpeg->lock); 2239free: 2240 kfree(ctx); 2241 return ret; 2242} 2243 2244static int mxc_jpeg_querycap(struct file *file, void *priv, 2245 struct v4l2_capability *cap) 2246{ 2247 strscpy(cap->driver, MXC_JPEG_NAME " codec", sizeof(cap->driver)); 2248 strscpy(cap->card, MXC_JPEG_NAME " codec", sizeof(cap->card)); 2249 cap->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M_MPLANE; 2250 cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; 2251 2252 return 0; 2253} 2254 2255static int mxc_jpeg_enum_fmt_vid_cap(struct file *file, void *priv, 2256 struct v4l2_fmtdesc *f) 2257{ 2258 struct mxc_jpeg_ctx *ctx = mxc_jpeg_file_to_ctx(file); 2259 struct mxc_jpeg_q_data *q_data = mxc_jpeg_get_q_data(ctx, f->type); 2260 2261 if (ctx->mxc_jpeg->mode == MXC_JPEG_ENCODE) { 2262 return enum_fmt(mxc_formats, MXC_JPEG_NUM_FORMATS, f, 2263 MXC_JPEG_FMT_TYPE_ENC); 2264 } else if (!ctx->header_parsed) { 2265 return enum_fmt(mxc_formats, MXC_JPEG_NUM_FORMATS, f, 2266 MXC_JPEG_FMT_TYPE_RAW); 2267 } else { 2268 /* For the decoder CAPTURE queue, only enumerate the raw formats 2269 * supported for the format currently active on OUTPUT 2270 * (more precisely what was propagated on capture queue 2271 * after jpeg parse on the output buffer) 2272 */ 2273 int ret = -EINVAL; 2274 const struct mxc_jpeg_fmt *sibling; 2275 2276 switch (f->index) { 2277 case 0: 2278 f->pixelformat = q_data->fmt->fourcc; 2279 ret = 0; 2280 break; 2281 case 1: 2282 sibling = mxc_jpeg_get_sibling_format(q_data->fmt); 2283 if (sibling) { 2284 f->pixelformat = sibling->fourcc; 2285 ret = 0; 2286 } 2287 break; 2288 default: 2289 break; 2290 } 2291 return ret; 2292 } 2293} 2294 2295static int mxc_jpeg_enum_fmt_vid_out(struct file *file, void *priv, 2296 struct v4l2_fmtdesc *f) 2297{ 2298 struct mxc_jpeg_ctx *ctx = mxc_jpeg_file_to_ctx(file); 2299 u32 type = ctx->mxc_jpeg->mode == MXC_JPEG_DECODE ? MXC_JPEG_FMT_TYPE_ENC : 2300 MXC_JPEG_FMT_TYPE_RAW; 2301 int ret; 2302 2303 ret = enum_fmt(mxc_formats, MXC_JPEG_NUM_FORMATS, f, type); 2304 if (ret) 2305 return ret; 2306 if (ctx->mxc_jpeg->mode == MXC_JPEG_DECODE) 2307 f->flags = V4L2_FMT_FLAG_DYN_RESOLUTION; 2308 return 0; 2309} 2310 2311static u32 mxc_jpeg_get_fmt_type(struct mxc_jpeg_ctx *ctx, u32 type) 2312{ 2313 if (ctx->mxc_jpeg->mode == MXC_JPEG_DECODE) 2314 return V4L2_TYPE_IS_OUTPUT(type) ? MXC_JPEG_FMT_TYPE_ENC : MXC_JPEG_FMT_TYPE_RAW; 2315 else 2316 return V4L2_TYPE_IS_CAPTURE(type) ? MXC_JPEG_FMT_TYPE_ENC : MXC_JPEG_FMT_TYPE_RAW; 2317} 2318 2319static u32 mxc_jpeg_get_default_fourcc(struct mxc_jpeg_ctx *ctx, u32 type) 2320{ 2321 if (ctx->mxc_jpeg->mode == MXC_JPEG_DECODE) 2322 return V4L2_TYPE_IS_OUTPUT(type) ? V4L2_PIX_FMT_JPEG : MXC_JPEG_DEFAULT_PFMT; 2323 else 2324 return V4L2_TYPE_IS_CAPTURE(type) ? V4L2_PIX_FMT_JPEG : MXC_JPEG_DEFAULT_PFMT; 2325} 2326 2327static u32 mxc_jpeg_try_fourcc(struct mxc_jpeg_ctx *ctx, u32 fourcc) 2328{ 2329 const struct mxc_jpeg_fmt *sibling; 2330 struct mxc_jpeg_q_data *q_data_cap; 2331 2332 if (ctx->mxc_jpeg->mode != MXC_JPEG_DECODE) 2333 return fourcc; 2334 if (!ctx->header_parsed) 2335 return fourcc; 2336 2337 q_data_cap = &ctx->cap_q; 2338 if (q_data_cap->fmt->fourcc == fourcc) 2339 return fourcc; 2340 2341 sibling = mxc_jpeg_get_sibling_format(q_data_cap->fmt); 2342 if (sibling && sibling->fourcc == fourcc) 2343 return sibling->fourcc; 2344 2345 return q_data_cap->fmt->fourcc; 2346} 2347 2348static int mxc_jpeg_try_fmt(struct v4l2_format *f, 2349 struct mxc_jpeg_ctx *ctx, struct mxc_jpeg_q_data *q_data) 2350{ 2351 const struct mxc_jpeg_fmt *fmt; 2352 struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; 2353 struct v4l2_plane_pix_format *pfmt; 2354 u32 fourcc = f->fmt.pix_mp.pixelformat; 2355 u32 w = (pix_mp->width < MXC_JPEG_MAX_WIDTH) ? 2356 pix_mp->width : MXC_JPEG_MAX_WIDTH; 2357 u32 h = (pix_mp->height < MXC_JPEG_MAX_HEIGHT) ? 2358 pix_mp->height : MXC_JPEG_MAX_HEIGHT; 2359 int i; 2360 2361 fmt = mxc_jpeg_find_format(fourcc); 2362 if (!fmt || fmt->flags != mxc_jpeg_get_fmt_type(ctx, f->type)) { 2363 dev_warn(ctx->mxc_jpeg->dev, "Format not supported: %c%c%c%c, use the default.\n", 2364 (fourcc & 0xff), 2365 (fourcc >> 8) & 0xff, 2366 (fourcc >> 16) & 0xff, 2367 (fourcc >> 24) & 0xff); 2368 fourcc = mxc_jpeg_get_default_fourcc(ctx, f->type); 2369 fmt = mxc_jpeg_find_format(fourcc); 2370 if (!fmt) 2371 return -EINVAL; 2372 f->fmt.pix_mp.pixelformat = fourcc; 2373 } 2374 q_data->fmt = fmt; 2375 2376 memset(pix_mp->reserved, 0, sizeof(pix_mp->reserved)); 2377 pix_mp->field = V4L2_FIELD_NONE; 2378 pix_mp->num_planes = fmt->mem_planes; 2379 pix_mp->pixelformat = fmt->fourcc; 2380 2381 q_data->w = w; 2382 q_data->h = h; 2383 q_data->w_adjusted = w; 2384 q_data->h_adjusted = h; 2385 v4l_bound_align_image(&q_data->w_adjusted, 2386 w, /* adjust upwards*/ 2387 MXC_JPEG_MAX_WIDTH, 2388 fmt->h_align, 2389 &q_data->h_adjusted, 2390 h, /* adjust upwards*/ 2391 MXC_JPEG_MAX_HEIGHT, 2392 fmt->v_align, 2393 0); 2394 for (i = 0; i < pix_mp->num_planes; i++) { 2395 pfmt = &pix_mp->plane_fmt[i]; 2396 q_data->bytesperline[i] = pfmt->bytesperline; 2397 q_data->sizeimage[i] = pfmt->sizeimage; 2398 } 2399 2400 /* calculate bytesperline & sizeimage */ 2401 mxc_jpeg_bytesperline(q_data, fmt->precision); 2402 mxc_jpeg_sizeimage(q_data); 2403 2404 /* adjust user format according to our calculations */ 2405 for (i = 0; i < pix_mp->num_planes; i++) { 2406 pfmt = &pix_mp->plane_fmt[i]; 2407 memset(pfmt->reserved, 0, sizeof(pfmt->reserved)); 2408 pfmt->bytesperline = q_data->bytesperline[i]; 2409 pfmt->sizeimage = mxc_jpeg_get_plane_size(q_data, i); 2410 } 2411 2412 /* fix colorspace information to sRGB for both output & capture */ 2413 pix_mp->colorspace = V4L2_COLORSPACE_SRGB; 2414 pix_mp->ycbcr_enc = V4L2_YCBCR_ENC_601; 2415 pix_mp->xfer_func = V4L2_XFER_FUNC_SRGB; 2416 /* 2417 * this hardware does not change the range of the samples 2418 * but since inside JPEG the YUV quantization is full-range, 2419 * this driver will always use full-range for the raw frames, too 2420 */ 2421 pix_mp->quantization = V4L2_QUANTIZATION_FULL_RANGE; 2422 2423 if (fmt->flags == MXC_JPEG_FMT_TYPE_RAW) { 2424 q_data->crop.left = 0; 2425 q_data->crop.top = 0; 2426 q_data->crop.width = q_data->w; 2427 q_data->crop.height = q_data->h; 2428 } 2429 2430 pix_mp->width = q_data->w_adjusted; 2431 pix_mp->height = q_data->h_adjusted; 2432 2433 return 0; 2434} 2435 2436static int mxc_jpeg_try_fmt_vid_cap(struct file *file, void *priv, 2437 struct v4l2_format *f) 2438{ 2439 struct mxc_jpeg_ctx *ctx = mxc_jpeg_file_to_ctx(file); 2440 struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg; 2441 struct device *dev = jpeg->dev; 2442 struct mxc_jpeg_q_data tmp_q; 2443 2444 if (!V4L2_TYPE_IS_MULTIPLANAR(f->type)) { 2445 dev_err(dev, "TRY_FMT with Invalid type: %d\n", f->type); 2446 return -EINVAL; 2447 } 2448 2449 if (ctx->mxc_jpeg->mode != MXC_JPEG_DECODE && V4L2_TYPE_IS_CAPTURE(f->type)) 2450 f->fmt.pix_mp.pixelformat = mxc_jpeg_try_fourcc(ctx, f->fmt.pix_mp.pixelformat); 2451 2452 return mxc_jpeg_try_fmt(f, ctx, &tmp_q); 2453} 2454 2455static int mxc_jpeg_try_fmt_vid_out(struct file *file, void *priv, 2456 struct v4l2_format *f) 2457{ 2458 struct mxc_jpeg_ctx *ctx = mxc_jpeg_file_to_ctx(file); 2459 struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg; 2460 struct device *dev = jpeg->dev; 2461 struct mxc_jpeg_q_data tmp_q; 2462 2463 if (!V4L2_TYPE_IS_MULTIPLANAR(f->type)) { 2464 dev_err(dev, "TRY_FMT with Invalid type: %d\n", f->type); 2465 return -EINVAL; 2466 } 2467 2468 return mxc_jpeg_try_fmt(f, ctx, &tmp_q); 2469} 2470 2471static void mxc_jpeg_s_parsed_fmt(struct mxc_jpeg_ctx *ctx, struct v4l2_format *f) 2472{ 2473 struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; 2474 struct mxc_jpeg_q_data *q_data_cap; 2475 2476 if (ctx->mxc_jpeg->mode != MXC_JPEG_DECODE || !V4L2_TYPE_IS_CAPTURE(f->type)) 2477 return; 2478 if (!ctx->header_parsed) 2479 return; 2480 2481 q_data_cap = mxc_jpeg_get_q_data(ctx, f->type); 2482 pix_mp->pixelformat = mxc_jpeg_try_fourcc(ctx, pix_mp->pixelformat); 2483 pix_mp->width = q_data_cap->w; 2484 pix_mp->height = q_data_cap->h; 2485} 2486 2487static int mxc_jpeg_s_fmt(struct mxc_jpeg_ctx *ctx, 2488 struct v4l2_format *f) 2489{ 2490 struct vb2_queue *vq; 2491 struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg; 2492 2493 vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type); 2494 2495 if (vb2_is_busy(vq)) { 2496 v4l2_err(&jpeg->v4l2_dev, "queue busy\n"); 2497 return -EBUSY; 2498 } 2499 2500 mxc_jpeg_s_parsed_fmt(ctx, f); 2501 2502 return mxc_jpeg_try_fmt(f, ctx, mxc_jpeg_get_q_data(ctx, f->type)); 2503} 2504 2505static int mxc_jpeg_s_fmt_vid_cap(struct file *file, void *priv, 2506 struct v4l2_format *f) 2507{ 2508 return mxc_jpeg_s_fmt(mxc_jpeg_file_to_ctx(file), f); 2509} 2510 2511static int mxc_jpeg_s_fmt_vid_out(struct file *file, void *priv, 2512 struct v4l2_format *f) 2513{ 2514 int ret; 2515 struct mxc_jpeg_ctx *ctx = mxc_jpeg_file_to_ctx(file); 2516 struct vb2_queue *dst_vq; 2517 struct mxc_jpeg_q_data *q_data_cap; 2518 enum v4l2_buf_type cap_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 2519 struct v4l2_format fc; 2520 2521 ret = mxc_jpeg_s_fmt(ctx, f); 2522 if (ret) 2523 return ret; 2524 2525 if (ctx->mxc_jpeg->mode != MXC_JPEG_DECODE) 2526 return 0; 2527 2528 dst_vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, cap_type); 2529 2530 if (vb2_is_busy(dst_vq)) 2531 return 0; 2532 2533 q_data_cap = mxc_jpeg_get_q_data(ctx, cap_type); 2534 if (q_data_cap->w == f->fmt.pix_mp.width && q_data_cap->h == f->fmt.pix_mp.height) 2535 return 0; 2536 memset(&fc, 0, sizeof(fc)); 2537 fc.type = cap_type; 2538 fc.fmt.pix_mp.pixelformat = q_data_cap->fmt->fourcc; 2539 fc.fmt.pix_mp.width = f->fmt.pix_mp.width; 2540 fc.fmt.pix_mp.height = f->fmt.pix_mp.height; 2541 2542 return mxc_jpeg_s_fmt_vid_cap(file, priv, &fc); 2543} 2544 2545static int mxc_jpeg_g_fmt_vid(struct file *file, void *priv, 2546 struct v4l2_format *f) 2547{ 2548 struct mxc_jpeg_ctx *ctx = mxc_jpeg_file_to_ctx(file); 2549 struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg; 2550 struct device *dev = jpeg->dev; 2551 struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; 2552 struct mxc_jpeg_q_data *q_data = mxc_jpeg_get_q_data(ctx, f->type); 2553 int i; 2554 2555 if (!V4L2_TYPE_IS_MULTIPLANAR(f->type)) { 2556 dev_err(dev, "G_FMT with Invalid type: %d\n", f->type); 2557 return -EINVAL; 2558 } 2559 2560 pix_mp->pixelformat = q_data->fmt->fourcc; 2561 pix_mp->width = q_data->w; 2562 pix_mp->height = q_data->h; 2563 pix_mp->field = V4L2_FIELD_NONE; 2564 if (q_data->fmt->flags == MXC_JPEG_FMT_TYPE_RAW) { 2565 pix_mp->width = q_data->w_adjusted; 2566 pix_mp->height = q_data->h_adjusted; 2567 } 2568 2569 /* fix colorspace information to sRGB for both output & capture */ 2570 pix_mp->colorspace = V4L2_COLORSPACE_SRGB; 2571 pix_mp->ycbcr_enc = V4L2_YCBCR_ENC_601; 2572 pix_mp->xfer_func = V4L2_XFER_FUNC_SRGB; 2573 pix_mp->quantization = V4L2_QUANTIZATION_FULL_RANGE; 2574 2575 pix_mp->num_planes = q_data->fmt->mem_planes; 2576 for (i = 0; i < pix_mp->num_planes; i++) { 2577 pix_mp->plane_fmt[i].bytesperline = q_data->bytesperline[i]; 2578 pix_mp->plane_fmt[i].sizeimage = mxc_jpeg_get_plane_size(q_data, i); 2579 } 2580 2581 return 0; 2582} 2583 2584static int mxc_jpeg_dec_g_selection(struct file *file, void *fh, struct v4l2_selection *s) 2585{ 2586 struct mxc_jpeg_ctx *ctx = mxc_jpeg_file_to_ctx(file); 2587 struct mxc_jpeg_q_data *q_data_cap; 2588 2589 if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) 2590 return -EINVAL; 2591 2592 q_data_cap = mxc_jpeg_get_q_data(ctx, s->type); 2593 2594 switch (s->target) { 2595 case V4L2_SEL_TGT_COMPOSE: 2596 case V4L2_SEL_TGT_COMPOSE_DEFAULT: 2597 s->r = q_data_cap->crop; 2598 break; 2599 case V4L2_SEL_TGT_COMPOSE_PADDED: 2600 case V4L2_SEL_TGT_COMPOSE_BOUNDS: 2601 s->r.left = 0; 2602 s->r.top = 0; 2603 s->r.width = q_data_cap->w_adjusted; 2604 s->r.height = q_data_cap->h_adjusted; 2605 break; 2606 default: 2607 return -EINVAL; 2608 } 2609 2610 return 0; 2611} 2612 2613static int mxc_jpeg_enc_g_selection(struct file *file, void *fh, struct v4l2_selection *s) 2614{ 2615 struct mxc_jpeg_ctx *ctx = mxc_jpeg_file_to_ctx(file); 2616 struct mxc_jpeg_q_data *q_data_out; 2617 2618 if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 2619 return -EINVAL; 2620 2621 q_data_out = mxc_jpeg_get_q_data(ctx, s->type); 2622 2623 switch (s->target) { 2624 case V4L2_SEL_TGT_CROP_DEFAULT: 2625 case V4L2_SEL_TGT_CROP_BOUNDS: 2626 s->r.left = 0; 2627 s->r.top = 0; 2628 s->r.width = q_data_out->w; 2629 s->r.height = q_data_out->h; 2630 break; 2631 case V4L2_SEL_TGT_CROP: 2632 s->r = q_data_out->crop; 2633 break; 2634 default: 2635 return -EINVAL; 2636 } 2637 2638 return 0; 2639} 2640 2641static int mxc_jpeg_g_selection(struct file *file, void *fh, struct v4l2_selection *s) 2642{ 2643 struct mxc_jpeg_ctx *ctx = mxc_jpeg_file_to_ctx(file); 2644 2645 if (ctx->mxc_jpeg->mode == MXC_JPEG_DECODE) 2646 return mxc_jpeg_dec_g_selection(file, fh, s); 2647 else 2648 return mxc_jpeg_enc_g_selection(file, fh, s); 2649} 2650 2651static int mxc_jpeg_s_selection(struct file *file, void *fh, struct v4l2_selection *s) 2652{ 2653 struct mxc_jpeg_ctx *ctx = mxc_jpeg_file_to_ctx(file); 2654 struct mxc_jpeg_q_data *q_data_out; 2655 2656 if (ctx->mxc_jpeg->mode != MXC_JPEG_ENCODE) 2657 return -ENOTTY; 2658 2659 if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 2660 return -EINVAL; 2661 if (s->target != V4L2_SEL_TGT_CROP) 2662 return -EINVAL; 2663 2664 q_data_out = mxc_jpeg_get_q_data(ctx, s->type); 2665 if (s->r.left || s->r.top) 2666 return -EINVAL; 2667 if (s->r.width > q_data_out->w || s->r.height > q_data_out->h) 2668 return -EINVAL; 2669 2670 q_data_out->crop.left = 0; 2671 q_data_out->crop.top = 0; 2672 q_data_out->crop.width = s->r.width; 2673 q_data_out->crop.height = s->r.height; 2674 2675 return 0; 2676} 2677 2678static int mxc_jpeg_subscribe_event(struct v4l2_fh *fh, 2679 const struct v4l2_event_subscription *sub) 2680{ 2681 switch (sub->type) { 2682 case V4L2_EVENT_EOS: 2683 return v4l2_event_subscribe(fh, sub, 0, NULL); 2684 case V4L2_EVENT_SOURCE_CHANGE: 2685 return v4l2_src_change_event_subscribe(fh, sub); 2686 case V4L2_EVENT_CTRL: 2687 return v4l2_ctrl_subscribe_event(fh, sub); 2688 default: 2689 return -EINVAL; 2690 } 2691} 2692 2693static const struct v4l2_ioctl_ops mxc_jpeg_ioctl_ops = { 2694 .vidioc_querycap = mxc_jpeg_querycap, 2695 .vidioc_enum_fmt_vid_cap = mxc_jpeg_enum_fmt_vid_cap, 2696 .vidioc_enum_fmt_vid_out = mxc_jpeg_enum_fmt_vid_out, 2697 2698 .vidioc_try_fmt_vid_cap_mplane = mxc_jpeg_try_fmt_vid_cap, 2699 .vidioc_try_fmt_vid_out_mplane = mxc_jpeg_try_fmt_vid_out, 2700 2701 .vidioc_s_fmt_vid_cap_mplane = mxc_jpeg_s_fmt_vid_cap, 2702 .vidioc_s_fmt_vid_out_mplane = mxc_jpeg_s_fmt_vid_out, 2703 2704 .vidioc_g_fmt_vid_cap_mplane = mxc_jpeg_g_fmt_vid, 2705 .vidioc_g_fmt_vid_out_mplane = mxc_jpeg_g_fmt_vid, 2706 2707 .vidioc_g_selection = mxc_jpeg_g_selection, 2708 .vidioc_s_selection = mxc_jpeg_s_selection, 2709 2710 .vidioc_subscribe_event = mxc_jpeg_subscribe_event, 2711 .vidioc_unsubscribe_event = v4l2_event_unsubscribe, 2712 2713 .vidioc_try_decoder_cmd = v4l2_m2m_ioctl_try_decoder_cmd, 2714 .vidioc_decoder_cmd = mxc_jpeg_decoder_cmd, 2715 .vidioc_try_encoder_cmd = v4l2_m2m_ioctl_try_encoder_cmd, 2716 .vidioc_encoder_cmd = mxc_jpeg_encoder_cmd, 2717 2718 .vidioc_qbuf = v4l2_m2m_ioctl_qbuf, 2719 .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf, 2720 2721 .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs, 2722 .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf, 2723 .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs, 2724 .vidioc_querybuf = v4l2_m2m_ioctl_querybuf, 2725 .vidioc_expbuf = v4l2_m2m_ioctl_expbuf, 2726 .vidioc_streamon = v4l2_m2m_ioctl_streamon, 2727 .vidioc_streamoff = v4l2_m2m_ioctl_streamoff, 2728}; 2729 2730static int mxc_jpeg_release(struct file *file) 2731{ 2732 struct mxc_jpeg_dev *mxc_jpeg = video_drvdata(file); 2733 struct mxc_jpeg_ctx *ctx = mxc_jpeg_file_to_ctx(file); 2734 struct device *dev = mxc_jpeg->dev; 2735 2736 mutex_lock(&mxc_jpeg->lock); 2737 if (mxc_jpeg->mode == MXC_JPEG_DECODE) 2738 dev_dbg(dev, "Release JPEG decoder instance on slot %d.", 2739 ctx->slot); 2740 else 2741 dev_dbg(dev, "Release JPEG encoder instance on slot %d.", 2742 ctx->slot); 2743 v4l2_ctrl_handler_free(&ctx->ctrl_handler); 2744 v4l2_m2m_ctx_release(ctx->fh.m2m_ctx); 2745 v4l2_fh_del(&ctx->fh, file); 2746 v4l2_fh_exit(&ctx->fh); 2747 kfree(ctx); 2748 mutex_unlock(&mxc_jpeg->lock); 2749 2750 return 0; 2751} 2752 2753static const struct v4l2_file_operations mxc_jpeg_fops = { 2754 .owner = THIS_MODULE, 2755 .open = mxc_jpeg_open, 2756 .release = mxc_jpeg_release, 2757 .poll = v4l2_m2m_fop_poll, 2758 .unlocked_ioctl = video_ioctl2, 2759 .mmap = v4l2_m2m_fop_mmap, 2760}; 2761 2762static const struct v4l2_m2m_ops mxc_jpeg_m2m_ops = { 2763 .job_ready = mxc_jpeg_job_ready, 2764 .device_run = mxc_jpeg_device_run, 2765}; 2766 2767static void mxc_jpeg_detach_pm_domains(struct mxc_jpeg_dev *jpeg) 2768{ 2769 int i; 2770 2771 for (i = 0; i < jpeg->num_domains; i++) { 2772 if (!IS_ERR_OR_NULL(jpeg->pd_dev[i]) && 2773 !pm_runtime_suspended(jpeg->pd_dev[i])) 2774 pm_runtime_force_suspend(jpeg->pd_dev[i]); 2775 if (!IS_ERR_OR_NULL(jpeg->pd_link[i])) 2776 device_link_del(jpeg->pd_link[i]); 2777 if (!IS_ERR_OR_NULL(jpeg->pd_dev[i])) 2778 dev_pm_domain_detach(jpeg->pd_dev[i], true); 2779 jpeg->pd_dev[i] = NULL; 2780 jpeg->pd_link[i] = NULL; 2781 } 2782} 2783 2784static int mxc_jpeg_attach_pm_domains(struct mxc_jpeg_dev *jpeg) 2785{ 2786 struct device *dev = jpeg->dev; 2787 struct device_node *np = jpeg->pdev->dev.of_node; 2788 int i; 2789 int ret; 2790 2791 jpeg->num_domains = of_count_phandle_with_args(np, "power-domains", 2792 "#power-domain-cells"); 2793 if (jpeg->num_domains < 0) { 2794 dev_err(dev, "No power domains defined for jpeg node\n"); 2795 return jpeg->num_domains; 2796 } 2797 if (jpeg->num_domains == 1) { 2798 /* genpd_dev_pm_attach() attach automatically if power domains count is 1 */ 2799 jpeg->num_domains = 0; 2800 return 0; 2801 } 2802 2803 jpeg->pd_dev = devm_kmalloc_array(dev, jpeg->num_domains, 2804 sizeof(*jpeg->pd_dev), GFP_KERNEL); 2805 if (!jpeg->pd_dev) 2806 return -ENOMEM; 2807 2808 jpeg->pd_link = devm_kmalloc_array(dev, jpeg->num_domains, 2809 sizeof(*jpeg->pd_link), GFP_KERNEL); 2810 if (!jpeg->pd_link) 2811 return -ENOMEM; 2812 2813 for (i = 0; i < jpeg->num_domains; i++) { 2814 jpeg->pd_dev[i] = dev_pm_domain_attach_by_id(dev, i); 2815 if (IS_ERR(jpeg->pd_dev[i])) { 2816 ret = PTR_ERR(jpeg->pd_dev[i]); 2817 goto fail; 2818 } 2819 2820 jpeg->pd_link[i] = device_link_add(dev, jpeg->pd_dev[i], 2821 DL_FLAG_STATELESS | 2822 DL_FLAG_PM_RUNTIME); 2823 if (!jpeg->pd_link[i]) { 2824 ret = -EINVAL; 2825 goto fail; 2826 } 2827 } 2828 2829 return 0; 2830fail: 2831 mxc_jpeg_detach_pm_domains(jpeg); 2832 return ret; 2833} 2834 2835static int mxc_jpeg_probe(struct platform_device *pdev) 2836{ 2837 struct mxc_jpeg_dev *jpeg; 2838 struct device *dev = &pdev->dev; 2839 int dec_irq; 2840 int ret; 2841 int mode; 2842 const struct of_device_id *of_id; 2843 2844 of_id = of_match_node(mxc_jpeg_match, dev->of_node); 2845 if (!of_id) 2846 return -ENODEV; 2847 mode = *(const int *)of_id->data; 2848 2849 jpeg = devm_kzalloc(dev, sizeof(struct mxc_jpeg_dev), GFP_KERNEL); 2850 if (!jpeg) 2851 return -ENOMEM; 2852 2853 mutex_init(&jpeg->lock); 2854 spin_lock_init(&jpeg->hw_lock); 2855 2856 ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32)); 2857 if (ret) { 2858 dev_err(&pdev->dev, "No suitable DMA available.\n"); 2859 goto err_irq; 2860 } 2861 2862 jpeg->base_reg = devm_platform_ioremap_resource(pdev, 0); 2863 if (IS_ERR(jpeg->base_reg)) 2864 return PTR_ERR(jpeg->base_reg); 2865 2866 ret = of_property_read_u32_index(pdev->dev.of_node, "slot", 0, &jpeg->slot_data.slot); 2867 if (ret) 2868 jpeg->slot_data.slot = 0; 2869 dev_info(&pdev->dev, "choose slot %d\n", jpeg->slot_data.slot); 2870 dec_irq = platform_get_irq(pdev, 0); 2871 if (dec_irq < 0) { 2872 ret = dec_irq; 2873 goto err_irq; 2874 } 2875 ret = devm_request_irq(&pdev->dev, dec_irq, mxc_jpeg_dec_irq, 2876 0, pdev->name, jpeg); 2877 if (ret) { 2878 dev_err(&pdev->dev, "Failed to request irq %d (%d)\n", 2879 dec_irq, ret); 2880 goto err_irq; 2881 } 2882 2883 jpeg->pdev = pdev; 2884 jpeg->dev = dev; 2885 jpeg->mode = mode; 2886 2887 /* Get clocks */ 2888 ret = devm_clk_bulk_get_all(&pdev->dev, &jpeg->clks); 2889 if (ret < 0) { 2890 dev_err(dev, "failed to get clock\n"); 2891 goto err_clk; 2892 } 2893 jpeg->num_clks = ret; 2894 2895 ret = mxc_jpeg_attach_pm_domains(jpeg); 2896 if (ret < 0) { 2897 dev_err(dev, "failed to attach power domains %d\n", ret); 2898 goto err_clk; 2899 } 2900 2901 /* v4l2 */ 2902 ret = v4l2_device_register(dev, &jpeg->v4l2_dev); 2903 if (ret) { 2904 dev_err(dev, "failed to register v4l2 device\n"); 2905 goto err_register; 2906 } 2907 jpeg->m2m_dev = v4l2_m2m_init(&mxc_jpeg_m2m_ops); 2908 if (IS_ERR(jpeg->m2m_dev)) { 2909 dev_err(dev, "failed to register v4l2 device\n"); 2910 ret = PTR_ERR(jpeg->m2m_dev); 2911 goto err_m2m; 2912 } 2913 2914 jpeg->dec_vdev = video_device_alloc(); 2915 if (!jpeg->dec_vdev) { 2916 dev_err(dev, "failed to register v4l2 device\n"); 2917 ret = -ENOMEM; 2918 goto err_vdev_alloc; 2919 } 2920 if (mode == MXC_JPEG_ENCODE) 2921 snprintf(jpeg->dec_vdev->name, 2922 sizeof(jpeg->dec_vdev->name), 2923 "%s-enc", MXC_JPEG_NAME); 2924 else 2925 snprintf(jpeg->dec_vdev->name, 2926 sizeof(jpeg->dec_vdev->name), 2927 "%s-dec", MXC_JPEG_NAME); 2928 2929 jpeg->dec_vdev->fops = &mxc_jpeg_fops; 2930 jpeg->dec_vdev->ioctl_ops = &mxc_jpeg_ioctl_ops; 2931 jpeg->dec_vdev->minor = -1; 2932 jpeg->dec_vdev->release = video_device_release; 2933 jpeg->dec_vdev->lock = &jpeg->lock; /* lock for ioctl serialization */ 2934 jpeg->dec_vdev->v4l2_dev = &jpeg->v4l2_dev; 2935 jpeg->dec_vdev->vfl_dir = VFL_DIR_M2M; 2936 jpeg->dec_vdev->device_caps = V4L2_CAP_STREAMING | 2937 V4L2_CAP_VIDEO_M2M_MPLANE; 2938 video_set_drvdata(jpeg->dec_vdev, jpeg); 2939 if (mode == MXC_JPEG_ENCODE) { 2940 v4l2_disable_ioctl(jpeg->dec_vdev, VIDIOC_DECODER_CMD); 2941 v4l2_disable_ioctl(jpeg->dec_vdev, VIDIOC_TRY_DECODER_CMD); 2942 } else { 2943 v4l2_disable_ioctl(jpeg->dec_vdev, VIDIOC_ENCODER_CMD); 2944 v4l2_disable_ioctl(jpeg->dec_vdev, VIDIOC_TRY_ENCODER_CMD); 2945 } 2946 ret = video_register_device(jpeg->dec_vdev, VFL_TYPE_VIDEO, -1); 2947 if (ret) { 2948 dev_err(dev, "failed to register video device\n"); 2949 goto err_vdev_register; 2950 } 2951 if (mode == MXC_JPEG_ENCODE) 2952 v4l2_info(&jpeg->v4l2_dev, 2953 "encoder device registered as /dev/video%d (%d,%d)\n", 2954 jpeg->dec_vdev->num, VIDEO_MAJOR, 2955 jpeg->dec_vdev->minor); 2956 else 2957 v4l2_info(&jpeg->v4l2_dev, 2958 "decoder device registered as /dev/video%d (%d,%d)\n", 2959 jpeg->dec_vdev->num, VIDEO_MAJOR, 2960 jpeg->dec_vdev->minor); 2961 2962 platform_set_drvdata(pdev, jpeg); 2963 pm_runtime_enable(dev); 2964 2965 return 0; 2966 2967err_vdev_register: 2968 video_device_release(jpeg->dec_vdev); 2969 2970err_vdev_alloc: 2971 v4l2_m2m_release(jpeg->m2m_dev); 2972 2973err_m2m: 2974 v4l2_device_unregister(&jpeg->v4l2_dev); 2975 2976err_register: 2977 mxc_jpeg_detach_pm_domains(jpeg); 2978 2979err_irq: 2980err_clk: 2981 return ret; 2982} 2983 2984static int mxc_jpeg_runtime_resume(struct device *dev) 2985{ 2986 struct mxc_jpeg_dev *jpeg = dev_get_drvdata(dev); 2987 int ret; 2988 2989 ret = clk_bulk_prepare_enable(jpeg->num_clks, jpeg->clks); 2990 if (ret < 0) { 2991 dev_err(dev, "failed to enable clock\n"); 2992 return ret; 2993 } 2994 2995 return 0; 2996} 2997 2998static int mxc_jpeg_runtime_suspend(struct device *dev) 2999{ 3000 struct mxc_jpeg_dev *jpeg = dev_get_drvdata(dev); 3001 3002 clk_bulk_disable_unprepare(jpeg->num_clks, jpeg->clks); 3003 3004 return 0; 3005} 3006 3007static int mxc_jpeg_suspend(struct device *dev) 3008{ 3009 struct mxc_jpeg_dev *jpeg = dev_get_drvdata(dev); 3010 3011 v4l2_m2m_suspend(jpeg->m2m_dev); 3012 return pm_runtime_force_suspend(dev); 3013} 3014 3015static int mxc_jpeg_resume(struct device *dev) 3016{ 3017 struct mxc_jpeg_dev *jpeg = dev_get_drvdata(dev); 3018 int ret; 3019 3020 ret = pm_runtime_force_resume(dev); 3021 if (ret < 0) 3022 return ret; 3023 3024 v4l2_m2m_resume(jpeg->m2m_dev); 3025 return ret; 3026} 3027 3028static const struct dev_pm_ops mxc_jpeg_pm_ops = { 3029 RUNTIME_PM_OPS(mxc_jpeg_runtime_suspend, mxc_jpeg_runtime_resume, NULL) 3030 SYSTEM_SLEEP_PM_OPS(mxc_jpeg_suspend, mxc_jpeg_resume) 3031}; 3032 3033static void mxc_jpeg_remove(struct platform_device *pdev) 3034{ 3035 struct mxc_jpeg_dev *jpeg = platform_get_drvdata(pdev); 3036 3037 mxc_jpeg_free_slot_data(jpeg); 3038 3039 pm_runtime_disable(&pdev->dev); 3040 video_unregister_device(jpeg->dec_vdev); 3041 v4l2_m2m_release(jpeg->m2m_dev); 3042 v4l2_device_unregister(&jpeg->v4l2_dev); 3043 mxc_jpeg_detach_pm_domains(jpeg); 3044} 3045 3046MODULE_DEVICE_TABLE(of, mxc_jpeg_match); 3047 3048static struct platform_driver mxc_jpeg_driver = { 3049 .probe = mxc_jpeg_probe, 3050 .remove = mxc_jpeg_remove, 3051 .driver = { 3052 .name = "mxc-jpeg", 3053 .of_match_table = mxc_jpeg_match, 3054 .pm = pm_ptr(&mxc_jpeg_pm_ops), 3055 }, 3056}; 3057module_platform_driver(mxc_jpeg_driver); 3058 3059MODULE_AUTHOR("Zhengyu Shen <zhengyu.shen_1@nxp.com>"); 3060MODULE_AUTHOR("Mirela Rabulea <mirela.rabulea@nxp.com>"); 3061MODULE_DESCRIPTION("V4L2 driver for i.MX8 QXP/QM JPEG encoder/decoder"); 3062MODULE_LICENSE("GPL v2");
~/
Read-only file preview.