分析内核自带的lcd驱动程序\_基于imx6ull(代码片段)

韦东山 韦东山     2022-12-25     402

关键词:

分析内核自带的LCD驱动程序_基于IMX6ULL

参考资料,GIT仓库里:

  • IMX6ULL\\开发板配套资料\\datasheet\\Core_board\\CPU\\IMX6ULLRM.pdf

    • 《Chapter 34 Enhanced LCD Interface (eLCDIF)》
  • IMX6ULL的LCD裸机程序

    • IMX6ULL\\source\\03_LCD\\05_参考的裸机源码\\03_font_test
  • 内核自带的IMX6ULL LCD驱动程序

    • 驱动源码:Linux-4.9.88\\drivers\\video\\fbdev\\mxsfb.c
    • 设备树:
      • arch/arm/boot/dts/imx6ull.dtsi
      • arch/arm/boot/dts/100ask_imx6ull-14x14.dts

1. 驱动程序框架

Linux驱动程序 = 驱动程序框架 + 硬件编程。
在前面已经基于QEMU编写了LCD驱动程序,对LCD驱动程序的框架已经分析清楚。
核心就是:

  • 分配fb_info
  • 设置fb_info
  • 注册fb_info
  • 硬件相关的设置

1.1 入口函数注册platform_driver

1.2 设备树有对应节点

1.3 probe函数分析

2. 编写硬件相关的代码

我们只需要针对IMX6ULL的编写硬件相关的代码,涉及3部分:

  • GPIO设置
    • LCD引脚
    • 背光引脚
  • 时钟设置
    • 确定LCD控制器的时钟
    • 根据LCD的DCLK计算相关时钟
  • LCD控制器本身的设置
    • 比如设置Framebuffer的地址
    • 设置Framebuffer中数据格式、LCD数据格式
    • 设置时序

2.1 GPIO设置

有两种方法:

  • 直接读写相关寄存器
  • 使用设备树,在设备树中设置pinctrl
    • 本课程专注于LCD,所以使用pinctrl简化程序

设备树arch/arm/boot/dts/100ask_imx6ull-14x14.dts中:

2.2 时钟设置

IMX6ULL的LCD控制器涉及2个时钟:

代码里直接使用时钟子系统的代码。

  • 在设备树里指定频率:

    • 文件:arch/arm/boot/dts/100ask_imx6ull-14x14.dts

    • 代码:clock-frequency

             display-timings 
                  native-mode = <&timing0>;
      
                   timing0: timing0_1024x768 
                   clock-frequency = <50000000>;
      
  • 从设备树获得dot clock,存入display_timing

    • 文件:drivers\\video\\of_display_timing.c

    • 代码:

      ret |= parse_timing_property(np, "clock-frequency", &dt->pixelclock);
      
  • 使用display_timing来设置videomode

    • 文件:drivers\\video\\videomode.c

    • 代码:

      void videomode_from_timing(const struct display_timing *dt,
      			  struct videomode *vm)
      
      	vm->pixelclock = dt->pixelclock.typ;
      	vm->hactive = dt->hactive.typ;
      	vm->hfront_porch = dt->hfront_porch.typ;
      	vm->hback_porch = dt->hback_porch.typ;
      	vm->hsync_len = dt->hsync_len.typ;
      
      	vm->vactive = dt->vactive.typ;
      	vm->vfront_porch = dt->vfront_porch.typ;
      	vm->vback_porch = dt->vback_porch.typ;
      	vm->vsync_len = dt->vsync_len.typ;
      
      	vm->flags = dt->flags;
      
      
      
  • 根据videomode的值,使用时钟子系统的函数设置时钟:

    • 文件:drivers\\video\\fbdev\\mxc\\ldb.c
    • 代码:

2.3 LCD控制器的配置

