内核客户端

此库为在内核中运行的客户端提供支持,例如 fbdev 和 bootsplash。

支持提供基于 GEM 的哑缓冲区和虚拟地址的 GEM 驱动程序。

struct drm_client_funcs

DRM 客户端回调

定义:

struct drm_client_funcs {
    struct module *owner;
    void (*unregister)(struct drm_client_dev *client);
    int (*restore)(struct drm_client_dev *client);
    int (*hotplug)(struct drm_client_dev *client);
    int (*suspend)(struct drm_client_dev *client, bool holds_console_lock);
    int (*resume)(struct drm_client_dev *client, bool holds_console_lock);
};

成员

owner

模块所有者

unregister

drm_device 被注销时调用。 客户端应使用 drm_client_release() 释放其资源来响应。

此回调是可选的。

restore

在 drm_lastclose() 上调用。 列表中第一个返回零的客户端有权恢复,不再调用更多客户端。 在调用 unregister 后,不会调用此回调。

请注意,核心不保证排除并发的 drm_open()。 客户端需要自己确保这一点,例如通过使用 drm_master_internal_acquire() 和 drm_master_internal_release()。

此回调是可选的。

hotplug

drm_kms_helper_hotplug_event() 上调用。 在调用 unregister 后,不会调用此回调。

此回调是可选的。

suspend

暂停设备时调用。

此回调是可选的。

FIXME:一些调用者在调用此函数时持有控制台锁

功能。 这会干扰 fbdev 模拟,fbdev 模拟也试图获取该锁。 将控制台锁推入回调中,并删除“holds_console_lock”。

resume

从暂停状态恢复设备时调用。

此回调是可选的。

FIXME:一些调用者在调用此函数时持有控制台锁

功能。 这会干扰 fbdev 模拟,fbdev 模拟也试图获取该锁。 将控制台锁推入回调中,并删除“holds_console_lock”。

struct drm_client_dev

DRM 客户端实例

定义:

struct drm_client_dev {
    struct drm_device *dev;
    const char *name;
    struct list_head list;
    const struct drm_client_funcs *funcs;
    struct drm_file *file;
    struct mutex modeset_mutex;
    struct drm_mode_set *modesets;
    bool suspended;
    bool hotplug_pending;
    bool hotplug_failed;
};

成员

dev

DRM 设备

name

客户端名称。

list

DRM 设备的所有客户端的列表,链接到 drm_device.clientlist 中。 受 drm_device.clientlist_mutex 保护。

funcs

DRM 客户端函数(可选)

file

DRM 文件

modeset_mutex

保护 modesets

modesets

CRTC 配置

suspended

客户端已被暂停。

hotplug_pending

客户端暂停时已收到热插拔事件。 恢复后重试。

hotplug_failed

如果热插拔之前失败,则由客户端热插拔助手设置。 通常不会再次尝试。

struct drm_client_buffer

DRM 客户端缓冲区

定义:

struct drm_client_buffer {
    struct drm_client_dev *client;
    u32 pitch;
    struct drm_gem_object *gem;
    struct iosys_map map;
    struct drm_framebuffer *fb;
};

成员

client

DRM 客户端

pitch

缓冲区 pitch

gem

支持此缓冲区的 GEM 对象

FIXME:此处不需要依赖 GEM,我们可以将驱动程序句柄转换为 dma-buf,并使用后端无关的 dma-buf vmap 支持。 这将需要重新设计 handle2fd prime ioctl,以从驱动程序后端挂钩中拉出 fd_install 步骤,以使最终步骤对于内部用户是可选的。

map

缓冲区的虚拟地址

fb

DRM 帧缓冲区

drm_client_for_each_modeset

drm_client_for_each_modeset (modeset, client)

迭代客户端模式集

参数

modeset

drm_mode_set 循环光标

client

DRM 客户端

drm_client_for_each_connector_iter

drm_client_for_each_connector_iter (connector, iter)

connector_list 迭代器宏

参数

connector

struct drm_connector 用作光标的指针

iter

struct drm_connector_list_iter

描述

这会迭代可用于内部客户端的连接器(不包括 writeback 连接器)。

