目录
2 设置 connector 的状态为“connector_status_connected”
2.2 强制设置connector 的状态为“connector_status_connected”
3.1 创建firmware 文件(以1920x1200分辨率为例)
3.2 将 1920x1200.bin 文件编译到内核镜像里
参考:Documentation/driver-api/edid.rst
1 简介
常见的个人电脑显示接口(如HDMI)都有探测信号,可以检测有没有连接显示器。当探测到连接新的显示器的时候,linux内核会通过I2C通道来获取显示器的分辨率、刷新率等信息,然后内核会根据显示器支持的分辨率设置输出的图像显示信号。
在平板电脑上,屏幕是固定的,所以不需要探测的过程,同时可以直接固定一个分辨率。
2 设置 connector 的状态为“connector_status_connected”
2.1 connector的状态
linux内核使用DRM框架来管理显示功能。在DRM框架中使用“struct drm_connector”来抽象化表示是VGA、HDMI等接口。struct drm_connector结构体中有一个成员变量“enum drm_connector_status status”来表示是否有连接显示器,有以下3中状态:
/**
* enum drm_connector_status - status for a &drm_connector
*
* This enum is used to track the connector status. There are no separate
* #defines for the uapi!
*/
enum drm_connector_status {
/**
* @connector_status_connected: The connector is definitely connected to
* a sink device, and can be enabled.
*/
connector_status_connected = 1,
/**
* @connector_status_disconnected: The connector isn't connected to a
* sink device which can be autodetect. For digital outputs like DP or
* HDMI (which can be realiable probed) this means there's really
* nothing there. It is driver-dependent whether a connector with this
* status can be lit up or not.
*/
connector_status_disconnected = 2,
/**
* @connector_status_unknown: The connector's status could not be
* reliably detected. This happens when probing would either cause
* flicker (like load-detection when the connector is in use), or when a
* hardware resource isn't available (like when load-detection needs a
* free CRTC). It should be possible to light up the connector with one
* of the listed fallback modes. For default configuration userspace
* should only try to light up connectors with unknown status when
* there's not connector with @connector_status_connected.
*/
connector_status_unknown = 3,
};
2.2 强制设置connector 的状态为“connector_status_connected”
2.2.1 简介
在某些平板电脑硬件上,因为屏幕是固定的,不需要动态探测是否有新屏幕连接,所以显示接口中的探测信号被省略了。在这种情况下就要通过其他方式告知linux内核当前屏幕已连接。
2.2.2 获取connector的名称
打开drm的调试信息
在启动参数里添加:drm.debug=0xfff
然后重启
查看dmesg信息,可以看到如下信息:
[ 0.824831] [drm] Connector 0:
[ 0.824833] [drm] DP-1
[ 0.824835] [drm] HPD1
[ 0.824837] [drm] DDC: 0x4868 0x4868 0x4869 0x4869 0x486a 0x486a 0x486b 0x486b
[ 0.824839] [drm] Encoders:
[ 0.824841] [drm] DFP1: INTERNAL_UNIPHY
上面显示的connector名称是“DP-1”
2.2.3 在启动参数里添加:video=DP-1:D
对应的内核处理函数
//drivers/gpu/drm/drm_modes.c
static int drm_mode_parse_cmdline_extra(const char *str, int length,
bool freestanding,
const struct drm_connector *connector,
struct drm_cmdline_mode *mode)
{
......
case 'D':
if (mode->force != DRM_FORCE_UNSPECIFIED)
return -EINVAL;
if ((connector->connector_type != DRM_MODE_CONNECTOR_DVII) &&
(connector->connector_type != DRM_MODE_CONNECTOR_HDMIB))
mode->force = DRM_FORCE_ON;
else
mode->force = DRM_FORCE_ON_DIGITAL;
break;
......
}
重启系统后,可以在dmesg信息中看到如下信息
[ 8.274745] [drm:drm_helper_probe_single_connector_modes] [CONNECTOR:53:DP-1]
[ 8.274749] [drm:drm_helper_probe_single_connector_modes] [CONNECTOR:53:DP-1] status updated from unknown to connected
3 通过firmware方式设置分辨率
3.1 创建firmware 文件(以1920x1200分辨率为例)
在获取了屏幕的具体显示参数后,在 linux-5.4.18/Documentation/EDID/目录下创建文件“1920x1200.S”,文件内容如下:
/* EDID */
#define VERSION 1
#define REVISION 3
#define XPIX 1920
#define XBLANK 160
#define XOFFSET 48
#define XPULSE 32
#define YPIX 1200
#define YBLANK 35
#define YOFFSET 3
#define YPULSE 6
#define DPI 72
/* Display */
#define CLOCK 77000 /* kHz */
#define XY_RATIO XY_RATIO_16_10
#define VFREQ 30 /* Hz */
#define TIMING_NAME "Linux XGA"
#define HSYNC_POL 1
#define VSYNC_POL 1
#include "edid.S"
将“1920x1200.S”文件编译成 bin 文件
cd linux-5.4.18/Documentation/EDID/
make
编译成功后,会在 linux-5.4.18/Documentation/EDID/目录下生成 1920x1200.bin
3.2 将 1920x1200.bin 文件编译到内核镜像里
修改下面 2 个内核配置来指定文件 1920x1200.bin
CONFIG_EXTRA_FIRMWARE
CONFIG_EXTRA_FIRMWARE_DIR
然后编译内核
3.3 添加启动参数
增加以下启动参数:drm.edid_firmware=DP-1:1920x1200.bin (对应的内核处理函数:drm_add_override_edid_modes();)
然后重启系统。
以上操作成功后,可以在 dmesg 信息里看到以下内容:
[ 9.219533] [drm] Got external EDID base block and 0 extensions from "1920x1200.bin" for connector "DP-1"
......
[ 9.240652] [drm:drm_helper_probe_single_connector_modes] [CONNECTOR:53:DP-1] probed modes :
[ 9.240657] [drm:drm_mode_debug_printmodeline] Modeline "1920x1200": 30 77000 1920 1968 2000 2080 1200 1203 1209 1235 0x48 0x5