“Linux内核-MIPI LCD驱动移植”的版本间的差异

来自华清远见研发中心
跳转至: 导航搜索
实验步骤
实验原理
 
第4行: 第4行:
 
MIPI®DSI主机包括内部连接到LTDC的专用视频接口以及一个通用的APB接口,可用于向显示器传输信息。<br>
 
MIPI®DSI主机包括内部连接到LTDC的专用视频接口以及一个通用的APB接口,可用于向显示器传输信息。<br>
  
[[Image:52-1-1-1.png|640px]] <br>
+
<center>[[Image:52-1-1-1.png|640px]]</center> <br>
  
 
FS_MP1A提供两组LCD显示接口,分别是RGB和MIPI接口,本节介绍如何在Linux中完成MIPI LCD的支持。<br>
 
FS_MP1A提供两组LCD显示接口,分别是RGB和MIPI接口,本节介绍如何在Linux中完成MIPI LCD的支持。<br>
  
  
[[Image:52-1-1-2.png]] <br>
+
<center>[[Image:52-1-1-2.png]]</center> <br>
  
 
上图为MIPI LCD的接口,接口信号线分为两组,分别是由DSI_D0P、DSI_D0N、DSI_D1P、DSI_D1N、DSI_CKP、DSI_CKN、DSI_TE、DSI_RST、LCD_PWM组成的LCD接口和由I2C2_SCL、I2C2_SDA、TP_RST、TP_IRQ组成的触摸屏接口,本节介绍LCD的支持。<br>
 
上图为MIPI LCD的接口,接口信号线分为两组,分别是由DSI_D0P、DSI_D0N、DSI_D1P、DSI_D1N、DSI_CKP、DSI_CKN、DSI_TE、DSI_RST、LCD_PWM组成的LCD接口和由I2C2_SCL、I2C2_SDA、TP_RST、TP_IRQ组成的触摸屏接口,本节介绍LCD的支持。<br>
第17行: 第17行:
 
MIPI LCD接口管脚对应关系:
 
MIPI LCD接口管脚对应关系:
  
[[Image:52-1-1-3.png]] <br>
+
<center>[[Image:52-1-1-3.png]]</center> <br>
  
[[Image:52-1-1-4.png]] <br>
+
<center>[[Image:52-1-1-4.png]]</center> <br>
  
[[Image:52-1-1-5.png]] <br>
+
<center>[[Image:52-1-1-5.png]]</center> <br>
  
[[Image:52-1-1-6.png]] <br>
+
<center> [[Image:52-1-1-6.png]]</center>  <br>
  
