程序项目代做,有需求私信(vue、React、Java、爬虫、电路板设计、嵌入式linux等)

Rockchip RK3399 - DRM HDMI调试

----------------------------------------------------------------------------------------------------------------------------

开发板 :NanoPC-T4开发板
eMMC16GB
LPDDR34GB
显示屏 :15.6英寸HDMI接口显示屏
u-boot2023.04
linux6.3
----------------------------------------------------------------------------------------------------------------------------

一、烧录内核

1.1 配置内核

linux内核根目录下执行make menuconfig配置以下选项:

Device Drivers --->
  Graphics support --->
   	 <*> Direct Rendering Manager (XFree86 4.1.0 and higher DRI support)  ---> 
  	 <*>  DRM Support for Rockchip (DRM_ROCKCHIP [=y])     
     [*]   Rockchip VOP driver        # CONFIG_ROCKCHIP_VOP2
	 [ ]   Rockchip VOP2 driver       # CONFIG_ROCKCHIP_VOP
     [*]   Rockchip specific extensions for Analogix DP driver  # CONFIG_ROCKCHIP_ANALOGIX_DP
     [*]   Rockchip cdn DP  # CONFIG_ROCKCHIP_CDN_DP
     [*]   Rockchip specific extensions for Synopsys DW HDMI    # CONFIG_ROCKCHIP_DW_HDMI
     [*]   Rockchip specific extensions for Synopsys DW MIPI DSI  # CONFIG_ROCKCHIP_DW_MIPI_DSI
     [*]   Rockchip specific extensions for Innosilicon HDMI    # CONFIG_ROCKCHIP_INNO_HDMI 实际上RK3399并没有使用Innosilicon IP,可以不选
     [*]   Rockchip LVDS support   # CONFIG_ROCKCHIP_LVDS
     [ ]   Rockchip RGB support    # CONFIG_ROCKCHIP_RGB
     Display Interface Bridges  --->     # CONFIG_DRM_DW_HDMI取决于CONFIG_DRM_BRIDGE、DRM_DRM(默认开启)
     	<M> Synopsys Designware AHB Audio interface   # CONFIG_DRM_DW_HDMI_AHB_AUDIO
     	<*> Synopsys Designware I2S Audio interface   # CONFIG_DRM_DW_HDMI_I2S_AUDIO  HDMI音频
     	<M> Synopsys Designware GP Audio interface    # CONFIG_DRM_DW_HDMI_I2S_AUDIO
	    <*> Synopsis Designware CEC interface         # CONFIG_DRM_DW_HDMI_CEC
     
Device Drivers  ---> 
    PHY Subsystem  --->
    	<M> Rockchip INNO HDMI PHY Driver          

HDMI PHY使用的是DesignWare HDMI IP,并没有使用Innosilicon IP。因此可以不用选择Rockchip INNO HDMI PHY Driver

CONFIG_DRM_DW_HDMI对应的驱动位于drivers/gpu/drm/bridge/synopsys/dw-hdmi.c

有关HDMI音频配置可以参考文章:《Rockchip RK3399 - HDMI音频》。

1.2 保存配置

配置完内核之后记得保存配置:

img

存档:

root@zhengyang:/work/sambashare/rk3399/linux-6.3# mv rk3399_defconfig ./arch/arm64/configs/

重新配置内核(如果不想重新编译内核,可以存档一份到.config):

root@zhengyang:/work/sambashare/rk3399/linux-6.3# make rk3399_defconfig

1.3 编译内核

linux内核根目录下执行如下命令进行编译内核:

root@zhengyang:/work/sambashare/rk3399/linux-6.3# make -j8

u-boot-2023.04路径下的mkimage工具拷贝过来,然后在命令行使用mkimage工具编译即可:

root@zhengyang:/work/sambashare/rk3399/linux-6.3# cp ../u-boot-2023.04/tools/mkimage ./
root@zhengyang:/work/sambashare/rk3399/linux-6.3# ./mkimage -f kernel.its kernel.itb

1.4 通过tftp烧录内核

给开发板上电,同时连接上网线,进入uboot命令行。我们将内核拷贝到tftp文件目录:

root@zhengyang:/work/sambashare/rk3399/linux-6.3# cp kernel.itb /work/tftpboot/

接着给开发板上电。通过uboot命令行将kernel.itb下到内存地址0x10000000处:

=> tftp 0x10000000 kernel.itb

通过mmc write命令将内核镜像烧录到eMMC0x8000个扇区处:

=> mmc erase 0x8000 0xA000
=> mmc write 0x10000000 0x8000 0xA000
=> bootm

1.5 启动内核

将开发板和hdmi显示器(显示器支持分辨率是12560x1440@144Hz)通过hdmi线缆连接起来,然后给开发板上电启动。内核输入有关hdmi日志:

[    0.539951] platform ff940000.hdmi: Fixed dependency cycle(s) with /vop@ff8f0000/port/endpoint@2
[    0.549676] platform ff940000.hdmi: Fixed dependency cycle(s) with /vop@ff900000/port/endpoint@2
[    1.430309] rockchip-vop ff8f0000.vop: Adding to iommu group 2
[    1.437640] rockchip-vop ff900000.vop: Adding to iommu group 3
[    1.450511] rockchip-drm display-subsystem: bound ff8f0000.vop (ops vop_component_ops)
[    1.459516] [drm] unsupported AFBC format[3231564e]
[    1.466072] rockchip-drm display-subsystem: bound ff900000.vop (ops vop_component_ops)
[    1.475048] dwhdmi-rockchip ff940000.hdmi: supply avdd-0v9 not found, using dummy regulator
[    1.484573] dwhdmi-rockchip ff940000.hdmi: supply avdd-1v8 not found, using dummy regulator
[    4.136104] rockchip-drm display-subsystem: bound ff8f0000.vop (ops vop_component_ops)
[    4.146266] rockchip-drm display-subsystem: bound ff900000.vop (ops vop_component_ops)
[    4.155351] dwhdmi-rockchip ff940000.hdmi: supply avdd-0v9 not found, using dummy regulator
[    4.164983] dwhdmi-rockchip ff940000.hdmi: supply avdd-1v8 not found, using dummy regulator
[    4.174627] dwhdmi-rockchip ff940000.hdmi: Detected HDMI TX controller v2.11a with HDCP (DWC HDMI 2.0 TX PHY)
[    4.188847] rockchip-drm display-subsystem: bound ff940000.hdmi (ops dw_hdmi_rockchip_ops)
[    4.199257] [drm] Initialized rockchip 1.0.0 20140818 for display-subsystem on minor 0
[    4.331400] Console: switching to colour frame buffer device 240x67
[    4.382497] rockchip-drm display-subsystem: [drm] fb0: rockchipdrmfb frame buffer device
[    5.035286] [drm] Initialized panfrost 1.2.0 20180908 for ff9a0000.gpu on minor 1

二、hdmi调试

/dev/dri/ 目录下可以看到驱动注册的各个显卡,DRM设备节点为 /dev/dri/cardXX0-15的数值。

root@rk3399:~# ll /dev/dri/
drwxr-xr-x   2 root root        100 Mar 15 23:04 by-path/
crw-rw----+  1 root video  226,   0 Mar 15 23:07 card0
crw-rw----+  1 root video  226,   1 Mar 15 23:04 card1
crw-rw----+  1 root render 226, 128 Mar 15 23:04 renderD128
root@rk3399:~# ll /sys/class/drm
lrwxrwxrwx  1 root root    0 Mar 15 23:04 card0 -> ../../devices/platform/display-subsystem/drm/card0/
lrwxrwxrwx  1 root root    0 Mar 15 23:04 card0-HDMI-A-1 -> ../../devices/platform/display-subsystem/drm/card0/card0-HDMI-A-1/
lrwxrwxrwx  1 root root    0 Mar 15 23:04 card1 -> ../../devices/platform/ff9a0000.gpu/drm/card1/
lrwxrwxrwx  1 root root    0 Mar 15 23:04 renderD128 -> ../../devices/platform/ff9a0000.gpu/drm/renderD128/
-r--r--r--  1 root root 4096 Mar 15 23:04 version

sysfs文件系统中的card0-HDMI-A-1代表的是hdmi显示设备,是由drm_sysfs_connector_add函数创建的。查看card0-HDMI-A-1目录结构;

root@rk3399:~# ll /sys/class/drm/card0-HDMI-A-1/
lrwxrwxrwx 1 root root    0 Mar 15 23:14 ddc -> ../../../../ff160000.i2c/i2c-7/
lrwxrwxrwx 1 root root    0 Mar 15 23:14 device -> ../../card0/
-r--r--r-- 1 root root 4096 Mar 15 23:14 dpms
-r--r--r-- 1 root root    0 Mar 15 23:14 edid
-r--r--r-- 1 root root 4096 Mar 15 23:04 enabled
-r--r--r-- 1 root root 4096 Mar 15 23:14 modes
drwxr-xr-x 2 root root    0 Mar 15 23:14 power/
-rw-r--r-- 1 root root 4096 Mar 15 23:04 status
lrwxrwxrwx 1 root root    0 Mar 15 23:04 subsystem -> ../../../../../../class/drm/
-rw-r--r-- 1 root root 4096 Mar 15 23:04 uevent