有关更多信息,请参见 drm_for_each_connector_iter()

int drm_client_init(struct drm_device *dev, struct drm_client_dev *client, const char *name, const struct drm_client_funcs *funcs)

初始化 DRM 客户端

参数

struct drm_device *dev

DRM 设备

struct drm_client_dev *client

DRM 客户端

const char *name

客户端名称

const struct drm_client_funcs *funcs

DRM 客户端函数(可选)

描述

这会初始化客户端并打开一个 drm_file。 使用 drm_client_register() 完成该过程。 调用方需要在调用此函数之前对 dev 持有引用。 当 drm_device 被注销时,客户端将被释放。 请参见 drm_client_release()

返回

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

void drm_client_register(struct drm_client_dev *client)

注册客户端

参数

struct drm_client_dev *client

DRM 客户端

描述

将客户端添加到 drm_device 客户端列表以激活其回调。 必须通过调用 drm_client_init() 初始化 client。 在 drm_client_register() 之后,不再允许直接调用 drm_client_release()(在注销回调之外),而是将在驱动程序卸载时自动进行清理。

注册客户端会生成一个热插拔事件,该事件允许客户端从预先存在的输出中设置其显示。 客户端必须已初始化其状态才能成功处理热插拔事件。

void drm_client_release(struct drm_client_dev *client)

释放 DRM 客户端资源

参数

struct drm_client_dev *client

DRM 客户端

描述

通过关闭由 drm_client_init() 打开的 drm_file 来释放资源。 如果 _未_ 设置 drm_client_funcs.unregister 回调,则会自动调用它。

此函数应仅从注销回调中调用。 例外是 fbdev,如果用户空间有打开的文件描述符,则无法释放缓冲区。

注意

客户端无法自行启动释放。 这样做是为了简化代码。 驱动程序必须在客户端可以卸载之前卸载。

int drm_client_buffer_vmap_local(struct drm_client_buffer *buffer, struct iosys_map *map_copy)

将 DRM 客户端缓冲区映射到地址空间中

参数

struct drm_client_buffer *buffer

DRM 客户端缓冲区

struct iosys_map *map_copy

返回映射内存的地址

描述

此函数将客户端缓冲区映射到内核地址空间中。 如果该缓冲区已经映射,则它将返回现有映射的地址。

客户端缓冲区映射没有引用计数。 每次调用 drm_client_buffer_vmap_local() 之后,都应紧跟调用 drm_client_buffer_vunmap_local()。 有关长期映射,请参见 drm_client_buffer_vmap()

返回的地址是内部值的副本。 与其他 vmap 接口相反,客户端的 vunmap 函数不需要它。 因此,您可以在 blit 和绘制操作期间随意修改它。

返回

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

void drm_client_buffer_vunmap_local(struct drm_client_buffer *buffer)

取消映射 DRM 客户端缓冲区

参数

struct drm_client_buffer *buffer

DRM 客户端缓冲区

描述

此函数删除使用 drm_client_buffer_vunmap_local() 建立的客户端缓冲区的内存映射。 只有自行管理其缓冲区映射的客户端才需要调用此函数。

int drm_client_buffer_vmap(struct drm_client_buffer *buffer, struct iosys_map *map_copy)

将 DRM 客户端缓冲区映射到地址空间中

参数

struct drm_client_buffer *buffer

DRM 客户端缓冲区

struct iosys_map *map_copy

返回映射内存的地址

描述

此函数将客户端缓冲区映射到内核地址空间中。 如果该缓冲区已经映射,则它将返回现有映射的地址。

客户端缓冲区映射没有引用计数。 每次调用 drm_client_buffer_vmap() 之后,都应紧跟调用 drm_client_buffer_vunmap();或者应在其整个生命周期中映射客户端缓冲区。

返回的地址是内部值的副本。 与其他 vmap 接口相反,客户端的 vunmap 函数不需要它。 因此,您可以在 blit 和绘制操作期间随意修改它。

返回

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

void drm_client_buffer_vunmap(struct drm_client_buffer *buffer)

取消映射 DRM 客户端缓冲区

参数