{|class="wikitable"
+
{|align=center border=1
 
|-
 
|-
 
! 原理图网络编号 !! 对应管脚 !! 管脚功能 !! 管脚功能码
 
! 原理图网络编号 !! 对应管脚 !! 管脚功能 !! 管脚功能码

2021年3月24日 (三) 15:27的最新版本

实验原理

DSI(Display Serial Interface),是有MIPI联盟定义的一组通信协议的一部分,MIPI DSI主机控制器是一个数字核心,实现MIPI DSI规范中定义的所有协议功能。它提供了系统和MIPI D_PHY中间的接口,允许用户和符合DSI的显示器进行通信。STM32MP157A系列芯片集成MIPI DSI主机控制器。

MIPI®DSI主机包括内部连接到LTDC的专用视频接口以及一个通用的APB接口,可用于向显示器传输信息。

52-1-1-1.png

FS_MP1A提供两组LCD显示接口,分别是RGB和MIPI接口,本节介绍如何在Linux中完成MIPI LCD的支持。


52-1-1-2.png

上图为MIPI LCD的接口,接口信号线分为两组,分别是由DSI_D0P、DSI_D0N、DSI_D1P、DSI_D1N、DSI_CKP、DSI_CKN、DSI_TE、DSI_RST、LCD_PWM组成的LCD接口和由I2C2_SCL、I2C2_SDA、TP_RST、TP_IRQ组成的触摸屏接口,本节介绍LCD的支持。

DSI_D0P、DSI_D0N、DSI_D1P、DSI_D1N、DSI_CKP、DSI_CKN是DSI-MIPI的信号线,DSI_TE未使用,DSI_RST是LCD屏复位信号LCD_PWM是背光控制信号。

MIPI LCD接口管脚对应关系:

52-1-1-3.png

52-1-1-4.png

52-1-1-5.png

52-1-1-6.png

原理图网络编号 对应管脚 管脚功能 管脚功能码
DSI_D0P DSI_D0P DSI_D0P DSI信号线对应管脚为单一功能管脚
DSI_D0N DSI_D0N DSI_D0N
DSI_D1P DSI_D1P DSI_D1P
DSI_D1N DSI_D1N DSI_D1N
DSI_CKP DSI_CKP DSI_CKP
DSI_CKN DSI_CKN DSI_CKN
DSI_TE PC6 IO
DSI_RST PG9 IO
LCD_PWM PA5 TIM2_CH1 AF1
  1. PWM设备节点

  2. 参考文档:

    Documentation/devicetree/bindings/pwm/pwm-stm32.txt
    

    内核中ST对STM32MP15x系列芯片的设备树资源了做了定义,可参见:

    arch/arm/boot/dts/stm32mp151.dtsi
    

    stm32mp151中timers2定义如下:

    timers2: timer@40000000 {
    	#address-cells = <1>;
    	#size-cells = <0>;
    	compatible = "st,stm32-timers";
    	reg = <0x40000000 0x400>;
    	clocks = <&rcc TIM2_K>;
    	clock-names = "int";
    	dmas = <&dmamux1 18 0x400 0x80000001>,
    	       <&dmamux1 19 0x400 0x80000001>,
    	       <&dmamux1 20 0x400 0x80000001>,
    	       <&dmamux1 21 0x400 0x80000001>,
    	       <&dmamux1 22 0x400 0x80000001>;
    	dma-names = "ch1", "ch2", "ch3", "ch4", "up";
    	status = "disabled";
    
    	pwm {
    		compatible = "st,stm32-pwm";
    		#pwm-cells = <3>;
    		status = "disabled";
    	};
    
    	timer@1 {
    		compatible = "st,stm32h7-timer-trigger";
    		reg = <1>;
    		status = "disabled";
    	};
    
    	counter {
    			compatible = "st,stm32-timer-counter";
    			status = "disabled";
    		};
    	};
    

    上述代码只对timers5做了基本的初始化,并没有针对不同的硬件设计做适配,所以需结合硬件补全设备树节点信息。

    参考文档或stm32mp15xx-dkx.dtsi对于i2c设备节点的描述,增加timers内容如下:

    &timers2 {
    	/* spare dmas for other usage */
    	/delete-property/dmas;
    	/delete-property/dma-names;
    	status = "okay";
    	pwm2: pwm {
    		pinctrl-0 = <&pwm2_pins_b>;
    		pinctrl-1 = <&pwm2_sleep_pins_b>;
    		pinctrl-names = "default", "sleep";
    		#pwm-cells = <2>;
    		status = "okay";
    	};
    	timer@2 {
    		status = "disabled";
    	};
    };
    

    stm32mp15-pinctrl.dtsi对于pwm2的描述与FS-MP1A所使用管脚不一致,所以无法直接使用,需参考其增加如下内容:

    pwm2_pins_b: pwm2-0 {
    	pins {
    		pinmux = <STM32_PINMUX('A', 5, AF1)>; /* TIM2_CH1 */
    		bias-pull-down;
    		drive-push-pull;
    		slew-rate = <0>;
    	};
    };
    pwm2_sleep_pins_b: pwm1-sleep-0 {
    	pins {
    		pinmux = <STM32_PINMUX('A', 5, ANALOG)>; /* TIM2_CH1 */
    	};
    };
    
  3. 背光设备节点

  4. 参考文档:

    Documentation/devicetree/bindings/leds/backlight/pwm-backlight.txt
    Documentation/devicetree/bindings/leds/backlight/gpio-backlight.txt
    

    FS-MP1A背光可以通过GPIO驱动也可通过PWM2的通道1驱动,可以对比参考文档或内核中其他设备树关于背光的定义。

    GPIO驱动背光节点内容如下:

    panel_backlight: panel-backlight {
    	compatible = "gpio-backlight";
    	gpios = <&gpiod 13 GPIO_ACTIVE_LOW>;
    		default-on;
    	status = "okay";
    };
    

    PWM驱动背光节点内容如下:

    panel_backlight: panel-backlight {
    	compatible = "pwm-backlight";
    	pwms = <&pwm2 0 5000000>;
    	brightness-levels = <0 4 8 16 32 64 128 255>;
    	default-brightness-level = <6>;
    	status = "okay";
    };
    
  5. LTDC设备节点

  6. 参考文档:

    Documentation/devicetree/bindings/display/st,stm32-ltdc.txt
    

    由于前面章节已经对LTDC做了讲解,并且已经增加了LTDC的设备节点,本节只需在原有基础上增加DSI对应的数据通道即可。

    &ltdc {
    	status = "okay";
    
    	port {
    		#address-cells = <1>;
    		#size-cells = <0>;
    
    		ltdc_ep1_out: endpoint@1 {
    			reg = <1>;
    			remote-endpoint = <&dsi_in>;
    		};
    	};
    };
    
  7. Panel设备树节点

  8. 参考文档:

    Documentation/devicetree/bindings/display/panel/panel-dsi-cm.txt
    

    结合参考文档及内核中STM32MP157其他设备树文件,Panel设备树节点为:

    panel: panel@0 {
    	compatible = "sitronix,st7701";
    	reg = <0>;
    	reset-gpios = <&gpiog 9 GPIO_ACTIVE_HIGH>;
    	power-supply = <&v3v3>;
    	status = "okay";
    
    	port {
    		panel_in: endpoint {
    			remote-endpoint = <&dsi_out>;
    		};
    	};
    };
    
  9. DSI设备树节点

  10. 参考文档:

    Documentation/devicetree/bindings/display/mipi-dsi-bus.txt
    

    内核中ST对STM32MP15x系列芯片的设备树资源了做了定义,可参见:

    arch/arm/boot/dts/stm32mp157.dtsi
    

    stm32mp157中dsi定义如下:

    dsi: dsi@5a000000 {
    		compatible = "st,stm32-dsi";
    		reg = <0x5a000000 0x800>;
    		phy-dsi-supply = <&reg18>;
    		clocks = <&rcc DSI_K>, <&scmi0_clk CK_SCMI0_HSE>, <&rcc DSI_PX>;
    		clock-names = "pclk", "ref", "px_clk";
    		resets = <&rcc DSI_R>;
    		reset-names = "apb";
    		status = "disabled";
    	};
    

    上述代码只对dsi做了基本的初始化,并没有针对不同的硬件设计做适配,所以需结合硬件补全设备树节点信息。补齐后内容如下:

    &dsi {
    	#address-cells = <1>;
    	#size-cells = <0>;
    	status = "okay";
    
    	ports {
    		#address-cells = <1>;
    		#size-cells = <0>;
    
    		port@0 {
    			reg = <0>;
    			dsi_in: endpoint {
    				remote-endpoint = <&ltdc_ep1_out>;
    			};
    		};
    
    		port@1 {
    			reg = <1>;
    			dsi_out: endpoint {
    				remote-endpoint = <&dsi_panel_in>;
    			};
    		};
    	};
    
    	panel_dsi: panel-dsi@0 {
    		compatible = "sitronix,st7701";
    		reg = <0>;
    		reset-gpios = <&gpiog 9 GPIO_ACTIVE_LOW>;
    		backlight = <&panel_backlight>;
    		power-supply = <&v3v3>;
    		status = "okay";
    
    		port {
    			dsi_panel_in: endpoint {
    				remote-endpoint = <&dsi_out>;
    			};
    		};
    	};
    };
    

实验目的

熟悉基于Linux操作系统下的MIPI-LCD设备驱动移植配置过程。

实验平台

华清远见开发环境,FS-MP1A平台;

实验步骤

  1. 导入交叉编译工具链
  2. linux@ubuntu:$ source /opt/st/stm32mp1/3.1-openstlinux-5.4-dunfell-mp1-20-06-24/environment-setup-cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi
    
  3. 添加MIPI-LCD驱动

  4. FS-MP1A配套MIPI屏幕主控芯片是st7701,内核中并没有提供其的驱动,所以需要移植st7701的驱动

    将【华清远见-FS_MP1A开发资料\02-程序源码\04-Linux系统移植\04-移植相关文件\02-Linux内核移植\st7701驱动】下的panel-sitronix-st7701.c复制到内核源码下的drivers/gpu/drm/panel/目录下。

    linux@ubuntu $> cp panel-sitronix-st7701.c drivers/gpu/drm/panel/
    
  5. 添加pwm2内容

  6. 修改stm32mp15xx-fsmp1x.dtsi,在stm32mp15xx-fsmp1x.dtsi文件末尾添加如下内容:

    &timers2 {
    	/* spare dmas for other usage */
    	/delete-property/dmas;
    	/delete-property/dma-names;
    	status = "okay";
    	pwm2: pwm {
    		pinctrl-0 = <&pwm2_pins_b>;
    		pinctrl-1 = <&pwm2_sleep_pins_b>;
    		pinctrl-names = "default", "sleep";
    		#pwm-cells = <2>;
    		status = "okay";
    	};
    	timer@2 {
    		status = "disabled";
    	};
    };
    
    &pinctrl {
    	pwm2_pins_b: pwm2-0 {
    		pins {
    			pinmux = <STM32_PINMUX('A', 5, AF1)>; /* TIM2_CH1 */
    			bias-pull-down;
    			drive-push-pull;
    			slew-rate = <0>;
    		};
    	};
    	pwm2_sleep_pins_b: pwm1-sleep-0 {
    		pins {
    			pinmux = <STM32_PINMUX('A', 5, ANALOG)>; /* TIM2_CH1 */
    		};
    	};
    };
    
  7. 添加背光内容

  8. 修改stm32mp15xx-fsmp1x.dtsi,在根节点中添加如下内容:

    panel_backlight: panel-backlight {
    	compatible = "pwm-backlight";
    	pwms = <&pwm2 0 5000000>;
    	brightness-levels = <0 4 8 16 32 64 128 255>;
    	default-brightness-level = <6>;
    	status = "okay";
    };
    
  9. 增加设备树文件

  10. 由于MIPI LCD并非FS-MP1A必须配置,本节增加一个设备树文件,对应增加了屏幕的设备。

    在内核的arch/arm/boot/dts目录下新建文件stm32mp157a-fsmp1a-mipi050.dts文件并添加如下内容:

    #include "stm32mp157a-fsmp1a.dts"
    
    / {
        model = "HQYJ STM32MP157 FSMP1A MIPI Discovery Board";
        compatible = "st,stm32mp157a-dk1", "st,stm32mp157";
    };
    

    由于增加了新的设备树文件需修改arch/arm/boot/dts/Makefile,在文件中增加新的条目,红色字体部分为增加内容

    dtb-$(CONFIG_ARCH_STM32) += \
    stm32mp157a-dk1.dtb \
    stm32mp157a-fsmp1a.dtb \

    stm32mp157a-fsmp1a-mipi050.dtb \

    stm32mp157d-dk1.dtb \
  11. 添加ltdc内容

  12. 修改stm32mp157a-fsmp1a-mipi050.dts,在文件末尾添加如下内容:

    &ltdc {
    	status = "okay";
    
    	port {
    		#address-cells = <1>;
    		#size-cells = <0>;
    
    		ltdc_ep1_out: endpoint@1 {
    			reg = <1>;
    			remote-endpoint = <&dsi_in>;
    		};
    	};
    };
    
  13. 添加dts内容

  14. 修改stm32mp157a-fsmp1a-mipi050.dts,在文件末尾添加如下内容:

    &dsi {
    	#address-cells = <1>;
    	#size-cells = <0>;
    	status = "okay";
    
    	ports {
    		#address-cells = <1>;
    		#size-cells = <0>;
    
    		port@0 {
    			reg = <0>;
    			dsi_in: endpoint {
    				remote-endpoint = <&ltdc_ep1_out>;
    			};
    		};
    
    		port@1 {
    			reg = <1>;
    			dsi_out: endpoint {
    				remote-endpoint = <&dsi_panel_in>;
    			};
    		};
    	};
    
    	panel_dsi: panel-dsi@0 {
    		compatible = "sitronix,st7701";
    		reg = <0>;
    		reset-gpios = <&gpiof 15 GPIO_ACTIVE_LOW>;
    		backlight = <&panel_backlight>;
    		power-supply = <&v3v3>;
    		status = "okay";
    
    		port {
    			dsi_panel_in: endpoint {
    				remote-endpoint = <&dsi_out>;
    			};
    		};
    	};
    };
    
  15. 配置内核

  16. 配置内核支持st7701,并列出主要选项,如下:

    linux@ubuntu:$ make menuconfig
    Device Drivers  --->
    	Graphics support  --->
    		<*> Direct Rendering Manager (XFree86 4.1.0 and higher DRI support)  --->
    		<*> DRM Support for STMicroelectronics SoC Series
    		<*>   STMicroelectronics specific extensions for Synopsys MIPI DSI
    		Display Panels  --->
    			<*> Sitronix ST7701 panel driver
    		Backlight & LCD device support  --->
    			<*>   Generic PWM based Backlight Driver
    			<*>   Generic GPIO based Backlight Driver
    
    
  17. 增加启动项
  18. 在虚拟机/tftpboot /tftpboot/pxelinux.cfg/01-00-80-e1-42-60-17末尾添加

    LABEL stm32mp157a-fsmp1a-mipi
       KERNEL /uImage
       FDT /stm32mp157a-fsmp1a-mipi050.dtb
       APPEND root=/dev/mmcblk1p4 rootwait rw console=ttySTM0,115200
    
  19. 编译内核及设备树
  20. linux@ubuntu:$ make -j4 uImage dtbs LOADADDR=0xC2000040
    
  21. 重启测试
  22. 将编译好的设备树和内核镜像拷贝到/tftpboot目录下,通过tftp引导内核,设备连接HDMI显示器,重启设备后查看/sys/class/drm会多出HMID的信息,同时显示器会有显示。