2 * Copyright (C) 2012 Spreadtrum Communications Inc.
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.
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.
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>
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>
31 #include "gen_scale_coef.h"
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) && \
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
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
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
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)
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)
66 #define DCAM_AXI_STOP_TIMEOUT 1000
67 #define DCAM_CLK_DOMAIN_AHB 1
68 #define DCAM_CLK_DOMAIN_DCAM 0
71 #define DCAM_PATH_TIMEOUT msecs_to_jiffies(500*10)
73 #define DCAM_PATH_TIMEOUT msecs_to_jiffies(500)
76 #define DCAM_FRM_QUEUE_LENGTH 4
78 #define DCAM_STATE_QUICKQUIT 0x01
80 #define DCAM_CHECK_PARAM_ZERO_POINTER(n) \
83 return -DCAM_RTN_PARA_ERR; \
86 #define DCAM_CLEAR(a) \
88 memset((void *)(a), 0, sizeof(*(a))); \
91 #define DEBUG_STR "Error L %d, %s \n"
92 #define DEBUG_ARGS __LINE__,__FUNCTION__
93 #define DCAM_RTN_IF_ERR \
96 printk(DEBUG_STR, DEBUG_ARGS); \
101 #define DCAM_IRQ_LINE_MASK 0x011FFFFFUL
103 typedef void (*dcam_isr)(void);
107 DCAM_FRM_LOCK_WRITE = 0x10011001,
108 DCAM_FRM_LOCK_READ = 0x01100110
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))
121 #define DCAM_IRQ_JPEG_OV_MASK (1 << DCAM_JPEG_BUF_OV)
123 #define DCAM_CHECK_ZERO(a) \
125 if (DCAM_ADDR_INVALID(a)) { \
126 printk("DCAM, zero pointer \n"); \
127 printk(DEBUG_STR, DEBUG_ARGS); \
132 #define DCAM_CHECK_ZERO_VOID(a) \
134 if (DCAM_ADDR_INVALID(a)) { \
135 printk("DCAM, zero pointer \n"); \
136 printk(DEBUG_STR, DEBUG_ARGS); \
141 struct dcam_cap_desc {
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;
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;
155 uint32_t data_endian :1;
156 uint32_t frame_deci :1;
157 uint32_t scale_tap :1;
159 uint32_t rot_mode :1;
163 struct dcam_frm_queue {
164 struct dcam_frame frm_array[DCAM_FRM_QUEUE_LENGTH];
168 struct dcam_buf_queue {
169 struct dcam_frame frame[DCAM_FRM_CNT_MAX];
170 struct dcam_frame *write;
171 struct dcam_frame *read;
175 struct dcam_path_desc {
176 struct dcam_size input_size;
177 struct dcam_rect input_rect;
178 struct dcam_size sc_input_size;
179 struct dcam_size output_size;
180 struct dcam_frame input_frame;
181 struct dcam_frm_queue frame_queue;
182 struct dcam_buf_queue buf_queue;
183 //struct dcam_frame *output_frame_head;
184 //struct dcam_frame *output_frame_cur;
185 struct dcam_endian_sel data_endian;
186 struct dcam_sc_tap scale_tap;
187 struct dcam_deci deci_val;
189 struct dcam_path_valid valid_param;
190 uint32_t frame_base_id;
191 uint32_t output_frame_count;
192 uint32_t output_format;
198 struct semaphore tx_done_sema;
199 struct semaphore sof_sema;
200 uint32_t wait_for_done;
202 uint32_t wait_for_sof;
210 uint32_t module_addr;
211 struct dcam_cap_desc dcam_cap;
212 struct dcam_path_desc dcam_path0;
213 struct dcam_path_desc dcam_path1;
214 struct dcam_path_desc dcam_path2;
215 struct dcam_frame path0_frame[DCAM_PATH_0_FRM_CNT_MAX];
216 struct dcam_frame path1_frame[DCAM_PATH_1_FRM_CNT_MAX];
217 struct dcam_frame path2_frame[DCAM_PATH_2_FRM_CNT_MAX];
218 struct dcam_frame path0_reserved_frame;
219 struct dcam_frame path1_reserved_frame;
220 struct dcam_frame path2_reserved_frame;
221 struct semaphore stop_sema;
223 struct semaphore resize_done_sema;
224 uint32_t wait_resize_done;
225 struct semaphore rotation_done_sema;
226 uint32_t wait_rotation_done;
227 uint32_t err_happened;
228 struct semaphore scale_coeff_mem_sema;
232 struct dcam_sc_coeff {
233 uint32_t buf[DCAM_SC_COEFF_BUF_SIZE];
235 struct dcam_path_desc dcam_path1;
238 struct dcam_sc_array {
239 struct dcam_sc_coeff scaling_coeff[DCAM_SC_COEFF_BUF_COUNT];
240 struct dcam_sc_coeff *scaling_coeff_queue[DCAM_SC_COEFF_BUF_COUNT];
242 uint32_t is_smooth_zoom;
245 LOCAL atomic_t s_dcam_users = ATOMIC_INIT(0);
246 LOCAL atomic_t s_resize_flag = ATOMIC_INIT(0);
247 LOCAL atomic_t s_rotation_flag = ATOMIC_INIT(0);
248 LOCAL struct clk* s_dcam_clk = NULL;
249 LOCAL struct dcam_module* s_p_dcam_mod = 0;
250 LOCAL uint32_t s_dcam_irq = 0x5A0000A5;
251 LOCAL dcam_isr_func s_user_func[DCAM_IRQ_NUMBER];
252 LOCAL void* s_user_data[DCAM_IRQ_NUMBER];
253 LOCAL struct dcam_sc_array* s_dcam_sc_array = NULL;
254 LOCAL struct wake_lock dcam_wakelock;
256 LOCAL DEFINE_MUTEX(dcam_sem);
257 LOCAL DEFINE_MUTEX(dcam_scale_sema);
258 LOCAL DEFINE_MUTEX(dcam_rot_sema);
259 LOCAL DEFINE_MUTEX(dcam_module_sema);
260 LOCAL DEFINE_SPINLOCK(dcam_mod_lock);
261 LOCAL DEFINE_SPINLOCK(dcam_lock);
262 LOCAL DEFINE_SPINLOCK(dcam_glb_reg_cfg_lock);
263 LOCAL DEFINE_SPINLOCK(dcam_glb_reg_control_lock);
264 LOCAL DEFINE_SPINLOCK(dcam_glb_reg_mask_lock);
265 LOCAL DEFINE_SPINLOCK(dcam_glb_reg_clr_lock);
266 LOCAL DEFINE_SPINLOCK(dcam_glb_reg_ahbm_sts_lock);
267 LOCAL DEFINE_SPINLOCK(dcam_glb_reg_endian_lock);
269 LOCAL void _dcam_path0_set(void);
270 LOCAL void _dcam_path1_set(struct dcam_path_desc *path);
271 LOCAL void _dcam_path2_set(void);
272 LOCAL void _dcam_frm_clear(enum dcam_path_index path_index);
273 LOCAL void _dcam_link_frm(uint32_t base_id);
274 LOCAL int32_t _dcam_path_set_next_frm(enum dcam_path_index path_index, uint32_t is_1st_frm);
275 /*LOCAL int32_t _dcam_path_trim(enum dcam_path_index path_index);*/
276 LOCAL int32_t _dcam_path_scaler(enum dcam_path_index path_index);
277 LOCAL int32_t _dcam_calc_sc_size(enum dcam_path_index path_index);
278 LOCAL int32_t _dcam_set_sc_coeff(enum dcam_path_index path_index);
279 LOCAL void _dcam_force_copy_ext(enum dcam_path_index path_index, uint32_t path_copy, uint32_t coef_copy);
280 LOCAL void _dcam_auto_copy_ext(enum dcam_path_index path_index, uint32_t path_copy, uint32_t coef_copy);
281 LOCAL void _dcam_force_copy(enum dcam_path_index path_index);
282 LOCAL void _dcam_auto_copy(enum dcam_path_index path_index);
283 LOCAL void _dcam_reg_trace(void);
284 LOCAL void _dcam_sensor_sof(void);
285 LOCAL void _dcam_sensor_eof(void);
286 LOCAL void _dcam_cap_sof(void);
287 LOCAL void _dcam_cap_eof(void);
288 LOCAL void _dcam_path0_done(void);
289 LOCAL void _dcam_path0_overflow(void);
290 LOCAL void _dcam_path1_done(void);
291 LOCAL void _dcam_path1_overflow(void);
292 LOCAL void _dcam_sensor_line_err(void);
293 LOCAL void _dcam_sensor_frame_err(void);
294 LOCAL void _dcam_jpeg_buf_ov(void);
295 LOCAL void _dcam_path2_done(void);
296 LOCAL void _dcam_path2_ov(void);
297 LOCAL void _dcam_isp_ov(void);
298 LOCAL void _dcam_mipi_ov(void);
299 LOCAL void _dcam_path1_slice_done(void);
300 LOCAL void _dcam_path2_slice_done(void);
301 LOCAL void _dcam_raw_slice_done(void);
302 LOCAL void _dcam_path0_sof(void);
303 LOCAL void _dcam_path1_sof(void);
304 LOCAL void _dcam_path2_sof(void);
305 LOCAL irqreturn_t _dcam_isr_root(int irq, void *dev_id);
306 LOCAL void _dcam_stopped_notice(void);
307 LOCAL void _dcam_stopped(void);
308 LOCAL int32_t _dcam_path_check_deci(enum dcam_path_index path_index, uint32_t *is_deci);
309 extern void _dcam_isp_root(void);
310 LOCAL int _dcam_internal_init(void);
311 LOCAL void _dcam_internal_deinit(void);
312 LOCAL void _dcam_wait_path_done(enum dcam_path_index path_index, uint32_t *p_flag);
313 LOCAL void _dcam_path_done_notice(enum dcam_path_index path_index);
314 LOCAL void _dcam_rot_done(void);
315 LOCAL int32_t _dcam_err_pre_proc(void);
316 LOCAL void _dcam_frm_queue_clear(struct dcam_frm_queue *queue);
317 LOCAL int32_t _dcam_frame_enqueue(struct dcam_frm_queue *queue, struct dcam_frame *frame);
318 LOCAL int32_t _dcam_frame_dequeue(struct dcam_frm_queue *queue, struct dcam_frame *frame);
319 LOCAL void _dcam_buf_queue_init(struct dcam_buf_queue *queue);
320 LOCAL int32_t _dcam_buf_queue_write(struct dcam_buf_queue *queue, struct dcam_frame *frame);
321 LOCAL int32_t _dcam_buf_queue_read(struct dcam_buf_queue *queue, struct dcam_frame *frame);
322 LOCAL void _dcam_wait_update_done(enum dcam_path_index path_index, uint32_t *p_flag);
323 LOCAL void _dcam_path_updated_notice(enum dcam_path_index path_index);
324 LOCAL int32_t _dcam_get_valid_sc_coeff(struct dcam_sc_array *sc, struct dcam_sc_coeff **sc_coeff);
325 LOCAL int32_t _dcam_push_sc_buf(struct dcam_sc_array *sc, uint32_t index);
326 LOCAL int32_t _dcam_pop_sc_buf(struct dcam_sc_array *sc, struct dcam_sc_coeff **sc_coeff);
327 LOCAL int32_t _dcam_calc_sc_coeff(enum dcam_path_index path_index);
328 LOCAL int32_t _dcam_write_sc_coeff(enum dcam_path_index path_index);
329 LOCAL void _dcam_wait_for_quickstop(enum dcam_path_index path_index);
331 LOCAL const dcam_isr isr_list[DCAM_IRQ_NUMBER] = {
332 NULL,//_dcam_isp_root,
337 _dcam_path0_overflow,
339 _dcam_path1_overflow,
342 _dcam_sensor_line_err,
343 _dcam_sensor_frame_err,
348 _dcam_path1_slice_done,
349 _dcam_path2_slice_done,
350 _dcam_raw_slice_done,
359 void dcam_glb_reg_awr(uint32_t addr, uint32_t val, uint32_t reg_id)
365 spin_lock_irqsave(&dcam_glb_reg_cfg_lock, flag);
366 REG_WR(addr, REG_RD(addr) & (val));
367 spin_unlock_irqrestore(&dcam_glb_reg_cfg_lock, flag);
369 case DCAM_CONTROL_REG:
370 spin_lock_irqsave(&dcam_glb_reg_control_lock, flag);
371 REG_WR(addr, REG_RD(addr) & (val));
372 spin_unlock_irqrestore(&dcam_glb_reg_control_lock, flag);
374 case DCAM_INIT_MASK_REG:
375 spin_lock_irqsave(&dcam_glb_reg_mask_lock, flag);
376 REG_WR(addr, REG_RD(addr) & (val));
377 spin_unlock_irqrestore(&dcam_glb_reg_mask_lock, flag);
379 case DCAM_INIT_CLR_REG:
380 spin_lock_irqsave(&dcam_glb_reg_clr_lock, flag);
381 REG_WR(addr, REG_RD(addr) & (val));
382 spin_unlock_irqrestore(&dcam_glb_reg_clr_lock, flag);
384 case DCAM_AHBM_STS_REG:
385 spin_lock_irqsave(&dcam_glb_reg_ahbm_sts_lock, flag);
386 REG_WR(addr, REG_RD(addr) & (val));
387 spin_unlock_irqrestore(&dcam_glb_reg_ahbm_sts_lock, flag);
389 case DCAM_ENDIAN_REG:
390 spin_lock_irqsave(&dcam_glb_reg_endian_lock, flag);
391 REG_WR(addr, REG_RD(addr) & (val));
392 spin_unlock_irqrestore(&dcam_glb_reg_endian_lock, flag);
395 REG_WR(addr, REG_RD(addr) & (val));
400 void dcam_glb_reg_owr(uint32_t addr, uint32_t val, uint32_t reg_id)
406 spin_lock_irqsave(&dcam_glb_reg_cfg_lock, flag);
407 REG_WR(addr, REG_RD(addr) | (val));
408 spin_unlock_irqrestore(&dcam_glb_reg_cfg_lock, flag);
410 case DCAM_CONTROL_REG:
411 spin_lock_irqsave(&dcam_glb_reg_control_lock, flag);
412 REG_WR(addr, REG_RD(addr) | (val));
413 spin_unlock_irqrestore(&dcam_glb_reg_control_lock, flag);
415 case DCAM_INIT_MASK_REG:
416 spin_lock_irqsave(&dcam_glb_reg_mask_lock, flag);
417 REG_WR(addr, REG_RD(addr) | (val));
418 spin_unlock_irqrestore(&dcam_glb_reg_mask_lock, flag);
420 case DCAM_INIT_CLR_REG:
421 spin_lock_irqsave(&dcam_glb_reg_clr_lock, flag);
422 REG_WR(addr, REG_RD(addr) | (val));
423 spin_unlock_irqrestore(&dcam_glb_reg_clr_lock, flag);
425 case DCAM_AHBM_STS_REG:
426 spin_lock_irqsave(&dcam_glb_reg_ahbm_sts_lock, flag);
427 REG_WR(addr, REG_RD(addr) | (val));
428 spin_unlock_irqrestore(&dcam_glb_reg_ahbm_sts_lock, flag);
430 case DCAM_ENDIAN_REG:
431 spin_lock_irqsave(&dcam_glb_reg_endian_lock, flag);
432 REG_WR(addr, REG_RD(addr) | (val));
433 spin_unlock_irqrestore(&dcam_glb_reg_endian_lock, flag);
436 REG_WR(addr, REG_RD(addr) | (val));
441 void dcam_glb_reg_mwr(uint32_t addr, uint32_t mask, uint32_t val, uint32_t reg_id)
448 spin_lock_irqsave(&dcam_glb_reg_cfg_lock, flag);
452 REG_WR(addr, tmp | ((mask) & (val)));
454 spin_unlock_irqrestore(&dcam_glb_reg_cfg_lock, flag);
456 case DCAM_CONTROL_REG:
457 spin_lock_irqsave(&dcam_glb_reg_control_lock, flag);
461 REG_WR(addr, tmp | ((mask) & (val)));
463 spin_unlock_irqrestore(&dcam_glb_reg_control_lock, flag);
465 case DCAM_INIT_MASK_REG:
466 spin_lock_irqsave(&dcam_glb_reg_mask_lock, flag);
470 REG_WR(addr, tmp | ((mask) & (val)));
472 spin_unlock_irqrestore(&dcam_glb_reg_mask_lock, flag);
474 case DCAM_INIT_CLR_REG:
475 spin_lock_irqsave(&dcam_glb_reg_clr_lock, flag);
479 REG_WR(addr, tmp | ((mask) & (val)));
481 spin_unlock_irqrestore(&dcam_glb_reg_clr_lock, flag);
483 case DCAM_AHBM_STS_REG:
484 spin_lock_irqsave(&dcam_glb_reg_ahbm_sts_lock, flag);
488 REG_WR(addr, tmp | ((mask) & (val)));
490 spin_unlock_irqrestore(&dcam_glb_reg_ahbm_sts_lock, flag);
492 case DCAM_ENDIAN_REG:
493 spin_lock_irqsave(&dcam_glb_reg_endian_lock, flag);
497 REG_WR(addr, tmp | ((mask) & (val)));
499 spin_unlock_irqrestore(&dcam_glb_reg_endian_lock, flag);
505 REG_WR(addr, tmp | ((mask) & (val)));
511 int32_t dcam_module_init(enum dcam_cap_if_mode if_mode,
512 enum dcam_cap_sensor_mode sn_mode)
514 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
515 struct dcam_cap_desc *cap_desc = NULL;
517 if (if_mode >= DCAM_CAP_IF_MODE_MAX) {
518 rtn = -DCAM_RTN_CAP_IF_MODE_ERR;
520 if (sn_mode >= DCAM_CAP_MODE_MAX) {
521 rtn = -DCAM_RTN_CAP_SENSOR_MODE_ERR;
523 _dcam_internal_init();
524 _dcam_link_frm(0); /* set default base frame index as 0 */
525 _dcam_buf_queue_init(&s_p_dcam_mod->dcam_path0.buf_queue);
526 _dcam_buf_queue_init(&s_p_dcam_mod->dcam_path1.buf_queue);
527 _dcam_buf_queue_init(&s_p_dcam_mod->dcam_path2.buf_queue);
528 cap_desc = &s_p_dcam_mod->dcam_cap;
529 cap_desc->interface = if_mode;
530 cap_desc->input_format = sn_mode;
531 /*REG_OWR(DCAM_EB, BIT_13);//MM_EB*/
532 /*REG_OWR(DCAM_MATRIX_EB, BIT_10|BIT_5);*/
533 if (DCAM_CAP_IF_CSI2 == if_mode) {
534 /* REG_OWR(CSI2_DPHY_EB, MIPI_EB_BIT);*/
535 //ret = _dcam_mipi_clk_en();
536 dcam_glb_reg_owr(DCAM_CFG, BIT_9, DCAM_CFG_REG);
537 REG_MWR(CAP_MIPI_CTRL, BIT_2 | BIT_1, sn_mode << 1);
539 /*REG_OWR(DCAM_EB, CCIR_IN_EB_BIT);
540 REG_OWR(DCAM_EB, CCIR_EB_BIT);*/
541 //ret = _dcam_ccir_clk_en();
542 dcam_glb_reg_mwr(DCAM_CFG, BIT_9, 0 << 9, DCAM_CFG_REG);
543 REG_MWR(CAP_CCIR_CTRL, BIT_2 | BIT_1, sn_mode << 1);
545 rtn = DCAM_RTN_SUCCESS;
552 int32_t dcam_module_deinit(enum dcam_cap_if_mode if_mode,
553 enum dcam_cap_sensor_mode sn_mode)
555 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
557 if (DCAM_CAP_IF_CSI2 == if_mode) {
558 /*REG_MWR(CSI2_DPHY_EB, MIPI_EB_BIT, 0 << 10);*/
559 dcam_glb_reg_mwr(DCAM_CFG, BIT_9, 0 << 9, DCAM_CFG_REG);
560 //_dcam_mipi_clk_dis();
562 /*REG_MWR(DCAM_EB, CCIR_IN_EB_BIT, 0 << 2);
563 REG_MWR(DCAM_EB, CCIR_EB_BIT, 0 << 9);*/
564 dcam_glb_reg_mwr(DCAM_CFG, BIT_9, 0 << 9, DCAM_CFG_REG);
565 //_dcam_ccir_clk_dis();
568 _dcam_internal_deinit();
573 int dcam_scale_coeff_alloc(void)
577 if (NULL == s_dcam_sc_array) {
578 s_dcam_sc_array = (struct dcam_sc_array*)vzalloc(sizeof(struct dcam_sc_array));
579 if (NULL == s_dcam_sc_array) {
580 printk("DCAM: _dcam_scale_coeff_alloc fail.\n");
588 void dcam_scale_coeff_free(void)
590 if (s_dcam_sc_array) {
591 vfree(s_dcam_sc_array);
592 s_dcam_sc_array = NULL;
596 LOCAL uint32_t *dcam_get_scale_coeff_addr(uint32_t *index)
600 if (DCAM_ADDR_INVALID(s_dcam_sc_array)) {
601 printk("DCAM: scale addr, invalid param 0x%x \n",
602 (uint32_t)s_dcam_sc_array);
606 for (i = 0; i < DCAM_SC_COEFF_BUF_COUNT; i++) {
607 if (0 == s_dcam_sc_array->scaling_coeff[i].flag) {
609 DCAM_TRACE("dcam: get buf index %d \n", i);
610 return s_dcam_sc_array->scaling_coeff[i].buf;
613 printk("dcam: get buf index %d \n", i);
618 int32_t dcam_module_en(struct device_node *dn)
621 unsigned int irq_no = 0;
623 DCAM_TRACE("DCAM: dcam_module_en, In %d \n", s_dcam_users.counter);
625 mutex_lock(&dcam_module_sema);
626 if (atomic_inc_return(&s_dcam_users) == 1) {
628 wake_lock_init(&dcam_wakelock, WAKE_LOCK_SUSPEND,
629 "pm_message_wakelock_dcam");
631 wake_lock(&dcam_wakelock);
633 ret = clk_mm_i_eb(dn,1);
639 ret = dcam_set_clk(dn,DCAM_CLK_312M);
646 parse_baseaddress(dn);
648 dcam_reset(DCAM_RST_ALL, 0);
649 atomic_set(&s_resize_flag, 0);
650 atomic_set(&s_rotation_flag, 0);
651 memset((void*)s_user_func, 0, sizeof(s_user_func));
652 memset((void*)s_user_data, 0, sizeof(s_user_data));
653 printk("DCAM: register isr, 0x%x \n", REG_RD(DCAM_INT_MASK));
655 irq_no = parse_irq(dn);
656 printk("DCAM: irq_no = 0x%x \n", irq_no);
657 ret = request_irq(irq_no,
663 printk("DCAM: dcam_start, error %d \n", ret);
664 dcam_set_clk(dn,DCAM_CLK_NONE);
670 DCAM_TRACE("DCAM: dcam_module_en end \n");
672 DCAM_TRACE("DCAM: dcam_module_en, Out %d \n", s_dcam_users.counter);
673 mutex_unlock(&dcam_module_sema);
677 wake_unlock(&dcam_wakelock);
678 wake_lock_destroy(&dcam_wakelock);
679 atomic_dec(&s_dcam_users);
680 mutex_unlock(&dcam_module_sema);
684 int32_t dcam_module_dis(struct device_node *dn)
686 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
688 unsigned int irq_no = 0;
690 DCAM_TRACE("DCAM: dcam_module_dis, In %d \n", s_dcam_users.counter);
692 mutex_lock(&dcam_module_sema);
693 if (atomic_dec_return(&s_dcam_users) == 0) {
695 sci_glb_clr(DCAM_EB, DCAM_EB_BIT);
696 dcam_set_clk(dn,DCAM_CLK_NONE);
697 printk("DCAM: un register isr \n");
698 irq_no = parse_irq(dn);
699 free_irq(irq_no, (void*)&s_dcam_irq);
700 ret = clk_mm_i_eb(dn,0);
704 wake_unlock(&dcam_wakelock);
705 wake_lock_destroy(&dcam_wakelock);
708 DCAM_TRACE("DCAM: dcam_module_dis, Out %d \n", s_dcam_users.counter);
709 mutex_unlock(&dcam_module_sema);
714 int32_t dcam_reset(enum dcam_rst_mode reset_mode, uint32_t is_isr)
716 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
717 uint32_t time_out = 0;
719 DCAM_TRACE("DCAM: reset: %d \n", reset_mode);
722 mutex_lock(&dcam_scale_sema);
723 mutex_lock(&dcam_rot_sema);
726 if (DCAM_RST_ALL == reset_mode) {
727 if (atomic_read(&s_dcam_users)) {
728 /* firstly, stop AXI writing */
729 dcam_glb_reg_owr(DCAM_AHBM_STS, BIT_6, DCAM_AHBM_STS_REG);
732 /* then wait for AHB busy cleared */
733 while (++time_out < DCAM_AXI_STOP_TIMEOUT) {
734 if (0 == (REG_RD(DCAM_AHBM_STS) & BIT_0))
737 if (time_out >= DCAM_AXI_STOP_TIMEOUT) {
738 printk("DCAM: reset TO: %d \n", time_out);
739 return DCAM_RTN_TIMEOUT;
743 /* do reset action */
744 switch (reset_mode) {
746 sci_glb_set(DCAM_RST, PATH0_RST_BIT);
747 sci_glb_clr(DCAM_RST, PATH0_RST_BIT);
748 DCAM_TRACE("DCAM: reset path0 \n");
752 sci_glb_set(DCAM_RST, PATH1_RST_BIT);
753 sci_glb_clr(DCAM_RST, PATH1_RST_BIT);
754 DCAM_TRACE("DCAM: reset path1 \n");
758 sci_glb_set(DCAM_RST, PATH2_RST_BIT);
759 sci_glb_clr(DCAM_RST, PATH2_RST_BIT);
760 DCAM_TRACE("DCAM: reset path2 \n");
764 sci_glb_set(DCAM_RST, DCAM_MOD_RST_BIT | CCIR_RST_BIT);
765 sci_glb_clr(DCAM_RST, DCAM_MOD_RST_BIT | CCIR_RST_BIT);
766 dcam_glb_reg_owr(DCAM_INT_CLR,
769 dcam_glb_reg_owr(DCAM_INT_MASK,
772 printk("DCAM: reset all \n");
775 rtn = DCAM_RTN_PARA_ERR;
779 if (DCAM_RST_ALL == reset_mode) {
780 if (atomic_read(&s_dcam_users)) {
781 /* the end, enable AXI writing */
782 dcam_glb_reg_awr(DCAM_AHBM_STS, ~BIT_6, DCAM_AHBM_STS_REG);
787 mutex_unlock(&dcam_rot_sema);
788 mutex_unlock(&dcam_scale_sema);
791 DCAM_TRACE("DCAM: reset_mode=%x end \n", reset_mode);
796 int32_t dcam_set_clk(struct device_node *dn, enum dcam_clk_sel clk_sel)
798 #ifdef CONFIG_SC_FPGA_CLK
801 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
802 struct clk *clk_parent;
803 char *parent = "clk_312m";
817 parent = "clk_76p8m";
820 printk("DCAM close CLK %d \n", (int)clk_get_rate(s_dcam_clk));
822 clk_disable(s_dcam_clk);
832 if (NULL == s_dcam_clk) {
833 s_dcam_clk = parse_clk(dn,"clk_dcam");
834 if (IS_ERR(s_dcam_clk)) {
835 printk("DCAM: clk_get fail, %d \n", (int)s_dcam_clk);
838 DCAM_TRACE("DCAM: get clk_parent ok \n");
841 clk_disable(s_dcam_clk);
844 clk_parent = clk_get(NULL, parent);
845 if (IS_ERR(clk_parent)) {
846 printk("DCAM: dcam_set_clk fail, %d \n", (int)clk_parent);
849 DCAM_TRACE("DCAM: get clk_parent ok \n");
852 ret = clk_set_parent(s_dcam_clk, clk_parent);
854 printk("DCAM: clk_set_parent fail, %d \n", ret);
857 ret = clk_enable(s_dcam_clk);
859 printk("enable dcam clk error.\n");
866 int32_t dcam_update_path(enum dcam_path_index path_index, struct dcam_size *in_size,
867 struct dcam_rect *in_rect, struct dcam_size *out_size)
869 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
871 uint32_t is_deci = 0;
873 DCAM_CHECK_ZERO(s_p_dcam_mod);
874 DCAM_CHECK_ZERO(s_dcam_sc_array);
876 DCAM_TRACE("DCAM:update path \n");
877 DCAM_TRACE("path_index %d s_p_dcam_mod->dcam_path0.valide %d \n", path_index, s_p_dcam_mod->dcam_path0.valide);
878 if ((DCAM_PATH_IDX_0 & path_index) && s_p_dcam_mod->dcam_path0.valide) {
879 rtn = dcam_path0_cfg(DCAM_PATH_INPUT_SIZE, in_size);
881 rtn = dcam_path0_cfg(DCAM_PATH_INPUT_RECT, in_rect);
883 rtn = dcam_path0_cfg(DCAM_PATH_OUTPUT_SIZE, out_size);
885 printk("DCAM: To update path0 \n");
886 //_dcam_auto_copy(DCAM_PATH_IDX_0);
889 if ((DCAM_PATH_IDX_1 & path_index) && s_p_dcam_mod->dcam_path1.valide) {
890 rtn = dcam_path1_cfg(DCAM_PATH_INPUT_SIZE, in_size);
892 rtn = dcam_path1_cfg(DCAM_PATH_INPUT_RECT, in_rect);
894 rtn = dcam_path1_cfg(DCAM_PATH_OUTPUT_SIZE, out_size);
896 rtn = _dcam_path_check_deci(DCAM_PATH_IDX_1, &is_deci);
898 DCAM_TRACE("DCAM: To update path1 \n");
899 rtn = _dcam_path_scaler(DCAM_PATH_IDX_1);
901 DCAM_TRACE("DCAM: dcam_update_path 1 \n");
902 if (s_dcam_sc_array->is_smooth_zoom) {
903 spin_lock_irqsave(&dcam_lock, flags);
904 s_p_dcam_mod->dcam_path1.is_update = 1;
905 spin_unlock_irqrestore(&dcam_lock, flags);
907 _dcam_wait_update_done(DCAM_PATH_IDX_1, &s_p_dcam_mod->dcam_path1.is_update);
909 if (!s_dcam_sc_array->is_smooth_zoom) {
910 _dcam_wait_update_done(DCAM_PATH_IDX_1, NULL);
914 if ((DCAM_PATH_IDX_2 & path_index) && s_p_dcam_mod->dcam_path2.valide) {
915 local_irq_save(flags);
916 if(s_p_dcam_mod->dcam_path2.is_update){
917 local_irq_restore(flags);
918 DCAM_TRACE("DCAM: dcam_update_path 2: updating return \n");
921 local_irq_restore(flags);
923 rtn = dcam_path2_cfg(DCAM_PATH_INPUT_SIZE, in_size);
925 rtn = dcam_path2_cfg(DCAM_PATH_INPUT_RECT, in_rect);
927 rtn = dcam_path2_cfg(DCAM_PATH_OUTPUT_SIZE, out_size);
930 rtn = _dcam_path_scaler(DCAM_PATH_IDX_2);
933 local_irq_save(flags);
934 s_p_dcam_mod->dcam_path2.is_update = 1;
935 local_irq_restore(flags);
938 DCAM_TRACE("DCAM: dcam_update_path: done \n");
943 int32_t dcam_start_path(enum dcam_path_index path_index)
945 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
948 DCAM_CHECK_ZERO(s_p_dcam_mod);
950 DCAM_TRACE("DCAM: start_path: path %d, mode %x path 0,1,2 {%d %d %d} \n",
952 s_p_dcam_mod->dcam_mode,
953 s_p_dcam_mod->dcam_path0.valide,
954 s_p_dcam_mod->dcam_path1.valide,
955 s_p_dcam_mod->dcam_path2.valide);
957 dcam_glb_reg_owr(DCAM_AHBM_STS, BIT_8, DCAM_AHBM_STS_REG); // aiden add: write arbit mode
959 cap_en = REG_RD(DCAM_CONTROL) & BIT_2;
960 DCAM_TRACE("DCAM: cap_eb %d \n", cap_en);
961 if ((DCAM_PATH_IDX_0 & path_index) && s_p_dcam_mod->dcam_path0.valide) {
963 rtn = _dcam_path_set_next_frm(DCAM_PATH_IDX_0, true);
965 //_dcam_force_copy(DCAM_PATH_IDX_0);
966 _dcam_auto_copy(DCAM_PATH_IDX_0);
969 /* if cap is already open, the sequence is:
970 cap force copy -> path 0 enable -> cap auto copy */
971 dcam_glb_reg_mwr(DCAM_CONTROL, BIT_0, 1 << 0, DCAM_CONTROL_REG); /* Cap force copy */
972 dcam_glb_reg_owr(DCAM_CFG, BIT_0, DCAM_CFG_REG); /* Enable Path 0 */
973 dcam_glb_reg_mwr(DCAM_CONTROL, BIT_1, 1 << 1, DCAM_CONTROL_REG); /* Cap auto copy, trigger path 0 enable */
975 dcam_glb_reg_owr(DCAM_CFG, BIT_0, DCAM_CFG_REG); /* Enable Path 0 */
980 if ((DCAM_PATH_IDX_1 & path_index) && s_p_dcam_mod->dcam_path1.valide) {
982 //rtn = _dcam_path_trim(DCAM_PATH_IDX_1);
984 rtn = _dcam_path_scaler(DCAM_PATH_IDX_1);
987 _dcam_path1_set(&s_p_dcam_mod->dcam_path1);
988 DCAM_TRACE("DCAM: start path: path_control=%x \n", REG_RD(DCAM_CONTROL));
990 rtn = _dcam_path_set_next_frm(DCAM_PATH_IDX_1, true);
992 _dcam_force_copy_ext(DCAM_PATH_IDX_1, true, true);
993 DCAM_TRACE("DCAM: int= %x \n", REG_RD(DCAM_INT_STS));
994 dcam_glb_reg_owr(DCAM_CFG, BIT_1, DCAM_CFG_REG);
997 if ((DCAM_PATH_IDX_2 & path_index) && s_p_dcam_mod->dcam_path2.valide) {
998 rtn = _dcam_path_scaler(DCAM_PATH_IDX_2);
1003 rtn = _dcam_path_set_next_frm(DCAM_PATH_IDX_2, true);
1005 _dcam_force_copy_ext(DCAM_PATH_IDX_2, true, true);
1008 if ((DCAM_PATH_IDX_0 & path_index) && s_p_dcam_mod->dcam_path0.valide) {
1009 //rtn = _dcam_path_set_next_frm(DCAM_PATH_IDX_0, false);
1011 //_dcam_auto_copy(DCAM_PATH_IDX_0);
1012 s_p_dcam_mod->dcam_path0.need_wait = 0;
1013 s_p_dcam_mod->dcam_path0.status = DCAM_ST_START;
1014 dcam_glb_reg_owr(DCAM_CFG, BIT_0, DCAM_CFG_REG); /* Enable Path 0 */
1017 if ((DCAM_PATH_IDX_1 & path_index) && s_p_dcam_mod->dcam_path1.valide) {
1018 s_p_dcam_mod->dcam_path1.need_wait = 0;
1019 s_p_dcam_mod->dcam_path1.status = DCAM_ST_START;
1020 dcam_glb_reg_owr(DCAM_CFG, BIT_1, DCAM_CFG_REG);
1023 if ((DCAM_PATH_IDX_2 & path_index) && s_p_dcam_mod->dcam_path2.valide) {
1024 s_p_dcam_mod->dcam_path2.need_wait = 0;
1025 s_p_dcam_mod->dcam_path2.status = DCAM_ST_START;
1026 dcam_glb_reg_owr(DCAM_CFG, BIT_2, DCAM_CFG_REG);
1030 #if 0 //def DCAM_DEBUG
1031 REG_MWR(CAP_CCIR_FRM_CTRL, BIT_5 | BIT_4, 0 << 4);
1032 REG_MWR(CAP_CCIR_FRM_CTRL, BIT_3|BIT_2|BIT_1|BIT_0, 0x07);
1033 REG_MWR(CAP_MIPI_FRM_CTRL, BIT_5 | BIT_4, 1 << 4);
1034 REG_MWR(CAP_MIPI_FRM_CTRL, BIT_3|BIT_2|BIT_1|BIT_0, 0x07);
1036 dcam_glb_reg_mwr(DCAM_CONTROL, BIT_0, 1 << 0, DCAM_CONTROL_REG); /* Cap force copy */
1037 //REG_MWR(DCAM_CONTROL, BIT_1, 1 << 1); /* Cap auto copy */
1038 dcam_glb_reg_mwr(DCAM_CONTROL, BIT_2, 1 << 2, DCAM_CONTROL_REG); /* Cap Enable */
1041 if (DCAM_PATH_IDX_ALL != path_index) {
1042 if ((DCAM_PATH_IDX_0 & path_index)) {
1043 _dcam_wait_path_done(DCAM_PATH_IDX_0, NULL);
1044 } else if ((DCAM_PATH_IDX_1 & path_index)) {
1045 _dcam_wait_path_done(DCAM_PATH_IDX_1, NULL);
1046 } else if ((DCAM_PATH_IDX_2 & path_index)) {
1047 _dcam_wait_path_done(DCAM_PATH_IDX_2, NULL);
1051 printk("DCAM PATH S: %d \n", path_index);
1055 DCAM_TRACE("DCAM: start_path E\n");
1059 int32_t dcam_start(void)
1061 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
1064 DCAM_CHECK_ZERO(s_p_dcam_mod);
1066 DCAM_TRACE("DCAM: dcam_start %x \n", s_p_dcam_mod->dcam_mode);
1068 ret = dcam_start_path(DCAM_PATH_IDX_ALL);
1069 //ret = dcam_start_path(DCAM_PATH_IDX_1);
1074 int32_t dcam_stop_cap(void)
1076 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
1078 DCAM_CHECK_ZERO(s_p_dcam_mod);
1080 printk("DCAM: stop cap %d \n", s_p_dcam_mod->dcam_mode);
1081 dcam_glb_reg_mwr(DCAM_CONTROL, BIT_2, 0, DCAM_CONTROL_REG); /* Cap Enable */
1082 DCAM_TRACE("DCAM: stop cap, s_resize_flag %d \n", atomic_read(&s_resize_flag));
1083 if (atomic_read(&s_resize_flag)) {
1084 s_p_dcam_mod->wait_resize_done = 1;
1085 rtn = down_timeout(&s_p_dcam_mod->resize_done_sema, DCAM_PATH_TIMEOUT);
1087 if (atomic_read(&s_rotation_flag)) {
1088 s_p_dcam_mod->wait_rotation_done = 1;
1089 rtn = down_timeout(&s_p_dcam_mod->rotation_done_sema, DCAM_PATH_TIMEOUT);
1092 dcam_reset(DCAM_RST_ALL, 0);
1093 DCAM_TRACE("DCAM: stop cap, Out \n");
1098 int32_t _dcam_stop_path(enum dcam_path_index path_index)
1100 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
1101 struct dcam_path_desc *p_path = NULL;
1104 spin_lock_irqsave(&dcam_lock, flag);
1106 if (DCAM_PATH_IDX_0 == path_index) {
1107 p_path = &s_p_dcam_mod->dcam_path0;
1108 } else if(DCAM_PATH_IDX_1 == path_index) {
1109 p_path = &s_p_dcam_mod->dcam_path1;
1110 } else if(DCAM_PATH_IDX_2 == path_index) {
1111 p_path = &s_p_dcam_mod->dcam_path2;
1113 printk("DCAM: stop path Wrong index 0x%x \n", path_index);
1114 spin_unlock_irqrestore(&dcam_lock, flag);
1118 _dcam_wait_for_quickstop(path_index);
1119 p_path->status = DCAM_ST_STOP;
1121 _dcam_frm_clear(path_index);
1123 spin_unlock_irqrestore(&dcam_lock, flag);
1128 int32_t dcam_stop_path(enum dcam_path_index path_index)
1130 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
1132 DCAM_CHECK_ZERO(s_p_dcam_mod);
1134 printk("DCAM: stop_path 0x%x \n", path_index);
1136 if (path_index < DCAM_PATH_IDX_0 ||
1137 path_index >= DCAM_PATH_IDX_ALL) {
1138 printk("DCAM: error path_index \n");
1142 if ((DCAM_PATH_IDX_0 & path_index) && s_p_dcam_mod->dcam_path0.valide) {
1143 _dcam_wait_path_done(DCAM_PATH_IDX_0, &s_p_dcam_mod->dcam_path0.need_stop);
1144 _dcam_stop_path(DCAM_PATH_IDX_0);
1147 if ((DCAM_PATH_IDX_1 & path_index) && s_p_dcam_mod->dcam_path1.valide) {
1148 _dcam_wait_path_done(DCAM_PATH_IDX_1, &s_p_dcam_mod->dcam_path1.need_stop);
1149 _dcam_stop_path(DCAM_PATH_IDX_1);
1152 if ((DCAM_PATH_IDX_2 & path_index) && s_p_dcam_mod->dcam_path2.valide) {
1153 DCAM_TRACE("DCAM: stop path2 In \n");
1154 _dcam_wait_path_done(DCAM_PATH_IDX_2, &s_p_dcam_mod->dcam_path2.need_stop);
1155 _dcam_stop_path(DCAM_PATH_IDX_2);
1158 DCAM_TRACE("DCAM dcam_stop_path E: %d \n", path_index);
1163 LOCAL void _dcam_wait_for_channel_stop(enum dcam_path_index path_index)
1165 int time_out = 5000;
1168 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
1170 /* wait for AHB path busy cleared */
1172 if (s_p_dcam_mod->dcam_path1.valide && (DCAM_PATH_IDX_1 & path_index)) {
1173 ret = REG_RD(DCAM_AHBM_STS) & BIT_17;
1174 } else if (s_p_dcam_mod->dcam_path2.valide && (DCAM_PATH_IDX_2 & path_index)) {
1175 ret = REG_RD(DCAM_AHBM_STS) & BIT_18;
1177 } else if (s_p_dcam_mod->dcam_path0.valide && (DCAM_PATH_IDX_0 & path_index)) {
1178 ret = REG_RD(DCAM_AHBM_STS) & BIT_19;
1189 DCAM_TRACE("DCAM: wait channel stop %d %d \n", ret, time_out);
1194 LOCAL void _dcam_quickstop_set(enum dcam_path_index path_index, uint32_t path_rst, uint32_t path_bit,
1195 uint32_t cfg_bit, uint32_t ahbm_bit, uint32_t auto_copy_bit)
1197 dcam_glb_reg_owr(DCAM_AHBM_STS, ahbm_bit, DCAM_AHBM_STS_REG);
1199 dcam_glb_reg_mwr(DCAM_CFG, cfg_bit, ~cfg_bit, DCAM_CFG_REG);
1200 _dcam_wait_for_channel_stop(path_index);
1201 _dcam_force_copy(path_index);
1202 dcam_reset(path_rst, 1);
1203 dcam_glb_reg_awr(DCAM_AHBM_STS, ~ahbm_bit, DCAM_AHBM_STS_REG);
1208 #define DCAM_IRQ_MASK_PATH0 (0x0f|(0x03<<4)|(1<<12)|(1<<21)) //let other module continue
1209 #define DCAM_IRQ_MASK_PATH1 (0x0f|(0x03<<6)|(1<<16)|(1<<19)|(1<<22))
1210 #define DCAM_IRQ_MASK_PATH2 (0x0f|(0x03<<8)|(1<<17)|(1<<20)|(1<<23))
1212 LOCAL void _dcam_quickstop_set_all(enum dcam_path_index path_index, uint32_t path_bit, uint32_t cfg_bit, uint32_t ahbm_bit)
1214 dcam_glb_reg_owr(DCAM_AHBM_STS, BIT_3 | BIT_4 | BIT_5, DCAM_AHBM_STS_REG);
1216 dcam_glb_reg_awr(DCAM_CFG, ~(BIT_0 | BIT_1 | BIT_2), DCAM_CFG_REG);
1217 dcam_glb_reg_owr(DCAM_CONTROL, BIT_8 | BIT_10 | BIT_12, DCAM_CONTROL_REG);
1218 dcam_glb_reg_awr(DCAM_CONTROL, ~(BIT_8 | BIT_10 | BIT_12), DCAM_CONTROL_REG);
1219 _dcam_wait_for_channel_stop(DCAM_PATH_IDX_0);
1220 _dcam_wait_for_channel_stop(DCAM_PATH_IDX_1);
1221 _dcam_wait_for_channel_stop(DCAM_PATH_IDX_2);
1226 LOCAL void _dcam_wait_for_quickstop(enum dcam_path_index path_index)
1228 int time_out = 5000;
1230 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
1232 DCAM_TRACE("DCAM: state before stop 0x%x\n", s_p_dcam_mod->state);
1234 if (DCAM_PATH_IDX_ALL == path_index) {
1235 _dcam_quickstop_set_all(0, 0, 0, 0);
1237 if (s_p_dcam_mod->dcam_path0.valide && (DCAM_PATH_IDX_0 & path_index)) {
1238 _dcam_quickstop_set(DCAM_PATH_IDX_0, DCAM_RST_PATH0, DCAM_IRQ_MASK_PATH0, BIT_0, BIT_3, BIT_9);
1240 if (s_p_dcam_mod->dcam_path1.valide && (DCAM_PATH_IDX_1 & path_index)) {
1241 _dcam_quickstop_set(DCAM_PATH_IDX_1, DCAM_RST_PATH1, DCAM_IRQ_MASK_PATH1, BIT_1, BIT_4, BIT_11);
1243 if (s_p_dcam_mod->dcam_path2.valide && (DCAM_PATH_IDX_2 & path_index)) {
1244 _dcam_quickstop_set(DCAM_PATH_IDX_2, DCAM_RST_PATH2, DCAM_IRQ_MASK_PATH2, BIT_2, BIT_5, BIT_13);
1248 DCAM_TRACE("DCAM: exit _dcam_wait_for_quickstop %d state: 0x%x \n ", time_out, s_p_dcam_mod->state);
1253 int32_t dcam_stop(void)
1255 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
1258 DCAM_CHECK_ZERO(s_p_dcam_mod);
1260 s_p_dcam_mod->state |= DCAM_STATE_QUICKQUIT;
1261 printk("DCAM dcam_stop In \n");
1262 if (atomic_read(&s_resize_flag)) {
1263 s_p_dcam_mod->wait_resize_done = 1;
1264 rtn = down_timeout(&s_p_dcam_mod->resize_done_sema, DCAM_PATH_TIMEOUT);
1266 if (atomic_read(&s_rotation_flag)) {
1267 s_p_dcam_mod->wait_rotation_done = 1;
1268 rtn = down_timeout(&s_p_dcam_mod->rotation_done_sema, DCAM_PATH_TIMEOUT);
1271 mutex_lock(&dcam_sem);
1272 printk("DCAM dcam_stop get dcam_sem\n");
1273 spin_lock_irqsave(&dcam_lock, flag);
1275 dcam_glb_reg_owr(DCAM_INT_MASK,
1277 DCAM_INIT_MASK_REG);
1279 _dcam_wait_for_quickstop(DCAM_PATH_IDX_ALL);
1280 s_p_dcam_mod->dcam_path0.status = DCAM_ST_STOP;
1281 s_p_dcam_mod->dcam_path0.valide = 0;
1282 s_p_dcam_mod->dcam_path1.status = DCAM_ST_STOP;
1283 s_p_dcam_mod->dcam_path1.valide = 0;
1284 s_p_dcam_mod->dcam_path2.status = DCAM_ST_STOP;
1285 s_p_dcam_mod->dcam_path2.valide = 0;
1286 _dcam_frm_clear(DCAM_PATH_IDX_0);
1287 _dcam_frm_clear(DCAM_PATH_IDX_1);
1288 _dcam_frm_clear(DCAM_PATH_IDX_2);
1289 spin_unlock_irqrestore(&dcam_lock, flag);
1291 dcam_reset(DCAM_RST_ALL, 0);
1292 s_p_dcam_mod->state &= ~DCAM_STATE_QUICKQUIT;
1293 mutex_unlock(&dcam_sem);
1295 printk("DCAM: dcam_stop Out, s_resize_flag %d \n", atomic_read(&s_resize_flag));
1300 int32_t dcam_resume(void)
1302 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
1304 DCAM_CHECK_ZERO(s_p_dcam_mod);
1306 if (s_p_dcam_mod->dcam_path0.valide) {
1307 rtn = _dcam_path_set_next_frm(DCAM_PATH_IDX_0, true);
1309 _dcam_force_copy(DCAM_PATH_IDX_0);
1310 _dcam_frm_clear(DCAM_PATH_IDX_0);
1313 if (s_p_dcam_mod->dcam_path1.valide) {
1314 rtn = _dcam_path_set_next_frm(DCAM_PATH_IDX_1, true);
1316 _dcam_force_copy(DCAM_PATH_IDX_1);
1317 _dcam_frm_clear(DCAM_PATH_IDX_1);
1320 if (s_p_dcam_mod->dcam_path2.valide) {
1321 rtn = _dcam_path_set_next_frm(DCAM_PATH_IDX_2, true);
1323 _dcam_force_copy(DCAM_PATH_IDX_2);
1324 _dcam_frm_clear(DCAM_PATH_IDX_2);
1328 if (s_p_dcam_mod->dcam_path0.valide) {
1329 rtn = _dcam_path_set_next_frm(DCAM_PATH_IDX_0, false);
1331 dcam_glb_reg_owr(DCAM_CFG, BIT_0, DCAM_CFG_REG);
1332 _dcam_auto_copy_ext(DCAM_PATH_IDX_0, true, true);
1335 if (s_p_dcam_mod->dcam_path1.valide) {
1336 rtn = _dcam_path_set_next_frm(DCAM_PATH_IDX_1, false);
1338 dcam_glb_reg_owr(DCAM_CFG, BIT_1, DCAM_CFG_REG);
1339 _dcam_auto_copy_ext(DCAM_PATH_IDX_1, true, true);
1342 if (s_p_dcam_mod->dcam_path2.valide) {
1343 rtn = _dcam_path_set_next_frm(DCAM_PATH_IDX_2, false);
1345 dcam_glb_reg_owr(DCAM_CFG, BIT_2, DCAM_CFG_REG);
1346 _dcam_auto_copy_ext(DCAM_PATH_IDX_2, true, true);
1349 printk("DCAM R \n");
1351 dcam_glb_reg_owr(DCAM_CONTROL, BIT_2, DCAM_CONTROL_REG); /* Enable CAP */
1355 int32_t dcam_pause(void)
1357 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
1359 dcam_glb_reg_awr(DCAM_CONTROL, ~BIT_2, DCAM_CONTROL_REG); /* Disable CAP */
1360 printk("DCAM P \n");
1364 int32_t dcam_reg_isr(enum dcam_irq_id id, dcam_isr_func user_func, void* user_data)
1366 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
1369 if(id >= DCAM_IRQ_NUMBER) {
1370 rtn = DCAM_RTN_ISR_ID_ERR;
1372 spin_lock_irqsave(&dcam_lock, flag);
1373 s_user_func[id] = user_func;
1374 s_user_data[id] = user_data;
1375 spin_unlock_irqrestore(&dcam_lock, flag);
1380 int32_t dcam_cap_cfg(enum dcam_cfg_id id, void *param)
1382 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
1383 struct dcam_cap_desc *cap_desc = NULL;
1385 DCAM_CHECK_ZERO(s_p_dcam_mod);
1386 DCAM_CHECK_ZERO(s_dcam_sc_array);
1387 cap_desc = &s_p_dcam_mod->dcam_cap;
1389 case DCAM_CAP_SYNC_POL:
1391 struct dcam_cap_sync_pol *sync_pol = (struct dcam_cap_sync_pol*)param;
1393 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1395 if (DCAM_CAP_IF_CCIR == cap_desc->interface) {
1397 if (sync_pol->vsync_pol > 1 ||
1398 sync_pol->hsync_pol > 1 ||
1399 sync_pol->pclk_pol > 1) {
1400 rtn = DCAM_RTN_CAP_SYNC_POL_ERR;
1402 sci_glb_set(DCAM_CCIR_PCLK_EB, CCIR_PCLK_EB_BIT);
1403 REG_MWR(CAP_CCIR_CTRL, BIT_3, sync_pol->hsync_pol << 3);
1404 REG_MWR(CAP_CCIR_CTRL, BIT_4, sync_pol->vsync_pol << 4);
1405 //REG_MWR(CLK_DLY_CTRL, BIT_19, sync_pol->pclk_pol << 19); // aiden todo
1407 if (sync_pol->pclk_src == 0x00) {
1408 sci_glb_clr(CAP_CCIR_PLCK_SRC, (BIT_25 | BIT_26));
1409 DCAM_TRACE("DCAM: set pclk src0\n");
1410 } else if (sync_pol->pclk_src == 0x01) {
1411 sci_glb_clr(CAP_CCIR_PLCK_SRC, (BIT_25 | BIT_26));
1412 sci_glb_set(CAP_CCIR_PLCK_SRC, (BIT_25));
1413 DCAM_TRACE("DCAM: set pclk src1\n");
1415 DCAM_TRACE("DCAM: set pclk src default\n");
1419 if (sync_pol->need_href) {
1420 REG_MWR(CAP_MIPI_CTRL, BIT_5, 1 << 5);
1422 REG_MWR(CAP_MIPI_CTRL, BIT_5, 0 << 5);
1428 case DCAM_CAP_DATA_BITS:
1430 enum dcam_cap_data_bits bits = *(enum dcam_cap_data_bits*)param;
1432 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1434 if (DCAM_CAP_IF_CCIR == cap_desc->interface) {
1435 if (DCAM_CAP_8_BITS == bits || DCAM_CAP_10_BITS == bits) {
1436 REG_MWR(CAP_CCIR_CTRL, BIT_10 | BIT_9, 0 << 9);
1437 } else if (DCAM_CAP_4_BITS == bits) {
1438 REG_MWR(CAP_CCIR_CTRL, BIT_10 | BIT_9, 1 << 9);
1439 } else if (DCAM_CAP_2_BITS == bits) {
1440 REG_MWR(CAP_CCIR_CTRL, BIT_10 | BIT_9, 2 << 9);
1441 } else if (DCAM_CAP_1_BITS == bits) {
1442 REG_MWR(CAP_CCIR_CTRL, BIT_10 | BIT_9, 3 << 9);
1444 rtn = DCAM_RTN_CAP_IN_BITS_ERR;
1448 if (DCAM_CAP_12_BITS == bits) {
1449 REG_MWR(CAP_MIPI_CTRL, BIT_4 | BIT_3, 2 << 3);
1450 } else if (DCAM_CAP_10_BITS == bits) {
1451 REG_MWR(CAP_MIPI_CTRL, BIT_4 | BIT_3, 1 << 3);
1452 } else if (DCAM_CAP_8_BITS == bits) {
1453 REG_MWR(CAP_MIPI_CTRL, BIT_4 | BIT_3, 0 << 3);
1455 rtn = DCAM_RTN_CAP_IN_BITS_ERR;
1461 case DCAM_CAP_YUV_TYPE:
1463 enum dcam_cap_pattern pat = *(enum dcam_cap_pattern*)param;
1465 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1467 if (pat < DCAM_PATTERN_MAX) {
1468 if (DCAM_CAP_IF_CCIR == cap_desc->interface)
1469 REG_MWR(CAP_CCIR_CTRL, BIT_8 | BIT_7, pat << 7);
1471 REG_MWR(CAP_MIPI_CTRL, BIT_8 | BIT_7, pat << 7);
1473 rtn = DCAM_RTN_CAP_IN_YUV_ERR;
1478 case DCAM_CAP_PRE_SKIP_CNT:
1480 uint32_t skip_num = *(uint32_t*)param;
1482 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1484 if (skip_num > DCAM_CAP_SKIP_FRM_MAX) {
1485 rtn = DCAM_RTN_CAP_SKIP_FRAME_ERR;
1487 if (DCAM_CAP_IF_CCIR == cap_desc->interface)
1488 REG_MWR(CAP_CCIR_FRM_CTRL, BIT_3 | BIT_2 | BIT_1 | BIT_0, skip_num);
1490 REG_MWR(CAP_MIPI_FRM_CTRL, BIT_3 | BIT_2 | BIT_1 | BIT_0, skip_num);
1495 case DCAM_CAP_FRM_DECI:
1497 uint32_t deci_factor = *(uint32_t*)param;
1499 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1501 if (deci_factor < DCAM_FRM_DECI_FAC_MAX) {
1502 if (DCAM_CAP_IF_CCIR == cap_desc->interface)
1503 REG_MWR(CAP_CCIR_FRM_CTRL, BIT_5 | BIT_4, deci_factor << 4);
1505 REG_MWR(CAP_MIPI_FRM_CTRL, BIT_5 | BIT_4, deci_factor << 4);
1507 rtn = DCAM_RTN_CAP_FRAME_DECI_ERR;
1512 case DCAM_CAP_FRM_COUNT_CLR:
1513 if (DCAM_CAP_IF_CCIR == cap_desc->interface)
1514 REG_MWR(CAP_CCIR_FRM_CTRL, BIT_22, 1 << 22);
1516 REG_MWR(CAP_MIPI_FRM_CTRL, BIT_22, 1 << 22);
1519 case DCAM_CAP_INPUT_RECT:
1521 struct dcam_rect *rect = (struct dcam_rect*)param;
1524 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1526 if (rect->x > DCAM_CAP_FRAME_WIDTH_MAX ||
1527 rect->y > DCAM_CAP_FRAME_HEIGHT_MAX ||
1528 rect->w > DCAM_CAP_FRAME_WIDTH_MAX ||
1529 rect->h > DCAM_CAP_FRAME_HEIGHT_MAX ) {
1530 rtn = DCAM_RTN_CAP_FRAME_SIZE_ERR;
1535 if (DCAM_CAP_IF_CCIR == cap_desc->interface) {
1536 if (DCAM_CAP_MODE_RAWRGB == cap_desc->input_format) {
1537 tmp = rect->x | (rect->y << 16);
1538 REG_WR(CAP_CCIR_START, tmp);
1539 tmp = (rect->x + rect->w - 1);
1540 tmp |= (rect->y + rect->h - 1) << 16;
1541 REG_WR(CAP_CCIR_END, tmp);
1543 tmp = (rect->x << 1) | (rect->y << 16);
1544 REG_WR(CAP_CCIR_START, tmp);
1545 tmp = ((rect->x + rect->w) << 1) - 1;
1546 tmp |= (rect->y + rect->h - 1) << 16;
1547 REG_WR(CAP_CCIR_END, tmp);
1550 tmp = rect->x | (rect->y << 16);
1551 REG_WR(CAP_MIPI_START, tmp);
1552 tmp = (rect->x + rect->w - 1);
1553 tmp |= (rect->y + rect->h - 1) << 16;
1554 REG_WR(CAP_MIPI_END, tmp);
1559 case DCAM_CAP_IMAGE_XY_DECI:
1561 struct dcam_cap_dec *cap_dec = (struct dcam_cap_dec*)param;
1563 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1565 if (cap_dec->x_factor > DCAM_CAP_X_DECI_FAC_MAX ||
1566 cap_dec->y_factor > DCAM_CAP_Y_DECI_FAC_MAX ) {
1567 rtn = DCAM_RTN_CAP_XY_DECI_ERR;
1569 if (DCAM_CAP_MODE_RAWRGB == cap_desc->input_format) {
1570 if (cap_dec->x_factor > 1 ||
1571 cap_dec->y_factor > 1) {
1572 rtn = DCAM_RTN_CAP_XY_DECI_ERR;
1575 if (DCAM_CAP_IF_CCIR == cap_desc->interface) {
1576 REG_MWR(CAP_CCIR_IMG_DECI, BIT_1 | BIT_0, cap_dec->x_factor);
1577 REG_MWR(CAP_CCIR_IMG_DECI, BIT_3 | BIT_2, cap_dec->y_factor << 2);
1579 if (DCAM_CAP_MODE_RAWRGB == cap_desc->input_format) {
1580 // REG_MWR(CAP_MIPI_IMG_DECI, BIT_0, cap_dec->x_factor); // for camera path
1581 REG_MWR(CAP_MIPI_IMG_DECI, BIT_1, cap_dec->x_factor << 1);//for ISP
1583 REG_MWR(CAP_MIPI_IMG_DECI, BIT_1 | BIT_0, cap_dec->x_factor);
1584 REG_MWR(CAP_MIPI_IMG_DECI, BIT_3 | BIT_2, cap_dec->y_factor << 2);
1592 case DCAM_CAP_JPEG_SET_BUF_LEN:
1594 uint32_t jpg_buf_size = *(uint32_t*)param;
1596 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1597 jpg_buf_size = jpg_buf_size/DCAM_JPG_BUF_UNIT;
1598 if (jpg_buf_size >= DCAM_JPG_UNITS) {
1599 rtn = DCAM_RTN_CAP_JPEG_BUF_LEN_ERR;
1601 if (DCAM_CAP_IF_CCIR == cap_desc->interface)
1602 REG_WR(CAP_CCIR_JPG_CTRL,jpg_buf_size);
1604 REG_WR(CAP_MIPI_JPG_CTRL,jpg_buf_size);
1609 case DCAM_CAP_TO_ISP:
1611 uint32_t need_isp = *(uint32_t*)param;
1613 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1616 dcam_glb_reg_mwr(DCAM_CFG, BIT_7, 1 << 7, DCAM_CFG_REG);
1618 dcam_glb_reg_mwr(DCAM_CFG, BIT_7, 0 << 7, DCAM_CFG_REG);
1623 case DCAM_CAP_DATA_PACKET:
1625 uint32_t is_loose = *(uint32_t*)param;
1627 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1629 if (DCAM_CAP_IF_CSI2 == cap_desc->interface &&
1630 DCAM_CAP_MODE_RAWRGB == cap_desc->input_format) {
1632 REG_MWR(CAP_MIPI_CTRL, BIT_0, 1);
1634 REG_MWR(CAP_MIPI_CTRL, BIT_0, 0);
1637 rtn = DCAM_RTN_MODE_ERR;
1643 case DCAM_CAP_SAMPLE_MODE:
1645 enum dcam_capture_mode samp_mode = *(enum dcam_capture_mode*)param;
1647 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1649 if (samp_mode >= DCAM_CAPTURE_MODE_MAX) {
1650 rtn = DCAM_RTN_MODE_ERR;
1652 if (DCAM_CAP_IF_CSI2 == cap_desc->interface) {
1653 REG_MWR(CAP_MIPI_CTRL, BIT_6, samp_mode << 6);
1655 REG_MWR(CAP_CCIR_CTRL, BIT_6, samp_mode << 6);
1657 s_p_dcam_mod->dcam_mode = samp_mode;
1662 case DCAM_CAP_ZOOM_MODE:
1664 uint32_t zoom_mode = *(uint32_t*)param;
1666 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1668 //Zoom operation issue fix in Z3. enable smooth_zoom
1669 s_dcam_sc_array->is_smooth_zoom = 1;
1673 rtn = DCAM_RTN_IO_ID_ERR;
1681 int32_t dcam_cap_get_info(enum dcam_cfg_id id, void *param)
1683 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
1684 struct dcam_cap_desc *cap_desc = NULL;
1686 DCAM_CHECK_ZERO(s_p_dcam_mod);
1688 cap_desc = &s_p_dcam_mod->dcam_cap;
1689 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1692 case DCAM_CAP_FRM_COUNT_GET:
1693 if (DCAM_CAP_IF_CSI2 == cap_desc->interface) {
1694 *(uint32_t*)param = REG_RD(CAP_MIPI_FRM_CTRL) >> 16;
1696 *(uint32_t*)param = REG_RD(CAP_CCIR_FRM_CTRL) >> 16;
1700 case DCAM_CAP_JPEG_GET_LENGTH:
1701 if (DCAM_CAP_IF_CSI2 == cap_desc->interface) {
1702 *(uint32_t*)param = REG_RD(CAP_MIPI_FRM_SIZE);
1704 *(uint32_t*)param = REG_RD(CAP_CCIR_FRM_SIZE);
1708 rtn = DCAM_RTN_IO_ID_ERR;
1714 int32_t dcam_path0_cfg(enum dcam_cfg_id id, void *param)
1716 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
1717 struct dcam_path_desc *path = NULL;
1719 DCAM_CHECK_ZERO(s_p_dcam_mod);
1720 path = &s_p_dcam_mod->dcam_path0;
1723 case DCAM_PATH_INPUT_SIZE:
1725 struct dcam_size *size = (struct dcam_size*)param;
1727 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1729 DCAM_TRACE("DCAM: DCAM_PATH0_INPUT_SIZE {%d %d} \n", size->w, size->h);
1731 if (size->w > DCAM_PATH_FRAME_WIDTH_MAX ||
1732 size->h > DCAM_PATH_FRAME_HEIGHT_MAX) {
1733 rtn = DCAM_RTN_PATH_SRC_SIZE_ERR;
1737 path->input_size.w = size->w;
1738 path->input_size.h = size->h;
1739 path->valid_param.input_size = 1;
1744 case DCAM_PATH_INPUT_RECT:
1746 struct dcam_rect *rect = (struct dcam_rect*)param;
1748 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1750 DCAM_TRACE("DCAM: DCAM_PATH0_INPUT_RECT {%d %d %d %d} \n",
1756 if (rect->x > DCAM_PATH_FRAME_WIDTH_MAX ||
1757 rect->y > DCAM_PATH_FRAME_HEIGHT_MAX ||
1758 rect->w > DCAM_PATH_FRAME_WIDTH_MAX ||
1759 rect->h > DCAM_PATH_FRAME_HEIGHT_MAX) {
1760 rtn = DCAM_RTN_PATH_TRIM_SIZE_ERR;
1762 memcpy((void*)&path->input_rect,
1764 sizeof(struct dcam_rect));
1765 //if (path->input_rect.h >= DCAM_HEIGHT_MIN) {
1766 // path->input_rect.h--;
1768 /* path0 output size is different with other paths */
1769 path->output_size.w = rect->w;
1770 path->output_size.h = rect->h;
1771 path->valid_param.input_rect = 1;
1775 case DCAM_PATH_OUTPUT_SIZE:
1777 struct dcam_size *size = (struct dcam_size*)param;
1779 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1781 DCAM_TRACE("DCAM: DCAM_PATH2_OUTPUT_SIZE {%d %d} \n", size->w, size->h);
1782 if (size->w > DCAM_PATH_FRAME_WIDTH_MAX ||
1783 size->h > DCAM_PATH_FRAME_HEIGHT_MAX) {
1784 rtn = DCAM_RTN_PATH_SRC_SIZE_ERR;
1786 path->output_size.w = size->w;
1787 path->output_size.h = size->h;
1788 path->valid_param.output_size = 1;
1793 case DCAM_PATH_SRC_SEL:
1795 uint32_t src_sel = *(uint32_t*)param;
1797 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1799 if (src_sel >= DCAM_PATH_FROM_NONE) {
1800 rtn = DCAM_RTN_PATH_SRC_ERR;
1802 path->src_sel = src_sel;
1803 path->valid_param.src_sel = 1;
1808 case DCAM_PATH_OUTPUT_FORMAT:
1810 enum dcam_output_mode format = *(enum dcam_output_mode*)param;
1812 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1814 if((DCAM_OUTPUT_WORD != format) &&
1815 (DCAM_OUTPUT_HALF_WORD != format) &&
1816 (DCAM_OUTPUT_YVYU_1FRAME != format) &&
1817 (DCAM_OUTPUT_YUV420 != format)){
1818 rtn = DCAM_RTN_PATH_OUT_FMT_ERR;
1819 path->output_format = DCAM_FTM_MAX;
1821 path->output_format = format;
1822 path->valid_param.output_format = 1;
1827 case DCAM_PATH_FRAME_BASE_ID:
1829 uint32_t base_id = *(uint32_t*)param, i;
1831 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1833 DCAM_TRACE("DCAM: DCAM_PATH_FRAME_BASE_ID 0x%x \n", base_id);
1834 s_p_dcam_mod->dcam_path0.frame_base_id = base_id;
1838 case DCAM_PATH_FRAME_TYPE:
1840 struct dcam_frame *frame = &s_p_dcam_mod->dcam_path0.buf_queue.frame[0];
1841 uint32_t frm_type = *(uint32_t*)param, i;
1843 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1845 DCAM_TRACE("DCAM: DCAM_PATH_FRAME_TYPE 0x%x \n", frm_type);
1846 for (i = 0; i < DCAM_PATH_0_FRM_CNT_MAX; i++) {
1847 (frame+i)->type = frm_type;
1852 case DCAM_PATH_OUTPUT_ADDR:
1854 struct dcam_addr *p_addr = (struct dcam_addr*)param;
1856 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1857 if (DCAM_YUV_ADDR_INVALID(p_addr->yaddr, p_addr->uaddr, p_addr->vaddr)) {
1858 rtn = DCAM_RTN_PATH_ADDR_ERR;
1860 struct dcam_frame frame;
1861 memset((void*)&frame, 0, sizeof(struct dcam_frame));
1862 frame.yaddr = p_addr->yaddr;
1863 frame.uaddr = p_addr->uaddr;
1864 frame.vaddr = p_addr->vaddr;
1865 frame.yaddr_vir = p_addr->yaddr_vir;
1866 frame.uaddr_vir = p_addr->uaddr_vir;
1867 frame.vaddr_vir = p_addr->vaddr_vir;
1868 frame.type = DCAM_PATH0;
1869 frame.fid = s_p_dcam_mod->dcam_path0.frame_base_id;
1870 DCAM_TRACE("DCAM: Path 0 DCAM_PATH_OUTPUT_ADDR, i=%d, y=0x%x, u=0x%x, v=0x%x \n",
1871 path->output_frame_count, p_addr->yaddr, p_addr->uaddr, p_addr->vaddr);
1872 _dcam_buf_queue_write(&s_p_dcam_mod->dcam_path0.buf_queue, &frame);
1877 case DCAM_PATH_OUTPUT_RESERVED_ADDR:
1879 struct dcam_addr *p_addr = (struct dcam_addr*)param;
1881 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1883 if (DCAM_YUV_ADDR_INVALID(p_addr->yaddr, p_addr->uaddr, p_addr->vaddr)) {
1884 rtn = DCAM_RTN_PATH_ADDR_ERR;
1886 struct dcam_frame *frame = &s_p_dcam_mod->path0_reserved_frame;
1887 frame->yaddr = p_addr->yaddr;
1888 frame->uaddr = p_addr->uaddr;
1889 frame->vaddr = p_addr->vaddr;
1890 frame->yaddr_vir = p_addr->yaddr_vir;
1891 frame->uaddr_vir = p_addr->uaddr_vir;
1892 frame->vaddr_vir = p_addr->vaddr_vir;
1894 DCAM_TRACE("DCAM: Path 0 DCAM_PATH_OUTPUT_RESERVED_ADDR, i=%d, y=0x%x, u=0x%x, v=0x%x \n",
1895 path->output_frame_count, p_addr->yaddr, p_addr->uaddr, p_addr->vaddr);
1900 case DCAM_PATH_FRM_DECI:
1902 uint32_t deci_factor = *(uint32_t*)param;
1904 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1906 if (deci_factor >= DCAM_FRM_DECI_FAC_MAX) {
1907 rtn = DCAM_RTN_PATH_FRM_DECI_ERR;
1909 path->frame_deci = deci_factor;
1910 path->valid_param.frame_deci = 1;
1915 case DCAM_PATH_DATA_ENDIAN:
1917 struct dcam_endian_sel *endian = (struct dcam_endian_sel*)param;
1919 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1921 if (endian->y_endian >= DCAM_ENDIAN_MAX ||
1922 endian->uv_endian >= DCAM_ENDIAN_MAX) {
1923 rtn = DCAM_RTN_PATH_ENDIAN_ERR;
1925 path->data_endian.y_endian = endian->y_endian;
1926 path->data_endian.uv_endian = endian->uv_endian; /*Bug449569 NV12 support*/
1927 path->valid_param.data_endian = 1;
1933 case DCAM_PATH_ENABLE:
1935 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1936 path->valide = *(uint32_t*)param;
1940 case DCAM_PATH_ROT_MODE:
1942 uint32_t rot_mode = *(uint32_t*)param;
1943 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1944 if (rot_mode >= DCAM_PATH_FRAME_ROT_MAX) {
1945 rtn = DCAM_RTN_PATH_FRM_DECI_ERR;
1947 path->rot_mode = rot_mode;
1948 path->valid_param.rot_mode = 1;
1949 printk("zcf dcam_path0_cfg rot: = %d\n",path->rot_mode);
1955 rtn = DCAM_RTN_IO_ID_ERR;
1962 int32_t dcam_path1_cfg(enum dcam_cfg_id id, void *param)
1964 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
1965 struct dcam_path_desc *path = NULL;
1967 DCAM_CHECK_ZERO(s_p_dcam_mod);
1968 path = &s_p_dcam_mod->dcam_path1;
1971 case DCAM_PATH_INPUT_SIZE:
1973 struct dcam_size *size = (struct dcam_size*)param;
1975 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1977 DCAM_TRACE("DCAM: DCAM_PATH1_INPUT_SIZE {%d %d} \n", size->w, size->h);
1978 if (size->w > DCAM_PATH_FRAME_WIDTH_MAX ||
1979 size->h > DCAM_PATH_FRAME_HEIGHT_MAX) {
1980 rtn = DCAM_RTN_PATH_SRC_SIZE_ERR;
1982 path->input_size.w = size->w;
1983 path->input_size.h = size->h;
1984 path->valid_param.input_size = 1;
1989 case DCAM_PATH_INPUT_RECT:
1991 struct dcam_rect *rect = (struct dcam_rect*)param;
1993 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1995 DCAM_TRACE("DCAM: DCAM_PATH1_INPUT_RECT {%d %d %d %d} \n",
2001 if (rect->x > DCAM_PATH_FRAME_WIDTH_MAX ||
2002 rect->y > DCAM_PATH_FRAME_HEIGHT_MAX ||
2003 rect->w > DCAM_PATH_FRAME_WIDTH_MAX ||
2004 rect->h > DCAM_PATH_FRAME_HEIGHT_MAX) {
2005 rtn = DCAM_RTN_PATH_TRIM_SIZE_ERR;
2007 memcpy((void*)&path->input_rect,
2009 sizeof(struct dcam_rect));
2010 //if (path->input_rect.h >= DCAM_HEIGHT_MIN) {
2011 // path->input_rect.h--;
2013 path->valid_param.input_rect = 1;
2018 case DCAM_PATH_OUTPUT_SIZE:
2020 struct dcam_size *size = (struct dcam_size*)param;
2022 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2024 DCAM_TRACE("DCAM: DCAM_PATH1_OUTPUT_SIZE {%d %d} \n", size->w, size->h);
2025 if (size->w > DCAM_PATH_FRAME_WIDTH_MAX ||
2026 size->h > DCAM_PATH_FRAME_HEIGHT_MAX) {
2027 rtn = DCAM_RTN_PATH_SRC_SIZE_ERR;
2029 path->output_size.w = size->w;
2030 path->output_size.h = size->h;
2031 path->valid_param.output_size = 1;
2036 case DCAM_PATH_OUTPUT_FORMAT:
2038 enum dcam_fmt format = *(enum dcam_fmt*)param;
2040 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2042 path->output_format = format;
2044 if((DCAM_YUV422 != format) &&
2045 (DCAM_YUV420 != format) &&
2046 (DCAM_YUV420_3FRAME != format)){
2047 rtn = DCAM_RTN_PATH_OUT_FMT_ERR;
2048 path->output_format = DCAM_FTM_MAX;
2050 path->valid_param.output_format = 1;
2055 case DCAM_PATH_OUTPUT_ADDR:
2057 struct dcam_addr *p_addr = (struct dcam_addr*)param;
2059 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2060 if (DCAM_YUV_ADDR_INVALID(p_addr->yaddr, p_addr->uaddr, p_addr->vaddr)) {
2061 rtn = DCAM_RTN_PATH_ADDR_ERR;
2063 struct dcam_frame frame;
2064 memset((void*)&frame, 0, sizeof(struct dcam_frame));
2065 frame.yaddr = p_addr->yaddr;
2066 frame.uaddr = p_addr->uaddr;
2067 frame.vaddr = p_addr->vaddr;
2068 frame.yaddr_vir = p_addr->yaddr_vir;
2069 frame.uaddr_vir = p_addr->uaddr_vir;
2070 frame.vaddr_vir = p_addr->vaddr_vir;
2071 frame.type = DCAM_PATH1;
2072 frame.fid = s_p_dcam_mod->dcam_path1.frame_base_id;
2073 DCAM_TRACE("DCAM: Path 1 DCAM_PATH_OUTPUT_ADDR, i=%d, y=0x%x, u=0x%x, v=0x%x \n",
2074 path->output_frame_count, p_addr->yaddr, p_addr->uaddr, p_addr->vaddr);
2075 _dcam_buf_queue_write(&s_p_dcam_mod->dcam_path1.buf_queue, &frame);
2080 case DCAM_PATH_OUTPUT_RESERVED_ADDR:
2082 struct dcam_addr *p_addr = (struct dcam_addr*)param;
2084 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2086 if (DCAM_YUV_ADDR_INVALID(p_addr->yaddr, p_addr->uaddr, p_addr->vaddr)) {
2087 rtn = DCAM_RTN_PATH_ADDR_ERR;
2089 struct dcam_frame *frame = &s_p_dcam_mod->path1_reserved_frame;
2090 frame->yaddr = p_addr->yaddr;
2091 frame->uaddr = p_addr->uaddr;
2092 frame->vaddr = p_addr->vaddr;
2093 frame->yaddr_vir = p_addr->yaddr_vir;
2094 frame->uaddr_vir = p_addr->uaddr_vir;
2095 frame->vaddr_vir = p_addr->vaddr_vir;
2096 DCAM_TRACE("DCAM: Path 1 DCAM_PATH_OUTPUT_RESERVED_ADDR, i=%d, y=0x%x, u=0x%x, v=0x%x \n",
2097 path->output_frame_count, p_addr->yaddr, p_addr->uaddr, p_addr->vaddr);
2102 case DCAM_PATH_SRC_SEL:
2104 uint32_t src_sel = *(uint32_t*)param;
2106 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2108 if (src_sel >= DCAM_PATH_FROM_NONE) {
2109 rtn = DCAM_RTN_PATH_SRC_ERR;
2111 path->src_sel = src_sel;
2112 path->valid_param.src_sel = 1;
2117 case DCAM_PATH_FRAME_BASE_ID:
2119 uint32_t base_id = *(uint32_t*)param, i;
2121 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2123 DCAM_TRACE("DCAM: DCAM_PATH_FRAME_BASE_ID 0x%x \n", base_id);
2124 s_p_dcam_mod->dcam_path1.frame_base_id = base_id;
2128 case DCAM_PATH_DATA_ENDIAN:
2130 struct dcam_endian_sel *endian = (struct dcam_endian_sel*)param;
2132 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2134 if (endian->y_endian >= DCAM_ENDIAN_MAX ||
2135 endian->uv_endian >= DCAM_ENDIAN_MAX) {
2136 rtn = DCAM_RTN_PATH_ENDIAN_ERR;
2138 path->data_endian.y_endian = endian->y_endian;
2139 path->data_endian.uv_endian = endian->uv_endian;
2140 path->valid_param.data_endian = 1;
2145 case DCAM_PATH_ENABLE:
2147 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2148 path->valide = *(uint32_t*)param;
2152 case DCAM_PATH_FRAME_TYPE:
2154 struct dcam_frame *frame = &s_p_dcam_mod->dcam_path1.buf_queue.frame[0];
2155 uint32_t frm_type = *(uint32_t*)param, i;
2157 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2159 DCAM_TRACE("DCAM: DCAM_PATH_FRAME_TYPE 0x%x \n", frm_type);
2160 for (i = 0; i < DCAM_PATH_1_FRM_CNT_MAX; i++) {
2161 (frame+i)->type = frm_type;
2166 case DCAM_PATH_FRM_DECI:
2168 uint32_t deci_factor = *(uint32_t*)param;
2170 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2172 if (deci_factor >= DCAM_FRM_DECI_FAC_MAX) {
2173 rtn = DCAM_RTN_PATH_FRM_DECI_ERR;
2175 path->frame_deci = deci_factor;
2176 path->valid_param.frame_deci = 1;
2181 case DCAM_PATH_SHRINK:
2183 uint32_t shrink = *(uint32_t*)param;
2185 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2192 path->valid_param.shrink = 1;
2196 case DCAM_PATH_ROT_MODE:
2198 uint32_t rot_mode = *(uint32_t*)param;
2199 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2200 if (rot_mode >= DCAM_PATH_FRAME_ROT_MAX) {
2201 rtn = DCAM_RTN_PATH_FRM_DECI_ERR;
2203 path->rot_mode = rot_mode;
2204 path->valid_param.rot_mode = 1;
2205 printk("zcf dcam_path1_cfg rot:\n",path->rot_mode);
2217 int32_t dcam_path2_cfg(enum dcam_cfg_id id, void *param)
2219 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
2220 struct dcam_path_desc *path = NULL;
2222 DCAM_CHECK_ZERO(s_p_dcam_mod);
2223 path = &s_p_dcam_mod->dcam_path2;
2226 case DCAM_PATH_INPUT_SIZE:
2228 struct dcam_size *size = (struct dcam_size*)param;
2230 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2232 DCAM_TRACE("DCAM: DCAM_PATH2_INPUT_SIZE {%d %d} \n", size->w, size->h);
2233 if (size->w > DCAM_PATH_FRAME_WIDTH_MAX ||
2234 size->h > DCAM_PATH_FRAME_HEIGHT_MAX) {
2235 rtn = DCAM_RTN_PATH_SRC_SIZE_ERR;
2237 path->input_size.w = size->w;
2238 path->input_size.h = size->h;
2239 path->valid_param.input_size = 1;
2245 case DCAM_PATH_INPUT_RECT:
2247 struct dcam_rect *rect = (struct dcam_rect*)param;
2249 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2251 DCAM_TRACE("DCAM: DCAM_PATH2_INPUT_RECT {%d %d %d %d} \n",
2257 if (rect->x > DCAM_PATH_FRAME_WIDTH_MAX ||
2258 rect->y > DCAM_PATH_FRAME_HEIGHT_MAX ||
2259 rect->w > DCAM_PATH_FRAME_WIDTH_MAX ||
2260 rect->h > DCAM_PATH_FRAME_HEIGHT_MAX) {
2261 rtn = DCAM_RTN_PATH_TRIM_SIZE_ERR;
2263 memcpy((void*)&path->input_rect,
2265 sizeof(struct dcam_rect));
2267 if (path->input_rect.h >= DCAM_HEIGHT_MIN) {
2268 path->input_rect.h--;
2271 path->valid_param.input_rect = 1;
2276 case DCAM_PATH_OUTPUT_SIZE:
2278 struct dcam_size *size = (struct dcam_size*)param;
2280 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2282 DCAM_TRACE("DCAM: DCAM_PATH2_OUTPUT_SIZE {%d %d} \n", size->w, size->h);
2283 if (size->w > DCAM_PATH_FRAME_WIDTH_MAX ||
2284 size->h > DCAM_PATH_FRAME_HEIGHT_MAX) {
2285 rtn = DCAM_RTN_PATH_SRC_SIZE_ERR;
2287 path->output_size.w = size->w;
2288 path->output_size.h = size->h;
2289 path->valid_param.output_size = 1;
2294 case DCAM_PATH_OUTPUT_FORMAT:
2296 enum dcam_fmt format = *(enum dcam_fmt*)param;
2298 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2300 if((DCAM_YUV422 != format) &&
2301 (DCAM_YUV420 != format) &&
2302 (DCAM_YUV420_3FRAME != format)){
2303 rtn = DCAM_RTN_PATH_OUT_FMT_ERR;
2304 path->output_format = DCAM_FTM_MAX;
2306 path->output_format = format;
2307 path->valid_param.output_format = 1;
2312 case DCAM_PATH_OUTPUT_ADDR:
2314 struct dcam_addr *p_addr = (struct dcam_addr*)param;
2316 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2317 if (DCAM_YUV_ADDR_INVALID(p_addr->yaddr, p_addr->uaddr, p_addr->vaddr)) {
2318 rtn = DCAM_RTN_PATH_ADDR_ERR;
2320 struct dcam_frame frame;
2321 memset((void*)&frame, 0, sizeof(struct dcam_frame));
2322 frame.yaddr = p_addr->yaddr;
2323 frame.uaddr = p_addr->uaddr;
2324 frame.vaddr = p_addr->vaddr;
2325 frame.yaddr_vir = p_addr->yaddr_vir;
2326 frame.uaddr_vir = p_addr->uaddr_vir;
2327 frame.vaddr_vir = p_addr->vaddr_vir;
2328 frame.type = DCAM_PATH2;
2329 frame.fid = s_p_dcam_mod->dcam_path2.frame_base_id;
2330 DCAM_TRACE("DCAM: Path 2 DCAM_PATH_OUTPUT_ADDR, i=%d, y=0x%x, u=0x%x, v=0x%x \n",
2331 path->output_frame_count, p_addr->yaddr, p_addr->uaddr, p_addr->vaddr);
2332 _dcam_buf_queue_write(&s_p_dcam_mod->dcam_path2.buf_queue, &frame);
2337 case DCAM_PATH_OUTPUT_RESERVED_ADDR:
2339 struct dcam_addr *p_addr = (struct dcam_addr*)param;
2341 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2343 if (DCAM_YUV_ADDR_INVALID(p_addr->yaddr, p_addr->uaddr, p_addr->vaddr)) {
2344 rtn = DCAM_RTN_PATH_ADDR_ERR;
2346 struct dcam_frame *frame = &s_p_dcam_mod->path2_reserved_frame;
2347 frame->yaddr = p_addr->yaddr;
2348 frame->uaddr = p_addr->uaddr;
2349 frame->vaddr = p_addr->vaddr;
2350 frame->yaddr_vir = p_addr->yaddr_vir;
2351 frame->uaddr_vir = p_addr->uaddr_vir;
2352 frame->vaddr_vir = p_addr->vaddr_vir;
2353 DCAM_TRACE("DCAM: Path 1 DCAM_PATH_OUTPUT_RESERVED_ADDR, i=%d, y=0x%x, u=0x%x, v=0x%x \n",
2354 path->output_frame_count, p_addr->yaddr, p_addr->uaddr, p_addr->vaddr);
2359 case DCAM_PATH_SRC_SEL:
2361 uint32_t src_sel = *(uint32_t*)param;
2363 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2365 if (src_sel >= DCAM_PATH_FROM_NONE) {
2366 rtn = DCAM_RTN_PATH_SRC_ERR;
2368 path->src_sel = src_sel;
2369 path->valid_param.src_sel = 1;
2375 case DCAM_PATH_FRAME_BASE_ID:
2377 uint32_t base_id = *(uint32_t*)param, i;
2379 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2381 DCAM_TRACE("DCAM: DCAM_PATH_FRAME_BASE_ID 0x%x \n", base_id);
2382 s_p_dcam_mod->dcam_path2.frame_base_id = base_id;
2386 case DCAM_PATH_DATA_ENDIAN:
2388 struct dcam_endian_sel *endian = (struct dcam_endian_sel*)param;
2390 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2392 if (endian->y_endian >= DCAM_ENDIAN_MAX ||
2393 endian->uv_endian >= DCAM_ENDIAN_MAX) {
2394 rtn = DCAM_RTN_PATH_ENDIAN_ERR;
2396 path->data_endian.y_endian = endian->y_endian;
2397 path->data_endian.uv_endian = endian->uv_endian;
2398 path->valid_param.data_endian = 1;
2403 case DCAM_PATH_ENABLE:
2405 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2407 path->valide = *(uint32_t*)param;
2412 case DCAM_PATH_FRAME_TYPE:
2414 struct dcam_frame *frame = &s_p_dcam_mod->dcam_path2.buf_queue.frame[0];
2415 uint32_t frm_type = *(uint32_t*)param, i;
2417 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2419 DCAM_TRACE("DCAM: DCAM_PATH_FRAME_TYPE 0x%x \n", frm_type);
2420 for (i = 0; i < DCAM_PATH_2_FRM_CNT_MAX; i++) {
2421 (frame+i)->type = frm_type;
2426 case DCAM_PATH_FRM_DECI:
2428 uint32_t deci_factor = *(uint32_t*)param;
2430 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2432 if (deci_factor >= DCAM_FRM_DECI_FAC_MAX) {
2433 rtn = DCAM_RTN_PATH_FRM_DECI_ERR;
2435 path->frame_deci = deci_factor;
2436 path->valid_param.frame_deci = 1;
2441 case DCAM_PATH_SHRINK:
2443 uint32_t shrink = *(uint32_t*)param;
2445 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2452 path->valid_param.shrink = 1;
2456 case DCAM_PATH_ROT_MODE:
2458 uint32_t rot_mode = *(uint32_t*)param;
2459 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2460 if (rot_mode >= DCAM_PATH_FRAME_ROT_MAX) {
2461 rtn = DCAM_RTN_PATH_FRM_DECI_ERR;
2463 path->rot_mode = rot_mode;
2464 path->valid_param.rot_mode = 1;
2465 printk("zcf dcam_path2_cfg rot:\n",path->rot_mode);
2477 int32_t dcam_get_resizer(uint32_t wait_opt)
2481 printk("resizer_get:%d\n",current->pid);
2484 if( 0 == wait_opt) {
2485 rtn = mutex_trylock(&dcam_sem) ? 0 : 1;
2487 } else if (DCAM_WAIT_FOREVER == wait_opt){
2488 mutex_lock(&dcam_sem);
2491 return 0;//mutex_timeout(&dcam_sem, wait_opt);
2495 int32_t dcam_rel_resizer(void)
2497 printk("resizer_put:%d\n",current->pid);
2498 mutex_unlock(&dcam_sem);
2502 int32_t dcam_resize_start(void)
2504 atomic_inc(&s_resize_flag);
2505 mutex_lock(&dcam_scale_sema);
2509 int32_t dcam_resize_end(void)
2513 atomic_dec(&s_resize_flag);
2514 mutex_unlock(&dcam_scale_sema);
2516 spin_lock_irqsave(&dcam_mod_lock, flag);
2517 if (DCAM_ADDR_INVALID(s_p_dcam_mod)) {
2518 spin_unlock_irqrestore(&dcam_mod_lock, flag);
2523 if (s_p_dcam_mod->wait_resize_done) {
2524 up(&s_p_dcam_mod->resize_done_sema);
2525 s_p_dcam_mod->wait_resize_done = 0;
2528 spin_unlock_irqrestore(&dcam_mod_lock, flag);
2532 int32_t dcam_rotation_start(void)
2534 atomic_inc(&s_rotation_flag);
2535 mutex_lock(&dcam_rot_sema);
2539 int32_t dcam_rotation_end(void)
2543 atomic_dec(&s_rotation_flag);
2544 mutex_unlock(&dcam_rot_sema);
2546 spin_lock_irqsave(&dcam_mod_lock, flag);
2547 if (DCAM_ADDR_INVALID(s_p_dcam_mod)) {
2548 spin_unlock_irqrestore(&dcam_mod_lock, flag);
2553 if (s_p_dcam_mod->wait_rotation_done) {
2554 up(&s_p_dcam_mod->rotation_done_sema);
2555 s_p_dcam_mod->wait_rotation_done = 0;
2558 spin_unlock_irqrestore(&dcam_mod_lock, flag);
2562 void dcam_int_en(void)
2564 if (atomic_read(&s_dcam_users) == 1) {
2565 enable_irq(DCAM_IRQ);
2569 void dcam_int_dis(void)
2571 if (atomic_read(&s_dcam_users) == 1) {
2572 disable_irq(DCAM_IRQ);
2576 int32_t dcam_frame_is_locked(struct dcam_frame *frame)
2579 unsigned long flags;
2582 local_irq_save(flags);
2584 rtn = frame->lock == DCAM_FRM_LOCK_WRITE ? 1 : 0;
2585 local_irq_restore(flags);
2591 int32_t dcam_frame_lock(struct dcam_frame *frame)
2594 unsigned long flags;
2596 DCAM_CHECK_ZERO(s_p_dcam_mod);
2598 DCAM_TRACE("DCAM: lock %d \n", (uint32_t)(0xF&frame->fid));
2601 local_irq_save(flags);
2603 frame->lock = DCAM_FRM_LOCK_WRITE;
2605 rtn = DCAM_RTN_PARA_ERR;
2606 local_irq_restore(flags);
2612 int32_t dcam_frame_unlock(struct dcam_frame *frame)
2615 unsigned long flags;
2617 DCAM_CHECK_ZERO(s_p_dcam_mod);
2619 DCAM_TRACE("DCAM: unlock %d \n", (uint32_t)(0xF&frame->fid));
2622 local_irq_save(flags);
2624 frame->lock = DCAM_FRM_UNLOCK;
2626 rtn = DCAM_RTN_PARA_ERR;
2627 local_irq_restore(flags);
2633 int32_t dcam_read_registers(uint32_t* reg_buf, uint32_t *buf_len)
2635 uint32_t *reg_addr = (uint32_t*)DCAM_BASE;
2637 if (NULL == reg_buf || NULL == buf_len || 0 != (*buf_len % 4)) {
2641 while (buf_len != 0 && (uint32_t)reg_addr < DCAM_END) {
2642 *reg_buf++ = REG_RD(reg_addr);
2647 *buf_len = (uint32_t)reg_addr - DCAM_BASE;
2651 int32_t dcam_get_path_id(struct dcam_get_path_id *path_id, uint32_t *channel_id)
2653 int ret = DCAM_RTN_SUCCESS;
2655 if (NULL == path_id || NULL == channel_id) {
2659 printk("DCAM: fourcc 0x%x, input w %d, h %d output w %d, h %d input_trim %d %d %d %d shrink %d need_isp %d id:%d\n", path_id->fourcc,
2660 path_id->input_size.w, path_id->input_size.h,
2661 path_id->output_size.w, path_id->output_size.h,
2662 path_id->input_trim.x, path_id->input_trim.y, path_id->input_trim.w, path_id->input_trim.h,
2663 path_id->need_shrink, path_id->need_isp, path_id->camera_id);
2665 if (path_id->need_isp_tool) {
2666 *channel_id = DCAM_PATH0;
2667 } else if (V4L2_PIX_FMT_GREY == path_id->fourcc && !path_id->is_path_work[DCAM_PATH0]) {
2668 *channel_id = DCAM_PATH0;
2669 } else if (V4L2_PIX_FMT_JPEG == path_id->fourcc && !path_id->is_path_work[DCAM_PATH0]) {
2670 *channel_id = DCAM_PATH0;
2671 } else if (path_id->output_size.w <= DCAM_PATH1_LINE_BUF_LENGTH && !path_id->is_path_work[DCAM_PATH1]) {
2672 *channel_id = DCAM_PATH1;
2674 } else if (!path_id->need_shrink && path_id->need_isp && !path_id->is_path_work[DCAM_PATH0]
2675 && path_id->output_size.w == path_id->input_trim.w && path_id->output_size.h == path_id->input_trim.h) {
2676 *channel_id = DCAM_PATH0;
2677 if (1 == path_id->camera_id) {
2678 *channel_id = DCAM_PATH2;
2681 } else if (path_id->output_size.w <= DCAM_PATH2_LINE_BUF_LENGTH && !path_id->is_path_work[DCAM_PATH2]) {
2682 *channel_id = DCAM_PATH2;
2684 *channel_id = DCAM_PATH0;
2686 printk("DCAM: path id %d \n", *channel_id);
2691 int32_t dcam_get_path_capability(struct dcam_path_capability *capacity)
2693 int ret = DCAM_RTN_SUCCESS;
2695 if (NULL == capacity) {
2699 capacity->count = 3;
2700 capacity->path_info[DCAM_PATH0].line_buf = 0;
2702 capacity->path_info[DCAM_PATH0].support_yuv = 1;
2704 capacity->path_info[DCAM_PATH0].support_yuv = 0;
2706 capacity->path_info[DCAM_PATH0].support_raw = 1;
2707 capacity->path_info[DCAM_PATH0].support_jpeg = 1;
2708 capacity->path_info[DCAM_PATH0].support_scaling = 0;
2709 capacity->path_info[DCAM_PATH0].support_trim = 0;
2710 capacity->path_info[DCAM_PATH0].is_scaleing_path = 0;
2712 capacity->path_info[DCAM_PATH1].line_buf = DCAM_PATH1_LINE_BUF_LENGTH;
2713 capacity->path_info[DCAM_PATH1].support_yuv = 1;
2714 capacity->path_info[DCAM_PATH1].support_raw = 0;
2715 capacity->path_info[DCAM_PATH1].support_jpeg = 0;
2716 capacity->path_info[DCAM_PATH1].support_scaling = 1;
2717 capacity->path_info[DCAM_PATH1].support_trim = 1;
2718 capacity->path_info[DCAM_PATH1].is_scaleing_path = 0;
2720 capacity->path_info[DCAM_PATH2].line_buf = DCAM_PATH2_LINE_BUF_LENGTH;
2721 capacity->path_info[DCAM_PATH2].support_yuv = 1;
2722 capacity->path_info[DCAM_PATH2].support_raw = 0;
2723 capacity->path_info[DCAM_PATH2].support_jpeg = 0;
2724 capacity->path_info[DCAM_PATH2].support_scaling = 1;
2725 capacity->path_info[DCAM_PATH2].support_trim = 1;
2726 capacity->path_info[DCAM_PATH2].is_scaleing_path = 1;
2732 LOCAL irqreturn_t _dcam_isr_root(int irq, void *dev_id)
2734 uint32_t irq_line, status;
2738 DCAM_TRACE("DCAM: ISR 0x%x \n", REG_RD(DCAM_INT_STS));
2739 status = REG_RD(DCAM_INT_STS) & DCAM_IRQ_LINE_MASK;
2740 if (unlikely(0 == status)) {
2745 if (unlikely(DCAM_IRQ_ERR_MASK & status)) {
2746 if (_dcam_err_pre_proc()) {
2751 spin_lock_irqsave(&dcam_lock,flag);
2753 //for (i = DCAM_IRQ_NUMBER - 1; i >= 0; i--) {
2754 for (i = 0; i < DCAM_IRQ_NUMBER; i++) {
2755 if (irq_line & (1 << (uint32_t)i)) {
2760 irq_line &= ~(uint32_t)(1 << (uint32_t)i); //clear the interrupt flag
2761 if(!irq_line) //no interrupt source left
2765 REG_WR(DCAM_INT_CLR, status);
2766 DCAM_TRACE("DCAM: status 0x%x, ISR 0x%x \n", status, REG_RD(DCAM_INT_STS));
2768 spin_unlock_irqrestore(&dcam_lock, flag);
2773 LOCAL void _dcam_path0_set(void)
2775 uint32_t reg_val = 0;
2776 struct dcam_path_desc *path = NULL;
2778 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
2779 path = &s_p_dcam_mod->dcam_path0;
2780 if (path->valid_param.input_size) {
2781 reg_val = path->input_size.w | (path->input_size.h << 16);
2782 REG_WR(DCAM_PATH0_SRC_SIZE, reg_val);
2785 if (path->valid_param.input_rect) {
2786 reg_val = path->input_rect.x | (path->input_rect.y << 16);
2787 REG_WR(DCAM_PATH0_TRIM_START, reg_val);
2788 reg_val = path->input_rect.w | (path->input_rect.h << 16);
2789 REG_WR(DCAM_PATH0_TRIM_SIZE, reg_val);
2790 DCAM_TRACE("DCAM: path0 set: rect {%d %d %d %d} \n",
2794 path->input_rect.h);
2797 if (path->valid_param.src_sel) {
2798 REG_MWR(DCAM_CFG, BIT_10 , path->src_sel << 10);
2799 DCAM_TRACE("DCAM: path 0: src_sel=0x%x \n", path->src_sel);
2802 if (path->valid_param.frame_deci) {
2803 REG_MWR(DCAM_PATH0_CFG, BIT_1 | BIT_0, path->frame_deci << 0);
2806 if (path->valid_param.output_format) {
2807 enum dcam_output_mode format = path->output_format;
2808 REG_MWR(DCAM_PATH0_CFG, BIT_2 | BIT_3, format << 2);
2809 DCAM_TRACE("DCAM: path 0: output_format=0x%x \n", format);
2812 if (path->valid_param.data_endian) {
2813 dcam_glb_reg_mwr(DCAM_ENDIAN_SEL, BIT_5 | BIT_4, path->data_endian.y_endian << 4, DCAM_ENDIAN_REG);
2814 if (DCAM_ENDIAN_BIG == path->data_endian.y_endian) {
2815 if (DCAM_ENDIAN_LITTLE == path->data_endian.uv_endian ||
2816 DCAM_ENDIAN_HALFBIG == path->data_endian.uv_endian) {
2817 dcam_glb_reg_mwr(DCAM_ENDIAN_SEL, BIT_20, 1 << 20, DCAM_ENDIAN_REG);
2819 dcam_glb_reg_mwr(DCAM_ENDIAN_SEL, BIT_20, 0, DCAM_ENDIAN_REG);
2821 } else if (DCAM_ENDIAN_LITTLE == path->data_endian.y_endian) {
2822 if (DCAM_ENDIAN_BIG == path->data_endian.uv_endian ||
2823 DCAM_ENDIAN_HALFBIG == path->data_endian.uv_endian) {
2824 dcam_glb_reg_mwr(DCAM_ENDIAN_SEL, BIT_20, 1 << 20, DCAM_ENDIAN_REG);
2826 dcam_glb_reg_mwr(DCAM_ENDIAN_SEL, BIT_20, 0, DCAM_ENDIAN_REG);
2829 printk("DCAM DRV: endian, do nothing u %d, v %d \n",
2830 path->data_endian.y_endian,
2831 path->data_endian.uv_endian);
2834 if(path->valid_param.rot_mode) {
2835 path->valid_param.rot_mode = 0;
2836 printk("zcf dcam_path2_set rot_mod :%d reg:%x\n",path->rot_mode,REG_RD(DCAM_PATH2_CFG));
2837 REG_MWR(DCAM_PATH2_CFG, BIT_10 | BIT_9, path->rot_mode << 9);
2838 printk("zcf dcam_path2_set rot_mod :%d reg:%x\n",path->rot_mode,REG_RD(DCAM_PATH2_CFG));
2841 dcam_glb_reg_mwr(DCAM_ENDIAN_SEL, BIT_18, BIT_18, DCAM_ENDIAN_REG); // axi write
2842 dcam_glb_reg_mwr(DCAM_ENDIAN_SEL, BIT_19, BIT_19, DCAM_ENDIAN_REG); // axi read
2843 DCAM_TRACE("DCAM DRV: path 0: data_endian y=0x%x, uv=0x%x \n",
2844 path->data_endian.y_endian, path->data_endian.uv_endian);
2848 LOCAL void _dcam_path1_set(struct dcam_path_desc *path)
2850 uint32_t reg_val = 0;
2852 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
2853 DCAM_CHECK_ZERO_VOID(path);
2855 if (path->valid_param.input_size) {
2856 reg_val = path->input_size.w | (path->input_size.h << 16);
2857 REG_WR(DCAM_PATH1_SRC_SIZE, reg_val);
2858 DCAM_TRACE("DCAM: path1 set: src {%d %d} \n",path->input_size.w, path->input_size.h);
2861 if (path->valid_param.input_rect) {
2862 reg_val = path->input_rect.x | (path->input_rect.y << 16);
2863 REG_WR(DCAM_PATH1_TRIM_START, reg_val);
2864 reg_val = path->input_rect.w | (path->input_rect.h << 16);
2865 REG_WR(DCAM_PATH1_TRIM_SIZE, reg_val);
2866 DCAM_TRACE("DCAM: path1 set: rect {%d %d %d %d} \n",
2870 path->input_rect.h);
2873 if (path->valid_param.output_size) {
2874 reg_val = path->output_size.w | (path->output_size.h << 16);
2875 REG_WR(DCAM_PATH1_DST_SIZE, reg_val);
2876 DCAM_TRACE("DCAM: path1 set: dst {%d %d} \n",path->output_size.w, path->output_size.h);
2879 if (path->valid_param.output_format) {
2880 enum dcam_fmt format = path->output_format;
2881 if (DCAM_YUV422 == format) {
2882 REG_MWR(DCAM_PATH1_CFG, BIT_7 | BIT_6, 0 << 6);
2883 } else if (DCAM_YUV420 == format) {
2884 REG_MWR(DCAM_PATH1_CFG, BIT_7 | BIT_6, 1 << 6);
2885 } else if (DCAM_YUV420_3FRAME == format) {
2886 REG_MWR(DCAM_PATH1_CFG, BIT_7 | BIT_6, 3 << 6);
2888 DCAM_TRACE("DCAM: invalid path 1 output format %d \n", format);
2890 DCAM_TRACE("DCAM: path 1: output_format=0x%x \n", format);
2893 if (path->valid_param.src_sel) {
2894 REG_MWR(DCAM_CFG, BIT_12 | BIT_11, path->src_sel << 11);
2895 DCAM_TRACE("DCAM: path 1: src_sel=0x%x \n", path->src_sel);
2898 if (path->valid_param.data_endian) {
2899 dcam_glb_reg_mwr(DCAM_ENDIAN_SEL, BIT_7 | BIT_6, path->data_endian.y_endian << 6, DCAM_ENDIAN_REG);
2900 dcam_glb_reg_mwr(DCAM_ENDIAN_SEL, BIT_9 | BIT_8, path->data_endian.uv_endian << 8, DCAM_ENDIAN_REG);
2901 dcam_glb_reg_mwr(DCAM_ENDIAN_SEL, BIT_18, BIT_18, DCAM_ENDIAN_REG); // axi write
2902 dcam_glb_reg_mwr(DCAM_ENDIAN_SEL, BIT_19, BIT_19, DCAM_ENDIAN_REG); // axi read
2903 DCAM_TRACE("DCAM: path 1: data_endian y=0x%x, uv=0x%x \n",
2904 path->data_endian.y_endian, path->data_endian.uv_endian);
2907 if (path->valid_param.frame_deci) {
2908 REG_MWR(DCAM_PATH0_CFG, BIT_24 | BIT_23, path->frame_deci << 23);
2909 DCAM_TRACE("DCAM: path 1: frame_deci=0x%x \n", path->frame_deci);
2912 if (path->valid_param.scale_tap) {
2913 path->valid_param.scale_tap = 0;
2914 REG_MWR(DCAM_PATH1_CFG, BIT_19 | BIT_18 | BIT_17 | BIT_16, (path->scale_tap.y_tap & 0x0F) << 16);
2915 REG_MWR(DCAM_PATH1_CFG, BIT_15 | BIT_14 | BIT_13 | BIT_12 | BIT_11, (path->scale_tap.uv_tap & 0x1F) << 11);
2916 DCAM_TRACE("DCAM: path 1: scale_tap, y=0x%x, uv=0x%x \n", path->scale_tap.y_tap, path->scale_tap.uv_tap);
2919 if (path->valid_param.v_deci) {
2920 path->valid_param.v_deci = 0;
2921 REG_MWR(DCAM_PATH1_CFG, BIT_2, path->deci_val.deci_x_en << 2);
2922 REG_MWR(DCAM_PATH1_CFG, BIT_1 | BIT_0, path->deci_val.deci_x);
2924 REG_MWR(DCAM_PATH1_CFG, BIT_5, path->deci_val.deci_y_en << 5);
2925 REG_MWR(DCAM_PATH1_CFG, BIT_4 | BIT_3, path->deci_val.deci_y << 3);
2926 DCAM_TRACE("DCAM: path 1: deci, x_en=%d, x=%d, y_en=%d, y=%d \n",
2927 path->deci_val.deci_x_en, path->deci_val.deci_x, path->deci_val.deci_y_en, path->deci_val.deci_y);
2930 if(path->valid_param.rot_mode){
2931 path->valid_param.rot_mode = 0;
2932 printk("zcf dcam_path1_set 1 rot_mod :%d reg:%x\n",path->rot_mode,REG_RD(DCAM_PATH1_CFG));
2933 REG_MWR(DCAM_PATH1_CFG, BIT_10 | BIT_9, path->rot_mode << 9);
2934 printk("zcf dcam_path1_set 1 rot_mod :%d reg:%x\n",path->rot_mode,REG_RD(DCAM_PATH1_CFG));
2937 if (path->valid_param.shrink) {
2938 path->valid_param.shrink = 0;
2939 REG_MWR(DCAM_PATH1_CFG, BIT_25 | BIT_26, path->shrink << 25);
2940 printk("DCAM: path 1: shrink, %d \n", path->shrink);
2945 LOCAL void _dcam_path2_set(void)
2947 struct dcam_path_desc *path = NULL;
2948 uint32_t reg_val = 0;
2950 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
2951 path = &s_p_dcam_mod->dcam_path2;
2952 if (path->valid_param.input_size) {
2953 reg_val = path->input_size.w | (path->input_size.h << 16);
2954 REG_WR(DCAM_PATH2_SRC_SIZE, reg_val);
2955 DCAM_TRACE("DCAM: path2 set: src {%d %d} \n",path->input_size.w, path->input_size.h);
2958 if (path->valid_param.input_rect) {
2959 reg_val = path->input_rect.x | (path->input_rect.y << 16);
2960 REG_WR(DCAM_PATH2_TRIM_START, reg_val);
2961 reg_val = path->input_rect.w | (path->input_rect.h << 16);
2962 REG_WR(DCAM_PATH2_TRIM_SIZE, reg_val);
2963 DCAM_TRACE("DCAM: path2 set: rect {%d %d %d %d} \n",
2967 path->input_rect.h);
2970 if(path->valid_param.output_size){
2971 reg_val = path->output_size.w | (path->output_size.h << 16);
2972 REG_WR(DCAM_PATH2_DST_SIZE, reg_val);
2973 DCAM_TRACE("DCAM: path2 set: dst {%d %d} \n",path->output_size.w, path->output_size.h);
2976 if (path->valid_param.output_format) {
2977 enum dcam_fmt format = path->output_format;
2979 // REG_MWR(DCAM_PATH2_CFG, BIT_8, 0 << 8); // aiden todo
2981 if (DCAM_YUV422 == format) {
2982 REG_MWR(DCAM_PATH2_CFG, BIT_7 | BIT_6, 0 << 6);
2983 } else if (DCAM_YUV420 == format) {
2984 REG_MWR(DCAM_PATH2_CFG, BIT_7 | BIT_6, 1 << 6);
2985 } else if (DCAM_YUV420_3FRAME == format) {
2986 REG_MWR(DCAM_PATH2_CFG, BIT_7 | BIT_6, 3 << 6);
2988 DCAM_TRACE("DCAM: invalid path 2 output format %d \n", format);
2990 DCAM_TRACE("DCAM: path 2: output_format=0x%x \n", format);
2993 if (path->valid_param.src_sel) {
2994 REG_MWR(DCAM_CFG, BIT_14 | BIT_13, path->src_sel << 13);
2997 if (path->valid_param.data_endian) {
2998 dcam_glb_reg_mwr(DCAM_ENDIAN_SEL, BIT_11 | BIT_10, path->data_endian.y_endian << 10,DCAM_ENDIAN_REG );
2999 dcam_glb_reg_mwr(DCAM_ENDIAN_SEL, BIT_13 | BIT_12, path->data_endian.uv_endian << 12, DCAM_ENDIAN_REG);
3000 dcam_glb_reg_mwr(DCAM_ENDIAN_SEL, BIT_18, BIT_18, DCAM_ENDIAN_REG); // axi write
3001 dcam_glb_reg_mwr(DCAM_ENDIAN_SEL, BIT_19, BIT_19, DCAM_ENDIAN_REG); // axi read
3002 DCAM_TRACE("DCAM: path 2: data_endian y=0x%x, uv=0x%x \n",
3003 path->data_endian.y_endian, path->data_endian.uv_endian);
3006 if (path->valid_param.frame_deci) {
3007 REG_MWR(DCAM_PATH0_CFG, BIT_24 | BIT_23, path->frame_deci << 23);
3008 DCAM_TRACE("DCAM: path 2: frame_deci=0x%x \n", path->frame_deci);
3011 if (path->valid_param.scale_tap) {
3012 path->valid_param.scale_tap = 0;
3013 REG_MWR(DCAM_PATH2_CFG, BIT_19 | BIT_18 | BIT_17 | BIT_16, (path->scale_tap.y_tap & 0x0F) << 16);
3014 REG_MWR(DCAM_PATH2_CFG, BIT_15 | BIT_14 | BIT_13 | BIT_12 | BIT_11, (path->scale_tap.uv_tap & 0x1F) << 11);
3015 DCAM_TRACE("DCAM: path 2: scale_tap, y=0x%x, uv=0x%x \n",
3016 path->scale_tap.y_tap, path->scale_tap.uv_tap);
3019 if (path->valid_param.v_deci) {
3020 path->valid_param.v_deci = 0;
3021 REG_MWR(DCAM_PATH2_CFG, BIT_2, path->deci_val.deci_x_en << 2);
3022 REG_MWR(DCAM_PATH2_CFG, BIT_1 | BIT_0, path->deci_val.deci_x);
3024 REG_MWR(DCAM_PATH2_CFG, BIT_5, path->deci_val.deci_y_en << 5);
3025 REG_MWR(DCAM_PATH2_CFG, BIT_4 | BIT_3, path->deci_val.deci_y << 3);
3026 DCAM_TRACE("DCAM: path 2: deci, x_en=%d, x=%d, y_en=%d, y=%d \n",
3027 path->deci_val.deci_x_en, path->deci_val.deci_x, path->deci_val.deci_y_en, path->deci_val.deci_y);
3030 if (path->valid_param.rot_mode){
3031 path->valid_param.rot_mode = 0;
3032 printk("zcf dcam_path2_set rot_mod :%d reg:%x\n",path->rot_mode,REG_RD(DCAM_PATH2_CFG));
3033 REG_MWR(DCAM_PATH2_CFG, BIT_10 | BIT_9, path->rot_mode << 9);
3034 printk("zcf dcam_path2_set rot_mod :%d reg:%x\n",path->rot_mode,REG_RD(DCAM_PATH2_CFG));
3037 if (path->valid_param.shrink) {
3038 path->valid_param.shrink = 0;
3039 REG_MWR(DCAM_PATH2_CFG, BIT_25 | BIT_26, path->shrink << 25);
3040 printk("DCAM: path 2: shrink, %d \n", path->shrink);
3045 LOCAL void _dcam_buf_queue_init(struct dcam_buf_queue *queue)
3047 if (DCAM_ADDR_INVALID(queue)) {
3048 printk("DCAM: invalid heap 0x%x \n", (uint32_t)queue);
3052 memset((void*)queue, 0, sizeof(struct dcam_buf_queue));
3053 queue->write = &queue->frame[0];
3054 queue->read = &queue->frame[0];
3055 spin_lock_init(&queue->lock);
3059 LOCAL int32_t _dcam_buf_queue_write(struct dcam_buf_queue *queue, struct dcam_frame *frame)
3061 int ret = DCAM_RTN_SUCCESS;
3062 struct dcam_frame *ori_frame;
3065 if (DCAM_ADDR_INVALID(queue) || DCAM_ADDR_INVALID(frame)) {
3066 printk("DCAM: enq, invalid param 0x%x, 0x%x \n",
3072 spin_lock_irqsave(&queue->lock, flag);
3073 ori_frame = queue->write;
3074 DCAM_TRACE("DCAM: _dcam_buf_queue_write \n");
3075 *queue->write++ = *frame;
3076 if (queue->write > &queue->frame[DCAM_FRM_CNT_MAX-1]) {
3077 queue->write = &queue->frame[0];
3080 if (queue->write == queue->read) {
3081 queue->write = ori_frame;
3082 printk("DCAM: warning, queue is full, cannot write 0x%lx \n", frame->yaddr);
3084 spin_unlock_irqrestore(&queue->lock, flag);
3085 DCAM_TRACE("DCAM: _dcam_buf_queue_write type %d \n", frame->type);
3089 LOCAL int32_t _dcam_buf_queue_read(struct dcam_buf_queue *queue, struct dcam_frame *frame)
3091 int ret = DCAM_RTN_SUCCESS;
3094 if (DCAM_ADDR_INVALID(queue) || DCAM_ADDR_INVALID(frame)) {
3095 printk("DCAM: deq, invalid param 0x%x, 0x%x \n",
3101 DCAM_TRACE("DCAM: _dcam_buf_queue_read \n");
3103 spin_lock_irqsave(&queue->lock, flag);
3104 if (queue->read != queue->write) {
3105 *frame = *queue->read++;
3106 if (queue->read > &queue->frame[DCAM_FRM_CNT_MAX-1]) {
3107 queue->read = &queue->frame[0];
3112 spin_unlock_irqrestore(&queue->lock, flag);
3113 DCAM_TRACE("DCAM: _dcam_buf_queue_read type %d \n", frame->type);
3117 LOCAL void _dcam_frm_queue_clear(struct dcam_frm_queue *queue)
3119 if (DCAM_ADDR_INVALID(queue)) {
3120 printk("DCAM: invalid heap 0x%x \n", (uint32_t)queue);
3124 memset((void*)queue, 0, sizeof(struct dcam_frm_queue));
3128 LOCAL int32_t _dcam_frame_enqueue(struct dcam_frm_queue *queue, struct dcam_frame *frame)
3130 if (DCAM_ADDR_INVALID(queue) || DCAM_ADDR_INVALID(frame)) {
3131 printk("DCAM: enq, invalid param 0x%x, 0x%x \n",
3136 if (queue->valid_cnt >= DCAM_FRM_QUEUE_LENGTH) {
3137 printk("DCAM: q over flow \n");
3140 //queue->frm_array[queue->valid_cnt] = frame;
3141 memcpy(&queue->frm_array[queue->valid_cnt], frame, sizeof(struct dcam_frame));
3142 queue->valid_cnt ++;
3143 DCAM_TRACE("DCAM: en queue, %d, %d, 0x%x, 0x%x \n",
3151 LOCAL int32_t _dcam_frame_dequeue(struct dcam_frm_queue *queue, struct dcam_frame *frame)
3155 if (DCAM_ADDR_INVALID(queue) || DCAM_ADDR_INVALID(frame)) {
3156 printk("DCAM: deq, invalid param 0x%x, 0x%x \n",
3161 if (queue->valid_cnt == 0) {
3162 printk("DCAM: q under flow \n");
3166 //*frame = queue->frm_array[0];
3167 memcpy(frame, &queue->frm_array[0], sizeof(struct dcam_frame));
3169 for (i = 0; i < queue->valid_cnt; i++) {
3170 //queue->frm_array[i] = queue->frm_array[i+1];
3171 memcpy(&queue->frm_array[i], &queue->frm_array[i+1], sizeof(struct dcam_frame));
3173 DCAM_TRACE("DCAM: de queue, %d, %d \n",
3174 (0xF & (frame)->fid),
3179 LOCAL void _dcam_frm_clear(enum dcam_path_index path_index)
3183 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3185 if (DCAM_PATH_IDX_0 & path_index) {
3186 _dcam_frm_queue_clear(&s_p_dcam_mod->dcam_path0.frame_queue);
3187 _dcam_buf_queue_init(&s_p_dcam_mod->dcam_path0.buf_queue);
3190 if (DCAM_PATH_IDX_1 & path_index) {
3191 _dcam_frm_queue_clear(&s_p_dcam_mod->dcam_path1.frame_queue);
3192 _dcam_buf_queue_init(&s_p_dcam_mod->dcam_path1.buf_queue);
3195 if (DCAM_PATH_IDX_2 & path_index) {
3196 _dcam_frm_queue_clear(&s_p_dcam_mod->dcam_path2.frame_queue);
3197 _dcam_buf_queue_init(&s_p_dcam_mod->dcam_path2.buf_queue);
3203 LOCAL void _dcam_frm_pop(enum dcam_path_index path_index)
3206 struct dcam_frame *frame = NULL;
3207 uint32_t *frame_count;
3209 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3211 if (DCAM_PATH_IDX_0 & path_index) {
3212 frame = &s_p_dcam_mod->path0_frame[0];
3213 frame_count = &s_p_dcam_mod->dcam_path0.output_frame_count;
3215 if (DCAM_PATH_IDX_1 & path_index) {
3216 frame = &s_p_dcam_mod->path1_frame[0];
3217 frame_count = &s_p_dcam_mod->dcam_path1.output_frame_count;
3219 if (DCAM_PATH_IDX_2 & path_index) {
3220 frame = &s_p_dcam_mod->path2_frame[0];
3221 frame_count = &s_p_dcam_mod->dcam_path2.output_frame_count;
3223 printk("DCAM: frame pop index %d frame_count %d addr 0x%x \n", path_index, *frame_count, frame->yaddr);
3224 if (0 == *frame_count) {
3228 for (i = 0; i < *frame_count - 1; i++) {
3229 memcpy(frame+i, frame+i+1, sizeof(struct dcam_frame));
3232 //memset(frame+(*frame_count), 0, sizeof(struct dcam_frame));
3233 (frame+(*frame_count))->yaddr = 0;
3234 (frame+(*frame_count))->uaddr = 0;
3235 (frame+(*frame_count))->vaddr = 0;
3237 if (0 == *frame_count) {
3238 //_dcam_wait_for_quickstop(path_index);
3240 DCAM_TRACE("DCAM: frame pop done \n");
3246 LOCAL void _dcam_link_frm(uint32_t base_id)
3249 struct dcam_frame *path0_frame = NULL;
3250 struct dcam_frame *path1_frame = NULL;
3251 struct dcam_frame *path2_frame = NULL;
3253 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3255 path0_frame = &s_p_dcam_mod->path0_frame[0];
3256 path1_frame = &s_p_dcam_mod->path1_frame[0];
3257 path2_frame = &s_p_dcam_mod->path2_frame[0];
3258 for (i = 0; i < DCAM_PATH_0_FRM_CNT_MAX; i++) {
3259 DCAM_CLEAR(path0_frame + i);
3260 //(path0_frame+i)->next = path0_frame + (i + 1) % DCAM_PATH_0_FRM_CNT_MAX;
3261 //(path0_frame+i)->prev = path0_frame + (i - 1 + DCAM_PATH_0_FRM_CNT_MAX) % DCAM_PATH_0_FRM_CNT_MAX;
3262 (path0_frame+i)->fid = base_id + i;
3265 for (i = 0; i < DCAM_PATH_1_FRM_CNT_MAX; i++) {
3266 DCAM_CLEAR(path1_frame + i);
3267 //(path1_frame+i)->next = path1_frame + (i + 1) % DCAM_PATH_1_FRM_CNT_MAX;
3268 //(path1_frame+i)->prev = path1_frame + (i - 1 + DCAM_PATH_1_FRM_CNT_MAX) % DCAM_PATH_1_FRM_CNT_MAX;
3269 (path1_frame+i)->fid = base_id + i;
3272 for (i = 0; i < DCAM_PATH_2_FRM_CNT_MAX; i++) {
3273 DCAM_CLEAR(path2_frame + i);
3274 //(path2_frame+i)->next = path2_frame+(i + 1) % DCAM_PATH_2_FRM_CNT_MAX;
3275 //(path2_frame+i)->prev = path2_frame+(i - 1 + DCAM_PATH_2_FRM_CNT_MAX) % DCAM_PATH_2_FRM_CNT_MAX;
3276 (path2_frame+i)->fid = base_id + i;
3279 //s_p_dcam_mod->dcam_path0.output_frame_head = path0_frame;
3280 //s_p_dcam_mod->dcam_path1.output_frame_head = path1_frame;
3281 //s_p_dcam_mod->dcam_path2.output_frame_head = path2_frame;
3282 //s_p_dcam_mod->dcam_path0.output_frame_cur = path0_frame;
3283 //s_p_dcam_mod->dcam_path1.output_frame_cur = path1_frame;
3284 //s_p_dcam_mod->dcam_path2.output_frame_cur = path2_frame;
3289 LOCAL int32_t _dcam_path_set_next_frm(enum dcam_path_index path_index, uint32_t is_1st_frm)
3291 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
3292 struct dcam_frame frame;
3293 struct dcam_frame *reserved_frame = NULL;
3294 struct dcam_frame *orig_frame = NULL;
3295 struct dcam_path_desc *path = NULL;
3296 uint32_t yuv_reg[3] = {0};
3297 uint32_t path_max_frm_cnt;
3299 struct dcam_frm_queue *p_heap = NULL;
3300 struct dcam_buf_queue *p_buf_queue = NULL;
3302 DCAM_CHECK_ZERO(s_p_dcam_mod);
3304 if (DCAM_PATH_IDX_0 == path_index) {
3305 //frame = &s_p_dcam_mod->path0_frame[0];
3306 reserved_frame = &s_p_dcam_mod->path0_reserved_frame;
3307 path = &s_p_dcam_mod->dcam_path0;
3308 yuv_reg[0] = DCAM_FRM_ADDR0;
3309 yuv_reg[1] = DCAM_FRM_ADDR12;
3310 path_max_frm_cnt = DCAM_PATH_0_FRM_CNT_MAX;
3311 p_heap = &s_p_dcam_mod->dcam_path0.frame_queue;
3312 p_buf_queue = &s_p_dcam_mod->dcam_path0.buf_queue;
3313 } else if (DCAM_PATH_IDX_1 == path_index) {
3314 //frame = &s_p_dcam_mod->path1_frame[0];
3315 reserved_frame = &s_p_dcam_mod->path1_reserved_frame;
3316 path = &s_p_dcam_mod->dcam_path1;
3317 yuv_reg[0] = DCAM_FRM_ADDR1;
3318 yuv_reg[1] = DCAM_FRM_ADDR2;
3319 yuv_reg[2] = DCAM_FRM_ADDR3;
3320 path_max_frm_cnt = DCAM_PATH_1_FRM_CNT_MAX;
3321 p_heap = &s_p_dcam_mod->dcam_path1.frame_queue;
3322 p_buf_queue = &s_p_dcam_mod->dcam_path1.buf_queue;
3323 } else /*if(DCAM_PATH_IDX_2 == path_index)*/ {
3324 //frame = &s_p_dcam_mod->path2_frame[0];
3325 reserved_frame = &s_p_dcam_mod->path2_reserved_frame;
3326 path = &s_p_dcam_mod->dcam_path2;
3327 yuv_reg[0] = DCAM_FRM_ADDR4;
3328 yuv_reg[1] = DCAM_FRM_ADDR5;
3329 yuv_reg[2] = DCAM_FRM_ADDR6;
3330 path_max_frm_cnt = DCAM_PATH_2_FRM_CNT_MAX;
3331 p_heap = &s_p_dcam_mod->dcam_path2.frame_queue;
3332 p_buf_queue = &s_p_dcam_mod->dcam_path2.buf_queue;
3335 if (0 != _dcam_buf_queue_read(p_buf_queue, &frame)) {
3336 DCAM_TRACE("DCAM: No freed frame id %d \n", frame.fid);
3337 memcpy(&frame, reserved_frame, sizeof(struct dcam_frame));
3340 DCAM_TRACE("DCAM: next %d y 0x%x uv 0x%x \n", path->output_frame_count, frame.yaddr, frame.uaddr);
3341 REG_WR(yuv_reg[0], frame.yaddr);
3342 if (((DCAM_YUV400 > path->output_format) && (DCAM_PATH_IDX_0 != path_index)) ||
3343 ((DCAM_OUTPUT_YUV420 == path->output_format) && (DCAM_PATH_IDX_0 == path_index))) {
3344 REG_WR(yuv_reg[1], frame.uaddr);
3345 if (DCAM_YUV420_3FRAME == path->output_format) {
3346 REG_WR(yuv_reg[2], frame.vaddr);
3349 dcam_frame_lock(&frame);
3350 if (0 == _dcam_frame_enqueue(p_heap, &frame)) {
3352 dcam_frame_unlock(&frame);
3353 rtn = DCAM_RTN_PATH_FRAME_LOCKED;
3360 LOCAL int32_t _dcam_path_trim(enum dcam_path_index path_index)
3362 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
3363 struct dcam_path_desc *path;
3364 uint32_t cfg_reg, ctrl_bit;
3366 DCAM_CHECK_ZERO(s_p_dcam_mod);
3368 if (DCAM_PATH_IDX_1 == path_index) {
3369 path = &s_p_dcam_mod->dcam_path1;
3370 cfg_reg = DCAM_PATH1_CFG;
3372 } else if (DCAM_PATH_IDX_2 == path_index) {
3373 path = &s_p_dcam_mod->dcam_path2;
3374 cfg_reg = DCAM_PATH2_CFG;
3377 printk("DCAM: _dcam_path_trim invalid path_index=%d \n", path_index);
3381 if (path->input_size.w != path->input_rect.w ||
3382 path->input_size.h != path->input_rect.h) {
3383 /*REG_OWR(cfg_reg, 1 << ctrl_bit);*/
3385 /*REG_MWR(cfg_reg, 1 << ctrl_bit, 0 << ctrl_bit);*/
3393 LOCAL int32_t _dcam_path_scaler(enum dcam_path_index path_index)
3395 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
3396 struct dcam_path_desc *path = NULL;
3397 uint32_t cfg_reg = 0;
3399 DCAM_CHECK_ZERO(s_p_dcam_mod);
3400 DCAM_CHECK_ZERO(s_dcam_sc_array);
3402 if (DCAM_PATH_IDX_0 == path_index) {
3403 path = &s_p_dcam_mod->dcam_path0;
3404 cfg_reg = DCAM_PATH0_CFG;
3405 } else if (DCAM_PATH_IDX_1 == path_index) {
3406 path = &s_p_dcam_mod->dcam_path1;
3407 cfg_reg = DCAM_PATH1_CFG;
3408 } else if (DCAM_PATH_IDX_2 == path_index){
3409 path = &s_p_dcam_mod->dcam_path2;
3410 cfg_reg = DCAM_PATH2_CFG;
3413 DCAM_CHECK_ZERO(path);
3414 if (DCAM_RAWRGB == path->output_format ||
3415 DCAM_JPEG == path->output_format) {
3416 DCAM_TRACE("DCAM: _dcam_path_scaler out format is %d, no need scaler \n", path->output_format);
3417 return DCAM_RTN_SUCCESS;
3420 rtn = _dcam_calc_sc_size(path_index);
3421 if (DCAM_RTN_SUCCESS != rtn) {
3425 if (path->sc_input_size.w == path->output_size.w &&
3426 path->sc_input_size.h == path->output_size.h &&
3427 DCAM_YUV422 == path->output_format) {
3428 REG_MWR(cfg_reg, BIT_20, 1 << 20);// bypass scaler if the output size equals input size for YUV422 format
3430 REG_MWR(cfg_reg, BIT_20, 0 << 20);
3431 if (s_dcam_sc_array->is_smooth_zoom
3432 && DCAM_PATH_IDX_1 == path_index
3433 && DCAM_ST_START == path->status) {
3434 rtn = _dcam_calc_sc_coeff(path_index);
3436 rtn = _dcam_set_sc_coeff(path_index);
3443 LOCAL int32_t _dcam_path_check_deci(enum dcam_path_index path_index, uint32_t *is_deci)
3445 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
3446 struct dcam_path_desc *path = NULL;
3447 uint32_t w_deci = 0;
3448 uint32_t h_deci = 0;
3450 DCAM_CHECK_ZERO(s_p_dcam_mod);
3452 if (DCAM_PATH_IDX_0 == path_index) {
3453 path = &s_p_dcam_mod->dcam_path1;
3454 } else if (DCAM_PATH_IDX_1 == path_index) {
3455 path = &s_p_dcam_mod->dcam_path1;
3456 } else if (DCAM_PATH_IDX_2 == path_index) {
3457 path = &s_p_dcam_mod->dcam_path2;
3459 rtn = DCAM_RTN_PATH_SC_ERR;
3463 if (path->input_rect.w > (path->output_size.w * DCAM_SC_COEFF_DOWN_MAX * (1<<DCAM_PATH_DECI_FAC_MAX)) ||
3464 path->input_rect.h > (path->output_size.h * DCAM_SC_COEFF_DOWN_MAX * (1<<DCAM_PATH_DECI_FAC_MAX)) ||
3465 path->input_rect.w * DCAM_SC_COEFF_UP_MAX < path->output_size.w ||
3466 path->input_rect.h * DCAM_SC_COEFF_UP_MAX < path->output_size.h) {
3467 rtn = DCAM_RTN_PATH_SC_ERR;
3469 if (path->input_rect.w > path->output_size.w * DCAM_SC_COEFF_DOWN_MAX)
3471 if (path->input_rect.h > path->output_size.h * DCAM_SC_COEFF_DOWN_MAX)
3474 if(w_deci || h_deci)
3481 DCAM_TRACE("DCAM: _dcam_path_check_deci: path_index=%d, is_deci=%d, rtn=%d \n", path_index, *is_deci, rtn);
3486 LOCAL uint32_t _dcam_get_path_deci_factor(uint32_t src_size, uint32_t dst_size)
3488 uint32_t factor = 0;
3490 if (0 == src_size || 0 == dst_size) {
3494 /* factor: 0 - 1/2, 1 - 1/4, 2 - 1/8, 3 - 1/16 */
3495 for (factor = 0; factor < DCAM_PATH_DECI_FAC_MAX; factor ++) {
3496 if (src_size < (uint32_t)(dst_size * (1 << (factor + 1)))) {
3504 LOCAL int32_t _dcam_calc_sc_size(enum dcam_path_index path_index)
3506 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
3507 struct dcam_path_desc *path = NULL;
3508 uint32_t cfg_reg = 0;
3509 uint32_t tmp_dstsize = 0;
3510 uint32_t align_size = 0;
3512 DCAM_CHECK_ZERO(s_p_dcam_mod);
3514 if (DCAM_PATH_IDX_0 == path_index) {
3515 path = &s_p_dcam_mod->dcam_path0;
3516 cfg_reg = DCAM_PATH0_CFG;
3517 } else if (DCAM_PATH_IDX_1 == path_index) {
3518 path = &s_p_dcam_mod->dcam_path1;
3519 cfg_reg = DCAM_PATH1_CFG;
3520 } else if (DCAM_PATH_IDX_2 == path_index){
3521 path = &s_p_dcam_mod->dcam_path2;
3522 cfg_reg = DCAM_PATH2_CFG;
3525 DCAM_CHECK_ZERO(path);
3526 if (path->input_rect.w > (path->output_size.w * DCAM_SC_COEFF_DOWN_MAX * (1<<DCAM_PATH_DECI_FAC_MAX)) ||
3527 path->input_rect.h > (path->output_size.h * DCAM_SC_COEFF_DOWN_MAX * (1<<DCAM_PATH_DECI_FAC_MAX)) ||
3528 path->input_rect.w * DCAM_SC_COEFF_UP_MAX < path->output_size.w ||
3529 path->input_rect.h * DCAM_SC_COEFF_UP_MAX < path->output_size.h) {
3530 rtn = DCAM_RTN_PATH_SC_ERR;
3532 path->sc_input_size.w = path->input_rect.w;
3533 path->sc_input_size.h = path->input_rect.h;
3534 if (path->input_rect.w > path->output_size.w * DCAM_SC_COEFF_DOWN_MAX) {
3535 tmp_dstsize = path->output_size.w * DCAM_SC_COEFF_DOWN_MAX;
3536 path->deci_val.deci_x = _dcam_get_path_deci_factor(path->input_rect.w, tmp_dstsize);
3537 path->deci_val.deci_x_en = 1;
3538 path->valid_param.v_deci = 1;
3539 align_size = (1 << (path->deci_val.deci_x+1))*DCAM_PIXEL_ALIGN_WIDTH;
3540 path->input_rect.w = (path->input_rect.w) & ~(align_size-1);
3541 path->input_rect.x = (path->input_rect.x) & ~(align_size-1);
3542 path->sc_input_size.w = path->input_rect.w >> (path->deci_val.deci_x+1);
3544 path->deci_val.deci_x = 0;
3545 path->deci_val.deci_x_en = 0;
3546 path->valid_param.v_deci = 1;
3549 if (path->input_rect.h > path->output_size.h * DCAM_SC_COEFF_DOWN_MAX) {
3550 tmp_dstsize = path->output_size.h * DCAM_SC_COEFF_DOWN_MAX;
3551 path->deci_val.deci_y = _dcam_get_path_deci_factor(path->input_rect.h, tmp_dstsize);
3552 path->deci_val.deci_y_en = 1;
3553 path->valid_param.v_deci = 1;
3554 align_size = (1 << (path->deci_val.deci_y+1))*DCAM_PIXEL_ALIGN_HEIGHT;
3555 path->input_rect.h = (path->input_rect.h) & ~(align_size-1);
3556 path->input_rect.y = (path->input_rect.y) & ~(align_size-1);
3557 path->sc_input_size.h = path->input_rect.h >> (path->deci_val.deci_y+1);
3559 path->deci_val.deci_y = 0;
3560 path->deci_val.deci_y_en = 0;
3561 path->valid_param.v_deci = 1;
3566 DCAM_TRACE("DCAM: _dcam_calc_sc_size, path=%d, x_en=%d, deci_x=%d, y_en=%d, deci_y=%d \n",
3567 path_index, path->deci_val.deci_x_en,
3568 path->deci_val.deci_x, path->deci_val.deci_y_en,
3569 path->deci_val.deci_y);
3574 LOCAL int32_t _dcam_set_sc_coeff(enum dcam_path_index path_index)
3576 struct dcam_path_desc *path = NULL;
3578 uint32_t h_coeff_addr = DCAM_BASE;
3579 uint32_t v_coeff_addr = DCAM_BASE;
3580 uint32_t v_chroma_coeff_addr = DCAM_BASE;
3581 uint32_t *tmp_buf = NULL;
3582 uint32_t *h_coeff = NULL;
3583 uint32_t *v_coeff = NULL;
3584 uint32_t *v_chroma_coeff = NULL;
3585 uint32_t clk_switch_bit = 0;
3586 uint32_t clk_switch_shift_bit = 0;
3587 uint32_t clk_status_bit = 0;
3588 uint32_t ver_tap_reg = 0;
3589 uint32_t scale2yuv420 = 0;
3594 DCAM_CHECK_ZERO(s_p_dcam_mod);
3596 if (DCAM_PATH_IDX_1 != path_index && DCAM_PATH_IDX_2 != path_index)
3597 return -DCAM_RTN_PARA_ERR;
3599 if (DCAM_PATH_IDX_1 == path_index) {
3600 path = &s_p_dcam_mod->dcam_path1;
3601 h_coeff_addr += DCAM_SC1_H_TAB_OFFSET;
3602 v_coeff_addr += DCAM_SC1_V_TAB_OFFSET;
3603 v_chroma_coeff_addr += DCAM_SC1_V_CHROMA_TAB_OFFSET;
3604 clk_switch_bit = BIT_3;
3605 clk_switch_shift_bit = 3;
3606 clk_status_bit = BIT_5;
3607 ver_tap_reg = DCAM_PATH1_CFG;
3608 } else if (DCAM_PATH_IDX_2 == path_index) {
3609 path = &s_p_dcam_mod->dcam_path2;
3610 h_coeff_addr += DCAM_SC2_H_TAB_OFFSET;
3611 v_coeff_addr += DCAM_SC2_V_TAB_OFFSET;
3612 v_chroma_coeff_addr += DCAM_SC2_V_CHROMA_TAB_OFFSET;
3613 clk_switch_bit = BIT_4;
3614 clk_switch_shift_bit = 4;
3615 clk_status_bit = BIT_6;
3616 ver_tap_reg = DCAM_PATH2_CFG;
3619 if (DCAM_YUV420 == path->output_format) {
3623 DCAM_TRACE("DCAM: _dcam_set_sc_coeff {%d %d %d %d}, 420=%d \n",
3624 path->sc_input_size.w,
3625 path->sc_input_size.h,
3626 path->output_size.w,
3627 path->output_size.h, scale2yuv420);
3630 tmp_buf = dcam_get_scale_coeff_addr(&index);
3632 if (NULL == tmp_buf) {
3633 return -DCAM_RTN_PATH_NO_MEM;
3637 v_coeff = tmp_buf + (DCAM_SC_COEFF_COEF_SIZE/4);
3638 v_chroma_coeff = v_coeff + (DCAM_SC_COEFF_COEF_SIZE/4);
3640 down(&s_p_dcam_mod->scale_coeff_mem_sema);
3642 if (!(Dcam_GenScaleCoeff((int16_t)path->sc_input_size.w,
3643 (int16_t)path->sc_input_size.h,
3644 (int16_t)path->output_size.w,
3645 (int16_t)path->output_size.h,
3652 tmp_buf + (DCAM_SC_COEFF_COEF_SIZE*3/4),
3653 DCAM_SC_COEFF_TMP_SIZE))) {
3654 printk("DCAM: _dcam_set_sc_coeff Dcam_GenScaleCoeff error! \n");
3655 up(&s_p_dcam_mod->scale_coeff_mem_sema);
3656 return -DCAM_RTN_PATH_GEN_COEFF_ERR;
3659 for (i = 0; i < DCAM_SC_COEFF_H_NUM; i++) {
3660 REG_WR(h_coeff_addr, *h_coeff);
3665 for (i = 0; i < DCAM_SC_COEFF_V_NUM; i++) {
3666 REG_WR(v_coeff_addr, *v_coeff);
3671 for (i = 0; i < DCAM_SC_COEFF_V_CHROMA_NUM; i++) {
3672 REG_WR(v_chroma_coeff_addr, *v_chroma_coeff);
3673 v_chroma_coeff_addr += 4;
3677 path->scale_tap.y_tap = y_tap;
3678 path->scale_tap.uv_tap = uv_tap;
3679 path->valid_param.scale_tap = 1;
3681 up(&s_p_dcam_mod->scale_coeff_mem_sema);
3683 return DCAM_RTN_SUCCESS;
3686 LOCAL void _dcam_force_copy_ext(enum dcam_path_index path_index, uint32_t path_copy, uint32_t coef_copy)
3688 uint32_t reg_val = 0;
3690 if (DCAM_PATH_IDX_1 == path_index) {
3696 dcam_glb_reg_mwr(DCAM_CONTROL, reg_val, reg_val, DCAM_CONTROL_REG);
3697 } else if(DCAM_PATH_IDX_2 == path_index) {
3703 dcam_glb_reg_mwr(DCAM_CONTROL, reg_val, reg_val, DCAM_CONTROL_REG);
3705 DCAM_TRACE("DCAM: _dcam_force_copy_ext invalid path index: %d \n", path_index);
3709 LOCAL void _dcam_auto_copy_ext(enum dcam_path_index path_index, uint32_t path_copy, uint32_t coef_copy)
3711 uint32_t reg_val = 0;
3713 if (DCAM_PATH_IDX_0 == path_index) {
3716 dcam_glb_reg_mwr(DCAM_CONTROL, reg_val, reg_val, DCAM_CONTROL_REG);
3717 } else if (DCAM_PATH_IDX_1 == path_index) {
3722 dcam_glb_reg_mwr(DCAM_CONTROL, reg_val, reg_val, DCAM_CONTROL_REG);
3723 } else if (DCAM_PATH_IDX_2 == path_index) {
3728 dcam_glb_reg_mwr(DCAM_CONTROL, reg_val, reg_val, DCAM_CONTROL_REG);
3730 DCAM_TRACE("DCAM: _dcam_auto_copy_ext invalid path index: %d \n", path_index);
3735 LOCAL void _dcam_force_copy(enum dcam_path_index path_index)
3737 if (DCAM_PATH_IDX_1 == path_index) {
3738 dcam_glb_reg_mwr(DCAM_CONTROL, BIT_10, 1 << 10, DCAM_CONTROL_REG);
3739 } else if (DCAM_PATH_IDX_2 == path_index) {
3740 dcam_glb_reg_mwr(DCAM_CONTROL, BIT_12, 1 << 12, DCAM_CONTROL_REG);
3742 } else if (DCAM_PATH_IDX_0 == path_index) {
3743 dcam_glb_reg_mwr(DCAM_CONTROL, BIT_8, 1 << 8, DCAM_CONTROL_REG);
3746 DCAM_TRACE("DCAM: _dcam_force_copy invalid path index: %d \n", path_index);
3750 LOCAL void _dcam_auto_copy(enum dcam_path_index path_index)
3752 if (DCAM_PATH_IDX_0 == path_index) {
3753 dcam_glb_reg_mwr(DCAM_CONTROL, BIT_9, 1 << 9, DCAM_CONTROL_REG);
3754 } else if(DCAM_PATH_IDX_1 == path_index) {
3755 dcam_glb_reg_mwr(DCAM_CONTROL, BIT_11, 1 << 11, DCAM_CONTROL_REG);
3756 } else if(DCAM_PATH_IDX_2 == path_index) {
3757 dcam_glb_reg_mwr(DCAM_CONTROL, BIT_13, 1 << 13, DCAM_CONTROL_REG);
3759 DCAM_TRACE("DCAM: _dcam_auto_copy invalid path index: %d \n", path_index);
3763 LOCAL void _dcam_reg_trace(void)
3765 #ifdef DCAM_DRV_DEBUG
3768 printk("DCAM: Register list");
3769 for (addr = DCAM_CFG; addr <= CAP_SENSOR_CTRL; addr += 16) {
3770 printk("\n 0x%x: 0x%x 0x%x 0x%x 0x%x",
3783 LOCAL void _dcam_sensor_sof(void)
3785 dcam_isr_func user_func = s_user_func[DCAM_SN_SOF];
3786 void *data = s_user_data[DCAM_SN_SOF];
3788 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3790 DCAM_TRACE("DCAM: _sn_sof \n");
3793 (*user_func)(NULL, data);
3800 LOCAL void _dcam_sensor_eof(void)
3802 dcam_isr_func user_func = s_user_func[DCAM_SN_EOF];
3803 void *data = s_user_data[DCAM_SN_EOF];
3805 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3807 DCAM_TRACE("DCAM: _sn_eof \n");
3810 (*user_func)(NULL, data);
3816 LOCAL void _dcam_cap_sof(void)
3818 dcam_isr_func user_func = s_user_func[DCAM_CAP_SOF];
3819 void *data = s_user_data[DCAM_CAP_SOF];
3821 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3823 DCAM_TRACE("DCAM: _cap_sof \n");
3825 _dcam_stopped_notice();
3828 (*user_func)(NULL, data);
3834 LOCAL void _dcam_cap_eof(void)
3836 dcam_isr_func user_func = s_user_func[DCAM_CAP_EOF];
3837 void *data = s_user_data[DCAM_CAP_EOF];
3839 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3842 (*user_func)(NULL, data);
3848 LOCAL void _dcam_path0_done(void)
3850 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
3851 dcam_isr_func user_func = s_user_func[DCAM_PATH0_DONE];
3852 void *data = s_user_data[DCAM_PATH0_DONE];
3853 struct dcam_path_desc *path;
3854 struct dcam_frame frame;
3856 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3857 path = &s_p_dcam_mod->dcam_path0;
3858 if (0 == path->valide) {
3859 printk("DCAM: path0 not valid \n");
3862 if (path->need_stop) {
3863 dcam_glb_reg_awr(DCAM_CFG, ~BIT_0, DCAM_CFG_REG);
3864 path->need_stop = 0;
3866 _dcam_path_done_notice(DCAM_PATH_IDX_0);
3867 //printk("DCAM 0 \n");
3868 if (path->sof_cnt < 1) {
3869 printk("DCAM: path0 done cnt %d\n", path->sof_cnt);
3870 path->need_wait = 0;
3875 if (path->need_wait) {
3876 path->need_wait = 0;
3878 rtn = _dcam_frame_dequeue(&path->frame_queue, &frame);
3879 if (0 == rtn && frame.yaddr != s_p_dcam_mod->path0_reserved_frame.yaddr && 0 != dcam_frame_is_locked(&frame)) {
3880 frame.width = path->output_size.w;
3881 frame.height = path->output_size.h;
3882 DCAM_TRACE("DCAM: path0 frame 0x%x, y uv, 0x%x 0x%x \n",
3883 (int)&frame, frame.yaddr, frame.uaddr);
3885 (*user_func)(&frame, data);
3888 DCAM_TRACE("DCAM: path0_reserved_frame \n");
3896 LOCAL void _dcam_path0_overflow(void)
3898 dcam_isr_func user_func = s_user_func[DCAM_PATH0_OV];
3899 void *data = s_user_data[DCAM_PATH0_OV];
3900 struct dcam_path_desc *path;
3901 struct dcam_frame frame;
3903 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3905 printk("DCAM: _path0_overflow \n");
3906 path = &s_p_dcam_mod->dcam_path0;
3907 //frame = path->output_frame_cur->prev->prev;
3908 //frame = &s_p_dcam_mod->path0_frame[0];
3909 _dcam_frame_dequeue(&path->frame_queue, &frame);
3912 (*user_func)(&frame, data);
3918 LOCAL void _dcam_path1_done(void)
3920 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
3921 dcam_isr_func user_func = s_user_func[DCAM_PATH1_DONE];
3922 void *data = s_user_data[DCAM_PATH1_DONE];
3923 struct dcam_path_desc *path;
3924 struct dcam_frame frame;
3926 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3927 path = &s_p_dcam_mod->dcam_path1;
3928 if (0 == path->valide) {
3929 printk("DCAM: path1 not valid \n");
3933 DCAM_TRACE("DCAM: 1\n");
3935 if (path->need_stop) {
3936 dcam_glb_reg_awr(DCAM_CFG, ~BIT_1, DCAM_CFG_REG);
3937 path->need_stop = 0;
3939 _dcam_path_done_notice(DCAM_PATH_IDX_1);
3941 if (path->sof_cnt < 1) {
3942 printk("DCAM: path1 done cnt %d\n", path->sof_cnt);
3943 path->need_wait = 0;
3948 if (path->need_wait) {
3949 path->need_wait = 0;
3951 rtn = _dcam_frame_dequeue(&path->frame_queue, &frame);
3952 if (0 == rtn && frame.yaddr != s_p_dcam_mod->path1_reserved_frame.yaddr && 0 != dcam_frame_is_locked(&frame)) {
3953 frame.width = path->output_size.w;
3954 frame.height = path->output_size.h;
3955 DCAM_TRACE("DCAM: path1 frame 0x%x, y uv, 0x%x 0x%x \n",
3956 (int)&frame, frame.yaddr, frame.uaddr);
3958 (*user_func)(&frame, data);
3961 DCAM_TRACE("DCAM: path1_reserved_frame \n");
3967 LOCAL void _dcam_path1_overflow(void)
3969 dcam_isr_func user_func = s_user_func[DCAM_PATH1_OV];
3970 void *data = s_user_data[DCAM_PATH1_OV];
3971 struct dcam_path_desc *path;
3972 struct dcam_frame frame;
3974 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3976 printk("DCAM: _path1_overflow \n");
3977 path = &s_p_dcam_mod->dcam_path1;
3978 //frame = path->output_frame_cur->prev->prev;
3979 _dcam_frame_dequeue(&path->frame_queue, &frame);
3982 (*user_func)(&frame, data);
3988 LOCAL void _dcam_sensor_line_err(void)
3990 dcam_isr_func user_func = s_user_func[DCAM_SN_LINE_ERR];
3991 void *data = s_user_data[DCAM_SN_LINE_ERR];
3993 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3995 printk("DCAM: _line_err \n");
3998 (*user_func)(NULL, data);
4004 LOCAL void _dcam_sensor_frame_err(void)
4006 dcam_isr_func user_func = s_user_func[DCAM_SN_FRAME_ERR];
4007 void *data = s_user_data[DCAM_SN_FRAME_ERR];
4009 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
4011 printk("DCAM: _frame_err \n");
4014 (*user_func)(NULL, data);
4020 LOCAL void _dcam_jpeg_buf_ov(void)
4022 dcam_isr_func user_func = s_user_func[DCAM_JPEG_BUF_OV];
4023 void *data = s_user_data[DCAM_JPEG_BUF_OV];
4024 struct dcam_path_desc *path;
4025 struct dcam_frame frame;
4027 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
4029 printk("DCAM: _jpeg_overflow \n");
4030 path = &s_p_dcam_mod->dcam_path0;
4031 //frame = path->output_frame_cur->prev->prev;
4032 //frame = &s_p_dcam_mod->path0_frame[0];
4033 _dcam_frame_dequeue(&path->frame_queue, &frame);
4036 (*user_func)(&frame, data);
4042 LOCAL void _dcam_path2_done(void)
4044 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
4045 dcam_isr_func user_func = s_user_func[DCAM_PATH2_DONE];
4046 void *data = s_user_data[DCAM_PATH2_DONE];
4047 struct dcam_path_desc *path;
4048 struct dcam_frame frame;
4050 if (atomic_read(&s_resize_flag)) {
4051 memset(&frame, 0, sizeof(struct dcam_frame));
4053 (*user_func)(&frame, data);
4056 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
4057 path = &s_p_dcam_mod->dcam_path2;
4059 DCAM_TRACE("DCAM: 2, %d %d \n", path->need_stop, path->need_wait);
4060 if (path->status == DCAM_ST_START) {
4062 if (path->need_stop) {
4063 dcam_glb_reg_awr(DCAM_CFG, ~BIT_2, DCAM_CFG_REG);
4064 path->need_stop = 0;
4066 _dcam_path_done_notice(DCAM_PATH_IDX_2);
4068 if (path->sof_cnt < 1) {
4069 printk("DCAM: path2 done cnt %d\n", path->sof_cnt);
4070 path->need_wait = 0;
4075 if (path->need_wait) {
4076 path->need_wait = 0;
4078 rtn = _dcam_frame_dequeue(&path->frame_queue, &frame);
4079 if (0 == rtn && frame.yaddr != s_p_dcam_mod->path2_reserved_frame.yaddr && 0 != dcam_frame_is_locked(&frame)) {
4080 DCAM_TRACE("DCAM: path2 frame 0x%x, y uv, 0x%x 0x%x \n",
4081 (int)&frame, frame.yaddr, frame.uaddr);
4082 frame.width = path->output_size.w;
4083 frame.height = path->output_size.h;
4085 (*user_func)(&frame, data);
4088 DCAM_TRACE("DCAM: path2_reserved_frame \n");
4095 LOCAL void _dcam_path2_ov(void)
4097 dcam_isr_func user_func = s_user_func[DCAM_PATH2_OV];
4098 void *data = s_user_data[DCAM_PATH2_OV];
4099 struct dcam_path_desc *path;
4100 struct dcam_frame frame;
4102 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
4104 printk("DCAM: _path2_overflow \n");
4105 path = &s_p_dcam_mod->dcam_path2;
4106 //frame = path->output_frame_cur->prev->prev;
4107 //frame = &s_p_dcam_mod->path2_frame[0];
4108 _dcam_frame_dequeue(&path->frame_queue, &frame);
4111 (*user_func)(&frame, data);
4117 LOCAL void _dcam_isp_ov(void)
4119 dcam_isr_func user_func = s_user_func[DCAM_ISP_OV];
4120 void *data = s_user_data[DCAM_ISP_OV];
4122 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
4124 printk("DCAM: _isp_overflow \n");
4127 (*user_func)(NULL, data);
4133 LOCAL void _dcam_mipi_ov(void)
4135 dcam_isr_func user_func = s_user_func[DCAM_MIPI_OV];
4136 void *data = s_user_data[DCAM_MIPI_OV];
4138 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
4142 (*user_func)(NULL, data);
4145 printk("DCAM: _mipi_overflow \n");
4149 LOCAL void _dcam_rot_done(void)
4151 dcam_isr_func user_func = s_user_func[DCAM_ROT_DONE];
4152 void *data = s_user_data[DCAM_ROT_DONE];
4154 DCAM_TRACE("DCAM: rot_done \n");
4157 (*user_func)(NULL, data);
4163 LOCAL void _dcam_path1_slice_done(void)
4165 dcam_isr_func user_func = s_user_func[DCAM_PATH1_SLICE_DONE];
4166 void *data = s_user_data[DCAM_PATH1_SLICE_DONE];
4168 DCAM_TRACE("DCAM: 1 slice done \n");
4171 (*user_func)(NULL, data);
4177 LOCAL void _dcam_path2_slice_done(void)
4179 dcam_isr_func user_func = s_user_func[DCAM_PATH2_SLICE_DONE];
4180 void *data = s_user_data[DCAM_PATH2_SLICE_DONE];
4182 DCAM_TRACE("DCAM: 2 slice done \n");
4185 (*user_func)(NULL, data);
4191 LOCAL void _dcam_raw_slice_done(void)
4193 dcam_isr_func user_func = s_user_func[DCAM_RAW_SLICE_DONE];
4194 void *data = s_user_data[DCAM_RAW_SLICE_DONE];
4196 DCAM_TRACE("DCAM: 0 slice done \n");
4199 (*user_func)(NULL, data);
4205 LOCAL void _dcam_path0_sof(void)
4207 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
4208 dcam_isr_func user_func = s_user_func[DCAM_PATH0_SOF];
4209 void *data = s_user_data[DCAM_PATH0_SOF];
4210 struct dcam_path_desc *path;
4211 struct dcam_sc_coeff *sc_coeff;
4213 DCAM_TRACE("DCAM: 0 sof 1 \n");
4215 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
4216 DCAM_CHECK_ZERO_VOID(s_dcam_sc_array);
4218 if(s_p_dcam_mod->dcam_path0.status == DCAM_ST_START){
4219 DCAM_TRACE("DCAM: 0 sof 2 \n");
4220 path = &s_p_dcam_mod->dcam_path0;
4221 if (0 == path->valide) {
4222 printk("DCAM: path0 not valid \n");
4226 if (path->sof_cnt > 0) {
4227 printk("DCAM: path0 sof %d \n", path->sof_cnt);
4233 rtn = _dcam_path_set_next_frm(DCAM_PATH_IDX_0, false);
4236 DCAM_TRACE("DCAM: path0 updated \n");
4238 _dcam_auto_copy(DCAM_PATH_IDX_0);
4241 _dcam_path_updated_notice(DCAM_PATH_IDX_0);
4244 path->need_wait = 1;
4245 printk("DCAM: 0 w\n");
4250 (*user_func)(NULL, data);
4257 LOCAL void _dcam_path1_sof(void)
4259 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
4260 dcam_isr_func user_func = s_user_func[DCAM_PATH1_SOF];
4261 void *data = s_user_data[DCAM_PATH1_SOF];
4262 struct dcam_path_desc *path;
4263 struct dcam_sc_coeff *sc_coeff;
4266 DCAM_TRACE("DCAM: 1 sof done \n");
4268 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
4269 DCAM_CHECK_ZERO_VOID(s_dcam_sc_array);
4271 if(s_p_dcam_mod->dcam_path1.status == DCAM_ST_START){
4273 path = &s_p_dcam_mod->dcam_path1;
4274 if (0 == path->valide) {
4275 printk("DCAM: path1 not valid \n");
4279 if (path->sof_cnt > 0) {
4280 printk("DCAM: path1 sof %d \n", path->sof_cnt);
4286 rtn = _dcam_path_set_next_frm(DCAM_PATH_IDX_1, false);
4287 if (path->is_update) {
4288 if (s_dcam_sc_array->is_smooth_zoom) {
4289 #ifndef CONFIG_MACH_Z3
4290 _dcam_get_valid_sc_coeff(s_dcam_sc_array, &sc_coeff);
4291 _dcam_write_sc_coeff(DCAM_PATH_IDX_1);
4292 #else /* possible fix for smooth zoom kernel panic */
4294 ret = _dcam_get_valid_sc_coeff(s_dcam_sc_array, &sc_coeff);
4296 printk("DCAM: get sc coeff ret %d \n", ret);
4299 ret = _dcam_write_sc_coeff(DCAM_PATH_IDX_1);
4301 printk("DCAM: write sc coeff ret %d \n", ret);
4305 _dcam_path1_set(&sc_coeff->dcam_path1);
4306 _dcam_pop_sc_buf(s_dcam_sc_array, &sc_coeff);
4308 _dcam_path1_set(path);
4310 path->is_update = 0;
4311 DCAM_TRACE("DCAM: path1 updated \n");
4312 _dcam_auto_copy_ext(DCAM_PATH_IDX_1, true, true);
4315 DCAM_TRACE("DCAM: path1 updated \n");
4317 _dcam_auto_copy(DCAM_PATH_IDX_1);
4321 _dcam_path_updated_notice(DCAM_PATH_IDX_1);
4324 path->need_wait = 1;
4325 printk("DCAM: 1 w\n");
4331 (*user_func)(NULL, data);
4337 LOCAL void _dcam_path2_sof(void)
4339 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
4340 dcam_isr_func user_func = s_user_func[DCAM_PATH2_SOF];
4341 void *data = s_user_data[DCAM_PATH2_SOF];
4342 struct dcam_path_desc *path;
4344 DCAM_TRACE("DCAM: 2 sof done \n");
4346 if (atomic_read(&s_resize_flag)) {
4347 printk("DCAM: path 2 sof, review now \n");
4349 if (DCAM_ADDR_INVALID(s_p_dcam_mod)) {
4353 if(s_p_dcam_mod->dcam_path2.status == DCAM_ST_START){
4355 path = &s_p_dcam_mod->dcam_path2;
4356 if (0 == path->valide) {
4357 printk("DCAM: path2 not valid \n");
4361 if (path->sof_cnt > 0) {
4362 printk("DCAM: path2 sof %d \n", path->sof_cnt);
4368 rtn = _dcam_path_set_next_frm(DCAM_PATH_IDX_2, false);
4369 if (path->is_update) {
4371 path->is_update = 0;
4372 DCAM_TRACE("DCAM: path2 updated \n");
4373 _dcam_auto_copy_ext(DCAM_PATH_IDX_2, true, true);
4376 DCAM_TRACE("DCAM: path2 updated \n");
4378 _dcam_auto_copy(DCAM_PATH_IDX_2);
4382 _dcam_path_updated_notice(DCAM_PATH_IDX_2);
4385 path->need_wait = 1;
4386 printk("DCAM:2 w \n");
4393 (*user_func)(NULL, data);
4399 LOCAL int32_t _dcam_err_pre_proc(void)
4401 DCAM_CHECK_ZERO(s_p_dcam_mod);
4403 DCAM_TRACE("DCAM: state in err_pre_proc 0x%x,",s_p_dcam_mod->state);
4404 if (s_p_dcam_mod->state & DCAM_STATE_QUICKQUIT)
4407 s_p_dcam_mod->err_happened = 1;
4408 printk("DCAM: err, 0x%x, ISP int 0x%x \n",
4409 REG_RD(DCAM_INT_STS),
4410 REG_RD(SPRD_ISP_BASE + 0x2080));
4413 dcam_glb_reg_mwr(DCAM_CONTROL, BIT_2, 0, DCAM_CONTROL_REG); /* Cap Disable */
4415 if (0 == atomic_read(&s_resize_flag) &&
4416 0 == atomic_read(&s_rotation_flag)) {
4417 dcam_reset(DCAM_RST_ALL, 1);
4422 LOCAL void _dcam_stopped(void)
4424 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
4426 DCAM_TRACE("DCAM: stopped, %d \n", s_p_dcam_mod->wait_stop);
4428 _dcam_path_done_notice(DCAM_PATH_IDX_0);
4429 _dcam_path_done_notice(DCAM_PATH_IDX_1);
4430 _dcam_path_done_notice(DCAM_PATH_IDX_2);
4431 _dcam_stopped_notice();
4435 LOCAL int _dcam_internal_init(void)
4439 s_p_dcam_mod = (struct dcam_module*)vzalloc(sizeof(struct dcam_module));
4441 DCAM_CHECK_ZERO(s_p_dcam_mod);
4443 sema_init(&s_p_dcam_mod->stop_sema, 0);
4444 sema_init(&s_p_dcam_mod->dcam_path0.tx_done_sema, 0);
4445 sema_init(&s_p_dcam_mod->dcam_path1.tx_done_sema, 0);
4446 sema_init(&s_p_dcam_mod->dcam_path2.tx_done_sema, 0);
4447 sema_init(&s_p_dcam_mod->dcam_path0.sof_sema, 0);
4448 sema_init(&s_p_dcam_mod->dcam_path1.sof_sema, 0);
4449 sema_init(&s_p_dcam_mod->dcam_path2.sof_sema, 0);
4450 sema_init(&s_p_dcam_mod->resize_done_sema, 0);
4451 sema_init(&s_p_dcam_mod->rotation_done_sema, 0);
4452 sema_init(&s_p_dcam_mod->scale_coeff_mem_sema, 1);
4454 memset((void*)s_dcam_sc_array, 0, sizeof(struct dcam_sc_array));
4457 LOCAL void _dcam_internal_deinit(void)
4461 spin_lock_irqsave(&dcam_mod_lock, flag);
4462 if (DCAM_ADDR_INVALID(s_p_dcam_mod)) {
4463 printk("DCAM: Invalid addr, 0x%x", (uint32_t)s_p_dcam_mod);
4465 vfree(s_p_dcam_mod);
4466 s_p_dcam_mod = NULL;
4468 spin_unlock_irqrestore(&dcam_mod_lock, flag);
4472 LOCAL void _dcam_wait_path_done(enum dcam_path_index path_index, uint32_t *p_flag)
4475 struct dcam_path_desc *p_path = NULL;
4478 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
4480 if (s_p_dcam_mod->err_happened) {
4483 if (DCAM_CAPTURE_MODE_SINGLE == s_p_dcam_mod->dcam_mode) {
4486 if (DCAM_PATH_IDX_0 == path_index) {
4487 p_path = &s_p_dcam_mod->dcam_path0;
4488 } else if (DCAM_PATH_IDX_1 == path_index) {
4489 p_path = &s_p_dcam_mod->dcam_path1;
4490 } else if (DCAM_PATH_IDX_2 == path_index) {
4491 p_path = &s_p_dcam_mod->dcam_path2;
4493 printk("DCAM: Wrong index 0x%x \n", path_index);
4496 DCAM_TRACE("DCAM: path done wait %d, %d \n", p_path->wait_for_done, p_path->tx_done_sema.count);
4498 spin_lock_irqsave(&dcam_lock, flag);
4502 p_path->wait_for_done = 1;
4503 spin_unlock_irqrestore(&dcam_lock, flag);
4504 ret = down_timeout(&p_path->tx_done_sema, DCAM_PATH_TIMEOUT);
4507 printk("DCAM: Failed to wait path 0x%x done \n", path_index);
4513 LOCAL void _dcam_path_done_notice(enum dcam_path_index path_index)
4515 struct dcam_path_desc *p_path = NULL;
4517 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
4519 if (DCAM_PATH_IDX_0 == path_index) {
4520 p_path = &s_p_dcam_mod->dcam_path0;
4521 } else if(DCAM_PATH_IDX_1 == path_index) {
4522 p_path = &s_p_dcam_mod->dcam_path1;
4523 } else if(DCAM_PATH_IDX_2 == path_index) {
4524 p_path = &s_p_dcam_mod->dcam_path2;
4526 printk("DCAM: Wrong index 0x%x \n", path_index);
4529 DCAM_TRACE("DCAM: path done notice %d, %d \n", p_path->wait_for_done, p_path->tx_done_sema.count);
4530 if (p_path->wait_for_done) {
4531 up(&p_path->tx_done_sema);
4532 p_path->wait_for_done = 0;
4538 LOCAL void _dcam_wait_update_done(enum dcam_path_index path_index, uint32_t *p_flag)
4541 struct dcam_path_desc *p_path = NULL;
4544 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
4546 if (s_p_dcam_mod->err_happened) {
4547 printk("DCAM: err happened \n");
4550 if (DCAM_CAPTURE_MODE_SINGLE == s_p_dcam_mod->dcam_mode) {
4553 if (DCAM_PATH_IDX_0 == path_index) {
4554 p_path = &s_p_dcam_mod->dcam_path0;
4555 } else if (DCAM_PATH_IDX_1 == path_index) {
4556 p_path = &s_p_dcam_mod->dcam_path1;
4557 } else if (DCAM_PATH_IDX_2 == path_index) {
4558 p_path = &s_p_dcam_mod->dcam_path2;
4560 printk("DCAM: Wrong index 0x%x \n", path_index);
4563 DCAM_TRACE("DCAM: path done wait %d, %d \n", p_path->wait_for_done, p_path->tx_done_sema.count);
4565 spin_lock_irqsave(&dcam_lock, flag);
4569 p_path->wait_for_sof = 1;
4570 spin_unlock_irqrestore(&dcam_lock, flag);
4571 ret = down_timeout(&p_path->sof_sema, DCAM_PATH_TIMEOUT);
4574 printk("DCAM: Failed to wait update path 0x%x done \n", path_index);
4580 LOCAL void _dcam_path_updated_notice(enum dcam_path_index path_index)
4582 struct dcam_path_desc *p_path = NULL;
4584 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
4586 if (DCAM_PATH_IDX_0 == path_index) {
4587 p_path = &s_p_dcam_mod->dcam_path0;
4588 } else if(DCAM_PATH_IDX_1 == path_index) {
4589 p_path = &s_p_dcam_mod->dcam_path1;
4590 } else if(DCAM_PATH_IDX_2 == path_index) {
4591 p_path = &s_p_dcam_mod->dcam_path2;
4593 printk("DCAM: Wrong index 0x%x \n", path_index);
4596 DCAM_TRACE("DCAM: path done notice %d, %d \n", p_path->wait_for_done, p_path->tx_done_sema.count);
4597 if (p_path->wait_for_sof) {
4598 up(&p_path->sof_sema);
4599 p_path->wait_for_sof = 0;
4606 LOCAL void _dcam_stopped_notice(void)
4608 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
4610 if (s_p_dcam_mod->wait_stop) {
4611 up(&s_p_dcam_mod->stop_sema);
4612 s_p_dcam_mod->wait_stop = 0;
4616 void mm_clk_register_trace(void)
4619 printk("REG_AON_APB_APB_EB0 = 0x%x \n",REG_RD(REG_AON_APB_APB_EB0));
4620 printk("REG_PMU_APB_PD_MM_TOP_CFG = 0x%x \n",REG_RD(REG_PMU_APB_PD_MM_TOP_CFG));
4621 printk("REG_PMU_APB_CP_SOFT_RST = 0x%x \n",REG_RD(REG_PMU_APB_CP_SOFT_RST));
4622 if(!(REG_RD(REG_AON_APB_APB_EB0)&BIT_MM_EB) ) return ;
4623 if(REG_RD(REG_PMU_APB_PD_MM_TOP_CFG)&BIT_PD_MM_TOP_FORCE_SHUTDOWN) return ;
4625 printk("mm_clk_reg, part 1 \n");
4626 for (i = 0 ; i <= 0x10; i += 4 ) {
4627 printk("MMAHB: %x val:%x \b\n",
4628 (SPRD_MMAHB_BASE + i),
4629 REG_RD(SPRD_MMAHB_BASE + i));
4632 printk("mm_clk_reg, part 2 \n");
4633 for (i = 0x20 ; i <= 0x38; i += 4 ) {
4634 printk("MMCKG: %x val:%x \b\n",
4635 (SPRD_MMCKG_BASE + i),
4636 REG_RD(SPRD_MMCKG_BASE + i));
4640 int32_t dcam_stop_sc_coeff(void)
4644 DCAM_CHECK_ZERO(s_dcam_sc_array);
4646 zoom_mode = s_dcam_sc_array->is_smooth_zoom;
4647 /*memset((void*)s_dcam_sc_array, 0, sizeof(struct dcam_sc_array));*/
4648 s_dcam_sc_array->is_smooth_zoom = zoom_mode;
4649 s_dcam_sc_array->valid_cnt = 0;
4650 memset(&s_dcam_sc_array->scaling_coeff_queue, 0, DCAM_SC_COEFF_BUF_COUNT*sizeof(struct dcam_sc_coeff *));
4655 LOCAL int32_t _dcam_get_valid_sc_coeff(struct dcam_sc_array *sc, struct dcam_sc_coeff **sc_coeff)
4657 if (DCAM_ADDR_INVALID(sc) || DCAM_ADDR_INVALID(sc_coeff)) {
4658 printk("DCAM: get valid sc, invalid param 0x%x, 0x%x \n",
4660 (uint32_t)sc_coeff);
4663 if (sc->valid_cnt == 0) {
4664 printk("DCAM: valid cnt 0 \n");
4668 *sc_coeff = sc->scaling_coeff_queue[0];
4669 DCAM_TRACE("DCAM: get valid sc, %d \n", sc->valid_cnt);
4674 LOCAL int32_t _dcam_push_sc_buf(struct dcam_sc_array *sc, uint32_t index)
4676 if (DCAM_ADDR_INVALID(sc)) {
4677 printk("DCAM: push sc, invalid param 0x%x \n",
4681 if (sc->valid_cnt >= DCAM_SC_COEFF_BUF_COUNT) {
4682 printk("DCAM: valid cnt %d \n", sc->valid_cnt);
4686 sc->scaling_coeff[index].flag = 1;
4687 sc->scaling_coeff_queue[sc->valid_cnt] = &sc->scaling_coeff[index];
4690 DCAM_TRACE("DCAM: push sc, %d \n", sc->valid_cnt);
4695 LOCAL int32_t _dcam_pop_sc_buf(struct dcam_sc_array *sc, struct dcam_sc_coeff **sc_coeff)
4699 if (DCAM_ADDR_INVALID(sc) || DCAM_ADDR_INVALID(sc_coeff)) {
4700 printk("DCAM: pop sc, invalid param 0x%x, 0x%x \n",
4702 (uint32_t)sc_coeff);
4705 if (sc->valid_cnt == 0) {
4706 printk("DCAM: valid cnt 0 \n");
4709 sc->scaling_coeff_queue[0]->flag = 0;
4710 *sc_coeff = sc->scaling_coeff_queue[0];
4712 for (i = 0; i < sc->valid_cnt; i++) {
4713 sc->scaling_coeff_queue[i] = sc->scaling_coeff_queue[i+1];
4715 DCAM_TRACE("DCAM: pop sc, %d \n", sc->valid_cnt);
4719 LOCAL int32_t _dcam_write_sc_coeff(enum dcam_path_index path_index)
4722 struct dcam_path_desc *path = NULL;
4724 uint32_t h_coeff_addr = DCAM_BASE;
4725 uint32_t v_coeff_addr = DCAM_BASE;
4726 uint32_t v_chroma_coeff_addr = DCAM_BASE;
4727 uint32_t *tmp_buf = NULL;
4728 uint32_t *h_coeff = NULL;
4729 uint32_t *v_coeff = NULL;
4730 uint32_t *v_chroma_coeff = NULL;
4731 uint32_t clk_switch_bit = 0;
4732 uint32_t clk_switch_shift_bit = 0;
4733 uint32_t clk_status_bit = 0;
4734 uint32_t ver_tap_reg = 0;
4735 uint32_t scale2yuv420 = 0;
4736 struct dcam_sc_coeff *sc_coeff;
4738 DCAM_CHECK_ZERO(s_p_dcam_mod);
4739 DCAM_CHECK_ZERO(s_dcam_sc_array);
4741 if (DCAM_PATH_IDX_1 != path_index && DCAM_PATH_IDX_2 != path_index)
4742 return -DCAM_RTN_PARA_ERR;
4744 ret = _dcam_get_valid_sc_coeff(s_dcam_sc_array, &sc_coeff);
4746 return -DCAM_RTN_PATH_NO_MEM;
4748 tmp_buf = sc_coeff->buf;
4749 if (NULL == tmp_buf) {
4750 return -DCAM_RTN_PATH_NO_MEM;
4754 v_coeff = tmp_buf + (DCAM_SC_COEFF_COEF_SIZE/4);
4755 v_chroma_coeff = v_coeff + (DCAM_SC_COEFF_COEF_SIZE/4);
4757 if (DCAM_PATH_IDX_1 == path_index) {
4758 path = &sc_coeff->dcam_path1;
4759 h_coeff_addr += DCAM_SC1_H_TAB_OFFSET;
4760 v_coeff_addr += DCAM_SC1_V_TAB_OFFSET;
4761 v_chroma_coeff_addr += DCAM_SC1_V_CHROMA_TAB_OFFSET;
4762 clk_switch_bit = BIT_3;
4763 clk_switch_shift_bit = 3;
4764 clk_status_bit = BIT_5;
4765 ver_tap_reg = DCAM_PATH1_CFG;
4766 } else if (DCAM_PATH_IDX_2 == path_index) {
4767 path = &s_p_dcam_mod->dcam_path2;
4768 h_coeff_addr += DCAM_SC2_H_TAB_OFFSET;
4769 v_coeff_addr += DCAM_SC2_V_TAB_OFFSET;
4770 v_chroma_coeff_addr += DCAM_SC2_V_CHROMA_TAB_OFFSET;
4771 clk_switch_bit = BIT_4;
4772 clk_switch_shift_bit = 4;
4773 clk_status_bit = BIT_6;
4774 ver_tap_reg = DCAM_PATH2_CFG;
4777 if (DCAM_YUV420 == path->output_format) {
4781 DCAM_TRACE("DCAM: _dcam_write_sc_coeff {%d %d %d %d}, 420=%d \n",
4782 path->sc_input_size.w,
4783 path->sc_input_size.h,
4784 path->output_size.w,
4785 path->output_size.h, scale2yuv420);
4787 for (i = 0; i < DCAM_SC_COEFF_H_NUM; i++) {
4788 REG_WR(h_coeff_addr, *h_coeff);
4793 for (i = 0; i < DCAM_SC_COEFF_V_NUM; i++) {
4794 REG_WR(v_coeff_addr, *v_coeff);
4799 for (i = 0; i < DCAM_SC_COEFF_V_CHROMA_NUM; i++) {
4800 REG_WR(v_chroma_coeff_addr, *v_chroma_coeff);
4801 v_chroma_coeff_addr += 4;
4805 DCAM_TRACE("DCAM: _dcam_write_sc_coeff E \n");
4810 LOCAL int32_t _dcam_calc_sc_coeff(enum dcam_path_index path_index)
4813 struct dcam_path_desc *path = NULL;
4814 uint32_t h_coeff_addr = DCAM_BASE;
4815 uint32_t v_coeff_addr = DCAM_BASE;
4816 uint32_t v_chroma_coeff_addr = DCAM_BASE;
4817 uint32_t *tmp_buf = NULL;
4818 uint32_t *h_coeff = NULL;
4819 uint32_t *v_coeff = NULL;
4820 uint32_t *v_chroma_coeff = NULL;
4821 uint32_t clk_switch_bit = 0;
4822 uint32_t clk_switch_shift_bit = 0;
4823 uint32_t clk_status_bit = 0;
4824 uint32_t ver_tap_reg = 0;
4825 uint32_t scale2yuv420 = 0;
4829 struct dcam_sc_coeff *sc_coeff;
4831 DCAM_CHECK_ZERO(s_p_dcam_mod);
4832 DCAM_CHECK_ZERO(s_dcam_sc_array);
4834 if (DCAM_PATH_IDX_1 != path_index && DCAM_PATH_IDX_2 != path_index)
4835 return -DCAM_RTN_PARA_ERR;
4837 if (DCAM_PATH_IDX_1 == path_index) {
4838 path = &s_p_dcam_mod->dcam_path1;
4839 h_coeff_addr += DCAM_SC1_H_TAB_OFFSET;
4840 v_coeff_addr += DCAM_SC1_V_TAB_OFFSET;
4841 v_chroma_coeff_addr += DCAM_SC1_V_CHROMA_TAB_OFFSET;
4842 clk_switch_bit = BIT_3;
4843 clk_switch_shift_bit = 3;
4844 clk_status_bit = BIT_5;
4845 ver_tap_reg = DCAM_PATH1_CFG;
4846 } else if (DCAM_PATH_IDX_2 == path_index) {
4847 path = &s_p_dcam_mod->dcam_path2;
4848 h_coeff_addr += DCAM_SC2_H_TAB_OFFSET;
4849 v_coeff_addr += DCAM_SC2_V_TAB_OFFSET;
4850 v_chroma_coeff_addr += DCAM_SC2_V_CHROMA_TAB_OFFSET;
4851 clk_switch_bit = BIT_4;
4852 clk_switch_shift_bit = 4;
4853 clk_status_bit = BIT_6;
4854 ver_tap_reg = DCAM_PATH2_CFG;
4857 if (DCAM_YUV420 == path->output_format) {
4861 DCAM_TRACE("DCAM: _dcam_calc_sc_coeff {%d %d %d %d}, 420=%d \n",
4862 path->sc_input_size.w,
4863 path->sc_input_size.h,
4864 path->output_size.w,
4865 path->output_size.h, scale2yuv420);
4867 down(&s_p_dcam_mod->scale_coeff_mem_sema);
4869 spin_lock_irqsave(&dcam_lock,flag);
4870 tmp_buf = dcam_get_scale_coeff_addr(&index);
4871 if (NULL == tmp_buf) {
4872 _dcam_pop_sc_buf(s_dcam_sc_array, &sc_coeff);
4873 tmp_buf = dcam_get_scale_coeff_addr(&index);
4875 spin_unlock_irqrestore(&dcam_lock,flag);
4877 if (NULL == tmp_buf) {
4878 return -DCAM_RTN_PATH_NO_MEM;
4882 v_coeff = tmp_buf + (DCAM_SC_COEFF_COEF_SIZE/4);
4883 v_chroma_coeff = v_coeff + (DCAM_SC_COEFF_COEF_SIZE/4);
4885 if (!(Dcam_GenScaleCoeff((int16_t)path->sc_input_size.w,
4886 (int16_t)path->sc_input_size.h,
4887 (int16_t)path->output_size.w,
4888 (int16_t)path->output_size.h,
4895 tmp_buf + (DCAM_SC_COEFF_COEF_SIZE*3/4),
4896 DCAM_SC_COEFF_TMP_SIZE))) {
4897 printk("DCAM: _dcam_calc_sc_coeff Dcam_GenScaleCoeff error! \n");
4898 up(&s_p_dcam_mod->scale_coeff_mem_sema);
4899 return -DCAM_RTN_PATH_GEN_COEFF_ERR;
4901 path->scale_tap.y_tap = y_tap;
4902 path->scale_tap.uv_tap = uv_tap;
4903 path->valid_param.scale_tap = 1;
4904 memcpy(&s_dcam_sc_array->scaling_coeff[index].dcam_path1, path, sizeof(struct dcam_path_desc));
4905 spin_lock_irqsave(&dcam_lock,flag);
4906 _dcam_push_sc_buf(s_dcam_sc_array, index);
4907 spin_unlock_irqrestore(&dcam_lock,flag);
4909 up(&s_p_dcam_mod->scale_coeff_mem_sema);
4910 DCAM_TRACE("DCAM: _dcam_calc_sc_coeff E \n");
4912 return DCAM_RTN_SUCCESS;