Merge remote-tracking branch 'origin/develop-3.0' into develop-3.0-jb

This commit is contained in:
黄涛 2012-07-14 14:25:50 +08:00
commit aa0e2f856a
4 changed files with 91 additions and 60 deletions

View File

@ -21,10 +21,4 @@ config MACH_RK30_PHONE_A22
endchoice
menu "support for RK power manage "
config CLK_SWITCH_TO_32K
bool "Support clock switch to 32.768k"
endmenu
endif

View File

@ -105,6 +105,15 @@ config RK_CLOCK_PROC
bool "/proc/clocks support"
depends on PROC_FS
if !ARCH_RK29
menu "Support for RK power manage"
config CLK_SWITCH_TO_32K
bool "Support clock switch to 32.768k"
endmenu
endif
config WIFI_CONTROL_FUNC
bool "Enable WiFi control function abstraction"
help

View File

@ -209,7 +209,7 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
*v0.x.b: specify the version is NOT sure stable.
*v0.x.c: 1. add cif reset when resolution changed to avoid of collecting data erro
2. irq process is splitted to two step.
*v0.x.e: fix bugs of early suspend when display_pd is closed.
*/
#define RK_CAM_VERSION_CODE KERNEL_VERSION(0, 2, 0xc)
@ -370,6 +370,7 @@ static DEFINE_MUTEX(camera_lock);
static const char *rk_cam_driver_description = "RK_Camera";
static int rk_camera_s_stream(struct soc_camera_device *icd, int enable);
static void rk_camera_capture_process(struct work_struct *work);
/*
@ -413,11 +414,17 @@ static int rk_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
}
if (pcdev->camera_work == NULL) {
int wk_index = 0;
struct rk_camera_work *wk;
pcdev->camera_work = kmalloc(sizeof(struct rk_camera_work)*(*count), GFP_KERNEL);
if (pcdev->camera_work == NULL) {
RKCAMERA_TR("\n %s kmalloc fail\n", __FUNCTION__);
BUG();
}
for(;wk_index < *count;wk_index++){
wk = pcdev->camera_work+wk_index;
INIT_WORK(&wk->work, rk_camera_capture_process);
}
pcdev->camera_work_count = *count;
}
}
@ -603,10 +610,10 @@ static void rk_camera_capture_process(struct work_struct *work)
scale_times = 1;
}
memset(&ipp_req, 0, sizeof(struct rk29_ipp_req));
down(&pcdev->zoominfo.sem);
ipp_req.timeout = 100;
down(&pcdev->zoominfo.sem);
ipp_req.timeout = 3000;
ipp_req.flag = IPP_ROT_0;
// if(pcdev->icd->user_width != pcdev->zoominfo.vir_width)
ipp_req.store_clip_mode =1;
@ -625,7 +632,7 @@ static void rk_camera_capture_process(struct work_struct *work)
dst_y_size = pcdev->icd->user_width*pcdev->icd->user_height;
for (h=0; h<scale_times; h++) {
for (w=0; w<scale_times; w++) {
int ipp_times = 3;
src_y_offset = (pcdev->zoominfo.a.c.top + h*pcdev->zoominfo.a.c.height/scale_times)* pcdev->host_width
+ pcdev->zoominfo.a.c.left + w*pcdev->zoominfo.a.c.width/scale_times;
src_uv_offset = (pcdev->zoominfo.a.c.top + h*pcdev->zoominfo.a.c.height/scale_times)* pcdev->host_width/2
@ -642,22 +649,31 @@ static void rk_camera_capture_process(struct work_struct *work)
// printk("ipp_req.dst0.YrgbMst = 0x%x , ipp_req.dst0.CbrMst = 0x%x\n",ipp_req.dst0.YrgbMst,ipp_req.dst0.CbrMst);
// printk("%dx%d@(%d,%d)->%dx%d\n",pcdev->zoominfo.a.c.width,pcdev->zoominfo.a.c.height,pcdev->zoominfo.a.c.left,pcdev->zoominfo.a.c.top,pcdev->icd->user_width,pcdev->icd->user_height);
// printk("ipp_req.src_vir_w:0x%x ipp_req.dst_vir_w :0x%x\n",ipp_req.src_vir_w ,ipp_req.dst_vir_w);
if (ipp_blit_sync(&ipp_req)) {
while(ipp_times-- > 0)
{
if (ipp_blit_sync(&ipp_req)){
RKCAMERA_TR("ipp do erro,do again,ipp_times = %d!\n",ipp_times);
}
else{
break;
}
}
if (ipp_times <= 0)
{
spin_lock_irqsave(&pcdev->lock, flags);
vb->state = VIDEOBUF_ERROR;
vb->state = VIDEOBUF_NEEDS_INIT;
spin_unlock_irqrestore(&pcdev->lock, flags);
RKCAMERA_TR("Capture image(vb->i:0x%x) which IPP operated is error:\n",vb->i);
RKCAMERA_TR("widx:%d hidx:%d ",w,h);
RKCAMERA_TR("%dx%d@(%d,%d)->%dx%d\n",pcdev->zoominfo.a.c.width,pcdev->zoominfo.a.c.height,pcdev->zoominfo.a.c.left,pcdev->zoominfo.a.c.top,pcdev->icd->user_width,pcdev->icd->user_height);
RKCAMERA_TR("ipp_req.src0.YrgbMst:0x%x ipp_req.src0.CbrMst:0x%x \n", ipp_req.src0.YrgbMst,ipp_req.src0.CbrMst);
RKCAMERA_TR("ipp_req.src0.w:0x%x ipp_req.src0.h:0x%x \n",ipp_req.src0.w,ipp_req.src0.h);
RKCAMERA_TR("ipp_req.src0.fmt:0x%x\n",ipp_req.src0.fmt);
RKCAMERA_TR("ipp_req.dst0.YrgbMst:0x%x ipp_req.dst0.CbrMst:0x%x \n",ipp_req.dst0.YrgbMst,ipp_req.dst0.CbrMst);
RKCAMERA_TR("ipp_req.dst0.w:0x%x ipp_req.dst0.h:0x%x \n",ipp_req.dst0.w ,ipp_req.dst0.h);
RKCAMERA_TR("ipp_req.dst0.fmt:0x%x\n",ipp_req.dst0.fmt);
RKCAMERA_TR("ipp_req.src_vir_w:0x%x ipp_req.dst_vir_w :0x%x\n",ipp_req.src_vir_w ,ipp_req.dst_vir_w);
RKCAMERA_TR("ipp_req.timeout:0x%x ipp_req.flag :0x%x\n",ipp_req.timeout,ipp_req.flag);
RKCAMERA_TR("Capture image(vb->i:0x%x) which IPP operated is error:\n",vb->i);
RKCAMERA_TR("widx:%d hidx:%d ",w,h);
RKCAMERA_TR("%dx%d@(%d,%d)->%dx%d\n",pcdev->zoominfo.a.c.width,pcdev->zoominfo.a.c.height,pcdev->zoominfo.a.c.left,pcdev->zoominfo.a.c.top,pcdev->icd->user_width,pcdev->icd->user_height);
RKCAMERA_TR("ipp_req.src0.YrgbMst:0x%x ipp_req.src0.CbrMst:0x%x \n", ipp_req.src0.YrgbMst,ipp_req.src0.CbrMst);
RKCAMERA_TR("ipp_req.src0.w:0x%x ipp_req.src0.h:0x%x \n",ipp_req.src0.w,ipp_req.src0.h);
RKCAMERA_TR("ipp_req.src0.fmt:0x%x\n",ipp_req.src0.fmt);
RKCAMERA_TR("ipp_req.dst0.YrgbMst:0x%x ipp_req.dst0.CbrMst:0x%x \n",ipp_req.dst0.YrgbMst,ipp_req.dst0.CbrMst);
RKCAMERA_TR("ipp_req.dst0.w:0x%x ipp_req.dst0.h:0x%x \n",ipp_req.dst0.w ,ipp_req.dst0.h);
RKCAMERA_TR("ipp_req.dst0.fmt:0x%x\n",ipp_req.dst0.fmt);
RKCAMERA_TR("ipp_req.src_vir_w:0x%x ipp_req.dst_vir_w :0x%x\n",ipp_req.src_vir_w ,ipp_req.dst_vir_w);
RKCAMERA_TR("ipp_req.timeout:0x%x ipp_req.flag :0x%x\n",ipp_req.timeout,ipp_req.flag);
goto do_ipp_err;
}
@ -666,7 +682,6 @@ static void rk_camera_capture_process(struct work_struct *work)
if (pcdev->icd_cb.sensor_cb)
(pcdev->icd_cb.sensor_cb)(vb);
do_ipp_err:
up(&pcdev->zoominfo.sem);
wake_up(&(camera_work->vb->done));
@ -738,7 +753,10 @@ static irqreturn_t rk_camera_irq(int irq, void *data)
else if(pcdev->active){
printk("vb state is wrong ,del it \n");
list_del_init(&(pcdev->active->queue));
pcdev->active->state = VIDEOBUF_NEEDS_INIT;
wake_up(&pcdev->active->done);
pcdev->active = NULL;
}
}
if (pcdev->active == NULL) {
@ -752,7 +770,7 @@ static irqreturn_t rk_camera_irq(int irq, void *data)
}
if (CAM_WORKQUEUE_IS_EN()) {
wk = pcdev->camera_work + vb->i;
INIT_WORK(&(wk->work), rk_camera_capture_process);
//INIT_WORK(&(wk->work), rk_camera_capture_process);
wk->vb = vb;
wk->pcdev = pcdev;
queue_work(pcdev->camera_wq, &(wk->work));
@ -901,6 +919,7 @@ static int rk_camera_activate(struct rk_camera_dev *pcdev, struct soc_camera_dev
static void rk_camera_deactivate(struct rk_camera_dev *pcdev)
{
//pcdev->active = NULL;
// printk("rk_camera_deactivate enter\n");
clk_disable(pcdev->aclk_cif);
clk_disable(pcdev->hclk_cif);
@ -1003,6 +1022,7 @@ static void rk_camera_remove_device(struct soc_camera_device *icd)
if (read_cif_reg(pcdev->base,CIF_CIF_CTRL) & ENABLE_CAPTURE) {
rk_camera_s_stream(icd,0);
}
//soft reset the registers
#if 0 //has somthing wrong when suspend and resume now
if(IS_CIF0()){
@ -1014,7 +1034,6 @@ static void rk_camera_remove_device(struct soc_camera_device *icd)
}
#endif
v4l2_subdev_call(sd, core, ioctl, RK29_CAM_SUBDEV_DEACTIVATE,NULL);
rk_camera_deactivate(pcdev);
//if stream off is not been executed,timer is running.
if(pcdev->fps_timer.istarted){
hrtimer_cancel(&pcdev->fps_timer.timer);
@ -1028,7 +1047,7 @@ static void rk_camera_remove_device(struct soc_camera_device *icd)
pcdev->camera_work = NULL;
pcdev->camera_work_count = 0;
}
rk_camera_deactivate(pcdev);
pcdev->active = NULL;
pcdev->icd = NULL;
pcdev->icd_cb.sensor_cb = NULL;
@ -1884,26 +1903,27 @@ static void rk_camera_reinit_work(struct work_struct *work)
tmp_soc_cam_link = to_soc_camera_link(pcdev->icd);
//dump regs
{
RKCAMERA_DG("CIF_CIF_CTRL = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_CTRL));
RKCAMERA_DG("CIF_CIF_INTEN = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_INTEN));
RKCAMERA_DG("CIF_CIF_INTSTAT = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_INTSTAT));
RKCAMERA_DG("CIF_CIF_FOR = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_FOR));
RKCAMERA_DG("CIF_CIF_CROP = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_CROP));
RKCAMERA_DG("CIF_CIF_SET_SIZE = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_SET_SIZE));
RKCAMERA_DG("CIF_CIF_SCL_CTRL = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL));
RKCAMERA_DG("CRU_PCLK_REG30 = 0X%x\n",read_cru_reg(CRU_PCLK_REG30));
RKCAMERA_DG("CIF_CIF_LAST_LINE = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_LAST_LINE));
RKCAMERA_TR("CIF_CIF_CTRL = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_CTRL));
RKCAMERA_TR("CIF_CIF_INTEN = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_INTEN));
RKCAMERA_TR("CIF_CIF_INTSTAT = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_INTSTAT));
RKCAMERA_TR("CIF_CIF_FOR = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_FOR));
RKCAMERA_TR("CIF_CIF_CROP = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_CROP));
RKCAMERA_TR("CIF_CIF_SET_SIZE = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_SET_SIZE));
RKCAMERA_TR("CIF_CIF_SCL_CTRL = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL));
RKCAMERA_TR("CRU_PCLK_REG30 = 0X%x\n",read_cru_reg(CRU_PCLK_REG30));
RKCAMERA_TR("CIF_CIF_LAST_LINE = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_LAST_LINE));
RKCAMERA_DG("CIF_CIF_LAST_PIX = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_LAST_PIX));
RKCAMERA_DG("CIF_CIF_VIR_LINE_WIDTH = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH));
RKCAMERA_DG("CIF_CIF_LINE_NUM_ADDR = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_LINE_NUM_ADDR));
RKCAMERA_DG("CIF_CIF_FRM0_ADDR_Y = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_Y));
RKCAMERA_DG("CIF_CIF_FRM0_ADDR_UV = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_UV));
RKCAMERA_DG("CIF_CIF_FRAME_STATUS = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS));
RKCAMERA_TR("CIF_CIF_LAST_PIX = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_LAST_PIX));
RKCAMERA_TR("CIF_CIF_VIR_LINE_WIDTH = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH));
RKCAMERA_TR("CIF_CIF_LINE_NUM_ADDR = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_LINE_NUM_ADDR));
RKCAMERA_TR("CIF_CIF_FRM0_ADDR_Y = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_Y));
RKCAMERA_TR("CIF_CIF_FRM0_ADDR_UV = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_UV));
RKCAMERA_TR("CIF_CIF_FRAME_STATUS = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS));
}
write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL)&(~ENABLE_CAPTURE)));
if(1/*pcdev->reinit_times++ > 0*/)
if(1/*pcdev->reinit_times++ >= 2*/)
{
pcdev->stop_cif = true;
write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL)&(~ENABLE_CAPTURE)));
RKCAMERA_DG("the reinit times = %d\n",pcdev->reinit_times);
#if 0
while (!list_empty(&pcdev->capture)) {
@ -1917,11 +1937,12 @@ static void rk_camera_reinit_work(struct work_struct *work)
}
}
#else
spin_lock_irqsave(pcdev->video_vq->irqlock, flags);
spin_lock_irqsave(pcdev->video_vq->irqlock, flags);
for (index = 0; index < VIDEO_MAX_FRAME; index++) {
if (NULL == pcdev->video_vq->bufs[index])
continue;
if (pcdev->video_vq->bufs[index]->state == VIDEOBUF_QUEUED) {
if (pcdev->video_vq->bufs[index]->state == VIDEOBUF_QUEUED)
{
list_del_init(&pcdev->video_vq->bufs[index]->queue);
pcdev->video_vq->bufs[index]->state = VIDEOBUF_NEEDS_INIT;
wake_up_all(&pcdev->video_vq->bufs[index]->done);
@ -1932,7 +1953,7 @@ static void rk_camera_reinit_work(struct work_struct *work)
#endif
RKCAMERA_TR("the %d reinit times ,wake up video buffers!\n ",pcdev->reinit_times);
}else{ //the first time,just reinit sensor ,don't wake up vb
}/*else{ //the first time,just reinit sensor ,don't wake up vb
// rk_cif_poweroff(pcdev);
RKCAMERA_DG("first time to reinit\n");
// return;
@ -1981,7 +2002,7 @@ static void rk_camera_reinit_work(struct work_struct *work)
write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL)|ENABLE_CAPTURE));
RKCAMERA_TR("first time Camera host haven't recevie data from sensor,Reinit sensor now! ret:0x%x\n",ret);
}
}*/
}
static enum hrtimer_restart rk_camera_fps_func(struct hrtimer *timer)
{
@ -1998,6 +2019,7 @@ static enum hrtimer_restart rk_camera_fps_func(struct hrtimer *timer)
RKCAMERA_TR("Camera host haven't recevie data from sensor,Reinit sensor delay,last fps = %d,pcdev->fps = %d!\n",pcdev->last_fps,pcdev->fps);
pcdev->camera_reinit_work.pcdev = pcdev;
//INIT_WORK(&(pcdev->camera_reinit_work.work), rk_camera_reinit_work);
pcdev->reinit_times++;
queue_work(pcdev->camera_wq,&(pcdev->camera_reinit_work.work));
} else if(!pcdev->timer_get_fps) {
pcdev->timer_get_fps = true;
@ -2062,7 +2084,10 @@ static enum hrtimer_restart rk_camera_fps_func(struct hrtimer *timer)
pcdev->fps_timer.timer.node.expires= ktime_add_us(pcdev->fps_timer.timer.node.expires, ktime_to_us(ktime_set(3, 0)));
pcdev->fps_timer.timer._softexpires= ktime_add_us(pcdev->fps_timer.timer._softexpires, ktime_to_us(ktime_set(3, 0)));
//return HRTIMER_NORESTART;
return HRTIMER_RESTART;
if(pcdev->reinit_times >=2)
return HRTIMER_NORESTART;
else
return HRTIMER_RESTART;
}
static int rk_camera_s_stream(struct soc_camera_device *icd, int enable)
{
@ -2090,19 +2115,21 @@ static int rk_camera_s_stream(struct soc_camera_device *icd, int enable)
hrtimer_start(&(pcdev->fps_timer.timer),ktime_set(3, 0),HRTIMER_MODE_REL);
pcdev->fps_timer.istarted = true;
} else {
cif_ctrl_val &= ~ENABLE_CAPTURE;
//cancel timer before stop cif
ret = hrtimer_cancel(&pcdev->fps_timer.timer);
pcdev->fps_timer.istarted = false;
flush_work(&(pcdev->camera_reinit_work.work));
cif_ctrl_val &= ~ENABLE_CAPTURE;
spin_lock_irqsave(&pcdev->lock, flags);
write_cif_reg(pcdev->base,CIF_CIF_CTRL, cif_ctrl_val);
pcdev->stop_cif = true;
spin_unlock_irqrestore(&pcdev->lock, flags);
// printk("flush work end!!!!!!!!!\n");
// mdelay(3*1000);
// write_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS, 0x00000003);//frame1 has been ready to receive data,frame 2 is not used
// write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0xFFFFFFFF); /* clear vip interrupte single */
// write_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS,0); /* clear vip interrupte single */
ret = hrtimer_cancel(&pcdev->fps_timer.timer);
pcdev->fps_timer.istarted = false;
flush_work(&(pcdev->camera_reinit_work.work));
flush_workqueue((pcdev->camera_wq));
RKCAMERA_DG("STREAM_OFF cancel timer and flush work:0x%x \n", ret);
}
@ -2447,12 +2474,12 @@ static int rk_camera_probe(struct platform_device *pdev)
if (pcdev->pdata && IS_CIF0()) {
pcdev->vipmem_phybase = pcdev->pdata->meminfo.start;
pcdev->vipmem_size = pcdev->pdata->meminfo.size;
RKCAMERA_DG("\n%s Memory(start:0x%x size:0x%x) for IPP obtain \n",__FUNCTION__, pcdev->pdata->meminfo.start,pcdev->pdata->meminfo.size);
RKCAMERA_TR("\n%s Memory(start:0x%x size:0x%x) for IPP obtain \n",__FUNCTION__, pcdev->pdata->meminfo.start,pcdev->pdata->meminfo.size);
}
else if (pcdev->pdata){
pcdev->vipmem_phybase = pcdev->pdata->meminfo_cif1.start;
pcdev->vipmem_size = pcdev->pdata->meminfo_cif1.size;
RKCAMERA_DG("\n%s Memory(start:0x%x size:0x%x) for IPP obtain \n",__FUNCTION__, pcdev->pdata->meminfo.start,pcdev->pdata->meminfo.size);
RKCAMERA_TR("\n%s Memory(start:0x%x size:0x%x) for IPP obtain \n",__FUNCTION__, pcdev->pdata->meminfo.start,pcdev->pdata->meminfo.size);
}
else{
RKCAMERA_TR("\n%s Memory for IPP have not obtain! IPP Function is fail\n",__FUNCTION__);

View File

@ -217,7 +217,7 @@ static int rk_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
#if defined(CONFIG_HDMI_RK30)
#if defined(CONFIG_DUAL_DISP_IN_KERNEL)
if(hdmi_get_hotplug())
if(hdmi_get_hotplug() == HDMI_HPD_ACTIVED)
{
if(inf->num_fb >= 2)
{
@ -370,7 +370,7 @@ static int rk_fb_set_par(struct fb_info *info)
#if defined(CONFIG_HDMI_RK30)
#if defined(CONFIG_DUAL_DISP_IN_KERNEL)
if(hdmi_get_hotplug())
if(hdmi_get_hotplug() == HDMI_HPD_ACTIVED)
{
if(inf->num_fb >= 2)
{
@ -481,7 +481,7 @@ static int rk_fb_set_par(struct fb_info *info)
#if defined(CONFIG_HDMI_RK30)
#if defined(CONFIG_DUAL_DISP_IN_KERNEL)
if(hdmi_get_hotplug())
if(hdmi_get_hotplug() == HDMI_HPD_ACTIVED)
{
if(info != info2)
{
@ -638,6 +638,7 @@ int rk_fb_switch_screen(rk_screen *screen ,int enable ,int lcdc_id)
if(!enable)
{
dev_drv->open(dev_drv,layer_id,enable); //disable the layer which attached to this fb
return 0;
}
hdmi_var = &info->var;