blob: 5566d679d6812ffdc66bf104378cd9bacbd53396 [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * V4L2 Driver for ASR camera controller
4 *
5 * Copyright (C) 2023 ASR Microelectronics Co., Ltd.
6 */
7
8#include <linux/init.h>
9#include <linux/module.h>
10#include <linux/io.h>
11#include <linux/delay.h>
12#include <linux/device.h>
13#include <linux/dma-mapping.h>
14#include <linux/err.h>
15#include <linux/errno.h>
16#include <linux/fs.h>
17#include <linux/interrupt.h>
18#include <linux/kernel.h>
19#include <linux/mm.h>
20#include <linux/moduleparam.h>
21#include <linux/of.h>
22#include <linux/of_graph.h>
23#include <linux/of_irq.h>
24#include <linux/time.h>
25#include <linux/platform_device.h>
26#include <linux/clk.h>
27#include <linux/sched.h>
28#include <linux/slab.h>
29#include <linux/syscalls.h>
30#include <linux/pm_qos.h>
31#include <media/v4l2-async.h>
32#include <media/v4l2-clk.h>
33#include <media/v4l2-common.h>
34#include <media/v4l2-ctrls.h>
35#include <media/v4l2-device.h>
36#include <media/v4l2-event.h>
37#include <media/v4l2-ioctl.h>
38#include <media/v4l2-fwnode.h>
39#include <media/videobuf2-dma-contig.h>
40#include <linux/videodev2.h>
41#include "camera_reg.h"
42#include "../../video/fbdev/asrfb/asrfb.h"
43
44#ifdef CONFIG_DEBUG_FS
45#include <linux/debugfs.h>
46#include <linux/seq_file.h>
47#endif /* CONFIG_DEBUG_FS */
48
49static int debug;
50static int snapshot_flag = 0;
51module_param(debug, int, 0644);
52
53#define ASR_CAM_DRV_NAME "asr-camera"
54#define DEFAULT_WIDTH 640
55#define DEFAULT_HEIGHT 480
56
57enum cam_interface {
58 INF_SPI1LAN = 0x0,
59 INF_SPI2LAN,
60 INF_SPI4LAN,
61 INF_MIPI1LAN,
62 INF_MIPI2LAN,
63 INF_MIPI4LAN,
64 INF_DVP,
65 INF_MAX,
66};
67
68struct spi_param {
69 u8 spi_sdr; //0x0:no sdr 0x1:sdr
70 u8 spi_crc; //0x0:no crc 0x1:crc
71 u8 spi_manual_enable; //0x0:not enable 0x1:enable
72 u8 spi_manual_mode;
73 u8 spi_manual_height_enable; //0x0:not enable 0x1:enable
74 u8 spi_manual_width_enable; //0x0:not enable 0x1:enable
75 u16 spi_manual_height;
76 u16 spi_manual_width;
77 u8 spi_ignore_line_id;
78};
79
80struct crop_param {
81 u16 start_x;
82 u16 start_y;
83 u16 end_x;
84 u16 end_y;
85};
86
87/*size:isp output size-->crop-->subsample-->scaler-->dma size*/
88struct pipeline_param {
89 u8 pipeline_num; //0x0:preview 0x1:video 0x2:capture
90 u8 pipeline_enable; //0x0:not enable 0x1:enable
91 u8 shadow_mode; //0x0:direct mode 0x1:shadow mode
92 struct crop_param pipeline_crop;
93 u8 subsample; //0x0:1-1 0x1 1-2 0x2:1-4 0x3:1-8 0x4:1-16 0x5 1-32
94 u8 scaler;
95 u8 output_format;
96 u16 dma_stride_y;
97 u16 pipeline_outw;/*dma_w*/
98 u16 pipeline_outh;/*dma_h*/
99};
100
101/*
102 * struct asr_sensor_info - Sensor infomations
103 * @mbus: media bus configuration
104 */
105struct asr_sensor_info {
106 struct v4l2_subdev *sd;
107 struct v4l2_mbus_config mbus;
108 struct v4l2_subdev_format fmt;
109 struct v4l2_subdev_pad_config cfg;
110};
111
112#define ISP_STAT_MAX_PLANE 3
113
114struct isp_buffer {
115 /* common v4l buffer stuff -- must be first */
116 struct vb2_v4l2_buffer vbuf;
117 struct list_head queue;
118 dma_addr_t dma;
119};
120
121struct asr_camera_dev {
122 struct v4l2_device v4l2_dev;
123 struct video_device vdev;
124 struct v4l2_async_notifier notifier;
125 struct v4l2_async_subdev asd;
126 struct vb2_queue vb2_vq;
127 struct asr_sensor_info sensor;
128 struct v4l2_pix_format current_pix;
129 u32 mclk_rate;
130 unsigned int irq;
131 void __iomem *ipe_base;
132 void __iomem *isp_base;
133 struct resource *res;
134 enum cam_interface camera_interface;
135 struct spi_param spi_config;
136 struct pipeline_param pipe2_config;
137
138 spinlock_t lock;
139 struct mutex mlock;
140 struct list_head capture;
141 unsigned int buf_sequence;
142 bool dma_state;
143 struct isp_buffer *curr_buf;
144 struct isp_buffer *next_buf;
145 struct tasklet_struct task_eof;
146 struct dentry *dentry;
147 void *dma_addr;
148 dma_addr_t dma_addr_phys;
149 struct pm_qos_request pm_qos_req;
150 s32 pm_qos;
151};
152void __iomem* ipe_base_reg;
153
154#define ALIGN_TO(addr,size) (((addr)+(size)-1)&(~((size)-1)))
155#define sensor_call(cam, o, f, args...) \
156 v4l2_subdev_call(cam->sensor.sd, o, f, ##args)
157
158static struct isp_buffer *vb2_to_isp_buffer(struct vb2_buffer *vb)
159{
160 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
161
162 return container_of(vbuf, struct isp_buffer, vbuf);
163}
164
165static struct asr_camera_dev *v4l2_dev_to_pcdev(struct v4l2_device *v4l2_dev)
166{
167 return container_of(v4l2_dev, struct asr_camera_dev, v4l2_dev);
168}
169
170void asr_camera_mclk_ctrl(int on)
171{
172 u32 value;
173
174 value = __raw_readl(ipe_base_reg + REG_CTRL_1);
175 if (on) {
176 value &= ~(1<<28);
177 __raw_writel(value, ipe_base_reg + REG_CTRL_1);
178 } else {
179 value |= (1<<28);
180 __raw_writel(value, ipe_base_reg + REG_CTRL_1);
181 }
182}
183EXPORT_SYMBOL(asr_camera_mclk_ctrl);
184
185static void asr_camera_activate(struct asr_camera_dev *pcdev)
186{
187 u32 mask = 0;
188
189 init_media_pmu();
190 clear_camera_setting(pcdev->ipe_base);
191 pm_qos_update_request(&pcdev->pm_qos_req, pcdev->pm_qos);
192 /* disable all interrupts */
193 writel(0xFFFFFFFF, pcdev->ipe_base + REG_CAMERA_IRQ_RAW_MASK);
194 mask = readl(pcdev->ipe_base + REG_CCIC_IRQ_MASK);
195 mask |= IRQ_CCIC_MASK_ALL;
196 writel(mask, pcdev->ipe_base + REG_CCIC_IRQ_MASK);
197
198 config_mclk(pcdev->ipe_base, pcdev->mclk_rate);
199}
200
201static void asr_camera_deactivate(struct asr_camera_dev *pcdev)
202{
203 deinit_media_pmu();
204 pm_qos_update_request(&pcdev->pm_qos_req, PM_QOS_CPUIDLE_BLOCK_DEFAULT_VALUE);
205}
206
207static u32 asr_mbus_image_size(struct pipeline_param *pipe_config)
208{
209 u32 size = 0;
210
211 switch(pipe_config->output_format) {
212 case RAW8: // only p2 support, refer to YV12
213 size = pipe_config->dma_stride_y*pipe_config->pipeline_outh;
214 break;
215 case YUV422_YUYV: // 1 planar
216 case YUV422_YVYU: // 1 planar
217 case YUV422_UYVY: // 1 planar
218 case YUV422_VYUY: // 1 planar
219 size = pipe_config->dma_stride_y*pipe_config->pipeline_outh * 2;
220 break;
221 case YUV420_YV12: // 3 planar
222 case YUV420_I420: // 3 planar
223 size = pipe_config->dma_stride_y*pipe_config->pipeline_outh * 3 / 2;
224 break;
225 case YUV420_NV12: // 2 planar
226 case YUV420_NV21: // 2 planar
227 size = pipe_config->dma_stride_y * pipe_config->pipeline_outh * 3 / 2;
228 break;
229 default:
230 break;
231 }
232 return size;
233}
234
235static int pipeline_shadow_mode_set(struct asr_camera_dev *dev, u32 shadow)
236{
237 u32 reg = REG_SUBSAMPLE_SCALER_CTRL2;
238 u32 mask = PIPE2_CTRL_SHADOW_MODE_MASK;
239 u32 val = shadow ? PIPE2_CTRL_SHADOW : PIPE2_CTRL_DIRECT;
240 u32 read_val;
241
242 read_val = readl(dev->ipe_base + reg);
243 read_val = (read_val & ~mask) | (mask & val);
244 writel(read_val, dev->ipe_base + reg);
245
246 v4l2_info(&dev->v4l2_dev, "set to %s mode", shadow ? "shadow" : "direct");
247
248 return 0;
249}
250
251static void set_pipeline_enable(struct asr_camera_dev *dev)
252{
253 u32 reg = REG_SUBSAMPLE_SCALER_CTRL2;
254
255 if (dev->pipe2_config.pipeline_enable)
256 writel(readl(dev->ipe_base + reg) | (1 << 0), dev->ipe_base + reg);
257 else
258 writel(readl(dev->ipe_base + reg) & ~(1 << 0), dev->ipe_base + reg);
259}
260
261static void set_pipeline_shadow_ready(struct asr_camera_dev *dev)
262{
263 u32 reg = REG_SUBSAMPLE_SCALER_CTRL2;
264
265 writel(readl(dev->ipe_base + reg) | (1 << 6), dev->ipe_base + reg);
266}
267
268static void pipeline_shadow_streamon(struct asr_camera_dev *dev)
269{
270 //config shadow mode
271 pipeline_shadow_mode_set(dev, 1);
272 //pipeline enable
273 set_pipeline_enable(dev);
274 //set shadow ready
275 set_pipeline_shadow_ready(dev);
276}
277
278/* Interface resemble MINIGUI */
279static int isp_io_format_set(struct asr_camera_dev *dev)
280{
281 int ret = 0;
282 u8 input_yuv = 0;
283 u32 mbus_fmt, out_fmt = YUV444;
284 u32 val;
285
286 mbus_fmt = dev->sensor.fmt.format.code;
287
288 switch (mbus_fmt) {
289 case MEDIA_BUS_FMT_SBGGR8_1X8:
290 case MEDIA_BUS_FMT_SBGGR10_1X10:
291 isp_reg_write(dev->isp_base, 0x5c, 0x20); // [5:4] CFA) = 00:GRBG) = 01:RGGB) = 10:BGGR) = 11:GBRG
292 break;
293 case MEDIA_BUS_FMT_SGBRG8_1X8:
294 case MEDIA_BUS_FMT_SGBRG10_1X10:
295 isp_reg_write(dev->isp_base, 0x5c, 0x30); // [5:4] CFA) = 00:GRBG) = 01:RGGB) = 10:BGGR) = 11:GBRG
296 break;
297 case MEDIA_BUS_FMT_SGRBG8_1X8:
298 case MEDIA_BUS_FMT_SGRBG10_1X10:
299 isp_reg_write(dev->isp_base, 0x5c, 0x00); // [5:4] CFA) = 00:GRBG) = 01:RGGB) = 10:BGGR) = 11:GBRG
300 break;
301 case MEDIA_BUS_FMT_SRGGB8_1X8:
302 case MEDIA_BUS_FMT_SRGGB10_1X10:
303 isp_reg_write(dev->isp_base, 0x5c, 0x10); // [5:4] CFA) = 00:GRBG) = 01:RGGB) = 10:BGGR) = 11:GBRG
304 break;
305
306 /*
307 This field defines the Endianness of the external CMOS sensor's output (CCIC's input).
308 This field has no effect on the MIPI CSI2 CMOS sensor.
309 0x0 = Y1CbY0Cr: YUYV sensor
310 0x1 = Y1CrY0Cb: YVYU sensor
311 0x2 = CrY1CbY0: VYUY sensor
312 0x3 = CbY1CrY0: UYVY sensor
313 */
314 case MEDIA_BUS_FMT_YUYV8_2X8:
315 val = readl(dev->ipe_base + REG_DATA_FORMAT_CTRL);
316 val = val & ~(0x3 << 24);
317 writel(val,dev->ipe_base + REG_DATA_FORMAT_CTRL);
318 input_yuv = 1;
319 break;
320 case MEDIA_BUS_FMT_YVYU8_2X8:
321 val = readl(dev->ipe_base + REG_DATA_FORMAT_CTRL);
322 val = (val & ~(0x3 << 24)) | (0x1 << 24);
323 writel(val,dev->ipe_base + REG_DATA_FORMAT_CTRL);
324 input_yuv = 1;
325 break;
326 case MEDIA_BUS_FMT_VYUY8_2X8:
327 val = readl(dev->ipe_base + REG_DATA_FORMAT_CTRL);
328 val = (val & ~(0x3 << 24)) | (0x2 << 24);
329 writel(val,dev->ipe_base + REG_DATA_FORMAT_CTRL);
330 input_yuv = 1;
331 break;
332 case MEDIA_BUS_FMT_UYVY8_2X8:
333 val = readl(dev->ipe_base + REG_DATA_FORMAT_CTRL);
334 val = (val & ~(0x3 << 24)) | (0x3 << 24);
335 writel(val,dev->ipe_base + REG_DATA_FORMAT_CTRL);
336 input_yuv = 1;
337 break;
338 default:
339 v4l2_err(&dev->v4l2_dev, "invalid media bus format 0x%x\n", mbus_fmt);
340 return -1;
341 }
342
343 if (input_yuv) {
344 if (out_fmt == YUV444) {
345 isp_reg_write(dev->isp_base, REG_ISP_OUT_FMT, INPUT_FMT_YUV);
346 } else {
347 v4l2_err(&dev->v4l2_dev, "%s: mbus_fmt(0x%x) mismatch out_fmt(0x%x)\n",
348 __func__, mbus_fmt, out_fmt);
349 return -1;
350 }
351 } else {
352 if (out_fmt == YUV444) {
353 isp_reg_write(dev->isp_base, REG_ISP_OUT_FMT, INPUT_FMT_RAW);
354 } else if (out_fmt == RAW8) {
355 isp_reg_write(dev->isp_base, REG_ISP_OUT_FMT, INPUT_FMT_RAW_BYPASS);
356 } else {
357 v4l2_err(&dev->v4l2_dev, "%s: mbus_fmt(0x%x) mismatch out_fmt(0x%x)\n",
358 __func__, mbus_fmt, out_fmt);
359 return -1;
360 }
361 }
362 return ret;
363}
364
365static void isp_cisctl_win_set(void __iomem *base, u32 sensor_w, u32 sensor_h)
366{
367 isp_reg_write(base, 0x34, (sensor_h >> 8) & 0x7); // CISCTL_win_height
368 isp_reg_write(base, 0x38, sensor_h & 0xff); // CISCTL_win_height
369 isp_reg_write(base, 0x3c, (sensor_w >> 8) & 0x7); // CISCTL_win_width
370 isp_reg_write(base, 0x40, sensor_w & 0xff); // CISCTL_win_width
371}
372
373static void pipeline_isp_output_size_set(struct asr_camera_dev *dev, u32 isp_out_w, u32 isp_out_h)
374{
375 v4l2_info(&dev->v4l2_dev,"%s: img_width = %d , img_height = %d",
376 __func__, isp_out_w, isp_out_h);
377
378 writel(isp_out_w + (isp_out_h << 16), dev->ipe_base + REG_ISP_IMG_SIZE); // image size from isp
379}
380
381static void isp_out_win_crop(struct asr_camera_dev *dev)
382{
383 u32 isp_out_width, isp_out_height;
384 u32 start_x, end_x, start_y, end_y;
385
386 start_x = dev->pipe2_config.pipeline_crop.start_x;
387 end_x = dev->pipe2_config.pipeline_crop.end_x;
388 start_y = dev->pipe2_config.pipeline_crop.start_y;
389 end_y = dev->pipe2_config.pipeline_crop.end_y;
390
391 isp_out_width = end_x - start_x;
392 isp_out_height = end_y - start_y;
393
394 isp_reg_write(dev->isp_base, 0x244, (start_y >> 8) & 0x7); // crop start y hight
395 isp_reg_write(dev->isp_base, 0x248, start_y & 0xff); // crop start y low
396 isp_reg_write(dev->isp_base, 0x24c, (start_x >> 8) & 0x7); //crop start x hight
397 isp_reg_write(dev->isp_base, 0x250, start_x & 0xff); // crop start x low
398 isp_reg_write(dev->isp_base, 0x254, (isp_out_height >> 8) & 0x7); // out window height
399 isp_reg_write(dev->isp_base, 0x258, isp_out_height & 0xff); // out window height
400 isp_reg_write(dev->isp_base, 0x25c, (isp_out_width >> 8) & 0x7); // out window width
401 isp_reg_write(dev->isp_base, 0x260, isp_out_width & 0xff); // out window width
402
403 pipeline_isp_output_size_set(dev, isp_out_width, isp_out_height);
404}
405
406int fe_isp_process_config(struct asr_camera_dev *dev)
407{
408 int ret = 0;
409
410 isp_cisctl_win_set(dev->isp_base, dev->pipe2_config.pipeline_outw, dev->pipe2_config.pipeline_outh);
411 ret = isp_io_format_set(dev);
412 if (ret)
413 return ret;
414
415 isp_out_win_crop(dev);
416
417 return ret;
418}
419
420static int spi_mtk_mode_set(struct asr_camera_dev *dev, u16 fifo_trig_num, u16 manual_w, u16 manual_h)
421{
422 u16 ln_val;
423 u16 lane_num = 0, spi_sdr_en = 0, spi_crc_en = 0;
424
425 lane_num = dev->camera_interface;
426 spi_sdr_en = dev->spi_config.spi_sdr;
427 spi_crc_en = dev->spi_config.spi_crc;
428
429 v4l2_info(&dev->v4l2_dev, "fifo triger = 0x%x, manual_w = %d, manual_h = %d, lane_num = %d\n",
430 fifo_trig_num, manual_w, manual_h, lane_num);
431
432 switch (lane_num) {
433 case 0:
434 ln_val = LN_SPI1_VAL;
435 break;
436 case 1:
437 ln_val = LN_SPI2_VAL;
438 break;
439 case 2:
440 ln_val = LN_SPI4_VAL;
441 break;
442 default:
443 v4l2_err(&dev->v4l2_dev, "spi lane%d not support\n", lane_num);
444 return -EINVAL;
445 }
446
447 isp_reg_write(dev->isp_base, 0x044, (fifo_trig_num >> 8) & 0xFF); // SPI trig num
448 isp_reg_write(dev->isp_base, 0x048, (fifo_trig_num & 0xFF));
449
450#if 0
451 /* working mode: BT565/Spreadtrum (packaged) */
452 isp_write_mask(dev->isp_base, REG_ISP_SPI_MODE1, 0x0, SPI_MANUAL_MODE_MASK);
453 isp_set_bit(dev->isp_base, REG_ISP_SPI_MODE1, SPI_MANUAL_MODE_EN | SPI_MANUAL_HEIGHT_EN | SPI_MANUAL_WIDTH_EN);
454 isp_reg_write(dev->isp_base, 0x084, (manual_w >> 8) & 0x7); // SPI_manual_width=1280 (in bytes)) = = image_width*2 when YUV422 mode
455 isp_reg_write(dev->isp_base, 0x088, manual_w & 0xff);
456 isp_reg_write(dev->isp_base, 0x08c, (manual_h >> 8) & 0x7); // SPI_manual_height=80
457 isp_reg_write(dev->isp_base, 0x090, manual_h & 0xff);
458#else
459 /* working mode: MTK mode */
460 isp_clr_bit(dev->isp_base, REG_ISP_SPI_MODE1, SPI_MANUAL_MODE_EN | SPI_MANUAL_HEIGHT_EN | SPI_MANUAL_WIDTH_EN);
461#endif
462
463 isp_set_bit(dev->isp_base, REG_ISP_SPI_MODE1, SPI_IGNORE_LINE_ID_EN);
464
465 isp_write_mask(dev->isp_base, REG_ISP_SPI_MODE2, ln_val, SPI_LANE_NUM_MASK);
466 isp_write_mask(dev->isp_base, REG_ISP_SPI_MODE2, (ln_val << 4), SPI_DATA_SWITCH_MASK);
467
468 if (spi_sdr_en) {
469 isp_clr_bit(dev->isp_base, REG_ISP_SPI_MODE2, SPI_NEG_SAMPLE_EN);
470 isp_set_bit(dev->isp_base, REG_ISP_SPI_MODE2, SPI_DDR_MODE_EN);
471 } else {
472 isp_set_bit(dev->isp_base, REG_ISP_SPI_MODE2, SPI_NEG_SAMPLE_EN);
473 isp_clr_bit(dev->isp_base, REG_ISP_SPI_MODE2, SPI_DDR_MODE_EN);
474 }
475
476 isp_reg_write(dev->isp_base, REG_ISP_TOP_MODE, SPI_EN | INPUT_SEL_SPI);
477 if (spi_crc_en) {
478 isp_set_bit(dev->isp_base, REG_ISP_TOP_MODE, SPI_CRC_EN);
479 } else {
480 isp_clr_bit(dev->isp_base, REG_ISP_TOP_MODE, SPI_CRC_EN);
481 }
482
483 return 0;
484}
485
486static int spi_config(struct asr_camera_dev *dev)
487{
488 int ret = 0;
489 u16 mbus_code, spi_fifo = 0;
490 u16 img_w, img_h, manual_w, manual_h;
491 u32 dvp_if = 0, val = 0;
492 struct v4l2_subdev_format fmt;
493
494 fmt = dev->sensor.fmt;
495
496 mbus_code = fmt.format.code;
497 img_w = fmt.format.width;
498 img_h = fmt.format.height;
499
500 v4l2_info(&dev->v4l2_dev, "mbus_code = 0x%x %dx%d\n", mbus_code, img_w, img_h);
501
502 switch (mbus_code) {
503 case MEDIA_BUS_FMT_SBGGR8_1X8:
504 case MEDIA_BUS_FMT_SGBRG8_1X8:
505 case MEDIA_BUS_FMT_SGRBG8_1X8:
506 case MEDIA_BUS_FMT_SRGGB8_1X8:
507 case MEDIA_BUS_FMT_SBGGR10_1X10:
508 case MEDIA_BUS_FMT_SGBRG10_1X10:
509 case MEDIA_BUS_FMT_SGRBG10_1X10:
510 case MEDIA_BUS_FMT_SRGGB10_1X10:
511 manual_w = img_w;
512 manual_h = img_h;
513 spi_fifo = manual_w / 4; // spi_fifo_trig = 1 line bytes / 4
514 dvp_if = ((img_w & 0x7FF) << 16) | 0xC080;
515 break;
516 case MEDIA_BUS_FMT_UYVY8_2X8:
517 case MEDIA_BUS_FMT_VYUY8_2X8:
518 case MEDIA_BUS_FMT_YUYV8_2X8:
519 case MEDIA_BUS_FMT_YVYU8_2X8:
520 manual_w = img_w * 2;
521 manual_h = img_h;
522 if(img_w >= 624)
523 spi_fifo = 0x138; // spi_fifo_trig = (1 line bytes / 4 -8)
524 else
525 spi_fifo = manual_w / 4; // spi_fifo_trig = 1 line bytes / 4
526 // [27]:ISP_OUT_422 '1' valid, <p>=1: use yuv422 from isp
527 // george: when isp reg 0x210[4] is_yuv422
528 dvp_if = BIT(27) | ((img_w & 0x7FF) << 16) | 0xC080;
529 break;
530 default:
531 v4l2_err(&dev->v4l2_dev, "invalid mbus fmt 0x%x\n", mbus_code);
532 return -EINVAL;
533 }
534
535 ret = spi_mtk_mode_set(dev, spi_fifo, manual_w, manual_h);
536 if (ret)
537 v4l2_err(&dev->v4l2_dev, "spi config failed!\n");
538
539 //writel(dvp_if, dev->ipe_base + REG_ISP_DVP_IF_CTRL);
540 val = readl(dev->ipe_base + REG_ISP_DVP_IF_CTRL);
541 val = (val & ~0x9FFFFFFF) | (dvp_if & 0x9FFFFFFF);
542 writel(val,dev->ipe_base + REG_ISP_DVP_IF_CTRL);
543
544 return ret;
545}
546
547int pipeline_update_mac_addr(struct asr_camera_dev *dev, u32 *addr, u32 plane)
548{
549 int i;
550 u32 mac_reg[3];
551
552 mac_reg[0] = REG_Y2_BASE;
553 mac_reg[1] = REG_U2_BASE;
554 mac_reg[2] = REG_V2_BASE;
555
556
557 for (i = 0; i < plane; i++)
558 writel(addr[i], dev->ipe_base + mac_reg[i]);
559
560 return 0;
561}
562
563void cam_set_addr(struct asr_camera_dev *dev, struct isp_buffer *buf)
564{
565 u32 tmp_u_addr = 0;
566 u32 tmp_v_addr = 0;
567 u32 y_size = 0;
568 u32 u_size = 0;
569 u32 start_addr;
570 u32 dmad[3];
571 u32 planes = 0;
572
573 struct pipeline_param *pipe_config = &dev->pipe2_config;
574
575 if (!buf || !buf->dma)
576 return;
577 else
578 start_addr = buf->dma;
579
580 if (0 != start_addr % 8) {
581 start_addr = (start_addr + 8) / 8 * 8;
582 }
583
584 switch(pipe_config->output_format) {
585 case RAW8: // only p2 support, refer to YV12
586 planes = 1; /* FIXME: asic workaround, if uv channel unset, axi wr error */
587 break;
588 case YUV422_YUYV: // 1 planar
589 case YUV422_YVYU: // 1 planar
590 case YUV422_UYVY: // 1 planar
591 case YUV422_VYUY: // 1 planar
592 planes = 1;
593 y_size = pipe_config->dma_stride_y*pipe_config->pipeline_outh*2;
594
595 break;
596 case YUV420_YV12: // 3 planar
597 case YUV420_I420: // 3 planar
598 planes = 3;
599 u_size = pipe_config->dma_stride_y*pipe_config->pipeline_outh * 3 / 2;
600 if(YUV420_I420 == pipe_config->output_format){
601 tmp_u_addr = start_addr + pipe_config->dma_stride_y*pipe_config->pipeline_outh;
602 if (0 != tmp_u_addr % 8) {
603 tmp_u_addr = (tmp_u_addr + 8) / 8 * 8;
604 }
605
606 tmp_v_addr = tmp_u_addr + pipe_config->dma_stride_y*pipe_config->pipeline_outh / 4;
607 if (0 != tmp_v_addr % 8) {
608 tmp_v_addr = (tmp_v_addr + 8) / 8 * 8;
609 }
610 }else{
611 tmp_v_addr = start_addr + pipe_config->dma_stride_y*pipe_config->pipeline_outh;
612 if (0 != tmp_v_addr % 8) {
613 tmp_v_addr = (tmp_v_addr + 8) / 8 * 8;
614 }
615
616 tmp_u_addr = tmp_v_addr + pipe_config->dma_stride_y*pipe_config->pipeline_outh/ 4;
617 if (0 != tmp_u_addr % 8) {
618 tmp_u_addr = (tmp_u_addr + 8) / 8 * 8;
619 }
620 }
621 break;
622 case YUV420_NV12: // 2 planar
623 case YUV420_NV21: // 2 planar
624 planes = 2;
625 u_size = pipe_config->dma_stride_y*pipe_config->pipeline_outh / 2;
626 tmp_u_addr = start_addr + pipe_config->dma_stride_y*pipe_config->pipeline_outh;
627
628 break;
629 default:
630 break;
631 }
632 dmad[0] = start_addr;
633 dmad[1] = tmp_u_addr;
634 dmad[2] = tmp_v_addr;
635
636 v4l2_dbg(1, debug, &dev->v4l2_dev, "update planes%d y:0x%08x u:0x%08x v:0x%08x",
637 planes, dmad[0], dmad[1], dmad[2]);
638
639 pipeline_update_mac_addr(dev, dmad, planes);
640}
641
642static void set_pipeline_scaler(struct pipeline_param* pipe_config)
643{
644 u16 width = 0;
645 u16 height = 0;
646
647 u8 subsample_ratio = 0;
648 u8 scaler_ratio = 4;
649 u8 scaler_cofe = 0;
650
651 u32 h_init_ph = 0x8;
652 u32 h_delta_ph = 0x10000;
653 u32 v_init_ph = 0x8;
654 u32 v_delta_ph = 0x10000;
655
656 subsample_ratio = 1 << pipe_config->subsample;
657
658 width = pipe_config->pipeline_crop.end_x - pipe_config->pipeline_crop.start_x;
659
660 height = pipe_config->pipeline_crop.end_y - pipe_config->pipeline_crop.start_y;
661
662 width /= subsample_ratio;
663 height /= subsample_ratio;
664
665 switch(pipe_config->scaler) {
666 case SCALER_QUARTER:
667 scaler_ratio = 16;
668 scaler_cofe = 0x0;
669 h_init_ph = 0x20;
670 h_delta_ph = 0x40000;
671 v_init_ph = 0x20;
672 v_delta_ph = 0x40000;
673 break;
674 case SCALER_HALF:
675 scaler_ratio = 8;
676 scaler_cofe = 0x5;
677 h_init_ph = 0x10;
678 h_delta_ph = 0x20000;
679 v_init_ph = 0x10;
680 v_delta_ph = 0x20000;
681 break;
682 case NO_SCALER:
683 scaler_ratio = 4;
684 scaler_cofe = 0xf;
685 h_init_ph = 0x8;
686 h_delta_ph = 0x10000;
687 v_init_ph = 0x8;
688 v_delta_ph = 0x10000;
689 break;
690 case SCALER_2:
691 scaler_ratio = 2;
692 scaler_cofe = 0xf;
693 h_init_ph = 0x4;
694 h_delta_ph = 0x8000;
695 v_init_ph = 0x4;
696 v_delta_ph = 0x8000;
697 break;
698 case SCALER_4:
699 scaler_ratio = 1;
700 scaler_cofe = 0xf;
701 h_init_ph = 0x2;
702 h_delta_ph = 0x4000;
703 v_init_ph = 0x2;
704 v_delta_ph = 0x4000;
705 break;
706 default:
707 break;
708 }
709
710 pipe_config->pipeline_outw= width * 4 / scaler_ratio;
711 pipe_config->pipeline_outh= height * 4 / scaler_ratio;
712 pr_info("set_pipeline_scaler: pipeline%d subsample = %d subsample_ratio = %d, dma_width = %d, dma_height = %d, scaler_ratio = %d\n",
713 pipe_config->pipeline_num, pipe_config->subsample, subsample_ratio, pipe_config->pipeline_outw, pipe_config->pipeline_outh, scaler_ratio);
714
715}
716
717static void set_pipeline_jpeg_mode(struct asr_camera_dev *dev)
718{
719 u32 val;
720 if (2 == dev->pipe2_config.pipeline_num) {
721 val = readl(dev->ipe_base + REG_DATA_FORMAT_CTRL);
722 val &= ~(1<<23);
723 writel(val, dev->ipe_base + REG_DATA_FORMAT_CTRL);
724 }
725}
726
727static int set_pipeline_dump_raw(struct asr_camera_dev *dev, u8 pipe_num)
728{
729 if (pipe_num == 2) {
730 writel(readl(dev->ipe_base + REG_SUBSAMPLE_SCALER_CTRL2) | PIPE2_CTRL_RAW_DUMP,
731 dev->ipe_base + REG_SUBSAMPLE_SCALER_CTRL2);
732 return 1;
733 } else {
734 v4l2_err(&dev->v4l2_dev, "pipeline%d not support dump raw!\n", pipe_num);
735 return -1;
736 }
737}
738
739static int set_pipeline_output_format(struct asr_camera_dev *dev)
740{
741 int ret = 0;
742 u32 value = 0;
743 u32 sensor_out_fmt = 0;
744 int is_yuv = 0;
745 struct pipeline_param *pipe_config;
746 u32 reg_value = readl(dev->ipe_base + REG_DATA_FORMAT_CTRL);
747
748 pipe_config = &dev->pipe2_config;
749
750 /*
751 0x0 422 8 bpp planar
752 0x4 422 8 bpp packed
753 0x5 420 8 bpp planar
754 others Reserved
755 */
756 switch(dev->sensor.fmt.format.code) {
757 /*
758 This field defines the Endianness of the external CMOS sensor's output (CCIC's input).
759 This field has no effect on the MIPI CSI2 CMOS sensor.
760 0x0 = Y1CbY0Cr: YUYV sensor
761 0x1 = Y1CrY0Cb: YVYU sensor
762 0x2 = CrY1CbY0: VYUY sensor
763 0x3 = CbY1CrY0: UYVY sensor
764 */
765 case MEDIA_BUS_FMT_YUYV8_2X8:
766 sensor_out_fmt= (0x0<<24); //YUVINFMT
767 is_yuv =1;
768 break;
769 case MEDIA_BUS_FMT_YVYU8_2X8:
770 sensor_out_fmt = (0x1<<24); //YUVINFMT
771 is_yuv =1;
772 break;
773 case MEDIA_BUS_FMT_VYUY8_2X8:
774 sensor_out_fmt= (0x2<<24); //YUVINFMT
775 is_yuv =1;
776 break;
777 case MEDIA_BUS_FMT_UYVY8_2X8:
778 sensor_out_fmt= (0x3<<24); //YUVINFMT
779 is_yuv =1;
780 break;
781 default:
782 break;
783 }
784
785 if(is_yuv)
786 isp_reg_write(dev->isp_base, ISP_OUT_FMT_REG, SENSOR_INPUT_FMT_YUV);
787 else
788 isp_reg_write(dev->isp_base, ISP_OUT_FMT_REG, SENSOR_INPUT_FMT_RAW);
789
790 switch(pipe_config->output_format) {
791 /*
792 <p>0x0 = Y1CbY0Cr: image format vyuy
793 <p>0x1 = Y1CrY0Cb: image format uyvy
794 <p>0x2 = CrY1CbY0: image format yuyv
795 <p>0x3 = CbY1CrY0: image format yvyu
796 */
797 case RAW8: /* only p2 support, refer to NV12 */
798 value += (0x1 << (0 + pipe_config->pipeline_num * 8)); //ISIM_420SP
799 value += (0x0 << (2 + pipe_config->pipeline_num * 8)); //SEMI_UV_ENDFMT
800 value += (0x5 << (4 + pipe_config->pipeline_num * 8)); //YUVOUTFMT
801 ret = set_pipeline_dump_raw(dev, pipe_config->pipeline_num);
802 break;
803 case YUV422_YUYV:
804 value += (0x02 << (26 + pipe_config->pipeline_num * 2)); //YUVENDFMT
805 value += (0x4 << (4 + pipe_config->pipeline_num * 8)); //YUVOUTFMT
806 break;
807 case YUV422_YVYU:
808 value += (0x03 << (26 + pipe_config->pipeline_num * 2)); //YUVENDFMT
809 value += (0x4 << (4 + pipe_config->pipeline_num * 8)); //YUVOUTFMT
810 break;
811 case YUV422_UYVY:
812 value += (0x01 << (26 + pipe_config->pipeline_num * 2)); //YUVENDFMT
813 value += (0x4 << (4 + pipe_config->pipeline_num * 8)); //YUVOUTFMT
814 break;
815 case YUV422_VYUY:
816 value += (0x00 << (26 + pipe_config->pipeline_num * 2)); //YUVENDFMT
817 value += (0x4 << (4 + pipe_config->pipeline_num * 8)); //YUVOUTFMT
818 break;
819 case YUV420_YV12:
820 value += (0x5 << (4 + pipe_config->pipeline_num * 8)); //YUVOUTFMT
821 value += (0x1 << (2 + pipe_config->pipeline_num * 8)); //SEMI_UV_ENDFMT
822 break;
823 case YUV420_I420:
824 value += (0x5 << (4 + pipe_config->pipeline_num * 8)); //YUVOUTFMT
825 value += (0x0 << (2 + pipe_config->pipeline_num * 8)); //SEMI_UV_ENDFMT
826 break;
827 case YUV420_NV12:
828 value += (0x1 << (0 + pipe_config->pipeline_num * 8)); //ISIM_420SP
829 value += (0x0 << (2 + pipe_config->pipeline_num * 8)); //SEMI_UV_ENDFMT
830 value += (0x5 << (4 + pipe_config->pipeline_num * 8)); //YUVOUTFMT
831 break;
832 case YUV420_NV21:
833 value += (0x1 << (0 + pipe_config->pipeline_num * 8)); //ISIM_420SP
834 value += (0x1 << (2 + pipe_config->pipeline_num * 8)); //SEMI_UV_ENDFMT
835 value += (0x5 << (4 + pipe_config->pipeline_num * 8)); //YUVOUTFMT
836 break;
837 case YUV422_3PLANAR:
838 value += (0x0 << (4 + pipe_config->pipeline_num * 8)); //YUVOUTFMT
839 break;
840 default:
841 break;
842 }
843
844 if (2 == pipe_config->pipeline_num) {
845 reg_value &= 0X3F80FFFF;
846 }
847 reg_value += value;
848 reg_value = (reg_value & 0xfcffffff) + sensor_out_fmt;
849 writel(reg_value, dev->ipe_base + REG_DATA_FORMAT_CTRL);
850 v4l2_info(&dev->v4l2_dev, "set_pipeline_output_format: ------pipeline%d format value = 0x%x----------- \n",
851 pipe_config->pipeline_num, reg_value);
852
853 return ret;
854}
855
856static void pipeline_set_img_pitch(struct asr_camera_dev *dev, u16 pitch_y, u16 pitch_uv)
857{
858 u32 reg = REG_PIP2_CCIC_IMG_PITCH;
859
860 writel(pitch_y + (pitch_uv << 16), dev->ipe_base + reg);
861}
862
863static void pipeline_set_img_size(struct asr_camera_dev *dev, u16 width, u16 height)
864{
865 u32 reg = REG_IMG_SIZE_PIP2;
866
867 writel(width + (height << 16), dev->ipe_base + reg);
868}
869
870static int cam_set_pitch_dma_size(struct asr_camera_dev *dev)
871{
872 u16 img_pitch_y, img_pitch_uv, img_width, img_height;
873 struct pipeline_param *pipe_config;
874
875 pipe_config = &dev->pipe2_config;
876 pipe_config->dma_stride_y = ALIGN_TO(pipe_config->pipeline_outw, 8);
877
878 switch (pipe_config->output_format) {
879 case YUV422_YUYV:
880 case YUV422_YVYU:
881 case YUV422_UYVY:
882 case YUV422_VYUY:
883 img_pitch_y = pipe_config->dma_stride_y * 2;
884 img_pitch_uv = pipe_config->dma_stride_y * 2;
885 img_width = pipe_config->pipeline_outw * 2;
886 img_height = pipe_config->pipeline_outh;
887 break;
888 case YUV420_NV12:
889 case YUV420_NV21:
890 img_pitch_y = pipe_config->dma_stride_y;
891 img_pitch_uv = pipe_config->dma_stride_y;
892 img_width = pipe_config->pipeline_outw;
893 img_height = pipe_config->pipeline_outh;
894 break;
895 case YUV420_I420:
896 case YUV420_YV12:
897 img_pitch_y = pipe_config->dma_stride_y;
898 img_pitch_uv = pipe_config->dma_stride_y / 2;
899 img_width = pipe_config->pipeline_outw;
900 img_height = pipe_config->pipeline_outh;
901 break;
902 case RAW8: // only p2 support, refer to YV12
903 if (pipe_config->pipeline_num != 2) {
904 v4l2_err(&dev->v4l2_dev, "pipeline%d not support format raw8!",
905 pipe_config->pipeline_num);
906 return -1;
907 }
908 img_pitch_y = pipe_config->dma_stride_y;
909 img_pitch_uv = pipe_config->dma_stride_y / 2;
910 img_width = pipe_config->pipeline_outw;
911 img_height = pipe_config->pipeline_outh;
912 break;
913 default:
914 v4l2_err(&dev->v4l2_dev, "invalid pipeline%d format%d", pipe_config->pipeline_num, pipe_config->output_format);
915 return -1;
916 }
917
918 v4l2_info(&dev->v4l2_dev, "set_pitch_dma_size: pipeline%d output_format = %d y_pitch = %d, pipe_config->dma_width = %d, pipe_config->dma_height = %d\n",
919 pipe_config->pipeline_num, pipe_config->output_format, pipe_config->dma_stride_y, pipe_config->pipeline_outw, pipe_config->pipeline_outh);
920
921 pipeline_set_img_pitch(dev, img_pitch_y, img_pitch_uv);
922 pipeline_set_img_size(dev, img_width, img_height);
923
924 return 0;
925}
926
927static void set_pipeline_default_fmt(struct asr_camera_dev *dev)
928{
929 struct pipeline_param* pipe_config = &dev->pipe2_config;
930
931 pipe_config->pipeline_num = 2;
932 pipe_config->pipeline_enable = 1;
933 pipe_config->shadow_mode = 1;
934 pipe_config->pipeline_crop.start_x = 0;
935 pipe_config->pipeline_crop.start_y = 0;
936 pipe_config->pipeline_crop.end_x = DEFAULT_WIDTH;
937 pipe_config->pipeline_crop.end_y = DEFAULT_HEIGHT;
938 pipe_config->scaler = NO_SCALER;
939 pipe_config->subsample = 0;
940 pipe_config->output_format = YUV420_NV12;
941
942 return;
943}
944
945static int asrc_sensor_set_stream(struct asr_camera_dev *pcdev, int on)
946{
947 int ret;
948
949 ret = sensor_call(pcdev, video, s_stream, on);
950 if (ret == -ENOIOCTLCMD)
951 ret = 0;
952 if (ret) {
953 v4l2_err(&pcdev->v4l2_dev,
954 "Failed to put subdevice in %s mode: %d\n",
955 on ? "normal operation" : "set stream", ret);
956 }
957
958 return ret;
959}
960
961static int asrc_sensor_set_power(struct asr_camera_dev *pcdev, int on)
962{
963 int ret;
964
965 ret = sensor_call(pcdev, core, s_power, on);
966 if (ret == -ENOIOCTLCMD)
967 ret = 0;
968 if (ret) {
969 v4l2_err(&pcdev->v4l2_dev,
970 "Failed to put subdevice in %s mode: %d\n",
971 on ? "normal operation" : "power saving", ret);
972 }
973
974 return ret;
975}
976
977/*
978 * Videobuf2 section
979 */
980static int asrc_vb2_init(struct vb2_buffer *vb)
981{
982 struct asr_camera_dev *pcdev = vb2_get_drv_priv(vb->vb2_queue);
983 struct isp_buffer *buf = vb2_to_isp_buffer(vb);
984
985 v4l2_dbg(1, debug, &pcdev->v4l2_dev,
986 "%s(vb=%p) size=%lu\n",
987 __func__, vb, vb2_get_plane_payload(vb, 0));
988
989 INIT_LIST_HEAD(&buf->queue);
990 return 0;
991}
992
993static void asrc_vb2_queue(struct vb2_buffer *vb)
994{
995 struct isp_buffer *buf = vb2_to_isp_buffer(vb);
996 struct asr_camera_dev *pcdev = vb2_get_drv_priv(vb->vb2_queue);
997
998 v4l2_dbg(1, debug, &pcdev->v4l2_dev,
999 "%s(vb=%p), addr=0x%x, size=%lu\n",
1000 __func__, vb, buf->dma, vb2_get_plane_payload(vb, 0));
1001
1002 list_add_tail(&buf->queue, &pcdev->capture);
1003}
1004
1005static int asrc_vb2_prepare(struct vb2_buffer *vb)
1006{
1007 struct asr_camera_dev *pcdev = vb2_get_drv_priv(vb->vb2_queue);
1008 struct isp_buffer *buf = vb2_to_isp_buffer(vb);
1009 dma_addr_t addr;
1010
1011 addr = vb2_dma_contig_plane_dma_addr(vb, 0);
1012 if (!IS_ALIGNED(addr, 32)) {
1013 v4l2_err(&pcdev->v4l2_dev,
1014 "Buffer address must be aligned to 32 bytes boundary.\n");
1015 return -EINVAL;
1016 }
1017
1018 vb2_set_plane_payload(vb, 0, pcdev->current_pix.sizeimage);
1019
1020 buf->dma = addr;
1021
1022 v4l2_dbg(1, debug, &pcdev->v4l2_dev,
1023 "%s (vb=%p), addr=0x%x, size=%lu\n",
1024 __func__, vb, addr, vb2_get_plane_payload(vb, 0));
1025
1026 return 0;
1027}
1028
1029static int asrc_vb2_queue_setup(struct vb2_queue *q,
1030 unsigned int *num_buffers,
1031 unsigned int *num_planes, unsigned int sizes[],
1032 struct device *alloc_devs[])
1033{
1034 struct asr_camera_dev *pcdev = vb2_get_drv_priv(q);
1035 int size = pcdev->current_pix.sizeimage;
1036
1037 v4l2_dbg(1, debug, &pcdev->v4l2_dev,
1038 "%s(vq=%p nbufs=%d num_planes=%d size=%d)\n",
1039 __func__, q, *num_buffers, *num_planes, size);
1040
1041 if (*num_planes)
1042 return sizes[0] < size ? -EINVAL : 0;
1043
1044 *num_planes = 1;
1045 sizes[0] = size;
1046
1047 return 0;
1048}
1049
1050static void asr_camera_eof_done(struct asr_camera_dev *pcdev,
1051 struct isp_buffer *buf,
1052 enum vb2_buffer_state state)
1053{
1054 struct vb2_buffer *vb = &buf->vbuf.vb2_buf;
1055 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
1056
1057 v4l2_dbg(1, debug, &pcdev->v4l2_dev, "%s dequeued buffer (buf=0x%x)\n",
1058 __func__, buf->dma);
1059
1060 vb->timestamp = ktime_get_ns();
1061 vbuf->sequence = pcdev->buf_sequence++;
1062 vbuf->field = V4L2_FIELD_NONE;
1063 vb2_buffer_done(vb, state);
1064
1065 if (pcdev->next_buf) {
1066 pcdev->curr_buf = pcdev->next_buf;
1067 pcdev->next_buf = NULL;
1068 } else
1069 pcdev->curr_buf = NULL;
1070
1071}
1072
1073static int asrc_vb2_start_streaming(struct vb2_queue *vq, unsigned int count)
1074{
1075 int ret = 0;
1076 struct asr_camera_dev *pcdev = vb2_get_drv_priv(vq);
1077 unsigned long lock_flags = 0;
1078
1079 spin_lock_irqsave(&pcdev->lock, lock_flags);
1080
1081 pcdev->buf_sequence = 0;
1082 pcdev->curr_buf = list_first_entry(&pcdev->capture,
1083 struct isp_buffer, queue);
1084 list_del(&pcdev->curr_buf->queue);
1085
1086 spin_unlock_irqrestore(&pcdev->lock, lock_flags);
1087
1088 if (pcdev->curr_buf) {
1089 cam_set_addr(pcdev, pcdev->curr_buf);
1090 pcdev->pipe2_config.pipeline_enable = 1;
1091 set_pipeline_enable(pcdev);
1092 set_pipeline_shadow_ready(pcdev);
1093 ret = asrc_sensor_set_stream(pcdev, 1);
1094 }
1095
1096 return ret;
1097}
1098
1099static void asrc_vb2_stop_streaming(struct vb2_queue *vq)
1100{
1101 struct asr_camera_dev *pcdev = vb2_get_drv_priv(vq);
1102 struct isp_buffer *buf;//, *tmp;
1103 unsigned long lock_flags = 0;
1104 unsigned int timeout = 0x100000;
1105
1106 while (pcdev->dma_state && (timeout-- > 0))
1107 udelay(1);
1108
1109 pcdev->pipe2_config.pipeline_enable = 0;
1110 set_pipeline_enable(pcdev);
1111 set_pipeline_shadow_ready(pcdev);
1112 asrc_sensor_set_stream(pcdev, 0);
1113
1114 spin_lock_irqsave(&pcdev->lock, lock_flags);
1115 if (pcdev->curr_buf) {
1116 list_add_tail(&pcdev->curr_buf->queue, &pcdev->capture);
1117 if (pcdev->curr_buf == pcdev->next_buf)
1118 pcdev->next_buf = NULL;
1119 pcdev->curr_buf = NULL;
1120 }
1121
1122 if (pcdev->next_buf) {
1123 list_add_tail(&pcdev->next_buf->queue, &pcdev->capture);
1124 pcdev->next_buf = NULL;
1125 }
1126
1127 while (!list_empty(&pcdev->capture)) {
1128 buf = list_first_entry(&pcdev->capture,
1129 struct isp_buffer, queue);
1130 list_del(&buf->queue);
1131 vb2_buffer_done(&buf->vbuf.vb2_buf, VB2_BUF_STATE_ERROR);
1132 }
1133
1134 spin_unlock_irqrestore(&pcdev->lock, lock_flags);
1135
1136 return;
1137}
1138
1139static const struct vb2_ops asrc_vb2_ops = {
1140 .queue_setup = asrc_vb2_queue_setup,
1141 .buf_prepare = asrc_vb2_prepare,
1142 .buf_init = asrc_vb2_init,
1143 .buf_queue = asrc_vb2_queue,
1144 .start_streaming = asrc_vb2_start_streaming,
1145 .stop_streaming = asrc_vb2_stop_streaming,
1146 .wait_prepare = vb2_ops_wait_prepare,
1147 .wait_finish = vb2_ops_wait_finish,
1148};
1149
1150static int asr_camera_init_videobuf2(struct asr_camera_dev *pcdev)
1151{
1152 int ret;
1153 struct vb2_queue *vq = &pcdev->vb2_vq;
1154
1155 memset(vq, 0, sizeof(*vq));
1156 vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1157 vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
1158 vq->drv_priv = pcdev;
1159 vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
1160 vq->buf_struct_size = sizeof(struct isp_buffer);
1161 vq->dev = pcdev->v4l2_dev.dev;
1162
1163 vq->ops = &asrc_vb2_ops;
1164 vq->mem_ops = &vb2_dma_contig_memops;
1165 vq->lock = &pcdev->mlock;
1166
1167 ret = vb2_queue_init(vq);
1168 v4l2_dbg(1, debug, &pcdev->v4l2_dev,
1169 "vb2_queue_init(vq=%p): %d\n", vq, ret);
1170
1171 return ret;
1172}
1173
1174static int asrc_vidioc_querycap(struct file *file, void *priv,
1175 struct v4l2_capability *cap)
1176{
1177 strscpy(cap->bus_info, "platform:asr-camera", sizeof(cap->bus_info));
1178 strscpy(cap->driver, ASR_CAM_DRV_NAME, sizeof(cap->driver));
1179 strscpy(cap->card, "ASR_Camera", sizeof(cap->card));
1180 return 0;
1181}
1182
1183static int asrc_vidioc_enum_input(struct file *file, void *priv,
1184 struct v4l2_input *i)
1185{
1186 if (i->index > 0)
1187 return -EINVAL;
1188
1189 i->type = V4L2_INPUT_TYPE_CAMERA;
1190 strscpy(i->name, "Camera", sizeof(i->name));
1191
1192 return 0;
1193}
1194
1195static int asrc_vidioc_g_input(struct file *file, void *priv, unsigned int *i)
1196{
1197 *i = 0;
1198
1199 return 0;
1200}
1201
1202static int asrc_vidioc_s_input(struct file *file, void *priv, unsigned int i)
1203{
1204 if (i > 0)
1205 return -EINVAL;
1206
1207 return 0;
1208}
1209
1210static int asrc_vidioc_enum_fmt_vid_cap(struct file *filp, void *priv,
1211 struct v4l2_fmtdesc *f)
1212{
1213 struct asr_camera_dev *pcdev = video_drvdata(filp);
1214
1215 if (f->index >= 1)
1216 return -EINVAL;
1217
1218 f->pixelformat = pcdev->current_pix.pixelformat;
1219 return 0;
1220}
1221
1222static int asrc_vidioc_g_fmt_vid_cap(struct file *filp, void *priv,
1223 struct v4l2_format *f)
1224{
1225 struct asr_camera_dev *pcdev = video_drvdata(filp);
1226 struct v4l2_pix_format *pix = &f->fmt.pix;
1227
1228 pix->width = pcdev->current_pix.width;
1229 pix->height = pcdev->current_pix.height;
1230 pix->bytesperline = pcdev->current_pix.bytesperline;
1231 pix->sizeimage = pcdev->current_pix.sizeimage;
1232 pix->field = pcdev->current_pix.field;
1233 pix->pixelformat = pcdev->current_pix.pixelformat;
1234 pix->colorspace = pcdev->current_pix.colorspace;
1235
1236 v4l2_info(&pcdev->v4l2_dev, "current_fmt->fourcc: 0x%08x\n",
1237 pcdev->current_pix.pixelformat);
1238 return 0;
1239}
1240
1241static int asrc_vidioc_try_fmt_vid_cap(struct file *filp, void *priv,
1242 struct v4l2_format *f)
1243{
1244 struct asr_camera_dev *pcdev = video_drvdata(filp);
1245 struct v4l2_pix_format *pix = &f->fmt.pix;
1246 struct v4l2_subdev_pad_config pad_cfg;
1247 struct v4l2_subdev_format format = {
1248 .which = V4L2_SUBDEV_FORMAT_TRY,
1249 };
1250 struct v4l2_mbus_framefmt *mf = &format.format;
1251 int ret;
1252
1253 if (pix->pixelformat != V4L2_PIX_FMT_YVYU) {
1254 v4l2_err(&pcdev->v4l2_dev, "Format %x not found\n", pix->pixelformat);
1255 return -EINVAL;
1256 }
1257
1258 v4l2_fill_mbus_format(mf, pix, MEDIA_BUS_FMT_YVYU8_2X8);
1259 ret = sensor_call(pcdev, pad, set_fmt, &pad_cfg, &format);
1260 if (ret < 0)
1261 return ret;
1262
1263 v4l2_fill_pix_format(pix, mf);
1264
1265 ret = asr_mbus_image_size(&pcdev->pipe2_config);
1266 if (ret < 0)
1267 return ret;
1268
1269 pix->sizeimage = ret;
1270 return 0;
1271}
1272
1273static int asrc_vidioc_s_fmt_vid_cap(struct file *filp, void *priv,
1274 struct v4l2_format *f)
1275{
1276 struct asr_camera_dev *pcdev = video_drvdata(filp);
1277 struct v4l2_pix_format *pix = &f->fmt.pix;
1278 unsigned long flags;
1279 int ret, is_busy;
1280
1281 v4l2_info(&pcdev->v4l2_dev,
1282 "s_fmt_vid_cap(pix=%dx%d:%x)\n",
1283 pix->width, pix->height, pix->pixelformat);
1284
1285 spin_lock_irqsave(&pcdev->lock, flags);
1286 is_busy = pcdev->curr_buf || vb2_is_busy(&pcdev->vb2_vq);
1287 spin_unlock_irqrestore(&pcdev->lock, flags);
1288
1289 if (is_busy)
1290 return -EBUSY;
1291
1292 ret = asrc_vidioc_try_fmt_vid_cap(filp, priv, f);
1293 if (ret)
1294 return ret;
1295
1296 return ret;
1297}
1298
1299static int asrc_fops_camera_open(struct file *filp)
1300{
1301 struct asr_camera_dev *pcdev = video_drvdata(filp);
1302 int ret;
1303
1304 mutex_lock(&pcdev->mlock);
1305 ret = v4l2_fh_open(filp);
1306 if (ret < 0)
1307 goto out;
1308
1309 if (!v4l2_fh_is_singular_file(filp))
1310 goto out;
1311
1312 ret = asrc_sensor_set_power(pcdev, 1);
1313 if (ret)
1314 v4l2_fh_release(filp);
1315out:
1316 mutex_unlock(&pcdev->mlock);
1317 return ret;
1318}
1319
1320static int asrc_fops_camera_release(struct file *filp)
1321{
1322 struct asr_camera_dev *pcdev = video_drvdata(filp);
1323 int ret;
1324 bool fh_singular;
1325
1326 mutex_lock(&pcdev->mlock);
1327
1328 fh_singular = v4l2_fh_is_singular_file(filp);
1329
1330 ret = _vb2_fop_release(filp, NULL);
1331
1332 if (fh_singular)
1333 ret = asrc_sensor_set_power(pcdev, 0);
1334
1335 mutex_unlock(&pcdev->mlock);
1336
1337 return ret;
1338}
1339
1340static const struct v4l2_file_operations asr_camera_fops = {
1341 .owner = THIS_MODULE,
1342 .open = asrc_fops_camera_open,
1343 .release = asrc_fops_camera_release,
1344 .read = vb2_fop_read,
1345 .poll = vb2_fop_poll,
1346 .mmap = vb2_fop_mmap,
1347 .unlocked_ioctl = video_ioctl2,
1348};
1349
1350static const struct v4l2_ioctl_ops asr_camera_ioctl_ops = {
1351 .vidioc_querycap = asrc_vidioc_querycap,
1352
1353 .vidioc_enum_input = asrc_vidioc_enum_input,
1354 .vidioc_g_input = asrc_vidioc_g_input,
1355 .vidioc_s_input = asrc_vidioc_s_input,
1356
1357 .vidioc_enum_fmt_vid_cap = asrc_vidioc_enum_fmt_vid_cap,
1358 .vidioc_g_fmt_vid_cap = asrc_vidioc_g_fmt_vid_cap,
1359 .vidioc_s_fmt_vid_cap = asrc_vidioc_s_fmt_vid_cap,
1360 .vidioc_try_fmt_vid_cap = asrc_vidioc_try_fmt_vid_cap,
1361
1362 .vidioc_reqbufs = vb2_ioctl_reqbufs,
1363 .vidioc_create_bufs = vb2_ioctl_create_bufs,
1364 .vidioc_querybuf = vb2_ioctl_querybuf,
1365 .vidioc_qbuf = vb2_ioctl_qbuf,
1366 .vidioc_dqbuf = vb2_ioctl_dqbuf,
1367 .vidioc_expbuf = vb2_ioctl_expbuf,
1368 .vidioc_streamon = vb2_ioctl_streamon,
1369 .vidioc_streamoff = vb2_ioctl_streamoff,
1370 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
1371 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
1372};
1373
1374static const struct video_device asr_camera_videodev_template = {
1375 .name = "asr-camera",
1376 .minor = -1,
1377 .fops = &asr_camera_fops,
1378 .ioctl_ops = &asr_camera_ioctl_ops,
1379 .release = video_device_release_empty,
1380 .device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING,
1381};
1382
1383int asrc_update_sensor_info(struct asr_camera_dev *dev)
1384{
1385 struct asr_sensor_info *sensor;
1386 struct v4l2_pix_format *pix = &dev->current_pix;
1387 struct v4l2_mbus_framefmt *mf;
1388 int ret = 0;
1389 struct v4l2_subdev_mbus_code_enum code = {
1390 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
1391 };
1392 unsigned int raw_fmts = 0;
1393
1394 sensor = &dev->sensor;
1395 ret = v4l2_subdev_call(sensor->sd, video, g_mbus_config,
1396 &sensor->mbus);
1397 if (ret && ret != -ENOIOCTLCMD)
1398 return ret;
1399
1400 sensor->fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
1401 ret = v4l2_subdev_call(sensor->sd, pad, get_fmt,
1402 &sensor->cfg, &sensor->fmt);
1403 if (ret && ret != -ENOIOCTLCMD)
1404 return ret;
1405
1406 dev->camera_interface = sensor->fmt.format.reserved[0];
1407 dev->spi_config.spi_sdr = sensor->fmt.format.reserved[1];
1408 dev->spi_config.spi_crc = sensor->fmt.format.reserved[2];
1409 dev->spi_config.spi_manual_enable = sensor->fmt.format.reserved[3];
1410 dev->spi_config.spi_manual_mode = sensor->fmt.format.reserved[4];
1411 dev->spi_config.spi_manual_height_enable = sensor->fmt.format.reserved[5];
1412 dev->spi_config.spi_manual_width_enable = sensor->fmt.format.reserved[6];
1413 dev->spi_config.spi_manual_height = sensor->fmt.format.reserved[7];
1414 dev->spi_config.spi_manual_width = sensor->fmt.format.reserved[8];
1415 dev->spi_config.spi_ignore_line_id = sensor->fmt.format.reserved[9];
1416 v4l2_dbg(1, debug, &dev->v4l2_dev, "lane%d sdr%d crc%d line_id%d\n",
1417 dev->camera_interface, dev->spi_config.spi_sdr, dev->spi_config.spi_crc, dev->spi_config.spi_ignore_line_id);
1418
1419 while (!v4l2_subdev_call(sensor->sd, pad, enum_mbus_code, NULL, &code)) {
1420 raw_fmts++;
1421 code.index++;
1422 }
1423
1424 mf = &sensor->fmt.format;
1425 pix->field = V4L2_FIELD_NONE;
1426 pix->width = DEFAULT_WIDTH;
1427 pix->height = DEFAULT_HEIGHT;
1428 pix->bytesperline = 0;
1429 pix->pixelformat = V4L2_PIX_FMT_YVYU;
1430 v4l2_fill_mbus_format(mf, pix, code.code);//MEDIA_BUS_FMT_YVYU8_2X8);
1431 ret = sensor_call(dev, pad, set_fmt, NULL, &sensor->fmt);
1432 if (ret)
1433 return ret;
1434
1435 v4l2_fill_pix_format(pix, mf);
1436 v4l2_info(&dev->v4l2_dev, "%s(): colorspace=0x%x pixfmt=0x%x\n",
1437 __func__, pix->colorspace, pix->pixelformat);
1438
1439 return ret;
1440}
1441
1442static int asr_camera_pipe_set(struct asr_camera_dev *pcdev)
1443{
1444 int ret = 0;
1445
1446 writel(readl(pcdev->ipe_base + REG_CTRL_1) & ~(1<<31), pcdev->ipe_base + REG_CTRL_1);
1447 set_pipeline_default_fmt(pcdev);
1448 //set scaler
1449 set_pipeline_scaler(&pcdev->pipe2_config);
1450 //set jpeg mode
1451 set_pipeline_jpeg_mode(pcdev);
1452 //set output format
1453 set_pipeline_output_format(pcdev);
1454 //set pitch and dma size
1455 cam_set_pitch_dma_size(pcdev);
1456 pipeline_shadow_streamon(pcdev);
1457
1458 ret = fe_isp_process_config(pcdev);
1459 if (ret < 0) {
1460 v4l2_err(&pcdev->v4l2_dev, "fe_isp_process_config err %d!\n",ret);
1461 return ret;
1462 }
1463
1464 spi_config(pcdev);
1465 return ret;
1466}
1467
1468static int asr_camera_sensor_complete(struct v4l2_async_notifier *notifier)
1469{
1470 int ret = 0;
1471 struct asr_camera_dev *pcdev = v4l2_dev_to_pcdev(notifier->v4l2_dev);
1472 struct v4l2_pix_format *pix = &pcdev->current_pix;
1473
1474 asr_camera_pipe_set(pcdev);
1475 pix->sizeimage = asr_mbus_image_size(&pcdev->pipe2_config);
1476
1477 v4l2_info(&pcdev->v4l2_dev, "Async subdev notifier completed\n");
1478
1479 ret = asrc_sensor_set_power(pcdev, 0);
1480 return ret;
1481}
1482
1483static int asr_camera_sensor_bound(struct v4l2_async_notifier *notifier,
1484 struct v4l2_subdev *subdev,
1485 struct v4l2_async_subdev *asd)
1486{
1487 int err;
1488 struct v4l2_device *v4l2_dev = notifier->v4l2_dev;
1489 struct asr_camera_dev *pcdev = v4l2_dev_to_pcdev(v4l2_dev);
1490 struct video_device *vdev = &pcdev->vdev;
1491
1492 v4l2_info(&pcdev->v4l2_dev, "%s(): trying to bind a device\n",
1493 __func__);
1494
1495 mutex_lock(&pcdev->mlock);
1496
1497 *vdev = asr_camera_videodev_template;
1498 vdev->v4l2_dev = v4l2_dev;
1499 vdev->lock = &pcdev->mlock;
1500 pcdev->sensor.sd = subdev;
1501 pcdev->vdev.queue = &pcdev->vb2_vq;
1502 pcdev->vdev.v4l2_dev = &pcdev->v4l2_dev;
1503 pcdev->vdev.ctrl_handler = subdev->ctrl_handler;
1504 video_set_drvdata(&pcdev->vdev, pcdev);
1505
1506 err = asrc_sensor_set_power(pcdev, 1);
1507 if (err)
1508 goto out;
1509
1510 asrc_sensor_set_stream(pcdev, 0);
1511
1512 err = asrc_update_sensor_info(pcdev);
1513 if (err < 0) {
1514 v4l2_err(&pcdev->v4l2_dev, "update sensor failed\n");
1515 goto out_sensor_poweroff;
1516 }
1517
1518 err = asr_camera_init_videobuf2(pcdev);
1519 if (err)
1520 goto out_sensor_poweroff;
1521
1522 err = video_register_device(&pcdev->vdev, VFL_TYPE_GRABBER, -1);
1523 if (err) {
1524 v4l2_err(v4l2_dev, "register video device failed: %d\n", err);
1525 pcdev->sensor.sd = NULL;
1526 goto out_sensor_poweroff;
1527 } else {
1528 v4l2_info(&pcdev->v4l2_dev,
1529 "ASR Camera driver attached to camera %s\n",
1530 subdev->name);
1531 }
1532
1533 mutex_unlock(&pcdev->mlock);
1534 return err;
1535
1536out_sensor_poweroff:
1537 err = asrc_sensor_set_power(pcdev, 0);
1538out:
1539 mutex_unlock(&pcdev->mlock);
1540 return err;
1541}
1542
1543static void asr_camera_sensor_unbind(struct v4l2_async_notifier *notifier,
1544 struct v4l2_subdev *subdev,
1545 struct v4l2_async_subdev *asd)
1546{
1547 struct asr_camera_dev *pcdev = v4l2_dev_to_pcdev(notifier->v4l2_dev);
1548
1549 mutex_lock(&pcdev->mlock);
1550 v4l2_info(&pcdev->v4l2_dev,
1551 "ASR Camera driver detached from camera %s\n",
1552 subdev->name);
1553
1554 video_unregister_device(&pcdev->vdev);
1555 pcdev->sensor.sd = NULL;
1556
1557 mutex_unlock(&pcdev->mlock);
1558}
1559
1560static const struct v4l2_async_notifier_operations asr_camera_sensor_ops = {
1561 .bound = asr_camera_sensor_bound,
1562 .complete = asr_camera_sensor_complete,
1563 .unbind = asr_camera_sensor_unbind,
1564};
1565
1566static void set_addr(struct asr_camera_dev *dev, int index)
1567{
1568 u32 init_addr = dev->dma_addr_phys;
1569 u32 tmp_u_addr = 0;
1570 u32 tmp_v_addr = 0;
1571 u32 y_size = 0;
1572 u32 u_size = 0;
1573 u32 start_addr;
1574 u32 dmad[3];
1575 u32 planes = 0;
1576
1577 struct pipeline_param *pipe_config = &dev->pipe2_config;
1578
1579 if (index%2 == 0)
1580 start_addr = init_addr;
1581 else
1582 start_addr = init_addr + dev->current_pix.sizeimage;
1583 if (0 != start_addr % 8) {
1584 start_addr = (start_addr + 8) / 8 * 8;
1585 }
1586
1587 switch(pipe_config->output_format) {
1588 case RAW8: // only p2 support, refer to YV12
1589 planes = 1; /* FIXME: asic workaround, if uv channel unset, axi wr error */
1590 break;
1591 case YUV422_YUYV: // 1 planar
1592 case YUV422_YVYU: // 1 planar
1593 case YUV422_UYVY: // 1 planar
1594 case YUV422_VYUY: // 1 planar
1595 planes = 1;
1596 y_size = pipe_config->dma_stride_y*pipe_config->pipeline_outh*2;
1597
1598 break;
1599 case YUV420_YV12: // 3 planar
1600 case YUV420_I420: // 3 planar
1601 planes = 3;
1602 u_size = pipe_config->dma_stride_y*pipe_config->pipeline_outh * 3 / 2;
1603 if(YUV420_I420 == pipe_config->output_format){
1604 tmp_u_addr = start_addr + pipe_config->dma_stride_y*pipe_config->pipeline_outh;
1605 if (0 != tmp_u_addr % 8) {
1606 tmp_u_addr = (tmp_u_addr + 8) / 8 * 8;
1607 }
1608
1609 tmp_v_addr = tmp_u_addr + pipe_config->dma_stride_y*pipe_config->pipeline_outh / 4;
1610 if (0 != tmp_v_addr % 8) {
1611 tmp_v_addr = (tmp_v_addr + 8) / 8 * 8;
1612 }
1613 }else{
1614 tmp_v_addr = start_addr + pipe_config->dma_stride_y*pipe_config->pipeline_outh;
1615 if (0 != tmp_v_addr % 8) {
1616 tmp_v_addr = (tmp_v_addr + 8) / 8 * 8;
1617 }
1618
1619 tmp_u_addr = tmp_v_addr + pipe_config->dma_stride_y*pipe_config->pipeline_outh/ 4;
1620 if (0 != tmp_u_addr % 8) {
1621 tmp_u_addr = (tmp_u_addr + 8) / 8 * 8;
1622 }
1623 }
1624 break;
1625 case YUV420_NV12: // 2 planar
1626 case YUV420_NV21: // 2 planar
1627 planes = 2;
1628 u_size = pipe_config->dma_stride_y*pipe_config->pipeline_outh / 2;
1629 tmp_u_addr = start_addr + pipe_config->dma_stride_y*pipe_config->pipeline_outh;
1630
1631 break;
1632 default:
1633 break;
1634 }
1635 dmad[0] = start_addr;
1636 dmad[1] = tmp_u_addr;
1637 dmad[2] = tmp_v_addr;
1638
1639 v4l2_dbg(1, debug, &dev->v4l2_dev, "update planes%d y:0x%08x u:0x%08x v:0x%08x",
1640 planes, dmad[0], dmad[1], dmad[2]);
1641
1642 pipeline_update_mac_addr(dev, dmad, planes);
1643}
1644
1645#define IMAGE_FILE "/tmp/camera/image"
1646static void cam_image_dump(struct asr_camera_dev *pcdev, int index)
1647{
1648 u32 imagesize = asr_mbus_image_size(&pcdev->pipe2_config);
1649 char filename[32];
1650 struct file *file = NULL;
1651 mm_segment_t old_fs;
1652 char *buf;
1653
1654 sprintf(filename,"%s.jpg", IMAGE_FILE);
1655 v4l2_info(&pcdev->v4l2_dev, "file: %s\n", filename);
1656
1657 if(file == NULL)
1658 file = filp_open(filename, O_RDWR | O_CREAT, 0644);
1659
1660 if (IS_ERR(file)) {
1661 v4l2_err(&pcdev->v4l2_dev, "error occured while opening file %s, exiting...\n", filename);
1662 return;
1663 }
1664 if (index%2 == 0)
1665 buf = (char *)pcdev->dma_addr;
1666 else
1667 buf = (char *)pcdev->dma_addr + imagesize;
1668
1669 old_fs = get_fs();
1670 set_fs(KERNEL_DS);
1671 vfs_write(file, (char *)buf, imagesize, &file->f_pos);
1672 set_fs(old_fs);
1673 filp_close(file, NULL);
1674}
1675
1676static void asr_camera_eof_task(unsigned long arg)
1677{
1678 struct asr_camera_dev *pcdev = (struct asr_camera_dev *)arg;
1679 static u32 index = 0;
1680
1681 if (pcdev->dma_addr) {
1682#ifdef CCIC_IRQ_DEBUG
1683 print_hex_dump(KERN_INFO, "image contents: ",
1684 DUMP_PREFIX_OFFSET, 16, 1,
1685 pcdev->dma_addr, 32, true);
1686#endif
1687 if (snapshot_flag) {
1688 cam_image_dump(pcdev, index);
1689 snapshot_flag = 0;
1690 }
1691 index++;
1692#ifdef CONFIG_FB_ASR
1693 asrfb_camera_preview_start(pcdev->dma_addr_phys, 0, 0, DEFAULT_WIDTH, DEFAULT_HEIGHT);
1694#endif
1695 } else if (!pcdev->curr_buf) {
1696 pcdev->pipe2_config.pipeline_enable = 0;
1697 set_pipeline_enable(pcdev);
1698 set_pipeline_shadow_ready(pcdev);
1699 }
1700 v4l2_dbg(1, debug, &pcdev->v4l2_dev, "Camera interrupt status!\n");
1701}
1702
1703#ifdef CCIC_IRQ_DEBUG
1704static void ccic_irq_handler(u32 irqs)
1705{
1706 u32 i;
1707 static const char *const err_msg[] = {
1708 "Reserved",
1709 "Reserved",
1710 "Reserved",
1711 "Reserved",
1712 "Reserved",
1713 "Reserved",
1714 "Reserved",
1715 "Reserved",
1716 "Reserved",
1717 "Reserved",
1718 "Reserved",
1719 "AXI Write Error IRQ",
1720 "MIPI DPHY RX CLK ULPS Active IRQ",
1721 "MIPI DPHY RX CLK ULPS IRQ",
1722 "MIPI DPHY Lane ULPS Active IRQ",
1723 "MIPI DPHY Lane Error Control IRQ",
1724 "MIPI DPHY Lane Start of Transmission Synchronization Error IRQ",
1725 "MIPI DPHY Lane Start of Transmission Error IRQ",
1726 "Reserved",
1727 "Reserved",
1728 "Reserved",
1729 "Reserved",
1730 "Reserved",
1731 "CSI2 Packet Error IRQ",
1732 "CSI2 CRC Error IRQ",
1733 "CSI2 ECC 2-bit (or more) Error IRQ",
1734 "CSI2 Parity Error IRQ",
1735 "CSI2 ECC Correctable Error IRQ",
1736 "CSI2 Lane FIFO Overrun Error IRQ",
1737 "CSI2 Parse Error IRQ",
1738 "CSI2 Generic Short Packet Valid IRQ",
1739 "CSI2 Generic Short Packet Error IRQ",
1740 };
1741 pr_debug("ccic irq status = 0x%08x\n", irqs);
1742
1743 for (i = 0; i < 32; i++) {
1744 if (irqs & (1 << i)){
1745 pr_info("### %s\n", err_msg[i]);
1746 }
1747 }
1748}
1749#endif
1750
1751static irqreturn_t camera_isr_handler(int irq, void *data)
1752{
1753 struct asr_camera_dev *pcdev = data;
1754 u32 status, csi_irqs;
1755 static u32 sof_index = 0;
1756 unsigned long lock_flags = 0;
1757
1758 csi_irqs = readl(pcdev->ipe_base + REG_CCIC_IRQ_STATUS);
1759 writel(csi_irqs, pcdev->ipe_base + REG_CCIC_IRQ_STATUS);
1760
1761 status = readl(pcdev->ipe_base + REG_CAMERA_IRQ_STATUS);
1762 v4l2_dbg(1, debug, &pcdev->v4l2_dev,
1763 "Camera interrupt status 0x%x\n", status);
1764
1765 if (!status) {
1766 return IRQ_NONE;
1767 }
1768
1769 writel(status, pcdev->ipe_base + REG_CAMERA_IRQ_STATUS);
1770
1771 /*deal with isp eof first.due to index would used by other irq.isp eof is very close with DMA sof*/
1772 if (status & ISP_SOF_IRQ) {
1773 sof_index++;
1774 v4l2_dbg(1, debug, &pcdev->v4l2_dev, ";ISP_SOF_IRQ -----index:%d", sof_index);
1775 if (pcdev->dma_addr) {
1776 set_addr(pcdev, sof_index);
1777 set_pipeline_shadow_ready(pcdev);
1778 } else {
1779 spin_lock_irqsave(&pcdev->lock, lock_flags);
1780 if (!list_empty(&pcdev->capture)) {
1781 pcdev->next_buf =
1782 list_first_entry(&pcdev->capture,
1783 struct isp_buffer,
1784 queue);
1785 list_del(&pcdev->next_buf->queue);
1786 } else {
1787 v4l2_err(&pcdev->v4l2_dev, "%s buffer is empty\n", __func__);
1788 spin_unlock_irqrestore(&pcdev->lock, lock_flags);
1789 return IRQ_HANDLED;
1790 }
1791 spin_unlock_irqrestore(&pcdev->lock, lock_flags);
1792
1793 cam_set_addr(pcdev, pcdev->next_buf);
1794 set_pipeline_shadow_ready(pcdev);
1795 }
1796 pcdev->dma_state = true;
1797 }
1798 if (status & ISP_EOF_IRQ) {
1799 v4l2_dbg(1, debug, &pcdev->v4l2_dev, ";ISP_EOF_IRQ ----- ");
1800 pcdev->dma_state = false;
1801 if (!pcdev->dma_addr && pcdev->curr_buf) {
1802 asr_camera_eof_done(pcdev, pcdev->curr_buf, VB2_BUF_STATE_DONE);
1803 }
1804 tasklet_schedule(&pcdev->task_eof);
1805 }
1806
1807#ifdef CCIC_IRQ_DEBUG
1808 if (status & DVP_FIFO_OVERUN_IRQ) {
1809 v4l2_info(&pcdev->v4l2_dev, ";DVP_FIFO_OVERUN_IRQxxxxx");
1810 }
1811
1812 if (status & DVP_FIFO_UNDERUN_IRQ) {
1813 v4l2_info(&pcdev->v4l2_dev, ";DVP_FIFO_UNDERUN_IRQxxxxx");
1814 }
1815
1816 if (status & PIP2_DMA_FIFO_UNDERUN_IRQ) {
1817 v4l2_info(&pcdev->v4l2_dev, ";PIP2_DMA_FIFO_UNDERUN_IRQxxxxx");
1818 }
1819
1820 if (status & SPI_LINE_ERR_IRQ) {
1821 v4l2_info(&pcdev->v4l2_dev, ";SPI_LINE_ERR_IRQxxxxx");
1822 }
1823
1824 if (status & SPI_CRC_ERR_IRQ) {
1825 v4l2_info(&pcdev->v4l2_dev, ";SPI_CRC_ERR_IRQxxxxx");
1826 }
1827
1828 if (status & PIP2_DMA_SOF_IRQ) {
1829 v4l2_info(&pcdev->v4l2_dev, ";PIP2_DMA_SOF_IRQ------");
1830 }
1831
1832 if (status & PIP2_DMA_FIFO_OVERRUN_IRQ) {
1833 v4l2_info(&pcdev->v4l2_dev, ";PIP2_DMA_FIFO_OVERRUN_IRQxxxxx");
1834 }
1835
1836 if (status & PIP2_DMA_EOF_IRQ) {
1837 v4l2_info(&pcdev->v4l2_dev, ";PIP2_DMA_EOF_IRQ------");
1838 }
1839 if (status & ISIM_IRQ) {
1840 v4l2_info(&pcdev->v4l2_dev, ";ISIM_IRQ------");
1841 ccic_irq_handler(csi_irqs);
1842 }
1843#endif
1844 return IRQ_HANDLED;
1845}
1846
1847static int asr_camera_pdata_from_dt(struct device *dev,
1848 struct asr_camera_dev *pcdev,
1849 struct v4l2_async_subdev *asd)
1850{
1851 u32 mclk_rate;
1852 struct device_node *remote, *np = dev->of_node;
1853 struct v4l2_fwnode_endpoint ep = { .bus_type = 0 };
1854 int err;
1855 int pm_qos;
1856
1857 if (!of_property_read_u32(np, "clock-frequency", &mclk_rate)){
1858 pcdev->mclk_rate = mclk_rate;
1859 } else
1860 pcdev->mclk_rate = 24;
1861
1862 if (of_property_read_u32(np, "lpm-qos", &pm_qos)) {
1863 dev_err(dev, "no pm qos defined\n");
1864 err = -EINVAL;
1865 goto out;
1866 }
1867 pcdev->pm_qos = pm_qos;
1868
1869 np = of_graph_get_next_endpoint(np, NULL);
1870 if (!np) {
1871 dev_err(dev, "could not find endpoint\n");
1872 return -EINVAL;
1873 }
1874
1875 err = v4l2_fwnode_endpoint_parse(of_fwnode_handle(np), &ep);
1876 if (err) {
1877 dev_err(dev, "could not parse endpoint\n");
1878 goto out;
1879 }
1880
1881 asd->match_type = V4L2_ASYNC_MATCH_FWNODE;
1882 remote = of_graph_get_remote_port_parent(np);
1883 if (remote)
1884 asd->match.fwnode = of_fwnode_handle(remote);
1885 else
1886 dev_notice(dev, "no remote for %pOF\n", np);
1887
1888 dev_err(dev, "of_fwnode_handle, name: %s\n", np->name);
1889
1890out:
1891 of_node_put(np);
1892
1893 return err;
1894}
1895static ssize_t capture_cfg_show(struct seq_file *s, void *data)
1896{
1897 struct asr_camera_dev *pcdev = s->private;
1898 struct pipeline_param *pipe_config = &pcdev->pipe2_config;
1899 struct v4l2_pix_format *pix = &pcdev->current_pix;
1900
1901
1902 seq_printf(s, "camera pipeline dump\n");
1903 seq_printf(s, "stridey: %d, width: %d, height: %d, outfmt: 0x%x\n",
1904 pipe_config->dma_stride_y, pipe_config->pipeline_outw, pipe_config->pipeline_outh, pipe_config->output_format);
1905
1906 seq_printf(s, "camera pix_format dump\n");
1907 seq_printf(s, "colorspace: 0x%x, width: %d, height: %d, outfmt: 0x%x, sizeimage: 0x%x\n",
1908 pix->colorspace, pix->width, pix->height, pix->pixelformat, pix->sizeimage);
1909
1910 return 0;
1911}
1912
1913static ssize_t capture_test_write(struct file *filp, const char __user *user_buf,
1914 size_t count, loff_t *ppos)
1915{
1916 struct asr_camera_dev *pcdev =
1917 ((struct seq_file *)(filp->private_data))->private;
1918
1919 char buf[8];
1920 int err;
1921 int on;
1922 int buf_size;
1923 u32 imagesize;
1924 unsigned int timeout = 0x100000;
1925
1926 if (count > 8) {
1927 pr_err("count must be less than 8.\n");
1928 return count;
1929 }
1930
1931 buf_size = min(count, sizeof(buf) - 1);
1932 if (copy_from_user(buf, user_buf, buf_size))
1933 return -EFAULT;
1934
1935 err = sscanf(buf, "%d", &on);
1936 if (err != 1) {
1937 pr_err("debugfs para count error\n");
1938 return count;
1939 }
1940
1941 if (!pcdev->sensor.sd) {
1942 pr_err("No sensor!\n");
1943 return count;
1944 }
1945
1946 imagesize = pcdev->current_pix.sizeimage;
1947
1948 if (on) {
1949 pr_info("alloc imagesize : 0x%x\n", imagesize);
1950 if (NULL == pcdev->dma_addr) {
1951 pcdev->dma_addr = dma_alloc_coherent(pcdev->v4l2_dev.dev,
1952 imagesize*2, &pcdev->dma_addr_phys, GFP_KERNEL);
1953 if (!pcdev->dma_addr) {
1954 dev_WARN_ONCE(pcdev->v4l2_dev.dev, 1,
1955 "failed to allocate tx dma memory\n");
1956 return count;
1957 }
1958 }
1959 asrc_sensor_set_power(pcdev, 1);
1960 set_addr(pcdev, 0);
1961 pcdev->pipe2_config.pipeline_enable = 1;
1962 set_pipeline_enable(pcdev);
1963 set_pipeline_shadow_ready(pcdev);
1964 asrc_sensor_set_stream(pcdev, 1);
1965 } else {
1966 while (pcdev->dma_state && (timeout-- > 0))
1967 udelay(1);
1968 pcdev->pipe2_config.pipeline_enable = 0;
1969 set_pipeline_enable(pcdev);
1970 set_pipeline_shadow_ready(pcdev);
1971 asrc_sensor_set_stream(pcdev, 0);
1972 asrc_sensor_set_power(pcdev, 0);
1973#ifdef CONFIG_FB_ASR
1974 asrfb_camera_preview_stop();
1975#endif
1976 if (pcdev->dma_addr != NULL) {
1977 dma_free_coherent(pcdev->v4l2_dev.dev, imagesize*2, pcdev->dma_addr,
1978 pcdev->dma_addr_phys);
1979 pcdev->dma_addr = NULL;
1980 }
1981 }
1982
1983 return count;
1984}
1985
1986static int capture_test_open(struct inode *inode, struct file *file)
1987{
1988 return single_open(file, capture_cfg_show, inode->i_private);
1989}
1990
1991const struct file_operations capture_test_fops = {
1992 .owner = THIS_MODULE,
1993 .open = capture_test_open,
1994 .read = seq_read,
1995 .write = capture_test_write,
1996};
1997
1998static ssize_t snapshot_cfg_show(struct seq_file *s, void *data)
1999{
2000 seq_printf(s, "snapshot: 0x%d\n", snapshot_flag);
2001
2002 return 0;
2003}
2004
2005static int snapshot_open(struct inode *inode, struct file *file)
2006{
2007 return single_open(file, snapshot_cfg_show, inode->i_private);
2008}
2009
2010static ssize_t snapshot_write(struct file *filp, const char __user *user_buf,
2011 size_t count, loff_t *ppos)
2012{
2013 char buf[8];
2014 int err;
2015 int buf_size;
2016 int cmd;
2017 struct asr_camera_dev *pcdev =
2018 ((struct seq_file *)(filp->private_data))->private;
2019
2020 if (count > 8) {
2021 pr_err("count must be less than 8.\n");
2022 return count;
2023 }
2024
2025 buf_size = min(count, sizeof(buf) - 1);
2026 if (copy_from_user(buf, user_buf, buf_size))
2027 return -EFAULT;
2028
2029 err = sscanf(buf, "%d", &cmd);
2030 if (err != 1) {
2031 pr_err("debugfs para count error\n");
2032 return count;
2033 }
2034 pr_err("input cmd: %d\n", cmd);
2035
2036 if (!pcdev->sensor.sd) {
2037 pr_err("No sensor!\n");
2038 return count;
2039 }
2040
2041 snapshot_flag = 1;
2042
2043 return count;
2044}
2045
2046const struct file_operations snapshot_test_fops = {
2047 .owner = THIS_MODULE,
2048 .open = snapshot_open,
2049 .read = seq_read,
2050 .write = snapshot_write,
2051};
2052
2053static int asr_camera_probe(struct platform_device *pdev)
2054{
2055 int ret;
2056 struct device *dev = &pdev->dev;
2057 struct asr_camera_dev *pcdev;
2058 struct resource *res, *regs;
2059 struct dentry *capture_debug;
2060 struct dentry *snapshot;
2061
2062 pcdev = devm_kzalloc(dev, sizeof(*pcdev), GFP_KERNEL);
2063 if (!pcdev)
2064 return -ENOMEM;
2065
2066 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2067
2068 regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ipe");
2069 pcdev->ipe_base = devm_ioremap_resource(dev, regs);
2070 if (IS_ERR(pcdev->ipe_base)) {
2071 dev_err(dev, "failed to map ipe base\n");
2072 return -ENODEV;
2073 }
2074 ipe_base_reg = pcdev->ipe_base;
2075 regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, "isp");
2076 pcdev->isp_base = devm_ioremap_resource(dev, regs);
2077 if (IS_ERR(pcdev->isp_base)) {
2078 dev_err(dev, "failed to map isp base\n");
2079 return -ENODEV;
2080 }
2081
2082 pcdev->res = res;
2083 pcdev->pm_qos_req.name = pdev->name;
2084 ret = asr_camera_pdata_from_dt(&pdev->dev, pcdev, &pcdev->asd);
2085 if (ret< 0) {
2086 dev_err(&pdev->dev, "Camera parse dt failed\n");
2087 return ret;
2088 }
2089
2090 pcdev->irq = platform_get_irq(pdev, 0);
2091 if (!res || pcdev->irq < 0)
2092 return -ENODEV;
2093 dev_err(&pdev->dev, "Camera irq: %d\n", pcdev->irq);
2094
2095 /* request irq */
2096 ret = devm_request_irq(&pdev->dev, pcdev->irq, camera_isr_handler, 0,
2097 ASR_CAM_DRV_NAME, pcdev);
2098 if (ret ) {
2099 dev_err(&pdev->dev, "Camera interrupt register failed\n");
2100 return ret;
2101 }
2102
2103 tasklet_init(&pcdev->task_eof, asr_camera_eof_task, (unsigned long)pcdev);
2104 dev_err(&pdev->dev, "Camera creat tasklet\n");
2105
2106 INIT_LIST_HEAD(&pcdev->capture);
2107 spin_lock_init(&pcdev->lock);
2108 mutex_init(&pcdev->mlock);
2109
2110 pm_qos_add_request(&pcdev->pm_qos_req, PM_QOS_CPUIDLE_BLOCK,
2111 PM_QOS_CPUIDLE_BLOCK_DEFAULT_VALUE);
2112 asr_camera_activate(pcdev);
2113 dev_set_drvdata(&pdev->dev, pcdev);
2114 ret = v4l2_device_register(&pdev->dev, &pcdev->v4l2_dev);
2115 if (ret) {
2116 dev_err(&pdev->dev, "v4l2_device_register failed\n");
2117 goto exit_deactivate;
2118 }
2119
2120 v4l2_async_notifier_init(&pcdev->notifier);
2121
2122 ret = v4l2_async_notifier_add_subdev(&pcdev->notifier, &pcdev->asd);
2123 if (ret) {
2124 fwnode_handle_put(pcdev->asd.match.fwnode);
2125 dev_err(&pdev->dev, "v4l2_async_notifier_add_subdev failed\n");
2126 goto exit_free_v4l2dev;
2127 }
2128
2129 pcdev->notifier.ops = &asr_camera_sensor_ops;
2130
2131 ret = asr_camera_init_videobuf2(pcdev);
2132 if (ret)
2133 goto exit_notifier_cleanup;
2134
2135 ret = v4l2_async_notifier_register(&pcdev->v4l2_dev, &pcdev->notifier);
2136 if (ret) {
2137 dev_err(&pdev->dev, "v4l2_async_notifier_register failed\n");
2138 goto exit_notifier_cleanup;
2139 }
2140
2141 if (!pcdev->dentry) {
2142 pcdev->dentry = debugfs_create_dir("camera", NULL);
2143
2144 if (!pcdev->dentry || IS_ERR(pcdev->dentry)) {
2145 pr_err("camera debugfs create directory failed\n");
2146 goto exit_notifier_unregister;
2147 } else {
2148 capture_debug = debugfs_create_file("capture", 0664,
2149 pcdev->dentry, pcdev, &capture_test_fops);
2150 if (!capture_debug) {
2151 pr_err("capture debugfs create file failed\n");
2152 goto clean_up;
2153 }
2154 snapshot= debugfs_create_file("snapshot", 0664,
2155 pcdev->dentry, pcdev, &snapshot_test_fops);
2156 if (!snapshot) {
2157 pr_err("snapshot debugfs create file failed\n");
2158 goto clean_up;
2159 }
2160
2161 }
2162 }
2163
2164 return 0;
2165
2166clean_up:
2167 debugfs_remove_recursive(pcdev->dentry);
2168exit_notifier_unregister:
2169 v4l2_async_notifier_unregister(&pcdev->notifier);
2170exit_notifier_cleanup:
2171 v4l2_async_notifier_cleanup(&pcdev->notifier);
2172exit_free_v4l2dev:
2173 v4l2_device_unregister(&pcdev->v4l2_dev);
2174exit_deactivate:
2175 asr_camera_deactivate(pcdev);
2176
2177 return ret;
2178}
2179
2180static int asr_camera_remove(struct platform_device *pdev)
2181{
2182 struct asr_camera_dev *pcdev = dev_get_drvdata(&pdev->dev);
2183
2184 asr_camera_deactivate(pcdev);
2185
2186 v4l2_async_notifier_unregister(&pcdev->notifier);
2187
2188 v4l2_device_unregister(&pcdev->v4l2_dev);
2189
2190 dev_info(&pdev->dev, "ASR Camera driver unloaded\n");
2191
2192 return 0;
2193}
2194
2195/*
2196 * Driver probe, remove, suspend and resume operations
2197 */
2198static int asr_camera_suspend(struct device *dev)
2199{
2200 struct asr_camera_dev *pcdev = dev_get_drvdata(dev);
2201 unsigned int timeout = 0x100000;
2202 int ret = 0;
2203
2204 while (pcdev->dma_state && (timeout-- > 0))
2205 udelay(1);
2206
2207 pcdev->pipe2_config.pipeline_enable = 0;
2208 set_pipeline_enable(pcdev);
2209 set_pipeline_shadow_ready(pcdev);
2210
2211 if (pcdev->sensor.sd) {
2212 ret = asrc_sensor_set_stream(pcdev, 0);
2213 ret |= asrc_sensor_set_power(pcdev, 0);
2214 }
2215
2216 asr_camera_deactivate(pcdev);
2217
2218 return ret;
2219}
2220
2221static int asr_camera_resume(struct device *dev)
2222{
2223 struct asr_camera_dev *pcdev = dev_get_drvdata(dev);
2224 int ret = 0;
2225
2226 init_media_pmu();
2227 config_mclk(pcdev->ipe_base, pcdev->mclk_rate);
2228 pm_qos_update_request(&pcdev->pm_qos_req, pcdev->pm_qos);
2229
2230 asr_camera_activate(pcdev);
2231 asr_camera_pipe_set(pcdev);
2232
2233 return ret;
2234}
2235
2236static const struct dev_pm_ops asr_camera_pm = {
2237 .suspend = asr_camera_suspend,
2238 .resume = asr_camera_resume,
2239};
2240
2241static const struct of_device_id asr_camera_of_match[] = {
2242 { .compatible = "asr,camera", },
2243 {},
2244};
2245MODULE_DEVICE_TABLE(of, asr_camera_of_match);
2246
2247static struct platform_driver asr_camera_driver = {
2248 .driver = {
2249 .name = ASR_CAM_DRV_NAME,
2250 .pm = &asr_camera_pm,
2251 .of_match_table = of_match_ptr(asr_camera_of_match),
2252 },
2253 .probe = asr_camera_probe,
2254 .remove = asr_camera_remove,
2255};
2256
2257module_platform_driver(asr_camera_driver);
2258
2259MODULE_AUTHOR("ASR Inc.");
2260MODULE_DESCRIPTION("ASR GCISP platform driver");
2261MODULE_LICENSE("GPL v2");