当前位置:   article > 正文

(六)正点原子4.3寸RGB屏幕驱动--从零开始自制linux掌上电脑(F1C200S) <嵌入式项目>

rgb屏幕驱动

目录

一、RGB屏幕介绍  

二、RGB屏幕驱动

1、设备树修改

2、屏幕信息添加

3、内核驱动修改

4、开机logo显示

三、RGB屏幕显示功能测试

四、屏幕背光调节功能测试

五、主要参考内容


一、RGB屏幕介绍  

正点原子ATK4384显示屏,分辨率800*480,支持RGB接口,详细资料下载地址为:4.3寸RGBLCD电容触摸屏800*480。RGB LCD接口信号线如下所示:

信号线描述
R[7:0]数据线
G[7:0]数据线
B[7:0]数据线
DE数据使能线
VSYNC 垂直同步信号线
HSYNC 水平同步信号线
PCLK 像素钟信号线

屏幕的参数如下所示,其中各参数的含义详见这篇博客,解释的比较详细,我就不再重复造轮子了。

参数单位
水平显示区域800每时钟 (tCLK)
HSPW (thp)48每时钟 (tCLK)
HBP (thb)88每时钟 (tCLK)
HFP (thf)40每时钟 (tCLK)
垂直显示区域480每行 (th)
VSPW (tvp)3个每行 (th)
VBP (tvb)32每行 (th)
VFP (tvf)13每行 (th)

我的板子上存在两个屏幕接口, 1.14寸ips屏幕、ATK4384的40pinrgb屏幕,由于1.14寸屏幕实在是太小了,因此,本系统使用的40PinRGB屏幕接口如图所示。由下面的硬件原理图可以看出我们采用的屏数据格式是RGB666当然,I2C接口用作触摸屏数据传输,本文暂时用不到。


二、RGB屏幕驱动

linux内核已经配备了RGB模式下的LCD驱动(见drivers/gpu/drm/panel/panel-simple.c,也就是DRM驱动),而我们的F1C200s支持RGB模式的LCD,我们不需要从零写一个屏幕驱动,我们只需要简单几步即可驱动LCD屏幕。F1C200s虽然不像IMX6ULL那样配备eLCDIF接口,但只需要符合RGB接口的时序即可点亮。

注意:内核配置文件和之前相同!

1、设备树修改

.dtsi文件中做以下修改,代码修改处添加了modify by kashine的标注。其中,加入reset和clock两个文件夹下的suniv-ccu-f1c100s.h文件,是为了提供一些宏定义设备树de结点是display engine驱动初始化结点,官方解释为:Allwinner A10 Display Engine DRM/KMS Driver,关于DRM驱动的知识,这里不在赘述;tcon0结点对应时序控制驱动,官方解释为:Allwinner A10 Timing Controller Driver;pio结点中加入RGB屏幕的管脚信息;fe0结点和be0结点为RGB显示的前后端驱动程序;pwm结点用于背光显示,亮度调节。

我们来详细分析一下代码中的各个部分。

  1. display-engine:描述了显示引擎,这是 F1C100s 处理器中的一个重要组件,用于处理图像数据。它与显示前端(display-frontend)和显示后端(display-backend),相连接包含一条pipeline fe0。

  2. tcon0:代表了时序控制器(Timing Controller,简称 TCON),它负责生成正确的时序信号,以驱动显示面板。这部分代码中,我们可以看到 TCON 的寄存器地址、中断号、时钟和复位信号等信息。此外,还定义了输入和输出端口,分别连接到显示后端和显示面板。

  3. lcd_rgb666_pins:定义了与 RGB 屏幕连接的引脚,这里使用了 18 位的 RGB666 接口。

  4. display-frontend 和 display-backend:显示前端和显示后端分别负责图像数据的预处理和后处理。显示前端接收原始图像数据,对其进行缩放、色彩空间转换等操作;显示后端则负责图像数据的合成、alpha 混合等功能。这两个部分通过端口和端点(endpoint)进行连接。

  5. panel:描述了显示面板,定义了使用的LCD panel参数。这里使用了一个兼容于 "alientek,alientek_4p3_inch" 和 "simple-panel" 的面板。面板的输入端口与 TCON 的输出端口相连接。

  6. reg_vcc3v3:描述了一个固定电压的电源,为面板提供 3.3V 电源。

