2 *************************************************************************
3 * Rockchip driver for CIF ISP 1.0
4 * (Based on Intel driver for sofiaxxx)
6 * Copyright (C) 2015 Intel Mobile Communications GmbH
7 * Copyright (C) 2016 Fuzhou Rockchip Electronics Co., Ltd.
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 *************************************************************************
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>
24 static int cif_isp10_mipi_isr(
27 static int cif_isp10_isp_isr(
30 static void init_output_formats(void);
32 struct v4l2_fmtdesc output_formats[MAX_NB_FORMATS];
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
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
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,
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,
105 /* Standard JPEG quantization tables */
107 /* According to JPEG spec:
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
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
133 /* According to JPEG spec:
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
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
158 static struct cif_isp10_fmt cif_isp10_output_format[] = {
159 /* ************* YUV422 ************* */
161 .name = "YUV422-Interleaved",
162 .fourcc = V4L2_PIX_FMT_YUYV,
169 .name = "YUV422-Interleaved",
170 .fourcc = V4L2_PIX_FMT_YUYV,
177 .name = "YVU422-Interleaved",
178 .fourcc = V4L2_PIX_FMT_UYVY,
185 .name = "YUV422-Planar",
186 .fourcc = V4L2_PIX_FMT_YUV422P,
193 .name = "YUV422-Semi-Planar",
194 .fourcc = V4L2_PIX_FMT_NV16,
200 /* ************* YUV420 ************* */
202 .name = "YUV420-Planar",
203 .fourcc = V4L2_PIX_FMT_YUV420,
210 .name = "YUV420-Planar",
211 .fourcc = V4L2_PIX_FMT_YUV420,
218 .name = "YVU420-Planar",
219 .fourcc = V4L2_PIX_FMT_YVU420,
226 .name = "YUV420-Semi-Planar",
227 .fourcc = V4L2_PIX_FMT_NV12,
234 .name = "YVU420-Semi-Planar",
235 .fourcc = V4L2_PIX_FMT_NV21,
241 /* ************* YUV400 ************* */
243 .name = "YVU400-Grey-Planar",
244 .fourcc = V4L2_PIX_FMT_GREY,
250 /* ************* YUV444 ************* */
252 .name = "YVU444-Planar",
253 .fourcc = V4L2_PIX_FMT_YUV444,
260 .name = "YVU444-Semi-Planar",
261 .fourcc = V4L2_PIX_FMT_NV24,
267 /* ************* JPEG ************* */
270 .fourcc = V4L2_PIX_FMT_JPEG,
276 /* ************ RGB565 *********** */
279 .fourcc = V4L2_PIX_FMT_RGB565,
285 /* ************ SGRBG8 *********** */
288 .fourcc = V4L2_PIX_FMT_SGRBG8,
296 struct cif_isp10_hw_error {
300 unsigned int type; /* isp:0 ;mipi:1 */
303 static struct cif_isp10_hw_error cif_isp10_hw_errors[] = {
305 .name = "isp_data_loss",
307 .mask = CIF_ISP_DATA_LOSS,
311 .name = "isp_pic_size_err",
313 .mask = CIF_ISP_PIC_SIZE_ERROR,
317 .name = "mipi_fifo_err",
319 .mask = CIF_MIPI_SYNC_FIFO_OVFLW(1),
323 .name = "dphy_err_sot",
325 .mask = CIF_MIPI_ERR_SOT(3),
329 .name = "dphy_err_sot_sync",
331 .mask = CIF_MIPI_ERR_SOT_SYNC(3),
335 .name = "dphy_err_eot_sync",
337 .mask = CIF_MIPI_ERR_EOT_SYNC(3),
341 .name = "dphy_err_ctrl",
343 .mask = CIF_MIPI_ERR_CTRL(3),
347 .name = "csi_err_protocol",
349 .mask = CIF_MIPI_ERR_PROTOCOL,
353 .name = "csi_err_ecc1",
355 .mask = CIF_MIPI_ERR_ECC1,
359 .name = "csi_err_ecc2",
361 .mask = CIF_MIPI_ERR_ECC2,
365 .name = "csi_err_cs",
367 .mask = CIF_MIPI_ERR_CS,
377 .name = "isp_outform",
379 .mask = CIF_ISP_ERR_OUTFORM_SIZE,
385 .mask = CIF_ISP_ERR_IS_SIZE,
389 .name = "isp_inform",
391 .mask = CIF_ISP_ERR_INFORM_SIZE,
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)
404 CIF_ISP10_ASYNC_JPEG = 0x1,
405 CIF_ISP10_ASYNC_YCFLT = 0x2,
406 CIF_ISP10_ASYNC_ISM = 0x4,
407 CIF_ISP10_ASYNC_DMA = 0x8
410 #define CIF_ISP10_ALWAYS_ASYNC 0x00
411 #define CIF_ISP10_ALWAYS_STALL_ON_NO_BUFS (false)
414 #define DIV_ROUND_UP(x, y) (((x) + (y) - 1) / (y))
418 #define DIV_TRUNCATE(x, y) ((x) / (y))
421 /* Structures and Types */
423 /* Static Functions */
424 static const char *cif_isp10_interface_string(
425 enum pltfrm_cam_itf_type itf)
428 case PLTFRM_CAM_ITF_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";
447 return "UNKNOWN/UNSUPPORTED";
451 static const char *cif_isp10_img_src_state_string(
452 enum cif_isp10_img_src_state state)
455 case CIF_ISP10_IMG_SRC_STATE_OFF:
457 case CIF_ISP10_IMG_SRC_STATE_SW_STNDBY:
459 case CIF_ISP10_IMG_SRC_STATE_STREAMING:
462 return "UNKNOWN/UNSUPPORTED";
466 static const char *cif_isp10_state_string(
467 enum cif_isp10_state state)
470 case CIF_ISP10_STATE_DISABLED:
472 case CIF_ISP10_STATE_INACTIVE:
474 case CIF_ISP10_STATE_READY:
476 case CIF_ISP10_STATE_STREAMING:
479 return "UNKNOWN/UNSUPPORTED";
483 static const char *cif_isp10_pm_state_string(
484 enum cif_isp10_pm_state pm_state)
487 case CIF_ISP10_PM_STATE_OFF:
489 case CIF_ISP10_PM_STATE_SW_STNDBY:
491 case CIF_ISP10_PM_STATE_SUSPENDED:
493 case CIF_ISP10_PM_STATE_STREAMING:
496 return "UNKNOWN/UNSUPPORTED";
500 static const char *cif_isp10_stream_id_string(
501 enum cif_isp10_stream_id stream_id)
504 case CIF_ISP10_STREAM_SP:
506 case CIF_ISP10_STREAM_MP:
508 case CIF_ISP10_STREAM_DMA:
510 case CIF_ISP10_STREAM_ISP:
513 return "UNKNOWN/UNSUPPORTED";
517 static const char *cif_isp10_inp_string(
518 enum cif_isp10_inp inp)
521 case CIF_ISP10_INP_CSI:
523 case CIF_ISP10_INP_CPI:
525 case CIF_ISP10_INP_DMA:
527 case CIF_ISP10_INP_DMA_IE:
528 return "DMA(Image Effects)";
529 case CIF_ISP10_INP_DMA_SP:
532 return "UNKNOWN/UNSUPPORTED";
536 enum cif_isp10_inp cif_isp10_input_index2inp(
537 struct cif_isp10_device *dev,
540 struct pltfrm_cam_itf itf;
542 if (input >= dev->img_src_cnt)
543 return input - dev->img_src_cnt + CIF_ISP10_INP_DMA;
545 cif_isp10_pltfrm_g_interface_config(
546 dev->img_src_array[input],
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;
556 static const char *cif_isp10_pix_fmt_string(int pixfmt)
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";
670 return "unknown/unsupported";
674 static void cif_isp10_debug_print_mi_sp(struct cif_isp10_device *dev)
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"
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 +
697 cif_ioread32(dev->config.base_addr +
699 cif_ioread32(dev->config.base_addr +
701 cif_ioread32(dev->config.base_addr +
703 cif_ioread32(dev->config.base_addr +
705 cif_ioread32(dev->config.base_addr +
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));
751 static void cif_isp10_debug_print_mi_mp(struct cif_isp10_device *dev)
753 cif_isp10_pltfrm_pr_info(dev->dev,
754 "\n MI_CTRL 0x%08x/0x%08x\n"
755 " MI_STATUS 0x%08x\n"
757 " MI_RIS 0x%08x/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 +
771 cif_ioread32(dev->config.base_addr +
773 cif_ioread32(dev->config.base_addr +
775 cif_ioread32(dev->config.base_addr +
777 cif_ioread32(dev->config.base_addr +
779 cif_ioread32(dev->config.base_addr +
781 cif_ioread32(dev->config.base_addr +
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));
819 static void cif_isp10_debug_print_srsz(struct cif_isp10_device *dev)
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 +
834 cif_ioread32(dev->config.base_addr +
836 cif_ioread32(dev->config.base_addr +
838 cif_ioread32(dev->config.base_addr +
839 CIF_SRSZ_SCALE_HY_SHD),
840 cif_ioread32(dev->config.base_addr +
842 cif_ioread32(dev->config.base_addr +
843 CIF_SRSZ_SCALE_HCB_SHD),
844 cif_ioread32(dev->config.base_addr +
846 cif_ioread32(dev->config.base_addr +
847 CIF_SRSZ_SCALE_HCR_SHD),
848 cif_ioread32(dev->config.base_addr +
850 cif_ioread32(dev->config.base_addr +
851 CIF_SRSZ_SCALE_VY_SHD),
852 cif_ioread32(dev->config.base_addr +
854 cif_ioread32(dev->config.base_addr +
855 CIF_SRSZ_SCALE_VC_SHD),
856 cif_ioread32(dev->config.base_addr +
858 cif_ioread32(dev->config.base_addr +
859 CIF_SRSZ_PHASE_HY_SHD),
860 cif_ioread32(dev->config.base_addr +
862 cif_ioread32(dev->config.base_addr +
863 CIF_SRSZ_PHASE_HC_SHD),
864 cif_ioread32(dev->config.base_addr +
866 cif_ioread32(dev->config.base_addr +
867 CIF_SRSZ_PHASE_VY_SHD),
868 cif_ioread32(dev->config.base_addr +
870 cif_ioread32(dev->config.base_addr +
871 CIF_SRSZ_PHASE_VC_SHD));
874 static void cif_isp10_debug_print_mrsz(struct cif_isp10_device *dev)
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 +
889 cif_ioread32(dev->config.base_addr +
891 cif_ioread32(dev->config.base_addr +
893 cif_ioread32(dev->config.base_addr +
894 CIF_MRSZ_SCALE_HY_SHD),
895 cif_ioread32(dev->config.base_addr +
897 cif_ioread32(dev->config.base_addr +
898 CIF_MRSZ_SCALE_HCB_SHD),
899 cif_ioread32(dev->config.base_addr +
901 cif_ioread32(dev->config.base_addr +
902 CIF_MRSZ_SCALE_HCR_SHD),
903 cif_ioread32(dev->config.base_addr +
905 cif_ioread32(dev->config.base_addr +
906 CIF_MRSZ_SCALE_VY_SHD),
907 cif_ioread32(dev->config.base_addr +
909 cif_ioread32(dev->config.base_addr +
910 CIF_MRSZ_SCALE_VC_SHD),
911 cif_ioread32(dev->config.base_addr +
913 cif_ioread32(dev->config.base_addr +
914 CIF_MRSZ_PHASE_HY_SHD),
915 cif_ioread32(dev->config.base_addr +
917 cif_ioread32(dev->config.base_addr +
918 CIF_MRSZ_PHASE_HC_SHD),
919 cif_ioread32(dev->config.base_addr +
921 cif_ioread32(dev->config.base_addr +
922 CIF_MRSZ_PHASE_VY_SHD),
923 cif_ioread32(dev->config.base_addr +
925 cif_ioread32(dev->config.base_addr +
926 CIF_MRSZ_PHASE_VC_SHD));
929 static void cif_isp10_debug_print_block(
930 struct cif_isp10_device *dev,
931 const char *block_name)
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);
947 cif_isp10_pltfrm_pr_err(dev->dev,
948 "unknown block %s\n", block_name);
952 static u32 cif_isp10_calc_llength(
955 enum cif_isp10_pix_fmt pix_fmt)
960 if (CIF_ISP10_PIX_FMT_IS_YUV(pix_fmt)) {
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);
967 } else if (CIF_ISP10_PIX_FMT_IS_RGB(pix_fmt)) {
968 return 8 * stride / CIF_ISP10_PIX_FMT_GET_BPP(pix_fmt);
974 static int cif_isp10_set_pm_state(
975 struct cif_isp10_device *dev,
976 enum cif_isp10_pm_state pm_state)
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));
982 if (dev->pm_state == 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);
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);
1001 cif_isp10_pltfrm_pr_err(dev->dev,
1002 "unknown or unsupported PM state %d\n", pm_state);
1006 dev->pm_state = pm_state;
1011 static int cif_isp10_img_src_set_state(
1012 struct cif_isp10_device *dev,
1013 enum cif_isp10_img_src_state state)
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));
1021 if (dev->img_src_state == state)
1025 case CIF_ISP10_IMG_SRC_STATE_OFF:
1026 ret = cif_isp10_img_src_s_power(dev->img_src, false);
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);
1033 ret = cif_isp10_img_src_s_power(dev->img_src, true);
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);
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);
1055 if (!IS_ERR_VALUE(ret))
1056 dev->img_src_state = state;
1058 cif_isp10_pltfrm_pr_err(dev->dev,
1059 "failed with err %d\n", ret);
1064 static int cif_isp10_img_srcs_init(
1065 struct cif_isp10_device *dev)
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);
1073 if (dev->img_src_cnt > 0)
1076 dev->img_src_cnt = 0;
1079 cif_isp10_pltfrm_pr_err(dev->dev,
1080 "failed with error %d\n", ret);
1084 static int cif_isp10_img_src_select_strm_fmt(
1085 struct cif_isp10_device *dev)
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;
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");
1105 ret = cif_isp10_get_target_frm_size(dev,
1106 &target_width, &target_height);
1107 if (IS_ERR_VALUE(ret))
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)))
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 >=
1121 img_src_width = target_width;
1123 img_src_width = strm_fmt_desc.max_frmsize.width;
1124 if (strm_fmt_desc.min_frmsize.height >= target_height)
1126 strm_fmt_desc.min_frmsize.height;
1127 else if (strm_fmt_desc.max_frmsize.height >=
1129 img_src_height = target_height;
1132 strm_fmt_desc.max_frmsize.height;
1134 img_src_width = strm_fmt_desc.min_frmsize.width;
1135 img_src_height = strm_fmt_desc.min_frmsize.height;
1137 if ((img_src_width >= target_width) &&
1138 (img_src_height >= target_height)) {
1141 (target_width * img_src_height /
1143 if (matching_format_found) {
1144 if (dev->config.jpeg_config.enable &&
1146 request_strm_fmt.frm_fmt.width) &&
1148 request_strm_fmt.frm_fmt.height)))
1150 * for image capturing we try to
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)))
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)) &&
1168 * chose better aspect ratio
1169 * match if fps equal
1171 better_match = true;
1173 better_match = false;
1176 if (!matching_format_found ||
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;
1193 matching_format_found = true;
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);
1206 cif_isp10_pltfrm_pr_dbg(
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));
1220 ret = cif_isp10_img_src_s_strm_fmt(dev->img_src, &request_strm_fmt);
1221 if (IS_ERR_VALUE(ret))
1224 dev->config.img_src_output = request_strm_fmt;
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(
1231 "get vblanking failed: %d\n", ret);
1236 dev->isp_dev.v_blanking_us = vblanking;
1240 cif_isp10_pltfrm_pr_err(dev->dev,
1241 "failed with err %d\n", ret);
1246 * This should only be called when configuring CIF
1247 * or at the frame end interrupt
1249 static void cif_isp10_config_ism(struct cif_isp10_device *dev, bool async)
1251 const struct cif_isp10_ism_config *pconfig =
1252 &dev->config.isp_config.ism_config;
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);
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;
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);
1294 dev->config.base_addr + CIF_ISP_IS_H_OFFS);
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);
1302 dev->config.base_addr + CIF_ISP_IS_CTRL);
1306 cif_iowrite32OR(CIF_ISP_CTRL_ISP_CFG_UPD,
1307 dev->config.base_addr + CIF_ISP_CTRL);
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 +
1321 cif_ioread32(dev->config.base_addr +
1322 CIF_ISP_IS_H_OFFS_SHD),
1323 cif_ioread32(dev->config.base_addr +
1325 cif_ioread32(dev->config.base_addr +
1326 CIF_ISP_IS_V_OFFS_SHD),
1327 cif_ioread32(dev->config.base_addr +
1329 cif_ioread32(dev->config.base_addr +
1330 CIF_ISP_IS_H_SIZE_SHD),
1331 cif_ioread32(dev->config.base_addr +
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 +
1339 cif_ioread32(dev->config.base_addr +
1341 cif_ioread32(dev->config.base_addr +
1342 CIF_ISP_IS_DISPLACE),
1343 cif_ioread32(dev->config.base_addr +
1347 static void cif_isp10_program_jpeg_tables(
1348 struct cif_isp10_device *dev)
1350 unsigned int ratio = dev->config.jpeg_config.ratio;
1352 unsigned int q, q_next, scale;
1354 cif_isp10_pltfrm_pr_dbg(NULL, "ratio %d\n", ratio);
1356 /* Y q-table 0 programming */
1357 cif_iowrite32(CIF_JPE_TAB_ID_QUANT0,
1358 dev->config.base_addr + CIF_JPE_TABLE_ID);
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);
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);
1383 /* U/V q-table 0 programming */
1384 cif_iowrite32(CIF_JPE_TAB_ID_QUANT1,
1385 dev->config.base_addr + CIF_JPE_TABLE_ID);
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);
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);
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);
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);
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);
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);
1454 static void cif_isp10_select_jpeg_tables(
1455 struct cif_isp10_device *dev)
1457 cif_isp10_pltfrm_pr_dbg(NULL, "\n");
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);
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));
1488 static int cif_isp10_config_img_src(
1489 struct cif_isp10_device *dev)
1492 struct isp_supplemental_sensor_mode_data sensor_mode;
1494 cif_isp10_pltfrm_pr_dbg(dev->dev, "\n");
1496 ret = cif_isp10_img_src_set_state(dev,
1497 CIF_ISP10_IMG_SRC_STATE_SW_STNDBY);
1498 if (IS_ERR_VALUE(ret))
1501 if (!dev->sp_stream.updt_cfg &&
1502 !dev->mp_stream.updt_cfg)
1505 ret = cif_isp10_pltfrm_g_interface_config(dev->img_src,
1506 &dev->config.cam_itf);
1507 if (IS_ERR_VALUE(ret))
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;
1515 if ((sensor_mode.exposure_valid_frame < 2) ||
1516 (sensor_mode.exposure_valid_frame > 6))
1517 dev->img_src_exps.exp_valid_frms = 2;
1519 dev->img_src_exps.exp_valid_frms =
1520 sensor_mode.exposure_valid_frame;
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);
1531 cif_isp10_pltfrm_pr_err(dev->dev,
1532 "failed with error %d\n", ret);
1536 static int cif_isp10_config_isp(
1537 struct cif_isp10_device *dev)
1544 u32 isp_input_sel = 0;
1545 u32 isp_bayer_pat = 0;
1549 enum cif_isp10_pix_fmt in_pix_fmt;
1550 struct cif_isp10_frm_fmt *output;
1551 struct pltfrm_cam_itf *cam_itf;
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);
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,
1565 cif_iowrite32OR(CIF_ICCL_ISP_CLK,
1566 dev->config.base_addr + CIF_ICCL);
1568 in_pix_fmt = dev->config.isp_config.input->pix_fmt;
1570 output = &dev->config.isp_config.output;
1571 cam_itf = &dev->config.cam_itf;
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;
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.
1582 dev->config.mi_config.sp.output.
1584 cif_isp10_pltfrm_pr_err(dev->dev,
1585 "colorspace quantization (mp: %d, sp: %d) is not support!\n",
1587 config.mi_config.mp.output.
1590 config.mi_config.sp.output.
1595 if (dev->sp_stream.state == CIF_ISP10_STATE_READY) {
1596 output->quantization =
1597 dev->config.mi_config.sp.output.quantization;
1600 if (dev->mp_stream.state == CIF_ISP10_STATE_READY) {
1601 output->quantization =
1602 dev->config.mi_config.sp.output.quantization;
1606 dev->config.base_addr + CIF_ISP_DEMOSAIC);
1608 if (PLTFRM_CAM_ITF_IS_BT656(dev->config.cam_itf.type)) {
1610 CIF_ISP_CTRL_ISP_MODE_BAYER_ITU656,
1611 dev->config.base_addr + CIF_ISP_CTRL);
1614 CIF_ISP_CTRL_ISP_MODE_BAYER_ITU601,
1615 dev->config.base_addr + CIF_ISP_CTRL);
1618 output->pix_fmt = in_pix_fmt;
1619 if (PLTFRM_CAM_ITF_IS_BT656(dev->config.cam_itf.type)) {
1621 CIF_ISP_CTRL_ISP_MODE_RAW_PICT_ITU656,
1622 dev->config.base_addr + CIF_ISP_CTRL);
1624 cif_iowrite32(CIF_ISP_CTRL_ISP_MODE_RAW_PICT,
1625 dev->config.base_addr + CIF_ISP_CTRL);
1629 bpp = CIF_ISP10_PIX_FMT_GET_BPP(in_pix_fmt);
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;
1637 cif_isp10_pltfrm_pr_err(dev->dev,
1638 "%d bits per pixel not supported\n", bpp);
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;
1651 cif_isp10_pltfrm_pr_err(dev->dev,
1652 "BAYER pattern not supported\n");
1656 } else if (CIF_ISP10_PIX_FMT_IS_YUV(in_pix_fmt)) {
1657 output->pix_fmt = in_pix_fmt;
1659 if (dev->config.input_sel == CIF_ISP10_INP_DMA) {
1660 bpp = CIF_ISP10_PIX_FMT_GET_BPP(in_pix_fmt);
1663 (4 + (CIF_ISP10_PIX_FMT_YUV_GET_X_SUBS(
1665 CIF_ISP10_PIX_FMT_YUV_GET_Y_SUBS(
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;
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),
1681 cif_iowrite32(CIF_ISP_CTRL_ISP_MODE_ITU601,
1682 dev->config.base_addr + CIF_ISP_CTRL);
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)) {
1694 CIF_ISP_CTRL_ISP_MODE_ITU656,
1695 dev->config.base_addr +
1699 CIF_ISP_CTRL_ISP_MODE_ITU601,
1700 dev->config.base_addr +
1704 switch (PLTFRM_CAM_ITF_DVP_BW(
1705 dev->config.cam_itf.type)) {
1708 CIF_ISP_ACQ_PROP_IN_SEL_8B_ZERO;
1712 CIF_ISP_ACQ_PROP_IN_SEL_10B_ZERO;
1716 CIF_ISP_ACQ_PROP_IN_SEL_12B;
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));
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));
1732 * ISP DATA LOSS is only meaningful
1733 * when input is not DMA
1735 irq_mask |= CIF_ISP_DATA_LOSS;
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;
1743 yuv_seq = CIF_ISP_ACQ_PROP_YCBYCR;
1746 cif_isp10_pltfrm_pr_err(dev->dev,
1747 "format %s not supported\n",
1748 cif_isp10_pix_fmt_string(in_pix_fmt));
1753 /* Set up input acquisition properties*/
1754 if (PLTFRM_CAM_ITF_IS_DVP(cam_itf->type)) {
1756 ((cam_itf->cfg.dvp.pclk == PLTFRM_CAM_SDR_POS_EDG) ?
1757 CIF_ISP_ACQ_PROP_POS_EDGE : CIF_ISP_ACQ_PROP_NEG_EDGE);
1759 if (PLTFRM_CAM_ITF_IS_BT601(cam_itf->type)) {
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;
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;
1773 signal |= CIF_ISP_ACQ_PROP_HSYNC_HIGH |
1774 CIF_ISP_ACQ_PROP_VSYNC_HIGH;
1777 signal = CIF_ISP_ACQ_PROP_NEG_EDGE |
1778 CIF_ISP_ACQ_PROP_HSYNC_HIGH |
1779 CIF_ISP_ACQ_PROP_VSYNC_HIGH;
1782 cif_iowrite32(signal |
1784 CIF_ISP_ACQ_PROP_FIELD_SEL_ALL |
1787 (0 << 20), /* input_selection_no_app */
1788 dev->config.base_addr + CIF_ISP_ACQ_PROP);
1790 dev->config.base_addr + CIF_ISP_ACQ_NR_FRAMES);
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);
1798 acq_mult * dev->config.isp_config.input->defrect.width,
1799 dev->config.base_addr + CIF_ISP_ACQ_H_SIZE);
1801 dev->config.isp_config.input->defrect.height,
1802 dev->config.base_addr + CIF_ISP_ACQ_V_SIZE);
1804 /* do cropping to match output aspect ratio */
1805 ret = cif_isp10_calc_isp_cropping(dev,
1806 &output->width, &output->height,
1808 if (IS_ERR_VALUE(ret))
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);
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;
1825 /* interrupt mask */
1828 CIF_ISP_PIC_SIZE_ERROR |
1831 cif_iowrite32(irq_mask,
1832 dev->config.base_addr + CIF_ISP_IMSC);
1834 if (!dev->config.mi_config.raw_enable)
1835 cifisp_configure_isp(&dev->isp_dev,
1837 output->quantization);
1839 cifisp_disable_isp(&dev->isp_dev);
1841 cif_isp10_pltfrm_pr_dbg(
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));
1867 cif_isp10_pltfrm_pr_err(dev->dev,
1868 "failed with error %d\n", ret);
1872 static int cif_isp10_config_mipi(
1873 struct cif_isp10_device *dev)
1880 enum cif_isp10_pix_fmt in_pix_fmt;
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,
1889 cif_iowrite32OR(CIF_ICCL_MIPI_CLK,
1890 dev->config.base_addr + CIF_ICCL);
1892 in_pix_fmt = dev->config.img_src_output.frm_fmt.pix_fmt;
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);
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);
1909 shutdown_lanes = 0x00;
1910 for (i = 0; i < dev->config.cam_itf.cfg.mipi.nb_lanes; i++)
1911 shutdown_lanes |= (1 << i);
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;
1923 cif_iowrite32(mipi_ctrl,
1924 dev->config.base_addr + CIF_MIPI_CTRL);
1927 cif_isp10_pltfrm_mipi_dphy_config(dev);
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;
1948 cif_isp10_pltfrm_pr_err(dev->dev,
1949 "unsupported format %s\n",
1950 cif_isp10_pix_fmt_string(in_pix_fmt));
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;
1962 cif_isp10_pltfrm_pr_err(dev->dev,
1963 "unsupported format %s\n",
1964 cif_isp10_pix_fmt_string(in_pix_fmt));
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;
1975 cif_isp10_pltfrm_pr_err(dev->dev,
1976 "unsupported format %s\n",
1977 cif_isp10_pix_fmt_string(in_pix_fmt));
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);
1988 /* Enable MIPI interrupts */
1990 dev->config.base_addr + CIF_MIPI_ICR);
1992 * Disable CIF_MIPI_ERR_DPHY interrupt here temporary for
1993 * isp bus may be dead when switch isp.
1996 CIF_MIPI_FRAME_END |
1999 CIF_MIPI_SYNC_FIFO_OVFLW(3) |
2000 CIF_MIPI_ADD_DATA_OVFLW,
2001 dev->config.base_addr + CIF_MIPI_IMSC);
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));
2015 cif_isp10_pltfrm_pr_err(dev->dev,
2016 "failed with error %d\n", ret);
2020 static int cif_isp10_config_mi_mp(
2021 struct cif_isp10_device *dev)
2023 enum cif_isp10_pix_fmt out_pix_fmt =
2024 dev->config.mi_config.mp.output.pix_fmt;
2026 dev->config.mi_config.mp.llength;
2028 dev->config.mi_config.mp.output.width;
2030 dev->config.mi_config.mp.output.height;
2031 u32 writeformat = CIF_ISP10_BUFF_FMT_PLANAR;
2033 u32 bpp = CIF_ISP10_PIX_FMT_GET_BPP(out_pix_fmt);
2034 u32 size = llength * height * bpp / 8;
2037 dev->config.mi_config.mp.input =
2038 &dev->config.mp_config.rsz_config.output;
2040 cif_isp10_pltfrm_pr_dbg(dev->dev,
2041 "%s %dx%d, llength = %d\n",
2042 cif_isp10_pix_fmt_string(out_pix_fmt),
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)) {
2052 CIF_ISP10_PIX_FMT_YUV_GET_NUM_CPLANES(out_pix_fmt);
2053 if (num_cplanes == 0) {
2054 writeformat = CIF_ISP10_BUFF_FMT_INTERLEAVED;
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(
2060 CIF_ISP10_PIX_FMT_YUV_GET_Y_SUBS(
2062 dev->config.mi_config.mp.cb_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;
2071 /* for U<->V swapping: */
2072 dev->config.mi_config.mp.cr_size =
2073 dev->config.mi_config.mp.cb_size;
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;
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) {
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;
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;
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;
2104 writeformat = CIF_ISP10_BUFF_FMT_RAW8;
2105 dev->config.mi_config.mp.y_size = width * height;
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;
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 +
2127 cif_iowrite32OR(swap_cb_cr,
2128 dev->config.base_addr + CIF_MI_XTD_FORMAT_CTRL);
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;
2139 cif_iowrite32_verify(mi_ctrl,
2140 dev->config.base_addr + CIF_MI_CTRL, ~0);
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 +
2150 cif_ioread32(dev->config.base_addr +
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));
2162 static int cif_isp10_config_mi_sp(
2163 struct cif_isp10_device *dev)
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;
2171 dev->config.mi_config.sp.llength;
2173 dev->config.mi_config.sp.output.width;
2175 dev->config.mi_config.sp.output.height;
2176 u32 writeformat = CIF_ISP10_BUFF_FMT_PLANAR;
2178 u32 bpp = CIF_ISP10_PIX_FMT_GET_BPP(out_pix_fmt);
2179 u32 size = llength * height * bpp / 8;
2180 u32 input_format = 0;
2184 dev->config.mi_config.sp.input =
2185 &dev->config.sp_config.rsz_config.output;
2187 cif_isp10_pltfrm_pr_dbg(dev->dev,
2188 "%s %dx%d, llength = %d\n",
2189 cif_isp10_pix_fmt_string(out_pix_fmt),
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));
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)) {
2207 CIF_ISP10_PIX_FMT_YUV_GET_NUM_CPLANES(out_pix_fmt);
2208 if (num_cplanes == 0) {
2209 writeformat = CIF_ISP10_BUFF_FMT_INTERLEAVED;
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(
2215 CIF_ISP10_PIX_FMT_YUV_GET_Y_SUBS(
2217 dev->config.mi_config.sp.cb_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;
2226 /* for U<->V swapping: */
2227 dev->config.mi_config.sp.cr_size =
2228 dev->config.mi_config.sp.cb_size;
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;
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;
2246 cif_isp10_pltfrm_pr_err(dev->dev,
2247 "unsupported YUV output format %s\n",
2248 cif_isp10_pix_fmt_string(out_pix_fmt));
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;
2260 cif_isp10_pltfrm_pr_err(dev->dev,
2261 "unsupported RGB output format %s\n",
2262 cif_isp10_pix_fmt_string(out_pix_fmt));
2267 cif_isp10_pltfrm_pr_err(dev->dev,
2268 "unsupported output format %s\n",
2269 cif_isp10_pix_fmt_string(out_pix_fmt));
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;
2287 cif_isp10_pltfrm_pr_err(dev->dev,
2288 "unsupported YUV input format %s\n",
2289 cif_isp10_pix_fmt_string(in_pix_fmt));
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) {
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;
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;
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 +
2339 cif_iowrite32OR(swap_cb_cr,
2340 dev->config.base_addr + CIF_MI_XTD_FORMAT_CTRL);
2343 mi_ctrl = cif_ioread32(dev->config.base_addr + CIF_MI_CTRL) |
2344 CIF_MI_CTRL_SP_WRITE_FMT(writeformat) |
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);
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));
2377 cif_isp10_pltfrm_pr_err(dev->dev,
2378 "failed with error %d\n", ret);
2382 static int cif_isp10_config_mi_dma(
2383 struct cif_isp10_device *dev)
2386 enum cif_isp10_pix_fmt out_pix_fmt =
2387 dev->config.mi_config.dma.output.pix_fmt;
2389 dev->config.mi_config.dma.llength;
2391 dev->config.mi_config.dma.output.width;
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;
2400 cif_isp10_pltfrm_pr_dbg(dev->dev,
2401 "%s %dx%d, llength = %d\n",
2402 cif_isp10_pix_fmt_string(out_pix_fmt),
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)) {
2412 CIF_ISP10_PIX_FMT_YUV_GET_NUM_CPLANES(out_pix_fmt);
2413 if (num_cplanes == 0) {
2414 readformat = CIF_ISP10_BUFF_FMT_INTERLEAVED;
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(
2420 CIF_ISP10_PIX_FMT_YUV_GET_Y_SUBS(
2422 dev->config.mi_config.dma.cb_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;
2431 /* for U<->V swapping: */
2432 dev->config.mi_config.dma.cr_size =
2433 dev->config.mi_config.dma.cb_size;
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;
2449 cif_isp10_pltfrm_pr_err(dev->dev,
2450 "unsupported YUV output format %s\n",
2451 cif_isp10_pix_fmt_string(out_pix_fmt));
2456 cif_isp10_pltfrm_pr_err(dev->dev,
2457 "unsupported output format %s\n",
2458 cif_isp10_pix_fmt_string(out_pix_fmt));
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;
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);
2483 mi_ctrl = cif_ioread32(dev->config.base_addr + CIF_MI_DMA_CTRL) |
2484 CIF_MI_DMA_CTRL_READ_FMT(readformat) |
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);
2491 cif_iowrite32OR_verify(CIF_MI_DMA_READY,
2492 dev->config.base_addr + CIF_MI_IMSC, ~0);
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 +
2505 cif_ioread32(dev->config.base_addr +
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));
2522 cif_isp10_pltfrm_pr_err(dev->dev,
2523 "failed with error %d\n", ret);
2527 static int cif_isp10_config_jpeg_enc(
2528 struct cif_isp10_device *dev)
2530 struct cif_isp10_frm_fmt *inp_fmt =
2531 &dev->config.mp_config.rsz_config.output;
2532 dev->config.jpeg_config.input = inp_fmt;
2534 cif_isp10_pltfrm_pr_dbg(NULL,
2536 cif_isp10_pix_fmt_string(inp_fmt->pix_fmt),
2537 inp_fmt->width, inp_fmt->height);
2540 * Reset JPEG-Encoder. In contrast to other software
2541 * resets this triggers the modules asynchronous reset
2542 * resulting in loss of all data
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);
2549 cif_iowrite32(CIF_JPE_ERROR_MASK,
2550 dev->config.base_addr + CIF_JPE_ERROR_IMSC);
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);
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)) {
2562 * upscaling of BT601 color space to full range 0..255
2563 * TODO: DMA or YUV sensor input in full range.
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);
2571 switch (inp_fmt->pix_fmt) {
2578 cif_iowrite32(CIF_JPE_PIC_FORMAT_YUV422,
2579 dev->config.base_addr + CIF_JPE_PIC_FORMAT);
2583 cif_iowrite32(CIF_JPE_PIC_FORMAT_YUV400,
2584 dev->config.base_addr + CIF_JPE_PIC_FORMAT);
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));
2595 * Set to normal operation (wait for encoded image data
2596 * to fill output buffer)
2598 cif_iowrite32(0, dev->config.base_addr + CIF_JPE_TABLE_FLUSH);
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
2618 /* Program JPEG tables */
2619 cif_isp10_program_jpeg_tables(dev);
2620 /* Select JPEG tables */
2621 cif_isp10_select_jpeg_tables(dev);
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);
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);
2639 cif_isp10_pltfrm_pr_err(NULL,
2640 "unknown/unsupport JPEG header type %d\n",
2641 dev->config.jpeg_config.header);
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));
2671 static int cif_isp10_config_path(
2672 struct cif_isp10_device *dev,
2677 cif_isp10_pltfrm_pr_dbg(dev->dev, "\n");
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;
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;
2693 cif_isp10_pltfrm_pr_err(dev->dev,
2694 "Sensor Interface: 0x%x isn't support\n",
2695 dev->config.cam_itf.type);
2701 if (stream_ids & CIF_ISP10_STREAM_SP)
2702 dpcl |= CIF_VI_DPCL_CHAN_MODE_SP;
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;
2708 if (dev->config.jpeg_config.enable)
2709 dpcl |= CIF_VI_DPCL_MP_MUX_MRSZ_JPEG;
2711 dpcl |= CIF_VI_DPCL_MP_MUX_MRSZ_MI;
2715 dev->config.base_addr + CIF_VI_DPCL);
2717 cif_isp10_pltfrm_pr_dbg(dev->dev, "CIF_DPCL 0x%08x\n", dpcl);
2722 int cif_isp10_config_dcrop(
2723 struct cif_isp10_device *dev,
2724 enum cif_isp10_stream_id stream_id,
2727 unsigned int dc_ctrl = cif_ioread32(
2728 dev->config.base_addr +
2729 CIF_DUAL_CROP_CTRL);
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);
2741 dc_ctrl |= CIF_DUAL_CROP_MP_MODE_BYPASS;
2743 dc_ctrl |= CIF_DUAL_CROP_GEN_CFG_UPD;
2745 dc_ctrl |= CIF_DUAL_CROP_CFG_UPD;
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);
2759 dc_ctrl |= CIF_DUAL_CROP_MP_MODE_BYPASS;
2761 dc_ctrl |= CIF_DUAL_CROP_GEN_CFG_UPD;
2763 dc_ctrl |= CIF_DUAL_CROP_CFG_UPD;
2765 cif_iowrite32(dc_ctrl,
2766 dev->config.base_addr + CIF_DUAL_CROP_CTRL);
2772 int cif_isp10_config_rsz(
2773 struct cif_isp10_device *dev,
2774 enum cif_isp10_stream_id stream_id,
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;
2798 u32 output_height_y;
2802 u32 output_height_c;
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++) {
2825 dev->config.base_addr +
2826 CIF_MRSZ_SCALE_LUT_ADDR);
2828 dev->config.base_addr +
2829 CIF_MRSZ_SCALE_LUT);
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;
2842 dev->config.sp_config.rsz_config.input =
2843 &dev->config.isp_config.output;
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++) {
2856 dev->config.base_addr +
2857 CIF_SRSZ_SCALE_LUT_ADDR);
2859 dev->config.base_addr +
2860 CIF_SRSZ_SCALE_LUT);
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);
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),
2893 cif_isp10_pix_fmt_string(rsz_output->pix_fmt),
2895 rsz_output->height);
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;
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;
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);
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");
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);
2945 /* calculate and set scale */
2947 if (input_width_y < output_width_y) {
2948 rsz_ctrl |= CIF_RSZ_CTRL_SCALE_HY_ENABLE |
2949 CIF_RSZ_CTRL_SCALE_HY_UP;
2951 DIV_TRUNCATE((input_width_y - 1)
2952 * CIF_RSZ_SCALER_BYPASS,
2953 output_width_y - 1),
2955 } else if (input_width_y > output_width_y) {
2956 rsz_ctrl |= CIF_RSZ_CTRL_SCALE_HY_ENABLE;
2958 DIV_TRUNCATE((output_width_y - 1)
2959 * CIF_RSZ_SCALER_BYPASS,
2960 input_width_y - 1) + 1,
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);
2980 if (input_height_y < output_height_y) {
2981 rsz_ctrl |= CIF_RSZ_CTRL_SCALE_VY_ENABLE |
2982 CIF_RSZ_CTRL_SCALE_VY_UP;
2984 DIV_TRUNCATE((input_height_y - 1)
2985 * CIF_RSZ_SCALER_BYPASS,
2986 output_height_y - 1),
2988 } else if (input_height_y > output_height_y) {
2989 rsz_ctrl |= CIF_RSZ_CTRL_SCALE_VY_ENABLE;
2991 DIV_TRUNCATE((output_height_y - 1)
2992 * CIF_RSZ_SCALER_BYPASS,
2993 input_height_y - 1) + 1,
2997 if (input_height_c < output_height_c) {
2998 rsz_ctrl |= CIF_RSZ_CTRL_SCALE_VC_ENABLE |
2999 CIF_RSZ_CTRL_SCALE_VC_UP;
3001 DIV_TRUNCATE((input_height_c - 1)
3002 * CIF_RSZ_SCALER_BYPASS,
3003 output_height_c - 1),
3005 } else if (input_height_c > output_height_c) {
3006 rsz_ctrl |= CIF_RSZ_CTRL_SCALE_VC_ENABLE;
3008 DIV_TRUNCATE((output_height_c - 1)
3009 * CIF_RSZ_SCALER_BYPASS,
3010 input_height_c - 1) + 1,
3014 cif_iowrite32(rsz_ctrl, rsz_ctrl_addr);
3016 if (stream_id == CIF_ISP10_STREAM_MP) {
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 +
3035 cif_ioread32(dev->config.base_addr +
3037 cif_ioread32(dev->config.base_addr +
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 +
3051 cif_ioread32(dev->config.base_addr +
3052 CIF_MRSZ_SCALE_VY_SHD),
3053 cif_ioread32(dev->config.base_addr +
3055 cif_ioread32(dev->config.base_addr +
3056 CIF_MRSZ_SCALE_VC_SHD),
3057 cif_ioread32(dev->config.base_addr +
3059 cif_ioread32(dev->config.base_addr +
3060 CIF_MRSZ_PHASE_HY_SHD),
3061 cif_ioread32(dev->config.base_addr +
3063 cif_ioread32(dev->config.base_addr +
3064 CIF_MRSZ_PHASE_HC_SHD),
3065 cif_ioread32(dev->config.base_addr +
3067 cif_ioread32(dev->config.base_addr +
3068 CIF_MRSZ_PHASE_VY_SHD),
3069 cif_ioread32(dev->config.base_addr +
3071 cif_ioread32(dev->config.base_addr +
3072 CIF_MRSZ_PHASE_VC_SHD));
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 +
3092 cif_ioread32(dev->config.base_addr +
3094 cif_ioread32(dev->config.base_addr +
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 +
3108 cif_ioread32(dev->config.base_addr +
3109 CIF_SRSZ_SCALE_VY_SHD),
3110 cif_ioread32(dev->config.base_addr +
3112 cif_ioread32(dev->config.base_addr +
3113 CIF_SRSZ_SCALE_VC_SHD),
3114 cif_ioread32(dev->config.base_addr +
3116 cif_ioread32(dev->config.base_addr +
3117 CIF_SRSZ_PHASE_HY_SHD),
3118 cif_ioread32(dev->config.base_addr +
3120 cif_ioread32(dev->config.base_addr +
3121 CIF_SRSZ_PHASE_HC_SHD),
3122 cif_ioread32(dev->config.base_addr +
3124 cif_ioread32(dev->config.base_addr +
3125 CIF_SRSZ_PHASE_VY_SHD),
3126 cif_ioread32(dev->config.base_addr +
3128 cif_ioread32(dev->config.base_addr +
3129 CIF_SRSZ_PHASE_VC_SHD));
3134 cif_isp10_pltfrm_pr_err(dev->dev,
3135 "failed with err %d\n", ret);
3139 static int cif_isp10_config_sp(
3140 struct cif_isp10_device *dev)
3144 cif_isp10_pltfrm_pr_dbg(NULL, "\n");
3146 ret = cif_isp10_config_rsz(dev, CIF_ISP10_STREAM_SP, true);
3147 if (IS_ERR_VALUE(ret))
3150 ret = cif_isp10_config_dcrop(dev, CIF_ISP10_STREAM_SP, true);
3151 if (IS_ERR_VALUE(ret))
3154 ret = cif_isp10_config_mi_sp(dev);
3155 if (IS_ERR_VALUE(ret))
3158 dev->sp_stream.updt_cfg = false;
3162 cif_isp10_pltfrm_pr_err(dev->dev,
3163 "failed with error %d\n", ret);
3167 static int cif_isp10_config_mp(
3168 struct cif_isp10_device *dev)
3172 cif_isp10_pltfrm_pr_dbg(NULL, "\n");
3174 ret = cif_isp10_config_rsz(dev, CIF_ISP10_STREAM_MP, true);
3175 if (IS_ERR_VALUE(ret))
3178 ret = cif_isp10_config_dcrop(dev, CIF_ISP10_STREAM_MP, true);
3179 if (IS_ERR_VALUE(ret))
3182 ret = cif_isp10_config_mi_mp(dev);
3183 if (IS_ERR_VALUE(ret))
3185 if (dev->config.jpeg_config.enable) {
3186 ret = cif_isp10_config_jpeg_enc(dev);
3187 if (IS_ERR_VALUE(ret))
3189 dev->config.jpeg_config.busy = false;
3192 dev->mp_stream.updt_cfg = false;
3196 cif_isp10_pltfrm_pr_err(dev->dev,
3197 "failed with error %d\n", ret);
3201 static void cif_isp10_config_clk(
3202 struct cif_isp10_device *dev)
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);
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));
3215 static int cif_isp10_config_cif(
3216 struct cif_isp10_device *dev,
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));
3231 cif_isp10_pltfrm_rtrace_printf(NULL,
3232 "start configuring CIF...\n");
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))
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))
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;
3252 cif_isp10_pltfrm_pr_dbg(dev->dev,
3253 "CIF_ID 0x%08x\n", cif_id);
3256 * Cancel isp reset internal here temporary for
3257 * isp bus may be dead when switch isp.
3260 * cif_iowrite32(CIF_IRCL_CIF_SW_RST,
3261 * dev->config.base_addr + CIF_IRCL);
3264 cif_isp10_config_clk(dev);
3266 /* Decide when to switch to asynchronous mode */
3268 * TODO: remove dev->isp_dev.ycflt_en check for
3269 * HW with the scaler fix.
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))
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;
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))
3292 ret = cif_isp10_config_isp(dev);
3293 if (IS_ERR_VALUE(ret))
3296 cif_isp10_config_ism(dev, true);
3297 dev->config.isp_config.ism_config.ism_update_needed = false;
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;
3304 if (stream_ids & CIF_ISP10_STREAM_SP) {
3305 ret = cif_isp10_config_sp(dev);
3306 if (IS_ERR_VALUE(ret))
3310 if (stream_ids & CIF_ISP10_STREAM_MP) {
3311 ret = cif_isp10_config_mp(dev);
3312 if (IS_ERR_VALUE(ret))
3315 ret = cif_isp10_config_path(dev, stream_ids);
3316 if (IS_ERR_VALUE(ret))
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;
3325 if (dev->isp_dev.cif_ism_cropping)
3326 dev->isp_dev.cif_ism_cropping = false;
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))
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;
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))
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;
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);
3370 cif_isp10_pltfrm_pr_err(dev->dev,
3371 "failed with error %d\n", ret);
3375 static void cif_isp10_init_stream(
3376 struct cif_isp10_device *dev,
3377 enum cif_isp10_stream_id stream_id)
3379 struct cif_isp10_stream *stream = NULL;
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;
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;
3399 case CIF_ISP10_STREAM_DMA:
3400 stream = &dev->dma_stream;
3401 dev->config.mi_config.dma.busy = false;
3404 cif_isp10_pltfrm_pr_err(NULL,
3405 "unknown/unsupported stream ID %d\n", stream_id);
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;
3417 cif_isp10_pltfrm_event_clear(dev->dev, &stream->done);
3418 stream->state = CIF_ISP10_STATE_INACTIVE;
3421 static int cif_isp10_jpeg_gen_header(
3422 struct cif_isp10_device *dev)
3424 unsigned int timeout = 10000;
3426 cif_isp10_pltfrm_pr_dbg(NULL, "\n");
3428 cif_iowrite32(CIF_JPE_GEN_HEADER_ENABLE,
3429 dev->config.base_addr + CIF_JPE_GEN_HEADER);
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);
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);
3451 #ifdef CIF_ISP10_VERIFY_JPEG_HEADER
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",
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));
3473 static void cif_isp10_mi_update_buff_addr(
3474 struct cif_isp10_device *dev,
3475 enum cif_isp10_stream_id strm_id)
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);
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
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);
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
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));
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));
3597 static int cif_isp10_update_mi_mp(
3598 struct cif_isp10_device *dev)
3601 enum cif_isp10_pix_fmt out_pix_fmt =
3602 dev->config.mi_config.mp.output.pix_fmt;
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);
3609 if (dev->config.jpeg_config.enable) {
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
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))
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 +
3632 dev->config.jpeg_config.busy = true;
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;
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) {
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,
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 +
3668 if (CIF_ISP10_PIX_FMT_IS_RAW_BAYER
3670 cif_iowrite32OR_verify(
3671 CIF_MI_CTRL_RAW_ENABLE,
3672 dev->config.base_addr +
3675 } else if (CIF_ISP10_PIX_FMT_IS_YUV
3677 cif_iowrite32OR_verify(
3678 CIF_MI_CTRL_MP_ENABLE_IN,
3679 dev->config.base_addr +
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;
3691 cif_isp10_pltfrm_pr_err(dev->dev,
3692 "failed with err %d\n", ret);
3696 static int cif_isp10_update_mi_sp(
3697 struct cif_isp10_device *dev)
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);
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) {
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);
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;
3730 static int cif_isp10_s_fmt_mp(
3731 struct cif_isp10_device *dev,
3732 struct cif_isp10_strm_fmt *strm_fmt,
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,
3745 strm_fmt->frm_fmt.quantization);
3747 /* TBD: check whether format is a valid format for MP */
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;
3760 dev->config.mi_config.mp.output = strm_fmt->frm_fmt;
3761 dev->config.mi_config.mp.output.stride = stride;
3763 dev->config.mi_config.mp.llength =
3764 cif_isp10_calc_llength(
3765 strm_fmt->frm_fmt.width,
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);
3771 dev->mp_stream.updt_cfg = true;
3772 dev->mp_stream.state = CIF_ISP10_STATE_READY;
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;
3785 cif_isp10_pltfrm_pr_err(dev->dev,
3786 "failed with error %d\n", ret);
3790 static int cif_isp10_s_fmt_sp(
3791 struct cif_isp10_device *dev,
3792 struct cif_isp10_strm_fmt *strm_fmt,
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,
3805 strm_fmt->frm_fmt.quantization);
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");
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,
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,
3832 strm_fmt->frm_fmt.pix_fmt);
3834 dev->sp_stream.updt_cfg = true;
3835 dev->sp_stream.state = CIF_ISP10_STATE_READY;
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;
3848 cif_isp10_pltfrm_pr_err(dev->dev,
3849 "failed with error %d\n", ret);
3853 static int cif_isp10_s_fmt_dma(
3854 struct cif_isp10_device *dev,
3855 struct cif_isp10_strm_fmt *strm_fmt,
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,
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,
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,
3888 strm_fmt->frm_fmt.pix_fmt);
3890 dev->dma_stream.updt_cfg = true;
3891 dev->dma_stream.state = CIF_ISP10_STATE_READY;
3895 cif_isp10_pltfrm_pr_err(dev->dev,
3896 "failed with error %d\n", ret);
3900 static void cif_isp10_dma_next_buff(
3901 struct cif_isp10_device *dev)
3903 cif_isp10_pltfrm_pr_dbg(NULL, "\n");
3905 if (!list_empty(&dev->dma_stream.buf_queue) &&
3906 !dev->dma_stream.stop) {
3907 if (dev->dma_stream.curr_buf)
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 */
3928 cif_iowrite32(CIF_MI_DMA_START_ENABLE,
3929 dev->config.base_addr + CIF_MI_DMA_START);
3931 } while (!cif_ioread32(
3932 dev->config.base_addr + CIF_MI_DMA_STATUS));
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 +
3940 cif_ioread32(dev->config.base_addr +
3941 CIF_MI_DMA_STATUS));
3944 static void cif_isp10_dma_ready(
3945 struct cif_isp10_device *dev)
3947 unsigned int mi_mis_tmp;
3949 cif_isp10_pltfrm_pr_dbg(NULL, "\n");
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",
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);
3965 static int cif_isp10_mi_frame_end(
3966 struct cif_isp10_device *dev,
3967 enum cif_isp10_stream_id stream_id)
3969 struct cif_isp10_stream *stream = NULL;
3970 u32 *next_buff_addr = NULL;
3971 CIF_ISP10_PLTFRM_MEM_IO_ADDR y_base_addr;
3973 struct cif_isp10_device *dev);
3974 struct cif_isp10_isp_readout_work *work;
3976 cif_isp10_pltfrm_pr_dbg(NULL, "%s\n",
3977 cif_isp10_stream_id_string(stream_id));
3979 if (stream_id == CIF_ISP10_STREAM_MP) {
3980 stream = &dev->mp_stream;
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 +
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.
4007 dev->config.base_addr +
4008 CIF_MI_MP_Y_SIZE_SHD),
4009 stream->curr_buf->size);
4013 } else if (stream_id == CIF_ISP10_STREAM_SP) {
4014 stream = &dev->sp_stream;
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;
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));
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;
4052 if (!stream->stall) {
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;
4059 if ((stream->curr_buf) &&
4060 (stream->next_buf)) {
4063 stream->curr_buf->field_count = dev->isp_dev.frame_id;
4064 stream->curr_buf->state = VIDEOBUF_DONE;
4067 if (stream->metadata.d && dev->isp_dev.streamon) {
4068 struct v4l2_buffer_metadata_s *metadata;
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;
4078 work = (struct cif_isp10_isp_readout_work *)
4081 struct cif_isp10_isp_readout_work),
4084 INIT_WORK((struct work_struct *)work,
4085 cifisp_isp_readout_work);
4087 CIF_ISP10_ISP_READOUT_META;
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(
4098 "Could not schedule work\n");
4100 kfree((void *)work);
4103 cif_isp10_pltfrm_pr_err(dev->dev,
4104 "Could not allocate work\n");
4112 cif_isp10_pltfrm_pr_dbg(NULL,
4114 wake_up(&stream->curr_buf->done);
4116 stream->curr_buf = NULL;
4119 if (!stream->curr_buf) {
4120 stream->curr_buf = stream->next_buf;
4121 stream->next_buf = NULL;
4125 if (!stream->next_buf) {
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
4132 if (!list_empty(&stream->buf_queue)) {
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(
4141 !dev->config.out_of_buffer_stall ||
4142 (dev->config.jpeg_config.enable &&
4143 (stream_id == CIF_ISP10_STREAM_MP))) {
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;
4151 * *next_buff_addr = CIF_ISP10_INVALID_BUFF_ADDR;
4155 videobuf_to_dma_contig(
4159 (void)update_mi(dev);
4161 stream->stall = false;
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,
4175 static void cif_isp10_stream_metadata_reset(
4176 struct cif_isp10_stream *stream_dev
4180 struct v4l2_buffer_metadata_s *metadata;
4181 struct cifisp_isp_metadata *isp_metadata;
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 *)
4190 isp_metadata->other_cfg.s_frame_id = 0xffffffff;
4191 isp_metadata->meas_cfg.s_frame_id = 0xffffffff;
4196 static void cif_isp10_start_mi(
4197 struct cif_isp10_device *dev,
4201 cif_isp10_pltfrm_pr_dbg(dev->dev, "\n");
4204 (dev->sp_stream.state == CIF_ISP10_STATE_STREAMING))
4205 start_mi_sp = false;
4207 (dev->mp_stream.state == CIF_ISP10_STATE_STREAMING))
4208 start_mi_mp = false;
4209 if (!start_mi_sp && !start_mi_mp)
4213 (dev->mp_stream.state == CIF_ISP10_STATE_STREAMING)) ||
4215 (dev->sp_stream.state == CIF_ISP10_STATE_STREAMING)))
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;
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;
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");
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;
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;
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);
4270 static void cif_isp10_stop_mi(
4271 struct cif_isp10_device *dev,
4275 cif_isp10_pltfrm_pr_dbg(dev->dev, "\n");
4278 (dev->sp_stream.state != CIF_ISP10_STATE_STREAMING))
4281 (dev->mp_stream.state != CIF_ISP10_STATE_STREAMING))
4284 if (!stop_mi_sp && !stop_mi_mp)
4287 if (stop_mi_sp && stop_mi_mp) {
4288 cif_iowrite32AND_verify(~(CIF_MI_SP_FRAME |
4290 CIF_JPE_STATUS_ENCODE_DONE),
4291 dev->config.base_addr + CIF_MI_IMSC, ~0);
4292 cif_iowrite32(CIF_MI_SP_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);
4321 static void cif_isp10_requeue_bufs(
4322 struct cif_isp10_device *dev,
4323 struct cif_isp10_stream *stream)
4325 INIT_LIST_HEAD(&stream->buf_queue);
4326 stream->next_buf = NULL;
4327 stream->curr_buf = NULL;
4328 dev->requeue_bufs(dev, stream->id);
4331 static void cif_isp10_stop_sp(
4332 struct cif_isp10_device *dev)
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,
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",
4350 if (dev->config.mi_config.sp.busy)
4351 cif_isp10_pltfrm_pr_warn(NULL,
4352 "SP path still active while stopping it\n");
4356 static void cif_isp10_stop_mp(
4357 struct cif_isp10_device *dev)
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,
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",
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");
4382 static void cif_isp10_stop_dma(
4383 struct cif_isp10_device *dev)
4385 unsigned long flags = 0;
4387 cif_isp10_pltfrm_pr_dbg(NULL, "\n");
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,
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);
4409 static int cif_isp10_stop(
4410 struct cif_isp10_device *dev,
4414 unsigned long flags = 0;
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),
4427 (dev->mp_stream.state == CIF_ISP10_STATE_STREAMING)) ||
4429 (dev->sp_stream.state == CIF_ISP10_STATE_STREAMING)))) {
4433 stop_all = ((stop_mp && stop_sp) ||
4435 (dev->mp_stream.state != CIF_ISP10_STATE_STREAMING)) ||
4437 (dev->sp_stream.state != CIF_ISP10_STATE_STREAMING)));
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
4446 cif_isp10_stop_mp(dev);
4447 cif_isp10_stop_sp(dev);
4448 cif_isp10_stop_dma(dev);
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);
4455 cif_iowrite32(0, dev->config.base_addr + CIF_ISP_IMSC);
4456 cif_iowrite32(~0, dev->config.base_addr + CIF_ISP_ICR);
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);
4462 cif_iowrite32AND(~CIF_MIPI_CTRL_OUTPUT_ENA,
4463 dev->config.base_addr + CIF_MIPI_CTRL);
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);
4472 while ((timeout-- > 0) &&
4473 ((cif_ioread32(dev->config.base_addr + CIF_ISP_RIS)
4474 & CIF_ISP_OFF) != CIF_ISP_OFF)) {
4477 local_irq_restore(flags);
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");
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);
4495 cif_isp10_stop_sp(dev);
4496 cif_iowrite32AND_verify(~CIF_MI_SP_FRAME,
4497 dev->config.base_addr + CIF_MI_IMSC, ~0);
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);
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);
4511 if (stop_mp && (dev->mp_stream.state == CIF_ISP10_STATE_STREAMING))
4512 dev->mp_stream.state = CIF_ISP10_STATE_READY;
4514 if (stop_sp && (dev->sp_stream.state == CIF_ISP10_STATE_STREAMING))
4515 dev->sp_stream.state = CIF_ISP10_STATE_READY;
4517 spin_lock(&dev->vbq_lock);
4519 dev->config.mi_config.sp.busy = false;
4520 cif_isp10_requeue_bufs(dev, &dev->sp_stream);
4523 dev->config.mi_config.mp.busy = false;
4524 cif_isp10_requeue_bufs(dev, &dev->mp_stream);
4526 spin_unlock(&dev->vbq_lock);
4528 cif_isp10_pltfrm_pr_dbg(dev->dev,
4529 "SP state = %s, MP state = %s, DMA state = %s, img_src state = %s\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));
4544 static int cif_isp10_start(
4545 struct cif_isp10_device *dev,
4550 struct videobuf_buffer *vb, *n;
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),
4562 (dev->mp_stream.state != CIF_ISP10_STATE_STREAMING)) ||
4564 (dev->sp_stream.state != CIF_ISP10_STATE_STREAMING))))
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");
4576 cif_isp10_start_mi(dev, start_sp, start_mp);
4578 if ((dev->sp_stream.state != CIF_ISP10_STATE_STREAMING) &&
4579 (dev->mp_stream.state != CIF_ISP10_STATE_STREAMING)) {
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);
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);
4594 (dev->sp_stream.state != CIF_ISP10_STATE_STREAMING)) {
4595 dev->sp_stream.state = CIF_ISP10_STATE_STREAMING;
4598 (dev->mp_stream.state != CIF_ISP10_STATE_STREAMING)) {
4599 dev->mp_stream.state = CIF_ISP10_STATE_STREAMING;
4601 ret = cif_isp10_set_pm_state(dev,
4602 CIF_ISP10_PM_STATE_STREAMING);
4603 if (IS_ERR_VALUE(ret))
4606 if (!CIF_ISP10_INP_IS_DMA(dev->config.input_sel)) {
4608 * CIF spec says to wait for sufficient time after enabling
4609 * the MIPI interface and before starting the sensor output.
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(
4622 "discard vb: %d\n", vb->i);
4625 videobuf_queue_unlock(&dev->isp_dev.vbq_stat);
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);
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))
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);
4652 cif_isp10_pltfrm_pr_dbg(dev->dev,
4653 "SP state = %s, MP state = %s, DMA state = %s, img_src state = %s\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));
4667 cif_isp10_pltfrm_pr_dbg(dev->dev,
4668 "SP state = %s, MP state = %s, DMA state = %s, img_src state = %s\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);
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)
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;
4695 if (dev->isp_dev.cif_ism_cropping)
4696 dev->isp_dev.cif_ism_cropping = false;
4701 * Update ISM, cif_isp10_config_ism() changes the output size of isp,
4702 * so it must be called before cif_isp10_config_rsz()
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;
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);
4715 if (dev->config.isp_config.ism_config.ism_en)
4716 dev->config.mi_config.async_updt |= CIF_ISP10_ASYNC_ISM;
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))
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))
4735 cif_isp10_pltfrm_pr_err(dev->dev,
4736 "failed with err %d\n", ret);
4740 static int cif_isp10_mi_isr(unsigned int mi_mis, void *cntxt)
4742 struct cif_isp10_device *dev = cntxt;
4743 unsigned int mi_mis_tmp;
4745 cif_isp10_pltfrm_pr_dbg(dev->dev,
4746 "\n MI_RIS 0x%08x\n"
4749 cif_ioread32(dev->config.base_addr + CIF_MI_RIS),
4750 cif_ioread32(dev->config.base_addr + CIF_MI_IMSC),
4753 cif_isp10_pltfrm_rtrace_printf(dev->dev,
4754 "MI_MIS %08x, MI_RIS %08x, MI_IMSC %08x\n",
4756 cif_ioread32(dev->config.base_addr + CIF_MI_RIS),
4757 cif_ioread32(dev->config.base_addr + CIF_MI_IMSC));
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",
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",
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;
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);
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);
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);
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);
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;
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);
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);
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;
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);
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);
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);
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);
4872 dev->b_mi_frame_end = true;
4874 if (dev->dma_stream.state == CIF_ISP10_STATE_STREAMING) {
4875 cif_isp10_dma_next_buff(dev);
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;
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);
4893 cif_iowrite32(~(CIF_MI_MP_FRAME |
4894 CIF_MI_SP_FRAME | CIF_MI_DMA_READY),
4895 dev->config.base_addr + CIF_MI_ICR);
4900 static int cif_isp10_register_isrs(struct cif_isp10_device *dev)
4904 cif_isp10_pltfrm_irq_register_isr(
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");
4913 cif_isp10_pltfrm_irq_register_isr(
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");
4922 ret = cif_isp10_pltfrm_irq_register_isr(
4927 if (IS_ERR_VALUE(ret)) {
4928 cif_isp10_pltfrm_pr_err(dev->dev,
4929 "unable to register MI ISR, aborting\n");
4936 cif_isp10_pltfrm_pr_err(dev->dev, "failed with error %d", ret);
4940 static void cif_isp10_vs_work(struct work_struct *work)
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;
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;
4954 cif_isp10_img_src_s_ext_ctrls(dev->img_src, exp_ctrl);
4956 cif_isp10_pltfrm_pr_err(dev->dev,
4957 "dev->img_src is NULL\n");
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];
4963 new_data = &dev->img_src_exps.data[1];
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,
4971 mutex_unlock(&dev->img_src_exps.mutex);
4974 * pr_info("%s: exp_time: %d gain: %d, frame_id: s %d, v %d\n",
4976 * new_data->data.exp_time,
4977 * new_data->data.gain,
4978 * dev->isp_dev.frame_id,
4979 * new_data->v_frame_id);
4982 kfree(exp->exp->ctrls);
4983 exp->exp->ctrls = NULL;
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)
5004 struct cif_isp10_img_src_data *last_data;
5005 struct cif_isp10_img_src_data *new_data;
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];
5013 last_data = &dev->img_src_exps.data[1];
5014 new_data = &dev->img_src_exps.data[0];
5017 if (frame_id >= new_data->v_frame_id) {
5020 sizeof(struct isp_supplemental_sensor_mode_data));
5024 sizeof(struct isp_supplemental_sensor_mode_data));
5026 mutex_unlock(&dev->img_src_exps.mutex);
5029 int cif_isp10_streamon(
5030 struct cif_isp10_device *dev,
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;
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);
5045 if (!((streamon_sp &&
5046 (dev->sp_stream.state != CIF_ISP10_STATE_STREAMING)) ||
5048 (dev->mp_stream.state != CIF_ISP10_STATE_STREAMING))))
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");
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");
5066 if (streamon_sp && dev->config.mi_config.raw_enable &&
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");
5076 (dev->sp_stream.state == CIF_ISP10_STATE_STREAMING))
5077 dev->mp_stream.updt_cfg = true;
5079 (dev->mp_stream.state == CIF_ISP10_STATE_STREAMING))
5080 dev->sp_stream.updt_cfg = true;
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))
5088 dev->mp_stream.updt_cfg = true;
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))
5097 dev->sp_stream.updt_cfg = true;
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;
5106 ret = cif_isp10_config_cif(dev, stream_ids);
5107 if (IS_ERR_VALUE(ret))
5110 ret = cif_isp10_start(dev, streamon_sp, streamon_mp);
5111 if (IS_ERR_VALUE(ret))
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));
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);
5132 int cif_isp10_streamoff(
5133 struct cif_isp10_device *dev,
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;
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),
5151 if (dev->config.flash_mode != CIF_ISP10_FLASH_MODE_OFF &&
5153 (dev->mp_stream.state == CIF_ISP10_STATE_INACTIVE)) ||
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);
5161 if (dev->sp_stream.state == CIF_ISP10_STATE_STREAMING) {
5163 streamoff_all |= CIF_ISP10_STREAM_SP;
5165 streamoff_all |= CIF_ISP10_STREAM_SP;
5167 if (dev->mp_stream.state == CIF_ISP10_STATE_STREAMING) {
5169 streamoff_all |= CIF_ISP10_STREAM_MP;
5171 streamoff_all |= CIF_ISP10_STREAM_MP;
5173 if (streamoff_all == (CIF_ISP10_STREAM_MP | CIF_ISP10_STREAM_SP))
5174 drain_workqueue(dev->vs_wq);
5176 ret = cif_isp10_stop(dev, streamoff_sp, streamoff_mp);
5177 if (IS_ERR_VALUE(ret))
5179 if ((streamoff_sp) &&
5180 (dev->sp_stream.state == CIF_ISP10_STATE_READY))
5181 dev->sp_stream.state = CIF_ISP10_STATE_INACTIVE;
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 =
5189 if (dev->mp_stream.state == CIF_ISP10_STATE_READY)
5190 dev->mp_stream.state = CIF_ISP10_STATE_INACTIVE;
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;
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;
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);
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);
5224 int cif_isp10_suspend(
5225 struct cif_isp10_device *dev)
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));
5234 if ((dev->pm_state == CIF_ISP10_PM_STATE_SUSPENDED) ||
5235 (dev->pm_state == CIF_ISP10_PM_STATE_OFF))
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))
5243 ret = cif_isp10_set_pm_state(dev, CIF_ISP10_PM_STATE_SUSPENDED);
5244 if (IS_ERR_VALUE(ret))
5246 ret = cif_isp10_img_src_set_state(dev, CIF_ISP10_IMG_SRC_STATE_OFF);
5247 if (IS_ERR_VALUE(ret))
5252 cif_isp10_pltfrm_pr_err(dev->dev,
5253 "failed with error %d\n", ret);
5257 int cif_isp10_resume(
5258 struct cif_isp10_device *dev)
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));
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;
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;
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;
5289 return cif_isp10_streamon(dev, stream_ids);
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,
5300 cif_isp10_pltfrm_pr_dbg(NULL, "%s\n",
5301 cif_isp10_stream_id_string(stream_id));
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);
5311 cif_isp10_pltfrm_pr_err(NULL,
5312 "unknown/unsupported stream ID %d\n", stream_id);
5319 cif_isp10_pltfrm_pr_err(NULL,
5320 "failed with error %d\n", ret);
5325 struct cif_isp10_device *dev,
5330 cif_isp10_pltfrm_pr_dbg(NULL, "0x%08x\n", stream_ids);
5332 if (stream_ids & ~(CIF_ISP10_ALL_STREAMS)) {
5333 cif_isp10_pltfrm_pr_err(NULL,
5334 "unknown/unsupported stream IDs 0x%08x\n",
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 =
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);
5358 cif_isp10_pltfrm_pr_err(NULL,
5359 "failed with error %d\n", ret);
5363 int cif_isp10_release(
5364 struct cif_isp10_device *dev,
5368 struct cif_isp10_stream *strm_dev;
5370 cif_isp10_pltfrm_pr_dbg(NULL, "0x%08x\n", stream_ids);
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))
5377 if (stream_ids & ~(CIF_ISP10_ALL_STREAMS)) {
5378 cif_isp10_pltfrm_pr_err(NULL,
5379 "unknown/unsupported stream IDs 0x%08x\n",
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;
5393 if (strm_dev->metadata.d) {
5394 vfree(strm_dev->metadata.d);
5395 strm_dev->metadata.d = NULL;
5396 strm_dev->metadata.cnt = 0;
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))
5408 dev->sp_stream.state = CIF_ISP10_STATE_DISABLED;
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))
5418 dev->mp_stream.state = CIF_ISP10_STATE_DISABLED;
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");
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;
5438 cif_isp10_pltfrm_pr_err(dev->dev,
5439 "failed with error %d\n", ret);
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)
5451 struct cif_isp10_device *dev;
5453 cif_isp10_pltfrm_pr_dbg(NULL, "\n");
5455 /* Allocate needed structures */
5456 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
5458 cif_isp10_pltfrm_pr_err(dev->dev,
5459 "memory allocation failed\n");
5463 dev->sof_event = sof_event;
5464 dev->requeue_bufs = requeue_bufs;
5466 ret = cif_isp10_pltfrm_dev_init(dev,
5467 &pdev, &dev->config.base_addr);
5468 if (IS_ERR_VALUE(ret))
5470 cif_isp10_pltfrm_debug_register_print_cb(
5472 (void (*)(void *, const char *))cif_isp10_debug_print_block,
5475 cif_isp10_pltfrm_soc_init(dev, soc_cfg);
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");
5484 ret = cif_isp10_register_isrs(dev);
5485 if (IS_ERR_VALUE(ret))
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);
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);
5509 /* TBD: clean this up */
5510 init_output_formats();
5514 cif_isp10_pltfrm_pr_err(NULL,
5515 "failed with error %d\n", ret);
5516 if (!IS_ERR_OR_NULL(dev))
5518 return ERR_PTR(ret);
5521 void cif_isp10_destroy(
5522 struct cif_isp10_device *dev)
5524 cif_isp10_pltfrm_pr_dbg(NULL, "\n");
5525 if (!IS_ERR_OR_NULL(dev))
5529 int cif_isp10_s_input(
5530 struct cif_isp10_device *dev,
5534 enum cif_isp10_inp inp;
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)));
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);
5548 dev->img_src = NULL;
5550 inp = cif_isp10_input_index2inp(dev, input);
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;
5557 dev->img_src = dev->img_src_array[input];
5558 dev->config.isp_config.input =
5559 &dev->config.img_src_output.frm_fmt;
5561 dev->config.input_sel = inp;
5565 cif_isp10_pltfrm_pr_err(NULL,
5566 "failed with error %d\n", ret);
5570 const char *cif_isp10_g_input_name(
5571 struct cif_isp10_device *dev,
5572 unsigned int 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",
5582 if (input_index < dev->img_src_cnt)
5583 return cif_isp10_img_src_g_name(
5584 dev->img_src_array[input_index]);
5586 return cif_isp10_inp_string(CIF_ISP10_INP_DMA +
5587 ((input_index - dev->img_src_cnt) << 24));
5591 struct cif_isp10_device *dev,
5592 enum cif_isp10_stream_id stream,
5593 struct cif_isp10_buffer *buf)
5597 cif_isp10_pltfrm_pr_dbg(dev->dev,
5599 cif_isp10_stream_id_string(stream));
5602 case CIF_ISP10_STREAM_SP:
5603 list_add_tail(&buf->queue, &dev->sp_stream.buf_queue);
5605 case CIF_ISP10_STREAM_MP:
5606 list_add_tail(&buf->queue, &dev->mp_stream.buf_queue);
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);
5614 case CIF_ISP10_STREAM_ISP:
5618 cif_isp10_pltfrm_pr_err(dev->dev,
5619 "unknown stream %d\n", stream);
5626 cif_isp10_pltfrm_pr_err(dev->dev,
5627 "failed with err %d\n", ret);
5631 int cif_isp10_reqbufs(
5632 struct cif_isp10_device *dev,
5633 enum cif_isp10_stream_id strm,
5634 struct v4l2_requestbuffers *req)
5636 struct cif_isp10_stream *strm_dev = NULL;
5639 case CIF_ISP10_STREAM_MP:
5640 strm_dev = &dev->mp_stream;
5642 case CIF_ISP10_STREAM_SP:
5643 strm_dev = &dev->sp_stream;
5646 cif_isp10_pltfrm_pr_err(dev->dev,
5647 "unknown stream id%d\n", strm);
5651 strm_dev->metadata.cnt = req->count;
5656 int cif_isp10_s_exp(
5657 struct cif_isp10_device *dev,
5658 struct cif_isp10_img_src_ext_ctrl *exp_ctrl)
5660 struct cif_isp10_img_src_exp *exp = NULL;
5661 unsigned long lock_flags;
5667 exp = kmalloc(sizeof(*exp), GFP_KERNEL);
5673 exp->exp = exp_ctrl;
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);
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)
5692 unsigned int stream_id =
5693 readout_work->stream_id;
5694 struct videobuf_buffer *vb =
5696 struct cif_isp10_stream *strm_dev = NULL;
5697 struct v4l2_buffer_metadata_s *metadata;
5698 struct cifisp_isp_metadata *isp_last;
5700 switch (stream_id) {
5701 case CIF_ISP10_STREAM_MP:
5702 strm_dev = &dev->mp_stream;
5704 case CIF_ISP10_STREAM_SP:
5705 strm_dev = &dev->sp_stream;
5708 cif_isp10_pltfrm_pr_err(dev->dev,
5709 "unknown stream id%d\n", stream_id);
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);
5718 metadata->frame_id = readout_work->frame_id;
5720 (struct cifisp_isp_metadata *)metadata->isp;
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,
5728 sizeof(struct cifisp_isp_meas_cfg));
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,
5738 sizeof(struct cifisp_isp_other_cfg));
5743 memcpy(&isp_last->meas_stat,
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;
5751 isp_last->meas_stat.meas_type = 0x00;
5756 cif_isp10_pltfrm_pr_dbg(NULL,
5765 struct cif_isp10_device *dev,
5766 enum cif_isp10_stream_id stream_id,
5767 struct vm_area_struct *vma)
5769 struct cif_isp10_stream *strm_dev;
5771 int retval = 0, pages;
5772 unsigned long mem_size;
5774 switch (stream_id) {
5775 case CIF_ISP10_STREAM_MP:
5776 strm_dev = &dev->mp_stream;
5778 case CIF_ISP10_STREAM_SP:
5779 strm_dev = &dev->sp_stream;
5782 cif_isp10_pltfrm_pr_err(dev->dev,
5783 "unknown stream id%d\n", stream_id);
5787 mem_size = vma->vm_end - vma->vm_start;
5788 if (mem_size > strm_dev->metadata.cnt * CAMERA_METADATA_LEN) {
5790 cif_isp10_pltfrm_pr_err(dev->dev,
5791 "mmap size(0x%lx) > metadata memory size(0x%lx), so failed!",
5793 (unsigned long)(strm_dev->metadata.cnt
5794 * CAMERA_METADATA_LEN));
5798 pages = PAGE_ALIGN(vma->vm_end - vma->vm_start);
5799 mem_vaddr = (struct v4l2_buffer_metadata_s *)vmalloc_user(pages);
5801 cif_isp10_pltfrm_pr_err(dev->dev,
5802 "vmalloc (%d bytes) failed for %s metadata\n",
5804 (stream_id == CIF_ISP10_STREAM_MP) ? "mp" : "sp");
5809 /* Try to remap memory */
5810 retval = remap_vmalloc_range(vma, mem_vaddr, 0);
5812 cif_isp10_pltfrm_pr_err(dev->dev,
5813 "mmap: remap failed with error %d. ", retval);
5818 strm_dev->metadata.d = (unsigned char *)mem_vaddr;
5820 vma->vm_private_data = (void *)&strm_dev->metadata;
5826 int cif_isp10_get_target_frm_size(
5827 struct cif_isp10_device *dev,
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))
5836 dev->config.mi_config.mp.output.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))
5844 dev->config.mi_config.mp.output.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;
5852 cif_isp10_pltfrm_pr_err(dev->dev,
5853 "cannot get target frame size, no path ready\n");
5859 int cif_isp10_calc_isp_cropping(
5860 struct cif_isp10_device *dev,
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");
5879 input_width = dev->config.isp_config.input->defrect.width;
5880 input_height = dev->config.isp_config.input->defrect.height;
5882 ret = cif_isp10_get_target_frm_size(dev,
5883 &target_width, &target_height);
5884 if (IS_ERR_VALUE(ret))
5887 *width = input_width;
5888 *height = input_width * target_height / target_width;
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;
5900 *h_offs = (input_width - *width) >> 1;
5905 cif_isp10_pltfrm_pr_err(dev->dev,
5906 "failed with err %d\n", ret);
5910 int cif_isp10_calc_min_out_buff_size(
5911 struct cif_isp10_device *dev,
5912 enum cif_isp10_stream_id stream_id,
5916 enum cif_isp10_pix_fmt pix_fmt;
5920 struct cif_isp10_mi_path_config *mi_path;
5921 struct cif_isp10_stream *stream;
5923 cif_isp10_pltfrm_pr_dbg(NULL,
5925 cif_isp10_stream_id_string(stream_id));
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;
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));
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));
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",
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 */
5963 bpp = CIF_ISP10_PIX_FMT_GET_BPP(pix_fmt);
5964 *size = llength * height * bpp / 8;
5966 cif_isp10_pltfrm_pr_dbg(NULL,
5967 "calculated buffer size: %d\n",
5972 cif_isp10_pltfrm_pr_err(dev->dev,
5973 "failed with err %d\n", ret);
5977 int cif_isp10_s_ctrl(
5978 struct cif_isp10_device *dev,
5979 const enum cif_isp10_cid id,
5982 cif_isp10_pltfrm_pr_dbg(NULL,
5987 case CIF_ISP10_CID_SUPER_IMPOSE:
5988 dev->config.isp_config.si_enable = val;
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);
5996 dev->config.isp_config.ie_config.effect = val;
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);
6004 dev->config.jpeg_config.ratio = val;
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);
6012 dev->config.flash_mode = val;
6013 cif_isp10_img_src_s_ctrl(
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;
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,
6056 cif_isp10_pltfrm_pr_err(dev->dev,
6057 "unknown/unsupported control %d\n", id);
6080 static void cif_isp10_hw_restart(struct cif_isp10_device *dev)
6082 cif_isp10_pltfrm_pr_dbg(NULL, "\n");
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);
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);
6110 dev->config.base_addr + CIF_MI_MP_Y_OFFS_CNT_INIT);
6112 dev->config.base_addr +
6113 CIF_MI_MP_CR_OFFS_CNT_INIT);
6115 dev->config.base_addr +
6116 CIF_MI_MP_CB_OFFS_CNT_INIT);
6118 dev->config.base_addr + CIF_MI_SP_Y_OFFS_CNT_INIT);
6120 dev->config.base_addr +
6121 CIF_MI_SP_CR_OFFS_CNT_INIT);
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);
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);
6134 cif_iowrite32OR(CIF_MIPI_CTRL_OUTPUT_ENA,
6135 dev->config.base_addr + CIF_MIPI_CTRL);
6138 int cif_isp10_mipi_isr(unsigned int mipi_mis, void *cntxt)
6140 struct cif_isp10_device *dev =
6141 (struct cif_isp10_device *)cntxt;
6142 unsigned int mipi_ris = 0;
6144 mipi_ris = cif_ioread32(dev->config.base_addr + CIF_MIPI_RIS);
6145 mipi_mis = cif_ioread32(dev->config.base_addr + CIF_MIPI_MIS);
6147 cif_isp10_pltfrm_rtrace_printf(dev->dev,
6148 "MIPI_MIS %08x, MIPI_RIS %08x, MIPI_IMSC %08x\n",
6151 cif_ioread32(dev->config.base_addr + CIF_MIPI_IMSC));
6154 dev->config.base_addr + CIF_MIPI_ICR);
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);
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.
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);
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);
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);
6181 if (mipi_mis == CIF_MIPI_FRAME_END) {
6183 * Enable DPHY errctrl interrupt again, if mipi have receive
6184 * the whole frame without any error.
6186 cif_iowrite32OR(CIF_MIPI_ERR_CTRL(3),
6187 dev->config.base_addr + CIF_MIPI_IMSC);
6190 mipi_mis = cif_ioread32(dev->config.base_addr + CIF_MIPI_MIS);
6193 cif_isp10_pltfrm_pr_err(dev->dev,
6194 "mipi_mis icr err: 0x%x\n", mipi_mis);
6200 /* ======================================================================== */
6201 int cif_isp10_isp_isr(unsigned int isp_mis, void *cntxt)
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;
6209 cif_isp10_pltfrm_pr_dbg(dev->dev,
6210 "ISP_MIS %08x, ISP_RIS %08x, ISP_IMSC %08x\n",
6212 cif_ioread32(dev->config.base_addr + CIF_ISP_RIS),
6213 cif_ioread32(dev->config.base_addr + CIF_ISP_IMSC));
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;
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);
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",
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");
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,
6245 list_del(&exp->list);
6249 spin_unlock(&dev->img_src_exps.lock);
6252 vs_wk = kmalloc(sizeof(*vs_wk),
6255 vs_wk->cmd = CIF_ISP10_VS_EXP;
6257 vs_wk->param = (void *)exp;
6258 INIT_WORK((struct work_struct *)&vs_wk->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__);
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);
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;
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 +
6286 cif_isp10_hw_errors[isp_pic_size_err].count++;
6288 cif_ioread32(dev->config.base_addr +
6291 "CIF_ISP_PIC_SIZE_ERROR (0x%08x)",
6293 cif_iowrite32(isp_err,
6294 dev->config.base_addr +
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 +
6301 cif_isp10_hw_errors[isp_data_loss].count++;
6303 "CIF_ISP_DATA_LOSS\n");
6304 cif_iowrite32(CIF_ISP_DATA_LOSS,
6305 dev->config.base_addr +
6310 cif_iowrite32AND(~CIF_ISP_CTRL_ISP_INFORM_ENABLE &
6311 ~CIF_ISP_CTRL_ISP_ENABLE,
6312 dev->config.base_addr + CIF_ISP_CTRL);
6314 cif_iowrite32OR(CIF_ISP_CTRL_ISP_CFG_UPD,
6315 dev->config.base_addr + CIF_ISP_CTRL);
6316 cif_isp10_hw_restart(dev);
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",
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))){
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);
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",
6356 if (dev->b_mi_frame_end)
6357 cif_isp10_update_ism_dcr_rsz(dev);
6358 dev->b_isp_frame_in = true;
6361 cifisp_isp_isr(&dev->isp_dev, isp_mis);
6366 /* ======================================================================== */
6368 void init_output_formats(void)
6371 int ret = 0; /* RF*/
6372 int xgold_num_format = 0; /*RF*/
6375 (sizeof(cif_isp10_output_format) / sizeof(struct cif_isp10_fmt));
6377 for (i = 0; i < xgold_num_format; i++) {
6378 struct v4l2_fmtdesc fmtdesc;
6380 memset(&fmtdesc, 0, sizeof(fmtdesc));
6382 fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
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;
6390 cif_isp10_output_format[(&fmtdesc)->index].flags;
6395 output_formats[i] = fmtdesc;
6399 int get_cif_isp10_output_format_size(void)
6401 return sizeof(cif_isp10_output_format) / sizeof(struct cif_isp10_fmt);
6404 struct cif_isp10_fmt *get_cif_isp10_output_format(int index)
6406 struct cif_isp10_fmt *fmt = NULL;
6408 if ((index >= 0) && (index < get_cif_isp10_output_format_size()))
6409 fmt = &cif_isp10_output_format[index];
6414 struct v4l2_fmtdesc *get_cif_isp10_output_format_desc(int index)
6416 struct v4l2_fmtdesc *desc = NULL;
6418 if ((index >= 0) && (index < get_cif_isp10_output_format_desc_size()))
6419 desc = &output_formats[index];
6424 int get_cif_isp10_output_format_desc_size(void)
6426 return ARRAY_SIZE(cif_isp10_output_format);