以设置分辨率为例。

  • 在设备树里指定频率:

    • 文件:arch/arm/boot/dts/100ask_imx6ull-14x14.dts

    • 代码:clock-frequency

             display-timings 
                  native-mode = <&timing0>;
      
                   timing0: timing0_1024x768 
      				hactive = <1024>;
      	            vactive = <600>;
      
      
  • 从设备树获得分辨率,存入display_timing

    • 文件:drivers\\video\\of_display_timing.c

    • 代码:

      	ret |= parse_timing_property(np, "hactive", &dt->hactive);
      	ret |= parse_timing_property(np, "vactive", &dt->vactive);
      
  • 使用display_timing来设置videomode

    • 文件:drivers\\video\\videomode.c

    • 代码:

      void videomode_from_timing(const struct display_timing *dt,
      			  struct videomode *vm)
      
      	vm->hactive = dt->hactive.typ;
      
          vm->vactive = dt->vactive.typ;
      
  • 根据videomode的值,设置fb_videomode

    • 文件:drivers\\video\\fbdev\\core\\fbmon.c

    • 代码:

      int fb_videomode_from_videomode(const struct videomode *vm,
      				struct fb_videomode *fbmode)
      
      	unsigned int htotal, vtotal;
      
      	fbmode->xres = vm->hactive;
      
          fbmode->yres = vm->vactive;
      
      
  • 根据fb_videomode的值,设置fb_info中的var:

    • 文件:drivers\\video\\fbdev\\core\\modedb.c

    • 代码:

      void fb_videomode_to_var(struct fb_var_screeninfo *var,
      			 const struct fb_videomode *mode)
      
      	var->xres = mode->xres;
      	var->yres = mode->yres;
      
      
  • 根据var的分辨率,设置寄存器

    • 文件:drivers\\video\\fbdev\\mxsfb.c

    • 代码:

      	writel(TRANSFER_COUNT_SET_VCOUNT(fb_info->var.yres) |
      			TRANSFER_COUNT_SET_HCOUNT(fb_info->var.xres),
      			host->base + host->devdata->transfer_count);
      
      

编程\_lcd驱动程序框架\_使用设备树(代码片段)

编程_LCD驱动程序框架_使用设备树参考资料,GIT仓库里:基于这个程序修改:IMX6ULL\\source\\03_LCD\\03_lcd_drv_qemu_okSTM32MP157\\source\\A7\\03_LCD\\03_lcd_drv_qemu_ok参考:内核自带的示例驱动程序Linux驱动源码:drivers/v 查看详情

编程\_配置lcd控制器之寄存器操作\_基于imx6ull(代码片段)

编程_配置LCD控制器之寄存器操作_基于IMX6ULL参考资料,GIT仓库里:芯片资料IMX6ULL\\开发板配套资料\\datasheet\\Core_board\\CPU\\IMX6ULLRM.pdf《Chapter34EnhancedLCDInterface(eLCDIF)》IMX6ULL的LCD裸机程序IMX6ULL\\source\\03_LCD\\05_参考 查看详情

上机实验\_基于imx6ull(代码片段)

上机实验_基于IMX6ULL参考资料,GIT仓库里:芯片资料IMX6ULL\\开发板配套资料\\datasheet\\Core_board\\CPU\\IMX6ULLRM.pdf《Chapter34EnhancedLCDInterface(eLCDIF)》IMX6ULL的LCD裸机程序IMX6ULL\\source\\03_LCD\\05_参考的裸机源码\\03_fon 查看详情

编程\_配置时钟\_基于imx6ull(代码片段)

编程_配置时钟_基于IMX6ULL参考资料,GIT仓库里:芯片资料IMX6ULL\\开发板配套资料\\datasheet\\Core_board\\CPU\\IMX6ULLRM.pdf《Chapter34EnhancedLCDInterface(eLCDIF)》IMX6ULL的LCD裸机程序IMX6ULL\\source\\03_LCD\\05_参考的裸机源码\\03_ 查看详情

编程\_配置引脚\_基于imx6ull(代码片段)

编程_配置引脚_基于IMX6ULL参考资料,GIT仓库里:芯片资料IMX6ULL\\开发板配套资料\\datasheet\\Core_board\\CPU\\IMX6ULLRM.pdf《Chapter34EnhancedLCDInterface(eLCDIF)》IMX6ULL的LCD裸机程序IMX6ULL\\source\\03_LCD\\05_参考的裸机源码\\03_ 查看详情

06_client端使用pinctrl过程的情景分析_基于imx6ull(代码片段)

资料下载coding无法使用浏览器打开,必须用git工具下载:gitclonehttps://e.coding.net/weidongshan/linux/doc_and_source_for_drivers.git视频观看百问网驱动大全client端使用pinctrl过程的情景分析_基于IMX6ULL参考资料:Linux5.x内核Documentatio 查看详情

最简单的lcd驱动\_基于qemu(代码片段)

最简单的LCD驱动_基于QEMU本节视频对应源码在GIT仓库中,位置如下(这2个文件是完全一样的):doc_and_source_for_drivers\\STM32MP157\\source\\A7\\03_LCD\\02_lcd_drv_qemu\\lcd_drv.c或:doc_and_source_for_drivers\\IMX6ULL\\sour 查看详情

