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 和對映

../../../_images/dcn2_cm_drm_current.svg

DCN 3.0 系列顏色 caps 和對映

../../../_images/dcn3_cm_drm_current.svg

混合模式屬性

畫素混合模式是 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.alphaDRM 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 介面

  1. 更新 drm_plane_state 時,DM 呼叫 amdgpu_dm_plane_fill_blending_from_plane_state(),將 drm_plane_state 屬性對映到 dc_plane_info 結構,以便在與作業系統無關的元件 (DC) 中處理。

  2. 在 DC 介面上,struct mpcc_blnd_cfg 考慮來自 DPP 的 dc_plane_info 輸入,來程式設計 MPCC 混合配置。