isp10: rockchip: v0.1.6
[firefly-linux-kernel-4.4.55.git] / drivers / media / platform / rk-isp10 / cif_isp10.c
1 /*
2  *************************************************************************
3  * Rockchip driver for CIF ISP 1.0
4  * (Based on Intel driver for sofiaxxx)
5  *
6  * Copyright (C) 2015 Intel Mobile Communications GmbH
7  * Copyright (C) 2016 Fuzhou Rockchip Electronics Co., Ltd.
8  *
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *************************************************************************
15  */
16
17 #include <linux/videodev2.h>
18 #include <media/videobuf-dma-contig.h>
19 #include "cif_isp10_regs.h"
20 #include "cif_isp10.h"
21 #include <linux/pm_runtime.h>
22 #include <linux/vmalloc.h>
23
24 static int cif_isp10_mipi_isr(
25         unsigned int mis,
26         void *cntxt);
27 static int cif_isp10_isp_isr(
28         unsigned int mis,
29         void *cntxt);
30 static void init_output_formats(void);
31
32 struct v4l2_fmtdesc output_formats[MAX_NB_FORMATS];
33
34 /* JPEG quantization tables for JPEG encoding */
35 /* DC luma table according to ISO/IEC 10918-1 annex K */
36 static const unsigned char dc_luma_table_annex_k[] = {
37         0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01,
38         0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
39         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
40         0x08, 0x09, 0x0a, 0x0b
41 };
42
43 /* DC chroma table according to ISO/IEC 10918-1 annex K */
44 static const unsigned char dc_chroma_table_annex_k[] = {
45         0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
46         0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
47         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
48         0x08, 0x09, 0x0a, 0x0b
49 };
50
51 /* AC luma table according to ISO/IEC 10918-1 annex K */
52 static const unsigned char ac_luma_table_annex_k[] = {
53         0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03,
54         0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7d,
55         0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
56         0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
57         0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
58         0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
59         0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
60         0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
61         0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
62         0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
63         0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
64         0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
65         0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
66         0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
67         0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
68         0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
69         0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
70         0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
71         0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
72         0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
73         0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
74         0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
75         0xf9, 0xfa
76 };
77
78 /* AC Chroma table according to ISO/IEC 10918-1 annex K */
79 static const unsigned char ac_chroma_table_annex_k[] = {
80         0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04,
81         0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77,
82         0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
83         0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
84         0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
85         0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
86         0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
87         0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
88         0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
89         0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
90         0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
91         0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
92         0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
93         0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
94         0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
95         0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
96         0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
97         0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
98         0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
99         0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
100         0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
101         0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
102         0xf9, 0xfa
103 };
104
105 /* Standard JPEG quantization tables */
106 /* luma */
107 /* According to JPEG spec:
108  * [
109  *      16, 11, 10, 16,  24,  40,  51,  61,
110  *      12, 12, 14, 19,  26,  58,  60,  55,
111  *      14, 13, 16, 24,  40,  57,  69,  56,
112  *      14, 17, 22, 29,  51,  87,  80,  62,
113  *      18, 22, 37, 56,  68, 109, 103,  77,
114  *      24, 35, 55, 64,  81, 104, 113,  92,
115  *      49, 64, 78, 87, 103, 121, 120, 101,
116  *      72, 92, 95, 98, 112, 100, 103,  99
117  * ]
118  */
119
120 /* CIF needs it in zigzag order */
121 static const unsigned char yq_table_base_zigzag[] = {
122         16, 11, 12, 14, 12, 10, 16, 14,
123         13, 14, 18, 17, 16, 19, 24, 40,
124         26, 24, 22, 22, 24, 49, 35, 37,
125         29, 40, 58, 51, 61, 60, 57, 51,
126         56, 55, 64, 72, 92, 78, 64, 68,
127         87, 69, 55, 56, 80, 109, 81, 87,
128         95, 98, 103, 104, 103, 62, 77, 113,
129         121, 112, 100, 120, 92, 101, 103, 99
130 };
131
132 /* chroma */
133 /* According to JPEG spec:
134  * [
135  *      17, 18, 24, 47, 99, 99, 99, 99,
136  *      18, 21, 26, 66, 99, 99, 99, 99,
137  *      24, 26, 56, 99, 99, 99, 99, 99,
138  *      47, 66, 99, 99, 99, 99, 99, 99,
139  *      99, 99, 99, 99, 99, 99, 99, 99,
140  *      99, 99, 99, 99, 99, 99, 99, 99,
141  *      99, 99, 99, 99, 99, 99, 99, 99,
142  *      99, 99, 99, 99, 99, 99, 99, 99
143  * ]
144  */
145
146 /* CIF needs it in zigzag order */
147 static const unsigned char uvq_table_base_zigzag[] = {
148         17, 18, 18, 24, 21, 24, 47, 26,
149         26, 47, 99, 66, 56, 66, 99, 99,
150         99, 99, 99, 99, 99, 99, 99, 99,
151         99, 99, 99, 99, 99, 99, 99, 99,
152         99, 99, 99, 99, 99, 99, 99, 99,
153         99, 99, 99, 99, 99, 99, 99, 99,
154         99, 99, 99, 99, 99, 99, 99, 99,
155         99, 99, 99, 99, 99, 99, 99, 99
156 };
157
158 static struct cif_isp10_fmt cif_isp10_output_format[] = {
159 /* ************* YUV422 ************* */
160 {
161         .name           = "YUV422-Interleaved",
162         .fourcc = V4L2_PIX_FMT_YUYV,
163         .flags  = 0,
164         .depth  = 16,
165         .rotation = false,
166         .overlay = false,
167 },
168 {
169         .name           = "YUV422-Interleaved",
170         .fourcc = V4L2_PIX_FMT_YUYV,
171         .flags  = 0,
172         .depth  = 16,
173         .rotation = false,
174         .overlay = false,
175 },
176 {
177         .name           = "YVU422-Interleaved",
178         .fourcc = V4L2_PIX_FMT_UYVY,
179         .flags  = 0,
180         .depth  = 16,
181         .rotation = false,
182         .overlay = false,
183 },
184 {
185         .name           = "YUV422-Planar",
186         .fourcc = V4L2_PIX_FMT_YUV422P,
187         .flags  = 0,
188         .depth  = 16,
189         .rotation = false,
190         .overlay = false,
191 },
192 {
193         .name           = "YUV422-Semi-Planar",
194         .fourcc = V4L2_PIX_FMT_NV16,
195         .flags  = 0,
196         .depth  = 16,
197         .rotation = false,
198         .overlay = false,
199 },
200 /* ************* YUV420 ************* */
201 {
202         .name           = "YUV420-Planar",
203         .fourcc = V4L2_PIX_FMT_YUV420,
204         .flags  = 0,
205         .depth  = 12,
206         .rotation = false,
207         .overlay = false,
208 },
209 {
210         .name           = "YUV420-Planar",
211         .fourcc = V4L2_PIX_FMT_YUV420,
212         .flags  = 0,
213         .depth  = 12,
214         .rotation = false,
215         .overlay = false,
216 },
217 {
218         .name           = "YVU420-Planar",
219         .fourcc = V4L2_PIX_FMT_YVU420,
220         .flags  = 0,
221         .depth  = 12,
222         .rotation = false,
223         .overlay = false,
224 },
225 {
226         .name           = "YUV420-Semi-Planar",
227         .fourcc = V4L2_PIX_FMT_NV12,
228         .flags  = 0,
229         .depth  = 12,
230         .rotation = false,
231         .overlay = false,
232 },
233 {
234         .name           = "YVU420-Semi-Planar",
235         .fourcc = V4L2_PIX_FMT_NV21,
236         .flags  = 0,
237         .depth  = 12,
238         .rotation = false,
239         .overlay = false,
240 },
241 /* ************* YUV400 ************* */
242 {
243         .name           = "YVU400-Grey-Planar",
244         .fourcc = V4L2_PIX_FMT_GREY,
245         .flags  = 0,
246         .depth  = 8,
247         .rotation = false,
248         .overlay = false,
249 },
250 /* ************* YUV444 ************* */
251 {
252         .name           = "YVU444-Planar",
253         .fourcc = V4L2_PIX_FMT_YUV444,
254         .flags  = 0,
255         .depth  = 16,
256         .rotation = false,
257         .overlay = false,
258 },
259 {
260         .name           = "YVU444-Semi-Planar",
261         .fourcc = V4L2_PIX_FMT_NV24,
262         .flags  = 0,
263         .depth  = 16,
264         .rotation = false,
265         .overlay = false,
266 },
267 /* ************* JPEG ************* */
268 {
269         .name           = "JPEG",
270         .fourcc = V4L2_PIX_FMT_JPEG,
271         .flags  = 0,
272         .depth  = 16,
273         .rotation = false,
274         .overlay = false,
275 },
276 /* ************ RGB565 *********** */
277 {
278         .name       = "RGB565",
279         .fourcc = V4L2_PIX_FMT_RGB565,
280         .flags  = 0,
281         .depth  = 16,
282         .rotation = false,
283         .overlay = false,
284 },
285 /* ************ SGRBG8 *********** */
286 {
287         .name       = "SGRBG8",
288         .fourcc = V4L2_PIX_FMT_SGRBG8,
289         .flags  = 0,
290         .depth  = 8,
291         .rotation = false,
292         .overlay = false,
293 },
294 };
295
296 struct cif_isp10_hw_error {
297         char *name;
298         unsigned int count;
299         unsigned int mask;
300         unsigned int type;      /* isp:0 ;mipi:1 */
301 };
302
303 static struct cif_isp10_hw_error cif_isp10_hw_errors[] = {
304         {
305          .name = "isp_data_loss",
306          .count = 0,
307          .mask = CIF_ISP_DATA_LOSS,
308          .type = 0,
309          },
310         {
311          .name = "isp_pic_size_err",
312          .count = 0,
313          .mask = CIF_ISP_PIC_SIZE_ERROR,
314          .type = 0,
315          },
316         {
317          .name = "mipi_fifo_err",
318          .count = 0,
319          .mask = CIF_MIPI_SYNC_FIFO_OVFLW(1),
320          .type = 1,
321          },
322         {
323          .name = "dphy_err_sot",
324          .count = 0,
325          .mask = CIF_MIPI_ERR_SOT(3),
326          .type = 1,
327          },
328         {
329          .name = "dphy_err_sot_sync",
330          .count = 0,
331          .mask = CIF_MIPI_ERR_SOT_SYNC(3),
332          .type = 1,
333          },
334         {
335          .name = "dphy_err_eot_sync",
336          .count = 0,
337          .mask = CIF_MIPI_ERR_EOT_SYNC(3),
338          .type = 1,
339          },
340         {
341          .name = "dphy_err_ctrl",
342          .count = 0,
343          .mask = CIF_MIPI_ERR_CTRL(3),
344          .type = 1,
345          },
346         {
347          .name = "csi_err_protocol",
348          .count = 0,
349          .mask = CIF_MIPI_ERR_PROTOCOL,
350          .type = 2,
351          },
352         {
353          .name = "csi_err_ecc1",
354          .count = 0,
355          .mask = CIF_MIPI_ERR_ECC1,
356          .type = 2,
357          },
358         {
359          .name = "csi_err_ecc2",
360          .count = 0,
361          .mask = CIF_MIPI_ERR_ECC2,
362          .type = 2,
363          },
364         {
365          .name = "csi_err_cs",
366          .count = 0,
367          .mask = CIF_MIPI_ERR_CS,
368          .type = 2,
369          },
370         {
371          .name = "fifo_ovf",
372          .count = 0,
373          .mask = (3 << 0),
374          .type = 2,
375          },
376         {
377          .name = "isp_outform",
378          .count = 0,
379          .mask = CIF_ISP_ERR_OUTFORM_SIZE,
380          .type = 0,
381          },
382         {
383          .name = "isp_stab",
384          .count = 0,
385          .mask = CIF_ISP_ERR_IS_SIZE,
386          .type = 0,
387          },
388         {
389          .name = "isp_inform",
390          .count = 0,
391          .mask = CIF_ISP_ERR_INFORM_SIZE,
392          .type = 0,
393         }
394 };
395
396 /* Defines */
397
398 #define CIF_ISP10_INVALID_BUFF_ADDR ((u32)~0)
399 #define CIF_ISP10_MI_IS_BUSY(dev)\
400         (dev->config.mi_config.mp.busy ||\
401         dev->config.mi_config.sp.busy ||\
402         dev->config.mi_config.dma.busy)
403 enum {
404         CIF_ISP10_ASYNC_JPEG = 0x1,
405         CIF_ISP10_ASYNC_YCFLT = 0x2,
406         CIF_ISP10_ASYNC_ISM = 0x4,
407         CIF_ISP10_ASYNC_DMA = 0x8
408 };
409
410 #define CIF_ISP10_ALWAYS_ASYNC 0x00
411 #define CIF_ISP10_ALWAYS_STALL_ON_NO_BUFS (false)
412
413 #ifndef DIV_ROUND_UP
414 #define DIV_ROUND_UP(x, y) (((x) + (y) - 1) / (y))
415 #endif
416
417 #ifndef DIV_TRUNCATE
418 #define DIV_TRUNCATE(x, y) ((x) / (y))
419 #endif
420
421 /* Structures and Types */
422
423 /* Static Functions */
424 static const char *cif_isp10_interface_string(
425         enum pltfrm_cam_itf_type itf)
426 {
427         switch (itf) {
428         case PLTFRM_CAM_ITF_MIPI:
429                 return "MIPI";
430         case PLTFRM_CAM_ITF_BT601_8:
431                 return "DVP_BT601_8Bit";
432         case PLTFRM_CAM_ITF_BT656_8:
433                 return "DVP_BT656_8Bit";
434         case PLTFRM_CAM_ITF_BT601_10:
435                 return "DVP_BT601_10Bit";
436         case PLTFRM_CAM_ITF_BT656_10:
437                 return "DVP_BT656_10Bit";
438         case PLTFRM_CAM_ITF_BT601_12:
439                 return "DVP_BT601_12Bit";
440         case PLTFRM_CAM_ITF_BT656_12:
441                 return "DVP_BT656_12Bit";
442         case PLTFRM_CAM_ITF_BT601_16:
443                 return "DVP_BT601_16Bit";
444         case PLTFRM_CAM_ITF_BT656_16:
445                 return "DVP_BT656_16Bit";
446         default:
447                 return "UNKNOWN/UNSUPPORTED";
448         }
449 }
450
451 static const char *cif_isp10_img_src_state_string(
452         enum cif_isp10_img_src_state state)
453 {
454         switch (state) {
455         case CIF_ISP10_IMG_SRC_STATE_OFF:
456                 return "OFF";
457         case CIF_ISP10_IMG_SRC_STATE_SW_STNDBY:
458                 return "SW_STNDBY";
459         case CIF_ISP10_IMG_SRC_STATE_STREAMING:
460                 return "STREAMING";
461         default:
462                 return "UNKNOWN/UNSUPPORTED";
463         }
464 }
465
466 static const char *cif_isp10_state_string(
467         enum cif_isp10_state state)
468 {
469         switch (state) {
470         case CIF_ISP10_STATE_DISABLED:
471                 return "DISABLED";
472         case CIF_ISP10_STATE_INACTIVE:
473                 return "INACTIVE";
474         case CIF_ISP10_STATE_READY:
475                 return "READY";
476         case CIF_ISP10_STATE_STREAMING:
477                 return "STREAMING";
478         default:
479                 return "UNKNOWN/UNSUPPORTED";
480         }
481 }
482
483 static const char *cif_isp10_pm_state_string(
484         enum cif_isp10_pm_state pm_state)
485 {
486         switch (pm_state) {
487         case CIF_ISP10_PM_STATE_OFF:
488                 return "OFF";
489         case CIF_ISP10_PM_STATE_SW_STNDBY:
490                 return "STANDBY";
491         case CIF_ISP10_PM_STATE_SUSPENDED:
492                 return "SUSPENDED";
493         case CIF_ISP10_PM_STATE_STREAMING:
494                 return "STREAMING";
495         default:
496                 return "UNKNOWN/UNSUPPORTED";
497         }
498 }
499
500 static const char *cif_isp10_stream_id_string(
501         enum cif_isp10_stream_id stream_id)
502 {
503         switch (stream_id) {
504         case CIF_ISP10_STREAM_SP:
505                 return "SP";
506         case CIF_ISP10_STREAM_MP:
507                 return "MP";
508         case CIF_ISP10_STREAM_DMA:
509                 return "DMA";
510         case CIF_ISP10_STREAM_ISP:
511                 return "ISP";
512         default:
513                 return "UNKNOWN/UNSUPPORTED";
514         }
515 }
516
517 static const char *cif_isp10_inp_string(
518         enum cif_isp10_inp inp)
519 {
520         switch (inp) {
521         case CIF_ISP10_INP_CSI:
522                 return "CSI";
523         case CIF_ISP10_INP_CPI:
524                 return "CPI";
525         case CIF_ISP10_INP_DMA:
526                 return "DMA(ISP)";
527         case CIF_ISP10_INP_DMA_IE:
528                 return "DMA(Image Effects)";
529         case CIF_ISP10_INP_DMA_SP:
530                 return "DMA(SP)";
531         default:
532                 return "UNKNOWN/UNSUPPORTED";
533         }
534 }
535
536 enum cif_isp10_inp cif_isp10_input_index2inp(
537         struct cif_isp10_device *dev,
538         unsigned int input)
539 {
540         struct pltfrm_cam_itf itf;
541
542         if (input >= dev->img_src_cnt)
543                 return input - dev->img_src_cnt + CIF_ISP10_INP_DMA;
544
545         cif_isp10_pltfrm_g_interface_config(
546                 dev->img_src_array[input],
547                 &itf);
548         if (PLTFRM_CAM_ITF_IS_MIPI(itf.type))
549                 return CIF_ISP10_INP_CSI;
550         if (PLTFRM_CAM_ITF_IS_DVP(itf.type))
551                 return CIF_ISP10_INP_CPI;
552
553         return -EINVAL;
554 }
555
556 static const char *cif_isp10_pix_fmt_string(int pixfmt)
557 {
558         switch (pixfmt) {
559         case CIF_YUV400:
560                 return "YUV400";
561         case CIF_YUV420I:
562                 return "YUV420I";
563         case CIF_YUV420SP:
564                 return "YUV420SP";
565         case CIF_YUV420P:
566                 return "YUV420P";
567         case CIF_YVU420I:
568                 return "YVU420I";
569         case CIF_YVU420SP:
570                 return "YVU420SP";
571         case CIF_YVU420P:
572                 return "YVU420P";
573         case CIF_YUV422I:
574                 return "YUV422I";
575         case CIF_YUV422SP:
576                 return "YUV422SP";
577         case CIF_YUV422P:
578                 return "YUV422P";
579         case CIF_YVU422I:
580                 return "YVU422I";
581         case CIF_YVU422SP:
582                 return "YVU422SP";
583         case CIF_YVU422P:
584                 return "YVU422P";
585         case CIF_YUV444I:
586                 return "YUV444I";
587         case CIF_YUV444SP:
588                 return "YUV444SP";
589         case CIF_YUV444P:
590                 return "YUV444P";
591         case CIF_YVU444I:
592                 return "YVU444I";
593         case CIF_YVU444SP:
594                 return "YVU444SP";
595         case CIF_YVU444P:
596                 return "YVU444SP";
597         case CIF_UYV400:
598                 return "UYV400";
599         case CIF_UYV420I:
600                 return "UYV420I";
601         case CIF_UYV420SP:
602                 return "UYV420SP";
603         case CIF_UYV420P:
604                 return "UYV420P";
605         case CIF_VYU420I:
606                 return "VYU420I";
607         case CIF_VYU420SP:
608                 return "VYU420SP";
609         case CIF_VYU420P:
610                 return "VYU420P";
611         case CIF_UYV422I:
612                 return "UYV422I";
613         case CIF_UYV422SP:
614                 return "UYV422I";
615         case CIF_UYV422P:
616                 return "UYV422P";
617         case CIF_VYU422I:
618                 return "VYU422I";
619         case CIF_VYU422SP:
620                 return "VYU422SP";
621         case CIF_VYU422P:
622                 return "VYU422P";
623         case CIF_UYV444I:
624                 return "UYV444I";
625         case CIF_UYV444SP:
626                 return "UYV444SP";
627         case CIF_UYV444P:
628                 return "UYV444P";
629         case CIF_VYU444I:
630                 return "VYU444I";
631         case CIF_VYU444SP:
632                 return "VYU444SP";
633         case CIF_VYU444P:
634                 return "VYU444P";
635         case CIF_RGB565:
636                 return "RGB565";
637         case CIF_RGB666:
638                 return "RGB666";
639         case CIF_RGB888:
640                 return "RGB888";
641         case CIF_BAYER_SBGGR8:
642                 return "BAYER BGGR8";
643         case CIF_BAYER_SGBRG8:
644                 return "BAYER GBRG8";
645         case CIF_BAYER_SGRBG8:
646                 return "BAYER GRBG8";
647         case CIF_BAYER_SRGGB8:
648                 return "BAYER RGGB8";
649         case CIF_BAYER_SBGGR10:
650                 return "BAYER BGGR10";
651         case CIF_BAYER_SGBRG10:
652                 return "BAYER GBRG10";
653         case CIF_BAYER_SGRBG10:
654                 return "BAYER GRBG10";
655         case CIF_BAYER_SRGGB10:
656                 return "BAYER RGGB10";
657         case CIF_BAYER_SBGGR12:
658                 return "BAYER BGGR12";
659         case CIF_BAYER_SGBRG12:
660                 return "BAYER GBRG12";
661         case CIF_BAYER_SGRBG12:
662                 return "BAYER GRBG12";
663         case CIF_BAYER_SRGGB12:
664                 return "BAYER RGGB12";
665         case CIF_DATA:
666                 return "DATA";
667         case CIF_JPEG:
668                 return "JPEG";
669         default:
670                 return "unknown/unsupported";
671         }
672 }
673
674 static void cif_isp10_debug_print_mi_sp(struct cif_isp10_device *dev)
675 {
676         cif_isp10_pltfrm_pr_info(dev->dev,
677                 "\n  MI_CTRL 0x%08x/0x%08x\n"
678                 "  MI_STATUS 0x%08x\n"
679                 "  MI_RIS 0x%08x/0x%08x\n"
680                 "  MI_IMSC 0x%08x\n"
681                 "  MI_SP_Y_SIZE %d/%d\n"
682                 "  MI_SP_CB_SIZE %d/%d\n"
683                 "  MI_SP_CR_SIZE %d/%d\n"
684                 "  MI_SP_PIC_WIDTH %d\n"
685                 "  MI_SP_PIC_HEIGHT %d\n"
686                 "  MI_SP_PIC_LLENGTH %d\n"
687                 "  MI_SP_PIC_SIZE %d\n"
688                 "  MI_SP_Y_BASE_AD 0x%08x/0x%08x\n"
689                 "  MI_SP_Y_OFFS_CNT %d/%d\n"
690                 "  MI_SP_Y_OFFS_CNT_START %d\n"
691                 "  MI_SP_CB_OFFS_CNT %d/%d\n"
692                 "  MI_SP_CB_OFFS_CNT_START %d\n"
693                 "  MI_SP_CR_OFFS_CNT %d/%d\n"
694                 "  MI_SP_CR_OFFS_CNT_START %d\n",
695                 cif_ioread32(dev->config.base_addr +
696                         CIF_MI_CTRL),
697                 cif_ioread32(dev->config.base_addr +
698                         CIF_MI_CTRL_SHD),
699                 cif_ioread32(dev->config.base_addr +
700                         CIF_MI_STATUS),
701                 cif_ioread32(dev->config.base_addr +
702                         CIF_MI_RIS),
703                 cif_ioread32(dev->config.base_addr +
704                         CIF_MI_MIS),
705                 cif_ioread32(dev->config.base_addr +
706                         CIF_MI_IMSC),
707                 cif_ioread32(dev->config.base_addr +
708                         CIF_MI_SP_Y_SIZE_INIT),
709                 cif_ioread32(dev->config.base_addr +
710                         CIF_MI_SP_Y_SIZE_SHD),
711                 cif_ioread32(dev->config.base_addr +
712                         CIF_MI_SP_CB_SIZE_INIT),
713                 cif_ioread32(dev->config.base_addr +
714                         CIF_MI_SP_CB_SIZE_SHD),
715                 cif_ioread32(dev->config.base_addr +
716                         CIF_MI_SP_CR_SIZE_INIT),
717                 cif_ioread32(dev->config.base_addr +
718                         CIF_MI_SP_CR_SIZE_SHD),
719                 cif_ioread32(dev->config.base_addr +
720                         CIF_MI_SP_Y_PIC_WIDTH),
721                 cif_ioread32(dev->config.base_addr +
722                         CIF_MI_SP_Y_PIC_HEIGHT),
723                 cif_ioread32(dev->config.base_addr +
724                         CIF_MI_SP_Y_LLENGTH),
725                 cif_ioread32(dev->config.base_addr +
726                         CIF_MI_SP_Y_PIC_SIZE),
727                 cif_ioread32(dev->config.base_addr +
728                         CIF_MI_SP_Y_BASE_AD_INIT),
729                 cif_ioread32(dev->config.base_addr +
730                         CIF_MI_SP_Y_BASE_AD_SHD),
731                 cif_ioread32(dev->config.base_addr +
732                         CIF_MI_SP_Y_OFFS_CNT_INIT),
733                 cif_ioread32(dev->config.base_addr +
734                         CIF_MI_SP_Y_OFFS_CNT_SHD),
735                 cif_ioread32(dev->config.base_addr +
736                         CIF_MI_SP_Y_OFFS_CNT_START),
737                 cif_ioread32(dev->config.base_addr +
738                         CIF_MI_SP_CB_OFFS_CNT_INIT),
739                 cif_ioread32(dev->config.base_addr +
740                         CIF_MI_SP_CB_OFFS_CNT_SHD),
741                 cif_ioread32(dev->config.base_addr +
742                         CIF_MI_SP_CB_OFFS_CNT_START),
743                 cif_ioread32(dev->config.base_addr +
744                         CIF_MI_SP_CR_OFFS_CNT_INIT),
745                 cif_ioread32(dev->config.base_addr +
746                         CIF_MI_SP_CR_OFFS_CNT_SHD),
747                 cif_ioread32(dev->config.base_addr +
748                         CIF_MI_SP_CR_OFFS_CNT_START));
749 }
750
751 static void cif_isp10_debug_print_mi_mp(struct cif_isp10_device *dev)
752 {
753         cif_isp10_pltfrm_pr_info(dev->dev,
754                 "\n  MI_CTRL 0x%08x/0x%08x\n"
755                 "  MI_STATUS 0x%08x\n"
756                 "  MI_BYTE_CNT %d\n"
757                 "  MI_RIS 0x%08x/0x%08x\n"
758                 "  MI_IMSC 0x%08x\n"
759                 "  MI_MP_Y_SIZE %d/%d\n"
760                 "  MI_MP_CB_SIZE %d/%d\n"
761                 "  MI_MP_CR_SIZE %d/%d\n"
762                 "  MI_MP_Y_BASE_AD 0x%08x/0x%08x\n"
763                 "  MI_MP_Y_OFFS_CNT %d/%d\n"
764                 "  MI_MP_Y_OFFS_CNT_START %d\n"
765                 "  MI_MP_CB_OFFS_CNT %d/%d\n"
766                 "  MI_MP_CB_OFFS_CNT_START %d\n"
767                 "  MI_MP_CR_OFFS_CNT %d/%d\n"
768                 "  MI_MP_CR_OFFS_CNT_START %d\n",
769                 cif_ioread32(dev->config.base_addr +
770                         CIF_MI_CTRL),
771                 cif_ioread32(dev->config.base_addr +
772                         CIF_MI_CTRL_SHD),
773                 cif_ioread32(dev->config.base_addr +
774                         CIF_MI_STATUS),
775                 cif_ioread32(dev->config.base_addr +
776                         CIF_MI_BYTE_CNT),
777                 cif_ioread32(dev->config.base_addr +
778                         CIF_MI_RIS),
779                 cif_ioread32(dev->config.base_addr +
780                         CIF_MI_MIS),
781                 cif_ioread32(dev->config.base_addr +
782                         CIF_MI_IMSC),
783                 cif_ioread32(dev->config.base_addr +
784                         CIF_MI_MP_Y_SIZE_INIT),
785                 cif_ioread32(dev->config.base_addr +
786                         CIF_MI_MP_Y_SIZE_SHD),
787                 cif_ioread32(dev->config.base_addr +
788                         CIF_MI_MP_CB_SIZE_INIT),
789                 cif_ioread32(dev->config.base_addr +
790                         CIF_MI_MP_CB_SIZE_SHD),
791                 cif_ioread32(dev->config.base_addr +
792                         CIF_MI_MP_CR_SIZE_INIT),
793                 cif_ioread32(dev->config.base_addr +
794                         CIF_MI_MP_CR_SIZE_SHD),
795                 cif_ioread32(dev->config.base_addr +
796                         CIF_MI_MP_Y_BASE_AD_INIT),
797                 cif_ioread32(dev->config.base_addr +
798                         CIF_MI_MP_Y_BASE_AD_SHD),
799                 cif_ioread32(dev->config.base_addr +
800                         CIF_MI_MP_Y_OFFS_CNT_INIT),
801                 cif_ioread32(dev->config.base_addr +
802                         CIF_MI_MP_Y_OFFS_CNT_SHD),
803                 cif_ioread32(dev->config.base_addr +
804                         CIF_MI_MP_Y_OFFS_CNT_START),
805                 cif_ioread32(dev->config.base_addr +
806                         CIF_MI_MP_CB_OFFS_CNT_INIT),
807                 cif_ioread32(dev->config.base_addr +
808                         CIF_MI_MP_CB_OFFS_CNT_SHD),
809                 cif_ioread32(dev->config.base_addr +
810                         CIF_MI_MP_CB_OFFS_CNT_START),
811                 cif_ioread32(dev->config.base_addr +
812                         CIF_MI_MP_CR_OFFS_CNT_INIT),
813                 cif_ioread32(dev->config.base_addr +
814                         CIF_MI_MP_CR_OFFS_CNT_SHD),
815                 cif_ioread32(dev->config.base_addr +
816                         CIF_MI_MP_CR_OFFS_CNT_START));
817 }
818
819 static void cif_isp10_debug_print_srsz(struct cif_isp10_device *dev)
820 {
821         cif_isp10_pltfrm_pr_info(dev->dev,
822                 "\n  SRSZ_CTRL 0x%08x/0x%08x\n"
823                 "  SRSZ_SCALE_HY %d/%d\n"
824                 "  SRSZ_SCALE_HCB %d/%d\n"
825                 "  SRSZ_SCALE_HCR %d/%d\n"
826                 "  SRSZ_SCALE_VY %d/%d\n"
827                 "  SRSZ_SCALE_VC %d/%d\n"
828                 "  SRSZ_PHASE_HY %d/%d\n"
829                 "  SRSZ_PHASE_HC %d/%d\n"
830                 "  SRSZ_PHASE_VY %d/%d\n"
831                 "  SRSZ_PHASE_VC %d/%d\n",
832                 cif_ioread32(dev->config.base_addr +
833                         CIF_SRSZ_CTRL),
834                 cif_ioread32(dev->config.base_addr +
835                         CIF_SRSZ_CTRL_SHD),
836                 cif_ioread32(dev->config.base_addr +
837                         CIF_SRSZ_SCALE_HY),
838                 cif_ioread32(dev->config.base_addr +
839                         CIF_SRSZ_SCALE_HY_SHD),
840                 cif_ioread32(dev->config.base_addr +
841                         CIF_SRSZ_SCALE_HCB),
842                 cif_ioread32(dev->config.base_addr +
843                         CIF_SRSZ_SCALE_HCB_SHD),
844                 cif_ioread32(dev->config.base_addr +
845                         CIF_SRSZ_SCALE_HCR),
846                 cif_ioread32(dev->config.base_addr +
847                         CIF_SRSZ_SCALE_HCR_SHD),
848                 cif_ioread32(dev->config.base_addr +
849                         CIF_SRSZ_SCALE_VY),
850                 cif_ioread32(dev->config.base_addr +
851                         CIF_SRSZ_SCALE_VY_SHD),
852                 cif_ioread32(dev->config.base_addr +
853                         CIF_SRSZ_SCALE_VC),
854                 cif_ioread32(dev->config.base_addr +
855                         CIF_SRSZ_SCALE_VC_SHD),
856                 cif_ioread32(dev->config.base_addr +
857                         CIF_SRSZ_PHASE_HY),
858                 cif_ioread32(dev->config.base_addr +
859                         CIF_SRSZ_PHASE_HY_SHD),
860                 cif_ioread32(dev->config.base_addr +
861                         CIF_SRSZ_PHASE_HC),
862                 cif_ioread32(dev->config.base_addr +
863                         CIF_SRSZ_PHASE_HC_SHD),
864                 cif_ioread32(dev->config.base_addr +
865                         CIF_SRSZ_PHASE_VY),
866                 cif_ioread32(dev->config.base_addr +
867                         CIF_SRSZ_PHASE_VY_SHD),
868                 cif_ioread32(dev->config.base_addr +
869                         CIF_SRSZ_PHASE_VC),
870                 cif_ioread32(dev->config.base_addr +
871                         CIF_SRSZ_PHASE_VC_SHD));
872 }
873
874 static void cif_isp10_debug_print_mrsz(struct cif_isp10_device *dev)
875 {
876         cif_isp10_pltfrm_pr_info(dev->dev,
877                 "\n  MRSZ_CTRL 0x%08x/0x%08x\n"
878                 "  MRSZ_SCALE_HY %d/%d\n"
879                 "  MRSZ_SCALE_HCB %d/%d\n"
880                 "  MRSZ_SCALE_HCR %d/%d\n"
881                 "  MRSZ_SCALE_VY %d/%d\n"
882                 "  MRSZ_SCALE_VC %d/%d\n"
883                 "  MRSZ_PHASE_HY %d/%d\n"
884                 "  MRSZ_PHASE_HC %d/%d\n"
885                 "  MRSZ_PHASE_VY %d/%d\n"
886                 "  MRSZ_PHASE_VC %d/%d\n",
887                 cif_ioread32(dev->config.base_addr +
888                         CIF_MRSZ_CTRL),
889                 cif_ioread32(dev->config.base_addr +
890                         CIF_MRSZ_CTRL_SHD),
891                 cif_ioread32(dev->config.base_addr +
892                         CIF_MRSZ_SCALE_HY),
893                 cif_ioread32(dev->config.base_addr +
894                         CIF_MRSZ_SCALE_HY_SHD),
895                 cif_ioread32(dev->config.base_addr +
896                         CIF_MRSZ_SCALE_HCB),
897                 cif_ioread32(dev->config.base_addr +
898                         CIF_MRSZ_SCALE_HCB_SHD),
899                 cif_ioread32(dev->config.base_addr +
900                         CIF_MRSZ_SCALE_HCR),
901                 cif_ioread32(dev->config.base_addr +
902                         CIF_MRSZ_SCALE_HCR_SHD),
903                 cif_ioread32(dev->config.base_addr +
904                         CIF_MRSZ_SCALE_VY),
905                 cif_ioread32(dev->config.base_addr +
906                         CIF_MRSZ_SCALE_VY_SHD),
907                 cif_ioread32(dev->config.base_addr +
908                         CIF_MRSZ_SCALE_VC),
909                 cif_ioread32(dev->config.base_addr +
910                         CIF_MRSZ_SCALE_VC_SHD),
911                 cif_ioread32(dev->config.base_addr +
912                         CIF_MRSZ_PHASE_HY),
913                 cif_ioread32(dev->config.base_addr +
914                         CIF_MRSZ_PHASE_HY_SHD),
915                 cif_ioread32(dev->config.base_addr +
916                         CIF_MRSZ_PHASE_HC),
917                 cif_ioread32(dev->config.base_addr +
918                         CIF_MRSZ_PHASE_HC_SHD),
919                 cif_ioread32(dev->config.base_addr +
920                         CIF_MRSZ_PHASE_VY),
921                 cif_ioread32(dev->config.base_addr +
922                         CIF_MRSZ_PHASE_VY_SHD),
923                 cif_ioread32(dev->config.base_addr +
924                         CIF_MRSZ_PHASE_VC),
925                 cif_ioread32(dev->config.base_addr +
926                         CIF_MRSZ_PHASE_VC_SHD));
927 }
928
929 static void cif_isp10_debug_print_block(
930         struct cif_isp10_device *dev,
931         const char *block_name)
932 {
933         if (!strncmp(block_name, "all", 3)) {
934                 cif_isp10_debug_print_srsz(dev);
935                 cif_isp10_debug_print_mrsz(dev);
936                 cif_isp10_debug_print_mi_sp(dev);
937                 cif_isp10_debug_print_mi_mp(dev);
938         } else if (!strncmp(block_name, "srsz", 4)) {
939                 cif_isp10_debug_print_srsz(dev);
940         } else if (!strncmp(block_name, "mrsz", 4)) {
941                 cif_isp10_debug_print_mrsz(dev);
942         } else if (!strncmp(block_name, "mi_sp", 5)) {
943                 cif_isp10_debug_print_mi_sp(dev);
944         } else if (!strncmp(block_name, "mi_mp", 5)) {
945                 cif_isp10_debug_print_mi_mp(dev);
946         } else {
947                 cif_isp10_pltfrm_pr_err(dev->dev,
948                         "unknown block %s\n", block_name);
949         }
950 }
951
952 static u32 cif_isp10_calc_llength(
953         u32 width,
954         u32 stride,
955         enum cif_isp10_pix_fmt pix_fmt)
956 {
957         if (stride == 0)
958                 return width;
959
960         if (CIF_ISP10_PIX_FMT_IS_YUV(pix_fmt)) {
961                 u32 num_cplanes =
962                         CIF_ISP10_PIX_FMT_YUV_GET_NUM_CPLANES(pix_fmt);
963                 if (num_cplanes == 0)
964                         return 8 * stride / CIF_ISP10_PIX_FMT_GET_BPP(pix_fmt);
965                 else
966                         return stride;
967         } else if (CIF_ISP10_PIX_FMT_IS_RGB(pix_fmt)) {
968                 return 8 * stride / CIF_ISP10_PIX_FMT_GET_BPP(pix_fmt);
969         } else {
970                 return width;
971         }
972 }
973
974 static int cif_isp10_set_pm_state(
975         struct cif_isp10_device *dev,
976         enum cif_isp10_pm_state pm_state)
977 {
978         cif_isp10_pltfrm_pr_dbg(dev->dev, "%s -> %s\n",
979                 cif_isp10_pm_state_string(dev->pm_state),
980                 cif_isp10_pm_state_string(pm_state));
981
982         if (dev->pm_state == pm_state)
983                 return 0;
984
985         switch (pm_state) {
986         case CIF_ISP10_PM_STATE_OFF:
987         case CIF_ISP10_PM_STATE_SUSPENDED:
988                 if ((dev->pm_state == CIF_ISP10_PM_STATE_SW_STNDBY) ||
989                         (dev->pm_state == CIF_ISP10_PM_STATE_STREAMING)) {
990                         pm_runtime_put_sync(dev->dev);
991                 }
992                 break;
993         case CIF_ISP10_PM_STATE_SW_STNDBY:
994         case CIF_ISP10_PM_STATE_STREAMING:
995                 if ((dev->pm_state == CIF_ISP10_PM_STATE_OFF) ||
996                         (dev->pm_state == CIF_ISP10_PM_STATE_SUSPENDED)) {
997                         pm_runtime_get_sync(dev->dev);
998                 }
999                 break;
1000         default:
1001                 cif_isp10_pltfrm_pr_err(dev->dev,
1002                         "unknown or unsupported PM state %d\n", pm_state);
1003                 return -EINVAL;
1004         }
1005
1006         dev->pm_state = pm_state;
1007
1008         return 0;
1009 }
1010
1011 static int cif_isp10_img_src_set_state(
1012         struct cif_isp10_device *dev,
1013         enum cif_isp10_img_src_state state)
1014 {
1015         int ret = 0;
1016
1017         cif_isp10_pltfrm_pr_dbg(dev->dev, "%s -> %s\n",
1018                 cif_isp10_img_src_state_string(dev->img_src_state),
1019                 cif_isp10_img_src_state_string(state));
1020
1021         if (dev->img_src_state == state)
1022                 return 0;
1023
1024         switch (state) {
1025         case CIF_ISP10_IMG_SRC_STATE_OFF:
1026                 ret = cif_isp10_img_src_s_power(dev->img_src, false);
1027                 break;
1028         case CIF_ISP10_IMG_SRC_STATE_SW_STNDBY:
1029                 if (dev->img_src_state == CIF_ISP10_IMG_SRC_STATE_STREAMING) {
1030                         ret = cif_isp10_img_src_s_streaming(
1031                                 dev->img_src, false);
1032                 } else {
1033                         ret = cif_isp10_img_src_s_power(dev->img_src, true);
1034                 }
1035                 break;
1036         case CIF_ISP10_IMG_SRC_STATE_STREAMING:
1037                 if (dev->config.flash_mode !=
1038                         CIF_ISP10_FLASH_MODE_OFF)
1039                         cif_isp10_img_src_s_ctrl(dev->img_src,
1040                                 CIF_ISP10_CID_FLASH_MODE,
1041                                 dev->config.flash_mode);
1042                 ret = cif_isp10_img_src_s_streaming(dev->img_src, true);
1043                 break;
1044         default:
1045                 break;
1046         }
1047
1048         if ((dev->config.flash_mode != CIF_ISP10_FLASH_MODE_OFF) &&
1049                 (IS_ERR_VALUE(ret) ||
1050                 (state == CIF_ISP10_IMG_SRC_STATE_OFF)))
1051                 cif_isp10_img_src_s_ctrl(dev->img_src,
1052                         CIF_ISP10_CID_FLASH_MODE,
1053                         CIF_ISP10_FLASH_MODE_OFF);
1054
1055         if (!IS_ERR_VALUE(ret))
1056                 dev->img_src_state = state;
1057         else
1058                 cif_isp10_pltfrm_pr_err(dev->dev,
1059                         "failed with err %d\n", ret);
1060
1061         return ret;
1062 }
1063
1064 static int cif_isp10_img_srcs_init(
1065         struct cif_isp10_device *dev)
1066 {
1067         int ret = 0;
1068
1069         memset(dev->img_src_array, 0x00, sizeof(dev->img_src_array));
1070         dev->img_src_cnt = cif_isp10_pltfrm_get_img_src_device(dev->dev,
1071                 dev->img_src_array, CIF_ISP10_NUM_INPUTS);
1072
1073         if (dev->img_src_cnt > 0)
1074                 return 0;
1075
1076         dev->img_src_cnt = 0;
1077         ret = -EFAULT;
1078
1079         cif_isp10_pltfrm_pr_err(dev->dev,
1080                 "failed with error %d\n", ret);
1081         return ret;
1082 }
1083
1084 static int cif_isp10_img_src_select_strm_fmt(
1085         struct cif_isp10_device *dev)
1086 {
1087         int ret = 0;
1088         u32 index;
1089         struct cif_isp10_strm_fmt_desc strm_fmt_desc;
1090         struct cif_isp10_strm_fmt request_strm_fmt;
1091         bool matching_format_found = false;
1092         bool better_match = false;
1093         u32 target_width, target_height;
1094         u32 img_src_width, img_src_height;
1095         u32 best_diff = ~0;
1096         int vblanking;
1097
1098         if (IS_ERR_OR_NULL(dev->img_src)) {
1099                 cif_isp10_pltfrm_pr_err(dev->dev,
1100                         "no image source selected as input (call s_input first)\n");
1101                 ret = -EFAULT;
1102                 goto err;
1103         }
1104
1105         ret = cif_isp10_get_target_frm_size(dev,
1106                 &target_width, &target_height);
1107         if (IS_ERR_VALUE(ret))
1108                 goto err;
1109
1110         /* find the best matching format from the image source */
1111         /* TODO: frame interval and pixel format handling */
1112         for (index = 0;; index++) {
1113                 if (IS_ERR_VALUE(cif_isp10_img_src_enum_strm_fmts(dev->img_src,
1114                         index, &strm_fmt_desc)))
1115                         break;
1116                 if (!strm_fmt_desc.discrete_frmsize) {
1117                         if (strm_fmt_desc.min_frmsize.width >= target_width)
1118                                 img_src_width = strm_fmt_desc.min_frmsize.width;
1119                         else if (strm_fmt_desc.max_frmsize.width >=
1120                                 target_width)
1121                                 img_src_width = target_width;
1122                         else
1123                                 img_src_width = strm_fmt_desc.max_frmsize.width;
1124                         if (strm_fmt_desc.min_frmsize.height >= target_height)
1125                                 img_src_height =
1126                                         strm_fmt_desc.min_frmsize.height;
1127                         else if (strm_fmt_desc.max_frmsize.height >=
1128                                 target_height)
1129                                 img_src_height = target_height;
1130                         else
1131                                 img_src_height =
1132                                         strm_fmt_desc.max_frmsize.height;
1133                 } else {
1134                         img_src_width = strm_fmt_desc.min_frmsize.width;
1135                         img_src_height = strm_fmt_desc.min_frmsize.height;
1136                 }
1137                 if ((img_src_width >= target_width) &&
1138                         (img_src_height >= target_height)) {
1139                         u32 diff = abs(
1140                                 target_height -
1141                                 (target_width * img_src_height /
1142                                 img_src_width));
1143                         if (matching_format_found) {
1144                                 if (dev->config.jpeg_config.enable &&
1145                                 ((img_src_width >=
1146                                 request_strm_fmt.frm_fmt.width) &&
1147                                 (img_src_height >
1148                                 request_strm_fmt.frm_fmt.height)))
1149                                         /*
1150                                          * for image capturing we try to
1151                                          * maximize the size
1152                                          */
1153                                         better_match = true;
1154                                 else if (!dev->config.jpeg_config.enable &&
1155                                 ((strm_fmt_desc.min_intrvl.denominator /
1156                                 strm_fmt_desc.min_intrvl.numerator) >
1157                                 (request_strm_fmt.frm_intrvl.denominator /
1158                                 request_strm_fmt.frm_intrvl.numerator)))
1159                                         /* maximize fps */
1160                                         better_match = true;
1161                                 else if (!dev->config.jpeg_config.enable &&
1162                                 ((strm_fmt_desc.min_intrvl.denominator /
1163                                 strm_fmt_desc.min_intrvl.numerator) ==
1164                                 (request_strm_fmt.frm_intrvl.denominator /
1165                                 request_strm_fmt.frm_intrvl.numerator)) &&
1166                                 (diff < best_diff))
1167                                         /*
1168                                          * chose better aspect ratio
1169                                          * match if fps equal
1170                                          */
1171                                         better_match = true;
1172                                 else
1173                                         better_match = false;
1174                         }
1175
1176                         if (!matching_format_found ||
1177                                 better_match) {
1178                                 request_strm_fmt.frm_fmt.width =
1179                                         strm_fmt_desc.min_frmsize.width;
1180                                 request_strm_fmt.frm_fmt.height =
1181                                         strm_fmt_desc.min_frmsize.height;
1182                                 request_strm_fmt.frm_fmt.std_id =
1183                                         strm_fmt_desc.std_id;
1184                                 request_strm_fmt.frm_fmt.pix_fmt =
1185                                         strm_fmt_desc.pix_fmt;
1186                                 request_strm_fmt.frm_intrvl.numerator =
1187                                         strm_fmt_desc.min_intrvl.numerator;
1188                                 request_strm_fmt.frm_intrvl.denominator =
1189                                         strm_fmt_desc.min_intrvl.denominator;
1190                                 request_strm_fmt.frm_fmt.defrect =
1191                                         strm_fmt_desc.defrect;
1192                                 best_diff = diff;
1193                                 matching_format_found = true;
1194                         }
1195                 }
1196         }
1197
1198         if (!matching_format_found) {
1199                 cif_isp10_pltfrm_pr_err(dev->dev,
1200                         "no matching image source format (%dx%d) found\n",
1201                         target_width, target_height);
1202                 ret = -EINVAL;
1203                 goto err;
1204         }
1205
1206         cif_isp10_pltfrm_pr_dbg(
1207                 dev->dev,
1208                 "requesting format %s %dx%d(%d,%d,%d,%d)@%d/%dfps from %s\n",
1209                 cif_isp10_pix_fmt_string(request_strm_fmt.frm_fmt.pix_fmt),
1210                 request_strm_fmt.frm_fmt.width,
1211                 request_strm_fmt.frm_fmt.height,
1212                 request_strm_fmt.frm_fmt.defrect.left,
1213                 request_strm_fmt.frm_fmt.defrect.top,
1214                 request_strm_fmt.frm_fmt.defrect.width,
1215                 request_strm_fmt.frm_fmt.defrect.height,
1216                 request_strm_fmt.frm_intrvl.denominator,
1217                 request_strm_fmt.frm_intrvl.numerator,
1218                 cif_isp10_img_src_g_name(dev->img_src));
1219
1220         ret = cif_isp10_img_src_s_strm_fmt(dev->img_src, &request_strm_fmt);
1221         if (IS_ERR_VALUE(ret))
1222                 goto err;
1223
1224         dev->config.img_src_output = request_strm_fmt;
1225
1226         ret = cif_isp10_img_src_g_ctrl(dev->img_src,
1227                 CIF_ISP10_CID_VBLANKING, &vblanking);
1228         if (IS_ERR_VALUE(ret)) {
1229                 cif_isp10_pltfrm_pr_dbg(
1230                         dev->dev,
1231                         "get vblanking failed: %d\n", ret);
1232                         vblanking = 0;
1233         }
1234
1235         if (vblanking >= 0)
1236                 dev->isp_dev.v_blanking_us = vblanking;
1237
1238         return 0;
1239 err:
1240         cif_isp10_pltfrm_pr_err(dev->dev,
1241                 "failed with err %d\n", ret);
1242         return ret;
1243 }
1244
1245 /*
1246  * This should only be called when configuring CIF
1247  * or at the frame end interrupt
1248  */
1249 static void cif_isp10_config_ism(struct cif_isp10_device *dev, bool async)
1250 {
1251         const struct cif_isp10_ism_config *pconfig =
1252                 &dev->config.isp_config.ism_config;
1253
1254         if (pconfig->ism_en) {
1255                 cif_isp10_pltfrm_pr_dbg(dev->dev, "%dx%d -> %dx%d@(%d,%d)\n",
1256                         dev->isp_dev.input_width,
1257                         dev->isp_dev.input_height,
1258                         pconfig->ism_params.h_size,
1259                         pconfig->ism_params.v_size,
1260                         pconfig->ism_params.h_offs,
1261                         pconfig->ism_params.v_offs);
1262                 cif_iowrite32(pconfig->ism_params.recenter,
1263                         dev->config.base_addr + CIF_ISP_IS_RECENTER);
1264                 cif_iowrite32(pconfig->ism_params.max_dx,
1265                         dev->config.base_addr + CIF_ISP_IS_MAX_DX);
1266                 cif_iowrite32(pconfig->ism_params.max_dy,
1267                         dev->config.base_addr + CIF_ISP_IS_MAX_DY);
1268                 cif_iowrite32(pconfig->ism_params.displace,
1269                         dev->config.base_addr + CIF_ISP_IS_DISPLACE);
1270                 cif_iowrite32(pconfig->ism_params.h_offs,
1271                         dev->config.base_addr + CIF_ISP_IS_H_OFFS);
1272                 cif_iowrite32(pconfig->ism_params.v_offs,
1273                         dev->config.base_addr + CIF_ISP_IS_V_OFFS);
1274                 cif_iowrite32(pconfig->ism_params.h_size,
1275                         dev->config.base_addr + CIF_ISP_IS_H_SIZE);
1276                 cif_iowrite32(pconfig->ism_params.v_size,
1277                         dev->config.base_addr + CIF_ISP_IS_V_SIZE);
1278                 cif_iowrite32OR(1,
1279                         dev->config.base_addr + CIF_ISP_IS_CTRL);
1280                 dev->config.isp_config.output.width =
1281                         dev->config.isp_config.ism_config.ism_params.h_size;
1282                 dev->config.isp_config.output.height =
1283                         dev->config.isp_config.ism_config.ism_params.v_size;
1284         } else {
1285                 cif_iowrite32(pconfig->ism_params.recenter,
1286                         dev->config.base_addr + CIF_ISP_IS_RECENTER);
1287                 cif_iowrite32(pconfig->ism_params.max_dx,
1288                         dev->config.base_addr + CIF_ISP_IS_MAX_DX);
1289                 cif_iowrite32(pconfig->ism_params.max_dy,
1290                         dev->config.base_addr + CIF_ISP_IS_MAX_DY);
1291                 cif_iowrite32(pconfig->ism_params.displace,
1292                         dev->config.base_addr + CIF_ISP_IS_DISPLACE);
1293                 cif_iowrite32(0,
1294                         dev->config.base_addr + CIF_ISP_IS_H_OFFS);
1295                 cif_iowrite32(0,
1296                         dev->config.base_addr + CIF_ISP_IS_V_OFFS);
1297                 cif_iowrite32(dev->config.isp_config.output.width,
1298                         dev->config.base_addr + CIF_ISP_IS_H_SIZE);
1299                 cif_iowrite32(dev->config.isp_config.output.height,
1300                         dev->config.base_addr + CIF_ISP_IS_V_SIZE);
1301                 cif_iowrite32(0,
1302                         dev->config.base_addr + CIF_ISP_IS_CTRL);
1303         }
1304
1305         if (async)
1306                 cif_iowrite32OR(CIF_ISP_CTRL_ISP_CFG_UPD,
1307                         dev->config.base_addr + CIF_ISP_CTRL);
1308
1309         cif_isp10_pltfrm_pr_dbg(dev->dev,
1310                 "\n  ISP_IS_H_OFFS %d/%d\n"
1311                 "  ISP_IS_V_OFFS %d/%d\n"
1312                 "  ISP_IS_H_SIZE %d/%d\n"
1313                 "  ISP_IS_V_SIZE %d/%d\n"
1314                 "  ISP_IS_RECENTER 0x%08x\n"
1315                 "  ISP_IS_MAX_DX %d\n"
1316                 "  ISP_IS_MAX_DY %d\n"
1317                 "  ISP_IS_DISPLACE 0x%08x\n"
1318                 "  ISP_IS_CTRL 0x%08x\n",
1319                 cif_ioread32(dev->config.base_addr +
1320                         CIF_ISP_IS_H_OFFS),
1321                 cif_ioread32(dev->config.base_addr +
1322                         CIF_ISP_IS_H_OFFS_SHD),
1323                 cif_ioread32(dev->config.base_addr +
1324                         CIF_ISP_IS_V_OFFS),
1325                 cif_ioread32(dev->config.base_addr +
1326                         CIF_ISP_IS_V_OFFS_SHD),
1327                 cif_ioread32(dev->config.base_addr +
1328                         CIF_ISP_IS_H_SIZE),
1329                 cif_ioread32(dev->config.base_addr +
1330                         CIF_ISP_IS_H_SIZE_SHD),
1331                 cif_ioread32(dev->config.base_addr +
1332                         CIF_ISP_IS_V_SIZE),
1333                 cif_ioread32(dev->config.base_addr +
1334                         CIF_ISP_IS_V_SIZE_SHD),
1335                 cif_ioread32(dev->config.base_addr +
1336                         CIF_ISP_IS_RECENTER),
1337                 cif_ioread32(dev->config.base_addr +
1338                         CIF_ISP_IS_MAX_DX),
1339                 cif_ioread32(dev->config.base_addr +
1340                         CIF_ISP_IS_MAX_DY),
1341                 cif_ioread32(dev->config.base_addr +
1342                         CIF_ISP_IS_DISPLACE),
1343                 cif_ioread32(dev->config.base_addr +
1344                         CIF_ISP_IS_CTRL));
1345 }
1346
1347 static void cif_isp10_program_jpeg_tables(
1348         struct cif_isp10_device *dev)
1349 {
1350         unsigned int ratio = dev->config.jpeg_config.ratio;
1351         unsigned int i = 0;
1352         unsigned int q, q_next, scale;
1353
1354         cif_isp10_pltfrm_pr_dbg(NULL, "ratio %d\n", ratio);
1355
1356         /* Y q-table 0 programming */
1357         cif_iowrite32(CIF_JPE_TAB_ID_QUANT0,
1358                 dev->config.base_addr + CIF_JPE_TABLE_ID);
1359         if (ratio != 50) {
1360                 scale = (ratio < 50) ? 5000 / ratio : 200 - (ratio << 1);
1361                 for (i = 0; i < 32; i++) {
1362                         q = yq_table_base_zigzag[i * 2];
1363                         q_next = yq_table_base_zigzag[i * 2 + 1];
1364                         q = (scale * q + 50) / 100;
1365                         q = (q > 1) ? ((q < 255) ? q : 255) : 1;
1366                         q_next = (scale * q_next + 50) / 100;
1367                         q_next = (q_next > 1) ?
1368                                 ((q_next < 255) ? q_next : 255) : 1;
1369                         cif_iowrite32(q_next + (q << 8),
1370                                 dev->config.base_addr +
1371                                 CIF_JPE_TABLE_DATA);
1372                 }
1373         } else {
1374                 for (i = 0; i < 32; i++) {
1375                         q = yq_table_base_zigzag[i * 2];
1376                         q_next = yq_table_base_zigzag[i * 2 + 1];
1377                         cif_iowrite32(q_next + (q << 8),
1378                                 dev->config.base_addr +
1379                                 CIF_JPE_TABLE_DATA);
1380                 }
1381         }
1382
1383         /* U/V q-table 0 programming */
1384         cif_iowrite32(CIF_JPE_TAB_ID_QUANT1,
1385                 dev->config.base_addr + CIF_JPE_TABLE_ID);
1386         if (ratio != 50) {
1387                 for (i = 0; i < 32; i++) {
1388                         q = uvq_table_base_zigzag[i * 2];
1389                         q_next = uvq_table_base_zigzag[i * 2 + 1];
1390                         q = (scale * q + 50) / 100;
1391                         q = (q > 1) ? ((q < 255) ? q : 255) : 1;
1392                         q_next = (scale * q_next + 50) / 100;
1393                         q_next = (q_next > 1) ?
1394                                 ((q_next < 255) ? q_next : 255) : 1;
1395                         cif_iowrite32(q_next + (q << 8),
1396                                 dev->config.base_addr +
1397                                 CIF_JPE_TABLE_DATA);
1398                 }
1399         } else {
1400                 for (i = 0; i < 32; i++) {
1401                         q = uvq_table_base_zigzag[i * 2];
1402                         q_next = uvq_table_base_zigzag[i * 2 + 1];
1403                         cif_iowrite32(q_next + (q << 8),
1404                                 dev->config.base_addr +
1405                                 CIF_JPE_TABLE_DATA);
1406                 }
1407         }
1408
1409         /* Y AC-table 0 programming */
1410         cif_iowrite32(CIF_JPE_TAB_ID_HUFFAC0,
1411                 dev->config.base_addr + CIF_JPE_TABLE_ID);
1412         cif_iowrite32(178, dev->config.base_addr + CIF_JPE_TAC0_LEN);
1413         for (i = 0; i < (178 / 2); i++) {
1414                 cif_iowrite32(ac_luma_table_annex_k[i * 2 + 1] +
1415                         (ac_luma_table_annex_k[i * 2] << 8),
1416                         dev->config.base_addr +
1417                         CIF_JPE_TABLE_DATA);
1418         }
1419
1420         /* U/V AC-table 1 programming */
1421         cif_iowrite32(CIF_JPE_TAB_ID_HUFFAC1,
1422                 dev->config.base_addr + CIF_JPE_TABLE_ID);
1423         cif_iowrite32(178, dev->config.base_addr + CIF_JPE_TAC1_LEN);
1424         for (i = 0; i < (178 / 2); i++) {
1425                 cif_iowrite32(ac_chroma_table_annex_k[i * 2 + 1] +
1426                         (ac_chroma_table_annex_k[i * 2] << 8),
1427                         dev->config.base_addr +
1428                         CIF_JPE_TABLE_DATA);
1429         }
1430
1431         /* Y DC-table 0 programming */
1432         cif_iowrite32(CIF_JPE_TAB_ID_HUFFDC0,
1433                 dev->config.base_addr + CIF_JPE_TABLE_ID);
1434         cif_iowrite32(28, dev->config.base_addr + CIF_JPE_TDC0_LEN);
1435         for (i = 0; i < (28 / 2); i++) {
1436                 cif_iowrite32(dc_luma_table_annex_k[i * 2 + 1] +
1437                         (dc_luma_table_annex_k[i * 2] << 8),
1438                         dev->config.base_addr +
1439                         CIF_JPE_TABLE_DATA);
1440         }
1441
1442         /* U/V DC-table 1 programming */
1443         cif_iowrite32(CIF_JPE_TAB_ID_HUFFDC1,
1444                 dev->config.base_addr + CIF_JPE_TABLE_ID);
1445         cif_iowrite32(28, dev->config.base_addr + CIF_JPE_TDC1_LEN);
1446         for (i = 0; i < (28 / 2); i++) {
1447                 cif_iowrite32(dc_chroma_table_annex_k[i * 2 + 1] +
1448                 (dc_chroma_table_annex_k[i * 2] << 8),
1449                 dev->config.base_addr +
1450                 CIF_JPE_TABLE_DATA);
1451         }
1452 }
1453
1454 static void cif_isp10_select_jpeg_tables(
1455         struct cif_isp10_device *dev)
1456 {
1457         cif_isp10_pltfrm_pr_dbg(NULL, "\n");
1458
1459         /* Selects quantization table for Y */
1460         cif_iowrite32(CIF_JPE_TQ_TAB0,
1461                 dev->config.base_addr + CIF_JPE_TQ_Y_SELECT);
1462         /* Selects quantization table for U */
1463         cif_iowrite32(CIF_JPE_TQ_TAB1,
1464                 dev->config.base_addr + CIF_JPE_TQ_U_SELECT);
1465         /* Selects quantization table for V */
1466         cif_iowrite32(CIF_JPE_TQ_TAB1,
1467                 dev->config.base_addr + CIF_JPE_TQ_V_SELECT);
1468         /* Selects Huffman DC table */
1469         cif_iowrite32(CIF_DC_V_TABLE | CIF_DC_U_TABLE,
1470                 dev->config.base_addr + CIF_JPE_DC_TABLE_SELECT);
1471         /* Selects Huffman AC table */
1472         cif_iowrite32(CIF_AC_V_TABLE | CIF_AC_U_TABLE,
1473                 dev->config.base_addr + CIF_JPE_AC_TABLE_SELECT);
1474
1475         cif_isp10_pltfrm_pr_dbg(NULL,
1476                 "\n  JPE_TQ_Y_SELECT 0x%08x\n"
1477                 "  JPE_TQ_U_SELECT 0x%08x\n"
1478                 "  JPE_TQ_V_SELECT 0x%08x\n"
1479                 "  JPE_DC_TABLE_SELECT 0x%08x\n"
1480                 "  JPE_AC_TABLE_SELECT 0x%08x\n",
1481                 cif_ioread32(dev->config.base_addr + CIF_JPE_TQ_Y_SELECT),
1482                 cif_ioread32(dev->config.base_addr + CIF_JPE_TQ_U_SELECT),
1483                 cif_ioread32(dev->config.base_addr + CIF_JPE_TQ_V_SELECT),
1484                 cif_ioread32(dev->config.base_addr + CIF_JPE_DC_TABLE_SELECT),
1485                 cif_ioread32(dev->config.base_addr + CIF_JPE_AC_TABLE_SELECT));
1486 }
1487
1488 static int cif_isp10_config_img_src(
1489         struct cif_isp10_device *dev)
1490 {
1491         int ret = 0;
1492         struct isp_supplemental_sensor_mode_data sensor_mode;
1493
1494         cif_isp10_pltfrm_pr_dbg(dev->dev, "\n");
1495
1496         ret = cif_isp10_img_src_set_state(dev,
1497                 CIF_ISP10_IMG_SRC_STATE_SW_STNDBY);
1498         if (IS_ERR_VALUE(ret))
1499                 goto err;
1500
1501         if (!dev->sp_stream.updt_cfg &&
1502                 !dev->mp_stream.updt_cfg)
1503                 return 0;
1504
1505         ret = cif_isp10_pltfrm_g_interface_config(dev->img_src,
1506                         &dev->config.cam_itf);
1507         if (IS_ERR_VALUE(ret))
1508                 goto err;
1509
1510         ret = (int)cif_isp10_img_src_ioctl(dev->img_src,
1511                 RK_VIDIOC_SENSOR_MODE_DATA, &sensor_mode);
1512         if (IS_ERR_VALUE(ret)) {
1513                 dev->img_src_exps.exp_valid_frms = 2;
1514         } else {
1515                 if ((sensor_mode.exposure_valid_frame < 2) ||
1516                         (sensor_mode.exposure_valid_frame > 6))
1517                         dev->img_src_exps.exp_valid_frms = 2;
1518                 else
1519                         dev->img_src_exps.exp_valid_frms =
1520                                 sensor_mode.exposure_valid_frame;
1521         }
1522         cif_isp10_pltfrm_pr_dbg(dev->dev,
1523                 "cam_itf: (type: 0x%x, dphy: %d, vc: %d, nb_lanes: %d, bitrate: %d)",
1524                 dev->config.cam_itf.type,
1525                 dev->config.cam_itf.cfg.mipi.dphy_index,
1526                 dev->config.cam_itf.cfg.mipi.vc,
1527                 dev->config.cam_itf.cfg.mipi.nb_lanes,
1528                 dev->config.cam_itf.cfg.mipi.bit_rate);
1529         return 0;
1530 err:
1531         cif_isp10_pltfrm_pr_err(dev->dev,
1532                 "failed with error %d\n", ret);
1533         return ret;
1534 }
1535
1536 static int cif_isp10_config_isp(
1537         struct cif_isp10_device *dev)
1538 {
1539         int ret = 0;
1540         u32 h_offs;
1541         u32 v_offs;
1542         u32 yuv_seq = 0;
1543         u32 bpp;
1544         u32 isp_input_sel = 0;
1545         u32 isp_bayer_pat = 0;
1546         u32 acq_mult = 1;
1547         u32 irq_mask = 0;
1548         u32 signal = 0;
1549         enum cif_isp10_pix_fmt in_pix_fmt;
1550         struct cif_isp10_frm_fmt *output;
1551         struct pltfrm_cam_itf *cam_itf;
1552
1553         if (dev->config.input_sel == CIF_ISP10_INP_DMA_IE) {
1554                 dev->config.isp_config.output =
1555                         dev->config.mi_config.dma.output;
1556                 cifisp_disable_isp(&dev->isp_dev);
1557                 return 0;
1558         } else if (dev->config.input_sel == CIF_ISP10_INP_DMA_SP) {
1559                 cif_iowrite32AND(~CIF_ICCL_ISP_CLK,
1560                         dev->config.base_addr + CIF_ICCL);
1561                 cif_isp10_pltfrm_pr_dbg(NULL,
1562                         "ISP disabled\n");
1563                 return 0;
1564         }
1565         cif_iowrite32OR(CIF_ICCL_ISP_CLK,
1566                 dev->config.base_addr + CIF_ICCL);
1567
1568         in_pix_fmt = dev->config.isp_config.input->pix_fmt;
1569
1570         output = &dev->config.isp_config.output;
1571         cam_itf = &dev->config.cam_itf;
1572
1573         if (CIF_ISP10_PIX_FMT_IS_RAW_BAYER(in_pix_fmt)) {
1574                 if (!dev->config.mi_config.raw_enable) {
1575                         output->pix_fmt = CIF_YUV422I;
1576
1577                         if ((dev->mp_stream.state == CIF_ISP10_STATE_READY) &&
1578                                 (dev->sp_stream.state ==
1579                                 CIF_ISP10_STATE_READY)) {
1580                                 if (dev->config.mi_config.mp.output.
1581                                         quantization !=
1582                                         dev->config.mi_config.sp.output.
1583                                         quantization) {
1584                                         cif_isp10_pltfrm_pr_err(dev->dev,
1585                                                 "colorspace quantization (mp: %d, sp: %d) is not support!\n",
1586                                                 dev->
1587                                                 config.mi_config.mp.output.
1588                                                 quantization,
1589                                                 dev->
1590                                                 config.mi_config.sp.output.
1591                                                 quantization);
1592                                 }
1593                         }
1594
1595                         if (dev->sp_stream.state == CIF_ISP10_STATE_READY) {
1596                                 output->quantization =
1597                                 dev->config.mi_config.sp.output.quantization;
1598                         }
1599
1600                         if (dev->mp_stream.state == CIF_ISP10_STATE_READY) {
1601                                 output->quantization =
1602                                 dev->config.mi_config.sp.output.quantization;
1603                         }
1604
1605                         cif_iowrite32(0xc,
1606                                 dev->config.base_addr + CIF_ISP_DEMOSAIC);
1607
1608                         if (PLTFRM_CAM_ITF_IS_BT656(dev->config.cam_itf.type)) {
1609                                 cif_iowrite32(
1610                                         CIF_ISP_CTRL_ISP_MODE_BAYER_ITU656,
1611                                         dev->config.base_addr + CIF_ISP_CTRL);
1612                         } else {
1613                                 cif_iowrite32(
1614                                         CIF_ISP_CTRL_ISP_MODE_BAYER_ITU601,
1615                                         dev->config.base_addr + CIF_ISP_CTRL);
1616                         }
1617                 } else {
1618                         output->pix_fmt = in_pix_fmt;
1619                         if (PLTFRM_CAM_ITF_IS_BT656(dev->config.cam_itf.type)) {
1620                                 cif_iowrite32(
1621                                         CIF_ISP_CTRL_ISP_MODE_RAW_PICT_ITU656,
1622                                         dev->config.base_addr + CIF_ISP_CTRL);
1623                         } else {
1624                                 cif_iowrite32(CIF_ISP_CTRL_ISP_MODE_RAW_PICT,
1625                                         dev->config.base_addr + CIF_ISP_CTRL);
1626                         }
1627                 }
1628
1629                 bpp = CIF_ISP10_PIX_FMT_GET_BPP(in_pix_fmt);
1630                 if (bpp == 8) {
1631                         isp_input_sel = CIF_ISP_ACQ_PROP_IN_SEL_8B_MSB;
1632                 } else if (bpp == 10) {
1633                         isp_input_sel = CIF_ISP_ACQ_PROP_IN_SEL_10B_MSB;
1634                 } else if (bpp == 12) {
1635                         isp_input_sel = CIF_ISP_ACQ_PROP_IN_SEL_12B;
1636                 } else {
1637                         cif_isp10_pltfrm_pr_err(dev->dev,
1638                                 "%d bits per pixel not supported\n", bpp);
1639                         ret = -EINVAL;
1640                         goto err;
1641                 }
1642                 if (CIF_ISP10_PIX_FMT_BAYER_PAT_IS_BGGR(in_pix_fmt)) {
1643                         isp_bayer_pat = CIF_ISP_ACQ_PROP_BAYER_PAT_BGGR;
1644                 } else if (CIF_ISP10_PIX_FMT_BAYER_PAT_IS_GBRG(in_pix_fmt)) {
1645                         isp_bayer_pat = CIF_ISP_ACQ_PROP_BAYER_PAT_GBRG;
1646                 } else if (CIF_ISP10_PIX_FMT_BAYER_PAT_IS_GRBG(in_pix_fmt)) {
1647                         isp_bayer_pat = CIF_ISP_ACQ_PROP_BAYER_PAT_GRBG;
1648                 } else if (CIF_ISP10_PIX_FMT_BAYER_PAT_IS_RGGB(in_pix_fmt)) {
1649                         isp_bayer_pat = CIF_ISP_ACQ_PROP_BAYER_PAT_RGGB;
1650                 } else {
1651                         cif_isp10_pltfrm_pr_err(dev->dev,
1652                                 "BAYER pattern not supported\n");
1653                         ret = -EINVAL;
1654                         goto err;
1655                 }
1656         } else if (CIF_ISP10_PIX_FMT_IS_YUV(in_pix_fmt)) {
1657                 output->pix_fmt = in_pix_fmt;
1658                 acq_mult = 2;
1659                 if (dev->config.input_sel == CIF_ISP10_INP_DMA) {
1660                         bpp = CIF_ISP10_PIX_FMT_GET_BPP(in_pix_fmt);
1661                         bpp =
1662                                 bpp * 4 /
1663                                 (4 + (CIF_ISP10_PIX_FMT_YUV_GET_X_SUBS(
1664                                         in_pix_fmt) *
1665                                 CIF_ISP10_PIX_FMT_YUV_GET_Y_SUBS(
1666                                         in_pix_fmt) / 2));
1667                         if (bpp == 8) {
1668                                 isp_input_sel = CIF_ISP_ACQ_PROP_IN_SEL_8B_MSB;
1669                         } else if (bpp == 10) {
1670                                 isp_input_sel = CIF_ISP_ACQ_PROP_IN_SEL_10B_MSB;
1671                         } else if (bpp == 12) {
1672                                 isp_input_sel = CIF_ISP_ACQ_PROP_IN_SEL_12B;
1673                         } else {
1674                                 cif_isp10_pltfrm_pr_err(dev->dev,
1675                                         "format %s not supported, invalid bpp %d\n",
1676                                         cif_isp10_pix_fmt_string(in_pix_fmt),
1677                                         bpp);
1678                                 ret = -EINVAL;
1679                                 goto err;
1680                         }
1681                         cif_iowrite32(CIF_ISP_CTRL_ISP_MODE_ITU601,
1682                                 dev->config.base_addr + CIF_ISP_CTRL);
1683                 } else{
1684                         if (PLTFRM_CAM_ITF_IS_MIPI(
1685                                 dev->config.cam_itf.type)) {
1686                                 isp_input_sel = CIF_ISP_ACQ_PROP_IN_SEL_12B;
1687                                 cif_iowrite32(CIF_ISP_CTRL_ISP_MODE_ITU601,
1688                                         dev->config.base_addr + CIF_ISP_CTRL);
1689                         } else if (PLTFRM_CAM_ITF_IS_DVP(
1690                                 dev->config.cam_itf.type)) {
1691                                 if (PLTFRM_CAM_ITF_IS_BT656(
1692                                         dev->config.cam_itf.type)) {
1693                                         cif_iowrite32(
1694                                         CIF_ISP_CTRL_ISP_MODE_ITU656,
1695                                         dev->config.base_addr +
1696                                         CIF_ISP_CTRL);
1697                                 } else {
1698                                         cif_iowrite32(
1699                                         CIF_ISP_CTRL_ISP_MODE_ITU601,
1700                                         dev->config.base_addr +
1701                                         CIF_ISP_CTRL);
1702                                 }
1703
1704                                 switch (PLTFRM_CAM_ITF_DVP_BW(
1705                                 dev->config.cam_itf.type)) {
1706                                 case 8:
1707                                         isp_input_sel =
1708                                         CIF_ISP_ACQ_PROP_IN_SEL_8B_ZERO;
1709                                         break;
1710                                 case 10:
1711                                         isp_input_sel =
1712                                         CIF_ISP_ACQ_PROP_IN_SEL_10B_ZERO;
1713                                         break;
1714                                 case 12:
1715                                         isp_input_sel =
1716                                         CIF_ISP_ACQ_PROP_IN_SEL_12B;
1717                                         break;
1718                                 default:
1719                                         cif_isp10_pltfrm_pr_err(dev->dev,
1720                                                 "%s isn't support for cif isp10\n",
1721                                                 cif_isp10_interface_string(
1722                                                 dev->config.cam_itf.type));
1723                                         break;
1724                                 }
1725                         } else {
1726                                 cif_isp10_pltfrm_pr_err(dev->dev,
1727                                         "%s isn't support for cif isp10\n",
1728                                         cif_isp10_interface_string(
1729                                         dev->config.cam_itf.type));
1730                         }
1731                         /*
1732                          * ISP DATA LOSS is only meaningful
1733                          * when input is not DMA
1734                          */
1735                         irq_mask |= CIF_ISP_DATA_LOSS;
1736                 }
1737                 if (CIF_ISP10_PIX_FMT_YUV_IS_YC_SWAPPED(in_pix_fmt)) {
1738                         yuv_seq = CIF_ISP_ACQ_PROP_CBYCRY;
1739                         cif_isp10_pix_fmt_set_yc_swapped(output->pix_fmt, 0);
1740                 } else if (CIF_ISP10_PIX_FMT_YUV_IS_UV_SWAPPED(in_pix_fmt)) {
1741                         yuv_seq = CIF_ISP_ACQ_PROP_YCRYCB;
1742                 } else {
1743                         yuv_seq = CIF_ISP_ACQ_PROP_YCBYCR;
1744                 }
1745         } else {
1746                 cif_isp10_pltfrm_pr_err(dev->dev,
1747                         "format %s not supported\n",
1748                         cif_isp10_pix_fmt_string(in_pix_fmt));
1749                 ret = -EINVAL;
1750                 goto err;
1751         }
1752
1753         /* Set up input acquisition properties*/
1754         if (PLTFRM_CAM_ITF_IS_DVP(cam_itf->type)) {
1755                 signal =
1756                         ((cam_itf->cfg.dvp.pclk == PLTFRM_CAM_SDR_POS_EDG) ?
1757                         CIF_ISP_ACQ_PROP_POS_EDGE : CIF_ISP_ACQ_PROP_NEG_EDGE);
1758
1759                 if (PLTFRM_CAM_ITF_IS_BT601(cam_itf->type)) {
1760                         signal |=
1761                                 (cam_itf->cfg.dvp.vsync ==
1762                                 PLTFRM_CAM_SIGNAL_HIGH_LEVEL) ?
1763                                 CIF_ISP_ACQ_PROP_VSYNC_HIGH :
1764                                 CIF_ISP_ACQ_PROP_VSYNC_LOW;
1765
1766                         signal |=
1767                                 (cam_itf->cfg.dvp.hsync ==
1768                                 PLTFRM_CAM_SIGNAL_HIGH_LEVEL) ?
1769                                 CIF_ISP_ACQ_PROP_HSYNC_HIGH :
1770                                 CIF_ISP_ACQ_PROP_HSYNC_LOW;
1771
1772                 } else {
1773                         signal |= CIF_ISP_ACQ_PROP_HSYNC_HIGH |
1774                                         CIF_ISP_ACQ_PROP_VSYNC_HIGH;
1775                 }
1776         } else {
1777                 signal = CIF_ISP_ACQ_PROP_NEG_EDGE |
1778                               CIF_ISP_ACQ_PROP_HSYNC_HIGH |
1779                               CIF_ISP_ACQ_PROP_VSYNC_HIGH;
1780         }
1781
1782         cif_iowrite32(signal |
1783                               yuv_seq |
1784                               CIF_ISP_ACQ_PROP_FIELD_SEL_ALL |
1785                               isp_input_sel |
1786                               isp_bayer_pat |
1787                               (0 << 20),  /* input_selection_no_app */
1788                               dev->config.base_addr + CIF_ISP_ACQ_PROP);
1789         cif_iowrite32(0,
1790                 dev->config.base_addr + CIF_ISP_ACQ_NR_FRAMES);
1791
1792         /* Acquisition Size */
1793         cif_iowrite32(dev->config.isp_config.input->defrect.left,
1794                 dev->config.base_addr + CIF_ISP_ACQ_H_OFFS);
1795         cif_iowrite32(dev->config.isp_config.input->defrect.top,
1796                 dev->config.base_addr + CIF_ISP_ACQ_V_OFFS);
1797         cif_iowrite32(
1798                 acq_mult * dev->config.isp_config.input->defrect.width,
1799                 dev->config.base_addr + CIF_ISP_ACQ_H_SIZE);
1800         cif_iowrite32(
1801                 dev->config.isp_config.input->defrect.height,
1802                 dev->config.base_addr + CIF_ISP_ACQ_V_SIZE);
1803
1804         /* do cropping to match output aspect ratio */
1805         ret = cif_isp10_calc_isp_cropping(dev,
1806                 &output->width, &output->height,
1807                 &h_offs, &v_offs);
1808         if (IS_ERR_VALUE(ret))
1809                 goto err;
1810
1811         cif_iowrite32(v_offs,
1812                 dev->config.base_addr + CIF_ISP_OUT_V_OFFS);
1813         cif_iowrite32(h_offs,
1814                 dev->config.base_addr + CIF_ISP_OUT_H_OFFS);
1815         cif_iowrite32(output->width,
1816                 dev->config.base_addr + CIF_ISP_OUT_H_SIZE);
1817         cif_iowrite32(output->height,
1818                 dev->config.base_addr + CIF_ISP_OUT_V_SIZE);
1819
1820         dev->isp_dev.input_width =
1821                 dev->config.isp_config.input->defrect.width;
1822         dev->isp_dev.input_height =
1823                 dev->config.isp_config.input->defrect.height;
1824
1825         /* interrupt mask */
1826         irq_mask |=
1827                 CIF_ISP_FRAME |
1828                 CIF_ISP_PIC_SIZE_ERROR |
1829                 CIF_ISP_FRAME_IN |
1830                 CIF_ISP_V_START;
1831         cif_iowrite32(irq_mask,
1832                 dev->config.base_addr + CIF_ISP_IMSC);
1833
1834         if (!dev->config.mi_config.raw_enable)
1835                 cifisp_configure_isp(&dev->isp_dev,
1836                         in_pix_fmt,
1837                         output->quantization);
1838         else
1839                 cifisp_disable_isp(&dev->isp_dev);
1840
1841         cif_isp10_pltfrm_pr_dbg(
1842                 dev->dev,
1843                 "\n  ISP_CTRL 0x%08x\n"
1844                 "  ISP_IMSC 0x%08x\n"
1845                 "  ISP_ACQ_PROP 0x%08x\n"
1846                 "  ISP_ACQ %dx%d@(%d,%d)\n"
1847                 "  ISP_OUT %dx%d@(%d,%d)\n"
1848                 "  ISP_IS %dx%d@(%d,%d)\n",
1849                 cif_ioread32(dev->config.base_addr + CIF_ISP_CTRL),
1850                 cif_ioread32(dev->config.base_addr + CIF_ISP_IMSC),
1851                 cif_ioread32(dev->config.base_addr + CIF_ISP_ACQ_PROP),
1852                 cif_ioread32(dev->config.base_addr + CIF_ISP_ACQ_H_SIZE),
1853                 cif_ioread32(dev->config.base_addr + CIF_ISP_ACQ_V_SIZE),
1854                 cif_ioread32(dev->config.base_addr + CIF_ISP_ACQ_H_OFFS),
1855                 cif_ioread32(dev->config.base_addr + CIF_ISP_ACQ_V_OFFS),
1856                 cif_ioread32(dev->config.base_addr + CIF_ISP_OUT_H_SIZE),
1857                 cif_ioread32(dev->config.base_addr + CIF_ISP_OUT_V_SIZE),
1858                 cif_ioread32(dev->config.base_addr + CIF_ISP_OUT_H_OFFS),
1859                 cif_ioread32(dev->config.base_addr + CIF_ISP_OUT_V_OFFS),
1860                 cif_ioread32(dev->config.base_addr + CIF_ISP_IS_H_SIZE),
1861                 cif_ioread32(dev->config.base_addr + CIF_ISP_IS_V_SIZE),
1862                 cif_ioread32(dev->config.base_addr + CIF_ISP_IS_H_OFFS),
1863                 cif_ioread32(dev->config.base_addr + CIF_ISP_IS_V_OFFS));
1864
1865         return 0;
1866 err:
1867         cif_isp10_pltfrm_pr_err(dev->dev,
1868                 "failed with error %d\n", ret);
1869         return ret;
1870 }
1871
1872 static int cif_isp10_config_mipi(
1873         struct cif_isp10_device *dev)
1874 {
1875         int ret = 0;
1876         u32 data_type;
1877         u32 mipi_ctrl;
1878         u32 shutdown_lanes;
1879         u32 i;
1880         enum cif_isp10_pix_fmt in_pix_fmt;
1881
1882         if (!CIF_ISP10_INP_IS_MIPI(dev->config.input_sel)) {
1883                 cif_iowrite32AND(~CIF_ICCL_MIPI_CLK,
1884                         dev->config.base_addr + CIF_ICCL);
1885                 cif_isp10_pltfrm_pr_dbg(NULL,
1886                         "MIPI disabled\n");
1887                 return 0;
1888         }
1889         cif_iowrite32OR(CIF_ICCL_MIPI_CLK,
1890                 dev->config.base_addr + CIF_ICCL);
1891
1892         in_pix_fmt = dev->config.img_src_output.frm_fmt.pix_fmt;
1893
1894         cif_isp10_pltfrm_pr_dbg(dev->dev,
1895                 "input %s, vc = %d, nb_lanes = %d\n",
1896                 cif_isp10_inp_string(dev->config.input_sel),
1897                 dev->config.cam_itf.cfg.mipi.vc,
1898                 dev->config.cam_itf.cfg.mipi.nb_lanes);
1899
1900         if ((dev->config.cam_itf.cfg.mipi.nb_lanes == 0) ||
1901                 (dev->config.cam_itf.cfg.mipi.nb_lanes > 4)) {
1902                 cif_isp10_pltfrm_pr_err(dev->dev,
1903                         "invalid number (%d) of MIPI lanes, valid range is [1..4]\n",
1904                         dev->config.cam_itf.cfg.mipi.nb_lanes);
1905                 ret = -EINVAL;
1906                 goto err;
1907         }
1908
1909         shutdown_lanes = 0x00;
1910         for (i = 0; i < dev->config.cam_itf.cfg.mipi.nb_lanes; i++)
1911                 shutdown_lanes |= (1 << i);
1912
1913         mipi_ctrl =
1914                 CIF_MIPI_CTRL_NUM_LANES(
1915                         dev->config.cam_itf.cfg.mipi.nb_lanes - 1) |
1916                 CIF_MIPI_CTRL_ERR_SOT_HS_ENA |
1917                 CIF_MIPI_CTRL_ERR_SOT_SYNC_HS_SKIP |
1918                 CIF_MIPI_CTRL_SHUTDOWNLANES(shutdown_lanes) |
1919                 CIF_MIPI_CTRL_ERR_SOT_SYNC_HS_ENA |
1920                 CIF_MIPI_CTRL_ERR_SOT_HS_ENA |
1921                 CIF_MIPI_CTRL_CLOCKLANE_ENA;
1922
1923         cif_iowrite32(mipi_ctrl,
1924                 dev->config.base_addr + CIF_MIPI_CTRL);
1925
1926         /* mipi_dphy */
1927         cif_isp10_pltfrm_mipi_dphy_config(dev);
1928
1929         /* Configure Data Type and Virtual Channel */
1930         if (CIF_ISP10_PIX_FMT_IS_YUV(in_pix_fmt)) {
1931                 if ((CIF_ISP10_PIX_FMT_YUV_GET_X_SUBS(in_pix_fmt) == 2) &&
1932                         (CIF_ISP10_PIX_FMT_YUV_GET_Y_SUBS(in_pix_fmt) == 2) &&
1933                         (CIF_ISP10_PIX_FMT_GET_BPP(in_pix_fmt) == 12))
1934                         data_type = CSI2_DT_YUV420_8b;
1935                 else if ((CIF_ISP10_PIX_FMT_YUV_GET_X_SUBS(in_pix_fmt) == 2) &&
1936                         (CIF_ISP10_PIX_FMT_YUV_GET_Y_SUBS(in_pix_fmt) == 2) &&
1937                         (CIF_ISP10_PIX_FMT_GET_BPP(in_pix_fmt) == 15))
1938                         data_type = CSI2_DT_YUV420_10b;
1939                 else if ((CIF_ISP10_PIX_FMT_YUV_GET_X_SUBS(in_pix_fmt) == 2) &&
1940                         (CIF_ISP10_PIX_FMT_YUV_GET_Y_SUBS(in_pix_fmt) == 4) &&
1941                         (CIF_ISP10_PIX_FMT_GET_BPP(in_pix_fmt) == 16))
1942                         data_type = CSI2_DT_YUV422_8b;
1943                 else if ((CIF_ISP10_PIX_FMT_YUV_GET_X_SUBS(in_pix_fmt) == 2) &&
1944                         (CIF_ISP10_PIX_FMT_YUV_GET_Y_SUBS(in_pix_fmt) == 4) &&
1945                         (CIF_ISP10_PIX_FMT_GET_BPP(in_pix_fmt) == 20))
1946                         data_type = CSI2_DT_YUV422_10b;
1947                 else {
1948                         cif_isp10_pltfrm_pr_err(dev->dev,
1949                                 "unsupported format %s\n",
1950                                 cif_isp10_pix_fmt_string(in_pix_fmt));
1951                         ret = -EINVAL;
1952                         goto err;
1953                 }
1954         } else if (CIF_ISP10_PIX_FMT_IS_RAW_BAYER(in_pix_fmt)) {
1955                 if (CIF_ISP10_PIX_FMT_GET_BPP(in_pix_fmt) == 8) {
1956                         data_type = CSI2_DT_RAW8;
1957                 } else if (CIF_ISP10_PIX_FMT_GET_BPP(in_pix_fmt) == 10) {
1958                         data_type = CSI2_DT_RAW10;
1959                 } else if (CIF_ISP10_PIX_FMT_GET_BPP(in_pix_fmt) == 12) {
1960                         data_type = CSI2_DT_RAW12;
1961                 } else {
1962                         cif_isp10_pltfrm_pr_err(dev->dev,
1963                                 "unsupported format %s\n",
1964                                 cif_isp10_pix_fmt_string(in_pix_fmt));
1965                         ret = -EINVAL;
1966                         goto err;
1967                 }
1968         } else if (in_pix_fmt == CIF_RGB565) {
1969                 data_type = CSI2_DT_RGB565;
1970         } else if (in_pix_fmt == CIF_RGB666) {
1971                 data_type = CSI2_DT_RGB666;
1972         } else if (in_pix_fmt == CIF_RGB888) {
1973                 data_type = CSI2_DT_RGB888;
1974         } else {
1975                 cif_isp10_pltfrm_pr_err(dev->dev,
1976                         "unsupported format %s\n",
1977                         cif_isp10_pix_fmt_string(in_pix_fmt));
1978                 ret = -EINVAL;
1979                 goto err;
1980         }
1981
1982         cif_iowrite32(
1983                 CIF_MIPI_DATA_SEL_DT(data_type) |
1984                 CIF_MIPI_DATA_SEL_VC(
1985                         dev->config.cam_itf.cfg.mipi.vc),
1986                 dev->config.base_addr + CIF_MIPI_IMG_DATA_SEL);
1987
1988         /* Enable MIPI interrupts */
1989         cif_iowrite32(~0,
1990                 dev->config.base_addr + CIF_MIPI_ICR);
1991         /*
1992          * Disable CIF_MIPI_ERR_DPHY interrupt here temporary for
1993          * isp bus may be dead when switch isp.
1994          */
1995         cif_iowrite32(
1996                 CIF_MIPI_FRAME_END |
1997                 CIF_MIPI_ERR_CSI |
1998                 CIF_MIPI_ERR_DPHY |
1999                 CIF_MIPI_SYNC_FIFO_OVFLW(3) |
2000                 CIF_MIPI_ADD_DATA_OVFLW,
2001                 dev->config.base_addr + CIF_MIPI_IMSC);
2002
2003         cif_isp10_pltfrm_pr_dbg(dev->dev,
2004                 "\n  MIPI_CTRL 0x%08x\n"
2005                 "  MIPI_IMG_DATA_SEL 0x%08x\n"
2006                 "  MIPI_STATUS 0x%08x\n"
2007                 "  MIPI_IMSC 0x%08x\n",
2008                 cif_ioread32(dev->config.base_addr + CIF_MIPI_CTRL),
2009                 cif_ioread32(dev->config.base_addr + CIF_MIPI_IMG_DATA_SEL),
2010                 cif_ioread32(dev->config.base_addr + CIF_MIPI_STATUS),
2011                 cif_ioread32(dev->config.base_addr + CIF_MIPI_IMSC));
2012
2013         return 0;
2014 err:
2015         cif_isp10_pltfrm_pr_err(dev->dev,
2016                 "failed with error %d\n", ret);
2017         return ret;
2018 }
2019
2020 static int cif_isp10_config_mi_mp(
2021         struct cif_isp10_device *dev)
2022 {
2023         enum cif_isp10_pix_fmt out_pix_fmt =
2024                 dev->config.mi_config.mp.output.pix_fmt;
2025         u32 llength =
2026                 dev->config.mi_config.mp.llength;
2027         u32 width =
2028                 dev->config.mi_config.mp.output.width;
2029         u32 height =
2030                 dev->config.mi_config.mp.output.height;
2031         u32 writeformat = CIF_ISP10_BUFF_FMT_PLANAR;
2032         u32 swap_cb_cr = 0;
2033         u32 bpp = CIF_ISP10_PIX_FMT_GET_BPP(out_pix_fmt);
2034         u32 size = llength * height * bpp / 8;
2035         u32 mi_ctrl;
2036
2037         dev->config.mi_config.mp.input =
2038                 &dev->config.mp_config.rsz_config.output;
2039
2040         cif_isp10_pltfrm_pr_dbg(dev->dev,
2041                 "%s %dx%d, llength = %d\n",
2042                 cif_isp10_pix_fmt_string(out_pix_fmt),
2043                 width,
2044                 height,
2045                 llength);
2046
2047         dev->config.mi_config.mp.y_size = size;
2048         dev->config.mi_config.mp.cb_size = 0;
2049         dev->config.mi_config.mp.cr_size = 0;
2050         if (CIF_ISP10_PIX_FMT_IS_YUV(out_pix_fmt)) {
2051                 u32 num_cplanes =
2052                         CIF_ISP10_PIX_FMT_YUV_GET_NUM_CPLANES(out_pix_fmt);
2053                 if (num_cplanes == 0) {
2054                         writeformat = CIF_ISP10_BUFF_FMT_INTERLEAVED;
2055                 } else {
2056                         dev->config.mi_config.mp.y_size =
2057                                 (dev->config.mi_config.mp.y_size * 4) /
2058                                 (4 + (CIF_ISP10_PIX_FMT_YUV_GET_X_SUBS(
2059                                         out_pix_fmt) *
2060                                 CIF_ISP10_PIX_FMT_YUV_GET_Y_SUBS(
2061                                         out_pix_fmt) / 2));
2062                         dev->config.mi_config.mp.cb_size =
2063                                 size -
2064                                 dev->config.mi_config.mp.y_size;
2065                         if (num_cplanes == 1) {
2066                                 writeformat = CIF_ISP10_BUFF_FMT_SEMIPLANAR;
2067                         } else if (num_cplanes == 2) {
2068                                 writeformat = CIF_ISP10_BUFF_FMT_PLANAR;
2069                                 dev->config.mi_config.mp.cb_size /= 2;
2070                         }
2071                         /* for U<->V swapping: */
2072                         dev->config.mi_config.mp.cr_size =
2073                                 dev->config.mi_config.mp.cb_size;
2074                 }
2075                 if (CIF_ISP10_PIX_FMT_YUV_IS_UV_SWAPPED(out_pix_fmt))
2076                         swap_cb_cr = CIF_MI_XTD_FMT_CTRL_MP_CB_CR_SWAP;
2077
2078                 if (writeformat == CIF_ISP10_BUFF_FMT_SEMIPLANAR) {
2079                         dev->config.mi_config.mp.cb_offs =
2080                             dev->config.mi_config.mp.y_size;
2081                         dev->config.mi_config.mp.cr_offs =
2082                             dev->config.mi_config.mp.cb_offs;
2083                 } else if (writeformat == CIF_ISP10_BUFF_FMT_PLANAR) {
2084                         if (swap_cb_cr) {
2085                                 swap_cb_cr = 0;
2086                                 dev->config.mi_config.mp.cr_offs =
2087                                         dev->config.mi_config.mp.y_size;
2088                                 dev->config.mi_config.mp.cb_offs =
2089                                         dev->config.mi_config.mp.cr_offs +
2090                                         dev->config.mi_config.mp.cr_size;
2091                         } else {
2092                                 dev->config.mi_config.mp.cb_offs =
2093                                         dev->config.mi_config.mp.y_size;
2094                                 dev->config.mi_config.mp.cr_offs =
2095                                         dev->config.mi_config.mp.cb_offs +
2096                                         dev->config.mi_config.mp.cb_size;
2097                         }
2098                 }
2099         } else if (CIF_ISP10_PIX_FMT_IS_RAW_BAYER(out_pix_fmt)) {
2100                 if (CIF_ISP10_PIX_FMT_GET_BPP(out_pix_fmt) > 8) {
2101                         writeformat = CIF_ISP10_BUFF_FMT_RAW12;
2102                         dev->config.mi_config.mp.y_size = width * height * 2;
2103                 } else {
2104                         writeformat = CIF_ISP10_BUFF_FMT_RAW8;
2105                         dev->config.mi_config.mp.y_size = width * height;
2106                 }
2107                 dev->config.mi_config.mp.cb_offs = 0x00;
2108                 dev->config.mi_config.mp.cr_offs = 0x00;
2109                 dev->config.mi_config.mp.cb_size = 0x00;
2110                 dev->config.mi_config.mp.cr_size = 0x00;
2111         }
2112
2113         cif_iowrite32_verify(dev->config.mi_config.mp.y_size,
2114                 dev->config.base_addr + CIF_MI_MP_Y_SIZE_INIT,
2115                 CIF_MI_ADDR_SIZE_ALIGN_MASK);
2116         cif_iowrite32_verify(dev->config.mi_config.mp.cb_size,
2117                 dev->config.base_addr + CIF_MI_MP_CB_SIZE_INIT,
2118                 CIF_MI_ADDR_SIZE_ALIGN_MASK);
2119         cif_iowrite32_verify(dev->config.mi_config.mp.cr_size,
2120                 dev->config.base_addr + CIF_MI_MP_CR_SIZE_INIT,
2121                 CIF_MI_ADDR_SIZE_ALIGN_MASK);
2122         cif_iowrite32OR_verify(CIF_MI_MP_FRAME,
2123                 dev->config.base_addr +
2124                 CIF_MI_IMSC, ~0);
2125
2126         if (swap_cb_cr) {
2127                 cif_iowrite32OR(swap_cb_cr,
2128                         dev->config.base_addr + CIF_MI_XTD_FORMAT_CTRL);
2129         }
2130
2131         mi_ctrl = cif_ioread32(dev->config.base_addr + CIF_MI_CTRL) |
2132                 CIF_MI_CTRL_MP_WRITE_FMT(writeformat) |
2133                 CIF_MI_CTRL_BURST_LEN_LUM_64 |
2134                 CIF_MI_CTRL_BURST_LEN_CHROM_64 |
2135                 CIF_MI_CTRL_INIT_BASE_EN |
2136                 CIF_MI_CTRL_INIT_OFFSET_EN |
2137                 CIF_MI_MP_AUTOUPDATE_ENABLE;
2138
2139         cif_iowrite32_verify(mi_ctrl,
2140                 dev->config.base_addr + CIF_MI_CTRL, ~0);
2141
2142         cif_isp10_pltfrm_pr_dbg(dev->dev,
2143                 "\n  MI_CTRL 0x%08x\n"
2144                 "  MI_STATUS 0x%08x\n"
2145                 "  MI_MP_Y_SIZE %d\n"
2146                 "  MI_MP_CB_SIZE %d\n"
2147                 "  MI_MP_CR_SIZE %d\n",
2148                 cif_ioread32(dev->config.base_addr +
2149                         CIF_MI_CTRL),
2150                 cif_ioread32(dev->config.base_addr +
2151                         CIF_MI_STATUS),
2152                 cif_ioread32(dev->config.base_addr +
2153                         CIF_MI_MP_Y_SIZE_INIT),
2154                 cif_ioread32(dev->config.base_addr +
2155                         CIF_MI_MP_CB_SIZE_INIT),
2156                 cif_ioread32(dev->config.base_addr +
2157                         CIF_MI_MP_CR_SIZE_INIT));
2158
2159         return 0;
2160 }
2161
2162 static int cif_isp10_config_mi_sp(
2163         struct cif_isp10_device *dev)
2164 {
2165         int ret = 0;
2166         enum cif_isp10_pix_fmt out_pix_fmt =
2167                 dev->config.mi_config.sp.output.pix_fmt;
2168         enum cif_isp10_pix_fmt in_pix_fmt =
2169                 dev->config.sp_config.rsz_config.output.pix_fmt;
2170         u32 llength =
2171                 dev->config.mi_config.sp.llength;
2172         u32 width =
2173                 dev->config.mi_config.sp.output.width;
2174         u32 height =
2175                 dev->config.mi_config.sp.output.height;
2176         u32 writeformat = CIF_ISP10_BUFF_FMT_PLANAR;
2177         u32 swap_cb_cr = 0;
2178         u32 bpp = CIF_ISP10_PIX_FMT_GET_BPP(out_pix_fmt);
2179         u32 size = llength * height * bpp / 8;
2180         u32 input_format = 0;
2181         u32 output_format;
2182         u32 mi_ctrl;
2183
2184         dev->config.mi_config.sp.input =
2185                 &dev->config.sp_config.rsz_config.output;
2186
2187         cif_isp10_pltfrm_pr_dbg(dev->dev,
2188                 "%s %dx%d, llength = %d\n",
2189                 cif_isp10_pix_fmt_string(out_pix_fmt),
2190                 width,
2191                 height,
2192                 llength);
2193
2194         if (!CIF_ISP10_PIX_FMT_IS_YUV(in_pix_fmt)) {
2195                 cif_isp10_pltfrm_pr_err(dev->dev,
2196                         "unsupported format %s (must be YUV)\n",
2197                         cif_isp10_pix_fmt_string(in_pix_fmt));
2198                 ret = -EINVAL;
2199                 goto err;
2200         }
2201
2202         dev->config.mi_config.sp.y_size = size;
2203         dev->config.mi_config.sp.cb_size = 0;
2204         dev->config.mi_config.sp.cr_size = 0;
2205         if (CIF_ISP10_PIX_FMT_IS_YUV(out_pix_fmt)) {
2206                 u32 num_cplanes =
2207                         CIF_ISP10_PIX_FMT_YUV_GET_NUM_CPLANES(out_pix_fmt);
2208                 if (num_cplanes == 0) {
2209                         writeformat = CIF_ISP10_BUFF_FMT_INTERLEAVED;
2210                 } else {
2211                         dev->config.mi_config.sp.y_size =
2212                                 (dev->config.mi_config.sp.y_size * 4) /
2213                                 (4 + (CIF_ISP10_PIX_FMT_YUV_GET_X_SUBS(
2214                                         out_pix_fmt) *
2215                                 CIF_ISP10_PIX_FMT_YUV_GET_Y_SUBS(
2216                                         out_pix_fmt) / 2));
2217                         dev->config.mi_config.sp.cb_size =
2218                                 size -
2219                                 dev->config.mi_config.sp.y_size;
2220                         if (num_cplanes == 1) {
2221                                 writeformat = CIF_ISP10_BUFF_FMT_SEMIPLANAR;
2222                         } else if (num_cplanes == 2) {
2223                                 writeformat = CIF_ISP10_BUFF_FMT_PLANAR;
2224                                 dev->config.mi_config.sp.cb_size /= 2;
2225                         }
2226                         /* for U<->V swapping: */
2227                         dev->config.mi_config.sp.cr_size =
2228                                 dev->config.mi_config.sp.cb_size;
2229                 }
2230                 if (CIF_ISP10_PIX_FMT_YUV_IS_UV_SWAPPED(out_pix_fmt))
2231                         swap_cb_cr = CIF_MI_XTD_FMT_CTRL_SP_CB_CR_SWAP;
2232
2233                 if ((CIF_ISP10_PIX_FMT_YUV_GET_X_SUBS(out_pix_fmt) == 0) &&
2234                         (CIF_ISP10_PIX_FMT_YUV_GET_Y_SUBS(out_pix_fmt) == 0))
2235                         output_format = CIF_MI_CTRL_SP_OUTPUT_FMT_YUV400;
2236                 else if ((CIF_ISP10_PIX_FMT_YUV_GET_X_SUBS(out_pix_fmt) == 2) &&
2237                         (CIF_ISP10_PIX_FMT_YUV_GET_Y_SUBS(out_pix_fmt) == 2))
2238                         output_format = CIF_MI_CTRL_SP_OUTPUT_FMT_YUV420;
2239                 else if ((CIF_ISP10_PIX_FMT_YUV_GET_X_SUBS(out_pix_fmt) == 2) &&
2240                         (CIF_ISP10_PIX_FMT_YUV_GET_Y_SUBS(out_pix_fmt) == 4))
2241                         output_format = CIF_MI_CTRL_SP_OUTPUT_FMT_YUV422;
2242                 else if ((CIF_ISP10_PIX_FMT_YUV_GET_X_SUBS(out_pix_fmt) == 4) &&
2243                         (CIF_ISP10_PIX_FMT_YUV_GET_Y_SUBS(out_pix_fmt) == 4))
2244                         output_format = CIF_MI_CTRL_SP_OUTPUT_FMT_YUV444;
2245                 else {
2246                         cif_isp10_pltfrm_pr_err(dev->dev,
2247                                 "unsupported YUV output format %s\n",
2248                                 cif_isp10_pix_fmt_string(out_pix_fmt));
2249                         ret = -EINVAL;
2250                         goto err;
2251                 }
2252         } else if (CIF_ISP10_PIX_FMT_IS_RGB(out_pix_fmt)) {
2253                 if (out_pix_fmt == CIF_RGB565) {
2254                         output_format = CIF_MI_CTRL_SP_OUTPUT_FMT_RGB565;
2255                 } else if (out_pix_fmt == CIF_RGB666) {
2256                         output_format = CIF_MI_CTRL_SP_OUTPUT_FMT_RGB666;
2257                 } else if (out_pix_fmt == CIF_RGB888) {
2258                         output_format = CIF_MI_CTRL_SP_OUTPUT_FMT_RGB888;
2259                 } else {
2260                         cif_isp10_pltfrm_pr_err(dev->dev,
2261                                 "unsupported RGB output format %s\n",
2262                                 cif_isp10_pix_fmt_string(out_pix_fmt));
2263                         ret = -EINVAL;
2264                         goto err;
2265                 }
2266         } else {
2267                 cif_isp10_pltfrm_pr_err(dev->dev,
2268                         "unsupported output format %s\n",
2269                         cif_isp10_pix_fmt_string(out_pix_fmt));
2270                 ret = -EINVAL;
2271                 goto err;
2272         }
2273
2274         if ((CIF_ISP10_PIX_FMT_YUV_GET_X_SUBS(in_pix_fmt) == 0) &&
2275                 (CIF_ISP10_PIX_FMT_YUV_GET_Y_SUBS(in_pix_fmt) == 0))
2276                 input_format = CIF_MI_CTRL_SP_INPUT_FMT_YUV400;
2277         else if ((CIF_ISP10_PIX_FMT_YUV_GET_X_SUBS(in_pix_fmt) == 2) &&
2278                 (CIF_ISP10_PIX_FMT_YUV_GET_Y_SUBS(in_pix_fmt) == 2))
2279                 input_format = CIF_MI_CTRL_SP_INPUT_FMT_YUV420;
2280         else if ((CIF_ISP10_PIX_FMT_YUV_GET_X_SUBS(in_pix_fmt) == 2) &&
2281                 (CIF_ISP10_PIX_FMT_YUV_GET_Y_SUBS(in_pix_fmt) == 4))
2282                 input_format = CIF_MI_CTRL_SP_INPUT_FMT_YUV422;
2283         else if ((CIF_ISP10_PIX_FMT_YUV_GET_X_SUBS(in_pix_fmt) == 4) &&
2284                 (CIF_ISP10_PIX_FMT_YUV_GET_Y_SUBS(in_pix_fmt) == 4))
2285                 input_format = CIF_MI_CTRL_SP_INPUT_FMT_YUV444;
2286         else {
2287                 cif_isp10_pltfrm_pr_err(dev->dev,
2288                         "unsupported YUV input format %s\n",
2289                         cif_isp10_pix_fmt_string(in_pix_fmt));
2290                 ret = -EINVAL;
2291                 goto err;
2292         }
2293
2294         if (writeformat == CIF_ISP10_BUFF_FMT_SEMIPLANAR) {
2295                 dev->config.mi_config.sp.cb_offs =
2296                     dev->config.mi_config.sp.y_size;
2297                 dev->config.mi_config.sp.cr_offs =
2298                     dev->config.mi_config.sp.cb_offs;
2299         } else if (writeformat == CIF_ISP10_BUFF_FMT_PLANAR) {
2300                 if (swap_cb_cr) {
2301                         swap_cb_cr = 0;
2302                         dev->config.mi_config.sp.cr_offs =
2303                                 dev->config.mi_config.sp.y_size;
2304                         dev->config.mi_config.sp.cb_offs =
2305                                 dev->config.mi_config.sp.cr_offs +
2306                                 dev->config.mi_config.sp.cr_size;
2307                 } else {
2308                         dev->config.mi_config.sp.cb_offs =
2309                                 dev->config.mi_config.sp.y_size;
2310                         dev->config.mi_config.sp.cr_offs =
2311                                 dev->config.mi_config.sp.cb_offs +
2312                                 dev->config.mi_config.sp.cb_size;
2313                 }
2314         }
2315
2316         cif_iowrite32_verify(dev->config.mi_config.sp.y_size,
2317                 dev->config.base_addr + CIF_MI_SP_Y_SIZE_INIT,
2318                 CIF_MI_ADDR_SIZE_ALIGN_MASK);
2319         cif_iowrite32_verify(dev->config.mi_config.sp.y_size,
2320                 dev->config.base_addr + CIF_MI_SP_Y_PIC_SIZE,
2321                 CIF_MI_ADDR_SIZE_ALIGN_MASK);
2322         cif_iowrite32_verify(dev->config.mi_config.sp.cb_size,
2323                 dev->config.base_addr + CIF_MI_SP_CB_SIZE_INIT,
2324                 CIF_MI_ADDR_SIZE_ALIGN_MASK);
2325         cif_iowrite32_verify(dev->config.mi_config.sp.cr_size,
2326                 dev->config.base_addr + CIF_MI_SP_CR_SIZE_INIT,
2327                 CIF_MI_ADDR_SIZE_ALIGN_MASK);
2328         cif_iowrite32_verify(width,
2329                 dev->config.base_addr + CIF_MI_SP_Y_PIC_WIDTH, ~0x3);
2330         cif_iowrite32_verify(height,
2331                 dev->config.base_addr + CIF_MI_SP_Y_PIC_HEIGHT, ~0x3);
2332         cif_iowrite32_verify(llength,
2333                 dev->config.base_addr + CIF_MI_SP_Y_LLENGTH, ~0x3);
2334         cif_iowrite32OR_verify(CIF_MI_SP_FRAME,
2335                 dev->config.base_addr +
2336                 CIF_MI_IMSC, ~0);
2337
2338         if (swap_cb_cr) {
2339                 cif_iowrite32OR(swap_cb_cr,
2340                         dev->config.base_addr + CIF_MI_XTD_FORMAT_CTRL);
2341         }
2342
2343         mi_ctrl = cif_ioread32(dev->config.base_addr + CIF_MI_CTRL) |
2344                 CIF_MI_CTRL_SP_WRITE_FMT(writeformat) |
2345                 input_format |
2346                 output_format |
2347                 CIF_MI_CTRL_BURST_LEN_LUM_64 |
2348                 CIF_MI_CTRL_BURST_LEN_CHROM_64 |
2349                 CIF_MI_CTRL_INIT_BASE_EN |
2350                 CIF_MI_CTRL_INIT_OFFSET_EN |
2351                 CIF_MI_SP_AUTOUPDATE_ENABLE;
2352         cif_iowrite32_verify(mi_ctrl,
2353                 dev->config.base_addr + CIF_MI_CTRL, ~0);
2354
2355         cif_isp10_pltfrm_pr_dbg(dev->dev,
2356                 "\n  MI_CTRL 0x%08x\n"
2357                 "  MI_STATUS 0x%08x\n"
2358                 "  MI_SP_Y_SIZE %d\n"
2359                 "  MI_SP_CB_SIZE %d\n"
2360                 "  MI_SP_CR_SIZE %d\n"
2361                 "  MI_SP_PIC_WIDTH %d\n"
2362                 "  MI_SP_PIC_HEIGHT %d\n"
2363                 "  MI_SP_PIC_LLENGTH %d\n"
2364                 "  MI_SP_PIC_SIZE %d\n",
2365                 cif_ioread32(dev->config.base_addr + CIF_MI_CTRL),
2366                 cif_ioread32(dev->config.base_addr + CIF_MI_STATUS),
2367                 cif_ioread32(dev->config.base_addr + CIF_MI_SP_Y_SIZE_INIT),
2368                 cif_ioread32(dev->config.base_addr + CIF_MI_SP_CB_SIZE_INIT),
2369                 cif_ioread32(dev->config.base_addr + CIF_MI_SP_CR_SIZE_INIT),
2370                 cif_ioread32(dev->config.base_addr + CIF_MI_SP_Y_PIC_WIDTH),
2371                 cif_ioread32(dev->config.base_addr + CIF_MI_SP_Y_PIC_HEIGHT),
2372                 cif_ioread32(dev->config.base_addr + CIF_MI_SP_Y_LLENGTH),
2373                 cif_ioread32(dev->config.base_addr + CIF_MI_SP_Y_PIC_SIZE));
2374
2375         return 0;
2376 err:
2377         cif_isp10_pltfrm_pr_err(dev->dev,
2378                 "failed with error %d\n", ret);
2379         return ret;
2380 }
2381
2382 static int cif_isp10_config_mi_dma(
2383         struct cif_isp10_device *dev)
2384 {
2385         int ret = 0;
2386         enum cif_isp10_pix_fmt out_pix_fmt =
2387                 dev->config.mi_config.dma.output.pix_fmt;
2388         u32 llength =
2389                 dev->config.mi_config.dma.llength;
2390         u32 width =
2391                 dev->config.mi_config.dma.output.width;
2392         u32 height =
2393                 dev->config.mi_config.dma.output.height;
2394         u32 readformat = CIF_ISP10_BUFF_FMT_PLANAR;
2395         u32 bpp = CIF_ISP10_PIX_FMT_GET_BPP(out_pix_fmt);
2396         u32 size = llength * height * bpp / 8;
2397         u32 output_format;
2398         u32 mi_ctrl;
2399
2400         cif_isp10_pltfrm_pr_dbg(dev->dev,
2401                 "%s %dx%d, llength = %d\n",
2402                 cif_isp10_pix_fmt_string(out_pix_fmt),
2403                 width,
2404                 height,
2405                 llength);
2406
2407         dev->config.mi_config.dma.y_size = size;
2408         dev->config.mi_config.dma.cb_size = 0;
2409         dev->config.mi_config.dma.cr_size = 0;
2410         if (CIF_ISP10_PIX_FMT_IS_YUV(out_pix_fmt)) {
2411                 u32 num_cplanes =
2412                         CIF_ISP10_PIX_FMT_YUV_GET_NUM_CPLANES(out_pix_fmt);
2413                 if (num_cplanes == 0) {
2414                         readformat = CIF_ISP10_BUFF_FMT_INTERLEAVED;
2415                 } else {
2416                         dev->config.mi_config.dma.y_size =
2417                                 (dev->config.mi_config.dma.y_size * 4) /
2418                                  (4 + (CIF_ISP10_PIX_FMT_YUV_GET_X_SUBS(
2419                                         out_pix_fmt) *
2420                                 CIF_ISP10_PIX_FMT_YUV_GET_Y_SUBS(
2421                                         out_pix_fmt) / 2));
2422                         dev->config.mi_config.dma.cb_size =
2423                                 size -
2424                                 dev->config.mi_config.dma.y_size;
2425                         if (num_cplanes == 1) {
2426                                 readformat = CIF_ISP10_BUFF_FMT_SEMIPLANAR;
2427                         } else if (num_cplanes == 2) {
2428                                 readformat = CIF_ISP10_BUFF_FMT_PLANAR;
2429                                 dev->config.mi_config.dma.cb_size /= 2;
2430                         }
2431                         /* for U<->V swapping: */
2432                         dev->config.mi_config.dma.cr_size =
2433                                 dev->config.mi_config.dma.cb_size;
2434                 }
2435
2436                 if ((CIF_ISP10_PIX_FMT_YUV_GET_X_SUBS(out_pix_fmt) == 0) &&
2437                         (CIF_ISP10_PIX_FMT_YUV_GET_Y_SUBS(out_pix_fmt) == 0))
2438                         output_format = CIF_MI_DMA_CTRL_FMT_YUV400;
2439                 else if ((CIF_ISP10_PIX_FMT_YUV_GET_X_SUBS(out_pix_fmt) == 2) &&
2440                         (CIF_ISP10_PIX_FMT_YUV_GET_Y_SUBS(out_pix_fmt) == 2))
2441                         output_format = CIF_MI_DMA_CTRL_FMT_YUV420;
2442                 else if ((CIF_ISP10_PIX_FMT_YUV_GET_X_SUBS(out_pix_fmt) == 2) &&
2443                         (CIF_ISP10_PIX_FMT_YUV_GET_Y_SUBS(out_pix_fmt) == 4))
2444                         output_format = CIF_MI_DMA_CTRL_FMT_YUV422;
2445                 else if ((CIF_ISP10_PIX_FMT_YUV_GET_X_SUBS(out_pix_fmt) == 4) &&
2446                         (CIF_ISP10_PIX_FMT_YUV_GET_Y_SUBS(out_pix_fmt) == 4))
2447                         output_format = CIF_MI_DMA_CTRL_FMT_YUV444;
2448                 else {
2449                         cif_isp10_pltfrm_pr_err(dev->dev,
2450                                 "unsupported YUV output format %s\n",
2451                                 cif_isp10_pix_fmt_string(out_pix_fmt));
2452                         ret = -EINVAL;
2453                         goto err;
2454                 }
2455         } else {
2456                 cif_isp10_pltfrm_pr_err(dev->dev,
2457                         "unsupported output format %s\n",
2458                         cif_isp10_pix_fmt_string(out_pix_fmt));
2459                 ret = -EINVAL;
2460                 goto err;
2461         }
2462
2463         if (readformat == CIF_ISP10_BUFF_FMT_SEMIPLANAR) {
2464                 dev->config.mi_config.dma.cb_offs =
2465                     dev->config.mi_config.dma.y_size;
2466                 dev->config.mi_config.dma.cr_offs =
2467                     dev->config.mi_config.dma.cb_offs;
2468         } else if (readformat == CIF_ISP10_BUFF_FMT_PLANAR) {
2469                 dev->config.mi_config.dma.cb_offs =
2470                         dev->config.mi_config.dma.y_size;
2471                 dev->config.mi_config.dma.cr_offs =
2472                         dev->config.mi_config.dma.cb_offs +
2473                         dev->config.mi_config.dma.cb_size;
2474         }
2475
2476         cif_iowrite32_verify(dev->config.mi_config.dma.y_size,
2477                 dev->config.base_addr + CIF_MI_DMA_Y_PIC_SIZE, ~0x3);
2478         cif_iowrite32_verify(width,
2479                 dev->config.base_addr + CIF_MI_DMA_Y_PIC_WIDTH, ~0x3);
2480         cif_iowrite32_verify(llength,
2481                 dev->config.base_addr + CIF_MI_DMA_Y_LLENGTH, ~0x3);
2482
2483         mi_ctrl = cif_ioread32(dev->config.base_addr + CIF_MI_DMA_CTRL) |
2484                 CIF_MI_DMA_CTRL_READ_FMT(readformat) |
2485                 output_format |
2486                 CIF_MI_DMA_CTRL_BURST_LEN_LUM_64 |
2487                 CIF_MI_DMA_CTRL_BURST_LEN_CHROM_64;
2488         cif_iowrite32_verify(mi_ctrl,
2489                 dev->config.base_addr + CIF_MI_DMA_CTRL, ~0);
2490
2491         cif_iowrite32OR_verify(CIF_MI_DMA_READY,
2492                 dev->config.base_addr + CIF_MI_IMSC, ~0);
2493
2494         cif_isp10_pltfrm_pr_dbg(dev->dev,
2495                 "\n  MI_DMA_CTRL 0x%08x\n"
2496                 "  MI_DMA_STATUS 0x%08x\n"
2497                 "  MI_DMA_Y_PIC_WIDTH %d\n"
2498                 "  MI_DMA_Y_LLENGTH %d\n"
2499                 "  MI_DMA_Y_PIC_SIZE %d\n"
2500                 "  MI_DMA_Y_PIC_START_AD %d\n"
2501                 "  MI_DMA_CB_PIC_START_AD %d\n"
2502                 "  MI_DMA_CR_PIC_START_AD %d\n",
2503                 cif_ioread32(dev->config.base_addr +
2504                         CIF_MI_DMA_CTRL),
2505                 cif_ioread32(dev->config.base_addr +
2506                         CIF_MI_DMA_STATUS),
2507                 cif_ioread32(dev->config.base_addr +
2508                         CIF_MI_DMA_Y_PIC_WIDTH),
2509                 cif_ioread32(dev->config.base_addr +
2510                         CIF_MI_DMA_Y_LLENGTH),
2511                 cif_ioread32(dev->config.base_addr +
2512                         CIF_MI_DMA_Y_PIC_SIZE),
2513                 cif_ioread32(dev->config.base_addr +
2514                         CIF_MI_DMA_Y_PIC_START_AD),
2515                 cif_ioread32(dev->config.base_addr +
2516                         CIF_MI_DMA_CB_PIC_START_AD),
2517                 cif_ioread32(dev->config.base_addr +
2518                         CIF_MI_DMA_CR_PIC_START_AD));
2519
2520         return 0;
2521 err:
2522         cif_isp10_pltfrm_pr_err(dev->dev,
2523                 "failed with error %d\n", ret);
2524         return ret;
2525 }
2526
2527 static int cif_isp10_config_jpeg_enc(
2528         struct cif_isp10_device *dev)
2529 {
2530         struct cif_isp10_frm_fmt *inp_fmt =
2531                 &dev->config.mp_config.rsz_config.output;
2532         dev->config.jpeg_config.input = inp_fmt;
2533
2534         cif_isp10_pltfrm_pr_dbg(NULL,
2535                 "%s %dx%d\n",
2536                 cif_isp10_pix_fmt_string(inp_fmt->pix_fmt),
2537                 inp_fmt->width, inp_fmt->height);
2538
2539         /*
2540          * Reset JPEG-Encoder. In contrast to other software
2541          * resets this triggers the modules asynchronous reset
2542          * resulting in loss of all data
2543          */
2544         cif_iowrite32OR(CIF_IRCL_JPEG_SW_RST,
2545                 dev->config.base_addr + CIF_IRCL);
2546         cif_iowrite32AND(~CIF_IRCL_JPEG_SW_RST,
2547                 dev->config.base_addr + CIF_IRCL);
2548
2549         cif_iowrite32(CIF_JPE_ERROR_MASK,
2550                 dev->config.base_addr + CIF_JPE_ERROR_IMSC);
2551
2552         /* Set configuration for the Jpeg capturing */
2553         cif_iowrite32(inp_fmt->width,
2554                 dev->config.base_addr + CIF_JPE_ENC_HSIZE);
2555         cif_iowrite32(inp_fmt->height,
2556                 dev->config.base_addr + CIF_JPE_ENC_VSIZE);
2557
2558         if (CIF_ISP10_INP_IS_DMA(dev->config.input_sel) ||
2559                 !CIF_ISP10_PIX_FMT_IS_RAW_BAYER(
2560                 dev->config.isp_config.input->pix_fmt)) {
2561                 /*
2562                  * upscaling of BT601 color space to full range 0..255
2563                  * TODO: DMA or YUV sensor input in full range.
2564                  */
2565                 cif_iowrite32(CIF_JPE_LUM_SCALE_ENABLE,
2566                         dev->config.base_addr + CIF_JPE_Y_SCALE_EN);
2567                 cif_iowrite32(CIF_JPE_CHROM_SCALE_ENABLE,
2568                         dev->config.base_addr + CIF_JPE_CBCR_SCALE_EN);
2569         }
2570
2571         switch (inp_fmt->pix_fmt) {
2572         case CIF_YUV422I:
2573         case CIF_YVU422I:
2574         case CIF_YUV422SP:
2575         case CIF_YVU422SP:
2576         case CIF_YUV422P:
2577         case CIF_YVU422P:
2578                 cif_iowrite32(CIF_JPE_PIC_FORMAT_YUV422,
2579                         dev->config.base_addr + CIF_JPE_PIC_FORMAT);
2580                 break;
2581         case CIF_YUV400:
2582         case CIF_YVU400:
2583                 cif_iowrite32(CIF_JPE_PIC_FORMAT_YUV400,
2584                         dev->config.base_addr + CIF_JPE_PIC_FORMAT);
2585                 break;
2586         default:
2587                 cif_isp10_pltfrm_pr_err(NULL,
2588                         "format %s not supported as input for JPEG encoder\n",
2589                         cif_isp10_pix_fmt_string(inp_fmt->pix_fmt));
2590                 WARN_ON(1);
2591                 break;
2592         }
2593
2594         /*
2595          * Set to normal operation (wait for encoded image data
2596          * to fill output buffer)
2597          */
2598         cif_iowrite32(0, dev->config.base_addr + CIF_JPE_TABLE_FLUSH);
2599
2600         /*
2601          *  CIF Spec 4.7
2602          *  3.14 JPEG Encoder Programming
2603          *  Do not forget to re-program all AC and DC tables
2604          *  after system reset as well as after
2605          *  module software reset because after any reset
2606          *  the internal RAM is filled with FFH which
2607          *  is an illegal symbol. This filling takes
2608          *  approximately 400 clock cycles. So do not start
2609          *  any table programming during the first 400 clock
2610          *  cycles after reset is de-asserted.
2611          *  Note: depends on CIF clock setting
2612          *  400 clock cycles at 312 Mhz CIF clock-> 1.3 us
2613          *  400 clock cycles at 208 Mhz CIF clock-> 1.93 us
2614          *  -> 2us ok for both
2615          */
2616         udelay(2);
2617
2618         /* Program JPEG tables */
2619         cif_isp10_program_jpeg_tables(dev);
2620         /* Select JPEG tables */
2621         cif_isp10_select_jpeg_tables(dev);
2622
2623         switch (dev->config.jpeg_config.header) {
2624         case CIF_ISP10_JPEG_HEADER_JFIF:
2625                 cif_isp10_pltfrm_pr_dbg(NULL,
2626                         "generate JFIF header\n");
2627                 cif_iowrite32(CIF_JPE_HEADER_MODE_JFIF,
2628                         dev->config.base_addr +
2629                         CIF_JPE_HEADER_MODE);
2630                 break;
2631         case CIF_ISP10_JPEG_HEADER_NONE:
2632                 cif_isp10_pltfrm_pr_dbg(NULL,
2633                         "generate no JPEG header\n");
2634                 cif_iowrite32(CIF_JPE_HEADER_MODE_NOAPPN,
2635                         dev->config.base_addr +
2636                         CIF_JPE_HEADER_MODE);
2637                 break;
2638         default:
2639                 cif_isp10_pltfrm_pr_err(NULL,
2640                         "unknown/unsupport JPEG header type %d\n",
2641                         dev->config.jpeg_config.header);
2642                 WARN_ON(1);
2643                 break;
2644         }
2645
2646         cif_isp10_pltfrm_pr_dbg(dev->dev,
2647                 "\n  JPE_PIC_FORMAT 0x%08x\n"
2648                 "  JPE_ENC_HSIZE %d\n"
2649                 "  JPE_ENC_VSIZE %d\n"
2650                 "  JPE_Y_SCALE_EN 0x%08x\n"
2651                 "  JPE_CBCR_SCALE_EN 0x%08x\n"
2652                 "  JPE_ERROR_RIS 0x%08x\n"
2653                 "  JPE_ERROR_IMSC 0x%08x\n"
2654                 "  JPE_STATUS_RIS 0x%08x\n"
2655                 "  JPE_STATUS_IMSC 0x%08x\n"
2656                 "  JPE_DEBUG 0x%08x\n",
2657                 cif_ioread32(dev->config.base_addr + CIF_JPE_PIC_FORMAT),
2658                 cif_ioread32(dev->config.base_addr + CIF_JPE_ENC_HSIZE),
2659                 cif_ioread32(dev->config.base_addr + CIF_JPE_ENC_VSIZE),
2660                 cif_ioread32(dev->config.base_addr + CIF_JPE_Y_SCALE_EN),
2661                 cif_ioread32(dev->config.base_addr + CIF_JPE_CBCR_SCALE_EN),
2662                 cif_ioread32(dev->config.base_addr + CIF_JPE_ERROR_RIS),
2663                 cif_ioread32(dev->config.base_addr + CIF_JPE_ERROR_IMSC),
2664                 cif_ioread32(dev->config.base_addr + CIF_JPE_STATUS_RIS),
2665                 cif_ioread32(dev->config.base_addr + CIF_JPE_STATUS_IMSC),
2666                 cif_ioread32(dev->config.base_addr + CIF_JPE_DEBUG));
2667
2668         return 0;
2669 }
2670
2671 static int cif_isp10_config_path(
2672         struct cif_isp10_device *dev,
2673         u32 stream_ids)
2674 {
2675         u32 dpcl = 0;
2676
2677         cif_isp10_pltfrm_pr_dbg(dev->dev, "\n");
2678
2679         /* if_sel */
2680         if (dev->config.input_sel == CIF_ISP10_INP_DMA) {
2681                 dpcl |= CIF_VI_DPCL_DMA_SW_ISP;
2682         }       else if (dev->config.input_sel == CIF_ISP10_INP_DMA_IE) {
2683                 dpcl |= CIF_VI_DPCL_DMA_IE_MUX_DMA |
2684                         CIF_VI_DPCL_DMA_SW_IE;
2685         } else if (dev->config.input_sel == CIF_ISP10_INP_DMA_SP) {
2686                 dpcl |= CIF_VI_DPCL_DMA_SP_MUX_DMA;
2687         } else {
2688                 if (PLTFRM_CAM_ITF_IS_DVP(dev->config.cam_itf.type)) {
2689                         dpcl |= CIF_VI_DPCL_IF_SEL_PARALLEL;
2690                 } else if (PLTFRM_CAM_ITF_IS_MIPI(dev->config.cam_itf.type)) {
2691                         dpcl |= CIF_VI_DPCL_IF_SEL_MIPI;
2692                 } else {
2693                         cif_isp10_pltfrm_pr_err(dev->dev,
2694                                 "Sensor Interface: 0x%x isn't support\n",
2695                                 dev->config.cam_itf.type);
2696                         return -EINVAL;
2697                 }
2698         }
2699
2700         /* chan_mode */
2701         if (stream_ids & CIF_ISP10_STREAM_SP)
2702                 dpcl |= CIF_VI_DPCL_CHAN_MODE_SP;
2703
2704         if ((stream_ids & CIF_ISP10_STREAM_MP) &&
2705                 !(dev->config.input_sel == CIF_ISP10_INP_DMA_SP)) {
2706                 dpcl |= CIF_VI_DPCL_CHAN_MODE_MP;
2707                 /* mp_dmux */
2708                 if (dev->config.jpeg_config.enable)
2709                         dpcl |= CIF_VI_DPCL_MP_MUX_MRSZ_JPEG;
2710                 else
2711                         dpcl |= CIF_VI_DPCL_MP_MUX_MRSZ_MI;
2712         }
2713
2714         cif_iowrite32(dpcl,
2715                 dev->config.base_addr + CIF_VI_DPCL);
2716
2717         cif_isp10_pltfrm_pr_dbg(dev->dev, "CIF_DPCL 0x%08x\n", dpcl);
2718
2719         return 0;
2720 }
2721
2722 int cif_isp10_config_dcrop(
2723         struct cif_isp10_device *dev,
2724         enum cif_isp10_stream_id stream_id,
2725         bool async)
2726 {
2727         unsigned int dc_ctrl = cif_ioread32(
2728                                                 dev->config.base_addr +
2729                                                 CIF_DUAL_CROP_CTRL);
2730
2731         if (stream_id == CIF_ISP10_STREAM_MP) {
2732                 cif_iowrite32(0, dev->config.base_addr +
2733                 CIF_DUAL_CROP_M_H_OFFS);
2734                 cif_iowrite32(0, dev->config.base_addr +
2735                 CIF_DUAL_CROP_M_V_OFFS);
2736                 cif_iowrite32(0, dev->config.base_addr +
2737                 CIF_DUAL_CROP_M_H_SIZE);
2738                 cif_iowrite32(0, dev->config.base_addr +
2739                 CIF_DUAL_CROP_M_V_SIZE);
2740
2741                 dc_ctrl |= CIF_DUAL_CROP_MP_MODE_BYPASS;
2742                 if (async)
2743                         dc_ctrl |= CIF_DUAL_CROP_GEN_CFG_UPD;
2744                 else
2745                         dc_ctrl |= CIF_DUAL_CROP_CFG_UPD;
2746
2747                 cif_iowrite32(dc_ctrl,
2748                         dev->config.base_addr + CIF_DUAL_CROP_CTRL);
2749         } else if (stream_id == CIF_ISP10_STREAM_SP) {
2750                 cif_iowrite32(0, dev->config.base_addr +
2751                 CIF_DUAL_CROP_S_H_OFFS);
2752                 cif_iowrite32(0, dev->config.base_addr +
2753                 CIF_DUAL_CROP_S_V_OFFS);
2754                 cif_iowrite32(0, dev->config.base_addr +
2755                 CIF_DUAL_CROP_S_H_SIZE);
2756                 cif_iowrite32(0, dev->config.base_addr +
2757                 CIF_DUAL_CROP_S_V_SIZE);
2758
2759                 dc_ctrl |= CIF_DUAL_CROP_MP_MODE_BYPASS;
2760                 if (async)
2761                         dc_ctrl |= CIF_DUAL_CROP_GEN_CFG_UPD;
2762                 else
2763                         dc_ctrl |= CIF_DUAL_CROP_CFG_UPD;
2764
2765                 cif_iowrite32(dc_ctrl,
2766                         dev->config.base_addr + CIF_DUAL_CROP_CTRL);
2767         }
2768
2769         return 0;
2770 }
2771
2772 int cif_isp10_config_rsz(
2773         struct cif_isp10_device *dev,
2774         enum cif_isp10_stream_id stream_id,
2775         bool async)
2776 {
2777         int ret;
2778         u32 i;
2779         CIF_ISP10_PLTFRM_MEM_IO_ADDR scale_h_y_addr =
2780                 dev->config.base_addr;
2781         CIF_ISP10_PLTFRM_MEM_IO_ADDR scale_h_cr_addr =
2782                 dev->config.base_addr;
2783         CIF_ISP10_PLTFRM_MEM_IO_ADDR scale_h_cb_addr =
2784                 dev->config.base_addr;
2785         CIF_ISP10_PLTFRM_MEM_IO_ADDR scale_v_y_addr =
2786                 dev->config.base_addr;
2787         CIF_ISP10_PLTFRM_MEM_IO_ADDR scale_v_c_addr =
2788                 dev->config.base_addr;
2789         CIF_ISP10_PLTFRM_MEM_IO_ADDR rsz_ctrl_addr =
2790                 dev->config.base_addr;
2791         struct cif_isp10_frm_fmt *rsz_input;
2792         struct cif_isp10_frm_fmt *rsz_output;
2793         struct cif_isp10_frm_fmt *mi_output;
2794         u32 rsz_ctrl;
2795         u32 input_width_y;
2796         u32 output_width_y;
2797         u32 input_height_y;
2798         u32 output_height_y;
2799         u32 input_width_c;
2800         u32 output_width_c;
2801         u32 input_height_c;
2802         u32 output_height_c;
2803         u32 scale_h_c;
2804
2805         if (stream_id == CIF_ISP10_STREAM_MP) {
2806                 rsz_ctrl_addr += CIF_MRSZ_CTRL;
2807                 scale_h_y_addr += CIF_MRSZ_SCALE_HY;
2808                 scale_v_y_addr += CIF_MRSZ_SCALE_VY;
2809                 scale_h_cb_addr += CIF_MRSZ_SCALE_HCB;
2810                 scale_h_cr_addr += CIF_MRSZ_SCALE_HCR;
2811                 scale_v_c_addr += CIF_MRSZ_SCALE_VC;
2812                 dev->config.mp_config.rsz_config.input =
2813                         &dev->config.isp_config.output;
2814                 rsz_input = dev->config.mp_config.rsz_config.input;
2815                 rsz_output = &dev->config.mp_config.rsz_config.output;
2816                 mi_output = &dev->config.mi_config.mp.output;
2817                 /* No phase offset */
2818                 cif_iowrite32(0, dev->config.base_addr + CIF_MRSZ_PHASE_HY);
2819                 cif_iowrite32(0, dev->config.base_addr + CIF_MRSZ_PHASE_HC);
2820                 cif_iowrite32(0, dev->config.base_addr + CIF_MRSZ_PHASE_VY);
2821                 cif_iowrite32(0, dev->config.base_addr + CIF_MRSZ_PHASE_VC);
2822                 /* Linear interpolation */
2823                 for (i = 0; i < 64; i++) {
2824                         cif_iowrite32(i,
2825                                 dev->config.base_addr +
2826                                         CIF_MRSZ_SCALE_LUT_ADDR);
2827                         cif_iowrite32(i,
2828                                 dev->config.base_addr +
2829                                         CIF_MRSZ_SCALE_LUT);
2830                 }
2831         } else {
2832                 rsz_ctrl_addr += CIF_SRSZ_CTRL;
2833                 scale_h_y_addr += CIF_SRSZ_SCALE_HY;
2834                 scale_v_y_addr += CIF_SRSZ_SCALE_VY;
2835                 scale_h_cb_addr += CIF_SRSZ_SCALE_HCB;
2836                 scale_h_cr_addr += CIF_SRSZ_SCALE_HCR;
2837                 scale_v_c_addr += CIF_SRSZ_SCALE_VC;
2838                 if (dev->config.input_sel == CIF_ISP10_INP_DMA_SP)
2839                         dev->config.sp_config.rsz_config.input =
2840                                 &dev->config.mi_config.dma.output;
2841                 else
2842                         dev->config.sp_config.rsz_config.input =
2843                                 &dev->config.isp_config.output;
2844
2845                 rsz_input = dev->config.sp_config.rsz_config.input;
2846                 rsz_output = &dev->config.sp_config.rsz_config.output;
2847                 mi_output = &dev->config.mi_config.sp.output;
2848                 /* No phase offset */
2849                 cif_iowrite32(0, dev->config.base_addr + CIF_SRSZ_PHASE_HY);
2850                 cif_iowrite32(0, dev->config.base_addr + CIF_SRSZ_PHASE_HC);
2851                 cif_iowrite32(0, dev->config.base_addr + CIF_SRSZ_PHASE_VY);
2852                 cif_iowrite32(0, dev->config.base_addr + CIF_SRSZ_PHASE_VC);
2853                 /* Linear interpolation */
2854                 for (i = 0; i < 64; i++) {
2855                         cif_iowrite32(i,
2856                                 dev->config.base_addr +
2857                                         CIF_SRSZ_SCALE_LUT_ADDR);
2858                         cif_iowrite32(i,
2859                                 dev->config.base_addr +
2860                                         CIF_SRSZ_SCALE_LUT);
2861                 }
2862         }
2863
2864         /* set RSZ input and output */
2865         rsz_output->width = mi_output->width;
2866         rsz_output->height = mi_output->height;
2867         rsz_output->pix_fmt = rsz_input->pix_fmt;
2868         if (CIF_ISP10_PIX_FMT_IS_YUV(mi_output->pix_fmt)) {
2869                 cif_isp10_pix_fmt_set_y_subs(
2870                         rsz_output->pix_fmt,
2871                         CIF_ISP10_PIX_FMT_YUV_GET_Y_SUBS(mi_output->pix_fmt));
2872                 cif_isp10_pix_fmt_set_x_subs(
2873                         rsz_output->pix_fmt,
2874                         CIF_ISP10_PIX_FMT_YUV_GET_X_SUBS(mi_output->pix_fmt));
2875                 cif_isp10_pix_fmt_set_bpp(
2876                         rsz_output->pix_fmt,
2877                         CIF_ISP10_PIX_FMT_GET_BPP(mi_output->pix_fmt));
2878         } else if (CIF_ISP10_PIX_FMT_IS_JPEG(mi_output->pix_fmt)) {
2879                 cif_isp10_pix_fmt_set_y_subs(
2880                         rsz_output->pix_fmt, 4);
2881                 cif_isp10_pix_fmt_set_x_subs(
2882                         rsz_output->pix_fmt, 2);
2883                 cif_isp10_pix_fmt_set_bpp(
2884                         rsz_output->pix_fmt, 16);
2885         }
2886
2887         cif_isp10_pltfrm_pr_dbg(dev->dev,
2888                 "%s %s %dx%d -> %s %dx%d\n",
2889                 cif_isp10_stream_id_string(stream_id),
2890                 cif_isp10_pix_fmt_string(rsz_input->pix_fmt),
2891                 rsz_input->width,
2892                 rsz_input->height,
2893                 cif_isp10_pix_fmt_string(rsz_output->pix_fmt),
2894                 rsz_output->width,
2895                 rsz_output->height);
2896
2897         /* set input and output sizes for scale calculation */
2898         input_width_y = rsz_input->width;
2899         output_width_y = rsz_output->width;
2900         input_height_y = rsz_input->height;
2901         output_height_y = rsz_output->height;
2902         input_width_c = input_width_y;
2903         output_width_c = output_width_y;
2904         input_height_c = input_height_y;
2905         output_height_c = output_height_y;
2906
2907         if (CIF_ISP10_PIX_FMT_IS_YUV(rsz_output->pix_fmt)) {
2908                 input_width_c = (input_width_c *
2909                         CIF_ISP10_PIX_FMT_YUV_GET_X_SUBS(
2910                                 rsz_input->pix_fmt)) / 4;
2911                 input_height_c = (input_height_c *
2912                         CIF_ISP10_PIX_FMT_YUV_GET_Y_SUBS(
2913                                 rsz_input->pix_fmt)) / 4;
2914                 output_width_c = (output_width_c *
2915                         CIF_ISP10_PIX_FMT_YUV_GET_X_SUBS(
2916                                 rsz_output->pix_fmt)) / 4;
2917                 output_height_c = (output_height_c *
2918                         CIF_ISP10_PIX_FMT_YUV_GET_Y_SUBS(
2919                                 rsz_output->pix_fmt)) / 4;
2920
2921                 cif_isp10_pltfrm_pr_dbg(NULL,
2922                         "chroma scaling %dx%d -> %dx%d\n",
2923                         input_width_c, input_height_c,
2924                         output_width_c, output_height_c);
2925
2926                 if (((input_width_c == 0) && (output_width_c > 0)) ||
2927                         ((input_height_c == 0) && (output_height_c > 0))) {
2928                         cif_isp10_pltfrm_pr_err(NULL,
2929                                 "input is black and white, cannot output colour\n");
2930                         ret = -EINVAL;
2931                         goto err;
2932                 }
2933         } else {
2934                 if ((input_width_y != output_width_y) ||
2935                         (input_height_y != output_height_y)) {
2936                         cif_isp10_pltfrm_pr_err(NULL,
2937                                 "%dx%d -> %dx%d isn't support, can only scale YUV input\n",
2938                                 input_width_y, input_height_y,
2939                                 output_width_y, output_height_y);
2940                         ret = -EINVAL;
2941                         goto err;
2942                 }
2943         }
2944
2945         /* calculate and set scale */
2946         rsz_ctrl = 0;
2947         if (input_width_y < output_width_y) {
2948                 rsz_ctrl |= CIF_RSZ_CTRL_SCALE_HY_ENABLE |
2949                         CIF_RSZ_CTRL_SCALE_HY_UP;
2950                 cif_iowrite32(
2951                         DIV_TRUNCATE((input_width_y - 1)
2952                         * CIF_RSZ_SCALER_BYPASS,
2953                         output_width_y - 1),
2954                         scale_h_y_addr);
2955         } else if (input_width_y > output_width_y) {
2956                 rsz_ctrl |= CIF_RSZ_CTRL_SCALE_HY_ENABLE;
2957                 cif_iowrite32(
2958                         DIV_TRUNCATE((output_width_y - 1)
2959                         * CIF_RSZ_SCALER_BYPASS,
2960                         input_width_y - 1) + 1,
2961                         scale_h_y_addr);
2962         }
2963         if (input_width_c < output_width_c) {
2964                 rsz_ctrl |= CIF_RSZ_CTRL_SCALE_HC_ENABLE |
2965                         CIF_RSZ_CTRL_SCALE_HC_UP;
2966                 scale_h_c = DIV_TRUNCATE((input_width_c - 1)
2967                 * CIF_RSZ_SCALER_BYPASS,
2968                 output_width_c - 1);
2969                 cif_iowrite32(scale_h_c, scale_h_cb_addr);
2970                 cif_iowrite32(scale_h_c, scale_h_cr_addr);
2971         } else if (input_width_c > output_width_c) {
2972                 rsz_ctrl |= CIF_RSZ_CTRL_SCALE_HC_ENABLE;
2973                 scale_h_c = DIV_TRUNCATE((output_width_c - 1)
2974                 * CIF_RSZ_SCALER_BYPASS,
2975                 input_width_c - 1) + 1;
2976                 cif_iowrite32(scale_h_c, scale_h_cb_addr);
2977                 cif_iowrite32(scale_h_c, scale_h_cr_addr);
2978         }
2979
2980         if (input_height_y < output_height_y) {
2981                 rsz_ctrl |= CIF_RSZ_CTRL_SCALE_VY_ENABLE |
2982                         CIF_RSZ_CTRL_SCALE_VY_UP;
2983                 cif_iowrite32(
2984                         DIV_TRUNCATE((input_height_y - 1)
2985                         * CIF_RSZ_SCALER_BYPASS,
2986                         output_height_y - 1),
2987                         scale_v_y_addr);
2988         } else if (input_height_y > output_height_y) {
2989                 rsz_ctrl |= CIF_RSZ_CTRL_SCALE_VY_ENABLE;
2990                 cif_iowrite32(
2991                         DIV_TRUNCATE((output_height_y - 1)
2992                         * CIF_RSZ_SCALER_BYPASS,
2993                         input_height_y - 1) + 1,
2994                         scale_v_y_addr);
2995         }
2996
2997         if (input_height_c < output_height_c) {
2998                 rsz_ctrl |= CIF_RSZ_CTRL_SCALE_VC_ENABLE |
2999                         CIF_RSZ_CTRL_SCALE_VC_UP;
3000                 cif_iowrite32(
3001                         DIV_TRUNCATE((input_height_c - 1)
3002                         * CIF_RSZ_SCALER_BYPASS,
3003                         output_height_c - 1),
3004                         scale_v_c_addr);
3005         } else if (input_height_c > output_height_c) {
3006                 rsz_ctrl |= CIF_RSZ_CTRL_SCALE_VC_ENABLE;
3007                 cif_iowrite32(
3008                         DIV_TRUNCATE((output_height_c - 1)
3009                         * CIF_RSZ_SCALER_BYPASS,
3010                         input_height_c - 1) + 1,
3011                         scale_v_c_addr);
3012         }
3013
3014         cif_iowrite32(rsz_ctrl, rsz_ctrl_addr);
3015
3016         if (stream_id == CIF_ISP10_STREAM_MP) {
3017                 if (async)
3018                         cif_iowrite32OR(CIF_RSZ_CTRL_CFG_UPD,
3019                                 dev->config.base_addr + CIF_MRSZ_CTRL);
3020                 dev->config.mp_config.rsz_config.ycflt_adjust = false;
3021                 dev->config.mp_config.rsz_config.ism_adjust = false;
3022                 cif_isp10_pltfrm_pr_dbg(dev->dev,
3023                         "\n  MRSZ_CTRL 0x%08x/0x%08x\n"
3024                         "  MRSZ_SCALE_HY %d/%d\n"
3025                         "  MRSZ_SCALE_HCB %d/%d\n"
3026                         "  MRSZ_SCALE_HCR %d/%d\n"
3027                         "  MRSZ_SCALE_VY %d/%d\n"
3028                         "  MRSZ_SCALE_VC %d/%d\n"
3029                         "  MRSZ_PHASE_HY %d/%d\n"
3030                         "  MRSZ_PHASE_HC %d/%d\n"
3031                         "  MRSZ_PHASE_VY %d/%d\n"
3032                         "  MRSZ_PHASE_VC %d/%d\n",
3033                         cif_ioread32(dev->config.base_addr +
3034                                 CIF_MRSZ_CTRL),
3035                         cif_ioread32(dev->config.base_addr +
3036                                 CIF_MRSZ_CTRL_SHD),
3037                         cif_ioread32(dev->config.base_addr +
3038                                 CIF_MRSZ_SCALE_HY),
3039                         cif_ioread32(dev->config.base_addr +
3040                                 CIF_MRSZ_SCALE_HY_SHD),
3041                         cif_ioread32(dev->config.base_addr +
3042                                 CIF_MRSZ_SCALE_HCB),
3043                         cif_ioread32(dev->config.base_addr +
3044                                 CIF_MRSZ_SCALE_HCB_SHD),
3045                         cif_ioread32(dev->config.base_addr +
3046                                 CIF_MRSZ_SCALE_HCR),
3047                         cif_ioread32(dev->config.base_addr +
3048                                 CIF_MRSZ_SCALE_HCR_SHD),
3049                         cif_ioread32(dev->config.base_addr +
3050                                 CIF_MRSZ_SCALE_VY),
3051                         cif_ioread32(dev->config.base_addr +
3052                                 CIF_MRSZ_SCALE_VY_SHD),
3053                         cif_ioread32(dev->config.base_addr +
3054                                 CIF_MRSZ_SCALE_VC),
3055                         cif_ioread32(dev->config.base_addr +
3056                                 CIF_MRSZ_SCALE_VC_SHD),
3057                         cif_ioread32(dev->config.base_addr +
3058                                 CIF_MRSZ_PHASE_HY),
3059                         cif_ioread32(dev->config.base_addr +
3060                                 CIF_MRSZ_PHASE_HY_SHD),
3061                         cif_ioread32(dev->config.base_addr +
3062                                 CIF_MRSZ_PHASE_HC),
3063                         cif_ioread32(dev->config.base_addr +
3064                                 CIF_MRSZ_PHASE_HC_SHD),
3065                         cif_ioread32(dev->config.base_addr +
3066                                 CIF_MRSZ_PHASE_VY),
3067                         cif_ioread32(dev->config.base_addr +
3068                                 CIF_MRSZ_PHASE_VY_SHD),
3069                         cif_ioread32(dev->config.base_addr +
3070                                 CIF_MRSZ_PHASE_VC),
3071                         cif_ioread32(dev->config.base_addr +
3072                                 CIF_MRSZ_PHASE_VC_SHD));
3073         } else {
3074                 if (async)
3075                         cif_iowrite32OR(CIF_RSZ_CTRL_CFG_UPD,
3076                                 dev->config.base_addr + CIF_SRSZ_CTRL);
3077                 dev->config.sp_config.rsz_config.ycflt_adjust = false;
3078                 dev->config.sp_config.rsz_config.ism_adjust = false;
3079                 cif_isp10_pltfrm_pr_dbg(dev->dev,
3080                         "\n  SRSZ_CTRL 0x%08x/0x%08x\n"
3081                         "  SRSZ_SCALE_HY %d/%d\n"
3082                         "  SRSZ_SCALE_HCB %d/%d\n"
3083                         "  SRSZ_SCALE_HCR %d/%d\n"
3084                         "  SRSZ_SCALE_VY %d/%d\n"
3085                         "  SRSZ_SCALE_VC %d/%d\n"
3086                         "  SRSZ_PHASE_HY %d/%d\n"
3087                         "  SRSZ_PHASE_HC %d/%d\n"
3088                         "  SRSZ_PHASE_VY %d/%d\n"
3089                         "  SRSZ_PHASE_VC %d/%d\n",
3090                         cif_ioread32(dev->config.base_addr +
3091                                 CIF_SRSZ_CTRL),
3092                         cif_ioread32(dev->config.base_addr +
3093                                 CIF_SRSZ_CTRL_SHD),
3094                         cif_ioread32(dev->config.base_addr +
3095                                 CIF_SRSZ_SCALE_HY),
3096                         cif_ioread32(dev->config.base_addr +
3097                                 CIF_SRSZ_SCALE_HY_SHD),
3098                         cif_ioread32(dev->config.base_addr +
3099                                 CIF_SRSZ_SCALE_HCB),
3100                         cif_ioread32(dev->config.base_addr +
3101                                 CIF_SRSZ_SCALE_HCB_SHD),
3102                         cif_ioread32(dev->config.base_addr +
3103                                 CIF_SRSZ_SCALE_HCR),
3104                         cif_ioread32(dev->config.base_addr +
3105                                 CIF_SRSZ_SCALE_HCR_SHD),
3106                         cif_ioread32(dev->config.base_addr +
3107                                 CIF_SRSZ_SCALE_VY),
3108                         cif_ioread32(dev->config.base_addr +
3109                                 CIF_SRSZ_SCALE_VY_SHD),
3110                         cif_ioread32(dev->config.base_addr +
3111                                 CIF_SRSZ_SCALE_VC),
3112                         cif_ioread32(dev->config.base_addr +
3113                                 CIF_SRSZ_SCALE_VC_SHD),
3114                         cif_ioread32(dev->config.base_addr +
3115                                 CIF_SRSZ_PHASE_HY),
3116                         cif_ioread32(dev->config.base_addr +
3117                                 CIF_SRSZ_PHASE_HY_SHD),
3118                         cif_ioread32(dev->config.base_addr +
3119                                 CIF_SRSZ_PHASE_HC),
3120                         cif_ioread32(dev->config.base_addr +
3121                                 CIF_SRSZ_PHASE_HC_SHD),
3122                         cif_ioread32(dev->config.base_addr +
3123                                 CIF_SRSZ_PHASE_VY),
3124                         cif_ioread32(dev->config.base_addr +
3125                                 CIF_SRSZ_PHASE_VY_SHD),
3126                         cif_ioread32(dev->config.base_addr +
3127                                 CIF_SRSZ_PHASE_VC),
3128                         cif_ioread32(dev->config.base_addr +
3129                                 CIF_SRSZ_PHASE_VC_SHD));
3130         }
3131
3132         return 0;
3133 err:
3134         cif_isp10_pltfrm_pr_err(dev->dev,
3135                 "failed with err %d\n", ret);
3136         return ret;
3137 }
3138
3139 static int cif_isp10_config_sp(
3140         struct cif_isp10_device *dev)
3141 {
3142         int ret = 0;
3143
3144         cif_isp10_pltfrm_pr_dbg(NULL, "\n");
3145
3146         ret = cif_isp10_config_rsz(dev, CIF_ISP10_STREAM_SP, true);
3147         if (IS_ERR_VALUE(ret))
3148                 goto err;
3149
3150         ret = cif_isp10_config_dcrop(dev, CIF_ISP10_STREAM_SP, true);
3151         if (IS_ERR_VALUE(ret))
3152                 goto err;
3153
3154         ret = cif_isp10_config_mi_sp(dev);
3155         if (IS_ERR_VALUE(ret))
3156                 goto err;
3157
3158         dev->sp_stream.updt_cfg = false;
3159
3160         return 0;
3161 err:
3162         cif_isp10_pltfrm_pr_err(dev->dev,
3163                 "failed with error %d\n", ret);
3164         return ret;
3165 }
3166
3167 static int cif_isp10_config_mp(
3168         struct cif_isp10_device *dev)
3169 {
3170         int ret = 0;
3171
3172         cif_isp10_pltfrm_pr_dbg(NULL, "\n");
3173
3174         ret = cif_isp10_config_rsz(dev, CIF_ISP10_STREAM_MP, true);
3175         if (IS_ERR_VALUE(ret))
3176                 goto err;
3177
3178         ret = cif_isp10_config_dcrop(dev, CIF_ISP10_STREAM_MP, true);
3179         if (IS_ERR_VALUE(ret))
3180                 goto err;
3181
3182         ret = cif_isp10_config_mi_mp(dev);
3183         if (IS_ERR_VALUE(ret))
3184                 goto err;
3185         if (dev->config.jpeg_config.enable) {
3186                 ret = cif_isp10_config_jpeg_enc(dev);
3187                 if (IS_ERR_VALUE(ret))
3188                         goto err;
3189                 dev->config.jpeg_config.busy = false;
3190         }
3191
3192         dev->mp_stream.updt_cfg = false;
3193
3194         return 0;
3195 err:
3196         cif_isp10_pltfrm_pr_err(dev->dev,
3197                 "failed with error %d\n", ret);
3198         return ret;
3199 }
3200
3201 static void cif_isp10_config_clk(
3202         struct cif_isp10_device *dev)
3203 {
3204         cif_iowrite32(CIF_CCL_CIF_CLK_ENA,
3205                 dev->config.base_addr + CIF_CCL);
3206         cif_iowrite32(0x0000187B, dev->config.base_addr + CIF_ICCL);
3207
3208         cif_isp10_pltfrm_pr_dbg(dev->dev,
3209                 "\n  CIF_CCL 0x%08x\n"
3210                 "  CIF_ICCL 0x%08x\n",
3211                 cif_ioread32(dev->config.base_addr + CIF_CCL),
3212                 cif_ioread32(dev->config.base_addr + CIF_ICCL));
3213 }
3214
3215 static int cif_isp10_config_cif(
3216         struct cif_isp10_device *dev,
3217         u32 stream_ids)
3218 {
3219         int ret = 0;
3220         u32 cif_id;
3221
3222         cif_isp10_pltfrm_pr_dbg(dev->dev,
3223                 "config MP = %d, config SP = %d, img_src state = %s, PM state = %s, SP state = %s, MP state = %s\n",
3224                 (stream_ids & CIF_ISP10_STREAM_MP) == CIF_ISP10_STREAM_MP,
3225                 (stream_ids & CIF_ISP10_STREAM_SP) == CIF_ISP10_STREAM_SP,
3226                 cif_isp10_img_src_state_string(dev->img_src_state),
3227                 cif_isp10_pm_state_string(dev->pm_state),
3228                 cif_isp10_state_string(dev->sp_stream.state),
3229                 cif_isp10_state_string(dev->mp_stream.state));
3230
3231         cif_isp10_pltfrm_rtrace_printf(NULL,
3232                 "start configuring CIF...\n");
3233
3234         if ((stream_ids & CIF_ISP10_STREAM_MP) ||
3235                 (stream_ids & CIF_ISP10_STREAM_SP)) {
3236                 ret = cif_isp10_set_pm_state(dev,
3237                         CIF_ISP10_PM_STATE_SW_STNDBY);
3238                 if (IS_ERR_VALUE(ret))
3239                         goto err;
3240
3241                 if (!CIF_ISP10_INP_IS_DMA(dev->config.input_sel)) {
3242                         /* configure sensor */
3243                         ret = cif_isp10_config_img_src(dev);
3244                         if (IS_ERR_VALUE(ret))
3245                                 goto err;
3246                 }
3247
3248                 cif_id = cif_ioread32(dev->config.base_addr + CIF_VI_ID);
3249                 dev->config.out_of_buffer_stall =
3250                                 CIF_ISP10_ALWAYS_STALL_ON_NO_BUFS;
3251
3252                 cif_isp10_pltfrm_pr_dbg(dev->dev,
3253                         "CIF_ID 0x%08x\n", cif_id);
3254
3255                 /*
3256                  * Cancel isp reset internal here temporary for
3257                  * isp bus may be dead when switch isp.
3258                  */
3259                 /*
3260                  * cif_iowrite32(CIF_IRCL_CIF_SW_RST,
3261                  * dev->config.base_addr + CIF_IRCL);
3262                  */
3263
3264                 cif_isp10_config_clk(dev);
3265
3266                 /* Decide when to switch to asynchronous mode */
3267                 /*
3268                  * TODO: remove dev->isp_dev.ycflt_en check for
3269                  * HW with the scaler fix.
3270                  */
3271                 dev->config.mi_config.async_updt = CIF_ISP10_ALWAYS_ASYNC;
3272                 if (CIF_ISP10_INP_IS_DMA(dev->config.input_sel)) {
3273                         dev->config.mi_config.async_updt |= CIF_ISP10_ASYNC_DMA;
3274                         ret = cif_isp10_config_mi_dma(dev);
3275                         if (IS_ERR_VALUE(ret))
3276                                 goto err;
3277                 }
3278                 if ((stream_ids & CIF_ISP10_STREAM_MP) &&
3279                         (dev->config.jpeg_config.enable))
3280                         dev->config.mi_config.async_updt |=
3281                                 CIF_ISP10_ASYNC_JPEG;
3282                 if (dev->config.isp_config.ism_config.ism_en)
3283                         dev->config.mi_config.async_updt |=
3284                                 CIF_ISP10_ASYNC_ISM;
3285
3286                 if (PLTFRM_CAM_ITF_IS_MIPI(dev->config.cam_itf.type)) {
3287                         ret = cif_isp10_config_mipi(dev);
3288                         if (IS_ERR_VALUE(ret))
3289                                 goto err;
3290                 }
3291
3292                 ret = cif_isp10_config_isp(dev);
3293                 if (IS_ERR_VALUE(ret))
3294                         goto err;
3295
3296                 cif_isp10_config_ism(dev, true);
3297                 dev->config.isp_config.ism_config.ism_update_needed = false;
3298
3299                 if (stream_ids & CIF_ISP10_STREAM_SP)
3300                         dev->config.sp_config.rsz_config.ism_adjust = true;
3301                 if (stream_ids & CIF_ISP10_STREAM_MP)
3302                         dev->config.mp_config.rsz_config.ism_adjust = true;
3303
3304                 if (stream_ids & CIF_ISP10_STREAM_SP) {
3305                         ret = cif_isp10_config_sp(dev);
3306                         if (IS_ERR_VALUE(ret))
3307                                 goto err;
3308                 }
3309
3310                 if (stream_ids & CIF_ISP10_STREAM_MP) {
3311                         ret = cif_isp10_config_mp(dev);
3312                         if (IS_ERR_VALUE(ret))
3313                                 goto err;
3314                 }
3315                 ret = cif_isp10_config_path(dev, stream_ids);
3316                 if (IS_ERR_VALUE(ret))
3317                         goto err;
3318         }
3319
3320         /* Turn off XNR vertical subsampling when ism cropping is enabled */
3321         if (dev->config.isp_config.ism_config.ism_en) {
3322                 if (!dev->isp_dev.cif_ism_cropping)
3323                         dev->isp_dev.cif_ism_cropping = true;
3324         } else {
3325                 if (dev->isp_dev.cif_ism_cropping)
3326                         dev->isp_dev.cif_ism_cropping = false;
3327         }
3328
3329         if (dev->config.sp_config.rsz_config.ycflt_adjust ||
3330                 dev->config.sp_config.rsz_config.ism_adjust) {
3331                 if (dev->sp_stream.state == CIF_ISP10_STATE_READY) {
3332                         ret = cif_isp10_config_rsz(dev,
3333                                 CIF_ISP10_STREAM_SP, true);
3334                         if (IS_ERR_VALUE(ret))
3335                                 goto err;
3336                 } else {
3337                         /* Disable SRSZ if SP is not used */
3338                         cif_iowrite32(0, dev->config.base_addr + CIF_SRSZ_CTRL);
3339                         cif_iowrite32OR(CIF_RSZ_CTRL_CFG_UPD,
3340                                 dev->config.base_addr + CIF_SRSZ_CTRL);
3341                         dev->config.sp_config.rsz_config.ycflt_adjust = false;
3342                         dev->config.sp_config.rsz_config.ism_adjust = false;
3343                 }
3344         }
3345
3346         if (dev->config.mp_config.rsz_config.ycflt_adjust ||
3347                 dev->config.mp_config.rsz_config.ism_adjust) {
3348                 if (dev->mp_stream.state == CIF_ISP10_STATE_READY) {
3349                         ret = cif_isp10_config_rsz(dev,
3350                                 CIF_ISP10_STREAM_MP, true);
3351                         if (IS_ERR_VALUE(ret))
3352                                 goto err;
3353                 } else {
3354                         /* Disable MRSZ if MP is not used */
3355                         cif_iowrite32(0, dev->config.base_addr + CIF_MRSZ_CTRL);
3356                         cif_iowrite32OR(CIF_RSZ_CTRL_CFG_UPD,
3357                                 dev->config.base_addr + CIF_MRSZ_CTRL);
3358                         dev->config.mp_config.rsz_config.ycflt_adjust = false;
3359                         dev->config.mp_config.rsz_config.ism_adjust = false;
3360                 }
3361         }
3362
3363         if (dev->config.mi_config.async_updt)
3364                 cif_isp10_pltfrm_pr_dbg(dev->dev,
3365                         "CIF in asynchronous mode (0x%08x)\n",
3366                         dev->config.mi_config.async_updt);
3367
3368         return 0;
3369 err:
3370         cif_isp10_pltfrm_pr_err(dev->dev,
3371                 "failed with error %d\n", ret);
3372         return ret;
3373 }
3374
3375 static void cif_isp10_init_stream(
3376         struct cif_isp10_device *dev,
3377         enum cif_isp10_stream_id stream_id)
3378 {
3379         struct cif_isp10_stream *stream = NULL;
3380
3381         switch (stream_id) {
3382         case CIF_ISP10_STREAM_SP:
3383                 stream = &dev->sp_stream;
3384                 dev->config.sp_config.rsz_config.ycflt_adjust = false;
3385                 dev->config.sp_config.rsz_config.ism_adjust = false;
3386                 dev->config.mi_config.sp.busy = false;
3387                 break;
3388         case CIF_ISP10_STREAM_MP:
3389                 stream = &dev->mp_stream;
3390                 dev->config.jpeg_config.ratio = 50;
3391                 dev->config.jpeg_config.header =
3392                         CIF_ISP10_JPEG_HEADER_JFIF;
3393                 dev->config.jpeg_config.enable = false;
3394                 dev->config.mi_config.raw_enable = false;
3395                 dev->config.mp_config.rsz_config.ycflt_adjust = false;
3396                 dev->config.mp_config.rsz_config.ism_adjust = false;
3397                 dev->config.mi_config.mp.busy = false;
3398                 break;
3399         case CIF_ISP10_STREAM_DMA:
3400                 stream = &dev->dma_stream;
3401                 dev->config.mi_config.dma.busy = false;
3402                 break;
3403         default:
3404                 cif_isp10_pltfrm_pr_err(NULL,
3405                         "unknown/unsupported stream ID %d\n", stream_id);
3406                 WARN_ON(1);
3407                 break;
3408         }
3409
3410         INIT_LIST_HEAD(&stream->buf_queue);
3411         stream->next_buf = NULL;
3412         stream->curr_buf = NULL;
3413         stream->updt_cfg = false;
3414         stream->stop = false;
3415         stream->stall = false;
3416
3417         cif_isp10_pltfrm_event_clear(dev->dev, &stream->done);
3418         stream->state = CIF_ISP10_STATE_INACTIVE;
3419 }
3420
3421 static int cif_isp10_jpeg_gen_header(
3422         struct cif_isp10_device *dev)
3423 {
3424         unsigned int timeout = 10000;
3425
3426         cif_isp10_pltfrm_pr_dbg(NULL, "\n");
3427
3428         cif_iowrite32(CIF_JPE_GEN_HEADER_ENABLE,
3429                 dev->config.base_addr + CIF_JPE_GEN_HEADER);
3430
3431         while (timeout--) {
3432                 if (cif_ioread32(dev->config.base_addr +
3433                         CIF_JPE_STATUS_RIS) &
3434                         CIF_JPE_STATUS_GENHEADER_DONE) {
3435                         cif_isp10_pltfrm_pr_dbg(NULL,
3436                                 "JPEG header generated\n");
3437                         cif_iowrite32(CIF_JPE_STATUS_GENHEADER_DONE,
3438                                 dev->config.base_addr + CIF_JPE_STATUS_ICR);
3439                         break;
3440                 }
3441         }
3442
3443         if (!timeout) {
3444                 cif_isp10_pltfrm_pr_err(NULL,
3445                         "JPEG header generation timeout\n");
3446                 cif_isp10_pltfrm_pr_err(NULL,
3447                         "failed with error %d\n", -ETIMEDOUT);
3448                 return -ETIMEDOUT;
3449         }
3450
3451 #ifdef CIF_ISP10_VERIFY_JPEG_HEADER
3452         {
3453                 u32 *buff = (u32 *)phys_to_virt(
3454                         dev->config.mi_config.mp.curr_buff_addr);
3455                 if (buff[0] != 0xe0ffd8ff)
3456                         cif_isp10_pltfrm_pr_err(NULL,
3457                                 "JPEG HEADER WRONG: 0x%08x\n"
3458                                 "curr_buff_addr 0x%08x\n"
3459                                 "MI_MP_Y_SIZE_SHD 0x%08x\n"
3460                                 "MI_MP_Y_BASE_AD_SHD 0x%08x\n",
3461                                 buff[0],
3462                                 dev->config.mi_config.mp.curr_buff_addr,
3463                                 cif_ioread32(dev->config.base_addr +
3464                                         CIF_MI_MP_Y_SIZE_SHD),
3465                                 cif_ioread32(dev->config.base_addr +
3466                                         CIF_MI_MP_Y_BASE_AD_SHD));
3467         }
3468 #endif
3469
3470         return 0;
3471 }
3472
3473 static void cif_isp10_mi_update_buff_addr(
3474         struct cif_isp10_device *dev,
3475         enum cif_isp10_stream_id strm_id)
3476 {
3477         if (strm_id == CIF_ISP10_STREAM_SP) {
3478                 cif_iowrite32_verify(dev->config.mi_config.sp.next_buff_addr,
3479                         dev->config.base_addr +
3480                         CIF_MI_SP_Y_BASE_AD_INIT, CIF_MI_ADDR_SIZE_ALIGN_MASK);
3481                 cif_iowrite32_verify(dev->config.mi_config.sp.next_buff_addr +
3482                         dev->config.mi_config.sp.cb_offs,
3483                         dev->config.base_addr +
3484                         CIF_MI_SP_CB_BASE_AD_INIT, CIF_MI_ADDR_SIZE_ALIGN_MASK);
3485                 cif_iowrite32_verify(dev->config.mi_config.sp.next_buff_addr +
3486                         dev->config.mi_config.sp.cr_offs,
3487                         dev->config.base_addr +
3488                         CIF_MI_SP_CR_BASE_AD_INIT, CIF_MI_ADDR_SIZE_ALIGN_MASK);
3489                 /*
3490                  * There have bee repeatedly issues with
3491                  * the offset registers, it is safer to write
3492                  * them each time, even though it is always
3493                  * 0 and even though that is the
3494                  * register's default value
3495                  */
3496                 cif_iowrite32_verify(0,
3497                         dev->config.base_addr +
3498                         CIF_MI_SP_Y_OFFS_CNT_INIT,
3499                         CIF_MI_ADDR_SIZE_ALIGN_MASK);
3500                 cif_iowrite32_verify(0,
3501                         dev->config.base_addr +
3502                         CIF_MI_SP_CB_OFFS_CNT_INIT,
3503                         CIF_MI_ADDR_SIZE_ALIGN_MASK);
3504                 cif_iowrite32_verify(0,
3505                         dev->config.base_addr +
3506                         CIF_MI_SP_CR_OFFS_CNT_INIT,
3507                         CIF_MI_ADDR_SIZE_ALIGN_MASK);
3508                 cif_isp10_pltfrm_pr_dbg(dev->dev,
3509                         "\n  MI_SP_Y_BASE_AD 0x%08x/0x%08x\n"
3510                         "  MI_SP_CB_BASE_AD 0x%08x/0x%08x\n"
3511                         "  MI_SP_CR_BASE_AD 0x%08x/0x%08x\n",
3512                         cif_ioread32(dev->config.base_addr +
3513                                 CIF_MI_SP_Y_BASE_AD_INIT),
3514                         cif_ioread32(dev->config.base_addr +
3515                                 CIF_MI_SP_Y_BASE_AD_SHD),
3516                         cif_ioread32(dev->config.base_addr +
3517                                 CIF_MI_SP_CB_BASE_AD_INIT),
3518                         cif_ioread32(dev->config.base_addr +
3519                                 CIF_MI_SP_CB_BASE_AD_SHD),
3520                         cif_ioread32(dev->config.base_addr +
3521                                 CIF_MI_SP_CR_BASE_AD_INIT),
3522                         cif_ioread32(dev->config.base_addr +
3523                                 CIF_MI_SP_CR_BASE_AD_SHD));
3524         } else if (strm_id == CIF_ISP10_STREAM_MP) {
3525                 cif_iowrite32_verify(dev->config.mi_config.mp.next_buff_addr,
3526                         dev->config.base_addr +
3527                         CIF_MI_MP_Y_BASE_AD_INIT, CIF_MI_ADDR_SIZE_ALIGN_MASK);
3528                 cif_iowrite32_verify(dev->config.mi_config.mp.next_buff_addr +
3529                         dev->config.mi_config.mp.cb_offs,
3530                         dev->config.base_addr +
3531                         CIF_MI_MP_CB_BASE_AD_INIT, CIF_MI_ADDR_SIZE_ALIGN_MASK);
3532                 cif_iowrite32_verify(dev->config.mi_config.mp.next_buff_addr +
3533                         dev->config.mi_config.mp.cr_offs,
3534                         dev->config.base_addr +
3535                         CIF_MI_MP_CR_BASE_AD_INIT, CIF_MI_ADDR_SIZE_ALIGN_MASK);
3536                 /*
3537                  * There have bee repeatedly issues with
3538                  * the offset registers, it is safer to write
3539                  * them each time, even though it is always
3540                  * 0 and even though that is the
3541                  * register's default value
3542                  */
3543                 cif_iowrite32_verify(0,
3544                         dev->config.base_addr +
3545                         CIF_MI_MP_Y_OFFS_CNT_INIT, CIF_MI_ADDR_SIZE_ALIGN_MASK);
3546                 cif_iowrite32_verify(0,
3547                         dev->config.base_addr +
3548                         CIF_MI_MP_CB_OFFS_CNT_INIT,
3549                         CIF_MI_ADDR_SIZE_ALIGN_MASK);
3550                 cif_iowrite32_verify(0,
3551                         dev->config.base_addr +
3552                         CIF_MI_MP_CR_OFFS_CNT_INIT,
3553                         CIF_MI_ADDR_SIZE_ALIGN_MASK);
3554                 cif_isp10_pltfrm_pr_dbg(dev->dev,
3555                         "\n  MI_MP_Y_BASE_AD 0x%08x/0x%08x\n"
3556                         "  MI_MP_CB_BASE_AD 0x%08x/0x%08x\n"
3557                         "  MI_MP_CR_BASE_AD 0x%08x/0x%08x\n",
3558                         cif_ioread32(dev->config.base_addr +
3559                                 CIF_MI_MP_Y_BASE_AD_INIT),
3560                         cif_ioread32(dev->config.base_addr +
3561                                 CIF_MI_MP_Y_BASE_AD_SHD),
3562                         cif_ioread32(dev->config.base_addr +
3563                                 CIF_MI_MP_CB_BASE_AD_INIT),
3564                         cif_ioread32(dev->config.base_addr +
3565                                 CIF_MI_MP_CB_BASE_AD_SHD),
3566                         cif_ioread32(dev->config.base_addr +
3567                                 CIF_MI_MP_CR_BASE_AD_INIT),
3568                         cif_ioread32(dev->config.base_addr +
3569                                 CIF_MI_MP_CR_BASE_AD_SHD));
3570         } else { /* DMA */
3571                 cif_iowrite32_verify(dev->config.mi_config.dma.next_buff_addr,
3572                         dev->config.base_addr +
3573                         CIF_MI_DMA_Y_PIC_START_AD, CIF_MI_ADDR_SIZE_ALIGN_MASK);
3574                 cif_iowrite32_verify(dev->config.mi_config.dma.next_buff_addr +
3575                         dev->config.mi_config.dma.cb_offs,
3576                         dev->config.base_addr +
3577                         CIF_MI_DMA_CB_PIC_START_AD,
3578                         CIF_MI_ADDR_SIZE_ALIGN_MASK);
3579                 cif_iowrite32_verify(dev->config.mi_config.dma.next_buff_addr +
3580                         dev->config.mi_config.dma.cr_offs,
3581                         dev->config.base_addr +
3582                         CIF_MI_DMA_CR_PIC_START_AD,
3583                         CIF_MI_ADDR_SIZE_ALIGN_MASK);
3584                 cif_isp10_pltfrm_pr_dbg(dev->dev,
3585                         "\n  MI_DMA_Y_PIC_START_AD 0x%08x\n"
3586                         "  MI_DMA_CB_PIC_START_AD 0x%08x\n"
3587                         "  MI_DMA_CR_PIC_START_AD 0x%08x\n",
3588                         cif_ioread32(dev->config.base_addr +
3589                                 CIF_MI_DMA_Y_PIC_START_AD),
3590                         cif_ioread32(dev->config.base_addr +
3591                                 CIF_MI_DMA_CB_PIC_START_AD),
3592                         cif_ioread32(dev->config.base_addr +
3593                                 CIF_MI_DMA_CR_PIC_START_AD));
3594         }
3595 }
3596
3597 static int cif_isp10_update_mi_mp(
3598         struct cif_isp10_device *dev)
3599 {
3600         int ret = 0;
3601         enum cif_isp10_pix_fmt out_pix_fmt =
3602                 dev->config.mi_config.mp.output.pix_fmt;
3603
3604         cif_isp10_pltfrm_pr_dbg(NULL,
3605                 "curr 0x%08x next 0x%08x\n",
3606                 dev->config.mi_config.mp.curr_buff_addr,
3607                 dev->config.mi_config.mp.next_buff_addr);
3608
3609         if (dev->config.jpeg_config.enable) {
3610                 /*
3611                  * in case of jpeg encoding, we don't have to disable the
3612                  * MI, because the encoding
3613                  * anyway has to be started explicitly
3614                  */
3615                 if (!dev->config.jpeg_config.busy) {
3616                         if ((dev->config.mi_config.mp.curr_buff_addr !=
3617                                 dev->config.mi_config.mp.next_buff_addr) &&
3618                                 (dev->config.mi_config.mp.curr_buff_addr !=
3619                                 CIF_ISP10_INVALID_BUFF_ADDR)) {
3620                                 ret = cif_isp10_jpeg_gen_header(dev);
3621                                 if (IS_ERR_VALUE(ret))
3622                                         goto err;
3623                                 cif_isp10_pltfrm_pr_dbg(NULL,
3624                                         "Starting JPEG encoding\n");
3625                                 cif_isp10_pltfrm_rtrace_printf(dev->dev,
3626                                         "Starting JPEG encoding\n");
3627                                 cif_iowrite32(CIF_JPE_ENCODE_ENABLE,
3628                                         dev->config.base_addr + CIF_JPE_ENCODE);
3629                                 cif_iowrite32(CIF_JPE_INIT_ENABLE,
3630                                         dev->config.base_addr +
3631                                         CIF_JPE_INIT);
3632                                 dev->config.jpeg_config.busy = true;
3633                         }
3634                         if (dev->config.mi_config.mp.next_buff_addr !=
3635                                 CIF_ISP10_INVALID_BUFF_ADDR)
3636                                 cif_isp10_mi_update_buff_addr(dev,
3637                                         CIF_ISP10_STREAM_MP);
3638                         dev->config.mi_config.mp.curr_buff_addr =
3639                                 dev->config.mi_config.mp.next_buff_addr;
3640                 }
3641         } else {
3642                 if (dev->config.mi_config.mp.next_buff_addr !=
3643                         dev->config.mi_config.mp.curr_buff_addr) {
3644                         if (dev->config.mi_config.mp.next_buff_addr ==
3645                                 CIF_ISP10_INVALID_BUFF_ADDR) {
3646                                 /* disable MI MP */
3647                                 cif_isp10_pltfrm_pr_dbg(NULL,
3648                                         "disabling MP MI\n");
3649                                 cif_iowrite32AND_verify(
3650                                     ~(CIF_MI_CTRL_MP_ENABLE_IN |
3651                                         CIF_MI_CTRL_JPEG_ENABLE |
3652                                         CIF_MI_CTRL_RAW_ENABLE),
3653                                         dev->config.base_addr + CIF_MI_CTRL,
3654                                         ~0);
3655                         } else if (dev->config.mi_config.mp.curr_buff_addr ==
3656                                 CIF_ISP10_INVALID_BUFF_ADDR) {
3657                                 /* re-enable MI MP */
3658                                 cif_isp10_pltfrm_pr_dbg(NULL,
3659                                         "enabling MP MI\n");
3660                                 cif_iowrite32(CIF_MI_MP_FRAME,
3661                                         dev->config.base_addr + CIF_MI_ICR);
3662                                 cif_iowrite32AND_verify(
3663                                             ~(CIF_MI_CTRL_MP_ENABLE_IN |
3664                                                 CIF_MI_CTRL_JPEG_ENABLE |
3665                                                 CIF_MI_CTRL_RAW_ENABLE),
3666                                                 dev->config.base_addr +
3667                                                 CIF_MI_CTRL, ~0);
3668                                 if (CIF_ISP10_PIX_FMT_IS_RAW_BAYER
3669                                         (out_pix_fmt)) {
3670                                         cif_iowrite32OR_verify(
3671                                                 CIF_MI_CTRL_RAW_ENABLE,
3672                                                 dev->config.base_addr +
3673                                                 CIF_MI_CTRL,
3674                                                 ~0);
3675                                 } else if (CIF_ISP10_PIX_FMT_IS_YUV
3676                                         (out_pix_fmt)) {
3677                                         cif_iowrite32OR_verify(
3678                                                 CIF_MI_CTRL_MP_ENABLE_IN,
3679                                                 dev->config.base_addr +
3680                                                 CIF_MI_CTRL, ~0);
3681                                 }
3682                         }
3683                         cif_isp10_mi_update_buff_addr(dev, CIF_ISP10_STREAM_MP);
3684                         dev->config.mi_config.mp.curr_buff_addr =
3685                                 dev->config.mi_config.mp.next_buff_addr;
3686                 }
3687         }
3688
3689         return 0;
3690 err:
3691         cif_isp10_pltfrm_pr_err(dev->dev,
3692                 "failed with err %d\n", ret);
3693         return ret;
3694 }
3695
3696 static int cif_isp10_update_mi_sp(
3697         struct cif_isp10_device *dev)
3698 {
3699         cif_isp10_pltfrm_pr_dbg(NULL,
3700                 "curr 0x%08x next 0x%08x\n",
3701                 dev->config.mi_config.sp.curr_buff_addr,
3702                 dev->config.mi_config.sp.next_buff_addr);
3703
3704         if (dev->config.mi_config.sp.next_buff_addr !=
3705                 dev->config.mi_config.sp.curr_buff_addr) {
3706                 if (dev->config.mi_config.sp.next_buff_addr ==
3707                         CIF_ISP10_INVALID_BUFF_ADDR) {
3708                         /* disable MI SP */
3709                         cif_isp10_pltfrm_pr_dbg(NULL, "disabling SP MI\n");
3710                         /* 'switch off' MI interface */
3711                         cif_iowrite32AND_verify(~CIF_MI_CTRL_SP_ENABLE,
3712                                 dev->config.base_addr + CIF_MI_CTRL, ~0);
3713                 } else if (dev->config.mi_config.sp.curr_buff_addr ==
3714                         CIF_ISP10_INVALID_BUFF_ADDR) {
3715                         /* re-enable MI SP */
3716                         cif_isp10_pltfrm_pr_dbg(NULL, "enabling SP MI\n");
3717                         cif_iowrite32(CIF_MI_SP_FRAME,
3718                                 dev->config.base_addr + CIF_MI_ICR);
3719                         cif_iowrite32OR_verify(CIF_MI_CTRL_SP_ENABLE,
3720                                 dev->config.base_addr + CIF_MI_CTRL, ~0);
3721                 }
3722                 cif_isp10_mi_update_buff_addr(dev, CIF_ISP10_STREAM_SP);
3723                 dev->config.mi_config.sp.curr_buff_addr =
3724                         dev->config.mi_config.sp.next_buff_addr;
3725         }
3726
3727         return 0;
3728 }
3729
3730 static int cif_isp10_s_fmt_mp(
3731         struct cif_isp10_device *dev,
3732         struct cif_isp10_strm_fmt *strm_fmt,
3733         u32 stride)
3734 {
3735         int ret = 0;
3736
3737         cif_isp10_pltfrm_pr_dbg(dev->dev,
3738                 "%s %dx%d@%d/%dfps, stride = %d, quantization: %d\n",
3739                 cif_isp10_pix_fmt_string(strm_fmt->frm_fmt.pix_fmt),
3740                 strm_fmt->frm_fmt.width,
3741                 strm_fmt->frm_fmt.height,
3742                 strm_fmt->frm_intrvl.numerator,
3743                 strm_fmt->frm_intrvl.denominator,
3744                 stride,
3745                 strm_fmt->frm_fmt.quantization);
3746
3747         /* TBD: check whether format is a valid format for MP */
3748
3749         if (CIF_ISP10_PIX_FMT_IS_JPEG(strm_fmt->frm_fmt.pix_fmt)) {
3750                 dev->config.jpeg_config.enable = true;
3751         }       else if (CIF_ISP10_PIX_FMT_IS_RAW_BAYER
3752                 (strm_fmt->frm_fmt.pix_fmt)) {
3753                 if ((dev->sp_stream.state == CIF_ISP10_STATE_READY) ||
3754                         (dev->sp_stream.state == CIF_ISP10_STATE_STREAMING))
3755                         cif_isp10_pltfrm_pr_warn(dev->dev,
3756                                 "cannot output RAW data when SP is active, you will not be able to (re-)start streaming\n");
3757                 dev->config.mi_config.raw_enable = true;
3758         }
3759
3760         dev->config.mi_config.mp.output = strm_fmt->frm_fmt;
3761         dev->config.mi_config.mp.output.stride = stride;
3762
3763         dev->config.mi_config.mp.llength =
3764                 cif_isp10_calc_llength(
3765                         strm_fmt->frm_fmt.width,
3766                         stride,
3767                         strm_fmt->frm_fmt.pix_fmt);
3768         cif_isp10_pltfrm_pr_dbg(dev->dev,
3769                 "mp llength=0x%x\n", dev->config.mi_config.mp.llength);
3770
3771         dev->mp_stream.updt_cfg = true;
3772         dev->mp_stream.state = CIF_ISP10_STATE_READY;
3773
3774         if (!CIF_ISP10_INP_IS_DMA(dev->config.input_sel)) {
3775                 ret = cif_isp10_img_src_select_strm_fmt(dev);
3776                 if (IS_ERR_VALUE(ret)) {
3777                         dev->mp_stream.updt_cfg = false;
3778                         dev->mp_stream.state = CIF_ISP10_STATE_INACTIVE;
3779                         goto err;
3780                 }
3781         }
3782
3783         return 0;
3784 err:
3785         cif_isp10_pltfrm_pr_err(dev->dev,
3786                 "failed with error %d\n", ret);
3787         return ret;
3788 }
3789
3790 static int cif_isp10_s_fmt_sp(
3791         struct cif_isp10_device *dev,
3792         struct cif_isp10_strm_fmt *strm_fmt,
3793         u32 stride)
3794 {
3795         int ret = 0;
3796
3797         cif_isp10_pltfrm_pr_dbg(dev->dev,
3798                 "%s %dx%d@%d/%dfps, stride = %d, quantization: %d\n",
3799                 cif_isp10_pix_fmt_string(strm_fmt->frm_fmt.pix_fmt),
3800                 strm_fmt->frm_fmt.width,
3801                 strm_fmt->frm_fmt.height,
3802                 strm_fmt->frm_intrvl.numerator,
3803                 strm_fmt->frm_intrvl.denominator,
3804                 stride,
3805                 strm_fmt->frm_fmt.quantization);
3806
3807         if (dev->config.mi_config.raw_enable)
3808                 cif_isp10_pltfrm_pr_warn(dev->dev,
3809                         "cannot activate SP when MP is set to RAW data output, you will not be able to (re-)start streaming\n");
3810
3811         /* TBD: more detailed check whether format is a valid format for SP */
3812         /* TBD: remove the mode stuff */
3813         if (!CIF_ISP10_PIX_FMT_IS_YUV(strm_fmt->frm_fmt.pix_fmt) &&
3814                 !CIF_ISP10_PIX_FMT_IS_RGB(strm_fmt->frm_fmt.pix_fmt)) {
3815                 cif_isp10_pltfrm_pr_err(dev->dev,
3816                         "format %s %dx%d@%d/%dfps, stride = %d not supported on SP\n",
3817                         cif_isp10_pix_fmt_string(strm_fmt->frm_fmt.pix_fmt),
3818                         strm_fmt->frm_fmt.width,
3819                         strm_fmt->frm_fmt.height,
3820                         strm_fmt->frm_intrvl.numerator,
3821                         strm_fmt->frm_intrvl.denominator,
3822                         stride);
3823                 ret = -EINVAL;
3824                 goto err;
3825         }
3826
3827         dev->config.mi_config.sp.output = strm_fmt->frm_fmt;
3828         dev->config.mi_config.sp.llength =
3829                 cif_isp10_calc_llength(
3830                 strm_fmt->frm_fmt.width,
3831                 stride,
3832                 strm_fmt->frm_fmt.pix_fmt);
3833
3834         dev->sp_stream.updt_cfg = true;
3835         dev->sp_stream.state = CIF_ISP10_STATE_READY;
3836
3837         if (!CIF_ISP10_INP_IS_DMA(dev->config.input_sel)) {
3838                 ret = cif_isp10_img_src_select_strm_fmt(dev);
3839                 if (IS_ERR_VALUE(ret)) {
3840                         dev->sp_stream.updt_cfg = false;
3841                         dev->sp_stream.state = CIF_ISP10_STATE_INACTIVE;
3842                         goto err;
3843                 }
3844         }
3845
3846         return 0;
3847 err:
3848         cif_isp10_pltfrm_pr_err(dev->dev,
3849                 "failed with error %d\n", ret);
3850         return ret;
3851 }
3852
3853 static int cif_isp10_s_fmt_dma(
3854         struct cif_isp10_device *dev,
3855         struct cif_isp10_strm_fmt *strm_fmt,
3856         u32 stride)
3857 {
3858         int ret = 0;
3859
3860         cif_isp10_pltfrm_pr_dbg(dev->dev,
3861                 "%s %dx%d@%d/%dfps, stride = %d\n",
3862                 cif_isp10_pix_fmt_string(strm_fmt->frm_fmt.pix_fmt),
3863                 strm_fmt->frm_fmt.width,
3864                 strm_fmt->frm_fmt.height,
3865                 strm_fmt->frm_intrvl.numerator,
3866                 strm_fmt->frm_intrvl.denominator,
3867                 stride);
3868
3869         if (!CIF_ISP10_PIX_FMT_IS_YUV(strm_fmt->frm_fmt.pix_fmt) &&
3870                 !CIF_ISP10_PIX_FMT_IS_RAW_BAYER(strm_fmt->frm_fmt.pix_fmt)) {
3871                 cif_isp10_pltfrm_pr_err(dev->dev,
3872                         "format %s %dx%d@%d/%dfps, stride = %d not supported for DMA\n",
3873                         cif_isp10_pix_fmt_string(strm_fmt->frm_fmt.pix_fmt),
3874                         strm_fmt->frm_fmt.width,
3875                         strm_fmt->frm_fmt.height,
3876                         strm_fmt->frm_intrvl.numerator,
3877                         strm_fmt->frm_intrvl.denominator,
3878                         stride);
3879                 ret = -EINVAL;
3880                 goto err;
3881         }
3882
3883         dev->config.mi_config.dma.output = strm_fmt->frm_fmt;
3884         dev->config.mi_config.dma.llength =
3885                 cif_isp10_calc_llength(
3886                 strm_fmt->frm_fmt.width,
3887                 stride,
3888                 strm_fmt->frm_fmt.pix_fmt);
3889
3890         dev->dma_stream.updt_cfg = true;
3891         dev->dma_stream.state = CIF_ISP10_STATE_READY;
3892
3893         return 0;
3894 err:
3895         cif_isp10_pltfrm_pr_err(dev->dev,
3896                 "failed with error %d\n", ret);
3897         return ret;
3898 }
3899
3900 static void cif_isp10_dma_next_buff(
3901         struct cif_isp10_device *dev)
3902 {
3903         cif_isp10_pltfrm_pr_dbg(NULL, "\n");
3904
3905         if (!list_empty(&dev->dma_stream.buf_queue) &&
3906                 !dev->dma_stream.stop) {
3907                 if (dev->dma_stream.curr_buf)
3908                         WARN_ON(1);
3909                 dev->dma_stream.curr_buf =
3910                         list_first_entry(&dev->dma_stream.buf_queue,
3911                                 struct videobuf_buffer, queue);
3912                 list_del(&dev->dma_stream.curr_buf->queue);
3913                 dev->dma_stream.curr_buf->state = VIDEOBUF_ACTIVE;
3914                 dev->config.mi_config.dma.next_buff_addr =
3915                         videobuf_to_dma_contig(
3916                                 dev->dma_stream.curr_buf);
3917                 cif_isp10_mi_update_buff_addr(dev,
3918                         CIF_ISP10_STREAM_DMA);
3919                 dev->config.mi_config.dma.busy = true;
3920                 if ((dev->sp_stream.state == CIF_ISP10_STATE_STREAMING) &&
3921                         dev->sp_stream.curr_buf)
3922                         dev->config.mi_config.sp.busy = true;
3923                 if ((dev->mp_stream.state == CIF_ISP10_STATE_STREAMING) &&
3924                         dev->mp_stream.curr_buf)
3925                         dev->config.mi_config.mp.busy = true;
3926                 /* workaround for write register failure bug */
3927                 do {
3928                         cif_iowrite32(CIF_MI_DMA_START_ENABLE,
3929                                 dev->config.base_addr + CIF_MI_DMA_START);
3930                         udelay(1);
3931                 } while (!cif_ioread32(
3932                         dev->config.base_addr + CIF_MI_DMA_STATUS));
3933         }
3934
3935         cif_isp10_pltfrm_pr_dbg(dev->dev,
3936                 "\n  MI_DMA_CTRL 0x%08x\n"
3937                 "  MI_DMA_STATUS 0x%08x\n",
3938                 cif_ioread32(dev->config.base_addr +
3939                         CIF_MI_DMA_CTRL),
3940                 cif_ioread32(dev->config.base_addr +
3941                         CIF_MI_DMA_STATUS));
3942 }
3943
3944 static void cif_isp10_dma_ready(
3945         struct cif_isp10_device *dev)
3946 {
3947         unsigned int mi_mis_tmp;
3948
3949         cif_isp10_pltfrm_pr_dbg(NULL, "\n");
3950
3951         cif_iowrite32(CIF_MI_DMA_READY,
3952                 dev->config.base_addr + CIF_MI_ICR);
3953         mi_mis_tmp = cif_ioread32(dev->config.base_addr + CIF_MI_MIS);
3954         if (mi_mis_tmp & CIF_MI_DMA_READY)
3955                 cif_isp10_pltfrm_pr_err(dev->dev,
3956                                         "dma icr err: 0x%x\n",
3957                                         mi_mis_tmp);
3958         dev->dma_stream.curr_buf->state = VIDEOBUF_DONE;
3959         wake_up(&dev->dma_stream.curr_buf->done);
3960         dev->dma_stream.curr_buf = NULL;
3961         dev->config.mi_config.dma.busy = false;
3962         cif_isp10_pltfrm_event_signal(dev->dev, &dev->dma_stream.done);
3963 }
3964
3965 static int cif_isp10_mi_frame_end(
3966         struct cif_isp10_device *dev,
3967         enum cif_isp10_stream_id stream_id)
3968 {
3969         struct cif_isp10_stream *stream = NULL;
3970         u32 *next_buff_addr = NULL;
3971         CIF_ISP10_PLTFRM_MEM_IO_ADDR y_base_addr;
3972         int (*update_mi)(
3973                 struct cif_isp10_device *dev);
3974         struct cif_isp10_isp_readout_work *work;
3975
3976         cif_isp10_pltfrm_pr_dbg(NULL, "%s\n",
3977                 cif_isp10_stream_id_string(stream_id));
3978
3979         if (stream_id == CIF_ISP10_STREAM_MP) {
3980                 stream = &dev->mp_stream;
3981                 y_base_addr =
3982                         dev->config.base_addr + CIF_MI_MP_Y_BASE_AD_SHD;
3983                 next_buff_addr = &dev->config.mi_config.mp.next_buff_addr;
3984                 update_mi = cif_isp10_update_mi_mp;
3985                 if (dev->config.jpeg_config.enable) {
3986                         unsigned int jpe_status =
3987                                 cif_ioread32(dev->config.base_addr +
3988                                         CIF_JPE_STATUS_RIS);
3989                         if (jpe_status & CIF_JPE_STATUS_ENCODE_DONE) {
3990                                 cif_iowrite32(CIF_JPE_STATUS_ENCODE_DONE,
3991                                         dev->config.base_addr +
3992                                                 CIF_JPE_STATUS_ICR);
3993                                 if (stream->curr_buf) {
3994                                         stream->curr_buf->size =
3995                                         cif_ioread32(dev->config.base_addr +
3996                                                 CIF_MI_BYTE_CNT);
3997                                         cif_isp10_pltfrm_pr_dbg(NULL,
3998                                                 "JPEG encoding done, size %lu\n",
3999                                                 stream->curr_buf->size);
4000                                         if (cif_ioread32(dev->config.base_addr +
4001                                                 CIF_MI_RIS) & CIF_MI_WRAP_MP_Y)
4002                                                 cif_isp10_pltfrm_pr_err(NULL,
4003                                                         "buffer wrap around detected, JPEG presumably corrupted (%d/%d/%lu)\n",
4004                                                         dev->config.mi_config.
4005                                                         mp.y_size,
4006                                                         cif_ioread32(
4007                                                         dev->config.base_addr +
4008                                                         CIF_MI_MP_Y_SIZE_SHD),
4009                                                         stream->curr_buf->size);
4010                                 }
4011                         }
4012                 }
4013         } else if (stream_id == CIF_ISP10_STREAM_SP) {
4014                 stream = &dev->sp_stream;
4015                 y_base_addr =
4016                         dev->config.base_addr + CIF_MI_SP_Y_BASE_AD_SHD;
4017                 next_buff_addr = &dev->config.mi_config.sp.next_buff_addr;
4018                 update_mi = cif_isp10_update_mi_sp;
4019         } else {
4020                 WARN_ON(1);
4021         }
4022
4023         cif_isp10_pltfrm_pr_dbg(dev->dev,
4024                 "%s Y_BASE_AD_INIT/Y_BASE_AD_SHD (0x%08x/0x%08x)\n",
4025                 cif_isp10_stream_id_string(stream_id),
4026                 (stream_id & CIF_ISP10_STREAM_MP) ?
4027                         cif_ioread32(dev->config.base_addr +
4028                         CIF_MI_MP_Y_BASE_AD_INIT) :
4029                         cif_ioread32(dev->config.base_addr +
4030                         CIF_MI_SP_Y_BASE_AD_INIT),
4031                 cif_ioread32(y_base_addr));
4032
4033         if ((!stream->next_buf) &&
4034                 !(dev->config.jpeg_config.enable &&
4035                 (stream_id == CIF_ISP10_STREAM_MP))) {
4036                 stream->stall = dev->config.out_of_buffer_stall;
4037         } else if ((stream->next_buf) &&
4038                 (videobuf_to_dma_contig(stream->next_buf) !=
4039                         cif_ioread32(y_base_addr))) {
4040                 cif_isp10_pltfrm_pr_warn(dev->dev,
4041                         "%s buffer queue is not advancing (0x%08x/0x%08x)\n",
4042                         cif_isp10_stream_id_string(stream_id),
4043                         (stream_id & CIF_ISP10_STREAM_MP) ?
4044                                 cif_ioread32(dev->config.base_addr +
4045                                 CIF_MI_MP_Y_BASE_AD_INIT) :
4046                                 cif_ioread32(dev->config.base_addr +
4047                                 CIF_MI_SP_Y_BASE_AD_INIT),
4048                         cif_ioread32(y_base_addr));
4049                 stream->stall = true;
4050         }
4051
4052         if (!stream->stall) {
4053                 /*
4054                  * If mi restart after switch off for buffer is empty,
4055                  * mi may be restart failed. So mi write data to last
4056                  * buffer, the last buffer isn't been release to user
4057                  * until new buffer queue;
4058                  */
4059                 if ((stream->curr_buf) &&
4060                         (stream->next_buf)) {
4061                         bool wake_now;
4062
4063                         stream->curr_buf->field_count = dev->isp_dev.frame_id;
4064                         stream->curr_buf->state = VIDEOBUF_DONE;
4065                         wake_now = false;
4066
4067                         if (stream->metadata.d && dev->isp_dev.streamon) {
4068                                 struct v4l2_buffer_metadata_s *metadata;
4069
4070                                 metadata = (struct v4l2_buffer_metadata_s *)
4071                                         (stream->metadata.d +
4072                                         stream->curr_buf->i *
4073                                         CAMERA_METADATA_LEN);
4074                                 metadata->frame_id = dev->isp_dev.frame_id;
4075                                 metadata->frame_t.vs_t = dev->isp_dev.vs_t;
4076                                 metadata->frame_t.fi_t = dev->isp_dev.fi_t;
4077
4078                                 work = (struct cif_isp10_isp_readout_work *)
4079                                         kmalloc(
4080                                         sizeof(
4081                                         struct cif_isp10_isp_readout_work),
4082                                         GFP_ATOMIC);
4083                                 if (work) {
4084                                         INIT_WORK((struct work_struct *)work,
4085                                                 cifisp_isp_readout_work);
4086                                         work->readout =
4087                                                 CIF_ISP10_ISP_READOUT_META;
4088                                         work->isp_dev =
4089                                                 &dev->isp_dev;
4090                                         work->frame_id =
4091                                                 dev->isp_dev.frame_id;
4092                                         work->vb = stream->curr_buf;
4093                                         work->stream_id = stream->id;
4094                                         if (!queue_work(dev->isp_dev.readout_wq,
4095                                                 (struct work_struct *)work)) {
4096                                                 cif_isp10_pltfrm_pr_err(
4097                                                 dev->dev,
4098                                                 "Could not schedule work\n");
4099                                                 wake_now = true;
4100                                                 kfree((void *)work);
4101                                         }
4102                                 } else {
4103                                         cif_isp10_pltfrm_pr_err(dev->dev,
4104                                                 "Could not allocate work\n");
4105                                         wake_now = true;
4106                                 }
4107                         } else {
4108                                 wake_now = true;
4109                         }
4110
4111                         if (wake_now) {
4112                                 cif_isp10_pltfrm_pr_dbg(NULL,
4113                                         "frame done\n");
4114                                 wake_up(&stream->curr_buf->done);
4115                         }
4116                         stream->curr_buf = NULL;
4117                 }
4118
4119                 if (!stream->curr_buf) {
4120                         stream->curr_buf = stream->next_buf;
4121                         stream->next_buf = NULL;
4122                 }
4123         }
4124
4125         if (!stream->next_buf) {
4126                 /*
4127                  * in case of jpeg encoding, we are only programming
4128                  * a new buffer, if the jpeg header was generated, because
4129                  * we need the curent buffer for the jpeg encoding
4130                  * in the current frame period
4131                  */
4132                 if (!list_empty(&stream->buf_queue)) {
4133                         stream->next_buf =
4134                                 list_first_entry(&stream->buf_queue,
4135                                         struct videobuf_buffer, queue);
4136                         list_del(&stream->next_buf->queue);
4137                         stream->next_buf->state = VIDEOBUF_ACTIVE;
4138                         *next_buff_addr = videobuf_to_dma_contig(
4139                                 stream->next_buf);
4140                 } else if (
4141                 !dev->config.out_of_buffer_stall ||
4142                 (dev->config.jpeg_config.enable &&
4143                 (stream_id == CIF_ISP10_STREAM_MP))) {
4144 /*
4145  * If mi restart after switch off for buffer is empty,
4146  * mi may be restart failed. So mi write data to last
4147  * buffer, the last buffer isn't been release to user
4148  * until new buffer queue;
4149  *
4150  * if
4151  * *next_buff_addr = CIF_ISP10_INVALID_BUFF_ADDR;
4152  * mi will stop;
4153  */
4154                         *next_buff_addr =
4155                         videobuf_to_dma_contig(
4156                         stream->curr_buf);
4157                 }
4158         }
4159         (void)update_mi(dev);
4160
4161         stream->stall = false;
4162
4163         cif_isp10_pltfrm_pr_dbg(dev->dev,
4164                 "%s curr_buff: %d, 0x%08x next_buf: %d, 0x%x\n",
4165                 cif_isp10_stream_id_string(stream_id),
4166                 (stream->curr_buf) ? stream->curr_buf->i : -1,
4167                 (stream->curr_buf) ? (int)videobuf_to_dma_contig
4168                 (stream->curr_buf) : -1,
4169                 (stream->next_buf) ? stream->next_buf->i : -1,
4170                 *next_buff_addr);
4171
4172         return 0;
4173 }
4174
4175 static void cif_isp10_stream_metadata_reset(
4176         struct cif_isp10_stream *stream_dev
4177 )
4178 {
4179         unsigned int i;
4180         struct v4l2_buffer_metadata_s *metadata;
4181         struct cifisp_isp_metadata *isp_metadata;
4182
4183         if (stream_dev->metadata.d) {
4184                 for (i = 0; i < stream_dev->metadata.cnt; i++) {
4185                         metadata = (struct v4l2_buffer_metadata_s *)
4186                                 (stream_dev->metadata.d +
4187                                 i * CAMERA_METADATA_LEN);
4188                         isp_metadata = (struct cifisp_isp_metadata *)
4189                                 metadata->isp;
4190                         isp_metadata->other_cfg.s_frame_id = 0xffffffff;
4191                         isp_metadata->meas_cfg.s_frame_id = 0xffffffff;
4192                 }
4193         }
4194 }
4195
4196 static void cif_isp10_start_mi(
4197         struct cif_isp10_device *dev,
4198         bool start_mi_sp,
4199         bool start_mi_mp)
4200 {
4201         cif_isp10_pltfrm_pr_dbg(dev->dev, "\n");
4202
4203         if (start_mi_sp &&
4204                 (dev->sp_stream.state == CIF_ISP10_STATE_STREAMING))
4205                 start_mi_sp = false;
4206         if (start_mi_mp &&
4207                 (dev->mp_stream.state == CIF_ISP10_STATE_STREAMING))
4208                 start_mi_mp = false;
4209         if (!start_mi_sp && !start_mi_mp)
4210                 return;
4211
4212         if ((start_mi_sp &&
4213                 (dev->mp_stream.state == CIF_ISP10_STATE_STREAMING)) ||
4214                 (start_mi_mp &&
4215                 (dev->sp_stream.state == CIF_ISP10_STATE_STREAMING)))
4216                 WARN_ON(1);
4217
4218         if (start_mi_sp) {
4219                 cif_isp10_stream_metadata_reset(&dev->sp_stream);
4220                 dev->config.mi_config.sp.next_buff_addr =
4221                         CIF_ISP10_INVALID_BUFF_ADDR;
4222                 dev->config.mi_config.sp.curr_buff_addr =
4223                         CIF_ISP10_INVALID_BUFF_ADDR;
4224                 spin_lock(&dev->vbq_lock);
4225                 cif_isp10_mi_frame_end(dev, CIF_ISP10_STREAM_SP);
4226                 spin_unlock(&dev->vbq_lock);
4227                 dev->sp_stream.stall = false;
4228         }
4229
4230         if (start_mi_mp) {
4231                 cif_isp10_stream_metadata_reset(&dev->mp_stream);
4232                 dev->config.mi_config.mp.next_buff_addr =
4233                         CIF_ISP10_INVALID_BUFF_ADDR;
4234                 dev->config.mi_config.mp.curr_buff_addr =
4235                         CIF_ISP10_INVALID_BUFF_ADDR;
4236                 spin_lock(&dev->vbq_lock);
4237                 cif_isp10_mi_frame_end(dev, CIF_ISP10_STREAM_MP);
4238                 spin_unlock(&dev->vbq_lock);
4239                 dev->mp_stream.stall = false;
4240         }
4241
4242         cif_iowrite32OR(CIF_MI_INIT_SOFT_UPD,
4243                 dev->config.base_addr + CIF_MI_INIT);
4244         cif_isp10_pltfrm_pr_dbg(NULL,
4245                 "CIF_MI_INIT_SOFT_UPD\n");
4246
4247         if (start_mi_sp) {
4248                 spin_lock(&dev->vbq_lock);
4249                 cif_isp10_mi_frame_end(dev, CIF_ISP10_STREAM_SP);
4250                 spin_unlock(&dev->vbq_lock);
4251                 if (dev->sp_stream.curr_buf &&
4252                         (!CIF_ISP10_INP_IS_DMA(dev->config.input_sel)))
4253                         dev->config.mi_config.sp.busy = true;
4254         }
4255
4256         if (start_mi_mp) {
4257                 spin_lock(&dev->vbq_lock);
4258                 cif_isp10_mi_frame_end(dev, CIF_ISP10_STREAM_MP);
4259                 spin_unlock(&dev->vbq_lock);
4260                 if (dev->mp_stream.curr_buf &&
4261                         (!CIF_ISP10_INP_IS_DMA(dev->config.input_sel)))
4262                         dev->config.mi_config.mp.busy = true;
4263         }
4264
4265         if (!dev->config.mi_config.async_updt)
4266                 cif_iowrite32OR(CIF_ISP_CTRL_ISP_GEN_CFG_UPD,
4267                         dev->config.base_addr + CIF_ISP_CTRL);
4268 }
4269
4270 static void cif_isp10_stop_mi(
4271         struct cif_isp10_device *dev,
4272         bool stop_mi_sp,
4273         bool stop_mi_mp)
4274 {
4275         cif_isp10_pltfrm_pr_dbg(dev->dev, "\n");
4276
4277         if (stop_mi_sp &&
4278                 (dev->sp_stream.state != CIF_ISP10_STATE_STREAMING))
4279                 stop_mi_sp = false;
4280         if (stop_mi_mp &&
4281                 (dev->mp_stream.state != CIF_ISP10_STATE_STREAMING))
4282                 stop_mi_mp = false;
4283
4284         if (!stop_mi_sp && !stop_mi_mp)
4285                 return;
4286
4287         if (stop_mi_sp && stop_mi_mp) {
4288                 cif_iowrite32AND_verify(~(CIF_MI_SP_FRAME |
4289                         CIF_MI_MP_FRAME |
4290                         CIF_JPE_STATUS_ENCODE_DONE),
4291                         dev->config.base_addr + CIF_MI_IMSC, ~0);
4292                 cif_iowrite32(CIF_MI_SP_FRAME |
4293                         CIF_MI_MP_FRAME |
4294                         CIF_JPE_STATUS_ENCODE_DONE,
4295                         dev->config.base_addr + CIF_MI_ICR);
4296                 cif_iowrite32AND_verify(~CIF_MI_CTRL_SP_ENABLE,
4297                         dev->config.base_addr + CIF_MI_CTRL, ~0);
4298                 cif_iowrite32AND_verify(~(CIF_MI_CTRL_MP_ENABLE_IN |
4299                         CIF_MI_CTRL_SP_ENABLE |
4300                         CIF_MI_CTRL_JPEG_ENABLE |
4301                         CIF_MI_CTRL_RAW_ENABLE),
4302                         dev->config.base_addr + CIF_MI_CTRL, ~0);
4303                 cif_iowrite32(CIF_MI_INIT_SOFT_UPD,
4304                         dev->config.base_addr + CIF_MI_INIT);
4305         } else if (stop_mi_sp) {
4306                 cif_iowrite32(CIF_MI_SP_FRAME,
4307                         dev->config.base_addr + CIF_MI_ICR);
4308                 cif_iowrite32AND_verify(~CIF_MI_CTRL_SP_ENABLE,
4309                         dev->config.base_addr + CIF_MI_CTRL, ~0);
4310         } else if (stop_mi_mp) {
4311                 cif_iowrite32(CIF_MI_MP_FRAME |
4312                         CIF_JPE_STATUS_ENCODE_DONE,
4313                         dev->config.base_addr + CIF_MI_ICR);
4314                 cif_iowrite32AND_verify(~(CIF_MI_CTRL_MP_ENABLE_IN |
4315                         CIF_MI_CTRL_JPEG_ENABLE |
4316                         CIF_MI_CTRL_RAW_ENABLE),
4317                         dev->config.base_addr + CIF_MI_CTRL, ~0);
4318         }
4319 }
4320
4321 static void cif_isp10_requeue_bufs(
4322         struct cif_isp10_device *dev,
4323         struct cif_isp10_stream *stream)
4324 {
4325         INIT_LIST_HEAD(&stream->buf_queue);
4326         stream->next_buf = NULL;
4327         stream->curr_buf = NULL;
4328         dev->requeue_bufs(dev, stream->id);
4329 }
4330
4331 static void cif_isp10_stop_sp(
4332         struct cif_isp10_device *dev)
4333 {
4334         int ret;
4335
4336         if (dev->sp_stream.state ==
4337                 CIF_ISP10_STATE_STREAMING) {
4338                 dev->sp_stream.stop = true;
4339                 ret = cif_isp10_pltfrm_event_wait_timeout(dev->dev,
4340                         &dev->sp_stream.done,
4341                         dev->sp_stream.state !=
4342                 CIF_ISP10_STATE_STREAMING,
4343                         1000000);
4344                 dev->sp_stream.stop = false;
4345                 if (IS_ERR_VALUE(ret)) {
4346                         cif_isp10_pltfrm_pr_warn(NULL,
4347                                 "waiting on event returned with error %d\n",
4348                                 ret);
4349                 }
4350                 if (dev->config.mi_config.sp.busy)
4351                         cif_isp10_pltfrm_pr_warn(NULL,
4352                                 "SP path still active while stopping it\n");
4353         }
4354 }
4355
4356 static void cif_isp10_stop_mp(
4357         struct cif_isp10_device *dev)
4358 {
4359         int ret;
4360
4361         if (dev->mp_stream.state ==
4362                 CIF_ISP10_STATE_STREAMING) {
4363                 dev->mp_stream.stop = true;
4364                 ret = cif_isp10_pltfrm_event_wait_timeout(dev->dev,
4365                         &dev->mp_stream.done,
4366                         dev->mp_stream.state !=
4367                 CIF_ISP10_STATE_STREAMING,
4368                         1000000);
4369                 dev->mp_stream.stop = false;
4370                 if (IS_ERR_VALUE(ret)) {
4371                         cif_isp10_pltfrm_pr_warn(NULL,
4372                                 "waiting on event returned with error %d\n",
4373                                 ret);
4374                 }
4375                 if (dev->config.mi_config.mp.busy ||
4376                         dev->config.jpeg_config.busy)
4377                         cif_isp10_pltfrm_pr_warn(NULL,
4378                                 "MP path still active while stopping it\n");
4379         }
4380 }
4381
4382 static void cif_isp10_stop_dma(
4383         struct cif_isp10_device *dev)
4384 {
4385         unsigned long flags = 0;
4386
4387         cif_isp10_pltfrm_pr_dbg(NULL, "\n");
4388
4389         if (dev->dma_stream.state ==
4390                 CIF_ISP10_STATE_STREAMING) {
4391                 /* we should not stop during an active DMA transfer */
4392                 dev->dma_stream.stop = true;
4393                 (void)cif_isp10_pltfrm_event_wait_timeout(dev->dev,
4394                         &dev->dma_stream.done,
4395                         dev->dma_stream.state !=
4396                         CIF_ISP10_STATE_STREAMING,
4397                         50000);
4398                 /* intentionally NOT checking dma.busy again */
4399                 if (dev->config.mi_config.dma.busy)
4400                         cif_isp10_pltfrm_pr_warn(NULL,
4401                                 "DMA transfer still active while stopping it\n");
4402                 dev->dma_stream.state = CIF_ISP10_STATE_READY;
4403                 spin_lock_irqsave(&dev->vbq_lock, flags);
4404                 cif_isp10_requeue_bufs(dev, &dev->dma_stream);
4405                 spin_unlock_irqrestore(&dev->vbq_lock, flags);
4406         }
4407 }
4408
4409 static int cif_isp10_stop(
4410         struct cif_isp10_device *dev,
4411         bool stop_sp,
4412         bool stop_mp)
4413 {
4414         unsigned long flags = 0;
4415         bool stop_all;
4416         int timeout;
4417
4418         cif_isp10_pltfrm_pr_dbg(dev->dev,
4419                 "SP state = %s, MP state = %s, img_src state = %s, stop_sp = %d, stop_mp = %d\n",
4420                 cif_isp10_state_string(dev->sp_stream.state),
4421                 cif_isp10_state_string(dev->mp_stream.state),
4422                 cif_isp10_img_src_state_string(dev->img_src_state),
4423                 stop_sp,
4424                 stop_mp);
4425
4426         if (!((stop_mp &&
4427                 (dev->mp_stream.state == CIF_ISP10_STATE_STREAMING)) ||
4428                 (stop_sp &&
4429                 (dev->sp_stream.state == CIF_ISP10_STATE_STREAMING)))) {
4430                 return 0;
4431         }
4432
4433         stop_all = ((stop_mp && stop_sp) ||
4434                 (stop_sp &&
4435                 (dev->mp_stream.state != CIF_ISP10_STATE_STREAMING)) ||
4436                 (stop_mp &&
4437                 (dev->sp_stream.state != CIF_ISP10_STATE_STREAMING)));
4438
4439         if (stop_all) {
4440                 /*
4441                  * Modify ISP stop sequence for isp bus dead:
4442                  * ISP(mi) stop in mi frame end -> Stop ISP(mipi) ->
4443                  * Stop ISP(isp) ->wait for ISP isp off
4444                  */
4445
4446                 cif_isp10_stop_mp(dev);
4447                 cif_isp10_stop_sp(dev);
4448                 cif_isp10_stop_dma(dev);
4449
4450                 local_irq_save(flags);
4451                 /* stop and clear MI, MIPI, and ISP interrupts */
4452                 cif_iowrite32(0, dev->config.base_addr + CIF_MIPI_IMSC);
4453                 cif_iowrite32(~0, dev->config.base_addr + CIF_MIPI_ICR);
4454
4455                 cif_iowrite32(0, dev->config.base_addr + CIF_ISP_IMSC);
4456                 cif_iowrite32(~0, dev->config.base_addr + CIF_ISP_ICR);
4457
4458                 cif_iowrite32_verify(0,
4459                         dev->config.base_addr + CIF_MI_IMSC, ~0);
4460                 cif_iowrite32(~0, dev->config.base_addr + CIF_MI_ICR);
4461
4462                 cif_iowrite32AND(~CIF_MIPI_CTRL_OUTPUT_ENA,
4463                         dev->config.base_addr + CIF_MIPI_CTRL);
4464                 /* stop ISP */
4465                 cif_iowrite32AND(~(CIF_ISP_CTRL_ISP_INFORM_ENABLE |
4466                         CIF_ISP_CTRL_ISP_ENABLE),
4467                         dev->config.base_addr + CIF_ISP_CTRL);
4468                 cif_iowrite32OR(CIF_ISP_CTRL_ISP_CFG_UPD,
4469                         dev->config.base_addr + CIF_ISP_CTRL);
4470
4471                 timeout = 100;
4472                 while ((timeout-- > 0) &&
4473                         ((cif_ioread32(dev->config.base_addr + CIF_ISP_RIS)
4474                         & CIF_ISP_OFF) != CIF_ISP_OFF)) {
4475                         msleep(20);
4476                 };
4477                 local_irq_restore(flags);
4478
4479                 if (!CIF_ISP10_INP_IS_DMA(dev->config.input_sel)) {
4480                         if (IS_ERR_VALUE(cif_isp10_img_src_set_state(dev,
4481                                 CIF_ISP10_IMG_SRC_STATE_SW_STNDBY)))
4482                                 cif_isp10_pltfrm_pr_dbg(dev->dev,
4483                                         "unable to put image source into standby\n");
4484                 }
4485                 if (IS_ERR_VALUE(cif_isp10_set_pm_state(dev,
4486                         CIF_ISP10_PM_STATE_SW_STNDBY)))
4487                         cif_isp10_pltfrm_pr_dbg(dev->dev,
4488                         "unable to put CIF into standby\n");
4489         } else if (stop_sp) {
4490                 if (!dev->config.mi_config.async_updt) {
4491                         local_irq_save(flags);
4492                         cif_isp10_stop_mi(dev, true, false);
4493                         local_irq_restore(flags);
4494                 }
4495                 cif_isp10_stop_sp(dev);
4496                 cif_iowrite32AND_verify(~CIF_MI_SP_FRAME,
4497                         dev->config.base_addr + CIF_MI_IMSC, ~0);
4498
4499         } else /* stop_mp */ {
4500                 if (!dev->config.mi_config.async_updt) {
4501                         local_irq_save(flags);
4502                         cif_isp10_stop_mi(dev, false, true);
4503                         local_irq_restore(flags);
4504                 }
4505                 cif_isp10_stop_mp(dev);
4506                 cif_iowrite32AND_verify(~(CIF_MI_MP_FRAME |
4507                         CIF_JPE_STATUS_ENCODE_DONE),
4508                         dev->config.base_addr + CIF_MI_IMSC, ~0);
4509         }
4510
4511         if (stop_mp && (dev->mp_stream.state == CIF_ISP10_STATE_STREAMING))
4512                 dev->mp_stream.state = CIF_ISP10_STATE_READY;
4513
4514         if (stop_sp && (dev->sp_stream.state == CIF_ISP10_STATE_STREAMING))
4515                 dev->sp_stream.state = CIF_ISP10_STATE_READY;
4516
4517         spin_lock(&dev->vbq_lock);
4518         if (stop_sp) {
4519                 dev->config.mi_config.sp.busy = false;
4520                 cif_isp10_requeue_bufs(dev, &dev->sp_stream);
4521         }
4522         if (stop_mp) {
4523                 dev->config.mi_config.mp.busy = false;
4524                 cif_isp10_requeue_bufs(dev, &dev->mp_stream);
4525         }
4526         spin_unlock(&dev->vbq_lock);
4527
4528         cif_isp10_pltfrm_pr_dbg(dev->dev,
4529                 "SP state = %s, MP state = %s, DMA state = %s, img_src state = %s\n"
4530                 "  MI_CTRL 0x%08x\n"
4531                 "  ISP_CTRL 0x%08x\n"
4532                 "  MIPI_CTRL 0x%08x\n",
4533                 cif_isp10_state_string(dev->sp_stream.state),
4534                 cif_isp10_state_string(dev->mp_stream.state),
4535                 cif_isp10_state_string(dev->dma_stream.state),
4536                 cif_isp10_img_src_state_string(dev->img_src_state),
4537                 cif_ioread32(dev->config.base_addr + CIF_MI_CTRL),
4538                 cif_ioread32(dev->config.base_addr + CIF_ISP_CTRL),
4539                 cif_ioread32(dev->config.base_addr + CIF_MIPI_CTRL));
4540
4541         return 0;
4542 }
4543
4544 static int cif_isp10_start(
4545         struct cif_isp10_device *dev,
4546         bool start_sp,
4547         bool start_mp)
4548 {
4549         unsigned int ret;
4550         struct videobuf_buffer *vb, *n;
4551
4552         cif_isp10_pltfrm_pr_dbg(dev->dev,
4553                 "SP state = %s, MP state = %s, DMA state = %s, img_src state = %s, start_sp = %d, start_mp = %d\n",
4554                 cif_isp10_state_string(dev->sp_stream.state),
4555                 cif_isp10_state_string(dev->mp_stream.state),
4556                 cif_isp10_state_string(dev->dma_stream.state),
4557                 cif_isp10_img_src_state_string(dev->img_src_state),
4558                 start_sp,
4559                 start_mp);
4560
4561         if (!((start_mp &&
4562                 (dev->mp_stream.state != CIF_ISP10_STATE_STREAMING)) ||
4563                 (start_sp &&
4564                 (dev->sp_stream.state != CIF_ISP10_STATE_STREAMING))))
4565                 return 0;
4566
4567         if (CIF_ISP10_INP_IS_DMA(dev->config.input_sel) &&
4568                 (dev->dma_stream.state < CIF_ISP10_STATE_READY)) {
4569                 cif_isp10_pltfrm_pr_err(NULL,
4570                         "cannot start streaming, input source (DMA) not ready\n");
4571                 ret = -EFAULT;
4572                 goto err;
4573         }
4574
4575         /* Activate MI */
4576         cif_isp10_start_mi(dev, start_sp, start_mp);
4577
4578         if ((dev->sp_stream.state != CIF_ISP10_STATE_STREAMING) &&
4579                 (dev->mp_stream.state != CIF_ISP10_STATE_STREAMING)) {
4580                 /* Activate MIPI */
4581                 if (CIF_ISP10_INP_IS_MIPI(dev->config.input_sel))
4582                         cif_iowrite32OR(CIF_MIPI_CTRL_OUTPUT_ENA,
4583                                 dev->config.base_addr + CIF_MIPI_CTRL);
4584
4585                 /* Activate ISP ! */
4586                 if (CIF_ISP10_INP_NEED_ISP(dev->config.input_sel))
4587                         cif_iowrite32OR(CIF_ISP_CTRL_ISP_CFG_UPD |
4588                                 CIF_ISP_CTRL_ISP_INFORM_ENABLE |
4589                                 CIF_ISP_CTRL_ISP_ENABLE,
4590                                 dev->config.base_addr + CIF_ISP_CTRL);
4591         }
4592
4593         if (start_sp &&
4594                 (dev->sp_stream.state != CIF_ISP10_STATE_STREAMING)) {
4595                 dev->sp_stream.state = CIF_ISP10_STATE_STREAMING;
4596         }
4597         if (start_mp &&
4598                 (dev->mp_stream.state != CIF_ISP10_STATE_STREAMING)) {
4599                 dev->mp_stream.state = CIF_ISP10_STATE_STREAMING;
4600         }
4601         ret = cif_isp10_set_pm_state(dev,
4602                 CIF_ISP10_PM_STATE_STREAMING);
4603         if (IS_ERR_VALUE(ret))
4604                 goto err;
4605
4606         if (!CIF_ISP10_INP_IS_DMA(dev->config.input_sel)) {
4607                 /*
4608                  * CIF spec says to wait for sufficient time after enabling
4609                  * the MIPI interface and before starting the sensor output.
4610                  */
4611                 mdelay(1);
4612                 /* start sensor output! */
4613                 dev->isp_dev.frame_id = 0;
4614                 dev->isp_dev.frame_id_setexp = 0;
4615                 videobuf_queue_lock(&dev->isp_dev.vbq_stat);
4616                 list_for_each_entry_safe(
4617                         vb, n, &dev->isp_dev.vbq_stat.stream, queue) {
4618                         if (vb->state == VIDEOBUF_DONE) {
4619                                 vb->field_count = -1;
4620                                 cif_isp10_pltfrm_pr_info(
4621                                         dev->dev,
4622                                         "discard vb: %d\n", vb->i);
4623                         }
4624                 }
4625                 videobuf_queue_unlock(&dev->isp_dev.vbq_stat);
4626
4627                 mutex_lock(&dev->img_src_exps.mutex);
4628                 cif_isp10_img_src_ioctl(dev->img_src,
4629                         RK_VIDIOC_SENSOR_MODE_DATA,
4630                         &dev->img_src_exps.data[0].data);
4631                 cif_isp10_img_src_ioctl(dev->img_src,
4632                         RK_VIDIOC_SENSOR_MODE_DATA,
4633                         &dev->img_src_exps.data[1].data);
4634                 dev->img_src_exps.data[0].v_frame_id = 0;
4635                 dev->img_src_exps.data[1].v_frame_id = 0;
4636                 mutex_unlock(&dev->img_src_exps.mutex);
4637
4638                 cif_isp10_pltfrm_rtrace_printf(dev->dev,
4639                         "starting image source...\n");
4640                 ret = cif_isp10_img_src_set_state(dev,
4641                         CIF_ISP10_IMG_SRC_STATE_STREAMING);
4642                 if (IS_ERR_VALUE(ret))
4643                         goto err;
4644         } else {
4645                 cif_isp10_pltfrm_rtrace_printf(dev->dev,
4646                         "starting DMA...\n");
4647                 dev->dma_stream.state = CIF_ISP10_STATE_STREAMING;
4648                 dev->dma_stream.stop = false;
4649                 cif_isp10_dma_next_buff(dev);
4650         }
4651
4652         cif_isp10_pltfrm_pr_dbg(dev->dev,
4653                 "SP state = %s, MP state = %s, DMA state = %s, img_src state = %s\n"
4654                 "  MI_CTRL 0x%08x\n"
4655                 "  ISP_CTRL 0x%08x\n"
4656                 "  MIPI_CTRL 0x%08x\n",
4657                 cif_isp10_state_string(dev->sp_stream.state),
4658                 cif_isp10_state_string(dev->mp_stream.state),
4659                 cif_isp10_state_string(dev->dma_stream.state),
4660                 cif_isp10_img_src_state_string(dev->img_src_state),
4661                 cif_ioread32(dev->config.base_addr + CIF_MI_CTRL),
4662                 cif_ioread32(dev->config.base_addr + CIF_ISP_CTRL),
4663                 cif_ioread32(dev->config.base_addr + CIF_MIPI_CTRL));
4664
4665         return 0;
4666 err:
4667         cif_isp10_pltfrm_pr_dbg(dev->dev,
4668                 "SP state = %s, MP state = %s, DMA state = %s, img_src state = %s\n"
4669                 "  MI_CTRL 0x%08x\n"
4670                 "  ISP_CTRL 0x%08x\n"
4671                 "  MIPI_CTRL 0x%08x\n",
4672                 cif_isp10_state_string(dev->sp_stream.state),
4673                 cif_isp10_state_string(dev->mp_stream.state),
4674                 cif_isp10_state_string(dev->dma_stream.state),
4675                 cif_isp10_img_src_state_string(dev->img_src_state),
4676                 cif_ioread32(dev->config.base_addr + CIF_MI_CTRL),
4677                 cif_ioread32(dev->config.base_addr + CIF_ISP_CTRL),
4678                 cif_ioread32(dev->config.base_addr + CIF_MIPI_CTRL));
4679         cif_isp10_pltfrm_pr_err(dev->dev,
4680                 "failed with err %d\n", ret);
4681         return ret;
4682 }
4683
4684 /* Function to be called inside ISR to update CIF ISM/DCROP/RSZ */
4685 static int cif_isp10_update_ism_dcr_rsz(
4686         struct cif_isp10_device *dev)
4687 {
4688         int ret = 0;
4689
4690         if (dev->config.isp_config.ism_config.ism_update_needed) {
4691                 if (dev->config.isp_config.ism_config.ism_en) {
4692                         if (!dev->isp_dev.cif_ism_cropping)
4693                                 dev->isp_dev.cif_ism_cropping = true;
4694                 } else {
4695                         if (dev->isp_dev.cif_ism_cropping)
4696                                 dev->isp_dev.cif_ism_cropping = false;
4697                 }
4698         }
4699
4700         /*
4701          * Update ISM, cif_isp10_config_ism() changes the output size of isp,
4702          * so it must be called before cif_isp10_config_rsz()
4703          */
4704         if (dev->config.isp_config.ism_config.ism_update_needed) {
4705                 cif_isp10_config_ism(dev, false);
4706                 if (dev->mp_stream.state == CIF_ISP10_STATE_STREAMING)
4707                         dev->config.mp_config.rsz_config.ism_adjust = true;
4708                 if (dev->sp_stream.state == CIF_ISP10_STATE_STREAMING)
4709                         dev->config.sp_config.rsz_config.ism_adjust = true;
4710
4711                 dev->config.isp_config.ism_config.ism_update_needed = false;
4712                 cif_iowrite32OR(CIF_ISP_CTRL_ISP_CFG_UPD,
4713                         dev->config.base_addr + CIF_ISP_CTRL);
4714
4715                 if (dev->config.isp_config.ism_config.ism_en)
4716                         dev->config.mi_config.async_updt |= CIF_ISP10_ASYNC_ISM;
4717         }
4718
4719         /* Update RSZ */
4720         if ((dev->config.mp_config.rsz_config.ycflt_adjust ||
4721                 dev->config.mp_config.rsz_config.ism_adjust)) {
4722                 ret = cif_isp10_config_rsz(dev, CIF_ISP10_STREAM_MP, true);
4723                 if (IS_ERR_VALUE(ret))
4724                         goto err;
4725         }
4726         if ((dev->config.sp_config.rsz_config.ycflt_adjust ||
4727                 dev->config.sp_config.rsz_config.ism_adjust)) {
4728                 ret = cif_isp10_config_rsz(dev, CIF_ISP10_STREAM_SP, true);
4729                 if (IS_ERR_VALUE(ret))
4730                         goto err;
4731         }
4732
4733         return 0;
4734 err:
4735         cif_isp10_pltfrm_pr_err(dev->dev,
4736                 "failed with err %d\n", ret);
4737         return ret;
4738 }
4739
4740 static int cif_isp10_mi_isr(unsigned int mi_mis, void *cntxt)
4741 {
4742         struct cif_isp10_device *dev = cntxt;
4743         unsigned int mi_mis_tmp;
4744
4745         cif_isp10_pltfrm_pr_dbg(dev->dev,
4746                 "\n  MI_RIS 0x%08x\n"
4747                 "  MI_IMSC 0x%08x\n"
4748                 "  MI_MIS 0x%08x\n",
4749                 cif_ioread32(dev->config.base_addr + CIF_MI_RIS),
4750                 cif_ioread32(dev->config.base_addr + CIF_MI_IMSC),
4751                 mi_mis);
4752
4753         cif_isp10_pltfrm_rtrace_printf(dev->dev,
4754                 "MI_MIS %08x, MI_RIS %08x, MI_IMSC %08x\n",
4755                 mi_mis,
4756                 cif_ioread32(dev->config.base_addr + CIF_MI_RIS),
4757                 cif_ioread32(dev->config.base_addr + CIF_MI_IMSC));
4758
4759         if (mi_mis & CIF_MI_SP_FRAME) {
4760                 dev->config.mi_config.sp.busy = false;
4761                 cif_iowrite32(CIF_MI_SP_FRAME,
4762                         dev->config.base_addr + CIF_MI_ICR);
4763                 mi_mis_tmp = cif_ioread32(dev->config.base_addr + CIF_MI_MIS);
4764                 if (mi_mis_tmp & CIF_MI_SP_FRAME)
4765                         cif_isp10_pltfrm_pr_err(dev->dev,
4766                                                 "sp icr err: 0x%x\n",
4767                                                 mi_mis_tmp);
4768         }
4769
4770         if (mi_mis & CIF_MI_MP_FRAME) {
4771                 dev->config.mi_config.mp.busy = false;
4772                 cif_iowrite32(CIF_MI_MP_FRAME,
4773                         dev->config.base_addr + CIF_MI_ICR);
4774                 mi_mis_tmp = cif_ioread32(dev->config.base_addr + CIF_MI_MIS);
4775                 if (mi_mis_tmp & CIF_MI_MP_FRAME)
4776                         cif_isp10_pltfrm_pr_err(dev->dev,
4777                                                 "mp icr err: 0x%x\n",
4778                                                 mi_mis_tmp);
4779         }
4780         if (mi_mis & CIF_MI_DMA_READY)
4781                 (void)cif_isp10_dma_ready(dev);
4782         if (dev->config.jpeg_config.enable &&
4783                 (cif_ioread32(dev->config.base_addr +
4784                         CIF_JPE_STATUS_RIS) & CIF_JPE_STATUS_ENCODE_DONE))
4785                 dev->config.jpeg_config.busy = false;
4786
4787         if (!CIF_ISP10_MI_IS_BUSY(dev) &&
4788                 !dev->config.jpeg_config.busy) {
4789                 if (dev->config.mi_config.async_updt) {
4790                         u32 mp_y_off_cnt_shd =
4791                                 cif_ioread32(dev->config.base_addr +
4792                                 CIF_MI_MP_Y_OFFS_CNT_SHD);
4793                         u32 sp_y_off_cnt_shd =
4794                                 cif_ioread32(dev->config.base_addr +
4795                                 CIF_MI_SP_Y_OFFS_CNT_SHD);
4796
4797                         cif_iowrite32(CIF_MI_INIT_SOFT_UPD,
4798                                 dev->config.base_addr + CIF_MI_INIT);
4799                         cif_isp10_pltfrm_pr_dbg(NULL,
4800                                 "CIF_MI_INIT_SOFT_UPD\n");
4801                         if (!dev->config.isp_config.ism_config.ism_en &&
4802                                 (dev->config.mi_config.async_updt &
4803                                 CIF_ISP10_ASYNC_ISM))
4804                                 dev->config.mi_config.async_updt &=
4805                                         ~CIF_ISP10_ASYNC_ISM;
4806                         if (sp_y_off_cnt_shd != 0) {
4807                                 spin_lock(&dev->vbq_lock);
4808                                 cif_isp10_requeue_bufs(dev, &dev->sp_stream);
4809                                 spin_unlock(&dev->vbq_lock);
4810                         }
4811                         if ((mp_y_off_cnt_shd != 0) &&
4812                                 (!dev->config.jpeg_config.enable)) {
4813                                 spin_lock(&dev->vbq_lock);
4814                                 cif_isp10_requeue_bufs(dev, &dev->mp_stream);
4815                                 spin_unlock(&dev->vbq_lock);
4816                         }
4817                         if (((mp_y_off_cnt_shd != 0) &&
4818                                 !dev->config.jpeg_config.enable) ||
4819                                 (sp_y_off_cnt_shd != 0)) {
4820                                 cif_isp10_pltfrm_pr_dbg(dev->dev,
4821                                         "soft update too late (SP offset %d, MP offset %d)\n",
4822                                         sp_y_off_cnt_shd, mp_y_off_cnt_shd);
4823                         }
4824                 }
4825
4826                 if (dev->mp_stream.stop &&
4827                         (dev->mp_stream.state == CIF_ISP10_STATE_STREAMING)) {
4828                         cif_isp10_stop_mi(dev, false, true);
4829                         dev->mp_stream.state = CIF_ISP10_STATE_READY;
4830                         dev->mp_stream.stop = false;
4831
4832                         /* Turn off MRSZ since it is not needed */
4833                         cif_iowrite32(0, dev->config.base_addr + CIF_MRSZ_CTRL);
4834                         cif_iowrite32OR(CIF_RSZ_CTRL_CFG_UPD,
4835                                 dev->config.base_addr + CIF_MRSZ_CTRL);
4836
4837                         cif_isp10_pltfrm_pr_dbg(NULL,
4838                                 "MP has stopped\n");
4839                         cif_isp10_pltfrm_event_signal(dev->dev,
4840                                 &dev->mp_stream.done);
4841                 }
4842                 if (dev->sp_stream.stop &&
4843                         (dev->sp_stream.state == CIF_ISP10_STATE_STREAMING)) {
4844                         cif_isp10_stop_mi(dev, true, false);
4845                         dev->sp_stream.state = CIF_ISP10_STATE_READY;
4846                         dev->sp_stream.stop = false;
4847
4848                         /* Turn off SRSZ since it is not needed */
4849                         cif_iowrite32(0, dev->config.base_addr + CIF_SRSZ_CTRL);
4850                         cif_iowrite32OR(CIF_RSZ_CTRL_CFG_UPD,
4851                                 dev->config.base_addr + CIF_SRSZ_CTRL);
4852
4853                         cif_isp10_pltfrm_pr_dbg(NULL,
4854                                 "SP has stopped\n");
4855                         cif_isp10_pltfrm_event_signal(dev->dev,
4856                                 &dev->sp_stream.done);
4857                 }
4858
4859                 if (dev->sp_stream.state == CIF_ISP10_STATE_STREAMING) {
4860                         spin_lock(&dev->vbq_lock);
4861                         (void)cif_isp10_mi_frame_end(dev,
4862                                 CIF_ISP10_STREAM_SP);
4863                         spin_unlock(&dev->vbq_lock);
4864                 }
4865                 if (dev->mp_stream.state == CIF_ISP10_STATE_STREAMING) {
4866                         spin_lock(&dev->vbq_lock);
4867                         (void)cif_isp10_mi_frame_end(dev,
4868                                 CIF_ISP10_STREAM_MP);
4869                         spin_unlock(&dev->vbq_lock);
4870                 }
4871
4872                 dev->b_mi_frame_end = true;
4873
4874                 if (dev->dma_stream.state == CIF_ISP10_STATE_STREAMING) {
4875                         cif_isp10_dma_next_buff(dev);
4876                 } else {
4877                         if ((dev->sp_stream.state ==
4878                                 CIF_ISP10_STATE_STREAMING) &&
4879                                 dev->sp_stream.curr_buf)
4880                                 dev->config.mi_config.sp.busy = true;
4881                         if ((dev->mp_stream.state ==
4882                                 CIF_ISP10_STATE_STREAMING) &&
4883                                 dev->mp_stream.curr_buf)
4884                                 dev->config.mi_config.mp.busy = true;
4885                 }
4886
4887                 if (dev->b_isp_frame_in &&
4888                 ((dev->mp_stream.state == CIF_ISP10_STATE_STREAMING) ||
4889                 (dev->sp_stream.state == CIF_ISP10_STATE_STREAMING)))
4890                         cif_isp10_update_ism_dcr_rsz(dev);
4891         }
4892
4893         cif_iowrite32(~(CIF_MI_MP_FRAME |
4894                 CIF_MI_SP_FRAME | CIF_MI_DMA_READY),
4895                 dev->config.base_addr + CIF_MI_ICR);
4896
4897         return 0;
4898 }
4899
4900 static int cif_isp10_register_isrs(struct cif_isp10_device *dev)
4901 {
4902         int ret = 0;
4903
4904         cif_isp10_pltfrm_irq_register_isr(
4905                 dev->dev,
4906                 CIF_ISP_MIS,
4907                 cif_isp10_isp_isr,
4908                 dev);
4909         if (IS_ERR_VALUE(ret))
4910                 cif_isp10_pltfrm_pr_warn(dev->dev,
4911                         "unable to register ISP ISR, some processing errors may go unnoticed\n");
4912
4913         cif_isp10_pltfrm_irq_register_isr(
4914                 dev->dev,
4915                 CIF_MIPI_MIS,
4916                 cif_isp10_mipi_isr,
4917                 dev);
4918         if (IS_ERR_VALUE(ret))
4919                 cif_isp10_pltfrm_pr_warn(dev->dev,
4920                         "unable to register MIPI ISR, MIPI errors may go unnoticed\n");
4921
4922         ret = cif_isp10_pltfrm_irq_register_isr(
4923                 dev->dev,
4924                 CIF_MI_MIS,
4925                 cif_isp10_mi_isr,
4926                 dev);
4927         if (IS_ERR_VALUE(ret)) {
4928                 cif_isp10_pltfrm_pr_err(dev->dev,
4929                         "unable to register MI ISR, aborting\n");
4930                 goto err;
4931         }
4932
4933         return 0;
4934
4935 err:
4936         cif_isp10_pltfrm_pr_err(dev->dev, "failed with error %d", ret);
4937         return ret;
4938 }
4939
4940 static void cif_isp10_vs_work(struct work_struct *work)
4941 {
4942         struct cif_isp10_isp_vs_work *vs_wk =
4943                 container_of(work, struct cif_isp10_isp_vs_work, work);
4944         struct cif_isp10_device *dev = vs_wk->dev;
4945
4946         switch (vs_wk->cmd) {
4947         case CIF_ISP10_VS_EXP: {
4948                 struct cif_isp10_img_src_exp *exp =
4949                         (struct cif_isp10_img_src_exp *)vs_wk->param;
4950                 struct cif_isp10_img_src_ext_ctrl *exp_ctrl = exp->exp;
4951                 struct cif_isp10_img_src_data *new_data;
4952
4953                 if (dev->img_src)
4954                         cif_isp10_img_src_s_ext_ctrls(dev->img_src, exp_ctrl);
4955                 else
4956                         cif_isp10_pltfrm_pr_err(dev->dev,
4957                         "dev->img_src is NULL\n");
4958
4959                 if (dev->img_src_exps.data[0].v_frame_id <
4960                         dev->img_src_exps.data[1].v_frame_id)
4961                         new_data = &dev->img_src_exps.data[0];
4962                 else
4963                         new_data = &dev->img_src_exps.data[1];
4964
4965                 mutex_lock(&dev->img_src_exps.mutex);
4966                 new_data->v_frame_id = dev->isp_dev.frame_id +
4967                         dev->img_src_exps.exp_valid_frms;
4968                 cif_isp10_img_src_ioctl(dev->img_src,
4969                         RK_VIDIOC_SENSOR_MODE_DATA,
4970                         &new_data->data);
4971                 mutex_unlock(&dev->img_src_exps.mutex);
4972
4973                 /*
4974                  * pr_info("%s: exp_time: %d gain: %d, frame_id: s %d, v %d\n",
4975                  * __func__,
4976                  * new_data->data.exp_time,
4977                  * new_data->data.gain,
4978                  * dev->isp_dev.frame_id,
4979                  * new_data->v_frame_id);
4980                  */
4981
4982                 kfree(exp->exp->ctrls);
4983                 exp->exp->ctrls = NULL;
4984                 kfree(exp->exp);
4985                 exp->exp = NULL;
4986                 kfree(exp);
4987                 exp = NULL;
4988                 break;
4989         }
4990         default:
4991                 break;
4992         }
4993
4994         kfree(vs_wk);
4995         vs_wk = NULL;
4996 }
4997
4998 /* Public Functions */
4999 void cif_isp10_sensor_mode_data_sync(
5000         struct cif_isp10_device *dev,
5001         unsigned int frame_id,
5002         struct isp_supplemental_sensor_mode_data *data)
5003 {
5004         struct cif_isp10_img_src_data *last_data;
5005         struct cif_isp10_img_src_data *new_data;
5006
5007         mutex_lock(&dev->img_src_exps.mutex);
5008         if (dev->img_src_exps.data[0].v_frame_id <
5009                 dev->img_src_exps.data[1].v_frame_id) {
5010                 last_data = &dev->img_src_exps.data[0];
5011                 new_data = &dev->img_src_exps.data[1];
5012         } else {
5013                 last_data = &dev->img_src_exps.data[1];
5014                 new_data = &dev->img_src_exps.data[0];
5015         }
5016
5017         if (frame_id >= new_data->v_frame_id) {
5018                 memcpy(data,
5019                         &new_data->data,
5020                         sizeof(struct isp_supplemental_sensor_mode_data));
5021         } else {
5022                 memcpy(data,
5023                         &last_data->data,
5024                         sizeof(struct isp_supplemental_sensor_mode_data));
5025         }
5026         mutex_unlock(&dev->img_src_exps.mutex);
5027 }
5028
5029 int cif_isp10_streamon(
5030         struct cif_isp10_device *dev,
5031         u32 stream_ids)
5032 {
5033         int ret = 0;
5034         bool streamon_sp = stream_ids & CIF_ISP10_STREAM_SP;
5035         bool streamon_mp = stream_ids & CIF_ISP10_STREAM_MP;
5036         bool streamon_dma = stream_ids & CIF_ISP10_STREAM_DMA;
5037
5038         cif_isp10_pltfrm_pr_dbg(dev->dev,
5039                 "SP state = %s, MP state = %s, DMA state = %s, streamon SP = %d, streamon MP = %d, streamon DMA = %d\n",
5040                 cif_isp10_state_string(dev->sp_stream.state),
5041                 cif_isp10_state_string(dev->mp_stream.state),
5042                 cif_isp10_state_string(dev->dma_stream.state),
5043                 streamon_sp, streamon_mp, streamon_dma);
5044
5045         if (!((streamon_sp &&
5046                 (dev->sp_stream.state != CIF_ISP10_STATE_STREAMING)) ||
5047                 (streamon_mp &&
5048                 (dev->mp_stream.state != CIF_ISP10_STATE_STREAMING))))
5049                 return 0;
5050
5051         if (streamon_sp &&
5052                 (dev->sp_stream.state != CIF_ISP10_STATE_READY)) {
5053                 cif_isp10_pltfrm_pr_err(dev->dev,
5054                         "cannot start streaming on SP path, path not yet enabled\n");
5055                 ret = -EFAULT;
5056                 goto err;
5057         }
5058
5059         if (streamon_mp && (dev->mp_stream.state != CIF_ISP10_STATE_READY)) {
5060                 cif_isp10_pltfrm_pr_err(dev->dev,
5061                         "cannot start streaming on MP path, path not yet enabled\n");
5062                 ret = -EFAULT;
5063                 goto err;
5064         }
5065
5066         if (streamon_sp && dev->config.mi_config.raw_enable &&
5067                 (streamon_mp ||
5068                 (dev->mp_stream.state == CIF_ISP10_STATE_STREAMING))) {
5069                 cif_isp10_pltfrm_pr_err(dev->dev,
5070                         "cannot start streaming on SP path when MP is active and set to RAW output\n");
5071                 ret = -EBUSY;
5072                 goto err;
5073         }
5074
5075         if (streamon_mp &&
5076                 (dev->sp_stream.state == CIF_ISP10_STATE_STREAMING))
5077                 dev->mp_stream.updt_cfg = true;
5078         if (streamon_sp &&
5079                 (dev->mp_stream.state == CIF_ISP10_STATE_STREAMING))
5080                 dev->sp_stream.updt_cfg = true;
5081
5082         if (streamon_sp && dev->sp_stream.updt_cfg &&
5083                 (dev->mp_stream.state == CIF_ISP10_STATE_STREAMING)) {
5084                 ret = cif_isp10_stop(dev, false, true);
5085                                 if (IS_ERR_VALUE(ret))
5086                                         goto err;
5087                                 streamon_mp = true;
5088                                 dev->mp_stream.updt_cfg = true;
5089         }
5090         if (streamon_mp && dev->mp_stream.updt_cfg &&
5091                 (dev->sp_stream.state == CIF_ISP10_STATE_STREAMING)) {
5092                 ret = cif_isp10_stop(dev, true, false);
5093                         if (IS_ERR_VALUE(ret))
5094                                 goto err;
5095
5096                         streamon_sp = true;
5097                         dev->sp_stream.updt_cfg = true;
5098         }
5099
5100         stream_ids = 0;
5101         if (streamon_mp && dev->mp_stream.updt_cfg)
5102                 stream_ids |= CIF_ISP10_STREAM_MP;
5103         if (streamon_sp && dev->sp_stream.updt_cfg)
5104                 stream_ids |= CIF_ISP10_STREAM_SP;
5105
5106         ret = cif_isp10_config_cif(dev, stream_ids);
5107         if (IS_ERR_VALUE(ret))
5108                 goto err;
5109
5110         ret = cif_isp10_start(dev, streamon_sp, streamon_mp);
5111         if (IS_ERR_VALUE(ret))
5112                 goto err;
5113
5114         cif_isp10_pltfrm_pr_dbg(dev->dev,
5115                 "SP state = %s, MP state = %s, DMA state = %s\n",
5116                 cif_isp10_state_string(dev->sp_stream.state),
5117                 cif_isp10_state_string(dev->mp_stream.state),
5118                 cif_isp10_state_string(dev->dma_stream.state));
5119
5120         return 0;
5121 err:
5122         cif_isp10_pltfrm_pr_dbg(dev->dev,
5123                 "SP state = %s, MP state = %s, DMA state = %s\n",
5124                 cif_isp10_state_string(dev->sp_stream.state),
5125                 cif_isp10_state_string(dev->mp_stream.state),
5126                 cif_isp10_state_string(dev->dma_stream.state));
5127         cif_isp10_pltfrm_pr_err(dev->dev,
5128                 "failed with error %d\n", ret);
5129         return ret;
5130 }
5131
5132 int cif_isp10_streamoff(
5133         struct cif_isp10_device *dev,
5134         u32 stream_ids)
5135 {
5136         int ret = 0;
5137         bool streamoff_sp = stream_ids & CIF_ISP10_STREAM_SP;
5138         bool streamoff_mp = stream_ids & CIF_ISP10_STREAM_MP;
5139         bool streamoff_dma = stream_ids & CIF_ISP10_STREAM_DMA;
5140         unsigned int streamoff_all = 0;
5141
5142         cif_isp10_pltfrm_pr_dbg(dev->dev,
5143                 "SP state = %s, MP state = %s, DMA state = %s, streamoff SP = %d, streamoff MP = %d, streamoff DMA = %d\n",
5144                 cif_isp10_state_string(dev->sp_stream.state),
5145                 cif_isp10_state_string(dev->mp_stream.state),
5146                 cif_isp10_state_string(dev->dma_stream.state),
5147                 streamoff_sp,
5148                 streamoff_mp,
5149                 streamoff_dma);
5150
5151         if (dev->config.flash_mode != CIF_ISP10_FLASH_MODE_OFF &&
5152                 ((streamoff_sp &&
5153                 (dev->mp_stream.state == CIF_ISP10_STATE_INACTIVE)) ||
5154                 (streamoff_mp &&
5155                 (dev->sp_stream.state == CIF_ISP10_STATE_INACTIVE))))
5156                 cif_isp10_img_src_s_ctrl(dev->img_src,
5157                         CIF_ISP10_CID_FLASH_MODE,
5158                         CIF_ISP10_FLASH_MODE_OFF);
5159
5160         streamoff_all = 0;
5161         if (dev->sp_stream.state == CIF_ISP10_STATE_STREAMING) {
5162                 if (streamoff_sp)
5163                         streamoff_all |= CIF_ISP10_STREAM_SP;
5164         } else {
5165                 streamoff_all |= CIF_ISP10_STREAM_SP;
5166         }
5167         if (dev->mp_stream.state == CIF_ISP10_STATE_STREAMING) {
5168                 if (streamoff_mp)
5169                         streamoff_all |= CIF_ISP10_STREAM_MP;
5170         } else {
5171                 streamoff_all |= CIF_ISP10_STREAM_MP;
5172         }
5173         if (streamoff_all == (CIF_ISP10_STREAM_MP | CIF_ISP10_STREAM_SP))
5174                 drain_workqueue(dev->vs_wq);
5175
5176         ret = cif_isp10_stop(dev, streamoff_sp, streamoff_mp);
5177         if (IS_ERR_VALUE(ret))
5178                 goto err;
5179         if ((streamoff_sp) &&
5180                 (dev->sp_stream.state == CIF_ISP10_STATE_READY))
5181                 dev->sp_stream.state = CIF_ISP10_STATE_INACTIVE;
5182         if (streamoff_mp) {
5183                 dev->config.jpeg_config.enable = false;
5184                 dev->config.mi_config.raw_enable = false;
5185                 dev->config.mi_config.mp.output.width = 0;
5186                 dev->config.mi_config.mp.output.height = 0;
5187                 dev->config.mi_config.mp.output.pix_fmt =
5188                         CIF_UNKNOWN_FORMAT;
5189                 if (dev->mp_stream.state == CIF_ISP10_STATE_READY)
5190                         dev->mp_stream.state = CIF_ISP10_STATE_INACTIVE;
5191         }
5192         if (streamoff_dma) {
5193                 cif_isp10_stop_dma(dev);
5194                 if (dev->dma_stream.state == CIF_ISP10_STATE_READY)
5195                         dev->dma_stream.state = CIF_ISP10_STATE_INACTIVE;
5196         }
5197         if ((dev->dma_stream.state <= CIF_ISP10_STATE_INACTIVE) &&
5198                 (dev->mp_stream.state <= CIF_ISP10_STATE_INACTIVE) &&
5199                 (dev->sp_stream.state <= CIF_ISP10_STATE_INACTIVE)) {
5200                 dev->isp_dev.input_width = 0;
5201                 dev->isp_dev.input_height = 0;
5202                 dev->config.isp_config.ism_config.ism_en = 0;
5203         }
5204
5205         cif_isp10_pltfrm_pr_dbg(dev->dev,
5206                 "SP state = %s, MP state = %s, DMA state = %s, # frames received = %d\n",
5207                 cif_isp10_state_string(dev->sp_stream.state),
5208                 cif_isp10_state_string(dev->mp_stream.state),
5209                 cif_isp10_state_string(dev->dma_stream.state),
5210                 dev->isp_dev.frame_id >> 1);
5211
5212         return 0;
5213 err:
5214         cif_isp10_pltfrm_pr_dbg(dev->dev,
5215                 "SP state = %s, MP state = %s, DMA state = %s\n",
5216                 cif_isp10_state_string(dev->sp_stream.state),
5217                 cif_isp10_state_string(dev->mp_stream.state),
5218                 cif_isp10_state_string(dev->dma_stream.state));
5219         cif_isp10_pltfrm_pr_err(dev->dev,
5220                 "failed with error %d\n", ret);
5221         return ret;
5222 }
5223
5224 int cif_isp10_suspend(
5225         struct cif_isp10_device *dev)
5226 {
5227         int ret = 0;
5228
5229         cif_isp10_pltfrm_pr_dbg(dev->dev,
5230                 "SP state = %s, MP state = %s\n",
5231                 cif_isp10_state_string(dev->sp_stream.state),
5232                 cif_isp10_state_string(dev->mp_stream.state));
5233
5234         if ((dev->pm_state == CIF_ISP10_PM_STATE_SUSPENDED) ||
5235                 (dev->pm_state == CIF_ISP10_PM_STATE_OFF))
5236                 return 0;
5237
5238         dev->sp_stream.saved_state = dev->sp_stream.state;
5239         dev->mp_stream.saved_state = dev->mp_stream.state;
5240         ret = cif_isp10_stop(dev, true, true);
5241         if (IS_ERR_VALUE(ret))
5242                 goto err;
5243         ret = cif_isp10_set_pm_state(dev, CIF_ISP10_PM_STATE_SUSPENDED);
5244         if (IS_ERR_VALUE(ret))
5245                 goto err;
5246         ret = cif_isp10_img_src_set_state(dev, CIF_ISP10_IMG_SRC_STATE_OFF);
5247         if (IS_ERR_VALUE(ret))
5248                 goto err;
5249
5250         return 0;
5251 err:
5252         cif_isp10_pltfrm_pr_err(dev->dev,
5253                 "failed with error %d\n", ret);
5254         return ret;
5255 }
5256
5257 int cif_isp10_resume(
5258         struct cif_isp10_device *dev)
5259 {
5260         u32 stream_ids = 0;
5261
5262         cif_isp10_pltfrm_pr_dbg(dev->dev,
5263                 "SP state = %s, MP state = %s\n",
5264                 cif_isp10_state_string(dev->sp_stream.state),
5265                 cif_isp10_state_string(dev->mp_stream.state));
5266
5267         if ((dev->sp_stream.saved_state == CIF_ISP10_STATE_READY) ||
5268                 (dev->sp_stream.saved_state == CIF_ISP10_STATE_STREAMING)) {
5269                 dev->sp_stream.updt_cfg = true;
5270                 dev->sp_stream.state = CIF_ISP10_STATE_READY;
5271                 if (dev->sp_stream.saved_state == CIF_ISP10_STATE_STREAMING)
5272                         stream_ids |= CIF_ISP10_STREAM_SP;
5273         }
5274         if ((dev->mp_stream.saved_state == CIF_ISP10_STATE_READY) ||
5275                 (dev->mp_stream.saved_state == CIF_ISP10_STATE_STREAMING)) {
5276                 dev->mp_stream.updt_cfg = true;
5277                 dev->mp_stream.state = CIF_ISP10_STATE_READY;
5278                 if (dev->mp_stream.saved_state == CIF_ISP10_STATE_STREAMING)
5279                         stream_ids |= CIF_ISP10_STREAM_MP;
5280         }
5281
5282         if ((dev->dma_stream.saved_state == CIF_ISP10_STATE_READY) ||
5283                 (dev->dma_stream.saved_state == CIF_ISP10_STATE_STREAMING)) {
5284                 dev->dma_stream.state = CIF_ISP10_STATE_READY;
5285                 if (dev->dma_stream.saved_state == CIF_ISP10_STATE_STREAMING)
5286                         stream_ids |= CIF_ISP10_STREAM_DMA;
5287         }
5288
5289         return cif_isp10_streamon(dev, stream_ids);
5290 }
5291
5292 int cif_isp10_s_fmt(
5293         struct cif_isp10_device *dev,
5294         enum cif_isp10_stream_id stream_id,
5295         struct cif_isp10_strm_fmt *strm_fmt,
5296         u32 stride)
5297 {
5298         int ret;
5299
5300         cif_isp10_pltfrm_pr_dbg(NULL, "%s\n",
5301                 cif_isp10_stream_id_string(stream_id));
5302
5303         switch (stream_id) {
5304         case CIF_ISP10_STREAM_SP:
5305                 return cif_isp10_s_fmt_sp(dev, strm_fmt, stride);
5306         case CIF_ISP10_STREAM_MP:
5307                 return cif_isp10_s_fmt_mp(dev, strm_fmt, stride);
5308         case CIF_ISP10_STREAM_DMA:
5309                 return cif_isp10_s_fmt_dma(dev, strm_fmt, stride);
5310         default:
5311                 cif_isp10_pltfrm_pr_err(NULL,
5312                         "unknown/unsupported stream ID %d\n", stream_id);
5313                 ret = -EINVAL;
5314                 goto err;
5315         }
5316
5317         return 0;
5318 err:
5319         cif_isp10_pltfrm_pr_err(NULL,
5320                 "failed with error %d\n", ret);
5321         return ret;
5322 }
5323
5324 int cif_isp10_init(
5325         struct cif_isp10_device *dev,
5326         u32 stream_ids)
5327 {
5328         int ret;
5329
5330         cif_isp10_pltfrm_pr_dbg(NULL, "0x%08x\n", stream_ids);
5331
5332         if (stream_ids & ~(CIF_ISP10_ALL_STREAMS)) {
5333                 cif_isp10_pltfrm_pr_err(NULL,
5334                         "unknown/unsupported stream IDs 0x%08x\n",
5335                         stream_ids);
5336                 ret = -EINVAL;
5337                 goto err;
5338         }
5339
5340         /* set default input, failure is not fatal here */
5341         if ((dev->sp_stream.state == CIF_ISP10_STATE_DISABLED) &&
5342                 (dev->mp_stream.state == CIF_ISP10_STATE_DISABLED)) {
5343                 (void)cif_isp10_s_input(dev, 0);
5344                 dev->config.isp_config.si_enable = false;
5345                 dev->config.isp_config.ie_config.effect =
5346                         CIF_ISP10_IE_NONE;
5347         }
5348
5349         if (stream_ids & CIF_ISP10_STREAM_SP)
5350                 cif_isp10_init_stream(dev, CIF_ISP10_STREAM_SP);
5351         if (stream_ids & CIF_ISP10_STREAM_MP)
5352                 cif_isp10_init_stream(dev, CIF_ISP10_STREAM_MP);
5353         if (stream_ids & CIF_ISP10_STREAM_DMA)
5354                 cif_isp10_init_stream(dev, CIF_ISP10_STREAM_DMA);
5355
5356         return 0;
5357 err:
5358         cif_isp10_pltfrm_pr_err(NULL,
5359                 "failed with error %d\n", ret);
5360         return ret;
5361 }
5362
5363 int cif_isp10_release(
5364         struct cif_isp10_device *dev,
5365         int stream_ids)
5366 {
5367         int ret;
5368         struct cif_isp10_stream *strm_dev;
5369
5370         cif_isp10_pltfrm_pr_dbg(NULL, "0x%08x\n", stream_ids);
5371
5372         if ((dev->sp_stream.state == CIF_ISP10_STATE_DISABLED) &&
5373                 (dev->mp_stream.state == CIF_ISP10_STATE_DISABLED) &&
5374                 (dev->dma_stream.state == CIF_ISP10_STATE_DISABLED))
5375                 return 0;
5376
5377         if (stream_ids & ~(CIF_ISP10_ALL_STREAMS)) {
5378                 cif_isp10_pltfrm_pr_err(NULL,
5379                         "unknown/unsupported stream IDs 0x%08x\n",
5380                         stream_ids);
5381                 ret = -EINVAL;
5382                 goto err;
5383         }
5384
5385         if (stream_ids == CIF_ISP10_STREAM_MP)
5386                 strm_dev = &dev->mp_stream;
5387         else if (stream_ids == CIF_ISP10_STREAM_SP)
5388                 strm_dev = &dev->sp_stream;
5389         else
5390                 strm_dev = NULL;
5391
5392         if (strm_dev) {
5393                 if (strm_dev->metadata.d) {
5394                         vfree(strm_dev->metadata.d);
5395                         strm_dev->metadata.d = NULL;
5396                         strm_dev->metadata.cnt = 0;
5397                 }
5398         }
5399
5400         if (stream_ids & CIF_ISP10_STREAM_SP) {
5401                 if (dev->sp_stream.state == CIF_ISP10_STATE_STREAMING) {
5402                         cif_isp10_pltfrm_pr_warn(dev->dev,
5403                                 "CIF SP in streaming state, should be stopped before release, trying to stop it\n");
5404                         ret = cif_isp10_stop(dev, true, false);
5405                         if (IS_ERR_VALUE(ret))
5406                                 goto err;
5407                 }
5408                 dev->sp_stream.state = CIF_ISP10_STATE_DISABLED;
5409         }
5410         if (stream_ids & CIF_ISP10_STREAM_MP) {
5411                 if (dev->mp_stream.state == CIF_ISP10_STATE_STREAMING) {
5412                         cif_isp10_pltfrm_pr_warn(dev->dev,
5413                                 "CIF MP in streaming state, should be stopped before release, trying to stop it\n");
5414                         ret = cif_isp10_stop(dev, false, true);
5415                         if (IS_ERR_VALUE(ret))
5416                                 goto err;
5417                 }
5418                 dev->mp_stream.state = CIF_ISP10_STATE_DISABLED;
5419         }
5420
5421         if ((dev->sp_stream.state == CIF_ISP10_STATE_DISABLED) &&
5422                 (dev->mp_stream.state == CIF_ISP10_STATE_DISABLED)) {
5423                 if (IS_ERR_VALUE(cif_isp10_set_pm_state(dev,
5424                         CIF_ISP10_PM_STATE_OFF)))
5425                         cif_isp10_pltfrm_pr_warn(dev->dev,
5426                         "CIF power off failed\n");
5427                 if (dev->img_src) {
5428                         if (IS_ERR_VALUE(cif_isp10_img_src_set_state(dev,
5429                                 CIF_ISP10_IMG_SRC_STATE_OFF)))
5430                                 cif_isp10_pltfrm_pr_warn(dev->dev,
5431                                         "image source power off failed\n");
5432                         dev->img_src = NULL;
5433                 }
5434         }
5435
5436         return 0;
5437 err:
5438         cif_isp10_pltfrm_pr_err(dev->dev,
5439                 "failed with error %d\n", ret);
5440         return ret;
5441 }
5442
5443 struct cif_isp10_device *cif_isp10_create(
5444         CIF_ISP10_PLTFRM_DEVICE pdev,
5445         void (*sof_event)(struct cif_isp10_device *dev, __u32 frame_sequence),
5446         void (*requeue_bufs)(struct cif_isp10_device *dev,
5447                                         enum cif_isp10_stream_id stream_id),
5448         struct pltfrm_soc_cfg *soc_cfg)
5449 {
5450         int ret;
5451         struct cif_isp10_device *dev;
5452
5453         cif_isp10_pltfrm_pr_dbg(NULL, "\n");
5454
5455         /* Allocate needed structures */
5456         dev = kzalloc(sizeof(*dev), GFP_KERNEL);
5457         if (!dev) {
5458                 cif_isp10_pltfrm_pr_err(dev->dev,
5459                         "memory allocation failed\n");
5460                 ret = -ENOMEM;
5461                 goto err;
5462         }
5463         dev->sof_event = sof_event;
5464         dev->requeue_bufs = requeue_bufs;
5465
5466         ret = cif_isp10_pltfrm_dev_init(dev,
5467                 &pdev, &dev->config.base_addr);
5468         if (IS_ERR_VALUE(ret))
5469                 goto err;
5470         cif_isp10_pltfrm_debug_register_print_cb(
5471                 dev->dev,
5472                 (void (*)(void *, const char *))cif_isp10_debug_print_block,
5473                 dev);
5474
5475         cif_isp10_pltfrm_soc_init(dev, soc_cfg);
5476
5477         ret = cif_isp10_img_srcs_init(dev);
5478         if (IS_ERR_VALUE(ret)) {
5479                 cif_isp10_pltfrm_pr_err(dev->dev,
5480                 "cif_isp10_img_srcs_init failed\n");
5481                 goto err;
5482         }
5483
5484         ret = cif_isp10_register_isrs(dev);
5485         if (IS_ERR_VALUE(ret))
5486                 goto err;
5487
5488         (void)cif_isp10_init(dev, CIF_ISP10_ALL_STREAMS);
5489         dev->pm_state = CIF_ISP10_PM_STATE_OFF;
5490         dev->sp_stream.state = CIF_ISP10_STATE_DISABLED;
5491         dev->sp_stream.id = CIF_ISP10_STREAM_SP;
5492         dev->mp_stream.state = CIF_ISP10_STATE_DISABLED;
5493         dev->mp_stream.id = CIF_ISP10_STREAM_MP;
5494         dev->dma_stream.state = CIF_ISP10_STATE_DISABLED;
5495         dev->dma_stream.id = CIF_ISP10_STREAM_DMA;
5496         dev->config.mi_config.async_updt = 0;
5497         cif_isp10_pltfrm_event_init(dev->dev, &dev->dma_stream.done);
5498         cif_isp10_pltfrm_event_init(dev->dev, &dev->sp_stream.done);
5499         cif_isp10_pltfrm_event_init(dev->dev, &dev->mp_stream.done);
5500
5501         dev->img_src_exps.exp_valid_frms = 2;
5502         mutex_init(&dev->img_src_exps.mutex);
5503         memset(&dev->img_src_exps.data, 0x00, sizeof(dev->img_src_exps.data));
5504         spin_lock_init(&dev->img_src_exps.lock);
5505         INIT_LIST_HEAD(&dev->img_src_exps.list);
5506         dev->vs_wq = alloc_workqueue("cif isp10 vs workqueue",
5507                         WQ_UNBOUND | WQ_MEM_RECLAIM, 1);
5508
5509         /* TBD: clean this up */
5510         init_output_formats();
5511
5512         return dev;
5513 err:
5514         cif_isp10_pltfrm_pr_err(NULL,
5515                 "failed with error %d\n", ret);
5516         if (!IS_ERR_OR_NULL(dev))
5517                 kfree(dev);
5518         return ERR_PTR(ret);
5519 }
5520
5521 void cif_isp10_destroy(
5522         struct cif_isp10_device *dev)
5523 {
5524         cif_isp10_pltfrm_pr_dbg(NULL, "\n");
5525         if (!IS_ERR_OR_NULL(dev))
5526                 kfree(dev);
5527 }
5528
5529 int cif_isp10_s_input(
5530         struct cif_isp10_device *dev,
5531         unsigned int input)
5532 {
5533         int ret;
5534         enum cif_isp10_inp inp;
5535
5536         cif_isp10_pltfrm_pr_dbg(dev->dev,
5537                 "setting input to %s\n",
5538                 cif_isp10_inp_string(
5539                 cif_isp10_input_index2inp(dev, input)));
5540
5541         if (input >= dev->img_src_cnt + CIF_ISP10_INP_DMA_CNT()) {
5542                 cif_isp10_pltfrm_pr_err(NULL,
5543                         "invalid input %d\n", input);
5544                 ret = -EINVAL;
5545                 goto err;
5546         }
5547
5548         dev->img_src = NULL;
5549
5550         inp = cif_isp10_input_index2inp(dev, input);
5551
5552         /* DMA -> ISP or DMA -> IE */
5553         if ((inp == CIF_ISP10_INP_DMA) || (inp == CIF_ISP10_INP_DMA_IE))
5554                 dev->config.isp_config.input =
5555                         &dev->config.mi_config.dma.output;
5556         else {
5557                 dev->img_src = dev->img_src_array[input];
5558                 dev->config.isp_config.input =
5559                         &dev->config.img_src_output.frm_fmt;
5560         }
5561         dev->config.input_sel = inp;
5562
5563         return 0;
5564 err:
5565         cif_isp10_pltfrm_pr_err(NULL,
5566                 "failed with error %d\n", ret);
5567         return ret;
5568 }
5569
5570 const char *cif_isp10_g_input_name(
5571         struct cif_isp10_device *dev,
5572         unsigned int input_index)
5573 {
5574         if (input_index >=
5575                 dev->img_src_cnt + CIF_ISP10_INP_DMA_CNT()) {
5576                 cif_isp10_pltfrm_pr_dbg(NULL,
5577                         "index %d out of bounds\n",
5578                         input_index);
5579                 return NULL;
5580         }
5581
5582         if (input_index < dev->img_src_cnt)
5583                 return cif_isp10_img_src_g_name(
5584                         dev->img_src_array[input_index]);
5585         else
5586                 return cif_isp10_inp_string(CIF_ISP10_INP_DMA +
5587                         ((input_index - dev->img_src_cnt) << 24));
5588 }
5589
5590 int cif_isp10_qbuf(
5591         struct cif_isp10_device *dev,
5592         enum cif_isp10_stream_id stream,
5593         struct cif_isp10_buffer *buf)
5594 {
5595         int ret = 0;
5596
5597         cif_isp10_pltfrm_pr_dbg(dev->dev,
5598                 "%s\n",
5599                 cif_isp10_stream_id_string(stream));
5600
5601         switch (stream) {
5602         case CIF_ISP10_STREAM_SP:
5603                 list_add_tail(&buf->queue, &dev->sp_stream.buf_queue);
5604                 break;
5605         case CIF_ISP10_STREAM_MP:
5606                 list_add_tail(&buf->queue, &dev->mp_stream.buf_queue);
5607                 break;
5608         case CIF_ISP10_STREAM_DMA:
5609                 list_add_tail(&buf->queue, &dev->dma_stream.buf_queue);
5610                 if ((dev->dma_stream.state == CIF_ISP10_STATE_STREAMING) &&
5611                         !CIF_ISP10_MI_IS_BUSY(dev))
5612                         cif_isp10_dma_next_buff(dev);
5613                 break;
5614         case CIF_ISP10_STREAM_ISP:
5615                 WARN_ON(1);
5616                 break;
5617         default:
5618                 cif_isp10_pltfrm_pr_err(dev->dev,
5619                         "unknown stream %d\n", stream);
5620                 ret = -EINVAL;
5621                 goto err;
5622         }
5623
5624         return 0;
5625 err:
5626         cif_isp10_pltfrm_pr_err(dev->dev,
5627                 "failed with err %d\n", ret);
5628         return ret;
5629 }
5630
5631 int cif_isp10_reqbufs(
5632         struct cif_isp10_device *dev,
5633         enum cif_isp10_stream_id strm,
5634         struct v4l2_requestbuffers *req)
5635 {
5636         struct cif_isp10_stream *strm_dev = NULL;
5637
5638         switch (strm) {
5639         case CIF_ISP10_STREAM_MP:
5640                 strm_dev = &dev->mp_stream;
5641                 break;
5642         case CIF_ISP10_STREAM_SP:
5643                 strm_dev = &dev->sp_stream;
5644                 break;
5645         default:
5646                 cif_isp10_pltfrm_pr_err(dev->dev,
5647                         "unknown stream id%d\n", strm);
5648                 break;
5649         }
5650
5651         strm_dev->metadata.cnt = req->count;
5652
5653         return 0;
5654 }
5655
5656 int cif_isp10_s_exp(
5657         struct cif_isp10_device *dev,
5658         struct cif_isp10_img_src_ext_ctrl *exp_ctrl)
5659 {
5660         struct cif_isp10_img_src_exp *exp = NULL;
5661         unsigned long lock_flags;
5662         int retval;
5663
5664         if (!dev->vs_wq)
5665                 return -ENODEV;
5666
5667         exp = kmalloc(sizeof(*exp), GFP_KERNEL);
5668         if (!exp) {
5669                 retval = -ENOMEM;
5670                 goto failed;
5671         }
5672
5673         exp->exp = exp_ctrl;
5674
5675         spin_lock_irqsave(&dev->img_src_exps.lock, lock_flags);
5676         list_add_tail(&exp->list, &dev->img_src_exps.list);
5677         spin_unlock_irqrestore(&dev->img_src_exps.lock, lock_flags);
5678
5679         return 0;
5680
5681 failed:
5682         return retval;
5683 }
5684
5685 int cif_isp10_s_isp_metadata(
5686         struct cif_isp10_device *dev,
5687         struct cif_isp10_isp_readout_work *readout_work,
5688         struct cifisp_isp_other_cfg *new_other,
5689         struct cifisp_isp_meas_cfg *new_meas,
5690         struct cifisp_stat_buffer *new_stats)
5691 {
5692         unsigned int stream_id =
5693                 readout_work->stream_id;
5694         struct videobuf_buffer *vb =
5695                 readout_work->vb;
5696         struct cif_isp10_stream *strm_dev = NULL;
5697         struct v4l2_buffer_metadata_s *metadata;
5698         struct cifisp_isp_metadata *isp_last;
5699
5700         switch (stream_id) {
5701         case CIF_ISP10_STREAM_MP:
5702                 strm_dev = &dev->mp_stream;
5703                 break;
5704         case CIF_ISP10_STREAM_SP:
5705                 strm_dev = &dev->sp_stream;
5706                 break;
5707         default:
5708                 cif_isp10_pltfrm_pr_err(dev->dev,
5709                         "unknown stream id%d\n", stream_id);
5710                 break;
5711         }
5712
5713         if (vb && strm_dev->metadata.d) {
5714                 metadata = (struct v4l2_buffer_metadata_s *)
5715                         (strm_dev->metadata.d +
5716                         vb->i * CAMERA_METADATA_LEN);
5717
5718                 metadata->frame_id = readout_work->frame_id;
5719                 isp_last =
5720                         (struct cifisp_isp_metadata *)metadata->isp;
5721
5722                 if (new_meas) {
5723                         if ((isp_last->meas_cfg.s_frame_id == 0xffffffff) ||
5724                                 (isp_last->meas_cfg.s_frame_id <
5725                                 new_meas->s_frame_id)) {
5726                                 memcpy(&isp_last->meas_cfg,
5727                                         new_meas,
5728                                         sizeof(struct cifisp_isp_meas_cfg));
5729                         }
5730                 }
5731
5732                 if (new_other) {
5733                         if ((isp_last->other_cfg.s_frame_id == 0xffffffff) ||
5734                                 (isp_last->other_cfg.s_frame_id <
5735                                 new_other->s_frame_id)) {
5736                                 memcpy(&isp_last->other_cfg,
5737                                         new_other,
5738                                         sizeof(struct cifisp_isp_other_cfg));
5739                         }
5740                 }
5741
5742                 if (new_stats) {
5743                         memcpy(&isp_last->meas_stat,
5744                                 new_stats,
5745                                 sizeof(struct cifisp_stat_buffer));
5746                         metadata->sensor.exp_time =
5747                                 new_stats->sensor_mode.exp_time;
5748                         metadata->sensor.gain =
5749                                 new_stats->sensor_mode.gain;
5750                 } else {
5751                         isp_last->meas_stat.meas_type = 0x00;
5752                 }
5753         }
5754
5755         if (vb) {
5756                 cif_isp10_pltfrm_pr_dbg(NULL,
5757                                 "frame done\n");
5758                 wake_up(&vb->done);
5759         }
5760
5761         return 0;
5762 }
5763
5764 int cif_isp10_mmap(
5765         struct cif_isp10_device *dev,
5766         enum cif_isp10_stream_id stream_id,
5767         struct vm_area_struct *vma)
5768 {
5769         struct cif_isp10_stream *strm_dev;
5770         void *mem_vaddr;
5771         int retval = 0, pages;
5772         unsigned long mem_size;
5773
5774         switch (stream_id) {
5775         case CIF_ISP10_STREAM_MP:
5776                 strm_dev = &dev->mp_stream;
5777                 break;
5778         case CIF_ISP10_STREAM_SP:
5779                 strm_dev = &dev->sp_stream;
5780                 break;
5781         default:
5782                 cif_isp10_pltfrm_pr_err(dev->dev,
5783                         "unknown stream id%d\n", stream_id);
5784                 return -ENODEV;
5785         }
5786
5787         mem_size = vma->vm_end - vma->vm_start;
5788         if (mem_size > strm_dev->metadata.cnt * CAMERA_METADATA_LEN) {
5789                 retval = -ENOMEM;
5790                 cif_isp10_pltfrm_pr_err(dev->dev,
5791                         "mmap size(0x%lx) > metadata memory size(0x%lx), so failed!",
5792                         mem_size,
5793                         (unsigned long)(strm_dev->metadata.cnt
5794                         * CAMERA_METADATA_LEN));
5795                 goto done;
5796         }
5797
5798         pages = PAGE_ALIGN(vma->vm_end - vma->vm_start);
5799         mem_vaddr = (struct v4l2_buffer_metadata_s *)vmalloc_user(pages);
5800         if (!mem_vaddr) {
5801                 cif_isp10_pltfrm_pr_err(dev->dev,
5802                         "vmalloc (%d bytes) failed for %s metadata\n",
5803                         pages,
5804                         (stream_id == CIF_ISP10_STREAM_MP) ? "mp" : "sp");
5805                 retval = -ENOMEM;
5806                 goto done;
5807         }
5808
5809         /* Try to remap memory */
5810         retval = remap_vmalloc_range(vma, mem_vaddr, 0);
5811         if (retval < 0) {
5812                 cif_isp10_pltfrm_pr_err(dev->dev,
5813                         "mmap: remap failed with error %d. ", retval);
5814                 vfree(mem_vaddr);
5815                 goto done;
5816         }
5817
5818         strm_dev->metadata.d = (unsigned char *)mem_vaddr;
5819
5820         vma->vm_private_data = (void *)&strm_dev->metadata;
5821
5822 done:
5823         return retval;
5824 }
5825
5826 int cif_isp10_get_target_frm_size(
5827         struct cif_isp10_device *dev,
5828         u32 *target_width,
5829         u32 *target_height)
5830 {
5831         if (dev->sp_stream.state >= CIF_ISP10_STATE_READY) {
5832                 if ((dev->mp_stream.state >= CIF_ISP10_STATE_READY) &&
5833                         (dev->config.mi_config.mp.output.width >
5834                         dev->config.mi_config.sp.output.width))
5835                         *target_width =
5836                                 dev->config.mi_config.mp.output.width;
5837                 else
5838                         *target_width =
5839                                 dev->config.mi_config.sp.output.width;
5840                 if ((dev->mp_stream.state >= CIF_ISP10_STATE_READY) &&
5841                         (dev->config.mi_config.mp.output.height >
5842                         dev->config.mi_config.sp.output.height))
5843                         *target_height =
5844                                 dev->config.mi_config.mp.output.height;
5845                 else
5846                         *target_height =
5847                                 dev->config.mi_config.sp.output.height;
5848         } else if (dev->mp_stream.state >= CIF_ISP10_STATE_READY) {
5849                 *target_width = dev->config.mi_config.mp.output.width;
5850                 *target_height = dev->config.mi_config.mp.output.height;
5851         } else {
5852                 cif_isp10_pltfrm_pr_err(dev->dev,
5853                         "cannot get target frame size, no path ready\n");
5854                 return -EFAULT;
5855         }
5856         return 0;
5857 }
5858
5859 int cif_isp10_calc_isp_cropping(
5860         struct cif_isp10_device *dev,
5861         u32 *width,
5862         u32 *height,
5863         u32 *h_offs,
5864         u32 *v_offs)
5865 {
5866         int ret = 0;
5867         u32 input_width;
5868         u32 input_height;
5869         u32 target_width;
5870         u32 target_height;
5871
5872         if (IS_ERR_OR_NULL(dev->config.isp_config.input)) {
5873                 cif_isp10_pltfrm_pr_err(dev->dev,
5874                         "no input selected for ISP\n");
5875                 ret = -EFAULT;
5876                 goto err;
5877         }
5878
5879         input_width = dev->config.isp_config.input->defrect.width;
5880         input_height = dev->config.isp_config.input->defrect.height;
5881
5882         ret = cif_isp10_get_target_frm_size(dev,
5883                 &target_width, &target_height);
5884         if (IS_ERR_VALUE(ret))
5885                 goto err;
5886
5887         *width = input_width;
5888         *height = input_width * target_height / target_width;
5889         *v_offs = 0;
5890         *h_offs = 0;
5891         *height &= ~1;
5892         if (*height < input_height)
5893                 /* vertical cropping */
5894                 *v_offs = (input_height - *height) >> 1;
5895         else if (*height > input_height) {
5896                 /* horizontal cropping */
5897                 *height = input_height;
5898                 *width = input_height * target_width / target_height;
5899                 *width &= ~1;
5900                 *h_offs = (input_width - *width) >> 1;
5901         }
5902
5903         return 0;
5904 err:
5905         cif_isp10_pltfrm_pr_err(dev->dev,
5906                 "failed with err %d\n", ret);
5907         return ret;
5908 }
5909
5910 int cif_isp10_calc_min_out_buff_size(
5911         struct cif_isp10_device *dev,
5912         enum cif_isp10_stream_id stream_id,
5913         u32 *size)
5914 {
5915         int ret = 0;
5916         enum cif_isp10_pix_fmt pix_fmt;
5917         u32 llength;
5918         u32 height;
5919         u32 bpp;
5920         struct cif_isp10_mi_path_config *mi_path;
5921         struct cif_isp10_stream *stream;
5922
5923         cif_isp10_pltfrm_pr_dbg(NULL,
5924                 "%s\n",
5925                 cif_isp10_stream_id_string(stream_id));
5926
5927         if (stream_id == CIF_ISP10_STREAM_SP) {
5928                 mi_path = &dev->config.mi_config.sp;
5929                 stream = &dev->sp_stream;
5930         } else if (stream_id == CIF_ISP10_STREAM_MP) {
5931                 mi_path = &dev->config.mi_config.mp;
5932                 stream = &dev->mp_stream;
5933         } else if (stream_id == CIF_ISP10_STREAM_DMA) {
5934                 mi_path = &dev->config.mi_config.dma;
5935                 stream = &dev->dma_stream;
5936         } else {
5937                 cif_isp10_pltfrm_pr_err(dev->dev,
5938                         "cannot calculate buffer size for this stream (%s)\n",
5939                         cif_isp10_stream_id_string(stream_id));
5940                 ret = -EINVAL;
5941                 goto err;
5942         }
5943
5944         if (stream->state < CIF_ISP10_STATE_READY) {
5945                 cif_isp10_pltfrm_pr_err(NULL,
5946                         "cannot calculate buffer size, %s stream not ready\n",
5947                         cif_isp10_stream_id_string(stream_id));
5948                 ret = -EINVAL;
5949                 goto err;
5950         }
5951         pix_fmt = mi_path->output.pix_fmt;
5952         llength = mi_path->llength;
5953         height = mi_path->output.height;
5954         cif_isp10_pltfrm_pr_dbg(NULL,
5955                 "mi_path->llength: 0x%x\n",
5956                 mi_path->llength);
5957
5958         if (CIF_ISP10_PIX_FMT_IS_RAW_BAYER(pix_fmt) &&
5959                 CIF_ISP10_PIX_FMT_GET_BPP(pix_fmt) > 8)
5960                 /* RAW input > 8BPP is stored with 16BPP by MI */
5961                 bpp = 16;
5962         else
5963                 bpp = CIF_ISP10_PIX_FMT_GET_BPP(pix_fmt);
5964         *size = llength * height * bpp / 8;
5965
5966         cif_isp10_pltfrm_pr_dbg(NULL,
5967                 "calculated buffer size: %d\n",
5968                 *size);
5969
5970         return 0;
5971 err:
5972         cif_isp10_pltfrm_pr_err(dev->dev,
5973                 "failed with err %d\n", ret);
5974         return ret;
5975 }
5976
5977 int cif_isp10_s_ctrl(
5978         struct cif_isp10_device *dev,
5979         const enum cif_isp10_cid id,
5980         int val)
5981 {
5982         cif_isp10_pltfrm_pr_dbg(NULL,
5983                 "id %d, val %d\n",
5984                 id, val);
5985
5986         switch (id) {
5987         case CIF_ISP10_CID_SUPER_IMPOSE:
5988                 dev->config.isp_config.si_enable = val;
5989                 break;
5990         case CIF_ISP10_CID_IMAGE_EFFECT:
5991                 if ((u32)val > CIF_ISP10_IE_NONE) {
5992                         cif_isp10_pltfrm_pr_err(NULL,
5993                                 "unknown/unsupported image effect %d\n", val);
5994                         return -EINVAL;
5995                 }
5996                 dev->config.isp_config.ie_config.effect = val;
5997                 break;
5998         case CIF_ISP10_CID_JPEG_QUALITY:
5999                 if ((u32)val > 100) {
6000                         cif_isp10_pltfrm_pr_err(NULL,
6001                                 "JPEG quality (%d) must be in [1..100]\n", val);
6002                         return -EINVAL;
6003                 }
6004                 dev->config.jpeg_config.ratio = val;
6005                 break;
6006         case CIF_ISP10_CID_FLASH_MODE:
6007                 if ((u32)val > CIF_ISP10_FLASH_MODE_TORCH) {
6008                         cif_isp10_pltfrm_pr_err(NULL,
6009                                 "unknown/unsupported flash mode (%d)\n", val);
6010                         return -EINVAL;
6011                 }
6012                 dev->config.flash_mode = val;
6013                 cif_isp10_img_src_s_ctrl(
6014                         dev->img_src,
6015                         CIF_ISP10_CID_FLASH_MODE,
6016                         dev->config.flash_mode);
6017                 if (dev->config.flash_mode == CIF_ISP10_FLASH_MODE_FLASH) {
6018                         do_gettimeofday(&dev->flash_t.mainflash_start_t);
6019                         dev->flash_t.mainflash_start_t.tv_usec +=
6020                                 dev->flash_t.flash_turn_on_time;
6021                         dev->flash_t.mainflash_end_t =
6022                                 dev->flash_t.mainflash_start_t;
6023                         dev->flash_t.mainflash_end_t.tv_sec +=
6024                                 dev->flash_t.flash_on_timeout;
6025                 } else if (dev->config.flash_mode ==
6026                            CIF_ISP10_FLASH_MODE_TORCH) {
6027                         do_gettimeofday(&dev->flash_t.preflash_start_t);
6028                         dev->flash_t.preflash_end_t =
6029                                 dev->flash_t.preflash_start_t;
6030                         dev->flash_t.preflash_end_t.tv_sec = 0x00;
6031                         dev->flash_t.preflash_end_t.tv_usec = 0x00;
6032                 } else if (dev->config.flash_mode == CIF_ISP10_FLASH_MODE_OFF) {
6033                         do_gettimeofday(&dev->flash_t.preflash_end_t);
6034                         if (dev->flash_t.preflash_end_t.tv_sec * 1000000 +
6035                             dev->flash_t.preflash_end_t.tv_usec <
6036                             dev->flash_t.mainflash_end_t.tv_sec * 1000000 +
6037                             dev->flash_t.mainflash_end_t.tv_usec) {
6038                                 dev->flash_t.mainflash_end_t =
6039                                         dev->flash_t.preflash_end_t;
6040                         }
6041                 }
6042                 break;
6043         case CIF_ISP10_CID_WB_TEMPERATURE:
6044         case CIF_ISP10_CID_ANALOG_GAIN:
6045         case CIF_ISP10_CID_EXPOSURE_TIME:
6046         case CIF_ISP10_CID_BLACK_LEVEL:
6047         case CIF_ISP10_CID_FOCUS_ABSOLUTE:
6048         case CIF_ISP10_CID_AUTO_N_PRESET_WHITE_BALANCE:
6049         case CIF_ISP10_CID_SCENE_MODE:
6050         case CIF_ISP10_CID_AUTO_FPS:
6051         case CIF_ISP10_CID_HFLIP:
6052         case CIF_ISP10_CID_VFLIP:
6053                 return cif_isp10_img_src_s_ctrl(dev->img_src,
6054                         id, val);
6055         default:
6056                 cif_isp10_pltfrm_pr_err(dev->dev,
6057                         "unknown/unsupported control %d\n", id);
6058                 return -EINVAL;
6059         }
6060
6061         return 0;
6062 }
6063
6064 /* end */
6065
6066 enum {
6067         isp_data_loss = 0,
6068         isp_pic_size_err,
6069         mipi_fifo_err,
6070         dphy_err_sot,
6071         dphy_err_sot_sync,
6072         dphy_err_eot_sync,
6073         dphy_err_ctrl,
6074         csi_err_protocol,
6075         csi_ecc1_err,
6076         csi_ecc2_err,
6077         csi_cs_err,
6078 };
6079
6080 static void cif_isp10_hw_restart(struct cif_isp10_device *dev)
6081 {
6082         cif_isp10_pltfrm_pr_dbg(NULL, "\n");
6083
6084         cif_isp10_hw_errors[isp_pic_size_err].count = 0;
6085         cif_isp10_hw_errors[isp_data_loss].count = 0;
6086         cif_isp10_hw_errors[csi_err_protocol].count = 0;
6087         cif_isp10_hw_errors[csi_ecc1_err].count = 0;
6088         cif_isp10_hw_errors[csi_ecc2_err].count = 0;
6089         cif_isp10_hw_errors[csi_cs_err].count = 0;
6090         cif_iowrite32(0x00000841, dev->config.base_addr + CIF_IRCL);
6091         cif_iowrite32(0x0, dev->config.base_addr + CIF_IRCL);
6092
6093         /* enable mipi frame end interrupt */
6094         cif_iowrite32(CIF_MIPI_FRAME_END,
6095                       dev->config.base_addr + CIF_MIPI_IMSC);
6096         /* enable csi protocol errors interrupts */
6097         cif_iowrite32OR(CIF_MIPI_ERR_CSI,
6098                         dev->config.base_addr + CIF_MIPI_IMSC);
6099         /* enable dphy errors interrupts */
6100         cif_iowrite32OR(CIF_MIPI_ERR_DPHY,
6101                         dev->config.base_addr + CIF_MIPI_IMSC);
6102         /* add fifo error */
6103         cif_iowrite32OR(CIF_MIPI_SYNC_FIFO_OVFLW(3),
6104                         dev->config.base_addr + CIF_MIPI_IMSC);
6105         /* add data overflow_error */
6106         cif_iowrite32OR(CIF_MIPI_ADD_DATA_OVFLW,
6107                         dev->config.base_addr + CIF_MIPI_IMSC);
6108
6109         cif_iowrite32(0x0,
6110                       dev->config.base_addr + CIF_MI_MP_Y_OFFS_CNT_INIT);
6111         cif_iowrite32(0x0,
6112                       dev->config.base_addr +
6113                       CIF_MI_MP_CR_OFFS_CNT_INIT);
6114         cif_iowrite32(0x0,
6115                       dev->config.base_addr +
6116                       CIF_MI_MP_CB_OFFS_CNT_INIT);
6117         cif_iowrite32(0x0,
6118                       dev->config.base_addr + CIF_MI_SP_Y_OFFS_CNT_INIT);
6119         cif_iowrite32(0x0,
6120                       dev->config.base_addr +
6121                       CIF_MI_SP_CR_OFFS_CNT_INIT);
6122         cif_iowrite32(0x0,
6123                       dev->config.base_addr +
6124                       CIF_MI_SP_CB_OFFS_CNT_INIT);
6125         cif_iowrite32OR(CIF_MI_CTRL_INIT_OFFSET_EN,
6126                         dev->config.base_addr + CIF_MI_CTRL);
6127
6128         /* Enable ISP ! */
6129         cif_iowrite32OR(CIF_ISP_CTRL_ISP_CFG_UPD |
6130                         CIF_ISP_CTRL_ISP_INFORM_ENABLE |
6131                         CIF_ISP_CTRL_ISP_ENABLE,
6132                         dev->config.base_addr + CIF_ISP_CTRL);
6133         /* enable MIPI */
6134         cif_iowrite32OR(CIF_MIPI_CTRL_OUTPUT_ENA,
6135                         dev->config.base_addr + CIF_MIPI_CTRL);
6136 }
6137
6138 int cif_isp10_mipi_isr(unsigned int mipi_mis, void *cntxt)
6139 {
6140         struct cif_isp10_device *dev =
6141             (struct cif_isp10_device *)cntxt;
6142         unsigned int mipi_ris = 0;
6143
6144         mipi_ris = cif_ioread32(dev->config.base_addr + CIF_MIPI_RIS);
6145         mipi_mis = cif_ioread32(dev->config.base_addr + CIF_MIPI_MIS);
6146
6147         cif_isp10_pltfrm_rtrace_printf(dev->dev,
6148                 "MIPI_MIS %08x, MIPI_RIS %08x, MIPI_IMSC %08x\n",
6149                 mipi_mis,
6150                 mipi_ris,
6151                 cif_ioread32(dev->config.base_addr + CIF_MIPI_IMSC));
6152
6153         cif_iowrite32(~0,
6154                 dev->config.base_addr + CIF_MIPI_ICR);
6155
6156         if (mipi_mis & CIF_MIPI_ERR_DPHY) {
6157                 cif_isp10_pltfrm_pr_warn(dev->dev,
6158                         "CIF_MIPI_ERR_DPHY: 0x%x\n", mipi_mis);
6159
6160                 /*
6161                  * Disable DPHY errctrl interrupt, because this dphy
6162                  * erctrl signal is assert and until the next changes
6163                  * in line state. This time is may be too long and cpu
6164                  * is hold in this interrupt.
6165                  */
6166                 if (mipi_mis & CIF_MIPI_ERR_CTRL(3))
6167                         cif_iowrite32AND(~(CIF_MIPI_ERR_CTRL(3)),
6168                                 dev->config.base_addr + CIF_MIPI_IMSC);
6169         }
6170
6171         if (mipi_mis & CIF_MIPI_ERR_CSI) {
6172                 cif_isp10_pltfrm_pr_warn(dev->dev,
6173                         "CIF_MIPI_ERR_CSI: 0x%x\n", mipi_mis);
6174         }
6175
6176         if (mipi_mis & CIF_MIPI_SYNC_FIFO_OVFLW(3)) {
6177                 cif_isp10_pltfrm_pr_warn(dev->dev,
6178                         "CIF_MIPI_SYNC_FIFO_OVFLW: 0x%x\n", mipi_mis);
6179         }
6180
6181         if (mipi_mis == CIF_MIPI_FRAME_END) {
6182                 /*
6183                  * Enable DPHY errctrl interrupt again, if mipi have receive
6184                  * the whole frame without any error.
6185                  */
6186                 cif_iowrite32OR(CIF_MIPI_ERR_CTRL(3),
6187                         dev->config.base_addr + CIF_MIPI_IMSC);
6188         }
6189
6190         mipi_mis = cif_ioread32(dev->config.base_addr + CIF_MIPI_MIS);
6191
6192         if (mipi_mis) {
6193                 cif_isp10_pltfrm_pr_err(dev->dev,
6194                         "mipi_mis icr err: 0x%x\n", mipi_mis);
6195         }
6196
6197         return 0;
6198 }
6199
6200 /* ======================================================================== */
6201 int cif_isp10_isp_isr(unsigned int isp_mis, void *cntxt)
6202 {
6203         struct cif_isp10_device *dev =
6204             (struct cif_isp10_device *)cntxt;
6205         unsigned int isp_mis_tmp = 0;
6206         unsigned int isp_err = 0;
6207         struct timeval tv;
6208
6209         cif_isp10_pltfrm_pr_dbg(dev->dev,
6210                 "ISP_MIS %08x, ISP_RIS %08x, ISP_IMSC %08x\n",
6211                 isp_mis,
6212                 cif_ioread32(dev->config.base_addr + CIF_ISP_RIS),
6213                 cif_ioread32(dev->config.base_addr + CIF_ISP_IMSC));
6214
6215         if (isp_mis & CIF_ISP_V_START) {
6216                 struct cif_isp10_isp_vs_work *vs_wk;
6217                 struct cif_isp10_img_src_exp *exp;
6218
6219                 do_gettimeofday(&tv);
6220                 dev->b_isp_frame_in = false;
6221                 dev->b_mi_frame_end = false;
6222                 cifisp_v_start(&dev->isp_dev, &tv);
6223
6224                 cif_iowrite32(CIF_ISP_V_START,
6225                       dev->config.base_addr + CIF_ISP_ICR);
6226                 isp_mis_tmp = cif_ioread32(dev->config.base_addr + CIF_ISP_MIS);
6227                 if (isp_mis_tmp & CIF_ISP_V_START)
6228                         cif_isp10_pltfrm_pr_err(dev->dev,
6229                                                 "isp icr v_statr err: 0x%x\n",
6230                                                 isp_mis_tmp);
6231
6232                 if (!dev->config.mi_config.async_updt) {
6233                         cif_iowrite32OR(CIF_ISP_CTRL_ISP_GEN_CFG_UPD,
6234                                 dev->config.base_addr + CIF_ISP_CTRL);
6235                         cif_isp10_pltfrm_pr_dbg(NULL,
6236                                 "CIF_ISP_CTRL_ISP_GEN_CFG_UPD\n");
6237                 }
6238                 if (dev->sof_event)
6239                         dev->sof_event(dev, dev->isp_dev.frame_id >> 1);
6240                 spin_lock(&dev->img_src_exps.lock);
6241                 if (!list_empty(&dev->img_src_exps.list)) {
6242                         exp = list_first_entry(&dev->img_src_exps.list,
6243                                 struct cif_isp10_img_src_exp,
6244                                 list);
6245                         list_del(&exp->list);
6246                 } else {
6247                         exp = NULL;
6248                 }
6249                 spin_unlock(&dev->img_src_exps.lock);
6250
6251                 if (exp) {
6252                         vs_wk = kmalloc(sizeof(*vs_wk),
6253                                 GFP_KERNEL);
6254                         if (vs_wk) {
6255                                 vs_wk->cmd = CIF_ISP10_VS_EXP;
6256                                 vs_wk->dev = dev;
6257                                 vs_wk->param = (void *)exp;
6258                                 INIT_WORK((struct work_struct *)&vs_wk->work,
6259                                         cif_isp10_vs_work);
6260                                 if (!queue_work(dev->vs_wq,
6261                                         (struct work_struct *)&vs_wk->work)) {
6262                                         cif_isp10_pltfrm_pr_err(dev->dev,
6263                                         "%s: queue work failed\n", __func__);
6264                                         kfree(vs_wk);
6265                                 }
6266                         }
6267                 }
6268         }
6269
6270         if (isp_mis & CIF_ISP_FRAME_IN) {
6271                 do_gettimeofday(&tv);
6272                 cif_iowrite32(CIF_ISP_FRAME_IN,
6273                               dev->config.base_addr + CIF_ISP_ICR);
6274                 cifisp_frame_in(&dev->isp_dev, &tv);
6275         }
6276
6277         if ((isp_mis & (CIF_ISP_DATA_LOSS | CIF_ISP_PIC_SIZE_ERROR))) {
6278                 dev->sp_stream.stall = true;
6279                 dev->mp_stream.stall = true;
6280
6281                 if ((isp_mis & CIF_ISP_PIC_SIZE_ERROR)) {
6282                         /* Clear pic_size_error */
6283                         cif_iowrite32(CIF_ISP_PIC_SIZE_ERROR,
6284                                 dev->config.base_addr +
6285                                 CIF_ISP_ICR);
6286                         cif_isp10_hw_errors[isp_pic_size_err].count++;
6287                         isp_err =
6288                             cif_ioread32(dev->config.base_addr +
6289                                          CIF_ISP_ERR);
6290                         dev_err(dev->dev,
6291                                 "CIF_ISP_PIC_SIZE_ERROR (0x%08x)",
6292                                 isp_err);
6293                         cif_iowrite32(isp_err,
6294                                 dev->config.base_addr +
6295                                 CIF_ISP_ERR_CLR);
6296                 } else if ((isp_mis & CIF_ISP_DATA_LOSS)) {
6297                         /* Clear data_loss */
6298                         cif_iowrite32(CIF_ISP_DATA_LOSS,
6299                                 dev->config.base_addr +
6300                                 CIF_ISP_ICR);
6301                         cif_isp10_hw_errors[isp_data_loss].count++;
6302                         dev_err(dev->dev,
6303                                 "CIF_ISP_DATA_LOSS\n");
6304                         cif_iowrite32(CIF_ISP_DATA_LOSS,
6305                                       dev->config.base_addr +
6306                                       CIF_ISP_ICR);
6307                 }
6308
6309                 /* Stop ISP */
6310                 cif_iowrite32AND(~CIF_ISP_CTRL_ISP_INFORM_ENABLE &
6311                                 ~CIF_ISP_CTRL_ISP_ENABLE,
6312                                 dev->config.base_addr + CIF_ISP_CTRL);
6313                 /* isp_update */
6314                 cif_iowrite32OR(CIF_ISP_CTRL_ISP_CFG_UPD,
6315                                 dev->config.base_addr + CIF_ISP_CTRL);
6316                 cif_isp10_hw_restart(dev);
6317         }
6318
6319         if (isp_mis & CIF_ISP_FRAME_IN) {
6320                 cif_iowrite32(CIF_ISP_FRAME_IN,
6321                         dev->config.base_addr + CIF_ISP_ICR);
6322                 isp_mis_tmp = cif_ioread32(dev->config.base_addr + CIF_ISP_MIS);
6323                 if (isp_mis_tmp & CIF_ISP_FRAME_IN)
6324                         cif_isp10_pltfrm_pr_err(dev->dev,
6325                                                 "isp icr frame_in err: 0x%x\n",
6326                                                 isp_mis_tmp);
6327
6328                 /* restart MI if CIF has run out of buffers */
6329                 if (!CIF_ISP10_INP_IS_DMA(dev->config.input_sel) &&
6330                         !CIF_ISP10_MI_IS_BUSY(dev) &&
6331                         !dev->config.jpeg_config.busy &&
6332                         (dev->config.mi_config.async_updt ||
6333                         (!dev->sp_stream.next_buf &&
6334                         !dev->mp_stream.next_buf))){
6335                         u32 mi_isr = 0;
6336
6337                         if (dev->sp_stream.state == CIF_ISP10_STATE_STREAMING)
6338                                 mi_isr |= CIF_MI_SP_FRAME;
6339                         if (dev->mp_stream.state == CIF_ISP10_STATE_STREAMING)
6340                                 mi_isr |= CIF_MI_MP_FRAME;
6341                         cif_iowrite32(mi_isr,
6342                                       dev->config.base_addr + CIF_MI_ISR);
6343                 }
6344         }
6345
6346         if (isp_mis & CIF_ISP_FRAME) {
6347                 /* Clear Frame In (ISP) */
6348                 cif_iowrite32(CIF_ISP_FRAME,
6349                               dev->config.base_addr + CIF_ISP_ICR);
6350                 isp_mis_tmp = cif_ioread32(dev->config.base_addr + CIF_ISP_MIS);
6351                 if (isp_mis_tmp & CIF_ISP_FRAME)
6352                         cif_isp10_pltfrm_pr_err(dev->dev,
6353                                                 "isp icr frame end err: 0x%x\n",
6354                                                 isp_mis_tmp);
6355
6356                 if (dev->b_mi_frame_end)
6357                         cif_isp10_update_ism_dcr_rsz(dev);
6358                 dev->b_isp_frame_in = true;
6359         }
6360
6361         cifisp_isp_isr(&dev->isp_dev, isp_mis);
6362
6363         return 0;
6364 }
6365
6366 /* ======================================================================== */
6367
6368 void init_output_formats(void)
6369 {
6370         unsigned int i = 0;
6371         int ret = 0;            /* RF*/
6372         int xgold_num_format = 0;       /*RF*/
6373
6374         xgold_num_format =
6375             (sizeof(cif_isp10_output_format) / sizeof(struct cif_isp10_fmt));
6376
6377         for (i = 0; i < xgold_num_format; i++) {
6378                 struct v4l2_fmtdesc fmtdesc;
6379
6380                 memset(&fmtdesc, 0, sizeof(fmtdesc));
6381                 fmtdesc.index = i;
6382                 fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
6383
6384                 strlcpy((&fmtdesc)->description,
6385                         cif_isp10_output_format[(&fmtdesc)->index].name,
6386                         sizeof((&fmtdesc)->description));
6387                 (&fmtdesc)->pixelformat =
6388                     cif_isp10_output_format[(&fmtdesc)->index].fourcc;
6389                 (&fmtdesc)->flags =
6390                     cif_isp10_output_format[(&fmtdesc)->index].flags;
6391
6392                 if (ret < 0)
6393                         break;
6394
6395                 output_formats[i] = fmtdesc;
6396         }
6397 }
6398
6399 int get_cif_isp10_output_format_size(void)
6400 {
6401         return sizeof(cif_isp10_output_format) / sizeof(struct cif_isp10_fmt);
6402 }
6403
6404 struct cif_isp10_fmt *get_cif_isp10_output_format(int index)
6405 {
6406         struct cif_isp10_fmt *fmt = NULL;
6407
6408         if ((index >= 0) && (index < get_cif_isp10_output_format_size()))
6409                 fmt = &cif_isp10_output_format[index];
6410
6411         return fmt;
6412 }
6413
6414 struct v4l2_fmtdesc *get_cif_isp10_output_format_desc(int index)
6415 {
6416         struct v4l2_fmtdesc *desc = NULL;
6417
6418         if ((index >= 0) && (index < get_cif_isp10_output_format_desc_size()))
6419                 desc = &output_formats[index];
6420
6421         return desc;
6422 }
6423
6424 int get_cif_isp10_output_format_desc_size(void)
6425 {
6426         return ARRAY_SIZE(cif_isp10_output_format);
6427 }