freescale R10 ipu lib 分析 - ipu_common.c

ipu_common.c

 

Common IPU API implementation,主要是为MXC V4L2和ipu device驱动提供IPU channel控制函数

 

 110 static inline int _ipu_is_ic_chan(uint32_t dma_chan)
 111 {
 112     return ((dma_chan >= 11) && (dma_chan <= 22) && (dma_chan != 17) && (dma_chan != 18));
 113 }

 

 

 126 static inline int _ipu_is_irt_chan(uint32_t dma_chan)
 127 {
 128     return ((dma_chan >= 45) && (dma_chan <= 50));
 129 }
channel 45-47 Bmem->IRT, channel 48-50 IRT->Bmem

 

 136 static inline int _ipu_is_smfc_chan(uint32_t dma_chan)
 137 {
 138     return ((dma_chan >= 0) && (dma_chan <= 3));
 139 }
DMA channel 是一个smfc channel,参看MX51 datasheet 42.4.2.1可知,0, 1, 2, 3通过smfc到达mem

这几个通道从CSI获取capture的数据 不做处理然后存储在mem中。(我现在疑惑的是channel本身有interlaced功能,这个算不算处理)

事实上是可以用这个channel进行de-interlaced的, 当然这种de-interlaced只是简单的de-interlaced方式,对于某些情况下(top bottom field拍摄时间点相差较大)的运动景象,可能不适应,我现在好奇的是VDI怎么解决运动景象de-interlaced问题的

 

 461 int32_t ipu_init_channel(ipu_channel_t channel, ipu_channel_params_t *params)
 462 {
 463     int ret = 0;
 464     uint32_t ipu_conf;
 465     uint32_t reg;
 466     unsigned long lock_flags;
 467
 468     dev_dbg(g_ipu_dev, "init channel = %d/n", IPU_CHAN_ID(channel));
 469
 470     /* re-enable error interrupts every time a channel is initialized */
 471     __raw_writel(0xFFFFFFFF, IPU_INT_CTRL(5));
 472     __raw_writel(0xFFFFFFFF, IPU_INT_CTRL(6));
 473     __raw_writel(0xFFFFFFFF, IPU_INT_CTRL(9));
 474     __raw_writel(0xFFFFFFFF, IPU_INT_CTRL(10));
 475
 476     if (g_ipu_clk_enabled == false) {
 477         stop_dvfs_per();
 478         g_ipu_clk_enabled = true;
 479         clk_enable(g_ipu_clk);
 480     }
 481
 482     spin_lock_irqsave(&ipu_lock, lock_flags);
 483
 484     if (g_channel_init_mask & (1L << IPU_CHAN_ID(channel))) {
 485         dev_err(g_ipu_dev, "Warning: channel already initialized %d/n",
 486             IPU_CHAN_ID(channel));
 487     }
 488
 489     ipu_conf = __raw_readl(IPU_CONF);
 490
 491     switch (channel) {
 492     case CSI_MEM0:
 493     case CSI_MEM1:
 494     case CSI_MEM2:
 495     case CSI_MEM3:
 496         if (params->csi_mem.csi > 1) {
 497             ret = -EINVAL;
 498             goto err;
 499         }
 500
 501         if (params->csi_mem.interlaced)
 502             g_chan_is_interlaced[channel_2_dma(channel,
 503                 IPU_OUTPUT_BUFFER)] = true;
 504         else
 505             g_chan_is_interlaced[channel_2_dma(channel,
 506                 IPU_OUTPUT_BUFFER)] = false;
 507
 508         ipu_smfc_use_count++;
 509         g_ipu_csi_channel[params->csi_mem.csi] = channel;
 510
 511         /*SMFC setting*/
 512         if (params->csi_mem.mipi_en) {
 513             ipu_conf |= (1 << (IPU_CONF_CSI0_DATA_SOURCE_OFFSET +
 514                 params->csi_mem.csi));
 515             _ipu_smfc_init(channel, params->csi_mem.mipi_id,
 516                 params->csi_mem.csi);
 517         } else {
 518             ipu_conf &= ~(1 << (IPU_CONF_CSI0_DATA_SOURCE_OFFSET +
 519                 params->csi_mem.csi));
 520             _ipu_smfc_init(channel, 0, params->csi_mem.csi);
 521         }
 522
 523         /*CSI data (include compander) dest*/
 524         _ipu_csi_init(channel, params->csi_mem.csi);
 525         break;

 

501 caller应该根据sensor传入的数据格式设置csi_mem,   如果数据是隔行的,那么设置一个g_chan_is_interlaced,这个标志会在完为为这个channel调用 _ipu_ch_param_set_interlaced_scan. 

524 调用_ipu_csi_init来设置CSI数据的流向,在当前的场景下, CSI数据通过SMFC流向IMDAC

 

 526     case CSI_PRP_ENC_MEM:
 527         if (params->csi_prp_enc_mem.csi > 1) {
 528             ret = -EINVAL;
 529             goto err;
 530         }
 531         if (using_ic_dirct_ch == MEM_VDI_PRP_VF_MEM) {
 532             ret = -EINVAL;
 533             goto err;
 534         }
 535         using_ic_dirct_ch = CSI_PRP_ENC_MEM;
 536
 537         ipu_ic_use_count++;
 538         g_ipu_csi_channel[params->csi_prp_enc_mem.csi] = channel;
 539
 540         /*Without SMFC, CSI only support parallel data source*/
 541         ipu_conf &= ~(1 << (IPU_CONF_CSI0_DATA_SOURCE_OFFSET +
 542             params->csi_prp_enc_mem.csi));
 543
 544         /*CSI0/1 feed into IC*/
 545         ipu_conf &= ~IPU_CONF_IC_INPUT;
 546         if (params->csi_prp_enc_mem.csi)
 547             ipu_conf |= IPU_CONF_CSI_SEL;
 548         else
 549             ipu_conf &= ~IPU_CONF_CSI_SEL;
 550
 551         /*PRP skip buffer in memory, only valid when RWS_EN is true*/
 552         reg = __raw_readl(IPU_FS_PROC_FLOW1);
 553         __raw_writel(reg & ~FS_ENC_IN_VALID, IPU_FS_PROC_FLOW1);
 554
 555         /*CSI data (include compander) dest*/
 556         _ipu_csi_init(channel, params->csi_prp_enc_mem.csi);
 557         _ipu_ic_init_prpenc(params, true);
 558         break;

 

540~542 设置数据源为parallel

544~549 设置IPU_CONF的CSI select bit, this bit select manually between 2 CSIs, 仅当IC_INPUT bit 清除时有效

行553 暂时不知道干嘛的

行556 设置CSI sensor的数据流向

行557 设置resize寄存器IC_CONF_ENC_RSC, 设置CSC(color space convert) 寄存器, 设置...

 

 

 

 

你可能感兴趣的:(api,buffer,input,include,output,parallel)