摩尔芯闻 > 行业新闻 > 半导体 > s3c2440的LCD驱动程序

s3c2440的LCD驱动程序

eefocus ·2020-04-25 00:00·电子工程世界
阅读:1575

本文档是看韦东山老师的LCD驱动视频手打下来的,所以可能会提示头文件找不到啊之类的,呵呵。另外cfb_fillrect.ko,cfb_copyarea.ko ,cfb_imageblit.ko这三个模块可以在内核的/drivers/video找到


#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

static int s3c_lcdfb_setcolreg(unsigned int regno,unsigned int red,unsigned int green,unsigned int blue,unsigned int transp,struct fb_info *info);

struct lcd_regs={

unsigned long lcdcon1;

unsigned long lcdcon2;

unsigned long lcdcon3;

unsigned long lcdcon4;

unsigned long lcdcon5;

unsigned long lcdsaddr1;

unsigned long lcdsaddr2;

unsigned long lcdsaddr3;

unsigned long redlut;

unsigned long greenlut;

unsigned long bluelut;

unsigned long reserved[9];

unsigned long dithmode;

unsigned long tpal;

unsigned long lcdintpnd;

unsigned long lcdsrcpnd;

unsigned long lcdintmsk;

unsigned long lpcsel;

};

static struct fb_ops s3c_lcdfb_ops={

.owner =THIS_MODULE,

.fb_setcolreg =s3c_lcdfb_setcolreg,

/*这三个函数分别由三个模块(在drivers/vedio目录下)来具体实现,然后一起加载,它们经常用到,所以这里不用实现他们*/

.fb_fillrect =cfb_fillrect,/*填充矩形 */

.fb_copyarea =cfb_copyarea,/*拷贝一个区域*/

.fb_imageblit =cfb_imageblit,

};

static struct fb_info *s3c_lcd;/*分配info结构体*/

/*GPIO控制器*/

static volatile unsigned long *gpbcon;

static volatile unsigned long *gpbdat;

static volatile unsigned long *gpccon;

static volatile unsigned long *gpdcon;

static volatile unsigned long *gpgcon;

static volatile struct lcd_regs *lcd_regs;

static u32 pseudo_palette[16];/*假的调色板*/

/*调色板函数*/

/*5:6:5 format*/

static int s3c_lcdfb_setcolreg(unsigned int regno,unsigned int red,unsigned int green,unsigned int blue,unsigned int transp,struct fb_info *info)

{

unsigned int val;

if(regno>16)

return 1;

/*用red,green,blue三原色构造出val*/

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

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

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

//((u32 *)(info->pseudo_palette))[regno]=val;

pseudo_palette[regno]=val;

return 0;

}

static int lcd_init(void)