05_pincontroller构造过程情景分析_基于imx6ull(代码片段)

资料下载coding无法使用浏览器打开,必须用git工具下载:gitclonehttps://e.coding.net/weidongshan/linux/doc_and_source_for_drivers.git视频观看百问网驱动大全Pincontroller构造过程情景分析_基于IMX6ULL参考资料:Linux4.x内核文档Documentatio 查看详情

结合app分析lcd驱动程序(代码片段)

结合APP分析LCD驱动程序本节视频对应源码在GIT仓库中,位置如下(这2个文件是完全一样的):doc_and_source_for_drivers\\STM32MP157\\source\\A7\\03_LCD\\04_fb_test或:doc_and_source_for_drivers\\IMX6ULL\\source\\03_LCD\\04_fb_ 查看详情

硬件\_imx6ull的lcd控制器(代码片段)

硬件_IMX6ULL的LCD控制器参考资料,GIT仓库里:IMX6ULL\\开发板配套资料\\datasheet\\Core_board\\CPU\\IMX6ULLRM.pdf《Chapter34EnhancedLCDInterface(eLCDIF)》IMX6ULL的LCD裸机程序IMX6ULL\\source\\03_LCD\\05_参考的裸机源码\\03_font 查看详情

06_imx6ull的gpio驱动源码分析(代码片段)

资料下载coding无法使用浏览器打开,必须用git工具下载:gitclonehttps://e.coding.net/weidongshan/linux/doc_and_source_for_drivers.git视频观看百问网驱动大全IMX6ULL的GPIO驱动源码分析参考资料:Linux4.x内核文档Linux-4.9.88\\Documentati 查看详情

linux内核lcd驱动分析与换屏方法(tiny4412)

...内核,可以通过修改bootargs实现驱动不同的LCD屏。​21.5.2分析bootargs中的lcd参数再启动uboot的时候会有如下的环境参数:​bootargs=noinitrdroot=/dev/nfsn 查看详情

编写使用多buffer的应用程序(代码片段)

编写使用多buffer的应用程序本节视频编写好的程序,在GIT仓库里IMX6ULL\\source\\03_LCD\\14_use_multi_framebufferSTM32MP157\\source\\A7\\03_LCD\\14_use_multi_framebuffer参考程序:应用基础课程里使用Framebuffer的精简程序IMX6ULL\\source\\ 查看详情

硬件\_tft-rgb接口lcd时序分析(代码片段)

硬件_TFT-RGB接口LCD时序分析参考资料,GIT仓库里:TFT-RGBLCD接口原理图:`IMX6ULL\\开发板配套资料\\原理图\\Base_board\\100ask_imx6ull_v1.1.pdf````STM32MP157\\开发板配套资料\\原理图\\01_Base_board(底板)\\100A 查看详情

lcd驱动源码分析(s3cfb.c)(代码片段)

1、驱动源码分析大致思路(1)分析LCD驱动首先需要分析内核的帧缓冲子系统,因为LCD驱动就是按照帧缓冲子系统提供的注册接口来注册的;(2)内核帧缓冲子系统参考博客:《Linux帧缓冲子系统详解:LCD介绍、framebuffe... 查看详情

10.lcd驱动程序——框架分析(代码片段)

...一副图像所需要的数据。因此,帧缓冲其实就是LCD设备的驱动程序) 一.LCD驱动程序框架根据上述思路,LinuxLCD驱动程分为两个层次,如下图所示类似于Platform平台驱动框架,也将驱动程序分为相对稳定的算法驱动,即fb总线... 查看详情

单buffer的缺点与改进方法(代码片段)

单Buffer的缺点与改进方法参考资料,GIT仓库里:内核自带的LCD驱动程序IMX6ULL驱动源码:Linux-4.9.88\\drivers\\video\\fbdev\\mxsfb.cSTM32MP157的驱动程序是基于GPU的,在Linux-5.4里没有mxsfb.c,可以参考另一个:Linux-5.4\\ 查看详情

lcd驱动端与设备端名称匹配过程分析(tiny4412)

...匹配也能驱动屏点亮,​这是怎么回事的呢?下面我们来分析这是如何实现的。​硬件平台​Cpu:exynos4412​板子:tiny4412​Linux内核:linux-3.5​21.6.1lcd平台驱动层相关代码构架​Lcd平台驱动层在S3c-fb.c(linux-3.5\\drivers\\vid 查看详情