linux2628下6410LCD驱动分析文档格式.docx

上传人:b****5 文档编号:20500953 上传时间:2023-01-23 格式:DOCX 页数:27 大小:49.07KB
下载 相关 举报
linux2628下6410LCD驱动分析文档格式.docx_第1页
第1页 / 共27页
linux2628下6410LCD驱动分析文档格式.docx_第2页
第2页 / 共27页
linux2628下6410LCD驱动分析文档格式.docx_第3页
第3页 / 共27页
linux2628下6410LCD驱动分析文档格式.docx_第4页
第4页 / 共27页
linux2628下6410LCD驱动分析文档格式.docx_第5页
第5页 / 共27页
点击查看更多>>
下载资源
资源描述

linux2628下6410LCD驱动分析文档格式.docx

《linux2628下6410LCD驱动分析文档格式.docx》由会员分享,可在线阅读,更多相关《linux2628下6410LCD驱动分析文档格式.docx(27页珍藏版)》请在冰豆网上搜索。

linux2628下6410LCD驱动分析文档格式.docx

//根据这个进行匹配

.id 

=-1,

.num_resources 

=ARRAY_SIZE(s3c_lcd_resource),

.resource 

=s3c_lcd_resource,

.dev 

={

.dma_mask 

=&

s3c_device_lcd_dmamask,

.coherent_dma_mask 

=0xffffffffUL

在arch/arm/mach-s3c6410/mach-smdk6410.c文件的

staticvoid__initsmdk6410_machine_init(void)函数中有这么一句话

platform_add_devices(smdk6410_devices,ARRAY_SIZE(smdk6410_devices));

这个就是对device设备进行注册,在注册driver驱动时,会根据name找到相应的device进行匹配,然后会调用probe。

下面分析driver,在drivers/video/samsung/s3cfb.c文件的最下面有这样的一段代码

staticstructplatform_drivers3cfb_driver={

.probe 

=s3cfb_probe, 

//匹配的话会调用这个函数

.remove 

=s3cfb_remove,

.suspend 

=s3cfb_suspend,

.resume 

=s3cfb_resume,

.driver 

={

="

//上面说的,内核会根据这个来找到相应的device

.owner 

=THIS_MODULE,

int__devinits3cfb_init(void)

{

returnplatform_driver_register(&

s3cfb_driver);

//进行drive注册

匹配后会掉用s3cfb_probe();

这个函数里面对fbinfo进行初始化,对相关寄存器进行初始化,在6410lcd驱动中,主要要修改的几个文件是:

drivers/video/samsung目录下的s3cfb.c,假设你在配置的时候即用makemenuconfig命令,在里面选择的是480WV,他对应的文件时s3cfb_lte480wv.c,s3cfb_lte480wv.c是和屏参数相关的文件。

还有个要改的文件是s3cfb_fimd4x.c,这个文件主要是涉及寄存器的一些参数的配置。

主要几个重点:

对构架的分析,理清楚各个文件的关系。

s3cfb.c中的s3cfb_probe主要是在根据s3cfb_fimd4x.c和s3cfb_lte480wv.c文件来初始fbinfo,并且写相关LCD寄存器。

s3cfb_lte480wv.c主要是记录屏的参数,在这里进行修改来满足不同的lcd屏。

s3cfb_fimd4x.c是对寄存器的值进行初始化,比如各个窗口的显示模式、颜色表寄存器的模式、各个窗口的控制寄存器,此文件还包含6410对于lcd的特殊功能,用ioctl来进行实现的。

fbmem.c这个是fb字符设备驱动,每个窗口都是一个字符设备,在s3cfb_probe中通过调用register_buffer进行注册,注意,里面有一个fb_notifier_call_chain,他最终会调用drivers/video/console/fbcon.c中的fbcon_init,里面会有对logo的调用;

fbmem.c文件里还有通用的ioctl功能调用,适合所有带lcd控制器的处理器,这个文件时通用的,每个处理器的fbmem都是一样的,做成了和硬件无关。

lcd驱动简单构架图 

abc

s3c2410_lcd&

framebuffer驱动分析

int__inits3c2410fb_probe(structdevice*dev)

structs3c2410fb_info*info;

structfb_info 

 

*fbinfo;

structplatform_device*pdev=to_platform_device(dev);

structs3c2410fb_hw*mregs;

intret;

intirq;

inti;

mach_info=dev->

platform_data;

//获取lcd相关寄存器配置信息

if(mach_info==NULL){

dev_err(dev,"

noplatformdataforlcd,cannotattach\n"

);

return-EINVAL;

}

mregs=&

mach_info->

regs;

irq=platform_get_irq(pdev,0);

if(irq<

0){

dev_err(dev,"

noirqfordevice\n"

return-ENOENT;

fbinfo=framebuffer_alloc(sizeof(structs3c2410fb_info),dev);

//分配structfb_info和structs3c2410fb_info结构

if(!

fbinfo){

return-ENOMEM;

info=fbinfo->

par;

//调用framebuffer_alloc分配内存的时候,其实顺带分配了structs3c2410fb_info结构,紧跟structfb_info结构的后面,fbinfo->

par指针处。

info->

fb=fbinfo;

dev_set_drvdata(dev,fbinfo);

s3c2410fb_init_registers(info);

//lcd相关寄存器配置

dprintk("

devinit\n"

strcpy(fbinfo->

fix.id,driver_name);

/*配置信息存储起来,以后用到*/

memcpy(&

info->

regs,&

regs,sizeof(info->

regs));

mach_info 

=dev->

/*以下配置,详细请参考网上资料*/

fbinfo->

fix.type 

=FB_TYPE_PACKED_PIXELS;

fix.type_aux 

=0;

fix.xpanstep 

fix.ypanstep 

fix.ywrapstep 

fix.accel 

=FB_ACCEL_NONE;

var.nonstd 

var.activate 

=FB_ACTIVATE_NOW;

/*设置分辨率*/

var.height 

=mach_info->

height;

var.width 

width;

var.accel_flags 

var.vmode 

=FB_VMODE_NONINTERLACED;

fbops 

=&

s3c2410fb_ops;

//重要的fop结构(fb设备本质上是字符设备)

flags 

=FBINFO_FLAG_DEFAULT;

pseudo_palette 

pseudo_pal;

var.xres 

xres.defval;

var.xres_virtual 

var.yres 

yres.defval;

var.yres_virtual 

var.bits_per_pixel 

bpp.defval;

var.upper_margin 

=S3C2410_LCDCON2_GET_VBPD(mregs->

lcdcon2)+1;

var.lower_margin 

=S3C2410_LCDCON2_GET_VFPD(mregs->

var.vsync_len 

=S3C2410_LCDCON2_GET_VSPW(mregs->

lcdcon2)+1;

var.left_margin 

=S3C2410_LCDCON3_GET_HFPD(mregs->

lcdcon3)+1;

var.right_margin 

=S3C2410_LCDCON3_GET_HBPD(mregs->

var.hsync_len 

=S3C2410_LCDCON4_GET_HSPW(mregs->

lcdcon4)+1;

/*配色板设置(采用5、6、5模式)*/

var.red.offset 

=11;

var.green.offset 

=5;

var.blue.offset 

var.transp.offset 

var.red.length 

var.green.length 

=6;

var.blue.length 

var.transp.length 

/*计算需要申请的framerbuffer大小(以字节为单位)*/

fix.smem_len 

mach_info->

xres.max*

yres.max*

bpp.max/8;

for(i=0;

i<

256;

i++)

palette_buffer[i]=PALETTE_BUFF_CLEAR;

request_mem_region((unsignedlong)S3C24XX_VA_LCD,SZ_1M,"

s3c2410-lcd"

)){

ret=-EBUSY;

gotodealloc_fb;

gotLCDregion\n"

ret=request_irq(irq,s3c2410fb_irq,SA_INTERRUPT,pdev->

name,info);

if(ret){

cannotgetirq%d-err%d\n"

irq,ret);

gotorelease_mem;

clk=clk_get(NULL,"

lcd"

clk||IS_ERR(info->

clk)){

printk(KERN_ERR"

failedtogetlcdclocksource\n"

ret=-ENOENT;

gotorelease_irq;

clk_use(info->

clk);

clk_enable(info->

gotandenabledclock\n"

msleep

(1);

/*Initializevideomemory*/

ret=s3c2410fb_map_video_memory(info);

printk(KERN_ERR"

FailedtoallocatevideoRAM:

%d\n"

ret);

ret=-ENOMEM;

gotorelease_clock;

gotvideomemory\n"

ret=s3c2410fb_init_registers(info);

//怎么再次初始化lcd相关寄存器了?

ret=s3c2410fb_check_var(&

fbinfo->

var,fbinfo);

//注册framebuffer前的一个例行检查

ret=register_framebuffer(fbinfo);

if(ret<

Failedtoregisterframebufferdevice:

gotofree_video_memory;

/*createdevicefiles*/

device_create_file(dev,&

dev_attr_debug);

printk(KERN_INFO"

fb%d:

%sframebufferdevice\n"

node,fbinfo->

fix.id);

return0;

free_video_memory:

s3c2410fb_unmap_video_memory(info);

release_clock:

clk_disable(info->

clk_unuse(info->

clk_put(info->

release_irq:

free_irq(irq,info);

release_mem:

release_mem_region((unsignedlong)S3C24XX_VA_LCD,S3C24XX_SZ_LCD);

dealloc_fb:

framebuffer_release(fbinfo);

returnret;

/*

*s3c2410fb_map_video_memory():

AllocatestheDRAMmemoryfortheframebuffer. 

Thisbufferis

remappedintoanon-cached,non-buffered,memoryregionto

allowpaletteandpixelwritestooccurwithoutflushingthe

cache. 

Oncethisareaisremapped,allvirtualmemory

accesstothevideomemoryshouldoccuratthenewregion.

*/

staticint__inits3c2410fb_map_video_memory(structs3c2410fb_info*fbi)

map_video_memory(fbi=%p)\n"

fbi);

fbi->

map_size=PAGE_ALIGN(fbi->

fb->

fix.smem_len+PAGE_SIZE);

//页对齐

map_cpu 

=dma_alloc_writecombine(fbi->

dev,fbi->

map_size,

&

fbi->

map_dma,GFP_KERNEL);

//目前我只知道用于分配可供dma使用的内存,其中返回地址fbi->

map_cpu为虚拟地址,fbi->

map_dma为物理地址。

map_size=fbi->

fix.smem_len;

//恢复真实的大小

if(fbi->

map_cpu){

/*preventinitialgarbageonscreen*/

map_video_memory:

clear%p:

%08x\n"

map_cpu,fbi->

map_size);

memset(fbi->

map_cpu,0xf0,fbi->

screen_dma 

=fbi->

map_dma;

//物理地址

screen_base 

map_cpu;

//虚拟地址

fix.smem_start 

screen_dma;

dma=%08xcpu=%psize=%08x\n"

map_dma,fbi->

fix.smem_len);

returnfbi->

map_cpu?

0:

-ENOMEM;

staticstructs3c2410fb_mach_infosbc2410_lcdcfg__initdata={

.fixed_syncs=0,

.regs={

.lcdcon1=S3C2410_LCDCON1_TFT16BPP|\

S3C2410_LCDCON1_TFT|\

S3C2410_LCDCON1_CLKVAL(6),

.lcdcon2=S3C2410_LCDCON2_VBPD

(2)|\

S3C2410_LCDCON2_LINEVAL(319)|\

S3C2410_LCDCON2_VFPD(0)|\

S3C2410_LCDCON2_

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 人文社科 > 法律资料

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1