其中:

  • ddchdmi显示数据通道,指向i2c7,用来获取edidhdcp密钥等内容;
  • device:指向card0
  • edid:存储hdmi显示器的扩展显示标识数据;
  • enabledhdmi接口是否被启用或禁用;
  • modes:连接的hdmi显示器以及当前hdmi控制器同时支持的分辨率列表;
  • statushdmi接口连接状态的信息;

需要注意:下文中提到的分辨率,指的是就是显示模式。

2.1 查看hdmi使能状态

查看hdmi输出使能状态:

root@rk3399:~# cat /sys/class/drm/card0-HDMI-A-1/enabled
enabled

如果将hdmi线拔掉:

root@rk3399:~# cat /sys/class/drm/card0-HDMI-A-1/enabled
disabled

在使用cat命令读取enabled文件时调用enabled_show方法;

static ssize_t enabled_show(struct device *device,
                            struct device_attribute *attr,
                           char *buf)
{
        struct drm_connector *connector = to_drm_connector(device);
        bool enabled;

        enabled = READ_ONCE(connector->encoder);

        return sysfs_emit(buf, enabled ? "enabled\n" : "disabled\n");
}

2.2 查看hdmi连接状态

查看hdmi的插拔连接状态;

root@rk3399:~# cat /sys/class/drm/card0-HDMI-A-1/status
connected

如果将hdmi线拔掉:

root@rk3399:~# cat /sys/class/drm/card0-HDMI-A-1/status
disconnected

在使用cat命令读取status文件时调用status_show方法;

static ssize_t status_show(struct device *device,
                           struct device_attribute *attr,
                           char *buf)
{
        struct drm_connector *connector = to_drm_connector(device);
        enum drm_connector_status status;

        status = READ_ONCE(connector->status);

        return sysfs_emit(buf, "%s\n",
                          drm_get_connector_status_name(status));
}

2.3 查看edid

通过如下命令可以查看edid信息,一共256个字节;

root@rk3399:/# cat /sys/class/drm/card0-HDMI-A-1/edid > /data/edid.bin
root@rk3399:/# hexdump -C  /data/edid.bin
00000000  00 ff ff ff ff ff ff 00  35 34 00 00 01 01 01 01  |........54......|
00000010  00 20 01 03 81 00 00 78  ee 8c 75 a9 54 45 98 22  |. .....x..u.TE."|
00000020  1e 50 54 2f cf 00 71 40  81 c0 81 80 95 00 a9 c0  |.PT/..q@........|
00000030  b3 00 d1 c0 d1 00 d3 bc  00 a0 a0 a0 29 50 30 20  |............)P0 |
00000040  35 00 b9 88 21 00 00 1a  56 5e 00 a0 a0 a0 29 50  |5...!...V^....)P|
00000050  30 20 35 00 b9 88 21 00  00 1a 67 e2 00 a0 a0 a0  |0 5...!...g.....|
00000060  29 50 30 20 35 00 b9 88  21 00 00 1a 00 00 00 fc  |)P0 5...!.......|
00000070  00 4d 45 49 54 49 41 4e  48 41 4f 0a 20 20 01 0b  |.MEITIANHAO.  ..|
00000080  02 03 3a f2 4f 04 05 10  13 14 1f 6c 6c 6c 27 6c  |..:.O......lll'l|
00000090  6c 6c 4b 4c e2 00 d5 e3  05 c0 00 23 09 7f 07 83  |llKL.......#....|
000000a0  01 00 00 67 03 0c 00 10  00 38 78 e6 06 05 01 69  |...g.....8x....i|
000000b0  69 4f 67 d8 5d c4 01 76  c0 00 02 3a 80 18 71 38  |iOg.]..v...:..q8|
000000c0  2d 40 58 2c 25 00 58 c3  10 00 00 1e d4 bc 00 a0  |-@X,%.X.........|
000000d0  a0 a0 29 50 30 20 35 00  b9 88 21 00 00 1e 98 e2  |..)P0 5...!.....|
000000e0  00 a0 a0 a0 29 50 30 20  35 00 b9 88 21 00 00 1e  |....)P0 5...!...|
000000f0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 c4  |................|

这里我们尝试通过EDID Manager工具去解析,首先需要去下载EDID Manager工具,然后将edid.bin下载到windows系统上,并加载文件解析内容如下:

			Time: 21:03:42
			Date: 2023年11月9日
			EDID Manager Version: 1.0.0.14
	___________________________________________________________________

	Block 0 (EDID Base Block), Bytes 0 - 127,  128  BYTES OF EDID CODE:

		        0   1   2   3   4   5   6   7   8   9   
		000  |  00  FF  FF  FF  FF  FF  FF  00  35  34
		010  |  00  00  01  01  01  01  00  20  01  03
		020  |  81  00  00  78  EE  8C  75  A9  54  45
		030  |  98  22  1E  50  54  2F  CF  00  71  40
		040  |  81  C0  81  80  95  00  A9  C0  B3  00
		050  |  D1  C0  D1  00  D3  BC  00  A0  A0  A0
		060  |  29  50  30  20  35  00  B9  88  21  00
		070  |  00  1A  56  5E  00  A0  A0  A0  29  50
		080  |  30  20  35  00  B9  88  21  00  00  1A
		090  |  67  E2  00  A0  A0  A0  29  50  30  20
		100  |  35  00  B9  88  21  00  00  1A  00  00
		110  |  00  FC  00  4D  45  49  54  49  41  4E
		120  |  48  41  4F  0A  20  20  01  0B

(8-9)    	ID Manufacture Name : MIT
(10-11)  	ID Product Code     : 0000
(12-15)  	ID Serial Number    : N/A
(16)     	Week of Manufacture : 0
(17)     	Year of Manufacture : 2022

(18)     	EDID Version Number : 1
(19)     	EDID Revision Number: 3

(20)     	Video Input Definition : Digital
			DFP 1.x Compatible

(21)     	Maximum Horizontal Image Size: 0 cm
(22)     	Maximum Vertical Image Size  : 0 cm
(23)     	Display Gamma                : 2.20
(24)     	Power Management and Supported Feature(s):
			Standby, Suspend, Active Off/Very Low Power, RGB Color, sRGB, Preferred Timing Mode

(25-34)  	Color Characteristics
			Red Chromaticity   :  Rx = 0.658  Ry = 0.328
			Green Chromaticity :  Gx = 0.269  Gy = 0.594
			Blue Chromaticity  :  Bx = 0.134  By = 0.120
			Default White Point:  Wx = 0.313  Wy = 0.329

(35)     	Established Timings I

			640 x 480 @ 60Hz (IBM, VGA)
			640 x 480 @ 72Hz (VESA)
			640 x 480 @ 75Hz (VESA)
			800 x 600 @ 56Hz (VESA)
			800 x 600 @ 60Hz (VESA)

(36)     	Established Timings II

			800 x 600 @ 72Hz (VESA)
			800 x 600 @ 75Hz (VESA)
			1024 x 768 @ 60Hz (VESA)
			1024 x 768 @ 70Hz(VESA)
			1024 x 768 @ 75Hz (VESA)
			1280 x 1024 @ 75Hz (VESA)

(37)     	Manufacturer's Timings (Not Used)

(38-53)  	Standard Timings

			1152x864 @ 60 Hz (4:3 Aspect Ratio)
			1280x720 @ 60 Hz (16:9 Aspect Ratio)
			1280x1024 @ 60 Hz (5:4 Aspect Ratio)
			1440x900 @ 60 Hz (16:10 Aspect Ratio)
			1600x900 @ 60 Hz (16:9 Aspect Ratio)
			1680x1050 @ 60 Hz (16:10 Aspect Ratio)
			1920x1080 @ 60 Hz (16:9 Aspect Ratio)
			1920x1200 @ 60 Hz (16:10 Aspect Ratio)

(54-71)  	Detailed Descriptor #1: Preferred Detailed Timing (2560x1440 @ 120Hz)

			Pixel Clock            : 483.39 MHz
			Horizontal Image Size  : 697 mm
			Vertical Image Size    : 392 mm
			Refresh Mode           : Non-interlaced
			Normal Display, No Stereo

			Horizontal:
				Active Time     : 2560 Pixels
				Blanking Time   : 160 Pixels
				Sync Offset     : 48 Pixels
				Sync Pulse Width: 32 Pixels
				Border          : 0 Pixels
				Frequency       : 177 kHz

			Vertical:
				Active Time     : 1440 Lines
				Blanking Time   : 41 Lines
				Sync Offset     : 3 Lines
				Sync Pulse Width: 5 Lines
				Border          : 0 Lines

			Digital Separate, Horizontal Polarity (+), Vertical Polarity (-)

			Modeline: "2560x1440" 483.390 2560 2608 2640 2720 1440 1443 1448 1481 +hsync -vsync

