模式设置辅助函数

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

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

这些辅助程序可以分为几个领域:

  • 用于实现模式设置的辅助程序。这里的重要辅助程序是原子辅助程序。旧的驱动程序仍然经常使用传统的 CRTC 辅助程序。它们都共享同一组通用辅助 vtable。对于真正简单的驱动程序(任何在已弃用的 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 正在运行,则驱动程序应禁用 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

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

传统的 CRTC 辅助程序和原子辅助程序都使用此函数。对于原子辅助程序,它是可选的。

注意

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

这与允许使用它的传统 CRTC 辅助程序相反。

需要检查和调整更多状态的原子驱动程序应改为使用 atomic_check 回调,但请注意,它们并非完全等效:mode_validdrm_atomic_helper_check_modeset() 调用,而 atomic_checkdrm_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。对于原子驱动程序,在已使用其自身的 drm_encoder_helper_funcs.disable 钩子关闭连接到此 CRTC 的所有编码器后调用此回调。如果该序列太简单,则驱动程序可以仅添加自己的钩子,并通过使用 for_each_encoder_on_crtc() 循环遍历连接到它的所有编码器,然后从此 CRTC 回调中调用它。

此钩子被传统的 CRTC 助手和原子助手使用。如果 CRTC 级别无需禁用任何内容,原子驱动程序则无需实现它。为确保运行时 PM 处理(使用 DPMS 或新的 “ACTIVE” 属性)正常工作,对于原子驱动程序,disable 必须是 atomic_enable 的逆操作。原子驱动程序应考虑使用 atomic_disable 而不是此钩子。

注意

对于传统的 CRTC 助手,用于关闭 CRTC 的 disable 和其他钩子(如 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。对于原子驱动程序,它在通过编码器自己的 drm_encoder_helper_funcs.enable 钩子启用连接到此 CRTC 的所有编码器之前调用。如果该顺序太简单,驱动程序可以只添加自己的钩子,并通过使用 for_each_encoder_on_crtc() 循环遍历连接到它的所有编码器,从这里的 CRTC 回调中调用它。

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

此函数是可选的。

atomic_disable

此回调应用于禁用 CRTC。对于原子驱动程序,在已使用其自身的 drm_encoder_helper_funcs.disable 钩子关闭连接到此 CRTC 的所有编码器后调用此回调。如果该序列太简单,则驱动程序可以仅添加自己的钩子,并通过使用 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 辅助程序相反。

需要检查和调整更多状态的原子驱动程序应改为使用 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 回调函数中。

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

detect

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

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

FIXME

这应该转换为一堆驱动程序 vfuncs。目前 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 助手和原子助手使用。如果不需要在编码器级别禁用任何内容,则原子驱动程序不需要实现它。为了确保运行时 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 的回调函数中调用它们。

此钩子仅由原子助手使用,它是 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, struct drm_display_mode *mode);
    int (*mode_valid_ctx)(struct drm_connector *connector,struct drm_display_mode *mode,struct drm_modeset_acquire_ctx *ctx, enum drm_mode_status *status);
    struct drm_encoder *(*best_encoder)(struct drm_connector *connector);
    struct drm_encoder *(*atomic_best_encoder)(struct drm_connector *connector, struct drm_atomic_state *state);
    int (*atomic_check)(struct drm_connector *connector, struct drm_atomic_state *state);
    void (*atomic_commit)(struct drm_connector *connector, struct drm_atomic_state *state);
    int (*prepare_writeback_job)(struct drm_writeback_connector *connector, struct drm_writeback_job *job);
    void (*cleanup_writeback_job)(struct drm_writeback_connector *connector, struct drm_writeback_job *job);
    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_status 指示连接器的状态,或 drm_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

实现回写连接器的驱动程序应使用此钩子来确定何时将回写作业提交到硬件。要提交的 writeback_job 在新的连接器状态中,在 drm_connector_state.writeback_job 中可用。

此钩子是可选的。

原子模式设置辅助函数使用此回调。

prepare_writeback_job

由于回写作业包含帧缓冲区,驱动程序可能需要准备和清理它们,就像它们可以为平面准备和清理帧缓冲区一样。此可选的连接器操作用于支持回写作业的准备。作业准备操作从 drm_atomic_helper_prepare_planes() 中为结构 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);
    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,以使缓冲区在提交后保持固定。

回调由原子模式设置辅助函数使用,但它是可选的。请参阅 end_fb_cleanup 以撤消 begin_fb_access 的效果,并参阅 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_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_update 的替代方法,如果未实现 atomic_disable 挂钩,则也将调用它来禁用平面。

此挂钩还可用于通过从 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() 调用,以确定是否可以异步提交给定的更新,也就是说,如果它可以跳到当前排队等待更新的状态之前。

返回值

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

atomic_async_update

驱动程序应设置此函数指针以执行平面的异步更新,即跳到当前排队的状态之前并更新平面。此处的异步是指“不与垂直同步同步”。

此挂钩由 drm_atomic_helper_async_commit() 调用。

异步更新将发生在传统的光标更新上。如果存在修改同一平面的未完成的提交,则不会发生异步更新。

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

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

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

  • 尚不支持异步页面翻转

  • 某些硬件可能会在下一个垂直同步信号到来之前继续扫描旧的缓冲区,但我们会在运行此钩子后立即释放帧缓冲区引用。目前,驱动程序必须实现自己的工作线程来延迟操作(如果需要),直到创建通用的解决方案。

get_scanout_buffer

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

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

panic_flush

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

描述

这些函数由 atomic 助手使用。

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

为平面设置 helper vtable

参数

struct drm_plane *plane

DRM 平面

const struct drm_plane_helper_funcs *funcs

要为 plane 设置的 helper vtable

struct drm_mode_config_helper_funcs

全局模式设置 helper 操作

定义:

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_commit() 中实现的默认 atomic_commit() 钩子以及非阻塞提交助手(有关起始点,请参见 drm_atomic_helper_setup_commit())一起使用,以轻松实现阻塞和非阻塞提交。它不由 atomic 助手使用。

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

将 atomic 更新提交到硬件后,此钩子需要调用 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 助手使用。

Atomic 模式设置助手函数参考

概述

此助手库在 CRTC 模式设置助手回调和平面助手回调之上提供了检查和提交函数的实现。它还为不需要子类化 drm 核心结构以添加其自己的其他内部状态的驱动程序提供了 atomic 状态处理回调的便捷实现。

此库还提供了 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 函数表。

实现异步 Atomic 提交

非阻塞 atomic 提交应使用 struct drm_crtc_commit 来对彼此不同的操作进行排序。锁,特别是 struct drm_modeset_lock,不应在工作线程或用于提交硬件状态的任何其他异步上下文中持有。

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

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

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

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

重要提示:对多个 CRTC 的 drm_atomic_state 更新会针对其中的所有 CRTC 进行排序。因此,对于仅翻转平面的原子状态更新,驱动程序不得在其原子检查代码中获取不相关的 CRTC 的结构 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_vblank是从drm_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 空间分配和水印计算时。

返回

成功返回 0,否则返回 -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

驱动程序状态对象

描述

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

返回

成功返回 0,否则返回 -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 定点表示的最小:目标缩放因子

int max_scale

以 16.16 定点表示的最大:目标缩放因子

bool can_position

是否允许定位平面,使其不覆盖整个 CRTC?这通常只对主平面为 false。

bool can_update_disabled

是否可以在 CRTC 被禁用时更新平面?

描述

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

返回

如果更新看起来有效,则返回 0,否则返回错误代码

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 已更新平面。

返回

成功返回 0,否则返回 -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_check** 和 **drm_crtc_helper_funcs.atomic_check** 函数依赖于更新后的 adjusted_mode.clock,以便例如正确计算水印。

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

返回

成功返回 0,否则返回 -errno

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

更新旧式模式设置状态

参数

struct drm_device *dev

DRM 设备

struct drm_atomic_state *old_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 *old_state)

模式设置提交以禁用输出

参数

struct drm_device *dev

DRM 设备