最后,在设备树末尾,启用了 be0(显示后端)、de(显示引擎)和 tcon0(时序控制器)节点。

从这段代码中可以看出,该 RGB 屏幕驱动确实使用了 DRM 框架。其工作原理大致如下:

  1. 显示前端接收原始图像数据,进行预处理。
  2. 处理后的图像数据传递给显示后端,进行后处理和合成。
  3. 处理后的图像数据通过 TCON 生成正确的时序信号,驱动显示面板。
  1. // SPDX-License-Identifier: (GPL-2.0+ OR X11)
  2. /*
  3. * Copyright 2018 Icenowy Zheng <icenowy@aosc.io>
  4. * Copyright 2018 Mesih Kilinc <mesihkilinc@gmail.com>
  5. */
  6. // modify by kashine
  7. #include <dt-bindings/clock/suniv-ccu-f1c100s.h>// 下面引用该文件中的一些宏定义
  8. #include <dt-bindings/reset/suniv-ccu-f1c100s.h>
  9. / {
  10. #address-cells = <1>;
  11. #size-cells = <1>;
  12. interrupt-parent = <&intc>;
  13. clocks {
  14. osc24M: clk-24M {
  15. #clock-cells = <0>;
  16. compatible = "fixed-clock";
  17. clock-frequency = <24000000>;
  18. clock-output-names = "osc24M";
  19. };
  20. osc32k: clk-32k {
  21. #clock-cells = <0>;
  22. compatible = "fixed-clock";
  23. clock-frequency = <32768>;
  24. clock-output-names = "osc32k";
  25. };
  26. };
  27. cpus {
  28. cpu {
  29. compatible = "arm,arm926ej-s";
  30. device_type = "cpu";
  31. };
  32. };
  33. // modify by kashine
  34. de: display-engine {
  35. compatible = "allwinner,suniv-f1c100s-display-engine";
  36. allwinner,pipelines = <&fe0>;
  37. status = "disabled";
  38. };
  39. soc {
  40. compatible = "simple-bus";
  41. #address-cells = <1>;
  42. #size-cells = <1>;
  43. ranges;
  44. sram-controller@1c00000 {
  45. compatible = "allwinner,suniv-f1c100s-system-control",
  46. "allwinner,sun4i-a10-system-control";
  47. reg = <0x01c00000 0x30>;
  48. #address-cells = <1>;
  49. #size-cells = <1>;
  50. ranges;
  51. sram_d: sram@10000 {
  52. compatible = "mmio-sram";
  53. reg = <0x00010000 0x1000>;
  54. #address-cells = <1>;
  55. #size-cells = <1>;
  56. ranges = <0 0x00010000 0x1000>;
  57. otg_sram: sram-section@0 {
  58. compatible = "allwinner,suniv-f1c100s-sram-d",
  59. "allwinner,sun4i-a10-sram-d";
  60. reg = <0x0000 0x1000>;
  61. status = "disabled";
  62. };
  63. };
  64. };
  65. // modify by kashine
  66. tcon0: lcd-controller@1c0c000 {
  67. compatible = "allwinner,suniv-f1c100s-tcon";
  68. reg = <0x01c0c000 0x1000>;
  69. interrupts = <29>;
  70. clocks = <&ccu CLK_BUS_LCD>,
  71. <&ccu CLK_TCON>;
  72. clock-names = "ahb",
  73. "tcon-ch0";
  74. clock-output-names = "tcon-pixel-clock";
  75. resets = <&ccu RST_BUS_LCD>;
  76. reset-names = "lcd";
  77. status = "disabled";
  78. ports {
  79. #address-cells = <1>;
  80. #size-cells = <0>;
  81. tcon0_in: port@0 {
  82. #address-cells = <1>;
  83. #size-cells = <0>;
  84. reg = <0>;
  85. tcon0_in_be0: endpoint@0 {
  86. reg = <0>;
  87. remote-endpoint = <&be0_out_tcon0>;
  88. };
  89. };
  90. tcon0_out: port@1 {
  91. #address-cells = <1>;
  92. #size-cells = <0>;
  93. reg = <1>;
  94. };
  95. };
  96. };
  97. ccu: clock@1c20000 {
  98. compatible = "allwinner,suniv-f1c100s-ccu";
  99. reg = <0x01c20000 0x400>;
  100. clocks = <&osc24M>, <&osc32k>;
  101. clock-names = "hosc", "losc";
  102. #clock-cells = <1>;
  103. #reset-cells = <1>;
  104. };
  105. intc: interrupt-controller@1c20400 {
  106. compatible = "allwinner,suniv-f1c100s-ic";
  107. reg = <0x01c20400 0x400>;
  108. interrupt-controller;
  109. #interrupt-cells = <1>;
  110. };
  111. pio: pinctrl@1c20800 {
  112. compatible = "allwinner,suniv-f1c100s-pinctrl";
  113. reg = <0x01c20800 0x400>;
  114. interrupts = <38>, <39>, <40>;
  115. clocks = <&ccu 37>, <&osc24M>, <&osc32k>;
  116. clock-names = "apb", "hosc", "losc";
  117. gpio-controller;
  118. interrupt-controller;
  119. #interrupt-cells = <3>;
  120. #gpio-cells = <3>;
  121. uart0_pe_pins: uart0-pe-pins {
  122. pins = "PE0", "PE1";
  123. function = "uart0";
  124. };
  125. // modify by kashine
  126. lcd_rgb666_pins: lcd-rgb666-pins {
  127. pins = "PD0", "PD1", "PD2", "PD3", "PD4",
  128. "PD5", "PD6", "PD7", "PD8", "PD9",
  129. "PD10", "PD11", "PD12", "PD13", "PD14",
  130. "PD15", "PD16", "PD17", "PD18", "PD19",
  131. "PD20", "PD21";
  132. function = "lcd";
  133. };
  134. // modify by kashine
  135. mmc0_pins: mmc0-pins {
  136. pins = "PF0", "PF1", "PF2", "PF3", "PF4", "PF5";
  137. function = "mmc0";
  138. };
  139. };
  140. timer@1c20c00 {
  141. compatible = "allwinner,suniv-f1c100s-timer";
  142. reg = <0x01c20c00 0x90>;
  143. interrupts = <13>;
  144. clocks = <&osc24M>;
  145. };
  146. wdt: watchdog@1c20ca0 {
  147. compatible = "allwinner,suniv-f1c100s-wdt",
  148. "allwinner,sun4i-a10-wdt";
  149. reg = <0x01c20ca0 0x20>;
  150. };
  151. uart0: serial@1c25000 {
  152. compatible = "snps,dw-apb-uart";
  153. reg = <0x01c25000 0x400>;
  154. interrupts = <1>;
  155. reg-shift = <2>;
  156. reg-io-width = <4>;
  157. clocks = <&ccu 38>;
  158. resets = <&ccu 24>;
  159. status = "disabled";
  160. };
  161. uart1: serial@1c25400 {
  162. compatible = "snps,dw-apb-uart";
  163. reg = <0x01c25400 0x400>;
  164. interrupts = <2>;
  165. reg-shift = <2>;
  166. reg-io-width = <4>;
  167. clocks = <&ccu 39>;
  168. resets = <&ccu 25>;
  169. status = "disabled";
  170. };
  171. uart2: serial@1c25800 {
  172. compatible = "snps,dw-apb-uart";
  173. reg = <0x01c25800 0x400>;
  174. interrupts = <3>;
  175. reg-shift = <2>;
  176. reg-io-width = <4>;
  177. clocks = <&ccu 40>;
  178. resets = <&ccu 26>;
  179. status = "disabled";
  180. };
  181. // modify by kashine
  182. mmc0: mmc@1c0f000 {
  183. compatible = "allwinner,suniv-f1c100s-mmc",
  184. "allwinner,sun7i-a20-mmc";
  185. reg = <0x01c0f000 0x1000>;
  186. clocks = <&ccu CLK_BUS_MMC0>,
  187. <&ccu CLK_MMC0>,
  188. <&ccu CLK_MMC0_OUTPUT>,
  189. <&ccu CLK_MMC0_SAMPLE>;
  190. clock-names = "ahb",
  191. "mmc",
  192. "output",
  193. "sample";
  194. resets = <&ccu RST_BUS_MMC0>;
  195. reset-names = "ahb";
  196. interrupts = <23>;
  197. pinctrl-names = "default";
  198. pinctrl-0 = <&mmc0_pins>;
  199. status = "disabled";
  200. #address-cells = <1>;
  201. #size-cells = <0>;
  202. };
  203. // modify by kashine
  204. fe0: display-frontend@1e00000 {
  205. compatible = "allwinner,suniv-f1c100s-display-frontend";
  206. reg = <0x01e00000 0x20000>;
  207. interrupts = <30>;
  208. clocks = <&ccu CLK_BUS_DE_FE>, <&ccu CLK_DE_FE>,
  209. <&ccu CLK_DRAM_DE_FE>;
  210. clock-names = "ahb", "mod",
  211. "ram";
  212. resets = <&ccu RST_BUS_DE_FE>;
  213. status = "disabled";
  214. ports {
  215. #address-cells = <1>;
  216. #size-cells = <0>;
  217. fe0_out: port@1 {
  218. #address-cells = <1>;
  219. #size-cells = <0>;
  220. reg = <1>;
  221. fe0_out_be0: endpoint@0 {
  222. reg = <0>;
  223. remote-endpoint = <&be0_in_fe0>;
  224. };
  225. };
  226. };
  227. };
  228. // modify by kashine
  229. be0: display-backend@1e60000 {
  230. compatible = "allwinner,suniv-f1c100s-display-backend";
  231. reg = <0x01e60000 0x10000>;
  232. reg-names = "be";
  233. interrupts = <31>;
  234. clocks = <&ccu CLK_BUS_DE_BE>, <&ccu CLK_DE_BE>,
  235. <&ccu CLK_DRAM_DE_BE>;
  236. clock-names = "ahb", "mod",
  237. "ram";
  238. resets = <&ccu RST_BUS_DE_BE>;
  239. reset-names = "be";
  240. assigned-clocks = <&ccu CLK_DE_BE>;
  241. assigned-clock-rates = <300000000>;
  242. ports {
  243. #address-cells = <1>;
  244. #size-cells = <0>;
  245. be0_in: port@0 {
  246. #address-cells = <1>;
  247. #size-cells = <0>;
  248. reg = <0>;
  249. be0_in_fe0: endpoint@0 {
  250. reg = <0>;
  251. remote-endpoint = <&fe0_out_be0>;
  252. };
  253. };
  254. be0_out: port@1 {
  255. #address-cells = <1>;
  256. #size-cells = <0>;
  257. reg = <1>;
  258. be0_out_tcon0: endpoint@0 {
  259. reg = <0>;
  260. remote-endpoint = <&tcon0_in_be0>;
  261. };
  262. };
  263. };
  264. };
  265. // modify by kashine
  266. pwm: pwm@1c21000 {
  267. compatible = "allwinner,sun4i-a10-pwm";
  268. reg = <0x01C21000 0x08>;
  269. clocks = <&osc24M>;
  270. #pwm-cells = <3>;
  271. status = "disabled";
  272. };
  273. };
  274. };

