GNU Linux-libre 4.19.245-gnu1
[releases.git] / drivers / media / platform / sti / delta / delta-mjpeg-dec.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) STMicroelectronics SA 2013
4  * Author: Hugues Fruchet <hugues.fruchet@st.com> for STMicroelectronics.
5  */
6
7 #include <linux/slab.h>
8
9 #include "delta.h"
10 #include "delta-ipc.h"
11 #include "delta-mjpeg.h"
12 #include "delta-mjpeg-fw.h"
13
14 #define DELTA_MJPEG_MAX_RESO DELTA_MAX_RESO
15
16 struct delta_mjpeg_ctx {
17         /* jpeg header */
18         struct mjpeg_header header_struct;
19         struct mjpeg_header *header;
20
21         /* ipc */
22         void *ipc_hdl;
23         struct delta_buf *ipc_buf;
24
25         /* decoded output frame */
26         struct delta_frame *out_frame;
27
28         unsigned char str[3000];
29 };
30
31 #define to_ctx(ctx) ((struct delta_mjpeg_ctx *)(ctx)->priv)
32
33 static char *ipc_open_param_str(struct jpeg_video_decode_init_params_t *p,
34                                 char *str, unsigned int len)
35 {
36         char *b = str;
37
38         if (!p)
39                 return "";
40
41         b += snprintf(b, len,
42                       "jpeg_video_decode_init_params_t\n"
43                       "circular_buffer_begin_addr_p 0x%x\n"
44                       "circular_buffer_end_addr_p   0x%x\n",
45                       p->circular_buffer_begin_addr_p,
46                       p->circular_buffer_end_addr_p);
47
48         return str;
49 }
50
51 static char *ipc_decode_param_str(struct jpeg_decode_params_t *p,
52                                   char *str, unsigned int len)
53 {
54         char *b = str;
55
56         if (!p)
57                 return "";
58
59         b += snprintf(b, len,
60                       "jpeg_decode_params_t\n"
61                       "picture_start_addr_p                  0x%x\n"
62                       "picture_end_addr_p                    0x%x\n"
63                       "decoding_mode                        %d\n"
64                       "display_buffer_addr.display_decimated_luma_p   0x%x\n"
65                       "display_buffer_addr.display_decimated_chroma_p 0x%x\n"
66                       "main_aux_enable                       %d\n"
67                       "additional_flags                     0x%x\n"
68                       "field_flag                           %x\n"
69                       "is_jpeg_image                        %x\n",
70                       p->picture_start_addr_p,
71                       p->picture_end_addr_p,
72                       p->decoding_mode,
73                       p->display_buffer_addr.display_decimated_luma_p,
74                       p->display_buffer_addr.display_decimated_chroma_p,
75                       p->main_aux_enable, p->additional_flags,
76                       p->field_flag,
77                       p->is_jpeg_image);
78
79         return str;
80 }
81
82 static inline bool is_stream_error(enum jpeg_decoding_error_t err)
83 {
84         switch (err) {
85         case JPEG_DECODER_UNDEFINED_HUFF_TABLE:
86         case JPEG_DECODER_BAD_RESTART_MARKER:
87         case JPEG_DECODER_BAD_SOS_SPECTRAL:
88         case JPEG_DECODER_BAD_SOS_SUCCESSIVE:
89         case JPEG_DECODER_BAD_HEADER_LENGTH:
90         case JPEG_DECODER_BAD_COUNT_VALUE:
91         case JPEG_DECODER_BAD_DHT_MARKER:
92         case JPEG_DECODER_BAD_INDEX_VALUE:
93         case JPEG_DECODER_BAD_NUMBER_HUFFMAN_TABLES:
94         case JPEG_DECODER_BAD_QUANT_TABLE_LENGTH:
95         case JPEG_DECODER_BAD_NUMBER_QUANT_TABLES:
96         case JPEG_DECODER_BAD_COMPONENT_COUNT:
97                 return true;
98         default:
99                 return false;
100         }
101 }
102
103 static inline const char *err_str(enum jpeg_decoding_error_t err)
104 {
105         switch (err) {
106         case JPEG_DECODER_NO_ERROR:
107                 return "JPEG_DECODER_NO_ERROR";
108         case JPEG_DECODER_UNDEFINED_HUFF_TABLE:
109                 return "JPEG_DECODER_UNDEFINED_HUFF_TABLE";
110         case JPEG_DECODER_UNSUPPORTED_MARKER:
111                 return "JPEG_DECODER_UNSUPPORTED_MARKER";
112         case JPEG_DECODER_UNABLE_ALLOCATE_MEMORY:
113                 return "JPEG_DECODER_UNABLE_ALLOCATE_MEMORY";
114         case JPEG_DECODER_NON_SUPPORTED_SAMP_FACTORS:
115                 return "JPEG_DECODER_NON_SUPPORTED_SAMP_FACTORS";
116         case JPEG_DECODER_BAD_PARAMETER:
117                 return "JPEG_DECODER_BAD_PARAMETER";
118         case JPEG_DECODER_DECODE_ERROR:
119                 return "JPEG_DECODER_DECODE_ERROR";
120         case JPEG_DECODER_BAD_RESTART_MARKER:
121                 return "JPEG_DECODER_BAD_RESTART_MARKER";
122         case JPEG_DECODER_UNSUPPORTED_COLORSPACE:
123                 return "JPEG_DECODER_UNSUPPORTED_COLORSPACE";
124         case JPEG_DECODER_BAD_SOS_SPECTRAL:
125                 return "JPEG_DECODER_BAD_SOS_SPECTRAL";
126         case JPEG_DECODER_BAD_SOS_SUCCESSIVE:
127                 return "JPEG_DECODER_BAD_SOS_SUCCESSIVE";
128         case JPEG_DECODER_BAD_HEADER_LENGTH:
129                 return "JPEG_DECODER_BAD_HEADER_LENGTH";
130         case JPEG_DECODER_BAD_COUNT_VALUE:
131                 return "JPEG_DECODER_BAD_COUNT_VALUE";
132         case JPEG_DECODER_BAD_DHT_MARKER:
133                 return "JPEG_DECODER_BAD_DHT_MARKER";
134         case JPEG_DECODER_BAD_INDEX_VALUE:
135                 return "JPEG_DECODER_BAD_INDEX_VALUE";
136         case JPEG_DECODER_BAD_NUMBER_HUFFMAN_TABLES:
137                 return "JPEG_DECODER_BAD_NUMBER_HUFFMAN_TABLES";
138         case JPEG_DECODER_BAD_QUANT_TABLE_LENGTH:
139                 return "JPEG_DECODER_BAD_QUANT_TABLE_LENGTH";
140         case JPEG_DECODER_BAD_NUMBER_QUANT_TABLES:
141                 return "JPEG_DECODER_BAD_NUMBER_QUANT_TABLES";
142         case JPEG_DECODER_BAD_COMPONENT_COUNT:
143                 return "JPEG_DECODER_BAD_COMPONENT_COUNT";
144         case JPEG_DECODER_DIVIDE_BY_ZERO_ERROR:
145                 return "JPEG_DECODER_DIVIDE_BY_ZERO_ERROR";
146         case JPEG_DECODER_NOT_JPG_IMAGE:
147                 return "JPEG_DECODER_NOT_JPG_IMAGE";
148         case JPEG_DECODER_UNSUPPORTED_ROTATION_ANGLE:
149                 return "JPEG_DECODER_UNSUPPORTED_ROTATION_ANGLE";
150         case JPEG_DECODER_UNSUPPORTED_SCALING:
151                 return "JPEG_DECODER_UNSUPPORTED_SCALING";
152         case JPEG_DECODER_INSUFFICIENT_OUTPUTBUFFER_SIZE:
153                 return "JPEG_DECODER_INSUFFICIENT_OUTPUTBUFFER_SIZE";
154         case JPEG_DECODER_BAD_HWCFG_GP_VERSION_VALUE:
155                 return "JPEG_DECODER_BAD_HWCFG_GP_VERSION_VALUE";
156         case JPEG_DECODER_BAD_VALUE_FROM_RED:
157                 return "JPEG_DECODER_BAD_VALUE_FROM_RED";
158         case JPEG_DECODER_BAD_SUBREGION_PARAMETERS:
159                 return "JPEG_DECODER_BAD_SUBREGION_PARAMETERS";
160         case JPEG_DECODER_PROGRESSIVE_DECODE_NOT_SUPPORTED:
161                 return "JPEG_DECODER_PROGRESSIVE_DECODE_NOT_SUPPORTED";
162         case JPEG_DECODER_ERROR_TASK_TIMEOUT:
163                 return "JPEG_DECODER_ERROR_TASK_TIMEOUT";
164         case JPEG_DECODER_ERROR_FEATURE_NOT_SUPPORTED:
165                 return "JPEG_DECODER_ERROR_FEATURE_NOT_SUPPORTED";
166         default:
167                 return "!unknown MJPEG error!";
168         }
169 }
170
171 static bool delta_mjpeg_check_status(struct delta_ctx *pctx,
172                                      struct jpeg_decode_return_params_t *status)
173 {
174         struct delta_dev *delta = pctx->dev;
175         bool dump = false;
176
177         if (status->error_code == JPEG_DECODER_NO_ERROR)
178                 goto out;
179
180         if (is_stream_error(status->error_code)) {
181                 dev_warn_ratelimited(delta->dev,
182                                      "%s  firmware: stream error @ frame %d (%s)\n",
183                                      pctx->name, pctx->decoded_frames,
184                                      err_str(status->error_code));
185                 pctx->stream_errors++;
186         } else {
187                 dev_warn_ratelimited(delta->dev,
188                                      "%s  firmware: decode error @ frame %d (%s)\n",
189                                      pctx->name, pctx->decoded_frames,
190                                      err_str(status->error_code));
191                 pctx->decode_errors++;
192                 dump = true;
193         }
194
195 out:
196         dev_dbg(delta->dev,
197                 "%s  firmware: decoding time(us)=%d\n", pctx->name,
198                 status->decode_time_in_us);
199
200         return dump;
201 }
202
203 static int delta_mjpeg_ipc_open(struct delta_ctx *pctx)
204 {
205         struct delta_dev *delta = pctx->dev;
206         struct delta_mjpeg_ctx *ctx = to_ctx(pctx);
207         int ret = 0;
208         struct jpeg_video_decode_init_params_t params_struct;
209         struct jpeg_video_decode_init_params_t *params = &params_struct;
210         struct delta_buf *ipc_buf;
211         u32 ipc_buf_size;
212         struct delta_ipc_param ipc_param;
213         void *hdl;
214
215         memset(params, 0, sizeof(*params));
216         params->circular_buffer_begin_addr_p = 0x00000000;
217         params->circular_buffer_end_addr_p = 0xffffffff;
218
219         dev_vdbg(delta->dev,
220                  "%s  %s\n", pctx->name,
221                  ipc_open_param_str(params, ctx->str, sizeof(ctx->str)));
222
223         ipc_param.size = sizeof(*params);
224         ipc_param.data = params;
225         ipc_buf_size = sizeof(struct jpeg_decode_params_t) +
226             sizeof(struct jpeg_decode_return_params_t);
227         ret = delta_ipc_open(pctx, "JPEG_DECODER_HW0", &ipc_param,
228                              ipc_buf_size, &ipc_buf, &hdl);
229         if (ret) {
230                 dev_err(delta->dev,
231                         "%s  dumping command %s\n", pctx->name,
232                         ipc_open_param_str(params, ctx->str, sizeof(ctx->str)));
233                 return ret;
234         }
235
236         ctx->ipc_buf = ipc_buf;
237         ctx->ipc_hdl = hdl;
238
239         return 0;
240 }
241
242 static int delta_mjpeg_ipc_decode(struct delta_ctx *pctx, struct delta_au *au)
243 {
244         struct delta_dev *delta = pctx->dev;
245         struct delta_mjpeg_ctx *ctx = to_ctx(pctx);
246         int ret = 0;
247         struct jpeg_decode_params_t *params = ctx->ipc_buf->vaddr;
248         struct jpeg_decode_return_params_t *status =
249             ctx->ipc_buf->vaddr + sizeof(*params);
250         struct delta_frame *frame;
251         struct delta_ipc_param ipc_param, ipc_status;
252
253         ret = delta_get_free_frame(pctx, &frame);
254         if (ret)
255                 return ret;
256
257         memset(params, 0, sizeof(*params));
258
259         params->picture_start_addr_p = (u32)(au->paddr);
260         params->picture_end_addr_p = (u32)(au->paddr + au->size - 1);
261
262         /*
263          * !WARNING!
264          * the NV12 decoded frame is only available
265          * on decimated output when enabling flag
266          * "JPEG_ADDITIONAL_FLAG_420MB"...
267          * the non decimated output gives YUV422SP
268          */
269         params->main_aux_enable = JPEG_DISP_AUX_EN;
270         params->additional_flags = JPEG_ADDITIONAL_FLAG_420MB;
271         params->horizontal_decimation_factor = JPEG_HDEC_1;
272         params->vertical_decimation_factor = JPEG_VDEC_1;
273         params->decoding_mode = JPEG_NORMAL_DECODE;
274
275         params->display_buffer_addr.struct_size =
276             sizeof(struct jpeg_display_buffer_address_t);
277         params->display_buffer_addr.display_decimated_luma_p =
278             (u32)frame->paddr;
279         params->display_buffer_addr.display_decimated_chroma_p =
280             (u32)(frame->paddr
281                   + frame->info.aligned_width * frame->info.aligned_height);
282
283         dev_vdbg(delta->dev,
284                  "%s  %s\n", pctx->name,
285                  ipc_decode_param_str(params, ctx->str, sizeof(ctx->str)));
286
287         /* status */
288         memset(status, 0, sizeof(*status));
289         status->error_code = JPEG_DECODER_NO_ERROR;
290
291         ipc_param.size = sizeof(*params);
292         ipc_param.data = params;
293         ipc_status.size = sizeof(*status);
294         ipc_status.data = status;
295         ret = delta_ipc_decode(ctx->ipc_hdl, &ipc_param, &ipc_status);
296         if (ret) {
297                 dev_err(delta->dev,
298                         "%s  dumping command %s\n", pctx->name,
299                         ipc_decode_param_str(params, ctx->str,
300                                              sizeof(ctx->str)));
301                 return ret;
302         }
303
304         pctx->decoded_frames++;
305
306         /* check firmware decoding status */
307         if (delta_mjpeg_check_status(pctx, status)) {
308                 dev_err(delta->dev,
309                         "%s  dumping command %s\n", pctx->name,
310                         ipc_decode_param_str(params, ctx->str,
311                                              sizeof(ctx->str)));
312         }
313
314         frame->field = V4L2_FIELD_NONE;
315         frame->flags = V4L2_BUF_FLAG_KEYFRAME;
316         frame->state |= DELTA_FRAME_DEC;
317
318         ctx->out_frame = frame;
319
320         return 0;
321 }
322
323 static int delta_mjpeg_open(struct delta_ctx *pctx)
324 {
325         struct delta_mjpeg_ctx *ctx;
326
327         ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
328         if (!ctx)
329                 return -ENOMEM;
330         pctx->priv = ctx;
331
332         return 0;
333 }
334
335 static int delta_mjpeg_close(struct delta_ctx *pctx)
336 {
337         struct delta_mjpeg_ctx *ctx = to_ctx(pctx);
338
339         if (ctx->ipc_hdl) {
340                 delta_ipc_close(ctx->ipc_hdl);
341                 ctx->ipc_hdl = NULL;
342         }
343
344         kfree(ctx);
345
346         return 0;
347 }
348
349 static int delta_mjpeg_get_streaminfo(struct delta_ctx *pctx,
350                                       struct delta_streaminfo *streaminfo)
351 {
352         struct delta_mjpeg_ctx *ctx = to_ctx(pctx);
353
354         if (!ctx->header)
355                 goto nodata;
356
357         streaminfo->streamformat = V4L2_PIX_FMT_MJPEG;
358         streaminfo->width = ctx->header->frame_width;
359         streaminfo->height = ctx->header->frame_height;
360
361         /* progressive stream */
362         streaminfo->field = V4L2_FIELD_NONE;
363
364         streaminfo->dpb = 1;
365
366         return 0;
367
368 nodata:
369         return -ENODATA;
370 }
371
372 static int delta_mjpeg_decode(struct delta_ctx *pctx, struct delta_au *pau)
373 {
374         struct delta_dev *delta = pctx->dev;
375         struct delta_mjpeg_ctx *ctx = to_ctx(pctx);
376         int ret;
377         struct delta_au au = *pau;
378         unsigned int data_offset = 0;
379         struct mjpeg_header *header = &ctx->header_struct;
380
381         if (!ctx->header) {
382                 ret = delta_mjpeg_read_header(pctx, au.vaddr, au.size,
383                                               header, &data_offset);
384                 if (ret) {
385                         pctx->stream_errors++;
386                         goto err;
387                 }
388                 if (header->frame_width * header->frame_height >
389                     DELTA_MJPEG_MAX_RESO) {
390                         dev_err(delta->dev,
391                                 "%s  stream resolution too large: %dx%d > %d pixels budget\n",
392                                 pctx->name,
393                                 header->frame_width,
394                                 header->frame_height, DELTA_MJPEG_MAX_RESO);
395                         ret = -EINVAL;
396                         goto err;
397                 }
398                 ctx->header = header;
399                 goto out;
400         }
401
402         if (!ctx->ipc_hdl) {
403                 ret = delta_mjpeg_ipc_open(pctx);
404                 if (ret)
405                         goto err;
406         }
407
408         ret = delta_mjpeg_read_header(pctx, au.vaddr, au.size,
409                                       ctx->header, &data_offset);
410         if (ret) {
411                 pctx->stream_errors++;
412                 goto err;
413         }
414
415         au.paddr += data_offset;
416         au.vaddr += data_offset;
417
418         ret = delta_mjpeg_ipc_decode(pctx, &au);
419         if (ret)
420                 goto err;
421
422 out:
423         return 0;
424
425 err:
426         return ret;
427 }
428
429 static int delta_mjpeg_get_frame(struct delta_ctx *pctx,
430                                  struct delta_frame **frame)
431 {
432         struct delta_mjpeg_ctx *ctx = to_ctx(pctx);
433
434         if (!ctx->out_frame)
435                 return -ENODATA;
436
437         *frame = ctx->out_frame;
438
439         ctx->out_frame = NULL;
440
441         return 0;
442 }
443
444 const struct delta_dec mjpegdec = {
445         .name = "MJPEG",
446         .streamformat = V4L2_PIX_FMT_MJPEG,
447         .pixelformat = V4L2_PIX_FMT_NV12,
448         .open = delta_mjpeg_open,
449         .close = delta_mjpeg_close,
450         .get_streaminfo = delta_mjpeg_get_streaminfo,
451         .get_frameinfo = delta_get_frameinfo_default,
452         .decode = delta_mjpeg_decode,
453         .get_frame = delta_mjpeg_get_frame,
454         .recycle = delta_recycle_default,
455 };