S3C6410 LCD驱动分析

发布时间:2024-09-19  

一. 理论分析

1. 几个概念:

FIMC :

    Fully Interactive Mobile Camera (完全交互式移动摄像机)

FIMD: 

    Fully Interactive Mobile Display (完全交互式移动显示设备)

2. 设置VCLK

在VIDCON0中

bit[3:2]-->Select the Video Clock source =00 --> HCLK=133MHZ

bit[13:6] --> CLKVAL_F = 13  (这个值是在驱动中计算出来的)

VCLK = Video Clock Source / (CLKVAL+1) where CLKVAL >= 1

         = 133MHZ / (13+1) = 9.5MHZ

3. 刷新频率计算

Frame Rate  = VCLK / (HSPW + HBPD + HOZVAL + HFPD) / (VSPW + VBPD + LINEVAL + VFPD)

            = 9.5MHZ/(2+41+2+480)/(2+272+10+2)

            =0.00006327MHZ

            =63HZ

二. 驱动分析

首先在平台的目录中定义platform_device

在arch/arm/plat-samsung/dev-fb.c中


 1 static struct resource s3c_fb_resource[] = {

 2     [0] = {

 3         .start = S3C_PA_FB,

 4         .end = S3C_PA_FB + SZ_16K - 1,

 5         .flags = IORESOURCE_MEM,

 6     },

 7     [1] = {

 8         .start = IRQ_LCD_VSYNC,

 9         .end = IRQ_LCD_VSYNC,

10         .flags = IORESOURCE_IRQ,

11     },

12     [2] = {

13         .start = IRQ_LCD_FIFO,

14         .end = IRQ_LCD_FIFO,

15         .flags = IORESOURCE_IRQ,

16     },

17     [3] = {

18         .start = IRQ_LCD_SYSTEM,

19         .end = IRQ_LCD_SYSTEM,

20         .flags = IORESOURCE_IRQ,

21     },

22 };

23 

24 struct platform_device s3c_device_fb = {

25     .name         = 's3c-fb',

26     .id         = -1,

27     .num_resources     = ARRAY_SIZE(s3c_fb_resource),

28     .resource     = s3c_fb_resource,

29     .dev.dma_mask     = &s3c_device_fb.dev.coherent_dma_mask,

30     .dev.coherent_dma_mask = 0xffffffffUL,

31 };


然后在驱动的probe函数中:

在driver/video/samsun/s3cfb.c中


 1 static int __init s3cfb_probe(struct platform_device *pdev)

 2 {

 3     struct resource *res;

 4     struct fb_info *fbinfo;

 5     s3cfb_info_t *info;

 6 

 7     char driver_name[] = 's3cfb';

 8     int index = 0, ret, size;

 9     //分配sizeof(fb_info+私有成员)大小的内存,使par指向s3cfb_info_t结构体

10     fbinfo = framebuffer_alloc(sizeof(s3cfb_info_t), &pdev->dev);   

11 

12     platform_set_drvdata(pdev, fbinfo);

13 

14     info = fbinfo->par;                //私有数据是一个结构体s3cfb_info_t

15     info->dev = &pdev->dev;

16     

17     //获取LCD的io端口,并映射

18     res = platform_get_resource(pdev, IORESOURCE_MEM, 0);

19     size = (res->end - res->start) + 1;

20     info->mem = request_mem_region(res->start, size, pdev->name);

21     info->io = ioremap(res->start, size);

22 

23     s3cfb_pre_init();                                 //2.使能中断寄存器,s3cfb_fimd的第一次初始化

24     s3cfb_set_backlight_power(1);                     //设置backlight_power = 1;

25     s3cfb_set_lcd_power(1);                           //设置lcd_power = 1;

26     s3cfb_set_backlight_level(S3CFB_DEFAULT_BACKLIGHT_LEVEL); //设置backlight_level = 2;

27     

28     //获取时钟,并使能

29     info->clk = clk_get(NULL, 'lcd');     //133.000Mhz,使用的是HCLK

30     clk_enable(info->clk);

31 

32     s3cfb_fimd.vsync_info.count = 0;

33     init_waitqueue_head(&s3cfb_fimd.vsync_info.wait_queue);

34     

35     //申请中断

36     res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);

37     ret = request_irq(res->start, s3cfb_irq, 0, 's3c-lcd', pdev);

38     msleep(5);

39     //对4个framebuffer分别初始化