struct drm_client_buffer *buffer

DRM 客户端缓冲区

描述

此函数删除客户端缓冲区的内存映射。 只有自行管理其缓冲区映射的客户端才需要调用此函数。

struct drm_client_buffer *drm_client_framebuffer_create(struct drm_client_dev *client, u32 width, u32 height, u32 format)

创建客户端帧缓冲区

参数

struct drm_client_dev *client

DRM 客户端

u32 width

帧缓冲区宽度

u32 height

帧缓冲区高度

u32 format

缓冲区格式

描述

此函数创建一个 drm_client_buffer,它由哑缓冲区支持的 drm_framebuffer 组成。 调用 drm_client_framebuffer_delete() 以释放缓冲区。

返回

指向客户端缓冲区的指针,如果失败,则指向错误指针。

void drm_client_framebuffer_delete(struct drm_client_buffer *buffer)

删除客户端帧缓冲区

参数

struct drm_client_buffer *buffer

DRM 客户端缓冲区(可以为 NULL)

int drm_client_framebuffer_flush(struct drm_client_buffer *buffer, struct drm_rect *rect)

手动刷新客户端帧缓冲区

参数

struct drm_client_buffer *buffer

DRM 客户端缓冲区(可以为 NULL)

struct drm_rect *rect

损坏矩形(如果为 NULL,则刷新所有)

描述

这会调用 drm_framebuffer_funcs->dirty(如果存在),为需要它的驱动程序刷新缓冲区更改。

返回

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

int drm_client_modeset_probe(struct drm_client_dev *client, unsigned int width, unsigned int height)

探测显示器

参数

struct drm_client_dev *client

DRM 客户端

unsigned int width

最大显示模式宽度(可选)

unsigned int height

最大显示模式高度(可选)

描述

此函数为启用的连接器设置显示管道,并将配置存储在客户端的 modeset 数组中。

返回

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

bool drm_client_rotation(struct drm_mode_set *modeset, unsigned int *rotation)

检查初始旋转值

参数

struct drm_mode_set *modeset

DRM modeset

unsigned int *rotation

返回的旋转值

描述

此函数检查 **modeset** 中的主平面是否可以进行硬件旋转,以匹配其连接器上所需的旋转。

注意

目前仅支持 0 度和 180 度。

返回

如果平面可以进行旋转,则为 True;否则为 false。

int drm_client_modeset_check(struct drm_client_dev *client)

检查 modeset 配置

参数

struct drm_client_dev *client

DRM 客户端

描述

检查 modeset 配置。

返回

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

int drm_client_modeset_commit_locked(struct drm_client_dev *client)

强制提交 CRTC 配置

参数

struct drm_client_dev *client

DRM 客户端

描述

将 modeset 配置提交到 crtc,而不检查是否存在 DRM 主设备。 假设调用者已经持有通过 drm_master_internal_acquire() 获取的内部 DRM 主设备引用。

返回

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

int drm_client_modeset_commit(struct drm_client_dev *client)

提交 CRTC 配置

参数

struct drm_client_dev *client

DRM 客户端

描述

将 modeset 配置提交到 crtc。

返回

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

int drm_client_modeset_dpms(struct drm_client_dev *client, int mode)

设置 DPMS 模式

参数

struct drm_client_dev *client

DRM 客户端

int mode

DPMS 模式

注意

对于原子驱动程序,**mode** 简化为开/关。

返回

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

void drm_client_dev_unregister(struct drm_device *dev)

注销客户端

参数

struct drm_device *dev

DRM 设备

描述

此函数通过调用每个客户端的 drm_client_funcs.unregister 回调来释放所有客户端。回调函数负责释放所有资源,包括客户端本身。

辅助函数 drm_dev_unregister() 调用此函数。 使用它的驱动程序无需自行调用此函数。

void drm_client_dev_hotplug(struct drm_device *dev)

向客户端发送热插拔事件

参数

struct drm_device *dev

DRM 设备

描述

此函数调用附加客户端上的 drm_client_funcs.hotplug 回调。

drm_kms_helper_hotplug_event() 调用此函数,因此使用它的驱动程序无需自行调用此函数。