RK3399:HDMI输出固定频率与热插拔

1、简介

我采用的开发环境是OK3399-C开发板,默认的HDMI输出频率是720P,而我使用的屏幕是800x600的分辨率,需改成固定分辨率。

2、增加HDMI支持的分辨率

在源码文件kernel/drivers/gpu/drm/drm_edid.c中的edid_cea_modes结构体中包含着各种分辨率,如果里面有你需要的就不用改,如果没有,需自己新加,例如800x600-60Hz。

/* 108 - 800x600p@60Hz 4:3 */
{ DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 40000, 800, 840, 
		   968, 1056, 0, 600, 601, 605, 628, 0,   /* 800x600@60Hz从上面的edid_est_modes结构体拷贝过来 */
		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) ,
		  .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3,  },

3、修改默认输出

在源码文件kernel/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c的2569行dw_hdmi_connector_get_modes函数中,

struct edid *edid;
struct drm_display_mode *mode;
//const u8 def_modes[6] = {4, 16, 31, 19, 17, 2};
const u8 def_modes[1] = {108}; //将默认模式改为自己新加的108项
struct drm_display_info *info = &connector->display_info;
struct hdr_static_metadata *metedata =
			&connector->display_info.hdmi.hdr_panel_metadata;
	int i, ret = 0;

	if (!hdmi->ddc)
		return 0;

	edid = drm_get_edid(connector, hdmi->ddc);
	edid = NULL;	//要把edid强制输出为空,否则就跟随edid了。
	if (edid) {

4、其它可选择修改

在源码文件kernel/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c文件中493行,去掉如下选项

/*
if (mode->clock > 340000 &&
	    connector->display_info.max_tmds_clock < 340000 &&
	    (!drm_mode_is_420(&connector->display_info, mode) ||
	     !connector->ycbcr_420_allowed))
		return MODE_BAD;
*/

在源码文件kernel/drivers/video/rockchip/hdmi/rockchip-hdm.h文件中hdmi_video_information_code结构体中加入新增的分辨率

HDMI_800X600P_60HZ_4_3,

在570行,修改默认的分辨率

/* HDMI default vide mode */
#define HDMI_VIDEO_DEFAULT_MODE			HDMI_800X600P_60HZ_4_3       //HDMI_1280X720P_60HZ

5、HDMI支持热插拔

我用的OK3399-C开发板的HDMI不支持热插拔,造成的原因是拔下后,系统切换成其它视频输出接口。权宜之计,驱动中一直挂着HDMI。在源码文件kernel/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c文件中第1645行

enum drm_connector_status dw_hdmi_phy_read_hpd(struct dw_hdmi *hdmi,
						      void *data)
{
	return hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_HPD ?
		connector_status_connected : connector_status_connected;
		//connector_status_connected : connector_status_disconnected;
}

6、结尾

修改上面的文件后,重新编译系统内核,并更新到开发板上,可以看到分辨率变成了800x600。

你可能感兴趣的:(嵌入式Linux,linux)