40     for (index = 0; index < S3CFB_NUM; index++) {

41         s3cfb_info[index].mem = info->mem;

42         s3cfb_info[index].io = info->io;

43         s3cfb_info[index].clk = info->clk;

44 

45         s3cfb_init_fbinfo(&s3cfb_info[index], driver_name, index);  //3.初始化fbinfo

46         ret = s3cfb_map_video_memory(&s3cfb_info[index]);           //4.分配dma内存 

47 

48         ret = s3cfb_init_registers(&s3cfb_info[index]);            //5.写寄存器

49         ret = s3cfb_check_var(&s3cfb_info[index].fb.var, &s3cfb_info[index].fb);  //6.设置var范围

50 

51         if (index < 2){

52             if (fb_alloc_cmap(&s3cfb_info[index].fb.cmap, 256, 0) < 0)     //7.申请color map

53                 goto dealloc_fb;

54         } else {

55             if (fb_alloc_cmap(&s3cfb_info[index].fb.cmap, 16, 0) < 0)

56                 goto dealloc_fb;

57         }

58 

59         ret = register_framebuffer(&s3cfb_info[index].fb);                 //8.注册framebuffer

60     }

61 

62     ret = device_create_file(&(pdev->dev), &dev_attr_backlight_power);

63     ret = device_create_file(&(pdev->dev), &dev_attr_backlight_level);

64     ret = device_create_file(&(pdev->dev), &dev_attr_lcd_power);

65     return 0;

66 }


1.分配内存

分配fb_info+size大小的内存,并使par指向私有数据size


 1 struct fb_info *framebuffer_alloc(size_t size, struct device *dev)

 2 {

 3     fb_info_size += PADDING;          //加上PADDING是让私有数据4字节对齐

 4     char *p = kzalloc(fb_info_size + size, GFP_KERNEL);

 5 

 6     struct fb_info * info = (struct fb_info *) p;

 7     info->par = p + fb_info_size;     //par指向私有数据

 8     info->device = dev;

 9     return info;                      //返回申请内存的首指针

10 }


2. 初始化视频中断控制寄存器0

在drivers/video/samsun/s3cfb_fimd4x.c中


 1 void s3cfb_pre_init(void)

 2 {

 3     //Video Frame Interrupt 0 at start of VSYNC,并使能

 4     s3cfb_fimd.vidintcon0 &= ~S3C_VIDINTCON0_FRAMESEL0_MASK;

 5     s3cfb_fimd.vidintcon0 |= S3C_VIDINTCON0_FRAMESEL0_VSYNC;

 6     s3cfb_fimd.vidintcon0 |= S3C_VIDINTCON0_INTFRMEN_ENABLE;

 7    //0x9021=1001 0000 0010 0001

 8    //打开video 中断,关闭fifo 中断

 9    //打开 video frame 中断, Video Frame Interrupt 0 at start of VSYNC

10     writel(s3cfb_fimd.vidintcon0, S3C_VIDINTCON0);

11 }


在driver/vidoe/samsun/s3cfb.c中


 1 static void s3cfb_set_lcd_power(int to)

 2 {

 3     s3cfb_fimd.lcd_power = to;

 4 }

 5 

 6 static void s3cfb_set_backlight_power(int to)

 7 {

 8     s3cfb_fimd.backlight_power = to;

 9 }

10 

11 static void s3cfb_set_backlight_level(int to)

12 {

13     s3cfb_fimd.backlight_level = to;

14 }


3. 初始化s3cfb_info_t结构体

在driver/vidoe/samsun/s3cfb.c中


 1 static void s3cfb_init_fbinfo(s3cfb_info_t *finfo, char *drv_name, int index)

 2 {

 3     int i = 0;   

 4     if (index == 0)

 5     {

 6         if(lcdsize == 1)

 7             s3cfb_init_hw_43();        //3.1 s3cfb_fimd及gpio的初始化

 8     }

 9     strcpy(finfo->fb.fix.id, drv_name);

10     //下面一大段就是要将初始化好后的s3cfb_fimd赋给finfo,类似于结构体转化

11     finfo->win_id = index;

12     finfo->fb.fix.type = FB_TYPE_PACKED_PIXELS;

13     finfo->fb.fix.type_aux = 0;

14     finfo->fb.fix.xpanstep = 0;

15     finfo->fb.fix.ypanstep = 1;

16     finfo->fb.fix.ywrapstep = 0;

17     finfo->fb.fix.accel = FB_ACCEL_NONE;

18 

19     finfo->fb.fbops = &s3cfb_ops;                //fb操作函数

20     finfo->fb.flags    = FBINFO_FLAG_DEFAULT;

21 

22     finfo->fb.pseudo_palette = &finfo->pseudo_pal;

23 

24     finfo->fb.var.nonstd = 0;

25     finfo->fb.var.activate = FB_ACTIVATE_NOW;

26     finfo->fb.var.accel_flags = 0;

27     finfo->fb.var.vmode = FB_VMODE_NONINTERLACED;

28 

29     finfo->fb.var.xoffset = s3cfb_fimd.xoffset;     //xoffset=0 

文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>