.dts文件做以下修改,添加了一个panel面板设备结点,对应4.3寸RGB屏幕,其compatible属性对应指定的显示驱动,我们将在后面提到;添加了backlight背光调节结点,设置了不同的背光等级;然后打开或修改了.dtsi文件中结点的功能。

  1. // SPDX-License-Identifier: (GPL-2.0+ OR X11)
  2. /*
  3. * Copyright 2018 Icenowy Zheng <icenowy@aosc.io>
  4. */
  5. /dts-v1/;
  6. #include "suniv-f1c100s.dtsi"
  7. // modify by kashine
  8. #include <dt-bindings/gpio/gpio.h>
  9. #include <dt-bindings/input/input.h>
  10. #include <dt-bindings/interrupt-controller/irq.h>
  11. / {
  12. model = "Lichee Pi Nano";
  13. compatible = "licheepi,licheepi-nano", "allwinner,suniv-f1c100s";
  14. aliases {
  15. serial0 = &uart0;
  16. };
  17. chosen {
  18. stdout-path = "serial0:115200n8";
  19. };
  20. // modify by kashine
  21. panel: panel {//ampire_am800480r3tmqwa1h_mode
  22. compatible = "alientek,alientek_4p3_inch", "simple-panel";
  23. #address-cells = <1>;
  24. #size-cells = <0>;
  25. reset-gpios = <&pio 4 4 GPIO_ACTIVE_LOW>;
  26. power-supply = <&reg_vcc3v3>;
  27. //backlight = <&backlight>;
  28. port@0 {
  29. reg = <0>;
  30. #address-cells = <1>;
  31. #size-cells = <0>;
  32. panel_input: endpoint@0 {
  33. reg = <0>;
  34. remote-endpoint = <&tcon0_out_lcd>;
  35. };
  36. };
  37. };
  38. // modify by kashine
  39. reg_vcc3v3: vcc3v3 {
  40. compatible = "regulator-fixed";
  41. regulator-name = "vcc3v3";
  42. regulator-min-microvolt = <3300000>;
  43. regulator-max-microvolt = <3300000>;
  44. };
  45. // modify by kashine
  46. backlight: backlight {
  47. compatible = "pwm-backlight";
  48. pwms = <&pwm 1 500000 0>;
  49. pwm-names = "backlight";
  50. brightness-levels = <0 4 8 16 32 64 128 255>;
  51. default-brightness-level = <7>;
  52. status = "okay";
  53. };
  54. };
  55. &uart0 {
  56. pinctrl-names = "default";
  57. pinctrl-0 = <&uart0_pe_pins>;
  58. status = "okay";
  59. };
  60. // modify by kashine all down
  61. &mmc0 {
  62. vmmc-supply = <&reg_vcc3v3>;
  63. bus-width = <4>;
  64. broken-cd;
  65. status = "okay";
  66. };
  67. &be0 {
  68. status = "okay";
  69. };
  70. &de {
  71. status = "okay";
  72. };
  73. &tcon0 {
  74. pinctrl-names = "default";
  75. pinctrl-0 = <&lcd_rgb666_pins>;
  76. status = "okay";
  77. };
  78. &tcon0_out {
  79. tcon0_out_lcd: endpoint@0 {
  80. reg = <0>;
  81. remote-endpoint = <&panel_input>;
  82. };
  83. };
  84. &pio {
  85. pwm1_pin: pwm1_pin {
  86. pins = "PE6";
  87. function = "pwm1";
  88. };
  89. };
  90. &pwm {
  91. pinctrl-names = "default";
  92. pinctrl-0 = <&pwm1_pin>;
  93. status = "okay";
  94. };

