imx6ul之LCD驱动移植

    xiaoxiao2022-07-05  155

    首先贴上一位大佬的博客,对LCD有很详细的描述

    https://blog.csdn.net/longxiaowu/article/details/24319933

    在uboot和kernel中,都存在这样一个结构体fb_videomode 描述LCD的各项参数,结构体代码如下:

    struct fb_videomode {

    const char *name; //液晶屏名字(可选)

    u32 refresh; //刷新频率(内核中很多例子都赋值为60,可选)

    u32 xres; //每行的像素个数

    u32 yres; //屏幕的行数

    u32 pixclock; //每个像素时钟周期的长度,单位是皮秒(10的负12次方分之1秒

    //在每行或每列的象素数据开始输出时要插入的象素时钟周期数

    u32 left_margin;

    //在每行或每列的象素结束到LCD 行时钟输出脉冲之间的象素时钟数

    u32 right_margin;

    //在垂直同步周期之后帧开头时的无效行数

    u32 upper_margin;

    //本帧数据输出结束到下一帧垂直同步周期开始之前的无效行数

    u32 lower_margin;

    //单位:像素时钟周期

    u32 hsync_len;

    //单位:显示一行的时间th

    u32 vsync_len;

    //可以根据需要设置FB_SYNC_HOR_HIGH_ACT(水平同步高电平有效)和FB_SYNC_VERT_HIGH_ACT(垂直同步高电平有效)

    u32 sync;

    //在内核中的大多数示例都直接置为FB_VMODE_NONINTERLACED。interlaced的意思是交错[隔行]扫描,电视中使用2:1的交错率, 即每帧分两场,垂直扫描两次,一场扫描奇数行,另一场扫描偶数行。很显然LCD目前不是这种模式。

    u32 vmode;

    u32 flag;

    };

    对于一些参数,网络有大佬给出这样一种计算方法,如下:

    xres 对应于规格书中的TEP

    yres 对应于规格书中的Tvd

    left_margin 对应于规格书中的Thf

    right_margin 对应于规格书中的Thb

    hsync_len 对应于规格书中的THS

    upper_margin 对应于规格书中的Tvf

    lower_margin 对应于规格书中的Tvb

    vsync_len 对应于规格书中的Tvs

    pixclock = 1000000 / DCF

    hsync_len =THS= TH-THD-THB

    vsync_len = TVS=TV-TVD-TVB

    还没有验证过不确定真实性,下面的参数有些都是我看了规格书自己瞎配的,运气好能用。

    目前imx6ul上使用的是7寸屏,要移植一个10寸屏到板子上,在linux-4.1.15内核中lcd驱动与imx平台相关的源码路径主要如下:

    arch/arm/boot/dts/tq-imx6ul.dts

    drivers/video/fbdev/mxc/mxc_edid.c

    drivers/video/fbdev/mxc/mxc_dispdrv.c

    drivers/video/fbdev/mxc/mxc_lcdif.c

    drivers/video/fbdev/mxc/mxc_ipuv3_fb.c

    1.首先需要修改dts文件,截取设备树中的一段代码如下:

    &lcdif { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_lcdif_dat &pinctrl_lcdif_ctrl>; display = <&display0>; //指定所使用显示特性 status = "okay"; display0: display { //与上面 display0对应 bits-per-pixel = <32>; //使用的位色 bus-width = <24>; //硬件上的数据位宽 display-timings { //显示时序参数 native-mode = <&timing0>; //默认使用的模式 timing0: timing0 { mode_name = "H50"; //此模式名,对应的 uboot 启动参数中的 pannel 参数 clock-frequency = <45000000 52000000 63000000>; //pixclock hactive = <1024>; //分辨率 vactive = <600>; /*以下为时序参数*/ hfront-porch = <16 210 354>; hback-porch = <46>; //影响图像显示的竖直位置 hsync-len = <41>; vback-porch = <23>; vfront-porch = <1 12 77>;//影响图像显示的水平位置 vsync-len = <10>; /*以下为同步信号属性*/ hsync-active = <0>; vsync-active = <0>; }; }; }; };

     

    其中 display-timings 中的 mode_name 如果不写会默认使用native-mode 指定的方式,如果有指定会将它与 uboot 中的命令行比较,相等才会使用此参数。

    2.修改uboot中的相关设置,修改uboot源码,位置如下:

    u-boot/board/freescale/mx6ul_14x14_evk/mx6ul_14x14_evk.c

    struct display_info_t const displays[] = { { .bus = MX6UL_LCDIF1_BASE_ADDR, .addr = 0, .pixfmt = 24, .detect = NULL, .enable = do_enable_parallel_lcd, /*以下参数需要根据lcd的规格书修改*/ .mode = { .name = "H50", //与设备树中的mode_name 相对应 .xres = 1024, .yres = 600, .pixclock = KHZ2PICOS(52000), .left_margin = 50, .right_margin = 160, .upper_margin = 12, .lower_margin = 23, .hsync_len = 160, .vsync_len = 12, .sync = 0, .vmode = FB_VMODE_NONINTERLACED }, }, };

    配置好以后还要将uboot的panel的环境变量修改为指定的屏(mode_name )

    最新回复(0)