你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32MP157 Linux系统移植开发篇11:Linux HDMI驱动移植

[复制链接]
STMCU小助手 发布时间:2022-9-30 18:21
1.1实验原理
STM32MP157A系列SoC中默认没有HDMI相关控制器,FS-MP1A使用SiI9022芯片将RGB信号转化为HDMI信号。STM32MP157A集成LTDC(LCD-TFT Display Controller),提供一个24bit RGB并行接口用于连接到各种LCD和TFT面板。

02d9316f76a34cd178e25aa474ce656d.jpg

SiI9022芯片通过I2C5总线与SoC进行交互,通过SoC的LCD_PCLK、LCD_VSYNC、LCD_HSYNC、LCD_DEN与RGB信号线来进行图像信号的传输,通过I2S2总线进行音频数据的传输。

492cf05ff35f9ac585e83f662e3d341e.jpg

查看原理图确认I2C5、中断、复位管脚对应关系:

23ecead22df12eae021f288293a3cbcd.png
AB@J9H(`TDHNY_0M_GXV6V4.png

LCD接口管脚对应关系:

4f0fbf246eda08c7552f6ac2b28d9ead.jpg

)J%_MWL`DI}%MK777U0HILM.png
(()KU8K1IZ)EYBXCC}{N~@7.png
(SVFSWYF52R2()`JM5)WP@9.png

1.I2C5设备树节点

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

arch/arm/boot/dts/stm32mp151.dtsi

stm32mp151中i2c5定义如下:

  1. i2c5: i2c@40015000 {

  2. compatible = "st,stm32mp15-i2c";

  3. reg = <0x40015000 0x400>;

  4. interrupt-names = "event", "error";

  5. interrupts-extended = <&exti 25 IRQ_TYPE_LEVEL_HIGH>,

  6. <&intc GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;

  7. clocks = <&rcc I2C5_K>;

  8. resets = <&rcc I2C5_R>;

  9. #address-cells = <1>;

  10. #size-cells = <0>;

  11. dmas = <&dmamux1 115 0x400 0x80000001>,

  12. <&dmamux1 116 0x400 0x80000001>;

  13. dma-names = "rx", "tx";

  14. power-domains = <&pd_core>;

  15. st,syscfg-fmp = <&syscfg 0x4 0x10>;

  16. wakeup-source;

  17. status = "disabled";

  18. };
复制代码


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

参考stm32mp15xx-dkx.dtsi对于i2c设备节点的描述,修改i2c5内容如下:

  1. &i2c5 {

  2. pinctrl-names = "default", "sleep";

  3. pinctrl-0 = <&i2c5_pins_a>;

  4. pinctrl-1 = <&i2c5_pins_sleep_a>;

  5. i2c-scl-rising-time-ns = <100>;

  6. i2c-scl-falling-time-ns = <7>;

  7. clock-frequency = <100000>;

  8. /* spare dmas for other usage */

  9. /delete-property/dmas;

  10. /delete-property/dma-names;

  11. status = "okay";

  12. };
复制代码

由于stm32mp15-pinctrl.dtsi中对于i2c5_pins_a和i2c5_pins_sleep_a的定义与板子实际使用管脚一致,所以无需修改,内容如下:

  1. i2c5_pins_a: i2c5-0 {

  2. pins {

  3. pinmux = <STM32_PINMUX('A', 11, AF4)>, /* I2C5_SCL */

  4. <STM32_PINMUX('A', 12, AF4)>; /* I2C5_SDA */

  5. bias-disable;

  6. drive-open-drain;

  7. slew-rate = <0>;

  8. };

  9. };

  10. i2c5_pins_sleep_a: i2c5-1 {

  11. pins {

  12. pinmux = <STM32_PINMUX('A', 11, ANALOG)>, /* I2C5_SCL */

  13. <STM32_PINMUX('A', 12, ANALOG)>; /* I2C5_SDA */

  14. };

  15. };
复制代码

2.I2S2设备树节点

3.LTDC设备树节点
SiI9022实现HDMI输出需要RGB信号作为数据源,LTDC为STM32MP157的LCD显示控制器,可以输出24bit的并行数据,HDMI显示首先需要驱动LTDC。

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

arch/arm/boot/dts/stm32mp151.dtsi

stm32mp151中ltdc定义如下:

  1. ltdc: display-controller@5a001000 {

  2. compatible = "st,stm32-ltdc";

  3. reg = <0x5a001000 0x400>;

  4. interrupts = <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>,

  5. <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;

  6. clocks = <&rcc LTDC_PX>;

  7. clock-names = "lcd";

  8. resets = <&rcc LTDC_R>;

  9. status = "disabled";

  10. };
复制代码

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

参考stm32mp15xx-dkx.dtsi对于ltdc设备节点的描述,需增加内容如下:

  1. <dc {

  2. pinctrl-names = "default", "sleep";

  3. pinctrl-0 = <<dc_pins_b>;

  4. pinctrl-1 = <<dc_pins_sleep_b>;

  5. status = "okay";

  6. port {

  7. #address-cells = <1>;

  8. #size-cells = <0>;

  9. ltdc_ep0_out: endpoint@0 {

  10. reg = <0>;

  11. /*图像输出通道,需对接显示设备*/

  12. remote-endpoint = <&sii9022_in>;

  13. };

  14. };

  15. };
复制代码

由于stm32mp15-pinctrl.dtsi中对于ltdc_pins_b和ltdc_pins_b的定于与板子实际使用管脚一致,所以无需修改,内容如下:

  1. ltdc_pins_b: ltdc-b-0 {

  2. pins {

  3. pinmux = <STM32_PINMUX('I', 14, AF14)>, /* LCD_CLK */

  4. <STM32_PINMUX('I', 12, AF14)>, /* LCD_HSYNC */

  5. <STM32_PINMUX('I', 13, AF14)>, /* LCD_VSYNC */

  6. <STM32_PINMUX('K', 7, AF14)>, /* LCD_DE */

  7. <STM32_PINMUX('I', 15, AF14)>, /* LCD_R0 */

  8. <STM32_PINMUX('J', 0, AF14)>, /* LCD_R1 */

  9. <STM32_PINMUX('J', 1, AF14)>, /* LCD_R2 */

  10. <STM32_PINMUX('J', 2, AF14)>, /* LCD_R3 */

  11. <STM32_PINMUX('J', 3, AF14)>, /* LCD_R4 */

  12. <STM32_PINMUX('J', 4, AF14)>, /* LCD_R5 */

  13. <STM32_PINMUX('J', 5, AF14)>, /* LCD_R6 */

  14. <STM32_PINMUX('J', 6, AF14)>, /* LCD_R7 */

  15. <STM32_PINMUX('J', 7, AF14)>, /* LCD_G0 */

  16. <STM32_PINMUX('J', 8, AF14)>, /* LCD_G1 */

  17. <STM32_PINMUX('J', 9, AF14)>, /* LCD_G2 */

  18. <STM32_PINMUX('J', 10, AF14)>, /* LCD_G3 */

  19. <STM32_PINMUX('J', 11, AF14)>, /* LCD_G4 */

  20. <STM32_PINMUX('K', 0, AF14)>, /* LCD_G5 */

  21. <STM32_PINMUX('K', 1, AF14)>, /* LCD_G6 */

  22. <STM32_PINMUX('K', 2, AF14)>, /* LCD_G7 */

  23. <STM32_PINMUX('J', 12, AF14)>, /* LCD_B0 */

  24. <STM32_PINMUX('J', 13, AF14)>, /* LCD_B1 */

  25. <STM32_PINMUX('J', 14, AF14)>, /* LCD_B2 */

  26. <STM32_PINMUX('J', 15, AF14)>, /* LCD_B3 */

  27. <STM32_PINMUX('K', 3, AF14)>, /* LCD_B4 */

  28. <STM32_PINMUX('K', 4, AF14)>, /* LCD_B5 */

  29. <STM32_PINMUX('K', 5, AF14)>, /* LCD_B6 */

  30. <STM32_PINMUX('K', 6, AF14)>; /* LCD_B7 */

  31. bias-disable;

  32. drive-push-pull;

  33. slew-rate = <1>;

  34. };

  35. };

  36. ltdc_pins_sleep_b: ltdc-b-1 {

  37. pins {

  38. pinmux = <STM32_PINMUX('I', 14, ANALOG)>, /* LCD_CLK */

  39. <STM32_PINMUX('I', 12, ANALOG)>, /* LCD_HSYNC */

  40. <STM32_PINMUX('I', 13, ANALOG)>, /* LCD_VSYNC */

  41. <STM32_PINMUX('K', 7, ANALOG)>, /* LCD_DE */

  42. <STM32_PINMUX('I', 15, ANALOG)>, /* LCD_R0 */

  43. <STM32_PINMUX('J', 0, ANALOG)>, /* LCD_R1 */

  44. <STM32_PINMUX('J', 1, ANALOG)>, /* LCD_R2 */

  45. <STM32_PINMUX('J', 2, ANALOG)>, /* LCD_R3 */

  46. <STM32_PINMUX('J', 3, ANALOG)>, /* LCD_R4 */

  47. <STM32_PINMUX('J', 4, ANALOG)>, /* LCD_R5 */

  48. <STM32_PINMUX('J', 5, ANALOG)>, /* LCD_R6 */

  49. <STM32_PINMUX('J', 6, ANALOG)>, /* LCD_R7 */

  50. <STM32_PINMUX('J', 7, ANALOG)>, /* LCD_G0 */

  51. <STM32_PINMUX('J', 8, ANALOG)>, /* LCD_G1 */

  52. <STM32_PINMUX('J', 9, ANALOG)>, /* LCD_G2 */

  53. <STM32_PINMUX('J', 10, ANALOG)>, /* LCD_G3 */

  54. <STM32_PINMUX('J', 11, ANALOG)>, /* LCD_G4 */

  55. <STM32_PINMUX('K', 0, ANALOG)>, /* LCD_G5 */

  56. <STM32_PINMUX('K', 1, ANALOG)>, /* LCD_G6 */

  57. <STM32_PINMUX('K', 2, ANALOG)>, /* LCD_G7 */

  58. <STM32_PINMUX('J', 12, ANALOG)>, /* LCD_B0 */

  59. <STM32_PINMUX('J', 13, ANALOG)>, /* LCD_B1 */

  60. <STM32_PINMUX('J', 14, ANALOG)>, /* LCD_B2 */

  61. <STM32_PINMUX('J', 15, ANALOG)>, /* LCD_B3 */

  62. <STM32_PINMUX('K', 3, ANALOG)>, /* LCD_B4 */

  63. <STM32_PINMUX('K', 4, ANALOG)>, /* LCD_B5 */

  64. <STM32_PINMUX('K', 5, ANALOG)>, /* LCD_B6 */

  65. <STM32_PINMUX('K', 6, ANALOG)>; /* LCD_B7 */

  66. };

  67. };
复制代码

3.SiI9022设备树节点
由于SiI9002只是I2C5总线上的一个外设,所以STM32MP157A的通用设备树文件中并没有相关的定义,结合arm,hdlcd.txt和stm32mp15xx-dkx.dtsi对于HDMI的描述,增加SiI9002的支持,需在I2C5节点下添加相关信息,添加内容为:

  1. hdmi-transmitter@39 {

  2. compatible = "sil,sii9022";

  3. reg = <0x39>;

  4. iovcc-supply = <&v3v3_hdmi>;

  5. cvcc12-supply = <&v1v2_hdmi>;

  6. reset-gpios = <&gpioa 10 GPIO_ACTIVE_LOW>;

  7. interrupts = <1 IRQ_TYPE_EDGE_FALLING>;

  8. interrupt-parent = <&gpiog>;

  9. #sound-dai-cells = <0>;

  10. status = "okay";

  11. ports {

  12. #address-cells = <1>;

  13. #size-cells = <0>;

  14. port@0 {

  15. reg = <0>;

  16. sii9022_in: endpoint {

  17. /*视频输入端口,与LTDC输出端口对接*/

  18. remote-endpoint = <<dc_ep0_out>;

  19. };

  20. };

  21. port@3 {

  22. reg = <3>;

  23. sii9022_tx_endpoint: endpoint {

  24. /*音频输入端口,与声卡输出端口对接*/

  25. remote-endpoint = <&i2s2_endpoint>;

  26. };

  27. };

  28. };

  29. };
复制代码

4.电源节点添加
由于内核中很多驱动会根据电源的方位调整设备的工作方式,所以在设备树中需要传递相关电源电压参数,如sii9022驱动中需要两个电源分别是iovcc和cvcc12,但是在设备树中并没有这两个电源的定义,官方参考板DK1使用的是MPU作为电源管理,而FS-MP1A使用的分离元器件的形式,所以stm32mp15xx-dkx.dtsi中对于电源的定义就不实用了。参考内核中相关文档添加固定电源节点的形式添加iovcc和cvcc12即可,根据sii9022的需求,iovcc和cvcc12电压分别为3.3v和1.2v。

需在设备树根节点下添加,内容如下:

  1. v3v3_hdmi: regulator-v3v3-hdmi {

  2. compatible = "regulator-fixed";

  3. regulator-name = "v3v3_hdmi ";

  4. regulator-min-microvolt = <3300000>;

  5. regulator-max-microvolt = <3300000>;

  6. regulator-always-on;

  7. regulator-boot-on;

  8. };

  9. v1v2_hdmi: regulator-v1v2-hdmi {

  10. compatible = "regulator-fixed";

  11. regulator-name = "v1v2_hdmi";

  12. regulator-min-microvolt = <1200000>;

  13. regulator-max-microvolt = <1200000>;

  14. regulator-always-on;

  15. regulator-boot-on;

  16. };
复制代码

1.2实验目的
熟悉基于Linux操作系统下的HDMI设备驱动移植配置过程。

1.3实验平台

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

1.4实验步骤
1.导入交叉编译工具链
linux@ubuntu source /opt/st/stm32mp1/3.1-openstlinux-5.4-dunfell-mp1-20-06-24/environment-setup-cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi

2.添加i2c5及sii9022内容
修改arch/arm/boot/dts/stm32mp15xx-fsmp1x.dtsi文件,在文件末尾添加如下内容:

  1. &i2c5 {

  2. pinctrl-names = "default", "sleep";

  3. pinctrl-0 = <&i2c5_pins_a>;

  4. pinctrl-1 = <&i2c5_pins_sleep_a>;

  5. i2c-scl-rising-time-ns = <100>;

  6. i2c-scl-falling-time-ns = <7>;

  7. clock-frequency = <100000>;

  8. /* spare dmas for other usage */

  9. /delete-property/dmas;

  10. /delete-property/dma-names;

  11. status = "okay";

  12. hdmi-transmitter@39 {

  13. compatible = "sil,sii9022";

  14. reg = <0x39>;

  15. iovcc-supply = <&v3v3_hdmi>;

  16. cvcc12-supply = <&v1v2_hdmi>;

  17. reset-gpios = <&gpioa 13 GPIO_ACTIVE_LOW>;

  18. interrupts = <14 IRQ_TYPE_EDGE_FALLING>;

  19. interrupt-parent = <&gpioa>;

  20. #sound-dai-cells = <0>;

  21. status = "okay";

  22. ports {

  23. #address-cells = <1>;

  24. #size-cells = <0>;

  25. port@0 {

  26. reg = <0>;

  27. sii9022_in: endpoint {

  28. remote-endpoint = <<dc_ep0_out>;

  29. };

  30. };

  31. };

  32. };

  33. };
复制代码

3.添加ltdc内容
修改arch/arm/boot/dts/stm32mp15xx-fsmp1x.dtsi文件,在文件末尾添加如下内容:

  1. <dc {

  2. pinctrl-names = "default", "sleep";

  3. pinctrl-0 = <<dc_pins_b>;

  4. pinctrl-1 = <<dc_pins_sleep_b>;

  5. status = "okay";

  6. port {

  7. #address-cells = <1>;

  8. #size-cells = <0>;

  9. ltdc_ep0_out: endpoint@0 {

  10. reg = <0>;

  11. remote-endpoint = <&sii9022_in>;

  12. };

  13. };

  14. };
复制代码

4.添加电源内容
修改arch/arm/boot/dts/stm32mp15xx-fsmp1x.dtsi文件,在根节点末尾添加如下内容:

  1. v3v3_hdmi: regulator-v3v3-hdmi {

  2. compatible = "regulator-fixed";

  3. regulator-name = "v3v3_hdmi ";

  4. regulator-min-microvolt = <3300000>;

  5. regulator-max-microvolt = <3300000>;

  6. regulator-always-on;

  7. regulator-boot-on;

  8. };

  9. v1v2_hdmi: regulator-v1v2-hdmi {

  10. compatible = "regulator-fixed";

  11. regulator-name = "v1v2_hdmi";

  12. regulator-min-microvolt = <1200000>;

  13. regulator-max-microvolt = <1200000>;

  14. regulator-always-on;

  15. regulator-boot-on;

  16. };
复制代码

5.配置内核
由于内核源码默认配置以及支持sii902x,本节列出主要选项,如下:

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

Display Interface Bridges --->

<*> Silicon Image sii902x RGB/HDMI bridge

6.编译内核及设备树:
linux@ubuntu make -j4 uImage dtbs LOADADDR=0xC2000040

7.重启测试
将编译好的设备树和内核镜像拷贝到/tftpboot目录下,通过tftp引导内核,设备连接HDMI显示器,重启设备后查看/sys/class/drm会多出HMID的信息,同时显示器会有显示。

dd22fa5d77f91f20f9f9d2db3c47cfb5.png

————————————————
版权声明:华清远见IT开放实验室


收藏 评论0 发布时间:2022-9-30 18:21

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版