本系列文章基于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)功能相关,用于调整状态以支持自刷新模式。
自刷新是一种节能技术,允许显示器在内容未变化时降低刷新率*/

最低0.47元/天 解锁文章
1735

被折叠的 条评论
为什么被折叠?



