示例#1
0
/**
 * 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;
}
示例#2
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;
	}

}
示例#3
0
/**
 * 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);
}
示例#4
0
/**
 * 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;
}
示例#5
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;
}
示例#6
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;
}
示例#7
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;
}
示例#9
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;
}
示例#10
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));
}
示例#11
0
/**
 * 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);
}
示例#12
0
/**
 * 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);
}
示例#13
0
/**
 * 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;
}