static int atmel_bl_update_status(struct backlight_device *bl)
{
	struct atmel_lcdfb_info *sinfo = bl_get_data(bl);
	int			power = sinfo->bl_power;
	int			brightness = bl->props.brightness;

	if (bl->props.fb_blank != sinfo->bl_power)
		power = bl->props.fb_blank;
	else if (bl->props.power != sinfo->bl_power)
		power = bl->props.power;

	if (brightness < 0 && power == FB_BLANK_UNBLANK)
		brightness = lcdc_readl(sinfo, ATMEL_LCDC_CONTRAST_VAL);
	else if (power != FB_BLANK_UNBLANK)
		brightness = 0;

	lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_VAL, brightness);
	if (contrast_ctr & ATMEL_LCDC_POL_POSITIVE)
		lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR,
			brightness ? contrast_ctr : 0);
	else
		lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, contrast_ctr);

	bl->props.fb_blank = bl->props.power = sinfo->bl_power = power;

	return 0;
}
static void atmel_lcdfb_start(struct atmel_lcdfb_info *sinfo)
{
	lcdc_writel(sinfo, ATMEL_LCDC_DMACON, sinfo->default_dmacon);
	lcdc_writel(sinfo, ATMEL_LCDC_PWRCON,
		(sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET)
		| ATMEL_LCDC_PWR);
}
Exemple #3
0
/* some bl->props field just changed */
static int atmel_bl_update_status(struct backlight_device *bl)
{
	struct atmel_lcdfb_info *sinfo = bl_get_data(bl);
	int			power = sinfo->bl_power;
	int			brightness = bl->props.brightness;

	/* REVISIT there may be a meaningful difference between
	 * fb_blank and power ... there seem to be some cases
	 * this doesn't handle correctly.
	 */
	if (bl->props.fb_blank != sinfo->bl_power)
		power = bl->props.fb_blank;
	else if (bl->props.power != sinfo->bl_power)
		power = bl->props.power;

	if (brightness < 0 && power == FB_BLANK_UNBLANK)
		brightness = lcdc_readl(sinfo, ATMEL_LCDC_CONTRAST_VAL);
	else if (power != FB_BLANK_UNBLANK)
		brightness = 0;

	lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_VAL, brightness);
	lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR,
			brightness ? contrast_ctr : 0);

	bl->props.fb_blank = bl->props.power = sinfo->bl_power = power;

	return 0;
}
Exemple #4
0
static void atmel_hlcdfb_update_dma_ovl(struct fb_info *info,
			       struct fb_var_screeninfo *var)
{
	struct atmel_lcdfb_info *sinfo = info->par;
	struct fb_fix_screeninfo *fix = &info->fix;
	unsigned long dma_addr;
	struct atmel_hlcd_dma_desc *desc;

	dma_addr = (fix->smem_start + var->yoffset * fix->line_length
		    + var->xoffset * var->bits_per_pixel / 8);

	dma_addr &= ~3UL;

	/* Setup the DMA descriptor, this descriptor will loop to itself */
	desc = sinfo->dma_desc;

	desc->address = dma_addr;
	/* Disable DMA transfer interrupt & descriptor loaded interrupt. */
	desc->control = LCDC_OVRCTRL_ADDIEN | LCDC_OVRCTRL_DSCRIEN
			| LCDC_OVRCTRL_DMAIEN | LCDC_OVRCTRL_DFETCH;
	desc->next = sinfo->dma_desc_phys;