struct drm_atomic_state *old_state

包含旧状态结构的原子状态对象

描述

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

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

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

模式设置提交以启用输出

参数

struct drm_device *dev

DRM 设备

struct drm_atomic_state *old_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)

等待存储在平面状态中的栅栏

参数

struct drm_device *dev

DRM 设备

struct drm_atomic_state *state

包含旧状态结构的原子状态对象

bool pre_swap

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

描述

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

请注意,需要 **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 *old_state)

等待 CRTC 上的垂直消隐

参数

struct drm_device *dev

DRM 设备

struct drm_atomic_state *old_state

包含旧状态结构的原子状态对象

描述

在原子提交之后,帮助程序等待所有受影响的 CRTC 上的垂直消隐(即,在使用 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 *old_state)

等待所有页面翻转完成

参数

struct drm_device *dev

DRM 设备

struct drm_atomic_state *old_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 *old_state)

将原子更新提交到硬件

参数

struct drm_atomic_state *old_state

包含旧状态结构的原子状态对象

描述

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

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

void drm_atomic_helper_commit_tail_rpm(struct drm_atomic_state *old_state)

将原子更新提交到硬件

参数

struct drm_atomic_state *old_state

要提交的新模式设置状态

描述

这是 drm_mode_config_helper_funcs.atomic_commit_tail 钩子的另一种实现,适用于支持 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

驱动程序状态对象

描述

此函数异步提交状态,即,不与垂直同步信号同步。仅当 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 钩子中调用此函数。

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

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

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

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

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

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

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

返回

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

void drm_atomic_helper_wait_for_dependencies(struct drm_atomic_state *old_state)

等待所需的前置提交

参数

struct drm_atomic_state *old_state

包含旧状态结构的原子状态对象

描述

此函数会等待所有与 old_state 触及同一 CRTC 的前置提交,以便将它们提交到硬件(如 drm_atomic_helper_commit_hw_done() 所指示)并由硬件执行(如通过在 drm_crtc_state.event 上调用 drm_crtc_send_vblank_event() 所指示)。

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

void drm_atomic_helper_fake_vblank(struct drm_atomic_state *old_state)

如果需要,则伪造 VBLANK 事件

参数

struct drm_atomic_state *old_state

包含旧状态结构的原子状态对象

描述

此函数会遍历所有 CRTC,并对 drm_crtc_state.no_vblank 设置为 true 且 drm_crtc_state.event != NULL 的 CRTC 伪造 VBLANK 事件。此函数的主要用途是在单次模式下工作的回写连接器和伪造 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 *old_state)

设置可能的非阻塞提交

参数

struct drm_atomic_state *old_state

包含旧状态结构的原子状态对象

描述

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

驱动程序应尝试将任何代价高昂或延迟的清理工作推迟到调用此函数之后。

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

void drm_atomic_helper_commit_cleanup_done(struct drm_atomic_state *old_state)

发出提交完成的信号

参数

struct drm_atomic_state *old_state

包含旧状态结构的原子状态对象

描述

这表示原子更新 old_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 *old_state, uint32_t flags)

提交平面状态

参数

struct drm_device *dev

DRM 设备

struct drm_atomic_state *old_state

包含旧状态结构的原子状态对象

uint32_t flags

用于提交平面状态的标志

描述

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

它仍然需要全局状态对象 old_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 钩子同步

描述

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

如果设置了 atomic 参数,则此函数在禁用平面之前调用 CRTC 的 atomic_begin 钩子,并在之后调用 atomic_flush 钩子。

如果在没有实现 drm_plane_helper_funcs.atomic_disable 平面钩子的情况下调用此函数,则会出现错误。

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

提交后清理平面资源

参数

struct drm_device *dev

DRM 设备

struct drm_atomic_state *old_state

包含旧状态结构的原子状态对象

描述

此函数从旧配置中清理平面状态,特别是帧缓冲区。因此,必须在 old_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,失败返回负错误代码。

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

原子连接器状态,不能为空。

struct drm_connector *connector

连接器对象,不能为空。

描述

使用默认值初始化新分配的 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 映射。

在扫描输出之前,需要将平面的帧缓冲与可能绘制到帧缓冲中的写入器同步。所有驱动程序都应从其结构 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,
};

使用阴影缓冲区的驱动程序在原子更新期间将阴影缓冲区的内容复制到硬件的帧缓冲内存中。这需要将阴影缓冲区映射到内核地址空间。映射不能由提交尾部函数(如 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,
};

在驱动程序的原子更新函数中,阴影缓冲区映射可从平面状态获得。使用 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
}

每个帧缓冲区的缓冲对象映射地址都存储在结构 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

格式转换状态

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

映射

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

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

数据

每个帧缓冲区 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

平面

描述

此函数为阴影缓冲平面实现结构 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 的平面状态

描述

此函数为阴影缓冲平面实现结构 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

平面

描述

此函数为阴影缓冲平面实现结构体 drm_plane_funcs.reset_plane。它假设当前的平面状态为结构体 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 的平面状态

描述

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

有关清理,请参阅 drm_gem_end_shadow_fb_access()

返回

成功时返回 0,否则返回负的错误代码。

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 的平面状态

描述

此函数实现结构体 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 的平面状态

描述

此函数实现结构体 drm_simple_display_funcs.begin_fb_access。

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

返回

成功时返回 0,否则返回负的错误代码。

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 的平面状态

描述

此函数实现结构体 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

简单显示管道

描述

此函数为阴影缓冲平面实现结构体 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

简单显示管道

描述

此函数为阴影缓冲平面实现结构体 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 的平面状态

描述

此函数为阴影缓冲平面实现结构体 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 禁用时会调用它。此钩子是可选的。

检查

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

返回值

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

更新

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

这是驱动程序应从中提交 drm_pending_vblank_event 的函数。如果驱动程序支持垂直消隐中断处理,则使用 drm_crtc_arm_vblank_event();对于更复杂的情况,使用 drm_crtc_send_vblank_event()。如果硬件完全缺乏垂直消隐支持,驱动程序可以在 struct drm_simple_display_pipe_funcs.check 中设置 struct drm_crtc_state.no_vblank,并让 DRM 的原子助手伪造一个垂直消隐事件。

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 钩子的文档以获取更多详细信息。

启用垂直消隐

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

禁用垂直消隐

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

重置 CRTC

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

复制 crtc 状态

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

销毁 crtc 状态

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

重置平面

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

复制平面状态

可选,由 drm_plane_funcs.atomic_duplicate_state 调用。请阅读 drm_plane_funcs.atomic_duplicate_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

平面控制结构

编码器

编码器控制结构

连接器

连接器控制结构

功能

管道控制函数(可选)

描述

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

drmm_simple_encoder_alloc

drmm_simple_encoder_alloc (dev, type, member, encoder_type)

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

参数

dev

drm 设备

type

包含结构体 drm_encoder 的结构体的类型

member

type 内的 drm_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 管理的资源基础设施负责清理和释放。

返回

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

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() 来初始化管道。

返回

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

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() 自动处理。驱动程序之后需要自己释放结构的内存。

返回

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

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 回调,它还将计划 dirty_work 并从 mmap 页面写入中收集损坏。

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_probe)(struct drm_fb_helper *helper, struct drm_fb_helper_surface_size *sizes);
    int (*fb_dirty)(struct drm_fb_helper *helper, struct drm_clip_rect *clip);
};

成员

fb_probe

驱动程序回调,用于分配和初始化 fbdev 信息结构。此外,它还需要分配用于支持 fbdev 的 DRM 帧缓冲。

此回调是强制性的。

返回值

驱动程序应该在成功时返回 0,在失败时返回负错误代码。

fb_dirty

驱动程序回调,用于更新帧缓冲内存。如果设置了此回调,fbdev 仿真将在帧缓冲被写入后定期调用此回调。

此回调是可选的。

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

描述

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 设备

功能

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,否则返回负的错误代码。

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()

返回

如果一切正常,则为零;否则为非零。

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。由驱动程序在 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 辅助程序,不能为空。