2、屏幕信息添加

本文使用正点原子40Pin RGB 屏幕,分辨率为800*480,根据正点原子提供的资料,在内核目录/drivers/gpu/drm/panel/panel_simple.c中,填写屏幕时序信息如下:

  1. // modify by kashine
  2. static const struct drm_display_mode alientek_4p3_inch_mode = {
  3. .clock = 31000,
  4. .hdisplay = 800,
  5. .hsync_start = 800 + 40,
  6. .hsync_end = 800 + 40 + 48,
  7. .htotal = 800 + 40 + 48 + 88,
  8. .vdisplay = 480,
  9. .vsync_start = 480 + 13,
  10. .vsync_end = 480 + 13 + 3,
  11. .vtotal = 480 + 13 + 3 + 32,
  12. .vrefresh = 60,
  13. };
  14. static const struct panel_desc alientek_4p3_inch = {
  15. .modes = &alientek_4p3_inch_mode,
  16. .num_modes = 1,
  17. .bpc = 6,
  18. .size = {
  19. .width = 154,
  20. .height = 85,
  21. },
  22. .bus_format = MEDIA_BUS_FMT_RGB666_1X18,
  23. };

首先来解释alientek_4p3_inch_mode结构体中的参数含义,主要为屏幕的时序信息,设置错误可能导致显示错位、不完整。

  1. clock: RGB屏幕需要使用的时钟频率
  2. hdisplay:有效显示区水平像素数量,800*480中的800,对应Active Width
  3. hsync_start:水平同步开始,对应hdispay + HFP
  4. hsync_end:水平同步结束,对应hdisplay + HFP + HSYNC width(HSPW)
  5. htotal:水平总像素,对应hdisplay + HFP + HSYNC width + HBP
  6. vdisplay:垂直显示像素,800*480中的480,对应Active Height
  7. vsync_start:垂直同步开始,对应vdispay + VFP
  8. vsync_end:垂直像素结束,对应vdisplay + VFP + VSYNC width(VSPW)
  9. vtotal:垂直总像素,对应vdisplay + VFP + VSYNC width + VBP
  10. vrefresh:刷新率
  11. 原文链接:https://blog.csdn.net/u012794472/article/details/124868025

