static int mipi_vdin_canvas_init(vdin_ops_privdata_t* data,unsigned int mem_start, unsigned int mem_size) { int i, canvas_start_index ; unsigned int canvas_width = (data->input.active_pixel*data->input.depth)>>3; unsigned int canvas_height = data->input.active_line; unsigned decbuf_start = mem_start; unsigned decbuf_size = canvas_width*canvas_height + 0x1000; #if 0 if( mem_size >= CANVAS_SIZE_6_500M){ canvas_width = 2592 << 1; canvas_height = 1952; decbuf_size = canvas_width*canvas_height + 0x1000; mipi_dbg("mipi_vdin_canvas_init--5M canvas config\n"); }else if( mem_size >= CANVAS_SIZE_6_300M ){ canvas_width = 2048 << 1; canvas_height = 1536; decbuf_size = canvas_width*canvas_height + 0x1000; mipi_dbg("mipi_vdin_canvas_init--3M canvas config\n"); } #endif i = (unsigned)(mem_size / decbuf_size); data->canvas_total_count = (VDIN_VF_POOL_MAX_SIZE > i)? i : VDIN_VF_POOL_MAX_SIZE; data->decbuf_size = decbuf_size; if((data->param.port == TVIN_PORT_MIPI_NV12)||(data->param.port == TVIN_PORT_MIPI_NV21)){ if(data->vdin_num) canvas_start_index = tvin_canvas_tab[1][0]; else canvas_start_index = tvin_canvas_tab[0][0]; for ( i = 0; i < data->canvas_total_count; i++){ canvas_config(canvas_start_index + i, decbuf_start + i * data->decbuf_size, data->input.active_pixel, canvas_height, CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR); } for ( i = 0; i < data->canvas_total_count; i++){ canvas_config(VDIN_START_CANVAS_CHROMA_OFFSET+canvas_start_index + i, decbuf_start + (i * data->decbuf_size)+(data->input.active_line*data->input.active_pixel), data->input.active_pixel, canvas_height/2, CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR); } }else{ if(data->vdin_num) canvas_start_index = tvin_canvas_tab[1][0]; else canvas_start_index = tvin_canvas_tab[0][0]; for ( i = 0; i < data->canvas_total_count; i++){ canvas_config(canvas_start_index + i, decbuf_start + i * data->decbuf_size, canvas_width, canvas_height, CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR); } } set_tvin_canvas_info(canvas_start_index ,data->canvas_total_count); return 0; }
static int mipi_vdin_check_callback(struct notifier_block *block, unsigned long cmd , void *para) { int ret = 0; vdin_dev_t *p = NULL; vdin_ops_privdata_t * data = NULL; switch(cmd){ case TVIN_EVENT_INFO_CHECK: if(para != NULL){ p = (vdin_dev_t*)para; if ((p->para.port != TVIN_PORT_MIPI)&& (p->para.port != TVIN_PORT_MIPI_NV12)&& (p->para.port != TVIN_PORT_MIPI_NV21)){ mipi_dbg("[mipi_vdin]: ignore TVIN_EVENT_INFO_CHECK (port=%d)\n", p->para.port); return ret; } data = (vdin_ops_privdata_t*)p->priv_data; csi2_vdin_check(data); if ((data->param.fmt_info.fmt != p->para.fmt_info.fmt) || (data->param.status!= p->para.status)){ vdin_info_update(p, &data->param); } ret = NOTIFY_STOP_MASK; } break; default: break; } return ret; }
static int mipi_vdin_notifier_callback(struct notifier_block *block, unsigned long cmd , void *para) { int ret = 0; vdin_dev_t *p = NULL; vdin_ops_privdata_t * data = NULL; switch(cmd){ case TVIN_EVENT_DEC_START: if(para != NULL){ p = (vdin_dev_t*)para; if ((p->para.port != TVIN_PORT_MIPI)&& (p->para.port != TVIN_PORT_MIPI_NV12)&& (p->para.port != TVIN_PORT_MIPI_NV21)){ mipi_dbg("[mipi_vdin]: ignore TVIN_EVENT_DEC_START (port=%d)\n", p->para.port); return ret; } mipi_dbg("mipi_vdin_notifier_callback, para = %x ,mem_start = %x, port = %d, format = %d, ca-_flag = %d.\n" , (unsigned int)para, p->mem_start, p->para.port, p->para.fmt_info.fmt, p->para.flag); data = (vdin_ops_privdata_t*)p->priv_data; start_mipi_vdin(data,p->mem_start,p->mem_size, p->para.fmt_info,p->para.port); data->param.status = TVIN_SIG_STATUS_STABLE; vdin_info_update(p, &data->param); tvin_dec_register(p, &mipi_vdin_op); tvin_check_notifier_register(&mipi_check_cb); ret = NOTIFY_STOP_MASK; } break; case TVIN_EVENT_DEC_STOP: if(para != NULL){ p = (vdin_dev_t*)para; if ((p->para.port != TVIN_PORT_MIPI)&& (p->para.port != TVIN_PORT_MIPI_NV12)&& (p->para.port != TVIN_PORT_MIPI_NV21)){ mipi_dbg("[mipi_vdin]: ignore TVIN_EVENT_DEC_STOP (port=%d)\n", p->para.port); return ret; } data = (vdin_ops_privdata_t*)p->priv_data; stop_mipi_vdin(data); tvin_dec_unregister(p); tvin_check_notifier_unregister(&mipi_check_cb); ret = NOTIFY_STOP_MASK; } break; default: break; } return ret; }
static void stop_mipi_vdin(vdin_ops_privdata_t * data) { if(data->run_flag == true){ mipi_dbg("stop_mipi_vdin.\n"); am_mipi_csi2_uninit(); data->param.fmt_info.fmt= TVIN_SIG_FMT_NULL; data->run_flag = false; }else{ mipi_error("stop_mipi_vdin is not started yet. \n"); } return; }
static void start_mipi_vdin(vdin_ops_privdata_t* data,unsigned int mem_start, unsigned int mem_size, fmt_info_t fmt_info,enum tvin_port_e port) { if(data->run_flag == true){ mipi_dbg("mipi_vdin is processing, don't do starting operation \n"); return; } mipi_dbg("start_mipi_vdin. \n"); data->param.port = port; mipi_vdin_canvas_init(data,mem_start, mem_size); init_mipi_vdin_parameter(data,fmt_info); data->wr_canvas_index = 0xff; data->reset_flag = 0; data->done_flag = true; data->hw_info.frame = NULL; data->mipi_vdin_skip = MIPI_SKIP_FRAME_NUM; am_mipi_csi2_init(&data->hw_info); data->watchdog_cnt = 0; data->run_flag = true; return; }
static void init_mipi_vdin_parameter(vdin_ops_privdata_t* data,fmt_info_t fmt_info) { data->param.fmt_info.fmt = fmt_info.fmt; data->param.fmt_info.frame_rate = fmt_info.frame_rate; switch(fmt_info.fmt){ case TVIN_SIG_FMT_MAX+1: case 0xFFFF: //default camera data->param.fmt_info.h_active = fmt_info.h_active; data->param.fmt_info.v_active = fmt_info.v_active; data->param.fmt_info.hsync_phase = fmt_info.hsync_phase; data->param.fmt_info.vsync_phase = fmt_info.vsync_phase; mipi_dbg("%dx%d input mode is selected for camera, \n",fmt_info.h_active,fmt_info.v_active); break; case TVIN_SIG_FMT_NULL: default: break; } return; }
/*! * This function is called to disable the mipi csi2 interface. * * @param info mipi csi2 hander * @return Returns setted value */ bool mipi_csi2_disable(struct mipi_csi2_info *info) { bool status; _mipi_csi2_lock(info); if (info->mipi_en) { info->mipi_en = false; clk_disable_unprepare(info->dphy_clk); clk_disable_unprepare(info->cfg_clk); } else mipi_dbg("mipi csi2 already disabled!\n"); status = info->mipi_en; _mipi_csi2_unlock(info); return status; }