描述

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 info 结构以及用于支持 fbdev 的 drm 帧缓冲。drm_fb_helper_fill_info() 作为辅助函数,用于为 fbdev info 结构设置简单的默认值。

挂起调试

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

标准的调试做法是在不使用 console_lock 的情况下运行 fbcon 设置,作为一种技巧,以便能够在串行线上看到回溯和崩溃。这可以通过设置 fb.lockless_register_fb=1 内核命令行选项来实现。

另一个选择是禁用 fbdev 仿真,因为很可能来自用户空间的第一个模式设置也会以相同的方式崩溃,并且更容易调试。这可以通过设置 drm_kms_helper.fbdev_emulation=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_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 -> 亮度(亮度)转换。

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)

在发生紧急情况时提供扫描输出缓冲区

参数

struct drm_plane *plane

DRM 主平面

struct drm_scanout_buffer *sb

紧急处理程序的扫描输出缓冲区

返回

0 或负错误代码

描述

通用的 get_scanout_buffer() 实现,适用于使用 drm_fb_dma_helper 的驱动程序。它不会在紧急上下文中调用 vmap,因此驱动程序应确保主平面已 vmapped,否则不会显示紧急屏幕。

帧缓冲区 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 描述。此描述包括支持帧缓冲的缓冲区句柄。

如果您的硬件有特殊的对齐或间距要求,则应在调用此函数之前进行检查。该函数会执行缓冲区大小验证。如果需要刷新帧缓冲,请使用 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() 用于脏回调,通过原子机制提供帧缓冲刷新。如果不需要脏回调,请使用 drm_gem_fb_create()。该函数会执行缓冲区大小验证。

驱动程序还应在所有平面上调用 drm_plane_enable_fb_damage_clips(),以使用户空间也可以使用 ATOMIC IOCTL 进行损坏剪辑。

驱动程序可以将此用作它们的 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,否则返回负的错误代码。

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)

准备用于 CPU 访问的 GEM 缓冲区对象

参数

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,否则返回负的错误代码。

void drm_gem_fb_end_cpu_access(struct drm_framebuffer *fb, enum dma_data_direction dir)

指示结束对 GEM 缓冲区对象的 CPU 访问

参数

struct drm_framebuffer *fb

帧缓冲

enum dma_data_direction dir

访问模式

描述

指示结束对给定帧缓冲的 GEM 缓冲区对象的 CPU 访问。此函数必须与对 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,然后桥接器 A 又馈送到桥接器 B。桥接器链可以任意长,并且应该是完全线性的:不支持将多个桥接器链接到桥接器的输出,或者将同一个桥接器链接到不同桥接器的输出。

drm_bridge,与 drm_panel 一样,不是像平面、CRTC、编码器或连接器那样的 drm_mode_object 实体,因此对用户空间不可见。它们只是提供额外的钩子,以在编码器链的末尾获得所需的输出。

显示驱动程序集成

显示驱动程序负责将编码器与链中的第一个桥接器链接起来。这通过使用 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_ATTACH_NO_CONNECTOR 标志时,应从其 drm_bridge_funcs.attach 处理程序返回错误。新的显示驱动程序应使用新模型,并在需要时转换它们使用的桥接驱动程序,以便逐步过渡到新模型。

桥接器连接器辅助函数

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, 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_bridge_state *old_bridge_state);
    void (*atomic_enable)(struct drm_bridge *bridge, struct drm_bridge_state *old_bridge_state);
    void (*atomic_disable)(struct drm_bridge *bridge, struct drm_bridge_state *old_bridge_state);
    void (*atomic_post_disable)(struct drm_bridge *bridge, struct drm_bridge_state *old_bridge_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);
    void (*debugfs_init)(struct drm_bridge *bridge, struct dentry *root);
};

成员

attach

每当我们的桥接器连接到 drm_encoder 时,就会调用此回调。 flags 参数调整附加操作的行为(请参阅 DRM_BRIDGE_ATTACH_*)。

attach 回调是可选的。

返回值

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

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

此回调用于验证和调整模式。参数 mode 是应该馈送到显示链中下一个元素的显示模式,可以是最终的 drm_connector 或下一个 drm_bridge。参数 adjusted_mode 是桥接器需要的输入模式。它可以由此回调修改,并且不需要与 mode 匹配。另请参阅 drm_crtc_state.adjusted_mode 了解更多详细信息。

这是唯一允许桥接器拒绝模式设置的挂钩。 如果此函数通过,则此配置的所有其他回调都必须成功。

mode_fixup 回调是可选的。当实现了 drm_bridge_funcs.atomic_check() 时,不会调用 drm_bridge_funcs.mode_fixup(),因此只能提供其中一个。

注意

此函数在原子模式设置的检查阶段调用,由于任何原因(包括用户空间请求仅检查配置是否可能)可以中止。驱动程序绝不能触摸任何持久状态(硬件或软件)或数据结构,除了传入的 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 参数不同,后者包含桥接器链末端连接器的所需模式,例如,当链中的第一个桥接器执行缩放时。调整后的模式对于链中的第一个桥接器最有用,并且可能与其他桥接器无关。

