diff options
Diffstat (limited to 'drivers/staging/dream/camera/msm_vfe8x_proc.c')
-rw-r--r-- | drivers/staging/dream/camera/msm_vfe8x_proc.c | 4003 |
1 files changed, 0 insertions, 4003 deletions
diff --git a/drivers/staging/dream/camera/msm_vfe8x_proc.c b/drivers/staging/dream/camera/msm_vfe8x_proc.c deleted file mode 100644 index f80ef967ba8..00000000000 --- a/drivers/staging/dream/camera/msm_vfe8x_proc.c +++ /dev/null @@ -1,4003 +0,0 @@ -/* -* Copyright (C) 2008-2009 QUALCOMM Incorporated. -*/ -#include <linux/slab.h> -#include <linux/interrupt.h> -#include <linux/spinlock.h> -#include <linux/io.h> -#include <linux/list.h> -#include <linux/delay.h> -#include <linux/platform_device.h> -#include "msm_vfe8x_proc.h" -#include <media/msm_camera.h> - -struct msm_vfe8x_ctrl { - /* bit 1:0 ENC_IRQ_MASK = 0x11: - * generate IRQ when both y and cbcr frame is ready. */ - - /* bit 1:0 VIEW_IRQ_MASK= 0x11: - * generate IRQ when both y and cbcr frame is ready. */ - struct vfe_irq_composite_mask_config vfeIrqCompositeMaskLocal; - struct vfe_module_enable vfeModuleEnableLocal; - struct vfe_camif_cfg_data vfeCamifConfigLocal; - struct vfe_interrupt_mask vfeImaskLocal; - struct vfe_stats_cmd_data vfeStatsCmdLocal; - struct vfe_bus_cfg_data vfeBusConfigLocal; - struct vfe_cmd_bus_pm_start vfeBusPmConfigLocal; - struct vfe_bus_cmd_data vfeBusCmdLocal; - enum vfe_interrupt_name vfeInterruptNameLocal; - uint32_t vfeLaBankSel; - struct vfe_gamma_lut_sel vfeGammaLutSel; - - boolean vfeStartAckPendingFlag; - boolean vfeStopAckPending; - boolean vfeResetAckPending; - boolean vfeUpdateAckPending; - - enum VFE_AXI_OUTPUT_MODE axiOutputMode; - enum VFE_START_OPERATION_MODE vfeOperationMode; - - uint32_t vfeSnapShotCount; - uint32_t vfeRequestedSnapShotCount; - boolean vfeStatsPingPongReloadFlag; - uint32_t vfeFrameId; - - struct vfe_cmd_frame_skip_config vfeFrameSkip; - uint32_t vfeFrameSkipPattern; - uint8_t vfeFrameSkipCount; - uint8_t vfeFrameSkipPeriod; - - boolean vfeTestGenStartFlag; - uint32_t vfeImaskPacked; - uint32_t vfeImaskCompositePacked; - enum VFE_RAW_PIXEL_DATA_SIZE axiInputDataSize; - struct vfe_irq_thread_msg vfeIrqThreadMsgLocal; - - struct vfe_output_path_combo viewPath; - struct vfe_output_path_combo encPath; - struct vfe_frame_skip_counts vfeDroppedFrameCounts; - struct vfe_stats_control afStatsControl; - struct vfe_stats_control awbStatsControl; - - enum VFE_STATE vstate; - - spinlock_t ack_lock; - spinlock_t state_lock; - spinlock_t io_lock; - - struct msm_vfe_callback *resp; - uint32_t extlen; - void *extdata; - - spinlock_t tasklet_lock; - struct list_head tasklet_q; - - int vfeirq; - void __iomem *vfebase; - - void *syncdata; -}; -static struct msm_vfe8x_ctrl *ctrl; -static irqreturn_t vfe_parse_irq(int irq_num, void *data); - -struct isr_queue_cmd { - struct list_head list; - struct vfe_interrupt_status vfeInterruptStatus; - struct vfe_frame_asf_info vfeAsfFrameInfo; - struct vfe_frame_bpc_info vfeBpcFrameInfo; - struct vfe_msg_camif_status vfeCamifStatusLocal; - struct vfe_bus_performance_monitor vfePmData; -}; - -static void vfe_prog_hw(uint8_t *hwreg, - uint32_t *inptr, uint32_t regcnt) -{ - /* unsigned long flags; */ - uint32_t i; - uint32_t *p; - - /* @todo This is causing issues, need further investigate */ - /* spin_lock_irqsave(&ctrl->io_lock, flags); */ - - p = (uint32_t *)(hwreg); - for (i = 0; i < (regcnt >> 2); i++) - writel(*inptr++, p++); - /* *p++ = *inptr++; */ - - /* spin_unlock_irqrestore(&ctrl->io_lock, flags); */ -} - -static void vfe_read_reg_values(uint8_t *hwreg, - uint32_t *dest, uint32_t count) -{ - /* unsigned long flags; */ - uint32_t *temp; - uint32_t i; - - /* @todo This is causing issues, need further investigate */ - /* spin_lock_irqsave(&ctrl->io_lock, flags); */ - - temp = (uint32_t *)(hwreg); - for (i = 0; i < count; i++) - *dest++ = *temp++; - - /* spin_unlock_irqrestore(&ctrl->io_lock, flags); */ -} - -static struct vfe_irqenable vfe_read_irq_mask(void) -{ - /* unsigned long flags; */ - uint32_t *temp; - struct vfe_irqenable rc; - - memset(&rc, 0, sizeof(rc)); - - /* @todo This is causing issues, need further investigate */ - /* spin_lock_irqsave(&ctrl->io_lock, flags); */ - temp = (uint32_t *)(ctrl->vfebase + VFE_IRQ_MASK); - - rc = *((struct vfe_irqenable *)temp); - /* spin_unlock_irqrestore(&ctrl->io_lock, flags); */ - - return rc; -} - -static void -vfe_set_bus_pipo_addr(struct vfe_output_path_combo *vpath, - struct vfe_output_path_combo *epath) -{ - vpath->yPath.hwRegPingAddress = (uint8_t *) - (ctrl->vfebase + VFE_BUS_VIEW_Y_WR_PING_ADDR); - vpath->yPath.hwRegPongAddress = (uint8_t *) - (ctrl->vfebase + VFE_BUS_VIEW_Y_WR_PONG_ADDR); - vpath->cbcrPath.hwRegPingAddress = (uint8_t *) - (ctrl->vfebase + VFE_BUS_VIEW_CBCR_WR_PING_ADDR); - vpath->cbcrPath.hwRegPongAddress = (uint8_t *) - (ctrl->vfebase + VFE_BUS_VIEW_CBCR_WR_PONG_ADDR); - - epath->yPath.hwRegPingAddress = (uint8_t *) - (ctrl->vfebase + VFE_BUS_ENC_Y_WR_PING_ADDR); - epath->yPath.hwRegPongAddress = (uint8_t *) - (ctrl->vfebase + VFE_BUS_ENC_Y_WR_PONG_ADDR); - epath->cbcrPath.hwRegPingAddress = (uint8_t *) - (ctrl->vfebase + VFE_BUS_ENC_CBCR_WR_PING_ADDR); - epath->cbcrPath.hwRegPongAddress = (uint8_t *) - (ctrl->vfebase + VFE_BUS_ENC_CBCR_WR_PONG_ADDR); -} - -static void vfe_axi_output(struct vfe_cmd_axi_output_config *in, - struct vfe_output_path_combo *out1, - struct vfe_output_path_combo *out2, uint16_t out) -{ - struct vfe_axi_out_cfg cmd; - - uint16_t temp; - uint32_t burstLength; - - /* force it to burst length 4, hardware does not support it. */ - burstLength = 1; - - /* AXI Output 2 Y Configuration*/ - /* VFE_BUS_ENC_Y_WR_PING_ADDR */ - cmd.out2YPingAddr = out2->yPath.addressBuffer[0]; - - /* VFE_BUS_ENC_Y_WR_PONG_ADDR */ - cmd.out2YPongAddr = out2->yPath.addressBuffer[1]; - - /* VFE_BUS_ENC_Y_WR_IMAGE_SIZE */ - cmd.out2YImageHeight = in->output2.outputY.imageHeight; - /* convert the image width and row increment to be in - * unit of 64bit (8 bytes) */ - temp = (in->output2.outputY.imageWidth + (out - 1)) / - out; - cmd.out2YImageWidthin64bit = temp; - - /* VFE_BUS_ENC_Y_WR_BUFFER_CFG */ - cmd.out2YBurstLength = burstLength; - cmd.out2YNumRows = in->output2.outputY.outRowCount; - temp = (in->output2.outputY.outRowIncrement + (out - 1)) / - out; - cmd.out2YRowIncrementIn64bit = temp; - - /* AXI Output 2 Cbcr Configuration*/ - /* VFE_BUS_ENC_Cbcr_WR_PING_ADDR */ - cmd.out2CbcrPingAddr = out2->cbcrPath.addressBuffer[0]; - - /* VFE_BUS_ENC_Cbcr_WR_PONG_ADDR */ - cmd.out2CbcrPongAddr = out2->cbcrPath.addressBuffer[1]; - - /* VFE_BUS_ENC_Cbcr_WR_IMAGE_SIZE */ - cmd.out2CbcrImageHeight = in->output2.outputCbcr.imageHeight; - temp = (in->output2.outputCbcr.imageWidth + (out - 1)) / - out; - cmd.out2CbcrImageWidthIn64bit = temp; - - /* VFE_BUS_ENC_Cbcr_WR_BUFFER_CFG */ - cmd.out2CbcrBurstLength = burstLength; - cmd.out2CbcrNumRows = in->output2.outputCbcr.outRowCount; - temp = (in->output2.outputCbcr.outRowIncrement + (out - 1)) / - out; - cmd.out2CbcrRowIncrementIn64bit = temp; - - /* AXI Output 1 Y Configuration */ - /* VFE_BUS_VIEW_Y_WR_PING_ADDR */ - cmd.out1YPingAddr = out1->yPath.addressBuffer[0]; - - /* VFE_BUS_VIEW_Y_WR_PONG_ADDR */ - cmd.out1YPongAddr = out1->yPath.addressBuffer[1]; - - /* VFE_BUS_VIEW_Y_WR_IMAGE_SIZE */ - cmd.out1YImageHeight = in->output1.outputY.imageHeight; - temp = (in->output1.outputY.imageWidth + (out - 1)) / - out; - cmd.out1YImageWidthin64bit = temp; - - /* VFE_BUS_VIEW_Y_WR_BUFFER_CFG */ - cmd.out1YBurstLength = burstLength; - cmd.out1YNumRows = in->output1.outputY.outRowCount; - - temp = - (in->output1.outputY.outRowIncrement + - (out - 1)) / out; - cmd.out1YRowIncrementIn64bit = temp; - - /* AXI Output 1 Cbcr Configuration*/ - cmd.out1CbcrPingAddr = out1->cbcrPath.addressBuffer[0]; - - /* VFE_BUS_VIEW_Cbcr_WR_PONG_ADDR */ - cmd.out1CbcrPongAddr = - out1->cbcrPath.addressBuffer[1]; - - /* VFE_BUS_VIEW_Cbcr_WR_IMAGE_SIZE */ - cmd.out1CbcrImageHeight = in->output1.outputCbcr.imageHeight; - temp = (in->output1.outputCbcr.imageWidth + - (out - 1)) / out; - cmd.out1CbcrImageWidthIn64bit = temp; - - cmd.out1CbcrBurstLength = burstLength; - cmd.out1CbcrNumRows = in->output1.outputCbcr.outRowCount; - temp = - (in->output1.outputCbcr.outRowIncrement + - (out - 1)) / out; - - cmd.out1CbcrRowIncrementIn64bit = temp; - - vfe_prog_hw(ctrl->vfebase + VFE_BUS_ENC_Y_WR_PING_ADDR, - (uint32_t *)&cmd, sizeof(cmd)); -} - -static void vfe_reg_bus_cfg(struct vfe_bus_cfg_data *in) -{ - struct vfe_axi_bus_cfg cmd; - - cmd.stripeRdPathEn = in->stripeRdPathEn; - cmd.encYWrPathEn = in->encYWrPathEn; - cmd.encCbcrWrPathEn = in->encCbcrWrPathEn; - cmd.viewYWrPathEn = in->viewYWrPathEn; - cmd.viewCbcrWrPathEn = in->viewCbcrWrPathEn; - cmd.rawPixelDataSize = (uint32_t)in->rawPixelDataSize; - cmd.rawWritePathSelect = (uint32_t)in->rawWritePathSelect; - - /* program vfe_bus_cfg */ - writel(*((uint32_t *)&cmd), ctrl->vfebase + VFE_BUS_CFG); -} - -static void vfe_reg_camif_config(struct vfe_camif_cfg_data *in) -{ - struct VFE_CAMIFConfigType cfg; - - memset(&cfg, 0, sizeof(cfg)); - - cfg.VSyncEdge = - in->camifCfgFromCmd.vSyncEdge; - - cfg.HSyncEdge = - in->camifCfgFromCmd.hSyncEdge; - - cfg.syncMode = - in->camifCfgFromCmd.syncMode; - - cfg.vfeSubsampleEnable = - in->camifCfgFromCmd.vfeSubSampleEnable; - - cfg.busSubsampleEnable = - in->camifCfgFromCmd.busSubSampleEnable; - - cfg.camif2vfeEnable = - in->camif2OutputEnable; - - cfg.camif2busEnable = - in->camif2BusEnable; - - cfg.irqSubsampleEnable = - in->camifCfgFromCmd.irqSubSampleEnable; - - cfg.binningEnable = - in->camifCfgFromCmd.binningEnable; - - cfg.misrEnable = - in->camifCfgFromCmd.misrEnable; - - /* program camif_config */ - writel(*((uint32_t *)&cfg), ctrl->vfebase + CAMIF_CONFIG); -} - -static void vfe_reg_bus_cmd(struct vfe_bus_cmd_data *in) -{ - struct vfe_buscmd cmd; - memset(&cmd, 0, sizeof(cmd)); - - cmd.stripeReload = in->stripeReload; - cmd.busPingpongReload = in->busPingpongReload; - cmd.statsPingpongReload = in->statsPingpongReload; - - writel(*((uint32_t *)&cmd), ctrl->vfebase + VFE_BUS_CMD); - - CDBG("bus command = 0x%x\n", (*((uint32_t *)&cmd))); - - /* this is needed, as the control bits are pulse based. - * Don't want to reload bus pingpong again. */ - in->busPingpongReload = 0; - in->statsPingpongReload = 0; - in->stripeReload = 0; -} - -static void vfe_reg_module_cfg(struct vfe_module_enable *in) -{ - struct vfe_mod_enable ena; - - memset(&ena, 0, sizeof(ena)); - - ena.blackLevelCorrectionEnable = in->blackLevelCorrectionEnable; - ena.lensRollOffEnable = in->lensRollOffEnable; - ena.demuxEnable = in->demuxEnable; - ena.chromaUpsampleEnable = in->chromaUpsampleEnable; - ena.demosaicEnable = in->demosaicEnable; - ena.statsEnable = in->statsEnable; - ena.cropEnable = in->cropEnable; - ena.mainScalerEnable = in->mainScalerEnable; - ena.whiteBalanceEnable = in->whiteBalanceEnable; - ena.colorCorrectionEnable = in->colorCorrectionEnable; - ena.yHistEnable = in->yHistEnable; - ena.skinToneEnable = in->skinToneEnable; - ena.lumaAdaptationEnable = in->lumaAdaptationEnable; - ena.rgbLUTEnable = in->rgbLUTEnable; - ena.chromaEnhanEnable = in->chromaEnhanEnable; - ena.asfEnable = in->asfEnable; - ena.chromaSuppressionEnable = in->chromaSuppressionEnable; - ena.chromaSubsampleEnable = in->chromaSubsampleEnable; - ena.scaler2YEnable = in->scaler2YEnable; - ena.scaler2CbcrEnable = in->scaler2CbcrEnable; - - writel(*((uint32_t *)&ena), ctrl->vfebase + VFE_MODULE_CFG); -} - -static void vfe_program_dmi_cfg(enum VFE_DMI_RAM_SEL bankSel) -{ - /* set bit 8 for auto increment. */ - uint32_t value = (uint32_t) ctrl->vfebase + VFE_DMI_CFG_DEFAULT; - - value += (uint32_t)bankSel; - /* CDBG("dmi cfg input bank is 0x%x\n", bankSel); */ - - writel(value, ctrl->vfebase + VFE_DMI_CFG); - writel(0, ctrl->vfebase + VFE_DMI_ADDR); -} - -static void vfe_write_lens_roll_off_table( - struct vfe_cmd_roll_off_config *in) -{ - uint16_t i; - uint32_t data; - - uint16_t *initGr = in->initTableGr; - uint16_t *initGb = in->initTableGb; - uint16_t *initB = in->initTableB; - uint16_t *initR = in->initTableR; - - int16_t *pDeltaGr = in->deltaTableGr; - int16_t *pDeltaGb = in->deltaTableGb; - int16_t *pDeltaB = in->deltaTableB; - int16_t *pDeltaR = in->deltaTableR; - - vfe_program_dmi_cfg(ROLLOFF_RAM); - - /* first pack and write init table */ - for (i = 0; i < VFE_ROLL_OFF_INIT_TABLE_SIZE; i++) { - data = (((uint32_t)(*initR)) & 0x0000FFFF) | - (((uint32_t)(*initGr)) << 16); - initR++; - initGr++; - - writel(data, ctrl->vfebase + VFE_DMI_DATA_LO); - - data = (((uint32_t)(*initB)) & 0x0000FFFF) | - (((uint32_t)(*initGr))<<16); - initB++; - initGb++; - - writel(data, ctrl->vfebase + VFE_DMI_DATA_LO); - } - - /* there are gaps between the init table and delta table, - * set the offset for delta table. */ - writel(LENS_ROLL_OFF_DELTA_TABLE_OFFSET, - ctrl->vfebase + VFE_DMI_ADDR); - - /* pack and write delta table */ - for (i = 0; i < VFE_ROLL_OFF_DELTA_TABLE_SIZE; i++) { - data = (((int32_t)(*pDeltaR)) & 0x0000FFFF) | - (((int32_t)(*pDeltaGr))<<16); - pDeltaR++; - pDeltaGr++; - - writel(data, ctrl->vfebase + VFE_DMI_DATA_LO); - - data = (((int32_t)(*pDeltaB)) & 0x0000FFFF) | - (((int32_t)(*pDeltaGb))<<16); - pDeltaB++; - pDeltaGb++; - - writel(data, ctrl->vfebase + VFE_DMI_DATA_LO); - } - - /* After DMI transfer, to make it safe, need to set the - * DMI_CFG to unselect any SRAM - */ - /* unselect the SRAM Bank. */ - writel(VFE_DMI_CFG_DEFAULT, ctrl->vfebase + VFE_DMI_CFG); -} - -static void vfe_set_default_reg_values(void) -{ - writel(0x800080, ctrl->vfebase + VFE_DEMUX_GAIN_0); - writel(0x800080, ctrl->vfebase + VFE_DEMUX_GAIN_1); - writel(0xFFFFF, ctrl->vfebase + VFE_CGC_OVERRIDE); - - /* default frame drop period and pattern */ - writel(0x1f, ctrl->vfebase + VFE_FRAMEDROP_ENC_Y_CFG); - writel(0x1f, ctrl->vfebase + VFE_FRAMEDROP_ENC_CBCR_CFG); - writel(0xFFFFFFFF, ctrl->vfebase + VFE_FRAMEDROP_ENC_Y_PATTERN); - writel(0xFFFFFFFF, ctrl->vfebase + VFE_FRAMEDROP_ENC_CBCR_PATTERN); - writel(0x1f, ctrl->vfebase + VFE_FRAMEDROP_VIEW_Y_CFG); - writel(0x1f, ctrl->vfebase + VFE_FRAMEDROP_VIEW_CBCR_CFG); - writel(0xFFFFFFFF, ctrl->vfebase + VFE_FRAMEDROP_VIEW_Y_PATTERN); - writel(0xFFFFFFFF, ctrl->vfebase + VFE_FRAMEDROP_VIEW_CBCR_PATTERN); - writel(0, ctrl->vfebase + VFE_CLAMP_MIN_CFG); - writel(0xFFFFFF, ctrl->vfebase + VFE_CLAMP_MAX_CFG); -} - -static void vfe_config_demux(uint32_t period, uint32_t even, uint32_t odd) -{ - writel(period, ctrl->vfebase + VFE_DEMUX_CFG); - writel(even, ctrl->vfebase + VFE_DEMUX_EVEN_CFG); - writel(odd, ctrl->vfebase + VFE_DEMUX_ODD_CFG); -} - -static void vfe_pm_stop(void) -{ - writel(VFE_PERFORMANCE_MONITOR_STOP, ctrl->vfebase + VFE_BUS_PM_CMD); -} - -static void vfe_program_bus_rd_irq_en(uint32_t value) -{ - writel(value, ctrl->vfebase + VFE_BUS_PINGPONG_IRQ_EN); -} - -static void vfe_camif_go(void) -{ - writel(CAMIF_COMMAND_START, ctrl->vfebase + CAMIF_COMMAND); -} - -static void vfe_camif_stop_immediately(void) -{ - writel(CAMIF_COMMAND_STOP_IMMEDIATELY, ctrl->vfebase + CAMIF_COMMAND); - writel(0, ctrl->vfebase + VFE_CGC_OVERRIDE); -} - -static void vfe_program_reg_update_cmd(uint32_t value) -{ - writel(value, ctrl->vfebase + VFE_REG_UPDATE_CMD); -} - -static void vfe_program_bus_cmd(uint32_t value) -{ - writel(value, ctrl->vfebase + VFE_BUS_CMD); -} - -static void vfe_program_global_reset_cmd(uint32_t value) -{ - writel(value, ctrl->vfebase + VFE_GLOBAL_RESET_CMD); -} - -static void vfe_program_axi_cmd(uint32_t value) -{ - writel(value, ctrl->vfebase + VFE_AXI_CMD); -} - -static void vfe_program_irq_composite_mask(uint32_t value) -{ - writel(value, ctrl->vfebase + VFE_IRQ_COMPOSITE_MASK); -} - -static inline void vfe_program_irq_mask(uint32_t value) -{ - writel(value, ctrl->vfebase + VFE_IRQ_MASK); -} - -static void vfe_program_chroma_upsample_cfg(uint32_t value) -{ - writel(value, ctrl->vfebase + VFE_CHROMA_UPSAMPLE_CFG); -} - -static uint32_t vfe_read_axi_status(void) -{ - return readl(ctrl->vfebase + VFE_AXI_STATUS); -} - -static uint32_t vfe_read_pm_status_in_raw_capture(void) -{ - return readl(ctrl->vfebase + VFE_BUS_ENC_CBCR_WR_PM_STATS_1); -} - -static void -vfe_set_stats_pingpong_address(struct vfe_stats_control *afControl, - struct vfe_stats_control *awbControl) -{ - afControl->hwRegPingAddress = (uint8_t *) - (ctrl->vfebase + VFE_BUS_STATS_AF_WR_PING_ADDR); - afControl->hwRegPongAddress = (uint8_t *) - (ctrl->vfebase + VFE_BUS_STATS_AF_WR_PONG_ADDR); - - awbControl->hwRegPingAddress = (uint8_t *) - (ctrl->vfebase + VFE_BUS_STATS_AWB_WR_PING_ADDR); - awbControl->hwRegPongAddress = (uint8_t *) - (ctrl->vfebase + VFE_BUS_STATS_AWB_WR_PONG_ADDR); -} - -static uint32_t vfe_read_camif_status(void) -{ - return readl(ctrl->vfebase + CAMIF_STATUS); -} - -static void vfe_program_lut_bank_sel(struct vfe_gamma_lut_sel *in) -{ - struct VFE_GammaLutSelect_ConfigCmdType cmd; - - memset(&cmd, 0, sizeof(cmd)); - - cmd.ch0BankSelect = in->ch0BankSelect; - cmd.ch1BankSelect = in->ch1BankSelect; - cmd.ch2BankSelect = in->ch2BankSelect; - CDBG("VFE gamma lut bank selection is 0x%x\n", *((uint32_t *)&cmd)); - vfe_prog_hw(ctrl->vfebase + VFE_LUT_BANK_SEL, - (uint32_t *)&cmd, sizeof(cmd)); -} - -static void vfe_program_stats_cmd(struct vfe_stats_cmd_data *in) -{ - struct VFE_StatsCmdType stats; - memset(&stats, 0, sizeof(stats)); - - stats.autoFocusEnable = in->autoFocusEnable; - stats.axwEnable = in->axwEnable; - stats.histEnable = in->histEnable; - stats.clearHistEnable = in->clearHistEnable; - stats.histAutoClearEnable = in->histAutoClearEnable; - stats.colorConversionEnable = in->colorConversionEnable; - - writel(*((uint32_t *)&stats), ctrl->vfebase + VFE_STATS_CMD); -} - -static void vfe_pm_start(struct vfe_cmd_bus_pm_start *in) -{ - struct VFE_Bus_Pm_ConfigCmdType cmd; - memset(&cmd, 0, sizeof(struct VFE_Bus_Pm_ConfigCmdType)); - - cmd.output2YWrPmEnable = in->output2YWrPmEnable; - cmd.output2CbcrWrPmEnable = in->output2CbcrWrPmEnable; - cmd.output1YWrPmEnable = in->output1YWrPmEnable; - cmd.output1CbcrWrPmEnable = in->output1CbcrWrPmEnable; - - vfe_prog_hw(ctrl->vfebase + VFE_BUS_PM_CFG, - (uint32_t *)&cmd, sizeof(cmd)); -} - -static void vfe_8k_pm_start(struct vfe_cmd_bus_pm_start *in) -{ - in->output1CbcrWrPmEnable = ctrl->vfeBusConfigLocal.viewCbcrWrPathEn; - in->output1YWrPmEnable = ctrl->vfeBusConfigLocal.viewYWrPathEn; - in->output2CbcrWrPmEnable = ctrl->vfeBusConfigLocal.encCbcrWrPathEn; - in->output2YWrPmEnable = ctrl->vfeBusConfigLocal.encYWrPathEn; - - if (in->output1CbcrWrPmEnable || in->output1YWrPmEnable) - ctrl->viewPath.pmEnabled = TRUE; - - if (in->output2CbcrWrPmEnable || in->output2YWrPmEnable) - ctrl->encPath.pmEnabled = TRUE; - - vfe_pm_start(in); - - writel(VFE_PERFORMANCE_MONITOR_GO, ctrl->vfebase + VFE_BUS_PM_CMD); -} - -static uint32_t vfe_irq_pack(struct vfe_interrupt_mask data) -{ - struct vfe_irqenable packedData; - - memset(&packedData, 0, sizeof(packedData)); - - packedData.camifErrorIrq = data.camifErrorIrq; - packedData.camifSofIrq = data.camifSofIrq; - packedData.camifEolIrq = data.camifEolIrq; - packedData.camifEofIrq = data.camifEofIrq; - packedData.camifEpoch1Irq = data.camifEpoch1Irq; - packedData.camifEpoch2Irq = data.camifEpoch2Irq; - packedData.camifOverflowIrq = data.camifOverflowIrq; - packedData.ceIrq = data.ceIrq; - packedData.regUpdateIrq = data.regUpdateIrq; - packedData.resetAckIrq = data.resetAckIrq; - packedData.encYPingpongIrq = data.encYPingpongIrq; - packedData.encCbcrPingpongIrq = data.encCbcrPingpongIrq; - packedData.viewYPingpongIrq = data.viewYPingpongIrq; - packedData.viewCbcrPingpongIrq = data.viewCbcrPingpongIrq; - packedData.rdPingpongIrq = data.rdPingpongIrq; - packedData.afPingpongIrq = data.afPingpongIrq; - packedData.awbPingpongIrq = data.awbPingpongIrq; - packedData.histPingpongIrq = data.histPingpongIrq; - packedData.encIrq = data.encIrq; - packedData.viewIrq = data.viewIrq; - packedData.busOverflowIrq = data.busOverflowIrq; - packedData.afOverflowIrq = data.afOverflowIrq; - packedData.awbOverflowIrq = data.awbOverflowIrq; - packedData.syncTimer0Irq = data.syncTimer0Irq; - packedData.syncTimer1Irq = data.syncTimer1Irq; - packedData.syncTimer2Irq = data.syncTimer2Irq; - packedData.asyncTimer0Irq = data.asyncTimer0Irq; - packedData.asyncTimer1Irq = data.asyncTimer1Irq; - packedData.asyncTimer2Irq = data.asyncTimer2Irq; - packedData.asyncTimer3Irq = data.asyncTimer3Irq; - packedData.axiErrorIrq = data.axiErrorIrq; - packedData.violationIrq = data.violationIrq; - - return *((uint32_t *)&packedData); -} - -static uint32_t -vfe_irq_composite_pack(struct vfe_irq_composite_mask_config data) -{ - struct VFE_Irq_Composite_MaskType packedData; - - memset(&packedData, 0, sizeof(packedData)); - - packedData.encIrqComMaskBits = data.encIrqComMask; - packedData.viewIrqComMaskBits = data.viewIrqComMask; - packedData.ceDoneSelBits = data.ceDoneSel; - - return *((uint32_t *)&packedData); -} - -static void vfe_addr_convert(struct msm_vfe_phy_info *pinfo, - enum vfe_resp_msg type, void *data, void **ext, int32_t *elen) -{ - switch (type) { - case VFE_MSG_OUTPUT1: { - pinfo->y_phy = - ((struct vfe_message *)data)->_u.msgOutput1.yBuffer; - pinfo->cbcr_phy = - ((struct vfe_message *)data)->_u.msgOutput1.cbcrBuffer; - - ((struct vfe_frame_extra *)ctrl->extdata)->bpcInfo = - ((struct vfe_message *)data)->_u.msgOutput1.bpcInfo; - - ((struct vfe_frame_extra *)ctrl->extdata)->asfInfo = - ((struct vfe_message *)data)->_u.msgOutput1.asfInfo; - - ((struct vfe_frame_extra *)ctrl->extdata)->frameCounter = - ((struct vfe_message *)data)->_u.msgOutput1.frameCounter; - - ((struct vfe_frame_extra *)ctrl->extdata)->pmData = - ((struct vfe_message *)data)->_u.msgOutput1.pmData; - - *ext = ctrl->extdata; - *elen = ctrl->extlen; - } - break; - - case VFE_MSG_OUTPUT2: { - pinfo->y_phy = - ((struct vfe_message *)data)->_u.msgOutput2.yBuffer; - pinfo->cbcr_phy = - ((struct vfe_message *)data)->_u.msgOutput2.cbcrBuffer; - - CDBG("vfe_addr_convert, pinfo->y_phy = 0x%x\n", pinfo->y_phy); - CDBG("vfe_addr_convert, pinfo->cbcr_phy = 0x%x\n", - pinfo->cbcr_phy); - - ((struct vfe_frame_extra *)ctrl->extdata)->bpcInfo = - ((struct vfe_message *)data)->_u.msgOutput2.bpcInfo; - - ((struct vfe_frame_extra *)ctrl->extdata)->asfInfo = - ((struct vfe_message *)data)->_u.msgOutput2.asfInfo; - - ((struct vfe_frame_extra *)ctrl->extdata)->frameCounter = - ((struct vfe_message *)data)->_u.msgOutput2.frameCounter; - - ((struct vfe_frame_extra *)ctrl->extdata)->pmData = - ((struct vfe_message *)data)->_u.msgOutput2.pmData; - - *ext = ctrl->extdata; - *elen = ctrl->extlen; - } - break; - - case VFE_MSG_STATS_AF: - pinfo->sbuf_phy = - ((struct vfe_message *)data)->_u.msgStatsAf.afBuffer; - break; - - case VFE_MSG_STATS_WE: - pinfo->sbuf_phy = - ((struct vfe_message *)data)->_u.msgStatsWbExp.awbBuffer; - break; - - default: - break; - } /* switch */ -} - -static void -vfe_proc_ops(enum VFE_MESSAGE_ID id, void *msg, size_t len) -{ - struct msm_vfe_resp *rp; - - /* In 8k, OUTPUT1 & OUTPUT2 messages arrive before - * SNAPSHOT_DONE. We don't send such messages to user */ - - CDBG("ctrl->vfeOperationMode = %d, msgId = %d\n", - ctrl->vfeOperationMode, id); - - if ((ctrl->vfeOperationMode == VFE_START_OPERATION_MODE_SNAPSHOT) && - (id == VFE_MSG_ID_OUTPUT1 || id == VFE_MSG_ID_OUTPUT2)) { - return; - } - - rp = ctrl->resp->vfe_alloc(sizeof(struct msm_vfe_resp), ctrl->syncdata); - if (!rp) { - CDBG("rp: cannot allocate buffer\n"); - return; - } - - CDBG("vfe_proc_ops, msgId = %d\n", id); - - rp->evt_msg.type = MSM_CAMERA_MSG; - rp->evt_msg.msg_id = id; - rp->evt_msg.len = len; - rp->evt_msg.data = msg; - - switch (rp->evt_msg.msg_id) { - case VFE_MSG_ID_SNAPSHOT_DONE: - rp->type = VFE_MSG_SNAPSHOT; - break; - - case VFE_MSG_ID_OUTPUT1: - rp->type = VFE_MSG_OUTPUT1; - vfe_addr_convert(&(rp->phy), VFE_MSG_OUTPUT1, - rp->evt_msg.data, &(rp->extdata), - &(rp->extlen)); - break; - - case VFE_MSG_ID_OUTPUT2: - rp->type = VFE_MSG_OUTPUT2; - vfe_addr_convert(&(rp->phy), VFE_MSG_OUTPUT2, - rp->evt_msg.data, &(rp->extdata), - &(rp->extlen)); - break; - - case VFE_MSG_ID_STATS_AUTOFOCUS: - rp->type = VFE_MSG_STATS_AF; - vfe_addr_convert(&(rp->phy), VFE_MSG_STATS_AF, - rp->evt_msg.data, NULL, NULL); - break; - - case VFE_MSG_ID_STATS_WB_EXP: - rp->type = VFE_MSG_STATS_WE; - vfe_addr_convert(&(rp->phy), VFE_MSG_STATS_WE, - rp->evt_msg.data, NULL, NULL); - break; - - default: - rp->type = VFE_MSG_GENERAL; - break; - } - - ctrl->resp->vfe_resp(rp, MSM_CAM_Q_VFE_MSG, ctrl->syncdata); -} - -static void vfe_send_msg_no_payload(enum VFE_MESSAGE_ID id) -{ - struct vfe_message *msg; - - msg = kzalloc(sizeof(*msg), GFP_ATOMIC); - if (!msg) - return; - - msg->_d = id; - vfe_proc_ops(id, msg, 0); -} - -static void vfe_send_bus_overflow_msg(void) -{ - struct vfe_message *msg; - msg = - kzalloc(sizeof(struct vfe_message), GFP_ATOMIC); - if (!msg) - return; - - msg->_d = VFE_MSG_ID_BUS_OVERFLOW; -#if 0 - memcpy(&(msg->_u.msgBusOverflow), - &ctrl->vfePmData, sizeof(ctrl->vfePmData)); -#endif - - vfe_proc_ops(VFE_MSG_ID_BUS_OVERFLOW, - msg, sizeof(struct vfe_message)); -} - -static void vfe_send_camif_error_msg(void) -{ -#if 0 - struct vfe_message *msg; - msg = - kzalloc(sizeof(struct vfe_message), GFP_ATOMIC); - if (!msg) - return; - - msg->_d = VFE_MSG_ID_CAMIF_ERROR; - memcpy(&(msg->_u.msgCamifError), - &ctrl->vfeCamifStatusLocal, sizeof(ctrl->vfeCamifStatusLocal)); - - vfe_proc_ops(VFE_MSG_ID_CAMIF_ERROR, - msg, sizeof(struct vfe_message)); -#endif -} - -static void vfe_process_error_irq( - struct vfe_interrupt_status *irqstatus) -{ - /* all possible error irq. Note error irqs are not enabled, it is - * checked only when other interrupts are present. */ - if (irqstatus->afOverflowIrq) - vfe_send_msg_no_payload(VFE_MSG_ID_AF_OVERFLOW); - - if (irqstatus->awbOverflowIrq) - vfe_send_msg_no_payload(VFE_MSG_ID_AWB_OVERFLOW); - - if (irqstatus->axiErrorIrq) - vfe_send_msg_no_payload(VFE_MSG_ID_AXI_ERROR); - - if (irqstatus->busOverflowIrq) - vfe_send_bus_overflow_msg(); - - if (irqstatus->camifErrorIrq) - vfe_send_camif_error_msg(); - - if (irqstatus->camifOverflowIrq) - vfe_send_msg_no_payload(VFE_MSG_ID_CAMIF_OVERFLOW); - - if (irqstatus->violationIrq) - ; -} - -static void vfe_process_camif_sof_irq(void) -{ - /* increment the frame id number. */ - ctrl->vfeFrameId++; - - CDBG("camif_sof_irq, frameId = %d\n", - ctrl->vfeFrameId); - - /* In snapshot mode, if frame skip is programmed, - * need to check it accordingly to stop camif at - * correct frame boundary. For the dropped frames, - * there won't be any output path irqs, but there is - * still SOF irq, which can help us determine when - * to stop the camif. - */ - if (ctrl->vfeOperationMode) { - if ((1 << ctrl->vfeFrameSkipCount) & - ctrl->vfeFrameSkipPattern) { - - ctrl->vfeSnapShotCount--; - if (ctrl->vfeSnapShotCount == 0) - /* terminate vfe pipeline at frame boundary. */ - writel(CAMIF_COMMAND_STOP_AT_FRAME_BOUNDARY, - ctrl->vfebase + CAMIF_COMMAND); - } - - /* update frame skip counter for bit checking. */ - ctrl->vfeFrameSkipCount++; - if (ctrl->vfeFrameSkipCount == - (ctrl->vfeFrameSkipPeriod + 1)) - ctrl->vfeFrameSkipCount = 0; - } -} - -static int vfe_get_af_pingpong_status(void) -{ - uint32_t busPingPongStatus; - int rc = 0; - - busPingPongStatus = - readl(ctrl->vfebase + VFE_BUS_PINGPONG_STATUS); - - if ((busPingPongStatus & VFE_AF_PINGPONG_STATUS_BIT) == 0) - return -EFAULT; - - return rc; -} - -static uint32_t vfe_read_af_buf_addr(boolean pipo) -{ - if (pipo == FALSE) - return readl(ctrl->vfebase + VFE_BUS_STATS_AF_WR_PING_ADDR); - else - return readl(ctrl->vfebase + VFE_BUS_STATS_AF_WR_PONG_ADDR); -} - -static void -vfe_update_af_buf_addr(boolean pipo, uint32_t addr) -{ - if (pipo == FALSE) - writel(addr, ctrl->vfebase + VFE_BUS_STATS_AF_WR_PING_ADDR); - else - writel(addr, ctrl->vfebase + VFE_BUS_STATS_AF_WR_PONG_ADDR); -} - -static void -vfe_send_af_stats_msg(uint32_t afBufAddress) -{ - /* unsigned long flags; */ - struct vfe_message *msg; - msg = - kzalloc(sizeof(struct vfe_message), GFP_ATOMIC); - if (!msg) - return; - - /* fill message with right content. */ - /* @todo This is causing issues, need further investigate */ - /* spin_lock_irqsave(&ctrl->state_lock, flags); */ - if (ctrl->vstate != VFE_STATE_ACTIVE) { - kfree(msg); - goto af_stats_done; - } - - msg->_d = VFE_MSG_ID_STATS_AUTOFOCUS; - msg->_u.msgStatsAf.afBuffer = afBufAddress; - msg->_u.msgStatsAf.frameCounter = ctrl->vfeFrameId; - - vfe_proc_ops(VFE_MSG_ID_STATS_AUTOFOCUS, - msg, sizeof(struct vfe_message)); - - ctrl->afStatsControl.ackPending = TRUE; - -af_stats_done: - /* spin_unlock_irqrestore(&ctrl->state_lock, flags); */ - return; -} - -static void vfe_process_stats_af_irq(void) -{ - boolean bufferAvailable; - - if (!(ctrl->afStatsControl.ackPending)) { - - /* read hardware status. */ - ctrl->afStatsControl.pingPongStatus = - vfe_get_af_pingpong_status(); - - bufferAvailable = - (ctrl->afStatsControl.pingPongStatus) ^ 1; - - ctrl->afStatsControl.bufToRender = - vfe_read_af_buf_addr(bufferAvailable); - - /* update the same buffer address (ping or pong) */ - vfe_update_af_buf_addr(bufferAvailable, - ctrl->afStatsControl.nextFrameAddrBuf); - - vfe_send_af_stats_msg(ctrl->afStatsControl.bufToRender); - } else - ctrl->afStatsControl.droppedStatsFrameCount++; -} - -static boolean vfe_get_awb_pingpong_status(void) -{ - uint32_t busPingPongStatus; - - busPingPongStatus = - readl(ctrl->vfebase + VFE_BUS_PINGPONG_STATUS); - - if ((busPingPongStatus & VFE_AWB_PINGPONG_STATUS_BIT) == 0) - return FALSE; - - return TRUE; -} - -static uint32_t -vfe_read_awb_buf_addr(boolean pingpong) -{ - if (pingpong == FALSE) - return readl(ctrl->vfebase + VFE_BUS_STATS_AWB_WR_PING_ADDR); - else - return readl(ctrl->vfebase + VFE_BUS_STATS_AWB_WR_PONG_ADDR); -} - -static void vfe_update_awb_buf_addr( - boolean pingpong, uint32_t addr) -{ - if (pingpong == FALSE) - writel(addr, ctrl->vfebase + VFE_BUS_STATS_AWB_WR_PING_ADDR); - else - writel(addr, ctrl->vfebase + VFE_BUS_STATS_AWB_WR_PONG_ADDR); -} - -static void vfe_send_awb_stats_msg(uint32_t awbBufAddress) -{ - /* unsigned long flags; */ - struct vfe_message *msg; - - msg = - kzalloc(sizeof(struct vfe_message), GFP_ATOMIC); - if (!msg) - return; - - /* fill message with right content. */ - /* @todo This is causing issues, need further investigate */ - /* spin_lock_irqsave(&ctrl->state_lock, flags); */ - if (ctrl->vstate != VFE_STATE_ACTIVE) { - kfree(msg); - goto awb_stats_done; - } - - msg->_d = VFE_MSG_ID_STATS_WB_EXP; - msg->_u.msgStatsWbExp.awbBuffer = awbBufAddress; - msg->_u.msgStatsWbExp.frameCounter = ctrl->vfeFrameId; - - vfe_proc_ops(VFE_MSG_ID_STATS_WB_EXP, - msg, sizeof(struct vfe_message)); - - ctrl->awbStatsControl.ackPending = TRUE; - -awb_stats_done: - /* spin_unlock_irqrestore(&ctrl->state_lock, flags); */ - return; -} - -static void vfe_process_stats_awb_irq(void) -{ - boolean bufferAvailable; - - if (!(ctrl->awbStatsControl.ackPending)) { - - ctrl->awbStatsControl.pingPongStatus = - vfe_get_awb_pingpong_status(); - - bufferAvailable = (ctrl->awbStatsControl.pingPongStatus) ^ 1; - - ctrl->awbStatsControl.bufToRender = - vfe_read_awb_buf_addr(bufferAvailable); - - vfe_update_awb_buf_addr(bufferAvailable, - ctrl->awbStatsControl.nextFrameAddrBuf); - - vfe_send_awb_stats_msg(ctrl->awbStatsControl.bufToRender); - - } else - ctrl->awbStatsControl.droppedStatsFrameCount++; -} - -static void vfe_process_sync_timer_irq( - struct vfe_interrupt_status *irqstatus) -{ - if (irqstatus->syncTimer0Irq) - vfe_send_msg_no_payload(VFE_MSG_ID_SYNC_TIMER0_DONE); - - if (irqstatus->syncTimer1Irq) - vfe_send_msg_no_payload(VFE_MSG_ID_SYNC_TIMER1_DONE); - - if (irqstatus->syncTimer2Irq) - vfe_send_msg_no_payload(VFE_MSG_ID_SYNC_TIMER2_DONE); -} - -static void vfe_process_async_timer_irq( - struct vfe_interrupt_status *irqstatus) -{ - - if (irqstatus->asyncTimer0Irq) - vfe_send_msg_no_payload(VFE_MSG_ID_ASYNC_TIMER0_DONE); - - if (irqstatus->asyncTimer1Irq) - vfe_send_msg_no_payload(VFE_MSG_ID_ASYNC_TIMER1_DONE); - - if (irqstatus->asyncTimer2Irq) - vfe_send_msg_no_payload(VFE_MSG_ID_ASYNC_TIMER2_DONE); - - if (irqstatus->asyncTimer3Irq) - vfe_send_msg_no_payload(VFE_MSG_ID_ASYNC_TIMER3_DONE); -} - -static void vfe_send_violation_msg(void) -{ - vfe_send_msg_no_payload(VFE_MSG_ID_VIOLATION); -} - -static void vfe_send_async_timer_msg(void) -{ - vfe_send_msg_no_payload(VFE_MSG_ID_ASYNC_TIMER0_DONE); -} - -static void vfe_write_gamma_table(uint8_t channel, - boolean bank, int16_t *pTable) -{ - uint16_t i; - - enum VFE_DMI_RAM_SEL dmiRamSel = NO_MEM_SELECTED; - - switch (channel) { - case 0: - if (bank == 0) - dmiRamSel = RGBLUT_RAM_CH0_BANK0; - else - dmiRamSel = RGBLUT_RAM_CH0_BANK1; - break; - - case 1: - if (bank == 0) - dmiRamSel = RGBLUT_RAM_CH1_BANK0; - else - dmiRamSel = RGBLUT_RAM_CH1_BANK1; - break; - - case 2: - if (bank == 0) - dmiRamSel = RGBLUT_RAM_CH2_BANK0; - else - dmiRamSel = RGBLUT_RAM_CH2_BANK1; - break; - - default: - break; - } - - vfe_program_dmi_cfg(dmiRamSel); - - for (i = 0; i < VFE_GAMMA_TABLE_LENGTH; i++) { - writel((uint32_t)(*pTable), ctrl->vfebase + VFE_DMI_DATA_LO); - pTable++; - } - - /* After DMI transfer, need to set the DMI_CFG to unselect any SRAM - unselect the SRAM Bank. */ - writel(VFE_DMI_CFG_DEFAULT, ctrl->vfebase + VFE_DMI_CFG); -} - -static void vfe_prog_hw_testgen_cmd(uint32_t value) -{ - writel(value, ctrl->vfebase + VFE_HW_TESTGEN_CMD); -} - -static inline void vfe_read_irq_status(struct vfe_irq_thread_msg *out) -{ - uint32_t *temp; - - memset(out, 0, sizeof(struct vfe_irq_thread_msg)); - - temp = (uint32_t *)(ctrl->vfebase + VFE_IRQ_STATUS); - out->vfeIrqStatus = readl(temp); - - temp = (uint32_t *)(ctrl->vfebase + CAMIF_STATUS); - out->camifStatus = readl(temp); - writel(0x7, ctrl->vfebase + CAMIF_COMMAND); - writel(0x3, ctrl->vfebase + CAMIF_COMMAND); - CDBG("camifStatus = 0x%x\n", out->camifStatus); - -/* - temp = (uint32_t *)(ctrl->vfebase + VFE_DEMOSAIC_STATUS); - out->demosaicStatus = readl(temp); - - temp = (uint32_t *)(ctrl->vfebase + VFE_ASF_MAX_EDGE); - out->asfMaxEdge = readl(temp); - - temp = (uint32_t *)(ctrl->vfebase + VFE_BUS_ENC_Y_WR_PM_STATS_0); -*/ - -#if 0 - out->pmInfo.encPathPmInfo.yWrPmStats0 = readl(temp++); - out->pmInfo.encPathPmInfo.yWrPmStats1 = readl(temp++); - out->pmInfo.encPathPmInfo.cbcrWrPmStats0 = readl(temp++); - out->pmInfo.encPathPmInfo.cbcrWrPmStats1 = readl(temp++); - out->pmInfo.viewPathPmInfo.yWrPmStats0 = readl(temp++); - out->pmInfo.viewPathPmInfo.yWrPmStats1 = readl(temp++); - out->pmInfo.viewPathPmInfo.cbcrWrPmStats0 = readl(temp++); - out->pmInfo.viewPathPmInfo.cbcrWrPmStats1 = readl(temp); -#endif /* if 0 Jeff */ -} - -static struct vfe_interrupt_status -vfe_parse_interrupt_status(uint32_t irqStatusIn) -{ - struct vfe_irqenable hwstat; - struct vfe_interrupt_status ret; - boolean temp; - - memset(&hwstat, 0, sizeof(hwstat)); - memset(&ret, 0, sizeof(ret)); - - hwstat = *((struct vfe_irqenable *)(&irqStatusIn)); - - ret.camifErrorIrq = hwstat.camifErrorIrq; - ret.camifSofIrq = hwstat.camifSofIrq; - ret.camifEolIrq = hwstat.camifEolIrq; - ret.camifEofIrq = hwstat.camifEofIrq; - ret.camifEpoch1Irq = hwstat.camifEpoch1Irq; - ret.camifEpoch2Irq = hwstat.camifEpoch2Irq; - ret.camifOverflowIrq = hwstat.camifOverflowIrq; - ret.ceIrq = hwstat.ceIrq; - ret.regUpdateIrq = hwstat.regUpdateIrq; - ret.resetAckIrq = hwstat.resetAckIrq; - ret.encYPingpongIrq = hwstat.encYPingpongIrq; - ret.encCbcrPingpongIrq = hwstat.encCbcrPingpongIrq; - ret.viewYPingpongIrq = hwstat.viewYPingpongIrq; - ret.viewCbcrPingpongIrq = hwstat.viewCbcrPingpongIrq; - ret.rdPingpongIrq = hwstat.rdPingpongIrq; - ret.afPingpongIrq = hwstat.afPingpongIrq; - ret.awbPingpongIrq = hwstat.awbPingpongIrq; - ret.histPingpongIrq = hwstat.histPingpongIrq; - ret.encIrq = hwstat.encIrq; - ret.viewIrq = hwstat.viewIrq; - ret.busOverflowIrq = hwstat.busOverflowIrq; - ret.afOverflowIrq = hwstat.afOverflowIrq; - ret.awbOverflowIrq = hwstat.awbOverflowIrq; - ret.syncTimer0Irq = hwstat.syncTimer0Irq; - ret.syncTimer1Irq = hwstat.syncTimer1Irq; - ret.syncTimer2Irq = hwstat.syncTimer2Irq; - ret.asyncTimer0Irq = hwstat.asyncTimer0Irq; - ret.asyncTimer1Irq = hwstat.asyncTimer1Irq; - ret.asyncTimer2Irq = hwstat.asyncTimer2Irq; - ret.asyncTimer3Irq = hwstat.asyncTimer3Irq; - ret.axiErrorIrq = hwstat.axiErrorIrq; - ret.violationIrq = hwstat.violationIrq; - - /* logic OR of any error bits - * although each irq corresponds to a bit, the data type here is a - * boolean already. hence use logic operation. - */ - temp = - ret.camifErrorIrq || - ret.camifOverflowIrq || - ret.afOverflowIrq || - ret.awbPingpongIrq || - ret.busOverflowIrq || - ret.axiErrorIrq || - ret.violationIrq; - - ret.anyErrorIrqs = temp; - - /* logic OR of any output path bits*/ - temp = - ret.encYPingpongIrq || - ret.encCbcrPingpongIrq || - ret.encIrq; - - ret.anyOutput2PathIrqs = temp; - - temp = - ret.viewYPingpongIrq || - ret.viewCbcrPingpongIrq || - ret.viewIrq; - - ret.anyOutput1PathIrqs = temp; - - ret.anyOutputPathIrqs = - ret.anyOutput1PathIrqs || - ret.anyOutput2PathIrqs; - - /* logic OR of any sync timer bits*/ - temp = - ret.syncTimer0Irq || - ret.syncTimer1Irq || - ret.syncTimer2Irq; - - ret.anySyncTimerIrqs = temp; - - /* logic OR of any async timer bits*/ - temp = - ret.asyncTimer0Irq || - ret.asyncTimer1Irq || - ret.asyncTimer2Irq || - ret.asyncTimer3Irq; - - ret.anyAsyncTimerIrqs = temp; - - /* bool for all interrupts that are not allowed in idle state */ - temp = - ret.anyErrorIrqs || - ret.anyOutputPathIrqs || - ret.anySyncTimerIrqs || - ret.regUpdateIrq || - ret.awbPingpongIrq || - ret.afPingpongIrq || - ret.camifSofIrq || - ret.camifEpoch2Irq || - ret.camifEpoch1Irq; - - ret.anyIrqForActiveStatesOnly = - temp; - - return ret; -} - -static struct vfe_frame_asf_info -vfe_get_asf_frame_info(struct vfe_irq_thread_msg *in) -{ - struct vfe_asf_info asfInfoTemp; - struct vfe_frame_asf_info rc; - - memset(&rc, 0, sizeof(rc)); - memset(&asfInfoTemp, 0, sizeof(asfInfoTemp)); - - asfInfoTemp = - *((struct vfe_asf_info *)(&(in->asfMaxEdge))); - - rc.asfHbiCount = asfInfoTemp.HBICount; - rc.asfMaxEdge = asfInfoTemp.maxEdge; - - return rc; -} - -static struct vfe_frame_bpc_info -vfe_get_demosaic_frame_info(struct vfe_irq_thread_msg *in) -{ - struct vfe_bps_info bpcInfoTemp; - struct vfe_frame_bpc_info rc; - - memset(&rc, 0, sizeof(rc)); - memset(&bpcInfoTemp, 0, sizeof(bpcInfoTemp)); - - bpcInfoTemp = - *((struct vfe_bps_info *)(&(in->demosaicStatus))); - - rc.greenDefectPixelCount = - bpcInfoTemp.greenBadPixelCount; - - rc.redBlueDefectPixelCount = - bpcInfoTemp.RedBlueBadPixelCount; - - return rc; -} - -static struct vfe_msg_camif_status -vfe_get_camif_status(struct vfe_irq_thread_msg *in) -{ - struct vfe_camif_stats camifStatusTemp; - struct vfe_msg_camif_status rc; - - memset(&rc, 0, sizeof(rc)); - memset(&camifStatusTemp, 0, sizeof(camifStatusTemp)); - - camifStatusTemp = - *((struct vfe_camif_stats *)(&(in->camifStatus))); - - rc.camifState = (boolean)camifStatusTemp.camifHalt; - rc.lineCount = camifStatusTemp.lineCount; - rc.pixelCount = camifStatusTemp.pixelCount; - - return rc; -} - -static struct vfe_bus_performance_monitor -vfe_get_performance_monitor_data(struct vfe_irq_thread_msg *in) -{ - struct vfe_bus_performance_monitor rc; - memset(&rc, 0, sizeof(rc)); - - rc.encPathPmInfo.yWrPmStats0 = - in->pmInfo.encPathPmInfo.yWrPmStats0; - rc.encPathPmInfo.yWrPmStats1 = - in->pmInfo.encPathPmInfo.yWrPmStats1; - rc.encPathPmInfo.cbcrWrPmStats0 = - in->pmInfo.encPathPmInfo.cbcrWrPmStats0; - rc.encPathPmInfo.cbcrWrPmStats1 = - in->pmInfo.encPathPmInfo.cbcrWrPmStats1; - rc.viewPathPmInfo.yWrPmStats0 = - in->pmInfo.viewPathPmInfo.yWrPmStats0; - rc.viewPathPmInfo.yWrPmStats1 = - in->pmInfo.viewPathPmInfo.yWrPmStats1; - rc.viewPathPmInfo.cbcrWrPmStats0 = - in->pmInfo.viewPathPmInfo.cbcrWrPmStats0; - rc.viewPathPmInfo.cbcrWrPmStats1 = - in->pmInfo.viewPathPmInfo.cbcrWrPmStats1; - - return rc; -} - -static void vfe_process_reg_update_irq(void) -{ - CDBG("vfe_process_reg_update_irq: ackPendingFlag is %d\n", - ctrl->vfeStartAckPendingFlag); - if (ctrl->vfeStartAckPendingFlag == TRUE) { - vfe_send_msg_no_payload(VFE_MSG_ID_START_ACK); - ctrl->vfeStartAckPendingFlag = FALSE; - } else - vfe_send_msg_no_payload(VFE_MSG_ID_UPDATE_ACK); -} - -static void vfe_process_reset_irq(void) -{ - /* unsigned long flags; */ - - /* @todo This is causing issues, need further investigate */ - /* spin_lock_irqsave(&ctrl->state_lock, flags); */ - ctrl->vstate = VFE_STATE_IDLE; - /* spin_unlock_irqrestore(&ctrl->state_lock, flags); */ - - if (ctrl->vfeStopAckPending == TRUE) { - ctrl->vfeStopAckPending = FALSE; - vfe_send_msg_no_payload(VFE_MSG_ID_STOP_ACK); - } else { - vfe_set_default_reg_values(); - vfe_send_msg_no_payload(VFE_MSG_ID_RESET_ACK); - } -} - -static void vfe_process_pingpong_irq(struct vfe_output_path *in, - uint8_t fragmentCount) -{ - uint16_t circularIndex; - uint32_t nextFragmentAddr; - - /* get next fragment address from circular buffer */ - circularIndex = (in->fragIndex) % (2 * fragmentCount); - nextFragmentAddr = in->addressBuffer[circularIndex]; - - in->fragIndex = circularIndex + 1; - - /* use next fragment to program hardware ping/pong address. */ - if (in->hwCurrentFlag == ping) { - writel(nextFragmentAddr, in->hwRegPingAddress); - in->hwCurrentFlag = pong; - - } else { - writel(nextFragmentAddr, in->hwRegPongAddress); - in->hwCurrentFlag = ping; - } -} - -static void vfe_send_output2_msg( - struct vfe_msg_output *pPayload) -{ - /* unsigned long flags; */ - struct vfe_message *msg; - - msg = kzalloc(sizeof(struct vfe_message), GFP_ATOMIC); - if (!msg) - return; - - /* fill message with right content. */ - /* @todo This is causing issues, need further investigate */ - /* spin_lock_irqsave(&ctrl->state_lock, flags); */ - if (ctrl->vstate != VFE_STATE_ACTIVE) { - kfree(msg); - goto output2_msg_done; - } - - msg->_d = VFE_MSG_ID_OUTPUT2; - - memcpy(&(msg->_u.msgOutput2), - (void *)pPayload, sizeof(struct vfe_msg_output)); - - vfe_proc_ops(VFE_MSG_ID_OUTPUT2, - msg, sizeof(struct vfe_message)); - - ctrl->encPath.ackPending = TRUE; - - if (!(ctrl->vfeRequestedSnapShotCount <= 3) && - (ctrl->vfeOperationMode == - VFE_START_OPERATION_MODE_SNAPSHOT)) - ctrl->encPath.ackPending = TRUE; - -output2_msg_done: - /* spin_unlock_irqrestore(&ctrl->state_lock, flags); */ - return; -} - -static void vfe_send_output1_msg( - struct vfe_msg_output *pPayload) -{ - /* unsigned long flags; */ - struct vfe_message *msg; - - msg = kzalloc(sizeof(struct vfe_message), GFP_ATOMIC); - if (!msg) - return; - - /* @todo This is causing issues, need further investigate */ - /* spin_lock_irqsave(&ctrl->state_lock, flags); */ - if (ctrl->vstate != VFE_STATE_ACTIVE) { - kfree(msg); - goto output1_msg_done; - } - - msg->_d = VFE_MSG_ID_OUTPUT1; - memmove(&(msg->_u), - (void *)pPayload, sizeof(struct vfe_msg_output)); - - vfe_proc_ops(VFE_MSG_ID_OUTPUT1, - msg, sizeof(struct vfe_message)); - - ctrl->viewPath.ackPending = TRUE; - - if (!(ctrl->vfeRequestedSnapShotCount <= 3) && - (ctrl->vfeOperationMode == - VFE_START_OPERATION_MODE_SNAPSHOT)) - ctrl->viewPath.ackPending = TRUE; - -output1_msg_done: - /* spin_unlock_irqrestore(&ctrl->state_lock, flags); */ - return; -} - -static void vfe_send_output_msg(boolean whichOutputPath, - uint32_t yPathAddr, uint32_t cbcrPathAddr) -{ - struct vfe_msg_output msgPayload; - - msgPayload.yBuffer = yPathAddr; - msgPayload.cbcrBuffer = cbcrPathAddr; - - /* asf info is common for both output1 and output2 */ -#if 0 - msgPayload.asfInfo.asfHbiCount = ctrl->vfeAsfFrameInfo.asfHbiCount; - msgPayload.asfInfo.asfMaxEdge = ctrl->vfeAsfFrameInfo.asfMaxEdge; - - /* demosaic info is common for both output1 and output2 */ - msgPayload.bpcInfo.greenDefectPixelCount = - ctrl->vfeBpcFrameInfo.greenDefectPixelCount; - msgPayload.bpcInfo.redBlueDefectPixelCount = - ctrl->vfeBpcFrameInfo.redBlueDefectPixelCount; -#endif /* if 0 */ - - /* frame ID is common for both paths. */ - msgPayload.frameCounter = ctrl->vfeFrameId; - - if (whichOutputPath) { - /* msgPayload.pmData = ctrl->vfePmData.encPathPmInfo; */ - vfe_send_output2_msg(&msgPayload); - } else { - /* msgPayload.pmData = ctrl->vfePmData.viewPathPmInfo; */ - vfe_send_output1_msg(&msgPayload); - } -} - -static void vfe_process_frame_done_irq_multi_frag( - struct vfe_output_path_combo *in) -{ - uint32_t yAddress, cbcrAddress; - uint16_t idx; - uint32_t *ptrY; - uint32_t *ptrCbcr; - const uint32_t *ptrSrc; - uint8_t i; - - if (!in->ackPending) { - - idx = (in->currentFrame) * (in->fragCount); - - /* Send output message. */ - yAddress = in->yPath.addressBuffer[idx]; - cbcrAddress = in->cbcrPath.addressBuffer[idx]; - - /* copy next frame to current frame. */ - ptrSrc = in->nextFrameAddrBuf; - ptrY = (uint32_t *)&(in->yPath.addressBuffer[idx]); - ptrCbcr = (uint32_t *)&(in->cbcrPath.addressBuffer[idx]); - - /* Copy Y address */ - for (i = 0; i < in->fragCount; i++) - *ptrY++ = *ptrSrc++; - - /* Copy Cbcr address */ - for (i = 0; i < in->fragCount; i++) - *ptrCbcr++ = *ptrSrc++; - - vfe_send_output_msg(in->whichOutputPath, yAddress, cbcrAddress); - - } else { - if (in->whichOutputPath == 0) - ctrl->vfeDroppedFrameCounts.output1Count++; - - if (in->whichOutputPath == 1) - ctrl->vfeDroppedFrameCounts.output2Count++; - } - - /* toggle current frame. */ - in->currentFrame = in->currentFrame^1; - - if (ctrl->vfeOperationMode) - in->snapshotPendingCount--; -} - -static void vfe_process_frame_done_irq_no_frag_io( - struct vfe_output_path_combo *in, uint32_t *pNextAddr, - uint32_t *pdestRenderAddr) -{ - uint32_t busPingPongStatus; - uint32_t tempAddress; - - /* 1. read hw status register. */ - busPingPongStatus = - readl(ctrl->vfebase + VFE_BUS_PINGPONG_STATUS); - - CDBG("hardware status is 0x%x\n", busPingPongStatus); - - /* 2. determine ping or pong */ - /* use cbcr status */ - busPingPongStatus = busPingPongStatus & (1<<(in->cbcrStatusBit)); - - /* 3. read out address and update address */ - if (busPingPongStatus == 0) { - /* hw is working on ping, render pong buffer */ - /* a. read out pong address */ - /* read out y address. */ - tempAddress = readl(in->yPath.hwRegPongAddress); - - CDBG("pong 1 addr = 0x%x\n", tempAddress); - *pdestRenderAddr++ = tempAddress; - /* read out cbcr address. */ - tempAddress = readl(in->cbcrPath.hwRegPongAddress); - - CDBG("pong 2 addr = 0x%x\n", tempAddress); - *pdestRenderAddr = tempAddress; - - /* b. update pong address */ - writel(*pNextAddr++, in->yPath.hwRegPongAddress); - writel(*pNextAddr, in->cbcrPath.hwRegPongAddress); - } else { - /* hw is working on pong, render ping buffer */ - - /* a. read out ping address */ - tempAddress = readl(in->yPath.hwRegPingAddress); - CDBG("ping 1 addr = 0x%x\n", tempAddress); - *pdestRenderAddr++ = tempAddress; - tempAddress = readl(in->cbcrPath.hwRegPingAddress); - - CDBG("ping 2 addr = 0x%x\n", tempAddress); - *pdestRenderAddr = tempAddress; - - /* b. update ping address */ - writel(*pNextAddr++, in->yPath.hwRegPingAddress); - CDBG("NextAddress = 0x%x\n", *pNextAddr); - writel(*pNextAddr, in->cbcrPath.hwRegPingAddress); - } -} - -static void vfe_process_frame_done_irq_no_frag( - struct vfe_output_path_combo *in) -{ - uint32_t addressToRender[2]; - static uint32_t fcnt; - - if (fcnt++ < 3) - return; - - if (!in->ackPending) { - vfe_process_frame_done_irq_no_frag_io(in, - in->nextFrameAddrBuf, addressToRender); - - /* use addressToRender to send out message. */ - vfe_send_output_msg(in->whichOutputPath, - addressToRender[0], addressToRender[1]); - - } else { - /* ackPending is still there, accumulate dropped frame count. - * These count can be read through ioctrl command. */ - CDBG("waiting frame ACK\n"); - - if (in->whichOutputPath == 0) - ctrl->vfeDroppedFrameCounts.output1Count++; - - if (in->whichOutputPath == 1) - ctrl->vfeDroppedFrameCounts.output2Count++; - } - - /* in case of multishot when upper layer did not ack, there will still - * be a snapshot done msg sent out, even though the number of frames - * sent out may be less than the desired number of frames. snapshot - * done msg would be helpful to indicate that vfe pipeline has stop, - * and in good known state. - */ - if (ctrl->vfeOperationMode) - in->snapshotPendingCount--; -} - -static void vfe_process_output_path_irq( - struct vfe_interrupt_status *irqstatus) -{ - /* unsigned long flags; */ - - /* process the view path interrupts */ - if (irqstatus->anyOutput1PathIrqs) { - if (ctrl->viewPath.multiFrag) { - - if (irqstatus->viewCbcrPingpongIrq) - vfe_process_pingpong_irq( - &(ctrl->viewPath.cbcrPath), - ctrl->viewPath.fragCount); - - if (irqstatus->viewYPingpongIrq) - vfe_process_pingpong_irq( - &(ctrl->viewPath.yPath), - ctrl->viewPath.fragCount); - - if (irqstatus->viewIrq) - vfe_process_frame_done_irq_multi_frag( - &ctrl->viewPath); - - } else { - /* typical case for no fragment, - only frame done irq is enabled. */ - if (irqstatus->viewIrq) - vfe_process_frame_done_irq_no_frag( - &ctrl->viewPath); - } - } - - /* process the encoder path interrupts */ - if (irqstatus->anyOutput2PathIrqs) { - if (ctrl->encPath.multiFrag) { - if (irqstatus->encCbcrPingpongIrq) - vfe_process_pingpong_irq( - &(ctrl->encPath.cbcrPath), - ctrl->encPath.fragCount); - - if (irqstatus->encYPingpongIrq) - vfe_process_pingpong_irq(&(ctrl->encPath.yPath), - ctrl->encPath.fragCount); - - if (irqstatus->encIrq) - vfe_process_frame_done_irq_multi_frag( - &ctrl->encPath); - - } else { - if (irqstatus->encIrq) - vfe_process_frame_done_irq_no_frag( - &ctrl->encPath); - } - } - - if (ctrl->vfeOperationMode) { - if ((ctrl->encPath.snapshotPendingCount == 0) && - (ctrl->viewPath.snapshotPendingCount == 0)) { - - /* @todo This is causing issues, further investigate */ - /* spin_lock_irqsave(&ctrl->state_lock, flags); */ - ctrl->vstate = VFE_STATE_IDLE; - /* spin_unlock_irqrestore(&ctrl->state_lock, flags); */ - - vfe_send_msg_no_payload(VFE_MSG_ID_SNAPSHOT_DONE); - vfe_prog_hw_testgen_cmd(VFE_TEST_GEN_STOP); - vfe_pm_stop(); - } - } -} - -static void vfe_do_tasklet(unsigned long data) -{ - unsigned long flags; - - struct isr_queue_cmd *qcmd = NULL; - - CDBG("=== vfe_do_tasklet start === \n"); - - spin_lock_irqsave(&ctrl->tasklet_lock, flags); - qcmd = list_first_entry(&ctrl->tasklet_q, - struct isr_queue_cmd, list); - - if (!qcmd) { - spin_unlock_irqrestore(&ctrl->tasklet_lock, flags); - return; - } - - list_del(&qcmd->list); - spin_unlock_irqrestore(&ctrl->tasklet_lock, flags); - - if (qcmd->vfeInterruptStatus.regUpdateIrq) { - CDBG("irq regUpdateIrq\n"); - vfe_process_reg_update_irq(); - } - - if (qcmd->vfeInterruptStatus.resetAckIrq) { - CDBG("irq resetAckIrq\n"); - vfe_process_reset_irq(); - } - - spin_lock_irqsave(&ctrl->state_lock, flags); - if (ctrl->vstate != VFE_STATE_ACTIVE) { - spin_unlock_irqrestore(&ctrl->state_lock, flags); - return; - } - spin_unlock_irqrestore(&ctrl->state_lock, flags); - -#if 0 - if (qcmd->vfeInterruptStatus.camifEpoch1Irq) - vfe_send_msg_no_payload(VFE_MSG_ID_EPOCH1); - - if (qcmd->vfeInterruptStatus.camifEpoch2Irq) - vfe_send_msg_no_payload(VFE_MSG_ID_EPOCH2); -#endif /* Jeff */ - - /* next, check output path related interrupts. */ - if (qcmd->vfeInterruptStatus.anyOutputPathIrqs) { - CDBG("irq anyOutputPathIrqs\n"); - vfe_process_output_path_irq(&qcmd->vfeInterruptStatus); - } - - if (qcmd->vfeInterruptStatus.afPingpongIrq) - vfe_process_stats_af_irq(); - - if (qcmd->vfeInterruptStatus.awbPingpongIrq) - vfe_process_stats_awb_irq(); - - /* any error irqs*/ - if (qcmd->vfeInterruptStatus.anyErrorIrqs) - vfe_process_error_irq(&qcmd->vfeInterruptStatus); - -#if 0 - if (qcmd->vfeInterruptStatus.anySyncTimerIrqs) - vfe_process_sync_timer_irq(); - - if (qcmd->vfeInterruptStatus.anyAsyncTimerIrqs) - vfe_process_async_timer_irq(); -#endif /* Jeff */ - - if (qcmd->vfeInterruptStatus.camifSofIrq) { - CDBG("irq camifSofIrq\n"); - vfe_process_camif_sof_irq(); - } - - kfree(qcmd); - CDBG("=== vfe_do_tasklet end === \n"); -} - -DECLARE_TASKLET(vfe_tasklet, vfe_do_tasklet, 0); - -static irqreturn_t vfe_parse_irq(int irq_num, void *data) -{ - unsigned long flags; - uint32_t irqStatusLocal; - struct vfe_irq_thread_msg irq; - struct isr_queue_cmd *qcmd; - - CDBG("vfe_parse_irq\n"); - - vfe_read_irq_status(&irq); - - if (irq.vfeIrqStatus == 0) { - CDBG("vfe_parse_irq: irq.vfeIrqStatus is 0\n"); - return IRQ_HANDLED; - } - - qcmd = kzalloc(sizeof(struct isr_queue_cmd), - GFP_ATOMIC); - if (!qcmd) { - CDBG("vfe_parse_irq: qcmd malloc failed!\n"); - return IRQ_HANDLED; - } - - spin_lock_irqsave(&ctrl->ack_lock, flags); - - if (ctrl->vfeStopAckPending) - irqStatusLocal = - (VFE_IMASK_WHILE_STOPPING & irq.vfeIrqStatus); - else - irqStatusLocal = - ((ctrl->vfeImaskPacked | VFE_IMASK_ERROR_ONLY) & - irq.vfeIrqStatus); - - spin_unlock_irqrestore(&ctrl->ack_lock, flags); - - /* first parse the interrupt status to local data structures. */ - qcmd->vfeInterruptStatus = vfe_parse_interrupt_status(irqStatusLocal); - qcmd->vfeAsfFrameInfo = vfe_get_asf_frame_info(&irq); - qcmd->vfeBpcFrameInfo = vfe_get_demosaic_frame_info(&irq); - qcmd->vfeCamifStatusLocal = vfe_get_camif_status(&irq); - qcmd->vfePmData = vfe_get_performance_monitor_data(&irq); - - spin_lock_irqsave(&ctrl->tasklet_lock, flags); - list_add_tail(&qcmd->list, &ctrl->tasklet_q); - spin_unlock_irqrestore(&ctrl->tasklet_lock, flags); - tasklet_schedule(&vfe_tasklet); - - /* clear the pending interrupt of the same kind.*/ - writel(irq.vfeIrqStatus, ctrl->vfebase + VFE_IRQ_CLEAR); - - return IRQ_HANDLED; -} - -int vfe_cmd_init(struct msm_vfe_callback *presp, - struct platform_device *pdev, void *sdata) -{ - struct resource *vfemem, *vfeirq, *vfeio; - int rc; - - vfemem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!vfemem) { - CDBG("no mem resource?\n"); - return -ENODEV; - } - - vfeirq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (!vfeirq) { - CDBG("no irq resource?\n"); - return -ENODEV; - } - - vfeio = request_mem_region(vfemem->start, - resource_size(vfemem), pdev->name); - if (!vfeio) { - CDBG("VFE region already claimed\n"); - return -EBUSY; - } - - ctrl = - kzalloc(sizeof(struct msm_vfe8x_ctrl), GFP_KERNEL); - if (!ctrl) { - rc = -ENOMEM; - goto cmd_init_failed1; - } - - ctrl->vfeirq = vfeirq->start; - - ctrl->vfebase = - ioremap(vfemem->start, (vfemem->end - vfemem->start) + 1); - if (!ctrl->vfebase) { - rc = -ENOMEM; - goto cmd_init_failed2; - } - - rc = request_irq(ctrl->vfeirq, vfe_parse_irq, - IRQF_TRIGGER_RISING, "vfe", 0); - if (rc < 0) - goto cmd_init_failed2; - - if (presp && presp->vfe_resp) - ctrl->resp = presp; - else { - rc = -EINVAL; - goto cmd_init_failed3; - } - - ctrl->extdata = - kmalloc(sizeof(struct vfe_frame_extra), GFP_KERNEL); - if (!ctrl->extdata) { - rc = -ENOMEM; - goto cmd_init_failed3; - } - - spin_lock_init(&ctrl->ack_lock); - spin_lock_init(&ctrl->state_lock); - spin_lock_init(&ctrl->io_lock); - - ctrl->extlen = sizeof(struct vfe_frame_extra); - - spin_lock_init(&ctrl->tasklet_lock); - INIT_LIST_HEAD(&ctrl->tasklet_q); - - ctrl->syncdata = sdata; - return 0; - -cmd_init_failed3: - disable_irq(ctrl->vfeirq); - free_irq(ctrl->vfeirq, 0); - iounmap(ctrl->vfebase); -cmd_init_failed2: - kfree(ctrl); -cmd_init_failed1: - release_mem_region(vfemem->start, (vfemem->end - vfemem->start) + 1); - return rc; -} - -void vfe_cmd_release(struct platform_device *dev) -{ - struct resource *mem; - - disable_irq(ctrl->vfeirq); - free_irq(ctrl->vfeirq, 0); - - iounmap(ctrl->vfebase); - mem = platform_get_resource(dev, IORESOURCE_MEM, 0); - release_mem_region(mem->start, (mem->end - mem->start) + 1); - - ctrl->extlen = 0; - - kfree(ctrl->extdata); - kfree(ctrl); -} - -void vfe_stats_af_stop(void) -{ - ctrl->vfeStatsCmdLocal.autoFocusEnable = FALSE; - ctrl->vfeImaskLocal.afPingpongIrq = FALSE; -} - -void vfe_stop(void) -{ - boolean vfeAxiBusy; - uint32_t vfeAxiStauts; - - /* for reset hw modules, and send msg when reset_irq comes.*/ - ctrl->vfeStopAckPending = TRUE; - - ctrl->vfeStatsPingPongReloadFlag = FALSE; - vfe_pm_stop(); - - /* disable all interrupts. */ - vfe_program_irq_mask(VFE_DISABLE_ALL_IRQS); - - /* in either continuous or snapshot mode, stop command can be issued - * at any time. - */ - vfe_camif_stop_immediately(); - vfe_program_axi_cmd(AXI_HALT); - vfe_prog_hw_testgen_cmd(VFE_TEST_GEN_STOP); - - vfeAxiBusy = TRUE; - - while (vfeAxiBusy) { - vfeAxiStauts = vfe_read_axi_status(); - if ((vfeAxiStauts & AXI_STATUS_BUSY_MASK) != 0) - vfeAxiBusy = FALSE; - } - - vfe_program_axi_cmd(AXI_HALT_CLEAR); - - /* clear all pending interrupts */ - writel(VFE_CLEAR_ALL_IRQS, ctrl->vfebase + VFE_IRQ_CLEAR); - - /* enable reset_ack and async timer interrupt only while stopping - * the pipeline. - */ - vfe_program_irq_mask(VFE_IMASK_WHILE_STOPPING); - - vfe_program_global_reset_cmd(VFE_RESET_UPON_STOP_CMD); -} - -void vfe_update(void) -{ - ctrl->vfeModuleEnableLocal.statsEnable = - ctrl->vfeStatsCmdLocal.autoFocusEnable | - ctrl->vfeStatsCmdLocal.axwEnable; - - vfe_reg_module_cfg(&ctrl->vfeModuleEnableLocal); - - vfe_program_stats_cmd(&ctrl->vfeStatsCmdLocal); - - ctrl->vfeImaskPacked = vfe_irq_pack(ctrl->vfeImaskLocal); - vfe_program_irq_mask(ctrl->vfeImaskPacked); - - if ((ctrl->vfeModuleEnableLocal.statsEnable == TRUE) && - (ctrl->vfeStatsPingPongReloadFlag == FALSE)) { - ctrl->vfeStatsPingPongReloadFlag = TRUE; - - ctrl->vfeBusCmdLocal.statsPingpongReload = TRUE; - vfe_reg_bus_cmd(&ctrl->vfeBusCmdLocal); - } - - vfe_program_reg_update_cmd(VFE_REG_UPDATE_TRIGGER); -} - -int vfe_rgb_gamma_update(struct vfe_cmd_rgb_gamma_config *in) -{ - int rc = 0; - - ctrl->vfeModuleEnableLocal.rgbLUTEnable = in->enable; - - switch (in->channelSelect) { - case RGB_GAMMA_CH0_SELECTED: - ctrl->vfeGammaLutSel.ch0BankSelect ^= 1; - vfe_write_gamma_table(0, - ctrl->vfeGammaLutSel.ch0BankSelect, in->table); - break; - - case RGB_GAMMA_CH1_SELECTED: - ctrl->vfeGammaLutSel.ch1BankSelect ^= 1; - vfe_write_gamma_table(1, - ctrl->vfeGammaLutSel.ch1BankSelect, in->table); - break; - - case RGB_GAMMA_CH2_SELECTED: - ctrl->vfeGammaLutSel.ch2BankSelect ^= 1; - vfe_write_gamma_table(2, - ctrl->vfeGammaLutSel.ch2BankSelect, in->table); - break; - - case RGB_GAMMA_CH0_CH1_SELECTED: - ctrl->vfeGammaLutSel.ch0BankSelect ^= 1; - ctrl->vfeGammaLutSel.ch1BankSelect ^= 1; - vfe_write_gamma_table(0, ctrl->vfeGammaLutSel.ch0BankSelect, - in->table); - vfe_write_gamma_table(1, ctrl->vfeGammaLutSel.ch1BankSelect, - in->table); - break; - - case RGB_GAMMA_CH0_CH2_SELECTED: - ctrl->vfeGammaLutSel.ch0BankSelect ^= 1; - ctrl->vfeGammaLutSel.ch2BankSelect ^= 1; - vfe_write_gamma_table(0, ctrl->vfeGammaLutSel.ch0BankSelect, - in->table); - vfe_write_gamma_table(2, ctrl->vfeGammaLutSel.ch2BankSelect, - in->table); - break; - - case RGB_GAMMA_CH1_CH2_SELECTED: - ctrl->vfeGammaLutSel.ch1BankSelect ^= 1; - ctrl->vfeGammaLutSel.ch2BankSelect ^= 1; - vfe_write_gamma_table(1, ctrl->vfeGammaLutSel.ch1BankSelect, - in->table); - vfe_write_gamma_table(2, ctrl->vfeGammaLutSel.ch2BankSelect, - in->table); - break; - - case RGB_GAMMA_CH0_CH1_CH2_SELECTED: - ctrl->vfeGammaLutSel.ch0BankSelect ^= 1; - ctrl->vfeGammaLutSel.ch1BankSelect ^= 1; - ctrl->vfeGammaLutSel.ch2BankSelect ^= 1; - vfe_write_gamma_table(0, ctrl->vfeGammaLutSel.ch0BankSelect, - in->table); - vfe_write_gamma_table(1, ctrl->vfeGammaLutSel.ch1BankSelect, - in->table); - vfe_write_gamma_table(2, ctrl->vfeGammaLutSel.ch2BankSelect, - in->table); - break; - - default: - return -EINVAL; - } /* switch */ - - /* update the gammaLutSel register. */ - vfe_program_lut_bank_sel(&ctrl->vfeGammaLutSel); - - return rc; -} - -int vfe_rgb_gamma_config(struct vfe_cmd_rgb_gamma_config *in) -{ - int rc = 0; - - ctrl->vfeModuleEnableLocal.rgbLUTEnable = in->enable; - - switch (in->channelSelect) { - case RGB_GAMMA_CH0_SELECTED: -vfe_write_gamma_table(0, 0, in->table); -break; - - case RGB_GAMMA_CH1_SELECTED: - vfe_write_gamma_table(1, 0, in->table); - break; - - case RGB_GAMMA_CH2_SELECTED: - vfe_write_gamma_table(2, 0, in->table); - break; - - case RGB_GAMMA_CH0_CH1_SELECTED: - vfe_write_gamma_table(0, 0, in->table); - vfe_write_gamma_table(1, 0, in->table); - break; - - case RGB_GAMMA_CH0_CH2_SELECTED: - vfe_write_gamma_table(0, 0, in->table); - vfe_write_gamma_table(2, 0, in->table); - break; - - case RGB_GAMMA_CH1_CH2_SELECTED: - vfe_write_gamma_table(1, 0, in->table); - vfe_write_gamma_table(2, 0, in->table); - break; - - case RGB_GAMMA_CH0_CH1_CH2_SELECTED: - vfe_write_gamma_table(0, 0, in->table); - vfe_write_gamma_table(1, 0, in->table); - vfe_write_gamma_table(2, 0, in->table); - break; - - default: - rc = -EINVAL; - break; - } /* switch */ - - return rc; -} - -void vfe_stats_af_ack(struct vfe_cmd_stats_af_ack *in) -{ - ctrl->afStatsControl.nextFrameAddrBuf = in->nextAFOutputBufferAddr; - ctrl->afStatsControl.ackPending = FALSE; -} - -void vfe_stats_wb_exp_ack(struct vfe_cmd_stats_wb_exp_ack *in) -{ - ctrl->awbStatsControl.nextFrameAddrBuf = in->nextWbExpOutputBufferAddr; - ctrl->awbStatsControl.ackPending = FALSE; -} - -void vfe_output2_ack(struct vfe_cmd_output_ack *in) -{ - const uint32_t *psrc; - uint32_t *pdest; - uint8_t i; - - pdest = ctrl->encPath.nextFrameAddrBuf; - - CDBG("output2_ack: ack addr = 0x%x\n", in->ybufaddr[0]); - - psrc = in->ybufaddr; - for (i = 0; i < ctrl->encPath.fragCount; i++) - *pdest++ = *psrc++; - - psrc = in->chromabufaddr; - for (i = 0; i < ctrl->encPath.fragCount; i++) - *pdest++ = *psrc++; - - ctrl->encPath.ackPending = FALSE; -} - -void vfe_output1_ack(struct vfe_cmd_output_ack *in) -{ - const uint32_t *psrc; - uint32_t *pdest; - uint8_t i; - - pdest = ctrl->viewPath.nextFrameAddrBuf; - - psrc = in->ybufaddr; - for (i = 0; i < ctrl->viewPath.fragCount; i++) - *pdest++ = *psrc++; - - psrc = in->chromabufaddr; - for (i = 0; i < ctrl->viewPath.fragCount; i++) - *pdest++ = *psrc++; - - ctrl->viewPath.ackPending = FALSE; -} - -void vfe_start(struct vfe_cmd_start *in) -{ - unsigned long flags; - uint32_t pmstatus = 0; - boolean rawmode; - uint32_t demperiod = 0; - uint32_t demeven = 0; - uint32_t demodd = 0; - - /* derived from other commands. (camif config, axi output config, - * etc) - */ - struct vfe_cfg hwcfg; - struct vfe_upsample_cfg chromupcfg; - - CDBG("vfe_start operationMode = %d\n", in->operationMode); - - memset(&hwcfg, 0, sizeof(hwcfg)); - memset(&chromupcfg, 0, sizeof(chromupcfg)); - - switch (in->pixel) { - case VFE_BAYER_RGRGRG: - demperiod = 1; - demeven = 0xC9; - demodd = 0xAC; - break; - - case VFE_BAYER_GRGRGR: - demperiod = 1; - demeven = 0x9C; - demodd = 0xCA; - break; - - case VFE_BAYER_BGBGBG: - demperiod = 1; - demeven = 0xCA; - demodd = 0x9C; - break; - - case VFE_BAYER_GBGBGB: - demperiod = 1; - demeven = 0xAC; - demodd = 0xC9; - break; - - case VFE_YUV_YCbYCr: - demperiod = 3; - demeven = 0x9CAC; - demodd = 0x9CAC; - break; - - case VFE_YUV_YCrYCb: - demperiod = 3; - demeven = 0xAC9C; - demodd = 0xAC9C; - break; - - case VFE_YUV_CbYCrY: - demperiod = 3; - demeven = 0xC9CA; - demodd = 0xC9CA; - break; - - case VFE_YUV_CrYCbY: - demperiod = 3; - demeven = 0xCAC9; - demodd = 0xCAC9; - break; - - default: - return; - } - - vfe_config_demux(demperiod, demeven, demodd); - - vfe_program_lut_bank_sel(&ctrl->vfeGammaLutSel); - - /* save variables to local. */ - ctrl->vfeOperationMode = in->operationMode; - if (ctrl->vfeOperationMode == - VFE_START_OPERATION_MODE_SNAPSHOT) { - /* in snapshot mode, initialize snapshot count*/ - ctrl->vfeSnapShotCount = in->snapshotCount; - - /* save the requested count, this is temporarily done, to - help with HJR / multishot. */ - ctrl->vfeRequestedSnapShotCount = ctrl->vfeSnapShotCount; - - CDBG("requested snapshot count = %d\n", ctrl->vfeSnapShotCount); - - /* Assumption is to have the same pattern and period for both - paths, if both paths are used. */ - if (ctrl->viewPath.pathEnabled) { - ctrl->viewPath.snapshotPendingCount = - in->snapshotCount; - - ctrl->vfeFrameSkipPattern = - ctrl->vfeFrameSkip.output1Pattern; - ctrl->vfeFrameSkipPeriod = - ctrl->vfeFrameSkip.output1Period; - } - - if (ctrl->encPath.pathEnabled) { - ctrl->encPath.snapshotPendingCount = - in->snapshotCount; - - ctrl->vfeFrameSkipPattern = - ctrl->vfeFrameSkip.output2Pattern; - ctrl->vfeFrameSkipPeriod = - ctrl->vfeFrameSkip.output2Period; - } - } - - /* enable color conversion for bayer sensor - if stats enabled, need to do color conversion. */ - if (in->pixel <= VFE_BAYER_GBGBGB) - ctrl->vfeStatsCmdLocal.colorConversionEnable = TRUE; - - vfe_program_stats_cmd(&ctrl->vfeStatsCmdLocal); - - if (in->pixel >= VFE_YUV_YCbYCr) - ctrl->vfeModuleEnableLocal.chromaUpsampleEnable = TRUE; - - ctrl->vfeModuleEnableLocal.demuxEnable = TRUE; - - /* if any stats module is enabled, the main bit is enabled. */ - ctrl->vfeModuleEnableLocal.statsEnable = - ctrl->vfeStatsCmdLocal.autoFocusEnable | - ctrl->vfeStatsCmdLocal.axwEnable; - - vfe_reg_module_cfg(&ctrl->vfeModuleEnableLocal); - - /* in case of offline processing, do not need to config camif. Having - * bus output enabled in camif_config register might confuse the - * hardware? - */ - if (in->inputSource != VFE_START_INPUT_SOURCE_AXI) { - vfe_reg_camif_config(&ctrl->vfeCamifConfigLocal); - } else { - /* offline processing, enable axi read */ - ctrl->vfeBusConfigLocal.stripeRdPathEn = TRUE; - ctrl->vfeBusCmdLocal.stripeReload = TRUE; - ctrl->vfeBusConfigLocal.rawPixelDataSize = - ctrl->axiInputDataSize; - } - - vfe_reg_bus_cfg(&ctrl->vfeBusConfigLocal); - - /* directly from start command */ - hwcfg.pixelPattern = in->pixel; - hwcfg.inputSource = in->inputSource; - writel(*(uint32_t *)&hwcfg, ctrl->vfebase + VFE_CFG); - - /* regardless module enabled or not, it does not hurt - * to program the cositing mode. */ - chromupcfg.chromaCositingForYCbCrInputs = - in->yuvInputCositingMode; - - writel(*(uint32_t *)&(chromupcfg), - ctrl->vfebase + VFE_CHROMA_UPSAMPLE_CFG); - - /* MISR to monitor the axi read. */ - writel(0xd8, ctrl->vfebase + VFE_BUS_MISR_MAST_CFG_0); - - /* clear all pending interrupts. */ - writel(VFE_CLEAR_ALL_IRQS, ctrl->vfebase + VFE_IRQ_CLEAR); - - /* define how composite interrupt work. */ - ctrl->vfeImaskCompositePacked = - vfe_irq_composite_pack(ctrl->vfeIrqCompositeMaskLocal); - - vfe_program_irq_composite_mask(ctrl->vfeImaskCompositePacked); - - /* enable all necessary interrupts. */ - ctrl->vfeImaskLocal.camifSofIrq = TRUE; - ctrl->vfeImaskLocal.regUpdateIrq = TRUE; - ctrl->vfeImaskLocal.resetAckIrq = TRUE; - - ctrl->vfeImaskPacked = vfe_irq_pack(ctrl->vfeImaskLocal); - vfe_program_irq_mask(ctrl->vfeImaskPacked); - - /* enable bus performance monitor */ - vfe_8k_pm_start(&ctrl->vfeBusPmConfigLocal); - - /* trigger vfe reg update */ - ctrl->vfeStartAckPendingFlag = TRUE; - - /* write bus command to trigger reload of ping pong buffer. */ - ctrl->vfeBusCmdLocal.busPingpongReload = TRUE; - - if (ctrl->vfeModuleEnableLocal.statsEnable == TRUE) { - ctrl->vfeBusCmdLocal.statsPingpongReload = TRUE; - ctrl->vfeStatsPingPongReloadFlag = TRUE; - } - - writel(VFE_REG_UPDATE_TRIGGER, - ctrl->vfebase + VFE_REG_UPDATE_CMD); - - /* program later than the reg update. */ - vfe_reg_bus_cmd(&ctrl->vfeBusCmdLocal); - - if ((in->inputSource == - VFE_START_INPUT_SOURCE_CAMIF) || - (in->inputSource == - VFE_START_INPUT_SOURCE_TESTGEN)) - writel(CAMIF_COMMAND_START, ctrl->vfebase + CAMIF_COMMAND); - - /* start test gen if it is enabled */ - if (ctrl->vfeTestGenStartFlag == TRUE) { - ctrl->vfeTestGenStartFlag = FALSE; - vfe_prog_hw_testgen_cmd(VFE_TEST_GEN_GO); - } - - CDBG("ctrl->axiOutputMode = %d\n", ctrl->axiOutputMode); - if (ctrl->axiOutputMode == VFE_AXI_OUTPUT_MODE_CAMIFToAXIViaOutput2) { - /* raw dump mode */ - rawmode = TRUE; - - while (rawmode) { - pmstatus = - readl(ctrl->vfebase + - VFE_BUS_ENC_CBCR_WR_PM_STATS_1); - - if ((pmstatus & VFE_PM_BUF_MAX_CNT_MASK) != 0) - rawmode = FALSE; - } - - vfe_send_msg_no_payload(VFE_MSG_ID_START_ACK); - ctrl->vfeStartAckPendingFlag = FALSE; - } - - spin_lock_irqsave(&ctrl->state_lock, flags); - ctrl->vstate = VFE_STATE_ACTIVE; - spin_unlock_irqrestore(&ctrl->state_lock, flags); -} - -void vfe_la_update(struct vfe_cmd_la_config *in) -{ - int16_t *pTable; - enum VFE_DMI_RAM_SEL dmiRamSel; - int i; - - pTable = in->table; - ctrl->vfeModuleEnableLocal.lumaAdaptationEnable = in->enable; - - /* toggle the bank to be used. */ - ctrl->vfeLaBankSel ^= 1; - - if (ctrl->vfeLaBankSel == 0) - dmiRamSel = LUMA_ADAPT_LUT_RAM_BANK0; - else - dmiRamSel = LUMA_ADAPT_LUT_RAM_BANK1; - - /* configure the DMI_CFG to select right sram */ - vfe_program_dmi_cfg(dmiRamSel); - - for (i = 0; i < VFE_LA_TABLE_LENGTH; i++) { - writel((uint32_t)(*pTable), ctrl->vfebase + VFE_DMI_DATA_LO); - pTable++; - } - - /* After DMI transfer, to make it safe, need to set - * the DMI_CFG to unselect any SRAM */ - writel(VFE_DMI_CFG_DEFAULT, ctrl->vfebase + VFE_DMI_CFG); - writel(ctrl->vfeLaBankSel, ctrl->vfebase + VFE_LA_CFG); -} - -void vfe_la_config(struct vfe_cmd_la_config *in) -{ - uint16_t i; - int16_t *pTable; - enum VFE_DMI_RAM_SEL dmiRamSel; - - pTable = in->table; - ctrl->vfeModuleEnableLocal.lumaAdaptationEnable = in->enable; - - if (ctrl->vfeLaBankSel == 0) - dmiRamSel = LUMA_ADAPT_LUT_RAM_BANK0; - else - dmiRamSel = LUMA_ADAPT_LUT_RAM_BANK1; - - /* configure the DMI_CFG to select right sram */ - vfe_program_dmi_cfg(dmiRamSel); - - for (i = 0; i < VFE_LA_TABLE_LENGTH; i++) { - writel((uint32_t)(*pTable), ctrl->vfebase + VFE_DMI_DATA_LO); - pTable++; - } - - /* After DMI transfer, to make it safe, need to set the - * DMI_CFG to unselect any SRAM */ - writel(VFE_DMI_CFG_DEFAULT, ctrl->vfebase + VFE_DMI_CFG); - - /* can only be bank 0 or bank 1 for now. */ - writel(ctrl->vfeLaBankSel, ctrl->vfebase + VFE_LA_CFG); - CDBG("VFE Luma adaptation bank selection is 0x%x\n", - *(uint32_t *)&ctrl->vfeLaBankSel); -} - -void vfe_test_gen_start(struct vfe_cmd_test_gen_start *in) -{ - struct VFE_TestGen_ConfigCmdType cmd; - - memset(&cmd, 0, sizeof(cmd)); - - cmd.numFrame = in->numFrame; - cmd.pixelDataSelect = in->pixelDataSelect; - cmd.systematicDataSelect = in->systematicDataSelect; - cmd.pixelDataSize = (uint32_t)in->pixelDataSize; - cmd.hsyncEdge = (uint32_t)in->hsyncEdge; - cmd.vsyncEdge = (uint32_t)in->vsyncEdge; - cmd.imageWidth = in->imageWidth; - cmd.imageHeight = in->imageHeight; - cmd.sofOffset = in->startOfFrameOffset; - cmd.eofNOffset = in->endOfFrameNOffset; - cmd.solOffset = in->startOfLineOffset; - cmd.eolNOffset = in->endOfLineNOffset; - cmd.hBlankInterval = in->hbi; - cmd.vBlankInterval = in->vbl; - cmd.vBlankIntervalEnable = in->vblEnable; - cmd.sofDummy = in->startOfFrameDummyLine; - cmd.eofDummy = in->endOfFrameDummyLine; - cmd.unicolorBarSelect = in->unicolorBarSelect; - cmd.unicolorBarEnable = in->unicolorBarEnable; - cmd.splitEnable = in->colorBarsSplitEnable; - cmd.pixelPattern = (uint32_t)in->colorBarsPixelPattern; - cmd.rotatePeriod = in->colorBarsRotatePeriod; - cmd.randomSeed = in->testGenRandomSeed; - - vfe_prog_hw(ctrl->vfebase + VFE_HW_TESTGEN_CFG, - (uint32_t *) &cmd, sizeof(cmd)); -} - -void vfe_frame_skip_update(struct vfe_cmd_frame_skip_update *in) -{ - struct VFE_FRAME_SKIP_UpdateCmdType cmd; - - cmd.yPattern = in->output1Pattern; - cmd.cbcrPattern = in->output1Pattern; - vfe_prog_hw(ctrl->vfebase + VFE_FRAMEDROP_VIEW_Y_PATTERN, - (uint32_t *)&cmd, sizeof(cmd)); - - cmd.yPattern = in->output2Pattern; - cmd.cbcrPattern = in->output2Pattern; - vfe_prog_hw(ctrl->vfebase + VFE_FRAMEDROP_ENC_Y_PATTERN, - (uint32_t *)&cmd, sizeof(cmd)); -} - -void vfe_frame_skip_config(struct vfe_cmd_frame_skip_config *in) -{ - struct vfe_frame_skip_cfg cmd; - memset(&cmd, 0, sizeof(cmd)); - - ctrl->vfeFrameSkip = *in; - - cmd.output2YPeriod = in->output2Period; - cmd.output2CbCrPeriod = in->output2Period; - cmd.output2YPattern = in->output2Pattern; - cmd.output2CbCrPattern = in->output2Pattern; - cmd.output1YPeriod = in->output1Period; - cmd.output1CbCrPeriod = in->output1Period; - cmd.output1YPattern = in->output1Pattern; - cmd.output1CbCrPattern = in->output1Pattern; - - vfe_prog_hw(ctrl->vfebase + VFE_FRAMEDROP_ENC_Y_CFG, - (uint32_t *)&cmd, sizeof(cmd)); -} - -void vfe_output_clamp_config(struct vfe_cmd_output_clamp_config *in) -{ - struct vfe_output_clamp_cfg cmd; - memset(&cmd, 0, sizeof(cmd)); - - cmd.yChanMax = in->maxCh0; - cmd.cbChanMax = in->maxCh1; - cmd.crChanMax = in->maxCh2; - - cmd.yChanMin = in->minCh0; - cmd.cbChanMin = in->minCh1; - cmd.crChanMin = in->minCh2; - - vfe_prog_hw(ctrl->vfebase + VFE_CLAMP_MAX_CFG, (uint32_t *)&cmd, - sizeof(cmd)); -} - -void vfe_camif_frame_update(struct vfe_cmds_camif_frame *in) -{ - struct vfe_camifframe_update cmd; - - memset(&cmd, 0, sizeof(cmd)); - - cmd.pixelsPerLine = in->pixelsPerLine; - cmd.linesPerFrame = in->linesPerFrame; - - vfe_prog_hw(ctrl->vfebase + CAMIF_FRAME_CONFIG, (uint32_t *)&cmd, - sizeof(cmd)); -} - -void vfe_color_correction_config( - struct vfe_cmd_color_correction_config *in) -{ - struct vfe_color_correction_cfg cmd; - - memset(&cmd, 0, sizeof(cmd)); - ctrl->vfeModuleEnableLocal.colorCorrectionEnable = in->enable; - - cmd.c0 = in->C0; - cmd.c1 = in->C1; - cmd.c2 = in->C2; - cmd.c3 = in->C3; - cmd.c4 = in->C4; - cmd.c5 = in->C5; - cmd.c6 = in->C6; - cmd.c7 = in->C7; - cmd.c8 = in->C8; - - cmd.k0 = in->K0; - cmd.k1 = in->K1; - cmd.k2 = in->K2; - - cmd.coefQFactor = in->coefQFactor; - - vfe_prog_hw(ctrl->vfebase + VFE_COLOR_CORRECT_COEFF_0, - (uint32_t *)&cmd, sizeof(cmd)); -} - -void vfe_demosaic_abf_update(struct vfe_cmd_demosaic_abf_update *in) -{ -struct vfe_demosaic_cfg cmd; - struct vfe_demosaic_abf_cfg cmdabf; - uint32_t temp; - - memset(&cmd, 0, sizeof(cmd)); - temp = readl(ctrl->vfebase + VFE_DEMOSAIC_CFG); - - cmd = *((struct vfe_demosaic_cfg *)(&temp)); - cmd.abfEnable = in->abfUpdate.enable; - cmd.forceAbfOn = in->abfUpdate.forceOn; - cmd.abfShift = in->abfUpdate.shift; - vfe_prog_hw(ctrl->vfebase + VFE_DEMOSAIC_CFG, - (uint32_t *)&cmd, sizeof(cmd)); - - cmdabf.lpThreshold = in->abfUpdate.lpThreshold; - cmdabf.ratio = in->abfUpdate.ratio; - cmdabf.minValue = in->abfUpdate.min; - cmdabf.maxValue = in->abfUpdate.max; - vfe_prog_hw(ctrl->vfebase + VFE_DEMOSAIC_ABF_CFG_0, - (uint32_t *)&cmdabf, sizeof(cmdabf)); -} - -void vfe_demosaic_bpc_update(struct vfe_cmd_demosaic_bpc_update *in) -{ - struct vfe_demosaic_cfg cmd; - struct vfe_demosaic_bpc_cfg cmdbpc; - uint32_t temp; - - memset(&cmd, 0, sizeof(cmd)); - - temp = readl(ctrl->vfebase + VFE_DEMOSAIC_CFG); - - cmd = *((struct vfe_demosaic_cfg *)(&temp)); - cmd.badPixelCorrEnable = in->bpcUpdate.enable; - cmd.fminThreshold = in->bpcUpdate.fminThreshold; - cmd.fmaxThreshold = in->bpcUpdate.fmaxThreshold; - - vfe_prog_hw(ctrl->vfebase + VFE_DEMOSAIC_CFG, - (uint32_t *)&cmd, sizeof(cmd)); - - cmdbpc.blueDiffThreshold = in->bpcUpdate.blueDiffThreshold; - cmdbpc.redDiffThreshold = in->bpcUpdate.redDiffThreshold; - cmdbpc.greenDiffThreshold = in->bpcUpdate.greenDiffThreshold; - - vfe_prog_hw(ctrl->vfebase + VFE_DEMOSAIC_BPC_CFG_0, - (uint32_t *)&cmdbpc, sizeof(cmdbpc)); -} - -void vfe_demosaic_config(struct vfe_cmd_demosaic_config *in) -{ - struct vfe_demosaic_cfg cmd; - struct vfe_demosaic_bpc_cfg cmd_bpc; - struct vfe_demosaic_abf_cfg cmd_abf; - - memset(&cmd, 0, sizeof(cmd)); - memset(&cmd_bpc, 0, sizeof(cmd_bpc)); - memset(&cmd_abf, 0, sizeof(cmd_abf)); - - ctrl->vfeModuleEnableLocal.demosaicEnable = in->enable; - - cmd.abfEnable = in->abfConfig.enable; - cmd.badPixelCorrEnable = in->bpcConfig.enable; - cmd.forceAbfOn = in->abfConfig.forceOn; - cmd.abfShift = in->abfConfig.shift; - cmd.fminThreshold = in->bpcConfig.fminThreshold; - cmd.fmaxThreshold = in->bpcConfig.fmaxThreshold; - cmd.slopeShift = in->slopeShift; - - vfe_prog_hw(ctrl->vfebase + VFE_DEMOSAIC_CFG, - (uint32_t *)&cmd, sizeof(cmd)); - - cmd_abf.lpThreshold = in->abfConfig.lpThreshold; - cmd_abf.ratio = in->abfConfig.ratio; - cmd_abf.minValue = in->abfConfig.min; - cmd_abf.maxValue = in->abfConfig.max; - - vfe_prog_hw(ctrl->vfebase + VFE_DEMOSAIC_ABF_CFG_0, - (uint32_t *)&cmd_abf, sizeof(cmd_abf)); - - cmd_bpc.blueDiffThreshold = in->bpcConfig.blueDiffThreshold; - cmd_bpc.redDiffThreshold = in->bpcConfig.redDiffThreshold; - cmd_bpc.greenDiffThreshold = in->bpcConfig.greenDiffThreshold; - - vfe_prog_hw(ctrl->vfebase + VFE_DEMOSAIC_BPC_CFG_0, - (uint32_t *)&cmd_bpc, sizeof(cmd_bpc)); -} - -void vfe_demux_channel_gain_update( - struct vfe_cmd_demux_channel_gain_config *in) -{ - struct vfe_demux_cfg cmd; - - memset(&cmd, 0, sizeof(cmd)); - - cmd.ch0EvenGain = in->ch0EvenGain; - cmd.ch0OddGain = in->ch0OddGain; - cmd.ch1Gain = in->ch1Gain; - cmd.ch2Gain = in->ch2Gain; - - vfe_prog_hw(ctrl->vfebase + VFE_DEMUX_GAIN_0, - (uint32_t *)&cmd, sizeof(cmd)); -} - -void vfe_demux_channel_gain_config( - struct vfe_cmd_demux_channel_gain_config *in) -{ - struct vfe_demux_cfg cmd; - - memset(&cmd, 0, sizeof(cmd)); - - cmd.ch0EvenGain = in->ch0EvenGain; - cmd.ch0OddGain = in->ch0OddGain; - cmd.ch1Gain = in->ch1Gain; - cmd.ch2Gain = in->ch2Gain; - - vfe_prog_hw(ctrl->vfebase + VFE_DEMUX_GAIN_0, - (uint32_t *)&cmd, sizeof(cmd)); -} - -void vfe_black_level_update(struct vfe_cmd_black_level_config *in) -{ - struct vfe_blacklevel_cfg cmd; - - memset(&cmd, 0, sizeof(cmd)); - ctrl->vfeModuleEnableLocal.blackLevelCorrectionEnable = in->enable; - - cmd.evenEvenAdjustment = in->evenEvenAdjustment; - cmd.evenOddAdjustment = in->evenOddAdjustment; - cmd.oddEvenAdjustment = in->oddEvenAdjustment; - cmd.oddOddAdjustment = in->oddOddAdjustment; - - vfe_prog_hw(ctrl->vfebase + VFE_BLACK_EVEN_EVEN_VALUE, - (uint32_t *)&cmd, sizeof(cmd)); -} - -void vfe_black_level_config(struct vfe_cmd_black_level_config *in) -{ - struct vfe_blacklevel_cfg cmd; - memset(&cmd, 0, sizeof(cmd)); - - ctrl->vfeModuleEnableLocal.blackLevelCorrectionEnable = in->enable; - - cmd.evenEvenAdjustment = in->evenEvenAdjustment; - cmd.evenOddAdjustment = in->evenOddAdjustment; - cmd.oddEvenAdjustment = in->oddEvenAdjustment; - cmd.oddOddAdjustment = in->oddOddAdjustment; - - vfe_prog_hw(ctrl->vfebase + VFE_BLACK_EVEN_EVEN_VALUE, - (uint32_t *)&cmd, sizeof(cmd)); -} - -void vfe_asf_update(struct vfe_cmd_asf_update *in) -{ - struct vfe_asf_update cmd; - memset(&cmd, 0, sizeof(cmd)); - - ctrl->vfeModuleEnableLocal.asfEnable = in->enable; - - cmd.smoothEnable = in->smoothFilterEnabled; - cmd.sharpMode = in->sharpMode; - cmd.smoothCoeff1 = in->smoothCoefCenter; - cmd.smoothCoeff0 = in->smoothCoefSurr; - cmd.cropEnable = in->cropEnable; - cmd.sharpThresholdE1 = in->sharpThreshE1; - cmd.sharpDegreeK1 = in->sharpK1; - cmd.sharpDegreeK2 = in->sharpK2; - cmd.normalizeFactor = in->normalizeFactor; - cmd.sharpThresholdE2 = in->sharpThreshE2; - cmd.sharpThresholdE3 = in->sharpThreshE3; - cmd.sharpThresholdE4 = in->sharpThreshE4; - cmd.sharpThresholdE5 = in->sharpThreshE5; - cmd.F1Coeff0 = in->filter1Coefficients[0]; - cmd.F1Coeff1 = in->filter1Coefficients[1]; - cmd.F1Coeff2 = in->filter1Coefficients[2]; - cmd.F1Coeff3 = in->filter1Coefficients[3]; - cmd.F1Coeff4 = in->filter1Coefficients[4]; - cmd.F1Coeff5 = in->filter1Coefficients[5]; - cmd.F1Coeff6 = in->filter1Coefficients[6]; - cmd.F1Coeff7 = in->filter1Coefficients[7]; - cmd.F1Coeff8 = in->filter1Coefficients[8]; - cmd.F2Coeff0 = in->filter2Coefficients[0]; - cmd.F2Coeff1 = in->filter2Coefficients[1]; - cmd.F2Coeff2 = in->filter2Coefficients[2]; - cmd.F2Coeff3 = in->filter2Coefficients[3]; - cmd.F2Coeff4 = in->filter2Coefficients[4]; - cmd.F2Coeff5 = in->filter2Coefficients[5]; - cmd.F2Coeff6 = in->filter2Coefficients[6]; - cmd.F2Coeff7 = in->filter2Coefficients[7]; - cmd.F2Coeff8 = in->filter2Coefficients[8]; - - vfe_prog_hw(ctrl->vfebase + VFE_ASF_CFG, - (uint32_t *)&cmd, sizeof(cmd)); -} - -void vfe_asf_config(struct vfe_cmd_asf_config *in) -{ - struct vfe_asf_update cmd; - struct vfe_asfcrop_cfg cmd2; - - memset(&cmd, 0, sizeof(cmd)); - memset(&cmd2, 0, sizeof(cmd2)); - - ctrl->vfeModuleEnableLocal.asfEnable = in->enable; - - cmd.smoothEnable = in->smoothFilterEnabled; - cmd.sharpMode = in->sharpMode; - cmd.smoothCoeff0 = in->smoothCoefCenter; - cmd.smoothCoeff1 = in->smoothCoefSurr; - cmd.cropEnable = in->cropEnable; - cmd.sharpThresholdE1 = in->sharpThreshE1; - cmd.sharpDegreeK1 = in->sharpK1; - cmd.sharpDegreeK2 = in->sharpK2; - cmd.normalizeFactor = in->normalizeFactor; - cmd.sharpThresholdE2 = in->sharpThreshE2; - cmd.sharpThresholdE3 = in->sharpThreshE3; - cmd.sharpThresholdE4 = in->sharpThreshE4; - cmd.sharpThresholdE5 = in->sharpThreshE5; - cmd.F1Coeff0 = in->filter1Coefficients[0]; - cmd.F1Coeff1 = in->filter1Coefficients[1]; - cmd.F1Coeff2 = in->filter1Coefficients[2]; - cmd.F1Coeff3 = in->filter1Coefficients[3]; - cmd.F1Coeff4 = in->filter1Coefficients[4]; - cmd.F1Coeff5 = in->filter1Coefficients[5]; - cmd.F1Coeff6 = in->filter1Coefficients[6]; - cmd.F1Coeff7 = in->filter1Coefficients[7]; - cmd.F1Coeff8 = in->filter1Coefficients[8]; - cmd.F2Coeff0 = in->filter2Coefficients[0]; - cmd.F2Coeff1 = in->filter2Coefficients[1]; - cmd.F2Coeff2 = in->filter2Coefficients[2]; - cmd.F2Coeff3 = in->filter2Coefficients[3]; - cmd.F2Coeff4 = in->filter2Coefficients[4]; - cmd.F2Coeff5 = in->filter2Coefficients[5]; - cmd.F2Coeff6 = in->filter2Coefficients[6]; - cmd.F2Coeff7 = in->filter2Coefficients[7]; - cmd.F2Coeff8 = in->filter2Coefficients[8]; - - vfe_prog_hw(ctrl->vfebase + VFE_ASF_CFG, - (uint32_t *)&cmd, sizeof(cmd)); - - cmd2.firstLine = in->cropFirstLine; - cmd2.lastLine = in->cropLastLine; - cmd2.firstPixel = in->cropFirstPixel; - cmd2.lastPixel = in->cropLastPixel; - - vfe_prog_hw(ctrl->vfebase + VFE_ASF_CROP_WIDTH_CFG, - (uint32_t *)&cmd2, sizeof(cmd2)); -} - -void vfe_white_balance_config(struct vfe_cmd_white_balance_config *in) -{ - struct vfe_wb_cfg cmd; - memset(&cmd, 0, sizeof(cmd)); - - ctrl->vfeModuleEnableLocal.whiteBalanceEnable = - in->enable; - - cmd.ch0Gain = in->ch0Gain; - cmd.ch1Gain = in->ch1Gain; - cmd.ch2Gain = in->ch2Gain; - - vfe_prog_hw(ctrl->vfebase + VFE_WB_CFG, - (uint32_t *)&cmd, sizeof(cmd)); -} - -void vfe_chroma_sup_config(struct vfe_cmd_chroma_suppression_config *in) -{ - struct vfe_chroma_suppress_cfg cmd; - memset(&cmd, 0, sizeof(cmd)); - - ctrl->vfeModuleEnableLocal.chromaSuppressionEnable = in->enable; - - cmd.m1 = in->m1; - cmd.m3 = in->m3; - cmd.n1 = in->n1; - cmd.n3 = in->n3; - cmd.mm1 = in->mm1; - cmd.nn1 = in->nn1; - - vfe_prog_hw(ctrl->vfebase + VFE_CHROMA_SUPPRESS_CFG_0, - (uint32_t *)&cmd, sizeof(cmd)); -} - -void vfe_roll_off_config(struct vfe_cmd_roll_off_config *in) -{ - struct vfe_rolloff_cfg cmd; - memset(&cmd, 0, sizeof(cmd)); - - ctrl->vfeModuleEnableLocal.lensRollOffEnable = in->enable; - - cmd.gridWidth = in->gridWidth; - cmd.gridHeight = in->gridHeight; - cmd.yDelta = in->yDelta; - cmd.gridX = in->gridXIndex; - cmd.gridY = in->gridYIndex; - cmd.pixelX = in->gridPixelXIndex; - cmd.pixelY = in->gridPixelYIndex; - cmd.yDeltaAccum = in->yDeltaAccum; - - vfe_prog_hw(ctrl->vfebase + VFE_ROLLOFF_CFG_0, - (uint32_t *)&cmd, sizeof(cmd)); - - vfe_write_lens_roll_off_table(in); -} - -void vfe_chroma_subsample_config( - struct vfe_cmd_chroma_subsample_config *in) -{ - struct vfe_chromasubsample_cfg cmd; - memset(&cmd, 0, sizeof(cmd)); - - ctrl->vfeModuleEnableLocal.chromaSubsampleEnable = in->enable; - - cmd.hCositedPhase = in->hCositedPhase; - cmd.vCositedPhase = in->vCositedPhase; - cmd.hCosited = in->hCosited; - cmd.vCosited = in->vCosited; - cmd.hsubSampleEnable = in->hsubSampleEnable; - cmd.vsubSampleEnable = in->vsubSampleEnable; - cmd.cropEnable = in->cropEnable; - cmd.cropWidthLastPixel = in->cropWidthLastPixel; - cmd.cropWidthFirstPixel = in->cropWidthFirstPixel; - cmd.cropHeightLastLine = in->cropHeightLastLine; - cmd.cropHeightFirstLine = in->cropHeightFirstLine; - - vfe_prog_hw(ctrl->vfebase + VFE_CHROMA_SUBSAMPLE_CFG, - (uint32_t *)&cmd, sizeof(cmd)); -} - -void vfe_chroma_enhan_config(struct vfe_cmd_chroma_enhan_config *in) -{ - struct vfe_chroma_enhance_cfg cmd; - struct vfe_color_convert_cfg cmd2; - - memset(&cmd, 0, sizeof(cmd)); - memset(&cmd2, 0, sizeof(cmd2)); - - ctrl->vfeModuleEnableLocal.chromaEnhanEnable = in->enable; - - cmd.ap = in->ap; - cmd.am = in->am; - cmd.bp = in->bp; - cmd.bm = in->bm; - cmd.cp = in->cp; - cmd.cm = in->cm; - cmd.dp = in->dp; - cmd.dm = in->dm; - cmd.kcb = in->kcb; - cmd.kcr = in->kcr; - - cmd2.v0 = in->RGBtoYConversionV0; - cmd2.v1 = in->RGBtoYConversionV1; - cmd2.v2 = in->RGBtoYConversionV2; - cmd2.ConvertOffset = in->RGBtoYConversionOffset; - - vfe_prog_hw(ctrl->vfebase + VFE_CHROMA_ENHAN_A, - (uint32_t *)&cmd, sizeof(cmd)); - - vfe_prog_hw(ctrl->vfebase + VFE_COLOR_CONVERT_COEFF_0, - (uint32_t *)&cmd2, sizeof(cmd2)); -} - -void vfe_scaler2cbcr_config(struct vfe_cmd_scaler2_config *in) -{ - struct vfe_scaler2_cfg cmd; - - memset(&cmd, 0, sizeof(cmd)); - - ctrl->vfeModuleEnableLocal.scaler2CbcrEnable = in->enable; - - cmd.hEnable = in->hconfig.enable; - cmd.vEnable = in->vconfig.enable; - cmd.inWidth = in->hconfig.inputSize; - cmd.outWidth = in->hconfig.outputSize; - cmd.horizPhaseMult = in->hconfig.phaseMultiplicationFactor; - cmd.horizInterResolution = in->hconfig.interpolationResolution; - cmd.inHeight = in->vconfig.inputSize; - cmd.outHeight = in->vconfig.outputSize; - cmd.vertPhaseMult = in->vconfig.phaseMultiplicationFactor; - cmd.vertInterResolution = in->vconfig.interpolationResolution; - - vfe_prog_hw(ctrl->vfebase + VFE_SCALE_CBCR_CFG, - (uint32_t *)&cmd, sizeof(cmd)); -} - -void vfe_scaler2y_config(struct vfe_cmd_scaler2_config *in) -{ - struct vfe_scaler2_cfg cmd; - - memset(&cmd, 0, sizeof(cmd)); - - ctrl->vfeModuleEnableLocal.scaler2YEnable = in->enable; - - cmd.hEnable = in->hconfig.enable; - cmd.vEnable = in->vconfig.enable; - cmd.inWidth = in->hconfig.inputSize; - cmd.outWidth = in->hconfig.outputSize; - cmd.horizPhaseMult = in->hconfig.phaseMultiplicationFactor; - cmd.horizInterResolution = in->hconfig.interpolationResolution; - cmd.inHeight = in->vconfig.inputSize; - cmd.outHeight = in->vconfig.outputSize; - cmd.vertPhaseMult = in->vconfig.phaseMultiplicationFactor; - cmd.vertInterResolution = in->vconfig.interpolationResolution; - - vfe_prog_hw(ctrl->vfebase + VFE_SCALE_Y_CFG, - (uint32_t *)&cmd, sizeof(cmd)); -} - -void vfe_main_scaler_config(struct vfe_cmd_main_scaler_config *in) -{ - struct vfe_main_scaler_cfg cmd; - - memset(&cmd, 0, sizeof(cmd)); - - ctrl->vfeModuleEnableLocal.mainScalerEnable = in->enable; - - cmd.hEnable = in->hconfig.enable; - cmd.vEnable = in->vconfig.enable; - cmd.inWidth = in->hconfig.inputSize; - cmd.outWidth = in->hconfig.outputSize; - cmd.horizPhaseMult = in->hconfig.phaseMultiplicationFactor; - cmd.horizInterResolution = in->hconfig.interpolationResolution; - cmd.horizMNInit = in->MNInitH.MNCounterInit; - cmd.horizPhaseInit = in->MNInitH.phaseInit; - cmd.inHeight = in->vconfig.inputSize; - cmd.outHeight = in->vconfig.outputSize; - cmd.vertPhaseMult = in->vconfig.phaseMultiplicationFactor; - cmd.vertInterResolution = in->vconfig.interpolationResolution; - cmd.vertMNInit = in->MNInitV.MNCounterInit; - cmd.vertPhaseInit = in->MNInitV.phaseInit; - - vfe_prog_hw(ctrl->vfebase + VFE_SCALE_CFG, - (uint32_t *)&cmd, sizeof(cmd)); -} - -void vfe_stats_wb_exp_stop(void) -{ - ctrl->vfeStatsCmdLocal.axwEnable = FALSE; - ctrl->vfeImaskLocal.awbPingpongIrq = FALSE; -} - -void vfe_stats_update_wb_exp(struct vfe_cmd_stats_wb_exp_update *in) -{ - struct vfe_statsawb_update cmd; - struct vfe_statsawbae_update cmd2; - - memset(&cmd, 0, sizeof(cmd)); - memset(&cmd2, 0, sizeof(cmd2)); - - cmd.m1 = in->awbMCFG[0]; - cmd.m2 = in->awbMCFG[1]; - cmd.m3 = in->awbMCFG[2]; - cmd.m4 = in->awbMCFG[3]; - cmd.c1 = in->awbCCFG[0]; - cmd.c2 = in->awbCCFG[1]; - cmd.c3 = in->awbCCFG[2]; - cmd.c4 = in->awbCCFG[3]; - vfe_prog_hw(ctrl->vfebase + VFE_STATS_AWB_MCFG, - (uint32_t *)&cmd, sizeof(cmd)); - - cmd2.aeRegionCfg = in->wbExpRegions; - cmd2.aeSubregionCfg = in->wbExpSubRegion; - cmd2.awbYMin = in->awbYMin; - cmd2.awbYMax = in->awbYMax; - vfe_prog_hw(ctrl->vfebase + VFE_STATS_AWBAE_CFG, - (uint32_t *)&cmd2, sizeof(cmd2)); -} - -void vfe_stats_update_af(struct vfe_cmd_stats_af_update *in) -{ - struct vfe_statsaf_update cmd; - memset(&cmd, 0, sizeof(cmd)); - - cmd.windowVOffset = in->windowVOffset; - cmd.windowHOffset = in->windowHOffset; - cmd.windowMode = in->windowMode; - cmd.windowHeight = in->windowHeight; - cmd.windowWidth = in->windowWidth; - - vfe_prog_hw(ctrl->vfebase + VFE_STATS_AF_CFG, - (uint32_t *)&cmd, sizeof(cmd)); -} - -void vfe_stats_start_wb_exp(struct vfe_cmd_stats_wb_exp_start *in) -{ - struct vfe_statsawb_update cmd; - struct vfe_statsawbae_update cmd2; - struct vfe_statsaxw_hdr_cfg cmd3; - - ctrl->vfeStatsCmdLocal.axwEnable = in->enable; - ctrl->vfeImaskLocal.awbPingpongIrq = TRUE; - - memset(&cmd, 0, sizeof(cmd)); - memset(&cmd2, 0, sizeof(cmd2)); - memset(&cmd3, 0, sizeof(cmd3)); - - cmd.m1 = in->awbMCFG[0]; - cmd.m2 = in->awbMCFG[1]; - cmd.m3 = in->awbMCFG[2]; - cmd.m4 = in->awbMCFG[3]; - cmd.c1 = in->awbCCFG[0]; - cmd.c2 = in->awbCCFG[1]; - cmd.c3 = in->awbCCFG[2]; - cmd.c4 = in->awbCCFG[3]; - vfe_prog_hw(ctrl->vfebase + VFE_STATS_AWB_MCFG, - (uint32_t *)&cmd, sizeof(cmd)); - - cmd2.aeRegionCfg = in->wbExpRegions; - cmd2.aeSubregionCfg = in->wbExpSubRegion; - cmd2.awbYMin = in->awbYMin; - cmd2.awbYMax = in->awbYMax; - vfe_prog_hw(ctrl->vfebase + VFE_STATS_AWBAE_CFG, - (uint32_t *)&cmd2, sizeof(cmd2)); - - cmd3.axwHeader = in->axwHeader; - vfe_prog_hw(ctrl->vfebase + VFE_STATS_AXW_HEADER, - (uint32_t *)&cmd3, sizeof(cmd3)); -} - -void vfe_stats_start_af(struct vfe_cmd_stats_af_start *in) -{ - struct vfe_statsaf_update cmd; - struct vfe_statsaf_cfg cmd2; - - memset(&cmd, 0, sizeof(cmd)); - memset(&cmd2, 0, sizeof(cmd2)); - -ctrl->vfeStatsCmdLocal.autoFocusEnable = in->enable; -ctrl->vfeImaskLocal.afPingpongIrq = TRUE; - - cmd.windowVOffset = in->windowVOffset; - cmd.windowHOffset = in->windowHOffset; - cmd.windowMode = in->windowMode; - cmd.windowHeight = in->windowHeight; - cmd.windowWidth = in->windowWidth; - - vfe_prog_hw(ctrl->vfebase + VFE_STATS_AF_CFG, - (uint32_t *)&cmd, sizeof(cmd)); - - cmd2.a00 = in->highPassCoef[0]; - cmd2.a04 = in->highPassCoef[1]; - cmd2.a20 = in->highPassCoef[2]; - cmd2.a21 = in->highPassCoef[3]; - cmd2.a22 = in->highPassCoef[4]; - cmd2.a23 = in->highPassCoef[5]; - cmd2.a24 = in->highPassCoef[6]; - cmd2.fvMax = in->metricMax; - cmd2.fvMetric = in->metricSelection; - cmd2.afHeader = in->bufferHeader; - cmd2.entry00 = in->gridForMultiWindows[0]; - cmd2.entry01 = in->gridForMultiWindows[1]; - cmd2.entry02 = in->gridForMultiWindows[2]; - cmd2.entry03 = in->gridForMultiWindows[3]; - cmd2.entry10 = in->gridForMultiWindows[4]; - cmd2.entry11 = in->gridForMultiWindows[5]; - cmd2.entry12 = in->gridForMultiWindows[6]; - cmd2.entry13 = in->gridForMultiWindows[7]; - cmd2.entry20 = in->gridForMultiWindows[8]; - cmd2.entry21 = in->gridForMultiWindows[9]; - cmd2.entry22 = in->gridForMultiWindows[10]; - cmd2.entry23 = in->gridForMultiWindows[11]; - cmd2.entry30 = in->gridForMultiWindows[12]; - cmd2.entry31 = in->gridForMultiWindows[13]; - cmd2.entry32 = in->gridForMultiWindows[14]; - cmd2.entry33 = in->gridForMultiWindows[15]; - - vfe_prog_hw(ctrl->vfebase + VFE_STATS_AF_GRID_0, - (uint32_t *)&cmd2, sizeof(cmd2)); -} - -void vfe_stats_setting(struct vfe_cmd_stats_setting *in) -{ - struct vfe_statsframe cmd1; - struct vfe_busstats_wrprio cmd2; - - memset(&cmd1, 0, sizeof(cmd1)); - memset(&cmd2, 0, sizeof(cmd2)); - - ctrl->afStatsControl.addressBuffer[0] = in->afBuffer[0]; - ctrl->afStatsControl.addressBuffer[1] = in->afBuffer[1]; - ctrl->afStatsControl.nextFrameAddrBuf = in->afBuffer[2]; - - ctrl->awbStatsControl.addressBuffer[0] = in->awbBuffer[0]; - ctrl->awbStatsControl.addressBuffer[1] = in->awbBuffer[1]; - ctrl->awbStatsControl.nextFrameAddrBuf = in->awbBuffer[2]; - - cmd1.lastPixel = in->frameHDimension; - cmd1.lastLine = in->frameVDimension; - vfe_prog_hw(ctrl->vfebase + VFE_STATS_FRAME_SIZE, - (uint32_t *)&cmd1, sizeof(cmd1)); - - cmd2.afBusPriority = in->afBusPriority; - cmd2.awbBusPriority = in->awbBusPriority; - cmd2.histBusPriority = in->histBusPriority; - cmd2.afBusPriorityEn = in->afBusPrioritySelection; - cmd2.awbBusPriorityEn = in->awbBusPrioritySelection; - cmd2.histBusPriorityEn = in->histBusPrioritySelection; - - vfe_prog_hw(ctrl->vfebase + VFE_BUS_STATS_WR_PRIORITY, - (uint32_t *)&cmd2, sizeof(cmd2)); - - /* Program the bus ping pong address for statistics modules. */ - writel(in->afBuffer[0], ctrl->vfebase + VFE_BUS_STATS_AF_WR_PING_ADDR); - writel(in->afBuffer[1], ctrl->vfebase + VFE_BUS_STATS_AF_WR_PONG_ADDR); - writel(in->awbBuffer[0], - ctrl->vfebase + VFE_BUS_STATS_AWB_WR_PING_ADDR); - writel(in->awbBuffer[1], - ctrl->vfebase + VFE_BUS_STATS_AWB_WR_PONG_ADDR); - writel(in->histBuffer[0], - ctrl->vfebase + VFE_BUS_STATS_HIST_WR_PING_ADDR); - writel(in->histBuffer[1], - ctrl->vfebase + VFE_BUS_STATS_HIST_WR_PONG_ADDR); -} - -void vfe_axi_input_config(struct vfe_cmd_axi_input_config *in) -{ - struct VFE_AxiInputCmdType cmd; - uint32_t xSizeWord, axiRdUnpackPattern; - uint8_t axiInputPpw; - uint32_t busPingpongRdIrqEnable; - - ctrl->vfeImaskLocal.rdPingpongIrq = TRUE; - - switch (in->pixelSize) { - case VFE_RAW_PIXEL_DATA_SIZE_10BIT: - ctrl->axiInputDataSize = VFE_RAW_PIXEL_DATA_SIZE_10BIT; - break; - - case VFE_RAW_PIXEL_DATA_SIZE_12BIT: - ctrl->axiInputDataSize = VFE_RAW_PIXEL_DATA_SIZE_12BIT; - break; - - case VFE_RAW_PIXEL_DATA_SIZE_8BIT: - default: - ctrl->axiInputDataSize = VFE_RAW_PIXEL_DATA_SIZE_8BIT; - break; - } - - memset(&cmd, 0, sizeof(cmd)); - - switch (in->pixelSize) { - case VFE_RAW_PIXEL_DATA_SIZE_10BIT: - axiInputPpw = 6; - axiRdUnpackPattern = 0xD43210; - break; - - case VFE_RAW_PIXEL_DATA_SIZE_12BIT: - axiInputPpw = 5; - axiRdUnpackPattern = 0xC3210; - break; - - case VFE_RAW_PIXEL_DATA_SIZE_8BIT: - default: - axiInputPpw = 8; - axiRdUnpackPattern = 0xF6543210; - break; - } - - xSizeWord = - ((((in->xOffset % axiInputPpw) + in->xSize) + - (axiInputPpw-1)) / axiInputPpw) - 1; - - cmd.stripeStartAddr0 = in->fragAddr[0]; - cmd.stripeStartAddr1 = in->fragAddr[1]; - cmd.stripeStartAddr2 = in->fragAddr[2]; - cmd.stripeStartAddr3 = in->fragAddr[3]; - cmd.ySize = in->ySize; - cmd.yOffsetDelta = 0; - cmd.xSizeWord = xSizeWord; - cmd.burstLength = 1; - cmd.NumOfRows = in->numOfRows; - cmd.RowIncrement = - (in->rowIncrement + (axiInputPpw-1))/axiInputPpw; - cmd.mainUnpackHeight = in->ySize; - cmd.mainUnpackWidth = in->xSize - 1; - cmd.mainUnpackHbiSel = (uint32_t)in->unpackHbi; - cmd.mainUnpackPhase = in->unpackPhase; - cmd.unpackPattern = axiRdUnpackPattern; - cmd.padLeft = in->padRepeatCountLeft; - cmd.padRight = in->padRepeatCountRight; - cmd.padTop = in->padRepeatCountTop; - cmd.padBottom = in->padRepeatCountBottom; - cmd.leftUnpackPattern0 = in->padLeftComponentSelectCycle0; - cmd.leftUnpackPattern1 = in->padLeftComponentSelectCycle1; - cmd.leftUnpackPattern2 = in->padLeftComponentSelectCycle2; - cmd.leftUnpackPattern3 = in->padLeftComponentSelectCycle3; - cmd.leftUnpackStop0 = in->padLeftStopCycle0; - cmd.leftUnpackStop1 = in->padLeftStopCycle1; - cmd.leftUnpackStop2 = in->padLeftStopCycle2; - cmd.leftUnpackStop3 = in->padLeftStopCycle3; - cmd.rightUnpackPattern0 = in->padRightComponentSelectCycle0; - cmd.rightUnpackPattern1 = in->padRightComponentSelectCycle1; - cmd.rightUnpackPattern2 = in->padRightComponentSelectCycle2; - cmd.rightUnpackPattern3 = in->padRightComponentSelectCycle3; - cmd.rightUnpackStop0 = in->padRightStopCycle0; - cmd.rightUnpackStop1 = in->padRightStopCycle1; - cmd.rightUnpackStop2 = in->padRightStopCycle2; - cmd.rightUnpackStop3 = in->padRightStopCycle3; - cmd.topUnapckPattern = in->padTopLineCount; - cmd.bottomUnapckPattern = in->padBottomLineCount; - - /* program vfe_bus_cfg */ - vfe_prog_hw(ctrl->vfebase + VFE_BUS_STRIPE_RD_ADDR_0, - (uint32_t *)&cmd, sizeof(cmd)); - - /* hacking code, put it to default value */ - busPingpongRdIrqEnable = 0xf; - - writel(busPingpongRdIrqEnable, - ctrl->vfebase + VFE_BUS_PINGPONG_IRQ_EN); -} - -void vfe_stats_config(struct vfe_cmd_stats_setting *in) -{ - ctrl->afStatsControl.addressBuffer[0] = in->afBuffer[0]; - ctrl->afStatsControl.addressBuffer[1] = in->afBuffer[1]; - ctrl->afStatsControl.nextFrameAddrBuf = in->afBuffer[2]; - - ctrl->awbStatsControl.addressBuffer[0] = in->awbBuffer[0]; - ctrl->awbStatsControl.addressBuffer[1] = in->awbBuffer[1]; - ctrl->awbStatsControl.nextFrameAddrBuf = in->awbBuffer[2]; - - vfe_stats_setting(in); -} - -void vfe_axi_output_config( - struct vfe_cmd_axi_output_config *in) -{ - /* local variable */ - uint32_t *pcircle; - uint32_t *pdest; - uint32_t *psrc; - uint8_t i; - uint8_t fcnt; - uint16_t axioutpw = 8; - - /* parameters check, condition and usage mode check */ - ctrl->encPath.fragCount = in->output2.fragmentCount; - if (ctrl->encPath.fragCount > 1) - ctrl->encPath.multiFrag = TRUE; - - ctrl->viewPath.fragCount = in->output1.fragmentCount; - if (ctrl->viewPath.fragCount > 1) - ctrl->viewPath.multiFrag = TRUE; - - /* VFE_BUS_CFG. raw data size */ - ctrl->vfeBusConfigLocal.rawPixelDataSize = in->outputDataSize; - - switch (in->outputDataSize) { - case VFE_RAW_PIXEL_DATA_SIZE_8BIT: - axioutpw = 8; - break; - - case VFE_RAW_PIXEL_DATA_SIZE_10BIT: - axioutpw = 6; - break; - - case VFE_RAW_PIXEL_DATA_SIZE_12BIT: - axioutpw = 5; - break; - } - - ctrl->axiOutputMode = in->outputMode; - - CDBG("axiOutputMode = %d\n", ctrl->axiOutputMode); - - switch (ctrl->axiOutputMode) { - case VFE_AXI_OUTPUT_MODE_Output1: { - ctrl->vfeCamifConfigLocal.camif2BusEnable = FALSE; - ctrl->vfeCamifConfigLocal.camif2OutputEnable = TRUE; - ctrl->vfeBusConfigLocal.rawWritePathSelect = - VFE_RAW_OUTPUT_DISABLED; - - ctrl->encPath.pathEnabled = FALSE; - ctrl->vfeImaskLocal.encIrq = FALSE; - ctrl->vfeIrqCompositeMaskLocal.encIrqComMask = - VFE_COMP_IRQ_BOTH_Y_CBCR; - - ctrl->vfeBusConfigLocal.encYWrPathEn = FALSE; - ctrl->vfeBusConfigLocal.encCbcrWrPathEn = FALSE; - ctrl->viewPath.pathEnabled = TRUE; - ctrl->vfeImaskLocal.viewIrq = TRUE; - ctrl->vfeIrqCompositeMaskLocal.viewIrqComMask = - VFE_COMP_IRQ_BOTH_Y_CBCR; - - ctrl->vfeBusConfigLocal.viewYWrPathEn = TRUE; - ctrl->vfeBusConfigLocal.viewCbcrWrPathEn = TRUE; - - if (ctrl->vfeBusConfigLocal.encYWrPathEn && - ctrl->encPath.multiFrag) - ctrl->vfeImaskLocal.encYPingpongIrq = TRUE; - - if (ctrl->vfeBusConfigLocal.encCbcrWrPathEn && - ctrl->encPath.multiFrag) - ctrl->vfeImaskLocal.encCbcrPingpongIrq = TRUE; - - if (ctrl->vfeBusConfigLocal.viewYWrPathEn && - ctrl->viewPath.multiFrag) - ctrl->vfeImaskLocal.viewYPingpongIrq = TRUE; - - if (ctrl->vfeBusConfigLocal.viewCbcrWrPathEn && - ctrl->viewPath.multiFrag) - ctrl->vfeImaskLocal.viewCbcrPingpongIrq = TRUE; - } /* VFE_AXI_OUTPUT_MODE_Output1 */ - break; - - case VFE_AXI_OUTPUT_MODE_Output2: { - ctrl->vfeCamifConfigLocal.camif2BusEnable = FALSE; - ctrl->vfeCamifConfigLocal.camif2OutputEnable = TRUE; - ctrl->vfeBusConfigLocal.rawWritePathSelect = - VFE_RAW_OUTPUT_DISABLED; - - ctrl->encPath.pathEnabled = TRUE; - ctrl->vfeImaskLocal.encIrq = TRUE; - ctrl->vfeIrqCompositeMaskLocal.encIrqComMask = - VFE_COMP_IRQ_BOTH_Y_CBCR; - - ctrl->vfeBusConfigLocal.encYWrPathEn = TRUE; - ctrl->vfeBusConfigLocal.encCbcrWrPathEn = TRUE; - - ctrl->viewPath.pathEnabled = FALSE; - ctrl->vfeImaskLocal.viewIrq = FALSE; - ctrl->vfeIrqCompositeMaskLocal.viewIrqComMask = - VFE_COMP_IRQ_BOTH_Y_CBCR; - - ctrl->vfeBusConfigLocal.viewYWrPathEn = FALSE; - ctrl->vfeBusConfigLocal.viewCbcrWrPathEn = FALSE; - - if (ctrl->vfeBusConfigLocal.encYWrPathEn && - ctrl->encPath.multiFrag) - ctrl->vfeImaskLocal.encYPingpongIrq = TRUE; - - if (ctrl->vfeBusConfigLocal.encCbcrWrPathEn && - ctrl->encPath.multiFrag) - ctrl->vfeImaskLocal.encCbcrPingpongIrq = TRUE; - - if (ctrl->vfeBusConfigLocal.viewYWrPathEn && - ctrl->viewPath.multiFrag) - ctrl->vfeImaskLocal.viewYPingpongIrq = TRUE; - - if (ctrl->vfeBusConfigLocal.viewCbcrWrPathEn && - ctrl->viewPath.multiFrag) - ctrl->vfeImaskLocal.viewCbcrPingpongIrq = TRUE; - } /* VFE_AXI_OUTPUT_MODE_Output2 */ - break; - - case VFE_AXI_OUTPUT_MODE_Output1AndOutput2: { - ctrl->vfeCamifConfigLocal.camif2BusEnable = FALSE; - ctrl->vfeCamifConfigLocal.camif2OutputEnable = TRUE; - ctrl->vfeBusConfigLocal.rawWritePathSelect = - VFE_RAW_OUTPUT_DISABLED; - - ctrl->encPath.pathEnabled = TRUE; - ctrl->vfeImaskLocal.encIrq = TRUE; - ctrl->vfeIrqCompositeMaskLocal.encIrqComMask = - VFE_COMP_IRQ_BOTH_Y_CBCR; - - ctrl->vfeBusConfigLocal.encYWrPathEn = TRUE; - ctrl->vfeBusConfigLocal.encCbcrWrPathEn = TRUE; - ctrl->viewPath.pathEnabled = TRUE; - ctrl->vfeImaskLocal.viewIrq = TRUE; - ctrl->vfeIrqCompositeMaskLocal.viewIrqComMask = - VFE_COMP_IRQ_BOTH_Y_CBCR; - - ctrl->vfeBusConfigLocal.viewYWrPathEn = TRUE; - ctrl->vfeBusConfigLocal.viewCbcrWrPathEn = TRUE; - - if (ctrl->vfeBusConfigLocal.encYWrPathEn && - ctrl->encPath.multiFrag) - ctrl->vfeImaskLocal.encYPingpongIrq = TRUE; - - if (ctrl->vfeBusConfigLocal.encCbcrWrPathEn && - ctrl->encPath.multiFrag) - ctrl->vfeImaskLocal.encCbcrPingpongIrq = TRUE; - - if (ctrl->vfeBusConfigLocal.viewYWrPathEn && - ctrl->viewPath.multiFrag) - ctrl->vfeImaskLocal.viewYPingpongIrq = TRUE; - - if (ctrl->vfeBusConfigLocal.viewCbcrWrPathEn && - ctrl->viewPath.multiFrag) - ctrl->vfeImaskLocal.viewCbcrPingpongIrq = TRUE; - } /* VFE_AXI_OUTPUT_MODE_Output1AndOutput2 */ - break; - - case VFE_AXI_OUTPUT_MODE_CAMIFToAXIViaOutput2: { - /* For raw snapshot, we need both ping and pong buffer - * initialized to the same address. Otherwise, if we - * leave the pong buffer to NULL, there will be axi_error. - * Note that ideally we should deal with this at upper layer, - * which is in msm_vfe8x.c */ - if (!in->output2.outputCbcr.outFragments[1][0]) { - in->output2.outputCbcr.outFragments[1][0] = - in->output2.outputCbcr.outFragments[0][0]; - } - - ctrl->vfeCamifConfigLocal.camif2BusEnable = TRUE; - ctrl->vfeCamifConfigLocal.camif2OutputEnable = FALSE; - ctrl->vfeBusConfigLocal.rawWritePathSelect = - VFE_RAW_OUTPUT_ENC_CBCR_PATH; - - ctrl->encPath.pathEnabled = TRUE; - ctrl->vfeImaskLocal.encIrq = TRUE; - ctrl->vfeIrqCompositeMaskLocal.encIrqComMask = - VFE_COMP_IRQ_CBCR_ONLY; - - ctrl->vfeBusConfigLocal.encYWrPathEn = FALSE; - ctrl->vfeBusConfigLocal.encCbcrWrPathEn = TRUE; - - ctrl->viewPath.pathEnabled = FALSE; - ctrl->vfeImaskLocal.viewIrq = FALSE; - ctrl->vfeIrqCompositeMaskLocal.viewIrqComMask = - VFE_COMP_IRQ_BOTH_Y_CBCR; - - ctrl->vfeBusConfigLocal.viewYWrPathEn = FALSE; - ctrl->vfeBusConfigLocal.viewCbcrWrPathEn = FALSE; - - if (ctrl->vfeBusConfigLocal.encYWrPathEn && - ctrl->encPath.multiFrag) - ctrl->vfeImaskLocal.encYPingpongIrq = TRUE; - - if (ctrl->vfeBusConfigLocal.encCbcrWrPathEn && - ctrl->encPath.multiFrag) - ctrl->vfeImaskLocal.encCbcrPingpongIrq = TRUE; - - if (ctrl->vfeBusConfigLocal.viewYWrPathEn && - ctrl->viewPath.multiFrag) - ctrl->vfeImaskLocal.viewYPingpongIrq = TRUE; - - if (ctrl->vfeBusConfigLocal.viewCbcrWrPathEn && - ctrl->viewPath.multiFrag) - ctrl->vfeImaskLocal.viewCbcrPingpongIrq = TRUE; - } /* VFE_AXI_OUTPUT_MODE_CAMIFToAXIViaOutput2 */ - break; - - case VFE_AXI_OUTPUT_MODE_Output2AndCAMIFToAXIViaOutput1: { - ctrl->vfeCamifConfigLocal.camif2BusEnable = TRUE; - ctrl->vfeCamifConfigLocal.camif2OutputEnable = TRUE; - ctrl->vfeBusConfigLocal.rawWritePathSelect = - VFE_RAW_OUTPUT_VIEW_CBCR_PATH; - - ctrl->encPath.pathEnabled = TRUE; - ctrl->vfeImaskLocal.encIrq = TRUE; - ctrl->vfeIrqCompositeMaskLocal.encIrqComMask = - VFE_COMP_IRQ_BOTH_Y_CBCR; - - ctrl->vfeBusConfigLocal.encYWrPathEn = TRUE; - ctrl->vfeBusConfigLocal.encCbcrWrPathEn = TRUE; - - ctrl->viewPath.pathEnabled = TRUE; - ctrl->vfeImaskLocal.viewIrq = TRUE; - ctrl->vfeIrqCompositeMaskLocal.viewIrqComMask = - VFE_COMP_IRQ_CBCR_ONLY; - - ctrl->vfeBusConfigLocal.viewYWrPathEn = FALSE; - ctrl->vfeBusConfigLocal.viewCbcrWrPathEn = TRUE; - - if (ctrl->vfeBusConfigLocal.encYWrPathEn && - ctrl->encPath.multiFrag) - ctrl->vfeImaskLocal.encYPingpongIrq = TRUE; - - if (ctrl->vfeBusConfigLocal.encCbcrWrPathEn && - ctrl->encPath.multiFrag) - ctrl->vfeImaskLocal.encCbcrPingpongIrq = TRUE; - - if (ctrl->vfeBusConfigLocal.viewYWrPathEn && - ctrl->viewPath.multiFrag) - ctrl->vfeImaskLocal.viewYPingpongIrq = TRUE; - - if (ctrl->vfeBusConfigLocal.viewCbcrWrPathEn && - ctrl->viewPath.multiFrag) - ctrl->vfeImaskLocal.viewCbcrPingpongIrq = TRUE; - } /* VFE_AXI_OUTPUT_MODE_Output2AndCAMIFToAXIViaOutput1 */ - break; - - case VFE_AXI_OUTPUT_MODE_Output1AndCAMIFToAXIViaOutput2: { - ctrl->vfeCamifConfigLocal.camif2BusEnable = TRUE; - ctrl->vfeCamifConfigLocal.camif2OutputEnable = TRUE; - ctrl->vfeBusConfigLocal.rawWritePathSelect = - VFE_RAW_OUTPUT_ENC_CBCR_PATH; - - ctrl->encPath.pathEnabled = TRUE; - ctrl->vfeImaskLocal.encIrq = TRUE; - ctrl->vfeIrqCompositeMaskLocal.encIrqComMask = - VFE_COMP_IRQ_CBCR_ONLY; - - ctrl->vfeBusConfigLocal.encYWrPathEn = FALSE; - ctrl->vfeBusConfigLocal.encCbcrWrPathEn = TRUE; - - ctrl->viewPath.pathEnabled = TRUE; - ctrl->vfeImaskLocal.viewIrq = TRUE; - - ctrl->vfeIrqCompositeMaskLocal.viewIrqComMask = - VFE_COMP_IRQ_BOTH_Y_CBCR; - - ctrl->vfeBusConfigLocal.viewYWrPathEn = TRUE; - ctrl->vfeBusConfigLocal.viewCbcrWrPathEn = TRUE; - - if (ctrl->vfeBusConfigLocal.encYWrPathEn && - ctrl->encPath.multiFrag) - ctrl->vfeImaskLocal.encYPingpongIrq = TRUE; - - if (ctrl->vfeBusConfigLocal.encCbcrWrPathEn && - ctrl->encPath.multiFrag) - ctrl->vfeImaskLocal.encCbcrPingpongIrq = TRUE; - - if (ctrl->vfeBusConfigLocal.viewYWrPathEn && - ctrl->viewPath.multiFrag) - ctrl->vfeImaskLocal.viewYPingpongIrq = TRUE; - - if (ctrl->vfeBusConfigLocal.viewCbcrWrPathEn && - ctrl->viewPath.multiFrag) - ctrl->vfeImaskLocal.viewCbcrPingpongIrq = TRUE; - } /* VFE_AXI_OUTPUT_MODE_Output1AndCAMIFToAXIViaOutput2 */ - break; - - case VFE_AXI_LAST_OUTPUT_MODE_ENUM: - break; - } /* switch */ - - /* Save the addresses for each path. */ - /* output2 path */ - fcnt = ctrl->encPath.fragCount; - - pcircle = ctrl->encPath.yPath.addressBuffer; - pdest = ctrl->encPath.nextFrameAddrBuf; - - psrc = &(in->output2.outputY.outFragments[0][0]); - for (i = 0; i < fcnt; i++) - *pcircle++ = *psrc++; - - psrc = &(in->output2.outputY.outFragments[1][0]); - for (i = 0; i < fcnt; i++) - *pcircle++ = *psrc++; - - psrc = &(in->output2.outputY.outFragments[2][0]); - for (i = 0; i < fcnt; i++) - *pdest++ = *psrc++; - - pcircle = ctrl->encPath.cbcrPath.addressBuffer; - - psrc = &(in->output2.outputCbcr.outFragments[0][0]); - for (i = 0; i < fcnt; i++) - *pcircle++ = *psrc++; - - psrc = &(in->output2.outputCbcr.outFragments[1][0]); - for (i = 0; i < fcnt; i++) - *pcircle++ = *psrc++; - - psrc = &(in->output2.outputCbcr.outFragments[2][0]); - for (i = 0; i < fcnt; i++) - *pdest++ = *psrc++; - - vfe_set_bus_pipo_addr(&ctrl->viewPath, &ctrl->encPath); - - ctrl->encPath.ackPending = FALSE; - ctrl->encPath.currentFrame = ping; - ctrl->encPath.whichOutputPath = 1; - ctrl->encPath.yPath.fragIndex = 2; - ctrl->encPath.cbcrPath.fragIndex = 2; - ctrl->encPath.yPath.hwCurrentFlag = ping; - ctrl->encPath.cbcrPath.hwCurrentFlag = ping; - - /* output1 path */ - pcircle = ctrl->viewPath.yPath.addressBuffer; - pdest = ctrl->viewPath.nextFrameAddrBuf; - fcnt = ctrl->viewPath.fragCount; - - psrc = &(in->output1.outputY.outFragments[0][0]); - for (i = 0; i < fcnt; i++) - *pcircle++ = *psrc++; - - psrc = &(in->output1.outputY.outFragments[1][0]); - for (i = 0; i < fcnt; i++) - *pcircle++ = *psrc++; - - psrc = &(in->output1.outputY.outFragments[2][0]); - for (i = 0; i < fcnt; i++) - *pdest++ = *psrc++; - - pcircle = ctrl->viewPath.cbcrPath.addressBuffer; - - psrc = &(in->output1.outputCbcr.outFragments[0][0]); - for (i = 0; i < fcnt; i++) - *pcircle++ = *psrc++; - - psrc = &(in->output1.outputCbcr.outFragments[1][0]); - for (i = 0; i < fcnt; i++) - *pcircle++ = *psrc++; - - psrc = &(in->output1.outputCbcr.outFragments[2][0]); - for (i = 0; i < fcnt; i++) - *pdest++ = *psrc++; - - ctrl->viewPath.ackPending = FALSE; - ctrl->viewPath.currentFrame = ping; - ctrl->viewPath.whichOutputPath = 0; - ctrl->viewPath.yPath.fragIndex = 2; - ctrl->viewPath.cbcrPath.fragIndex = 2; - ctrl->viewPath.yPath.hwCurrentFlag = ping; - ctrl->viewPath.cbcrPath.hwCurrentFlag = ping; - - /* call to program the registers. */ - vfe_axi_output(in, &ctrl->viewPath, &ctrl->encPath, axioutpw); -} - -void vfe_camif_config(struct vfe_cmd_camif_config *in) -{ - struct vfe_camifcfg cmd; - memset(&cmd, 0, sizeof(cmd)); - - CDBG("camif.frame pixelsPerLine = %d\n", in->frame.pixelsPerLine); - CDBG("camif.frame linesPerFrame = %d\n", in->frame.linesPerFrame); - CDBG("camif.window firstpixel = %d\n", in->window.firstpixel); - CDBG("camif.window lastpixel = %d\n", in->window.lastpixel); - CDBG("camif.window firstline = %d\n", in->window.firstline); - CDBG("camif.window lastline = %d\n", in->window.lastline); - - /* determine if epoch interrupt needs to be enabled. */ - if ((in->epoch1.enable == TRUE) && - (in->epoch1.lineindex <= - in->frame.linesPerFrame)) - ctrl->vfeImaskLocal.camifEpoch1Irq = 1; - - if ((in->epoch2.enable == TRUE) && - (in->epoch2.lineindex <= - in->frame.linesPerFrame)) { - ctrl->vfeImaskLocal.camifEpoch2Irq = 1; - } - - /* save the content to program CAMIF_CONFIG separately. */ - ctrl->vfeCamifConfigLocal.camifCfgFromCmd = in->camifConfig; - - /* EFS_Config */ - cmd.efsEndOfLine = in->EFS.efsendofline; - cmd.efsStartOfLine = in->EFS.efsstartofline; - cmd.efsEndOfFrame = in->EFS.efsendofframe; - cmd.efsStartOfFrame = in->EFS.efsstartofframe; - - /* Frame Config */ - cmd.frameConfigPixelsPerLine = in->frame.pixelsPerLine; - cmd.frameConfigLinesPerFrame = in->frame.linesPerFrame; - - /* Window Width Config */ - cmd.windowWidthCfgLastPixel = in->window.lastpixel; - cmd.windowWidthCfgFirstPixel = in->window.firstpixel; - - /* Window Height Config */ - cmd.windowHeightCfglastLine = in->window.lastline; - cmd.windowHeightCfgfirstLine = in->window.firstline; - - /* Subsample 1 Config */ - cmd.subsample1CfgPixelSkip = in->subsample.pixelskipmask; - cmd.subsample1CfgLineSkip = in->subsample.lineskipmask; - - /* Subsample 2 Config */ - cmd.subsample2CfgFrameSkip = in->subsample.frameskip; - cmd.subsample2CfgFrameSkipMode = in->subsample.frameskipmode; - cmd.subsample2CfgPixelSkipWrap = in->subsample.pixelskipwrap; - - /* Epoch Interrupt */ - cmd.epoch1Line = in->epoch1.lineindex; - cmd.epoch2Line = in->epoch2.lineindex; - - vfe_prog_hw(ctrl->vfebase + CAMIF_EFS_CONFIG, - (uint32_t *)&cmd, sizeof(cmd)); -} - -void vfe_fov_crop_config(struct vfe_cmd_fov_crop_config *in) -{ - struct vfe_fov_crop_cfg cmd; - memset(&cmd, 0, sizeof(cmd)); - - ctrl->vfeModuleEnableLocal.cropEnable = in->enable; - - /* FOV Corp, Part 1 */ - cmd.lastPixel = in->lastPixel; - cmd.firstPixel = in->firstPixel; - - /* FOV Corp, Part 2 */ - cmd.lastLine = in->lastLine; - cmd.firstLine = in->firstLine; - - vfe_prog_hw(ctrl->vfebase + VFE_CROP_WIDTH_CFG, - (uint32_t *)&cmd, sizeof(cmd)); -} - -void vfe_get_hw_version(struct vfe_cmd_hw_version *out) -{ - uint32_t vfeHwVersionPacked; - struct vfe_hw_ver ver; - - vfeHwVersionPacked = readl(ctrl->vfebase + VFE_HW_VERSION); - - ver = *((struct vfe_hw_ver *)&vfeHwVersionPacked); - - out->coreVersion = ver.coreVersion; - out->minorVersion = ver.minorVersion; - out->majorVersion = ver.majorVersion; -} - -static void vfe_reset_internal_variables(void) -{ - unsigned long flags; - - /* local variables to program the hardware. */ - ctrl->vfeImaskPacked = 0; - ctrl->vfeImaskCompositePacked = 0; - - /* FALSE = disable, 1 = enable. */ - memset(&ctrl->vfeModuleEnableLocal, 0, - sizeof(ctrl->vfeModuleEnableLocal)); - - /* 0 = disable, 1 = enable */ - memset(&ctrl->vfeCamifConfigLocal, 0, - sizeof(ctrl->vfeCamifConfigLocal)); - /* 0 = disable, 1 = enable */ - memset(&ctrl->vfeImaskLocal, 0, sizeof(ctrl->vfeImaskLocal)); - memset(&ctrl->vfeStatsCmdLocal, 0, sizeof(ctrl->vfeStatsCmdLocal)); - memset(&ctrl->vfeBusConfigLocal, 0, sizeof(ctrl->vfeBusConfigLocal)); - memset(&ctrl->vfeBusPmConfigLocal, 0, - sizeof(ctrl->vfeBusPmConfigLocal)); - memset(&ctrl->vfeBusCmdLocal, 0, sizeof(ctrl->vfeBusCmdLocal)); - memset(&ctrl->vfeInterruptNameLocal, 0, - sizeof(ctrl->vfeInterruptNameLocal)); - memset(&ctrl->vfeDroppedFrameCounts, 0, - sizeof(ctrl->vfeDroppedFrameCounts)); - memset(&ctrl->vfeIrqThreadMsgLocal, 0, - sizeof(ctrl->vfeIrqThreadMsgLocal)); - - /* state control variables */ - ctrl->vfeStartAckPendingFlag = FALSE; - ctrl->vfeStopAckPending = FALSE; - ctrl->vfeIrqCompositeMaskLocal.ceDoneSel = 0; - ctrl->vfeIrqCompositeMaskLocal.encIrqComMask = - VFE_COMP_IRQ_BOTH_Y_CBCR; - ctrl->vfeIrqCompositeMaskLocal.viewIrqComMask = - VFE_COMP_IRQ_BOTH_Y_CBCR; - - spin_lock_irqsave(&ctrl->state_lock, flags); - ctrl->vstate = VFE_STATE_IDLE; - spin_unlock_irqrestore(&ctrl->state_lock, flags); - - ctrl->axiOutputMode = VFE_AXI_LAST_OUTPUT_MODE_ENUM; - /* 0 for continuous mode, 1 for snapshot mode */ - ctrl->vfeOperationMode = VFE_START_OPERATION_MODE_CONTINUOUS; - ctrl->vfeSnapShotCount = 0; - ctrl->vfeStatsPingPongReloadFlag = FALSE; - /* this is unsigned 32 bit integer. */ - ctrl->vfeFrameId = 0; - ctrl->vfeFrameSkip.output1Pattern = 0xffffffff; - ctrl->vfeFrameSkip.output1Period = 31; - ctrl->vfeFrameSkip.output2Pattern = 0xffffffff; - ctrl->vfeFrameSkip.output2Period = 31; - ctrl->vfeFrameSkipPattern = 0xffffffff; - ctrl->vfeFrameSkipCount = 0; - ctrl->vfeFrameSkipPeriod = 31; - - memset((void *)&ctrl->encPath, 0, sizeof(ctrl->encPath)); - memset((void *)&ctrl->viewPath, 0, sizeof(ctrl->viewPath)); - - ctrl->encPath.whichOutputPath = 1; - ctrl->encPath.cbcrStatusBit = 5; - ctrl->viewPath.whichOutputPath = 0; - ctrl->viewPath.cbcrStatusBit = 7; - - ctrl->vfeTestGenStartFlag = FALSE; - - /* default to bank 0. */ - ctrl->vfeLaBankSel = 0; - - /* default to bank 0 for all channels. */ - memset(&ctrl->vfeGammaLutSel, 0, sizeof(ctrl->vfeGammaLutSel)); - - /* Stats control variables. */ - memset(&ctrl->afStatsControl, 0, sizeof(ctrl->afStatsControl)); - memset(&ctrl->awbStatsControl, 0, sizeof(ctrl->awbStatsControl)); - vfe_set_stats_pingpong_address(&ctrl->afStatsControl, - &ctrl->awbStatsControl); -} - -void vfe_reset(void) -{ - vfe_reset_internal_variables(); - - ctrl->vfeImaskLocal.resetAckIrq = TRUE; - ctrl->vfeImaskPacked = vfe_irq_pack(ctrl->vfeImaskLocal); - - /* disable all interrupts. */ - writel(VFE_DISABLE_ALL_IRQS, - ctrl->vfebase + VFE_IRQ_COMPOSITE_MASK); - - /* clear all pending interrupts*/ - writel(VFE_CLEAR_ALL_IRQS, - ctrl->vfebase + VFE_IRQ_CLEAR); - - /* enable reset_ack interrupt. */ - writel(ctrl->vfeImaskPacked, - ctrl->vfebase + VFE_IRQ_MASK); - - writel(VFE_RESET_UPON_RESET_CMD, - ctrl->vfebase + VFE_GLOBAL_RESET_CMD); -} |