一、RGBLCD 硬件原理
【正点原子MP157连载】第十八章 RGB LCD彩条显示实验-摘自【正点原子】STM32MP1嵌入式Linux驱动开发指南V1.7_正点原子的博客-CSDN博客
ATK7016
时序参数:
二、eLCDIF 接口
eLCDIF
是I.MX6U
自带的液晶屏幕接口,用于连接RGB LCD
接口的屏幕。
三、Linux 下 LCD 驱动分析
1、LCD 操作流程
1、初始化I.MX6U
的eLCDIF
控制器,重点是LCD
屏幕宽(width
)、高(height
)、hspw
、hbp
、hfp
、vspw
、vbp
和vfp
等信息。
2、初始化LCD
像素时钟。
3、设置RGBLCD
显存。
4、应用程序直接通过操作显存来操作LCD
,实现在LCD
上显示字符、图片等信息。
2、Framebuffer 设备
Linux
内核中使用Framebuffer
提供统一的标准接口显示设备。Framebuffer
翻译过来就是帧缓冲,简称fb
。fb
是一种机制,将系统中所有跟显示有关的硬件以及软件集合起来,虚拟出一个fb
设备,当我们编写好LCD
驱动以后会生成一个名为/dev/fbX(X=0~n)
的设备,应用程序通过访问/dev/fbX
这个设备就可以访问LCD
。
NXP
官方的Linux
内核默认已经开启了LCD
驱动,因此我们是可以看到/dev/fb0
这样一个设备,如下所示:
# ls -l /dev/fb0crw-rw---- 1 rootroot 29, 0 Jan 1 00:00 /dev/fb0#
/dev/fb0
就是LCD
对应的设备文件,/dev/fb0
是个字符设备,fb
的file_operations
操作集定义在drivers/video/fbdev/core/fbmem.c
文件中。
3、驱动分析
1、通过设备树确定驱动文件
设备树信息如下:
// 文件路径:linux-imx-4.1.15\arch\arm\boot\dts\imx6ull.dtsilcdif: lcdif@021c8000 {compatible = "fsl,imx6ul-lcdif", "fsl,imx28-lcdif";reg = <0x021c8000 0x4000>;interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;clocks = <&clks IMX6UL_CLK_LCDIF_PIX>,<&clks IMX6UL_CLK_LCDIF_APB>,<&clks IMX6UL_CLK_DUMMY>;clock-names = "pix", "axi", "disp_axi";status = "disabled";};
通过fsl,imx6ul-lcdif
或fsl,imx28-lcdif
查找驱动文件,驱动文件路径:linux-imx-4.1.15\drivers\video\fbdev\mxsfb.c
。
驱动分析待完成……。
四、重要结构体
1、fb_info
struct fb_info {atomic_t count;int node;int flags;struct mutex lock;/* Lock for open/release/ioctl funcs */struct mutex mm_lock;/* Lock for fb_mmap and smem_* fields */struct fb_var_screeninfo var;/* Current var */struct fb_fix_screeninfo fix;/* Current fix */struct fb_monspecs monspecs;/* Current Monitor specs */struct work_struct queue;/* Framebuffer event queue */struct fb_pixmap pixmap;/* Image hardware mapper */struct fb_pixmap sprite;/* Cursor hardware mapper */struct fb_cmap cmap;/* Current cmap */struct list_head modelist;/* mode list */struct fb_videomode *mode;/* current mode */#ifdef CONFIG_FB_BACKLIGHT/* assigned backlight device *//* set before framebuffer registration, remove after unregister */struct backlight_device *bl_dev;/* Backlight level curve */struct mutex bl_curve_mutex;u8 bl_curve[FB_BACKLIGHT_LEVELS];#endif#ifdef CONFIG_FB_DEFERRED_IOstruct delayed_work deferred_work;struct fb_deferred_io *fbdefio;#endifstruct fb_ops *fbops;struct device *device;/* This is the parent */struct device *dev;/* This is this fb device */int class_flag;/* private sysfs flags */#ifdef CONFIG_FB_TILEBLITTINGstruct fb_tile_ops *tileops; /* Tile Blitting */#endifchar __iomem *screen_base;/* Virtual address */unsigned long screen_size;/* Amount of ioremapped VRAM or 0 */ void *pseudo_palette;/* Fake palette of 16 colors */ #define FBINFO_STATE_RUNNING0#define FBINFO_STATE_SUSPENDED1u32 state;/* Hardware state i.e suspend */void *fbcon_par;/* fbcon use-only private area *//* From here on everything is device dependent */void *par;/* we need the PCI or similar aperture base/size notsmem_start/size as smem_start may just be an objectallocated inside the aperture so may not actually overlap */struct apertures_struct {unsigned int count;struct aperture {resource_size_t base;resource_size_t size;} ranges[0];} *apertures;bool skip_vt_switch; /* no VT switch on suspend/resume required */};
2、mxsfb_info
struct mxsfb_info {struct fb_info *fb_info;struct platform_device *pdev;struct clk *clk_pix;struct clk *clk_axi;struct clk *clk_disp_axi;bool clk_pix_enabled;bool clk_axi_enabled;bool clk_disp_axi_enabled;void __iomem *base;/* registers */u32 sync;/* record display timing polarities */unsigned allocated_size;int enabled;unsigned ld_intf_width;unsigned dotclk_delay;const struct mxsfb_devdata *devdata;struct regulator *reg_lcd;bool wait4vsync;struct completion vsync_complete;struct completion flip_complete;int cur_blank;int restore_blank;char disp_dev[32];struct mxc_dispdrv_handle *dispdrv;int id;struct fb_var_screeninfo var;};
五、设备树添加
1、设备树添加说明
Linux 驱动开发 六十二:《mxsfb.txt》翻译_lqonlylove的博客-CSDN博客
Linux 驱动开发 六十三:《display-timing.txt》翻译_lqonlylove的博客-CSDN博客
2、添加设备树
在lcdif
节点中追加或修改LCD
时序相关参数,如题内容如下:
lcdif: lcdif@021c8000 {compatible = "fsl,imx6ul-lcdif", "fsl,imx28-lcdif";reg = <0x021c8000 0x4000>;interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;clocks = <&clks IMX6UL_CLK_LCDIF_PIX>,<&clks IMX6UL_CLK_LCDIF_APB>,<&clks IMX6UL_CLK_DUMMY>;clock-names = "pix", "axi", "disp_axi";status = "disabled";};&lcdif {pinctrl-names = "default";pinctrl-0 = <&pinctrl_lcdif_dat&pinctrl_lcdif_ctrl>;display = <&display0>;status = "okay";/* 7寸1024*600 */display0: display {bits-per-pixel = <32>;// RGB值(RGB888/666)bus-width = <24>;// 数据线数量display-timings {native-mode = <&timing0>;timing0: timing0 {clock-frequency = <51200000>;// 时钟配置hactive = <1024>;// 水平像素点vactive = <600>;// 垂直像素点hfront-porch = <160>;// HFP 配置hback-porch = <140>;// HBP 配置hsync-len = <20>;// HSPW 配置vback-porch = <20>;// VBP 配置vfront-porch = <12>;// VFP 配置vsync-len = <3>;// VSPW 配置hsync-active = <0>;// HSYNC 信号有效电平vsync-active = <0>;// VSYNC 信号有效电平de-active = <1>;// DE 信号有效电平pixelclk-active = <0>;// 数据更新和数据采样有效电平};};};};
六、LCD 背光配置
1、确定LCD背光使用的 PIN 引脚
通过原理图确定背光使用的PIN
引脚。LCD
使用引脚为BLT_PWM
(GPIO1_IO08
)。LCD
背光使用PWM
驱动。
2、设备树配置
pinctrl_pwm1: pwm1grp {fsl,pins = <MX6UL_PAD_GPIO1_IO08__PWM1_OUT 0x110b0>;};pwm1: pwm@02080000 {compatible = "fsl,imx6ul-pwm", "fsl,imx27-pwm";reg = <0x02080000 0x4000>;interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;clocks = <&clks IMX6UL_CLK_PWM1>,<&clks IMX6UL_CLK_PWM1>;clock-names = "ipg", "per";#pwm-cells = <2>;};&pwm1 {pinctrl-names = "default";pinctrl-0 = <&pinctrl_pwm1>;status = "okay";};backlight {compatible = "pwm-backlight";pwms = <&pwm1 0 5000000>;brightness-levels = <0 4 8 16 32 64 128 255>;default-brightness-level = <7>;status = "okay";};
3、Linux 中相关说明
Linux 驱动开发 六十四:《pwm-backlight.txt》翻译_lqonlylove的博客-CSDN博客
七、特别说明
LCD
驱动Linux
内核已经写好,我们只需要按照硬件参数配置设备树即可使用。
八、LCD 熄屏关闭
Linux
在drivers/tty/vt/vt.c
源码中配置LCD
熄屏时间,配置项static int blankinterval = 10*60
配置LCD
熄屏时间,将blankinterva
l 设置为 0,表示LCD
常亮。