alientek_4p3_inch结构体主要用来描述所用屏幕的信息,包括显示模式、像素格式等。其中MEDIA_BUS_FMT_RGB666_1X18的含义详见The Linux Kernel documentationwidth、height为液晶的尺寸,需要根据屏幕的用户使用手册进行设置,如下图所示为本文使用的ATK4384屏幕尺寸图。

另一处需要修改的地方如下所示,添加设备树对应的设备驱动绑定信息。

  1. .data = &vl050_8048nt_c01,
  2. }, {
  3. .compatible = "winstar,wf35ltiacd",
  4. .data = &winstar_wf35ltiacd,
  5. }, {// modify by kashine
  6. .compatible = "alientek,alientek_4p3_inch",
  7. .data = &alientek_4p3_inch,
  8. },{
  9. /* Must be the last entry */
  10. .compatible = "panel-dpi",
  11. .data = &panel_dpi,
  12. }, {
  13. /* sentinel */
  14. }

3、内核驱动修改

以下为核心内容,本人尝试了坑网、CSDN、荔枝派、芒果派等的众多教程,历经多次内核修改与编译,最终整理出关于F1C200s在Linux5.7.1内核下的RGB驱动修改方法如下。主要修改文件为内核目录/drivers/gpu/drm/sun4i/文件夹下的三个文件,分别为sun4i_tcon.c、sun4i_drv.c、sun4i_backend.c。以下修改内容主要是为了使驱动适配F1C200s这款芯片。

