目录
一、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结点 用于背光显示,亮度调节。
我们来详细分析一下代码中的各个部分。
- display-engine:描述了显示引擎,这是 F1C100s 处理器中的一个重要组件,用于处理图像数据。它与显示前端(display-frontend)和显示后端(display-backend),相连接包含一条pipeline fe0。
- tcon0:代表了时序控制器(Timing Controller,简称 TCON),它负责生成正确的时序信号,以驱动显示面板。这部分代码中,我们可以看到 TCON 的寄存器地址、中断号、时钟和复位信号等信息。此外,还定义了输入和输出端口,分别连接到显示后端和显示面板。
- lcd_rgb666_pins:定义了与 RGB 屏幕连接的引脚,这里使用了 18 位的 RGB666 接口。
- display-frontend 和 display-backend:显示前端和显示后端分别负责图像数据的预处理和后处理。显示前端接收原始图像数据,对其进行缩放、色彩空间转换等操作;显示后端则负责图像数据的合成、alpha 混合等功能。这两个部分通过端口和端点(endpoint)进行连接。
- panel:描述了显示面板,定义了使用的LCD panel参数。这里使用了一个兼容于 "alientek,alientek_4p3_inch" 和 "simple-panel" 的面板。面板的输入端口与 TCON 的输出端口相连接。
- reg_vcc3v3:描述了一个固定电压的电源,为面板提供 3.3V 电源。
最后,在设备树末尾,启用了 be0(显示后端)、de(显示引擎)和 tcon0(时序控制器)节点。
从这段代码中可以看出,该 RGB 屏幕驱动确实使用了 DRM 框架。其工作原理大致如下:
- 显示前端接收原始图像数据,进行预处理。
- 处理后的图像数据传递给显示后端,进行后处理和合成。
- 处理后的图像数据通过 TCON 生成正确的时序信号,驱动显示面板。
// SPDX-License-Identifier: (GPL-2.0+ OR X11)
/*
- Copyright 2018 Icenowy Zheng
- Copyright 2018 Mesih Kilinc
*/
// modify by kashine
#include // 下面引用该文件中的一些宏定义
#include
/ {
#address-cells = <1>;
#size-cells = <1>;
interrupt-parent = <&intc;>;
clocks {
osc24M: clk-24M {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <24000000>;
clock-output-names = "osc24M";
};
osc32k: clk-32k {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <32768>;
clock-output-names = "osc32k";
};
};
cpus {
cpu {
compatible = "arm,arm926ej-s";
device_type = "cpu";
};
};
// modify by kashine
de: display-engine {
compatible = "allwinner,suniv-f1c100s-display-engine";
allwinner,pipelines = <&fe0;>;
status = "disabled";
};
soc {
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <1>;
ranges;
sram-controller@1c00000 {
compatible = "allwinner,suniv-f1c100s-system-control",
"allwinner,sun4i-a10-system-control";
reg = <0x01c00000 0x30>;
#address-cells = <1>;
#size-cells = <1>;
ranges;
sram_d: sram@10000 {
compatible = "mmio-sram";
reg = <0x00010000 0x1000>;
#address-cells = <1>;
#size-cells = <1>;
ranges = <0 0x00010000 0x1000>;
otg_sram: sram-section@0 {
compatible = "allwinner,suniv-f1c100s-sram-d",
"allwinner,sun4i-a10-sram-d";
reg = <0x0000 0x1000>;
status = "disabled";
};
};
};
// modify by kashine
tcon0: lcd-controller@1c0c000 {
compatible = "allwinner,suniv-f1c100s-tcon";
reg = <0x01c0c000 0x1000>;
interrupts = <29>;
clocks = <&ccu; CLK_BUS_LCD>,
<&ccu; CLK_TCON>;
clock-names = "ahb",
"tcon-ch0";
clock-output-names = "tcon-pixel-clock";
resets = <&ccu; RST_BUS_LCD>;
reset-names = "lcd";
status = "disabled";
ports {
#address-cells = <1>;
#size-cells = <0>;
tcon0_in: port@0 {
#address-cells = <1>;
#size-cells = <0>;
reg = <0>;
tcon0_in_be0: endpoint@0 {
reg = <0>;
remote-endpoint = <&be0;_out_tcon0>;
};
};
tcon0_out: port@1 {
#address-cells = <1>;
#size-cells = <0>;
reg = <1>;
};
};
};
ccu: clock@1c20000 {
compatible = "allwinner,suniv-f1c100s-ccu";
reg = <0x01c20000 0x400>;
clocks = <&osc24M;>, <&osc32k;>;
clock-names = "hosc", "losc";
#clock-cells = <1>;
#reset-cells = <1>;
};
intc: interrupt-controller@1c20400 {
compatible = "allwinner,suniv-f1c100s-ic";
reg = <0x01c20400 0x400>;
interrupt-controller;
#interrupt-cells = <1>;
};
pio: pinctrl@1c20800 {
compatible = "allwinner,suniv-f1c100s-pinctrl";
reg = <0x01c20800 0x400>;
interrupts = <38>, <39>, <40>;
clocks = <&ccu; 37>, <&osc24M;>, <&osc32k;>;
clock-names = "apb", "hosc", "losc";
gpio-controller;
interrupt-controller;
#interrupt-cells = <3>;
#gpio-cells = <3>;
uart0_pe_pins: uart0-pe-pins {
pins = "PE0", "PE1";
function = "uart0";
};
// modify by kashine
lcd_rgb666_pins: lcd-rgb666-pins {
pins = "PD0", "PD1", "PD2", "PD3", "PD4",
"PD5", "PD6", "PD7", "PD8", "PD9",
"PD10", "PD11", "PD12", "PD13", "PD14",
"PD15", "PD16", "PD17", "PD18", "PD19",
"PD20", "PD21";
function = "lcd";
};
// modify by kashine
mmc0_pins: mmc0-pins {
pins = "PF0", "PF1", "PF2", "PF3", "PF4", "PF5";
function = "mmc0";
};
};
timer@1c20c00 {
compatible = "allwinner,suniv-f1c100s-timer";
reg = <0x01c20c00 0x90>;
interrupts = <13>;
clocks = <&osc24M;>;
};
wdt: watchdog@1c20ca0 {
compatible = "allwinner,suniv-f1c100s-wdt",
"allwinner,sun4i-a10-wdt";
reg = <0x01c20ca0 0x20>;
};
uart0: serial@1c25000 {
compatible = "snps,dw-apb-uart";
reg = <0x01c25000 0x400>;
interrupts = <1>;
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&ccu; 38>;
resets = <&ccu; 24>;
status = "disabled";
};
uart1: serial@1c25400 {
compatible = "snps,dw-apb-uart";
reg = <0x01c25400 0x400>;
interrupts = <2>;
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&ccu; 39>;
resets = <&ccu; 25>;
status = "disabled";
};
uart2: serial@1c25800 {
compatible = "snps,dw-apb-uart";
reg = <0x01c25800 0x400>;
interrupts = <3>;
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&ccu; 40>;
resets = <&ccu; 26>;
status = "disabled";
};
// modify by kashine
mmc0: mmc@1c0f000 {
compatible = "allwinner,suniv-f1c100s-mmc",
"allwinner,sun7i-a20-mmc";
reg = <0x01c0f000 0x1000>;
clocks = <&ccu; CLK_BUS_MMC0>,
<&ccu; CLK_MMC0>,
<&ccu; CLK_MMC0_OUTPUT>,
<&ccu; CLK_MMC0_SAMPLE>;
clock-names = "ahb",
"mmc",
"output",
"sample";
resets = <&ccu; RST_BUS_MMC0>;
reset-names = "ahb";
interrupts = <23>;
pinctrl-names = "default";
pinctrl-0 = <&mmc0;_pins>;
status = "disabled";
#address-cells = <1>;
#size-cells = <0>;
};
// modify by kashine
fe0: display-frontend@1e00000 {
compatible = "allwinner,suniv-f1c100s-display-frontend";
reg = <0x01e00000 0x20000>;
interrupts = <30>;
clocks = <&ccu; CLK_BUS_DE_FE>, <&ccu; CLK_DE_FE>,
<&ccu; CLK_DRAM_DE_FE>;
clock-names = "ahb", "mod",
"ram";
resets = <&ccu; RST_BUS_DE_FE>;
status = "disabled";
ports {
#address-cells = <1>;
#size-cells = <0>;
fe0_out: port@1 {
#address-cells = <1>;
#size-cells = <0>;
reg = <1>;
fe0_out_be0: endpoint@0 {
reg = <0>;
remote-endpoint = <&be0;_in_fe0>;
};
};
};
};
// modify by kashine
be0: display-backend@1e60000 {
compatible = "allwinner,suniv-f1c100s-display-backend";
reg = <0x01e60000 0x10000>;
reg-names = "be";
interrupts = <31>;
clocks = <&ccu; CLK_BUS_DE_BE>, <&ccu; CLK_DE_BE>,
<&ccu; CLK_DRAM_DE_BE>;
clock-names = "ahb", "mod",
"ram";
resets = <&ccu; RST_BUS_DE_BE>;
reset-names = "be";
assigned-clocks = <&ccu; CLK_DE_BE>;
assigned-clock-rates = <300000000>;
ports {
#address-cells = <1>;
#size-cells = <0>;
be0_in: port@0 {
#address-cells = <1>;
#size-cells = <0>;
reg = <0>;
be0_in_fe0: endpoint@0 {
reg = <0>;
remote-endpoint = <&fe0;_out_be0>;
};
};
be0_out: port@1 {
#address-cells = <1>;
#size-cells = <0>;
reg = <1>;
be0_out_tcon0: endpoint@0 {
reg = <0>;
remote-endpoint = <&tcon0;_in_be0>;
};
};
};
};
// modify by kashine
pwm: pwm@1c21000 {
compatible = "allwinner,sun4i-a10-pwm";
reg = <0x01C21000 0x08>;
clocks = <&osc24M;>;
#pwm-cells = <3>;
status = "disabled";
};
};
};
.dts文件 做以下修改,添加了一个 panel面板设备结点,
对应4.3寸RGB屏幕,其compatible属性对应指定的显示驱动,我们将在后面提到;添加了 backlight背光调节结点,
设置了不同的背光等级;然后打开或修改了.dtsi文件中结点的功能。
// SPDX-License-Identifier: (GPL-2.0+ OR X11)
/*
- Copyright 2018 Icenowy Zheng
*/
/dts-v1/;
#include "suniv-f1c100s.dtsi"
// modify by kashine
#include
#include
#include
/ {
model = "Lichee Pi Nano";
compatible = "licheepi,licheepi-nano", "allwinner,suniv-f1c100s";
aliases {
serial0 = &uart0;
};
chosen {
stdout-path = "serial0:115200n8";
};
// modify by kashine
panel: panel {//ampire_am800480r3tmqwa1h_mode
compatible = "alientek,alientek_4p3_inch", "simple-panel";
#address-cells = <1>;
#size-cells = <0>;
reset-gpios = <&pio; 4 4 GPIO_ACTIVE_LOW>;
power-supply = <®_vcc3v3>;
//backlight = <&backlight;>;
port@0 {
reg = <0>;
#address-cells = <1>;
#size-cells = <0>;
panel_input: endpoint@0 {
reg = <0>;
remote-endpoint = <&tcon0;_out_lcd>;
};
};
};
// modify by kashine
reg_vcc3v3: vcc3v3 {
compatible = "regulator-fixed";
regulator-name = "vcc3v3";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
};
// modify by kashine
backlight: backlight {
compatible = "pwm-backlight";
pwms = <&pwm; 1 500000 0>;
pwm-names = "backlight";
brightness-levels = <0 4 8 16 32 64 128 255>;
default-brightness-level = <7>;
status = "okay";
};
};
&uart0; {
pinctrl-names = "default";
pinctrl-0 = <&uart0;_pe_pins>;
status = "okay";
};
// modify by kashine all down
&mmc0; {
vmmc-supply = <®_vcc3v3>;
bus-width = <4>;
broken-cd;
status = "okay";
};
&be0; {
status = "okay";
};
&de; {
status = "okay";
};
&tcon0; {
pinctrl-names = "default";
pinctrl-0 = <&lcd;_rgb666_pins>;
status = "okay";
};
&tcon0;_out {
tcon0_out_lcd: endpoint@0 {
reg = <0>;
remote-endpoint = <&panel;_input>;
};
};
&pio; {
pwm1_pin: pwm1_pin {
pins = "PE6";
function = "pwm1";
};
};
&pwm; {
pinctrl-names = "default";
pinctrl-0 = <&pwm1;_pin>;
status = "okay";
};
2、屏幕信息添加
本文使用 正点原子40Pin RGB 屏幕,分辨率为800*480, 根据正点原子提供的资料,在内核目录
/drivers/gpu/drm/panel/panel_simple.c 中,填写屏幕 时序信息 如下:
// modify by kashine
static const struct drm_display_mode alientek_4p3_inch_mode = {
.clock = 31000,
.hdisplay = 800,
.hsync_start = 800 + 40,
.hsync_end = 800 + 40 + 48,
.htotal = 800 + 40 + 48 + 88,
.vdisplay = 480,
.vsync_start = 480 + 13,
.vsync_end = 480 + 13 + 3,
.vtotal = 480 + 13 + 3 + 32,
.vrefresh = 60,
};
static const struct panel_desc alientek_4p3_inch = {
.modes = &alientek;_4p3_inch_mode,
.num_modes = 1,
.bpc = 6,
.size = {
.width = 154,
.height = 85,
},
.bus_format = MEDIA_BUS_FMT_RGB666_1X18,
};
首先来解释 alientek_4p3_inch_mode结构体 中的 参数含义 ,主要为 屏幕的时序信息
,设置错误可能导致显示错位、不完整。
clock: RGB屏幕需要使用的时钟频率
hdisplay:有效显示区水平像素数量,800*480中的800,对应Active Width
hsync_start:水平同步开始,对应hdispay + HFP
hsync_end:水平同步结束,对应hdisplay + HFP + HSYNC width(HSPW)
htotal:水平总像素,对应hdisplay + HFP + HSYNC width + HBP
vdisplay:垂直显示像素,800*480中的480,对应Active Height
vsync_start:垂直同步开始,对应vdispay + VFP
vsync_end:垂直像素结束,对应vdisplay + VFP + VSYNC width(VSPW)
vtotal:垂直总像素,对应vdisplay + VFP + VSYNC width + VBP
vrefresh:刷新率
原文链接:https://blog.csdn.net/u012794472/article/details/124868025
alientek_4p3_inch结构体 主要用来描述所用屏幕的信息,包括 显示模式、像素格式等。 其中
MEDIA_BUS_FMT_RGB666_1X18 的含义详见[The Linux Kernel
documentation](https://www.kernel.org/doc/html/latest/userspace-
api/media/v4l/subdev-formats.html?highlight=media_bus_fmt_uyvy8_2x8 "The Linux
Kernel documentation")。 width、height为液晶的尺寸, 需要根据屏幕的用户 使用手册
进行设置,如下图所示为本文使用的ATK4384屏幕尺寸图。

另一处需要修改的地方如下所示,添加设备树对应的 设备驱动绑定信息。
.data = &vl050;_8048nt_c01,
}, {
.compatible = "winstar,wf35ltiacd",
.data = &winstar;_wf35ltiacd,
}, {// modify by kashine
.compatible = "alientek,alientek_4p3_inch",
.data = &alientek;_4p3_inch,
},{
/* Must be the last entry /
.compatible = "panel-dpi",
.data = &panel;_dpi,
}, {
/ sentinel */
}
3、内核驱动修改
以下为核心内容,本人尝试了 坑网、CSDN、荔枝派、芒果派 等的众多教程,历经多次内核修改与编译,最终整理出 关于F1C200s在
Linux5.7.1内核下的RGB驱动修改方法如下。主要修改文件为内核目录 /drivers/gpu/drm/sun4i/
文件夹下的三个文件,分别为 sun4i_tcon.c、sun4i_drv.c、sun4i_backend.c。
以下修改内容主要是为了使驱动适配F1C200s这款芯片。
可以根据代码中注释及前后内容,定位三个文件需要修改的地方。
// sun4i_backend.c文件修改
// modify by kashine
static const struct sun4i_backend_quirks suniv_backend_quirks = {
};
static const struct sun4i_backend_quirks sun4i_backend_quirks = {
.needs_output_muxing = true,
};
static const struct sun4i_backend_quirks sun5i_backend_quirks = {
};
static const struct sun4i_backend_quirks sun6i_backend_quirks = {
};
static const struct sun4i_backend_quirks sun7i_backend_quirks = {
.needs_output_muxing = true,
.supports_lowest_plane_alpha = true,
};
static const struct sun4i_backend_quirks sun8i_a33_backend_quirks = {
.supports_lowest_plane_alpha = true,
};
static const struct sun4i_backend_quirks sun9i_backend_quirks = {
};
static const struct of_device_id sun4i_backend_of_table[] = {
{// modify by kashine
.compatible = "allwinner,suniv-f1c100s-display-backend",
.data = &suniv;_backend_quirks,
},
{
.compatible = "allwinner,sun4i-a10-display-backend",
.data = &sun4i;_backend_quirks,
},
{
.compatible = "allwinner,sun5i-a13-display-backend",
.data = &sun5i;_backend_quirks,
},
{
.compatible = "allwinner,sun6i-a31-display-backend",
.data = &sun6i;_backend_quirks,
},
{
.compatible = "allwinner,sun7i-a20-display-backend",
.data = &sun7i;_backend_quirks,
},
{
.compatible = "allwinner,sun8i-a23-display-backend",
.data = &sun8i;_a33_backend_quirks,
},
{
.compatible = "allwinner,sun8i-a33-display-backend",
.data = &sun8i;_a33_backend_quirks,
},
{
.compatible = "allwinner,sun9i-a80-display-backend",
.data = &sun9i;_backend_quirks,
},
{ }
};
// sun4i_drv.c文件修改
static bool sun4i_drv_node_is_frontend(struct device_node *node)
{
// modify by kashine
return of_device_is_compatible(node, "allwinner,suniv-f1c100s-display-frontend") ||
of_device_is_compatible(node, "allwinner,sun4i-a10-display-frontend") ||
of_device_is_compatible(node, "allwinner,sun5i-a13-display-frontend") ||
of_device_is_compatible(node, "allwinner,sun6i-a31-display-frontend") ||
of_device_is_compatible(node, "allwinner,sun7i-a20-display-frontend") ||
of_device_is_compatible(node, "allwinner,sun8i-a23-display-frontend") ||
of_device_is_compatible(node, "allwinner,sun8i-a33-display-frontend") ||
of_device_is_compatible(node, "allwinner,sun9i-a80-display-frontend");
}
static const struct of_device_id sun4i_drv_of_table[] = {
{ .compatible = "allwinner,suniv-f1c100s-display-engine" },// modify by kashine
{ .compatible = "allwinner,sun4i-a10-display-engine" },
{ .compatible = "allwinner,sun5i-a10s-display-engine" },
{ .compatible = "allwinner,sun5i-a13-display-engine" },
{ .compatible = "allwinner,sun6i-a31-display-engine" },
{ .compatible = "allwinner,sun6i-a31s-display-engine" },
{ .compatible = "allwinner,sun7i-a20-display-engine" },
{ .compatible = "allwinner,sun8i-a23-display-engine" },
{ .compatible = "allwinner,sun8i-a33-display-engine" },
{ .compatible = "allwinner,sun8i-a83t-display-engine" },
{ .compatible = "allwinner,sun8i-h3-display-engine" },
{ .compatible = "allwinner,sun8i-r40-display-engine" },
{ .compatible = "allwinner,sun8i-v3s-display-engine" },
{ .compatible = "allwinner,sun9i-a80-display-engine" },
{ .compatible = "allwinner,sun50i-a64-display-engine" },
{ .compatible = "allwinner,sun50i-h6-display-engine" },
{ }
};
// sun4i_tcon.c文件修改
// modify by kashine
static const struct sun4i_tcon_quirks suniv_f1c100s_quirks = {
/*
- The F1C100s SoC has a second channel in TCON, but the clock input of
- it is not documented.
*/
.has_channel_0 = true,
//.has_channel_1 = true,
.dclk_min_div = 1,// Linux5.2不需要加,5.7.1不加该代码会白屏
};
static const struct sun4i_tcon_quirks sun4i_a10_quirks = {
.has_channel_0 = true,
.has_channel_1 = true,
.dclk_min_div = 4,
.set_mux = sun4i_a10_tcon_set_mux,
};
/* sun4i_drv uses this list to check if a device node is a TCON */
const struct of_device_id sun4i_tcon_of_table[] = {
{.compatible = "allwinner,suniv-f1c100s-tcon", .data = &suniv;_f1c100s_quirks },// modify by kashine
{ .compatible = "allwinner,sun4i-a10-tcon", .data = &sun4i;_a10_quirks },
{ .compatible = "allwinner,sun5i-a13-tcon", .data = &sun5i;_a13_quirks },
{ .compatible = "allwinner,sun6i-a31-tcon", .data = &sun6i;_a31_quirks },
{ .compatible = "allwinner,sun6i-a31s-tcon", .data = &sun6i;_a31s_quirks },
{ .compatible = "allwinner,sun7i-a20-tcon", .data = &sun7i;_a20_quirks },
{ .compatible = "allwinner,sun7i-a20-tcon0", .data = &sun7i;_a20_tcon0_quirks },
{ .compatible = "allwinner,sun7i-a20-tcon1", .data = &sun7i;_a20_quirks },
{ .compatible = "allwinner,sun8i-a23-tcon", .data = &sun8i;_a33_quirks },
{ .compatible = "allwinner,sun8i-a33-tcon", .data = &sun8i;_a33_quirks },
{ .compatible = "allwinner,sun8i-a83t-tcon-lcd", .data = &sun8i;_a83t_lcd_quirks },
{ .compatible = "allwinner,sun8i-a83t-tcon-tv", .data = &sun8i;_a83t_tv_quirks },
{ .compatible = "allwinner,sun8i-r40-tcon-tv", .data = &sun8i;_r40_tv_quirks },
{ .compatible = "allwinner,sun8i-v3s-tcon", .data = &sun8i;_v3s_quirks },
{ .compatible = "allwinner,sun9i-a80-tcon-lcd", .data = &sun9i;_a80_tcon_lcd_quirks },
{ .compatible = "allwinner,sun9i-a80-tcon-tv", .data = &sun9i;_a80_tcon_tv_quirks },
{ }
};
4、开机logo显示
使用 make menuconfig 打开图形化配置界面,打开Bootup logo,其中的 三个选项全部选中。
-> Device Drivers
-> Graphics support
-> Bootup logo (LOGO [=y])
-> Standard black and white Linux logo
-> Standard 16-color Linux logo
-> Standard 224-color Linux logo

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

