微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > S3C2440上LCD驱动(FrameBuffer)实例开发讲解(二)

S3C2440上LCD驱动(FrameBuffer)实例开发讲解(二)

时间:08-15 来源:互联网 点击:

dcon1 |= S3C2410_LCDCON1_TFT24BPP;

regs->lcdcon5 &= ~(S3C2410_LCDCON5_BSWP | S3C2410_LCDCON5_HWSWP | S3C2410_LCDCON5_BPP24BL);

break;

default:/*无效的BPP*/

dev_err(fbvar->dev, "invalid bpp %d\n", var->bits_per_pixel);

}

/*设置LCD配置寄存器2、3、4*/

regs->lcdcon2 = S3C2410_LCDCON2_LINEVAL(var->yres - 1) |

S3C2410_LCDCON2_VBPD(var->upper_margin - 1) |

S3C2410_LCDCON2_VFPD(var->lower_margin - 1) |

S3C2410_LCDCON2_VSPW(var->vsync_len - 1);

regs->lcdcon3 = S3C2410_LCDCON3_HBPD(var->right_margin - 1) |

S3C2410_LCDCON3_HFPD(var->left_margin - 1) |

S3C2410_LCDCON3_HOZVAL(var->xres - 1);

regs->lcdcon4 = S3C2410_LCDCON4_HSPW(var->hsync_len - 1);

}

/*根据数据手册按照STN屏的要求配置LCD控制寄存器1-5*/

static void my2440fb_config_stn_lcd_regs(const struct fb_info *fbinfo, struct s3c2410fb_hw *regs)

{

const struct my2440fb_var *fbvar = fbinfo->par;

const struct fb_var_screeninfo *var = &fbinfo->var;

int type = regs->lcdcon1 & ~S3C2410_LCDCON1_TFT;

int hs = var->xres >> 2;

unsigned wdly = (var->left_margin >> 4) - 1;

unsigned wlh = (var->hsync_len >> 4) - 1;

if (type != S3C2410_LCDCON1_STN4)

{

hs >>= 1;

}

/*根据色位模式设置LCD控制寄存器1,参考数据手册*/

switch (var->bits_per_pixel)

{

case 1:/*1BPP*/

regs->lcdcon1 |= S3C2410_LCDCON1_STN1BPP;

break;

case 2:/*2BPP*/

regs->lcdcon1 |= S3C2410_LCDCON1_STN2GREY;

break;

case 4:/*4BPP*/

regs->lcdcon1 |= S3C2410_LCDCON1_STN4GREY;

break;

case 8:/*8BPP*/

regs->lcdcon1 |= S3C2410_LCDCON1_STN8BPP;

hs *= 3;

break;

case 12:/*12BPP*/

regs->lcdcon1 |= S3C2410_LCDCON1_STN12BPP;

hs *= 3;

break;

default:/*无效的BPP*/

dev_err(fbvar->dev, "invalid bpp %d\n", var->bits_per_pixel);

}

/*设置LCD配置寄存器2、3、4, 参考数据手册*/

if (wdly > 3) wdly = 3;

if (wlh > 3) wlh = 3;

regs->lcdcon2 = S3C2410_LCDCON2_LINEVAL(var->yres - 1);

regs->lcdcon3 = S3C2410_LCDCON3_WDLY(wdly) |

S3C2410_LCDCON3_LINEBLANK(var->right_margin / 8) |

S3C2410_LCDCON3_HOZVAL(hs - 1);

regs->lcdcon4 = S3C2410_LCDCON4_WLH(wlh);

}

/*配置帧缓冲起始地址寄存器1-3,参考数据手册*/

static void my2440fb_set_lcdaddr(struct fb_info *fbinfo)

{

unsigned long saddr1, saddr2, saddr3;

struct my2440fb_var *fbvar = fbinfo->par;

void __iomem *regs = fbvar->lcd_base;

saddr1 = fbinfo->fix.smem_start >> 1;

saddr2 = fbinfo->fix.smem_start;

saddr2 += fbinfo->fix.line_length * fbinfo->var.yres;

saddr2 >>= 1;

saddr3 = S3C2410_OFFSIZE(0) | S3C2410_PAGEWIDTH((fbinfo->fix.line_length / 2) & 0x3ff);

writel(saddr1, regs + S3C2410_LCDSADDR1);

writel(saddr2, regs + S3C2410_LCDSADDR2);

writel(saddr3, regs + S3C2410_LCDSADDR3);

}

/*显示空白,blank mode有5种模式,定义在fb.h中,是一个枚举*/

static int my2440fb_blank(int blank_mode, struct fb_info *fbinfo)

{

struct my2440fb_var *fbvar = fbinfo->par;

void __iomem *regs = fbvar->lcd_base;

/*根据显示空白的模式来设置LCD是开启还是停止*/

if (blank_mode == FB_BLANK_POWERDOWN)

{

my2440fb_lcd_enable(fbvar, 0);/*在第②步中定义*/

}

else

{

my2440fb_lcd_enable(fbvar, 1);/*在第②步中定义*/

}

/*根据显示空白的模式来控制临时调色板寄存器*/

if (blank_mode == FB_BLANK_UNBLANK)

{

/*临时调色板寄存器无效*/

writel(0x0, regs + S3C2410_TPAL);

}

else

{

/*临时调色板寄存器有效*/

writel(S3C2410_TPAL_EN, regs + S3C2410_TPAL);

}

return 0;

}

/*设置颜色表*/

static int my2440fb_setcolreg(unsigned regno,unsigned red,unsigned green,unsigned blue,unsigned transp,struct fb_info *fbinfo)

{

unsigned int val;

struct my2440fb_var *fbvar = fbinfo->par;

void __iomem *regs = fbvar->l

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top