rk3576 hdmi i2c延时

在设备数中hdmi节点

&hdmi {
	status = "okay";
	// rockchip,sda-falling-delay-ns = <360>;
};

关于rockchip,sda-falling-delay-ns,开启延时后hdmi屏幕不亮,注释改属性后出现刷屏

[   44.119907] dwhdmi-rockchip 27da0000.hdmi: i2c read err!
[   44.131171] dwhdmi-rockchip 27da0000.hdmi: i2c read err!
[   44.142673] dwhdmi-rockchip 27da0000.hdmi: i2c read err!
[   44.154272] EDID block 0 is all zeroes
[   44.154299] dwhdmi-rockchip 27da0000.hdmi: failed to get edid

i2c无法读取到屏幕的edid

新增特殊分辨率时序

在 kernel/drivers/gpu/drm/drm_edid.c 中的 drm_dmt_modes 的末尾新增项⽬

/* 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) },

cat /sys/class/drm/card0-HDMI-A-1/edid > /data/edid.bin
从edid.bin中获取分辨率和刷新率

在 Linux 内核的 DRM 子系统中,如果需要将特定显示器的时钟频率修改为 50MHz(50000 kHz),有以下几种实现方式,根据不同的场景和需求选择合适的方案:

方案 1:通过 EDID Quirks 机制修改(推荐)

这是最标准的方式,通过添加一个 EDID quirk 来覆盖原始 EDID 中的时钟频率。

  1. 定义新的 Quirk 类型
    enum edid_quirk 中添加新的 quirk 类型:

    enum edid_quirk {
        // ... 其他 quirks ...
        EDID_QUIRK_FORCE_50MHZ_PIXEL_CLOCK,
        // ...
    };
    
  2. 在 quirks 列表中注册
    edid_quirk_list[] 中添加针对特定显示器的条目:

    static const struct edid_quirk edid_quirk_list[] = {
        /* ABC 公司的显示器,产品ID 1234 */
        { "ABC", 1234, EDID_QUIRK_FORCE_50MHZ_PIXEL_CLOCK },
        /* XYZ 公司的显示器,产品ID 5678 */
        { "XYZ", 5678, EDID_QUIRK_FORCE_50MHZ_PIXEL_CLOCK },
        { }, /* 结束标记 */
    };
    
  3. 实现时钟覆盖逻辑
    在创建模式时应用这个 quirk:

    struct drm_display_mode *drm_mode_detailed(struct drm_device *dev,
                                             const struct edid *edid,
                                             struct detailed_timing *timing,
                                             const struct edid_quirk *quirk)
    {
        // 解析原始时序
        struct drm_display_mode *mode;
        unsigned pixel_clock = le16_to_cpu(timing->pixel_clock);
        
        // 创建模式
        mode = drm_mode_create(dev);
        if (!mode)
            return NULL;
            
        // 应用 quirk 覆盖时钟
        if (quirk->type == EDID_QUIRK_FORCE_50MHZ_PIXEL_CLOCK) {
            mode->clock = 50000; // 50 MHz in kHz (50000)
            DRM_INFO("Applying clock override for %s: %u -> %u kHz\n",
                     edid_get_monitor_name(edid), pixel_clock * 10, 50000);
        } else {
            mode->clock = pixel_clock * 10; // 常规转换 (10kHz -> kHz)
        }
        
        // 解析其他参数(水平/垂直尺寸等)
        // ...
        
        return mode;
    }
    
          [Display Hardware]
                  |
                  v
(DDC/I2C)  drm_do_get_edid / drm_edid_read_ddc
                  |        |
                  v        | (可选自定义)
          drm_edid_read_custom
                  |
                  v
             [Raw EDID Data Blocks]
                  |
                  v
          drm_edid_is_valid? (头、校验和)
                  |
                  v
         drm_parse_edid (基础信息)
          |             |
          v             |  (更详细能力)
drm_add_edid_modes     | (Audio, Color, HDR, Link Cap)
          |             |
          |       +-----v-----+
          |       | Quirks    | (drm_find_edid_quirk)
          |       +-----+-----+
          |             |
          v             v
          [ Build Mode List ]
          | (Established, Standard,   |
          |  Detailed Timings, VIC,   | <-- add_cea_modes
          |  DisplayID Timings)       | <-- drm_add_displayid_modes
          |              |
          |              v
          |       [ Apply Quirks ]  (修改/添加/跳过模式)
          |              |
          v              v
 drm_mode_probed_add(connector, mode)
          |
          v
[connector->probed_modes list updated]
          |
          v
   [drm_connector->display_info]
          |
          v
[KMS Atomic Check/Commit uses modes]
          |
          v
      [Screen Output]
posted @ 2025-06-25 23:52  fangshuo  阅读(171)  评论(0)    收藏  举报