	lcdc_writel(sinfo, ATMEL_LCDC_OVRADDR, dma_addr);
	lcdc_writel(sinfo, ATMEL_LCDC_OVRCTRL, desc->control);
	lcdc_writel(sinfo, ATMEL_LCDC_OVRNEXT, sinfo->dma_desc_phys);
	lcdc_writel(sinfo, ATMEL_LCDC_OVRCHER, LCDC_OVRCHER_CHEN | LCDC_OVRCHER_UPDATEEN);
}
Exemple #5
0
static  int win0_display(struct rk3188_lcdc_device *lcdc_dev,struct layer_par *par )
{
	u32 y_addr;
	u32 uv_addr;
	y_addr = par->smem_start + par->y_offset;
	uv_addr = par->cbr_start + par->c_offset;
	DBG(2,"lcdc%d>>%s:y_addr:0x%x>>uv_addr:0x%x\n",lcdc_dev->id,__func__,y_addr,uv_addr);

	spin_lock(&lcdc_dev->reg_lock);
	if(likely(lcdc_dev->clk_on))
	{
		lcdc_writel(lcdc_dev, WIN0_YRGB_MST0, y_addr);
		lcdc_writel(lcdc_dev, WIN0_CBR_MST0, uv_addr);	
// #if defined(CONFIG_RK_HDMI)
// #if defined(CONFIG_DUAL_LCDC_DUAL_DISP_IN_KERNEL)
//        if(lcdc_dev->driver.screen_ctr_info->prop == EXTEND)
//        {
//            if(hdmi_get_hotplug() == HDMI_HPD_ACTIVED)
//            {
                lcdc_cfg_done(lcdc_dev);
//            }
//        }
// #endif 
// #endif
	}
	spin_unlock(&lcdc_dev->reg_lock);

	return 0;
	
}
Exemple #6
0
int rk30_lcdc_ioctl(struct rk_lcdc_device_driver * dev_drv,unsigned int cmd, unsigned long arg,int layer_id)
{
	struct rk30_lcdc_device *lcdc_dev = container_of(dev_drv,struct rk30_lcdc_device,driver);
	u32 panel_size[2];
	void __user *argp = (void __user *)arg;
	int ret = 0;
	struct color_key_cfg clr_key_cfg;
	switch(cmd)
	{
		case RK_FBIOGET_PANEL_SIZE:    //get panel size
                	panel_size[0] = dev_drv->screen0->x_res;
                	panel_size[1] = dev_drv->screen0->y_res;
            		if(copy_to_user(argp, panel_size, 8)) 
				return -EFAULT;
			break;
		case RK_FBIOPUT_COLOR_KEY_CFG:
			if(copy_from_user(&clr_key_cfg,argp,sizeof(struct color_key_cfg ))) 
				return -EFAULT;
			lcdc_writel(lcdc_dev,WIN0_COLOR_KEY_CTRL,clr_key_cfg.win0_color_key_cfg);
			lcdc_writel(lcdc_dev,WIN1_COLOR_KEY_CTRL,clr_key_cfg.win1_color_key_cfg);
			lcdc_writel(lcdc_dev,WIN2_COLOR_KEY_CTRL,clr_key_cfg.win2_color_key_cfg);
			break;
		default:
			break;
	}

	return ret;
}
Exemple #7
0
static void atmel_hlcdfb_stop(struct atmel_lcdfb_info *sinfo, u32 flags)
{
	/* Disable DISP signal */
	lcdc_writel(sinfo, ATMEL_LCDC_LCDDIS, LCDC_LCDDIS_DISPDIS);
	while ((lcdc_readl(sinfo, ATMEL_LCDC_LCDSR) & LCDC_LCDSR_DISPSTS))
		mdelay(1);
	/* Disable synchronization */
	lcdc_writel(sinfo, ATMEL_LCDC_LCDDIS, LCDC_LCDDIS_SYNCDIS);
	while ((lcdc_readl(sinfo, ATMEL_LCDC_LCDSR) & LCDC_LCDSR_LCDSTS))
		mdelay(1);
	/* Disable pixel clock */
	lcdc_writel(sinfo, ATMEL_LCDC_LCDDIS, LCDC_LCDDIS_CLKDIS);
	while ((lcdc_readl(sinfo, ATMEL_LCDC_LCDSR) & LCDC_LCDSR_CLKSTS))
		mdelay(1);
	/* Disable PWM */
	lcdc_writel(sinfo, ATMEL_LCDC_LCDDIS, LCDC_LCDDIS_PWMDIS);
	while ((lcdc_readl(sinfo, ATMEL_LCDC_LCDSR) & LCDC_LCDSR_PWMSTS))
		mdelay(1);

	if (!(flags & ATMEL_LCDC_STOP_NOWAIT))
		/* Wait for the end of DMA transfer */
		while (!(lcdc_readl(sinfo, ATMEL_LCDC_BASEISR) & LCDC_BASEISR_DMA))
			mdelay(10);
		/*FIXME: OVL DMA? */
}
Exemple #8
0
static void init_contrast(struct atmel_lcdfb_info *sinfo)
{
	/* have some default contrast/backlight settings */
	lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, contrast_ctr);
	lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_VAL, ATMEL_LCDC_CVAL_DEFAULT);

	if (sinfo->lcdcon_is_backlight)
		init_backlight(sinfo);
}
Exemple #9
0
static void atmel_lcdfb_start(struct atmel_lcdfb_info *sinfo)
{
	struct atmel_lcdfb_platform_data *pdata = sinfo->pdata;

	lcdc_writel(sinfo, ATMEL_LCDC_DMACON, pdata->default_dmacon);
	lcdc_writel(sinfo, ATMEL_LCDC_PWRCON,
		(pdata->guard_time << ATMEL_LCDC_GUARDT_OFFSET)
		| ATMEL_LCDC_PWR);
}
Exemple #10
0
static void atmel_lcdfb_init_contrast(struct atmel_lcdfb_info *sinfo)
{
	/* contrast pwm can be 'inverted' */
	if (sinfo->lcdcon_pol_negative)
			contrast_ctr &= ~(ATMEL_LCDC_POL_POSITIVE);

	/* have some default contrast/backlight settings */
	lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, contrast_ctr);
	lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_VAL, ATMEL_LCDC_CVAL_DEFAULT);
}
static void atmel_lcdfb_stop_nowait(struct atmel_lcdfb_info *sinfo)
{
	
	lcdc_writel(sinfo, ATMEL_LCDC_PWRCON,
			sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET);

	
	while (lcdc_readl(sinfo, ATMEL_LCDC_PWRCON) & ATMEL_LCDC_BUSY)
		msleep(10);

	lcdc_writel(sinfo, ATMEL_LCDC_DMACON, 0);
}
static void atmel_lcdfb_stop_nowait(struct atmel_lcdfb_info *sinfo)
{
    /* Turn off the LCD controller and the DMA controller */
    lcdc_writel(sinfo, ATMEL_LCDC_PWRCON,
                sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET);

    /* Wait for the LCDC core to become idle */
    while (lcdc_readl(sinfo, ATMEL_LCDC_PWRCON) & ATMEL_LCDC_BUSY)
        msleep(10);

    lcdc_writel(sinfo, ATMEL_LCDC_DMACON, 0);
}
Exemple #13
0
/**
 *  	atmel_lcdfb_setcolreg - Optional function. Sets a color register.
 *      @regno: Which register in the CLUT we are programming
 *      @red: The red value which can be up to 16 bits wide
 *	@green: The green value which can be up to 16 bits wide
 *	@blue:  The blue value which can be up to 16 bits wide.
 *	@transp: If supported the alpha value which can be up to 16 bits wide.
 *      @info: frame buffer info structure
 *
 *  	Set a single color register. The values supplied have a 16 bit
 *  	magnitude which needs to be scaled in this function for the hardware.
 *	Things to take into consideration are how many color registers, if
 *	any, are supported with the current color visual. With truecolor mode
 *	no color palettes are supported. Here a psuedo palette is created
 *	which we store the value in pseudo_palette in struct fb_info. For
 *	pseudocolor mode we have a limited color palette. To deal with this
 *	we can program what color is displayed for a particular pixel value.
 *	DirectColor is similar in that we can program each color field. If
 *	we have a static colormap we don't need to implement this function.
 *
 *	Returns negative errno on error, or zero on success. In an
 *	ideal world, this would have been the case, but as it turns
 *	out, the other drivers return 1 on failure, so that's what
 *	we're going to do.
 */
