本文章為《STM32MP157 Linux系統移植開發篇》系列中的一篇,筆者使用的開發平台為華清遠見FS-MP1A開發闆(STM32MP157開發闆)。stm32mp157是ARM雙核,2個A7核,1個M4核,A7核上可以跑Linux作業系統,M4核上可以跑FreeRTOS、RT-Thread等實時作業系統,STM32MP157開發闆是以既可以學嵌入式linux,也可以學stm32單片機。
針對FS-MP1A開發闆,除了Linux系統移植篇外,還包括其他多系列教程,包括Cortex-A7開發篇、Cortex-M4開發篇、擴充闆驅動移植篇、Linux應用開發篇、FreeRTOS系統移植篇、Linux驅動開發篇、硬體設計篇、人工智能機器視覺篇、Qt應用程式設計篇、Qt綜合項目實戰篇等。歡迎關注,更多stm32mp157開發教程及視訊,可加技術交流Q群459754978,感謝關注。
關于FS-MP1A開發闆:
手機淘寶分享碼:複制本行文字打開手淘₤T4FPXn3YYJ2₤
連結:https://item.taobao.com/item.htm?id=622457259672
1.1實驗原理
STM32MP157A系列SoC中預設沒有HDMI相關控制器,FS-MP1A使用SiI9022晶片将RGB信号轉化為HDMI信号。STM32MP157A內建LTDC(LCD-TFT Display Controller),提供一個24bit RGB并行接口用于連接配接到各種LCD和TFT面闆。

