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>
24 #include <soc/sprd/hardware.h>
25 #include <mach/irqs.h>
27 #include <soc/sprd/irqs.h>
29 #include <soc/sprd/sci.h>
30 #include <soc/sprd/sci_glb_regs.h>
31 #include <linux/vmalloc.h>
32 #include <linux/videodev2.h>
33 #include <linux/wakelock.h>
35 #include "gen_scale_coef.h"
40 //#define DCAM_DRV_DEBUG
41 #define DCAM_LOWEST_ADDR 0x800
42 #define DCAM_ADDR_INVALID(addr) ((unsigned long)(addr) < DCAM_LOWEST_ADDR)
43 #define DCAM_YUV_ADDR_INVALID(y,u,v) \
44 (DCAM_ADDR_INVALID(y) && \
45 DCAM_ADDR_INVALID(u) && \
48 #define DCAM_SC1_H_TAB_OFFSET 0x400
49 #define DCAM_SC1_V_TAB_OFFSET 0x4F0
50 #define DCAM_SC1_V_CHROMA_TAB_OFFSET 0x8F0
52 #define DCAM_SC2_H_TAB_OFFSET 0x1400
53 #define DCAM_SC2_V_TAB_OFFSET 0x14F0
54 #define DCAM_SC2_V_CHROMA_TAB_OFFSET 0x18F0
56 #define DCAM_SC_COEFF_BUF_SIZE (24 << 10)
57 #define DCAM_SC_COEFF_COEF_SIZE (1 << 10)
58 #define DCAM_SC_COEFF_TMP_SIZE (21 << 10)
59 #define DCAM_SC_COEFF_BUF_COUNT 2
62 #define DCAM_SC_H_COEF_SIZE (0xC0)
63 #define DCAM_SC_V_COEF_SIZE (0x210)
64 #define DCAM_SC_V_CHROM_COEF_SIZE (0x210)
66 #define DCAM_SC_COEFF_H_NUM (DCAM_SC_H_COEF_SIZE/4)
67 #define DCAM_SC_COEFF_V_NUM (DCAM_SC_V_COEF_SIZE/4)
68 #define DCAM_SC_COEFF_V_CHROMA_NUM (DCAM_SC_V_CHROM_COEF_SIZE/4)
70 #define DCAM_AXI_STOP_TIMEOUT 1000
71 #define DCAM_CLK_DOMAIN_AHB 1
72 #define DCAM_CLK_DOMAIN_DCAM 0
75 #define DCAM_PATH_TIMEOUT msecs_to_jiffies(500*10)
77 #define DCAM_PATH_TIMEOUT msecs_to_jiffies(500)
80 #define DCAM_FRM_QUEUE_LENGTH 4
82 #define DCAM_STATE_QUICKQUIT 0x01
84 #define DCAM_CHECK_PARAM_ZERO_POINTER(n) \
86 if (0 == (unsigned long)(n)) \
87 return -DCAM_RTN_PARA_ERR; \
90 #define DCAM_CLEAR(a) \
92 memset((void *)(a), 0, sizeof(*(a))); \
95 #define DEBUG_STR "Error L %d, %s \n"
96 #define DEBUG_ARGS __LINE__,__FUNCTION__
97 #define DCAM_RTN_IF_ERR \
100 printk(DEBUG_STR, DEBUG_ARGS); \
105 #define DCAM_IRQ_LINE_MASK 0x001FFFFFUL
107 typedef void (*dcam_isr)(void);
111 DCAM_FRM_LOCK_WRITE = 0x10011001,
112 DCAM_FRM_LOCK_READ = 0x01100110
120 #define DCAM_IRQ_ERR_MASK \
121 ((1 << DCAM_PATH0_OV) | (1 << DCAM_PATH1_OV) | (1 << DCAM_PATH2_OV) | \
122 (1 << DCAM_SN_LINE_ERR) | (1 << DCAM_SN_FRAME_ERR) | \
123 (1 << DCAM_ISP_OV) | (1 << DCAM_MIPI_OV))
125 #define DCAM_IRQ_JPEG_OV_MASK (1 << DCAM_JPEG_BUF_OV)
127 #define DCAM_CHECK_ZERO(a) \
129 if (DCAM_ADDR_INVALID(a)) { \
130 printk("DCAM, zero pointer \n"); \
131 printk(DEBUG_STR, DEBUG_ARGS); \
136 #define DCAM_CHECK_ZERO_VOID(a) \
138 if (DCAM_ADDR_INVALID(a)) { \
139 printk("DCAM, zero pointer \n"); \
140 printk(DEBUG_STR, DEBUG_ARGS); \
145 struct dcam_cap_desc {
147 uint32_t input_format;
148 uint32_t frame_deci_factor;
149 uint32_t img_x_deci_factor;
150 uint32_t img_y_deci_factor;
153 struct dcam_path_valid {
154 uint32_t input_size :1;
155 uint32_t input_rect :1;
156 uint32_t output_size :1;
157 uint32_t output_format :1;
159 uint32_t data_endian :1;
160 uint32_t frame_deci :1;
161 uint32_t scale_tap :1;
165 struct dcam_frm_queue {
166 struct dcam_frame frm_array[DCAM_FRM_QUEUE_LENGTH];
170 struct dcam_buf_queue {
171 struct dcam_frame frame[DCAM_FRM_CNT_MAX];
172 struct dcam_frame *write;
173 struct dcam_frame *read;
177 struct dcam_path_desc {
178 struct dcam_size input_size;
179 struct dcam_rect input_rect;
180 struct dcam_size sc_input_size;
181 struct dcam_size output_size;
182 struct dcam_frame input_frame;
183 struct dcam_frm_queue frame_queue;
184 struct dcam_buf_queue buf_queue;
185 //struct dcam_frame *output_frame_head;
186 //struct dcam_frame *output_frame_cur;
187 struct dcam_endian_sel data_endian;
188 struct dcam_sc_tap scale_tap;
189 struct dcam_deci deci_val;
190 struct dcam_path_valid valid_param;
191 uint32_t frame_base_id;
192 uint32_t output_frame_count;
193 uint32_t output_format;
199 struct semaphore tx_done_sema;
200 struct semaphore sof_sema;
201 uint32_t wait_for_done;
203 uint32_t wait_for_sof;
211 uint32_t module_addr;
212 struct dcam_cap_desc dcam_cap;
213 struct dcam_path_desc dcam_path0;
214 struct dcam_path_desc dcam_path1;
215 struct dcam_path_desc dcam_path2;
216 struct dcam_frame path0_frame[DCAM_PATH_0_FRM_CNT_MAX];
217 struct dcam_frame path1_frame[DCAM_PATH_1_FRM_CNT_MAX];
218 struct dcam_frame path2_frame[DCAM_PATH_2_FRM_CNT_MAX];
219 struct dcam_frame path0_reserved_frame;
220 struct dcam_frame path1_reserved_frame;
221 struct dcam_frame path2_reserved_frame;
222 struct semaphore stop_sema;
224 struct semaphore resize_done_sema;
225 uint32_t wait_resize_done;
226 struct semaphore rotation_done_sema;
227 uint32_t wait_rotation_done;
228 uint32_t err_happened;
229 struct semaphore scale_coeff_mem_sema;
233 struct dcam_sc_coeff {
234 uint32_t buf[DCAM_SC_COEFF_BUF_SIZE];
236 struct dcam_path_desc dcam_path1;
239 struct dcam_sc_array {
240 struct dcam_sc_coeff scaling_coeff[DCAM_SC_COEFF_BUF_COUNT];
241 struct dcam_sc_coeff *scaling_coeff_queue[DCAM_SC_COEFF_BUF_COUNT];
243 uint32_t is_smooth_zoom;
246 LOCAL atomic_t s_dcam_users = ATOMIC_INIT(0);
247 LOCAL atomic_t s_resize_flag = ATOMIC_INIT(0);
248 LOCAL atomic_t s_rotation_flag = ATOMIC_INIT(0);
249 #ifndef CONFIG_SC_FPGA
250 LOCAL struct clk* s_dcam_clk = NULL;
252 LOCAL struct dcam_module* s_p_dcam_mod = 0;
253 LOCAL uint32_t s_dcam_irq = 0x5A0000A5;
254 LOCAL dcam_isr_func s_user_func[DCAM_IRQ_NUMBER];
255 LOCAL void* s_user_data[DCAM_IRQ_NUMBER];
256 LOCAL struct dcam_sc_array* s_dcam_sc_array = NULL;
257 LOCAL struct wake_lock dcam_wakelock;
259 LOCAL DEFINE_MUTEX(dcam_sem);
260 LOCAL DEFINE_MUTEX(dcam_scale_sema);
261 LOCAL DEFINE_MUTEX(dcam_rot_sema);
262 LOCAL DEFINE_MUTEX(dcam_module_sema);
263 LOCAL DEFINE_SPINLOCK(dcam_mod_lock);
264 LOCAL DEFINE_SPINLOCK(dcam_lock);
265 LOCAL DEFINE_SPINLOCK(dcam_glb_reg_cfg_lock);
266 LOCAL DEFINE_SPINLOCK(dcam_glb_reg_control_lock);
267 LOCAL DEFINE_SPINLOCK(dcam_glb_reg_mask_lock);
268 LOCAL DEFINE_SPINLOCK(dcam_glb_reg_clr_lock);
269 LOCAL DEFINE_SPINLOCK(dcam_glb_reg_ahbm_sts_lock);
270 LOCAL DEFINE_SPINLOCK(dcam_glb_reg_endian_lock);
272 LOCAL void _dcam_path0_set(void);
273 LOCAL void _dcam_path1_set(struct dcam_path_desc *path);
274 LOCAL void _dcam_path2_set(void);
275 LOCAL void _dcam_frm_clear(enum dcam_path_index path_index);
276 LOCAL void _dcam_link_frm(uint32_t base_id);
277 LOCAL int32_t _dcam_path_set_next_frm(enum dcam_path_index path_index, uint32_t is_1st_frm);
278 /*LOCAL int32_t _dcam_path_trim(enum dcam_path_index path_index);*/
279 LOCAL int32_t _dcam_path_scaler(enum dcam_path_index path_index);
280 LOCAL int32_t _dcam_calc_sc_size(enum dcam_path_index path_index);
281 LOCAL int32_t _dcam_set_sc_coeff(enum dcam_path_index path_index);
282 LOCAL void _dcam_force_copy_ext(enum dcam_path_index path_index, uint32_t path_copy, uint32_t coef_copy);
283 LOCAL void _dcam_auto_copy_ext(enum dcam_path_index path_index, uint32_t path_copy, uint32_t coef_copy);
284 LOCAL void _dcam_force_copy(enum dcam_path_index path_index);
285 LOCAL void _dcam_auto_copy(enum dcam_path_index path_index);
286 LOCAL void _dcam_reg_trace(void);
287 /*LOCAL void _dcam_sensor_sof(void);*/
288 LOCAL void _dcam_sensor_eof(void);
289 LOCAL void _dcam_cap_sof(void);
290 LOCAL void _dcam_cap_eof(void);
291 LOCAL void _dcam_path0_done(void);
292 LOCAL void _dcam_path0_overflow(void);
293 LOCAL void _dcam_path1_done(void);
294 LOCAL void _dcam_path1_overflow(void);
295 LOCAL void _dcam_sensor_line_err(void);
296 LOCAL void _dcam_sensor_frame_err(void);
297 LOCAL void _dcam_jpeg_buf_ov(void);
298 LOCAL void _dcam_path2_done(void);
299 LOCAL void _dcam_path2_ov(void);
300 LOCAL void _dcam_isp_ov(void);
301 LOCAL void _dcam_mipi_ov(void);
302 LOCAL void _dcam_path1_slice_done(void);
303 LOCAL void _dcam_path2_slice_done(void);
304 LOCAL void _dcam_raw_slice_done(void);
305 LOCAL void _dcam_path1_sof(void);
306 LOCAL void _dcam_path2_sof(void);
307 LOCAL irqreturn_t _dcam_isr_root(int irq, void *dev_id);
308 LOCAL void _dcam_stopped_notice(void);
309 LOCAL void _dcam_stopped(void);
310 LOCAL int32_t _dcam_path_check_deci(enum dcam_path_index path_index, uint32_t *is_deci);
311 extern void _dcam_isp_root(void);
312 LOCAL int _dcam_internal_init(void);
313 LOCAL void _dcam_internal_deinit(void);
314 LOCAL void _dcam_wait_path_done(enum dcam_path_index path_index, uint32_t *p_flag);
315 LOCAL void _dcam_path_done_notice(enum dcam_path_index path_index);
316 LOCAL void _dcam_rot_done(void);
317 LOCAL int32_t _dcam_err_pre_proc(void);
318 LOCAL void _dcam_frm_queue_clear(struct dcam_frm_queue *queue);
319 LOCAL int32_t _dcam_frame_enqueue(struct dcam_frm_queue *queue, struct dcam_frame *frame);
320 LOCAL int32_t _dcam_frame_dequeue(struct dcam_frm_queue *queue, struct dcam_frame *frame);
321 LOCAL void _dcam_buf_queue_init(struct dcam_buf_queue *queue);
322 LOCAL int32_t _dcam_buf_queue_write(struct dcam_buf_queue *queue, struct dcam_frame *frame);
323 LOCAL int32_t _dcam_buf_queue_read(struct dcam_buf_queue *queue, struct dcam_frame *frame);
324 LOCAL void _dcam_wait_update_done(enum dcam_path_index path_index, uint32_t *p_flag);
325 LOCAL void _dcam_path_updated_notice(enum dcam_path_index path_index);
326 LOCAL int32_t _dcam_get_valid_sc_coeff(struct dcam_sc_array *sc, struct dcam_sc_coeff **sc_coeff);
327 LOCAL int32_t _dcam_push_sc_buf(struct dcam_sc_array *sc, uint32_t index);
328 LOCAL int32_t _dcam_pop_sc_buf(struct dcam_sc_array *sc, struct dcam_sc_coeff **sc_coeff);
329 LOCAL int32_t _dcam_calc_sc_coeff(enum dcam_path_index path_index);
330 LOCAL int32_t _dcam_write_sc_coeff(enum dcam_path_index path_index);
331 LOCAL void _dcam_wait_for_quickstop(enum dcam_path_index path_index);
333 LOCAL const dcam_isr isr_list[DCAM_IRQ_NUMBER] = {
334 NULL,//_dcam_isp_root,
339 _dcam_path0_overflow,
341 _dcam_path1_overflow,
344 _dcam_sensor_line_err,
345 _dcam_sensor_frame_err,
350 _dcam_path1_slice_done,
351 _dcam_path2_slice_done,
352 _dcam_raw_slice_done,
357 void dcam_glb_reg_awr(unsigned long addr, uint32_t val, uint32_t reg_id)
363 spin_lock_irqsave(&dcam_glb_reg_cfg_lock, flag);
364 REG_WR(addr, REG_RD(addr) & (val));
365 spin_unlock_irqrestore(&dcam_glb_reg_cfg_lock, flag);
367 case DCAM_CONTROL_REG:
368 spin_lock_irqsave(&dcam_glb_reg_control_lock, flag);
369 REG_WR(addr, REG_RD(addr) & (val));
370 spin_unlock_irqrestore(&dcam_glb_reg_control_lock, flag);
372 case DCAM_INIT_MASK_REG:
373 spin_lock_irqsave(&dcam_glb_reg_mask_lock, flag);
374 REG_WR(addr, REG_RD(addr) & (val));
375 spin_unlock_irqrestore(&dcam_glb_reg_mask_lock, flag);
377 case DCAM_INIT_CLR_REG:
378 spin_lock_irqsave(&dcam_glb_reg_clr_lock, flag);
379 REG_WR(addr, REG_RD(addr) & (val));
380 spin_unlock_irqrestore(&dcam_glb_reg_clr_lock, flag);
382 case DCAM_AHBM_STS_REG:
383 spin_lock_irqsave(&dcam_glb_reg_ahbm_sts_lock, flag);
384 REG_WR(addr, REG_RD(addr) & (val));
385 spin_unlock_irqrestore(&dcam_glb_reg_ahbm_sts_lock, flag);
387 case DCAM_ENDIAN_REG:
388 spin_lock_irqsave(&dcam_glb_reg_endian_lock, flag);
389 REG_WR(addr, REG_RD(addr) & (val));
390 spin_unlock_irqrestore(&dcam_glb_reg_endian_lock, flag);
393 REG_WR(addr, REG_RD(addr) & (val));
398 void dcam_glb_reg_owr(unsigned long addr, uint32_t val, uint32_t reg_id)
404 spin_lock_irqsave(&dcam_glb_reg_cfg_lock, flag);
405 REG_WR(addr, REG_RD(addr) | (val));
406 spin_unlock_irqrestore(&dcam_glb_reg_cfg_lock, flag);
408 case DCAM_CONTROL_REG:
409 spin_lock_irqsave(&dcam_glb_reg_control_lock, flag);
410 REG_WR(addr, REG_RD(addr) | (val));
411 spin_unlock_irqrestore(&dcam_glb_reg_control_lock, flag);
413 case DCAM_INIT_MASK_REG:
414 spin_lock_irqsave(&dcam_glb_reg_mask_lock, flag);
415 REG_WR(addr, REG_RD(addr) | (val));
416 spin_unlock_irqrestore(&dcam_glb_reg_mask_lock, flag);
418 case DCAM_INIT_CLR_REG:
419 spin_lock_irqsave(&dcam_glb_reg_clr_lock, flag);
420 REG_WR(addr, REG_RD(addr) | (val));
421 spin_unlock_irqrestore(&dcam_glb_reg_clr_lock, flag);
423 case DCAM_AHBM_STS_REG:
424 spin_lock_irqsave(&dcam_glb_reg_ahbm_sts_lock, flag);
425 REG_WR(addr, REG_RD(addr) | (val));
426 spin_unlock_irqrestore(&dcam_glb_reg_ahbm_sts_lock, flag);
428 case DCAM_ENDIAN_REG:
429 spin_lock_irqsave(&dcam_glb_reg_endian_lock, flag);
430 REG_WR(addr, REG_RD(addr) | (val));
431 spin_unlock_irqrestore(&dcam_glb_reg_endian_lock, flag);
434 REG_WR(addr, REG_RD(addr) | (val));
439 void dcam_glb_reg_mwr(unsigned long addr, uint32_t mask, uint32_t val, uint32_t reg_id)
446 spin_lock_irqsave(&dcam_glb_reg_cfg_lock, flag);
450 REG_WR(addr, tmp | ((mask) & (val)));
452 spin_unlock_irqrestore(&dcam_glb_reg_cfg_lock, flag);
454 case DCAM_CONTROL_REG:
455 spin_lock_irqsave(&dcam_glb_reg_control_lock, flag);
459 REG_WR(addr, tmp | ((mask) & (val)));
461 spin_unlock_irqrestore(&dcam_glb_reg_control_lock, flag);
463 case DCAM_INIT_MASK_REG:
464 spin_lock_irqsave(&dcam_glb_reg_mask_lock, flag);
468 REG_WR(addr, tmp | ((mask) & (val)));
470 spin_unlock_irqrestore(&dcam_glb_reg_mask_lock, flag);
472 case DCAM_INIT_CLR_REG:
473 spin_lock_irqsave(&dcam_glb_reg_clr_lock, flag);
477 REG_WR(addr, tmp | ((mask) & (val)));
479 spin_unlock_irqrestore(&dcam_glb_reg_clr_lock, flag);
481 case DCAM_AHBM_STS_REG:
482 spin_lock_irqsave(&dcam_glb_reg_ahbm_sts_lock, flag);
486 REG_WR(addr, tmp | ((mask) & (val)));
488 spin_unlock_irqrestore(&dcam_glb_reg_ahbm_sts_lock, flag);
490 case DCAM_ENDIAN_REG:
491 spin_lock_irqsave(&dcam_glb_reg_endian_lock, flag);
495 REG_WR(addr, tmp | ((mask) & (val)));
497 spin_unlock_irqrestore(&dcam_glb_reg_endian_lock, flag);
503 REG_WR(addr, tmp | ((mask) & (val)));
509 int32_t dcam_module_init(enum dcam_cap_if_mode if_mode,
510 enum dcam_cap_sensor_mode sn_mode)
512 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
513 struct dcam_cap_desc *cap_desc = NULL;
515 if (if_mode >= DCAM_CAP_IF_MODE_MAX) {
516 rtn = -DCAM_RTN_CAP_IF_MODE_ERR;
518 if (sn_mode >= DCAM_CAP_MODE_MAX) {
519 rtn = -DCAM_RTN_CAP_SENSOR_MODE_ERR;
521 _dcam_internal_init();
522 _dcam_link_frm(0); /* set default base frame index as 0 */
523 _dcam_buf_queue_init(&s_p_dcam_mod->dcam_path0.buf_queue);
524 _dcam_buf_queue_init(&s_p_dcam_mod->dcam_path1.buf_queue);
525 _dcam_buf_queue_init(&s_p_dcam_mod->dcam_path2.buf_queue);
526 cap_desc = &s_p_dcam_mod->dcam_cap;
527 cap_desc->interface = if_mode;
528 cap_desc->input_format = sn_mode;
529 /*REG_OWR(DCAM_EB, BIT_13);//MM_EB*/
530 /*REG_OWR(DCAM_MATRIX_EB, BIT_10|BIT_5);*/
531 if (DCAM_CAP_IF_CSI2 == if_mode) {
532 /* REG_OWR(CSI2_DPHY_EB, MIPI_EB_BIT);*/
533 //ret = _dcam_mipi_clk_en();
534 dcam_glb_reg_owr(DCAM_CFG, BIT_9, DCAM_CFG_REG);
535 REG_MWR(CAP_MIPI_CTRL, BIT_2 | BIT_1, sn_mode << 1);
537 /*REG_OWR(DCAM_EB, CCIR_IN_EB_BIT);
538 REG_OWR(DCAM_EB, CCIR_EB_BIT);*/
539 //ret = _dcam_ccir_clk_en();
540 dcam_glb_reg_mwr(DCAM_CFG, BIT_9, 0 << 9, DCAM_CFG_REG);
541 REG_MWR(CAP_CCIR_CTRL, BIT_2 | BIT_1, sn_mode << 1);
543 rtn = DCAM_RTN_SUCCESS;
550 int32_t dcam_module_deinit(enum dcam_cap_if_mode if_mode,
551 enum dcam_cap_sensor_mode sn_mode)
553 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
555 if (DCAM_CAP_IF_CSI2 == if_mode) {
556 /*REG_MWR(CSI2_DPHY_EB, MIPI_EB_BIT, 0 << 10);*/
557 dcam_glb_reg_mwr(DCAM_CFG, BIT_9, 0 << 9, DCAM_CFG_REG);
558 //_dcam_mipi_clk_dis();
560 /*REG_MWR(DCAM_EB, CCIR_IN_EB_BIT, 0 << 2);
561 REG_MWR(DCAM_EB, CCIR_EB_BIT, 0 << 9);*/
562 dcam_glb_reg_mwr(DCAM_CFG, BIT_9, 0 << 9, DCAM_CFG_REG);
563 //_dcam_ccir_clk_dis();
566 _dcam_internal_deinit();
571 int dcam_scale_coeff_alloc(void)
575 if (NULL == s_dcam_sc_array) {
576 s_dcam_sc_array = (struct dcam_sc_array*)vzalloc(sizeof(struct dcam_sc_array));
577 if (NULL == s_dcam_sc_array) {
578 printk("DCAM: _dcam_scale_coeff_alloc fail.\n");
586 void dcam_scale_coeff_free(void)
588 if (s_dcam_sc_array) {
589 vfree(s_dcam_sc_array);
590 s_dcam_sc_array = NULL;
594 LOCAL uint32_t *dcam_get_scale_coeff_addr(uint32_t *index)
598 if (DCAM_ADDR_INVALID(s_dcam_sc_array)) {
599 printk("DCAM: scale addr, invalid param %p \n", s_dcam_sc_array);
603 for (i = 0; i < DCAM_SC_COEFF_BUF_COUNT; i++) {
604 if (0 == s_dcam_sc_array->scaling_coeff[i].flag) {
606 DCAM_TRACE("dcam: get buf index %d \n", i);
607 return s_dcam_sc_array->scaling_coeff[i].buf;
610 printk("dcam: get buf index %d \n", i);
615 int32_t dcam_module_en(struct device_node *dn)
618 unsigned int irq_no = 0;
620 DCAM_TRACE("DCAM: dcam_module_en, In %d \n", s_dcam_users.counter);
622 mutex_lock(&dcam_module_sema);
623 if (atomic_inc_return(&s_dcam_users) == 1) {
625 wake_lock_init(&dcam_wakelock, WAKE_LOCK_SUSPEND,
626 "pm_message_wakelock_dcam");
628 wake_lock(&dcam_wakelock);
630 ret = clk_mm_i_eb(dn,1);
636 ret = dcam_set_clk(dn,DCAM_CLK_312M);
642 //parse_baseaddress(dn);
644 dcam_reset(DCAM_RST_ALL, 0);
645 atomic_set(&s_resize_flag, 0);
646 atomic_set(&s_rotation_flag, 0);
647 memset((void*)s_user_func, 0, sizeof(s_user_func));
648 memset((void*)s_user_data, 0, sizeof(s_user_data));
649 printk("DCAM: register isr, 0x%x \n", REG_RD(DCAM_INT_MASK));
651 irq_no = parse_irq(dn);
652 printk("DCAM: irq_no = 0x%x \n", irq_no);
653 ret = request_irq(irq_no,
659 printk("DCAM: dcam_start, error %d \n", ret);
660 dcam_set_clk(dn,DCAM_CLK_NONE);
666 DCAM_TRACE("DCAM: dcam_module_en end \n");
668 DCAM_TRACE("DCAM: dcam_module_en, Out %d \n", s_dcam_users.counter);
669 mutex_unlock(&dcam_module_sema);
673 wake_unlock(&dcam_wakelock);
674 wake_lock_destroy(&dcam_wakelock);
675 atomic_dec(&s_dcam_users);
676 mutex_unlock(&dcam_module_sema);
680 int32_t dcam_module_dis(struct device_node *dn)
682 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
684 unsigned int irq_no = 0;
686 DCAM_TRACE("DCAM: dcam_module_dis, In %d \n", s_dcam_users.counter);
688 mutex_lock(&dcam_module_sema);
689 if (atomic_dec_return(&s_dcam_users) == 0) {
691 sci_glb_clr(DCAM_EB, DCAM_EB_BIT);
692 dcam_set_clk(dn,DCAM_CLK_NONE);
693 printk("DCAM: un register isr \n");
694 irq_no = parse_irq(dn);
695 free_irq(irq_no, (void*)&s_dcam_irq);
696 ret = clk_mm_i_eb(dn,0);
700 wake_unlock(&dcam_wakelock);
701 wake_lock_destroy(&dcam_wakelock);
704 DCAM_TRACE("DCAM: dcam_module_dis, Out %d \n", s_dcam_users.counter);
705 mutex_unlock(&dcam_module_sema);
710 int32_t dcam_reset(enum dcam_rst_mode reset_mode, uint32_t is_isr)
712 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
713 uint32_t time_out = 0;
715 DCAM_TRACE("DCAM: reset: %d \n", reset_mode);
717 printk("DCAM: reset: %d %d \n", reset_mode, is_isr);
718 if (DCAM_RST_ALL == reset_mode) {
719 /* then wait for AHB busy cleared */
720 while (++time_out < DCAM_AXI_STOP_TIMEOUT) {
721 if (0 == (REG_RD(DCAM_AHBM_STS) & BIT_0))
724 if (time_out >= DCAM_AXI_STOP_TIMEOUT) {
725 printk("DCAM: reset TO: %d \n", time_out);
726 return DCAM_RTN_TIMEOUT;
730 /* do reset action */
731 switch (reset_mode) {
733 sci_glb_set(DCAM_RST, PATH0_RST_BIT);
734 sci_glb_clr(DCAM_RST, PATH0_RST_BIT);
735 DCAM_TRACE("DCAM: reset path0 \n");
739 sci_glb_set(DCAM_RST, PATH1_RST_BIT);
740 sci_glb_clr(DCAM_RST, PATH1_RST_BIT);
741 DCAM_TRACE("DCAM: reset path1 \n");
745 sci_glb_set(DCAM_RST, PATH2_RST_BIT);
746 sci_glb_clr(DCAM_RST, PATH2_RST_BIT);
747 DCAM_TRACE("DCAM: reset path2 \n");
751 sci_glb_set(DCAM_RST, DCAM_MOD_RST_BIT | CCIR_RST_BIT);
752 sci_glb_clr(DCAM_RST, DCAM_MOD_RST_BIT | CCIR_RST_BIT);
753 dcam_glb_reg_owr(DCAM_INT_CLR,
756 dcam_glb_reg_owr(DCAM_INT_MASK,
759 printk("DCAM: reset all \n");
762 rtn = DCAM_RTN_PARA_ERR;
766 if (DCAM_RST_ALL == reset_mode) {
767 if (atomic_read(&s_dcam_users)) {
768 /* the end, enable AXI writing */
769 dcam_glb_reg_awr(DCAM_AHBM_STS, ~BIT_6, DCAM_AHBM_STS_REG);
773 DCAM_TRACE("DCAM: reset_mode=%x end \n", reset_mode);
778 int32_t dcam_set_clk(struct device_node *dn, enum dcam_clk_sel clk_sel)
780 #ifdef CONFIG_SC_FPGA
783 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
784 struct clk *clk_parent;
785 char *parent = "clk_312m";
799 parent = "clk_76p8m";
802 printk("DCAM close CLK %d \n", (int)clk_get_rate(s_dcam_clk));
804 clk_disable(s_dcam_clk);
814 if (NULL == s_dcam_clk) {
815 s_dcam_clk = parse_clk(dn,"clk_dcam");
816 if (IS_ERR(s_dcam_clk)) {
817 printk("DCAM: clk_get fail, %d \n", (int)s_dcam_clk);
820 DCAM_TRACE("DCAM: get clk_parent ok \n");
823 clk_disable(s_dcam_clk);
826 clk_parent = clk_get(NULL, parent);
827 if (IS_ERR(clk_parent)) {
828 printk("DCAM: dcam_set_clk fail, %d \n", (int)clk_parent);
831 DCAM_TRACE("DCAM: get clk_parent ok \n");
834 ret = clk_set_parent(s_dcam_clk, clk_parent);
836 printk("DCAM: clk_set_parent fail, %d \n", ret);
839 ret = clk_enable(s_dcam_clk);
841 printk("enable dcam clk error.\n");
848 int32_t dcam_update_path(enum dcam_path_index path_index, struct dcam_size *in_size,
849 struct dcam_rect *in_rect, struct dcam_size *out_size)
851 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
853 uint32_t is_deci = 0;
855 DCAM_CHECK_ZERO(s_p_dcam_mod);
856 DCAM_CHECK_ZERO(s_dcam_sc_array);
858 spin_lock_irqsave(&dcam_lock, flags);
859 if ((DCAM_PATH_IDX_1 & path_index) && s_p_dcam_mod->dcam_path1.valide) {
860 rtn = dcam_path1_cfg(DCAM_PATH_INPUT_SIZE, in_size);
862 rtn = dcam_path1_cfg(DCAM_PATH_INPUT_RECT, in_rect);
864 rtn = dcam_path1_cfg(DCAM_PATH_OUTPUT_SIZE, out_size);
866 rtn = _dcam_path_check_deci(DCAM_PATH_IDX_1, &is_deci);
868 DCAM_TRACE("DCAM: To update path1 \n");
869 rtn = _dcam_path_scaler(DCAM_PATH_IDX_1);
871 DCAM_TRACE("DCAM: dcam_update_path 1 \n");
872 if (s_dcam_sc_array->is_smooth_zoom) {
873 s_p_dcam_mod->dcam_path1.is_update = 1;
874 spin_unlock_irqrestore(&dcam_lock, flags);
876 spin_unlock_irqrestore(&dcam_lock, flags);
877 _dcam_wait_update_done(DCAM_PATH_IDX_1, &s_p_dcam_mod->dcam_path1.is_update);
879 if (!s_dcam_sc_array->is_smooth_zoom) {
880 _dcam_wait_update_done(DCAM_PATH_IDX_1, NULL);
884 if ((DCAM_PATH_IDX_2 & path_index) && s_p_dcam_mod->dcam_path2.valide) {
885 if (s_p_dcam_mod->dcam_path2.is_update) {
886 spin_unlock_irqrestore(&dcam_lock, flags);
887 DCAM_TRACE("DCAM: dcam_update_path 2: updating return \n");
890 rtn = dcam_path2_cfg(DCAM_PATH_INPUT_SIZE, in_size);
892 rtn = dcam_path2_cfg(DCAM_PATH_INPUT_RECT, in_rect);
894 rtn = dcam_path2_cfg(DCAM_PATH_OUTPUT_SIZE, out_size);
896 rtn = _dcam_path_scaler(DCAM_PATH_IDX_2);
898 s_p_dcam_mod->dcam_path2.is_update = 1;
899 spin_unlock_irqrestore(&dcam_lock, flags);
903 DCAM_TRACE("DCAM: dcam_update_path: done \n");
908 int32_t dcam_start_path(enum dcam_path_index path_index)
910 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
913 DCAM_CHECK_ZERO(s_p_dcam_mod);
915 DCAM_TRACE("DCAM: start_path: path %d, mode %x path 0,1,2 {%d %d %d} \n",
917 s_p_dcam_mod->dcam_mode,
918 s_p_dcam_mod->dcam_path0.valide,
919 s_p_dcam_mod->dcam_path1.valide,
920 s_p_dcam_mod->dcam_path2.valide);
922 dcam_glb_reg_owr(DCAM_AHBM_STS, BIT_8, DCAM_AHBM_STS_REG); // aiden add: write arbit mode
924 cap_en = REG_RD(DCAM_CONTROL) & BIT_2;
925 DCAM_TRACE("DCAM: cap_eb %d \n", cap_en);
926 if ((DCAM_PATH_IDX_0 & path_index) && s_p_dcam_mod->dcam_path0.valide) {
928 rtn = _dcam_path_set_next_frm(DCAM_PATH_IDX_0, true);
930 _dcam_force_copy(DCAM_PATH_IDX_0);
933 /* if cap is already open, the sequence is:
934 cap force copy -> path 0 enable -> cap auto copy */
935 dcam_glb_reg_mwr(DCAM_CONTROL, BIT_0, 1 << 0, DCAM_CONTROL_REG); /* Cap force copy */
936 dcam_glb_reg_owr(DCAM_CFG, BIT_0, DCAM_CFG_REG); /* Enable Path 0 */
937 dcam_glb_reg_mwr(DCAM_CONTROL, BIT_1, 1 << 1, DCAM_CONTROL_REG); /* Cap auto copy, trigger path 0 enable */
939 dcam_glb_reg_owr(DCAM_CFG, BIT_0, DCAM_CFG_REG); /* Enable Path 0 */
944 if ((DCAM_PATH_IDX_1 & path_index) && s_p_dcam_mod->dcam_path1.valide) {
946 //rtn = _dcam_path_trim(DCAM_PATH_IDX_1);
948 rtn = _dcam_path_scaler(DCAM_PATH_IDX_1);
951 _dcam_path1_set(&s_p_dcam_mod->dcam_path1);
952 DCAM_TRACE("DCAM: start path: path_control=%x \n", REG_RD(DCAM_CONTROL));
954 rtn = _dcam_path_set_next_frm(DCAM_PATH_IDX_1, true);
956 _dcam_force_copy_ext(DCAM_PATH_IDX_1, true, true);
957 DCAM_TRACE("DCAM: int= %x \n", REG_RD(DCAM_INT_STS));
958 dcam_glb_reg_owr(DCAM_CFG, BIT_1, DCAM_CFG_REG);
961 if ((DCAM_PATH_IDX_2 & path_index) && s_p_dcam_mod->dcam_path2.valide) {
962 rtn = _dcam_path_scaler(DCAM_PATH_IDX_2);
967 rtn = _dcam_path_set_next_frm(DCAM_PATH_IDX_2, true);
969 _dcam_force_copy_ext(DCAM_PATH_IDX_2, true, true);
972 if ((DCAM_PATH_IDX_0 & path_index) && s_p_dcam_mod->dcam_path0.valide) {
973 rtn = _dcam_path_set_next_frm(DCAM_PATH_IDX_0, false);
975 _dcam_auto_copy(DCAM_PATH_IDX_0);
976 s_p_dcam_mod->dcam_path0.status = DCAM_ST_START;
977 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) {
981 s_p_dcam_mod->dcam_path1.need_wait = 0;
982 s_p_dcam_mod->dcam_path1.status = DCAM_ST_START;
983 dcam_glb_reg_owr(DCAM_CFG, BIT_1, DCAM_CFG_REG);
986 if ((DCAM_PATH_IDX_2 & path_index) && s_p_dcam_mod->dcam_path2.valide) {
987 s_p_dcam_mod->dcam_path2.need_wait = 0;
988 s_p_dcam_mod->dcam_path2.status = DCAM_ST_START;
989 dcam_glb_reg_owr(DCAM_CFG, BIT_2, DCAM_CFG_REG);
993 #if 0 //def DCAM_DEBUG
994 REG_MWR(CAP_CCIR_FRM_CTRL, BIT_5 | BIT_4, 0 << 4);
995 REG_MWR(CAP_CCIR_FRM_CTRL, BIT_3|BIT_2|BIT_1|BIT_0, 0x07);
996 REG_MWR(CAP_MIPI_FRM_CTRL, BIT_5 | BIT_4, 1 << 4);
997 REG_MWR(CAP_MIPI_FRM_CTRL, BIT_3|BIT_2|BIT_1|BIT_0, 0x07);
999 dcam_glb_reg_mwr(DCAM_CONTROL, BIT_0, 1 << 0, DCAM_CONTROL_REG); /* Cap force copy */
1000 //REG_MWR(DCAM_CONTROL, BIT_1, 1 << 1); /* Cap auto copy */
1001 dcam_glb_reg_mwr(DCAM_CONTROL, BIT_2, 1 << 2, DCAM_CONTROL_REG); /* Cap Enable */
1004 if (DCAM_PATH_IDX_ALL != path_index) {
1005 if ((DCAM_PATH_IDX_0 & path_index)) {
1006 _dcam_wait_path_done(DCAM_PATH_IDX_0, NULL);
1007 } else if ((DCAM_PATH_IDX_1 & path_index)) {
1008 _dcam_wait_path_done(DCAM_PATH_IDX_1, NULL);
1009 } else if ((DCAM_PATH_IDX_2 & path_index)) {
1010 _dcam_wait_path_done(DCAM_PATH_IDX_2, NULL);
1014 printk("DCAM PATH S: %d \n", path_index);
1018 DCAM_TRACE("DCAM: start_path E\n");
1022 int32_t dcam_start(void)
1024 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
1027 DCAM_CHECK_ZERO(s_p_dcam_mod);
1029 DCAM_TRACE("DCAM: dcam_start %x \n", s_p_dcam_mod->dcam_mode);
1031 ret = dcam_start_path(DCAM_PATH_IDX_ALL);
1032 //ret = dcam_start_path(DCAM_PATH_IDX_1);
1037 int32_t dcam_stop_cap(void)
1039 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
1044 int32_t _dcam_stop_path(enum dcam_path_index path_index)
1046 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
1047 struct dcam_path_desc *p_path = NULL;
1050 spin_lock_irqsave(&dcam_lock, flag);
1052 if (DCAM_PATH_IDX_0 == path_index) {
1053 p_path = &s_p_dcam_mod->dcam_path0;
1054 } else if(DCAM_PATH_IDX_1 == path_index) {
1055 p_path = &s_p_dcam_mod->dcam_path1;
1056 } else if(DCAM_PATH_IDX_2 == path_index) {
1057 p_path = &s_p_dcam_mod->dcam_path2;
1059 printk("DCAM: stop path Wrong index 0x%x \n", path_index);
1060 spin_unlock_irqrestore(&dcam_lock, flag);
1064 _dcam_wait_for_quickstop(path_index);
1065 p_path->status = DCAM_ST_STOP;
1067 _dcam_frm_clear(path_index);
1069 spin_unlock_irqrestore(&dcam_lock, flag);
1074 int32_t dcam_stop_path(enum dcam_path_index path_index)
1076 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
1078 DCAM_CHECK_ZERO(s_p_dcam_mod);
1080 printk("DCAM: stop_path 0x%x \n", path_index);
1082 if (path_index < DCAM_PATH_IDX_0 ||
1083 path_index >= DCAM_PATH_IDX_ALL) {
1084 printk("DCAM: error path_index \n");
1088 if ((DCAM_PATH_IDX_0 & path_index) && s_p_dcam_mod->dcam_path0.valide) {
1089 _dcam_wait_path_done(DCAM_PATH_IDX_0, &s_p_dcam_mod->dcam_path0.need_stop);
1090 _dcam_stop_path(DCAM_PATH_IDX_0);
1093 if ((DCAM_PATH_IDX_1 & path_index) && s_p_dcam_mod->dcam_path1.valide) {
1094 _dcam_wait_path_done(DCAM_PATH_IDX_1, &s_p_dcam_mod->dcam_path1.need_stop);
1095 _dcam_stop_path(DCAM_PATH_IDX_1);
1098 if ((DCAM_PATH_IDX_2 & path_index) && s_p_dcam_mod->dcam_path2.valide) {
1099 DCAM_TRACE("DCAM: stop path2 In \n");
1100 _dcam_wait_path_done(DCAM_PATH_IDX_2, &s_p_dcam_mod->dcam_path2.need_stop);
1101 _dcam_stop_path(DCAM_PATH_IDX_2);
1104 DCAM_TRACE("DCAM dcam_stop_path E: %d \n", path_index);
1109 LOCAL void _dcam_wait_for_channel_stop(enum dcam_path_index path_index)
1111 int time_out = 5000;
1114 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
1116 /* wait for AHB path busy cleared */
1118 if (s_p_dcam_mod->dcam_path1.valide && (DCAM_PATH_IDX_1 & path_index)) {
1119 ret = REG_RD(DCAM_AHBM_STS) & BIT_17;
1120 } else if (s_p_dcam_mod->dcam_path2.valide && (DCAM_PATH_IDX_2 & path_index)) {
1121 ret = REG_RD(DCAM_AHBM_STS) & BIT_18;
1131 DCAM_TRACE("DCAM: wait channel stop %d %d \n", ret, time_out);
1136 LOCAL void _dcam_quickstop_set(enum dcam_path_index path_index, uint32_t path_rst, uint32_t path_bit,
1137 uint32_t cfg_bit, uint32_t ahbm_bit, uint32_t auto_copy_bit)
1139 dcam_glb_reg_owr(DCAM_AHBM_STS, ahbm_bit, DCAM_AHBM_STS_REG);
1141 dcam_glb_reg_mwr(DCAM_CFG, cfg_bit, ~cfg_bit, DCAM_CFG_REG);
1142 _dcam_force_copy(path_index);
1143 _dcam_wait_for_channel_stop(path_index);
1144 dcam_glb_reg_awr(DCAM_AHBM_STS, ~ahbm_bit, DCAM_AHBM_STS_REG);
1145 dcam_reset(path_rst, 0);
1150 #define DCAM_IRQ_MASK_PATH0 (0x0f|(0x03<<4)|(1<<12)|(1<<21)) //let other module continue
1151 #define DCAM_IRQ_MASK_PATH1 (0x0f|(0x03<<6)|(1<<16)|(1<<19)|(1<<22))
1152 #define DCAM_IRQ_MASK_PATH2 (0x0f|(0x03<<8)|(1<<17)|(1<<20)|(1<<23))
1154 LOCAL void _dcam_quickstop_set_all(enum dcam_path_index path_index, uint32_t path_bit, uint32_t cfg_bit, uint32_t ahbm_bit)
1156 dcam_glb_reg_owr(DCAM_AHBM_STS, BIT_3 | BIT_4 | BIT_5, DCAM_AHBM_STS_REG);
1158 dcam_glb_reg_awr(DCAM_CFG, ~(BIT_0 | BIT_1 | BIT_2), DCAM_CFG_REG);
1159 dcam_glb_reg_owr(DCAM_CONTROL, BIT_10 | BIT_12, DCAM_CONTROL_REG);
1160 dcam_glb_reg_awr(DCAM_CONTROL, ~(BIT_10 | BIT_12), DCAM_CONTROL_REG);
1161 _dcam_wait_for_channel_stop(DCAM_PATH_IDX_1);
1162 _dcam_wait_for_channel_stop(DCAM_PATH_IDX_2);
1167 LOCAL void _dcam_wait_for_quickstop(enum dcam_path_index path_index)
1169 int time_out = 5000;
1171 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
1173 DCAM_TRACE("DCAM: state before stop 0x%x\n", s_p_dcam_mod->state);
1175 if (DCAM_PATH_IDX_ALL == path_index) {
1176 _dcam_quickstop_set_all(0, 0, 0, 0);
1178 if (s_p_dcam_mod->dcam_path0.valide && (DCAM_PATH_IDX_0 & path_index)) {
1179 _dcam_quickstop_set(DCAM_PATH_IDX_0, DCAM_RST_PATH0, DCAM_IRQ_MASK_PATH0, BIT_0, BIT_3, BIT_9);
1181 if (s_p_dcam_mod->dcam_path1.valide && (DCAM_PATH_IDX_1 & path_index)) {
1182 _dcam_quickstop_set(DCAM_PATH_IDX_1, DCAM_RST_PATH1, DCAM_IRQ_MASK_PATH1, BIT_1, BIT_4, BIT_11);
1184 if (s_p_dcam_mod->dcam_path2.valide && (DCAM_PATH_IDX_2 & path_index)) {
1185 _dcam_quickstop_set(DCAM_PATH_IDX_2, DCAM_RST_PATH2, DCAM_IRQ_MASK_PATH2, BIT_2, BIT_5, BIT_13);
1189 DCAM_TRACE("DCAM: exit _dcam_wait_for_quickstop %d state: 0x%x \n ", time_out, s_p_dcam_mod->state);
1194 int32_t dcam_stop(void)
1196 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
1199 DCAM_CHECK_ZERO(s_p_dcam_mod);
1201 s_p_dcam_mod->state |= DCAM_STATE_QUICKQUIT;
1202 printk("DCAM dcam_stop In \n");
1203 if (atomic_read(&s_resize_flag)) {
1204 s_p_dcam_mod->wait_resize_done = 1;
1205 rtn = down_timeout(&s_p_dcam_mod->resize_done_sema, DCAM_PATH_TIMEOUT);
1207 if (atomic_read(&s_rotation_flag)) {
1208 s_p_dcam_mod->wait_rotation_done = 1;
1209 rtn = down_timeout(&s_p_dcam_mod->rotation_done_sema, DCAM_PATH_TIMEOUT);
1212 mutex_lock(&dcam_scale_sema);
1213 mutex_lock(&dcam_rot_sema);
1215 spin_lock_irqsave(&dcam_lock, flag);
1217 _dcam_wait_for_quickstop(DCAM_PATH_IDX_ALL);
1218 s_p_dcam_mod->dcam_path0.status = DCAM_ST_STOP;
1219 s_p_dcam_mod->dcam_path0.valide = 0;
1220 s_p_dcam_mod->dcam_path1.status = DCAM_ST_STOP;
1221 s_p_dcam_mod->dcam_path1.valide = 0;
1222 s_p_dcam_mod->dcam_path2.status = DCAM_ST_STOP;
1223 s_p_dcam_mod->dcam_path2.valide = 0;
1224 _dcam_frm_clear(DCAM_PATH_IDX_0);
1225 _dcam_frm_clear(DCAM_PATH_IDX_1);
1226 _dcam_frm_clear(DCAM_PATH_IDX_2);
1227 spin_unlock_irqrestore(&dcam_lock, flag);
1229 dcam_reset(DCAM_RST_ALL, 0);
1230 mutex_unlock(&dcam_rot_sema);
1231 mutex_unlock(&dcam_scale_sema);
1233 s_p_dcam_mod->state &= ~DCAM_STATE_QUICKQUIT;
1235 DCAM_TRACE("DCAM: dcam_stop Out, s_resize_flag %d \n", atomic_read(&s_resize_flag));
1241 int32_t dcam_reg_isr(enum dcam_irq_id id, dcam_isr_func user_func, void* user_data)
1243 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
1246 if(id >= DCAM_IRQ_NUMBER) {
1247 rtn = DCAM_RTN_ISR_ID_ERR;
1249 spin_lock_irqsave(&dcam_lock, flag);
1250 s_user_func[id] = user_func;
1251 s_user_data[id] = user_data;
1252 spin_unlock_irqrestore(&dcam_lock, flag);
1257 int32_t dcam_cap_cfg(enum dcam_cfg_id id, void *param)
1259 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
1260 struct dcam_cap_desc *cap_desc = NULL;
1262 DCAM_CHECK_ZERO(s_p_dcam_mod);
1263 DCAM_CHECK_ZERO(s_dcam_sc_array);
1264 cap_desc = &s_p_dcam_mod->dcam_cap;
1266 case DCAM_CAP_SYNC_POL:
1268 struct dcam_cap_sync_pol *sync_pol = (struct dcam_cap_sync_pol*)param;
1270 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1272 if (DCAM_CAP_IF_CCIR == cap_desc->interface) {
1274 if (sync_pol->vsync_pol > 1 ||
1275 sync_pol->hsync_pol > 1 ||
1276 sync_pol->pclk_pol > 1) {
1277 rtn = DCAM_RTN_CAP_SYNC_POL_ERR;
1279 #ifndef CONFIG_SC_FPGA
1280 sci_glb_set(DCAM_CCIR_PCLK_EB, CCIR_PCLK_EB_BIT);
1282 REG_MWR(CAP_CCIR_CTRL, BIT_3, sync_pol->hsync_pol << 3);
1283 REG_MWR(CAP_CCIR_CTRL, BIT_4, sync_pol->vsync_pol << 4);
1284 //REG_MWR(CLK_DLY_CTRL, BIT_19, sync_pol->pclk_pol << 19); // aiden todo
1286 if (sync_pol->pclk_src == 0x00) {
1287 #ifndef CONFIG_SC_FPGA
1288 sci_glb_clr(CAP_CCIR_PLCK_SRC, (BIT_25 | BIT_26));
1290 DCAM_TRACE("DCAM: set pclk src0\n");
1291 } else if (sync_pol->pclk_src == 0x01) {
1292 #ifndef CONFIG_SC_FPGA
1293 sci_glb_clr(CAP_CCIR_PLCK_SRC, (BIT_25 | BIT_26));
1294 sci_glb_set(CAP_CCIR_PLCK_SRC, (BIT_25));
1296 DCAM_TRACE("DCAM: set pclk src1\n");
1298 DCAM_TRACE("DCAM: set pclk src default\n");
1302 if (sync_pol->need_href) {
1303 REG_MWR(CAP_MIPI_CTRL, BIT_5, 1 << 5);
1305 REG_MWR(CAP_MIPI_CTRL, BIT_5, 0 << 5);
1311 case DCAM_CAP_DATA_BITS:
1313 enum dcam_cap_data_bits bits = *(enum dcam_cap_data_bits*)param;
1315 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1317 if (DCAM_CAP_IF_CCIR == cap_desc->interface) {
1318 if (DCAM_CAP_8_BITS == bits || DCAM_CAP_10_BITS == bits) {
1319 REG_MWR(CAP_CCIR_CTRL, BIT_10 | BIT_9, 0 << 9);
1320 } else if (DCAM_CAP_4_BITS == bits) {
1321 REG_MWR(CAP_CCIR_CTRL, BIT_10 | BIT_9, 1 << 9);
1322 } else if (DCAM_CAP_2_BITS == bits) {
1323 REG_MWR(CAP_CCIR_CTRL, BIT_10 | BIT_9, 2 << 9);
1324 } else if (DCAM_CAP_1_BITS == bits) {
1325 REG_MWR(CAP_CCIR_CTRL, BIT_10 | BIT_9, 3 << 9);
1327 rtn = DCAM_RTN_CAP_IN_BITS_ERR;
1331 if (DCAM_CAP_12_BITS == bits) {
1332 REG_MWR(CAP_MIPI_CTRL, BIT_4 | BIT_3, 2 << 3);
1333 } else if (DCAM_CAP_10_BITS == bits) {
1334 REG_MWR(CAP_MIPI_CTRL, BIT_4 | BIT_3, 1 << 3);
1335 } else if (DCAM_CAP_8_BITS == bits) {
1336 REG_MWR(CAP_MIPI_CTRL, BIT_4 | BIT_3, 0 << 3);
1338 rtn = DCAM_RTN_CAP_IN_BITS_ERR;
1344 case DCAM_CAP_YUV_TYPE:
1346 enum dcam_cap_pattern pat = *(enum dcam_cap_pattern*)param;
1348 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1350 if (pat < DCAM_PATTERN_MAX) {
1351 if (DCAM_CAP_IF_CCIR == cap_desc->interface)
1352 REG_MWR(CAP_CCIR_CTRL, BIT_8 | BIT_7, pat << 7);
1354 REG_MWR(CAP_MIPI_CTRL, BIT_8 | BIT_7, pat << 7);
1356 rtn = DCAM_RTN_CAP_IN_YUV_ERR;
1361 case DCAM_CAP_PRE_SKIP_CNT:
1363 uint32_t skip_num = *(uint32_t*)param;
1365 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1367 if (skip_num > DCAM_CAP_SKIP_FRM_MAX) {
1368 rtn = DCAM_RTN_CAP_SKIP_FRAME_ERR;
1370 if (DCAM_CAP_IF_CCIR == cap_desc->interface)
1371 REG_MWR(CAP_CCIR_FRM_CTRL, BIT_3 | BIT_2 | BIT_1 | BIT_0, skip_num);
1373 REG_MWR(CAP_MIPI_FRM_CTRL, BIT_3 | BIT_2 | BIT_1 | BIT_0, skip_num);
1378 case DCAM_CAP_FRM_DECI:
1380 uint32_t deci_factor = *(uint32_t*)param;
1382 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1384 if (deci_factor < DCAM_FRM_DECI_FAC_MAX) {
1385 if (DCAM_CAP_IF_CCIR == cap_desc->interface)
1386 REG_MWR(CAP_CCIR_FRM_CTRL, BIT_5 | BIT_4, deci_factor << 4);
1388 REG_MWR(CAP_MIPI_FRM_CTRL, BIT_5 | BIT_4, deci_factor << 4);
1390 rtn = DCAM_RTN_CAP_FRAME_DECI_ERR;
1395 case DCAM_CAP_FRM_COUNT_CLR:
1396 if (DCAM_CAP_IF_CCIR == cap_desc->interface)
1397 REG_MWR(CAP_CCIR_FRM_CTRL, BIT_22, 1 << 22);
1399 REG_MWR(CAP_MIPI_FRM_CTRL, BIT_22, 1 << 22);
1402 case DCAM_CAP_INPUT_RECT:
1404 struct dcam_rect *rect = (struct dcam_rect*)param;
1407 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1409 if (rect->x > DCAM_CAP_FRAME_WIDTH_MAX ||
1410 rect->y > DCAM_CAP_FRAME_HEIGHT_MAX ||
1411 rect->w > DCAM_CAP_FRAME_WIDTH_MAX ||
1412 rect->h > DCAM_CAP_FRAME_HEIGHT_MAX ) {
1413 rtn = DCAM_RTN_CAP_FRAME_SIZE_ERR;
1418 if (DCAM_CAP_IF_CCIR == cap_desc->interface) {
1419 if (DCAM_CAP_MODE_RAWRGB == cap_desc->input_format) {
1420 tmp = rect->x | (rect->y << 16);
1421 REG_WR(CAP_CCIR_START, tmp);
1422 tmp = (rect->x + rect->w - 1);
1423 tmp |= (rect->y + rect->h - 1) << 16;
1424 REG_WR(CAP_CCIR_END, tmp);
1426 tmp = (rect->x << 1) | (rect->y << 16);
1427 REG_WR(CAP_CCIR_START, tmp);
1428 tmp = ((rect->x + rect->w) << 1) - 1;
1429 tmp |= (rect->y + rect->h - 1) << 16;
1430 REG_WR(CAP_CCIR_END, tmp);
1433 tmp = rect->x | (rect->y << 16);
1434 REG_WR(CAP_MIPI_START, tmp);
1435 tmp = (rect->x + rect->w - 1);
1436 tmp |= (rect->y + rect->h - 1) << 16;
1437 REG_WR(CAP_MIPI_END, tmp);
1442 case DCAM_CAP_IMAGE_XY_DECI:
1444 struct dcam_cap_dec *cap_dec = (struct dcam_cap_dec*)param;
1446 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1448 if (cap_dec->x_factor > DCAM_CAP_X_DECI_FAC_MAX ||
1449 cap_dec->y_factor > DCAM_CAP_Y_DECI_FAC_MAX ) {
1450 rtn = DCAM_RTN_CAP_XY_DECI_ERR;
1452 if (DCAM_CAP_MODE_RAWRGB == cap_desc->input_format) {
1453 if (cap_dec->x_factor > 1 ||
1454 cap_dec->y_factor > 1) {
1455 rtn = DCAM_RTN_CAP_XY_DECI_ERR;
1458 if (DCAM_CAP_IF_CCIR == cap_desc->interface) {
1459 REG_MWR(CAP_CCIR_IMG_DECI, BIT_1 | BIT_0, cap_dec->x_factor);
1460 REG_MWR(CAP_CCIR_IMG_DECI, BIT_3 | BIT_2, cap_dec->y_factor << 2);
1462 if (DCAM_CAP_MODE_RAWRGB == cap_desc->input_format) {
1463 // REG_MWR(CAP_MIPI_IMG_DECI, BIT_0, cap_dec->x_factor); // for camera path
1464 REG_MWR(CAP_MIPI_IMG_DECI, BIT_1, cap_dec->x_factor << 1);//for ISP
1466 REG_MWR(CAP_MIPI_IMG_DECI, BIT_1 | BIT_0, cap_dec->x_factor);
1467 REG_MWR(CAP_MIPI_IMG_DECI, BIT_3 | BIT_2, cap_dec->y_factor << 2);
1475 case DCAM_CAP_JPEG_SET_BUF_LEN:
1477 uint32_t jpg_buf_size = *(uint32_t*)param;
1479 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1480 jpg_buf_size = jpg_buf_size/DCAM_JPG_BUF_UNIT;
1481 if (jpg_buf_size >= DCAM_JPG_UNITS) {
1482 rtn = DCAM_RTN_CAP_JPEG_BUF_LEN_ERR;
1484 if (DCAM_CAP_IF_CCIR == cap_desc->interface)
1485 REG_WR(CAP_CCIR_JPG_CTRL,jpg_buf_size);
1487 REG_WR(CAP_MIPI_JPG_CTRL,jpg_buf_size);
1492 case DCAM_CAP_TO_ISP:
1494 uint32_t need_isp = *(uint32_t*)param;
1496 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1499 dcam_glb_reg_mwr(DCAM_CFG, BIT_7, 1 << 7, DCAM_CFG_REG);
1501 dcam_glb_reg_mwr(DCAM_CFG, BIT_7, 0 << 7, DCAM_CFG_REG);
1506 case DCAM_CAP_DATA_PACKET:
1508 uint32_t is_loose = *(uint32_t*)param;
1510 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1512 if (DCAM_CAP_IF_CSI2 == cap_desc->interface &&
1513 DCAM_CAP_MODE_RAWRGB == cap_desc->input_format) {
1515 REG_MWR(CAP_MIPI_CTRL, BIT_0, 1);
1517 REG_MWR(CAP_MIPI_CTRL, BIT_0, 0);
1520 rtn = DCAM_RTN_MODE_ERR;
1526 case DCAM_CAP_SAMPLE_MODE:
1528 enum dcam_capture_mode samp_mode = *(enum dcam_capture_mode*)param;
1530 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1532 if (samp_mode >= DCAM_CAPTURE_MODE_MAX) {
1533 rtn = DCAM_RTN_MODE_ERR;
1535 if (DCAM_CAP_IF_CSI2 == cap_desc->interface) {
1536 REG_MWR(CAP_MIPI_CTRL, BIT_6, samp_mode << 6);
1538 REG_MWR(CAP_CCIR_CTRL, BIT_6, samp_mode << 6);
1540 s_p_dcam_mod->dcam_mode = samp_mode;
1545 case DCAM_CAP_ZOOM_MODE:
1547 uint32_t zoom_mode = *(uint32_t*)param;
1549 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1551 s_dcam_sc_array->is_smooth_zoom = zoom_mode;
1555 rtn = DCAM_RTN_IO_ID_ERR;
1563 int32_t dcam_cap_get_info(enum dcam_cfg_id id, void *param)
1565 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
1566 struct dcam_cap_desc *cap_desc = NULL;
1568 DCAM_CHECK_ZERO(s_p_dcam_mod);
1570 cap_desc = &s_p_dcam_mod->dcam_cap;
1571 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1574 case DCAM_CAP_FRM_COUNT_GET:
1575 if (DCAM_CAP_IF_CSI2 == cap_desc->interface) {
1576 *(uint32_t*)param = REG_RD(CAP_MIPI_FRM_CTRL) >> 16;
1578 *(uint32_t*)param = REG_RD(CAP_CCIR_FRM_CTRL) >> 16;
1582 case DCAM_CAP_JPEG_GET_LENGTH:
1583 if (DCAM_CAP_IF_CSI2 == cap_desc->interface) {
1584 *(uint32_t*)param = REG_RD(CAP_MIPI_FRM_SIZE);
1586 *(uint32_t*)param = REG_RD(CAP_CCIR_FRM_SIZE);
1590 rtn = DCAM_RTN_IO_ID_ERR;
1596 int32_t dcam_path0_cfg(enum dcam_cfg_id id, void *param)
1598 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
1599 struct dcam_path_desc *path = NULL;
1601 DCAM_CHECK_ZERO(s_p_dcam_mod);
1602 path = &s_p_dcam_mod->dcam_path0;
1605 case DCAM_PATH_INPUT_SIZE:
1607 struct dcam_size *size = (struct dcam_size*)param;
1609 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1611 DCAM_TRACE("DCAM: DCAM_PATH0_INPUT_SIZE {%d %d} \n", size->w, size->h);
1613 if (size->w > DCAM_PATH_FRAME_WIDTH_MAX ||
1614 size->h > DCAM_PATH_FRAME_HEIGHT_MAX) {
1615 rtn = DCAM_RTN_PATH_SRC_SIZE_ERR;
1619 path->input_size.w = size->w;
1620 path->input_size.h = size->h;
1621 path->valid_param.input_size = 1;
1626 case DCAM_PATH_INPUT_RECT:
1628 struct dcam_rect *rect = (struct dcam_rect*)param;
1630 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1632 DCAM_TRACE("DCAM: DCAM_PATH0_INPUT_RECT {%d %d %d %d} \n",
1638 //if (rect->x > DCAM_PATH_FRAME_WIDTH_MAX ||
1639 //rect->y > DCAM_PATH_FRAME_HEIGHT_MAX ||
1640 //rect->w > DCAM_PATH_FRAME_WIDTH_MAX ||
1641 //rect->h > DCAM_PATH_FRAME_HEIGHT_MAX) {
1642 // rtn = DCAM_RTN_PATH_TRIM_SIZE_ERR;
1644 memcpy((void*)&path->input_rect,
1646 sizeof(struct dcam_rect));
1647 //if (path->input_rect.h >= DCAM_HEIGHT_MIN) {
1648 // path->input_rect.h--;
1650 /* path0 output size is different with other paths */
1651 path->output_size.w = rect->w;
1652 path->output_size.h = rect->h;
1653 path->valid_param.input_rect = 1;
1658 case DCAM_PATH_SRC_SEL:
1660 uint32_t src_sel = *(uint32_t*)param;
1662 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1664 if (src_sel >= DCAM_PATH_FROM_NONE) {
1665 rtn = DCAM_RTN_PATH_SRC_ERR;
1667 path->src_sel = src_sel;
1668 path->valid_param.src_sel = 1;
1673 case DCAM_PATH_OUTPUT_FORMAT:
1675 enum dcam_output_mode format = *(enum dcam_output_mode*)param;
1677 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1679 if((DCAM_OUTPUT_WORD != format) &&
1680 (DCAM_OUTPUT_HALF_WORD != format) &&
1681 (DCAM_OUTPUT_YVYU_1FRAME != format) &&
1682 (DCAM_OUTPUT_YUV420 != format)){
1683 rtn = DCAM_RTN_PATH_OUT_FMT_ERR;
1684 path->output_format = DCAM_FTM_MAX;
1686 path->output_format = format;
1687 path->valid_param.output_format = 1;
1692 case DCAM_PATH_FRAME_BASE_ID:
1694 uint32_t base_id = *(uint32_t*)param, i;
1696 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1698 DCAM_TRACE("DCAM: DCAM_PATH_FRAME_BASE_ID 0x%x \n", base_id);
1699 s_p_dcam_mod->dcam_path0.frame_base_id = base_id;
1703 case DCAM_PATH_FRAME_TYPE:
1705 struct dcam_frame *frame = &s_p_dcam_mod->dcam_path0.buf_queue.frame[0];
1706 uint32_t frm_type = *(uint32_t*)param, i;
1708 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1710 DCAM_TRACE("DCAM: DCAM_PATH_FRAME_TYPE 0x%x \n", frm_type);
1711 for (i = 0; i < DCAM_PATH_0_FRM_CNT_MAX; i++) {
1712 (frame+i)->type = frm_type;
1717 case DCAM_PATH_OUTPUT_ADDR:
1719 struct dcam_addr *p_addr = (struct dcam_addr*)param;
1721 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1722 if (DCAM_YUV_ADDR_INVALID(p_addr->yaddr, p_addr->uaddr, p_addr->vaddr)) {
1723 rtn = DCAM_RTN_PATH_ADDR_ERR;
1725 struct dcam_frame frame;
1726 memset((void*)&frame, 0, sizeof(struct dcam_frame));
1727 frame.yaddr = p_addr->yaddr;
1728 frame.uaddr = p_addr->uaddr;
1729 frame.vaddr = p_addr->vaddr;
1730 frame.yaddr_vir = p_addr->yaddr_vir;
1731 frame.uaddr_vir = p_addr->uaddr_vir;
1732 frame.vaddr_vir = p_addr->vaddr_vir;
1733 frame.type = DCAM_PATH0;
1734 frame.fid = s_p_dcam_mod->dcam_path0.frame_base_id;
1735 DCAM_TRACE("DCAM: Path 0 DCAM_PATH_OUTPUT_ADDR, i=%d, y=0x%x, u=0x%x, v=0x%x \n",
1736 path->output_frame_count, p_addr->yaddr, p_addr->uaddr, p_addr->vaddr);
1737 _dcam_buf_queue_write(&s_p_dcam_mod->dcam_path0.buf_queue, &frame);
1742 case DCAM_PATH_OUTPUT_RESERVED_ADDR:
1744 struct dcam_addr *p_addr = (struct dcam_addr*)param;
1746 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1748 if (DCAM_YUV_ADDR_INVALID(p_addr->yaddr, p_addr->uaddr, p_addr->vaddr)) {
1749 rtn = DCAM_RTN_PATH_ADDR_ERR;
1751 struct dcam_frame *frame = &s_p_dcam_mod->path0_reserved_frame;
1752 frame->yaddr = p_addr->yaddr;
1753 frame->uaddr = p_addr->uaddr;
1754 frame->vaddr = p_addr->vaddr;
1755 frame->yaddr_vir = p_addr->yaddr_vir;
1756 frame->uaddr_vir = p_addr->uaddr_vir;
1757 frame->vaddr_vir = p_addr->vaddr_vir;
1759 DCAM_TRACE("DCAM: Path 1 DCAM_PATH_OUTPUT_RESERVED_ADDR, i=%d, y=0x%x, u=0x%x, v=0x%x \n",
1760 path->output_frame_count, p_addr->yaddr, p_addr->uaddr, p_addr->vaddr);
1765 case DCAM_PATH_FRM_DECI:
1767 uint32_t deci_factor = *(uint32_t*)param;
1769 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1771 if (deci_factor >= DCAM_FRM_DECI_FAC_MAX) {
1772 rtn = DCAM_RTN_PATH_FRM_DECI_ERR;
1774 path->frame_deci = deci_factor;
1775 path->valid_param.frame_deci = 1;
1780 case DCAM_PATH_DATA_ENDIAN:
1782 struct dcam_endian_sel *endian = (struct dcam_endian_sel*)param;
1784 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1786 if (endian->y_endian >= DCAM_ENDIAN_MAX ||
1787 endian->uv_endian >= DCAM_ENDIAN_MAX) {
1788 rtn = DCAM_RTN_PATH_ENDIAN_ERR;
1790 path->data_endian.y_endian = endian->y_endian;
1791 path->data_endian.uv_endian = endian->uv_endian;
1792 path->valid_param.data_endian = 1;
1798 case DCAM_PATH_ENABLE:
1800 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1801 path->valide = *(uint32_t*)param;
1806 rtn = DCAM_RTN_IO_ID_ERR;
1813 int32_t dcam_path1_cfg(enum dcam_cfg_id id, void *param)
1815 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
1816 struct dcam_path_desc *path = NULL;
1818 DCAM_CHECK_ZERO(s_p_dcam_mod);
1819 path = &s_p_dcam_mod->dcam_path1;
1822 case DCAM_PATH_INPUT_SIZE:
1824 struct dcam_size *size = (struct dcam_size*)param;
1826 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1828 DCAM_TRACE("DCAM: DCAM_PATH1_INPUT_SIZE {%d %d} \n", size->w, size->h);
1829 if (size->w > DCAM_PATH_FRAME_WIDTH_MAX ||
1830 size->h > DCAM_PATH_FRAME_HEIGHT_MAX) {
1831 rtn = DCAM_RTN_PATH_SRC_SIZE_ERR;
1833 path->input_size.w = size->w;
1834 path->input_size.h = size->h;
1835 path->valid_param.input_size = 1;
1840 case DCAM_PATH_INPUT_RECT:
1842 struct dcam_rect *rect = (struct dcam_rect*)param;
1844 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1846 DCAM_TRACE("DCAM: DCAM_PATH1_INPUT_RECT {%d %d %d %d} \n",
1852 if (rect->x > DCAM_PATH_FRAME_WIDTH_MAX ||
1853 rect->y > DCAM_PATH_FRAME_HEIGHT_MAX ||
1854 rect->w > DCAM_PATH_FRAME_WIDTH_MAX ||
1855 rect->h > DCAM_PATH_FRAME_HEIGHT_MAX) {
1856 rtn = DCAM_RTN_PATH_TRIM_SIZE_ERR;
1858 memcpy((void*)&path->input_rect,
1860 sizeof(struct dcam_rect));
1861 //if (path->input_rect.h >= DCAM_HEIGHT_MIN) {
1862 // path->input_rect.h--;
1864 path->valid_param.input_rect = 1;
1869 case DCAM_PATH_OUTPUT_SIZE:
1871 struct dcam_size *size = (struct dcam_size*)param;
1873 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1875 DCAM_TRACE("DCAM: DCAM_PATH1_OUTPUT_SIZE {%d %d} \n", size->w, size->h);
1876 if (size->w > DCAM_PATH_FRAME_WIDTH_MAX ||
1877 size->h > DCAM_PATH_FRAME_HEIGHT_MAX) {
1878 rtn = DCAM_RTN_PATH_SRC_SIZE_ERR;
1880 path->output_size.w = size->w;
1881 path->output_size.h = size->h;
1882 path->valid_param.output_size = 1;
1887 case DCAM_PATH_OUTPUT_FORMAT:
1889 enum dcam_fmt format = *(enum dcam_fmt*)param;
1891 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1893 path->output_format = format;
1895 if((DCAM_YUV422 != format) &&
1896 (DCAM_YUV420 != format) &&
1897 (DCAM_YUV420_3FRAME != format)){
1898 rtn = DCAM_RTN_PATH_OUT_FMT_ERR;
1899 path->output_format = DCAM_FTM_MAX;
1901 path->valid_param.output_format = 1;
1906 case DCAM_PATH_OUTPUT_ADDR:
1908 struct dcam_addr *p_addr = (struct dcam_addr*)param;
1910 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1911 if (DCAM_YUV_ADDR_INVALID(p_addr->yaddr, p_addr->uaddr, p_addr->vaddr)) {
1912 rtn = DCAM_RTN_PATH_ADDR_ERR;
1914 struct dcam_frame frame;
1915 memset((void*)&frame, 0, sizeof(struct dcam_frame));
1916 frame.yaddr = p_addr->yaddr;
1917 frame.uaddr = p_addr->uaddr;
1918 frame.vaddr = p_addr->vaddr;
1919 frame.yaddr_vir = p_addr->yaddr_vir;
1920 frame.uaddr_vir = p_addr->uaddr_vir;
1921 frame.vaddr_vir = p_addr->vaddr_vir;
1922 frame.type = DCAM_PATH1;
1923 frame.fid = s_p_dcam_mod->dcam_path1.frame_base_id;
1924 DCAM_TRACE("DCAM: Path 1 DCAM_PATH_OUTPUT_ADDR, i=%d, y=0x%x, u=0x%x, v=0x%x \n",
1925 path->output_frame_count, p_addr->yaddr, p_addr->uaddr, p_addr->vaddr);
1926 _dcam_buf_queue_write(&s_p_dcam_mod->dcam_path1.buf_queue, &frame);
1931 case DCAM_PATH_OUTPUT_RESERVED_ADDR:
1933 struct dcam_addr *p_addr = (struct dcam_addr*)param;
1935 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1937 if (DCAM_YUV_ADDR_INVALID(p_addr->yaddr, p_addr->uaddr, p_addr->vaddr)) {
1938 rtn = DCAM_RTN_PATH_ADDR_ERR;
1940 struct dcam_frame *frame = &s_p_dcam_mod->path1_reserved_frame;
1941 frame->yaddr = p_addr->yaddr;
1942 frame->uaddr = p_addr->uaddr;
1943 frame->vaddr = p_addr->vaddr;
1944 frame->yaddr_vir = p_addr->yaddr_vir;
1945 frame->uaddr_vir = p_addr->uaddr_vir;
1946 frame->vaddr_vir = p_addr->vaddr_vir;
1947 DCAM_TRACE("DCAM: Path 1 DCAM_PATH_OUTPUT_RESERVED_ADDR, i=%d, y=0x%x, u=0x%x, v=0x%x \n",
1948 path->output_frame_count, p_addr->yaddr, p_addr->uaddr, p_addr->vaddr);
1953 case DCAM_PATH_SRC_SEL:
1955 uint32_t src_sel = *(uint32_t*)param;
1957 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1959 if (src_sel >= DCAM_PATH_FROM_NONE) {
1960 rtn = DCAM_RTN_PATH_SRC_ERR;
1962 path->src_sel = src_sel;
1963 path->valid_param.src_sel = 1;
1968 case DCAM_PATH_FRAME_BASE_ID:
1970 uint32_t base_id = *(uint32_t*)param, i;
1972 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1974 DCAM_TRACE("DCAM: DCAM_PATH_FRAME_BASE_ID 0x%x \n", base_id);
1975 s_p_dcam_mod->dcam_path1.frame_base_id = base_id;
1979 case DCAM_PATH_DATA_ENDIAN:
1981 struct dcam_endian_sel *endian = (struct dcam_endian_sel*)param;
1983 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1985 if (endian->y_endian >= DCAM_ENDIAN_MAX ||
1986 endian->uv_endian >= DCAM_ENDIAN_MAX) {
1987 rtn = DCAM_RTN_PATH_ENDIAN_ERR;
1989 path->data_endian.y_endian = endian->y_endian;
1990 path->data_endian.uv_endian = endian->uv_endian;
1991 path->valid_param.data_endian = 1;
1996 case DCAM_PATH_ENABLE:
1998 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1999 path->valide = *(uint32_t*)param;
2003 case DCAM_PATH_FRAME_TYPE:
2005 struct dcam_frame *frame = &s_p_dcam_mod->dcam_path1.buf_queue.frame[0];
2006 uint32_t frm_type = *(uint32_t*)param, i;
2008 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2010 DCAM_TRACE("DCAM: DCAM_PATH_FRAME_TYPE 0x%x \n", frm_type);
2011 for (i = 0; i < DCAM_PATH_1_FRM_CNT_MAX; i++) {
2012 (frame+i)->type = frm_type;
2017 case DCAM_PATH_FRM_DECI:
2019 uint32_t deci_factor = *(uint32_t*)param;
2021 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2023 if (deci_factor >= DCAM_FRM_DECI_FAC_MAX) {
2024 rtn = DCAM_RTN_PATH_FRM_DECI_ERR;
2026 path->frame_deci = deci_factor;
2027 path->valid_param.frame_deci = 1;
2039 int32_t dcam_path2_cfg(enum dcam_cfg_id id, void *param)
2041 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
2042 struct dcam_path_desc *path = NULL;
2044 DCAM_CHECK_ZERO(s_p_dcam_mod);
2045 path = &s_p_dcam_mod->dcam_path2;
2048 case DCAM_PATH_INPUT_SIZE:
2050 struct dcam_size *size = (struct dcam_size*)param;
2052 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2054 DCAM_TRACE("DCAM: DCAM_PATH2_INPUT_SIZE {%d %d} \n", size->w, size->h);
2055 if (size->w > DCAM_PATH2_FRAME_WIDTH_MAX ||
2056 size->h > DCAM_PATH2_FRAME_HEIGHT_MAX) {
2057 rtn = DCAM_RTN_PATH_SRC_SIZE_ERR;
2059 path->input_size.w = size->w;
2060 path->input_size.h = size->h;
2061 path->valid_param.input_size = 1;
2067 case DCAM_PATH_INPUT_RECT:
2069 struct dcam_rect *rect = (struct dcam_rect*)param;
2071 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2073 DCAM_TRACE("DCAM: DCAM_PATH2_INPUT_RECT {%d %d %d %d} \n",
2079 if (rect->x > DCAM_PATH2_FRAME_WIDTH_MAX ||
2080 rect->y > DCAM_PATH2_FRAME_HEIGHT_MAX ||
2081 rect->w > DCAM_PATH2_FRAME_WIDTH_MAX ||
2082 rect->h > DCAM_PATH2_FRAME_HEIGHT_MAX) {
2083 rtn = DCAM_RTN_PATH_TRIM_SIZE_ERR;
2085 memcpy((void*)&path->input_rect,
2087 sizeof(struct dcam_rect));
2089 if (path->input_rect.h >= DCAM_HEIGHT_MIN) {
2090 path->input_rect.h--;
2093 path->valid_param.input_rect = 1;
2098 case DCAM_PATH_OUTPUT_SIZE:
2100 struct dcam_size *size = (struct dcam_size*)param;
2102 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2104 DCAM_TRACE("DCAM: DCAM_PATH2_OUTPUT_SIZE {%d %d} \n", size->w, size->h);
2105 if (size->w > DCAM_PATH2_FRAME_WIDTH_MAX ||
2106 size->h > DCAM_PATH2_FRAME_HEIGHT_MAX) {
2107 rtn = DCAM_RTN_PATH_SRC_SIZE_ERR;
2109 path->output_size.w = size->w;
2110 path->output_size.h = size->h;
2111 path->valid_param.output_size = 1;
2116 case DCAM_PATH_OUTPUT_FORMAT:
2118 enum dcam_fmt format = *(enum dcam_fmt*)param;
2120 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2122 if((DCAM_YUV422 != format) &&
2123 (DCAM_YUV420 != format) &&
2124 (DCAM_YUV420_3FRAME != format)){
2125 rtn = DCAM_RTN_PATH_OUT_FMT_ERR;
2126 path->output_format = DCAM_FTM_MAX;
2128 path->output_format = format;
2129 path->valid_param.output_format = 1;
2134 case DCAM_PATH_OUTPUT_ADDR:
2136 struct dcam_addr *p_addr = (struct dcam_addr*)param;
2138 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2139 if (DCAM_YUV_ADDR_INVALID(p_addr->yaddr, p_addr->uaddr, p_addr->vaddr)) {
2140 rtn = DCAM_RTN_PATH_ADDR_ERR;
2142 struct dcam_frame frame;
2143 memset((void*)&frame, 0, sizeof(struct dcam_frame));
2144 frame.yaddr = p_addr->yaddr;
2145 frame.uaddr = p_addr->uaddr;
2146 frame.vaddr = p_addr->vaddr;
2147 frame.yaddr_vir = p_addr->yaddr_vir;
2148 frame.uaddr_vir = p_addr->uaddr_vir;
2149 frame.vaddr_vir = p_addr->vaddr_vir;
2150 frame.type = DCAM_PATH2;
2151 frame.fid = s_p_dcam_mod->dcam_path2.frame_base_id;
2152 DCAM_TRACE("DCAM: Path 2 DCAM_PATH_OUTPUT_ADDR, i=%d, y=0x%x, u=0x%x, v=0x%x \n",
2153 path->output_frame_count, p_addr->yaddr, p_addr->uaddr, p_addr->vaddr);
2154 _dcam_buf_queue_write(&s_p_dcam_mod->dcam_path2.buf_queue, &frame);
2159 case DCAM_PATH_OUTPUT_RESERVED_ADDR:
2161 struct dcam_addr *p_addr = (struct dcam_addr*)param;
2163 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2165 if (DCAM_YUV_ADDR_INVALID(p_addr->yaddr, p_addr->uaddr, p_addr->vaddr)) {
2166 rtn = DCAM_RTN_PATH_ADDR_ERR;
2168 struct dcam_frame *frame = &s_p_dcam_mod->path2_reserved_frame;
2169 frame->yaddr = p_addr->yaddr;
2170 frame->uaddr = p_addr->uaddr;
2171 frame->vaddr = p_addr->vaddr;
2172 frame->yaddr_vir = p_addr->yaddr_vir;
2173 frame->uaddr_vir = p_addr->uaddr_vir;
2174 frame->vaddr_vir = p_addr->vaddr_vir;
2175 DCAM_TRACE("DCAM: Path 1 DCAM_PATH_OUTPUT_RESERVED_ADDR, i=%d, y=0x%x, u=0x%x, v=0x%x \n",
2176 path->output_frame_count, p_addr->yaddr, p_addr->uaddr, p_addr->vaddr);
2181 case DCAM_PATH_SRC_SEL:
2183 uint32_t src_sel = *(uint32_t*)param;
2185 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2187 if (src_sel >= DCAM_PATH_FROM_NONE) {
2188 rtn = DCAM_RTN_PATH_SRC_ERR;
2190 path->src_sel = src_sel;
2191 path->valid_param.src_sel = 1;
2197 case DCAM_PATH_FRAME_BASE_ID:
2199 uint32_t base_id = *(uint32_t*)param, i;
2201 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2203 DCAM_TRACE("DCAM: DCAM_PATH_FRAME_BASE_ID 0x%x \n", base_id);
2204 s_p_dcam_mod->dcam_path2.frame_base_id = base_id;
2208 case DCAM_PATH_DATA_ENDIAN:
2210 struct dcam_endian_sel *endian = (struct dcam_endian_sel*)param;
2212 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2214 if (endian->y_endian >= DCAM_ENDIAN_MAX ||
2215 endian->uv_endian >= DCAM_ENDIAN_MAX) {
2216 rtn = DCAM_RTN_PATH_ENDIAN_ERR;
2218 path->data_endian.y_endian = endian->y_endian;
2219 path->data_endian.uv_endian = endian->uv_endian;
2220 path->valid_param.data_endian = 1;
2225 case DCAM_PATH_ENABLE:
2227 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2229 path->valide = *(uint32_t*)param;
2234 case DCAM_PATH_FRAME_TYPE:
2236 struct dcam_frame *frame = &s_p_dcam_mod->dcam_path2.buf_queue.frame[0];
2237 uint32_t frm_type = *(uint32_t*)param, i;
2239 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2241 DCAM_TRACE("DCAM: DCAM_PATH_FRAME_TYPE 0x%x \n", frm_type);
2242 for (i = 0; i < DCAM_PATH_2_FRM_CNT_MAX; i++) {
2243 (frame+i)->type = frm_type;
2248 case DCAM_PATH_FRM_DECI:
2250 uint32_t deci_factor = *(uint32_t*)param;
2252 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2254 if (deci_factor >= DCAM_FRM_DECI_FAC_MAX) {
2255 rtn = DCAM_RTN_PATH_FRM_DECI_ERR;
2257 path->frame_deci = deci_factor;
2258 path->valid_param.frame_deci = 1;
2270 int32_t dcam_get_resizer(uint32_t wait_opt)
2274 printk("resizer_get:%d\n",current->pid);
2277 if( 0 == wait_opt) {
2278 rtn = mutex_trylock(&dcam_sem) ? 0 : 1;
2280 } else if (DCAM_WAIT_FOREVER == wait_opt){
2281 mutex_lock(&dcam_sem);
2284 return 0;//mutex_timeout(&dcam_sem, wait_opt);
2288 int32_t dcam_rel_resizer(void)
2290 printk("resizer_put:%d\n",current->pid);
2291 mutex_unlock(&dcam_sem);
2295 int32_t dcam_resize_start(void)
2297 atomic_inc(&s_resize_flag);
2298 mutex_lock(&dcam_scale_sema);
2302 int32_t dcam_resize_end(void)
2306 atomic_dec(&s_resize_flag);
2307 mutex_unlock(&dcam_scale_sema);
2309 spin_lock_irqsave(&dcam_mod_lock, flag);
2310 if (DCAM_ADDR_INVALID(s_p_dcam_mod)) {
2311 spin_unlock_irqrestore(&dcam_mod_lock, flag);
2316 if (s_p_dcam_mod->wait_resize_done) {
2317 up(&s_p_dcam_mod->resize_done_sema);
2318 s_p_dcam_mod->wait_resize_done = 0;
2321 spin_unlock_irqrestore(&dcam_mod_lock, flag);
2325 int32_t dcam_rotation_start(void)
2327 atomic_inc(&s_rotation_flag);
2328 mutex_lock(&dcam_rot_sema);
2332 int32_t dcam_rotation_end(void)
2336 atomic_dec(&s_rotation_flag);
2337 mutex_unlock(&dcam_rot_sema);
2339 spin_lock_irqsave(&dcam_mod_lock, flag);
2340 if (DCAM_ADDR_INVALID(s_p_dcam_mod)) {
2341 spin_unlock_irqrestore(&dcam_mod_lock, flag);
2346 if (s_p_dcam_mod->wait_rotation_done) {
2347 up(&s_p_dcam_mod->rotation_done_sema);
2348 s_p_dcam_mod->wait_rotation_done = 0;
2351 spin_unlock_irqrestore(&dcam_mod_lock, flag);
2355 void dcam_int_en(void)
2357 if (atomic_read(&s_dcam_users) == 1) {
2358 enable_irq(DCAM_IRQ);
2362 void dcam_int_dis(void)
2364 if (atomic_read(&s_dcam_users) == 1) {
2365 disable_irq(DCAM_IRQ);
2369 int32_t dcam_frame_is_locked(struct dcam_frame *frame)
2372 unsigned long flags;
2375 local_irq_save(flags);
2377 rtn = frame->lock == DCAM_FRM_LOCK_WRITE ? 1 : 0;
2378 local_irq_restore(flags);
2384 int32_t dcam_frame_lock(struct dcam_frame *frame)
2388 DCAM_CHECK_ZERO(s_p_dcam_mod);
2390 DCAM_TRACE("DCAM: lock %d \n", (uint32_t)(0xF&frame->fid));
2393 frame->lock = DCAM_FRM_LOCK_WRITE;
2395 rtn = DCAM_RTN_PARA_ERR;
2400 int32_t dcam_frame_unlock(struct dcam_frame *frame)
2403 unsigned long flags;
2405 DCAM_CHECK_ZERO(s_p_dcam_mod);
2407 DCAM_TRACE("DCAM: unlock %d \n", (uint32_t)(0xF&frame->fid));
2410 spin_lock_irqsave(&dcam_lock, flags);
2412 frame->lock = DCAM_FRM_UNLOCK;
2414 rtn = DCAM_RTN_PARA_ERR;
2415 spin_unlock_irqrestore(&dcam_lock, flags);
2421 int32_t dcam_read_registers(uint32_t* reg_buf, uint32_t *buf_len)
2423 uint32_t *reg_addr = (uint32_t*)DCAM_BASE;
2425 if (NULL == reg_buf || NULL == buf_len || 0 != (*buf_len % 4)) {
2429 while (buf_len != 0 && (unsigned long)reg_addr < DCAM_END) {
2430 *reg_buf++ = REG_RD(reg_addr);
2435 *buf_len = (unsigned long)reg_addr - DCAM_BASE;
2439 int32_t dcam_get_path_id(struct dcam_get_path_id *path_id, uint32_t *channel_id)
2441 int ret = DCAM_RTN_SUCCESS;
2443 if (NULL == path_id || NULL == channel_id) {
2447 DCAM_TRACE("DCAM: fourcc 0x%x, w %d, h %d \n", path_id->fourcc, path_id->input_size.w, path_id->input_size.h);
2449 if (path_id->need_isp_tool) {
2450 *channel_id = DCAM_PATH0;
2451 } else if (V4L2_PIX_FMT_GREY == path_id->fourcc && !path_id->is_path_work[DCAM_PATH0]) {
2452 *channel_id = DCAM_PATH0;
2453 } else if (V4L2_PIX_FMT_JPEG == path_id->fourcc && !path_id->is_path_work[DCAM_PATH0]) {
2454 *channel_id = DCAM_PATH0;
2455 /*} else if (path_id->output_size.w == path_id->input_size.w && path_id->output_size.h == path_id->input_size.h) {
2456 *channel_id = DCAM_PATH0;*/
2457 } else if (path_id->output_size.w <= DCAM_PATH1_LINE_BUF_LENGTH && !path_id->is_path_work[DCAM_PATH1]) {
2458 *channel_id = DCAM_PATH1;
2459 } else if (path_id->output_size.w <= DCAM_PATH2_LINE_BUF_LENGTH && !path_id->is_path_work[DCAM_PATH2]) {
2460 *channel_id = DCAM_PATH2;
2462 *channel_id = DCAM_PATH0;
2464 printk("DCAM: path id %d \n", *channel_id);
2469 int32_t dcam_get_path_capability(struct dcam_path_capability *capacity)
2471 int ret = DCAM_RTN_SUCCESS;
2473 if (NULL == capacity) {
2477 capacity->count = 3;
2478 capacity->path_info[DCAM_PATH0].line_buf = 0;
2479 capacity->path_info[DCAM_PATH0].support_yuv = 0;
2480 capacity->path_info[DCAM_PATH0].support_raw = 1;
2481 capacity->path_info[DCAM_PATH0].support_jpeg = 1;
2482 capacity->path_info[DCAM_PATH0].support_scaling = 0;
2483 capacity->path_info[DCAM_PATH0].support_trim = 0;
2484 capacity->path_info[DCAM_PATH0].is_scaleing_path = 0;
2486 capacity->path_info[DCAM_PATH1].line_buf = DCAM_PATH1_LINE_BUF_LENGTH;
2487 capacity->path_info[DCAM_PATH1].support_yuv = 1;
2488 capacity->path_info[DCAM_PATH1].support_raw = 0;
2489 capacity->path_info[DCAM_PATH1].support_jpeg = 0;
2490 capacity->path_info[DCAM_PATH1].support_scaling = 1;
2491 capacity->path_info[DCAM_PATH1].support_trim = 1;
2492 capacity->path_info[DCAM_PATH1].is_scaleing_path = 0;
2494 capacity->path_info[DCAM_PATH2].line_buf = DCAM_PATH2_LINE_BUF_LENGTH;
2495 capacity->path_info[DCAM_PATH2].support_yuv = 1;
2496 capacity->path_info[DCAM_PATH2].support_raw = 0;
2497 capacity->path_info[DCAM_PATH2].support_jpeg = 0;
2498 capacity->path_info[DCAM_PATH2].support_scaling = 1;
2499 capacity->path_info[DCAM_PATH2].support_trim = 1;
2500 capacity->path_info[DCAM_PATH2].is_scaleing_path = 1;
2506 LOCAL irqreturn_t _dcam_isr_root(int irq, void *dev_id)
2508 uint32_t irq_line, status;
2512 DCAM_TRACE("DCAM: ISR 0x%x \n", REG_RD(DCAM_INT_STS));
2513 status = REG_RD(DCAM_INT_STS) & DCAM_IRQ_LINE_MASK;
2514 if (unlikely(0 == status)) {
2519 if (unlikely(DCAM_IRQ_ERR_MASK & status)) {
2520 if (_dcam_err_pre_proc()) {
2525 spin_lock_irqsave(&dcam_lock,flag);
2527 //for (i = DCAM_IRQ_NUMBER - 1; i >= 0; i--) {
2528 for (i = 0; i < DCAM_IRQ_NUMBER; i++) {
2529 if (irq_line & (1 << (uint32_t)i)) {
2534 irq_line &= ~(uint32_t)(1 << (uint32_t)i); //clear the interrupt flag
2535 if(!irq_line) //no interrupt source left
2539 REG_WR(DCAM_INT_CLR, status);
2540 DCAM_TRACE("DCAM: status 0x%x, ISR 0x%x \n", status, REG_RD(DCAM_INT_STS));
2542 spin_unlock_irqrestore(&dcam_lock, flag);
2547 LOCAL void _dcam_path0_set(void)
2549 uint32_t reg_val = 0;
2550 struct dcam_path_desc *path = NULL;
2552 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
2553 path = &s_p_dcam_mod->dcam_path0;
2554 if (path->valid_param.input_size) {
2555 reg_val = path->input_size.w | (path->input_size.h << 16);
2556 REG_WR(DCAM_PATH0_SRC_SIZE, reg_val);
2559 if (path->valid_param.input_rect) {
2560 reg_val = path->input_rect.x | (path->input_rect.y << 16);
2561 REG_WR(DCAM_PATH0_TRIM_START, reg_val);
2562 reg_val = path->input_rect.w | (path->input_rect.h << 16);
2563 REG_WR(DCAM_PATH0_TRIM_SIZE, reg_val);
2564 DCAM_TRACE("DCAM: path0 set: rect {%d %d %d %d} \n",
2568 path->input_rect.h);
2571 if (path->valid_param.src_sel) {
2572 REG_MWR(DCAM_CFG, BIT_10 , path->src_sel << 10);
2573 DCAM_TRACE("DCAM: path 0: src_sel=0x%x \n", path->src_sel);
2576 if (path->valid_param.frame_deci) {
2577 REG_MWR(DCAM_PATH0_CFG, BIT_1 | BIT_0, path->frame_deci << 0);
2580 if (path->valid_param.output_format) {
2581 enum dcam_output_mode format = path->output_format;
2582 REG_MWR(DCAM_PATH0_CFG, BIT_2 | BIT_3, format << 2);
2583 DCAM_TRACE("DCAM: path 0: output_format=0x%x \n", format);
2586 if (path->valid_param.data_endian) {
2587 dcam_glb_reg_mwr(DCAM_ENDIAN_SEL, BIT_5 | BIT_4, path->data_endian.y_endian << 4, DCAM_ENDIAN_REG);
2588 if (DCAM_ENDIAN_BIG == path->data_endian.y_endian) {
2589 if (DCAM_ENDIAN_LITTLE == path->data_endian.uv_endian ||
2590 DCAM_ENDIAN_HALFBIG == path->data_endian.uv_endian) {
2591 dcam_glb_reg_mwr(DCAM_ENDIAN_SEL, BIT_20, 1 << 20, DCAM_ENDIAN_REG);
2593 dcam_glb_reg_mwr(DCAM_ENDIAN_SEL, BIT_20, 0, DCAM_ENDIAN_REG);
2595 } else if (DCAM_ENDIAN_LITTLE == path->data_endian.y_endian) {
2596 if (DCAM_ENDIAN_BIG == path->data_endian.uv_endian ||
2597 DCAM_ENDIAN_HALFBIG == path->data_endian.uv_endian) {
2598 dcam_glb_reg_mwr(DCAM_ENDIAN_SEL, BIT_20, 1 << 20, DCAM_ENDIAN_REG);
2600 dcam_glb_reg_mwr(DCAM_ENDIAN_SEL, BIT_20, 0, DCAM_ENDIAN_REG);
2603 printk("DCAM DRV: endian, do nothing u %d, v %d \n",
2604 path->data_endian.y_endian,
2605 path->data_endian.uv_endian);
2608 dcam_glb_reg_mwr(DCAM_ENDIAN_SEL, BIT_18, BIT_18, DCAM_ENDIAN_REG); // axi write
2609 dcam_glb_reg_mwr(DCAM_ENDIAN_SEL, BIT_19, BIT_19, DCAM_ENDIAN_REG); // axi read
2610 DCAM_TRACE("DCAM DRV: path 0: data_endian y=0x%x, uv=0x%x \n",
2611 path->data_endian.y_endian, path->data_endian.uv_endian);
2616 LOCAL void _dcam_path1_set(struct dcam_path_desc *path)
2618 uint32_t reg_val = 0;
2620 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
2621 DCAM_CHECK_ZERO_VOID(path);
2623 if (path->valid_param.input_size) {
2624 reg_val = path->input_size.w | (path->input_size.h << 16);
2625 REG_WR(DCAM_PATH1_SRC_SIZE, reg_val);
2626 DCAM_TRACE("DCAM: path1 set: src {%d %d} \n",path->input_size.w, path->input_size.h);
2629 if (path->valid_param.input_rect) {
2630 reg_val = path->input_rect.x | (path->input_rect.y << 16);
2631 REG_WR(DCAM_PATH1_TRIM_START, reg_val);
2632 reg_val = path->input_rect.w | (path->input_rect.h << 16);
2633 REG_WR(DCAM_PATH1_TRIM_SIZE, reg_val);
2634 DCAM_TRACE("DCAM: path1 set: rect {%d %d %d %d} \n",
2638 path->input_rect.h);
2641 if (path->valid_param.output_size) {
2642 reg_val = path->output_size.w | (path->output_size.h << 16);
2643 REG_WR(DCAM_PATH1_DST_SIZE, reg_val);
2644 DCAM_TRACE("DCAM: path1 set: dst {%d %d} \n",path->output_size.w, path->output_size.h);
2647 if (path->valid_param.output_format) {
2648 enum dcam_fmt format = path->output_format;
2649 if (DCAM_YUV422 == format) {
2650 REG_MWR(DCAM_PATH1_CFG, BIT_7 | BIT_6, 0 << 6);
2651 } else if (DCAM_YUV420 == format) {
2652 REG_MWR(DCAM_PATH1_CFG, BIT_7 | BIT_6, 1 << 6);
2653 } else if (DCAM_YUV420_3FRAME == format) {
2654 REG_MWR(DCAM_PATH1_CFG, BIT_7 | BIT_6, 3 << 6);
2656 DCAM_TRACE("DCAM: invalid path 1 output format %d \n", format);
2658 DCAM_TRACE("DCAM: path 1: output_format=0x%x \n", format);
2661 if (path->valid_param.src_sel) {
2662 REG_MWR(DCAM_CFG, BIT_12 | BIT_11, path->src_sel << 11);
2663 DCAM_TRACE("DCAM: path 1: src_sel=0x%x \n", path->src_sel);
2666 if (path->valid_param.data_endian) {
2667 dcam_glb_reg_mwr(DCAM_ENDIAN_SEL, BIT_7 | BIT_6, path->data_endian.y_endian << 6, DCAM_ENDIAN_REG);
2668 dcam_glb_reg_mwr(DCAM_ENDIAN_SEL, BIT_9 | BIT_8, path->data_endian.uv_endian << 8, DCAM_ENDIAN_REG);
2669 dcam_glb_reg_mwr(DCAM_ENDIAN_SEL, BIT_18, BIT_18, DCAM_ENDIAN_REG); // axi write
2670 dcam_glb_reg_mwr(DCAM_ENDIAN_SEL, BIT_19, BIT_19, DCAM_ENDIAN_REG); // axi read
2671 DCAM_TRACE("DCAM: path 1: data_endian y=0x%x, uv=0x%x \n",
2672 path->data_endian.y_endian, path->data_endian.uv_endian);
2675 if (path->valid_param.frame_deci) {
2676 REG_MWR(DCAM_PATH0_CFG, BIT_24 | BIT_23, path->frame_deci << 23);
2677 DCAM_TRACE("DCAM: path 1: frame_deci=0x%x \n", path->frame_deci);
2680 if (path->valid_param.scale_tap) {
2681 path->valid_param.scale_tap = 0;
2682 REG_MWR(DCAM_PATH1_CFG, BIT_19 | BIT_18 | BIT_17 | BIT_16, (path->scale_tap.y_tap & 0x0F) << 16);
2683 REG_MWR(DCAM_PATH1_CFG, BIT_15 | BIT_14 | BIT_13 | BIT_12 | BIT_11, (path->scale_tap.uv_tap & 0x1F) << 11);
2684 DCAM_TRACE("DCAM: path 1: scale_tap, y=0x%x, uv=0x%x \n", path->scale_tap.y_tap, path->scale_tap.uv_tap);
2687 if (path->valid_param.v_deci) {
2688 path->valid_param.v_deci = 0;
2689 REG_MWR(DCAM_PATH1_CFG, BIT_2, path->deci_val.deci_x_en << 2);
2690 REG_MWR(DCAM_PATH1_CFG, BIT_1 | BIT_0, path->deci_val.deci_x);
2692 REG_MWR(DCAM_PATH1_CFG, BIT_5, path->deci_val.deci_y_en << 5);
2693 REG_MWR(DCAM_PATH1_CFG, BIT_4 | BIT_3, path->deci_val.deci_y << 3);
2694 DCAM_TRACE("DCAM: path 1: deci, x_en=%d, x=%d, y_en=%d, y=%d \n",
2695 path->deci_val.deci_x_en, path->deci_val.deci_x, path->deci_val.deci_y_en, path->deci_val.deci_y);
2699 LOCAL void _dcam_path2_set(void)
2701 struct dcam_path_desc *path = NULL;
2702 uint32_t reg_val = 0;
2704 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
2705 path = &s_p_dcam_mod->dcam_path2;
2706 if (path->valid_param.input_size) {
2707 reg_val = path->input_size.w | (path->input_size.h << 16);
2708 REG_WR(DCAM_PATH2_SRC_SIZE, reg_val);
2709 DCAM_TRACE("DCAM: path2 set: src {%d %d} \n",path->input_size.w, path->input_size.h);
2712 if (path->valid_param.input_rect) {
2713 reg_val = path->input_rect.x | (path->input_rect.y << 16);
2714 REG_WR(DCAM_PATH2_TRIM_START, reg_val);
2715 reg_val = path->input_rect.w | (path->input_rect.h << 16);
2716 REG_WR(DCAM_PATH2_TRIM_SIZE, reg_val);
2717 DCAM_TRACE("DCAM: path2 set: rect {%d %d %d %d} \n",
2721 path->input_rect.h);
2724 if(path->valid_param.output_size){
2725 reg_val = path->output_size.w | (path->output_size.h << 16);
2726 REG_WR(DCAM_PATH2_DST_SIZE, reg_val);
2727 DCAM_TRACE("DCAM: path2 set: dst {%d %d} \n",path->output_size.w, path->output_size.h);
2730 if (path->valid_param.output_format) {
2731 enum dcam_fmt format = path->output_format;
2733 // REG_MWR(DCAM_PATH2_CFG, BIT_8, 0 << 8); // aiden todo
2735 if (DCAM_YUV422 == format) {
2736 REG_MWR(DCAM_PATH2_CFG, BIT_7 | BIT_6, 0 << 6);
2737 } else if (DCAM_YUV420 == format) {
2738 REG_MWR(DCAM_PATH2_CFG, BIT_7 | BIT_6, 1 << 6);
2739 } else if (DCAM_YUV420_3FRAME == format) {
2740 REG_MWR(DCAM_PATH2_CFG, BIT_7 | BIT_6, 3 << 6);
2742 DCAM_TRACE("DCAM: invalid path 2 output format %d \n", format);
2744 DCAM_TRACE("DCAM: path 2: output_format=0x%x \n", format);
2747 if (path->valid_param.src_sel) {
2748 REG_MWR(DCAM_CFG, BIT_14 | BIT_13, path->src_sel << 13);
2751 if (path->valid_param.data_endian) {
2752 dcam_glb_reg_mwr(DCAM_ENDIAN_SEL, BIT_11 | BIT_10, path->data_endian.y_endian << 10,DCAM_ENDIAN_REG );
2753 dcam_glb_reg_mwr(DCAM_ENDIAN_SEL, BIT_13 | BIT_12, path->data_endian.uv_endian << 12, DCAM_ENDIAN_REG);
2754 dcam_glb_reg_mwr(DCAM_ENDIAN_SEL, BIT_18, BIT_18, DCAM_ENDIAN_REG); // axi write
2755 dcam_glb_reg_mwr(DCAM_ENDIAN_SEL, BIT_19, BIT_19, DCAM_ENDIAN_REG); // axi read
2756 DCAM_TRACE("DCAM: path 2: data_endian y=0x%x, uv=0x%x \n",
2757 path->data_endian.y_endian, path->data_endian.uv_endian);
2760 if (path->valid_param.frame_deci) {
2761 REG_MWR(DCAM_PATH0_CFG, BIT_24 | BIT_23, path->frame_deci << 23);
2762 DCAM_TRACE("DCAM: path 2: frame_deci=0x%x \n", path->frame_deci);
2765 if (path->valid_param.scale_tap) {
2766 path->valid_param.scale_tap = 0;
2767 REG_MWR(DCAM_PATH2_CFG, BIT_19 | BIT_18 | BIT_17 | BIT_16, (path->scale_tap.y_tap & 0x0F) << 16);
2768 REG_MWR(DCAM_PATH2_CFG, BIT_15 | BIT_14 | BIT_13 | BIT_12 | BIT_11, (path->scale_tap.uv_tap & 0x1F) << 11);
2769 DCAM_TRACE("DCAM: path 2: scale_tap, y=0x%x, uv=0x%x \n",
2770 path->scale_tap.y_tap, path->scale_tap.uv_tap);
2773 if (path->valid_param.v_deci) {
2774 path->valid_param.v_deci = 0;
2775 REG_MWR(DCAM_PATH2_CFG, BIT_2, path->deci_val.deci_x_en << 2);
2776 REG_MWR(DCAM_PATH2_CFG, BIT_1 | BIT_0, path->deci_val.deci_x);
2778 REG_MWR(DCAM_PATH2_CFG, BIT_5, path->deci_val.deci_y_en << 5);
2779 REG_MWR(DCAM_PATH2_CFG, BIT_4 | BIT_3, path->deci_val.deci_y << 3);
2780 DCAM_TRACE("DCAM: path 2: deci, x_en=%d, x=%d, y_en=%d, y=%d \n",
2781 path->deci_val.deci_x_en, path->deci_val.deci_x, path->deci_val.deci_y_en, path->deci_val.deci_y);
2785 LOCAL void _dcam_buf_queue_init(struct dcam_buf_queue *queue)
2787 if (DCAM_ADDR_INVALID(queue)) {
2788 printk("DCAM: invalid heap %p \n", queue);
2792 memset((void*)queue, 0, sizeof(struct dcam_buf_queue));
2793 queue->write = &queue->frame[0];
2794 queue->read = &queue->frame[0];
2795 spin_lock_init(&queue->lock);
2799 LOCAL int32_t _dcam_buf_queue_write(struct dcam_buf_queue *queue, struct dcam_frame *frame)
2801 int ret = DCAM_RTN_SUCCESS;
2802 struct dcam_frame *ori_frame;
2805 if (DCAM_ADDR_INVALID(queue) || DCAM_ADDR_INVALID(frame)) {
2806 printk("DCAM: enq, invalid param %p, %p \n",
2812 spin_lock_irqsave(&queue->lock, flag);
2813 ori_frame = queue->write;
2814 DCAM_TRACE("DCAM: _dcam_buf_queue_write \n");
2815 *queue->write++ = *frame;
2816 if (queue->write > &queue->frame[DCAM_FRM_CNT_MAX-1]) {
2817 queue->write = &queue->frame[0];
2820 if (queue->write == queue->read) {
2821 queue->write = ori_frame;
2822 printk("DCAM: warning, queue is full, cannot write 0x%lx \n", frame->yaddr);
2824 spin_unlock_irqrestore(&queue->lock, flag);
2826 DCAM_TRACE("DCAM: _dcam_buf_queue_write type %d \n", frame->type);
2830 LOCAL int32_t _dcam_buf_queue_read(struct dcam_buf_queue *queue, struct dcam_frame *frame)
2832 int ret = DCAM_RTN_SUCCESS;
2835 if (DCAM_ADDR_INVALID(queue) || DCAM_ADDR_INVALID(frame)) {
2836 printk("DCAM: deq, invalid param %p, %p \n",
2842 DCAM_TRACE("DCAM: _dcam_buf_queue_read \n");
2844 spin_lock_irqsave(&queue->lock, flag);
2845 if (queue->read != queue->write) {
2846 *frame = *queue->read++;
2847 if (queue->read > &queue->frame[DCAM_FRM_CNT_MAX-1]) {
2848 queue->read = &queue->frame[0];
2853 spin_unlock_irqrestore(&queue->lock, flag);
2855 DCAM_TRACE("DCAM: _dcam_buf_queue_read type %d \n", frame->type);
2859 LOCAL void _dcam_frm_queue_clear(struct dcam_frm_queue *queue)
2861 if (DCAM_ADDR_INVALID(queue)) {
2862 printk("DCAM: invalid heap %p \n", queue);
2866 memset((void*)queue, 0, sizeof(struct dcam_frm_queue));
2870 LOCAL int32_t _dcam_frame_enqueue(struct dcam_frm_queue *queue, struct dcam_frame *frame)
2872 if (DCAM_ADDR_INVALID(queue) || DCAM_ADDR_INVALID(frame)) {
2873 printk("DCAM: enq, invalid param %p, %p \n",
2878 if (queue->valid_cnt >= DCAM_FRM_QUEUE_LENGTH) {
2879 printk("DCAM: q over flow \n");
2882 //queue->frm_array[queue->valid_cnt] = frame;
2883 memcpy(&queue->frm_array[queue->valid_cnt], frame, sizeof(struct dcam_frame));
2884 queue->valid_cnt ++;
2885 DCAM_TRACE("DCAM: en queue, %d, %d, 0x%x, 0x%x \n",
2893 LOCAL int32_t _dcam_frame_dequeue(struct dcam_frm_queue *queue, struct dcam_frame *frame)
2897 if (DCAM_ADDR_INVALID(queue) || DCAM_ADDR_INVALID(frame)) {
2898 printk("DCAM: deq, invalid param %p, %p \n",
2903 if (queue->valid_cnt == 0) {
2904 printk("DCAM: q under flow \n");
2908 //*frame = queue->frm_array[0];
2909 memcpy(frame, &queue->frm_array[0], sizeof(struct dcam_frame));
2911 for (i = 0; i < queue->valid_cnt; i++) {
2912 //queue->frm_array[i] = queue->frm_array[i+1];
2913 memcpy(&queue->frm_array[i], &queue->frm_array[i+1], sizeof(struct dcam_frame));
2915 DCAM_TRACE("DCAM: de queue, %d, %d \n",
2916 (0xF & (frame)->fid),
2921 LOCAL void _dcam_frm_clear(enum dcam_path_index path_index)
2925 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
2927 if (DCAM_PATH_IDX_0 & path_index) {
2928 _dcam_frm_queue_clear(&s_p_dcam_mod->dcam_path0.frame_queue);
2929 _dcam_buf_queue_init(&s_p_dcam_mod->dcam_path0.buf_queue);
2932 if (DCAM_PATH_IDX_1 & path_index) {
2933 _dcam_frm_queue_clear(&s_p_dcam_mod->dcam_path1.frame_queue);
2934 _dcam_buf_queue_init(&s_p_dcam_mod->dcam_path1.buf_queue);
2937 if (DCAM_PATH_IDX_2 & path_index) {
2938 _dcam_frm_queue_clear(&s_p_dcam_mod->dcam_path2.frame_queue);
2939 _dcam_buf_queue_init(&s_p_dcam_mod->dcam_path2.buf_queue);
2945 LOCAL void _dcam_frm_pop(enum dcam_path_index path_index)
2948 struct dcam_frame *frame = NULL;
2949 uint32_t *frame_count;
2951 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
2953 if (DCAM_PATH_IDX_0 & path_index) {
2954 frame = &s_p_dcam_mod->path0_frame[0];
2955 frame_count = &s_p_dcam_mod->dcam_path0.output_frame_count;
2957 if (DCAM_PATH_IDX_1 & path_index) {
2958 frame = &s_p_dcam_mod->path1_frame[0];
2959 frame_count = &s_p_dcam_mod->dcam_path1.output_frame_count;
2961 if (DCAM_PATH_IDX_2 & path_index) {
2962 frame = &s_p_dcam_mod->path2_frame[0];
2963 frame_count = &s_p_dcam_mod->dcam_path2.output_frame_count;
2965 printk("DCAM: frame pop index %d frame_count %d addr 0x%x \n", path_index, *frame_count, frame->yaddr);
2966 if (0 == *frame_count) {
2970 for (i = 0; i < *frame_count - 1; i++) {
2971 memcpy(frame+i, frame+i+1, sizeof(struct dcam_frame));
2974 //memset(frame+(*frame_count), 0, sizeof(struct dcam_frame));
2975 (frame+(*frame_count))->yaddr = 0;
2976 (frame+(*frame_count))->uaddr = 0;
2977 (frame+(*frame_count))->vaddr = 0;
2979 if (0 == *frame_count) {
2980 //_dcam_wait_for_quickstop(path_index);
2982 DCAM_TRACE("DCAM: frame pop done \n");
2988 LOCAL void _dcam_link_frm(uint32_t base_id)
2991 struct dcam_frame *path0_frame = NULL;
2992 struct dcam_frame *path1_frame = NULL;
2993 struct dcam_frame *path2_frame = NULL;
2995 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
2997 path0_frame = &s_p_dcam_mod->path0_frame[0];
2998 path1_frame = &s_p_dcam_mod->path1_frame[0];
2999 path2_frame = &s_p_dcam_mod->path2_frame[0];
3000 for (i = 0; i < DCAM_PATH_0_FRM_CNT_MAX; i++) {
3001 DCAM_CLEAR(path0_frame + i);
3002 //(path0_frame+i)->next = path0_frame + (i + 1) % DCAM_PATH_0_FRM_CNT_MAX;
3003 //(path0_frame+i)->prev = path0_frame + (i - 1 + DCAM_PATH_0_FRM_CNT_MAX) % DCAM_PATH_0_FRM_CNT_MAX;
3004 (path0_frame+i)->fid = base_id + i;
3007 for (i = 0; i < DCAM_PATH_1_FRM_CNT_MAX; i++) {
3008 DCAM_CLEAR(path1_frame + i);
3009 //(path1_frame+i)->next = path1_frame + (i + 1) % DCAM_PATH_1_FRM_CNT_MAX;
3010 //(path1_frame+i)->prev = path1_frame + (i - 1 + DCAM_PATH_1_FRM_CNT_MAX) % DCAM_PATH_1_FRM_CNT_MAX;
3011 (path1_frame+i)->fid = base_id + i;
3014 for (i = 0; i < DCAM_PATH_2_FRM_CNT_MAX; i++) {
3015 DCAM_CLEAR(path2_frame + i);
3016 //(path2_frame+i)->next = path2_frame+(i + 1) % DCAM_PATH_2_FRM_CNT_MAX;
3017 //(path2_frame+i)->prev = path2_frame+(i - 1 + DCAM_PATH_2_FRM_CNT_MAX) % DCAM_PATH_2_FRM_CNT_MAX;
3018 (path2_frame+i)->fid = base_id + i;
3021 //s_p_dcam_mod->dcam_path0.output_frame_head = path0_frame;
3022 //s_p_dcam_mod->dcam_path1.output_frame_head = path1_frame;
3023 //s_p_dcam_mod->dcam_path2.output_frame_head = path2_frame;
3024 //s_p_dcam_mod->dcam_path0.output_frame_cur = path0_frame;
3025 //s_p_dcam_mod->dcam_path1.output_frame_cur = path1_frame;
3026 //s_p_dcam_mod->dcam_path2.output_frame_cur = path2_frame;
3031 LOCAL int32_t _dcam_path_set_next_frm(enum dcam_path_index path_index, uint32_t is_1st_frm)
3033 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
3034 struct dcam_frame frame;
3035 struct dcam_frame *reserved_frame = NULL;
3036 struct dcam_frame *orig_frame = NULL;
3037 struct dcam_path_desc *path = NULL;
3038 unsigned long yuv_reg[3] = {0};
3039 uint32_t path_max_frm_cnt;
3041 struct dcam_frm_queue *p_heap = NULL;
3042 struct dcam_buf_queue *p_buf_queue = NULL;
3044 DCAM_CHECK_ZERO(s_p_dcam_mod);
3046 if (DCAM_PATH_IDX_0 == path_index) {
3047 //frame = &s_p_dcam_mod->path0_frame[0];
3048 reserved_frame = &s_p_dcam_mod->path0_reserved_frame;
3049 path = &s_p_dcam_mod->dcam_path0;
3050 yuv_reg[0] = DCAM_FRM_ADDR0;
3051 yuv_reg[1] = DCAM_FRM_ADDR12;
3052 path_max_frm_cnt = DCAM_PATH_0_FRM_CNT_MAX;
3053 p_heap = &s_p_dcam_mod->dcam_path0.frame_queue;
3054 p_buf_queue = &s_p_dcam_mod->dcam_path0.buf_queue;
3055 } else if (DCAM_PATH_IDX_1 == path_index) {
3056 //frame = &s_p_dcam_mod->path1_frame[0];
3057 reserved_frame = &s_p_dcam_mod->path1_reserved_frame;
3058 path = &s_p_dcam_mod->dcam_path1;
3059 yuv_reg[0] = DCAM_FRM_ADDR1;
3060 yuv_reg[1] = DCAM_FRM_ADDR2;
3061 yuv_reg[2] = DCAM_FRM_ADDR3;
3062 path_max_frm_cnt = DCAM_PATH_1_FRM_CNT_MAX;
3063 p_heap = &s_p_dcam_mod->dcam_path1.frame_queue;
3064 p_buf_queue = &s_p_dcam_mod->dcam_path1.buf_queue;
3065 } else /*if(DCAM_PATH_IDX_2 == path_index)*/ {
3066 //frame = &s_p_dcam_mod->path2_frame[0];
3067 reserved_frame = &s_p_dcam_mod->path2_reserved_frame;
3068 path = &s_p_dcam_mod->dcam_path2;
3069 yuv_reg[0] = DCAM_FRM_ADDR4;
3070 yuv_reg[1] = DCAM_FRM_ADDR5;
3071 yuv_reg[2] = DCAM_FRM_ADDR6;
3072 path_max_frm_cnt = DCAM_PATH_2_FRM_CNT_MAX;
3073 p_heap = &s_p_dcam_mod->dcam_path2.frame_queue;
3074 p_buf_queue = &s_p_dcam_mod->dcam_path2.buf_queue;
3077 if (0 != _dcam_buf_queue_read(p_buf_queue, &frame)) {
3078 DCAM_TRACE("DCAM: No freed frame id %d \n", frame.fid);
3079 memcpy(&frame, reserved_frame, sizeof(struct dcam_frame));
3082 DCAM_TRACE("DCAM: next %d y 0x%x uv 0x%x \n", path->output_frame_count, frame.yaddr, frame.uaddr);
3083 REG_WR(yuv_reg[0], frame.yaddr);
3084 if ((DCAM_YUV400 > path->output_format) && (DCAM_PATH_IDX_0 != path_index)) {
3085 REG_WR(yuv_reg[1], frame.uaddr);
3086 if (DCAM_YUV420_3FRAME == path->output_format) {
3087 REG_WR(yuv_reg[2], frame.vaddr);
3090 dcam_frame_lock(&frame);
3091 if (0 == _dcam_frame_enqueue(p_heap, &frame)) {
3093 dcam_frame_unlock(&frame);
3094 rtn = DCAM_RTN_PATH_FRAME_LOCKED;
3101 LOCAL int32_t _dcam_path_trim(enum dcam_path_index path_index)
3103 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
3104 struct dcam_path_desc *path;
3105 uint32_t cfg_reg, ctrl_bit;
3107 DCAM_CHECK_ZERO(s_p_dcam_mod);
3109 if (DCAM_PATH_IDX_1 == path_index) {
3110 path = &s_p_dcam_mod->dcam_path1;
3111 cfg_reg = DCAM_PATH1_CFG;
3113 } else if (DCAM_PATH_IDX_2 == path_index) {
3114 path = &s_p_dcam_mod->dcam_path2;
3115 cfg_reg = DCAM_PATH2_CFG;
3118 printk("DCAM: _dcam_path_trim invalid path_index=%d \n", path_index);
3122 if (path->input_size.w != path->input_rect.w ||
3123 path->input_size.h != path->input_rect.h) {
3124 /*REG_OWR(cfg_reg, 1 << ctrl_bit);*/
3126 /*REG_MWR(cfg_reg, 1 << ctrl_bit, 0 << ctrl_bit);*/
3134 LOCAL int32_t _dcam_path_scaler(enum dcam_path_index path_index)
3136 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
3137 struct dcam_path_desc *path = NULL;
3138 unsigned long cfg_reg = 0;
3140 DCAM_CHECK_ZERO(s_p_dcam_mod);
3141 DCAM_CHECK_ZERO(s_dcam_sc_array);
3143 if (DCAM_PATH_IDX_1 == path_index) {
3144 path = &s_p_dcam_mod->dcam_path1;
3145 cfg_reg = DCAM_PATH1_CFG;
3146 } else if (DCAM_PATH_IDX_2 == path_index){
3147 path = &s_p_dcam_mod->dcam_path2;
3148 cfg_reg = DCAM_PATH2_CFG;
3151 DCAM_CHECK_ZERO(path);
3152 if (DCAM_RAWRGB == path->output_format ||
3153 DCAM_JPEG == path->output_format) {
3154 DCAM_TRACE("DCAM: _dcam_path_scaler out format is %d, no need scaler \n", path->output_format);
3155 return DCAM_RTN_SUCCESS;
3158 rtn = _dcam_calc_sc_size(path_index);
3159 if (DCAM_RTN_SUCCESS != rtn) {
3163 if (path->sc_input_size.w == path->output_size.w &&
3164 path->sc_input_size.h == path->output_size.h &&
3165 DCAM_YUV422 == path->output_format) {
3166 REG_MWR(cfg_reg, BIT_20, 1 << 20);// bypass scaler if the output size equals input size for YUV422 format
3168 REG_MWR(cfg_reg, BIT_20, 0 << 20);
3169 if (s_dcam_sc_array->is_smooth_zoom
3170 && DCAM_PATH_IDX_1 == path_index
3171 && DCAM_ST_START == path->status) {
3172 rtn = _dcam_calc_sc_coeff(path_index);
3174 rtn = _dcam_set_sc_coeff(path_index);
3181 LOCAL int32_t _dcam_path_check_deci(enum dcam_path_index path_index, uint32_t *is_deci)
3183 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
3184 struct dcam_path_desc *path = NULL;
3185 uint32_t w_deci = 0;
3186 uint32_t h_deci = 0;
3188 DCAM_CHECK_ZERO(s_p_dcam_mod);
3190 if (DCAM_PATH_IDX_1 == path_index) {
3191 path = &s_p_dcam_mod->dcam_path1;
3192 } else if (DCAM_PATH_IDX_2 == path_index) {
3193 path = &s_p_dcam_mod->dcam_path2;
3195 rtn = DCAM_RTN_PATH_SC_ERR;
3199 if (path->input_rect.w > (path->output_size.w * DCAM_SC_COEFF_DOWN_MAX * (1<<DCAM_PATH_DECI_FAC_MAX)) ||
3200 path->input_rect.h > (path->output_size.h * DCAM_SC_COEFF_DOWN_MAX * (1<<DCAM_PATH_DECI_FAC_MAX)) ||
3201 path->input_rect.w * DCAM_SC_COEFF_UP_MAX < path->output_size.w ||
3202 path->input_rect.h * DCAM_SC_COEFF_UP_MAX < path->output_size.h) {
3203 rtn = DCAM_RTN_PATH_SC_ERR;
3205 if (path->input_rect.w > path->output_size.w * DCAM_SC_COEFF_DOWN_MAX)
3207 if (path->input_rect.h > path->output_size.h * DCAM_SC_COEFF_DOWN_MAX)
3210 if(w_deci || h_deci)
3217 DCAM_TRACE("DCAM: _dcam_path_check_deci: path_index=%d, is_deci=%d, rtn=%d \n", path_index, *is_deci, rtn);
3222 LOCAL uint32_t _dcam_get_path_deci_factor(uint32_t src_size, uint32_t dst_size)
3224 uint32_t factor = 0;
3226 if (0 == src_size || 0 == dst_size) {
3230 /* factor: 0 - 1/2, 1 - 1/4, 2 - 1/8, 3 - 1/16 */
3231 for (factor = 0; factor < DCAM_PATH_DECI_FAC_MAX; factor ++) {
3232 if (src_size < (uint32_t)(dst_size * (1 << (factor + 1)))) {
3240 LOCAL int32_t _dcam_calc_sc_size(enum dcam_path_index path_index)
3242 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
3243 struct dcam_path_desc *path = NULL;
3244 unsigned long cfg_reg = 0;
3245 uint32_t tmp_dstsize = 0;
3246 uint32_t align_size = 0;
3248 DCAM_CHECK_ZERO(s_p_dcam_mod);
3250 if (DCAM_PATH_IDX_1 == path_index) {
3251 path = &s_p_dcam_mod->dcam_path1;
3252 cfg_reg = DCAM_PATH1_CFG;
3253 } else if (DCAM_PATH_IDX_2 == path_index){
3254 path = &s_p_dcam_mod->dcam_path2;
3255 cfg_reg = DCAM_PATH2_CFG;
3258 DCAM_CHECK_ZERO(path);
3259 if (path->input_rect.w > (path->output_size.w * DCAM_SC_COEFF_DOWN_MAX * (1<<DCAM_PATH_DECI_FAC_MAX)) ||
3260 path->input_rect.h > (path->output_size.h * DCAM_SC_COEFF_DOWN_MAX * (1<<DCAM_PATH_DECI_FAC_MAX)) ||
3261 path->input_rect.w * DCAM_SC_COEFF_UP_MAX < path->output_size.w ||
3262 path->input_rect.h * DCAM_SC_COEFF_UP_MAX < path->output_size.h) {
3263 rtn = DCAM_RTN_PATH_SC_ERR;
3265 path->sc_input_size.w = path->input_rect.w;
3266 path->sc_input_size.h = path->input_rect.h;
3267 if (path->input_rect.w > path->output_size.w * DCAM_SC_COEFF_DOWN_MAX) {
3268 tmp_dstsize = path->output_size.w * DCAM_SC_COEFF_DOWN_MAX;
3269 path->deci_val.deci_x = _dcam_get_path_deci_factor(path->input_rect.w, tmp_dstsize);
3270 path->deci_val.deci_x_en = 1;
3271 path->valid_param.v_deci = 1;
3272 align_size = (1 << (path->deci_val.deci_x+1))*DCAM_PIXEL_ALIGN_WIDTH;
3273 path->input_rect.w = (path->input_rect.w) & ~(align_size-1);
3274 path->input_rect.x = (path->input_rect.x) & ~(align_size-1);
3275 path->sc_input_size.w = path->input_rect.w >> (path->deci_val.deci_x+1);
3277 path->deci_val.deci_x = 0;
3278 path->deci_val.deci_x_en = 0;
3279 path->valid_param.v_deci = 1;
3282 if (path->input_rect.h > path->output_size.h * DCAM_SC_COEFF_DOWN_MAX) {
3283 tmp_dstsize = path->output_size.h * DCAM_SC_COEFF_DOWN_MAX;
3284 path->deci_val.deci_y = _dcam_get_path_deci_factor(path->input_rect.h, tmp_dstsize);
3285 path->deci_val.deci_y_en = 1;
3286 path->valid_param.v_deci = 1;
3287 align_size = (1 << (path->deci_val.deci_y+1))*DCAM_PIXEL_ALIGN_HEIGHT;
3288 path->input_rect.h = (path->input_rect.h) & ~(align_size-1);
3289 path->input_rect.y = (path->input_rect.y) & ~(align_size-1);
3290 path->sc_input_size.h = path->input_rect.h >> (path->deci_val.deci_y+1);
3292 path->deci_val.deci_y = 0;
3293 path->deci_val.deci_y_en = 0;
3294 path->valid_param.v_deci = 1;
3299 DCAM_TRACE("DCAM: _dcam_calc_sc_size, path=%d, x_en=%d, deci_x=%d, y_en=%d, deci_y=%d \n",
3300 path_index, path->deci_val.deci_x_en,
3301 path->deci_val.deci_x, path->deci_val.deci_y_en,
3302 path->deci_val.deci_y);
3307 LOCAL int32_t _dcam_set_sc_coeff(enum dcam_path_index path_index)
3309 struct dcam_path_desc *path = NULL;
3311 unsigned long h_coeff_addr = DCAM_BASE;
3312 unsigned long v_coeff_addr = DCAM_BASE;
3313 unsigned long v_chroma_coeff_addr = DCAM_BASE;
3314 uint32_t *tmp_buf = NULL;
3315 uint32_t *h_coeff = NULL;
3316 uint32_t *v_coeff = NULL;
3317 uint32_t *v_chroma_coeff = NULL;
3318 uint32_t clk_switch_bit = 0;
3319 uint32_t clk_switch_shift_bit = 0;
3320 uint32_t clk_status_bit = 0;
3321 unsigned long ver_tap_reg = 0;
3322 uint32_t scale2yuv420 = 0;
3327 DCAM_CHECK_ZERO(s_p_dcam_mod);
3329 if (DCAM_PATH_IDX_1 != path_index && DCAM_PATH_IDX_2 != path_index)
3330 return -DCAM_RTN_PARA_ERR;
3332 if (DCAM_PATH_IDX_1 == path_index) {
3333 path = &s_p_dcam_mod->dcam_path1;
3334 h_coeff_addr += DCAM_SC1_H_TAB_OFFSET;
3335 v_coeff_addr += DCAM_SC1_V_TAB_OFFSET;
3336 v_chroma_coeff_addr += DCAM_SC1_V_CHROMA_TAB_OFFSET;
3337 clk_switch_bit = BIT_3;
3338 clk_switch_shift_bit = 3;
3339 clk_status_bit = BIT_5;
3340 ver_tap_reg = DCAM_PATH1_CFG;
3341 } else if (DCAM_PATH_IDX_2 == path_index) {
3342 path = &s_p_dcam_mod->dcam_path2;
3343 h_coeff_addr += DCAM_SC2_H_TAB_OFFSET;
3344 v_coeff_addr += DCAM_SC2_V_TAB_OFFSET;
3345 v_chroma_coeff_addr += DCAM_SC2_V_CHROMA_TAB_OFFSET;
3346 clk_switch_bit = BIT_4;
3347 clk_switch_shift_bit = 4;
3348 clk_status_bit = BIT_6;
3349 ver_tap_reg = DCAM_PATH2_CFG;
3352 if (DCAM_YUV420 == path->output_format) {
3356 DCAM_TRACE("DCAM: _dcam_set_sc_coeff {%d %d %d %d}, 420=%d \n",
3357 path->sc_input_size.w,
3358 path->sc_input_size.h,
3359 path->output_size.w,
3360 path->output_size.h, scale2yuv420);
3363 tmp_buf = dcam_get_scale_coeff_addr(&index);
3365 if (NULL == tmp_buf) {
3366 return -DCAM_RTN_PATH_NO_MEM;
3370 v_coeff = tmp_buf + (DCAM_SC_COEFF_COEF_SIZE/4);
3371 v_chroma_coeff = v_coeff + (DCAM_SC_COEFF_COEF_SIZE/4);
3373 down(&s_p_dcam_mod->scale_coeff_mem_sema);
3375 if (!(Dcam_GenScaleCoeff((int16_t)path->sc_input_size.w,
3376 (int16_t)path->sc_input_size.h,
3377 (int16_t)path->output_size.w,
3378 (int16_t)path->output_size.h,
3385 tmp_buf + (DCAM_SC_COEFF_COEF_SIZE*3/4),
3386 DCAM_SC_COEFF_TMP_SIZE))) {
3387 printk("DCAM: _dcam_set_sc_coeff Dcam_GenScaleCoeff error! \n");
3388 up(&s_p_dcam_mod->scale_coeff_mem_sema);
3389 return -DCAM_RTN_PATH_GEN_COEFF_ERR;
3392 for (i = 0; i < DCAM_SC_COEFF_H_NUM; i++) {
3393 REG_WR(h_coeff_addr, *h_coeff);
3398 for (i = 0; i < DCAM_SC_COEFF_V_NUM; i++) {
3399 REG_WR(v_coeff_addr, *v_coeff);
3404 for (i = 0; i < DCAM_SC_COEFF_V_CHROMA_NUM; i++) {
3405 REG_WR(v_chroma_coeff_addr, *v_chroma_coeff);
3406 v_chroma_coeff_addr += 4;
3410 path->scale_tap.y_tap = y_tap;
3411 path->scale_tap.uv_tap = uv_tap;
3412 path->valid_param.scale_tap = 1;
3414 up(&s_p_dcam_mod->scale_coeff_mem_sema);
3416 return DCAM_RTN_SUCCESS;
3419 LOCAL void _dcam_force_copy_ext(enum dcam_path_index path_index, uint32_t path_copy, uint32_t coef_copy)
3421 uint32_t reg_val = 0;
3423 if (DCAM_PATH_IDX_1 == path_index) {
3429 dcam_glb_reg_mwr(DCAM_CONTROL, reg_val, reg_val, DCAM_CONTROL_REG);
3430 } else if(DCAM_PATH_IDX_2 == path_index) {
3436 dcam_glb_reg_mwr(DCAM_CONTROL, reg_val, reg_val, DCAM_CONTROL_REG);
3438 DCAM_TRACE("DCAM: _dcam_force_copy_ext invalid path index: %d \n", path_index);
3442 LOCAL void _dcam_auto_copy_ext(enum dcam_path_index path_index, uint32_t path_copy, uint32_t coef_copy)
3444 uint32_t reg_val = 0;
3446 if (DCAM_PATH_IDX_0 == path_index) {
3449 dcam_glb_reg_mwr(DCAM_CONTROL, reg_val, reg_val, DCAM_CONTROL_REG);
3450 } else if (DCAM_PATH_IDX_1 == path_index) {
3455 dcam_glb_reg_mwr(DCAM_CONTROL, reg_val, reg_val, DCAM_CONTROL_REG);
3456 } else if (DCAM_PATH_IDX_2 == path_index) {
3461 dcam_glb_reg_mwr(DCAM_CONTROL, reg_val, reg_val, DCAM_CONTROL_REG);
3463 DCAM_TRACE("DCAM: _dcam_auto_copy_ext invalid path index: %d \n", path_index);
3468 LOCAL void _dcam_force_copy(enum dcam_path_index path_index)
3470 if (DCAM_PATH_IDX_0 == path_index) {
3471 dcam_glb_reg_mwr(DCAM_CONTROL, BIT_0, 1 << 0, DCAM_CONTROL_REG); /* Cap force copy */
3472 } else if (DCAM_PATH_IDX_1 == path_index) {
3473 dcam_glb_reg_mwr(DCAM_CONTROL, BIT_10, 1 << 10, DCAM_CONTROL_REG);
3474 } else if (DCAM_PATH_IDX_2 == path_index) {
3475 dcam_glb_reg_mwr(DCAM_CONTROL, BIT_12, 1 << 12, DCAM_CONTROL_REG);
3477 DCAM_TRACE("DCAM: _dcam_force_copy invalid path index: %d \n", path_index);
3481 LOCAL void _dcam_auto_copy(enum dcam_path_index path_index)
3483 if (DCAM_PATH_IDX_0 == path_index) {
3484 dcam_glb_reg_mwr(DCAM_CONTROL, BIT_9, 1 << 9, DCAM_CONTROL_REG);
3485 } else if(DCAM_PATH_IDX_1 == path_index) {
3486 dcam_glb_reg_mwr(DCAM_CONTROL, BIT_11, 1 << 11, DCAM_CONTROL_REG);
3487 } else if(DCAM_PATH_IDX_2 == path_index) {
3488 dcam_glb_reg_mwr(DCAM_CONTROL, BIT_13, 1 << 13, DCAM_CONTROL_REG);
3490 DCAM_TRACE("DCAM: _dcam_auto_copy invalid path index: %d \n", path_index);
3494 LOCAL void _dcam_reg_trace(void)
3496 #ifdef DCAM_DRV_DEBUG
3497 unsigned long addr = 0;
3499 printk("DCAM: Register list");
3500 for (addr = DCAM_CFG; addr <= CAP_SENSOR_CTRL; addr += 16) {
3501 printk("\n 0x%lx: 0x%x 0x%x 0x%x 0x%x",
3514 LOCAL void _dcam_sensor_sof(void)
3516 dcam_isr_func user_func = s_user_func[DCAM_SN_SOF];
3517 void *data = s_user_data[DCAM_SN_SOF];
3519 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3521 DCAM_TRACE("DCAM: _sn_sof \n");
3524 (*user_func)(NULL, data);
3531 LOCAL void _dcam_sensor_eof(void)
3533 dcam_isr_func user_func = s_user_func[DCAM_SN_EOF];
3534 void *data = s_user_data[DCAM_SN_EOF];
3536 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3538 DCAM_TRACE("DCAM: _sn_eof \n");
3541 (*user_func)(NULL, data);
3547 LOCAL void _dcam_cap_sof(void)
3549 dcam_isr_func user_func = s_user_func[DCAM_CAP_SOF];
3550 void *data = s_user_data[DCAM_CAP_SOF];
3552 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3554 DCAM_TRACE("DCAM: _cap_sof \n");
3556 _dcam_stopped_notice();
3559 (*user_func)(NULL, data);
3565 LOCAL void _dcam_cap_eof(void)
3567 dcam_isr_func user_func = s_user_func[DCAM_CAP_EOF];
3568 void *data = s_user_data[DCAM_CAP_EOF];
3570 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3573 (*user_func)(NULL, data);
3579 LOCAL void _dcam_path0_done(void)
3581 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
3582 dcam_isr_func user_func = s_user_func[DCAM_PATH0_DONE];
3583 void *data = s_user_data[DCAM_PATH0_DONE];
3584 struct dcam_path_desc *path;
3585 struct dcam_frame frame;
3587 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3588 path = &s_p_dcam_mod->dcam_path0;
3589 if (0 == path->valide) {
3590 printk("DCAM: path0 not valid \n");
3593 if (path->need_stop) {
3594 dcam_glb_reg_awr(DCAM_CFG, ~BIT_0, DCAM_CFG_REG);
3595 path->need_stop = 0;
3597 _dcam_path_done_notice(DCAM_PATH_IDX_0);
3598 DCAM_TRACE("DCAM 0 \n");
3599 rtn = _dcam_path_set_next_frm(DCAM_PATH_IDX_0, false);
3601 printk("DCAM: 0 w \n");
3604 _dcam_auto_copy(DCAM_PATH_IDX_0);
3606 rtn = _dcam_frame_dequeue(&path->frame_queue, &frame);
3607 if (0 == rtn && frame.yaddr != s_p_dcam_mod->path0_reserved_frame.yaddr && 0 != dcam_frame_is_locked(&frame)) {
3608 frame.width = path->output_size.w;
3609 frame.height = path->output_size.h;
3611 (*user_func)(&frame, data);
3614 DCAM_TRACE("DCAM: path0_reserved_frame \n");
3620 LOCAL void _dcam_path0_overflow(void)
3622 dcam_isr_func user_func = s_user_func[DCAM_PATH0_OV];
3623 void *data = s_user_data[DCAM_PATH0_OV];
3624 struct dcam_path_desc *path;
3625 struct dcam_frame frame;
3627 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3629 printk("DCAM: _path0_overflow \n");
3630 path = &s_p_dcam_mod->dcam_path0;
3631 //frame = path->output_frame_cur->prev->prev;
3632 //frame = &s_p_dcam_mod->path0_frame[0];
3633 _dcam_frame_dequeue(&path->frame_queue, &frame);
3636 (*user_func)(&frame, data);
3642 LOCAL void _dcam_path1_done(void)
3644 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
3645 dcam_isr_func user_func = s_user_func[DCAM_PATH1_DONE];
3646 void *data = s_user_data[DCAM_PATH1_DONE];
3647 struct dcam_path_desc *path;
3648 struct dcam_frame frame;
3650 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3651 path = &s_p_dcam_mod->dcam_path1;
3652 if (0 == path->valide) {
3653 printk("DCAM: path1 not valid \n");
3657 DCAM_TRACE("DCAM: 1\n");
3659 if (path->need_stop) {
3660 dcam_glb_reg_awr(DCAM_CFG, ~BIT_1, DCAM_CFG_REG);
3661 path->need_stop = 0;
3663 _dcam_path_done_notice(DCAM_PATH_IDX_1);
3665 if (path->sof_cnt < 1) {
3666 printk("DCAM: path1 done cnt %d\n", path->sof_cnt);
3667 path->need_wait = 0;
3672 if (path->need_wait) {
3673 path->need_wait = 0;
3675 rtn = _dcam_frame_dequeue(&path->frame_queue, &frame);
3676 if (0 == rtn && frame.yaddr != s_p_dcam_mod->path1_reserved_frame.yaddr && 0 != dcam_frame_is_locked(&frame)) {
3677 frame.width = path->output_size.w;
3678 frame.height = path->output_size.h;
3679 DCAM_TRACE("DCAM: path1 frame 0x%x, y uv, 0x%x 0x%x \n",
3680 (int)&frame, frame.yaddr, frame.uaddr);
3682 (*user_func)(&frame, data);
3685 DCAM_TRACE("DCAM: path1_reserved_frame \n");
3691 LOCAL void _dcam_path1_overflow(void)
3693 dcam_isr_func user_func = s_user_func[DCAM_PATH1_OV];
3694 void *data = s_user_data[DCAM_PATH1_OV];
3695 struct dcam_path_desc *path;
3696 struct dcam_frame frame;
3698 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3700 printk("DCAM: _path1_overflow \n");
3701 path = &s_p_dcam_mod->dcam_path1;
3702 //frame = path->output_frame_cur->prev->prev;
3703 _dcam_frame_dequeue(&path->frame_queue, &frame);
3706 (*user_func)(&frame, data);
3712 LOCAL void _dcam_sensor_line_err(void)
3714 dcam_isr_func user_func = s_user_func[DCAM_SN_LINE_ERR];
3715 void *data = s_user_data[DCAM_SN_LINE_ERR];
3717 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3719 printk("DCAM: _line_err \n");
3722 (*user_func)(NULL, data);
3728 LOCAL void _dcam_sensor_frame_err(void)
3730 dcam_isr_func user_func = s_user_func[DCAM_SN_FRAME_ERR];
3731 void *data = s_user_data[DCAM_SN_FRAME_ERR];
3733 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3735 printk("DCAM: _frame_err \n");
3738 (*user_func)(NULL, data);
3744 LOCAL void _dcam_jpeg_buf_ov(void)
3746 dcam_isr_func user_func = s_user_func[DCAM_JPEG_BUF_OV];
3747 void *data = s_user_data[DCAM_JPEG_BUF_OV];
3748 struct dcam_path_desc *path;
3749 struct dcam_frame frame;
3751 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3753 printk("DCAM: _jpeg_overflow \n");
3754 path = &s_p_dcam_mod->dcam_path0;
3755 //frame = path->output_frame_cur->prev->prev;
3756 //frame = &s_p_dcam_mod->path0_frame[0];
3757 _dcam_frame_dequeue(&path->frame_queue, &frame);
3760 (*user_func)(&frame, data);
3766 LOCAL void _dcam_path2_done(void)
3768 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
3769 dcam_isr_func user_func = s_user_func[DCAM_PATH2_DONE];
3770 void *data = s_user_data[DCAM_PATH2_DONE];
3771 struct dcam_path_desc *path;
3772 struct dcam_frame frame;
3774 if (atomic_read(&s_resize_flag)) {
3775 memset(&frame, 0, sizeof(struct dcam_frame));
3777 (*user_func)(&frame, data);
3780 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3781 path = &s_p_dcam_mod->dcam_path2;
3783 DCAM_TRACE("DCAM: 2, %d %d \n", path->need_stop, path->need_wait);
3784 if (path->status == DCAM_ST_START) {
3786 if (path->need_stop) {
3787 dcam_glb_reg_awr(DCAM_CFG, ~BIT_2, DCAM_CFG_REG);
3788 path->need_stop = 0;
3790 _dcam_path_done_notice(DCAM_PATH_IDX_2);
3792 if (path->sof_cnt < 1) {
3793 printk("DCAM: path2 done cnt %d\n", path->sof_cnt);
3794 path->need_wait = 0;
3799 if (path->need_wait) {
3800 path->need_wait = 0;
3802 rtn = _dcam_frame_dequeue(&path->frame_queue, &frame);
3803 if (0 == rtn && frame.yaddr != s_p_dcam_mod->path2_reserved_frame.yaddr && 0 != dcam_frame_is_locked(&frame)) {
3804 DCAM_TRACE("DCAM: path2 frame 0x%x, y uv, 0x%x 0x%x \n",
3805 (int)&frame, frame.yaddr, frame.uaddr);
3806 frame.width = path->output_size.w;
3807 frame.height = path->output_size.h;
3809 (*user_func)(&frame, data);
3812 DCAM_TRACE("DCAM: path2_reserved_frame \n");
3819 LOCAL void _dcam_path2_ov(void)
3821 dcam_isr_func user_func = s_user_func[DCAM_PATH2_OV];
3822 void *data = s_user_data[DCAM_PATH2_OV];
3823 struct dcam_path_desc *path;
3824 struct dcam_frame frame;
3826 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3828 printk("DCAM: _path2_overflow \n");
3829 path = &s_p_dcam_mod->dcam_path2;
3830 //frame = path->output_frame_cur->prev->prev;
3831 //frame = &s_p_dcam_mod->path2_frame[0];
3832 _dcam_frame_dequeue(&path->frame_queue, &frame);
3835 (*user_func)(&frame, data);
3841 LOCAL void _dcam_isp_ov(void)
3843 dcam_isr_func user_func = s_user_func[DCAM_ISP_OV];
3844 void *data = s_user_data[DCAM_ISP_OV];
3846 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3848 printk("DCAM: _isp_overflow \n");
3851 (*user_func)(NULL, data);
3857 LOCAL void _dcam_mipi_ov(void)
3859 dcam_isr_func user_func = s_user_func[DCAM_MIPI_OV];
3860 void *data = s_user_data[DCAM_MIPI_OV];
3862 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3866 (*user_func)(NULL, data);
3869 printk("DCAM: _mipi_overflow \n");
3873 LOCAL void _dcam_rot_done(void)
3875 dcam_isr_func user_func = s_user_func[DCAM_ROT_DONE];
3876 void *data = s_user_data[DCAM_ROT_DONE];
3878 DCAM_TRACE("DCAM: rot_done \n");
3881 (*user_func)(NULL, data);
3887 LOCAL void _dcam_path1_slice_done(void)
3889 dcam_isr_func user_func = s_user_func[DCAM_PATH1_SLICE_DONE];
3890 void *data = s_user_data[DCAM_PATH1_SLICE_DONE];
3892 DCAM_TRACE("DCAM: 1 slice done \n");
3895 (*user_func)(NULL, data);
3901 LOCAL void _dcam_path2_slice_done(void)
3903 dcam_isr_func user_func = s_user_func[DCAM_PATH2_SLICE_DONE];
3904 void *data = s_user_data[DCAM_PATH2_SLICE_DONE];
3906 DCAM_TRACE("DCAM: 2 slice done \n");
3909 (*user_func)(NULL, data);
3915 LOCAL void _dcam_raw_slice_done(void)
3917 dcam_isr_func user_func = s_user_func[DCAM_RAW_SLICE_DONE];
3918 void *data = s_user_data[DCAM_RAW_SLICE_DONE];
3920 DCAM_TRACE("DCAM: 0 slice done \n");
3923 (*user_func)(NULL, data);
3929 LOCAL void _dcam_path1_sof(void)
3931 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
3932 dcam_isr_func user_func = s_user_func[DCAM_PATH1_SOF];
3933 void *data = s_user_data[DCAM_PATH1_SOF];
3934 struct dcam_path_desc *path;
3935 struct dcam_sc_coeff *sc_coeff;
3937 DCAM_TRACE("DCAM: 1 sof done \n");
3939 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3940 DCAM_CHECK_ZERO_VOID(s_dcam_sc_array);
3942 if(s_p_dcam_mod->dcam_path1.status == DCAM_ST_START){
3944 path = &s_p_dcam_mod->dcam_path1;
3945 if (0 == path->valide) {
3946 printk("DCAM: path1 not valid \n");
3950 if (path->sof_cnt > 0) {
3951 printk("DCAM: path1 sof %d \n", path->sof_cnt);
3957 rtn = _dcam_path_set_next_frm(DCAM_PATH_IDX_1, false);
3958 if (path->is_update) {
3959 if (s_dcam_sc_array->is_smooth_zoom) {
3960 _dcam_get_valid_sc_coeff(s_dcam_sc_array, &sc_coeff);
3961 _dcam_write_sc_coeff(DCAM_PATH_IDX_1);
3962 _dcam_path1_set(&sc_coeff->dcam_path1);
3963 _dcam_pop_sc_buf(s_dcam_sc_array, &sc_coeff);
3965 _dcam_path1_set(path);
3967 path->is_update = 0;
3968 DCAM_TRACE("DCAM: path1 updated \n");
3969 _dcam_auto_copy_ext(DCAM_PATH_IDX_1, true, true);
3972 DCAM_TRACE("DCAM: path1 updated \n");
3974 _dcam_auto_copy(DCAM_PATH_IDX_1);
3978 _dcam_path_updated_notice(DCAM_PATH_IDX_1);
3981 path->need_wait = 1;
3982 printk("DCAM: 1 w\n");
3988 (*user_func)(NULL, data);
3994 LOCAL void _dcam_path2_sof(void)
3996 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
3997 dcam_isr_func user_func = s_user_func[DCAM_PATH2_SOF];
3998 void *data = s_user_data[DCAM_PATH2_SOF];
3999 struct dcam_path_desc *path;
4001 DCAM_TRACE("DCAM: 2 sof done \n");
4003 if (atomic_read(&s_resize_flag)) {
4004 printk("DCAM: path 2 sof, review now \n");
4006 if (DCAM_ADDR_INVALID(s_p_dcam_mod)) {
4010 if(s_p_dcam_mod->dcam_path2.status == DCAM_ST_START){
4012 path = &s_p_dcam_mod->dcam_path2;
4013 if (0 == path->valide) {
4014 printk("DCAM: path2 not valid \n");
4018 if (path->sof_cnt > 0) {
4019 printk("DCAM: path2 sof %d \n", path->sof_cnt);
4025 rtn = _dcam_path_set_next_frm(DCAM_PATH_IDX_2, false);
4026 if (path->is_update) {
4028 path->is_update = 0;
4029 DCAM_TRACE("DCAM: path2 updated \n");
4030 _dcam_auto_copy_ext(DCAM_PATH_IDX_2, true, true);
4033 DCAM_TRACE("DCAM: path2 updated \n");
4035 _dcam_auto_copy(DCAM_PATH_IDX_2);
4039 _dcam_path_updated_notice(DCAM_PATH_IDX_2);
4042 path->need_wait = 1;
4043 printk("DCAM:2 w \n");
4050 (*user_func)(NULL, data);
4056 LOCAL int32_t _dcam_err_pre_proc(void)
4058 DCAM_CHECK_ZERO(s_p_dcam_mod);
4060 DCAM_TRACE("DCAM: state in err_pre_proc 0x%x,",s_p_dcam_mod->state);
4061 if (s_p_dcam_mod->state & DCAM_STATE_QUICKQUIT)
4064 s_p_dcam_mod->err_happened = 1;
4065 //printk("DCAM: err, 0x%x, ISP int 0x%x \n",
4066 // REG_RD(DCAM_INT_STS),
4067 // REG_RD(SPRD_ISP_BASE + 0x2080));
4068 printk("DCAM: err, 0x%x \n",
4069 REG_RD(DCAM_INT_STS));
4072 dcam_glb_reg_mwr(DCAM_CONTROL, BIT_2, 0, DCAM_CONTROL_REG); /* Cap Disable */
4074 if (0 == atomic_read(&s_resize_flag) &&
4075 0 == atomic_read(&s_rotation_flag)) {
4076 dcam_reset(DCAM_RST_ALL, 1);
4081 LOCAL void _dcam_stopped(void)
4083 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
4085 DCAM_TRACE("DCAM: stopped, %d \n", s_p_dcam_mod->wait_stop);
4087 _dcam_path_done_notice(DCAM_PATH_IDX_0);
4088 _dcam_path_done_notice(DCAM_PATH_IDX_1);
4089 _dcam_path_done_notice(DCAM_PATH_IDX_2);
4090 _dcam_stopped_notice();
4094 LOCAL int _dcam_internal_init(void)
4098 s_p_dcam_mod = (struct dcam_module*)vzalloc(sizeof(struct dcam_module));
4100 DCAM_CHECK_ZERO(s_p_dcam_mod);
4102 sema_init(&s_p_dcam_mod->stop_sema, 0);
4103 sema_init(&s_p_dcam_mod->dcam_path0.tx_done_sema, 0);
4104 sema_init(&s_p_dcam_mod->dcam_path1.tx_done_sema, 0);
4105 sema_init(&s_p_dcam_mod->dcam_path2.tx_done_sema, 0);
4106 sema_init(&s_p_dcam_mod->dcam_path0.sof_sema, 0);
4107 sema_init(&s_p_dcam_mod->dcam_path1.sof_sema, 0);
4108 sema_init(&s_p_dcam_mod->dcam_path2.sof_sema, 0);
4109 sema_init(&s_p_dcam_mod->resize_done_sema, 0);
4110 sema_init(&s_p_dcam_mod->rotation_done_sema, 0);
4111 sema_init(&s_p_dcam_mod->scale_coeff_mem_sema, 1);
4113 memset((void*)s_dcam_sc_array, 0, sizeof(struct dcam_sc_array));
4116 LOCAL void _dcam_internal_deinit(void)
4120 spin_lock_irqsave(&dcam_mod_lock, flag);
4121 if (DCAM_ADDR_INVALID(s_p_dcam_mod)) {
4122 printk("DCAM: Invalid addr, %p", s_p_dcam_mod);
4124 vfree(s_p_dcam_mod);
4125 s_p_dcam_mod = NULL;
4127 spin_unlock_irqrestore(&dcam_mod_lock, flag);
4131 LOCAL void _dcam_wait_path_done(enum dcam_path_index path_index, uint32_t *p_flag)
4134 struct dcam_path_desc *p_path = NULL;
4137 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
4139 if (s_p_dcam_mod->err_happened) {
4142 if (DCAM_CAPTURE_MODE_SINGLE == s_p_dcam_mod->dcam_mode) {
4145 if (DCAM_PATH_IDX_0 == path_index) {
4146 p_path = &s_p_dcam_mod->dcam_path0;
4147 } else if (DCAM_PATH_IDX_1 == path_index) {
4148 p_path = &s_p_dcam_mod->dcam_path1;
4149 } else if (DCAM_PATH_IDX_2 == path_index) {
4150 p_path = &s_p_dcam_mod->dcam_path2;
4152 printk("DCAM: Wrong index 0x%x \n", path_index);
4155 DCAM_TRACE("DCAM: path done wait %d, %d \n", p_path->wait_for_done, p_path->tx_done_sema.count);
4157 spin_lock_irqsave(&dcam_lock, flag);
4161 p_path->wait_for_done = 1;
4162 spin_unlock_irqrestore(&dcam_lock, flag);
4163 ret = down_timeout(&p_path->tx_done_sema, DCAM_PATH_TIMEOUT);
4166 printk("DCAM: Failed to wait path 0x%x done \n", path_index);
4172 LOCAL void _dcam_path_done_notice(enum dcam_path_index path_index)
4174 struct dcam_path_desc *p_path = NULL;
4176 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
4178 if (DCAM_PATH_IDX_0 == path_index) {
4179 p_path = &s_p_dcam_mod->dcam_path0;
4180 } else if(DCAM_PATH_IDX_1 == path_index) {
4181 p_path = &s_p_dcam_mod->dcam_path1;
4182 } else if(DCAM_PATH_IDX_2 == path_index) {
4183 p_path = &s_p_dcam_mod->dcam_path2;
4185 printk("DCAM: Wrong index 0x%x \n", path_index);
4188 DCAM_TRACE("DCAM: path done notice %d, %d \n", p_path->wait_for_done, p_path->tx_done_sema.count);
4189 if (p_path->wait_for_done) {
4190 up(&p_path->tx_done_sema);
4191 p_path->wait_for_done = 0;
4197 LOCAL void _dcam_wait_update_done(enum dcam_path_index path_index, uint32_t *p_flag)
4200 struct dcam_path_desc *p_path = NULL;
4203 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
4205 if (s_p_dcam_mod->err_happened) {
4208 if (DCAM_CAPTURE_MODE_SINGLE == s_p_dcam_mod->dcam_mode) {
4211 if (DCAM_PATH_IDX_0 == path_index) {
4212 p_path = &s_p_dcam_mod->dcam_path0;
4213 } else if (DCAM_PATH_IDX_1 == path_index) {
4214 p_path = &s_p_dcam_mod->dcam_path1;
4215 } else if (DCAM_PATH_IDX_2 == path_index) {
4216 p_path = &s_p_dcam_mod->dcam_path2;
4218 printk("DCAM: Wrong index 0x%x \n", path_index);
4221 DCAM_TRACE("DCAM: path done wait %d, %d \n", p_path->wait_for_done, p_path->tx_done_sema.count);
4223 spin_lock_irqsave(&dcam_lock, flag);
4227 p_path->wait_for_sof = 1;
4228 spin_unlock_irqrestore(&dcam_lock, flag);
4229 ret = down_timeout(&p_path->sof_sema, DCAM_PATH_TIMEOUT);
4232 printk("DCAM: Failed to wait update path 0x%x done \n", path_index);
4238 LOCAL void _dcam_path_updated_notice(enum dcam_path_index path_index)
4240 struct dcam_path_desc *p_path = NULL;
4242 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
4244 if (DCAM_PATH_IDX_0 == path_index) {
4245 p_path = &s_p_dcam_mod->dcam_path0;
4246 } else if(DCAM_PATH_IDX_1 == path_index) {
4247 p_path = &s_p_dcam_mod->dcam_path1;
4248 } else if(DCAM_PATH_IDX_2 == path_index) {
4249 p_path = &s_p_dcam_mod->dcam_path2;
4251 printk("DCAM: Wrong index 0x%x \n", path_index);
4254 DCAM_TRACE("DCAM: path done notice %d, %d \n", p_path->wait_for_done, p_path->tx_done_sema.count);
4255 if (p_path->wait_for_sof) {
4256 up(&p_path->sof_sema);
4257 p_path->wait_for_sof = 0;
4264 LOCAL void _dcam_stopped_notice(void)
4266 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
4268 if (s_p_dcam_mod->wait_stop) {
4269 up(&s_p_dcam_mod->stop_sema);
4270 s_p_dcam_mod->wait_stop = 0;
4274 void mm_clk_register_trace(void)
4277 printk("REG_AON_APB_APB_EB0 = 0x%x \n",REG_RD(REG_AON_APB_APB_EB0));
4278 printk("REG_PMU_APB_PD_MM_TOP_CFG = 0x%x \n",REG_RD(REG_PMU_APB_PD_MM_TOP_CFG));
4279 printk("REG_PMU_APB_CP_SOFT_RST = 0x%x \n",REG_RD(REG_PMU_APB_CP_SOFT_RST));
4280 if(!(REG_RD(REG_AON_APB_APB_EB0)&BIT_MM_EB) ) return ;
4281 if(REG_RD(REG_PMU_APB_PD_MM_TOP_CFG)&BIT_PD_MM_TOP_FORCE_SHUTDOWN) return ;
4283 printk("mm_clk_reg, part 1 \n");
4284 for (i = 0 ; i <= 0x10; i += 4 ) {
4285 printk("MMAHB: %lx val:%x \b\n",
4286 (SPRD_MMAHB_BASE + i),
4287 REG_RD(SPRD_MMAHB_BASE + i));
4290 printk("mm_clk_reg, part 2 \n");
4291 for (i = 0x20 ; i <= 0x38; i += 4 ) {
4292 printk("MMCKG: %lx val:%x \b\n",
4293 (SPRD_MMCKG_BASE + i),
4294 REG_RD(SPRD_MMCKG_BASE + i));
4298 int32_t dcam_stop_sc_coeff(void)
4302 DCAM_CHECK_ZERO(s_dcam_sc_array);
4304 zoom_mode = s_dcam_sc_array->is_smooth_zoom;
4305 /*memset((void*)s_dcam_sc_array, 0, sizeof(struct dcam_sc_array));*/
4306 s_dcam_sc_array->is_smooth_zoom = zoom_mode;
4307 s_dcam_sc_array->valid_cnt = 0;
4308 memset(&s_dcam_sc_array->scaling_coeff_queue, 0, DCAM_SC_COEFF_BUF_COUNT*sizeof(struct dcam_sc_coeff *));
4313 LOCAL int32_t _dcam_get_valid_sc_coeff(struct dcam_sc_array *sc, struct dcam_sc_coeff **sc_coeff)
4315 if (DCAM_ADDR_INVALID(sc) || DCAM_ADDR_INVALID(sc_coeff)) {
4316 printk("DCAM: get valid sc, invalid param %p, %p \n",
4321 if (sc->valid_cnt == 0) {
4322 printk("DCAM: valid cnt 0 \n");
4326 *sc_coeff = sc->scaling_coeff_queue[0];
4327 DCAM_TRACE("DCAM: get valid sc, %d \n", sc->valid_cnt);
4332 LOCAL int32_t _dcam_push_sc_buf(struct dcam_sc_array *sc, uint32_t index)
4334 if (DCAM_ADDR_INVALID(sc)) {
4335 printk("DCAM: push sc, invalid param %p \n", sc);
4338 if (sc->valid_cnt >= DCAM_SC_COEFF_BUF_COUNT) {
4339 printk("DCAM: valid cnt %d \n", sc->valid_cnt);
4343 sc->scaling_coeff[index].flag = 1;
4344 sc->scaling_coeff_queue[sc->valid_cnt] = &sc->scaling_coeff[index];
4347 DCAM_TRACE("DCAM: push sc, %d \n", sc->valid_cnt);
4352 LOCAL int32_t _dcam_pop_sc_buf(struct dcam_sc_array *sc, struct dcam_sc_coeff **sc_coeff)
4356 if (DCAM_ADDR_INVALID(sc) || DCAM_ADDR_INVALID(sc_coeff)) {
4357 printk("DCAM: pop sc, invalid param %p, %p \n",
4362 if (sc->valid_cnt == 0) {
4363 printk("DCAM: valid cnt 0 \n");
4366 sc->scaling_coeff_queue[0]->flag = 0;
4367 *sc_coeff = sc->scaling_coeff_queue[0];
4369 for (i = 0; i < sc->valid_cnt; i++) {
4370 sc->scaling_coeff_queue[i] = sc->scaling_coeff_queue[i+1];
4372 DCAM_TRACE("DCAM: pop sc, %d \n", sc->valid_cnt);
4376 LOCAL int32_t _dcam_write_sc_coeff(enum dcam_path_index path_index)
4379 struct dcam_path_desc *path = NULL;
4381 unsigned long h_coeff_addr = DCAM_BASE;
4382 unsigned long v_coeff_addr = DCAM_BASE;
4383 unsigned long v_chroma_coeff_addr = DCAM_BASE;
4384 uint32_t *tmp_buf = NULL;
4385 uint32_t *h_coeff = NULL;
4386 uint32_t *v_coeff = NULL;
4387 uint32_t *v_chroma_coeff = NULL;
4388 uint32_t clk_switch_bit = 0;
4389 uint32_t clk_switch_shift_bit = 0;
4390 uint32_t clk_status_bit = 0;
4391 unsigned long ver_tap_reg = 0;
4392 uint32_t scale2yuv420 = 0;
4393 struct dcam_sc_coeff *sc_coeff;
4395 DCAM_CHECK_ZERO(s_p_dcam_mod);
4396 DCAM_CHECK_ZERO(s_dcam_sc_array);
4398 if (DCAM_PATH_IDX_1 != path_index && DCAM_PATH_IDX_2 != path_index)
4399 return -DCAM_RTN_PARA_ERR;
4401 ret = _dcam_get_valid_sc_coeff(s_dcam_sc_array, &sc_coeff);
4403 return -DCAM_RTN_PATH_NO_MEM;
4405 tmp_buf = sc_coeff->buf;
4406 if (NULL == tmp_buf) {
4407 return -DCAM_RTN_PATH_NO_MEM;
4411 v_coeff = tmp_buf + (DCAM_SC_COEFF_COEF_SIZE/4);
4412 v_chroma_coeff = v_coeff + (DCAM_SC_COEFF_COEF_SIZE/4);
4414 if (DCAM_PATH_IDX_1 == path_index) {
4415 path = &sc_coeff->dcam_path1;
4416 h_coeff_addr += DCAM_SC1_H_TAB_OFFSET;
4417 v_coeff_addr += DCAM_SC1_V_TAB_OFFSET;
4418 v_chroma_coeff_addr += DCAM_SC1_V_CHROMA_TAB_OFFSET;
4419 clk_switch_bit = BIT_3;
4420 clk_switch_shift_bit = 3;
4421 clk_status_bit = BIT_5;
4422 ver_tap_reg = DCAM_PATH1_CFG;
4423 } else if (DCAM_PATH_IDX_2 == path_index) {
4424 path = &s_p_dcam_mod->dcam_path2;
4425 h_coeff_addr += DCAM_SC2_H_TAB_OFFSET;
4426 v_coeff_addr += DCAM_SC2_V_TAB_OFFSET;
4427 v_chroma_coeff_addr += DCAM_SC2_V_CHROMA_TAB_OFFSET;
4428 clk_switch_bit = BIT_4;
4429 clk_switch_shift_bit = 4;
4430 clk_status_bit = BIT_6;
4431 ver_tap_reg = DCAM_PATH2_CFG;
4434 if (DCAM_YUV420 == path->output_format) {
4438 DCAM_TRACE("DCAM: _dcam_write_sc_coeff {%d %d %d %d}, 420=%d \n",
4439 path->sc_input_size.w,
4440 path->sc_input_size.h,
4441 path->output_size.w,
4442 path->output_size.h, scale2yuv420);
4444 for (i = 0; i < DCAM_SC_COEFF_H_NUM; i++) {
4445 REG_WR(h_coeff_addr, *h_coeff);
4450 for (i = 0; i < DCAM_SC_COEFF_V_NUM; i++) {
4451 REG_WR(v_coeff_addr, *v_coeff);
4456 for (i = 0; i < DCAM_SC_COEFF_V_CHROMA_NUM; i++) {
4457 REG_WR(v_chroma_coeff_addr, *v_chroma_coeff);
4458 v_chroma_coeff_addr += 4;
4462 DCAM_TRACE("DCAM: _dcam_write_sc_coeff E \n");
4467 LOCAL int32_t _dcam_calc_sc_coeff(enum dcam_path_index path_index)
4470 struct dcam_path_desc *path = NULL;
4471 unsigned long h_coeff_addr = DCAM_BASE;
4472 unsigned long v_coeff_addr = DCAM_BASE;
4473 unsigned long v_chroma_coeff_addr = DCAM_BASE;
4474 uint32_t *tmp_buf = NULL;
4475 uint32_t *h_coeff = NULL;
4476 uint32_t *v_coeff = NULL;
4477 uint32_t *v_chroma_coeff = NULL;
4478 uint32_t clk_switch_bit = 0;
4479 uint32_t clk_switch_shift_bit = 0;
4480 uint32_t clk_status_bit = 0;
4481 unsigned long ver_tap_reg = 0;
4482 uint32_t scale2yuv420 = 0;
4486 struct dcam_sc_coeff *sc_coeff;
4488 DCAM_CHECK_ZERO(s_p_dcam_mod);
4489 DCAM_CHECK_ZERO(s_dcam_sc_array);
4491 if (DCAM_PATH_IDX_1 != path_index && DCAM_PATH_IDX_2 != path_index)
4492 return -DCAM_RTN_PARA_ERR;
4494 if (DCAM_PATH_IDX_1 == path_index) {
4495 path = &s_p_dcam_mod->dcam_path1;
4496 h_coeff_addr += DCAM_SC1_H_TAB_OFFSET;
4497 v_coeff_addr += DCAM_SC1_V_TAB_OFFSET;
4498 v_chroma_coeff_addr += DCAM_SC1_V_CHROMA_TAB_OFFSET;
4499 clk_switch_bit = BIT_3;
4500 clk_switch_shift_bit = 3;
4501 clk_status_bit = BIT_5;
4502 ver_tap_reg = DCAM_PATH1_CFG;
4503 } else if (DCAM_PATH_IDX_2 == path_index) {
4504 path = &s_p_dcam_mod->dcam_path2;
4505 h_coeff_addr += DCAM_SC2_H_TAB_OFFSET;
4506 v_coeff_addr += DCAM_SC2_V_TAB_OFFSET;
4507 v_chroma_coeff_addr += DCAM_SC2_V_CHROMA_TAB_OFFSET;
4508 clk_switch_bit = BIT_4;
4509 clk_switch_shift_bit = 4;
4510 clk_status_bit = BIT_6;
4511 ver_tap_reg = DCAM_PATH2_CFG;
4514 if (DCAM_YUV420 == path->output_format) {
4518 DCAM_TRACE("DCAM: _dcam_calc_sc_coeff {%d %d %d %d}, 420=%d \n",
4519 path->sc_input_size.w,
4520 path->sc_input_size.h,
4521 path->output_size.w,
4522 path->output_size.h, scale2yuv420);
4524 down(&s_p_dcam_mod->scale_coeff_mem_sema);
4526 spin_lock_irqsave(&dcam_lock,flag);
4527 tmp_buf = dcam_get_scale_coeff_addr(&index);
4528 if (NULL == tmp_buf) {
4529 _dcam_pop_sc_buf(s_dcam_sc_array, &sc_coeff);
4530 tmp_buf = dcam_get_scale_coeff_addr(&index);
4532 spin_unlock_irqrestore(&dcam_lock,flag);
4534 if (NULL == tmp_buf) {
4535 return -DCAM_RTN_PATH_NO_MEM;
4539 v_coeff = tmp_buf + (DCAM_SC_COEFF_COEF_SIZE/4);
4540 v_chroma_coeff = v_coeff + (DCAM_SC_COEFF_COEF_SIZE/4);
4542 if (!(Dcam_GenScaleCoeff((int16_t)path->sc_input_size.w,
4543 (int16_t)path->sc_input_size.h,
4544 (int16_t)path->output_size.w,
4545 (int16_t)path->output_size.h,
4552 tmp_buf + (DCAM_SC_COEFF_COEF_SIZE*3/4),
4553 DCAM_SC_COEFF_TMP_SIZE))) {
4554 printk("DCAM: _dcam_calc_sc_coeff Dcam_GenScaleCoeff error! \n");
4555 up(&s_p_dcam_mod->scale_coeff_mem_sema);
4556 return -DCAM_RTN_PATH_GEN_COEFF_ERR;
4558 path->scale_tap.y_tap = y_tap;
4559 path->scale_tap.uv_tap = uv_tap;
4560 path->valid_param.scale_tap = 1;
4561 memcpy(&s_dcam_sc_array->scaling_coeff[index].dcam_path1, path, sizeof(struct dcam_path_desc));
4562 spin_lock_irqsave(&dcam_lock,flag);
4563 _dcam_push_sc_buf(s_dcam_sc_array, index);
4564 spin_unlock_irqrestore(&dcam_lock,flag);
4566 up(&s_p_dcam_mod->scale_coeff_mem_sema);
4567 DCAM_TRACE("DCAM: _dcam_calc_sc_coeff E \n");
4569 return DCAM_RTN_SUCCESS;