DRM系列十:Drm之drm_atomic_check_only

本系列文章基于linux 5.15

接着上篇,在提交之前,需要进行check检查,此时会调用drm_atomic_check_only这一函数。

一、drm_atomic_check_only

主要作用是验证原子提交的状态是否合法。它通过检查plane、crtc 和connector的状态,确保这些状态不会导致硬件或软件冲突。如果检查通过,状态可以安全地提交到硬件;否则,返回错误并阻止提交。

int drm_atomic_check_only(struct drm_atomic_state *state)
{
   
   
	struct drm_device *dev = state->dev;
	struct drm_mode_config *config = &dev->mode_config;
	struct drm_plane *plane;
	struct drm_plane_state *old_plane_state;
	struct drm_plane_state *new_plane_state;
	struct drm_crtc *crtc;
	struct drm_crtc_state *old_crtc_state;
	struct drm_crtc_state *new_crtc_state;
	struct drm_connector *conn;
	struct drm_connector_state *conn_state;
	unsigned int requested_crtc = 0;
	unsigned int affected_crtc = 0;
	int i, ret = 0;

	DRM_DEBUG_ATOMIC("checking %p\n", state);

	for_each_new_crtc_in_state(state, crtc, new_crtc_state, i)
		requested_crtc |= drm_crtc_mask(crtc);

	for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, i) {
   
   
		/*检查plane的state里面的参数值是否合法*/
		ret = drm_atomic_plane_check(old_plane_state, new_plane_state);
		if (ret) {
   
   
			DRM_DEBUG_ATOMIC("[PLANE:%d:%s] atomic core check failed\n",
					 plane->base.id, plane->name);
			return ret;
		}
	}

	for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
   
   
		/*检查crtc的state里面的参数值是否合法*/
		ret = drm_atomic_crtc_check(old_crtc_state, new_crtc_state);
		if (ret) {
   
   
			DRM_DEBUG_ATOMIC("[CRTC:%d:%s] atomic core check failed\n",
					 crtc->base.id, crtc->name);
			return ret;
		}
	}

	for_each_new_connector_in_state(state, conn, conn_state, i) {
   
   
		/*检查connector的state里面的参数值是否合法*/
		ret = drm_atomic_connector_check(conn, conn_state);
		if (ret) {
   
   
			DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] atomic core check failed\n",
					 conn->base.id, conn->name);
			return ret;
		}
	}
/*调用 atomic_check 回调函数,调用该函数进行额外的check。(厂商自己实现)*/
	if (config->funcs->atomic_check) {
   
   
		ret = config->funcs->atomic_check(state->dev, state);

		if (ret) {
   
   
			DRM_DEBUG_ATOMIC("atomic driver check for %p failed: %d\n",
					 state, ret);
			return ret;
		}
	}
/*如果当前提交不允许模式设置(state->allow_modeset 为 false),
但某个 CRTC 需要完整模式设置(drm_atomic_crtc_needs_modeset 返回 true),则返回错误。*/
	if (!state->allow_modeset) {
   
   
		for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) {
   
   
			if (drm_atomic_crtc_needs_modeset(new_crtc_state)) {
   
   
				DRM_DEBUG_ATOMIC("[CRTC:%d:%s] requires full modeset\n",
						 crtc->base.id, crtc->name);
				return -EINVAL;
			}
		}
	}

	for_each_new_crtc_in_state(state, crtc, new_crtc_state, i)
		affected_crtc |= drm_crtc_mask(crtc);

	/*判断受影响的 CRTC 与请求的 CRTC 是否一致*/
	if (affected_crtc != requested_crtc) {
   
   
		DRM_DEBUG_ATOMIC("driver added CRTC to commit: requested 0x%x, affected 0x%0x\n",
				 requested_crtc, affected_crtc);
		WARN(!state->allow_modeset, "adding CRTC not allowed without modesets: requested 0x%x, affected 0x%0x\n",
		     requested_crtc, affected_crtc);
	}

	return 0;
}

drm_atomic_xxx_check函数是检查plane、crtc、connector相关state内容是否合法,比较简单,报错可以轻松找到问题点,这里不做详述。

1.config->funcs->atomic_check

调用 atomic_check 回调函数,调用该函数进行额外的check,这里都是各大厂商根据自己的驱动进行实现,以rockchip为例,atomic_check回调直接调用了drm_atomic_helper_check函数。

static const struct drm_mode_config_funcs rockchip_drm_mode_config_funcs = {
   
   
	.fb_create = rockchip_fb_create,
	.output_poll_changed = drm_fb_helper_output_poll_changed,
	.atomic_check = drm_atomic_helper_check,
	.atomic_commit = drm_atomic_helper_commit,
};

1.1drm_atomic_helper_check

用于在提交原子状态之前对其进行验证和准备。

int drm_atomic_helper_check(struct drm_device *dev,
			    struct drm_atomic_state *state)
{
   
   
	int ret;
/*检查并验证原子状态中的 modeset(显示模式设置)部分。
它确保提出的显示配置(例如分辨率、刷新率)是有效的.*/
	ret = drm_atomic_helper_check_modeset(dev, state);
	if (ret)
		return ret;
/*如果设备的 mode_config 中启用了 normalize_zpos 标志,该函数会规范化平面的 z-pos(z 轴位置)。
z-pos 决定了平面的堆叠顺序(例如哪个平面显示在另一个平面的上方)。*/
	if (dev->mode_config.normalize_zpos) {
   
   
		ret = drm_atomic_normalize_zpos(dev, state);
		if (ret)
			return ret;
	}
/*检查并验证原子状态中的 平面(plane)部分。
它确保所有平面的配置(例如大小、格式、位置)是有效的。*/
	ret = drm_atomic_helper_check_planes(dev, state);
	if (ret)
		return ret;
/*如果 state->legacy_cursor_update 为真,表示这是一个传统的游标更新。
通过调用 drm_atomic_helper_async_check(dev, state) 检查是否可以异步更新。
如果可以异步更新,state->async_update 被设置为 true,否则为 false。
目前异步还未设计,之后在研究*/
	if (state->legacy_cursor_update)
		state->async_update = !drm_atomic_helper_async_check(dev, state);
/*与 自刷新(self-refresh)功能相关,用于调整状态以支持自刷新模式。
自刷新是一种节能技术,允许显示器在内容未变化时降低刷新率*/
	
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值