LCD驱动中的xxx_probe()函数

LCD驱动是一个标准的platform驱动。当驱动和设备匹配以后,mxsfb_probe 函数就会执行。
mxsfb_probe 函数的主要工作是:
1)、申请fb_info。

framebuffer_alloc()

2)、初始化fb_info结构体中,各个成员变量。
3)、初始化eLCDIF控制器。
4)、使用register_frambebuffer函数向Linux内核注册初始化好的fb_info结构体。
mxsfb_probe 函数中,重要函数/结构体的简要的说明:
1)、
Linux内核将所有的Framebuffer抽象为一个叫fb_info的结构体,fb_info结构体里面包含Framerbuffer设备完整的属性和操作集合,因此,每一个Framebuffer都必须有一个fb_info结构体。换言之,就是lcd驱动,实质上,就是构建fb_info结构体,并且向系统注册fb_info结构体的过程。

struct fb_info {
……
   struct fb_var_screeninfo var; /* 当前可变参数 */
struct fb_fix_screeninfo fix; /* 当前固定参数 */
   struct fb_ops *fbops; /* 帧缓冲操作函数集 */
   char __iomem *screen_base; /* 虚拟内存基地址(屏幕显存) */
unsigned long screen_size; /* 虚拟内存大小(屏幕显存大小) */
void *pseudo_palette; /* 伪 16 位调色板 */
......
};

这个结构体里面的成员变量很多,重要的有如上六个。
2)、register_framebuffer 函数

int register_framebuffer(struct fb_info *fb_info)

3)、mxsfb_probe 函数的主要梳理:
①、

struct mxsfb_info *host;

定义结构体指针变量host,表示IMX6ULL的LCD主控接口,这个结构体是自定义的,里面的成员变量记录了Framebuffer 设备详细信息,比如时钟、 eLCDIF控制器寄存器基地址、 fb_info(struct fb_info *fb_info) 等
②、

res = platform_get_resource(pdev, IORESOURCE_MEM, 0);

从设备树中,获取eLCDIF接口控制器的寄存器首地址。寄存器首地址信息,已经在设备树中的,对应的lcd节点中设置了。

lcdif: lcdif@021c8000 {
		compatible = "fsl,imx6ul-lcdif", "fsl,imx28-lcdif";
	。。。。。。
	};

③、给host、fb_info申请内存

host = devm_kzalloc(&pdev->dev, sizeof(struct mxsfb_info), GFP_KERNEL);
fb_info = framebuffer_alloc(sizeof(struct fb_info), &pdev->dev);

④、通过这一步就将前面申请的 host 和 fb_info 联系在了一起。

host->fb_info = fb_info;
fb_info->par = host;  

⑤、对从设备树中获取到的寄存器首地址(res)进行内存映射,得到虚拟地址,并保存到host的base成员变量里面。之后,只要通过访问 host 的 base 成员即可访问 I.MX6ULL 的整个 eLCDIF寄存器。

host->base = devm_ioremap_resource(&pdev->dev, res);

⑥、给pseudo_palette申请内存。

fb_info->pseudo_palette = devm_kzalloc(&pdev->dev, sizeof(u32) * 16,GFP_KERNEL);

⑦、调用 mxsfb_init_fbinfo 函数初始化 fb_info,重点是 fb_info 的 var、 fix、 fbops(操作集),screen_base 和 screen_size。

mxsfb_init_fbinfo(host);
//从设备树中,获取LCD各个参数的信息
    -mxsfb_init_fbinfo_dt(host);
//申请LCD的帧缓冲内存(就是缓存)
    -mxsfb_map_videomem(fb_info)

类似于字符设备操作集file_operations(这里面的函数,已经由芯片厂商写好):

static struct fb_ops mxsfb_ops = {
.owner = THIS_MODULE,
.fb_check_var = mxsfb_check_var,
.fb_set_par = mxsfb_set_par,
.fb_ioctl = mxsfb_ioctl,
.fb_blank = mxsfb_blank,
.fb_pan_display = mxsfb_pan_display,
.fb_mmap = mxsfb_mmap,
……
};

⑧、设置eLCDIF控制器相应的寄存器

mxsfb_set_par(fb_info); //函数里面包含大量的writel()函数
eg:
 {   writel(CTRL1_FIFO_CLEAR, host->base + REG_SET);
     writel(ctrl, host->base + LCDC_CTRL);  ……   }
mxsfb_enable_controller(fb_info);  //同上(大量的writel())

⑨、调用 register_framebuffer 函数向 Linux 内核注册 fb_info

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

One Piece&

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值