static int atmel_lcdfb_setcolreg(unsigned int regno, unsigned int red,
                                 unsigned int green, unsigned int blue,
                                 unsigned int transp, struct fb_info *info)
{
    struct atmel_lcdfb_info *sinfo = info->par;
    unsigned int val;
    u32 *pal;
    int ret = 1;

    if (info->var.grayscale)
        red = green = blue = (19595 * red + 38470 * green
                              + 7471 * blue) >> 16;

    switch (info->fix.visual) {
    case FB_VISUAL_TRUECOLOR:
        if (regno < 16) {
            pal = info->pseudo_palette;

            val  = chan_to_field(red, &info->var.red);
            val |= chan_to_field(green, &info->var.green);
            val |= chan_to_field(blue, &info->var.blue);

            pal[regno] = val;
            ret = 0;
        }
        break;

    case FB_VISUAL_PSEUDOCOLOR:
        if (regno < 256) {
            val  = ((red   >> 11) & 0x001f);
            val |= ((green >>  6) & 0x03e0);
            val |= ((blue  >>  1) & 0x7c00);

            /*
             * TODO: intensity bit. Maybe something like
             *   ~(red[10] ^ green[10] ^ blue[10]) & 1
             */

            lcdc_writel(sinfo, ATMEL_LCDC_LUT(regno), val);
            ret = 0;
        }
        break;

    case FB_VISUAL_MONO01:
        if (regno < 2) {
            val = (regno == 0) ? 0x00 : 0x1F;
            lcdc_writel(sinfo, ATMEL_LCDC_LUT(regno), val);
            ret = 0;
        }
        break;

    }
static void init_contrast(struct atmel_lcdfb_info *sinfo)
{
	
	if (sinfo->lcdcon_pol_negative)
			contrast_ctr &= ~(ATMEL_LCDC_POL_POSITIVE);

	
	lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, contrast_ctr);
	lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_VAL, ATMEL_LCDC_CVAL_DEFAULT);

	if (sinfo->lcdcon_is_backlight)
		init_backlight(sinfo);
}
Exemple #15
0
static void atmel_hlcdfb_start(struct atmel_lcdfb_info *sinfo)
{
	lcdc_writel(sinfo, ATMEL_LCDC_LCDEN, LCDC_LCDEN_CLKEN);
	while (!(lcdc_readl(sinfo, ATMEL_LCDC_LCDSR) & LCDC_LCDSR_CLKSTS))
		mdelay(1);
	lcdc_writel(sinfo, ATMEL_LCDC_LCDEN, LCDC_LCDEN_SYNCEN);
	while (!(lcdc_readl(sinfo, ATMEL_LCDC_LCDSR) & LCDC_LCDSR_LCDSTS))
		mdelay(1);
	lcdc_writel(sinfo, ATMEL_LCDC_LCDEN, LCDC_LCDEN_DISPEN);
	while (!(lcdc_readl(sinfo, ATMEL_LCDC_LCDSR) & LCDC_LCDSR_DISPSTS))
		mdelay(1);
	lcdc_writel(sinfo, ATMEL_LCDC_LCDEN, LCDC_LCDEN_PWMEN);
	while (!(lcdc_readl(sinfo, ATMEL_LCDC_LCDSR) & LCDC_LCDSR_PWMSTS))
		mdelay(1);
}
Exemple #16
0
/*
 * the CLUT register map as following
 * RCLUT(24 ~ 16), GCLUT(15 ~ 8), BCLUT(7 ~ 0)
 */
void lcd_setcolreg(ushort regno, ushort red, ushort green, ushort blue)
{
	lcdc_writel(((red << LCDC_BASECLUT_RCLUT_Pos) & LCDC_BASECLUT_RCLUT_Msk)
		| ((green << LCDC_BASECLUT_GCLUT_Pos) & LCDC_BASECLUT_GCLUT_Msk)
		| ((blue << LCDC_BASECLUT_BCLUT_Pos) & LCDC_BASECLUT_BCLUT_Msk),
		panel_info.mmio + ATMEL_LCDC_LUT(regno));
}
Exemple #17
0
static int win2_open(struct rk30_lcdc_device *lcdc_dev,bool open)
{
	spin_lock(&lcdc_dev->reg_lock);
	if(likely(lcdc_dev->clk_on))
	{
		if(open)
		{
			if(!lcdc_dev->atv_layer_cnt)
			{
				printk(KERN_INFO "lcdc%d wakeup from standby!",lcdc_dev->id);
				lcdc_msk_reg(lcdc_dev, SYS_CTRL0,m_LCDC_STANDBY,v_LCDC_STANDBY(0));
			}
			lcdc_dev->atv_layer_cnt++;
		}
		else if((lcdc_dev->atv_layer_cnt > 0) && (!open))
		{
			lcdc_dev->atv_layer_cnt--;
		}
		lcdc_dev->driver.layer_par[1]->state = open;
		
		lcdc_msk_reg(lcdc_dev, SYS_CTRL1, m_W2_EN, v_W2_EN(open));

		if(!lcdc_dev->atv_layer_cnt)  //if no layer used,disable lcdc
		{
			printk(KERN_INFO "no layer of lcdc%d is used,go to standby!",lcdc_dev->id);
			lcdc_msk_reg(lcdc_dev, SYS_CTRL0,m_LCDC_STANDBY,v_LCDC_STANDBY(1));
		}
		
		lcdc_writel(lcdc_dev, REG_CFG_DONE, 0x01);
		lcdc_dev->driver.layer_par[1]->state = open;
	}
	spin_unlock(&lcdc_dev->reg_lock);
	
	return 0;
}
Exemple #18
0
/***********************************
overlay manager
swap:1 win0 on the top of win1
        0 win1 on the top of win0
set  : 1 set overlay 
        0 get overlay state
************************************/
static int rk30_lcdc_ovl_mgr(struct rk_lcdc_device_driver *dev_drv,int swap,bool set)
{
	struct rk30_lcdc_device *lcdc_dev = container_of(dev_drv,struct rk30_lcdc_device,driver);
	int ovl;
	spin_lock(&lcdc_dev->reg_lock);
	if(lcdc_dev->clk_on)
	{
		if(set)  //set overlay
		{
			lcdc_msk_reg(lcdc_dev,DSP_CTRL0,m_W0W1_POSITION_SWAP,v_W0W1_POSITION_SWAP(swap));
			lcdc_writel(lcdc_dev, REG_CFG_DONE, 0x01);
			lcdc_cfg_done(lcdc_dev);
			ovl = swap;
		}
		else  //get overlay
		{
			ovl = lcdc_read_bit(lcdc_dev,DSP_CTRL0,m_W0W1_POSITION_SWAP);
		}
	}
	else
	{
		ovl = -EPERM;
	}
	spin_unlock(&lcdc_dev->reg_lock);

	return ovl;
}
Exemple #19
0
static void atmel_lcdfb_update_dma2d(struct atmel_lcdfb_info *sinfo,
                                     struct fb_var_screeninfo *var)
{
    u32 dma2dcfg;
    u32 pixeloff;

