/** * ispccdc_try_size - Checks if requested Input/output dimensions are valid * @input_w: input width for the CCDC in number of pixels per line * @input_h: input height for the CCDC in number of lines * @output_w: output width from the CCDC in number of pixels per line * @output_h: output height for the CCDC in number of lines * * Calculates the number of pixels cropped if the reformater is disabled, * Fills up the output width and height variables in the isp_ccdc structure. * * Returns 0 if successful, or -EINVAL if the input width is less than 2 pixels **/ int ispccdc_try_size(u32 input_w, u32 input_h, u32 *output_w, u32 *output_h) { if (input_w < 32 || input_h < 32) { DPRINTK_ISPCCDC("ISP_ERR: CCDC cannot handle input width less" " than 32 pixels or height less than 32\n"); return -EINVAL; } if (ispccdc_obj.crop_w) *output_w = ispccdc_obj.crop_w; else *output_w = input_w; if (ispccdc_obj.crop_h) *output_h = ispccdc_obj.crop_h; else *output_h = input_h; if (!ispccdc_obj.refmt_en && ispccdc_obj.ccdc_outfmt != CCDC_OTHERS_MEM && ispccdc_obj.ccdc_outfmt != CCDC_OTHERS_VP_MEM) *output_h -= 1; if (ispccdc_obj.ccdc_outfmt == CCDC_OTHERS_VP) { *output_h -= ispccdc_obj.ccdcin_hoffset; *output_w -= ispccdc_obj.ccdcin_woffset; *output_h &= 0xFFFFFFFE; *output_w &= 0xFFFFFFFE; } if (ispccdc_obj.ccdc_outfmt == CCDC_OTHERS_MEM || ispccdc_obj.ccdc_outfmt == CCDC_OTHERS_VP_MEM) { if (*output_w % 16) { *output_w -= (*output_w % 16); *output_w += 16; } } ispccdc_obj.ccdcout_w = *output_w; ispccdc_obj.ccdcout_h = *output_h; ispccdc_obj.ccdcin_w = input_w; ispccdc_obj.ccdcin_h = input_h; DPRINTK_ISPCCDC("try size: ccdcin_w=%u,ccdcin_h=%u,ccdcout_w=%u," " ccdcout_h=%u\n", ispccdc_obj.ccdcin_w, ispccdc_obj.ccdcin_h, ispccdc_obj.ccdcout_w, ispccdc_obj.ccdcout_h); return 0; }
/** * ispccdc_set_outaddr - Sets the memory address where the output will be saved * @addr: 32-bit memory address aligned on 32 byte boundary. * * Sets the memory address where the output will be saved. * * Returns 0 if successful, or -EINVAL if the address is not in the 32 byte * boundary. **/ int ispccdc_set_outaddr(u32 addr) { if ((addr & ISP_32B_BOUNDARY_BUF) == addr) { isp_reg_writel(addr, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SDR_ADDR); return 0; } else { DPRINTK_ISPCCDC("ISP_ERR : Address should be in 32 byte" " boundary\n"); return -EINVAL; } }
/** * ispccdc_config_crop - Configures crop parameters for the ISP CCDC. * @left: Left offset of the crop area. * @top: Top offset of the crop area. * @height: Height of the crop area. * @width: Width of the crop area. * * The following restrictions are applied for the crop settings. If incoming * values do not follow these restrictions then we map the settings to the * closest acceptable crop value. * 1) Left offset is always odd. This can be avoided if we enable byte swap * option for incoming data into CCDC. * 2) Top offset is always even. * 3) Crop height is always even. * 4) Crop width is always a multiple of 16 pixels **/ void ispccdc_config_crop(u32 left, u32 top, u32 height, u32 width) { ispccdc_obj.ccdcin_woffset = left + (left % 2); ispccdc_obj.ccdcin_hoffset = top + (top % 2); ispccdc_obj.crop_w = width - (width % 16); ispccdc_obj.crop_h = height + (height % 2); DPRINTK_ISPCCDC("\n\tOffsets L %d T %d W %d H %d\n", ispccdc_obj.ccdcin_woffset, ispccdc_obj.ccdcin_hoffset, ispccdc_obj.crop_w, ispccdc_obj.crop_h); }
/** * ispccdc_free - Frees the CCDC module. * * Frees the CCDC module so it can be used by another process. * * Returns 0 if successful, or -EINVAL if module has been already freed. **/ int ispccdc_free(void) { mutex_lock(&ispccdc_obj.mutexlock); if (!ispccdc_obj.ccdc_inuse) { mutex_unlock(&ispccdc_obj.mutexlock); DPRINTK_ISPCCDC("ISP_ERR: CCDC Module already freed\n"); return -EINVAL; } ispccdc_obj.ccdc_inuse = 0; mutex_unlock(&ispccdc_obj.mutexlock); isp_reg_and(OMAP3_ISP_IOMEM_MAIN, ISP_CTRL, ~(ISPCTRL_CCDC_CLK_EN | ISPCTRL_CCDC_RAM_EN | ISPCTRL_SBL_WR1_RAM_EN)); return 0; }
/** * ispccdc_request - Reserves the CCDC module. * * Reserves the CCDC module and assures that is used only once at a time. * * Returns 0 if successful, or -EBUSY if CCDC module is busy. **/ int ispccdc_request(void) { mutex_lock(&ispccdc_obj.mutexlock); if (ispccdc_obj.ccdc_inuse) { mutex_unlock(&ispccdc_obj.mutexlock); DPRINTK_ISPCCDC("ISP_ERR : CCDC Module Busy\n"); return -EBUSY; } ispccdc_obj.ccdc_inuse = 1; mutex_unlock(&ispccdc_obj.mutexlock); isp_reg_or(OMAP3_ISP_IOMEM_MAIN, ISP_CTRL, ISPCTRL_CCDC_RAM_EN | ISPCTRL_CCDC_CLK_EN | ISPCTRL_SBL_WR1_RAM_EN); isp_reg_or(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_CFG, ISPCCDC_CFG_VDLC); return 0; }
/** * ispccdc_config_fpc - Configures the Faulty Pixel Correction parameters. * @fpc: Structure containing the number of faulty pixels corrected in the * frame, address of the FPC table. * * Returns 0 if successful, or -EINVAL if FPC Address is not on the 64 byte * boundary. **/ int ispccdc_config_fpc(struct ispccdc_fpc fpc) { u32 fpc_val = 0; fpc_val = isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FPC); if ((fpc.fpcaddr & 0xFFFFFFC0) == fpc.fpcaddr) { isp_reg_writel(fpc_val & (~ISPCCDC_FPC_FPCEN), OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FPC); isp_reg_writel(fpc.fpcaddr, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FPC_ADDR); } else { DPRINTK_ISPCCDC("FPC Address should be on 64byte boundary\n"); return -EINVAL; } isp_reg_writel(fpc_val | (fpc.fpnum << ISPCCDC_FPC_FPNUM_SHIFT), OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FPC); return 0; }
/** * ispccdc_config_outlineoffset - Configures the output line offset * @offset: Must be twice the Output width and aligned on 32 byte boundary * @oddeven: Specifies the odd/even line pattern to be chosen to store the * output. * @numlines: Set the value 0-3 for +1-4lines, 4-7 for -1-4lines. * * - Configures the output line offset when stored in memory * - Sets the odd/even line pattern to store the output * (EVENEVEN (1), ODDEVEN (2), EVENODD (3), ODDODD (4)) * - Configures the number of even and odd line fields in case of rearranging * the lines. * * Returns 0 if successful, or -EINVAL if the offset is not in 32 byte * boundary. **/ int ispccdc_config_outlineoffset(u32 offset, u8 oddeven, u8 numlines) { if ((offset & ISP_32B_BOUNDARY_OFFSET) == offset) { isp_reg_writel((offset & 0xFFFF), OMAP3_ISP_IOMEM_CCDC, ISPCCDC_HSIZE_OFF); } else { DPRINTK_ISPCCDC("ISP_ERR : Offset should be in 32 byte" " boundary\n"); return -EINVAL; } isp_reg_and(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SDOFST, ~ISPCCDC_SDOFST_FINV); isp_reg_and(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SDOFST, ~ISPCCDC_SDOFST_FOFST_4L); switch (oddeven) { case EVENEVEN: isp_reg_or(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SDOFST, (numlines & 0x7) << ISPCCDC_SDOFST_LOFST0_SHIFT); break; case ODDEVEN: isp_reg_or(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SDOFST, (numlines & 0x7) << ISPCCDC_SDOFST_LOFST1_SHIFT); break; case EVENODD: isp_reg_or(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SDOFST, (numlines & 0x7) << ISPCCDC_SDOFST_LOFST2_SHIFT); break; case ODDODD: isp_reg_or(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SDOFST, (numlines & 0x7) << ISPCCDC_SDOFST_LOFST3_SHIFT); break; default: break; } return 0; }
/** * ispresizer_try_size - Validates input and output images size. * @input_w: input width for the resizer in number of pixels per line * @input_h: input height for the resizer in number of lines * @output_w: output width from the resizer in number of pixels per line * resizer when writing to memory needs this to be multiple of 16. * @output_h: output height for the resizer in number of lines, must be even. * * Calculates the horizontal and vertical resize ratio, number of pixels to * be cropped in the resizer module and checks the validity of various * parameters. Formula used for calculation is:- * * 8-phase 4-tap mode :- * inputwidth = (32 * sph + (ow - 1) * hrsz + 16) >> 8 + 7 * inputheight = (32 * spv + (oh - 1) * vrsz + 16) >> 8 + 4 * endpahse for width = ((32 * sph + (ow - 1) * hrsz + 16) >> 5) % 8 * endphase for height = ((32 * sph + (oh - 1) * hrsz + 16) >> 5) % 8 * * 4-phase 7-tap mode :- * inputwidth = (64 * sph + (ow - 1) * hrsz + 32) >> 8 + 7 * inputheight = (64 * spv + (oh - 1) * vrsz + 32) >> 8 + 7 * endpahse for width = ((64 * sph + (ow - 1) * hrsz + 32) >> 6) % 4 * endphase for height = ((64 * sph + (oh - 1) * hrsz + 32) >> 6) % 4 * * Where: * sph = Start phase horizontal * spv = Start phase vertical * ow = Output width * oh = Output height * hrsz = Horizontal resize value * vrsz = Vertical resize value * * Fills up the output/input widht/height, horizontal/vertical resize ratio, * horizontal/vertical crop variables in the isp_res structure. **/ int ispresizer_try_size(u32 *input_width, u32 *input_height, u32 *output_w, u32 *output_h) { u32 rsz, rsz_7, rsz_4; u32 sph; u32 input_w, input_h; int max_in_otf, max_out_7tap; input_w = *input_width; input_h = *input_height; if (input_w < 32 || input_h < 32) { DPRINTK_ISPCCDC("ISP_ERR: RESIZER cannot handle input width" " less than 32 pixels or height less than" " 32\n"); return -EINVAL; } input_w -= 6; input_h -= 6; if (input_h > MAX_IN_HEIGHT) return -EINVAL; if (*output_w < 16) *output_w = 16; if (*output_h < 2) *output_h = 2; if (omap_rev() == OMAP3430_REV_ES1_0) { max_in_otf = MAX_IN_WIDTH_ONTHEFLY_MODE; max_out_7tap = MAX_7TAP_VRSZ_OUTWIDTH; } else { max_in_otf = MAX_IN_WIDTH_ONTHEFLY_MODE_ES2; max_out_7tap = MAX_7TAP_VRSZ_OUTWIDTH_ES2; } if (ispres_obj.resinput == RSZ_OTFLY_YUV) { if (input_w > max_in_otf) return -EINVAL; } else { if (input_w > MAX_IN_WIDTH_MEMORY_MODE) return -EINVAL; } *output_h &= 0xfffffffe; sph = DEFAULTSTPHASE; rsz_7 = ((input_h - 7) * 256) / (*output_h - 1); rsz_4 = ((input_h - 4) * 256) / (*output_h - 1); rsz = (input_h * 256) / *output_h; if (rsz <= MID_RESIZE_VALUE) { rsz = rsz_4; if (rsz < MINIMUM_RESIZE_VALUE) { rsz = MINIMUM_RESIZE_VALUE; *output_h = (((input_h - 4) * 256) / rsz) + 1; DPRINTK_ISPRESZ("%s: using output_h" "%d instead\n", __func__, *output_h); } } else { rsz = rsz_7; if (*output_w > max_out_7tap) *output_w = max_out_7tap; if (rsz > MAXIMUM_RESIZE_VALUE) { rsz = MAXIMUM_RESIZE_VALUE; *output_h = (((input_h - 7) * 256) / rsz) + 1; DPRINTK_ISPRESZ("%s: using output_h" "%d instead\n", __func__, *output_h); } } if (rsz > MID_RESIZE_VALUE) { input_h = (((64 * sph) + ((*output_h - 1) * rsz) + 32) / 256) + 7; } else { input_h = (((32 * sph) + ((*output_h - 1) * rsz) + 16) / 256) + 4; } ispres_obj.outputheight = *output_h; ispres_obj.v_resz = rsz; ispres_obj.inputheight = input_h; ispres_obj.ipht_crop = DEFAULTSTPIXEL; ispres_obj.v_startphase = sph; *output_w &= 0xfffffff0; sph = DEFAULTSTPHASE; rsz_7 = ((input_w - 7) * 256) / (*output_w - 1); rsz_4 = ((input_w - 4) * 256) / (*output_w - 1); rsz = (input_w * 256) / *output_w; if (rsz > MID_RESIZE_VALUE) { rsz = rsz_7; if (rsz > MAXIMUM_RESIZE_VALUE) { rsz = MAXIMUM_RESIZE_VALUE; *output_w = (((input_w - 7) * 256) / rsz) + 1; *output_w = (*output_w + 0xf) & 0xfffffff0; DPRINTK_ISPRESZ("%s: using output_w" "%d instead\n", __func__, *output_w); } } else { rsz = rsz_4; if (rsz < MINIMUM_RESIZE_VALUE) { rsz = MINIMUM_RESIZE_VALUE; *output_w = (((input_w - 4) * 256) / rsz) + 1; *output_w = (*output_w + 0xf) & 0xfffffff0; DPRINTK_ISPRESZ("%s: using output_w %d" "instead\n", __func__, *output_w); } } /* Recalculate input based on TRM equations */ if (rsz > MID_RESIZE_VALUE) { input_w = (((64 * sph) + ((*output_w - 1) * rsz) + 32) / 256) + 7; } else { input_w = (((32 * sph) + ((*output_w - 1) * rsz) + 16) / 256) + 7; } ispres_obj.outputwidth = *output_w; ispres_obj.h_resz = rsz; ispres_obj.inputwidth = input_w; ispres_obj.ipwd_crop = DEFAULTSTPIXEL; ispres_obj.h_startphase = sph; *input_height = input_h; *input_width = input_w; return 0; }
/** * ispccdc_config_datapath - Specifies the input and output modules for CCDC. * @input: Indicates the module that inputs the image to the CCDC. * @output: Indicates the module to which the CCDC outputs the image. * * Configures the default configuration for the CCDC to work with. * * The valid values for the input are CCDC_RAW (0), CCDC_YUV_SYNC (1), * CCDC_YUV_BT (2), and CCDC_OTHERS (3). * * The valid values for the output are CCDC_YUV_RSZ (0), CCDC_YUV_MEM_RSZ (1), * CCDC_OTHERS_VP (2), CCDC_OTHERS_MEM (3), CCDC_OTHERS_VP_MEM (4). * * Returns 0 if successful, or -EINVAL if wrong I/O combination or wrong input * or output values. **/ int ispccdc_config_datapath(enum ccdc_input input, enum ccdc_output output) { u32 syn_mode = 0; struct ispccdc_vp vpcfg; struct ispccdc_syncif syncif; struct ispccdc_bclamp blkcfg; u32 colptn = ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP0PLC0_SHIFT | ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP0PLC1_SHIFT | ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP0PLC2_SHIFT | ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP0PLC3_SHIFT | ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP1PLC0_SHIFT | ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP1PLC1_SHIFT | ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP1PLC2_SHIFT | ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP1PLC3_SHIFT | ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP2PLC0_SHIFT | ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP2PLC1_SHIFT | ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP2PLC2_SHIFT | ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP2PLC3_SHIFT | ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP3PLC0_SHIFT | ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP3PLC1_SHIFT | ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP3PLC2_SHIFT | ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP3PLC3_SHIFT; /* CCDC does not convert the image format */ if ((input == CCDC_RAW || input == CCDC_OTHERS) && output == CCDC_YUV_RSZ) { DPRINTK_ISPCCDC("ISP_ERR: Wrong CCDC I/O Combination\n"); return -EINVAL; } syn_mode = isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SYN_MODE); switch (output) { case CCDC_YUV_RSZ: syn_mode |= ISPCCDC_SYN_MODE_SDR2RSZ; syn_mode &= ~ISPCCDC_SYN_MODE_WEN; break; case CCDC_YUV_MEM_RSZ: syn_mode |= ISPCCDC_SYN_MODE_SDR2RSZ; ispccdc_obj.wen = 1; syn_mode |= ISPCCDC_SYN_MODE_WEN; break; case CCDC_OTHERS_VP: syn_mode &= ~ISPCCDC_SYN_MODE_VP2SDR; syn_mode &= ~ISPCCDC_SYN_MODE_SDR2RSZ; syn_mode &= ~ISPCCDC_SYN_MODE_WEN; vpcfg.bitshift_sel = BIT9_0; vpcfg.freq_sel = PIXCLKBY2; ispccdc_config_vp(vpcfg); ispccdc_enable_vp(1); break; case CCDC_OTHERS_MEM: syn_mode &= ~ISPCCDC_SYN_MODE_VP2SDR; syn_mode &= ~ISPCCDC_SYN_MODE_SDR2RSZ; syn_mode |= ISPCCDC_SYN_MODE_WEN; syn_mode &= ~ISPCCDC_SYN_MODE_EXWEN; isp_reg_and(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_CFG, ~ISPCCDC_CFG_WENLOG); vpcfg.bitshift_sel = BIT11_2; vpcfg.freq_sel = PIXCLKBY2; ispccdc_config_vp(vpcfg); ispccdc_enable_vp(0); break; case CCDC_OTHERS_VP_MEM: syn_mode &= ~ISPCCDC_SYN_MODE_VP2SDR; syn_mode &= ~ISPCCDC_SYN_MODE_SDR2RSZ; syn_mode |= ISPCCDC_SYN_MODE_WEN; syn_mode &= ~ISPCCDC_SYN_MODE_EXWEN; isp_reg_and_or(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_CFG, ~ISPCCDC_CFG_WENLOG, ispccdc_obj.wenlog); vpcfg.bitshift_sel = BIT9_0; vpcfg.freq_sel = PIXCLKBY2; ispccdc_config_vp(vpcfg); ispccdc_enable_vp(1); break; default: DPRINTK_ISPCCDC("ISP_ERR: Wrong CCDC Output\n"); return -EINVAL; }; isp_reg_writel(syn_mode, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SYN_MODE); switch (input) { case CCDC_RAW: syncif.ccdc_mastermode = 0; syncif.datapol = 0; syncif.datsz = DAT10; syncif.fldmode = 0; syncif.fldout = 0; syncif.fldpol = 0; syncif.fldstat = 0; syncif.hdpol = 0; syncif.ipmod = RAW; syncif.vdpol = 0; ispccdc_config_sync_if(syncif); ispccdc_config_imgattr(colptn); blkcfg.dcsubval = 64; ispccdc_config_black_clamp(blkcfg); if (is_isplsc_activated()) { ispccdc_config_lsc(&lsc_config); ispccdc_load_lsc(lsc_gain_table_tmp, LSC_TABLE_INIT_SIZE); } break; case CCDC_YUV_SYNC: syncif.ccdc_mastermode = 0; syncif.datapol = 0; syncif.datsz = DAT8; syncif.fldmode = 0; syncif.fldout = 0; syncif.fldpol = 0; syncif.fldstat = 0; syncif.hdpol = 0; syncif.ipmod = YUV16; syncif.vdpol = 1; ispccdc_config_imgattr(0); ispccdc_config_sync_if(syncif); blkcfg.dcsubval = 0; ispccdc_config_black_clamp(blkcfg); break; case CCDC_YUV_BT: break; case CCDC_OTHERS: break; default: DPRINTK_ISPCCDC("ISP_ERR: Wrong CCDC Input\n"); return -EINVAL; } ispccdc_obj.ccdc_inpfmt = input; ispccdc_obj.ccdc_outfmt = output; ispccdc_print_status(); isp_print_status(); return 0; }
/** * ispccdc_print_status - Prints the values of the CCDC Module registers * * Also prints other debug information stored in the CCDC module. **/ void ispccdc_print_status(void) { if (!is_ispccdc_debug_enabled()) return; DPRINTK_ISPCCDC("Module in use =%d\n", ispccdc_obj.ccdc_inuse); DPRINTK_ISPCCDC("Accepted CCDC Input (width = %d,Height = %d)\n", ispccdc_obj.ccdcin_w, ispccdc_obj.ccdcin_h); DPRINTK_ISPCCDC("Accepted CCDC Output (width = %d,Height = %d)\n", ispccdc_obj.ccdcout_w, ispccdc_obj.ccdcout_h); DPRINTK_ISPCCDC("###CCDC PCR=0x%x\n", isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_PCR)); DPRINTK_ISPCCDC("ISP_CTRL =0x%x\n", isp_reg_readl(OMAP3_ISP_IOMEM_MAIN, ISP_CTRL)); switch (ispccdc_obj.ccdc_inpfmt) { case CCDC_RAW: DPRINTK_ISPCCDC("ccdc input format is CCDC_RAW\n"); break; case CCDC_YUV_SYNC: DPRINTK_ISPCCDC("ccdc input format is CCDC_YUV_SYNC\n"); break; case CCDC_YUV_BT: DPRINTK_ISPCCDC("ccdc input format is CCDC_YUV_BT\n"); break; } switch (ispccdc_obj.ccdc_outfmt) { case CCDC_OTHERS_VP: DPRINTK_ISPCCDC("ccdc output format is CCDC_OTHERS_VP\n"); break; case CCDC_OTHERS_MEM: DPRINTK_ISPCCDC("ccdc output format is CCDC_OTHERS_MEM\n"); break; case CCDC_YUV_RSZ: DPRINTK_ISPCCDC("ccdc output format is CCDC_YUV_RSZ\n"); break; } DPRINTK_ISPCCDC("###ISP_CTRL in ccdc =0x%x\n", isp_reg_readl(OMAP3_ISP_IOMEM_MAIN, ISP_CTRL)); DPRINTK_ISPCCDC("###ISP_IRQ0ENABLE in ccdc =0x%x\n", isp_reg_readl(OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0ENABLE)); DPRINTK_ISPCCDC("###ISP_IRQ0STATUS in ccdc =0x%x\n", isp_reg_readl(OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0STATUS)); DPRINTK_ISPCCDC("###CCDC SYN_MODE=0x%x\n", isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SYN_MODE)); DPRINTK_ISPCCDC("###CCDC HORZ_INFO=0x%x\n", isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_HORZ_INFO)); DPRINTK_ISPCCDC("###CCDC VERT_START=0x%x\n", isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_VERT_START)); DPRINTK_ISPCCDC("###CCDC VERT_LINES=0x%x\n", isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_VERT_LINES)); DPRINTK_ISPCCDC("###CCDC CULLING=0x%x\n", isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_CULLING)); DPRINTK_ISPCCDC("###CCDC HSIZE_OFF=0x%x\n", isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_HSIZE_OFF)); DPRINTK_ISPCCDC("###CCDC SDOFST=0x%x\n", isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SDOFST)); DPRINTK_ISPCCDC("###CCDC SDR_ADDR=0x%x\n", isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SDR_ADDR)); DPRINTK_ISPCCDC("###CCDC CLAMP=0x%x\n", isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_CLAMP)); DPRINTK_ISPCCDC("###CCDC COLPTN=0x%x\n", isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_COLPTN)); DPRINTK_ISPCCDC("###CCDC CFG=0x%x\n", isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_CFG)); DPRINTK_ISPCCDC("###CCDC VP_OUT=0x%x\n", isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_VP_OUT)); DPRINTK_ISPCCDC("###CCDC_SDR_ADDR= 0x%x\n", isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SDR_ADDR)); DPRINTK_ISPCCDC("###CCDC FMTCFG=0x%x\n", isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FMTCFG)); DPRINTK_ISPCCDC("###CCDC FMT_HORZ=0x%x\n", isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FMT_HORZ)); DPRINTK_ISPCCDC("###CCDC FMT_VERT=0x%x\n", isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FMT_VERT)); DPRINTK_ISPCCDC("###CCDC LSC_CONFIG=0x%x\n", isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_LSC_CONFIG)); DPRINTK_ISPCCDC("###CCDC LSC_INIT=0x%x\n", isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_LSC_INITIAL)); DPRINTK_ISPCCDC("###CCDC LSC_TABLE BASE=0x%x\n", isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_LSC_TABLE_BASE)); DPRINTK_ISPCCDC("###CCDC LSC TABLE OFFSET=0x%x\n", isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_LSC_TABLE_OFFSET)); }
/** * ispccdc_restore_context - Restores the values of the CCDC module registers **/ void ispccdc_restore_context(void) { DPRINTK_ISPCCDC("Restoring context\n"); isp_restore_context(ispccdc_reg_list); }
/** * ispccdc_save_context - Saves the values of the CCDC module registers **/ void ispccdc_save_context(void) { DPRINTK_ISPCCDC("Saving context\n"); isp_save_context(ispccdc_reg_list); }
/** * ispccdc_config_size - Configure the dimensions of the CCDC input/output * @input_w: input width for the CCDC in number of pixels per line * @input_h: input height for the CCDC in number of lines * @output_w: output width from the CCDC in number of pixels per line * @output_h: output height for the CCDC in number of lines * * Configures the appropriate values stored in the isp_ccdc structure to * HORZ/VERT_INFO registers and the VP_OUT depending on whether the image * is stored in memory or given to the another module in the ISP pipeline. * * Returns 0 if successful, or -EINVAL if try_size was not called before to * validate the requested dimensions. **/ int ispccdc_config_size(u32 input_w, u32 input_h, u32 output_w, u32 output_h) { DPRINTK_ISPCCDC("config size: input_w=%u, input_h=%u, output_w=%u," " output_h=%u\n", input_w, input_h, output_w, output_h); if (output_w != ispccdc_obj.ccdcout_w || output_h != ispccdc_obj.ccdcout_h) { DPRINTK_ISPCCDC("ISP_ERR : ispccdc_try_size should" " be called before config size\n"); return -EINVAL; } if (ispccdc_obj.ccdc_outfmt == CCDC_OTHERS_VP) { isp_reg_writel((ispccdc_obj.ccdcin_woffset << ISPCCDC_FMT_HORZ_FMTSPH_SHIFT) | ((ispccdc_obj.ccdcin_w-ispccdc_obj.ccdcin_woffset) << ISPCCDC_FMT_HORZ_FMTLNH_SHIFT), OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FMT_HORZ); isp_reg_writel((ispccdc_obj.ccdcin_hoffset << ISPCCDC_FMT_VERT_FMTSLV_SHIFT) | ((ispccdc_obj.ccdcin_h-ispccdc_obj.ccdcin_hoffset) << ISPCCDC_FMT_VERT_FMTLNV_SHIFT), OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FMT_VERT); isp_reg_writel((ispccdc_obj.ccdcout_w << ISPCCDC_VP_OUT_HORZ_NUM_SHIFT) | (ispccdc_obj.ccdcout_h - 1) << ISPCCDC_VP_OUT_VERT_NUM_SHIFT, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_VP_OUT); isp_reg_writel((((ispccdc_obj.ccdcout_h - 25) & ISPCCDC_VDINT_0_MASK) << ISPCCDC_VDINT_0_SHIFT) | ((50 & ISPCCDC_VDINT_1_MASK) << ISPCCDC_VDINT_1_SHIFT), OMAP3_ISP_IOMEM_CCDC, ISPCCDC_VDINT); } else if (ispccdc_obj.ccdc_outfmt == CCDC_OTHERS_MEM) { isp_reg_writel(0, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_VP_OUT); if (ispccdc_obj.ccdc_inpfmt == CCDC_RAW) { isp_reg_writel(ispccdc_obj.ccdcin_woffset << ISPCCDC_HORZ_INFO_SPH_SHIFT | ((ispccdc_obj.ccdcout_w - 1) << ISPCCDC_HORZ_INFO_NPH_SHIFT), OMAP3_ISP_IOMEM_CCDC, ISPCCDC_HORZ_INFO); } else { isp_reg_writel(0 << ISPCCDC_HORZ_INFO_SPH_SHIFT | ((ispccdc_obj.ccdcout_w - 1) << ISPCCDC_HORZ_INFO_NPH_SHIFT), OMAP3_ISP_IOMEM_CCDC, ISPCCDC_HORZ_INFO); } isp_reg_writel(ispccdc_obj.ccdcin_hoffset << ISPCCDC_VERT_START_SLV0_SHIFT, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_VERT_START); isp_reg_writel((ispccdc_obj.ccdcout_h - 1) << ISPCCDC_VERT_LINES_NLV_SHIFT, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_VERT_LINES); ispccdc_config_outlineoffset(ispccdc_obj.ccdcout_w * 2, 0, 0); isp_reg_writel((((ispccdc_obj.ccdcout_h - 2) & ISPCCDC_VDINT_0_MASK) << ISPCCDC_VDINT_0_SHIFT) | ((100 & ISPCCDC_VDINT_1_MASK) << ISPCCDC_VDINT_1_SHIFT), OMAP3_ISP_IOMEM_CCDC, ISPCCDC_VDINT); } else if (ispccdc_obj.ccdc_outfmt == CCDC_OTHERS_VP_MEM) { isp_reg_writel((ispccdc_obj.ccdcin_woffset << ISPCCDC_FMT_HORZ_FMTSPH_SHIFT) | ((ispccdc_obj.ccdcin_w - ispccdc_obj.ccdcin_woffset) << ISPCCDC_FMT_HORZ_FMTLNH_SHIFT), OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FMT_HORZ); isp_reg_writel((ispccdc_obj.ccdcin_hoffset << ISPCCDC_FMT_VERT_FMTSLV_SHIFT) | ((ispccdc_obj.ccdcin_h - ispccdc_obj.ccdcin_hoffset) << ISPCCDC_FMT_VERT_FMTLNV_SHIFT), OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FMT_VERT); isp_reg_writel((ispccdc_obj.ccdcout_w << ISPCCDC_VP_OUT_HORZ_NUM_SHIFT) | ((ispccdc_obj.ccdcout_h - 1) << ISPCCDC_VP_OUT_VERT_NUM_SHIFT), OMAP3_ISP_IOMEM_CCDC, ISPCCDC_VP_OUT); isp_reg_writel((ispccdc_obj.ccdcin_woffset << ISPCCDC_HORZ_INFO_SPH_SHIFT) | ((ispccdc_obj.ccdcout_w - 1) << ISPCCDC_HORZ_INFO_NPH_SHIFT), OMAP3_ISP_IOMEM_CCDC, ISPCCDC_HORZ_INFO); isp_reg_writel(ispccdc_obj.ccdcin_hoffset << ISPCCDC_VERT_START_SLV0_SHIFT, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_VERT_START); isp_reg_writel((ispccdc_obj.ccdcout_h - 1) << ISPCCDC_VERT_LINES_NLV_SHIFT, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_VERT_LINES); ispccdc_config_outlineoffset(ispccdc_obj.ccdcout_w * 2, 0, 0); isp_reg_writel((((ispccdc_obj.ccdcout_h - 2) & ISPCCDC_VDINT_0_MASK) << ISPCCDC_VDINT_0_SHIFT) | ((100 & ISPCCDC_VDINT_1_MASK) << ISPCCDC_VDINT_1_SHIFT), OMAP3_ISP_IOMEM_CCDC, ISPCCDC_VDINT); } if (is_isplsc_activated()) { if (ispccdc_obj.ccdc_inpfmt == CCDC_RAW) { ispccdc_config_lsc(&lsc_config); ispccdc_load_lsc(lsc_gain_table, lsc_config.size); } } return 0; }