“Linux内核-MIPI LCD驱动移植”的版本间的差异
(创建页面,内容为“==实验原理== DSI(Display Serial Interface),是有MIPI联盟定义的一组通信协议的一部分,MIPI DSI主机控制器是一个数字核心,实现MIPI...”) |
(→实验原理) |
||
| 第5行: | 第5行: | ||
[[Image:52-1-1-1.png]] <br> | [[Image:52-1-1-1.png]] <br> | ||
| + | |||
| + | FS_MP1A提供两组LCD显示接口,分别是RGB和MIPI接口,本节介绍如何在Linux中完成MIPI LCD的支持。<br> | ||
| + | |||
| + | |||
| + | [[Image:52-1-1-2.png]] <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> | ||
| + | |||
| + | DSI_D0P、DSI_D0N、DSI_D1P、DSI_D1N、DSI_CKP、DSI_CKN是DSI-MIPI的信号线,DSI_TE未使用,DSI_RST是LCD屏复位信号LCD_PWM是背光控制信号。<br> | ||
| + | |||
| + | MIPI LCD接口管脚对应关系: | ||
| + | |||
| + | [[Image:52-1-1-3.png]] <br> | ||
| + | |||
| + | [[Image:52-1-1-4.png]] <br> | ||
| + | |||
| + | [[Image:52-1-1-5.png]] <br> | ||
| + | |||
| + | [[Image:52-1-1-6.png]] <br> | ||
| + | |||
| + | {|class="wikitable" | ||
| + | |- | ||
| + | ! 原理图网络编号 !! 对应管脚 !! 管脚功能 !! 管脚功能码 | ||
| + | |- | ||
| + | | DSI_D0P | ||
| + | | DSI_D0P | ||
| + | | DSI_D0P | ||
| + | | DSI信号线对应管脚为单一功能管脚 | ||
| + | |- | ||
| + | | DSI_D0N | ||
| + | | DSI_D0N | ||
| + | | DSI_D0N | ||
| + | | DSI信号线对应管脚为单一功能管脚 | ||
| + | |- | ||
| + | | DSI_D1P | ||
| + | | DSI_D1P | ||
| + | | DSI_D1P | ||
| + | | DSI信号线对应管脚为单一功能管脚 | ||
| + | |- | ||
| + | | DSI_D1N | ||
| + | | DSI_D1N | ||
| + | | DSI_D1N | ||
| + | | DSI信号线对应管脚为单一功能管脚 | ||
| + | |- | ||
| + | | DSI_CKP | ||
| + | | DSI_CKP | ||
| + | | DSI_CKP | ||
| + | | DSI信号线对应管脚为单一功能管脚 | ||
| + | |- | ||
| + | | DSI_CKN | ||
| + | | DSI_CKN | ||
| + | | DSI_CKN | ||
| + | | DSI信号线对应管脚为单一功能管脚 | ||
| + | |- | ||
| + | | DSI_TE | ||
| + | | PC6 | ||
| + | | IO | ||
| + | | | ||
| + | |- | ||
| + | | DSI_RST | ||
| + | | PG9 | ||
| + | | IO | ||
| + | | | ||
| + | |- | ||
| + | | LCD_PWM | ||
| + | | PA5 | ||
| + | | TIM2_CH1 | ||
| + | | AF1 | ||
| + | |} | ||
| + | *PWM设备节点<br> | ||
| + | |||
| + | 参考文档: | ||
| + | Documentation/devicetree/bindings/pwm/pwm-stm32.txt | ||
| + | 内核中ST对STM32MP15x系列芯片的设备树资源了做了定义,可参见: | ||
| + | arch/arm/boot/dts/stm32mp151.dtsi | ||
| + | stm32mp151中timers2定义如下: | ||
| + | <pre><nowiki> | ||
| + | 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"; | ||
| + | }; | ||
| + | }; | ||
| + | </nowiki></pre> | ||
| + | 上述代码只对timers5做了基本的初始化,并没有针对不同的硬件设计做适配,所以需结合硬件补全设备树节点信息。<br> | ||
| + | |||
| + | 参考文档或stm32mp15xx-dkx.dtsi对于i2c设备节点的描述,增加timers内容如下: | ||
| + | <pre><nowiki> | ||
| + | &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"; | ||
| + | }; | ||
| + | }; | ||
| + | </nowiki></pre> | ||
| + | stm32mp15-pinctrl.dtsi对于pwm2的描述与FS-MP1A所使用管脚不一致,所以无法直接使用,需参考其增加如下内容: | ||
| + | <pre><nowiki> | ||
| + | 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 */ | ||
| + | }; | ||
| + | }; | ||
| + | </nowiki></pre> | ||
| + | *背光设备节点<br> | ||
| + | |||
| + | 参考文档: | ||
| + | <pre><nowiki> | ||
| + | Documentation/devicetree/bindings/leds/backlight/pwm-backlight.txt | ||
| + | Documentation/devicetree/bindings/leds/backlight/gpio-backlight.txt | ||
| + | </nowiki></pre> | ||
| + | FS-MP1A背光可以通过GPIO驱动也可通过PWM2的通道1驱动,可以对比参考文档或内核中其他设备树关于背光的定义。<br> | ||
| + | |||
| + | GPIO驱动背光节点内容如下: | ||
| + | <pre><nowiki> | ||
| + | panel_backlight: panel-backlight { | ||
| + | compatible = "gpio-backlight"; | ||
| + | gpios = <&gpiod 13 GPIO_ACTIVE_LOW>; | ||
| + | default-on; | ||
| + | status = "okay"; | ||
| + | }; | ||
| + | </nowiki></pre> | ||
| + | PWM驱动背光节点内容如下: | ||
| + | <pre><nowiki> | ||
| + | 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"; | ||
| + | }; | ||
| + | </nowiki></pre> | ||
| + | *LTDC设备节点<br> | ||
| + | |||
| + | 参考文档: | ||
| + | Documentation/devicetree/bindings/display/st,stm32-ltdc.txt | ||
| + | 由于前面章节已经对LTDC做了讲解,并且已经增加了LTDC的设备节点,本节只需在原有基础上增加DSI对应的数据通道即可。 | ||
| + | <pre><nowiki> | ||
| + | <dc { | ||
| + | status = "okay"; | ||
| + | |||
| + | port { | ||
| + | #address-cells = <1>; | ||
| + | #size-cells = <0>; | ||
| + | |||
| + | ltdc_ep1_out: endpoint@1 { | ||
| + | reg = <1>; | ||
| + | remote-endpoint = <&dsi_in>; | ||
| + | }; | ||
| + | }; | ||
| + | }; | ||
| + | </nowiki></pre> | ||
| + | *Panel设备树节点<br> | ||
| + | |||
| + | 参考文档: | ||
| + | Documentation/devicetree/bindings/display/panel/panel-dsi-cm.txt | ||
| + | 结合参考文档及内核中STM32MP157其他设备树文件,Panel设备树节点为: | ||
| + | <pre><nowiki> | ||
| + | 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>; | ||
| + | }; | ||
| + | }; | ||
| + | }; | ||
| + | </nowiki></pre> | ||
| + | *DSI设备树节点<br> | ||
| + | |||
| + | 参考文档: | ||
| + | Documentation/devicetree/bindings/display/mipi-dsi-bus.txt | ||
| + | 内核中ST对STM32MP15x系列芯片的设备树资源了做了定义,可参见: | ||
| + | arch/arm/boot/dts/stm32mp157.dtsi | ||
| + | stm32mp157中dsi定义如下: | ||
| + | <pre><nowiki> | ||
| + | dsi: dsi@5a000000 { | ||
| + | compatible = "st,stm32-dsi"; | ||
| + | reg = <0x5a000000 0x800>; | ||
| + | phy-dsi-supply = <®18>; | ||
| + | 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"; | ||
| + | }; | ||
| + | </nowiki></pre> | ||
| + | 上述代码只对dsi做了基本的初始化,并没有针对不同的硬件设计做适配,所以需结合硬件补全设备树节点信息。补齐后内容如下: | ||
| + | <pre><nowiki> | ||
| + | &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 = <<dc_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>; | ||
| + | }; | ||
| + | }; | ||
| + | }; | ||
| + | }; | ||
| + | </nowiki></pre> | ||
| + | |||
==实验目的== | ==实验目的== | ||
==实验平台== | ==实验平台== | ||
==实验步骤== | ==实验步骤== | ||
2020年7月28日 (二) 10:44的版本
实验原理
DSI(Display Serial Interface),是有MIPI联盟定义的一组通信协议的一部分,MIPI DSI主机控制器是一个数字核心,实现MIPI DSI规范中定义的所有协议功能。它提供了系统和MIPI D_PHY中间的接口,允许用户和符合DSI的显示器进行通信。STM32MP157A系列芯片集成MIPI DSI主机控制器。
MIPI®DSI主机包括内部连接到LTDC的专用视频接口以及一个通用的APB接口,可用于向显示器传输信息。
FS_MP1A提供两组LCD显示接口,分别是RGB和MIPI接口,本节介绍如何在Linux中完成MIPI LCD的支持。
上图为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接口管脚对应关系:
| 原理图网络编号 | 对应管脚 | 管脚功能 | 管脚功能码 |
|---|---|---|---|
| DSI_D0P | DSI_D0P | DSI_D0P | DSI信号线对应管脚为单一功能管脚 |
| DSI_D0N | DSI_D0N | DSI_D0N | DSI信号线对应管脚为单一功能管脚 |
| DSI_D1P | DSI_D1P | DSI_D1P | DSI信号线对应管脚为单一功能管脚 |
| DSI_D1N | DSI_D1N | DSI_D1N | DSI信号线对应管脚为单一功能管脚 |
| DSI_CKP | DSI_CKP | DSI_CKP | DSI信号线对应管脚为单一功能管脚 |
| DSI_CKN | DSI_CKN | DSI_CKN | DSI信号线对应管脚为单一功能管脚 |
| DSI_TE | PC6 | IO | |
| DSI_RST | PG9 | IO | |
| LCD_PWM | PA5 | TIM2_CH1 | AF1 |
- PWM设备节点
参考文档:
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 */
};
};
- 背光设备节点
参考文档:
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";
};
- LTDC设备节点
参考文档:
Documentation/devicetree/bindings/display/st,stm32-ltdc.txt
由于前面章节已经对LTDC做了讲解,并且已经增加了LTDC的设备节点,本节只需在原有基础上增加DSI对应的数据通道即可。
<dc {
status = "okay";
port {
#address-cells = <1>;
#size-cells = <0>;
ltdc_ep1_out: endpoint@1 {
reg = <1>;
remote-endpoint = <&dsi_in>;
};
};
};
- Panel设备树节点
参考文档:
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>;
};
};
};
- DSI设备树节点
参考文档:
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 = <®18>;
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 = <<dc_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>;
};
};
};
};