    pixeloff = (var->xoffset * var->bits_per_pixel) & 0x1f;

    dma2dcfg = ((var->xres_virtual - var->xres) * var->bits_per_pixel) / 8;
    dma2dcfg |= pixeloff << ATMEL_LCDC_PIXELOFF_OFFSET;
    lcdc_writel(sinfo, ATMEL_LCDC_DMA2DCFG, dma2dcfg);

    /* Update configuration */
    lcdc_writel(sinfo, ATMEL_LCDC_DMACON,
                lcdc_readl(sinfo, ATMEL_LCDC_DMACON)
                | ATMEL_LCDC_DMAUPDT);
}
Exemple #20
0
static void atmel_lcdfb_stop(struct atmel_lcdfb_info *sinfo, u32 flags)
{
	/* Turn off the LCD controller and the DMA controller */
	lcdc_writel(sinfo, ATMEL_LCDC_PWRCON,
			sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET);

	/* Wait for the LCDC core to become idle */
	while (lcdc_readl(sinfo, ATMEL_LCDC_PWRCON) & ATMEL_LCDC_BUSY)
		msleep(10);

	lcdc_writel(sinfo, ATMEL_LCDC_DMACON, 0);

	if (!(flags & ATMEL_LCDC_STOP_NOWAIT))
		/* Wait for DMA engine to become idle... */
		while (lcdc_readl(sinfo, ATMEL_LCDC_DMACON) & ATMEL_LCDC_DMABUSY)
			msleep(10);
}
Exemple #21
0
static  int win2_display(struct rk30_lcdc_device *lcdc_dev,struct layer_par *par )
{
	u32 y_addr;
	u32 uv_addr;
	y_addr = par->smem_start + par->y_offset;
    	uv_addr = par->cbr_start + par->c_offset;
	DBG(2,KERN_INFO "lcdc%d>>%s>>y_addr:0x%x>>uv_addr:0x%x\n",lcdc_dev->id,__func__,y_addr,uv_addr);
	
	spin_lock(&lcdc_dev->reg_lock);
	if(likely(lcdc_dev->clk_on))
	{
		lcdc_writel(lcdc_dev, WIN2_MST, y_addr);
		lcdc_writel(lcdc_dev, REG_CFG_DONE, 0x01); 
	}
	spin_unlock(&lcdc_dev->reg_lock);
	
	return 0;
}
static void atmel_lcdfb_update_dma2d(struct atmel_lcdfb_info *sinfo,
				     struct fb_var_screeninfo *var,
				     struct fb_info *info)
{
	u32 dma2dcfg;
	u32 pixeloff;

	pixeloff = (var->xoffset * info->var.bits_per_pixel) & 0x1f;