三、RGB屏幕显示功能测试
修改完上述内核文件后, 重新编译, 编译所需的时间相比于初次编译要短很多。在uboot的 bootargs参数 中添加如下内容
可使内核输出更多drm相关信息, 便于调试:
drm.debug=0x1f debug
如图所示为开发板 上电启动 过程中 RGB屏幕显示的内容, 启动时左上角 显示Linux logo, 符合我们的预期。



进入Debian文件系统后,可以使用如下命令 查看日志的输出级别 (在Linux中日志一共分为8个等级,数值越小,优先级越高)下面的四个数字是由
kernel/printk.c 文件中定义的一个数组决定的。
cat /proc/sys/kernel/printk
默认输出7 4 1 7
上面四个数字的 含别如下:
控制台日志级别: 优先级高于该值的消息将被打印至控制台
默认的消息日志级别: 将用该优先级来打印没有优先级的消息
最低的控制台日志级别: 控制台日志级别可被设置的最小值(最高优先级)
默认的控制台日志级别: 控制台日志级别的缺省值
如果觉得开机之后输出的 日志信息太多 ,可以使用如下命令修改打印的日志信息级别,减少不必要的信息干扰。
屏蔽掉所有的内核printk打印
echo 0 4 1 7 > /proc/sys/kernel/printk
四、屏幕背光调节功能测试

通过 PE6管脚 输出PWM波,控制屏幕 背光引脚 ,进而控制屏幕亮度,本文在设备树中设置了 八个亮度等级, 通过在
脚本(.sh文件,并chomd权限) 中输入以下代码可以 控制亮度变化。 (这里有个小问题,输入零的时候并没有熄屏,留个小坑吧)
while true
do
for i in {7..1}
do
sleep 0.2
echo $i > /sys/class/backlight/backlight/brightness
done
for j in {1..7}
do
echo $j > /sys/class/backlight/backlight/brightness
sleep 0.2
done
done
五、主要参考内容
2.Lctech
Pi(F1C200S)4.3寸(480*272)16位RGB565LCD屏驱动适配 ;
3.解决f1c100s 主线Linux 升级到 4.19 之后的版本没有
framebuffer(fb0)设备问题(Linux5.2);
6.更换正点原子7寸RGB LCD(1024*600),启动失败
7.ttyS、ttySAC、tty、ttyn的区别_HeroKern的博客-
CSDN博客_ttytcu0和ttyths0的区别。
评论区