1.实验原理4 o5 T; \7 z ]8 C8 i& `) e 前文介绍过LTDC的内容,本节只需为LTDC添加一个面板即可。内核中包含一个通用的面板驱动,驱动之包含大量各种各样的面板。4 V4 s* w4 _" \" V , e c/ T2 u# d9 r- ? 1.驱动修改5 O, n( T* K4 A6 u/ ~% `: Q4 `, K 驱动路径为:drivers/gpu/drm/panel/panel-simple.c+ l$ m7 J1 W' g' [) Z 移植时可以在驱动中支持新的面板的内容,也可以找到一个与自己面板相仿的内容进行修改,本节即使用在原有面板修改的方法。如本节参考面板名称为zj070na-01p,对于一个面板最关键的内容在驱动通过drm_display_mode的结构体描述,zj070na-01p的描述如下: ( g* X- V, l8 O! @3 q2 g
这个结构体主要用来描述面板的时序相关信息,时序框图如下: 6 R0 Z6 A( D/ x, n! J( L' M hdisplay:有效显示区水平像素数量,对应Active Width hsync_start:水平同步开始,对应hdispay + HFP: ~- W$ Q r8 m2 }" e hsync_end:水平同步结束,对应hdisplay + HFP + HSYNC width(HPW) ) H9 x/ M9 f9 @8 ~% }; D0 M htotal:水平总像素,对应hdisplay + HFP + HSYNC width + HBP vdisplay:垂直显示像素,对应Active Height! K" M, [# i# C$ c vsync_start:垂直同步开始,对应vdispay + VFP vsync_end:垂直像素结束,对应vdisplay + VFP + VSYNC width(VPW) vtotal:垂直总像素,对应vdisplay + VFP + VSYNC width + VBP ( a& i6 s$ `/ k% o3 m vrefresh:刷新率& E7 j! O _5 R: Y+ E' h0 a# N 面板芯片手册中关于时序的描述如下:+ z0 ?. _7 B! S: x( l % O3 Q! V" T$ b% }: X( G. C( L 表中可以确认HBP=140、HPW=20、HFP=160、VBP=20、VPW=3、VFP=12,修改面板信息如下: static const struct drm_display_mode innolux_zj070na_01p_mode = {6 h; j: K! O) \! z n1 f- ? 2 t$ ?+ v( U: `. Z, k .clock = 51501,9 D; ]9 y7 m3 c8 l1 r. m: g .hdisplay = 1024,& s9 Z6 T% q; E, G6 s U$ g 0 v+ R0 P% S# D .hsync_start = 1024 + 160,, T" b( p ]: j3 m/ P0 i2 C .hsync_end = 1024 + 160 + 20, . ]$ C: X4 A9 v5 |. K I6 o .htotal = 1024 + 160 + 20 + 140,$ e- L( \4 G- F6 E3 T " U/ p' P& U+ q- U6 {& b5 v .vdisplay = 600, & \( s* z& ?# ?0 q- P' \) C8 {% j0 i .vsync_start = 600 + 12,# a# O& n! c* w7 M, M1 ^ .vsync_end = 600 + 12 + 3,/ [; ]% d+ g7 `; u2 v ; {7 D3 [* M' r- S. P. P .vtotal = 600 + 12 + 3 + 12, .vrefresh = 60,, z; z0 k3 r/ ?5 o3 K! w9 V/ _. P2 O % \7 i* y( ~; U- [# M- b2 t% g }; 2.设备树修改' Z1 k2 Y, H# q5 N 增加ltdc输出端口: <dc {+ s( v Z$ f) l [2 g8 m 2 s* b% @) v/ u) Q5 ` status = "okay";* l" M* E& ^- Z7 i' B# x port { ) t8 y( B. z/ W$ u9 ^! ^8 D" o #address-cells = <1>;7 x: @2 @+ v- W6 x' i6 x+ r #size-cells = <0>;. ~8 H$ i1 L& } ltdc_ep1_out: endpoint@1 { reg = <1>;2 E9 t6 q" a# `- \ remote-endpoint = <&panel_in_rgb>; }; }; };+ h: W- u: ^) N" w6 d; ~. p% v 3.增加面板节点:# b) f, l) d& Y* a) C + k; @9 Z$ K1 E* {! F. V panel: panel-rgb { - E8 D: l- a0 O! }& ]9 l compatible = "innolux,zj070na-01p"; f$ V. G$ e1 C8 ~( W . M/ j, r0 ]0 |( b pinctrl-names = "default", "sleep";& I& W, G- d. R* ]4 ~ backlight = <&panel_backlight>;" |; L3 _5 Y; M! I; X$ R status = "okay"; 3 q+ z3 F' k0 J }- i% t v port { ! Y9 l3 X8 T( F# F+ S panel_in_rgb: endpoint { remote-endpoint = <<dc_ep1_out>; + |- T0 S* e1 W, V6 v. n }; }; u; x1 ]$ F# P( w }; . g6 n6 p$ W% I 4.PWM设备节点0 |) V7 K0 z" D$ F. N 内核中ST对STM32MP15x系列芯片的设备树资源了做了定义,可参见: arch/arm/boot/dts/stm32mp151.dtsi / [" P: M! A# Q! F' @8 s) p& y stm32mp151中timers2定义如下:; w+ A5 U2 |6 j& q1 G, y; | timers2: timer@40000000 { #address-cells = <1>; #size-cells = <0>;& u* n3 I+ g6 H( O% O , a1 ^% |5 A7 f ]4 P) B0 t compatible = "st,stm32-timers";* P @9 r2 U y- _4 @! ] reg = <0x40000000 0x400>; clocks = <&rcc TIM2_K>; 7 p0 e! g: F: [' r6 h5 h2 ]- p# r. x clock-names = "int"; 0 B1 Q6 p# \# d" h( y; Y, m! ~) E' M& { dmas = <&dmamux1 18 0x400 0x80000001>, . N. N* x3 e. [9 g2 L8 p1 g <&dmamux1 19 0x400 0x80000001>,2 u! F9 w1 B+ j: r' n: O ' Z" ^+ j5 o+ l: E' K: o <&dmamux1 20 0x400 0x80000001>, * w' M& ~5 |& h7 g% n0 I9 X S% A <&dmamux1 21 0x400 0x80000001>, - a( n" _9 M8 A <&dmamux1 22 0x400 0x80000001>; dma-names = "ch1", "ch2", "ch3", "ch4", "up"; ) H# h3 V" K& M1 f$ F, U status = "disabled"; pwm {) J& D4 E2 q# _; i: t . G& I9 a0 g; z" E- S9 L9 p compatible = "st,stm32-pwm"; ! f2 _5 k' o8 c5 v6 w #pwm-cells = <3>;- @* a4 E' q7 A, x. \* f0 B status = "disabled";9 n7 m- e3 h. T: ^: Q , [1 i# n4 i& N };% A$ s1 G! b! L- y+ y! v9 C. E5 v9 m timer@1 { compatible = "st,stm32h7-timer-trigger";% i$ V5 D4 N- g1 M* J8 Q3 S 2 H' Z2 _7 i& S3 D reg = <1>;. J6 w+ K7 [2 H/ r. Z + P) ^, _3 f+ X6 p' Y# ~( Z* _ status = "disabled";* ~& h; V; P% e* M3 u2 t };$ b/ i7 L% d/ o @# V# B counter { 7 l, A1 V8 c y2 K compatible = "st,stm32-timer-counter"; 2 D8 A6 g- X+ d ^% D, ? status = "disabled";' k0 T1 k' X; w% V% K $ o- ~0 l/ y1 e- J };, \4 t2 W/ ^, R4 p! q };. w7 N1 {9 e# c- p) j% k* g 上述代码只对timers5做了基本的初始化,并没有针对不同的硬件设计做适配,所以需结合硬件补全设备树节点信息。- v Q% |; v: f0 q" g& S- k * R4 _; V: D. [0 D& { 参考文档或stm32mp15xx-dkx.dtsi对于i2c设备节点的描述,增加timers内容如下:+ n) J5 ~7 T5 B; h6 \. ~' Q u0 [ 2 k: @& Y f2 @6 `1 C( @ &timers2 { /* spare dmas for other usage */0 f" x, ~0 V! J " ^! N! I3 U- P" K /delete-property/dmas;' \1 f1 c2 H% c " \+ Q s( A1 j/ n /delete-property/dma-names; $ m: E" Z% s5 b' [3 J/ x. N% D% X status = "okay";9 S6 t- x! k1 u; J8 i: R3 E4 `# @4 \ pwm2: pwm { pinctrl-0 = <&pwm2_pins_b>; pinctrl-1 = <&pwm2_sleep_pins_b>;# A7 p: U; q$ i# x& g% M- _ pinctrl-names = "default", "sleep";8 R6 F: Y9 l! j! f #pwm-cells = <2>;$ Y2 a2 s: T8 r% s- I' u 0 U+ O& m; T+ a \0 O4 e R! p k status = "okay"; };- v+ d% [. W/ l timer@2 {! [/ ]& x+ v7 o2 b0 ~) h status = "disabled";* l! g) o, i0 w# ^. C' n& f }5 w }; }; stm32mp15-pinctrl.dtsi对于pwm2的描述与FS-MP1A所使用管脚不一致,所以无法直接使用,需参考其增加如下内容: $ S. {3 x; s1 I4 B! _/ X4 @ pwm2_pins_b: pwm2-0 { pins {0 \9 I* j8 Y: v) S3 | . B5 H: w( P$ Z2 N6 z. ` pinmux = <STM32_PINMUX('A', 5, AF1)>; /* TIM2_CH1 */ & i$ x, }2 Q) ]6 M- l: v5 m bias-pull-down; drive-push-pull; I- ~( j; X9 Y2 a3 D slew-rate = <0>;) y6 `7 y! w0 [/ X# Z3 e0 ~ % G1 I. \& X3 C; V };$ X( t7 H! n2 v# P ! {4 }$ W" k$ m0 W };% |6 I' j7 Z4 v1 c ( k1 V. I+ y0 K7 H% p pwm2_sleep_pins_b: pwm1-sleep-0 {, C7 ? J5 {- |6 M0 o. N0 O 1 u/ i6 u8 _# n3 ?- U. U" ~ pins {$ F+ C$ G( M8 R! A# W/ I$ m pinmux = <STM32_PINMUX('A', 5, ANALOG)>; /* TIM2_CH1 */0 m) y: l& h/ n$ }9 o; `6 q4 p& V' d ( ~! l* P: ^, g0 ^ }; / p6 J* o, |% [2 `* P4 D }; 1 k6 n4 N( ], V$ U' R. J 5.背光设备节点% a) v5 m0 H3 X6 P% Z5 [) D4 D) t + b B; k) T$ I2 v, @" Q/ d FS-MP1A背光可以通过GPIO驱动也可通过PWM2的通道1驱动,可以对比参考文档或内核中其他设备树关于背光的定义。 GPIO驱动背光节点内容如下: & B9 ~$ [, u& h. I' [6 b panel_backlight: panel-backlight { compatible = "gpio-backlight"; gpios = <&gpiod 13 GPIO_ACTIVE_LOW>;2 m& E8 i3 \# |6 L6 F& _# A, @( S1 r 1 K" S6 |% C' E" q default-on; status = "okay"; ; }% k6 N; ]( @9 b9 h };( q% t; d' L3 n" a+ n PWM驱动背光节点内容如下: panel_backlight: panel-backlight {$ j( ^/ k; q' q; N4 }0 } + Z2 z( ~( M: r S$ \' @ compatible = "pwm-backlight";1 ]- N q# ]3 L* l: G6 u # L6 ~( l: l2 }. {- S7 P* u2 q pwms = <&pwm2 0 5000000>; ) Z, m' H4 G$ t% V brightness-levels = <0 4 8 16 32 64 128 255>; & c% x) C2 v4 d6 ~4 Q4 r default-brightness-level = <6>;% s/ G6 I1 T: p0 h! B/ F status = "okay";$ y& u4 ^& X3 `! R/ o 7 d& p( X0 l4 N7 A* B };* G; c* l1 s! F 0 l9 n& v% d7 t' Y' Q& s% U 2.实验目的 熟悉基于Linux操作系统下的摄像头设备驱动移植配置过程。5 E2 W5 D* Z. _4 p% B2 z : _; ?9 C" \2 e! S4 `2 ]. J 3.实验平台 华清远见开发环境,FS-MP1A平台; 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-gnueabi5 I T% V% R/ [* |$ |( O & v6 F2 A$ {. _' J6 O 2.增加设备树文件 由于RGB LCD并非FS-MP1A必须配置,本节增加一个设备树文件,对应增加了屏幕的设备。, T/ h4 k; V& z7 `( k& C6 t& I 在内核的arch/arm/boot/dts目录下新建文件stm32mp157a-fsmp1a-rgb070.dts文件并添加如下内容: #include "stm32mp157a-fsmp1a.dts"7 a/ w b, o- m8 A% j / { model = "HQYJ STM32MP157 FSMP1A RGB Discovery Board";! z0 D( X6 |( n) M( ^ compatible = "st,stm32mp157a-dk1", "st,stm32mp157";, b l% u* K _ };' N3 i3 w: p9 j% x% z + p' S% Y. E2 S- X1 h1 F: S6 R7 Y 由于增加了新的设备树文件需修改arch/arm/boot/dts/Makefile,在文件中增加新的条目,红色字体部分为增加内容) h% Q/ P L# }* {) w 0 ~' V- T; y) u5 n dtb-$(CONFIG_ARCH_STM32) += \ …..# o8 K& e2 ]- {2 V) w+ ~ 3 z0 {1 ^5 z0 X/ z$ D, }8 ] stm32mp157a-dk1.dtb \% h3 S/ z! H% f1 f. b( E. x7 z R stm32mp157a-fsmp1a.dtb \ C# {! \; z, z stm32mp157a-fsmp1a-mipi050.dtb \) ]: f7 i- @( [: X4 u 4 H& X5 B. Q; K/ e1 X stm32mp157a-fsmp1a-rgb070.dtb \1 r( b _8 S/ d) |9 @0 u Z stm32mp157d-dk1.dtb \ 添加pwm2内容5 s4 E3 B) z2 o# b 修改stm32mp15xx-fsmp1x.dtsi,在stm32mp15xx-fsmp1x.dtsi文件末尾添加如下内容: & c0 [' z: n v' p5 F &timers2 {- S7 c1 | k& V, o. n /* spare dmas for other usage */ $ a6 L. ~3 B8 j; q% t+ ]+ g# D' H /delete-property/dmas; /delete-property/dma-names;/ p3 U. d4 Q* Q# N: e) V7 U status = "okay";1 d1 i& ]$ Q1 R8 U 1 Q( p. r1 q+ J* U. N pwm2: pwm { pinctrl-0 = <&pwm2_pins_b>;8 ]' [7 y# k7 p7 M: t pinctrl-1 = <&pwm2_sleep_pins_b>;# l/ Q4 A8 J+ u5 {0 p# u, B8 e , ~% t( y, G( T( W% ? pinctrl-names = "default", "sleep"; #pwm-cells = <2>; status = "okay"; 3 q9 U G$ j; e: r2 x }; timer@2 {7 S8 l4 [8 O& `. [( E status = "disabled";9 \' d" P: g, |. w8 Q$ I5 c* ~ };: A% }4 b0 S! V9 ~ 5 K; m" d$ P$ U7 [- O' i* S2 {$ W. y5 o }; &pinctrl { / v L5 ~& b+ c2 { pwm2_pins_b: pwm2-0 { . V' x2 J8 E" E1 u2 s, Y0 ? pins {( K( z9 z+ E) Q8 l 1 m% R9 h4 }7 q3 c& f: @" u. r pinmux = <STM32_PINMUX('A', 5, AF1)>; /* TIM2_CH1 */ bias-pull-down;6 ~$ z+ e+ f* L. O1 v/ J0 C" I4 M 2 R+ Y$ Y" _1 p' Z# a& K9 H drive-push-pull; j% p" L( C: P# y2 j slew-rate = <0>; };5 l. O: d2 J: A* x( E }; pwm2_sleep_pins_b: pwm1-sleep-0 {2 b7 w# p: v# P2 a6 M3 A/ n2 M, Y pins { , h- Y) u# B% P) e pinmux = <STM32_PINMUX('A', 5, ANALOG)>; /* TIM2_CH1 */2 o% g2 Y4 W7 ]0 d; [ l5 W. ^, f: l2 T5 R/ y6 T0 m };" b$ E9 I: b- D) n : c3 t- V X% K$ f, u };7 S+ z9 e3 s& j( r$ v3 d & i3 \3 K( |7 [0 W& B1 @1 r# E }; 3.添加背光内容 修改stm32mp15xx-fsmp1x.dtsi,在根节点中添加如下内容:* Q( a- s1 U* z& H) T0 e0 G panel_backlight: panel-backlight { . l9 B( \/ I1 L compatible = "pwm-backlight"; pwms = <&pwm2 0 5000000>;/ L- d! Q C9 k( V! J" N3 v7 Y brightness-levels = <0 4 8 16 32 64 128 255>; " K2 c6 n: }& `) Q4 Q9 x& P3 q9 d default-brightness-level = <6>; status = "okay"; }; ! N& E' g! k- [4 r% U& y+ t% G* Y 4.添加ltdc端口0 g s: |0 m* | R+ ?; { 修改文件arm/arm/boot/dts/stm32mp157a-fsmp1a-rgb070.dts,在文件末尾添加如下内容:+ D, k3 i+ G3 t+ w) F: \8 S 2 r* ?/ F7 K0 Y: ~ <dc {- S. P/ D5 z: j X% z# H2 ?% Q status = "okay"; - J" F- t# F- H5 k$ X port { 7 u5 p( N! W! \3 w, t$ R& c #address-cells = <1>;; B2 @9 b; T/ x9 b- O$ Q, o4 \: S #size-cells = <0>; 3 [0 d/ V3 p) F& y6 O ltdc_ep1_out: endpoint@1 {9 [" K m7 b4 N% k- B/ Q reg = <1>;, q, V, z8 f5 d remote-endpoint = <&panel_in_rgb>;, @* t5 \5 w& L$ v ! \5 y# Q0 p0 ?$ |2 U t$ \& @, K8 | }; }; 6 V& t2 d# T+ p: t' K }; : Q* A3 D5 _( y& I m1 z 5.添加面板信息 修改文件arm/arm/boot/dts/stm32mp157a-fsmp1a-rgb070.dts,在根节点中添加如下内容: , [, m4 g, \4 E) ]7 x8 H) U3 n% U; E) U panel: panel-rgb {& ?( N+ v1 e& P( \% @ compatible = "innolux,zj070na-01p"; : Y' l8 B1 u. s pinctrl-names = "default", "sleep"; backlight = <&panel_backlight>; 5 Y# ~" \" t3 v4 \( i* b status = "okay";7 j ~. i& o3 P# U port {( S; m2 b. N& n, `- ? {1 Z ' ]5 V, B( Z1 T% v: J panel_in_rgb: endpoint { remote-endpoint = <<dc_ep1_out>;5 \+ O1 A+ f: L 1 o9 ]9 b8 f' W5 t9 L7 `7 `- H }; };& ]" Z! _# U' \6 O) x 2 a4 B6 m3 B S; P; f8 X* d% y }; 修改面板驱动,修改面板时序参数 修改文件drivers/gpu/drm/panel/panel-simple.c,修改zj070na-01p面板信息,对照面板芯片手册修改原有内容,红色字体部分为修改内容:& X9 c. Q* h2 y$ M8 Q- G2 q: w0 L 0 u( G5 {5 l5 Q4 L! @' z static const struct drm_display_mode innolux_zj070na_01p_mode = { B1 i' F% D+ ]' }5 C .clock = 51501, N7 b" B& ?$ {+ S .hdisplay = 1024, .hsync_start = 1024 + 160, .hsync_end = 1024 + 160 + 20, 2 Q9 O! K# K+ b( z0 Y7 m1 t .htotal = 1024 + 160 + 20 + 140, .vdisplay = 600, 2 @, V8 L, f1 m4 Z2 H4 w% f W) H .vsync_start = 600 + 12,4 e9 `1 K# D2 U .vsync_end = 600 + 12 + 3, .vtotal = 600 + 12 + 3 + 12,# b$ h; C6 C. E7 A .vrefresh = 60, ! Q4 q3 E0 N- e, _1 z) @ }; 6.配置内核. c, d9 e/ O6 ?! Z! `% Z 由于内核默认支持通用面板驱动,本节列出主要选项,如下 - _- }+ d3 s& a5 O/ {5 ]1 w% F linux@ubuntu make menuconfig Device Drivers ---> X( W5 Z0 p* h0 U8 N' n3 V; o- W Graphics support --->! K! g5 j9 Y, `( l <*> Direct Rendering Manager (XFree86 4.1.0 and higher DRI support) ---> <*> DRM Support for STMicroelectronics SoC Series Display Panels ---> <*> support for simple panels5 W" [( R& Y4 S. P: |& Y+ r5 F 6 ?% x; V( A3 {% \" R: j- L" [+ D Backlight & LCD device support --->, \2 p; e( Y" a& ?6 t G <*> Generic PWM based Backlight Driver ' m) K+ }& _0 U 7.增加启动项& Y# a) r+ U+ L! Y! [ 在虚拟机/tftpboot /tftpboot/pxelinux.cfg/01-00-80-e1-42-60-17末尾添加 3 f: ^; F. C( l LABEL stm32mp157a-fsmp1a-mipi KERNEL /uImage FDT /stm32mp157a-fsmp1a-rgb070.dtb0 p9 C3 v0 A V APPEND root=/dev/mmcblk1p4 rootwait rw console=ttySTM0,115200 % P# L+ r- h" I8 F# F 8.编译内核及设备树. L! h$ s @9 C" D/ _ linux@ubuntu make -j4 uImage dtbs LOADADDR=0xC20000400 f6 d% p6 E$ a0 V9 z$ J 9.重启测试 安装上7寸LCD面板,将编译好的设备树和内核镜像拷贝到/tftpboot目录下,通过tftp引导内核,启动后可正常显示,如果屏幕显示不正可适当调节面板参数。; y p9 v- u/ V( d/ i+ I, ` ———————————————— 版权声明:华清远见IT开放实验室 |
最新消息:意法半导体最具性价比、速度最快的单核MPU STM32MP13现已支持运行RTOS!意法半导体兑现了之前的承诺!
STM32MP135F-DK开发板评测-开箱亮屏
意法半导体扩展STM32Cube开发环境,简化单核STM32MP1裸机软件开发
1月18日有奖直播 | 如何在STM32MP13x上实现FOTA升级?
【STM32MP13x直播回顾】 直播答疑汇总
STM32MP135 开发平台介绍
使用STM32MP13: 如MCU般在Cortex-A核上裸 跑应用程序
米尔核心板加速基于STM32MP1的产品开发
STM32MP1充电桩全数字交互实现
STM32MP13 产品线 应用于工业和安全的高性价比MPU