📄 imgdma.c
字号:
if(s->cb)
reg = IMGDMA_IBW2_CON_IT;
if(s->twice)
{
imgdma_dcb.twice = KAL_TRUE;
reg |= IMGDMA_IBW2_CON_TWC;
}
if(s->lcd_hk)
reg |= IMGDMA_IBW2_CON_LCD;
if(s->restart)
reg |= IMGDMA_IBW2_CON_ATUORSTR;
if(s->couple)
reg |= IMGDMA_IBW2_CON_DC;
if(s->pan)
{
reg |= IMGDMA_IBW2_CON_PAN;
DRV_WriteReg32(IMGDMA_IBW2_HPITCH1, s->hpitch1);
DRV_WriteReg32(IMGDMA_IBW2_HPITCH2, s->hpitch2);
DRV_WriteReg32(IMGDMA_IBW2_VPITCH1, s->vpitch1);
DRV_WriteReg32(IMGDMA_IBW2_VPITCH2, s->vpitch2);
}
DRV_WriteReg32(IMGDMA_IBW2_CON, reg);
DRV_WriteReg32(IMGDMA_IBW2_BSADDR1, s->bs1);
DRV_WriteReg32(IMGDMA_IBW2_BSADDR2, s->bs2);
DRV_WriteReg32(IMGDMA_IBW2_HSIZE, s->width-1);
DRV_WriteReg32(IMGDMA_IBW2_VSIZE, s->height-1);
imgdma_dcb.state[IMGDMA_IBW2_CH] = IMGDMA_READY;
if(start)
{
IMGDMA_Start(IMGDMA_IBW2_CH, owner);
}
return NO_ERROR;
}
/*
* FUNCTION
* IMGPROC_SetColorize
*
* DESCRIPTION
* Set the parameters for colorization
*
* CALLS
*
* PARAMETERS
*
* RETURNS
* None
*
* GLOBALS AFFECTED
* None
*/
kal_int32 API IMGDMA_IBR1Config(IMGDMA_IBR1_STRUCT *s, kal_bool start, MMDI_SCENERIO_ID owner)
{
kal_uint32 reg = 0;
ASSERT(owner == imgdma_dcb.owner);
ASSERT(imgdma_dcb.state[IMGDMA_IBR1_CH] != IMGDMA_BUSY);
imgdma_dcb.cb[IMGDMA_IBR1_CH] = s->cb;
if(s->cb)
reg = IMGDMA_IBR1_CON_IT;
if(s->type == IBR1_TYPE_RGB888)
{
reg |= IMGDMA_IBR1_CON_FMT;
if(s->order == IBR1_ORDER_RGB888)
reg |= IMGDMA_IBR1_CON_FMT;
}
DRV_WriteReg32(IMGDMA_IBR1_CON, reg);
DRV_WriteReg32(IMGDMA_IBR1_PXLNUM, s->pxlnum-1);
DRV_WriteReg32(IMGDMA_IBR1_BSADDR, s->bs);
imgdma_dcb.state[IMGDMA_IBR1_CH] = IMGDMA_READY;
if(start)
{
IMGDMA_Start(IMGDMA_IBR1_CH, owner);
}
return NO_ERROR;
}
/*
* FUNCTION
* IMGDMA_CheckBusy
*
* DESCRIPTION
* Check the specified channel is busy
*
* CALLS
*
* PARAMETERS
*
* RETURNS
* None
*
* GLOBALS AFFECTED
* None
*/
kal_bool API IMGDMA_CheckBusy(IMGDMA_CHANNEL_ENUM ch, MMDI_SCENERIO_ID owner)
{
kal_uint32 reg;
ASSERT(owner == imgdma_dcb.owner);
reg = DRV_Reg32(IMGDMA_STA) >> 16;
if(reg & (1 << ch))
return KAL_TRUE;
return KAL_FALSE;
}
/*
* FUNCTION
* IMGDMA_Open
*
* DESCRIPTION
* Obtain the owner ship of the IMGDMA
*
* CALLS
*
* PARAMETERS
*
* RETURNS
* None
*
* GLOBALS AFFECTED
* None
*/
kal_int32 API IMGDMA_Open(MMDI_SCENERIO_ID owner)
{
ENTER_CRITICAL();
ASSERT(imgdma_dcb.owner == SCENARIO_UNKNOW_ID);
imgdma_dcb.owner = owner;
EXIT_CRITICAL();
DRVPDN_Disable(DRVPDN_CON3,DRVPDN_CON3_IMGDMA,PDN_IMGDMA);
return NO_ERROR;
}
/*
* FUNCTION
* IMGDMA_Close
*
* DESCRIPTION
* Release the ownership of the IMGDMA
*
* CALLS
*
* PARAMETERS
*
* RETURNS
* None
*
* GLOBALS AFFECTED
* None
*/
kal_int32 API IMGDMA_Close(MMDI_SCENERIO_ID owner)
{
kal_uint32 i;
ASSERT(imgdma_dcb.owner == owner);
kal_mem_set(&imgdma_dcb,0,sizeof(IMGDMA_DCB_STRUCT));
for(i=0;i<IMGDMA_ALL_CH;i++)
{
DRV_Reg(IMGDMA_STR(i)) = 0;
DRV_Reg(IMGDMA_CON(i)) = 0;
}
DRVPDN_Enable(DRVPDN_CON3,DRVPDN_CON3_IMGDMA,PDN_IMGDMA);
return NO_ERROR;
}
/*
* FUNCTION
* IMGDMA_Start
*
* DESCRIPTION
* start the specified channel to funciotn
*
* CALLS
*
* PARAMETERS
*
* RETURNS
* None
*
* GLOBALS AFFECTED
* None
*/
kal_int32 API IMGDMA_Start(IMGDMA_CHANNEL_ENUM ch, MMDI_SCENERIO_ID owner)
{
ASSERT(imgdma_dcb.state[ch] == IMGDMA_READY);
ASSERT(owner == imgdma_dcb.owner);
imgdma_dcb.state[ch] = IMGDMA_BUSY;
IMGDMA_START(ch);
return NO_ERROR;
}
/*
* FUNCTION
* IMGDMA_Stop
*
* DESCRIPTION
* stop the specified channel with various method
*
* CALLS
*
* PARAMETERS
*
* RETURNS
* None
*
* GLOBALS AFFECTED
* None
*/
kal_int32 API IMGDMA_Stop(IMGDMA_CHANNEL_ENUM ch, IMGDMA_STOP_ENUM stop, IDMA_Callback stop_cb, MMDI_SCENERIO_ID owner)
{
kal_bool busy;
kal_uint16 auto_rstr;
ASSERT(owner == imgdma_dcb.owner);
switch(stop)
{
case IMGDMA_STOP_NOW:
IMGDMA_STOP(ch);
break;
case IMGDMA_STOP_CALLBACK:
// It should be used wihtout enabling auto restart.
ASSERT(stop_cb != NULL);
if(ch == IMGDMA_VDO_CH)
{
ASSERT((DRV_Reg(IMGDMA_CON(ch))& IMGDMA_VDO_CON_AUTORSTR) == 0);
}
else if(ch == IMGDMA_IBW2_CH)
{
ASSERT((DRV_Reg(IMGDMA_CON(ch))& IMGDMA_IBW2_CON_ATUORSTR) == 0);
}
busy = IMGDMA_CheckBusy(ch,owner);
if(busy == KAL_TRUE)
{
imgdma_dcb.stop_cb[ch] = KAL_TRUE;
imgdma_dcb.cb[ch] = stop_cb;
IMGDMA_ENABLE_INT(ch);
busy = IMGDMA_CheckBusy(ch,owner);
if(busy == KAL_FALSE && imgdma_dcb.stop_cb[ch] == KAL_TRUE)
{
IMGDMA_STOP(ch);
IMGDMA_DISABLE_INT(ch);
stop_cb();
}
}
else
stop_cb();
break;
case IMGDMA_STOP_AT_FRAME_BOUNDARY:
// It will make sure IMGDMA will stop at the frame bounday
// Stop IMGDMA first and then the ISP source, the remain data will be dropped by IMGDMA
// The worse case is that it may block for a frame time.
ASSERT(ch == IMGDMA_VDO_CH || ch == IMGDMA_IBW2_CH);
auto_rstr = (ch == IMGDMA_VDO_CH)?IMGDMA_VDO_CON_AUTORSTR:IMGDMA_IBW2_CON_ATUORSTR;
DRV_Reg(IMGDMA_CON(ch))&= ~auto_rstr;
while(IMGDMA_IS_BUSY(ch));
break;
case IMGDMA_STOP_IDLE:
break;
default:
ASSERT(0);
break;
}
imgdma_dcb.state[ch] = IMGDMA_READY;
return NO_ERROR;
}
/*
* FUNCTION
* IMGDMA_VdoSetBS1
*
* DESCRIPTION
* Set the bass address for VDO channel ( for MPEG4 decode)
*
* CALLS
*
* PARAMETERS
*
* RETURNS
* None
*
* GLOBALS AFFECTED
* None
*/
kal_int32 API IMGDMA_VdoSetBS1(kal_uint32 bs, MMDI_SCENERIO_ID owner)
{
ASSERT(imgdma_dcb.state[IMGDMA_VDO_CH] == IMGDMA_READY);
ASSERT(owner == imgdma_dcb.owner);
DRV_WriteReg32(IMGDMA_VDO_BSADDR1, bs);
return NO_ERROR;
}
#if 0
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
#endif
#endif /* MT6219, MT6226, MT6227 */
#if (defined(MT6228)||defined(MT6229)||defined(MT6230))
void set_overlay_palette(kal_uint8 palette_size,kal_uint32 *palette_addr_ptr)
{
kal_uint16 i;
kal_uint32 save_irq_mask;
save_irq_mask=SaveAndSetIRQMask();
DRV_Reg(DRVPDN_CON3) &= (~DRVPDN_CON3_IMGDMA); /* Turn on image DMA clock */
RestoreIRQMask(save_irq_mask);
ENABLE_IMGDMA_IBR2_PALETTE;
for (i=0;i<=palette_size;i++)
{
*((volatile kal_uint32 *) (IMGDMA_IBR2_COLOR_PALETTE_BASE+ (i<<2)))= *(palette_addr_ptr+i);
}
if (current_image_data_path_owner==SCENARIO_UNKNOW_ID)
{
save_irq_mask=SaveAndSetIRQMask();
DRV_Reg(DRVPDN_CON3) &= (~DRVPDN_CON3_IMGDMA); /* Turn on image DMA clock */
RestoreIRQMask(save_irq_mask);
}
} /* set_overlay_palette() */
void image_dma_LISR(void)
{
kal_uint32 reg;
IRQMask(IRQ_IMGDMA_CODE);
reg = DRV_Reg32(IMGDMA_STATUS_REG);
ASSERT(reg != 0);
// first run of VDO
if (reg & IMGDMA_IBW2_INT_STATUS_BIT)
{
ACK_IMGDMA_IBW2_INT;
if(ibw2_cb!=NULL)
ibw2_cb();
}
// interrupts may occur simutaneusly
else if(reg & IMGDMA_IBW1_INT_STATUS_BIT)
{
ACK_IMGDMA_IBW1_INT;
}
else if (reg & IMGDMA_VIDEO_ENCODE_W_INT_STATUS_BIT)
{
ACK_IMGDMA_VIDEO_ENCODE_W_INT;
if (MPEG4_RECODE_START==KAL_TRUE)
{
if (vid_enc_w_cb1!=NULL)
vid_enc_w_cb1(mpeg4_video_buffer[current_video_buffer_count]);
}
current_video_buffer_count++;
current_video_buffer_count &= 0x1;
if (vid_enc_w_cb!=NULL)
vid_enc_w_cb();
if (vid_enc_r_cb!=NULL)
vid_enc_r_cb();
}
else if (reg & IMGDMA_VIDEO_ENCODE_R_INT_STATUS_BIT)
{
ACK_IMGDMA_VIDEO_ENCODE_R_INT;
}
else if (reg & IMGDMA_VIDEO_DECODE_INT_STATUS_BIT)
{
ACK_IMGDMA_VIDEO_DECODE_INT;
}
else if (reg & IMGDMA_IBW2_INT_STATUS_BIT)
{
ACK_IMGDMA_IBW2_INT;
if (ibw2_cb!=NULL)
ibw2_cb();
}
else if (reg & IMGDMA_IBR1_INT_STATUS_BIT)
{
ACK_IMGDMA_IBR1_INT;
}
else if (reg & IMGDMA_IBR2_INT_STATUS_BIT)
{
ACK_IMGDMA_IBR2_INT;
}
else if (reg & IMGDMA_IBW3_INT_STATUS_BIT)
{
if (wait_ibw3_complete==KAL_TRUE)
{
ibw3_complete_flag=KAL_TRUE;
}
ACK_IMGDMA_IBW3_INT;
}
else if (reg & IMGDMA_IBW4_INT_STATUS_BIT)
{
#if 1
if (wait_ibw4_complete==KAL_TRUE)
{
ibw4_complete_flag=KAL_TRUE;
}
#endif
ACK_IMGDMA_IBW4_INT;
}
IRQUnmask(IRQ_IMGDMA_CODE);
} /* image_dma_LISR() */
void init_image_dma(void)
{
IRQ_Register_LISR(IRQ_IMGDMA_CODE, image_dma_LISR,"IMGDMA");
IRQSensitivity(IRQ_IMGDMA_CODE,LEVEL_SENSITIVE);
IRQUnmask(IRQ_IMGDMA_CODE);
} /* init_image_dma() */
/*the following defines the control part of IMGDMA*/
void IMGDMA_IBW1Config(IMGDMA_IBW1_STRUCT *ibw1_struct)
{
STOP_IBW1;
REG_IMGDMA_IBW1_CTRL=0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -