DRM框架(vkms)分析(3)----connector->func && connector->helper_private的使用

一 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,
}

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值