模式设置辅助函数

DRM 子系统旨在将核心代码和辅助库之间进行强分离。核心代码负责通用设置和拆卸以及将用户空间请求解码为内核内部对象。 其他一切都由大量辅助库处理,这些辅助库可以自由组合以选择适合每个驱动程序的库,并避免在需要特殊行为时共享代码。

核心代码和辅助函数之间的这种区别在模式设置代码中尤为突出,其中所有驱动程序都有一个共享的用户空间 ABI。 这与渲染方面形成对比,渲染方面几乎所有内容(极少数例外)都可以被认为是可选的辅助代码。

这些辅助函数可以分为几个区域

  • 用于实现模式设置的辅助函数。 这里重要的是原子辅助函数。 旧驱动程序仍然经常使用旧版 CRTC 辅助函数。 它们都共享同一组公共辅助 vtables。 对于非常简单的驱动程序(任何非常适合已弃用的 fbdev 子系统的驱动程序),还有简单的显示管道辅助函数。

  • 有很多用于处理输出的辅助函数。 首先是用于处理编码器和转码器 IP 块的通用桥接辅助函数。 其次是用于处理面板相关信息和逻辑的面板辅助函数。 此外还有用于各种接收器标准(DisplayPort、HDMI、MIPI DSI)的大量辅助函数。 最后还有用于处理输出探测和处理 EDID 的通用辅助函数。

  • 最后一组辅助函数关注显示管道的前端:平面、处理矩形以进行可见性检查和剪切、翻转队列和各种位。

通用 Vtable 的模式设置辅助函数参考

DRM 模式设置辅助函数是驱动程序可以使用的通用代码(如果他们愿意)。 驱动程序不必在其实现中使用此代码,但如果他们使用的代码至少为用户空间提供一致的接口和操作,这将非常有用。 因此,强烈建议尽可能多地使用提供的辅助函数。

因为每个模式设置对象只有一个指针可以保存辅助库的 vfunc 表,所以它们必须在不同的辅助函数之间共享。

为了清楚起见,所有辅助 vtable 都集中在此处。

struct drm_crtc_helper_funcs

CRTC 的辅助操作

定义:

struct drm_crtc_helper_funcs {
    void (*dpms)(struct drm_crtc *crtc, int mode);
    void (*prepare)(struct drm_crtc *crtc);
    void (*commit)(struct drm_crtc *crtc);
    enum drm_mode_status (*mode_valid)(struct drm_crtc *crtc, const struct drm_display_mode *mode);
    bool (*mode_fixup)(struct drm_crtc *crtc,const struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode);
    int (*mode_set)(struct drm_crtc *crtc, struct drm_display_mode *mode,struct drm_display_mode *adjusted_mode, int x, int y, struct drm_framebuffer *old_fb);
    void (*mode_set_nofb)(struct drm_crtc *crtc);
    int (*mode_set_base)(struct drm_crtc *crtc, int x, int y, struct drm_framebuffer *old_fb);
    int (*mode_set_base_atomic)(struct drm_crtc *crtc,struct drm_framebuffer *fb, int x, int y, enum mode_set_atomic);
    void (*disable)(struct drm_crtc *crtc);
    int (*atomic_check)(struct drm_crtc *crtc, struct drm_atomic_state *state);
    void (*atomic_begin)(struct drm_crtc *crtc, struct drm_atomic_state *state);
    void (*atomic_flush)(struct drm_crtc *crtc, struct drm_atomic_state *state);
    void (*atomic_enable)(struct drm_crtc *crtc, struct drm_atomic_state *state);
    void (*atomic_disable)(struct drm_crtc *crtc, struct drm_atomic_state *state);
    bool (*get_scanout_position)(struct drm_crtc *crtc,bool in_vblank_irq, int *vpos, int *hpos,ktime_t *stime, ktime_t *etime, const struct drm_display_mode *mode);
};

成员

dpms

用于控制 CRTC 上的功率级别的回调。 如果传入的模式不受支持,则提供程序必须使用下一个最低功率级别。 旧版 CRTC 辅助函数使用此功能在 drm_helper_connector_dpms() 中实现 DPMS 功能。

如果未使用 disable 挂钩,此回调也用于通过使用 DRM_MODE_DPMS_OFF 调用来禁用 CRTC。

此回调由旧版 CRTC 辅助函数使用。 原子辅助函数也支持使用此挂钩来启用和禁用 CRTC 以方便过渡到原子,但不建议使用。 应该使用 atomic_enableatomic_disable

prepare

此回调应准备 CRTC 以进行后续模式设置,这实际上意味着如果 CRTC 正在运行,则驱动程序应禁用它。 大多数驱动程序最终通过使用 DRM_MODE_DPMS_OFF 调用其 dpms 挂钩来实现此目的。

此回调由旧版 CRTC 辅助函数使用。 原子辅助函数也支持使用此挂钩来禁用 CRTC 以方便过渡到原子,但不建议使用。 应该使用 atomic_disable

commit

此回调应在模式设置后提交 CRTC 上的新模式,这实际上意味着驱动程序应启用 CRTC。 大多数驱动程序最终通过使用 DRM_MODE_DPMS_ON 调用其 dpms 挂钩来实现此目的。

此回调由旧版 CRTC 辅助函数使用。 原子辅助函数也支持使用此挂钩来启用 CRTC 以方便过渡到原子,但不建议使用。 应该使用 atomic_enable

mode_valid

此回调用于检查特定模式在此 crtc 中是否有效。 如果 crtc 在其可以显示的模式中存在某种限制,则应实现此功能。 例如,给定的 crtc 可能负责设置时钟值。 如果时钟无法生成可用模式的所有值,则可以使用此回调将模式数量限制为只能显示的模式。

此挂钩由探测辅助函数用于筛选 drm_helper_probe_single_connector_modes() 中的模式列表,并且原子辅助函数使用它来验证用户空间在 drm_atomic_helper_check_modeset() 中提供的模式。

此函数是可选的。

注意

由于此函数是从原子提交的检查阶段和探测路径中的模式验证调用的,因此不允许查看除传入模式之外的任何内容,并根据配置不变的硬件约束对其进行验证。 任何其他取决于配置的限制只能在 mode_fixupatomic_check 中检查。

返回值

drm_mode_status 枚举

mode_fixup

此回调用于验证模式。 参数 mode 是用户空间请求的显示模式,adjusted_mode 是编码器需要馈送的模式。 请注意,这与 drm_encoderdrm_bridge_funcs.mode_fixup vfunc 的含义相反。 如果 CRTC 无法支持从 mode 到 adjusted_mode 的请求转换,则应拒绝模式设置。 有关更多详细信息,另请参见 drm_crtc_state.adjusted_mode

此函数由旧版 CRTC 辅助函数和原子辅助函数使用。 对于原子辅助函数,它是可选的。

注意

此函数在原子模式设置的检查阶段调用,由于任何原因都可以中止(包括应用户空间的要求只是检查配置是否可行)。 原子驱动程序不得触及任何持久状态(硬件或软件)或数据结构,除了传入的 adjusted_mode 参数。

这与旧版 CRTC 辅助函数形成对比,在旧版 CRTC 辅助函数中,这是允许的。

如果需要检查和调整更多状态,原子驱动程序应改用 atomic_check 回调,但请注意,它们并非完全等效:mode_valid 是从 drm_atomic_helper_check_modeset() 调用的,但 atomic_check 是从 drm_atomic_helper_check_planes() 调用的,因为最初它仅用于平面更新检查。

另请注意,用户空间可以请求自己的自定义模式,核心或辅助函数都不会将模式筛选到 GETCONNECTOR IOCTL 报告并存储在 drm_connector.modes 中的探测模式列表中。 要确保模式得到一致的筛选,请将任何 CRTC 约束和限制检查放入 mode_valid 中。

返回值

如果可以接受的配置是可能的,则为 True,如果应拒绝模式设置操作,则为 False。

mode_set

此回调由旧版 CRTC 辅助函数用于设置新模式、位置和帧缓冲。 由于它将主平面绑定到每个模式更改,因此它与通用平面支持不兼容。 并且由于它无法更新其他平面,因此它与原子模式设置支持不兼容。

此回调仅由 CRTC 辅助函数使用,并且已弃用。

返回值

成功时为 0,失败时为负错误代码。

mode_set_nofb

此回调用于更新 CRTC 的显示模式,而不更改主平面配置的任何内容。 这符合原子的要求,因此被原子辅助函数使用。

请注意,调用此函数时,显示管道已完全关闭。 如果需要硬件在程序新显示模式之前运行(例如,因为它们实现了运行时 PM)的原子驱动程序不应使用此挂钩。 这是因为辅助库每次模式更改只调用此挂钩一次,而不是每次使用 DPMS 或新的“ACTIVE”属性暂停显示管道时都调用。 这意味着在此回调中设置的寄存器值可能会在 CRTC 暂停时重置,但不会恢复。 此类驱动程序应将所有 CRTC 设置移到 atomic_enable 回调中。

此回调是可选的。

mode_set_base

此回调由旧版 CRTC 辅助函数用于设置新的帧缓冲和扫描输出位置。 它是可选的,可用作优化的快速路径,而不是具有所有结果闪烁的完整模式设置操作。 如果不存在,drm_crtc_helper_set_config() 将回退到完整模式设置,使用 mode_set 回调。 由于它无法更新其他平面,因此它与原子模式设置支持不兼容。

此回调仅由 CRTC 辅助函数使用,并且已弃用。

返回值

成功时为 0,失败时为负错误代码。

mode_set_base_atomic

此回调由 fbdev 辅助函数用于设置新的帧缓冲和扫描输出,而无需休眠,即从原子调用上下文中进行。 它仅用于实现 kgdb 支持。

此回调是可选的,仅在 fbdev 辅助函数中需要 kgdb 支持。

返回值

成功时为 0,失败时为负错误代码。

disable

应使用此回调来禁用 CRTC。 对于原子驱动程序,在连接到此 CRTC 的所有编码器已使用其自己的 drm_encoder_helper_funcs.disable 挂钩关闭后,会调用它。 如果该序列太简单,驱动程序可以只添加自己的挂钩,并通过使用 for_each_encoder_on_crtc() 循环遍历连接到它的所有编码器,从此 CRTC 回调中调用它。

旧版 CRTC 辅助函数和原子辅助函数都使用此挂钩。 如果不需要在 CRTC 级别禁用任何内容,则原子驱动程序不需要实现它。 为了确保运行时 PM 处理(使用 DPMS 或新的“ACTIVE”属性)工作,对于原子驱动程序,disable 必须是 atomic_enable 的反函数。 原子驱动程序应考虑使用 atomic_disable 而不是这个。

注意

对于旧版 CRTC 辅助函数,disable 和用于关闭 CRTC 的其他挂钩(如 preparedpms)之间存在很大的语义差异:只有在逻辑上禁用显示管道时才调用 disable,并且需要释放在 mode_set 中获取的任何资源(如共享 PLL,或再次释放固定的帧缓冲)。

因此,对于仍然使用旧版 CRTC 辅助函数的驱动程序,disable 必须是 mode_setcommit 的反函数,这与原子下的规则不同。

atomic_check

驱动程序应在此挂钩中检查与平面更新相关的 CRTC 约束。 他们还可以检查与模式相关的限制,但需要注意调用顺序,因为此挂钩由 drm_atomic_helper_check_planes() 使用,而检查输出路由和显示模式所需的准备工作是在 drm_atomic_helper_check_modeset() 中完成的。 因此,如果驱动程序想要在此回调中检查输出路由和显示模式约束,则必须确保之前已调用 drm_atomic_helper_check_modeset()。 这是 drm_atomic_helper_check() 中默认辅助实现的调用顺序。

当使用 drm_atomic_helper_check_planes() 时,此挂钩在平面的 drm_plane_helper_funcs.atomic_check 挂钩之后调用,这允许驱动程序在此回调中分配由平面请求的共享资源。 对于更复杂的依赖关系,驱动程序可以多次调用提供的检查辅助函数,直到计算出的状态具有最终配置并且所有内容都已检查。

还允许此函数检查任何其他对象的状态,并且如果需要,可以将更多状态对象添加到原子提交。 但是,必须小心确保调用这些添加状态的状态检查和计算函数,并且更新其他对象中的派生状态。 再次建议只调用检查辅助函数,直到达到最大配置。

原子模式设置辅助函数使用此回调,但它是可选的。

注意

此函数在原子更新的检查阶段调用。 不允许驱动程序更改传入的独立状态对象之外的任何内容。

另请注意,用户空间可以请求自己的自定义模式,核心或辅助函数都不会将模式筛选到 GETCONNECTOR IOCTL 报告并存储在 drm_connector.modes 中的探测模式列表中。 要确保模式得到一致的筛选,请将任何 CRTC 约束和限制检查放入 mode_valid 中。

返回值

成功时为 0,如果不支持状态或转换,则为 -EINVAL,内存分配失败时为 -ENOMEM,如果尝试获取另一个状态对象遇到 drm_modeset_lock 死锁,则为 -EDEADLK。

atomic_begin

驱动程序应在此挂钩中准备对 CRTC 上的多个平面进行原子更新。 根据硬件的不同,这可能是 vblank 回避,通过设置位来阻止更新,或者为例如手动更新显示做准备工作。

在调用任何平面提交函数之前调用此挂钩。

请注意,调用此函数时显示管道的电源状态取决于驱动程序选择的确切辅助函数和调用序列。 有关平面提交辅助函数的权衡和变体的讨论,请参见 drm_atomic_helper_commit_planes()

原子模式设置辅助函数使用此回调,但它是可选的。

atomic_flush

驱动程序应在此挂钩中完成 CRTC 上多个平面的原子更新。 根据硬件的不同,这可能包括检查 vblank 回避是否成功,通过设置位来取消阻止更新,或者设置 GO 位以刷新所有更新。

具有特殊要求的简单硬件或硬件可以从此挂钩提交和刷新所有平面的所有更新,并放弃平面更新的所有其他提交挂钩。

在调用任何平面提交函数之后调用此挂钩。

请注意,调用此函数时显示管道的电源状态取决于驱动程序选择的确切辅助函数和调用序列。 有关平面提交辅助函数的权衡和变体的讨论,请参见 drm_atomic_helper_commit_planes()

原子模式设置辅助函数使用此回调,但它是可选的。

atomic_enable

应使用此回调来启用 CRTC。 对于原子驱动程序,在此编码器的 CRTC 已使用其自己的 drm_crtc_helper_funcs.atomic_enable 挂钩启用之前调用。 如果该序列太简单,驱动程序可以只添加自己的挂钩,并通过使用 for_each_encoder_on_crtc() 循环遍历连接到它的所有编码器,从此 CRTC 回调中调用它们。

此挂钩仅由原子辅助函数使用,以与 atomic_disable 对称。 如果不需要在 CRTC 级别启用任何内容,则原子驱动程序不需要实现它。 为了确保运行时 PM 处理(使用 DPMS 或新的“ACTIVE”属性)工作,对于原子驱动程序,atomic_enable 必须是 atomic_disable 的反函数。

此函数是可选的。

atomic_disable

应使用此回调来禁用 CRTC。 对于原子驱动程序,在连接到此 CRTC 的所有编码器已使用其自己的 drm_encoder_helper_funcs.disable 挂钩关闭后,会调用它。 如果该序列太简单,驱动程序可以只添加自己的挂钩,并通过使用 for_each_encoder_on_crtc() 循环遍历连接到它的所有编码器,从此 CRTC 回调中调用它。

此挂钩仅由原子辅助函数使用。 如果不需要在 CRTC 级别禁用任何内容,则原子驱动程序不需要实现它。

此函数是可选的。

get_scanout_position

由 vblank 时间戳代码调用。

从 CRTC 返回当前显示扫描输出位置,以及测量位置时可选的精确 ktime_get() 时间戳。 请注意,这是一个辅助回调,仅当驱动程序使用 drm_crtc_vblank_helper_get_vblank_timestamp() 作为 drm_crtc_funcs.get_vblank_timestamp 回调时才使用。

参数

crtc

CRTC。

in_vblank_irq

drm_crtc_handle_vblank() 调用时为 True。 如果设置了该标志,一些驱动程序需要应用一些针对 gpu 特定 vblank irq 错误的解决方法。

vpos

当前垂直扫描输出位置的目标位置。

hpos

当前水平扫描输出位置的目标位置。

stime

紧接在扫描输出位置查询之前获取的时间戳的目标位置。 可以为 NULL 以跳过时间戳。

etime

紧接在扫描输出位置查询之后获取的时间戳的目标位置。 可以为 NULL 以跳过时间戳。

mode

当前显示时序。

在活动扫描输出区域中时,将 vpos 返回为正数。 在 vblank 内时,将 vpos 返回为负数,计数到 vblank 结束的扫描线数,例如,-1 表示“到活动扫描输出/vblank 结束还有一条扫描线”。

返回值

成功时为 True,如果无法读出可靠的扫描输出位置计数器,则为 False。

描述

旧版 CRTC 辅助函数和新的原子模式设置辅助函数使用这些挂钩。

void drm_crtc_helper_add(struct drm_crtc *crtc, const struct drm_crtc_helper_funcs *funcs)

设置 crtc 的辅助 vtable

参数

struct drm_crtc *crtc

DRM CRTC

const struct drm_crtc_helper_funcs *funcs

要为 crtc 设置的辅助 vtable

struct drm_encoder_helper_funcs

编码器的辅助操作

定义:

struct drm_encoder_helper_funcs {
    void (*dpms)(struct drm_encoder *encoder, int mode);
    enum drm_mode_status (*mode_valid)(struct drm_encoder *crtc, const struct drm_display_mode *mode);
    bool (*mode_fixup)(struct drm_encoder *encoder,const struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode);
    void (*prepare)(struct drm_encoder *encoder);
    void (*commit)(struct drm_encoder *encoder);
    void (*mode_set)(struct drm_encoder *encoder,struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode);
    void (*atomic_mode_set)(struct drm_encoder *encoder,struct drm_crtc_state *crtc_state, struct drm_connector_state *conn_state);
    enum drm_connector_status (*detect)(struct drm_encoder *encoder, struct drm_connector *connector);
    void (*atomic_disable)(struct drm_encoder *encoder, struct drm_atomic_state *state);
    void (*atomic_enable)(struct drm_encoder *encoder, struct drm_atomic_state *state);
    void (*disable)(struct drm_encoder *encoder);
    void (*enable)(struct drm_encoder *encoder);
    int (*atomic_check)(struct drm_encoder *encoder,struct drm_crtc_state *crtc_state, struct drm_connector_state *conn_state);
};

成员

dpms

用于控制编码器上的功率级别的回调。 如果传入的模式不受支持,则提供程序必须使用下一个最低功率级别。 旧版编码器辅助函数使用此功能在 drm_helper_connector_dpms() 中实现 DPMS 功能。

如果未使用 disable 挂钩,此回调也用于通过使用 DRM_MODE_DPMS_OFF 调用来禁用编码器。

此回调由旧版 CRTC 辅助函数使用。 原子辅助函数也支持使用此挂钩来启用和禁用编码器以方便过渡到原子,但不建议使用。 应该使用 enabledisable

mode_valid

此回调用于检查特定模式在此编码器中是否有效。 如果编码器在其可以显示的模式中存在某种限制,则应实现此功能。 例如,给定的编码器可能负责设置时钟值。 如果时钟无法生成可用模式的所有值,则可以使用此回调将模式数量限制为只能显示的模式。

此挂钩由探测辅助函数用于筛选 drm_helper_probe_single_connector_modes() 中的模式列表,并且原子辅助函数使用它来验证用户空间在 drm_atomic_helper_check_modeset() 中提供的模式。

此函数是可选的。

注意

由于此函数是从原子提交的检查阶段和探测路径中的模式验证调用的,因此不允许查看除传入模式之外的任何内容,并根据配置不变的硬件约束对其进行验证。 任何其他取决于配置的限制只能在 mode_fixupatomic_check 中检查。

返回值

drm_mode_status 枚举

mode_fixup

此回调用于验证和调整模式。 参数 mode 是应馈送到显示链中下一个元素的显示模式,即最终的 drm_connectordrm_bridge。 参数 adjusted_mode 是编码器所需的输入模式。 它可以由此回调修改,并且不需要与 mode 匹配。 有关更多详细信息,另请参见 drm_crtc_state.adjusted_mode

此函数由旧版 CRTC 辅助函数和原子辅助函数使用。 此挂钩是可选的。

注意

此函数在原子模式设置的检查阶段调用,由于任何原因都可以中止(包括应用户空间的要求只是检查配置是否可行)。 原子驱动程序不得触及任何持久状态(硬件或软件)或数据结构,除了传入的 adjusted_mode 参数。

这与旧版 CRTC 辅助函数形成对比,在旧版 CRTC 辅助函数中,这是允许的。

如果需要检查和调整更多状态,原子驱动程序应改用 atomic_check 回调。 如果使用 atomic_check,则不会调用此挂钩,因为 atomic_check 允许 mode_fixup 功能的严格超集。

另请注意,用户空间可以请求自己的自定义模式,核心或辅助函数都不会将模式筛选到 GETCONNECTOR IOCTL 报告并存储在 drm_connector.modes 中的探测模式列表中。 要确保模式得到一致的筛选,请将任何编码器约束和限制检查放入 mode_valid 中。

返回值

如果可以接受的配置是可能的,则为 True,如果应拒绝模式设置操作,则为 False。

prepare

此回调应准备编码器以进行后续模式设置,这实际上意味着如果编码器正在运行,则驱动程序应禁用它。 大多数驱动程序最终通过使用 DRM_MODE_DPMS_OFF 调用其 dpms 挂钩来实现此目的。

此回调由旧版 CRTC 辅助函数使用。 原子辅助函数也支持使用此挂钩来禁用编码器以方便过渡到原子,但不建议使用。 应该使用 disable

commit

此回调应在模式设置后提交编码器上的新模式,这实际上意味着驱动程序应启用编码器。 大多数驱动程序最终通过使用 DRM_MODE_DPMS_ON 调用其 dpms 挂钩来实现此目的。

此回调由旧版 CRTC 辅助函数使用。 原子辅助函数也支持使用此挂钩来启用编码器以方便过渡到原子,但不建议使用。 应该使用 enable

mode_set

此回调用于更新编码器的显示模式。

请注意,调用此函数时,显示管道已完全关闭。 如果需要硬件在程序新显示模式之前运行(因为它们实现了运行时 PM)的驱动程序不应使用此挂钩,因为辅助库只调用它一次,而不是每次使用 DPMS 或新的“ACTIVE”属性暂停显示管道时都调用。 此类驱动程序应将所有编码器设置移到 enable 回调中。

旧版 CRTC 辅助函数和原子模式设置辅助函数都使用此回调。 在原子辅助函数中,它是可选的。

注意

如果驱动程序使用原子模式设置辅助函数,并且需要在模式设置期间检查连接器状态或连接器显示信息,则可以使用 atomic_mode_set

atomic_mode_set

此回调用于更新编码器的显示模式。

请注意,调用此函数时,显示管道已完全关闭。 如果需要硬件在程序新显示模式之前运行(因为它们实现了运行时 PM)的驱动程序不应使用此挂钩,因为辅助库只调用它一次,而不是每次使用 DPMS 或新的“ACTIVE”属性暂停显示管道时都调用。 此类驱动程序应将所有编码器设置移到 enable 回调中。

如果驱动程序设置了 atomic_mode_set,则原子模式设置辅助函数会使用它来代替 mode_set 回调。 它是可选的,如果驱动程序需要检查连接器状态或显示信息,则应使用它来代替 mode_set,因为没有直接从编码器转到当前连接器的方法。

detect

如果驱动程序想要在编码器对象上而不是在连接器函数中进行检测,可以使用此回调。

任何辅助函数都不会使用它,因此它具有纯粹的驱动程序特定语义。 新驱动程序不应使用此功能,而应只实现自己的私有回调。

FIXME

这应该转换为驱动程序 vfunc 堆栈。 目前 radeon、amdgpu 和 nouveau 正在使用它。

atomic_disable

应使用此回调来禁用编码器。 对于原子驱动程序,在使用其自己的 drm_crtc_helper_funcs.atomic_disable 挂钩关闭此编码器的 CRTC 之前调用此回调。 如果该序列太简单,驱动程序可以只添加自己的驱动程序专用编码器挂钩,并通过使用 for_each_encoder_on_crtc() 循环遍历连接到它的所有编码器,从 CRTC 的回调中调用它们。

此回调是 disable 的变体,它将原子状态提供给驱动程序。 如果实现了 atomic_disable,则辅助函数不会调用 disable

此挂钩仅由原子辅助函数使用。 如果不需要在编码器级别禁用任何内容,则原子驱动程序不需要实现它。 为了确保运行时 PM 处理(使用 DPMS 或新的“ACTIVE”属性)工作,atomic_disable 必须是 atomic_enable 的反函数。

atomic_enable

应使用此回调来启用编码器。 在使用其自己的 drm_crtc_helper_funcs.atomic_enable 挂钩启用此编码器的 CRTC 之后调用此回调。 如果该序列太简单,驱动程序可以只添加自己的驱动程序专用编码器挂钩,并通过使用 for_each_encoder_on_crtc() 循环遍历连接到它的所有编码器,从 CRTC 的回调中调用它们。

此回调是 enable 的变体,它将原子状态提供给驱动程序。 如果实现了 atomic_enable,则辅助函数不会调用 enable

此挂钩仅由原子辅助函数使用,它是 atomic_disable 的反函数。 如果不需要在编码器级别启用任何内容,则原子驱动程序不需要实现它。 为了确保运行时 PM 处理工作,atomic_enable 必须是 atomic_disable 的反函数。

disable

此回调应用于禁用编码器。对于原子驱动程序,它会在使用 drm_crtc_helper_funcs.disable 钩子关闭此编码器的 CRTC 之前调用。如果该序列过于简单,驱动程序可以只添加自己的驱动程序私有编码器钩子,并通过使用 for_each_encoder_on_crtc() 循环连接到 CRTC 的所有编码器,从 CRTC 的回调中调用它们。

旧式 CRTC 助手和原子助手都使用此钩子。如果不需要在编码器级别禁用任何内容,则原子驱动程序不需要实现它。为了确保运行时 PM 处理(使用 DPMS 或新的“ACTIVE”属性)正常工作,对于原子驱动程序,disable 必须是 enable 的逆操作。

对于原子驱动程序,还可以考虑 atomic_disable,这样就不需要阅读下面的注释了!

注意

对于旧式 CRTC 助手,disable 与用于关闭编码器的其他钩子(如 preparedpms)之间存在很大的语义差异:disable 仅在逻辑上也禁用显示管道时调用,并且需要释放在 mode_set 中获得的任何资源(如共享 PLL 或再次释放固定的帧缓冲区)。

因此,对于仍然使用旧版 CRTC 辅助函数的驱动程序,disable 必须是 mode_setcommit 的反函数,这与原子下的规则不同。

enable

此回调应用于启用编码器。对于原子驱动程序,它会在使用 drm_crtc_helper_funcs.enable 钩子启用此编码器的 CRTC 之后调用。如果该序列过于简单,驱动程序可以只添加自己的驱动程序私有编码器钩子,并通过使用 for_each_encoder_on_crtc() 循环连接到 CRTC 的所有编码器,从 CRTC 的回调中调用它们。

此钩子仅由原子助手使用,它是 disable 的逆操作。如果不需要在编码器级别启用任何内容,则原子驱动程序不需要实现它。为了确保运行时 PM 处理(使用 DPMS 或新的“ACTIVE”属性)正常工作,对于原子驱动程序,enable 必须是 disable 的逆操作。

atomic_check

此回调用于验证原子驱动程序的编码器状态。由于编码器是连接 CRTC 和连接器的对象,因此它会传递两种状态,以便能够验证交互并更新 CRTC 以匹配编码器对请求的连接器的需求。

由于这提供了 mode_fixup 功能的严格超集(请求的和调整的模式都可以通过传入的 struct drm_crtc_state 获取),因此当实现 atomic_check 时,不会调用 mode_fixup

此函数由原子助手使用,但它是可选的。

注意

此函数在原子更新的检查阶段调用。不允许驱动程序更改传入的独立状态对象之外的任何内容,或在整个 drm_atomic_state 更新跟踪结构中组装的任何内容。

另请注意,用户空间可以请求自己的自定义模式,核心或辅助函数都不会将模式筛选到 GETCONNECTOR IOCTL 报告并存储在 drm_connector.modes 中的探测模式列表中。 要确保模式得到一致的筛选,请将任何编码器约束和限制检查放入 mode_valid 中。

返回值

成功时为 0,如果不支持状态或转换,则为 -EINVAL,内存分配失败时为 -ENOMEM,如果尝试获取另一个状态对象遇到 drm_modeset_lock 死锁,则为 -EDEADLK。

描述

旧版 CRTC 辅助函数和新的原子模式设置辅助函数使用这些挂钩。

void drm_encoder_helper_add(struct drm_encoder *encoder, const struct drm_encoder_helper_funcs *funcs)

设置编码器的助手 vtable

参数

struct drm_encoder *encoder

DRM 编码器

const struct drm_encoder_helper_funcs *funcs

要为 encoder 设置的助手 vtable

struct drm_connector_helper_funcs

连接器的助手操作

定义:

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, const struct drm_display_mode *mode);
    int (*mode_valid_ctx)(struct drm_connector *connector,const 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);
    void (*enable_hpd)(struct drm_connector *connector);
    void (*disable_hpd)(struct drm_connector *connector);
};

成员

get_modes

此函数应将当前对接收器有效的所有模式填充到 drm_connector.probed_modes 列表中。它还应通过调用 drm_connector_update_edid_property() 来更新 EDID 属性。

实现此目的的常用方法是在驱动程序私有连接器结构中的探测回调中缓存检索到的 EDID。然后,在此函数中,驱动程序解析 EDID 中的模式,并通过调用 drm_add_edid_modes() 添加它们。但是,驱动固定面板的连接器也可以使用 drm_mode_probed_add() 手动添加特定模式。手动添加模式的驱动程序还应确保填充 drm_connector.display_infodrm_connector.width_mmdrm_connector.height_mm 字段。

请注意,如果 .get_modes() 助手操作返回无模式,并且连接器状态为 connector_status_connected 或 connector_status_unknown,则调用方函数将自动添加高达 1024x768 的标准 VESA DMT 模式。在这种情况下,无需手动调用 drm_add_modes_noedid()

只想要具有给定分辨率的某些标准 VESA 模式的虚拟驱动程序可以调用 drm_add_modes_noedid(),并使用 drm_set_preferred_mode() 标记首选模式。

仅在 detect 钩子指示已连接接收器且 EDID 未通过 sysfs 或内核命令行覆盖后才调用此函数。

此回调由探测助手使用,例如 drm_helper_probe_single_connector_modes()

为了避免与并发连接器状态更新发生竞争,助手库始终使用 drm_mode_config.connection_mutex 来调用此方法。因此,检查 drm_connector->state 是安全的。

返回值

通过调用 drm_mode_probed_add() 添加的模式数。在失败时返回 0(无模式),而不是负错误代码。

detect_ctx

检查是否有任何东西连接到连接器。轮询时,参数 force 设置为 false;由于用户请求检查连接器时,参数 force 设置为 true。驱动程序可以使用 force 来避免在自动探测期间进行昂贵的破坏性操作。

此回调是可选的,如果未实现,则连接器将被视为始终已连接。

这是 drm_connector_funcs.detect 的原子版本。

为了避免与并发连接器状态更新发生竞争,助手库始终使用 ctx 设置为有效上下文来调用此方法,并且 drm_mode_config.connection_mutex 将始终使用 ctx 参数设置为此 ctx 来锁定。这允许根据需要获取额外的锁。

返回值

指示连接器状态的 drm_connector_statusdrm_modeset_lock() 返回的错误代码 -EDEADLK。

mode_valid

用于验证连接器的模式的回调,与特定显示配置无关。

此回调由探测助手使用,以过滤模式列表(通常是从接收器的 EDID 数据块派生的)。请参见例如 drm_helper_probe_single_connector_modes()

此函数是可选的。

注意

这仅过滤在 GETCONNECTOR IOCTL 中提供给用户空间的模式列表。与 drm_encoder_helper_funcs.mode_validdrm_crtc_helper_funcs.mode_validdrm_bridge_funcs.mode_valid 相比,这些函数也由 drm_atomic_helper_check_modeset() 中的原子助手调用。这允许用户空间强制和忽略接收器约束(例如屏幕 EDID 中的像素时钟限制),这对于测试或解决损坏的 EDID 非常有用。因此,任何源硬件约束(始终需要强制执行)都应在上述回调之一中进行检查,而不是在此处。

为了避免与并发连接器状态更新发生竞争,助手库始终使用 drm_mode_config.connection_mutex 来调用此方法。因此,检查 drm_connector->state 是安全的。

返回值

或者是 drm_mode_status.MODE_OK 或者是 enum drm_mode_status 中的故障原因之一。

mode_valid_ctx

用于验证连接器的模式的回调,与特定显示配置无关。

此回调由探测助手使用,以过滤模式列表(通常是从接收器的 EDID 数据块派生的)。请参见例如 drm_helper_probe_single_connector_modes()

此函数是可选的,并且是 drm_connector_helper_funcs.mode_valid 的原子版本。

为了允许访问模式设置对象的原子状态,助手库始终使用 ctx 设置为有效上下文来调用此方法,并且 drm_mode_config.connection_mutex 将始终使用 ctx 参数设置为 ctx 来锁定。这允许根据需要获取额外的锁。

即使可以获取额外的锁,仍然希望此回调不考虑任何受当前设置的显示状态影响的约束 - 此类约束应在驱动程序的原子检查中处理。例如,如果连接器与其他连接器共享显示带宽,则可以根据连接器的最大可能带宽验证模式的最低带宽要求。但是,考虑其他连接器的当前带宽使用情况是不可行的,因为这会根据显示状态而变化。

返回值:如果 drm_connector_helper_funcs.mode_valid_ctx 成功并将 enum drm_mode_status 值写入 status,则返回 0;否则,返回负错误代码。

best_encoder

此函数应为给定连接器选择最佳编码器。

此函数由原子助手(在 drm_atomic_helper_check_modeset() 函数中)和旧式 CRTC 助手使用。

注意

在原子驱动程序中,此函数在原子更新的检查阶段调用。不允许驱动程序更改或检查传入的参数之外的任何内容。需要检查动态配置状态的原子驱动程序应改为使用 atomic_best_encoder

如果连接器仅连接到单个编码器,则可以将此函数保留为 NULL。在这种情况下,核心将为您调用 drm_connector_get_single_encoder()。

返回值

应用于给定连接器和连接器状态的编码器;如果不存在合适的编码器,则为 NULL。请注意,助手将确保不使用两次编码器,驱动程序不应检查此情况。

atomic_best_encoder

这是 best_encoder 的原子版本,适用于需要根据所需配置选择最佳编码器的原子驱动程序,并且无法静态选择它。

此函数由 drm_atomic_helper_check_modeset() 使用。如果未实现,核心将回退到 best_encoder(如果 best_encoder 为 NULL,则回退到 drm_connector_get_single_encoder())。

注意

此函数在原子更新的检查阶段调用。不允许驱动程序更改传入的 drm_atomic_state 更新跟踪结构之外的任何内容。

返回值

应用于给定连接器和连接器状态的编码器;如果不存在合适的编码器,则为 NULL。请注意,助手将确保不使用两次编码器,驱动程序不应检查此情况。

atomic_check

此钩子用于验证连接器状态。从 drm_atomic_helper_check_modeset 调用此函数,并在设置连接器属性或强制执行 crtc 上的模式设置时调用。

因为可以多次调用 drm_atomic_helper_check_modeset,所以此函数应处理也被多次调用的情况。

还允许此函数检查任何其他对象的状态,并且如果需要,可以将更多状态对象添加到原子提交。 但是,必须小心确保调用这些添加状态的状态检查和计算函数,并且更新其他对象中的派生状态。 再次建议只调用检查辅助函数,直到达到最大配置。

注意

此函数在原子更新的检查阶段调用。不允许驱动程序更改传入的独立状态对象之外的任何内容,或在整个 drm_atomic_state 更新跟踪结构中组装的任何内容。

返回值

成功时为 0,如果不支持状态或转换,则为 -EINVAL,内存分配失败时为 -ENOMEM,如果尝试获取另一个状态对象遇到 drm_modeset_lock 死锁,则为 -EDEADLK。

atomic_commit

此钩子供实现需要将回写作业提交到硬件时的回写连接器的驱动程序使用。要提交的回写作业可在新的连接器状态中找到,位于 drm_connector_state.writeback_job 中。

此钩子是可选的。

原子模式设置助手使用此回调。

prepare_writeback_job

由于回写作业包含帧缓冲区,驱动程序可能需要准备和清理它们,就像它们可以准备和清理平面的帧缓冲区一样。此可选连接器操作用于支持回写作业的准备。作业准备操作从 drm_atomic_helper_prepare_planes() 中调用,仅适用于 struct drm_writeback_connector 连接器。

此操作是可选的。

原子模式设置助手使用此回调。

cleanup_writeback_job

此可选连接器操作用于支持回写作业的清理。作业清理操作从现有的 drm_writeback_cleanup_job() 函数中调用,该函数在销毁作为中止提交的一部分的作业或作业完成时调用。

此操作是可选的。

原子模式设置助手使用此回调。

enable_hpd

启用连接器的热插拔检测。

此操作是可选的。

此回调由 drm_kms_helper_poll_enable() 助手使用。

此操作不需要执行任何 hpd 状态跟踪,因为 DRM 核心会处理该维护并确保对启用和禁用 hpd 的调用是平衡的。

disable_hpd

禁用连接器的热插拔检测。

此操作是可选的。

此回调由 drm_kms_helper_poll_disable() 助手使用。

此操作不需要执行任何 hpd 状态跟踪,因为 DRM 核心会处理该维护并确保对启用和禁用 hpd 的调用是平衡的。

描述

原子和旧式模式设置助手以及探测助手使用这些函数。

void drm_connector_helper_add(struct drm_connector *connector, const struct drm_connector_helper_funcs *funcs)

设置连接器的助手 vtable

参数

struct drm_connector *connector

DRM 连接器

const struct drm_connector_helper_funcs *funcs

要为 connector 设置的助手 vtable

struct drm_plane_helper_funcs

平面的助手操作

定义:

struct drm_plane_helper_funcs {
    int (*prepare_fb)(struct drm_plane *plane, struct drm_plane_state *new_state);
    void (*cleanup_fb)(struct drm_plane *plane, struct drm_plane_state *old_state);
    int (*begin_fb_access)(struct drm_plane *plane, struct drm_plane_state *new_plane_state);
    void (*end_fb_access)(struct drm_plane *plane, struct drm_plane_state *new_plane_state);
    int (*atomic_check)(struct drm_plane *plane, struct drm_atomic_state *state);
    void (*atomic_update)(struct drm_plane *plane, struct drm_atomic_state *state);
    void (*atomic_enable)(struct drm_plane *plane, struct drm_atomic_state *state);
    void (*atomic_disable)(struct drm_plane *plane, struct drm_atomic_state *state);
    int (*atomic_async_check)(struct drm_plane *plane, struct drm_atomic_state *state, bool flip);
    void (*atomic_async_update)(struct drm_plane *plane, struct drm_atomic_state *state);
    int (*get_scanout_buffer)(struct drm_plane *plane, struct drm_scanout_buffer *sb);
    void (*panic_flush)(struct drm_plane *plane);
};

成员

prepare_fb

此钩子用于准备用于扫描输出的帧缓冲区,例如,通过固定其后备存储或将其重定位到 VRAM 的连续块中。其他可能的准备工作包括刷新缓存。

此函数不得阻止未完成的渲染,因为即使对于异步提交,它也会在原子 IOCTL 的上下文中调用,以便能够向用户空间返回任何错误。相反,建议的方法是填充传入的 drm_plane_statedrm_plane_state.fence。如果驱动程序不支持本机栅栏,则应通过平面结构中的私有成员来实现等效功能。

对于既没有设置 prepare_fb 钩子也没有设置 cleanup_fb 钩子的 GEM 驱动程序,会自动调用 drm_gem_plane_helper_prepare_fb() 来实现此目的。其他需要额外平面处理的驱动程序可以从其 prepare_fb 钩子调用 drm_gem_plane_helper_prepare_fb()

在原子提交结束后,在 prepare_fb 中获得的资源会持久存在。可以在提交结束时释放的资源应在 begin_fb_access 中获取,并在 end_fb_access 中释放。例如,GEM 缓冲区的固定操作属于 prepare_fb,以便在提交后保持缓冲区固定。但是,用于影子平面助手的 vmap 操作属于 begin_fb_access,因此原子助手会在提交结束时删除映射。

对于对此钩子的每次成功调用,助手都会使用匹配的参数调用 cleanup_fb

此回调由原子模式设置助手使用,但它是可选的。有关准备每次提交资源的更多信息,请参见 begin_fb_access

返回值

成功时返回 0,或者返回 drm_mode_config_funcs.atomic_commit vfunc 允许的以下负错误代码之一。当使用助手时,此回调是唯一可以使原子提交失败的回调,其他所有操作都必须成功完成。

cleanup_fb

调用此钩子是为了清理在 prepare_fb 中为给定帧缓冲区和平面配置分配的任何资源。

原子模式设置辅助函数使用此回调,但它是可选的。

begin_fb_access

此钩子准备在原子提交期间访问平面。与 prepare_fb 相比,在 begin_fb_access 中获取的资源会在 end_fb_access 中提交结束时释放。

例如,使用影子平面助手,GEM 缓冲区的 vmap 操作属于 begin_fb_access,因此缓冲区的内存在提交结束时将在 end_fb_access 中取消映射。但是,GEM 缓冲区的固定操作属于 prepare_fb,以便在提交后保持缓冲区固定。

回调由原子模式设置助手使用,但它是可选的。有关撤消 begin_fb_access 效果的信息,请参见 end_fb_cleanup;有关获取资源直到下一个页面翻转的信息,请参见 prepare_fb

返回值:成功时返回 0;否则,返回负 errno 代码。

end_fb_access

此钩子清理由 begin_fb_access 分配的资源。它在提交结束时为新的平面状态调用。

atomic_check

驱动程序应在此钩子中检查平面特定约束。

当使用 drm_atomic_helper_check_planes() 时,平面的 atomic_check 钩子会在 CRTC 的钩子之前调用,这允许驱动程序请求 CRTC 在此处控制的共享资源。对于更复杂的依赖关系,驱动程序可以多次调用提供的检查助手,直到计算的状态具有最终配置并且已检查所有内容为止。

还允许此函数检查任何其他对象的状态,并且如果需要,可以将更多状态对象添加到原子提交。 但是,必须小心确保调用这些添加状态的状态检查和计算函数,并且更新其他对象中的派生状态。 再次建议只调用检查辅助函数,直到达到最大配置。

原子模式设置辅助函数使用此回调,但它是可选的。

注意

此函数在原子更新的检查阶段调用。不允许驱动程序更改 drm_atomic_state 更新跟踪结构之外的任何内容。

返回值

成功时为 0,如果不支持状态或转换,则为 -EINVAL,内存分配失败时为 -ENOMEM,如果尝试获取另一个状态对象遇到 drm_modeset_lock 死锁,则为 -EDEADLK。

atomic_update

驱动程序应使用此函数来更新平面状态。此钩子在 drm_crtc_helper_funcs.atomic_begin 和 drm_crtc_helper_funcs.atomic_flush 回调之间调用。

请注意,调用此函数时显示管道的电源状态取决于驱动程序选择的确切辅助函数和调用序列。 有关平面提交辅助函数的权衡和变体的讨论,请参见 drm_atomic_helper_commit_planes()

原子模式设置辅助函数使用此回调,但它是可选的。

atomic_enable

驱动程序应使用此函数来无条件地启用平面。此钩子在 drm_crtc_helper_funcs.atomic_begin 和 drm_crtc_helper_funcs.atomic_flush 回调之间调用。在 atomic_update 之后调用它,对于所有启用的平面都会调用 atomic_update。使用 atomic_enable 的驱动程序应在 atomic_update 中设置平面,然后在 atomic_enable 中启用平面。如果需要在安装扫描输出缓冲区之前启用平面,驱动程序仍然可以在 atomic_update 中执行此操作。

请注意,调用此函数时显示管道的电源状态取决于驱动程序选择的确切辅助函数和调用序列。 有关平面提交辅助函数的权衡和变体的讨论,请参见 drm_atomic_helper_commit_planes()

此回调由原子模式设置助手使用,但它是可选的。如果已实现,则 atomic_enable 应为 atomic_disable 的逆操作。不想使用两者的驱动程序仍然可以在 atomic_update 中实现完整的平面更新。

atomic_disable

驱动程序应使用此函数来无条件地禁用平面。此钩子在 drm_crtc_helper_funcs.atomic_begin 和 drm_crtc_helper_funcs.atomic_flush 回调之间调用。如果未实现 atomic_disable 钩子,则这是 atomic_update 的替代方法,对于禁用平面也会调用 atomic_update

此钩子还可用于通过从 drm_crtc_helper_funcs.disable 钩子调用 drm_atomic_helper_disable_planes_on_crtc() 来禁用为模式设置准备的平面。

请注意,调用此函数时显示管道的电源状态取决于驱动程序选择的确切辅助函数和调用序列。 有关平面提交辅助函数的权衡和变体的讨论,请参见 drm_atomic_helper_commit_planes()

此回调由原子模式设置助手使用,但它是可选的。它旨在反转 atomic_enable 的效果。

atomic_async_check

驱动程序应设置此函数指针来检查是否可以以异步方式更新平面的原子状态。此处的异步意味着“未与垂直消隐同步”。

此钩子由 drm_atomic_async_check() 调用,以确定是否可以异步提交给定的更新,即,如果它可以在当前排队等待更新的状态之前跳转。

此函数还由 drm_atomic_set_property() 使用,以确定是否可以异步翻转平面。翻转标志用于区分该函数是否仅用于平面状态或用于翻转。

返回值

成功时返回 0,返回的任何错误都表明无法以异步方式应用更新。

atomic_async_update

驱动程序应设置此函数指针来执行平面的异步更新,即,在当前排队状态之前跳转并更新平面。此处的异步意味着“未与垂直消隐同步”。

此钩子由 drm_atomic_helper_async_commit() 调用。

异步更新将发生在旧式游标更新中。如果存在修改同一平面的未完成提交,则不会发生异步更新。

在执行 async_update 时,驱动程序不应替换 drm_plane_state,而是使用新平面配置更新新平面状态中的当前平面状态。

驱动程序还应在当前平面状态 (drm_plane.state) 和 new_state 之间交换帧缓冲区。这是必需的,因为异步提交的清理是在新状态下执行的,而不是像传统提交那样在旧状态下执行的。由于我们想放弃对当前(旧)fb 而不是我们全新 fb 的引用,因此在异步提交期间在驱动程序中交换它们。

FIXME
  • 它仅适用于单平面更新

  • 尚不支持异步页面翻转

  • 某些硬件可能仍会扫描旧缓冲区,直到下一个垂直消隐,但是我们会在运行此钩子后立即释放 fb 引用。目前,驱动程序必须实现自己的工作程序以进行延迟(如果需要),直到创建通用解决方案为止。

get_scanout_buffer

获取当前扫描输出缓冲区,以便使用 drm_panic 显示消息。驱动程序应进行最小的更改以提供可用于显示紧急情况屏幕的缓冲区。目前仅支持线性缓冲区。非线性缓冲区支持在 TODO 列表中。设备 dev.mode_config.panic_lock 在调用此函数之前被获取,因此您可以安全地访问 plane.state。它是从紧急情况回调中调用的,必须遵循其限制。有关安全和不允许的内容的深入讨论,请查看 drm_panic_trylock() 中的文档。这是一种尽力而为模式,因此在某些复杂情况下,预计不会显示紧急情况屏幕。如果没有返回错误代码,则返回的 drm_scanout_buffer.map 必须有效。

返回值:成功时返回 0,失败时返回负 errno。

panic_flush

它由 drm_panic 使用,并在将紧急情况屏幕绘制到扫描输出缓冲区后调用。在此函数中,驱动程序可以向硬件发送额外的命令,以使扫描输出缓冲区可见。仅当 get_scanout_buffer() 成功返回,并且在整个序列中持有 dev.mode_config.panic_lock 时才会调用它。它是从紧急情况回调中调用的,必须遵循其限制。有关安全和不允许的内容的深入讨论,请查看 drm_panic_trylock() 中的文档。

描述

原子助手使用这些函数。

void drm_plane_helper_add(struct drm_plane *plane, const struct drm_plane_helper_funcs *funcs)

设置平面的助手 vtable

参数

struct drm_plane *plane

DRM 平面

const struct drm_plane_helper_funcs *funcs

要为 plane 设置的助手 vtable

struct drm_mode_config_helper_funcs

全局模式设置助手操作

定义:

struct drm_mode_config_helper_funcs {
    void (*atomic_commit_tail)(struct drm_atomic_state *state);
    int (*atomic_commit_setup)(struct drm_atomic_state *state);
};

成员

atomic_commit_tail

此钩子与非阻塞提交助手(请参见 drm_atomic_helper_setup_commit() 作为起点)一起,由 drm_atomic_helper_commit() 中实现的默认 atomic_commit() 钩子使用,以便轻松实现阻塞和非阻塞提交。原子助手不使用此钩子

当新的原子状态已交换到各种状态指针中时,将调用此函数。因此,传入的状态包含旧状态/先前状态的副本。此钩子应将新状态提交到硬件。请注意,助手已经等待了前面的原子提交和栅栏,但是驱动程序可以在其实现的开头添加更多等待调用,例如,等待驱动程序内部的隐式同步请求,然后再开始将更新提交到硬件。

将原子更新提交到硬件后,此钩子需要调用 drm_atomic_helper_commit_hw_done()。然后,等待硬件执行更新,例如使用 drm_atomic_helper_wait_for_vblanks()drm_atomic_helper_wait_for_flip_done(),然后使用 drm_atomic_helper_cleanup_planes() 清理旧的帧缓冲区。

禁用 CRTC 时,此钩子_必须_暂停,直到提交完成。垂直消隐等待在禁用的 CRTC 上不起作用,因此核心无法处理此问题。并且它也不能依赖垂直消隐事件,因为该事件可能已经在屏幕显示黑屏时发出信号,这可能比完全关闭显示管道所需的最后一次硬件访问早得多。

此钩子是可选的,默认实现是 drm_atomic_helper_commit_tail()

atomic_commit_setup

此钩子由 drm_atomic_helper_commit() 中实现的默认 atomic_commit() 钩子以及非阻塞助手(请参阅 drm_atomic_helper_setup_commit())一起使用,以扩展 DRM 提交设置。atomic 助手不使用它。

此函数在 drm_atomic_helper_setup_commit() 的末尾调用,因此一旦提交已在通用 DRM 对象状态中正确设置。它允许驱动程序进行一些额外的提交跟踪,这些跟踪与 CRTC、平面或连接器无关,这些跟踪在 drm_private_obj 结构中跟踪。

请注意,drm_private_obj 的文档提供了有关应如何实现此功能的更多详细信息。

此钩子是可选的。

描述

这些辅助函数由 atomic 助手使用。

原子模式设置辅助函数参考

概述

此辅助库提供了基于 CRTC 模式设置辅助回调和平板辅助回调的检查和提交函数的实现。它还为不需要子类化 drm 核心结构以添加其自身额外内部状态的驱动程序提供了原子状态处理回调的便捷实现。

此库还为 drm_atomic_helper_check() 中的检查回调以及使用 drm_atomic_helper_commit() 的提交回调提供了默认实现。但各个阶段和回调都已公开,以允许驱动程序混合和匹配,例如,仅将平板助手与驱动程序私有模式设置实现一起使用。

此库还为基于 atomic 接口的所有旧驱动程序接口提供了实现。请参阅 drm_atomic_helper_set_config()drm_atomic_helper_disable_plane() 以及用于实现 set_property 回调的各种函数。新驱动程序不得自己实现这些函数,而必须使用提供的助手。

atomic 助手使用与其他所有模式设置助手相同的功能表结构。请参阅 struct drm_crtc_helper_funcs、struct drm_encoder_helper_funcsstruct drm_connector_helper_funcs 的文档。它还与平板助手共享 struct drm_plane_helper_funcs 功能表。

实现异步原子提交

非阻塞原子提交应使用 struct drm_crtc_commit 来按顺序执行彼此不同的操作。锁,尤其是 struct drm_modeset_lock,不应在工作线程或任何其他用于提交硬件状态的异步上下文中持有。

drm_atomic_helper_commit() 使用 drm_atomic_helper_setup_commit() 在内部实现了非阻塞提交的推荐序列

1. 运行 drm_atomic_helper_prepare_planes()。由于这可能会失败,并且我们需要将内存不足/VRAM 错误传播到用户空间,因此必须同步调用它。

2. 与可能受新状态更新影响的任何未完成的非阻塞提交工作线程同步。这由 drm_atomic_helper_setup_commit() 处理。

异步工作线程需要有足够的并行性,才能并行地在不同的 CRTC 上运行不同的原子提交。实现此目的的最简单方法是在 system_unbound_wq 工作队列上运行它们。请注意,驱动程序不需要拆分原子提交并并行运行单个提交 - 如果用户空间关心,则应该这样做。但是对于模式设置来说,这样做可能是有益的,因为这些模式设置必须作为一个全局操作来完成,并且启用或禁用 CRTC 可能需要很长时间。但即使那样也不是必需的。

重要提示:针对多个 CRTC 的 drm_atomic_state 更新是针对其中的所有 CRTC 按顺序执行的。因此,对于仅翻转平面的原子状态更新,驱动程序不得在其原子检查代码中获取不相关的 CRTC 的 struct drm_crtc_state:这将阻止并行提交对多个 CRTC 的原子更新。一般来说,应尽可能避免添加额外的状态结构,因为这会降低(非阻塞)提交的并行性,这既是因为锁定,也是因为提交排序要求。

3. 软件状态与 drm_atomic_helper_swap_state() 同步更新。在所有模式设置锁的保护下执行此操作意味着并发调用方永远不会看到不一致的状态。请注意,提交工作线程不持有任何锁;它们的访问仅通过排序进行协调。如果工作线程仅通过独立的状态对象中的指针访问状态(目前任何驱动程序都不是这种情况),那么甚至可以同时进行多个挂起的提交。

4. 计划一个工作项以执行所有后续步骤,使用拆分的提交助手:a) 平面预提交 b) 平面提交 c) 平面后提交,然后在旧帧缓冲区不再显示后清理帧缓冲区。计划的工作应根据需要使用 drm_crtc_commit 基础设施与其他工作线程同步。有关更多详细信息,请参阅 drm_atomic_helper_setup_commit()

辅助函数参考

drm_atomic_crtc_for_each_plane

drm_atomic_crtc_for_each_plane (plane, crtc)

迭代当前连接到 CRTC 的平面

参数

plane

循环游标

crtc

将迭代其平面的 CRTC

描述

这会迭代当前状态,在检查和交换原子状态后应用原子状态时非常有用(例如)。要迭代要附加的平面(在从 drm_mode_config_funcs.atomic_check 调用的代码中更有用),请参阅 drm_atomic_crtc_state_for_each_plane()

drm_atomic_crtc_state_for_each_plane

drm_atomic_crtc_state_for_each_plane (plane, crtc_state)

迭代新状态中附加的平面

参数

plane

循环游标

crtc_state

传入的 CRTC 状态

描述

与 drm_crtc_for_each_plane() 类似,但会迭代如果应用指定状态将附加的平面。例如,在从 drm_mode_config_funcs.atomic_check 操作调用的代码中验证传入状态期间非常有用。

drm_atomic_crtc_state_for_each_plane_state

drm_atomic_crtc_state_for_each_plane_state (plane, plane_state, crtc_state)

迭代新状态中附加的平面

参数

plane

循环游标

plane_state

平面的状态的循环游标,必须为 const

crtc_state

传入的 CRTC 状态

描述

与 drm_crtc_for_each_plane() 类似,但会迭代如果应用指定状态将附加的平面。例如,在从 drm_mode_config_funcs.atomic_check 操作调用的代码中验证传入状态期间非常有用。

与仅 drm_atomic_crtc_state_for_each_plane() 相比,这也填充了 const plane_state。当驱动程序只想查看此 CRTC 上的其他活动平面,但不需要更改它时,这非常有用。

bool drm_atomic_plane_enabling(struct drm_plane_state *old_plane_state, struct drm_plane_state *new_plane_state)

检查是否正在启用平面

参数

struct drm_plane_state *old_plane_state

旧的原子平面状态

struct drm_plane_state *new_plane_state

新的原子平面状态

描述

检查平面的原子状态以确定是否正在启用它。如果它检测到无效状态(CRTC 和 FB 都需要为 NULL 或都为非 NULL),它还会发出警告。

返回

如果正在启用平面,则为 True;否则为 False。

bool drm_atomic_plane_disabling(struct drm_plane_state *old_plane_state, struct drm_plane_state *new_plane_state)

检查是否正在禁用平面

参数

struct drm_plane_state *old_plane_state

旧的原子平面状态

struct drm_plane_state *new_plane_state

新的原子平面状态

描述

检查平面的原子状态以确定是否正在禁用它。如果它检测到无效状态(CRTC 和 FB 都需要为 NULL 或都为非 NULL),它还会发出警告。

返回

如果正在禁用平面,则为 True;否则为 False。

int drm_atomic_helper_check_modeset(struct drm_device *dev, struct drm_atomic_state *state)

验证模式设置更改的状态对象

参数

struct drm_device *dev

DRM 设备

struct drm_atomic_state *state

驱动程序状态对象

描述

检查状态对象以查看请求的状态是否在物理上可行。这会为原子更新执行所有 CRTC 和连接器相关的计算,并添加完整模式设置所需的任何其他连接器。它按以下顺序调用各种每个对象的回调

  1. drm_connector_helper_funcs.atomic_best_encoder 用于确定新的编码器。

  2. drm_connector_helper_funcs.atomic_check 验证连接器状态。

  3. 如果确定需要模式设置,则添加受影响 CRTC 上的所有连接器,并在其上运行 drm_connector_helper_funcs.atomic_check

  4. 在受影响的组件上调用 drm_encoder_helper_funcs.mode_validdrm_bridge_funcs.mode_validdrm_crtc_helper_funcs.mode_valid

  5. 在所有编码器桥上调用 drm_bridge_funcs.mode_fixup

  6. 调用 drm_encoder_helper_funcs.atomic_check 以验证任何编码器状态。仅当编码器将成为配置的 CRTC 的一部分时才调用此函数,不得用于实现连接器属性验证。如果此函数为 NULL,则改为调用 drm_atomic_encoder_helper_funcs.mode_fixup

  7. 最后调用 drm_crtc_helper_funcs.mode_fixup,以使用 CRTC 约束修复模式。

当输入模式更改时,会设置 drm_crtc_state.mode_changed。当从 CRTC 添加或删除连接器时,会设置 drm_crtc_state.connectors_changed。当 drm_crtc_state.active 更改时,会设置 drm_crtc_state.active_changed,这用于 DPMS。drm_crtc_state.no_vblankdrm_dev_has_vblank() 的结果中设置。另请参阅:drm_atomic_crtc_needs_modeset()

重要提示

设置 drm_crtc_state.mode_changed 的驱动程序(例如,如果无法在没有完全模式设置的情况下完成平面更新,则在其 drm_plane_helper_funcs.atomic_check 钩子中)_必须_在该更改后调用此函数。允许对同一更新多次调用此函数,例如,当 drm_crtc_helper_funcs.atomic_check 函数依赖于调整后的点时钟以进行 fifo 空间分配和水位线计算时。

返回

成功则为零,失败则为 -errno

int drm_atomic_helper_check_wb_connector_state(struct drm_connector *connector, struct drm_atomic_state *state)

检查回写连接器状态

参数

struct drm_connector *connector

相应的连接器

struct drm_atomic_state *state

驱动程序状态对象

描述

检查回写连接器状态是否有效,如果无效,则返回错误。

返回

成功则为零,失败则为 -errno

int drm_atomic_helper_check_plane_state(struct drm_plane_state *plane_state, const struct drm_crtc_state *crtc_state, int min_scale, int max_scale, bool can_position, bool can_update_disabled)

检查平面状态的有效性

参数

struct drm_plane_state *plane_state

要检查的平面状态

const struct drm_crtc_state *crtc_state

要检查的 CRTC 状态

int min_scale

16.16 定点表示法中的最小src:dest 缩放因子

int max_scale

16.16 定点表示法中的最大src:dest 缩放因子

bool can_position

是否可以定位平面,使其不覆盖整个 CRTC?这通常仅对主平面为假。

bool can_update_disabled

可以在 CRTC 禁用的情况下更新平面吗?

描述

检查所需的平面更新是否有效,并更新各种派生状态位(裁剪坐标等)。提供自己的平面处理而不是助手提供的实现的驱动程序可能仍然希望调用此函数,以避免重复错误检查代码。

返回

如果更新显示有效则为零,否则为错误代码

int drm_atomic_helper_check_crtc_primary_plane(struct drm_crtc_state *crtc_state)

检查 CRTC 状态的主平面

参数

struct drm_crtc_state *crtc_state

要检查的 CRTC 状态

描述

检查 CRTC 是否至少附加了一个主平面,这是某些硬件上的要求。请注意,这仅涉及测试的 CRTC 端。要测试主平面是否可见,或者是否可以在不启用 CRTC 的情况下更新它,请在平面的原子检查中使用 drm_atomic_helper_check_plane_state()

返回

如果主平面已附加到 CRTC,则为 0,否则为错误代码

int drm_atomic_helper_check_planes(struct drm_device *dev, struct drm_atomic_state *state)

验证平面更改的状态对象

参数

struct drm_device *dev

DRM 设备

struct drm_atomic_state *state

驱动程序状态对象

描述

检查状态对象以查看请求的状态是否在物理上可行。这通过调用驱动程序提供的 drm_crtc_helper_funcs.atomic_checkdrm_plane_helper_funcs.atomic_check 钩子来执行所有与平面更新相关的检查。

它还会设置 drm_crtc_state.planes_changed 以指示 CRTC 已更新平面。

返回

成功则为零,失败则为 -errno

int drm_atomic_helper_check(struct drm_device *dev, struct drm_atomic_state *state)

验证状态对象

参数

struct drm_device *dev

DRM 设备

struct drm_atomic_state *state

驱动程序状态对象

描述

检查状态对象以查看请求的状态是否在物理上可行。只有 CRTC 和平面具有检查回调,因此对于驱动程序需要的任何额外(全局)检查,只需将其围绕此函数包装即可。没有这种需求的驱动程序可以直接将其用作其 drm_mode_config_funcs.atomic_check 回调。

这只是按默认顺序包装平面和模式设置状态的状态检查的两个部分:首先,它调用 drm_atomic_helper_check_modeset(),然后调用 drm_atomic_helper_check_planes()。假设 drm_plane_helper_funcs.atomic_checkdrm_crtc_helper_funcs.atomic_check 函数依赖于更新的 adjusted_mode.clock,以便例如正确计算水位线。

请注意,zpos 规范化会将所有启用的平面添加到状态,这对于某些驱动程序可能是不希望的。例如,具有固定 zpos 值的光标平面的启用/禁用会触发所有其他启用的平面强制更改状态。

重要提示

由于此函数在内部调用 drm_atomic_helper_check_modeset(),因此其限制也适用:设置 drm_crtc_state.mode_changed 的驱动程序(例如,如果无法在没有完全模式设置的情况下完成平面更新,则在其 drm_plane_helper_funcs.atomic_check 钩子中)_必须_在该更改后再次调用 drm_atomic_helper_check_modeset() 函数。

返回

成功则为零,失败则为 -errno

void drm_atomic_helper_update_legacy_modeset_state(struct drm_device *dev, struct drm_atomic_state *state)

更新旧模式设置状态

参数

struct drm_device *dev

DRM 设备

struct drm_atomic_state *state

要提交的原子状态对象

描述

此函数更新连接器、编码器和 CRTC 中所有各种旧模式设置状态指针。

如果驱动程序没有纯粹基于助手的模式设置实现,则可以使用它来构建自己的原子提交。

由于这些更新与锁定不同步,因此只有从 drm_mode_config_helper_funcs.atomic_commit_tail 调用的代码路径可以查看此助手填充的旧状态。实际上,这意味着此助手和旧状态指针仅对将现有驱动程序过渡到原子世界真正有用。

void drm_atomic_helper_calc_timestamping_constants(struct drm_atomic_state *state)

更新垂直消隐时间戳常量

参数

struct drm_atomic_state *state

原子状态对象

描述

通过为 state 中所有启用的 crtc 调用 drm_calc_timestamping_constants() 来更新用于精确垂直消隐时间戳的时间戳常量。

void drm_atomic_helper_commit_modeset_disables(struct drm_device *dev, struct drm_atomic_state *state)

模式设置提交以禁用输出

参数

struct drm_device *dev

DRM 设备

struct drm_atomic_state *state

要提交的原子状态对象

描述

此函数关闭所有需要关闭的输出,并使用新模式准备它们(如果需要)。

为了与旧 CRTC 助手兼容,应在 drm_atomic_helper_commit_planes() 之前调用此函数,这是默认提交函数的作用。但是,有不同需求的驱动程序可以将模式设置提交分组在一起,并在最后执行平面提交。这对于执行运行时 PM 的驱动程序非常有用,因为平面更新仅在 CRTC 实际启用时才会发生。

void drm_atomic_helper_commit_modeset_enables(struct drm_device *dev, struct drm_atomic_state *state)

模式设置提交以启用输出

参数

struct drm_device *dev

DRM 设备

struct drm_atomic_state *state

要提交的原子状态对象

描述

此函数使用新配置启用所有必须关闭才能进行更新的输出。

为了与旧 CRTC 助手兼容,应在 drm_atomic_helper_commit_planes() 之后调用此函数,这是默认提交函数的作用。但是,有不同需求的驱动程序可以将模式设置提交分组在一起,并在最后执行平面提交。这对于执行运行时 PM 的驱动程序非常有用,因为平面更新仅在 CRTC 实际启用时才会发生。

int drm_atomic_helper_wait_for_fences(struct drm_device *dev, struct drm_atomic_state *state, bool pre_swap)

等待平面状态中存储的 fences。

参数

struct drm_device *dev

DRM 设备

struct drm_atomic_state *state

具有旧状态结构的原子状态对象。

bool pre_swap

如果为 true,则进行可中断的等待,并且 state 是新状态。否则,state 是旧状态。

描述

对于隐式同步,驱动程序应该从传入的 fb 中提取独占 fence 并将其存储在 drm_plane_state 中。这在 drm_atomic_helper_swap_state() 之后调用,因此它使用当前的平面状态(并且仅使用原子状态来查找已更改的平面)。

请注意,由于我们阻塞 fences 的点取决于原子提交是阻塞还是非阻塞,因此需要 pre_swap。对于非阻塞提交,所有等待都需要在调用 drm_atomic_helper_swap_state() 之后发生,但对于阻塞提交,我们希望在执行任何无法轻易回滚的操作之前等待。即在调用 drm_atomic_helper_swap_state() 之前。

如果成功则返回零,如果 dma_fence_wait() 失败则返回 < 0。

void drm_atomic_helper_wait_for_vblanks(struct drm_device *dev, struct drm_atomic_state *state)

等待 CRTC 上的 vblank。

参数

struct drm_device *dev

DRM 设备

struct drm_atomic_state *state

要提交的原子状态对象

描述

用于在原子提交后,等待所有受影响的 CRTC 上的 vblank 的辅助函数(即,在使用 drm_atomic_helper_cleanup_planes() 清理旧的帧缓冲区之前)。它只会等待帧缓冲区实际更改的 CRTC,以优化传统的光标和平面更新用例。

使用通过调用 drm_atomic_helper_setup_commit() 初始化的非阻塞提交跟踪支持的驱动程序应查看 drm_atomic_helper_wait_for_flip_done() 作为替代方案。

void drm_atomic_helper_wait_for_flip_done(struct drm_device *dev, struct drm_atomic_state *state)

等待所有页面翻转完成。

参数

struct drm_device *dev

DRM 设备

struct drm_atomic_state *state

要提交的原子状态对象

描述

用于在原子提交后,等待所有受影响的 CRTC 上的页面翻转的辅助函数(即,在使用 drm_atomic_helper_cleanup_planes() 清理旧的帧缓冲区之前)。与 drm_atomic_helper_wait_for_vblanks() 相比,这会等待所有 CRTC 上的完成,假设仅光标更新会立即发出完成信号(或使用不同的路径)。

这要求驱动程序使用使用 drm_atomic_helper_setup_commit() 初始化的非阻塞提交跟踪支持。

void drm_atomic_helper_commit_tail(struct drm_atomic_state *state)

将原子更新提交到硬件。

参数

struct drm_atomic_state *state

要提交的原子状态对象

描述

这是 drm_mode_config_helper_funcs.atomic_commit_tail hook 的默认实现,适用于不支持 runtime_pm 或不需要启用 CRTC 即可执行提交的驱动程序。否则,请参阅 drm_atomic_helper_commit_tail_rpm()

请注意,调用各个阶段的默认顺序与传统模式设置辅助库最接近。

void drm_atomic_helper_commit_tail_rpm(struct drm_atomic_state *state)

将原子更新提交到硬件。

参数

struct drm_atomic_state *state

要提交的新模式设置状态。

描述

这是 drm_mode_config_helper_funcs.atomic_commit_tail hook 的替代实现,适用于支持 runtime_pm 或需要启用 CRTC 才能执行提交的驱动程序。否则,应使用默认实现 drm_atomic_helper_commit_tail()

int drm_atomic_helper_async_check(struct drm_device *dev, struct drm_atomic_state *state)

检查状态是否可以异步提交。

参数

struct drm_device *dev

DRM 设备

struct drm_atomic_state *state

驱动程序状态对象

描述

此辅助函数将检查是否可以异步提交状态。异步提交不应像正常的同步提交那样交换状态,而只需对当前状态进行就地更改。

如果提交可以异步进行,则它将返回 0,否则返回错误。请注意,错误仅表示无法异步提交,如果失败,则应将提交视为正常的同步提交。

void drm_atomic_helper_async_commit(struct drm_device *dev, struct drm_atomic_state *state)

异步提交状态。

参数

struct drm_device *dev

DRM 设备

struct drm_atomic_state *state

驱动程序状态对象

描述

此函数异步提交状态,即不与 vblank 同步。只有在 drm_atomic_async_check() 成功时才应在状态上使用它。异步提交不应像正常的同步提交那样交换状态,而只需对当前状态进行就地更改。

TODO:实现完整的交换,而不是进行就地更改。

int drm_atomic_helper_commit(struct drm_device *dev, struct drm_atomic_state *state, bool nonblock)

提交已验证的状态对象。

参数

struct drm_device *dev

DRM 设备

struct drm_atomic_state *state

驱动程序状态对象

bool nonblock

是否请求非阻塞行为。

描述

此函数使用 drm_atomic_helper_check() 提交预先验证的状态对象。当例如帧缓冲区预留失败时,这仍然可能失败。此函数使用 drm_atomic_helper_setup_commit() 和相关函数实现非阻塞提交。

实际硬件状态的提交是通过 drm_mode_config_helper_funcs.atomic_commit_tail 回调或其默认实现 drm_atomic_helper_commit_tail() 完成的。

返回

成功则为零,否则为 -errno。

int drm_atomic_helper_setup_commit(struct drm_atomic_state *state, bool nonblock)

设置可能的非阻塞提交。

参数

struct drm_atomic_state *state

要提交的新模式设置状态。

bool nonblock

是否请求非阻塞行为。

描述

此函数准备 state 以供原子辅助函数的非阻塞提交支持使用。使用非阻塞提交基础设施的驱动程序应始终从其 drm_mode_config_funcs.atomic_commit hook 调用此函数。

需要将提交设置扩展到私有对象的驱动程序可以使用 drm_mode_config_helper_funcs.atomic_commit_setup hook。

为了能够使用此支持,驱动程序需要使用一些其他辅助函数。drm_atomic_helper_wait_for_dependencies() 必须在实际提交硬件状态之前调用,对于非阻塞提交,此调用必须放在异步 worker 中。另请参阅 drm_atomic_helper_swap_state() 及其 stall 参数,用于驱动程序的提交 hook 直接查看 drm_crtc.statedrm_plane.statedrm_connector.state 指针的情况。

必须使用 drm_atomic_helper_commit_hw_done() 发出硬件提交步骤的完成信号。在此步骤之后,驱动程序不允许读取或更改任何永久性软件或硬件模式设置状态。唯一的例外是受 drm_modeset_lock 锁保护的状态。只能检查具有指向旧状态结构的指针的独立 state,例如使用 drm_atomic_helper_cleanup_planes() 清理旧缓冲区。

最后,在清理 state 之前,驱动程序必须调用 drm_atomic_helper_commit_cleanup_done()

所有这些都是在 drm_atomic_helper_commit() 中实现的,为驱动程序提供了 atomic_commit() hook 的完整且易于使用的默认实现。

异步执行和仍在挂起的提交的跟踪是使用核心结构 drm_crtc_commit 完成的。

默认情况下,无需显式清理此函数分配的资源:drm_atomic_state_default_clear() 将自动处理。

返回

成功时返回 0。当用户空间调度非阻塞提交太快时返回 -EBUSY,分配失败时返回 -ENOMEM,信号挂起时返回 -EINTR。

void drm_atomic_helper_wait_for_dependencies(struct drm_atomic_state *state)

等待所需的前置提交。

参数

struct drm_atomic_state *state

要提交的原子状态对象

描述

此函数等待所有与 state 触摸同一 CRTC 的先前提交都提交到硬件(如 drm_atomic_helper_commit_hw_done() 发出的信号)并由硬件执行(如通过调用 drm_crtc_send_vblank_event()drm_crtc_state.event 上发出的信号)。

这是对非阻塞提交的原子辅助函数支持的一部分,有关概述,请参阅 drm_atomic_helper_setup_commit()

void drm_atomic_helper_fake_vblank(struct drm_atomic_state *state)

如果需要,伪造 VBLANK 事件。

参数

struct drm_atomic_state *state

要提交的原子状态对象

描述

此函数遍历所有 CRTC,并为那些 drm_crtc_state.no_vblank 设置为 true 且 drm_crtc_state.event != NULL 的 CRTC 伪造 VBLANK 事件。此函数的主要用途是工作在 oneshot 模式下的回写连接器和伪造 VBLANK 事件。在这种情况下,它们仅在作业排队时伪造 VBLANK 事件,并且对管道的任何更改都不会触摸连接器,从而导致调用 drm_atomic_helper_wait_for_vblanks()drm_atomic_helper_wait_for_flip_done() 时超时。除了回写连接器之外,此函数还可以为没有 VBLANK 中断的 CRTC 伪造 VBLANK 事件。

这是对非阻塞提交的原子辅助函数支持的一部分,有关概述,请参阅 drm_atomic_helper_setup_commit()

void drm_atomic_helper_commit_hw_done(struct drm_atomic_state *state)

设置可能的非阻塞提交。

参数

struct drm_atomic_state *state

要提交的原子状态对象

描述

此函数用于发出硬件提交步骤完成的信号。在此步骤之后,驱动程序不允许读取或更改任何永久性软件或硬件模式设置状态。唯一的例外是受 drm_modeset_lock 锁保护的状态。

驱动程序应尝试在此函数调用后推迟任何昂贵或延迟的清理工作。

这是对非阻塞提交的原子辅助函数支持的一部分,有关概述,请参阅 drm_atomic_helper_setup_commit()

void drm_atomic_helper_commit_cleanup_done(struct drm_atomic_state *state)

发出提交完成信号。

参数

struct drm_atomic_state *state

要提交的原子状态对象

描述

这表示原子更新 state 的完成,包括任何清理工作。如果使用,则必须在调用 drm_atomic_state_put() 之前调用。

这是对非阻塞提交的原子辅助函数支持的一部分,有关概述,请参阅 drm_atomic_helper_setup_commit()

int drm_atomic_helper_prepare_planes(struct drm_device *dev, struct drm_atomic_state *state)

在提交之前准备平面资源。

参数

struct drm_device *dev

DRM 设备

struct drm_atomic_state *state

具有新状态结构的原子状态对象。

描述

此函数通过调用 drm_plane_helper_funcs.prepare_fb 来准备平面状态,特别是帧缓冲区。如果遇到任何故障,此函数将调用 drm_plane_helper_funcs.cleanup_fb 在任何已成功准备好的帧缓冲区上。

返回

成功时返回 0,失败时返回负错误代码。

void drm_atomic_helper_unprepare_planes(struct drm_device *dev, struct drm_atomic_state *state)

在中止时释放平面资源。

参数

struct drm_device *dev

DRM 设备

struct drm_atomic_state *state

具有旧状态结构的原子状态对象。

描述

此函数从原子状态中清理平面状态,特别是帧缓冲区。它在中止原子提交时撤消 drm_atomic_helper_prepare_planes() 的效果。对于在成功提交后进行清理,请使用 drm_atomic_helper_cleanup_planes()

void drm_atomic_helper_commit_planes(struct drm_device *dev, struct drm_atomic_state *state, uint32_t flags)

提交平面状态。

参数

struct drm_device *dev

DRM 设备

struct drm_atomic_state *state

要提交的原子状态对象

uint32_t flags

用于提交平面状态的标志。

描述

此函数使用平面和原子辅助函数来提交新的平面状态。它假设原子状态已推送到相关的对象状态指针中,因为此步骤不再可能失败。

它仍然需要全局状态对象 state 来知道哪些平面和 crtc 需要更新。

请注意,此函数在一个步骤中跨所有 CRTC 执行所有平面更新。如果硬件不支持此方法,请查看 drm_atomic_helper_commit_planes_on_crtc()

应用程序可以在关联的 CRTC 禁用时更新平面参数。DRM/KMS 核心会将参数存储在平面状态中,这将在 CRTC 开启时可供驱动程序使用。因此,大多数驱动程序不需要立即收到禁用 CRTC 的平面更新通知。

除非另有需要,否则建议驱动程序在 flags 中设置 ACTIVE_ONLY 标志,以便不接收与禁用 CRTC 相关的平面更新通知。这避免了在驱动程序代码中手动忽略平面更新的需求,当驱动程序和/或硬件无法或不需要处理禁用 CRTC 上的更新时,例如在支持运行时 PM 时。

如果相关的显示控制器需要在禁用 CRTC 时禁用 CRTC 的平面,则驱动程序可以在 flags 中设置 NO_DISABLE_AFTER_MODESET 标志。如果旧平面状态的 CRTC 需要模式设置操作,则此函数将跳过平面的 drm_plane_helper_funcs.atomic_disable 调用。当然,驱动程序需要在其 CRTC 禁用回调中禁用平面,因为没有人会这样做。

drm_atomic_helper_commit() 默认实现未设置 ACTIVE_ONLY 标志,以最接近地匹配传统辅助函数的行为。驱动程序不应盲目复制这一点。

void drm_atomic_helper_commit_planes_on_crtc(struct drm_crtc_state *old_crtc_state)

提交 CRTC 的平面状态。

参数

struct drm_crtc_state *old_crtc_state

具有旧 CRTC 状态的原子状态对象。

描述

此函数使用平面和原子辅助函数来提交特定 CRTC 上的平面的新状态。它假设原子状态已推送到相关的对象状态指针中,因为此步骤不再可能失败。

当平面更新应按 CRTC 执行,而不是像 drm_atomic_helper_commit_planes() 那样在一个全局步骤中执行时,此函数很有用。

只有当不允许平面在不同的 CRTC 之间移动时,才能安全地使用此函数,因为此函数不处理 CRTC 间依赖关系。调用者需要确保不存在此类依赖关系,通过提交调用的顺序或通过其他方式解决它们。

void drm_atomic_helper_disable_planes_on_crtc(struct drm_crtc_state *old_crtc_state, bool atomic)

用于禁用 CRTC 平面的辅助函数。

参数

struct drm_crtc_state *old_crtc_state

具有旧 CRTC 状态的原子状态对象。

bool atomic

如果设置,则与 CRTC 的 atomic_begin/flush hook 同步。

描述

禁用与给定 CRTC 关联的所有平面。例如,这可以在 CRTC 辅助函数 atomic_disable 回调中使用,以禁用所有平面。

如果设置了 atomic-parameter,则该函数在禁用平面之前调用 CRTC 的 atomic_begin hook,并在禁用平面之后调用 atomic_flush hook。

如果未实现 drm_plane_helper_funcs.atomic_disable 平面 hook,则调用此函数是一个 bug。

void drm_atomic_helper_cleanup_planes(struct drm_device *dev, struct drm_atomic_state *state)

提交后清理平面资源

参数

struct drm_device *dev

DRM 设备

struct drm_atomic_state *state

要提交的原子状态对象

描述

此函数从旧配置中清理平面状态,特别是帧缓冲区。因此,必须在 state 中保留旧配置才能调用此函数。

如果在调用 drm_atomic_helper_prepare_planes() 之后,原子更新在任何时候失败,则不得在新状态下调用此函数。在这种情况下,请使用 drm_atomic_helper_unprepare_planes()

int drm_atomic_helper_swap_state(struct drm_atomic_state *state, bool stall)

将原子状态存储到当前软件状态中

参数

struct drm_atomic_state *state

原子状态

bool stall

暂停先前的提交

描述

此函数将原子状态存储到所有驱动程序对象中的当前状态指针中。应在完成所有失败步骤并成功后,但在实际硬件状态提交之前调用它。

为了清理和错误恢复,所有已更改对象的当前状态将被交换到 state 中。

按照该顺序,它可以完美地融入平面准备/清理序列中

  1. 使用暂存的原子状态调用 drm_atomic_helper_prepare_planes()

  2. 执行任何其他可能失败的步骤。

  3. 使用此函数将暂存状态放入当前状态指针中。

  4. 实际提交硬件状态。

5. 使用 state 调用 drm_atomic_helper_cleanup_planes(),由于步骤 3,其中包含旧状态。 此外,使用该状态执行任何其他所需的清理。

当此驱动程序的非阻塞提交直接访问 drm_plane.statedrm_crtc.statedrm_connector.state 指针时,必须设置 stall。 对于当前的原子助手,几乎总是这样,因为助手不会将正确的状态结构传递给回调。

返回

成功时返回 0。当 stall 为 true 且等待先前的提交被中断时,可以返回 -ERESTARTSYS。

int drm_atomic_helper_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, struct drm_framebuffer *fb, int crtc_x, int crtc_y, unsigned int crtc_w, unsigned int crtc_h, uint32_t src_x, uint32_t src_y, uint32_t src_w, uint32_t src_h, struct drm_modeset_acquire_ctx *ctx)

使用原子操作进行主平面更新的助手

参数

struct drm_plane *plane

要更新的平面对象

struct drm_crtc *crtc

拥有平面的拥有 CRTC

struct drm_framebuffer *fb

要翻转到平面上的帧缓冲区

int crtc_x

主平面在 crtc 上的 x 偏移量

int crtc_y

主平面在 crtc 上的 y 偏移量

unsigned int crtc_w

主平面在 crtc 上的矩形的宽度

unsigned int crtc_h

主平面在 crtc 上的矩形的高度

uint32_t src_x

fb 中用于平移的 x 偏移量

uint32_t src_y

fb 中用于平移的 y 偏移量

uint32_t src_w

fb 中源矩形的宽度

uint32_t src_h

fb 中源矩形的高度

struct drm_modeset_acquire_ctx *ctx

锁定获取上下文

描述

提供使用原子驱动程序接口的默认平面更新处理程序。

返回

成功时为零,失败时为错误代码

int drm_atomic_helper_disable_plane(struct drm_plane *plane, struct drm_modeset_acquire_ctx *ctx)

使用原子操作禁用主平面的助手

参数

struct drm_plane *plane

要禁用的平面

struct drm_modeset_acquire_ctx *ctx

锁定获取上下文

描述

提供使用原子驱动程序接口的默认平面禁用处理程序。

返回

成功时为零,失败时为错误代码

int drm_atomic_helper_set_config(struct drm_mode_set *set, struct drm_modeset_acquire_ctx *ctx)

从用户空间设置新配置

参数

struct drm_mode_set *set

模式设置配置

struct drm_modeset_acquire_ctx *ctx

锁定获取上下文

描述

提供使用原子驱动程序接口的默认 CRTC set_config 处理程序。

注意

为了向后兼容旧的用户空间,这会自动将“link-status”属性重置为 GOOD,以强制执行任何链路重新训练。SETCRTC ioctl 没有定义更新是否需要完整的模式设置或仅仅是平面更新,因此我们允许这样做。另请参阅 drm_connector_set_link_status_property()

返回

成功时返回 0,失败时返回负 errno 编号。

int drm_atomic_helper_disable_all(struct drm_device *dev, struct drm_modeset_acquire_ctx *ctx)

禁用所有当前活动的输出

参数

struct drm_device *dev

DRM 设备

struct drm_modeset_acquire_ctx *ctx

锁定获取上下文

描述

循环遍历所有连接器,找到那些未关闭的连接器,然后通过将其 DPMS 模式设置为 OFF 并停用与其连接的 CRTC 来关闭它们。

例如,这用于挂起/恢复中,以在挂起时禁用所有当前活动的函数。如果您只想在例如驱动程序卸载时关闭所有内容,请查看 drm_atomic_helper_shutdown()

请注意,如果调用者尚未获取所有模式设置锁,则这可能会返回 -EDEADLK,必须通过调用 drm_modeset_backoff() 来处理。

另请参阅:drm_atomic_helper_suspend()drm_atomic_helper_resume()drm_atomic_helper_shutdown()

返回

成功时为 0,失败时为负错误代码。

int drm_atomic_helper_reset_crtc(struct drm_crtc *crtc, struct drm_modeset_acquire_ctx *ctx)

重置 CRTC 的活动输出

参数

struct drm_crtc *crtc

DRM CRTC

struct drm_modeset_acquire_ctx *ctx

锁定获取上下文

描述

通过指示连接器已更改来重置活动输出。这意味着重置 CRTC 和连接器之间所有可用的活动组件。

此函数的一个变体存在于 drm_bridge_helper_reset_crtc() 中,专用于桥接器。

注意

这依赖于重置 drm_crtc_state.connectors_changed。对于优化掉不必要的模式设置的驱动程序,这将导致空操作提交,什么也实现不了。

返回

成功时为 0,失败时为负错误代码。

void drm_atomic_helper_shutdown(struct drm_device *dev)

关闭所有 CRTC

参数

struct drm_device *dev

DRM 设备

描述

这会关闭所有 CRTC,这对于驱动程序卸载很有用。挂起时的关闭应使用 drm_atomic_helper_suspend() 来处理,因为它还会获取模式设置状态的快照以在恢复时恢复。

这只是 drm_atomic_helper_disable_all() 的便捷包装器,它是 drm_helper_force_disable_all() 的原子版本。

struct drm_atomic_state *drm_atomic_helper_duplicate_state(struct drm_device *dev, struct drm_modeset_acquire_ctx *ctx)

复制原子状态对象

参数

struct drm_device *dev

DRM 设备

struct drm_modeset_acquire_ctx *ctx

锁定获取上下文

描述

通过循环遍历所有对象并复制它们各自的状态来制作当前原子状态的副本。例如,这被挂起/恢复支持代码用于保存挂起之前的状态,以便可以在恢复时恢复。

请注意,这会将原子状态视为在保存和恢复之间是持久的。驱动程序必须确保这是可能的,并且不会导致混淆或错误的行为。

请注意,如果调用者尚未获取所有模式设置锁,则这可能会返回 -EDEADLK,必须通过调用 drm_modeset_backoff() 来处理。

另请参阅:drm_atomic_helper_suspend()drm_atomic_helper_resume()

返回

成功时指向原子状态对象副本的指针,失败时指向 ERR_PTR() 编码的错误代码。

struct drm_atomic_state *drm_atomic_helper_suspend(struct drm_device *dev)

子系统级别的挂起助手

参数

struct drm_device *dev

DRM 设备

描述

复制当前原子状态,禁用所有活动输出,然后向调用者返回指向原始原子状态的指针。驱动程序可以将此指针传递给 drm_atomic_helper_resume() 助手,以便在恢复时恢复系统进入挂起状态时处于活动状态的输出配置。

请注意,使用此功能可能不安全。此函数返回的原子状态对象被假定为持久的。驱动程序必须确保这一点。在调用此函数之前,驱动程序必须确保挂起 fbdev 模拟,以便没有任何东西可以使用该设备。

另请参阅:drm_atomic_helper_duplicate_state()drm_atomic_helper_disable_all()drm_atomic_helper_resume()drm_atomic_helper_commit_duplicated_state()

返回

成功时指向挂起前状态副本的指针,失败时指向 ERR_PTR() 编码的错误代码。驱动程序应存储返回的原子状态对象,并在恢复时将其传递给 drm_atomic_helper_resume() 助手。

int drm_atomic_helper_commit_duplicated_state(struct drm_atomic_state *state, struct drm_modeset_acquire_ctx *ctx)

提交复制的状态

参数

struct drm_atomic_state *state

要提交的复制的原子状态

struct drm_modeset_acquire_ctx *ctx

指向用于提交的 acquire_ctx 的指针。

描述

drm_atomic_helper_duplicate_state()drm_atomic_helper_suspend() 返回的状态部分无效,需要在提交之前进行修复。

另请参阅:drm_atomic_helper_suspend()

返回

成功时为 0,失败时为负错误代码。

int drm_atomic_helper_resume(struct drm_device *dev, struct drm_atomic_state *state)

子系统级别的恢复助手

参数

struct drm_device *dev

DRM 设备

struct drm_atomic_state *state

要恢复到的原子状态

描述

调用 drm_mode_config_reset() 以同步硬件和软件状态,获取所有模式设置锁并提交原子状态对象。这可以与 drm_atomic_helper_suspend() 助手结合使用,以实现对支持原子模式设置的驱动程序的挂起/恢复。

另请参阅:drm_atomic_helper_suspend()

返回

成功时为 0,失败时为负错误代码。

int drm_atomic_helper_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, struct drm_pending_vblank_event *event, uint32_t flags, struct drm_modeset_acquire_ctx *ctx)

执行旧版页面翻转

参数

struct drm_crtc *crtc

DRM CRTC

struct drm_framebuffer *fb

DRM 帧缓冲区

struct drm_pending_vblank_event *event

完成时要发出信号的可选 DRM 事件

uint32_t flags

用于非垂直消隐同步更新的翻转标志

struct drm_modeset_acquire_ctx *ctx

锁定获取上下文

描述

提供使用原子驱动程序接口的默认 drm_crtc_funcs.page_flip 实现。

另请参阅:drm_atomic_helper_page_flip_target()

返回

成功时返回 0,失败时返回负 errno 编号。

int drm_atomic_helper_page_flip_target(struct drm_crtc *crtc, struct drm_framebuffer *fb, struct drm_pending_vblank_event *event, uint32_t flags, uint32_t target, struct drm_modeset_acquire_ctx *ctx)

在目标垂直消隐周期执行页面翻转。

参数

struct drm_crtc *crtc

DRM CRTC

struct drm_framebuffer *fb

DRM 帧缓冲区

struct drm_pending_vblank_event *event

完成时要发出信号的可选 DRM 事件

uint32_t flags

用于非垂直消隐同步更新的翻转标志

uint32_t target

指定翻转生效的目标垂直消隐周期

struct drm_modeset_acquire_ctx *ctx

锁定获取上下文

描述

提供默认的 drm_crtc_funcs.page_flip_target 实现。类似于 drm_atomic_helper_page_flip(),但有一个额外的参数来指定翻转的目标垂直消隐周期。

返回

成功时返回 0,失败时返回负 errno 编号。

u32 *drm_atomic_helper_bridge_propagate_bus_fmt(struct drm_bridge *bridge, struct drm_bridge_state *bridge_state, struct drm_crtc_state *crtc_state, struct drm_connector_state *conn_state, u32 output_fmt, unsigned int *num_input_fmts)

将输出格式传播到桥的输入端

参数

struct drm_bridge *bridge

桥控制结构

struct drm_bridge_state *bridge_state

新的桥状态

struct drm_crtc_state *crtc_state

新的 CRTC 状态

struct drm_connector_state *conn_state

新的连接器状态

u32 output_fmt

经过测试的输出总线格式

unsigned int *num_input_fmts

将包含返回数组的大小

描述

对于不修改其输入和输出之间的总线配置的桥,此助手是 drm_bridge_funcs.atomic_get_input_bus_fmts 操作的可插拔实现。它返回一个输入格式数组,其中单个元素设置为 output_fmt

返回

大小为 num_input_fmts 的有效格式数组,如果分配失败,则为 NULL

原子状态重置和初始化

drm 核心和原子助手都假定所有连接器、CRTC 和平面始终存在完整且正确的原子软件状态。这在驱动程序加载和系统挂起后都是一个问题。一种解决方案是拥有硬件状态读取基础设施,该基础设施可以重建完整的软件状态(例如 i915 驱动程序)。

更简单的解决方案是将软件状态重置为全部关闭,最简单的方法是调用 drm_mode_config_reset()。为了方便起见,原子助手为所有挂钩提供了默认的重置实现。

从好的方面来说,原子操作的精确状态跟踪大大简化了系统挂起和恢复。对于使用 drm_mode_config_reset() 的驱动程序,drm_atomic_helper_suspend()drm_atomic_helper_resume() 中实现了一个完整的配方。对于其他驱动程序,构建块已分离出来,请参阅这些函数的文档。

原子状态助手参考

void __drm_atomic_helper_crtc_state_reset(struct drm_crtc_state *crtc_state, struct drm_crtc *crtc)

重置 CRTC 状态

参数

struct drm_crtc_state *crtc_state

原子 CRTC 状态,不得为 NULL

struct drm_crtc *crtc

CRTC 对象,不得为 NULL

描述

使用默认值初始化新分配的 crtc_state。这对于子类化 CRTC 状态的驱动程序很有用。

void __drm_atomic_helper_crtc_reset(struct drm_crtc *crtc, struct drm_crtc_state *crtc_state)

重置 CRTC 上的状态

参数

struct drm_crtc *crtc

drm CRTC

struct drm_crtc_state *crtc_state

要分配的 CRTC 状态

描述

初始化新分配的 crtc_state,并将其分配给 crtcdrm_crtc->state 指针。通常在初始化驱动程序或从 drm_crtc_funcs.reset 钩子调用时需要。

这对子类化 CRTC 状态的驱动程序很有用。

void drm_atomic_helper_crtc_reset(struct drm_crtc *crtc)

CRTC 的默认 drm_crtc_funcs.reset 钩子

参数

struct drm_crtc *crtc

drm CRTC

描述

通过释放状态指针(可能是 NULL,例如在驱动程序加载时)并分配一个新的空状态对象,重置 crtc 的原子状态。

void __drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc, struct drm_crtc_state *state)

复制原子 CRTC 状态

参数

struct drm_crtc *crtc

CRTC 对象

struct drm_crtc_state *state

原子 CRTC 状态

描述

从 CRTC 的当前状态复制原子状态,并重置推断值。这对子类化 CRTC 状态的驱动程序很有用。

struct drm_crtc_state *drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc)

默认状态复制钩子

参数

struct drm_crtc *crtc

drm CRTC

描述

适用于没有自己的子类化 CRTC 状态结构的驱动程序的默认 CRTC 状态复制钩子。

void __drm_atomic_helper_crtc_destroy_state(struct drm_crtc_state *state)

释放 CRTC 状态

参数

struct drm_crtc_state *state

要释放的 CRTC 状态对象

描述

释放 CRTC 状态中存储的所有资源,而实际上并不释放 CRTC 状态的内存。这对子类化 CRTC 状态的驱动程序很有用。

void drm_atomic_helper_crtc_destroy_state(struct drm_crtc *crtc, struct drm_crtc_state *state)

默认状态销毁钩子

参数

struct drm_crtc *crtc

drm CRTC

struct drm_crtc_state *state

要释放的 CRTC 状态对象

描述

适用于没有自己的子类化 CRTC 状态结构的驱动程序的默认 CRTC 状态销毁钩子。

void __drm_atomic_helper_plane_state_reset(struct drm_plane_state *plane_state, struct drm_plane *plane)

将平面状态重置为默认值

参数

struct drm_plane_state *plane_state

原子平面状态,不得为 NULL

struct drm_plane *plane

平面对象,不得为 NULL

描述

使用默认值初始化新分配的 plane_state。这对子类化 CRTC 状态的驱动程序很有用。

void __drm_atomic_helper_plane_reset(struct drm_plane *plane, struct drm_plane_state *plane_state)

重置平面上的状态

参数

struct drm_plane *plane

drm 平面

struct drm_plane_state *plane_state

要分配的平面状态

描述

初始化新分配的 plane_state,并将其分配给 planedrm_crtc->state 指针。通常在初始化驱动程序或从 drm_plane_funcs.reset 钩子调用时需要。

这对子类化平面状态的驱动程序很有用。

void drm_atomic_helper_plane_reset(struct drm_plane *plane)

平面的默认 drm_plane_funcs.reset 钩子

参数

struct drm_plane *plane

drm 平面

描述

通过释放状态指针(可能是 NULL,例如在驱动程序加载时)并分配一个新的空状态对象,重置 plane 的原子状态。

void __drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane, struct drm_plane_state *state)

复制原子平面状态

参数

struct drm_plane *plane

平面对象

struct drm_plane_state *state

原子平面状态

描述

从平面的当前状态复制原子状态。这对子类化平面状态的驱动程序很有用。

struct drm_plane_state *drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane)

默认状态复制钩子

参数

struct drm_plane *plane

drm 平面

描述

适用于没有自己的子类化平面状态结构的驱动程序的默认平面状态复制钩子。

void __drm_atomic_helper_plane_destroy_state(struct drm_plane_state *state)

释放平面状态

参数

struct drm_plane_state *state

要释放的平面状态对象

描述

释放平面状态中存储的所有资源,而实际上并不释放平面状态的内存。这对子类化平面状态的驱动程序很有用。

void drm_atomic_helper_plane_destroy_state(struct drm_plane *plane, struct drm_plane_state *state)

默认状态销毁钩子

参数

struct drm_plane *plane

drm 平面

struct drm_plane_state *state

要释放的平面状态对象

描述

适用于没有自己的子类化平面状态结构的驱动程序的默认平面状态销毁钩子。

void __drm_atomic_helper_connector_state_reset(struct drm_connector_state *conn_state, struct drm_connector *connector)

重置连接器状态

参数

struct drm_connector_state *conn_state

原子连接器状态,不得为 NULL

struct drm_connector *connector

连接器对象,不得为 NULL

描述

使用默认值初始化新分配的 conn_state。这对子类化连接器状态的驱动程序很有用。

void __drm_atomic_helper_connector_reset(struct drm_connector *connector, struct drm_connector_state *conn_state)

重置连接器上的状态

参数

struct drm_connector *connector

drm 连接器

struct drm_connector_state *conn_state

要分配的连接器状态

描述

初始化新分配的 conn_state,并将其分配给 connectordrm_connector->state 指针。通常在初始化驱动程序或从 drm_connector_funcs.reset 钩子调用时需要。

这对子类化连接器状态的驱动程序很有用。

void drm_atomic_helper_connector_reset(struct drm_connector *connector)

连接器的默认 drm_connector_funcs.reset 钩子

参数

struct drm_connector *connector

drm 连接器

描述

通过释放状态指针(可能是 NULL,例如在驱动程序加载时)并分配一个新的空状态对象,重置 connector 的原子状态。

void drm_atomic_helper_connector_tv_margins_reset(struct drm_connector *connector)

重置电视连接器属性

参数

struct drm_connector *connector

DRM 连接器

描述

重置附加到连接器的与电视相关的属性。

void drm_atomic_helper_connector_tv_reset(struct drm_connector *connector)

重置模拟电视连接器属性

参数

struct drm_connector *connector

DRM 连接器

描述

重置附加到连接器的模拟电视属性

int drm_atomic_helper_connector_tv_check(struct drm_connector *connector, struct drm_atomic_state *state)

验证模拟电视连接器状态

参数

struct drm_connector *connector

DRM 连接器

struct drm_atomic_state *state

DRM 状态对象

描述

检查状态对象以查看请求的状态对于模拟电视连接器是否有效。

返回

0 表示成功,负错误代码表示错误。

void __drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector, struct drm_connector_state *state)

复制原子连接器状态

参数

struct drm_connector *connector

连接器对象

struct drm_connector_state *state

原子连接器状态

描述

从连接器的当前状态复制原子状态。这对子类化连接器状态的驱动程序很有用。

struct drm_connector_state *drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector)

默认状态复制钩子

参数

struct drm_connector *connector

drm 连接器

描述

适用于没有自己的子类化连接器状态结构的驱动程序的默认连接器状态复制钩子。

void __drm_atomic_helper_connector_destroy_state(struct drm_connector_state *state)

释放连接器状态

参数

struct drm_connector_state *state

要释放的连接器状态对象

描述

释放连接器状态中存储的所有资源,而实际上并不释放连接器状态的内存。这对子类化连接器状态的驱动程序很有用。

void drm_atomic_helper_connector_destroy_state(struct drm_connector *connector, struct drm_connector_state *state)

默认状态销毁钩子

参数

struct drm_connector *connector

drm 连接器

struct drm_connector_state *state

要释放的连接器状态对象

描述

适用于没有自己的子类化连接器状态结构的驱动程序的默认连接器状态销毁钩子。

void __drm_atomic_helper_private_obj_duplicate_state(struct drm_private_obj *obj, struct drm_private_state *state)

复制原子私有状态

参数

struct drm_private_obj *obj

CRTC 对象

struct drm_private_state *state

新的私有对象状态

描述

从私有对象的当前状态复制原子状态,并重置推断值。这对子类化私有状态的驱动程序很有用。

void __drm_atomic_helper_bridge_duplicate_state(struct drm_bridge *bridge, struct drm_bridge_state *state)

复制原子桥状态

参数

struct drm_bridge *bridge

桥对象

struct drm_bridge_state *state

原子桥状态

描述

从桥的当前状态复制原子状态,并重置推断值。这对子类化桥状态的驱动程序很有用。

struct drm_bridge_state *drm_atomic_helper_bridge_duplicate_state(struct drm_bridge *bridge)

复制桥状态对象

参数

struct drm_bridge *bridge

桥对象

描述

分配一个新的桥状态,并使用当前的桥状态值初始化它。此助手旨在用作不子类化桥状态的桥的 drm_bridge_funcs.atomic_duplicate_state 钩子。

void drm_atomic_helper_bridge_destroy_state(struct drm_bridge *bridge, struct drm_bridge_state *state)

销毁桥状态对象

参数

struct drm_bridge *bridge

此状态引用的桥

struct drm_bridge_state *state

要销毁的桥状态

描述

销毁先前由 drm_atomic_helper_bridge_reset`() :c:type:`drm_atomic_helper_bridge_duplicate_state`() 创建的桥状态。此助手旨在用作不子类化桥状态的桥的 :c:type:`drm_bridge_funcs.atomic_destroy_state 钩子。

void __drm_atomic_helper_bridge_reset(struct drm_bridge *bridge, struct drm_bridge_state *state)

将桥状态初始化为其默认值

参数

struct drm_bridge *bridge

此状态引用的桥

struct drm_bridge_state *state

要初始化的桥状态

描述

将桥状态初始化为默认值。这旨在由子类化桥状态的桥的 drm_bridge_funcs.atomic_reset 钩子调用。

struct drm_bridge_state *drm_atomic_helper_bridge_reset(struct drm_bridge *bridge)

分配桥状态并将其初始化为其默认值

参数

struct drm_bridge *bridge

此状态引用的桥

描述

分配桥状态并将其初始化为默认值。此助手旨在用作不子类化桥状态的桥的 drm_bridge_funcs.atomic_reset 钩子。

GEM 原子助手参考

GEM 原子助手库为使用 GEM 对象的驱动程序实现了通用的原子提交功能。目前,它提供了同步助手,以及用于具有阴影缓冲区的平面的平面状态和帧缓冲 BO 映射。

在扫描输出之前,平面的帧缓冲需要与可能写入帧缓冲的写入器同步。所有驱动程序都应从 struct drm_plane_helper.prepare_fb 的实现中调用 drm_gem_plane_helper_prepare_fb()。它从帧缓冲设置平面的围栏,以便 DRM 核心可以自动同步访问。drm_gem_plane_helper_prepare_fb() 也可以直接用作 prepare_fb 的实现。

#include <drm/drm_gem_atomic_helper.h>

struct drm_plane_helper_funcs driver_plane_helper_funcs = {
        ...,
        . prepare_fb = drm_gem_plane_helper_prepare_fb,
};

使用阴影缓冲区的驱动程序在原子更新期间将阴影缓冲区的内容复制到 HW 的帧缓冲存储器中。这需要将阴影缓冲区映射到内核地址空间。提交尾部函数(例如 atomic_update)无法建立映射,因为这会违反围绕 dma_buf_vmap() 的锁定规则。

阴影缓冲平面的助手建立和释放映射,并提供 struct drm_shadow_plane_state,它存储提交尾部函数的平面映射。

可以通过使用提供的宏 DRM_GEM_SHADOW_PLANE_FUNCSDRM_GEM_SHADOW_PLANE_HELPER_FUNCS 轻松启用阴影缓冲平面。这些宏设置平面和平面助手回调以指向阴影缓冲区助手。

#include <drm/drm_gem_atomic_helper.h>

struct drm_plane_funcs driver_plane_funcs = {
        ...,
        DRM_GEM_SHADOW_PLANE_FUNCS,
};

struct drm_plane_helper_funcs driver_plane_helper_funcs = {
        ...,
        DRM_GEM_SHADOW_PLANE_HELPER_FUNCS,
};

在驱动程序的 atomic-update 函数中,阴影缓冲区映射可从平面状态获得。使用 to_drm_shadow_plane_state()struct drm_plane_state 向上转换。

void driver_plane_atomic_update(struct drm_plane *plane,
                                struct drm_plane_state *old_plane_state)
{
        struct drm_plane_state *plane_state = plane->state;
        struct drm_shadow_plane_state *shadow_plane_state =
                to_drm_shadow_plane_state(plane_state);

        // access shadow buffer via shadow_plane_state->map
}

每个帧缓冲区的缓冲区对象的映射地址存储在 struct drm_shadow_plane_state.map 中。映射在状态被使用时有效。

使用 struct drm_simple_display_pipe 的驱动程序可以使用 DRM_GEM_SIMPLE_DISPLAY_PIPE_SHADOW_PLANE_FUNCS 初始化 rsp 回调。对阴影缓冲区映射的访问与常规 atomic_update 类似。

struct drm_simple_display_pipe_funcs driver_pipe_funcs = {
        ...,
        DRM_GEM_SIMPLE_DISPLAY_PIPE_SHADOW_PLANE_FUNCS,
};

void driver_pipe_enable(struct drm_simple_display_pipe *pipe,
                        struct drm_crtc_state *crtc_state,
                        struct drm_plane_state *plane_state)
{
        struct drm_shadow_plane_state *shadow_plane_state =
                to_drm_shadow_plane_state(plane_state);

        // access shadow buffer via shadow_plane_state->map
}
DRM_SHADOW_PLANE_MAX_WIDTH

DRM_SHADOW_PLANE_MAX_WIDTH

平面阴影缓冲区的最大宽度(以像素为单位)

描述

对于具有阴影平面的驱动程序,帧缓冲区的最大宽度通常独立于硬件限制。驱动程序可以从 DRM_SHADOW_PLANE_MAX_WIDTH 初始化 struct drm_mode_config.max_width。

DRM_SHADOW_PLANE_MAX_HEIGHT

DRM_SHADOW_PLANE_MAX_HEIGHT

平面阴影缓冲区的最大高度(以扫描线为单位)

描述

对于具有阴影平面的驱动程序,帧缓冲区的最大高度通常独立于硬件限制。驱动程序可以从 DRM_SHADOW_PLANE_MAX_HEIGHT 初始化 struct drm_mode_config.max_height。

struct drm_shadow_plane_state

具有阴影缓冲区的平面的平面状态

定义:

struct drm_shadow_plane_state {
    struct drm_plane_state base;
    struct drm_format_conv_state fmtcnv_state;
    struct iosys_map map[DRM_FORMAT_MAX_PLANES];
    struct iosys_map data[DRM_FORMAT_MAX_PLANES];
};

成员

基础

平面状态

fmtcnv_state

格式转换状态

用于格式转换的每个平面的状态。用于将阴影缓冲区复制到后端存储的标志。还包含格式转换的临时存储。

map

平面帧缓冲区 BO 映射到内核地址空间

存储在 map 中的内存映射应在平面的 prepare_fb 回调中建立,并在 cleanup_fb 回调中移除。

data

每个帧缓冲区 BO 数据的地址

存储在每个映射中的数据的地址。对于具有非零偏移字段的帧缓冲区,这是不同的。

描述

对于使用阴影缓冲区的平面,struct drm_shadow_plane_state 提供常规平面状态以及阴影缓冲区到内核地址空间的映射。

struct drm_shadow_plane_state *to_drm_shadow_plane_state(struct drm_plane_state *state)

struct drm_plane_state 向上转换

参数

struct drm_plane_state *state

平面状态

DRM_GEM_SHADOW_PLANE_FUNCS

DRM_GEM_SHADOW_PLANE_FUNCS

初始化用于阴影缓冲平面的 struct drm_plane_funcs

描述

驱动程序可以使用 GEM BO 作为帧缓冲区内存上的阴影缓冲区。此宏初始化 struct drm_plane_funcs 以使用 rsp 辅助函数。

DRM_GEM_SHADOW_PLANE_HELPER_FUNCS

DRM_GEM_SHADOW_PLANE_HELPER_FUNCS

初始化用于阴影缓冲平面的 struct drm_plane_helper_funcs

描述

驱动程序可以使用 GEM BO 作为帧缓冲区内存上的阴影缓冲区。此宏初始化 struct drm_plane_helper_funcs 以使用 rsp 辅助函数。

DRM_GEM_SIMPLE_DISPLAY_PIPE_SHADOW_PLANE_FUNCS

DRM_GEM_SIMPLE_DISPLAY_PIPE_SHADOW_PLANE_FUNCS

初始化用于阴影缓冲平面的 struct drm_simple_display_pipe_funcs

描述

驱动程序可以使用 GEM BO 作为帧缓冲区内存上的阴影缓冲区。此宏初始化 struct drm_simple_display_pipe_funcs 以使用 rsp 辅助函数。

int drm_gem_plane_helper_prepare_fb(struct drm_plane *plane, struct drm_plane_state *state)

准备 GEM 支持的帧缓冲区

参数

struct drm_plane *plane

平面

struct drm_plane_state *state

围栏将附加到的平面状态

描述

此函数从 drm_gem_object.resv 中提取独占围栏,并将其附加到平面状态,以供原子帮助程序等待。这对于为作为 dma_buf 结构的任何共享缓冲区正确实施隐式同步是必要的。此函数可用作 drm_plane_helper_funcs.prepare_fb 回调。

对于缓冲器始终固定在内存中的基于 GEM 的简单帧缓冲区驱动程序,无需 drm_plane_helper_funcs.cleanup_fb 挂钩。

如果未提供回调,则此函数是 drm_plane_helper_funcs.prepare_fb 的 GEM 驱动程序的默认实现。

void __drm_gem_duplicate_shadow_plane_state(struct drm_plane *plane, struct drm_shadow_plane_state *new_shadow_plane_state)

复制阴影缓冲平面状态

参数

struct drm_plane *plane

平面

struct drm_shadow_plane_state *new_shadow_plane_state

新的阴影缓冲平面状态

描述

此函数复制阴影缓冲平面状态。这对于子类化 struct drm_shadow_plane_state 的驱动程序很有帮助。

此函数不复制阴影缓冲区的现有映射。映射在原子提交期间由平面的 prepare_fb 和 cleanup_fb 辅助程序维护。有关相应的辅助程序,请参阅 drm_gem_prepare_shadow_fb() 和 drm_gem_cleanup_shadow_fb()。

struct drm_plane_state *drm_gem_duplicate_shadow_plane_state(struct drm_plane *plane)

复制阴影缓冲平面状态

参数

struct drm_plane *plane

平面

描述

此函数为阴影缓冲平面实现 struct drm_plane_funcs.atomic_duplicate_state。它假定现有状态为 struct drm_shadow_plane_state 类型,并将新状态分配为此类型。

此函数不复制阴影缓冲区的现有映射。映射在原子提交期间由平面的 prepare_fb 和 cleanup_fb 辅助程序维护。有关相应的辅助程序,请参阅 drm_gem_prepare_shadow_fb() 和 drm_gem_cleanup_shadow_fb()。

返回

指向成功时的新的平面状态的指针,否则为 NULL。

void __drm_gem_destroy_shadow_plane_state(struct drm_shadow_plane_state *shadow_plane_state)

清除阴影缓冲平面状态

参数

struct drm_shadow_plane_state *shadow_plane_state

阴影缓冲平面状态

描述

此函数清除阴影缓冲平面状态。这对于子类化 struct drm_shadow_plane_state 的驱动程序很有帮助。

void drm_gem_destroy_shadow_plane_state(struct drm_plane *plane, struct drm_plane_state *plane_state)

删除阴影缓冲平面状态

参数

struct drm_plane *plane

平面

struct drm_plane_state *plane_state

类型为 struct drm_shadow_plane_state 的平面状态

描述

此函数为阴影缓冲平面实现 struct drm_plane_funcs.atomic_destroy_state。它期望阴影缓冲区的映射已被释放。

void __drm_gem_reset_shadow_plane(struct drm_plane *plane, struct drm_shadow_plane_state *shadow_plane_state)

重置阴影缓冲平面

参数

struct drm_plane *plane

平面

struct drm_shadow_plane_state *shadow_plane_state

阴影缓冲平面状态

描述

此函数重置阴影缓冲平面的状态。这对于子类化 struct drm_shadow_plane_state 的驱动程序很有帮助。

void drm_gem_reset_shadow_plane(struct drm_plane *plane)

重置阴影缓冲平面

参数

struct drm_plane *plane

平面

描述

此函数为阴影缓冲平面实现 struct drm_plane_funcs.reset_plane。它假定当前平面状态为 struct drm_shadow_plane 类型,并将此类型的新状态分配。

int drm_gem_begin_shadow_fb_access(struct drm_plane *plane, struct drm_plane_state *plane_state)

准备用于 CPU 访问的阴影帧缓冲区

参数

struct drm_plane *plane

平面

struct drm_plane_state *plane_state

类型为 struct drm_shadow_plane_state 的平面状态

描述

此函数实现 struct drm_plane_helper_funcs.begin_fb_access。它将平面帧缓冲区的所有缓冲区对象映射到内核地址空间,并将它们存储在 struct drm_shadow_plane_state.map 中。第一个数据字节在 struct drm_shadow_plane_state.data 中可用。

有关清理,请参阅 drm_gem_end_shadow_fb_access()

返回

成功时为 0,否则为负 errno 代码。

void drm_gem_end_shadow_fb_access(struct drm_plane *plane, struct drm_plane_state *plane_state)

从 CPU 访问中释放阴影帧缓冲区

参数

struct drm_plane *plane

平面

struct drm_plane_state *plane_state

类型为 struct drm_shadow_plane_state 的平面状态

描述

此函数实现 struct drm_plane_helper_funcs.end_fb_access。它以相反的顺序撤消 drm_gem_begin_shadow_fb_access() 的所有效果。

有关更多信息,请参阅 drm_gem_begin_shadow_fb_access()

int drm_gem_simple_kms_begin_shadow_fb_access(struct drm_simple_display_pipe *pipe, struct drm_plane_state *plane_state)

准备用于 CPU 访问的阴影帧缓冲区

参数

struct drm_simple_display_pipe *pipe

简单的显示管道

struct drm_plane_state *plane_state

类型为 struct drm_shadow_plane_state 的平面状态

描述

此函数实现 struct drm_simple_display_funcs.begin_fb_access。

有关详细信息,请参阅 drm_gem_begin_shadow_fb_access(),有关清理,请参阅 drm_gem_simple_kms_cleanup_shadow_fb()。

返回

成功时为 0,否则为负 errno 代码。

void drm_gem_simple_kms_end_shadow_fb_access(struct drm_simple_display_pipe *pipe, struct drm_plane_state *plane_state)

从 CPU 访问中释放阴影帧缓冲区

参数

struct drm_simple_display_pipe *pipe

简单的显示管道

struct drm_plane_state *plane_state

类型为 struct drm_shadow_plane_state 的平面状态

描述

此函数实现 struct drm_simple_display_funcs.end_fb_access。它以相反的顺序撤消 drm_gem_simple_kms_begin_shadow_fb_access() 的所有效果。

请参阅 drm_gem_simple_kms_begin_shadow_fb_access()

void drm_gem_simple_kms_reset_shadow_plane(struct drm_simple_display_pipe *pipe)

重置阴影缓冲平面

参数

struct drm_simple_display_pipe *pipe

简单的显示管道

描述

此函数实现用于阴影缓冲平面的 struct drm_simple_display_funcs.reset_plane。

struct drm_plane_state *drm_gem_simple_kms_duplicate_shadow_plane_state(struct drm_simple_display_pipe *pipe)

复制阴影缓冲平面状态

参数

struct drm_simple_display_pipe *pipe

简单的显示管道

描述

此函数实现用于阴影缓冲平面的 struct drm_simple_display_funcs.duplicate_plane_state。它不复制阴影缓冲区的现有映射。映射在原子提交期间由平面的 prepare_fb 和 cleanup_fb 辅助程序维护。

返回

指向成功时的新的平面状态的指针,否则为 NULL。

void drm_gem_simple_kms_destroy_shadow_plane_state(struct drm_simple_display_pipe *pipe, struct drm_plane_state *plane_state)

重置阴影缓冲平面状态

参数

struct drm_simple_display_pipe *pipe

简单的显示管道

struct drm_plane_state *plane_state

类型为 struct drm_shadow_plane_state 的平面状态

描述

此函数实现用于阴影缓冲平面的 struct drm_simple_display_funcs.destroy_plane_state。它期望阴影缓冲区的映射已被释放。

简单 KMS 辅助程序参考

此辅助程序库为简单显示硬件的驱动程序提供辅助程序。

drm_simple_display_pipe_init() 初始化一个简单的显示管道,该管道只有一个全屏扫描输出缓冲区馈送一个输出。管道由 struct drm_simple_display_pipe 表示,并将 drm_planedrm_crtcdrm_encoder 结构绑定到一个固定实体中。通过单独分配的 drm_connector 对象和支持可选的 drm_bridge 编码器驱动程序,提供了一些代码重用的灵活性。

许多驱动程序只需要一个非常简单的编码器,该编码器满足显示管道的最低要求,并且不添加其他功能。函数 drm_simple_encoder_init() 提供了此类编码器的实现。

struct drm_simple_display_pipe_funcs

简单显示管道的辅助操作

定义:

struct drm_simple_display_pipe_funcs {
    enum drm_mode_status (*mode_valid)(struct drm_simple_display_pipe *pipe, const struct drm_display_mode *mode);
    void (*enable)(struct drm_simple_display_pipe *pipe,struct drm_crtc_state *crtc_state, struct drm_plane_state *plane_state);
    void (*disable)(struct drm_simple_display_pipe *pipe);
    int (*check)(struct drm_simple_display_pipe *pipe,struct drm_plane_state *plane_state, struct drm_crtc_state *crtc_state);
    void (*update)(struct drm_simple_display_pipe *pipe, struct drm_plane_state *old_plane_state);
    int (*prepare_fb)(struct drm_simple_display_pipe *pipe, struct drm_plane_state *plane_state);
    void (*cleanup_fb)(struct drm_simple_display_pipe *pipe, struct drm_plane_state *plane_state);
    int (*begin_fb_access)(struct drm_simple_display_pipe *pipe, struct drm_plane_state *new_plane_state);
    void (*end_fb_access)(struct drm_simple_display_pipe *pipe, struct drm_plane_state *plane_state);
    int (*enable_vblank)(struct drm_simple_display_pipe *pipe);
    void (*disable_vblank)(struct drm_simple_display_pipe *pipe);
    void (*reset_crtc)(struct drm_simple_display_pipe *pipe);
    struct drm_crtc_state * (*duplicate_crtc_state)(struct drm_simple_display_pipe *pipe);
    void (*destroy_crtc_state)(struct drm_simple_display_pipe *pipe, struct drm_crtc_state *crtc_state);
    void (*reset_plane)(struct drm_simple_display_pipe *pipe);
    struct drm_plane_state * (*duplicate_plane_state)(struct drm_simple_display_pipe *pipe);
    void (*destroy_plane_state)(struct drm_simple_display_pipe *pipe, struct drm_plane_state *plane_state);
};

成员

mode_valid

此回调用于检查特定模式在此简单显示管道中使用的 crtc 中是否有效。如果显示管道对其可以显示的模式有一些限制,则应实现此回调。例如,给定的显示管道可能负责设置时钟值。如果时钟无法生成可用模式的所有值,则可以使用此回调将模式数量限制为只能显示的模式。另一个原因可能是带宽缓解:显示控制器上的内存端口可能具有带宽限制,不允许以任何速率提取像素数据。

此挂钩由探测辅助函数用于筛选 drm_helper_probe_single_connector_modes() 中的模式列表,并且原子辅助函数使用它来验证用户空间在 drm_atomic_helper_check_modeset() 中提供的模式。

此函数是可选的。

注意

由于此函数既从原子提交的检查阶段调用,又从探针路径中的模式验证调用,因此不允许查看除传入模式之外的任何内容,并根据配置不变的硬件约束对其进行验证。

返回值

drm_mode_status 枚举

enable

此函数应用于启用管道。在启用底层 crtc 时调用此函数。此挂钩是可选的。

disable

此函数应用于禁用管道。在禁用底层 crtc 时调用此函数。此挂钩是可选的。

check

此函数在原子更新的检查阶段调用,特别是在检查底层平面时。简单显示管道辅助程序已检查平面是否未缩放,填充整个可见区域,并且始终在启用 crtc 时启用。此挂钩是可选的。

返回值

成功时为 0,如果不支持状态或转换,则为 -EINVAL,内存分配失败时为 -ENOMEM,如果尝试获取另一个状态对象遇到 drm_modeset_lock 死锁,则为 -EDEADLK。

update

更新底层平面状态时调用此函数。此挂钩是可选的。

这是驱动程序应提交 drm_pending_vblank_event 的函数。使用 drm_crtc_arm_vblank_event()(当驱动程序支持 vblank 中断处理时)或 drm_crtc_send_vblank_event()(对于更复杂的情况)。如果硬件完全缺少 vblank 支持,驱动程序可以在 struct drm_simple_display_pipe_funcs.check 中设置 struct drm_crtc_state.no_vblank,并让 DRM 的原子辅助程序伪造 vblank 事件。

prepare_fb

可选,由 drm_plane_helper_funcs.prepare_fb 调用。请阅读 drm_plane_helper_funcs.prepare_fb 挂钩的文档以获取更多详细信息。

对于既没有设置 prepare_fb 也没有设置 cleanup_fb 挂钩的 GEM 驱动程序,会自动调用 drm_gem_plane_helper_prepare_fb() 来实现此目的。其他需要额外平面处理的驱动程序可以从其 prepare_fb 挂钩调用 drm_gem_plane_helper_prepare_fb()

cleanup_fb

可选,由 drm_plane_helper_funcs.cleanup_fb 调用。请阅读 drm_plane_helper_funcs.cleanup_fb 挂钩的文档以获取更多详细信息。

begin_fb_access

可选,由 drm_plane_helper_funcs.begin_fb_access 调用。请阅读 drm_plane_helper_funcs.begin_fb_access 挂钩的文档以获取更多详细信息。

end_fb_access

可选,由 drm_plane_helper_funcs.end_fb_access 调用。请阅读 drm_plane_helper_funcs.end_fb_access 挂钩的文档以获取更多详细信息。

enable_vblank

可选,由 drm_crtc_funcs.enable_vblank 调用。请阅读 drm_crtc_funcs.enable_vblank 挂钩的文档以获取更多详细信息。

disable_vblank

可选,由 drm_crtc_funcs.disable_vblank 调用。请阅读 drm_crtc_funcs.disable_vblank 挂钩的文档以获取更多详细信息。

reset_crtc

可选,由 drm_crtc_funcs.reset 调用。请阅读 drm_crtc_funcs.reset 挂钩的文档以获取更多详细信息。

duplicate_crtc_state

可选,由 drm_crtc_funcs.atomic_duplicate_state 调用。请阅读 drm_crtc_funcs.atomic_duplicate_state 挂钩的文档以获取更多详细信息。

destroy_crtc_state

可选,由 drm_crtc_funcs.atomic_destroy_state 调用。请阅读 drm_crtc_funcs.atomic_destroy_state 挂钩的文档以获取更多详细信息。

reset_plane

可选,由 drm_plane_funcs.reset 调用。请阅读 drm_plane_funcs.reset 挂钩的文档以获取更多详细信息。

duplicate_plane_state

可选,由 drm_plane_funcs.atomic_duplicate_state 调用。请阅读 drm_plane_funcs.atomic_duplicate_state 挂钩的文档以获取更多详细信息。

destroy_plane_state

可选,由 drm_plane_funcs.atomic_destroy_state 调用。请阅读 drm_plane_funcs.atomic_destroy_state 挂钩的文档以获取更多详细信息。

struct drm_simple_display_pipe

简单显示管道

定义:

struct drm_simple_display_pipe {
    struct drm_crtc crtc;
    struct drm_plane plane;
    struct drm_encoder encoder;
    struct drm_connector *connector;
    const struct drm_simple_display_pipe_funcs *funcs;
};

成员

crtc

CRTC 控制结构

plane

平面控制结构

encoder

编码器控制结构

connector

连接器控制结构

funcs

管道控制函数(可选)

描述

具有平面、crtc 和编码器折叠为一个实体的简单显示管道。应通过调用 drm_simple_display_pipe_init() 进行初始化。

drmm_simple_encoder_alloc

drmm_simple_encoder_alloc (dev, type, member, encoder_type)

分配和初始化具有基本功能的编码器。

参数

dev

drm 设备

type

包含 struct drm_encoder 的结构的类型

member

typedrm_encoder 的名称。

encoder_type

编码器的用户可见类型

描述

分配和初始化没有其他功能的编码器。可能的 CRTC 和克隆的设置保留为其初始值。通过使用 drmm_add_action() 注册 drm_encoder_cleanup() 来自动处理清理。

返回

指向新编码器的指针,失败时为 ERR_PTR。

int drm_simple_encoder_init(struct drm_device *dev, struct drm_encoder *encoder, int encoder_type)

初始化具有基本功能的预分配编码器。

参数

struct drm_device *dev

drm 设备

struct drm_encoder *encoder

要初始化的编码器

int encoder_type

编码器的用户可见类型

描述

初始化没有其他功能的预分配编码器。可能的 CRTC 和克隆的设置保留为其初始值。编码器将作为模式设置清理的一部分自动清理。

drm_simple_encoder_init() 的调用者负责在编码器清理后释放编码器的内存。目前,这只有在编码器数据结构存储在设备结构中时才能可靠地工作。释放编码器的内存作为设备释放功能的一部分。

注意

考虑使用 drmm_simple_encoder_alloc() 而不是 drm_simple_encoder_init(),以便让 DRM 管理的资源基础设施来处理清理和释放。

返回

成功时返回 0,失败时返回错误代码。

int drm_simple_display_pipe_attach_bridge(struct drm_simple_display_pipe *pipe, struct drm_bridge *bridge)

将桥接器附加到显示管道

参数

struct drm_simple_display_pipe *pipe

简单的显示管道对象

struct drm_bridge *bridge

要附加的桥接器

描述

使得在必须使用 DRM 桥接器时仍然可以使用 drm_simple_display_pipe 助手函数。

请注意,您可能希望通过将 NULL 连接器传递给 drm_simple_display_pipe_init() 来初始化管道。

返回

成功时返回 0,失败时返回负错误代码。

int drm_simple_display_pipe_init(struct drm_device *dev, struct drm_simple_display_pipe *pipe, const struct drm_simple_display_pipe_funcs *funcs, const uint32_t *formats, unsigned int format_count, const uint64_t *format_modifiers, struct drm_connector *connector)

初始化一个简单的显示管道

参数

struct drm_device *dev

DRM 设备

struct drm_simple_display_pipe *pipe

要初始化的简单显示管道对象

const struct drm_simple_display_pipe_funcs *funcs

显示管道的回调函数(可选)

const uint32_t *formats

支持格式的数组 (DRM_FORMAT_*)

unsigned int format_count

formats 中的元素数量

const uint64_t *format_modifiers

格式修饰符的数组

struct drm_connector *connector

要附加和注册的连接器(可选)

描述

设置一个由非常简单的平面-CRTC-编码器管道组成的显示管道。

如果提供了连接器,管道将与提供的连接器耦合。使用 DRM 桥接器时,您可以提供 NULL 连接器,这些桥接器本身处理连接器(请参阅 drm_simple_display_pipe_attach_bridge())。

简单显示管道的拆卸完全由 DRM 核心通过调用 drm_mode_config_cleanup() 自动处理。驱动程序随后需要自行释放结构的内存。

返回

成功时返回 0,失败时返回负错误代码。

fbdev 助手函数参考

fb 助手函数对于在 DRM 内核模式设置驱动程序之上提供 fbdev 非常有用。它们可以主要独立于许多驱动程序用于实现内核模式设置接口的 CRTC 助手函数使用。使用共享内存管理器 TTM、SHMEM、DMA 的驱动程序应改为使用相应的 fbdev 仿真。

对于挂起/恢复,请考虑使用 drm_mode_config_helper_suspend()drm_mode_config_helper_resume(),它们也负责处理 fbdev。

fb 助手库导出的所有其他函数都可以被驱动程序用来实现 fbdev 驱动程序接口。

可以使用 fbdev 助手函数来实现无竞争的热插拔检测,但这可能有些棘手。drm_fb_helper_prepare() 助手函数必须首先被调用,以初始化热插拔检测工作的最低要求。驱动程序还需要确保正确设置 drm_mode_config.funcs 成员。在调用 drm_kms_helper_poll_init() 之后,启用中断并开始处理热插拔事件是安全的。同时,驱动程序应初始化所有模式设置对象,如 CRTC、编码器和连接器。要完成 fbdev 助手函数的初始化,应调用 drm_fb_helper_init() 函数。要探测所有已连接的显示器并使用检测到的硬件设置初始配置,驱动程序应调用 drm_fb_helper_initial_config()

如果设置了 drm_framebuffer_funcs.dirty,drm_fb_helper_{cfb,sys}_{write,fillrect,copyarea,imageblit} 函数将累积更改并安排 drm_fb_helper.dirty_work 立即运行。然后,此工作线程调用 dirty() 函数,确保它始终在进程上下文中运行,因为 fb_*() 函数可能在原子上下文中运行。如果 drm_fb_helper_deferred_io() 用作 deferred_io 回调函数,它还将使用从 mmap 页面写入收集的损坏安排 dirty_work。

struct drm_fb_helper_surface_size

描述 fbdev 大小和扫描输出表面大小

定义:

struct drm_fb_helper_surface_size {
    u32 fb_width;
    u32 fb_height;
    u32 surface_width;
    u32 surface_height;
    u32 surface_bpp;
    u32 surface_depth;
};

成员

fb_width

fbdev 宽度

fb_height

fbdev 高度

surface_width

扫描输出缓冲区宽度

surface_height

扫描输出缓冲区高度

surface_bpp

扫描输出缓冲区 bpp

surface_depth

扫描输出缓冲区深度

描述

请注意,扫描输出表面宽度/高度可能大于 fbdev 宽度/高度。在多个显示器的情况下,扫描输出表面根据最大宽度/高度调整大小(因此它对于所有 CRTC 扫描输出都足够大)。但 fbdev 宽度/高度调整为所有显示器的最小宽度/高度。这确保了 fbcon 适合于最小的已连接显示器。fb_width/fb_height 由 drm_fb_helper_fill_info() 用来填充 fb_info.var 结构。

struct drm_fb_helper_funcs

fbdev 仿真库的驱动程序回调函数

定义:

struct drm_fb_helper_funcs {
    int (*fb_dirty)(struct drm_fb_helper *helper, struct drm_clip_rect *clip);
    void (*fb_restore)(struct drm_fb_helper *helper);
    void (*fb_set_suspend)(struct drm_fb_helper *helper, bool suspend);
};

成员

fb_dirty

驱动程序回调函数,用于更新帧缓冲存储器。如果设置,fbdev 仿真将在帧缓冲存储器写入后以正常间隔调用此回调函数。

此回调是可选的。

返回值:成功时返回 0,否则返回错误代码。

fb_restore

驱动程序回调函数,用于恢复内部 fbdev 状态。如果设置,fbdev 仿真将在恢复显示模式后调用此回调函数。

仅适用于 i915。请勿在新代码中使用。

TODO:修复 i915,使其不需要此回调函数。

fb_set_suspend

如果设置了驱动程序回调函数以挂起或恢复,fbdev 仿真将在挂起和恢复期间调用此回调函数。驱动程序应从其实现中调用 fb_set_suspend()。如果未设置,fbdev 仿真将直接调用 fb_set_suspend()

仅适用于 i915。请勿在新代码中使用。

TODO:修复 i915,使其不需要此回调函数。

描述

fbdev 仿真助手库使用的驱动程序回调函数。

struct drm_fb_helper

在 KMS 之上模拟 fbdev 的主要结构

定义:

struct drm_fb_helper {
    struct drm_client_dev client;
    struct drm_client_buffer *buffer;
    struct drm_framebuffer *fb;
    struct drm_device *dev;
    const struct drm_fb_helper_funcs *funcs;
    struct fb_info *info;
    u32 pseudo_palette[17];
    struct drm_clip_rect damage_clip;
    spinlock_t damage_lock;
    struct work_struct damage_work;
    struct work_struct resume_work;
    struct mutex lock;
    struct list_head kernel_fb_list;
    bool delayed_hotplug;
    bool deferred_setup;
    int preferred_bpp;
#ifdef CONFIG_FB_DEFERRED_IO;
    struct fb_deferred_io fbdefio;
#endif;
};

成员

client

通用 fbdev 仿真使用的 DRM 客户端。

buffer

通用 fbdev 仿真使用的帧缓冲存储器。

fb

扫描输出帧缓冲存储器对象

dev

DRM 设备

funcs

fb 助手函数的驱动程序回调函数

info

模拟的 fbdev 设备信息结构

pseudo_palette

16 种颜色的伪调色板

damage_clip

与 deferred_io 一起使用的剪辑矩形,用于累积屏幕缓冲区的损坏

damage_lock

保护 damage_clip 的自旋锁

damage_work

用于刷新帧缓冲存储器的工作线程

resume_work

如果在恢复期间已经获取了控制台锁,则在恢复期间使用的工作线程

lock

顶级 FBDEV 助手函数锁。这保护所有内部数据结构和列表,例如 connector_infocrtc_info

FIXME:fbdev 仿真锁定是一团糟,从长远来看,我们希望使用此锁保护所有助手函数的内部状态,并尽可能减少核心 KMS 锁定。

kernel_fb_list

全局 kernel_fb_helper_list 上的条目,用于 kgdb 进入/退出。

delayed_hotplug

当 fbdev 不控制 DRM 设备时(即另一个 KMS 主设备处于活动状态)收到了热插拔事件。当 fbdev 再次控制时,需要重新探测输出配置。

deferred_setup

如果未连接任何输出(已断开连接或未知),则 FB 助手函数代码将延迟设置,直到至少一个输出显示出来。此字段跟踪状态,以便可以在每次热插拔事件时重试设置,直到最终成功为止。

lock 保护。

preferred_bpp

驱动程序传递给 FB 助手函数初始化的首选 BPP 设置的临时存储。这需要跟踪,以便延迟的 FB 助手函数设置可以传递此信息。

另请参阅:deferred_setup

fbdefio

驱动程序的 FB 延迟 I/O 处理程序的临时存储。如果驱动程序使用 DRM fbdev 仿真层,则如果驱动程序更喜欢使用阴影缓冲区,则核心会将此设置为通用的延迟 I/O 处理程序。

描述

这是 fbdev 助手函数使用的主要结构。支持 fbdev 仿真的驱动程序应将其嵌入到其整体驱动程序结构中。驱动程序还必须使用一些操作填充 struct drm_fb_helper_funcs

DRM_FB_HELPER_DEFAULT_OPS

DRM_FB_HELPER_DEFAULT_OPS

drm 驱动程序的助手函数定义

描述

用于注册 drm_fb_helper 函数的默认实现的助手函数定义。用于 DRM 驱动程序的 struct fb_ops 中。

int drm_fb_helper_debug_enter(struct fb_info *info)

fb_ops.fb_debug_enter 的实现

参数

struct fb_info *info

助手函数注册的 fbdev

int drm_fb_helper_debug_leave(struct fb_info *info)

fb_ops.fb_debug_leave 的实现

参数

struct fb_info *info

助手函数注册的 fbdev

int drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper)

恢复 fbdev 配置

参数

struct drm_fb_helper *fb_helper

驱动程序分配的 fbdev 助手函数,可以为 NULL

描述

此助手函数应从 fbdev 仿真的 drm_client_funcs.restore 回调函数中调用。它确保当用户空间合成器释放显示设备时,用户不会看到黑屏。

返回

成功时为 0,否则为负 errno 代码。

int drm_fb_helper_blank(int blank, struct fb_info *info)

fb_ops.fb_blank 的实现

参数

int blank

所需的消隐状态

struct fb_info *info

助手函数注册的 fbdev

void drm_fb_helper_prepare(struct drm_device *dev, struct drm_fb_helper *helper, unsigned int preferred_bpp, const struct drm_fb_helper_funcs *funcs)

设置 drm_fb_helper 结构

参数

struct drm_device *dev

DRM 设备

struct drm_fb_helper *helper

要设置的驱动程序分配的 fbdev 助手函数结构

unsigned int preferred_bpp

设备的首选每像素位数。

const struct drm_fb_helper_funcs *funcs

指向与此助手函数关联的函数结构的指针

描述

设置使帧缓冲存储器助手函数可用的最低要求。这对于实现轮询助手函数的无竞争初始化非常有用。

void drm_fb_helper_unprepare(struct drm_fb_helper *fb_helper)

清理 drm_fb_helper 结构

参数

struct drm_fb_helper *fb_helper

要设置的驱动程序分配的 fbdev 助手函数结构

描述

清理帧缓冲存储器助手函数。是 drm_fb_helper_prepare() 的逆操作。

int drm_fb_helper_init(struct drm_device *dev, struct drm_fb_helper *fb_helper)

初始化 struct drm_fb_helper

参数

struct drm_device *dev

drm 设备

struct drm_fb_helper *fb_helper

要初始化的驱动程序分配的 fbdev 助手函数结构

描述

这将为具有给定限制的 fbdev 助手函数分配结构。请注意,这还不会通过驱动程序接口访问硬件,也不会注册 fbdev。这仅在 drm_fb_helper_initial_config() 中完成,以允许驱动程序对确切的初始化序列进行更多控制。

驱动程序必须在调用此函数之前调用 drm_fb_helper_prepare()

返回

如果一切正常,则返回 0,否则返回非零值。

struct fb_info *drm_fb_helper_alloc_info(struct drm_fb_helper *fb_helper)

分配 fb_info 及其一些成员

参数

struct drm_fb_helper *fb_helper

驱动程序分配的 fbdev 助手函数

描述

用于分配 fb_info 和成员 cmap 的助手函数。由驱动程序在 struct drm_driver.fbdev_probe 回调函数中调用。驱动程序不需要自行释放已分配的 fb_info 结构,这会在调用 drm_fb_helper_fini() 时自动完成。

返回

如果一切正常,则返回 fb_info 指针,否则返回包含错误代码的指针

void drm_fb_helper_release_info(struct drm_fb_helper *fb_helper)

释放 fb_info 及其成员

参数

struct drm_fb_helper *fb_helper

驱动程序分配的 fbdev 助手函数

描述

用于释放 fb_info 和成员 cmap 的助手函数。驱动程序不需要自行释放已分配的 fb_info 结构,这会在调用 drm_fb_helper_fini() 时自动完成。

void drm_fb_helper_unregister_info(struct drm_fb_helper *fb_helper)

取消注册 fb_info 帧缓冲存储器设备

参数

struct drm_fb_helper *fb_helper

驱动程序分配的 fbdev 助手函数,不得为 NULL

描述

unregister_framebuffer 的包装器,用于释放 fb_info 帧缓冲存储器设备。这必须在通过调用 drm_fb_helper_fini() 释放 fb_helper 的所有资源之前调用。

void drm_fb_helper_fini(struct drm_fb_helper *fb_helper)

完成 struct drm_fb_helper

参数

struct drm_fb_helper *fb_helper

驱动程序分配的 fbdev 助手函数,可以为 NULL

描述

这将清理与 fb_helper 关联的所有剩余资源。

void drm_fb_helper_deferred_io(struct fb_info *info, struct list_head *pagereflist)

fbdev deferred_io 回调函数

参数

struct fb_info *info

fb_info 结构指针

struct list_head *pagereflist

需要刷新的 mmap 帧缓冲存储器页面的列表

描述

此函数用作 fb_deferred_io.deferred_io 回调函数,用于刷新 fbdev mmap 写入。

void drm_fb_helper_set_suspend(struct drm_fb_helper *fb_helper, bool suspend)

fb_set_suspend 的包装器

参数

struct drm_fb_helper *fb_helper

驱动程序分配的 fbdev 助手函数,可以为 NULL

bool suspend

是否挂起或恢复

描述

fbdev 核心实现的 fb_set_suspend 的包装器。如果不需要自己获取锁,请使用 drm_fb_helper_set_suspend_unlocked()

void drm_fb_helper_set_suspend_unlocked(struct drm_fb_helper *fb_helper, bool suspend)

还获取控制台锁的 fb_set_suspend 的包装器

参数

struct drm_fb_helper *fb_helper

驱动程序分配的 fbdev 助手函数,可以为 NULL

bool suspend

是否挂起或恢复

描述

fb_set_suspend() 的包装器,它获取控制台锁。如果在恢复时锁不可用,则会分配一个工作线程来等待锁变为可用。由于所有 printk 活动,控制台锁在恢复时可能非常争用。

可以使用相同的状态多次调用此函数,因为在锁定之前会检查 fb_info.state 以查看 fbdev 是否正在运行。

如果需要自己获取锁,请使用 drm_fb_helper_set_suspend()

int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info)

fb_ops.fb_setcmap 的实现

参数

struct fb_cmap *cmap

要设置的 cmap

struct fb_info *info

助手函数注册的 fbdev

int drm_fb_helper_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)

旧版 ioctl 实现

参数

struct fb_info *info

助手函数注册的 fbdev

unsigned int cmd

ioctl 命令

unsigned long arg

ioctl 参数

描述

用于实现标准 fbdev ioctl 的助手函数。目前仅实现了 FBIO_WAITFORVSYNC。

int drm_fb_helper_check_var(struct fb_var_screeninfo *var, struct fb_info *info)

fb_ops.fb_check_var 的实现

参数

struct fb_var_screeninfo *var

要检查的 screeninfo

struct fb_info *info

助手函数注册的 fbdev

int drm_fb_helper_set_par(struct fb_info *info)

fb_ops.fb_set_par 的实现

参数

struct fb_info *info

助手函数注册的 fbdev

描述

这将让 fbcon 执行模式初始化,并在初始化时由 fbdev 核心在注册驱动程序时调用,以及稍后通过热插拔回调函数调用。

int drm_fb_helper_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)

fb_ops.fb_pan_display 的实现

参数

struct fb_var_screeninfo *var

更新的屏幕信息

struct fb_info *info

助手函数注册的 fbdev

void drm_fb_helper_fill_info(struct fb_info *info, struct drm_fb_helper *fb_helper, struct drm_fb_helper_surface_size *sizes)

初始化 fbdev 信息

参数

struct fb_info *info

要设置的 fbdev 实例

struct drm_fb_helper *fb_helper

用作模板的 fb 助手函数实例

struct drm_fb_helper_surface_size *sizes

描述 fbdev 大小和扫描输出表面大小

描述

从给定的 fb 助手函数实例和 drm_fb_helper.fb 中分配的 DRM 帧缓冲存储器设置变量和固定的 fbdev 元信息。

驱动程序应在分配 fbdev 后备存储帧缓冲存储器之后,从其 drm_driver.fbdev_probe 回调函数中调用此代码(或其等效的设置代码)。

int drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper)

设置合理的初始连接器配置

参数

struct drm_fb_helper *fb_helper

fb_helper 设备结构体

描述

扫描 CRTC 和连接器,并尝试组合成初始设置。目前,这是一个在所有头上的克隆配置,使用一个新的帧缓冲对象作为后备存储。

请注意,这也会注册 fbdev,因此允许用户空间通过 fbdev 接口调用驱动程序。

此函数将向下调用 drm_driver.fbdev_probe 回调,以允许驱动程序分配和初始化 fbdev 信息结构体和用于支持 fbdev 的 drm 帧缓冲。drm_fb_helper_fill_info() 作为帮助程序提供,用于为 fbdev 信息结构体设置简单的默认值。

挂起调试

当您具有内置或已加载的 fbcon 支持时,此函数将执行完整的模式设置以设置 fbdev 控制台。由于 VT/fbdev 子系统中的锁定错误设计,整个模式设置序列必须在持有 console_lock 时完成。在调用 console_unlock 之前,不会将 dmesg 行发送到控制台,甚至不会发送到串行控制台。这意味着当您的驱动程序崩溃时,除了系统卡在此函数中之外,您将看不到任何其他内容,也不会有进一步的输出。您放置在自己的驱动程序中或 drm 核心模式设置代码中的任何类型的 printk() 也永远不会显示。

标准的调试实践是以一种破解方式运行 fbcon 设置而不获取 console_lock,以便能够在串行线上看到回溯和崩溃。这可以通过设置 fb.lockless_register_fb=1 内核命令行选项来完成。

另一种选择是禁用 fbdev 仿真,因为很可能来自用户空间的第一个模式设置会以相同的方式崩溃,并且调试起来甚至更容易。这可以通过设置 drm_kms_helper.fbdev_emulation=0 内核命令行选项来完成。

返回

如果一切正常,则返回 0,否则返回非零值。

int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper)

通过探测连接到 fb 的所有输出,响应热插拔通知

参数

struct drm_fb_helper *fb_helper

驱动程序分配的 fbdev 助手函数,可以为 NULL

描述

扫描连接到 fb_helper 的连接器,并尝试在输出配置更改的通知后组合成一个设置。

在运行时调用,获取模式配置锁,以便能够检查/更改模式设置配置。必须从进程上下文中运行(通常意味着输出轮询工作或从驱动程序的热插拔中断启动的工作项)。

请注意,驱动程序甚至可以在调用 drm_fb_helper_initial_config 之前调用此函数,但只能在 drm_fb_helper_init 之后调用。这允许无竞争的 fbcon 设置,并将确保 fbdev 仿真不会错过任何热插拔事件。

返回

成功时返回 0,否则返回非零错误代码。

void drm_fb_helper_lastclose(struct drm_device *dev)

用于 fbdev 仿真的 DRM 驱动程序 lastclose 帮助程序

参数

struct drm_device *dev

DRM 设备

描述

此函数已过时。请改用 drm_fb_helper_restore_fbdev_mode_unlocked()

格式帮助程序函数参考

void drm_format_conv_state_init(struct drm_format_conv_state *state)

初始化格式转换状态

参数

struct drm_format_conv_state *state

要初始化的状态

描述

清除 struct drm_format_conv_state 中的所有字段。该状态将为空,没有预分配的资源。

void drm_format_conv_state_copy(struct drm_format_conv_state *state, const struct drm_format_conv_state *old_state)

复制格式转换状态

参数

struct drm_format_conv_state *state

目标状态

const struct drm_format_conv_state *old_state

源状态

描述

将格式转换状态从 old_state 复制到 state;临时存储除外。

void *drm_format_conv_state_reserve(struct drm_format_conv_state *state, size_t new_size, gfp_t flags)

为格式转换分配存储空间

参数

struct drm_format_conv_state *state

格式转换状态

size_t new_size

最小分配大小

gfp_t flags

kmalloc() 的标志

描述

分配至少 new_size 个字节,并返回指向内存范围的指针。调用此函数后,先前返回的内存块无效。最好收集格式转换的所有内存需求,并调用此函数一次以分配该范围。

返回

指向已分配内存范围的指针,否则为 NULL。

void drm_format_conv_state_release(struct drm_format_conv_state *state)

释放格式转换存储

参数

struct drm_format_conv_state *state

格式转换状态

描述

释放格式转换状态引用的内存范围。在此调用之后,所有指向内存的指针都无效。首选 drm_format_conv_state_init() 来清理和卸载驱动程序。

unsigned int drm_fb_clip_offset(unsigned int pitch, const struct drm_format_info *format, const struct drm_rect *clip)

返回帧缓冲中裁剪矩形的字节偏移量

参数

unsigned int pitch

帧缓冲行距(以字节为单位)

const struct drm_format_info *format

帧缓冲格式

const struct drm_rect *clip

裁剪矩形

返回

裁剪矩形左上角在帧缓冲中的字节偏移量。

void drm_fb_memcpy(struct iosys_map *dst, const unsigned int *dst_pitch, const struct iosys_map *src, const struct drm_framebuffer *fb, const struct drm_rect *clip)

复制裁剪缓冲区

参数

struct iosys_map *dst

目标缓冲区数组

const unsigned int *dst_pitch

**dst** 中两个连续扫描线的起始位置之间的字节数数组;如果扫描线彼此相邻存储,则可以为 NULL。

const struct iosys_map *src

源缓冲区数组

const struct drm_framebuffer *fb

DRM 帧缓冲区

const struct drm_rect *clip

要复制的裁剪矩形区域

描述

此函数将帧缓冲的部分内容复制到显示内存。目标和帧缓冲格式必须匹配。不进行转换。参数 dstdst_pitchsrc 指的是数组。每个数组必须至少有与 fb 格式中的平面一样多的条目。每个条目存储格式在相同索引处的各个颜色平面的值。

此函数不适用于 dst 上的裁剪(即目标位于左上角)。

void drm_fb_swab(struct iosys_map *dst, const unsigned int *dst_pitch, const struct iosys_map *src, const struct drm_framebuffer *fb, const struct drm_rect *clip, bool cached, struct drm_format_conv_state *state)

将字节交换到裁剪缓冲区中

参数

struct iosys_map *dst

目标缓冲区数组

const unsigned int *dst_pitch

**dst** 中两个连续扫描线的起始位置之间的字节数数组;如果扫描线彼此相邻存储,则可以为 NULL。

const struct iosys_map *src

源缓冲区数组

const struct drm_framebuffer *fb

DRM 帧缓冲区

const struct drm_rect *clip

要复制的裁剪矩形区域

bool cached

源缓冲区被映射缓存(例如,不是写组合)

struct drm_format_conv_state *state

转换和转换状态

描述

此函数将帧缓冲的部分内容复制到显示内存,并在该过程中交换每个像素的字节。目标和帧缓冲格式必须匹配。参数 dstdst_pitchsrc 指的是数组。每个数组必须至少有与 fb 格式中的平面一样多的条目。每个条目存储格式在相同索引处的各个颜色平面的值。如果 cached 为 false,则使用临时缓冲区一次缓存一行像素,以加快慢速非缓存读取。

此函数不适用于 dst 上的裁剪(即目标位于左上角)。

void drm_fb_xrgb8888_to_rgb332(struct iosys_map *dst, const unsigned int *dst_pitch, const struct iosys_map *src, const struct drm_framebuffer *fb, const struct drm_rect *clip, struct drm_format_conv_state *state)

将 XRGB8888 转换为 RGB332 裁剪缓冲区

参数

struct iosys_map *dst

RGB332 目标缓冲区数组

const unsigned int *dst_pitch

**dst** 中两个连续扫描线的起始位置之间的字节数数组;如果扫描线彼此相邻存储,则可以为 NULL。

const struct iosys_map *src

XRGB8888 源缓冲区数组

const struct drm_framebuffer *fb

DRM 帧缓冲区

const struct drm_rect *clip

要复制的裁剪矩形区域

struct drm_format_conv_state *state

转换和转换状态

描述

此函数将帧缓冲的部分内容复制到显示内存,并在该过程中转换颜色格式。目标和帧缓冲格式必须匹配。参数 dstdst_pitchsrc 指的是数组。每个数组必须至少有与 fb 格式中的平面一样多的条目。每个条目存储格式在相同索引处的各个颜色平面的值。

此函数不适用于 dst 上的裁剪(即目标位于左上角)。

对于本身不支持 XRGB8888 的 RGB332 设备,驱动程序可以使用此函数。

void drm_fb_xrgb8888_to_rgb565(struct iosys_map *dst, const unsigned int *dst_pitch, const struct iosys_map *src, const struct drm_framebuffer *fb, const struct drm_rect *clip, struct drm_format_conv_state *state, bool swab)

将 XRGB8888 转换为 RGB565 裁剪缓冲区

参数

struct iosys_map *dst

RGB565 目标缓冲区数组

const unsigned int *dst_pitch

**dst** 中两个连续扫描线的起始位置之间的字节数数组;如果扫描线彼此相邻存储,则可以为 NULL。

const struct iosys_map *src

XRGB8888 源缓冲区数组

const struct drm_framebuffer *fb

DRM 帧缓冲区

const struct drm_rect *clip

要复制的裁剪矩形区域

struct drm_format_conv_state *state

转换和转换状态

bool swab

交换字节

描述

此函数将帧缓冲的部分内容复制到显示内存,并在该过程中转换颜色格式。目标和帧缓冲格式必须匹配。参数 dstdst_pitchsrc 指的是数组。每个数组必须至少有与 fb 格式中的平面一样多的条目。每个条目存储格式在相同索引处的各个颜色平面的值。

此函数不适用于 dst 上的裁剪(即目标位于左上角)。

对于本身不支持 XRGB8888 的 RGB565 设备,驱动程序可以使用此函数。

void drm_fb_xrgb8888_to_xrgb1555(struct iosys_map *dst, const unsigned int *dst_pitch, const struct iosys_map *src, const struct drm_framebuffer *fb, const struct drm_rect *clip, struct drm_format_conv_state *state)

将 XRGB8888 转换为 XRGB1555 裁剪缓冲区

参数

struct iosys_map *dst

XRGB1555 目标缓冲区数组

const unsigned int *dst_pitch

**dst** 中两个连续扫描线的起始位置之间的字节数数组;如果扫描线彼此相邻存储,则可以为 NULL。

const struct iosys_map *src

XRGB8888 源缓冲区数组

const struct drm_framebuffer *fb

DRM 帧缓冲区

const struct drm_rect *clip

要复制的裁剪矩形区域

struct drm_format_conv_state *state

转换和转换状态

描述

此函数将帧缓冲的部分内容复制到显示内存,并在该过程中转换颜色格式。参数 dstdst_pitchsrc 指的是数组。每个数组必须至少有与 fb 格式中的平面一样多的条目。每个条目存储格式在相同索引处的各个颜色平面的值。

此函数不适用于 dst 上的裁剪(即目标位于左上角)。

对于本身不支持 XRGB8888 的 XRGB1555 设备,驱动程序可以使用此函数。

void drm_fb_xrgb8888_to_argb1555(struct iosys_map *dst, const unsigned int *dst_pitch, const struct iosys_map *src, const struct drm_framebuffer *fb, const struct drm_rect *clip, struct drm_format_conv_state *state)

将 XRGB8888 转换为 ARGB1555 裁剪缓冲区

参数

struct iosys_map *dst

ARGB1555 目标缓冲区数组

const unsigned int *dst_pitch

**dst** 中两个连续扫描线的起始位置之间的字节数数组;如果扫描线彼此相邻存储,则可以为 NULL。

const struct iosys_map *src

XRGB8888 源缓冲区数组

const struct drm_framebuffer *fb

DRM 帧缓冲区

const struct drm_rect *clip

要复制的裁剪矩形区域

struct drm_format_conv_state *state

转换和转换状态

描述

此函数将帧缓冲的部分内容复制到显示内存,并在该过程中转换颜色格式。参数 dstdst_pitchsrc 指的是数组。每个数组必须至少有与 fb 格式中的平面一样多的条目。每个条目存储格式在相同索引处的各个颜色平面的值。

此函数不适用于 dst 上的裁剪(即目标位于左上角)。

对于本身不支持 XRGB8888 的 ARGB1555 设备,驱动程序可以使用此函数。它设置一个不透明的 Alpha 通道作为转换的一部分。

void drm_fb_xrgb8888_to_rgba5551(struct iosys_map *dst, const unsigned int *dst_pitch, const struct iosys_map *src, const struct drm_framebuffer *fb, const struct drm_rect *clip, struct drm_format_conv_state *state)

将 XRGB8888 转换为 RGBA5551 裁剪缓冲区

参数

struct iosys_map *dst

RGBA5551 目标缓冲区数组

const unsigned int *dst_pitch

**dst** 中两个连续扫描线的起始位置之间的字节数数组;如果扫描线彼此相邻存储,则可以为 NULL。

const struct iosys_map *src

XRGB8888 源缓冲区数组

const struct drm_framebuffer *fb

DRM 帧缓冲区

const struct drm_rect *clip

要复制的裁剪矩形区域

struct drm_format_conv_state *state

转换和转换状态

描述

此函数将帧缓冲的部分内容复制到显示内存,并在该过程中转换颜色格式。参数 dstdst_pitchsrc 指的是数组。每个数组必须至少有与 fb 格式中的平面一样多的条目。每个条目存储格式在相同索引处的各个颜色平面的值。

此函数不适用于 dst 上的裁剪(即目标位于左上角)。

对于本身不支持 XRGB8888 的 RGBA5551 设备,驱动程序可以使用此函数。它设置一个不透明的 Alpha 通道作为转换的一部分。

void drm_fb_xrgb8888_to_rgb888(struct iosys_map *dst, const unsigned int *dst_pitch, const struct iosys_map *src, const struct drm_framebuffer *fb, const struct drm_rect *clip, struct drm_format_conv_state *state)

将 XRGB8888 转换为 RGB888 裁剪缓冲区

参数

struct iosys_map *dst

RGB888 目标缓冲区数组

const unsigned int *dst_pitch

**dst** 中两个连续扫描线的起始位置之间的字节数数组;如果扫描线彼此相邻存储,则可以为 NULL。

const struct iosys_map *src

XRGB8888 源缓冲区数组

const struct drm_framebuffer *fb

DRM 帧缓冲区

const struct drm_rect *clip

要复制的裁剪矩形区域

struct drm_format_conv_state *state

转换和转换状态

描述

此函数将帧缓冲的部分内容复制到显示内存,并在该过程中转换颜色格式。目标和帧缓冲格式必须匹配。参数 dstdst_pitchsrc 指的是数组。每个数组必须至少有与 fb 格式中的平面一样多的条目。每个条目存储格式在相同索引处的各个颜色平面的值。

此函数不适用于 dst 上的裁剪(即目标位于左上角)。

对于本身不支持 XRGB8888 的 RGB888 设备,驱动程序可以使用此函数。

void drm_fb_xrgb8888_to_bgr888(struct iosys_map *dst, const unsigned int *dst_pitch, const struct iosys_map *src, const struct drm_framebuffer *fb, const struct drm_rect *clip, struct drm_format_conv_state *state)

将 XRGB8888 转换为 BGR888 裁剪缓冲区

参数

struct iosys_map *dst

BGR888 目标缓冲区数组

const unsigned int *dst_pitch

**dst** 中两个连续扫描线的起始位置之间的字节数数组;如果扫描线彼此相邻存储,则可以为 NULL。

const struct iosys_map *src

XRGB8888 源缓冲区数组

const struct drm_framebuffer *fb

DRM 帧缓冲区

const struct drm_rect *clip

要复制的裁剪矩形区域

struct drm_format_conv_state *state

转换和转换状态

描述

此函数将帧缓冲的部分内容复制到显示内存,并在该过程中转换颜色格式。目标和帧缓冲格式必须匹配。参数 dstdst_pitchsrc 指的是数组。每个数组必须至少有与 fb 格式中的平面一样多的条目。每个条目存储格式在相同索引处的各个颜色平面的值。

此函数不适用于 dst 上的裁剪(即目标位于左上角)。

对于本身不支持 XRGB8888 的 BGR888 设备,驱动程序可以使用此函数。

void drm_fb_xrgb8888_to_argb8888(struct iosys_map *dst, const unsigned int *dst_pitch, const struct iosys_map *src, const struct drm_framebuffer *fb, const struct drm_rect *clip, struct drm_format_conv_state *state)

将 XRGB8888 转换为 ARGB8888 裁剪缓冲区

参数

struct iosys_map *dst

ARGB8888 目标缓冲区数组

const unsigned int *dst_pitch

**dst** 中两个连续扫描线的起始位置之间的字节数数组;如果扫描线彼此相邻存储,则可以为 NULL。

const struct iosys_map *src

XRGB8888 源缓冲区数组

const struct drm_framebuffer *fb

DRM 帧缓冲区

const struct drm_rect *clip

要复制的裁剪矩形区域

struct drm_format_conv_state *state

转换和转换状态

描述

此函数将帧缓冲的部分内容复制到显示内存,并在该过程中转换颜色格式。参数 dstdst_pitchsrc 指的是数组。每个数组必须至少有与 fb 格式中的平面一样多的条目。每个条目存储格式在相同索引处的各个颜色平面的值。

此函数不适用于 dst 上的裁剪(即目标位于左上角)。

对于本身不支持 XRGB8888 的 ARGB8888 设备,驱动程序可以使用此函数。它设置一个不透明的 Alpha 通道作为转换的一部分。

void drm_fb_xrgb8888_to_xrgb2101010(struct iosys_map *dst, const unsigned int *dst_pitch, const struct iosys_map *src, const struct drm_framebuffer *fb, const struct drm_rect *clip, struct drm_format_conv_state *state)

转换 XRGB8888 到 XRGB2101010 裁剪缓冲区

参数

struct iosys_map *dst

XRGB2101010 目标缓冲区数组

const unsigned int *dst_pitch

**dst** 中两个连续扫描线的起始位置之间的字节数数组;如果扫描线彼此相邻存储,则可以为 NULL。

const struct iosys_map *src

XRGB8888 源缓冲区数组

const struct drm_framebuffer *fb

DRM 帧缓冲区

const struct drm_rect *clip

要复制的裁剪矩形区域

struct drm_format_conv_state *state

转换和转换状态

描述

此函数将帧缓冲的部分内容复制到显示内存,并在该过程中转换颜色格式。目标和帧缓冲格式必须匹配。参数 dstdst_pitchsrc 指的是数组。每个数组必须至少有与 fb 格式中的平面一样多的条目。每个条目存储格式在相同索引处的各个颜色平面的值。

此函数不适用于 dst 上的裁剪(即目标位于左上角)。

对于原生不支持 XRGB8888 的 XRGB2101010 设备,驱动程序可以使用此函数。

void drm_fb_xrgb8888_to_argb2101010(struct iosys_map *dst, const unsigned int *dst_pitch, const struct iosys_map *src, const struct drm_framebuffer *fb, const struct drm_rect *clip, struct drm_format_conv_state *state)

转换 XRGB8888 到 ARGB2101010 裁剪缓冲区

参数

struct iosys_map *dst

ARGB2101010 目标缓冲区数组

const unsigned int *dst_pitch

**dst** 中两个连续扫描线的起始位置之间的字节数数组;如果扫描线彼此相邻存储,则可以为 NULL。

const struct iosys_map *src

XRGB8888 源缓冲区数组

const struct drm_framebuffer *fb

DRM 帧缓冲区

const struct drm_rect *clip

要复制的裁剪矩形区域

struct drm_format_conv_state *state

转换和转换状态

描述

此函数将帧缓冲的部分内容复制到显示内存,并在该过程中转换颜色格式。参数 dstdst_pitchsrc 指的是数组。每个数组必须至少有与 fb 格式中的平面一样多的条目。每个条目存储格式在相同索引处的各个颜色平面的值。

此函数不适用于 dst 上的裁剪(即目标位于左上角)。

对于原生不支持 XRGB8888 的 ARGB2101010 设备,驱动程序可以使用此函数。

void drm_fb_xrgb8888_to_gray8(struct iosys_map *dst, const unsigned int *dst_pitch, const struct iosys_map *src, const struct drm_framebuffer *fb, const struct drm_rect *clip, struct drm_format_conv_state *state)

转换 XRGB8888 为灰度

参数

struct iosys_map *dst

8 位灰度目标缓冲区数组

const unsigned int *dst_pitch

**dst** 中两个连续扫描线的起始位置之间的字节数数组;如果扫描线彼此相邻存储,则可以为 NULL。

const struct iosys_map *src

XRGB8888 源缓冲区数组

const struct drm_framebuffer *fb

DRM 帧缓冲区

const struct drm_rect *clip

要复制的裁剪矩形区域

struct drm_format_conv_state *state

转换和转换状态

描述

此函数将帧缓冲的部分内容复制到显示内存,并在该过程中转换颜色格式。目标和帧缓冲格式必须匹配。参数 dstdst_pitchsrc 指的是数组。每个数组必须至少有与 fb 格式中的平面一样多的条目。每个条目存储格式在相同索引处的各个颜色平面的值。

此函数不适用于 dst 上的裁剪(即目标位于左上角)。

DRM 没有原生的单色或灰度支持。对于原生不支持 XRGB8888 的灰度设备,驱动程序可以使用此函数。此类驱动程序可以向用户空间声明常用的 XR24 格式,并使用此函数转换为原生格式。单色驱动程序将使用最高有效位,其中 1 表示前景色,0 表示背景色。ITU BT.601 用于 RGB -> 亮度(亮度)转换。

void drm_fb_argb8888_to_argb4444(struct iosys_map *dst, const unsigned int *dst_pitch, const struct iosys_map *src, const struct drm_framebuffer *fb, const struct drm_rect *clip, struct drm_format_conv_state *state)

转换 ARGB8888 到 ARGB4444 裁剪缓冲区

参数

struct iosys_map *dst

ARGB4444 目标缓冲区数组

const unsigned int *dst_pitch

**dst** 中两个连续扫描线的起始位置之间的字节数数组;如果扫描线彼此相邻存储,则可以为 NULL。

const struct iosys_map *src

ARGB8888 源缓冲区数组

const struct drm_framebuffer *fb

DRM 帧缓冲区

const struct drm_rect *clip

要复制的裁剪矩形区域

struct drm_format_conv_state *state

转换和转换状态

描述

此函数将帧缓冲的部分内容复制到显示内存,并在该过程中转换颜色格式。参数 dstdst_pitchsrc 指的是数组。每个数组必须至少有与 fb 格式中的平面一样多的条目。每个条目存储格式在相同索引处的各个颜色平面的值。

此函数不适用于 dst 上的裁剪(即目标位于左上角)。

对于原生不支持 ARGB8888 的 ARGB4444 设备,驱动程序可以使用此函数。

int drm_fb_blit(struct iosys_map *dst, const unsigned int *dst_pitch, uint32_t dst_format, const struct iosys_map *src, const struct drm_framebuffer *fb, const struct drm_rect *clip, struct drm_format_conv_state *state)

将帧缓冲区的部分内容复制到显示内存

参数

struct iosys_map *dst

要复制到的显示内存地址数组

const unsigned int *dst_pitch

**dst** 中两个连续扫描线的起始位置之间的字节数数组;如果扫描线彼此相邻存储,则可以为 NULL。

uint32_t dst_format

显示的颜色格式的 FOURCC 代码

const struct iosys_map *src

要复制的帧缓冲区内存

const struct drm_framebuffer *fb

要复制的帧缓冲区

const struct drm_rect *clip

要复制的裁剪矩形区域

struct drm_format_conv_state *state

转换和转换状态

描述

此函数将帧缓冲区的部分内容复制到显示内存。如果显示器和帧缓冲区的格式不匹配,则 blit 函数将尝试在此过程中在它们之间进行转换。参数 dstdst_pitchsrc 引用数组。每个数组必须至少具有与 dst_format 格式中的平面一样多的条目。每个条目存储格式相应颜色平面中相同索引的值。

此函数不适用于 dst 上的裁剪(即目标位于左上角)。

返回

成功时返回 0,如果颜色格式转换失败则返回 -EINVAL,否则返回负错误代码。

void drm_fb_xrgb8888_to_mono(struct iosys_map *dst, const unsigned int *dst_pitch, const struct iosys_map *src, const struct drm_framebuffer *fb, const struct drm_rect *clip, struct drm_format_conv_state *state)

转换 XRGB8888 为单色

参数

struct iosys_map *dst

单色目标缓冲区数组(0=黑色,1=白色)

const unsigned int *dst_pitch

**dst** 中两个连续扫描线的起始位置之间的字节数数组;如果扫描线彼此相邻存储,则可以为 NULL。

const struct iosys_map *src

XRGB8888 源缓冲区数组

const struct drm_framebuffer *fb

DRM 帧缓冲区

const struct drm_rect *clip

要复制的裁剪矩形区域

struct drm_format_conv_state *state

转换和转换状态

描述

此函数将帧缓冲的部分内容复制到显示内存,并在该过程中转换颜色格式。目标和帧缓冲格式必须匹配。参数 dstdst_pitchsrc 指的是数组。每个数组必须至少有与 fb 格式中的平面一样多的条目。每个条目存储格式在相同索引处的各个颜色平面的值。

此函数不应用于 dst 的裁剪(即,目标位于左上角)。第一个像素(裁剪矩形的左上角)将被转换并复制到单色目标缓冲区的第一个字节中的第一个位 (LSB)。如果调用者要求字节中的第一个像素必须位于 x 坐标是 8 的倍数的位置,则调用者必须自己注意提供合适的裁剪矩形。

DRM 没有原生的单色支持。对于原生不支持 XRGB8888 的单色设备,驱动程序可以使用此函数。此类驱动程序可以向用户空间声明常用的 XR24 格式,并使用此函数转换为原生格式。

此函数使用 drm_fb_xrgb8888_to_gray8() 转换为灰度,然后将结果从灰度转换为单色。

size_t drm_fb_build_fourcc_list(struct drm_device *dev, const u32 *native_fourccs, size_t native_nfourccs, u32 *fourccs_out, size_t nfourccs_out)

根据设备的原生格式过滤支持的颜色格式列表

参数

struct drm_device *dev

DRM 设备

const u32 *native_fourccs

原生支持的颜色格式的 4CC 代码

size_t native_nfourccs

native_fourccs 中的条目数

u32 *fourccs_out

返回支持的颜色格式的 4CC 代码

size_t nfourccs_out

fourccs_out 中可用条目的数量

描述

此函数从原生支持的格式和其他模拟格式创建支持的颜色格式列表。至少,大多数用户空间程序都希望至少支持主平面上的 XRGB8888。必须模拟格式的设备以及可能的其他格式可以使用 drm_fb_build_fourcc_list() 创建支持的颜色格式列表。返回的列表可以传递给 drm_universal_plane_init() 等。原生格式将位于模拟格式之前。具有 alpha 通道的原生格式将被没有 alpha 通道的格式替换,因为主平面通常不支持 alpha。可能会应用其他启发式方法来优化顺序。列表中靠近开头的格式通常优先于列表中靠近结尾的格式。

返回

fourccs_out 中返回的颜色格式 4CC 代码的数量。

帧缓冲区 DMA 助手函数参考

提供用于创建 DMA 连续帧缓冲区的助手函数。

根据平台的不同,缓冲区可能在物理上是不连续的,并通过 IOMMU 或类似的机制进行映射,或者从物理上连续的内存分配(例如,使用 CMA 或在早期启动时保留的内存池)。这是由 DMA 映射 API 在后台处理的。

drm_gem_fb_create()drm_mode_config_funcs.fb_create 回调函数中用于创建 DMA 连续帧缓冲区。

struct drm_gem_dma_object *drm_fb_dma_get_gem_obj(struct drm_framebuffer *fb, unsigned int plane)

获取帧缓冲区的 DMA GEM 对象

参数

struct drm_framebuffer *fb

帧缓冲区

unsigned int plane

哪个平面

描述

返回给定帧缓冲区的 DMA GEM 对象。

此函数通常从 CRTC 回调函数中调用。

dma_addr_t drm_fb_dma_get_gem_addr(struct drm_framebuffer *fb, struct drm_plane_state *state, unsigned int plane)

获取帧缓冲区的 DMA(总线)地址,对于值分组在块中的像素格式,这将获得块的开头

参数

struct drm_framebuffer *fb

帧缓冲区

struct drm_plane_state *state

drm 平面的哪个状态

unsigned int plane

哪个平面 返回给定帧缓冲区的 DMA GEM 地址。

描述

此函数通常从 PLANE 回调函数中调用。

void drm_fb_dma_sync_non_coherent(struct drm_device *drm, struct drm_plane_state *old_state, struct drm_plane_state *state)

将 GEM 对象同步到非一致性后备内存

参数

struct drm_device *drm

DRM 设备

struct drm_plane_state *old_state

旧平面状态

struct drm_plane_state *state

新平面状态

描述

此函数可由使用损坏剪辑并具有非一致性内存支持的 DMA GEM 对象的驱动程序使用。在平面的 .atomic_update 中调用此函数可确保后备内存中的所有数据都已写入 RAM。

int drm_fb_dma_get_scanout_buffer(struct drm_plane *plane, struct drm_scanout_buffer *sb)

在发生 panic 时提供扫描输出缓冲区

参数

struct drm_plane *plane

DRM 主平面

struct drm_scanout_buffer *sb

panic 处理程序的扫描输出缓冲区

返回

0 或负错误代码

描述

通用的 get_scanout_buffer() 实现,适用于使用 drm_fb_dma_helper 的驱动程序。它不会在 panic 上下文中调用 vmap,因此驱动程序应确保主平面已 vmapped,否则不会显示 panic 屏幕。

帧缓冲区 GEM 助手参考

此库为不子类化 drm_framebuffer 并使用 drm_gem_object 作为其后备存储的驱动程序提供助手。

没有其他帧缓冲区验证需求的驱动程序可以简单地使用 drm_gem_fb_create(),并且一切都会自动连接。其他驱动程序可以独立使用所有部件。

struct drm_gem_object *drm_gem_fb_get_obj(struct drm_framebuffer *fb, unsigned int plane)

获取支持帧缓冲区的 GEM 对象

参数

struct drm_framebuffer *fb

帧缓冲区

unsigned int plane

平面索引

描述

除了 drm_frambuffer 已经持有的引用之外,不会获取其他引用。

返回

指向给定帧缓冲区和平面索引的 drm_gem_object 的指针,如果不存在则为 NULL。

void drm_gem_fb_destroy(struct drm_framebuffer *fb)

释放 GEM 支持的帧缓冲区

参数

struct drm_framebuffer *fb

帧缓冲区

描述

释放 GEM 支持的帧缓冲区及其后备缓冲区和结构本身。驱动程序可以将其用作 drm_framebuffer_funcs->destroy 回调。

int drm_gem_fb_create_handle(struct drm_framebuffer *fb, struct drm_file *file, unsigned int *handle)

为 GEM 支持的帧缓冲区创建句柄

参数

struct drm_framebuffer *fb

帧缓冲区

struct drm_file *file

用于注册句柄的 DRM 文件

unsigned int *handle

指向返回创建的句柄的指针

描述

此函数为支持帧缓冲区的 GEM 对象创建一个句柄。驱动程序可以将其用作 drm_framebuffer_funcs->create_handle 回调。GETFB IOCTL 调用此回调。

返回

成功时为 0,失败时为负错误代码。

int drm_gem_fb_init_with_funcs(struct drm_device *dev, struct drm_framebuffer *fb, struct drm_file *file, const struct drm_mode_fb_cmd2 *mode_cmd, const struct drm_framebuffer_funcs *funcs)

用于在驱动程序分配 struct drm_framebuffer 的子类时实现 drm_mode_config_funcs.fb_create 回调的助手函数

参数

struct drm_device *dev

DRM 设备

struct drm_framebuffer *fb

帧缓冲区对象

struct drm_file *file

保存支持帧缓冲区的 GEM 句柄的 DRM 文件

const struct drm_mode_fb_cmd2 *mode_cmd

来自用户空间帧缓冲区创建请求的元数据

const struct drm_framebuffer_funcs *funcs

将用于新帧缓冲区对象的 vtable

描述

此函数可用于为需要自定义帧缓冲区回调的驱动程序设置 drm_framebuffer_funcs。如果您不需要更改 drm_framebuffer_funcs,请使用 drm_gem_fb_create()。该函数执行缓冲区大小验证。缓冲区大小验证适用于一般情况,但用户应注意检查是否适合他们,或者至少不冲突。

返回

零或负错误代码。

struct drm_framebuffer *drm_gem_fb_create_with_funcs(struct drm_device *dev, struct drm_file *file, const struct drm_mode_fb_cmd2 *mode_cmd, const struct drm_framebuffer_funcs *funcs)

用于 drm_mode_config_funcs.fb_create 回调的助手函数

参数

struct drm_device *dev

DRM 设备

struct drm_file *file

保存支持帧缓冲区的 GEM 句柄的 DRM 文件

const struct drm_mode_fb_cmd2 *mode_cmd

来自用户空间帧缓冲区创建请求的元数据

const struct drm_framebuffer_funcs *funcs

将用于新帧缓冲区对象的 vtable

描述

此函数可用于为需要自定义帧缓冲区回调的驱动程序设置 drm_framebuffer_funcs。如果您不需要更改 drm_framebuffer_funcs,请使用 drm_gem_fb_create()。该函数执行缓冲区大小验证。

返回

成功时指向 drm_framebuffer 的指针,失败时指向错误指针。

struct drm_framebuffer *drm_gem_fb_create(struct drm_device *dev, struct drm_file *file, const struct drm_mode_fb_cmd2 *mode_cmd)

用于 drm_mode_config_funcs.fb_create 回调的助手函数

参数

struct drm_device *dev

DRM 设备

struct drm_file *file

保存支持帧缓冲区的 GEM 句柄的 DRM 文件

const struct drm_mode_fb_cmd2 *mode_cmd

来自用户空间帧缓冲区创建请求的元数据

描述

此函数创建一个由 drm_mode_fb_cmd2 描述的新帧缓冲区对象。此描述包括支持帧缓冲区的缓冲区句柄。

如果您的硬件有特殊的对齐或pitch要求,应在调用此函数之前进行检查。该函数会进行缓冲区大小验证。如果需要刷新帧缓冲区,请使用 drm_gem_fb_create_with_dirty()

驱动程序可以将其用作 drm_mode_config_funcs.fb_create 回调。ADDFB2 IOCTL 调用此回调。

返回

成功时指向 drm_framebuffer 的指针,失败时指向错误指针。

struct drm_framebuffer *drm_gem_fb_create_with_dirty(struct drm_device *dev, struct drm_file *file, const struct drm_mode_fb_cmd2 *mode_cmd)

用于 drm_mode_config_funcs.fb_create 回调的助手函数

参数

struct drm_device *dev

DRM 设备

struct drm_file *file

保存支持帧缓冲区的 GEM 句柄的 DRM 文件

const struct drm_mode_fb_cmd2 *mode_cmd

来自用户空间帧缓冲区创建请求的元数据

描述

此函数创建一个由 drm_mode_fb_cmd2 描述的新帧缓冲区对象。此描述包括支持帧缓冲区的缓冲区句柄。drm_atomic_helper_dirtyfb() 用于dirty回调,通过原子机制进行帧缓冲区刷新。如果您不需要dirty回调,请使用 drm_gem_fb_create()。该函数会进行缓冲区大小验证。

驱动程序还应在所有平面上调用 drm_plane_enable_fb_damage_clips(),以允许用户空间也使用具有 ATOMIC IOCTL 的 damage clips。

驱动程序可以将其用作 drm_mode_config_funcs.fb_create 回调。ADDFB2 IOCTL 调用此回调。

返回

成功时指向 drm_framebuffer 的指针,失败时指向错误指针。

int drm_gem_fb_vmap(struct drm_framebuffer *fb, struct iosys_map *map, struct iosys_map *data)

将所有帧缓冲区 BO 映射到内核地址空间

参数

struct drm_framebuffer *fb

帧缓冲区

struct iosys_map *map

返回每个 BO 的映射地址

struct iosys_map *data

返回每个 BO 的数据地址,可以为 NULL

描述

此函数将给定帧缓冲区的所有缓冲区对象映射到内核地址空间,并将它们存储在 struct iosys_map 中。如果其中一个 BO 的映射操作失败,该函数会自动取消映射已建立的映射。

想要访问 BO 存储数据的调用者应传递 data。该参数返回存储在每个 BO 中的数据的地址。如果帧缓冲区的偏移量字段非零,则这与 map 不同。

mapdata 都必须引用至少具有 fb->format->num_planes 元素的数组。

有关取消映射,请参阅 drm_gem_fb_vunmap()

返回

成功时为 0,否则为负 errno 代码。

void drm_gem_fb_vunmap(struct drm_framebuffer *fb, struct iosys_map *map)

从内核地址空间取消映射帧缓冲区 BO

参数

struct drm_framebuffer *fb

帧缓冲区

struct iosys_map *map

映射地址由 drm_gem_fb_vmap() 返回

描述

此函数取消映射给定帧缓冲区的所有缓冲区对象。

有关更多信息,请参阅 drm_gem_fb_vmap()

int drm_gem_fb_begin_cpu_access(struct drm_framebuffer *fb, enum dma_data_direction dir)

准备 GEM 缓冲区对象以进行 CPU 访问

参数

struct drm_framebuffer *fb

帧缓冲区

enum dma_data_direction dir

访问模式

描述

准备帧缓冲区的 GEM 缓冲区对象以进行 CPU 访问。在内核中访问 BO 数据之前,必须调用此函数。对于导入的 BO,该函数调用 dma_buf_begin_cpu_access()

有关发出 CPU 访问结束信号,请参阅 drm_gem_fb_end_cpu_access()

返回

成功时为 0,否则为负 errno 代码。

void drm_gem_fb_end_cpu_access(struct drm_framebuffer *fb, enum dma_data_direction dir)

发出 CPU 访问 GEM 缓冲区对象结束的信号

参数

struct drm_framebuffer *fb

帧缓冲区

enum dma_data_direction dir

访问模式

描述

发出 CPU 访问给定帧缓冲区的 GEM 缓冲区对象结束的信号。此函数必须与对 drm_gem_fb_begin_cpu_access() 的相应调用配对。对于导入的 BO,该函数调用 dma_buf_end_cpu_access()

另请参阅 drm_gem_fb_begin_cpu_access()

int drm_gem_fb_afbc_init(struct drm_device *dev, const struct drm_mode_fb_cmd2 *mode_cmd, struct drm_afbc_framebuffer *afbc_fb)

用于驱动程序使用 afbc 填充和验证所有 afbc 特定 struct drm_afbc_framebuffer 成员的辅助函数

参数

struct drm_device *dev

DRM 设备

const struct drm_mode_fb_cmd2 *mode_cmd

来自用户空间帧缓冲区创建请求的元数据

struct drm_afbc_framebuffer *afbc_fb

afbc 帧缓冲区

描述

支持 afbc 的驱动程序可以使用此函数来完成 struct drm_afbc_framebuffer 的准备工作。必须在分配上述结构并调用 drm_gem_fb_init_with_funcs() 之后调用它。如果调用不成功,则调用方负责放入 afbc_fb->base.obj 对象。

返回

成功时为零,失败时为负错误值。

桥接器

概述

struct drm_bridge 表示挂接到编码器的设备。当常规的 drm_encoder 实体不足以表示整个编码器链时,这些会很有用。

桥接器始终一次连接到单个 drm_encoder,但可以直接连接到它,也可以通过桥接器链连接。

[ CRTC ---> ] Encoder ---> Bridge A ---> Bridge B

这里,编码器的输出馈送到桥接器 A,然后进一步馈送到桥接器 B。桥接器链可以任意长,并且应该是完全线性的:不支持将多个桥接器链接到桥接器的输出,或者将相同的桥接器链接到不同桥接器的输出。

drm_bridge,像 drm_panel 一样,不是 drm_mode_object 实体,如 planes、CRTC、编码器或连接器,因此对用户空间不可见。它们只是提供额外的钩子以在编码器链的末尾获得所需的输出。

显示驱动程序集成

显示驱动程序负责将编码器与链中的第一个桥接器链接。这是通过使用 devm_drm_of_get_bridge() 获取适当的桥接器来完成的。获取后,应通过调用 drm_bridge_attach() 将桥接器附加到编码器。

桥接器负责将自身与链中的下一个桥接器链接(如果有)。这与编码器的方式相同,在 drm_bridge_funcs.attach 操作中调用 drm_bridge_attach()

创建这些链接后,桥接器可以与编码器函数一起参与执行模式验证和修复(通过 drm_bridge_chain_mode_valid()drm_atomic_bridge_chain_check())、模式设置(通过 drm_bridge_chain_mode_set())、启用(通过 drm_atomic_bridge_chain_pre_enable()drm_atomic_bridge_chain_enable())和禁用(通过 drm_atomic_bridge_chain_disable()drm_atomic_bridge_chain_post_disable())。这些函数按顺序调用 drm_bridge_funcs 中为链中所有桥接器提供的相应操作。

对于使用原子辅助程序的显示驱动程序 drm_atomic_helper_check_modeset()drm_atomic_helper_commit_modeset_enables()drm_atomic_helper_commit_modeset_disables()(直接在手动提交检查和提交尾部处理程序中,或者通过更高级别的 drm_atomic_helper_check()drm_atomic_helper_commit_tail()drm_atomic_helper_commit_tail_rpm() 辅助程序),这是透明完成的,不需要驱动程序的干预。对于其他驱动程序,应手动调用相关的 DRM 桥接器链函数。

桥接器还参与实现桥接器链末端的 drm_connector。显示驱动程序可以使用 drm_bridge_connector_init() 辅助程序创建 drm_connector,或者基于桥接器公开的与连接器相关的操作手动实现它(有关更多详细信息,请参见桥接器操作的概述文档)。

MIPI-DSI 桥接器的特殊注意事项

桥接器与参与探测上游驱动程序和桥接器驱动程序的其他框架之间的交互可能具有挑战性。实际上,需要考虑多种情况

  • 上游驱动程序不使用组件框架,也不是 MIPI-DSI 主机。在这种情况下,桥接器驱动程序将在某个时刻进行探测,并且只要桥接器驱动程序尚未探测,上游驱动程序就应通过返回 EPROBE_DEFER 来尝试再次探测。

  • 上游驱动程序不使用组件框架,但它是 MIPI-DSI 主机。桥接器设备使用 MIPI-DCS 命令进行控制。在这种情况下,桥接器设备是显示设备的子设备,当它进行探测时,可以确保显示设备(和 MIPI-DSI 主机)存在。上游驱动程序可以确保桥接器驱动程序连接在 mipi_dsi_host_ops.attachmipi_dsi_host_ops.detach 操作之间。因此,它必须在其探测函数中运行 mipi_dsi_host_register(),然后在 mipi_dsi_host_ops.attach 钩子中运行 drm_bridge_attach()

  • 上游驱动程序使用组件框架,并且是 MIPI-DSI 主机。桥接器设备使用 MIPI-DCS 命令进行控制。这与上述情况相同,并且可以在其探测或绑定钩子中运行 mipi_dsi_host_register()。

  • 上游驱动程序使用组件框架,并且是 MIPI-DSI 主机。桥接器设备使用单独的总线(例如 I2C)进行控制。在这种情况下,桥接器驱动程序和上游驱动程序的探测之间没有关联,因此必须注意避免无休止的 EPROBE_DEFER 循环,每个驱动程序都等待另一个驱动程序进行探测。

涵盖最后一项(以及 MIPI-DSI 主机驱动程序情况下的所有其他项)的理想模式是将操作拆分为以下形式

  • MIPI-DSI 主机驱动程序必须在其探测钩子中运行 mipi_dsi_host_register()。它将确保 MIPI-DSI 主机保持存在,并且可以调用驱动程序的绑定。

  • 在其探测钩子中,桥接器驱动程序必须尝试查找其 MIPI-DSI 主机,注册为 MIPI-DSI 设备,并将 MIPI-DSI 设备附加到其主机。桥接器驱动程序现在可以工作。

  • 在其 struct mipi_dsi_host_ops.attach 钩子中,MIPI-DSI 主机现在可以添加其组件。现在将调用其绑定钩子,并且由于桥接器驱动程序已附加和注册,因此我们现在可以查找并附加它。

此时,我们现在可以确定上游驱动程序和桥接器驱动程序都可以正常工作,并且在探测时不会发生类似死锁的情况。

桥接器操作

桥接器驱动程序通过 drm_bridge_funcs 结构公开操作。DRM 内部程序(原子和 CRTC 辅助程序)使用 drm_bridge.c 中定义的辅助程序来调用桥接器操作。这些操作分为三大类,以支持桥接器使用的不同部分。

  • 与编码器相关的操作支持控制链中的桥接器,并且大致相当于 drm_encoder_helper_funcs 操作。传统的 CRTC 和原子模式设置辅助程序使用它们来执行模式验证、修复和设置,并自动启用和禁用桥接器。

    启用和禁用操作分为 drm_bridge_funcs.pre_enabledrm_bridge_funcs.enabledrm_bridge_funcs.disabledrm_bridge_funcs.post_disable,以提供更精细的控制。

    桥接器驱动程序可以实现这些操作的旧版本,也可以实现原子版本(带有 atomic_ 前缀),在这种情况下,它们还应实现原子状态簿记操作(drm_bridge_funcs.atomic_duplicate_statedrm_bridge_funcs.atomic_destroy_statedrm_bridge_funcs.reset)。不支持混合使用原子和非原子版本的操作。

  • 总线格式协商操作 drm_bridge_funcs.atomic_get_output_bus_fmtsdrm_bridge_funcs.atomic_get_input_bus_fmts 允许桥接器驱动程序在支持多种格式时协商链中桥接器之间传输的格式。对于显示驱动程序,格式协商由原子模式设置辅助程序透明地执行。仅存在这些操作的原子版本,因此需要实现它们的桥接器驱动程序还应实现与编码器相关的操作的原子版本。传统的 CRTC 辅助程序不支持此功能。

  • 与连接器相关的操作支持基于桥接器链实现 drm_connector。DRM 桥接器传统上为旨在在链末端使用的桥接器创建 drm_connector。这给桥接器驱动程序带来了额外的负担,尤其是对于可能在链中间或末端使用的桥接器。此外,它要求 drm_connector 的所有操作都由单个桥接器处理,这并不总是与硬件架构匹配。

    为了简化桥接器驱动程序并使连接器实现更加灵活,一种新模型允许桥接器无条件地跳过创建 drm_connector,而是公开 drm_bridge_funcs 操作以支持外部实现的 drm_connector。这些操作是 drm_bridge_funcs.detectdrm_bridge_funcs.get_modesdrm_bridge_funcs.get_ediddrm_bridge_funcs.hpd_notifydrm_bridge_funcs.hpd_enabledrm_bridge_funcs.hpd_disable。实现后,显示驱动程序应为每个桥接器链创建一个 drm_connector 实例,并基于桥接器连接器操作实现这些连接器实例。

    桥接器驱动程序应为桥接器硬件支持的所有功能实现与连接器相关的操作。例如,如果桥接器支持读取 EDID,则应实现 drm_bridge_funcs.get_edid。然而,这并不意味着 DDC 线路已连接到特定平台上的桥接器,因为它们也可能连接到 SoC 的 I2C 控制器。在运行平台上对与连接器相关的操作的支持通过 drm_bridge.ops 标志报告。桥接器驱动程序应检测它们可以在平台上支持的操作(通常此信息由 ACPI 或 DT 提供),并为所有支持的操作设置 drm_bridge.ops 标志。仅当实现相应的 drm_bridge_funcs 操作时,才应设置标志,但实现的操作并不一定意味着将设置相应的标志。显示驱动程序应使用 drm_bridge.ops 标志来决定将连接器操作委托给哪个桥接器。此机制允许在桥接器驱动程序中提供单个静态 const drm_bridge_funcs 实例,从而通过将函数指针存储在只读存储器中来提高安全性。

    为了简化过渡,桥接器驱动程序可以通过使连接器创建成为可选的并实现连接相关的桥接器操作来支持旧模型和新模型。然后,通过 drm_bridge_attach() 函数的 flags 参数控制连接器创建。支持新模型并自行创建连接器的显示驱动程序应设置 DRM_BRIDGE_ATTACH_NO_CONNECTOR 标志,然后桥接器驱动程序应跳过连接器创建。对于链中的中间桥接器,应将该标志传递给下游桥接器的 drm_bridge_attach() 调用。仅实现新模型的桥接器驱动程序应在其 drm_bridge_funcs.attach 处理程序中在未设置 DRM_BRIDGE_ATTACH_NO_CONNECTOR 标志时返回错误。新的显示驱动程序应使用新模型,并在需要时转换它们使用的桥接器驱动程序,以便逐步过渡到新模型。

桥接连接器助手

DRM 桥接连接器助手对象提供了一个 DRM 连接器实现,它封装了一个 struct drm_bridge 链。连接器操作完全基于链中桥接器的操作实现,不需要显示控制器驱动程序在运行时进行任何干预。

为了使用助手,显示控制器驱动程序通过调用 drm_bridge_connector_init() 来创建一个桥接连接器。这会将新创建的连接器与传递给该函数的桥接器链相关联,并将其注册到 DRM 设备。此时,连接器将变得完全可用,无需进一步操作。

DRM 桥接连接器操作基于链中桥接器提供的操作来实现。每个连接器操作都委托给最靠近连接器的桥接器(在链的末尾),该桥接器提供相关功能。

为了使用此助手,链中的所有桥接器都应报告桥接器操作标志(drm_bridge->ops)和桥接器输出类型(drm_bridge->type),以及 DRM_BRIDGE_ATTACH_NO_CONNECTOR 连接标志(任何桥接器都不应直接创建 DRM 连接器)。

桥接器助手参考

enum drm_bridge_attach_flags

用于 drm_bridge_funcs.attach 的标志

常量

DRM_BRIDGE_ATTACH_NO_CONNECTOR

当设置此标志时,桥接器不应创建 drm_connector。

struct drm_bridge_funcs

drm_bridge 控制函数

定义:

struct drm_bridge_funcs {
    int (*attach)(struct drm_bridge *bridge, struct drm_encoder *encoder, enum drm_bridge_attach_flags flags);
    void (*detach)(struct drm_bridge *bridge);
    enum drm_mode_status (*mode_valid)(struct drm_bridge *bridge,const struct drm_display_info *info, const struct drm_display_mode *mode);
    bool (*mode_fixup)(struct drm_bridge *bridge,const struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode);
    void (*disable)(struct drm_bridge *bridge);
    void (*post_disable)(struct drm_bridge *bridge);
    void (*mode_set)(struct drm_bridge *bridge,const struct drm_display_mode *mode, const struct drm_display_mode *adjusted_mode);
    void (*pre_enable)(struct drm_bridge *bridge);
    void (*enable)(struct drm_bridge *bridge);
    void (*atomic_pre_enable)(struct drm_bridge *bridge, struct drm_atomic_state *state);
    void (*atomic_enable)(struct drm_bridge *bridge, struct drm_atomic_state *state);
    void (*atomic_disable)(struct drm_bridge *bridge, struct drm_atomic_state *state);
    void (*atomic_post_disable)(struct drm_bridge *bridge, struct drm_atomic_state *state);
    struct drm_bridge_state *(*atomic_duplicate_state)(struct drm_bridge *bridge);
    void (*atomic_destroy_state)(struct drm_bridge *bridge, struct drm_bridge_state *state);
    u32 *(*atomic_get_output_bus_fmts)(struct drm_bridge *bridge,struct drm_bridge_state *bridge_state,struct drm_crtc_state *crtc_state,struct drm_connector_state *conn_state, unsigned int *num_output_fmts);
    u32 *(*atomic_get_input_bus_fmts)(struct drm_bridge *bridge,struct drm_bridge_state *bridge_state,struct drm_crtc_state *crtc_state,struct drm_connector_state *conn_state,u32 output_fmt, unsigned int *num_input_fmts);
    int (*atomic_check)(struct drm_bridge *bridge,struct drm_bridge_state *bridge_state,struct drm_crtc_state *crtc_state, struct drm_connector_state *conn_state);
    struct drm_bridge_state *(*atomic_reset)(struct drm_bridge *bridge);
    enum drm_connector_status (*detect)(struct drm_bridge *bridge);
    int (*get_modes)(struct drm_bridge *bridge, struct drm_connector *connector);
    const struct drm_edid *(*edid_read)(struct drm_bridge *bridge, struct drm_connector *connector);
    void (*hpd_notify)(struct drm_bridge *bridge, enum drm_connector_status status);
    void (*hpd_enable)(struct drm_bridge *bridge);
    void (*hpd_disable)(struct drm_bridge *bridge);
    enum drm_mode_status(*hdmi_tmds_char_rate_valid)(const struct drm_bridge *bridge,const struct drm_display_mode *mode, unsigned long long tmds_rate);
    int (*hdmi_clear_infoframe)(struct drm_bridge *bridge, enum hdmi_infoframe_type type);
    int (*hdmi_write_infoframe)(struct drm_bridge *bridge,enum hdmi_infoframe_type type, const u8 *buffer, size_t len);
    int (*hdmi_audio_startup)(struct drm_connector *connector, struct drm_bridge *bridge);
    int (*hdmi_audio_prepare)(struct drm_connector *connector,struct drm_bridge *bridge,struct hdmi_codec_daifmt *fmt, struct hdmi_codec_params *hparms);
    void (*hdmi_audio_shutdown)(struct drm_connector *connector, struct drm_bridge *bridge);
    int (*hdmi_audio_mute_stream)(struct drm_connector *connector,struct drm_bridge *bridge, bool enable, int direction);
    int (*dp_audio_startup)(struct drm_connector *connector, struct drm_bridge *bridge);
    int (*dp_audio_prepare)(struct drm_connector *connector,struct drm_bridge *bridge,struct hdmi_codec_daifmt *fmt, struct hdmi_codec_params *hparms);
    void (*dp_audio_shutdown)(struct drm_connector *connector, struct drm_bridge *bridge);
    int (*dp_audio_mute_stream)(struct drm_connector *connector,struct drm_bridge *bridge, bool enable, int direction);
    void (*debugfs_init)(struct drm_bridge *bridge, struct dentry *root);
};

成员

attach

每当我们的桥接器连接到 drm_encoder 时,都会调用此回调。flags 参数调整连接操作的行为(请参阅 DRM_BRIDGE_ATTACH_*)。

attach 回调是可选的。

返回值

成功时返回 0,失败时返回错误代码。

detach

每当我们的桥接器从 drm_encoder 断开连接时,都会调用此回调。

detach 回调是可选的。

mode_valid

此回调用于检查特定模式在此桥接器中是否有效。如果桥接器对其可以显示的模式有某种限制,则应实现此回调。例如,给定的桥接器可能负责设置时钟值。如果时钟无法生成可用模式的所有值,则可以使用此回调来限制模式数量,使其仅为可以显示的模式。

此挂钩由探测辅助函数用于筛选 drm_helper_probe_single_connector_modes() 中的模式列表,并且原子辅助函数使用它来验证用户空间在 drm_atomic_helper_check_modeset() 中提供的模式。

mode_valid 回调是可选的。

注意

由于此函数是从原子提交的检查阶段以及探测路径中的模式验证调用的,因此不允许查看除传入模式之外的任何内容,并根据配置不变的硬件约束对其进行验证。任何进一步的限制,具体取决于配置,只能在 mode_fixup 中进行检查。

返回值

drm_mode_status 枚举

mode_fixup

此回调用于验证和调整模式。参数模式是要馈送到显示链中下一个元素的显示模式,可以是最终的 drm_connector 或下一个 drm_bridge。参数 adjusted_mode 是桥接器需要的输入模式。它可以通过此回调修改,不需要与模式匹配。另请参阅 drm_crtc_state.adjusted_mode 了解更多详细信息。

这是唯一允许桥接器拒绝模式设置的挂钩。如果此函数通过,则所有其他回调对于此配置都必须成功。

mode_fixup 回调是可选的。当实现 drm_bridge_funcs.mode_fixup() 时,不会调用 drm_bridge_funcs.atomic_check(),因此只能提供其中一个。

注意

此函数在原子模式设置的检查阶段调用,该阶段可能会因任何原因中止(包括在用户空间要求仅检查配置是否可能的情况下)。驱动程序绝不能接触任何持久状态(硬件或软件)或数据结构,除了传入的 state 参数。

另请注意,用户空间可以请求其自己的自定义模式,核心和助手都不会将模式过滤到 GETCONNECTOR IOCTL 报告并存储在 drm_connector.modes 中的探测模式列表中。为了确保模式被一致地过滤,请将任何桥接器约束和限制检查放入 mode_valid 中。

返回值

如果可以接受的配置是可能的,则为 True,如果应拒绝模式设置操作,则为 False。

disable

此回调应禁用桥接器。它在显示管道中的前一个元素被禁用之前立即调用。如果前一个元素是桥接器,这意味着它在该桥接器的 disable vfunc 之前被调用。如果前一个元素是 drm_encoder,则它在 drm_encoder_helper_funcs.disabledrm_encoder_helper_funcs.preparedrm_encoder_helper_funcs.dpms 挂钩之前立即调用。

桥接器可以假定在调用此回调时,馈送它的显示管道(即时钟和定时信号)仍在运行。

disable 回调是可选的。

注意

这已弃用,请勿使用!新驱动程序应使用 drm_bridge_funcs.atomic_disable

post_disable

此回调应禁用桥接器。它在显示管道中的前一个元素被禁用之后立即调用。如果前一个元素是桥接器,这意味着它在该桥接器的 post_disable 函数之后被调用。如果前一个元素是 drm_encoder,则它在编码器的 drm_encoder_helper_funcs.disabledrm_encoder_helper_funcs.preparedrm_encoder_helper_funcs.dpms 挂钩之后立即调用。

桥接器必须假定在调用此回调时,馈送它的显示管道(即时钟和定时信号)已不再运行。

post_disable 回调是可选的。

注意

这已弃用,请勿使用!新驱动程序应使用 drm_bridge_funcs.atomic_post_disable

mode_set

此回调应在桥接器上设置给定模式。它在前一个显示管道元素的 mode_set 回调已经被调用之后调用。如果桥接器是第一个元素,那么这将是 drm_encoder_helper_funcs.mode_set。当调用此函数时,显示管道(即时钟和定时信号)已关闭。

adjusted_mode 参数是 CRTC 为链中的第一个桥接器输出的模式。它可能与 mode 参数不同,mode 参数包含桥接器链末尾连接器的期望模式,例如,当链中的第一个桥接器执行缩放时。调整后的模式对于链中的第一个桥接器最有用,对于其他桥接器可能无关紧要。

对于原子驱动程序,adjusted_mode 是存储在 drm_crtc_state.adjusted_mode 中的模式。

注意

这已弃用,请勿使用!新驱动程序应在其 drm_bridge_funcs.atomic_enable 操作中设置模式。

pre_enable

此回调应启用桥接器。它在显示管道中的前一个元素被启用之前立即调用。如果前一个元素是桥接器,这意味着它在该桥接器的 pre_enable 函数之前被调用。如果前一个元素是 drm_encoder,则它在编码器的 drm_encoder_helper_funcs.enabledrm_encoder_helper_funcs.commitdrm_encoder_helper_funcs.dpms 挂钩之前立即调用。

当调用此回调时,馈送此桥接器的显示管道(即时钟和定时信号)尚未运行。当调用此回调时,桥接器不得启用馈送链中下一个桥接器的显示链接(如果存在)。

pre_enable 回调是可选的。

注意

这已弃用,请勿使用!新驱动程序应使用 drm_bridge_funcs.atomic_pre_enable

enable

此回调应启用桥接器。它在显示管道中的前一个元素被启用之后立即调用。如果前一个元素是桥接器,这意味着它在该桥接器的 enable 函数之后被调用。如果前一个元素是 drm_encoder,则它在编码器的 drm_encoder_helper_funcs.enabledrm_encoder_helper_funcs.commitdrm_encoder_helper_funcs.dpms 挂钩之后立即调用。

桥接器可以假定在调用此回调时,馈送它的显示管道(即时钟和定时信号)正在运行。此回调必须启用馈送链中下一个桥接器的显示链接(如果存在)。

enable 回调是可选的。

注意

这已弃用,请勿使用!新驱动程序应使用 drm_bridge_funcs.atomic_enable

atomic_pre_enable

此回调应启用桥接器。它在显示管道中的前一个元素被启用之前立即调用。如果前一个元素是桥接器,这意味着它在该桥接器的 atomic_pre_enablepre_enable 函数之前被调用。如果前一个元素是 drm_encoder,则它在编码器的 drm_encoder_helper_funcs.atomic_enable 挂钩之前立即调用。

当调用此回调时,馈送此桥接器的显示管道(即时钟和定时信号)尚未运行。当调用此回调时,桥接器不得启用馈送链中下一个桥接器的显示链接(如果存在)。

atomic_pre_enable 回调是可选的。

atomic_enable

此回调应启用桥接器。它在显示管道中的前一个元素被启用之后立即调用。如果前一个元素是桥接器,这意味着它在该桥接器的 atomic_enableenable 函数之后被调用。如果前一个元素是 drm_encoder,则它在编码器的 drm_encoder_helper_funcs.atomic_enable 挂钩之后立即调用。

桥接器可以假定在调用此回调时,馈送它的显示管道(即时钟和定时信号)正在运行。此回调必须启用馈送链中下一个桥接器的显示链接(如果存在)。

atomic_enable 回调是可选的。

atomic_disable

此回调应禁用桥接器。它在显示管道中的前一个元素被禁用之前立即调用。如果前一个元素是桥接器,这意味着它在该桥接器的 atomic_disabledisable vfunc 之前被调用。如果前一个元素是 drm_encoder,则它在 drm_encoder_helper_funcs.atomic_disable 挂钩之前立即调用。

桥接器可以假定在调用此回调时,馈送它的显示管道(即时钟和定时信号)仍在运行。

atomic_disable 回调是可选的。

atomic_post_disable

此回调应禁用桥接器。它在显示管道中的前一个元素被禁用之后立即调用。如果前一个元素是桥接器,这意味着它在该桥接器的 atomic_post_disablepost_disable 函数之后被调用。如果前一个元素是 drm_encoder,则它在编码器的 drm_encoder_helper_funcs.atomic_disable 挂钩之后立即调用。

桥接器必须假定在调用此回调时,馈送它的显示管道(即时钟和定时信号)已不再运行。

atomic_post_disable 回调是可选的。

atomic_duplicate_state

复制当前桥接器状态对象(保证为非 NULL)。

如果桥接器实现了任何原子挂钩,则 atomic_duplicate_state 挂钩是必需的,否则应将其保留为未分配。对于未子类化 drm_bridge_state 的桥接器,应使用 drm_atomic_helper_bridge_duplicate_state() 帮助程序函数来实现此挂钩。

返回值:如果分配失败,则返回一个有效的 drm_bridge_state 对象或 NULL。

atomic_destroy_state

销毁先前由 drm_bridge_funcs.atomic_duplicate_state() 分配的桥接器状态对象。

如果桥接器实现了任何原子挂钩,则 atomic_destroy_state 挂钩是必需的,否则应将其保留为未分配。对于未子类化 drm_bridge_state 的桥接器,应使用 drm_atomic_helper_bridge_destroy_state() 帮助程序函数来实现此挂钩。

atomic_get_output_bus_fmts

返回桥接器输出端支持的总线格式。返回的数组必须使用 kmalloc() 分配,并将由调用方释放。如果分配失败,则应返回 NULL。num_output_fmts 必须设置为返回的数组大小。返回的数组中列出的格式应按首选顺序(核心将尝试所有格式,直到找到有效的格式)列出。

此方法仅在作为 drm_atomic_bridge_chain_select_bus_fmts`() 中发生的总线格式协商过程的一部分的桥接器链的最后一个元素上调用。此方法是可选的。如果未实现,则核心将回退到 :c:type:`drm_connector.display_info。如果 drm_connector.display_info.num_bus_formats > 0,则为 bus_formats[0],否则为 MEDIA_BUS_FMT_FIXED。

atomic_get_input_bus_fmts

返回特定输出总线格式的桥接器输入端支持的总线格式。

返回的数组必须使用 kmalloc() 分配,并将由调用方释放。如果分配失败,则应返回 NULL。num_input_fmts 必须设置为返回的数组大小。返回的数组中列出的格式应按首选顺序(核心将尝试所有格式,直到找到有效的格式)列出。当不支持格式时,应返回 NULL,并且 num_input_fmts 应设置为 0。

此方法作为 drm_atomic_bridge_chain_select_bus_fmts() 中发生的总线格式协商过程的一部分在桥接器链的所有元素上调用。此方法是可选的。如果未实现,则核心将绕过此桥接器元素的总线格式协商,而不会失败,并且链中前一个元素将传递 MEDIA_BUS_FMT_FIXED 作为其输出总线格式。

需要支持链接到不支持总线格式协商的桥接器的桥接器驱动程序应通过选择一个合理的默认值或从其他地方(固件属性、drm_display_modedrm_display_info、...)提取此信息,来适当地处理 output_fmt == MEDIA_BUS_FMT_FIXED 情况。

注意:即使第一个桥接器上的输入格式选择对协商过程没有影响(一旦我们到达链的第一个元素,总线格式协商就会停止),驱动程序也应返回准确的输入格式,因为输入格式可用于适当地配置 CRTC 输出。

atomic_check

此方法负责检查桥接器状态的正确性。它还可以检查链中周围组件的状态,以确保整个管道可以正常工作。

drm_bridge_funcs.atomic_check() 挂钩以相反的顺序(从最后一个桥接器到第一个桥接器)调用。

此方法是可选的。当实现 drm_bridge_funcs.atomic_check() 时,不会调用 drm_bridge_funcs.mode_fixup(),因此只能提供其中一个。

如果驱动程序需要调整 drm_bridge_state.input_bus_cfg.flags 或 drm_bridge_state.output_bus_cfg.flags,则应在此函数中进行。默认情况下,drm_bridge_state.output_bus_cfg.flags 字段设置为下一个桥接器 drm_bridge_state.input_bus_cfg.flags 值,如果桥接器是链中的最后一个元素,则设置为 drm_connector.display_info.bus_flags。

返回值:如果检查通过,则返回零;否则,返回一个负错误代码。

atomic_reset

将桥接器重置为预定义状态(或检索其当前状态),并返回一个与此状态匹配的 drm_bridge_state 对象。此函数在连接时调用。

如果桥接器实现了任何原子挂钩,则 atomic_reset 挂钩是必需的,否则应将其保留为未分配。对于未子类化 drm_bridge_state 的桥接器,应使用 drm_atomic_helper_bridge_reset() 帮助程序函数来实现此挂钩。

请注意,atomic_reset() 语义与在其他组件(连接器、平面、...)上找到的 reset() 语义不完全匹配。

  1. 重置操作在连接桥接器时发生,而不是在调用 drm_mode_config_reset() 时发生

  2. 它仅用于已转换为 ATOMIC API 的桥接器

返回值:如果成功,则返回一个有效的 drm_bridge_state 对象;否则,返回一个 ERR_PTR(),说明失败的原因。

detect

检查是否有任何东西连接到桥接器输出。

此回调是可选的,如果未实现,则桥接器将被视为始终有组件连接到其输出。实现此回调的桥接器应在其 drm_bridge->ops 中设置 DRM_BRIDGE_OP_DETECT 标志。

返回值

drm_connector_status 指示桥接器输出状态。

get_modes

将当前对接收器有效的所有模式使用 drm_mode_probed_add() 填充到 drm_connector 中。

get_modes 回调主要用于支持不可探测的显示器,例如许多固定面板。支持读取 EDID 的桥接器应保留 get_modes 未实现,而是实现 drm_bridge_funcs->edid_read 回调。

此回调是可选的。实现此回调的桥接器应在其 drm_bridge->ops 中设置 DRM_BRIDGE_OP_MODES 标志。

连接器参数应仅用于填充模式,不应由桥接器驱动程序在内部存储以供将来使用。

返回值

通过调用 drm_mode_probed_add() 添加的模式数量。

edid_read

读取连接显示的 EDID 数据。

edid_read 回调是报告连接到桥接器输出的显示器的模式信息的首选方式。支持读取 EDID 的桥接器应实现此回调并保留 get_modes 回调未实现。

此操作的调用方应首先验证输出连接状态,并避免从断开连接的输出中读取 EDID。

此回调是可选的。实现此回调的桥接器应在其 drm_bridge->ops 中设置 DRM_BRIDGE_OP_EDID 标志。

连接器参数应仅用于 EDID 检索,不应由桥接器驱动程序在内部存储以供将来使用。

返回值

如果成功,则返回一个使用 drm_edid_alloc() 新分配的或从 drm_edid_read() 系列函数返回的 edid 结构,否则返回 NULL。调用方负责使用 drm_edid_free() 释放返回的 edid 结构。

hpd_notify

通知桥接器热插拔检测。

此回调是可选的,可以由需要通知显示器连接或断开连接的桥接器来实现,以实现内部原因。一个用例是重置 HDMI 桥接器的 CEC 控制器的内部状态。

hpd_enable

启用热插拔检测。从现在开始,每当检测到输出连接状态发生更改时,桥接器都应调用 drm_bridge_hpd_notify(),直到使用 hpd_disable 禁用热插拔检测。

此回调是可选的,仅应由支持在没有轮询的情况下进行热插拔通知的桥接器来实现。实现此回调的桥接器还应实现 hpd_disable 回调,并在其 drm_bridge->ops 中设置 DRM_BRIDGE_OP_HPD 标志。

hpd_disable

禁用热插拔检测。一旦此函数返回,当输出连接状态发生更改时,桥接器不应调用 drm_bridge_hpd_notify()

此回调是可选的,仅应由支持热插拔通知而无需轮询的桥接器实现。实现此回调的桥接器还应实现 hpd_enable 回调,并在其 drm_bridge->ops 中设置 DRM_BRIDGE_OP_HPD 标志。

hdmi_tmds_char_rate_valid

检查驱动程序是否支持特定的 TMDS 字符速率。

此回调是可选的,仅应由参与 HDMI 连接器实现的桥接器实现。实现此回调的桥接器应在其 drm_bridge->ops 中设置 DRM_BRIDGE_OP_HDMI 标志。

返回值

或者是 drm_mode_status.MODE_OK 或者是 enum drm_mode_status 中的故障原因之一。

hdmi_clear_infoframe

此回调在提交期间清除硬件中的信息帧。它将被多次调用,每次针对一个禁用的信息帧类型。

此回调是可选的,但必须由在其 drm_bridge->ops 中设置 DRM_BRIDGE_OP_HDMI 标志的桥接器实现。

hdmi_write_infoframe

将信息帧编程到硬件中。它将被多次调用,每次针对一个更新的信息帧类型。

此回调是可选的,但必须由在其 drm_bridge->ops 中设置 DRM_BRIDGE_OP_HDMI 标志的桥接器实现。

hdmi_audio_startup

当 ASoC 启动音频流设置时调用。

此回调是可选的,可以由在其 drm_bridge->ops 中设置 DRM_BRIDGE_OP_HDMI_AUDIO 标志的桥接器实现。

返回值:成功时返回 0,否则返回负错误代码

hdmi_audio_prepare

为音频流配置 HDMI 编码器。每次设置可以多次调用。

此回调是可选的,但必须由在其 drm_bridge->ops 中设置 DRM_BRIDGE_OP_HDMI_AUDIO 标志的桥接器实现。

返回值:成功时返回 0,否则返回负错误代码

hdmi_audio_shutdown

关闭音频流。

此回调是可选的,但必须由在其 drm_bridge->ops 中设置 DRM_BRIDGE_OP_HDMI_AUDIO 标志的桥接器实现。

返回值:成功时返回 0,否则返回负错误代码

hdmi_audio_mute_stream

静音/取消静音 HDMI 音频流。

此回调是可选的,可以由在其 drm_bridge->ops 中设置 DRM_BRIDGE_OP_HDMI_AUDIO 标志的桥接器实现。

返回值:成功时返回 0,否则返回负错误代码

dp_audio_startup

当 ASoC 启动 DisplayPort 音频流设置时调用。

此回调是可选的,可以由在其 drm_bridge->ops 中设置 DRM_BRIDGE_OP_DP_AUDIO 标志的桥接器实现。

返回值:成功时返回 0,否则返回负错误代码

dp_audio_prepare

配置 DisplayPort 音频流。每次设置可以多次调用。

此回调是可选的,但必须由在其 drm_bridge->ops 中设置 DRM_BRIDGE_OP_DP_AUDIO 标志的桥接器实现。

返回值:成功时返回 0,否则返回负错误代码

dp_audio_shutdown

关闭 DisplayPort 音频流。

此回调是可选的,但必须由在其 drm_bridge->ops 中设置 DRM_BRIDGE_OP_DP_AUDIO 标志的桥接器实现。

返回值:成功时返回 0,否则返回负错误代码

dp_audio_mute_stream

静音/取消静音 DisplayPort 音频流。

此回调是可选的,可以由在其 drm_bridge->ops 中设置 DRM_BRIDGE_OP_DP_AUDIO 标志的桥接器实现。

返回值:成功时返回 0,否则返回负错误代码

debugfs_init

允许桥接器创建特定于桥接器的 debugfs 文件。

struct drm_bridge_timings

桥接器的时序信息

定义:

struct drm_bridge_timings {
    u32 input_bus_flags;
    u32 setup_time_ps;
    u32 hold_time_ps;
    bool dual_link;
};

成员

input_bus_flags

告知此桥接器对总线上的像素数据有哪些其他设置要求(如像素信号极性)。另请参阅 drm_display_info->bus_flags

setup_time_ps

定义时钟沿之前输入数据线必须稳定的时间(皮秒)。

hold_time_ps

定义桥接器在时钟沿之后对输入信号进行采样所需的时间(皮秒)。

dual_link

如果总线以双链路模式运行,则为 True。确切含义取决于总线类型。对于 LVDS 总线,这表示偶数和奇数像素在单独的链路上接收。

enum drm_bridge_ops

桥接器支持的操作的位掩码

常量

DRM_BRIDGE_OP_DETECT

桥接器可以检测连接到其输出的显示器。设置此标志的桥接器应实现 drm_bridge_funcs->detect 回调。

DRM_BRIDGE_OP_EDID

桥接器可以检索连接到其输出的显示器的 EDID。设置此标志的桥接器应实现 drm_bridge_funcs->edid_read 回调。

DRM_BRIDGE_OP_HPD

桥接器可以检测热插拔和热插拔,而无需轮询。如果桥接器支持动态启用和禁用热插拔检测,则设置此标志的桥接器应实现 drm_bridge_funcs->hpd_enabledrm_bridge_funcs->hpd_disable 回调。

DRM_BRIDGE_OP_MODES

桥接器可以检索其输出端显示器支持的模式。这不包括读取 EDID,EDID 由 DRM_BRIDGE_OP_EDID 单独覆盖。设置此标志的桥接器应实现 drm_bridge_funcs->get_modes 回调。

DRM_BRIDGE_OP_HDMI

桥接器提供 HDMI 连接器操作,包括信息帧支持。设置此标志的桥接器必须实现 drm_bridge_funcs->write_infoframe 回调。

注意:目前,链中最多只能有一个桥接器设置此位。这是为了简化连接器驱动程序中的相应粘合代码。

DRM_BRIDGE_OP_HDMI_AUDIO

桥接器提供 HDMI 音频操作。设置此标志的桥接器必须实现 drm_bridge_funcs->hdmi_audio_preparedrm_bridge_funcs->hdmi_audio_shutdown 回调。

注意:目前,链中最多只能有一个桥接器设置此位。这是为了简化连接器驱动程序中的相应粘合代码。如果链中有一个桥接器设置了此标志,则不可能有桥接器设置 DRM_BRIDGE_OP_DP_AUDIO

DRM_BRIDGE_OP_DP_AUDIO

桥接器提供 DisplayPort 音频操作。设置此标志的桥接器必须实现 drm_bridge_funcs->dp_audio_preparedrm_bridge_funcs->dp_audio_shutdown 回调。

注意:目前,链中最多只能有一个桥接器设置此位。这是为了简化连接器驱动程序中的相应粘合代码。如果链中有一个桥接器设置了此标志,则不可能有桥接器设置 DRM_BRIDGE_OP_HDMI_AUDIO

struct drm_bridge

中心 DRM 桥接器控制结构

定义:

struct drm_bridge {
    struct drm_private_obj base;
    struct drm_device *dev;
    struct drm_encoder *encoder;
    struct list_head chain_node;
    struct device_node *of_node;
    struct list_head list;
    const struct drm_bridge_timings *timings;
    const struct drm_bridge_funcs *funcs;
    void *container;
    struct kref refcount;
    void *driver_private;
    enum drm_bridge_ops ops;
    int type;
    bool interlace_allowed;
    bool ycbcr_420_allowed;
    bool pre_enable_prev_first;
    struct i2c_adapter *ddc;
    struct mutex hpd_mutex;
    void (*hpd_cb)(void *data, enum drm_connector_status status);
    void *hpd_data;
    const char *vendor;
    const char *product;
    unsigned int supported_formats;
    unsigned int max_bpc;
    struct device *hdmi_audio_dev;
    int hdmi_audio_max_i2s_playback_channels;
    unsigned int hdmi_audio_spdif_playback : 1;
    int hdmi_audio_dai_port;
};

成员

基础

继承自 drm_private_object

dev

此桥接器所属的 DRM 设备

encoder

此桥接器连接到的编码器

chain_node

用于形成桥接器链

of_node

指向桥接器的设备节点指针

list

用于跟踪所有添加的桥接器

timings

桥接器的时序规范(如果有)(可能为 NULL)

funcs

控制功能

container

指向嵌入此 struct drm_bridge 的私有驱动程序结构的指针。

refcount

引用此桥接器的用户的引用计数。

driver_private

指向桥接器驱动程序的内部上下文的指针

ops

桥接器支持的操作的位掩码

type

桥接器输出端的连接类型 (DRM_MODE_CONNECTOR_*)。对于此链末端的桥接器,这标识了连接的显示器的类型。

interlace_allowed

指示桥接器可以处理隔行扫描模式。

ycbcr_420_allowed

指示桥接器可以处理 YCbCr 420 输出。

pre_enable_prev_first

桥接器要求在调用其 pre_enable 函数之前调用前一个桥接器的 pre_enable 函数,反之亦然对于 post_disable。对于需要在外围设备之前初始化主机的 DSI 设备,这通常是一个要求。

ddc

用于 DDC 访问的关联 I2C 适配器(如果有)。

hpd_mutex

保护 hpd_cbhpd_data 字段。

hpd_cb

热插拔检测回调,已使用 drm_bridge_hpd_enable() 注册。

hpd_data

传递给热插拔检测回调 hpd_cb 的私有数据。

vendor

产品的供应商,用于 SPD InfoFrame 生成。如果设置了 DRM_BRIDGE_OP_HDMI,则这是必需的。

product

产品的名称,用于 SPD InfoFrame 生成。如果设置了 DRM_BRIDGE_OP_HDMI,则这是必需的。

supported_formats

列出支持的输出格式的 hdmi_colorspace 位掩码。这仅在设置了 DRM_BRIDGE_OP_HDMI 时才相关。

max_bpc

HDMI 桥接器支持的最大每字符位数。允许值为 8、10 和 12。这仅在设置了 DRM_BRIDGE_OP_HDMI 时才相关。

hdmi_audio_dev

如果设置了 DRM_BRIDGE_OP_HDMI_AUDIODRM_BRIDGE_OP_DP_AUDIO 中的任何一个,则用作 HDMI 编解码器的父设备的设备。

hdmi_audio_max_i2s_playback_channels

DRM_BRIDGE_OP_HDMI_AUDIODRM_BRIDGE_OP_DP_AUDIO 的最大回放 I2S 通道数。

hdmi_audio_spdif_playback

如果此桥接器具有用于 DRM_BRIDGE_OP_HDMI_AUDIODRM_BRIDGE_OP_DP_AUDIO 的 S/PDIF 回放端口,则设置此项。

hdmi_audio_dai_port

用于 DRM_BRIDGE_OP_HDMI_AUDIODRM_BRIDGE_OP_DP_AUDIO 中的任何一个的声音 DAI 端口,如果不使用则为 -1。

devm_drm_bridge_alloc

devm_drm_bridge_alloc (dev, type, member, funcs)

分配和初始化桥接器

参数

dev

桥接器设备的 struct device

type

包含 struct drm_bridge 的 struct 的类型

member

typedrm_bridge 的名称

funcs

此桥接器的回调

描述

返回的桥接器的引用计数初始化为 1。当删除 dev 时,将通过 devm 自动删除此引用(通过调用 drm_bridge_put())。

返回

指向新桥接器的指针,或失败时返回 ERR_PTR。

struct drm_bridge_state *drm_bridge_get_current_state(struct drm_bridge *bridge)

获取当前桥接器状态

参数

struct drm_bridge *bridge

桥对象

描述

必须在持有 modeset 锁的情况下调用此函数。

当前桥接器状态,如果没有则为 NULL。

struct drm_bridge *drm_bridge_get_next_bridge(struct drm_bridge *bridge)

获取链中的下一个桥接器

参数

struct drm_bridge *bridge

桥对象

返回

bridge 之后的链中的下一个桥接器,如果 bridge 是最后一个,则为 NULL。

struct drm_bridge *drm_bridge_get_prev_bridge(struct drm_bridge *bridge)

获取链中的上一个桥接器

参数

struct drm_bridge *bridge

桥对象

返回

链中的上一个桥接器,如果 bridge 是第一个,则为 NULL。

struct drm_bridge *drm_bridge_chain_get_first_bridge(struct drm_encoder *encoder)

获取链中的第一个桥接器

参数

struct drm_encoder *encoder

编码器对象

返回

链中的第一个桥接器,如果 encoder 没有附加桥接器,则为 NULL。

drm_for_each_bridge_in_chain

drm_for_each_bridge_in_chain (encoder, bridge)

迭代链中存在的所有桥接器

参数

encoder

要在其上迭代桥接器的编码器

bridge

一个桥接器指针,在每次迭代时更新为指向当前桥接器

描述

迭代附加到 encoder 的桥接器链中存在的所有桥接器。

struct drm_bridge *drm_bridge_get(struct drm_bridge *bridge)

获取桥接器引用

参数

struct drm_bridge *bridge

DRM 桥接器

描述

此函数会递增桥接器的 refcount。

返回

指向 bridge 的指针。

void drm_bridge_put(struct drm_bridge *bridge)

释放桥接器引用

参数

struct drm_bridge *bridge

DRM 桥接器

描述

此函数会递减桥接器的引用计数,如果引用计数降至零,则释放该对象。

void drm_bridge_add(struct drm_bridge *bridge)

将给定的桥接器添加到全局桥接器列表

参数

struct drm_bridge *bridge

桥控制结构

描述

要添加的桥接器必须已由 devm_drm_bridge_alloc() 分配。

int devm_drm_bridge_add(struct device *dev, struct drm_bridge *bridge)

drm_bridge_add() 的 devm 管理版本

参数

struct device *dev

将桥接器生命周期绑定到的设备

struct drm_bridge *bridge

桥控制结构

描述

这是 drm_bridge_add() 的托管版本,它会在取消绑定 dev 时自动调用 drm_bridge_remove()

返回

如果无错误则为 0 或负错误代码。

void drm_bridge_remove(struct drm_bridge *bridge)

从全局桥接器列表中删除给定的桥接器

参数

struct drm_bridge *bridge

桥控制结构

int drm_bridge_attach(struct drm_encoder *encoder, struct drm_bridge *bridge, struct drm_bridge *previous, enum drm_bridge_attach_flags flags)

将桥接器附加到编码器的链

参数

struct drm_encoder *encoder

DRM 编码器

struct drm_bridge *bridge

要附加的桥接器

struct drm_bridge *previous

链中的上一个桥接器(可选)

enum drm_bridge_attach_flags flags

DRM_BRIDGE_ATTACH_* 标志

描述

由 KMS 驱动程序调用以将桥接器链接到编码器的链。 previous 参数指定链中的上一个桥接器。如果为 NULL,则桥接器直接链接到编码器的输出端。否则,它链接到上一个桥接器的输出端。

如果 non-NULL,则必须已通过对此函数的调用附加上一个桥接器。

请注意,附加到编码器的桥接器会在 drm_encoder_cleanup() 中的编码器清理期间自动分离,因此通常 不应 在驱动程序代码中使用 drm_bridge_detach() 平衡 drm_bridge_attach()

返回

成功时为零,失败时为错误代码

enum drm_mode_status drm_bridge_chain_mode_valid(struct drm_bridge *bridge, const struct drm_display_info *info, const struct drm_display_mode *mode)

验证模式与编码器链中的所有桥接器是否匹配。

参数

struct drm_bridge *bridge

桥控制结构

const struct drm_display_info *info

应针对其验证模式的显示信息

const struct drm_display_mode *mode

要验证的所需模式

描述

对编码器链中的所有桥接器调用 drm_bridge_funcs.mode_valid,从第一个桥接器到最后一个桥接器。如果至少一个桥接器不接受该模式,则该函数将返回错误代码。

注意

传递的桥接器应是最靠近编码器的桥接器。

返回

成功时返回 MODE_OK,失败时返回 drm_mode_status 枚举错误代码

void drm_bridge_chain_mode_set(struct drm_bridge *bridge, const struct drm_display_mode *mode, const struct drm_display_mode *adjusted_mode)

为编码器链中的所有桥接器设置建议的模式

参数

struct drm_bridge *bridge

桥控制结构

const struct drm_display_mode *mode

要为编码器链设置的所需模式

const struct drm_display_mode *adjusted_mode

适用于此编码器链的更新模式

描述

为编码器链中的所有桥接器调用 drm_bridge_funcs.mode_set 操作,从第一个桥接器到最后一个桥接器。

注意

传递的桥接器应是最靠近编码器的桥接器

void drm_atomic_bridge_chain_disable(struct drm_bridge *bridge, struct drm_atomic_state *state)

禁用编码器链中的所有桥接器

参数

struct drm_bridge *bridge

桥控制结构

struct drm_atomic_state *state

正在提交的原子状态

描述

为编码器链中的所有桥接器调用 drm_bridge_funcs.atomic_disable(回退到 drm_bridge_funcs.disable)操作,从最后一个桥接器到第一个桥接器。这些在调用 drm_encoder_helper_funcs.atomic_disable 之前调用

注意

传递的桥接器应是最靠近编码器的桥接器

void drm_atomic_bridge_chain_post_disable(struct drm_bridge *bridge, struct drm_atomic_state *state)

在禁用编码器链中的所有桥接器后进行清理

参数

struct drm_bridge *bridge

桥控制结构

struct drm_atomic_state *state

正在提交的原子状态

描述

为编码器链中的所有桥接器调用 drm_bridge_funcs.atomic_post_disable(回退到 drm_bridge_funcs.post_disable)操作,从第一个桥接器到最后一个桥接器。这些在完成 drm_encoder_helper_funcs.atomic_disable 后调用

如果桥接器设置了 pre_enable_prev_first,则该桥接器的 post_disable 将在之前的桥接器之前调用,以反转 pre_enable 调用方向。

如果 Bridge B、D、E 中启用了 pre_enable_prev_first 标志,则生成的 post_disable 顺序将为:Bridge B、Bridge A、Bridge E、Bridge D、Bridge C。

示例

Bridge A ---> Bridge B ---> Bridge C ---> Bridge D ---> Bridge E

注意

传递的桥接器应是最靠近编码器的桥接器

void drm_atomic_bridge_chain_pre_enable(struct drm_bridge *bridge, struct drm_atomic_state *state)

准备启用编码器链中的所有桥接器

参数

struct drm_bridge *bridge

桥控制结构

struct drm_atomic_state *state

正在提交的原子状态

描述

为编码器链中的所有桥接器调用 drm_bridge_funcs.atomic_pre_enable(回退到 drm_bridge_funcs.pre_enable)操作,从最后一个桥接器到第一个桥接器。这些在调用 drm_encoder_helper_funcs.atomic_enable 之前调用

如果桥接器设置了 pre_enable_prev_first,则先前桥接器的 pre_enable 将在此桥接器的 pre_enable 之前调用。

如果 Bridge B、D、E 中启用了 pre_enable_prev_first 标志,则生成的 pre_enable 顺序将为:Bridge C、Bridge D、Bridge E、Bridge A、Bridge B。

示例

Bridge A ---> Bridge B ---> Bridge C ---> Bridge D ---> Bridge E

注意

传递的桥接器应是最靠近编码器的桥接器

void drm_atomic_bridge_chain_enable(struct drm_bridge *bridge, struct drm_atomic_state *state)

启用编码器链中的所有桥接器

参数

struct drm_bridge *bridge

桥控制结构

struct drm_atomic_state *state

正在提交的原子状态

描述

为编码器链中的所有桥接器调用 drm_bridge_funcs.atomic_enable(回退到 drm_bridge_funcs.enable)操作,从第一个桥接器到最后一个桥接器。这些在完成 drm_encoder_helper_funcs.atomic_enable 后调用

注意

传递的桥接器应是最靠近编码器的桥接器

int drm_atomic_bridge_chain_check(struct drm_bridge *bridge, struct drm_crtc_state *crtc_state, struct drm_connector_state *conn_state)

对桥接器链执行原子检查

参数

struct drm_bridge *bridge

桥控制结构

struct drm_crtc_state *crtc_state

新的 CRTC 状态

struct drm_connector_state *conn_state

新的连接器状态

描述

首先,在调用 drm_bridge_funcs.atomic_check() (回退到 drm_bridge_funcs.mode_fixup())操作之前,触发一个总线格式协商,用于编码器链中的所有桥接器,从最后一个桥接器到第一个桥接器。这些调用发生在调用 drm_encoder_helper_funcs.atomic_check() 之前。

返回

成功时返回 0,失败时返回负错误代码

enum drm_connector_status drm_bridge_detect(struct drm_bridge *bridge)

检查是否有任何设备连接到桥接器的输出

参数

struct drm_bridge *bridge

桥控制结构

描述

如果桥接器支持输出检测,如 DRM_BRIDGE_OP_DETECT 桥接器操作标志所报告的那样,则调用桥接器的 drm_bridge_funcs.detect 并返回连接状态。否则,返回 connector_status_unknown。

返回

成功时的检测状态,如果桥接器不支持输出检测,则返回 connector_status_unknown。

int drm_bridge_get_modes(struct drm_bridge *bridge, struct drm_connector *connector)

将当前对接收器有效的所有模式填充到 connector

参数

struct drm_bridge *bridge

桥控制结构

struct drm_connector *connector

要填充模式的连接器

描述

如果桥接器支持输出模式检索,如 DRM_BRIDGE_OP_MODES 桥接器操作标志所报告的那样,则调用 drm_bridge_funcs.get_modes 以使用所有有效模式填充连接器,并返回添加的模式数量。否则,返回 0。

返回

添加到连接器的模式数量。

const struct drm_edid *drm_bridge_edid_read(struct drm_bridge *bridge, struct drm_connector *connector)

读取连接的显示器的 EDID 数据

参数

struct drm_bridge *bridge

桥控制结构

struct drm_connector *connector

要读取 EDID 的连接器

描述

如果桥接器支持输出 EDID 检索,如 DRM_BRIDGE_OP_EDID 桥接器操作标志所报告的那样,则调用 drm_bridge_funcs.edid_read 以获取 EDID 并返回它。否则,返回 NULL。

返回

成功时返回检索到的 EDID,否则返回 NULL。

void drm_bridge_hpd_enable(struct drm_bridge *bridge, void (*cb)(void *data, enum drm_connector_status status), void *data)

为桥接器启用热插拔检测

参数

struct drm_bridge *bridge

桥控制结构

void (*cb)(void *data, enum drm_connector_status status)

热插拔检测回调

void *data

要传递给热插拔检测回调的数据

描述

如果实现了 drm_bridge_funcs.hpd_enable,则调用它,并将给定的 cbdata 注册为热插拔通知回调。从现在开始,当桥接器检测到输出状态更改时,将使用 data 调用 cb,直到使用 drm_bridge_hpd_disable() 禁用热插拔通知。

只有在 bridge->ops 中设置了 DRM_BRIDGE_OP_HPD 标志时才支持热插拔检测。当未设置该标志时,不得调用此函数。

一次只能注册一个热插拔检测回调,如果已经为桥接器启用了热插拔检测,则调用此函数是错误的。

void drm_bridge_hpd_disable(struct drm_bridge *bridge)

禁用桥接器的热插拔检测

参数

struct drm_bridge *bridge

桥控制结构

描述

如果实现了 drm_bridge_funcs.hpd_disable,则调用它,并注销之前使用 drm_bridge_hpd_enable() 注册的热插拔检测回调。一旦此函数返回,当输出状态发生更改时,桥接器将不再调用该回调。

只有在 bridge->ops 中设置了 DRM_BRIDGE_OP_HPD 标志时才支持热插拔检测。当未设置该标志时,不得调用此函数。

void drm_bridge_hpd_notify(struct drm_bridge *bridge, enum drm_connector_status status)

通知热插拔检测事件

参数

struct drm_bridge *bridge

桥控制结构

enum drm_connector_status status

输出连接状态

描述

当桥接器驱动程序检测到输出状态发生更改时,应调用此函数来报告热插拔事件,前提是已通过 drm_bridge_hpd_enable() 启用了热插拔检测。

应在可以休眠的上下文中调用此函数。

struct drm_bridge *of_drm_find_bridge(struct device_node *np)

在全局桥接器列表中查找与设备节点对应的桥接器

参数

struct device_node *np

设备节点

返回

成功时返回 drm_bridge 控制结构,失败时返回 NULL

MIPI-DSI 桥接器操作

DSI 主机接口预计将实现为桥接器而不是编码器,但是,为了提供一致的接口,需要定义其操作的一些方面。

DSI 主机应保持 PHY 掉电,直到调用 pre_enable 操作。此时所有通道都处于未定义的空闲状态,并且不得假定它是 LP-11。 pre_enable 应初始化 PHY,将数据通道设置为 LP-11,并将时钟通道设置为 LP-11 或 HS,具体取决于 mode_flag MIPI_DSI_CLOCK_NON_CONTINUOUS

通常,下游桥接器 DSI 外围设备的 pre_enable 将在 DSI 主机之前被调用。如果 DSI 外围设备需要在 pre_enable 之前处于 LP-11 和/或 HS 模式的时钟通道,则它可以设置 pre_enable_prev_first 标志,以请求更改 pre_enable(和 post_disable)的顺序,以首先启用 DSI 主机。

启用 CRTC 或 DSI 主机启用操作应将主机切换为主动在数据通道上传输视频。

反之亦然。 DSI 主机禁用操作或停止 CRTC 应停止传输视频,并且数据通道应返回到 LP-11 状态。 DSI 主机 post_disable 操作应禁用 PHY。如果设置了 pre_enable_prev_first 标志,则 DSI 外围设备的桥接器 post_disable 将在 DSI 主机的 post_disable 之前被调用。

虽然在 pre_enable 之前或 post_disable 之后调用 host_transfer 是有效的,但此时通道的确切状态是未定义的。 DSI 主机应初始化接口,传输数据,然后再次禁用接口。

DRM 不显式支持超低功耗状态 (ULPS)。因此,如果已实现,则需要在 DSI 主机驱动程序中完全处理它。

桥接器连接器助手参考

struct drm_connector *drm_bridge_connector_init(struct drm_device *drm, struct drm_encoder *encoder)

为桥接器链初始化连接器

参数

struct drm_device *drm

DRM 设备

struct drm_encoder *encoder

桥接器链开始的编码器

描述

使用 drm 设备分配、初始化和注册一个 drm_bridge_connector。连接器与以 encoder 开头的桥接器链相关联。链中的所有桥接器都应报告桥接器操作标志(drm_bridge->ops)和桥接器输出类型(drm_bridge->type),并且它们都不能直接创建 DRM 连接器。

成功时返回指向新连接器的指针,否则返回负错误指针。

面板桥接器助手参考

bool drm_bridge_is_panel(const struct drm_bridge *bridge)

检查 drm_bridge 是否为 panel_bridge。

参数

const struct drm_bridge *bridge

要检查的 drm_bridge。

描述

如果桥接器是面板桥接器,则返回 true,否则返回 false。

struct drm_bridge *drm_panel_bridge_add(struct drm_panel *panel)

创建一个 drm_bridgedrm_connector,它们只是从 drm_panel 调用适当的函数。

参数

struct drm_panel *panel

要包装的 drm_panel。必须为非 NULL。

描述

对于从直接使用 drm_panel 转换的驱动程序:预期的用法模式是在编码器模块探测或 DSI 主机连接期间,将通过 drm_of_find_panel_or_bridge() 查找 drm_panel。 drm_panel_bridge_add() 用于在新桥接器中包装该面板,然后可以将结果传递给 drm_bridge_attach()。可以从编码器驱动程序中删除 drm_panel_prepare() 和相关函数(它们现在由 KMS 助手在调用编码器之前调用),以及连接器创建。完成桥接器后(如果在已连接桥接器的情况下,在 drm_mode_config_cleanup() 之后),然后调用 drm_panel_bridge_remove() 释放它。

连接器类型设置为 panel->connector_type,必须将其设置为已知类型。使用连接器类型为 DRM_MODE_CONNECTOR_Unknown 的面板调用此函数将返回 ERR_PTR(-EINVAL)。

有关此函数的自动管理版本,请参阅 devm_drm_panel_bridge_add()

struct drm_bridge *drm_panel_bridge_add_typed(struct drm_panel *panel, u32 connector_type)

使用显式连接器类型创建 drm_bridgedrm_connector

参数

struct drm_panel *panel

要包装的 drm_panel。必须为非 NULL。

u32 connector_type

连接器类型 (DRM_MODE_CONNECTOR_*)

描述

这就像 drm_panel_bridge_add(),但强制连接器类型为 connector_type,而不是从面板推断它。

此函数已弃用,不应在新驱动程序中使用。请改用 drm_panel_bridge_add(),并在必要时修复面板驱动程序(如果它们未报告连接器类型)。

void drm_panel_bridge_remove(struct drm_bridge *bridge)

注销并释放由 drm_panel_bridge_add() 创建的 drm_bridge。

参数

struct drm_bridge *bridge

要释放的 drm_bridge。

int drm_panel_bridge_set_orientation(struct drm_connector *connector, struct drm_bridge *bridge)

从可以转换为面板桥接器的桥接器设置连接器的面板方向。

参数

struct drm_connector *connector

要设置面板方向的连接器。

struct drm_bridge *bridge

要转换为面板桥接器的 drm_bridge。

描述

成功时返回 0,失败时返回负 errno。

struct drm_bridge *devm_drm_panel_bridge_add(struct device *dev, struct drm_panel *panel)

创建一个托管的 drm_bridgedrm_connector,它们只是从 drm_panel 调用适当的函数。

参数

struct device *dev

将桥接器生命周期绑定到的设备

struct drm_panel *panel

要包装的 drm_panel。必须为非 NULL。

描述

这是 drm_panel_bridge_add() 的托管版本,当 dev 未绑定时,它会自动调用 drm_panel_bridge_remove()

struct drm_bridge *devm_drm_panel_bridge_add_typed(struct device *dev, struct drm_panel *panel, u32 connector_type)

使用显式连接器类型创建一个托管的 drm_bridgedrm_connector

参数

struct device *dev

将桥接器生命周期绑定到的设备

struct drm_panel *panel

要包装的 drm_panel。必须为非 NULL。

u32 connector_type

连接器类型 (DRM_MODE_CONNECTOR_*)

描述

这就像 devm_drm_panel_bridge_add(),但强制连接器类型为 connector_type,而不是从面板推断它。

此函数已弃用,不应在新驱动程序中使用。请改用 devm_drm_panel_bridge_add(),并在必要时修复面板驱动程序(如果它们未报告连接器类型)。

struct drm_bridge *drmm_panel_bridge_add(struct drm_device *drm, struct drm_panel *panel)

创建一个 DRM 管理的 drm_bridgedrm_connector,它们只是从 drm_panel 调用适当的函数。

参数

struct drm_device *drm

将桥接器生命周期绑定到的 DRM 设备

struct drm_panel *panel

要包装的 drm_panel。必须为非 NULL。

描述

这是 drm_panel_bridge_add() 的 DRM 管理版本,当 dev 被清理时,它会自动调用 drm_panel_bridge_remove()

struct drm_connector *drm_panel_bridge_connector(struct drm_bridge *bridge)

返回面板桥接器的连接器

参数

struct drm_bridge *bridge

drm_bridge。

描述

drm_panel_bridge 创建连接器。此函数提供对连接器的外部访问。

返回

指向 drm_connector 的指针

struct drm_bridge *devm_drm_of_get_bridge(struct device *dev, struct device_node *np, u32 port, u32 endpoint)

返回链中的下一个桥接器

参数

struct device *dev

将桥接器生命周期绑定到的设备

struct device_node *np

包含编码器输出端口的设备树节点

u32 port

设备树节点中的端口

u32 endpoint

设备树节点中的端点

描述

给定 DT 节点的端口和端点号,查找连接的节点并返回关联的桥接器(如果有),如果连接了面板,则创建并返回 drm 面板桥接器实例。

如果成功,则返回指向桥接器的指针,否则返回错误指针。

struct drm_bridge *drmm_of_get_bridge(struct drm_device *drm, struct device_node *np, u32 port, u32 endpoint)

返回链中的下一个桥接器

参数

struct drm_device *drm

将桥接器生命周期绑定到的设备

struct device_node *np

包含编码器输出端口的设备树节点

u32 port

设备树节点中的端口

u32 endpoint

设备树节点中的端点

描述

给定 DT 节点的端口和端点号,查找连接的节点并返回关联的桥接器(如果有),如果连接了面板,则创建并返回 drm 面板桥接器实例。

如果成功,则返回指向 bridge 的 drmm 管理指针,否则返回错误指针。

面板助手参考

DRM 面板助手允许驱动程序向中央注册表注册面板对象,并提供函数以在显示驱动程序中检索这些面板。

为了方便集成到使用 drm_bridge 基础设施的驱动程序中,请查看 drm_panel_bridge_add()devm_drm_panel_bridge_add()

struct drm_panel_funcs

对给定面板执行操作

定义:

struct drm_panel_funcs {
    int (*prepare)(struct drm_panel *panel);
    int (*enable)(struct drm_panel *panel);
    int (*disable)(struct drm_panel *panel);
    int (*unprepare)(struct drm_panel *panel);
    int (*get_modes)(struct drm_panel *panel, struct drm_connector *connector);
    enum drm_panel_orientation (*get_orientation)(struct drm_panel *panel);
    int (*get_timings)(struct drm_panel *panel, unsigned int num_timings, struct display_timing *timings);
    void (*debugfs_init)(struct drm_panel *panel, struct dentry *root);
};

成员

prepare

开启面板并执行设置。

此函数是可选的。

enable

启用面板(开启背光等)。

此函数是可选的。

disable

禁用面板(关闭背光等)。

此函数是可选的。

unprepare

关闭面板。

此函数是可选的。

get_modes

将模式添加到面板连接到的连接器,并返回添加的模式数量。

此函数是强制性的。

get_orientation

返回设备树或 EDID 设置的面板方向。

此函数是可选的。

get_timings

将显示时序复制到提供的数组中,并返回可用的显示时序数量。

此函数是可选的。

debugfs_init

允许面板创建特定于面板的 debugfs 文件。

描述

.prepare() 函数通常在显示控制器开始传输视频数据之前调用。面板驱动程序可以使用它来开启面板并等待其准备就绪。如果需要额外的配置(例如,通过 I2C、SPI 或 DSI 等控制总线),这是一个好时机。

在显示控制器开始传输视频数据后,可以安全地调用 .enable() 函数。这通常会启用背光以使屏幕上的图像可见。某些面板在显示图像之前需要一定的或帧数。此函数负责考虑到这一点,然后再启用背光,以避免视觉故障。

在停止从显示控制器传输视频数据之前,可能需要关闭面板以避免视觉故障。这在 .disable() 函数中完成。与 .enable() 类似,这通常涉及关闭背光并等待一段时间,以确保面板上看不到图像。然后,显示控制器可以安全地停止传输视频数据。

为了在未传输视频数据时节省功耗,驱动程序可以关闭面板。这是 .unprepare() 函数的工作。

如果使用 drm_panel_of_backlight()drm_panel_dp_aux_backlight() 进行配置,则可以自动处理背光。然后,驱动程序不需要实现启用/禁用背光的功能。

struct drm_panel

DRM 面板对象

定义:

struct drm_panel {
    struct device *dev;
    struct backlight_device *backlight;
    const struct drm_panel_funcs *funcs;
    int connector_type;
    struct list_head list;
    struct list_head followers;
    struct mutex follower_lock;
    bool prepare_prev_first;
    bool prepared;
    bool enabled;
    void *container;
    struct kref refcount;
};

成员

dev

面板的父设备。

backlight

背光设备,用于在调用 enable() 后开启背光,并在调用 disable() 之前关闭背光。背光由 drm_panel_of_backlight()drm_panel_dp_aux_backlight() 设置,驱动程序不应分配它。

funcs

可以在面板上执行的操作。

connector_type

面板的类型,作为 DRM_MODE_CONNECTOR_* 值。这用于使用正确的连接器类型初始化与面板对应的 drm_connector。

list

注册表中的面板条目。

followers

依赖于此面板的 struct drm_panel_follower 列表。

follower_lock

followers 列表的锁。

prepare_prev_first

先前的控制器应该首先准备好,然后再调用面板的 prepare。这主要是在 DSI 主机控制器应该初始化为 LP-11 后才能启动面板电源的 DSI 面板上需要的。

prepared

如果为 true,则面板已准备好。

enabled

如果为 true,则面板已启用。

container

指向嵌入此 struct drm_panel 的私有驱动程序结构体的指针。

refcount

引用此面板的用户的引用计数。

devm_drm_panel_alloc

devm_drm_panel_alloc (dev, type, member, funcs, connector_type)

分配并初始化一个引用计数的面板。

参数

dev

面板设备的 struct device

type

包含 struct drm_panel 的 struct 类型

member

typedrm_panel 的名称

funcs

此面板的回调

connector_type

与面板接口对应的连接器类型 (DRM_MODE_CONNECTOR_*)

描述

返回的面板的引用计数初始化为 1。当 dev 被移除时,此引用将通过 devm 自动删除(通过调用 drm_panel_put())。

返回

指向嵌入面板的容器结构的指针,失败时为 ERR_PTR。

void drm_panel_init(struct drm_panel *panel, struct device *dev, const struct drm_panel_funcs *funcs, int connector_type)

初始化面板

参数

struct drm_panel *panel

DRM 面板

struct device *dev

面板的父设备

const struct drm_panel_funcs *funcs

面板操作

int connector_type

与面板接口对应的连接器类型 (DRM_MODE_CONNECTOR_*)(不得为 DRM_MODE_CONNECTOR_Unknown)

描述

初始化面板结构,以便随后使用 drm_panel_add() 进行注册。

void drm_panel_add(struct drm_panel *panel)

将面板添加到全局注册表

参数

struct drm_panel *panel

要添加的面板

描述

将面板添加到全局注册表,以便显示驱动程序可以查找它。要添加的面板必须已由 devm_drm_panel_alloc() 分配。

void drm_panel_remove(struct drm_panel *panel)

从全局注册表中删除面板

参数

struct drm_panel *panel

DRM 面板

描述

从全局注册表中删除面板。

void drm_panel_prepare(struct drm_panel *panel)

开启面板电源

参数

struct drm_panel *panel

DRM 面板

描述

调用此函数将启用电源并取消对面板的任何重置信号的断言。在此完成后,可以通过命令总线与任何集成电路进行通信。此函数不能失败(因为它从 pre_enable 调用链中调用)。之后始终会调用 drm_panel_disable()

void drm_panel_unprepare(struct drm_panel *panel)

关闭面板电源

参数

struct drm_panel *panel

DRM 面板

描述

调用此函数将完全关闭面板电源(声明面板的重置,关闭电源,...)。在此函数完成后,通常无法与面板通信,直到再次调用 drm_panel_prepare()

void drm_panel_enable(struct drm_panel *panel)

启用面板

参数

struct drm_panel *panel

DRM 面板

描述

调用此函数将导致面板显示驱动程序打开,并且背光启用。在此调用完成后,屏幕上将显示内容。此函数不能失败(因为它从启用调用链中调用)。之后始终会调用 drm_panel_disable()

void drm_panel_disable(struct drm_panel *panel)

禁用面板

参数

struct drm_panel *panel

DRM 面板

描述

这通常会关闭面板的背光或禁用显示驱动程序。对于智能面板,在此调用后仍然可以通过任何命令总线与集成电路进行通信。

int drm_panel_get_modes(struct drm_panel *panel, struct drm_connector *connector)

探测面板的可用显示模式

参数

struct drm_panel *panel

DRM 面板

struct drm_connector *connector

DRM 连接器

描述

从面板探测到的模式会自动添加到面板连接到的连接器。

返回

成功时面板提供的模式数量,或失败时为 0(无模式)。

struct drm_panel *drm_panel_get(struct drm_panel *panel)

获取面板引用

参数

struct drm_panel *panel

DRM 面板

描述

此函数会递增面板的引用计数。

返回

指向 panel 的指针

void drm_panel_put(struct drm_panel *panel)

释放面板引用

参数

struct drm_panel *panel

DRM 面板

描述

此函数会递减面板的引用计数,如果引用计数降至零,则释放该对象。

struct drm_panel *of_drm_find_panel(const struct device_node *np)

使用设备树节点查找面板

参数

const struct device_node *np

面板的设备树节点

描述

搜索已注册面板的集合,以查找与给定设备树节点匹配的面板。如果找到匹配的面板,则返回指向它的指针。

此函数返回的可能错误代码

  • EPROBE_DEFER:尚未探测面板设备,调用者应稍后重试

  • ENODEV:设备不可用(状态 != “okay” 或 “ok”)

返回

指向为指定设备树节点注册的面板的指针,如果找不到与设备树节点匹配的面板,则为 ERR_PTR()

int of_drm_get_panel_orientation(const struct device_node *np, enum drm_panel_orientation *orientation)

通过设备树中的“rotation”绑定查找面板的方向

参数

const struct device_node *np

面板的设备树节点

enum drm_panel_orientation *orientation

要填充的方向枚举

描述

在设备树中查找面板的旋转角度。面板的方向在设备树中表示为属性名称“rotation”。设备树中的旋转是逆时针方向。

返回

读取有效的旋转值(0、90、180 或 270)或旋转属性不存在时为 0。失败时返回负错误代码。

bool drm_is_panel_follower(struct device *dev)

检查设备是否为面板跟随器

参数

struct device *dev

要检查的 ‘struct device

描述

这检查设备是否需要使用面板跟随器 API 与面板一起进行电源排序。目前,只能在启用设备树的系统上跟随面板。跟随器的“panel”属性指向要跟随的面板。

返回

如果应该与面板一起进行电源排序,则为 true;否则为 false。

int drm_panel_add_follower(struct device *follower_dev, struct drm_panel_follower *follower)

注册一些东西来跟随面板状态。

参数

struct device *follower_dev

跟随器的 ‘struct device’。

struct drm_panel_follower *follower

跟随器的面板跟随器描述符。

描述

面板跟随器在准备面板之后和取消准备面板之前立即调用。它的主要目的是开启关联的触摸屏电源,尽管它可以用于任何类似的设备。允许多个设备跟随同一面板。

如果将跟随器添加到已打开的面板,则会立即调用跟随器的 prepare 回调。

目前,只能在启用设备树的系统上跟随面板。跟随器的“panel”属性指向要跟随的面板。

返回

0 或错误代码。请注意,-ENODEV 意味着我们检测到

follower_dev 实际上没有跟随面板。如果跟随面板是可选的,则调用者可以选择忽略此返回值。

void drm_panel_remove_follower(struct drm_panel_follower *follower)

反向 drm_panel_add_follower()

参数

struct drm_panel_follower *follower

跟随器的面板跟随器描述符。

描述

撤消 drm_panel_add_follower()。这包括调用跟随器的 unprepare 函数(如果我们从当前已准备好的面板中删除)。

返回

0 或错误代码。

int devm_drm_panel_add_follower(struct device *follower_dev, struct drm_panel_follower *follower)

drm_panel_add_follower() 的 devm 版本

参数

struct device *follower_dev

跟随器的 ‘struct device’。

struct drm_panel_follower *follower

跟随器的面板跟随器描述符。

描述

处理在 follower_dev 上使用 devm 调用 drm_panel_remove_follower()

返回

0 或错误代码。

int drm_panel_of_backlight(struct drm_panel *panel)

使用背光设备节点进行背光

参数

struct drm_panel *panel

DRM 面板

描述

如果您的面板使用设备树并且具有背光 phandle,请使用此函数来启用背光处理。

当面板启用时,在成功调用 drm_panel_funcs.enable() 后将启用背光

当面板禁用时,在调用 drm_panel_funcs.disable() 之前将禁用背光。

支持设备树的面板驱动程序的典型实现将在探测时调用此函数。然后,将透明地处理背光,而无需驱动程序的任何干预。drm_panel_of_backlight() 必须在调用 drm_panel_init() 后调用。

返回

成功时为 0,失败时为负错误代码。

int drm_get_panel_orientation_quirk(int width, int height)

检查面板方向怪癖

参数

int width

面板的像素宽度

int height

面板的像素高度

描述

此函数检查平台特定的(例如基于 DMI 的)怪癖,这些怪癖提供有关无法从硬件/固件中探测到的系统的 panel_orientation 的信息。为避免出现误报,此函数将面板分辨率作为参数,并根据怪癖表条目期望的分辨率进行检查。

请注意,此函数也用于 drm-subsys 之外,例如 efifb 代码。因此,当作为模块构建时,此函数会被编译到其自己的内核模块中。

返回

如果此系统存在怪癖,则为 DRM_MODE_PANEL_ORIENTATION_* 值;如果不存在怪癖,则为 DRM_MODE_PANEL_ORIENTATION_UNKNOWN。

int drm_get_panel_min_brightness_quirk(const struct drm_edid *edid)

获取面板支持的最小亮度级别。

参数

const struct drm_edid *edid

要检查的面板的 EDID

描述

此函数检查平台特定的(例如基于 DMI 的)怪癖,这些怪癖提供有关无法从硬件/固件中正确探测到的系统的最小背光亮度的信息。

返回

负错误值或 [0, 255] 范围内的覆盖值,表示 0-100%,将被缩放到驱动程序的目标范围。

面板自刷新助手参考

此助手库为驱动程序提供了一种利用原子框架来实现面板自刷新 (SR) 支持的简便方法。驱动程序负责在加载/卸载时初始化和清理 SR 助手(请参阅 drm_self_refresh_helper_init/drm_self_refresh_helper_cleanup)。如果连接器是 SR 感知的(意味着它知道如何在面板上启动自刷新),则连接器负责在运行时将 drm_connector_state.self_refresh_aware 设置为 true。

一旦 crtc 使用 drm_self_refresh_helper_init 启用了 SR,助手将监视活动并回调到驱动程序以根据需要启用/禁用 SR。考虑此问题的最佳方法是,它是一个 DPMS 开/关请求,其中 crtc 状态中设置了 drm_crtc_state.self_refresh_active,告诉您在面板上禁用/启用 SR,而不是对其进行电源循环。

在 SR 期间,驱动程序可以选择完全禁用其 crtc/编码器/桥硬件(在这种情况下,无需进行驱动程序更改),或者它们可以检查 drm_crtc_state.self_refresh_active 如果它们想要进入低功耗模式而不完全禁用(以防完全禁用/启用太慢)。

如果存在任何影响处于 SR 模式的管道的原子更新,则 SR 将被停用。如果 crtc 驱动多个连接器,则所有连接器都必须是 SR 感知的,并且所有连接器将同时进入/退出 SR 模式。

如果 crtc 和连接器是 SR 感知的,但是连接的面板不支持它(或者无法进入 SR),则当 drm_crtc_state.self_refresh_active 为 true 时,驱动程序应使 atomic_check 失败。

void drm_self_refresh_helper_update_avg_times(struct drm_atomic_state *state, unsigned int commit_time_ms, unsigned int new_self_refresh_mask)

更新 CRTC 的 SR 时间平均值

参数

struct drm_atomic_state *state

已应用于硬件的状态

unsigned int commit_time_ms

此提交完成所用的时间(毫秒)

unsigned int new_self_refresh_mask

在新状态下具有 self_refresh_active 的 CRTC 的位掩码

描述

drm_mode_config_funcs.atomic_commit_tail 之后调用,此函数将更新自刷新转换时的平均进入/退出自刷新时间。 这些平均值将用于计算在活动后进入自刷新模式之前延迟的时间。

void drm_self_refresh_helper_alter_state(struct drm_atomic_state *state)

更改 SR 退出的原子状态

参数

struct drm_atomic_state *state

当前正在检查的状态

描述

在原子检查结束时调用。此函数检查状态中与自刷新退出不兼容的标志并更改它们。 这有点不真实,因为用户空间期望一件事,而我们给它另一件事。 但是,为了使自刷新完全对用户空间隐藏,这是必需的。

最后,我们将自刷新进入工作排队,以便我们可以在所需的延迟后进入 PSR。

int drm_self_refresh_helper_init(struct drm_crtc *crtc)

初始化 CRTC 的自刷新助手

参数

struct drm_crtc *crtc

支持自刷新支持显示的 CRTC

描述

如果成功,则返回零,如果失败,则返回 -errno

void drm_self_refresh_helper_cleanup(struct drm_crtc *crtc)

清理 CRTC 的自刷新助手

参数

struct drm_crtc *crtc

要清理的 CRTC

HDMI 原子状态助手

概述

这些函数包含 HDMI 规范的实现,以 KMS 助手的形式。

它包含 TMDS 字符速率计算、输出格式的自动选择、信息帧生成等。

信息帧合规性

使用助手的驱动程序将公开根据 debugfs 中的 HDMI 规范生成的各种信息帧。

然后可以使用来自 v4l-utils 项目的 edid-decode 进行合规性测试(https://git.linuxtv.org/v4l-utils.git/)。 示例运行如下所示

# edid-decode \
        -I /sys/kernel/debug/dri/1/HDMI-A-1/infoframes/audio \
        -I /sys/kernel/debug/dri/1/HDMI-A-1/infoframes/avi \
        -I /sys/kernel/debug/dri/1/HDMI-A-1/infoframes/hdmi \
        -I /sys/kernel/debug/dri/1/HDMI-A-1/infoframes/hdr_drm \
        -I /sys/kernel/debug/dri/1/HDMI-A-1/infoframes/spd \
        /sys/class/drm/card1-HDMI-A-1/edid \
        -c

edid-decode (hex):

00 ff ff ff ff ff ff 00 1e 6d f4 5b 1e ef 06 00
07 20 01 03 80 2f 34 78 ea 24 05 af 4f 42 ab 25
0f 50 54 21 08 00 d1 c0 61 40 45 40 01 01 01 01
01 01 01 01 01 01 98 d0 00 40 a1 40 d4 b0 30 20
3a 00 d1 0b 12 00 00 1a 00 00 00 fd 00 3b 3d 1e
b2 31 00 0a 20 20 20 20 20 20 00 00 00 fc 00 4c
47 20 53 44 51 48 44 0a 20 20 20 20 00 00 00 ff
00 32 30 37 4e 54 52 4c 44 43 34 33 30 0a 01 46

02 03 42 72 23 09 07 07 4d 01 03 04 90 12 13 1f
22 5d 5e 5f 60 61 83 01 00 00 6d 03 0c 00 10 00
b8 3c 20 00 60 01 02 03 67 d8 5d c4 01 78 80 03
e3 0f 00 18 e2 00 6a e3 05 c0 00 e6 06 05 01 52
52 51 11 5d 00 a0 a0 40 29 b0 30 20 3a 00 d1 0b
12 00 00 1a 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 c3

----------------

Block 0, Base EDID:
  EDID Structure Version & Revision: 1.3
  Vendor & Product Identification:
    Manufacturer: GSM
    Model: 23540
    Serial Number: 454430 (0x0006ef1e)
    Made in: week 7 of 2022
  Basic Display Parameters & Features:
    Digital display
    Maximum image size: 47 cm x 52 cm
    Gamma: 2.20
    DPMS levels: Standby Suspend Off
    RGB color display
    First detailed timing is the preferred timing
  Color Characteristics:
    Red  : 0.6835, 0.3105
    Green: 0.2587, 0.6679
    Blue : 0.1445, 0.0585
    White: 0.3134, 0.3291
  Established Timings I & II:
    DMT 0x04:   640x480    59.940476 Hz   4:3     31.469 kHz     25.175000 MHz
    DMT 0x09:   800x600    60.316541 Hz   4:3     37.879 kHz     40.000000 MHz
    DMT 0x10:  1024x768    60.003840 Hz   4:3     48.363 kHz     65.000000 MHz
  Standard Timings:
    DMT 0x52:  1920x1080   60.000000 Hz  16:9     67.500 kHz    148.500000 MHz
    DMT 0x10:  1024x768    60.003840 Hz   4:3     48.363 kHz     65.000000 MHz
    DMT 0x09:   800x600    60.316541 Hz   4:3     37.879 kHz     40.000000 MHz
  Detailed Timing Descriptors:
    DTD 1:  2560x2880   59.966580 Hz   8:9    185.417 kHz    534.000000 MHz (465 mm x 523 mm)
                 Hfront   48 Hsync  32 Hback  240 Hpol P
                 Vfront    3 Vsync  10 Vback  199 Vpol N
    Display Range Limits:
      Monitor ranges (GTF): 59-61 Hz V, 30-178 kHz H, max dotclock 490 MHz
    Display Product Name: 'LG SDQHD'
    Display Product Serial Number: '207NTRLDC430'
  Extension blocks: 1
Checksum: 0x46

----------------

Block 1, CTA-861 Extension Block:
  Revision: 3
  Basic audio support
  Supports YCbCr 4:4:4
  Supports YCbCr 4:2:2
  Native detailed modes: 2
  Audio Data Block:
    Linear PCM:
      Max channels: 2
      Supported sample rates (kHz): 48 44.1 32
      Supported sample sizes (bits): 24 20 16
  Video Data Block:
    VIC   1:   640x480    59.940476 Hz   4:3     31.469 kHz     25.175000 MHz
    VIC   3:   720x480    59.940060 Hz  16:9     31.469 kHz     27.000000 MHz
    VIC   4:  1280x720    60.000000 Hz  16:9     45.000 kHz     74.250000 MHz
    VIC  16:  1920x1080   60.000000 Hz  16:9     67.500 kHz    148.500000 MHz (native)
    VIC  18:   720x576    50.000000 Hz  16:9     31.250 kHz     27.000000 MHz
    VIC  19:  1280x720    50.000000 Hz  16:9     37.500 kHz     74.250000 MHz
    VIC  31:  1920x1080   50.000000 Hz  16:9     56.250 kHz    148.500000 MHz
    VIC  34:  1920x1080   30.000000 Hz  16:9     33.750 kHz     74.250000 MHz
    VIC  93:  3840x2160   24.000000 Hz  16:9     54.000 kHz    297.000000 MHz
    VIC  94:  3840x2160   25.000000 Hz  16:9     56.250 kHz    297.000000 MHz
    VIC  95:  3840x2160   30.000000 Hz  16:9     67.500 kHz    297.000000 MHz
    VIC  96:  3840x2160   50.000000 Hz  16:9    112.500 kHz    594.000000 MHz
    VIC  97:  3840x2160   60.000000 Hz  16:9    135.000 kHz    594.000000 MHz
  Speaker Allocation Data Block:
    FL/FR - Front Left/Right
  Vendor-Specific Data Block (HDMI), OUI 00-0C-03:
    Source physical address: 1.0.0.0
    Supports_AI
    DC_36bit
    DC_30bit
    DC_Y444
    Maximum TMDS clock: 300 MHz
    Extended HDMI video details:
      HDMI VICs:
        HDMI VIC 1:  3840x2160   30.000000 Hz  16:9     67.500 kHz    297.000000 MHz
        HDMI VIC 2:  3840x2160   25.000000 Hz  16:9     56.250 kHz    297.000000 MHz
        HDMI VIC 3:  3840x2160   24.000000 Hz  16:9     54.000 kHz    297.000000 MHz
  Vendor-Specific Data Block (HDMI Forum), OUI C4-5D-D8:
    Version: 1
    Maximum TMDS Character Rate: 600 MHz
    SCDC Present
    Supports 12-bits/component Deep Color 4:2:0 Pixel Encoding
    Supports 10-bits/component Deep Color 4:2:0 Pixel Encoding
  YCbCr 4:2:0 Capability Map Data Block:
    VIC  96:  3840x2160   50.000000 Hz  16:9    112.500 kHz    594.000000 MHz
    VIC  97:  3840x2160   60.000000 Hz  16:9    135.000 kHz    594.000000 MHz
  Video Capability Data Block:
    YCbCr quantization: No Data
    RGB quantization: Selectable (via AVI Q)
    PT scan behavior: Always Underscanned
    IT scan behavior: Always Underscanned
    CE scan behavior: Always Underscanned
  Colorimetry Data Block:
    BT2020YCC
    BT2020RGB
  HDR Static Metadata Data Block:
    Electro optical transfer functions:
      Traditional gamma - SDR luminance range
      SMPTE ST2084
    Supported static metadata descriptors:
      Static metadata type 1
    Desired content max luminance: 82 (295.365 cd/m^2)
    Desired content max frame-average luminance: 82 (295.365 cd/m^2)
    Desired content min luminance: 81 (0.298 cd/m^2)
  Detailed Timing Descriptors:
    DTD 2:  2560x2880   29.986961 Hz   8:9     87.592 kHz    238.250000 MHz (465 mm x 523 mm)
                 Hfront   48 Hsync  32 Hback   80 Hpol P
                 Vfront    3 Vsync  10 Vback   28 Vpol N
Checksum: 0xc3  Unused space in Extension Block: 43 bytes

----------------

edid-decode 1.29.0-5346
edid-decode SHA: c363e9aa6d70 2025-03-11 11:41:18

Warnings:

Block 1, CTA-861 Extension Block:
  IT Video Formats are overscanned by default, but normally this should be underscanned.
  Video Data Block: VIC 1 and the first DTD are not identical. Is this intended?
  Video Data Block: All VICs are in ascending order, and the first (preferred) VIC <= 4, is that intended?
  Video Capability Data Block: Set Selectable YCbCr Quantization to avoid interop issues.
  Video Capability Data Block: S_PT is equal to S_IT and S_CE, so should be set to 0 instead.
  Colorimetry Data Block: Set the sRGB colorimetry bit to avoid interop issues.
  Display Product Serial Number is set, so the Serial Number in the Base EDID should be 0.
EDID:
  Base EDID: Some timings are out of range of the Monitor Ranges:
    Vertical Freq: 24.000 - 60.317 Hz (Monitor: 59.000 - 61.000 Hz)
    Horizontal Freq: 31.250 - 185.416 kHz (Monitor: 30.000 - 178.000 kHz)
    Maximum Clock: 594.000 MHz (Monitor: 490.000 MHz)

Failures:

Block 1, CTA-861 Extension Block:
  Video Capability Data Block: IT video formats are always underscanned, but bit 7 of Byte 3 of the CTA-861 Extension header is set to overscanned.
EDID:
  CTA-861: Native progressive timings are a mix of several resolutions.

EDID conformity: FAIL

================

InfoFrame of '/sys/kernel/debug/dri/1/HDMI-A-1/infoframes/audio' was empty.

================

edid-decode InfoFrame (hex):

82 02 0d 31 12 28 04 00 00 00 00 00 00 00 00 00
00

----------------

HDMI InfoFrame Checksum: 0x31

AVI InfoFrame
  Version: 2
  Length: 13
  Y: Color Component Sample Format: RGB
  A: Active Format Information Present: Yes
  B: Bar Data Present: Bar Data not present
  S: Scan Information: Composed for an underscanned display
  C: Colorimetry: No Data
  M: Picture Aspect Ratio: 16:9
  R: Active Portion Aspect Ratio: 8
  ITC: IT Content: No Data
  EC: Extended Colorimetry: xvYCC601
  Q: RGB Quantization Range: Limited Range
  SC: Non-Uniform Picture Scaling: No Known non-uniform scaling
  YQ: YCC Quantization Range: Limited Range
  CN: IT Content Type: Graphics
  PR: Pixel Data Repetition Count: 0
  Line Number of End of Top Bar: 0
  Line Number of Start of Bottom Bar: 0
  Pixel Number of End of Left Bar: 0
  Pixel Number of Start of Right Bar: 0

----------------

AVI InfoFrame conformity: PASS

================

edid-decode InfoFrame (hex):

81 01 05 49 03 0c 00 20 01

----------------

HDMI InfoFrame Checksum: 0x49

Vendor-Specific InfoFrame (HDMI), OUI 00-0C-03
  Version: 1
  Length: 5
  HDMI Video Format: HDMI_VIC is present
  HDMI VIC 1:  3840x2160   30.000000 Hz  16:9     67.500 kHz    297.000000 MHz

----------------

Vendor-Specific InfoFrame (HDMI), OUI 00-0C-03 conformity: PASS

================

InfoFrame of '/sys/kernel/debug/dri/1/HDMI-A-1/infoframes/hdr_drm' was empty.

================

edid-decode InfoFrame (hex):

83 01 19 93 42 72 6f 61 64 63 6f 6d 56 69 64 65
6f 63 6f 72 65 00 00 00 00 00 00 00 09

----------------

HDMI InfoFrame Checksum: 0x93

Source Product Description InfoFrame
  Version: 1
  Length: 25
  Vendor Name: 'Broadcom'
  Product Description: 'Videocore'
  Source Information: PC general

----------------

Source Product Description InfoFrame conformity: PASS

测试

助手具有单元测试,可以使用 kunit 进行测试

$ ./tools/testing/kunit/kunit.py run \
        --kunitconfig=drivers/gpu/drm/tests \
        drm_atomic_helper_connector_hdmi_*

函数参考

void __drm_atomic_helper_connector_hdmi_reset(struct drm_connector *connector, struct drm_connector_state *new_conn_state)

初始化所有 HDMI drm_connector_state 资源

参数

struct drm_connector *connector

DRM 连接器

struct drm_connector_state *new_conn_state

要重置的连接器状态

描述

drm_connector_state 初始化所有 HDMI 资源,而无需实际分配它。 这对于 HDMI 驱动程序很有用,与 __drm_atomic_helper_connector_reset()drm_atomic_helper_connector_reset() 结合使用。

int drm_atomic_helper_connector_hdmi_check(struct drm_connector *connector, struct drm_atomic_state *state)

用于检查 HDMI 连接器原子状态的助手

参数

struct drm_connector *connector

DRM 连接器

struct drm_atomic_state *state

DRM 状态对象

描述

为 HDMI 连接器提供默认的连接器状态检查处理程序。 检查所需的连接器更新是否有效,并更新派生状态的各种字段。

返回

成功时为零,否则为 errno 代码。

enum drm_mode_status drm_hdmi_connector_mode_valid(struct drm_connector *connector, const struct drm_display_mode *mode)

检查模式对于 HDMI 连接器是否有效

参数

struct drm_connector *connector

用于验证模式的 DRM 连接器

const struct drm_display_mode *mode

要验证的显示模式

描述

HDMI 连接器的通用 .mode_valid 实现。

int drm_atomic_helper_connector_hdmi_update_infoframes(struct drm_connector *connector, struct drm_atomic_state *state)

更新信息帧

参数

struct drm_connector *connector

指向 HDMI 连接器的指针

struct drm_atomic_state *state

从中生成信息帧的 HDMI 连接器状态

描述

此函数用于 HDMI 连接器驱动程序写入其信息帧。 它通常用于 drm_connector_helper_funcs.atomic_enable 实现中。

返回

成功时返回 0,失败时返回错误代码。

int drm_atomic_helper_connector_hdmi_update_audio_infoframe(struct drm_connector *connector, struct hdmi_audio_infoframe *frame)

更新音频信息帧

参数

struct drm_connector *connector

指向 HDMI 连接器的指针

struct hdmi_audio_infoframe *frame

指向要写入的音频信息帧的指针

描述

此函数用于 HDMI 连接器驱动程序更新其音频信息帧。 它通常用于 ALSA 挂钩之一(最可能是 prepare)中。

返回

成功时返回 0,失败时返回错误代码。

int drm_atomic_helper_connector_hdmi_clear_audio_infoframe(struct drm_connector *connector)

停止发送音频信息帧

参数

struct drm_connector *connector

指向 HDMI 连接器的指针

描述

此函数用于 HDMI 连接器驱动程序停止发送其音频信息帧。 它通常用于 ALSA 挂钩之一(最可能是 shutdown)中。

返回

成功时返回 0,失败时返回错误代码。

void drm_atomic_helper_connector_hdmi_hotplug(struct drm_connector *connector, enum drm_connector_status status)

处理 HDMI 连接器的热插拔事件

参数

struct drm_connector *connector

指向 HDMI 连接器的指针

enum drm_connector_status status

连接状态

描述

应将此函数作为所有状态更改的 .detect() / .detect_ctx() 回调的一部分调用。

void drm_atomic_helper_connector_hdmi_force(struct drm_connector *connector)

强制回调的 HDMI 连接器实现

参数

struct drm_connector *connector

指向 HDMI 连接器的指针

描述

此函数实现 HDMI 连接器的 .force() 回调。 它可以直接用作回调,也可以从 .force() 回调实现中调用,以维护 HDMI 特定连接器的数据。

HDCP 助手函数参考

int drm_hdcp_check_ksvs_revoked(struct drm_device *drm_dev, u8 *ksvs, u32 ksv_count)

检查 ID 的撤销状态

参数

struct drm_device *drm_dev

请求 HDCP 撤销检查的 drm_device

u8 *ksvs

KSV(HDCP 接收器 ID)列表

u32 ksv_count

通过 ksvs 传入的 KSV 计数

描述

此函数从用户空间读取 HDCP 系统可更新性消息(SRM 表)作为固件,并解析它以获取由 DCP LLC 检测到的已撤销的 HDCP KSV(接收器 ID)。 一旦知道已撤销的 KSV,就会决定显示驱动程序传入的列表中 KSV 的已撤销状态,并发送响应。

SRM 应以“display_hdcp_srm.bin”的名称呈现。

用户空间需要写入二进制文件的 SRM 表的格式定义在: 1. HDCP 1.4 规范第 55 页上的可更新性章节 https://www.digital-cp.com/sites/default/files/specifications/HDCP``20Specification````20Rev1_4_Secure``.pdf 2. HDCP 2.2 规范第 63 页上的可更新性章节 https://www.digital-cp.com/sites/default/files/specifications/HDCP``20on````20HDMI````20Specification````20Rev2_2_Final1``.pdf

返回

已撤销 KSV 的计数,或者失败时的 -ve 错误号。

int drm_connector_attach_content_protection_property(struct drm_connector *connector, bool hdcp_content_type)

附加内容保护属性

参数

struct drm_connector *connector

要在其上附加 CP 属性的连接器。

bool hdcp_content_type

连接器是否需要 HDCP 内容类型属性

描述

这用于添加对选定连接器的内容保护的支持。 内容保护故意含糊不清,以允许不同的底层技术,但它主要由 HDCP 实现。

当 hdcp_content_type 为 true 时,将创建一个名为 HDCP 内容类型的枚举属性(如果它还不存在),并将其附加到连接器。

此属性用于在选定的连接器上将受保护内容流类型从用户空间发送到内核。 受保护的内容提供商将决定其内容的类型,并将相同的内容声明给内核。

内容类型将在 HDCP 2.2 身份验证期间使用。 内容类型将设置为 drm_connector_state.hdcp_content_type

内容保护将设置为 drm_connector_state.content_protection

当内核触发内容保护状态更改(例如 DESIRED->ENABLED 和 ENABLED->DESIRED)时,将使用 drm_hdcp_update_content_protection() 更新连接器的内容保护状态。

返回

成功时为零,失败时为负 errno。

void drm_hdcp_update_content_protection(struct drm_connector *connector, u64 val)

更新连接器的内容保护状态

参数

struct drm_connector *connector

需要更新内容保护状态的 drm_connector

u64 val

内容保护属性的新状态

描述

显示驱动程序可以使用此函数更新 drm_connector 的内核触发的内容保护状态更改,例如 DESIRED->ENABLED 和 ENABLED->DESIRED。 没有 DESIRED->UNDESIRED 或 ENABLED->UNDESIRED 的 uevent,因为用户空间正在触发此类状态更改,并且内核会毫无失败地执行它。此函数会将属性的新状态更新到连接器的状态中,并生成一个 uevent 以通知用户空间。

DisplayPort 助手函数参考

这些函数包含一些常见的逻辑和助手,用于处理 Display Port 接收器设备以及相关的 DP aux 通道传输、通过 DP aux 通道读取 EDID、解码某些 DPCD 块等。

DisplayPort AUX 通道是一种抽象,允许以通用、独立于驱动程序的方式访问 AUX 功能。 驱动程序可以通过填写 drm_dp_aux 结构的字段来利用这一点。

事务使用独立于硬件的 drm_dp_aux_msg 结构进行描述,该结构传递到驱动程序的 .transfer() 实现中。 支持本机和 I2C over AUX 事务。

struct dp_sdp_header

DP 二次数据包标头

定义:

struct dp_sdp_header {
    u8 HB0;
    u8 HB1;
    u8 HB2;
    u8 HB3;
};

成员

HB0

二次数据包 ID

HB1

二次数据包类型

HB2

二次数据包特定标头,字节 0

HB3

二次数据包特定标头,字节 1

struct dp_sdp

DP 二次数据包

定义:

struct dp_sdp {
    struct dp_sdp_header sdp_header;
    u8 db[32];
};

成员

sdp_header

DP 二次数据包标头

db

用于 PSR 的 DP 二次数据包数据块 VSC SDP 负载 db[0]:立体声接口 db[1]:0 - PSR 状态;1 - 更新 RFB;2 - CRC 有效 db[2]:R 或 Cr 分量的 CRC 值位 7:0 db[3]:R 或 Cr 分量的 CRC 值位 15:8 db[4]:G 或 Y 分量的 CRC 值位 7:0 db[5]:G 或 Y 分量的 CRC 值位 15:8 db[6]:B 或 Cb 分量的 CRC 值位 7:0 db[7]:B 或 Cb 分量的 CRC 值位 15:8 db[8] - db[31]:保留用于像素编码/色度格式的 VSC SDP 负载 db[0] - db[15]:保留 db[16]:像素编码和色度格式 db[17]:动态范围和分量位深度 db[18]:内容类型 db[19] - db[31]:保留

enum dp_pixelformat

DRM DP 像素编码格式

常量

DP_PIXELFORMAT_RGB

RGB 像素编码格式

DP_PIXELFORMAT_YUV444

YCbCr 4:4:4 像素编码格式

DP_PIXELFORMAT_YUV422

YCbCr 4:2:2 像素编码格式

DP_PIXELFORMAT_YUV420

YCbCr 4:2:0 像素编码格式

DP_PIXELFORMAT_Y_ONLY

仅 Y 像素编码格式

DP_PIXELFORMAT_RAW

原始像素编码格式

DP_PIXELFORMAT_RESERVED

保留像素编码格式

描述

此枚举用于指示 DP VSC SDP 像素编码格式。 它基于 DP 1.4 规范 [表 2-117:DB16 到 DB18 的 VSC SDP 负载]

enum dp_colorimetry

DRM DP 色度格式

常量

DP_COLORIMETRY_DEFAULT

sRGB (IEC 61966-2-1) 或 ITU-R BT.601 色度格式

DP_COLORIMETRY_RGB_WIDE_FIXED

RGB 宽色域定点色度格式

DP_COLORIMETRY_BT709_YCC

ITU-R BT.709 色度格式

DP_COLORIMETRY_RGB_WIDE_FLOAT

RGB 宽色域浮点 (scRGB (IEC 61966-2-2)) 色度格式

DP_COLORIMETRY_XVYCC_601

xvYCC601 色度格式

DP_COLORIMETRY_OPRGB

OpRGB 色度格式

DP_COLORIMETRY_XVYCC_709

xvYCC709 色度格式

DP_COLORIMETRY_DCI_P3_RGB

DCI-P3 (SMPTE RP 431-2) 色度格式

DP_COLORIMETRY_SYCC_601

sYCC601 色度格式

DP_COLORIMETRY_RGB_CUSTOM

RGB 自定义颜色配置文件色度格式

DP_COLORIMETRY_OPYCC_601

opYCC601 色度格式

DP_COLORIMETRY_BT2020_RGB

ITU-R BT.2020 R’ G’ B’ 色度格式

DP_COLORIMETRY_BT2020_CYCC

ITU-R BT.2020 Y’c C’bc C’rc 色度格式

DP_COLORIMETRY_BT2020_YCC

ITU-R BT.2020 Y’ C’b C’r 色度格式

描述

此枚举用于指示 DP VSC SDP 色度格式。 它基于 DP 1.4 规范 [表 2-117:DB16 到 DB18 的 VSC SDP 负载],枚举成员的名称遵循枚举 drm_colorimetry 定义。

enum dp_dynamic_range

DRM DP 动态范围

常量

DP_DYNAMIC_RANGE_VESA

VESA 范围

DP_DYNAMIC_RANGE_CTA

CTA 范围

描述

此枚举用于指示 DP VSC SDP 动态范围。 它基于 DP 1.4 规范 [表 2-117:DB16 到 DB18 的 VSC SDP 负载]

enum dp_content_type

DRM DP 内容类型

常量

DP_CONTENT_TYPE_NOT_DEFINED

未定义类型

DP_CONTENT_TYPE_GRAPHICS

图形类型

DP_CONTENT_TYPE_PHOTO

照片类型

DP_CONTENT_TYPE_VIDEO

视频类型

DP_CONTENT_TYPE_GAME

游戏类型

描述

此枚举用于指示 DP VSC SDP 内容类型。 它基于 DP 1.4 规范 [表 2-117:DB16 到 DB18 的 VSC SDP 负载] CTA-861-G 定义了内容类型和接收器设备的预期处理

struct drm_dp_vsc_sdp

DRM DP VSC SDP

定义:

struct drm_dp_vsc_sdp {
    unsigned char sdp_type;
    unsigned char revision;
    unsigned char length;
    enum dp_pixelformat pixelformat;
    enum dp_colorimetry colorimetry;
    int bpc;
    enum dp_dynamic_range dynamic_range;
    enum dp_content_type content_type;
};

成员

sdp_type

二次数据包类型

revision

修订号

length

有效数据字节数

pixelformat

像素编码格式

colorimetry

色度格式

bpc

每种颜色的位数

dynamic_range

动态范围信息

content_type

CTA-861-G 定义了内容类型和接收器设备的预期处理

描述

此结构表示 DRM 的 DP VSC SDP。 它基于 DP 1.4 规范 [表 2-116:VSC SDP 标头字节] 和 [表 2-117:DB16 到 DB18 的 VSC SDP 负载]

struct drm_dp_as_sdp

DRM DP 自适应同步 SDP

定义:

struct drm_dp_as_sdp {
    unsigned char sdp_type;
    unsigned char revision;
    unsigned char length;
    int vtotal;
    int target_rr;
    int duration_incr_ms;
    int duration_decr_ms;
    bool target_rr_divider;
    enum operation_mode mode;
};

成员

sdp_type

二次数据包类型

revision

修订号

length

有效数据字节数

vtotal

最小垂直 Vtotal

target_rr

目标刷新

duration_incr_ms

连续帧持续时间增加

duration_decr_ms

连续帧持续时间减少

target_rr_divider

目标刷新率除数

mode

自适应同步操作模式

描述

此结构表示 DRM 的 DP AS SDP。 它基于 DP 2.1 规范 [表 2-126:自适应同步 SDP 标头字节] 和 [表 2-127:DB0 到 DB8 的自适应同步 SDP 负载]

bool drm_dp_dsc_sink_supports_format(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE], u8 output_format)

检查接收器是否支持具有给定输出格式的 DSC

参数

const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE]

接收器的 DSC 功能 DPCD

u8 output_format

要检查的 output_format

描述

如果接收器支持具有给定 output_format 的 DSC,则返回 true,否则返回 false。

bool drm_edp_backlight_supported(const u8 edp_dpcd[EDP_DISPLAY_CTL_CAP_SIZE])

检查 eDP DPCD 的 VESA 背光支持

参数

const u8 edp_dpcd[EDP_DISPLAY_CTL_CAP_SIZE]

要检查的 DPCD

描述

请注意,目前此函数将为支持各种 DPCD 背光功能但需要通过 PWM 设置亮度并且不支持通过 DPCD 设置亮度级别的面板返回 false

返回

如果 edp_dpcd 指示支持 VESA 背光控制,则返回 True,否则返回 false

bool drm_dp_is_uhbr_rate(int link_rate)

确定链路速率是否为 UHBR

参数

int link_rate

链路速率,单位为 10kbits/s

描述

确定提供的链路速率是否为 UHBR 速率。

返回

如果 link_rate 是 UHBR 速率,则返回 True

struct drm_dp_aux_msg

DisplayPort AUX 通道事务

定义:

struct drm_dp_aux_msg {
    unsigned int address;
    u8 request;
    u8 reply;
    void *buffer;
    size_t size;
};

成员

address

要访问的(第一个)寄存器的地址

request

包含事务类型(参见 DP_AUX_* 宏)

reply

完成后,包含事务的回复类型

buffer

指向传输或接收缓冲区的指针

size

buffer 的大小

struct drm_dp_aux_cec

DisplayPort CEC-Tunneling-over-AUX

定义:

struct drm_dp_aux_cec {
    struct mutex lock;
    struct cec_adapter *adap;
    struct drm_connector *connector;
    struct delayed_work unregister_work;
};

成员

lock

保护此结构的互斥锁

adap

用于 CEC-Tunneling-over-AUX 支持的 CEC 适配器。

connector

此 CEC 适配器关联的连接器

unregister_work

注销 CEC 适配器

struct drm_dp_aux

DisplayPort AUX 通道

定义:

struct drm_dp_aux {
    const char *name;
    struct i2c_adapter ddc;
    struct device *dev;
    struct drm_device *drm_dev;
    struct drm_crtc *crtc;
    struct mutex hw_mutex;
    struct work_struct crc_work;
    u8 crc_count;
    ssize_t (*transfer)(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg);
    int (*wait_hpd_asserted)(struct drm_dp_aux *aux, unsigned long wait_us);
    unsigned i2c_nack_count;
    unsigned i2c_defer_count;
    struct drm_dp_aux_cec cec;
    bool is_remote;
    bool powered_down;
    bool no_zero_sized;
};

成员

name

此 AUX 通道和 I2C over AUX 适配器的用户可见名称。

它还用于指定 I2C 适配器的名称。 如果设置为 NULL,将使用 devdev_name()

ddc

可用于 I2C over AUX 通信的 I2C 适配器

dev

指向struct device的指针,该结构体是此 AUX 通道的父设备。

drm_dev

指向拥有此 AUX 通道的drm_device的指针。请注意,在调用drm_dp_aux_register()之前,这可能为NULL

应该尽早将其设置为将使用此 AUX 通道的drm_device。对于许多图形驱动程序,这应该发生在drm_dp_aux_init()之前,但是,只要在调用drm_dp_aux_register()之前进行赋值,稍后设置此字段也是完全可以的。

crtc

指向当前正在使用此 AUX 通道的 crtc 的反向指针

hw_mutex

用于锁定传输的内部互斥锁。

请注意,如果底层硬件在多个通道之间共享,则驱动程序需要进行额外的锁定以防止并发访问。

crc_work

捕获每一帧 CRC 的工作线程

crc_count

捕获的帧 CRC 的计数器

transfer

传输表示单个 AUX 事务的消息。

这是事务如何执行的硬件特定实现,驱动程序必须提供。

指向描述事务的drm_dp_aux_msg结构的指针会传递给此函数。成功后,实现应返回已传输的有效负载字节数,失败时返回负错误代码。

助手将传播这些错误,但 -EBUSY 错误除外,该错误会导致事务重试。如果发生短路,助手将返回 -EPROTO 以简化故障检查。

transfer() 函数只能修改drm_dp_aux_msg结构的 reply 字段。重试逻辑和 i2c 助手假设情况如此。

另请注意,无论 dev 处于什么状态,也无论面板处于什么状态,都可以调用此回调。

  • 如果提供 AUX 总线的 dev 当前未通电,则它将自行通电以进行传输。

  • 如果我们使用 eDP(使用 drm_panel),并且面板未处于可以响应的状态(未通电或处于低功耗状态),则此函数可能会返回错误,但不会崩溃。如果返回错误是可以接受的,则由该代码的调用者来确保面板已通电。如果 drm_panel 驱动程序正在启动 DP AUX 传输,它可以随意自行通电。所有其他代码应确保 pre_enable() 桥链(最终调用 drm_panel prepare 函数)已为面板供电。

wait_hpd_asserted

等待 HPD 被置位

这主要用于 eDP 面板驱动程序等待 eDP 面板完成通电。 DP AUX 控制器可以选择实现此功能。 DP AUX 端点(面板驱动程序)需要在通电后但在执行 AUX 传输之前调用此函数,除非 DP AUX 端点驱动程序知道我们没有使用 AUX 控制器的 HPD。面板驱动程序不需要调用此函数的一个例子是,如果 HPD 连接到面板驱动程序可以直接读取的 GPIO。

如果 DP AUX 控制器未实现此功能,则它仍然可以通过在 transfer() 回调中实现对 HPD 的长时间等待来支持使用 AUX 控制器内置 HPD 信号的 eDP 面板,尽管这种做法已被弃用。

此函数将有效地等待 HPD 信号被置位。传入的 wait_us 参数表示我们知道 HPD 信号预计会在 wait_us 微秒内被置位。如果 DP 控制器中的逻辑具有较长的防抖动时间,则此函数可能会等待比 wait_us 更长的时间。重要的是,如果此函数返回成功,则 DP 控制器已准备好发送 AUX 事务。

如果 HPD 被置位,此函数返回 0,如果时间到期并且 HPD 未被置位,则返回 -ETIMEDOUT。此函数不应将超时错误打印到日志中。

此函数的语义旨在与 readx_poll_timeout() 函数匹配。这意味着 wait_us 为 0 意味着永远等待。与 readx_poll_timeout() 一样,此函数可能会休眠。

注意:此函数专门报告与 DP AUX 通道关联的 HPD 引脚的状态。这与 DRM 中 HPD 的概念大不相同,DRM 中 HPD 更多的是关于显示器的物理存在。例如,对于 eDP,即使 HPD 引脚被解除置位,也假定显示器始终存在。

i2c_nack_count

计算 I2C NACK,用于 DP 验证。

i2c_defer_count

计算 I2C DEFER,用于 DP 验证。

cec

包含用于 CEC-Tunneling-over-AUX 的字段的结构体。

is_remote

此 AUX CH 实际上是否使用边带消息传递。

powered_down

如果为 true,则远程端点已断电。

no_zero_sized

如果硬件无法使用零大小的传输(NVIDIA)

描述

AUX 通道也可用于将 I2C 消息传输到接收器。一种典型的应用是访问接收器设备中存在的 EDID。 transfer() 函数也可用于执行此类事务。drm_dp_aux_register() 函数注册一个可以传递给drm_probe_ddc()的 I2C 适配器。卸载时,驱动程序应调用drm_dp_aux_unregister()以移除 I2C 适配器。 I2C 适配器默认使用长传输;如果收到部分响应,则适配器将仅针对此事务降至部分响应给出的尺寸。

int drm_dp_dpcd_read_data(struct drm_dp_aux *aux, unsigned int offset, void *buffer, size_t size)

从 DPCD 读取一系列字节

参数

struct drm_dp_aux *aux

DisplayPort AUX 通道(SST 或 MST)

unsigned int offset

要读取的(第一个)寄存器的地址

void *buffer

用于存储寄存器值的缓冲区

size_t size

buffer 中的字节数

描述

成功时返回零 (0),失败时返回负错误代码。如果请求被接收器 NAK 或重试计数超出,则返回 -EIO。如果不是所有字节都被传输,此函数返回 -EPROTO。来自底层 AUX 通道传输函数的错误,除了 -EBUSY(导致事务被重试)之外,都会传播给调用者。

int drm_dp_dpcd_write_data(struct drm_dp_aux *aux, unsigned int offset, void *buffer, size_t size)

向 DPCD 写入一系列字节

参数

struct drm_dp_aux *aux

DisplayPort AUX 通道(SST 或 MST)

unsigned int offset

要写入的(第一个)寄存器的地址

void *buffer

包含要写入的值的缓冲区

size_t size

buffer 中的字节数

描述

成功时返回零 (0),失败时返回负错误代码。如果请求被接收器 NAK 或重试计数超出,则返回 -EIO。如果不是所有字节都被传输,此函数返回 -EPROTO。来自底层 AUX 通道传输函数的错误,除了 -EBUSY(导致事务被重试)之外,都会传播给调用者。

ssize_t drm_dp_dpcd_readb(struct drm_dp_aux *aux, unsigned int offset, u8 *valuep)

从 DPCD 读取单个字节

参数

struct drm_dp_aux *aux

DisplayPort AUX 通道

unsigned int offset

要读取的寄存器的地址

u8 *valuep

将存储寄存器值的位置

描述

成功时返回传输的字节数 (1),失败时返回负错误代码。在大多数情况下,您应该使用drm_dp_dpcd_read_byte()代替。

ssize_t drm_dp_dpcd_writeb(struct drm_dp_aux *aux, unsigned int offset, u8 value)

将单个字节写入 DPCD

参数

struct drm_dp_aux *aux

DisplayPort AUX 通道

unsigned int offset

要写入的寄存器的地址

u8 value

要写入寄存器的值

描述

成功时返回传输的字节数 (1),失败时返回负错误代码。在大多数情况下,您应该使用drm_dp_dpcd_write_byte()代替。

int drm_dp_dpcd_read_byte(struct drm_dp_aux *aux, unsigned int offset, u8 *valuep)

从 DPCD 读取单个字节

参数

struct drm_dp_aux *aux

DisplayPort AUX 通道

unsigned int offset

要读取的寄存器的地址

u8 *valuep

将存储寄存器值的位置

描述

成功时返回零 (0),失败时返回负错误代码。

int drm_dp_dpcd_write_byte(struct drm_dp_aux *aux, unsigned int offset, u8 value)

将单个字节写入 DPCD

参数

struct drm_dp_aux *aux

DisplayPort AUX 通道

unsigned int offset

要写入的寄存器的地址

u8 value

要写入寄存器的值

描述

成功时返回零 (0),失败时返回负错误代码。

struct drm_dp_desc

DP 分支/接收器设备描述符

定义:

struct drm_dp_desc {
    struct drm_dp_dpcd_ident ident;
    u32 quirks;
};

成员

ident

来自 DPCD 0x400(接收器)或 0x500(分支)的 DP 设备标识。

quirks

Quirks; 使用drm_dp_has_quirk()查询 quirks。

enum drm_dp_quirk

Display Port 接收器/分支设备特定 quirks

常量

DP_DPCD_QUIRK_CONSTANT_N

该设备要求主链路属性 Mvid 和 Nvid 限制为 16 位。因此将为兼容性提供一个常量值 (0x8000)。

DP_DPCD_QUIRK_NO_PSR

即使设备报告它支持 PSR,或者驱动程序仍然需要为此类设备实现适当的处理,该设备也不支持 PSR。

DP_DPCD_QUIRK_NO_SINK_COUNT

该设备不会将 SINK_COUNT 设置为非零值。驱动程序应在检测期间忽略 SINK_COUNT。请注意,drm_dp_read_sink_count_cap()会自动检查此 quirk。

DP_DPCD_QUIRK_DSC_WITHOUT_VIRTUAL_DPCD

即使设备不支持 Virtual DPCD,也支持 MST DSC。 DSC caps 可以从物理 aux 中读取。

DP_DPCD_QUIRK_CAN_DO_MAX_LINK_RATE_3_24_GBPS

尽管 DP_MAX_LINK_RATE 寄存器报告较低的最大乘数,该设备仍支持 3.24 Gbps 的链路速率(乘数 0xc)。

DP_DPCD_QUIRK_HBLANK_EXPANSION_REQUIRES_DSC

该设备对某些模式应用 HBLANK 扩展,但这需要启用 DSC。

描述

在野外的 Display Port 接收器和分支设备有各种错误,请尝试在此处收集它们。 quirks 是共享的,但驱动程序需要为它们实现解决方法。

bool drm_dp_has_quirk(const struct drm_dp_desc *desc, enum drm_dp_quirk quirk)

DP 设备是否有特定的 quirk

参数

const struct drm_dp_desc *desc

drm_dp_read_desc()填充的设备描述符

enum drm_dp_quirk quirk

要查询的 quirk

描述

如果由 desc 标识的 DP 设备具有 quirk,则返回 true。

struct drm_edp_backlight_info

探测的 eDP 背光信息结构体

定义:

struct drm_edp_backlight_info {
    u8 pwmgen_bit_count;
    u8 pwm_freq_pre_divider;
    u16 max;
    bool lsb_reg_used : 1;
    bool aux_enable : 1;
    bool aux_set : 1;
};

成员

pwmgen_bit_count

pwmgen 位数

pwm_freq_pre_divider

用于此背光的 PWM 频率预分频值(如果有)

max

可以设置的最大背光级别

lsb_reg_used

我们是否也将值写入 DP_EDP_BACKLIGHT_BRIGHTNESS_LSB 寄存器?

aux_enable

面板是否支持 AUX enable cap?

aux_set

面板是否支持通过 AUX 设置亮度?

描述

此结构体包含有关 eDP 背光的各种数据,可以使用drm_edp_backlight_init()填充。

struct drm_dp_phy_test_params

DP Phy 一致性参数

定义:

struct drm_dp_phy_test_params {
    int link_rate;
    u8 num_lanes;
    u8 phy_pattern;
    u8 hbr2_reset[2];
    u8 custom80[10];
    bool enhanced_frame_cap;
};

成员

link_rate

来自 DPCD 0x219 的请求链路速率

num_lanes

sing 通过 DPCD 0x220 请求的通道数

phy_pattern

来自 DPCD 0x248 的 DP Phy 测试模式

hbr2_reset

来自 DCPD 0x24A 和 0x24B 的 DP HBR2_COMPLIANCE_SCRAMBLER_RESET

custom80

来自 DPCD 0x250 到 0x259 的 DP Test_80BIT_CUSTOM_PATTERN

enhanced_frame_cap

增强帧功能的标志。

const char *drm_dp_phy_name(enum drm_dp_phy dp_phy)

获取给定 DP PHY 的名称

参数

enum drm_dp_phy dp_phy

DP PHY 标识符

描述

给定 dp_phy,获取 DP PHY 的用户友好名称,无论是“DPRX”还是“LTTPR ”,还是错误时的“”。返回的字符串始终为非 NULL 且有效。

返回

DP PHY 的名称。

void drm_dp_lttpr_wake_timeout_setup(struct drm_dp_aux *aux, bool transparent_mode)

授予接收器扩展唤醒时间

参数

struct drm_dp_aux *aux

要使用的 DP AUX 通道

bool transparent_mode

如果 lttpr 处于透明模式,则为 True

描述

此函数检查接收器是否需要任何扩展唤醒时间,如果需要,则授予此请求。在此设置之后,源设备可以继续尝试 Aux 事务,直到授予的唤醒超时时间。如果未调用此函数,则所有 Aux 事务预计将在抛出错误之前花费默认的 1 毫秒。

int drm_dp_dpcd_probe(struct drm_dp_aux *aux, unsigned int offset)

使用 1 字节读取访问探测给定的 DPCD 地址

参数

struct drm_dp_aux *aux

DisplayPort AUX 通道 (SST)

unsigned int offset

要探测的寄存器的地址

描述

通过从中读取 1 个字节来探测提供的 DPCD 地址。该函数可用于触发读取访问具有的某些副作用,例如唤醒接收器,而无需读出值。

如果读取访问成功,则返回 0,如果失败,则返回负错误代码。

void drm_dp_dpcd_set_powered(struct drm_dp_aux *aux, bool powered)

设置 DP 设备是否通电

参数

struct drm_dp_aux *aux

DisplayPort AUX 通道;为了方便起见,可以在此处传递 NULL,该函数将不执行任何操作。

bool powered

如果通电,则为 true;如果未通电,则为 false

描述

如果已知 DP AUX 总线上的端点设备已断电,则可以调用此函数使将来的传输立即失败,而不是需要超时。

如果从未调用此函数,则设备默认设置为通电状态。

ssize_t drm_dp_dpcd_read(struct drm_dp_aux *aux, unsigned int offset, void *buffer, size_t size)

从 DPCD 读取一系列字节

参数

struct drm_dp_aux *aux

DisplayPort AUX 通道(SST 或 MST)

unsigned int offset

要读取的(第一个)寄存器的地址

void *buffer

用于存储寄存器值的缓冲区

size_t size

buffer 中的字节数

描述

成功时返回传输的字节数,失败时返回负错误代码。如果请求被接收器 NAK 或重试计数超出,则返回 -EIO。如果不是所有字节都被传输,此函数返回 -EPROTO。来自底层 AUX 通道传输函数的错误,除了 -EBUSY(导致事务被重试)之外,都会传播给调用者。

在大多数情况下,您想要使用drm_dp_dpcd_read_data()代替。

ssize_t drm_dp_dpcd_write(struct drm_dp_aux *aux, unsigned int offset, void *buffer, size_t size)

向 DPCD 写入一系列字节

参数

struct drm_dp_aux *aux

DisplayPort AUX 通道(SST 或 MST)

unsigned int offset

要写入的(第一个)寄存器的地址

void *buffer

包含要写入的值的缓冲区

size_t size

buffer 中的字节数

描述

成功时返回传输的字节数,失败时返回负错误代码。如果请求被接收器 NAK 或重试计数超出,则返回 -EIO。如果不是所有字节都被传输,此函数返回 -EPROTO。来自底层 AUX 通道传输函数的错误,除了 -EBUSY(导致事务被重试)之外,都会传播给调用者。

在大多数情况下,您想要使用drm_dp_dpcd_write_data()代替。

读取 DPCD 链路状态(字节 0x202-0x207)

参数

struct drm_dp_aux *aux

DisplayPort AUX 通道

u8 status[DP_LINK_STATUS_SIZE]

用于存储链路状态的缓冲区(必须至少为 6 个字节)

描述

失败时返回负错误代码,成功时返回 0。

获取 DP PHY 的链路状态信息

参数

struct drm_dp_aux *aux

DisplayPort AUX 通道

enum drm_dp_phy dp_phy

要获取链路状态的 DP PHY

u8 link_status[DP_LINK_STATUS_SIZE]

用于返回状态的缓冲区

描述

获取 DPRX 或 LTTPR PHY 链路状态的 AUX DPCD 寄存器。返回的 link_status 的布局与 DPRX PHY 链路状态的 DPCD 寄存器布局匹配。

如果成功读取信息,则返回 0,如果失败,则返回负错误代码。

开启 DisplayPort 链路的电源

参数

struct drm_dp_aux *aux

DisplayPort AUX 通道

unsigned char revision

链路上支持的 DPCD 版本

描述

成功时返回 0,失败时返回负错误代码。

关闭 DisplayPort 链路的电源

参数

struct drm_dp_aux *aux

DisplayPort AUX 通道

unsigned char revision

链路上支持的 DPCD 版本

描述

成功时返回 0,失败时返回负错误代码。

int drm_dp_dpcd_write_payload(struct drm_dp_aux *aux, int vcpid, u8 start_time_slot, u8 time_slot_count)

将虚拟通道信息写入有效负载表

参数

struct drm_dp_aux *aux

DisplayPort AUX 通道

int vcpid

虚拟通道有效负载 ID

u8 start_time_slot

起始时隙

u8 time_slot_count

时隙计数

描述

写入虚拟通道有效负载分配表,检查有效负载更新状态并根据需要重试。

返回

成功时返回 0,否则返回负错误

int drm_dp_dpcd_clear_payload(struct drm_dp_aux *aux)

清除整个 VC 有效负载 ID 表

参数

struct drm_dp_aux *aux

DisplayPort AUX 通道

描述

清除整个 VC 有效负载 ID 表。

返回

成功返回 0,错误返回负错误码。

int drm_dp_dpcd_poll_act_handled(struct drm_dp_aux *aux, int timeout_ms)

轮询 ACT 处理状态

参数

struct drm_dp_aux *aux

DisplayPort AUX 通道

int timeout_ms

超时时间,单位为毫秒

描述

尝试等待接收器完成对其有效负载表的更新,通过轮询 DP_PAYLOAD_TABLE_UPDATE_STATUS 的 ACT 处理位,最长等待 timeout_ms 毫秒,如果为 0,则默认为 3000 毫秒。

返回

如果 ACT 及时处理,则返回 0;如果失败,则返回负错误码。

bool drm_dp_downstream_is_type(const u8 dpcd[DP_RECEIVER_CAP_SIZE], const u8 port_cap[4], u8 type)

下游端口是否为特定类型?

参数

const u8 dpcd[DP_RECEIVER_CAP_SIZE]

DisplayPort 配置数据

const u8 port_cap[4]

端口功能

u8 type

要检查的端口类型。可以是:DP_DS_PORT_TYPE_DP, DP_DS_PORT_TYPE_VGA, DP_DS_PORT_TYPE_DVI, DP_DS_PORT_TYPE_HDMI, DP_DS_PORT_TYPE_NON_EDID, DP_DS_PORT_TYPE_DP_DUALMODEDP_DS_PORT_TYPE_WIRELESS

描述

注意:仅适用于 DPCD 1.1+ 端口功能。

返回

下游端口是否匹配该类型。

bool drm_dp_downstream_is_tmds(const u8 dpcd[DP_RECEIVER_CAP_SIZE], const u8 port_cap[4], const struct drm_edid *drm_edid)

下游端口是否为 TMDS?

参数

const u8 dpcd[DP_RECEIVER_CAP_SIZE]

DisplayPort 配置数据

const u8 port_cap[4]

端口功能

const struct drm_edid *drm_edid

EDID

返回

下游端口是否为 TMDS (HDMI/DVI)。

bool drm_dp_send_real_edid_checksum(struct drm_dp_aux *aux, u8 real_edid_checksum)

发回真实的 EDID 校验和值

参数

struct drm_dp_aux *aux

DisplayPort AUX 通道

u8 real_edid_checksum

最后一个块的真实 EDID 校验和

返回

成功返回 True

int drm_dp_read_dpcd_caps(struct drm_dp_aux *aux, u8 dpcd[DP_RECEIVER_CAP_SIZE])

读取 DPCD 功能和扩展 DPCD 功能(如果可用)

参数

struct drm_dp_aux *aux

DisplayPort AUX 通道

u8 dpcd[DP_RECEIVER_CAP_SIZE]

用于存储结果 DPCD 的缓冲区

描述

尝试读取 aux 的基本 DPCD 功能。此外,如果存在,此函数会检查并读取扩展的 DPRX 功能 (DP_DP13_DPCD_REV)。

返回

如果成功读取 DPCD,则返回 0;否则,返回负错误码。

int drm_dp_read_downstream_info(struct drm_dp_aux *aux, const u8 dpcd[DP_RECEIVER_CAP_SIZE], u8 downstream_ports[DP_MAX_DOWNSTREAM_PORTS])

读取 DPCD 下游端口信息(如果可用)

参数

struct drm_dp_aux *aux

DisplayPort AUX 通道

const u8 dpcd[DP_RECEIVER_CAP_SIZE]

端口 DPCD 的缓存副本

u8 downstream_ports[DP_MAX_DOWNSTREAM_PORTS]

用于存储下游端口信息的缓冲区

描述

另请参阅:drm_dp_downstream_max_clock() drm_dp_downstream_max_bpc()

返回

如果成功读取下游端口信息或没有下游信息可读取,则返回 0;否则,返回负错误码。

int drm_dp_downstream_max_dotclock(const u8 dpcd[DP_RECEIVER_CAP_SIZE], const u8 port_cap[4])

提取下游端口最大点时钟

参数

const u8 dpcd[DP_RECEIVER_CAP_SIZE]

DisplayPort 配置数据

const u8 port_cap[4]

端口功能

返回

成功时,下游端口最大点时钟(kHz);如果未定义最大时钟,则返回 0

int drm_dp_downstream_max_tmds_clock(const u8 dpcd[DP_RECEIVER_CAP_SIZE], const u8 port_cap[4], const struct drm_edid *drm_edid)

提取下游端口最大 TMDS 时钟

参数

const u8 dpcd[DP_RECEIVER_CAP_SIZE]

DisplayPort 配置数据

const u8 port_cap[4]

端口功能

const struct drm_edid *drm_edid

EDID

返回

成功时,HDMI/DVI 下游端口最大 TMDS 时钟(kHz);如果未定义最大 TMDS 时钟,则返回 0

int drm_dp_downstream_min_tmds_clock(const u8 dpcd[DP_RECEIVER_CAP_SIZE], const u8 port_cap[4], const struct drm_edid *drm_edid)

提取下游端口最小 TMDS 时钟

参数

const u8 dpcd[DP_RECEIVER_CAP_SIZE]

DisplayPort 配置数据

const u8 port_cap[4]

端口功能

const struct drm_edid *drm_edid

EDID

返回

成功时,HDMI/DVI 下游端口最小 TMDS 时钟(kHz);如果未定义最大 TMDS 时钟,则返回 0

int drm_dp_downstream_max_bpc(const u8 dpcd[DP_RECEIVER_CAP_SIZE], const u8 port_cap[4], const struct drm_edid *drm_edid)

提取下游端口最大每分量位数

参数

const u8 dpcd[DP_RECEIVER_CAP_SIZE]

DisplayPort 配置数据

const u8 port_cap[4]

下游端口功能

const struct drm_edid *drm_edid

EDID

返回

成功时返回最大 bpc;如果未定义最大 bpc,则返回 0

bool drm_dp_downstream_420_passthrough(const u8 dpcd[DP_RECEIVER_CAP_SIZE], const u8 port_cap[4])

确定下游端口 YCbCr 4:2:0 直通能力

参数

const u8 dpcd[DP_RECEIVER_CAP_SIZE]

DisplayPort 配置数据

const u8 port_cap[4]

下游端口功能

返回

下游端口是否可以直通 YCbCr 4:2:0

bool drm_dp_downstream_444_to_420_conversion(const u8 dpcd[DP_RECEIVER_CAP_SIZE], const u8 port_cap[4])

确定下游端口 YCbCr 4:4:4->4:2:0 转换能力

参数

const u8 dpcd[DP_RECEIVER_CAP_SIZE]

DisplayPort 配置数据

const u8 port_cap[4]

下游端口功能

返回

下游端口是否可以将 YCbCr 4:4:4 转换为 4:2:0

bool drm_dp_downstream_rgb_to_ycbcr_conversion(const u8 dpcd[DP_RECEIVER_CAP_SIZE], const u8 port_cap[4], u8 color_spc)

确定下游端口 RGB->YCbCr 转换能力

参数

const u8 dpcd[DP_RECEIVER_CAP_SIZE]

DisplayPort 配置数据

const u8 port_cap[4]

下游端口功能

u8 color_spc

寻求转换能力的色彩空间

返回

下游端口是否可以针对给定的色彩空间转换 RGB->YCbCr。

struct drm_display_mode *drm_dp_downstream_mode(struct drm_device *dev, const u8 dpcd[DP_RECEIVER_CAP_SIZE], const u8 port_cap[4])

为下游端口返回一种模式

参数

struct drm_device *dev

DRM 设备

const u8 dpcd[DP_RECEIVER_CAP_SIZE]

DisplayPort 配置数据

const u8 port_cap[4]

端口功能

描述

为没有 EDID 的下游端口提供合适的模式。

返回

成功时返回一个新的 drm_display_mode;失败时返回 NULL

int drm_dp_downstream_id(struct drm_dp_aux *aux, char id[6])

识别分支设备

参数

struct drm_dp_aux *aux

DisplayPort AUX 通道

char id[6]

DisplayPort 分支设备 ID

描述

成功时返回分支设备 ID;失败时返回 NULL

void drm_dp_downstream_debug(struct seq_file *m, const u8 dpcd[DP_RECEIVER_CAP_SIZE], const u8 port_cap[4], const struct drm_edid *drm_edid, struct drm_dp_aux *aux)

调试 DP 分支设备

参数

struct seq_file *m

debugfs 文件指针

const u8 dpcd[DP_RECEIVER_CAP_SIZE]

DisplayPort 配置数据

const u8 port_cap[4]

端口功能

const struct drm_edid *drm_edid

EDID

struct drm_dp_aux *aux

DisplayPort AUX 通道

enum drm_mode_subconnector drm_dp_subconnector_type(const u8 dpcd[DP_RECEIVER_CAP_SIZE], const u8 port_cap[4])

获取 DP 分支设备类型

参数

const u8 dpcd[DP_RECEIVER_CAP_SIZE]

DisplayPort 配置数据

const u8 port_cap[4]

端口功能

void drm_dp_set_subconnector_property(struct drm_connector *connector, enum drm_connector_status status, const u8 *dpcd, const u8 port_cap[4])

设置 DP 连接器的子连接器

参数

struct drm_connector *connector

要设置属性的连接器

enum drm_connector_status status

连接器状态

const u8 *dpcd

DisplayPort 配置数据

const u8 port_cap[4]

端口功能

描述

驱动程序在每次检测事件时调用。

bool drm_dp_read_sink_count_cap(struct drm_connector *connector, const u8 dpcd[DP_RECEIVER_CAP_SIZE], const struct drm_dp_desc *desc)

检查给定的连接器是否具有有效的接收器计数

参数

struct drm_connector *connector

要检查的 DRM 连接器

const u8 dpcd[DP_RECEIVER_CAP_SIZE]

连接器的 DPCD RX 功能的缓存副本

const struct drm_dp_desc *desc

连接器的 DP 描述符的缓存副本

描述

另请参阅:drm_dp_read_sink_count()

返回

如果 (e)DP 连接器具有应探测的有效接收器计数,则返回 True;否则,返回 false

int drm_dp_read_sink_count(struct drm_dp_aux *aux)

检索给定接收器的接收器计数

参数

struct drm_dp_aux *aux

要使用的 DP AUX 通道

描述

另请参阅:drm_dp_read_sink_count_cap()

返回

aux 报告的当前接收器计数;否则,返回负错误码。

void drm_dp_remote_aux_init(struct drm_dp_aux *aux)

最小化初始化远程 AUX 通道

参数

struct drm_dp_aux *aux

DisplayPort AUX 通道

描述

通常用于远程 AUX 通道。仅初始化 CRC 工作结构。

void drm_dp_aux_init(struct drm_dp_aux *aux)

最小化初始化 AUX 通道

参数

struct drm_dp_aux *aux

DisplayPort AUX 通道

描述

如果您需要在向外界注册之前使用 drm_dp_aux 的 i2c 适配器,请先调用 drm_dp_aux_init()。对于其 AUX 适配器的祖父级驱动程序(例如,AUX 适配器由 drm_connector 担任父级),在注册连接器后,您仍然必须调用 drm_dp_aux_register() 以允许用户空间访问辅助 DP 通道。同样,对于此类驱动程序,您还应尽早分配 drm_dp_aux.drm_dev,以便与 AUX 适配器对应的 drm_device 可以在 DRM DP 帮助程序的调试输出中提及。

对于为其 AUX 适配器使用单独平台设备的设备,可以根据驱动程序的要求尽早调用此函数。

int drm_dp_aux_register(struct drm_dp_aux *aux)

初始化并注册 AUX 通道

参数

struct drm_dp_aux *aux

DisplayPort AUX 通道

描述

如果尚未完成,则自动调用 drm_dp_aux_init()。只有在 aux 的父级 drm_dp_aux.dev 初始化后才能调用此函数。对于 AUX 通道的祖父级设备,drm_dp_aux.dev 通常是与 aux 对应的 drm_connector device。对于这些设备,建议在 drm_connector_funcs.late_register 中调用 drm_dp_aux_register(),同样,在 drm_connector_funcs.early_unregister 中调用 drm_dp_aux_unregister()。不遵循此规则的函数在启用 CONFIG_DRM_DISPLAY_DP_AUX_CHARDEV 时可能会发生 Oops。

对于 AUX 通道是一个独立于使用它的 drm_device 的设备(例如 SoC 和桥接设备),建议在将 drm_device 分配给 drm_dp_aux.drm_dev 后调用 drm_dp_aux_register(),同样,一旦 drm_device 不应再与 AUX 通道关联(例如,在桥接分离时),就调用 drm_dp_aux_unregister()

需要在上述两个点之前使用 AUX 通道的驱动程序需要调用 drm_dp_aux_init(),以便在注册之前使用 AUX 通道。

成功时返回 0,失败时返回负错误代码。

void drm_dp_aux_unregister(struct drm_dp_aux *aux)

注销 AUX 适配器

参数

struct drm_dp_aux *aux

DisplayPort AUX 通道

int drm_dp_psr_setup_time(const u8 psr_cap[EDP_PSR_RECEIVER_CAP_SIZE])

PSR 设置时间(微秒)

参数

const u8 psr_cap[EDP_PSR_RECEIVER_CAP_SIZE]

来自 DPCD 的 PSR 功能

返回

面板的 PSR 设置时间,以微秒为单位。如果失败,则返回负的错误代码。

int drm_dp_start_crc(struct drm_dp_aux *aux, struct drm_crtc *crtc)

开始捕获帧 CRC

参数

struct drm_dp_aux *aux

DisplayPort AUX 通道

struct drm_crtc *crtc

显示要捕获 CRC 的帧的 CRTC

描述

成功时返回 0,失败时返回负错误代码。

int drm_dp_stop_crc(struct drm_dp_aux *aux)

停止捕获帧 CRC

参数

struct drm_dp_aux *aux

DisplayPort AUX 通道

描述

成功时返回 0,失败时返回负错误代码。

int drm_dp_read_desc(struct drm_dp_aux *aux, struct drm_dp_desc *desc, bool is_branch)

从 DPCD 读取接收器/分支描述符

参数

struct drm_dp_aux *aux

DisplayPort AUX 通道

struct drm_dp_desc *desc

要从 DPCD 填充的设备描述符

bool is_branch

分支设备为 true,接收器设备为 false

描述

将 DPCD 0x400(接收器)或 0x500(分支)读取到 desc 中。同时调试记录标识。

成功时返回 0,失败时返回负错误代码。

int drm_dp_dump_lttpr_desc(struct drm_dp_aux *aux, enum drm_dp_phy dp_phy)

读取并转储 LTTPR PHY 的 DPCD 描述符

参数

struct drm_dp_aux *aux

DisplayPort AUX 通道

enum drm_dp_phy dp_phy

LTTPR PHY 实例

描述

读取 dp_phy 的 DPCD LTTPR PHY 描述符,并在 dmesg 中打印一条包含其详细信息的调试消息。

成功时返回 0,失败时返回负错误代码。

u8 drm_dp_dsc_sink_bpp_incr(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE])

获取每像素位数增量

参数

const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE]

来自 DPCD 的 DSC 功能

描述

返回 DP 接收器支持的 bpp 精度。

u8 drm_dp_dsc_sink_max_slice_count(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE], bool is_edp)

获取 DSC 接收器支持的最大切片计数。

参数

const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE]

来自 DPCD 的 DSC 功能

bool is_edp

如果是 eDP 则为 true,如果是 DP 则为 false

描述

从 DSC 接收器读取切片功能 DPCD 寄存器以获取支持的最大切片计数。这用于在 struct drm_dsc_config 中填充 DSC 参数。驱动程序使用这些参数创建一个信息帧,以填充 struct drm_dsc_pps_infoframe。这些信息使用辅助函数 drm_dsc_pps_infoframe_pack() 通过 DSC 信息帧发送到接收器

返回

DSC 接收器支持的最大切片计数,如果无效则为 0

u8 drm_dp_dsc_sink_line_buf_depth(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE])

获取行缓冲区深度(以位为单位)

参数

const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE]

来自 DPCD 的 DSC 功能

描述

读取 DSC DPCD 寄存器以解析行缓冲区深度(以位为单位),这是 DSC 接收器支持的解码器行缓冲区内的精度位数。这用于在 struct drm_dsc_config 中填充 DSC 参数。驱动程序使用这些参数创建一个信息帧,以填充 struct drm_dsc_pps_infoframe。这些信息使用辅助函数 drm_dsc_pps_infoframe_pack() 通过 DSC 信息帧发送到接收器

返回

DSC 面板支持的行缓冲区深度,如果无效则为 0

int drm_dp_dsc_sink_supported_input_bpcs(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE], u8 dsc_bpc[3])

获取 DSC 接收器支持的所有每分量输入位数的值。

参数

const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE]

来自 DPCD 的 DSC 功能

u8 dsc_bpc[3]

此辅助函数将填充支持的输入 bpc 的数组。

描述

从接收器设备读取 DSC DPCD 以解析支持的每分量位数的值。这用于在 struct drm_dsc_config 中填充 DSC 参数。驱动程序使用这些参数创建一个信息帧,以填充 struct drm_dsc_pps_infoframe。这些信息使用辅助函数 drm_dsc_pps_infoframe_pack() 通过 DSC 信息帧发送到接收器

返回

从 DPCD 解析的输入 BPC 值的数量

int drm_dp_read_lttpr_common_caps(struct drm_dp_aux *aux, const u8 dpcd[DP_RECEIVER_CAP_SIZE], u8 caps[DP_LTTPR_COMMON_CAP_SIZE])

读取 LTTPR 公共功能

参数

struct drm_dp_aux *aux

DisplayPort AUX 通道

const u8 dpcd[DP_RECEIVER_CAP_SIZE]

DisplayPort 配置数据

u8 caps[DP_LTTPR_COMMON_CAP_SIZE]

用于返回功能信息的缓冲区

描述

读取所有 LTTPR 的通用功能。

成功时返回 0,失败时返回负错误代码。

int drm_dp_read_lttpr_phy_caps(struct drm_dp_aux *aux, const u8 dpcd[DP_RECEIVER_CAP_SIZE], enum drm_dp_phy dp_phy, u8 caps[DP_LTTPR_PHY_CAP_SIZE])

读取给定 LTTPR PHY 的功能

参数

struct drm_dp_aux *aux

DisplayPort AUX 通道

const u8 dpcd[DP_RECEIVER_CAP_SIZE]

DisplayPort 配置数据

enum drm_dp_phy dp_phy

要读取其功能的 LTTPR PHY

u8 caps[DP_LTTPR_PHY_CAP_SIZE]

用于返回功能信息的缓冲区

描述

读取给定 LTTPR PHY 的功能。

成功时返回 0,失败时返回负错误代码。

int drm_dp_lttpr_count(const u8 caps[DP_LTTPR_COMMON_CAP_SIZE])

获取检测到的 LTTPR 的数量

参数

const u8 caps[DP_LTTPR_COMMON_CAP_SIZE]

LTTPR 公共功能

描述

从 LTTPR 公共功能信息中获取检测到的 LTTPR 的数量。

返回

如果检测到的 LTTPR 数量超过支持的数量 (8),则返回 -ERANGE;如果 DP_PHY_REPEATER_CNT 寄存器包含无效值,则返回 -EINVAL;否则返回检测到的 LTTPR 的数量

获取所有 LTTPR 支持的最大链路速率

参数

const u8 caps[DP_LTTPR_COMMON_CAP_SIZE]

LTTPR 公共功能

描述

返回所有检测到的 LTTPR 支持的最大链路速率。

int drm_dp_lttpr_set_transparent_mode(struct drm_dp_aux *aux, bool enable)

将 LTTPR 设置为透明模式

参数

struct drm_dp_aux *aux

DisplayPort AUX 通道

bool enable

启用或禁用透明模式

返回

成功时为 0,失败时为负错误代码。

int drm_dp_lttpr_init(struct drm_dp_aux *aux, int lttpr_count)

根据 DP 标准初始化 LTTPR 透明模式

参数

struct drm_dp_aux *aux

DisplayPort AUX 通道

int lttpr_count

LTTPR 的数量。根据 DP 标准,数量介于 0 到 8 之间。对于任何无效数字,返回负的错误代码。请参阅 drm_dp_lttpr_count()

返回

成功时为 0,失败时为负错误代码。

int drm_dp_lttpr_max_lane_count(const u8 caps[DP_LTTPR_COMMON_CAP_SIZE])

获取所有 LTTPR 支持的最大通道数

参数

const u8 caps[DP_LTTPR_COMMON_CAP_SIZE]

LTTPR 公共功能

描述

返回所有检测到的 LTTPR 支持的最大通道数。

bool drm_dp_lttpr_voltage_swing_level_3_supported(const u8 caps[DP_LTTPR_PHY_CAP_SIZE])

检查 LTTPR vswing3 支持

参数

const u8 caps[DP_LTTPR_PHY_CAP_SIZE]

LTTPR PHY 功能

描述

如果 LTTPR TX PHY 的 caps 指示支持电压摆幅级别 3,则返回 true。

bool drm_dp_lttpr_pre_emphasis_level_3_supported(const u8 caps[DP_LTTPR_PHY_CAP_SIZE])

检查 LTTPR preemph3 支持

参数

const u8 caps[DP_LTTPR_PHY_CAP_SIZE]

LTTPR PHY 功能

描述

如果 LTTPR TX PHY 的 caps 指示支持预加重级别 3,则返回 true。

int drm_dp_get_phy_test_pattern(struct drm_dp_aux *aux, struct drm_dp_phy_test_params *data)

从接收器获取请求的模式。

参数

struct drm_dp_aux *aux

DisplayPort AUX 通道

struct drm_dp_phy_test_params *data

DP phy 一致性测试参数。

描述

成功时返回 0,失败时返回负错误代码。

int drm_dp_set_phy_test_pattern(struct drm_dp_aux *aux, struct drm_dp_phy_test_params *data, u8 dp_rev)

将模式设置为接收器。

参数

struct drm_dp_aux *aux

DisplayPort AUX 通道

struct drm_dp_phy_test_params *data

DP phy 一致性测试参数。

u8 dp_rev

用于一致性测试的 DP 修订版

描述

成功时返回 0,失败时返回负错误代码。

bool drm_dp_as_sdp_supported(struct drm_dp_aux *aux, const u8 dpcd[DP_RECEIVER_CAP_SIZE])

检查是否支持自适应同步 sdp

参数

struct drm_dp_aux *aux

DisplayPort AUX 通道

const u8 dpcd[DP_RECEIVER_CAP_SIZE]

DisplayPort 配置数据

描述

如果支持自适应同步 sdp,则返回 true,否则返回 false

bool drm_dp_vsc_sdp_supported(struct drm_dp_aux *aux, const u8 dpcd[DP_RECEIVER_CAP_SIZE])

检查是否支持 vsc sdp

参数

struct drm_dp_aux *aux

DisplayPort AUX 通道

const u8 dpcd[DP_RECEIVER_CAP_SIZE]

DisplayPort 配置数据

描述

如果支持 vsc sdp,则返回 true,否则返回 false

ssize_t drm_dp_vsc_sdp_pack(const struct drm_dp_vsc_sdp *vsc, struct dp_sdp *sdp)

将给定的 vsc sdp 打包到通用 dp_sdp 中

参数

const struct drm_dp_vsc_sdp *vsc

根据 DP 1.4a 规范中的表 2-118 - 表 2-120 中定义的用途初始化的 vsc sdp

struct dp_sdp *sdp

将打包到的通用 dp_sdp 的有效句柄

描述

成功时返回 sdp 的长度,失败时返回错误代码

int drm_dp_get_pcon_max_frl_bw(const u8 dpcd[DP_RECEIVER_CAP_SIZE], const u8 port_cap[4])

PCON 支持的最大 frl

参数

const u8 dpcd[DP_RECEIVER_CAP_SIZE]

DisplayPort 配置数据

const u8 port_cap[4]

端口功能

描述

返回 PCON 支持的最大 frl 带宽(以 GBPS 为单位),如果不支持,则返回 0。

int drm_dp_pcon_frl_prepare(struct drm_dp_aux *aux, bool enable_frl_ready_hpd)

为 FRL 准备 PCON。

参数

struct drm_dp_aux *aux

DisplayPort AUX 通道

bool enable_frl_ready_hpd

配置 DP_PCON_ENABLE_HPD_READY。

描述

如果成功,则返回 0;否则返回负的错误代码。

bool drm_dp_pcon_is_frl_ready(struct drm_dp_aux *aux)

PCON 是否为 FRL 准备就绪

参数

struct drm_dp_aux *aux

DisplayPort AUX 通道

描述

如果成功,则返回 true;否则返回 false。

int drm_dp_pcon_frl_configure_1(struct drm_dp_aux *aux, int max_frl_gbps, u8 frl_mode)

设置 HDMI LINK 配置 - 步骤 1

参数

struct drm_dp_aux *aux

DisplayPort AUX 通道

int max_frl_gbps

要在 PCON 和 HDMI 接收器之间配置的最大 frl bw

u8 frl_mode

FRL 训练模式,可以是并发或顺序。在并发模式下,FRL 链路启动可以与 DP 链路训练一起完成。在顺序模式下,FRL 链路启动在 DP 链路训练之前完成。

描述

如果成功,则返回 0;否则返回负的错误代码。

int drm_dp_pcon_frl_configure_2(struct drm_dp_aux *aux, int max_frl_mask, u8 frl_type)

设置 HDMI 链路配置步骤 2

参数

struct drm_dp_aux *aux

DisplayPort AUX 通道

int max_frl_mask

PCON 与 HDMI 接收器尝试的最大 FRL BW

u8 frl_type

FRL 训练类型,可以是扩展或正常。在正常 FRL 训练中,PCON 尝试从 max_frl_mask 开始的每个 frl bw(从最小值开始),并在链路训练成功时停止。在扩展 FRL 训练中,掩码中选择的所有 frl bw 都由 PCON 训练。

描述

如果成功,则返回 0;否则返回负的错误代码。

int drm_dp_pcon_reset_frl_config(struct drm_dp_aux *aux)

重新设置 HDMI 链路配置。

参数

struct drm_dp_aux *aux

DisplayPort AUX 通道

描述

如果成功,则返回 0;否则返回负的错误代码。

int drm_dp_pcon_frl_enable(struct drm_dp_aux *aux)

通过 FRL 启用 HDMI 链路

参数

struct drm_dp_aux *aux

DisplayPort AUX 通道

描述

如果成功,则返回 0;否则返回负的错误代码。

检查 PCON HDMI LINK 状态是否处于活动状态。

参数

struct drm_dp_aux *aux

DisplayPort AUX 通道

描述

如果链路处于活动状态,则返回 true,否则返回 false。

获取 PCON HDMI LINK MODE

参数

struct drm_dp_aux *aux

DisplayPort AUX 通道

u8 *frl_trained_mask

指向存储训练的 bw 配置的位掩码的指针。仅当返回的 MODE 为 FRL 时有效。对于普通链路训练模式,仅设置 1 位,但在扩展模式下,可以设置多位。

描述

如果成功,则返回链路模式:TMDS 或 FRL,否则返回负的错误代码。

打印 PCON 和 HDMI 接收器之间链路故障期间每个通道的错误计数

参数

struct drm_dp_aux *aux

DisplayPort AUX 通道

struct drm_connector *connector

DRM 连接器代码。

int drm_dp_pcon_pps_default(struct drm_dp_aux *aux)

让 PCON 填充 PCON 和 HDMI2.1 接收器之间 DSC1.2 的默认 pps 参数

参数

struct drm_dp_aux *aux

DisplayPort AUX 通道

描述

成功时返回 0,否则返回负的错误代码。

int drm_dp_pcon_pps_override_buf(struct drm_dp_aux *aux, u8 pps_buf[128])

为 HDMI sink 配置 PPS 编码器覆盖缓冲区

参数

struct drm_dp_aux *aux

DisplayPort AUX 通道

u8 pps_buf[128]

128 字节将被 PCON 写入到 HDMI sink 的 PPS 缓冲区中。

描述

成功时返回 0,否则返回负的错误代码。

int drm_edp_backlight_set_level(struct drm_dp_aux *aux, const struct drm_edp_backlight_info *bl, u16 level)

通过 AUX 设置 eDP 面板的背光级别

参数

struct drm_dp_aux *aux

要使用的 DP AUX 通道

const struct drm_edp_backlight_info *bl

来自 drm_edp_backlight_init() 的背光功能信息

u16 level

要设置的亮度级别

描述

设置 eDP 面板背光的亮度级别。 请注意,面板的背光必须已由驱动程序通过调用 drm_edp_backlight_enable() 启用。

返回

成功时返回 0,失败时返回负错误代码

int drm_edp_backlight_enable(struct drm_dp_aux *aux, const struct drm_edp_backlight_info *bl, const u16 level)

使用 DPCD 启用 eDP 面板的背光

参数

struct drm_dp_aux *aux

要使用的 DP AUX 通道

const struct drm_edp_backlight_info *bl

来自 drm_edp_backlight_init() 的背光功能信息

const u16 level

如果存在,通过 AUX 设置的初始背光级别

描述

此函数处理通过 DPCD 在面板上启用 DPCD 背光控制,同时恢复任何重要的背光状态,例如给定的背光级别、亮度字节计数、背光频率等。

请注意,某些面板不支持通过 DPCD 启用或禁用,而是需要驱动程序通过使用 EDP_BL_PWR GPIO 的特定于实现的手段来处理面板的启用/禁用。 对于此类面板,drm_edp_backlight_info.aux_enable 将设置为 false,此函数变为无操作,并且驱动程序应使用 EDP_BL_PWR GPIO 处理面板的供电。

返回

成功时返回 0,失败时返回负错误代码。

int drm_edp_backlight_disable(struct drm_dp_aux *aux, const struct drm_edp_backlight_info *bl)

如果支持,使用 DPCD 禁用 eDP 背光

参数

struct drm_dp_aux *aux

要使用的 DP AUX 通道

const struct drm_edp_backlight_info *bl

来自 drm_edp_backlight_init() 的背光功能信息

描述

此函数处理通过 AUX 在面板上禁用 DPCD 背光控制。

请注意,某些面板不支持通过 DPCD 启用或禁用,而是需要驱动程序通过使用 EDP_BL_PWR GPIO 的特定于实现的手段来处理面板的启用/禁用。 对于此类面板,drm_edp_backlight_info.aux_enable 将设置为 false,此函数变为无操作,并且驱动程序应使用 EDP_BL_PWR GPIO 处理面板的断电。

返回

成功或无操作时返回 0,失败时返回负错误代码。

int drm_edp_backlight_init(struct drm_dp_aux *aux, struct drm_edp_backlight_info *bl, u16 driver_pwm_freq_hz, const u8 edp_dpcd[EDP_DISPLAY_CTL_CAP_SIZE], u16 *current_level, u8 *current_mode)

使用标准的 VESA eDP 背光接口探测显示面板的 TCON。

参数

struct drm_dp_aux *aux

用于探测的 DP aux 设备

struct drm_edp_backlight_info *bl

要用背光信息填充的 drm_edp_backlight_info 结构体

u16 driver_pwm_freq_hz

驱动程序中的可选 PWM 频率,单位为 Hz

const u8 edp_dpcd[EDP_DISPLAY_CTL_CAP_SIZE]

eDP DPCD 的缓存副本

u16 *current_level

如果存在,在哪里存储探测到的亮度级别

u8 *current_mode

在哪里存储当前设置的背光控制模式

描述

通过探测 aux 的背光功能来初始化 drm_edp_backlight_info 结构体,同时还探测当前和最大支持的亮度级别。

如果 driver_pwm_freq_hz 为非零值,则将使用它作为背光频率。 否则,将使用面板的默认频率。

返回

成功时返回 0,失败时返回负错误代码。

int drm_panel_dp_aux_backlight(struct drm_panel *panel, struct drm_dp_aux *aux)

创建并使用 DP AUX 背光

参数

struct drm_panel *panel

DRM 面板

struct drm_dp_aux *aux

要使用的 DP AUX 通道

描述

如果您的面板支持通过 DP AUX 通道使用 DPCD 寄存器按照 VESA 的标准背光控制接口进行背光控制,请使用此函数创建和处理背光。

当面板启用时,在成功调用 drm_panel_funcs.enable() 后将启用背光

当面板禁用时,在调用 drm_panel_funcs.disable() 之前将禁用背光。

支持通过 DP AUX 进行背光控制的面板驱动程序的典型实现将在探测时调用此函数。 然后将透明地处理背光,而无需驱动程序的任何干预。

drm_panel_dp_aux_backlight() 必须在调用 drm_panel_init() 之后调用。

返回

成功时为 0,失败时为负错误代码。

计算有/无 DSC 的链路符号计数

参数

int lane_count

DP 链路通道数

int pixels

扫描线中的像素数

int dsc_slice_count

DSC 的切片数,如果不是 DSC,则为“0”

int bpp_x16

像素的位数,采用 .4 二进制固定格式

int symbol_size

DP 符号大小

bool is_mst

MST 为 true,SST 为 false

描述

计算 DSC (dsc_slice_count !=0) 和非 DSC 情况 (dsc_slice_count == 0) 的链路符号周期,并返回计数。

int drm_dp_bw_overhead(int lane_count, int hactive, int dsc_slice_count, int bpp_x16, unsigned long flags)

计算 DP 链路流的带宽开销

参数

int lane_count

DP 链路通道数

int hactive

流的一个扫描线中活动周期的像素计数

int dsc_slice_count

DSC 的切片数,如果不是 DSC,则为“0”

int bpp_x16

以 .4 二进制定点表示的每像素位数

unsigned long flags

DRM_DP_OVERHEAD_x 标志

描述

计算 DP 链路流的带宽分配开销,具体取决于链路的 - lane_count - SST/MST 模式(flags / DRM_DP_OVERHEAD_MST)- 符号大小(flags / DRM_DP_OVERHEAD_UHBR)- FEC 模式(flags / DRM_DP_OVERHEAD_FEC)- SSC/REF_CLK 模式(flags / DRM_DP_OVERHEAD_SSC_REF_CLK)以及流的 - hactive 时序 - bpp_x16 颜色深度 - 压缩模式(dsc_slice_count != 0)请注意,此开销不考虑 8b/10b、128b/132b 通道编码效率,有关更多信息,请参见 drm_dp_link_bw_channel_coding_efficiency()

以 1ppm 为单位返回以 100% + 开销% 表示的开销。

int drm_dp_bw_channel_coding_efficiency(bool is_uhbr)

获取 DP 链路的通道编码效率

参数

bool is_uhbr

链路是否具有 128b/132b 通道编码

描述

返回给定 DP 链路类型的通道编码效率,该类型为 8b/10b 或 128b/132b(又名 UHBR)。 相应的开销包括 8b -> 10b、128b -> 132b 像素数据到链路符号的转换开销,以及对于 128b/132b 的任何链路或 PHY 级别控制符号插入开销(LLCP、FEC、PHY 同步,请参见 DP 标准 v2.1 3.5.2.18)。 对于 8b/10b,相应的 FEC 开销是 BW 分配特定的,包含在 drm_dp_bw_overhead() 返回的值中。

以 1ppm 为单位返回 100%/编码开销% 比率的效率。

int drm_dp_max_dprx_data_rate(int max_link_rate, int max_lanes)

获取 DPRX sink 的最大数据带宽

参数

int max_link_rate

最大 DPRX 链路速率,单位为 10kbps

int max_lanes

最大 DPRX 通道数

描述

给定链路速率和通道数,获取数据带宽。

数据带宽是实际的有效负载速率,它取决于数据带宽效率和链路速率。

请注意,此处考虑的 DPRX 链路级别之上的协议层可以进一步限制最大数据速率。 此类层是 MST 拓扑(限制源和第一个分支设备之间的链路以及直到 DPRX 链路的整个 MST 路径)和(Thunderbolt)DP 隧道 - 依次可以封装具有其自身限制的 MST 链路 - 每个 SST 或 MST 封装的隧道共享隧道组的带宽。

以 kBps 为单位返回最大数据速率。

Display Port CEC 帮助程序函数参考

这些函数负责支持 DisplayPort 到 HDMI 适配器的 CEC-Tunneling-over-AUX 功能。

void drm_dp_cec_irq(struct drm_dp_aux *aux)

处理 CEC 中断(如果有)

参数

struct drm_dp_aux *aux

DisplayPort AUX 通道

描述

应在处理 IRQ_HPD 请求时调用。 如果存在 CEC-tunneling-over-AUX,则它将检查 CEC_IRQ 并进行相应处理。

void drm_dp_cec_register_connector(struct drm_dp_aux *aux, struct drm_connector *connector)

注册新连接器

参数

struct drm_dp_aux *aux

DisplayPort AUX 通道

struct drm_connector *connector

drm 连接器

描述

已注册一个新连接器,其中包含关联的 CEC 适配器名称和 CEC 适配器父设备。 在注册名称和父级之后,将调用 drm_dp_cec_set_edid() 以检查连接器是否支持 CEC,并在支持的情况下注册 CEC 适配器。

void drm_dp_cec_unregister_connector(struct drm_dp_aux *aux)

注销 CEC 适配器(如果有)

参数

struct drm_dp_aux *aux

DisplayPort AUX 通道

Display Port 双模适配器帮助程序函数参考

用于处理 DP 双模(又名 DP++)适配器的帮助程序函数。

类型 1:适配器寄存器(如果有)和 sink DDC 总线可以通过 I2C 访问。

类型 2:可以通过 I2C 或 I2C-over-AUX 访问适配器寄存器和 sink DDC 总线。 源设备可以选择实现这些访问方法中的任何一种。

enum drm_lspcon_mode

常量

DRM_LSPCON_MODE_INVALID

没有 LSPCON。

DRM_LSPCON_MODE_LS

LSPCON 的电平转换器模式,将 DP++ 驱动为 HDMI 1.4 转换。

DRM_LSPCON_MODE_PCON

LSPCON 的协议转换器模式,将 DP++ 驱动为 HDMI 2.0 主动转换。

enum drm_dp_dual_mode_type

DP 双模适配器的类型

常量

DRM_DP_DUAL_MODE_NONE

没有 DP 双模适配器

DRM_DP_DUAL_MODE_UNKNOWN

可能是无适配器或类型 1 DVI 适配器

DRM_DP_DUAL_MODE_TYPE1_DVI

类型 1 DVI 适配器

DRM_DP_DUAL_MODE_TYPE1_HDMI

类型 1 HDMI 适配器

DRM_DP_DUAL_MODE_TYPE2_DVI

类型 2 DVI 适配器

DRM_DP_DUAL_MODE_TYPE2_HDMI

类型 2 HDMI 适配器

DRM_DP_DUAL_MODE_LSPCON

电平转换器 / 协议转换器

ssize_t drm_dp_dual_mode_read(struct i2c_adapter *adapter, u8 offset, void *buffer, size_t size)

从 DP 双模适配器寄存器读取

参数

struct i2c_adapter *adapter

DDC 总线的 I2C 适配器

u8 offset

寄存器偏移

void *buffer

用于返回数据的缓冲区

size_t size

缓冲区的大小

描述

从 DP 双模适配器寄存器中,从 offset 开始读取 size 字节。

返回

成功时返回 0,失败时返回负错误代码

ssize_t drm_dp_dual_mode_write(struct i2c_adapter *adapter, u8 offset, const void *buffer, size_t size)

写入 DP 双模适配器寄存器

参数

struct i2c_adapter *adapter

DDC 总线的 I2C 适配器

u8 offset

寄存器偏移

const void *buffer

写入数据的缓冲区

size_t size

缓冲区的大小

描述

size 字节写入到 DP 双模适配器寄存器中,从 offset 开始。

返回

成功时返回 0,失败时返回负错误代码

enum drm_dp_dual_mode_type drm_dp_dual_mode_detect(const struct drm_device *dev, struct i2c_adapter *adapter)

识别 DP 双模适配器

参数

const struct drm_device *dev

要使用的 drm_device

struct i2c_adapter *adapter

DDC 总线的 I2C 适配器

描述

尝试识别所使用的 DP 双模适配器的类型。

请注意,当答案为 DRM_DP_DUAL_MODE_UNKNOWN 时,不能确定我们是在处理本机 HDMI 端口还是类型 1 DVI 双模适配器。 驱动程序必须使用一些其他硬件/驱动程序特定的机制来进行区分。

返回

所使用的 DP 双模适配器的类型

int drm_dp_dual_mode_max_tmds_clock(const struct drm_device *dev, enum drm_dp_dual_mode_type type, struct i2c_adapter *adapter)

DP 双模适配器的最大 TMDS 时钟

参数

const struct drm_device *dev

要使用的 drm_device

enum drm_dp_dual_mode_type type

DP 双模适配器类型

struct i2c_adapter *adapter

DDC 总线的 I2C 适配器

描述

根据双模适配器的类型和 DP_DUAL_MODE_MAX_TMDS_CLOCK 寄存器(在 type2 适配器上)确定适配器支持的最大 TMDS 时钟。 由于某些类型 1 适配器存在寄存器问题(请参见 drm_dp_dual_mode_detect() 中的注释),因此我们不会在这些适配器上读取寄存器,而是简单地基于规范假设 165 MHz 的限制。

返回

DP 双模适配器支持的最大 TMDS 时钟速率,单位为 kHz。

int drm_dp_dual_mode_get_tmds_output(const struct drm_device *dev, enum drm_dp_dual_mode_type type, struct i2c_adapter *adapter, bool *enabled)

获取 DP 双模适配器中 TMDS 输出缓冲区的状态

参数

const struct drm_device *dev

要使用的 drm_device

enum drm_dp_dual_mode_type type

DP 双模适配器类型

struct i2c_adapter *adapter

DDC 总线的 I2C 适配器

bool *enabled

TMDS 输出缓冲区的当前状态

描述

获取适配器中 TMDS 输出缓冲区的状态。 对于 type2 适配器,这是从 DP_DUAL_MODE_TMDS_OEN 寄存器查询的。 由于某些类型 1 适配器存在寄存器问题(请参见 drm_dp_dual_mode_detect() 中的注释),因此我们不会在这些适配器上读取寄存器,而是简单地假设始终启用缓冲区。

返回

成功时返回 0,失败时返回负错误代码

int drm_dp_dual_mode_set_tmds_output(const struct drm_device *dev, enum drm_dp_dual_mode_type type, struct i2c_adapter *adapter, bool enable)

启用/禁用 DP 双模适配器中的 TMDS 输出缓冲区

参数

const struct drm_device *dev

要使用的 drm_device

enum drm_dp_dual_mode_type type

DP 双模适配器类型

struct i2c_adapter *adapter

DDC 总线的 I2C 适配器

bool enable

启用(而不是禁用)TMDS 输出缓冲区

描述

设置适配器中 TMDS 输出缓冲区的状态。 对于 type2,这是通过 DP_DUAL_MODE_TMDS_OEN 寄存器设置的。 类型 1 适配器不支持任何寄存器写入。

返回

成功时返回 0,失败时返回负错误代码

const char *drm_dp_get_dual_mode_type_name(enum drm_dp_dual_mode_type type)

获取 DP 双模适配器类型的名称,作为字符串

参数

enum drm_dp_dual_mode_type type

DP 双模适配器类型

返回

DP 双模适配器类型的字符串表示形式

int drm_lspcon_get_mode(const struct drm_device *dev, struct i2c_adapter *adapter, enum drm_lspcon_mode *mode)

通过读取偏移量 (0x80, 0x41) 获取 LSPCON 的当前工作模式

参数

const struct drm_device *dev

要使用的 drm_device

struct i2c_adapter *adapter

I2C-over-aux 适配器

enum drm_lspcon_mode *mode

当前 lspcon 工作模式输出变量

返回

成功时返回 0,将 current_mode 值设置为适当的模式 - 失败时返回错误

int drm_lspcon_set_mode(const struct drm_device *dev, struct i2c_adapter *adapter, enum drm_lspcon_mode mode, int time_out)

通过写入偏移量 (0x80, 0x40) 更改 LSPCON 的工作模式

参数

const struct drm_device *dev

要使用的 drm_device

struct i2c_adapter *adapter

I2C-over-aux 适配器

enum drm_lspcon_mode mode

所需的工作模式

int time_out

LSPCON 模式更改稳定超时

返回

成功时返回 0,失败/超时时返回 -错误

Display Port MST 帮助程序

概述

这些函数包含 DisplayPort 1.2a MultiStream Transport 协议的部分内容。这些辅助函数包含拓扑管理器和带宽管理器。这些辅助函数封装了边带消息的发送和接收。

拓扑引用计数概述

struct drm_dp_mst_branchstruct drm_dp_mst_port 的引用计数方案有些不寻常。端口和分支设备都有两种不同类型的引用计数:拓扑引用计数和 malloc 引用计数。

拓扑引用计数不会暴露给驱动程序,而是由 DP MST 辅助函数在内部处理。辅助函数使用它们来防止内存中的拓扑状态在关键操作(例如更改有效负载分配的内部状态)期间被更改。这意味着每个分支和端口都将被视为已连接到拓扑的其余部分,直到其拓扑引用计数达到零。此外,对于端口,这意味着它们的关联 struct drm_connector 将保持向用户空间注册,直到端口的引用计数达到 0。

Malloc 引用计数概述

Malloc 引用用于保持 struct drm_dp_mst_portstruct drm_dp_mst_branch 在其所有拓扑引用都已删除后仍然分配,以便驱动程序或 MST 辅助函数可以安全地访问每个分支从拓扑中断开连接之前的最后已知状态。当端口或分支的 malloc 引用计数达到 0 时,包含 struct drm_dp_mst_branchstruct drm_dp_mst_port 的内存分配将分别被释放。

对于 struct drm_dp_mst_branch,malloc 引用计数当前未暴露给驱动程序。在编写此文档时,没有任何驱动程序有在 MST 辅助函数之外访问 struct drm_dp_mst_branch 的用例。以无竞争的方式将此 API 暴露给驱动程序需要更多地调整引用计数方案,但是如果有一个合法的驱动程序用例,则欢迎补丁。

拓扑中的引用计数关系

让我们看看为什么拓扑和 malloc 引用计数之间的关系被设计成现在这样。

../_images/topology-figure-1.svg

具有两个活动有效负载的 DP MST 拓扑中的拓扑和 malloc 引用的示例。拓扑引用计数增量用实线表示,malloc 引用计数增量用虚线表示。每个引用计数都从增加引用计数的分支开始,到引用计数所属的分支结束,即箭头指向与用于引用结构的 C 指针相同的方向。

如上图所示,每个分支都会增加其子节点的拓扑引用计数,并增加其父节点的 malloc 引用计数。此外,每个有效负载都会将其分配端口的 malloc 引用计数增加 1。

那么,如果从系统中拔下上图中的 MSTB #3,但驱动程序尚未从端口 #3 中删除有效负载 #2,会发生什么?拓扑将开始如下图所示。

../_images/topology-figure-2.svg

已从内存中释放的端口和分支设备着色为灰色,已删除的引用着色为红色。

每当端口或分支设备的拓扑引用计数达到零时,它将减少其所有子节点的拓扑引用计数、其父节点的 malloc 引用计数,最后是它自己的 malloc 引用计数。对于 MSTB #4 和端口 #4,这意味着它们都已与拓扑断开连接并从内存中释放。但是,由于有效负载 #2 仍然持有对端口 #3 的引用,因此端口 #3 将从拓扑中删除,但其 struct drm_dp_mst_port 仍然可以从内存中访问。这也意味着端口 #3 尚未减少 MSTB #3 的 malloc 引用计数,因此其 struct drm_dp_mst_branch 也将保持在内存中分配,直到端口 #3 的 malloc 引用计数达到 0。

这种关系是必要的,因为为了释放有效负载 #2,我们需要能够确定仍然连接到拓扑的端口 #3 的最后一个相关项。在这种情况下,我们将如下图所示地遍历拓扑。

../_images/topology-figure-3.svg

最后,通过与端口 #2 的边带事务来删除有效负载 #2。

函数参考

struct drm_dp_mst_port

MST 端口

定义:

struct drm_dp_mst_port {
    struct kref topology_kref;
    struct kref malloc_kref;
#if IS_ENABLED(CONFIG_DRM_DEBUG_DP_MST_TOPOLOGY_REFS);
    struct drm_dp_mst_topology_ref_history topology_ref_history;
#endif;
    u8 port_num;
    bool input;
    bool mcs;
    bool ddps;
    u8 pdt;
    bool ldps;
    u8 dpcd_rev;
    u8 num_sdp_streams;
    u8 num_sdp_stream_sinks;
    uint16_t full_pbn;
    struct list_head next;
    struct drm_dp_mst_branch *mstb;
    struct drm_dp_aux aux;
    struct drm_dp_aux *passthrough_aux;
    struct drm_dp_mst_branch *parent;
    struct drm_connector *connector;
    struct drm_dp_mst_topology_mgr *mgr;
    const struct drm_edid *cached_edid;
    bool fec_capable;
};

成员

topology_kref

此端口在拓扑中的生存期的引用计数,只有 DP MST 辅助函数需要触及此计数

malloc_kref

包含此结构的内存分配的引用计数。请参阅 drm_dp_mst_get_port_malloc()drm_dp_mst_put_port_malloc()

topology_ref_history

每个拓扑引用/解引用的历史记录。请参阅 CONFIG_DRM_DEBUG_DP_MST_TOPOLOGY_REFS。

port_num

端口号

input

如果此端口是输入端口。受 drm_dp_mst_topology_mgr.base.lock 保护。

mcs

消息能力状态 - DP 1.2 规范。受 drm_dp_mst_topology_mgr.base.lock 保护。

ddps

DisplayPort 设备插入状态 - DP 1.2。受 drm_dp_mst_topology_mgr.base.lock 保护。

pdt

对等设备类型。受 drm_dp_mst_topology_mgr.base.lock 保护。

ldps

旧版设备插入状态。受 drm_dp_mst_topology_mgr.base.lock 保护。

dpcd_rev

此端口上设备的 DPCD 修订版。受 drm_dp_mst_topology_mgr.base.lock 保护。

num_sdp_streams

并发流的数量。受 drm_dp_mst_topology_mgr.base.lock 保护。

num_sdp_stream_sinks

流接收器的数量。受 drm_dp_mst_topology_mgr.base.lock 保护。

full_pbn

此端口的最大可能带宽。受 drm_dp_mst_topology_mgr.base.lock 保护。

next

指向此分支设备上下一个端口的链接

mstb

连接到此端口的分支设备(如果有)。应认为受 drm_dp_mst_topology_mgr.lock 保护以进行读取。对此有两个例外:drm_dp_mst_topology_mgr.up_req_workdrm_dp_mst_topology_mgr.work,它们在读取期间不会获取 drm_dp_mst_topology_mgr.lock,但它们是此列表的唯一更新程序,并且通过 drm_dp_mst_topology_mgr.probe_lock 保护免受并发写入。

aux

与连接到此端口的设备通信的 i2c aux 传输,受 drm_dp_mst_topology_mgr.base.lock 保护。

passthrough_aux

应将 DSC 直通请求发送到的父 aux,仅在 DSC 直通可行时设置。

parent

此端口的分支设备父设备

connector

此端口连接到的 DRM 连接器。受 drm_dp_mst_topology_mgr.base.lock 保护。

mgr

此端口所属的拓扑管理器。

cached_edid

对于 DP 逻辑端口 - 通过确保立即读取所有连接器的 EDID 来实现平铺。

fec_capable

指示 FEC 是否可以在 MST 拓扑中支持到该点的布尔值。

描述

此结构表示 MST 拓扑中某处设备上的 MST 端口端点。

struct drm_dp_mst_branch

MST 分支设备。

定义:

struct drm_dp_mst_branch {
    struct kref topology_kref;
    struct kref malloc_kref;
#if IS_ENABLED(CONFIG_DRM_DEBUG_DP_MST_TOPOLOGY_REFS);
    struct drm_dp_mst_topology_ref_history topology_ref_history;
#endif;
    struct list_head destroy_next;
    u8 rad[8];
    u8 lct;
    int num_ports;
    struct list_head ports;
    struct drm_dp_mst_port *port_parent;
    struct drm_dp_mst_topology_mgr *mgr;
    bool link_address_sent;
    guid_t guid;
};

成员

topology_kref

此分支设备在拓扑中的生存期的引用计数,只有 DP MST 辅助函数需要触及此计数

malloc_kref

包含此结构的内存分配的引用计数。请参阅 drm_dp_mst_get_mstb_malloc()drm_dp_mst_put_mstb_malloc()

topology_ref_history

每个拓扑引用/解引用的历史记录。请参阅 CONFIG_DRM_DEBUG_DP_MST_TOPOLOGY_REFS。

destroy_next

drm_dp_delayed_destroy_work() 使用的链表条目

rad

MST 分支的相对地址。对于 drm_dp_mst_topology_mgr.mst_primary,其 rad[8] 全为 0,未设置且未使用。对于在 mst_primary 之后连接的 MST 分支,在 rad[] 的每个元素中,nibbles 按最重要的 4 位在前,最不重要的 4 位在后的顺序排列。

lct

与此分支设备通信的链接总计数。

num_ports

分支上的端口数。

ports

此分支设备上的端口列表。应认为受 drm_dp_mst_topology_mgr.lock 保护以进行读取。对此有两个例外:drm_dp_mst_topology_mgr.up_req_workdrm_dp_mst_topology_mgr.work,它们在读取期间不会获取 drm_dp_mst_topology_mgr.lock,但它们是此列表的唯一更新程序,并且通过 drm_dp_mst_topology_mgr.probe_lock 保护免受并发更新列表。

port_parent

指向端口父设备的指针,如果是顶层则为 NULL。

mgr

此分支设备的拓扑管理器。

link_address_sent

是否已将链接地址消息发送到此设备。

guid

DP 1.2 分支设备的 guid。此分支下的端口可以通过端口号识别。

描述

此结构表示 MST 分支设备,根目录上有一个主分支设备,以及连接到父分支下游端口的任何其他分支。

struct drm_dp_mst_atomic_payload

MST 有效负载的原子状态结构

定义:

struct drm_dp_mst_atomic_payload {
    struct drm_dp_mst_port *port;
    s8 vc_start_slot;
    u8 vcpi;
    int time_slots;
    int pbn;
    bool delete : 1;
    bool dsc_enabled : 1;
    enum drm_dp_mst_payload_allocation payload_allocation_status;
    struct list_head next;
};

成员

port

分配给此有效负载的 MST 端口

vc_start_slot

此有效负载开始的时隙。由于有效负载起始时隙无法提前确定,因此在原子检查时此值的内容为 UNDEFINED。这通常无关紧要,因为起始时隙对于原子状态计算永远不应相关。

由于此值是在提交时而不是在检查时确定的,因此此值受 MST 辅助函数的保护,这些辅助函数确保对给定拓扑进行操作的异步提交永远不会并行运行。如果驱动程序确实需要读取此值(例如,通知硬件有效负载的起始时隙),则驱动程序可以

如果以上两种解决方案都不足够(例如,驱动程序出于某种原因需要在原子提交的中间读取起始时隙而不等待),则驱动程序应在更改有效负载后自行缓存此值。

vcpi

虚拟通道有效负载标识符

time_slots

从源 DP Tx 到直接下游 DP Rx 分配给此有效负载的时隙数

pbn

此有效负载的有效负载带宽

delete

我们是否打算在此原子提交期间删除此有效负载

dsc_enabled

是否为此有效负载启用了 DSC

payload_allocation_status

此有效负载的分配状态

next

此有效负载的链表节点

描述

给定 MST 有效负载的主原子状态结构。存储诸如当前带宽分配、此有效负载的预期操作等信息。

struct drm_dp_mst_topology_state

DisplayPort MST 拓扑原子状态

定义:

struct drm_dp_mst_topology_state {
    struct drm_private_state base;
    struct drm_dp_mst_topology_mgr *mgr;
    u32 pending_crtc_mask;
    struct drm_crtc_commit **commit_deps;
    size_t num_commit_deps;
    u32 payload_mask;
    struct list_head payloads;
    u8 total_avail_slots;
    u8 start_slot;
    fixed20_12 pbn_div;
};

成员

基础

原子的基本私有状态

mgr

拓扑管理器

pending_crtc_mask

此拓扑状态触及的所有 CRTC 的位掩码,如果需要,驱动程序可以修改此掩码以添加其他依赖项。

commit_deps

影响此拓扑的所有 CRTC 提交的列表,此字段在调用 drm_dp_mst_atomic_wait_for_dependencies() 之前不会填充。

num_commit_deps

commit_deps 中的 CRTC 提交的数量

payload_mask

已分配 VCPI 的位掩码,用于 VCPI 分配

payloads

在此状态下创建/销毁的有效负载列表

total_avail_slots

此拓扑可以处理的总时隙数(63 或 64)

start_slot

此拓扑中的第一个可用时隙(1 或 0)

pbn_div

此拓扑的当前 PBN 除数。驱动程序应自行填充此值。

描述

此结构表示顶层 DisplayPort MST 管理器的原子状态

struct drm_dp_mst_topology_mgr

DisplayPort MST 管理器

定义:

struct drm_dp_mst_topology_mgr {
    struct drm_private_obj base;
    struct drm_device *dev;
    const struct drm_dp_mst_topology_cbs *cbs;
    int max_dpcd_transaction_bytes;
    struct drm_dp_aux *aux;
    int max_payloads;
    int conn_base_id;
    struct drm_dp_sideband_msg_rx up_req_recv;
    struct drm_dp_sideband_msg_rx down_rep_recv;
    struct mutex lock;
    struct mutex probe_lock;
    bool mst_state : 1;
    bool payload_id_table_cleared : 1;
    bool reset_rx_state : 1;
    u8 payload_count;
    u8 next_start_slot;
    struct drm_dp_mst_branch *mst_primary;
    u8 dpcd[DP_RECEIVER_CAP_SIZE];
    u8 sink_count;
    const struct drm_private_state_funcs *funcs;
    struct mutex qlock;
    struct list_head tx_msg_downq;
    wait_queue_head_t tx_waitq;
    struct work_struct work;
    struct work_struct tx_work;
    struct list_head destroy_port_list;
    struct list_head destroy_branch_device_list;
    struct mutex delayed_destroy_lock;
    struct workqueue_struct *delayed_destroy_wq;
    struct work_struct delayed_destroy_work;
    struct list_head up_req_list;
    struct mutex up_req_lock;
    struct work_struct up_req_work;
#if IS_ENABLED(CONFIG_DRM_DEBUG_DP_MST_TOPOLOGY_REFS);
    struct mutex topology_ref_history_lock;
#endif;
};

成员

基础

原子的基本私有对象

dev

用于添加 i2c 设备等的设备指针。

cbs

用于连接器添加和销毁的回调。

max_dpcd_transaction_bytes

一次读取/写入的最大字节数。

aux

用于此拓扑管理器控制的 DP MST 连接器的 AUX 通道。

max_payloads

GPU 可以生成的最大有效负载数。

conn_base_id

此管理器连接到的 DRM 连接器 ID。仅用于构建 MST 连接器路径值。

up_req_recv

上行请求的消息接收器状态。

down_rep_recv

下行请求回复的消息接收器状态。

lock

保护 mst_statemst_primarydpcdpayload_id_table_cleared

probe_lock

防止 workup_req_workdrm_dp_mst_port.mstbdrm_dp_mst_branch.ports 的唯一写入器)在更新拓扑时发生竞争。

mst_state

此管理器是否为支持 MST 的端口启用。如果未连接 MST 接收器/分支设备,则为 False。

payload_id_table_cleared

我们是否已清除 mst_primary 的有效负载 ID 表。受 lock 保护。

reset_rx_state

在删除拓扑管理器后,必须重置下行请求的回复和上行请求消息接收器状态。受 lock 保护。

payload_count

硬件中当前活动有效负载的数量。此值仅供 MST 辅助函数在内部用于有效负载跟踪,并且只能从原子提交(而非检查)上下文中安全地读取/写入。

next_start_slot

用于新 VC 有效负载的起始时隙。此值由 MST 辅助函数在内部用于有效负载跟踪,并且只能从原子提交(而非检查)上下文中安全地读取/写入。

mst_primary

指向主/第一个分支设备的指针。

dpcd

主端口的 DPCD 缓存。

sink_count

来自 DEVICE_SERVICE_IRQ_VECTOR_ESI0 的接收器计数。

funcs

原子辅助函数回调

qlock

保护 tx_msg_downqdrm_dp_sideband_msg_tx.state

tx_msg_downq

挂起的下行请求列表

tx_waitq

等待 tx worker 的队列停顿。

work

探测工作。

tx_work

边带传输 worker。这可以在主 work worker 中嵌套,用于 work 启动的每个事务。

destroy_port_list

要销毁的连接器列表。

destroy_branch_device_list

要销毁的分支设备列表。

delayed_destroy_lock

保护 destroy_port_listdestroy_branch_device_list

delayed_destroy_wq

用于 delayed_destroy_work 项的工作队列。专用 WQ 使排空其上任何重新排队的工作项成为可能。

delayed_destroy_work

用于销毁 MST 端口和分支设备的工作项,需要避免锁定反转。

up_req_list

来自拓扑的挂起上行请求列表,需要按时间顺序处理。

up_req_lock

保护 up_req_list

up_req_work

用于处理从拓扑接收的上行请求的工作项。需要避免阻止热插拔处理和边带传输。

topology_ref_history_lock

保护 drm_dp_mst_port.topology_ref_historydrm_dp_mst_branch.topology_ref_history

描述

此结构表示顶层 displayport MST 拓扑管理器。对于 GPU 上的每个支持 MST 的 DP 连接器,都应有一个此结构的实例。

enum drm_dp_mst_mode

接收器的 MST 模式能力

常量

DRM_DP_SST

接收器不支持 MST 也不支持单流边带消息。

DRM_DP_MST

接收器支持 MST、多个流和单流边带消息。

DRM_DP_SST_SIDEBAND_MSG

接收器仅支持一个流和单流边带消息。

bool __drm_dp_mst_state_iter_get(struct drm_atomic_state *state, struct drm_dp_mst_topology_mgr **mgr, struct drm_dp_mst_topology_state **old_state, struct drm_dp_mst_topology_state **new_state, int i)

用于宏内部使用的私有原子状态迭代器函数

参数

struct drm_atomic_state *state

struct drm_atomic_state 指针

struct drm_dp_mst_topology_mgr **mgr

指向 struct drm_dp_mst_topology_mgr 迭代光标的指针

struct drm_dp_mst_topology_state **old_state

指向旧 struct drm_dp_mst_topology_state 迭代光标的可选指针

struct drm_dp_mst_topology_state **new_state

指向新 struct drm_dp_mst_topology_state 迭代光标的可选指针

int i

int 迭代光标,用于宏内部使用

描述

for_each_oldnew_mst_mgr_in_state()for_each_old_mst_mgr_in_state()for_each_new_mst_mgr_in_state() 使用。不要直接调用此函数。

返回

如果当前 struct drm_private_objstruct drm_dp_mst_topology_mgr,则为 True,否则为 False。

for_each_oldnew_mst_mgr_in_state

for_each_oldnew_mst_mgr_in_state (__state, mgr, old_state, new_state, __i)

迭代原子更新中的所有 DP MST 拓扑管理器

参数

__state

struct drm_atomic_state 指针

mgr

struct drm_dp_mst_topology_mgr 迭代光标

old_state

旧状态的 struct drm_dp_mst_topology_state 迭代光标

new_state

新状态的 struct drm_dp_mst_topology_state 迭代光标

__i

int 迭代光标,用于宏内部使用

描述

这迭代原子更新中的所有 DRM DP MST 拓扑管理器,跟踪旧状态和新状态。这在需要考虑状态增量的地方很有用,例如在原子检查函数中。

for_each_old_mst_mgr_in_state

for_each_old_mst_mgr_in_state (__state, mgr, old_state, __i)

迭代原子更新中的所有 DP MST 拓扑管理器

参数

__state

struct drm_atomic_state 指针

mgr

struct drm_dp_mst_topology_mgr 迭代光标

old_state

旧状态的 struct drm_dp_mst_topology_state 迭代光标

__i

int 迭代光标,用于宏内部使用

描述

这迭代原子更新中的所有 DRM DP MST 拓扑管理器,仅跟踪旧状态。这在禁用函数中很有用,我们需要硬件仍然处于旧状态。

for_each_new_mst_mgr_in_state

for_each_new_mst_mgr_in_state (__state, mgr, new_state, __i)

迭代原子更新中的所有 DP MST 拓扑管理器

参数

__state

struct drm_atomic_state 指针

mgr

struct drm_dp_mst_topology_mgr 迭代光标

new_state

新状态的 struct drm_dp_mst_topology_state 迭代光标

__i

int 迭代光标,用于宏内部使用

描述

这迭代原子更新中的所有 DRM DP MST 拓扑管理器,仅跟踪新状态。这在启用函数中很有用,我们需要在原子提交操作完成后硬件应处于的新状态。

void drm_dp_mst_get_port_malloc(struct drm_dp_mst_port *port)

增加 MST 端口的 malloc 引用计数

参数

struct drm_dp_mst_port *port

要增加 malloc 引用计数的 struct drm_dp_mst_port

描述

增加 drm_dp_mst_port.malloc_kref。当 drm_dp_mst_port.malloc_kref 达到 0 时,将释放 port 的内存分配,并且 port 可能不再使用。

由于如果 drm_dp_mst_port.malloc_kref 达到 0,port 可能会在任何时候被 DP MST 辅助函数释放,包括在调用此函数期间。因此,希望使用 struct drm_dp_mst_port 的驱动程序应确保在 drm_dp_mst_topology_cbs.add_connector 中至少获取对其 MST 端口的一个主 malloc 引用。此回调会在 drm_dp_mst_port.malloc_kref 有机会达到 0 之前被调用。

另请参阅:drm_dp_mst_put_port_malloc()

void drm_dp_mst_put_port_malloc(struct drm_dp_mst_port *port)

递减 MST 端口的 malloc 引用计数

参数

struct drm_dp_mst_port *port

要递减 malloc 引用计数的 struct drm_dp_mst_port

描述

递减 drm_dp_mst_port.malloc_kref。当 drm_dp_mst_port.malloc_kref 达到 0 时,将释放 port 的内存分配,并且可能不再使用 port

另请参阅:drm_dp_mst_get_port_malloc()

int drm_dp_mst_connector_late_register(struct drm_connector *connector, struct drm_dp_mst_port *port)

延迟 MST 连接器注册

参数

struct drm_connector *connector

MST 连接器

struct drm_dp_mst_port *port

此连接器的 MST 端口

描述

用于注册此 MST 端口的远程 aux 设备的辅助函数。驱动程序应从其 mst 连接器的 late_register 钩子调用此函数,以启用 MST aux 设备。

返回

成功时返回 0,失败时返回负错误代码。

void drm_dp_mst_connector_early_unregister(struct drm_connector *connector, struct drm_dp_mst_port *port)

提前 MST 连接器注销

参数

struct drm_connector *connector

MST 连接器

struct drm_dp_mst_port *port

此连接器的 MST 端口

描述

用于注销由 drm_dp_mst_connector_late_register() 注册的此 MST 端口的远程 aux 设备的辅助函数。驱动程序应从其 mst 连接器的 early_unregister 钩子调用此函数。

int drm_dp_add_payload_part1(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_topology_state *mst_state, struct drm_dp_mst_atomic_payload *payload)

执行负载更新第 1 部分

参数

struct drm_dp_mst_topology_mgr *mgr

要使用的管理器。

struct drm_dp_mst_topology_state *mst_state

MST 原子状态

struct drm_dp_mst_atomic_payload *payload

要写入的负载

描述

确定给定负载的起始时隙,并将此负载的 VCPI 编程到 DPRX 的 DPCD 中。调用此函数后,驱动程序应生成 ACT 和负载数据包。

返回

成功时返回 0,失败时返回错误代码。

void drm_dp_remove_payload_part1(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_topology_state *mst_state, struct drm_dp_mst_atomic_payload *payload)

沿虚拟通道移除 MST 负载

参数

struct drm_dp_mst_topology_mgr *mgr

要使用的管理器。

struct drm_dp_mst_topology_state *mst_state

MST 原子状态

struct drm_dp_mst_atomic_payload *payload

要移除的负载

描述

如果已成功分配负载,则沿虚拟通道移除负载。调用此函数后,驱动程序应设置 HW 以生成 ACT,然后切换到新的负载分配状态。

void drm_dp_remove_payload_part2(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_topology_state *mst_state, const struct drm_dp_mst_atomic_payload *old_payload, struct drm_dp_mst_atomic_payload *new_payload)

在本地移除 MST 负载

参数

struct drm_dp_mst_topology_mgr *mgr

要使用的管理器。

struct drm_dp_mst_topology_state *mst_state

MST 原子状态

const struct drm_dp_mst_atomic_payload *old_payload

具有其旧状态的负载

struct drm_dp_mst_atomic_payload *new_payload

具有其最新状态的负载

描述

更新所有其他负载的起始时隙,这些时隙会由于移除负载而向负载 ID 表的开头移动。每当驱动程序在其 HW 中移除负载时,都应调用此函数。它独立于沿虚拟通道的分支设备处的负载分配/取消分配的结果。

int drm_dp_add_payload_part2(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_atomic_payload *payload)

执行负载更新第 2 部分

参数

struct drm_dp_mst_topology_mgr *mgr

要使用的管理器。

struct drm_dp_mst_atomic_payload *payload

要更新的负载

描述

如果 drm_dp_add_payload_part1() 已成功为 payload 分配起始时隙,则此函数将发送边带消息以完成此负载的分配。

返回

成功时返回 0,失败时返回负错误代码。

fixed20_12 drm_dp_get_vc_payload_bw(int link_rate, int link_lane_count)

获取 MTP 链路的 VC 负载带宽

参数

int link_rate

链路速率,单位为 10kbits/s

int link_lane_count

通道数

描述

计算 MultiStream Transport 链路的总带宽。返回的值以 PBNs/(timeslots/1 MTP) 为单位。此值可用于将给定流所需的 PBN 数量转换为此流在每个 MTP 中所需的时隙数。

以 20.12 定点格式返回值 BW / 时隙。

enum drm_dp_mst_mode drm_dp_read_mst_cap(struct drm_dp_aux *aux, const u8 dpcd[DP_RECEIVER_CAP_SIZE])

读取接收器的 MST 模式能力

参数

struct drm_dp_aux *aux

要使用的 DP AUX 通道

const u8 dpcd[DP_RECEIVER_CAP_SIZE]

此接收器的 DPCD 能力的缓存副本

返回

enum drm_dp_mst_mode 以指示 MST 模式能力

int drm_dp_mst_topology_mgr_set_mst(struct drm_dp_mst_topology_mgr *mgr, bool mst_state)

设置拓扑管理器的 MST 状态

参数

struct drm_dp_mst_topology_mgr *mgr

要设置状态的管理器

bool mst_state

true 以在此连接器上启用 MST - false 以禁用。

描述

当驱动程序检测到支持 MST 的设备插入到支持 DP MST 的端口时,或者当支持 DP MST 的设备拔出时,会调用此函数。

void drm_dp_mst_topology_queue_probe(struct drm_dp_mst_topology_mgr *mgr)

排队拓扑探测

参数

struct drm_dp_mst_topology_mgr *mgr

要探测的管理器

描述

排队一个工作来探测 MST 拓扑。只有在 MST 链路的参数以某种方式发生变化,导致状态可能不同步(HW->SW 状态)后,驱动程序才应调用此函数来同步拓扑。例如,源和第一个下游分支设备之间的链路速率已在 UHBR 和非 UHBR 速率之间切换就是这种情况。除了这些情况(例如,当接收器插入/拔出端口时),SW 状态将通过 MST UP 消息通知自动更新。

void drm_dp_mst_topology_mgr_suspend(struct drm_dp_mst_topology_mgr *mgr)

挂起 MST 管理器

参数

struct drm_dp_mst_topology_mgr *mgr

要挂起的管理器

描述

此函数告诉 MST 设备我们无法再处理 UP 消息。这应该会阻止它发送任何消息,因为我们已挂起。

int drm_dp_mst_topology_mgr_resume(struct drm_dp_mst_topology_mgr *mgr, bool sync)

恢复 MST 管理器

参数

struct drm_dp_mst_topology_mgr *mgr

要恢复的管理器

bool sync

是否同步执行拓扑重新探测

描述

这将获取 DPCD 并查看设备是否仍然存在,如果存在,它将重写 MSTM 控制位并返回。

如果设备失败,则返回 -1,驱动程序应执行完整的 MST 重新探测,以防我们已取消停靠。

在系统恢复期间(假设驱动程序将调用 drm_atomic_helper_resume()),应事先调用此函数,并将 sync 设置为 true。在运行时恢复等上下文中,预计驱动程序不会调用 drm_atomic_helper_resume(),应调用此函数,并将 sync 设置为 false,以避免死锁。

返回

如果在我们挂起期间 MST 拓扑已移除,则返回 -1,否则返回 0。

int drm_dp_mst_hpd_irq_handle_event(struct drm_dp_mst_topology_mgr *mgr, const u8 *esi, u8 *ack, bool *handled)

MST 热插拔 IRQ 处理 MST 事件

参数

struct drm_dp_mst_topology_mgr *mgr

用于通知 irq 的管理器。

const u8 *esi

来自 SINK_COUNT_ESI 的 4 个字节

u8 *ack

用于确认从 SINK_COUNT_ESI 开始的事件的 4 个字节

bool *handled

是否已使用 hpd 中断

描述

当驱动程序检测到 HPD IRQ 时,应调用此函数以及 DEVICE_SERVICE_IRQ_VECTOR_ESI0 的值。拓扑管理器将处理 DEVICE_SERVICE_IRQ_VECTOR_ESI0 中指示的收到的边带消息,并设置相应的标志,驱动程序稍后必须确认 DP 接收器。

请注意,如果在调用此函数后设置了“handled”,驱动程序还应调用 drm_dp_mst_hpd_irq_send_new_request(),以尝试启动队列中的新请求(如果先前的消息事务已完成)。

另请参阅:drm_dp_mst_hpd_irq_send_new_request()

void drm_dp_mst_hpd_irq_send_new_request(struct drm_dp_mst_topology_mgr *mgr)

MST 热插拔 IRQ 启动新请求

参数

struct drm_dp_mst_topology_mgr *mgr

用于通知 irq 的管理器。

描述

当处理并确认 mst irq 事件时,应从驱动程序调用此函数。请注意,只有在先前的消息事务完成后,才应发送新的向下请求。源不应生成交错的消息事务。

int drm_dp_mst_detect_port(struct drm_connector *connector, struct drm_modeset_acquire_ctx *ctx, struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port)

获取 MST 端口的连接状态

参数

struct drm_connector *connector

此端口的 DRM 连接器

struct drm_modeset_acquire_ctx *ctx

用于获取锁的获取上下文

struct drm_dp_mst_topology_mgr *mgr

此端口的管理器

struct drm_dp_mst_port *port

指向端口的指针

描述

这将返回端口的当前连接状态。

const struct drm_edid *drm_dp_mst_edid_read(struct drm_connector *connector, struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port)

获取 MST 端口的 EDID

参数

struct drm_connector *connector

要获取 EDID 的顶级连接器

struct drm_dp_mst_topology_mgr *mgr

此端口的管理器

struct drm_dp_mst_port *port

指向端口的未经验证的指针。

描述

这将返回连接到连接器的端口的 EDID。它会验证指针是否仍然存在,因此调用者不需要引用。

struct edid *drm_dp_mst_get_edid(struct drm_connector *connector, struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port)

获取 MST 端口的 EDID

参数

struct drm_connector *connector

要获取 EDID 的顶级连接器

struct drm_dp_mst_topology_mgr *mgr

此端口的管理器

struct drm_dp_mst_port *port

指向端口的未经验证的指针。

描述

此函数已弃用;请改用 drm_dp_mst_edid_read()

这将返回连接到连接器的端口的 EDID。它会验证指针是否仍然存在,因此调用者不需要引用。

int drm_dp_atomic_find_time_slots(struct drm_atomic_state *state, struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port, int pbn)

查找时隙并将它们添加到状态

参数

struct drm_atomic_state *state

全局原子状态

struct drm_dp_mst_topology_mgr *mgr

端口的 MST 拓扑管理器

struct drm_dp_mst_port *port

要查找时隙的端口

int pbn

模式所需的 PBN 带宽

描述

port 分配时隙,替换它可能具有的任何先前的时隙分配。任何支持 MST 的原子驱动程序都必须在其 drm_encoder_helper_funcs.atomic_check() 回调中无条件调用此函数,以更改新状态的当前时隙分配,并确保每当拓扑中负载的状态更改时,都会添加 MST 原子状态。

由该函数设置的分配不会针对 mgr 的带宽限制进行检查,直到驱动程序调用 drm_dp_mst_atomic_check()

此外,可以根据需要在同一 port 上多次调用此函数。但是,在同一原子检查阶段调用此函数和 drm_dp_atomic_release_time_slots() 是不允许的。

另请参阅:drm_dp_atomic_release_time_slots() drm_dp_mst_atomic_check()

返回

为此端口分配的原子状态中的总时隙,如果端口不再存在,则返回负错误代码

int drm_dp_atomic_release_time_slots(struct drm_atomic_state *state, struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port)

释放已分配的时隙

参数

struct drm_atomic_state *state

全局原子状态

struct drm_dp_mst_topology_mgr *mgr

端口的 MST 拓扑管理器

struct drm_dp_mst_port *port

从中释放时隙的端口

描述

释放已分配给原子状态中端口的任何时隙。任何支持 MST 的原子驱动程序都必须在其 drm_connector_helper_funcs.atomic_check() 回调中无条件调用此函数。此辅助函数将检查新状态是否会释放时隙并做出相应响应,同时确保每当新状态将修改拓扑上负载的状态时,始终将 MST 状态添加到原子状态。

即使 port 已从系统中移除,也可以调用此函数。此外,可以根据需要在同一 port 上多次调用此函数。但是,在单个原子检查阶段在同一 port 上调用此函数和 drm_dp_atomic_find_time_slots() 是不允许的。

另请参阅:drm_dp_atomic_find_time_slots() drm_dp_mst_atomic_check()

返回

成功时返回 0,否则返回负错误代码

int drm_dp_mst_atomic_setup_commit(struct drm_atomic_state *state)

MST 辅助函数的 setup_commit 钩子

参数

struct drm_atomic_state *state

全局原子状态

描述

此函数保存原子状态中触摸当前分配给 MST 拓扑的任何 CRTC 的所有 drm_crtc_commit 结构。驱动程序必须从其 drm_mode_config_helper_funcs.atomic_commit_setup 钩子调用此钩子。

返回

如果成功检索所有 CRTC 提交,则返回 0,否则返回负错误代码

void drm_dp_mst_atomic_wait_for_dependencies(struct drm_atomic_state *state)

等待 MST 拓扑上的所有挂起的提交,为提交准备新的 MST 状态

参数

struct drm_atomic_state *state

全局原子状态

描述

遍历此原子状态下的任何 MST 拓扑,并等待任何已触及 CRTC(曾经或现在位于 MST 拓扑上)的挂起提交被编程到硬件并翻转后才返回。这是为了防止影响 MST 拓扑的多个非阻塞提交相互竞争,通过强制它们在提交中模式设置对象共享的唯一资源是 MST 拓扑的情况下按顺序执行。

此函数还通过执行一些状态准备来为提交准备新的 MST 状态,这些准备工作必须在此步骤才能完成,例如从之前的状态读取最终 VC 起始槽(在提交时确定)。

所有 MST 驱动程序必须在调用 drm_atomic_helper_wait_for_dependencies() 或其等效项之后调用此函数。

int drm_dp_mst_root_conn_atomic_check(struct drm_connector_state *new_conn_state, struct drm_dp_mst_topology_mgr *mgr)

在以 SST 模式运行的支持 MST 的连接器上序列化 CRTC 提交

参数

struct drm_connector_state *new_conn_state

drm_connector 的新连接器状态

struct drm_dp_mst_topology_mgr *mgr

drm_connector 的 MST 拓扑管理器

描述

由于 MST 使用伪 drm_encoder 结构,通用的原子模式设置代码无法序列化发生在 MST 拓扑的真实 DP 连接器上的非阻塞提交,因为真实 DP 连接器上的 CRTC 和连接器的 MST 拓扑上的 CRTC 将永远不会共享同一个 drm_encoder

此函数通过检查根 MST 连接器的原子状态来确定它是否即将进行模式设置来处理此序列化问题,然后引入 MST 拓扑状态(如果适用),同时将任何相关的 CRTC 添加到 drm_dp_mst_topology_state.pending_crtc_mask

实现 MST 的驱动程序必须从任何能够驱动 MST sink 的物理 DP drm_connectordrm_connector_helper_funcs.atomic_check hook 中调用此函数。

返回

成功时返回 0,否则返回负错误代码

void drm_dp_mst_update_slots(struct drm_dp_mst_topology_state *mst_state, uint8_t link_encoding_cap)

根据 DP 编码格式更新时隙信息

参数

struct drm_dp_mst_topology_state *mst_state

要更新的 mst_state

uint8_t link_encoding_cap

链路上的编码格式

int drm_dp_check_act_status(struct drm_dp_mst_topology_mgr *mgr)

轮询 ACT 处理状态。

参数

struct drm_dp_mst_topology_mgr *mgr

要使用的管理器

描述

尝试通过轮询 ACT 处理位最多 3 秒来等待 MST 集线器完成更新其有效负载表(是的,有些集线器确实需要这么长时间)。

返回

如果 ACT 及时处理,则返回 0;如果失败,则返回负错误码。

int drm_dp_calc_pbn_mode(int clock, int bpp)

计算模式的 PBN。

参数

int clock

点时钟

int bpp

bpp 作为 .4 二进制定点数

描述

这使用规范中的公式来计算模式的 PBN 值。

void drm_dp_mst_dump_topology(struct seq_file *m, struct drm_dp_mst_topology_mgr *mgr)

将拓扑转储到 seq 文件。

参数

struct seq_file *m

要将输出转储到的 seq_file

struct drm_dp_mst_topology_mgr *mgr

要转储当前拓扑的管理器。

描述

帮助程序将 MST 拓扑转储到 debugfs 的 seq 文件。

bool drm_dp_mst_port_downstream_of_parent(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port, struct drm_dp_mst_port *parent)

检查端口是否位于父端口的下游

参数

struct drm_dp_mst_topology_mgr *mgr

MST 拓扑管理器

struct drm_dp_mst_port *port

正在查找的端口

struct drm_dp_mst_port *parent

父端口

描述

如果 port 位于 parent 的下游,该函数返回 true。 如果 parentNULL(表示根端口),如果 port 位于 mgr 的拓扑中,则该函数返回 true

int drm_dp_mst_add_affected_dsc_crtcs(struct drm_atomic_state *state, struct drm_dp_mst_topology_mgr *mgr)

参数

struct drm_atomic_state *state

指向新的 struct drm_dp_mst_topology_state 的指针

struct drm_dp_mst_topology_mgr *mgr

MST 拓扑管理器

描述

只要 mst 拓扑发生更改,就必须重新计算 DSC 配置,因此我们需要在该拓扑中的所有受影响的 CRTC 上触发模式设置

另请参阅:drm_dp_mst_atomic_enable_dsc()

int drm_dp_mst_atomic_enable_dsc(struct drm_atomic_state *state, struct drm_dp_mst_port *port, int pbn, bool enable)

将 DSC 启用标志设置为开/关

参数

struct drm_atomic_state *state

指向新的 drm_atomic_state 的指针

struct drm_dp_mst_port *port

指向受影响的 MST 端口的指针

int pbn

启用 DSC 后,重新计算的链路所需带宽

bool enable

布尔标志,用于启用或禁用端口上的 DSC

描述

此函数通过从提供的 pbn 重新计算其 vcpi 并在 dsc_enable 标志中启用 DSC 来跟踪哪些端口已启用 DSC

int drm_dp_mst_atomic_check_mgr(struct drm_atomic_state *state, struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_topology_state *mst_state, struct drm_dp_mst_port **failing_port)

检查 MST 拓扑管理器的原子状态

参数

struct drm_atomic_state *state

全局原子状态

struct drm_dp_mst_topology_mgr *mgr

要检查的管理器

struct drm_dp_mst_topology_state *mst_state

mgr 的 MST 原子状态

struct drm_dp_mst_port **failing_port

返回具有 BW 限制的端口

描述

检查给定的 MST 管理器的拓扑状态是否存在原子更新,以确保其有效。 这包括检查是否有足够的带宽来支持原子更新中的新时隙分配。

任何支持 DP MST 的原子驱动程序都必须确保在检查其 drm_mode_config_funcs.atomic_check() 回调中的其余状态之后调用此函数或 drm_dp_mst_atomic_check() 函数。

另请参阅:drm_dp_mst_atomic_check() drm_dp_atomic_find_time_slots() drm_dp_atomic_release_time_slots()

返回

  • 如果新状态有效,则为 0

  • 如果新状态无效,因为 BW 限制,则为 -ENOSPC

    failing_port 设置为

    • BW 限制检查失败的非根端口,并且 failing_port 的所有下游端口都通过了 BW 限制检查。 返回的端口指针至少在它的一个下游有效负载存在之前有效。

    • 如果根端口的 BW 限制检查失败,并且根端口的所有下游端口都通过了 BW 限制检查,则为 NULL

  • 如果新状态无效,因为根端口具有太多有效负载,则为 -EINVAL

int drm_dp_mst_atomic_check(struct drm_atomic_state *state)

检查原子更新中 MST 拓扑的新状态是否有效

参数

struct drm_atomic_state *state

指向新的 struct drm_dp_mst_topology_state 的指针

描述

检查给定拓扑状态是否存在原子更新,以确保其有效,为原子状态中的所有 MST 管理器调用 drm_dp_mst_atomic_check_mgr()。 这包括检查是否有足够的带宽来支持原子更新中的新时隙分配。

任何支持 DP MST 的原子驱动程序都必须确保在检查其 drm_mode_config_funcs.atomic_check() 回调中的其余状态之后调用此函数。

另请参阅:drm_dp_mst_atomic_check_mgr() drm_dp_atomic_find_time_slots() drm_dp_atomic_release_time_slots()

返回

如果新状态有效,则为 0;否则为负错误代码。

struct drm_dp_mst_topology_state *drm_atomic_get_mst_topology_state(struct drm_atomic_state *state, struct drm_dp_mst_topology_mgr *mgr)

获取 MST 拓扑状态

参数

struct drm_atomic_state *state

全局原子状态

struct drm_dp_mst_topology_mgr *mgr

MST 拓扑管理器,在本例中也是私有对象

描述

此函数包装 drm_atomic_get_priv_obj_state(),传入 MST 原子状态 vtable,以便返回的私有对象状态是 MST 拓扑对象的状态。

返回

MST 拓扑状态或错误指针。

struct drm_dp_mst_topology_state *drm_atomic_get_old_mst_topology_state(struct drm_atomic_state *state, struct drm_dp_mst_topology_mgr *mgr)

获取原子状态中的旧 MST 拓扑状态(如果有)

参数

struct drm_atomic_state *state

全局原子状态

struct drm_dp_mst_topology_mgr *mgr

MST 拓扑管理器,在本例中也是私有对象

描述

此函数包装 drm_atomic_get_old_private_obj_state(),传入 MST 原子状态 vtable,以便返回的私有对象状态是 MST 拓扑对象的状态。

返回

旧 MST 拓扑状态;如果全局原子状态中没有此 MST mgr 的拓扑状态,则为 NULL

struct drm_dp_mst_topology_state *drm_atomic_get_new_mst_topology_state(struct drm_atomic_state *state, struct drm_dp_mst_topology_mgr *mgr)

获取原子状态中的新 MST 拓扑状态(如果有)

参数

struct drm_atomic_state *state

全局原子状态

struct drm_dp_mst_topology_mgr *mgr

MST 拓扑管理器,在本例中也是私有对象

描述

此函数包装 drm_atomic_get_new_private_obj_state(),传入 MST 原子状态 vtable,以便返回的私有对象状态是 MST 拓扑对象的状态。

返回

新 MST 拓扑状态;如果全局原子状态中没有此 MST mgr 的拓扑状态,则为 NULL

int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr, struct drm_device *dev, struct drm_dp_aux *aux, int max_dpcd_transaction_bytes, int max_payloads, int conn_base_id)

初始化拓扑管理器

参数

struct drm_dp_mst_topology_mgr *mgr

要初始化的管理器结构

struct drm_device *dev

提供此结构的设备 - 用于 i2c 添加。

struct drm_dp_aux *aux

用于与此设备通信的 DP 帮助程序 aux 通道

int max_dpcd_transaction_bytes

硬件特定的 DPCD 事务限制

int max_payloads

此 GPU 可以提供的最大有效负载数

int conn_base_id

MST 设备连接到的连接器对象 ID。

描述

成功返回 0,失败返回负错误代码

void drm_dp_mst_topology_mgr_destroy(struct drm_dp_mst_topology_mgr *mgr)

销毁拓扑管理器。

参数

struct drm_dp_mst_topology_mgr *mgr

要销毁的管理器

struct drm_dp_aux *drm_dp_mst_aux_for_parent(struct drm_dp_mst_port *port)

获取 MST 端口的父端口的 AUX 设备

参数

struct drm_dp_mst_port *port

返回其父端口的 AUX 设备的 MST 端口

描述

返回 port 的父端口的 AUX 设备;如果 port 的父端口是根端口,则返回 NULL。

struct drm_dp_aux *drm_dp_mst_dsc_aux_for_port(struct drm_dp_mst_port *port)

查找 DSC 的正确 aux

参数

struct drm_dp_mst_port *port

要检查的端口。 具有附加显示的 MST 树的叶子。

描述

根据具体情况,DSC 可以通过端点 aux、直接上游 aux 或连接器的物理 aux 启用。

这既是读取 DSC_CAPABILITY 的正确 aux,也是写入 DSC_ENABLED 的正确 aux。

此操作可能很昂贵(最多四次 aux 读取),因此调用者应缓存返回值。

返回

如果无法在此端口上启用 DSC,则返回 NULL;否则返回 aux 设备

拓扑生存期内部

这些函数未导出到驱动程序,但此处记录它们是为了帮助更好地理解 MST 拓扑帮助程序

void drm_dp_mst_get_mstb_malloc(struct drm_dp_mst_branch *mstb)

递增分支设备的 malloc 引用计数

参数

struct drm_dp_mst_branch *mstb

要递增 malloc 引用计数的 struct drm_dp_mst_branch

描述

递增 drm_dp_mst_branch.malloc_kref。 当 drm_dp_mst_branch.malloc_kref 达到 0 时,将释放 mstb 的内存分配,并且不得再使用 mstb

另请参阅:drm_dp_mst_put_mstb_malloc()

void drm_dp_mst_put_mstb_malloc(struct drm_dp_mst_branch *mstb)

递减分支设备的 malloc 引用计数

参数

struct drm_dp_mst_branch *mstb

要递减 malloc 引用计数的 struct drm_dp_mst_branch

描述

递减 drm_dp_mst_branch.malloc_kref。 当 drm_dp_mst_branch.malloc_kref 达到 0 时,将释放 mstb 的内存分配,并且不得再使用 mstb

另请参阅:drm_dp_mst_get_mstb_malloc()

int drm_dp_mst_topology_try_get_mstb(struct drm_dp_mst_branch *mstb)

递增分支设备的拓扑引用计数(除非它为零)

参数

struct drm_dp_mst_branch *mstb

要递增拓扑引用计数的 struct drm_dp_mst_branch

描述

尝试获取 mstb 的拓扑引用(如果尚未从拓扑中删除)(例如,drm_dp_mst_branch.topology_kref 已达到 0)。 保持拓扑引用意味着只要用户保持拓扑引用,malloc 引用将保持在 mstb 中。

应注意确保用户至少具有一个 mstb 的 malloc 引用。 如果您已经具有 mstb 的拓扑引用,则应改用 drm_dp_mst_topology_get_mstb()

另请参阅:drm_dp_mst_topology_get_mstb() drm_dp_mst_topology_put_mstb()

返回

  • 1:已成功获取拓扑引用

  • 0:port 不再位于拓扑中,未获取引用

void drm_dp_mst_topology_get_mstb(struct drm_dp_mst_branch *mstb)

递增分支设备的拓扑引用计数

参数

struct drm_dp_mst_branch *mstb

要递增拓扑引用计数的 struct drm_dp_mst_branch

描述

递增 drm_dp_mst_branch.topology_refcount,而不检查它是否已达到 0。 这仅在您已保证至少具有一个 mstb 的活动拓扑引用的情况下才有效。 否则,必须使用 drm_dp_mst_topology_try_get_mstb()

另请参阅:drm_dp_mst_topology_try_get_mstb() drm_dp_mst_topology_put_mstb()

void drm_dp_mst_topology_put_mstb(struct drm_dp_mst_branch *mstb)

释放分支设备的拓扑引用

参数

struct drm_dp_mst_branch *mstb

要从中释放拓扑引用的 struct drm_dp_mst_branch

描述

通过递减 drm_dp_mst_branch.topology_krefmstb 释放拓扑引用。

另请参阅:drm_dp_mst_topology_try_get_mstb() drm_dp_mst_topology_get_mstb()

int drm_dp_mst_topology_try_get_port(struct drm_dp_mst_port *port)

递增端口的拓扑引用计数(除非它为零)

参数

struct drm_dp_mst_port *port

要递增拓扑引用计数的 struct drm_dp_mst_port

描述

尝试获取对 port 的拓扑引用,如果它尚未从拓扑中移除(例如,drm_dp_mst_port.topology_kref 已达到 0)。持有拓扑引用意味着只要用户持有拓扑引用,就会持有对 port 的 malloc 引用。

应注意确保用户至少有一个对 port 的 malloc 引用。如果您已经有对 port 的拓扑引用,则应使用 drm_dp_mst_topology_get_port() 代替。

另请参见:drm_dp_mst_topology_get_port() drm_dp_mst_topology_put_port()

返回

  • 1:已成功获取拓扑引用

  • 0:port 不再位于拓扑中,未获取引用

void drm_dp_mst_topology_get_port(struct drm_dp_mst_port *port)

增加端口的拓扑引用计数

参数

struct drm_dp_mst_port *port

要增加拓扑引用计数的 struct drm_dp_mst_port

描述

增加 drm_dp_mst_port.topology_refcount,而不检查它是否已达到 0。这仅在保证您至少有一个对 port 的活动拓扑引用的情况下才有效。否则,必须使用 drm_dp_mst_topology_try_get_port()

另请参见:drm_dp_mst_topology_try_get_port() drm_dp_mst_topology_put_port()

void drm_dp_mst_topology_put_port(struct drm_dp_mst_port *port)

释放端口的拓扑引用

参数

struct drm_dp_mst_port *port

要释放拓扑引用的 struct drm_dp_mst_port

描述

通过递减 drm_dp_mst_port.topology_krefport 释放拓扑引用。

另请参见:drm_dp_mst_topology_try_get_port() drm_dp_mst_topology_get_port()

MIPI DBI 辅助函数参考

此库为 MIPI 显示总线接口 (DBI) 兼容的显示控制器提供辅助函数。

许多用于小型 LCD 显示器的控制器都符合 MIPI 标准,可以使用此库。如果控制器使用寄存器 0x2A 和 0x2B 设置要更新的区域,并使用寄存器 0x2C 写入帧内存,则它很可能符合 MIPI 标准。

由于需要完整的帧内存,因此仅支持 MIPI Type 1 显示器。

有 3 种 MIPI DBI 实现类型

  1. Motorola 6800 型并行总线

  2. Intel 8080 型并行总线

  3. 具有 3 个选项的 SPI 类型

    1. 9 位,其中数据/命令信号作为第九位

    2. 与上述相同,只是它作为 16 位发送

    3. 8 位,其中数据/命令信号作为单独的 D/CX 引脚

目前,mipi_dbi 仅支持带有 mipi_dbi_spi_init() 的 Type C 选项 1 和 3。

struct mipi_dbi

MIPI DBI 接口

定义:

struct mipi_dbi {
    struct mutex cmdlock;
    int (*command)(struct mipi_dbi *dbi, u8 *cmd, u8 *param, size_t num);
    const u8 *read_commands;
    bool swap_bytes;
    struct gpio_desc *reset;
    struct spi_device *spi;
    unsigned int write_memory_bpw;
    struct gpio_desc *dc;
    void *tx_buf9;
    size_t tx_buf9_len;
};

成员

cmdlock

命令锁

command

执行命令的总线特定回调。

read_commands
以零条目结尾的读取命令数组。

如果此项为 NULL,则禁用读取。

swap_bytes

在传输之前交换缓冲区中的字节

reset

可选的重置 gpio

spi

SPI 设备

write_memory_bpw

在 MIPI_DCS_WRITE_MEMORY_START 传输上使用的每字位数

dc

可选的 D/C gpio。

tx_buf9

用于选项 1 9 位转换的缓冲区

tx_buf9_len

tx_buf9 的大小。

struct mipi_dbi_dev

MIPI DBI 设备

定义:

struct mipi_dbi_dev {
    struct drm_device drm;
    struct drm_simple_display_pipe pipe;
    struct drm_connector connector;
    struct drm_display_mode mode;
    u32 pixel_format;
    u16 *tx_buf;
    unsigned int rotation;
    unsigned int left_offset;
    unsigned int top_offset;
    struct backlight_device *backlight;
    struct regulator *regulator;
    struct regulator *io_regulator;
    struct mipi_dbi dbi;
    void *driver_private;
};

成员

drm

DRM 设备

pipe

显示管道结构

connector

Connector

mode

固定显示模式

pixel_format

本机像素格式 (DRM_FORMAT_*)

tx_buf

用于传输的缓冲区(复制剪辑矩形区域)

rotation

以逆时针方向的初始旋转角度

left_offset
显示器相对于显示器的水平偏移量

控制器的驱动程序数组

top_offset
显示器相对于显示器的垂直偏移量

控制器的驱动程序数组

backlight

背光设备(可选)

regulator

电源稳压器 (Vdd)(可选)

io_regulator

I/O 电源稳压器 (Vddi)(可选)

dbi

MIPI DBI 接口

driver_private
驱动程序私有数据。

对于具有私有数据的驱动程序是必需的,因为 devm_drm_dev_alloc() 无法分配嵌入结构的结构,该结构又嵌入 drm_device。

mipi_dbi_command

mipi_dbi_command (dbi, cmd, seq...)

带有可选参数的 MIPI DCS 命令

参数

dbi

MIPI DBI 结构

cmd

命令

seq...

可选参数

描述

将 MIPI DCS 命令发送到控制器。使用 mipi_dbi_command_read() 进行 get/read。

返回

成功时返回 0,失败时返回负错误代码。

DRM_MIPI_DBI_SIMPLE_DISPLAY_PIPE_FUNCS

DRM_MIPI_DBI_SIMPLE_DISPLAY_PIPE_FUNCS (enable_)

为 MIPI-DBI 设备初始化 struct drm_simple_display_pipe_funcs

参数

enable_

启用回调实现

描述

此宏使用 MIPI-DBI 设备默认值初始化 struct drm_simple_display_pipe_funcs。唯一依赖硬件的回调是 enable,驱动程序必须为其提供实现。鼓励基于 MIPI 的驱动程序使用此宏进行初始化。

int mipi_dbi_command_read(struct mipi_dbi *dbi, u8 cmd, u8 *val)

MIPI DCS 读取命令

参数

struct mipi_dbi *dbi

MIPI DBI 结构

u8 cmd

命令

u8 *val

读取的值

描述

将 MIPI DCS 读取命令发送到控制器。

返回

成功时返回 0,失败时返回负错误代码。

int mipi_dbi_command_buf(struct mipi_dbi *dbi, u8 cmd, u8 *data, size_t len)

带有数组中参数的 MIPI DCS 命令

参数

struct mipi_dbi *dbi

MIPI DBI 结构

u8 cmd

命令

u8 *data

参数缓冲区

size_t len

缓冲区长度

返回

成功时返回 0,失败时返回负错误代码。

int mipi_dbi_buf_copy(void *dst, struct iosys_map *src, struct drm_framebuffer *fb, struct drm_rect *clip, bool swap, struct drm_format_conv_state *fmtcnv_state)

复制帧缓冲区,如有必要进行转换

参数

void *dst

目标缓冲区

struct iosys_map *src

源缓冲区

struct drm_framebuffer *fb

源帧缓冲区

struct drm_rect *clip

要复制的区域的剪辑矩形

bool swap

如果为 true,则交换 16 位值的 MSB/LSB

struct drm_format_conv_state *fmtcnv_state

格式转换状态

返回

成功时返回 0,失败时返回负错误代码。

enum drm_mode_status mipi_dbi_pipe_mode_valid(struct drm_simple_display_pipe *pipe, const struct drm_display_mode *mode)

MIPI DBI 模式有效辅助函数

参数

struct drm_simple_display_pipe *pipe

简单显示管道

const struct drm_display_mode *mode

要测试的模式

描述

此函数根据 MIPI DBI 的硬件显示器验证给定的显示模式。驱动程序可以使用此作为其 drm_simple_display_pipe_funcs->mode_valid 回调。

void mipi_dbi_pipe_update(struct drm_simple_display_pipe *pipe, struct drm_plane_state *old_state)

显示管道更新辅助函数

参数

struct drm_simple_display_pipe *pipe

简单显示管道

struct drm_plane_state *old_state

旧平面状态

描述

此函数处理帧缓冲区刷新和 vblank 事件。驱动程序可以使用此作为其 drm_simple_display_pipe_funcs->update 回调。

void mipi_dbi_enable_flush(struct mipi_dbi_dev *dbidev, struct drm_crtc_state *crtc_state, struct drm_plane_state *plane_state)

MIPI DBI 启用辅助函数

参数

struct mipi_dbi_dev *dbidev

MIPI DBI 设备结构

struct drm_crtc_state *crtc_state

CRTC 状态

struct drm_plane_state *plane_state

平面状态

描述

刷新整个帧缓冲区并启用背光。驱动程序可以在其 drm_simple_display_pipe_funcs->enable 回调中使用此函数。

注意

由于它们都使用相同的刷新代码,因此不使用 mipi_dbi_pipe_update() 的驱动程序无法使用此函数,因为它们具有自定义帧缓冲区刷新。

void mipi_dbi_pipe_disable(struct drm_simple_display_pipe *pipe)

MIPI DBI 管道禁用辅助函数

参数

struct drm_simple_display_pipe *pipe

显示管道

描述

如果存在,此函数禁用背光,否则显示内存将变为空白。如果正在使用稳压器,则禁用稳压器。驱动程序可以使用此作为其 drm_simple_display_pipe_funcs->disable 回调。

int mipi_dbi_pipe_begin_fb_access(struct drm_simple_display_pipe *pipe, struct drm_plane_state *plane_state)

MIPI DBI 管道开始访问辅助函数

参数

struct drm_simple_display_pipe *pipe

显示管道

struct drm_plane_state *plane_state

平面状态

描述

此函数实现 struct drm_simple_display_funcs.begin_fb_access

有关详细信息,请参见 drm_gem_begin_shadow_fb_access(),有关清理,请参见 mipi_dbi_pipe_cleanup_fb()。

返回

成功时为 0,否则为负 errno 代码。

void mipi_dbi_pipe_end_fb_access(struct drm_simple_display_pipe *pipe, struct drm_plane_state *plane_state)

MIPI DBI 管道结束访问辅助函数

参数

struct drm_simple_display_pipe *pipe

显示管道

struct drm_plane_state *plane_state

平面状态

描述

此函数实现 struct drm_simple_display_funcs.end_fb_access

参见 mipi_dbi_pipe_begin_fb_access()

void mipi_dbi_pipe_reset_plane(struct drm_simple_display_pipe *pipe)

MIPI DBI 平面重置辅助函数

参数

struct drm_simple_display_pipe *pipe

显示管道

描述

此函数为 MIPI DBI 平面实现 struct drm_simple_display_funcs.reset_plane

struct drm_plane_state *mipi_dbi_pipe_duplicate_plane_state(struct drm_simple_display_pipe *pipe)

复制 MIPI DBI 平面状态

参数

struct drm_simple_display_pipe *pipe

显示管道

描述

此函数为 MIPI DBI 平面实现 struct drm_simple_display_funcs.duplicate_plane_state

有关更多详细信息,请参见 drm_gem_duplicate_shadow_plane_state()

返回

指向成功时的新的平面状态的指针,否则为 NULL。

void mipi_dbi_pipe_destroy_plane_state(struct drm_simple_display_pipe *pipe, struct drm_plane_state *plane_state)

清理 MIPI DBI 平面状态

参数

struct drm_simple_display_pipe *pipe

显示管道

struct drm_plane_state *plane_state

平面状态

描述

此函数为 MIPI DBI 平面实现 struct drm_simple_display_funcs.destroy_plane_state。

有关更多详细信息,请参见 drm_gem_destroy_shadow_plane_state()

int mipi_dbi_dev_init_with_formats(struct mipi_dbi_dev *dbidev, const struct drm_simple_display_pipe_funcs *funcs, const uint32_t *formats, unsigned int format_count, const struct drm_display_mode *mode, unsigned int rotation, size_t tx_buf_size)

具有自定义格式的 MIPI DBI 设备初始化

参数

struct mipi_dbi_dev *dbidev

要初始化的 MIPI DBI 设备结构

const struct drm_simple_display_pipe_funcs *funcs

显示管道函数

const uint32_t *formats

支持格式数组 (DRM_FORMAT_*)。

unsigned int format_count

formats 中的元素数

const struct drm_display_mode *mode

显示模式

unsigned int rotation

以逆时针方向的初始旋转角度

size_t tx_buf_size

分配此大小的传输缓冲区。

描述

此函数使用具有一个固定 drm_display_modedrm_connector 设置 drm_simple_display_pipe,该固定 drm_display_mode 根据 rotation 旋转。此模式用于设置模式配置的最小/最大宽度/高度属性。

如果要使用本机 RGB565 和模拟的 XRGB8888 格式,请使用 mipi_dbi_dev_init()

注意

某些辅助函数期望 RGB565 为默认格式,并且传输缓冲区的大小适合该格式。

返回

成功时返回 0,失败时返回负错误代码。

int mipi_dbi_dev_init(struct mipi_dbi_dev *dbidev, const struct drm_simple_display_pipe_funcs *funcs, const struct drm_display_mode *mode, unsigned int rotation)

MIPI DBI 设备初始化

参数

struct mipi_dbi_dev *dbidev

要初始化的 MIPI DBI 设备结构

const struct drm_simple_display_pipe_funcs *funcs

显示管道函数

const struct drm_display_mode *mode

显示模式

unsigned int rotation

以逆时针方向的初始旋转角度

描述

此函数使用具有一个固定 drm_display_modedrm_connector 设置 drm_simple_display_pipe,该固定 drm_display_mode 根据 rotation 旋转。此模式用于设置模式配置的最小/最大宽度/高度属性。此外,还分配了 mipi_dbi.tx_buf

支持的格式:本机 RGB565 和模拟的 XRGB8888。

返回

成功时返回 0,失败时返回负错误代码。

void mipi_dbi_hw_reset(struct mipi_dbi *dbi)

控制器的硬件重置

参数

struct mipi_dbi *dbi

MIPI DBI 结构

描述

如果设置了 mipi_dbi->reset gpio,则重置控制器。

bool mipi_dbi_display_is_on(struct mipi_dbi *dbi)

检查显示是否已开启

参数

struct mipi_dbi *dbi

MIPI DBI 结构

描述

此函数检查电源模式寄存器(如果可读)以查看显示输出是否已打开。 这可用于查看引导加载程序是否已打开显示器,从而避免在启用流水线时出现闪烁。

返回

如果可以验证显示已开启,则为 true,否则为 false。

int mipi_dbi_poweron_reset(struct mipi_dbi_dev *dbidev)

MIPI DBI 上电和复位

参数

struct mipi_dbi_dev *dbidev

MIPI DBI 设备结构

描述

此函数启用稳压器(如果使用),并执行硬件和软件复位。

返回

成功返回零,否则返回负错误代码。

int mipi_dbi_poweron_conditional_reset(struct mipi_dbi_dev *dbidev)

MIPI DBI 上电和条件复位

参数

struct mipi_dbi_dev *dbidev

MIPI DBI 设备结构

描述

此函数启用稳压器(如果使用),如果显示器关闭,则执行硬件和软件复位。 如果 mipi_dbi_display_is_on() 确定显示器已打开,则不执行复位。

返回

如果控制器已复位,则返回零;如果显示器已打开,则返回 1;否则返回负错误代码。

u32 mipi_dbi_spi_cmd_max_speed(struct spi_device *spi, size_t len)

获取最大 SPI 总线速度

参数

struct spi_device *spi

SPI 设备

size_t len

传输缓冲区长度。

描述

许多控制器的最大速度为 10MHz,但可以推到远高于此速度。 通过以最大速度运行像素数据,其余数据以 10MHz 运行,提高可靠性,防止传输故障搞乱初始化设置。

int mipi_dbi_spi_init(struct spi_device *spi, struct mipi_dbi *dbi, struct gpio_desc *dc)

初始化 MIPI DBI SPI 接口

参数

struct spi_device *spi

SPI 设备

struct mipi_dbi *dbi

要初始化的 MIPI DBI 结构

struct gpio_desc *dc

D/C gpio(可选)

描述

此函数设置 mipi_dbi->command,为常用的读取命令启用 mipi_dbi->read_commands。 之后应调用 mipi_dbi_dev_init() 或驱动程序特定的初始化。

如果设置了 dc,则假定为 C 型选项 3 接口,如果没有,则假定为 C 型选项 1。

如果命令是 MIPI_DCS_WRITE_MEMORY_START 并且像素格式是 RGB565,则必须考虑字节序。 MIPI DBI 串行接口是大端,帧缓冲区假定以小端方式存储在内存中(不支持 DRM_FORMAT_BIG_ENDIAN)。

这是字节序的处理方式

选项 1(D/C 作为一位):缓冲区在导线上逐字节发送,因此 16 位缓冲区是

在传输之前进行字节交换。

选项 3(D/C 作为 gpio):如果 SPI 控制器支持每个字 16 位,则缓冲区可以是

按原样发送。 如果不是,则调用者负责在调用 mipi_dbi_command_buf() 之前交换字节,并且缓冲区以 8 bpw 发送。

此处理针对 DRM_FORMAT_RGB565 帧缓冲区进行了优化。

如果接口是选项 1 并且 SPI 控制器不支持每个字 9 位,则缓冲区将作为 9x 8 位字发送,如有必要,填充 MIPI DCS 空操作命令。

返回

成功时返回 0,失败时返回负错误代码。

int mipi_dbi_spi_transfer(struct spi_device *spi, u32 speed_hz, u8 bpw, const void *buf, size_t len)

SPI 传输助手

参数

struct spi_device *spi

SPI 设备

u32 speed_hz

覆盖速度(可选)

u8 bpw

每个字的位数

const void *buf

要传输的缓冲区

size_t len

缓冲区长度

描述

此 SPI 传输助手将 buf 的传输分解为 SPI 控制器驱动程序可以处理的块。 调用此方法时,必须锁定 SPI 总线。

返回

成功时返回 0,失败时返回负错误代码。

void mipi_dbi_debugfs_init(struct drm_minor *minor)

创建 debugfs 条目

参数

struct drm_minor *minor

DRM 次要

描述

此函数创建一个“command”debugfs 文件,用于将命令发送到控制器或获取读取命令值。 驱动程序可以将其用作 drm_driver->debugfs_init 回调。

MIPI DSI 助手函数参考

这些函数包含一些通用逻辑和助手,用于处理 MIPI DSI 外设。

为许多标准 MIPI DSI 命令以及 MIPI DCS 命令集的子集提供了助手。

struct mipi_dsi_msg

读取/写入 DSI 缓冲区

定义:

struct mipi_dsi_msg {
    u8 channel;
    u8 type;
    u16 flags;
    size_t tx_len;
    const void *tx_buf;
    size_t rx_len;
    void *rx_buf;
};

成员

通道

虚拟通道 ID

type

有效负载数据类型

标志

控制此消息传输的标志

tx_len

tx_buf 的长度

tx_buf

要写入的数据

rx_len

rx_buf 的长度

rx_buf

要读取的数据,或 NULL

struct mipi_dsi_packet

以协议格式表示 MIPI DSI 数据包

定义:

struct mipi_dsi_packet {
    size_t size;
    u8 header[4];
    size_t payload_length;
    const u8 *payload;
};

成员

size

数据包的大小(以字节为单位)

标头

构成标头的四个字节(数据 ID、字数或数据包数据以及 ECC)

payload_length

有效负载中的字节数

有效负载

指向包含有效负载的缓冲区的指针(如果有)

struct mipi_dsi_host_ops

DSI 总线操作

定义:

struct mipi_dsi_host_ops {
    int (*attach)(struct mipi_dsi_host *host, struct mipi_dsi_device *dsi);
    int (*detach)(struct mipi_dsi_host *host, struct mipi_dsi_device *dsi);
    ssize_t (*transfer)(struct mipi_dsi_host *host, const struct mipi_dsi_msg *msg);
};

成员

attach

将 DSI 设备连接到 DSI 主机

detach

从 DSI 主机分离 DSI 设备

transfer

传输 DSI 数据包

描述

.transfer() 传输的 DSI 数据包作为 mipi_dsi_msg 结构传入。 此结构包含有关传输的数据包类型以及传输和接收缓冲区的信息。 如果在传输期间遇到错误,此函数将返回负错误代码。 成功后,它应返回写入数据包传输的字节数或读取数据包接收的字节数。

请注意,通常 DSI 数据包传输是原子的,因此 .transfer() 函数很少返回成功时传输缓冲区中包含的字节数以外的任何内容。

另请注意,无论主机处于何种状态,都可以调用这些回调。 需要底层设备供电才能执行这些操作的驱动程序首先需要确保已正确启用它。

struct mipi_dsi_host

DSI 主机设备

定义:

struct mipi_dsi_host {
    struct device *dev;
    const struct mipi_dsi_host_ops *ops;
    struct list_head list;
};

成员

dev

此 DSI 主机的驱动程序模型设备节点

ops

DSI 主机操作

list

列表管理

struct mipi_dsi_device_info

用于创建 mipi_dsi_device 的模板

定义:

struct mipi_dsi_device_info {
    char type[DSI_DEV_NAME_SIZE];
    u32 channel;
    struct device_node *node;
};

成员

type

DSI 外围芯片类型

通道

分配给外围设备的 DSI 虚拟通道

节点

指向 OF 设备节点的指针或 NULL

描述

填充此内容并将其传递给 mipi_dsi_device_new 以创建新的 DSI 设备

struct mipi_dsi_device

DSI 外围设备

定义:

struct mipi_dsi_device {
    struct mipi_dsi_host *host;
    struct device dev;
    bool attached;
    char name[DSI_DEV_NAME_SIZE];
    unsigned int channel;
    unsigned int lanes;
    enum mipi_dsi_pixel_format format;
    unsigned long mode_flags;
    unsigned long hs_rate;
    unsigned long lp_rate;
    struct drm_dsc_config *dsc;
};

成员

主机

此外围设备的 DSI 主机

dev

此外围设备的驱动程序模型设备节点

已连接

DSI 设备已成功连接

name

DSI 外围芯片类型

通道

分配给外围设备的虚拟通道

通道

活动的 data lanes 的数量

格式

视频模式的像素格式

mode_flags

DSI 操作模式相关标志

hs_rate

高速模式下的最大通道频率(以赫兹为单位),应将其设置为硬件的实际限制,零仅适用于旧驱动程序

lp_rate

低功耗模式下的最大通道频率(以赫兹为单位),应将其设置为硬件的实际限制,零仅适用于旧驱动程序

dsc

要发送的面板/桥 DSC pps 有效负载

struct mipi_dsi_multi_context

连续调用多个 MIPI DSI 函数的上下文

定义:

struct mipi_dsi_multi_context {
    struct mipi_dsi_device *dsi;
    int accum_err;
};

成员

dsi

指向 MIPI DSI 设备的指针

accum_err

用于存储多次调用累积的错误

初始化为 0。 如果函数遇到错误,则错误代码将存储在此处。 如果您调用一个函数并且此值指向一个非零值,则该函数将是一个空操作。 这允许连续多次调用一个函数,只需在最后检查错误以查看它们是否失败。

int mipi_dsi_pixel_format_to_bpp(enum mipi_dsi_pixel_format fmt)

获取 MIPI DSI 规范定义的任何给定像素格式的每像素位数

参数

enum mipi_dsi_pixel_format fmt

MIPI DSI 像素格式

返回

给定像素格式的每像素位数。

enum mipi_dsi_dcs_tear_mode

撕裂效应输出线模式

常量

MIPI_DSI_DCS_TEAR_MODE_VBLANK

TE 输出线仅包含 V-消隐信息

MIPI_DSI_DCS_TEAR_MODE_VHBLANK

TE 输出线包含 V-消隐和 H-消隐信息

mipi_dsi_generic_write_seq

mipi_dsi_generic_write_seq (dsi, seq...)

使用通用写入数据包传输数据

参数

dsi

DSI 外围设备

seq...

包含有效负载的缓冲区

描述

此宏将为您打印错误,并在出错时从调用函数返回(是的,这很不直观)。

由于不直观的返回行为,此宏已弃用。 请将对此宏的调用替换为 mipi_dsi_generic_write_seq_multi()

mipi_dsi_generic_write_seq_multi

mipi_dsi_generic_write_seq_multi (ctx, seq...)

使用通用写入数据包传输数据

参数

ctx

用于多个 DSI 事务的上下文

seq...

包含有效负载的缓冲区

描述

此宏将为您打印错误,并且错误处理已针对连续多次调用此方法的调用者进行了优化。

mipi_dsi_dcs_write_seq_multi

mipi_dsi_dcs_write_seq_multi (ctx, cmd, seq...)

传输带有有效负载的 DCS 命令

参数

ctx

用于多个 DSI 事务的上下文

cmd

命令

seq...

包含要传输的数据的缓冲区

描述

此宏将为您打印错误,并且错误处理已针对连续多次调用此方法的调用者进行了优化。

struct mipi_dsi_driver

DSI 驱动程序

定义:

struct mipi_dsi_driver {
    struct device_driver driver;
    int(*probe)(struct mipi_dsi_device *dsi);
    void (*remove)(struct mipi_dsi_device *dsi);
    void (*shutdown)(struct mipi_dsi_device *dsi);
};

成员

驱动程序

设备驱动程序模型驱动程序

探测

用于设备绑定的回调

移除

用于设备解绑的回调

关闭

在关闭时调用以使设备静止

struct mipi_dsi_device *of_find_mipi_dsi_device_by_node(struct device_node *np)

查找与设备树节点匹配的 MIPI DSI 设备

参数

struct device_node *np

设备树节点

返回

指向对应于 np 的 MIPI DSI 设备的指针,如果没有,则为 NULL

存在此类设备(或尚未注册)。

struct mipi_dsi_device *mipi_dsi_device_register_full(struct mipi_dsi_host *host, const struct mipi_dsi_device_info *info)

创建 MIPI DSI 设备

参数

struct mipi_dsi_host *host

此设备连接到的 DSI 主机

const struct mipi_dsi_device_info *info

指向包含 DSI 设备信息的模板的指针

描述

通过使用 mipi_dsi_device_info 模板提供的设备信息来创建 MIPI DSI 设备

返回

指向新创建的 MIPI DSI 设备的指针,或使用错误编码的指针

void mipi_dsi_device_unregister(struct mipi_dsi_device *dsi)

注销 MIPI DSI 设备

参数

struct mipi_dsi_device *dsi

DSI 外围设备

struct mipi_dsi_device *devm_mipi_dsi_device_register_full(struct device *dev, struct mipi_dsi_host *host, const struct mipi_dsi_device_info *info)

创建托管的 MIPI DSI 设备

参数

struct device *dev

用于将 MIPI-DSI 设备生命周期绑定到的设备

struct mipi_dsi_host *host

此设备连接到的 DSI 主机

const struct mipi_dsi_device_info *info

指向包含 DSI 设备信息的模板的指针

描述

通过使用 mipi_dsi_device_info 模板提供的设备信息来创建 MIPI DSI 设备

这是 mipi_dsi_device_register_full() 的托管版本,它会在 dev 未绑定时自动调用 mipi_dsi_device_unregister()

返回

指向新创建的 MIPI DSI 设备的指针,或使用错误编码的指针

struct mipi_dsi_host *of_find_mipi_dsi_host_by_node(struct device_node *node)

查找与设备树节点匹配的 MIPI DSI 主机

参数

struct device_node *node

设备树节点

返回

指向对应于 node 的 MIPI DSI 主机的指针,如果没有此类设备(或尚未注册),则为 NULL。

int mipi_dsi_attach(struct mipi_dsi_device *dsi)

将 DSI 设备连接到其 DSI 主机

参数

struct mipi_dsi_device *dsi

DSI 外围设备

int mipi_dsi_detach(struct mipi_dsi_device *dsi)

从其 DSI 主机分离 DSI 设备

参数

struct mipi_dsi_device *dsi

DSI 外围设备

int devm_mipi_dsi_attach(struct device *dev, struct mipi_dsi_device *dsi)

将 MIPI-DSI 设备连接到其 DSI 主机

参数

struct device *dev

用于将 MIPI-DSI 设备连接生命周期绑定到的设备

struct mipi_dsi_device *dsi

DSI 外围设备

描述

这是 mipi_dsi_attach() 的托管版本,它会在 dev 未绑定时自动调用 mipi_dsi_detach()

返回

成功返回 0,失败返回负错误代码。

bool mipi_dsi_packet_format_is_short(u8 type)

检查数据包是否为短格式

参数

u8 type

数据包的 MIPI DSI 数据类型

返回

如果给定数据类型的数据包是短数据包,则返回 true,否则返回 false。

bool mipi_dsi_packet_format_is_long(u8 type)

检查数据包是否为长格式

参数

u8 type

数据包的 MIPI DSI 数据类型

返回

如果给定数据类型的数据包是长数据包,则返回 true,否则返回 false。

int mipi_dsi_create_packet(struct mipi_dsi_packet *packet, const struct mipi_dsi_msg *msg)

根据 DSI 协议从消息创建数据包

参数

struct mipi_dsi_packet *packet

指向 DSI 数据包结构的指针

const struct mipi_dsi_msg *msg

要转换为数据包的消息

返回

成功时为 0,失败时为负错误代码。

int mipi_dsi_shutdown_peripheral(struct mipi_dsi_device *dsi)

发送关机外设命令

参数

struct mipi_dsi_device *dsi

DSI 外围设备

返回

成功时为 0,失败时为负错误代码。

int mipi_dsi_turn_on_peripheral(struct mipi_dsi_device *dsi)

发送打开外设命令

参数

struct mipi_dsi_device *dsi

DSI 外围设备

描述

此函数已弃用。 请改用 mipi_dsi_turn_on_peripheral_multi()

返回

成功时为 0,失败时为负错误代码。

int mipi_dsi_compression_mode_ext(struct mipi_dsi_device *dsi, bool enable, enum mipi_dsi_compression_algo algo, unsigned int pps_selector)

在外围设备上启用/禁用 DSC

参数

struct mipi_dsi_device *dsi

DSI 外围设备

bool enable

是否启用或禁用 DSC

enum mipi_dsi_compression_algo algo

选定的压缩算法

unsigned int pps_selector

从预存储或上载的 PPS 条目的表中选择 PPS

描述

在外围设备上启用或禁用显示流压缩。 此函数已弃用。 请改用 mipi_dsi_compression_mode_ext_multi()

返回

成功时为 0,失败时为负错误代码。

int mipi_dsi_compression_mode(struct mipi_dsi_device *dsi, bool enable)

在外围设备上启用/禁用 DSC

参数

struct mipi_dsi_device *dsi

DSI 外围设备

bool enable

是否启用或禁用 DSC

描述

使用默认的图片参数集和 VESA DSC 1.1 算法在外部设备上启用或禁用 Display Stream Compression(显示流压缩)。

返回

成功时为 0,失败时为负错误代码。

int mipi_dsi_picture_parameter_set(struct mipi_dsi_device *dsi, const struct drm_dsc_picture_parameter_set *pps)

将 DSC PPS 传输到外部设备

参数

struct mipi_dsi_device *dsi

DSI 外围设备

const struct drm_dsc_picture_parameter_set *pps

VESA DSC 1.1 图片参数集

描述

将 VESA DSC 1.1 图片参数集传输到外部设备。此函数已弃用。请改用 mipi_dsi_picture_parameter_set_multi()

返回

成功时为 0,失败时为负错误代码。

ssize_t mipi_dsi_generic_write(struct mipi_dsi_device *dsi, const void *payload, size_t size)

使用通用写入数据包传输数据

参数

struct mipi_dsi_device *dsi

DSI 外围设备

const void *payload

包含有效负载的缓冲区

size_t size

payload 缓冲区的大小

描述

此函数将根据 payload 长度自动选择正确的数据类型。

返回

成功传输的字节数,失败则为负的错误代码。

int mipi_dsi_generic_write_chatty(struct mipi_dsi_device *dsi, const void *payload, size_t size)

mipi_dsi_generic_write() 带错误日志

参数

struct mipi_dsi_device *dsi

DSI 外围设备

const void *payload

包含有效负载的缓冲区

size_t size

payload 缓冲区的大小

描述

mipi_dsi_generic_write() 类似,但包含一个 dev_err() 调用,并在成功时返回 0,而不是发送的字节数。

返回

成功时为 0,失败时为负错误代码。

void mipi_dsi_generic_write_multi(struct mipi_dsi_multi_context *ctx, const void *payload, size_t size)

mipi_dsi_generic_write_chatty() 带 accum_err

参数

struct mipi_dsi_multi_context *ctx

用于多个 DSI 事务的上下文

const void *payload

包含有效负载的缓冲区

size_t size

payload 缓冲区的大小

描述

mipi_dsi_generic_write_chatty() 类似,但以一种方便连续进行多次调用的方式处理错误。

ssize_t mipi_dsi_generic_read(struct mipi_dsi_device *dsi, const void *params, size_t num_params, void *data, size_t size)

使用通用读取数据包接收数据

参数

struct mipi_dsi_device *dsi

DSI 外围设备

const void *params

包含请求参数的缓冲区

size_t num_params

请求参数的数量

void *data

用于返回接收数据的缓冲区

size_t size

接收缓冲区的大小

描述

此函数将根据传入的参数数量自动选择正确的数据类型。

返回

成功读取的字节数,失败则为负的错误代码。

u32 drm_mipi_dsi_get_input_bus_fmt(enum mipi_dsi_pixel_format dsi_format)

获取给定 DSI 输出像素格式所需的基于 MEDIA_BUS_FMT_* 的输入像素格式

参数

enum mipi_dsi_pixel_format dsi_format

DSI 主机需要输出的像素格式

描述

各种 DSI 主机可以在其 drm_bridge_funcs.atomic_get_input_bus_fmts 操作期间使用此函数来确定作为输入所需的 MEDIA_BUS_FMT_* 像素格式。

返回

成功时为 32 位 MEDIA_BUS_FMT_* 值,失败时为 0。

ssize_t mipi_dsi_dcs_write_buffer(struct mipi_dsi_device *dsi, const void *data, size_t len)

传输带有有效负载的 DCS 命令

参数

struct mipi_dsi_device *dsi

DSI 外围设备

const void *data

包含要传输的数据的缓冲区

size_t len

传输缓冲区的大小

描述

此函数将根据命令 payload 长度自动选择正确的数据类型。

返回

成功传输的字节数,失败则为负的错误代码。

int mipi_dsi_dcs_write_buffer_chatty(struct mipi_dsi_device *dsi, const void *data, size_t len)

mipi_dsi_dcs_write_buffer() 带错误日志

参数

struct mipi_dsi_device *dsi

DSI 外围设备

const void *data

包含要传输的数据的缓冲区

size_t len

传输缓冲区的大小

描述

mipi_dsi_dcs_write_buffer() 类似,但包含一个 dev_err() 调用,并在成功时返回 0,而不是发送的字节数。

返回

成功时为 0,失败时为负错误代码。

void mipi_dsi_dcs_write_buffer_multi(struct mipi_dsi_multi_context *ctx, const void *data, size_t len)

mipi_dsi_dcs_write_buffer_chatty() 带 accum_err

参数

struct mipi_dsi_multi_context *ctx

用于多个 DSI 事务的上下文

const void *data

包含要传输的数据的缓冲区

size_t len

传输缓冲区的大小

描述

mipi_dsi_dcs_write_buffer_chatty() 类似,但以一种方便连续进行多次调用的方式处理错误。

ssize_t mipi_dsi_dcs_write(struct mipi_dsi_device *dsi, u8 cmd, const void *data, size_t len)

发送 DCS 写入命令

参数

struct mipi_dsi_device *dsi

DSI 外围设备

u8 cmd

DCS 命令

const void *data

包含命令 payload 的缓冲区

size_t len

命令 payload 长度

描述

此函数将根据命令 payload 长度自动选择正确的数据类型。

返回

成功传输的字节数,失败则为负的错误代码。

ssize_t mipi_dsi_dcs_read(struct mipi_dsi_device *dsi, u8 cmd, void *data, size_t len)

发送 DCS 读取请求命令

参数

struct mipi_dsi_device *dsi

DSI 外围设备

u8 cmd

DCS 命令

void *data

用于接收数据的缓冲区

size_t len

接收缓冲区的大小

返回

读取的字节数,失败则为负的错误代码。

int mipi_dsi_dcs_nop(struct mipi_dsi_device *dsi)

发送 DCS nop 数据包

参数

struct mipi_dsi_device *dsi

DSI 外围设备

描述

此函数已弃用。请改用 mipi_dsi_dcs_nop_multi()

返回

成功时为 0,失败时为负错误代码。

int mipi_dsi_dcs_soft_reset(struct mipi_dsi_device *dsi)

执行显示模块的软件重置

参数

struct mipi_dsi_device *dsi

DSI 外围设备

描述

此函数已弃用。请改用 mipi_dsi_dcs_soft_reset_multi()

返回

成功时为 0,失败时为负错误代码。

int mipi_dsi_dcs_get_power_mode(struct mipi_dsi_device *dsi, u8 *mode)

查询显示模块的当前电源模式

参数

struct mipi_dsi_device *dsi

DSI 外围设备

u8 *mode

当前电源模式的返回位置

返回

成功时为 0,失败时为负错误代码。

int mipi_dsi_dcs_get_pixel_format(struct mipi_dsi_device *dsi, u8 *format)

获取界面使用的 RGB 图像数据的像素格式

参数

struct mipi_dsi_device *dsi

DSI 外围设备

u8 *format

像素格式的返回位置

返回

成功时为 0,失败时为负错误代码。

int mipi_dsi_dcs_enter_sleep_mode(struct mipi_dsi_device *dsi)

禁用显示模块内部所有不必要的块,除了界面通信

参数

struct mipi_dsi_device *dsi

DSI 外围设备

描述

此函数已弃用。请改用 mipi_dsi_dcs_enter_sleep_mode_multi()

返回

成功时为 0,失败时为负错误代码。

int mipi_dsi_dcs_exit_sleep_mode(struct mipi_dsi_device *dsi)

启用显示模块内部所有块

参数

struct mipi_dsi_device *dsi

DSI 外围设备

描述

此函数已弃用。请改用 mipi_dsi_dcs_exit_sleep_mode_multi()

返回

成功时为 0,失败时为负错误代码。

int mipi_dsi_dcs_set_display_off(struct mipi_dsi_device *dsi)

停止在显示设备上显示图像数据

参数

struct mipi_dsi_device *dsi

DSI 外围设备

描述

此函数已弃用。请改用 mipi_dsi_dcs_set_display_off_multi()

返回

成功时为 0,失败时为负错误代码。

int mipi_dsi_dcs_set_display_on(struct mipi_dsi_device *dsi)

开始在显示设备上显示图像数据

参数

struct mipi_dsi_device *dsi

DSI 外围设备

描述

此函数已弃用。请改用 mipi_dsi_dcs_set_display_on_multi()

返回

成功时为 0,失败则为负的错误代码

int mipi_dsi_dcs_set_column_address(struct mipi_dsi_device *dsi, u16 start, u16 end)

定义主机处理器访问的帧存储器的列范围

参数

struct mipi_dsi_device *dsi

DSI 外围设备

u16 start

帧存储器的第一列

u16 end

帧存储器的最后一列

描述

此函数已弃用。请改用 mipi_dsi_dcs_set_column_address_multi()

返回

成功时为 0,失败时为负错误代码。

int mipi_dsi_dcs_set_page_address(struct mipi_dsi_device *dsi, u16 start, u16 end)

定义主机处理器访问的帧存储器的页面范围

参数

struct mipi_dsi_device *dsi

DSI 外围设备

u16 start

帧存储器的第一页

u16 end

帧存储器的最后一页

描述

此函数已弃用。请改用 mipi_dsi_dcs_set_page_address_multi()

返回

成功时为 0,失败时为负错误代码。

int mipi_dsi_dcs_set_tear_on(struct mipi_dsi_device *dsi, enum mipi_dsi_dcs_tear_mode mode)

在 TE 信号线上打开显示模块的 Tearing Effect 输出信号。

参数

struct mipi_dsi_device *dsi

DSI 外围设备

enum mipi_dsi_dcs_tear_mode mode

Tearing Effect 输出行模式

描述

此函数已弃用。请改用 mipi_dsi_dcs_set_tear_on_multi()

返回

成功时为 0,失败则为负的错误代码

int mipi_dsi_dcs_set_pixel_format(struct mipi_dsi_device *dsi, u8 format)

设置界面使用的 RGB 图像数据的像素格式

参数

struct mipi_dsi_device *dsi

DSI 外围设备

u8 format

像素格式

描述

此函数已弃用。请改用 mipi_dsi_dcs_set_pixel_format_multi()

返回

成功时为 0,失败时为负错误代码。

int mipi_dsi_dcs_set_tear_scanline(struct mipi_dsi_device *dsi, u16 scanline)

设置要用作显示模块 Tearing Effect 输出信号触发器的扫描线

参数

struct mipi_dsi_device *dsi

DSI 外围设备

u16 scanline

要用作触发器的扫描线

描述

此函数已弃用。请改用 mipi_dsi_dcs_set_tear_scanline_multi()

返回

成功时为 0,失败则为负的错误代码

int mipi_dsi_dcs_set_display_brightness(struct mipi_dsi_device *dsi, u16 brightness)

设置显示器的亮度值

参数

struct mipi_dsi_device *dsi

DSI 外围设备

u16 brightness

亮度值

描述

此函数已弃用。请改用 mipi_dsi_dcs_set_display_brightness_multi()

返回

成功时为 0,失败时为负错误代码。

int mipi_dsi_dcs_get_display_brightness(struct mipi_dsi_device *dsi, u16 *brightness)

获取显示器的当前亮度值

参数

struct mipi_dsi_device *dsi

DSI 外围设备

u16 *brightness

亮度值

返回

成功时为 0,失败时为负错误代码。

int mipi_dsi_dcs_set_display_brightness_large(struct mipi_dsi_device *dsi, u16 brightness)

设置显示器的 16 位亮度值

参数

struct mipi_dsi_device *dsi

DSI 外围设备

u16 brightness

亮度值

返回

成功时为 0,失败时为负错误代码。

int mipi_dsi_dcs_get_display_brightness_large(struct mipi_dsi_device *dsi, u16 *brightness)

获取显示器的当前 16 位亮度值

参数

struct mipi_dsi_device *dsi

DSI 外围设备

u16 *brightness

亮度值

返回

成功时为 0,失败时为负错误代码。

void mipi_dsi_picture_parameter_set_multi(struct mipi_dsi_multi_context *ctx, const struct drm_dsc_picture_parameter_set *pps)

将 DSC PPS 传输到外部设备

参数

struct mipi_dsi_multi_context *ctx

用于多个 DSI 事务的上下文

const struct drm_dsc_picture_parameter_set *pps

VESA DSC 1.1 图片参数集

描述

mipi_dsi_picture_parameter_set() 类似,但以一种方便连续进行多次调用的方式处理错误。

void mipi_dsi_compression_mode_ext_multi(struct mipi_dsi_multi_context *ctx, bool enable, enum mipi_dsi_compression_algo algo, unsigned int pps_selector)

在外围设备上启用/禁用 DSC

参数

struct mipi_dsi_multi_context *ctx

用于多个 DSI 事务的上下文

bool enable

是否启用或禁用 DSC

enum mipi_dsi_compression_algo algo

选定的压缩算法

unsigned int pps_selector

从预存储或上载的 PPS 条目的表中选择 PPS

描述

mipi_dsi_compression_mode_ext() 类似,但以一种方便连续进行多次调用的方式处理错误。

void mipi_dsi_compression_mode_multi(struct mipi_dsi_multi_context *ctx, bool enable)

在外围设备上启用/禁用 DSC

参数

struct mipi_dsi_multi_context *ctx

用于多个 DSI 事务的上下文

bool enable

是否启用或禁用 DSC

描述

使用默认的图片参数集和 VESA DSC 1.1 算法在外部设备上启用或禁用 Display Stream Compression(显示流压缩)。

void mipi_dsi_dcs_nop_multi(struct mipi_dsi_multi_context *ctx)

发送 DCS NOP 数据包

参数

struct mipi_dsi_multi_context *ctx

用于多个 DSI 事务的上下文

描述

mipi_dsi_dcs_nop() 类似,但以一种方便连续进行多次调用的方式处理错误。

void mipi_dsi_dcs_enter_sleep_mode_multi(struct mipi_dsi_multi_context *ctx)

发送 DCS ENTER_SLEEP_MODE 数据包

参数

struct mipi_dsi_multi_context *ctx

用于多个 DSI 事务的上下文

描述

mipi_dsi_dcs_enter_sleep_mode() 类似,但以一种方便连续进行多次调用的方式处理错误。

void mipi_dsi_dcs_exit_sleep_mode_multi(struct mipi_dsi_multi_context *ctx)

发送 DCS EXIT_SLEEP_MODE 数据包

参数

struct mipi_dsi_multi_context *ctx

用于多个 DSI 事务的上下文

描述

mipi_dsi_dcs_exit_sleep_mode() 类似,但以一种方便连续进行多次调用的方式处理错误。

void mipi_dsi_dcs_set_display_off_multi(struct mipi_dsi_multi_context *ctx)

发送 DCS SET_DISPLAY_OFF 数据包

参数

struct mipi_dsi_multi_context *ctx

用于多个 DSI 事务的上下文

描述

类似于 mipi_dsi_dcs_set_display_off(),但是以一种方便连续进行多次调用的方式处理错误。

void mipi_dsi_dcs_set_display_on_multi(struct mipi_dsi_multi_context *ctx)

发送 DCS SET_DISPLAY_ON 数据包

参数

struct mipi_dsi_multi_context *ctx

用于多个 DSI 事务的上下文

描述

类似于 mipi_dsi_dcs_set_display_on(),但是以一种方便连续进行多次调用的方式处理错误。

void mipi_dsi_dcs_set_tear_on_multi(struct mipi_dsi_multi_context *ctx, enum mipi_dsi_dcs_tear_mode mode)

发送 DCS SET_TEAR_ON 数据包

参数

struct mipi_dsi_multi_context *ctx

用于多个 DSI 事务的上下文

enum mipi_dsi_dcs_tear_mode mode

Tearing Effect 输出行模式

描述

类似于 mipi_dsi_dcs_set_tear_on(),但是以一种方便连续进行多次调用的方式处理错误。

void mipi_dsi_turn_on_peripheral_multi(struct mipi_dsi_multi_context *ctx)

发送打开外设命令

参数

struct mipi_dsi_multi_context *ctx

用于多个 DSI 事务的上下文

描述

类似于 mipi_dsi_turn_on_peripheral(),但是以一种方便连续进行多次调用的方式处理错误。

void mipi_dsi_dcs_set_tear_off_multi(struct mipi_dsi_multi_context *ctx)

关闭显示模块在 TE 信号线上的 Tearing Effect 输出信号

参数

struct mipi_dsi_multi_context *ctx

用于多个 DSI 事务的上下文

void mipi_dsi_dcs_soft_reset_multi(struct mipi_dsi_multi_context *ctx)

执行显示模块的软件重置

参数

struct mipi_dsi_multi_context *ctx

用于多个 DSI 事务的上下文

描述

类似于 mipi_dsi_dcs_soft_reset(),但是以一种方便连续进行多次调用的方式处理错误。

void mipi_dsi_dcs_set_display_brightness_multi(struct mipi_dsi_multi_context *ctx, u16 brightness)

设置显示器的亮度值

参数

struct mipi_dsi_multi_context *ctx

用于多个 DSI 事务的上下文

u16 brightness

亮度值

描述

类似于 mipi_dsi_dcs_set_display_brightness(),但是以一种方便连续进行多次调用的方式处理错误。

void mipi_dsi_dcs_set_pixel_format_multi(struct mipi_dsi_multi_context *ctx, u8 format)

设置界面使用的 RGB 图像数据的像素格式

参数

struct mipi_dsi_multi_context *ctx

用于多个 DSI 事务的上下文

u8 format

像素格式

描述

类似于 mipi_dsi_dcs_set_pixel_format(),但是以一种方便连续进行多次调用的方式处理错误。

void mipi_dsi_dcs_set_column_address_multi(struct mipi_dsi_multi_context *ctx, u16 start, u16 end)

定义主机处理器访问的帧存储器的列范围

参数

struct mipi_dsi_multi_context *ctx

用于多个 DSI 事务的上下文

u16 start

帧存储器的第一列

u16 end

帧存储器的最后一列

描述

类似于 mipi_dsi_dcs_set_column_address(),但是以一种方便连续进行多次调用的方式处理错误。

void mipi_dsi_dcs_set_page_address_multi(struct mipi_dsi_multi_context *ctx, u16 start, u16 end)

定义主机处理器访问的帧存储器的页面范围

参数

struct mipi_dsi_multi_context *ctx

用于多个 DSI 事务的上下文

u16 start

帧存储器的第一页

u16 end

帧存储器的最后一页

描述

类似于 mipi_dsi_dcs_set_page_address(),但是以一种方便连续进行多次调用的方式处理错误。

void mipi_dsi_dcs_set_tear_scanline_multi(struct mipi_dsi_multi_context *ctx, u16 scanline)

设置要用作显示模块 Tearing Effect 输出信号触发器的扫描线

参数

struct mipi_dsi_multi_context *ctx

用于多个 DSI 事务的上下文

u16 scanline

要用作触发器的扫描线

描述

类似于 mipi_dsi_dcs_set_tear_scanline(),但是以一种方便连续进行多次调用的方式处理错误。

int mipi_dsi_driver_register_full(struct mipi_dsi_driver *drv, struct module *owner)

注册 DSI 设备的驱动程序

参数

struct mipi_dsi_driver *drv

DSI 驱动程序结构

struct module *owner

所有者模块

返回

成功时为 0,失败时为负错误代码。

void mipi_dsi_driver_unregister(struct mipi_dsi_driver *drv)

注销 DSI 设备的驱动程序

参数

struct mipi_dsi_driver *drv

DSI 驱动程序结构

返回

成功时为 0,失败时为负错误代码。

显示流压缩辅助函数参考

DP 1.4 的 VESA 规范增加了一项名为显示流压缩 (DSC) 的新功能,用于在通过 DP/eDP/MIPI DSI 接口发送像素位之前对其进行压缩。需要启用 DSC,以便现有显示接口可以使用这些接口的最大可用链路容量,以更高的帧速率支持高分辨率。

这些函数包含一些通用逻辑和辅助函数,用于处理 DP/eDP 或 MIPI 显示接口上 DSC 所需的 VESA 显示流压缩标准。

struct drm_dsc_rc_range_parameters

DSC 速率控制范围参数

定义:

struct drm_dsc_rc_range_parameters {
    u8 range_min_qp;
    u8 range_max_qp;
    u8 range_bpg_offset;
};

成员

range_min_qp

此范围允许的最小量化参数

range_max_qp

此范围允许的最大量化参数

range_bpg_offset

应用于此组目标的每组位数偏移量

描述

这定义了 DSC 引擎用于压缩帧的不同速率控制参数。

struct drm_dsc_config

配置 DSC 所需的参数

定义:

struct drm_dsc_config {
    u8 line_buf_depth;
    u8 bits_per_component;
    bool convert_rgb;
    u8 slice_count;
    u16 slice_width;
    u16 slice_height;
    bool simple_422;
    u16 pic_width;
    u16 pic_height;
    u8 rc_tgt_offset_high;
    u8 rc_tgt_offset_low;
    u16 bits_per_pixel;
    u8 rc_edge_factor;
    u8 rc_quant_incr_limit1;
    u8 rc_quant_incr_limit0;
    u16 initial_xmit_delay;
    u16 initial_dec_delay;
    bool block_pred_enable;
    u8 first_line_bpg_offset;
    u16 initial_offset;
    u16 rc_buf_thresh[DSC_NUM_BUF_RANGES - 1];
    struct drm_dsc_rc_range_parameters rc_range_params[DSC_NUM_BUF_RANGES];
    u16 rc_model_size;
    u8 flatness_min_qp;
    u8 flatness_max_qp;
    u8 initial_scale_value;
    u16 scale_decrement_interval;
    u16 scale_increment_interval;
    u16 nfl_bpg_offset;
    u16 slice_bpg_offset;
    u16 final_offset;
    bool vbr_enable;
    u8 mux_word_size;
    u16 slice_chunk_size;
    u16 rc_bits;
    u8 dsc_version_minor;
    u8 dsc_version_major;
    bool native_422;
    bool native_420;
    u8 second_line_bpg_offset;
    u16 nsl_bpg_offset;
    u16 second_line_offset_adj;
};

成员

line_buf_depth

先前重建的行缓冲区的每个组件的位数

bits_per_component

要编码的每个组件的位数 (8/10/12)

convert_rgb

标志,指示是否需要 RGB - YCoCg 转换 如果为 RGB 输入,则为 True;如果为 YCoCg 输入,则为 False

slice_count

DSC 编码器使用的每行切片数

slice_width

每个切片的宽度(以像素为单位)

slice_height

切片高度(以像素为单位)

simple_422

如果启用了简单 4_2_2 模式,则为 True;否则为 False

pic_width

输入显示帧的宽度(以像素为单位)

pic_height

输入显示帧的垂直高度

rc_tgt_offset_high

RC 用于确定 QP 调整的位数/组的偏移量

rc_tgt_offset_low

RC 用于确定 QP 调整的位数/组的偏移量

bits_per_pixel

目标每像素位数,带 4 个小数位,bits_per_pixel << 4

rc_edge_factor

用于根据生成的位数确定是否存在边缘的因子

rc_quant_incr_limit1

一旦范围达到此值,则减慢递增速度

rc_quant_incr_limit0

一旦范围达到此值,则减慢递增速度

initial_xmit_delay

延迟初始传输的像素数

initial_dec_delay

初始解码器延迟,解码器在其速率缓冲区中累积数据,然后开始解码和输出像素的像素时间数。

block_pred_enable

如果使用块预测来编码图片中的任何组,则为 True。 如果未使用 BP,则为 False

first_line_bpg_offset

在切片的第一行上为每个组分配的额外位数。

initial_offset

在切片开始时用于 RC 模型偏移量的值

rc_buf_thresh

定义每个缓冲区范围的阈值

rc_range_params

struct drm_dsc_rc_range_parameters 中定义的每个 RC 范围的参数

rc_model_size

RC 模型的总大小

flatness_min_qp

发送平面信息时的最小 QP

flatness_max_qp

发送平面信息时的最大 QP

initial_scale_value

比例因子的初始值

scale_decrement_interval

指定在切片开始时递减比例因子之间的组时间数。

scale_increment_interval

在切片开始时使用的增加比例因子值的组时间数。

nfl_bpg_offset

要使用的非第一行 BPG 偏移量

slice_bpg_offset

用于强制切片位的 BPG 偏移量

final_offset

最终 RC 线性变换偏移量值

vbr_enable

如果启用了 VBR 模式,则为 True;如果禁用,则为 false

mux_word_size

SSM 模式的 Mux 字大小(以位为单位)

slice_chunk_size

在切片多路复用中使用的“块”的最大大小(以字节为单位)。

rc_bits

速率控制缓冲区大小(以位为单位)

dsc_version_minor

DSC 次要版本

dsc_version_major

DSC 主要版本

native_422

如果支持 Native 4:2:2,则为 True;否则为 false

native_420

如果支持 Native 4:2:0,则为 True;否则为 false。

second_line_bpg_offset

Native 4:2:0 的切片的第二行的额外位数/组

nsl_bpg_offset

为切片第二行中的每个组分配的位数

second_line_offset_adj

Native 4:2:0 模式下第二行的偏移量调整

描述

驱动程序使用配置源上的显示流压缩所需的所有参数填充此结构。

struct drm_dsc_picture_parameter_set

表示 128 字节的图片参数集

定义:

struct drm_dsc_picture_parameter_set {
    u8 dsc_version;
    u8 pps_identifier;
    u8 pps_reserved;
    u8 pps_3;
    u8 pps_4;
    u8 bits_per_pixel_low;
    __be16 pic_height;
    __be16 pic_width;
    __be16 slice_height;
    __be16 slice_width;
    __be16 chunk_size;
    u8 initial_xmit_delay_high;
    u8 initial_xmit_delay_low;
    __be16 initial_dec_delay;
    u8 pps20_reserved;
    u8 initial_scale_value;
    __be16 scale_increment_interval;
    u8 scale_decrement_interval_high;
    u8 scale_decrement_interval_low;
    u8 pps26_reserved;
    u8 first_line_bpg_offset;
    __be16 nfl_bpg_offset;
    __be16 slice_bpg_offset;
    __be16 initial_offset;
    __be16 final_offset;
    u8 flatness_min_qp;
    u8 flatness_max_qp;
    __be16 rc_model_size;
    u8 rc_edge_factor;
    u8 rc_quant_incr_limit0;
    u8 rc_quant_incr_limit1;
    u8 rc_tgt_offset;
    u8 rc_buf_thresh[DSC_NUM_BUF_RANGES - 1];
    __be16 rc_range_parameters[DSC_NUM_BUF_RANGES];
    u8 native_422_420;
    u8 second_line_bpg_offset;
    __be16 nsl_bpg_offset;
    __be16 second_line_offset_adj;
    u32 pps_long_94_reserved;
    u32 pps_long_98_reserved;
    u32 pps_long_102_reserved;
    u32 pps_long_106_reserved;
    u32 pps_long_110_reserved;
    u32 pps_long_114_reserved;
    u32 pps_long_118_reserved;
    u32 pps_long_122_reserved;
    __be16 pps_short_126_reserved;
};

成员

dsc_version

PPS0[3:0] - dsc_version_minor:包含 DSC 的次要版本 PPS0[7:4] - dsc_version_major:包含 DSC 的主要版本

pps_identifier

PPS1[7:0] - 应用特定的标识符,可用于区分不同的 PPS 表。

pps_reserved

PPS2[7:0]- 保留字节

pps_3

PPS3[3:0] - linebuf_depth:包含用于生成位流的行缓冲区位深度。(0x0 - DSC 1.2 为 16 位,0x8 - 8 位,0xA - 10 位,0xB - 11 位,0xC - 12 位,0xD - 13 位,0xE - DSC1.2 为 14 位,0xF - DSC 1.2 为 14 位。PPS3[7:4] - bits_per_component:编码图片的原始像素的每个组件的位数。 0x0 = 16bpc(仅当 dsc_version_minor = 0x2 时允许)0x8 = 8bpc,0xA = 10bpc,0xC = 12bpc,0xE = 14bpc(也仅当 dsc_minor_version = 0x2 时允许)

pps_4

PPS4[1:0] - 这是压缩 BPP bits_per_pixel[9:0] 语法元素的最重要的 2 位。 PPS4[2] - vbr_enable:0 = VBR 已禁用,1 = VBR 已启用 PPS4[3] - simple_422:指示解码器是否丢弃样本以重建 4:2:2 图片。 PPS4[4] - Convert_rgb:指示 DSC 颜色空间转换是否处于活动状态。 PPS4[5] - blobk_pred_enable:指示是否使用 BP 来编码图片中的任何组 PPS4[7:6] - 保留位

bits_per_pixel_low

PPS5[7:0] - 指示压缩 BPP bits_per_pixel[9:0] 元素的较低有效 8 位。

pic_height

PPS6[7:0],PPS7[7:0] -pic_height:指定栅格内的像素行数。

pic_width

PPS8[7:0],PPS9[7:0] - pic_width:栅格内的像素列数。

slice_height

PPS10[7:0],PPS11[7:0] - 切片高度,以像素为单位。

slice_width

PPS12[7:0],PPS13[7:0] - 切片宽度,以像素为单位。

chunk_size

PPS14[7:0],PPS15[7:0] - 用于切片多路复用的块的大小,以字节为单位。

initial_xmit_delay_high

PPS16[1:0] - 初始传输延迟的最高有效两位。 它指定编码器在从其速率缓冲区传输数据之前等待的像素时间数。 PPS16[7:2] - 保留

initial_xmit_delay_low

PPS17[7:0] - 初始传输延迟的最低有效 8 位。

initial_dec_delay

PPS18[7:0],PPS19[7:0] - 初始解码延迟,它是解码器在其速率缓冲区中累积数据,然后开始解码和输出像素的像素时间数。

pps20_reserved

PPS20[7:0] - 保留

initial_scale_value

PPS21[5:0] - 在切片开始时使用的初始 rcXformScale 因子。 PPS21[7:6] - 保留

scale_increment_interval

PPS22[7:0],PPS23[7:0] - 在切片末尾增加 rcXformScale 因子之间的组时间数。

scale_decrement_interval_high

PPS24[3:0] - 指示在切片开始时递减 rcXformScale 因子之间的组时间的较高 4 位。 PPS24[7:4] - 保留

scale_decrement_interval_low

PPS25[7:0] - 比例递减间隔的较低 8 位

pps26_reserved

PPS26[7:0]

first_line_bpg_offset

PPS27[4:0] - 为切片第一行上的每个组分配的额外位数。 PPS27[7:5] - 保留

nfl_bpg_offset

PPS28[7:0],PPS29[7:0] - 在切片的第一行之后,包括小数位在内的为每个组取消分配的位数。

slice_bpg_offset

PPS30,PPS31[7:0] - 为强制切片约束而为每个组取消分配的位数。

initial_offset

PPS32,33[7:0] - rcXformOffset 的初始值

final_offset

PPS34,35[7:0] - rcXformOffset 的最大切片结束值

flatness_min_qp

PPS36[4:0] - 在其中指示平面度并进行平面度 QP 调整的最小 QP。 PPS36[7:5] - 保留

flatness_max_qp

PPS37[4:0] - 在其中指示平面度并进行平面度调整的最大 QP。 PPS37[7:5] - 保留

rc_model_size

PPS38,39[7:0] - RC 模型中的位数。

rc_edge_factor

PPS40[3:0] - 当前活动与先前活动的比率,以确定是否存在边缘。 PPS40[7:4] - 保留

rc_quant_incr_limit0

PPS41[4:0] - 短期 RC 中使用的 QP 阈值 PPS41[7:5] - 保留

rc_quant_incr_limit1

PPS42[4:0] - 短期 RC 中使用的 QP 阈值 PPS42[7:5] - 保留

rc_tgt_offset

PPS43[3:0] - 目标每组位数周围的可变范围的下限,该可变范围允许短期 RC。 PPS43[7:4]- 目标每组位数周围的可变范围的上限,允许短期 rc。

rc_buf_thresh

PPS44[7:0] - PPS57[7:0] - 指定 RC 模型中由 14 个阈值定义的 15 个范围的阈值。

rc_range_parameters

PPS58[7:0] - PPS87[7:0] 与 15 个范围中的每一个对应的参数。

native_422_420

PPS88[0] - 0 = 未使用 Native 4:2:2 1 = 已使用 Native 4:2:2 PPS88[1] - 0 = 未使用 Native 4:2:0 1 = 已使用 Native 4:2:0 PPS88[7:2] - 保留 6 位

second_line_bpg_offset

PPS89[4:0] - Native 4:2:0 模式下切片第二行的额外位数/组预算。 如果 DSC 次要版本为 1 或 native420 为 0,则设置为 0。 PPS89[7:5] - 保留

nsl_bpg_offset

PPS90[7:0],PPS91[7:0] - 对于切片的第二行之外的每个组,取消分配的位数。

second_line_offset_adj

PPS92[7:0],PPS93[7:0] - 在 Native 4:2:0 模式下用作第二行的偏移量调整。

pps_long_94_reserved

PPS 94、95、96、97 - 保留

pps_long_98_reserved

PPS 98、99、100、101 - 保留

pps_long_102_reserved

PPS 102、103、104、105 - 保留

pps_long_106_reserved

PPS 106、107、108、109 - 保留

pps_long_110_reserved

PPS 110、111、112、113 - 保留

pps_long_114_reserved

PPS 114 - 117 - 保留

pps_long_118_reserved

PPS 118 - 121 - 保留

pps_long_122_reserved

PPS 122- 125 - 保留

pps_short_126_reserved

PPS 126、127 - 保留

描述

VESA DSC 标准定义了图片参数集 (PPS),显示流压缩编码器必须将其传达给解码器。 PPS 封装在 128 字节中(PPS 0 到 PPS 127)。 此结构中的字段与 Vesa DSC 规范 v1.1/v1.2 中的表 4.1 一致。 跨越多个字节的 PPS 字段应以大端格式存储。

struct drm_dsc_pps_infoframe

携带图片参数集元数据的 DSC 信息帧

定义:

struct drm_dsc_pps_infoframe {
    struct dp_sdp_header pps_header;
    struct drm_dsc_picture_parameter_set pps_payload;
};

成员

pps_header

根据 DP SDP 标头格式的 struct dp_sdp_header 类型的 PPS 标头

pps_payload

根据 struct drm_dsc_picture_parameter_set 中表示的 DSC 规范表 4-1 的 PPS 有效负载字段

描述

此结构表示发送启用 VESA 显示流压缩之前所需的图片参数集元数据所需的 DSC PPS 信息帧。 这基于 DP 辅助数据包结构,并包括 drm_dp_helper.h 中的 struct dp_sdp_header 中定义的 SDP 标头和 struct drm_dsc_picture_parameter_set 中定义的 PPS 有效负载。

void drm_dsc_dp_pps_header_init(struct dp_sdp_header *pps_header)

根据 DP 1.4 规范初始化 DisplayPort 的 PPS 标头。

参数

struct dp_sdp_header *pps_header

DSC 图片参数集的辅助数据包标头,如 struct dp_sdp_header 中所定义

描述

DP 1.4 规范定义了辅助数据包,用于从源发送到接收器的图片参数信息帧。 此函数填充 struct dp_sdp_header 中定义的 SDP 标头。

int drm_dsc_dp_rc_buffer_size(u8 rc_buffer_block_size, u8 rc_buffer_size)

以字节为单位获取 rc 缓冲区大小

参数

u8 rc_buffer_block_size

块大小代码,根据 DPCD 偏移量 62h

u8 rc_buffer_size

块数 - 1,根据 DPCD 偏移量 63h

返回

字节为单位的缓冲区大小,无效输入时为 0

void drm_dsc_pps_payload_pack(struct drm_dsc_picture_parameter_set *pps_payload, const struct drm_dsc_config *dsc_cfg)

填充 DSC PPS

参数

struct drm_dsc_picture_parameter_set *pps_payload

DSC 图片参数集的按位结构。 由 struct drm_dsc_picture_parameter_set 定义

const struct drm_dsc_config *dsc_cfg

驱动程序填充的 DSC 配置数据,由 struct drm_dsc_config 定义

描述

DSC 源设备发送图片参数集 (PPS),其中包含接收器解码压缩帧所需的信息。 驱动程序使用 DSC 配置参数以 DSC 显示接收器设备期望的顺序填充 DSC PPS 结构。 对于 DSC,对于跨越多个字节的字段,接收器设备期望 PPS 有效负载采用大端格式。

void drm_dsc_set_const_params(struct drm_dsc_config *vdsc_cfg)

设置在操作模式中通常被视为常量的 DSC 参数

参数

struct drm_dsc_config *vdsc_cfg

驱动程序部分填充的 DSC 配置数据

void drm_dsc_set_rc_buf_thresh(struct drm_dsc_config *vdsc_cfg)

根据 DSC 1.2 规范设置 RC 模型的阈值。

参数

struct drm_dsc_config *vdsc_cfg

驱动程序部分填充的 DSC 配置数据

int drm_dsc_setup_rc_params(struct drm_dsc_config *vdsc_cfg, enum drm_dsc_params_type type)

根据 DSC 1.1 或 1.2 规范设置 RC 模型的参数和限制,并且在调用此函数之前必须设置 DSC C 模型所需的 bits_per_pixel 和 bits_per_component。

参数

struct drm_dsc_config *vdsc_cfg

驱动程序部分填充的 DSC 配置数据

enum drm_dsc_params_type type

要遵循的运行模式和标准

返回

如果出现错误,则为 0 或 - 错误代码

int drm_dsc_compute_rc_parameters(struct drm_dsc_config *vdsc_cfg)

根据 DSC 1.2 规范,将速率控制参数写入 struct drm_dsc_config 中定义的 dsc 配置。 必须事先提供一些配置字段。

参数

struct drm_dsc_config *vdsc_cfg

驱动程序部分填充的 DSC 配置数据

u32 drm_dsc_get_bpp_int(const struct drm_dsc_config *vdsc_cfg)

获取给定 DRM DSC 配置的每像素整数位数的值

参数

const struct drm_dsc_config *vdsc_cfg

指向 DRM DSC 配置结构的指针

返回

整数 BPP 值

u8 drm_dsc_initial_scale_value(const struct drm_dsc_config *dsc)

计算给定 DSC 配置的初始比例值

参数

const struct drm_dsc_config *dsc

指向 DRM DSC 配置结构的指针

返回

计算的初始比例值

u32 drm_dsc_flatness_det_thresh(const struct drm_dsc_config *dsc)

计算给定 DSC 配置的 flatness_det_thresh

参数

const struct drm_dsc_config *dsc

指向 DRM DSC 配置结构的指针

返回

计算出的 flatness det thresh 值

void drm_dsc_dump_config(struct drm_printer *p, int indent, const struct drm_dsc_config *cfg)

转储提供的 DSC 配置

参数

struct drm_printer *p

用于输出的打印机

int indent

制表符缩进级别(最大 5)

const struct drm_dsc_config *cfg

要打印的 DSC 配置

描述

打印 cfg 中提供的 DSC 配置。

输出探测辅助函数参考

此库为输出探测提供了一些辅助代码。它提供了一个核心 drm_connector_funcs.fill_modes 接口的实现,使用 drm_helper_probe_single_connector_modes()

它还支持使用工作项轮询连接器,以及通用的热插拔中断处理,其中驱动程序不跟踪或无法跟踪每个连接器的 hpd 中断。

此辅助库可以独立于模式设置辅助库使用。驱动程序还可以覆盖不同的部分,例如,使用它们自己的热插拔处理代码以避免探测不相关的输出。

探测辅助函数与其他显示辅助库共享函数表结构。有关详细信息,请参见 struct drm_connector_helper_funcs

void drm_kms_helper_poll_enable(struct drm_device *dev)

重新启用输出轮询。

参数

struct drm_device *dev

drm_device

描述

此函数重新启用输出轮询工作,例如在使用 drm_kms_helper_poll_disable() 临时禁用输出轮询工作(例如,在挂起/恢复期间)之后。

驱动程序可以从其设备恢复实现中调用此辅助函数。即使未启用输出轮询,调用此函数也不会出错。

如果以前从未初始化设备轮询,则此调用将触发警告并返回。

请注意,启用和禁用轮询的调用必须严格排序,当它们仅从挂起/恢复回调中调用时,情况会自动如此。

void drm_kms_helper_poll_reschedule(struct drm_device *dev)

重新调度输出轮询工作

参数

struct drm_device *dev

drm_device

描述

在启用连接器的轮询之后,此函数会重新调度输出轮询工作。

驱动程序必须在通过在 drm_connector::polled 中设置 DRM_CONNECTOR_POLL_CONNECT / DRM_CONNECTOR_POLL_DISCONNECT 标志来启用连接器的轮询之后调用此辅助函数。 请注意,如果在禁用轮询之后,通过清除连接器的这些标志,并且如果也为所有其他连接器禁用了轮询,将自动停止输出轮询工作。

只有在调用 drm_kms_helper_poll_init() / drm_kms_helper_poll_enable() 启用了轮询之后,才能调用该函数。

int drm_helper_probe_detect(struct drm_connector *connector, struct drm_modeset_acquire_ctx *ctx, bool force)

探测连接器状态

参数

struct drm_connector *connector

要探测的连接器

struct drm_modeset_acquire_ctx *ctx

acquire_ctx,或者 NULL 以让此函数处理锁定。

bool force

是否应执行破坏性探测操作。

描述

此函数调用连接器的检测回调。此函数返回 drm_connector_status,如果设置了 ctx,它也可能返回 -EDEADLK。

int drm_helper_probe_single_connector_modes(struct drm_connector *connector, uint32_t maxX, uint32_t maxY)

获取完整的显示模式集

参数

struct drm_connector *connector

要探测的连接器

uint32_t maxX

模式的最大宽度

uint32_t maxY

模式的最大高度

描述

基于 connector 在 struct drm_connector_helper_funcs 中实现的辅助回调,尝试检测所有有效的模式。模式将首先添加到连接器的 probed_modes 列表中,然后进行筛选(基于有效性和 maxXmaxY 参数),并放入正常的模式列表中。

旨在用作 drm_connector_funcs.fill_modes() vfunc 的通用实现,适用于使用 CRTC 辅助函数进行输出模式过滤和检测的驱动程序。

基本过程如下

  1. 当前连接器模式列表上的所有模式都标记为过时

  2. 使用 drm_mode_probed_add() 将新模式添加到连接器的 probed_modes 列表中。新模式的生命周期开始时状态为 OK。使用以下优先级顺序从单个源添加模式。

    最后,除了早期探测产生的模式之外,还添加通过内核命令行(video=...)指定的模式(drm_helper_probe_add_cmdline_mode())。这些模式是使用 VESA GTF/CVT 公式生成的。

  3. 模式从 probed_modes 列表移动到 modes 列表。潜在的重复模式会合并在一起(请参见 drm_connector_list_update())。在此步骤之后,probed_modes 列表将再次为空。

  4. 然后 modes 列表上的任何非过时的模式都会经过验证

  5. 任何状态不是 OK 的模式都会从连接器的模式列表中删除,并附带一条调试消息,指示拒绝该模式的原因(请参见 drm_mode_prune_invalid())。

返回

connector 上找到的模式数。

void drm_kms_helper_hotplug_event(struct drm_device *dev)

触发 KMS 热插拔事件

参数

struct drm_device *dev

连接器状态已更改的 drm_device

描述

此函数触发 userspace 的 uevent,并且调用客户端热插拔函数,该函数最常用于通知 fbdev 仿真代码并允许其更新 fbcon 输出配置。

当检测到更改时,驱动程序应从其热插拔处理代码中调用此函数。请注意,此函数不会执行任何自己的输出检测,例如 drm_helper_hpd_irq_event() 所做的那样 - 假定这已由驱动程序完成。

必须在没有模式设置锁定的进程上下文中调用此函数。

如果仅更改了一个连接器,请考虑调用 drm_kms_helper_connector_hotplug_event()

void drm_kms_helper_connector_hotplug_event(struct drm_connector *connector)

触发 KMS 连接器热插拔事件

参数

struct drm_connector *connector

已更改的 drm_connector

描述

这与 drm_kms_helper_hotplug_event() 相同,除了它为单个连接器触发更细粒度的 uevent。

bool drm_kms_helper_is_poll_worker(void)

current 任务是否为输出轮询工作线程?

参数

void

没有参数

描述

确定 current 任务是否为输出轮询工作线程。 这可以用于为输出轮询与其他上下文选择不同的代码路径。

一个用例是避免输出轮询工作线程和自动挂起工作线程之间的死锁,其中后者在调用 drm_kms_helper_poll_disable() 时等待轮询完成,而前者在连接器 ->detect 钩子中调用 pm_runtime_get_sync() 时等待运行时挂起完成。

void drm_kms_helper_poll_disable(struct drm_device *dev)

禁用输出轮询

参数

struct drm_device *dev

drm_device

描述

此函数禁用输出轮询工作。

驱动程序可以从其设备挂起实现中调用此辅助函数。 即使未启用或已禁用输出轮询,调用此函数也不会出错。 通过调用 drm_kms_helper_poll_enable() 重新启用轮询。

但是,如果从未初始化轮询,则此调用将触发警告并返回。

请注意,启用和禁用轮询的调用必须严格排序,当它们仅从挂起/恢复回调中调用时,情况会自动如此。

void drm_kms_helper_poll_init(struct drm_device *dev)

初始化并启用输出轮询

参数

struct drm_device *dev

drm_device

描述

此函数初始化并启用对 dev 的输出轮询支持。 硬件中没有可靠热插拔支持的驱动程序可以使用此辅助基础结构定期轮询此类连接器以获取其连接状态的更改。

驱动程序可以通过设置 DRM_CONNECTOR_POLL_CONNECT 和 DRM_CONNECTOR_POLL_DISCONNECT 标志来控制轮询哪些连接器。 在探测实时输出可能会导致视觉失真的连接器上,驱动程序不应设置 DRM_CONNECTOR_POLL_DISCONNECT 标志以避免这种情况。 没有标志或仅设置 DRM_CONNECTOR_POLL_HPD 的连接器将被轮询逻辑完全忽略。

请注意,可以从热插拔处理程序中轮询和探测连接器,以防热插拔中断已知为不可靠。

void drm_kms_helper_poll_fini(struct drm_device *dev)

禁用输出轮询并清理它

参数

struct drm_device *dev

drm_device

void drmm_kms_helper_poll_init(struct drm_device *dev)

初始化并启用输出轮询

参数

struct drm_device *dev

drm_device

描述

此函数初始化并启用对 dev 的输出轮询支持,类似于 drm_kms_helper_poll_init()。当 DRM 设备消失时,将自动清理轮询。

有关更多信息,请参见 drm_kms_helper_poll_init()

bool drm_connector_helper_hpd_irq_event(struct drm_connector *connector)

热插拔处理

参数

struct drm_connector *connector

drm_connector

描述

驱动程序可以使用此辅助函数在连接器上运行检测周期,该连接器在其 polled 成员中设置了 DRM_CONNECTOR_POLL_HPD 标志。

此辅助函数对于可以跟踪单个连接器的热插拔中断的驱动程序很有用。 想要为所有连接器发送热插拔事件或无法按连接器跟踪热插拔中断的驱动程序需要使用 drm_helper_hpd_irq_event()

必须在没有模式设置锁定的进程上下文中调用此函数。

请注意,可以从热插拔处理程序中轮询和探测连接器,以防热插拔中断已知为不可靠。

返回

一个布尔值,指示连接器状态是否已更改

bool drm_helper_hpd_irq_event(struct drm_device *dev)

热插拔处理

参数

struct drm_device *dev

drm_device

描述

驱动程序可以使用此辅助函数在所有连接器上运行检测周期,这些连接器在其 polled 成员中设置了 DRM_CONNECTOR_POLL_HPD 标志。 所有其他连接器都将被忽略,这对于避免重新探测固定面板很有用。

此辅助函数对于无法或不跟踪每个连接器的热插拔中断的驱动程序很有用。

支持每个连接器的热插拔中断并且具有更细粒度的检测逻辑的驱动程序可以使用 drm_connector_helper_hpd_irq_event()。 或者,如果连接器状态已更改,他们应绕过此代码并直接调用 drm_kms_helper_hotplug_event()

必须在没有模式设置锁定的进程上下文中调用此函数。

请注意,可以从热插拔处理程序中轮询和探测连接器,以防热插拔中断已知为不可靠。

返回

一个布尔值,指示连接器状态是否已更改

enum drm_mode_status drm_crtc_helper_mode_valid_fixed(struct drm_crtc *crtc, const struct drm_display_mode *mode, const struct drm_display_mode *fixed_mode)

验证显示模式

参数

struct drm_crtc *crtc

crtc

const struct drm_display_mode *mode

要验证的模式

const struct drm_display_mode *fixed_mode

显示硬件的模式

返回

成功时为 MODE_OK,否则为另一个模式状态代码。

int drm_connector_helper_get_modes_fixed(struct drm_connector *connector, const struct drm_display_mode *fixed_mode)

复制连接器的显示模式

参数

struct drm_connector *connector

连接器

const struct drm_display_mode *fixed_mode

显示硬件的模式

描述

此函数复制连接器的显示模式。 仅支持单个固定模式的硬件驱动程序可以在其连接器的 get_modes 辅助函数中使用此函数。

返回

创建的模式数。

int drm_connector_helper_get_modes(struct drm_connector *connector)

读取 EDID 并更新连接器。

参数

struct drm_connector *connector

连接器

描述

使用 drm_edid_read()(需要设置 connector->ddc)读取 EDID,并使用 EDID 更新连接器。

如果驱动程序不需要任何特殊处理,则可以将此用作“默认”连接器辅助 .get_modes() 钩子。 这设置了关于自定义 .get_modes() 钩子应该如何处理 EDID 读取和连接器更新的示例。

返回

模式数。

int drm_connector_helper_tv_get_modes(struct drm_connector *connector)

填充电视连接器可用的模式

参数

struct drm_connector *connector

连接器

描述

基于支持的电视模式和内核命令行表达的默认模式,填充电视连接器可用的模式。

如果驱动程序不需要任何特殊处理,则可以将此用作默认的电视连接器辅助 .get_modes() 钩子。

返回

添加到连接器的模式数量。

int drm_connector_helper_detect_from_ddc(struct drm_connector *connector, struct drm_modeset_acquire_ctx *ctx, bool force)

读取 EDID 并检测连接器状态。

参数

struct drm_connector *connector

连接器

struct drm_modeset_acquire_ctx *ctx

获取上下文

bool force

如有必要,执行屏幕破坏性操作

描述

通过使用 drm_probe_ddc() 读取 EDID 来检测连接器状态,这需要设置 connector->ddc。 成功时返回 connector_status_connected,失败时返回 connector_status_disconnected。

返回

enum drm_connector_status 定义的连接器状态。

EDID 辅助函数参考

const char *drm_edid_decode_mfg_id(u16 mfg_id, char vend[4])

解码制造商 ID

参数

u16 mfg_id

制造商 ID

char vend[4]

用于存储 3 个字母的供应商字符串加上“0”终止符的 4 字节缓冲区

drm_edid_encode_panel_id

drm_edid_encode_panel_id (vend_chr_0, vend_chr_1, vend_chr_2, product_id)

对 ID 进行编码以与 drm_edid_get_panel_id() 匹配

参数

vend_chr_0

供应商字符串的第一个字符。

vend_chr_1

供应商字符串的第二个字符。

vend_chr_2

供应商字符串的第三个字符。

product_id

16 位产品 ID。

描述

这是一个宏,因此可以在编译时计算并用作初始化程序。

例如

drm_edid_encode_panel_id('B', 'O', 'E', 0x2d08) => 0x09e52d08

返回

每个面板 32 位 ID。

void drm_edid_decode_panel_id(u32 panel_id, char vend[4], u16 *product_id)

drm_edid_encode_panel_id() 解码面板 ID

参数

u32 panel_id

要解码的面板 ID。

char vend[4]

用于存储 3 个字母的供应商字符串加上“0”终止符的 4 字节缓冲区

u16 *product_id

产品 ID 将在此处返回。

描述

例如,之后

drm_edid_decode_panel_id(0x09e52d08, vend, product_id)

这些将为真

vend[0] = 'B' vend[1] = 'O' vend[2] = 'E' vend[3] = '0' product_id = 0x2d08

int drm_edid_header_is_valid(const void *_edid)

对基本 EDID 块的标头进行健全性检查

参数

const void *_edid

指向原始基本 EDID 块的指针

描述

对基本 EDID 块的标头进行健全性检查。

返回

如果标头完美,则为 8,如果完全错误,则降至 0。

bool drm_edid_is_valid(struct edid *edid)

健全性检查 EDID 数据

参数

struct edid *edid

EDID 数据

描述

对整个 EDID 记录(包括扩展)进行健全性检查

返回

如果 EDID 数据有效,则为 True,否则为 false。

bool drm_edid_valid(const struct drm_edid *drm_edid)

健全性检查 EDID 数据

参数

const struct drm_edid *drm_edid

EDID 数据

描述

健全性检查 EDID。交叉检查块计数与已分配的大小,并校验块的校验和。

返回

如果 EDID 数据有效,则为 True,否则为 false。

int drm_edid_override_connector_update(struct drm_connector *connector)

从覆盖/固件 EDID 添加模式

参数

struct drm_connector *connector

我们正在探测的连接器

描述

如果可用,则从覆盖/固件 EDID 添加模式。仅用于 drm_helper_probe_single_connector_modes() 作为在 drm_get_edid() 期间 DDC 探测失败并导致跳过覆盖/固件 EDID 时的备用方案。

返回

添加的模式数量,如果找不到任何模式,则为 0。

const struct edid *drm_edid_raw(const struct drm_edid *drm_edid)

获取原始 EDID 数据的指针。

参数

const struct drm_edid *drm_edid

drm_edid 容器

描述

获取原始 EDID 数据的指针。

这仅用于过渡。避免像瘟疫一样使用它。

返回

指向原始 EDID 数据的指针。

const struct drm_edid *drm_edid_alloc(const void *edid, size_t size)

分配一个新的 drm_edid 容器

参数

const void *edid

指向原始 EDID 数据的指针

size_t size

为 EDID 分配的内存大小

描述

分配一个新的 drm_edid 容器。不要从 edid 计算 edid 大小,传递已为数据分配的实际大小。不对原始 EDID 数据进行大小验证,但至少 EDID 基本块必须适合缓冲区。

返回的指针必须使用 drm_edid_free() 释放。

返回

drm_edid 容器,如果出现错误,则为 NULL

const struct drm_edid *drm_edid_dup(const struct drm_edid *drm_edid)

复制 drm_edid 容器

参数

const struct drm_edid *drm_edid

要复制的 EDID

描述

返回的指针必须使用 drm_edid_free() 释放。

返回

drm_edid 容器副本,如果出现错误,则为 NULL

void drm_edid_free(const struct drm_edid *drm_edid)

释放 drm_edid 容器

参数

const struct drm_edid *drm_edid

要释放的 EDID

bool drm_probe_ddc(struct i2c_adapter *adapter)

探测 DDC 是否存在

参数

struct i2c_adapter *adapter

要探测的 I2C 适配器

返回

成功时为 True,失败时为 False。

struct edid *drm_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter)

获取 EDID 数据(如果可用)

参数

struct drm_connector *connector

我们正在探测的连接器

struct i2c_adapter *adapter

用于 DDC 的 I2C 适配器

描述

Poke 给定的 I2C 通道以在可能的情况下抓取 EDID 数据。如果找到,则将其附加到连接器。

返回

指向有效 EDID 的指针,如果找不到任何 EDID,则为 NULL。

const struct drm_edid *drm_edid_read_custom(struct drm_connector *connector, read_block_fn read_block, void *context)

使用给定的 EDID 块读取函数读取 EDID 数据

参数

struct drm_connector *connector

要使用的连接器

read_block_fn read_block

EDID 块读取函数

void *context

传递给块读取函数的私有数据

描述

当连接到 DDC 总线的 I2C 适配器隐藏在暴露不同接口以读取 EDID 块的设备后面时,可以使用此函数使用自定义块读取函数获取 EDID 数据。

与一般情况一样,内核可以在 I2C 级别访问 DDC 总线,驱动程序必须尽一切合理努力将其公开为 I2C 适配器,并使用 drm_edid_read()drm_edid_read_ddc(),而不是滥用此函数。

EDID 可以使用 debugfs override_edid 或固件 EDID(drm_edid_load_firmware() 和 drm.edid_firmware 参数)覆盖,此优先级顺序。拥有其中任何一个都会绕过实际的 EDID 读取。

返回的指针必须使用 drm_edid_free() 释放。

返回

指向 EDID 的指针,如果探测/读取失败,则为 NULL。

const struct drm_edid *drm_edid_read_ddc(struct drm_connector *connector, struct i2c_adapter *adapter)

使用给定的 I2C 适配器读取 EDID 数据

参数

struct drm_connector *connector

要使用的连接器

struct i2c_adapter *adapter

用于 DDC 的 I2C 适配器

描述

使用给定的 I2C 适配器读取 EDID。

EDID 可以使用 debugfs override_edid 或固件 EDID(drm_edid_load_firmware() 和 drm.edid_firmware 参数)覆盖,此优先级顺序。拥有其中任何一个都会绕过实际的 EDID 读取。

首选使用 drm_connector_init_with_ddc() 初始化 connector->ddc,并使用 drm_edid_read() 而不是此函数。

返回的指针必须使用 drm_edid_free() 释放。

返回

指向 EDID 的指针,如果探测/读取失败,则为 NULL。

const struct drm_edid *drm_edid_read(struct drm_connector *connector)

使用连接器的 I2C 适配器读取 EDID 数据

参数

struct drm_connector *connector

要使用的连接器

描述

使用连接器的 I2C 适配器读取 EDID。

EDID 可以使用 debugfs override_edid 或固件 EDID(drm_edid_load_firmware() 和 drm.edid_firmware 参数)覆盖,此优先级顺序。拥有其中任何一个都会绕过实际的 EDID 读取。

返回的指针必须使用 drm_edid_free() 释放。

返回

指向 EDID 的指针,如果探测/读取失败,则为 NULL。

void drm_edid_get_product_id(const struct drm_edid *drm_edid, struct drm_edid_product_id *id)

获取供应商和产品标识

参数

const struct drm_edid *drm_edid

EDID

struct drm_edid_product_id *id

将产品 ID 放置在哪里

void drm_edid_print_product_id(struct drm_printer *p, const struct drm_edid_product_id *id, bool raw)

将解码的产品 ID 打印到打印机

参数

struct drm_printer *p

drm 打印机

const struct drm_edid_product_id *id

EDID 产品 ID

bool raw

如果为 true,则还打印原始十六进制

描述

请参阅 VESA E-EDID 1.4 第 3.4 节。

u32 drm_edid_get_panel_id(const struct drm_edid *drm_edid)

从 EDID 获取面板的 ID

参数

const struct drm_edid *drm_edid

包含面板 ID 的 EDID。

描述

此函数使用面板 EDID 的第一个块,并(假设 EDID 有效)从中提取 ID。ID 是一个 32 位值(16 位制造商 ID 和 16 位制造商 ID),对于每个不同的面板调制解调器,它应该是不同的。

返回

一个 32 位 ID,对于面板的每个制造商/型号,它应该是不同的。

有关此 ID 的结构的详细信息,请参阅函数 drm_edid_encode_panel_id()drm_edid_decode_panel_id()。如果 EDID 大小小于基本块,则返回 0。

const struct drm_edid *drm_edid_read_base_block(struct i2c_adapter *adapter)

获取面板的 EDID 基本块

参数

struct i2c_adapter *adapter

用于 DDC 的 I2C 适配器

描述

此函数返回包含面板 EDID 的第一个块的 drm_edid。

此函数旨在用于早期探测可能存在多个面板的设备。由于其预期用途,它必须假定面板的 EDID 是正确的,至少就基本块而言(换句话说,我们在此处不处理任何覆盖)。

使用后调用者应调用 drm_edid_free()

警告:仅当连接器未知时才使用此函数。例如,在面板的早期探测期间。从此函数读取的 EDID 是临时的,应替换为从其他 drm_edid_read 返回的完整 EDID。

注意

预计此函数和 drm_do_get_edid() 都将读取 EDID,但它们之间没有缓存。由于我们只读取第一个块,因此希望这种额外的开销不会太大。

返回

指向已分配 EDID 基本块的指针,如果任何故障,则为 NULL。

struct edid *drm_get_edid_switcheroo(struct drm_connector *connector, struct i2c_adapter *adapter)

获取 vga_switcheroo 输出的 EDID 数据

参数

struct drm_connector *connector

我们正在探测的连接器

struct i2c_adapter *adapter

用于 DDC 的 I2C 适配器

描述

drm_get_edid() 的包装器,适用于具有双 GPU 并使用一组输出的笔记本电脑。包装器添加了必需的 vga_switcheroo 调用,以临时将 DDC 切换到正在检索 EDID 的 GPU。

返回

指向有效 EDID 的指针,如果找不到任何 EDID,则为 NULL

const struct drm_edid *drm_edid_read_switcheroo(struct drm_connector *connector, struct i2c_adapter *adapter)

获取 vga_switcheroo 输出的 EDID 数据

参数

struct drm_connector *connector

我们正在探测的连接器

struct i2c_adapter *adapter

用于 DDC 的 I2C 适配器

描述

drm_edid_read_ddc() 的包装器,适用于具有双 GPU 并使用一组输出的笔记本电脑。包装器添加了必需的 vga_switcheroo 调用,以临时将 DDC 切换到正在检索 EDID 的 GPU。

返回

指向有效 EDID 的指针,如果找不到任何 EDID,则为 NULL

struct edid *drm_edid_duplicate(const struct edid *edid)

复制 EDID 和扩展

参数

const struct edid *edid

要复制的 EDID

返回

指向已复制 EDID 的指针,如果分配失败,则为 NULL。

u8 drm_match_cea_mode(const struct drm_display_mode *to_match)

查找与给定模式匹配的 CEA 模式

参数

const struct drm_display_mode *to_match

显示模式

返回

模式的 CEA 视频 ID (VIC),如果不是 CEA-861 模式,则为 0。

struct drm_display_mode *drm_display_mode_from_cea_vic(struct drm_device *dev, u8 video_code)

返回 CEA VIC 的模式

参数

struct drm_device *dev

DRM 设备

u8 video_code

模式的 CEA VIC

描述

创建与指定的 CEA VIC 匹配的新模式。

返回

成功时返回一个新的 drm_display_mode;失败时返回 NULL

bool drm_edid_match(const struct drm_edid *drm_edid, const struct drm_edid_ident *ident)

将 drm_edid 与给定的标识匹配

参数

const struct drm_edid *drm_edid

EDID

const struct drm_edid_ident *ident

要匹配的 EDID 标识

描述

检查 EDID 是否与给定的标识匹配。

返回

如果给定的标识与 EDID 匹配,则为 True,否则为 False。

void drm_edid_get_monitor_name(const struct edid *edid, char *name, int bufsize)

从 edid 中获取监视器名称

参数

const struct edid *edid

监视器 EDID 信息

char *name

指向字符数组的指针,以保存监视器的名称

int bufsize

名称缓冲区的大小(应至少为 14 个字符。)

int drm_edid_to_sad(const struct edid *edid, struct cea_sad **sads)

从 EDID 中提取 SAD

参数

const struct edid *edid

要解析的 EDID

struct cea_sad **sads

指针,将设置为提取的 SAD

描述

查找 CEA EDID 块并从中提取 SAD(短音频描述符)。

注意

返回的指针需要使用 kfree() 释放。

返回

找到的 SAD 的数量,如果出现错误,则为负数。

int drm_edid_to_speaker_allocation(const struct edid *edid, u8 **sadb)

从 EDID 中提取扬声器分配数据块

参数

const struct edid *edid

要解析的 EDID

u8 **sadb

指向扬声器块的指针

描述

查找 CEA EDID 块并从中提取扬声器分配数据块。

注意

返回的指针需要使用 kfree() 释放。

返回

找到的扬声器分配块的数量,如果出现错误,则为负数。

int drm_av_sync_delay(struct drm_connector *connector, const struct drm_display_mode *mode)

计算 HDMI/DP sink 音频-视频同步延迟

参数

struct drm_connector *connector

与 HDMI/DP sink 关联的连接器

const struct drm_display_mode *mode

显示模式

返回

HDMI/DP sink 的音频-视频同步延迟(以毫秒为单位),如果 sink 不支持音频或视频,则为 0。

bool drm_detect_hdmi_monitor(const struct edid *edid)

检测监视器是否为 HDMI

参数

const struct edid *edid

监视器 EDID 信息

描述

根据 CEA-861-B 解析 CEA 扩展。

已将从 EDID 解析的模式添加到 drm_display_info 的驱动程序应使用 drm_display_info.is_hdmi 而不是调用此函数。

返回

如果监视器是 HDMI,则为 True,如果不是或未知,则为 False。

bool drm_detect_monitor_audio(const struct edid *edid)

检查监视器音频功能

参数

const struct edid *edid

要扫描的 EDID 块

描述

监视器应具有 CEA 扩展块。如果监视器具有“基本音频”,但没有 CEA 音频块,则仅为“基本音频”。如果存在任何音频扩展块和支持的音频格式,则假定至少支持“基本音频”,即使 EDID 中未定义“基本音频”。

返回

如果监视器支持音频,则为 True,否则为 False。

enum hdmi_quantization_range drm_default_rgb_quant_range(const struct drm_display_mode *mode)

默认 RGB 量化范围

参数

const struct drm_display_mode *mode

显示模式

描述

根据 CEA-861 的规定,确定模式的默认 RGB 量化范围。

返回

模式的默认 RGB 量化范围

int drm_edid_connector_update(struct drm_connector *connector, const struct drm_edid *drm_edid)

从 EDID 更新连接器信息

参数

struct drm_connector *connector

Connector

const struct drm_edid *drm_edid

EDID

描述

从传入的 EDID 更新连接器的显示信息、ELD、HDR 元数据、相关属性等。

如果 EDID 为 NULL,则重置信息。

必须在调用 drm_edid_connector_add_modes() 之前调用。

返回

成功时返回 0,发生错误时返回负错误码。

int drm_edid_connector_add_modes(struct drm_connector *connector)

从 EDID 属性更新探测到的模式

参数

struct drm_connector *connector

Connector

描述

将之前更新的 EDID 属性中的模式添加到连接器探测到的模式列表中。

必须先调用 drm_edid_connector_update() 以更新 EDID 属性。

返回

添加的模式数量,如果找不到任何模式则返回 0。

int drm_connector_update_edid_property(struct drm_connector *connector, const struct edid *edid)

更新连接器的 edid 属性

参数

struct drm_connector *connector

drm 连接器

const struct edid *edid

edid 属性的新值

描述

此函数创建一个新的 blob 模式集对象,并将其 ID 分配给连接器的 edid 属性。由于我们还从 EDID 的 displayID 块解析平铺信息,因此我们还在此处设置连接器的平铺属性。有关详细信息,请参见 drm_connector_set_tile_property()

此函数已弃用。请改用 drm_edid_connector_update()

返回

成功时为零,失败时为负 errno。

int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid)

如果可用,则从 EDID 数据添加模式

参数

struct drm_connector *connector

我们正在探测的连接器

struct edid *edid

EDID 数据

描述

将指定的模式添加到连接器的模式列表。 此外,还使用可以从 edid 派生的任何信息来填充 connector 中的 drm_display_info 结构和 ELD。

此函数已弃用。请改用 drm_edid_connector_add_modes()

返回

添加的模式数量,如果找不到任何模式,则为 0。

int drm_add_modes_noedid(struct drm_connector *connector, unsigned int hdisplay, unsigned int vdisplay)

为没有 EDID 的连接器添加模式

参数

struct drm_connector *connector

我们正在探测的连接器

unsigned int hdisplay

水平显示限制

unsigned int vdisplay

垂直显示限制

描述

将指定的模式添加到连接器的模式列表。 只有当 hdisplay/vdisplay 不超过给定的限制时,才会添加它。

返回

添加的模式数量,如果找不到任何模式,则为 0。

int drm_hdmi_avi_infoframe_from_display_mode(struct hdmi_avi_infoframe *frame, const struct drm_connector *connector, const struct drm_display_mode *mode)

使用来自 DRM 显示模式的数据填充 HDMI AVI 信息帧

参数

struct hdmi_avi_infoframe *frame

HDMI AVI 信息帧

const struct drm_connector *connector

连接器

const struct drm_display_mode *mode

DRM 显示模式

返回

成功时为 0,失败时为负错误代码。

void drm_hdmi_avi_infoframe_quant_range(struct hdmi_avi_infoframe *frame, const struct drm_connector *connector, const struct drm_display_mode *mode, enum hdmi_quantization_range rgb_quant_range)

填充 HDMI AVI 信息帧量化范围信息

参数

struct hdmi_avi_infoframe *frame

HDMI AVI 信息帧

const struct drm_connector *connector

连接器

const struct drm_display_mode *mode

DRM 显示模式

enum hdmi_quantization_range rgb_quant_range

RGB 量化范围 (Q)

int drm_hdmi_vendor_infoframe_from_display_mode(struct hdmi_vendor_infoframe *frame, const struct drm_connector *connector, const struct drm_display_mode *mode)

使用来自 DRM 显示模式的数据填充 HDMI 信息帧

参数

struct hdmi_vendor_infoframe *frame

HDMI 供应商信息帧

const struct drm_connector *connector

连接器

const struct drm_display_mode *mode

DRM 显示模式

描述

请注意,仅在使用 4k 或立体 3D 模式时才需要发送 HDMI 供应商信息帧。 因此,当提供任何其他模式作为输入时,此函数将返回 -EINVAL,此错误可以安全地忽略。

返回

成功时为 0,失败时为负错误代码。

bool drm_edid_is_digital(const struct drm_edid *drm_edid)

是数字的吗?

参数

const struct drm_edid *drm_edid

EDID

描述

如果输入是数字的,则返回 true。

int drm_eld_mnl(const u8 *eld)

以字节为单位获取 ELD 监视器名称长度。

参数

const u8 *eld

指向具有 mnl 设置的 eld 内存结构的指针

const u8 *drm_eld_sad(const u8 *eld)

获取 ELD SAD 结构。

参数

const u8 *eld

指向具有 sad_count 设置的 eld 内存结构的指针

int drm_eld_sad_count(const u8 *eld)

获取 ELD SAD 计数。

参数

const u8 *eld

指向具有 sad_count 设置的 eld 内存结构的指针

int drm_eld_calc_baseline_block_size(const u8 *eld)

以字节为单位计算基线块大小

参数

const u8 *eld

指向具有 mnl 和 sad_count 设置的 eld 内存结构的指针

描述

这是一个辅助函数,用于确定基线块的有效负载大小(以字节为单位),例如,设置 ELD 标头块中的 Baseline_ELD_Len 字段。

int drm_eld_size(const u8 *eld)

以字节为单位获取 ELD 大小

参数

const u8 *eld

指向完整 eld 内存结构的指针

描述

返回的值不包括供应商块。 它是供应商特定的,并且由 ELD 内存缓冲区中 drm_eld_size() 字节的标头和基线块之后的剩余字节组成。

保证返回的值是 4 的倍数。

u8 drm_eld_get_spk_alloc(const u8 *eld)

获取扬声器分配

参数

const u8 *eld

指向 ELD 内存结构的指针

描述

返回的值是扬声器掩码。 用户必须使用 DRM_ELD_SPEAKER 字段定义来识别扬声器。

u8 drm_eld_get_conn_type(const u8 *eld)

获取设备类型 hdmi/dp 连接

参数

const u8 *eld

指向 ELD 内存结构的指针

描述

调用者需要使用 DRM_ELD_CONN_TYPE_HDMIDRM_ELD_CONN_TYPE_DP 来识别连接的显示类型。

int drm_eld_sad_get(const u8 *eld, int sad_index, struct cea_sad *cta_sad)

从 ELD 获取 SAD 到 struct cea_sad

参数

const u8 *eld

ELD 缓冲区

int sad_index

SAD 索引

struct cea_sad *cta_sad

目标 struct cea_sad

返回

成功时返回 0,发生错误时返回负值

int drm_eld_sad_set(u8 *eld, int sad_index, const struct cea_sad *cta_sad)

从 struct cea_sad 将 SAD 设置为 ELD

参数

u8 *eld

ELD 缓冲区

int sad_index

SAD 索引

const struct cea_sad *cta_sad

源 struct cea_sad

返回

成功时返回 0,发生错误时返回负值

SCDC 辅助函数参考

状态和控制数据通道 (SCDC) 是 HDMI 2.0 规范引入的一种机制。 它是一种点对点协议,允许 HDMI 源和 HDMI sink 交换数据。 用于访问 EDID 的同一 I2C 接口用作 SCDC 的传输机制。

注意:当显示器断开连接时,SCDC 状态将丢失。 当用户断开电缆时,或者当显示器开启时(例如,唤醒电视),可能会发生这种情况。

更复杂的是,在断开/重新连接时,KMS 不会自动更改模式。 这意味着不能仅依赖于在启用时设置 SCDC 状态,还必须使用中断来跟踪连接器状态更改并恢复 SCDC 状态。 典型的解决方案是在 drm_connector_helper_funcs.detect_ctx() 中触发一个空模式集,就像 vc4 在 vc4_hdmi_reset_link() 中所做的那样。

int drm_scdc_readb(struct i2c_adapter *adapter, u8 offset, u8 *value)

从 SCDC 读取单个字节

参数

struct i2c_adapter *adapter

I2C 适配器

u8 offset

要读取的寄存器的偏移量

u8 *value

寄存器值的返回位置

描述

从 SCDC 读取单个字节。 这是 drm_scdc_read() 函数周围的一个方便的包装器。

返回

成功时为 0,失败时为负错误代码。

int drm_scdc_writeb(struct i2c_adapter *adapter, u8 offset, u8 value)

将单个字节写入 SCDC

参数

struct i2c_adapter *adapter

I2C 适配器

u8 offset

要读取的寄存器的偏移量

u8 value

寄存器值的返回位置

描述

将单个字节写入 SCDC。 这是 drm_scdc_write() 函数周围的一个方便的包装器。

返回

成功时为 0,失败时为负错误代码。

ssize_t drm_scdc_read(struct i2c_adapter *adapter, u8 offset, void *buffer, size_t size)

从 SCDC 读取数据块

参数

struct i2c_adapter *adapter

I2C 控制器

u8 offset

要读取的块的起始偏移量

void *buffer

要读取的块的返回位置

size_t size

要读取的块的大小

描述

从 SCDC 读取数据块,从给定的偏移量开始。

返回

成功时返回 0,失败时返回负错误代码。

ssize_t drm_scdc_write(struct i2c_adapter *adapter, u8 offset, const void *buffer, size_t size)

将数据块写入 SCDC

参数

struct i2c_adapter *adapter

I2C 控制器

u8 offset

要写入的块的起始偏移量

const void *buffer

要写入的数据块

size_t size

要写入的块的大小

描述

将数据块写入 SCDC,从给定的偏移量开始。

返回

成功时返回 0,失败时返回负错误代码。

bool drm_scdc_get_scrambling_status(struct drm_connector *connector)

加扰的状态是什么?

参数

struct drm_connector *connector

connector

描述

通过 SCDC 读取加扰器状态,并检查加扰状态。

返回

如果启用加扰,则为 True,否则为 False。

bool drm_scdc_set_scrambling(struct drm_connector *connector, bool enable)

启用加扰

参数

struct drm_connector *connector

connector

bool enable

bool 值,指示是要启用/禁用加扰

描述

通过 SCDC 通道写入 TMDS 配置寄存器,并且: 当 enable = 1 时启用加扰 当 enable = 0 时禁用加扰

返回

如果成功设置/重置加扰,则为 True,否则为 False。

bool drm_scdc_set_high_tmds_clock_ratio(struct drm_connector *connector, bool set)

设置 TMDS 时钟比率

参数

struct drm_connector *connector

connector

bool set

恢复或重置高时钟比率

TMDS 时钟比率计算如下

TMDS 字符 = 10 位 TMDS 编码值

TMDS 字符速率 = 传输 TMDS 字符的速率 (Mcsc)

TMDS 比特率 = 10x TMDS 字符速率

根据规范

像素时钟 < 340 MHz 的 TMDS 时钟速率 = 1x 字符速率 = 1/10 像素时钟速率

像素时钟 > 340 MHz 的 TMDS 时钟速率 = 0.25x 字符速率 = 1/40 像素时钟速率

通过 SCDC 通道写入 TMDS 配置寄存器,并且

当 set = 1 时,将 TMDS 时钟比率设置为 1/40

当 set = 0 时,将 TMDS 时钟比率设置为 1/10

返回

如果写入成功,则为 True,否则为 False。

HDMI 信息帧辅助函数参考

严格来说,这并不是 DRM 辅助库,但通常可供任何与 HDMI 输出接口的驱动程序(如 v4l 或 alsa 驱动程序)使用。 但它很好地适应了模式设置辅助库的总体主题,因此也包含在此处。

struct hdr_sink_metadata

HDR sink 元数据

定义:

struct hdr_sink_metadata {
    __u32 metadata_type;
    union {
        struct hdr_static_metadata hdmi_type1;
    };
};

成员

metadata_type

Static_Metadata_Descriptor_ID。

{unnamed_union}

anonymous

hdmi_type1

HDR 元数据信息帧。

描述

从 Sink 的 EDID 读取的元数据信息

union hdmi_infoframe

所有抽象信息帧表示的总体联合

定义:

union hdmi_infoframe {
    struct hdmi_any_infoframe any;
    struct hdmi_avi_infoframe avi;
    struct hdmi_spd_infoframe spd;
    union hdmi_vendor_any_infoframe vendor;
    struct hdmi_audio_infoframe audio;
    struct hdmi_drm_infoframe drm;
};

成员

any

通用信息帧

avi

avi 信息帧

spd

spd 信息帧

vendor

所有供应商信息帧的联合

audio

音频信息帧

drm

动态范围和母带处理信息帧

描述

这由通用打包函数使用。 这可行,因为所有信息帧都具有相同的标头,该标头还指示应打包哪种类型的信息帧。

void hdmi_avi_infoframe_init(struct hdmi_avi_infoframe *frame)

初始化 HDMI AVI 信息帧

参数

struct hdmi_avi_infoframe *frame

HDMI AVI 信息帧

int hdmi_avi_infoframe_check(struct hdmi_avi_infoframe *frame)

检查 HDMI AVI 信息帧

参数

struct hdmi_avi_infoframe *frame

HDMI AVI 信息帧

描述

验证信息帧是否一致,并根据其他字段更新派生字段(例如,长度)。

成功时返回 0,失败时返回负错误代码。

ssize_t hdmi_avi_infoframe_pack_only(const struct hdmi_avi_infoframe *frame, void *buffer, size_t size)

将 HDMI AVI 信息帧写入二进制缓冲区

参数

const struct hdmi_avi_infoframe *frame

HDMI AVI 信息帧

void *buffer

目标缓冲区

size_t size

缓冲区大小

描述

frame 结构中包含的信息打包为可以写入相应控制器寄存器的二进制表示形式。 还会根据 HDMI 1.4 规范的第 5.3.5 节的要求计算校验和。

返回打包到二进制缓冲区中的字节数,如果失败,则返回负错误代码。

ssize_t hdmi_avi_infoframe_pack(struct hdmi_avi_infoframe *frame, void *buffer, size_t size)

检查 HDMI AVI 信息帧,并将其写入二进制缓冲区

参数

struct hdmi_avi_infoframe *frame

HDMI AVI 信息帧

void *buffer

目标缓冲区

size_t size

缓冲区大小

描述

验证信息帧的一致性,并基于其他字段更新派生字段(例如长度),然后将 frame 结构中包含的信息打包成二进制表示形式,可以将其写入相应的控制器寄存器。此函数还会计算 HDMI 1.4 规范第 5.3.5 节要求的校验和。

返回打包到二进制缓冲区中的字节数,如果失败,则返回负错误代码。

int hdmi_spd_infoframe_init(struct hdmi_spd_infoframe *frame, const char *vendor, const char *product)

初始化一个 HDMI SPD 信息帧

参数

struct hdmi_spd_infoframe *frame

HDMI SPD 信息帧

const char *vendor

供应商字符串

const char *product

产品字符串

描述

成功时返回 0,失败时返回负错误代码。

int hdmi_spd_infoframe_check(struct hdmi_spd_infoframe *frame)

检查一个 HDMI SPD 信息帧

参数

struct hdmi_spd_infoframe *frame

HDMI SPD 信息帧

描述

验证信息帧是否一致,并根据其他字段更新派生字段(例如,长度)。

成功时返回 0,失败时返回负错误代码。

ssize_t hdmi_spd_infoframe_pack_only(const struct hdmi_spd_infoframe *frame, void *buffer, size_t size)

将 HDMI SPD 信息帧写入二进制缓冲区

参数

const struct hdmi_spd_infoframe *frame

HDMI SPD 信息帧

void *buffer

目标缓冲区

size_t size

缓冲区大小

描述

frame 结构中包含的信息打包为可以写入相应控制器寄存器的二进制表示形式。 还会根据 HDMI 1.4 规范的第 5.3.5 节的要求计算校验和。

返回打包到二进制缓冲区中的字节数,如果失败,则返回负错误代码。

ssize_t hdmi_spd_infoframe_pack(struct hdmi_spd_infoframe *frame, void *buffer, size_t size)

检查 HDMI SPD 信息帧,并将其写入二进制缓冲区

参数

struct hdmi_spd_infoframe *frame

HDMI SPD 信息帧

void *buffer

目标缓冲区

size_t size

缓冲区大小

描述

验证信息帧的一致性,并基于其他字段更新派生字段(例如长度),然后将 frame 结构中包含的信息打包成二进制表示形式,可以将其写入相应的控制器寄存器。此函数还会计算 HDMI 1.4 规范第 5.3.5 节要求的校验和。

返回打包到二进制缓冲区中的字节数,如果失败,则返回负错误代码。

int hdmi_audio_infoframe_init(struct hdmi_audio_infoframe *frame)

初始化 HDMI 音频信息帧

参数

struct hdmi_audio_infoframe *frame

HDMI 音频信息帧

描述

成功时返回 0,失败时返回负错误代码。

int hdmi_audio_infoframe_check(const struct hdmi_audio_infoframe *frame)

检查 HDMI 音频信息帧

参数

const struct hdmi_audio_infoframe *frame

HDMI 音频信息帧

描述

验证信息帧是否一致,并根据其他字段更新派生字段(例如,长度)。

成功时返回 0,失败时返回负错误代码。

ssize_t hdmi_audio_infoframe_pack_only(const struct hdmi_audio_infoframe *frame, void *buffer, size_t size)

将 HDMI 音频信息帧写入二进制缓冲区

参数

const struct hdmi_audio_infoframe *frame

HDMI 音频信息帧

void *buffer

目标缓冲区

size_t size

缓冲区大小

描述

frame 结构中包含的信息打包为可以写入相应控制器寄存器的二进制表示形式。 还会根据 HDMI 1.4 规范的第 5.3.5 节的要求计算校验和。

返回打包到二进制缓冲区中的字节数,如果失败,则返回负错误代码。

ssize_t hdmi_audio_infoframe_pack(struct hdmi_audio_infoframe *frame, void *buffer, size_t size)

检查 HDMI 音频信息帧,并将其写入二进制缓冲区

参数

struct hdmi_audio_infoframe *frame

HDMI 音频信息帧

void *buffer

目标缓冲区

size_t size

缓冲区大小

描述

验证信息帧的一致性,并基于其他字段更新派生字段(例如长度),然后将 frame 结构中包含的信息打包成二进制表示形式,可以将其写入相应的控制器寄存器。此函数还会计算 HDMI 1.4 规范第 5.3.5 节要求的校验和。

返回打包到二进制缓冲区中的字节数,如果失败,则返回负错误代码。

ssize_t hdmi_audio_infoframe_pack_for_dp(const struct hdmi_audio_infoframe *frame, struct dp_sdp *sdp, u8 dp_version)

为 DisplayPort 打包 HDMI 音频信息帧

参数

const struct hdmi_audio_infoframe *frame

HDMI 音频信息帧

struct dp_sdp *sdp

DisplayPort 的辅助数据包。

u8 dp_version

要在标头中编码的 DisplayPort 版本

描述

打包 HDMI 音频信息帧以通过 DisplayPort 发送。此函数填充要用于 DisplayPort 的辅助数据包。

返回

已写入的总字节数,或失败时的负 errno。

int hdmi_vendor_infoframe_init(struct hdmi_vendor_infoframe *frame)

初始化 HDMI 供应商信息帧

参数

struct hdmi_vendor_infoframe *frame

HDMI 供应商信息帧

描述

成功时返回 0,失败时返回负错误代码。

int hdmi_vendor_infoframe_check(struct hdmi_vendor_infoframe *frame)

检查 HDMI 供应商信息帧

参数

struct hdmi_vendor_infoframe *frame

HDMI 信息帧

描述

验证信息帧是否一致,并根据其他字段更新派生字段(例如,长度)。

成功时返回 0,失败时返回负错误代码。

ssize_t hdmi_vendor_infoframe_pack_only(const struct hdmi_vendor_infoframe *frame, void *buffer, size_t size)

将 HDMI 供应商信息帧写入二进制缓冲区

参数

const struct hdmi_vendor_infoframe *frame

HDMI 信息帧

void *buffer

目标缓冲区

size_t size

缓冲区大小

描述

frame 结构中包含的信息打包为可以写入相应控制器寄存器的二进制表示形式。 还会根据 HDMI 1.4 规范的第 5.3.5 节的要求计算校验和。

返回打包到二进制缓冲区中的字节数,如果失败,则返回负错误代码。

ssize_t hdmi_vendor_infoframe_pack(struct hdmi_vendor_infoframe *frame, void *buffer, size_t size)

检查 HDMI 供应商信息帧,并将其写入二进制缓冲区

参数

struct hdmi_vendor_infoframe *frame

HDMI 供应商信息帧

void *buffer

目标缓冲区

size_t size

缓冲区大小

描述

验证信息帧的一致性,并基于其他字段更新派生字段(例如长度),然后将 frame 结构中包含的信息打包成二进制表示形式,可以将其写入相应的控制器寄存器。此函数还会计算 HDMI 1.4 规范第 5.3.5 节要求的校验和。

返回打包到二进制缓冲区中的字节数,如果失败,则返回负错误代码。

int hdmi_drm_infoframe_init(struct hdmi_drm_infoframe *frame)

初始化 HDMI 动态范围和母带制作信息帧

参数

struct hdmi_drm_infoframe *frame

HDMI DRM 信息帧

描述

成功时返回 0,失败时返回负错误代码。

int hdmi_drm_infoframe_check(struct hdmi_drm_infoframe *frame)

检查 HDMI DRM 信息帧

参数

struct hdmi_drm_infoframe *frame

HDMI DRM 信息帧

描述

验证信息帧的一致性。成功时返回 0,失败时返回负错误代码。

ssize_t hdmi_drm_infoframe_pack_only(const struct hdmi_drm_infoframe *frame, void *buffer, size_t size)

将 HDMI DRM 信息帧写入二进制缓冲区

参数

const struct hdmi_drm_infoframe *frame

HDMI DRM 信息帧

void *buffer

目标缓冲区

size_t size

缓冲区大小

描述

frame 结构中包含的信息打包为可以写入相应控制器寄存器的二进制表示形式。 还会根据 HDMI 1.4 规范的第 5.3.5 节的要求计算校验和。

返回打包到二进制缓冲区中的字节数,如果失败,则返回负错误代码。

ssize_t hdmi_drm_infoframe_pack(struct hdmi_drm_infoframe *frame, void *buffer, size_t size)

检查 HDMI DRM 信息帧,并将其写入二进制缓冲区

参数

struct hdmi_drm_infoframe *frame

HDMI DRM 信息帧

void *buffer

目标缓冲区

size_t size

缓冲区大小

描述

验证信息帧的一致性,并基于其他字段更新派生字段(例如长度),然后将 frame 结构中包含的信息打包成二进制表示形式,可以将其写入相应的控制器寄存器。此函数还会计算 HDMI 1.4 规范第 5.3.5 节要求的校验和。

返回打包到二进制缓冲区中的字节数,如果失败,则返回负错误代码。

ssize_t hdmi_infoframe_pack_only(const union hdmi_infoframe *frame, void *buffer, size_t size)

将 HDMI 信息帧写入二进制缓冲区

参数

const union hdmi_infoframe *frame

HDMI 信息帧

void *buffer

目标缓冲区

size_t size

缓冲区大小

描述

frame 结构中包含的信息打包为可以写入相应控制器寄存器的二进制表示形式。 还会根据 HDMI 1.4 规范的第 5.3.5 节的要求计算校验和。

返回打包到二进制缓冲区中的字节数,如果失败,则返回负错误代码。

ssize_t hdmi_infoframe_pack(union hdmi_infoframe *frame, void *buffer, size_t size)

检查 HDMI 信息帧,并将其写入二进制缓冲区

参数

union hdmi_infoframe *frame

HDMI 信息帧

void *buffer

目标缓冲区

size_t size

缓冲区大小

描述

验证信息帧的一致性,并基于其他字段更新派生字段(例如长度),然后将 frame 结构中包含的信息打包成二进制表示形式,可以将其写入相应的控制器寄存器。此函数还会计算 HDMI 1.4 规范第 5.3.5 节要求的校验和。

返回打包到二进制缓冲区中的字节数,如果失败,则返回负错误代码。

void hdmi_infoframe_log(const char *level, struct device *dev, const union hdmi_infoframe *frame)

记录 HDMI 信息帧的信息

参数

const char *level

日志记录级别

struct device *dev

设备

const union hdmi_infoframe *frame

HDMI 信息帧

int hdmi_drm_infoframe_unpack_only(struct hdmi_drm_infoframe *frame, const void *buffer, size_t size)

将 CTA-861-G DRM 信息帧 DataBytes 的二进制缓冲区解包为 HDMI DRM 信息帧

参数

struct hdmi_drm_infoframe *frame

HDMI DRM 信息帧

const void *buffer

源缓冲区

size_t size

缓冲区大小

描述

将二进制 buffer 中包含的 CTA-861-G DRM 信息帧 DataBytes 解包为 HDMI 动态范围和母带制作 (DRM) 信息帧的结构化 frame

成功时返回 0,失败时返回负错误代码。

int hdmi_infoframe_unpack(union hdmi_infoframe *frame, const void *buffer, size_t size)

将二进制缓冲区解包为 HDMI 信息帧

参数

union hdmi_infoframe *frame

HDMI 信息帧

const void *buffer

源缓冲区

size_t size

缓冲区大小

描述

将二进制缓冲区 buffer 中包含的信息解包为 HDMI 信息帧的结构化 frame。还会验证 HDMI 1.4 规范第 5.3.5 节要求的校验和。

成功时返回 0,失败时返回负错误代码。

矩形实用程序参考

实用程序函数,用于帮助管理矩形区域以进行剪裁、缩放等计算。

struct drm_rect

二维矩形

定义:

struct drm_rect {
    int x1, y1, x2, y2;
};

成员

x1

水平起始坐标(含)

y1

垂直起始坐标(含)

x2

水平结束坐标(不含)

y2

垂直结束坐标(不含)

描述

请注意,这必须与 struct drm_mode_rect 的布局匹配,否则损坏辅助程序(如 drm_atomic_helper_damage_iter_init())会中断。

DRM_RECT_INIT

DRM_RECT_INIT (x, y, w, h)

从 x/y/w/h 初始化矩形

参数

x

x 坐标

y

y 坐标

w

宽度

h

高度

返回

指定大小的新矩形。

DRM_RECT_FMT

DRM_RECT_FMT

用于 struct drm_rect 的 printf 字符串

DRM_RECT_ARG

DRM_RECT_ARG (r)

用于 struct drm_rect 的 printf 参数

参数

r

矩形结构

DRM_RECT_FP_FMT

DRM_RECT_FP_FMT

用于 16.16 定点形式的 struct drm_rect 的 printf 字符串

DRM_RECT_FP_ARG

DRM_RECT_FP_ARG (r)

用于 16.16 定点形式的 struct drm_rect 的 printf 参数

参数

r

矩形结构

描述

这对于打印平面源矩形(采用 16.16 定点形式)等很有用。

void drm_rect_init(struct drm_rect *r, int x, int y, int width, int height)

从 x/y/w/h 初始化矩形

参数

struct drm_rect *r

矩形

int x

x 坐标

int y

y 坐标

int width

宽度

int height

高度

void drm_rect_adjust_size(struct drm_rect *r, int dw, int dh)

调整矩形的大小

参数

struct drm_rect *r

要调整的矩形

int dw

水平调整

int dh

垂直调整

描述

将矩形 r 的大小在水平方向上调整 dw,在垂直方向上调整 dh,同时保持 r 的中心不动。

dwdh 增加大小,负值减小大小。

void drm_rect_translate(struct drm_rect *r, int dx, int dy)

平移矩形

参数

struct drm_rect *r

要平移的矩形

int dx

水平平移

int dy

垂直平移

描述

将矩形 r 在水平方向上移动 dx,在垂直方向上移动 dy

void drm_rect_translate_to(struct drm_rect *r, int x, int y)

将矩形平移到绝对位置

参数

struct drm_rect *r

要平移的矩形

int x

水平位置

int y

垂直位置

描述

将矩形 r 在水平方向上移动到 x,在垂直方向上移动到 y

void drm_rect_downscale(struct drm_rect *r, int horz, int vert)

缩小矩形

参数

struct drm_rect *r

要缩小的矩形

int horz

水平缩小因子

int vert

垂直缩小因子

描述

将矩形 r 的坐标除以 horzvert

int drm_rect_width(const struct drm_rect *r)

确定矩形的宽度

参数

const struct drm_rect *r

返回其宽度的矩形

返回

矩形的宽度。

int drm_rect_height(const struct drm_rect *r)

确定矩形的高度

参数

const struct drm_rect *r

返回其高度的矩形

返回

矩形的高度。

bool drm_rect_visible(const struct drm_rect *r)

确定矩形是否可见

参数

const struct drm_rect *r

返回其可见性的矩形

返回

如果矩形可见,则为 true,否则为 false

bool drm_rect_equals(const struct drm_rect *r1, const struct drm_rect *r2)

确定两个矩形是否相等

参数

const struct drm_rect *r1

第一个矩形

const struct drm_rect *r2

第二个矩形

返回

如果矩形相等,则为 true,否则为 false

void drm_rect_fp_to_int(struct drm_rect *dst, const struct drm_rect *src)

将 16.16 定点形式的矩形转换为 int 形式。

参数

struct drm_rect *dst

用于存储转换后的值的矩形

const struct drm_rect *src

16.16 定点形式的矩形

bool drm_rect_overlap(const struct drm_rect *a, const struct drm_rect *b)

检查两个矩形是否重叠

参数

const struct drm_rect *a

第一个矩形

const struct drm_rect *b

第二个矩形

返回

如果矩形重叠,则返回 true,否则返回 false

bool drm_rect_intersect(struct drm_rect *r1, const struct drm_rect *r2)

计算两个矩形的交集

参数

struct drm_rect *r1

第一个矩形

const struct drm_rect *r2

第二个矩形

描述

计算矩形 r1r2 的交集。 r1 将被交集覆盖。

返回

如果矩形 r1 在操作后仍然可见,则返回 true,否则返回 false

bool drm_rect_clip_scaled(struct drm_rect *src, struct drm_rect *dst, const struct drm_rect *clip)

执行缩放剪裁操作

参数

struct drm_rect *src

源窗口矩形

struct drm_rect *dst

目标窗口矩形

const struct drm_rect *clip

剪裁矩形

描述

通过矩形 clip 剪裁矩形 dst。通过相应的量剪裁矩形 src,保留从 srcdst 的垂直和水平缩放因子。

返回

如果矩形 dst 在被剪裁后仍然可见,则返回 true,否则返回 false

int drm_rect_calc_hscale(const struct drm_rect *src, const struct drm_rect *dst, int min_hscale, int max_hscale)

计算水平缩放因子

参数

const struct drm_rect *src

源窗口矩形

const struct drm_rect *dst

目标窗口矩形

int min_hscale

允许的最小水平缩放因子

int max_hscale

允许的最大水平缩放因子

描述

计算水平缩放因子,计算公式为 (src 宽度) / (dst 宽度)。

如果比例低于 1 << 16,则向下舍入。如果比例高于 1 << 16,则向上舍入。这将使用最悲观的限制计算来计算比例。

返回

水平缩放因子,或者超出限制的 errno。

int drm_rect_calc_vscale(const struct drm_rect *src, const struct drm_rect *dst, int min_vscale, int max_vscale)

计算垂直缩放因子

参数

const struct drm_rect *src

源窗口矩形

const struct drm_rect *dst

目标窗口矩形

int min_vscale

允许的最小垂直缩放因子

int max_vscale

允许的最大垂直缩放因子

描述

计算垂直缩放因子,计算公式为 (src 高度) / (dst 高度)。

如果比例低于 1 << 16,则向下舍入。如果比例高于 1 << 16,则向上舍入。这将使用最悲观的限制计算来计算比例。

返回

垂直缩放因子,或者超出限制的 errno。

void drm_rect_debug_print(const char *prefix, const struct drm_rect *r, bool fixed_point)

打印矩形信息

参数

const char *prefix

前缀字符串

const struct drm_rect *r

要打印的矩形

bool fixed_point

矩形采用 16.16 定点格式

void drm_rect_rotate(struct drm_rect *r, int width, int height, unsigned int rotation)

旋转矩形

参数

struct drm_rect *r

要旋转的矩形

int width

坐标空间的宽度

int height

坐标空间的高度

unsigned int rotation

要应用的变换

描述

rotation 应用于矩形 r 的坐标。

widthheightrotation 结合使用来定义新原点的位置。

width 对应于未变换坐标空间的水平轴,height 对应于垂直轴。

void drm_rect_rotate_inv(struct drm_rect *r, int width, int height, unsigned int rotation)

反向旋转矩形

参数

struct drm_rect *r

要旋转的矩形

int width

坐标空间的宽度

int height

坐标空间的高度

unsigned int rotation

要应用其逆变换的变换

描述

rotation 的逆变换应用于矩形 r 的坐标。

widthheightrotation 结合使用来定义新原点的位置。

width 对应于原始未变换坐标空间的水平轴,height 对应于垂直轴,因此在进行旋转及其逆变换时,您永远不必翻转它们。也就是说,如果您执行

drm_rect_rotate(&r, width, height, rotation);
drm_rect_rotate_inv(&r, width, height, rotation);

您将始终获得原始矩形。

Flip-work 助手参考

实用程序,用于在 flip/vblank 后从工作队列上下文中排队运行工作。通常,这可以用于延迟 framebuffer、cursor bo 等的 unref,直到 vblank 之后。API 都是线程安全的。此外,可以 atomic 上下文中调用 drm_flip_work_commit()

struct drm_flip_work

flip 工作队列

定义:

struct drm_flip_work {
    const char *name;
    drm_flip_func_t func;
    struct work_struct worker;
    struct list_head queued;
    struct list_head commited;
    spinlock_t lock;
};

成员

name

调试名称

func

为每个提交的项目调用的回调 fxn

worker

调用 func 的 worker

queued

已排队的任务

commited

已提交的任务

lock

用于访问 queued 和 commited 列表的锁

void drm_flip_work_queue(struct drm_flip_work *work, void *val)

排队工作

参数

struct drm_flip_work *work

flip-work

void *val

要排队的值

描述

排队工作,稍后将在调用 drm_flip_work_commit() 后在工作队列上运行(传递回 drm_flip_func_t func)。

void drm_flip_work_commit(struct drm_flip_work *work, struct workqueue_struct *wq)

提交排队的工作

参数

struct drm_flip_work *work

flip-work

struct workqueue_struct *wq

要在其上运行排队工作的工作队列

描述

触发先前由 drm_flip_work_queue() 排队的工作,使其在工作队列上运行。典型的用法是在任何时候(从 vblank irq 和/或之前)排队工作(通过 drm_flip_work_queue()),然后从 vblank irq 提交排队的工作。

void drm_flip_work_init(struct drm_flip_work *work, const char *name, drm_flip_func_t func)

初始化 flip-work

参数

struct drm_flip_work *work

要初始化的 flip-work

const char *name

调试名称

drm_flip_func_t func

回调工作函数

描述

初始化/分配 flip-work 的资源

void drm_flip_work_cleanup(struct drm_flip_work *work)

清理 flip-work

参数

struct drm_flip_work *work

要清理的 flip-work

描述

销毁为 flip-work 分配的资源

辅助模式设置助手

此助手库包含各种一次性函数,这些函数实际上不适合 DRM 模式设置助手库中的任何其他位置。

void drm_helper_move_panel_connectors_to_head(struct drm_device *dev)

将面板移动到连接器列表的前面

参数

struct drm_device *dev

要操作的 drm 设备

描述

一些用户空间假定第一个连接的连接器是主显示器,它应该在其中显示例如登录屏幕。对于笔记本电脑,这应该是主面板。使用此函数将所有 (eDP/LVDS/DSI) 面板排序到连接器列表的前面,而不是费力地尝试以正确的顺序初始化它们。

void drm_helper_mode_fill_fb_struct(struct drm_device *dev, struct drm_framebuffer *fb, const struct drm_mode_fb_cmd2 *mode_cmd)

填充 framebuffer 元数据

参数

struct drm_device *dev

DRM 设备

struct drm_framebuffer *fb

要填充的 drm_framebuffer 对象

const struct drm_mode_fb_cmd2 *mode_cmd

来自用户空间 fb 创建请求的元数据

描述

此助手可用于驱动程序的 fb_create 回调中,以预填充 fb 的元数据字段。

int drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, const struct drm_crtc_funcs *funcs)

旧式 CRTC 初始化函数

参数

struct drm_device *dev

DRM 设备

struct drm_crtc *crtc

要初始化的 CRTC 对象

const struct drm_crtc_funcs *funcs

新 CRTC 的回调

描述

使用默认的助手提供的 primary plane 且没有 cursor plane 来初始化 CRTC 对象。

请注意,我们对硬件限制做了一些假设,这些假设可能不适用于所有硬件

  1. 无法重新定位 Primary plane。

  2. 无法缩放 Primary plane。

  3. Primary plane 必须覆盖整个 CRTC。

  4. 不支持亚像素定位。

  5. 如果 CRTC 已启用,Primary plane 必须始终处于启用状态。

这纯粹是旧驱动程序的向后兼容性助手。驱动程序应改为实现自己的 primary plane。原子驱动程序必须这样做。具有上述硬件限制的驱动程序可以考虑使用 struct drm_simple_display_pipe,它将上述限制封装到一个不错的接口中。

返回

成功时返回 0,失败时返回错误代码。

int drm_mode_config_helper_suspend(struct drm_device *dev)

模式设置挂起助手

参数

struct drm_device *dev

DRM 设备

描述

此辅助函数负责挂起模式设置端。它禁用输出轮询(如果已初始化),挂起 fbdev(如果已使用),最后调用 drm_atomic_helper_suspend()。如果挂起失败,则重新启用 fbdev 和轮询。

另请参阅:drm_kms_helper_poll_disable() 和 drm_client_dev_suspend()。

返回

成功时返回零,出错时返回负错误代码。

int drm_mode_config_helper_resume(struct drm_device *dev)

模式设置恢复助手

参数

struct drm_device *dev

DRM 设备

描述

此辅助函数负责恢复模式设置端。它调用 drm_atomic_helper_resume(),恢复 fbdev(如果已使用),并启用输出轮询(如果已初始化)。

另请参阅:drm_client_dev_resume() 和 drm_kms_helper_poll_enable()

返回

成功时返回零,出错时返回负错误代码。

OF/DT 助手

一组辅助函数,用于帮助 DRM 驱动程序解析标准 DT 属性。

uint32_t drm_of_crtc_port_mask(struct drm_device *dev, struct device_node *port)

按端口 OF 节点查找已注册 CRTC 的掩码

参数

struct drm_device *dev

DRM 设备

struct device_node *port

端口 OF 节点

描述

给定一个端口 OF 节点,返回设备 CRTC 列表中相应 CRTC 的可能掩码。如果未找到,则返回零。

uint32_t drm_of_find_possible_crtcs(struct drm_device *dev, struct device_node *port)

查找编码器端口的可能 CRTC

参数

struct drm_device *dev

DRM 设备

struct device_node *port

要扫描端点的编码器端口

描述

扫描连接到端口的所有端点,找到其连接的 CRTC,并生成可以连接到此编码器的 CRTC 的 DRM 掩码。

有关绑定的信息,请参阅 Documentation/devicetree/bindings/graph.txt。

void drm_of_component_match_add(struct device *master, struct component_match **matchptr, int (*compare)(struct device*, void*), struct device_node *node)

添加组件助手 OF 节点匹配规则

参数

struct device *master

主设备

struct component_match **matchptr

组件匹配指针

int (*compare)(struct device *, void *)

用于匹配组件的比较函数

struct device_node *node

of_node

int drm_of_component_probe(struct device *dev, int (*compare_of)(struct device*, void*), const struct component_master_ops *m_ops)

基于组件的主设备的通用探测函数

参数

struct device *dev

包含 OF 节点的主设备

int (*compare_of)(struct device *, void *)

用于匹配组件的比较函数

const struct component_master_ops *m_ops

要使用的组件主操作

描述

解析平台设备 OF 节点并绑定与主设备关联的所有组件。接口端口在编码器之前添加,以满足其 .bind 要求。有关绑定的信息,请参阅 Documentation/devicetree/bindings/graph.txt。

如果成功,则返回零,如果失败,则返回标准错误代码之一。

int drm_of_find_panel_or_bridge(const struct device_node *np, int port, int endpoint, struct drm_panel **panel, struct drm_bridge **bridge)

返回连接的面板或桥设备

参数

const struct device_node *np

包含编码器输出端口的设备树节点

int port

设备树节点中的端口

int endpoint

设备树节点中的端点

struct drm_panel **panel

用于保存返回的 drm_panel 的指针

struct drm_bridge **bridge

用于保存返回的 drm_bridge 的指针

描述

给定一个 DT 节点的端口和端点编号,查找连接的节点并返回关联的 struct drm_panel 或 drm_bridge 设备。 panelbridge 必须有一个不为 NULL。

此函数已弃用,不应在新驱动程序中使用。请改用 devm_drm_of_get_bridge()

如果成功,则返回零,如果失败,则返回标准错误代码之一。

获取 LVDS 双链路源像素顺序

参数

const struct device_node *port1

双链路 LVDS 源的第一个 DT 端口节点

const struct device_node *port2

双链路 LVDS 源的第二个 DT 端口节点

描述

LVDS 双链路连接由两个链路组成,偶数像素在一个链路上传输,奇数像素在另一个链路上传输。此函数针对 LVDS 双链路源的两个端口,根据连接的接收器的要求,返回哪个端口应传输偶数和奇数像素。

像素顺序由接收器 DT 端口节点中的 dual-lvds-even-pixels 和 dual-lvds-odd-pixels 属性确定。如果这些属性不存在,或者它们的使用无效,则此函数返回 -EINVAL。

如果任一端口未连接,则此函数返回 -EPIPE。

port1port2 通常是 DT 兄弟节点,但当例如两个独立的 LVDS 编码器承载偶数和奇数像素时,可能具有不同的父节点。

返回

  • DRM_LVDS_DUAL_LINK_EVEN_ODD_PIXELS - port1 承载偶数像素,port2 承载奇数像素

  • DRM_LVDS_DUAL_LINK_ODD_EVEN_PIXELS - port1 承载奇数像素,port2 承载偶数像素

  • -EINVAL - port1port2 未连接到双链路 LVDS 接收器,或者接收器配置无效

  • -EPIPE - 当 port1port2 未连接时

获取 LVDS 双链路接收器像素顺序

参数

struct device_node *port1

双链路 LVDS 接收器的第一个 DT 端口节点

struct device_node *port2

双链路 LVDS 接收器的第二个 DT 端口节点

描述

LVDS 双链路连接由两个链路组成,偶数像素在一个链路上传输,奇数像素在另一个链路上传输。此函数针对 LVDS 双链路接收器的两个端口,根据接收器的要求,返回哪个端口应传输偶数和奇数像素。

像素顺序由接收器 DT 端口节点中的 dual-lvds-even-pixels 和 dual-lvds-odd-pixels 属性确定。如果这些属性不存在,或者它们的使用无效,则此函数返回 -EINVAL。

如果任一端口未连接,则此函数返回 -EPIPE。

port1port2 通常是 DT 兄弟节点,但当例如两个独立的 LVDS 解码器接收偶数和奇数像素时,可能具有不同的父节点。

返回

  • DRM_LVDS_DUAL_LINK_EVEN_ODD_PIXELS - port1 接收偶数像素,port2 接收奇数像素

  • DRM_LVDS_DUAL_LINK_ODD_EVEN_PIXELS - port1 接收奇数像素,port2 接收偶数像素

  • -EINVAL - port1port2 为 NULL

  • -EPIPE - 当 port1port2 未连接时

int drm_of_lvds_get_data_mapping(const struct device_node *port)

获取 LVDS 数据映射

参数

const struct device_node *port

LVDS 源或接收器的 DT 端口节点

描述

将 DT “data-mapping” 属性字符串值转换为媒体总线格式值。

返回

  • MEDIA_BUS_FMT_RGB666_1X7X3_SPWG - data-mapping 为 “jeida-18”

  • MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA - data-mapping 为 “jeida-24”

  • MEDIA_BUS_FMT_RGB101010_1X7X5_JEIDA - data-mapping 为 “jeida-30”

  • MEDIA_BUS_FMT_RGB888_1X7X4_SPWG - data-mapping 为 “vesa-24”

  • MEDIA_BUS_FMT_RGB101010_1X7X5_SPWG - data-mapping 为 “vesa-30”

  • -EINVAL - 不支持 “data-mapping” 属性

  • -ENODEV - 缺少 “data-mapping” 属性

int drm_of_get_data_lanes_count(const struct device_node *endpoint, const unsigned int min, const unsigned int max)

获取 DSI/(e)DP 数据通道计数

参数

const struct device_node *endpoint

DSI/(e)DP 源或接收器的 DT 端点节点

const unsigned int min

支持的最小数据通道数

const unsigned int max

支持的最大数据通道数

描述

计算 DT “data-lanes” 属性元素并检查其有效性。

返回

  • min..max - “data-lanes” 元素的正整数计数

  • -ve - 缺少或无效 “data-lanes” 属性

  • -EINVAL - 不支持 “data-lanes” 属性

int drm_of_get_data_lanes_count_ep(const struct device_node *port, int port_reg, int reg, const unsigned int min, const unsigned int max)

按端点获取 DSI/(e)DP 数据通道计数

参数

const struct device_node *port

DSI/(e)DP 源或接收器的 DT 端口节点

int port_reg

父端口节点的标识符(reg 属性的值)

int reg

端点节点的标识符(reg 属性的值)

const unsigned int min

支持的最小数据通道数

const unsigned int max

支持的最大数据通道数

描述

计算 DT “data-lanes” 属性元素并检查其有效性。此变体使用端点说明符。

返回

  • min..max - “data-lanes” 元素的正整数计数

  • -EINVAL - 不支持 “data-mapping” 属性

  • -ENODEV - 缺少 “data-mapping” 属性

struct mipi_dsi_host *drm_of_get_dsi_bus(struct device *dev)

查找给定设备的 DSI 总线

参数

struct device *dev

显示设备的父设备 (SPI, I2C)

描述

使用设备树获取通过 MIPI-DCS 以外的总线(SPI、I2C 等)控制的 DSI 设备的父 DSI 总线。

此函数假定设备的 port**0** 是 DSI 输入。

如果成功,则返回指向 mipi_dsi_host 的指针;如果请求不受支持,则返回 -EINVAL;如果找到 DSI 主机但不可用,则返回 -EPROBE_DEFER;否则返回 -ENODEV。

旧式平面助手参考

此助手库包含用于在普通 CRTC 配置接口之上实现主平面支持的助手。由于旧式 drm_mode_config_funcs.set_config 接口将主平面与 CRTC 状态绑定在一起,因此不允许用户空间本身禁用主平面。默认主平面仅将 XRBG8888 和 ARGB8888 公开为附加帧缓冲区的有效像素格式。

强烈建议驱动程序实现对主平面的正确支持,并且新合并的驱动程序不得依赖这些过渡助手。

平面助手与其他助手共享函数表结构,特别是原子助手。有关详细信息,请参阅 struct drm_plane_helper_funcs

int drm_plane_helper_update_primary(struct drm_plane *plane, struct drm_crtc *crtc, struct drm_framebuffer *fb, int crtc_x, int crtc_y, unsigned int crtc_w, unsigned int crtc_h, uint32_t src_x, uint32_t src_y, uint32_t src_w, uint32_t src_h, struct drm_modeset_acquire_ctx *ctx)

用于更新主平面的助手

参数

struct drm_plane *plane

要更新的平面

struct drm_crtc *crtc

平面的新 CRTC

struct drm_framebuffer *fb

平面的新帧缓冲区

int crtc_x

CRTC 中的 x 坐标

int crtc_y

CRTC 中的 y 坐标

unsigned int crtc_w

CRTC 中的宽度坐标

unsigned int crtc_h

CRTC 中的高度坐标

uint32_t src_x

源中的 x 坐标

uint32_t src_y

源中的 y 坐标

uint32_t src_w

源中的宽度坐标

uint32_t src_h

源中的高度坐标

struct drm_modeset_acquire_ctx *ctx

模式设置锁定上下文

描述

此助手验证给定的参数并更新主平面。

此函数仅对非原子模式设置有用。请勿在新驱动程序中使用它。

返回

成功时为零,否则为 errno 代码。

int drm_plane_helper_disable_primary(struct drm_plane *plane, struct drm_modeset_acquire_ctx *ctx)

用于禁用主平面的助手

参数

struct drm_plane *plane

要禁用的平面

struct drm_modeset_acquire_ctx *ctx

模式设置锁定上下文

描述

尝试禁用主平面时,此助手返回错误。

此函数仅对非原子模式设置有用。请勿在新驱动程序中使用它。

返回

errno 代码。

void drm_plane_helper_destroy(struct drm_plane *plane)

用于主平面销毁的助手

参数

struct drm_plane *plane

要销毁的平面

描述

为主平面提供默认的平面销毁处理程序。此处理程序在 CRTC 销毁期间调用。我们禁用主平面,从 DRM 平面列表中删除它,并释放平面结构。

旧式 CRTC/模式设置助手函数参考

CRTC 模式设置助手库在 drm_crtc_helper_set_config() 中提供默认的 set_config 实现。以及一些其他便捷函数,使用相同的回调,驱动程序可以使用这些回调来恢复模式设置配置,例如,使用 drm_helper_resume_force_mode() 恢复。

请注意,此助手库不跟踪 CRTC 和编码器的当前电源状态。它可以调用 drm_encoder_helper_funcs.dpms 等回调,即使硬件已处于所需状态。此缺陷已在原子助手中修复。

驱动程序回调主要与原子模式设置助手兼容,但主平面的处理除外:原子助手要求主平面实现为真正的独立平面,而不是直接绑定到 CRTC 状态。为了更轻松地过渡,此库提供了使用新的平面和原子助手回调来实现 CRTC 助手所需的旧语义的函数。

强烈建议驱动程序转换为原子助手(通过首先转换为平面助手)。新驱动程序不得使用这些函数,而是需要实现原子接口,并可能为此使用原子助手。

这些旧式模式设置助手使用与其他所有模式设置助手相同的函数表结构。请参阅 struct drm_crtc_helper_funcsstruct drm_encoder_helper_funcs 和 struct drm_connector_helper_funcs 的文档。

bool drm_helper_encoder_in_use(struct drm_encoder *encoder)

检查给定的编码器是否正在使用

参数

struct drm_encoder *encoder

要检查的编码器

描述

检查 encoder 是否与任何连接器的当前模式设置输出配置一起使用。这并不意味着它实际上已启用,因为 DPMS 状态是单独跟踪的。

返回

如果使用 encoder,则为 True;否则为 false。

bool drm_helper_crtc_in_use(struct drm_crtc *crtc)

检查给定的 CRTC 是否在 mode_config 中

参数

struct drm_crtc *crtc

要检查的 CRTC

描述

检查 crtc 是否与任何连接器的当前模式设置输出配置一起使用。这并不意味着它实际上已启用,因为 DPMS 状态是单独跟踪的。

返回

如果使用 crtc,则为 True;否则为 false。

void drm_helper_disable_unused_functions(struct drm_device *dev)

禁用未使用的对象

参数

struct drm_device *dev

DRM 设备

描述

此函数遍历 dev 的整个模式设置配置。它将删除未使用的编码器的任何 CRTC 链接,并删除已断开连接的连接器的编码器链接。然后,它将禁用所有未使用的编码器和 CRTC,方法是调用其禁用回调(如果可用),或者使用 DRM_MODE_DPMS_OFF 调用其 dpms 回调。

此函数是旧式模式设置助手库的一部分,会导致与原子驱动程序发生重大混淆。这是因为原子助手保证永远不会在禁用的函数上调用 ->disable() 挂钩,或者在启用的函数上调用 ->enable() 挂钩。另一方面,drm_helper_disable_unused_functions() 会将此类保证抛之脑后,并无条件地在未使用的函数上调用禁用挂钩。

注意

bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, struct drm_display_mode *mode, int x, int y, struct drm_framebuffer *old_fb)

用于设置模式的内部助手

参数

struct drm_crtc *crtc

要编程的 CRTC

struct drm_display_mode *mode

要使用的模式

int x

进入表面的水平偏移

int y

进入表面的垂直偏移

struct drm_framebuffer *old_fb

旧的帧缓冲区,用于清理

描述

尝试在 crtc 上设置 mode。在尝试设置模式之前,让 crtc 及其关联的连接器有机会修复或拒绝该模式。这是一个内部助手,驱动程序可以使用它来更新需要禁用整个输出管道并在新配置中重新启用的属性。例如,用于更改是否在 hdmi 链路上启用音频,或者用于更改面板适配器或抖动属性。它也由 drm_crtc_helper_set_config() 助手函数调用,以驱动模式设置序列。

返回

如果模式设置成功,则为 True;否则为 false。

int drm_crtc_helper_atomic_check(struct drm_crtc *crtc, struct drm_atomic_state *state)

用于检查 CRTC 原子状态的助手

参数

struct drm_crtc *crtc

要检查的 CRTC

struct drm_atomic_state *state

原子状态对象

描述

为主 CRTC 提供默认的 CRTC 状态检查处理程序,该 CRTC 仅附加一个主平面。这通常是简单帧缓冲区的 CRTC 的情况。

返回

成功时为零,否则为 errno 代码。

int drm_crtc_helper_set_config(struct drm_mode_set *set, struct drm_modeset_acquire_ctx *ctx)

从用户空间设置新配置

参数

struct drm_mode_set *set

模式设置配置

struct drm_modeset_acquire_ctx *ctx

锁定获取上下文,此处未使用

描述

drm_crtc_helper_set_config() 助手函数为使用旧式 CRTC 助手的驱动程序实现 drm_crtc_funcs.set_config 回调。

它首先尝试通过调用连接器 drm_connector_helper_funcs.best_encoder 助手操作来为每个连接器找到最佳编码器。

找到适当的编码器后,助手函数将调用 mode_fixup 编码器和 CRTC 助手操作来调整请求的模式,或完全拒绝该模式,在这种情况下,将向应用程序返回错误。如果在模式调整后新配置与当前配置相同,则助手函数将返回,而不执行任何其他操作。

如果调整后的模式与当前模式相同,但需要应用对帧缓冲区的更改,则 drm_crtc_helper_set_config() 函数将调用 CRTC drm_crtc_helper_funcs.mode_set_base 助手操作。

如果调整后的模式与当前模式不同,或者如果未提供 ->mode_set_base() 助手操作,则助手函数将按顺序调用 ->prepare()、->mode_set() 和 ->commit() CRTC 和编码器助手操作来执行完整的模式设置序列。或者,它也可以使用 dpms 和 disable 助手操作。有关详细信息,请参见 struct drm_crtc_helper_funcs 和 struct drm_encoder_helper_funcs

此函数已弃用。新驱动程序必须实现原子模式设置支持,此函数不适用于该支持。相反,驱动程序应使用 drm_atomic_helper_set_config()

返回

成功时返回 0,失败时返回负 errno 编号。

int drm_helper_connector_dpms(struct drm_connector *connector, int mode)

连接器 dpms 助手实现

参数

struct drm_connector *connector

受影响的连接器

int mode

DPMS 模式

描述

drm_helper_connector_dpms() 助手函数为使用旧式 CRTC 助手的驱动程序实现 drm_connector_funcs.dpms 回调。

这是 CRTC 助手框架提供的主要助手函数,用于实现 DPMS 连接器属性。它计算输出网格中所有编码器和 CRTC 的新期望 DPMS 状态,并调用驱动程序提供的 drm_crtc_helper_funcs.dpmsdrm_encoder_helper_funcs.dpms 回调。

此函数已弃用。新驱动程序必须实现原子模式设置支持,其中 DPMS 在 DRM 核心中处理。

返回

始终返回 0。

void drm_helper_resume_force_mode(struct drm_device *dev)

强制恢复模式设置配置

参数

struct drm_device *dev

应恢复的 drm_device

描述

使用模式设置助手的驱动程序可以使用此函数来强制恢复模式设置配置,例如,在恢复时或当其他内容可能践踏了硬件状态时(例如,某些过度热心的旧 BIOS 倾向于这样做)。

此助手不提供错误返回值,因为恢复旧配置永远不会因资源分配问题而失败,因为驱动程序已经成功设置了恢复的配置。因此,这应归结为几个 dpms on 调用的等效项,这些调用也不提供错误代码。

简单地再次恢复旧配置可能会失败(例如,由于以与用户空间设置的顺序不同的顺序恢复配置时分配共享资源略有不同)的驱动程序需要使用他们自己的恢复逻辑。

此函数已弃用。新驱动程序应实现原子模式设置,并使用原子挂起/恢复助手。

另请参阅:drm_atomic_helper_suspend()drm_atomic_helper_resume()

int drm_helper_force_disable_all(struct drm_device *dev)

强制关闭所有启用的 CRTC

参数

struct drm_device *dev

要关闭 CRTC 的 DRM 设备

描述

驱动程序可能希望在卸载时调用此函数,以确保所有显示器都熄灭,并且 GPU 处于一致的低功耗状态。需要 modeset 锁。

注意

这应该只被非原子传统驱动程序使用。对于原子版本,请查看 drm_atomic_helper_shutdown()

返回

成功时返回 0,失败时返回错误代码。

隐私屏幕类

此类允许来自例如 drivers/platform/x86 的非 KMS 驱动程序注册隐私屏幕设备,KMS 驱动程序可以使用该设备来实现标准隐私屏幕属性,请参阅 标准连接器属性

建议使用隐私屏幕类设备的 KMS 驱动程序使用 drm_connector_attach_privacy_screen_provider()drm_connector_update_privacy_screen() 辅助函数来处理此问题。

struct drm_privacy_screen_ops

drm_privacy_screen 操作

定义:

struct drm_privacy_screen_ops {
    int (*set_sw_state)(struct drm_privacy_screen *priv, enum drm_privacy_screen_status sw_state);
    void (*get_hw_state)(struct drm_privacy_screen *priv);
};

成员

set_sw_state

调用以请求更改隐私屏幕状态。 隐私屏幕类代码包含一个检查,以避免在 hw_state 报告状态已锁定时调用此方法。 驱动程序有责任更新 sw_state 和 hw_state。 这始终在持有 drm_privacy_screen 的锁的情况下被调用。

get_hw_state

调用以请求驱动程序从硬件获取当前的隐私屏幕状态,然后相应地更新 sw_state 和 hw_state。 这将在 sysfs 中注册隐私屏幕之前由核心调用。

描述

定义隐私屏幕类代码可以调用的操作。 这些函数应由隐私屏幕驱动程序实现。

struct drm_privacy_screen

中央隐私屏幕结构

定义:

struct drm_privacy_screen {
    struct device dev;
    struct mutex lock;
    struct list_head list;
    struct blocking_notifier_head notifier_head;
    const struct drm_privacy_screen_ops *ops;
    enum drm_privacy_screen_status sw_state;
    enum drm_privacy_screen_status hw_state;
    void *drvdata;
};

成员

dev

用于在 sysfs 中注册隐私屏幕的设备。

lock

mutex 保护此结构中的所有字段。

list

隐私屏幕设备列表列表项。

notifier_head

隐私屏幕通知链头。

ops

此隐私屏幕的 struct drm_privacy_screen_ops。 如果驱动程序已注销隐私屏幕,则此值为 NULL。

sw_state

隐私屏幕的软件状态,有关更多信息,请参阅 标准连接器属性

hw_state

隐私屏幕的硬件状态,有关更多信息,请参阅 标准连接器属性

drvdata

隐私屏幕提供程序拥有的私有数据

描述

中央隐私屏幕结构,其中包含用于在 sysfs 中注册屏幕的 struct device、屏幕的状态、操作等。

struct drm_privacy_screen_lookup

静态隐私屏幕查找列表项

定义:

struct drm_privacy_screen_lookup {
    struct list_head list;
    const char *dev_id;
    const char *con_id;
    const char *provider;
};

成员

list

查找列表列表项。

dev_id

使用者设备名称,或 NULL 以匹配所有设备。

con_id

使用者连接器名称,或 NULL 以匹配所有连接器。

provider

隐私屏幕提供程序的 dev_name()

描述

用于静态查找列表,用于将隐私屏幕使用者设备-连接器对映射到隐私屏幕提供程序。

void drm_privacy_screen_lookup_add(struct drm_privacy_screen_lookup *lookup)

向静态隐私屏幕查找列表添加条目

参数

struct drm_privacy_screen_lookup *lookup

要添加的查找列表条目

描述

向静态隐私屏幕查找列表添加条目。 请注意,作为 struct drm_privacy_screen_lookup 一部分的 struct list_head 将被添加到隐私屏幕核心拥有的列表中。 因此,在通过调用 drm_privacy_screen_lookup_remove() 从查找列表中删除传入的 struct drm_privacy_screen_lookup 之前,不得释放它。

void drm_privacy_screen_lookup_remove(struct drm_privacy_screen_lookup *lookup)

从静态隐私屏幕查找列表中删除条目

参数

struct drm_privacy_screen_lookup *lookup

要删除的查找列表条目

描述

从静态隐私屏幕查找列表中删除先前使用 drm_privacy_screen_lookup_add() 添加的条目。

struct drm_privacy_screen *drm_privacy_screen_get(struct device *dev, const char *con_id)

获取隐私屏幕提供程序

参数

struct device *dev

要为其获取隐私屏幕提供程序的使用者设备

const char *con_id

要为其获取隐私屏幕提供程序的(视频)连接器名称

描述

获取连接到由 devcon_id 参数描述的显示器的隐私屏幕的隐私屏幕提供程序。

返回

  • 成功时,指向 struct drm_privacy_screen 的指针。

  • 如果未找到匹配的隐私屏幕,则为 ERR_PTR(-ENODEV)

  • 如果存在匹配的隐私屏幕,则为 ERR_PTR(-EPROBE_DEFER),

    但尚未注册。

void drm_privacy_screen_put(struct drm_privacy_screen *priv)

释放隐私屏幕引用

参数

struct drm_privacy_screen *priv

要释放的隐私屏幕引用

描述

释放通过 drm_privacy_screen_get() 获取的隐私屏幕提供程序引用。 可以使用 NULL 或 ERR_PTR 调用,在这种情况下,它是无操作。

int drm_privacy_screen_set_sw_state(struct drm_privacy_screen *priv, enum drm_privacy_screen_status sw_state)

设置隐私屏幕的 sw-state

参数

struct drm_privacy_screen *priv

要为其设置 sw-state 的隐私屏幕

enum drm_privacy_screen_status sw_state

要设置的新 sw-state 值

描述

设置隐私屏幕的 sw-state。 如果隐私屏幕未处于锁定的 hw-state,则隐私屏幕的实际状态和 hw-state 将立即更新为新值。 如果隐私屏幕处于锁定的 hw-state,则新的 sw-state 将被记住,作为解锁时隐私屏幕要置入的请求状态。

返回

成功时返回 0,失败时返回负错误代码。

void drm_privacy_screen_get_state(struct drm_privacy_screen *priv, enum drm_privacy_screen_status *sw_state_ret, enum drm_privacy_screen_status *hw_state_ret)

获取隐私屏幕的当前状态

参数

struct drm_privacy_screen *priv

要为其获取状态的隐私屏幕

enum drm_privacy_screen_status *sw_state_ret

要在其中存储隐私屏幕当前 sw-state 的地址

enum drm_privacy_screen_status *hw_state_ret

要在其中存储隐私屏幕当前 hw-state 的地址

描述

获取隐私屏幕的当前状态,包括 sw-state 和 hw-state。

int drm_privacy_screen_register_notifier(struct drm_privacy_screen *priv, struct notifier_block *nb)

注册通知程序

参数

struct drm_privacy_screen *priv

要向其注册通知程序的隐私屏幕

struct notifier_block *nb

要注册的通知程序的 Notifier-block

描述

向隐私屏幕注册一个通知程序,以便在隐私屏幕类外部对隐私屏幕状态进行更改时收到通知。 例如,状态可能会因热键按下而由硬件本身更改。

调用通知程序时不持有任何锁。 可以使用 drm_privacy_screen_get_state() 函数检索新的 hw_state 和 sw_state。 指向 drm_privacy_screen 的 struct 的指针作为 notifier_block 的 notifier_call 的 void *data 参数传递。

通过 drm_privacy_screen_set_sw_state() 进行更改时,将不会调用通知程序。 仅针对外部更改调用它。

返回

成功时返回 0,失败时返回负错误代码。

int drm_privacy_screen_unregister_notifier(struct drm_privacy_screen *priv, struct notifier_block *nb)

注销通知程序

参数

struct drm_privacy_screen *priv

要向其注册通知程序的隐私屏幕

struct notifier_block *nb

要注册的通知程序的 Notifier-block

描述

注销使用 drm_privacy_screen_register_notifier() 注册的通知程序。

返回

成功时返回 0,失败时返回负错误代码。

struct drm_privacy_screen *drm_privacy_screen_register(struct device *parent, const struct drm_privacy_screen_ops *ops, void *data)

注册隐私屏幕

参数

struct device *parent

隐私屏幕的父设备

const struct drm_privacy_screen_ops *ops

具有隐私屏幕操作的 struct drm_privacy_screen_ops 指针

void *data

隐私屏幕提供程序拥有的私有数据

描述

创建并注册隐私屏幕。

返回

  • 成功时,指向创建的隐私屏幕的指针。

  • 失败时,为 ERR_PTR(errno)。

void drm_privacy_screen_unregister(struct drm_privacy_screen *priv)

注销隐私屏幕

参数

struct drm_privacy_screen *priv

要注销的隐私屏幕

描述

注销使用 drm_privacy_screen_register() 注册的隐私屏幕。 可以使用 NULL 或 ERR_PTR 调用,在这种情况下,它是无操作。

void drm_privacy_screen_call_notifier_chain(struct drm_privacy_screen *priv)

通知状态更改的使用者

参数

struct drm_privacy_screen *priv

要向其注册通知程序的隐私屏幕

描述

隐私屏幕提供程序驱动程序可以在外部更改隐私屏幕状态时调用此函数。 例如,状态可能会因热键按下而由硬件本身更改。 调用此函数时不得持有隐私屏幕锁。 驱动程序必须更新 sw_state 和 hw_state 以反映新状态,然后再调用此函数。 驱动程序在收到外部状态更改事件后的预期行为是: 1. 获取锁; 2. 更新 sw_state 和 hw_state; 3. 释放锁。 4. 调用 drm_privacy_screen_call_notifier_chain()