可以根据代码中注释及前后内容,定位三个文件需要修改的地方。

// sun4i_backend.c文件修改

  1. // modify by kashine
  2. static const struct sun4i_backend_quirks suniv_backend_quirks = {
  3. };
  4. static const struct sun4i_backend_quirks sun4i_backend_quirks = {
  5. .needs_output_muxing = true,
  6. };
  7. static const struct sun4i_backend_quirks sun5i_backend_quirks = {
  8. };
  9. static const struct sun4i_backend_quirks sun6i_backend_quirks = {
  10. };
  11. static const struct sun4i_backend_quirks sun7i_backend_quirks = {
  12. .needs_output_muxing = true,
  13. .supports_lowest_plane_alpha = true,
  14. };
  15. static const struct sun4i_backend_quirks sun8i_a33_backend_quirks = {
  16. .supports_lowest_plane_alpha = true,
  17. };
  18. static const struct sun4i_backend_quirks sun9i_backend_quirks = {
  19. };
  20. static const struct of_device_id sun4i_backend_of_table[] = {
  21. {// modify by kashine
  22. .compatible = "allwinner,suniv-f1c100s-display-backend",
  23. .data = &suniv_backend_quirks,
  24. },
  25. {
  26. .compatible = "allwinner,sun4i-a10-display-backend",
  27. .data = &sun4i_backend_quirks,
  28. },
  29. {
  30. .compatible = "allwinner,sun5i-a13-display-backend",
  31. .data = &sun5i_backend_quirks,
  32. },
  33. {
  34. .compatible = "allwinner,sun6i-a31-display-backend",
  35. .data = &sun6i_backend_quirks,
  36. },
  37. {
  38. .compatible = "allwinner,sun7i-a20-display-backend",
  39. .data = &sun7i_backend_quirks,
  40. },
  41. {
  42. .compatible = "allwinner,sun8i-a23-display-backend",
  43. .data = &sun8i_a33_backend_quirks,
  44. },
  45. {
  46. .compatible = "allwinner,sun8i-a33-display-backend",
  47. .data = &sun8i_a33_backend_quirks,
  48. },
  49. {
  50. .compatible = "allwinner,sun9i-a80-display-backend",
  51. .data = &sun9i_backend_quirks,
  52. },
  53. { }
  54. };

