/*  Config lcdc timimg when hdmi chooses a resolution
 *  params: mode[lcdc_timimg_parms_t] lcdc timimg to 
 *          set
 *  return: null
 */
void sep0611_hdmi_lcdc_timing(struct lcdc_timing_params_t *mode)
{
    unsigned int plcr = 0;
	unsigned int pfcr = 0;
	unsigned int lcdcscr = 0;
	unsigned int lcdcbcr = 0;
	
	plcr = H_WIDTH(mode->lpw) | H_WAIT1((mode->lswc + 1)) | H_WAIT2((mode->lewc + 1));
	pfcr = V_WIDTH(mode->fpw) | V_WAIT1((mode->fswc + 1)) | V_WAIT2((mode->fewc + 1));
	
	lcdcscr = XMAX((mode->lpc + 1))|YMAX((mode->flc + 1));
	lcdcbcr = readl(LCDC_BCR_V);
	lcdcbcr &= ~0x3f;
	lcdcbcr |= PCD(mode->pcd);
	
	writel(0x0, LCDC_ECR_V);
	
	msleep(20);
	
	writel(lcdcbcr, LCDC_BCR_V);
	writel(plcr, LCDC_PLCR_V);
	writel(pfcr, LCDC_PFCR_V);
	writel(lcdcscr, LCDC_SCR_V);
	
	msleep(20);
	
	writel(0x1, LCDC_ECR_V);
	
	msleep(10);
}
/******************************** the module driver ************************************************************/
static int sep0611_overlay_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
	unsigned int intArg,data;
	overlay_config_t config;
	lcdc_timming timming_tmp;
	switch(cmd)
	{
#if 0
		case OVERLAY_FORBID:
			if(copy_from_user(&intArg, (int *)arg, sizeof(int)))
				return -EFAULT;
			overlay_forbid = intArg;
			return 0;
#endif
#if USE_PICTURE
		case 111://GET_IMG
			//if(copy_from_user(&config, (overlay_config_t *)arg, sizeof(overlay_config_t)))
			//	return -EFAULT;
			return sep0611_overlay_get_img();
#endif
		case OVERLAY_PRINT_REGS:
			dprintk("print regs:\n");
			for(intArg=0; intArg<=0xCC;intArg+=4)
			{
				printk("reg[0x%x] = (0x%x)\n", (unsigned int)io + intArg, readl(io + intArg));
			}
			break;
		case OVERLAY_GET_STARTBUF:
			dprintk("overlay_kernel ioctl get startbuffer!\n");
			if(copy_to_user((unsigned int *)arg, &over1_addr_phy, sizeof(unsigned int)))
			{
				dprintk("error while copy!\n");
				return -EFAULT;
			}else{
			//	dprintk("success get startbuf: 0x%x",over1_addr_phy);
			}
			break;
		case OVERLAY_AUTORP_CTL:
			if(copy_from_user(&intArg, (int *)arg, sizeof(int)))
				return -EFAULT;
			if(intArg == 1){
				writel(0, io + SEP0611_ACSR);
				data = readl(io + SEP0611_LCDCBCR);
				data &=~(0x3<<13);
				data |=(0x2<<13);
				writel(data, io + SEP0611_LCDCBCR);
				mdelay(10);
				writel(1, io + SEP0611_ACSR);
				dprintk("ctl enable auto repair\n");
			}else{
				data = readl(io + SEP0611_LCDCBCR);
				data &=~(0x3<<13);
				writel(data, io + SEP0611_LCDCBCR);
				dprintk("ctl disable auto repair\n");
			}
			break;
		case OVERLAY_SHOW_CURSOR:
			return sep0611_overlay_drawcursor();
		case OVERLAY_SETPOS_CURSOR:
			if(copy_from_user(&intArg, (int *)arg, sizeof(int)))
				return -EFAULT;
			return sep0611_overlay_setpos_cursor(intArg);

		case OVERLAY_LAYERS_CTL://enable or disable layers
			if(copy_from_user(&intArg, (int *)arg, sizeof(int)))
				return -EFAULT;
			sep0611_overlay_layers_ctl(intArg);
			break;
		case 114://set lcdc timming
			if(copy_from_user(&timming_tmp, (lcdc_timming *)arg, sizeof(lcdc_timming)))
				return -EFAULT;
			sep0611_overlay_settimming(timming_tmp);
			break;
		case 115://set lcdc base layer size and format
			if(copy_from_user(&config, (overlay_config_t *)arg, sizeof(overlay_config_t)))
				return -EFAULT;
			intArg = 0;
			dprintk("set base size:(%d,%d)\n", config.width, config.height);
			intArg = XMAX(config.width)|YMAX(config.height);
			writel(intArg, io + SEP0611_BBPCR);
			writel(config.width, io + SEP0611_BASE_RAW_IMAGE_WIDTH); 
			switch(config.format)
			{
				case V4L2_PIX_FMT_RGB565:
					dprintk("use rgb565\n");
					data = readl(io + SEP0611_LCDCBCR);
					data &=~(0x3<<27);
					writel(data, io + SEP0611_LCDCBCR);
					break;
				case V4L2_PIX_FMT_RGB24:
					dprintk("use rgb888\n");
					data = readl(io + SEP0611_LCDCBCR);
					data &= ~(0x3<<27);
					data |= (0x2<<27);
					writel(data, io + SEP0611_LCDCBCR);
					break;
				default:
					dprintk("not support!\n");
					break;
			}
			break;
		case OVERLAY_GET_POSITION:
			return sep0611_overlay_get_pos((overlay_config_t*)arg);

		case OVERLAY_GET_SCREEN_INFO:
			return sep0611_overlay_get_screenInfo((overlay_config_t*)arg);

		case OVERLAY_SET_POSITION:
			if(copy_from_user(&config, (overlay_config_t *)arg, sizeof(overlay_config_t)))
				return -EFAULT;
			return sep0611_overlay_set_pos(config);

		case OVERLAY_QUEUE_BUFFER:
			if(copy_from_user(&intArg, (overlay_config_t *)arg, sizeof(unsigned int)))
				return -EFAULT;
			return sep0611_overlay_q_buffer((unsigned int)intArg);

		case OVERLAY_SET_CONFIGURE:
			if(copy_from_user(&config, (overlay_config_t *)arg, sizeof(overlay_config_t)))
				return -EFAULT;
			sep0611_overlay_set_configure(config);
			//sep0611_overlay_q_buffer(over1_addr_phy);
			break;

		case OVERLAY_SET_DISABLE:
			return sep0611_overlay_disable();

		case OVERLAY_SET_ENABLE:
			return sep0611_overlay_enable();

		case OVERLAY_COMMON_ENABLE:
			sep0611_common_enable();
			return 0;
		case OVERLAY_COMMON_DISABLE:
			sep0611_common_disable();
			return 0;
		case OVERLAY_SWITCHTO_VIDEO:
			sep0611_switchto_mode(0);
			break;
		case OVERLAY_SWITCHTO_HDMI:
			sep0611_switchto_mode(1);
			break;
		case OVERLAY_SWITCHTO_LCD:
			sep0611_switchto_mode(2);
			break;
		default:
			dprintk(" Unsupported IOCTL(%d)!!!\n", cmd);      
			break;			
	}
	return 0;
}
Ejemplo n.º 3
0
static void miSubtractSpans (SpanGroup *spanGroup, Spans *sub)
{
    int		i, subCount, spansCount;
    int		ymin, ymax, xmin, xmax;
    Spans	*spans;
    DDXPointPtr	subPt, spansPt;
    int		*subWid, *spansWid;
    int		extra;

    ymin = YMIN(sub);
    ymax = YMAX(sub);
    spans = spanGroup->group;
    for (i = spanGroup->count; i; i--, spans++) {
	if (YMIN(spans) <= ymax && ymin <= YMAX(spans)) {
	    subCount = sub->count;
	    subPt = sub->points;
	    subWid = sub->widths;
	    spansCount = spans->count;
	    spansPt = spans->points;
	    spansWid = spans->widths;
	    extra = 0;
	    for (;;)
 	    {
		while (spansCount && spansPt->y < subPt->y)
		{
		    spansPt++;  spansWid++; spansCount--;
		}
		if (!spansCount)
		    break;
		while (subCount && subPt->y < spansPt->y)
		{
		    subPt++;	subWid++;   subCount--;
		}
		if (!subCount)
		    break;
		if (subPt->y == spansPt->y)
		{
		    xmin = subPt->x;
		    xmax = xmin + *subWid;
		    if (xmin >= spansPt->x + *spansWid || spansPt->x >= xmax)
		    {
			;
		    }
		    else if (xmin <= spansPt->x)
		    {
			if (xmax >= spansPt->x + *spansWid) 
			{
			    memmove (spansPt, spansPt + 1, sizeof *spansPt * (spansCount - 1));
			    memmove (spansWid, spansWid + 1, sizeof *spansWid * (spansCount - 1));
			    spansPt--;
			    spansWid--;
			    spans->count--;
			    extra++;
			}
			else 
			{
			    *spansWid = *spansWid - (xmax - spansPt->x);
			    spansPt->x = xmax;
			}
		    }
		    else
		    {
			if (xmax >= spansPt->x + *spansWid)
			{
			    *spansWid = xmin - spansPt->x;
			}
			else
			{
			    if (!extra) {
				DDXPointPtr newPt;
				int	    *newwid;

#define EXTRA 8
				newPt = (DDXPointPtr) realloc(spans->points, (spans->count + EXTRA) * sizeof (DDXPointRec));
				if (!newPt)
				    break;
				spansPt = newPt + (spansPt - spans->points);
				spans->points = newPt;
				newwid = (int *) realloc(spans->widths, (spans->count + EXTRA) * sizeof (int));
				if (!newwid)
				    break;
				spansWid = newwid + (spansWid - spans->widths);
				spans->widths = newwid;
				extra = EXTRA;
			    }
			    memmove (spansPt + 1, spansPt, sizeof *spansPt * (spansCount));
			    memmove (spansWid + 1, spansWid, sizeof *spansWid * (spansCount));
			    spans->count++;
			    extra--;
			    *spansWid = xmin - spansPt->x;
			    spansWid++;
			    spansPt++;
			    *spansWid = *spansWid - (xmax - spansPt->x);
			    spansPt->x = xmax;
			}
		    }
		}
		spansPt++;  spansWid++; spansCount--;
	    }
	}
    }
}
static int sep0611_overlay_settimming(lcdc_timming timming)
{
	unsigned int data;
	dprintk("go to %s\n", __func__);

	//disable LCDC
	writel(WIN_DISABLE, io + SEP0611_LCDCECR);

#if 1
	if(timming.width == 9999)//switch PLL source
	{	
		data = readl(io_pmu + 0x2c);
		dprintk("pmu_0x2c = 0x%x\n", data);
		data = readl(io_pmu + 0x34);
		dprintk("pmu_0x34 = 0x%x\n", data);

		data = readl(io_pmu + 0x2c);
		data &= ~(0x3<<4);
		if(timming.height == 9999) ;//use MPLL
		else {data |= 0x1<<4; /*data|=0x1;*/}		//use APLL
		writel(data, io_pmu + 0x2c);//to use APLL 800MHz

		data = readl(io_pmu + 0x34);
		data &= ~(0x1<<3);
		data |= 0x1<<3;
		writel(data , io_pmu + 0x34);

		for(;;)
		{
			data = readl(io_pmu + 0x34);
			data &= 0x1<<3;
			dprintk("data = %d\n",data);
			if(data ==0) break;
			msleep(100);
		}
		dprintk("after write the regs\n");
		data = readl(io_pmu + 0x2c);
		dprintk("pmu_0x2c = 0x%x\n", data);
		data = readl(io_pmu + 0x34);
		dprintk("pmu_0x34 = 0x%x\n", data);
		dprintk("pmu config OK\n");
		writel(WIN_ENABLE, io + SEP0611_LCDCECR);
		return 0;
	}

#endif
	dprintk("lcd.t=%d, %d, %d, %d, %d, %d, %d, %d, %d\n",timming.width,timming.height,timming.pcd,timming.h_width,timming.h_wait1,timming.h_wait2,timming.v_width,timming.v_wait1,timming.v_wait2);

	msleep(10);
	//size
	data = 0;
	data |= XMAX(timming.width)|YMAX(timming.height);
	writel(data, io + SEP0611_LCDCSCR);

	// PCD
	data = readl(io + SEP0611_LCDCBCR);
	data &=~(0x1F);
	data |=timming.pcd;
	writel(data, io + SEP0611_LCDCBCR);

	// H timming
	data = 0;
	data = H_WIDTH(timming.h_width) | H_WAIT1(timming.h_wait1) | H_WAIT2(timming.h_wait2);
	writel(data, io + SEP0611_PLCR);

	// V timming
	data = 0;
	data = V_WIDTH(timming.v_width) | V_WAIT1(timming.v_wait1) | V_WAIT2(timming.v_wait2);
	writel(data, io + SEP0611_PFCR);

	msleep(10);
	//enable LCDC
	writel(WIN_ENABLE, io + SEP0611_LCDCECR);
	return 0;
}