	dma2dcfg = (info->var.xres_virtual - info->var.xres)
		 * info->var.bits_per_pixel / 8;
	dma2dcfg |= pixeloff << ATMEL_LCDC_PIXELOFF_OFFSET;
	lcdc_writel(sinfo, ATMEL_LCDC_DMA2DCFG, dma2dcfg);

	
	lcdc_writel(sinfo, ATMEL_LCDC_DMACON,
		    lcdc_readl(sinfo, ATMEL_LCDC_DMACON)
		    | ATMEL_LCDC_DMAUPDT);
}
Exemple #23
0
static  int win0_display(struct rk30_lcdc_device *lcdc_dev,struct layer_par *par )
{
	u32 y_addr;
	u32 uv_addr;
	y_addr = par->smem_start + par->y_offset;
    	uv_addr = par->cbr_start + par->c_offset;
	DBG(2,KERN_INFO "lcdc%d>>%s:y_addr:0x%x>>uv_addr:0x%x\n",lcdc_dev->id,__func__,y_addr,uv_addr);

	spin_lock(&lcdc_dev->reg_lock);
	if(likely(lcdc_dev->clk_on))
	{
		lcdc_writel(lcdc_dev, WIN0_YRGB_MST0, y_addr);
	    	lcdc_writel(lcdc_dev, WIN0_CBR_MST0, uv_addr);
		lcdc_cfg_done(lcdc_dev);
	}
	spin_unlock(&lcdc_dev->reg_lock);

	return 0;
	
}
Exemple #24
0
static void atmel_lcdfb_update_dma(struct fb_info *info)
{
	struct atmel_lcdfb_info *sinfo = info->priv;
	unsigned long dma_addr;

	dma_addr = (unsigned long)info->screen_base;

	dma_addr &= ~3UL;

	/* Set framebuffer DMA base address and pixel offset */
	lcdc_writel(sinfo, ATMEL_LCDC_DMABADDR1, dma_addr);
}
Exemple #25
0
void rk_lcdc_set_par(struct fb_dsp_info *fb_info, vidinfo_t *vid)
{
	struct lcdc_device *lcdc_dev = &rk32_lcdc;

	fb_info->layer_id = lcdc_dev->dft_win;
	switch (fb_info->layer_id) {
	case WIN0:
		win0_set_par(lcdc_dev, fb_info, vid);
		break;
	case WIN1:
		printf("%s --->WIN1 not support\n", __func__);
		break;
	default:
		printf("%s --->unknow lay_id \n", __func__);
		break;
	}
	lcdc_writel(lcdc_dev, BCSH_BCS, 0xd0010000);
	lcdc_writel(lcdc_dev, BCSH_H, 0x01000000);
	lcdc_writel(lcdc_dev, BCSH_COLOR_BAR, 1);
	lcdc_cfg_done(lcdc_dev);
}
Exemple #26
0
static void atmel_hlcdfb_update_dma(struct fb_info *info)
{
	struct atmel_lcdfb_info *sinfo = info->priv;
	unsigned long dma_addr;
	struct atmel_hlcd_dma_desc *desc;

	dma_addr = (u32)info->screen_base;
	dma_addr &= ~3UL;

	/* Setup the DMA descriptor, this descriptor will loop to itself */
	desc = sinfo->dma_desc;

	desc->address = dma_addr;
	/* Disable DMA transfer interrupt & descriptor loaded interrupt. */
	desc->control = LCDC_BASECTRL_ADDIEN | LCDC_BASECTRL_DSCRIEN
			| LCDC_BASECTRL_DMAIEN | LCDC_BASECTRL_DFETCH;
	desc->next = (u32)desc;

	lcdc_writel(sinfo, ATMEL_LCDC_BASEADDR, desc->address);
	lcdc_writel(sinfo, ATMEL_LCDC_BASECTRL, desc->control);
	lcdc_writel(sinfo, ATMEL_LCDC_BASENEXT, desc->next);
	lcdc_writel(sinfo, ATMEL_LCDC_BASECHER, LCDC_BASECHER_CHEN | LCDC_BASECHER_UPDATEEN);
}
Exemple #27
0
static void atmel_lcdfb_update_dma(struct fb_info *info,
                                   struct fb_var_screeninfo *var)
{
    struct atmel_lcdfb_info *sinfo = info->par;
    struct fb_fix_screeninfo *fix = &info->fix;
    unsigned long dma_addr;

    dma_addr = (fix->smem_start + var->yoffset * fix->line_length
                + var->xoffset * var->bits_per_pixel / 8);

    dma_addr &= ~3UL;

    /* Set framebuffer DMA base address and pixel offset */
    lcdc_writel(sinfo, ATMEL_LCDC_DMABADDR1, dma_addr);

    atmel_lcdfb_update_dma2d(sinfo, var);
}
Exemple #28
0
/**
 *      atmel_lcdfb_set_par - Alters the hardware state.
 *      @info: frame buffer structure that represents a single frame buffer
 *
 *	Using the fb_var_screeninfo in fb_info we set the resolution
 *	of the this particular framebuffer. This function alters the
 *	par AND the fb_fix_screeninfo stored in fb_info. It doesn't
 *	not alter var in fb_info since we are using that data. This
 *	means we depend on the data in var inside fb_info to be
 *	supported by the hardware.  atmel_lcdfb_check_var is always called
 *	before atmel_lcdfb_set_par to ensure this.  Again if you can't
 *	change the resolution you don't need this function.
 *
 */
