tizen 2.4 release
[profile/mobile/platform/kernel/linux-3.10-sc7730.git] / drivers / media / sprd_dcam / pike / dcam_drv.c
1 /*
2  * Copyright (C) 2012 Spreadtrum Communications Inc.
3  *
4  * This software is licensed under the terms of the GNU General Public
5  * License version 2, as published by the Free Software Foundation, and
6  * may be copied, distributed, and modified under those terms.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  */
13 #include <linux/kernel.h>
14 #include <linux/slab.h>
15 #include <linux/interrupt.h>
16 #include <linux/bitops.h>
17 #include <linux/semaphore.h>
18 #include <linux/delay.h>
19 #include <linux/clk.h>
20 #include <linux/err.h>
21 #include <asm/io.h>
22 #include <linux/kthread.h>
23 #include <soc/sprd/hardware.h>
24 #include <mach/irqs.h>
25 #include <soc/sprd/sci.h>
26 #include <soc/sprd/sci_glb_regs.h>
27 #include <linux/vmalloc.h>
28 #include <linux/videodev2.h>
29 #include <linux/wakelock.h>
30 #include "dcam_drv.h"
31 #include "gen_scale_coef.h"
32
33 #define LOCAL static
34 /*#define LOCAL*/
35
36 //#define DCAM_DRV_DEBUG
37 #define DCAM_LOWEST_ADDR                               0x800
38 #define DCAM_ADDR_INVALID(addr)                       ((uint32_t)(addr) < DCAM_LOWEST_ADDR)
39 #define DCAM_YUV_ADDR_INVALID(y,u,v) \
40         (DCAM_ADDR_INVALID(y) && \
41         DCAM_ADDR_INVALID(u) && \
42         DCAM_ADDR_INVALID(v))
43
44 #define DCAM_SC1_H_TAB_OFFSET                          0x400
45 #define DCAM_SC1_V_TAB_OFFSET                          0x4F0
46 #define DCAM_SC1_V_CHROMA_TAB_OFFSET                   0x8F0
47
48 #define DCAM_SC2_H_TAB_OFFSET                          0x1400
49 #define DCAM_SC2_V_TAB_OFFSET                          0x14F0
50 #define DCAM_SC2_V_CHROMA_TAB_OFFSET                   0x18F0
51
52 #define DCAM_SC_COEFF_BUF_SIZE                         (24 << 10)
53 #define DCAM_SC_COEFF_COEF_SIZE                        (1 << 10)
54 #define DCAM_SC_COEFF_TMP_SIZE                         (21 << 10)
55 #define DCAM_SC_COEFF_BUF_COUNT                        2
56
57
58 #define DCAM_SC_H_COEF_SIZE                            (0xC0)
59 #define DCAM_SC_V_COEF_SIZE                            (0x210)
60 #define DCAM_SC_V_CHROM_COEF_SIZE                      (0x210)
61
62 #define DCAM_SC_COEFF_H_NUM                            (DCAM_SC_H_COEF_SIZE/4)
63 #define DCAM_SC_COEFF_V_NUM                            (DCAM_SC_V_COEF_SIZE/4)
64 #define DCAM_SC_COEFF_V_CHROMA_NUM                     (DCAM_SC_V_CHROM_COEF_SIZE/4)
65
66 #define DCAM_AXI_STOP_TIMEOUT                          1000
67 #define DCAM_CLK_DOMAIN_AHB                            1
68 #define DCAM_CLK_DOMAIN_DCAM                           0
69
70 #ifdef CONFIG_SC_FPGA
71 #define DCAM_PATH_TIMEOUT                              msecs_to_jiffies(500*10)
72 #else
73 #define DCAM_PATH_TIMEOUT                              msecs_to_jiffies(500)
74 #endif
75
76 #define DCAM_FRM_QUEUE_LENGTH                          4
77
78 #define DCAM_STATE_QUICKQUIT                           0x01
79
80 #define DCAM_CHECK_PARAM_ZERO_POINTER(n) \
81         do { \
82                 if (0 == (int)(n)) \
83                         return -DCAM_RTN_PARA_ERR; \
84         } while(0)
85
86 #define DCAM_CLEAR(a) \
87         do { \
88                 memset((void *)(a), 0, sizeof(*(a))); \
89         } while(0)
90
91 #define DEBUG_STR                                      "Error L %d, %s \n"
92 #define DEBUG_ARGS                                     __LINE__,__FUNCTION__
93 #define DCAM_RTN_IF_ERR \
94         do { \
95                 if(rtn) { \
96                         printk(DEBUG_STR, DEBUG_ARGS); \
97                         return -(rtn); \
98                 } \
99         } while(0)
100
101 #define DCAM_IRQ_LINE_MASK                             0x001FFFFFUL
102
103 typedef void (*dcam_isr)(void);
104
105 enum {
106         DCAM_FRM_UNLOCK = 0,
107         DCAM_FRM_LOCK_WRITE = 0x10011001,
108         DCAM_FRM_LOCK_READ = 0x01100110
109 };
110
111 enum {
112         DCAM_ST_STOP = 0,
113         DCAM_ST_START,
114 };
115
116 #define DCAM_IRQ_ERR_MASK \
117         ((1 << DCAM_PATH0_OV) | (1 << DCAM_PATH1_OV) | (1 << DCAM_PATH2_OV) | \
118         (1 << DCAM_SN_LINE_ERR) | (1 << DCAM_SN_FRAME_ERR) | \
119         (1 << DCAM_ISP_OV) | (1 << DCAM_MIPI_OV))
120
121 #define DCAM_IRQ_JPEG_OV_MASK                          (1 << DCAM_JPEG_BUF_OV)
122
123 #define DCAM_CHECK_ZERO(a) \
124         do { \
125                 if (DCAM_ADDR_INVALID(a)) { \
126                         printk("DCAM, zero pointer \n"); \
127                         printk(DEBUG_STR, DEBUG_ARGS); \
128                         return -EFAULT; \
129                 } \
130         } while(0)
131
132 #define DCAM_CHECK_ZERO_VOID(a) \
133         do { \
134                 if (DCAM_ADDR_INVALID(a)) { \
135                         printk("DCAM, zero pointer \n"); \
136                         printk(DEBUG_STR, DEBUG_ARGS); \
137                         return; \
138                 } \
139         } while(0)
140
141 struct dcam_cap_desc {
142         uint32_t                   interface;
143         uint32_t                   input_format;
144         uint32_t                   frame_deci_factor;
145         uint32_t                   img_x_deci_factor;
146         uint32_t                   img_y_deci_factor;
147 };
148
149 struct dcam_path_valid {
150         uint32_t                   input_size    :1;
151         uint32_t                   input_rect    :1;
152         uint32_t                   output_size   :1;
153         uint32_t                   output_format :1;
154         uint32_t                   src_sel       :1;
155         uint32_t                   data_endian   :1;
156         uint32_t                   frame_deci    :1;
157         uint32_t                   scale_tap     :1;
158         uint32_t                   v_deci        :1;
159 };
160
161 struct dcam_frm_queue {
162         struct dcam_frame          frm_array[DCAM_FRM_QUEUE_LENGTH];
163         uint32_t                   valid_cnt;
164 };
165
166 struct dcam_buf_queue {
167         struct dcam_frame           frame[DCAM_FRM_CNT_MAX];
168         struct dcam_frame           *write;
169         struct dcam_frame           *read;
170         spinlock_t                  lock;
171 };
172
173 struct dcam_path_desc {
174         struct dcam_size           input_size;
175         struct dcam_rect           input_rect;
176         struct dcam_size           sc_input_size;
177         struct dcam_size           output_size;
178         struct dcam_frame          input_frame;
179         struct dcam_frm_queue      frame_queue;
180         struct dcam_buf_queue      buf_queue;
181         //struct dcam_frame          *output_frame_head;
182         //struct dcam_frame          *output_frame_cur;
183         struct dcam_endian_sel     data_endian;
184         struct dcam_sc_tap         scale_tap;
185         struct dcam_deci           deci_val;
186         struct dcam_path_valid     valid_param;
187         uint32_t                   frame_base_id;
188         uint32_t                   output_frame_count;
189         uint32_t                   output_format;
190         uint32_t                   src_sel;
191         uint32_t                   rot_mode;
192         uint32_t                   frame_deci;
193         uint32_t                   valide;
194         uint32_t                   status;
195         struct semaphore           tx_done_sema;
196         struct semaphore           sof_sema;
197         uint32_t                   wait_for_done;
198         uint32_t                   is_update;
199         uint32_t                   wait_for_sof;
200         uint32_t                   need_stop;
201         uint32_t                   need_wait;
202         int32_t                    sof_cnt;
203 };
204
205 struct dcam_module {
206         uint32_t                   dcam_mode;
207         uint32_t                   module_addr;
208         struct dcam_cap_desc       dcam_cap;
209         struct dcam_path_desc      dcam_path0;
210         struct dcam_path_desc      dcam_path1;
211         struct dcam_path_desc      dcam_path2;
212         struct dcam_frame          path0_frame[DCAM_PATH_0_FRM_CNT_MAX];
213         struct dcam_frame          path1_frame[DCAM_PATH_1_FRM_CNT_MAX];
214         struct dcam_frame          path2_frame[DCAM_PATH_2_FRM_CNT_MAX];
215         struct dcam_frame          path0_reserved_frame;
216         struct dcam_frame          path1_reserved_frame;
217         struct dcam_frame          path2_reserved_frame;
218         struct semaphore           stop_sema;
219         uint32_t                   wait_stop;
220         struct semaphore           resize_done_sema;
221         uint32_t                   wait_resize_done;
222         struct semaphore           rotation_done_sema;
223         uint32_t                   wait_rotation_done;
224         uint32_t                   err_happened;
225         struct semaphore           scale_coeff_mem_sema;
226         uint32_t                   state;
227 };
228
229 struct dcam_sc_coeff {
230         uint32_t                   buf[DCAM_SC_COEFF_BUF_SIZE];
231         uint32_t                   flag;
232         struct dcam_path_desc      dcam_path1;
233 };
234
235 struct dcam_sc_array {
236         struct dcam_sc_coeff       scaling_coeff[DCAM_SC_COEFF_BUF_COUNT];
237         struct dcam_sc_coeff       *scaling_coeff_queue[DCAM_SC_COEFF_BUF_COUNT];
238         uint32_t                   valid_cnt;
239         uint32_t                   is_smooth_zoom;
240 };
241
242 LOCAL atomic_t                 s_dcam_users = ATOMIC_INIT(0);
243 LOCAL atomic_t                 s_resize_flag = ATOMIC_INIT(0);
244 LOCAL atomic_t                 s_rotation_flag = ATOMIC_INIT(0);
245 LOCAL struct clk*              s_dcam_clk = NULL;
246 LOCAL struct dcam_module*      s_p_dcam_mod = 0;
247 LOCAL uint32_t                 s_dcam_irq = 0x5A0000A5;
248 LOCAL dcam_isr_func            s_user_func[DCAM_IRQ_NUMBER];
249 LOCAL void*                    s_user_data[DCAM_IRQ_NUMBER];
250 LOCAL struct dcam_sc_array*    s_dcam_sc_array = NULL;
251 LOCAL struct wake_lock         dcam_wakelock;
252
253 LOCAL DEFINE_MUTEX(dcam_sem);
254 LOCAL DEFINE_MUTEX(dcam_scale_sema);
255 LOCAL DEFINE_MUTEX(dcam_rot_sema);
256 LOCAL DEFINE_MUTEX(dcam_module_sema);
257 LOCAL DEFINE_SPINLOCK(dcam_mod_lock);
258 LOCAL DEFINE_SPINLOCK(dcam_lock);
259 LOCAL DEFINE_SPINLOCK(dcam_glb_reg_cfg_lock);
260 LOCAL DEFINE_SPINLOCK(dcam_glb_reg_control_lock);
261 LOCAL DEFINE_SPINLOCK(dcam_glb_reg_mask_lock);
262 LOCAL DEFINE_SPINLOCK(dcam_glb_reg_clr_lock);
263 LOCAL DEFINE_SPINLOCK(dcam_glb_reg_ahbm_sts_lock);
264 LOCAL DEFINE_SPINLOCK(dcam_glb_reg_endian_lock);
265
266 LOCAL void        _dcam_path0_set(void);
267 LOCAL void        _dcam_path1_set(struct dcam_path_desc *path);
268 LOCAL void        _dcam_path2_set(void);
269 LOCAL void        _dcam_frm_clear(enum dcam_path_index path_index);
270 LOCAL void        _dcam_link_frm(uint32_t base_id);
271 LOCAL int32_t     _dcam_path_set_next_frm(enum dcam_path_index path_index, uint32_t is_1st_frm);
272 /*LOCAL int32_t     _dcam_path_trim(enum dcam_path_index path_index);*/
273 LOCAL int32_t     _dcam_path_scaler(enum dcam_path_index path_index);
274 LOCAL int32_t     _dcam_calc_sc_size(enum dcam_path_index path_index);
275 LOCAL int32_t     _dcam_set_sc_coeff(enum dcam_path_index path_index);
276 LOCAL void        _dcam_force_copy_ext(enum dcam_path_index path_index, uint32_t path_copy, uint32_t coef_copy);
277 LOCAL void        _dcam_auto_copy_ext(enum dcam_path_index path_index, uint32_t path_copy, uint32_t coef_copy);
278 LOCAL void        _dcam_force_copy(enum dcam_path_index path_index);
279 LOCAL void        _dcam_auto_copy(enum dcam_path_index path_index);
280 LOCAL void        _dcam_reg_trace(void);
281 /*LOCAL void        _dcam_sensor_sof(void);*/
282 LOCAL void        _dcam_sensor_eof(void);
283 LOCAL void        _dcam_cap_sof(void);
284 LOCAL void        _dcam_cap_eof(void);
285 LOCAL void        _dcam_path0_done(void);
286 LOCAL void        _dcam_path0_overflow(void);
287 LOCAL void        _dcam_path1_done(void);
288 LOCAL void        _dcam_path1_overflow(void);
289 LOCAL void        _dcam_sensor_line_err(void);
290 LOCAL void        _dcam_sensor_frame_err(void);
291 LOCAL void        _dcam_jpeg_buf_ov(void);
292 LOCAL void        _dcam_path2_done(void);
293 LOCAL void        _dcam_path2_ov(void);
294 LOCAL void        _dcam_isp_ov(void);
295 LOCAL void        _dcam_mipi_ov(void);
296 LOCAL void        _dcam_path1_slice_done(void);
297 LOCAL void        _dcam_path2_slice_done(void);
298 LOCAL void        _dcam_raw_slice_done(void);
299 LOCAL void        _dcam_path1_sof(void);
300 LOCAL void        _dcam_path2_sof(void);
301 LOCAL irqreturn_t _dcam_isr_root(int irq, void *dev_id);
302 LOCAL void        _dcam_stopped_notice(void);
303 LOCAL void        _dcam_stopped(void);
304 LOCAL int32_t     _dcam_path_check_deci(enum dcam_path_index path_index, uint32_t *is_deci);
305 extern void       _dcam_isp_root(void);
306 LOCAL int         _dcam_internal_init(void);
307 LOCAL void        _dcam_internal_deinit(void);
308 LOCAL void        _dcam_wait_path_done(enum dcam_path_index path_index, uint32_t *p_flag);
309 LOCAL void        _dcam_path_done_notice(enum dcam_path_index path_index);
310 LOCAL void        _dcam_rot_done(void);
311 LOCAL int32_t     _dcam_err_pre_proc(void);
312 LOCAL void        _dcam_frm_queue_clear(struct dcam_frm_queue *queue);
313 LOCAL int32_t     _dcam_frame_enqueue(struct dcam_frm_queue *queue, struct dcam_frame *frame);
314 LOCAL int32_t     _dcam_frame_dequeue(struct dcam_frm_queue *queue, struct dcam_frame *frame);
315 LOCAL void        _dcam_buf_queue_init(struct dcam_buf_queue *queue);
316 LOCAL int32_t     _dcam_buf_queue_write(struct dcam_buf_queue *queue, struct dcam_frame *frame);
317 LOCAL int32_t     _dcam_buf_queue_read(struct dcam_buf_queue *queue, struct dcam_frame *frame);
318 LOCAL void        _dcam_wait_update_done(enum dcam_path_index path_index, uint32_t *p_flag);
319 LOCAL void        _dcam_path_updated_notice(enum dcam_path_index path_index);
320 LOCAL int32_t     _dcam_get_valid_sc_coeff(struct dcam_sc_array *sc, struct dcam_sc_coeff **sc_coeff);
321 LOCAL int32_t     _dcam_push_sc_buf(struct dcam_sc_array *sc, uint32_t index);
322 LOCAL int32_t     _dcam_pop_sc_buf(struct dcam_sc_array *sc, struct dcam_sc_coeff **sc_coeff);
323 LOCAL int32_t     _dcam_calc_sc_coeff(enum dcam_path_index path_index);
324 LOCAL int32_t     _dcam_write_sc_coeff(enum dcam_path_index path_index);
325 LOCAL void        _dcam_wait_for_quickstop(enum dcam_path_index path_index);
326
327 LOCAL const dcam_isr isr_list[DCAM_IRQ_NUMBER] = {
328         NULL,//_dcam_isp_root,
329         _dcam_sensor_eof,
330         _dcam_cap_sof,
331         _dcam_cap_eof,
332         _dcam_path0_done,
333         _dcam_path0_overflow,
334         _dcam_path1_done,
335         _dcam_path1_overflow,
336         _dcam_path2_done,
337         _dcam_path2_ov,
338         _dcam_sensor_line_err,
339         _dcam_sensor_frame_err,
340         _dcam_jpeg_buf_ov,
341         _dcam_isp_ov,
342         _dcam_mipi_ov,
343         _dcam_rot_done,
344         _dcam_path1_slice_done,
345         _dcam_path2_slice_done,
346         _dcam_raw_slice_done,
347         _dcam_path1_sof,
348         _dcam_path2_sof,
349 };
350
351 void dcam_glb_reg_awr(uint32_t addr, uint32_t val, uint32_t reg_id)
352 {
353         unsigned long flag;
354
355         switch(reg_id) {
356         case DCAM_CFG_REG:
357                 spin_lock_irqsave(&dcam_glb_reg_cfg_lock, flag);
358                 REG_WR(addr, REG_RD(addr) & (val));
359                 spin_unlock_irqrestore(&dcam_glb_reg_cfg_lock, flag);
360                 break;
361         case DCAM_CONTROL_REG:
362                 spin_lock_irqsave(&dcam_glb_reg_control_lock, flag);
363                 REG_WR(addr, REG_RD(addr) & (val));
364                 spin_unlock_irqrestore(&dcam_glb_reg_control_lock, flag);
365                 break;
366         case DCAM_INIT_MASK_REG:
367                 spin_lock_irqsave(&dcam_glb_reg_mask_lock, flag);
368                 REG_WR(addr, REG_RD(addr) & (val));
369                 spin_unlock_irqrestore(&dcam_glb_reg_mask_lock, flag);
370                 break;
371         case DCAM_INIT_CLR_REG:
372                 spin_lock_irqsave(&dcam_glb_reg_clr_lock, flag);
373                 REG_WR(addr, REG_RD(addr) & (val));
374                 spin_unlock_irqrestore(&dcam_glb_reg_clr_lock, flag);
375                 break;
376         case DCAM_AHBM_STS_REG:
377                 spin_lock_irqsave(&dcam_glb_reg_ahbm_sts_lock, flag);
378                 REG_WR(addr, REG_RD(addr) & (val));
379                 spin_unlock_irqrestore(&dcam_glb_reg_ahbm_sts_lock, flag);
380                 break;
381         case DCAM_ENDIAN_REG:
382                 spin_lock_irqsave(&dcam_glb_reg_endian_lock, flag);
383                 REG_WR(addr, REG_RD(addr) & (val));
384                 spin_unlock_irqrestore(&dcam_glb_reg_endian_lock, flag);
385                 break;
386         default:
387                 REG_WR(addr, REG_RD(addr) & (val));
388                 break;
389         }
390 }
391
392 void dcam_glb_reg_owr(uint32_t addr, uint32_t val, uint32_t reg_id)
393 {
394         unsigned long flag;
395
396         switch(reg_id) {
397         case DCAM_CFG_REG:
398                 spin_lock_irqsave(&dcam_glb_reg_cfg_lock, flag);
399                 REG_WR(addr, REG_RD(addr) | (val));
400                 spin_unlock_irqrestore(&dcam_glb_reg_cfg_lock, flag);
401                 break;
402         case DCAM_CONTROL_REG:
403                 spin_lock_irqsave(&dcam_glb_reg_control_lock, flag);
404                 REG_WR(addr, REG_RD(addr) | (val));
405                 spin_unlock_irqrestore(&dcam_glb_reg_control_lock, flag);
406                 break;
407         case DCAM_INIT_MASK_REG:
408                 spin_lock_irqsave(&dcam_glb_reg_mask_lock, flag);
409                 REG_WR(addr, REG_RD(addr) | (val));
410                 spin_unlock_irqrestore(&dcam_glb_reg_mask_lock, flag);
411                 break;
412         case DCAM_INIT_CLR_REG:
413                 spin_lock_irqsave(&dcam_glb_reg_clr_lock, flag);
414                 REG_WR(addr, REG_RD(addr) | (val));
415                 spin_unlock_irqrestore(&dcam_glb_reg_clr_lock, flag);
416                 break;
417         case DCAM_AHBM_STS_REG:
418                 spin_lock_irqsave(&dcam_glb_reg_ahbm_sts_lock, flag);
419                 REG_WR(addr, REG_RD(addr) | (val));
420                 spin_unlock_irqrestore(&dcam_glb_reg_ahbm_sts_lock, flag);
421                 break;
422         case DCAM_ENDIAN_REG:
423                 spin_lock_irqsave(&dcam_glb_reg_endian_lock, flag);
424                 REG_WR(addr, REG_RD(addr) | (val));
425                 spin_unlock_irqrestore(&dcam_glb_reg_endian_lock, flag);
426                 break;
427         default:
428                 REG_WR(addr, REG_RD(addr) | (val));
429                 break;
430         }
431 }
432
433 void dcam_glb_reg_mwr(uint32_t addr, uint32_t mask, uint32_t val, uint32_t reg_id)
434 {
435         unsigned long flag;
436         uint32_t tmp = 0;
437
438         switch(reg_id) {
439         case DCAM_CFG_REG:
440                 spin_lock_irqsave(&dcam_glb_reg_cfg_lock, flag);
441                 {
442                         tmp = REG_RD(addr);
443                         tmp &= ~(mask);
444                         REG_WR(addr, tmp | ((mask) & (val)));
445                 }
446                 spin_unlock_irqrestore(&dcam_glb_reg_cfg_lock, flag);
447                 break;
448         case DCAM_CONTROL_REG:
449                 spin_lock_irqsave(&dcam_glb_reg_control_lock, flag);
450                 {
451                         tmp = REG_RD(addr);
452                         tmp &= ~(mask);
453                         REG_WR(addr, tmp | ((mask) & (val)));
454                 }
455                 spin_unlock_irqrestore(&dcam_glb_reg_control_lock, flag);
456                 break;
457         case DCAM_INIT_MASK_REG:
458                 spin_lock_irqsave(&dcam_glb_reg_mask_lock, flag);
459                 {
460                         tmp = REG_RD(addr);
461                         tmp &= ~(mask);
462                         REG_WR(addr, tmp | ((mask) & (val)));
463                 }
464                 spin_unlock_irqrestore(&dcam_glb_reg_mask_lock, flag);
465                 break;
466         case DCAM_INIT_CLR_REG:
467                 spin_lock_irqsave(&dcam_glb_reg_clr_lock, flag);
468                 {
469                         tmp = REG_RD(addr);
470                         tmp &= ~(mask);
471                         REG_WR(addr, tmp | ((mask) & (val)));
472                 }
473                 spin_unlock_irqrestore(&dcam_glb_reg_clr_lock, flag);
474                 break;
475         case DCAM_AHBM_STS_REG:
476                 spin_lock_irqsave(&dcam_glb_reg_ahbm_sts_lock, flag);
477                 {
478                         tmp = REG_RD(addr);
479                         tmp &= ~(mask);
480                         REG_WR(addr, tmp | ((mask) & (val)));
481                 }
482                 spin_unlock_irqrestore(&dcam_glb_reg_ahbm_sts_lock, flag);
483                 break;
484         case DCAM_ENDIAN_REG:
485                 spin_lock_irqsave(&dcam_glb_reg_endian_lock, flag);
486                 {
487                         tmp = REG_RD(addr);
488                         tmp &= ~(mask);
489                         REG_WR(addr, tmp | ((mask) & (val)));
490                 }
491                 spin_unlock_irqrestore(&dcam_glb_reg_endian_lock, flag);
492                 break;
493         default:
494                 {
495                         tmp = REG_RD(addr);
496                         tmp &= ~(mask);
497                         REG_WR(addr, tmp | ((mask) & (val)));
498                 }
499                 break;
500         }
501 }
502
503 int32_t dcam_module_init(enum dcam_cap_if_mode if_mode,
504                       enum dcam_cap_sensor_mode sn_mode)
505 {
506         enum dcam_drv_rtn       rtn = DCAM_RTN_SUCCESS;
507         struct dcam_cap_desc    *cap_desc = NULL;
508
509         if (if_mode >= DCAM_CAP_IF_MODE_MAX) {
510                 rtn = -DCAM_RTN_CAP_IF_MODE_ERR;
511         } else {
512                 if (sn_mode >= DCAM_CAP_MODE_MAX) {
513                         rtn = -DCAM_RTN_CAP_SENSOR_MODE_ERR;
514                 } else {
515                         _dcam_internal_init();
516                         _dcam_link_frm(0); /* set default base frame index as 0 */
517                         _dcam_buf_queue_init(&s_p_dcam_mod->dcam_path0.buf_queue);
518                         _dcam_buf_queue_init(&s_p_dcam_mod->dcam_path1.buf_queue);
519                         _dcam_buf_queue_init(&s_p_dcam_mod->dcam_path2.buf_queue);
520                         cap_desc = &s_p_dcam_mod->dcam_cap;
521                         cap_desc->interface = if_mode;
522                         cap_desc->input_format = sn_mode;
523                         /*REG_OWR(DCAM_EB, BIT_13);//MM_EB*/
524                         /*REG_OWR(DCAM_MATRIX_EB, BIT_10|BIT_5);*/
525                         if (DCAM_CAP_IF_CSI2 == if_mode) {
526                         /*      REG_OWR(CSI2_DPHY_EB, MIPI_EB_BIT);*/
527                                 //ret = _dcam_mipi_clk_en();
528                                 dcam_glb_reg_owr(DCAM_CFG, BIT_9, DCAM_CFG_REG);
529                                 REG_MWR(CAP_MIPI_CTRL, BIT_2 | BIT_1, sn_mode << 1);
530                         } else {
531                                 /*REG_OWR(DCAM_EB, CCIR_IN_EB_BIT);
532                                 REG_OWR(DCAM_EB, CCIR_EB_BIT);*/
533                                 //ret = _dcam_ccir_clk_en();
534                                 dcam_glb_reg_mwr(DCAM_CFG, BIT_9, 0 << 9, DCAM_CFG_REG);
535                                 REG_MWR(CAP_CCIR_CTRL, BIT_2 | BIT_1, sn_mode << 1);
536                         }
537                         rtn = DCAM_RTN_SUCCESS;
538                 }
539         }
540
541         return -rtn;
542 }
543
544 int32_t dcam_module_deinit(enum dcam_cap_if_mode if_mode,
545                       enum dcam_cap_sensor_mode sn_mode)
546 {
547         enum dcam_drv_rtn       rtn = DCAM_RTN_SUCCESS;
548
549         if (DCAM_CAP_IF_CSI2 == if_mode) {
550                 /*REG_MWR(CSI2_DPHY_EB, MIPI_EB_BIT, 0 << 10);*/
551                 dcam_glb_reg_mwr(DCAM_CFG, BIT_9, 0 << 9, DCAM_CFG_REG);
552                 //_dcam_mipi_clk_dis();
553         } else {
554                 /*REG_MWR(DCAM_EB, CCIR_IN_EB_BIT, 0 << 2);
555                 REG_MWR(DCAM_EB, CCIR_EB_BIT, 0 << 9);*/
556                 dcam_glb_reg_mwr(DCAM_CFG, BIT_9, 0 << 9, DCAM_CFG_REG);
557                 //_dcam_ccir_clk_dis();
558         }
559
560         _dcam_internal_deinit();
561
562         return -rtn;
563 }
564
565 int dcam_scale_coeff_alloc(void)
566 {
567         int ret = 0;
568
569         if (NULL == s_dcam_sc_array) {
570                 s_dcam_sc_array = (struct dcam_sc_array*)vzalloc(sizeof(struct dcam_sc_array));
571                 if (NULL == s_dcam_sc_array) {
572                         printk("DCAM: _dcam_scale_coeff_alloc fail.\n");
573                         ret = -1;
574                 }
575         }
576
577         return ret;
578 }
579
580 void dcam_scale_coeff_free(void)
581 {
582         if (s_dcam_sc_array) {
583                 vfree(s_dcam_sc_array);
584                 s_dcam_sc_array = NULL;
585         }
586 }
587
588 LOCAL uint32_t *dcam_get_scale_coeff_addr(uint32_t *index)
589 {
590         uint32_t i;
591
592         if (DCAM_ADDR_INVALID(s_dcam_sc_array)) {
593                 printk("DCAM: scale addr, invalid param 0x%x \n",
594                         (uint32_t)s_dcam_sc_array);
595                 return NULL;
596         }
597
598         for (i = 0; i < DCAM_SC_COEFF_BUF_COUNT; i++) {
599                 if (0 == s_dcam_sc_array->scaling_coeff[i].flag) {
600                         *index = i;
601                         DCAM_TRACE("dcam: get buf index %d \n", i);
602                         return s_dcam_sc_array->scaling_coeff[i].buf;
603                 }
604         }
605         printk("dcam: get buf index %d \n", i);
606
607         return NULL;
608 }
609
610 int32_t dcam_module_en(struct device_node *dn)
611 {
612         int             ret = 0;
613         unsigned int    irq_no = 0;
614
615         DCAM_TRACE("DCAM: dcam_module_en, In %d \n", s_dcam_users.counter);
616
617         mutex_lock(&dcam_module_sema);
618         if (atomic_inc_return(&s_dcam_users) == 1) {
619
620                 wake_lock_init(&dcam_wakelock, WAKE_LOCK_SUSPEND,
621                         "pm_message_wakelock_dcam");
622
623                 wake_lock(&dcam_wakelock);
624
625                 ret = clk_mm_i_eb(dn,1);
626                 if (ret) {
627                         ret = -DCAM_RTN_MAX;
628                         goto fail_exit;
629                 }
630
631                 ret = dcam_set_clk(dn,DCAM_CLK_256M);
632                 if (ret) {
633                         clk_mm_i_eb(dn,0);
634                         ret = -DCAM_RTN_MAX;
635                         goto fail_exit;
636                 }
637
638                 parse_baseaddress(dn);
639
640                 dcam_reset(DCAM_RST_ALL, 0);
641                 atomic_set(&s_resize_flag, 0);
642                 atomic_set(&s_rotation_flag, 0);
643                 memset((void*)s_user_func, 0, sizeof(s_user_func));
644                 memset((void*)s_user_data, 0, sizeof(s_user_data));
645                 printk("DCAM: register isr, 0x%x \n", REG_RD(DCAM_INT_MASK));
646
647                 irq_no = parse_irq(dn);
648                 printk("DCAM: irq_no = 0x%x \n", irq_no);
649                 ret = request_irq(irq_no,
650                                 _dcam_isr_root,
651                                 IRQF_SHARED,
652                                 "DCAM",
653                                 (void*)&s_dcam_irq);
654                 if (ret) {
655                         printk("DCAM: dcam_start, error %d \n", ret);
656                         dcam_set_clk(dn,DCAM_CLK_NONE);
657                         clk_mm_i_eb(dn,0);
658                         ret = -DCAM_RTN_MAX;
659                         goto fail_exit;
660                 }
661
662                 DCAM_TRACE("DCAM: dcam_module_en end \n");
663         }
664         DCAM_TRACE("DCAM: dcam_module_en, Out %d \n", s_dcam_users.counter);
665         mutex_unlock(&dcam_module_sema);
666         return 0;
667
668 fail_exit:
669         wake_unlock(&dcam_wakelock);
670         wake_lock_destroy(&dcam_wakelock);
671         atomic_dec(&s_dcam_users);
672         mutex_unlock(&dcam_module_sema);
673         return ret;
674 }
675
676 int32_t dcam_module_dis(struct device_node *dn)
677 {
678         enum dcam_drv_rtn       rtn = DCAM_RTN_SUCCESS;
679         int                     ret = 0;
680         unsigned int            irq_no = 0;
681
682         DCAM_TRACE("DCAM: dcam_module_dis, In %d \n", s_dcam_users.counter);
683
684         mutex_lock(&dcam_module_sema);
685         if (atomic_dec_return(&s_dcam_users) == 0) {
686
687                 sci_glb_clr(DCAM_EB, DCAM_EB_BIT);
688                 dcam_set_clk(dn,DCAM_CLK_NONE);
689                 printk("DCAM: un register isr \n");
690                 irq_no = parse_irq(dn);
691                 free_irq(irq_no, (void*)&s_dcam_irq);
692                 ret = clk_mm_i_eb(dn,0);
693                 if (ret) {
694                         rtn = -DCAM_RTN_MAX;
695                 }
696                 wake_unlock(&dcam_wakelock);
697                 wake_lock_destroy(&dcam_wakelock);
698         }
699
700         DCAM_TRACE("DCAM: dcam_module_dis, Out %d \n", s_dcam_users.counter);
701         mutex_unlock(&dcam_module_sema);
702
703         return rtn;
704 }
705
706 int32_t dcam_reset(enum dcam_rst_mode reset_mode, uint32_t is_isr)
707 {
708         enum dcam_drv_rtn       rtn = DCAM_RTN_SUCCESS;
709         uint32_t                time_out = 0;
710
711         DCAM_TRACE("DCAM: reset: %d \n", reset_mode);
712
713         if (!is_isr) {
714                 mutex_lock(&dcam_scale_sema);
715                 mutex_lock(&dcam_rot_sema);
716         }
717
718         if (DCAM_RST_ALL == reset_mode) {
719                 if (atomic_read(&s_dcam_users)) {
720                         /* firstly, stop AXI writing */
721                         dcam_glb_reg_owr(DCAM_AHBM_STS, BIT_6, DCAM_AHBM_STS_REG);
722                 }
723
724                 /* then wait for AHB busy cleared */
725                 while (++time_out < DCAM_AXI_STOP_TIMEOUT) {
726                         if (0 == (REG_RD(DCAM_AHBM_STS) & BIT_0))
727                                 break;
728                 }
729                 if (time_out >= DCAM_AXI_STOP_TIMEOUT) {
730                         printk("DCAM: reset TO: %d \n", time_out);
731                         return DCAM_RTN_TIMEOUT;
732                 }
733         }
734
735         /* do reset action */
736         switch (reset_mode) {
737         case DCAM_RST_PATH0:
738                 sci_glb_set(DCAM_RST, PATH0_RST_BIT);
739                 sci_glb_clr(DCAM_RST, PATH0_RST_BIT);
740                 DCAM_TRACE("DCAM: reset path0 \n");
741                 break;
742
743         case DCAM_RST_PATH1:
744                 sci_glb_set(DCAM_RST, PATH1_RST_BIT);
745                 sci_glb_clr(DCAM_RST, PATH1_RST_BIT);
746                 DCAM_TRACE("DCAM: reset path1 \n");
747                 break;
748
749         case DCAM_RST_PATH2:
750                 sci_glb_set(DCAM_RST, PATH2_RST_BIT);
751                 sci_glb_clr(DCAM_RST, PATH2_RST_BIT);
752                 DCAM_TRACE("DCAM: reset path2 \n");
753                 break;
754
755         case DCAM_RST_ALL:
756                 sci_glb_set(DCAM_RST, DCAM_MOD_RST_BIT | CCIR_RST_BIT);
757                 sci_glb_clr(DCAM_RST, DCAM_MOD_RST_BIT | CCIR_RST_BIT);
758                 dcam_glb_reg_owr(DCAM_INT_CLR,
759                                         DCAM_IRQ_LINE_MASK,
760                                         DCAM_INIT_CLR_REG);
761                 dcam_glb_reg_owr(DCAM_INT_MASK,
762                                                 DCAM_IRQ_LINE_MASK,
763                                                 DCAM_INIT_MASK_REG);
764                 printk("DCAM: reset all \n");
765                 break;
766         default:
767                 rtn = DCAM_RTN_PARA_ERR;
768                 break;
769         }
770
771         if (DCAM_RST_ALL == reset_mode) {
772                 if (atomic_read(&s_dcam_users)) {
773                         /* the end, enable AXI writing */
774                         dcam_glb_reg_awr(DCAM_AHBM_STS, ~BIT_6, DCAM_AHBM_STS_REG);
775                 }
776         }
777
778         if (!is_isr) {
779                 mutex_unlock(&dcam_rot_sema);
780                 mutex_unlock(&dcam_scale_sema);
781         }
782
783         DCAM_TRACE("DCAM: reset_mode=%x  end \n", reset_mode);
784
785         return -rtn;
786 }
787
788 int32_t dcam_set_clk(struct device_node *dn, enum dcam_clk_sel clk_sel)
789 {
790 #ifdef CONFIG_SC_FPGA_CLK
791         return 0;
792 #else
793         enum dcam_drv_rtn       rtn = DCAM_RTN_SUCCESS;
794         struct clk              *clk_parent;
795         char                    *parent = "clk_312m";
796         int                     ret = 0;
797
798         switch (clk_sel) {
799         case DCAM_CLK_312M:
800                 parent = "clk_312m";
801                 break;
802         case DCAM_CLK_256M:
803                 parent = "clk_256m";
804                 break;
805         case DCAM_CLK_128M:
806                 parent = "clk_128m";
807                 break;
808         case DCAM_CLK_76M8:
809                 parent = "clk_76p8m";
810                 break;
811         case DCAM_CLK_NONE:
812                 printk("DCAM close CLK %d \n", (int)clk_get_rate(s_dcam_clk));
813                 if (s_dcam_clk) {
814                         clk_disable(s_dcam_clk);
815                         clk_put(s_dcam_clk);
816                         s_dcam_clk = NULL;
817                 }
818                 return 0;
819         default:
820                 parent = "clk_128m";
821                 break;
822         }
823
824         if (NULL == s_dcam_clk) {
825                 s_dcam_clk = parse_clk(dn,"clk_dcam");
826                 if (IS_ERR(s_dcam_clk)) {
827                         printk("DCAM: clk_get fail, %d \n", (int)s_dcam_clk);
828                         return -1;
829                 } else {
830                         DCAM_TRACE("DCAM: get clk_parent ok \n");
831                 }
832         } else {
833                 clk_disable(s_dcam_clk);
834         }
835
836         clk_parent = clk_get(NULL, parent);
837         if (IS_ERR(clk_parent)) {
838                 printk("DCAM: dcam_set_clk fail, %d \n", (int)clk_parent);
839                 return -1;
840         } else {
841                 DCAM_TRACE("DCAM: get clk_parent ok \n");
842         }
843
844         ret = clk_set_parent(s_dcam_clk, clk_parent);
845         if(ret){
846                 printk("DCAM: clk_set_parent fail, %d \n", ret);
847         }
848
849         ret = clk_enable(s_dcam_clk);
850         if (ret) {
851                 printk("enable dcam clk error.\n");
852                 return -1;
853         }
854         return rtn;
855 #endif
856 }
857
858 int32_t dcam_update_path(enum dcam_path_index path_index, struct dcam_size *in_size,
859                 struct dcam_rect *in_rect, struct dcam_size *out_size)
860 {
861         enum dcam_drv_rtn       rtn = DCAM_RTN_SUCCESS;
862         unsigned long           flags;
863         uint32_t                is_deci = 0;
864
865         DCAM_CHECK_ZERO(s_p_dcam_mod);
866         DCAM_CHECK_ZERO(s_dcam_sc_array);
867
868         if ((DCAM_PATH_IDX_1 & path_index) && s_p_dcam_mod->dcam_path1.valide) {
869                 rtn = dcam_path1_cfg(DCAM_PATH_INPUT_SIZE, in_size);
870                 DCAM_RTN_IF_ERR;
871                 rtn = dcam_path1_cfg(DCAM_PATH_INPUT_RECT, in_rect);
872                 DCAM_RTN_IF_ERR;
873                 rtn = dcam_path1_cfg(DCAM_PATH_OUTPUT_SIZE, out_size);
874                 DCAM_RTN_IF_ERR;
875                 rtn = _dcam_path_check_deci(DCAM_PATH_IDX_1, &is_deci);
876                 DCAM_RTN_IF_ERR;
877                 DCAM_TRACE("DCAM: To update path1 \n");
878                 rtn = _dcam_path_scaler(DCAM_PATH_IDX_1);
879                 DCAM_RTN_IF_ERR;
880                 DCAM_TRACE("DCAM: dcam_update_path 1 \n");
881                         if (s_dcam_sc_array->is_smooth_zoom) {
882                                 spin_lock_irqsave(&dcam_lock, flags);
883                                 s_p_dcam_mod->dcam_path1.is_update = 1;
884                                 spin_unlock_irqrestore(&dcam_lock, flags);
885                         } else {
886                                 _dcam_wait_update_done(DCAM_PATH_IDX_1, &s_p_dcam_mod->dcam_path1.is_update);
887                         }
888                 if (!s_dcam_sc_array->is_smooth_zoom) {
889                         _dcam_wait_update_done(DCAM_PATH_IDX_1, NULL);
890                 }
891         }
892
893         if ((DCAM_PATH_IDX_2 & path_index) && s_p_dcam_mod->dcam_path2.valide) {
894                 local_irq_save(flags);
895                 if(s_p_dcam_mod->dcam_path2.is_update){
896                         local_irq_restore(flags);
897                         DCAM_TRACE("DCAM: dcam_update_path 2:  updating return \n");
898                         return rtn;
899                 }
900                 local_irq_restore(flags);
901
902                 rtn = dcam_path2_cfg(DCAM_PATH_INPUT_SIZE, in_size);
903                 DCAM_RTN_IF_ERR;
904                 rtn = dcam_path2_cfg(DCAM_PATH_INPUT_RECT, in_rect);
905                 DCAM_RTN_IF_ERR;
906                 rtn = dcam_path2_cfg(DCAM_PATH_OUTPUT_SIZE, out_size);
907                 DCAM_RTN_IF_ERR;
908
909                 rtn = _dcam_path_scaler(DCAM_PATH_IDX_2);
910                 DCAM_RTN_IF_ERR;
911
912                 local_irq_save(flags);
913                 s_p_dcam_mod->dcam_path2.is_update = 1;
914                 local_irq_restore(flags);
915         }
916
917         DCAM_TRACE("DCAM: dcam_update_path: done \n");
918
919         return -rtn;
920 }
921
922 int32_t dcam_start_path(enum dcam_path_index path_index)
923 {
924         enum dcam_drv_rtn       rtn = DCAM_RTN_SUCCESS;
925         uint32_t                cap_en = 0;
926
927         DCAM_CHECK_ZERO(s_p_dcam_mod);
928
929         DCAM_TRACE("DCAM: start_path: path %d, mode %x path 0,1,2 {%d %d %d} \n",
930                 path_index,
931                 s_p_dcam_mod->dcam_mode,
932                 s_p_dcam_mod->dcam_path0.valide,
933                 s_p_dcam_mod->dcam_path1.valide,
934                 s_p_dcam_mod->dcam_path2.valide);
935
936         dcam_glb_reg_owr(DCAM_AHBM_STS, BIT_8, DCAM_AHBM_STS_REG); // aiden add: write arbit mode
937
938         cap_en = REG_RD(DCAM_CONTROL) & BIT_2;
939         DCAM_TRACE("DCAM: cap_eb %d \n", cap_en);
940         if ((DCAM_PATH_IDX_0 & path_index) && s_p_dcam_mod->dcam_path0.valide) {
941                 _dcam_path0_set();
942                 rtn = _dcam_path_set_next_frm(DCAM_PATH_IDX_0, true);
943                 DCAM_RTN_IF_ERR;
944                 if (cap_en) {
945                         /* if cap is already open, the sequence is:
946                            cap force copy -> path 0 enable -> cap auto copy */
947                         dcam_glb_reg_mwr(DCAM_CONTROL, BIT_0, 1 << 0, DCAM_CONTROL_REG); /* Cap force copy */
948                         dcam_glb_reg_owr(DCAM_CFG, BIT_0, DCAM_CFG_REG);             /* Enable Path 0 */
949                         dcam_glb_reg_mwr(DCAM_CONTROL, BIT_1, 1 << 1, DCAM_CONTROL_REG); /* Cap auto copy, trigger path 0 enable */
950                 } else {
951                         dcam_glb_reg_owr(DCAM_CFG, BIT_0, DCAM_CFG_REG);             /* Enable Path 0 */
952                 }
953         }
954
955         if ((DCAM_PATH_IDX_1 & path_index) && s_p_dcam_mod->dcam_path1.valide) {
956
957                 //rtn = _dcam_path_trim(DCAM_PATH_IDX_1);
958                 //DCAM_RTN_IF_ERR;
959                 rtn = _dcam_path_scaler(DCAM_PATH_IDX_1);
960                 DCAM_RTN_IF_ERR;
961
962                 _dcam_path1_set(&s_p_dcam_mod->dcam_path1);
963                 DCAM_TRACE("DCAM: start path: path_control=%x \n", REG_RD(DCAM_CONTROL));
964
965                 rtn = _dcam_path_set_next_frm(DCAM_PATH_IDX_1, true);
966                 DCAM_RTN_IF_ERR;
967                 _dcam_force_copy_ext(DCAM_PATH_IDX_1, true, true);
968                 DCAM_TRACE("DCAM: int= %x \n", REG_RD(DCAM_INT_STS));
969                 dcam_glb_reg_owr(DCAM_CFG, BIT_1, DCAM_CFG_REG);
970         }
971
972         if ((DCAM_PATH_IDX_2 & path_index) && s_p_dcam_mod->dcam_path2.valide) {
973                 rtn = _dcam_path_scaler(DCAM_PATH_IDX_2);
974                 DCAM_RTN_IF_ERR;
975
976                 _dcam_path2_set();
977
978                 rtn = _dcam_path_set_next_frm(DCAM_PATH_IDX_2, true);
979                 DCAM_RTN_IF_ERR;
980                 _dcam_force_copy_ext(DCAM_PATH_IDX_2, true, true);
981                 dcam_glb_reg_owr(DCAM_CFG, BIT_2, DCAM_CFG_REG);
982         }
983
984         printk("DCAM PATH S: %d \n", path_index);
985
986         if (0 == cap_en) {
987 #ifdef DCAM_DEBUG
988                 REG_MWR(CAP_CCIR_FRM_CTRL, BIT_5 | BIT_4, 1 << 4);
989                 REG_MWR(CAP_MIPI_FRM_CTRL, BIT_5 | BIT_4, 1 << 4);
990 #endif
991                 dcam_glb_reg_mwr(DCAM_CONTROL, BIT_0, 1 << 0, DCAM_CONTROL_REG); /* Cap force copy */
992                 //REG_MWR(DCAM_CONTROL, BIT_1, 1 << 1); /* Cap auto  copy */
993                 dcam_glb_reg_mwr(DCAM_CONTROL, BIT_2, 1 << 2, DCAM_CONTROL_REG); /* Cap Enable */
994         }
995         if ((DCAM_PATH_IDX_0 & path_index) && s_p_dcam_mod->dcam_path0.valide) {
996                 rtn = _dcam_path_set_next_frm(DCAM_PATH_IDX_0, false);
997                 DCAM_RTN_IF_ERR;
998                 _dcam_auto_copy(DCAM_PATH_IDX_0);
999                 s_p_dcam_mod->dcam_path0.status = DCAM_ST_START;
1000         }
1001
1002         _dcam_reg_trace();
1003         if ((DCAM_PATH_IDX_1 & path_index) && s_p_dcam_mod->dcam_path1.valide) {
1004                 s_p_dcam_mod->dcam_path1.need_wait = 0;
1005                 s_p_dcam_mod->dcam_path1.status = DCAM_ST_START;
1006         }
1007
1008         if ((DCAM_PATH_IDX_2 & path_index) && s_p_dcam_mod->dcam_path2.valide) {
1009                 s_p_dcam_mod->dcam_path2.need_wait = 0;
1010                 s_p_dcam_mod->dcam_path2.status = DCAM_ST_START;
1011         }
1012
1013         if (DCAM_PATH_IDX_ALL != path_index) {
1014                 if ((DCAM_PATH_IDX_0 & path_index)) {
1015                         _dcam_wait_path_done(DCAM_PATH_IDX_0, NULL);
1016                 } else if ((DCAM_PATH_IDX_1 & path_index)) {
1017                         _dcam_wait_path_done(DCAM_PATH_IDX_1, NULL);
1018                 } else if ((DCAM_PATH_IDX_2 & path_index)) {
1019                         _dcam_wait_path_done(DCAM_PATH_IDX_2, NULL);
1020                 }
1021         }
1022
1023         DCAM_TRACE("DCAM: start_path E\n");
1024         return -rtn;
1025 }
1026
1027 int32_t dcam_start(void)
1028 {
1029         enum dcam_drv_rtn       rtn = DCAM_RTN_SUCCESS;
1030         int                     ret = 0;
1031
1032         DCAM_CHECK_ZERO(s_p_dcam_mod);
1033
1034         DCAM_TRACE("DCAM: dcam_start %x \n", s_p_dcam_mod->dcam_mode);
1035
1036         ret = dcam_start_path(DCAM_PATH_IDX_ALL);
1037         //ret = dcam_start_path(DCAM_PATH_IDX_1);
1038
1039         return -rtn;
1040 }
1041
1042 int32_t dcam_stop_cap(void)
1043 {
1044         enum dcam_drv_rtn       rtn = DCAM_RTN_SUCCESS;
1045 #if 0
1046         DCAM_CHECK_ZERO(s_p_dcam_mod);
1047
1048         printk("DCAM: stop cap %d \n", s_p_dcam_mod->dcam_mode);
1049         dcam_glb_reg_mwr(DCAM_CONTROL, BIT_2, 0, DCAM_CONTROL_REG); /* Cap Enable */
1050         DCAM_TRACE("DCAM: stop cap, s_resize_flag %d \n", atomic_read(&s_resize_flag));
1051         if (atomic_read(&s_resize_flag)) {
1052                 s_p_dcam_mod->wait_resize_done = 1;
1053                 rtn = down_timeout(&s_p_dcam_mod->resize_done_sema, DCAM_PATH_TIMEOUT);
1054         }
1055         if (atomic_read(&s_rotation_flag)) {
1056                 s_p_dcam_mod->wait_rotation_done = 1;
1057                 rtn = down_timeout(&s_p_dcam_mod->rotation_done_sema, DCAM_PATH_TIMEOUT);
1058         }
1059
1060         dcam_reset(DCAM_RST_ALL, 0);
1061         DCAM_TRACE("DCAM: stop cap, Out \n");
1062 #endif
1063         return -rtn;
1064 }
1065
1066 int32_t _dcam_stop_path(enum dcam_path_index path_index)
1067 {
1068         enum dcam_drv_rtn       rtn = DCAM_RTN_SUCCESS;
1069         struct dcam_path_desc   *p_path = NULL;
1070         unsigned long           flag;
1071
1072         spin_lock_irqsave(&dcam_lock, flag);
1073
1074         if (DCAM_PATH_IDX_0 == path_index) {
1075                 p_path = &s_p_dcam_mod->dcam_path0;
1076         } else if(DCAM_PATH_IDX_1 == path_index) {
1077                 p_path = &s_p_dcam_mod->dcam_path1;
1078         } else if(DCAM_PATH_IDX_2 == path_index) {
1079                 p_path = &s_p_dcam_mod->dcam_path2;
1080         } else {
1081                 printk("DCAM: stop path Wrong index 0x%x \n", path_index);
1082                 spin_unlock_irqrestore(&dcam_lock, flag);
1083                 return -rtn;
1084         }
1085
1086         _dcam_wait_for_quickstop(path_index);
1087         p_path->status = DCAM_ST_STOP;
1088         p_path->valide = 0;
1089         _dcam_frm_clear(path_index);
1090
1091         spin_unlock_irqrestore(&dcam_lock, flag);
1092
1093         return rtn;
1094 }
1095
1096 int32_t dcam_stop_path(enum dcam_path_index path_index)
1097 {
1098         enum dcam_drv_rtn       rtn = DCAM_RTN_SUCCESS;
1099
1100         DCAM_CHECK_ZERO(s_p_dcam_mod);
1101
1102         printk("DCAM: stop_path 0x%x \n", path_index);
1103
1104         if (path_index < DCAM_PATH_IDX_0 ||
1105                 path_index >= DCAM_PATH_IDX_ALL) {
1106                 printk("DCAM: error path_index \n");
1107                 return -rtn;
1108         }
1109
1110         if ((DCAM_PATH_IDX_0 & path_index) && s_p_dcam_mod->dcam_path0.valide) {
1111                 _dcam_wait_path_done(DCAM_PATH_IDX_0, &s_p_dcam_mod->dcam_path0.need_stop);
1112                 _dcam_stop_path(DCAM_PATH_IDX_0);
1113         }
1114
1115         if ((DCAM_PATH_IDX_1 & path_index) && s_p_dcam_mod->dcam_path1.valide) {
1116                 _dcam_wait_path_done(DCAM_PATH_IDX_1, &s_p_dcam_mod->dcam_path1.need_stop);
1117                 _dcam_stop_path(DCAM_PATH_IDX_1);
1118         }
1119
1120         if ((DCAM_PATH_IDX_2 & path_index) && s_p_dcam_mod->dcam_path2.valide) {
1121                 DCAM_TRACE("DCAM: stop path2 In \n");
1122                 _dcam_wait_path_done(DCAM_PATH_IDX_2, &s_p_dcam_mod->dcam_path2.need_stop);
1123                 _dcam_stop_path(DCAM_PATH_IDX_2);
1124         }
1125
1126         DCAM_TRACE("DCAM dcam_stop_path E: %d \n", path_index);
1127
1128         return -rtn;
1129 }
1130
1131 LOCAL void    _dcam_wait_for_channel_stop(enum dcam_path_index path_index)
1132 {
1133         int                     time_out = 5000;
1134         uint32_t                ret = 0;
1135
1136         DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
1137
1138         /* wait for AHB path busy cleared */
1139         while (time_out) {
1140                 if (s_p_dcam_mod->dcam_path1.valide && (DCAM_PATH_IDX_1 & path_index)) {
1141                         ret = REG_RD(DCAM_AHBM_STS) & BIT_17;
1142                 } else if (s_p_dcam_mod->dcam_path2.valide && (DCAM_PATH_IDX_2 & path_index)) {
1143                         ret = REG_RD(DCAM_AHBM_STS) & BIT_18;
1144                 } else {
1145                         /*nothing*/
1146                 }
1147                 if (!ret) {
1148                         break;
1149                 }
1150                 time_out --;
1151         }
1152
1153         DCAM_TRACE("DCAM: wait channel stop %d %d \n", ret, time_out);
1154
1155         return;
1156 }
1157
1158 LOCAL void    _dcam_quickstop_set(enum dcam_path_index path_index, uint32_t path_rst, uint32_t path_bit,
1159         uint32_t cfg_bit, uint32_t ahbm_bit, uint32_t auto_copy_bit)
1160 {
1161         dcam_glb_reg_owr(DCAM_AHBM_STS, ahbm_bit, DCAM_AHBM_STS_REG);
1162         udelay(10);
1163         dcam_glb_reg_mwr(DCAM_CFG, cfg_bit, ~cfg_bit, DCAM_CFG_REG);
1164         _dcam_force_copy(path_index);
1165         _dcam_wait_for_channel_stop(path_index);
1166         dcam_glb_reg_awr(DCAM_AHBM_STS, ~ahbm_bit, DCAM_AHBM_STS_REG);
1167         dcam_reset(path_rst, 0);
1168
1169         return;
1170 }
1171
1172 #define DCAM_IRQ_MASK_PATH0                            (0x0f|(0x03<<4)|(1<<12)|(1<<21))  //let other module continue
1173 #define DCAM_IRQ_MASK_PATH1                            (0x0f|(0x03<<6)|(1<<16)|(1<<19)|(1<<22))
1174 #define DCAM_IRQ_MASK_PATH2                            (0x0f|(0x03<<8)|(1<<17)|(1<<20)|(1<<23))
1175
1176 LOCAL void    _dcam_quickstop_set_all(enum dcam_path_index path_index, uint32_t path_bit, uint32_t cfg_bit, uint32_t ahbm_bit)
1177 {
1178         dcam_glb_reg_owr(DCAM_AHBM_STS, BIT_3 | BIT_4 | BIT_5, DCAM_AHBM_STS_REG);
1179         udelay(10);
1180         dcam_glb_reg_awr(DCAM_CFG, ~(BIT_0 | BIT_1 | BIT_2), DCAM_CFG_REG);
1181         dcam_glb_reg_owr(DCAM_CONTROL, BIT_10 | BIT_12, DCAM_CONTROL_REG);
1182         dcam_glb_reg_awr(DCAM_CONTROL, ~(BIT_10 | BIT_12), DCAM_CONTROL_REG);
1183         _dcam_wait_for_channel_stop(DCAM_PATH_IDX_1);
1184         _dcam_wait_for_channel_stop(DCAM_PATH_IDX_2);
1185
1186         return;
1187 }
1188
1189 LOCAL void    _dcam_wait_for_quickstop(enum dcam_path_index path_index)
1190 {
1191         int                     time_out = 5000;
1192
1193         DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
1194
1195         DCAM_TRACE("DCAM: state  before stop   0x%x\n", s_p_dcam_mod->state);
1196
1197         if (DCAM_PATH_IDX_ALL == path_index) {
1198                 _dcam_quickstop_set_all(0, 0, 0, 0);
1199         } else {
1200                 if (s_p_dcam_mod->dcam_path0.valide && (DCAM_PATH_IDX_0 & path_index)) {
1201                         _dcam_quickstop_set(DCAM_PATH_IDX_0, DCAM_RST_PATH0, DCAM_IRQ_MASK_PATH0, BIT_0, BIT_3, BIT_9);
1202                 }
1203                 if (s_p_dcam_mod->dcam_path1.valide && (DCAM_PATH_IDX_1 & path_index)) {
1204                         _dcam_quickstop_set(DCAM_PATH_IDX_1, DCAM_RST_PATH1, DCAM_IRQ_MASK_PATH1, BIT_1, BIT_4, BIT_11);
1205                 }
1206                 if (s_p_dcam_mod->dcam_path2.valide && (DCAM_PATH_IDX_2 & path_index)) {
1207                         _dcam_quickstop_set(DCAM_PATH_IDX_2, DCAM_RST_PATH2, DCAM_IRQ_MASK_PATH2, BIT_2, BIT_5, BIT_13);
1208                 }
1209         }
1210
1211         DCAM_TRACE("DCAM: exit _dcam_wait_for_quickstop %d state: 0x%x \n ", time_out, s_p_dcam_mod->state);
1212
1213         return;
1214 }
1215
1216 int32_t dcam_stop(void)
1217 {
1218         enum dcam_drv_rtn       rtn = DCAM_RTN_SUCCESS;
1219         unsigned long           flag;
1220
1221         DCAM_CHECK_ZERO(s_p_dcam_mod);
1222
1223         s_p_dcam_mod->state |= DCAM_STATE_QUICKQUIT;
1224         printk("DCAM dcam_stop In \n");
1225         if (atomic_read(&s_resize_flag)) {
1226                 s_p_dcam_mod->wait_resize_done = 1;
1227                 rtn = down_timeout(&s_p_dcam_mod->resize_done_sema, DCAM_PATH_TIMEOUT);
1228         }
1229         if (atomic_read(&s_rotation_flag)) {
1230                 s_p_dcam_mod->wait_rotation_done = 1;
1231                 rtn = down_timeout(&s_p_dcam_mod->rotation_done_sema, DCAM_PATH_TIMEOUT);
1232         }
1233
1234         mutex_lock(&dcam_sem);
1235         printk("DCAM dcam_stop get  dcam_sem\n");
1236         spin_lock_irqsave(&dcam_lock, flag);
1237
1238         dcam_glb_reg_owr(DCAM_INT_MASK,
1239                                                 DCAM_IRQ_LINE_MASK,
1240                                                 DCAM_INIT_MASK_REG);
1241
1242         _dcam_wait_for_quickstop(DCAM_PATH_IDX_ALL);
1243         s_p_dcam_mod->dcam_path0.status = DCAM_ST_STOP;
1244         s_p_dcam_mod->dcam_path0.valide = 0;
1245         s_p_dcam_mod->dcam_path1.status = DCAM_ST_STOP;
1246         s_p_dcam_mod->dcam_path1.valide = 0;
1247         s_p_dcam_mod->dcam_path2.status = DCAM_ST_STOP;
1248         s_p_dcam_mod->dcam_path2.valide = 0;
1249         _dcam_frm_clear(DCAM_PATH_IDX_0);
1250         _dcam_frm_clear(DCAM_PATH_IDX_1);
1251         _dcam_frm_clear(DCAM_PATH_IDX_2);
1252         spin_unlock_irqrestore(&dcam_lock, flag);
1253
1254         dcam_reset(DCAM_RST_ALL, 0);
1255         s_p_dcam_mod->state &= ~DCAM_STATE_QUICKQUIT;
1256         mutex_unlock(&dcam_sem);
1257
1258         printk("DCAM: dcam_stop Out, s_resize_flag %d \n", atomic_read(&s_resize_flag));
1259
1260         return -rtn;
1261 }
1262
1263 int32_t dcam_resume(void)
1264 {
1265         enum dcam_drv_rtn       rtn = DCAM_RTN_SUCCESS;
1266
1267         DCAM_CHECK_ZERO(s_p_dcam_mod);
1268
1269         if (s_p_dcam_mod->dcam_path1.valide) {
1270                 rtn = _dcam_path_set_next_frm(DCAM_PATH_IDX_1, true);
1271                 DCAM_RTN_IF_ERR;
1272                 _dcam_force_copy(DCAM_PATH_IDX_1);
1273                 _dcam_frm_clear(DCAM_PATH_IDX_1);
1274         }
1275
1276         if (s_p_dcam_mod->dcam_path2.valide) {
1277                 rtn = _dcam_path_set_next_frm(DCAM_PATH_IDX_2, true);
1278                 DCAM_RTN_IF_ERR;
1279                 _dcam_force_copy(DCAM_PATH_IDX_2);
1280                 _dcam_frm_clear(DCAM_PATH_IDX_2);
1281         }
1282
1283
1284         if (s_p_dcam_mod->dcam_path1.valide) {
1285                 rtn = _dcam_path_set_next_frm(DCAM_PATH_IDX_1, false);
1286                 DCAM_RTN_IF_ERR;
1287                 dcam_glb_reg_owr(DCAM_CFG, BIT_1, DCAM_CFG_REG);
1288                 _dcam_auto_copy_ext(DCAM_PATH_IDX_1, true, true);
1289         }
1290
1291         if (s_p_dcam_mod->dcam_path2.valide) {
1292                 rtn = _dcam_path_set_next_frm(DCAM_PATH_IDX_2, false);
1293                 DCAM_RTN_IF_ERR;
1294                 dcam_glb_reg_owr(DCAM_CFG, BIT_2, DCAM_CFG_REG);
1295                 _dcam_auto_copy_ext(DCAM_PATH_IDX_2, true, true);
1296         }
1297
1298         printk("DCAM R \n");
1299
1300         dcam_glb_reg_owr(DCAM_CONTROL, BIT_2, DCAM_CONTROL_REG); /* Enable CAP */
1301         return -rtn;
1302 }
1303
1304 int32_t dcam_pause(void)
1305 {
1306         enum dcam_drv_rtn       rtn = DCAM_RTN_SUCCESS;
1307
1308         dcam_glb_reg_awr(DCAM_CONTROL, ~BIT_2, DCAM_CONTROL_REG); /* Disable CAP */
1309         printk("DCAM P \n");
1310         return -rtn;
1311 }
1312
1313 int32_t dcam_reg_isr(enum dcam_irq_id id, dcam_isr_func user_func, void* user_data)
1314 {
1315         enum dcam_drv_rtn       rtn = DCAM_RTN_SUCCESS;
1316         unsigned long           flag;
1317
1318         if(id >= DCAM_IRQ_NUMBER) {
1319                 rtn = DCAM_RTN_ISR_ID_ERR;
1320         } else {
1321                 spin_lock_irqsave(&dcam_lock, flag);
1322                 s_user_func[id] = user_func;
1323                 s_user_data[id] = user_data;
1324                 spin_unlock_irqrestore(&dcam_lock, flag);
1325         }
1326         return -rtn;
1327 }
1328
1329 int32_t dcam_cap_cfg(enum dcam_cfg_id id, void *param)
1330 {
1331         enum dcam_drv_rtn       rtn = DCAM_RTN_SUCCESS;
1332         struct dcam_cap_desc    *cap_desc = NULL;
1333
1334         DCAM_CHECK_ZERO(s_p_dcam_mod);
1335         DCAM_CHECK_ZERO(s_dcam_sc_array);
1336         cap_desc = &s_p_dcam_mod->dcam_cap;
1337         switch (id) {
1338         case DCAM_CAP_SYNC_POL:
1339         {
1340                 struct dcam_cap_sync_pol *sync_pol = (struct dcam_cap_sync_pol*)param;
1341
1342                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1343
1344                 if (DCAM_CAP_IF_CCIR == cap_desc->interface) {
1345
1346                         if (sync_pol->vsync_pol > 1 ||
1347                             sync_pol->hsync_pol > 1 ||
1348                             sync_pol->pclk_pol > 1) {
1349                                 rtn = DCAM_RTN_CAP_SYNC_POL_ERR;
1350                         } else {
1351                                 sci_glb_set(DCAM_CCIR_PCLK_EB, CCIR_PCLK_EB_BIT);
1352                                 REG_MWR(CAP_CCIR_CTRL, BIT_3, sync_pol->hsync_pol << 3);
1353                                 REG_MWR(CAP_CCIR_CTRL, BIT_4, sync_pol->vsync_pol << 4);
1354                                 //REG_MWR(CLK_DLY_CTRL,  BIT_19, sync_pol->pclk_pol << 19); // aiden todo
1355
1356                                 if (sync_pol->pclk_src == 0x00) {
1357                                         sci_glb_clr(CAP_CCIR_PLCK_SRC, (BIT_25 | BIT_26));
1358                                         DCAM_TRACE("DCAM: set pclk src0\n");
1359                                 } else if (sync_pol->pclk_src == 0x01) {
1360                                         sci_glb_clr(CAP_CCIR_PLCK_SRC, (BIT_25 | BIT_26));
1361                                         sci_glb_set(CAP_CCIR_PLCK_SRC, (BIT_25));
1362                                         DCAM_TRACE("DCAM: set pclk src1\n");
1363                                 } else {
1364                                         DCAM_TRACE("DCAM: set pclk src default\n");
1365                                 }
1366                         }
1367                 } else {
1368                         if (sync_pol->need_href) {
1369                                 REG_MWR(CAP_MIPI_CTRL, BIT_5, 1 << 5);
1370                         } else {
1371                                 REG_MWR(CAP_MIPI_CTRL, BIT_5, 0 << 5);
1372                         }
1373                 }
1374                 break;
1375         }
1376
1377         case DCAM_CAP_DATA_BITS:
1378         {
1379                 enum dcam_cap_data_bits bits = *(enum dcam_cap_data_bits*)param;
1380
1381                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1382
1383                 if (DCAM_CAP_IF_CCIR == cap_desc->interface) {
1384                         if (DCAM_CAP_8_BITS == bits || DCAM_CAP_10_BITS == bits) {
1385                                 REG_MWR(CAP_CCIR_CTRL,  BIT_10 | BIT_9, 0 << 9);
1386                         } else if (DCAM_CAP_4_BITS == bits) {
1387                                 REG_MWR(CAP_CCIR_CTRL,  BIT_10 | BIT_9, 1 << 9);
1388                         } else if (DCAM_CAP_2_BITS == bits) {
1389                                 REG_MWR(CAP_CCIR_CTRL,  BIT_10 | BIT_9, 2 << 9);
1390                         } else if (DCAM_CAP_1_BITS == bits) {
1391                                 REG_MWR(CAP_CCIR_CTRL,  BIT_10 | BIT_9, 3 << 9);
1392                         } else {
1393                                 rtn = DCAM_RTN_CAP_IN_BITS_ERR;
1394                         }
1395
1396                 } else {
1397                         if (DCAM_CAP_12_BITS == bits) {
1398                                 REG_MWR(CAP_MIPI_CTRL,  BIT_4 | BIT_3, 2 << 3);
1399                         } else if (DCAM_CAP_10_BITS == bits) {
1400                                 REG_MWR(CAP_MIPI_CTRL,  BIT_4 | BIT_3, 1 << 3);
1401                         } else if (DCAM_CAP_8_BITS == bits) {
1402                                 REG_MWR(CAP_MIPI_CTRL,  BIT_4 | BIT_3, 0 << 3);
1403                         } else {
1404                                 rtn = DCAM_RTN_CAP_IN_BITS_ERR;
1405                         }
1406                 }
1407                 break;
1408         }
1409
1410         case DCAM_CAP_YUV_TYPE:
1411         {
1412                 enum dcam_cap_pattern pat = *(enum dcam_cap_pattern*)param;
1413
1414                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1415
1416                 if (pat < DCAM_PATTERN_MAX) {
1417                         if (DCAM_CAP_IF_CCIR == cap_desc->interface)
1418                                 REG_MWR(CAP_CCIR_CTRL, BIT_8 | BIT_7, pat << 7);
1419                         else
1420                                 REG_MWR(CAP_MIPI_CTRL, BIT_8 | BIT_7, pat << 7);
1421                 } else {
1422                         rtn = DCAM_RTN_CAP_IN_YUV_ERR;
1423                 }
1424                 break;
1425         }
1426
1427         case DCAM_CAP_PRE_SKIP_CNT:
1428         {
1429                 uint32_t skip_num = *(uint32_t*)param;
1430
1431                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1432
1433                 if (skip_num > DCAM_CAP_SKIP_FRM_MAX) {
1434                         rtn = DCAM_RTN_CAP_SKIP_FRAME_ERR;
1435                 } else {
1436                         if (DCAM_CAP_IF_CCIR == cap_desc->interface)
1437                                 REG_MWR(CAP_CCIR_FRM_CTRL, BIT_3 | BIT_2 | BIT_1 | BIT_0, skip_num);
1438                         else
1439                                 REG_MWR(CAP_MIPI_FRM_CTRL, BIT_3 | BIT_2 | BIT_1 | BIT_0, skip_num);
1440                 }
1441                 break;
1442         }
1443
1444         case DCAM_CAP_FRM_DECI:
1445         {
1446                 uint32_t deci_factor = *(uint32_t*)param;
1447
1448                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1449
1450                 if (deci_factor < DCAM_FRM_DECI_FAC_MAX) {
1451                         if (DCAM_CAP_IF_CCIR == cap_desc->interface)
1452                                 REG_MWR(CAP_CCIR_FRM_CTRL, BIT_5 | BIT_4, deci_factor << 4);
1453                         else
1454                                 REG_MWR(CAP_MIPI_FRM_CTRL, BIT_5 | BIT_4, deci_factor << 4);
1455                 } else {
1456                         rtn = DCAM_RTN_CAP_FRAME_DECI_ERR;
1457                 }
1458                 break;
1459         }
1460
1461         case DCAM_CAP_FRM_COUNT_CLR:
1462                 if (DCAM_CAP_IF_CCIR == cap_desc->interface)
1463                         REG_MWR(CAP_CCIR_FRM_CTRL, BIT_22, 1 << 22);
1464                 else
1465                         REG_MWR(CAP_MIPI_FRM_CTRL, BIT_22, 1 << 22);
1466                 break;
1467
1468         case DCAM_CAP_INPUT_RECT:
1469         {
1470                 struct dcam_rect *rect = (struct dcam_rect*)param;
1471                 uint32_t         tmp = 0;
1472
1473                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1474 #if 0
1475                 if (rect->x > DCAM_CAP_FRAME_WIDTH_MAX ||
1476                 rect->y > DCAM_CAP_FRAME_HEIGHT_MAX ||
1477                 rect->w > DCAM_CAP_FRAME_WIDTH_MAX ||
1478                 rect->h > DCAM_CAP_FRAME_HEIGHT_MAX ) {
1479                         rtn = DCAM_RTN_CAP_FRAME_SIZE_ERR;
1480                         return -rtn;
1481                 }
1482 #endif
1483
1484                 if (DCAM_CAP_IF_CCIR == cap_desc->interface) {
1485                         if (DCAM_CAP_MODE_RAWRGB == cap_desc->input_format) {
1486                                 tmp = rect->x | (rect->y << 16);
1487                                 REG_WR(CAP_CCIR_START, tmp);
1488                                 tmp = (rect->x + rect->w - 1);
1489                                 tmp |= (rect->y + rect->h - 1) << 16;
1490                                 REG_WR(CAP_CCIR_END, tmp);
1491                         } else {
1492                                 tmp = (rect->x << 1) | (rect->y << 16);
1493                                 REG_WR(CAP_CCIR_START, tmp);
1494                                 tmp = ((rect->x + rect->w) << 1) - 1;
1495                                 tmp |= (rect->y + rect->h - 1) << 16;
1496                                 REG_WR(CAP_CCIR_END, tmp);
1497                         }
1498                 } else {
1499                         tmp = rect->x | (rect->y << 16);
1500                         REG_WR(CAP_MIPI_START, tmp);
1501                         tmp = (rect->x + rect->w - 1);
1502                         tmp |= (rect->y + rect->h - 1) << 16;
1503                         REG_WR(CAP_MIPI_END, tmp);
1504                 }
1505                 break;
1506         }
1507
1508         case DCAM_CAP_IMAGE_XY_DECI:
1509         {
1510                 struct dcam_cap_dec *cap_dec = (struct dcam_cap_dec*)param;
1511
1512                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1513
1514                 if (cap_dec->x_factor > DCAM_CAP_X_DECI_FAC_MAX ||
1515                 cap_dec->y_factor > DCAM_CAP_Y_DECI_FAC_MAX ) {
1516                         rtn = DCAM_RTN_CAP_XY_DECI_ERR;
1517                 } else {
1518                         if (DCAM_CAP_MODE_RAWRGB == cap_desc->input_format) {
1519                                 if (cap_dec->x_factor > 1 ||
1520                                     cap_dec->y_factor > 1) {
1521                                         rtn = DCAM_RTN_CAP_XY_DECI_ERR;
1522                                 }
1523                         }
1524                         if (DCAM_CAP_IF_CCIR == cap_desc->interface) {
1525                                 REG_MWR(CAP_CCIR_IMG_DECI, BIT_1 | BIT_0, cap_dec->x_factor);
1526                                 REG_MWR(CAP_CCIR_IMG_DECI, BIT_3 | BIT_2, cap_dec->y_factor << 2);
1527                         } else {
1528                                 if (DCAM_CAP_MODE_RAWRGB == cap_desc->input_format) {
1529                                         // REG_MWR(CAP_MIPI_IMG_DECI, BIT_0, cap_dec->x_factor); // for camera path
1530                                         REG_MWR(CAP_MIPI_IMG_DECI, BIT_1, cap_dec->x_factor << 1);//for ISP
1531                                 } else {
1532                                         REG_MWR(CAP_MIPI_IMG_DECI, BIT_1 | BIT_0, cap_dec->x_factor);
1533                                         REG_MWR(CAP_MIPI_IMG_DECI, BIT_3 | BIT_2, cap_dec->y_factor << 2);
1534                                 }
1535                         }
1536                 }
1537
1538                 break;
1539         }
1540
1541         case DCAM_CAP_JPEG_SET_BUF_LEN:
1542         {
1543                 uint32_t jpg_buf_size = *(uint32_t*)param;
1544
1545                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1546                 jpg_buf_size = jpg_buf_size/DCAM_JPG_BUF_UNIT;
1547                 if (jpg_buf_size >= DCAM_JPG_UNITS) {
1548                         rtn = DCAM_RTN_CAP_JPEG_BUF_LEN_ERR;
1549                 } else {
1550                         if (DCAM_CAP_IF_CCIR == cap_desc->interface)
1551                                 REG_WR(CAP_CCIR_JPG_CTRL,jpg_buf_size);
1552                         else
1553                                 REG_WR(CAP_MIPI_JPG_CTRL,jpg_buf_size);
1554                 }
1555                 break;
1556         }
1557
1558         case DCAM_CAP_TO_ISP:
1559         {
1560                 uint32_t need_isp = *(uint32_t*)param;
1561
1562                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1563
1564                 if (need_isp) {
1565                         dcam_glb_reg_mwr(DCAM_CFG, BIT_7, 1 << 7, DCAM_CFG_REG);
1566                 } else {
1567                         dcam_glb_reg_mwr(DCAM_CFG, BIT_7, 0 << 7, DCAM_CFG_REG);
1568                 }
1569                 break;
1570         }
1571
1572         case DCAM_CAP_DATA_PACKET:
1573         {
1574                 uint32_t is_loose = *(uint32_t*)param;
1575
1576                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1577
1578                 if (DCAM_CAP_IF_CSI2 == cap_desc->interface &&
1579                         DCAM_CAP_MODE_RAWRGB == cap_desc->input_format) {
1580                         if (is_loose) {
1581                                 REG_MWR(CAP_MIPI_CTRL, BIT_0, 1);
1582                         } else {
1583                                 REG_MWR(CAP_MIPI_CTRL, BIT_0, 0);
1584                         }
1585                 } else {
1586                         rtn = DCAM_RTN_MODE_ERR;
1587                 }
1588
1589                 break;
1590         }
1591
1592         case DCAM_CAP_SAMPLE_MODE:
1593         {
1594                 enum dcam_capture_mode samp_mode = *(enum dcam_capture_mode*)param;
1595
1596                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1597
1598                 if (samp_mode >= DCAM_CAPTURE_MODE_MAX) {
1599                         rtn = DCAM_RTN_MODE_ERR;
1600                 } else {
1601                         if (DCAM_CAP_IF_CSI2 == cap_desc->interface) {
1602                                 REG_MWR(CAP_MIPI_CTRL, BIT_6, samp_mode << 6);
1603                         } else {
1604                                 REG_MWR(CAP_CCIR_CTRL, BIT_6, samp_mode << 6);
1605                         }
1606                         s_p_dcam_mod->dcam_mode = samp_mode;
1607                 }
1608                 break;
1609         }
1610
1611         case DCAM_CAP_ZOOM_MODE:
1612         {
1613                 uint32_t zoom_mode = *(uint32_t*)param;
1614
1615                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1616
1617                 s_dcam_sc_array->is_smooth_zoom = zoom_mode;
1618                 break;
1619         }
1620         default:
1621                 rtn = DCAM_RTN_IO_ID_ERR;
1622                 break;
1623
1624         }
1625
1626         return -rtn;
1627 }
1628
1629 int32_t dcam_cap_get_info(enum dcam_cfg_id id, void *param)
1630 {
1631         enum dcam_drv_rtn       rtn = DCAM_RTN_SUCCESS;
1632         struct dcam_cap_desc    *cap_desc = NULL;
1633
1634         DCAM_CHECK_ZERO(s_p_dcam_mod);
1635
1636         cap_desc = &s_p_dcam_mod->dcam_cap;
1637         DCAM_CHECK_PARAM_ZERO_POINTER(param);
1638
1639         switch(id) {
1640                 case DCAM_CAP_FRM_COUNT_GET:
1641                         if (DCAM_CAP_IF_CSI2 == cap_desc->interface) {
1642                                 *(uint32_t*)param = REG_RD(CAP_MIPI_FRM_CTRL) >> 16;
1643                         } else {
1644                                 *(uint32_t*)param = REG_RD(CAP_CCIR_FRM_CTRL) >> 16;
1645                         }
1646                         break;
1647
1648                 case DCAM_CAP_JPEG_GET_LENGTH:
1649                         if (DCAM_CAP_IF_CSI2 == cap_desc->interface) {
1650                                 *(uint32_t*)param = REG_RD(CAP_MIPI_FRM_SIZE);
1651                         } else {
1652                                 *(uint32_t*)param = REG_RD(CAP_CCIR_FRM_SIZE);
1653                         }
1654                         break;
1655                 default:
1656                         rtn = DCAM_RTN_IO_ID_ERR;
1657                         break;
1658         }
1659         return -rtn;
1660 }
1661
1662 int32_t dcam_path0_cfg(enum dcam_cfg_id id, void *param)
1663 {
1664         enum dcam_drv_rtn       rtn = DCAM_RTN_SUCCESS;
1665         struct dcam_path_desc   *path = NULL;
1666
1667         DCAM_CHECK_ZERO(s_p_dcam_mod);
1668         path = &s_p_dcam_mod->dcam_path0;
1669         switch (id) {
1670
1671         case DCAM_PATH_INPUT_SIZE:
1672         {
1673                 struct dcam_size *size = (struct dcam_size*)param;
1674
1675                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1676
1677                 DCAM_TRACE("DCAM: DCAM_PATH0_INPUT_SIZE {%d %d} \n", size->w, size->h);
1678 #if 0
1679                 if (size->w > DCAM_PATH_FRAME_WIDTH_MAX ||
1680                 size->h > DCAM_PATH_FRAME_HEIGHT_MAX) {
1681                         rtn = DCAM_RTN_PATH_SRC_SIZE_ERR;
1682                 } else
1683 #endif
1684                  {
1685                         path->input_size.w = size->w;
1686                         path->input_size.h = size->h;
1687                         path->valid_param.input_size = 1;
1688                 }
1689                 break;
1690         }
1691
1692         case DCAM_PATH_OUTPUT_FORMAT:
1693         {
1694                 enum dcam_output_mode format = *(enum dcam_output_mode*)param;
1695
1696                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1697
1698                 if((DCAM_OUTPUT_WORD != format) &&
1699                 (DCAM_OUTPUT_HALF_WORD != format)){
1700                         rtn = DCAM_RTN_PATH_OUT_FMT_ERR;
1701                         path->output_format = DCAM_FTM_MAX;
1702                 }else{
1703                         path->output_format = format;
1704                         path->valid_param.output_format = 1;
1705                 }
1706                 break;
1707         }
1708
1709         case DCAM_PATH_FRAME_BASE_ID:
1710         {
1711                 uint32_t          base_id = *(uint32_t*)param, i;
1712
1713                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1714
1715                 DCAM_TRACE("DCAM: DCAM_PATH_FRAME_BASE_ID 0x%x \n", base_id);
1716                 s_p_dcam_mod->dcam_path0.frame_base_id = base_id;
1717                 break;
1718         }
1719
1720         case DCAM_PATH_FRAME_TYPE:
1721         {
1722                 struct dcam_frame *frame  = &s_p_dcam_mod->dcam_path0.buf_queue.frame[0];
1723                 uint32_t          frm_type = *(uint32_t*)param, i;
1724
1725                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1726
1727                 DCAM_TRACE("DCAM: DCAM_PATH_FRAME_TYPE 0x%x \n", frm_type);
1728                 for (i = 0; i < DCAM_PATH_0_FRM_CNT_MAX; i++) {
1729                         (frame+i)->type = frm_type;
1730                 }
1731                 break;
1732         }
1733
1734         case DCAM_PATH_OUTPUT_ADDR:
1735         {
1736                 struct dcam_addr *p_addr = (struct dcam_addr*)param;
1737
1738                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1739                 if (DCAM_YUV_ADDR_INVALID(p_addr->yaddr, p_addr->uaddr, p_addr->vaddr)) {
1740                         rtn = DCAM_RTN_PATH_ADDR_ERR;
1741                 } else {
1742                         struct dcam_frame frame;
1743                         memset((void*)&frame, 0, sizeof(struct dcam_frame));
1744                         frame.yaddr = p_addr->yaddr;
1745                         frame.uaddr = p_addr->uaddr;
1746                         frame.vaddr = p_addr->vaddr;
1747                         frame.yaddr_vir = p_addr->yaddr_vir;
1748                         frame.uaddr_vir = p_addr->uaddr_vir;
1749                         frame.vaddr_vir = p_addr->vaddr_vir;
1750                         frame.type  = DCAM_PATH0;
1751                         frame.fid   = s_p_dcam_mod->dcam_path0.frame_base_id;
1752                         DCAM_TRACE("DCAM: Path 0 DCAM_PATH_OUTPUT_ADDR, i=%d, y=0x%x, u=0x%x, v=0x%x \n",
1753                                 path->output_frame_count, p_addr->yaddr, p_addr->uaddr, p_addr->vaddr);
1754                         _dcam_buf_queue_write(&s_p_dcam_mod->dcam_path0.buf_queue, &frame);
1755                 }
1756                 break;
1757         }
1758
1759         case DCAM_PATH_OUTPUT_RESERVED_ADDR:
1760         {
1761                 struct dcam_addr *p_addr = (struct dcam_addr*)param;
1762
1763                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1764
1765                 if (DCAM_YUV_ADDR_INVALID(p_addr->yaddr, p_addr->uaddr, p_addr->vaddr)) {
1766                         rtn = DCAM_RTN_PATH_ADDR_ERR;
1767                 } else {
1768                         struct dcam_frame *frame  = &s_p_dcam_mod->path0_reserved_frame;
1769                         frame->yaddr = p_addr->yaddr;
1770                         frame->uaddr = p_addr->uaddr;
1771                         frame->vaddr = p_addr->vaddr;
1772                         frame->yaddr_vir = p_addr->yaddr_vir;
1773                         frame->uaddr_vir = p_addr->uaddr_vir;
1774                         frame->vaddr_vir = p_addr->vaddr_vir;
1775
1776                         DCAM_TRACE("DCAM: Path 1 DCAM_PATH_OUTPUT_RESERVED_ADDR, i=%d, y=0x%x, u=0x%x, v=0x%x \n",
1777                                 path->output_frame_count, p_addr->yaddr, p_addr->uaddr, p_addr->vaddr);
1778                 }
1779                 break;
1780         }
1781
1782         case DCAM_PATH_FRM_DECI:
1783         {
1784                 uint32_t deci_factor = *(uint32_t*)param;
1785
1786                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1787
1788                 if (deci_factor >= DCAM_FRM_DECI_FAC_MAX) {
1789                         rtn = DCAM_RTN_PATH_FRM_DECI_ERR;
1790                 } else {
1791                         path->frame_deci = deci_factor;
1792                         path->valid_param.frame_deci = 1;
1793                 }
1794                 break;
1795         }
1796
1797         case DCAM_PATH_DATA_ENDIAN:
1798         {
1799                 struct dcam_endian_sel *endian = (struct dcam_endian_sel*)param;
1800
1801                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1802
1803                 if (endian->y_endian >= DCAM_ENDIAN_MAX ||
1804                         endian->uv_endian >= DCAM_ENDIAN_MAX) {
1805                         rtn = DCAM_RTN_PATH_ENDIAN_ERR;
1806                 } else {
1807                         path->data_endian.y_endian      = endian->y_endian;
1808                         path->valid_param.data_endian = 1;
1809                 }
1810                 break;
1811         }
1812
1813
1814         case DCAM_PATH_ENABLE:
1815         {
1816                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1817                 path->valide = *(uint32_t*)param;
1818                 break;
1819         }
1820
1821         default:
1822                 rtn = DCAM_RTN_IO_ID_ERR;
1823                 break;
1824         }
1825
1826         return -rtn;
1827 }
1828
1829 int32_t dcam_path1_cfg(enum dcam_cfg_id id, void *param)
1830 {
1831         enum dcam_drv_rtn       rtn = DCAM_RTN_SUCCESS;
1832         struct dcam_path_desc   *path = NULL;
1833
1834         DCAM_CHECK_ZERO(s_p_dcam_mod);
1835         path = &s_p_dcam_mod->dcam_path1;
1836         switch (id) {
1837
1838         case DCAM_PATH_INPUT_SIZE:
1839         {
1840                 struct dcam_size *size = (struct dcam_size*)param;
1841
1842                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1843
1844                 DCAM_TRACE("DCAM: DCAM_PATH1_INPUT_SIZE {%d %d} \n", size->w, size->h);
1845                 if (size->w > DCAM_PATH_FRAME_WIDTH_MAX ||
1846                 size->h > DCAM_PATH_FRAME_HEIGHT_MAX) {
1847                         rtn = DCAM_RTN_PATH_SRC_SIZE_ERR;
1848                 } else {
1849                         path->input_size.w = size->w;
1850                         path->input_size.h = size->h;
1851                         path->valid_param.input_size = 1;
1852                 }
1853                 break;
1854         }
1855
1856         case DCAM_PATH_INPUT_RECT:
1857         {
1858                 struct dcam_rect *rect = (struct dcam_rect*)param;
1859
1860                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1861
1862                 DCAM_TRACE("DCAM: DCAM_PATH1_INPUT_RECT  {%d %d %d %d} \n",
1863                         rect->x,
1864                         rect->y,
1865                         rect->w,
1866                         rect->h);
1867
1868                 if (rect->x > DCAM_PATH_FRAME_WIDTH_MAX ||
1869                 rect->y > DCAM_PATH_FRAME_HEIGHT_MAX ||
1870                 rect->w > DCAM_PATH_FRAME_WIDTH_MAX ||
1871                 rect->h > DCAM_PATH_FRAME_HEIGHT_MAX) {
1872                         rtn = DCAM_RTN_PATH_TRIM_SIZE_ERR;
1873                 } else {
1874                         memcpy((void*)&path->input_rect,
1875                                 (void*)rect,
1876                                 sizeof(struct dcam_rect));
1877                         //if (path->input_rect.h >= DCAM_HEIGHT_MIN) {
1878                         //      path->input_rect.h--;
1879                         //}
1880                         path->valid_param.input_rect = 1;
1881                 }
1882                 break;
1883         }
1884
1885         case DCAM_PATH_OUTPUT_SIZE:
1886         {
1887                 struct dcam_size *size = (struct dcam_size*)param;
1888
1889                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1890
1891                 DCAM_TRACE("DCAM: DCAM_PATH1_OUTPUT_SIZE {%d %d} \n", size->w, size->h);
1892                 if (size->w > DCAM_PATH_FRAME_WIDTH_MAX ||
1893                 size->h > DCAM_PATH_FRAME_HEIGHT_MAX) {
1894                         rtn = DCAM_RTN_PATH_SRC_SIZE_ERR;
1895                 } else {
1896                         path->output_size.w = size->w;
1897                         path->output_size.h = size->h;
1898                         path->valid_param.output_size = 1;
1899                 }
1900                 break;
1901         }
1902
1903         case DCAM_PATH_OUTPUT_FORMAT:
1904         {
1905                 enum dcam_fmt format = *(enum dcam_fmt*)param;
1906
1907                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1908
1909                 path->output_format = format;
1910
1911                 if((DCAM_YUV422 != format) &&
1912                 (DCAM_YUV420 != format) &&
1913                 (DCAM_YUV420_3FRAME != format)){
1914                         rtn = DCAM_RTN_PATH_OUT_FMT_ERR;
1915                         path->output_format = DCAM_FTM_MAX;
1916                 }else{
1917                         path->valid_param.output_format = 1;
1918                 }
1919                 break;
1920         }
1921
1922         case DCAM_PATH_OUTPUT_ADDR:
1923         {
1924                 struct dcam_addr *p_addr = (struct dcam_addr*)param;
1925
1926                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1927                 if (DCAM_YUV_ADDR_INVALID(p_addr->yaddr, p_addr->uaddr, p_addr->vaddr)) {
1928                         rtn = DCAM_RTN_PATH_ADDR_ERR;
1929                 } else {
1930                         struct dcam_frame frame;
1931                         memset((void*)&frame, 0, sizeof(struct dcam_frame));
1932                         frame.yaddr = p_addr->yaddr;
1933                         frame.uaddr = p_addr->uaddr;
1934                         frame.vaddr = p_addr->vaddr;
1935                         frame.yaddr_vir = p_addr->yaddr_vir;
1936                         frame.uaddr_vir = p_addr->uaddr_vir;
1937                         frame.vaddr_vir = p_addr->vaddr_vir;
1938                         frame.type  = DCAM_PATH1;
1939                         frame.fid   = s_p_dcam_mod->dcam_path1.frame_base_id;
1940                         DCAM_TRACE("DCAM: Path 1 DCAM_PATH_OUTPUT_ADDR, i=%d, y=0x%x, u=0x%x, v=0x%x \n",
1941                                 path->output_frame_count, p_addr->yaddr, p_addr->uaddr, p_addr->vaddr);
1942                         _dcam_buf_queue_write(&s_p_dcam_mod->dcam_path1.buf_queue, &frame);
1943                 }
1944                 break;
1945         }
1946
1947         case DCAM_PATH_OUTPUT_RESERVED_ADDR:
1948         {
1949                 struct dcam_addr *p_addr = (struct dcam_addr*)param;
1950
1951                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1952
1953                 if (DCAM_YUV_ADDR_INVALID(p_addr->yaddr, p_addr->uaddr, p_addr->vaddr)) {
1954                         rtn = DCAM_RTN_PATH_ADDR_ERR;
1955                 } else {
1956                         struct dcam_frame *frame  = &s_p_dcam_mod->path1_reserved_frame;
1957                         frame->yaddr = p_addr->yaddr;
1958                         frame->uaddr = p_addr->uaddr;
1959                         frame->vaddr = p_addr->vaddr;
1960                         frame->yaddr_vir = p_addr->yaddr_vir;
1961                         frame->uaddr_vir = p_addr->uaddr_vir;
1962                         frame->vaddr_vir = p_addr->vaddr_vir;
1963                         DCAM_TRACE("DCAM: Path 1 DCAM_PATH_OUTPUT_RESERVED_ADDR, i=%d, y=0x%x, u=0x%x, v=0x%x \n",
1964                                 path->output_frame_count, p_addr->yaddr, p_addr->uaddr, p_addr->vaddr);
1965                 }
1966                 break;
1967         }
1968
1969         case DCAM_PATH_SRC_SEL:
1970         {
1971                 uint32_t       src_sel = *(uint32_t*)param;
1972
1973                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1974
1975                 if (src_sel >= DCAM_PATH_FROM_NONE) {
1976                         rtn = DCAM_RTN_PATH_SRC_ERR;
1977                 } else {
1978                         path->src_sel = src_sel;
1979                         path->valid_param.src_sel = 1;
1980                 }
1981                 break;
1982         }
1983
1984         case DCAM_PATH_FRAME_BASE_ID:
1985         {
1986                 uint32_t          base_id = *(uint32_t*)param, i;
1987
1988                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1989
1990                 DCAM_TRACE("DCAM: DCAM_PATH_FRAME_BASE_ID 0x%x \n", base_id);
1991                 s_p_dcam_mod->dcam_path1.frame_base_id = base_id;
1992                 break;
1993         }
1994
1995         case DCAM_PATH_DATA_ENDIAN:
1996         {
1997                 struct dcam_endian_sel *endian = (struct dcam_endian_sel*)param;
1998
1999                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2000
2001                 if (endian->y_endian >= DCAM_ENDIAN_MAX ||
2002                         endian->uv_endian >= DCAM_ENDIAN_MAX) {
2003                         rtn = DCAM_RTN_PATH_ENDIAN_ERR;
2004                 } else {
2005                         path->data_endian.y_endian  = endian->y_endian;
2006                         path->data_endian.uv_endian = endian->uv_endian;
2007                         path->valid_param.data_endian = 1;
2008                 }
2009                 break;
2010         }
2011
2012         case DCAM_PATH_ENABLE:
2013         {
2014                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2015                 path->valide = *(uint32_t*)param;
2016                 break;
2017         }
2018
2019         case DCAM_PATH_FRAME_TYPE:
2020         {
2021                 struct dcam_frame *frame  = &s_p_dcam_mod->dcam_path1.buf_queue.frame[0];
2022                 uint32_t          frm_type = *(uint32_t*)param, i;
2023
2024                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2025
2026                 DCAM_TRACE("DCAM: DCAM_PATH_FRAME_TYPE 0x%x \n", frm_type);
2027                 for (i = 0; i < DCAM_PATH_1_FRM_CNT_MAX; i++) {
2028                         (frame+i)->type = frm_type;
2029                 }
2030                 break;
2031         }
2032
2033         case DCAM_PATH_FRM_DECI:
2034         {
2035                 uint32_t deci_factor = *(uint32_t*)param;
2036
2037                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2038
2039                 if (deci_factor >= DCAM_FRM_DECI_FAC_MAX) {
2040                         rtn = DCAM_RTN_PATH_FRM_DECI_ERR;
2041                 } else {
2042                         path->frame_deci = deci_factor;
2043                         path->valid_param.frame_deci = 1;
2044                 }
2045                 break;
2046         }
2047
2048         default:
2049                 break;
2050         }
2051
2052         return -rtn;
2053 }
2054
2055 int32_t dcam_path2_cfg(enum dcam_cfg_id id, void *param)
2056 {
2057         enum dcam_drv_rtn       rtn = DCAM_RTN_SUCCESS;
2058         struct dcam_path_desc   *path = NULL;
2059
2060         DCAM_CHECK_ZERO(s_p_dcam_mod);
2061         path = &s_p_dcam_mod->dcam_path2;
2062         switch (id) {
2063
2064         case DCAM_PATH_INPUT_SIZE:
2065         {
2066                 struct dcam_size *size = (struct dcam_size*)param;
2067
2068                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2069
2070                 DCAM_TRACE("DCAM: DCAM_PATH2_INPUT_SIZE {%d %d} \n", size->w, size->h);
2071                 if (size->w > DCAM_PATH_FRAME_WIDTH_MAX ||
2072                 size->h > DCAM_PATH_FRAME_HEIGHT_MAX) {
2073                         rtn = DCAM_RTN_PATH_SRC_SIZE_ERR;
2074                 } else {
2075                         path->input_size.w = size->w;
2076                         path->input_size.h = size->h;
2077                         path->valid_param.input_size = 1;
2078
2079                 }
2080                 break;
2081         }
2082
2083         case DCAM_PATH_INPUT_RECT:
2084         {
2085                 struct dcam_rect *rect = (struct dcam_rect*)param;
2086
2087                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2088
2089                 DCAM_TRACE("DCAM: DCAM_PATH2_INPUT_RECT {%d %d %d %d} \n",
2090                         rect->x,
2091                         rect->y,
2092                         rect->w,
2093                         rect->h);
2094
2095                 if (rect->x > DCAM_PATH_FRAME_WIDTH_MAX ||
2096                 rect->y > DCAM_PATH_FRAME_HEIGHT_MAX ||
2097                 rect->w > DCAM_PATH_FRAME_WIDTH_MAX ||
2098                 rect->h > DCAM_PATH_FRAME_HEIGHT_MAX) {
2099                         rtn = DCAM_RTN_PATH_TRIM_SIZE_ERR;
2100                 } else {
2101                         memcpy((void*)&path->input_rect,
2102                                 (void*)rect,
2103                                 sizeof(struct dcam_rect));
2104 #if 0
2105                         if (path->input_rect.h >= DCAM_HEIGHT_MIN) {
2106                                 path->input_rect.h--;
2107                         }
2108 #endif
2109                         path->valid_param.input_rect = 1;
2110                 }
2111                 break;
2112         }
2113
2114         case DCAM_PATH_OUTPUT_SIZE:
2115         {
2116                 struct dcam_size *size = (struct dcam_size*)param;
2117
2118                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2119
2120                 DCAM_TRACE("DCAM: DCAM_PATH2_OUTPUT_SIZE {%d %d} \n", size->w, size->h);
2121                 if (size->w > DCAM_PATH_FRAME_WIDTH_MAX ||
2122                 size->h > DCAM_PATH_FRAME_HEIGHT_MAX) {
2123                         rtn = DCAM_RTN_PATH_SRC_SIZE_ERR;
2124                 } else {
2125                         path->output_size.w = size->w;
2126                         path->output_size.h = size->h;
2127                         path->valid_param.output_size = 1;
2128                 }
2129                 break;
2130         }
2131
2132         case DCAM_PATH_OUTPUT_FORMAT:
2133         {
2134                 enum dcam_fmt format = *(enum dcam_fmt*)param;
2135
2136                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2137
2138                 if((DCAM_YUV422 != format) &&
2139                 (DCAM_YUV420 != format) &&
2140                 (DCAM_YUV420_3FRAME != format)){
2141                         rtn = DCAM_RTN_PATH_OUT_FMT_ERR;
2142                         path->output_format = DCAM_FTM_MAX;
2143                 }else{
2144                         path->output_format = format;
2145                         path->valid_param.output_format = 1;
2146                 }
2147                 break;
2148         }
2149
2150         case DCAM_PATH_OUTPUT_ADDR:
2151         {
2152                 struct dcam_addr *p_addr = (struct dcam_addr*)param;
2153
2154                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2155                 if (DCAM_YUV_ADDR_INVALID(p_addr->yaddr, p_addr->uaddr, p_addr->vaddr)) {
2156                         rtn = DCAM_RTN_PATH_ADDR_ERR;
2157                 } else {
2158                         struct dcam_frame frame;
2159                         memset((void*)&frame, 0, sizeof(struct dcam_frame));
2160                         frame.yaddr = p_addr->yaddr;
2161                         frame.uaddr = p_addr->uaddr;
2162                         frame.vaddr = p_addr->vaddr;
2163                         frame.yaddr_vir = p_addr->yaddr_vir;
2164                         frame.uaddr_vir = p_addr->uaddr_vir;
2165                         frame.vaddr_vir = p_addr->vaddr_vir;
2166                         frame.type  = DCAM_PATH2;
2167                         frame.fid   = s_p_dcam_mod->dcam_path2.frame_base_id;
2168                         DCAM_TRACE("DCAM: Path 2 DCAM_PATH_OUTPUT_ADDR, i=%d, y=0x%x, u=0x%x, v=0x%x \n",
2169                                 path->output_frame_count, p_addr->yaddr, p_addr->uaddr, p_addr->vaddr);
2170                         _dcam_buf_queue_write(&s_p_dcam_mod->dcam_path2.buf_queue, &frame);
2171                 }
2172                 break;
2173         }
2174
2175         case DCAM_PATH_OUTPUT_RESERVED_ADDR:
2176         {
2177                 struct dcam_addr *p_addr = (struct dcam_addr*)param;
2178
2179                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2180
2181                 if (DCAM_YUV_ADDR_INVALID(p_addr->yaddr, p_addr->uaddr, p_addr->vaddr)) {
2182                         rtn = DCAM_RTN_PATH_ADDR_ERR;
2183                 } else {
2184                         struct dcam_frame *frame  = &s_p_dcam_mod->path2_reserved_frame;
2185                         frame->yaddr = p_addr->yaddr;
2186                         frame->uaddr = p_addr->uaddr;
2187                         frame->vaddr = p_addr->vaddr;
2188                         frame->yaddr_vir = p_addr->yaddr_vir;
2189                         frame->uaddr_vir = p_addr->uaddr_vir;
2190                         frame->vaddr_vir = p_addr->vaddr_vir;
2191                         DCAM_TRACE("DCAM: Path 1 DCAM_PATH_OUTPUT_RESERVED_ADDR, i=%d, y=0x%x, u=0x%x, v=0x%x \n",
2192                                 path->output_frame_count, p_addr->yaddr, p_addr->uaddr, p_addr->vaddr);
2193                 }
2194                 break;
2195         }
2196
2197         case DCAM_PATH_SRC_SEL:
2198         {
2199                 uint32_t       src_sel = *(uint32_t*)param;
2200
2201                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2202
2203                 if (src_sel >= DCAM_PATH_FROM_NONE) {
2204                         rtn = DCAM_RTN_PATH_SRC_ERR;
2205                 } else {
2206                         path->src_sel = src_sel;
2207                         path->valid_param.src_sel = 1;
2208
2209                 }
2210                 break;
2211         }
2212
2213         case DCAM_PATH_FRAME_BASE_ID:
2214         {
2215                 uint32_t          base_id = *(uint32_t*)param, i;
2216
2217                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2218
2219                 DCAM_TRACE("DCAM: DCAM_PATH_FRAME_BASE_ID 0x%x \n", base_id);
2220                 s_p_dcam_mod->dcam_path2.frame_base_id = base_id;
2221                 break;
2222         }
2223
2224         case DCAM_PATH_DATA_ENDIAN:
2225         {
2226                 struct dcam_endian_sel *endian = (struct dcam_endian_sel*)param;
2227
2228                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2229
2230                 if (endian->y_endian >= DCAM_ENDIAN_MAX ||
2231                         endian->uv_endian >= DCAM_ENDIAN_MAX) {
2232                         rtn = DCAM_RTN_PATH_ENDIAN_ERR;
2233                 } else {
2234                         path->data_endian.y_endian  = endian->y_endian;
2235                         path->data_endian.uv_endian = endian->uv_endian;
2236                         path->valid_param.data_endian = 1;
2237                 }
2238                 break;
2239         }
2240
2241         case DCAM_PATH_ENABLE:
2242         {
2243                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2244
2245                 path->valide = *(uint32_t*)param;
2246
2247                 break;
2248         }
2249
2250         case DCAM_PATH_FRAME_TYPE:
2251         {
2252                 struct dcam_frame *frame  = &s_p_dcam_mod->dcam_path2.buf_queue.frame[0];
2253                 uint32_t          frm_type = *(uint32_t*)param, i;
2254
2255                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2256
2257                 DCAM_TRACE("DCAM: DCAM_PATH_FRAME_TYPE 0x%x \n", frm_type);
2258                 for (i = 0; i < DCAM_PATH_2_FRM_CNT_MAX; i++) {
2259                         (frame+i)->type = frm_type;
2260                 }
2261                 break;
2262         }
2263
2264         case DCAM_PATH_FRM_DECI:
2265         {
2266                 uint32_t deci_factor = *(uint32_t*)param;
2267
2268                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2269
2270                 if (deci_factor >= DCAM_FRM_DECI_FAC_MAX) {
2271                         rtn = DCAM_RTN_PATH_FRM_DECI_ERR;
2272                 } else {
2273                         path->frame_deci = deci_factor;
2274                         path->valid_param.frame_deci = 1;
2275                 }
2276                 break;
2277         }
2278
2279         default:
2280                 break;
2281         }
2282
2283         return -rtn;
2284 }
2285
2286 int32_t    dcam_get_resizer(uint32_t wait_opt)
2287 {
2288         int32_t                 rtn = 0;
2289
2290         printk("resizer_get:%d\n",current->pid);
2291
2292         
2293         if( 0 == wait_opt) {
2294                 rtn = mutex_trylock(&dcam_sem) ? 0 : 1;
2295                 return rtn;
2296         } else if (DCAM_WAIT_FOREVER == wait_opt){
2297                 mutex_lock(&dcam_sem);
2298                 return rtn;
2299         } else {
2300                 return 0;//mutex_timeout(&dcam_sem, wait_opt);
2301         }
2302 }
2303
2304 int32_t    dcam_rel_resizer(void)
2305 {
2306         printk("resizer_put:%d\n",current->pid);
2307         mutex_unlock(&dcam_sem);
2308         return 0;
2309 }
2310
2311 int32_t    dcam_resize_start(void)
2312 {
2313         atomic_inc(&s_resize_flag);
2314         mutex_lock(&dcam_scale_sema);
2315         return 0;
2316 }
2317
2318 int32_t    dcam_resize_end(void)
2319 {
2320         unsigned long flag;
2321
2322         atomic_dec(&s_resize_flag);
2323         mutex_unlock(&dcam_scale_sema);
2324
2325         spin_lock_irqsave(&dcam_mod_lock, flag);
2326         if (DCAM_ADDR_INVALID(s_p_dcam_mod)) {
2327                 spin_unlock_irqrestore(&dcam_mod_lock, flag);
2328                 return 0;
2329         }
2330
2331         if (s_p_dcam_mod) {
2332                 if (s_p_dcam_mod->wait_resize_done) {
2333                         up(&s_p_dcam_mod->resize_done_sema);
2334                         s_p_dcam_mod->wait_resize_done = 0;
2335                 }
2336         }
2337         spin_unlock_irqrestore(&dcam_mod_lock, flag);
2338         return 0;
2339 }
2340
2341 int32_t    dcam_rotation_start(void)
2342 {
2343         atomic_inc(&s_rotation_flag);
2344         mutex_lock(&dcam_rot_sema);
2345         return 0;
2346 }
2347
2348 int32_t    dcam_rotation_end(void)
2349 {
2350         unsigned long flag;
2351
2352         atomic_dec(&s_rotation_flag);
2353         mutex_unlock(&dcam_rot_sema);
2354
2355         spin_lock_irqsave(&dcam_mod_lock, flag);
2356         if (DCAM_ADDR_INVALID(s_p_dcam_mod)) {
2357                 spin_unlock_irqrestore(&dcam_mod_lock, flag);
2358                 return 0;
2359         }
2360
2361         if (s_p_dcam_mod) {
2362                 if (s_p_dcam_mod->wait_rotation_done) {
2363                         up(&s_p_dcam_mod->rotation_done_sema);
2364                         s_p_dcam_mod->wait_rotation_done = 0;
2365                 }
2366         }
2367         spin_unlock_irqrestore(&dcam_mod_lock, flag);
2368         return 0;
2369 }
2370
2371 void dcam_int_en(void)
2372 {
2373         if (atomic_read(&s_dcam_users) == 1) {
2374                 enable_irq(DCAM_IRQ);
2375         }
2376 }
2377
2378 void dcam_int_dis(void)
2379 {
2380         if (atomic_read(&s_dcam_users) == 1) {
2381                 disable_irq(DCAM_IRQ);
2382         }
2383 }
2384
2385 int32_t dcam_frame_is_locked(struct dcam_frame *frame)
2386 {
2387         uint32_t                rtn = 0;
2388         unsigned long           flags;
2389
2390         /*To disable irq*/
2391         local_irq_save(flags);
2392         if (frame)
2393                 rtn = frame->lock == DCAM_FRM_LOCK_WRITE ? 1 : 0;
2394         local_irq_restore(flags);
2395         /*To enable irq*/
2396
2397         return -rtn;
2398 }
2399
2400 int32_t dcam_frame_lock(struct dcam_frame *frame)
2401 {
2402         uint32_t                rtn = 0;
2403         unsigned long           flags;
2404
2405         DCAM_CHECK_ZERO(s_p_dcam_mod);
2406
2407         DCAM_TRACE("DCAM: lock %d \n", (uint32_t)(0xF&frame->fid));
2408
2409         /*To disable irq*/
2410         local_irq_save(flags);
2411         if (likely(frame))
2412                 frame->lock = DCAM_FRM_LOCK_WRITE;
2413         else
2414                 rtn = DCAM_RTN_PARA_ERR;
2415         local_irq_restore(flags);
2416         /*To enable irq*/
2417
2418         return -rtn;
2419 }
2420
2421 int32_t dcam_frame_unlock(struct dcam_frame *frame)
2422 {
2423         uint32_t                rtn = 0;
2424         unsigned long           flags;
2425
2426         DCAM_CHECK_ZERO(s_p_dcam_mod);
2427
2428         DCAM_TRACE("DCAM: unlock %d \n", (uint32_t)(0xF&frame->fid));
2429
2430         /*To disable irq*/
2431         local_irq_save(flags);
2432         if (likely(frame))
2433                 frame->lock = DCAM_FRM_UNLOCK;
2434         else
2435                 rtn = DCAM_RTN_PARA_ERR;
2436         local_irq_restore(flags);
2437         /*To enable irq*/
2438
2439         return -rtn;
2440 }
2441
2442 int32_t    dcam_read_registers(uint32_t* reg_buf, uint32_t *buf_len)
2443 {
2444         uint32_t                *reg_addr = (uint32_t*)DCAM_BASE;
2445
2446         if (NULL == reg_buf || NULL == buf_len || 0 != (*buf_len % 4)) {
2447                 return -1;
2448         }
2449
2450         while (buf_len != 0 && (uint32_t)reg_addr < DCAM_END) {
2451                 *reg_buf++ = REG_RD(reg_addr);
2452                 reg_addr++;
2453                 *buf_len -= 4;
2454         }
2455
2456         *buf_len = (uint32_t)reg_addr - DCAM_BASE;
2457         return 0;
2458 }
2459
2460 int32_t    dcam_get_path_id(struct dcam_get_path_id *path_id, uint32_t *channel_id)
2461 {
2462         int                      ret = DCAM_RTN_SUCCESS;
2463
2464         if (NULL == path_id || NULL == channel_id) {
2465                 return -1;
2466         }
2467
2468         DCAM_TRACE("DCAM: fourcc 0x%x, w %d, h %d, %d %d \n",
2469                 path_id->fourcc, path_id->input_size.w, path_id->input_size.h,
2470                 path_id->is_path_work[DCAM_PATH1], path_id->is_path_work[DCAM_PATH2]);
2471
2472         if (path_id->need_isp_tool) {
2473                 *channel_id = DCAM_PATH0;
2474         } else if (V4L2_PIX_FMT_GREY == path_id->fourcc && !path_id->is_path_work[DCAM_PATH0]) {
2475                 *channel_id = DCAM_PATH0;
2476         } else if (V4L2_PIX_FMT_JPEG == path_id->fourcc && !path_id->is_path_work[DCAM_PATH0]) {
2477                 *channel_id = DCAM_PATH0;
2478         } else if (path_id->output_size.w <= DCAM_PATH1_LINE_BUF_LENGTH  && !path_id->is_path_work[DCAM_PATH1]) {
2479                 *channel_id = DCAM_PATH1;
2480         } else if (path_id->output_size.w <= DCAM_PATH2_LINE_BUF_LENGTH  && !path_id->is_path_work[DCAM_PATH2]) {
2481                 *channel_id = DCAM_PATH2;
2482         } else {
2483                 *channel_id = DCAM_PATH0;
2484         }
2485         printk("DCAM: path id %d \n", *channel_id);
2486
2487         return ret;
2488 }
2489
2490 int32_t    dcam_get_path_capability(struct dcam_path_capability *capacity)
2491 {
2492         int                      ret = DCAM_RTN_SUCCESS;
2493
2494         if (NULL == capacity) {
2495                 return -1;
2496         }
2497
2498         capacity->count = 3;
2499         capacity->path_info[DCAM_PATH0].line_buf = 0;
2500         capacity->path_info[DCAM_PATH0].support_yuv = 0;
2501         capacity->path_info[DCAM_PATH0].support_raw = 1;
2502         capacity->path_info[DCAM_PATH0].support_jpeg = 1;
2503         capacity->path_info[DCAM_PATH0].support_scaling = 0;
2504         capacity->path_info[DCAM_PATH0].support_trim = 0;
2505         capacity->path_info[DCAM_PATH0].is_scaleing_path = 0;
2506
2507         capacity->path_info[DCAM_PATH1].line_buf = DCAM_PATH1_LINE_BUF_LENGTH;
2508         capacity->path_info[DCAM_PATH1].support_yuv = 1;
2509         capacity->path_info[DCAM_PATH1].support_raw = 0;
2510         capacity->path_info[DCAM_PATH1].support_jpeg = 0;
2511         capacity->path_info[DCAM_PATH1].support_scaling = 1;
2512         capacity->path_info[DCAM_PATH1].support_trim = 1;
2513         capacity->path_info[DCAM_PATH1].is_scaleing_path = 0;
2514
2515         capacity->path_info[DCAM_PATH2].line_buf = DCAM_PATH2_LINE_BUF_LENGTH;
2516         capacity->path_info[DCAM_PATH2].support_yuv = 1;
2517         capacity->path_info[DCAM_PATH2].support_raw = 0;
2518         capacity->path_info[DCAM_PATH2].support_jpeg = 0;
2519         capacity->path_info[DCAM_PATH2].support_scaling = 1;
2520         capacity->path_info[DCAM_PATH2].support_trim = 1;
2521         capacity->path_info[DCAM_PATH2].is_scaleing_path = 1;
2522
2523         return ret;
2524 }
2525
2526
2527 LOCAL irqreturn_t _dcam_isr_root(int irq, void *dev_id)
2528 {
2529         uint32_t                irq_line, status;
2530         unsigned long           flag;
2531         int32_t                 i;
2532
2533         DCAM_TRACE("DCAM: ISR 0x%x \n", REG_RD(DCAM_INT_STS));
2534         status = REG_RD(DCAM_INT_STS) & DCAM_IRQ_LINE_MASK;
2535         if (unlikely(0 == status)) {
2536                 return IRQ_NONE;
2537         }
2538
2539         irq_line = status;
2540         if (unlikely(DCAM_IRQ_ERR_MASK & status)) {
2541                 if (_dcam_err_pre_proc()) {
2542                         return IRQ_NONE;
2543                 }
2544         }
2545
2546         spin_lock_irqsave(&dcam_lock,flag);
2547
2548         //for (i = DCAM_IRQ_NUMBER - 1; i >= 0; i--) {
2549         for (i = 0; i < DCAM_IRQ_NUMBER; i++) {
2550                 if (irq_line & (1 << (uint32_t)i)) {
2551                         if (isr_list[i]) {
2552                                 isr_list[i]();
2553                         }
2554                 }
2555                 irq_line &= ~(uint32_t)(1 << (uint32_t)i); //clear the interrupt flag
2556                 if(!irq_line) //no interrupt source left
2557                         break;
2558         }
2559
2560         REG_WR(DCAM_INT_CLR, status);
2561         DCAM_TRACE("DCAM: status 0x%x, ISR 0x%x \n", status, REG_RD(DCAM_INT_STS));
2562
2563         spin_unlock_irqrestore(&dcam_lock, flag);
2564
2565         return IRQ_HANDLED;
2566 }
2567
2568 LOCAL void _dcam_path0_set(void)
2569 {
2570         uint32_t                reg_val = 0;
2571         struct dcam_path_desc   *path = NULL;
2572
2573         DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
2574         path = &s_p_dcam_mod->dcam_path0;
2575         if (path->valid_param.input_size) {
2576                 reg_val = path->input_size.w | (path->input_size.h << 16);
2577                 REG_WR(DCAM_PATH0_SRC_SIZE, reg_val);
2578         }
2579
2580         if (path->valid_param.output_format) {
2581                 enum dcam_output_mode format = path->output_format;
2582                 REG_MWR(DCAM_PATH0_CFG, BIT_2, format << 2);
2583                 DCAM_TRACE("DCAM: path 0: output_format=0x%x \n", format);
2584         }
2585
2586         if (path->valid_param.frame_deci) {
2587                 REG_MWR(DCAM_PATH0_CFG, BIT_1 | BIT_0, path->frame_deci << 0);
2588         }
2589
2590         if (path->valid_param.data_endian) {
2591                 dcam_glb_reg_mwr(DCAM_ENDIAN_SEL, BIT_5 | BIT_4, path->data_endian.y_endian << 4, DCAM_ENDIAN_REG);
2592                 dcam_glb_reg_mwr(DCAM_ENDIAN_SEL, BIT_18, BIT_18, DCAM_ENDIAN_REG); // axi write
2593                 dcam_glb_reg_mwr(DCAM_ENDIAN_SEL, BIT_19, BIT_19, DCAM_ENDIAN_REG); // axi read
2594                 DCAM_TRACE("DCAM DRV: path 0: data_endian y=0x%x, uv=0x%x \n",
2595                         path->data_endian.y_endian, path->data_endian.uv_endian);
2596         }
2597
2598 }
2599 LOCAL void _dcam_path1_set(struct dcam_path_desc *path)
2600 {
2601         uint32_t                reg_val = 0;
2602
2603         DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
2604         DCAM_CHECK_ZERO_VOID(path);
2605
2606         if (path->valid_param.input_size) {
2607                 reg_val = path->input_size.w | (path->input_size.h << 16);
2608                 REG_WR(DCAM_PATH1_SRC_SIZE, reg_val);
2609                 DCAM_TRACE("DCAM: path1 set: src {%d %d} \n",path->input_size.w, path->input_size.h);
2610         }
2611
2612         if (path->valid_param.input_rect) {
2613                 reg_val = path->input_rect.x | (path->input_rect.y << 16);
2614                 REG_WR(DCAM_PATH1_TRIM_START, reg_val);
2615                 reg_val = path->input_rect.w | (path->input_rect.h << 16);
2616                 REG_WR(DCAM_PATH1_TRIM_SIZE, reg_val);
2617                 DCAM_TRACE("DCAM: path1 set: rect {%d %d %d %d} \n",
2618                         path->input_rect.x,
2619                         path->input_rect.y,
2620                         path->input_rect.w,
2621                         path->input_rect.h);
2622         }
2623
2624         if (path->valid_param.output_size) {
2625                 reg_val = path->output_size.w | (path->output_size.h << 16);
2626                 REG_WR(DCAM_PATH1_DST_SIZE, reg_val);
2627                 DCAM_TRACE("DCAM: path1 set: dst {%d %d} \n",path->output_size.w, path->output_size.h);
2628         }
2629
2630         if (path->valid_param.output_format) {
2631                 enum dcam_fmt format = path->output_format;
2632                 if (DCAM_YUV422 == format) {
2633                         REG_MWR(DCAM_PATH1_CFG, BIT_7 | BIT_6, 0 << 6);
2634                 } else if (DCAM_YUV420 == format) {
2635                         REG_MWR(DCAM_PATH1_CFG, BIT_7 | BIT_6, 1 << 6);
2636                 } else if (DCAM_YUV420_3FRAME == format) {
2637                         REG_MWR(DCAM_PATH1_CFG, BIT_7 | BIT_6, 3 << 6);
2638                 } else {
2639                         DCAM_TRACE("DCAM: invalid path 1 output format %d \n", format);
2640                 }
2641                 DCAM_TRACE("DCAM: path 1: output_format=0x%x \n", format);
2642         }
2643
2644         if (path->valid_param.src_sel) {
2645                 REG_MWR(DCAM_CFG, BIT_12 | BIT_11, path->src_sel << 11);
2646                 DCAM_TRACE("DCAM: path 1: src_sel=0x%x \n", path->src_sel);
2647         }
2648
2649         if (path->valid_param.data_endian) {
2650                 dcam_glb_reg_mwr(DCAM_ENDIAN_SEL, BIT_7 | BIT_6, path->data_endian.y_endian << 6, DCAM_ENDIAN_REG);
2651                 dcam_glb_reg_mwr(DCAM_ENDIAN_SEL, BIT_9 | BIT_8, path->data_endian.uv_endian << 8, DCAM_ENDIAN_REG);
2652                 dcam_glb_reg_mwr(DCAM_ENDIAN_SEL, BIT_18, BIT_18, DCAM_ENDIAN_REG); // axi write
2653                 dcam_glb_reg_mwr(DCAM_ENDIAN_SEL, BIT_19, BIT_19, DCAM_ENDIAN_REG); // axi read
2654                 DCAM_TRACE("DCAM: path 1: data_endian y=0x%x, uv=0x%x \n",
2655                         path->data_endian.y_endian, path->data_endian.uv_endian);
2656         }
2657
2658         if (path->valid_param.frame_deci) {
2659                 REG_MWR(DCAM_PATH0_CFG, BIT_24 | BIT_23, path->frame_deci << 23);
2660                 DCAM_TRACE("DCAM: path 1: frame_deci=0x%x \n", path->frame_deci);
2661         }
2662
2663         if (path->valid_param.scale_tap) {
2664                 path->valid_param.scale_tap = 0;
2665                 REG_MWR(DCAM_PATH1_CFG, BIT_19 | BIT_18 | BIT_17 | BIT_16, (path->scale_tap.y_tap & 0x0F) << 16);
2666                 REG_MWR(DCAM_PATH1_CFG, BIT_15 | BIT_14 | BIT_13 | BIT_12 | BIT_11, (path->scale_tap.uv_tap & 0x1F) << 11);
2667                 DCAM_TRACE("DCAM: path 1: scale_tap, y=0x%x, uv=0x%x \n", path->scale_tap.y_tap, path->scale_tap.uv_tap);
2668         }
2669
2670         if (path->valid_param.v_deci) {
2671                 path->valid_param.v_deci = 0;
2672                 REG_MWR(DCAM_PATH1_CFG, BIT_2, path->deci_val.deci_x_en << 2);
2673                 REG_MWR(DCAM_PATH1_CFG, BIT_1 | BIT_0, path->deci_val.deci_x);
2674
2675                 REG_MWR(DCAM_PATH1_CFG, BIT_5, path->deci_val.deci_y_en << 5);
2676                 REG_MWR(DCAM_PATH1_CFG, BIT_4 | BIT_3, path->deci_val.deci_y << 3);
2677                 DCAM_TRACE("DCAM: path 1: deci, x_en=%d, x=%d, y_en=%d, y=%d \n",
2678                         path->deci_val.deci_x_en, path->deci_val.deci_x, path->deci_val.deci_y_en, path->deci_val.deci_y);
2679         }
2680 }
2681
2682 LOCAL void _dcam_path2_set(void)
2683 {
2684         struct dcam_path_desc   *path = NULL;
2685         uint32_t                reg_val = 0;
2686
2687         DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
2688         path = &s_p_dcam_mod->dcam_path2;
2689         if (path->valid_param.input_size) {
2690                 reg_val = path->input_size.w | (path->input_size.h << 16);
2691                 REG_WR(DCAM_PATH2_SRC_SIZE, reg_val);
2692                 DCAM_TRACE("DCAM: path2 set: src {%d %d} \n",path->input_size.w, path->input_size.h);
2693         }
2694
2695         if (path->valid_param.input_rect) {
2696                 reg_val = path->input_rect.x | (path->input_rect.y << 16);
2697                 REG_WR(DCAM_PATH2_TRIM_START, reg_val);
2698                 reg_val = path->input_rect.w | (path->input_rect.h << 16);
2699                 REG_WR(DCAM_PATH2_TRIM_SIZE, reg_val);
2700                 DCAM_TRACE("DCAM: path2 set: rect {%d %d %d %d} \n",
2701                         path->input_rect.x,
2702                         path->input_rect.y,
2703                         path->input_rect.w,
2704                         path->input_rect.h);
2705         }
2706
2707         if(path->valid_param.output_size){
2708                 reg_val = path->output_size.w | (path->output_size.h << 16);
2709                 REG_WR(DCAM_PATH2_DST_SIZE, reg_val);
2710                 DCAM_TRACE("DCAM: path2 set: dst {%d %d} \n",path->output_size.w, path->output_size.h);
2711         }
2712
2713         if (path->valid_param.output_format) {
2714                 enum dcam_fmt format = path->output_format;
2715
2716                 // REG_MWR(DCAM_PATH2_CFG, BIT_8, 0 << 8); // aiden todo
2717
2718                 if (DCAM_YUV422 == format) {
2719                         REG_MWR(DCAM_PATH2_CFG, BIT_7 | BIT_6, 0 << 6);
2720                 } else if (DCAM_YUV420 == format) {
2721                         REG_MWR(DCAM_PATH2_CFG, BIT_7 | BIT_6, 1 << 6);
2722                 } else if (DCAM_YUV420_3FRAME == format) {
2723                         REG_MWR(DCAM_PATH2_CFG, BIT_7 | BIT_6, 3 << 6);
2724                 } else {
2725                         DCAM_TRACE("DCAM: invalid path 2 output format %d \n", format);
2726                 }
2727                 DCAM_TRACE("DCAM: path 2: output_format=0x%x \n", format);
2728         }
2729
2730         if (path->valid_param.src_sel) {
2731                 REG_MWR(DCAM_CFG, BIT_14 | BIT_13, path->src_sel << 13);
2732         }
2733
2734         if (path->valid_param.data_endian) {
2735                 dcam_glb_reg_mwr(DCAM_ENDIAN_SEL, BIT_11 | BIT_10, path->data_endian.y_endian << 10,DCAM_ENDIAN_REG );
2736                 dcam_glb_reg_mwr(DCAM_ENDIAN_SEL, BIT_13 | BIT_12, path->data_endian.uv_endian << 12, DCAM_ENDIAN_REG);
2737                 dcam_glb_reg_mwr(DCAM_ENDIAN_SEL, BIT_18, BIT_18, DCAM_ENDIAN_REG); // axi write
2738                 dcam_glb_reg_mwr(DCAM_ENDIAN_SEL, BIT_19, BIT_19, DCAM_ENDIAN_REG); // axi read
2739                 DCAM_TRACE("DCAM: path 2: data_endian y=0x%x, uv=0x%x \n",
2740                         path->data_endian.y_endian, path->data_endian.uv_endian);
2741         }
2742
2743         if (path->valid_param.frame_deci) {
2744                 REG_MWR(DCAM_PATH0_CFG, BIT_24 | BIT_23, path->frame_deci << 23);
2745                 DCAM_TRACE("DCAM: path 2: frame_deci=0x%x \n", path->frame_deci);
2746         }
2747
2748         if (path->valid_param.scale_tap) {
2749                 path->valid_param.scale_tap = 0;
2750                 REG_MWR(DCAM_PATH2_CFG, BIT_19 | BIT_18 | BIT_17 | BIT_16, (path->scale_tap.y_tap & 0x0F) << 16);
2751                 REG_MWR(DCAM_PATH2_CFG, BIT_15 | BIT_14 | BIT_13 | BIT_12 | BIT_11, (path->scale_tap.uv_tap & 0x1F) << 11);
2752                 DCAM_TRACE("DCAM: path 2: scale_tap, y=0x%x, uv=0x%x \n",
2753                         path->scale_tap.y_tap, path->scale_tap.uv_tap);
2754         }
2755
2756         if (path->valid_param.v_deci) {
2757                 path->valid_param.v_deci = 0;
2758                 REG_MWR(DCAM_PATH2_CFG, BIT_2, path->deci_val.deci_x_en << 2);
2759                 REG_MWR(DCAM_PATH2_CFG, BIT_1 | BIT_0, path->deci_val.deci_x);
2760
2761                 REG_MWR(DCAM_PATH2_CFG, BIT_5, path->deci_val.deci_y_en << 5);
2762                 REG_MWR(DCAM_PATH2_CFG, BIT_4 | BIT_3, path->deci_val.deci_y << 3);
2763                 DCAM_TRACE("DCAM: path 2: deci, x_en=%d, x=%d, y_en=%d, y=%d \n",
2764                         path->deci_val.deci_x_en, path->deci_val.deci_x, path->deci_val.deci_y_en, path->deci_val.deci_y);
2765         }
2766 }
2767
2768 LOCAL void _dcam_buf_queue_init(struct dcam_buf_queue *queue)
2769 {
2770         if (DCAM_ADDR_INVALID(queue)) {
2771                 printk("DCAM: invalid heap 0x%x \n", (uint32_t)queue);
2772                 return;
2773         }
2774
2775         memset((void*)queue, 0, sizeof(struct dcam_buf_queue));
2776         queue->write = &queue->frame[0];
2777         queue->read  = &queue->frame[0];
2778         spin_lock_init(&queue->lock);
2779         return;
2780 }
2781
2782 LOCAL int32_t _dcam_buf_queue_write(struct dcam_buf_queue *queue, struct dcam_frame *frame)
2783 {
2784         int                      ret = DCAM_RTN_SUCCESS;
2785         struct dcam_frame         *ori_frame;
2786         unsigned long            flag;
2787
2788         if (DCAM_ADDR_INVALID(queue) || DCAM_ADDR_INVALID(frame)) {
2789                 printk("DCAM: enq, invalid param 0x%x, 0x%x \n",
2790                         (uint32_t)queue,
2791                         (uint32_t)frame);
2792                 return -EINVAL;
2793         }
2794
2795         spin_lock_irqsave(&queue->lock, flag);
2796         ori_frame = queue->write;
2797         DCAM_TRACE("DCAM: _dcam_buf_queue_write \n");
2798         *queue->write++ = *frame;
2799         if (queue->write > &queue->frame[DCAM_FRM_CNT_MAX-1]) {
2800                 queue->write = &queue->frame[0];
2801         }
2802
2803         if (queue->write == queue->read) {
2804                 queue->write = ori_frame;
2805                 printk("DCAM: warning, queue is full, cannot write 0x%lx \n", frame->yaddr);
2806         }
2807         spin_unlock_irqrestore(&queue->lock, flag);
2808         DCAM_TRACE("DCAM: _dcam_buf_queue_write type %d \n", frame->type);
2809         return ret;
2810 }
2811
2812 LOCAL int32_t _dcam_buf_queue_read(struct dcam_buf_queue *queue, struct dcam_frame *frame)
2813 {
2814         int                      ret = DCAM_RTN_SUCCESS;
2815         unsigned long            flag;
2816
2817         if (DCAM_ADDR_INVALID(queue) || DCAM_ADDR_INVALID(frame)) {
2818                 printk("DCAM: deq, invalid param 0x%x, 0x%x \n",
2819                         (uint32_t)queue,
2820                         (uint32_t)frame);
2821                 return -EINVAL;
2822         }
2823
2824         DCAM_TRACE("DCAM: _dcam_buf_queue_read \n");
2825
2826         spin_lock_irqsave(&queue->lock, flag);
2827         if (queue->read != queue->write) {
2828                 *frame = *queue->read++;
2829                 if (queue->read > &queue->frame[DCAM_FRM_CNT_MAX-1]) {
2830                         queue->read = &queue->frame[0];
2831                 }
2832         } else {
2833                 ret = EAGAIN;
2834         }
2835         spin_unlock_irqrestore(&queue->lock, flag);
2836         DCAM_TRACE("DCAM: _dcam_buf_queue_read type %d \n", frame->type);
2837         return ret;
2838 }
2839
2840 LOCAL void _dcam_frm_queue_clear(struct dcam_frm_queue *queue)
2841 {
2842         if (DCAM_ADDR_INVALID(queue)) {
2843                 printk("DCAM: invalid heap 0x%x \n", (uint32_t)queue);
2844                 return;
2845         }
2846
2847         memset((void*)queue, 0, sizeof(struct dcam_frm_queue));
2848         return;
2849 }
2850
2851 LOCAL int32_t _dcam_frame_enqueue(struct dcam_frm_queue *queue, struct dcam_frame *frame)
2852 {
2853         if (DCAM_ADDR_INVALID(queue) || DCAM_ADDR_INVALID(frame)) {
2854                 printk("DCAM: enq, invalid param 0x%x, 0x%x \n",
2855                         (uint32_t)queue,
2856                         (uint32_t)frame);
2857                 return -1;
2858         }
2859         if (queue->valid_cnt >= DCAM_FRM_QUEUE_LENGTH) {
2860                 printk("DCAM: q over flow \n");
2861                 return -1;
2862         }
2863         //queue->frm_array[queue->valid_cnt] = frame;
2864         memcpy(&queue->frm_array[queue->valid_cnt], frame, sizeof(struct dcam_frame));
2865         queue->valid_cnt ++;
2866         DCAM_TRACE("DCAM: en queue, %d, %d, 0x%x, 0x%x \n",
2867                 (0xF & frame->fid),
2868                 queue->valid_cnt,
2869                 frame->yaddr,
2870                 frame->uaddr);
2871         return 0;
2872 }
2873
2874 LOCAL int32_t _dcam_frame_dequeue(struct dcam_frm_queue *queue, struct dcam_frame *frame)
2875 {
2876         uint32_t                i = 0;
2877
2878         if (DCAM_ADDR_INVALID(queue) || DCAM_ADDR_INVALID(frame)) {
2879                 printk("DCAM: deq, invalid param 0x%x, 0x%x \n",
2880                         (uint32_t)queue,
2881                         (uint32_t)frame);
2882                 return -1;
2883         }
2884         if (queue->valid_cnt == 0) {
2885                 printk("DCAM: q under flow \n");
2886                 return -1;
2887         }
2888
2889         //*frame  = queue->frm_array[0];
2890         memcpy(frame, &queue->frm_array[0], sizeof(struct dcam_frame));
2891         queue->valid_cnt--;
2892         for (i = 0; i < queue->valid_cnt; i++) {
2893                 //queue->frm_array[i] = queue->frm_array[i+1];
2894                 memcpy(&queue->frm_array[i], &queue->frm_array[i+1], sizeof(struct dcam_frame));
2895         }
2896         DCAM_TRACE("DCAM: de queue, %d, %d \n",
2897                 (0xF & (frame)->fid),
2898                 queue->valid_cnt);
2899         return 0;
2900 }
2901
2902 LOCAL void _dcam_frm_clear(enum dcam_path_index path_index)
2903 {
2904         uint32_t                i = 0;
2905
2906         DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
2907
2908         if (DCAM_PATH_IDX_0 & path_index) {
2909                 _dcam_frm_queue_clear(&s_p_dcam_mod->dcam_path0.frame_queue);
2910                 _dcam_buf_queue_init(&s_p_dcam_mod->dcam_path0.buf_queue);
2911         }
2912
2913         if (DCAM_PATH_IDX_1 & path_index) {
2914                 _dcam_frm_queue_clear(&s_p_dcam_mod->dcam_path1.frame_queue);
2915                 _dcam_buf_queue_init(&s_p_dcam_mod->dcam_path1.buf_queue);
2916         }
2917
2918         if (DCAM_PATH_IDX_2 & path_index) {
2919                 _dcam_frm_queue_clear(&s_p_dcam_mod->dcam_path2.frame_queue);
2920                 _dcam_buf_queue_init(&s_p_dcam_mod->dcam_path2.buf_queue);
2921         }
2922
2923         return;
2924 }
2925
2926 LOCAL void _dcam_frm_pop(enum dcam_path_index path_index)
2927 {
2928         uint32_t                i = 0;
2929         struct dcam_frame       *frame = NULL;
2930         uint32_t                *frame_count;
2931
2932         DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
2933
2934         if (DCAM_PATH_IDX_0 & path_index) {
2935                 frame = &s_p_dcam_mod->path0_frame[0];
2936                 frame_count = &s_p_dcam_mod->dcam_path0.output_frame_count;
2937         }
2938         if (DCAM_PATH_IDX_1 & path_index) {
2939                 frame = &s_p_dcam_mod->path1_frame[0];
2940                 frame_count = &s_p_dcam_mod->dcam_path1.output_frame_count;
2941         }
2942         if (DCAM_PATH_IDX_2 & path_index) {
2943                 frame = &s_p_dcam_mod->path2_frame[0];
2944                 frame_count = &s_p_dcam_mod->dcam_path2.output_frame_count;
2945         }
2946         printk("DCAM: frame pop index %d frame_count %d addr 0x%x \n", path_index, *frame_count, frame->yaddr);
2947         if (0 == *frame_count) {
2948                 return;
2949         }
2950
2951         for (i = 0; i < *frame_count - 1; i++) {
2952                 memcpy(frame+i, frame+i+1, sizeof(struct dcam_frame));
2953         }
2954         (*frame_count)--;
2955         //memset(frame+(*frame_count), 0, sizeof(struct dcam_frame));
2956         (frame+(*frame_count))->yaddr = 0;
2957         (frame+(*frame_count))->uaddr = 0;
2958         (frame+(*frame_count))->vaddr = 0;
2959
2960         if (0 == *frame_count) {
2961                 //_dcam_wait_for_quickstop(path_index);
2962         }
2963         DCAM_TRACE("DCAM: frame pop done \n");
2964         
2965         return;
2966 }
2967
2968
2969 LOCAL void _dcam_link_frm(uint32_t base_id)
2970 {
2971 /*      uint32_t                i = 0;
2972         struct dcam_frame       *path0_frame = NULL;
2973         struct dcam_frame       *path1_frame = NULL;
2974         struct dcam_frame       *path2_frame = NULL;
2975
2976         DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
2977
2978         path0_frame = &s_p_dcam_mod->path0_frame[0];
2979         path1_frame = &s_p_dcam_mod->path1_frame[0];
2980         path2_frame = &s_p_dcam_mod->path2_frame[0];
2981         for (i = 0; i < DCAM_PATH_0_FRM_CNT_MAX; i++) {
2982                 DCAM_CLEAR(path0_frame + i);
2983                 //(path0_frame+i)->next = path0_frame + (i + 1) % DCAM_PATH_0_FRM_CNT_MAX;
2984                 //(path0_frame+i)->prev = path0_frame + (i - 1 + DCAM_PATH_0_FRM_CNT_MAX) % DCAM_PATH_0_FRM_CNT_MAX;
2985                 (path0_frame+i)->fid  = base_id + i;
2986         }
2987
2988         for (i = 0; i < DCAM_PATH_1_FRM_CNT_MAX; i++) {
2989                 DCAM_CLEAR(path1_frame + i);
2990                 //(path1_frame+i)->next = path1_frame + (i + 1) % DCAM_PATH_1_FRM_CNT_MAX;
2991                 //(path1_frame+i)->prev = path1_frame + (i - 1 + DCAM_PATH_1_FRM_CNT_MAX) % DCAM_PATH_1_FRM_CNT_MAX;
2992                 (path1_frame+i)->fid  = base_id + i;
2993         }
2994
2995         for (i = 0; i < DCAM_PATH_2_FRM_CNT_MAX; i++) {
2996                 DCAM_CLEAR(path2_frame + i);
2997                 //(path2_frame+i)->next = path2_frame+(i + 1) % DCAM_PATH_2_FRM_CNT_MAX;
2998                 //(path2_frame+i)->prev = path2_frame+(i - 1 + DCAM_PATH_2_FRM_CNT_MAX) % DCAM_PATH_2_FRM_CNT_MAX;
2999                 (path2_frame+i)->fid  = base_id + i;
3000         }
3001
3002         //s_p_dcam_mod->dcam_path0.output_frame_head = path0_frame;
3003         //s_p_dcam_mod->dcam_path1.output_frame_head = path1_frame;
3004         //s_p_dcam_mod->dcam_path2.output_frame_head = path2_frame;
3005         //s_p_dcam_mod->dcam_path0.output_frame_cur = path0_frame;
3006         //s_p_dcam_mod->dcam_path1.output_frame_cur = path1_frame;
3007         //s_p_dcam_mod->dcam_path2.output_frame_cur = path2_frame;
3008 */
3009         return;
3010 }
3011
3012 LOCAL int32_t _dcam_path_set_next_frm(enum dcam_path_index path_index, uint32_t is_1st_frm)
3013 {
3014         enum dcam_drv_rtn       rtn = DCAM_RTN_SUCCESS;
3015         struct dcam_frame       frame;
3016         struct dcam_frame       *reserved_frame = NULL;
3017         struct dcam_frame       *orig_frame = NULL;
3018         struct dcam_path_desc   *path = NULL;
3019         uint32_t                yuv_reg[3] = {0};
3020         uint32_t                path_max_frm_cnt;
3021         uint32_t                flag = 0;
3022         struct dcam_frm_queue   *p_heap = NULL;
3023         struct dcam_buf_queue   *p_buf_queue = NULL;
3024
3025         DCAM_CHECK_ZERO(s_p_dcam_mod);
3026
3027         if (DCAM_PATH_IDX_0 == path_index) {
3028                 //frame = &s_p_dcam_mod->path0_frame[0];
3029                 reserved_frame = &s_p_dcam_mod->path0_reserved_frame;
3030                 path = &s_p_dcam_mod->dcam_path0;
3031                 yuv_reg[0] = DCAM_FRM_ADDR0;
3032                 path_max_frm_cnt = DCAM_PATH_0_FRM_CNT_MAX;
3033                 p_heap = &s_p_dcam_mod->dcam_path0.frame_queue;
3034                 p_buf_queue = &s_p_dcam_mod->dcam_path0.buf_queue;
3035         } else if (DCAM_PATH_IDX_1 == path_index) {
3036                 //frame = &s_p_dcam_mod->path1_frame[0];
3037                 reserved_frame = &s_p_dcam_mod->path1_reserved_frame;
3038                 path = &s_p_dcam_mod->dcam_path1;
3039                 yuv_reg[0] = DCAM_FRM_ADDR1;
3040                 yuv_reg[1] = DCAM_FRM_ADDR2;
3041                 yuv_reg[2] = DCAM_FRM_ADDR3;
3042                 path_max_frm_cnt = DCAM_PATH_1_FRM_CNT_MAX;
3043                 p_heap = &s_p_dcam_mod->dcam_path1.frame_queue;
3044                 p_buf_queue = &s_p_dcam_mod->dcam_path1.buf_queue;
3045         } else /*if(DCAM_PATH_IDX_2 == path_index)*/ {
3046                 //frame = &s_p_dcam_mod->path2_frame[0];
3047                 reserved_frame = &s_p_dcam_mod->path2_reserved_frame;
3048                 path = &s_p_dcam_mod->dcam_path2;
3049                 yuv_reg[0] = DCAM_FRM_ADDR4;
3050                 yuv_reg[1] = DCAM_FRM_ADDR5;
3051                 yuv_reg[2] = DCAM_FRM_ADDR6;
3052                 path_max_frm_cnt = DCAM_PATH_2_FRM_CNT_MAX;
3053                 p_heap = &s_p_dcam_mod->dcam_path2.frame_queue;
3054                 p_buf_queue = &s_p_dcam_mod->dcam_path2.buf_queue;
3055         }
3056
3057         if (0 != _dcam_buf_queue_read(p_buf_queue, &frame)) {
3058                 DCAM_TRACE("DCAM: No freed frame id %d \n", frame.fid);
3059                 memcpy(&frame, reserved_frame, sizeof(struct dcam_frame));
3060         }
3061
3062         DCAM_TRACE("DCAM: next %d y 0x%x uv 0x%x \n", path->output_frame_count, frame.yaddr, frame.uaddr);
3063         REG_WR(yuv_reg[0], frame.yaddr);
3064         if ((DCAM_YUV400 > path->output_format) && (DCAM_PATH_IDX_0 != path_index)) {
3065                 REG_WR(yuv_reg[1], frame.uaddr);
3066                 if (DCAM_YUV420_3FRAME == path->output_format) {
3067                         REG_WR(yuv_reg[2], frame.vaddr);
3068                 }
3069         }
3070         dcam_frame_lock(&frame);
3071         if (0 == _dcam_frame_enqueue(p_heap, &frame)) {
3072         } else {
3073                 dcam_frame_unlock(&frame);
3074                 rtn = DCAM_RTN_PATH_FRAME_LOCKED;
3075         }
3076
3077         return -rtn;
3078 }
3079
3080 #if 0
3081 LOCAL int32_t _dcam_path_trim(enum dcam_path_index path_index)
3082 {
3083         enum dcam_drv_rtn       rtn = DCAM_RTN_SUCCESS;
3084         struct dcam_path_desc   *path;
3085         uint32_t                cfg_reg, ctrl_bit;
3086
3087         DCAM_CHECK_ZERO(s_p_dcam_mod);
3088
3089         if (DCAM_PATH_IDX_1 == path_index) {
3090                 path = &s_p_dcam_mod->dcam_path1;
3091                 cfg_reg = DCAM_PATH1_CFG;
3092                 ctrl_bit = 8;
3093         } else if (DCAM_PATH_IDX_2 == path_index) {
3094                 path = &s_p_dcam_mod->dcam_path2;
3095                 cfg_reg = DCAM_PATH2_CFG;
3096                 ctrl_bit = 1;
3097         } else {
3098                 printk("DCAM: _dcam_path_trim invalid path_index=%d \n", path_index);
3099                 return -1;
3100         }
3101
3102         if (path->input_size.w != path->input_rect.w ||
3103                 path->input_size.h != path->input_rect.h) {
3104                 /*REG_OWR(cfg_reg, 1 << ctrl_bit);*/
3105         } else {
3106                 /*REG_MWR(cfg_reg, 1 << ctrl_bit, 0 << ctrl_bit);*/
3107         }
3108
3109         return rtn;
3110
3111 }
3112 #endif
3113
3114 LOCAL int32_t _dcam_path_scaler(enum dcam_path_index path_index)
3115 {
3116         enum dcam_drv_rtn       rtn = DCAM_RTN_SUCCESS;
3117         struct dcam_path_desc   *path = NULL;
3118         uint32_t                cfg_reg = 0;
3119
3120         DCAM_CHECK_ZERO(s_p_dcam_mod);
3121         DCAM_CHECK_ZERO(s_dcam_sc_array);
3122
3123         if (DCAM_PATH_IDX_1 == path_index) {
3124                 path = &s_p_dcam_mod->dcam_path1;
3125                 cfg_reg = DCAM_PATH1_CFG;
3126         } else if (DCAM_PATH_IDX_2 == path_index){
3127                 path = &s_p_dcam_mod->dcam_path2;
3128                 cfg_reg = DCAM_PATH2_CFG;
3129         }
3130
3131         DCAM_CHECK_ZERO(path);
3132         if (DCAM_RAWRGB == path->output_format ||
3133                 DCAM_JPEG == path->output_format) {
3134                 DCAM_TRACE("DCAM: _dcam_path_scaler out format is %d, no need scaler \n", path->output_format);
3135                 return DCAM_RTN_SUCCESS;
3136         }
3137
3138         rtn = _dcam_calc_sc_size(path_index);
3139         if (DCAM_RTN_SUCCESS != rtn) {
3140                 return rtn;
3141         }
3142
3143         if (path->sc_input_size.w == path->output_size.w &&
3144                 path->sc_input_size.h == path->output_size.h &&
3145                 DCAM_YUV422 == path->output_format) {
3146                 REG_MWR(cfg_reg, BIT_20, 1 << 20);// bypass scaler if the output size equals input size for YUV422 format
3147         } else {
3148                 REG_MWR(cfg_reg, BIT_20, 0 << 20);
3149                 if (s_dcam_sc_array->is_smooth_zoom
3150                         && DCAM_PATH_IDX_1 == path_index
3151                         && DCAM_ST_START == path->status) {
3152                         rtn = _dcam_calc_sc_coeff(path_index);
3153                 } else {
3154                         rtn = _dcam_set_sc_coeff(path_index);
3155                 }
3156         }
3157
3158         return rtn;
3159 }
3160
3161 LOCAL int32_t _dcam_path_check_deci(enum dcam_path_index path_index, uint32_t *is_deci)
3162 {
3163         enum dcam_drv_rtn       rtn = DCAM_RTN_SUCCESS;
3164         struct dcam_path_desc   *path = NULL;
3165         uint32_t                                w_deci = 0;
3166         uint32_t                                h_deci = 0;
3167
3168         DCAM_CHECK_ZERO(s_p_dcam_mod);
3169
3170         if (DCAM_PATH_IDX_1 == path_index) {
3171                 path = &s_p_dcam_mod->dcam_path1;
3172         } else if (DCAM_PATH_IDX_2 == path_index) {
3173                 path = &s_p_dcam_mod->dcam_path2;
3174         } else {
3175                 rtn = DCAM_RTN_PATH_SC_ERR;
3176                 goto dcam_path_err;
3177         }
3178
3179         if (path->input_rect.w > (path->output_size.w * DCAM_SC_COEFF_DOWN_MAX * (1<<DCAM_PATH_DECI_FAC_MAX)) ||
3180                 path->input_rect.h > (path->output_size.h * DCAM_SC_COEFF_DOWN_MAX * (1<<DCAM_PATH_DECI_FAC_MAX)) ||
3181                 path->input_rect.w * DCAM_SC_COEFF_UP_MAX < path->output_size.w ||
3182                 path->input_rect.h * DCAM_SC_COEFF_UP_MAX < path->output_size.h) {
3183                 rtn = DCAM_RTN_PATH_SC_ERR;
3184         } else {
3185                 if (path->input_rect.w > path->output_size.w * DCAM_SC_COEFF_DOWN_MAX)
3186                         w_deci = 1;
3187                 if (path->input_rect.h > path->output_size.h * DCAM_SC_COEFF_DOWN_MAX)
3188                         h_deci = 1;
3189
3190                 if(w_deci || h_deci)
3191                         *is_deci = 1;
3192                 else
3193                         *is_deci = 0;
3194         }
3195
3196 dcam_path_err:
3197         DCAM_TRACE("DCAM: _dcam_path_check_deci: path_index=%d, is_deci=%d, rtn=%d \n", path_index, *is_deci, rtn);
3198
3199         return rtn;
3200 }
3201
3202 LOCAL uint32_t _dcam_get_path_deci_factor(uint32_t src_size, uint32_t dst_size)
3203 {
3204         uint32_t                 factor = 0;
3205
3206         if (0 == src_size || 0 == dst_size) {
3207                 return factor;
3208         }
3209
3210         /* factor: 0 - 1/2, 1 - 1/4, 2 - 1/8, 3 - 1/16 */
3211         for (factor = 0; factor < DCAM_PATH_DECI_FAC_MAX; factor ++) {
3212                 if (src_size < (uint32_t)(dst_size * (1 << (factor + 1)))) {
3213                         break;
3214                 }
3215         }
3216
3217         return factor;
3218 }
3219
3220 LOCAL int32_t _dcam_calc_sc_size(enum dcam_path_index path_index)
3221 {
3222         enum dcam_drv_rtn       rtn = DCAM_RTN_SUCCESS;
3223         struct dcam_path_desc   *path = NULL;
3224         uint32_t                cfg_reg = 0;
3225         uint32_t                tmp_dstsize = 0;
3226         uint32_t                align_size = 0;
3227
3228         DCAM_CHECK_ZERO(s_p_dcam_mod);
3229
3230         if (DCAM_PATH_IDX_1 == path_index) {
3231                 path = &s_p_dcam_mod->dcam_path1;
3232                 cfg_reg = DCAM_PATH1_CFG;
3233         } else if (DCAM_PATH_IDX_2 == path_index){
3234                 path = &s_p_dcam_mod->dcam_path2;
3235                 cfg_reg = DCAM_PATH2_CFG;
3236         }
3237
3238         DCAM_CHECK_ZERO(path);
3239         if (path->input_rect.w > (path->output_size.w * DCAM_SC_COEFF_DOWN_MAX * (1<<DCAM_PATH_DECI_FAC_MAX)) ||
3240                 path->input_rect.h > (path->output_size.h * DCAM_SC_COEFF_DOWN_MAX * (1<<DCAM_PATH_DECI_FAC_MAX)) ||
3241                 path->input_rect.w * DCAM_SC_COEFF_UP_MAX < path->output_size.w ||
3242                 path->input_rect.h * DCAM_SC_COEFF_UP_MAX < path->output_size.h) {
3243                 rtn = DCAM_RTN_PATH_SC_ERR;
3244         } else {
3245                 path->sc_input_size.w = path->input_rect.w;
3246                 path->sc_input_size.h = path->input_rect.h;
3247                 if (path->input_rect.w > path->output_size.w * DCAM_SC_COEFF_DOWN_MAX) {
3248                         tmp_dstsize = path->output_size.w * DCAM_SC_COEFF_DOWN_MAX;
3249                         path->deci_val.deci_x = _dcam_get_path_deci_factor(path->input_rect.w, tmp_dstsize);
3250                         path->deci_val.deci_x_en = 1;
3251                         path->valid_param.v_deci = 1;
3252                         align_size = (1 << (path->deci_val.deci_x+1))*DCAM_PIXEL_ALIGN_WIDTH;
3253                         path->input_rect.w = (path->input_rect.w) & ~(align_size-1);
3254                         path->input_rect.x = (path->input_rect.x) & ~(align_size-1);
3255                         path->sc_input_size.w = path->input_rect.w >> (path->deci_val.deci_x+1);
3256                 } else {
3257                         path->deci_val.deci_x = 0;
3258                         path->deci_val.deci_x_en = 0;
3259                         path->valid_param.v_deci = 1;
3260                 }
3261
3262                 if (path->input_rect.h > path->output_size.h * DCAM_SC_COEFF_DOWN_MAX) {
3263                         tmp_dstsize = path->output_size.h * DCAM_SC_COEFF_DOWN_MAX;
3264                         path->deci_val.deci_y = _dcam_get_path_deci_factor(path->input_rect.h, tmp_dstsize);
3265                         path->deci_val.deci_y_en = 1;
3266                         path->valid_param.v_deci = 1;
3267                         align_size = (1 << (path->deci_val.deci_y+1))*DCAM_PIXEL_ALIGN_HEIGHT;
3268                         path->input_rect.h = (path->input_rect.h) & ~(align_size-1);
3269                         path->input_rect.y = (path->input_rect.y) & ~(align_size-1);
3270                         path->sc_input_size.h = path->input_rect.h >> (path->deci_val.deci_y+1);
3271                 } else {
3272                         path->deci_val.deci_y = 0;
3273                         path->deci_val.deci_y_en = 0;
3274                         path->valid_param.v_deci = 1;
3275                 }
3276
3277         }
3278
3279         DCAM_TRACE("DCAM: _dcam_calc_sc_size, path=%d, x_en=%d, deci_x=%d, y_en=%d, deci_y=%d \n",
3280                 path_index, path->deci_val.deci_x_en,
3281                 path->deci_val.deci_x, path->deci_val.deci_y_en,
3282                 path->deci_val.deci_y);
3283
3284         return -rtn;
3285 }
3286
3287 LOCAL int32_t _dcam_set_sc_coeff(enum dcam_path_index path_index)
3288 {
3289         struct dcam_path_desc   *path = NULL;
3290         uint32_t                i = 0;
3291         uint32_t                h_coeff_addr = DCAM_BASE;
3292         uint32_t                v_coeff_addr  = DCAM_BASE;
3293         uint32_t                v_chroma_coeff_addr  = DCAM_BASE;
3294         uint32_t                *tmp_buf = NULL;
3295         uint32_t                *h_coeff = NULL;
3296         uint32_t                *v_coeff = NULL;
3297         uint32_t                *v_chroma_coeff = NULL;
3298         uint32_t                clk_switch_bit = 0;
3299         uint32_t                clk_switch_shift_bit = 0;
3300         uint32_t                clk_status_bit = 0;
3301         uint32_t                ver_tap_reg = 0;
3302         uint32_t                scale2yuv420 = 0;
3303         uint8_t                 y_tap = 0;
3304         uint8_t                 uv_tap = 0;
3305         uint32_t                index = 0;
3306
3307         DCAM_CHECK_ZERO(s_p_dcam_mod);
3308
3309         if (DCAM_PATH_IDX_1 != path_index && DCAM_PATH_IDX_2 != path_index)
3310                 return -DCAM_RTN_PARA_ERR;
3311
3312         if (DCAM_PATH_IDX_1 == path_index) {
3313                 path = &s_p_dcam_mod->dcam_path1;
3314                 h_coeff_addr += DCAM_SC1_H_TAB_OFFSET;
3315                 v_coeff_addr += DCAM_SC1_V_TAB_OFFSET;
3316                 v_chroma_coeff_addr += DCAM_SC1_V_CHROMA_TAB_OFFSET;
3317                 clk_switch_bit = BIT_3;
3318                 clk_switch_shift_bit = 3;
3319                 clk_status_bit = BIT_5;
3320                 ver_tap_reg = DCAM_PATH1_CFG;
3321         } else if (DCAM_PATH_IDX_2 == path_index) {
3322                 path = &s_p_dcam_mod->dcam_path2;
3323                 h_coeff_addr += DCAM_SC2_H_TAB_OFFSET;
3324                 v_coeff_addr += DCAM_SC2_V_TAB_OFFSET;
3325                 v_chroma_coeff_addr += DCAM_SC2_V_CHROMA_TAB_OFFSET;
3326                 clk_switch_bit = BIT_4;
3327                 clk_switch_shift_bit = 4;
3328                 clk_status_bit = BIT_6;
3329                 ver_tap_reg = DCAM_PATH2_CFG;
3330         }
3331
3332         if (DCAM_YUV420 == path->output_format) {
3333             scale2yuv420 = 1;
3334         }
3335
3336         DCAM_TRACE("DCAM: _dcam_set_sc_coeff {%d %d %d %d}, 420=%d \n",
3337                 path->sc_input_size.w,
3338                 path->sc_input_size.h,
3339                 path->output_size.w,
3340                 path->output_size.h, scale2yuv420);
3341
3342
3343         tmp_buf = dcam_get_scale_coeff_addr(&index);
3344
3345         if (NULL == tmp_buf) {
3346                 return -DCAM_RTN_PATH_NO_MEM;
3347         }
3348
3349         h_coeff = tmp_buf;
3350         v_coeff = tmp_buf + (DCAM_SC_COEFF_COEF_SIZE/4);
3351         v_chroma_coeff = v_coeff + (DCAM_SC_COEFF_COEF_SIZE/4);
3352
3353         down(&s_p_dcam_mod->scale_coeff_mem_sema);
3354
3355         if (!(Dcam_GenScaleCoeff((int16_t)path->sc_input_size.w,
3356                 (int16_t)path->sc_input_size.h,
3357                 (int16_t)path->output_size.w,
3358                 (int16_t)path->output_size.h,
3359                 h_coeff,
3360                 v_coeff,
3361                 v_chroma_coeff,
3362                 scale2yuv420,
3363                 &y_tap,
3364                 &uv_tap,
3365                 tmp_buf + (DCAM_SC_COEFF_COEF_SIZE*3/4),
3366                 DCAM_SC_COEFF_TMP_SIZE))) {
3367                 printk("DCAM: _dcam_set_sc_coeff Dcam_GenScaleCoeff error! \n");
3368                 up(&s_p_dcam_mod->scale_coeff_mem_sema);
3369                 return -DCAM_RTN_PATH_GEN_COEFF_ERR;
3370         }
3371
3372         for (i = 0; i < DCAM_SC_COEFF_H_NUM; i++) {
3373                 REG_WR(h_coeff_addr, *h_coeff);
3374                 h_coeff_addr += 4;
3375                 h_coeff++;
3376         }
3377
3378         for (i = 0; i < DCAM_SC_COEFF_V_NUM; i++) {
3379                 REG_WR(v_coeff_addr, *v_coeff);
3380                 v_coeff_addr += 4;
3381                 v_coeff++;
3382         }
3383
3384         for (i = 0; i < DCAM_SC_COEFF_V_CHROMA_NUM; i++) {
3385                 REG_WR(v_chroma_coeff_addr, *v_chroma_coeff);
3386                 v_chroma_coeff_addr += 4;
3387                 v_chroma_coeff++;
3388         }
3389
3390         path->scale_tap.y_tap = y_tap;
3391         path->scale_tap.uv_tap = uv_tap;
3392         path->valid_param.scale_tap = 1;
3393
3394         up(&s_p_dcam_mod->scale_coeff_mem_sema);
3395
3396         return DCAM_RTN_SUCCESS;
3397 }
3398
3399 LOCAL void _dcam_force_copy_ext(enum dcam_path_index path_index, uint32_t path_copy, uint32_t coef_copy)
3400 {
3401         uint32_t         reg_val = 0;
3402
3403         if (DCAM_PATH_IDX_1 == path_index) {
3404                 if(path_copy)
3405                         reg_val |= BIT_10;
3406                 if(coef_copy)
3407                         reg_val |= BIT_14;
3408
3409                 dcam_glb_reg_mwr(DCAM_CONTROL, reg_val, reg_val, DCAM_CONTROL_REG);
3410         } else if(DCAM_PATH_IDX_2 == path_index) {
3411                 if(path_copy)
3412                         reg_val |= BIT_12;
3413                 if(coef_copy)
3414                         reg_val |= BIT_16;
3415
3416                 dcam_glb_reg_mwr(DCAM_CONTROL, reg_val, reg_val, DCAM_CONTROL_REG);
3417         } else {
3418                 DCAM_TRACE("DCAM: _dcam_force_copy_ext invalid path index: %d \n", path_index);
3419         }
3420 }
3421
3422 LOCAL void _dcam_auto_copy_ext(enum dcam_path_index path_index, uint32_t path_copy, uint32_t coef_copy)
3423 {
3424         uint32_t         reg_val = 0;
3425
3426         if (DCAM_PATH_IDX_0 == path_index) {
3427                 if (path_copy)
3428                         reg_val |= BIT_9;
3429                 dcam_glb_reg_mwr(DCAM_CONTROL, reg_val, reg_val, DCAM_CONTROL_REG);
3430         } else if (DCAM_PATH_IDX_1 == path_index) {
3431                 if (path_copy)
3432                         reg_val |= BIT_11;
3433                 if (coef_copy)
3434                         reg_val |= BIT_15;
3435                 dcam_glb_reg_mwr(DCAM_CONTROL, reg_val, reg_val, DCAM_CONTROL_REG);
3436         } else if (DCAM_PATH_IDX_2 == path_index) {
3437                 if (path_copy)
3438                         reg_val |= BIT_13;
3439                 if (coef_copy)
3440                         reg_val |= BIT_17;
3441                 dcam_glb_reg_mwr(DCAM_CONTROL, reg_val, reg_val, DCAM_CONTROL_REG);
3442         } else {
3443                 DCAM_TRACE("DCAM: _dcam_auto_copy_ext invalid path index: %d \n", path_index);
3444         }
3445
3446 }
3447
3448 LOCAL void _dcam_force_copy(enum dcam_path_index path_index)
3449 {
3450         if (DCAM_PATH_IDX_1 == path_index) {
3451                 dcam_glb_reg_mwr(DCAM_CONTROL, BIT_10, 1 << 10, DCAM_CONTROL_REG);
3452         } else if (DCAM_PATH_IDX_2 == path_index) {
3453                 dcam_glb_reg_mwr(DCAM_CONTROL, BIT_12, 1 << 12, DCAM_CONTROL_REG);
3454         } else {
3455                 DCAM_TRACE("DCAM: _dcam_force_copy invalid path index: %d \n", path_index);
3456         }
3457 }
3458
3459 LOCAL void _dcam_auto_copy(enum dcam_path_index path_index)
3460 {
3461         if (DCAM_PATH_IDX_0 == path_index) {
3462                 dcam_glb_reg_mwr(DCAM_CONTROL, BIT_9, 1 << 9, DCAM_CONTROL_REG);
3463         } else if(DCAM_PATH_IDX_1 == path_index) {
3464                 dcam_glb_reg_mwr(DCAM_CONTROL, BIT_11, 1 << 11, DCAM_CONTROL_REG);
3465         } else if(DCAM_PATH_IDX_2 == path_index) {
3466                 dcam_glb_reg_mwr(DCAM_CONTROL, BIT_13, 1 << 13, DCAM_CONTROL_REG);
3467         } else {
3468                 DCAM_TRACE("DCAM: _dcam_auto_copy invalid path index: %d \n", path_index);
3469         }
3470 }
3471
3472 LOCAL void _dcam_reg_trace(void)
3473 {
3474 #ifdef DCAM_DRV_DEBUG
3475         uint32_t                addr = 0;
3476
3477         printk("DCAM: Register list");
3478         for (addr = DCAM_CFG; addr <= CAP_SENSOR_CTRL; addr += 16) {
3479                 printk("\n 0x%x: 0x%x 0x%x 0x%x 0x%x",
3480                         addr,
3481                         REG_RD(addr),
3482                         REG_RD(addr + 4),
3483                         REG_RD(addr + 8),
3484                         REG_RD(addr + 12));
3485         }
3486
3487         printk("\n");
3488 #endif
3489 }
3490
3491 #if 0
3492 LOCAL void    _dcam_sensor_sof(void)
3493 {
3494         dcam_isr_func           user_func = s_user_func[DCAM_SN_SOF];
3495         void                    *data = s_user_data[DCAM_SN_SOF];
3496
3497         DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3498
3499         DCAM_TRACE("DCAM: _sn_sof \n");
3500
3501         if (user_func) {
3502                 (*user_func)(NULL, data);
3503         }
3504
3505         return;
3506 }
3507 #endif
3508
3509 LOCAL void    _dcam_sensor_eof(void)
3510 {
3511         dcam_isr_func           user_func = s_user_func[DCAM_SN_EOF];
3512         void                    *data = s_user_data[DCAM_SN_EOF];
3513
3514         DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3515
3516         DCAM_TRACE("DCAM: _sn_eof \n");
3517
3518         if (user_func) {
3519                 (*user_func)(NULL, data);
3520         }
3521
3522         return;
3523 }
3524
3525 LOCAL void    _dcam_cap_sof(void)
3526 {
3527         dcam_isr_func           user_func = s_user_func[DCAM_CAP_SOF];
3528         void                    *data = s_user_data[DCAM_CAP_SOF];
3529
3530         DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3531
3532         DCAM_TRACE("DCAM: _cap_sof \n");
3533
3534         _dcam_stopped_notice();
3535
3536         if (user_func) {
3537                 (*user_func)(NULL, data);
3538         }
3539
3540         return;
3541 }
3542
3543 LOCAL void    _dcam_cap_eof(void)
3544 {
3545         dcam_isr_func           user_func = s_user_func[DCAM_CAP_EOF];
3546         void                    *data = s_user_data[DCAM_CAP_EOF];
3547
3548         DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3549
3550         if (user_func) {
3551                 (*user_func)(NULL, data);
3552         }
3553
3554         return;
3555 }
3556
3557 LOCAL void    _dcam_path0_done(void)
3558 {
3559         enum dcam_drv_rtn       rtn = DCAM_RTN_SUCCESS;
3560         dcam_isr_func           user_func = s_user_func[DCAM_PATH0_DONE];
3561         void                    *data = s_user_data[DCAM_PATH0_DONE];
3562         struct dcam_path_desc   *path;
3563         struct dcam_frame       frame;
3564
3565         DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3566         path = &s_p_dcam_mod->dcam_path0;
3567         if (0 == path->valide) {
3568                 printk("DCAM: path0 not valid \n");
3569                 return;
3570         }
3571         if (path->need_stop) {
3572                 dcam_glb_reg_awr(DCAM_CFG, ~BIT_0, DCAM_CFG_REG);
3573                 path->need_stop = 0;
3574         }
3575         _dcam_path_done_notice(DCAM_PATH_IDX_0);
3576         DCAM_TRACE("DCAM 0 \n");
3577         rtn = _dcam_path_set_next_frm(DCAM_PATH_IDX_0, false);
3578         if (rtn) {
3579                 printk("DCAM: 0 w \n");
3580                 return;
3581         }
3582         _dcam_auto_copy(DCAM_PATH_IDX_0);
3583
3584         rtn = _dcam_frame_dequeue(&path->frame_queue, &frame);
3585         if (0 == rtn && frame.yaddr != s_p_dcam_mod->path0_reserved_frame.yaddr && 0 != dcam_frame_is_locked(&frame)) {
3586                 frame.width = path->output_size.w;
3587                 frame.height = path->output_size.h;
3588                 if (user_func) {
3589                         (*user_func)(&frame, data);
3590                 }
3591         } else {
3592                 DCAM_TRACE("DCAM: path0_reserved_frame \n");
3593         }
3594
3595         return;
3596 }
3597
3598 LOCAL void    _dcam_path0_overflow(void)
3599 {
3600         dcam_isr_func           user_func = s_user_func[DCAM_PATH0_OV];
3601         void                    *data = s_user_data[DCAM_PATH0_OV];
3602         struct dcam_path_desc   *path;
3603         struct dcam_frame       frame;
3604
3605         DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3606
3607         printk("DCAM: _path0_overflow \n");
3608         path = &s_p_dcam_mod->dcam_path0;
3609         //frame = path->output_frame_cur->prev->prev;
3610         //frame = &s_p_dcam_mod->path0_frame[0];
3611         _dcam_frame_dequeue(&path->frame_queue, &frame);
3612
3613         if (user_func) {
3614                 (*user_func)(&frame, data);
3615         }
3616
3617         return;
3618 }
3619
3620 LOCAL void    _dcam_path1_done(void)
3621 {
3622         enum dcam_drv_rtn       rtn = DCAM_RTN_SUCCESS;
3623         dcam_isr_func           user_func = s_user_func[DCAM_PATH1_DONE];
3624         void                    *data = s_user_data[DCAM_PATH1_DONE];
3625         struct dcam_path_desc   *path;
3626         struct dcam_frame       frame;
3627
3628         DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3629         path = &s_p_dcam_mod->dcam_path1;
3630         if (0 == path->valide) {
3631                 printk("DCAM: path1 not valid \n");
3632                 return;
3633         }
3634
3635         DCAM_TRACE("DCAM: 1\n");
3636
3637         if (path->need_stop) {
3638                 dcam_glb_reg_awr(DCAM_CFG, ~BIT_1, DCAM_CFG_REG);
3639                 path->need_stop = 0;
3640         }
3641         _dcam_path_done_notice(DCAM_PATH_IDX_1);
3642
3643         if (path->sof_cnt < 1) {
3644                 printk("DCAM: path1 done cnt %d\n", path->sof_cnt);
3645                 path->need_wait = 0;
3646                 return;
3647         }
3648         path->sof_cnt = 0;
3649
3650         if (path->need_wait) {
3651                 path->need_wait = 0;
3652         } else {
3653                 rtn = _dcam_frame_dequeue(&path->frame_queue, &frame);
3654                 if (0 == rtn && frame.yaddr != s_p_dcam_mod->path1_reserved_frame.yaddr && 0 != dcam_frame_is_locked(&frame)) {
3655                         frame.width = path->output_size.w;
3656                         frame.height = path->output_size.h;
3657                         DCAM_TRACE("DCAM: path1 frame 0x%x, y uv, 0x%x 0x%x \n",
3658                                 (int)&frame, frame.yaddr, frame.uaddr);
3659                         if (user_func) {
3660                                 (*user_func)(&frame, data);
3661                         }
3662                 } else {
3663                         DCAM_TRACE("DCAM: path1_reserved_frame \n");
3664                 }
3665         }
3666         return;
3667 }
3668
3669 LOCAL void    _dcam_path1_overflow(void)
3670 {
3671         dcam_isr_func           user_func = s_user_func[DCAM_PATH1_OV];
3672         void                    *data = s_user_data[DCAM_PATH1_OV];
3673         struct dcam_path_desc   *path;
3674         struct dcam_frame       frame;
3675
3676         DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3677
3678         printk("DCAM: _path1_overflow \n");
3679         path = &s_p_dcam_mod->dcam_path1;
3680         //frame = path->output_frame_cur->prev->prev;
3681         _dcam_frame_dequeue(&path->frame_queue, &frame);
3682
3683         if (user_func) {
3684                 (*user_func)(&frame, data);
3685         }
3686
3687         return;
3688 }
3689
3690 LOCAL void    _dcam_sensor_line_err(void)
3691 {
3692         dcam_isr_func           user_func = s_user_func[DCAM_SN_LINE_ERR];
3693         void                    *data = s_user_data[DCAM_SN_LINE_ERR];
3694
3695         DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3696
3697         printk("DCAM: _line_err \n");
3698
3699         if (user_func) {
3700                 (*user_func)(NULL, data);
3701         }
3702
3703         return;
3704 }
3705
3706 LOCAL void    _dcam_sensor_frame_err(void)
3707 {
3708         dcam_isr_func           user_func = s_user_func[DCAM_SN_FRAME_ERR];
3709         void                    *data = s_user_data[DCAM_SN_FRAME_ERR];
3710
3711         DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3712
3713         printk("DCAM: _frame_err \n");
3714
3715         if (user_func) {
3716                 (*user_func)(NULL, data);
3717         }
3718
3719         return;
3720 }
3721
3722 LOCAL void    _dcam_jpeg_buf_ov(void)
3723 {
3724         dcam_isr_func           user_func = s_user_func[DCAM_JPEG_BUF_OV];
3725         void                    *data = s_user_data[DCAM_JPEG_BUF_OV];
3726         struct dcam_path_desc   *path;
3727         struct dcam_frame       frame;
3728
3729         DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3730
3731         printk("DCAM: _jpeg_overflow \n");
3732         path = &s_p_dcam_mod->dcam_path0;
3733         //frame = path->output_frame_cur->prev->prev;
3734         //frame = &s_p_dcam_mod->path0_frame[0];
3735         _dcam_frame_dequeue(&path->frame_queue, &frame);
3736
3737         if (user_func) {
3738                 (*user_func)(&frame, data);
3739         }
3740
3741         return;
3742 }
3743
3744 LOCAL void    _dcam_path2_done(void)
3745 {
3746         enum dcam_drv_rtn       rtn = DCAM_RTN_SUCCESS;
3747         dcam_isr_func           user_func = s_user_func[DCAM_PATH2_DONE];
3748         void                    *data = s_user_data[DCAM_PATH2_DONE];
3749         struct dcam_path_desc   *path;
3750         struct dcam_frame       frame;
3751
3752         if (atomic_read(&s_resize_flag)) {
3753                 memset(&frame, 0, sizeof(struct dcam_frame));
3754                 if (user_func) {
3755                         (*user_func)(&frame, data);
3756                 }
3757         } else {
3758                 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3759                 path = &s_p_dcam_mod->dcam_path2;
3760
3761                 DCAM_TRACE("DCAM: 2, %d %d \n", path->need_stop, path->need_wait);
3762                 if (path->status == DCAM_ST_START) {
3763
3764                         if (path->need_stop) {
3765                                 dcam_glb_reg_awr(DCAM_CFG, ~BIT_2, DCAM_CFG_REG);
3766                                 path->need_stop = 0;
3767                         }
3768                         _dcam_path_done_notice(DCAM_PATH_IDX_2);
3769
3770                         if (path->sof_cnt < 1) {
3771                                 printk("DCAM: path2 done cnt %d\n", path->sof_cnt);
3772                                 path->need_wait = 0;
3773                                 return;
3774                         }
3775                         path->sof_cnt = 0;
3776
3777                         if (path->need_wait) {
3778                                 path->need_wait = 0;
3779                         } else {
3780                                 rtn = _dcam_frame_dequeue(&path->frame_queue, &frame);
3781                                 if (0 == rtn && frame.yaddr != s_p_dcam_mod->path2_reserved_frame.yaddr && 0 != dcam_frame_is_locked(&frame)) {
3782                                         DCAM_TRACE("DCAM: path2 frame 0x%x, y uv, 0x%x 0x%x \n",
3783                                                 (int)&frame, frame.yaddr, frame.uaddr);
3784                                         frame.width = path->output_size.w;
3785                                         frame.height = path->output_size.h;
3786                                         if (user_func) {
3787                                                 (*user_func)(&frame, data);
3788                                         }
3789                                 } else {
3790                                         DCAM_TRACE("DCAM: path2_reserved_frame \n");
3791                                 }
3792                         }
3793                 }
3794         }
3795 }
3796
3797 LOCAL void    _dcam_path2_ov(void)
3798 {
3799         dcam_isr_func           user_func = s_user_func[DCAM_PATH2_OV];
3800         void                    *data = s_user_data[DCAM_PATH2_OV];
3801         struct dcam_path_desc   *path;
3802         struct dcam_frame       frame;
3803
3804         DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3805
3806         printk("DCAM: _path2_overflow \n");
3807         path = &s_p_dcam_mod->dcam_path2;
3808         //frame = path->output_frame_cur->prev->prev;
3809         //frame = &s_p_dcam_mod->path2_frame[0];
3810         _dcam_frame_dequeue(&path->frame_queue, &frame);
3811
3812         if (user_func) {
3813                 (*user_func)(&frame, data);
3814         }
3815
3816         return;
3817 }
3818
3819 LOCAL void    _dcam_isp_ov(void)
3820 {
3821         dcam_isr_func           user_func = s_user_func[DCAM_ISP_OV];
3822         void                    *data = s_user_data[DCAM_ISP_OV];
3823
3824         DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3825
3826         printk("DCAM: _isp_overflow \n");
3827
3828         if (user_func) {
3829                 (*user_func)(NULL, data);
3830         }
3831
3832         return;
3833 }
3834
3835 LOCAL void    _dcam_mipi_ov(void)
3836 {
3837         dcam_isr_func           user_func = s_user_func[DCAM_MIPI_OV];
3838         void                    *data = s_user_data[DCAM_MIPI_OV];
3839
3840         DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3841
3842
3843         if (user_func) {
3844                 (*user_func)(NULL, data);
3845         }
3846
3847         printk("DCAM: _mipi_overflow \n");
3848         return;
3849 }
3850
3851 LOCAL void    _dcam_rot_done(void)
3852 {
3853         dcam_isr_func           user_func = s_user_func[DCAM_ROT_DONE];
3854         void                    *data = s_user_data[DCAM_ROT_DONE];
3855
3856         DCAM_TRACE("DCAM: rot_done \n");
3857
3858         if (user_func) {
3859                 (*user_func)(NULL, data);
3860         }
3861
3862         return;
3863 }
3864
3865 LOCAL void    _dcam_path1_slice_done(void)
3866 {
3867         dcam_isr_func           user_func = s_user_func[DCAM_PATH1_SLICE_DONE];
3868         void                    *data = s_user_data[DCAM_PATH1_SLICE_DONE];
3869
3870         DCAM_TRACE("DCAM: 1 slice done \n");
3871
3872         if (user_func) {
3873                 (*user_func)(NULL, data);
3874         }
3875
3876         return;
3877 }
3878
3879 LOCAL void    _dcam_path2_slice_done(void)
3880 {
3881         dcam_isr_func           user_func = s_user_func[DCAM_PATH2_SLICE_DONE];
3882         void                    *data = s_user_data[DCAM_PATH2_SLICE_DONE];
3883
3884         DCAM_TRACE("DCAM: 2 slice done \n");
3885
3886         if (user_func) {
3887                 (*user_func)(NULL, data);
3888         }
3889
3890         return;
3891 }
3892
3893 LOCAL void    _dcam_raw_slice_done(void)
3894 {
3895         dcam_isr_func           user_func = s_user_func[DCAM_RAW_SLICE_DONE];
3896         void                    *data = s_user_data[DCAM_RAW_SLICE_DONE];
3897
3898         DCAM_TRACE("DCAM: 0 slice done \n");
3899
3900         if (user_func) {
3901                 (*user_func)(NULL, data);
3902         }
3903
3904         return;
3905 }
3906
3907 LOCAL void    _dcam_path1_sof(void)
3908 {
3909         enum dcam_drv_rtn       rtn = DCAM_RTN_SUCCESS;
3910         dcam_isr_func           user_func = s_user_func[DCAM_PATH1_SOF];
3911         void                    *data = s_user_data[DCAM_PATH1_SOF];
3912         struct dcam_path_desc   *path;
3913         struct dcam_sc_coeff    *sc_coeff;
3914
3915         DCAM_TRACE("DCAM: 1 sof done \n");
3916
3917         DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3918         DCAM_CHECK_ZERO_VOID(s_dcam_sc_array);
3919
3920         if(s_p_dcam_mod->dcam_path1.status == DCAM_ST_START){
3921
3922                 path = &s_p_dcam_mod->dcam_path1;
3923                 if (0 == path->valide) {
3924                         printk("DCAM: path1 not valid \n");
3925                         return;
3926                 }
3927
3928                 if (path->sof_cnt > 0) {
3929                         printk("DCAM: path1 sof %d \n", path->sof_cnt);
3930                         return;
3931                 } else {
3932                         path->sof_cnt++;
3933                 }
3934
3935                 rtn = _dcam_path_set_next_frm(DCAM_PATH_IDX_1, false);
3936                 if (path->is_update) {
3937                         if (s_dcam_sc_array->is_smooth_zoom) {
3938                                 _dcam_get_valid_sc_coeff(s_dcam_sc_array, &sc_coeff);
3939                                 _dcam_write_sc_coeff(DCAM_PATH_IDX_1);
3940                                 _dcam_path1_set(&sc_coeff->dcam_path1);
3941                                 _dcam_pop_sc_buf(s_dcam_sc_array, &sc_coeff);
3942                         } else {
3943                                 _dcam_path1_set(path);
3944                         }
3945                         path->is_update = 0;
3946                         DCAM_TRACE("DCAM: path1 updated \n");
3947                         _dcam_auto_copy_ext(DCAM_PATH_IDX_1, true, true);
3948                 } else {
3949                         if (rtn) {
3950                                 DCAM_TRACE("DCAM: path1 updated \n");
3951                         } else {
3952                                 _dcam_auto_copy(DCAM_PATH_IDX_1);
3953                         }
3954                 }
3955
3956                 _dcam_path_updated_notice(DCAM_PATH_IDX_1);
3957
3958                 if (rtn) {
3959                         path->need_wait = 1;
3960                         printk("DCAM: 1 w\n");
3961                         return;
3962                 }
3963         }
3964
3965         if (user_func) {
3966                 (*user_func)(NULL, data);
3967         }
3968
3969         return;
3970 }
3971
3972 LOCAL void    _dcam_path2_sof(void)
3973 {
3974         enum dcam_drv_rtn       rtn = DCAM_RTN_SUCCESS;
3975         dcam_isr_func           user_func = s_user_func[DCAM_PATH2_SOF];
3976         void                    *data = s_user_data[DCAM_PATH2_SOF];
3977         struct dcam_path_desc   *path;
3978
3979         DCAM_TRACE("DCAM: 2 sof done \n");
3980
3981         if (atomic_read(&s_resize_flag)) {
3982                 printk("DCAM: path 2  sof, review now \n");
3983         } else {
3984                 if (DCAM_ADDR_INVALID(s_p_dcam_mod)) {
3985                         return;
3986                 }
3987
3988                 if(s_p_dcam_mod->dcam_path2.status == DCAM_ST_START){
3989
3990                         path = &s_p_dcam_mod->dcam_path2;
3991                         if (0 == path->valide) {
3992                                 printk("DCAM: path2 not valid \n");
3993                                 return;
3994                         }
3995
3996                         if (path->sof_cnt > 0) {
3997                                 printk("DCAM: path2 sof %d \n", path->sof_cnt);
3998                                 return;
3999                         } else {
4000                                 path->sof_cnt++;
4001                         }
4002
4003                         rtn = _dcam_path_set_next_frm(DCAM_PATH_IDX_2, false);
4004                         if (path->is_update) {
4005                                 _dcam_path2_set();
4006                                 path->is_update = 0;
4007                                 DCAM_TRACE("DCAM: path2 updated \n");
4008                                 _dcam_auto_copy_ext(DCAM_PATH_IDX_2, true, true);
4009                         } else {
4010                                 if (rtn) {
4011                                         DCAM_TRACE("DCAM: path2 updated \n");
4012                                 } else {
4013                                         _dcam_auto_copy(DCAM_PATH_IDX_2);
4014                                 }
4015                         }
4016
4017                         _dcam_path_updated_notice(DCAM_PATH_IDX_2);
4018
4019                         if (rtn) {
4020                                 path->need_wait = 1;
4021                                 printk("DCAM:2 w \n");
4022                                 return;
4023                         }
4024                 }
4025         }
4026
4027         if (user_func) {
4028                 (*user_func)(NULL, data);
4029         }
4030
4031         return;
4032 }
4033
4034 LOCAL int32_t    _dcam_err_pre_proc(void)
4035 {
4036         DCAM_CHECK_ZERO(s_p_dcam_mod);
4037
4038         DCAM_TRACE("DCAM: state in err_pre_proc  0x%x,",s_p_dcam_mod->state);
4039         if (s_p_dcam_mod->state & DCAM_STATE_QUICKQUIT)
4040                 return -1;
4041
4042         s_p_dcam_mod->err_happened = 1;
4043         printk("DCAM: err, 0x%x, ISP int 0x%x \n",
4044                 REG_RD(DCAM_INT_STS),
4045                 REG_RD(SPRD_ISP_BASE + 0x2080));
4046
4047         _dcam_reg_trace();
4048         dcam_glb_reg_mwr(DCAM_CONTROL, BIT_2, 0, DCAM_CONTROL_REG); /* Cap Disable */
4049         _dcam_stopped();
4050         if (0 == atomic_read(&s_resize_flag) &&
4051                 0 == atomic_read(&s_rotation_flag)) {
4052                         dcam_reset(DCAM_RST_ALL, 1);
4053         }
4054         return 0;
4055 }
4056
4057 LOCAL void    _dcam_stopped(void)
4058 {
4059         DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
4060
4061         DCAM_TRACE("DCAM: stopped, %d \n", s_p_dcam_mod->wait_stop);
4062
4063         _dcam_path_done_notice(DCAM_PATH_IDX_0);
4064         _dcam_path_done_notice(DCAM_PATH_IDX_1);
4065         _dcam_path_done_notice(DCAM_PATH_IDX_2);
4066         _dcam_stopped_notice();
4067         return;
4068 }
4069
4070 LOCAL int  _dcam_internal_init(void)
4071 {
4072         int                     ret = 0;
4073
4074         s_p_dcam_mod = (struct dcam_module*)vzalloc(sizeof(struct dcam_module));
4075
4076         DCAM_CHECK_ZERO(s_p_dcam_mod);
4077
4078         sema_init(&s_p_dcam_mod->stop_sema, 0);
4079         sema_init(&s_p_dcam_mod->dcam_path0.tx_done_sema, 0);
4080         sema_init(&s_p_dcam_mod->dcam_path1.tx_done_sema, 0);
4081         sema_init(&s_p_dcam_mod->dcam_path2.tx_done_sema, 0);
4082         sema_init(&s_p_dcam_mod->dcam_path0.sof_sema, 0);
4083         sema_init(&s_p_dcam_mod->dcam_path1.sof_sema, 0);
4084         sema_init(&s_p_dcam_mod->dcam_path2.sof_sema, 0);
4085         sema_init(&s_p_dcam_mod->resize_done_sema, 0);
4086         sema_init(&s_p_dcam_mod->rotation_done_sema, 0);
4087         sema_init(&s_p_dcam_mod->scale_coeff_mem_sema, 1);
4088
4089         memset((void*)s_dcam_sc_array, 0, sizeof(struct dcam_sc_array));
4090         return ret;
4091 }
4092 LOCAL void _dcam_internal_deinit(void)
4093 {
4094         unsigned long flag;
4095
4096         spin_lock_irqsave(&dcam_mod_lock, flag);
4097         if (DCAM_ADDR_INVALID(s_p_dcam_mod)) {
4098                 printk("DCAM: Invalid addr, 0x%x", (uint32_t)s_p_dcam_mod);
4099         } else {
4100                 vfree(s_p_dcam_mod);
4101                 s_p_dcam_mod = NULL;
4102         }
4103         spin_unlock_irqrestore(&dcam_mod_lock, flag);
4104         return;
4105 }
4106
4107 LOCAL void _dcam_wait_path_done(enum dcam_path_index path_index, uint32_t *p_flag)
4108 {
4109         int                     ret = 0;
4110         struct dcam_path_desc   *p_path = NULL;
4111         unsigned long           flag;
4112
4113         DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
4114
4115         if (s_p_dcam_mod->err_happened) {
4116                 return;
4117         }
4118         if (DCAM_CAPTURE_MODE_SINGLE == s_p_dcam_mod->dcam_mode) {
4119                 return;
4120         }
4121         if (DCAM_PATH_IDX_0 == path_index) {
4122                 p_path = &s_p_dcam_mod->dcam_path0;
4123         } else if (DCAM_PATH_IDX_1 == path_index) {
4124                 p_path = &s_p_dcam_mod->dcam_path1;
4125         } else if (DCAM_PATH_IDX_2 == path_index) {
4126                 p_path = &s_p_dcam_mod->dcam_path2;
4127         } else {
4128                 printk("DCAM: Wrong index 0x%x \n", path_index);
4129                 return;
4130         }
4131         DCAM_TRACE("DCAM: path done wait %d, %d \n", p_path->wait_for_done, p_path->tx_done_sema.count);
4132
4133         spin_lock_irqsave(&dcam_lock, flag);
4134         if (p_flag) {
4135                 *p_flag = 1;
4136         }
4137         p_path->wait_for_done = 1;
4138         spin_unlock_irqrestore(&dcam_lock, flag);
4139         ret = down_timeout(&p_path->tx_done_sema, DCAM_PATH_TIMEOUT);
4140         if (ret) {
4141                 _dcam_reg_trace();
4142                 printk("DCAM: Failed to wait path 0x%x done \n", path_index);
4143         }
4144
4145         return;
4146 }
4147
4148 LOCAL void _dcam_path_done_notice(enum dcam_path_index path_index)
4149 {
4150         struct dcam_path_desc   *p_path = NULL;
4151
4152         DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
4153
4154         if (DCAM_PATH_IDX_0 == path_index) {
4155                 p_path = &s_p_dcam_mod->dcam_path0;
4156         } else if(DCAM_PATH_IDX_1 == path_index) {
4157                 p_path = &s_p_dcam_mod->dcam_path1;
4158         } else if(DCAM_PATH_IDX_2 == path_index) {
4159                 p_path = &s_p_dcam_mod->dcam_path2;
4160         } else {
4161                 printk("DCAM: Wrong index 0x%x \n", path_index);
4162                 return;
4163         }
4164         DCAM_TRACE("DCAM: path done notice %d, %d \n", p_path->wait_for_done, p_path->tx_done_sema.count);
4165         if (p_path->wait_for_done) {
4166                 up(&p_path->tx_done_sema);
4167                 p_path->wait_for_done = 0;
4168         }
4169
4170         return;
4171 }
4172
4173 LOCAL void _dcam_wait_update_done(enum dcam_path_index path_index, uint32_t *p_flag)
4174 {
4175         int                     ret = 0;
4176         struct dcam_path_desc   *p_path = NULL;
4177         unsigned long           flag;
4178
4179         DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
4180
4181         if (s_p_dcam_mod->err_happened) {
4182                 return;
4183         }
4184         if (DCAM_CAPTURE_MODE_SINGLE == s_p_dcam_mod->dcam_mode) {
4185                 return;
4186         }
4187         if (DCAM_PATH_IDX_0 == path_index) {
4188                 p_path = &s_p_dcam_mod->dcam_path0;
4189         } else if (DCAM_PATH_IDX_1 == path_index) {
4190                 p_path = &s_p_dcam_mod->dcam_path1;
4191         } else if (DCAM_PATH_IDX_2 == path_index) {
4192                 p_path = &s_p_dcam_mod->dcam_path2;
4193         } else {
4194                 printk("DCAM: Wrong index 0x%x \n", path_index);
4195                 return;
4196         }
4197         DCAM_TRACE("DCAM: path done wait %d, %d \n", p_path->wait_for_done, p_path->tx_done_sema.count);
4198
4199         spin_lock_irqsave(&dcam_lock, flag);
4200         if (p_flag) {
4201                 *p_flag = 1;
4202         }
4203         p_path->wait_for_sof = 1;
4204         spin_unlock_irqrestore(&dcam_lock, flag);
4205         ret = down_timeout(&p_path->sof_sema, DCAM_PATH_TIMEOUT);
4206         if (ret) {
4207                 _dcam_reg_trace();
4208                 printk("DCAM: Failed to wait update path 0x%x done \n", path_index);
4209         }
4210
4211         return;
4212 }
4213
4214 LOCAL void _dcam_path_updated_notice(enum dcam_path_index path_index)
4215 {
4216         struct dcam_path_desc   *p_path = NULL;
4217
4218         DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
4219
4220         if (DCAM_PATH_IDX_0 == path_index) {
4221                 p_path = &s_p_dcam_mod->dcam_path0;
4222         } else if(DCAM_PATH_IDX_1 == path_index) {
4223                 p_path = &s_p_dcam_mod->dcam_path1;
4224         } else if(DCAM_PATH_IDX_2 == path_index) {
4225                 p_path = &s_p_dcam_mod->dcam_path2;
4226         } else {
4227                 printk("DCAM: Wrong index 0x%x \n", path_index);
4228                 return;
4229         }
4230         DCAM_TRACE("DCAM: path done notice %d, %d \n", p_path->wait_for_done, p_path->tx_done_sema.count);
4231         if (p_path->wait_for_sof) {
4232                 up(&p_path->sof_sema);
4233                 p_path->wait_for_sof = 0;
4234         }
4235
4236         return;
4237 }
4238
4239
4240 LOCAL void _dcam_stopped_notice(void)
4241 {
4242         DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
4243
4244         if (s_p_dcam_mod->wait_stop) {
4245                 up(&s_p_dcam_mod->stop_sema);
4246                 s_p_dcam_mod->wait_stop = 0;
4247         }
4248 }
4249
4250 void mm_clk_register_trace(void)
4251 {
4252    uint32_t i = 0;
4253    printk("REG_AON_APB_APB_EB0 = 0x%x \n",REG_RD(REG_AON_APB_APB_EB0));
4254    printk("REG_PMU_APB_PD_MM_TOP_CFG = 0x%x \n",REG_RD(REG_PMU_APB_PD_MM_TOP_CFG));
4255    printk("REG_PMU_APB_CP_SOFT_RST = 0x%x \n",REG_RD(REG_PMU_APB_CP_SOFT_RST));
4256         if(!(REG_RD(REG_AON_APB_APB_EB0)&BIT_MM_EB) ) return ;
4257         if(REG_RD(REG_PMU_APB_PD_MM_TOP_CFG)&BIT_PD_MM_TOP_FORCE_SHUTDOWN) return ;
4258
4259    printk("mm_clk_reg, part 1 \n");
4260    for (i = 0 ; i <= 0x10; i += 4 ) {
4261                 printk("MMAHB: %x val:%x \b\n",
4262                         (SPRD_MMAHB_BASE + i),
4263                         REG_RD(SPRD_MMAHB_BASE + i));
4264    }
4265
4266    printk("mm_clk_reg, part 2 \n");
4267    for (i = 0x20 ; i <= 0x38; i += 4 ) {
4268                 printk("MMCKG: %x val:%x \b\n",
4269                         (SPRD_MMCKG_BASE + i),
4270                         REG_RD(SPRD_MMCKG_BASE + i));
4271    }
4272 }
4273
4274 int32_t dcam_stop_sc_coeff(void)
4275 {
4276         uint32_t zoom_mode;
4277
4278         DCAM_CHECK_ZERO(s_dcam_sc_array);
4279
4280         zoom_mode = s_dcam_sc_array->is_smooth_zoom;
4281         /*memset((void*)s_dcam_sc_array, 0, sizeof(struct dcam_sc_array));*/
4282         s_dcam_sc_array->is_smooth_zoom = zoom_mode;
4283         s_dcam_sc_array->valid_cnt = 0;
4284         memset(&s_dcam_sc_array->scaling_coeff_queue, 0, DCAM_SC_COEFF_BUF_COUNT*sizeof(struct dcam_sc_coeff *));
4285
4286         return 0;
4287 }
4288
4289 LOCAL int32_t _dcam_get_valid_sc_coeff(struct dcam_sc_array *sc, struct dcam_sc_coeff **sc_coeff)
4290 {
4291         if (DCAM_ADDR_INVALID(sc) || DCAM_ADDR_INVALID(sc_coeff)) {
4292                 printk("DCAM: get valid sc, invalid param 0x%x, 0x%x \n",
4293                         (uint32_t)sc,
4294                         (uint32_t)sc_coeff);
4295                 return -1;
4296         }
4297         if (sc->valid_cnt == 0) {
4298                 printk("DCAM: valid cnt 0 \n");
4299                 return -1;
4300         }
4301
4302         *sc_coeff  = sc->scaling_coeff_queue[0];
4303         DCAM_TRACE("DCAM: get valid sc, %d \n", sc->valid_cnt);
4304         return 0;
4305 }
4306
4307
4308 LOCAL int32_t _dcam_push_sc_buf(struct dcam_sc_array *sc, uint32_t index)
4309 {
4310         if (DCAM_ADDR_INVALID(sc)) {
4311                 printk("DCAM: push sc, invalid param 0x%x \n",
4312                         (uint32_t)sc);
4313                 return -1;
4314         }
4315         if (sc->valid_cnt >= DCAM_SC_COEFF_BUF_COUNT) {
4316                 printk("DCAM: valid cnt %d \n", sc->valid_cnt);
4317                 return -1;
4318         }
4319
4320         sc->scaling_coeff[index].flag = 1;
4321         sc->scaling_coeff_queue[sc->valid_cnt] = &sc->scaling_coeff[index];
4322         sc->valid_cnt ++;
4323
4324         DCAM_TRACE("DCAM: push sc, %d \n", sc->valid_cnt);
4325
4326         return 0;
4327 }
4328
4329 LOCAL int32_t _dcam_pop_sc_buf(struct dcam_sc_array *sc, struct dcam_sc_coeff **sc_coeff)
4330 {
4331         uint32_t                i = 0;
4332
4333         if (DCAM_ADDR_INVALID(sc) || DCAM_ADDR_INVALID(sc_coeff)) {
4334                 printk("DCAM: pop sc, invalid param 0x%x, 0x%x \n",
4335                         (uint32_t)sc,
4336                         (uint32_t)sc_coeff);
4337                 return -1;
4338         }
4339         if (sc->valid_cnt == 0) {
4340                 printk("DCAM: valid cnt 0 \n");
4341                 return -1;
4342         }
4343         sc->scaling_coeff_queue[0]->flag = 0;
4344         *sc_coeff  = sc->scaling_coeff_queue[0];
4345         sc->valid_cnt--;
4346         for (i = 0; i < sc->valid_cnt; i++) {
4347                 sc->scaling_coeff_queue[i] = sc->scaling_coeff_queue[i+1];
4348         }
4349         DCAM_TRACE("DCAM: pop sc, %d \n", sc->valid_cnt);
4350         return 0;
4351 }
4352
4353 LOCAL int32_t _dcam_write_sc_coeff(enum dcam_path_index path_index)
4354 {
4355         int32_t                 ret = 0;
4356         struct dcam_path_desc   *path = NULL;
4357         uint32_t                i = 0;
4358         uint32_t                h_coeff_addr = DCAM_BASE;
4359         uint32_t                v_coeff_addr  = DCAM_BASE;
4360         uint32_t                v_chroma_coeff_addr  = DCAM_BASE;
4361         uint32_t                *tmp_buf = NULL;
4362         uint32_t                *h_coeff = NULL;
4363         uint32_t                *v_coeff = NULL;
4364         uint32_t                *v_chroma_coeff = NULL;
4365         uint32_t                clk_switch_bit = 0;
4366         uint32_t                clk_switch_shift_bit = 0;
4367         uint32_t                clk_status_bit = 0;
4368         uint32_t                ver_tap_reg = 0;
4369         uint32_t                scale2yuv420 = 0;
4370         struct dcam_sc_coeff    *sc_coeff;
4371
4372         DCAM_CHECK_ZERO(s_p_dcam_mod);
4373         DCAM_CHECK_ZERO(s_dcam_sc_array);
4374
4375         if (DCAM_PATH_IDX_1 != path_index && DCAM_PATH_IDX_2 != path_index)
4376                 return -DCAM_RTN_PARA_ERR;
4377
4378         ret = _dcam_get_valid_sc_coeff(s_dcam_sc_array, &sc_coeff);
4379         if (ret) {
4380                 return -DCAM_RTN_PATH_NO_MEM;
4381         }
4382         tmp_buf = sc_coeff->buf;
4383         if (NULL == tmp_buf) {
4384                 return -DCAM_RTN_PATH_NO_MEM;
4385         }
4386
4387         h_coeff = tmp_buf;
4388         v_coeff = tmp_buf + (DCAM_SC_COEFF_COEF_SIZE/4);
4389         v_chroma_coeff = v_coeff + (DCAM_SC_COEFF_COEF_SIZE/4);
4390
4391         if (DCAM_PATH_IDX_1 == path_index) {
4392                 path = &sc_coeff->dcam_path1;
4393                 h_coeff_addr += DCAM_SC1_H_TAB_OFFSET;
4394                 v_coeff_addr += DCAM_SC1_V_TAB_OFFSET;
4395                 v_chroma_coeff_addr += DCAM_SC1_V_CHROMA_TAB_OFFSET;
4396                 clk_switch_bit = BIT_3;
4397                 clk_switch_shift_bit = 3;
4398                 clk_status_bit = BIT_5;
4399                 ver_tap_reg = DCAM_PATH1_CFG;
4400         } else if (DCAM_PATH_IDX_2 == path_index) {
4401                 path = &s_p_dcam_mod->dcam_path2;
4402                 h_coeff_addr += DCAM_SC2_H_TAB_OFFSET;
4403                 v_coeff_addr += DCAM_SC2_V_TAB_OFFSET;
4404                 v_chroma_coeff_addr += DCAM_SC2_V_CHROMA_TAB_OFFSET;
4405                 clk_switch_bit = BIT_4;
4406                 clk_switch_shift_bit = 4;
4407                 clk_status_bit = BIT_6;
4408                 ver_tap_reg = DCAM_PATH2_CFG;
4409         }
4410
4411         if (DCAM_YUV420 == path->output_format) {
4412             scale2yuv420 = 1;
4413         }
4414
4415         DCAM_TRACE("DCAM: _dcam_write_sc_coeff {%d %d %d %d}, 420=%d \n",
4416                 path->sc_input_size.w,
4417                 path->sc_input_size.h,
4418                 path->output_size.w,
4419                 path->output_size.h, scale2yuv420);
4420
4421         for (i = 0; i < DCAM_SC_COEFF_H_NUM; i++) {
4422                 REG_WR(h_coeff_addr, *h_coeff);
4423                 h_coeff_addr += 4;
4424                 h_coeff++;
4425         }
4426
4427         for (i = 0; i < DCAM_SC_COEFF_V_NUM; i++) {
4428                 REG_WR(v_coeff_addr, *v_coeff);
4429                 v_coeff_addr += 4;
4430                 v_coeff++;
4431         }
4432
4433         for (i = 0; i < DCAM_SC_COEFF_V_CHROMA_NUM; i++) {
4434                 REG_WR(v_chroma_coeff_addr, *v_chroma_coeff);
4435                 v_chroma_coeff_addr += 4;
4436                 v_chroma_coeff++;
4437         }
4438
4439         DCAM_TRACE("DCAM: _dcam_write_sc_coeff E \n");
4440
4441         return ret;
4442 }
4443
4444 LOCAL int32_t _dcam_calc_sc_coeff(enum dcam_path_index path_index)
4445 {
4446         unsigned long           flag;
4447         struct dcam_path_desc   *path = NULL;
4448         uint32_t                h_coeff_addr = DCAM_BASE;
4449         uint32_t                v_coeff_addr  = DCAM_BASE;
4450         uint32_t                v_chroma_coeff_addr  = DCAM_BASE;
4451         uint32_t                *tmp_buf = NULL;
4452         uint32_t                *h_coeff = NULL;
4453         uint32_t                *v_coeff = NULL;
4454         uint32_t                *v_chroma_coeff = NULL;
4455         uint32_t                clk_switch_bit = 0;
4456         uint32_t                clk_switch_shift_bit = 0;
4457         uint32_t                clk_status_bit = 0;
4458         uint32_t                ver_tap_reg = 0;
4459         uint32_t                scale2yuv420 = 0;
4460         uint8_t                 y_tap = 0;
4461         uint8_t                 uv_tap = 0;
4462         uint32_t                index = 0;
4463         struct dcam_sc_coeff    *sc_coeff;
4464
4465         DCAM_CHECK_ZERO(s_p_dcam_mod);
4466         DCAM_CHECK_ZERO(s_dcam_sc_array);
4467
4468         if (DCAM_PATH_IDX_1 != path_index && DCAM_PATH_IDX_2 != path_index)
4469                 return -DCAM_RTN_PARA_ERR;
4470
4471         if (DCAM_PATH_IDX_1 == path_index) {
4472                 path = &s_p_dcam_mod->dcam_path1;
4473                 h_coeff_addr += DCAM_SC1_H_TAB_OFFSET;
4474                 v_coeff_addr += DCAM_SC1_V_TAB_OFFSET;
4475                 v_chroma_coeff_addr += DCAM_SC1_V_CHROMA_TAB_OFFSET;
4476                 clk_switch_bit = BIT_3;
4477                 clk_switch_shift_bit = 3;
4478                 clk_status_bit = BIT_5;
4479                 ver_tap_reg = DCAM_PATH1_CFG;
4480         } else if (DCAM_PATH_IDX_2 == path_index) {
4481                 path = &s_p_dcam_mod->dcam_path2;
4482                 h_coeff_addr += DCAM_SC2_H_TAB_OFFSET;
4483                 v_coeff_addr += DCAM_SC2_V_TAB_OFFSET;
4484                 v_chroma_coeff_addr += DCAM_SC2_V_CHROMA_TAB_OFFSET;
4485                 clk_switch_bit = BIT_4;
4486                 clk_switch_shift_bit = 4;
4487                 clk_status_bit = BIT_6;
4488                 ver_tap_reg = DCAM_PATH2_CFG;
4489         }
4490
4491         if (DCAM_YUV420 == path->output_format) {
4492             scale2yuv420 = 1;
4493         }
4494
4495         DCAM_TRACE("DCAM: _dcam_calc_sc_coeff {%d %d %d %d}, 420=%d \n",
4496                 path->sc_input_size.w,
4497                 path->sc_input_size.h,
4498                 path->output_size.w,
4499                 path->output_size.h, scale2yuv420);
4500
4501         down(&s_p_dcam_mod->scale_coeff_mem_sema);
4502
4503         spin_lock_irqsave(&dcam_lock,flag);
4504         tmp_buf = dcam_get_scale_coeff_addr(&index);
4505         if (NULL == tmp_buf) {
4506                 _dcam_pop_sc_buf(s_dcam_sc_array, &sc_coeff);
4507                 tmp_buf = dcam_get_scale_coeff_addr(&index);
4508         }
4509         spin_unlock_irqrestore(&dcam_lock,flag);
4510
4511         if (NULL == tmp_buf) {
4512                 return -DCAM_RTN_PATH_NO_MEM;
4513         }
4514
4515         h_coeff = tmp_buf;
4516         v_coeff = tmp_buf + (DCAM_SC_COEFF_COEF_SIZE/4);
4517         v_chroma_coeff = v_coeff + (DCAM_SC_COEFF_COEF_SIZE/4);
4518
4519         if (!(Dcam_GenScaleCoeff((int16_t)path->sc_input_size.w,
4520                 (int16_t)path->sc_input_size.h,
4521                 (int16_t)path->output_size.w,
4522                 (int16_t)path->output_size.h,
4523                 h_coeff,
4524                 v_coeff,
4525                 v_chroma_coeff,
4526                 scale2yuv420,
4527                 &y_tap,
4528                 &uv_tap,
4529                 tmp_buf + (DCAM_SC_COEFF_COEF_SIZE*3/4),
4530                 DCAM_SC_COEFF_TMP_SIZE))) {
4531                 printk("DCAM: _dcam_calc_sc_coeff Dcam_GenScaleCoeff error! \n");
4532                 up(&s_p_dcam_mod->scale_coeff_mem_sema);
4533                 return -DCAM_RTN_PATH_GEN_COEFF_ERR;
4534         }
4535         path->scale_tap.y_tap = y_tap;
4536         path->scale_tap.uv_tap = uv_tap;
4537         path->valid_param.scale_tap = 1;
4538         memcpy(&s_dcam_sc_array->scaling_coeff[index].dcam_path1, path, sizeof(struct dcam_path_desc));
4539         spin_lock_irqsave(&dcam_lock,flag);
4540         _dcam_push_sc_buf(s_dcam_sc_array, index);
4541         spin_unlock_irqrestore(&dcam_lock,flag);
4542
4543         up(&s_p_dcam_mod->scale_coeff_mem_sema);
4544         DCAM_TRACE("DCAM: _dcam_calc_sc_coeff E \n");
4545
4546         return DCAM_RTN_SUCCESS;
4547 }