对于原子驱动程序,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`() 中发生的总线格式协商过程的一部分在桥接器链的最后一个元素上调用。此方法是可选的。当未实现时,如果 drm_connector.display_info.num_bus_formats > 0,则核心将回退到 drm_connector.display_info.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 作为其输出总线格式传递。

需要支持链接到不支持总线格式协商的桥接器的桥接器驱动程序,应通过选择一个合理的默认值或从其他地方(FW 属性,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 标志。

connector 参数仅用于填充模式,桥接器驱动程序不应将其存储在内部以供将来使用。

返回值

通过调用 drm_mode_probed_add() 添加的模式数量。

edid_read

读取连接的显示器的 EDID 数据。

edid_read 回调是报告连接到桥接器输出的显示器模式信息的首选方式。支持读取 EDID 的桥接器应实现此回调,并将 get_modes 回调保持未实现状态。

此操作的调用者应首先验证输出连接状态,并避免从断开连接的输出读取 EDID。

此回调是可选的。实现此回调的桥接器应在其 drm_bridge->ops 中设置 DRM_BRIDGE_OP_EDID 标志。

connector 参数仅用于 EDID 检索,桥接器驱动程序不应将其存储在内部以供将来使用。

返回值

成功时,使用 drm_edid_alloc() 新分配的 edid 结构,或从 drm_edid_read() 系列函数返回,否则为 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 标志的桥接器实现。

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 回调。

注意:目前,链中最多只能有一个桥接器设置此位。这是为了简化连接器驱动程序中的相应粘合代码。

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 *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;
};

成员

基本

继承自 drm_private_object

dev

此桥接器所属的 DRM 设备

编码器

此桥接器连接到的编码器

chain_node

用于形成桥接器链

of_node

指向桥接器的设备节点指针

list

用于跟踪所有添加的桥接器

timings

桥接器的时序规范(如果有,可能为 NULL)

功能

控制函数

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 设备的要求,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,则这是必需的。

产品

用于生成 SPD InfoFrame 的产品名称。如果设置了 DRM_BRIDGE_OP_HDMI,则这是必需的。

supported_formats

hdmi_colorspace 的位掩码,列出了支持的输出格式。这仅在设置了 DRM_BRIDGE_OP_HDMI 时相关。

max_bpc

HDMI 桥接器支持的最大每字符位数。允许的值为 8、10 和 12。这仅在设置了 DRM_BRIDGE_OP_HDMI 时相关。

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)

迭代链中存在的所有桥接器

参数

编码器

要在其上迭代桥接器的编码器

bridge

一个桥接器指针,在每次迭代时更新为指向当前桥接器

描述

迭代附加到 encoder 的桥接器链中存在的所有桥接器。

void drm_bridge_add(struct drm_bridge *bridge)

将给定的桥接器添加到全局桥接器列表

参数

struct drm_bridge *bridge

桥控制结构

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,则桥接器直接链接到编码器的输出。否则,它将链接到上一个桥接器的输出。

如果为非 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 *old_state)

禁用编码器链中的所有桥接器

参数

struct drm_bridge *bridge

桥控制结构

struct drm_atomic_state *old_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 *old_state)

在禁用编码器链中的所有桥接器后进行清理

参数

struct drm_bridge *bridge

桥控制结构

struct drm_atomic_state *old_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** 的调用方向。

如果桥接器 B、D、E 中启用了 pre_enable_prev_first 标志,则最终的 **post_disable** 顺序将是:桥接器 B、桥接器 A、桥接器 E、桥接器 D、桥接器 C。

示例

桥接器 A ---> 桥接器 B ---> 桥接器 C ---> 桥接器 D ---> 桥接器 E

注意

传递的桥接器应是最靠近编码器的那个

void drm_atomic_bridge_chain_pre_enable(struct drm_bridge *bridge, struct drm_atomic_state *old_state)

准备启用编码器链中的所有桥接器

参数

struct drm_bridge *bridge

桥控制结构

struct drm_atomic_state *old_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 之前被调用。

如果桥接器 B、D、E 中启用了 pre_enable_prev_first 标志,则最终的 **pre_enable** 顺序将是:桥接器 C、桥接器 D、桥接器 E、桥接器 A、桥接器 B。

示例

桥接器 A ---> 桥接器 B ---> 桥接器 C ---> 桥接器 D ---> 桥接器 E

注意

传递的桥接器应是最靠近编码器的那个

void drm_atomic_bridge_chain_enable(struct drm_bridge *bridge, struct drm_atomic_state *old_state)

启用编码器链中的所有桥接器

参数

struct drm_bridge *bridge

桥控制结构

struct drm_atomic_state *old_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 面板桥接器实例。

如果成功,则返回指向桥接器的 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

禁用面板(关闭背光等)。

此函数是可选的。

取消准备。

关闭面板。

此函数是可选的。

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;
};

成员

dev

面板的父设备。

背光

背光设备,用于在调用 enable() 后打开背光,以及在调用 disable() 之前关闭背光。背光由 drm_panel_of_backlight()drm_panel_dp_aux_backlight() 设置,驱动程序不得分配它。

功能

可以在面板上执行的操作。

connector_type

面板的类型,作为 DRM_MODE_CONNECTOR_* 值。这用于使用正确的连接器类型初始化与面板对应的 drm_connector。

list

注册表中的面板条目。

followers

依赖于此面板的 struct drm_panel_follower 列表。

follower_lock

followers 列表的锁。

prepare_prev_first

上一个控制器应首先准备好,然后再调用面板的准备。这在很大程度上是 DSI 面板所必需的,其中 DSI 主机控制器应在面板上电之前初始化为 LP-11。

prepared

如果为 true,则面板已准备好。

enabled

如果为 true,则面板已启用。

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_panel_add() 进行注册。

void drm_panel_add(struct drm_panel *panel)

将面板添加到全局注册表。

参数

struct drm_panel *panel

要添加的面板。

描述

将面板添加到全局注册表,以便显示驱动程序可以查找它。

void drm_panel_remove(struct drm_panel *panel)

从全局注册表中删除面板。

参数

struct drm_panel *panel

DRM 面板。

描述

从全局注册表中删除面板。

int drm_panel_prepare(struct drm_panel *panel)

打开面板的电源。

参数

struct drm_panel *panel

DRM 面板。

描述

调用此函数将启用电源并取消断言对面板的任何复位信号。完成此操作后,可以通过命令总线与任何集成电路进行通信。

返回

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

int drm_panel_unprepare(struct drm_panel *panel)

关闭面板电源

参数

struct drm_panel *panel

DRM 面板。

描述

调用此函数将完全关闭面板电源(断言面板复位,关闭电源等)。此函数完成后,通常无法再与面板通信,直到再次调用drm_panel_prepare()

返回

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

int drm_panel_enable(struct drm_panel *panel)

启用面板

参数

struct drm_panel *panel

DRM 面板。

描述

调用此函数将导致面板显示驱动程序开启,并启用背光。此调用完成后,屏幕上将显示内容。

返回

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

int drm_panel_disable(struct drm_panel *panel)

禁用面板

参数

struct drm_panel *panel

DRM 面板。

描述

这将通常关闭面板的背光或禁用显示驱动程序。对于智能面板,在此调用之后,仍然可以通过任何命令总线与集成电路进行通信。

返回

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

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 *of_drm_find_panel(const struct device_node *np)

使用设备树节点查找面板

参数

const struct device_node *np

面板的设备树节点

描述

搜索已注册面板的集合,以查找与给定设备树节点匹配的面板。如果找到匹配的面板,则返回指向它的指针。

此函数返回的可能错误代码

  • EPROBE_DEFER: 面板设备尚未探测,调用者应稍后重试

  • ENODEV: 设备不可用(status != “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 与面板一起进行电源排序。目前,面板只能在启用设备树的系统上跟随。“跟随者”的“面板”属性指向要跟随的面板。

返回

如果应该与面板一起进行电源排序,则为 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

跟随者的面板跟随者描述符。

描述

面板跟随者在准备面板之后立即调用,并在取消准备面板之前立即调用。它的主要目的是为相关的触摸屏供电,尽管它也可以用于任何类似的设备。允许多个设备跟随同一面板。

如果将跟随者添加到已开启的面板,则会立即调用跟随者的准备回调。

目前,面板只能在启用设备树的系统上跟随。“跟随者”的“面板”属性指向要跟随的面板。

返回

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()。这包括如果我们从当前已准备的面板中移除,则调用跟随者的取消准备函数。

返回

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 子系统之外的代码使用,例如 efifb 代码。因此,当作为模块构建时,此函数会被编译成自己的内核模块。

返回

如果此系统有特殊设置,则返回 DRM_MODE_PANEL_ORIENTATION_* 值;如果没有特殊设置,则返回 DRM_MODE_PANEL_ORIENTATION_UNKNOWN。

面板自刷新助手参考

此助手库为驱动程序提供了一种利用原子框架实现面板自刷新 (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 开/关请求,其中 drm_crtc_state.self_refresh_active 在 crtc 状态中设置,指示你禁用/启用面板上的 SR,而不是对其进行电源循环。

在 SR 期间,驱动程序可以选择完全禁用其 crtc/编码器/桥接硬件(在这种情况下,无需进行驱动程序更改),或者他们可以检查 drm_crtc_state.self_refresh_active,如果他们想要进入低功耗模式而不完全禁用(以防完全禁用/启用太慢)。

如果有任何影响处于 SR 模式的管道的原子更新,SR 将被停用。如果一个 crtc 驱动多个连接器,则所有连接器都必须支持 SR,并且它们将同时进入/退出 SR 模式。

如果 crtc 和连接器支持 SR,但连接的面板不支持 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

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 辅助函数参考

这些函数包含一些通用的逻辑和辅助函数,用于在各种抽象级别上处理 DisplayPort 接收设备和相关事物,例如 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

DP 二次数据包数据块 VSC SDP 有效负载,用于 PSR 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

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 适配器。

连接器

此 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;
};

成员

name

此 AUX 通道和 I2C-over-AUX 适配器的用户可见名称。

它也用于指定 I2C 适配器的名称。如果设置为 NULL,则将使用 devdev_name()

ddc

可用于 I2C-over-AUX 通信的 I2C 适配器

dev

指向作为此 AUX 通道的父级的 struct device 的指针。

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 结构的回复字段。重试逻辑和 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 概念不同,后者更多的是关于显示器的物理存在。例如,对于 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,则远程端点已断电。

描述

AUX 通道还可用于将 I2C 消息传输到接收器。典型的应用是访问接收器设备中存在的 EDID。transfer() 函数也可用于执行此类事务。drm_dp_aux_register() 函数注册一个可以传递给 drm_probe_ddc() 的 I2C 适配器。删除时,驱动程序应调用 drm_dp_aux_unregister() 以删除 I2C 适配器。默认情况下,I2C 适配器使用长传输;如果收到部分响应,则适配器将仅针对此事务降低到部分响应给出的大小。

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),失败时返回负错误代码。

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),失败时返回负错误代码。

struct drm_dp_desc

DP 分支/接收器设备描述符

定义:

struct drm_dp_desc {
    struct drm_dp_dpcd_ident ident;
    u32 quirks;
};

成员

ident

来自 DPCD 0x400(接收器)或 0x500(分支)的 DP 设备标识。

quirks

怪癖;使用 drm_dp_has_quirk() 查询怪癖。

enum drm_dp_quirk

DisplayPort接收器/分支设备特定的怪癖

常量

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() 会自动检查此怪癖。

DP_DPCD_QUIRK_DSC_WITHOUT_VIRTUAL_DPCD

该设备支持MST DSC,即使不支持虚拟DPCD。 可以从物理aux读取DSC cap。

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。

描述

野外的DisplayPort接收器和分支设备存在各种各样的错误,请尝试在此处收集它们。 这些怪癖是共享的,但由驱动程序来实现它们的解决方法。

bool drm_dp_has_quirk(const struct drm_dp_desc *desc, enum drm_dp_quirk quirk)

DP设备是否具有特定的怪癖

参数

const struct drm_dp_desc *desc

drm_dp_read_desc() 填充的设备描述符

enum drm_dp_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启用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

通过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 <N>”,或者错误时为“<INVALID DP PHY>”。 返回的字符串始终为非NULL且有效。

返回

DP PHY的名称。

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除外,它会导致重试事务)会传播给调用方。

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除外,它会导致重试事务)会传播给调用方。

读取DPCD链路状态(字节0x202-0x207)

参数

struct drm_dp_aux *aux

DisplayPort AUX 通道

u8 status[DP_LINK_STATUS_SIZE]

用于存储链路状态的缓冲区(必须至少为6个字节)

描述

成功时返回传输的字节数,失败时返回负错误代码。

获取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;否则返回负错误代码。

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_DPDP_DS_PORT_TYPE_VGADP_DS_PORT_TYPE_DVIDP_DS_PORT_TYPE_HDMIDP_DS_PORT_TYPE_NON_EDIDDP_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,以便在 DRM DP 帮助程序的调试输出中可以提到与 AUX 适配器对应的 drm_device

对于为其 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 sink 读取 slice capabilities DPCD 寄存器,获取支持的最大 slice 数量。驱动程序使用此值填充 struct drm_dsc_config 中的 DSC 参数。驱动程序使用这些参数创建信息帧,以填充 struct drm_dsc_pps_infoframe。这些信息帧通过辅助函数 drm_dsc_pps_infoframe_pack() 使用 DSC 信息帧发送到 sink。

返回

DSC sink 支持的最大 slice 数量,如果为 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 sink 支持的解码器行缓冲区内的精度比特数。驱动程序使用此值填充 struct drm_dsc_config 中的 DSC 参数。驱动程序使用这些参数创建信息帧,以填充 struct drm_dsc_pps_infoframe。这些信息帧通过辅助函数 drm_dsc_pps_infoframe_pack() 使用 DSC 信息帧发送到 sink。

返回

DSC 面板支持的行缓冲深度,如果为 0 则无效。

int drm_dp_dsc_sink_supported_input_bpcs(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE], u8 dsc_bpc[3])

获取 DSC sink 支持的每个分量的所有输入比特数。

参数

const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE]

来自 DPCD 的 DSC 功能

u8 dsc_bpc[3]

一个数组,由这个辅助函数填充支持的输入 bpc。

描述

从 sink 设备读取 DSC DPCD,以解析支持的每分量比特数值。驱动程序使用此值填充 struct drm_dsc_config 中的 DSC 参数。驱动程序使用这些参数创建信息帧,以填充 struct drm_dsc_pps_infoframe。这些信息帧通过辅助函数 drm_dsc_pps_infoframe_pack() 使用 DSC 信息帧发送到 sink。

返回

从 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]

用于返回功能信息的缓冲区

描述

读取所有 LTTPRs 通用的功能。

成功时返回 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])

获取检测到的 LTTPRs 的数量

参数

const u8 caps[DP_LTTPR_COMMON_CAP_SIZE]

LTTPR 通用功能

描述

从 LTTPR 通用功能信息中获取检测到的 LTTPRs 的数量。

返回

- 如果检测到的 LTTPRs 数量超过支持的数量 (8),则返回 -ERANGE; - 如果 DP_PHY_REPEATER_CNT 寄存器包含无效值,则返回 -EINVAL;否则,返回检测到的 LTTPRs 的数量。

获取所有 LTTPRs 支持的最大链路速率

参数

const u8 caps[DP_LTTPR_COMMON_CAP_SIZE]

LTTPR 通用功能

描述

返回所有检测到的 LTTPRs 支持的最大链路速率。

int drm_dp_lttpr_max_lane_count(const u8 caps[DP_LTTPR_COMMON_CAP_SIZE])

获取所有 LTTPRs 支持的最大通道数

参数

const u8 caps[DP_LTTPR_COMMON_CAP_SIZE]

LTTPR 通用功能

描述

返回所有检测到的 LTTPRs 支持的最大通道数。

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)

从 sink 获取请求的模式。

参数

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 链路配置 - 第 1 步

参数

struct drm_dp_aux *aux

DisplayPort AUX 通道

int max_frl_gbps

要在 PCON 和 HDMI 接收器之间配置的最大 FRL 带宽

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 带宽

u8 frl_type

FRL 训练类型,可以是扩展的或普通的。在普通 FRL 训练中,PCON 从 min 开始尝试 max_frl_mask 中的每个 FRL 带宽,并在链路训练成功时停止。在扩展 FRL 训练中,PCON 会训练掩码中选择的所有 FRL 带宽。

描述

如果成功,则返回 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 链路状态是否处于活动状态。

参数

struct drm_dp_aux *aux

DisplayPort AUX 通道

描述

如果链路处于活动状态,则返回 true,否则返回 false。

获取 PCON HDMI 链路模式

参数

struct drm_dp_aux *aux

DisplayPort AUX 通道

u8 *frl_trained_mask

用于存储训练带宽配置的位掩码的指针。仅当返回的 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 Sink 之间 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,失败返回负错误代码。

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

如果设置了 flags/DRM_DP_LINK_BW_OVERHEAD_DSC,则为 DSC 切片计数。

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 颜色深度 - 压缩模式(flags / DRM_DP_OVERHEAD_DSC)。请注意,此开销不包括 8b/10b、128b/132b 通道编码效率,有关详细信息,请参阅 drm_dp_link_bw_channel_coding_efficiency()

以百万分之一 (ppm) 为单位返回开销,表示为 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 开销是特定于带宽分配的,包含在 drm_dp_bw_overhead() 返回的值中。

以百万分之一 (ppm) 为单位返回效率,表示为 100%/编码开销 % 比率。

int drm_dp_max_dprx_data_rate(int max_link_rate, int max_lanes)

获取 DPRX 接收器的最大数据带宽

参数

int max_link_rate

以 10kbps 为单位的最大 DPRX 链路速率

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:适配器寄存器(如果有),可以通过 I2C 访问接收器 DDC 总线。

类型 2:适配器寄存器,可以通过 I2C 或 I2C-over-AUX 访问接收器 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

缓冲区的大小

描述

offset 开始的 DP 双模式适配器寄存器中读取 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

缓冲区的大小

描述

offset 开始的 DP 双模式适配器寄存器中写入 size 个字节。

返回

成功时返回 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 时钟频率。由于某些 type 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 寄存器查询的。由于某些 type 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 寄存器设置的。Type1 适配器不支持任何寄存器写入。

返回

成功时返回 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)

通过写入偏移量 (0x80, 0x40) 更改 LSPCON 的工作模式

参数

const struct drm_device *dev

要使用的 drm_device

struct i2c_adapter *adapter

I2C-over-aux 适配器

enum drm_lspcon_mode mode

所需的工作模式

返回

成功时为 0,失败/超时时返回 -错误

Display Port MST 助手

概述

这些函数包含 DisplayPort 1.2a 多流传输协议的部分内容。助手包含拓扑管理器和带宽管理器。助手封装了边带消息的发送和接收。

拓扑引用计数概述

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

此端口的分支设备父设备

连接器

此端口连接到的 DRM 连接器。受 drm_dp_mst_topology_mgr.base.lock 保护。

mgr

此端口所处的拓扑管理器。

cached_edid

对于 DP 逻辑端口 - 通过确保立即读取所有连接器的 EDID 来使平铺工作正常。

fec_capable

布尔值,指示在 MST 拓扑中,是否可以在该点支持 FEC。

描述

此结构表示 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

与此分支设备通信的相对地址。

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 sink/分支设备,则为 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 的 sink 计数。

功能

原子助手回调

qlock

保护 tx_msg_downqdrm_dp_sideband_msg_tx.state

tx_msg_downq

待处理的下行请求列表

tx_waitq

等待 tx 工作线程的队列停顿。

work

探测工作。

tx_work

边带传输工作线程。这可以嵌套在每个事务 work 启动的主 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

sink 的 MST 模式功能

常量

DRM_DP_SST

sink 不支持 MST 也不支持单流边带消息传递。

DRM_DP_MST

sink 支持 MST,多个流和单流边带消息传递。

DRM_DP_SST_SIDEBAND_MSG

sink 仅支持一个流和单流边带消息传递。

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)

执行负载更新的第二部分

参数

struct drm_dp_mst_topology_mgr *mgr

要使用的管理器。

struct drm_dp_mst_atomic_payload *payload

要更新的负载

描述

如果 payload 已被 drm_dp_add_payload_part1() 成功分配了起始时隙,此函数将发送边带消息以完成此负载的分配。

返回

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

fixed20_12 drm_dp_get_vc_payload_bw(const struct drm_dp_mst_topology_mgr *mgr, int link_rate, int link_lane_count)

获取 MST 链路的 VC 负载带宽

参数

const struct drm_dp_mst_topology_mgr *mgr

要使用的 drm_dp_mst_topology_mgr

int link_rate

链路速率,单位为 10kbits/s

int link_lane_count

通道数

描述

计算多流传输链路的总带宽。返回值的单位是 PBNs/(时隙/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 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 中断事件并确认后,应该从驱动程序调用此函数。请注意,只有在前一个消息事务完成后才应发送新的下行请求。源不应生成交错的消息事务。

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 原子状态。

在驱动程序调用 drm_dp_mst_atomic_check() 之前,此函数设置的分配不会针对 mgr 的带宽限制进行检查。

此外,根据需要多次在同一个 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 拓扑,并等待任何挂起的提交(这些提交触及了曾经或现在位于 MST 拓扑上的 CRTC)被编程到硬件并翻转后才返回。这是为了防止多个非阻塞提交影响 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 连接器上发生的非阻塞提交,该连接器正在进入/退出 MST 模式 - 因为实际 DP 连接器上的 CRTC 和连接器的 MST 拓扑上的 CRTC 将永远不会共享同一个 drm_encoder

此函数通过检查根 MST 连接器的原子状态来解决此序列化问题,以确定它是否即将进行模式设置 - 然后在需要时拉入 MST 拓扑状态,同时将任何相关的 CRTC 添加到 drm_dp_mst_topology_state.pending_crtc_mask

实现 MST 的驱动程序必须从任何能够驱动 MST 接收器的物理 DP drm_connectordrm_connector_helper_funcs.atomic_check 钩子中调用此函数。

返回

成功时返回 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

要使用的管理器

描述

尝试等待 MST 集线器完成其有效负载表的更新,方法是轮询 ACT 处理位最多 3 秒(是的,有些集线器确实需要那么长时间)。

返回

如果及时处理了 ACT,则返回 0,如果失败,则返回负错误代码。

int drm_dp_calc_pbn_mode(int clock, int bpp)

计算模式的 PBN。

参数

int clock

点时钟

int bpp

以 .4 二进制定点表示的 bpp

描述

这使用规范中的公式来计算模式的 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

父端口

描述

如果 portparent 的下游,则该函数返回 true。如果 parentNULL(表示根端口),则如果 portmgr 的拓扑中,则该函数返回 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

返回带宽受限的端口

描述

检查给定的 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

  • 如果新状态因带宽限制而无效,则为 -ENOSPC

    failing_port 设置为

    • 带宽限制检查失败的非根端口,且 **failing_port** 的所有下游端口都通过了带宽限制检查。 返回的端口指针至少在它的一个下游有效负载存在之前有效。

    • 如果带宽限制检查在根端口失败,且根端口的所有下游端口都通过了带宽限制检查,则为 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 管理器没有拓扑状态,则为 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 管理器没有拓扑状态,则为 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 辅助通道

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 树的叶子节点,附加了显示器。

描述

根据情况,可以通过端点 AUX、直接上游的 AUX 或连接器的物理 AUX 启用 DSC。

这既是读取 DSC_CAPABILITY 的正确 AUX,也是写入 DSC_ENABLED 的正确 AUX。

此操作可能很耗时(最多 4 次 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)。 持有拓扑引用意味着,只要用户持有拓扑引用,就会持有对 **mstb** 的 malloc 引用。

应注意确保用户至少有一个对 **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_kref 来释放对 **mstb** 的拓扑引用。

另请参见: 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 类型 1 显示屏。

有 3 种 MIPI DBI 实现类型

  1. 摩托罗拉 6800 型并行总线

  2. 英特尔 8080 型并行总线

  3. 具有 3 个选项的 SPI 类型

    1. 9 位,其中数据/命令信号作为第九位

    2. 与上述相同,只是它以 16 位发送

    3. 8 位,其中数据/命令信号作为单独的 D/CX 引脚

目前,mipi_dbi 仅支持类型 C 选项 1 和 3,使用 mipi_dbi_spi_init()

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

mode

固定显示模式

pixel_format

原生像素格式 (DRM_FORMAT_*)

tx_buf

用于传输的缓冲区(复制剪辑矩形区域)

rotation

初始旋转,以逆时针方向表示的度数

left_offset
显示屏相对于

控制器的驱动程序阵列的水平偏移量

top_offset
显示屏相对于

控制器的驱动程序阵列的水平偏移量

背光

背光设备(可选)的垂直偏移量

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() 进行获取/读取。

返回

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

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 读取命令发送到控制器。

返回

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

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

缓冲区长度

返回

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

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 位值的高位/低位

struct drm_format_conv_state *fmtcnv_state

格式转换状态

返回

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

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

旧的平面状态

描述

此函数处理帧缓冲区的刷新和垂直同步事件。驱动程序可以使用此函数作为其 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,否则返回负的错误代码。

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_connectordrm_simple_display_pipe,该连接器具有一个固定的 drm_display_mode,该模式根据 rotation 进行旋转。此模式用于设置模式配置的最小/最大宽度/高度属性。

如果您需要原生 RGB565 和模拟的 XRGB8888 格式,请使用 mipi_dbi_dev_init()

注意

某些辅助函数期望 RGB565 作为默认格式,并且传输缓冲区的大小适合该格式。

返回

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

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_connectordrm_simple_display_pipe,该连接器具有一个固定的 drm_display_mode,该模式根据 rotation 进行旋转。此模式用于设置模式配置的最小/最大宽度/高度属性。 此外,还分配了 mipi_dbi.tx_buf

支持的格式:原生 RGB565 和模拟的 XRGB8888。

返回

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

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 位,则缓冲区将作为 9 个 8 位字发送,必要时使用 MIPI DCS 空操作命令进行填充。

返回

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

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 总线。

返回

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

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)

有效负载长度

有效负载中的字节数

有效负载

指向包含有效负载的缓冲区的指针(如果有)

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 外围芯片类型

通道

分配给外围设备的虚拟通道

通道

活动数据通道的数量

格式

视频模式的像素格式

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

mipi_dsi_dcs_write_seq (dsi, cmd, seq...)

传输带有有效负载的 DCS 命令

参数

dsi

DSI 外围设备

cmd

命令

seq...

包含要传输的数据的缓冲区

描述

此宏将为您打印错误,并在发生错误时从调用函数返回(是的,这并不直观)。

由于返回行为不直观,此宏已被弃用。请使用 mipi_dsi_dcs_write_seq_multi() 替换对此宏的调用。

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);
};

成员

驱动程序

设备驱动模型驱动程序

probe

设备绑定的回调函数

remove

设备解绑的回调函数

shutdown

在关机时调用以使设备静止

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 算法在设备上启用或禁用显示流压缩。

返回

成功返回 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

有效负载缓冲区的大小

描述

此函数将根据有效负载长度自动选择正确的数据类型。

返回

成功传输的字节数,或者失败时的负错误代码。

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

有效负载缓冲区的大小

描述

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() 带累积错误

参数

struct mipi_dsi_multi_context *ctx

用于多个 DSI 事务的上下文

const void *payload

包含有效负载的缓冲区

size_t size

有效负载缓冲区的大小

描述

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

接收缓冲区的大小

描述

此函数将根据传入的参数数量自动选择正确的数据类型。

返回

成功读取的字节数,或者失败时的负错误代码。

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

传输缓冲区的大小

描述

此函数将根据命令有效负载长度自动选择正确的数据类型。

返回

成功传输的字节数,或者失败时的负错误代码。

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() 带累积错误

参数

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

包含命令有效载荷的缓冲区

size_t len

命令有效载荷长度

描述

此函数将根据命令有效负载长度自动选择正确的数据类型。

返回

成功传输的字节数,或者失败时的负错误代码。

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_off(struct mipi_dsi_device *dsi)

关闭显示模块 TE 信号线上的撕裂效应输出信号

参数

struct mipi_dsi_device *dsi

DSI 外围设备

返回

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

int mipi_dsi_dcs_set_tear_on(struct mipi_dsi_device *dsi, enum mipi_dsi_dcs_tear_mode mode)

打开显示模块 TE 信号线上的撕裂效应输出信号。

参数

struct mipi_dsi_device *dsi

DSI 外围设备

enum mipi_dsi_dcs_tear_mode mode

撕裂效应输出线模式

描述

此函数已弃用。请改用 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)

设置用作显示模块撕裂效果输出信号触发的扫描线。

参数

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 算法在设备上启用或禁用显示流压缩。

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

撕裂效应输出线模式

描述

类似于 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_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)

设置用作显示模块撕裂效果输出信号触发的扫描线。

参数

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,以便现有的显示接口能够在使用这些接口的最大可用链路容量的情况下支持更高帧率的高分辨率。

这些函数包含一些通用逻辑和助手,用于处理显示端口/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

如果启用了 simple 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 模式的复用字大小(以比特为单位)

slice_chunk_size

切片复用中使用的“块”的最大大小(以字节为单位)。

rc_bits

速率控制缓冲区大小(以比特为单位)

dsc_version_minor

DSC 次版本

dsc_version_major

DSC 主版本

native_422

如果支持原生 4:2:2,则为 True,否则为 False

native_420

如果支持原生 4:2:0,则为 True,否则为 False。

second_line_bpg_offset

原生 4:2:0 的切片第二行的额外比特/组

nsl_bpg_offset

对于不在切片第二行中的每个组,取消分配的比特数

second_line_offset_adj

原生 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 = 不使用原生 4:2:2,1 = 使用原生 4:2:2。PPS88[1] - 0 = 不使用原生 4:2:0,1 = 使用原生 4:2:0。PPS88[7:2] - 保留 6 位

second_line_bpg_offset

PPS89[4:0] - 原生 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] - 用作原生 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

符合 struct dp_sdp_header 类型的 DP SDP 标头格式的 PPS 标头

pps_payload

符合 DSC 规范表 4-1 中所示的 PPS 负载字段,如 struct drm_dsc_picture_parameter_set 中所示

描述

此结构表示在启用 VESA 显示流压缩之前,发送所需的图像参数集元数据的 DSC PPS 信息帧。它基于 DP 二级数据包结构,包含 drm_dp_helper.h 中定义的 SDP 头部 struct dp_sdp_headerstruct 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,接收器设备期望跨越 1 个以上字节的字段的 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()

它还支持使用工作项轮询连接器,以及在驱动程序无法或不能跟踪每个连接器的热插拔中断时,进行通用的热插拔中断处理。

这个辅助库可以独立于模式设置辅助库使用。驱动程序也可以覆盖不同的部分,例如使用它们自己的热插拔处理代码来避免探测无关的输出。

探测辅助函数与其他显示辅助库共享函数表结构。有关详细信息,请参见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 列表中,然后进行筛选(基于有效性和 **maxX**、**maxY** 参数)并放入正常的模式列表中。

旨在用作 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. 模式列表中任何非过时的模式都会进行验证

  5. 任何状态不是 OK 的模式都会从连接器的模式列表中删除,并附带一条调试消息,指示模式被拒绝的原因(参见 drm_mode_prune_invalid())。

返回

在 **connector** 上找到的模式数。

void drm_kms_helper_hotplug_event(struct drm_device *dev)

触发 KMS 热插拔事件

参数

struct drm_device *dev

连接器状态发生更改的 drm_device

描述

此函数为用户空间触发 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

int 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()

返回

成功时返回 0,否则返回负的错误代码。

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() 读取 EDID (这要求设置 connector->ddc),并使用 EDID 更新连接器。

如果驱动程序不需要任何特殊处理,则可以将其用作“默认”连接器助手 .get_modes() 钩子。这设置了关于 EDID 读取和连接器更新的自定义 .get_modes() 钩子应该如何操作的示例。

返回

模式数量。

int drm_connector_helper_tv_get_modes(struct drm_connector *connector)

填充 TV 连接器可用的模式

参数

struct drm_connector *connector

连接器

描述

根据支持的 TV 模式以及内核命令行表达的默认模式,填充 TV 连接器可用的模式。

如果驱动程序不需要任何特殊处理,则可以将其用作默认 TV 连接器助手 .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]

一个 4 字节的缓冲区,用于存储 3 个字母的供应商字符串和一个 '0' 终止符

drm_edid_encode_panel_id

drm_edid_encode_panel_id (vend_chr_0, vend_chr_1, vend_chr_2, product_id)

编码一个用于匹配 drm_edid_get_panel_id() 的 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]

一个 4 字节的缓冲区,用于存储 3 个字母的供应商字符串和一个 '0' 终止符

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 适配器

描述

探测给定的 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() 而不是滥用此函数。

可以使用 debugfs override_edid 或固件 EDID (drm_edid_load_firmware() 和 drm.edid_firmware 参数) 来覆盖 EDID,优先级顺序如此。拥有其中任何一个都会绕过实际的 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。

可以使用 debugfs override_edid 或固件 EDID (drm_edid_load_firmware() 和 drm.edid_firmware 参数) 来覆盖 EDID,优先级顺序如此。拥有其中任何一个都会绕过实际的 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。

可以使用 debugfs override_edid 或固件 EDID (drm_edid_load_firmware() 和 drm.edid_firmware 参数) 来覆盖 EDID,优先级顺序如此。拥有其中任何一个都会绕过实际的 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 适配器

描述

对于使用一组输出的双 GPU 笔记本电脑,此函数是 drm_get_edid() 的包装器。该包装器添加了必要的 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 适配器

描述

对于使用一组输出的双 GPU 笔记本电脑,此函数是 drm_edid_read_ddc() 的包装器。该包装器添加了必要的 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 接收器音频-视频同步延迟

参数

struct drm_connector *connector

与 HDMI/DP 接收器关联的连接器

const struct drm_display_mode *mode

显示模式

返回

HDMI/DP 接收器的音频-视频同步延迟(以毫秒为单位),如果接收器不支持音频或视频,则为 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 数据

描述

将指定的模式添加到连接器的模式列表中。还在 **connector** 中填充 drm_display_info 结构和 ELD,其中包含可以从 edid 导出的任何信息。

此函数已弃用。请改用 drm_edid_connector_add_modes()

返回

添加的模式数量,如果没有找到则为 0。

int drm_add_modes_noedid(struct drm_connector *connector, int hdisplay, int vdisplay)

为没有 EDID 的连接器添加模式

参数

struct drm_connector *connector

我们正在探测的连接器

int hdisplay

水平显示限制

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)

将 SAD 从 ELD 获取到 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)

将 SAD 从 struct cea_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 接收器交换数据。 用于访问 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

连接器

描述

通过 SCDC 读取加扰器状态,并检查加扰状态。

返回

如果启用了加扰,则为 True,否则为 False。

bool drm_scdc_set_scrambling(struct drm_connector *connector, bool enable)

启用加扰

参数

struct drm_connector *connector

连接器

bool enable

布尔值,指示是否启用/禁用加扰

描述

通过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

连接器

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接收端元数据

定义:

struct hdr_sink_metadata {
    __u32 metadata_type;
    union {
        struct hdr_static_metadata hdmi_type1;
    };
};

成员

metadata_type

Static_Metadata_Descriptor_ID。

{unnamed_union}

匿名

hdmi_type1

HDR 元数据信息帧。

描述

从接收端的 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 版本

描述

打包要通过 DisplayPort 发送的 HDMI 音频信息帧。此函数填充要用于 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 节的要求计算校验和。

返回打包到二进制缓冲区中的字节数,如果失败,则返回负错误代码。

int hdmi_infoframe_check(union hdmi_infoframe *frame)

检查 HDMI 信息帧

参数

union hdmi_infoframe *frame

HDMI 信息帧

描述

验证信息帧是否一致,并根据其他字段更新派生字段(例如,长度)。

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

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** 的中心静止。

正的 **dw** 和 **dh** 会增加大小,负值会减小大小。

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** 的坐标除以 **horz** 和 **vert**。

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 定点形式的矩形转换为整数形式。

参数

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);

您将始终获得原始矩形。

翻转工作辅助参考

实用程序,用于在翻转/垂直消隐后从工作队列上下文中排队运行工作。通常,这可以用于延迟取消引用帧缓冲区、光标 bo 等,直到垂直消隐之后。这些 API 都是线程安全的。此外,可以在原子上下文中调用 drm_flip_work_commit()

struct drm_flip_work

翻转工作队列

定义:

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

为每个已提交的项调用的回调函数

worker

调用 func 的工作线程

queued

已排队的任务

commited

已提交的任务

lock

用于访问已排队和已提交列表的锁

void drm_flip_work_queue(struct drm_flip_work *work, void *val)

排队工作

参数

struct drm_flip_work *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

翻转工作

struct workqueue_struct *wq

在其上运行已排队工作的工作队列

描述

触发之前由 drm_flip_work_queue() 排队的工作在工作队列上运行。典型的用法是在任何时候(从垂直消隐 irq 和/或之前)排队工作(通过 drm_flip_work_queue()),然后在垂直消隐 irq 中提交已排队的工作。

void drm_flip_work_init(struct drm_flip_work *work, const char *name, drm_flip_func_t func)

初始化翻转工作

参数

struct drm_flip_work *work

要初始化的翻转工作

const char *name

调试名称

drm_flip_func_t func

回调工作函数

描述

初始化/分配翻转工作的资源

void drm_flip_work_cleanup(struct drm_flip_work *work)

清理翻转工作

参数

struct drm_flip_work *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)

填写帧缓冲元数据

参数

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 的回调

描述

使用默认的助手提供的原语平面和没有光标平面来初始化 CRTC 对象。

请注意,我们对可能并非所有硬件都适用的硬件限制做出了一些假设

  1. 主平面无法重新定位。

  2. 主平面无法缩放。

  3. 主平面必须覆盖整个 CRTC。

  4. 不支持子像素定位。

  5. 如果启用了 CRTC,则主平面必须始终处于启用状态。

这纯粹是旧驱动程序的向后兼容性助手。驱动程序应该改为实现自己的主平面。原子驱动程序必须这样做。具有上述硬件限制的驱动程序可以考虑使用 struct drm_simple_display_pipe,它将上述限制封装到一个不错的接口中。

返回

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

int drm_mode_config_helper_suspend(struct drm_device *dev)

模式设置挂起助手

参数

struct drm_device *dev

DRM 设备

描述

此辅助函数负责挂起模式设置端。如果已初始化,它会禁用输出轮询,如果使用了 fbdev,则会挂起 fbdev,最后调用 drm_atomic_helper_suspend()。如果挂起失败,则会重新启用 fbdev 和轮询。

另请参阅:drm_kms_helper_poll_disable() 和 drm_client_dev_suspend()。

返回

成功返回 0,错误返回负的错误代码。

int drm_mode_config_helper_resume(struct drm_device *dev)

模式设置恢复助手

参数

struct drm_device *dev

DRM 设备

描述

此辅助函数负责恢复模式设置端。它会调用 drm_atomic_helper_resume(),如果使用了 fbdev,则会恢复 fbdev,如果已初始化,则会启用输出轮询。

另请参阅:drm_client_dev_resume() 和 drm_kms_helper_poll_enable()

返回

成功返回 0,错误返回负的错误代码。

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 不能为空。

此函数已弃用,不应在新驱动程序中使用。请改用 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 总线。

如果成功,则返回指向 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

模式设置锁定上下文

描述

此辅助函数验证给定的参数并更新主平面。

此函数仅适用于非原子模式设置。请勿在新驱动程序中使用它。

返回

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

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 辅助函数所需的旧语义的函数。

强烈建议驱动程序转换为原子辅助函数(首先转换为平面辅助函数)。 新的驱动程序不得使用这些函数,而是需要实现原子接口,并可能为此使用原子辅助函数。

这些传统的模式设置辅助函数使用与所有其他模式设置辅助函数相同的功能表结构。 请参阅结构 drm_crtc_helper_funcsstruct drm_encoder_helper_funcs 和结构 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 的情况。

返回

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

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 处于一致的低功耗状态。需要模式设置锁。

注意

这应该仅由非原子旧版驱动程序使用。对于原子版本,请查看 drm_atomic_helper_shutdown()

返回

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

隐私屏幕类

此类允许非 KMS 驱动程序(例如,来自 drivers/platform/x86 的驱动程序)注册一个隐私屏幕设备,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

互斥锁保护此结构中的所有字段。

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 list_headstruct drm_privacy_screen_lookup 的一部分,它被添加到隐私屏幕核心拥有的列表中。因此,传入的struct drm_privacy_screen_lookup 必须在通过调用drm_privacy_screen_lookup_remove() 从查找列表中删除之前,不得被释放。

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

要获取隐私屏幕提供程序的(视频)连接器名称

描述

为由 **dev** 和 **con_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 状态

参数

struct drm_privacy_screen *priv

要设置 sw 状态的隐私屏幕

enum drm_privacy_screen_status sw_state

要设置的新 sw 状态值

描述

设置隐私屏幕的 sw 状态。如果隐私屏幕未处于锁定的 hw 状态,则隐私屏幕的实际状态和 hw 状态将立即更新为新值。如果隐私屏幕处于锁定的 hw 状态,则新的 sw 状态将被记住,作为隐私屏幕解锁时要将隐私屏幕置于的状态。

返回

成功返回 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 状态的地址

enum drm_privacy_screen_status *hw_state_ret

存储隐私屏幕当前 hw 状态的地址

描述

获取隐私屏幕的当前状态,包括 sw 状态和 hw 状态。

int drm_privacy_screen_register_notifier(struct drm_privacy_screen *priv, struct notifier_block *nb)

注册一个通知器

参数

struct drm_privacy_screen *priv

要注册通知器的隐私屏幕

struct notifier_block *nb

要注册的通知器的通知块

描述

使用隐私屏幕注册一个通知器,以便在隐私屏幕类外部对隐私屏幕状态进行更改时收到通知。例如,状态可能会因热键按下而由硬件本身更改。

调用通知器时不会持有任何锁。可以使用 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

要注册的通知器的通知块

描述

取消注册使用 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()