// sun4i_drv.c文件修改

  1. static bool sun4i_drv_node_is_frontend(struct device_node *node)
  2. {
  3. // modify by kashine
  4. return of_device_is_compatible(node, "allwinner,suniv-f1c100s-display-frontend") ||
  5. of_device_is_compatible(node, "allwinner,sun4i-a10-display-frontend") ||
  6. of_device_is_compatible(node, "allwinner,sun5i-a13-display-frontend") ||
  7. of_device_is_compatible(node, "allwinner,sun6i-a31-display-frontend") ||
  8. of_device_is_compatible(node, "allwinner,sun7i-a20-display-frontend") ||
  9. of_device_is_compatible(node, "allwinner,sun8i-a23-display-frontend") ||
  10. of_device_is_compatible(node, "allwinner,sun8i-a33-display-frontend") ||
  11. of_device_is_compatible(node, "allwinner,sun9i-a80-display-frontend");
  12. }
  1. static const struct of_device_id sun4i_drv_of_table[] = {
  2. { .compatible = "allwinner,suniv-f1c100s-display-engine" },// modify by kashine
  3. { .compatible = "allwinner,sun4i-a10-display-engine" },
  4. { .compatible = "allwinner,sun5i-a10s-display-engine" },
  5. { .compatible = "allwinner,sun5i-a13-display-engine" },
  6. { .compatible = "allwinner,sun6i-a31-display-engine" },
  7. { .compatible = "allwinner,sun6i-a31s-display-engine" },
  8. { .compatible = "allwinner,sun7i-a20-display-engine" },
  9. { .compatible = "allwinner,sun8i-a23-display-engine" },
  10. { .compatible = "allwinner,sun8i-a33-display-engine" },
  11. { .compatible = "allwinner,sun8i-a83t-display-engine" },
  12. { .compatible = "allwinner,sun8i-h3-display-engine" },
  13. { .compatible = "allwinner,sun8i-r40-display-engine" },
  14. { .compatible = "allwinner,sun8i-v3s-display-engine" },
  15. { .compatible = "allwinner,sun9i-a80-display-engine" },
  16. { .compatible = "allwinner,sun50i-a64-display-engine" },
  17. { .compatible = "allwinner,sun50i-h6-display-engine" },
  18. { }
  19. };

 // sun4i_tcon.c文件修改

  1. // modify by kashine
  2. static const struct sun4i_tcon_quirks suniv_f1c100s_quirks = {
  3. /*
  4. * The F1C100s SoC has a second channel in TCON, but the clock input of
  5. * it is not documented.
  6. */
  7. .has_channel_0 = true,
  8. //.has_channel_1 = true,
  9. .dclk_min_div = 1,// Linux5.2不需要加,5.7.1不加该代码会白屏
  10. };
  11. static const struct sun4i_tcon_quirks sun4i_a10_quirks = {
  12. .has_channel_0 = true,
  13. .has_channel_1 = true,
  14. .dclk_min_div = 4,
  15. .set_mux = sun4i_a10_tcon_set_mux,
  16. };
  1. /* sun4i_drv uses this list to check if a device node is a TCON */
  2. const struct of_device_id sun4i_tcon_of_table[] = {
  3. {.compatible = "allwinner,suniv-f1c100s-tcon", .data = &suniv_f1c100s_quirks },// modify by kashine
  4. { .compatible = "allwinner,sun4i-a10-tcon", .data = &sun4i_a10_quirks },
  5. { .compatible = "allwinner,sun5i-a13-tcon", .data = &sun5i_a13_quirks },
  6. { .compatible = "allwinner,sun6i-a31-tcon", .data = &sun6i_a31_quirks },
  7. { .compatible = "allwinner,sun6i-a31s-tcon", .data = &sun6i_a31s_quirks },
  8. { .compatible = "allwinner,sun7i-a20-tcon", .data = &sun7i_a20_quirks },
  9. { .compatible = "allwinner,sun7i-a20-tcon0", .data = &sun7i_a20_tcon0_quirks },
  10. { .compatible = "allwinner,sun7i-a20-tcon1", .data = &sun7i_a20_quirks },
  11. { .compatible = "allwinner,sun8i-a23-tcon", .data = &sun8i_a33_quirks },
  12. { .compatible = "allwinner,sun8i-a33-tcon", .data = &sun8i_a33_quirks },
  13. { .compatible = "allwinner,sun8i-a83t-tcon-lcd", .data = &sun8i_a83t_lcd_quirks },
  14. { .compatible = "allwinner,sun8i-a83t-tcon-tv", .data = &sun8i_a83t_tv_quirks },
  15. { .compatible = "allwinner,sun8i-r40-tcon-tv", .data = &sun8i_r40_tv_quirks },
  16. { .compatible = "allwinner,sun8i-v3s-tcon", .data = &sun8i_v3s_quirks },
  17. { .compatible = "allwinner,sun9i-a80-tcon-lcd", .data = &sun9i_a80_tcon_lcd_quirks },
  18. { .compatible = "allwinner,sun9i-a80-tcon-tv", .data = &sun9i_a80_tcon_tv_quirks },
  19. { }
  20. };