(72-89)  	Detailed Descriptor #2: Detailed Timing (2560x1440 @ 60Hz)

			Pixel Clock            : 241.5 MHz
			Horizontal Image Size  : 697 mm
			Vertical Image Size    : 392 mm
			Refresh Mode           : Non-interlaced
			Normal Display, No Stereo

			Horizontal:
				Active Time     : 2560 Pixels
				Blanking Time   : 160 Pixels
				Sync Offset     : 48 Pixels
				Sync Pulse Width: 32 Pixels
				Border          : 0 Pixels
				Frequency       : 88 kHz

			Vertical:
				Active Time     : 1440 Lines
				Blanking Time   : 41 Lines
				Sync Offset     : 3 Lines
				Sync Pulse Width: 5 Lines
				Border          : 0 Lines

			Digital Separate, Horizontal Polarity (+), Vertical Polarity (-)

			Modeline: "2560x1440" 241.500 2560 2608 2640 2720 1440 1443 1448 1481 +hsync -vsync

(90-107) 	Detailed Descriptor #3: Detailed Timing (2560x1440 @ 144Hz)

			Pixel Clock            : 579.59 MHz
			Horizontal Image Size  : 697 mm
			Vertical Image Size    : 392 mm
			Refresh Mode           : Non-interlaced
			Normal Display, No Stereo

			Horizontal:
				Active Time     : 2560 Pixels
				Blanking Time   : 160 Pixels
				Sync Offset     : 48 Pixels
				Sync Pulse Width: 32 Pixels
				Border          : 0 Pixels
				Frequency       : 213 kHz

			Vertical:
				Active Time     : 1440 Lines
				Blanking Time   : 41 Lines
				Sync Offset     : 3 Lines
				Sync Pulse Width: 5 Lines
				Border          : 0 Lines

			Digital Separate, Horizontal Polarity (+), Vertical Polarity (-)

			Modeline: "2560x1440" 579.590 2560 2608 2640 2720 1440 1443 1448 1481 +hsync -vsync

(108-125)	Detailed Descriptor #4: Monitor Name

			Monitor Name: MEITIANHAO

(126-127)	Extension Flag and Checksum

			Extension Block(s)  : 1
			Checksum Value      : 11

	___________________________________________________________________

	Block 1 ( CEA-861 Extension Block), Bytes 128 - 255,  128  BYTES OF EDID CODE:

		        0   1   2   3   4   5   6   7   8   9   
		128  |  02  03  3A  F2  4F  04  05  10  13  14
		138  |  1F  6C  6C  6C  27  6C  6C  6C  4B  4C
		148  |  E2  00  D5  E3  05  C0  00  23  09  7F
		158  |  07  83  01  00  00  67  03  0C  00  10
		168  |  00  38  78  E6  06  05  01  69  69  4F
		178  |  67  D8  5D  C4  01  76  C0  00  02  3A
		188  |  80  18  71  38  2D  40  58  2C  25  00
		198  |  58  C3  10  00  00  1E  D4  BC  00  A0
		208  |  A0  A0  29  50  30  20  35  00  B9  88
		218  |  21  00  00  1E  98  E2  00  A0  A0  A0
		228  |  29  50  30  20  35  00  B9  88  21  00
		238  |  00  1E  00  00  00  00  00  00  00  00
		248  |  00  00  00  00  00  00  00  C4

(128-130)	Extension Header

			Revision Number    :	3
			DTD Starting Offset:	58

(131)    	Display Support

			DTV Underscan, Basic Audio, YCbCr 4:4:4, YCbCr 4:2:2
			Number of Native Formats: 2

(132-147)	Video Data Block

			1280x720p @ 59.94/60Hz - HDTV (16:9, 1:1)
			1920x1080i @ 59.94/60Hz - HDTV (16:9, 1:1)
			1920x1080p @ 59.94/60Hz - HDTV (16:9, 1:1)
			1280x720p  @ 50Hz - HDTV  (16:9, 1:1)
			1920x1080i @ 50Hz - HDTV (16:9, 1:1)
			1920x1080p @ 50Hz - HDTV (16:9, 1:1)
			Reserved for the Future
			Reserved for the Future
			Reserved for the Future
			1920x1080i (1250 total) - HDTV 50Hz (16:9, 1:1)
			Reserved for the Future
			Reserved for the Future
			Reserved for the Future
			Reserved for the Future
			Reserved for the Future

(148-150)	Video Capability Data Block (VCDB)


(151-154)	Colorimetry Data Block
2.3.1 Established Timings

Established Timings其定义在drivers/gpu/drm/drm_edid.c文件的edid_est_modes数组中:

/*
 * These more or less come from the DMT spec.  The 720x400 modes are
 * inferred from historical 80x25 practice.  The 640x480@67 and 832x624@75
 * modes are old-school Mac modes.  The EDID spec says the 1152x864@75 mode
 * should be 1152x870, again for the Mac, but instead we use the x864 DMT
 * mode.
 *
 * The DMT modes have been fact-checked; the rest are mild guesses.
 */
