[Beijing Xunwei] i.MX6ULL Terminator Linux LCD driver experiment writing LCD driver

The eLCDIF interface driver NXP of i.MX6ULL has been written, so
we don't need to modify the LCD driver part . What we need to do is to modify the device tree according to the LCD used. There are three important points to pay attention to:
① The IO configuration used by the LCD.
② Modify the LCD screen node, modify the corresponding attribute value, and replace it with the LCD screen parameters we use.
③ To modify LCD backlight node information, modify the corresponding device node information according to the actual backlight IO used. Next, let's take a look at how to modify the above two nodes in turn.

1 LCD screen GPIO configuration in the device tree

First of all, we must determine which pins are used by the LCD screen. In fact, these pins are already written in the NXP device tree file. Let's check whether the GPIO pins are correct. Open the imx6ull-14x14-evk.dts file, there are the following contents under the iomuxc node:

1 pinctrl_lcdif_dat: lcdifdatgrp {
    
     
2 	fsl,pins = < 
3 			MX6UL_PAD_LCD_DATA00__LCDIF_DATA00 0x79 
4 			MX6UL_PAD_LCD_DATA01__LCDIF_DATA01 0x79 
5 			MX6UL_PAD_LCD_DATA02__LCDIF_DATA02 0x79 
6 			MX6UL_PAD_LCD_DATA03__LCDIF_DATA03 0x79 
7 			MX6UL_PAD_LCD_DATA04__LCDIF_DATA04 0x79 
8 			MX6UL_PAD_LCD_DATA05__LCDIF_DATA05 0x79 
9 			MX6UL_PAD_LCD_DATA06__LCDIF_DATA06 0x79 
10 			MX6UL_PAD_LCD_DATA07__LCDIF_DATA07 0x79 
11 			MX6UL_PAD_LCD_DATA08__LCDIF_DATA08 0x79 
12 			MX6UL_PAD_LCD_DATA09__LCDIF_DATA09 0x79 
13 			MX6UL_PAD_LCD_DATA10__LCDIF_DATA10 0x79 
14 			MX6UL_PAD_LCD_DATA11__LCDIF_DATA11 0x79 
15 			MX6UL_PAD_LCD_DATA12__LCDIF_DATA12 0x79 
16 			MX6UL_PAD_LCD_DATA13__LCDIF_DATA13 0x79 
17 			MX6UL_PAD_LCD_DATA14__LCDIF_DATA14 0x79 
18 			MX6UL_PAD_LCD_DATA15__LCDIF_DATA15 0x79 
19 			MX6UL_PAD_LCD_DATA16__LCDIF_DATA16 0x79 
20 			MX6UL_PAD_LCD_DATA17__LCDIF_DATA17 0x79 
21 			MX6UL_PAD_LCD_DATA18__LCDIF_DATA18 0x79 
22 			MX6UL_PAD_LCD_DATA19__LCDIF_DATA19 0x79 
23 			MX6UL_PAD_LCD_DATA20__LCDIF_DATA20 0x79 
24 			MX6UL_PAD_LCD_DATA21__LCDIF_DATA21 0x79 
25 			MX6UL_PAD_LCD_DATA22__LCDIF_DATA22 0x79 
26 			MX6UL_PAD_LCD_DATA23__LCDIF_DATA23 0x79 
27 		>; 
28 }; 
29
30 pinctrl_lcdif_ctrl: lcdifctrlgrp {
    
     
31 		fsl,pins = < 
32 			MX6UL_PAD_LCD_CLK__LCDIF_CLK 0x79 
33 			MX6UL_PAD_LCD_ENABLE__LCDIF_ENABLE 0x79 
34 			MX6UL_PAD_LCD_HSYNC__LCDIF_HSYNC 0x79 
35 			MX6UL_PAD_LCD_VSYNC__LCDIF_VSYNC 0x79 
36 		>; 
37 pinctrl_pwm1: pwm1grp {
    
     
38 		fsl,pins = < 
39 			MX6UL_PAD_GPIO1_IO08__PWM1_OUT 0x110b0 
40 		>; 
41 }; 

Lines 2-27, the sub-node pinctrl_lcdif_dat, is the configuration item of 24 data lines of RGB LCD.
Rows 30~36, subnode pinctrl_lcdif_ctrl, 4 control line configuration items of RGB LCD, including CLK, ENABLE, VSYNC and HSYNC.
Line 37~40, sub-node pinctrl_pwm1, LCD backlight PWM pin configuration item. This pin should be set according to the actual situation.

2 LCD screen parameter node information

Open the imx6ull-14x14-evk.dts file, find the lcdif node, the content is as follows:

1 &lcdif {
    
     
2          pinctrl-names = "default"; 
3          pinctrl-0 = <&pinctrl_lcdif_dat /* 使用到的 IO */ 
4          &pinctrl_lcdif_ctrl 
5          &pinctrl_lcdif_reset>; 
6          display = <&display0>; 
7          status = "okay"; 
8 
9          display0: display {
    
     /* LCD 属性信息 */ 
10                 bits-per-pixel = <16>; /* 一个像素占用几个 bit */ 
11              bus-width = <24>; /* 总线宽度 */ 
12 
13                 display-timings {
    
     
14                 native-mode = <&timing0>; /* 时序信息 */ 
15                 timing0: timing0 {
    
     
16                     clock-frequency = <9200000>; /* LCD 像素时钟,单位 Hz */ 
17                     hactive = <480>; /* LCD X 轴像素个数 */ 
18                     vactive = <272>; /* LCD Y 轴像素个数 */ 
19                     hfront-porch = <8>; /* LCD hfp 参数 */ 
20                     hback-porch = <4>; /* LCD hbp 参数 */ 
21                     hsync-len = <41>; /* LCD hspw 参数 */ 
22                     vback-porch = <2>; /* LCD vbp 参数 */
23                     vfront-porch = <4>; /* LCD vfp 参数 */ 
24                     vsync-len = <10>; /* LCD vspw 参数 */ 
25 
26                     hsync-active = <0>; /* hsync 数据线极性 */ 
27                     vsync-active = <0>; /* vsync 数据线极性 */ 
28                     de-active = <1>; /* de 数据线极性 */
29                     pixelclk-active = <0>; /* clk 数据线先极性 */ 
30                     };
31             }; 
32         }; 
33 }; 

The above code is the content added according to the LCD screen information you use.
Line 3, pinctrl-0 attribute, IO information used by LCD, here are three IO-related nodes, pinctrl_lcdif_dat, pinctrl_lcdif_ctrl and pinctrl_lcdif_reset, pinctrl_lcdif_reset is the LCD reset IO information node.
Line 6, display attribute, specifies the child node where the LCD attribute information is located, here is display0, and below is the content of the child node of display0.
Lines 9~32, display0 sub-node, describe LCD parameter information, the bits-per-pixel attribute in line 10 is used to indicate the number of bits occupied by a pixel, and the default is 16bit. In this tutorial, we will configure the LCD to RGB888 mode, so a pixel occupies 24 bits, and the bits-per-pixel attribute should be changed to 24. The bus-width property in line 11 is used to set the data line width, because it is configured to be RGB888 mode, the bus-width should also be set to 24.
Lines 13~30, these lines are very important! Because these lines set the timing parameter information of the LCD, NXP's official EVK development board uses a 4.3-inch 480*272 screen, so the default setting here is based on the official NXP screen parameters. The comments behind the meaning of each attribute have been written in great detail, so you can just read it yourself. These timing parameters are what we need to modify and need to be modified according to the screen you use.
Take Xunwei's 7-inch screen as an example, modify the lcdif node in the topeet_emmc_4_3.dts file:

1 &lcdif {
    
     
2  pinctrl-names = "default"; 
3  pinctrl-0 = <&pinctrl_lcdif_dat /* 使用到的 IO */ 
4              &pinctrl_lcdif_ctrl>; 
5  display = <&display0>; 
6  status = "okay"; 
7 
8  display0: display {
    
     /* LCD 属性信息 */ 
9      bits-per-pixel = <24>; /* 一个像素占用 24bit */ 
10         bus-width = <24>; /* 总线宽度 */ 
11 
12         display-timings {
    
     
13             native-mode = <&timing0>; /* 时序信息 */
14             timing0: timing0 {
    
     
15             clock-frequency = <70000000>;/* LCD 像素时钟,单位 Hz */ 
16             hactive = <1024>; /* LCD X 轴像素个数 */ 
17             vactive = <600>; /* LCD Y 轴像素个数 */ 
18             hfront-porch = <160>; /* LCD hfp 参数 */ 
19             hback-porch = <140>; /* LCD hbp 参数 */ 
20             hsync-len = <20>; /* LCD hspw 参数 */ 
21             vback-porch = <20>; /* LCD vbp 参数 */
22             vfront-porch = <12>; /* LCD vfp 参数 */ 
23             vsync-len = <3>; /* LCD vspw 参数 */ 
24 
25             hsync-active = <0>; /* hsync 数据线极性 */
26             vsync-active = <0>; /* vsync 数据线极性 */ 
27             de-active = <1>; /* de 数据线极性 */ 
28             pixelclk-active = <0>; /* clk 数据线先极性 */ 
29             }; 
30         }; 
31   }; 
32 }; 

Line 3, set the IO used by the LCD screen, delete the original pinctrl_lcdif_reset, because the screen reset IO is not used, and the other IOs remain unchanged.
The 9th line uses the RGB888 mode, so a pixel is 24bit.
Line 15~23, 7-inch screen timing parameters, or modify it according to the screen you are using.

3 LCD screen backlight node information

The i.MX6UL Terminator development board uses the GPIO1_IO08 pin as the backlight control pin of the LCD screen. The GPIO1_IO08 pin is multiplexed with the PWM1_OUT function, and the backlight brightness of the LCD screen is controlled by the PWM signal. Because the backlight control pin used by the official NXP development board is the same, the device node information about the backlight control pin in the device tree is modified differently. Because some users may use other pins to control the backlight, let's take a look at how to add device node information for backlight control GPIO.
The first is to add the pinctrl node of the GPIO1_IO08 pin. In the topeet_emmc_4_3.dts file, the content is as follows:

1 pinctrl_pwm1: pwm1grp {
    
     
2 	fsl,pins = < 
3 		MX6UL_PAD_GPIO1_IO08__PWM1_OUT 0x110b0 
4 	>; 
5 }; 

In line 3, set the multiplexing function of the GPIO1_IO08 pin to PWM1_OUT, and the electrical property to 0x110b0.
Because the GPIO1_IO08 pin is multiplexed as a pwm function, take a look at the node information of PWM1 in the imx6ull.dtsi file:

1 pwm1: pwm@02080000 {
    
    
2      compatible = "fsl,imx6ul-pwm", "fsl,imx27-pwm"; 
3      reg = <0x02080000 0x4000>; 
4      interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>; 
5      clocks = <&clks IMX6UL_CLK_PWM1>, 
6      <&clks IMX6UL_CLK_PWM1>; 
7      clock-names = "ipg", "per"; 
8        #pwm-cells = <2>; 
9 }; 

If you want to modify the information of the PWM1 node, do not modify it in the imx6ull.dtsi file. You can modify it by referencing the node in your device tree file, such as in the topeet_emmc_4_3.dts file. Through the compatible attribute value information, you can find the PWM driver file as drivers/pwm/pwm-imx.c.
Then take a look at what is modified in the pwm node in the topeet_emmc_4_3.dts file:

1 &pwm1 {
    
     
2 		pinctrl-names = "default"; 
3 		pinctrl-0 = <&pinctrl_pwm1>; 
4 		status = "okay"; 
5 };

The third line specifies that the pinctrl pin used by pwm1 is GPIO1_IO08.
In line 4, set status to okay.
If the backlight control pin uses other pwm channels, just add related content according to the settings of pwm1.
After setting pwm1, you also need to connect pwm1 and LCD backlight control. This node is the backlight. For the description of the backlight node, please refer to Documentation/devicetree/indings/video/backlight/pwm-backlight.txt. This document explains in detail How to create the backlight node, here is a summary:
① The node name should be "backlight".
② The compatible attribute value of the node must be "pwm-backlight", so you can search for "pwm-backlight" in the Linux kernel to find the PWM backlight control driver. The driver file is drivers/video/backlight/pwm_bl.c, Those who are interested can take a look at this driver.
③ The pwms attribute is used to describe the PWM and PWM frequency used by the backlight, such as the pwm1 we will use in this chapter, and the pwm frequency is set to 5KHz (the official NXP recommended setting).
④ The brightness-levels attribute describes the brightness level, ranging from 0 to 255, 0 means that the PWM duty cycle is 0%, which means the lowest brightness, and 255 means 100% duty cycle, which means the highest brightness. As for setting several levels of brightness, you can fill in this attribute yourself.
⑤ The default-brightness-level attribute is the default brightness level.
According to the above requirements, take a look at how to set in the topeet_emmc_4_3.dts file:

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

In line 3, set the backlight to use pwm1 and the PWM frequency to 5KHz.
In the fourth line, set the back 8 levels of backlight (0~7), respectively 0, 4, 8, 16, 32, 64, 128, 255, corresponding to the duty cycle of 0%, 1.57%, 3.13%, 6.27%, 12.55%, 25.1%, 50.19%, 100%, if you want to control the backlight brightness more accurately, you can add some other backlight level values ​​yourself.
In line 5, set the default backlight level to 6, which is 50.19% brightness.

Insert picture description here

Guess you like

Origin blog.csdn.net/BeiJingXunWei/article/details/112321060