static int atmel_lcdfb_set_par(struct fb_info *info)
{
    struct atmel_lcdfb_info *sinfo = info->par;
    unsigned long hozval_linesz;
    unsigned long value;
    unsigned long clk_value_khz;
    unsigned long bits_per_line;

    dev_dbg(info->device, "%s:\n", __func__);
    dev_dbg(info->device, "  * resolution: %ux%u (%ux%u virtual)\n",
            info->var.xres, info->var.yres,
            info->var.xres_virtual, info->var.yres_virtual);

    /* Turn off the LCD controller and the DMA controller */
    lcdc_writel(sinfo, ATMEL_LCDC_PWRCON, sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET);

    /* Wait for the LCDC core to become idle */
    while (lcdc_readl(sinfo, ATMEL_LCDC_PWRCON) & ATMEL_LCDC_BUSY)
        msleep(10);

    lcdc_writel(sinfo, ATMEL_LCDC_DMACON, 0);

    if (info->var.bits_per_pixel == 1)
        info->fix.visual = FB_VISUAL_MONO01;
    else if (info->var.bits_per_pixel <= 8)
        info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
    else
        info->fix.visual = FB_VISUAL_TRUECOLOR;

    bits_per_line = info->var.xres_virtual * info->var.bits_per_pixel;
    info->fix.line_length = DIV_ROUND_UP(bits_per_line, 8);

    /* Re-initialize the DMA engine... */
    dev_dbg(info->device, "  * update DMA engine\n");
    atmel_lcdfb_update_dma(info, &info->var);

    /* ...set frame size and burst length = 8 words (?) */
    value = (info->var.yres * info->var.xres * info->var.bits_per_pixel) / 32;
    value |= ((ATMEL_LCDC_DMA_BURST_LEN - 1) << ATMEL_LCDC_BLENGTH_OFFSET);
    lcdc_writel(sinfo, ATMEL_LCDC_DMAFRMCFG, value);

    /* Now, the LCDC core... */

    /* Set pixel clock */
    clk_value_khz = clk_get_rate(sinfo->lcdc_clk) / 1000;

    value = DIV_ROUND_UP(clk_value_khz, PICOS2KHZ(info->var.pixclock));

    value = (value / 2) - 1;
    dev_dbg(info->device, "  * programming CLKVAL = 0x%08lx\n", value);

    if (value <= 0) {
        dev_notice(info->device, "Bypassing pixel clock divider\n");
        lcdc_writel(sinfo, ATMEL_LCDC_LCDCON1, ATMEL_LCDC_BYPASS);
    } else {
        lcdc_writel(sinfo, ATMEL_LCDC_LCDCON1, value << ATMEL_LCDC_CLKVAL_OFFSET);
        info->var.pixclock = KHZ2PICOS(clk_value_khz / (2 * (value + 1)));
        dev_dbg(info->device, "  updated pixclk:     %lu KHz\n",
                PICOS2KHZ(info->var.pixclock));
    }


    /* Initialize control register 2 */
    value = sinfo->default_lcdcon2;

    if (!(info->var.sync & FB_SYNC_HOR_HIGH_ACT))
        value |= ATMEL_LCDC_INVLINE_INVERTED;
    if (!(info->var.sync & FB_SYNC_VERT_HIGH_ACT))
        value |= ATMEL_LCDC_INVFRAME_INVERTED;

    switch (info->var.bits_per_pixel) {
    case 1:
        value |= ATMEL_LCDC_PIXELSIZE_1;
        break;
    case 2:
        value |= ATMEL_LCDC_PIXELSIZE_2;
        break;
    case 4:
        value |= ATMEL_LCDC_PIXELSIZE_4;
        break;
    case 8:
        value |= ATMEL_LCDC_PIXELSIZE_8;
        break;
    case 15: /* fall through */
    case 16:
        value |= ATMEL_LCDC_PIXELSIZE_16;
        break;
    case 24:
        value |= ATMEL_LCDC_PIXELSIZE_24;
        break;
    case 32:
        value |= ATMEL_LCDC_PIXELSIZE_32;
        break;
    default:
        BUG();
        break;
    }
    dev_dbg(info->device, "  * LCDCON2 = %08lx\n", value);
    lcdc_writel(sinfo, ATMEL_LCDC_LCDCON2, value);

    /* Vertical timing */
    value = (info->var.vsync_len - 1) << ATMEL_LCDC_VPW_OFFSET;
    value |= info->var.upper_margin << ATMEL_LCDC_VBP_OFFSET;
    value |= info->var.lower_margin;
    dev_dbg(info->device, "  * LCDTIM1 = %08lx\n", value);
    lcdc_writel(sinfo, ATMEL_LCDC_TIM1, value);

    /* Horizontal timing */
    value = (info->var.right_margin - 1) << ATMEL_LCDC_HFP_OFFSET;
    value |= (info->var.hsync_len - 1) << ATMEL_LCDC_HPW_OFFSET;
    value |= (info->var.left_margin - 1);
    dev_dbg(info->device, "  * LCDTIM2 = %08lx\n", value);
    lcdc_writel(sinfo, ATMEL_LCDC_TIM2, value);

    /* Horizontal value (aka line size) */
    hozval_linesz = compute_hozval(info->var.xres,
                                   lcdc_readl(sinfo, ATMEL_LCDC_LCDCON2));

    /* Display size */
    value = (hozval_linesz - 1) << ATMEL_LCDC_HOZVAL_OFFSET;
    value |= info->var.yres - 1;
    dev_dbg(info->device, "  * LCDFRMCFG = %08lx\n", value);
    lcdc_writel(sinfo, ATMEL_LCDC_LCDFRMCFG, value);

    /* FIFO Threshold: Use formula from data sheet */
    value = ATMEL_LCDC_FIFO_SIZE - (2 * ATMEL_LCDC_DMA_BURST_LEN + 3);
    lcdc_writel(sinfo, ATMEL_LCDC_FIFO, value);

    /* Toggle LCD_MODE every frame */
    lcdc_writel(sinfo, ATMEL_LCDC_MVAL, 0);

    /* Disable all interrupts */
    lcdc_writel(sinfo, ATMEL_LCDC_IDR, ~0UL);

    /* Set contrast */
    value = ATMEL_LCDC_PS_DIV8 | ATMEL_LCDC_POL_POSITIVE | ATMEL_LCDC_ENA_PWMENABLE;
    lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, value);
    lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_VAL, ATMEL_LCDC_CVAL_DEFAULT);
    /* ...wait for DMA engine to become idle... */
    while (lcdc_readl(sinfo, ATMEL_LCDC_DMACON) & ATMEL_LCDC_DMABUSY)
        msleep(10);

    dev_dbg(info->device, "  * re-enable DMA engine\n");
    /* ...and enable it with updated configuration */
    lcdc_writel(sinfo, ATMEL_LCDC_DMACON, sinfo->default_dmacon);

    dev_dbg(info->device, "  * re-enable LCDC core\n");
    lcdc_writel(sinfo, ATMEL_LCDC_PWRCON,
                (sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET) | ATMEL_LCDC_PWR);

    dev_dbg(info->device, "  * DONE\n");

    return 0;
}
Exemple #29
0
static int win1_set_par(struct rk3188_lcdc_device *lcdc_dev,rk_screen *screen,
			   struct layer_par *par )
{
	u32 xact, yact, xvir, yvir, xpos, ypos;
	u8 fmt_cfg;