4、开机logo显示

使用make menuconfig打开图形化配置界面,打开Bootup logo,其中的三个选项全部选中。

  1. -> Device Drivers
  2. -> Graphics support
  3. -> Bootup logo (LOGO [=y])
  4. -> Standard black and white Linux logo
  5. -> Standard 16-color Linux logo
  6. -> Standard 224-color Linux logo

背光选项记得勾上(其实不勾也可以)。


三、RGB屏幕显示功能测试

修改完上述内核文件后,重新编译,编译所需的时间相比于初次编译要短很多。在uboot的bootargs参数中添加如下内容可使内核输出更多drm相关信息,便于调试:

 drm.debug=0x1f debug

如图所示为开发板上电启动过程中RGB屏幕显示的内容,启动时左上角显示Linux logo,符合我们的预期。

进入Debian文件系统后,可以使用如下命令查看日志的输出级别(在Linux中日志一共分为8个等级,数值越小,优先级越高)下面的四个数字是由kernel/printk.c文件中定义的一个数组决定的。

  1. cat /proc/sys/kernel/printk
  2. # 默认输出7 4 1 7

上面四个数字的含别如下:

控制台日志级别:优先级高于该值的消息将被打印至控制台
默认的消息日志级别:将用该优先级来打印没有优先级的消息
最低的控制台日志级别:控制台日志级别可被设置的最小值(最高优先级)
默认的控制台日志级别:控制台日志级别的缺省值

如果觉得开机之后输出的日志信息太多,可以使用如下命令修改打印的日志信息级别,减少不必要的信息干扰。

  1. # 屏蔽掉所有的内核printk打印
  2. echo 0 4 1 7 > /proc/sys/kernel/printk

四、屏幕背光调节功能测试

通过PE6管脚输出PWM波,控制屏幕背光引脚,进而控制屏幕亮度,本文在设备树中设置了八个亮度等级,通过在脚本(.sh文件,并chomd权限)中输入以下代码可以控制亮度变化。(这里有个小问题,输入零的时候并没有熄屏,留个小坑吧)

  1. while true
  2. do
  3. for i in {7..1}
  4. do
  5. sleep 0.2
  6. echo $i > /sys/class/backlight/backlight/brightness
  7. done
  8. for j in {1..7}
  9. do
  10. echo $j > /sys/class/backlight/backlight/brightness
  11. sleep 0.2
  12. done
  13. done

五、主要参考内容

1.RGB接口 LCD驱动适配

2.Lctech Pi(F1C200S)4.3寸(480*272)16位RGB565LCD屏驱动适配 ;

3.解决f1c100s 主线Linux 升级到 4.19 之后的版本没有 framebuffer(fb0)设备问题(Linux5.2)

4.修改Linux kernel中打印的级别

5.f1c100s驱动rgb屏求助

6.更换正点原子7寸RGB LCD(1024*600),启动失败

7.ttyS、ttySAC、tty、ttyn的区别_HeroKern的博客-CSDN博客_ttytcu0和ttyths0的区别


声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/712795
推荐阅读
相关标签
  

闽ICP备14008679号