概述
一 connector->func
drm_connector_funcs类型的对象实例,其中有些对象实例可直接使用helper函数,有些可以自定义, 还有一些可以忽略掉不赋值的
/**
* struct drm_connector_funcs - control connectors on a given device
*
* Each CRTC may have one or more connectors attached to it. The functions
* below allow the core DRM code to control connectors, enumerate available modes,
* etc.
*/
struct drm_connector_funcs {
int (*dpms)(struct drm_connector *connector, int mode);
void (*reset)(struct drm_connector *connector);
enum drm_connector_status (*detect)(struct drm_connector *connector,
bool force);
void (*force)(struct drm_connector *connector);
int (*fill_modes)(struct drm_connector *connector, uint32_t max_width, uint32_t max_height);
int (*set_property)(struct drm_connector *connector, struct drm_property *property,
uint64_t val);
int (*late_register)(struct drm_connector *connector);
void (*early_unregister)(struct drm_connector *connector);
void (*destroy)(struct drm_connector *connector);
struct drm_connector_state *(*atomic_duplicate_state)(struct drm_connector *connector);
void (*atomic_destroy_state)(struct drm_connector *connector,
struct drm_connector_state *state);
int (*atomic_set_property)(struct drm_connector *connector,
struct drm_connector_state *state,
struct drm_property *property,
uint64_t val);
int (*atomic_get_property)(struct drm_connector *connector,
const struct drm_connector_state *state,
struct drm_property *property,
uint64_t *val);
void (*atomic_print_state)(struct drm_printer *p,
const struct drm_connector_state *state);
};
vkms实例如下, 这里仅初始化了其中几项:
static const struct drm_connector_funcs vkms_connector_funcs = {
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = vkms_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,
};
分析下常用的函数接口:
(1) dpms
电源管理相关,connector的dpms主要赋值为drm_helper_connector_dpms, 其会依次调用crtc及encoder的dpms接口(如果有的话), crtc和encoder的dpms一般都是自定义直接操作硬件了
drm_helper_connector_dpms
//获取crtc自定义的dpms接口,并调用
struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
(*crtc_funcs->dpms)(crtc, drm_helper_choose_crtc_dpms(crtc))
drm_helper_encoder_dpms(encoder, encoder_dpms)
//获取encoder自定义的dpms接口,并调用
struct drm_encoder_helpers_funcs * encoder_funcs = encoder->helper_private
encoder_funcs->dpms(encoder, mode);
dpms的设置,目前找到一个,如下:
drm_connector_set_obj_prop
if (property == connector->dev->mode_config.dpms_property)
{
//如果设置connecotr的dpms属性,需要调用dpms接口
ret = (*connector->funcs->dpms)(connector, (int)value);
}
(2)reset
复位connector的state(drm_connector_state类型), 一般直接赋值为drm_atomic_helper_connector_reset, 该接口会复位state状态
其调用逻辑一般在plane/crtc/connector/encoder等初始化后, 通过drm_mode_config_reset调用:
vkms_output_int
drm_mode_config_reset
//遍历所有connector,并调用reset接口
drm_connector_list_iter_begin(dev, &conn_iter);
drm_for_each_connector_iter(connecotr, &conn_iter)
connecotr->funcs->reset(connector)
(3)detect
检测connector连接状态的,可以参考如下xlinx芯片的接口:
struct drm_connector_funcs zynqmp_dp_connector_funcs = {
.detect = zynqmp_dp_connector_detect,//该接口直接读寄存器获取连接状态
}
调用逻辑:
(1)drm_helper_probe_single_connector_modes
ret = drm_helper_probe_detect(connector, &ctx, true);
(2)drm_helper_hpd_irq_event
connector->status = drm_helper_probe_detect(connector, NULL, false);
return drm_helper_probe_detect_ctx(connector, force)
connctor->funcs->detect(connector, force);
connctor->funcs->detect(connector, force);
(4)force
貌似是用来强制设置connector的状态,待确认?
//drm_connector_funcs.fill_modes = drm_helper_probe_single_connector_modes
drm_helper_probe_single_connector_modes
if ( connector->force )
{
if (connector->force == DRM_FORCE_ON || ...)
connector->status = connector_status_connected;
if (connector->funcs->force)
connector->funcs->force(connector);
}
(5) fill_modes
用于输出模式的检测和过滤。一般会被赋值为drm_helper_probe_single_connector_modes
如下:
static const struct drm_connector_funcs vkms_connector_funcs = {
.fill_modes = drm_helper_probe_single_connector_modes,
...
}
具体梳理下函数内部逻辑:
drm_helper_probe_single_connector
if (connector->force )
{
//force connector的status
if (connector->funcs->force)
connecotr->funcs->force(connector)
}
else
//探测connector的连接状态,主要调用connector->funcs->detect[_ctx]
ret = drm_helper_probe_detect(connector, &ctx, true);
//connector_funcs = connetor->helper_private
// .get_modes = vkms_conn_get_modes
//这里调用的就是drm_connector_helper_funcs的.get_modes函数,由drm设备驱动自行定义
count = (*connector_funcs->get_modes)(connector);
//vkms_conn_get_modes
//直接添加mode信息
count = drm_add_modes_noedid(connector, XRES_MAX, YRES_MAX)
drm_set_perferred_mode(connector, XRES_DEF, YRES_DEF)
//通过edid增加mode到connect->probed_modes链表中
count = drm_add_override_edid_modes(connector);
count = drm_add_modes_noedid(connector, 1024, 768);
//通过cmdline的参数增加mode到probed_modes链表中
coutn = drm_helper_probe_add_cmdline_mode(connector);、
//将probed_modes链表中的modes添加到connector->modes中
drm_connector_list_update(connector);
list_for_each_entry(mode, &connector->modes, head)
{
//过滤验证所有modes以确认mode的status
drm_mode_validate_driver(dev, mode);
drm_mode_validate_size(mode, maxX, maxY);
drm_mode_validate_flag
//严重该mode在connector的管道有效性(crtc connector encoder)
drm_mode_pipe_line(mode, connector, &ctx, &mode->status)
}
mode->status = drm_mode_validate_ycbcr
//将mode->status != MODE_OK的 mode从connector->modes链表中删除掉
drm_mode_prune_invalid
//给connector->modes排序
drm_mode_sort(&connector->modes)
list_for_each_entry(mode, &connector->modes, head)
{
//更新mode->crtc_*参数
drm_mode_set_crtcinfo(mode, )
}
其调用逻辑如下:
//用户态
drmModeGetConnector()
conn.connector_id = connector_id;
drmIoctl(fd, DRM_IOCTL_MODE_GETCONNECTOR, &conn)
//内核态
DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCONNECTOR, drm_mode_getconnector, 0)
drm_mode_getconnector
//也就是说在用户态调用drmModeGetConnector时会探测获取connector的modes
connector->funcs->fill_modes(connector, max_width, max_height);
(6)late_register && early_unregister
这两个接口是为了在drm_connector_register后(late_register)/前(early_unregister)做一些额外的操作
(7)atomic_duplicate_state && atomic_destory_state
用于复制connector的state(drm_connector_state类型)和销毁state
一般会被赋值为helper接口,如下
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
调用逻辑如下:
//atomic方式获取connector state
drm_atomic_get_connector_state
connector_state = connector->funcs->atomic_duplicate_state(connector);
//清除connector state
drm_connector_cleanup
connector->funcs->atomic_destroy_state
(8)atomic_set_property && atomic_get_property
设置/获取driver-private属性值,也就是驱动自定义的非通用属性。一般是驱动自定义实现
其调用逻辑如下:
//用户态
int drmModeAtomicCommit
ret = DRM_IOCTL(fd, DRM_IOCTL_MODE_ATOMIC, &atomic);
//内核态
DRM_IOCTL_DEF(DRM_IOCTL_MODE_ATOMIC, drm_mode_atomic_ioctl, DRM_MASET)
drm_atomic_set_property
{
swtich(obj->type)
{
case DRM_MODE_OBJECT_CONNECTOR:
//设置connector的属性
drm_atomic_connector_set_property
connector->funcs->atomic_set_property
}
}
(9)atomic_print_state
打印当前connector的state
在cat /sys/kernel/debug/dri/0/state时,会以此遍历设备的所有plane /crtc/connector并打印其state信息
实现逻辑如下:
const struct drm_info_list drm_atomic_debugfs_list[] = {
{"state", drm_state_info, 0},
};
//drm_state_info
__drm_state_dump
//遍历plane 并打印其state
list_for_each_entry(plane, &config->plane_list, head)
drm_atomic_plane_print_state
//遍历crtc, 并打印其state
list_for_each_entry(crtc, &config->crtc_list, head)
drm_atomic_crtc_print_state
//遍历connector, 并打印其state
drm_connector_list_iter_begin(dev, &conn_iter)
drm_for_each_connector_iter(connector, &conn_iter)
drm_atomic_connectgr_print_state
drm_connector_list_iter_end(&conn_iter)
(10)
二 connector->helper_private
drm驱动自定义的接口,一般有connector->func回调. 其类型是drm_connector_helper_funcs类型
/**
* struct drm_connector_helper_funcs - helper operations for connectors
*
* These functions are used by the atomic and legacy modeset helpers and by the
* probe helpers.
*/
struct drm_connector_helper_funcs {
int (*get_modes)(struct drm_connector *connector);
int (*detect_ctx)(struct drm_connector *connector,
struct drm_modeset_acquire_ctx *ctx,
bool force);
enum drm_mode_status (*mode_valid)(struct drm_connector *connector,
struct drm_display_mode *mode);
int (*mode_valid_ctx)(struct drm_connector *connector,
struct drm_display_mode *mode,
struct drm_modeset_acquire_ctx *ctx,
enum drm_mode_status *status);
struct drm_encoder *(*best_encoder)(struct drm_connector *connector);
struct drm_encoder *(*atomic_best_encoder)(struct drm_connector *connector,
struct drm_atomic_state *state);
int (*atomic_check)(struct drm_connector *connector,
struct drm_atomic_state *state);
void (*atomic_commit)(struct drm_connector *connector,
struct drm_atomic_state *state);
int (*prepare_writeback_job)(struct drm_writeback_connector *connector,
struct drm_writeback_job *job);
void (*cleanup_writeback_job)(struct drm_writeback_connector *connector,
struct drm_writeback_job *job);
};
(1)get_modes
用于设置connector的output mode, 由drm_helper_probe_single_connector_modes调用
举例如下:
static const struct drm_connector_helper_funcs vkms_conn_helper_funcs = {
//用于设置connector的output mode, 由drm_helper_probe_single_connector_modes调用
.get_modes = vkms_conn_get_modes,
}
(2)atomic_check
//用来检查state, 不过没找到connector的atomic_check实例
(3)atomic_commit
//用来实现回写任务的,具体参考:
struct drm_connector_helper_funcs vkms_wb_conn_helper_funcs = {
.get_modes = vkms_wb_connector_get_modes,
.prepare_writeback_job = vkms_wb_prepare_job,
.cleanup_writeback_job = vkms_wb_cleanup_job,
.atomic_commit = vkms_wb_atomic_commit,
}
最后
以上就是虚拟蜻蜓为你收集整理的DRM框架(vkms)分析(3)----connector->func && connector->helper_private的使用的全部内容,希望文章能够帮你解决DRM框架(vkms)分析(3)----connector->func && connector->helper_private的使用所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复