SiI9022晶片通過I2C5總線與SoC進行互動,通過SoC的LCD_PCLK、LCD_VSYNC、LCD_HSYNC、LCD_DEN與RGB信号線來進行圖像信号的傳輸,通過I2S2總線進行音頻資料的傳輸。
檢視原理圖确認I2C5、中斷、複位管腳對應關系:
原理圖網絡編号 | 對應管腳 | 管腳功能 | 管腳功能碼 |
I2C5_SCL | PA11 | I2C5_SCL | AF4 |
I2C5_SDA | PA12 | I2C5_SDA | AF4 |
HDMI_RST | PA13 | GPIO | |
HDMI_INT | PA14 | INT |
LCD接口管腳對應關系:
原理圖網絡編号 | 對應管腳 | 管腳功能 | 管腳功能碼 |
LCD_R0 | PI15 | LCD_R0 | AF14 |
LCD_R1 | PJ0 | LCD_R1 | AF14 |
LCD_R2 | PJ1 | LCD_R2 | AF14 |
LCD_R3 | PJ2 | LCD_R3 | AF14 |
LCD_R4 | PJ3 | LCD_R4 | AF14 |
LCD_R5 | PJ4 | LCD_R5 | AF14 |
LCD_R6 | PJ5 | LCD_R6 | AF14 |
LCD_R7 | PJ6 | LCD_R7 | AF14 |
LCD_G0 | PJ8 | LCD_G0 | AF14 |
LCD_G1 | PJ7 | LCD_G1 | AF14 |
LCD_G2 | PJ10 | LCD_G2 | AF14 |
LCD_G3 | PJ19 | LCD_G3 | AF14 |
LCD_G4 | PJ11 | LCD_G4 | AF14 |
LCD_G5 | PK0 | LCD_G5 | AF14 |
LCD_G6 | PK1 | LCD_G6 | AF14 |
LCD_G7 | PK2 | LCD_G7 | AF14 |
LCD_B0 | PJ12 | LCD_B0 | AF14 |
LCD_B1 | PJ13 | LCD_B1 | AF14 |
LCD_B2 | PJ14 | LCD_B2 | AF14 |
LCD_B3 | PJ15 | LCD_B3 | AF14 |
LCD_B4 | PK3 | LCD_B4 | AF14 |
LCD_B5 | PK4 | LCD_B5 | AF14 |
LCD_B6 | PK5 | LCD_B6 | AF14 |
LCD_B7 | PK6 | LCD_B7 | AF14 |
LCD_PCLK | PI14 | LCD_PCLK | AF14 |
LCD_DEN | PK7 | LCD_DEN | AF14 |
LCD_HSYNC | PI12 | LCD_HSYNC | AF14 |
LCD_VSYNC | PI13 | LCD_VSYNC | AF14 |
- I2C5裝置樹節點
參考文檔:
Documentation/devicetree/bindings/i2c/i2c-stm32.txt
核心中ST對STM32MP15x系列晶片的裝置樹資源了做了定義,可參見:
arch/arm/boot/dts/stm32mp151.dtsi
stm32mp151中i2c5定義如下:
i2c5: [email protected] {
compatible = "st,stm32mp15-i2c";
reg = <0x40015000 0x400>;
interrupt-names = "event", "error";
interrupts-extended = <&exti 25 IRQ_TYPE_LEVEL_HIGH>,
<&intc GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&rcc I2C5_K>;
resets = <&rcc I2C5_R>;
#address-cells = <1>;
#size-cells = <0>;
dmas = <&dmamux1 115 0x400 0x80000001>,
<&dmamux1 116 0x400 0x80000001>;
dma-names = "rx", "tx";
power-domains = <&pd_core>;
st,syscfg-fmp = <&syscfg 0x4 0x10>;
wakeup-source;
status = "disabled";
};
上述代碼隻對i2c5做了基本的初始化,并沒有針對不同的硬體設計做适配,是以需結合硬體補全裝置樹節點資訊。
參考stm32mp15xx-dkx.dtsi對于i2c裝置節點的描述,修改i2c5内容如下:
&i2c5 {
pinctrl-names = "default", "sleep";
pinctrl-0 = <&i2c5_pins_a>;
pinctrl-1 = <&i2c5_pins_sleep_a>;
i2c-scl-rising-time-ns = <100>;
i2c-scl-falling-time-ns = <7>;
clock-frequency = <100000>;
/delete-property/dmas;
/delete-property/dma-names;
status = "okay";
};
由于stm32mp15-pinctrl.dtsi中對于i2c5_pins_a和i2c5_pins_sleep_a的定義與闆子實際使用管腳一緻,是以無需修改,内容如下:
i2c5_pins_a: i2c5-0 {
pins {
pinmux = <STM32_PINMUX('A', 11, AF4)>,
<STM32_PINMUX('A', 12, AF4)>;
bias-disable;
drive-open-drain;
slew-rate = <0>;
};
};
i2c5_pins_sleep_a: i2c5-1 {
pins {
pinmux = <STM32_PINMUX('A', 11, ANALOG)>,
<STM32_PINMUX('A', 12, ANALOG)>;
};
};
- I2S2裝置樹節點
參考文檔:
Documentation/devicetree/bindings/i2c/sound/st,stm32-i2s.txt
- LTDC裝置樹節點
SiI9022實作HDMI輸出需要RGB信号作為資料源,LTDC為STM32MP157的LCD顯示控制器,可以輸出24bit的并行資料,HDMI顯示首先需要驅動LTDC。
參考文檔:
Documentation/devicetree/bindings/display/st,stm32-ltdc.txt
核心中ST對STM32MP15x系列晶片的裝置樹資源了做了定義,可參見:
arch/arm/boot/dts/stm32mp151.dtsi
stm32mp151中ltdc定義如下:
ltdc: [email protected] {
compatible = "st,stm32-ltdc";
reg = <0x5a001000 0x400>;
interrupts = <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&rcc LTDC_PX>;
clock-names = "lcd";
resets = <&rcc LTDC_R>;
status = "disabled";
};
上述代碼隻對ltdc做了基本的初始化,并沒有針對不同的硬體設計做适配,是以需結合硬體補全裝置樹節點資訊。
參考stm32mp15xx-dkx.dtsi對于ltdc裝置節點的描述,需增加内容如下:
<dc {
pinctrl-names = "default", "sleep";
pinctrl-0 = <<dc_pins_b>;
pinctrl-1 = <<dc_pins_sleep_b>;
status = "okay";
port {
#address-cells = <1>;
#size-cells = <0>;
ltdc_ep0_out: [email protected] {
reg = <0>;
remote-endpoint = <&sii9022_in>;
};
};
};
由于stm32mp15-pinctrl.dtsi中對于ltdc_pins_b和ltdc_pins_b的定于與闆子實際使用管腳一緻,是以無需修改,内容如下:
ltdc_pins_b: ltdc-b-0 {
pins {
pinmux = <STM32_PINMUX('I', 14, AF14)>,
<STM32_PINMUX('I', 12, AF14)>,
<STM32_PINMUX('I', 13, AF14)>,
<STM32_PINMUX('K', 7, AF14)>,
<STM32_PINMUX('I', 15, AF14)>,
<STM32_PINMUX('J', 0, AF14)>,
<STM32_PINMUX('J', 1, AF14)>,
<STM32_PINMUX('J', 2, AF14)>,
<STM32_PINMUX('J', 3, AF14)>,
<STM32_PINMUX('J', 4, AF14)>,
<STM32_PINMUX('J', 5, AF14)>,
<STM32_PINMUX('J', 6, AF14)>,
<STM32_PINMUX('J', 7, AF14)>,
<STM32_PINMUX('J', 8, AF14)>,
<STM32_PINMUX('J', 9, AF14)>,
<STM32_PINMUX('J', 10, AF14)>,
<STM32_PINMUX('J', 11, AF14)>,
<STM32_PINMUX('K', 0, AF14)>,
<STM32_PINMUX('K', 1, AF14)>,
<STM32_PINMUX('K', 2, AF14)>,
<STM32_PINMUX('J', 12, AF14)>,
<STM32_PINMUX('J', 13, AF14)>,
<STM32_PINMUX('J', 14, AF14)>,
<STM32_PINMUX('J', 15, AF14)>,
<STM32_PINMUX('K', 3, AF14)>,
<STM32_PINMUX('K', 4, AF14)>,
<STM32_PINMUX('K', 5, AF14)>,
<STM32_PINMUX('K', 6, AF14)>;
bias-disable;
drive-push-pull;
slew-rate = <1>;
};
};
ltdc_pins_sleep_b: ltdc-b-1 {
pins {
pinmux = <STM32_PINMUX('I', 14, ANALOG)>,
<STM32_PINMUX('I', 12, ANALOG)>,
<STM32_PINMUX('I', 13, ANALOG)>,
<STM32_PINMUX('K', 7, ANALOG)>,
<STM32_PINMUX('I', 15, ANALOG)>,
<STM32_PINMUX('J', 0, ANALOG)>,
<STM32_PINMUX('J', 1, ANALOG)>,
<STM32_PINMUX('J', 2, ANALOG)>,
<STM32_PINMUX('J', 3, ANALOG)>,
<STM32_PINMUX('J', 4, ANALOG)>,
<STM32_PINMUX('J', 5, ANALOG)>,
<STM32_PINMUX('J', 6, ANALOG)>,
<STM32_PINMUX('J', 7, ANALOG)>,
<STM32_PINMUX('J', 8, ANALOG)>,
<STM32_PINMUX('J', 9, ANALOG)>,
<STM32_PINMUX('J', 10, ANALOG)>,
<STM32_PINMUX('J', 11, ANALOG)>,
<STM32_PINMUX('K', 0, ANALOG)>,
<STM32_PINMUX('K', 1, ANALOG)>,
<STM32_PINMUX('K', 2, ANALOG)>,
<STM32_PINMUX('J', 12, ANALOG)>,
<STM32_PINMUX('J', 13, ANALOG)>,
<STM32_PINMUX('J', 14, ANALOG)>,
<STM32_PINMUX('J', 15, ANALOG)>,
<STM32_PINMUX('K', 3, ANALOG)>,
<STM32_PINMUX('K', 4, ANALOG)>,
<STM32_PINMUX('K', 5, ANALOG)>,
<STM32_PINMUX('K', 6, ANALOG)>;
};
};
- SiI9022裝置樹節點
參考文檔:
Documentation/devicetree/bindings/display/arm,hdlcd.txt
由于SiI9002隻是I2C5總線上的一個外設,是以STM32MP157A的通用裝置樹檔案中并沒有相關的定義,結合arm,hdlcd.txt和stm32mp15xx-dkx.dtsi對于HDMI的描述,增加SiI9002的支援,需在I2C5節點下添加相關資訊,添加内容為:
[email protected] {
compatible = "sil,sii9022";
reg = <0x39>;
iovcc-supply = <&v3v3_hdmi>;
cvcc12-supply = <&v1v2_hdmi>;
reset-gpios = <&gpioa 10 GPIO_ACTIVE_LOW>;
interrupts = <1 IRQ_TYPE_EDGE_FALLING>;
interrupt-parent = <&gpiog>;
#sound-dai-cells = <0>;
status = "okay";
ports {
#address-cells = <1>;
#size-cells = <0>;
[email protected] {
reg = <0>;
sii9022_in: endpoint {
remote-endpoint = <<dc_ep0_out>;
};
};
[email protected] {
reg = <3>;
sii9022_tx_endpoint: endpoint {
remote-endpoint = <&i2s2_endpoint>;
};
};
};
};
- 電源節點添加
由于核心中很多驅動會根據電源的方位調整裝置的工作方式,是以在裝置樹中需要傳遞相關電源電壓參數,如sii9022驅動中需要兩個電源分别是iovcc和cvcc12,但是在裝置樹中并沒有這兩個電源的定義,官方參考闆DK1使用的是MPU作為電源管理,而FS-MP1A使用的分離元器件的形式,是以stm32mp15xx-dkx.dtsi中對于電源的定義就不實用了。參考核心中相關文檔添加強定電源節點的形式添加iovcc和cvcc12即可,根據sii9022的需求,iovcc和cvcc12電壓分别為3.3v和1.2v。
參考文檔
Documentation/devicetree/bindings/regulator/fixed-regulator.yaml
需在裝置樹根節點下添加,内容如下:
v3v3_hdmi: regulator-v3v3-hdmi {
compatible = "regulator-fixed";
regulator-name = "v3v3_hdmi ";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-always-on;
regulator-boot-on;
};
v1v2_hdmi: regulator-v1v2-hdmi {
compatible = "regulator-fixed";
regulator-name = "v1v2_hdmi";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <1200000>;
regulator-always-on;
regulator-boot-on;
};
1.2實驗目的
熟悉基于Linux作業系統下的HDMI裝置驅動移植配置過程。
1.3實驗平台
華清遠見開發環境,FS-MP1A平台;
1.4實驗步驟
- 導入交叉編譯工具鍊
[email protected]:$ source /opt/st/stm32mp1/3.1-openstlinux-5.4-dunfell-mp1-20-06-24/environment-setup-cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi
- 添加i2c5及sii9022内容
修改arch/arm/boot/dts/stm32mp15xx-fsmp1x.dtsi檔案,在檔案末尾添加如下内容:
&i2c5 {
pinctrl-names = "default", "sleep";
pinctrl-0 = <&i2c5_pins_a>;
pinctrl-1 = <&i2c5_pins_sleep_a>;
i2c-scl-rising-time-ns = <100>;
i2c-scl-falling-time-ns = <7>;
clock-frequency = <100000>;
/delete-property/dmas;
/delete-property/dma-names;
status = "okay";
[email protected] {
compatible = "sil,sii9022";
reg = <0x39>;
iovcc-supply = <&v3v3_hdmi>;
cvcc12-supply = <&v1v2_hdmi>;
reset-gpios = <&gpioa 13 GPIO_ACTIVE_LOW>;
interrupts = <14 IRQ_TYPE_EDGE_FALLING>;
interrupt-parent = <&gpioa>;
#sound-dai-cells = <0>;
status = "okay";
ports {
#address-cells = <1>;
#size-cells = <0>;
[email protected] {
reg = <0>;
sii9022_in: endpoint {
remote-endpoint = <<dc_ep0_out>;
};
};
};
};
};
- 添加ltdc内容
修改arch/arm/boot/dts/stm32mp15xx-fsmp1x.dtsi檔案,在檔案末尾添加如下内容:
<dc {
pinctrl-names = "default", "sleep";
pinctrl-0 = <<dc_pins_b>;
pinctrl-1 = <<dc_pins_sleep_b>;
status = "okay";
port {
#address-cells = <1>;
#size-cells = <0>;
ltdc_ep0_out: [email protected] {
reg = <0>;
remote-endpoint = <&sii9022_in>;
};
};
};
- 添加電源内容
修改arch/arm/boot/dts/stm32mp15xx-fsmp1x.dtsi檔案,在根節點末尾添加如下内容:
v3v3_hdmi: regulator-v3v3-hdmi {
compatible = "regulator-fixed";
regulator-name = "v3v3_hdmi ";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-always-on;
regulator-boot-on;
};
v1v2_hdmi: regulator-v1v2-hdmi {
compatible = "regulator-fixed";
regulator-name = "v1v2_hdmi";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <1200000>;
regulator-always-on;
regulator-boot-on;
};
- 配置核心
由于核心源碼預設配置以及支援sii902x,本節列出主要選項,如下:
[email protected]:$ make menuconfig
Device Drivers --->
Graphics support --->
<*> Direct Rendering Manager (XFree86 4.1.0 and higher DRI support) --->
<*> DRM Support for STMicroelectronics SoC Series
Display Interface Bridges --->
<*> Silicon Image sii902x RGB/HDMI bridge
- 編譯核心及裝置樹:
[email protected]:$ make -j4 uImage dtbs LOADADDR=0xC2000040
- 重新開機測試
将編譯好的裝置樹和核心鏡像拷貝到/tftpboot目錄下,通過tftp引導核心,裝置連接配接HDMI顯示器,重新開機裝置後檢視/sys/class/drm會多出HMID的資訊,同時顯示器會有顯示。
硬體平台:華清遠見FS-MP1A開發闆(STM32MP157)
部分開發教程下載下傳:加QQ群459754978,群檔案裡有。
部分視訊課程收看:華清遠見研發中心的個人空間_哔哩哔哩_Bilibili
淘寶購買連結:https://item.taobao.com/item.htm?id=622457259672
手機淘寶分享碼:複制本行文字打開手淘₤T4FPXn3YYJ2₤