AMDgpu 显示管理器¶
AMDgpu 显示管理器,amdgpu_dm(或更简单的 dm)位于 DRM 和 DC 之间。它充当联络员,将 DRM 请求转换为 DC 请求,并将 DC 响应转换为 DRM 响应。
根控制结构是 struct amdgpu_display_manager
。
-
struct dm_compressor_info¶
帧缓冲区压缩使用的缓冲区信息
定义:
struct dm_compressor_info {
void *cpu_addr;
struct amdgpu_bo *bo_ptr;
uint64_t gpu_addr;
};
成员
cpu_addr
MMIO CPU 地址
bo_ptr
指向缓冲区对象的指针
gpu_addr
MMIO GPU 地址
-
struct dmub_hpd_work¶
在低优先级出站箱 IRQ 中处理耗时的工作
定义:
struct dmub_hpd_work {
struct work_struct handle_hpd_work;
struct dmub_notification *dmub_notify;
struct amdgpu_device *adev;
};
成员
handle_hpd_work
要在单独的线程中执行以处理 hpd_low_irq 的工作
dmub_notify
回调函数的通知
adev
amdgpu_device 指针
-
struct vblank_control_work¶
垂直消隐控制的工作数据
定义:
struct vblank_control_work {
struct work_struct work;
struct amdgpu_display_manager *dm;
struct amdgpu_crtc *acrtc;
struct dc_stream_state *stream;
bool enable;
};
成员
work
工作事件的内核工作数据
dm
amdgpu 显示管理器设备
acrtc
发生事件的 amdgpu CRTC 实例
stream
发生事件的 DC 流
enable
如果启用垂直消隐,则为 true
-
struct idle_workqueue¶
空闲时定期操作的工作数据
定义:
struct idle_workqueue {
struct work_struct work;
struct amdgpu_display_manager *dm;
bool enable;
bool running;
};
成员
work
工作事件的内核工作数据
dm
amdgpu 显示管理器设备
enable
如果启用空闲工作程序,则为 true
running
如果空闲工作程序正在运行,则为 true
-
struct amdgpu_dm_luminance_data¶
自定义亮度数据
定义:
struct amdgpu_dm_luminance_data {
u8 luminance;
u8 input_signal;
};
成员
luminance
以百分比表示的亮度
input_signal
范围 0-255 中的输入信号
-
struct amdgpu_dm_backlight_caps¶
关于背光的信息
定义:
struct amdgpu_dm_backlight_caps {
union dpcd_sink_ext_caps *ext_caps;
u32 aux_min_input_signal;
u32 aux_max_input_signal;
int min_input_signal;
int max_input_signal;
bool caps_valid;
bool aux_support;
u8 ac_level;
u8 dc_level;
u8 data_points;
struct amdgpu_dm_luminance_data luminance_data[MAX_LUMINANCE_DATA_POINTS];
};
成员
ext_caps
保留具有有关 HDR 显示器支持的所有信息的数据结构。
aux_min_input_signal
显示器支持的最小亮度值
aux_max_input_signal
显示器支持的最大亮度值(以尼特为单位)。
min_input_signal
范围 0-255 中的最小可能输入。
max_input_signal
范围 0-255 中的最大可能输入。
caps_valid
如果这些值来自 ACPI 接口,则为 true。
aux_support
描述显示器是否支持 AUX 背光。
ac_level
如果引导至交流电源,则为默认亮度
dc_level
如果引导至直流电源,则为默认亮度
data_points
自定义亮度数据点的数量
luminance_data
自定义亮度数据
描述
描述 ACPI 或 eDP AUX 的背光支持。
-
struct dal_allocation¶
跟踪为 SMU 通信映射的 FB 内存
定义:
struct dal_allocation {
struct list_head list;
struct amdgpu_bo *bo;
void *cpu_ptr;
u64 gpu_addr;
};
成员
list
dal 分配列表
bo
GPU 缓冲区对象
cpu_ptr
GPU 缓冲区对象的 CPU 虚拟地址
gpu_addr
GPU 缓冲区对象的 GPU 虚拟地址
-
struct hpd_rx_irq_offload_work_queue¶
工作队列以处理 hpd_rx_irq 卸载工作
定义:
struct hpd_rx_irq_offload_work_queue {
struct workqueue_struct *wq;
spinlock_t offload_lock;
bool is_handling_link_loss;
bool is_handling_mst_msg_rdy_event;
struct amdgpu_dm_connector *aconnector;
};
成员
wq
将卸载工作排队的工作队列结构。
offload_lock
用于保护卸载工作队列的字段。
is_handling_link_loss
用于防止在我们处理链路丢失时插入链路丢失事件
is_handling_mst_msg_rdy_event
用于防止在我们已经处理 mst 消息就绪事件时插入 mst 消息就绪事件
aconnector
此工作队列所连接到的 aconnector
-
struct hpd_rx_irq_offload_work¶
hpd_rx_irq 卸载工作结构
定义:
struct hpd_rx_irq_offload_work {
struct work_struct work;
union hpd_irq_data data;
struct hpd_rx_irq_offload_work_queue *offload_wq;
struct amdgpu_device *adev;
};
成员
work
卸载工作
data
在处理卸载工作时使用的参考 irq 数据
offload_wq
此工作排队到的卸载工作队列
adev
amdgpu_device 指针
-
struct amdgpu_display_manager¶
中央 amdgpu 显示管理器设备
定义:
struct amdgpu_display_manager {
struct dc *dc;
struct dmub_srv *dmub_srv;
struct dmub_notification *dmub_notify;
dmub_notify_interrupt_callback_t dmub_callback[AMDGPU_DMUB_NOTIFICATION_MAX];
bool dmub_thread_offload[AMDGPU_DMUB_NOTIFICATION_MAX];
struct dmub_srv_fb_info *dmub_fb_info;
const struct firmware *dmub_fw;
struct amdgpu_bo *dmub_bo;
u64 dmub_bo_gpu_addr;
void *dmub_bo_cpu_addr;
uint32_t dmcub_fw_version;
struct cgs_device *cgs_device;
struct amdgpu_device *adev;
struct drm_device *ddev;
u16 display_indexes_num;
struct drm_private_obj atomic_obj;
struct mutex dc_lock;
struct mutex audio_lock;
struct drm_audio_component *audio_component;
bool audio_registered;
struct list_head irq_handler_list_low_tab[DAL_IRQ_SOURCES_NUMBER];
struct list_head irq_handler_list_high_tab[DAL_IRQ_SOURCES_NUMBER];
struct common_irq_params pflip_params[DC_IRQ_SOURCE_PFLIP_LAST - DC_IRQ_SOURCE_PFLIP_FIRST + 1];
struct common_irq_params vblank_params[DC_IRQ_SOURCE_VBLANK6 - DC_IRQ_SOURCE_VBLANK1 + 1];
struct common_irq_params vline0_params[DC_IRQ_SOURCE_DC6_VLINE0 - DC_IRQ_SOURCE_DC1_VLINE0 + 1];
struct common_irq_params vupdate_params[DC_IRQ_SOURCE_VUPDATE6 - DC_IRQ_SOURCE_VUPDATE1 + 1];
struct common_irq_params dmub_trace_params[1];
struct common_irq_params dmub_outbox_params[1];
spinlock_t irq_handler_list_table_lock;
struct backlight_device *backlight_dev[AMDGPU_DM_MAX_NUM_EDP];
const struct dc_link *backlight_link[AMDGPU_DM_MAX_NUM_EDP];
uint8_t num_of_edps;
struct amdgpu_dm_backlight_caps backlight_caps[AMDGPU_DM_MAX_NUM_EDP];
struct mod_freesync *freesync_module;
struct hdcp_workqueue *hdcp_workqueue;
struct workqueue_struct *vblank_control_workqueue;
struct idle_workqueue *idle_workqueue;
struct drm_atomic_state *cached_state;
struct dc_state *cached_dc_state;
struct dm_compressor_info compressor;
const struct firmware *fw_dmcu;
uint32_t dmcu_fw_version;
const struct gpu_info_soc_bounding_box_v1_0 *soc_bounding_box;
uint32_t active_vblank_irq_count;
#if defined(CONFIG_DRM_AMD_SECURE_DISPLAY);
struct secure_display_context secure_display_ctx;
#endif;
struct hpd_rx_irq_offload_work_queue *hpd_rx_offload_wq;
struct amdgpu_encoder mst_encoders[AMDGPU_DM_MAX_CRTC];
bool force_timing_sync;
bool disable_hpd_irq;
bool dmcub_trace_event_en;
struct list_head da_list;
struct completion dmub_aux_transfer_done;
struct workqueue_struct *delayed_hpd_wq;
u32 brightness[AMDGPU_DM_MAX_NUM_EDP];
u32 actual_brightness[AMDGPU_DM_MAX_NUM_EDP];
bool aux_hpd_discon_quirk;
bool edp0_on_dp1_quirk;
struct mutex dpia_aux_lock;
struct dml2_soc_bb *bb_from_dmub;
struct amdgpu_i2c_adapter *oem_i2c;
struct fused_io_sync {
struct completion replied;
char reply_data[0x40];
} fused_io[8];
};
成员
dc
显示核心控制结构
dmub_srv
DMUB 服务,用于控制支持它的硬件上的 DMUB。在不支持它的硬件上,指向 dmub_srv 的指针将为 NULL。
dmub_notify
来自 DMUB 的通知。
dmub_callback
用于处理来自 DMUB 的通知的回调函数。
dmub_thread_offload
指示回调是否卸载的标志。
dmub_fb_info
DMUB 的帧缓冲区区域。
dmub_fw
DMUB 固件,在具有 DMUB 支持的硬件上是必需的。
dmub_bo
DMUB 的缓冲区对象。
dmub_bo_gpu_addr
DMUB 缓冲区对象的 GPU 虚拟地址。
dmub_bo_cpu_addr
DMUB 缓冲区对象的 CPU 地址。
dmcub_fw_version
DMCUB 固件版本。
cgs_device
通用图形服务设备。它提供了一个用于访问寄存器的接口。
adev
AMDGPU 基本驱动程序结构
ddev
DRM 基本驱动程序结构
display_indexes_num
支持的最大显示流数
atomic_obj
与
dm_atomic_state
结合使用,它有助于管理全局原子状态,该状态无法完全映射到现有的 DRM 资源中,例如dc_context
。dc_lock
保护对可以发出寄存器写入序列的 DC 函数的访问。
audio_lock
保护对音频实例更改的访问。
audio_component
用于将 ELD 更改通知给声音驱动程序。
audio_registered
如果音频组件已成功注册,则为 True,否则为 False。
irq_handler_list_low_tab
低优先级 IRQ 处理程序表。
它是一个 n*m 表,由 n 个 IRQ 源和每个 IRQ 源 m 个处理程序组成。低优先级 IRQ 处理程序被推迟到工作队列进行处理。因此,它们可以休眠。
请注意,处理程序的调用顺序与它们注册的顺序相同 (FIFO)。
irq_handler_list_high_tab
高优先级 IRQ 处理程序表。
它是一个 n*m 表,与
irq_handler_list_low_tab
相同。但是,此表中的处理程序不会被推迟,而是立即调用。pflip_params
页面翻转 IRQ 参数,在触发时传递给注册的处理程序。
vblank_params
垂直消隐 IRQ 参数,在触发时传递给注册的处理程序。
vline0_params
OTG 垂直中断 0 IRQ 参数,在触发时传递给注册的处理程序。
vupdate_params
垂直更新 IRQ 参数,在触发时传递给注册的处理程序。
dmub_trace_params
DMUB 跟踪事件 IRQ 参数,在触发时传递给注册的处理程序。
dmub_outbox_params
DMUB 出站箱参数
irq_handler_list_table_lock
同步对 IRQ 表的访问
backlight_dev
背光控制设备
backlight_link
要在其上控制背光的链路
num_of_edps
背光 eDP 的数量
backlight_caps
背光设备的功能
freesync_module
处理 freesync 计算的模块
hdcp_workqueue
AMDGPU 内容保护队列
vblank_control_workqueue
垂直消隐控制事件的延迟工作。
idle_workqueue
空闲事件的定期工作。
cached_state
缓存设备原子状态以进行挂起/恢复
cached_dc_state
内容流的缓存状态
compressor
帧缓冲区压缩缓冲区。请参阅
struct dm_compressor_info
fw_dmcu
对 DMCU 固件的引用
dmcu_fw_version
DMCU 固件的版本
soc_bounding_box
gpu_info FW 提供的 soc 边界框结构,如果 FW 中不可用,则为 0
active_vblank_irq_count
当前活动的垂直消隐 irq 的数量
secure_display_ctx
存储安全显示相关信息。例如,ROI 信息、用于命令 dmub 的 work_struct 等。
hpd_rx_offload_wq
用于卸载 hpd_rx_irq 工作的队列
mst_encoders
用于 DP MST 的伪编码器。
force_timing_sync
通过 debugfs 设置。设置后,指示将强制所有连接的显示器同步。
disable_hpd_irq
为 true 时,禁用驱动程序中的所有 HPD 和 HPD RX 中断处理
dmcub_trace_event_en
启用 dmcub 跟踪事件
da_list
DAL fb 内存分配列表,用于与 SMU 通信。
dmub_aux_transfer_done
用于指示 DMUB 传输何时完成的结构完成
delayed_hpd_wq
用于延迟 DMUB HPD 工作的工作队列
brightness
缓存的背光值。
actual_brightness
上次成功应用的背光值。
aux_hpd_discon_quirk
当 aux 正在进行时,hpd 断开连接的怪癖。发生在某些英特尔平台上
edp0_on_dp1_quirk
将 edp0 放在 DP1 上的平台的怪癖。
dpia_aux_lock
保护对 DPIA AUX 的访问
bb_from_dmub
在 DCN4+ 的早期初始化期间从 dmub 读取的边界框数据
oem_i2c
OEM i2c 总线
fused_io
dmub 融合 io 接口
-
struct amdgpu_hdmi_vsdb_info¶
跟踪 VSDB 信息
定义:
struct amdgpu_hdmi_vsdb_info {
unsigned int amd_vsdb_version;
bool freesync_supported;
unsigned int min_refresh_rate_hz;
unsigned int max_refresh_rate_hz;
bool replay_mode;
};
成员
amd_vsdb_version
供应商特定数据块版本,应用于确定要发送哪个供应商特定信息帧 (VSIF)。
freesync_supported
FreeSync 支持。
min_refresh_rate_hz
FreeSync 最小刷新率(以 Hz 为单位)。
max_refresh_rate_hz
FreeSync 最大刷新率(以 Hz 为单位)
replay_mode
支持重播
描述
AMDGPU 通过使用 VSDB 部分支持 HDMI 上的 FreeSync,并且此结构对于跟踪有关 FreeSync 的显示器特定信息很有用。
生命周期¶
DM(以及随之而来的 DC)在 amdgpu 基本驱动程序中注册为 IP 块。启用 CONFIG_DRM_AMD_DC 后,DM 设备 IP 块将添加到基本驱动程序的设备列表中,以便相应地进行初始化和拆除。
执行此操作的函数在 struct amd_ip_funcs
中作为挂钩提供。
-
int dm_hw_init(struct amdgpu_ip_block *ip_block)¶
初始化 DC 设备
参数
struct amdgpu_ip_block *ip_block
指向此硬件实例的 amdgpu_ip_block 的指针。
描述
初始化 struct amdgpu_display_manager
设备。这涉及调用每个 DM 组件的初始化程序,然后使用它们填充结构。
虽然该函数暗示硬件初始化,但硬件和软件都在此处初始化。将它们拆分到它们相关的 init 挂钩是一个未来的 TODO 项。
在此处初始化的一些值得注意的事情
显示核心,软件和硬件
我们需要的 DC 模块(freesync 和颜色管理)
DRM 软件状态
中断源和处理程序
垂直消隐支持
调试 FS 条目(如果已启用)
-
int dm_hw_fini(struct amdgpu_ip_block *ip_block)¶
拆除 DC 设备
参数
struct amdgpu_ip_block *ip_block
指向此硬件实例的 amdgpu_ip_block 的指针。
描述
拆除 struct amdgpu_display_manager
中需要清理的组件。这涉及清理 DRM 设备、DC 和加载的任何模块。还要刷新 IRQ 工作队列并禁用它们。
中断¶
DM 在基本驱动程序已经提供的基础上提供了另一层 IRQ 管理。这是一个可以清理的东西,也是一个未来的 TODO 项。
基本驱动程序提供 IRQ 源注册与 DRM、处理程序注册到基本驱动程序的 IRQ 表以及处理程序回调 amdgpu_irq_handler()
,DRM 通过它在中断时调用。此通用处理程序查找 IRQ 表,并调用相应的 amdgpu_irq_src_funcs.process
挂钩。
DM 在其之上提供的是两个专门用于上半部分和下半部分 IRQ 处理的 IRQ 表,其中下半部分实现工作队列
它们会覆盖基本驱动程序的 IRQ 表,并且效果可以在 DM 为 amdgpu_irq_src_funcs.process
提供的挂钩中看到。它们都设置为 DM 通用处理程序 amdgpu_dm_irq_handler()
,它查找 DM 的 IRQ 表。但是,为了使基本驱动程序识别此挂钩,DM 仍然需要使用基本驱动程序注册 IRQ。请参阅 dce110_register_irq_handlers() 和 dcn10_register_irq_handlers()。
为了将 DC 的硬件中断切换公开给基本驱动程序,DM 实现了 amdgpu_irq_src_funcs.set
挂钩。基本驱动程序通过 amdgpu_irq_update()
调用它来启用或禁用中断。
-
struct amdgpu_dm_irq_handler_data¶
DM 中断处理程序的数据。
定义:
struct amdgpu_dm_irq_handler_data {
struct list_head list;
interrupt_handler handler;
void *handler_arg;
struct amdgpu_display_manager *dm;
enum dc_irq_source irq_source;
struct work_struct work;
};
成员
list
引用下一个/上一个处理程序的链表条目
handler
处理程序函数
handler_arg
触发时传递给处理程序的参数
dm
此处理程序所属的 DM
irq_source
此处理程序注册的 DC 中断源
work
work struct
-
void dm_irq_work_func(struct work_struct *work)¶
在中断处理程序之外处理 IRQ。
参数
struct work_struct *work
work struct
-
void unregister_all_irq_handlers(struct amdgpu_device *adev)¶
从 DM IRQ 表中清除处理程序
参数
struct amdgpu_device *adev
包含 DM 设备的基本驱动程序设备
描述
遍历低上下文和高上下文 IRQ 表并取消分配处理程序。
-
void *amdgpu_dm_irq_register_interrupt(struct amdgpu_device *adev, struct dc_interrupt_params *int_params, void (*ih)(void*), void *handler_args)¶
在 DM 中注册处理程序。
参数
struct amdgpu_device *adev
包含 DM 设备的基本驱动程序设备。
struct dc_interrupt_params *int_params
包含源和处理程序上下文的中断参数
void (*ih)(void *)
指向要注册的中断处理程序的函数指针
void *handler_args
中断发生时传递给处理程序的参数
描述
为给定上下文中给定的 IRQ 源注册中断处理程序。上下文可以是高上下文也可以是低上下文。高上下文处理程序直接在 ISR 上下文中执行,而低上下文在工作队列中执行,从而允许休眠操作。
已注册的处理程序以 FIFO 方式调用,即首先调用最近注册的处理程序。
返回
- 处理程序数据
struct amdgpu_dm_irq_handler_data
,其中包含 IRQ 源、处理程序函数和参数
-
void amdgpu_dm_irq_unregister_interrupt(struct amdgpu_device *adev, enum dc_irq_source irq_source, void *ih)¶
从 DM IRQ 表中删除处理程序
参数
struct amdgpu_device *adev
包含 DM 设备的基本驱动程序设备
enum dc_irq_source irq_source
从中删除给定处理程序的 IRQ 源
void *ih
指向要取消注册的中断处理程序的函数指针
描述
遍历低上下文和高上下文 IRQ 表,并找到给定 irq 源的给定处理程序。如果找到,则删除它。否则,什么也不做。
-
int amdgpu_dm_irq_init(struct amdgpu_device *adev)¶
初始化 DM IRQ 管理
参数
struct amdgpu_device *adev
包含 DM 设备的基本驱动程序设备
描述
初始化 DM 的高上下文和低上下文 IRQ 表。
N by M 表包含 N 个 IRQ 源,其中 M 个 struct amdgpu_dm_irq_handler_data
在链表中连接在一起。list_heads 在此处初始化。当中断 n 被触发时,所有 m 个处理程序按注册顺序依次调用 (FIFO)。
低上下文表需要特殊的初始化步骤,因为处理程序将被推迟到工作队列。请参阅 struct irq_list_head
。
-
void amdgpu_dm_irq_fini(struct amdgpu_device *adev)¶
拆除 DM IRQ 管理
参数
struct amdgpu_device *adev
包含 DM 设备的基本驱动程序设备
描述
刷新低上下文 IRQ 表中的所有工作。
-
int amdgpu_dm_irq_handler(struct amdgpu_device *adev, struct amdgpu_irq_src *source, struct amdgpu_iv_entry *entry)¶
通用 DM IRQ 处理程序
参数
struct amdgpu_device *adev
amdgpu 基本驱动程序设备,其中包含 DM 设备
struct amdgpu_irq_src *source
未使用
struct amdgpu_iv_entry *entry
有关触发的中断的数据
描述
立即调用所有已注册的高 irq 工作,并计划低 irq 的工作。DM IRQ 表用于查找相应的处理程序。
-
void amdgpu_dm_hpd_init(struct amdgpu_device *adev)¶
hpd 设置回调。
参数
struct amdgpu_device *adev
amdgpu_device 指针
描述
设置卡使用的 hpd 引脚(evergreen+)。启用引脚,设置极性,然后启用 hpd 中断。
-
void amdgpu_dm_hpd_fini(struct amdgpu_device *adev)¶
hpd 拆卸回调。
参数
struct amdgpu_device *adev
amdgpu_device 指针
描述
拆卸卡使用的 hpd 引脚(evergreen+)。禁用 hpd 中断。
-
void dm_pflip_high_irq(void *interrupt_params)¶
处理页面翻转中断
参数
void *interrupt_params
已忽略
描述
通过通知所有相关方页面翻转已完成来处理页面翻转中断。
-
void dm_crtc_high_irq(void *interrupt_params)¶
处理 CRTC 中断
参数
void *interrupt_params
用于确定 CRTC 实例
描述
通过通知 DRM 的 VBLANK 事件处理程序来处理 CRTC/VSYNC 中断。
原子实现¶
正在进行中
-
void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)¶
AMDgpu DM 的提交尾部实现。
参数
struct drm_atomic_state *state
要提交的原子状态
描述
这将告诉 DC 从 atomic_check 提交构造的 DC 状态,从而对硬件进行编程。这里的任何故障都意味着硬件故障,因为原子检查应该已经过滤掉了任何非 kos。
-
int amdgpu_dm_atomic_check(struct drm_device *dev, struct drm_atomic_state *state)¶
AMDgpu DM 的原子检查实现。
参数
struct drm_device *dev
DRM 设备
struct drm_atomic_state *state
要提交的原子状态
描述
验证给定的原子状态是否可以通过 DC 编程到硬件中。这包括构造一个 struct dc_state
,反映我们希望提交的新的硬件状态,然后查询 DC 以查看它是否可编程。重要的是不要修改现有的 DC 状态。否则,atomic_check 可能会意外地提交硬件更改。
验证 DC 状态时,获取正确的锁非常重要。对于完全更新的情况,即在一个 CRTC 上删除/添加/更新流,同时在另一个 CRTC 上翻转,获取全局锁将保证任何此类完全更新提交都会等待使用 DRM 同步事件完成任何未完成的翻转。
请注意,DM 会为状态中的所有 CRTC 添加受影响的连接器,即使这似乎没有必要。这是因为 DC 流创建需要 DC sink,而 DC sink 与 DRM 连接器状态相关联。清理这一点应该是可能的,但并非易事 - 一个可能的 TODO 项。
返回
- 如果验证失败,则返回错误代码。
颜色管理属性¶
HW 的 DC 接口为我们提供了每个管道(表面)的以下颜色管理块
输入 gamma LUT(反归一化)
输入 CSC(归一化)
表面 degamma LUT(归一化)
表面 CSC(归一化)
表面 regamma LUT(归一化)
输出 CSC(归一化)
但这些并不是 DRM 颜色属性的直接映射。当前的 DRM 接口公开了 CRTC degamma、CRTC CTM 和 CRTC regamma,而我们的硬件本质上是提供
Plane CTM -> Plane degamma -> Plane CTM -> Plane regamma -> Plane CTM
输入 gamma LUT 块并不真正适用于此,因为它作用于实际的输入数据本身,而不是 HW fp 表示。输入和输出 CSC 块在技术上可以用作 DC 接口的一部分,但通常由 DC 在内部用于颜色空间之间的转换。这些将来可以与用户调整混合在一起,但目前应该保持不变。
管道混合也发生在这些块之后,因此我们实际上不支持任何具有与多个平面正确混合的 CRTC 属性 - 但在大多数单平面情况下,通过巧妙地管理 DM 中的 DC 接口,我们仍然可以正确地支持 DM 中的 CRTC 颜色管理属性。
根据 DRM 文档,当各自的属性设置为 NULL 时,块应处于硬件旁路状态。线性 DGM/RGM LUT 也应被视为将各自的块置于旁路模式。
这意味着以下配置被假定为默认配置
Plane DGM Bypass -> Plane CTM Bypass -> Plane RGM Bypass -> ... CRTC DGM Bypass -> CRTC CTM Bypass -> CRTC RGM Bypass
-
void amdgpu_dm_init_color_mod(void)¶
初始化颜色模块。
参数
void
无参数
描述
我们没有使用完整的颜色模块,只使用某些组件。只为我们需要的组件调用设置函数。
-
const struct drm_color_lut *__extract_blob_lut(const struct drm_property_blob *blob, uint32_t *size)¶
从 blob 中提取 DRM lut 和 lut 大小。
参数
const struct drm_property_blob *blob
DRM 颜色管理属性 blob
uint32_t *size
lut 大小
返回
DRM LUT 或 NULL
-
bool __is_lut_linear(const struct drm_color_lut *lut, uint32_t size)¶
检查给定的 lut 是否是值的线性映射
参数
const struct drm_color_lut *lut
给定的 lut 以检查值
uint32_t size
lut 大小
描述
如果 lut 表示:f(a) = (0xFF00/MAX_COLOR_LUT_ENTRIES-1)a;对于 [0, MAX_COLOR_LUT_ENTRIES) 中的整数 a,则认为它是线性的
返回
如果给定的 lut 是值的线性映射,即它充当旁路 LUT,则为 True。否则为 false。
-
void __drm_lut_to_dc_gamma(const struct drm_color_lut *lut, struct dc_gamma *gamma, bool is_legacy)¶
将 drm_color_lut 转换为 dc_gamma。
参数
const struct drm_color_lut *lut
用于颜色转换的 DRM 查找表
struct dc_gamma *gamma
DC gamma 设置条目
bool is_legacy
旧式或原子 gamma
描述
转换取决于 lut 的大小 - 是否为旧式。
-
void __drm_ctm_to_dc_matrix(const struct drm_color_ctm *ctm, struct fixed31_32 *matrix)¶
将 DRM CTM 转换为 DC CSC 浮点矩阵
参数
const struct drm_color_ctm *ctm
DRM 颜色转换矩阵
struct fixed31_32 *matrix
DC CSC 浮点矩阵
描述
矩阵需要是 3x4(12 个条目)矩阵。
-
void __drm_ctm_3x4_to_dc_matrix(const struct drm_color_ctm_3x4 *ctm, struct fixed31_32 *matrix)¶
将 DRM CTM 3x4 转换为 DC CSC 浮点矩阵
参数
const struct drm_color_ctm_3x4 *ctm
具有 3x4 维度的 DRM 颜色转换矩阵
struct fixed31_32 *matrix
DC CSC 浮点矩阵
描述
矩阵需要是 3x4(12 个条目)矩阵。
-
int __set_legacy_tf(struct dc_transfer_func *func, const struct drm_color_lut *lut, uint32_t lut_size, bool has_rom)¶
计算旧式传输函数
参数
struct dc_transfer_func *func
传输函数
const struct drm_color_lut *lut
定义颜色空间的查找表
uint32_t lut_size
各自 lut 的大小
bool has_rom
如果 ROM 可以用于硬编码曲线
描述
仅适用于 sRGB 输入空间
返回
成功时为 0,失败时为 -ENOMEM
-
int __set_output_tf(struct dc_transfer_func *func, const struct drm_color_lut *lut, uint32_t lut_size, bool has_rom)¶
根据预期的输入空间计算输出传输函数。
参数
struct dc_transfer_func *func
传输函数
const struct drm_color_lut *lut
定义颜色空间的查找表
uint32_t lut_size
各自 lut 的大小
bool has_rom
如果 ROM 可以用于硬编码曲线
返回
成功时为 0。如果失败,则为 -ENOMEM。
-
int __set_input_tf(struct dc_color_caps *caps, struct dc_transfer_func *func, const struct drm_color_lut *lut, uint32_t lut_size)¶
根据预期的输入空间计算输入传输函数。
参数
struct dc_color_caps *caps
dc 颜色功能
struct dc_transfer_func *func
传输函数
const struct drm_color_lut *lut
定义颜色空间的查找表
uint32_t lut_size
各自 lut 的大小。
返回
成功时为 0。如果失败,则为 -ENOMEM。
-
int amdgpu_dm_verify_lut3d_size(struct amdgpu_device *adev, struct drm_plane_state *plane_state)¶
验证是否支持 3D LUT,以及用户整形器和 3D LUT 是否与硬件支持的大小匹配
参数
struct amdgpu_device *adev
amdgpu 设备
struct drm_plane_state *plane_state
DRM 平面状态
描述
验证 HW(DCN 2.0 或更高版本)是否支持预混合 (DPP) 3D LUT,以及用户整形器和 3D LUT 是否与支持的大小匹配。
返回
成功时为 0。如果 lut 大小无效,则为 -EINVAL。
-
int amdgpu_dm_verify_lut_sizes(const struct drm_crtc_state *crtc_state)¶
验证 DRM lut 是否与硬件支持的大小匹配
参数
const struct drm_crtc_state *crtc_state
DRM CRTC 状态
描述
验证附加到 crtc_state
的 Degamma 和 Gamma LUT 是否为预期的大小。
返回
成功时为 0。如果任何 lut 大小无效,则为 -EINVAL。
-
int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc)¶
将 DRM 颜色管理映射到 DC 流。
参数
struct dm_crtc_state *crtc
amdgpu_dm crtc 状态
描述
在没有平面级别颜色管理属性的情况下,我们可以自由使用任何 HW 块,只要 CRTC CTM 始终位于 CRTC RGM 之前和 CRTC DGM 之后即可。
如果 CRTC RGM 块是非线性的,则将其放置在 RGM LUT 块中。
如果 CRTC DGM 块是非线性的,则将其放置在 DGM LUT 块中。
如果 CRTC CTM 是非线性的,则将其放置在色域重映射块中。
RGM 块通常在所有 ASIC 中都具有更完整的功能和更高的准确性 - DCE 不能支持自定义非线性 CRTC DGM。
为了同时支持平面级别颜色管理和 CRTC 级别颜色管理,我们必须限制 CRTC 属性的使用或将调整混合在一起。
返回
成功时为 0。如果设置失败,则返回错误代码。
-
int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc, struct drm_plane_state *plane_state, struct dc_plane_state *dc_plane_state)¶
将 DRM 颜色管理映射到 DC 平面。
参数
struct dm_crtc_state *crtc
amdgpu_dm crtc 状态
struct drm_plane_state *plane_state
DRM 平面状态
struct dc_plane_state *dc_plane_state
目标 DC 表面
描述
更新底层 dc_stream_state 的输入传输函数 (ITF),以准备进行硬件提交。使用的传输函数取决于为颜色管理在流上完成的准备工作。
返回
成功时为 0。如果内存分配失败,则返回 -ENOMEM。
DCN 代之间的 DC 颜色功能¶
DRM/KMS 框架定义了三个 CRTC 颜色校正属性:degamma、颜色变换矩阵 (CTM) 和 gamma,以及两个 degamma 和 gamma LUT 大小的属性。AMD DC 编程一些预混合的颜色校正功能,但 DRM/KMS 没有每个平面的颜色校正属性。
一般来说,DRM CRTC 颜色属性被编程到 DC,如下所示:混合后的 CRTC gamma 和预混合的 CRTC degamma。虽然 CTM 在混合后被编程,但它被映射到 DPP 硬件块(预混合)。硬件中提供的其他颜色 caps 当前未由 DRM 接口公开,并且被绕过。
颜色管理 caps(DPP 和 MPC)
Modules/color 计算各种颜色操作,这些操作被转换为抽象的 HW。DCE 5-12 几乎没有重要的更改,但从 DCN1 开始,每一代新产品在颜色管道方面都有相当大的差异。因此,我们抽象颜色管道功能,以便模块/DM 可以根据逻辑功能决定映射到 HW 块。
-
MAX_SURFACES¶
MAX_SURFACES
表示可以管道传输到单个 CRTC 的表面的上限
-
MAX_PLANES¶
MAX_PLANES
表示 HW 支持的平面的上限
-
struct rom_curve_caps¶
degamma 和 regamma 的预定义传输函数 caps
定义:
struct rom_curve_caps {
uint16_t srgb : 1;
uint16_t bt2020 : 1;
uint16_t gamma2_2 : 1;
uint16_t pq : 1;
uint16_t hlg : 1;
};
成员
srgb
RGB 颜色空间传输函数
bt2020
BT.2020 传输函数
gamma2_2
标准 gamma
pq
感知量化器传输函数
hlg
混合对数 gamma 传输函数
-
struct dpp_color_caps¶
显示管道和平面块的颜色管道功能
定义:
struct dpp_color_caps {
uint16_t dcn_arch : 1;
uint16_t input_lut_shared : 1;
uint16_t icsc : 1;
uint16_t dgam_ram : 1;
uint16_t post_csc : 1;
uint16_t gamma_corr : 1;
uint16_t hw_3d_lut : 1;
uint16_t ogam_ram : 1;
uint16_t ocsc : 1;
uint16_t dgam_rom_for_yuv : 1;
struct rom_curve_caps dgam_rom_caps;
struct rom_curve_caps ogam_rom_caps;
};
成员
dcn_arch
所有 DCE 代都以相同的方式处理
input_lut_shared
与 DGAM 共享。输入 LUT 与大多数 LUT 不同,只是普通的 256 条目查找
icsc
输入颜色空间转换
dgam_ram
可编程 degamma LUT
post_csc
色域重映射之前的后颜色空间转换
gamma_corr
degamma 校正
hw_3d_lut
3D LUT 支持。它意味着之前的整形器 LUT。可以通过设置 mpc:shared_3d_lut 标志与 MPC 共享
ogam_ram
可编程输出/混合 gamma LUT
ocsc
输出颜色空间转换
dgam_rom_for_yuv
YUV 平面的预定义 degamma LUT
dgam_rom_caps
degamma 1D LUT 的预定义曲线 caps
ogam_rom_caps
regamma 1D LUT 的预定义曲线 caps
注意
hdr_mult 和色域重映射 (CTM) 始终在 DPP 中可用(按此顺序)
-
struct mpc_color_caps¶
多个管道和平面组合块的颜色管道功能
定义:
struct mpc_color_caps {
uint16_t gamut_remap : 1;
uint16_t ogam_ram : 1;
uint16_t ocsc : 1;
uint16_t num_3dluts : 3;
uint16_t shared_3d_lut:1;
struct rom_curve_caps ogam_rom_caps;
};
成员
gamut_remap
颜色转换矩阵
ogam_ram
可编程输出 gamma LUT
ocsc
输出颜色空间转换矩阵
num_3dluts
MPC 3D LUT;始终假定前面的整形器 LUT
shared_3d_lut
共享 3D LUT 标志。可以是 DPP 或 MPC,但单实例
ogam_rom_caps
regamma 1D LUT 的预定义曲线 caps
-
struct dc_color_caps¶
DPP 和 MPC 硬件块的颜色管道功能
定义:
struct dc_color_caps {
struct dpp_color_caps dpp;
struct mpc_color_caps mpc;
};
成员
dpp
DPP 的颜色管道 caps
mpc
MPC 的颜色管道 caps
-
enum pipe_split_policy¶
DCN 支持的管道拆分策略
常量
MPC_SPLIT_DYNAMIC
DC 将自动决定如何拆分管道,以便在性能和功耗之间实现最佳折衷。这是推荐的选项。
MPC_SPLIT_AVOID
避免管道拆分,这意味着 DC 不会尝试任何类型的拆分优化。
MPC_SPLIT_AVOID_MULT_DISP
使用此选项,DC 仅在使用单个显示器时尝试优化管道利用率;如果用户连接到第二个显示器,DC 将避免管道拆分。
描述
此枚举用于定义 DCN 支持的管道拆分策略。默认情况下,DC 倾向于 MPC_SPLIT_DYNAMIC。
-
struct dc_validation_set¶
用于存储表面/流关联以进行验证的结构
定义:
struct dc_validation_set {
struct dc_stream_state *stream;
struct dc_plane_state *plane_states[MAX_SURFACES];
uint8_t plane_count;
};
成员
stream
流状态属性
plane_states
表面状态
plane_count
活动平面的总数
颜色管道在 DCN 硬件代之间经历了重大变化。在混合之前和之后可以做什么取决于硬件功能,如下面的 DCN 2.0 和 DCN 3.0 系列架构所示。
DCN 2.0 系列颜色 caps 和映射
DCN 3.0 系列颜色 caps 和映射
混合模式属性¶
像素混合模式是 drm_plane
的 DRM 平面合成属性,用于描述如何将前景平面 (fg) 的像素与背景平面 (bg) 合成。在这里,我们介绍 DRM 混合模式的主要概念,以帮助了解此属性如何映射到 AMD DC 接口。有关此 DRM 属性和 alpha 混合方程的更多信息,请参见DRM 平面合成属性。
基本上,混合模式设置平面合成的 alpha 混合方程,该方程适合 alpha 通道影响像素颜色值的状态,因此,影响生成的像素颜色的模式。例如,考虑 alpha 混合方程的以下元素
fg.rgb:前景像素的每个 RGB 分量值。
fg.alpha:前景像素的 Alpha 分量值。
bg.rgb:背景的每个 RGB 分量值。
plane_alpha:由平面“alpha”属性设置的平面 alpha 值,有关更多信息,请参见DRM 平面合成属性。
在基本 alpha 混合方程中
out.rgb = alpha * fg.rgb + (1 - alpha) * bg.rgb
忽略平面中每个像素的 alpha 通道值,只有平面 alpha 影响生成的像素颜色值。
DRM 有三种混合模式来定义平面合成中的混合公式
None:忽略像素 alpha 的混合公式。
Pre-multiplied:假设平面中的像素颜色值在存储之前已经乘以其自身的 alpha 通道的混合公式。
Coverage:假设像素颜色值未与 alpha 通道值预乘的混合公式。
预乘是默认像素混合模式,这意味着,当未创建或定义混合模式属性时,DRM 认为平面的像素具有预乘的颜色值。在 IGT GPU 工具上,kms_plane_alpha_blend 测试提供了一组子测试来验证平面 alpha 和混合模式属性。
然后,DRM 混合模式及其元素由 AMDGPU 显示管理器 (DM) 映射,以编程多个管道/平面组合 (MPC) 的混合配置,如下所示
因此,MPC 树上单个 MPCC 实例的混合配置由 mpcc_blnd_cfg
定义,其中 pre_multiplied_alpha
是用于设置 MPCC_ALPHA_MULTIPLIED_MODE
的 alpha 预乘模式标志。它控制是否乘以 alpha(true/false),仅对于 DRM 预乘混合模式为 true。mpcc_alpha_blend_mode
定义关于像素 alpha 和平面 alpha 值的 alpha 混合模式。它为 MPCC_ALPHA_BLND_MODE
设置三种模式之一,如下所述。
然后,DM 将 enum mpcc_alpha_blend_mode 的元素映射到 DRM 混合公式中的元素,如下所示
MPC 像素 alpha 匹配 DRM fg.alpha 作为平面像素的 alpha 分量值
当应忽略像素 alpha 且像素值未预乘时,MPC 全局 alpha 匹配 DRM plane_alpha
当 DRM fg.alpha 和 DRM plane_alpha 都参与混合方程时,MPC 全局增益 假定 MPC 全局 alpha 值
简而言之,通过选择 MPCC_ALPHA_BLEND_MODE_GLOBAL_ALPHA
忽略 fg.alpha。另一方面,通过选择 MPCC_ALPHA_BLEND_MODE_PER_PIXEL_ALPHA_COMBINED_GLOBAL_GAIN
,(plane_alpha * fg.alpha) 分量变为可用。并且 MPCC_ALPHA_MULTIPLIED_MODE
定义像素颜色值是否乘以 alpha。
混合配置流程¶
alpha 混合方程通过以下路径从 DRM 配置到 DC 接口
更新
drm_plane_state
时,DM 调用amdgpu_dm_plane_fill_blending_from_plane_state()
,将drm_plane_state
属性映射到dc_plane_info
结构,以便在与操作系统无关的组件 (DC) 中处理。在 DC 接口上,
struct mpcc_blnd_cfg
考虑来自 DPP 的dc_plane_info
输入,来编程 MPCC 混合配置。