	xact = par->xact;			
	yact = par->yact;
	xvir = par->xvir;		
	yvir = par->yvir;
	xpos = par->xpos+screen->left_margin + screen->hsync_len;
	ypos = par->ypos+screen->upper_margin + screen->vsync_len;

	
	DBG(1,"lcdc%d>>%s>>format:%d>>>xact:%d>>yact:%d>>xsize:%d>>ysize:%d>>xvir:%d>>yvir:%d>>xpos:%d>>ypos:%d>>\n",
		lcdc_dev->id,__func__,par->format,xact,yact,par->xsize,par->ysize,xvir,yvir,xpos,ypos);

	
	spin_lock(&lcdc_dev->reg_lock);
	if(likely(lcdc_dev->clk_on))
	{
		
		lcdc_writel(lcdc_dev, WIN1_DSP_INFO,v_DSP_WIDTH(par->xsize) | v_DSP_HEIGHT(par->ysize));
		lcdc_writel(lcdc_dev, WIN1_DSP_ST,v_DSP_STX(xpos) | v_DSP_STY(ypos));
		// disable win1 color key and set the color to black(rgb=0)
		lcdc_msk_reg(lcdc_dev, WIN1_COLOR_KEY,m_COLOR_KEY_EN,v_COLOR_KEY_EN(0));
		switch(par->format)
		{
		case XBGR888:
			fmt_cfg = 0;
			lcdc_msk_reg(lcdc_dev, WIN_VIR,m_WIN1_VIR,v_WIN1_ARGB888_VIRWIDTH(xvir));
			//lcdc_msk_reg(lcdc_dev,ALPHA_CTRL,m_WIN1_ALPHA_EN,v_WIN1_ALPHA_EN(0));
			lcdc_msk_reg(lcdc_dev,SYS_CTRL,m_WIN1_RB_SWAP,v_WIN1_RB_SWAP(1));
			break;
		case ABGR888:
			fmt_cfg = 0;
			lcdc_msk_reg(lcdc_dev, WIN_VIR,m_WIN1_VIR,v_WIN1_ARGB888_VIRWIDTH(xvir));
			lcdc_msk_reg(lcdc_dev,ALPHA_CTRL,m_WIN1_ALPHA_EN,v_WIN1_ALPHA_EN(1));
			lcdc_msk_reg(lcdc_dev,DSP_CTRL0,m_WIN1_ALPHA_MODE | m_ALPHA_MODE_SEL0,
				v_WIN1_ALPHA_MODE(1) | v_ALPHA_MODE_SEL0(1));//default set to per-pixel alpha
			lcdc_msk_reg(lcdc_dev,SYS_CTRL,m_WIN1_RB_SWAP,v_WIN1_RB_SWAP(1));
			break;
		case ARGB888:
			fmt_cfg = 0;
			lcdc_msk_reg(lcdc_dev, WIN_VIR,m_WIN1_VIR,v_WIN1_ARGB888_VIRWIDTH(xvir));
			//lcdc_msk_reg(lcdc_dev,ALPHA_CTRL,m_WIN1_ALPHA_EN,v_WIN1_ALPHA_EN(1));
			//lcdc_msk_reg(lcdc_dev,DSP_CTRL0,m_WIN1_ALPHA_MODE | m_ALPHA_MODE_SEL0,
			//	v_WIN1_ALPHA_MODE(1) | v_ALPHA_MODE_SEL0(1));//default set to per-pixel alpha
			lcdc_msk_reg(lcdc_dev,SYS_CTRL,m_WIN1_RB_SWAP,v_WIN1_RB_SWAP(0));
			break;
		case RGB888:  //rgb888
			fmt_cfg = 1;
			lcdc_msk_reg(lcdc_dev, WIN_VIR,m_WIN1_VIR,v_WIN1_RGB888_VIRWIDTH(xvir));
			//lcdc_msk_reg(lcdc_dev,ALPHA_CTRL,m_WIN1_ALPHA_EN,v_WIN1_ALPHA_EN(0));
			lcdc_msk_reg(lcdc_dev,SYS_CTRL,m_WIN1_RB_SWAP,v_WIN1_RB_SWAP(0));
		 	//lcdc_msk_reg(lcdc_dev,SYS_CTRL1,m_W1_RGB_RB_SWAP,v_W1_RGB_RB_SWAP(1));
			break;
		case RGB565:  //rgb565
			fmt_cfg = 2;
			lcdc_msk_reg(lcdc_dev, WIN_VIR,m_WIN1_VIR,v_WIN1_RGB565_VIRWIDTH(xvir));
			//lcdc_msk_reg(lcdc_dev,ALPHA_CTRL,m_WIN1_ALPHA_EN,v_WIN1_ALPHA_EN(0));
			lcdc_msk_reg(lcdc_dev,SYS_CTRL,m_WIN1_RB_SWAP,v_WIN1_RB_SWAP(0));
			break;
		default:
			dev_err(lcdc_dev->driver.dev,"%s:un supported format!\n",__func__);
			break;
		}
		lcdc_msk_reg(lcdc_dev,SYS_CTRL,m_WIN1_FORMAT, v_WIN1_FORMAT(fmt_cfg));

	}
	spin_unlock(&lcdc_dev->reg_lock);

	return 0;
}
Exemple #30
0
static  int win0_set_par(struct rk3188_lcdc_device *lcdc_dev,rk_screen *screen,
			    struct layer_par *par )
{
	u32 xact, yact, xvir, yvir, xpos, ypos;
	u32 ScaleYrgbX = 0x1000;
	u32 ScaleYrgbY = 0x1000;
	u32 ScaleCbrX = 0x1000;
	u32 ScaleCbrY = 0x1000;
	u8 fmt_cfg =0 ; //data format register config value
	
	xact = par->xact;			    //active (origin) picture window width/height		
	yact = par->yact;
	xvir = par->xvir;			   // virtual resolution		
	yvir = par->yvir;
	xpos = par->xpos+screen->left_margin + screen->hsync_len;
	ypos = par->ypos+screen->upper_margin + screen->vsync_len;

	
	ScaleYrgbX = CalScale(xact, par->xsize); //both RGB and yuv need this two factor
	ScaleYrgbY = CalScale(yact, par->ysize);
	switch (par->format)
	{
	case ARGB888:
	case XBGR888:
	case ABGR888:
	     	fmt_cfg = 0;
		break;
	case RGB888:
		fmt_cfg = 1;
		break;
	case RGB565:
		fmt_cfg = 2;
		break;
	case YUV422:// yuv422
		fmt_cfg = 5;
		ScaleCbrX = CalScale((xact/2), par->xsize);
		ScaleCbrY = CalScale(yact, par->ysize);
		break;
	case YUV420: // yuv420
		fmt_cfg = 4;
		ScaleCbrX = CalScale(xact/2, par->xsize);
		ScaleCbrY = CalScale(yact/2, par->ysize);
		break;
	case YUV444:// yuv444
		fmt_cfg = 6;
		ScaleCbrX = CalScale(xact, par->xsize);
		ScaleCbrY = CalScale(yact, par->ysize);
		break;
	default:
		dev_err(lcdc_dev->driver.dev,"%s:un supported format!\n",__func__);
		break;
	}

