2 * Copyright (C) 2012 Spreadtrum Communications Inc.
4 * This software is licensed under the terms of the GNU General Public
5 * License version 2, as published by the Free Software Foundation, and
6 * may be copied, distributed, and modified under those terms.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 #include <linux/kernel.h>
14 #include <linux/slab.h>
15 #include <linux/interrupt.h>
16 #include <linux/bitops.h>
17 #include <linux/semaphore.h>
18 #include <linux/delay.h>
19 #include <linux/clk.h>
20 #include <linux/err.h>
22 #include <linux/kthread.h>
23 #include <soc/sprd/hardware.h>
24 #include <mach/irqs.h>
25 #include <soc/sprd/sci.h>
26 #include <soc/sprd/sci_glb_regs.h>
27 #include <linux/vmalloc.h>
28 #include <linux/videodev2.h>
29 #include <linux/wakelock.h>
31 #include "gen_scale_coef.h"
36 //#define DCAM_DRV_DEBUG
37 #define DCAM_LOWEST_ADDR 0x800
38 #define DCAM_ADDR_INVALID(addr) ((uint32_t)(addr) < DCAM_LOWEST_ADDR)
39 #define DCAM_YUV_ADDR_INVALID(y,u,v) \
40 (DCAM_ADDR_INVALID(y) && \
41 DCAM_ADDR_INVALID(u) && \
44 #define DCAM_SC1_H_TAB_OFFSET 0x400
45 #define DCAM_SC1_V_TAB_OFFSET 0x4F0
46 #define DCAM_SC1_V_CHROMA_TAB_OFFSET 0x8F0
48 #define DCAM_SC2_H_TAB_OFFSET 0x1400
49 #define DCAM_SC2_V_TAB_OFFSET 0x14F0
50 #define DCAM_SC2_V_CHROMA_TAB_OFFSET 0x18F0
52 #define DCAM_SC_COEFF_BUF_SIZE (24 << 10)
53 #define DCAM_SC_COEFF_COEF_SIZE (1 << 10)
54 #define DCAM_SC_COEFF_TMP_SIZE (21 << 10)
55 #define DCAM_SC_COEFF_BUF_COUNT 2
58 #define DCAM_SC_H_COEF_SIZE (0xC0)
59 #define DCAM_SC_V_COEF_SIZE (0x210)
60 #define DCAM_SC_V_CHROM_COEF_SIZE (0x210)
62 #define DCAM_SC_COEFF_H_NUM (DCAM_SC_H_COEF_SIZE/4)
63 #define DCAM_SC_COEFF_V_NUM (DCAM_SC_V_COEF_SIZE/4)
64 #define DCAM_SC_COEFF_V_CHROMA_NUM (DCAM_SC_V_CHROM_COEF_SIZE/4)
66 #define DCAM_AXI_STOP_TIMEOUT 1000
67 #define DCAM_CLK_DOMAIN_AHB 1
68 #define DCAM_CLK_DOMAIN_DCAM 0
71 #define DCAM_PATH_TIMEOUT msecs_to_jiffies(500*10)
73 #define DCAM_PATH_TIMEOUT msecs_to_jiffies(500)
76 #define DCAM_FRM_QUEUE_LENGTH 4
78 #define DCAM_STATE_QUICKQUIT 0x01
80 #define DCAM_CHECK_PARAM_ZERO_POINTER(n) \
83 return -DCAM_RTN_PARA_ERR; \
86 #define DCAM_CLEAR(a) \
88 memset((void *)(a), 0, sizeof(*(a))); \
91 #define DEBUG_STR "Error L %d, %s \n"
92 #define DEBUG_ARGS __LINE__,__FUNCTION__
93 #define DCAM_RTN_IF_ERR \
96 printk(DEBUG_STR, DEBUG_ARGS); \
101 #define DCAM_IRQ_LINE_MASK 0x001FFFFFUL
103 typedef void (*dcam_isr)(void);
107 DCAM_FRM_LOCK_WRITE = 0x10011001,
108 DCAM_FRM_LOCK_READ = 0x01100110
116 #define DCAM_IRQ_ERR_MASK \
117 ((1 << DCAM_PATH0_OV) | (1 << DCAM_PATH1_OV) | (1 << DCAM_PATH2_OV) | \
118 (1 << DCAM_SN_LINE_ERR) | (1 << DCAM_SN_FRAME_ERR) | \
119 (1 << DCAM_ISP_OV) | (1 << DCAM_MIPI_OV))
121 #define DCAM_IRQ_JPEG_OV_MASK (1 << DCAM_JPEG_BUF_OV)
123 #define DCAM_CHECK_ZERO(a) \
125 if (DCAM_ADDR_INVALID(a)) { \
126 printk("DCAM, zero pointer \n"); \
127 printk(DEBUG_STR, DEBUG_ARGS); \
132 #define DCAM_CHECK_ZERO_VOID(a) \
134 if (DCAM_ADDR_INVALID(a)) { \
135 printk("DCAM, zero pointer \n"); \
136 printk(DEBUG_STR, DEBUG_ARGS); \
141 struct dcam_cap_desc {
143 uint32_t input_format;
144 uint32_t frame_deci_factor;
145 uint32_t img_x_deci_factor;
146 uint32_t img_y_deci_factor;
149 struct dcam_path_valid {
150 uint32_t input_size :1;
151 uint32_t input_rect :1;
152 uint32_t output_size :1;
153 uint32_t output_format :1;
155 uint32_t data_endian :1;
156 uint32_t frame_deci :1;
157 uint32_t scale_tap :1;
161 struct dcam_frm_queue {
162 struct dcam_frame frm_array[DCAM_FRM_QUEUE_LENGTH];
166 struct dcam_buf_queue {
167 struct dcam_frame frame[DCAM_FRM_CNT_MAX];
168 struct dcam_frame *write;
169 struct dcam_frame *read;
173 struct dcam_path_desc {
174 struct dcam_size input_size;
175 struct dcam_rect input_rect;
176 struct dcam_size sc_input_size;
177 struct dcam_size output_size;
178 struct dcam_frame input_frame;
179 struct dcam_frm_queue frame_queue;
180 struct dcam_buf_queue buf_queue;
181 //struct dcam_frame *output_frame_head;
182 //struct dcam_frame *output_frame_cur;
183 struct dcam_endian_sel data_endian;
184 struct dcam_sc_tap scale_tap;
185 struct dcam_deci deci_val;
186 struct dcam_path_valid valid_param;
187 uint32_t frame_base_id;
188 uint32_t output_frame_count;
189 uint32_t output_format;
195 struct semaphore tx_done_sema;
196 struct semaphore sof_sema;
197 uint32_t wait_for_done;
199 uint32_t wait_for_sof;
207 uint32_t module_addr;
208 struct dcam_cap_desc dcam_cap;
209 struct dcam_path_desc dcam_path0;
210 struct dcam_path_desc dcam_path1;
211 struct dcam_path_desc dcam_path2;
212 struct dcam_frame path0_frame[DCAM_PATH_0_FRM_CNT_MAX];
213 struct dcam_frame path1_frame[DCAM_PATH_1_FRM_CNT_MAX];
214 struct dcam_frame path2_frame[DCAM_PATH_2_FRM_CNT_MAX];
215 struct dcam_frame path0_reserved_frame;
216 struct dcam_frame path1_reserved_frame;
217 struct dcam_frame path2_reserved_frame;
218 struct semaphore stop_sema;
220 struct semaphore resize_done_sema;
221 uint32_t wait_resize_done;
222 struct semaphore rotation_done_sema;
223 uint32_t wait_rotation_done;
224 uint32_t err_happened;
225 struct semaphore scale_coeff_mem_sema;
229 struct dcam_sc_coeff {
230 uint32_t buf[DCAM_SC_COEFF_BUF_SIZE];
232 struct dcam_path_desc dcam_path1;
235 struct dcam_sc_array {
236 struct dcam_sc_coeff scaling_coeff[DCAM_SC_COEFF_BUF_COUNT];
237 struct dcam_sc_coeff *scaling_coeff_queue[DCAM_SC_COEFF_BUF_COUNT];
239 uint32_t is_smooth_zoom;
242 LOCAL atomic_t s_dcam_users = ATOMIC_INIT(0);
243 LOCAL atomic_t s_resize_flag = ATOMIC_INIT(0);
244 LOCAL atomic_t s_rotation_flag = ATOMIC_INIT(0);
245 LOCAL struct clk* s_dcam_clk = NULL;
246 LOCAL struct dcam_module* s_p_dcam_mod = 0;
247 LOCAL uint32_t s_dcam_irq = 0x5A0000A5;
248 LOCAL dcam_isr_func s_user_func[DCAM_IRQ_NUMBER];
249 LOCAL void* s_user_data[DCAM_IRQ_NUMBER];
250 LOCAL struct dcam_sc_array* s_dcam_sc_array = NULL;
251 LOCAL struct wake_lock dcam_wakelock;
253 LOCAL DEFINE_MUTEX(dcam_sem);
254 LOCAL DEFINE_MUTEX(dcam_scale_sema);
255 LOCAL DEFINE_MUTEX(dcam_rot_sema);
256 LOCAL DEFINE_MUTEX(dcam_module_sema);
257 LOCAL DEFINE_SPINLOCK(dcam_mod_lock);
258 LOCAL DEFINE_SPINLOCK(dcam_lock);
259 LOCAL DEFINE_SPINLOCK(dcam_glb_reg_cfg_lock);
260 LOCAL DEFINE_SPINLOCK(dcam_glb_reg_control_lock);
261 LOCAL DEFINE_SPINLOCK(dcam_glb_reg_mask_lock);
262 LOCAL DEFINE_SPINLOCK(dcam_glb_reg_clr_lock);
263 LOCAL DEFINE_SPINLOCK(dcam_glb_reg_ahbm_sts_lock);
264 LOCAL DEFINE_SPINLOCK(dcam_glb_reg_endian_lock);
266 LOCAL void _dcam_path0_set(void);
267 LOCAL void _dcam_path1_set(struct dcam_path_desc *path);
268 LOCAL void _dcam_path2_set(void);
269 LOCAL void _dcam_frm_clear(enum dcam_path_index path_index);
270 LOCAL void _dcam_link_frm(uint32_t base_id);
271 LOCAL int32_t _dcam_path_set_next_frm(enum dcam_path_index path_index, uint32_t is_1st_frm);
272 /*LOCAL int32_t _dcam_path_trim(enum dcam_path_index path_index);*/
273 LOCAL int32_t _dcam_path_scaler(enum dcam_path_index path_index);
274 LOCAL int32_t _dcam_calc_sc_size(enum dcam_path_index path_index);
275 LOCAL int32_t _dcam_set_sc_coeff(enum dcam_path_index path_index);
276 LOCAL void _dcam_force_copy_ext(enum dcam_path_index path_index, uint32_t path_copy, uint32_t coef_copy);
277 LOCAL void _dcam_auto_copy_ext(enum dcam_path_index path_index, uint32_t path_copy, uint32_t coef_copy);
278 LOCAL void _dcam_force_copy(enum dcam_path_index path_index);
279 LOCAL void _dcam_auto_copy(enum dcam_path_index path_index);
280 LOCAL void _dcam_reg_trace(void);
281 /*LOCAL void _dcam_sensor_sof(void);*/
282 LOCAL void _dcam_sensor_eof(void);
283 LOCAL void _dcam_cap_sof(void);
284 LOCAL void _dcam_cap_eof(void);
285 LOCAL void _dcam_path0_done(void);
286 LOCAL void _dcam_path0_overflow(void);
287 LOCAL void _dcam_path1_done(void);
288 LOCAL void _dcam_path1_overflow(void);
289 LOCAL void _dcam_sensor_line_err(void);
290 LOCAL void _dcam_sensor_frame_err(void);
291 LOCAL void _dcam_jpeg_buf_ov(void);
292 LOCAL void _dcam_path2_done(void);
293 LOCAL void _dcam_path2_ov(void);
294 LOCAL void _dcam_isp_ov(void);
295 LOCAL void _dcam_mipi_ov(void);
296 LOCAL void _dcam_path1_slice_done(void);
297 LOCAL void _dcam_path2_slice_done(void);
298 LOCAL void _dcam_raw_slice_done(void);
299 LOCAL void _dcam_path1_sof(void);
300 LOCAL void _dcam_path2_sof(void);
301 LOCAL irqreturn_t _dcam_isr_root(int irq, void *dev_id);
302 LOCAL void _dcam_stopped_notice(void);
303 LOCAL void _dcam_stopped(void);
304 LOCAL int32_t _dcam_path_check_deci(enum dcam_path_index path_index, uint32_t *is_deci);
305 extern void _dcam_isp_root(void);
306 LOCAL int _dcam_internal_init(void);
307 LOCAL void _dcam_internal_deinit(void);
308 LOCAL void _dcam_wait_path_done(enum dcam_path_index path_index, uint32_t *p_flag);
309 LOCAL void _dcam_path_done_notice(enum dcam_path_index path_index);
310 LOCAL void _dcam_rot_done(void);
311 LOCAL int32_t _dcam_err_pre_proc(void);
312 LOCAL void _dcam_frm_queue_clear(struct dcam_frm_queue *queue);
313 LOCAL int32_t _dcam_frame_enqueue(struct dcam_frm_queue *queue, struct dcam_frame *frame);
314 LOCAL int32_t _dcam_frame_dequeue(struct dcam_frm_queue *queue, struct dcam_frame *frame);
315 LOCAL void _dcam_buf_queue_init(struct dcam_buf_queue *queue);
316 LOCAL int32_t _dcam_buf_queue_write(struct dcam_buf_queue *queue, struct dcam_frame *frame);
317 LOCAL int32_t _dcam_buf_queue_read(struct dcam_buf_queue *queue, struct dcam_frame *frame);
318 LOCAL void _dcam_wait_update_done(enum dcam_path_index path_index, uint32_t *p_flag);
319 LOCAL void _dcam_path_updated_notice(enum dcam_path_index path_index);
320 LOCAL int32_t _dcam_get_valid_sc_coeff(struct dcam_sc_array *sc, struct dcam_sc_coeff **sc_coeff);
321 LOCAL int32_t _dcam_push_sc_buf(struct dcam_sc_array *sc, uint32_t index);
322 LOCAL int32_t _dcam_pop_sc_buf(struct dcam_sc_array *sc, struct dcam_sc_coeff **sc_coeff);
323 LOCAL int32_t _dcam_calc_sc_coeff(enum dcam_path_index path_index);
324 LOCAL int32_t _dcam_write_sc_coeff(enum dcam_path_index path_index);
325 LOCAL void _dcam_wait_for_quickstop(enum dcam_path_index path_index);
327 LOCAL const dcam_isr isr_list[DCAM_IRQ_NUMBER] = {
328 NULL,//_dcam_isp_root,
333 _dcam_path0_overflow,
335 _dcam_path1_overflow,
338 _dcam_sensor_line_err,
339 _dcam_sensor_frame_err,
344 _dcam_path1_slice_done,
345 _dcam_path2_slice_done,
346 _dcam_raw_slice_done,
351 void dcam_glb_reg_awr(uint32_t addr, uint32_t val, uint32_t reg_id)
357 spin_lock_irqsave(&dcam_glb_reg_cfg_lock, flag);
358 REG_WR(addr, REG_RD(addr) & (val));
359 spin_unlock_irqrestore(&dcam_glb_reg_cfg_lock, flag);
361 case DCAM_CONTROL_REG:
362 spin_lock_irqsave(&dcam_glb_reg_control_lock, flag);
363 REG_WR(addr, REG_RD(addr) & (val));
364 spin_unlock_irqrestore(&dcam_glb_reg_control_lock, flag);
366 case DCAM_INIT_MASK_REG:
367 spin_lock_irqsave(&dcam_glb_reg_mask_lock, flag);
368 REG_WR(addr, REG_RD(addr) & (val));
369 spin_unlock_irqrestore(&dcam_glb_reg_mask_lock, flag);
371 case DCAM_INIT_CLR_REG:
372 spin_lock_irqsave(&dcam_glb_reg_clr_lock, flag);
373 REG_WR(addr, REG_RD(addr) & (val));
374 spin_unlock_irqrestore(&dcam_glb_reg_clr_lock, flag);
376 case DCAM_AHBM_STS_REG:
377 spin_lock_irqsave(&dcam_glb_reg_ahbm_sts_lock, flag);
378 REG_WR(addr, REG_RD(addr) & (val));
379 spin_unlock_irqrestore(&dcam_glb_reg_ahbm_sts_lock, flag);
381 case DCAM_ENDIAN_REG:
382 spin_lock_irqsave(&dcam_glb_reg_endian_lock, flag);
383 REG_WR(addr, REG_RD(addr) & (val));
384 spin_unlock_irqrestore(&dcam_glb_reg_endian_lock, flag);
387 REG_WR(addr, REG_RD(addr) & (val));
392 void dcam_glb_reg_owr(uint32_t addr, uint32_t val, uint32_t reg_id)
398 spin_lock_irqsave(&dcam_glb_reg_cfg_lock, flag);
399 REG_WR(addr, REG_RD(addr) | (val));
400 spin_unlock_irqrestore(&dcam_glb_reg_cfg_lock, flag);
402 case DCAM_CONTROL_REG:
403 spin_lock_irqsave(&dcam_glb_reg_control_lock, flag);
404 REG_WR(addr, REG_RD(addr) | (val));
405 spin_unlock_irqrestore(&dcam_glb_reg_control_lock, flag);
407 case DCAM_INIT_MASK_REG:
408 spin_lock_irqsave(&dcam_glb_reg_mask_lock, flag);
409 REG_WR(addr, REG_RD(addr) | (val));
410 spin_unlock_irqrestore(&dcam_glb_reg_mask_lock, flag);
412 case DCAM_INIT_CLR_REG:
413 spin_lock_irqsave(&dcam_glb_reg_clr_lock, flag);
414 REG_WR(addr, REG_RD(addr) | (val));
415 spin_unlock_irqrestore(&dcam_glb_reg_clr_lock, flag);
417 case DCAM_AHBM_STS_REG:
418 spin_lock_irqsave(&dcam_glb_reg_ahbm_sts_lock, flag);
419 REG_WR(addr, REG_RD(addr) | (val));
420 spin_unlock_irqrestore(&dcam_glb_reg_ahbm_sts_lock, flag);
422 case DCAM_ENDIAN_REG:
423 spin_lock_irqsave(&dcam_glb_reg_endian_lock, flag);
424 REG_WR(addr, REG_RD(addr) | (val));
425 spin_unlock_irqrestore(&dcam_glb_reg_endian_lock, flag);
428 REG_WR(addr, REG_RD(addr) | (val));
433 void dcam_glb_reg_mwr(uint32_t addr, uint32_t mask, uint32_t val, uint32_t reg_id)
440 spin_lock_irqsave(&dcam_glb_reg_cfg_lock, flag);
444 REG_WR(addr, tmp | ((mask) & (val)));
446 spin_unlock_irqrestore(&dcam_glb_reg_cfg_lock, flag);
448 case DCAM_CONTROL_REG:
449 spin_lock_irqsave(&dcam_glb_reg_control_lock, flag);
453 REG_WR(addr, tmp | ((mask) & (val)));
455 spin_unlock_irqrestore(&dcam_glb_reg_control_lock, flag);
457 case DCAM_INIT_MASK_REG:
458 spin_lock_irqsave(&dcam_glb_reg_mask_lock, flag);
462 REG_WR(addr, tmp | ((mask) & (val)));
464 spin_unlock_irqrestore(&dcam_glb_reg_mask_lock, flag);
466 case DCAM_INIT_CLR_REG:
467 spin_lock_irqsave(&dcam_glb_reg_clr_lock, flag);
471 REG_WR(addr, tmp | ((mask) & (val)));
473 spin_unlock_irqrestore(&dcam_glb_reg_clr_lock, flag);
475 case DCAM_AHBM_STS_REG:
476 spin_lock_irqsave(&dcam_glb_reg_ahbm_sts_lock, flag);
480 REG_WR(addr, tmp | ((mask) & (val)));
482 spin_unlock_irqrestore(&dcam_glb_reg_ahbm_sts_lock, flag);
484 case DCAM_ENDIAN_REG:
485 spin_lock_irqsave(&dcam_glb_reg_endian_lock, flag);
489 REG_WR(addr, tmp | ((mask) & (val)));
491 spin_unlock_irqrestore(&dcam_glb_reg_endian_lock, flag);
497 REG_WR(addr, tmp | ((mask) & (val)));
503 int32_t dcam_module_init(enum dcam_cap_if_mode if_mode,
504 enum dcam_cap_sensor_mode sn_mode)
506 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
507 struct dcam_cap_desc *cap_desc = NULL;
509 if (if_mode >= DCAM_CAP_IF_MODE_MAX) {
510 rtn = -DCAM_RTN_CAP_IF_MODE_ERR;
512 if (sn_mode >= DCAM_CAP_MODE_MAX) {
513 rtn = -DCAM_RTN_CAP_SENSOR_MODE_ERR;
515 _dcam_internal_init();
516 _dcam_link_frm(0); /* set default base frame index as 0 */
517 _dcam_buf_queue_init(&s_p_dcam_mod->dcam_path0.buf_queue);
518 _dcam_buf_queue_init(&s_p_dcam_mod->dcam_path1.buf_queue);
519 _dcam_buf_queue_init(&s_p_dcam_mod->dcam_path2.buf_queue);
520 cap_desc = &s_p_dcam_mod->dcam_cap;
521 cap_desc->interface = if_mode;
522 cap_desc->input_format = sn_mode;
523 /*REG_OWR(DCAM_EB, BIT_13);//MM_EB*/
524 /*REG_OWR(DCAM_MATRIX_EB, BIT_10|BIT_5);*/
525 if (DCAM_CAP_IF_CSI2 == if_mode) {
526 /* REG_OWR(CSI2_DPHY_EB, MIPI_EB_BIT);*/
527 //ret = _dcam_mipi_clk_en();
528 dcam_glb_reg_owr(DCAM_CFG, BIT_9, DCAM_CFG_REG);
529 REG_MWR(CAP_MIPI_CTRL, BIT_2 | BIT_1, sn_mode << 1);
531 /*REG_OWR(DCAM_EB, CCIR_IN_EB_BIT);
532 REG_OWR(DCAM_EB, CCIR_EB_BIT);*/
533 //ret = _dcam_ccir_clk_en();
534 dcam_glb_reg_mwr(DCAM_CFG, BIT_9, 0 << 9, DCAM_CFG_REG);
535 REG_MWR(CAP_CCIR_CTRL, BIT_2 | BIT_1, sn_mode << 1);
537 rtn = DCAM_RTN_SUCCESS;
544 int32_t dcam_module_deinit(enum dcam_cap_if_mode if_mode,
545 enum dcam_cap_sensor_mode sn_mode)
547 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
549 if (DCAM_CAP_IF_CSI2 == if_mode) {
550 /*REG_MWR(CSI2_DPHY_EB, MIPI_EB_BIT, 0 << 10);*/
551 dcam_glb_reg_mwr(DCAM_CFG, BIT_9, 0 << 9, DCAM_CFG_REG);
552 //_dcam_mipi_clk_dis();
554 /*REG_MWR(DCAM_EB, CCIR_IN_EB_BIT, 0 << 2);
555 REG_MWR(DCAM_EB, CCIR_EB_BIT, 0 << 9);*/
556 dcam_glb_reg_mwr(DCAM_CFG, BIT_9, 0 << 9, DCAM_CFG_REG);
557 //_dcam_ccir_clk_dis();
560 _dcam_internal_deinit();
565 int dcam_scale_coeff_alloc(void)
569 if (NULL == s_dcam_sc_array) {
570 s_dcam_sc_array = (struct dcam_sc_array*)vzalloc(sizeof(struct dcam_sc_array));
571 if (NULL == s_dcam_sc_array) {
572 printk("DCAM: _dcam_scale_coeff_alloc fail.\n");
580 void dcam_scale_coeff_free(void)
582 if (s_dcam_sc_array) {
583 vfree(s_dcam_sc_array);
584 s_dcam_sc_array = NULL;
588 LOCAL uint32_t *dcam_get_scale_coeff_addr(uint32_t *index)
592 if (DCAM_ADDR_INVALID(s_dcam_sc_array)) {
593 printk("DCAM: scale addr, invalid param 0x%x \n",
594 (uint32_t)s_dcam_sc_array);
598 for (i = 0; i < DCAM_SC_COEFF_BUF_COUNT; i++) {
599 if (0 == s_dcam_sc_array->scaling_coeff[i].flag) {
601 DCAM_TRACE("dcam: get buf index %d \n", i);
602 return s_dcam_sc_array->scaling_coeff[i].buf;
605 printk("dcam: get buf index %d \n", i);
610 int32_t dcam_module_en(struct device_node *dn)
613 unsigned int irq_no = 0;
615 DCAM_TRACE("DCAM: dcam_module_en, In %d \n", s_dcam_users.counter);
617 mutex_lock(&dcam_module_sema);
618 if (atomic_inc_return(&s_dcam_users) == 1) {
620 wake_lock_init(&dcam_wakelock, WAKE_LOCK_SUSPEND,
621 "pm_message_wakelock_dcam");
623 wake_lock(&dcam_wakelock);
625 ret = clk_mm_i_eb(dn,1);
631 ret = dcam_set_clk(dn,DCAM_CLK_256M);
638 parse_baseaddress(dn);
640 dcam_reset(DCAM_RST_ALL, 0);
641 atomic_set(&s_resize_flag, 0);
642 atomic_set(&s_rotation_flag, 0);
643 memset((void*)s_user_func, 0, sizeof(s_user_func));
644 memset((void*)s_user_data, 0, sizeof(s_user_data));
645 printk("DCAM: register isr, 0x%x \n", REG_RD(DCAM_INT_MASK));
647 irq_no = parse_irq(dn);
648 printk("DCAM: irq_no = 0x%x \n", irq_no);
649 ret = request_irq(irq_no,
655 printk("DCAM: dcam_start, error %d \n", ret);
656 dcam_set_clk(dn,DCAM_CLK_NONE);
662 DCAM_TRACE("DCAM: dcam_module_en end \n");
664 DCAM_TRACE("DCAM: dcam_module_en, Out %d \n", s_dcam_users.counter);
665 mutex_unlock(&dcam_module_sema);
669 wake_unlock(&dcam_wakelock);
670 wake_lock_destroy(&dcam_wakelock);
671 atomic_dec(&s_dcam_users);
672 mutex_unlock(&dcam_module_sema);
676 int32_t dcam_module_dis(struct device_node *dn)
678 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
680 unsigned int irq_no = 0;
682 DCAM_TRACE("DCAM: dcam_module_dis, In %d \n", s_dcam_users.counter);
684 mutex_lock(&dcam_module_sema);
685 if (atomic_dec_return(&s_dcam_users) == 0) {
687 sci_glb_clr(DCAM_EB, DCAM_EB_BIT);
688 dcam_set_clk(dn,DCAM_CLK_NONE);
689 printk("DCAM: un register isr \n");
690 irq_no = parse_irq(dn);
691 free_irq(irq_no, (void*)&s_dcam_irq);
692 ret = clk_mm_i_eb(dn,0);
696 wake_unlock(&dcam_wakelock);
697 wake_lock_destroy(&dcam_wakelock);
700 DCAM_TRACE("DCAM: dcam_module_dis, Out %d \n", s_dcam_users.counter);
701 mutex_unlock(&dcam_module_sema);
706 int32_t dcam_reset(enum dcam_rst_mode reset_mode, uint32_t is_isr)
708 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
709 uint32_t time_out = 0;
711 DCAM_TRACE("DCAM: reset: %d \n", reset_mode);
714 mutex_lock(&dcam_scale_sema);
715 mutex_lock(&dcam_rot_sema);
718 if (DCAM_RST_ALL == reset_mode) {
719 if (atomic_read(&s_dcam_users)) {
720 /* firstly, stop AXI writing */
721 dcam_glb_reg_owr(DCAM_AHBM_STS, BIT_6, DCAM_AHBM_STS_REG);
724 /* then wait for AHB busy cleared */
725 while (++time_out < DCAM_AXI_STOP_TIMEOUT) {
726 if (0 == (REG_RD(DCAM_AHBM_STS) & BIT_0))
729 if (time_out >= DCAM_AXI_STOP_TIMEOUT) {
730 printk("DCAM: reset TO: %d \n", time_out);
731 return DCAM_RTN_TIMEOUT;
735 /* do reset action */
736 switch (reset_mode) {
738 sci_glb_set(DCAM_RST, PATH0_RST_BIT);
739 sci_glb_clr(DCAM_RST, PATH0_RST_BIT);
740 DCAM_TRACE("DCAM: reset path0 \n");
744 sci_glb_set(DCAM_RST, PATH1_RST_BIT);
745 sci_glb_clr(DCAM_RST, PATH1_RST_BIT);
746 DCAM_TRACE("DCAM: reset path1 \n");
750 sci_glb_set(DCAM_RST, PATH2_RST_BIT);
751 sci_glb_clr(DCAM_RST, PATH2_RST_BIT);
752 DCAM_TRACE("DCAM: reset path2 \n");
756 sci_glb_set(DCAM_RST, DCAM_MOD_RST_BIT | CCIR_RST_BIT);
757 sci_glb_clr(DCAM_RST, DCAM_MOD_RST_BIT | CCIR_RST_BIT);
758 dcam_glb_reg_owr(DCAM_INT_CLR,
761 dcam_glb_reg_owr(DCAM_INT_MASK,
764 printk("DCAM: reset all \n");
767 rtn = DCAM_RTN_PARA_ERR;
771 if (DCAM_RST_ALL == reset_mode) {
772 if (atomic_read(&s_dcam_users)) {
773 /* the end, enable AXI writing */
774 dcam_glb_reg_awr(DCAM_AHBM_STS, ~BIT_6, DCAM_AHBM_STS_REG);
779 mutex_unlock(&dcam_rot_sema);
780 mutex_unlock(&dcam_scale_sema);
783 DCAM_TRACE("DCAM: reset_mode=%x end \n", reset_mode);
788 int32_t dcam_set_clk(struct device_node *dn, enum dcam_clk_sel clk_sel)
790 #ifdef CONFIG_SC_FPGA_CLK
793 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
794 struct clk *clk_parent;
795 char *parent = "clk_312m";
809 parent = "clk_76p8m";
812 printk("DCAM close CLK %d \n", (int)clk_get_rate(s_dcam_clk));
814 clk_disable(s_dcam_clk);
824 if (NULL == s_dcam_clk) {
825 s_dcam_clk = parse_clk(dn,"clk_dcam");
826 if (IS_ERR(s_dcam_clk)) {
827 printk("DCAM: clk_get fail, %d \n", (int)s_dcam_clk);
830 DCAM_TRACE("DCAM: get clk_parent ok \n");
833 clk_disable(s_dcam_clk);
836 clk_parent = clk_get(NULL, parent);
837 if (IS_ERR(clk_parent)) {
838 printk("DCAM: dcam_set_clk fail, %d \n", (int)clk_parent);
841 DCAM_TRACE("DCAM: get clk_parent ok \n");
844 ret = clk_set_parent(s_dcam_clk, clk_parent);
846 printk("DCAM: clk_set_parent fail, %d \n", ret);
849 ret = clk_enable(s_dcam_clk);
851 printk("enable dcam clk error.\n");
858 int32_t dcam_update_path(enum dcam_path_index path_index, struct dcam_size *in_size,
859 struct dcam_rect *in_rect, struct dcam_size *out_size)
861 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
863 uint32_t is_deci = 0;
865 DCAM_CHECK_ZERO(s_p_dcam_mod);
866 DCAM_CHECK_ZERO(s_dcam_sc_array);
868 if ((DCAM_PATH_IDX_1 & path_index) && s_p_dcam_mod->dcam_path1.valide) {
869 rtn = dcam_path1_cfg(DCAM_PATH_INPUT_SIZE, in_size);
871 rtn = dcam_path1_cfg(DCAM_PATH_INPUT_RECT, in_rect);
873 rtn = dcam_path1_cfg(DCAM_PATH_OUTPUT_SIZE, out_size);
875 rtn = _dcam_path_check_deci(DCAM_PATH_IDX_1, &is_deci);
877 DCAM_TRACE("DCAM: To update path1 \n");
878 rtn = _dcam_path_scaler(DCAM_PATH_IDX_1);
880 DCAM_TRACE("DCAM: dcam_update_path 1 \n");
881 if (s_dcam_sc_array->is_smooth_zoom) {
882 spin_lock_irqsave(&dcam_lock, flags);
883 s_p_dcam_mod->dcam_path1.is_update = 1;
884 spin_unlock_irqrestore(&dcam_lock, flags);
886 _dcam_wait_update_done(DCAM_PATH_IDX_1, &s_p_dcam_mod->dcam_path1.is_update);
888 if (!s_dcam_sc_array->is_smooth_zoom) {
889 _dcam_wait_update_done(DCAM_PATH_IDX_1, NULL);
893 if ((DCAM_PATH_IDX_2 & path_index) && s_p_dcam_mod->dcam_path2.valide) {
894 local_irq_save(flags);
895 if(s_p_dcam_mod->dcam_path2.is_update){
896 local_irq_restore(flags);
897 DCAM_TRACE("DCAM: dcam_update_path 2: updating return \n");
900 local_irq_restore(flags);
902 rtn = dcam_path2_cfg(DCAM_PATH_INPUT_SIZE, in_size);
904 rtn = dcam_path2_cfg(DCAM_PATH_INPUT_RECT, in_rect);
906 rtn = dcam_path2_cfg(DCAM_PATH_OUTPUT_SIZE, out_size);
909 rtn = _dcam_path_scaler(DCAM_PATH_IDX_2);
912 local_irq_save(flags);
913 s_p_dcam_mod->dcam_path2.is_update = 1;
914 local_irq_restore(flags);
917 DCAM_TRACE("DCAM: dcam_update_path: done \n");
922 int32_t dcam_start_path(enum dcam_path_index path_index)
924 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
927 DCAM_CHECK_ZERO(s_p_dcam_mod);
929 DCAM_TRACE("DCAM: start_path: path %d, mode %x path 0,1,2 {%d %d %d} \n",
931 s_p_dcam_mod->dcam_mode,
932 s_p_dcam_mod->dcam_path0.valide,
933 s_p_dcam_mod->dcam_path1.valide,
934 s_p_dcam_mod->dcam_path2.valide);
936 dcam_glb_reg_owr(DCAM_AHBM_STS, BIT_8, DCAM_AHBM_STS_REG); // aiden add: write arbit mode
938 cap_en = REG_RD(DCAM_CONTROL) & BIT_2;
939 DCAM_TRACE("DCAM: cap_eb %d \n", cap_en);
940 if ((DCAM_PATH_IDX_0 & path_index) && s_p_dcam_mod->dcam_path0.valide) {
942 rtn = _dcam_path_set_next_frm(DCAM_PATH_IDX_0, true);
945 /* if cap is already open, the sequence is:
946 cap force copy -> path 0 enable -> cap auto copy */
947 dcam_glb_reg_mwr(DCAM_CONTROL, BIT_0, 1 << 0, DCAM_CONTROL_REG); /* Cap force copy */
948 dcam_glb_reg_owr(DCAM_CFG, BIT_0, DCAM_CFG_REG); /* Enable Path 0 */
949 dcam_glb_reg_mwr(DCAM_CONTROL, BIT_1, 1 << 1, DCAM_CONTROL_REG); /* Cap auto copy, trigger path 0 enable */
951 dcam_glb_reg_owr(DCAM_CFG, BIT_0, DCAM_CFG_REG); /* Enable Path 0 */
955 if ((DCAM_PATH_IDX_1 & path_index) && s_p_dcam_mod->dcam_path1.valide) {
957 //rtn = _dcam_path_trim(DCAM_PATH_IDX_1);
959 rtn = _dcam_path_scaler(DCAM_PATH_IDX_1);
962 _dcam_path1_set(&s_p_dcam_mod->dcam_path1);
963 DCAM_TRACE("DCAM: start path: path_control=%x \n", REG_RD(DCAM_CONTROL));
965 rtn = _dcam_path_set_next_frm(DCAM_PATH_IDX_1, true);
967 _dcam_force_copy_ext(DCAM_PATH_IDX_1, true, true);
968 DCAM_TRACE("DCAM: int= %x \n", REG_RD(DCAM_INT_STS));
969 dcam_glb_reg_owr(DCAM_CFG, BIT_1, DCAM_CFG_REG);
972 if ((DCAM_PATH_IDX_2 & path_index) && s_p_dcam_mod->dcam_path2.valide) {
973 rtn = _dcam_path_scaler(DCAM_PATH_IDX_2);
978 rtn = _dcam_path_set_next_frm(DCAM_PATH_IDX_2, true);
980 _dcam_force_copy_ext(DCAM_PATH_IDX_2, true, true);
981 dcam_glb_reg_owr(DCAM_CFG, BIT_2, DCAM_CFG_REG);
984 printk("DCAM PATH S: %d \n", path_index);
988 REG_MWR(CAP_CCIR_FRM_CTRL, BIT_5 | BIT_4, 1 << 4);
989 REG_MWR(CAP_MIPI_FRM_CTRL, BIT_5 | BIT_4, 1 << 4);
991 dcam_glb_reg_mwr(DCAM_CONTROL, BIT_0, 1 << 0, DCAM_CONTROL_REG); /* Cap force copy */
992 //REG_MWR(DCAM_CONTROL, BIT_1, 1 << 1); /* Cap auto copy */
993 dcam_glb_reg_mwr(DCAM_CONTROL, BIT_2, 1 << 2, DCAM_CONTROL_REG); /* Cap Enable */
995 if ((DCAM_PATH_IDX_0 & path_index) && s_p_dcam_mod->dcam_path0.valide) {
996 rtn = _dcam_path_set_next_frm(DCAM_PATH_IDX_0, false);
998 _dcam_auto_copy(DCAM_PATH_IDX_0);
999 s_p_dcam_mod->dcam_path0.status = DCAM_ST_START;
1003 if ((DCAM_PATH_IDX_1 & path_index) && s_p_dcam_mod->dcam_path1.valide) {
1004 s_p_dcam_mod->dcam_path1.need_wait = 0;
1005 s_p_dcam_mod->dcam_path1.status = DCAM_ST_START;
1008 if ((DCAM_PATH_IDX_2 & path_index) && s_p_dcam_mod->dcam_path2.valide) {
1009 s_p_dcam_mod->dcam_path2.need_wait = 0;
1010 s_p_dcam_mod->dcam_path2.status = DCAM_ST_START;
1013 if (DCAM_PATH_IDX_ALL != path_index) {
1014 if ((DCAM_PATH_IDX_0 & path_index)) {
1015 _dcam_wait_path_done(DCAM_PATH_IDX_0, NULL);
1016 } else if ((DCAM_PATH_IDX_1 & path_index)) {
1017 _dcam_wait_path_done(DCAM_PATH_IDX_1, NULL);
1018 } else if ((DCAM_PATH_IDX_2 & path_index)) {
1019 _dcam_wait_path_done(DCAM_PATH_IDX_2, NULL);
1023 DCAM_TRACE("DCAM: start_path E\n");
1027 int32_t dcam_start(void)
1029 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
1032 DCAM_CHECK_ZERO(s_p_dcam_mod);
1034 DCAM_TRACE("DCAM: dcam_start %x \n", s_p_dcam_mod->dcam_mode);
1036 ret = dcam_start_path(DCAM_PATH_IDX_ALL);
1037 //ret = dcam_start_path(DCAM_PATH_IDX_1);
1042 int32_t dcam_stop_cap(void)
1044 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
1046 DCAM_CHECK_ZERO(s_p_dcam_mod);
1048 printk("DCAM: stop cap %d \n", s_p_dcam_mod->dcam_mode);
1049 dcam_glb_reg_mwr(DCAM_CONTROL, BIT_2, 0, DCAM_CONTROL_REG); /* Cap Enable */
1050 DCAM_TRACE("DCAM: stop cap, s_resize_flag %d \n", atomic_read(&s_resize_flag));
1051 if (atomic_read(&s_resize_flag)) {
1052 s_p_dcam_mod->wait_resize_done = 1;
1053 rtn = down_timeout(&s_p_dcam_mod->resize_done_sema, DCAM_PATH_TIMEOUT);
1055 if (atomic_read(&s_rotation_flag)) {
1056 s_p_dcam_mod->wait_rotation_done = 1;
1057 rtn = down_timeout(&s_p_dcam_mod->rotation_done_sema, DCAM_PATH_TIMEOUT);
1060 dcam_reset(DCAM_RST_ALL, 0);
1061 DCAM_TRACE("DCAM: stop cap, Out \n");
1066 int32_t _dcam_stop_path(enum dcam_path_index path_index)
1068 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
1069 struct dcam_path_desc *p_path = NULL;
1072 spin_lock_irqsave(&dcam_lock, flag);
1074 if (DCAM_PATH_IDX_0 == path_index) {
1075 p_path = &s_p_dcam_mod->dcam_path0;
1076 } else if(DCAM_PATH_IDX_1 == path_index) {
1077 p_path = &s_p_dcam_mod->dcam_path1;
1078 } else if(DCAM_PATH_IDX_2 == path_index) {
1079 p_path = &s_p_dcam_mod->dcam_path2;
1081 printk("DCAM: stop path Wrong index 0x%x \n", path_index);
1082 spin_unlock_irqrestore(&dcam_lock, flag);
1086 _dcam_wait_for_quickstop(path_index);
1087 p_path->status = DCAM_ST_STOP;
1089 _dcam_frm_clear(path_index);
1091 spin_unlock_irqrestore(&dcam_lock, flag);
1096 int32_t dcam_stop_path(enum dcam_path_index path_index)
1098 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
1100 DCAM_CHECK_ZERO(s_p_dcam_mod);
1102 printk("DCAM: stop_path 0x%x \n", path_index);
1104 if (path_index < DCAM_PATH_IDX_0 ||
1105 path_index >= DCAM_PATH_IDX_ALL) {
1106 printk("DCAM: error path_index \n");
1110 if ((DCAM_PATH_IDX_0 & path_index) && s_p_dcam_mod->dcam_path0.valide) {
1111 _dcam_wait_path_done(DCAM_PATH_IDX_0, &s_p_dcam_mod->dcam_path0.need_stop);
1112 _dcam_stop_path(DCAM_PATH_IDX_0);
1115 if ((DCAM_PATH_IDX_1 & path_index) && s_p_dcam_mod->dcam_path1.valide) {
1116 _dcam_wait_path_done(DCAM_PATH_IDX_1, &s_p_dcam_mod->dcam_path1.need_stop);
1117 _dcam_stop_path(DCAM_PATH_IDX_1);
1120 if ((DCAM_PATH_IDX_2 & path_index) && s_p_dcam_mod->dcam_path2.valide) {
1121 DCAM_TRACE("DCAM: stop path2 In \n");
1122 _dcam_wait_path_done(DCAM_PATH_IDX_2, &s_p_dcam_mod->dcam_path2.need_stop);
1123 _dcam_stop_path(DCAM_PATH_IDX_2);
1126 DCAM_TRACE("DCAM dcam_stop_path E: %d \n", path_index);
1131 LOCAL void _dcam_wait_for_channel_stop(enum dcam_path_index path_index)
1133 int time_out = 5000;
1136 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
1138 /* wait for AHB path busy cleared */
1140 if (s_p_dcam_mod->dcam_path1.valide && (DCAM_PATH_IDX_1 & path_index)) {
1141 ret = REG_RD(DCAM_AHBM_STS) & BIT_17;
1142 } else if (s_p_dcam_mod->dcam_path2.valide && (DCAM_PATH_IDX_2 & path_index)) {
1143 ret = REG_RD(DCAM_AHBM_STS) & BIT_18;
1153 DCAM_TRACE("DCAM: wait channel stop %d %d \n", ret, time_out);
1158 LOCAL void _dcam_quickstop_set(enum dcam_path_index path_index, uint32_t path_rst, uint32_t path_bit,
1159 uint32_t cfg_bit, uint32_t ahbm_bit, uint32_t auto_copy_bit)
1161 dcam_glb_reg_owr(DCAM_AHBM_STS, ahbm_bit, DCAM_AHBM_STS_REG);
1163 dcam_glb_reg_mwr(DCAM_CFG, cfg_bit, ~cfg_bit, DCAM_CFG_REG);
1164 _dcam_force_copy(path_index);
1165 _dcam_wait_for_channel_stop(path_index);
1166 dcam_glb_reg_awr(DCAM_AHBM_STS, ~ahbm_bit, DCAM_AHBM_STS_REG);
1167 dcam_reset(path_rst, 0);
1172 #define DCAM_IRQ_MASK_PATH0 (0x0f|(0x03<<4)|(1<<12)|(1<<21)) //let other module continue
1173 #define DCAM_IRQ_MASK_PATH1 (0x0f|(0x03<<6)|(1<<16)|(1<<19)|(1<<22))
1174 #define DCAM_IRQ_MASK_PATH2 (0x0f|(0x03<<8)|(1<<17)|(1<<20)|(1<<23))
1176 LOCAL void _dcam_quickstop_set_all(enum dcam_path_index path_index, uint32_t path_bit, uint32_t cfg_bit, uint32_t ahbm_bit)
1178 dcam_glb_reg_owr(DCAM_AHBM_STS, BIT_3 | BIT_4 | BIT_5, DCAM_AHBM_STS_REG);
1180 dcam_glb_reg_awr(DCAM_CFG, ~(BIT_0 | BIT_1 | BIT_2), DCAM_CFG_REG);
1181 dcam_glb_reg_owr(DCAM_CONTROL, BIT_10 | BIT_12, DCAM_CONTROL_REG);
1182 dcam_glb_reg_awr(DCAM_CONTROL, ~(BIT_10 | BIT_12), DCAM_CONTROL_REG);
1183 _dcam_wait_for_channel_stop(DCAM_PATH_IDX_1);
1184 _dcam_wait_for_channel_stop(DCAM_PATH_IDX_2);
1189 LOCAL void _dcam_wait_for_quickstop(enum dcam_path_index path_index)
1191 int time_out = 5000;
1193 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
1195 DCAM_TRACE("DCAM: state before stop 0x%x\n", s_p_dcam_mod->state);
1197 if (DCAM_PATH_IDX_ALL == path_index) {
1198 _dcam_quickstop_set_all(0, 0, 0, 0);
1200 if (s_p_dcam_mod->dcam_path0.valide && (DCAM_PATH_IDX_0 & path_index)) {
1201 _dcam_quickstop_set(DCAM_PATH_IDX_0, DCAM_RST_PATH0, DCAM_IRQ_MASK_PATH0, BIT_0, BIT_3, BIT_9);
1203 if (s_p_dcam_mod->dcam_path1.valide && (DCAM_PATH_IDX_1 & path_index)) {
1204 _dcam_quickstop_set(DCAM_PATH_IDX_1, DCAM_RST_PATH1, DCAM_IRQ_MASK_PATH1, BIT_1, BIT_4, BIT_11);
1206 if (s_p_dcam_mod->dcam_path2.valide && (DCAM_PATH_IDX_2 & path_index)) {
1207 _dcam_quickstop_set(DCAM_PATH_IDX_2, DCAM_RST_PATH2, DCAM_IRQ_MASK_PATH2, BIT_2, BIT_5, BIT_13);
1211 DCAM_TRACE("DCAM: exit _dcam_wait_for_quickstop %d state: 0x%x \n ", time_out, s_p_dcam_mod->state);
1216 int32_t dcam_stop(void)
1218 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
1221 DCAM_CHECK_ZERO(s_p_dcam_mod);
1223 s_p_dcam_mod->state |= DCAM_STATE_QUICKQUIT;
1224 printk("DCAM dcam_stop In \n");
1225 if (atomic_read(&s_resize_flag)) {
1226 s_p_dcam_mod->wait_resize_done = 1;
1227 rtn = down_timeout(&s_p_dcam_mod->resize_done_sema, DCAM_PATH_TIMEOUT);
1229 if (atomic_read(&s_rotation_flag)) {
1230 s_p_dcam_mod->wait_rotation_done = 1;
1231 rtn = down_timeout(&s_p_dcam_mod->rotation_done_sema, DCAM_PATH_TIMEOUT);
1234 mutex_lock(&dcam_sem);
1235 printk("DCAM dcam_stop get dcam_sem\n");
1236 spin_lock_irqsave(&dcam_lock, flag);
1238 dcam_glb_reg_owr(DCAM_INT_MASK,
1240 DCAM_INIT_MASK_REG);
1242 _dcam_wait_for_quickstop(DCAM_PATH_IDX_ALL);
1243 s_p_dcam_mod->dcam_path0.status = DCAM_ST_STOP;
1244 s_p_dcam_mod->dcam_path0.valide = 0;
1245 s_p_dcam_mod->dcam_path1.status = DCAM_ST_STOP;
1246 s_p_dcam_mod->dcam_path1.valide = 0;
1247 s_p_dcam_mod->dcam_path2.status = DCAM_ST_STOP;
1248 s_p_dcam_mod->dcam_path2.valide = 0;
1249 _dcam_frm_clear(DCAM_PATH_IDX_0);
1250 _dcam_frm_clear(DCAM_PATH_IDX_1);
1251 _dcam_frm_clear(DCAM_PATH_IDX_2);
1252 spin_unlock_irqrestore(&dcam_lock, flag);
1254 dcam_reset(DCAM_RST_ALL, 0);
1255 s_p_dcam_mod->state &= ~DCAM_STATE_QUICKQUIT;
1256 mutex_unlock(&dcam_sem);
1258 printk("DCAM: dcam_stop Out, s_resize_flag %d \n", atomic_read(&s_resize_flag));
1263 int32_t dcam_resume(void)
1265 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
1267 DCAM_CHECK_ZERO(s_p_dcam_mod);
1269 if (s_p_dcam_mod->dcam_path1.valide) {
1270 rtn = _dcam_path_set_next_frm(DCAM_PATH_IDX_1, true);
1272 _dcam_force_copy(DCAM_PATH_IDX_1);
1273 _dcam_frm_clear(DCAM_PATH_IDX_1);
1276 if (s_p_dcam_mod->dcam_path2.valide) {
1277 rtn = _dcam_path_set_next_frm(DCAM_PATH_IDX_2, true);
1279 _dcam_force_copy(DCAM_PATH_IDX_2);
1280 _dcam_frm_clear(DCAM_PATH_IDX_2);
1284 if (s_p_dcam_mod->dcam_path1.valide) {
1285 rtn = _dcam_path_set_next_frm(DCAM_PATH_IDX_1, false);
1287 dcam_glb_reg_owr(DCAM_CFG, BIT_1, DCAM_CFG_REG);
1288 _dcam_auto_copy_ext(DCAM_PATH_IDX_1, true, true);
1291 if (s_p_dcam_mod->dcam_path2.valide) {
1292 rtn = _dcam_path_set_next_frm(DCAM_PATH_IDX_2, false);
1294 dcam_glb_reg_owr(DCAM_CFG, BIT_2, DCAM_CFG_REG);
1295 _dcam_auto_copy_ext(DCAM_PATH_IDX_2, true, true);
1298 printk("DCAM R \n");
1300 dcam_glb_reg_owr(DCAM_CONTROL, BIT_2, DCAM_CONTROL_REG); /* Enable CAP */
1304 int32_t dcam_pause(void)
1306 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
1308 dcam_glb_reg_awr(DCAM_CONTROL, ~BIT_2, DCAM_CONTROL_REG); /* Disable CAP */
1309 printk("DCAM P \n");
1313 int32_t dcam_reg_isr(enum dcam_irq_id id, dcam_isr_func user_func, void* user_data)
1315 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
1318 if(id >= DCAM_IRQ_NUMBER) {
1319 rtn = DCAM_RTN_ISR_ID_ERR;
1321 spin_lock_irqsave(&dcam_lock, flag);
1322 s_user_func[id] = user_func;
1323 s_user_data[id] = user_data;
1324 spin_unlock_irqrestore(&dcam_lock, flag);
1329 int32_t dcam_cap_cfg(enum dcam_cfg_id id, void *param)
1331 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
1332 struct dcam_cap_desc *cap_desc = NULL;
1334 DCAM_CHECK_ZERO(s_p_dcam_mod);
1335 DCAM_CHECK_ZERO(s_dcam_sc_array);
1336 cap_desc = &s_p_dcam_mod->dcam_cap;
1338 case DCAM_CAP_SYNC_POL:
1340 struct dcam_cap_sync_pol *sync_pol = (struct dcam_cap_sync_pol*)param;
1342 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1344 if (DCAM_CAP_IF_CCIR == cap_desc->interface) {
1346 if (sync_pol->vsync_pol > 1 ||
1347 sync_pol->hsync_pol > 1 ||
1348 sync_pol->pclk_pol > 1) {
1349 rtn = DCAM_RTN_CAP_SYNC_POL_ERR;
1351 sci_glb_set(DCAM_CCIR_PCLK_EB, CCIR_PCLK_EB_BIT);
1352 REG_MWR(CAP_CCIR_CTRL, BIT_3, sync_pol->hsync_pol << 3);
1353 REG_MWR(CAP_CCIR_CTRL, BIT_4, sync_pol->vsync_pol << 4);
1354 //REG_MWR(CLK_DLY_CTRL, BIT_19, sync_pol->pclk_pol << 19); // aiden todo
1356 if (sync_pol->pclk_src == 0x00) {
1357 sci_glb_clr(CAP_CCIR_PLCK_SRC, (BIT_25 | BIT_26));
1358 DCAM_TRACE("DCAM: set pclk src0\n");
1359 } else if (sync_pol->pclk_src == 0x01) {
1360 sci_glb_clr(CAP_CCIR_PLCK_SRC, (BIT_25 | BIT_26));
1361 sci_glb_set(CAP_CCIR_PLCK_SRC, (BIT_25));
1362 DCAM_TRACE("DCAM: set pclk src1\n");
1364 DCAM_TRACE("DCAM: set pclk src default\n");
1368 if (sync_pol->need_href) {
1369 REG_MWR(CAP_MIPI_CTRL, BIT_5, 1 << 5);
1371 REG_MWR(CAP_MIPI_CTRL, BIT_5, 0 << 5);
1377 case DCAM_CAP_DATA_BITS:
1379 enum dcam_cap_data_bits bits = *(enum dcam_cap_data_bits*)param;
1381 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1383 if (DCAM_CAP_IF_CCIR == cap_desc->interface) {
1384 if (DCAM_CAP_8_BITS == bits || DCAM_CAP_10_BITS == bits) {
1385 REG_MWR(CAP_CCIR_CTRL, BIT_10 | BIT_9, 0 << 9);
1386 } else if (DCAM_CAP_4_BITS == bits) {
1387 REG_MWR(CAP_CCIR_CTRL, BIT_10 | BIT_9, 1 << 9);
1388 } else if (DCAM_CAP_2_BITS == bits) {
1389 REG_MWR(CAP_CCIR_CTRL, BIT_10 | BIT_9, 2 << 9);
1390 } else if (DCAM_CAP_1_BITS == bits) {
1391 REG_MWR(CAP_CCIR_CTRL, BIT_10 | BIT_9, 3 << 9);
1393 rtn = DCAM_RTN_CAP_IN_BITS_ERR;
1397 if (DCAM_CAP_12_BITS == bits) {
1398 REG_MWR(CAP_MIPI_CTRL, BIT_4 | BIT_3, 2 << 3);
1399 } else if (DCAM_CAP_10_BITS == bits) {
1400 REG_MWR(CAP_MIPI_CTRL, BIT_4 | BIT_3, 1 << 3);
1401 } else if (DCAM_CAP_8_BITS == bits) {
1402 REG_MWR(CAP_MIPI_CTRL, BIT_4 | BIT_3, 0 << 3);
1404 rtn = DCAM_RTN_CAP_IN_BITS_ERR;
1410 case DCAM_CAP_YUV_TYPE:
1412 enum dcam_cap_pattern pat = *(enum dcam_cap_pattern*)param;
1414 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1416 if (pat < DCAM_PATTERN_MAX) {
1417 if (DCAM_CAP_IF_CCIR == cap_desc->interface)
1418 REG_MWR(CAP_CCIR_CTRL, BIT_8 | BIT_7, pat << 7);
1420 REG_MWR(CAP_MIPI_CTRL, BIT_8 | BIT_7, pat << 7);
1422 rtn = DCAM_RTN_CAP_IN_YUV_ERR;
1427 case DCAM_CAP_PRE_SKIP_CNT:
1429 uint32_t skip_num = *(uint32_t*)param;
1431 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1433 if (skip_num > DCAM_CAP_SKIP_FRM_MAX) {
1434 rtn = DCAM_RTN_CAP_SKIP_FRAME_ERR;
1436 if (DCAM_CAP_IF_CCIR == cap_desc->interface)
1437 REG_MWR(CAP_CCIR_FRM_CTRL, BIT_3 | BIT_2 | BIT_1 | BIT_0, skip_num);
1439 REG_MWR(CAP_MIPI_FRM_CTRL, BIT_3 | BIT_2 | BIT_1 | BIT_0, skip_num);
1444 case DCAM_CAP_FRM_DECI:
1446 uint32_t deci_factor = *(uint32_t*)param;
1448 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1450 if (deci_factor < DCAM_FRM_DECI_FAC_MAX) {
1451 if (DCAM_CAP_IF_CCIR == cap_desc->interface)
1452 REG_MWR(CAP_CCIR_FRM_CTRL, BIT_5 | BIT_4, deci_factor << 4);
1454 REG_MWR(CAP_MIPI_FRM_CTRL, BIT_5 | BIT_4, deci_factor << 4);
1456 rtn = DCAM_RTN_CAP_FRAME_DECI_ERR;
1461 case DCAM_CAP_FRM_COUNT_CLR:
1462 if (DCAM_CAP_IF_CCIR == cap_desc->interface)
1463 REG_MWR(CAP_CCIR_FRM_CTRL, BIT_22, 1 << 22);
1465 REG_MWR(CAP_MIPI_FRM_CTRL, BIT_22, 1 << 22);
1468 case DCAM_CAP_INPUT_RECT:
1470 struct dcam_rect *rect = (struct dcam_rect*)param;
1473 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1475 if (rect->x > DCAM_CAP_FRAME_WIDTH_MAX ||
1476 rect->y > DCAM_CAP_FRAME_HEIGHT_MAX ||
1477 rect->w > DCAM_CAP_FRAME_WIDTH_MAX ||
1478 rect->h > DCAM_CAP_FRAME_HEIGHT_MAX ) {
1479 rtn = DCAM_RTN_CAP_FRAME_SIZE_ERR;
1484 if (DCAM_CAP_IF_CCIR == cap_desc->interface) {
1485 if (DCAM_CAP_MODE_RAWRGB == cap_desc->input_format) {
1486 tmp = rect->x | (rect->y << 16);
1487 REG_WR(CAP_CCIR_START, tmp);
1488 tmp = (rect->x + rect->w - 1);
1489 tmp |= (rect->y + rect->h - 1) << 16;
1490 REG_WR(CAP_CCIR_END, tmp);
1492 tmp = (rect->x << 1) | (rect->y << 16);
1493 REG_WR(CAP_CCIR_START, tmp);
1494 tmp = ((rect->x + rect->w) << 1) - 1;
1495 tmp |= (rect->y + rect->h - 1) << 16;
1496 REG_WR(CAP_CCIR_END, tmp);
1499 tmp = rect->x | (rect->y << 16);
1500 REG_WR(CAP_MIPI_START, tmp);
1501 tmp = (rect->x + rect->w - 1);
1502 tmp |= (rect->y + rect->h - 1) << 16;
1503 REG_WR(CAP_MIPI_END, tmp);
1508 case DCAM_CAP_IMAGE_XY_DECI:
1510 struct dcam_cap_dec *cap_dec = (struct dcam_cap_dec*)param;
1512 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1514 if (cap_dec->x_factor > DCAM_CAP_X_DECI_FAC_MAX ||
1515 cap_dec->y_factor > DCAM_CAP_Y_DECI_FAC_MAX ) {
1516 rtn = DCAM_RTN_CAP_XY_DECI_ERR;
1518 if (DCAM_CAP_MODE_RAWRGB == cap_desc->input_format) {
1519 if (cap_dec->x_factor > 1 ||
1520 cap_dec->y_factor > 1) {
1521 rtn = DCAM_RTN_CAP_XY_DECI_ERR;
1524 if (DCAM_CAP_IF_CCIR == cap_desc->interface) {
1525 REG_MWR(CAP_CCIR_IMG_DECI, BIT_1 | BIT_0, cap_dec->x_factor);
1526 REG_MWR(CAP_CCIR_IMG_DECI, BIT_3 | BIT_2, cap_dec->y_factor << 2);
1528 if (DCAM_CAP_MODE_RAWRGB == cap_desc->input_format) {
1529 // REG_MWR(CAP_MIPI_IMG_DECI, BIT_0, cap_dec->x_factor); // for camera path
1530 REG_MWR(CAP_MIPI_IMG_DECI, BIT_1, cap_dec->x_factor << 1);//for ISP
1532 REG_MWR(CAP_MIPI_IMG_DECI, BIT_1 | BIT_0, cap_dec->x_factor);
1533 REG_MWR(CAP_MIPI_IMG_DECI, BIT_3 | BIT_2, cap_dec->y_factor << 2);
1541 case DCAM_CAP_JPEG_SET_BUF_LEN:
1543 uint32_t jpg_buf_size = *(uint32_t*)param;
1545 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1546 jpg_buf_size = jpg_buf_size/DCAM_JPG_BUF_UNIT;
1547 if (jpg_buf_size >= DCAM_JPG_UNITS) {
1548 rtn = DCAM_RTN_CAP_JPEG_BUF_LEN_ERR;
1550 if (DCAM_CAP_IF_CCIR == cap_desc->interface)
1551 REG_WR(CAP_CCIR_JPG_CTRL,jpg_buf_size);
1553 REG_WR(CAP_MIPI_JPG_CTRL,jpg_buf_size);
1558 case DCAM_CAP_TO_ISP:
1560 uint32_t need_isp = *(uint32_t*)param;
1562 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1565 dcam_glb_reg_mwr(DCAM_CFG, BIT_7, 1 << 7, DCAM_CFG_REG);
1567 dcam_glb_reg_mwr(DCAM_CFG, BIT_7, 0 << 7, DCAM_CFG_REG);
1572 case DCAM_CAP_DATA_PACKET:
1574 uint32_t is_loose = *(uint32_t*)param;
1576 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1578 if (DCAM_CAP_IF_CSI2 == cap_desc->interface &&
1579 DCAM_CAP_MODE_RAWRGB == cap_desc->input_format) {
1581 REG_MWR(CAP_MIPI_CTRL, BIT_0, 1);
1583 REG_MWR(CAP_MIPI_CTRL, BIT_0, 0);
1586 rtn = DCAM_RTN_MODE_ERR;
1592 case DCAM_CAP_SAMPLE_MODE:
1594 enum dcam_capture_mode samp_mode = *(enum dcam_capture_mode*)param;
1596 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1598 if (samp_mode >= DCAM_CAPTURE_MODE_MAX) {
1599 rtn = DCAM_RTN_MODE_ERR;
1601 if (DCAM_CAP_IF_CSI2 == cap_desc->interface) {
1602 REG_MWR(CAP_MIPI_CTRL, BIT_6, samp_mode << 6);
1604 REG_MWR(CAP_CCIR_CTRL, BIT_6, samp_mode << 6);
1606 s_p_dcam_mod->dcam_mode = samp_mode;
1611 case DCAM_CAP_ZOOM_MODE:
1613 uint32_t zoom_mode = *(uint32_t*)param;
1615 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1617 s_dcam_sc_array->is_smooth_zoom = zoom_mode;
1621 rtn = DCAM_RTN_IO_ID_ERR;
1629 int32_t dcam_cap_get_info(enum dcam_cfg_id id, void *param)
1631 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
1632 struct dcam_cap_desc *cap_desc = NULL;
1634 DCAM_CHECK_ZERO(s_p_dcam_mod);
1636 cap_desc = &s_p_dcam_mod->dcam_cap;
1637 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1640 case DCAM_CAP_FRM_COUNT_GET:
1641 if (DCAM_CAP_IF_CSI2 == cap_desc->interface) {
1642 *(uint32_t*)param = REG_RD(CAP_MIPI_FRM_CTRL) >> 16;
1644 *(uint32_t*)param = REG_RD(CAP_CCIR_FRM_CTRL) >> 16;
1648 case DCAM_CAP_JPEG_GET_LENGTH:
1649 if (DCAM_CAP_IF_CSI2 == cap_desc->interface) {
1650 *(uint32_t*)param = REG_RD(CAP_MIPI_FRM_SIZE);
1652 *(uint32_t*)param = REG_RD(CAP_CCIR_FRM_SIZE);
1656 rtn = DCAM_RTN_IO_ID_ERR;
1662 int32_t dcam_path0_cfg(enum dcam_cfg_id id, void *param)
1664 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
1665 struct dcam_path_desc *path = NULL;
1667 DCAM_CHECK_ZERO(s_p_dcam_mod);
1668 path = &s_p_dcam_mod->dcam_path0;
1671 case DCAM_PATH_INPUT_SIZE:
1673 struct dcam_size *size = (struct dcam_size*)param;
1675 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1677 DCAM_TRACE("DCAM: DCAM_PATH0_INPUT_SIZE {%d %d} \n", size->w, size->h);
1679 if (size->w > DCAM_PATH_FRAME_WIDTH_MAX ||
1680 size->h > DCAM_PATH_FRAME_HEIGHT_MAX) {
1681 rtn = DCAM_RTN_PATH_SRC_SIZE_ERR;
1685 path->input_size.w = size->w;
1686 path->input_size.h = size->h;
1687 path->valid_param.input_size = 1;
1692 case DCAM_PATH_OUTPUT_FORMAT:
1694 enum dcam_output_mode format = *(enum dcam_output_mode*)param;
1696 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1698 if((DCAM_OUTPUT_WORD != format) &&
1699 (DCAM_OUTPUT_HALF_WORD != format)){
1700 rtn = DCAM_RTN_PATH_OUT_FMT_ERR;
1701 path->output_format = DCAM_FTM_MAX;
1703 path->output_format = format;
1704 path->valid_param.output_format = 1;
1709 case DCAM_PATH_FRAME_BASE_ID:
1711 uint32_t base_id = *(uint32_t*)param, i;
1713 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1715 DCAM_TRACE("DCAM: DCAM_PATH_FRAME_BASE_ID 0x%x \n", base_id);
1716 s_p_dcam_mod->dcam_path0.frame_base_id = base_id;
1720 case DCAM_PATH_FRAME_TYPE:
1722 struct dcam_frame *frame = &s_p_dcam_mod->dcam_path0.buf_queue.frame[0];
1723 uint32_t frm_type = *(uint32_t*)param, i;
1725 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1727 DCAM_TRACE("DCAM: DCAM_PATH_FRAME_TYPE 0x%x \n", frm_type);
1728 for (i = 0; i < DCAM_PATH_0_FRM_CNT_MAX; i++) {
1729 (frame+i)->type = frm_type;
1734 case DCAM_PATH_OUTPUT_ADDR:
1736 struct dcam_addr *p_addr = (struct dcam_addr*)param;
1738 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1739 if (DCAM_YUV_ADDR_INVALID(p_addr->yaddr, p_addr->uaddr, p_addr->vaddr)) {
1740 rtn = DCAM_RTN_PATH_ADDR_ERR;
1742 struct dcam_frame frame;
1743 memset((void*)&frame, 0, sizeof(struct dcam_frame));
1744 frame.yaddr = p_addr->yaddr;
1745 frame.uaddr = p_addr->uaddr;
1746 frame.vaddr = p_addr->vaddr;
1747 frame.yaddr_vir = p_addr->yaddr_vir;
1748 frame.uaddr_vir = p_addr->uaddr_vir;
1749 frame.vaddr_vir = p_addr->vaddr_vir;
1750 frame.type = DCAM_PATH0;
1751 frame.fid = s_p_dcam_mod->dcam_path0.frame_base_id;
1752 DCAM_TRACE("DCAM: Path 0 DCAM_PATH_OUTPUT_ADDR, i=%d, y=0x%x, u=0x%x, v=0x%x \n",
1753 path->output_frame_count, p_addr->yaddr, p_addr->uaddr, p_addr->vaddr);
1754 _dcam_buf_queue_write(&s_p_dcam_mod->dcam_path0.buf_queue, &frame);
1759 case DCAM_PATH_OUTPUT_RESERVED_ADDR:
1761 struct dcam_addr *p_addr = (struct dcam_addr*)param;
1763 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1765 if (DCAM_YUV_ADDR_INVALID(p_addr->yaddr, p_addr->uaddr, p_addr->vaddr)) {
1766 rtn = DCAM_RTN_PATH_ADDR_ERR;
1768 struct dcam_frame *frame = &s_p_dcam_mod->path0_reserved_frame;
1769 frame->yaddr = p_addr->yaddr;
1770 frame->uaddr = p_addr->uaddr;
1771 frame->vaddr = p_addr->vaddr;
1772 frame->yaddr_vir = p_addr->yaddr_vir;
1773 frame->uaddr_vir = p_addr->uaddr_vir;
1774 frame->vaddr_vir = p_addr->vaddr_vir;
1776 DCAM_TRACE("DCAM: Path 1 DCAM_PATH_OUTPUT_RESERVED_ADDR, i=%d, y=0x%x, u=0x%x, v=0x%x \n",
1777 path->output_frame_count, p_addr->yaddr, p_addr->uaddr, p_addr->vaddr);
1782 case DCAM_PATH_FRM_DECI:
1784 uint32_t deci_factor = *(uint32_t*)param;
1786 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1788 if (deci_factor >= DCAM_FRM_DECI_FAC_MAX) {
1789 rtn = DCAM_RTN_PATH_FRM_DECI_ERR;
1791 path->frame_deci = deci_factor;
1792 path->valid_param.frame_deci = 1;
1797 case DCAM_PATH_DATA_ENDIAN:
1799 struct dcam_endian_sel *endian = (struct dcam_endian_sel*)param;
1801 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1803 if (endian->y_endian >= DCAM_ENDIAN_MAX ||
1804 endian->uv_endian >= DCAM_ENDIAN_MAX) {
1805 rtn = DCAM_RTN_PATH_ENDIAN_ERR;
1807 path->data_endian.y_endian = endian->y_endian;
1808 path->valid_param.data_endian = 1;
1814 case DCAM_PATH_ENABLE:
1816 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1817 path->valide = *(uint32_t*)param;
1822 rtn = DCAM_RTN_IO_ID_ERR;
1829 int32_t dcam_path1_cfg(enum dcam_cfg_id id, void *param)
1831 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
1832 struct dcam_path_desc *path = NULL;
1834 DCAM_CHECK_ZERO(s_p_dcam_mod);
1835 path = &s_p_dcam_mod->dcam_path1;
1838 case DCAM_PATH_INPUT_SIZE:
1840 struct dcam_size *size = (struct dcam_size*)param;
1842 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1844 DCAM_TRACE("DCAM: DCAM_PATH1_INPUT_SIZE {%d %d} \n", size->w, size->h);
1845 if (size->w > DCAM_PATH_FRAME_WIDTH_MAX ||
1846 size->h > DCAM_PATH_FRAME_HEIGHT_MAX) {
1847 rtn = DCAM_RTN_PATH_SRC_SIZE_ERR;
1849 path->input_size.w = size->w;
1850 path->input_size.h = size->h;
1851 path->valid_param.input_size = 1;
1856 case DCAM_PATH_INPUT_RECT:
1858 struct dcam_rect *rect = (struct dcam_rect*)param;
1860 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1862 DCAM_TRACE("DCAM: DCAM_PATH1_INPUT_RECT {%d %d %d %d} \n",
1868 if (rect->x > DCAM_PATH_FRAME_WIDTH_MAX ||
1869 rect->y > DCAM_PATH_FRAME_HEIGHT_MAX ||
1870 rect->w > DCAM_PATH_FRAME_WIDTH_MAX ||
1871 rect->h > DCAM_PATH_FRAME_HEIGHT_MAX) {
1872 rtn = DCAM_RTN_PATH_TRIM_SIZE_ERR;
1874 memcpy((void*)&path->input_rect,
1876 sizeof(struct dcam_rect));
1877 //if (path->input_rect.h >= DCAM_HEIGHT_MIN) {
1878 // path->input_rect.h--;
1880 path->valid_param.input_rect = 1;
1885 case DCAM_PATH_OUTPUT_SIZE:
1887 struct dcam_size *size = (struct dcam_size*)param;
1889 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1891 DCAM_TRACE("DCAM: DCAM_PATH1_OUTPUT_SIZE {%d %d} \n", size->w, size->h);
1892 if (size->w > DCAM_PATH_FRAME_WIDTH_MAX ||
1893 size->h > DCAM_PATH_FRAME_HEIGHT_MAX) {
1894 rtn = DCAM_RTN_PATH_SRC_SIZE_ERR;
1896 path->output_size.w = size->w;
1897 path->output_size.h = size->h;
1898 path->valid_param.output_size = 1;
1903 case DCAM_PATH_OUTPUT_FORMAT:
1905 enum dcam_fmt format = *(enum dcam_fmt*)param;
1907 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1909 path->output_format = format;
1911 if((DCAM_YUV422 != format) &&
1912 (DCAM_YUV420 != format) &&
1913 (DCAM_YUV420_3FRAME != format)){
1914 rtn = DCAM_RTN_PATH_OUT_FMT_ERR;
1915 path->output_format = DCAM_FTM_MAX;
1917 path->valid_param.output_format = 1;
1922 case DCAM_PATH_OUTPUT_ADDR:
1924 struct dcam_addr *p_addr = (struct dcam_addr*)param;
1926 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1927 if (DCAM_YUV_ADDR_INVALID(p_addr->yaddr, p_addr->uaddr, p_addr->vaddr)) {
1928 rtn = DCAM_RTN_PATH_ADDR_ERR;
1930 struct dcam_frame frame;
1931 memset((void*)&frame, 0, sizeof(struct dcam_frame));
1932 frame.yaddr = p_addr->yaddr;
1933 frame.uaddr = p_addr->uaddr;
1934 frame.vaddr = p_addr->vaddr;
1935 frame.yaddr_vir = p_addr->yaddr_vir;
1936 frame.uaddr_vir = p_addr->uaddr_vir;
1937 frame.vaddr_vir = p_addr->vaddr_vir;
1938 frame.type = DCAM_PATH1;
1939 frame.fid = s_p_dcam_mod->dcam_path1.frame_base_id;
1940 DCAM_TRACE("DCAM: Path 1 DCAM_PATH_OUTPUT_ADDR, i=%d, y=0x%x, u=0x%x, v=0x%x \n",
1941 path->output_frame_count, p_addr->yaddr, p_addr->uaddr, p_addr->vaddr);
1942 _dcam_buf_queue_write(&s_p_dcam_mod->dcam_path1.buf_queue, &frame);
1947 case DCAM_PATH_OUTPUT_RESERVED_ADDR:
1949 struct dcam_addr *p_addr = (struct dcam_addr*)param;
1951 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1953 if (DCAM_YUV_ADDR_INVALID(p_addr->yaddr, p_addr->uaddr, p_addr->vaddr)) {
1954 rtn = DCAM_RTN_PATH_ADDR_ERR;
1956 struct dcam_frame *frame = &s_p_dcam_mod->path1_reserved_frame;
1957 frame->yaddr = p_addr->yaddr;
1958 frame->uaddr = p_addr->uaddr;
1959 frame->vaddr = p_addr->vaddr;
1960 frame->yaddr_vir = p_addr->yaddr_vir;
1961 frame->uaddr_vir = p_addr->uaddr_vir;
1962 frame->vaddr_vir = p_addr->vaddr_vir;
1963 DCAM_TRACE("DCAM: Path 1 DCAM_PATH_OUTPUT_RESERVED_ADDR, i=%d, y=0x%x, u=0x%x, v=0x%x \n",
1964 path->output_frame_count, p_addr->yaddr, p_addr->uaddr, p_addr->vaddr);
1969 case DCAM_PATH_SRC_SEL:
1971 uint32_t src_sel = *(uint32_t*)param;
1973 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1975 if (src_sel >= DCAM_PATH_FROM_NONE) {
1976 rtn = DCAM_RTN_PATH_SRC_ERR;
1978 path->src_sel = src_sel;
1979 path->valid_param.src_sel = 1;
1984 case DCAM_PATH_FRAME_BASE_ID:
1986 uint32_t base_id = *(uint32_t*)param, i;
1988 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1990 DCAM_TRACE("DCAM: DCAM_PATH_FRAME_BASE_ID 0x%x \n", base_id);
1991 s_p_dcam_mod->dcam_path1.frame_base_id = base_id;
1995 case DCAM_PATH_DATA_ENDIAN:
1997 struct dcam_endian_sel *endian = (struct dcam_endian_sel*)param;
1999 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2001 if (endian->y_endian >= DCAM_ENDIAN_MAX ||
2002 endian->uv_endian >= DCAM_ENDIAN_MAX) {
2003 rtn = DCAM_RTN_PATH_ENDIAN_ERR;
2005 path->data_endian.y_endian = endian->y_endian;
2006 path->data_endian.uv_endian = endian->uv_endian;
2007 path->valid_param.data_endian = 1;
2012 case DCAM_PATH_ENABLE:
2014 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2015 path->valide = *(uint32_t*)param;
2019 case DCAM_PATH_FRAME_TYPE:
2021 struct dcam_frame *frame = &s_p_dcam_mod->dcam_path1.buf_queue.frame[0];
2022 uint32_t frm_type = *(uint32_t*)param, i;
2024 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2026 DCAM_TRACE("DCAM: DCAM_PATH_FRAME_TYPE 0x%x \n", frm_type);
2027 for (i = 0; i < DCAM_PATH_1_FRM_CNT_MAX; i++) {
2028 (frame+i)->type = frm_type;
2033 case DCAM_PATH_FRM_DECI:
2035 uint32_t deci_factor = *(uint32_t*)param;
2037 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2039 if (deci_factor >= DCAM_FRM_DECI_FAC_MAX) {
2040 rtn = DCAM_RTN_PATH_FRM_DECI_ERR;
2042 path->frame_deci = deci_factor;
2043 path->valid_param.frame_deci = 1;
2055 int32_t dcam_path2_cfg(enum dcam_cfg_id id, void *param)
2057 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
2058 struct dcam_path_desc *path = NULL;
2060 DCAM_CHECK_ZERO(s_p_dcam_mod);
2061 path = &s_p_dcam_mod->dcam_path2;
2064 case DCAM_PATH_INPUT_SIZE:
2066 struct dcam_size *size = (struct dcam_size*)param;
2068 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2070 DCAM_TRACE("DCAM: DCAM_PATH2_INPUT_SIZE {%d %d} \n", size->w, size->h);
2071 if (size->w > DCAM_PATH_FRAME_WIDTH_MAX ||
2072 size->h > DCAM_PATH_FRAME_HEIGHT_MAX) {
2073 rtn = DCAM_RTN_PATH_SRC_SIZE_ERR;
2075 path->input_size.w = size->w;
2076 path->input_size.h = size->h;
2077 path->valid_param.input_size = 1;
2083 case DCAM_PATH_INPUT_RECT:
2085 struct dcam_rect *rect = (struct dcam_rect*)param;
2087 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2089 DCAM_TRACE("DCAM: DCAM_PATH2_INPUT_RECT {%d %d %d %d} \n",
2095 if (rect->x > DCAM_PATH_FRAME_WIDTH_MAX ||
2096 rect->y > DCAM_PATH_FRAME_HEIGHT_MAX ||
2097 rect->w > DCAM_PATH_FRAME_WIDTH_MAX ||
2098 rect->h > DCAM_PATH_FRAME_HEIGHT_MAX) {
2099 rtn = DCAM_RTN_PATH_TRIM_SIZE_ERR;
2101 memcpy((void*)&path->input_rect,
2103 sizeof(struct dcam_rect));
2105 if (path->input_rect.h >= DCAM_HEIGHT_MIN) {
2106 path->input_rect.h--;
2109 path->valid_param.input_rect = 1;
2114 case DCAM_PATH_OUTPUT_SIZE:
2116 struct dcam_size *size = (struct dcam_size*)param;
2118 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2120 DCAM_TRACE("DCAM: DCAM_PATH2_OUTPUT_SIZE {%d %d} \n", size->w, size->h);
2121 if (size->w > DCAM_PATH_FRAME_WIDTH_MAX ||
2122 size->h > DCAM_PATH_FRAME_HEIGHT_MAX) {
2123 rtn = DCAM_RTN_PATH_SRC_SIZE_ERR;
2125 path->output_size.w = size->w;
2126 path->output_size.h = size->h;
2127 path->valid_param.output_size = 1;
2132 case DCAM_PATH_OUTPUT_FORMAT:
2134 enum dcam_fmt format = *(enum dcam_fmt*)param;
2136 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2138 if((DCAM_YUV422 != format) &&
2139 (DCAM_YUV420 != format) &&
2140 (DCAM_YUV420_3FRAME != format)){
2141 rtn = DCAM_RTN_PATH_OUT_FMT_ERR;
2142 path->output_format = DCAM_FTM_MAX;
2144 path->output_format = format;
2145 path->valid_param.output_format = 1;
2150 case DCAM_PATH_OUTPUT_ADDR:
2152 struct dcam_addr *p_addr = (struct dcam_addr*)param;
2154 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2155 if (DCAM_YUV_ADDR_INVALID(p_addr->yaddr, p_addr->uaddr, p_addr->vaddr)) {
2156 rtn = DCAM_RTN_PATH_ADDR_ERR;
2158 struct dcam_frame frame;
2159 memset((void*)&frame, 0, sizeof(struct dcam_frame));
2160 frame.yaddr = p_addr->yaddr;
2161 frame.uaddr = p_addr->uaddr;
2162 frame.vaddr = p_addr->vaddr;
2163 frame.yaddr_vir = p_addr->yaddr_vir;
2164 frame.uaddr_vir = p_addr->uaddr_vir;
2165 frame.vaddr_vir = p_addr->vaddr_vir;
2166 frame.type = DCAM_PATH2;
2167 frame.fid = s_p_dcam_mod->dcam_path2.frame_base_id;
2168 DCAM_TRACE("DCAM: Path 2 DCAM_PATH_OUTPUT_ADDR, i=%d, y=0x%x, u=0x%x, v=0x%x \n",
2169 path->output_frame_count, p_addr->yaddr, p_addr->uaddr, p_addr->vaddr);
2170 _dcam_buf_queue_write(&s_p_dcam_mod->dcam_path2.buf_queue, &frame);
2175 case DCAM_PATH_OUTPUT_RESERVED_ADDR:
2177 struct dcam_addr *p_addr = (struct dcam_addr*)param;
2179 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2181 if (DCAM_YUV_ADDR_INVALID(p_addr->yaddr, p_addr->uaddr, p_addr->vaddr)) {
2182 rtn = DCAM_RTN_PATH_ADDR_ERR;
2184 struct dcam_frame *frame = &s_p_dcam_mod->path2_reserved_frame;
2185 frame->yaddr = p_addr->yaddr;
2186 frame->uaddr = p_addr->uaddr;
2187 frame->vaddr = p_addr->vaddr;
2188 frame->yaddr_vir = p_addr->yaddr_vir;
2189 frame->uaddr_vir = p_addr->uaddr_vir;
2190 frame->vaddr_vir = p_addr->vaddr_vir;
2191 DCAM_TRACE("DCAM: Path 1 DCAM_PATH_OUTPUT_RESERVED_ADDR, i=%d, y=0x%x, u=0x%x, v=0x%x \n",
2192 path->output_frame_count, p_addr->yaddr, p_addr->uaddr, p_addr->vaddr);
2197 case DCAM_PATH_SRC_SEL:
2199 uint32_t src_sel = *(uint32_t*)param;
2201 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2203 if (src_sel >= DCAM_PATH_FROM_NONE) {
2204 rtn = DCAM_RTN_PATH_SRC_ERR;
2206 path->src_sel = src_sel;
2207 path->valid_param.src_sel = 1;
2213 case DCAM_PATH_FRAME_BASE_ID:
2215 uint32_t base_id = *(uint32_t*)param, i;
2217 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2219 DCAM_TRACE("DCAM: DCAM_PATH_FRAME_BASE_ID 0x%x \n", base_id);
2220 s_p_dcam_mod->dcam_path2.frame_base_id = base_id;
2224 case DCAM_PATH_DATA_ENDIAN:
2226 struct dcam_endian_sel *endian = (struct dcam_endian_sel*)param;
2228 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2230 if (endian->y_endian >= DCAM_ENDIAN_MAX ||
2231 endian->uv_endian >= DCAM_ENDIAN_MAX) {
2232 rtn = DCAM_RTN_PATH_ENDIAN_ERR;
2234 path->data_endian.y_endian = endian->y_endian;
2235 path->data_endian.uv_endian = endian->uv_endian;
2236 path->valid_param.data_endian = 1;
2241 case DCAM_PATH_ENABLE:
2243 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2245 path->valide = *(uint32_t*)param;
2250 case DCAM_PATH_FRAME_TYPE:
2252 struct dcam_frame *frame = &s_p_dcam_mod->dcam_path2.buf_queue.frame[0];
2253 uint32_t frm_type = *(uint32_t*)param, i;
2255 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2257 DCAM_TRACE("DCAM: DCAM_PATH_FRAME_TYPE 0x%x \n", frm_type);
2258 for (i = 0; i < DCAM_PATH_2_FRM_CNT_MAX; i++) {
2259 (frame+i)->type = frm_type;
2264 case DCAM_PATH_FRM_DECI:
2266 uint32_t deci_factor = *(uint32_t*)param;
2268 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2270 if (deci_factor >= DCAM_FRM_DECI_FAC_MAX) {
2271 rtn = DCAM_RTN_PATH_FRM_DECI_ERR;
2273 path->frame_deci = deci_factor;
2274 path->valid_param.frame_deci = 1;
2286 int32_t dcam_get_resizer(uint32_t wait_opt)
2290 printk("resizer_get:%d\n",current->pid);
2293 if( 0 == wait_opt) {
2294 rtn = mutex_trylock(&dcam_sem) ? 0 : 1;
2296 } else if (DCAM_WAIT_FOREVER == wait_opt){
2297 mutex_lock(&dcam_sem);
2300 return 0;//mutex_timeout(&dcam_sem, wait_opt);
2304 int32_t dcam_rel_resizer(void)
2306 printk("resizer_put:%d\n",current->pid);
2307 mutex_unlock(&dcam_sem);
2311 int32_t dcam_resize_start(void)
2313 atomic_inc(&s_resize_flag);
2314 mutex_lock(&dcam_scale_sema);
2318 int32_t dcam_resize_end(void)
2322 atomic_dec(&s_resize_flag);
2323 mutex_unlock(&dcam_scale_sema);
2325 spin_lock_irqsave(&dcam_mod_lock, flag);
2326 if (DCAM_ADDR_INVALID(s_p_dcam_mod)) {
2327 spin_unlock_irqrestore(&dcam_mod_lock, flag);
2332 if (s_p_dcam_mod->wait_resize_done) {
2333 up(&s_p_dcam_mod->resize_done_sema);
2334 s_p_dcam_mod->wait_resize_done = 0;
2337 spin_unlock_irqrestore(&dcam_mod_lock, flag);
2341 int32_t dcam_rotation_start(void)
2343 atomic_inc(&s_rotation_flag);
2344 mutex_lock(&dcam_rot_sema);
2348 int32_t dcam_rotation_end(void)
2352 atomic_dec(&s_rotation_flag);
2353 mutex_unlock(&dcam_rot_sema);
2355 spin_lock_irqsave(&dcam_mod_lock, flag);
2356 if (DCAM_ADDR_INVALID(s_p_dcam_mod)) {
2357 spin_unlock_irqrestore(&dcam_mod_lock, flag);
2362 if (s_p_dcam_mod->wait_rotation_done) {
2363 up(&s_p_dcam_mod->rotation_done_sema);
2364 s_p_dcam_mod->wait_rotation_done = 0;
2367 spin_unlock_irqrestore(&dcam_mod_lock, flag);
2371 void dcam_int_en(void)
2373 if (atomic_read(&s_dcam_users) == 1) {
2374 enable_irq(DCAM_IRQ);
2378 void dcam_int_dis(void)
2380 if (atomic_read(&s_dcam_users) == 1) {
2381 disable_irq(DCAM_IRQ);
2385 int32_t dcam_frame_is_locked(struct dcam_frame *frame)
2388 unsigned long flags;
2391 local_irq_save(flags);
2393 rtn = frame->lock == DCAM_FRM_LOCK_WRITE ? 1 : 0;
2394 local_irq_restore(flags);
2400 int32_t dcam_frame_lock(struct dcam_frame *frame)
2403 unsigned long flags;
2405 DCAM_CHECK_ZERO(s_p_dcam_mod);
2407 DCAM_TRACE("DCAM: lock %d \n", (uint32_t)(0xF&frame->fid));
2410 local_irq_save(flags);
2412 frame->lock = DCAM_FRM_LOCK_WRITE;
2414 rtn = DCAM_RTN_PARA_ERR;
2415 local_irq_restore(flags);
2421 int32_t dcam_frame_unlock(struct dcam_frame *frame)
2424 unsigned long flags;
2426 DCAM_CHECK_ZERO(s_p_dcam_mod);
2428 DCAM_TRACE("DCAM: unlock %d \n", (uint32_t)(0xF&frame->fid));
2431 local_irq_save(flags);
2433 frame->lock = DCAM_FRM_UNLOCK;
2435 rtn = DCAM_RTN_PARA_ERR;
2436 local_irq_restore(flags);
2442 int32_t dcam_read_registers(uint32_t* reg_buf, uint32_t *buf_len)
2444 uint32_t *reg_addr = (uint32_t*)DCAM_BASE;
2446 if (NULL == reg_buf || NULL == buf_len || 0 != (*buf_len % 4)) {
2450 while (buf_len != 0 && (uint32_t)reg_addr < DCAM_END) {
2451 *reg_buf++ = REG_RD(reg_addr);
2456 *buf_len = (uint32_t)reg_addr - DCAM_BASE;
2460 int32_t dcam_get_path_id(struct dcam_get_path_id *path_id, uint32_t *channel_id)
2462 int ret = DCAM_RTN_SUCCESS;
2464 if (NULL == path_id || NULL == channel_id) {
2468 DCAM_TRACE("DCAM: fourcc 0x%x, w %d, h %d, %d %d \n",
2469 path_id->fourcc, path_id->input_size.w, path_id->input_size.h,
2470 path_id->is_path_work[DCAM_PATH1], path_id->is_path_work[DCAM_PATH2]);
2472 if (path_id->need_isp_tool) {
2473 *channel_id = DCAM_PATH0;
2474 } else if (V4L2_PIX_FMT_GREY == path_id->fourcc && !path_id->is_path_work[DCAM_PATH0]) {
2475 *channel_id = DCAM_PATH0;
2476 } else if (V4L2_PIX_FMT_JPEG == path_id->fourcc && !path_id->is_path_work[DCAM_PATH0]) {
2477 *channel_id = DCAM_PATH0;
2478 } else if (path_id->output_size.w <= DCAM_PATH1_LINE_BUF_LENGTH && !path_id->is_path_work[DCAM_PATH1]) {
2479 *channel_id = DCAM_PATH1;
2480 } else if (path_id->output_size.w <= DCAM_PATH2_LINE_BUF_LENGTH && !path_id->is_path_work[DCAM_PATH2]) {
2481 *channel_id = DCAM_PATH2;
2483 *channel_id = DCAM_PATH0;
2485 printk("DCAM: path id %d \n", *channel_id);
2490 int32_t dcam_get_path_capability(struct dcam_path_capability *capacity)
2492 int ret = DCAM_RTN_SUCCESS;
2494 if (NULL == capacity) {
2498 capacity->count = 3;
2499 capacity->path_info[DCAM_PATH0].line_buf = 0;
2500 capacity->path_info[DCAM_PATH0].support_yuv = 0;
2501 capacity->path_info[DCAM_PATH0].support_raw = 1;
2502 capacity->path_info[DCAM_PATH0].support_jpeg = 1;
2503 capacity->path_info[DCAM_PATH0].support_scaling = 0;
2504 capacity->path_info[DCAM_PATH0].support_trim = 0;
2505 capacity->path_info[DCAM_PATH0].is_scaleing_path = 0;
2507 capacity->path_info[DCAM_PATH1].line_buf = DCAM_PATH1_LINE_BUF_LENGTH;
2508 capacity->path_info[DCAM_PATH1].support_yuv = 1;
2509 capacity->path_info[DCAM_PATH1].support_raw = 0;
2510 capacity->path_info[DCAM_PATH1].support_jpeg = 0;
2511 capacity->path_info[DCAM_PATH1].support_scaling = 1;
2512 capacity->path_info[DCAM_PATH1].support_trim = 1;
2513 capacity->path_info[DCAM_PATH1].is_scaleing_path = 0;
2515 capacity->path_info[DCAM_PATH2].line_buf = DCAM_PATH2_LINE_BUF_LENGTH;
2516 capacity->path_info[DCAM_PATH2].support_yuv = 1;
2517 capacity->path_info[DCAM_PATH2].support_raw = 0;
2518 capacity->path_info[DCAM_PATH2].support_jpeg = 0;
2519 capacity->path_info[DCAM_PATH2].support_scaling = 1;
2520 capacity->path_info[DCAM_PATH2].support_trim = 1;
2521 capacity->path_info[DCAM_PATH2].is_scaleing_path = 1;
2527 LOCAL irqreturn_t _dcam_isr_root(int irq, void *dev_id)
2529 uint32_t irq_line, status;
2533 DCAM_TRACE("DCAM: ISR 0x%x \n", REG_RD(DCAM_INT_STS));
2534 status = REG_RD(DCAM_INT_STS) & DCAM_IRQ_LINE_MASK;
2535 if (unlikely(0 == status)) {
2540 if (unlikely(DCAM_IRQ_ERR_MASK & status)) {
2541 if (_dcam_err_pre_proc()) {
2546 spin_lock_irqsave(&dcam_lock,flag);
2548 //for (i = DCAM_IRQ_NUMBER - 1; i >= 0; i--) {
2549 for (i = 0; i < DCAM_IRQ_NUMBER; i++) {
2550 if (irq_line & (1 << (uint32_t)i)) {
2555 irq_line &= ~(uint32_t)(1 << (uint32_t)i); //clear the interrupt flag
2556 if(!irq_line) //no interrupt source left
2560 REG_WR(DCAM_INT_CLR, status);
2561 DCAM_TRACE("DCAM: status 0x%x, ISR 0x%x \n", status, REG_RD(DCAM_INT_STS));
2563 spin_unlock_irqrestore(&dcam_lock, flag);
2568 LOCAL void _dcam_path0_set(void)
2570 uint32_t reg_val = 0;
2571 struct dcam_path_desc *path = NULL;
2573 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
2574 path = &s_p_dcam_mod->dcam_path0;
2575 if (path->valid_param.input_size) {
2576 reg_val = path->input_size.w | (path->input_size.h << 16);
2577 REG_WR(DCAM_PATH0_SRC_SIZE, reg_val);
2580 if (path->valid_param.output_format) {
2581 enum dcam_output_mode format = path->output_format;
2582 REG_MWR(DCAM_PATH0_CFG, BIT_2, format << 2);
2583 DCAM_TRACE("DCAM: path 0: output_format=0x%x \n", format);
2586 if (path->valid_param.frame_deci) {
2587 REG_MWR(DCAM_PATH0_CFG, BIT_1 | BIT_0, path->frame_deci << 0);
2590 if (path->valid_param.data_endian) {
2591 dcam_glb_reg_mwr(DCAM_ENDIAN_SEL, BIT_5 | BIT_4, path->data_endian.y_endian << 4, DCAM_ENDIAN_REG);
2592 dcam_glb_reg_mwr(DCAM_ENDIAN_SEL, BIT_18, BIT_18, DCAM_ENDIAN_REG); // axi write
2593 dcam_glb_reg_mwr(DCAM_ENDIAN_SEL, BIT_19, BIT_19, DCAM_ENDIAN_REG); // axi read
2594 DCAM_TRACE("DCAM DRV: path 0: data_endian y=0x%x, uv=0x%x \n",
2595 path->data_endian.y_endian, path->data_endian.uv_endian);
2599 LOCAL void _dcam_path1_set(struct dcam_path_desc *path)
2601 uint32_t reg_val = 0;
2603 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
2604 DCAM_CHECK_ZERO_VOID(path);
2606 if (path->valid_param.input_size) {
2607 reg_val = path->input_size.w | (path->input_size.h << 16);
2608 REG_WR(DCAM_PATH1_SRC_SIZE, reg_val);
2609 DCAM_TRACE("DCAM: path1 set: src {%d %d} \n",path->input_size.w, path->input_size.h);
2612 if (path->valid_param.input_rect) {
2613 reg_val = path->input_rect.x | (path->input_rect.y << 16);
2614 REG_WR(DCAM_PATH1_TRIM_START, reg_val);
2615 reg_val = path->input_rect.w | (path->input_rect.h << 16);
2616 REG_WR(DCAM_PATH1_TRIM_SIZE, reg_val);
2617 DCAM_TRACE("DCAM: path1 set: rect {%d %d %d %d} \n",
2621 path->input_rect.h);
2624 if (path->valid_param.output_size) {
2625 reg_val = path->output_size.w | (path->output_size.h << 16);
2626 REG_WR(DCAM_PATH1_DST_SIZE, reg_val);
2627 DCAM_TRACE("DCAM: path1 set: dst {%d %d} \n",path->output_size.w, path->output_size.h);
2630 if (path->valid_param.output_format) {
2631 enum dcam_fmt format = path->output_format;
2632 if (DCAM_YUV422 == format) {
2633 REG_MWR(DCAM_PATH1_CFG, BIT_7 | BIT_6, 0 << 6);
2634 } else if (DCAM_YUV420 == format) {
2635 REG_MWR(DCAM_PATH1_CFG, BIT_7 | BIT_6, 1 << 6);
2636 } else if (DCAM_YUV420_3FRAME == format) {
2637 REG_MWR(DCAM_PATH1_CFG, BIT_7 | BIT_6, 3 << 6);
2639 DCAM_TRACE("DCAM: invalid path 1 output format %d \n", format);
2641 DCAM_TRACE("DCAM: path 1: output_format=0x%x \n", format);
2644 if (path->valid_param.src_sel) {
2645 REG_MWR(DCAM_CFG, BIT_12 | BIT_11, path->src_sel << 11);
2646 DCAM_TRACE("DCAM: path 1: src_sel=0x%x \n", path->src_sel);
2649 if (path->valid_param.data_endian) {
2650 dcam_glb_reg_mwr(DCAM_ENDIAN_SEL, BIT_7 | BIT_6, path->data_endian.y_endian << 6, DCAM_ENDIAN_REG);
2651 dcam_glb_reg_mwr(DCAM_ENDIAN_SEL, BIT_9 | BIT_8, path->data_endian.uv_endian << 8, DCAM_ENDIAN_REG);
2652 dcam_glb_reg_mwr(DCAM_ENDIAN_SEL, BIT_18, BIT_18, DCAM_ENDIAN_REG); // axi write
2653 dcam_glb_reg_mwr(DCAM_ENDIAN_SEL, BIT_19, BIT_19, DCAM_ENDIAN_REG); // axi read
2654 DCAM_TRACE("DCAM: path 1: data_endian y=0x%x, uv=0x%x \n",
2655 path->data_endian.y_endian, path->data_endian.uv_endian);
2658 if (path->valid_param.frame_deci) {
2659 REG_MWR(DCAM_PATH0_CFG, BIT_24 | BIT_23, path->frame_deci << 23);
2660 DCAM_TRACE("DCAM: path 1: frame_deci=0x%x \n", path->frame_deci);
2663 if (path->valid_param.scale_tap) {
2664 path->valid_param.scale_tap = 0;
2665 REG_MWR(DCAM_PATH1_CFG, BIT_19 | BIT_18 | BIT_17 | BIT_16, (path->scale_tap.y_tap & 0x0F) << 16);
2666 REG_MWR(DCAM_PATH1_CFG, BIT_15 | BIT_14 | BIT_13 | BIT_12 | BIT_11, (path->scale_tap.uv_tap & 0x1F) << 11);
2667 DCAM_TRACE("DCAM: path 1: scale_tap, y=0x%x, uv=0x%x \n", path->scale_tap.y_tap, path->scale_tap.uv_tap);
2670 if (path->valid_param.v_deci) {
2671 path->valid_param.v_deci = 0;
2672 REG_MWR(DCAM_PATH1_CFG, BIT_2, path->deci_val.deci_x_en << 2);
2673 REG_MWR(DCAM_PATH1_CFG, BIT_1 | BIT_0, path->deci_val.deci_x);
2675 REG_MWR(DCAM_PATH1_CFG, BIT_5, path->deci_val.deci_y_en << 5);
2676 REG_MWR(DCAM_PATH1_CFG, BIT_4 | BIT_3, path->deci_val.deci_y << 3);
2677 DCAM_TRACE("DCAM: path 1: deci, x_en=%d, x=%d, y_en=%d, y=%d \n",
2678 path->deci_val.deci_x_en, path->deci_val.deci_x, path->deci_val.deci_y_en, path->deci_val.deci_y);
2682 LOCAL void _dcam_path2_set(void)
2684 struct dcam_path_desc *path = NULL;
2685 uint32_t reg_val = 0;
2687 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
2688 path = &s_p_dcam_mod->dcam_path2;
2689 if (path->valid_param.input_size) {
2690 reg_val = path->input_size.w | (path->input_size.h << 16);
2691 REG_WR(DCAM_PATH2_SRC_SIZE, reg_val);
2692 DCAM_TRACE("DCAM: path2 set: src {%d %d} \n",path->input_size.w, path->input_size.h);
2695 if (path->valid_param.input_rect) {
2696 reg_val = path->input_rect.x | (path->input_rect.y << 16);
2697 REG_WR(DCAM_PATH2_TRIM_START, reg_val);
2698 reg_val = path->input_rect.w | (path->input_rect.h << 16);
2699 REG_WR(DCAM_PATH2_TRIM_SIZE, reg_val);
2700 DCAM_TRACE("DCAM: path2 set: rect {%d %d %d %d} \n",
2704 path->input_rect.h);
2707 if(path->valid_param.output_size){
2708 reg_val = path->output_size.w | (path->output_size.h << 16);
2709 REG_WR(DCAM_PATH2_DST_SIZE, reg_val);
2710 DCAM_TRACE("DCAM: path2 set: dst {%d %d} \n",path->output_size.w, path->output_size.h);
2713 if (path->valid_param.output_format) {
2714 enum dcam_fmt format = path->output_format;
2716 // REG_MWR(DCAM_PATH2_CFG, BIT_8, 0 << 8); // aiden todo
2718 if (DCAM_YUV422 == format) {
2719 REG_MWR(DCAM_PATH2_CFG, BIT_7 | BIT_6, 0 << 6);
2720 } else if (DCAM_YUV420 == format) {
2721 REG_MWR(DCAM_PATH2_CFG, BIT_7 | BIT_6, 1 << 6);
2722 } else if (DCAM_YUV420_3FRAME == format) {
2723 REG_MWR(DCAM_PATH2_CFG, BIT_7 | BIT_6, 3 << 6);
2725 DCAM_TRACE("DCAM: invalid path 2 output format %d \n", format);
2727 DCAM_TRACE("DCAM: path 2: output_format=0x%x \n", format);
2730 if (path->valid_param.src_sel) {
2731 REG_MWR(DCAM_CFG, BIT_14 | BIT_13, path->src_sel << 13);
2734 if (path->valid_param.data_endian) {
2735 dcam_glb_reg_mwr(DCAM_ENDIAN_SEL, BIT_11 | BIT_10, path->data_endian.y_endian << 10,DCAM_ENDIAN_REG );
2736 dcam_glb_reg_mwr(DCAM_ENDIAN_SEL, BIT_13 | BIT_12, path->data_endian.uv_endian << 12, DCAM_ENDIAN_REG);
2737 dcam_glb_reg_mwr(DCAM_ENDIAN_SEL, BIT_18, BIT_18, DCAM_ENDIAN_REG); // axi write
2738 dcam_glb_reg_mwr(DCAM_ENDIAN_SEL, BIT_19, BIT_19, DCAM_ENDIAN_REG); // axi read
2739 DCAM_TRACE("DCAM: path 2: data_endian y=0x%x, uv=0x%x \n",
2740 path->data_endian.y_endian, path->data_endian.uv_endian);
2743 if (path->valid_param.frame_deci) {
2744 REG_MWR(DCAM_PATH0_CFG, BIT_24 | BIT_23, path->frame_deci << 23);
2745 DCAM_TRACE("DCAM: path 2: frame_deci=0x%x \n", path->frame_deci);
2748 if (path->valid_param.scale_tap) {
2749 path->valid_param.scale_tap = 0;
2750 REG_MWR(DCAM_PATH2_CFG, BIT_19 | BIT_18 | BIT_17 | BIT_16, (path->scale_tap.y_tap & 0x0F) << 16);
2751 REG_MWR(DCAM_PATH2_CFG, BIT_15 | BIT_14 | BIT_13 | BIT_12 | BIT_11, (path->scale_tap.uv_tap & 0x1F) << 11);
2752 DCAM_TRACE("DCAM: path 2: scale_tap, y=0x%x, uv=0x%x \n",
2753 path->scale_tap.y_tap, path->scale_tap.uv_tap);
2756 if (path->valid_param.v_deci) {
2757 path->valid_param.v_deci = 0;
2758 REG_MWR(DCAM_PATH2_CFG, BIT_2, path->deci_val.deci_x_en << 2);
2759 REG_MWR(DCAM_PATH2_CFG, BIT_1 | BIT_0, path->deci_val.deci_x);
2761 REG_MWR(DCAM_PATH2_CFG, BIT_5, path->deci_val.deci_y_en << 5);
2762 REG_MWR(DCAM_PATH2_CFG, BIT_4 | BIT_3, path->deci_val.deci_y << 3);
2763 DCAM_TRACE("DCAM: path 2: deci, x_en=%d, x=%d, y_en=%d, y=%d \n",
2764 path->deci_val.deci_x_en, path->deci_val.deci_x, path->deci_val.deci_y_en, path->deci_val.deci_y);
2768 LOCAL void _dcam_buf_queue_init(struct dcam_buf_queue *queue)
2770 if (DCAM_ADDR_INVALID(queue)) {
2771 printk("DCAM: invalid heap 0x%x \n", (uint32_t)queue);
2775 memset((void*)queue, 0, sizeof(struct dcam_buf_queue));
2776 queue->write = &queue->frame[0];
2777 queue->read = &queue->frame[0];
2778 spin_lock_init(&queue->lock);
2782 LOCAL int32_t _dcam_buf_queue_write(struct dcam_buf_queue *queue, struct dcam_frame *frame)
2784 int ret = DCAM_RTN_SUCCESS;
2785 struct dcam_frame *ori_frame;
2788 if (DCAM_ADDR_INVALID(queue) || DCAM_ADDR_INVALID(frame)) {
2789 printk("DCAM: enq, invalid param 0x%x, 0x%x \n",
2795 spin_lock_irqsave(&queue->lock, flag);
2796 ori_frame = queue->write;
2797 DCAM_TRACE("DCAM: _dcam_buf_queue_write \n");
2798 *queue->write++ = *frame;
2799 if (queue->write > &queue->frame[DCAM_FRM_CNT_MAX-1]) {
2800 queue->write = &queue->frame[0];
2803 if (queue->write == queue->read) {
2804 queue->write = ori_frame;
2805 printk("DCAM: warning, queue is full, cannot write 0x%lx \n", frame->yaddr);
2807 spin_unlock_irqrestore(&queue->lock, flag);
2808 DCAM_TRACE("DCAM: _dcam_buf_queue_write type %d \n", frame->type);
2812 LOCAL int32_t _dcam_buf_queue_read(struct dcam_buf_queue *queue, struct dcam_frame *frame)
2814 int ret = DCAM_RTN_SUCCESS;
2817 if (DCAM_ADDR_INVALID(queue) || DCAM_ADDR_INVALID(frame)) {
2818 printk("DCAM: deq, invalid param 0x%x, 0x%x \n",
2824 DCAM_TRACE("DCAM: _dcam_buf_queue_read \n");
2826 spin_lock_irqsave(&queue->lock, flag);
2827 if (queue->read != queue->write) {
2828 *frame = *queue->read++;
2829 if (queue->read > &queue->frame[DCAM_FRM_CNT_MAX-1]) {
2830 queue->read = &queue->frame[0];
2835 spin_unlock_irqrestore(&queue->lock, flag);
2836 DCAM_TRACE("DCAM: _dcam_buf_queue_read type %d \n", frame->type);
2840 LOCAL void _dcam_frm_queue_clear(struct dcam_frm_queue *queue)
2842 if (DCAM_ADDR_INVALID(queue)) {
2843 printk("DCAM: invalid heap 0x%x \n", (uint32_t)queue);
2847 memset((void*)queue, 0, sizeof(struct dcam_frm_queue));
2851 LOCAL int32_t _dcam_frame_enqueue(struct dcam_frm_queue *queue, struct dcam_frame *frame)
2853 if (DCAM_ADDR_INVALID(queue) || DCAM_ADDR_INVALID(frame)) {
2854 printk("DCAM: enq, invalid param 0x%x, 0x%x \n",
2859 if (queue->valid_cnt >= DCAM_FRM_QUEUE_LENGTH) {
2860 printk("DCAM: q over flow \n");
2863 //queue->frm_array[queue->valid_cnt] = frame;
2864 memcpy(&queue->frm_array[queue->valid_cnt], frame, sizeof(struct dcam_frame));
2865 queue->valid_cnt ++;
2866 DCAM_TRACE("DCAM: en queue, %d, %d, 0x%x, 0x%x \n",
2874 LOCAL int32_t _dcam_frame_dequeue(struct dcam_frm_queue *queue, struct dcam_frame *frame)
2878 if (DCAM_ADDR_INVALID(queue) || DCAM_ADDR_INVALID(frame)) {
2879 printk("DCAM: deq, invalid param 0x%x, 0x%x \n",
2884 if (queue->valid_cnt == 0) {
2885 printk("DCAM: q under flow \n");
2889 //*frame = queue->frm_array[0];
2890 memcpy(frame, &queue->frm_array[0], sizeof(struct dcam_frame));
2892 for (i = 0; i < queue->valid_cnt; i++) {
2893 //queue->frm_array[i] = queue->frm_array[i+1];
2894 memcpy(&queue->frm_array[i], &queue->frm_array[i+1], sizeof(struct dcam_frame));
2896 DCAM_TRACE("DCAM: de queue, %d, %d \n",
2897 (0xF & (frame)->fid),
2902 LOCAL void _dcam_frm_clear(enum dcam_path_index path_index)
2906 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
2908 if (DCAM_PATH_IDX_0 & path_index) {
2909 _dcam_frm_queue_clear(&s_p_dcam_mod->dcam_path0.frame_queue);
2910 _dcam_buf_queue_init(&s_p_dcam_mod->dcam_path0.buf_queue);
2913 if (DCAM_PATH_IDX_1 & path_index) {
2914 _dcam_frm_queue_clear(&s_p_dcam_mod->dcam_path1.frame_queue);
2915 _dcam_buf_queue_init(&s_p_dcam_mod->dcam_path1.buf_queue);
2918 if (DCAM_PATH_IDX_2 & path_index) {
2919 _dcam_frm_queue_clear(&s_p_dcam_mod->dcam_path2.frame_queue);
2920 _dcam_buf_queue_init(&s_p_dcam_mod->dcam_path2.buf_queue);
2926 LOCAL void _dcam_frm_pop(enum dcam_path_index path_index)
2929 struct dcam_frame *frame = NULL;
2930 uint32_t *frame_count;
2932 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
2934 if (DCAM_PATH_IDX_0 & path_index) {
2935 frame = &s_p_dcam_mod->path0_frame[0];
2936 frame_count = &s_p_dcam_mod->dcam_path0.output_frame_count;
2938 if (DCAM_PATH_IDX_1 & path_index) {
2939 frame = &s_p_dcam_mod->path1_frame[0];
2940 frame_count = &s_p_dcam_mod->dcam_path1.output_frame_count;
2942 if (DCAM_PATH_IDX_2 & path_index) {
2943 frame = &s_p_dcam_mod->path2_frame[0];
2944 frame_count = &s_p_dcam_mod->dcam_path2.output_frame_count;
2946 printk("DCAM: frame pop index %d frame_count %d addr 0x%x \n", path_index, *frame_count, frame->yaddr);
2947 if (0 == *frame_count) {
2951 for (i = 0; i < *frame_count - 1; i++) {
2952 memcpy(frame+i, frame+i+1, sizeof(struct dcam_frame));
2955 //memset(frame+(*frame_count), 0, sizeof(struct dcam_frame));
2956 (frame+(*frame_count))->yaddr = 0;
2957 (frame+(*frame_count))->uaddr = 0;
2958 (frame+(*frame_count))->vaddr = 0;
2960 if (0 == *frame_count) {
2961 //_dcam_wait_for_quickstop(path_index);
2963 DCAM_TRACE("DCAM: frame pop done \n");
2969 LOCAL void _dcam_link_frm(uint32_t base_id)
2972 struct dcam_frame *path0_frame = NULL;
2973 struct dcam_frame *path1_frame = NULL;
2974 struct dcam_frame *path2_frame = NULL;
2976 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
2978 path0_frame = &s_p_dcam_mod->path0_frame[0];
2979 path1_frame = &s_p_dcam_mod->path1_frame[0];
2980 path2_frame = &s_p_dcam_mod->path2_frame[0];
2981 for (i = 0; i < DCAM_PATH_0_FRM_CNT_MAX; i++) {
2982 DCAM_CLEAR(path0_frame + i);
2983 //(path0_frame+i)->next = path0_frame + (i + 1) % DCAM_PATH_0_FRM_CNT_MAX;
2984 //(path0_frame+i)->prev = path0_frame + (i - 1 + DCAM_PATH_0_FRM_CNT_MAX) % DCAM_PATH_0_FRM_CNT_MAX;
2985 (path0_frame+i)->fid = base_id + i;
2988 for (i = 0; i < DCAM_PATH_1_FRM_CNT_MAX; i++) {
2989 DCAM_CLEAR(path1_frame + i);
2990 //(path1_frame+i)->next = path1_frame + (i + 1) % DCAM_PATH_1_FRM_CNT_MAX;
2991 //(path1_frame+i)->prev = path1_frame + (i - 1 + DCAM_PATH_1_FRM_CNT_MAX) % DCAM_PATH_1_FRM_CNT_MAX;
2992 (path1_frame+i)->fid = base_id + i;
2995 for (i = 0; i < DCAM_PATH_2_FRM_CNT_MAX; i++) {
2996 DCAM_CLEAR(path2_frame + i);
2997 //(path2_frame+i)->next = path2_frame+(i + 1) % DCAM_PATH_2_FRM_CNT_MAX;
2998 //(path2_frame+i)->prev = path2_frame+(i - 1 + DCAM_PATH_2_FRM_CNT_MAX) % DCAM_PATH_2_FRM_CNT_MAX;
2999 (path2_frame+i)->fid = base_id + i;
3002 //s_p_dcam_mod->dcam_path0.output_frame_head = path0_frame;
3003 //s_p_dcam_mod->dcam_path1.output_frame_head = path1_frame;
3004 //s_p_dcam_mod->dcam_path2.output_frame_head = path2_frame;
3005 //s_p_dcam_mod->dcam_path0.output_frame_cur = path0_frame;
3006 //s_p_dcam_mod->dcam_path1.output_frame_cur = path1_frame;
3007 //s_p_dcam_mod->dcam_path2.output_frame_cur = path2_frame;
3012 LOCAL int32_t _dcam_path_set_next_frm(enum dcam_path_index path_index, uint32_t is_1st_frm)
3014 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
3015 struct dcam_frame frame;
3016 struct dcam_frame *reserved_frame = NULL;
3017 struct dcam_frame *orig_frame = NULL;
3018 struct dcam_path_desc *path = NULL;
3019 uint32_t yuv_reg[3] = {0};
3020 uint32_t path_max_frm_cnt;
3022 struct dcam_frm_queue *p_heap = NULL;
3023 struct dcam_buf_queue *p_buf_queue = NULL;
3025 DCAM_CHECK_ZERO(s_p_dcam_mod);
3027 if (DCAM_PATH_IDX_0 == path_index) {
3028 //frame = &s_p_dcam_mod->path0_frame[0];
3029 reserved_frame = &s_p_dcam_mod->path0_reserved_frame;
3030 path = &s_p_dcam_mod->dcam_path0;
3031 yuv_reg[0] = DCAM_FRM_ADDR0;
3032 path_max_frm_cnt = DCAM_PATH_0_FRM_CNT_MAX;
3033 p_heap = &s_p_dcam_mod->dcam_path0.frame_queue;
3034 p_buf_queue = &s_p_dcam_mod->dcam_path0.buf_queue;
3035 } else if (DCAM_PATH_IDX_1 == path_index) {
3036 //frame = &s_p_dcam_mod->path1_frame[0];
3037 reserved_frame = &s_p_dcam_mod->path1_reserved_frame;
3038 path = &s_p_dcam_mod->dcam_path1;
3039 yuv_reg[0] = DCAM_FRM_ADDR1;
3040 yuv_reg[1] = DCAM_FRM_ADDR2;
3041 yuv_reg[2] = DCAM_FRM_ADDR3;
3042 path_max_frm_cnt = DCAM_PATH_1_FRM_CNT_MAX;
3043 p_heap = &s_p_dcam_mod->dcam_path1.frame_queue;
3044 p_buf_queue = &s_p_dcam_mod->dcam_path1.buf_queue;
3045 } else /*if(DCAM_PATH_IDX_2 == path_index)*/ {
3046 //frame = &s_p_dcam_mod->path2_frame[0];
3047 reserved_frame = &s_p_dcam_mod->path2_reserved_frame;
3048 path = &s_p_dcam_mod->dcam_path2;
3049 yuv_reg[0] = DCAM_FRM_ADDR4;
3050 yuv_reg[1] = DCAM_FRM_ADDR5;
3051 yuv_reg[2] = DCAM_FRM_ADDR6;
3052 path_max_frm_cnt = DCAM_PATH_2_FRM_CNT_MAX;
3053 p_heap = &s_p_dcam_mod->dcam_path2.frame_queue;
3054 p_buf_queue = &s_p_dcam_mod->dcam_path2.buf_queue;
3057 if (0 != _dcam_buf_queue_read(p_buf_queue, &frame)) {
3058 DCAM_TRACE("DCAM: No freed frame id %d \n", frame.fid);
3059 memcpy(&frame, reserved_frame, sizeof(struct dcam_frame));
3062 DCAM_TRACE("DCAM: next %d y 0x%x uv 0x%x \n", path->output_frame_count, frame.yaddr, frame.uaddr);
3063 REG_WR(yuv_reg[0], frame.yaddr);
3064 if ((DCAM_YUV400 > path->output_format) && (DCAM_PATH_IDX_0 != path_index)) {
3065 REG_WR(yuv_reg[1], frame.uaddr);
3066 if (DCAM_YUV420_3FRAME == path->output_format) {
3067 REG_WR(yuv_reg[2], frame.vaddr);
3070 dcam_frame_lock(&frame);
3071 if (0 == _dcam_frame_enqueue(p_heap, &frame)) {
3073 dcam_frame_unlock(&frame);
3074 rtn = DCAM_RTN_PATH_FRAME_LOCKED;
3081 LOCAL int32_t _dcam_path_trim(enum dcam_path_index path_index)
3083 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
3084 struct dcam_path_desc *path;
3085 uint32_t cfg_reg, ctrl_bit;
3087 DCAM_CHECK_ZERO(s_p_dcam_mod);
3089 if (DCAM_PATH_IDX_1 == path_index) {
3090 path = &s_p_dcam_mod->dcam_path1;
3091 cfg_reg = DCAM_PATH1_CFG;
3093 } else if (DCAM_PATH_IDX_2 == path_index) {
3094 path = &s_p_dcam_mod->dcam_path2;
3095 cfg_reg = DCAM_PATH2_CFG;
3098 printk("DCAM: _dcam_path_trim invalid path_index=%d \n", path_index);
3102 if (path->input_size.w != path->input_rect.w ||
3103 path->input_size.h != path->input_rect.h) {
3104 /*REG_OWR(cfg_reg, 1 << ctrl_bit);*/
3106 /*REG_MWR(cfg_reg, 1 << ctrl_bit, 0 << ctrl_bit);*/
3114 LOCAL int32_t _dcam_path_scaler(enum dcam_path_index path_index)
3116 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
3117 struct dcam_path_desc *path = NULL;
3118 uint32_t cfg_reg = 0;
3120 DCAM_CHECK_ZERO(s_p_dcam_mod);
3121 DCAM_CHECK_ZERO(s_dcam_sc_array);
3123 if (DCAM_PATH_IDX_1 == path_index) {
3124 path = &s_p_dcam_mod->dcam_path1;
3125 cfg_reg = DCAM_PATH1_CFG;
3126 } else if (DCAM_PATH_IDX_2 == path_index){
3127 path = &s_p_dcam_mod->dcam_path2;
3128 cfg_reg = DCAM_PATH2_CFG;
3131 DCAM_CHECK_ZERO(path);
3132 if (DCAM_RAWRGB == path->output_format ||
3133 DCAM_JPEG == path->output_format) {
3134 DCAM_TRACE("DCAM: _dcam_path_scaler out format is %d, no need scaler \n", path->output_format);
3135 return DCAM_RTN_SUCCESS;
3138 rtn = _dcam_calc_sc_size(path_index);
3139 if (DCAM_RTN_SUCCESS != rtn) {
3143 if (path->sc_input_size.w == path->output_size.w &&
3144 path->sc_input_size.h == path->output_size.h &&
3145 DCAM_YUV422 == path->output_format) {
3146 REG_MWR(cfg_reg, BIT_20, 1 << 20);// bypass scaler if the output size equals input size for YUV422 format
3148 REG_MWR(cfg_reg, BIT_20, 0 << 20);
3149 if (s_dcam_sc_array->is_smooth_zoom
3150 && DCAM_PATH_IDX_1 == path_index
3151 && DCAM_ST_START == path->status) {
3152 rtn = _dcam_calc_sc_coeff(path_index);
3154 rtn = _dcam_set_sc_coeff(path_index);
3161 LOCAL int32_t _dcam_path_check_deci(enum dcam_path_index path_index, uint32_t *is_deci)
3163 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
3164 struct dcam_path_desc *path = NULL;
3165 uint32_t w_deci = 0;
3166 uint32_t h_deci = 0;
3168 DCAM_CHECK_ZERO(s_p_dcam_mod);
3170 if (DCAM_PATH_IDX_1 == path_index) {
3171 path = &s_p_dcam_mod->dcam_path1;
3172 } else if (DCAM_PATH_IDX_2 == path_index) {
3173 path = &s_p_dcam_mod->dcam_path2;
3175 rtn = DCAM_RTN_PATH_SC_ERR;
3179 if (path->input_rect.w > (path->output_size.w * DCAM_SC_COEFF_DOWN_MAX * (1<<DCAM_PATH_DECI_FAC_MAX)) ||
3180 path->input_rect.h > (path->output_size.h * DCAM_SC_COEFF_DOWN_MAX * (1<<DCAM_PATH_DECI_FAC_MAX)) ||
3181 path->input_rect.w * DCAM_SC_COEFF_UP_MAX < path->output_size.w ||
3182 path->input_rect.h * DCAM_SC_COEFF_UP_MAX < path->output_size.h) {
3183 rtn = DCAM_RTN_PATH_SC_ERR;
3185 if (path->input_rect.w > path->output_size.w * DCAM_SC_COEFF_DOWN_MAX)
3187 if (path->input_rect.h > path->output_size.h * DCAM_SC_COEFF_DOWN_MAX)
3190 if(w_deci || h_deci)
3197 DCAM_TRACE("DCAM: _dcam_path_check_deci: path_index=%d, is_deci=%d, rtn=%d \n", path_index, *is_deci, rtn);
3202 LOCAL uint32_t _dcam_get_path_deci_factor(uint32_t src_size, uint32_t dst_size)
3204 uint32_t factor = 0;
3206 if (0 == src_size || 0 == dst_size) {
3210 /* factor: 0 - 1/2, 1 - 1/4, 2 - 1/8, 3 - 1/16 */
3211 for (factor = 0; factor < DCAM_PATH_DECI_FAC_MAX; factor ++) {
3212 if (src_size < (uint32_t)(dst_size * (1 << (factor + 1)))) {
3220 LOCAL int32_t _dcam_calc_sc_size(enum dcam_path_index path_index)
3222 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
3223 struct dcam_path_desc *path = NULL;
3224 uint32_t cfg_reg = 0;
3225 uint32_t tmp_dstsize = 0;
3226 uint32_t align_size = 0;
3228 DCAM_CHECK_ZERO(s_p_dcam_mod);
3230 if (DCAM_PATH_IDX_1 == path_index) {
3231 path = &s_p_dcam_mod->dcam_path1;
3232 cfg_reg = DCAM_PATH1_CFG;
3233 } else if (DCAM_PATH_IDX_2 == path_index){
3234 path = &s_p_dcam_mod->dcam_path2;
3235 cfg_reg = DCAM_PATH2_CFG;
3238 DCAM_CHECK_ZERO(path);
3239 if (path->input_rect.w > (path->output_size.w * DCAM_SC_COEFF_DOWN_MAX * (1<<DCAM_PATH_DECI_FAC_MAX)) ||
3240 path->input_rect.h > (path->output_size.h * DCAM_SC_COEFF_DOWN_MAX * (1<<DCAM_PATH_DECI_FAC_MAX)) ||
3241 path->input_rect.w * DCAM_SC_COEFF_UP_MAX < path->output_size.w ||
3242 path->input_rect.h * DCAM_SC_COEFF_UP_MAX < path->output_size.h) {
3243 rtn = DCAM_RTN_PATH_SC_ERR;
3245 path->sc_input_size.w = path->input_rect.w;
3246 path->sc_input_size.h = path->input_rect.h;
3247 if (path->input_rect.w > path->output_size.w * DCAM_SC_COEFF_DOWN_MAX) {
3248 tmp_dstsize = path->output_size.w * DCAM_SC_COEFF_DOWN_MAX;
3249 path->deci_val.deci_x = _dcam_get_path_deci_factor(path->input_rect.w, tmp_dstsize);
3250 path->deci_val.deci_x_en = 1;
3251 path->valid_param.v_deci = 1;
3252 align_size = (1 << (path->deci_val.deci_x+1))*DCAM_PIXEL_ALIGN_WIDTH;
3253 path->input_rect.w = (path->input_rect.w) & ~(align_size-1);
3254 path->input_rect.x = (path->input_rect.x) & ~(align_size-1);
3255 path->sc_input_size.w = path->input_rect.w >> (path->deci_val.deci_x+1);
3257 path->deci_val.deci_x = 0;
3258 path->deci_val.deci_x_en = 0;
3259 path->valid_param.v_deci = 1;
3262 if (path->input_rect.h > path->output_size.h * DCAM_SC_COEFF_DOWN_MAX) {
3263 tmp_dstsize = path->output_size.h * DCAM_SC_COEFF_DOWN_MAX;
3264 path->deci_val.deci_y = _dcam_get_path_deci_factor(path->input_rect.h, tmp_dstsize);
3265 path->deci_val.deci_y_en = 1;
3266 path->valid_param.v_deci = 1;
3267 align_size = (1 << (path->deci_val.deci_y+1))*DCAM_PIXEL_ALIGN_HEIGHT;
3268 path->input_rect.h = (path->input_rect.h) & ~(align_size-1);
3269 path->input_rect.y = (path->input_rect.y) & ~(align_size-1);
3270 path->sc_input_size.h = path->input_rect.h >> (path->deci_val.deci_y+1);
3272 path->deci_val.deci_y = 0;
3273 path->deci_val.deci_y_en = 0;
3274 path->valid_param.v_deci = 1;
3279 DCAM_TRACE("DCAM: _dcam_calc_sc_size, path=%d, x_en=%d, deci_x=%d, y_en=%d, deci_y=%d \n",
3280 path_index, path->deci_val.deci_x_en,
3281 path->deci_val.deci_x, path->deci_val.deci_y_en,
3282 path->deci_val.deci_y);
3287 LOCAL int32_t _dcam_set_sc_coeff(enum dcam_path_index path_index)
3289 struct dcam_path_desc *path = NULL;
3291 uint32_t h_coeff_addr = DCAM_BASE;
3292 uint32_t v_coeff_addr = DCAM_BASE;
3293 uint32_t v_chroma_coeff_addr = DCAM_BASE;
3294 uint32_t *tmp_buf = NULL;
3295 uint32_t *h_coeff = NULL;
3296 uint32_t *v_coeff = NULL;
3297 uint32_t *v_chroma_coeff = NULL;
3298 uint32_t clk_switch_bit = 0;
3299 uint32_t clk_switch_shift_bit = 0;
3300 uint32_t clk_status_bit = 0;
3301 uint32_t ver_tap_reg = 0;
3302 uint32_t scale2yuv420 = 0;
3307 DCAM_CHECK_ZERO(s_p_dcam_mod);
3309 if (DCAM_PATH_IDX_1 != path_index && DCAM_PATH_IDX_2 != path_index)
3310 return -DCAM_RTN_PARA_ERR;
3312 if (DCAM_PATH_IDX_1 == path_index) {
3313 path = &s_p_dcam_mod->dcam_path1;
3314 h_coeff_addr += DCAM_SC1_H_TAB_OFFSET;
3315 v_coeff_addr += DCAM_SC1_V_TAB_OFFSET;
3316 v_chroma_coeff_addr += DCAM_SC1_V_CHROMA_TAB_OFFSET;
3317 clk_switch_bit = BIT_3;
3318 clk_switch_shift_bit = 3;
3319 clk_status_bit = BIT_5;
3320 ver_tap_reg = DCAM_PATH1_CFG;
3321 } else if (DCAM_PATH_IDX_2 == path_index) {
3322 path = &s_p_dcam_mod->dcam_path2;
3323 h_coeff_addr += DCAM_SC2_H_TAB_OFFSET;
3324 v_coeff_addr += DCAM_SC2_V_TAB_OFFSET;
3325 v_chroma_coeff_addr += DCAM_SC2_V_CHROMA_TAB_OFFSET;
3326 clk_switch_bit = BIT_4;
3327 clk_switch_shift_bit = 4;
3328 clk_status_bit = BIT_6;
3329 ver_tap_reg = DCAM_PATH2_CFG;
3332 if (DCAM_YUV420 == path->output_format) {
3336 DCAM_TRACE("DCAM: _dcam_set_sc_coeff {%d %d %d %d}, 420=%d \n",
3337 path->sc_input_size.w,
3338 path->sc_input_size.h,
3339 path->output_size.w,
3340 path->output_size.h, scale2yuv420);
3343 tmp_buf = dcam_get_scale_coeff_addr(&index);
3345 if (NULL == tmp_buf) {
3346 return -DCAM_RTN_PATH_NO_MEM;
3350 v_coeff = tmp_buf + (DCAM_SC_COEFF_COEF_SIZE/4);
3351 v_chroma_coeff = v_coeff + (DCAM_SC_COEFF_COEF_SIZE/4);
3353 down(&s_p_dcam_mod->scale_coeff_mem_sema);
3355 if (!(Dcam_GenScaleCoeff((int16_t)path->sc_input_size.w,
3356 (int16_t)path->sc_input_size.h,
3357 (int16_t)path->output_size.w,
3358 (int16_t)path->output_size.h,
3365 tmp_buf + (DCAM_SC_COEFF_COEF_SIZE*3/4),
3366 DCAM_SC_COEFF_TMP_SIZE))) {
3367 printk("DCAM: _dcam_set_sc_coeff Dcam_GenScaleCoeff error! \n");
3368 up(&s_p_dcam_mod->scale_coeff_mem_sema);
3369 return -DCAM_RTN_PATH_GEN_COEFF_ERR;
3372 for (i = 0; i < DCAM_SC_COEFF_H_NUM; i++) {
3373 REG_WR(h_coeff_addr, *h_coeff);
3378 for (i = 0; i < DCAM_SC_COEFF_V_NUM; i++) {
3379 REG_WR(v_coeff_addr, *v_coeff);
3384 for (i = 0; i < DCAM_SC_COEFF_V_CHROMA_NUM; i++) {
3385 REG_WR(v_chroma_coeff_addr, *v_chroma_coeff);
3386 v_chroma_coeff_addr += 4;
3390 path->scale_tap.y_tap = y_tap;
3391 path->scale_tap.uv_tap = uv_tap;
3392 path->valid_param.scale_tap = 1;
3394 up(&s_p_dcam_mod->scale_coeff_mem_sema);
3396 return DCAM_RTN_SUCCESS;
3399 LOCAL void _dcam_force_copy_ext(enum dcam_path_index path_index, uint32_t path_copy, uint32_t coef_copy)
3401 uint32_t reg_val = 0;
3403 if (DCAM_PATH_IDX_1 == path_index) {
3409 dcam_glb_reg_mwr(DCAM_CONTROL, reg_val, reg_val, DCAM_CONTROL_REG);
3410 } else if(DCAM_PATH_IDX_2 == path_index) {
3416 dcam_glb_reg_mwr(DCAM_CONTROL, reg_val, reg_val, DCAM_CONTROL_REG);
3418 DCAM_TRACE("DCAM: _dcam_force_copy_ext invalid path index: %d \n", path_index);
3422 LOCAL void _dcam_auto_copy_ext(enum dcam_path_index path_index, uint32_t path_copy, uint32_t coef_copy)
3424 uint32_t reg_val = 0;
3426 if (DCAM_PATH_IDX_0 == path_index) {
3429 dcam_glb_reg_mwr(DCAM_CONTROL, reg_val, reg_val, DCAM_CONTROL_REG);
3430 } else if (DCAM_PATH_IDX_1 == path_index) {
3435 dcam_glb_reg_mwr(DCAM_CONTROL, reg_val, reg_val, DCAM_CONTROL_REG);
3436 } else if (DCAM_PATH_IDX_2 == path_index) {
3441 dcam_glb_reg_mwr(DCAM_CONTROL, reg_val, reg_val, DCAM_CONTROL_REG);
3443 DCAM_TRACE("DCAM: _dcam_auto_copy_ext invalid path index: %d \n", path_index);
3448 LOCAL void _dcam_force_copy(enum dcam_path_index path_index)
3450 if (DCAM_PATH_IDX_1 == path_index) {
3451 dcam_glb_reg_mwr(DCAM_CONTROL, BIT_10, 1 << 10, DCAM_CONTROL_REG);
3452 } else if (DCAM_PATH_IDX_2 == path_index) {
3453 dcam_glb_reg_mwr(DCAM_CONTROL, BIT_12, 1 << 12, DCAM_CONTROL_REG);
3455 DCAM_TRACE("DCAM: _dcam_force_copy invalid path index: %d \n", path_index);
3459 LOCAL void _dcam_auto_copy(enum dcam_path_index path_index)
3461 if (DCAM_PATH_IDX_0 == path_index) {
3462 dcam_glb_reg_mwr(DCAM_CONTROL, BIT_9, 1 << 9, DCAM_CONTROL_REG);
3463 } else if(DCAM_PATH_IDX_1 == path_index) {
3464 dcam_glb_reg_mwr(DCAM_CONTROL, BIT_11, 1 << 11, DCAM_CONTROL_REG);
3465 } else if(DCAM_PATH_IDX_2 == path_index) {
3466 dcam_glb_reg_mwr(DCAM_CONTROL, BIT_13, 1 << 13, DCAM_CONTROL_REG);
3468 DCAM_TRACE("DCAM: _dcam_auto_copy invalid path index: %d \n", path_index);
3472 LOCAL void _dcam_reg_trace(void)
3474 #ifdef DCAM_DRV_DEBUG
3477 printk("DCAM: Register list");
3478 for (addr = DCAM_CFG; addr <= CAP_SENSOR_CTRL; addr += 16) {
3479 printk("\n 0x%x: 0x%x 0x%x 0x%x 0x%x",
3492 LOCAL void _dcam_sensor_sof(void)
3494 dcam_isr_func user_func = s_user_func[DCAM_SN_SOF];
3495 void *data = s_user_data[DCAM_SN_SOF];
3497 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3499 DCAM_TRACE("DCAM: _sn_sof \n");
3502 (*user_func)(NULL, data);
3509 LOCAL void _dcam_sensor_eof(void)
3511 dcam_isr_func user_func = s_user_func[DCAM_SN_EOF];
3512 void *data = s_user_data[DCAM_SN_EOF];
3514 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3516 DCAM_TRACE("DCAM: _sn_eof \n");
3519 (*user_func)(NULL, data);
3525 LOCAL void _dcam_cap_sof(void)
3527 dcam_isr_func user_func = s_user_func[DCAM_CAP_SOF];
3528 void *data = s_user_data[DCAM_CAP_SOF];
3530 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3532 DCAM_TRACE("DCAM: _cap_sof \n");
3534 _dcam_stopped_notice();
3537 (*user_func)(NULL, data);
3543 LOCAL void _dcam_cap_eof(void)
3545 dcam_isr_func user_func = s_user_func[DCAM_CAP_EOF];
3546 void *data = s_user_data[DCAM_CAP_EOF];
3548 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3551 (*user_func)(NULL, data);
3557 LOCAL void _dcam_path0_done(void)
3559 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
3560 dcam_isr_func user_func = s_user_func[DCAM_PATH0_DONE];
3561 void *data = s_user_data[DCAM_PATH0_DONE];
3562 struct dcam_path_desc *path;
3563 struct dcam_frame frame;
3565 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3566 path = &s_p_dcam_mod->dcam_path0;
3567 if (0 == path->valide) {
3568 printk("DCAM: path0 not valid \n");
3571 if (path->need_stop) {
3572 dcam_glb_reg_awr(DCAM_CFG, ~BIT_0, DCAM_CFG_REG);
3573 path->need_stop = 0;
3575 _dcam_path_done_notice(DCAM_PATH_IDX_0);
3576 DCAM_TRACE("DCAM 0 \n");
3577 rtn = _dcam_path_set_next_frm(DCAM_PATH_IDX_0, false);
3579 printk("DCAM: 0 w \n");
3582 _dcam_auto_copy(DCAM_PATH_IDX_0);
3584 rtn = _dcam_frame_dequeue(&path->frame_queue, &frame);
3585 if (0 == rtn && frame.yaddr != s_p_dcam_mod->path0_reserved_frame.yaddr && 0 != dcam_frame_is_locked(&frame)) {
3586 frame.width = path->output_size.w;
3587 frame.height = path->output_size.h;
3589 (*user_func)(&frame, data);
3592 DCAM_TRACE("DCAM: path0_reserved_frame \n");
3598 LOCAL void _dcam_path0_overflow(void)
3600 dcam_isr_func user_func = s_user_func[DCAM_PATH0_OV];
3601 void *data = s_user_data[DCAM_PATH0_OV];
3602 struct dcam_path_desc *path;
3603 struct dcam_frame frame;
3605 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3607 printk("DCAM: _path0_overflow \n");
3608 path = &s_p_dcam_mod->dcam_path0;
3609 //frame = path->output_frame_cur->prev->prev;
3610 //frame = &s_p_dcam_mod->path0_frame[0];
3611 _dcam_frame_dequeue(&path->frame_queue, &frame);
3614 (*user_func)(&frame, data);
3620 LOCAL void _dcam_path1_done(void)
3622 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
3623 dcam_isr_func user_func = s_user_func[DCAM_PATH1_DONE];
3624 void *data = s_user_data[DCAM_PATH1_DONE];
3625 struct dcam_path_desc *path;
3626 struct dcam_frame frame;
3628 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3629 path = &s_p_dcam_mod->dcam_path1;
3630 if (0 == path->valide) {
3631 printk("DCAM: path1 not valid \n");
3635 DCAM_TRACE("DCAM: 1\n");
3637 if (path->need_stop) {
3638 dcam_glb_reg_awr(DCAM_CFG, ~BIT_1, DCAM_CFG_REG);
3639 path->need_stop = 0;
3641 _dcam_path_done_notice(DCAM_PATH_IDX_1);
3643 if (path->sof_cnt < 1) {
3644 printk("DCAM: path1 done cnt %d\n", path->sof_cnt);
3645 path->need_wait = 0;
3650 if (path->need_wait) {
3651 path->need_wait = 0;
3653 rtn = _dcam_frame_dequeue(&path->frame_queue, &frame);
3654 if (0 == rtn && frame.yaddr != s_p_dcam_mod->path1_reserved_frame.yaddr && 0 != dcam_frame_is_locked(&frame)) {
3655 frame.width = path->output_size.w;
3656 frame.height = path->output_size.h;
3657 DCAM_TRACE("DCAM: path1 frame 0x%x, y uv, 0x%x 0x%x \n",
3658 (int)&frame, frame.yaddr, frame.uaddr);
3660 (*user_func)(&frame, data);
3663 DCAM_TRACE("DCAM: path1_reserved_frame \n");
3669 LOCAL void _dcam_path1_overflow(void)
3671 dcam_isr_func user_func = s_user_func[DCAM_PATH1_OV];
3672 void *data = s_user_data[DCAM_PATH1_OV];
3673 struct dcam_path_desc *path;
3674 struct dcam_frame frame;
3676 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3678 printk("DCAM: _path1_overflow \n");
3679 path = &s_p_dcam_mod->dcam_path1;
3680 //frame = path->output_frame_cur->prev->prev;
3681 _dcam_frame_dequeue(&path->frame_queue, &frame);
3684 (*user_func)(&frame, data);
3690 LOCAL void _dcam_sensor_line_err(void)
3692 dcam_isr_func user_func = s_user_func[DCAM_SN_LINE_ERR];
3693 void *data = s_user_data[DCAM_SN_LINE_ERR];
3695 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3697 printk("DCAM: _line_err \n");
3700 (*user_func)(NULL, data);
3706 LOCAL void _dcam_sensor_frame_err(void)
3708 dcam_isr_func user_func = s_user_func[DCAM_SN_FRAME_ERR];
3709 void *data = s_user_data[DCAM_SN_FRAME_ERR];
3711 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3713 printk("DCAM: _frame_err \n");
3716 (*user_func)(NULL, data);
3722 LOCAL void _dcam_jpeg_buf_ov(void)
3724 dcam_isr_func user_func = s_user_func[DCAM_JPEG_BUF_OV];
3725 void *data = s_user_data[DCAM_JPEG_BUF_OV];
3726 struct dcam_path_desc *path;
3727 struct dcam_frame frame;
3729 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3731 printk("DCAM: _jpeg_overflow \n");
3732 path = &s_p_dcam_mod->dcam_path0;
3733 //frame = path->output_frame_cur->prev->prev;
3734 //frame = &s_p_dcam_mod->path0_frame[0];
3735 _dcam_frame_dequeue(&path->frame_queue, &frame);
3738 (*user_func)(&frame, data);
3744 LOCAL void _dcam_path2_done(void)
3746 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
3747 dcam_isr_func user_func = s_user_func[DCAM_PATH2_DONE];
3748 void *data = s_user_data[DCAM_PATH2_DONE];
3749 struct dcam_path_desc *path;
3750 struct dcam_frame frame;
3752 if (atomic_read(&s_resize_flag)) {
3753 memset(&frame, 0, sizeof(struct dcam_frame));
3755 (*user_func)(&frame, data);
3758 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3759 path = &s_p_dcam_mod->dcam_path2;
3761 DCAM_TRACE("DCAM: 2, %d %d \n", path->need_stop, path->need_wait);
3762 if (path->status == DCAM_ST_START) {
3764 if (path->need_stop) {
3765 dcam_glb_reg_awr(DCAM_CFG, ~BIT_2, DCAM_CFG_REG);
3766 path->need_stop = 0;
3768 _dcam_path_done_notice(DCAM_PATH_IDX_2);
3770 if (path->sof_cnt < 1) {
3771 printk("DCAM: path2 done cnt %d\n", path->sof_cnt);
3772 path->need_wait = 0;
3777 if (path->need_wait) {
3778 path->need_wait = 0;
3780 rtn = _dcam_frame_dequeue(&path->frame_queue, &frame);
3781 if (0 == rtn && frame.yaddr != s_p_dcam_mod->path2_reserved_frame.yaddr && 0 != dcam_frame_is_locked(&frame)) {
3782 DCAM_TRACE("DCAM: path2 frame 0x%x, y uv, 0x%x 0x%x \n",
3783 (int)&frame, frame.yaddr, frame.uaddr);
3784 frame.width = path->output_size.w;
3785 frame.height = path->output_size.h;
3787 (*user_func)(&frame, data);
3790 DCAM_TRACE("DCAM: path2_reserved_frame \n");
3797 LOCAL void _dcam_path2_ov(void)
3799 dcam_isr_func user_func = s_user_func[DCAM_PATH2_OV];
3800 void *data = s_user_data[DCAM_PATH2_OV];
3801 struct dcam_path_desc *path;
3802 struct dcam_frame frame;
3804 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3806 printk("DCAM: _path2_overflow \n");
3807 path = &s_p_dcam_mod->dcam_path2;
3808 //frame = path->output_frame_cur->prev->prev;
3809 //frame = &s_p_dcam_mod->path2_frame[0];
3810 _dcam_frame_dequeue(&path->frame_queue, &frame);
3813 (*user_func)(&frame, data);
3819 LOCAL void _dcam_isp_ov(void)
3821 dcam_isr_func user_func = s_user_func[DCAM_ISP_OV];
3822 void *data = s_user_data[DCAM_ISP_OV];
3824 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3826 printk("DCAM: _isp_overflow \n");
3829 (*user_func)(NULL, data);
3835 LOCAL void _dcam_mipi_ov(void)
3837 dcam_isr_func user_func = s_user_func[DCAM_MIPI_OV];
3838 void *data = s_user_data[DCAM_MIPI_OV];
3840 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3844 (*user_func)(NULL, data);
3847 printk("DCAM: _mipi_overflow \n");
3851 LOCAL void _dcam_rot_done(void)
3853 dcam_isr_func user_func = s_user_func[DCAM_ROT_DONE];
3854 void *data = s_user_data[DCAM_ROT_DONE];
3856 DCAM_TRACE("DCAM: rot_done \n");
3859 (*user_func)(NULL, data);
3865 LOCAL void _dcam_path1_slice_done(void)
3867 dcam_isr_func user_func = s_user_func[DCAM_PATH1_SLICE_DONE];
3868 void *data = s_user_data[DCAM_PATH1_SLICE_DONE];
3870 DCAM_TRACE("DCAM: 1 slice done \n");
3873 (*user_func)(NULL, data);
3879 LOCAL void _dcam_path2_slice_done(void)
3881 dcam_isr_func user_func = s_user_func[DCAM_PATH2_SLICE_DONE];
3882 void *data = s_user_data[DCAM_PATH2_SLICE_DONE];
3884 DCAM_TRACE("DCAM: 2 slice done \n");
3887 (*user_func)(NULL, data);
3893 LOCAL void _dcam_raw_slice_done(void)
3895 dcam_isr_func user_func = s_user_func[DCAM_RAW_SLICE_DONE];
3896 void *data = s_user_data[DCAM_RAW_SLICE_DONE];
3898 DCAM_TRACE("DCAM: 0 slice done \n");
3901 (*user_func)(NULL, data);
3907 LOCAL void _dcam_path1_sof(void)
3909 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
3910 dcam_isr_func user_func = s_user_func[DCAM_PATH1_SOF];
3911 void *data = s_user_data[DCAM_PATH1_SOF];
3912 struct dcam_path_desc *path;
3913 struct dcam_sc_coeff *sc_coeff;
3915 DCAM_TRACE("DCAM: 1 sof done \n");
3917 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3918 DCAM_CHECK_ZERO_VOID(s_dcam_sc_array);
3920 if(s_p_dcam_mod->dcam_path1.status == DCAM_ST_START){
3922 path = &s_p_dcam_mod->dcam_path1;
3923 if (0 == path->valide) {
3924 printk("DCAM: path1 not valid \n");
3928 if (path->sof_cnt > 0) {
3929 printk("DCAM: path1 sof %d \n", path->sof_cnt);
3935 rtn = _dcam_path_set_next_frm(DCAM_PATH_IDX_1, false);
3936 if (path->is_update) {
3937 if (s_dcam_sc_array->is_smooth_zoom) {
3938 _dcam_get_valid_sc_coeff(s_dcam_sc_array, &sc_coeff);
3939 _dcam_write_sc_coeff(DCAM_PATH_IDX_1);
3940 _dcam_path1_set(&sc_coeff->dcam_path1);
3941 _dcam_pop_sc_buf(s_dcam_sc_array, &sc_coeff);
3943 _dcam_path1_set(path);
3945 path->is_update = 0;
3946 DCAM_TRACE("DCAM: path1 updated \n");
3947 _dcam_auto_copy_ext(DCAM_PATH_IDX_1, true, true);
3950 DCAM_TRACE("DCAM: path1 updated \n");
3952 _dcam_auto_copy(DCAM_PATH_IDX_1);
3956 _dcam_path_updated_notice(DCAM_PATH_IDX_1);
3959 path->need_wait = 1;
3960 printk("DCAM: 1 w\n");
3966 (*user_func)(NULL, data);
3972 LOCAL void _dcam_path2_sof(void)
3974 enum dcam_drv_rtn rtn = DCAM_RTN_SUCCESS;
3975 dcam_isr_func user_func = s_user_func[DCAM_PATH2_SOF];
3976 void *data = s_user_data[DCAM_PATH2_SOF];
3977 struct dcam_path_desc *path;
3979 DCAM_TRACE("DCAM: 2 sof done \n");
3981 if (atomic_read(&s_resize_flag)) {
3982 printk("DCAM: path 2 sof, review now \n");
3984 if (DCAM_ADDR_INVALID(s_p_dcam_mod)) {
3988 if(s_p_dcam_mod->dcam_path2.status == DCAM_ST_START){
3990 path = &s_p_dcam_mod->dcam_path2;
3991 if (0 == path->valide) {
3992 printk("DCAM: path2 not valid \n");
3996 if (path->sof_cnt > 0) {
3997 printk("DCAM: path2 sof %d \n", path->sof_cnt);
4003 rtn = _dcam_path_set_next_frm(DCAM_PATH_IDX_2, false);
4004 if (path->is_update) {
4006 path->is_update = 0;
4007 DCAM_TRACE("DCAM: path2 updated \n");
4008 _dcam_auto_copy_ext(DCAM_PATH_IDX_2, true, true);
4011 DCAM_TRACE("DCAM: path2 updated \n");
4013 _dcam_auto_copy(DCAM_PATH_IDX_2);
4017 _dcam_path_updated_notice(DCAM_PATH_IDX_2);
4020 path->need_wait = 1;
4021 printk("DCAM:2 w \n");
4028 (*user_func)(NULL, data);
4034 LOCAL int32_t _dcam_err_pre_proc(void)
4036 DCAM_CHECK_ZERO(s_p_dcam_mod);
4038 DCAM_TRACE("DCAM: state in err_pre_proc 0x%x,",s_p_dcam_mod->state);
4039 if (s_p_dcam_mod->state & DCAM_STATE_QUICKQUIT)
4042 s_p_dcam_mod->err_happened = 1;
4043 printk("DCAM: err, 0x%x, ISP int 0x%x \n",
4044 REG_RD(DCAM_INT_STS),
4045 REG_RD(SPRD_ISP_BASE + 0x2080));
4048 dcam_glb_reg_mwr(DCAM_CONTROL, BIT_2, 0, DCAM_CONTROL_REG); /* Cap Disable */
4050 if (0 == atomic_read(&s_resize_flag) &&
4051 0 == atomic_read(&s_rotation_flag)) {
4052 dcam_reset(DCAM_RST_ALL, 1);
4057 LOCAL void _dcam_stopped(void)
4059 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
4061 DCAM_TRACE("DCAM: stopped, %d \n", s_p_dcam_mod->wait_stop);
4063 _dcam_path_done_notice(DCAM_PATH_IDX_0);
4064 _dcam_path_done_notice(DCAM_PATH_IDX_1);
4065 _dcam_path_done_notice(DCAM_PATH_IDX_2);
4066 _dcam_stopped_notice();
4070 LOCAL int _dcam_internal_init(void)
4074 s_p_dcam_mod = (struct dcam_module*)vzalloc(sizeof(struct dcam_module));
4076 DCAM_CHECK_ZERO(s_p_dcam_mod);
4078 sema_init(&s_p_dcam_mod->stop_sema, 0);
4079 sema_init(&s_p_dcam_mod->dcam_path0.tx_done_sema, 0);
4080 sema_init(&s_p_dcam_mod->dcam_path1.tx_done_sema, 0);
4081 sema_init(&s_p_dcam_mod->dcam_path2.tx_done_sema, 0);
4082 sema_init(&s_p_dcam_mod->dcam_path0.sof_sema, 0);
4083 sema_init(&s_p_dcam_mod->dcam_path1.sof_sema, 0);
4084 sema_init(&s_p_dcam_mod->dcam_path2.sof_sema, 0);
4085 sema_init(&s_p_dcam_mod->resize_done_sema, 0);
4086 sema_init(&s_p_dcam_mod->rotation_done_sema, 0);
4087 sema_init(&s_p_dcam_mod->scale_coeff_mem_sema, 1);
4089 memset((void*)s_dcam_sc_array, 0, sizeof(struct dcam_sc_array));
4092 LOCAL void _dcam_internal_deinit(void)
4096 spin_lock_irqsave(&dcam_mod_lock, flag);
4097 if (DCAM_ADDR_INVALID(s_p_dcam_mod)) {
4098 printk("DCAM: Invalid addr, 0x%x", (uint32_t)s_p_dcam_mod);
4100 vfree(s_p_dcam_mod);
4101 s_p_dcam_mod = NULL;
4103 spin_unlock_irqrestore(&dcam_mod_lock, flag);
4107 LOCAL void _dcam_wait_path_done(enum dcam_path_index path_index, uint32_t *p_flag)
4110 struct dcam_path_desc *p_path = NULL;
4113 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
4115 if (s_p_dcam_mod->err_happened) {
4118 if (DCAM_CAPTURE_MODE_SINGLE == s_p_dcam_mod->dcam_mode) {
4121 if (DCAM_PATH_IDX_0 == path_index) {
4122 p_path = &s_p_dcam_mod->dcam_path0;
4123 } else if (DCAM_PATH_IDX_1 == path_index) {
4124 p_path = &s_p_dcam_mod->dcam_path1;
4125 } else if (DCAM_PATH_IDX_2 == path_index) {
4126 p_path = &s_p_dcam_mod->dcam_path2;
4128 printk("DCAM: Wrong index 0x%x \n", path_index);
4131 DCAM_TRACE("DCAM: path done wait %d, %d \n", p_path->wait_for_done, p_path->tx_done_sema.count);
4133 spin_lock_irqsave(&dcam_lock, flag);
4137 p_path->wait_for_done = 1;
4138 spin_unlock_irqrestore(&dcam_lock, flag);
4139 ret = down_timeout(&p_path->tx_done_sema, DCAM_PATH_TIMEOUT);
4142 printk("DCAM: Failed to wait path 0x%x done \n", path_index);
4148 LOCAL void _dcam_path_done_notice(enum dcam_path_index path_index)
4150 struct dcam_path_desc *p_path = NULL;
4152 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
4154 if (DCAM_PATH_IDX_0 == path_index) {
4155 p_path = &s_p_dcam_mod->dcam_path0;
4156 } else if(DCAM_PATH_IDX_1 == path_index) {
4157 p_path = &s_p_dcam_mod->dcam_path1;
4158 } else if(DCAM_PATH_IDX_2 == path_index) {
4159 p_path = &s_p_dcam_mod->dcam_path2;
4161 printk("DCAM: Wrong index 0x%x \n", path_index);
4164 DCAM_TRACE("DCAM: path done notice %d, %d \n", p_path->wait_for_done, p_path->tx_done_sema.count);
4165 if (p_path->wait_for_done) {
4166 up(&p_path->tx_done_sema);
4167 p_path->wait_for_done = 0;
4173 LOCAL void _dcam_wait_update_done(enum dcam_path_index path_index, uint32_t *p_flag)
4176 struct dcam_path_desc *p_path = NULL;
4179 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
4181 if (s_p_dcam_mod->err_happened) {
4184 if (DCAM_CAPTURE_MODE_SINGLE == s_p_dcam_mod->dcam_mode) {
4187 if (DCAM_PATH_IDX_0 == path_index) {
4188 p_path = &s_p_dcam_mod->dcam_path0;
4189 } else if (DCAM_PATH_IDX_1 == path_index) {
4190 p_path = &s_p_dcam_mod->dcam_path1;
4191 } else if (DCAM_PATH_IDX_2 == path_index) {
4192 p_path = &s_p_dcam_mod->dcam_path2;
4194 printk("DCAM: Wrong index 0x%x \n", path_index);
4197 DCAM_TRACE("DCAM: path done wait %d, %d \n", p_path->wait_for_done, p_path->tx_done_sema.count);
4199 spin_lock_irqsave(&dcam_lock, flag);
4203 p_path->wait_for_sof = 1;
4204 spin_unlock_irqrestore(&dcam_lock, flag);
4205 ret = down_timeout(&p_path->sof_sema, DCAM_PATH_TIMEOUT);
4208 printk("DCAM: Failed to wait update path 0x%x done \n", path_index);
4214 LOCAL void _dcam_path_updated_notice(enum dcam_path_index path_index)
4216 struct dcam_path_desc *p_path = NULL;
4218 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
4220 if (DCAM_PATH_IDX_0 == path_index) {
4221 p_path = &s_p_dcam_mod->dcam_path0;
4222 } else if(DCAM_PATH_IDX_1 == path_index) {
4223 p_path = &s_p_dcam_mod->dcam_path1;
4224 } else if(DCAM_PATH_IDX_2 == path_index) {
4225 p_path = &s_p_dcam_mod->dcam_path2;
4227 printk("DCAM: Wrong index 0x%x \n", path_index);
4230 DCAM_TRACE("DCAM: path done notice %d, %d \n", p_path->wait_for_done, p_path->tx_done_sema.count);
4231 if (p_path->wait_for_sof) {
4232 up(&p_path->sof_sema);
4233 p_path->wait_for_sof = 0;
4240 LOCAL void _dcam_stopped_notice(void)
4242 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
4244 if (s_p_dcam_mod->wait_stop) {
4245 up(&s_p_dcam_mod->stop_sema);
4246 s_p_dcam_mod->wait_stop = 0;
4250 void mm_clk_register_trace(void)
4253 printk("REG_AON_APB_APB_EB0 = 0x%x \n",REG_RD(REG_AON_APB_APB_EB0));
4254 printk("REG_PMU_APB_PD_MM_TOP_CFG = 0x%x \n",REG_RD(REG_PMU_APB_PD_MM_TOP_CFG));
4255 printk("REG_PMU_APB_CP_SOFT_RST = 0x%x \n",REG_RD(REG_PMU_APB_CP_SOFT_RST));
4256 if(!(REG_RD(REG_AON_APB_APB_EB0)&BIT_MM_EB) ) return ;
4257 if(REG_RD(REG_PMU_APB_PD_MM_TOP_CFG)&BIT_PD_MM_TOP_FORCE_SHUTDOWN) return ;
4259 printk("mm_clk_reg, part 1 \n");
4260 for (i = 0 ; i <= 0x10; i += 4 ) {
4261 printk("MMAHB: %x val:%x \b\n",
4262 (SPRD_MMAHB_BASE + i),
4263 REG_RD(SPRD_MMAHB_BASE + i));
4266 printk("mm_clk_reg, part 2 \n");
4267 for (i = 0x20 ; i <= 0x38; i += 4 ) {
4268 printk("MMCKG: %x val:%x \b\n",
4269 (SPRD_MMCKG_BASE + i),
4270 REG_RD(SPRD_MMCKG_BASE + i));
4274 int32_t dcam_stop_sc_coeff(void)
4278 DCAM_CHECK_ZERO(s_dcam_sc_array);
4280 zoom_mode = s_dcam_sc_array->is_smooth_zoom;
4281 /*memset((void*)s_dcam_sc_array, 0, sizeof(struct dcam_sc_array));*/
4282 s_dcam_sc_array->is_smooth_zoom = zoom_mode;
4283 s_dcam_sc_array->valid_cnt = 0;
4284 memset(&s_dcam_sc_array->scaling_coeff_queue, 0, DCAM_SC_COEFF_BUF_COUNT*sizeof(struct dcam_sc_coeff *));
4289 LOCAL int32_t _dcam_get_valid_sc_coeff(struct dcam_sc_array *sc, struct dcam_sc_coeff **sc_coeff)
4291 if (DCAM_ADDR_INVALID(sc) || DCAM_ADDR_INVALID(sc_coeff)) {
4292 printk("DCAM: get valid sc, invalid param 0x%x, 0x%x \n",
4294 (uint32_t)sc_coeff);
4297 if (sc->valid_cnt == 0) {
4298 printk("DCAM: valid cnt 0 \n");
4302 *sc_coeff = sc->scaling_coeff_queue[0];
4303 DCAM_TRACE("DCAM: get valid sc, %d \n", sc->valid_cnt);
4308 LOCAL int32_t _dcam_push_sc_buf(struct dcam_sc_array *sc, uint32_t index)
4310 if (DCAM_ADDR_INVALID(sc)) {
4311 printk("DCAM: push sc, invalid param 0x%x \n",
4315 if (sc->valid_cnt >= DCAM_SC_COEFF_BUF_COUNT) {
4316 printk("DCAM: valid cnt %d \n", sc->valid_cnt);
4320 sc->scaling_coeff[index].flag = 1;
4321 sc->scaling_coeff_queue[sc->valid_cnt] = &sc->scaling_coeff[index];
4324 DCAM_TRACE("DCAM: push sc, %d \n", sc->valid_cnt);
4329 LOCAL int32_t _dcam_pop_sc_buf(struct dcam_sc_array *sc, struct dcam_sc_coeff **sc_coeff)
4333 if (DCAM_ADDR_INVALID(sc) || DCAM_ADDR_INVALID(sc_coeff)) {
4334 printk("DCAM: pop sc, invalid param 0x%x, 0x%x \n",
4336 (uint32_t)sc_coeff);
4339 if (sc->valid_cnt == 0) {
4340 printk("DCAM: valid cnt 0 \n");
4343 sc->scaling_coeff_queue[0]->flag = 0;
4344 *sc_coeff = sc->scaling_coeff_queue[0];
4346 for (i = 0; i < sc->valid_cnt; i++) {
4347 sc->scaling_coeff_queue[i] = sc->scaling_coeff_queue[i+1];
4349 DCAM_TRACE("DCAM: pop sc, %d \n", sc->valid_cnt);
4353 LOCAL int32_t _dcam_write_sc_coeff(enum dcam_path_index path_index)
4356 struct dcam_path_desc *path = NULL;
4358 uint32_t h_coeff_addr = DCAM_BASE;
4359 uint32_t v_coeff_addr = DCAM_BASE;
4360 uint32_t v_chroma_coeff_addr = DCAM_BASE;
4361 uint32_t *tmp_buf = NULL;
4362 uint32_t *h_coeff = NULL;
4363 uint32_t *v_coeff = NULL;
4364 uint32_t *v_chroma_coeff = NULL;
4365 uint32_t clk_switch_bit = 0;
4366 uint32_t clk_switch_shift_bit = 0;
4367 uint32_t clk_status_bit = 0;
4368 uint32_t ver_tap_reg = 0;
4369 uint32_t scale2yuv420 = 0;
4370 struct dcam_sc_coeff *sc_coeff;
4372 DCAM_CHECK_ZERO(s_p_dcam_mod);
4373 DCAM_CHECK_ZERO(s_dcam_sc_array);
4375 if (DCAM_PATH_IDX_1 != path_index && DCAM_PATH_IDX_2 != path_index)
4376 return -DCAM_RTN_PARA_ERR;
4378 ret = _dcam_get_valid_sc_coeff(s_dcam_sc_array, &sc_coeff);
4380 return -DCAM_RTN_PATH_NO_MEM;
4382 tmp_buf = sc_coeff->buf;
4383 if (NULL == tmp_buf) {
4384 return -DCAM_RTN_PATH_NO_MEM;
4388 v_coeff = tmp_buf + (DCAM_SC_COEFF_COEF_SIZE/4);
4389 v_chroma_coeff = v_coeff + (DCAM_SC_COEFF_COEF_SIZE/4);
4391 if (DCAM_PATH_IDX_1 == path_index) {
4392 path = &sc_coeff->dcam_path1;
4393 h_coeff_addr += DCAM_SC1_H_TAB_OFFSET;
4394 v_coeff_addr += DCAM_SC1_V_TAB_OFFSET;
4395 v_chroma_coeff_addr += DCAM_SC1_V_CHROMA_TAB_OFFSET;
4396 clk_switch_bit = BIT_3;
4397 clk_switch_shift_bit = 3;
4398 clk_status_bit = BIT_5;
4399 ver_tap_reg = DCAM_PATH1_CFG;
4400 } else if (DCAM_PATH_IDX_2 == path_index) {
4401 path = &s_p_dcam_mod->dcam_path2;
4402 h_coeff_addr += DCAM_SC2_H_TAB_OFFSET;
4403 v_coeff_addr += DCAM_SC2_V_TAB_OFFSET;
4404 v_chroma_coeff_addr += DCAM_SC2_V_CHROMA_TAB_OFFSET;
4405 clk_switch_bit = BIT_4;
4406 clk_switch_shift_bit = 4;
4407 clk_status_bit = BIT_6;
4408 ver_tap_reg = DCAM_PATH2_CFG;
4411 if (DCAM_YUV420 == path->output_format) {
4415 DCAM_TRACE("DCAM: _dcam_write_sc_coeff {%d %d %d %d}, 420=%d \n",
4416 path->sc_input_size.w,
4417 path->sc_input_size.h,
4418 path->output_size.w,
4419 path->output_size.h, scale2yuv420);
4421 for (i = 0; i < DCAM_SC_COEFF_H_NUM; i++) {
4422 REG_WR(h_coeff_addr, *h_coeff);
4427 for (i = 0; i < DCAM_SC_COEFF_V_NUM; i++) {
4428 REG_WR(v_coeff_addr, *v_coeff);
4433 for (i = 0; i < DCAM_SC_COEFF_V_CHROMA_NUM; i++) {
4434 REG_WR(v_chroma_coeff_addr, *v_chroma_coeff);
4435 v_chroma_coeff_addr += 4;
4439 DCAM_TRACE("DCAM: _dcam_write_sc_coeff E \n");
4444 LOCAL int32_t _dcam_calc_sc_coeff(enum dcam_path_index path_index)
4447 struct dcam_path_desc *path = NULL;
4448 uint32_t h_coeff_addr = DCAM_BASE;
4449 uint32_t v_coeff_addr = DCAM_BASE;
4450 uint32_t v_chroma_coeff_addr = DCAM_BASE;
4451 uint32_t *tmp_buf = NULL;
4452 uint32_t *h_coeff = NULL;
4453 uint32_t *v_coeff = NULL;
4454 uint32_t *v_chroma_coeff = NULL;
4455 uint32_t clk_switch_bit = 0;
4456 uint32_t clk_switch_shift_bit = 0;
4457 uint32_t clk_status_bit = 0;
4458 uint32_t ver_tap_reg = 0;
4459 uint32_t scale2yuv420 = 0;
4463 struct dcam_sc_coeff *sc_coeff;
4465 DCAM_CHECK_ZERO(s_p_dcam_mod);
4466 DCAM_CHECK_ZERO(s_dcam_sc_array);
4468 if (DCAM_PATH_IDX_1 != path_index && DCAM_PATH_IDX_2 != path_index)
4469 return -DCAM_RTN_PARA_ERR;
4471 if (DCAM_PATH_IDX_1 == path_index) {
4472 path = &s_p_dcam_mod->dcam_path1;
4473 h_coeff_addr += DCAM_SC1_H_TAB_OFFSET;
4474 v_coeff_addr += DCAM_SC1_V_TAB_OFFSET;
4475 v_chroma_coeff_addr += DCAM_SC1_V_CHROMA_TAB_OFFSET;
4476 clk_switch_bit = BIT_3;
4477 clk_switch_shift_bit = 3;
4478 clk_status_bit = BIT_5;
4479 ver_tap_reg = DCAM_PATH1_CFG;
4480 } else if (DCAM_PATH_IDX_2 == path_index) {
4481 path = &s_p_dcam_mod->dcam_path2;
4482 h_coeff_addr += DCAM_SC2_H_TAB_OFFSET;
4483 v_coeff_addr += DCAM_SC2_V_TAB_OFFSET;
4484 v_chroma_coeff_addr += DCAM_SC2_V_CHROMA_TAB_OFFSET;
4485 clk_switch_bit = BIT_4;
4486 clk_switch_shift_bit = 4;
4487 clk_status_bit = BIT_6;
4488 ver_tap_reg = DCAM_PATH2_CFG;
4491 if (DCAM_YUV420 == path->output_format) {
4495 DCAM_TRACE("DCAM: _dcam_calc_sc_coeff {%d %d %d %d}, 420=%d \n",
4496 path->sc_input_size.w,
4497 path->sc_input_size.h,
4498 path->output_size.w,
4499 path->output_size.h, scale2yuv420);
4501 down(&s_p_dcam_mod->scale_coeff_mem_sema);
4503 spin_lock_irqsave(&dcam_lock,flag);
4504 tmp_buf = dcam_get_scale_coeff_addr(&index);
4505 if (NULL == tmp_buf) {
4506 _dcam_pop_sc_buf(s_dcam_sc_array, &sc_coeff);
4507 tmp_buf = dcam_get_scale_coeff_addr(&index);
4509 spin_unlock_irqrestore(&dcam_lock,flag);
4511 if (NULL == tmp_buf) {
4512 return -DCAM_RTN_PATH_NO_MEM;
4516 v_coeff = tmp_buf + (DCAM_SC_COEFF_COEF_SIZE/4);
4517 v_chroma_coeff = v_coeff + (DCAM_SC_COEFF_COEF_SIZE/4);
4519 if (!(Dcam_GenScaleCoeff((int16_t)path->sc_input_size.w,
4520 (int16_t)path->sc_input_size.h,
4521 (int16_t)path->output_size.w,
4522 (int16_t)path->output_size.h,
4529 tmp_buf + (DCAM_SC_COEFF_COEF_SIZE*3/4),
4530 DCAM_SC_COEFF_TMP_SIZE))) {
4531 printk("DCAM: _dcam_calc_sc_coeff Dcam_GenScaleCoeff error! \n");
4532 up(&s_p_dcam_mod->scale_coeff_mem_sema);
4533 return -DCAM_RTN_PATH_GEN_COEFF_ERR;
4535 path->scale_tap.y_tap = y_tap;
4536 path->scale_tap.uv_tap = uv_tap;
4537 path->valid_param.scale_tap = 1;
4538 memcpy(&s_dcam_sc_array->scaling_coeff[index].dcam_path1, path, sizeof(struct dcam_path_desc));
4539 spin_lock_irqsave(&dcam_lock,flag);
4540 _dcam_push_sc_buf(s_dcam_sc_array, index);
4541 spin_unlock_irqrestore(&dcam_lock,flag);
4543 up(&s_p_dcam_mod->scale_coeff_mem_sema);
4544 DCAM_TRACE("DCAM: _dcam_calc_sc_coeff E \n");
4546 return DCAM_RTN_SUCCESS;