{

/*1.分配一个fb_info

*其中分配时fb_info里面的值默认都是0,所有下面有些参数可以不用设置默认0

*/

s3c_lcd=framebuffer_alloc(0,NULL); /*其中0代表不需要额外的私有数据空间*/

/*2.设置*/

/*2.1设置固定的参数*/

strcpy(s3c_lcd->fix.id,"mylcd"); /*设置fix的名称*/

s3c_lcd->fix.smem_len =240*320*16; /*按具体的屏幕--设置一帧的大小*/

s3c_lcd->fix.type =FB_TYPE_PACKED_PIXELS;/*默认值0*/

s3c_lcd->fix.visual =FB_VISUAL_TRUECOLOR; /*TFT真彩色*/

s3c_lcd->fix.line_lenth  =240*2; /*一行的长度大小。。单位byte*/

/*2.2设置可变的参数*/

s3c_lcd->var.xres =240; /*x方向的分辨率*/

s3c_lcd->var.yres =320; /*y方向的分辨率*/

s3c_lcd->var.xres_virtual =240; /*x方向的虚拟分辨率*/

s3c_lcd->var.xres_virtual =320; /*y方向的虚拟分辨率*/

s3c_lcd->var.bits_per_pixel =16; /*每个像素16位--bpp*/

/*RGB--5:6:5*/

s3c_lcd->var.red.offset =11; /*第11位开始*/

s3c_lcd->var.red.length =5; /*长度5位*/

s3c_lcd->var.green.offset =5;

s3c_lcd->var.green.length =6;

s3c_lcd->var.blue.offset =0;

s3c_lcd->var.blue.length =5;

s3c_lcd->var.activate =FB_ACTIVATE_NOW;

/*2.3设置操作函数*/

s3c_lcd->fbops =&s3c_lcdfb_ops;

/*2.4其他的设置*/

s3c_lcd->pseudo_palette = pseudo_palette;

//s3c_lcd->screen_base =; /*显存的虚拟地址*/

s3c_lcd->screen_size =240*320*2; /*屏幕的大小,单位byte*/

/*3.硬件相关的设置*/

/*3.1配置GPIO用于LCD*/

gpbcon=ioremap(0x56000010,8);

gpbdat=gpbcon+1;/*相当于+4 byte*/

gpccon=ioremap(0x56000020,4);

gpdcon=ioremap(0x56000030,4);

gpgcon=ioremap(0x56000060,4);

*gpccon=0xaaaaaaaa;/*GPIO管脚用于VD[7:0],LCDVF[2:0],VM,VFRAME,VLINE,VCLK,LEND*/

*gpdcon=0xaaaaaaaa;/*GPIO管脚用于VD[23:8]*/

*gpbcon&=~(3);/*GPBO设置为输出引脚*/

*gpbcon |=1;

*gpbdat &=~1;/*输出低电平*/

*gpgcon|=(3<<8);/*GPG4用作LCD_PWREN*/

/*3.2根据LCD手册设置LCD控制器,比如VCLK的频率等*/

lcd_regs=ioremap(0x4D000000,sizeof(struct lcd_regs));

/*bit[17:8]:VCLK=HCLK/[(CLKVAL+1)*2],LCD手册P14

* 10MHz=100MHz/[CLKVAL+1]*2]

*          10MHz是我们2440手册里的100ns得出的(1us->1MHz)

* 100MHz是我们主机的频率

* CLKVAL=4

*bit[6:5]: ob11,TFT LCD

*bit[4:1]: ob1100,16 bpp for TFT

*bit[0]:  0=Disable the video output and the LCD control signal.

*/

lcd_regs->lcdcon1  =(4<<8) | (3<<5) | (0x0c<<1);

/*垂直方向的时间参数

*bit[31:24]:VBPD,VSYNC之后再过多长时间才能发出第1行数据

* LCD手册  T0-T2-T1=4

* VBPD=3

*bit[23:14]:多少行,320,所以LINEVAL=320-1=319

*bit[13:6] :VFPD,发出最后一行数据之后,再过多长时间才发出VSYNC

* LCD手册T2-T5=322-320=2,所以VFPD=2-1=1

*bit[5:0] : VSPW,VSYNC信号的脉冲宽度,LCD手册T1=1,所以VSPW=1-1=0

*/

lcd_regs->lcdcon2 =(3<<24) | (319<<14) | (1<<6) | (0<<0);

/*水平方向的时间参数

*bit[25:19]:HBPD,HSYNC之后再过多长时间才能发出第1行数据

* LCD手册  T6-T7-T8=17

* HBPD=16

*bit[18:8]:多少列,240,所以HOZVAL=240-1=239

*bit[7:0]:HFPD,发出最后一行里最后一个像素数据之后,再过多长时间才能发出HSYNC

* LCD手册T8-T11=251-240=11,所以HFPD=11-1=10

*/

lcd_regs->lcdcon3=(16<<19) | (239<<9) | (10<<0);

/*水平方向的同步信号

*bit[7:0]:HSPW,HSYNC信号的脉冲宽度,LCD手册T7=5,所以HSPW=5-1=4

*/

lcd_regs->lcdcon4=4;

/*信号的极性

*bit[11]: 1=5:6:5 format

*bit[10]: 0=The video data is fetched at VCLK falling edge

*bit[9]:  1=HSYNC信号要反转,即低电平有效

*bit[8]:  1=VSYNC信号要反转,即低电平有效

*bit[6]:  0=VDEN不用反转

*bit[3]:  0=PWREN输出0

*下面两位控制在framebuffer中[0:31]->[P1,P2]还是[p2,p1]

*bit[1]:  0=BSWP

*bit[0]:  1=HWSWP 2440手册P413

*很明显是[p1,p2]

*/

lcd_regs->lcdcon5= (1<<11) | (0<<10) | (1<<9) | (1<<8) | (1<<0);

/*3.3分配显存(framebuffer),并把地址告诉LCD控制器*/

/*申请一块连续的内存,返回虚拟地址*/

s3c_lcd->screen_base=dma_alloc_writecombine(NULL,s3c_lcd->fix.smem_len,&s3c_lcd->fix.smem_start,GFP_KERNEL);

/*lcdsaddr1的bit[29:0]对应A[30:1],最低1位不要,所以右移一位--最高两位不需要--清0*/

lcd_regs->lcdsaddr1=(s3c_lcd->fix.smem_start>>1) & ~(3<<30);

/*lcsaddr2的bit[20:0]对应A[21:1],所以最低一位不需要,右移一位,其他位清0*/

lcd_regs->lcdsaddr2=((s3c_lcd->fix.smem_start+s3c_lcd->fix.smem_len)>>1)& 0x1fffff;

lcd_regs->lcdsaddr3=(240*16/16);/*一行的长度(单位2字节)*/

//s3c_lcd->fix.smem_start=xxx;/*显存的物理地址*/

/*启动LCD*/

lcd_regs->lcdcon1 |=(1<<0);/*使能LCD控制器*/

lcd_regs->lcdcon5 |=(1<<3);/*使能LCD本身*/

*gpbdat |=1; /*输出高电平,使能背光*/

/*4.注册*/

register_framebuffer(s3c_lcd);

return 0;

}

static void lcd_exit(void)

{

unrigster_framebuffer(s3c_lcd);

lcd_regs->lcdcon1 &= ~(1<<0); /*关闭LCD本身*/

*gpbdat &=~1; /*关闭背光*/

dma_free_writecombine(NULL,s3c_lcd->fix.smem_len,s3c_lcd->screen_base,s3c_lcd->fix.smem_start);

iounmap(lcd_regs);

iounmap(gpbcon);

iounmap(gpccon);

iounmap(gpdcon);

iounmap(gpgcon);

framebuffer_release(s3c_lcd);

}

module_init(lcd_init);

module_exit(lcd_exit);

MODULE_LICENSE("GPL");

关键字: s3c2440 LCD 驱动程序 编辑:什么鱼 引用地址: http://news.eeworld.com.cn/mcu/ic495363.html 本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。
分享到:
微信 新浪微博 QQ空间 LinkedIn

上一篇:《韦东山视频第二期》——LCD驱动

下一篇:新基建下的工业智能,既红红火火又恍恍惚惚

打开摩尔直播,更多新闻内容
半导体大咖直播分享高清观看
立即下载