	DBG(1,"lcdc%d>>%s>>format:%d>>>xact:%d>>yact:%d>>xsize:%d>>ysize:%d>>xvir:%d>>yvir:%d>>xpos:%d>>ypos:%d>>\n",
		lcdc_dev->id,__func__,par->format,xact,yact,par->xsize,par->ysize,xvir,yvir,xpos,ypos);
	
	spin_lock(&lcdc_dev->reg_lock);
	if(likely(lcdc_dev->clk_on))
	{
		lcdc_writel(lcdc_dev,WIN0_SCL_FACTOR_YRGB,v_X_SCL_FACTOR(ScaleYrgbX) | v_Y_SCL_FACTOR(ScaleYrgbY));
		lcdc_writel(lcdc_dev,WIN0_SCL_FACTOR_CBR,v_X_SCL_FACTOR(ScaleCbrX) | v_Y_SCL_FACTOR(ScaleCbrY));
		lcdc_msk_reg(lcdc_dev,SYS_CTRL,m_WIN0_FORMAT,v_WIN0_FORMAT(fmt_cfg));		//(inf->video_mode==0)
		lcdc_writel(lcdc_dev,WIN0_ACT_INFO,v_ACT_WIDTH(xact) | v_ACT_HEIGHT(yact));
		lcdc_writel(lcdc_dev,WIN0_DSP_ST,v_DSP_STX(xpos) | v_DSP_STY(ypos));
		lcdc_writel(lcdc_dev,WIN0_DSP_INFO,v_DSP_WIDTH(par->xsize) | v_DSP_HEIGHT(par->ysize));
		lcdc_msk_reg(lcdc_dev,WIN0_COLOR_KEY,m_COLOR_KEY_EN,v_COLOR_KEY_EN(0));
		
		switch(par->format) 
		{
		case XBGR888:
			lcdc_msk_reg(lcdc_dev, WIN_VIR,m_WIN0_VIR,v_ARGB888_VIRWIDTH(xvir));
			//lcdc_msk_reg(lcdc_dev,ALPHA_CTRL,m_WIN0_ALPHA_EN,v_WIN0_ALPHA_EN(0));
			lcdc_msk_reg(lcdc_dev,SYS_CTRL,m_WIN0_RB_SWAP,v_WIN0_RB_SWAP(1));
			break;
		case ABGR888:
			lcdc_msk_reg(lcdc_dev,WIN_VIR,m_WIN0_VIR,v_ARGB888_VIRWIDTH(xvir));
			//lcdc_msk_reg(lcdc_dev,ALPHA_CTRL,m_WIN0_ALPHA_EN,v_WIN0_ALPHA_EN(1));
			//lcdc_msk_reg(lcdc_dev,DSP_CTRL0,m_WIN0_ALPHA_MODE | m_ALPHA_MODE_SEL0 |
			//	m_ALPHA_MODE_SEL1,v_WIN0_ALPHA_MODE(1) | v_ALPHA_MODE_SEL0(1) |
			//	v_ALPHA_MODE_SEL1(0));//default set to per-pixel alpha
			lcdc_msk_reg(lcdc_dev,SYS_CTRL,m_WIN0_RB_SWAP,v_WIN0_RB_SWAP(1));
			break;
		case ARGB888:
			lcdc_msk_reg(lcdc_dev,WIN_VIR,m_WIN0_VIR,v_ARGB888_VIRWIDTH(xvir));
			//lcdc_msk_reg(lcdc_dev,ALPHA_CTRL,m_WIN0_ALPHA_EN,v_WIN0_ALPHA_EN(1));
			//lcdc_msk_reg(lcdc_dev,DSP_CTRL0,m_WIN0_ALPHA_MODE | m_ALPHA_MODE_SEL0,
			//	v_WIN0_ALPHA_MODE(1) | v_ALPHA_MODE_SEL0(1));//default set to per-pixel alpha
			lcdc_msk_reg(lcdc_dev,SYS_CTRL,m_WIN0_RB_SWAP,v_WIN0_RB_SWAP(0));
			break;
		case RGB888:  //rgb888
			lcdc_msk_reg(lcdc_dev, WIN_VIR,m_WIN0_VIR,v_RGB888_VIRWIDTH(xvir));
			//lcdc_msk_reg(lcdc_dev,ALPHA_CTRL,m_WIN0_ALPHA_EN,v_WIN0_ALPHA_EN(0));
			lcdc_msk_reg(lcdc_dev,SYS_CTRL,m_WIN0_RB_SWAP,v_WIN0_RB_SWAP(0));
			break;
		case RGB565:  //rgb565
			lcdc_msk_reg(lcdc_dev, WIN_VIR,m_WIN0_VIR,v_RGB565_VIRWIDTH(xvir));
			//lcdc_msk_reg(lcdc_dev,ALPHA_CTRL,m_WIN0_ALPHA_EN,v_WIN0_ALPHA_EN(0));
			lcdc_msk_reg(lcdc_dev,SYS_CTRL,m_WIN0_RB_SWAP,v_WIN0_RB_SWAP(0));
			break;
		case YUV422:
		case YUV420:
		case YUV444:
			lcdc_msk_reg(lcdc_dev, WIN_VIR,m_WIN0_VIR,v_YUV_VIRWIDTH(xvir));
			//lcdc_msk_reg(lcdc_dev,ALPHA_CTRL,m_WIN0_ALPHA_EN,v_WIN0_ALPHA_EN(0));
			lcdc_msk_reg(lcdc_dev,SYS_CTRL,m_WIN0_RB_SWAP,v_WIN0_RB_SWAP(0));
			break;
		default:
			dev_err(lcdc_dev->driver.dev,"%s:un supported format!\n",__func__);
			break;
		}
		lcdc_cfg_done(lcdc_dev);

	}
	spin_unlock(&lcdc_dev->reg_lock);

    return 0;

}