• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * linux-5.4/drivers/media/platform/sunxi-vin/vin-isp/sunxi_isp.c
3  *
4  * Copyright (c) 2007-2017 Allwinnertech Co., Ltd.
5  *
6  * This software is licensed under the terms of the GNU General Public
7  * License version 2, as published by the Free Software Foundation, and
8  * may be copied, distributed, and modified under those terms.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  */
16 
17 #include <linux/platform_device.h>
18 #include <linux/kernel.h>
19 #include <linux/module.h>
20 #include <media/v4l2-device.h>
21 #include <media/v4l2-mediabus.h>
22 #include <media/v4l2-subdev.h>
23 #include <media/v4l2-event.h>
24 #include <media/v4l2-ctrls.h>
25 #include "../platform/platform_cfg.h"
26 #include "sunxi_isp.h"
27 
28 #include "../vin-csi/sunxi_csi.h"
29 #include "../vin-vipp/sunxi_scaler.h"
30 #include "../vin-video/vin_core.h"
31 #include "../utility/vin_io.h"
32 #include "isp_default_tbl.h"
33 
34 #define ISP_MODULE_NAME "vin_isp"
35 
36 struct isp_dev *glb_isp[VIN_MAX_ISP];
37 
38 #ifdef CONFIG_D3D_COMPRESS_EN
39 #define D3D_RAW_LBC_MODE		16 /* <=10 = lossless, 12 = 1.2x, 30 = 3x(< 3x)*/
40 #define D3D_K_LBC_MODE			20 /* <=10 = lossless, 12 = 1.2x, 20 = 2x(< 2x)*/
41 #else
42 #define D3D_RAW_LBC_MODE		10 /* <=10 = lossless, 12 = 1.2x, 30 = 3x(< 3x)*/
43 #define D3D_K_LBC_MODE			10 /* <=10 = lossless, 12 = 1.2x, 20 = 2x(< 2x)*/
44 #endif
45 
46 #ifdef CONFIG_WDR_COMPRESS_EN
47 #define WDR_RAW_LBC_MODE		26 /* <=10 = lossless, 12 = 1.2x, 30 = 3x(< 3x)*/
48 #else
49 #define WDR_RAW_LBC_MODE		10 /* <=10 = lossless, 12 = 1.2x, 30 = 3x(< 3x)*/
50 #endif
51 
52 #define LARGE_IMAGE_OFF			32
53 
54 #define MIN_IN_WIDTH			192
55 #define MIN_IN_HEIGHT			128
56 #define MAX_IN_WIDTH			4224
57 #define MAX_IN_HEIGHT			4224
58 
59 static struct isp_pix_fmt sunxi_isp_formats[] = {
60 	{
61 		.fourcc = V4L2_PIX_FMT_SBGGR8,
62 		.mbus_code = MEDIA_BUS_FMT_SBGGR8_1X8,
63 		.infmt = ISP_BGGR,
64 	}, {
65 		.fourcc = V4L2_PIX_FMT_SGBRG8,
66 		.mbus_code = MEDIA_BUS_FMT_SGBRG8_1X8,
67 		.infmt = ISP_GBRG,
68 	}, {
69 		.fourcc = V4L2_PIX_FMT_SGRBG8,
70 		.mbus_code = MEDIA_BUS_FMT_SGRBG8_1X8,
71 		.infmt = ISP_GRBG,
72 	}, {
73 		.fourcc = V4L2_PIX_FMT_SRGGB8,
74 		.mbus_code = MEDIA_BUS_FMT_SRGGB8_1X8,
75 		.infmt = ISP_RGGB,
76 	}, {
77 		.fourcc = V4L2_PIX_FMT_SBGGR10,
78 		.mbus_code = MEDIA_BUS_FMT_SBGGR10_1X10,
79 		.infmt = ISP_BGGR,
80 	}, {
81 		.fourcc = V4L2_PIX_FMT_SGBRG8,
82 		.mbus_code = MEDIA_BUS_FMT_SGBRG10_1X10,
83 		.infmt = ISP_GBRG,
84 	}, {
85 		.fourcc = V4L2_PIX_FMT_SGRBG10,
86 		.mbus_code = MEDIA_BUS_FMT_SGRBG10_1X10,
87 		.infmt = ISP_GRBG,
88 	}, {
89 		.fourcc = V4L2_PIX_FMT_SRGGB10,
90 		.mbus_code = MEDIA_BUS_FMT_SRGGB10_1X10,
91 		.infmt = ISP_RGGB,
92 	}, {
93 		.fourcc = V4L2_PIX_FMT_SBGGR12,
94 		.mbus_code = MEDIA_BUS_FMT_SBGGR12_1X12,
95 		.infmt = ISP_BGGR,
96 	}, {
97 		.fourcc = V4L2_PIX_FMT_SGBRG12,
98 		.mbus_code = MEDIA_BUS_FMT_SGBRG12_1X12,
99 		.infmt = ISP_GBRG,
100 	}, {
101 		.fourcc = V4L2_PIX_FMT_SGRBG12,
102 		.mbus_code = MEDIA_BUS_FMT_SGRBG12_1X12,
103 		.infmt = ISP_GRBG,
104 	}, {
105 		.fourcc = V4L2_PIX_FMT_SRGGB12,
106 		.mbus_code = MEDIA_BUS_FMT_SRGGB12_1X12,
107 		.infmt = ISP_RGGB,
108 	},
109 };
110 
__isp_s_sensor_stby_handle(struct work_struct * work)111 static void __isp_s_sensor_stby_handle(struct work_struct *work)
112 {
113 	int sensor_stby_stat, i;
114 	struct isp_dev *isp =
115 			container_of(work, struct isp_dev, s_sensor_stby_task);
116 	struct vin_md *vind = dev_get_drvdata(isp->subdev.v4l2_dev->dev);
117 	struct vin_core *vinc = NULL;
118 
119 	for (i = 0; i < VIN_MAX_DEV; i++) {
120 		if (vind->vinc[i] == NULL)
121 			continue;
122 		if (!vin_streaming(&vind->vinc[i]->vid_cap))
123 			continue;
124 
125 		vinc = vind->vinc[i];
126 		if (vinc->isp_sel == isp->id)
127 			break;
128 	}
129 
130 	sensor_stby_stat = STBY_ON;
131 	v4l2_subdev_call(vinc->vid_cap.pipe.sd[VIN_IND_SENSOR], core, ioctl,
132 				SET_SENSOR_STANDBY, &sensor_stby_stat);
133 
134 	sensor_stby_stat = STBY_OFF;
135 	v4l2_subdev_call(vinc->vid_cap.pipe.sd[VIN_IND_SENSOR], core, ioctl,
136 				SET_SENSOR_STANDBY, &sensor_stby_stat);
137 
138 
139 	vin_print("%s done, %s is standby and then on!\n", __func__, vinc->vid_cap.pipe.sd[VIN_IND_SENSOR]->name);
140 }
141 
142 #if defined CONFIG_D3D
isp_3d_pingpong_alloc(struct isp_dev * isp)143 static int isp_3d_pingpong_alloc(struct isp_dev *isp)
144 {
145 	int ret = 0;
146 #if defined CONFIG_ARCH_SUN8IW19P1
147 	int cmp_ratio, bitdepth, wth;
148 
149 	if (D3D_K_LBC_MODE > 10) {
150 		if (D3D_K_LBC_MODE > 20)
151 			cmp_ratio = 1000/2;
152 		else
153 			cmp_ratio = 1000*10/D3D_K_LBC_MODE;
154 	} else
155 		cmp_ratio = 1000;
156 	bitdepth = 5;
157 	wth = roundup(isp->mf.width, 16);
158 	if (D3D_K_LBC_MODE <= 10)
159 		isp->d3d_k_lbc.line_tar_bits = roundup(wth*bitdepth + wth/16*2, 512);
160 	else
161 		isp->d3d_k_lbc.line_tar_bits = roundup(cmp_ratio*wth*bitdepth/1000, 512);
162 	isp->d3d_k_lbc.mb_min_bit = clamp((cmp_ratio*bitdepth*16)/1000, 0, 127);
163 
164 	if (D3D_RAW_LBC_MODE > 10) {
165 		if (D3D_RAW_LBC_MODE > 30)
166 			cmp_ratio = 1000/3;
167 		else
168 			cmp_ratio = 1000*10/D3D_RAW_LBC_MODE;
169 	} else
170 		cmp_ratio = 1000;
171 	bitdepth = 12;
172 	wth = roundup(isp->mf.width, 32);
173 	if (D3D_RAW_LBC_MODE <= 10)
174 		isp->d3d_raw_lbc.line_tar_bits = roundup(wth*bitdepth + wth/32*2, 512);
175 	else
176 		isp->d3d_raw_lbc.line_tar_bits = roundup(cmp_ratio*wth*bitdepth/1000, 512);
177 	isp->d3d_raw_lbc.mb_min_bit = clamp(((cmp_ratio*bitdepth + 500)/1000-1)*32+6, 0, 511);
178 
179 	isp->d3d_pingpong[0].size = isp->d3d_k_lbc.line_tar_bits * isp->mf.height / 8;
180 	isp->d3d_pingpong[1].size = isp->d3d_raw_lbc.line_tar_bits * isp->mf.height / 8;
181 #if defined CONFIG_D3D_LTF_EN
182 	isp->d3d_pingpong[2].size = isp->d3d_raw_lbc.line_tar_bits * isp->mf.height / 8;
183 	ret = os_mem_alloc(&isp->pdev->dev, &isp->d3d_pingpong[2]);
184 	if (ret < 0) {
185 		vin_err("isp 3d pingpong buf2 requset failed!\n");
186 		return -ENOMEM;
187 	}
188 #endif
189 #elif defined CONFIG_ARCH_SUN8IW16P1
190 #if defined CONFIG_D3D_LTF_EN
191 	isp->d3d_pingpong[0].size = roundup(isp->mf.width, 64) * isp->mf.height * 29 / 8;
192 	isp->d3d_pingpong[1].size = roundup(isp->mf.width, 64) * isp->mf.height * 29 / 8;
193 #else
194 	isp->d3d_pingpong[0].size = roundup(isp->mf.width, 64) * isp->mf.height * 17 / 8;
195 	isp->d3d_pingpong[1].size = roundup(isp->mf.width, 64) * isp->mf.height * 17 / 8;
196 #endif
197 #else
198 	isp->d3d_pingpong[0].size = roundup(isp->mf.width, 64) * isp->mf.height * 29 / 8;
199 	isp->d3d_pingpong[1].size = roundup(isp->mf.width, 64) * isp->mf.height * 29 / 8;
200 #endif
201 	ret = os_mem_alloc(&isp->pdev->dev, &isp->d3d_pingpong[0]);
202 	if (ret < 0) {
203 		vin_err("isp 3d pingpong buf0 requset failed!\n");
204 		return -ENOMEM;
205 	}
206 
207 	ret = os_mem_alloc(&isp->pdev->dev, &isp->d3d_pingpong[1]);
208 	if (ret < 0) {
209 		vin_err("isp 3d pingpong buf1 requset failed!\n");
210 		return -ENOMEM;
211 	}
212 	return ret;
213 }
isp_3d_pingpong_free(struct isp_dev * isp)214 static void isp_3d_pingpong_free(struct isp_dev *isp)
215 {
216 	os_mem_free(&isp->pdev->dev, &isp->d3d_pingpong[0]);
217 	os_mem_free(&isp->pdev->dev, &isp->d3d_pingpong[1]);
218 #if defined CONFIG_ARCH_SUN8IW19P1
219 #if defined CONFIG_D3D_LTF_EN
220 	os_mem_free(&isp->pdev->dev, &isp->d3d_pingpong[2]);
221 #endif
222 #endif
223 }
224 
isp_3d_pingpong_update(struct isp_dev * isp)225 static int isp_3d_pingpong_update(struct isp_dev *isp)
226 {
227 	dma_addr_t addr;
228 
229 #if defined CONFIG_ARCH_SUN8IW19P1
230 	addr = (dma_addr_t)isp->d3d_pingpong[0].dma_addr;
231 	bsp_isp_set_d3d_ref_k_addr(isp->id, addr);
232 	addr = (dma_addr_t)isp->d3d_pingpong[1].dma_addr;
233 	bsp_isp_set_d3d_ref_raw_addr(isp->id, addr);
234 #if defined CONFIG_D3D_LTF_EN
235 	addr = (dma_addr_t)isp->d3d_pingpong[2].dma_addr;
236 	bsp_isp_set_d3d_ltf_raw_addr(isp->id, addr);
237 #endif
238 
239 	if (D3D_K_LBC_MODE <= 10)
240 		bsp_isp_set_d3d_k_lbc_ctrl(isp->id, &isp->d3d_k_lbc, 0);
241 	else
242 		bsp_isp_set_d3d_k_lbc_ctrl(isp->id, &isp->d3d_k_lbc, 1);
243 
244 	if (D3D_RAW_LBC_MODE <= 10)
245 		bsp_isp_set_d3d_raw_lbc_ctrl(isp->id, &isp->d3d_raw_lbc, 0);
246 	else
247 		bsp_isp_set_d3d_raw_lbc_ctrl(isp->id, &isp->d3d_raw_lbc, 1);
248 
249 	bsp_isp_set_d3d_stride(isp->id, isp->d3d_k_lbc.line_tar_bits/32, isp->d3d_raw_lbc.line_tar_bits/32);
250 	bsp_isp_d3d_fifo_en(isp->id, 1);
251 #else
252 	struct vin_mm tmp;
253 
254 	tmp = isp->d3d_pingpong[0];
255 	isp->d3d_pingpong[0] = isp->d3d_pingpong[1];
256 	isp->d3d_pingpong[1] = tmp;
257 
258 	addr = (dma_addr_t)isp->d3d_pingpong[0].dma_addr;
259 	bsp_isp_set_d3d_addr0(isp->id, addr);
260 	addr = (dma_addr_t)isp->d3d_pingpong[1].dma_addr;
261 	bsp_isp_set_d3d_addr1(isp->id, addr);
262 #if defined CONFIG_ARCH_SUN8IW16P1 && !defined CONFIG_D3D_LTF_EN
263 	/* close d3d long time frame */
264 	writel(readl(isp->isp_load.vir_addr + 0x2d4) & ~(1 << 24), isp->isp_load.vir_addr + 0x2d4);
265 #endif
266 #endif
267 	return 0;
268 }
269 #else
isp_3d_pingpong_alloc(struct isp_dev * isp)270 static int isp_3d_pingpong_alloc(struct isp_dev *isp)
271 {
272 	return 0;
273 }
isp_3d_pingpong_free(struct isp_dev * isp)274 static void isp_3d_pingpong_free(struct isp_dev *isp)
275 {
276 
277 }
isp_3d_pingpong_update(struct isp_dev * isp)278 static int isp_3d_pingpong_update(struct isp_dev *isp)
279 {
280 	return 0;
281 }
282 #endif
283 
284 #if defined CONFIG_WDR
isp_wdr_pingpong_alloc(struct isp_dev * isp)285 static int isp_wdr_pingpong_alloc(struct isp_dev *isp)
286 {
287 	int ret = 0, i;
288 #if !defined CONFIG_ARCH_SUN8IW16P1 && !defined CONFIG_ARCH_SUN8IW19P1
289 	short *wdr_tbl = isp->isp_lut_tbl.vir_addr + ISP_WDR_GAMMA_FE_MEM_OFS;
290 #else
291 	short *wdr_tbl = isp->isp_load.vir_addr + ISP_LOAD_REG_SIZE + ISP_FE_TBL_SIZE + ISP_S0_LC_TBL_SIZE;
292 #endif
293 
294 #if defined CONFIG_ARCH_SUN8IW19P1
295 	int cmp_ratio, bitdepth, wth;
296 
297 	if (WDR_RAW_LBC_MODE > 10) {
298 		if (WDR_RAW_LBC_MODE > 30)
299 			cmp_ratio = 1000/3;
300 		else
301 			cmp_ratio = 1000*10/WDR_RAW_LBC_MODE;
302 	} else
303 		cmp_ratio = 1000;
304 	bitdepth = 12;
305 	wth = roundup(isp->mf.width, 32);
306 	if (WDR_RAW_LBC_MODE <= 10)
307 		isp->wdr_raw_lbc.line_tar_bits = roundup(wth*bitdepth + wth/32*2, 512);
308 	else
309 		isp->wdr_raw_lbc.line_tar_bits = roundup(cmp_ratio*wth*bitdepth/1000, 512);
310 	isp->wdr_raw_lbc.mb_min_bit = clamp(((cmp_ratio*bitdepth + 500)/1000-1)*32+16, 0, 511);
311 
312 	isp->wdr_pingpong[0].size = isp->wdr_raw_lbc.line_tar_bits * isp->mf.height / 8;
313 #else
314 	isp->wdr_pingpong[0].size = isp->mf.width * isp->mf.height * 2;
315 	isp->wdr_pingpong[1].size = isp->mf.width * isp->mf.height * 2;
316 
317 	ret = os_mem_alloc(&isp->pdev->dev, &isp->wdr_pingpong[1]);
318 	if (ret < 0) {
319 		vin_err("isp wdr pingpong buf1 requset failed!\n");
320 		return -ENOMEM;
321 	}
322 #endif
323 	ret = os_mem_alloc(&isp->pdev->dev, &isp->wdr_pingpong[0]);
324 	if (ret < 0) {
325 		vin_err("isp wdr pingpong buf0 requset failed!\n");
326 		return -ENOMEM;
327 	}
328 
329 	for (i = 0; i < 4096; i++) {
330 		wdr_tbl[i] = i;
331 		wdr_tbl[i + 4096] = i*16;
332 	}
333 
334 	return ret;
335 }
isp_wdr_pingpong_free(struct isp_dev * isp)336 static void isp_wdr_pingpong_free(struct isp_dev *isp)
337 {
338 #if defined CONFIG_ARCH_SUN8IW19P1
339 	os_mem_free(&isp->pdev->dev, &isp->wdr_pingpong[0]);
340 #else
341 	os_mem_free(&isp->pdev->dev, &isp->wdr_pingpong[0]);
342 	os_mem_free(&isp->pdev->dev, &isp->wdr_pingpong[1]);
343 #endif
344 }
345 
isp_wdr_pingpong_set(struct isp_dev * isp)346 static int isp_wdr_pingpong_set(struct isp_dev *isp)
347 {
348 	dma_addr_t addr;
349 #if defined  CONFIG_ARCH_SUN8IW19P1
350 	addr = (dma_addr_t)isp->wdr_pingpong[0].dma_addr;
351 	bsp_isp_set_wdr_addr0(isp->id, addr);
352 	if (WDR_RAW_LBC_MODE <= 10)
353 		bsp_isp_set_wdr_raw_lbc_ctrl(isp->id, &isp->wdr_raw_lbc, 0);
354 	else
355 		bsp_isp_set_wdr_raw_lbc_ctrl(isp->id, &isp->wdr_raw_lbc, 1);
356 	bsp_isp_set_wdr_stride(isp->id, isp->wdr_raw_lbc.line_tar_bits / 32);
357 	bsp_isp_wdr_fifo_en(isp->id, 1);
358 #else
359 	addr = (dma_addr_t)isp->wdr_pingpong[0].dma_addr;
360 	bsp_isp_set_wdr_addr0(isp->id, addr);
361 	addr = (dma_addr_t)isp->wdr_pingpong[1].dma_addr;
362 	bsp_isp_set_wdr_addr1(isp->id, addr);
363 #endif
364 	return 0;
365 }
366 #else
isp_wdr_pingpong_alloc(struct isp_dev * isp)367 static int isp_wdr_pingpong_alloc(struct isp_dev *isp)
368 {
369 	isp->wdr_mode = ISP_NORMAL_MODE;
370 
371 	return 0;
372 }
isp_wdr_pingpong_free(struct isp_dev * isp)373 static void isp_wdr_pingpong_free(struct isp_dev *isp) {}
isp_wdr_pingpong_set(struct isp_dev * isp)374 static int isp_wdr_pingpong_set(struct isp_dev *isp)
375 {
376 	return 0;
377 }
378 #endif
379 
380 #ifdef SUPPORT_ISP_TDM
__sunxi_isp_tdm_off(struct isp_dev * isp)381 static int __sunxi_isp_tdm_off(struct isp_dev *isp)
382 {
383 	struct vin_md *vind = dev_get_drvdata(isp->subdev.v4l2_dev->dev);
384 	struct vin_core *vinc = NULL;
385 	int i, j;
386 
387 	for (i = 0; i < VIN_MAX_DEV; i++) {
388 		if (vind->vinc[i] == NULL)
389 			continue;
390 		if (!vin_streaming(&vind->vinc[i]->vid_cap))
391 			continue;
392 		vinc = vind->vinc[i];
393 		for (j = 0; j < VIN_MAX_ISP; j++) {
394 			if (vinc->isp_sel == j)
395 				return -1;
396 		}
397 	}
398 	return 0;
399 }
400 #endif
401 
sunxi_isp_cal_bandwidth_memory(struct v4l2_subdev * sd,unsigned int on)402 static void sunxi_isp_cal_bandwidth_memory(struct v4l2_subdev *sd, unsigned int on)
403 {
404 	struct isp_dev *isp = v4l2_get_subdevdata(sd);
405 	struct vin_md *vind = dev_get_drvdata(isp->subdev.v4l2_dev->dev);
406 	struct v4l2_mbus_framefmt *mf = &isp->mf;
407 	__maybe_unused struct mbus_framefmt_res *res = (void *)mf->reserved;
408 	unsigned int bandw;
409 
410 	bandw = 0;
411 #if defined CONFIG_D3D
412 	bandw += isp->mf.height * isp->mf.width * 5 / 8 * 2 * res->fps * 10 / D3D_RAW_LBC_MODE;
413 #endif
414 
415 #if defined CONFIG_WDR
416 	if (res->res_wdr_mode == ISP_DOL_WDR_MODE)
417 		bandw += isp->mf.height * isp->mf.width * 3 / 2 * 2 * res->fps * 10 / WDR_RAW_LBC_MODE;
418 #endif
419 
420 	if (on)
421 		vind->isp_bd_tatol += bandw;
422 	else
423 		vind->isp_bd_tatol -= bandw;
424 
425 	vin_log(VIN_LOG_ISP, "isp%d %s bandwidth = %d.\n", isp->id, on ? "use" : "release", bandw);
426 }
427 
sunxi_isp_subdev_s_stream(struct v4l2_subdev * sd,int enable)428 static int sunxi_isp_subdev_s_stream(struct v4l2_subdev *sd, int enable)
429 {
430 	struct isp_dev *isp = v4l2_get_subdevdata(sd);
431 	struct v4l2_mbus_framefmt *mf = &isp->mf;
432 	struct mbus_framefmt_res *res = (void *)mf->reserved;
433 	struct v4l2_event event;
434 #if defined CONFIG_ARCH_SUN8IW16P1 || defined CONFIG_ARCH_SUN8IW19P1 || defined CONFIG_ARCH_SUN50IW10
435 	struct isp_wdr_mode_cfg wdr_cfg;
436 #endif
437 	unsigned int load_val;
438 	__maybe_unused int i;
439 
440 	if (!isp->use_isp)
441 		return 0;
442 
443 	switch (res->res_pix_fmt) {
444 	case V4L2_PIX_FMT_SBGGR8:
445 	case V4L2_PIX_FMT_SGBRG8:
446 	case V4L2_PIX_FMT_SGRBG8:
447 	case V4L2_PIX_FMT_SRGGB8:
448 	case V4L2_PIX_FMT_SBGGR10:
449 	case V4L2_PIX_FMT_SGBRG10:
450 	case V4L2_PIX_FMT_SGRBG10:
451 	case V4L2_PIX_FMT_SRGGB10:
452 	case V4L2_PIX_FMT_SBGGR12:
453 	case V4L2_PIX_FMT_SGBRG12:
454 	case V4L2_PIX_FMT_SGRBG12:
455 	case V4L2_PIX_FMT_SRGGB12:
456 		vin_log(VIN_LOG_FMT, "%s output fmt is raw, return directly\n", __func__);
457 		if (isp->isp_dbg.debug_en) {
458 			bsp_isp_debug_output_cfg(isp->id, 1, isp->isp_dbg.debug_sel);
459 			break;
460 		} else {
461 			return 0;
462 		}
463 	default:
464 		break;
465 	}
466 
467 	if (enable) {
468 		isp->h3a_stat.frame_number = 0;
469 		isp->ptn_isp_cnt = 0;
470 		isp->isp_ob.set_cnt = 0;
471 		isp->sensor_lp_mode = res->res_lp_mode;
472 		/*when normal to wdr, old register would lead timeout, so we clean it up*/
473 		if (isp->wdr_mode != res->res_wdr_mode) {
474 			isp->wdr_mode = res->res_wdr_mode;
475 			memcpy(isp->isp_load.vir_addr, &isp_default_reg[0], ISP_LOAD_REG_SIZE);
476 		}
477 		if (isp->load_flag)
478 			memcpy(isp->isp_load.vir_addr, &isp->load_shadow[0], ISP_LOAD_DRAM_SIZE);
479 
480 		if (isp->large_image == 0) {
481 			if (isp->runtime_flag == 0) {
482 				if (isp_3d_pingpong_alloc(isp))
483 					return -ENOMEM;
484 				isp_3d_pingpong_update(isp);
485 			} else
486 				isp->runtime_flag = 0;
487 		}
488 		if (isp->wdr_mode != ISP_NORMAL_MODE) {
489 			if (isp_wdr_pingpong_alloc(isp)) {
490 				isp_3d_pingpong_free(isp);
491 				return -ENOMEM;
492 			}
493 			isp_wdr_pingpong_set(isp);
494 		}
495 #ifndef SUPPORT_ISP_TDM
496 		bsp_isp_enable(isp->id, 1);
497 #else
498 		for (i = 0; i < VIN_MAX_ISP; i++)
499 			bsp_isp_enable(i, 1);
500 #endif
501 		bsp_isp_clr_irq_status(isp->id, ISP_IRQ_EN_ALL);
502 #if !defined CONFIG_ARCH_SUN8IW16P1 && !defined CONFIG_ARCH_SUN8IW19P1 && !defined CONFIG_ARCH_SUN50IW10
503 		bsp_isp_irq_enable(isp->id, FINISH_INT_EN | PARA_LOAD_INT_EN | SRC0_FIFO_INT_EN
504 				     | FRAME_ERROR_INT_EN | FRAME_LOST_INT_EN);
505 
506 		load_val = bsp_isp_load_update_flag(isp->id);
507 		if (isp->wdr_mode == ISP_DOL_WDR_MODE) {
508 			load_val = load_val | WDR_UPDATE;
509 			bsp_isp_module_enable(isp->id, WDR_EN);
510 			bsp_isp_set_wdr_mode(isp->id, ISP_DOL_WDR_MODE);
511 			bsp_isp_ch_enable(isp->id, ISP_CH1, 1);
512 		} else if (isp->wdr_mode == ISP_COMANDING_MODE) {
513 			load_val = load_val | WDR_UPDATE;
514 			bsp_isp_module_enable(isp->id, WDR_EN);
515 			bsp_isp_set_wdr_mode(isp->id, ISP_COMANDING_MODE);
516 		} else {
517 			load_val = load_val & ~WDR_UPDATE;
518 			bsp_isp_module_disable(isp->id, WDR_EN);
519 			bsp_isp_set_wdr_mode(isp->id, ISP_NORMAL_MODE);
520 		}
521 #else
522 		bsp_isp_irq_enable(isp->id, FINISH_INT_EN | S0_PARA_LOAD_INT_EN | S0_FIFO_INT_EN
523 				     | S0_FRAME_ERROR_INT_EN | S0_FRAME_LOST_INT_EN);
524 #if defined CONFIG_ARCH_SUN8IW19P1
525 		bsp_isp_irq_enable(isp->id, S0_BTYPE_ERROR_INT_EN | ADDR_ERROR_INT_EN | LBC_ERROR_INT_EN);
526 #endif
527 
528 		load_val = bsp_isp_load_update_flag(isp->id);
529 		if (isp->wdr_mode == ISP_DOL_WDR_MODE) {
530 			load_val = load_val | WDR_UPDATE;
531 			wdr_cfg.wdr_exp_seq = 0;
532 			wdr_cfg.wdr_ch_seq = 0;
533 			wdr_cfg.wdr_mode = 0;
534 			bsp_isp_module_enable(isp->id, WDR_EN);
535 			bsp_isp_wdr_mode_cfg(isp->id, &wdr_cfg);
536 			bsp_isp_ch_enable(isp->id, ISP_CH1, 1);
537 		} else if (isp->wdr_mode == ISP_COMANDING_MODE) {
538 			load_val = load_val | WDR_UPDATE;
539 			wdr_cfg.wdr_exp_seq = 0;
540 			wdr_cfg.wdr_ch_seq = 0;
541 			wdr_cfg.wdr_mode = ISP_COMANDING_MODE;
542 			bsp_isp_module_enable(isp->id, WDR_EN);
543 			bsp_isp_wdr_mode_cfg(isp->id, &wdr_cfg);
544 		} else {
545 			load_val = load_val & ~WDR_UPDATE;
546 			bsp_isp_module_disable(isp->id, WDR_EN);
547 		}
548 #endif
549 
550 #if !defined CONFIG_D3D
551 		bsp_isp_module_disable(isp->id, D3D_EN);
552 		load_val = load_val & ~D3D_UPDATE;
553 #endif
554 		if (isp->large_image == 2)
555 			bsp_isp_module_disable(isp->id, PLTM_EN | D3D_EN | AE_EN | AWB_EN | AF_EN | HIST_EN);
556 		bsp_isp_update_table(isp->id, load_val);
557 
558 		bsp_isp_module_enable(isp->id, SRC0_EN);
559 		bsp_isp_set_input_fmt(isp->id, isp->isp_fmt->infmt);
560 		bsp_isp_set_size(isp->id, &isp->isp_ob);
561 		bsp_isp_set_para_ready_mode(isp->id, 1);
562 		bsp_isp_set_para_ready(isp->id, PARA_READY);
563 		bsp_isp_set_last_blank_cycle(isp->id, 5);
564 		bsp_isp_set_speed_mode(isp->id, 3);
565 #if !defined CONFIG_D3D_LTF_EN && !defined CONFIG_WDR
566 		bsp_isp_set_fifo_mode(isp->id, 0);
567 		bsp_isp_fifo_raw_write(isp->id, 0x200);
568 #endif
569 		bsp_isp_ch_enable(isp->id, ISP_CH0, 1);
570 		bsp_isp_capture_start(isp->id);
571 	} else {
572 		if (!isp->nosend_ispoff && !isp->runtime_flag) {
573 			memset(&event, 0, sizeof(event));
574 			event.type = V4L2_EVENT_VIN_ISP_OFF;
575 			event.id = 0;
576 			v4l2_event_queue(isp->subdev.devnode, &event);
577 		}
578 		bsp_isp_capture_stop(isp->id);
579 		bsp_isp_module_disable(isp->id, SRC0_EN);
580 		bsp_isp_ch_enable(isp->id, ISP_CH0, 0);
581 		bsp_isp_irq_disable(isp->id, ISP_IRQ_EN_ALL);
582 		bsp_isp_clr_irq_status(isp->id, ISP_IRQ_EN_ALL);
583 #ifndef SUPPORT_ISP_TDM
584 		bsp_isp_enable(isp->id, 0);
585 #else
586 		if (__sunxi_isp_tdm_off(isp) == 0) {
587 			for (i = 0; i < VIN_MAX_ISP; i++)
588 				bsp_isp_enable(i, 0);
589 
590 		} else
591 			vin_warn("ISP is used in TDM mode, ISP%d cannot be closing when other isp is used!\n", isp->id);
592 #endif
593 		if (isp->large_image == 0) {
594 			if (isp->runtime_flag == 0)
595 				isp_3d_pingpong_free(isp);
596 			else
597 				isp->runtime_flag = 0;
598 		}
599 		if (isp->wdr_mode != ISP_NORMAL_MODE) {
600 			bsp_isp_ch_enable(isp->id, ISP_CH1, 0);
601 			isp_wdr_pingpong_free(isp);
602 		}
603 		isp->f1_after_librun = 0;
604 	}
605 
606 	sunxi_isp_cal_bandwidth_memory(sd, enable);
607 
608 	vin_log(VIN_LOG_FMT, "isp%d %s, %d*%d hoff: %d voff: %d code: %x field: %d\n",
609 		isp->id, enable ? "stream on" : "stream off",
610 		isp->isp_ob.ob_valid.width, isp->isp_ob.ob_valid.height,
611 		isp->isp_ob.ob_start.hor, isp->isp_ob.ob_start.ver,
612 		mf->code, mf->field);
613 
614 	return 0;
615 }
616 
__isp_try_format(struct isp_dev * isp,struct v4l2_mbus_framefmt * mf)617 static struct isp_pix_fmt *__isp_try_format(struct isp_dev *isp,
618 					struct v4l2_mbus_framefmt *mf)
619 {
620 	struct isp_pix_fmt *isp_fmt = NULL;
621 	struct isp_size_settings *ob = &isp->isp_ob;
622 	unsigned int i;
623 
624 	for (i = 0; i < ARRAY_SIZE(sunxi_isp_formats); ++i)
625 		if (mf->code == sunxi_isp_formats[i].mbus_code)
626 			isp_fmt = &sunxi_isp_formats[i];
627 
628 	if (isp_fmt == NULL)
629 		isp_fmt = &sunxi_isp_formats[0];
630 
631 	ob->ob_black.width = mf->width;
632 	ob->ob_black.height = mf->height;
633 
634 	if (!isp->large_image) {
635 		if (isp->id == 1) {
636 			mf->width = clamp_t(u32, mf->width, MIN_IN_WIDTH, 3264);
637 			mf->height = clamp_t(u32, mf->height, MIN_IN_HEIGHT, 3264);
638 		} else {
639 			mf->width = clamp_t(u32, mf->width, MIN_IN_WIDTH, 4224);
640 			mf->height = clamp_t(u32, mf->height, MIN_IN_HEIGHT, 4224);
641 		}
642 	}
643 
644 	ob->ob_valid.width = mf->width;
645 	ob->ob_valid.height = mf->height;
646 	ob->ob_start.hor = (ob->ob_black.width - ob->ob_valid.width) / 2;
647 	ob->ob_start.ver = (ob->ob_black.height - ob->ob_valid.height) / 2;
648 
649 	if (isp->large_image == 2) {
650 		isp->left_right = 0;
651 		isp->isp_ob.ob_valid.width = mf->width / 2 + LARGE_IMAGE_OFF;
652 	}
653 
654 	switch (mf->colorspace) {
655 	case V4L2_COLORSPACE_REC709:
656 		mf->colorspace = V4L2_COLORSPACE_REC709;
657 		break;
658 	case V4L2_COLORSPACE_BT2020:
659 		mf->colorspace = V4L2_COLORSPACE_BT2020;
660 		break;
661 	default:
662 		mf->colorspace = V4L2_COLORSPACE_JPEG;
663 		break;
664 	}
665 	return isp_fmt;
666 }
667 
sunxi_isp_s_parm(struct v4l2_subdev * sd,struct v4l2_streamparm * parms)668 int sunxi_isp_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms)
669 {
670 	struct v4l2_captureparm *cp = &parms->parm.capture;
671 	struct isp_dev *isp = v4l2_get_subdevdata(sd);
672 
673 	if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
674 		return -EINVAL;
675 
676 	isp->capture_mode = cp->capturemode;
677 	isp->large_image = cp->reserved[2];
678 
679 	return 0;
680 }
681 
sunxi_isp_g_parm(struct v4l2_subdev * sd,struct v4l2_streamparm * parms)682 int sunxi_isp_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms)
683 {
684 	struct v4l2_captureparm *cp = &parms->parm.capture;
685 	struct isp_dev *isp = v4l2_get_subdevdata(sd);
686 
687 	if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
688 		return -EINVAL;
689 
690 	memset(cp, 0, sizeof(struct v4l2_captureparm));
691 	cp->capability = V4L2_CAP_TIMEPERFRAME;
692 	cp->capturemode = isp->capture_mode;
693 
694 	return 0;
695 }
696 
sunxi_isp_subdev_get_fmt(struct v4l2_subdev * sd,struct v4l2_subdev_pad_config * cfg,struct v4l2_subdev_format * fmt)697 static int sunxi_isp_subdev_get_fmt(struct v4l2_subdev *sd,
698 				    struct v4l2_subdev_pad_config *cfg,
699 				    struct v4l2_subdev_format *fmt)
700 {
701 	struct isp_dev *isp = v4l2_get_subdevdata(sd);
702 
703 	mutex_lock(&isp->subdev_lock);
704 	fmt->format = isp->mf;
705 	mutex_unlock(&isp->subdev_lock);
706 	return 0;
707 }
708 
sunxi_isp_subdev_set_fmt(struct v4l2_subdev * sd,struct v4l2_subdev_pad_config * cfg,struct v4l2_subdev_format * fmt)709 static int sunxi_isp_subdev_set_fmt(struct v4l2_subdev *sd,
710 				    struct v4l2_subdev_pad_config *cfg,
711 				    struct v4l2_subdev_format *fmt)
712 {
713 	struct isp_dev *isp = v4l2_get_subdevdata(sd);
714 	struct v4l2_mbus_framefmt *mf = &isp->mf;
715 	struct isp_pix_fmt *isp_fmt;
716 
717 	vin_log(VIN_LOG_FMT, "%s %d*%d %x %d\n", __func__,
718 		fmt->format.width, fmt->format.height,
719 		fmt->format.code, fmt->format.field);
720 
721 	if (fmt->pad == ISP_PAD_SOURCE) {
722 		if (mf) {
723 			mutex_lock(&isp->subdev_lock);
724 			fmt->format = *mf;
725 			mutex_unlock(&isp->subdev_lock);
726 		}
727 		return 0;
728 	}
729 	isp_fmt = __isp_try_format(isp, &fmt->format);
730 	if (mf) {
731 		mutex_lock(&isp->subdev_lock);
732 		*mf = fmt->format;
733 		if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE)
734 			isp->isp_fmt = isp_fmt;
735 		mutex_unlock(&isp->subdev_lock);
736 	}
737 
738 	return 0;
739 
740 }
741 
sunxi_isp_subdev_init(struct v4l2_subdev * sd,u32 val)742 int sunxi_isp_subdev_init(struct v4l2_subdev *sd, u32 val)
743 {
744 	struct isp_dev *isp = v4l2_get_subdevdata(sd);
745 	struct vin_md *vind = dev_get_drvdata(isp->subdev.v4l2_dev->dev);
746 
747 	if (!isp->use_isp)
748 		return 0;
749 
750 	if (val && isp->use_cnt++ > 0)
751 		return 0;
752 	else if (!val && (isp->use_cnt == 0 || --isp->use_cnt > 0))
753 		return 0;
754 
755 	vin_log(VIN_LOG_ISP, "isp%d %s use_cnt = %d.\n", isp->id,
756 		val ? "init" : "uninit", isp->use_cnt);
757 
758 	if (val) {
759 		bsp_isp_ver_read_en(isp->id, 1);
760 		bsp_isp_get_isp_ver(isp->id, &vind->isp_ver_major, &vind->isp_ver_minor);
761 		bsp_isp_ver_read_en(isp->id, 0);
762 		if (!isp->have_init) {
763 			memcpy(isp->isp_load.vir_addr, &isp_default_reg[0], ISP_LOAD_REG_SIZE);
764 			memset(&isp->load_shadow[0], 0, ISP_LOAD_DRAM_SIZE);
765 			isp->load_flag = 0;
766 			isp->have_init = 1;
767 		} else {
768 #if defined CONFIG_D3D
769 			if ((isp->load_shadow[0x2d4 + 0x3]) & (1<<1)) {
770 				/* clear D3D rec_en */
771 				isp->load_shadow[0x2d4 + 0x3] = (isp->load_shadow[0x2d4 + 0x3]) & (~(1<<1));
772 				memcpy(isp->isp_load.vir_addr, &isp->load_shadow[0], ISP_LOAD_DRAM_SIZE);
773 			}
774 #endif
775 		}
776 		isp->isp_frame_number = 0;
777 		isp->h3a_stat.buf[0].empty = 1;
778 		isp->h3a_stat.buf[0].dma_addr = isp->isp_stat.dma_addr;
779 		isp->h3a_stat.buf[0].virt_addr = isp->isp_stat.vir_addr;
780 		bsp_isp_set_statistics_addr(isp->id, (dma_addr_t)isp->isp_stat.dma_addr);
781 		bsp_isp_set_saved_addr(isp->id, (unsigned long)isp->isp_save.dma_addr);
782 #if !defined CONFIG_ARCH_SUN8IW16P1 && !defined CONFIG_ARCH_SUN8IW19P1 && !defined CONFIG_ARCH_SUN50IW10
783 		bsp_isp_set_load_addr(isp->id, (unsigned long)isp->isp_load.dma_addr);
784 		bsp_isp_set_table_addr(isp->id, LENS_GAMMA_TABLE, (unsigned long)(isp->isp_lut_tbl.dma_addr));
785 		bsp_isp_set_table_addr(isp->id, DRC_TABLE, (unsigned long)(isp->isp_drc_tbl.dma_addr));
786 #else
787 		bsp_isp_set_load_addr0(isp->id, (dma_addr_t)isp->isp_load.dma_addr);
788 		bsp_isp_set_load_addr1(isp->id, (dma_addr_t)isp->isp_load.dma_addr);
789 #endif
790 		bsp_isp_set_para_ready(isp->id, PARA_NOT_READY);
791 	}
792 
793 	return 0;
794 }
795 
__isp_set_load_reg(struct v4l2_subdev * sd,struct isp_table_reg_map * reg)796 static int __isp_set_load_reg(struct v4l2_subdev *sd, struct isp_table_reg_map *reg)
797 {
798 	struct isp_dev *isp = v4l2_get_subdevdata(sd);
799 
800 	if (!isp->use_isp)
801 		return 0;
802 
803 	if (reg->size > ISP_LOAD_DRAM_SIZE) {
804 		vin_err("user ask for 0x%x data, it more than isp load_data 0x%x\n", reg->size, ISP_LOAD_DRAM_SIZE);
805 		return -EINVAL;
806 	}
807 
808 	isp->load_flag = 1;
809 	return copy_from_user(&isp->load_shadow[0], reg->addr, reg->size);
810 }
811 
812 #if !defined CONFIG_ARCH_SUN8IW16P1 && !defined CONFIG_ARCH_SUN8IW19P1 && !defined CONFIG_ARCH_SUN50IW10
__isp_set_table1_map(struct v4l2_subdev * sd,struct isp_table_reg_map * tbl)813 static int __isp_set_table1_map(struct v4l2_subdev *sd, struct isp_table_reg_map *tbl)
814 {
815 	struct isp_dev *isp = v4l2_get_subdevdata(sd);
816 	int ret;
817 
818 	if (!isp->use_isp)
819 		return 0;
820 
821 	if (tbl->size > ISP_TABLE_MAPPING1_SIZE) {
822 		vin_err("user ask for 0x%x data, it more than isp table1_data 0x%x\n", tbl->size, ISP_TABLE_MAPPING1_SIZE);
823 		return -EINVAL;
824 	}
825 
826 	ret = copy_from_user(&isp->load_shadow[0] + ISP_LOAD_REG_SIZE, tbl->addr, tbl->size);
827 	if (ret < 0) {
828 		vin_err("copy table mapping1 from usr error!\n");
829 		return ret;
830 	}
831 
832 	return 0;
833 }
834 
__isp_set_table2_map(struct v4l2_subdev * sd,struct isp_table_reg_map * tbl)835 static int __isp_set_table2_map(struct v4l2_subdev *sd, struct isp_table_reg_map *tbl)
836 {
837 	struct isp_dev *isp = v4l2_get_subdevdata(sd);
838 	int ret;
839 
840 	if (!isp->use_isp)
841 		return 0;
842 
843 	if (tbl->size > ISP_TABLE_MAPPING2_SIZE) {
844 		vin_err("user ask for 0x%x data, it more than isp table1_data 0x%x\n", tbl->size, ISP_TABLE_MAPPING2_SIZE);
845 		return -EINVAL;
846 	}
847 
848 	ret = copy_from_user(&isp->load_shadow[0] + ISP_LOAD_REG_SIZE + ISP_TABLE_MAPPING1_SIZE, tbl->addr, tbl->size);
849 	if (ret < 0) {
850 		vin_err("copy table mapping2 from usr error!\n");
851 		return ret;
852 	}
853 
854 	return 0;
855 }
856 #endif
857 
sunxi_isp_subdev_ioctl(struct v4l2_subdev * sd,unsigned int cmd,void * arg)858 static long sunxi_isp_subdev_ioctl(struct v4l2_subdev *sd, unsigned int cmd,
859 				   void *arg)
860 {
861 	int ret = 0;
862 
863 	switch (cmd) {
864 	case VIDIOC_VIN_ISP_LOAD_REG:
865 		ret = __isp_set_load_reg(sd, (struct isp_table_reg_map *)arg);
866 		break;
867 #if !defined CONFIG_ARCH_SUN8IW16P1 && !defined CONFIG_ARCH_SUN8IW19P1 && !defined CONFIG_ARCH_SUN50IW10
868 	case VIDIOC_VIN_ISP_TABLE1_MAP:
869 		ret = __isp_set_table1_map(sd, (struct isp_table_reg_map *)arg);
870 		break;
871 	case VIDIOC_VIN_ISP_TABLE2_MAP:
872 		ret = __isp_set_table2_map(sd, (struct isp_table_reg_map *)arg);
873 		break;
874 #endif
875 	default:
876 		return -ENOIOCTLCMD;
877 	}
878 
879 	return ret;
880 }
881 
882 #ifdef CONFIG_COMPAT
883 
884 struct isp_table_reg_map32 {
885 	compat_caddr_t addr;
886 	unsigned int size;
887 };
888 
889 #define VIDIOC_VIN_ISP_LOAD_REG32 \
890 	_IOWR('V', BASE_VIDIOC_PRIVATE + 70, struct isp_table_reg_map32)
891 
892 #define VIDIOC_VIN_ISP_TABLE1_MAP32 \
893 	_IOWR('V', BASE_VIDIOC_PRIVATE + 71, struct isp_table_reg_map32)
894 
895 #define VIDIOC_VIN_ISP_TABLE2_MAP32 \
896 	_IOWR('V', BASE_VIDIOC_PRIVATE + 72, struct isp_table_reg_map32)
897 
get_isp_table_reg_map32(struct isp_table_reg_map * kp,struct isp_table_reg_map32 __user * up)898 static int get_isp_table_reg_map32(struct isp_table_reg_map *kp,
899 			      struct isp_table_reg_map32 __user *up)
900 {
901 	u32 tmp;
902 
903 	if (!access_ok(up, sizeof(struct isp_table_reg_map32)) ||
904 	    get_user(kp->size, &up->size) || get_user(tmp, &up->addr))
905 		return -EFAULT;
906 	kp->addr = compat_ptr(tmp);
907 	return 0;
908 }
909 
put_isp_table_reg_map32(struct isp_table_reg_map * kp,struct isp_table_reg_map32 __user * up)910 static int put_isp_table_reg_map32(struct isp_table_reg_map *kp,
911 			      struct isp_table_reg_map32 __user *up)
912 {
913 	u32 tmp = (u32) ((unsigned long)kp->addr);
914 
915 	if (!access_ok(up, sizeof(struct isp_table_reg_map32)) ||
916 	    put_user(kp->size, &up->size) || put_user(tmp, &up->addr))
917 		return -EFAULT;
918 	return 0;
919 }
920 
isp_compat_ioctl32(struct v4l2_subdev * sd,unsigned int cmd,unsigned long arg)921 static long isp_compat_ioctl32(struct v4l2_subdev *sd,
922 		unsigned int cmd, unsigned long arg)
923 {
924 	union {
925 		struct isp_table_reg_map isd;
926 	} karg;
927 	void __user *up = compat_ptr(arg);
928 	int compatible_arg = 1;
929 	long err = 0;
930 
931 	vin_log(VIN_LOG_ISP, "%s cmd is %d\n", __func__, cmd);
932 
933 	switch (cmd) {
934 	case VIDIOC_VIN_ISP_LOAD_REG32:
935 		cmd = VIDIOC_VIN_ISP_LOAD_REG;
936 		break;
937 	case VIDIOC_VIN_ISP_TABLE1_MAP32:
938 		cmd = VIDIOC_VIN_ISP_TABLE1_MAP;
939 		break;
940 	case VIDIOC_VIN_ISP_TABLE2_MAP32:
941 		cmd = VIDIOC_VIN_ISP_TABLE2_MAP;
942 		break;
943 	}
944 
945 	switch (cmd) {
946 	case VIDIOC_VIN_ISP_LOAD_REG:
947 	case VIDIOC_VIN_ISP_TABLE1_MAP:
948 	case VIDIOC_VIN_ISP_TABLE2_MAP:
949 		err = get_isp_table_reg_map32(&karg.isd, up);
950 		compatible_arg = 0;
951 		break;
952 	}
953 
954 	if (err)
955 		return err;
956 
957 	if (compatible_arg)
958 		err = sunxi_isp_subdev_ioctl(sd, cmd, up);
959 	else {
960 		mm_segment_t old_fs = get_fs();
961 
962 		set_fs(KERNEL_DS);
963 		err = sunxi_isp_subdev_ioctl(sd, cmd, &karg);
964 		set_fs(old_fs);
965 	}
966 
967 	switch (cmd) {
968 	case VIDIOC_VIN_ISP_LOAD_REG:
969 	case VIDIOC_VIN_ISP_TABLE1_MAP:
970 	case VIDIOC_VIN_ISP_TABLE2_MAP:
971 		err = put_isp_table_reg_map32(&karg.isd, up);
972 		break;
973 	}
974 
975 	return err;
976 }
977 #endif
978 
979 /*
980  * must reset all the pipeline through isp.
981  */
sunxi_isp_reset(struct isp_dev * isp)982 void sunxi_isp_reset(struct isp_dev *isp)
983 {
984 #ifndef SUPPORT_ISP_TDM
985 	struct vin_md *vind = dev_get_drvdata(isp->subdev.v4l2_dev->dev);
986 	struct vin_core *vinc = NULL;
987 	struct prs_cap_mode mode = {.mode = VCAP};
988 	bool flags = 1;
989 	int i = 0;
990 
991 	if (!isp->use_isp)
992 		return;
993 
994 	if (!isp->subdev.entity.stream_count) {
995 		vin_err("isp%d is not used, cannot be resetted!!!\n", isp->id);
996 		return;
997 	}
998 
999 	vin_print("%s:isp%d reset!!!,ISP frame number is %d\n", __func__, isp->id, isp->isp_frame_number);
1000 
1001 	bsp_isp_set_para_ready(isp->id, PARA_NOT_READY);
1002 #if defined CONFIG_D3D
1003 	if ((isp->load_shadow[0x2d4 + 0x3]) & (1<<1)) {
1004 		/* clear D3D rec_en 0x2d4 bit25*/
1005 		isp->load_shadow[0x2d4 + 0x3] = (isp->load_shadow[0x2d4 + 0x3]) & (~(1<<1));
1006 		memcpy(isp->isp_load.vir_addr, &isp->load_shadow[0], ISP_LOAD_DRAM_SIZE);
1007 	}
1008 #endif
1009 
1010 	/*****************stop*******************/
1011 	for (i = 0; i < VIN_MAX_DEV; i++) {
1012 		if (vind->vinc[i] == NULL)
1013 			continue;
1014 		if (!vin_streaming(&vind->vinc[i]->vid_cap))
1015 			continue;
1016 
1017 		if (vind->vinc[i]->isp_sel == isp->id) {
1018 			vinc = vind->vinc[i];
1019 			vinc->vid_cap.frame_delay_cnt = 1;
1020 
1021 			if (flags) {
1022 				csic_prs_capture_stop(vinc->csi_sel);
1023 
1024 #if defined CONFIG_ARCH_SUN8IW16P1
1025 				if (vinc->mipi_sel == 0)
1026 					cmb_rx_disable(vinc->mipi_sel);
1027 #endif
1028 				csic_prs_disable(vinc->csi_sel);
1029 				csic_isp_bridge_disable(0);
1030 
1031 				bsp_isp_clr_irq_status(isp->id, ISP_IRQ_EN_ALL);
1032 				bsp_isp_enable(isp->id, 0);
1033 				bsp_isp_capture_stop(isp->id);
1034 				flags = 0;
1035 			}
1036 			vipp_disable(vinc->vipp_sel);
1037 			vipp_top_clk_en(vinc->vipp_sel, 0);
1038 			csic_dma_int_clear_status(vinc->vipp_sel, DMA_INT_ALL);
1039 			csic_dma_top_disable(vinc->vipp_sel);
1040 		}
1041 	}
1042 
1043 	/*****************start*******************/
1044 	flags = 1;
1045 	for (i = 0; i < VIN_MAX_DEV; i++) {
1046 		if (vind->vinc[i] == NULL)
1047 			continue;
1048 		if (!vin_streaming(&vind->vinc[i]->vid_cap))
1049 			continue;
1050 
1051 		if (vind->vinc[i]->isp_sel == isp->id) {
1052 			vinc = vind->vinc[i];
1053 
1054 			csic_dma_top_enable(vinc->vipp_sel);
1055 			vipp_top_clk_en(vinc->vipp_sel, 1);
1056 			vipp_enable(vinc->vipp_sel);
1057 			vinc->vin_status.frame_cnt = 0;
1058 			vinc->vin_status.lost_cnt = 0;
1059 
1060 			if (flags) {
1061 				bsp_isp_enable(isp->id, 1);
1062 				bsp_isp_set_para_ready(isp->id, PARA_READY);
1063 				bsp_isp_capture_start(isp->id);
1064 				isp->isp_frame_number = 0;
1065 
1066 				csic_isp_bridge_enable(0);
1067 
1068 				csic_prs_enable(vinc->csi_sel);
1069 
1070 #if defined CONFIG_ARCH_SUN8IW16P1
1071 				if (vinc->mipi_sel == 0)
1072 					cmb_rx_enable(vinc->mipi_sel);
1073 #endif
1074 
1075 				csic_prs_capture_start(vinc->csi_sel, 1, &mode);
1076 				flags = 0;
1077 			}
1078 		}
1079 	}
1080 
1081 	if (isp->sensor_lp_mode)
1082 		schedule_work(&isp->s_sensor_stby_task);
1083 #endif
1084 }
1085 
sunxi_isp_frame_sync_isr(struct v4l2_subdev * sd)1086 void sunxi_isp_frame_sync_isr(struct v4l2_subdev *sd)
1087 {
1088 	struct isp_dev *isp = v4l2_get_subdevdata(sd);
1089 	struct v4l2_event event;
1090 	static short isp_log_param;
1091 	bool send_event = 0;
1092 
1093 	memset(&event, 0, sizeof(event));
1094 	event.type = V4L2_EVENT_FRAME_SYNC;
1095 	event.id = 0;
1096 	event.u.data[0] = 1;/*load type (0: load seperate; 1: load together)*/
1097 	switch (isp->mf.colorspace) {
1098 	case V4L2_COLORSPACE_REC709:
1099 		event.u.data[1] = 1;
1100 		break;
1101 	case V4L2_COLORSPACE_BT2020:
1102 		event.u.data[1] = 2;
1103 		break;
1104 	default:
1105 		event.u.data[1] = 0;
1106 		break;
1107 	}
1108 	if (isp_log_param != (vin_log_mask >> 16)) {
1109 		isp_log_param = vin_log_mask >> 16;
1110 		send_event = 1;
1111 	} else {
1112 		send_event = 0;
1113 	}
1114 	event.u.data[2] = isp_log_param;
1115 	event.u.data[3] = isp_log_param >> 8;
1116 	if ((isp->h3a_stat.frame_number < 2) || send_event)
1117 		v4l2_event_queue(isp->subdev.devnode, &event);
1118 
1119 	isp_stat_isr(&isp->h3a_stat);
1120 }
1121 
sunxi_isp_subscribe_event(struct v4l2_subdev * sd,struct v4l2_fh * fh,struct v4l2_event_subscription * sub)1122 int sunxi_isp_subscribe_event(struct v4l2_subdev *sd,
1123 				  struct v4l2_fh *fh,
1124 				  struct v4l2_event_subscription *sub)
1125 {
1126 	vin_log(VIN_LOG_ISP, "%s id = %d\n", __func__, sub->id);
1127 	if (sub->type == V4L2_EVENT_CTRL)
1128 		return v4l2_ctrl_subdev_subscribe_event(sd, fh, sub);
1129 	else
1130 		return v4l2_event_subscribe(fh, sub, 1, NULL);
1131 }
1132 
1133 static const struct v4l2_subdev_core_ops sunxi_isp_subdev_core_ops = {
1134 	.init = sunxi_isp_subdev_init,
1135 	.ioctl = sunxi_isp_subdev_ioctl,
1136 #ifdef CONFIG_COMPAT
1137 	.compat_ioctl32 = isp_compat_ioctl32,
1138 #endif
1139 	.subscribe_event = sunxi_isp_subscribe_event,
1140 	.unsubscribe_event = v4l2_event_subdev_unsubscribe,
1141 };
1142 
1143 static const struct v4l2_subdev_video_ops sunxi_isp_subdev_video_ops = {
1144 	.s_stream = sunxi_isp_subdev_s_stream,
1145 };
1146 
1147 static const struct v4l2_subdev_pad_ops sunxi_isp_subdev_pad_ops = {
1148 	.get_fmt = sunxi_isp_subdev_get_fmt,
1149 	.set_fmt = sunxi_isp_subdev_set_fmt,
1150 };
1151 
1152 static struct v4l2_subdev_ops sunxi_isp_subdev_ops = {
1153 	.core = &sunxi_isp_subdev_core_ops,
1154 	.video = &sunxi_isp_subdev_video_ops,
1155 	.pad = &sunxi_isp_subdev_pad_ops,
1156 };
1157 
__sunxi_isp_ctrl(struct isp_dev * isp,struct v4l2_ctrl * ctrl)1158 static int __sunxi_isp_ctrl(struct isp_dev *isp, struct v4l2_ctrl *ctrl)
1159 {
1160 	int ret = 0;
1161 
1162 	if (ctrl->flags & V4L2_CTRL_FLAG_INACTIVE)
1163 		return 0;
1164 
1165 	switch (ctrl->id) {
1166 	case V4L2_CID_BRIGHTNESS:
1167 	case V4L2_CID_CONTRAST:
1168 	case V4L2_CID_SATURATION:
1169 	case V4L2_CID_HUE:
1170 	case V4L2_CID_AUTO_WHITE_BALANCE:
1171 	case V4L2_CID_EXPOSURE:
1172 	case V4L2_CID_AUTOGAIN:
1173 	case V4L2_CID_GAIN:
1174 	case V4L2_CID_POWER_LINE_FREQUENCY:
1175 	case V4L2_CID_HUE_AUTO:
1176 	case V4L2_CID_WHITE_BALANCE_TEMPERATURE:
1177 	case V4L2_CID_SHARPNESS:
1178 	case V4L2_CID_CHROMA_AGC:
1179 	case V4L2_CID_COLORFX:
1180 	case V4L2_CID_AUTOBRIGHTNESS:
1181 	case V4L2_CID_BAND_STOP_FILTER:
1182 	case V4L2_CID_ILLUMINATORS_1:
1183 	case V4L2_CID_ILLUMINATORS_2:
1184 	case V4L2_CID_EXPOSURE_AUTO:
1185 	case V4L2_CID_EXPOSURE_ABSOLUTE:
1186 	case V4L2_CID_EXPOSURE_AUTO_PRIORITY:
1187 	case V4L2_CID_FOCUS_ABSOLUTE:
1188 	case V4L2_CID_FOCUS_RELATIVE:
1189 	case V4L2_CID_FOCUS_AUTO:
1190 	case V4L2_CID_AUTO_EXPOSURE_BIAS:
1191 	case V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE:
1192 	case V4L2_CID_WIDE_DYNAMIC_RANGE:
1193 	case V4L2_CID_IMAGE_STABILIZATION:
1194 	case V4L2_CID_ISO_SENSITIVITY:
1195 	case V4L2_CID_ISO_SENSITIVITY_AUTO:
1196 	case V4L2_CID_EXPOSURE_METERING:
1197 	case V4L2_CID_SCENE_MODE:
1198 	case V4L2_CID_3A_LOCK:
1199 	case V4L2_CID_AUTO_FOCUS_START:
1200 	case V4L2_CID_AUTO_FOCUS_STOP:
1201 	case V4L2_CID_AUTO_FOCUS_RANGE:
1202 	case V4L2_CID_FLASH_LED_MODE:
1203 	case V4L2_CID_AUTO_FOCUS_INIT:
1204 	case V4L2_CID_AUTO_FOCUS_RELEASE:
1205 	case V4L2_CID_FLASH_LED_MODE_V1:
1206 	case V4L2_CID_TAKE_PICTURE:
1207 		break;
1208 	default:
1209 		break;
1210 	}
1211 	return ret;
1212 }
1213 
1214 #define ctrl_to_sunxi_isp(ctrl) \
1215 	container_of(ctrl->handler, struct isp_dev, ctrls.handler)
1216 
sunxi_isp_s_ctrl(struct v4l2_ctrl * ctrl)1217 static int sunxi_isp_s_ctrl(struct v4l2_ctrl *ctrl)
1218 {
1219 	struct isp_dev *isp = ctrl_to_sunxi_isp(ctrl);
1220 	unsigned long flags;
1221 	int ret;
1222 
1223 	vin_log(VIN_LOG_ISP, "%s, val = %d, cur.val = %d\n",
1224 		v4l2_ctrl_get_name(ctrl->id), ctrl->val, ctrl->cur.val);
1225 	spin_lock_irqsave(&isp->slock, flags);
1226 	ret = __sunxi_isp_ctrl(isp, ctrl);
1227 	spin_unlock_irqrestore(&isp->slock, flags);
1228 
1229 	return ret;
1230 }
1231 
sunxi_isp_try_ctrl(struct v4l2_ctrl * ctrl)1232 static int sunxi_isp_try_ctrl(struct v4l2_ctrl *ctrl)
1233 {
1234 	/*
1235 	 * to cheat control framework, because of  when ctrl->cur.val == ctrl->val
1236 	 * s_ctrl would not be called
1237 	 */
1238 	if ((ctrl->minimum == 0) && (ctrl->maximum == 1)) {
1239 		if (ctrl->val)
1240 			ctrl->cur.val = 0;
1241 		else
1242 			ctrl->cur.val = 1;
1243 	} else {
1244 		if (ctrl->val == ctrl->maximum)
1245 			ctrl->cur.val = ctrl->val - 1;
1246 		else
1247 			ctrl->cur.val = ctrl->val + 1;
1248 	}
1249 
1250 	/*
1251 	 * to cheat control framework, because of  when ctrl->flags is
1252 	 * V4L2_CTRL_FLAG_VOLATILE, s_ctrl would not be called
1253 	 */
1254 	switch (ctrl->id) {
1255 	case V4L2_CID_EXPOSURE:
1256 	case V4L2_CID_EXPOSURE_ABSOLUTE:
1257 	case V4L2_CID_GAIN:
1258 		if (ctrl->val != ctrl->cur.val)
1259 			ctrl->flags &= ~V4L2_CTRL_FLAG_VOLATILE;
1260 		break;
1261 	default:
1262 		break;
1263 	}
1264 	return 0;
1265 }
1266 
1267 static const struct v4l2_ctrl_ops sunxi_isp_ctrl_ops = {
1268 	.s_ctrl = sunxi_isp_s_ctrl,
1269 	.try_ctrl = sunxi_isp_try_ctrl,
1270 };
1271 
1272 static const struct v4l2_ctrl_config ae_win_ctrls[] = {
1273 	{
1274 		.ops = &sunxi_isp_ctrl_ops,
1275 		.id = V4L2_CID_AE_WIN_X1,
1276 		.name = "R GAIN",
1277 		.type = V4L2_CTRL_TYPE_INTEGER,
1278 		.min = 32,
1279 		.max = 3264,
1280 		.step = 16,
1281 		.def = 256,
1282 		.flags = V4L2_CTRL_FLAG_VOLATILE,
1283 	}, {
1284 		.ops = &sunxi_isp_ctrl_ops,
1285 		.id = V4L2_CID_AE_WIN_Y1,
1286 		.name = "R GAIN",
1287 		.type = V4L2_CTRL_TYPE_INTEGER,
1288 		.min = 32,
1289 		.max = 3264,
1290 		.step = 16,
1291 		.def = 256,
1292 		.flags = V4L2_CTRL_FLAG_VOLATILE,
1293 	}, {
1294 		.ops = &sunxi_isp_ctrl_ops,
1295 		.id = V4L2_CID_AE_WIN_X2,
1296 		.name = "R GAIN",
1297 		.type = V4L2_CTRL_TYPE_INTEGER,
1298 		.min = 32,
1299 		.max = 3264,
1300 		.step = 16,
1301 		.def = 256,
1302 		.flags = V4L2_CTRL_FLAG_VOLATILE,
1303 	}, {
1304 		.ops = &sunxi_isp_ctrl_ops,
1305 		.id = V4L2_CID_AE_WIN_Y2,
1306 		.name = "R GAIN",
1307 		.type = V4L2_CTRL_TYPE_INTEGER,
1308 		.min = 32,
1309 		.max = 3264,
1310 		.step = 16,
1311 		.def = 256,
1312 		.flags = V4L2_CTRL_FLAG_VOLATILE,
1313 	}
1314 };
1315 
1316 static const struct v4l2_ctrl_config af_win_ctrls[] = {
1317 	{
1318 		.ops = &sunxi_isp_ctrl_ops,
1319 		.id = V4L2_CID_AF_WIN_X1,
1320 		.name = "R GAIN",
1321 		.type = V4L2_CTRL_TYPE_INTEGER,
1322 		.min = 32,
1323 		.max = 3264,
1324 		.step = 16,
1325 		.def = 256,
1326 		.flags = V4L2_CTRL_FLAG_VOLATILE,
1327 	}, {
1328 		.ops = &sunxi_isp_ctrl_ops,
1329 		.id = V4L2_CID_AF_WIN_Y1,
1330 		.name = "R GAIN",
1331 		.type = V4L2_CTRL_TYPE_INTEGER,
1332 		.min = 32,
1333 		.max = 3264,
1334 		.step = 16,
1335 		.def = 256,
1336 		.flags = V4L2_CTRL_FLAG_VOLATILE,
1337 	}, {
1338 		.ops = &sunxi_isp_ctrl_ops,
1339 		.id = V4L2_CID_AF_WIN_X2,
1340 		.name = "R GAIN",
1341 		.type = V4L2_CTRL_TYPE_INTEGER,
1342 		.min = 32,
1343 		.max = 3264,
1344 		.step = 16,
1345 		.def = 256,
1346 		.flags = V4L2_CTRL_FLAG_VOLATILE,
1347 	}, {
1348 		.ops = &sunxi_isp_ctrl_ops,
1349 		.id = V4L2_CID_AF_WIN_Y2,
1350 		.name = "R GAIN",
1351 		.type = V4L2_CTRL_TYPE_INTEGER,
1352 		.min = 32,
1353 		.max = 3264,
1354 		.step = 16,
1355 		.def = 256,
1356 		.flags = V4L2_CTRL_FLAG_VOLATILE,
1357 	}
1358 };
1359 
1360 static const struct v4l2_ctrl_config custom_ctrls[] = {
1361 	{
1362 		.ops = &sunxi_isp_ctrl_ops,
1363 		.id = V4L2_CID_FOCUS_LENGTH,
1364 		.name = "Focus Length",
1365 		.type = V4L2_CTRL_TYPE_INTEGER,
1366 		.min = 0,
1367 		.max = 1000,
1368 		.step = 1,
1369 		.def = 280,
1370 		.flags = V4L2_CTRL_FLAG_VOLATILE,
1371 	}, {
1372 		.ops = &sunxi_isp_ctrl_ops,
1373 		.id = V4L2_CID_AUTO_FOCUS_INIT,
1374 		.name = "AutoFocus Initial",
1375 		.type = V4L2_CTRL_TYPE_BUTTON,
1376 		.min = 0,
1377 		.max = 0,
1378 		.step = 0,
1379 		.def = 0,
1380 	}, {
1381 		.ops = &sunxi_isp_ctrl_ops,
1382 		.id = V4L2_CID_AUTO_FOCUS_RELEASE,
1383 		.name = "AutoFocus Release",
1384 		.type = V4L2_CTRL_TYPE_BUTTON,
1385 		.min = 0,
1386 		.max = 0,
1387 		.step = 0,
1388 		.def = 0,
1389 	}, {
1390 		.ops = &sunxi_isp_ctrl_ops,
1391 		.id = V4L2_CID_TAKE_PICTURE,
1392 		.name = "Take Picture",
1393 		.type = V4L2_CTRL_TYPE_INTEGER,
1394 		.min = 0,
1395 		.max = 16,
1396 		.step = 1,
1397 		.def = 0,
1398 	}, {
1399 		.ops = &sunxi_isp_ctrl_ops,
1400 		.id = V4L2_CID_FLASH_LED_MODE_V1,
1401 		.name = "VIN Flash ctrl",
1402 		.type = V4L2_CTRL_TYPE_MENU,
1403 		.min = 0,
1404 		.max = 2,
1405 		.def = 0,
1406 		.menu_skip_mask = 0x0,
1407 		.qmenu = flash_led_mode_v1,
1408 		.flags = 0,
1409 		.step = 0,
1410 	},
1411 };
1412 static const s64 iso_qmenu[] = {
1413 	100, 200, 400, 800, 1600, 3200, 6400,
1414 };
1415 static const s64 exp_bias_qmenu[] = {
1416 	-4, -3, -2, -1, 0, 1, 2, 3, 4,
1417 };
1418 
__isp_init_subdev(struct isp_dev * isp)1419 int __isp_init_subdev(struct isp_dev *isp)
1420 {
1421 	struct v4l2_ctrl_handler *handler = &isp->ctrls.handler;
1422 	struct v4l2_subdev *sd = &isp->subdev;
1423 	struct sunxi_isp_ctrls *ctrls = &isp->ctrls;
1424 	struct v4l2_ctrl *ctrl;
1425 	int i, ret;
1426 
1427 	mutex_init(&isp->subdev_lock);
1428 	v4l2_subdev_init(sd, &sunxi_isp_subdev_ops);
1429 	sd->grp_id = VIN_GRP_ID_ISP;
1430 	sd->flags |= V4L2_SUBDEV_FL_HAS_EVENTS | V4L2_SUBDEV_FL_HAS_DEVNODE;
1431 	snprintf(sd->name, sizeof(sd->name), "sunxi_isp.%u", isp->id);
1432 	v4l2_set_subdevdata(sd, isp);
1433 
1434 	v4l2_ctrl_handler_init(handler, 38 + ARRAY_SIZE(ae_win_ctrls)
1435 		+ ARRAY_SIZE(af_win_ctrls) + ARRAY_SIZE(custom_ctrls));
1436 
1437 	for (i = 0; i < ARRAY_SIZE(ae_win_ctrls); i++)
1438 		ctrls->ae_win[i] = v4l2_ctrl_new_custom(handler,
1439 						&ae_win_ctrls[i], NULL);
1440 	v4l2_ctrl_cluster(ARRAY_SIZE(ae_win_ctrls), &ctrls->ae_win[0]);
1441 
1442 	for (i = 0; i < ARRAY_SIZE(af_win_ctrls); i++)
1443 		ctrls->af_win[i] = v4l2_ctrl_new_custom(handler,
1444 						&af_win_ctrls[i], NULL);
1445 	v4l2_ctrl_cluster(ARRAY_SIZE(af_win_ctrls), &ctrls->af_win[0]);
1446 
1447 	v4l2_ctrl_new_std(handler, &sunxi_isp_ctrl_ops, V4L2_CID_BRIGHTNESS, -128, 128, 1, 0);
1448 	v4l2_ctrl_new_std(handler, &sunxi_isp_ctrl_ops, V4L2_CID_CONTRAST, -128, 128, 1, 0);
1449 	v4l2_ctrl_new_std(handler, &sunxi_isp_ctrl_ops, V4L2_CID_SATURATION, -256, 512, 1, 0);
1450 	v4l2_ctrl_new_std(handler, &sunxi_isp_ctrl_ops, V4L2_CID_HUE, -180, 180, 1, 0);
1451 	v4l2_ctrl_new_std(handler, &sunxi_isp_ctrl_ops, V4L2_CID_AUTO_WHITE_BALANCE, 0, 1, 1, 1);
1452 	v4l2_ctrl_new_std(handler, &sunxi_isp_ctrl_ops, V4L2_CID_EXPOSURE, 1, 65536 * 16, 1, 1);
1453 	v4l2_ctrl_new_std(handler, &sunxi_isp_ctrl_ops, V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
1454 	v4l2_ctrl_new_std(handler, &sunxi_isp_ctrl_ops, V4L2_CID_GAIN, 16, 6000 * 16, 1, 16);
1455 
1456 	v4l2_ctrl_new_std_menu(handler, &sunxi_isp_ctrl_ops,
1457 			       V4L2_CID_POWER_LINE_FREQUENCY,
1458 			       V4L2_CID_POWER_LINE_FREQUENCY_AUTO, 0,
1459 			       V4L2_CID_POWER_LINE_FREQUENCY_AUTO);
1460 	v4l2_ctrl_new_std(handler, &sunxi_isp_ctrl_ops, V4L2_CID_HUE_AUTO, 0, 1, 1, 1);
1461 	v4l2_ctrl_new_std(handler, &sunxi_isp_ctrl_ops,
1462 			  V4L2_CID_WHITE_BALANCE_TEMPERATURE, 2800, 10000, 1, 6500);
1463 	v4l2_ctrl_new_std(handler, &sunxi_isp_ctrl_ops, V4L2_CID_SHARPNESS, 0, 1000, 1, 0);
1464 	v4l2_ctrl_new_std(handler, &sunxi_isp_ctrl_ops, V4L2_CID_CHROMA_AGC, 0, 1, 1, 1);
1465 	v4l2_ctrl_new_std_menu(handler, &sunxi_isp_ctrl_ops, V4L2_CID_COLORFX,
1466 			       V4L2_COLORFX_SET_CBCR, 0, V4L2_COLORFX_NONE);
1467 	v4l2_ctrl_new_std(handler, &sunxi_isp_ctrl_ops, V4L2_CID_AUTOBRIGHTNESS, 0, 1, 1, 1);
1468 	v4l2_ctrl_new_std(handler, &sunxi_isp_ctrl_ops, V4L2_CID_BAND_STOP_FILTER, 0, 1, 1, 1);
1469 	v4l2_ctrl_new_std(handler, &sunxi_isp_ctrl_ops, V4L2_CID_ILLUMINATORS_1, 0, 1, 1, 0);
1470 	v4l2_ctrl_new_std(handler, &sunxi_isp_ctrl_ops, V4L2_CID_ILLUMINATORS_2, 0, 1, 1, 0);
1471 	v4l2_ctrl_new_std_menu(handler, &sunxi_isp_ctrl_ops, V4L2_CID_EXPOSURE_AUTO,
1472 			       V4L2_EXPOSURE_APERTURE_PRIORITY, 0,
1473 			       V4L2_EXPOSURE_AUTO);
1474 	v4l2_ctrl_new_std(handler, &sunxi_isp_ctrl_ops, V4L2_CID_EXPOSURE_ABSOLUTE, 1, 30 * 1000000, 1, 1);
1475 	v4l2_ctrl_new_std(handler, &sunxi_isp_ctrl_ops, V4L2_CID_EXPOSURE_AUTO_PRIORITY, 0, 1, 1, 0);
1476 	v4l2_ctrl_new_std(handler, &sunxi_isp_ctrl_ops, V4L2_CID_FOCUS_ABSOLUTE, 0, 127, 1, 0);
1477 	v4l2_ctrl_new_std(handler, &sunxi_isp_ctrl_ops, V4L2_CID_FOCUS_RELATIVE, -127, 127, 1, 0);
1478 	v4l2_ctrl_new_std(handler, &sunxi_isp_ctrl_ops, V4L2_CID_FOCUS_AUTO, 0, 1, 1, 1);
1479 	v4l2_ctrl_new_int_menu(handler, &sunxi_isp_ctrl_ops, V4L2_CID_AUTO_EXPOSURE_BIAS,
1480 			       ARRAY_SIZE(exp_bias_qmenu) - 1,
1481 			       ARRAY_SIZE(exp_bias_qmenu) / 2, exp_bias_qmenu);
1482 	v4l2_ctrl_new_std_menu(handler, &sunxi_isp_ctrl_ops,
1483 			       V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE,
1484 			       V4L2_WHITE_BALANCE_SHADE, 0,
1485 			       V4L2_WHITE_BALANCE_AUTO);
1486 	v4l2_ctrl_new_std(handler, &sunxi_isp_ctrl_ops, V4L2_CID_WIDE_DYNAMIC_RANGE, 0, 1, 1, 0);
1487 	v4l2_ctrl_new_std(handler, &sunxi_isp_ctrl_ops, V4L2_CID_IMAGE_STABILIZATION, 0, 1, 1, 0);
1488 	v4l2_ctrl_new_int_menu(handler, &sunxi_isp_ctrl_ops, V4L2_CID_ISO_SENSITIVITY,
1489 			       ARRAY_SIZE(iso_qmenu) - 1,
1490 			       ARRAY_SIZE(iso_qmenu) / 2 - 1, iso_qmenu);
1491 	v4l2_ctrl_new_std_menu(handler, &sunxi_isp_ctrl_ops,
1492 			       V4L2_CID_ISO_SENSITIVITY_AUTO,
1493 			       V4L2_ISO_SENSITIVITY_AUTO, 0,
1494 			       V4L2_ISO_SENSITIVITY_AUTO);
1495 	v4l2_ctrl_new_std_menu(handler, &sunxi_isp_ctrl_ops,
1496 			       V4L2_CID_EXPOSURE_METERING,
1497 			       V4L2_EXPOSURE_METERING_MATRIX, 0,
1498 			       V4L2_EXPOSURE_METERING_AVERAGE);
1499 	v4l2_ctrl_new_std_menu(handler, &sunxi_isp_ctrl_ops, V4L2_CID_SCENE_MODE,
1500 			       V4L2_SCENE_MODE_TEXT, 0, V4L2_SCENE_MODE_NONE);
1501 	ctrl = v4l2_ctrl_new_std(handler, &sunxi_isp_ctrl_ops, V4L2_CID_3A_LOCK, 0, 7, 0, 0);
1502 	if (ctrl != NULL)
1503 		ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
1504 
1505 	v4l2_ctrl_new_std(handler, &sunxi_isp_ctrl_ops, V4L2_CID_AUTO_FOCUS_START, 0, 0, 0, 0);
1506 	v4l2_ctrl_new_std(handler, &sunxi_isp_ctrl_ops, V4L2_CID_AUTO_FOCUS_STOP, 0, 0, 0, 0);
1507 	ctrl = v4l2_ctrl_new_std(handler, &sunxi_isp_ctrl_ops, V4L2_CID_AUTO_FOCUS_STATUS, 0, 7, 0, 0);
1508 	if (ctrl != NULL)
1509 		ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
1510 
1511 	v4l2_ctrl_new_std_menu(handler, &sunxi_isp_ctrl_ops, V4L2_CID_AUTO_FOCUS_RANGE,
1512 			       V4L2_AUTO_FOCUS_RANGE_INFINITY, 0,
1513 			       V4L2_AUTO_FOCUS_RANGE_AUTO);
1514 	v4l2_ctrl_new_std_menu(handler, &sunxi_isp_ctrl_ops, V4L2_CID_FLASH_LED_MODE,
1515 			       V4L2_FLASH_LED_MODE_RED_EYE, 0,
1516 			       V4L2_FLASH_LED_MODE_NONE);
1517 
1518 	for (i = 0; i < ARRAY_SIZE(custom_ctrls); i++)
1519 		v4l2_ctrl_new_custom(handler, &custom_ctrls[i], NULL);
1520 
1521 	if (handler->error)
1522 		return handler->error;
1523 
1524 	/*sd->entity->ops = &isp_media_ops;*/
1525 	isp->isp_pads[ISP_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
1526 	isp->isp_pads[ISP_PAD_SOURCE_ST].flags = MEDIA_PAD_FL_SOURCE;
1527 	isp->isp_pads[ISP_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
1528 	sd->entity.function = MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER;
1529 
1530 	ret = media_entity_pads_init(&sd->entity, ISP_PAD_NUM, isp->isp_pads);
1531 	if (ret < 0)
1532 		return ret;
1533 
1534 	sd->ctrl_handler = handler;
1535 	/*sd->internal_ops = &sunxi_isp_sd_internal_ops;*/
1536 	return 0;
1537 }
1538 
isp_resource_alloc(struct isp_dev * isp)1539 static int isp_resource_alloc(struct isp_dev *isp)
1540 {
1541 	int ret = 0;
1542 #if !defined CONFIG_ARCH_SUN8IW16P1 && !defined CONFIG_ARCH_SUN8IW19P1 && !defined CONFIG_ARCH_SUN50IW10
1543 	isp->isp_stat.size = ISP_SAVE_DRAM_SIZE + ISP_LOAD_DRAM_SIZE;
1544 	ret = os_mem_alloc(&isp->pdev->dev, &isp->isp_stat);
1545 	if (ret < 0) {
1546 		vin_err("isp statistic buf requset failed!\n");
1547 		return -ENOMEM;
1548 	}
1549 	isp->isp_save.dma_addr = isp->isp_stat.dma_addr + ISP_STAT_TOTAL_SIZE;
1550 	isp->isp_save.vir_addr = isp->isp_stat.vir_addr + ISP_STAT_TOTAL_SIZE;
1551 	isp->isp_load.dma_addr = isp->isp_save.dma_addr + ISP_SAVED_REG_SIZE;
1552 	isp->isp_load.vir_addr = isp->isp_save.vir_addr + ISP_SAVED_REG_SIZE;
1553 	isp->isp_lut_tbl.dma_addr = isp->isp_load.dma_addr + ISP_LOAD_REG_SIZE;
1554 	isp->isp_lut_tbl.vir_addr = isp->isp_load.vir_addr + ISP_LOAD_REG_SIZE;
1555 	isp->isp_drc_tbl.dma_addr = isp->isp_lut_tbl.dma_addr + ISP_TABLE_MAPPING1_SIZE;
1556 	isp->isp_drc_tbl.vir_addr = isp->isp_lut_tbl.vir_addr + ISP_TABLE_MAPPING1_SIZE;
1557 #else
1558 	isp->isp_stat.size = ISP_SAVE_DRAM_SIZE + ISP_LOAD_DRAM_SIZE;
1559 	ret = os_mem_alloc(&isp->pdev->dev, &isp->isp_stat);
1560 	if (ret < 0) {
1561 		vin_err("isp statistic buf requset failed!\n");
1562 		return -ENOMEM;
1563 	}
1564 	isp->isp_load.dma_addr = isp->isp_stat.dma_addr + ISP_STAT_TOTAL_SIZE;
1565 	isp->isp_load.vir_addr = isp->isp_stat.vir_addr + ISP_STAT_TOTAL_SIZE;
1566 	isp->isp_save.dma_addr = isp->isp_stat.dma_addr;
1567 	isp->isp_save.vir_addr = isp->isp_stat.vir_addr;
1568 #endif
1569 	return ret;
1570 }
isp_resource_free(struct isp_dev * isp)1571 static void isp_resource_free(struct isp_dev *isp)
1572 {
1573 	os_mem_free(&isp->pdev->dev, &isp->isp_stat);
1574 }
1575 
isp_isr(int irq,void * priv)1576 static irqreturn_t isp_isr(int irq, void *priv)
1577 {
1578 	struct isp_dev *isp = (struct isp_dev *)priv;
1579 	unsigned int load_val;
1580 	unsigned long flags;
1581 
1582 	if (!isp->use_isp)
1583 		return 0;
1584 
1585 	if (isp->subdev.entity.stream_count == 0) {
1586 		bsp_isp_clr_irq_status(isp->id, ISP_IRQ_EN_ALL);
1587 		return IRQ_HANDLED;
1588 	}
1589 
1590 	vin_log(VIN_LOG_ISP, "isp%d interrupt, status is 0x%x!!!\n", isp->id,
1591 		bsp_isp_get_irq_status(isp->id, ISP_IRQ_STATUS_ALL));
1592 
1593 	spin_lock_irqsave(&isp->slock, flags);
1594 #if !defined CONFIG_ARCH_SUN8IW16P1 && !defined CONFIG_ARCH_SUN8IW19P1 && !defined CONFIG_ARCH_SUN50IW10
1595 	if (bsp_isp_get_irq_status(isp->id, SRC0_FIFO_OF_PD)) {
1596 		vin_err("isp%d source0 fifo overflow\n", isp->id);
1597 		bsp_isp_clr_irq_status(isp->id, SRC0_FIFO_OF_PD);
1598 		if (bsp_isp_get_irq_status(isp->id, CIN_FIFO_OF_PD)) {
1599 			vin_err("isp%d Cin0 fifo overflow\n", isp->id);
1600 			bsp_isp_clr_irq_status(isp->id, CIN_FIFO_OF_PD);
1601 		}
1602 		if (bsp_isp_get_irq_status(isp->id, DPC_FIFO_OF_PD)) {
1603 			vin_err("isp%d DPC fifo overflow\n", isp->id);
1604 			bsp_isp_clr_irq_status(isp->id, DPC_FIFO_OF_PD);
1605 		}
1606 		if (bsp_isp_get_irq_status(isp->id, D2D_FIFO_OF_PD)) {
1607 			vin_err("isp%d D2D fifo overflow\n", isp->id);
1608 			bsp_isp_clr_irq_status(isp->id, D2D_FIFO_OF_PD);
1609 		}
1610 		if (bsp_isp_get_irq_status(isp->id, BIS_FIFO_OF_PD)) {
1611 			vin_err("isp%d BIS fifo overflow\n", isp->id);
1612 			bsp_isp_clr_irq_status(isp->id, BIS_FIFO_OF_PD);
1613 		}
1614 		if (bsp_isp_get_irq_status(isp->id, CNR_FIFO_OF_PD)) {
1615 			vin_err("isp%d CNR fifo overflow\n", isp->id);
1616 			bsp_isp_clr_irq_status(isp->id, CNR_FIFO_OF_PD);
1617 		}
1618 		if (bsp_isp_get_irq_status(isp->id, PLTM_FIFO_OF_PD)) {
1619 			vin_err("isp%d PLTM fifo overflow\n", isp->id);
1620 			bsp_isp_clr_irq_status(isp->id, PLTM_FIFO_OF_PD);
1621 		}
1622 		if (bsp_isp_get_irq_status(isp->id, D3D_WRITE_FIFO_OF_PD)) {
1623 			vin_err("isp%d D3D cmp write to DDR fifo overflow\n", isp->id);
1624 			bsp_isp_clr_irq_status(isp->id, D3D_WRITE_FIFO_OF_PD);
1625 		}
1626 		if (bsp_isp_get_irq_status(isp->id, D3D_READ_FIFO_OF_PD)) {
1627 			vin_err("isp%d D3D umcmp read from DDR fifo empty\n", isp->id);
1628 			bsp_isp_clr_irq_status(isp->id, D3D_READ_FIFO_OF_PD);
1629 		}
1630 		if (bsp_isp_get_irq_status(isp->id, D3D_WT2CMP_FIFO_OF_PD)) {
1631 			vin_err("isp%d D3D write to cmp fifo overflow\n", isp->id);
1632 			bsp_isp_clr_irq_status(isp->id, D3D_WT2CMP_FIFO_OF_PD);
1633 		}
1634 
1635 		if (bsp_isp_get_irq_status(isp->id, WDR_WRITE_FIFO_OF_PD)) {
1636 			vin_err("isp%d WDR cmp write to DDR fifo overflow\n", isp->id);
1637 			bsp_isp_clr_irq_status(isp->id, WDR_WRITE_FIFO_OF_PD);
1638 		}
1639 		if (bsp_isp_get_irq_status(isp->id, WDR_READ_FIFO_OF_PD)) {
1640 			vin_err("isp%d WDR umcmp read from DDR fifo empty\n", isp->id);
1641 			bsp_isp_clr_irq_status(isp->id, WDR_READ_FIFO_OF_PD);
1642 		}
1643 		if (bsp_isp_get_irq_status(isp->id, WDR_WT2CMP_FIFO_OF_PD)) {
1644 			vin_err("isp%d WDR write to cmp fifo overflow\n", isp->id);
1645 			bsp_isp_clr_irq_status(isp->id, WDR_WT2CMP_FIFO_OF_PD);
1646 		}
1647 		if (bsp_isp_get_irq_status(isp->id, D3D_HB_PD)) {
1648 			vin_err("isp%d Hblanking is not enough for D3D\n", isp->id);
1649 			bsp_isp_clr_irq_status(isp->id, D3D_HB_PD);
1650 		}
1651 		/*isp reset*/
1652 		sunxi_isp_reset(isp);
1653 	}
1654 #else
1655 	if (bsp_isp_get_irq_status(isp->id, S0_FIFO_OF_PD)) {
1656 		vin_err("isp%d source0 fifo overflow\n", isp->id);
1657 		bsp_isp_clr_irq_status(isp->id, S0_FIFO_OF_PD);
1658 		if (bsp_isp_get_internal_status0(isp->id, S0_CIN_FIFO_OF_PD)) {
1659 			vin_err("isp%d Cin0 fifo overflow\n", isp->id);
1660 			bsp_isp_clr_internal_status0(isp->id, S0_CIN_FIFO_OF_PD);
1661 		}
1662 		if (bsp_isp_get_internal_status0(isp->id, BIS_FIFO_OF_PD)) {
1663 			vin_err("isp%d BIS fifo overflow\n", isp->id);
1664 			bsp_isp_clr_internal_status0(isp->id, BIS_FIFO_OF_PD);
1665 		}
1666 #if !defined CONFIG_ARCH_SUN50IW10
1667 		if (bsp_isp_get_internal_status0(isp->id, DPC_FIFO_OF_PD)) {
1668 			vin_err("isp%d DPC fifo overflow\n", isp->id);
1669 			bsp_isp_clr_internal_status0(isp->id, DPC_FIFO_OF_PD);
1670 		}
1671 		if (bsp_isp_get_internal_status0(isp->id, CNR_FIFO_OF_PD)) {
1672 			vin_err("isp%d CNR fifo overflow\n", isp->id);
1673 			bsp_isp_clr_internal_status0(isp->id, CNR_FIFO_OF_PD);
1674 		}
1675 		if (bsp_isp_get_internal_status0(isp->id, PLTM_FIFO_OF_PD)) {
1676 			vin_err("isp%d PLTM fifo overflow\n", isp->id);
1677 			bsp_isp_clr_internal_status0(isp->id, PLTM_FIFO_OF_PD);
1678 		}
1679 		if (bsp_isp_get_internal_status0(isp->id, D3D_WRITE_FIFO_OF_PD)) {
1680 			vin_err("isp%d D3D cmp write to DDR fifo overflow\n", isp->id);
1681 			bsp_isp_clr_internal_status0(isp->id, D3D_WRITE_FIFO_OF_PD);
1682 		}
1683 		if (bsp_isp_get_internal_status0(isp->id, D3D_READ_FIFO_OF_PD)) {
1684 			vin_err("isp%d D3D umcmp read from DDR fifo empty\n", isp->id);
1685 			bsp_isp_clr_internal_status0(isp->id, D3D_READ_FIFO_OF_PD);
1686 		}
1687 		if (bsp_isp_get_internal_status0(isp->id, WDR_WRITE_FIFO_OF_PD)) {
1688 			vin_err("isp%d WDR cmp write to DDR fifo overflow\n", isp->id);
1689 			bsp_isp_clr_internal_status0(isp->id, WDR_WRITE_FIFO_OF_PD);
1690 		}
1691 		if (bsp_isp_get_internal_status0(isp->id, WDR_READ_FIFO_OF_PD)) {
1692 			vin_err("isp%d WDR umcmp read from DDR fifo empty\n", isp->id);
1693 			bsp_isp_clr_internal_status0(isp->id, WDR_READ_FIFO_OF_PD);
1694 		}
1695 #endif
1696 #if defined CONFIG_ARCH_SUN8IW19P1
1697 		if (bsp_isp_get_internal_status0(isp->id, LCA_RGB_FIFO_R_EMP_PD)) {
1698 			vin_err("isp%d RGB fifo of LCA read empty\n", isp->id);
1699 			bsp_isp_clr_internal_status0(isp->id, LCA_RGB_FIFO_R_EMP_PD);
1700 		}
1701 		if (bsp_isp_get_internal_status0(isp->id, LCA_RGB_FIFO_W_FULL_PD)) {
1702 			vin_err("isp%d RGB fifo of LCA write full\n", isp->id);
1703 			bsp_isp_clr_internal_status0(isp->id, LCA_RGB_FIFO_W_FULL_PD);
1704 		}
1705 		if (bsp_isp_get_internal_status0(isp->id, LCA_BY_FIFO_R_EMP_PD)) {
1706 			vin_err("isp%d bayer fifo of LCA read empty\n", isp->id);
1707 			bsp_isp_clr_internal_status0(isp->id, LCA_BY_FIFO_R_EMP_PD);
1708 		}
1709 		if (bsp_isp_get_internal_status0(isp->id, LCA_BY_FIFO_W_FULL_PD)) {
1710 			vin_err("isp%d bayer fifo of LCA write full\n", isp->id);
1711 			bsp_isp_clr_internal_status0(isp->id, LCA_BY_FIFO_W_FULL_PD);
1712 		}
1713 		if (bsp_isp_get_internal_status0(isp->id, D3D_K_FIFO_W_FULL_PD)) {
1714 			vin_err("isp%d write fifo of D3D K data full\n", isp->id);
1715 			bsp_isp_clr_internal_status0(isp->id, D3D_K_FIFO_W_FULL_PD);
1716 		}
1717 		if (bsp_isp_get_internal_status0(isp->id, D3D_RAW_FIFO_W_FULL_PD)) {
1718 			vin_err("isp%d write fifo of D3D RAW data full\n", isp->id);
1719 			bsp_isp_clr_internal_status0(isp->id, D3D_RAW_FIFO_W_FULL_PD);
1720 		}
1721 		if (bsp_isp_get_internal_status0(isp->id, D3D_K_FIFO_R_EMP_PD)) {
1722 			vin_err("isp%d read fifo of D3D K data empty\n", isp->id);
1723 			bsp_isp_clr_internal_status0(isp->id, D3D_K_FIFO_R_EMP_PD);
1724 		}
1725 		if (bsp_isp_get_internal_status0(isp->id, D3D_REF_FIFO_R_EMP_PD)) {
1726 			vin_err("isp%d read fifo of D3D REF data empty\n", isp->id);
1727 			bsp_isp_clr_internal_status0(isp->id, D3D_REF_FIFO_R_EMP_PD);
1728 		}
1729 		if (bsp_isp_get_internal_status0(isp->id, D3D_LTF_FIFO_R_EMP_PD)) {
1730 			vin_err("isp%d read fifo of D3D LTF data empty\n", isp->id);
1731 			bsp_isp_clr_internal_status0(isp->id, D3D_LTF_FIFO_R_EMP_PD);
1732 		}
1733 #endif
1734 		/*isp reset*/
1735 		sunxi_isp_reset(isp);
1736 	}
1737 #endif
1738 	if (bsp_isp_get_irq_status(isp->id, HB_SHORT_PD)) {
1739 		vin_err("isp%d Hblanking is short (less than 96 cycles)\n", isp->id);
1740 		bsp_isp_clr_irq_status(isp->id, HB_SHORT_PD);
1741 	}
1742 
1743 	if (bsp_isp_get_irq_status(isp->id, FRAME_ERROR_PD)) {
1744 		bsp_isp_get_s0_ch_fmerr_cnt(isp->id, &isp->err_size);
1745 		bsp_isp_get_s0_ch_hb_cnt(isp->id, &isp->hb_max, &isp->hb_min);
1746 		vin_err("isp%d frame error, size %d %d, hblank max %d min %d!!\n", isp->id,
1747 			isp->err_size.width, isp->err_size.height, isp->hb_max, isp->hb_min);
1748 		bsp_isp_clr_irq_status(isp->id, FRAME_ERROR_PD);
1749 		sunxi_isp_reset(isp);
1750 	}
1751 
1752 	if (bsp_isp_get_irq_status(isp->id, FRAME_LOST_PD)) {
1753 		vin_err("isp%d frame lost\n", isp->id);
1754 		bsp_isp_clr_irq_status(isp->id, FRAME_LOST_PD);
1755 		sunxi_isp_reset(isp);
1756 	}
1757 
1758 #if defined CONFIG_ARCH_SUN8IW19P1
1759 	if (bsp_isp_get_irq_status(isp->id, S0_BTYPE_ERROR_PD)) {
1760 		vin_err("isp%d input btype error\n", isp->id);
1761 		bsp_isp_clr_irq_status(isp->id, S0_BTYPE_ERROR_PD);
1762 	}
1763 
1764 	if (bsp_isp_get_irq_status(isp->id, ADDR_ERROR_PD)) {
1765 		vin_err("isp%d aligned addr error\n", isp->id);
1766 		bsp_isp_clr_irq_status(isp->id, ADDR_ERROR_PD);
1767 	}
1768 
1769 	if (bsp_isp_get_irq_status(isp->id, LBC_ERROR_PD)) {
1770 		vin_err("isp%d LBC de-compress error\n", isp->id);
1771 		bsp_isp_clr_irq_status(isp->id, LBC_ERROR_PD);
1772 		if (bsp_isp_get_lbc_internal_status(isp->id, WDR_LBC_DEC_ERR_PD)) {
1773 			vin_err("isp%d WDR LBC decode error\n", isp->id);
1774 			if (bsp_isp_get_lbc_internal_status(isp->id, LBC_MSQ_DEC_ERR_PD << WDR_LBC_DEC_ERR_OFF)) {
1775 				vin_err("isp%d msq decode error\n", isp->id);
1776 				bsp_isp_clr_lbc_internal_status(isp->id, LBC_MSQ_DEC_ERR_PD << WDR_LBC_DEC_ERR_OFF);
1777 			}
1778 			if (bsp_isp_get_lbc_internal_status(isp->id, LBC_DTS_DEC_ERR_PD << WDR_LBC_DEC_ERR_OFF)) {
1779 				vin_err("isp%d dts decode error\n", isp->id);
1780 				bsp_isp_clr_lbc_internal_status(isp->id, LBC_DTS_DEC_ERR_PD << WDR_LBC_DEC_ERR_OFF);
1781 			}
1782 			if (bsp_isp_get_lbc_internal_status(isp->id, LBC_QP_DEC_ERR_PD << WDR_LBC_DEC_ERR_OFF)) {
1783 				vin_err("isp%d qp decode error\n", isp->id);
1784 				bsp_isp_clr_lbc_internal_status(isp->id, LBC_QP_DEC_ERR_PD << WDR_LBC_DEC_ERR_OFF);
1785 			}
1786 			if (bsp_isp_get_lbc_internal_status(isp->id, LBC_CODEC_BIT_LOST_PD << WDR_LBC_DEC_ERR_OFF)) {
1787 				vin_err("isp%d codec bit lost error\n", isp->id);
1788 				bsp_isp_clr_lbc_internal_status(isp->id, LBC_CODEC_BIT_LOST_PD << WDR_LBC_DEC_ERR_OFF);
1789 			}
1790 			if (bsp_isp_get_lbc_internal_status(isp->id, LBC_CODEC_RED_ERR_PD << WDR_LBC_DEC_ERR_OFF)) {
1791 				vin_err("isp%d codec redundancy error\n", isp->id);
1792 				bsp_isp_clr_lbc_internal_status(isp->id, LBC_CODEC_RED_ERR_PD << WDR_LBC_DEC_ERR_OFF);
1793 			}
1794 		}
1795 		if (bsp_isp_get_lbc_internal_status(isp->id, D3D_K_LBC_DEC_ERR_PD)) {
1796 			vin_err("isp%d D3D K LBC decode error\n", isp->id);
1797 			if (bsp_isp_get_lbc_internal_status(isp->id, LBC_MSQ_DEC_ERR_PD << D3D_K_LBC_DEC_ERR_OFF)) {
1798 				vin_err("isp%d msq decode error\n", isp->id);
1799 				bsp_isp_clr_lbc_internal_status(isp->id, LBC_MSQ_DEC_ERR_PD << D3D_K_LBC_DEC_ERR_OFF);
1800 			}
1801 			if (bsp_isp_get_lbc_internal_status(isp->id, LBC_DTS_DEC_ERR_PD << D3D_K_LBC_DEC_ERR_OFF)) {
1802 				vin_err("isp%d dts decode error\n", isp->id);
1803 				bsp_isp_clr_lbc_internal_status(isp->id, LBC_DTS_DEC_ERR_PD << D3D_K_LBC_DEC_ERR_OFF);
1804 			}
1805 			if (bsp_isp_get_lbc_internal_status(isp->id, LBC_QP_DEC_ERR_PD << D3D_K_LBC_DEC_ERR_OFF)) {
1806 				vin_err("isp%d qp decode error\n", isp->id);
1807 				bsp_isp_clr_lbc_internal_status(isp->id, LBC_QP_DEC_ERR_PD << D3D_K_LBC_DEC_ERR_OFF);
1808 			}
1809 			if (bsp_isp_get_lbc_internal_status(isp->id, LBC_CODEC_BIT_LOST_PD << D3D_K_LBC_DEC_ERR_OFF)) {
1810 				vin_err("isp%d codec bit lost error\n", isp->id);
1811 				bsp_isp_clr_lbc_internal_status(isp->id, LBC_CODEC_BIT_LOST_PD << D3D_K_LBC_DEC_ERR_OFF);
1812 			}
1813 			if (bsp_isp_get_lbc_internal_status(isp->id, LBC_CODEC_RED_ERR_PD << D3D_K_LBC_DEC_ERR_OFF)) {
1814 				vin_err("isp%d codec redundancy error\n", isp->id);
1815 				bsp_isp_clr_lbc_internal_status(isp->id, LBC_CODEC_RED_ERR_PD << D3D_K_LBC_DEC_ERR_OFF);
1816 			}
1817 		}
1818 		if (bsp_isp_get_lbc_internal_status(isp->id, D3D_REF_LBC_DEC_ERR_PD)) {
1819 			vin_err("isp%d D3D reference frame LBC decode error\n", isp->id);
1820 			if (bsp_isp_get_lbc_internal_status(isp->id, LBC_MSQ_DEC_ERR_PD << D3D_REF_LBC_DEC_ERR_OFF)) {
1821 				vin_err("isp%d msq decode error\n", isp->id);
1822 				bsp_isp_clr_lbc_internal_status(isp->id, LBC_MSQ_DEC_ERR_PD << D3D_REF_LBC_DEC_ERR_OFF);
1823 			}
1824 			if (bsp_isp_get_lbc_internal_status(isp->id, LBC_DTS_DEC_ERR_PD << D3D_REF_LBC_DEC_ERR_OFF)) {
1825 				vin_err("isp%d dts decode error\n", isp->id);
1826 				bsp_isp_clr_lbc_internal_status(isp->id, LBC_DTS_DEC_ERR_PD << D3D_REF_LBC_DEC_ERR_OFF);
1827 			}
1828 			if (bsp_isp_get_lbc_internal_status(isp->id, LBC_QP_DEC_ERR_PD << D3D_REF_LBC_DEC_ERR_OFF)) {
1829 				vin_err("isp%d qp decode error\n", isp->id);
1830 				bsp_isp_clr_lbc_internal_status(isp->id, LBC_QP_DEC_ERR_PD << D3D_REF_LBC_DEC_ERR_OFF);
1831 			}
1832 			if (bsp_isp_get_lbc_internal_status(isp->id, LBC_CODEC_BIT_LOST_PD << D3D_REF_LBC_DEC_ERR_OFF)) {
1833 				vin_err("isp%d codec bit lost error\n", isp->id);
1834 				bsp_isp_clr_lbc_internal_status(isp->id, LBC_CODEC_BIT_LOST_PD << D3D_REF_LBC_DEC_ERR_OFF);
1835 			}
1836 			if (bsp_isp_get_lbc_internal_status(isp->id, LBC_CODEC_RED_ERR_PD << D3D_REF_LBC_DEC_ERR_OFF)) {
1837 				vin_err("isp%d codec redundancy error\n", isp->id);
1838 				bsp_isp_clr_lbc_internal_status(isp->id, LBC_CODEC_RED_ERR_PD << D3D_REF_LBC_DEC_ERR_OFF);
1839 			}
1840 		}
1841 		if (bsp_isp_get_lbc_internal_status(isp->id, D3D_LTF_LBC_DEV_ERR_PD)) {
1842 			vin_err("isp%d D3D long time reference frame LBC decode error\n", isp->id);
1843 			if (bsp_isp_get_lbc_internal_status(isp->id, LBC_MSQ_DEC_ERR_PD << D3D_LTF_LBC_DEV_ERR_OFF)) {
1844 				vin_err("isp%d msq decode error\n", isp->id);
1845 				bsp_isp_clr_lbc_internal_status(isp->id, LBC_MSQ_DEC_ERR_PD << D3D_LTF_LBC_DEV_ERR_OFF);
1846 			}
1847 			if (bsp_isp_get_lbc_internal_status(isp->id, LBC_DTS_DEC_ERR_PD << D3D_LTF_LBC_DEV_ERR_OFF)) {
1848 				vin_err("isp%d dts decode error\n", isp->id);
1849 				bsp_isp_clr_lbc_internal_status(isp->id, LBC_DTS_DEC_ERR_PD << D3D_LTF_LBC_DEV_ERR_OFF);
1850 			}
1851 			if (bsp_isp_get_lbc_internal_status(isp->id, LBC_QP_DEC_ERR_PD << D3D_LTF_LBC_DEV_ERR_OFF)) {
1852 				vin_err("isp%d qp decode error\n", isp->id);
1853 				bsp_isp_clr_lbc_internal_status(isp->id, LBC_QP_DEC_ERR_PD << D3D_LTF_LBC_DEV_ERR_OFF);
1854 			}
1855 			if (bsp_isp_get_lbc_internal_status(isp->id, LBC_CODEC_BIT_LOST_PD << D3D_LTF_LBC_DEV_ERR_OFF)) {
1856 				vin_err("isp%d codec bit lost error\n", isp->id);
1857 				bsp_isp_clr_lbc_internal_status(isp->id, LBC_CODEC_BIT_LOST_PD << D3D_LTF_LBC_DEV_ERR_OFF);
1858 			}
1859 			if (bsp_isp_get_lbc_internal_status(isp->id, LBC_CODEC_RED_ERR_PD << D3D_LTF_LBC_DEV_ERR_OFF)) {
1860 				vin_err("isp%d codec redundancy error\n", isp->id);
1861 				bsp_isp_clr_lbc_internal_status(isp->id, LBC_CODEC_RED_ERR_PD << D3D_LTF_LBC_DEV_ERR_OFF);
1862 			}
1863 		}
1864 	}
1865 #endif
1866 
1867 	if (bsp_isp_get_irq_status(isp->id, PARA_LOAD_PD)) {
1868 		bsp_isp_clr_irq_status(isp->id, PARA_LOAD_PD);
1869 		if (isp->ptn_type) {
1870 			spin_unlock_irqrestore(&isp->slock, flags);
1871 			return IRQ_HANDLED;
1872 		}
1873 		bsp_isp_set_para_ready(isp->id, PARA_NOT_READY);
1874 		if (isp->load_flag)
1875 			memcpy(isp->isp_load.vir_addr, &isp->load_shadow[0], ISP_LOAD_DRAM_SIZE);
1876 		isp->isp_ob.set_cnt++;
1877 		load_val = bsp_isp_load_update_flag(isp->id);
1878 		if (isp->wdr_mode != ISP_NORMAL_MODE)
1879 			isp_wdr_pingpong_set(isp);
1880 		else {
1881 			vin_log(VIN_LOG_ISP, "please close wdr in normal mode!!\n");
1882 			load_val = load_val & ~WDR_UPDATE;
1883 			bsp_isp_module_disable(isp->id, WDR_EN);
1884 #if !defined CONFIG_ARCH_SUN8IW16P1 && !defined CONFIG_ARCH_SUN8IW19P1 && !defined CONFIG_ARCH_SUN50IW10
1885 			bsp_isp_set_wdr_mode(isp->id, ISP_NORMAL_MODE);
1886 #endif
1887 		}
1888 		if (isp->large_image == 2) {
1889 			bsp_isp_module_disable(isp->id, PLTM_EN | D3D_EN | AE_EN | AWB_EN | AF_EN | HIST_EN);
1890 			if (isp->left_right == 1) {
1891 				isp->left_right = 0;
1892 				isp->isp_ob.ob_start.hor -= isp->isp_ob.ob_valid.width - LARGE_IMAGE_OFF * 2;
1893 			} else {
1894 				isp->left_right = 1;
1895 				isp->isp_ob.ob_start.hor += isp->isp_ob.ob_valid.width - LARGE_IMAGE_OFF * 2;
1896 			}
1897 		}
1898 #if !defined CONFIG_D3D
1899 		bsp_isp_module_disable(isp->id, D3D_EN);
1900 		load_val = load_val & ~D3D_UPDATE;
1901 #endif
1902 		bsp_isp_set_size(isp->id, &isp->isp_ob);
1903 		bsp_isp_update_table(isp->id, (unsigned short)load_val);
1904 #if defined CONFIG_ARCH_SUN8IW12P1 || defined CONFIG_ARCH_SUN8IW17P1 || defined CONFIG_ARCH_SUN8IW19P1
1905 		isp_3d_pingpong_update(isp);
1906 #endif
1907 		bsp_isp_set_para_ready(isp->id, PARA_READY);
1908 	}
1909 	spin_unlock_irqrestore(&isp->slock, flags);
1910 
1911 	if (bsp_isp_get_irq_status(isp->id, FINISH_PD)) {
1912 		isp->isp_frame_number++;
1913 		bsp_isp_clr_irq_status(isp->id, FINISH_PD);
1914 #ifdef SUPPORT_PTN
1915 		if (isp->ptn_type) {
1916 			bsp_isp_set_para_ready(isp->id, PARA_NOT_READY);
1917 			memcpy(isp->isp_load.vir_addr, &isp->load_shadow[0] + (isp->ptn_isp_cnt%3) * ISP_LOAD_DRAM_SIZE, ISP_LOAD_DRAM_SIZE);
1918 			isp->ptn_isp_cnt++;
1919 			load_val = bsp_isp_load_update_flag(isp->id);
1920 			bsp_isp_set_size(isp->id, &isp->isp_ob);
1921 			bsp_isp_update_table(isp->id, (unsigned short)load_val);
1922 			isp_3d_pingpong_update(isp);
1923 			bsp_isp_set_para_ready(isp->id, PARA_READY);
1924 		}
1925 #endif
1926 		if (!isp->f1_after_librun) {
1927 			sunxi_isp_frame_sync_isr(&isp->subdev);
1928 			if (isp->h3a_stat.stat_en_flag)
1929 				isp->f1_after_librun = 1;
1930 		} else {
1931 			if (isp->load_flag || (isp->event_lost_cnt == 10)) {
1932 				sunxi_isp_frame_sync_isr(&isp->subdev);
1933 				isp->event_lost_cnt = 0;
1934 			} else {
1935 				isp->event_lost_cnt++;
1936 			}
1937 		}
1938 		isp->load_flag = 0;
1939 	}
1940 
1941 	return IRQ_HANDLED;
1942 }
1943 
1944 static unsigned int isp_id;
1945 
isp_probe(struct platform_device * pdev)1946 static int isp_probe(struct platform_device *pdev)
1947 {
1948 	struct device_node *np = pdev->dev.of_node;
1949 	struct isp_dev *isp = NULL;
1950 	int ret = 0;
1951 
1952 	if (np == NULL) {
1953 		vin_err("ISP failed to get of node\n");
1954 		return -ENODEV;
1955 	}
1956 
1957 	isp = kzalloc(sizeof(struct isp_dev), GFP_KERNEL);
1958 	if (!isp) {
1959 		ret = -ENOMEM;
1960 		goto ekzalloc;
1961 	}
1962 
1963 	of_property_read_u32(np, "device_id", &pdev->id);
1964 	if (pdev->id < 0) {
1965 		vin_err("ISP failed to get device id\n");
1966 		ret = -EINVAL;
1967 		goto freedev;
1968 	}
1969 
1970 	isp->id = pdev->id;
1971 	isp->pdev = pdev;
1972 	isp->nosend_ispoff = 0;
1973 
1974 	if (isp->id > 0xf0) {
1975 		isp->is_empty = 1;
1976 		isp->id = isp_id;
1977 		isp_id++;
1978 	} else {
1979 		isp->base = of_iomap(np, 0);
1980 		isp->is_empty = 0;
1981 		/*get irq resource */
1982 		isp->irq = irq_of_parse_and_map(np, 0);
1983 		if (isp->irq <= 0) {
1984 			vin_err("failed to get ISP IRQ resource\n");
1985 			goto unmap;
1986 		}
1987 
1988 		ret = request_irq(isp->irq, isp_isr, IRQF_SHARED, isp->pdev->name, isp);
1989 		if (ret) {
1990 			vin_err("isp%d request irq failed\n", isp->id);
1991 			goto unmap;
1992 		}
1993 		if (isp_resource_alloc(isp) < 0) {
1994 			ret = -ENOMEM;
1995 			goto freeirq;
1996 		}
1997 		bsp_isp_map_reg_addr(isp->id, (unsigned long)isp->base);
1998 		bsp_isp_map_load_dram_addr(isp->id, (unsigned long)isp->isp_load.vir_addr);
1999 	}
2000 
2001 	__isp_init_subdev(isp);
2002 
2003 	spin_lock_init(&isp->slock);
2004 
2005 	ret = vin_isp_h3a_init(isp);
2006 	if (ret < 0) {
2007 		vin_err("VIN H3A initialization failed\n");
2008 			goto free_res;
2009 	}
2010 
2011 	INIT_WORK(&isp->s_sensor_stby_task, __isp_s_sensor_stby_handle);
2012 
2013 	platform_set_drvdata(pdev, isp);
2014 	glb_isp[isp->id] = isp;
2015 
2016 	vin_log(VIN_LOG_ISP, "isp%d probe end!\n", isp->id);
2017 	return 0;
2018 free_res:
2019 	isp_resource_free(isp);
2020 freeirq:
2021 	if (!isp->is_empty)
2022 		free_irq(isp->irq, isp);
2023 unmap:
2024 	if (!isp->is_empty)
2025 		iounmap(isp->base);
2026 	else
2027 		kfree(isp->base);
2028 freedev:
2029 	kfree(isp);
2030 ekzalloc:
2031 	vin_err("isp probe err!\n");
2032 	return ret;
2033 }
2034 
isp_remove(struct platform_device * pdev)2035 static int isp_remove(struct platform_device *pdev)
2036 {
2037 	struct isp_dev *isp = platform_get_drvdata(pdev);
2038 	struct v4l2_subdev *sd = &isp->subdev;
2039 
2040 	platform_set_drvdata(pdev, NULL);
2041 	v4l2_ctrl_handler_free(sd->ctrl_handler);
2042 	v4l2_set_subdevdata(sd, NULL);
2043 
2044 	if (!isp->is_empty) {
2045 		isp_resource_free(isp);
2046 		free_irq(isp->irq, isp);
2047 		if (isp->base)
2048 			iounmap(isp->base);
2049 	}
2050 	vin_isp_h3a_cleanup(isp);
2051 	media_entity_cleanup(&isp->subdev.entity);
2052 	kfree(isp);
2053 	return 0;
2054 }
2055 
2056 static const struct of_device_id sunxi_isp_match[] = {
2057 	{.compatible = "allwinner,sunxi-isp",},
2058 	{},
2059 };
2060 
2061 static struct platform_driver isp_platform_driver = {
2062 	.probe = isp_probe,
2063 	.remove = isp_remove,
2064 	.driver = {
2065 		   .name = ISP_MODULE_NAME,
2066 		   .owner = THIS_MODULE,
2067 		   .of_match_table = sunxi_isp_match,
2068 		   },
2069 };
2070 
sunxi_isp_sensor_type(struct v4l2_subdev * sd,int use_isp)2071 void sunxi_isp_sensor_type(struct v4l2_subdev *sd, int use_isp)
2072 {
2073 	struct isp_dev *isp = v4l2_get_subdevdata(sd);
2074 
2075 	isp->use_isp = use_isp;
2076 	if (isp->is_empty)
2077 		isp->use_isp = 0;
2078 }
2079 
sunxi_isp_sensor_fps(struct v4l2_subdev * sd,int fps)2080 void sunxi_isp_sensor_fps(struct v4l2_subdev *sd, int fps)
2081 {
2082 	struct isp_dev *isp = v4l2_get_subdevdata(sd);
2083 
2084 	isp->h3a_stat.sensor_fps = fps;
2085 }
2086 
sunxi_isp_debug(struct v4l2_subdev * sd,struct isp_debug_mode * isp_debug)2087 void sunxi_isp_debug(struct v4l2_subdev *sd, struct isp_debug_mode *isp_debug)
2088 {
2089 	struct isp_dev *isp = v4l2_get_subdevdata(sd);
2090 
2091 	isp->isp_dbg = *isp_debug;
2092 }
2093 
sunxi_isp_ptn(struct v4l2_subdev * sd,unsigned int ptn_type)2094 void sunxi_isp_ptn(struct v4l2_subdev *sd, unsigned int ptn_type)
2095 {
2096 	struct isp_dev *isp = v4l2_get_subdevdata(sd);
2097 	isp->ptn_type = ptn_type;
2098 }
2099 
sunxi_isp_get_subdev(int id)2100 struct v4l2_subdev *sunxi_isp_get_subdev(int id)
2101 {
2102 	if (id < VIN_MAX_ISP)
2103 		return &glb_isp[id]->subdev;
2104 	else
2105 		return NULL;
2106 }
2107 
sunxi_stat_get_subdev(int id)2108 struct v4l2_subdev *sunxi_stat_get_subdev(int id)
2109 {
2110 	if (id < VIN_MAX_ISP && glb_isp[id])
2111 		return &glb_isp[id]->h3a_stat.sd;
2112 	else
2113 		return NULL;
2114 }
2115 
sunxi_isp_platform_register(void)2116 int sunxi_isp_platform_register(void)
2117 {
2118 	return platform_driver_register(&isp_platform_driver);
2119 }
2120 
sunxi_isp_platform_unregister(void)2121 void sunxi_isp_platform_unregister(void)
2122 {
2123 	platform_driver_unregister(&isp_platform_driver);
2124 	vin_log(VIN_LOG_ISP, "isp_exit end\n");
2125 }
2126