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

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

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

分成红、绿、蓝三基色)*/

fbinfo->fix.visual = FB_VISUAL_TRUECOLOR;

break;

case 1:/*1BPP时,设置为黑白色(分黑、白两种色,FB_VISUAL_MONO01代表黑,FB_VISUAL_MONO10代表白)*/

fbinfo->fix.visual = FB_VISUAL_MONO01;

break;

default:/*默认设置为伪彩色,采用索引颜色显示*/

fbinfo->fix.visual = FB_VISUAL_PSEUDOCOLOR;

break;

}

/*设置fb_info中固定参数中一行的字节数,公式:1行字节数=(1行像素个数*每像素位数BPP)/8 */

fbinfo->fix.line_length = (var->xres_virtual * var->bits_per_pixel) / 8;

/*修改以上参数后,重新激活fb_info中的参数配置(即:使修改后的参数在硬件上生效)*/

my2440fb_activate_var(fbinfo);

return 0;

}

/*重新激活fb_info中的参数配置*/

static void my2440fb_activate_var(struct fb_info *fbinfo)

{

/*获得结构体变量*/

struct my2440fb_var *fbvar = fbinfo->par;

void __iomem *regs = fbvar->lcd_base;

/*获得fb_info可变参数*/

struct fb_var_screeninfo *var = &fbinfo->var;

/*计算LCD控制寄存器1中的CLKVAL值, 根据数据手册中该寄存器的描述,计算公式如下:

* STN屏:VCLK = HCLK / (CLKVAL * 2), CLKVAL要求>= 2

* TFT屏:VCLK = HCLK / [(CLKVAL + 1) * 2], CLKVAL要求>= 0*/

int clkdiv = my2440fb_calc_pixclk(fbvar, var->pixclock) / 2;

/*获得屏幕的类型*/

int type = fbvar->regs.lcdcon1 & S3C2410_LCDCON1_TFT;

if (type == S3C2410_LCDCON1_TFT)

{

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

my2440fb_config_tft_lcd_regs(fbinfo, &fbvar->regs);

--clkdiv;

if (clkdiv < 0)

{

clkdiv = 0;

}

}

else

{

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

my2440fb_config_stn_lcd_regs(fbinfo, &fbvar->regs);

if (clkdiv < 2)

{

clkdiv = 2;

}

}

/*设置计算的LCD控制寄存器1中的CLKVAL值*/

fbvar->regs.lcdcon1 |= S3C2410_LCDCON1_CLKVAL(clkdiv);

/*将各参数值写入LCD控制寄存器1-5中*/

writel(fbvar->regs.lcdcon1 & ~S3C2410_LCDCON1_ENVID, regs + S3C2410_LCDCON1);

writel(fbvar->regs.lcdcon2, regs + S3C2410_LCDCON2);

writel(fbvar->regs.lcdcon3, regs + S3C2410_LCDCON3);

writel(fbvar->regs.lcdcon4, regs + S3C2410_LCDCON4);

writel(fbvar->regs.lcdcon5, regs + S3C2410_LCDCON5);

/*配置帧缓冲起始地址寄存器1-3*/

my2440fb_set_lcdaddr(fbinfo);

fbvar->regs.lcdcon1 |= S3C2410_LCDCON1_ENVID,

writel(fbvar->regs.lcdcon1, regs + S3C2410_LCDCON1);

}

/*计算LCD控制寄存器1中的CLKVAL值*/

static unsigned int my2440fb_calc_pixclk(struct my2440fb_var *fbvar, unsigned long pixclk)

{

/*获得LCD的时钟*/

unsigned long clk = clk_get_rate(fbvar->lcd_clock);

/* 像素时钟单位是皮秒,而时钟的单位是赫兹,所以计算公式为:

* Hz -> picoseconds is / 10^-12

*/

unsigned long long div = (unsigned long long)clk * pixclk;

div >>= 12;/* div / 2^12 */

do_div(div, 625 * 625UL * 625); /* div / 5^12, do_div宏定义在asm/div64.h中*/

return div;

}

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

static void my2440fb_config_tft_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;

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

switch (var->bits_per_pixel)

{

case 1:/*1BPP*/

regs->lcdcon1 |= S3C2410_LCDCON1_TFT1BPP;

break;

case 2:/*2BPP*/

regs->lcdcon1 |= S3C2410_LCDCON1_TFT2BPP;

break;

case 4:/*4BPP*/

regs->lcdcon1 |= S3C2410_LCDCON1_TFT4BPP;

break;

case 8:/*8BPP*/

regs->lcdcon1 |= S3C2410_LCDCON1_TFT8BPP;

regs->lcdcon5 |= S3C2410_LCDCON5_BSWP | S3C2410_LCDCON5_FRM565;

regs->lcdcon5 &= ~S3C2410_LCDCON5_HWSWP;

break;

case 16:/*16BPP*/

regs->lcdcon1 |= S3C2410_LCDCON1_TFT16BPP;

regs->lcdcon5 &= ~S3C2410_LCDCON5_BSWP;

regs->lcdcon5 |= S3C2410_LCDCON5_HWSWP;

break;

case 32:/*32BPP*/

regs->lc

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

网站地图

Top