我是靠谱客的博主 深情帆布鞋,最近开发中收集的这篇文章主要介绍3399 hdmi输出特殊分辨率1.添加配置2.drivers/gpu/drm/rockchip/rockchip_drm_vop.c3.drivers/gpu/drm/bridge/synopsys/dw-hdmi.c4.虚拟机内编译5.将两个img文件烧入到RK3399开发板内6.连接LCD屏,远程进入RK3399环境内,输入以下命令附录,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

1.添加配置

drivers/gpu/drm/drm_edid.c

        /* 106 - 3840x2160p@50Hz 64:27 */
        { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 594000, 3840, 4896,
                4984, 5280, 0, 2160, 2168, 2178, 2250, 0,
                DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
          .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
        /* 107 - 3840x2160p@60Hz 64:27 */
        { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 594000, 3840, 4016,
                4104, 4400, 0, 2160, 2168, 2178, 2250, 0,
                DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
          .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
//在这里添加新的数据
        /* 108 - 1920x3240@60Hz 16:27 */
        { DRM_MODE("1920x3240", DRM_MODE_TYPE_DRIVER, 410000, 1920, 1968,
                2000, 2160, 0, 3240, 3243, 3253, 3299, 0,
                DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
          .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },

#define DRM_MODE(nm, t, c, hd, hss, hse, ht, hsk, vd, vss, vse, vt, vs, f) 
        .name = nm, .status = 0, .type = (t), .clock = (c), 
        .hdisplay = (hd), .hsync_start = (hss), .hsync_end = (hse), 
        .htotal = (ht), .hskew = (hsk), .vdisplay = (vd), 
        .vsync_start = (vss), .vsync_end = (vse), .vtotal = (vt), 
        .vscan = (vs), .flags = (f), 
        .base.type = DRM_MODE_OBJECT_MODE
// DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 后面的参数依次是:
// clock, hdisplay, hsync_start, hsync_end, htotal, skew, 
// vdisplay, vsync_start, vsync_end, vtotal, vscan, flags


在这里插入图片描述
比如需要改的分辨率是:
在这里插入图片描述
那么clock = 410000,
hdisplay = 1920
hsync_start = hdisplay + tHFP = 1920 + 48 = 1968
hsync_end = hsync_start + tHsync = 2000
htotal = hsync_end + tHBP = 2160
skew = 0

vdisplay = 3240
vsync_start = vdisplay + tVFP = 3240 + 3 = 3243
vsync_end = vsync_start + tVsync = 3253
vtotal = vsync_end + tVBP = 3299
vscan = 0

        { 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 */

// 增加一个自定义的结构体
static const struct drm_display_mode my_self_modes[] = {
        /* 108 - 1920x3240@60Hz 16:27 */
        { DRM_MODE("1920x3240", DRM_MODE_TYPE_DRIVER, 410000, 1920, 1968,
                2000, 2160, 0, 3240, 3243, 3253, 3299, 0,
                DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
};

struct minimode {
//.....

//增加自定义的函数
static int
add_myself_modes(struct drm_connector *connector)
{
        int i, modes = 0;
        struct drm_device *dev = connector->dev;
        for(i=0;i<=ARRAY_SIZE(my_self_modes);i++) {
                struct drm_display_mode *newmode;
                newmode = drm_mode_duplicate(dev, &my_self_modes[i]);
                if(newmode) {
                        drm_mode_probed_add(connector, newmode);
                        modes++;
                }
        }

        return modes;
}


int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid)
//....
        num_modes += add_established_modes(connector, edid);
        num_modes += add_cea_modes(connector, edid);
        num_modes += add_alternate_cea_modes(connector, edid);
        num_modes += add_displayid_detailed_modes(connector, edid);
        num_modes += add_myself_modes(connector);			//增加自定义mode
        if (edid->features & DRM_EDID_FEATURE_DEFAULT_GTF)
                num_modes += add_inferred_modes(connector, edid);

        if (quirks & (EDID_QUIRK_PREFER_LARGE_60 | EDID_QUIRK_PREFER_LARGE_75))
//....

static int
drm_dmt_modes_for_range(struct drm_connector *connector, struct edid *edid,
                        struct detailed_timing *timing)
{
        int i, modes = 0;
        struct drm_display_mode *newmode;
        struct drm_device *dev = connector->dev;

        for (i = 0; i < ARRAY_SIZE(drm_dmt_modes); i++) {
                if ((mode_in_range(drm_dmt_modes + i, edid, timing) &&
                    valid_inferred_mode(connector, drm_dmt_modes + i))|| 
                    	//增加判断,保证进入这个分支
                        (strcmp(drm_dmt_modes[i].name, "1920x3240") == 0)) {		
                        newmode = drm_mode_duplicate(dev, &drm_dmt_modes[i]);
                        if (newmode) {
                                drm_mode_probed_add(connector, newmode);
                                modes++;
                        }
                }
        }

        return modes;
}

2.drivers/gpu/drm/rockchip/rockchip_drm_vop.c

vop_crtc_mode_valid函数

static enum drm_mode_status
vop_crtc_mode_valid(struct drm_crtc *crtc, const struct drm_display_mode *mode,
                    int output_type)
//...
	     /*
         * Hdmi or DisplayPort request a Accurate clock.
         */
     if (output_type == DRM_MODE_CONNECTOR_HDMIA ||
            output_type == DRM_MODE_CONNECTOR_DisplayPort)
                if ((clock != request_clock) && 
                        (strcmp(mode->name, "1920x3240") == 0))
                                return MODE_CLOCK_RANGE;

//...

3.drivers/gpu/drm/bridge/synopsys/dw-hdmi.c

static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
{
        struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi,
                                             connector);
        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};
        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;

//...

4.虚拟机内编译

执行make_kernel.sh获取kernel.img和resource.img

5.将两个img文件烧入到RK3399开发板内

使用烧录工具单独烧录kernel和resource就行

6.连接LCD屏,远程进入RK3399环境内,输入以下命令

cat /sys/class/drm/card0-HDMI-A-1/mode

看到特定分辨率即表示成功

附录

HDMI输出4K时,修改quant range
drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c

static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master,
void *data)
hdmi->hdmi_quant_range = 2;

最后

以上就是深情帆布鞋为你收集整理的3399 hdmi输出特殊分辨率1.添加配置2.drivers/gpu/drm/rockchip/rockchip_drm_vop.c3.drivers/gpu/drm/bridge/synopsys/dw-hdmi.c4.虚拟机内编译5.将两个img文件烧入到RK3399开发板内6.连接LCD屏,远程进入RK3399环境内,输入以下命令附录的全部内容,希望文章能够帮你解决3399 hdmi输出特殊分辨率1.添加配置2.drivers/gpu/drm/rockchip/rockchip_drm_vop.c3.drivers/gpu/drm/bridge/synopsys/dw-hdmi.c4.虚拟机内编译5.将两个img文件烧入到RK3399开发板内6.连接LCD屏,远程进入RK3399环境内,输入以下命令附录所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(62)

评论列表共有 0 条评论

立即
投稿
返回
顶部