图显系统DRM ENCODER和CONNECTOR完全解析
0. 引言
DRM ENCODER 和 CONNECTOR 模块由图显外设抽象而来,从传统意义上来讲,ENCODER 包含外设控制器的功能,而 CONNECTOR 包含外设 PHY 或者显示器参数。但是这两部分又紧密关联,因此,软件 DRM 架构下的 ENCODER 和 CONNECTOR 需要按照一个整体来理解和实现。

目前的图显外设接口主要有 MIPI、HDMI、LVDS、DP、VGA、DVI、RGB 等等,同时,又可以通过转接卡来实现各种接口之间的转换。目前,市面上的处理器 SoC 又同时具备以上接口。

因此,DRM 架构为了统一管理、无差别化对待不同芯片厂商的 IP,抽象出了 ENCODER 和 CONNECTOR 两部分内容。
2. 功能
ENCODER 作为图显外设的逻辑控制器,从图显处理器接收并行的 RGB 数据,并按照接口类型对 RGB 数据进行编码,例如 HDMI 通过 encoder 将 RGB 数据编码为 TMDS 类型的数据。
在软件层面的 DRM 架构中规定了使用下面两个数据结构,注册 DRM ENCODER 相关功能。
encoder 控制
struct drm_encoder_funcs {void (*reset)(struct drm_encoder *encoder);void (*destroy)(struct drm_encoder *encoder);int (*late_register)(struct drm_encoder *encoder);void (*early_unregister)(struct drm_encoder *encoder);
};
encoder 配置
struct drm_encoder_helper_funcs {void (*dpms)();enum drm_mode_status ();bool (*mode_fixup)();void (*prepare)();void (*commit)();void (*mode_set)();void (*atomic_mode_set)();struct drm_crtc *(*get_crtc)();enum drm_connector_status ();void (*atomic_disable)();void (*atomic_enable)();void (*disable)();void (*enable)();int (*atomic_check)();
};
图显外设 IP 厂商需要提供相关的例化代码,如下:
static const struct drm_encoder_funcs exynos_hdmi_encoder_funcs = {.destroy = drm_encoder_cleanup,
};static const struct drm_encoder_helper_funcs exynos_hdmi_encoder_helper_funcs = {.mode_fixup = hdmi_mode_fixup,.enable = hdmi_enable,.disable = hdmi_disable,
};
mode_fixup()会将上层应用下发的图显参数进行校验,可以对参数进行修正也可以终止不符合显示要求的请求。若显示参数符合要求,将其拷贝给 struct drm_display_mode。
static bool hdmi_mode_fixup(struct drm_encoder *encoder,const struct drm_display_mode *mode,struct drm_display_mode *adjusted_mode)
{
...mode_ok = hdmi_mode_valid(connector, adjusted_mode);
...drm_mode_copy(adjusted_mode, m);
...
CONNECTOR 包含 PHY 或者显示屏的参数,接收 ENCODER 发送过来的编码数据后,按照显示接口类型发送给显示器。例如 HDMI PHY 内部集成 Serializer,将 TMDS 数据转换成高速串行 bit 流发送到差分数据通道。
DRM 架构中 connector 需要提供支持的显示参数以及显示屏的连接状态等。规定使用下面两个数据结构,注册 DRM CONNECTR 相关功能。
connctor 控制
struct drm_connector_funcs {int (*dpms)();void (*reset)();enum drm_connector_status ();void (*force)();int (*fill_modes)();int (*set_property)();int (*late_register)();void (*early_unregister)();void (*destroy)();struct drm_connector_state *();void (*atomic_destroy_state)();int (*atomic_set_property)();int (*atomic_get_property)();void (*atomic_print_state)();
};
connector 配置
struct drm_connector_helper_funcs {int (*get_modes)();int (*detect_ctx)();enum drm_mode_status (*mode_valid)();struct drm_encoder *(*best_encoder)();struct drm_encoder *(*atomic_best_encoder)();int (*atomic_check)();void (*atomic_commit)();int (*prepare_writeback_job)();void (*cleanup_writeback_job)();
};
图显外设 IP 厂商需要提供相关的例化代码,如下:
static const struct drm_connector_funcs hdmi_connector_funcs = {.fill_modes = drm_helper_probe_single_connector_modes,.detect = hdmi_detect,.destroy = hdmi_connector_destroy,.reset = drm_atomic_helper_connector_reset,.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
};static const struct drm_connector_helper_funcs hdmi_connector_helper_funcs = {.get_modes = hdmi_get_modes,.mode_valid = hdmi_mode_valid,
};
对于显示参数等信息需要通过某种方式从外部获取的图显 IP,如 HDMI、MIPI,hdmi_get_modes 是一个很关键的函数。
对于 HDMI 而言,通过 DDC 总线从外部显示屏中获取显示参数 EDID,以此决定是否支持当前显示要求。若无法获取 EDID 信息,那么是无法点亮屏幕的。DRM 也规定了获取 EDID 的统一标准接口,即 drm_get_edid()。
static int hdmi_get_modes(struct drm_connector *connector)
{...edid = drm_get_edid(connector, hdata->ddc_adpt);if (!edid)return -ENODEV;...
}
SoC 芯片能够同时连接、同时工作的 ENCODER 和 CONNECTOR 数量,取决于内部集成的图显处理器的数量以及每个图显处理器的端口数,当然,SoC 芯片的时钟系统也是影响多个接口能否同时显示的一个关键要素。
3. 初始化
图显外设使用 component_add()注册进 DRM 系统,关于 component_add()
链接
encoder 的初始化包含两部分内容,分别是:
- drm_encoder_init()
- drm_encoder_helper_add()
DRM通过数据结构struct drm_encoder来描述ENCODER设备信息及同其他DRM组件之间的关系。
struct drm_encoder {struct drm_device *dev;struct list_head head;struct drm_mode_object base;char *name;int encoder_type;unsigned index;uint32_t possible_crtcs;uint32_t possible_clones;struct drm_crtc *crtc;struct drm_bridge *bridge;const struct drm_encoder_funcs *funcs;const struct drm_encoder_helper_funcs *helper_private;
};
DRM ENCODER初始化流程如下图所示,其主要实现了drm_encoder的例化以及注册drm_encoder_funcs、drm_encoder_helper_funcs两个数据结构。

DRM CONNECTOR初始化流程如下图所示,其主要实现了drm_connector的例化以及注册drm_connector_funcs、drm_connector_helper_funcs两个数据结构。

本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