static const struct drm_display_mode edid_est_modes[] = {
        { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 40000, 800, 840,
                   968, 1056, 0, 600, 601, 605, 628, 0,
                   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 800x600@60Hz 支持 */
        { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 36000, 800, 824,
                   896, 1024, 0, 600, 601, 603,  625, 0,
                   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 800x600@56Hz 支持 */
        { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 31500, 640, 656,
                   720, 840, 0, 480, 481, 484, 500, 0,
                   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 640x480@75Hz 支持 */
        { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 31500, 640, 664,
                   704,  832, 0, 480, 489, 492, 520, 0,
                   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 640x480@72Hz 支持 */
        { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 30240, 640, 704,
                   768,  864, 0, 480, 483, 486, 525, 0,
                   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 640x480@67Hz */
        { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25175, 640, 656,
                   752, 800, 0, 480, 490, 492, 525, 0,
                   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 640x480@60Hz 支持  */
        { DRM_MODE("720x400", DRM_MODE_TYPE_DRIVER, 35500, 720, 738,
                   846, 900, 0, 400, 421, 423,  449, 0,
                   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 720x400@88Hz */
        { DRM_MODE("720x400", DRM_MODE_TYPE_DRIVER, 28320, 720, 738,
                   846,  900, 0, 400, 412, 414, 449, 0,
                   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 720x400@70Hz */
        { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 135000, 1280, 1296,
                   1440, 1688, 0, 1024, 1025, 1028, 1066, 0,
                   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 1280x1024@75Hz 支持 */
        { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 78750, 1024, 1040,
                   1136, 1312, 0,  768, 769, 772, 800, 0,
                   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 1024x768@75Hz 支持 */
        { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 75000, 1024, 1048,
                   1184, 1328, 0,  768, 771, 777, 806, 0,
                   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 1024x768@70Hz 支持 */
        { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 65000, 1024, 1048,
                   1184, 1344, 0,  768, 771, 777, 806, 0,
                   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 1024x768@60Hz 支持 */
        { DRM_MODE("1024x768i", DRM_MODE_TYPE_DRIVER,44900, 1024, 1032,
                   1208, 1264, 0, 768, 768, 776, 817, 0,
                   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_INTERLACE) }, /* 1024x768@43Hz */
        { DRM_MODE("832x624", DRM_MODE_TYPE_DRIVER, 57284, 832, 864,
                   928, 1152, 0, 624, 625, 628, 667, 0,
                   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 832x624@75Hz */
        { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 49500, 800, 816,
                   896, 1056, 0, 600, 601, 604,  625, 0,
                   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 800x600@75Hz 支持 */
        { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 50000, 800, 856,
                   976, 1040, 0, 600, 637, 643, 666, 0,
                   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 800x600@72Hz 支持 */
        { DRM_MODE("1152x864", DRM_MODE_TYPE_DRIVER, 108000, 1152, 1216,
                   1344, 1600, 0,  864, 865, 868, 900, 0,
                   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 1152x864@75Hz */
};

其中我使用的这款hdmi显示器支持的Established Timings时序有:

  • 640x480@60Hz (IBM, VGA)

  • 640x480@72Hz (VESA);

  • 640x480@75Hz (VESA);

  • 800x600@56Hz (VESA);

  • 800x600@60Hz (VESA);

  • 800x600@72Hz (VESA);

  • 800x600@75Hz (VESA);

  • 1024x768@60Hz (VESA);

  • 1024x768@70Hz(VESA);

  • 1024x768@75Hz (VESA);

  • 1280x1024@75Hz (VESA)

2.3.2 Standard Timings

Standard Timings其定义在drivers/gpu/drm/drm_edid.c文件的drm_dmt_modes数组中,由于数组元素比较多,这里就不一一列出了,只列出部分:

static const struct drm_display_mode drm_dmt_modes[] = {
	/* 0x55 - 1280x720@60Hz */
	{ DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 1390,
			   1430, 1650, 0, 720, 725, 730, 750, 0,
			   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
	/* 0x23 - 1280x1024@60Hz */
	{ DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 108000, 1280, 1328,
			   1440, 1688, 0, 1024, 1025, 1028, 1066, 0,
			   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
	/* 0x2f - 1440x900@60Hz */
	{ DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 106500, 1440, 1520,
			   1672, 1904, 0, 900, 903, 909, 934, 0,
			   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
	/* 0x53 - 1600x900@60Hz */
	{ DRM_MODE("1600x900", DRM_MODE_TYPE_DRIVER, 108000, 1600, 1624,
			   1704, 1800, 0, 900, 901, 904, 1000, 0,
			   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
	/* 0x3a - 1680x1050@60Hz */
	{ DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 146250, 1680, 1784,
			   1960, 2240, 0, 1050, 1053, 1059, 1089, 0,
			   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
	/* 0x52 - 1920x1080@60Hz */
	{ DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2008,
			   2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
			   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
	/* 0x45 - 1920x1200@60Hz */
	{ DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 193250, 1920, 2056,
			   2256, 2592, 0, 1200, 1203, 1209, 1245, 0,
			   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
    ......
}

其中我使用的这款hdmi显示器支持的 Standard Timings时序有:

  • 1152x864@60Hz (4:3 Aspect Ratio)
  • 1280x720@60Hz (16:9 Aspect Ratio)
  • 1280x1024@60Hz (5:4 Aspect Ratio);
  • 1440x900@60Hz (16:10 Aspect Ratio);
  • 1600x900@60Hz (16:9 Aspect Ratio)
  • 1680x1050@60Hz (16:10 Aspect Ratio);
  • 1920x1080@60Hz (16:9 Aspect Ratio);
  • 1920x1200@60Hz (16:10 Aspect Ratio)

需要注意的是1152x864@60Hz并没有在drm_dmt_modes数组中定义,如果想要支持该显示模式,需要我们自己扩展。

2.3.3 Detailed Timings

此外,我使用的这款hdmi显示器支持的 Detailed Timings时序有:

  • 2560x1440@120Hz最佳时序;
  • 2560x1440@60Hz
  • 2560x1440@144Hz

2560x1440@120Hz为例,具体描述信息如下:

(54-71)  	Detailed Descriptor #1: Preferred Detailed Timing (2560x1440 @ 120Hz)

			Pixel Clock            : 483.39 MHz
			Horizontal Image Size  : 697 mm
			Vertical Image Size    : 392 mm
			Refresh Mode           : Non-interlaced
			Normal Display, No Stereo

			Horizontal:
				Active Time     : 2560 Pixels
				Blanking Time   : 160 Pixels
				Sync Offset     : 48 Pixels
				Sync Pulse Width: 32 Pixels
				Border          : 0 Pixels
				Frequency       : 177 kHz

			Vertical:
				Active Time     : 1440 Lines
				Blanking Time   : 41 Lines
				Sync Offset     : 3 Lines
				Sync Pulse Width: 5 Lines
				Border          : 0 Lines

			Digital Separate, Horizontal Polarity (+), Vertical Polarity (-)

			Modeline: "2560x1440" 483.390 2560 2608 2640 2720 1440 1443 1448 1481 +hsync -vsync
2.3.4 Video Data Block

edid的扩展块Video Data Block中也定义了支持的显示时序有:

  • 1280x720p @ 59.94/60Hz - HDTV (16:9, 1:1)
  • 1920x1080i @ 59.94/60Hz - HDTV (16:9, 1:1)
  • 1920x1080p @ 59.94/60Hz - HDTV (16:9, 1:1)
  • 1280x720p @ 50Hz - HDTV (16:9, 1:1);
  • 1920x1080i @ 50Hz - HDTV (16:9, 1:1)
  • 1920x1080p @ 50Hz - HDTV (16:9, 1:1)
  • 1920x1080i (1250 total) - HDTV 50Hz (16:9, 1:1)

这里我们大概介绍一下p和i的含义:p代表的是逐行扫描(Progressive scan),而i代表着是隔行扫描(interlaced scan),具体的区别是:逐行扫描是按照顺序一个一个的扫描;而隔行扫描是对奇数和偶数分别进行扫描。

因此1080i只需要1080p一半的带宽,因此在电视信号上十分适合表现非常复杂的场景,比如纪录片的野生动物题材,但是1080p在画面的表现会更加的平滑,不过一般情况下1080p的画面效果是优于1080i,所以在播放的选择上还是1080p比较好。

默认情况下我们平时所说的1920*1080指的就是1920x1080p

2.4 分辨率

查看连接的hdmi显示器以及当前hdmi控制器同时支持的分辨率列表;;

root@rk3399:~#  cat /sys/class/drm/card0-HDMI-A-1/modes
1920x1080          # 1920x1080@60Hz
1920x1080          
1920x1080
1920x1080i        
1920x1080
1920x1080
1920x1080i         
1600x900           # 1600x900@60Hz
1280x1024          # 1280x1024@60Hz
1280x720           # 1280x720p@60Hz 
1280x720           
1280x720          
1024x768           # 1024x768@60Hz
800x600            # 800x600@60Hz
800x600            # 800x600@56Hz

需要注意的是:为啥会看到多个重复的分辨率呢?实际上这里输出的是显示模式的名称,同样名称是800x600,实际上他们的刷新率、屏幕扫描方式可能是不一样的,比如:800x600@56Hz800x600@60Hz

在使用cat命令读取modes文件时调用modes_show方法;

static ssize_t modes_show(struct device *device,
                           struct device_attribute *attr,
                           char *buf)
{
        struct drm_connector *connector = to_drm_connector(device);
        struct drm_display_mode *mode;
        int written = 0;

        mutex_lock(&connector->dev->mode_config.mutex);
    	// 遍历connector支持的modes
        list_for_each_entry(mode, &connector->modes, head) {
            	// 写入到buf 在上一篇博客我们说过显示模式的命名规则为:%dx%d%s 第一个参数为:mode->hdisplay  第二个参数为:mode->vdisplay 第三个参数为:i/''(取决于mode->flags是否设置了DRM_MODE_FLAG_INTERLACE隔行扫描)
                written += scnprintf(buf + written, PAGE_SIZE - written, "%s\n",
                                    mode->name);
        }
        mutex_unlock(&connector->dev->mode_config.mutex);

        return written;
}

在上一篇博客中我们介绍了drm_add_edid_modes函数会探测hdmi显示器支持的显示模式,并添加到connectorprobed_modes 链表;

connector->modes链表中的显示模式实际上是由drm_helper_probe_single_connector_modes函数从probed_modes链表中移动过去的,并通过调用一系列的mode_validae方法筛选之后的结果,其中有一个至关重要的校验函数drm_bridge_funcs.mode_valid,其会调用dw_hdmi_bridge_mode_valid函数进行校验;

static enum drm_mode_status
dw_hdmi_rockchip_mode_valid(struct dw_hdmi *hdmi, void *data,
                            const struct drm_display_info *info,
                            const struct drm_display_mode *mode)
{
        const struct dw_hdmi_mpll_config *mpll_cfg = rockchip_mpll_cfg;
        int pclk = mode->clock * 1000;    // 计算得到像素时钟频率
        bool valid = false;
        int i;
		// 遍历mpll_cfg像素时钟,查找匹配的时钟
        for (i = 0; mpll_cfg[i].mpixelclock != (~0UL); i++) {
                if (pclk == mpll_cfg[i].mpixelclock) {
                        valid = true;
                        break;
                }
        }

        return (valid) ? MODE_OK : MODE_BAD;
}


static enum drm_mode_status
dw_hdmi_bridge_mode_valid(struct drm_bridge *bridge,
                          const struct drm_display_info *info,
                          const struct drm_display_mode *mode)
{
        struct dw_hdmi *hdmi = bridge->driver_private;
        const struct dw_hdmi_plat_data *pdata = hdmi->plat_data;
        enum drm_mode_status mode_status = MODE_OK;

        /* We don't support double-clocked modes */
        if (mode->flags & DRM_MODE_FLAG_DBLCLK)
                return MODE_BAD;

        if (pdata->mode_valid)
        		// 调用dw_hdmi_rockchip_mode_valid
                mode_status = pdata->mode_valid(hdmi, pdata->priv_data, info, 
                                                mode);

        return mode_status;
}

通过遍历rockchip_mpll_cfg,查找是否支持当前显示模式的像素时钟频率,如果匹配不到,也会不支持该显示模式。

当然,除了上面的校验外,在解析edidStandard Timings也会去drm_dmt_modes数组查找匹配的标准显示模式,如果匹配不到,也会不支持该显示模式。

因此命令cat /sys/class/drm/card0-HDMI-A-1/modes看到的显示模式个数是远远少于edid中看到的hdmi显示器支持的显示模式。

2.4.1 查看当前分辨率

在桌面系统打开终端,运行如下命令查看当前分辨率:

root@rk3399:/data# xrandr
Screen 0: minimum 320 x 200, current 1920 x 1080, maximum 4096 x 4096
HDMI-1 connected primary 1920x1080+0+0 (normal left inverted right x axis y axis) 697mm x 392mm
   1920x1080     60.00    60.00*   50.00
   1920x1080i    60.00    50.00
   1600x900      60.00
   1280x1024     60.02
   1280x720      60.00    50.00
   1024x768      60.00
   800x600       60.32    56.25

可以看到当前分辨率为1920x1080,实际上我们从edid信息中了解到我们使用的hdmi显示器的最佳时序是2560x1440@120Hz

然而这里默认确是1920x1080,这主要是因为我们的驱动中并没有支持2560x1440的分辨率。因此我们需要新增2560x1440分辨率时序。

2.4.2 设置分辨率

如果要设置分辨率为1600X9000@60Hz,在桌面系统终端运行如下命令:

root@rk3399:/# xrandr --output HDMI-1 --mode 1600x900 --refresh 60
2.4.3 设置HDMI输出边界

For example, the transformation scaling horizontal coordinates by 0.8, vertical coordinates by 1.04 and moving the screen by 35 pixels right and 19 pixels down

root@rk3399:/# xrandr --output HDMI-1 --transform 0.80,0,-35,0,1.04,-19,0,0,1

2.5 modetest

安装modetest

root@rk3399:/# cd /data/
root@rk3399:/data# wget https://gitlab.freedesktop.org/mesa/drm/-/archive/libdrm-2.4.105/drm-libdrm-2.4.105.tar.gz
root@rk3399:/data# tar -zvxf drm-libdrm-2.4.105.tar.gz
root@rk3399:/data# apt-get install meson
root@rk3399:/data# cd drm-libdrm-2.4.105
root@rk3399:/data/drm-libdrm-2.4.105# meson builddir/
root@rk3399:/data/drm-libdrm-2.4.105# ninja -C builddir install
root@rk3399:/data/drm-libdrm-2.4.105# cp builddir/tests/modetest/modetest /usr/bin/

查看帮助信息:

root@rk3399:/data/drm-libdrm-2.4.105#  modetest -h
usage: modetest [-acDdefMPpsCvrw]

 Query options:

        -c      list connectors
        -e      list encoders
        -f      list framebuffers
        -p      list CRTCs and planes (pipes)

 Test options:

        -P <plane_id>@<crtc_id>:<w>x<h>[+<x>+<y>][*<scale>][@<format>]  set a plane
        -s <connector_id>[,<connector_id>][@<crtc_id>]:[#<mode index>]<mode>[-<vrefresh>][@<format>]    set a mode
        -C      test hw cursor
        -v      test vsynced page flipping
        -r      set the preferred mode for all connectors
        -w <obj_id>:<prop_name>:<value> set property
        -a      use atomic API
        -F pattern1,pattern2    specify fill patterns

 Generic options:

        -d      drop master after mode set
        -M module       use the given driver
        -D device       use the given device

        Default is to dump all info.

2.5.1 modetest -c

查看connector的信息:

root@rk3399:/# modetest -c
trying to open device 'i915'...failed
trying to open device 'amdgpu'...failed
trying to open device 'radeon'...failed
trying to open device 'nouveau'...failed
trying to open device 'vmwgfx'...failed
trying to open device 'omapdrm'...failed
trying to open device 'exynos'...failed
trying to open device 'tilcdc'...failed
trying to open device 'msm'...failed
trying to open device 'sti'...failed
trying to open device 'tegra'...failed
trying to open device 'imx-drm'...failed
trying to open device 'rockchip'...failed
trying to open device 'atmel-hlcdc'...failed
trying to open device 'fsl-dcu-drm'...failed
trying to open device 'vc4'...failed
trying to open device 'virtio_gpu'...failed
trying to open device 'mediatek'...failed
trying to open device 'meson'...failed
trying to open device 'pl111'...failed
trying to open device 'stm'...failed
trying to open device 'sun4i-drm'...failed
trying to open device 'armada-drm'...failed
trying to open device 'komeda'...failed
trying to open device 'imx-dcss'...failed
trying to open device 'mxsfb-drm'...failed
no device found

modetest测试失败,原因:/dev/dri/card0被占用。需要关闭系统原有的显示进程,方法:

root@rk3399:/# ps -A | grep Xorg    # 显示进程
   4828 tty2     00:00:06 Xorg
root@rk3399:/# killall Xorg & modetest -M rockchip -c   # 如果一次没有kill Xorg成功,多试几次
[1] 6726
Connectors:
id      encoder status          name            size (mm)       modes   encoders
52      51      connected       HDMI-A-1        0x0             12      51
  modes:
        index name refresh (Hz) hdisp hss hse htot vdisp vss vse vtot
  #0 1920x1080 60.00 1920 2008 2052 2200 1080 1082 1087 1125 148500 flags: phsync, pvsync; type: driver
  #1 1920x1080 60.00 1920 2008 2052 2200 1080 1084 1089 1125 148500 flags: phsync, pvsync; type: driver
  #2 1920x1080i 30.00 1920 2008 2052 2200 1080 1084 1094 1125 74250 flags: phsync, pvsync, interlace; type: driver
  #3 1920x1080 50.00 1920 2448 2492 2640 1080 1084 1089 1125 148500 flags: phsync, pvsync; type: driver
  #4 1920x1080i 25.00 1920 2448 2492 2640 1080 1084 1094 1125 74250 flags: phsync, pvsync, interlace; type: driver
  #5 1600x900 60.00 1600 1624 1704 1800 900 901 904 1000 108000 flags: phsync, pvsync; type: driver
  #6 1280x1024 60.02 1280 1328 1440 1688 1024 1025 1028 1066 108000 flags: phsync, pvsync; type: driver
  #7 1280x720 60.00 1280 1390 1430 1650 720 725 730 750 74250 flags: phsync, pvsync; type: driver
  #8 1280x720 50.00 1280 1720 1760 1980 720 725 730 750 74250 flags: phsync, pvsync; type: driver
  #9 1024x768 60.00 1024 1048 1184 1344 768 771 777 806 65000 flags: nhsync, nvsync; type: driver
  #10 800x600 60.32 800 840 968 1056 600 601 605 628 40000 flags: phsync, pvsync; type: driver
  #11 800x600 56.25 800 824 896 1024 600 601 603 625 36000 flags: phsync, pvsync; type: driver
  props:
        1 EDID:
                flags: immutable blob
                blobs:

                value:
                        00ffffffffffff003534000001010101
                        0020010381000078ee8c75a954459822
                        1e50542fcf00714081c081809500a9c0
                        b300d1c0d100d3bc00a0a0a029503020
                        3500b9882100001a565e00a0a0a02950
                        30203500b9882100001a67e200a0a0a0
                        295030203500b9882100001a000000fc
                        004d45495449414e48414f0a2020010b
                        02033af24f04051013141f6c6c6c276c
                        6c6c4b4ce200d5e305c00023097f0783
                        01000067030c0010003878e606050169
                        694f67d85dc40176c000023a80187138
                        2d40582c250058c31000001ed4bc00a0
                        a0a0295030203500b9882100001e98e2
                        00a0a0a0295030203500b9882100001e
                        000000000000000000000000000000c4
        2 DPMS:
                flags: enum
                enums: On=0 Standby=1 Suspend=2 Off=3
                value: 0
        5 link-status:
                flags: enum
                enums: Good=0 Bad=1
                value: 0
        6 non-desktop:
                flags: immutable range
                values: 0 1
                value: 0
        4 TILE:
                flags: immutable blob
                blobs:

                value:
        53 max bpc:
                flags: range
                values: 8 16
                value: 0
        7 HDR_OUTPUT_METADATA:
                flags: blob
                blobs:

                value:

可以看到connector只有一个,其中:

  • modes是和当前connector关联的modes个数,当前为12个;
  • encoders是和当前connector关联的encoders列表,如果有多个会按逗号分隔。当前只有id51encoder
2.5.2 modetest -e

输出当前内核的encoders,可以看到encoder只有一个,id51,其连接的crtc37

root@rk3399:/# killall Xorg & modetest  -M rockchip -e
[1] 6184
Encoders:
id      crtc    type    possible crtcs  possible clones
51      37      TMDS    0x00000003      0x00000001

possible_crtcs通常是驱动在是初始化encoder同时直接设置的,比如dw_hdmi_rockchip_bind函数中:

static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master,
                                 void *data)
{
	......
	encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, dev->of_node);
	......
}
2.5.3 modetest -p

输出当前内核的crtcplane,从输出信息可以看到有两个CRTC,分别对应vopbvopl

root@rk3399:/# killall Xorg & modetest  -M rockchip -p
[1] 5990
CRTCs:
id      fb      pos     size
37      54      (0,0)   (1920x1080)
  #0 1920x1080 60.00 1920 2008 2052 2200 1080 1082 1087 1125 148500 flags: phsync, pvsync; type: driver
  props:
        24 VRR_ENABLED:
                flags: range
                values: 0 1
                value: 0
        28 GAMMA_LUT:
                flags: blob
                blobs:

                value:
                        00000000000000000001000100010000
                        00020002000200000003000300030000
                   		......
                        80fa80fa80fa000080fb80fb80fb0000
                        80fc80fc80fc000080fd80fd80fd0000
                        80fe80fe80fe0000c0ffc0ffc0ff0000
        29 GAMMA_LUT_SIZE:
                flags: immutable range
                values: 0 4294967295
                value: 256
44      0       (0,0)   (0x0)
  #0  nan 0 0 0 0 0 0 0 0 0 flags: ; type:
  props:
        24 VRR_ENABLED:
                flags: range
                values: 0 1
                value: 0
        28 GAMMA_LUT:
                flags: blob
                blobs:

                value:
        29 GAMMA_LUT_SIZE:
                flags: immutable range
                values: 0 4294967295
                value: 1024

Planes:
id      crtc    fb      CRTC x,y        x,y     gamma size      possible crtcs
31      37      54      0,0             0,0     0               0x00000001
  formats: XR24 AR24 XB24 AB24 RG24 BG24 RG16 BG16 NV12 NV21 NV16 NV61 NV24 NV42
  props:
        8 type:
                flags: immutable enum
                enums: Overlay=0 Primary=1 Cursor=2
                value: 1
        30 IN_FORMATS:
                flags: immutable blob
                blobs:

                value:
                        01000000000000000e00000018000000
                        01000000500000005852323441523234
                        58423234414232345247323442473234
                        52473136424731364e5631324e563231
                        4e5631364e5636314e5632344e563432
                        ff3f0000000000000000000000000000
                        0000000000000000
                in_formats blob decoded:
                         XR24:  LINEAR
                         AR24:  LINEAR
                         XB24:  LINEAR
                         AB24:  LINEAR
                         RG24:  LINEAR
                         BG24:  LINEAR
                         RG16:  LINEAR
                         BG16:  LINEAR
                         NV12:  LINEAR
                         NV21:  LINEAR
                         NV16:  LINEAR
                         NV61:  LINEAR
                         NV24:  LINEAR
                         NV42:  LINEAR
        33 rotation:
                flags: bitmask
                values: rotate-0=0x1 reflect-x=0x10 reflect-y=0x20
                value: 1
34      0       0       0,0             0,0     0               0x00000001
  formats: XR24 AR24 XB24 AB24 RG24 BG24 RG16 BG16
  props:
        8 type:
                flags: immutable enum
                enums: Overlay=0 Primary=1 Cursor=2
                value: 2
        30 IN_FORMATS:
                flags: immutable blob
                blobs:

                value:
                        01000000000000000800000018000000
                        01000000380000005852323441523234
                        58423234414232345247323442473234
                        5247313642473136ff00000000000000
                        00000000000000000000000000000000
                in_formats blob decoded:
                         XR24:  LINEAR
                         AR24:  LINEAR
                         XB24:  LINEAR
                         AB24:  LINEAR
                         RG24:  LINEAR
                         BG24:  LINEAR
                         RG16:  LINEAR
                         BG16:  LINEAR
        36 rotation:
                flags: bitmask
                values: rotate-0=0x1 reflect-y=0x20
                value: 1
38      0       0       0,0             0,0     0               0x00000002
  formats: XR24 AR24 XB24 AB24 RG24 BG24 RG16 BG16 NV12 NV21 NV16 NV61 NV24 NV42
  props:
        8 type:
                flags: immutable enum
                enums: Overlay=0 Primary=1 Cursor=2
                value: 1
        30 IN_FORMATS:
                flags: immutable blob
                blobs:

                value:
                        01000000000000000e00000018000000
                        02000000500000005852323441523234
                        58423234414232345247323442473234
                        52473136424731364e5631324e563231
                        4e5631364e5636314e5632344e563432
                        ff000000000000000000000000000000
                        5100000000000008ff3f000000000000
                        00000000000000000000000000000000
                in_formats blob decoded:
                         XR24:  (UNKNOWN MODIFIER) LINEAR
                         AR24:  (UNKNOWN MODIFIER) LINEAR
                         XB24:  (UNKNOWN MODIFIER) LINEAR
                         AB24:  (UNKNOWN MODIFIER) LINEAR
                         RG24:  (UNKNOWN MODIFIER) LINEAR
                         BG24:  (UNKNOWN MODIFIER) LINEAR
                         RG16:  (UNKNOWN MODIFIER) LINEAR
                         BG16:  (UNKNOWN MODIFIER) LINEAR
                         NV12:  LINEAR
                         NV21:  LINEAR
                         NV16:  LINEAR
                         NV61:  LINEAR
                         NV24:  LINEAR
                         NV42:  LINEAR
        40 rotation:
                flags: bitmask
                values: rotate-0=0x1 reflect-x=0x10 reflect-y=0x20
                value: 1
41      0       0       0,0             0,0     0               0x00000002
  formats: XR24 AR24 XB24 AB24 RG24 BG24 RG16 BG16
  props:
        8 type:
                flags: immutable enum
                enums: Overlay=0 Primary=1 Cursor=2
                value: 2
        30 IN_FORMATS:
                flags: immutable blob
                blobs:

                value:
                        01000000000000000800000018000000
                        01000000380000005852323441523234
                        58423234414232345247323442473234
                        5247313642473136ff00000000000000
                        00000000000000000000000000000000
                in_formats blob decoded:
                         XR24:  LINEAR
                         AR24:  LINEAR
                         XB24:  LINEAR
                         AB24:  LINEAR
                         RG24:  LINEAR
                         BG24:  LINEAR
                         RG16:  LINEAR
                         BG16:  LINEAR
        43 rotation:
                flags: bitmask
                values: rotate-0=0x1 reflect-y=0x20
                value: 1
45      0       0       0,0             0,0     0               0x00000002
  formats: XR24 AR24 XB24 AB24 RG24 BG24 RG16 BG16 NV12 NV21 NV16 NV61 NV24 NV42
  props:
        8 type:
                flags: immutable enum
                enums: Overlay=0 Primary=1 Cursor=2
                value: 0
        30 IN_FORMATS:
                flags: immutable blob
                blobs:

                value:
                        01000000000000000e00000018000000
                        01000000500000005852323441523234
                        58423234414232345247323442473234
                        52473136424731364e5631324e563231
                        4e5631364e5636314e5632344e563432
                        ff3f0000000000000000000000000000
                        0000000000000000
                in_formats blob decoded:
                         XR24:  LINEAR
                         AR24:  LINEAR
                         XB24:  LINEAR
                         AB24:  LINEAR
                         RG24:  LINEAR
                         BG24:  LINEAR
                         RG16:  LINEAR
                         BG16:  LINEAR
                         NV12:  LINEAR
                         NV21:  LINEAR
                         NV16:  LINEAR
                         NV61:  LINEAR
                         NV24:  LINEAR
                         NV42:  LINEAR
        47 rotation:
                flags: bitmask
                values: rotate-0=0x1 reflect-x=0x10 reflect-y=0x20
                value: 1
48      0       0       0,0             0,0     0               0x00000002
  formats: XR24 AR24 XB24 AB24 RG24 BG24 RG16 BG16
  props:
        8 type:
                flags: immutable enum
                enums: Overlay=0 Primary=1 Cursor=2
                value: 0
        30 IN_FORMATS:
                flags: immutable blob
                blobs:

                value:
                        01000000000000000800000018000000
                        01000000380000005852323441523234
                        58423234414232345247323442473234
                        5247313642473136ff00000000000000
                        00000000000000000000000000000000
                in_formats blob decoded:
                         XR24:  LINEAR
                         AR24:  LINEAR
                         XB24:  LINEAR
                         AB24:  LINEAR
                         RG24:  LINEAR
                         BG24:  LINEAR
                         RG16:  LINEAR
                         BG16:  LINEAR
        50 rotation:
                flags: bitmask
                values: rotate-0=0x1 reflect-y=0x20
                value: 1
2.5.4 设置分辨率

modetest中通过id来引用encoder / connector / CRTC / plane,查看个组件的id

root@rk3399:/# modetest -M rockchip | cut -f1 | grep -E ^[0-9A-Z]\|id
Encoders:
id
51
Connectors:
id
52
CRTCs:
id
37
44
Planes:
id
31
34
38
41
45
48
Frame buffers:
id

更改分辨率为1600x900@60Hz

root@rk3399:/# killall Xorg & modetest -M rockchip  -s 52@37:1600x900-60   # 正常情况下 在对应屏幕会有彩色条纹显示

其中:

  • 52HDMI connector id
  • 37: 某个vopcrtc id
  • 1600x900:显示 模式;
  • 60:刷新率;

如果出现如下错误:

failed to set mode: Permission denied

大概率是有进程占用了drm设备;

root@rk3399:~# ps -ef | grep display
gdm         5967    5899  0 13:48 tty1     00:00:00 /usr/bin/Xwayland :1024 -rootless -noreset -accessx -core -auth /run/user/127/.mutter-Xwaylandauth.WK5EE2 -listen 4 -listen 5 -displayfd 6 -listen 7
root@rk3399:~# kill -9 5967
root@rk3399:~# killall Xorg & modetest -M rockchip  -s 52@37:1920x1080-60  # 可以正常显示
[1] 6413
Xorg: no process found
setting mode 1920x1080-60.00Hz on connectors 52, crtc 37
root@rk3399:~# killall Xorg & modetest -M rockchip  -s 52@37:1600x900   # 可以正常显示
root@rk3399:~# killall Xorg & modetest -M rockchip  -s 52@37:1280x1024  # 可以正常显示
root@rk3399:~# killall Xorg & modetest -M rockchip  -s 52@37:1280x720   # 可以正常显示
root@rk3399:~# killall Xorg & modetest -M rockchip  -s 52@37:1024x768   # 可以正常显示
root@rk3399:~# killall Xorg & modetest -M rockchip  -s 52@37:800x600    # 无法显示

正常情况下在对应屏幕会有彩色条纹显示;

2.6 查看调试信息

DRM子系统内核debug日志位于/sys/kernel/debug/dri/

root@rk3399:~# ll /sys/kernel/debug/dri/
drwxr-xr-x  5 root root 0 Jan  1  1970 0/
drwxr-xr-x  2 root root 0 Jan  1  1970 1/
drwxr-xr-x  2 root root 0 Jan  1  1970 128/
root@rk3399:~# ll /sys/kernel/debug/dri/0/
drwxr-xr-x 2 root root 0 Jan  1  1970 HDMI-A-1/
-r--r--r-- 1 root root 0 Jan  1  1970 clients
drwxr-xr-x 3 root root 0 Jan  1  1970 crtc-0/
drwxr-xr-x 3 root root 0 Jan  1  1970 crtc-1/
-r--r--r-- 1 root root 0 Jan  1  1970 framebuffer
-r--r--r-- 1 root root 0 Jan  1  1970 gem_names
-r--r--r-- 1 root root 0 Jan  1  1970 internal_clients
-r--r--r-- 1 root root 0 Jan  1  1970 name
-r--r--r-- 1 root root 0 Jan  1  1970 state
2.6.1 查看设备名称
root@rk3399:~# cat /sys/kernel/debug/dri/0/name
rockchip dev=display-subsystem unique=display-subsystem
2.6.2 查看framebuffer

查看framebuffer信息:

root@rk3399:/# cat /sys/kernel/debug/dri/0/framebuffer
framebuffer[56]:
        allocated by = Xorg
        refcount=2
        format=XR24 little-endian (0x34325258)
        modifier=0x0
        size=1920x1080
        layers:
                size[0]=1920x1080
                pitch[0]=7680
                offset[0]=0
                obj[0]:
                        name=0
                        refcount=5
                        start=00000000
                        size=8294400
                        imported=no
framebuffer[58]:
        allocated by = Xorg
        refcount=1
        format=AR24 little-endian (0x34325241)
        modifier=0x0
        size=64x64
        layers:
                size[0]=64x64
                pitch[0]=256
                offset[0]=0
                obj[0]:
                        name=0
                        refcount=3
                        start=00100004
                        size=16384
                        imported=no
framebuffer[54]:
        allocated by = [fbcon]
        refcount=1
        format=XR24 little-endian (0x34325258)
        modifier=0x0
        size=1920x1080
        layers:
                size[0]=1920x1080
                pitch[0]=7680
                offset[0]=0
                obj[0]:
                        name=0
                        refcount=2
                        start=00000000
                        size=8294400
                        imported=no

三、新增特殊分辨率时序

DRM框架目前代码已经支持了绝大部分分辨率时序,但是还有一些特殊分辨率不支持,如果我们想支持更多的Standard Timings,那么就需要在 drivers/gpu/drm/drm_edid.c中的drm_dmt_modes的末尾新增项目。

drm_dmt_modes最后一项为例介绍:

/*
 * Autogenerated from the DMT spec.
 * This table is copied from xfree86/modes/xf86EdidModes.c.
 */
static const struct drm_display_mode drm_dmt_modes[] = {
		......
        /* 0x4d - 2560x1600@60Hz */
        { DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 348500, 2560, 2752,
                   3032, 3504, 0, 1600, 1603, 1609, 1658, 0,
                   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
		.....
		/* 0x58 - 4096x2160@59.94Hz RB */
        { DRM_MODE("4096x2160", DRM_MODE_TYPE_DRIVER, 556188, 4096, 4104,
                   4136, 4176, 0, 2160, 2208, 2216, 2222, 0,
                   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
}

其中:

  • 4096x2160display mode name,为分辨率的名字,命名规则为%dx%d%s

    • 第一个参数为:mode->hdisplay
    • 第二个参数为:mode->vdisplay
    • 第三个参数为:i/''(如果是隔行扫描,则为i);
  • DRM_MODE_TYPE_DRIVERdisplay mode type,配置为DRM_MODE_TYPE_DRIVER

  • 556188clock,像素时钟频率,单位为kHz

  • 4096hdisplay,行有效像素;

  • 4104hsync_start,行同步起始像素;

  • 4136hsync_end,行同步结束像素;

  • 4176htotal,行总大小;

  • 0hskew,行偏差,通常为0

  • 2160vdisplay,帧有效行;

  • 2208vsync_start,帧同步起始行;

  • 2216vsync_end,帧同步结束行;

  • 2222vtotal,一帧总行数;

  • 0vscan, 帧扫描信号,通常为0

  • DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNCflagshsyncvsync极性;

具体时序说明见下图:

img

更多细节参考文章:《Rockchip RK3399 - DRM crtc基础知识》。

这里我们的目标是使内核支持2560x1440@60Hz的分辨率,至于刷新率为啥是60Hz、是因为我们使用的EK3399 hdmi接口支持的最大输出为:

VOP BIG::4096X2160@60hz
VOP LITE: 2560x1600@60hz

3.1 修改drm_dmt_modes

定位到drivers/gpu/drm/drm_edid.c,修改drm_dmt_modes在数组最后新增:

/* 0x59 - 2560x1440@60Hz */
{ DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 241500, 2560, 2608,
		   2640, 2720, 0, 1440, 1443, 1448, 1481, 0,
		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },

这里的信息来自edid信息中的Detailed Timings

3.2 修改rockchip_mpll_cfg

定位到drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c,修改rockchip_mpll_cfg数组,由于我们拿不到有关HDMI phydatasheet,所以我去参考了官方提供的linux-4.19内核源码,将整个rockchip_mpll_cfg拷贝过来:

static const struct dw_hdmi_mpll_config rockchip_mpll_cfg[] = {
        {
                30666000, {
                        { 0x00b3, 0x0000 },
                        { 0x2153, 0x0000 },
                        { 0x40f3, 0x0000 },
                },
        },  {
                36800000, {
                        { 0x00b3, 0x0000 },
                        { 0x2153, 0x0000 },
                        { 0x40a2, 0x0001 },
                },
        },  {
                46000000, {
                        { 0x00b3, 0x0000 },
                        { 0x2142, 0x0001 },
                        { 0x40a2, 0x0001 },
                },
        },  {
                61333000, {
                        { 0x0072, 0x0001 },
                        { 0x2142, 0x0001 },
                        { 0x40a2, 0x0001 },
                },
        },  {
                73600000, {
                        { 0x0072, 0x0001 },
                        { 0x2142, 0x0001 },
                        { 0x4061, 0x0002 },
                },
        },  {
                92000000, {
                        { 0x0072, 0x0001 },
                        { 0x2145, 0x0002 },
                        { 0x4061, 0x0002 },
                },
        },  {
                122666000, {
                        { 0x0051, 0x0002 },
                        { 0x2145, 0x0002 },
                        { 0x4061, 0x0002 },
                },
        },  {
                147200000, {
                        { 0x0051, 0x0002 },
                        { 0x2145, 0x0002 },
                        { 0x4064, 0x0003 },
                },
        },  {
                184000000, {
                        { 0x0051, 0x0002 },
                        { 0x214c, 0x0003 },
                        { 0x4064, 0x0003 },
                },
        },  {
                226666000, {
                        { 0x0040, 0x0003 },
                        { 0x214c, 0x0003 },
                        { 0x4064, 0x0003 },
                },
        },  {
                272000000, {
                        { 0x0040, 0x0003 },
                        { 0x214c, 0x0003 },
                        { 0x5a64, 0x0003 },
                },
        },  {
                340000000, {
                        { 0x0040, 0x0003 },
                        { 0x3b4c, 0x0003 },
                        { 0x5a64, 0x0003 },
                },
        },  {
                600000000, {
                        { 0x1a40, 0x0003 },
                        { 0x3b4c, 0x0003 },
                        { 0x5a64, 0x0003 },
                },
        },  {
                ~0UL, {
                        { 0x0000, 0x0000 },
                        { 0x0000, 0x0000 },
                        { 0x0000, 0x0000 },
                },
        }
};

这里我们将linux-6.3内核中的rockchip_mpll_cfg合并进来:

static const struct dw_hdmi_mpll_config rockchip_mpll_cfg[] = {
		{
                27000000, {
                        { 0x00b3, 0x0000},
                        { 0x2153, 0x0000},
                        { 0x40f3, 0x0000}
                },
        }, {
                30666000, {
                        { 0x00b3, 0x0000 },
                        { 0x2153, 0x0000 },
                        { 0x40f3, 0x0000 },
                },
        }, {
                36000000, {    // 适用于drm_dmt_modes中定义的预定义的标准显示模式:800x600@56Hz  640x480@85Hz;适用于edid_est_modes中定义的显示模式:800x600@56Hz                  
                        { 0x00b3, 0x0000},
                        { 0x2153, 0x0000},
                        { 0x40f3, 0x0000}
                },
        }, {
                36800000, {
                        { 0x00b3, 0x0000 },
                        { 0x2153, 0x0000 },
                        { 0x40a2, 0x0001 },
                },
        }, {
                40000000, {    // 适用于drm_dmt_modes中定义的预定义的标准显示模式:800x600@60Hz;适用于edid_est_modes中定义的显示模式:800x600@60Hz                  
                        { 0x00b3, 0x0000},
                        { 0x2153, 0x0000},
                        { 0x40f3, 0x0000}
                },
        }, {
                46000000, {
                        { 0x00b3, 0x0000 },
                        { 0x2142, 0x0001 },
                        { 0x40a2, 0x0001 },
                },
        }, {
                54000000, {
                        { 0x0072, 0x0001},
                        { 0x2142, 0x0001},
                        { 0x40a2, 0x0001},
                },
        }, {
                61333000, {
                        { 0x0072, 0x0001 },
                        { 0x2142, 0x0001 },
                        { 0x40a2, 0x0001 },
                },
        }, {
                65000000, {    // 适用于edid_est_modes中定义的显示模式:1024x768@70Hz       
                        { 0x0072, 0x0001},
                        { 0x2142, 0x0001},
                        { 0x40a2, 0x0001},
                },
        }, {
                66000000, {  
                        { 0x013e, 0x0003},
                        { 0x217e, 0x0002},
                        { 0x4061, 0x0002}
                },
        }, {
                73600000, {
                        { 0x0072, 0x0001 },
                        { 0x2142, 0x0001 },
                        { 0x4061, 0x0002 },
                },
        }, {
                74250000, {   // 适用于drm_dmt_modes中定义的预定义的标准显示模式:1280x720@60Hz
                        { 0x0072, 0x0001},
                        { 0x2145, 0x0002},
                        { 0x4061, 0x0002}
                },
        }, {
                83500000, {   // 适用于drm_dmt_modes中定义的预定义的标准显示模式:1280x800@60Hz
                        { 0x0072, 0x0001},
                },
        }, {
                92000000, {
                        { 0x0072, 0x0001 },
                        { 0x2145, 0x0002 },
                        { 0x4061, 0x0002 },
                },
        },  {
                108000000, {   // 适用于drm_dmt_modes中定义的预定义的标准显示模式:1600x900@60Hz 1280x1024@60Hz 1152x864@75Hz 1280x960@60Hz;适用于edid_est_modes中定义的显示模式:1152x864@75Hz                 
                        { 0x0051, 0x0002},
                        { 0x2145, 0x0002},
                        { 0x4061, 0x0002}
                },
        }, {
                106500000, {   // 适用于drm_dmt_modes中定义的预定义的标准显示模式:1440x900@60Hz、1280x800@75Hz
                        { 0x0051, 0x0002},
                        { 0x2145, 0x0002},
                        { 0x4061, 0x0002}
                },
        }, {
                122666000, {
                        { 0x0051, 0x0002 },
                        { 0x2145, 0x0002 },
                        { 0x4061, 0x0002 },
                },
        }, {
                146250000, {     // 适用于drm_dmt_modes中定义的预定义的标准显示模式:1680x1050@60Hz  1280x800@120Hz RB
                        { 0x0051, 0x0002},
                        { 0x2145, 0x0002},
                        { 0x4061, 0x0002}
                },
        }, {
                147200000, {
                        { 0x0051, 0x0002 },
                        { 0x2145, 0x0002 },
                        { 0x4064, 0x0003 },
                },
        }, {
                148500000, {       // 适用于drm_dmt_modes中定义的预定义的标准显示模式:1920x1080@60Hz  1280x960@85Hz 
                        { 0x0051, 0x0003},
                        { 0x214c, 0x0003},
                        { 0x4064, 0x0003}
                },
        }, {
                184000000, {
                        { 0x0051, 0x0002 },
                        { 0x214c, 0x0003 },
                        { 0x4064, 0x0003 },
                },
        },  {
                226666000, {
                        { 0x0040, 0x0003 },
                        { 0x214c, 0x0003 },
                        { 0x4064, 0x0003 },
                },
        },  {
                272000000, {
                        { 0x0040, 0x0003 },
                        { 0x214c, 0x0003 },
                        { 0x5a64, 0x0003 },
                },
        },  {
                340000000, {
                        { 0x0040, 0x0003 },
                        { 0x3b4c, 0x0003 },
                        { 0x5a64, 0x0003 },
                },
        },  {
                600000000, {
                        { 0x1a40, 0x0003 },
                        { 0x3b4c, 0x0003 },
                        { 0x5a64, 0x0003 },
                },
        },  {
                ~0UL, {
                        { 0x0000, 0x0000 },
                        { 0x0000, 0x0000 },
                        { 0x0000, 0x0000 },
                },
        }
};

同时需要新增像素时钟频率241500000,我在272000000之前新增:

{
                241500000, {
                        { 0x0040, 0x0003 },
                        { 0x214c, 0x0003 },
                        { 0x4064, 0x0003 },
                },
        },

需要注意:该配置是个人猜测的,后面我们会验证是否存在问题。

3.3 修改rockchip_cur_ctr

定位到drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c,如果我们的像素时钟频率小于rockchip_cur_ctr中最大的像素时钟频率则跳过这一步。

由于rockchip_cur_ctr中支持的最大像素时钟频率为148500000,小于241500000,因此修改rockchip_cur_ctr数组,在148500000之后新增新的像素时钟频率配置.

由于我们拿不到有关HDMI phydatasheet,所以我去参考了官方提供的linux-4.19内核源码,将整个rockchip_cur_ctr拷贝过来:

static const struct dw_hdmi_curr_ctrl rockchip_cur_ctr[] = {
        /*      pixelclk    bpp8    bpp10   bpp12 */
        {
                600000000, { 0x0000, 0x0000, 0x0000 },
        },  {
                ~0UL,      { 0x0000, 0x0000, 0x0000},
        }
};

这里我们将linux-6.3内核中的rockchip_cur_ctr合并进来:

static const struct dw_hdmi_curr_ctrl rockchip_cur_ctr[] = {
        /*      pixelclk    bpp8    bpp10   bpp12 */
        {
                40000000,  { 0x0018, 0x0018, 0x0018 },
        }, {
                65000000,  { 0x0028, 0x0028, 0x0028 },
        }, {
                66000000,  { 0x0038, 0x0038, 0x0038 },
        }, {
                74250000,  { 0x0028, 0x0038, 0x0038 },
        }, {
                83500000,  { 0x0028, 0x0038, 0x0038 },
        }, {
                146250000, { 0x0038, 0x0038, 0x0038 },
        }, {
                148500000, { 0x0000, 0x0038, 0x0038 },
        }, {
                600000000, { 0x0000, 0x0000, 0x0000 },
        }, {
                ~0UL,      { 0x0000, 0x0000, 0x0000},
        }
};

3.4 修改rockchip_phy_config

定位到drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c,如果我们的像素时钟频率小于rockchip_phy_config中最大的像素时钟频率则跳过这一步。

由于我们的目标像素时钟频率241500000低于rockchip_phy_config中的最大像素时钟频率297000000,因此该项可以不用配置了。

不过这里我去参考了官方提供的linux-4.19内核源码,将整个rockchip_phy_config拷贝过来:

static struct dw_hdmi_phy_config rockchip_phy_config[] = {
        /*pixelclk   symbol   term   vlev*/
        { 74250000,  0x8009, 0x0004, 0x0272},
        { 165000000, 0x802b, 0x0004, 0x0209},
        { 297000000, 0x8039, 0x0005, 0x028d},
        { 594000000, 0x8039, 0x0000, 0x019d},
        { ~0UL,      0x0000, 0x0000, 0x0000},
};

这里我们将linux-6.3内核中的rockchip_phy_config合并进来:

static struct dw_hdmi_phy_config rockchip_phy_config[] = {
        /*pixelclk   symbol   term   vlev*/
        { 74250000,  0x8009, 0x0004, 0x0272},
        { 148500000, 0x802b, 0x0004, 0x028d},
        { 165000000, 0x802b, 0x0004, 0x0209},
        { 297000000, 0x8039, 0x0005, 0x028d},
        { 594000000, 0x8039, 0x0000, 0x019d},
        { ~0UL,      0x0000, 0x0000, 0x0000},
};

3.5 测试

重新编译内核并烧录,此时执行cat /sys/class/drm/card0-HDMI-A-1/modes命令:

root@rk3399:/# cat /sys/class/drm/card0-HDMI-A-1/modes
2560x1440
1920x1080
1920x1080
1920x1080
1920x1080i
1920x1080
1920x1080
1920x1080i
1600x900
1280x1024
1280x720
1280x720
1280x720
1024x768
800x600
800x600

此时固然可以看到分辨率2560x1440,但是hdmi显示器确无法正常工作,不难猜测应该是我配置的rockchip_mpll_cfgrockchip_cur_ctr有问题,因此我将之前我追加的这些配置最终移除了,至于如何配置可以联系fae@rock-chips.com咨询。

参考文章

[1] [Rockchip_Developer_Guide_HDMI_CN]

[2] DesignWare HDMI IP 解决方案

[3] LVDS+HDMI输出特殊分辨率800*1280竖屏

[4] Linux DRM那些事-HDMI接口EDID获取

[5] EDID的简介和解析

[6] 什么是EDIDEDID能做什么,EDID基本介绍

[7] modetest工具测试(linux-5.10)

posted @ 2023-11-14 23:27  大奥特曼打小怪兽  阅读(2169)  评论(0编辑  收藏  举报
如果有任何技术小问题,欢迎大家交流沟通,共同进步