DeviceDriver (11): LCD driver (device tree)

LCD non-device tree driver framework reference:

https://blog.csdn.net/qq_34968572/article/details/89922596

One: Device tree file analysis

1. Public file imx6ull.dtsi

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";
};

The lcdif node is shared by the imx6ull chip board is not complete, such as screen parameters need to be added according to different hardware platforms, each has its own corresponding dts file.

According to the lcdif node compatible property "fsl,imx6ul-lcdif", "fsl,imx28-lcdif", you can find the LCD driver file of imx6ull: drivers/video/fbdev/mxsfb.c

static const struct of_device_id mxsfb_dt_ids[] = {
	{ .compatible = "fsl,imx23-lcdif", .data = &mxsfb_devtype[0], },
	{ .compatible = "fsl,imx28-lcdif", .data = &mxsfb_devtype[1], },
	{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, mxsfb_dt_ids);

... ...

static struct platform_driver mxsfb_driver = {
	.probe = mxsfb_probe,
	.remove = mxsfb_remove,
	.shutdown = mxsfb_shutdown,
	.id_table = mxsfb_devtype,
	.driver = {
		   .name = DRIVER_NAME,
		   .of_match_table = mxsfb_dt_ids,
		   .pm = &mxsfb_pm_ops,
	},
};

2. LCD screen IO configuration

 pinctrl_lcdif_dat: lcdifdatgrp {
	fsl,pins = <
		MX6UL_PAD_LCD_DATA00__LCDIF_DATA00  0x79
		MX6UL_PAD_LCD_DATA01__LCDIF_DATA01  0x79
		MX6UL_PAD_LCD_DATA02__LCDIF_DATA02  0x79
		MX6UL_PAD_LCD_DATA03__LCDIF_DATA03  0x79
		MX6UL_PAD_LCD_DATA04__LCDIF_DATA04  0x79
		MX6UL_PAD_LCD_DATA05__LCDIF_DATA05  0x79
		MX6UL_PAD_LCD_DATA06__LCDIF_DATA06  0x79
		MX6UL_PAD_LCD_DATA07__LCDIF_DATA07  0x79
		MX6UL_PAD_LCD_DATA08__LCDIF_DATA08  0x79
		MX6UL_PAD_LCD_DATA09__LCDIF_DATA09  0x79
		MX6UL_PAD_LCD_DATA10__LCDIF_DATA10  0x79
		MX6UL_PAD_LCD_DATA11__LCDIF_DATA11  0x79
		MX6UL_PAD_LCD_DATA12__LCDIF_DATA12  0x79
		MX6UL_PAD_LCD_DATA13__LCDIF_DATA13  0x79
		MX6UL_PAD_LCD_DATA14__LCDIF_DATA14  0x79
		MX6UL_PAD_LCD_DATA15__LCDIF_DATA15  0x79
		MX6UL_PAD_LCD_DATA16__LCDIF_DATA16  0x79
		MX6UL_PAD_LCD_DATA17__LCDIF_DATA17  0x79
		MX6UL_PAD_LCD_DATA18__LCDIF_DATA18  0x79
		MX6UL_PAD_LCD_DATA19__LCDIF_DATA19  0x79
		MX6UL_PAD_LCD_DATA20__LCDIF_DATA20  0x79
		MX6UL_PAD_LCD_DATA21__LCDIF_DATA21  0x79
		MX6UL_PAD_LCD_DATA22__LCDIF_DATA22  0x79
		MX6UL_PAD_LCD_DATA23__LCDIF_DATA23  0x79
	>;
};

pinctrl_lcdif_ctrl: lcdifctrlgrp {
	fsl,pins = <
		MX6UL_PAD_LCD_CLK__LCDIF_CLK	    0x79
		MX6UL_PAD_LCD_ENABLE__LCDIF_ENABLE  0x79
		MX6UL_PAD_LCD_HSYNC__LCDIF_HSYNC    0x79
		MX6UL_PAD_LCD_VSYNC__LCDIF_VSYNC    0x79
	>;
};

pinctrl_pwm1: pwm1grp {
	fsl,pins = <
		MX6UL_PAD_GPIO1_IO08__PWM1_OUT   0x110b0
	>;
};

The child node pinctrl_lcdif_dat is the configuration item of 24 data lines of RGBLCD

The child node pinctrl_lcdif_ctrl is the 4 control line configuration items of RBGLCD including CLK

The child node pinctrl_pwm1 is the configuration item of the LCD backlight PWM pin

3. LCD screen parameter node information

&lcdif {
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_lcdif_dat           /* 使用到的 IO */ 
		     &pinctrl_lcdif_ctrl;

	display = <&display0>;
	status = "okay";

	display0: display {                       /* LCD 属性信息 */
		bits-per-pixel = <24>;                /* 一个像素占用 24bit */
		bus-width = <24>;                     /* 总线宽度 */

		display-timings {                     /* 时序信息 */
			native-mode = <&timing0>;
			timing0: timing0 {
			clock-frequency = <51200000>;
			hactive = <1024>;
			vactive = <600>;
			hfront-porch = <160>;
			hback-porch = <140>;
			hsync-len = <20>;
			vback-porch = <20>;
			vfront-porch = <12>;
			vsync-len = <3>;

			hsync-active = <0>;               /* hsync 数据线极性 */
			vsync-active = <0>;               /* vsync 数据线极性 */
			de-active = <1>;                  /* de 数据线极性 */
			pixelclk-active = <0>;            /* clk 数据线先极性 */  
			};
		};
	};
};

4. LCD backlight

(1) PWM drive

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>;
};

Search the compatible attribute to find the driver of pwm in the linux kernel

(2) Add pwm node

Add under the corresponding development board device tree dts file:

&pwm1 {
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_pwm1>;
	status = "okay";
};

(3) Connect the backlight node to linux

backlight {
	compatible = "pwm-backlight";
	pwms = <&pwm1 0 5000000>;
	brightness-levels = <0 4 8 16 32 64 128 255>;
	default-brightness-level = <6>;
	status = "okay";
};

Two: Compile and debug

1. Turn on the little penguin logo when Linux starts

2. Set LCD as a terminal console

(1) Modify the bootargs of uboot: open two consoles

setenv bootargs 'console=tty1 console=ttymxc0,115200 root=/dev/nfs rw nfsroot=192.168.1.250:
/home/zuozhongkai/linux/nfs/rootfs ip=192.168.1.251:192.168.1.250:192.168.1.1:255.255.255.0::eth0:
off'

(2) Modify /etc/inittab

Add to:

tty1::askfirst:-/bin/sh

After startup, you can enter echo hello linux >/dev/tty1

3. Adjust the backlight

echo n > brightness

Where n is the maximum brightness level of 7

Guess you like

Origin blog.csdn.net/qq_34968572/article/details/104796182