核心模式設定 (KMS)

驅動程式必須透過呼叫 drmm_mode_config_init() 在 DRM 裝置上初始化模式設定核心。該函式初始化 struct drm_device mode_config 欄位且永遠不會失敗。完成後,必須透過初始化以下欄位來設定模式配置。

  • int min_width, min_height; int max_width, max_height; 幀緩衝區在畫素單位中的最小和最大寬度和高度。

  • struct drm_mode_config_funcs *funcs; 模式設定函式。

概述

KMS Display Pipeline

KMS 顯示流水線概述

KMS 呈現給使用者空間的基本物件結構相當簡單。幀緩衝區(由 struct drm_framebuffer 表示,請參閱 幀緩衝區抽象)饋送到平面中。平面由 struct drm_plane 表示,有關更多詳細資訊,請參閱 平面抽象。一個或多個(甚至沒有)平面將其畫素資料饋送到 CRTC(由 struct drm_crtc 表示,請參閱 CRTC 抽象)以進行混合。精確的混合步驟在 平面合成屬性和相關章節中進行了更詳細的解釋。

對於輸出路由,第一步是編碼器(由 struct drm_encoder 表示,請參閱 編碼器抽象)。這些實際上只是用於實現 KMS 驅動程式的輔助庫的內部產物。除此之外,它們不必要地使使用者空間更難以弄清楚 CRTC 和聯結器之間的哪些連線是可能的,以及支援什麼樣的克隆,它們在使用者空間 API 中沒有任何作用。不幸的是,編碼器已暴露給使用者空間,因此此時無法刪除它們。此外,公開的限制通常被驅動程式錯誤地設定,並且在許多情況下不足以表達實際限制。CRTC 可以連線到多個編碼器,並且對於活動的 CRTC,必須至少有一個編碼器。

顯示鏈中的最終和真正的端點是聯結器(由 struct drm_connector 表示,請參閱 聯結器抽象)。聯結器可以具有不同的可能編碼器,但核心驅動程式會為每個聯結器選擇要使用的編碼器。用例是 DVI,它可以在模擬和數字編碼器之間切換。編碼器也可以驅動多個不同的聯結器。每個活動的編碼器都有一個活動的聯結器。

在內部,輸出流水線稍微複雜一些,並且與今天的硬體更匹配

KMS Output Pipeline

KMS 輸出流水線

在內部,還有兩個額外的輔助物件發揮作用。首先,為了能夠共享編碼器的程式碼(有時在同一 SoC 上,有時在晶片外),一個或多個 橋接器(由 struct drm_bridge 表示)可以連結到編碼器。此連結是靜態的且無法更改,這意味著需要在 CRTC 和任何編碼器之間對映交叉開關(如果有)。通常對於帶有橋接器的驅動程式,編碼器級別上沒有剩餘程式碼。原子驅動程式可以省略所有編碼器回撥,從而基本上只留下一個虛擬路由物件,這對於向後相容性是必需的,因為編碼器已暴露給使用者空間。

第二個物件用於面板,由 struct drm_panel 表示,請參閱 面板輔助程式參考。面板沒有固定的繫結點,但通常連結到嵌入 struct drm_connector 的驅動程式私有結構。

請注意,目前橋接器連結以及與聯結器和麵板的互動仍在變化中,尚未完全解決。

KMS 核心結構和函式

struct drm_mode_config_funcs

基本驅動程式提供的模式設定函式

定義:

struct drm_mode_config_funcs {
    struct drm_framebuffer *(*fb_create)(struct drm_device *dev,struct drm_file *file_priv, const struct drm_mode_fb_cmd2 *mode_cmd);
    const struct drm_format_info *(*get_format_info)(const struct drm_mode_fb_cmd2 *mode_cmd);
    enum drm_mode_status (*mode_valid)(struct drm_device *dev, const struct drm_display_mode *mode);
    int (*atomic_check)(struct drm_device *dev, struct drm_atomic_state *state);
    int (*atomic_commit)(struct drm_device *dev,struct drm_atomic_state *state, bool nonblock);
    struct drm_atomic_state *(*atomic_state_alloc)(struct drm_device *dev);
    void (*atomic_state_clear)(struct drm_atomic_state *state);
    void (*atomic_state_free)(struct drm_atomic_state *state);
};

成員

fb_create

建立一個新的幀緩衝區物件。核心對請求的元資料進行基本檢查,但大部分留給驅動程式。有關詳細資訊,請參閱 struct drm_mode_fb_cmd2

為了驗證畫素格式和修飾符,驅動程式可以使用 drm_any_plane_has_format() 來確保至少一個平面支援請求的值。請注意,如果請求未指定實際使用的修飾符,即當 (mode_cmd->flags & DRM_MODE_FB_MODIFIERS) == 0 時,驅動程式必須首先確定實際使用的修飾符。

重要提示:這些用於舊使用者空間的隱含修飾符必須儲存在 struct drm_framebuffer 中,包括所有相關元資料,如 drm_framebuffer.pitchesdrm_framebuffer.offsets,如果修飾符啟用了四cc畫素格式程式碼之外的附加平面。GETFB2 ioctl 需要這樣做。

如果引數被認為是有效的,並且底層記憶體管理器中的後備儲存物件都存在,則驅動程式會分配一個新的 drm_framebuffer 結構,該結構被子類化以包含驅動程式特定的資訊(如內部原生緩衝區物件引用)。它還需要填寫所有相關的元資料,這應該透過呼叫 drm_helper_mode_fill_fb_struct() 來完成。

透過呼叫 drm_framebuffer_init() 完成初始化,該函式註冊幀緩衝區並使其可供其他執行緒訪問。

返回值

一個新的幀緩衝區,其初始引用計數為 1,或者使用 ERR_PTR() 編碼的負錯誤程式碼。

get_format_info

允許驅動程式為特殊的 fb 佈局(例如,帶有輔助壓縮控制平面的佈局)返回自定義格式資訊。

返回值

特定於給定 fb 元資料的格式資訊,如果未找到,則返回 NULL。

mode_valid

裝置特定的顯示模式驗證。可用於拒絕永遠無法支援的模式。此處只能檢查裝置範圍內的約束。應在每個特定物件的 .mode_valid() 鉤子中檢查 crtc/encoder/bridge/connector 特定的約束。

atomic_check

這是驗證原子模式設定更新的唯一鉤子。此函式必須拒絕硬體或驅動程式不支援的任何模式設定和狀態更改。這包括但不限於

  • 檢查模式、幀緩衝區、縮放和放置要求等是否在硬體的限制範圍內。

  • 檢查任何隱藏的共享資源是否未被過度訂閱。這可以是共享 PLL、共享通道、整體記憶體頻寬、顯示 FIFO 空間(在平面之間或甚至 CRTC 之間共享)。

  • 檢查匯出到使用者空間的虛擬化資源是否未被過度訂閱。由於各種原因,暴露比物理存在的更多平面、crtc 或編碼器是有意義的。一個例子是雙通道操作(如果在硬體中鎖定,通常應該對使用者空間隱藏,否則公開),其中一個平面可能需要 1 個硬體平面(如果它只在一個通道上),2 個硬體平面(當它跨越兩個通道時),或者甚至與第二個平面共享一個硬體平面(如果在另一個通道處理的區域上請求了相容的平面)。

  • 檢查任何過渡狀態是否可能,並且如果請求,更新確實可以在 vblank 期間完成,而不會暫時停用某些功能。

  • 檢查驅動程式或硬體可能具有的任何其他約束。

  • 此回撥還需要正確填寫此更新中的 drm_crtc_state,以確保 drm_atomic_crtc_needs_modeset() 反映可能更新的性質,並且當且僅當無法在 CRTC 上的一個 vblank 內應用更新而不撕裂時才返回 true。核心使用該資訊來拒絕需要完整模式設定的更新(即,使螢幕空白,或者至少暫停更新相當長的時間),如果使用者空間在其請求中不允許這樣做。

  • 驅動程式也不需要重複基本輸入驗證,例如對相應的舊入口點所做的驗證。核心在呼叫此鉤子之前執行此操作。

有關不必在此回撥中檢查的錯誤條件的詳盡列表,請參閱 atomic_commit 的文件。

有關如何準確描述原子模式設定更新的資訊,請參閱 struct drm_atomic_state 的文件。

使用原子輔助程式的驅動程式可以使用 drm_atomic_helper_check() 或其匯出的子函式之一來實現此鉤子。

返回值

成功時為 0,或者為以下負錯誤程式碼之一

  • -EINVAL,如果違反了上述任何約束。

  • -EDEADLK,當從嘗試透過 drm_modeset_lock() 獲取附加的 drm_modeset_lock 時返回。

  • -ENOMEM,如果由於缺少記憶體而導致分配附加狀態子結構失敗。

  • -EINTR、-EAGAIN 或 -ERESTARTSYS,如果應重新啟動 IOCTL。這可能是由於掛起的訊號,或者因為驅動程式需要完全退出以從 GPU 掛起等異常情況中恢復。從使用者空間的角度來看,所有錯誤都受到同等對待。

atomic_commit

這是提交原子模式設定更新的唯一鉤子。核心保證在呼叫此函式之前已成功呼叫 atomic_check,並且在此期間未進行任何更改。

有關如何準確描述原子模式設定更新的資訊,請參閱 struct drm_atomic_state 的文件。

使用原子輔助程式的驅動程式可以使用 drm_atomic_helper_commit() 或其匯出的子函式之一來實現此鉤子。

非阻塞提交(如非阻塞引數所示)必須在此回撥的上下文中執行任何可能導致提交失敗的準備工作。唯一的例外是導致 -EIO 的硬體錯誤。但即使在這種情況下,驅動程式也必須確保顯示通道至少正在執行,以避免在頁面翻轉不起作用時合成器崩潰。任何其他操作,特別是將更新提交到硬體,都應該在不阻塞呼叫者的情況下完成。對於不需要模式設定的更新,必須保證這一點。

驅動程式必須等待完成對新幀緩衝區的任何掛起渲染,然後才能執行翻轉。如果底層緩衝區是共享的 dma-buf,它也應該等待來自其他驅動程式的任何掛起渲染。非阻塞提交不得在此回撥的上下文中等待渲染。

應用程式可以請求在原子提交完成後收到通知。這些事件是按 CRTC 發生的,可以透過 drm_event 中提供給使用者空間的 CRTC 索引來區分。

drm 核心將在每個 CRTC 的 drm_crtc_state.event 中提供一個 struct drm_event。有關此事件的精確語義的更多詳細資訊,請參閱 drm_crtc_state.event 的文件。

注意

驅動程式不允許自行關閉透過原子提交成功啟用的任何顯示通道。這樣做會導致合成器崩潰,如果突然拒絕頁面翻轉,因為通道已關閉。

返回值

成功時為 0,或者為以下負錯誤程式碼之一

  • -EBUSY,如果請求了非阻塞更新,並且有更早的更新掛起。驅動程式允許支援未完成更新的佇列,但目前沒有驅動程式支援這一點。請注意,如果請求了同步更新,驅動程式必須等待前面的更新完成,在這種情況下不允許提交失敗。

  • -ENOMEM,如果驅動程式未能分配記憶體。具體來說,這可能發生在嘗試固定幀緩衝區時,這隻能在提交狀態時完成。

  • -ENOSPC,作為更通用的 -ENOMEM 的細化,用於指示驅動程式已耗盡用於幀緩衝區的 vram、iommu 空間或類似的 GPU 地址空間。

  • -EIO,如果硬體完全宕機。

  • -EINTR、-EAGAIN 或 -ERESTARTSYS,如果應重新啟動 IOCTL。這可能是由於掛起的訊號,或者因為驅動程式需要完全退出以從 GPU 掛起等異常情況中恢復。從使用者空間的角度來看,所有錯誤都受到同等對待。

此列表是詳盡的。具體來說,不允許此鉤子返回 -EINVAL(任何無效請求都應在 atomic_check 中捕獲)或 -EDEADLK(此函式不得獲取附加的模式設定鎖)。

atomic_state_alloc

想要子類化 struct drm_atomic_state 以便能夠輕鬆跟蹤自己的驅動程式私有全域性狀態的驅動程式可以使用此可選鉤子。如果實現了此鉤子,驅動程式還必須實現 atomic_state_clearatomic_state_free

不建議使用 drm_atomic_state 的子類化,而建議使用 drm_private_statedrm_private_obj

返回值

成功時為新的 drm_atomic_state,失敗時為 NULL。

atomic_state_clear

此鉤子必須清除複製到傳入的 drm_atomic_state 中的任何驅動程式私有狀態。當呼叫者遇到 drm_modeset_lock 死鎖並且需要刪除作為 drm_modeset_backoff() 中實現的死鎖避免舞蹈的一部分的所有已獲取鎖時,將呼叫此鉤子。

任何複製的狀態都必須失效,因為併發的原子更新可能會更改它,並且 drm 原子介面始終將更新作為相對於當前狀態的更改應用。

實現此功能的驅動程式必須呼叫 drm_atomic_state_default_clear() 以清除常見狀態。

不建議使用 drm_atomic_state 的子類化,而建議使用 drm_private_statedrm_private_obj

atomic_state_free

此鉤子需要驅動程式私有資源和 drm_atomic_state 本身。請注意,核心首先呼叫 drm_atomic_state_clear() 以避免清除和釋放鉤子之間的程式碼重複。

實現此功能的驅動程式必須呼叫 drm_atomic_state_default_release() 以釋放常見資源。

不建議使用 drm_atomic_state 的子類化,而建議使用 drm_private_statedrm_private_obj

描述

一些涉及驅動程式的全域性(即,不是每個 CRTC、聯結器等)模式設定函式。

struct drm_mode_config

模式配置控制結構

定義:

struct drm_mode_config {
    struct mutex mutex;
    struct drm_modeset_lock connection_mutex;
    struct drm_modeset_acquire_ctx *acquire_ctx;
    struct mutex idr_mutex;
    struct idr object_idr;
    struct idr tile_idr;
    struct mutex fb_lock;
    int num_fb;
    struct list_head fb_list;
    spinlock_t connector_list_lock;
    int num_connector;
    struct ida connector_ida;
    struct list_head connector_list;
    struct llist_head connector_free_list;
    struct work_struct connector_free_work;
    int num_encoder;
    struct list_head encoder_list;
    int num_total_plane;
    struct list_head plane_list;
    struct raw_spinlock panic_lock;
    int num_crtc;
    struct list_head crtc_list;
    struct list_head property_list;
    struct list_head privobj_list;
    unsigned int min_width, min_height;
    unsigned int max_width, max_height;
    const struct drm_mode_config_funcs *funcs;
    bool poll_enabled;
    bool poll_running;
    bool delayed_event;
    struct delayed_work output_poll_work;
    struct mutex blob_lock;
    struct list_head property_blob_list;
    struct drm_property *edid_property;
    struct drm_property *dpms_property;
    struct drm_property *path_property;
    struct drm_property *tile_property;
    struct drm_property *link_status_property;
    struct drm_property *plane_type_property;
    struct drm_property *prop_src_x;
    struct drm_property *prop_src_y;
    struct drm_property *prop_src_w;
    struct drm_property *prop_src_h;
    struct drm_property *prop_crtc_x;
    struct drm_property *prop_crtc_y;
    struct drm_property *prop_crtc_w;
    struct drm_property *prop_crtc_h;
    struct drm_property *prop_fb_id;
    struct drm_property *prop_in_fence_fd;
    struct drm_property *prop_out_fence_ptr;
    struct drm_property *prop_crtc_id;
    struct drm_property *prop_fb_damage_clips;
    struct drm_property *prop_active;
    struct drm_property *prop_mode_id;
    struct drm_property *prop_vrr_enabled;
    struct drm_property *dvi_i_subconnector_property;
    struct drm_property *dvi_i_select_subconnector_property;
    struct drm_property *dp_subconnector_property;
    struct drm_property *tv_subconnector_property;
    struct drm_property *tv_select_subconnector_property;
    struct drm_property *legacy_tv_mode_property;
    struct drm_property *tv_mode_property;
    struct drm_property *tv_left_margin_property;
    struct drm_property *tv_right_margin_property;
    struct drm_property *tv_top_margin_property;
    struct drm_property *tv_bottom_margin_property;
    struct drm_property *tv_brightness_property;
    struct drm_property *tv_contrast_property;
    struct drm_property *tv_flicker_reduction_property;
    struct drm_property *tv_overscan_property;
    struct drm_property *tv_saturation_property;
    struct drm_property *tv_hue_property;
    struct drm_property *scaling_mode_property;
    struct drm_property *aspect_ratio_property;
    struct drm_property *content_type_property;
    struct drm_property *degamma_lut_property;
    struct drm_property *degamma_lut_size_property;
    struct drm_property *ctm_property;
    struct drm_property *gamma_lut_property;
    struct drm_property *gamma_lut_size_property;
    struct drm_property *suggested_x_property;
    struct drm_property *suggested_y_property;
    struct drm_property *non_desktop_property;
    struct drm_property *panel_orientation_property;
    struct drm_property *writeback_fb_id_property;
    struct drm_property *writeback_pixel_formats_property;
    struct drm_property *writeback_out_fence_ptr_property;
    struct drm_property *hdr_output_metadata_property;
    struct drm_property *content_protection_property;
    struct drm_property *hdcp_content_type_property;
    uint32_t preferred_depth, prefer_shadow;
    bool quirk_addfb_prefer_xbgr_30bpp;
    bool quirk_addfb_prefer_host_byte_order;
    bool async_page_flip;
    bool fb_modifiers_not_supported;
    bool normalize_zpos;
    struct drm_property *modifiers_property;
    struct drm_property *async_modifiers_property;
    struct drm_property *size_hints_property;
    uint32_t cursor_width, cursor_height;
    struct drm_atomic_state *suspend_state;
    const struct drm_mode_config_helper_funcs *helper_private;
};

成員

mutex

這是大型的、可怕的模式設定 BKL,它保護未以其他方式保護的所有內容。範圍不明確且模糊,嘗試從其保護下刪除任何內容並將其移動到範圍更好的鎖定中。

它保護的一個重要的事情是 acquire_ctx 的使用。

connection_mutex

這保護聯結器狀態和聯結器到編碼器到 CRTC 路由鏈。

對於原子驅動程式,具體來說,這保護 drm_connector.state

acquire_ctx

原子驅動程式用於舊 IOCTL 的全域性隱式獲取上下文。已棄用,因為隱式鎖定上下文使得無法使用驅動程式私有的 struct drm_modeset_lock。它的使用者必須持有 mutex

idr_mutex

用於 KMS ID 分配和管理的互斥鎖。同時保護 object_idrtile_idr

object_idr

主 KMS ID 跟蹤物件。對此 ID 使用所有 ID、fb、crtc、connector、模式 - 只有一個可以更輕鬆地生活。

tile_idr

使用此 idr 為平鋪接收器分配新 ID,例如在某些高解析度 DP MST 螢幕中使用。

fb_lock

互斥鎖,用於保護 fb 全域性 fb_listnum_fb

num_fb

fb_list 上的條目數。

fb_list

所有 struct drm_framebuffer 的列表。

connector_list_lock

保護 num_connectorconnector_list 以及 connector_free_list

num_connector

此裝置上的聯結器數。受 connector_list_lock 保護。

connector_ida

聯結器索引的 ID 分配器。

connector_list

使用 drm_connector.head 連結的聯結器物件列表。受 connector_list_lock 保護。僅使用 drm_for_each_connector_iter()struct drm_connector_list_iter 遍歷此列表。

connector_free_list

使用 drm_connector.free_head 連結的聯結器物件列表。受 connector_list_lock 保護。由 drm_for_each_connector_iter()struct drm_connector_list_iter 使用,以使用 connector_free_work 安全地釋放聯結器。

connector_free_work

用於清理 connector_free_list 的工作。

num_encoder

此裝置上的編碼器數。這在裝置的整個生命週期內是不變的,因此不需要任何鎖定。

encoder_list

drm_encoder.head 連結的編碼器物件列表。此列表在裝置的整個生命週期內是不變的,因此不需要任何鎖。

num_total_plane

此裝置上的通用(即帶有主/游標)平面數量。此數量在裝置的整個生命週期內是不變的,因此不需要任何鎖。

plane_list

drm_plane.head 連結的平面物件列表。此列表在裝置的整個生命週期內是不變的,因此不需要任何鎖。

panic_lock

原始自旋鎖,用於保護訪問顯示硬體或模式設定軟體狀態的關鍵程式碼段,緊急列印程式碼必須防止訪問這些程式碼段。參見 drm_panic_trylock()drm_panic_lock()drm_panic_unlock()

num_crtc

此裝置上與 drm_crtc.head 連結的 CRTC 數量。此數量在裝置的整個生命週期內是不變的,因此不需要任何鎖。

crtc_list

drm_crtc.head 連結的 CRTC 物件列表。此列表在裝置的整個生命週期內是不變的,因此不需要任何鎖。

property_list

drm_property.head 連結的屬性型別物件列表。此列表在裝置的整個生命週期內是不變的,因此不需要任何鎖。

privobj_list

drm_private_obj.head 連結的私有物件列表。此列表在裝置的整個生命週期內是不變的,因此不需要任何鎖。

min_width

此裝置上的最小幀緩衝區畫素寬度

min_height

此裝置上的最小幀緩衝區畫素高度

max_width

此裝置上的最大幀緩衝區畫素寬度

max_height

此裝置上的最大幀緩衝區畫素高度

funcs

核心驅動程式提供的模式設定函式

poll_enabled

跟蹤此裝置的輪詢支援

poll_running

跟蹤此裝置的輪詢狀態

delayed_event

跟蹤此裝置的延遲輪詢 uevent 傳遞

output_poll_work

程序上下文中輪詢的延遲工作

blob_lock

用於 blob 屬性分配和管理的互斥鎖,保護 property_blob_listdrm_file.blobs

property_blob_list

drm_property_blob.head 連結的所有 blob 屬性物件的列表。受 blob_lock 保護。

edid_property

預設聯結器屬性,用於儲存當前連線的接收器的 EDID(如果有)。

dpms_property

預設聯結器屬性,用於控制聯結器的 DPMS 狀態。

path_property

預設聯結器屬性,用於儲存埠的 DP MST 路徑。

tile_property

預設聯結器屬性,用於儲存平鋪螢幕的平鋪位置,適用於需要使用多個 CRTC 驅動的接收器。

link_status_property

聯結器連結狀態的預設聯結器屬性

plane_type_property

預設平面屬性,用於區分平面 CURSOR、PRIMARY 和 OVERLAY 的舊用法。

prop_src_x

用於連線的 drm_framebuffer 中平面源位置的預設原子平面屬性。

prop_src_y

用於連線的 drm_framebuffer 中平面源位置的預設原子平面屬性。

prop_src_w

用於連線的 drm_framebuffer 中平面源位置的預設原子平面屬性。

prop_src_h

用於連線的 drm_framebuffer 中平面源位置的預設原子平面屬性。

prop_crtc_x

用於 drm_crtc 上顯示的平面目標位置的預設原子平面屬性。

prop_crtc_y

用於 drm_crtc 上顯示的平面目標位置的預設原子平面屬性。

prop_crtc_w

用於 drm_crtc 上顯示的平面目標位置的預設原子平面屬性。

prop_crtc_h

用於 drm_crtc 上顯示的平面目標位置的預設原子平面屬性。

prop_fb_id

用於指定 drm_framebuffer 的預設原子平面屬性。

prop_in_fence_fd

表示平面傳入圍欄的同步檔案 fd。

prop_out_fence_ptr

表示 CRTC 傳出圍欄的同步檔案 fd 指標。使用者空間應提供指向 s32 型別值的指標,然後將該指標轉換為 u64。

prop_crtc_id

用於指定 drm_crtc 的預設原子平面屬性。

prop_fb_damage_clips

可選平面屬性,用於標記平面上附加到平面的幀緩衝區的幀緩衝區座標中的損壞區域。

blob 資料的佈局只是一個 drm_mode_rect 陣列。與平面源座標不同,損壞剪輯不是 16.16 定點。

prop_active

控制活動狀態的預設原子 CRTC 屬性,這是原子驅動程式中 DPMS 的簡化實現。

prop_mode_id

用於設定 CRTC 模式的預設原子 CRTC 屬性。0 模式表示 CRTC 已完全停用 - 所有聯結器必須關閉,並且活動狀態必須設定為停用。

prop_vrr_enabled

預設原子 CRTC 屬性,用於指示是否應在 CRTC 上啟用可變重新整理率。

dvi_i_subconnector_property

可選 DVI-I 屬性,用於區分模擬或數字模式。

dvi_i_select_subconnector_property

可選 DVI-I 屬性,用於在模擬或數字模式之間進行選擇。

dp_subconnector_property

可選 DP 屬性,用於區分不同的 DP 下游埠型別。

tv_subconnector_property

可選 TV 屬性,用於區分不同的 TV 聯結器型別。

tv_select_subconnector_property

可選 TV 屬性,用於在不同的 TV 聯結器型別之間進行選擇。

legacy_tv_mode_property

可選 TV 屬性,用於選擇輸出 TV 模式。

已由 tv_mode_property 取代

tv_mode_property

可選 TV 屬性,用於選擇聯結器上的 TV 標準輸出。

tv_left_margin_property

可選 TV 屬性,用於設定左邊距(以畫素為單位表示)。

tv_right_margin_property

可選 TV 屬性,用於設定右邊距(以畫素為單位表示)。

tv_top_margin_property

可選 TV 屬性,用於設定右邊距(以畫素為單位表示)。

tv_bottom_margin_property

可選 TV 屬性,用於設定右邊距(以畫素為單位表示)。

tv_brightness_property

可選 TV 屬性,用於設定亮度。

tv_contrast_property

可選 TV 屬性,用於設定對比度。

tv_flicker_reduction_property

可選 TV 屬性,用於控制閃爍減少模式。

tv_overscan_property

可選 TV 屬性,用於控制過掃描設定。

tv_saturation_property

可選 TV 屬性,用於設定飽和度。

tv_hue_property

可選 TV 屬性,用於設定色調。

scaling_mode_property

可選聯結器屬性,用於控制放大,主要用於內建面板。

aspect_ratio_property

可選聯結器屬性,用於控制 HDMI 資訊幀寬高比設定。

content_type_property

可選聯結器屬性,用於控制 HDMI 資訊幀內容型別設定。

degamma_lut_property

可選 CRTC 屬性,用於設定用於將幀緩衝區的顏色轉換為線性伽瑪的 LUT。

degamma_lut_size_property

可選 CRTC 屬性,用於驅動程式支援的去伽瑪 LUT 的大小(只讀)。

ctm_property

可選 CRTC 屬性,用於設定在去伽瑪 LUT 中查詢後用於轉換顏色的矩陣。

gamma_lut_property

可選 CRTC 屬性,用於設定在 CTM 矩陣之後用於將顏色轉換為連線螢幕的伽瑪空間的 LUT。

gamma_lut_size_property

可選 CRTC 屬性,用於驅動程式支援的伽瑪 LUT 的大小(只讀)。

suggested_x_property

可選聯結器屬性,提示輸出在主機螢幕上的位置。

suggested_y_property

可選聯結器屬性,提示輸出在主機螢幕上的位置。

non_desktop_property

可選聯結器屬性,提示裝置不是標準顯示器,並且不應在其上顯示控制檯/桌面。

panel_orientation_property

可選聯結器屬性,指示液晶面板在外殼內的安裝方式(例如,正常或倒置)。

writeback_fb_id_property

用於回寫聯結器的屬性,儲存輸出幀緩衝區的 ID。另請參見:drm_writeback_connector_init()

writeback_pixel_formats_property

用於回寫聯結器的屬性,儲存回寫引擎支援的畫素格式陣列(只讀)。另請參見:drm_writeback_connector_init()

writeback_out_fence_ptr_property

用於回寫聯結器的屬性,fd 指標表示回寫聯結器的傳出圍欄。使用者空間應提供指向 s32 型別值的指標,然後將該指標轉換為 u64。另請參見:drm_writeback_connector_init()

hdr_output_metadata_property

包含 HDR 元資料的聯結器屬性。這將由使用者空間合成器基於 HDR 內容提供

content_protection_property

用於內容保護的 DRM ENUM 屬性。參見 drm_connector_attach_content_protection_property()

hdcp_content_type_property

用於受保護內容的 DRM ENUM 屬性。

preferred_depth

首選 RBG 畫素深度,由 fb 輔助函式使用

prefer_shadow

提示使用者空間首選陰影 fb 渲染

quirk_addfb_prefer_xbgr_30bpp

用於舊 ADDFB 的特殊 hack,以保持 nouveau 使用者空間正常工作。應僅由 nouveau 核心驅動程式設定。

quirk_addfb_prefer_host_byte_order

如果設定為 true,則 drm_mode_addfb() 在呼叫 drm_mode_addfb2() 時將選擇主機位元組順序 pixel_format。這應該是 drm_mode_addfb() 從一開始就應該工作的方式。但事實並非如此,因此我們最終在核心和使用者空間驅動程式中都存在怪癖,以處理錯誤的行為。簡單地無條件修復 drm_mode_addfb() 會破壞這些驅動程式,因此在此處新增一個怪癖位以允許驅動程式選擇加入。

async_page_flip

此裝置是否支援在主平面上進行非同步翻轉?

fb_modifiers_not_supported

設定此標誌後,DRM 裝置將不會向用戶空間公開修飾符支援。這僅由透過啟發式方法推斷緩衝區佈局而不使用修飾符的舊驅動程式使用。新驅動程式不應設定此標誌。

normalize_zpos

如果為 true,則 DRM 核心將呼叫 drm_atomic_normalize_zpos() 作為來自 drm_atomic_helper_check() 的原子模式檢查的一部分

modifiers_property

用於列出支援的修飾符/格式組合的平面屬性。

async_modifiers_property

用於列出非同步翻轉支援的修飾符/格式組合的平面屬性。

size_hints_property

平面 SIZE_HINTS 屬性。

cursor_width

提示使用者空間最大游標寬度

cursor_height

提示使用者空間最大游標高度

suspend_state

掛起時的原子狀態。由 drm_mode_config_helper_suspend() 設定,並由 drm_mode_config_helper_resume() 清除。

helper_private

中間層私有資料

描述

核心模式資源跟蹤結構。驅動程式列舉的所有 CRTC、編碼器和聯結器都將新增到此處,全域性屬性也是如此。一些全侷限制也在這裡,例如維度限制。

幀緩衝區大小是指 CRTC 可以顯示的虛擬螢幕。這可能與程式設計的物理解析度不同。儲存在 min_widthmin_height 中的最小寬度和高度描述了幀緩衝區的最小尺寸。它與最小可程式設計解析度相關。儲存在 max_width 中的最大寬度通常受兩個相鄰掃描線之間的最大間距限制。儲存在 max_height 中的最大高度通常僅受可定址影片記憶體量的限制。對於沒有實際最大值的硬體,驅動程式應選擇一個合理的預設值。

另請參見 DRM_SHADOW_PLANE_MAX_WIDTHDRM_SHADOW_PLANE_MAX_HEIGHT

int drm_mode_config_init(struct drm_device *dev)

DRM mode_configuration 結構初始化

引數

struct drm_device *dev

DRM 裝置

描述

這是 drmm_mode_config_init() 的非託管版本,適用於仍顯式呼叫 drm_mode_config_cleanup() 的驅動程式。

FIXME:此函式已棄用,應將驅動程式轉換為 drmm_mode_config_init()

void drm_mode_config_reset(struct drm_device *dev)

呼叫 ->reset 回撥

引數

struct drm_device *dev

drm 裝置

描述

此函式呼叫所有 crtc、編碼器和聯結器的 ->reset 回撥。驅動程式可以在其驅動程式載入或恢復程式碼中使用此功能來重置硬體和軟體狀態。

int drmm_mode_config_init(struct drm_device *dev)

託管的 DRM mode_configuration 結構初始化

引數

struct drm_device *dev

DRM 裝置

描述

初始化 dev 的 mode_config 結構,用於跟蹤 dev 的圖形配置。

由於這會初始化模式設定鎖,因此不可能進行鎖定。這沒有問題,因為這應該在初始化時以單執行緒方式進行。驅動程式有責任確保此保證。

清理透過使用 drmm_add_action() 註冊 drm_mode_config_cleanup 來自動處理。

返回

成功時返回 0,失敗時返回負錯誤值。

void drm_mode_config_cleanup(struct drm_device *dev)

釋放 DRM mode_config 資訊

引數

struct drm_device *dev

DRM 裝置

描述

釋放與此 DRM 裝置關聯的所有聯結器和 CRTC,然後釋放幀緩衝區和關聯的緩衝區物件。

請注意,由於這/應該/在驅動程式/裝置拆卸時以單執行緒方式進行,因此不需要鎖定。驅動程式的工作是確保此保證實際上成立。

FIXME:使用託管的 drmm_mode_config_init() 後,驅動程式不再需要顯式呼叫此函式。

模式設定基本物件抽象

Mode Objects and Properties

模式物件和屬性

所有 KMS 物件的基本結構是 struct drm_mode_object。它提供的基本服務之一是跟蹤屬性,這對於原子 IOCTL(請參見 原子模式設定)尤其重要。這裡有點令人驚訝的是,屬性不是直接在每個物件上例項化的,而是獨立的模式物件本身,由 struct drm_property 表示,它僅指定屬性的型別和值範圍。可以使用 drm_object_attach_property() 將任何給定屬性多次附加到不同的物件。

struct drm_mode_object

模式設定物件的基本結構

定義:

struct drm_mode_object {
    uint32_t id;
    uint32_t type;
    struct drm_object_properties *properties;
    struct kref refcount;
    void (*free_cb)(struct kref *kref);
};

成員

id

使用者空間可見的識別符號

type

物件的型別,為 DRM_MODE_OBJECT_* 之一

properties

附加到此物件的屬性,包括值

refcount

具有動態生命週期的物件的引用計數

free_cb

釋放函式回撥,僅為具有動態生命週期的物件設定

描述

使用者空間可見的模式設定物件的基本結構。可以使用 drm_mode_object_find() 查詢物件。除了 idtype 等基本 uapi 介面屬性之外,它還提供兩項服務

struct drm_object_properties

用於 drm_mode_object 的屬性跟蹤

定義:

struct drm_object_properties {
    int count;
    struct drm_property *properties[DRM_OBJECT_MAX_PROPERTY];
    uint64_t values[DRM_OBJECT_MAX_PROPERTY];
};

成員

count

有效屬性的數量,必須小於或等於 DRM_OBJECT_MAX_PROPERTY。

properties

指向 drm_property 的指標陣列。

注意:如果我們開始動態銷燬屬性(即不在 drm_mode_config_cleanup() 時),那麼我們必須更好地將屬性從模式物件分離,以避免懸掛屬性指標

values

用於儲存屬性值的陣列,與 properties 匹配。不要直接讀取/寫入值,而是使用 drm_object_property_get_value()drm_object_property_set_value()

請注意,原子驅動程式不會在此陣列中儲存可變屬性,而只會將解碼後的值儲存在相應的狀態結構中。解碼使用 drm_crtc.atomic_get_propertydrm_crtc.atomic_set_property 鉤子對於 struct drm_crtc 完成。 對於 struct drm_plane, 鉤子是 drm_plane_funcs.atomic_get_propertydrm_plane_funcs.atomic_set_property。對於 struct drm_connector, 鉤子是 drm_connector_funcs.atomic_get_propertydrm_connector_funcs.atomic_set_property

因此,原子驅動程式不應在可變物件上使用 drm_object_property_set_value()drm_object_property_get_value(),即那些沒有設定 DRM_MODE_PROP_IMMUTABLE 標誌的物件。

對於原子驅動程式,屬性的預設值儲存在此陣列中,因此可以使用 drm_object_property_get_default_value 檢索它。

struct drm_mode_object *drm_mode_object_find(struct drm_device *dev, struct drm_file *file_priv, uint32_t id, uint32_t type)

查詢具有靜態生命週期的 drm 物件

引數

struct drm_device *dev

drm 裝置

struct drm_file *file_priv

drm 檔案

uint32_t id

模式物件的 ID

uint32_t type

模式物件的型別

描述

此函式用於查詢模式設定物件。它將獲取引用計數的物件的引用。必須透過呼叫 drm_mode_object_put() 再次刪除此引用。

void drm_mode_object_put(struct drm_mode_object *obj)

釋放模式物件引用

引數

struct drm_mode_object *obj

DRM 模式物件

描述

如果物件是一個引用計數的模式設定物件,此函式會遞減物件的引用計數。 它對任何其他物件都是空操作。 這用於刪除透過 drm_mode_object_get() 獲取的引用。

void drm_mode_object_get(struct drm_mode_object *obj)

獲取模式物件引用

引數

struct drm_mode_object *obj

DRM 模式物件

描述

如果物件是一個引用計數的模式設定物件,此函式會遞增物件的引用計數。 它對任何其他物件都是空操作。 應透過呼叫 drm_mode_object_put() 再次刪除引用。

void drm_object_attach_property(struct drm_mode_object *obj, struct drm_property *property, uint64_t init_val)

將屬性附加到模式設定物件

引數

struct drm_mode_object *obj

drm 模式設定物件

struct drm_property *property

要附加的屬性

uint64_t init_val

屬性的初始值

描述

這會將給定的屬性與給定的初始值附加到模式設定物件。目前,此函式不會失敗,因為屬性儲存在靜態大小的陣列中。

請注意,所有屬性必須在物件本身被註冊並可從使用者空間訪問之前附加。

int drm_object_property_set_value(struct drm_mode_object *obj, struct drm_property *property, uint64_t val)

設定屬性的值

引數

struct drm_mode_object *obj

要設定屬性值的 drm 模式物件

struct drm_property *property

要設定的屬性

uint64_t val

屬性應設定為的值

描述

此函式設定給定物件上的給定屬性。此函式僅更改屬性的軟體狀態,它不會呼叫驅動程式的 ->set_property 回撥。

請注意,原子驅動程式應該不需要呼叫此函式,核心將確保透過適當的 ->atomic_get_property 回撥將值報告回用戶空間的一致性。只有傳統驅動程式才應呼叫此函式來更新跟蹤的值(在應用鉗制和其他限制後)。

返回

成功時為零,失敗時為錯誤程式碼。

int drm_object_property_get_value(struct drm_mode_object *obj, struct drm_property *property, uint64_t *val)

檢索屬性的值

引數

struct drm_mode_object *obj

從中獲取屬性值的 drm 模式物件

struct drm_property *property

要檢索的屬性

uint64_t *val

屬性值的儲存

描述

此函式檢索給定屬性的軟體狀態。由於沒有驅動程式回撥來檢索當前屬性值,因此根據驅動程式和屬性,這可能與硬體不同步。

原子驅動程式永遠不應直接呼叫此函式,核心將透過各種 ->atomic_get_property 回撥讀取屬性值。

返回

成功時為零,失敗時為錯誤程式碼。

int drm_object_property_get_default_value(struct drm_mode_object *obj, struct drm_property *property, uint64_t *val)

在原子模式下檢索屬性的預設值。

引數

struct drm_mode_object *obj

從中獲取屬性值的 drm 模式物件

struct drm_property *property

要檢索的屬性

uint64_t *val

屬性值的儲存

描述

此函式檢索傳遞給 drm_object_attach_property 的給定屬性的預設狀態

只有原子驅動程式才應直接呼叫此函式,因為對於非原子驅動程式,它將返回當前值。

返回

成功時為零,失敗時為錯誤程式碼。

原子模式設定

Mode Objects and Properties

模式物件和屬性

原子提供了事務性的模式設定(包括 plane)更新,但與通常的 try-commit 和回滾事務性方法略有不同

  • 首先,當提交將失敗時,不允許硬體更改。這使我們能夠實現 DRM_MODE_ATOMIC_TEST_ONLY 模式,該模式允許使用者空間探索某些配置是否有效。

  • 這仍然允許僅設定和回滾軟體狀態,從而簡化了現有驅動程式的轉換。但是,審計驅動程式的 atomic_check 程式碼的正確性變得非常困難:在各處的資料結構中回滾更改很難做好。

  • 最後,為了向後相容並支援所有用例,原子更新需要是增量的並且能夠並行執行。硬體並不總是允許它,但在可能的情況下,不同 CRTC 上的平面更新不應相互干擾,並且不應由於不同 CRTC 上的輸出路由更改而停滯。

綜上所述,原子設計有兩個後果

  • 總體狀態分為每個物件的狀態結構:struct drm_plane_state 用於 plane, struct drm_crtc_state 用於 CRTC 和 struct drm_connector_state 用於 connector。 這些是唯一具有使用者空間可見和可設定狀態的物件。 對於內部狀態,驅動程式可以透過嵌入來子類化這些結構,或者為其全域性共享的硬體功能新增全新的狀態結構,請參見 struct drm_private_state.

  • 原子更新在 drm_atomic_state 容器中被組裝和驗證為完全獨立的結構堆。驅動程式私有狀態結構也在同一結構中被跟蹤;請參見下一章。只有在提交狀態時,它才會被應用於驅動程式和模式設定物件。這樣,回滾更新就歸結為釋放記憶體和取消引用諸如幀緩衝區的物件。

原子狀態結構的鎖定在內部使用 struct drm_modeset_lock。作為一般規則,不應將鎖定暴露給驅動程式,而是應由任何複製或窺視狀態的函式自動獲取正確的鎖定,例如 drm_atomic_get_crtc_state()。鎖定僅保護軟體資料結構,將狀態更改提交到硬體的順序使用 struct drm_crtc_commit 進行排序。

請繼續閱讀本章以及 原子模式設定助手函式參考 以獲得有關特定主題的更詳細的報道。

處理驅動程式私有狀態

通常,在原子模式設定 api 中暴露給使用者空間的 DRM 物件(drm_connector, drm_crtcdrm_plane) 不能完全對映到底層硬體。特別是對於任何型別的共享資源(例如,在 planes 或 CRTC 組之間共享的共享時鐘、縮放器單元、頻寬和 fifo 限制等等),將這些建模為獨立物件是有意義的。然後,驅動程式需要為這些私有物件(因為未暴露給使用者空間)執行類似的狀態跟蹤和提交排序,原子核心和 helpers 已經為 connectors、planes 和 CRTC 提供了這些功能。

為了使驅動程式更容易,原子核心提供了一些支援,以使用 struct drm_private_obj 和相關的狀態 struct drm_private_state 來跟蹤驅動程式私有狀態物件。

類似於使用者空間暴露的物件,可以透過呼叫 drm_atomic_get_private_obj_state() 獲取私有狀態結構。 這也負責鎖定,因此驅動程式不需要直接呼叫 drm_modeset_lock()。 不處理實際硬體狀態提交的順序,驅動程式可能需要根據需要在 drm_private_state 的子類化結構中跟蹤 struct drm_crtc_commit,例如類似於 drm_plane_state.commit。另請參見 drm_atomic_state.fake_commit

可以使用 for_each_oldnew_private_obj_in_state(), for_each_new_private_obj_in_state()for_each_old_private_obj_in_state() 迭代 drm_atomic_state 更新中包含的所有私有狀態結構。建議驅動程式為它們擁有的每種驅動程式私有狀態物件包裝這些函式,並使用 for_each_if() 過濾 drm_private_obj.funcs,至少如果他們想要迭代給定型別的所有物件。

先前處理驅動程式私有狀態的方法是透過子類化 struct drm_atomic_state。但是,由於這鼓勵了非標準方式來實現原子所需的 check/commit 分裂(例如,使用“檢查和回滾或提交而不是”而不是“複製狀態,檢查,然後提交或釋放複製狀態),因此它已被棄用,而贊成使用 drm_private_state

原子模式設定功能參考

struct drm_crtc_commit

跟蹤 CRTC 上的模式設定提交

定義:

struct drm_crtc_commit {
    struct drm_crtc *crtc;
    struct kref ref;
    struct completion flip_done;
    struct completion hw_done;
    struct completion cleanup_done;
    struct list_head commit_entry;
    struct drm_pending_vblank_event *event;
    bool abort_completion;
};

成員

crtc

此提交的 DRM CRTC。

ref

此結構的引用計數。 需要允許阻塞完成而沒有完成消失的風險。

flip_done

當硬體翻轉到新的緩衝區集時,將發出訊號。 與將此提交的 drm 事件傳送到使用者空間或發出 out-fence 訊號時同時發出訊號。 請注意,對於大多數硬體,在大多數情況下,這發生在 hw_done 發出訊號之後。

此階段的完成透過在 drm_crtc_state.event 上呼叫 drm_crtc_send_vblank_event() 來隱式發出訊號。

hw_done

當此次提交的所有硬體暫存器更改都已寫入後,將發出訊號。尤其是在停用管道時,這可能比 flip_done 晚得多,因為 flip_done 可以在螢幕變黑時發出訊號,而完全關閉管道需要更多的暫存器 I/O。

請注意,這不需要包括單獨的引用計數資源,如後備儲存緩衝區鎖定或執行時電源管理。

驅動程式應呼叫 drm_atomic_helper_commit_hw_done() 以發出此階段完成的訊號。

cleanup_done

在透過呼叫 drm_atomic_helper_cleanup_planes() 清理舊緩衝區後,將發出訊號。由於這隻能在 vblank 等待完成後發生,因此可能會稍晚一些。此完成對於限制更新並避免硬體更新過多地超前於緩衝區清理非常有用。

驅動程式應呼叫 drm_atomic_helper_commit_cleanup_done() 以發出此階段完成的訊號。

commit_entry

每個 CRTC 的 drm_crtc.commit_list 上的條目。受 $drm_crtc.commit_lock 保護。

event

指向清除私有事件的 drm_pending_vblank_event 指標。

abort_completion

drm_atomic_helper_setup_commit() 為 $drm_crtc_state.event 的完成獲取第二個引用後設置的標誌。它被 free 程式碼用於在提交失敗時刪除第二個引用。

描述

此結構用於跟蹤每個 CRTC 上掛起的模式設定更改和原子提交。由於更新列表永遠不應阻塞,因此此結構是引用計數的,以允許等待者安全地等待事件完成,而無需持有任何鎖。

它總共有 3 個不同的事件,以允許在未完成的更新之間進行細粒度的同步

atomic commit thread                    hardware

write new state into hardware   ---->   ...
signal hw_done
                                        switch to new state on next
...                                     v/hblank

wait for buffers to show up             ...

...                                     send completion irq
                                        irq handler signals flip_done
cleanup old buffers

signal cleanup_done

wait for flip_done              <----
clean up atomic state

需要了解的重要一點是 cleanup_done 是終端事件,但 flip_donehw_done 之間的順序完全取決於特定的驅動程式和模式設定狀態更改。

有關如何使用此功能的實現,請參閱原子助手庫中的 drm_atomic_helper_setup_commit()

另請參閱 drm_crtc_commit_wait()

struct drm_private_state_funcs

私有物件的原子狀態函式

定義:

struct drm_private_state_funcs {
    struct drm_private_state *(*atomic_duplicate_state)(struct drm_private_obj *obj);
    void (*atomic_destroy_state)(struct drm_private_obj *obj, struct drm_private_state *state);
    void (*atomic_print_state)(struct drm_printer *p, const struct drm_private_state *state);
};

成員

atomic_duplicate_state

複製私有物件的當前狀態並返回它。在 obj->state 初始化之前呼叫此方法是一個錯誤。

返回值

複製的原子狀態,或者當 obj->state 未初始化或分配失敗時為 NULL。

atomic_destroy_state

釋放使用 atomic_duplicate_state 建立的私有物件狀態。

atomic_print_state

如果驅動程式子類化 struct drm_private_state,它應該實現這個可選的 hook 來列印額外的驅動程式特定狀態。

不要直接呼叫此函式,請改用 drm_atomic_private_obj_print_state()。

描述

這些 hook 被原子助手用來建立、交換和銷燬私有物件的狀態。該結構本身用作 vtable 來識別關聯的私有物件型別。需要新增到原子狀態的每種私有物件型別都應實現這些 hook,並將指向其 drm_private_state_funcs 結構的指標傳遞給 drm_atomic_get_private_obj_state()

struct drm_private_obj

驅動程式私有原子物件的基本結構

定義:

struct drm_private_obj {
    struct list_head head;
    struct drm_modeset_lock lock;
    struct drm_private_state *state;
    const struct drm_private_state_funcs *funcs;
};

成員

head

用於將私有物件附加到 drm_device 的列表條目(排隊到 drm_mode_config.privobj_list)。

lock

模式設定鎖,用於保護狀態物件。

state

此驅動程式私有物件的當前原子狀態。

funcs

用於操作此驅動程式私有物件狀態的函式,請參閱 drm_private_state_funcs

描述

驅動程式私有物件透過呼叫 drm_atomic_private_obj_init() 初始化,並透過呼叫 drm_atomic_private_obj_fini() 清理。

當前僅跟蹤狀態更新函式和不透明的驅動程式私有狀態本身,但在將來也可能跟蹤需要哪個 drm_modeset_lock 來複制和更新此物件的狀態。

所有私有物件都必須在它們所附加到的 DRM 設備註冊到 DRM 子系統之前初始化(呼叫 drm_dev_register()),並且應該一直存在,直到此 DRM 設備註銷(呼叫 drm_dev_unregister())。換句話說,私有物件的生命週期與 DRM 裝置的生命週期相關聯。這意味著

1/ 所有對 drm_atomic_private_obj_init() 的呼叫都必須在呼叫之前完成

drm_dev_register()

2/ 所有對 drm_atomic_private_obj_fini() 的呼叫都必須在呼叫之後完成

drm_dev_unregister()

如果該私有物件用於儲存多個 CRTC 共享的狀態,則必須採取適當的措施來確保非阻塞提交正確排序,以避免發生 use-after-free 問題。

事實上,假設在兩個不同的 drm_crtc 上進行兩次非阻塞 drm_atomic_commit,使用不同的 drm_planedrm_connector,因此沒有共享資源,無法保證哪個提交會首先發生。但是,第二個 drm_atomic_commit 會將第一個 drm_private_obj 視為其舊狀態,並且在第二個 drm_atomic_commit 完成時,負責釋放它。

如果第一個 drm_atomic_commit 在它之後發生,它會將其 drm_private_obj 視為新狀態,並且可能會訪問它,從而導致訪問已釋放的記憶體區域。驅動程式應在 drm_mode_config_helper_funcs.atomic_commit_setup 中的私有狀態中儲存(並獲取對)drm_crtc_commit 結構,然後在 drm_mode_config_helper_funcs.atomic_commit_tail 的第一步中等待該提交完成,類似於 drm_atomic_helper_wait_for_dependencies()

drm_for_each_privobj

drm_for_each_privobj (privobj, dev)

私有物件迭代器

引數

privobj

指向當前私有物件的指標。每次迭代後更新

dev

我們想要從中獲取私有物件的 DRM 裝置

描述

允許人們迭代附加到 dev 的所有私有物件

struct drm_private_state

驅動程式私有物件狀態的基本結構

定義:

struct drm_private_state {
    struct drm_atomic_state *state;
    struct drm_private_obj *obj;
};

成員

state

指向全域性 drm_atomic_state 的後向指標

obj

指向私有物件的後向指標

描述

當前僅包含指向整體原子更新的後向指標和相關的私有物件,但將來也可能包含類似於例如 drm_crtc.commit 的同步資訊。

struct drm_atomic_state

原子提交結構

定義:

struct drm_atomic_state {
    struct kref ref;
    struct drm_device *dev;
    bool allow_modeset : 1;
    bool legacy_cursor_update : 1;
    bool async_update : 1;
    bool duplicated : 1;
    struct __drm_planes_state *planes;
    struct __drm_crtcs_state *crtcs;
    int num_connector;
    struct __drm_connnectors_state *connectors;
    int num_private_objs;
    struct __drm_private_objs_state *private_objs;
    struct drm_modeset_acquire_ctx *acquire_ctx;
    struct drm_crtc_commit *fake_commit;
    struct work_struct commit_work;
};

成員

ref

對此更新的所有引用的計數(在歸零之前不會釋放)。

dev

父 DRM 裝置。

allow_modeset

允許完全模式設定。這被 ATOMIC IOCTL 處理程式用於實現 DRM_MODE_ATOMIC_ALLOW_MODESET 標誌。驅動程式通常不應查詢此標誌,而應檢視 drm_atomic_crtc_needs_modeset() 的輸出。詳細規則如下

  • 驅動程式不得在原子提交路徑中查詢 allow_modeset。請改用 drm_atomic_crtc_needs_modeset()

  • 驅動程式必須在透過呼叫 drm_atomic_get_crtc_state() 將不相關的 struct drm_crtc_state 新增到此提交之前查詢 allow_modeset。另請參閱該函式文件中的警告。

  • 驅動程式不得更改此標誌,它受使用者空間的獨家控制。

  • 驅動程式可以在原子檢查路徑中查詢 allow_modeset,如果它們可以選擇需要模式設定的最佳硬體配置,以及可以在沒有模式設定的情況下提交的次優配置。一個例子是次優的掃描輸出 FIFO 分配導致空閒功耗增加。這允許使用者空間以合理的成本避免正常組合迴圈的閃爍和延遲。

legacy_cursor_update

強制執行舊游標 IOCTL 語義的提示。

警告:這完全損壞並且幾乎不可能正確實現。驅動程式必須忽略此項,而應實現 drm_plane_helper_funcs.atomic_async_checkdrm_plane_helper_funcs.atomic_async_commit hook。不允許使用此標誌的新使用者。

async_update

用於非同步平面更新的提示

duplicated

指示此原子狀態是否使用 drm_atomic_helper_duplicate_state() 複製。驅動程式和原子助手應使用它來修復複製狀態中的正常不一致。

planes

指向屬於此更新的 drm_planedrm_plane_state 陣列的指標。

crtcs

指向屬於此更新的 drm_crtcdrm_crtc_state 陣列的指標。

num_connector

connectors 陣列的大小

connectors

指向屬於此更新的 drm_connectordrm_connector_state 陣列的指標。

num_private_objs

private_objs 陣列的大小

private_objs

指向屬於此更新的 drm_private_objdrm_private_obj_state 陣列的指標。

acquire_ctx

此原子模式設定狀態更新的獲取上下文

fake_commit

用於發出未繫結平面/聯結器的訊號。當聯結器或平面未繫結到任何 CRTC 時,保持線性以防止過早釋放原子狀態仍然很重要。

此提交(如果設定)未繫結到任何 CRTC,但將在呼叫 drm_atomic_helper_commit_hw_done() 時完成。

commit_work

工作項,驅動程式或助手可以使用它來執行提交而不阻塞。

描述

此結構是 drm_mode_atomic 的核心對應物,表示從舊顯示狀態轉換到新顯示狀態的原子提交。它包含受原子提交影響的所有物件,以及這些物件的新狀態結構和指向舊狀態結構的指標。

透過呼叫 drm_atomic_get_crtc_state()drm_atomic_get_plane_state()drm_atomic_get_connector_state() 或對於私有狀態結構,drm_atomic_get_private_obj_state() 將狀態新增到原子更新中。

在 atomic_check 時,您可以從 drm_atomic_state 獲取即將提交的狀態,並從實體狀態指標(例如 drm_crtc.state)獲取當前執行的狀態。在呼叫 drm_atomic_helper_swap_state() 之後,實體狀態指標將包含先前檢查的狀態,而 drm_atomic_state 結構將包含舊狀態。

隨著時間的推移,為了避免混淆,drm_atomic_state 已經發展為同時具有舊狀態(即,我們替換的狀態)和新狀態(即,我們想要應用的狀態)。這些名稱在提交過程中是穩定的,這使得推理更容易。

您仍然可以透過一些採用名為“old_state”的 drm_atomic_state 引數的 hook 或回撥來找到該演變的痕跡。這不一定意味著傳遞了先前的 drm_atomic_state,而是說這曾經是我們 drm_atomic_helper_swap_state() 之後替換的狀態集合,但變數名稱從未更新。

一些原子操作實現遵循類似的過程。我們首先開始僅傳遞實體狀態。然而,對於驅動程式,尤其是 CRTC,檢索其他元件的狀態非常麻煩。因此,我們切換為將整個 drm_atomic_state 作為引數傳遞給這些操作。同樣,過渡尚未完成,並且可能仍然找到採用 drm_atomic_state 指標或元件狀態指標的原子操作。前者是首選形式。

注意

struct drm_atomic_state 首先開始作為實體狀態指標(drm_plane_state、drm_crtc_state 等)的單個集合。

struct drm_crtc_commit *drm_crtc_commit_get(struct drm_crtc_commit *commit)

獲取對 CRTC 提交的引用

引數

struct drm_crtc_commit *commit

CRTC 提交

描述

增加 commit 的引用。

返回

指向 commit 的指標,引用增加。

void drm_crtc_commit_put(struct drm_crtc_commit *commit)

釋放對 CRTC 提交的引用

引數

struct drm_crtc_commit *commit

CRTC 提交

描述

這會釋放對 commit 的引用,該引用在刪除最終引用後釋放。不需要鎖定,並且可以從任何上下文呼叫。

struct drm_atomic_state *drm_atomic_state_get(struct drm_atomic_state *state)

獲取對原子狀態的引用

引數

struct drm_atomic_state *state

原子狀態

描述

返回對 state 的新引用

void drm_atomic_state_put(struct drm_atomic_state *state)

釋放對原子狀態的引用

引數

struct drm_atomic_state *state

原子狀態

描述

這會釋放對 state 的引用,該引用在刪除最終引用後釋放。不需要鎖定,並且可以從任何上下文呼叫。

struct drm_crtc_state *drm_atomic_get_existing_crtc_state(const struct drm_atomic_state *state, struct drm_crtc *crtc)

獲取 CRTC 狀態(如果存在)

引數

const struct drm_atomic_state *state

全域性原子狀態物件

struct drm_crtc *crtc

要獲取的 CRTC

描述

此函式返回給定 CRTC 的 CRTC 狀態,如果 CRTC 不屬於全域性原子狀態,則返回 NULL。

此函式已棄用,應改用 drm_atomic_get_old_crtc_statedrm_atomic_get_new_crtc_state

struct drm_crtc_state *drm_atomic_get_old_crtc_state(const struct drm_atomic_state *state, struct drm_crtc *crtc)

獲取舊的 CRTC 狀態(如果存在)

引數

const struct drm_atomic_state *state

全域性原子狀態物件

struct drm_crtc *crtc

要獲取的 CRTC

描述

此函式返回給定 CRTC 的舊 CRTC 狀態,如果 CRTC 不屬於全域性原子狀態,則返回 NULL。

struct drm_crtc_state *drm_atomic_get_new_crtc_state(const struct drm_atomic_state *state, struct drm_crtc *crtc)

獲取新的 CRTC 狀態(如果存在)

引數

const struct drm_atomic_state *state

全域性原子狀態物件

struct drm_crtc *crtc

要獲取的 CRTC

描述

此函式返回給定 CRTC 的新 CRTC 狀態,如果 CRTC 不屬於全域性原子狀態,則返回 NULL。

struct drm_plane_state *drm_atomic_get_existing_plane_state(const struct drm_atomic_state *state, struct drm_plane *plane)

獲取 plane 狀態(如果存在)

引數

const struct drm_atomic_state *state

全域性原子狀態物件

struct drm_plane *plane

要獲取的 plane

描述

此函式返回給定 plane 的 plane 狀態,如果 plane 不屬於全域性原子狀態,則返回 NULL。

此函式已棄用,應改用 drm_atomic_get_old_plane_statedrm_atomic_get_new_plane_state

struct drm_plane_state *drm_atomic_get_old_plane_state(const struct drm_atomic_state *state, struct drm_plane *plane)

獲取 plane 狀態(如果存在)

引數

const struct drm_atomic_state *state

全域性原子狀態物件

struct drm_plane *plane

要獲取的 plane

描述

此函式返回給定 plane 的舊 plane 狀態,如果 plane 不屬於全域性原子狀態,則返回 NULL。

struct drm_plane_state *drm_atomic_get_new_plane_state(const struct drm_atomic_state *state, struct drm_plane *plane)

獲取 plane 狀態(如果存在)

引數

const struct drm_atomic_state *state

全域性原子狀態物件

struct drm_plane *plane

要獲取的 plane

描述

此函式返回給定 plane 的新 plane 狀態,如果 plane 不屬於全域性原子狀態,則返回 NULL。

struct drm_connector_state *drm_atomic_get_existing_connector_state(const struct drm_atomic_state *state, struct drm_connector *connector)

獲取 connector 狀態(如果存在)

引數

const struct drm_atomic_state *state

全域性原子狀態物件

struct drm_connector *connector

要獲取的 connector

描述

此函式返回給定 connector 的 connector 狀態,如果 connector 不屬於全域性原子狀態,則返回 NULL。

此函式已棄用,應改用 drm_atomic_get_old_connector_statedrm_atomic_get_new_connector_state

struct drm_connector_state *drm_atomic_get_old_connector_state(const struct drm_atomic_state *state, struct drm_connector *connector)

獲取 connector 狀態(如果存在)

引數

const struct drm_atomic_state *state

全域性原子狀態物件

struct drm_connector *connector

要獲取的 connector

描述

此函式返回給定 connector 的舊 connector 狀態,如果 connector 不屬於全域性原子狀態,則返回 NULL。

struct drm_connector_state *drm_atomic_get_new_connector_state(const struct drm_atomic_state *state, struct drm_connector *connector)

獲取 connector 狀態(如果存在)

引數

const struct drm_atomic_state *state

全域性原子狀態物件

struct drm_connector *connector

要獲取的 connector

描述

此函式返回給定 connector 的新 connector 狀態,如果 connector 不屬於全域性原子狀態,則返回 NULL。

const struct drm_plane_state *__drm_atomic_get_current_plane_state(const struct drm_atomic_state *state, struct drm_plane *plane)

獲取當前的 plane 狀態

引數

const struct drm_atomic_state *state

全域性原子狀態物件

struct drm_plane *plane

要獲取的 plane

描述

此函式返回給定 plane 的 plane 狀態,如果該 plane 不屬於原子狀態更新,則從 state 返回,否則從 plane 返回。 這在原子檢查回撥中很有用,因為驅動程式需要檢視但不更改其他 plane 的狀態,因為它避免了將錯誤程式碼向上傳遞呼叫鏈。

警告

請注意,此函式通常是不安全的,因為它不檢查訪問狀態結構所需的鎖定。 驅動程式必須確保透過其他方式訪問返回的狀態結構是安全的。 一個常見的例子是,當 plane 固定到單個 CRTC 時,驅動程式知道已經保持了 CRTC 鎖。 在這種情況下,保持 CRTC 鎖可以對連線到該 CRTC 的所有 plane 進行讀取鎖定。 但是,如果可以重新分配 plane,情況會變得更加棘手。 在這種情況下,最好使用 drm_atomic_get_plane_state 並連線完整的錯誤處理。

指向當前 plane 狀態的只讀指標。

for_each_oldnew_connector_in_state

for_each_oldnew_connector_in_state (__state, connector, old_connector_state, new_connector_state, __i)

迭代原子更新中的所有 connector

引數

__state

struct drm_atomic_state 指標

connector

struct drm_connector 迭代游標

old_connector_state

struct drm_connector_state 舊狀態的迭代游標

new_connector_state

struct drm_connector_state 新狀態的迭代游標

__i

int 迭代游標,用於宏內部使用

描述

這會迭代原子更新中的所有 connector,跟蹤舊狀態和新狀態。 這在需要考慮狀態增量的地方很有用,例如在原子檢查函式中。

for_each_old_connector_in_state

for_each_old_connector_in_state (__state, connector, old_connector_state, __i)

迭代原子更新中的所有 connector

引數

__state

struct drm_atomic_state 指標

connector

struct drm_connector 迭代游標

old_connector_state

struct drm_connector_state 舊狀態的迭代游標

__i

int 迭代游標,用於宏內部使用

描述

這會迭代原子更新中的所有 connector,僅跟蹤舊狀態。 這在停用函式中很有用,我們需要硬體仍在使用的舊狀態。

for_each_new_connector_in_state

for_each_new_connector_in_state (__state, connector, new_connector_state, __i)

迭代原子更新中的所有 connector

引數

__state

struct drm_atomic_state 指標

connector

struct drm_connector 迭代游標

new_connector_state

struct drm_connector_state 新狀態的迭代游標

__i

int 迭代游標,用於宏內部使用

描述

這會迭代原子更新中的所有 connector,僅跟蹤新狀態。 這在啟用函式中很有用,我們需要硬體在原子提交操作完成後應處於的新狀態。

for_each_oldnew_crtc_in_state

for_each_oldnew_crtc_in_state (__state, crtc, old_crtc_state, new_crtc_state, __i)

迭代原子更新中的所有 CRTC

引數

__state

struct drm_atomic_state 指標

crtc

struct drm_crtc 迭代游標

old_crtc_state

struct drm_crtc_state 舊狀態的迭代游標

new_crtc_state

struct drm_crtc_state 新狀態的迭代游標

__i

int 迭代游標,用於宏內部使用

描述

這會迭代原子更新中的所有 CRTC,跟蹤舊狀態和新狀態。 這在需要考慮狀態增量的地方很有用,例如在原子檢查函式中。

for_each_old_crtc_in_state

for_each_old_crtc_in_state (__state, crtc, old_crtc_state, __i)

迭代原子更新中的所有 CRTC

引數

__state

struct drm_atomic_state 指標

crtc

struct drm_crtc 迭代游標

old_crtc_state

struct drm_crtc_state 舊狀態的迭代游標

__i

int 迭代游標,用於宏內部使用

描述

這會迭代原子更新中的所有 CRTC,僅跟蹤舊狀態。 這在停用函式中很有用,我們需要硬體仍在使用的舊狀態。

for_each_new_crtc_in_state

for_each_new_crtc_in_state (__state, crtc, new_crtc_state, __i)

迭代原子更新中的所有 CRTC

引數

__state

struct drm_atomic_state 指標

crtc

struct drm_crtc 迭代游標

new_crtc_state

struct drm_crtc_state 新狀態的迭代游標

__i

int 迭代游標,用於宏內部使用

描述

這會迭代原子更新中的所有 CRTC,僅跟蹤新狀態。 這在啟用函式中很有用,我們需要硬體在原子提交操作完成後應處於的新狀態。

for_each_oldnew_plane_in_state

for_each_oldnew_plane_in_state (__state, plane, old_plane_state, new_plane_state, __i)

迭代原子更新中的所有 plane

引數

__state

struct drm_atomic_state 指標

plane

struct drm_plane 迭代游標

old_plane_state

struct drm_plane_state 舊狀態的迭代游標

new_plane_state

struct drm_plane_state 新狀態的迭代游標

__i

int 迭代游標,用於宏內部使用

描述

這會迭代原子更新中的所有 plane,跟蹤舊狀態和新狀態。 這在需要考慮狀態增量的地方很有用,例如在原子檢查函式中。

for_each_oldnew_plane_in_state_reverse

for_each_oldnew_plane_in_state_reverse (__state, plane, old_plane_state, new_plane_state, __i)

以相反的順序迭代原子更新中的所有 plane

引數

__state

struct drm_atomic_state 指標

plane

struct drm_plane 迭代游標

old_plane_state

struct drm_plane_state 舊狀態的迭代游標

new_plane_state

struct drm_plane_state 新狀態的迭代游標

__i

int 迭代游標,用於宏內部使用

描述

這會以相反的順序迭代原子更新中的所有 plane,跟蹤舊狀態和新狀態。 這在需要考慮狀態增量的地方很有用,例如在原子檢查函式中。

for_each_new_plane_in_state_reverse

for_each_new_plane_in_state_reverse (__state, plane, new_plane_state, __i)

除了僅跟蹤新狀態之外,它與 for_each_oldnew_plane_in_state_reverse 相同

引數

__state

struct drm_atomic_state 指標

plane

struct drm_plane 迭代游標

new_plane_state

struct drm_plane_state 新狀態的迭代游標

__i

int 迭代游標,用於宏內部使用

for_each_old_plane_in_state

for_each_old_plane_in_state (__state, plane, old_plane_state, __i)

迭代原子更新中的所有 plane

引數

__state

struct drm_atomic_state 指標

plane

struct drm_plane 迭代游標

old_plane_state

struct drm_plane_state 舊狀態的迭代游標

__i

int 迭代游標,用於宏內部使用

描述

這會迭代原子更新中的所有 plane,僅跟蹤舊狀態。 這在停用函式中很有用,我們需要硬體仍在使用的舊狀態。

for_each_new_plane_in_state

for_each_new_plane_in_state (__state, plane, new_plane_state, __i)

迭代原子更新中的所有 plane

引數

__state

struct drm_atomic_state 指標

plane

struct drm_plane 迭代游標

new_plane_state

struct drm_plane_state 新狀態的迭代游標

__i

int 迭代游標,用於宏內部使用

描述

此函式迭代原子更新中的所有平面,僅跟蹤新狀態。這在啟用函式中非常有用,在這些函式中,我們需要在原子提交操作完成後硬體應處於的新狀態。

for_each_oldnew_private_obj_in_state

for_each_oldnew_private_obj_in_state (__state, obj, old_obj_state, new_obj_state, __i)

迭代原子更新中的所有私有物件

引數

__state

struct drm_atomic_state 指標

obj

struct drm_private_obj 迭代遊標

old_obj_state

struct drm_private_state 舊狀態的迭代遊標

new_obj_state

struct drm_private_state 新狀態的迭代遊標

__i

int 迭代游標,用於宏內部使用

描述

此函式迭代原子更新中的所有私有物件,同時跟蹤舊狀態和新狀態。這在需要考慮狀態增量的地方非常有用,例如在原子檢查函式中。

for_each_old_private_obj_in_state

for_each_old_private_obj_in_state (__state, obj, old_obj_state, __i)

迭代原子更新中的所有私有物件

引數

__state

struct drm_atomic_state 指標

obj

struct drm_private_obj 迭代遊標

old_obj_state

struct drm_private_state 舊狀態的迭代遊標

__i

int 迭代游標,用於宏內部使用

描述

此函式迭代原子更新中的所有私有物件,僅跟蹤舊狀態。這在停用函式中非常有用,在這些函式中,我們需要硬體仍然處於的舊狀態。

for_each_new_private_obj_in_state

for_each_new_private_obj_in_state (__state, obj, new_obj_state, __i)

迭代原子更新中的所有私有物件

引數

__state

struct drm_atomic_state 指標

obj

struct drm_private_obj 迭代遊標

new_obj_state

struct drm_private_state 新狀態的迭代遊標

__i

int 迭代游標,用於宏內部使用

描述

此函式迭代原子更新中的所有私有物件,僅跟蹤新狀態。這在啟用函式中非常有用,在這些函式中,我們需要在原子提交操作完成後硬體應處於的新狀態。

bool drm_atomic_crtc_needs_modeset(const struct drm_crtc_state *state)

計算組合的模式設定需求

引數

const struct drm_crtc_state *state

CRTC 的 drm_crtc_state

描述

為了給驅動程式靈活性,struct drm_crtc_state 具有 3 個布林值來跟蹤狀態 CRTC 是否發生了足夠的改變,需要完整的模式設定週期:mode_changed、active_changed 和 connectors_changed。此輔助函式簡單地將這三個值組合起來,以計算 **state** 的模式設定的總體需求。

原子輔助程式碼設定這些布林值,但驅動程式可以並且應該適當地更改它們,以準確地表示是否真的需要模式設定。通常,驅動程式應儘可能避免完整的模式設定。

例如,如果 CRTC 模式已更改,並且硬體能夠在不經過完整的模式設定的情況下實現所請求的模式更改,則驅動程式應在其 drm_mode_config_funcs.atomic_check 實現中清除 mode_changed。

bool drm_atomic_crtc_effectively_active(const struct drm_crtc_state *state)

計算 CRTC 是否實際處於活動狀態

引數

const struct drm_crtc_state *state

CRTC 的 drm_crtc_state

描述

在自重新整理模式下,crtc_state->active 值將為 false,因為 CRTC 已關閉。但是,在某些情況下,我們對 CRTC 是否處於活動狀態或有效活動狀態(即:它是否連線到活動顯示器)感興趣。在這些情況下,請使用此函式而不是僅檢查活動狀態。

struct drm_bus_cfg

匯流排配置

定義:

struct drm_bus_cfg {
    u32 format;
    u32 flags;
};

成員

格式

在此總線上使用的格式(MEDIA_BUS_FMT_* 格式之一)

驅動程式不應直接修改此欄位 (drm_atomic_bridge_chain_select_bus_fmts() 負責匯流排格式協商)。

標誌

在此總線上使用的 DRM_BUS_* 標誌

描述

此結構儲存輸出管道中兩個元件之間(通常是兩個橋接器、編碼器和橋接器,或橋接器和聯結器之間)的物理匯流排的配置。

匯流排配置儲存在 drm_bridge_state 中,對於輸入匯流排和輸出匯流排分別儲存,從每個橋接器的角度來看。橋接器輸出的匯流排配置通常與下一個橋接器的輸入的配置相同,但如果在兩個橋接器之間修改訊號,例如透過板上的反相器,則可能會有所不同。如果橋接器在內部修改訊號(例如透過執行格式轉換或修改訊號極性),則橋接器的輸入和輸出配置可能會有所不同。

struct drm_bridge_state

原子橋接器狀態物件

定義:

struct drm_bridge_state {
    struct drm_private_state base;
    struct drm_bridge *bridge;
    struct drm_bus_cfg input_bus_cfg;
    struct drm_bus_cfg output_bus_cfg;
};

成員

基本

繼承自 drm_private_state

橋接器

此狀態引用的橋接器

input_bus_cfg

輸入匯流排配置

output_bus_cfg

輸出匯流排配置

int drm_crtc_commit_wait(struct drm_crtc_commit *commit)

等待提交完成

引數

struct drm_crtc_commit *commit

要等待的 drm_crtc_commit

描述

等待給定的 drm_crtc_commit 被程式設計到硬體中並翻轉到。

返回

成功時返回 0,否則返回負錯誤程式碼。

void drm_atomic_state_default_release(struct drm_atomic_state *state)

釋放 drm_atomic_state_init 初始化的記憶體

引數

struct drm_atomic_state *state

原子狀態

描述

釋放 drm_atomic_state_init 分配的所有記憶體。這應該只由仍然對 drm_atomic_state 進行子類化且尚未切換到 drm_private_state 的驅動程式使用。

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

初始化新的原子狀態

引數

struct drm_device *dev

DRM 裝置

struct drm_atomic_state *state

原子狀態

描述

用於填充新原子狀態的預設實現。這應該只由仍然對 drm_atomic_state 進行子類化且尚未切換到 drm_private_state 的驅動程式使用。

struct drm_atomic_state *drm_atomic_state_alloc(struct drm_device *dev)

分配原子狀態

引數

struct drm_device *dev

DRM 裝置

描述

這將分配一個空的原子狀態以跟蹤更新。

void drm_atomic_state_default_clear(struct drm_atomic_state *state)

清除基本原子狀態

引數

struct drm_atomic_state *state

原子狀態

描述

用於清除原子狀態的預設實現。這應該只由仍然對 drm_atomic_state 進行子類化且尚未切換到 drm_private_state 的驅動程式使用。

void drm_atomic_state_clear(struct drm_atomic_state *state)

清除狀態物件

引數

struct drm_atomic_state *state

原子狀態

描述

當 w/w 互斥演算法檢測到死鎖時,我們需要退出並刪除所有鎖。因此,其他人可能會偷偷進入並更改當前的模式設定配置。這意味著 **state** 中組裝的所有狀態不再是對當前狀態的原子更新,而是對一些任意的早期狀態的更新。這可能會破壞驅動程式的 drm_mode_config_funcs.atomic_check 可能依賴的假設。

因此,我們必須清除所有快取的狀態並使用此函式完全重新開始。

void __drm_atomic_state_free(struct kref *ref)

釋放原子狀態的所有記憶體

引數

struct kref *ref

要取消分配的原子狀態

描述

這會釋放與原子狀態關聯的所有記憶體,包括平面、CRTC 和聯結器的所有按物件狀態。

struct drm_crtc_state *drm_atomic_get_crtc_state(struct drm_atomic_state *state, struct drm_crtc *crtc)

獲取 CRTC 狀態

引數

struct drm_atomic_state *state

全域性原子狀態物件

struct drm_crtc *crtc

要獲取狀態物件的 CRTC

描述

此函式返回給定 CRTC 的 CRTC 狀態,如果需要,則分配它。它還將獲取相關的 CRTC 鎖,以確保狀態一致。

警告:只有在設定了 drm_atomic_state.allow_modeset 時,或者如果是使用者空間透過 IOCTL 呼叫建立的驅動程式內部提交,驅動程式才能向 **state** 新增新的 CRTC 狀態。

返回

分配的狀態或編碼到指標中的錯誤程式碼。當錯誤為 EDEADLK 時,w/w 互斥程式碼檢測到死鎖,必須重新啟動整個原子序列。所有其他錯誤都是致命的。

struct drm_plane_state *drm_atomic_get_plane_state(struct drm_atomic_state *state, struct drm_plane *plane)

獲取平面狀態

引數

struct drm_atomic_state *state

全域性原子狀態物件

struct drm_plane *plane

要獲取狀態物件的平面

描述

此函式返回給定平面的平面狀態,如果需要,則分配它。它還將獲取相關的平面鎖,以確保狀態一致。

返回

分配的狀態或編碼到指標中的錯誤程式碼。當錯誤為 EDEADLK 時,w/w 互斥程式碼檢測到死鎖,必須重新啟動整個原子序列。所有其他錯誤都是致命的。

void drm_atomic_private_obj_init(struct drm_device *dev, struct drm_private_obj *obj, struct drm_private_state *state, const struct drm_private_state_funcs *funcs)

初始化私有物件

引數

struct drm_device *dev

此物件將附加到的 DRM 裝置

struct drm_private_obj *obj

私有物件

struct drm_private_state *state

初始私有物件狀態

const struct drm_private_state_funcs *funcs

指向標識物件型別的函式指標結構的指標

描述

初始化私有物件,該物件可以嵌入到任何需要自己的原子狀態的驅動程式私有物件中。

void drm_atomic_private_obj_fini(struct drm_private_obj *obj)

完成私有物件

引數

struct drm_private_obj *obj

私有物件

描述

完成私有物件。

struct drm_private_state *drm_atomic_get_private_obj_state(struct drm_atomic_state *state, struct drm_private_obj *obj)

獲取私有物件狀態

引數

struct drm_atomic_state *state

全域性原子狀態

struct drm_private_obj *obj

要獲取狀態的私有物件

描述

此函式返回給定私有物件的私有物件狀態,如果需要,則分配該狀態。它還將獲取相關的私有物件鎖,以確保狀態一致。

返回

分配的狀態或編碼為指標的錯誤程式碼。

struct drm_private_state *drm_atomic_get_old_private_obj_state(const struct drm_atomic_state *state, struct drm_private_obj *obj)

引數

const struct drm_atomic_state *state

全域性原子狀態物件

struct drm_private_obj *obj

要獲取的private_obj

描述

此函式返回給定 private_obj 的舊的私有物件狀態,如果 private_obj 不是全域性原子狀態的一部分,則返回 NULL。

struct drm_private_state *drm_atomic_get_new_private_obj_state(const struct drm_atomic_state *state, struct drm_private_obj *obj)

引數

const struct drm_atomic_state *state

全域性原子狀態物件

struct drm_private_obj *obj

要獲取的private_obj

描述

此函式返回給定 private_obj 的新的私有物件狀態,如果 private_obj 不是全域性原子狀態的一部分,則返回 NULL。

struct drm_connector *drm_atomic_get_old_connector_for_encoder(const struct drm_atomic_state *state, struct drm_encoder *encoder)

獲取編碼器的舊聯結器

引數

const struct drm_atomic_state *state

原子狀態

struct drm_encoder *encoder

要獲取聯結器狀態的編碼器

描述

此函式查詢並返回由 state 指定的連線到 encoder 的聯結器。

如果在 state 中沒有之前連線到 encoder 的聯結器,則此函式將返回 NULL。雖然這看起來像是一個無效的用例,但有時區分沒有連線到 encoder 的先前聯結器的提交與確實連線的提交(並檢查它們的狀態)很有用。這在啟用鉤子中尤其如此,因為管道已更改。

如果您無法訪問原子狀態,請參閱 drm_atomic_get_connector_for_encoder()

返回

連線到 encoder 的舊聯結器,如果編碼器未連線,則為 NULL。

struct drm_connector *drm_atomic_get_new_connector_for_encoder(const struct drm_atomic_state *state, struct drm_encoder *encoder)

獲取編碼器的新聯結器

引數

const struct drm_atomic_state *state

原子狀態

struct drm_encoder *encoder

要獲取聯結器狀態的編碼器

描述

此函式查詢並返回由 state 指定的將連線到 encoder 的聯結器。

如果在 state 中沒有將連線到 encoder 的聯結器,則此函式將返回 NULL。雖然這看起來像是一個無效的用例,但有時區分沒有連線到 encoder 的聯結器的提交與確實連線的提交(並檢查它們的狀態)很有用。這在停用鉤子中尤其如此,因為管道將更改。

如果您無法訪問原子狀態,請參閱 drm_atomic_get_connector_for_encoder()

返回

連線到 encoder 的新聯結器,如果編碼器未連線,則為 NULL。

struct drm_connector *drm_atomic_get_connector_for_encoder(const struct drm_encoder *encoder, struct drm_modeset_acquire_ctx *ctx)

獲取當前分配給編碼器的聯結器

引數

const struct drm_encoder *encoder

要查詢聯結器的編碼器

struct drm_modeset_acquire_ctx *ctx

Modeset 鎖定上下文

描述

此函式查詢並返回當前分配給 encoder 的聯結器。

它類似於 drm_atomic_get_old_connector_for_encoder()drm_atomic_get_new_connector_for_encoder() 助手,但不需要訪問原子狀態。如果您可以訪問它,請首選使用這些。此助手通常在您無法訪問原子狀態的情況下很有用,例如檢測、連結修復、執行緒化中斷處理程式或其他框架(ALSA、CEC 等)中的鉤子。

返回

連線到 encoder 的聯結器,否則為錯誤指標。當錯誤為 EDEADLK 時,已檢測到死鎖,必須重新啟動該序列。

struct drm_crtc *drm_atomic_get_old_crtc_for_encoder(struct drm_atomic_state *state, struct drm_encoder *encoder)

獲取編碼器的舊 crtc

引數

struct drm_atomic_state *state

原子狀態

struct drm_encoder *encoder

要獲取 crtc 狀態的編碼器

描述

此函式查詢並返回由 state 指定的連線到 encoder 的 crtc。

返回

連線到 encoder 的舊 crtc,如果編碼器未連線,則為 NULL。

struct drm_crtc *drm_atomic_get_new_crtc_for_encoder(struct drm_atomic_state *state, struct drm_encoder *encoder)

獲取編碼器的新 crtc

引數

struct drm_atomic_state *state

原子狀態

struct drm_encoder *encoder

要獲取 crtc 狀態的編碼器

描述

此函式查詢並返回由 state 指定的將連線到 encoder 的 crtc。

返回

連線到 encoder 的新 crtc,如果編碼器未連線,則為 NULL。

struct drm_connector_state *drm_atomic_get_connector_state(struct drm_atomic_state *state, struct drm_connector *connector)

獲取聯結器狀態

引數

struct drm_atomic_state *state

全域性原子狀態物件

struct drm_connector *connector

要獲取狀態物件的聯結器

描述

此函式返回給定聯結器的聯結器狀態,並在需要時分配它。它還將獲取相關的聯結器鎖,以確保狀態是一致的。

返回

分配的狀態或編碼到指標中的錯誤程式碼。當錯誤為 EDEADLK 時,w/w 互斥程式碼檢測到死鎖,必須重新啟動整個原子序列。所有其他錯誤都是致命的。

struct drm_bridge_state *drm_atomic_get_bridge_state(struct drm_atomic_state *state, struct drm_bridge *bridge)

獲取橋接狀態

引數

struct drm_atomic_state *state

全域性原子狀態物件

struct drm_bridge *bridge

要獲取狀態物件的橋接

描述

此函式返回給定橋接的橋接狀態,並在需要時分配它。它還將獲取相關的橋接鎖,以確保狀態是一致的。

返回

分配的狀態或編碼到指標中的錯誤程式碼。當錯誤為 EDEADLK 時,w/w 互斥程式碼已檢測到死鎖,必須重新啟動整個原子序列。

struct drm_bridge_state *drm_atomic_get_old_bridge_state(const struct drm_atomic_state *state, struct drm_bridge *bridge)

獲取舊的橋接狀態(如果存在)

引數

const struct drm_atomic_state *state

全域性原子狀態物件

struct drm_bridge *bridge

要抓取的橋接

描述

此函式返回給定橋接的舊的橋接狀態,如果該橋接不是全域性原子狀態的一部分,則返回 NULL。

struct drm_bridge_state *drm_atomic_get_new_bridge_state(const struct drm_atomic_state *state, struct drm_bridge *bridge)

獲取新的橋接狀態(如果存在)

引數

const struct drm_atomic_state *state

全域性原子狀態物件

struct drm_bridge *bridge

要抓取的橋接

描述

此函式返回給定橋接的新的橋接狀態,如果該橋接不是全域性原子狀態的一部分,則返回 NULL。

int drm_atomic_add_encoder_bridges(struct drm_atomic_state *state, struct drm_encoder *encoder)

新增連線到編碼器的橋接

引數

struct drm_atomic_state *state

原子狀態

struct drm_encoder *encoder

DRM 編碼器

描述

此函式新增連線到 encoder 的所有橋接。需要將橋接狀態新增到 state,並在呼叫 drm_bridge_funcs.atomic_check()drm_bridge_funcs.atomic_pre_enable()drm_bridge_funcs.atomic_enable()drm_bridge_funcs.atomic_disable_post_disable() 時使它們可用。

返回

成功時返回 0,或在出現 -EDEADLK 或 -ENOMEM 錯誤時失敗。當錯誤為 EDEADLK 時,w/w 互斥程式碼已檢測到死鎖,必須重新啟動整個原子序列。所有其他錯誤都是致命的。

int drm_atomic_add_affected_connectors(struct drm_atomic_state *state, struct drm_crtc *crtc)

為 CRTC 新增聯結器

引數

struct drm_atomic_state *state

原子狀態

struct drm_crtc *crtc

DRM CRTC

描述

此函式遍歷當前配置,並將當前使用 crtc 的所有聯結器新增到原子配置 state。請注意,此函式必須獲取連線互斥鎖。如果更新僅適用於一個 CRTC 上的平面,這可能會導致不必要的序列化。因此,驅動程式和助手應僅在真正需要時才呼叫此函式(例如,由於某些更改而需要進行完整的模式設定時)。

返回

成功時返回 0,或在出現 -EDEADLK 或 -ENOMEM 錯誤時失敗。當錯誤為 EDEADLK 時,w/w 互斥程式碼已檢測到死鎖,必須重新啟動整個原子序列。所有其他錯誤都是致命的。

int drm_atomic_add_affected_planes(struct drm_atomic_state *state, struct drm_crtc *crtc)

為 CRTC 新增平面

引數

struct drm_atomic_state *state

原子狀態

struct drm_crtc *crtc

DRM CRTC

描述

此函式遍歷當前配置,並將 crtc 當前使用的所有平面新增到原子配置 state。當原子提交還需要檢查 crtc 上的所有當前已啟用平面時(例如,在更改模式時),這非常有用。在重新啟用 CRTC 時,避免強制啟用所有平面的特殊程式碼也很有用。

由於獲取平面狀態始終還會獲取該平面當前 CRTC 的 w/w 互斥鎖(如果存在),因此新增 CRTC 的所有平面狀態不會降低原子更新的並行性。

返回

成功時返回 0,或在出現 -EDEADLK 或 -ENOMEM 錯誤時失敗。當錯誤為 EDEADLK 時,w/w 互斥程式碼已檢測到死鎖,必須重新啟動整個原子序列。所有其他錯誤都是致命的。

int drm_atomic_check_only(struct drm_atomic_state *state)

檢查給定的配置是否有效

引數

struct drm_atomic_state *state

要檢查的原子配置

描述

請注意,如果驅動程式需要獲取更多鎖但遇到死鎖,則此函式可能會返回 -EDEADLK。然後,呼叫方必須執行通常的 w/w 回退舞並重新啟動。所有其他錯誤都是致命的。

返回

成功時返回 0,失敗時返回負錯誤程式碼。

int drm_atomic_commit(struct drm_atomic_state *state)

以原子方式提交配置

引數

struct drm_atomic_state *state

要檢查的原子配置

描述

請注意,如果驅動程式需要獲取更多鎖但遇到死鎖,則此函式可能會返回 -EDEADLK。然後,呼叫方必須執行通常的 w/w 回退舞並重新啟動。所有其他錯誤都是致命的。

此函式將採用 state 上的自身引用。呼叫方應始終使用 drm_atomic_state_put() 釋放其引用。

返回

成功時返回 0,失敗時返回負錯誤程式碼。

int drm_atomic_nonblocking_commit(struct drm_atomic_state *state)

原子非阻塞提交

引數

struct drm_atomic_state *state

要檢查的原子配置

描述

請注意,如果驅動程式需要獲取更多鎖但遇到死鎖,則此函式可能會返回 -EDEADLK。然後,呼叫方必須執行通常的 w/w 回退舞並重新啟動。所有其他錯誤都是致命的。

此函式將採用 state 上的自身引用。呼叫方應始終使用 drm_atomic_state_put() 釋放其引用。

返回

成功時返回 0,失敗時返回負錯誤程式碼。

void drm_atomic_print_new_state(const struct drm_atomic_state *state, struct drm_printer *p)

列印drm原子狀態

引數

const struct drm_atomic_state *state

要檢查的原子配置

struct drm_printer *p

drm印表機

描述

此函式使用傳遞給它的drm印表機列印drm原子狀態快照。此快照可用於除錯目的。

請注意,此函式會檢視新的狀態物件,因此在呼叫drm_atomic_helper_commit_hw_done()之後使用它是不安全的。

void drm_state_dump(struct drm_device *dev, struct drm_printer *p)

轉儲整個裝置原子狀態

引數

struct drm_device *dev

drm裝置

struct drm_printer *p

狀態列印到哪裡

描述

僅用於除錯。驅動程式可能希望在錯誤 irq 的情況下選擇將狀態轉儲到 dmesg。(提示,您可能想要速率限制它!)

呼叫者必須包裝drm_modeset_lock_all_ctx()drm_modeset_drop_locks()。 如果從錯誤 irq 處理程式呼叫此函式,則預設情況下不應啟用 - 如果您正在除錯錯誤,您可能不關心這是競爭的,但在未持有所有模式設定鎖的情況下呼叫此函式本質上是不安全的。

原子模式設定 IOCTL 和 UAPI 函式

此檔案包含所有形式的原子 UAPI 的編組和解組粘合程式碼:怪物 ATOMIC IOCTL 本身,GET_PROPERTY 和 SET_PROPERTY IOCTL 的程式碼。 加上相容性輔助程式和驅動程式的介面函式,這些輔助程式和驅動程式有特殊的需求來構造自己的原子更新,例如,用於負載檢測或類似目的。

int drm_atomic_set_mode_for_crtc(struct drm_crtc_state *state, const struct drm_display_mode *mode)

為CRTC設定模式

引數

struct drm_crtc_state *state

要更新的CRTC的傳入狀態

const struct drm_display_mode *mode

用於CRTC的核心內部模式,或停用時為NULL

描述

在所需的CRTC狀態上設定模式(源自核心),並更新enable屬性。

返回

成功時為零,失敗時為錯誤程式碼。不能返回-EDEADLK。

int drm_atomic_set_mode_prop_for_crtc(struct drm_crtc_state *state, struct drm_property_blob *blob)

為CRTC設定模式

引數

struct drm_crtc_state *state

要更新的CRTC的傳入狀態

struct drm_property_blob *blob

指向用於模式的blob屬性的指標

描述

在所需的CRTC狀態上設定模式(源自blob屬性)。此函式將獲取CRTC狀態的blob屬性的引用,並釋放狀態的現有模式屬性(如果已設定)上保留的引用。

返回

成功時為零,失敗時為錯誤程式碼。不能返回-EDEADLK。

int drm_atomic_set_crtc_for_plane(struct drm_plane_state *plane_state, struct drm_crtc *crtc)

為平面設定CRTC

引數

struct drm_plane_state *plane_state

要更新的平面的傳入狀態

struct drm_crtc *crtc

用於平面的CRTC

描述

更改平面的指定CRTC需要我們根據需要獲取新CRTC的鎖和狀態。 除了更新狀態物件本身的指標之外,此函式還處理所有這些細節。

返回

成功時返回 0,或在出現 -EDEADLK 或 -ENOMEM 錯誤時失敗。當錯誤為 EDEADLK 時,w/w 互斥程式碼已檢測到死鎖,必須重新啟動整個原子序列。所有其他錯誤都是致命的。

void drm_atomic_set_fb_for_plane(struct drm_plane_state *plane_state, struct drm_framebuffer *fb)

為平面設定幀緩衝區

引數

struct drm_plane_state *plane_state

平面的原子狀態物件

struct drm_framebuffer *fb

用於平面的fb

描述

更改平面的指定幀緩衝區需要我們獲取對新fb的引用並刪除對舊fb的引用(如果有)。 除了更新狀態物件本身的指標之外,此函式還處理所有這些細節。

int drm_atomic_set_crtc_for_connector(struct drm_connector_state *conn_state, struct drm_crtc *crtc)

為聯結器設定CRTC

引數

struct drm_connector_state *conn_state

聯結器的原子狀態物件

struct drm_crtc *crtc

用於聯結器的CRTC

描述

更改聯結器的指定CRTC需要我們根據需要獲取新CRTC的鎖和狀態。 除了更新狀態物件本身的指標之外,此函式還處理所有這些細節。

返回

成功時返回 0,或在出現 -EDEADLK 或 -ENOMEM 錯誤時失敗。當錯誤為 EDEADLK 時,w/w 互斥程式碼已檢測到死鎖,必須重新啟動整個原子序列。所有其他錯誤都是致命的。

CRTC抽象

CRTC表示整體顯示流水線。 它從drm_plane接收畫素資料並將它們混合在一起。 drm_display_mode也附加到CRTC,指定顯示時序。 在輸出端,資料被饋送到一個或多個drm_encoder,然後每個drm_encoder連線到一個drm_connector

要建立CRTC,KMS驅動程式分配並將struct drm_crtc的一個例項(可能作為更大的結構的一部分)歸零,並透過呼叫drm_crtc_init_with_planes()註冊它。

CRTC也是傳統模式設定操作的入口點(請參閱drm_crtc_funcs.set_config),傳統平面操作(請參閱drm_crtc_funcs.page_flipdrm_crtc_funcs.cursor_set2)以及其他傳統操作(如drm_crtc_funcs.gamma_set)。 對於原子驅動程式,所有這些功能都透過drm_propertydrm_mode_config_funcs.atomic_check控制。

CRTC函式參考

struct drm_crtc_state

可變的CRTC狀態

定義:

struct drm_crtc_state {
    struct drm_crtc *crtc;
    bool enable;
    bool active;
    bool planes_changed : 1;
    bool mode_changed : 1;
    bool active_changed : 1;
    bool connectors_changed : 1;
    bool zpos_changed : 1;
    bool color_mgmt_changed : 1;
    bool no_vblank : 1;
    u32 plane_mask;
    u32 connector_mask;
    u32 encoder_mask;
    struct drm_display_mode adjusted_mode;
    struct drm_display_mode mode;
    struct drm_property_blob *mode_blob;
    struct drm_property_blob *degamma_lut;
    struct drm_property_blob *ctm;
    struct drm_property_blob *gamma_lut;
    u32 target_vblank;
    bool async_flip;
    bool vrr_enabled;
    bool self_refresh_active;
    enum drm_scaling_filter scaling_filter;
    struct drm_pending_vblank_event *event;
    struct drm_crtc_commit *commit;
    struct drm_atomic_state *state;
};

成員

crtc

返回到CRTC的指標

啟用

是否應啟用CRTC,門控所有其他狀態。 這控制共享資源的預留。 實際硬體狀態由active控制。

active

CRTC是否正在主動顯示(用於DPMS)。 意味著設定了enable。 如果將active設定為false但enable仍為true,則驅動程式不得釋放任何共享資源,因為使用者空間期望DPMS ON始終成功。

因此,驅動程式不得在其各種drm_mode_config_funcs.atomic_check回撥中查詢active以拒絕原子提交。 它們可以查詢它以幫助計算派生的硬體狀態,因為即使在DPMS OFF狀態下,顯示硬體也應儘可能地關閉電源,就像透過將enable設定為false來完全停用CRTC一樣。

planes_changed

此crtc上的平面已更新。 原子輔助程式和驅動程式使用它來控制原子提交控制流程。

mode_changed

modeenable已更改。 原子輔助程式和驅動程式使用它來控制原子提交控制流程。 另請參閱drm_atomic_crtc_needs_modeset()

驅動程式應該為此設定任何需要完整模式設定的CRTC狀態更改。 他們還可以將其重置為false,例如,如果可以透過僅更改縮放器設定來完成沒有完整模式設定的mode更改。

active_changed

active已切換。 原子輔助程式和驅動程式使用它來控制原子提交控制流程。 另請參閱drm_atomic_crtc_needs_modeset()

connectors_changed

此crtc的聯結器已更新,無論是在其狀態還是路由中。 原子輔助程式和驅動程式使用它來控制原子提交控制流程。 另請參閱drm_atomic_crtc_needs_modeset()

驅動程式應該根據需要從他們自己的原子檢查程式碼中設定此項,例如從drm_encoder_helper_funcs.atomic_check

zpos_changed

此crtc上平面的zpos值已更新。 原子輔助程式和驅動程式使用它來控制原子提交控制流程。

color_mgmt_changed

顏色管理屬性已更改(gamma_lutdegamma_lutctm)。 原子輔助程式和驅動程式使用它來控制原子提交控制流程。

no_vblank

反映CRTC傳送VBLANK事件的能力。 此狀態通常取決於流水線配置。 如果設定為true,則DRM原子輔助程式將在提交所有硬體更改後,在顯示更新期間傳送偽VBLANK事件。 這在drm_atomic_helper_fake_vblank()中實現。

一種用法是用於不支援VBLANK中斷的驅動程式和/或硬體。 此類驅動程式通常不初始化垂直消隱(即,使用CRTC的數量呼叫drm_vblank_init())。 對於沒有初始化垂直消隱的CRTC,此欄位在drm_atomic_helper_check_modeset()中設定為true,並且drm_atomic_helper_fake_vblank()將在每次更新顯示流水線時傳送偽VBLANK事件。

另一種用法是CRTC饋送以單次模式執行的回寫聯結器。 在這種情況下,僅當作業排隊到回寫聯結器時才會生成偽VBLANK事件,並且我們希望核心在流水線的這一部分未更改但其他部分已更改時或CRTC和聯結器被停用時偽造VBLANK事件。

__drm_atomic_helper_crtc_duplicate_state()不會重置當前狀態的值,然後CRTC驅動程式負責在需要時更新此欄位。

請注意,drm_crtc_state.event == NULL和drm_crtc_state.no_blank == true的組合有效,通常在附加到CRTC的回寫聯結器已將新作業排隊時使用。 在這種情況下,驅動程式將在回寫作業完成時自行傳送VBLANK事件。

plane_mask

附加到此CRTC的平面的drm_plane_mask(plane)的位掩碼。

connector_mask

附加到此CRTC的聯結器的drm_connector_mask(connector)的位掩碼。

encoder_mask

附加到此CRTC的編碼器的drm_encoder_mask(encoder)的位掩碼。

adjusted_mode

內部顯示時序,驅動程式可以使用這些時序來處理使用者空間在mode中請求的模式與實際程式設計到硬體中的模式之間的差異。

對於使用drm_bridge的驅動程式,這儲存CRTC和第一個橋之間的硬體顯示時序。 對於其他驅動程式,adjusted_mode欄位的含義純粹是驅動程式實現定義的資訊,通常用於儲存CRTC和編碼器塊之間的硬體顯示時序。

mode

使用者空間請求的顯示時序。 驅動程式應嘗試儘可能地匹配重新整理率(但請注意,尚不清楚到底足夠接近,例如,某些HDMI模式的重新整理率差異小於1%)。 使用者空間觀察到的用於定位平面的活動寬度和高度必須完全匹配。

對於接收器未固定的外部聯結器(例如內建面板),此處的模式應與線上的物理模式匹配到最後一個細節(即,包括同步極性等)。

mode_blob

drm_property_blob用於mode,用於將模式公開給原子使用者空間。

degamma_lut

用於在應用顏色轉換矩陣ctm之前轉換幀緩衝區畫素資料的查詢表。 請參閱drm_crtc_enable_color_mgmt()。 blob(如果不是NULL)是struct drm_color_lut的陣列。

ctm

顏色轉換矩陣。 請參閱drm_crtc_enable_color_mgmt()。 blob(如果不是NULL)是struct drm_color_ctm

gamma_lut

用於在顏色轉換矩陣ctm之後轉換畫素資料的查詢表。 請參閱drm_crtc_enable_color_mgmt()。 blob(如果不是NULL)是struct drm_color_lut的陣列。

請注意,由於主要來自Xorg傳承的歷史原因,它也用於儲存索引格式(如DRM_FORMAT_C8)的顏色對映(有時也稱為顏色lut、CLUT或調色盤)。

target_vblank

頁面翻轉生效時的目標垂直消隱週期。

async_flip

當在傳統PAGE_FLIP IOCTL中設定DRM_MODE_PAGE_FLIP_ASYNC時,將設定此項。 它尚未連線到原子IOCTL本身。

vrr_enabled

指示是否應為CRTC啟用可變重新整理率。 對請求的vrr狀態的支援將取決於驅動程式和硬體功能 - 缺少支援不被視為失敗。

self_refresh_active

由自重新整理輔助程式使用,以表示正在發生自重新整理轉換。 啟用/停用自重新整理時,將在啟用/停用回撥上設定此項。 在某些情況下,可能不希望在自重新整理期間完全關閉crtc。 CRTC可以檢查此標誌並確定最佳操作方案。

scaling_filter

要應用的縮放過濾器

event

指向DRM事件的可選指標,以在狀態更新完成後發出訊號。 驅動程式必須在原子提交操作完成後傳送事件。 有兩種情況

  • 此事件用於透過原子提交停用的 CRTC。在這種情況下,硬體停止掃描當前幀緩衝區後,可以隨時傳送該事件。它應該包含顯示管道關閉前的最後一個垂直空白的 timestamp 和計數器。實現這一點的最簡單方法是在呼叫 drm_crtc_vblank_off() 之後,在某個時刻呼叫 drm_crtc_send_vblank_event()

  • 對於在提交結束時啟用的 CRTC(即使它經歷了完整的模式設定),垂直空白 timestamp 和計數器必須是掃描輸出新緩衝區集之前的垂直空白。同樣,只有在硬體停止掃描輸出舊緩衝區後,才能傳送該事件。

  • 不允許停用 CRTC 的事件,驅動程式可以忽略這種情況。

對於沒有 VBLANK 中斷的非常簡單的硬體,啟用 struct drm_crtc_state.no_vblank 會使 DRM 的原子提交輔助函式在所有硬體更改應用後,在顯示更新結束時傳送一個偽 VBLANK 事件。請參閱 drm_atomic_helper_fake_vblank()

對於更復雜的硬體,這可以透過 drm_crtc_send_vblank_event() 函式來處理,驅動程式應在原子提交完成後,在提供的事件上呼叫該函式。請注意,如果驅動程式支援垂直空白訊號和 timestamp,則垂直空白計數器和 timestamp 必須與頁面翻轉事件返回的計數器和 timestamp 一致。使用當前的垂直空白輔助基礎結構,這可以透過在頁面翻轉掛起時保持垂直空白引用來實現,該引用透過 drm_crtc_vblank_get() 獲取,並透過 drm_crtc_vblank_put() 釋放。驅動程式可以自由地實現自己的垂直空白計數器和 timestamp 跟蹤,例如,如果它們在硬體中具有精確的 timestamp 暫存器。

對於支援某種方式將垂直空白中斷傳遞與提交顯示狀態同步的硬體,還存在 drm_crtc_arm_vblank_event()。有關安全使用它所需約束的詳細討論,請參閱該函式的文件。

如果裝置根本無法以無競爭的方式通知翻轉完成,則應在頁面翻轉提交後立即準備好該事件。在最壞的情況下,驅動程式會將事件傳送到使用者空間,延遲一幀。這不允許真正的原子更新,但應避免撕裂。

提交

這跟蹤此更新的提交如何透過各個階段。除非我們銷燬狀態,否則它永遠不會被清除,以便後續提交可以與之前的提交同步。

state

指向全域性 drm_atomic_state 的後向指標

描述

請注意,**enable** 和 **active** 之間的區別非常微妙:在 enable 設定時翻轉 active 而不更改任何其他內容,可能永遠不會從 drm_mode_config_funcs.atomic_check 回撥中返回失敗。使用者空間假定 DPMS On 總是會成功。換句話說:**enable** 控制資源分配,**active** 控制實際的硬體狀態。

三個布林值 active_changed、connectors_changed 和 mode_changed 旨在指示是否需要完整的模式設定,而不是嚴格描述提交中發生了什麼更改。另請參閱:drm_atomic_crtc_needs_modeset()

struct drm_crtc_funcs

控制給定裝置的 CRTC

定義:

struct drm_crtc_funcs {
    void (*reset)(struct drm_crtc *crtc);
    int (*cursor_set)(struct drm_crtc *crtc, struct drm_file *file_priv, uint32_t handle, uint32_t width, uint32_t height);
    int (*cursor_set2)(struct drm_crtc *crtc, struct drm_file *file_priv,uint32_t handle, uint32_t width, uint32_t height, int32_t hot_x, int32_t hot_y);
    int (*cursor_move)(struct drm_crtc *crtc, int x, int y);
    int (*gamma_set)(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b,uint32_t size, struct drm_modeset_acquire_ctx *ctx);
    void (*destroy)(struct drm_crtc *crtc);
    int (*set_config)(struct drm_mode_set *set, struct drm_modeset_acquire_ctx *ctx);
    int (*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);
    int (*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);
    int (*set_property)(struct drm_crtc *crtc, struct drm_property *property, uint64_t val);
    struct drm_crtc_state *(*atomic_duplicate_state)(struct drm_crtc *crtc);
    void (*atomic_destroy_state)(struct drm_crtc *crtc, struct drm_crtc_state *state);
    int (*atomic_set_property)(struct drm_crtc *crtc,struct drm_crtc_state *state,struct drm_property *property, uint64_t val);
    int (*atomic_get_property)(struct drm_crtc *crtc,const struct drm_crtc_state *state,struct drm_property *property, uint64_t *val);
    int (*late_register)(struct drm_crtc *crtc);
    void (*early_unregister)(struct drm_crtc *crtc);
    int (*set_crc_source)(struct drm_crtc *crtc, const char *source);
    int (*verify_crc_source)(struct drm_crtc *crtc, const char *source, size_t *values_cnt);
    const char *const *(*get_crc_sources)(struct drm_crtc *crtc, size_t *count);
    void (*atomic_print_state)(struct drm_printer *p, const struct drm_crtc_state *state);
    u32 (*get_vblank_counter)(struct drm_crtc *crtc);
    int (*enable_vblank)(struct drm_crtc *crtc);
    void (*disable_vblank)(struct drm_crtc *crtc);
    bool (*get_vblank_timestamp)(struct drm_crtc *crtc,int *max_error,ktime_t *vblank_time, bool in_vblank_irq);
};

成員

重置

將 CRTC 硬體和軟體狀態重置為關閉。此函式不是由核心直接呼叫的,而是僅透過 drm_mode_config_reset() 呼叫的。它不是僅用於歷史原因的輔助鉤子。

原子驅動程式可以使用 drm_atomic_helper_crtc_reset() 透過此鉤子重置原子狀態。

cursor_set

更新游標影像。游標位置相對於 CRTC,可以部分或完全位於可見區域之外。

請注意,與所有其他 KMS 函式相反,舊版游標入口點不採用幀緩衝區物件,而是直接從驅動程式的緩衝區管理器(對於當前驅動程式,為 GEM 或 TTM)獲取原始緩衝區物件 ID。

此入口點已棄用,驅動程式應改為實現通用平面支援,並使用 drm_crtc_init_with_planes() 註冊適當的游標平面。

此回撥是可選的

返回值

成功時為 0,失敗時為負錯誤程式碼。

cursor_set2

更新游標影像,包括熱點資訊。熱點不得影響 CRTC 座標中的游標位置,而僅用作虛擬化顯示硬體協調訪客和主機游標位置的提示。游標熱點相對於游標影像。否則,此函式的工作方式與 **cursor_set** 完全相同。

此入口點已棄用,驅動程式應改為實現通用平面支援,並使用 drm_crtc_init_with_planes() 註冊適當的游標平面。

此回撥是可選的。

返回值

成功時為 0,失敗時為負錯誤程式碼。

cursor_move

更新游標位置。呼叫此鉤子時,游標不需要可見。

此入口點已棄用,驅動程式應改為實現通用平面支援,並使用 drm_crtc_init_with_planes() 註冊適當的游標平面。

此回撥是可選的。

返回值

成功時為 0,失敗時為負錯誤程式碼。

gamma_set

在 CRTC 上設定 gamma。

此回撥是可選的。

想要支援 gamma 表的原子驅動程式應實現原子顏色管理支援,透過呼叫 drm_crtc_enable_color_mgmt() 啟用,然後透過 drm_atomic_helper_legacy_gamma_set() 相容性實現支援舊版 gamma 介面。

destroy

清理 CRTC 資源。僅在驅動程式解除安裝時透過 drm_mode_config_cleanup() 呼叫,因為 CRTC 無法在 DRM 中熱插拔。

set_config

這是在 CRTC 上更改模式設定狀態的主要舊版入口點。所需配置的所有詳細資訊都透過 struct drm_mode_set 傳遞 - 有關詳細資訊,請參見那裡。

實現原子模式設定的驅動程式應使用 drm_atomic_helper_set_config() 來實現此鉤子。

返回值

成功時為 0,失敗時為負錯誤程式碼。

page_flip

舊版入口點,用於計劃翻轉到給定的幀緩衝區。

頁面翻轉是一種同步機制,它在垂直消隱期間用新的幀緩衝區替換 CRTC 正在掃描輸出的幀緩衝區,從而避免了撕裂(除非透過 DRM_MODE_PAGE_FLIP_ASYNC 標誌另行請求)。當應用程式請求頁面翻轉時,DRM 核心會驗證新的幀緩衝區是否足夠大,可以在當前配置的模式下由 CRTC 掃描輸出,然後使用指向新幀緩衝區的指標呼叫此鉤子。

驅動程式必須等待任何掛起的對新幀緩衝區的渲染完成,然後才能執行翻轉。如果底層緩衝區是共享的 dma-buf,它還應等待來自其他驅動程式的任何掛起的渲染。

應用程式可以請求在頁面翻轉完成後收到通知。在這種情況下,drm 核心將在 event 引數中提供 struct drm_event。這可以透過 drm_crtc_send_vblank_event() 函式來處理,驅動程式應在翻轉完成後,在提供的事件上呼叫該函式。請注意,如果驅動程式支援垂直空白訊號和 timestamp,則垂直空白計數器和 timestamp 必須與頁面翻轉事件返回的計數器和 timestamp 一致。使用當前的垂直空白輔助基礎結構,這可以透過在頁面翻轉掛起時保持垂直空白引用來實現,該引用透過 drm_crtc_vblank_get() 獲取,並透過 drm_crtc_vblank_put() 釋放。驅動程式可以自由地實現自己的垂直空白計數器和 timestamp 跟蹤,例如,如果它們在硬體中具有精確的 timestamp 暫存器。

此回撥是可選的。

注意

KMS ABI 的非常早期的版本規定,驅動程式必須阻止(但不拒絕)任何對舊幀緩衝區的渲染,直到翻轉操作完成並且舊幀緩衝區不再可見。此要求已取消,而是希望使用者空間請求傳遞事件並等待回收舊緩衝區,直到收到此類事件。

返回值

成功時為 0,失敗時為負錯誤程式碼。請注意,如果頁面翻轉操作已掛起,則回撥應返回 -EBUSY。在停用的 CRTC 上(透過設定 NULL 模式或僅透過 DPMS 分別執行時停用新的原子“ACTIVE”狀態)進行頁面翻轉應導致 -EINVAL 錯誤程式碼。請注意,drm_atomic_helper_page_flip() 已經為原子驅動程式檢查了這一點。

page_flip_target

與 **page_flip** 相同,但具有一個額外的引數,用於指定翻轉生效時的絕對目標垂直消隱週期(如 drm_crtc_vblank_count() 報告的)。

請注意,核心程式碼會在呼叫此入口點之前呼叫 drm_crtc_vblank_get,如果此入口點返回任何非 0 錯誤程式碼,則會呼叫 drm_crtc_vblank_put。驅動程式有責任在此入口點返回 0 後呼叫 drm_crtc_vblank_put,通常在翻轉完成時呼叫。

set_property

這是更新附加到 CRTC 的屬性的舊版入口點。

如果驅動程式不支援任何舊版驅動程式私有屬性,則此回撥是可選的。對於原子驅動程式,它不使用,因為屬性處理完全在 DRM 核心中完成。

返回值

成功時為 0,失敗時為負錯誤程式碼。

atomic_duplicate_state

複製此 CRTC 的當前原子狀態並返回它。核心和輔助函式保證任何使用此鉤子複製的原子狀態,並且仍然由呼叫者擁有(即,沒有透過呼叫 drm_mode_config_funcs.atomic_commit 轉移到驅動程式)將透過呼叫此結構中的 **atomic_destroy_state** 鉤子進行清理。

此回撥對於原子驅動程式是必需的。

不繼承 struct drm_crtc_state 的原子驅動程式應使用 drm_atomic_helper_crtc_duplicate_state()。繼承狀態結構以使用驅動程式私有狀態擴充套件它的驅動程式應使用 __drm_atomic_helper_crtc_duplicate_state() 以確保共享狀態以跨驅動程式一致的方式複製。

在正確初始化 drm_crtc.state 之前呼叫此鉤子是一個錯誤。

注意

如果重複的狀態引用了引用計數的資源,則此鉤子必須獲取對每個資源的引用。驅動程式必須在 **atomic_destroy_state** 中再次釋放這些引用。

返回值

重複的原子狀態,或者當分配失敗時為 NULL。

atomic_destroy_state

銷燬使用 **atomic_duplicate_state** 複製的狀態,並釋放或取消引用它引用的所有資源

此回撥對於原子驅動程式是必需的。

atomic_set_property

解碼驅動程式私有屬性值,並將解碼後的值儲存到傳入的狀態結構中。由於原子核心解碼所有標準化屬性(即使是超出核心屬性集範圍的擴充套件,這些擴充套件可能並非所有驅動程式都實現),因此這要求驅動程式繼承狀態結構。

此類驅動程式私有屬性實際上只應為真正的硬體/供應商特定狀態實現。相反,最好標準化原子擴充套件並在核心中解碼用於公開此類擴充套件的屬性。

不要直接呼叫此函式,而是使用 drm_atomic_crtc_set_property()。

如果驅動程式不支援任何驅動程式私有原子屬性,則此回撥是可選的。

注意

此函式在原子模式設定的狀態程式集階段中呼叫,該階段可能因任何原因中止(包括應使用者空間請求僅檢查配置是否可能)。驅動程式不得觸控任何持久狀態(硬體或軟體)或資料結構,除了傳入的 **state** 引數。

此外,由於使用者空間控制屬性的設定順序,因此此函式不得進行任何輸入驗證(因為狀態更新不完整,因此可能不一致)。相反,任何此類輸入驗證都必須在各種 atomic_check 回撥中完成。

返回值

如果找到了該屬性,則為 0;如果該屬性未由驅動程式實現,則為 -EINVAL(這不應該發生,核心只請求附加到此 CRTC 的屬性)。驅動程式不允許進行其他驗證。核心已經檢查了屬性值是否在驅動程式註冊屬性時設定的範圍內(整數、有效列舉值等)。

atomic_get_property

讀出解碼後的驅動程式私有屬性。這用於實現 GETCRTC IOCTL。

不要直接呼叫此函式,而是使用 drm_atomic_crtc_get_property()。

如果驅動程式不支援任何驅動程式私有原子屬性,則此回撥是可選的。

返回值

成功時為 0,如果該屬性未由驅動程式實現,則為 -EINVAL(這不應該發生,核心只請求附加到此 CRTC 的屬性)。

late_register

此可選鉤子可用於註冊附加到 crtc 的其他使用者空間介面,如 debugfs 介面。它在驅動程式載入序列的後期從 drm_dev_register() 呼叫。從此回撥新增的所有內容都應在 early_unregister 回撥中取消註冊。

返回

成功時為 0,失敗時為負錯誤程式碼。

early_unregister

應使用此可選鉤子來取消註冊附加到 crtc 的其他使用者空間介面,這些介面來自 **late_register**。它從 drm_dev_unregister() 呼叫,在驅動程式解除安裝序列的早期,以在資料結構被拆除之前停用使用者空間訪問。

set_crc_source

應使用者空間的要求,更改幀的 CRC 校驗和的來源,通常用於測試目的。可用來源是每個驅動程式特定的, NULL 值表示要關閉 CRC 生成。

啟用 CRC 生成後,驅動程式應在每個幀呼叫 drm_crtc_add_crc_entry(),在 crcN 引數中提供任何表徵幀內容的資訊,這些資訊來自配置的來源。驅動程式必須接受一個“auto”來源名稱,該名稱將為此 CRTC 選擇一個預設來源。

如果需要,這可能會觸發原子模式設定提交,以啟用 CRC 生成。

請注意,“auto”可能取決於當前的模式設定配置,例如,它可以選擇編碼器或輸出特定的 CRC 取樣點。

如果驅動程式不支援任何 CRC 生成功能,則此回撥是可選的。

返回值

成功時為 0,失敗時為負錯誤程式碼。

verify_crc_source

在設定 CRC 的來源之前和在 crc 開啟期間驗證幀的 CRC 校驗和的來源。在停用 crc 來源時,Source 引數可以為 NULL。

如果驅動程式不支援任何 CRC 生成功能,則此回撥是可選的。

返回值

成功時為 0,失敗時為負錯誤程式碼。

get_crc_sources

用於獲取 CRC 生成的所有可用來源列表的驅動程式回撥。此回撥依賴於 verify_crc_source,因此應在實現此回撥之前實現 verify_crc_source 回撥。驅動程式可以傳遞可用 crc 來源的完整列表,此回撥在將每個 crc-source 傳遞給使用者空間之前對其進行驗證。

如果驅動程式不支援匯出可能的 CRC 來源列表,則此回撥是可選的。

返回值

指向所有可用 CRC 來源列表的常量字元指標。如果失敗,驅動程式應返回 NULL。應使用列表中的來源數量更新 count。如果為零,我們不處理列表中的任何來源。

atomic_print_state

如果驅動程式繼承 struct drm_crtc_state,它應實現此可選鉤子以列印其他驅動程式特定狀態。

不要直接呼叫此函式,而是使用 drm_atomic_crtc_print_state()。

get_vblank_counter

用於獲取 CRTC 的原始硬體垂直空白計數器的驅動程式回撥。它旨在供新驅動程式使用,作為 drm_driver.get_vblank_counter 鉤子的替代品。

此回撥是可選的。如果裝置沒有硬體計數器,驅動程式可以簡單地將鉤子保留為 NULL。DRM 核心會在中斷被停用時,根據系統 timestamp 考慮錯過的垂直空白事件。

由於模式設定導致的環繞處理和事件丟失在 DRM 核心程式碼中處理,只要驅動程式在停用或啟用 CRTC 時呼叫 drm_crtc_vblank_off()drm_crtc_vblank_on() 即可。

另請參閱 drm_device.vblank_disable_immediatedrm_device.max_vblank_count

返回

原始垂直空白計數器值。

enable_vblank

為 CRTC 啟用垂直空白中斷。它旨在供新驅動程式使用,作為 drm_driver.enable_vblank 鉤子的替代品。

返回

成功時為零,如果無法啟用垂直空白中斷,則為適當的 errno。

disable_vblank

為 CRTC 停用垂直空白中斷。它旨在供新驅動程式使用,作為 drm_driver.disable_vblank 鉤子的替代品。

get_vblank_timestamp

由 drm_get_last_vbltimestamp() 呼叫。應返回最精確的 timestamp,指示最近的垂直空白間隔何時結束或將要結束。

具體來說,**vblank_time** 中的 timestamp 應儘可能接近垂直空白結束後影片幀的第一條影片掃描線將開始掃描輸出的時間,即垂直空白間隔結束後立即的時間。如果 **crtc** 當前位於垂直空白中,這將是未來的時間。如果 **crtc** 當前正在掃描輸出幀,這將是當前掃描輸出的過去開始時間。這意味著要符合 OpenML OML_sync_control 擴充套件規範。

引數

crtc

要為其返回 timestamp 的 CRTC。

max_error

允許的最大 timestamp 誤差(以納秒為單位)。實現應努力提供誤差最多為 max_error 納秒的 timestamp。返回 timestamp 誤差的真上界。

vblank_time

返回的垂直空白 timestamp 的目標位置。

in_vblank_irq

drm_crtc_handle_vblank() 呼叫時為 True。如果設定了標誌,某些驅動程式需要應用一些針對 gpu 特定垂直空白 irq 怪癖的解決方法。

返回

成功時為 True,失敗時為 False,這意味著核心應回退到在 drm_crtc_handle_vblank() 中獲取的簡單 timestamp。

描述

drm_crtc_funcs 結構是 DRM 中的中心 CRTC 管理結構。每個 CRTC 控制一個或多個聯結器(請注意,名稱 CRTC 只是歷史名稱,CRTC 可以控制 LVDS、VGA、DVI、TV 輸出等聯結器,而不僅僅是 CRT)。

除了提供其他模式設定功能(如 i2c 和 DDC 匯流排訪問器)外,每個驅動程式都負責在啟動時填寫此結構。

struct drm_crtc

中心 CRTC 控制結構

定義:

struct drm_crtc {
    struct drm_device *dev;
    struct device_node *port;
    struct list_head head;
    char *name;
    struct drm_modeset_lock mutex;
    struct drm_mode_object base;
    struct drm_plane *primary;
    struct drm_plane *cursor;
    unsigned index;
    int cursor_x;
    int cursor_y;
    bool enabled;
    struct drm_display_mode mode;
    struct drm_display_mode hwmode;
    int x;
    int y;
    const struct drm_crtc_funcs *funcs;
    uint32_t gamma_size;
    uint16_t *gamma_store;
    const struct drm_crtc_helper_funcs *helper_private;
    struct drm_object_properties properties;
    struct drm_property *scaling_filter_property;
    struct drm_crtc_state *state;
    struct list_head commit_list;
    spinlock_t commit_lock;
    struct dentry *debugfs_entry;
    struct drm_crtc_crc crc;
    unsigned int fence_context;
    spinlock_t fence_lock;
    unsigned long fence_seqno;
    char timeline_name[32];
    struct drm_self_refresh_data *self_refresh_data;
};

成員

dev

父 DRM 裝置

drm_of_find_possible_crtcs() 使用的 OF 節點。

head

dev 上的所有 CRTC 的列表,從 drm_mode_config.crtc_list 連結。在 dev 的整個生命週期內不變,因此不需要鎖定。

名稱

人類可讀的名稱,可以由驅動程式覆蓋

mutex

這為整體 CRTC 狀態(模式、dpms 狀態等)提供了一個讀鎖,為可以在沒有完整模式設定的情況下更新的所有內容(fb、游標資料、CRTC 屬性等)提供了一個寫鎖。完整的模式設定還需要獲取 drm_mode_config.connection_mutex

對於原子驅動程式,這專門保護 state

基本

用於 ID 跟蹤等的基本 KMS 物件。

主要

此 CRTC 的主平面。請注意,這僅與舊版 IOCTL 相關,它指定了 SETCRTC 和 PAGE_FLIP IOCTL 隱式使用的平面。除此之外,它沒有任何意義。

游標

此 CRTC 的游標平面。請注意,這僅與舊版 IOCTL 相關,它指定了 SETCURSOR 和 SETCURSOR2 IOCTL 隱式使用的平面。除此之外,它沒有任何意義。

索引

模式配置列表中的位置,可以用作陣列索引。它在 CRTC 的整個生命週期內不變。

cursor_x

游標的當前 x 位置,用於通用游標平面,因為 SETCURSOR IOCTL 只能更新幀緩衝區,而無需提供座標。驅動程式不應直接使用此值,原子驅動程式應檢視游標平面的 drm_plane_state.crtc_x

cursor_y

游標的當前 y 位置,用於通用游標平面,因為 SETCURSOR IOCTL 只能更新幀緩衝區,而無需提供座標。驅動程式不應直接使用此值,原子驅動程式應檢視游標平面的 drm_plane_state.crtc_y

已啟用

是否啟用了 CRTC?僅應由舊驅動程式使用,原子驅動程式應改為查閱 drm_crtc_state.enabledrm_crtc_state.active。原子驅動程式可以透過呼叫 drm_atomic_helper_update_legacy_modeset_state() 來更新此設定。

mode

當前模式時序。僅應由舊驅動程式使用,原子驅動程式應改為查閱 drm_crtc_state.mode。原子驅動程式可以透過呼叫 drm_atomic_helper_update_legacy_modeset_state() 來更新此設定。

hwmode

硬體中已程式設計的模式,經過對編碼器、CRTC、面板縮放等的調整。僅應由舊驅動程式使用,用於 drm_crtc_vblank_helper_get_vblank_timestamp() 中的高精度垂直消隱時間戳。

請注意,原子驅動程式不應使用此項,而應使用 drm_crtc_state.adjusted_mode。對於高精度時間戳,drm_crtc_vblank_helper_get_vblank_timestamp() 使用 drm_vblank_crtc.hwmode,後者透過呼叫 drm_calc_timestamping_constants() 填充。

x

螢幕上的 x 位置。僅應由舊驅動程式使用,原子驅動程式應檢視主平面的 drm_plane_state.crtc_x。透過呼叫 drm_atomic_helper_update_legacy_modeset_state() 更新。

y

螢幕上的 y 位置。僅應由舊驅動程式使用,原子驅動程式應檢視主平面的 drm_plane_state.crtc_y。透過呼叫 drm_atomic_helper_update_legacy_modeset_state() 更新。

funcs

CRTC 控制函式

gamma_size

報告給使用者空間的舊版伽馬斜坡的大小。透過呼叫 drm_mode_crtc_set_gamma_size() 設定。

請注意,原子驅動程式需要改為使用 drm_crtc_state.gamma_lut。請參閱 drm_crtc_enable_color_mgmt()

gamma_store

舊版 SETGAMMA 和 GETGAMMA IOCTL 使用的伽馬斜坡值。透過呼叫 drm_mode_crtc_set_gamma_size() 設定。

請注意,原子驅動程式需要改為使用 drm_crtc_state.gamma_lut。請參閱 drm_crtc_enable_color_mgmt()

helper_private

中間層私有資料

properties

此 CRTC 的屬性跟蹤

scaling_filter_property

在縮放時應用特定過濾器的屬性。

state

此 CRTC 的當前原子狀態。

受 **mutex** 保護。請注意,非阻塞原子提交在不獲取鎖的情況下訪問當前的 CRTC 狀態。可以透過 struct drm_atomic_state 指標,請參閱 for_each_oldnew_crtc_in_state()for_each_old_crtc_in_state()for_each_new_crtc_in_state()。或者透過原子輔助程式中實現的原子提交操作的仔細排序,請參閱 struct drm_crtc_commit

commit_list

跟蹤掛起提交的 drm_crtc_commit 結構的列表。受 **commit_lock** 保護。此列表持有其自己的完整引用,正在進行的提交也是如此。

“請注意,狀態更改的提交也在 drm_crtc_state.commit 中跟蹤。為了訪問原子更新中緊鄰之前的提交,建議僅使用舊 CRTC 狀態中的指標,因為訪問它不需要任何鎖定或列表遍歷。**commit_list** 僅應用於暫停幀緩衝區清理,該清理透過 drm_crtc_commit.cleanup_done 發出訊號。”

commit_lock

用於保護 **commit_list** 的自旋鎖。

debugfs_entry

此 CRTC 的 Debugfs 目錄。

crc

CRC 捕獲的配置設定。

fence_context

用於柵欄操作的時間線上下文。

fence_lock

用於保護 fence_context 中柵欄的自旋鎖。

fence_seqno

用作 CRTC 時間線上建立的柵欄的單調計數器的 Seqno 變數。

timeline_name

CRTC 柵欄時間線的名稱。

self_refresh_data

儲存自重新整理輔助程式的狀態

透過 drm_self_refresh_helper_init() 初始化。

描述

每個 CRTC 可以有一個或多個與其關聯的聯結器。此結構允許控制 CRTC。

struct drm_mode_set

CRTC 配置更改的新值

定義:

struct drm_mode_set {
    struct drm_framebuffer *fb;
    struct drm_crtc *crtc;
    struct drm_display_mode *mode;
    uint32_t x;
    uint32_t y;
    struct drm_connector **connectors;
    size_t num_connectors;
};

成員

fb

用於新配置的幀緩衝區

crtc

我們要更改其配置的 CRTC

mode

要使用的模式時序

x

此 CRTC 相對於 **fb** 的位置

y

此 CRTC 相對於 **fb** 的位置

connectors

如果可能,用於驅動此 CRTC 的聯結器陣列

num_connectors

**connectors** 陣列的大小

描述

這表示舊版 SETCRTC ioctl 的模式集配置,也用於內部。原子驅動程式改為使用 drm_atomic_state

drmm_crtc_alloc_with_planes

drmm_crtc_alloc_with_planes (dev, type, member, primary, cursor, funcs, name, ...)

分配並初始化具有指定的主平面和游標平面的新 CRTC 物件。

引數

dev

DRM 裝置

type

包含 struct drm_crtc 的結構體的型別

member

**type** 中的 drm_crtc 的名稱。

主要

CRTC 的主平面

游標

CRTC 的游標平面

funcs

新 CRTC 的回撥

名稱

CRTC 名稱的 printf 樣式格式字串,如果為 NULL,則為預設名稱

...

可變引數

描述

分配並初始化新的 crtc 物件。透過使用 drmm_add_action() 註冊 drmm_crtc_cleanup() 來自動處理清理。

**drm_crtc_funcs.destroy** 掛鉤必須為 NULL。

返回

指向新 crtc 的指標,如果失敗,則為 ERR_PTR。

unsigned int drm_crtc_index(const struct drm_crtc *crtc)

查詢已註冊 CRTC 的索引

引數

const struct drm_crtc *crtc

要查詢索引的 CRTC

描述

給定一個已註冊的 CRTC,返回該 CRTC 在 DRM 裝置的 CRTC 列表中的索引。

uint32_t drm_crtc_mask(const struct drm_crtc *crtc)

查詢已註冊 CRTC 的掩碼

引數

const struct drm_crtc *crtc

要查詢掩碼的 CRTC

描述

給定一個已註冊的 CRTC,返回該 CRTC 的掩碼位,用於 drm_encoder.possible_crtcsdrm_plane.possible_crtcs 欄位。

struct drm_crtc *drm_crtc_find(struct drm_device *dev, struct drm_file *file_priv, uint32_t id)

從其 ID 查詢 CRTC 物件

引數

struct drm_device *dev

DRM 裝置

struct drm_file *file_priv

用於檢查租賃的 DRM 檔案。

uint32_t id

drm_mode_object ID

描述

這可用於從其使用者空間 ID 查詢 CRTC。僅由驅動程式用於舊版 IOCTL 和介面,如今,KMS 使用者空間介面的擴充套件應使用 drm_property 完成。

drm_for_each_crtc

drm_for_each_crtc (crtc, dev)

迭代所有 CRTC

引數

crtc

作為迴圈游標的 struct drm_crtc

dev

struct drm_device

描述

迭代 **dev** 的所有 CRTC。

drm_for_each_crtc_reverse

drm_for_each_crtc_reverse (crtc, dev)

以相反的順序迭代所有 CRTC

引數

crtc

作為迴圈游標的 struct drm_crtc

dev

struct drm_device

描述

迭代 **dev** 的所有 CRTC。

struct drm_crtc *drm_crtc_from_index(struct drm_device *dev, int idx)

查詢索引處的已註冊 CRTC

引數

struct drm_device *dev

DRM 裝置

int idx

要查詢的已註冊 CRTC 的索引

描述

給定一個 CRTC 索引,從 DRM 裝置的 CRTC 列表中返回具有匹配索引的已註冊 CRTC。這是 drm_crtc_index() 的逆運算。它在垂直消隱回撥(如 drm_driver.enable_vblankdrm_driver.disable_vblank)中很有用,因為這仍然處理索引而不是指向 struct drm_crtc 的指標。”

int drm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc, struct drm_plane *primary, struct drm_plane *cursor, const struct drm_crtc_funcs *funcs, const char *name, ...)

使用指定的主平面和游標平面初始化新的 CRTC 物件。

引數

struct drm_device *dev

DRM 裝置

struct drm_crtc *crtc

要初始化的 CRTC 物件

struct drm_plane *primary

CRTC 的主平面

struct drm_plane *cursor

CRTC 的游標平面

const struct drm_crtc_funcs *funcs

新 CRTC 的回撥

const char *name

CRTC 名稱的 printf 樣式格式字串,如果為 NULL,則為預設名稱

...

可變引數

描述

初始化作為驅動程式 crtc 物件基本部分建立的新物件。驅動程式應使用此函式而不是 drm_crtc_init(),該函式僅為與尚不支援通用平面的驅動程式向後相容而提供)。對於只有 1 個平面的非常簡單的硬體,請檢視 drm_simple_display_pipe_init()。應該呼叫 drm_crtc_funcs.destroy 鉤子 drm_crtc_cleanup()kfree() crtc 結構。crtc 結構不應使用 devm_kzalloc() 分配。

**primary** 和 **cursor** 平面僅與舊版 uAPI 相關,請參閱 drm_crtc.primarydrm_crtc.cursor

注意

考慮使用 drmm_crtc_alloc_with_planes()drmm_crtc_init_with_planes() 而不是 drm_crtc_init_with_planes(),以讓 DRM 管理的資源基礎設施負責清理和釋放。

返回

成功時為零,失敗時為錯誤程式碼。

int drmm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc, struct drm_plane *primary, struct drm_plane *cursor, const struct drm_crtc_funcs *funcs, const char *name, ...)

使用指定的主平面和游標平面初始化新的 CRTC 物件。

引數

struct drm_device *dev

DRM 裝置

struct drm_crtc *crtc

要初始化的 CRTC 物件

struct drm_plane *primary

CRTC 的主平面

struct drm_plane *cursor

CRTC 的游標平面

const struct drm_crtc_funcs *funcs

新 CRTC 的回撥

const char *name

CRTC 名稱的 printf 樣式格式字串,如果為 NULL,則為預設名稱

...

可變引數

描述

初始化作為驅動程式 crtc 物件基本部分建立的新物件。驅動程式應使用此函式代替 drm_crtc_init(),它僅用於向後相容尚不支援通用平面的驅動程式)。對於只有 1 個平面的非常簡單的硬體,請檢視 drm_simple_display_pipe_init()

清理工作透過使用 drmm_add_action() 註冊 drmm_crtc_cleanup() 自動處理。應使用 drmm_kzalloc() 分配 crtc 結構。

**drm_crtc_funcs.destroy** 掛鉤必須為 NULL。

**primary** 和 **cursor** 平面僅與舊版 uAPI 相關,請參閱 drm_crtc.primarydrm_crtc.cursor

返回

成功時為零,失敗時為錯誤程式碼。

void drm_crtc_cleanup(struct drm_crtc *crtc)

清理核心 crtc 用法

引數

struct drm_crtc *crtc

要清理的 CRTC

描述

此函式清理 **crtc** 並將其從 DRM 模式設定核心中移除。請注意,該函式_不會_釋放 crtc 結構本身,這是呼叫者的責任。

int drm_mode_set_config_internal(struct drm_mode_set *set)

呼叫 drm_mode_config_funcs.set_config 的幫助程式

引數

struct drm_mode_set *set

要設定的模式集配置

描述

這是一個用於包裝對 drm_mode_config_funcs.set_config 驅動程式介面的內部呼叫的一個小幫助程式。它唯一新增的是正確的引用計數。

這應該僅由非原子舊版驅動程式使用。

返回

成功時返回零,失敗時返回負 errno。

int drm_crtc_check_viewport(const struct drm_crtc *crtc, int x, int y, const struct drm_display_mode *mode, const struct drm_framebuffer *fb)

檢查幀緩衝區是否足夠大以用於 CRTC 視口

引數

const struct drm_crtc *crtc

將在其上顯示幀緩衝區的 CRTC

int x

x 平移

int y

y 平移

const struct drm_display_mode *mode

將在其下顯示幀緩衝區的模式

const struct drm_framebuffer *fb

要檢查大小的幀緩衝區

int drm_crtc_create_scaling_filter_property(struct drm_crtc *crtc, unsigned int supported_filters)

建立新的縮放濾鏡屬性

引數

struct drm_crtc *crtc

drm CRTC

unsigned int supported_filters

支援的縮放濾鏡的位掩碼,必須包括 BIT(DRM_SCALING_FILTER_DEFAULT)。

描述

此函式允許驅動程式在給定的 CRTC 上啟用縮放濾鏡屬性。

返回

成功時返回零,或返回 -errno

bool drm_crtc_in_clone_mode(struct drm_crtc_state *crtc_state)

檢查給定的 CRTC 狀態是否處於克隆模式

引數

struct drm_crtc_state *crtc_state

要檢查的 CRTC 狀態

描述

此函式確定給定的 CRTC 狀態是否正被多個編碼器克隆。

返回

如果 CRTC 狀態處於克隆模式,則為 True。否則為 False

顏色管理函式參考

u64 drm_color_ctm_s31_32_to_qm_n(u64 user_input, u32 m, u32 n)

引數

u64 user_input

輸入值

u32 m

整數位的數量,僅支援 m <= 32,包括符號位

u32 n

小數位的數量,僅支援 n <= 32

描述

將 S31.32 符號大小轉換為 Qm.n(帶符號的 2 的補碼)並進行截斷。符號位 BIT(m+n-1) 及以上為 0 表示正值,為 1 表示負值,值的範圍為 [-2^(m-1), 2^(m-1) - 2^-n]

例如,Q3.12 格式的數字: - 必需的位:3 + 12 = 15 位 - 範圍:[-2^2, 2^2 - 2^−15]

注意

如果所有 bit_precision 都用於表示小數,則 m 可以為零

位,如 Q0.32

void drm_crtc_enable_color_mgmt(struct drm_crtc *crtc, uint degamma_lut_size, bool has_ctm, uint gamma_lut_size)

啟用顏色管理屬性

引數

struct drm_crtc *crtc

DRM CRTC

uint degamma_lut_size

去伽瑪 lut 的大小(CSC 之前)

bool has_ctm

是否為 CSC 矩陣附加 ctm_property

uint gamma_lut_size

伽瑪 lut 的大小(CSC 之後)

描述

此函式允許驅動程式在 CRTC 上啟用顏色校正屬性。這包括 3 個去伽瑪、csc 和伽瑪屬性,使用者空間可以設定,以及 2 個大小屬性,用於通知使用者空間 lut 的大小。每個屬性都是可選的。僅當大小不為 0 時才附加伽瑪和去伽瑪屬性,並且僅當 has_ctm 為 true 時才附加 ctm_property。

int drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc, int gamma_size)

設定伽瑪表大小

引數

struct drm_crtc *crtc

要設定伽瑪表大小的 CRTC

int gamma_size

伽瑪表的大小

描述

支援伽瑪表的驅動程式應在初始化 CRTC 時將其設定為支援的伽瑪表大小。目前,drm 核心僅支援固定的伽瑪表大小。

返回

成功時返回零,失敗時返回負 errno。

int drm_plane_create_color_properties(struct drm_plane *plane, u32 supported_encodings, u32 supported_ranges, enum drm_color_encoding default_encoding, enum drm_color_range default_range)

顏色編碼相關的平面屬性

引數

struct drm_plane *plane

平面物件

u32 supported_encodings

指示支援的顏色編碼的位欄位

u32 supported_ranges

指示支援的顏色範圍的位欄位

enum drm_color_encoding default_encoding

預設顏色編碼

enum drm_color_range default_range

預設顏色範圍

描述

建立並附加平面特定的 COLOR_ENCODING 和 COLOR_RANGE 屬性到 **plane**。支援的編碼和範圍應在 supported_encodings 和 supported_ranges 位掩碼中提供。在位掩碼中設定的每個位指示支援將其編號作為列舉值。

int drm_color_lut_check(const struct drm_property_blob *lut, u32 tests)

檢查查詢表的有效性

引數

const struct drm_property_blob *lut

包含要檢查的 LUT 的屬性 Blob

u32 tests

要執行的測試的位掩碼

描述

幫助程式,用於檢查使用者空間提供的查詢表是否有效並滿足硬體要求。驅動程式傳遞一個位掩碼,指示應執行 drm_color_lut_tests 中的哪些測試。

成功時返回 0,失敗時返回 -EINVAL。

u32 drm_color_lut_extract(u32 user_input, int bit_precision)

截斷並舍入 LUT 條目

引數

u32 user_input

輸入值

int bit_precision

硬體 LUT 支援的位數

描述

提取使用者提供的去伽瑪/伽瑪 LUT 值(以 drm_color_lut 條目的形式),並按照 OpenGL int<->float 轉換規則將其舍入到硬體支援的精度(例如,請參見 OpenGL 4.6 規範 - 2.3.5 定點資料轉換)。

int drm_color_lut_size(const struct drm_property_blob *blob)

計算 LUT 中的條目數

引數

const struct drm_property_blob *blob

包含 LUT 的 Blob

返回

儲存在 **blob** 中的顏色 LUT 中的條目數。

enum drm_color_lut_tests

要執行的特定於硬體的 LUT 測試

常量

DRM_COLOR_LUT_EQUAL_CHANNELS

檢查 LUT 的條目是否所有通道(紅色、綠色和藍色)都具有相等的值。適用於僅接受每個 LUT 條目的單個值並假定該值應用於所有三個顏色分量的硬體。

DRM_COLOR_LUT_NON_DECREASING

檢查 LUT 的條目是否始終平坦或增加(從不減少)。

描述

drm_color_lut_check() 函式採用此處值的位掩碼,以確定要應用於使用者空間提供的 LUT 的哪些測試。

幀緩衝區抽象

幀緩衝區是抽象的記憶體物件,它提供畫素源以掃描到 CRTC。應用程式透過 DRM_IOCTL_MODE_ADDFB(2) ioctl 顯式請求建立幀緩衝區,並接收一個不透明的控制代碼,該控制代碼可以傳遞到 KMS CRTC 控制、平面配置和頁面翻轉函式。

幀緩衝區依賴於底層記憶體管理器來分配後備儲存。建立幀緩衝區時,應用程式透過 struct drm_mode_fb_cmd2 引數傳遞記憶體控制代碼(或用於多平面格式的記憶體控制代碼列表)。對於使用 GEM 作為其使用者空間緩衝區管理介面的驅動程式,這將是 GEM 控制代碼。但是,驅動程式可以自由使用其自己的後備儲存物件控制代碼,例如,vmwgfx 直接向用戶空間公開特殊的 TTM 控制代碼,因此在建立 ioctl 中需要 TTM 控制代碼,而不是 GEM 控制代碼。

幀緩衝區使用 struct drm_framebuffer 進行跟蹤。它們使用 drm_framebuffer_init() 釋出 - 呼叫該函式後,使用者空間可以使用和訪問幀緩衝區物件。幫助程式函式 drm_helper_mode_fill_fb_struct() 可用於預填充所需的元資料欄位。

DRM幀緩衝區的生命週期由引用計數控制,驅動程式可以使用drm_framebuffer_get()獲取額外的引用,並使用drm_framebuffer_put()再次釋放它們。對於驅動程式私有的幀緩衝區,其中最後一個引用永遠不會被釋放(例如,當struct drm_framebuffer結構嵌入到fbdev輔助結構中時,用於fbdev幀緩衝區),驅動程式可以在模組解除安裝時使用drm_framebuffer_unregister_private()手動清理幀緩衝區。但不建議這樣做,最好有一個獨立的struct drm_framebuffer

幀緩衝區函式參考

struct drm_framebuffer_funcs

幀緩衝區鉤子

定義:

struct drm_framebuffer_funcs {
    void (*destroy)(struct drm_framebuffer *framebuffer);
    int (*create_handle)(struct drm_framebuffer *fb,struct drm_file *file_priv, unsigned int *handle);
    int (*dirty)(struct drm_framebuffer *framebuffer,struct drm_file *file_priv, unsigned flags,unsigned color, struct drm_clip_rect *clips, unsigned num_clips);
};

成員

destroy

清理幀緩衝區資源,特別是取消對後備儲存的引用。核心保證為每個透過呼叫drm_mode_config_funcs.fb_create成功建立的幀緩衝區呼叫此函式。驅動程式還必須呼叫drm_framebuffer_cleanup()來釋放此幀緩衝區的DRM核心資源。

create_handle

在特定於驅動程式的緩衝區管理器(GEM或TTM)中為傳入的struct drm_file建立一個緩衝區控制代碼。核心使用它來實現GETFB IOCTL,它(對於具有足夠許可權的使用者)也返回一個本機緩衝區控制代碼。這可以用於模式設定客戶端之間的無縫轉換,方法是將當前螢幕內容複製到私有緩衝區,並在該緩衝區和新內容之間進行混合。

基於GEM的驅動程式應該呼叫drm_gem_handle_create()來建立控制代碼。

返回值

成功時為 0,失敗時為負錯誤程式碼。

dirty

用於髒fb IOCTL的可選回撥。

使用者空間可以透過此回撥通知驅動程式幀緩衝區的某個區域已更改,應重新整理到顯示硬體。這也可以在內部使用,例如,透過fbdev模擬,但目前情況並非如此。

有關更多資訊,請參閱drm_mode.h中的drm_mode_fb_dirty_cmd結構文件,因為所有語義和引數都與此函式一一對應。

原子驅動程式應使用drm_atomic_helper_dirtyfb()來實現此鉤子。

返回值

成功時為 0,失敗時為負錯誤程式碼。

struct drm_framebuffer

幀緩衝區物件

定義:

struct drm_framebuffer {
    struct drm_device *dev;
    struct list_head head;
    struct drm_mode_object base;
    char comm[TASK_COMM_LEN];
    const struct drm_format_info *format;
    const struct drm_framebuffer_funcs *funcs;
    unsigned int pitches[DRM_FORMAT_MAX_PLANES];
    unsigned int offsets[DRM_FORMAT_MAX_PLANES];
    uint64_t modifier;
    unsigned int width;
    unsigned int height;
    int flags;
    struct list_head filp_head;
    struct drm_gem_object *obj[DRM_FORMAT_MAX_PLANES];
};

成員

dev

此幀緩衝區所屬的DRM裝置

head

放置在drm_mode_config.fb_list上,訪問受drm_mode_config.fb_lock保護。

基本

基本模式設定物件結構,包含引用計數。

comm

分配fb的程序名稱,用於fb轉儲。

格式

幀緩衝區格式資訊

funcs

幀緩衝區vfunc表

pitches

每個緩衝區的行跨度。對於使用者空間建立的物件,這是從drm_mode_fb_cmd2複製的。

offsets

從緩衝區開始到實際畫素資料的偏移量(以位元組為單位),每個緩衝區。對於使用者空間建立的物件,這是從drm_mode_fb_cmd2複製的。

請注意,這是一個線性偏移量,不考慮每個modifier的平鋪或緩衝區佈局。它旨在用於此幀緩衝區平面的實際畫素資料以偏移量開始時,例如,當多個平面在同一個後備儲存緩衝區物件中分配時。對於平鋪佈局,這通常意味著它的offsets必須至少與平鋪大小對齊,但硬體通常有更嚴格的要求。

這不應用於指定到緩衝區資料中的x/y畫素偏移量(即使對於線性緩衝區)。指定x/y畫素偏移量而是透過struct drm_plane_state中的源矩形完成的。

modifier

資料佈局修飾符。這用於描述輔助緩衝區的平鋪或特殊佈局(如壓縮)。對於使用者空間建立的物件,這是從drm_mode_fb_cmd2複製的。

width

幀緩衝區可見區域的邏輯寬度(以畫素為單位)。

height

幀緩衝區可見區域的邏輯高度(以畫素為單位)。

標誌

幀緩衝區標誌,如DRM_MODE_FB_INTERLACED或DRM_MODE_FB_MODIFIERS。

filp_head

放置在drm_file.fbs上,受drm_file.fbs_lock保護。

obj

支援幀緩衝區的GEM物件,每個平面一個(可選)。

這由GEM幀緩衝區輔助程式使用,例如,請參閱drm_gem_fb_create()

描述

請注意,fb被引用計數,以方便驅動程式內部使用,例如,某些硬體,停用CRTC/平面是非同步的,並且掃描輸出實際上直到下一個垂直消隱才完成。因此,一些清理(如釋放對後備GEM bo的引用)應該被推遲。在這種情況下,驅動程式希望保持對fb的引用,即使它已經從使用者空間的角度刪除了。請參閱drm_framebuffer_get()drm_framebuffer_put()

引用計數儲存在模式物件base中。

void drm_framebuffer_get(struct drm_framebuffer *fb)

獲取幀緩衝區引用

引數

struct drm_framebuffer *fb

DRM幀緩衝區

描述

此函式遞增幀緩衝區的引用計數。

void drm_framebuffer_put(struct drm_framebuffer *fb)

釋放幀緩衝區引用

引數

struct drm_framebuffer *fb

DRM幀緩衝區

描述

此函式遞減幀緩衝區的引用計數,如果引用計數降至零,則釋放幀緩衝區。

uint32_t drm_framebuffer_read_refcount(const struct drm_framebuffer *fb)

讀取幀緩衝區引用計數。

引數

const struct drm_framebuffer *fb

幀緩衝區

描述

此函式返回幀緩衝區的引用計數。

void drm_framebuffer_assign(struct drm_framebuffer **p, struct drm_framebuffer *fb)

儲存對fb的引用

引數

struct drm_framebuffer **p

儲存幀緩衝區的位置

struct drm_framebuffer *fb

新的幀緩衝區(可能為NULL)

描述

此函式設定儲存對幀緩衝區的引用的位置,取消引用先前儲存在該位置的幀緩衝區。

struct drm_afbc_framebuffer

一個特殊的afbc幀緩衝區物件

定義:

struct drm_afbc_framebuffer {
    struct drm_framebuffer base;
    u32 block_width;
    u32 block_height;
    u32 aligned_width;
    u32 aligned_height;
    u32 offset;
    u32 afbc_size;
};

成員

基本

基本幀緩衝區結構。

block_width

單個afbc塊的寬度

block_height

單個afbc塊的高度

aligned_width

對齊的幀緩衝區寬度

aligned_height

對齊的幀緩衝區高度

offset

第一個afbc標頭的偏移量

afbc_size

afbc緩衝區的最小大小

描述

一個struct drm_framebuffer的派生類,專用於afbc用例。

int drm_framebuffer_init(struct drm_device *dev, struct drm_framebuffer *fb, const struct drm_framebuffer_funcs *funcs)

初始化幀緩衝區

引數

struct drm_device *dev

DRM 裝置

struct drm_framebuffer *fb

要初始化的幀緩衝區

const struct drm_framebuffer_funcs *funcs

...使用這些函式

描述

為幀緩衝區的父模式物件分配一個ID,設定其模式函式和裝置檔案,並將其新增到主fd列表。

重要提示:此函式釋出fb並使其可供其他使用者併發訪問。這意味著到目前為止,fb _必須_完全設定 - 由於所有fb屬性在其生命週期內是不變的,因此不需要進一步鎖定,只需要正確的引用計數。

返回

成功時為零,失敗時為錯誤程式碼。

struct drm_framebuffer *drm_framebuffer_lookup(struct drm_device *dev, struct drm_file *file_priv, uint32_t id)

查詢DRM幀緩衝區並獲取引用

引數

struct drm_device *dev

drm 裝置

struct drm_file *file_priv

用於檢查租賃的 DRM 檔案。

uint32_t id

fb物件的id

描述

如果成功,這將獲取對幀緩衝區的額外引用 - 呼叫者需要確保最終再次取消引用返回的幀緩衝區,使用drm_framebuffer_put()

void drm_framebuffer_unregister_private(struct drm_framebuffer *fb)

從查詢idr中登出私有fb

引數

struct drm_framebuffer *fb

要登出的fb

描述

驅動程式需要在清理驅動程式私有幀緩衝區時呼叫此函式,例如,用於fbdev的幀緩衝區。請注意,呼叫者必須持有自己的引用,即物件可能不會透過此呼叫銷燬(因為它會導致鎖定反轉)。

注意

此函式已棄用。對於驅動程式私有幀緩衝區,不建議將幀緩衝區結構嵌入到fbdev結構中,而是首選幀緩衝區指標,並且在清理幀緩衝區時應呼叫drm_framebuffer_put()

void drm_framebuffer_cleanup(struct drm_framebuffer *fb)

刪除幀緩衝區物件

引數

struct drm_framebuffer *fb

要刪除的幀緩衝區

描述

清理幀緩衝區。此函式旨在從驅動程式的drm_framebuffer_funcs.destroy回撥中使用。它也可以用於清理嵌入到較大結構中的驅動程式私有幀緩衝區。

請注意,此函式不會從活動使用中刪除fb - 如果它仍然在任何地方使用,可能會出現混亂,因為使用者空間可以呼叫getfb上的id並返回-EINVAL。顯然,在驅動程式解除安裝時不用擔心。

此外,幀緩衝區不會從查詢idr中刪除 - 對於使用者建立的幀緩衝區,這將發生在rmfb ioctl中。對於驅動程式私有物件(例如,對於fbdev),驅動程式需要顯式呼叫drm_framebuffer_unregister_private。

void drm_framebuffer_remove(struct drm_framebuffer *fb)

刪除並取消引用幀緩衝區物件

引數

struct drm_framebuffer *fb

要刪除的幀緩衝區

描述

掃描dev的mode_config中的所有CRTC和平面。如果它們正在使用fb,則將其刪除,將其設定為NULL。然後刪除對傳入幀緩衝區的引用。可能需要模式設定鎖。

請注意,如果呼叫者持有對幀緩衝區的最後一個引用,則此函式會最佳化清理過程。在這種情況下,它也保證不會獲取模式設定鎖。

DRM格式處理

在DRM子系統中,幀緩衝區畫素格式使用include/uapi/drm/drm_fourcc.h中定義的fourcc程式碼描述。除了fourcc程式碼外,還可以選擇提供格式修飾符,以便進一步描述緩衝區的格式 - 例如平鋪或壓縮。

格式修飾符

格式修飾符與fourcc程式碼結合使用,形成唯一的fourcc:modifier對。此格式:modifier對必須完全定義緩衝區的格式和資料佈局,並且應該是描述該特定緩衝區的唯一方法。

應避免具有描述相同佈局的多個fourcc:modifier對,因為此類別名存在不同的驅動程式為相同資料格式公開不同名稱的風險,從而迫使使用者空間瞭解它們是別名。

格式修飾符可以更改緩衝區的任何屬性,包括平面數和/或所需的分配大小。格式修飾符是供應商命名的,因此fourcc程式碼和修飾符之間的關係特定於正在使用的修飾符。例如,某些修飾符可能會保留來自fourcc程式碼的含義 - 例如平面數 - 而另一些修飾符可能不會。

修飾符必須唯一地編碼緩衝區佈局。換句話說,一個緩衝區必須只匹配一個修飾符。一個修飾符不能是另一個修飾符的佈局的子集。例如,在修飾符中編碼pitch對齊是不正確的:一個緩衝區可能匹配一個64畫素對齊的修飾符和一個32畫素對齊的修飾符。也就是說,修飾符可以具有隱式最小要求。

對於fourcc程式碼和修飾符的組合可以別名的修飾符,需要定義一個規範對並由所有驅動程式使用。還鼓勵使用首選組合,在所有組合都可能導致混淆並過度降低互操作性的情況下。AFBC是後者的一個例子,其中ABGR佈局優先於ARGB佈局。

有兩種型別的修飾符使用者

  • 核心和使用者空間驅動程式:對於驅動程式來說,修飾符不別名非常重要,否則兩個驅動程式可能支援相同的格式但使用不同的別名,從而阻止它們以高效的格式共享緩衝區。

  • 與KMS/GBM/EGL/Vulkan等介面的高階程式:這些使用者將修飾符視為他們可以檢查相等性和相交的不透明令牌。這些使用者不需要知道修飾符值的推理(即,不期望他們從修飾符中提取資訊)。

供應商應儘可能詳細地記錄其修飾符的使用情況,以確保跨裝置、驅動程式和應用程式的最大相容性。

格式修飾符程式碼的權威列表可以在include/uapi/drm/drm_fourcc.h中找到

開源使用者豁免

因為這是GL、Vulkan擴充套件和其他標準引用的畫素格式和修飾符的權威來源,因此被開源和閉源驅動程式堆疊使用,因此通常的上游核心或開源使用者空間使用者的要求不適用。

為了儘可能確保跨堆疊的相容性,並避免與不相容的列舉混淆,所有相關驅動程式堆疊的利益相關者都應批准新增。

格式函式參考

DRM_FORMAT_MAX_PLANES

DRM_FORMAT_MAX_PLANES

DRM格式可以具有的最大平面數

struct drm_format_info

有關DRM格式的資訊

定義:

struct drm_format_info {
    u32 format;
    u8 depth;
    u8 num_planes;
    union {
        u8 cpp[DRM_FORMAT_MAX_PLANES];
        u8 char_per_block[DRM_FORMAT_MAX_PLANES];
    };
    u8 block_w[DRM_FORMAT_MAX_PLANES];
    u8 block_h[DRM_FORMAT_MAX_PLANES];
    u8 hsub;
    u8 vsub;
    bool has_alpha;
    bool is_yuv;
    bool is_color_indexed;
};

成員

格式

4CC格式識別符號 (DRM_FORMAT_*)

depth

顏色深度(每個畫素的位數,不包括填充位),僅對RGB格式的子集有效。這是一個遺留欄位,請勿在新程式碼中使用,併為新格式設定為0。

num_planes

顏色平面數(1到3)

{unnamed_union}

anonymous

cpp

每個畫素(每個平面)的位元組數,這與char_per_block別名。不推薦使用它,而推薦使用三元組char_per_blockblock_wblock_h,以便更好地描述畫素格式。

char_per_block

每個塊(每個平面)的位元組數,其中塊定義為畫素的矩形,這些畫素儲存在位元組對齊的記憶體區域中。與block_wblock_h一起,這用於正確描述平鋪格式中的圖塊或描述打包格式中的畫素組,對於這些格式,單個畫素所需的記憶體不是位元組對齊的。

由於驅動程式中有很多地方使用cpp,因此出於歷史原因保留了它。在drm核心中,對於通用程式碼路徑,首選使用char_per_blockdrm_format_info_block_width()drm_format_info_block_height(),這允許以相同的方式處理塊和非塊格式。

對於僅用於非線性修改器的格式,通用格式表中的 cppchar_per_block 必須都為 0。如果驅動程式希望核心驗證 pitch,它們可以從其 drm_mode_config.get_format_info 鉤子提供準確的資訊。

block_w

塊的畫素寬度,旨在透過 drm_format_info_block_width() 訪問

block_h

塊的畫素高度,旨在透過 drm_format_info_block_height() 訪問

hsub

水平色度子取樣因子

vsub

垂直色度子取樣因子

has_alpha

該格式是否嵌入了 alpha 分量?

is_yuv

它是否是 YUV 格式?

is_color_indexed

它是否是顏色索引格式?

bool drm_format_info_is_yuv_packed(const struct drm_format_info *info)

檢查格式資訊是否與以單平面形式排列的 YUV 格式匹配

引數

const struct drm_format_info *info

格式資訊

返回

一個布林值,指示格式資訊是否與 packed YUV 格式匹配。

bool drm_format_info_is_yuv_semiplanar(const struct drm_format_info *info)

檢查格式資訊是否與以兩個平面形式排列的 YUV 格式匹配(亮度分量和色度分量)

引數

const struct drm_format_info *info

格式資訊

返回

一個布林值,指示格式資訊是否與 semiplanar YUV 格式匹配。

bool drm_format_info_is_yuv_planar(const struct drm_format_info *info)

檢查格式資訊是否與以三個平面形式排列的 YUV 格式匹配(每個 YUV 分量一個平面)

引數

const struct drm_format_info *info

格式資訊

返回

一個布林值,指示格式資訊是否與 planar YUV 格式匹配。

bool drm_format_info_is_yuv_sampling_410(const struct drm_format_info *info)

檢查格式資訊是否與 4:1:0 子取樣的 YUV 格式匹配

引數

const struct drm_format_info *info

格式資訊

返回

一個布林值,指示格式資訊是否與 4:1:0 子取樣的 YUV 格式匹配。

bool drm_format_info_is_yuv_sampling_411(const struct drm_format_info *info)

檢查格式資訊是否與 4:1:1 子取樣的 YUV 格式匹配

引數

const struct drm_format_info *info

格式資訊

返回

一個布林值,指示格式資訊是否與 4:1:1 子取樣的 YUV 格式匹配。

bool drm_format_info_is_yuv_sampling_420(const struct drm_format_info *info)

檢查格式資訊是否與 4:2:0 子取樣的 YUV 格式匹配

引數

const struct drm_format_info *info

格式資訊

返回

一個布林值,指示格式資訊是否與 4:2:0 子取樣的 YUV 格式匹配。

bool drm_format_info_is_yuv_sampling_422(const struct drm_format_info *info)

檢查格式資訊是否與 4:2:2 子取樣的 YUV 格式匹配

引數

const struct drm_format_info *info

格式資訊

返回

一個布林值,指示格式資訊是否與 4:2:2 子取樣的 YUV 格式匹配。

bool drm_format_info_is_yuv_sampling_444(const struct drm_format_info *info)

檢查格式資訊是否與 4:4:4 子取樣的 YUV 格式匹配

引數

const struct drm_format_info *info

格式資訊

返回

一個布林值,指示格式資訊是否與 4:4:4 子取樣的 YUV 格式匹配。

int drm_format_info_plane_width(const struct drm_format_info *info, int width, int plane)

給定第一個平面,計算該平面的寬度

引數

const struct drm_format_info *info

畫素格式資訊

int width

第一個平面的寬度

int plane

平面索引

返回

如果第一個平面的寬度為 width,則 plane 的寬度。

int drm_format_info_plane_height(const struct drm_format_info *info, int height, int plane)

給定第一個平面,計算該平面的高度

引數

const struct drm_format_info *info

畫素格式資訊

int height

第一個平面的高度

int plane

平面索引

返回

如果第一個平面的高度為 height,則 plane 的高度。

uint32_t drm_mode_legacy_fb_format(uint32_t bpp, uint32_t depth)

從傳統描述計算 drm fourcc 程式碼

引數

uint32_t bpp

每畫素位數

uint32_t depth

每畫素位深度

描述

為給定的 bpp/depth 值計算 drm fourcc 畫素格式程式碼。

uint32_t drm_driver_legacy_fb_format(struct drm_device *dev, uint32_t bpp, uint32_t depth)

從傳統描述計算 drm fourcc 程式碼

引數

struct drm_device *dev

DRM 裝置

uint32_t bpp

每畫素位數

uint32_t depth

每畫素位深度

描述

為給定的 bpp/depth 值計算 drm fourcc 畫素格式程式碼。與 drm_mode_legacy_fb_format() 不同,它會檢視驅動程式的 mode_config,並根據 drm_mode_config.quirk_addfb_prefer_host_byte_order 標誌返回小端位元組序或主機位元組序幀緩衝格式。

uint32_t drm_driver_color_mode_format(struct drm_device *dev, unsigned int color_mode)

從顏色模式計算 DRM 4CC 程式碼

引數

struct drm_device *dev

DRM 裝置

unsigned int color_mode

命令列顏色模式

描述

使用 drm_driver_color_mode() 為給定的顏色模式計算 DRM 4CC 畫素格式程式碼。顏色模式採用命令列使用的格式。它在一個值中指定每畫素的位數和顏色深度。

在 fbdev 模擬程式碼中非常有用,因為它處理這些值。該助手不考慮 YUV 或其他複雜格式。這意味著僅支援傳統格式(fmt->depth 是一個傳統欄位),但幀緩衝模擬只能處理此類格式,特別是 RGB/BGA 格式。

const struct drm_format_info *drm_format_info(u32 format)

查詢給定格式的資訊

引數

u32 format

畫素格式 (DRM_FORMAT_*)

描述

呼叫者應僅將支援的畫素格式傳遞給此函式。不支援的畫素格式將在核心日誌中生成警告。

返回

描述畫素格式的 struct drm_format_info 例項,如果不支援該格式,則為 NULL。

const struct drm_format_info *drm_get_format_info(struct drm_device *dev, const struct drm_mode_fb_cmd2 *mode_cmd)

查詢給定幀緩衝配置的資訊

引數

struct drm_device *dev

DRM 裝置

const struct drm_mode_fb_cmd2 *mode_cmd

來自使用者空間 fb 建立請求的元資料

返回

描述畫素格式的 struct drm_format_info 例項,如果不支援該格式,則為 NULL。

unsigned int drm_format_info_block_width(const struct drm_format_info *info, int plane)

塊的畫素寬度。

引數

const struct drm_format_info *info

畫素格式資訊

int plane

平面索引

返回

塊的畫素寬度,具體取決於平面索引。

unsigned int drm_format_info_block_height(const struct drm_format_info *info, int plane)

塊的畫素高度

引數

const struct drm_format_info *info

畫素格式資訊

int plane

平面索引

返回

塊的畫素高度,具體取決於平面索引。

unsigned int drm_format_info_bpp(const struct drm_format_info *info, int plane)

每畫素位數

引數

const struct drm_format_info *info

畫素格式資訊

int plane

平面索引

返回

每畫素的實際位數,具體取決於平面索引。

uint64_t drm_format_info_min_pitch(const struct drm_format_info *info, int plane, unsigned int buffer_width)

計算所需的最小 pitch(以位元組為單位)

引數

const struct drm_format_info *info

畫素格式資訊

int plane

平面索引

unsigned int buffer_width

緩衝區寬度(以畫素為單位)

返回

透過考慮畫素格式資訊和緩衝區寬度,計算緩衝區所需的最小 pitch(以位元組為單位)。

Dumb 緩衝區物件

KMS API 不標準化後備儲存物件的建立,而是將其留給特定於驅動程式的 ioctl。此外,即使對於基於 GEM 的驅動程式,實際建立緩衝區物件也是透過特定於驅動程式的 ioctl 完成的 - GEM 僅具有用於共享和銷燬物件的通用使用者空間介面。雖然對於包括裝置特定使用者空間元件的完整圖形堆疊(例如在 libdrm 中)來說這不是問題,但此限制使基於 DRM 的早期啟動圖形不必要地複雜。

Dumb 物件透過提供適用於掃描輸出的 dumb 緩衝區的標準 API,部分緩解了該問題,然後可用於建立 KMS 幀緩衝區。

為了支援 dumb 物件,驅動程式必須實現 drm_driver.dumb_createdrm_driver.dumb_map_offset 操作(如果未設定後者,則預設為 drm_gem_dumb_map_offset())。不使用 GEM 控制代碼的驅動程式還需要實現 drm_driver.dumb_destroy 操作。有關更多詳細資訊,請參見回撥。

請注意,dumb 物件可能不用於 gpu 加速,正如某些 ARM 嵌入式平臺上嘗試的那樣。此類驅動程式確實必須具有特定於硬體的 ioctl 才能分配合適的緩衝區物件。

平面抽象

平面表示一個影像源,可以在掃描輸出過程中與 CRTC 混合或疊加在 CRTC 之上。平面從 drm_framebuffer 物件獲取其輸入資料。平面本身指定該影像的裁剪和縮放,以及它在顯示流水線的可見區域上的位置,該可見區域由 drm_crtc 表示。平面還可以具有指定畫素如何定位和混合的其他屬性,例如旋轉或 Z 軸位置。所有這些屬性都儲存在 drm_plane_state 中。

除非明確指定(透過 CRTC 屬性或其他方式),否則 CRTC 的活動區域預設將為黑色。這意味著未被平面覆蓋的活動區域部分將為黑色,並且任何平面與 CRTC 背景的 alpha 混合將在最低 zpos 處與黑色混合。

要建立平面,KMS 驅動程式會分配並將 struct drm_plane 的例項清零(可能作為更大的結構的一部分),並透過呼叫 drm_universal_plane_init() 註冊它。

每個平面都有一個型別,請參見 enum drm_plane_type。一個平面可以與多個 CRTC 相容,請參見 drm_plane.possible_crtcs

每個 CRTC 必須具有一個唯一的 primary plane,使用者空間可以附加該 primary plane 以啟用 CRTC。換句話說,使用者空間必須能夠同時將不同的 primary plane 附加到每個 CRTC。Primary plane 仍然可以與多個 CRTC 相容。Primary plane 的數量必須與 CRTC 的數量完全相同。

舊版 uAPI 不會直接公開 primary plane 和 cursor plane。DRM 核心依賴於驅動程式來設定用於舊版 IOCTL 的 primary plane 和可選的 cursor plane。這是透過呼叫 drm_crtc_init_with_planes() 來完成的。所有驅動程式都必須為每個 CRTC 提供一個 primary plane,以避免讓舊版使用者空間感到意外。

平面函式參考

struct drm_plane_state

可變平面狀態

定義:

struct drm_plane_state {
    struct drm_plane *plane;
    struct drm_crtc *crtc;
    struct drm_framebuffer *fb;
    struct dma_fence *fence;
    int32_t crtc_x;
    int32_t crtc_y;
    uint32_t crtc_w, crtc_h;
    uint32_t src_x;
    uint32_t src_y;
    uint32_t src_h, src_w;
    int32_t hotspot_x, hotspot_y;
    u16 alpha;
    uint16_t pixel_blend_mode;
    unsigned int rotation;
    unsigned int zpos;
    unsigned int normalized_zpos;
    enum drm_color_encoding color_encoding;
    enum drm_color_range color_range;
    struct drm_property_blob *fb_damage_clips;
    bool ignore_damage_clips;
    struct drm_rect src, dst;
    bool visible;
    enum drm_scaling_filter scaling_filter;
    struct drm_crtc_commit *commit;
    struct drm_atomic_state *state;
    bool color_mgmt_changed : 1;
};

成員

plane

指向平面的後向指標

crtc

當前繫結的 CRTC,如果停用則為 NULL。不要直接寫入此項,請使用 drm_atomic_set_crtc_for_plane()

fb

當前繫結的幀緩衝區。不要直接寫入此項,請使用 drm_atomic_set_fb_for_plane()

fence

在掃描輸出 fb 之前要等待的可選 fence。當用戶空間使用顯式 fencing 時,核心原子程式碼將設定此項。不要為驅動程式的隱式 fence 直接寫入此欄位。

驅動程式應從此結構中儲存來自其 drm_plane_helper_funcs.prepare_fb 回撥中的任何隱式 fence。請參見 drm_gem_plane_helper_prepare_fb() 以獲取合適的幫助程式。

crtc_x

平面在 crtc 上的可見部分的左側位置,帶符號的目標位置允許其部分位於螢幕外。

crtc_y

平面在 crtc 上的可見部分的上方位置,帶符號的目標位置允許其部分位於螢幕外。

crtc_w

平面在 crtc 上的可見部分的寬度

crtc_h

平面在 crtc 上的可見部分的高度

src_x

平面內平面可見部分的左側位置(以 16.16 定點表示)。

src_y

平面內平面可見部分的上方位置(以 16.16 定點表示)。

src_h

平面可見部分的高度(以 16.16 表示)

src_w

平面可見部分的寬度(以 16.16 表示)

hotspot_x

滑鼠游標熱點的 x 偏移量

hotspot_y

滑鼠游標熱點的 y 偏移量

alpha

平面的不透明度,0 表示完全透明,0xffff 表示完全不透明。有關更多詳細資訊,請參見 drm_plane_create_alpha_property()

pixel_blend_mode

alpha 混合公式選擇,描述當前平面的畫素如何與背景合成。值可以是 DRM_MODE_BLEND_* 之一

rotation

平面的旋轉。有關更多詳細資訊,請參見 drm_plane_create_rotation_property()

zpos

給定平面在 crtc 上的優先順序(可選)。

使用者空間可以設定可變 zpos 屬性,以便同一 CRTC 上的多個活動平面具有相同的 zpos 值。這是一個使用者空間的錯誤,但驅動程式可以透過比較平面物件 ID 來解決衝突;ID 較高的平面堆疊在 ID 較低的平面之上。

有關更多詳細資訊,請參見 drm_plane_create_zpos_property()drm_plane_create_zpos_immutable_property()

normalized_zpos

zpos 的標準化值:唯一,範圍從 0 到 N-1,其中 N 是給定 crtc 的活動平面數。請注意,驅動程式必須設定 drm_mode_config.normalize_zpos 或呼叫 drm_atomic_normalize_zpos() 以在此值可信之前更新它。

color_encoding

非 RGB 格式的顏色編碼

color_range

非 RGB 格式的顏色範圍

fb_damage_clips

Blob 表示損壞(自上次平面更新以來平面幀緩衝區中更改的區域),作為附加幀緩衝區的幀緩衝區座標中的 drm_mode_rect 陣列。請注意,與平面 src 不同,損壞剪輯不是 16.16 定點。

有關訪問這些剪輯的資訊,請參見 drm_plane_get_damage_clips()drm_plane_get_damage_clips_count()

ignore_damage_clips

由驅動程式設定,以指示 drm_atomic_helper_damage_iter_init() 幫助程式應忽略 fb_damage_clips blob 屬性。

有關更多資訊,請參見 損壞跟蹤屬性

src

平面的源座標(以 16.16 表示)。

使用 drm_atomic_helper_check_plane_state() 時,座標會被裁剪,但當硬體自動執行裁剪時,驅動程式可以選擇改用未裁剪的座標。

dst

平面的裁剪目標座標。

使用 drm_atomic_helper_check_plane_state() 時,座標會被裁剪,但當硬體自動執行裁剪時,驅動程式可以選擇改用未裁剪的座標。

visible

平面的可見性。即使 fb!=NULL 且 crtc!=NULL,由於裁剪,這也可能為 false。

scaling_filter

要應用的縮放過濾器

提交

跟蹤掛起的提交以防止使用後釋放情況,並用於非同步平面更新。

可能為 NULL。

state

指向全域性 drm_atomic_state 的後向指標

color_mgmt_changed

顏色管理屬性已更改。由原子幫助程式和驅動程式用於引導原子提交控制流。

描述

請注意,目標座標 crtc_xcrtc_ycrtc_hcrtc_w 以及源座標 src_xsrc_ysrc_hsrc_w 是使用者空間提供的原始座標。驅動程式應使用 drm_atomic_helper_check_plane_state(),並且僅使用 srcdst 中的派生矩形來程式設計硬體。

struct drm_plane_funcs

驅動程式平面控制函式

定義:

struct drm_plane_funcs {
    int (*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);
    int (*disable_plane)(struct drm_plane *plane, struct drm_modeset_acquire_ctx *ctx);
    void (*destroy)(struct drm_plane *plane);
    void (*reset)(struct drm_plane *plane);
    int (*set_property)(struct drm_plane *plane, struct drm_property *property, uint64_t val);
    struct drm_plane_state *(*atomic_duplicate_state)(struct drm_plane *plane);
    void (*atomic_destroy_state)(struct drm_plane *plane, struct drm_plane_state *state);
    int (*atomic_set_property)(struct drm_plane *plane,struct drm_plane_state *state,struct drm_property *property, uint64_t val);
    int (*atomic_get_property)(struct drm_plane *plane,const struct drm_plane_state *state,struct drm_property *property, uint64_t *val);
    int (*late_register)(struct drm_plane *plane);
    void (*early_unregister)(struct drm_plane *plane);
    void (*atomic_print_state)(struct drm_printer *p, const struct drm_plane_state *state);
    bool (*format_mod_supported)(struct drm_plane *plane, uint32_t format, uint64_t modifier);
    bool (*format_mod_supported_async)(struct drm_plane *plane, u32 format, u64 modifier);
};

成員

update_plane

這是啟用和配置給定 CRTC 和幀緩衝區的平面的舊版入口點。它永遠不會被呼叫來停用平面,即傳入的 crtc 和 fb 引數永遠不會為 NULL。

幀緩衝區記憶體座標中的源矩形由 src_x、src_y、src_w 和 src_h 引數給出(作為 16.16 定點值)。不支援子畫素平面座標的裝置可以忽略小數部分。

CRTC 座標中的目標矩形由 crtc_x、crtc_y、crtc_w 和 crtc_h 引數給出(作為整數值)。裝置將源矩形縮放到目標矩形。如果不支援縮放,並且源矩形大小與目標矩形大小不匹配,則驅動程式必須返回 -<errorname>EINVAL</errorname> 錯誤。

實現原子模式設定的驅動程式應使用 drm_atomic_helper_update_plane() 來實現此掛鉤。

返回值

成功時為 0,失敗時為負錯誤程式碼。

disable_plane

這是停用平面的舊版入口點。DRM 核心響應於幀緩衝區 ID 設定為 0 的 DRM_IOCTL_MODE_SETPLANE IOCTL 呼叫來呼叫此方法。CRTC 不得處理停用的平面。

實現原子模式設定的驅動程式應使用 drm_atomic_helper_disable_plane() 來實現此掛鉤。

返回值

成功時為 0,失敗時為負錯誤程式碼。

destroy

清理平面資源。這僅在驅動程式解除安裝時透過 drm_mode_config_cleanup() 呼叫,因為平面無法在 DRM 中熱插拔。

重置

將平面硬體和軟體狀態重置為關閉。此函式不是由核心直接呼叫,而是僅透過 drm_mode_config_reset() 呼叫。它不是幫助程式掛鉤,僅是出於歷史原因。

原子驅動程式可以使用 drm_atomic_helper_plane_reset() 以使用此掛鉤重置原子狀態。

set_property

這是更新附加到平面的屬性的舊版入口點。

如果驅動程式不支援任何舊版驅動程式私有屬性,則此回撥是可選的。對於原子驅動程式,它不使用,因為屬性處理完全在 DRM 核心中完成。

返回值

成功時為 0,失敗時為負錯誤程式碼。

atomic_duplicate_state

為此平面複製當前原子狀態並返回它。核心和幫助程式保證使用此掛鉤複製的任何原子狀態,並且仍然由呼叫方擁有(即,未透過呼叫 drm_mode_config_funcs.atomic_commit 轉移到驅動程式)將透過呼叫此結構中的 atomic_destroy_state 掛鉤來清理。

此回撥對於原子驅動程式是必需的。

不繼承 struct drm_plane_state 的原子驅動程式應使用 drm_atomic_helper_plane_duplicate_state()。繼承狀態結構以使用驅動程式私有狀態擴充套件它的驅動程式應使用 __drm_atomic_helper_plane_duplicate_state() 以確保在驅動程式之間以一致的方式複製共享狀態。

在正確初始化 drm_plane.state 之前呼叫此掛鉤是一個錯誤。

注意

如果重複的狀態引用了引用計數的資源,則此鉤子必須獲取對每個資源的引用。驅動程式必須在 **atomic_destroy_state** 中再次釋放這些引用。

返回值

重複的原子狀態,或者當分配失敗時為 NULL。

atomic_destroy_state

銷燬使用 **atomic_duplicate_state** 複製的狀態,並釋放或取消引用它引用的所有資源

此回撥對於原子驅動程式是必需的。

atomic_set_property

解碼驅動程式私有屬性值,並將解碼後的值儲存到傳入的狀態結構中。由於原子核心解碼所有標準化屬性(即使是超出核心屬性集範圍的擴充套件,這些擴充套件可能並非所有驅動程式都實現),因此這要求驅動程式繼承狀態結構。

此類驅動程式私有屬性實際上只應為真正的硬體/供應商特定狀態實現。相反,最好標準化原子擴充套件並在核心中解碼用於公開此類擴充套件的屬性。

不要直接呼叫此函式,請改為使用 drm_atomic_plane_set_property()。

如果驅動程式不支援任何驅動程式私有原子屬性,則此回撥是可選的。

注意

此函式在原子模式設定的狀態程式集階段中呼叫,該階段可能因任何原因中止(包括應使用者空間請求僅檢查配置是否可能)。驅動程式不得觸控任何持久狀態(硬體或軟體)或資料結構,除了傳入的 **state** 引數。

此外,由於使用者空間控制屬性的設定順序,因此此函式不得進行任何輸入驗證(因為狀態更新不完整,因此可能不一致)。相反,任何此類輸入驗證都必須在各種 atomic_check 回撥中完成。

返回值

如果已找到該屬性,則為 0;如果驅動程式未實現該屬性,則為 -EINVAL(這永遠不應發生,核心僅請求附加到此平面的屬性)。驅動程式不允許進行其他驗證。核心已檢查屬性值是否在驅動程式在註冊屬性時設定的範圍內(整數、有效列舉值等)。

atomic_get_property

讀出解碼的驅動程式私有屬性。這用於實現 GETPLANE IOCTL。

不要直接呼叫此函式,請改為使用 drm_atomic_plane_get_property()。

如果驅動程式不支援任何驅動程式私有原子屬性,則此回撥是可選的。

返回值

成功時為 0,如果驅動程式未實現該屬性,則為 -EINVAL(這永遠不應發生,核心僅請求附加到此平面的屬性)。

late_register

此可選掛鉤可用於註冊附加到平面的其他使用者空間介面,如 debugfs 介面。它在驅動程式載入序列的後期從 drm_dev_register() 呼叫。應在 early_unregister 回撥中取消註冊從此回撥新增的所有內容。

返回

成功時為 0,失敗時為負錯誤程式碼。

early_unregister

此可選掛鉤應用於取消註冊來自 late_register 的附加到平面的其他使用者空間介面。它從 drm_dev_unregister() 呼叫,在驅動程式解除安裝序列的早期停用使用者空間訪問,然後再分解資料結構。

atomic_print_state

如果驅動程式繼承 struct drm_plane_state,則它應實現此可選掛鉤以列印其他驅動程式特定狀態。

不要直接呼叫此函式,請改為使用 drm_atomic_plane_print_state()。

format_mod_supported

此可選掛鉤由 DRM 用於確定給定的格式/修飾符組合對於平面是否有效。這允許 DRM 生成正確的格式位掩碼(哪些格式適用於哪些修飾符),並在 atomic_check 時驗證修飾符。

如果不存在,則允許平面的修飾符列表中的任何修飾符與平面的任何格式一起使用。

返回

如果給定的修飾符對於平面上的該格式有效,則為 True。否則為 False。

format_mod_supported_async

此可選掛鉤由 DRM 用於確定對於非同步翻轉,給定的格式/修飾符組合對於平面是否有效。這允許 DRM 生成正確的格式位掩碼(哪些格式適用於哪些修飾符),並在 atomic_check 時驗證修飾符。

返回

如果給定的修飾符對於平面上的該格式有效,則為 True。否則為 False。

enum drm_plane_type

uapi 平面型別列舉

常量

DRM_PLANE_TYPE_OVERLAY

Overlay plane 表示所有非 primary、非 cursor plane。某些驅動程式在內部將這些型別的平面稱為“精靈”。

DRM_PLANE_TYPE_PRIMARY

當不使用縮放/裁剪並且平面覆蓋整個 CRTC 時,附加到 CRTC 的 primary plane 最有可能能夠點亮 CRTC。

DRM_PLANE_TYPE_CURSOR

當不使用縮放/裁剪並且幀緩衝區的大小由 drm_mode_config.cursor_widthdrm_mode_config.cursor_height 指示時,附加到 CRTC 的 cursor plane 更有可能能夠啟用。此外,如果驅動程式不支援修飾符,則幀緩衝區應具有線性佈局。

描述

由於歷史原因,並非所有平面的製造方式都相同。此列舉用於區分不同型別的平面,以實現它們的不同 uapi 語義。對於瞭解通用平面並且正在使用原子 IOCTL 的使用者空間,這些平面之間沒有區別(當然,除了驅動程式和硬體可以支援的內容之外)。

為了與舊版使用者空間相容,預設情況下僅向用戶空間提供 overlay plane。使用者空間客戶端可以設定 DRM_CLIENT_CAP_UNIVERSAL_PLANES 客戶端功能位,以指示他們希望接收包含所有平面型別的通用平面列表。另請參見 drm_for_each_legacy_plane()

除了設定每個平面的型別外,驅動程式還需要為舊版 IOCTL 設定 drm_crtc.primary 和可選的 drm_crtc.cursor 指標。請參見 drm_crtc_init_with_planes()

警告:此列舉的值是 UABI,因為它們在“type”屬性中公開。

struct drm_plane

中央 DRM 平面控制結構

定義:

struct drm_plane {
    struct drm_device *dev;
    struct list_head head;
    char *name;
    struct drm_modeset_lock mutex;
    struct drm_mode_object base;
    uint32_t possible_crtcs;
    uint32_t *format_types;
    unsigned int format_count;
    bool format_default;
    uint64_t *modifiers;
    unsigned int modifier_count;
    struct drm_crtc *crtc;
    struct drm_framebuffer *fb;
    struct drm_framebuffer *old_fb;
    const struct drm_plane_funcs *funcs;
    struct drm_object_properties properties;
    enum drm_plane_type type;
    unsigned index;
    const struct drm_plane_helper_funcs *helper_private;
    struct drm_plane_state *state;
    struct drm_property *alpha_property;
    struct drm_property *zpos_property;
    struct drm_property *rotation_property;
    struct drm_property *blend_mode_property;
    struct drm_property *color_encoding_property;
    struct drm_property *color_range_property;
    struct drm_property *scaling_filter_property;
    struct drm_property *hotspot_x_property;
    struct drm_property *hotspot_y_property;
    struct kmsg_dumper kmsg_panic;
};

成員

dev

此平面所屬的 DRM 裝置

head

dev 上的所有平面列表,從 drm_mode_config.plane_list 連結。在 dev 的生命週期內是不變的,因此不需要鎖定。

名稱

人類可讀的名稱,可以由驅動程式覆蓋

mutex

與此平面連結的 CRTC 的 drm_crtc.mutex 一起保護模式設定平面狀態(當活動、正在啟用或正在停用時)。

對於原子驅動程式,這專門保護 state

基本

基本模式物件

possible_crtcs

此平面可以繫結到的管道,由 drm_crtc_mask() 構造

format_types

此平面支援的格式陣列

format_count

format_types 指向的陣列的大小。

format_default

驅動程式未提供平面支援的格式。僅由非原子驅動程式相容性包裝器使用。

modifiers

此平面支援的修飾符陣列

modifier_count

modifier_count 指向的陣列的大小。

crtc

當前繫結的 CRTC,僅對非原子驅動程式有意義。對於原子驅動程式,這將被強制為 NULL,原子驅動程式應改為檢查 drm_plane_state.crtc

fb

當前繫結的幀緩衝區,僅對非原子驅動程式有意義。對於原子驅動程式,這將被強制為 NULL,原子驅動程式應改為檢查 drm_plane_state.fb

old_fb

在模式設定正在進行時,臨時跟蹤舊的 fb。僅由非原子驅動程式使用,對於原子驅動程式,這將被強制為 NULL。

funcs

平面控制函式

properties

此平面的屬性跟蹤

type

平面型別,有關詳細資訊,請參見 enum drm_plane_type

索引

模式配置列表中位置,可以用作陣列索引。在平面的生命週期內是不變的。

helper_private

中間層私有資料

state

此平面的當前原子狀態。

這受 mutex 保護。請注意,非阻塞原子提交無需獲取鎖即可訪問當前平面狀態。可以透過 struct drm_atomic_state 指標進行訪問,請參見 for_each_oldnew_plane_in_state()for_each_old_plane_in_state()for_each_new_plane_in_state()。或者透過原子幫助程式中實現的原子提交操作的仔細排序進行訪問,請參見 struct drm_crtc_commit

alpha_property

此平面可選的 alpha 屬性。請參閱 drm_plane_create_alpha_property()

zpos_property

此平面可選的 zpos 屬性。請參閱 drm_plane_create_zpos_property()

rotation_property

此平面可選的 rotation 屬性。請參閱 drm_plane_create_rotation_property()

blend_mode_property

此平面可選的“畫素混合模式”列舉屬性。混合模式屬性表示 alpha 混合方程的選擇,描述如何將當前平面的畫素與背景合成。

color_encoding_property

可選的“COLOR_ENCODING”列舉屬性,用於為非 RGB 格式指定顏色編碼。請參閱 drm_plane_create_color_properties()

color_range_property

可選的“COLOR_RANGE”列舉屬性,用於為非 RGB 格式指定顏色範圍。請參閱 drm_plane_create_color_properties()

scaling_filter_property

在縮放時應用特定過濾器的屬性。

hotspot_x_property

用於設定滑鼠熱點 x 偏移量的屬性。

hotspot_y_property

用於設定滑鼠熱點 y 偏移量的屬性。

kmsg_panic

用於為此平面註冊 panic 通知器

描述

平面代表顯示塊的掃描輸出硬體。它們從 drm_framebuffer 接收其輸入資料,並將其饋送到 drm_crtc。平面控制顏色轉換,更多細節請參閱 平面合成屬性,並且還參與輸入畫素的顏色轉換,有關詳細資訊,請參閱 顏色管理屬性

drmm_universal_plane_alloc

drmm_universal_plane_alloc (dev, type, member, possible_crtcs, funcs, formats, format_count, format_modifiers, plane_type, name, ...)

分配並初始化一個通用平面物件

引數

dev

DRM 裝置

type

包含結構體 drm_plane 的結構體的型別

member

typedrm_plane 的名稱

possible_crtcs

可能的 CRTC 的位掩碼

funcs

新平面的回撥

格式

支援格式的陣列 (DRM_FORMAT_*)

format_count

formats 中的元素數量

format_modifiers

struct drm_format modifiers 陣列,以 DRM_FORMAT_MOD_INVALID 結尾

plane_type

平面型別(overlay,primary,cursor)

名稱

平面名稱的 printf 樣式格式字串,如果為 NULL 則使用預設名稱

...

可變引數

描述

分配並初始化型別為 type 的平面物件。透過使用 drmm_add_action() 註冊 drm_plane_cleanup() 來自動處理清理工作。

drm_plane_funcs.destroy 鉤子必須為 NULL。

僅支援 DRM_FORMAT_MOD_LINEAR modifier 的驅動程式可以將 format_modifiers 設定為 NULL。該平面將宣告 linear modifier。

返回

指向新平面的指標,如果失敗,則為 ERR_PTR。

drm_universal_plane_alloc

drm_universal_plane_alloc (dev, type, member, possible_crtcs, funcs, formats, format_count, format_modifiers, plane_type, name, ...)

分配並初始化一個通用平面物件

引數

dev

DRM 裝置

type

包含結構體 drm_plane 的結構體的型別

member

typedrm_plane 的名稱

possible_crtcs

可能的 CRTC 的位掩碼

funcs

新平面的回撥

格式

支援格式的陣列 (DRM_FORMAT_*)

format_count

formats 中的元素數量

format_modifiers

struct drm_format modifiers 陣列,以 DRM_FORMAT_MOD_INVALID 結尾

plane_type

平面型別(overlay,primary,cursor)

名稱

平面名稱的 printf 樣式格式字串,如果為 NULL 則使用預設名稱

...

可變引數

描述

分配並初始化型別為 type 的平面物件。呼叫者負責使用 kfree() 釋放已分配的記憶體。

建議驅動程式使用 drmm_universal_plane_alloc() 代替。

僅支援 DRM_FORMAT_MOD_LINEAR modifier 的驅動程式可以將 format_modifiers 設定為 NULL。該平面將宣告 linear modifier。

返回

指向新平面的指標,如果失敗,則為 ERR_PTR。

unsigned int drm_plane_index(const struct drm_plane *plane)

查詢已註冊平面的索引

引數

要查詢索引的平面

用於查詢索引的平面

描述

給定一個已註冊的平面,返回該平面在 DRM 裝置平面列表中的索引。

u32 drm_plane_mask(const struct drm_plane *plane)

查詢已註冊平面的掩碼

引數

要查詢索引的平面

要查詢掩碼的平面

struct drm_plane *drm_plane_find(struct drm_device *dev, struct drm_file *file_priv, uint32_t id)

查詢一個 drm_plane

引數

struct drm_device *dev

DRM 裝置

struct drm_file *file_priv

用於檢查租賃的 DRM 檔案。

uint32_t id

平面 ID

描述

返回具有 id 的平面,如果不存在則返回 NULL。只是 drm_mode_object_find() 的一個簡單包裝器。

drm_for_each_plane_mask

drm_for_each_plane_mask (plane, dev, plane_mask)

迭代由位掩碼指定的平面

引數

plane

循環遊標

dev

DRM 裝置

plane_mask

平面索引的位掩碼

描述

迭代由位掩碼指定的所有平面。

drm_for_each_legacy_plane

drm_for_each_legacy_plane (plane, dev)

為舊版使用者空間迭代所有平面

引數

plane

循環遊標

dev

DRM 裝置

描述

迭代 dev 的所有舊版平面,不包括主平面和游標平面。當用戶空間不知道通用平面時,這對於實現使用者空間 API 非常有用。另請參閱 enum drm_plane_type

drm_for_each_plane

drm_for_each_plane (plane, dev)

迭代所有平面

引數

plane

循環遊標

dev

DRM 裝置

描述

迭代 dev 的所有平面,包括主平面和游標平面。

int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane, uint32_t possible_crtcs, const struct drm_plane_funcs *funcs, const uint32_t *formats, unsigned int format_count, const uint64_t *format_modifiers, enum drm_plane_type type, const char *name, ...)

初始化一個新的通用平面物件

引數

struct drm_device *dev

DRM 裝置

struct drm_plane *plane

要初始化的平面物件

uint32_t possible_crtcs

可能的 CRTC 的位掩碼

const struct drm_plane_funcs *funcs

新平面的回撥

const uint32_t *formats

支援格式的陣列 (DRM_FORMAT_*)

unsigned int format_count

formats 中的元素數量

const uint64_t *format_modifiers

struct drm_format modifiers 陣列,以 DRM_FORMAT_MOD_INVALID 結尾

enum drm_plane_type type

平面型別(overlay,primary,cursor)

const char *name

平面名稱的 printf 樣式格式字串,如果為 NULL 則使用預設名稱

...

可變引數

描述

初始化型別為 type 的平面物件。drm_plane_funcs.destroy 鉤子應該呼叫 drm_plane_cleanup() 並且使用 kfree() 釋放平面結構。不應該使用 devm_kzalloc() 分配平面結構。

僅支援 DRM_FORMAT_MOD_LINEAR modifier 的驅動程式可以將 format_modifiers 設定為 NULL。該平面將宣告 linear modifier。

注意

考慮使用 drmm_universal_plane_alloc() 代替 drm_universal_plane_init(),以便讓 DRM 管理的資源基礎架構處理清理和釋放。

返回

成功時為零,失敗時為錯誤程式碼。

void drm_plane_cleanup(struct drm_plane *plane)

清理核心平面使用情況

引數

struct drm_plane *plane

要清理的平面

描述

此函式清理 plane 並將其從 DRM 模式設定核心中移除。請注意,該函式 *不* 釋放平面結構本身,這由呼叫者負責。

struct drm_plane *drm_plane_from_index(struct drm_device *dev, int idx)

查詢指定索引處的已註冊平面

引數

struct drm_device *dev

DRM 裝置

int idx

要查詢的已註冊平面的索引

描述

給定一個平面索引,從 DRM 裝置的平面列表中返回具有匹配索引的已註冊平面。這是 drm_plane_index() 的逆操作。

void drm_plane_force_disable(struct drm_plane *plane)

強制停用一個平面

引數

struct drm_plane *plane

要停用的平面

描述

強制停用該平面。

在該平面當前 framebuffer 被銷燬時以及恢復 fbdev 模式時使用。

請注意,此函式不適用於原子驅動程式,因為它沒有正確地連線鎖定獲取上下文,因此無法處理重試或驅動程式私有鎖定。你可能想使用 drm_atomic_helper_disable_plane()drm_atomic_helper_disable_planes_on_crtc() 來代替。

int drm_mode_plane_set_obj_prop(struct drm_plane *plane, struct drm_property *property, uint64_t value)

設定屬性的值

引數

struct drm_plane *plane

要在其上設定屬性值的 drm 平面物件

struct drm_property *property

要設定的屬性

uint64_t value

屬性應設定為的值

描述

此函式在給定的平面物件上設定給定的屬性。如果回撥成功,此函式將呼叫驅動程式的 ->set_property 回撥並更改屬性的軟體狀態。

返回

成功時為零,失敗時為錯誤程式碼。

bool drm_plane_has_format(struct drm_plane *plane, u32 format, u64 modifier)

檢查平面是否支援此格式和修飾符組合

引數

struct drm_plane *plane

drm 平面

u32 format

畫素格式 (DRM_FORMAT_*)

u64 modifier

資料佈局修飾符

返回

平面是否支援指定的格式和修飾符組合。

bool drm_any_plane_has_format(struct drm_device *dev, u32 format, u64 modifier)

檢查是否有任何平面支援此格式和修飾符組合

引數

struct drm_device *dev

DRM 裝置

u32 format

畫素格式 (DRM_FORMAT_*)

u64 modifier

資料佈局修飾符

返回

是否至少有一個平面支援指定的格式和修飾符組合。

void drm_plane_enable_fb_damage_clips(struct drm_plane *plane)

啟用平面 fb 損壞剪輯屬性。

引數

struct drm_plane *plane

要在其上啟用損壞剪輯屬性的平面。

描述

此函式允許驅動程式在平面上啟用損壞剪輯屬性。

unsigned int drm_plane_get_damage_clips_count(const struct drm_plane_state *state)

返回損壞剪輯計數。

引數

const struct drm_plane_state *state

平面狀態。

描述

一個簡單的輔助函式,用於獲取使用者空間在平面更新期間設定的 drm_mode_rect 裁剪區域的數量。

返回

平面 fb_damage_clips blob 屬性中的裁剪區域數量。

struct drm_mode_rect *drm_plane_get_damage_clips(const struct drm_plane_state *state)

返回損壞的裁剪區域。

引數

const struct drm_plane_state *state

平面狀態。

描述

請注意,此函式返回 uapi 型別 drm_mode_rect。驅動程式可能希望使用輔助函式 drm_atomic_helper_damage_iter_init()drm_atomic_helper_damage_iter_next()drm_atomic_helper_damage_merged(),如果驅動程式最多隻能處理單個損壞區域。

返回

平面 fb_damage_clips blob 屬性中的損壞裁剪區域。

int drm_plane_create_scaling_filter_property(struct drm_plane *plane, unsigned int supported_filters)

建立新的縮放濾鏡屬性

引數

struct drm_plane *plane

drm 平面

unsigned int supported_filters

支援的縮放濾鏡的位掩碼,必須包括 BIT(DRM_SCALING_FILTER_DEFAULT)。

描述

此函式允許驅動程式在給定平面上啟用縮放濾鏡屬性。

返回

成功時返回零,或返回 -errno

int drm_plane_add_size_hints_property(struct drm_plane *plane, const struct drm_plane_size_hint *hints, int num_hints)

建立一個大小提示屬性

引數

struct drm_plane *plane

drm 平面

const struct drm_plane_size_hint *hints

大小提示

int num_hints

大小提示的數量

描述

為平面建立一個大小提示屬性。

返回

成功時返回零,或返回 -errno

平面合成函式參考

int drm_plane_create_alpha_property(struct drm_plane *plane)

建立一個新的 alpha 屬性

引數

struct drm_plane *plane

drm 平面

描述

此函式建立一個通用的、可變的 alpha 屬性,並在 DRM 核心中啟用對其的支援。 它附加到 plane

alpha 屬性將被允許在 0(透明)到 0xffff(不透明)的範圍內。

返回

成功時返回 0,失敗時返回負錯誤程式碼。

int drm_plane_create_rotation_property(struct drm_plane *plane, unsigned int rotation, unsigned int supported_rotations)

建立一個新的旋轉屬性

引數

struct drm_plane *plane

drm 平面

unsigned int rotation

旋轉屬性的初始值

unsigned int supported_rotations

支援的旋轉和反射的位掩碼

描述

這將建立一個新屬性,其中包含對轉換的選定支援。

由於旋轉 180° 與同時沿 x 軸和 y 軸反射相同,因此旋轉屬性有點冗餘。驅動程式可以使用 drm_rotation_simplify() 來標準化此屬性的值。

暴露給使用者空間的屬性是一個位掩碼屬性(請參閱 drm_property_create_bitmask()),名為“rotation”,並具有以下位掩碼列舉值

DRM_MODE_ROTATE_0

“rotate-0”

DRM_MODE_ROTATE_90

“rotate-90”

DRM_MODE_ROTATE_180

“rotate-180”

DRM_MODE_ROTATE_270

“rotate-270”

DRM_MODE_REFLECT_X

“reflect-x”

DRM_MODE_REFLECT_Y

“reflect-y”

旋轉是在逆時針方向上指定的角度量,X 軸和 Y 軸位於源矩形內,即旋轉之前的 X/Y 軸。 反射後,旋轉將應用於從源矩形取樣的影像,然後在縮放該影像以適合目標矩形之前。

unsigned int drm_rotation_simplify(unsigned int rotation, unsigned int supported_rotations)

嘗試簡化旋轉

引數

unsigned int rotation

要簡化的旋轉

unsigned int supported_rotations

支援的旋轉

描述

嘗試將旋轉簡化為支援的形式。例如,如果硬體支援除 DRM_MODE_REFLECT_X 之外的所有內容,則可以像這樣呼叫此函式

drm_rotation_simplify(rotation, DRM_MODE_ROTATE_0 |

DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_180 | DRM_MODE_ROTATE_270 | DRM_MODE_REFLECT_Y);

消除 DRM_MODE_REFLECT_X 標誌。根據硬體支援的轉換型別,此函式可能無法生成支援的轉換,因此呼叫者應在之後檢查結果。

int drm_plane_create_zpos_property(struct drm_plane *plane, unsigned int zpos, unsigned int min, unsigned int max)

建立可變 zpos 屬性

引數

struct drm_plane *plane

drm 平面

unsigned int zpos

zpos 屬性的初始值

unsigned int min

zpos 屬性的最小可能值

unsigned int max

zpos 屬性的最大可能值

描述

此函式初始化通用可變 zpos 屬性,並在 drm 核心中啟用對其的支援。然後,驅動程式可以將此屬性附加到平面,以啟用對混合操作期間可配置平面排列的支援。將可變 zpos 屬性附加到任何平面的驅動程式應在其 drm_mode_config_funcs.atomic_check() 的實現期間呼叫 drm_atomic_normalize_zpos() 輔助函式,這將更新規範化的 zpos 值並將其儲存在 drm_plane_state.normalized_zpos 中。通常,min 應設定為 0,max 設定為給定 crtc 的最大平面數 - 1。

如果某些平面的 zpos 無法更改(如固定背景或游標/最頂層平面),則驅動程式應調整 min/max 值,並將這些平面分配給具有較低或較高值的不可變 zpos 屬性(有關更多資訊,請參閱 drm_plane_create_zpos_immutable_property() 函式)。在這種情況下,驅動程式還應在其 plane_reset() 回撥中為所有平面分配正確的初始 zpos 值,以便平面始終正確排序。

另請參閱 drm_atomic_normalize_zpos()

暴露給使用者空間的屬性稱為“zpos”。

返回

成功時返回零,失敗時返回負 errno。

int drm_plane_create_zpos_immutable_property(struct drm_plane *plane, unsigned int zpos)

建立不可變的 zpos 屬性

引數

struct drm_plane *plane

drm 平面

unsigned int zpos

zpos 屬性的值

描述

此函式初始化通用不可變 zpos 屬性,並在 drm 核心中啟用對其的支援。使用此屬性驅動程式允許使用者空間獲取用於混合操作的平面的排列,並通知使用者空間硬體(或驅動程式)不支援更改平面的順序。對於可變 zpos,請參閱 drm_plane_create_zpos_property()

暴露給使用者空間的屬性稱為“zpos”。

返回

成功時返回零,失敗時返回負 errno。

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

計算所有 crtc 的規範化 zpos 值

引數

struct drm_device *dev

DRM 裝置

struct drm_atomic_state *state

DRM 裝置的原子狀態

描述

此函式計算提供的 DRM 裝置的原子狀態中所有修改後的平面的規範化 zpos 值。

對於每個 CRTC,此函式檢查分配給它的所有平面的新狀態,並計算這些平面的規範化 zpos 值。 平面首先按其 zpos 值進行比較,然後按平面 id 進行比較(如果 zpos 相等)。 具有最低 zpos 值的平面位於底部。 然後,drm_plane_state.normalized_zpos 填充從 0 到 crtc 中活動平面數減 1 的唯一值。

成功時返回零,否則返回 -errno

int drm_plane_create_blend_mode_property(struct drm_plane *plane, unsigned int supported_modes)

建立一個新的混合模式屬性

引數

struct drm_plane *plane

drm 平面

unsigned int supported_modes

支援的模式的位掩碼,必須包括 BIT(DRM_MODE_BLEND_PREMULTI)。 當前的 DRM 假設 alpha 已預乘,如果該屬性預設為其他值,則舊的使用者空間可能會中斷。

描述

這將建立一個描述混合模式的新屬性。

暴露給使用者空間的屬性是一個列舉屬性(請參閱 drm_property_create_enum()),名為“pixel blend mode”,並具有以下列舉值

“None”

忽略畫素 alpha 的混合公式。

“Pre-multiplied”

混合公式假定畫素顏色值已預先乘以 alpha 通道值。

“Coverage”

混合公式假定畫素顏色值尚未預乘,並在將它們混合到背景顏色值時將這樣做。

返回

成功時返回零,或返回 -errno

平面損壞跟蹤函式參考

void drm_atomic_helper_check_plane_damage(struct drm_atomic_state *state, struct drm_plane_state *plane_state)

在 atomic_check 上驗證平面損壞。

引數

struct drm_atomic_state *state

驅動程式狀態物件。

struct drm_plane_state *plane_state

要驗證損壞的平面狀態。

描述

此輔助函式確保為完整模式設定丟棄平面狀態的損壞。如果驅動程式有更多理由希望進行完整的平面更新,而不是處理單個損壞區域,則應在此處處理這些情況。

請注意,平面狀態中的 drm_plane_state.fb_damage_clips == NULL 意味著應該進行完整的平面更新。 它還確保輔助迭代器將返回 drm_plane_state.src 作為損壞。

int drm_atomic_helper_dirtyfb(struct drm_framebuffer *fb, struct drm_file *file_priv, unsigned int flags, unsigned int color, struct drm_clip_rect *clips, unsigned int num_clips)

dirtyfb 的輔助函式。

引數

struct drm_framebuffer *fb

DRM 幀緩衝區。

struct drm_file *file_priv

ioctl 呼叫的 Drm 檔案。

unsigned int flags

髒 fb 註釋標誌。

unsigned int color

用於註釋填充的顏色。

struct drm_clip_rect *clips

髒區域。

unsigned int num_clips

剪輯區域中的剪輯計數。

描述

一個輔助函式,用於在使用平面更新期間的損壞介面實現 drm_framebuffer_funcs.dirty。 如果 num_clips 為 0,則此輔助函式將執行完整的平面更新。 這與 DIRTFB IOCTL 期望的行為相同。

請注意,此輔助函式是阻塞實現。 這是當前驅動程式和使用者空間在其 DIRTYFB IOCTL 實現中所期望的,作為限制使用者空間速率並確保其渲染不會過多地超前於上傳新資料的一種方式。

返回

成功時返回零,失敗時返回負 errno。

void drm_atomic_helper_damage_iter_init(struct drm_atomic_helper_damage_iter *iter, const struct drm_plane_state *old_state, const struct drm_plane_state *state)

初始化損壞迭代器。

引數

struct drm_atomic_helper_damage_iter *iter

要初始化的迭代器。

const struct drm_plane_state *old_state

用於驗證的舊平面狀態。

const struct drm_plane_state *state

從中迭代損壞剪輯的平面狀態。

描述

初始化一個迭代器,該迭代器將平面損壞 drm_plane_state.fb_damage_clips 剪輯到平面 drm_plane_state.src。 如果損壞不存在,因為使用者空間未傳送或驅動程式已丟棄(它想要執行完整的平面更新),則此迭代器將返回完整的平面 src。 目前,如果平面 src 更改,此迭代器將返回完整的平面 src,但將來可以更改為返回損壞。

如果平面不可見或不應發生平面更新,則第一次呼叫 iter_next 將返回 false。 請注意,此幫助程式使用剪裁的 drm_plane_state.src,因此呼叫此幫助程式的驅動程式應已更早地呼叫 drm_atomic_helper_check_plane_state()

bool drm_atomic_helper_damage_iter_next(struct drm_atomic_helper_damage_iter *iter, struct drm_rect *rect)

推進損壞迭代器。

引數

struct drm_atomic_helper_damage_iter *iter

要推進的迭代器。

struct drm_rect *rect

返回剪裁到平面 src 的 fb 座標中的矩形。

描述

由於平面 src 採用 16.16 定點數,而損壞剪輯是整數,因此此迭代器會舍入與平面 src 相交的剪輯。 對於相交的座標,x1/y1 向下舍入,x2/y2 向上舍入。 如果返回為損壞,則對完整平面 src 進行類似的舍入。 此迭代器將跳過平面 src 之外的損壞剪輯。

如果對迭代器 next 的第一次呼叫返回 false,則意味著無需更新平面。

返回

如果輸出有效,則為 True,如果到達末尾,則為 false。

bool drm_atomic_helper_damage_merged(const struct drm_plane_state *old_state, const struct drm_plane_state *state, struct drm_rect *rect)

合併平面損壞

引數

const struct drm_plane_state *old_state

用於驗證的舊平面狀態。

const struct drm_plane_state *state

從中迭代損壞剪輯的平面狀態。

struct drm_rect *rect

返回合併的損壞矩形

描述

此函式將任何有效的平面損壞剪輯合併到一個矩形中,並將其返回到 rect 中。

有關詳細資訊,請參見:drm_atomic_helper_damage_iter_init()drm_atomic_helper_damage_iter_next()

返回

如果存在有效的平面損壞,則為 True,否則為 false。

drm_atomic_for_each_plane_damage

drm_atomic_for_each_plane_damage (iter, rect)

平面損壞的迭代器宏。

引數

iter

要推進的迭代器。

rect

返回剪裁到平面 src 的 fb 座標中的矩形。

描述

請注意,如果對迭代器宏的第一次呼叫返回 false,則無需執行平面更新。 當用戶空間未傳遞損壞時,迭代器將返回完整的平面 src。

struct drm_atomic_helper_damage_iter

損壞迭代器的閉包結構。

定義:

struct drm_atomic_helper_damage_iter {
};

成員

描述

此結構跟蹤遍歷平面損壞剪輯列表所需的狀態。

平面 Panic 功能

要為驅動程式啟用 DRM panic,主平面必須實現 drm_plane_helper_funcs.get_scanout_buffer 輔助函式。 然後會自動註冊到 drm panic 處理程式。 發生 panic 時,將呼叫 drm_plane_helper_funcs.get_scanout_buffer,並且驅動程式可以提供幀緩衝區,以便 panic 處理程式可以在其上繪製 panic 螢幕。 目前僅支援線性緩衝區和一些顏色格式。 (可選)驅動程式還可以提供一個 drm_plane_helper_funcs.panic_flush 回撥,該回調將在之後呼叫,以向硬體傳送其他命令以使掃描輸出緩衝區可見。

平面 Panic 函式參考

struct drm_scanout_buffer

DRM 掃描輸出緩衝區

定義:

struct drm_scanout_buffer {
    const struct drm_format_info *format;
    struct iosys_map map[DRM_FORMAT_MAX_PLANES];
    struct page **pages;
    unsigned int width;
    unsigned int height;
    unsigned int pitch[DRM_FORMAT_MAX_PLANES];
    void (*set_pixel)(struct drm_scanout_buffer *sb, unsigned int x, unsigned int y, u32 color);
};

成員

格式

掃描輸出緩衝區的 drm 格式。

map

掃描輸出緩衝區的虛擬地址,位於記憶體或 iomem 中。 掃描輸出緩衝區應為線性格式,並且可以直接傳送到顯示硬體。 對於 panic 螢幕,撕裂不是問題。

pages

可選,如果未對映掃描輸出緩衝區,則將此欄位設定為掃描輸出緩衝區的頁面陣列。 panic 程式碼將使用 kmap_local_page_try_from_panic() 一次對映一個頁面以寫入所有畫素。 不應從 get_scanoutbuffer() 回撥中分配此陣列。 掃描輸出緩衝區應為線性格式。

width

掃描輸出緩衝區的寬度(以畫素為單位)。

height

掃描輸出緩衝區的高度(以畫素為單位)。

pitch

兩個連續行的開頭之間的長度(以位元組為單位)。

set_pixel

可選函式,用於在幀緩衝區上設定畫素顏色。 它允許處理驅動程式內部的特殊平鋪格式。 它優先於 mappages 欄位。

描述

此結構儲存 drm_panic 繪製 panic 螢幕並顯示它所需的資訊。

drm_panic_trylock

drm_panic_trylock (dev, flags)

嘗試進入 panic 列印關鍵部分

引數

dev

struct drm_device

標誌

你需要傳遞給 unlock() 對應部分的無符號長 irq 標誌

描述

任何 panic 列印程式碼都必須呼叫此函式。 如果 trylock 失敗,則必須中止 panic 列印嘗試。

panic 列印程式碼在持有 panic 鎖時可以做出以下假設

特別感謝 drm_atomic_helper_swap_state() 中平面更新的保護,以下額外保證成立

  • 可以安全地取消引用 drm_plane.state 指標。

  • struct drm_plane_state 或驅動程式子類中的任何在原子檢查程式碼完成後保持不變的內容都可以安全訪問。 特別是,這包括對幀緩衝區和緩衝區物件的引用計數指標。

  • drm_plane_helper_funcs.fb_prepare 設定和由 drm_plane_helper_funcs.fb_cleanup 清理的任何內容都可以安全訪問,只要它在這兩個呼叫之間保持不變。 這也意味著對於使用動態緩衝區管理的驅動程式,幀緩衝區被固定,因此,可以在不採取任何進一步鎖定的情況下訪問所有相關的資料結構(這在 panic 上下文中是不可能的)。

  • 重要的是,由 drm_plane_helper_funcs.begin_fb_accessdrm_plane_helper_funcs.end_fb_access 設定的軟體和硬體狀態無法安全訪問。

驅動程式不得對硬體的實際狀態做出任何假設,除非它們使用 drm_panic_lock()drm_panic_unlock() 顯式保護了這些硬體訪問。

返回

0 表示未能獲取原始自旋鎖,非零表示成功。

drm_panic_lock

drm_panic_lock (dev, flags)

保護 panic 列印相關狀態

引數

dev

struct drm_device

標誌

你需要傳遞給 unlock() 對應部分的無符號長 irq 標誌

描述

必須呼叫此函式來保護 panic 列印程式碼必須能夠依賴的軟體和硬體狀態。 受保護的部分必須儘可能小。 它使用 irqsave/irqrestore 變體,並且可以從 irq 處理程式中呼叫。 示例包括

  • 訪問 peek/poke 或其他類似暫存器,如果這是驅動程式在 panic 時將畫素列印到掃描輸出緩衝區的方式。

  • 更新指標,例如 drm_plane.state,允許 panic 處理程式安全地取消引用這些指標。 這在 drm_atomic_helper_swap_state() 中完成。

  • 驅動程式在 panic 列印期間必須能夠訪問的非不變狀態。

drm_panic_unlock

drm_panic_unlock (dev, flags)

panic 列印關鍵部分的結尾

引數

dev

struct drm_device

標誌

獲取鎖時返回的 irq 標誌

描述

解鎖由 drm_panic_lock()drm_panic_trylock() 獲取的原始自旋鎖。

bool drm_panic_is_enabled(struct drm_device *dev)

引數

struct drm_device *dev

可能支援 drm_panic 的 drm 裝置

描述

如果 drm 裝置支援 drm_panic,則返回 true

顯示模式函式參考

enum drm_mode_status

模式的硬體支援狀態

常量

MODE_OK

模式正常

MODE_HSYNC

hsync 超出範圍

MODE_VSYNC

vsync 超出範圍

MODE_H_ILLEGAL

模式具有非法的水平時序

MODE_V_ILLEGAL

模式具有非法的垂直時序

MODE_BAD_WIDTH

需要不支援的行距

MODE_NOMODE

沒有具有匹配名稱的模式

MODE_NO_INTERLACE

不支援隔行掃描模式

MODE_NO_DBLESCAN

不支援倍頻掃描模式

MODE_NO_VSCAN

不支援多重掃描模式

MODE_MEM

影片記憶體不足

MODE_VIRTUAL_X

模式寬度對於指定的虛擬大小而言太大

MODE_VIRTUAL_Y

模式高度對於指定的虛擬大小而言太大

MODE_MEM_VIRT

給定虛擬大小,影片記憶體不足

MODE_NOCLOCK

沒有可用的固定時鐘

MODE_CLOCK_HIGH

所需的時鐘太高

MODE_CLOCK_LOW

所需的時鐘太低

MODE_CLOCK_RANGE

時鐘/模式不在 ClockRange 中

MODE_BAD_HVALUE

水平時序超出範圍

MODE_BAD_VVALUE

垂直時序超出範圍

MODE_BAD_VSCAN

VScan 值超出範圍

MODE_HSYNC_NARROW

水平同步太窄

MODE_HSYNC_WIDE

水平同步太寬

MODE_HBLANK_NARROW

水平消隱太窄

MODE_HBLANK_WIDE

水平消隱太寬

MODE_VSYNC_NARROW

垂直同步太窄

MODE_VSYNC_WIDE

垂直同步太寬

MODE_VBLANK_NARROW

垂直消隱太窄

MODE_VBLANK_WIDE

垂直消隱太寬

MODE_PANEL

超出面板尺寸

MODE_INTERLACE_WIDTH

寬度對於隔行掃描模式而言太大

MODE_ONE_WIDTH

僅支援一種寬度

MODE_ONE_HEIGHT

僅支援一種高度

MODE_ONE_SIZE

僅支援一種解析度

MODE_NO_REDUCED

監視器不接受減少的消隱

MODE_NO_STEREO

不支援立體模式

MODE_NO_420

不支援 ycbcr 420 模式

MODE_STALE

模式已過時

MODE_BAD

未指定原因

MODE_ERROR

錯誤情況

描述

此列舉用於濾除驅動程式/硬體組合不支援的模式。

DRM_MODE_RES_MM

DRM_MODE_RES_MM (res, dpi)

根據解析度和 DPI 計算顯示尺寸

引數

res

解析度(以畫素為單位)

dpi

每英寸的點數

DRM_MODE_INIT

DRM_MODE_INIT (hz, hd, vd, hd_mm, vd_mm)

初始化顯示模式

引數

hz

垂直重新整理率(以赫茲為單位)

hd

水平解析度,寬度

vd

垂直解析度,高度

hd_mm

顯示寬度(以毫米為單位)

vd_mm

顯示高度(以毫米為單位)

描述

此宏初始化一個 drm_display_mode,該模式包含有關重新整理率、解析度和物理尺寸的資訊。

DRM_SIMPLE_MODE

DRM_SIMPLE_MODE (hd, vd, hd_mm, vd_mm)

簡單顯示模式

引數

hd

水平解析度,寬度

vd

垂直解析度,高度

hd_mm

顯示寬度(以毫米為單位)

vd_mm

顯示高度(以毫米為單位)

描述

此宏初始化一個 drm_display_mode,它只包含解析度和物理尺寸的資訊。

struct drm_display_mode

DRM核心內部顯示模式結構體

定義:

struct drm_display_mode {
    int clock;
    u16 hdisplay;
    u16 hsync_start;
    u16 hsync_end;
    u16 htotal;
    u16 hskew;
    u16 vdisplay;
    u16 vsync_start;
    u16 vsync_end;
    u16 vtotal;
    u16 vscan;
    u32 flags;
    int crtc_clock;
    u16 crtc_hdisplay;
    u16 crtc_hblank_start;
    u16 crtc_hblank_end;
    u16 crtc_hsync_start;
    u16 crtc_hsync_end;
    u16 crtc_htotal;
    u16 crtc_hskew;
    u16 crtc_vdisplay;
    u16 crtc_vblank_start;
    u16 crtc_vblank_end;
    u16 crtc_vsync_start;
    u16 crtc_vsync_end;
    u16 crtc_vtotal;
    u16 width_mm;
    u16 height_mm;
    u8 type;
    bool expose_to_userspace;
    struct list_head head;
    char name[DRM_DISPLAY_MODE_LEN];
    enum drm_mode_status status;
    enum hdmi_picture_aspect picture_aspect_ratio;
};

成員

clock

畫素時鐘,單位為 kHz。

hdisplay

水平顯示尺寸

hsync_start

水平同步起始位置

hsync_end

水平同步結束位置

htotal

水平總尺寸

hskew

水平傾斜?!

vdisplay

垂直顯示尺寸

vsync_start

垂直同步起始位置

vsync_end

垂直同步結束位置

vtotal

垂直總尺寸

vscan

垂直掃描?!

標誌

同步和時序標誌

  • DRM_MODE_FLAG_PHSYNC:水平同步為高電平有效。

  • DRM_MODE_FLAG_NHSYNC:水平同步為低電平有效。

  • DRM_MODE_FLAG_PVSYNC:垂直同步為高電平有效。

  • DRM_MODE_FLAG_NVSYNC:垂直同步為低電平有效。

  • DRM_MODE_FLAG_INTERLACE:模式為隔行掃描。

  • DRM_MODE_FLAG_DBLSCAN:模式使用雙掃描。

  • DRM_MODE_FLAG_CSYNC:模式使用複合同步。

  • DRM_MODE_FLAG_PCSYNC:複合同步為高電平有效。

  • DRM_MODE_FLAG_NCSYNC:複合同步為低電平有效。

  • DRM_MODE_FLAG_HSKEW:提供了 hskew(未使用?)。

  • DRM_MODE_FLAG_BCAST:<已棄用>

  • DRM_MODE_FLAG_PIXMUX:<已棄用>

  • DRM_MODE_FLAG_DBLCLK:雙時鐘模式。

  • DRM_MODE_FLAG_CLKDIV2:半時鐘模式。

此外,還有一些標誌用於指定 3D 模式的打包方式

  • DRM_MODE_FLAG_3D_NONE:正常,非 3D 模式。

  • DRM_MODE_FLAG_3D_FRAME_PACKING:左右眼各 2 個完整幀。

  • DRM_MODE_FLAG_3D_FIELD_ALTERNATIVE:像欄位一樣交錯。

  • DRM_MODE_FLAG_3D_LINE_ALTERNATIVE:交錯的行。

  • DRM_MODE_FLAG_3D_SIDE_BY_SIDE_FULL:並排的完整幀。

  • DRM_MODE_FLAG_3D_L_DEPTH:?

  • DRM_MODE_FLAG_3D_L_DEPTH_GFX_GFX_DEPTH:?

  • DRM_MODE_FLAG_3D_TOP_AND_BOTTOM:幀分為頂部和底部兩部分。

  • DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF:幀分為左右兩部分。

crtc_clock

硬體中的實際畫素或點時鐘。當使用隔行掃描、雙時鐘、立體模式或其他改變實際透過電線傳送的時序和訊號的複雜操作時,這與邏輯 **clock** 不同。

這再次以 kHz 為單位。

請注意,對於像 HDMI 或 DP 這樣的數字輸出,通常在位編碼級別的點時鐘和訊號時鐘之間存在很大的混淆。特別是當使用 8b/10b 編碼時,差異正好是 10 的因子。

crtc_hdisplay

硬體模式水平顯示尺寸

crtc_hblank_start

硬體模式水平消隱起始位置

crtc_hblank_end

硬體模式水平消隱結束位置

crtc_hsync_start

硬體模式水平同步起始位置

crtc_hsync_end

硬體模式水平同步結束位置

crtc_htotal

硬體模式水平總尺寸

crtc_hskew

硬體模式水平傾斜?!

crtc_vdisplay

硬體模式垂直顯示尺寸

crtc_vblank_start

硬體模式垂直消隱起始位置

crtc_vblank_end

硬體模式垂直消隱結束位置

crtc_vsync_start

硬體模式垂直同步起始位置

crtc_vsync_end

硬體模式垂直同步結束位置

crtc_vtotal

硬體模式垂直總尺寸

width_mm

輸出的可定址尺寸,單位為毫米,投影儀應將其設定為 0。

height_mm

輸出的可定址尺寸,單位為毫米,投影儀應將其設定為 0。

type

標誌的位掩碼,主要關於模式的來源。可能的標誌有

  • DRM_MODE_TYPE_PREFERRED:首選模式,通常是 LCD 面板的原始解析度。每個聯結器在任何給定時間都應該只有一個首選模式。

  • DRM_MODE_TYPE_DRIVER:由驅動程式建立的模式,實際上就是所有模式。驅動程式必須為他們建立並暴露給使用者空間的所有模式設定此位。

  • DRM_MODE_TYPE_USERDEF:透過核心命令列定義或選擇的模式。

以及一大堆不應該使用的標誌,但由於這些標誌也在使用者空間 ABI 中使用,所以仍然存在。我們不再接受這些型別的模式

  • DRM_MODE_TYPE_BUILTIN:用於硬編碼模式,未使用。請改用 DRM_MODE_TYPE_DRIVER。

  • DRM_MODE_TYPE_DEFAULT:同樣是遺留物,請改用 DRM_MODE_TYPE_PREFERRED。

  • DRM_MODE_TYPE_CLOCK_C 和 DRM_MODE_TYPE_CRTC_C:定義遺留物,它們僅因歷史原因而存在。沒有人知道它們的用途。不要使用。

expose_to_userspace

指示是否將模式暴露給使用者空間。這是為了在 drm_mode_getconnector ioctl 中準備使用者模式列表時,維護一組暴露的模式。此目的僅在於 ioctl 函式,不應在函式外部使用。

head

用於模式列表的 struct list_head。

名稱

模式的人類可讀名稱,使用 drm_mode_set_name() 填充。

status

模式的狀態,用於過濾掉硬體不支援的模式。參見 enum drm_mode_status

picture_aspect_ratio

用於設定模式的 HDMI 畫面寬高比的欄位。

描述

這是核心 API 顯示模式資訊結構。對於使用者空間版本,請參見 struct drm_mode_modeinfo

水平和垂直時序根據以下圖表定義。

          Active                 Front           Sync           Back
         Region                 Porch                          Porch
<-----------------------><----------------><-------------><-------------->
  //////////////////////|
 ////////////////////// |
//////////////////////  |..................               ................
                                           _______________
<----- [hv]display ----->
<------------- [hv]sync_start ------------>
<--------------------- [hv]sync_end --------------------->
<-------------------------------- [hv]total ----------------------------->*

此結構包含時序的兩個副本。首先是普通的時序,它指定邏輯模式,就像在使用者空間可以透過 vblank 時間戳觀察到的重新整理率下進行逐行 1:1 掃描一樣。然後是硬體時序,它們已經針對隔行掃描、雙時鐘和類似的事情進行了校正。它們作為便利提供,可以使用 drm_mode_set_crtcinfo() 適當地計算它們。

對於列印,你可以使用 DRM_MODE_FMTDRM_MODE_ARG()

DRM_MODE_FMT

DRM_MODE_FMT

用於 struct drm_display_mode 的 printf 字串

DRM_MODE_ARG

DRM_MODE_ARG (m)

用於 struct drm_display_mode 的 printf 引數

引數

m

顯示模式

bool drm_mode_is_stereo(const struct drm_display_mode *mode)

檢查立體模式標誌

引數

const struct drm_display_mode *mode

要檢查的 drm_display_mode

返回

如果模式是立體模式之一(如並排),則為 True,否則為 False。

void drm_mode_debug_printmodeline(const struct drm_display_mode *mode)

將模式列印到 dmesg

引數

const struct drm_display_mode *mode

要列印的模式

描述

使用 DRM_DEBUG 描述 **mode**。

struct drm_display_mode *drm_mode_create(struct drm_device *dev)

建立一個新的顯示模式

引數

struct drm_device *dev

DRM 裝置

描述

使用 kzalloc 建立一個新的、已清除的 drm_display_mode,為其分配一個 ID 並返回它。

返回

成功時指向新模式的指標,出錯時為 NULL。

void drm_mode_destroy(struct drm_device *dev, struct drm_display_mode *mode)

刪除一個模式

引數

struct drm_device *dev

DRM 裝置

struct drm_display_mode *mode

要刪除的模式

描述

釋放 **mode** 的唯一 ID,然後使用 kfree 釋放 **mode** 結構本身。

void drm_mode_probed_add(struct drm_connector *connector, struct drm_display_mode *mode)

將模式新增到聯結器的 probed_mode 列表

引數

struct drm_connector *connector

新模式的聯結器

struct drm_display_mode *mode

模式資料

描述

將 **mode** 新增到 **connector** 的 probed_mode 列表中以供以後使用。然後,此列表應在第二步中進行過濾,並將硬體實際支援的所有模式移動到 **connector** 的模式列表中。

struct drm_display_mode *drm_analog_tv_mode(struct drm_device *dev, enum drm_connector_tv_mode tv_mode, unsigned long pixel_clock_hz, unsigned int hdisplay, unsigned int vdisplay, bool interlace)

為模擬電視建立顯示模式

引數

struct drm_device *dev

drm 裝置

enum drm_connector_tv_mode tv_mode

用於建立模式的電視模式標準。參見 DRM_MODE_TV_MODE_*。

unsigned long pixel_clock_hz

畫素時鐘頻率,單位為赫茲

unsigned int hdisplay

hdisplay 大小

unsigned int vdisplay

vdisplay 大小

bool interlace

是否計算隔行掃描模式

描述

此函式建立一個適合模擬電視輸出的 struct drm_display_mode 例項,用於通常的模擬電視模式之一。如果此值為 DRM_MODE_TV_MODE_MONOCHROME,將建立一個 625 行模式。

請注意,**hdisplay** 大於 PAL 和 NTSC 時序的通常約束,並且我們將選擇忽略大多數時序約束以達到這些解析度。

返回

指向該模式的指標,使用 drm_mode_create() 分配。出錯時返回 NULL。

struct drm_display_mode *drm_cvt_mode(struct drm_device *dev, int hdisplay, int vdisplay, int vrefresh, bool reduced, bool interlaced, bool margins)

建立一個基於 CVT 演算法的模式線

引數

struct drm_device *dev

drm 裝置

int hdisplay

hdisplay 大小

int vdisplay

vdisplay 大小

int vrefresh

vrefresh 速率

bool reduced

是否使用減少的消隱

bool interlaced

是否計算隔行掃描模式

bool margins

是否新增邊距(邊框)

描述

呼叫此函式以根據 hdisplay、vdisplay、vrefresh 基於 CVT 演算法生成模式線。它基於 Graham Loveridge 於 2003 年 4 月 9 日釋出的 VESA(TM) Coordinated Video Timing Generator,可在 http://www.elo.utfsm.cl/~elo212/docs/CVTd6r1.xls 獲取

並且它是從 xserver/hw/xfree86/modes/xf86cvt.c 中的 xf86CVTmode 複製的。我所做的是使用整數計算來翻譯它。

返回

基於 CVT 演算法的模式線儲存在 drm_display_mode 物件中。顯示模式物件使用 drm_mode_create() 分配。當無法分配任何模式時,返回 NULL。

struct drm_display_mode *drm_gtf_mode_complex(struct drm_device *dev, int hdisplay, int vdisplay, int vrefresh, bool interlaced, int margins, int GTF_M, int GTF_2C, int GTF_K, int GTF_2J)

基於完整 GTF 演算法建立模式線

引數

struct drm_device *dev

drm 裝置

int hdisplay

hdisplay 大小

int vdisplay

vdisplay 大小

int vrefresh

vrefresh 速率。

bool interlaced

是否計算隔行掃描模式

int margins

所需的邊距(邊框)大小

int GTF_M

擴充套件的 GTF 公式引數

int GTF_2C

擴充套件的 GTF 公式引數

int GTF_K

擴充套件的 GTF 公式引數

int GTF_2J

擴充套件的 GTF 公式引數

描述

GTF 特徵塊以 0.5 的倍數指定 C 和 J,因此我們將它們乘以 2 後傳遞到此處。對於 C 為 40,傳入 80。

返回

基於完整 GTF 演算法的模式線儲存在 drm_display_mode 物件中。顯示模式物件使用 drm_mode_create() 分配。當無法分配任何模式時,返回 NULL。

struct drm_display_mode *drm_gtf_mode(struct drm_device *dev, int hdisplay, int vdisplay, int vrefresh, bool interlaced, int margins)

基於 GTF 演算法建立 modeline

引數

struct drm_device *dev

drm 裝置

int hdisplay

hdisplay 大小

int vdisplay

vdisplay 大小

int vrefresh

vrefresh 速率。

bool interlaced

是否計算隔行掃描模式

int margins

所需的邊距(邊框)大小

描述

返回基於 GTF 演算法的 modeline

此函式用於基於 GTF 演算法建立 modeline。通用時序公式源自

Andy Morrish (1/5/97) 的 GTF 電子表格,可在 https://www.vesa.org 獲取

它複製自 xserver/hw/xfree86/modes/xf86gtf.c 檔案。我所做的是使用整數計算對其進行翻譯。我還參考了 drivers/video/fbmon.c 檔案中的 fb_get_mode 函式

標準 GTF 引數

M = 600
C = 40
K = 128
J = 20

返回

基於 GTF 演算法的 modeline 儲存在 drm_display_mode 物件中。顯示模式物件使用 drm_mode_create() 分配。如果無法分配模式,則返回 NULL。

void drm_display_mode_from_videomode(const struct videomode *vm, struct drm_display_mode *dmode)

使用 vm 填充 dmode

引數

const struct videomode *vm

用作源的 videomode 結構

struct drm_display_mode *dmode

用作目標的 drm_display_mode 結構

描述

使用 vm 中指定的顯示模式填充 dmode

void drm_display_mode_to_videomode(const struct drm_display_mode *dmode, struct videomode *vm)

使用 dmode 填充 vm

引數

const struct drm_display_mode *dmode

用作源的 drm_display_mode 結構

struct videomode *vm

用作目標的 videomode 結構

描述

使用 dmode 中指定的顯示模式填充 vm

void drm_bus_flags_from_videomode(const struct videomode *vm, u32 *bus_flags)

從 videomode 提取有關 pixelclk 和 DE 極性的資訊,並將其儲存在單獨的變數中

引數

const struct videomode *vm

要使用的 videomode 結構

u32 *bus_flags

有關 pixelclk、同步和 DE 極性的資訊將儲存在此處

描述

根據 vm 中找到的 DISPLAY_FLAGS,在 bus_flags 中設定 DRM_BUS_FLAG_DE_(LOW|HIGH)、DRM_BUS_FLAG_PIXDATA_DRIVE_(POS|NEG)EDGE 和 DISPLAY_FLAGS_SYNC_(POS|NEG)EDGE

int of_get_drm_display_mode(struct device_node *np, struct drm_display_mode *dmode, u32 *bus_flags, int index)

從裝置樹獲取 drm_display_mode

引數

struct device_node *np

具有時序規範的 device_node

struct drm_display_mode *dmode

將設定為返回值

u32 *bus_flags

有關 pixelclk、同步和 DE 極性的資訊

int index

裝置樹中顯示時序列表的索引

描述

此函式開銷很大,僅當從 DT 讀取一種模式時才應使用。要獲取多種模式,請從 of_get_display_timings 開始,然後使用它。

返回

成功時為 0,未找到 of videomode 節點時為負 errno 程式碼。

int of_get_drm_panel_display_mode(struct device_node *np, struct drm_display_mode *dmode, u32 *bus_flags)

從裝置樹獲取 panel-timing drm_display_mode

引數

struct device_node *np

具有 panel-timing 規範的 device_node

struct drm_display_mode *dmode

將設定為返回值

u32 *bus_flags

有關 pixelclk、同步和 DE 極性的資訊

描述

讀取強制裝置樹屬性 width-mm 和 height-mm 並在顯示模式下設定。

返回

成功時為零,失敗時為負錯誤程式碼。

void drm_mode_set_name(struct drm_display_mode *mode)

在模式下設定名稱

引數

struct drm_display_mode *mode

名稱將在此模式下設定

描述

mode 的名稱設定為標準格式,即 <hdisplay>x<vdisplay>,對於隔行掃描模式,可以選擇新增 ‘i’ 字尾。

int drm_mode_vrefresh(const struct drm_display_mode *mode)

獲取模式的 vrefresh

引數

const struct drm_display_mode *mode

mode

返回

modes 的 vrefresh 率,單位為 Hz,四捨五入到最接近的整數。

void drm_mode_get_hv_timing(const struct drm_display_mode *mode, int *hdisplay, int *vdisplay)

獲取給定模式的 hdisplay/vdisplay

引數

const struct drm_display_mode *mode

要查詢的模式

int *hdisplay

要填充的 hdisplay 值

int *vdisplay

要填充的 vdisplay 值

描述

如果指定的模式是適當佈局的立體模式,則 vdisplay 值將加倍。

void drm_mode_set_crtcinfo(struct drm_display_mode *p, int adjust_flags)

設定 CRTC 模式設定時序引數

引數

struct drm_display_mode *p

mode

int adjust_flags

調整標誌的組合

描述

p 設定 CRTC 模式設定時序引數,必要時進行調整。

  • CRTC_INTERLACE_HALVE_V 標誌可用於將隔行掃描模式的垂直時序減半。

  • CRTC_STEREO_DOUBLE 標誌可用於計算包含兩個眼睛的緩衝區的時序(僅在需要時調整時序,例如,對於“幀封裝”或“並排完整”)。

  • CRTC_NO_DBLSCAN 和 CRTC_NO_VSCAN 標誌分別請求不對雙掃描和 vscan > 1 模式執行調整。

void drm_mode_copy(struct drm_display_mode *dst, const struct drm_display_mode *src)

複製模式

引數

struct drm_display_mode *dst

要覆蓋的模式

const struct drm_display_mode *src

要複製的模式

描述

將現有模式複製到另一個模式,保留目標模式的列表頭。

void drm_mode_init(struct drm_display_mode *dst, const struct drm_display_mode *src)

從另一個模式初始化模式

引數

struct drm_display_mode *dst

要覆蓋的模式

const struct drm_display_mode *src

要複製的模式

描述

將現有模式複製到另一個模式,將目標模式的列表頭清零。通常用於保證列表頭不會在堆疊模式下留下堆疊垃圾。

struct drm_display_mode *drm_mode_duplicate(struct drm_device *dev, const struct drm_display_mode *mode)

分配並複製現有模式

引數

struct drm_device *dev

用於分配重複模式的 drm_device

const struct drm_display_mode *mode

要複製的模式

描述

只需分配一個新模式,將現有模式複製到其中,然後返回指向它的指標。用於建立已建立模式的新例項。

返回

成功時指向重複模式的指標,出錯時為 NULL。

bool drm_mode_match(const struct drm_display_mode *mode1, const struct drm_display_mode *mode2, unsigned int match_flags)

測試模式是否(部分)相等

引數

const struct drm_display_mode *mode1

第一種模式

const struct drm_display_mode *mode2

第二種模式

unsigned int match_flags

哪些部分需要匹配 (DRM_MODE_MATCH_*)

描述

檢查 mode1mode2 是否等效。

返回

如果模式(部分)相等,則為 True,否則為 False。

bool drm_mode_equal(const struct drm_display_mode *mode1, const struct drm_display_mode *mode2)

測試模式是否相等

引數

const struct drm_display_mode *mode1

第一種模式

const struct drm_display_mode *mode2

第二種模式

描述

檢查 mode1mode2 是否等效。

返回

如果模式相等,則為 True,否則為 False。

bool drm_mode_equal_no_clocks(const struct drm_display_mode *mode1, const struct drm_display_mode *mode2)

測試模式是否相等

引數

const struct drm_display_mode *mode1

第一種模式

const struct drm_display_mode *mode2

第二種模式

描述

檢查 mode1mode2 是否等效,但不檢查畫素時鐘。

返回

如果模式相等,則為 True,否則為 False。

bool drm_mode_equal_no_clocks_no_stereo(const struct drm_display_mode *mode1, const struct drm_display_mode *mode2)

測試模式是否相等

引數

const struct drm_display_mode *mode1

第一種模式

const struct drm_display_mode *mode2

第二種模式

描述

檢查 mode1mode2 是否等效,但不檢查畫素時鐘和立體佈局。

返回

如果模式相等,則為 True,否則為 False。

enum drm_mode_status drm_mode_validate_driver(struct drm_device *dev, const struct drm_display_mode *mode)

確保模式在某種程度上是合理的

引數

struct drm_device *dev

drm 裝置

const struct drm_display_mode *mode

要檢查的模式

描述

首先對模式進行基本驗證,然後允許驅動程式透過可選的 drm_mode_config_helper_funcs.mode_valid 鉤子檢查裝置/驅動程式特定的限制。

返回

模式狀態

enum drm_mode_status drm_mode_validate_size(const struct drm_display_mode *mode, int maxX, int maxY)

確保模式符合尺寸約束

引數

const struct drm_display_mode *mode

要檢查的模式

int maxX

最大寬度

int maxY

最大高度

描述

此函式是一個輔助函式,可用於根據 DRM 裝置/聯結器的尺寸限制驗證模式。如果模式太大,則其狀態成員將使用相應的驗證失敗程式碼進行更新。列表本身不會更改。

返回

模式狀態

enum drm_mode_status drm_mode_validate_ycbcr420(const struct drm_display_mode *mode, struct drm_connector *connector)

僅在允許時新增“ycbcr420-only”模式

引數

const struct drm_display_mode *mode

要檢查的模式

struct drm_connector *connector

正在操作的 DRM 聯結器

描述

此函式是一個輔助函式,可用於過濾掉任何僅 YCBCR420 模式,當源不支援它時。

返回

模式狀態

void drm_mode_prune_invalid(struct drm_device *dev, struct list_head *mode_list, bool verbose)

從模式列表中刪除無效模式

引數

struct drm_device *dev

DRM 裝置

struct list_head *mode_list

要檢查的模式列表

bool verbose

詳細說明

描述

此輔助函式可用於在驗證完成後修剪顯示模式列表。狀態不是 MODE_OK 的所有模式都將從列表中刪除,如果 verbose,狀態程式碼和模式名稱也會列印到 dmesg。

void drm_mode_sort(struct list_head *mode_list)

對模式列表進行排序

引數

struct list_head *mode_list

要排序的 drm_display_mode 結構的列表

描述

按有利性對 mode_list 進行排序,將良好的模式移動到列表的頭部。

void drm_connector_list_update(struct drm_connector *connector)

更新聯結器的模式列表

引數

struct drm_connector *connector

要更新的聯結器

描述

這將模式從 connector probed_modes 列表移動到實際模式列表。它將探測到的模式與當前列表進行比較,並且僅新增不同的/新的模式。

這只是一個輔助函式,本身不驗證任何模式,也不修剪任何無效模式。呼叫者需要自己完成。

bool drm_mode_parse_command_line_for_connector(const char *mode_option, const struct drm_connector *connector, struct drm_cmdline_mode *mode)

解析聯結器的命令列 modeline

引數

const char *mode_option

可選的每個聯結器的模式選項

const struct drm_connector *connector

要解析 modeline 的聯結器

struct drm_cmdline_mode *mode

要填充的預分配的 drm_cmdline_mode 結構

描述

這將解析 mode_option 命令列 modeline,用於配置聯結器的模式和選項。

這使用與 fb modedb.c 相同的引數,除了末尾的一個額外的強制啟用、強制啟用數字和強制停用位

<xres>x<yres>[M][R][-<bpp>][@<refresh>][i][m][eDd]

可以使用逗號分隔每個選項,在模式之後提供其他選項。有效的選項可以在 modedb 預設影片模式支援 中找到。

需要中間 drm_cmdline_mode 結構來儲存來自命令列 modline 的其他選項,例如 force-enable/disable 標誌。

返回

如果已解析有效的 modeline,則為 True,否則為 False。

struct drm_display_mode *drm_mode_create_from_cmdline_mode(struct drm_device *dev, struct drm_cmdline_mode *cmd)

將命令列 modeline 轉換為 DRM 顯示模式

引數

struct drm_device *dev

用於建立新模式的 DRM 裝置

struct drm_cmdline_mode *cmd

輸入命令列 modeline

返回

成功時指向轉換後的模式的指標,出錯時為 NULL。

bool drm_mode_is_420_only(const struct drm_display_info *display, const struct drm_display_mode *mode)

如果給定的影片模式只能在 YCBCR420 輸出格式中支援

引數

const struct drm_display_info *display

正在操作的顯示器

const struct drm_display_mode *mode

要測試的影片模式。

返回

如果該模式可以在 YCBCR420 格式中支援,則為 true,否則為 false。

bool drm_mode_is_420_also(const struct drm_display_info *display, const struct drm_display_mode *mode)

如果給定的影片模式也可以在 YCBCR420 輸出格式中支援(以及 RGB/YCBCR444/422)

引數

const struct drm_display_info *display

正在操作的顯示器。

const struct drm_display_mode *mode

要測試的影片模式。

返回

如果該模式可以支援 YCBCR420 格式,則為 true,否則為 false。

bool drm_mode_is_420(const struct drm_display_info *display, const struct drm_display_mode *mode)

如果給定的影片模式可以在 YCBCR420 輸出格式中支援

引數

const struct drm_display_info *display

正在操作的顯示器。

const struct drm_display_mode *mode

要測試的影片模式。

返回

如果該模式可以在 YCBCR420 格式中支援,則為 true,否則為 false。

void drm_set_preferred_mode(struct drm_connector *connector, int hpref, int vpref)

設定聯結器的首選模式

引數

struct drm_connector *connector

應處理其模式列表的聯結器

int hpref

首選模式的水平解析度

int vpref

首選模式的垂直解析度

描述

如果模式與 hprefvpref 指定的解析度匹配,則將其標記為首選。

聯結器抽象

在 DRM 中,聯結器是顯示接收器的通用抽象,並且還包括固定面板或任何其他可以以某種形式顯示畫素的東西。與代表硬體的所有其他 KMS 物件(如 CRTC、編碼器或平面抽象)不同,聯結器可以在執行時熱插拔和拔出。因此,它們使用 drm_connector_get()drm_connector_put() 進行引用計數。

KMS 驅動程式必須為每個此類接收器建立一個 struct drm_connector、初始化、註冊和附加。該例項與其他 KMS 物件一樣建立,並透過設定以下欄位進行初始化。透過呼叫 drm_connector_init(),使用指向 struct drm_connector_funcs 和聯結器型別的指標來初始化聯結器,然後透過呼叫 drm_connector_register() 將其公開給使用者空間。

必須將聯結器附加到編碼器才能使用。對於將聯結器對映到編碼器的裝置,聯結器應在初始化時透過呼叫 drm_connector_attach_encoder() 來附加。驅動程式還必須將 drm_connector.encoder 欄位設定為指向附加的編碼器。

對於非固定聯結器(如內建面板),驅動程式需要支援熱插拔通知。最簡單的方法是使用探測幫助程式,有關沒有硬體支援熱插拔中斷的聯結器,請參閱 drm_kms_helper_poll_init()。具有硬體熱插拔支援的聯結器可以改為使用例如 drm_helper_hpd_irq_event()

聯結器函式參考

enum drm_connector_status

drm_connector 的狀態

常量

connector_status_connected

聯結器肯定已連線到接收器裝置,並且可以啟用。

connector_status_disconnected

聯結器未連線到可以自動檢測的接收器裝置。對於數字輸出(如 DP 或 HDMI)(可以可靠地進行探測),這意味著實際上沒有任何東西。是否可以點亮具有此狀態的聯結器取決於驅動程式。

connector_status_unknown

無法可靠地檢測到聯結器的狀態。當探測會導致閃爍(如使用聯結器時的負載檢測)或硬體資源不可用(如負載檢測需要空閒 CRTC 時)時,會發生這種情況。應該可以使用列出的回退模式之一來點亮聯結器。對於預設配置,使用者空間應僅在沒有具有 connector_status_connected 的聯結器時才嘗試點亮具有未知狀態的聯結器。

描述

此列舉用於跟蹤聯結器狀態。沒有單獨的 #defines 用於 uapi!

enum drm_connector_registration_state

drm_connector 的使用者空間註冊狀態

常量

DRM_CONNECTOR_INITIALIZING

聯結器剛剛建立,但尚未公開給使用者空間。如何修改此聯結器的狀態應該沒有其他限制。

DRM_CONNECTOR_REGISTERED

聯結器已完全初始化並在 sysfs 中註冊,因此它已公開給使用者空間。如何修改此聯結器的狀態應該沒有其他限制。

DRM_CONNECTOR_UNREGISTERED

聯結器已公開給使用者空間,此後已從使用者空間取消註冊和刪除,或者聯結器在有機會公開給使用者空間之前已取消註冊(例如,仍在 DRM_CONNECTOR_INITIALIZING 狀態)。取消註冊聯結器後,如何修改其狀態存在其他限制

  • 取消註冊的聯結器只能將其 DPMS 從 On->Off 更改。一旦 DPMS 更改為 Off,就不能將其切換回 On。

  • 除非它們會導致停用其分配的 CRTC,否則不允許在未註冊的聯結器上進行 Modeset。這意味著停用未註冊的聯結器上的 CRTC 是可以的,但啟用一個 CRTC 是不可以的。

  • 從未註冊的聯結器中刪除 CRTC 是可以的,但新的 CRTC 永遠不能分配給未註冊的聯結器。

描述

此列舉用於跟蹤初始化聯結器並將其註冊到使用者空間的狀態,以便 DRM 可以防止在不再存在的聯結器上進行虛假模式設定。

enum drm_connector_tv_mode

模擬電視輸出模式

常量

DRM_MODE_TV_MODE_NTSC

CCIR 系統 M(也稱為 525 行)以及 NTSC 顏色編碼。

DRM_MODE_TV_MODE_NTSC_443

DRM_MODE_TV_MODE_NTSC 的變體。使用 4.43 MHz 的顏色副載波頻率。

DRM_MODE_TV_MODE_NTSC_J

DRM_MODE_TV_MODE_NTSC 的變體,用於日本。使用等於消隱級別的黑電平。

DRM_MODE_TV_MODE_PAL

CCIR 系統 B 以及 PAL 顏色系統。

DRM_MODE_TV_MODE_PAL_M

CCIR 系統 M(也稱為 525 行)以及 PAL 顏色編碼

DRM_MODE_TV_MODE_PAL_N

CCIR 系統 N 以及 PAL 顏色編碼。它使用 625 行,但具有 3.58MHz 的顏色副載波頻率、SECAM 顏色空間以及比大多數其他 PAL 變體更窄的通道。

DRM_MODE_TV_MODE_SECAM

CCIR 系統 B 以及 SECAM 顏色系統。

DRM_MODE_TV_MODE_MONOCHROME

使用適合 DRM 模式的計時,包括用於 525 行或 625 行模式的均衡脈衝,沒有基座或顏色編碼。

DRM_MODE_TV_MODE_MAX

模擬電視輸出模式的數量。

內部實施細節;這不是 uABI。

描述

此列舉用於指示模擬電視聯結器上使用的電視輸出模式。

警告:此列舉的值是 uABI,因為它們在“TV 模式”聯結器屬性中公開。

struct drm_scrambling

接收器的加擾支援。

定義:

struct drm_scrambling {
    bool supported;
    bool low_rates;
};

成員

已支援

支援速率 > 340 Mhz 的加擾。

low_rates

支援速率 <= 340 Mhz 的加擾。

struct drm_hdmi_dsc_cap

HDMI 接收器的 DSC 功能

定義:

struct drm_hdmi_dsc_cap {
    bool v_1p2;
    bool native_420;
    bool all_bpp;
    u8 bpc_supported;
    u8 max_slices;
    int clk_per_slice;
    u8 max_lanes;
    u8 max_frl_rate_per_lane;
    u8 total_chunk_kbytes;
};

成員

v_1p2

接收器支援 dsc1.2 版本的標誌

native_420

接收器是否支援使用 4:2:0 壓縮的 DSC

all_bpp

接收器是否支援所有 bpp 以及 4:4:4: 或 4:2:2 壓縮格式

bpc_supported

接收器支援的壓縮 bpc:10、12 或 16 bpc

max_slices

支援的最大水平切片數

clk_per_slice

每個切片支援的最大畫素時鐘(MHz)

max_lanes

固定速率鏈路訓練的 DSC 最大支援通道數

max_frl_rate_per_lane

每個通道使用 DSC 的最大 frl 速率

total_chunk_kbytes

每行支援的最大資料塊大小(KB)

描述

描述 HDMI 2.1 接收器提供的 DSC 支援。 此資訊從為 HDMI 2.1 定義的附加 HFVSDB 塊中獲取。

struct drm_hdmi_info

有關已連線 HDMI 接收器的執行時資訊

定義:

struct drm_hdmi_info {
    struct drm_scdc scdc;
    unsigned long y420_vdb_modes[BITS_TO_LONGS(256)];
    unsigned long y420_cmdb_modes[BITS_TO_LONGS(256)];
    u8 y420_dc_modes;
    u8 max_frl_rate_per_lane;
    u8 max_lanes;
    struct drm_hdmi_dsc_cap dsc_cap;
};

成員

scdc

接收器的 scdc 支援和功能

y420_vdb_modes

僅支援 ycbcr420 輸出的模式的點陣圖(不是普通的 RGB/YCBCR444/422 輸出)。CEA-861-G 規範定義的最大 VIC 為 219,因此大小為 256 位,最多可對映 256 個 VIC。

y420_cmdb_modes

可以同時支援 ycbcr420 輸出和普通 HDMI 輸出的模式的點陣圖。CEA-861-G 規範定義的最大 VIC 為 219,因此大小為 256 位,最多可對映 256 個 VIC。

y420_dc_modes

深度顏色支援索引的點陣圖

max_frl_rate_per_lane

支援固定速率鏈路

max_lanes

接收器支援

dsc_cap

接收器的 DSC 功能

描述

描述給定的顯示器是否支援高階 HDMI 2.0 功能。 此資訊可在 CEA-861-F 擴充套件塊(如 HF-VSDB)中找到。

聯結器的 link_status 屬性值

常量

DRM_LINK_STATUS_GOOD

由於成功的鏈路訓練,DP 鏈路良好

DRM_LINK_STATUS_BAD

由於鏈路訓練失敗,DP 鏈路不良

描述

此列舉用作聯結器的鏈路狀態屬性值。 它設定為 uapi 中定義的值。

enum drm_panel_orientation

drm_display_info的 panel_orientation 資訊

常量

DRM_MODE_PANEL_ORIENTATION_UNKNOWN

drm 驅動程式未提供任何面板方向資訊(非面板的正常情況),在這種情況下,不會附加“面板方向”聯結器屬性。

DRM_MODE_PANEL_ORIENTATION_NORMAL

面板的頂部與裝置外殼的頂部匹配。

DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP

面板的頂部與裝置外殼的底部匹配,即面板倒置安裝。

DRM_MODE_PANEL_ORIENTATION_LEFT_UP

面板的左側與裝置外殼的頂部匹配。

DRM_MODE_PANEL_ORIENTATION_RIGHT_UP

面板的右側與裝置外殼的頂部匹配。

描述

此列舉用於跟蹤 (LCD) 面板的方向。 uapi 沒有單獨的 #defines!

enum drm_hdmi_broadcast_rgb

HDMI **drm_connector** 的廣播 RGB 選擇

常量

DRM_HDMI_BROADCAST_RGB_AUTO

RGB 範圍根據模式自動選擇。

DRM_HDMI_BROADCAST_RGB_FULL

強制使用全範圍 RGB。

DRM_HDMI_BROADCAST_RGB_LIMITED

強制使用有限範圍 RGB。

struct drm_monitor_range_info

drm_display_info的 EDID 中面板的監視器範圍

定義:

struct drm_monitor_range_info {
    u16 min_vfreq;
    u16 max_vfreq;
};

成員

min_vfreq

這是來自 EDID 詳細監視器範圍的最小支援重新整理率(以 Hz 為單位)。

max_vfreq

這是來自 EDID 詳細監視器範圍的最大支援重新整理率(以 Hz 為單位)

描述

此結構用於儲存面板支援的頻率範圍,該範圍從 EDID 的詳細監視器範圍描述符塊中解析。

struct drm_luminance_range_info

drm_display_info的面板亮度範圍。 使用 EDID 中的資料計算得出

定義:

struct drm_luminance_range_info {
    u32 min_luminance;
    u32 max_luminance;
};

成員

min_luminance

這是最小支援的亮度值

max_luminance

這是最大支援的亮度值

描述

此結構用於儲存面板支援的亮度範圍,該範圍使用來自 EDID 靜態 hdr 元資料的資料計算得出。

enum drm_privacy_screen_status

隱私螢幕狀態

常量

PRIVACY_SCREEN_DISABLED

面板上的隱私螢幕已停用

PRIVACY_SCREEN_ENABLED

面板上的隱私螢幕已啟用

PRIVACY_SCREEN_DISABLED_LOCKED

面板上的隱私螢幕已停用並鎖定(無法更改)

PRIVACY_SCREEN_ENABLED_LOCKED

面板上的隱私螢幕已啟用並鎖定(無法更改)

描述

此列舉用於透過“隱私螢幕 sw-state”和“隱私螢幕 hw-state”屬性跟蹤和控制某些顯示面板上存在的整合隱私螢幕的狀態。 請注意,_LOCKED 列舉值僅對“隱私螢幕 hw-state”屬性有效。

enum drm_colorspace

色彩空間

常量

DRM_MODE_COLORIMETRY_DEFAULT

驅動程式特定行為。

DRM_MODE_COLORIMETRY_NO_DATA

驅動程式特定行為。

DRM_MODE_COLORIMETRY_SMPTE_170M_YCC

(HDMI) SMPTE ST 170M 色彩格式

DRM_MODE_COLORIMETRY_BT709_YCC

(HDMI, DP) ITU-R BT.709 色彩格式

DRM_MODE_COLORIMETRY_XVYCC_601

(HDMI, DP) xvYCC601 色彩格式

DRM_MODE_COLORIMETRY_XVYCC_709

(HDMI, DP) xvYCC709 色彩格式

DRM_MODE_COLORIMETRY_SYCC_601

(HDMI, DP) sYCC601 色彩格式

DRM_MODE_COLORIMETRY_OPYCC_601

(HDMI, DP) opYCC601 色彩格式

DRM_MODE_COLORIMETRY_OPRGB

(HDMI, DP) opRGB 色彩格式

DRM_MODE_COLORIMETRY_BT2020_CYCC

(HDMI, DP) ITU-R BT.2020 Y’c C’bc C’rc(恆定亮度)色彩格式

DRM_MODE_COLORIMETRY_BT2020_RGB

(HDMI, DP) ITU-R BT.2020 R’ G’ B’ 色彩格式

DRM_MODE_COLORIMETRY_BT2020_YCC

(HDMI, DP) ITU-R BT.2020 Y’ C’b C’r 色彩格式

DRM_MODE_COLORIMETRY_DCI_P3_RGB_D65

(HDMI) SMPTE ST 2113 P3D65 色彩格式

DRM_MODE_COLORIMETRY_DCI_P3_RGB_THEATER

(HDMI) SMPTE ST 2113 P3DCI 色彩格式

DRM_MODE_COLORIMETRY_RGB_WIDE_FIXED

(DP) RGB 寬色域定點色彩格式

DRM_MODE_COLORIMETRY_RGB_WIDE_FLOAT

(DP) RGB 寬色域浮點 (scRGB (IEC 61966-2-2)) 色彩格式

DRM_MODE_COLORIMETRY_BT601_YCC

(DP) ITU-R BT.601 色彩格式。DP 規範未說明這是 525 行版本還是 625 行版本。

DRM_MODE_COLORIMETRY_COUNT

不是有效值;僅用於計數

描述

此列舉是 HDMI 和 DP 協議標準支援的合併色彩列表。 相應的聯結器將註冊一個屬性,其中包含此列表的子集(由該相應協議支援)。 使用者空間將透過色彩空間屬性設定色彩空間,該屬性將被建立並公開給使用者空間。

DP 定義來自 DP v2.0 規範 HDMI 定義來自 CTA-861-H 規範

enum drm_bus_flags

drm_display_info的 bus_flags 資訊

常量

DRM_BUS_FLAG_DE_LOW

資料啟用訊號為低電平有效

DRM_BUS_FLAG_DE_HIGH

資料啟用訊號為高電平有效

DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE

資料在畫素時鐘的上升沿驅動

DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE

資料在畫素時鐘的下降沿驅動

DRM_BUS_FLAG_PIXDATA_SAMPLE_POSEDGE

資料在畫素時鐘的上升沿取樣

DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE

資料在畫素時鐘的下降沿取樣

DRM_BUS_FLAG_DATA_MSB_TO_LSB

資料在總線上從 MSB 傳輸到 LSB

DRM_BUS_FLAG_DATA_LSB_TO_MSB

資料在總線上從 LSB 傳輸到 MSB

DRM_BUS_FLAG_SYNC_DRIVE_POSEDGE

同步訊號在畫素時鐘的上升沿驅動

DRM_BUS_FLAG_SYNC_DRIVE_NEGEDGE

同步訊號在畫素時鐘的下降沿驅動

DRM_BUS_FLAG_SYNC_SAMPLE_POSEDGE

同步訊號在畫素時鐘的上升沿取樣

DRM_BUS_FLAG_SYNC_SAMPLE_NEGEDGE

同步訊號在畫素時鐘的下降沿取樣

DRM_BUS_FLAG_SHARP_SIGNALS

如果必須使用 Sharp 特有的訊號(SPL、CLS、PS、REV),則設定

描述

此列舉定義了總線上訊號的訊號極性和時鐘沿資訊,作為位掩碼標誌。

時鐘沿資訊由兩組符號傳達,DRM_BUS_FLAGS_*_DRIVE_* 和 DRM_BUS_FLAGS_*_SAMPLE_*。 當此列舉用於從發射器的角度描述匯流排時,應使用 *_DRIVE_* 標誌。 當從接收器的角度使用時,應使用 *_SAMPLE_* 標誌。 *_DRIVE_* 和 *_SAMPLE_* 標誌相互別名,其中 *_SAMPLE_POSEDGE 和 *_SAMPLE_NEGEDGE 標誌分別等於 *_DRIVE_NEGEDGE 和 *_DRIVE_POSEDGE。 這簡化了程式碼,因為訊號通常在驅動沿的相反邊沿取樣。 但是,發射器和接收器可能需要考慮其他訊號時序才能在驅動和取樣沿之間進行轉換。

struct drm_display_info

有關已連線接收器的執行時資料

定義:

struct drm_display_info {
    unsigned int width_mm;
    unsigned int height_mm;
    unsigned int bpc;
    enum subpixel_order subpixel_order;
#define DRM_COLOR_FORMAT_RGB444         (1<<0);
#define DRM_COLOR_FORMAT_YCBCR444       (1<<1);
#define DRM_COLOR_FORMAT_YCBCR422       (1<<2);
#define DRM_COLOR_FORMAT_YCBCR420       (1<<3);
    int panel_orientation;
    u32 color_formats;
    const u32 *bus_formats;
    unsigned int num_bus_formats;
    u32 bus_flags;
    int max_tmds_clock;
    bool dvi_dual;
    bool is_hdmi;
    bool has_audio;
    bool has_hdmi_infoframe;
    bool rgb_quant_range_selectable;
    u8 edid_hdmi_rgb444_dc_modes;
    u8 edid_hdmi_ycbcr444_dc_modes;
    u8 cea_rev;
    struct drm_hdmi_info hdmi;
    bool non_desktop;
    struct drm_monitor_range_info monitor_range;
    struct drm_luminance_range_info luminance_range;
    u8 mso_stream_count;
    u8 mso_pixel_overlap;
    u32 max_dsc_bpp;
    u8 *vics;
    int vics_len;
    u32 quirks;
    u16 source_physical_address;
};

成員

width_mm

以毫米為單位的物理寬度。

height_mm

以毫米為單位的物理高度。

bpc

每個顏色通道的最大位數。 由 HDMI 和 DP 輸出使用。

subpixel_order

LCD 面板的子畫素順序。

panel_orientation

內建面板的只讀聯結器屬性,指示面板相對於裝置外殼的方向。 drm_connector_init() 將其設定為 DRM_MODE_PANEL_ORIENTATION_UNKNOWN。 當不是 UNKNOWN 時,drm_fb_helpers 會使用它來旋轉 fb 以進行補償,並作為 prop 匯出到使用者空間。

color_formats

HDMI 顏色格式,在 RGB 和 YCrCb 模式之間進行選擇。 使用 DRM_COLOR_FORMAT_ 定義,這些定義與用於描述幀緩衝區中畫素格式的定義不同,並且與 **bus_formats** 中的格式也不匹配,後者與 v4l 共享。

bus_formats

線上的畫素資料格式,在某種程度上與 **color_formats** 冗餘。 使用與 v4l 和媒體驅動程式共享的 MEDIA_BUS_FMT_ 定義編碼的 **num_bus_formats** 大小的陣列。

num_bus_formats

**bus_formats** 陣列的大小。

bus_flags

總線上畫素資料的附加資訊(如畫素訊號極性),使用 enum drm_bus_flags 值 DRM_BUS_FLAGS_。

max_tmds_clock

接收器支援的最大 TMDS 時鐘速率(以 kHz 為單位)。 0 表示未定義。

dvi_dual

雙鏈路 DVI 接收器?

is_hdmi

如果接收器是 HDMI 裝置,則為 True。

此欄位應在可能的情況下代替呼叫 drm_detect_hdmi_monitor()

has_audio

如果接收器支援音訊,則為 True。

此欄位應在可能的情況下代替呼叫 drm_detect_monitor_audio()

has_hdmi_infoframe

接收器是否支援 HDMI 資訊幀?

rgb_quant_range_selectable

接收器是否支援選擇 RGB 量化範圍?

edid_hdmi_rgb444_dc_modes

RGB 4:4:4 中支援的 hdmi 深度顏色模式的掩碼。 更多與 **bus_formats** 冗餘的內容。

edid_hdmi_ycbcr444_dc_modes

YCbCr 4:4:4 中支援的 hdmi 深度顏色模式的掩碼。 更多與 **bus_formats** 冗餘的內容。

cea_rev

HDMI 接收器的 CEA 修訂版本。

hdmi

HDMI 接收器的高階功能。

non_desktop

非桌面顯示器 (HMD)。

monitor_range

監視器範圍描述符支援的頻率範圍

luminance_range

面板支援的亮度範圍

mso_stream_count

來自 DisplayID VESA 供應商塊的 eDP 多 SST 操作 (MSO) 流計數。 常規單流傳輸 (SST) 為 0,或為 2 或 4 個 MSO 流。

mso_pixel_overlap

eDP MSO 段畫素重疊,0-8 畫素。

max_dsc_bpp

最大 DSC 目標位元率,如果設定為 0,則改為使用監視器的預設值。

vics

vics_len VIC 的陣列。 EDID 解析的內部變數。

vics_len

vics 中的元素數。 EDID 解析的內部變數。

quirks

基於 EDID 的怪癖。 EDID 解析的內部變數。

source_physical_address

來自 HDMI 供應商特定資料塊的源物理地址,用於 CEC 用途。

預設為 CEC_PHYS_ADDR_INVALID (0xffff)。

描述

描述給定的顯示器(例如 CRT 或平板面板)及其限制。 對於像內建面板這樣的固定顯示器接收器,這與 struct drm_connector 之間沒有太大區別。 但對於帶有真電纜的接收器,此結構旨在描述電纜另一端的所有內容。

對於提供 EDID 的接收器,可以透過呼叫 drm_add_edid_modes() 來填充此結構。

struct drm_connector_tv_margins

TV 聯結器相關邊距

定義:

struct drm_connector_tv_margins {
    unsigned int bottom;
    unsigned int left;
    unsigned int right;
    unsigned int top;
};

成員

bottom

以畫素為單位的底部邊距。

left

以畫素為單位的左側邊距。

right

以畫素為單位的右側邊距。

top

以畫素為單位的頂部邊距。

描述

描述在 TV 聯結器上的影像周圍放置的邊距(以畫素為單位),以處理過掃描。

struct drm_tv_connector_state

TV 聯結器相關狀態

定義:

struct drm_tv_connector_state {
    enum drm_mode_subconnector select_subconnector;
    enum drm_mode_subconnector subconnector;
    struct drm_connector_tv_margins margins;
    unsigned int legacy_mode;
    unsigned int mode;
    unsigned int brightness;
    unsigned int contrast;
    unsigned int flicker_reduction;
    unsigned int overscan;
    unsigned int saturation;
    unsigned int hue;
};

成員

select_subconnector

選擇的子聯結器

subconnector

檢測到的子聯結器

margins

TV 邊距

legacy_mode

舊版 TV 模式,驅動程式特定的值

mode

TV 模式

brightness

以百分比表示的亮度

contrast

以百分比表示的對比度

flicker_reduction

以百分比表示的閃爍減少

overscan

以百分比表示的過掃描

saturation

以百分比表示的飽和度

hue

以百分比表示的色調

struct drm_connector_hdmi_infoframe

HDMI 資訊幀容器

定義:

struct drm_connector_hdmi_infoframe {
    union hdmi_infoframe data;
    bool set;
};

成員

data

HDMI 資訊幀結構

set

**data** 的內容是否有效?

struct drm_connector_state

可變聯結器狀態

定義:

struct drm_connector_state {
    struct drm_connector *connector;
    struct drm_crtc *crtc;
    struct drm_encoder *best_encoder;
    enum drm_link_status link_status;
    struct drm_atomic_state *state;
    struct drm_crtc_commit *commit;
    struct drm_tv_connector_state tv;
    bool self_refresh_aware;
    enum hdmi_picture_aspect picture_aspect_ratio;
    unsigned int content_type;
    unsigned int hdcp_content_type;
    unsigned int scaling_mode;
    unsigned int content_protection;
    enum drm_colorspace colorspace;
    struct drm_writeback_job *writeback_job;
    u8 max_requested_bpc;
    u8 max_bpc;
    enum drm_privacy_screen_status privacy_screen_sw_state;
    struct drm_property_blob *hdr_output_metadata;
    struct drm_connector_hdmi_state hdmi;
};

成員

connector

指向聯結器的後向指標

crtc

將聯結器連線到的 CRTC,如果停用,則為 NULL。

請勿直接修改此項,請使用 drm_atomic_set_crtc_for_connector() 代替。

best_encoder

由原子 helpers 使用,透過 drm_connector_helper_funcs.atomic_best_encoderdrm_connector_helper_funcs.best_encoder 回撥來選擇編碼器。

這也被原子 helpers 使用,用於將編碼器對映到它們當前和先前的聯結器,參見 drm_atomic_get_old_connector_for_encoder()drm_atomic_get_new_connector_for_encoder()

注意:原子驅動程式必須填充此項(無論是自己填充還是透過 helpers),否則 GETCONNECTOR 和 GETENCODER IOCTL 將不會向用戶空間返回正確的資料。

link_status

聯結器 link_status 用於跟蹤連結是 GOOD 還是 BAD,以便在需要重新訓練時通知使用者空間。

state

指向全域性 drm_atomic_state 的後向指標

提交

跟蹤掛起的提交,以防止使用後釋放的情況。

僅當 crtc 為 NULL 時設定。

tv

TV 聯結器狀態

self_refresh_aware

這跟蹤聯結器是否知道自重新整理狀態。對於那些瞭解自重新整理狀態的聯結器實現,應將其設定為 true。這是必需的,因為 crtc 註冊了自重新整理 helpers,並且它不知道下游的聯結器是否已實現自重新整理進入/退出。

如果驅動程式知道如何處理 self_refresh 請求,則應在 atomic_check 中將其設定為 true。

picture_aspect_ratio

聯結器屬性,用於控制 HDMI 資訊幀寬高比設定。

DRM_MODE_PICTURE_ASPECT_* 值必須與 enum hdmi_picture_aspect 的值匹配

content_type

聯結器屬性,用於控制 HDMI 資訊幀內容型別設定。DRM_MODE_CONTENT_TYPE_* 值必須與相應的值匹配。

hdcp_content_type

聯結器屬性,用於傳遞受保護內容型別。這通常用於 HDCP。

scaling_mode

聯結器屬性,用於控制放大,主要用於內建面板。

content_protection

聯結器屬性,用於請求內容保護。這通常用於 HDCP。

colorspace

聯結器屬性的狀態變數,用於請求在 Sink 上更改顏色空間。這通常用於切換到更寬的色域,如 BT2020。

writeback_job

回寫聯結器的回寫作業

儲存回寫聯結器的幀緩衝區和輸出柵欄。由於回寫完成可能與正常提交週期非同步,因此回寫作業的生命週期由此物件與正常原子狀態分開管理。

另請參見:drm_writeback_queue_job()drm_writeback_signal_completion()

max_requested_bpc

聯結器屬性,用於限制畫素的最大位深度。

max_bpc

基於請求的 max_bpc 屬性和從 edid 獲取的聯結器 bpc 限制的聯結器 max_bpc。

privacy_screen_sw_state

參見 標準聯結器屬性

hdr_output_metadata

HDR 輸出元資料的 DRM blob 屬性

hdmi

與 HDMI 相關的變數和屬性。由 drm_atomic_helper_connector_hdmi_check() 填充。

struct drm_connector_hdmi_funcs

drm_hdmi_connector 控制函式

定義:

struct drm_connector_hdmi_funcs {
    enum drm_mode_status(*tmds_char_rate_valid)(const struct drm_connector *connector,const struct drm_display_mode *mode, unsigned long long tmds_rate);
    int (*clear_infoframe)(struct drm_connector *connector, enum hdmi_infoframe_type type);
    int (*write_infoframe)(struct drm_connector *connector,enum hdmi_infoframe_type type, const u8 *buffer, size_t len);
    const struct drm_edid *(*read_edid)(struct drm_connector *connector);
};

成員

tmds_char_rate_valid

此回撥在 atomic_check 時被呼叫,以確定驅動程式是否支援特定的 TMDS 字元速率。

tmds_char_rate_valid 回撥是可選的。

返回

drm_mode_status.MODE_OKenum drm_mode_status 中的失敗原因之一。

clear_infoframe

此回撥透過 drm_atomic_helper_connector_hdmi_update_infoframes 在提交期間呼叫,以將資訊幀清除到硬體中。它將被多次呼叫,對於每個停用的資訊幀型別呼叫一次。

clear_infoframe 回撥是可選的。

返回值:成功時為 0,否則為負錯誤程式碼

write_infoframe

此回撥透過 drm_atomic_helper_connector_hdmi_update_infoframes 在提交期間呼叫,以將資訊幀程式設計到硬體中。它將被多次呼叫,對於每個更新的資訊幀型別呼叫一次。

write_infoframe 回撥是強制性的。

返回值:成功時為 0,否則為負錯誤程式碼

read_edid

此回撥被框架用作從 connector->ddc 讀取 EDID 的替代方法。仍然建議提供 connector->ddc 而不是實現此回撥。返回的 EDID 應透過 drm_edid_free() 釋放。

read_edid 回撥是可選的。

返回值:成功時為有效 EDID,失敗時為 NULL。

struct drm_connector_funcs

控制給定裝置上的聯結器

定義:

struct drm_connector_funcs {
    int (*dpms)(struct drm_connector *connector, int mode);
    void (*reset)(struct drm_connector *connector);
    enum drm_connector_status (*detect)(struct drm_connector *connector, bool force);
    void (*force)(struct drm_connector *connector);
    int (*fill_modes)(struct drm_connector *connector, uint32_t max_width, uint32_t max_height);
    int (*set_property)(struct drm_connector *connector, struct drm_property *property, uint64_t val);
    int (*late_register)(struct drm_connector *connector);
    void (*early_unregister)(struct drm_connector *connector);
    void (*destroy)(struct drm_connector *connector);
    struct drm_connector_state *(*atomic_duplicate_state)(struct drm_connector *connector);
    void (*atomic_destroy_state)(struct drm_connector *connector, struct drm_connector_state *state);
    int (*atomic_set_property)(struct drm_connector *connector,struct drm_connector_state *state,struct drm_property *property, uint64_t val);
    int (*atomic_get_property)(struct drm_connector *connector,const struct drm_connector_state *state,struct drm_property *property, uint64_t *val);
    void (*atomic_print_state)(struct drm_printer *p, const struct drm_connector_state *state);
    void (*oob_hotplug_event)(struct drm_connector *connector, enum drm_connector_status status);
    void (*debugfs_init)(struct drm_connector *connector, struct dentry *root);
};

成員

dpms

設定每個聯結器 DPMS 狀態的傳統入口點。傳統 DPMS 作為聯結器上的標準屬性公開,但在 drm 核心中被轉移到此回撥。請注意,原子驅動程式不再在聯結器上實現 4 級 DPMS 支援,而是僅在 CRTC 物件上具有一個開/關“ACTIVE”屬性。

原子驅動程式不使用此鉤子,傳統 DPMS 屬性的重新對映完全在 DRM 核心中處理。

返回值

成功時為 0,失敗時為負錯誤程式碼。

重置

將聯結器硬體和軟體狀態重置為關閉。此函式不由核心直接呼叫,僅透過 drm_mode_config_reset() 呼叫。由於歷史原因,它不是一個 helper 鉤子。

原子驅動程式可以使用 drm_atomic_helper_connector_reset() 使用此鉤子重置原子狀態。

detect

檢查是否有任何東西連線到聯結器。引數 force 在輪詢時設定為 false,在由於使用者請求而檢查聯結器時設定為 true。驅動程式可以使用 force 來避免在自動探測期間進行昂貴的、破壞性的操作。

此回撥是可選的,如果未實現,則聯結器將被視為始終連線。

待辦

請注意,此鉤子僅由 probe helper 呼叫。它不在 helper 庫 vtable 中僅僅是出於歷史原因。探測聯結器狀態的唯一 DRM 核心入口點是 fill_modes

請注意,helper 庫已經持有 drm_mode_config.connection_mutex。需要獲取其他鎖以避免與併發模式集更改競爭的驅動程式需要使用 drm_connector_helper_funcs.detect_ctx 代替。

另請注意,無論聯結器處於何種狀態,都可以呼叫此回撥。需要底層裝置上電才能執行檢測的驅動程式首先需要確保已正確啟用它。

返回值

drm_connector_status 指示聯結器的狀態。

force

當用戶空間透過 sysfs 介面或在核心命令列上強制將聯結器設定為特定狀態時,將呼叫此函式以更新內部編碼器狀態。在這種情況下,不會呼叫 detect 回撥。

待辦

請注意,此鉤子僅由 probe helper 呼叫。它不在 helper 庫 vtable 中僅僅是出於歷史原因。探測聯結器狀態的唯一 DRM 核心入口點是 fill_modes

fill_modes

輸出檢測和基本模式驗證的入口點。如果需要,驅動程式應重新探測輸出(例如,當熱插拔處理不可靠時),將所有檢測到的模式新增到 drm_connector.modes,並過濾掉裝置在任何配置中都無法支援的任何模式。它還需要過濾掉任何比引數 max_width 和 max_height 指示的更寬或更高的模式。

驅動程式還必須從 drm_connector.modes 中刪除任何不再有效的模式。此外,它必須更新 drm_connector.statusdrm_connector.edid。如果此輸出沒有收到 EDID,則 connector->edid 必須為 NULL。

使用 probe helpers 的驅動程式應使用 drm_helper_probe_single_connector_modes() 來實現此函式。

返回值

檢測到的模式數量並填充到 drm_connector.modes 中。

set_property

這是更新附加到聯結器的屬性的傳統入口點。

如果驅動程式不支援任何舊版驅動程式私有屬性,則此回撥是可選的。對於原子驅動程式,它不使用,因為屬性處理完全在 DRM 核心中完成。

返回值

成功時為 0,失敗時為負錯誤程式碼。

late_register

可以使用此可選鉤子來註冊附加到聯結器的其他使用者空間介面,例如背光控制、i2c、DP aux 或類似介面。它在驅動程式載入序列的後期從 drm_connector_register() 呼叫,以註冊所有核心 drm 聯結器介面。從此回撥新增的所有內容都應在 early_unregister 回撥中登出。

在持有 drm_connector.mutex 時呼叫。

返回

成功時為 0,失敗時為負錯誤程式碼。

early_unregister

此可選鉤子應用於登出附加到聯結器的其他使用者空間介面,這些介面來自 late_register()。它從 drm_connector_unregister() 呼叫,在驅動程式解除安裝序列的早期呼叫,以在資料結構被拆除之前停用使用者空間訪問。

在持有 drm_connector.mutex 時呼叫。

destroy

清理聯結器資源。這在驅動程式解除安裝時透過 drm_mode_config_cleanup() 呼叫。當聯結器被熱插拔時,也可能在執行時呼叫它,對於支援聯結器熱插拔的驅動程式(例如 DisplayPort MST)。

atomic_duplicate_state

複製此聯結器的當前原子狀態並返回它。核心和 helpers 保證任何使用此鉤子複製的原子狀態,並且仍然由呼叫者擁有(即,未透過呼叫 drm_mode_config_funcs.atomic_commit 轉移到驅動程式)將透過呼叫此結構中的 atomic_destroy_state 鉤子來清理。

此回撥對於原子驅動程式是必需的。

不子類化 struct drm_connector_state 的原子驅動程式應使用 drm_atomic_helper_connector_duplicate_state()。子類化狀態結構以使用驅動程式私有狀態擴充套件它的驅動程式應使用 __drm_atomic_helper_connector_duplicate_state() 來確保跨驅動程式以一致的方式複製共享狀態。

在正確初始化 drm_connector.state 之前呼叫此鉤子是一個錯誤。

注意

如果重複的狀態引用了引用計數的資源,則此鉤子必須獲取對每個資源的引用。驅動程式必須在 **atomic_destroy_state** 中再次釋放這些引用。

返回值

重複的原子狀態,或者當分配失敗時為 NULL。

atomic_destroy_state

銷燬使用 **atomic_duplicate_state** 複製的狀態,並釋放或取消引用它引用的所有資源

此回撥對於原子驅動程式是必需的。

atomic_set_property

解碼驅動程式私有屬性值,並將解碼後的值儲存到傳入的狀態結構中。由於原子核心解碼所有標準化屬性(即使是超出核心屬性集範圍的擴充套件,這些擴充套件可能並非所有驅動程式都實現),因此這要求驅動程式繼承狀態結構。

此類驅動程式私有屬性實際上只應為真正的硬體/供應商特定狀態實現。相反,最好標準化原子擴充套件並在核心中解碼用於公開此類擴充套件的屬性。

不要直接呼叫此函式,請使用 drm_atomic_connector_set_property() 代替。

如果驅動程式不支援任何驅動程式私有原子屬性,則此回撥是可選的。

注意

此函式在原子模式設定的狀態程式集階段中呼叫,該階段可能因任何原因中止(包括應使用者空間請求僅檢查配置是否可能)。驅動程式不得觸控任何持久狀態(硬體或軟體)或資料結構,除了傳入的 **state** 引數。

此外,由於使用者空間控制屬性的設定順序,因此此函式不得進行任何輸入驗證(因為狀態更新不完整,因此可能不一致)。相反,任何此類輸入驗證都必須在各種 atomic_check 回撥中完成。

返回值

如果找到了該屬性,則為 0;如果驅動程式未實現該屬性,則為 -EINVAL(這不應該發生,核心只請求附加到此聯結器的屬性)。驅動程式不允許進行其他驗證。核心已經檢查了屬性值是否在驅動程式註冊該屬性時設定的範圍內(整數、有效列舉值...)。

atomic_get_property

讀取解碼後的驅動程式私有屬性。這用於實現 GETCONNECTOR IOCTL。

不要直接呼叫此函式,請使用 drm_atomic_connector_get_property() 代替。

如果驅動程式不支援任何驅動程式私有原子屬性,則此回撥是可選的。

返回值

成功時為 0,如果驅動程式未實現該屬性,則為 -EINVAL(這不應該發生,核心只請求附加到此聯結器的屬性)。

atomic_print_state

如果驅動程式子類化 struct drm_connector_state,則應實現此可選鉤子以列印其他驅動程式特定狀態。

不要直接呼叫此函式,請使用 drm_atomic_connector_print_state() 代替。

oob_hotplug_event

當從顯示驅動程式/裝置外部的源接收到 drm-connector 的熱插拔事件時,將呼叫此函式。

debugfs_init

允許聯結器建立特定於聯結器的 debugfs 檔案。

描述

每個 CRTC 可以連線到一個或多個聯結器。以下函式允許核心 DRM 程式碼控制聯結器、列舉可用模式等。

struct drm_cmdline_mode

透過核心命令列傳遞的 DRM 模式

定義:

struct drm_cmdline_mode {
    char name[DRM_DISPLAY_MODE_LEN];
    bool specified;
    bool refresh_specified;
    bool bpp_specified;
    unsigned int pixel_clock;
    int xres;
    int yres;
    int bpp;
    int refresh;
    bool rb;
    bool interlace;
    bool cvt;
    bool margins;
    enum drm_connector_force force;
    unsigned int rotation_reflection;
    enum drm_panel_orientation panel_orientation;
    struct drm_connector_tv_margins tv_margins;
    enum drm_connector_tv_mode tv_mode;
    bool tv_mode_specified;
};

成員

名稱

模式的名稱。

specified

是否已從命令列讀取模式?

refresh_specified

該模式是否具有首選重新整理率?

bpp_specified

該模式是否具有首選 BPP?

pixel_clock

畫素時鐘,單位為 kHz。可選。

xres

X 軸上的活動解析度,以畫素為單位。

yres

Y 軸上的活動解析度,以畫素為單位。

bpp

該模式的每畫素位數。

refresh

重新整理率,單位為赫茲。

rb

我們需要使用減少的消隱嗎?

interlace

該模式是隔行掃描的。

cvt

時序將使用 VESA 協調影片時序計算,而不是從表中查詢模式。

margins

將邊距新增到模式計算(xres 的 1.8% 向下舍入到 8 畫素,yres 的 1.8%)。

force

忽略聯結器的熱插拔狀態,並強制將其狀態設定為 DRM_FORCE_* 值之一。

rotation_reflection

從命令列設定的模式的初始旋轉和反射。參見 DRM_MODE_ROTATE_* 和 DRM_MODE_REFLECT_*. 僅支援的旋轉是 DRM_MODE_ROTATE_0 和 DRM_MODE_ROTATE_180。

panel_orientation

drm-connector “面板方向”屬性覆蓋值,如果未設定,則為 DRM_MODE_PANEL_ORIENTATION_UNKNOWN。

tv_margins

應用於模式的 TV 邊距。

tv_mode

電視模式標準。參見 DRM_MODE_TV_MODE_*。

tv_mode_specified

該模式是否具有首選電視模式?

描述

每個聯結器都可以有一個初始模式,其中包含透過核心命令列傳遞的其他選項。此結構允許表達這些引數,並將由命令列解析器填充。

struct drm_connector_hdmi_audio

DRM gemeric HDMI 編解碼器相關結構

定義:

struct drm_connector_hdmi_audio {
    const struct drm_connector_hdmi_audio_funcs *funcs;
    struct platform_device *codec_pdev;
    struct mutex lock;
    void (*plugged_cb)(struct device *dev, bool plugged);
    struct device *plugged_cb_dev;
    bool last_state;
    int dai_port;
};

成員

funcs

要由 DRM HDMI 編解碼器框架使用的 HDMI 編解碼器功能的實現。

codec_pdev

為儲存 HDMI 編解碼器而建立的平臺裝置。它將在 drm_connector_cleanup() 期間自動登出。

lock

Mutex 用於保護 last_stateplugged_cbplugged_cb_dev

plugged_cb

當 HDMI sink 插入或從該聯結器拔出時要呼叫的回撥。當 ASoC 程式碼請求時,框架會分配此回撥。

plugged_cb_dev

plugged_cb() 的資料。它由 ASoC 提供。

last_state

框架記錄的上次插入狀態。它用於正確地向 plugged_cb() 報告狀態。

dai_port

DT 中用於編解碼器 DAI 的埠。

描述

HDMI 驅動程式通常包含 HDMI 編解碼器。此結構表示 DRM HDMI 編解碼器框架使用的通用 HDMI 編解碼器。

struct drm_connector

中央 DRM 聯結器控制結構

定義:

struct drm_connector {
    struct drm_device *dev;
    struct device *kdev;
    struct device_attribute *attr;
    struct fwnode_handle *fwnode;
    struct list_head head;
    struct list_head global_connector_list_entry;
    struct drm_mode_object base;
    char *name;
    struct mutex mutex;
    unsigned index;
    int connector_type;
    int connector_type_id;
    bool interlace_allowed;
    bool doublescan_allowed;
    bool stereo_allowed;
    bool ycbcr_420_allowed;
    enum drm_connector_registration_state registration_state;
    struct list_head modes;
    enum drm_connector_status status;
    struct list_head probed_modes;
    struct drm_display_info display_info;
    const struct drm_connector_funcs *funcs;
    struct drm_property_blob *edid_blob_ptr;
    struct drm_object_properties properties;
    struct drm_property *scaling_mode_property;
    struct drm_property *vrr_capable_property;
    struct drm_property *colorspace_property;
    struct drm_property_blob *path_blob_ptr;
    unsigned int max_bpc;
    struct drm_property *max_bpc_property;
    struct drm_privacy_screen *privacy_screen;
    struct notifier_block privacy_screen_notifier;
    struct drm_property *privacy_screen_sw_state_property;
    struct drm_property *privacy_screen_hw_state_property;
    struct drm_property *broadcast_rgb_property;
#define DRM_CONNECTOR_POLL_HPD (1 << 0);
#define DRM_CONNECTOR_POLL_CONNECT (1 << 1);
#define DRM_CONNECTOR_POLL_DISCONNECT (1 << 2);
    uint8_t polled;
    int dpms;
    const struct drm_connector_helper_funcs *helper_private;
    struct drm_cmdline_mode cmdline_mode;
    enum drm_connector_force force;
    const struct drm_edid *edid_override;
    struct mutex edid_override_mutex;
    u64 epoch_counter;
    u32 possible_encoders;
    struct drm_encoder *encoder;
#define MAX_ELD_BYTES   128;
    uint8_t eld[MAX_ELD_BYTES];
    struct mutex eld_mutex;
    bool latency_present[2];
    int video_latency[2];
    int audio_latency[2];
    struct i2c_adapter *ddc;
    int null_edid_counter;
    unsigned bad_edid_counter;
    bool edid_corrupt;
    u8 real_edid_checksum;
    struct dentry *debugfs_entry;
    struct drm_connector_state *state;
    struct drm_property_blob *tile_blob_ptr;
    bool has_tile;
    struct drm_tile_group *tile_group;
    bool tile_is_single_monitor;
    uint8_t num_h_tile, num_v_tile;
    uint8_t tile_h_loc, tile_v_loc;
    uint16_t tile_h_size, tile_v_size;
    struct llist_node free_node;
    struct hdr_sink_metadata hdr_sink_metadata;
    struct drm_connector_hdmi hdmi;
    struct drm_connector_hdmi_audio hdmi_audio;
};

成員

dev

父 DRM 裝置

kdev

sysfs 屬性的核心裝置

attr

sysfs 屬性

fwnode

平臺韌體提供的關聯 fwnode

驅動程式可以設定此項以將 fwnode 與聯結器關聯,驅動程式應在設定此項時獲取對 fwnode 的引用。drm_connector_cleanup() 將在此項上呼叫 fwnode_handle_put()。

head

dev 上所有聯結器的列表,從 drm_mode_config.connector_list 連結。受 drm_mode_config.connector_list_lock 保護,但請僅使用 drm_connector_list_iter 遍歷此列表。

global_connector_list_entry

全域性聯結器列表中的聯結器條目,由 drm_connector_find_by_fwnode() 使用。

基本

基本 KMS 物件

名稱

人類可讀的名稱,可以由驅動程式覆蓋

mutex

用於一般聯結器狀態的鎖,但目前僅保護 registered。大多數聯結器狀態仍然受 drm_mode_config.mutex 保護。

索引

壓縮的聯結器索引,與不支援熱新增/刪除的驅動程式的 mode_config.list 中的位置匹配。可以用作陣列索引。它在聯結器的生命週期內是不變的。

connector_type

drm_mode.h 中的 DRM_MODE_CONNECTOR_<foo> 型別之一

connector_type_id

聯結器型別列舉中的索引

interlace_allowed

此聯結器可以處理隔行掃描模式嗎?僅由 drm_helper_probe_single_connector_modes() 用於模式過濾。

doublescan_allowed

此聯結器可以處理 doublescan 嗎?僅由 drm_helper_probe_single_connector_modes() 用於模式過濾。

stereo_allowed

此聯結器可以處理立體模式嗎?僅由 drm_helper_probe_single_connector_modes() 用於模式過濾。

ycbcr_420_allowed

此布林值指示此聯結器是否能夠處理 YCBCR 420 輸出。在解析 EDID 塊時,瞭解源是否能夠處理 YCBCR 420 輸出非常有幫助。

registration_state

此聯結器是在初始化、已向用戶空間公開(已註冊)還是未註冊?

mutex 保護。

modes

此聯結器上可用的模式(來自 fill_modes() + 使用者)。受 drm_mode_config.mutex 保護。

status

drm_connector_status 列舉之一(已連線、未連線或未知)。受 drm_mode_config.mutex 保護。

probed_modes

這些是使用 DDC 或 BIOS 探測新增的模式,在應用過濾之前。由 probe helpers 使用。受 drm_mode_config.mutex 保護。

display_info

檢測到顯示器時,顯示資訊會從 EDID 資訊中填充。對於非熱插拔的顯示器,例如嵌入式系統中的平板顯示器,驅動程式應使用顯示器的物理尺寸初始化 drm_display_info.width_mmdrm_display_info.height_mm 欄位。

drm_mode_config.mutex 保護。

funcs

聯結器控制函式

edid_blob_ptr

DRM 屬性,如果存在則包含 EDID。受 drm_mode_config.mutex 保護。

只能透過呼叫 drm_edid_connector_update()drm_connector_update_edid_property() 來更新此屬性。

驅動程式不得直接使用此屬性。

properties

此聯結器的屬性跟蹤

scaling_mode_property

用於控制放大比例的可選原子屬性。請參閱 drm_connector_attach_content_protection_property()

vrr_capable_property

可選屬性,用於幫助使用者空間查詢聯結器上可變重新整理率的硬體支援。驅動程式可以透過呼叫 drm_connector_attach_vrr_capable_property() 將該屬性新增到聯結器。

只能透過呼叫 drm_connector_set_vrr_capable_property() 來更新此屬性。

colorspace_property

聯結器屬性,用於設定接收器支援的合適顏色空間。

path_blob_ptr

DP MST 路徑屬性的 DRM blob 屬性資料。只能透過呼叫 drm_connector_set_path_property() 來更新此屬性。

max_bpc

聯結器支援的每個顏色通道的最大位數。

max_bpc_property

用於驅動聯結器的最大 bpc 的預設聯結器屬性。

privacy_screen

此聯結器的 drm_privacy_screen,或 NULL。

privacy_screen_notifier

privacy-screen notifier_block

privacy_screen_sw_state_property

用於控制整合隱私螢幕的聯結器的可選原子屬性。

privacy_screen_hw_state_property

用於報告實際整合隱私螢幕狀態的聯結器的可選原子屬性。

broadcast_rgb_property

用於設定 Broadcast RGB 選擇以進行輸出的聯結器屬性。

polled

聯結器輪詢模式,是以下項的組合:

DRM_CONNECTOR_POLL_HPD

聯結器生成熱插拔事件,不需要定期輪詢。CONNECT 和 DISCONNECT 標誌不得與 HPD 標誌一起設定。

DRM_CONNECTOR_POLL_CONNECT

定期輪詢聯結器的連線狀態。

DRM_CONNECTOR_POLL_DISCONNECT

定期輪詢聯結器的斷開連線狀態,即使聯結器正在使用中也不會導致閃爍。DAC 在沒有大量測試的情況下應很少這樣做。

對於不支援連線狀態發現的聯結器,設定為 0。

dpms

當前的 dpms 狀態。對於舊版驅動程式,drm_connector_funcs.dpms 回撥必須更新此值。對於原子驅動程式,這由核心原子程式碼處理,驅動程式只需考慮 drm_crtc_state.active 即可。

helper_private

中間層私有資料

cmdline_mode

從此聯結器的核心 cmdline 中解析的模式行

force

強制模式設定的 DRM_FORCE_<foo> 狀態

edid_override

透過 debugfs 設定的覆蓋 EDID。

請勿在 drm_edid_override_* 系列函式之外修改或訪問。

edid_override_mutex

保護對 edid_override 的訪問。

epoch_counter

用於檢測聯結器中的任何其他更改,狀態除外

possible_encoders

可以驅動此聯結器的編碼器的位掩碼,drm_encoder_index() 確定位域中的索引,位使用 drm_connector_attach_encoder() 設定。

encoder

當前繫結到驅動此聯結器的編碼器(如果存在)。僅對於非原子驅動程式真正有意義。原子驅動程式應改為檢視 drm_connector_state.best_encoder,如果需要驅動此輸出的 CRTC,則檢視 drm_connector_state.crtc

eld

類似 EDID 的資料(如果存在),受 eld_mutex 保護

eld_mutex

保護對 eld 的併發訪問

latency_present

來自 ELD 的 AV 延遲資訊(如果找到)

video_latency

來自 ELD 的影片延遲資訊(如果找到)。[0]:逐行掃描,[1]:隔行掃描

audio_latency

來自 ELD 的音訊延遲資訊(如果找到)。[0]:逐行掃描,[1]:隔行掃描

ddc

關聯的 ddc 介面卡。聯結器通常具有其關聯的 ddc 介面卡。如果驅動程式使用此欄位,則在聯結器 sysfs 目錄中建立一個相應的符號連結,以便使用者可以輕鬆地判斷哪個 i2c 介面卡用於特定顯示器。

應透過呼叫 drm_connector_init_with_ddc() 來設定該欄位。

null_edid_counter

跟蹤為我們提供 EDID 全零的接收器。需要解決我們獲得全 0 的一些硬體錯誤

bad_edid_counter

跟蹤為我們提供具有無效校驗和的 EDID 的接收器

edid_corrupt

指示上次讀取的 EDID 是否已損壞。用於 Displayport 一致性測試 - Displayport Link CTS Core 1.2 rev1.1 4.2.2.6

real_edid_checksum

損壞的 edid 塊的真實 edid 校驗和。Displayport 1.4 一致性測試 rev1.1 4.2.2.6 中需要

debugfs_entry

此聯結器的 debugfs 目錄

state

此聯結器的當前原子狀態。

drm_mode_config.connection_mutex 保護。請注意,非阻塞原子提交在不加鎖的情況下訪問當前聯結器狀態。要麼透過 struct drm_atomic_state 指標,請參閱 for_each_oldnew_connector_in_state()for_each_old_connector_in_state()for_each_new_connector_in_state()。要麼透過原子輔助函式中實現的原子提交操作的仔細排序,請參閱 struct drm_crtc_commit

tile_blob_ptr

平鋪屬性的 DRM blob 屬性資料(主要由 DP MST 使用)。這適用於透過由 drm_crtc 表示的單獨顯示流水線驅動的螢幕,這些流水線可能未執行 genlocked 時鐘。對於像雙鏈路 LVDS 或雙鏈路 DSI 這樣 genlocked 的平鋪面板,驅動程式應儘量不公開平鋪,並在需要時虛擬化 drm_crtcdrm_plane

只能透過呼叫 drm_connector_set_tile_property() 來更新此屬性。

has_tile

此聯結器是否連線到平鋪顯示器

tile_group

連線顯示器的平鋪組

tile_is_single_monitor

平鋪是否為單個顯示器外殼

num_h_tile

平鋪組中的水平平鋪數

num_v_tile

平鋪組中的垂直平鋪數

tile_h_loc

此平鋪的水平位置

tile_v_loc

此平鋪的垂直位置

tile_h_size

此平鋪的水平大小。

tile_v_size

此平鋪的垂直大小。

free_node

僅由 drm_connector_list_iter 使用的列表,以便能夠從任何上下文中清理聯結器,與 drm_mode_config.connector_free_work 結合使用。

hdr_sink_metadata

從接收器讀取的 HDR 元資料資訊

hdmi

HDMI 相關變數和屬性。

hdmi_audio

HDMI 編解碼器屬性和非 DRM 狀態。

描述

每個聯結器可以連線到一個或多個 CRTC,或者如果它們可以共享一個 CRTC,則可以被另一個聯結器克隆。每個聯結器在更廣泛的顯示器中也具有特定位置(稱為“螢幕”,儘管它可以跨越多個顯示器)。

struct drm_connector *drm_connector_lookup(struct drm_device *dev, struct drm_file *file_priv, uint32_t id)

查詢聯結器物件

引數

struct drm_device *dev

DRM 裝置

struct drm_file *file_priv

用於檢查租賃的 DRM 檔案。

uint32_t id

聯結器物件 ID

描述

此函式查詢由 id 指定的聯結器物件,並獲取對其的引用。

void drm_connector_get(struct drm_connector *connector)

獲取聯結器引用

引數

struct drm_connector *connector

DRM 聯結器

描述

此函式遞增聯結器的 refcount。

void drm_connector_put(struct drm_connector *connector)

釋放聯結器引用

引數

struct drm_connector *connector

DRM 聯結器

描述

此函式遞減聯結器的引用計數,並在引用計數降至零時釋放該物件。

bool drm_connector_is_unregistered(struct drm_connector *connector)

聯結器是否已從使用者空間登出?

引數

struct drm_connector *connector

DRM 聯結器

描述

檢查是否已從使用者空間登出了 connector

返回

如果已登出聯結器,則為 True;如果已註冊聯結器或尚未向用戶空間註冊,則為 False。

struct drm_tile_group

平鋪組元資料

定義:

struct drm_tile_group {
    struct kref refcount;
    struct drm_device *dev;
    int id;
    u8 group_data[8];
};

成員

refcount

引用計數

dev

DRM 裝置

id

暴露給使用者空間的平鋪組 ID

group_data

標識此組的接收器私有資料

描述

對於具有 EDID 的外部螢幕,group_data 對應於 displayid vend/prod/serial。

struct drm_connector_list_iter

connector_list 迭代器

定義:

struct drm_connector_list_iter {
};

成員

描述

此迭代器跟蹤在 struct drm_mode_config 中遍歷 connector_list 所需的狀態。僅與 drm_connector_list_iter_begin()drm_connector_list_iter_end()drm_connector_list_iter_next() 以及便捷宏 drm_for_each_connector_iter() 一起使用。

請注意,drm_connector_list_iter_next() 的返回值僅在下一次 drm_connector_list_iter_next()drm_connector_list_iter_end() 呼叫之前有效。如果稍後要使用該聯結器,則需要首先使用 drm_connector_get() 獲取自己的引用。

drm_for_each_connector_iter

drm_for_each_connector_iter (connector, iter)

connector_list 迭代器宏

引數

connector

用作遊標的 struct drm_connector 指標

iter

struct drm_connector_list_iter

描述

請注意,connector 僅在列表主體中有效。如果在呼叫 drm_connector_list_iter_end() 後要使用 connector,則需要首先使用 drm_connector_get() 獲取自己的引用。

drm_connector_for_each_possible_encoder

drm_connector_for_each_possible_encoder (connector, encoder)

迭代聯結器的可能編碼器

引數

connector

struct drm_connector 指標

encoder

用作遊標的 struct drm_encoder 指標

const char *drm_get_connector_type_name(unsigned int type)

返回聯結器型別的字串

引數

unsigned int type

聯結器型別 (DRM_MODE_CONNECTOR_*)

返回

聯結器型別的名稱,如果型別無效,則為 NULL。

int drm_connector_init(struct drm_device *dev, struct drm_connector *connector, const struct drm_connector_funcs *funcs, int connector_type)

初始化預分配的聯結器

引數

struct drm_device *dev

DRM 裝置

struct drm_connector *connector

要初始化的聯結器

const struct drm_connector_funcs *funcs

此聯結器的回撥

int connector_type

使用者可見的聯結器型別

描述

初始化預分配的聯結器。聯結器應作為驅動程式聯結器物件的一部分進行子類化。

在驅動程式解除安裝時,驅動程式的 drm_connector_funcs.destroy 鉤子函式應呼叫 drm_connector_cleanup() 並釋放聯結器結構體。聯結器結構體不應使用 devm_kzalloc() 分配。

注意

考慮使用 drmm_connector_init() 而不是 drm_connector_init(),以便讓 DRM 管理的資源基礎設施負責清理和釋放。

返回

成功時為零,失敗時為錯誤程式碼。

int drm_connector_dynamic_init(struct drm_device *dev, struct drm_connector *connector, const struct drm_connector_funcs *funcs, int connector_type, struct i2c_adapter *ddc)

初始化一個預先分配的動態聯結器

引數

struct drm_device *dev

DRM 裝置

struct drm_connector *connector

要初始化的聯結器

const struct drm_connector_funcs *funcs

此聯結器的回撥

int connector_type

使用者可見的聯結器型別

struct i2c_adapter *ddc

指向關聯的 ddc 介面卡的指標

描述

初始化一個預先分配的動態聯結器。聯結器應作為驅動程式聯結器物件的一部分進行子類化。聯結器結構體不應使用 devm_kzalloc() 分配。

對於在 drm_dev_register() 被呼叫後可以熱插拔的動態聯結器,例如 DP MST 聯結器,驅動程式應呼叫此函式。對於所有其他 - 靜態 - 聯結器,驅動程式應呼叫 drm_connector_init*()/drmm_connector_init*() 函式之一。

呼叫此函式後,驅動程式必須呼叫 drm_connector_dynamic_register()

要移除聯結器,驅動程式必須呼叫 drm_connector_unregister(),然後呼叫 drm_connector_put()。釋放最後一個引用將呼叫驅動程式的 drm_connector_funcs.destroy 鉤子函式,該函式又必須呼叫 drm_connector_cleanup() 並釋放聯結器結構體。

返回

成功時為零,失敗時為錯誤程式碼。

int drm_connector_init_with_ddc(struct drm_device *dev, struct drm_connector *connector, const struct drm_connector_funcs *funcs, int connector_type, struct i2c_adapter *ddc)

初始化預分配的聯結器

引數

struct drm_device *dev

DRM 裝置

struct drm_connector *connector

要初始化的聯結器

const struct drm_connector_funcs *funcs

此聯結器的回撥

int connector_type

使用者可見的聯結器型別

struct i2c_adapter *ddc

指向關聯的 ddc 介面卡的指標

描述

初始化預分配的聯結器。聯結器應作為驅動程式聯結器物件的一部分進行子類化。

在驅動程式解除安裝時,驅動程式的 drm_connector_funcs.destroy 鉤子函式應呼叫 drm_connector_cleanup() 並釋放聯結器結構體。聯結器結構體不應使用 devm_kzalloc() 分配。

確保正確設定聯結器的 ddc 欄位。

注意

考慮使用 drmm_connector_init() 而不是 drm_connector_init_with_ddc(),以便讓 DRM 管理的資源基礎設施負責清理和釋放。

返回

成功時為零,失敗時為錯誤程式碼。

int drmm_connector_init(struct drm_device *dev, struct drm_connector *connector, const struct drm_connector_funcs *funcs, int connector_type, struct i2c_adapter *ddc)

初始化預分配的聯結器

引數

struct drm_device *dev

DRM 裝置

struct drm_connector *connector

要初始化的聯結器

const struct drm_connector_funcs *funcs

此聯結器的回撥

int connector_type

使用者可見的聯結器型別

struct i2c_adapter *ddc

指向關聯的 ddc 介面卡的可選指標

描述

初始化預分配的聯結器。聯結器應作為驅動程式聯結器物件的一部分進行子類化。

透過在 DRM 管理的操作中呼叫 drm_connector_cleanup() 自動處理清理。

聯結器結構體應使用 drmm_kzalloc() 分配。

drm_connector_funcs.destroy 鉤子函式必須為 NULL。

返回

成功時為零,失敗時為錯誤程式碼。

int drmm_connector_hdmi_init(struct drm_device *dev, struct drm_connector *connector, const char *vendor, const char *product, const struct drm_connector_funcs *funcs, const struct drm_connector_hdmi_funcs *hdmi_funcs, int connector_type, struct i2c_adapter *ddc, unsigned long supported_formats, unsigned int max_bpc)

初始化一個預先分配的 HDMI 聯結器

引數

struct drm_device *dev

DRM 裝置

struct drm_connector *connector

指向要初始化的 HDMI 聯結器的指標

const char *vendor

HDMI 控制器供應商名稱

const char *product

HDMI 控制器產品名稱

const struct drm_connector_funcs *funcs

此聯結器的回撥

const struct drm_connector_hdmi_funcs *hdmi_funcs

此聯結器的 HDMI 相關回調

int connector_type

使用者可見的聯結器型別

struct i2c_adapter *ddc

指向關聯的 ddc 介面卡的可選指標

unsigned long supported_formats

hdmi_colorspace 的位掩碼,列出支援的輸出格式

unsigned int max_bpc

HDMI 聯結器支援的最大每字元位數

描述

初始化一個預先分配的 HDMI 聯結器。聯結器可以作為驅動程式聯結器物件的一部分進行子類化。

透過在 DRM 管理的操作中呼叫 drm_connector_cleanup() 自動處理清理。

聯結器結構體應使用 drmm_kzalloc() 分配。

drm_connector_funcs.destroy 鉤子函式必須為 NULL。

返回

成功時為零,失敗時為錯誤程式碼。

void drm_connector_attach_edid_property(struct drm_connector *connector)

附加 edid 屬性。

引數

struct drm_connector *connector

聯結器

描述

某些聯結器型別(如 DRM_MODE_CONNECTOR_VIRTUAL)預設情況下不會附加 edid 屬性。此函式可用於在這些情況下顯式啟用 edid 屬性。

int drm_connector_attach_encoder(struct drm_connector *connector, struct drm_encoder *encoder)

將聯結器附加到編碼器

引數

struct drm_connector *connector

要附加的聯結器

struct drm_encoder *encoder

要將 connector 附加到的編碼器

描述

此函式將聯結器連結到編碼器。請注意,編碼器和 crtc 之間的路由限制透過 possible_clones 和 possible_crtcs 位掩碼暴露給使用者空間。

返回

成功時返回零,失敗時返回負 errno。

bool drm_connector_has_possible_encoder(struct drm_connector *connector, struct drm_encoder *encoder)

檢查聯結器和編碼器是否彼此關聯

引數

struct drm_connector *connector

聯結器

struct drm_encoder *encoder

編碼器

返回

如果 encoderconnector 的可能編碼器之一,則為 True。

void drm_connector_cleanup(struct drm_connector *connector)

清理已初始化的聯結器

引數

struct drm_connector *connector

要清理的聯結器

描述

清理聯結器但不釋放物件。

int drm_connector_register(struct drm_connector *connector)

註冊聯結器

引數

struct drm_connector *connector

要註冊的聯結器

描述

為聯結器註冊使用者空間介面。驅動程式不應呼叫此函式。靜態聯結器將由 DRM 核心從 drm_dev_register() 自動註冊,動態聯結器 (MST) 應由驅動程式呼叫 drm_connector_dynamic_register() 註冊。

當聯結器不再可用時,呼叫者必須呼叫 drm_connector_unregister()

注意

驅動程式中此函式的現有用法應已是空操作,並且計劃移除。

返回

成功時為零,失敗時為錯誤程式碼。

int drm_connector_dynamic_register(struct drm_connector *connector)

註冊動態聯結器

引數

struct drm_connector *connector

要註冊的聯結器

描述

為聯結器註冊使用者空間介面。僅對透過呼叫 drm_connector_dynamic_init() 初始化的聯結器呼叫此函式。所有其他聯結器將在呼叫 drm_dev_register() 時自動註冊。

當聯結器不再可用時,驅動程式必須呼叫 drm_connector_unregister()

返回

成功時為零,失敗時為錯誤程式碼。

void drm_connector_unregister(struct drm_connector *connector)

登出聯結器

引數

struct drm_connector *connector

要登出的聯結器

描述

為聯結器登出使用者空間介面。驅動程式應僅對透過呼叫 drm_connector_dynamic_register() 顯式註冊的動態聯結器 (MST) 呼叫此函式。所有其他 - 靜態 - 聯結器將由 DRM 核心自動登出,驅動程式不應為這些聯結器呼叫此函式。

注意

驅動程式中此函式的現有用法應已是空操作,並且計劃移除。

const char *drm_get_connector_status_name(enum drm_connector_status status)

返回聯結器狀態的字串

引數

enum drm_connector_status status

要計算名稱的聯結器狀態

描述

與其他 drm_get_*_name 函式相比,此函式返回一個 const 指標,因此是執行緒安全的。

返回

聯結器狀態字串

void drm_connector_list_iter_begin(struct drm_device *dev, struct drm_connector_list_iter *iter)

初始化 connector_list 迭代器

引數

struct drm_device *dev

DRM 裝置

struct drm_connector_list_iter *iter

connector_list 迭代器

描述

設定 iter 以遍歷 devdrm_mode_config.connector_listiter 必須始終透過呼叫 drm_connector_list_iter_end() 再次清理。迭代本身使用 drm_connector_list_iter_next()drm_for_each_connector_iter() 進行。

struct drm_connector *drm_connector_list_iter_next(struct drm_connector_list_iter *iter)

返回下一個聯結器

引數

struct drm_connector_list_iter *iter

connector_list 迭代器

返回

iter 的下一個聯結器,或者在列表遍歷完成時返回 NULL。

void drm_connector_list_iter_end(struct drm_connector_list_iter *iter)

拆卸聯結器列表迭代器

引數

struct drm_connector_list_iter *iter

connector_list 迭代器

描述

拆卸 iter 並釋放任何資源(如遍歷列表時獲取的 drm_connector 引用)。無論迭代完全完成還是在未遍歷整個列表的情況下中止,都必須始終呼叫此函式。

const char *drm_get_subpixel_order_name(enum subpixel_order order)

返回給定子畫素列舉的字串

引數

enum subpixel_order order

subpixel_order 的列舉

描述

請注意,你可以濫用此功能並返回超出範圍的內容,但這將是呼叫者的錯誤。任何未清理的使用者資料都不應到達此處。

返回

描述列舉的子畫素屬性的字串

int drm_display_info_set_bus_formats(struct drm_display_info *info, const u32 *formats, unsigned int num_formats)

設定支援的匯流排格式

引數

struct drm_display_info *info

用於儲存匯流排格式的顯示資訊

const u32 *formats

包含支援的匯流排格式的陣列

unsigned int num_formats

fmts 陣列中的條目數

描述

將支援的匯流排格式儲存在顯示資訊結構中。有關可用格式的完整列表,請參見 include/uapi/linux/media-bus-format.h 中的 MEDIA_BUS_FMT_* 定義。

返回

成功時為 0,失敗時為負錯誤程式碼。

int drm_get_tv_mode_from_name(const char *name, size_t len)

將電視模式名稱轉換為其列舉值

引數

const char *name

我們要轉換的電視模式名稱

size_t len

name 的長度

描述

name 轉換為 enum drm_connector_tv_mode

返回

成功時的列舉值,否則為負的 errno。

int drm_mode_create_dvi_i_properties(struct drm_device *dev)

建立 DVI-I 特定的聯結器屬性

引數

struct drm_device *dev

DRM 裝置

描述

由驅動程式在首次建立 DVI-I 聯結器時呼叫。

返回

0

void drm_connector_attach_dp_subconnector_property(struct drm_connector *connector)

為 DP 建立子聯結器屬性

引數

struct drm_connector *connector

要附加屬性的 drm_connector

描述

由驅動程式在建立 DP 聯結器時呼叫。

int drm_connector_attach_content_type_property(struct drm_connector *connector)

附加 content-type 屬性

引數

struct drm_connector *connector

要在其上附加 content type 屬性的聯結器。

描述

由驅動程式在首次建立 HDMI 聯結器時呼叫。

返回

0

void drm_connector_attach_tv_margin_properties(struct drm_connector *connector)

附加 TV 聯結器邊距屬性

引數

struct drm_connector *connector

DRM 聯結器

描述

當驅動程式需要將 TV 邊距屬性附加到聯結器時呼叫。通常用於 SDTV 和 HDMI 聯結器。

int drm_mode_create_tv_margin_properties(struct drm_device *dev)

建立 TV 聯結器邊距屬性

引數

struct drm_device *dev

DRM 裝置

描述

此函式由驅動程式的 HDMI 聯結器初始化例程呼叫,用於為給定裝置建立 TV 邊距屬性。對於 SDTV 聯結器,無需呼叫此函式,它已經從 drm_mode_create_tv_properties_legacy() 中呼叫。

返回

成功時為 0,失敗時為負錯誤程式碼。

int drm_mode_create_tv_properties_legacy(struct drm_device *dev, unsigned int num_modes, const char *const modes[])

建立 TV 特定的聯結器屬性

引數

struct drm_device *dev

DRM 裝置

unsigned int num_modes

支援的不同 TV 格式(模式)的數量

const char * const modes[]

指向包含每個格式名稱的字串的指標陣列

描述

此函式由驅動程式的 TV 初始化例程呼叫,用於為給定裝置建立 TV 特定的聯結器屬性。呼叫者負責分配格式名稱列表並將它們傳遞給此例程。

注意

此函式註冊已棄用的“mode”聯結器屬性,以選擇模擬電視模式(即,NTSC、PAL 等)。新的驅動程式必須使用 drm_mode_create_tv_properties() 代替。

返回

成功時為 0,失敗時為負錯誤程式碼。

int drm_mode_create_tv_properties(struct drm_device *dev, unsigned int supported_tv_modes)

建立 TV 特定的聯結器屬性

引數

struct drm_device *dev

DRM 裝置

unsigned int supported_tv_modes

支援的 TV 模式的位掩碼(參見 DRM_MODE_TV_MODE_*)

描述

此函式由驅動程式的 TV 初始化例程呼叫,用於為給定裝置建立 TV 特定的聯結器屬性。

返回

成功時為 0,失敗時為負錯誤程式碼。

int drm_mode_create_scaling_mode_property(struct drm_device *dev)

建立縮放模式屬性

引數

struct drm_device *dev

DRM 裝置

描述

由驅動程式在首次需要時呼叫,必須附加到所需的聯結器。

原子驅動程式應使用 drm_connector_attach_scaling_mode_property() 代替,以在原子狀態中正確分配 drm_connector_state.scaling_mode

返回

0

int drm_connector_attach_vrr_capable_property(struct drm_connector *connector)

建立 vrr_capable 屬性

引數

struct drm_connector *connector

在其上建立 vrr_capable 屬性的聯結器。

描述

原子驅動程式使用它來新增對查詢聯結器的可變重新整理率功能的支援。

返回

成功時返回零,失敗時返回負 errno。

int drm_connector_attach_scaling_mode_property(struct drm_connector *connector, u32 scaling_mode_mask)

附加原子縮放模式屬性

引數

struct drm_connector *connector

要在其上附加縮放模式屬性的聯結器。

u32 scaling_mode_mask

BIT(DRM_MODE_SCALE_*) 的或運算掩碼。

描述

這用於向原子驅動程式新增對縮放模式的支援。縮放模式將設定為 drm_connector_state.scaling_mode,並且可以從 drm_connector_helper_funcs->atomic_check 中用於驗證。

這是 drm_mode_create_scaling_mode_property() 的原子版本。

返回

成功時返回零,失敗時返回負 errno。

int drm_mode_create_aspect_ratio_property(struct drm_device *dev)

建立寬高比屬性

引數

struct drm_device *dev

DRM 裝置

描述

由驅動程式在首次需要時呼叫,必須附加到所需的聯結器。

返回

成功時返回零,失敗時返回負 errno。

int drm_mode_create_hdmi_colorspace_property(struct drm_connector *connector, u32 supported_colorspaces)

建立 HDMI 色彩空間屬性

引數

struct drm_connector *connector

在其上建立 Colorspace 屬性的聯結器。

u32 supported_colorspaces

支援的顏色空間的點陣圖

描述

由驅動程式在首次需要時呼叫,必須附加到所需的 HDMI 聯結器。

返回

成功時返回零,失敗時返回負 errno。

int drm_mode_create_dp_colorspace_property(struct drm_connector *connector, u32 supported_colorspaces)

建立 dp 色彩空間屬性

引數

struct drm_connector *connector

在其上建立 Colorspace 屬性的聯結器。

u32 supported_colorspaces

支援的顏色空間的點陣圖

描述

由驅動程式在首次需要時呼叫,必須附加到所需的 DP 聯結器。

返回

成功時返回零,失敗時返回負 errno。

int drm_mode_create_content_type_property(struct drm_device *dev)

建立 content type 屬性

引數

struct drm_device *dev

DRM 裝置

描述

由驅動程式在首次需要時呼叫,必須附加到所需的聯結器。

返回

成功時返回零,失敗時返回負 errno。

int drm_mode_create_suggested_offset_properties(struct drm_device *dev)

建立 suggests offset 屬性

引數

struct drm_device *dev

DRM 裝置

描述

為聯結器建立建議的 x/y 偏移屬性。

返回

成功時為 0,失敗時為負錯誤程式碼。

int drm_connector_set_path_property(struct drm_connector *connector, const char *path)

在聯結器上設定 tile 屬性

引數

struct drm_connector *connector

要在其上設定屬性的聯結器。

const char *path

用於屬性的路徑;不得為 NULL。

描述

這會建立一個屬性,以向用戶空間公開,以指定聯結器路徑。這主要用於 DisplayPort MST,其中聯結器具有拓撲結構,並且我們希望允許使用者空間為它們提供更有意義的名稱。

返回

成功時返回零,失敗時返回負 errno。

int drm_connector_set_tile_property(struct drm_connector *connector)

在聯結器上設定 tile 屬性

引數

struct drm_connector *connector

要在其上設定屬性的聯結器。

描述

這將查詢聯結器的 tile 資訊,並建立一個屬性供使用者空間在存在時進行解析。該屬性的形式為 8 個整數,使用“:”作為分隔符。這用於具有 DisplayPort SST 或 DisplayPort MST 聯結器的雙埠 tiled 顯示器。

返回

成功時返回零,失敗時返回 errno。

設定聯結器的連結狀態屬性

引數

struct drm_connector *connector

drm 聯結器

uint64_t link_status

連結狀態屬性的新值(0:良好,1:不良)

描述

在通常的工作場景中,此連結狀態屬性將始終設定為“GOOD”。如果在模式設定期間或之後發生某些錯誤,則核心驅動程式可能會將此連結狀態屬性設定為“BAD”。然後,呼叫者需要傳送一個熱插拔 uevent,以便使用者空間透過 GET_CONNECTOR_IOCTL 重新檢查有效模式並重試模式設定。

新增此屬性的原因是為了處理連結訓練失敗,但這並不限於 DP 或連結訓練。例如,如果我們實現非同步 setcrtc,則可以使用此屬性報告其中的任何失敗。

注意

驅動程式不能依賴於使用者空間來支援此屬性併發出模式設定。因此,他們可以選擇在沒有使用者空間干預的情況下處理問題(如重新訓練連結)。

int drm_connector_attach_max_bpc_property(struct drm_connector *connector, int min, int max)

附加 "max bpc" 屬性

引數

struct drm_connector *connector

聯結器,用於附加 max bpc 屬性。

int min

聯結器支援的最小位深度。

int max

聯結器支援的最大位深度。

描述

用於新增限制聯結器位深度的支援。

返回

成功時返回零,失敗時返回負 errno。

int drm_connector_attach_hdr_output_metadata_property(struct drm_connector *connector)

附加 “HDR_OUTPUT_METADA” 屬性

引數

struct drm_connector *connector

聯結器,用於附加屬性。

描述

用於允許使用者空間將 HDR 元資料傳送到驅動程式。

返回

成功時返回零,失敗時返回負 errno。

int drm_connector_attach_broadcast_rgb_property(struct drm_connector *connector)

附加 “Broadcast RGB” 屬性

引數

struct drm_connector *connector

聯結器,用於附加屬性。

描述

用於新增強制聯結器上 RGB 範圍的支援

返回

成功時返回零,失敗時返回負 errno。

int drm_connector_attach_colorspace_property(struct drm_connector *connector)

附加 "Colorspace" 屬性

引數

struct drm_connector *connector

聯結器,用於附加屬性。

描述

用於允許使用者空間將輸出色彩空間訊號傳送到驅動程式。

返回

成功時返回零,失敗時返回負 errno。

bool drm_connector_atomic_hdr_metadata_equal(struct drm_connector_state *old_state, struct drm_connector_state *new_state)

檢查 hdr 元資料是否已更改

引數

struct drm_connector_state *old_state

要比較的舊聯結器狀態

struct drm_connector_state *new_state

要比較的新聯結器狀態

描述

啟用了 HDR 的驅動程式使用此功能來測試兩個不同聯結器狀態之間的 HDR 元資料是否已更改(因此可能需要進行全面的模式更改)。

返回

如果元資料相等,則為 True,否則為 False

void drm_connector_set_vrr_capable_property(struct drm_connector *connector, bool capable)

設定聯結器的可變重新整理率能力屬性

引數

struct drm_connector *connector

drm 聯結器

bool capable

如果聯結器具有可變重新整理率能力,則為 True

描述

應由 atomic 驅動程式使用來更新聯結器上指示的可變重新整理率支援。

int drm_connector_set_panel_orientation(struct drm_connector *connector, enum drm_panel_orientation panel_orientation)

設定聯結器的 panel_orientation

引數

struct drm_connector *connector

要為其設定面板方向屬性的聯結器。

enum drm_panel_orientation panel_orientation

要設定的 drm_panel_orientation 值

描述

此函式設定聯結器的 panel_orientation,並將“面板方向”屬性附加到聯結器。

在已設定 panel_orientation 的聯結器上呼叫此函式是一個空操作(例如,已使用核心命令列選項覆蓋了方向)。

允許使用 DRM_MODE_PANEL_ORIENTATION_UNKNOWN 的 panel_orientation 呼叫此函式,在這種情況下,它是一個空操作。

該函式不應在註冊 drm 後在面板中呼叫(即在 drm 中呼叫 drm_dev_register())。

返回

成功時返回零,失敗時返回負 errno。

int drm_connector_set_panel_orientation_with_quirk(struct drm_connector *connector, enum drm_panel_orientation panel_orientation, int width, int height)

在檢查怪癖後設置聯結器的 panel_orientation

引數

struct drm_connector *connector

要為其初始化面板方向屬性的聯結器。

enum drm_panel_orientation panel_orientation

要設定的 drm_panel_orientation 值

int width

面板的畫素寬度,用於面板怪癖檢測

int height

面板的畫素高度,用於面板怪癖檢測

描述

類似於 drm_connector_set_panel_orientation(),但具有平臺特定的(例如,基於 DMI)怪癖檢查,該怪癖會覆蓋傳入的 panel_orientation。

返回

成功時返回零,失敗時返回負 errno。

int drm_connector_set_orientation_from_panel(struct drm_connector *connector, struct drm_panel *panel)

從面板的回撥設定聯結器的 panel_orientation。

引數

struct drm_connector *connector

要為其初始化面板方向屬性的聯結器。

struct drm_panel *panel

可以提供方向資訊的面板。

描述

Drm 驅動程式應在 drm_dev_register() 之前呼叫此函式。方向是從面板的 .get_orientation() 回撥獲得的。

返回

成功時返回零,失敗時返回負 errno。

void drm_connector_create_privacy_screen_properties(struct drm_connector *connector)

建立 drm 聯結器的隱私螢幕屬性。

引數

struct drm_connector *connector

要為其建立隱私螢幕屬性的聯結器

描述

此函式為聯結器建立“privacy-screen sw-state”和“privacy-screen hw-state”屬性。 它們未附加。

void drm_connector_attach_privacy_screen_properties(struct drm_connector *connector)

附加 drm 聯結器的隱私螢幕屬性。

引數

struct drm_connector *connector

要在其上附加隱私螢幕屬性的聯結器

描述

此函式將“privacy-screen sw-state”和“privacy-screen hw-state”屬性附加到聯結器。 兩者的初始狀態都設定為“Disabled”。

void drm_connector_attach_privacy_screen_provider(struct drm_connector *connector, struct drm_privacy_screen *priv)

將隱私螢幕附加到聯結器

引數

struct drm_connector *connector

要將隱私螢幕附加到的聯結器

struct drm_privacy_screen *priv

要附加的 drm_privacy_screen

描述

建立並附加標準隱私螢幕屬性,並註冊一個通用通知程式,用於在隱私螢幕狀態發生外部更改時生成 sysfs-connector-status-events。 此函式獲取傳入的 drm_privacy_screen 的所有權,並在銷燬聯結器時對其呼叫 drm_privacy_screen_put()

void drm_connector_update_privacy_screen(const struct drm_connector_state *connector_state)

更新聯結器的隱私螢幕 sw-state

引數

const struct drm_connector_state *connector_state

要更新隱私螢幕的聯結器狀態

描述

此函式在聯結器的隱私螢幕上呼叫 drm_privacy_screen_set_sw_state()

如果聯結器沒有隱私螢幕,則這是一個空操作。

void drm_connector_oob_hotplug_event(struct fwnode_handle *connector_fwnode, enum drm_connector_status status)

將帶外熱插拔事件報告給聯結器

引數

struct fwnode_handle *connector_fwnode

要在其上報告事件的 fwnode_handle

enum drm_connector_status status

熱插拔檢測邏輯狀態

描述

在某些硬體上,熱插拔事件通知可能來自顯示驅動程式/裝置外部。 例如,某些 USB Type-C 設定,其中硬體複用 DisplayPort 資料和輔助線,但不將 altmode HPD 狀態位傳遞到 GPU 的 DP HPD 引腳。

此函式可用於在透過呼叫 drm_connector_find_by_fwnode() 獲取 drm_connector 引用後報告這些帶外事件。

void drm_mode_put_tile_group(struct drm_device *dev, struct drm_tile_group *tg)

刪除對圖塊組的引用。

引數

struct drm_device *dev

DRM 裝置

struct drm_tile_group *tg

要刪除引用的圖塊組。

描述

刪除對圖塊組的引用,如果為 0,則釋放。

struct drm_tile_group *drm_mode_get_tile_group(struct drm_device *dev, const char topology[8])

獲取對現有圖塊組的引用

引數

struct drm_device *dev

DRM 裝置

const char topology[8]

每個監視器唯一的 8 位元組。

描述

使用唯一位元組獲取對現有圖塊組的引用。

返回

如果未找到,則返回圖塊組或 NULL。

struct drm_tile_group *drm_mode_create_tile_group(struct drm_device *dev, const char topology[8])

從 displayid 描述建立圖塊組

引數

struct drm_device *dev

DRM 裝置

const char topology[8]

每個監視器唯一的 8 位元組。

描述

為唯一的監視器建立圖塊組,並獲取圖塊組的唯一識別符號。

返回

新的圖塊組或 NULL。

回寫聯結器

回寫聯結器用於公開可以將 CRTC 的輸出寫入記憶體緩衝區的硬體。 它們的使用方式和其他型別的聯結器類似,但有一些重要的區別

  • 回寫聯結器不提供以視覺方式輸出給使用者的方式。

  • 僅當客戶端設定 DRM_CLIENT_CAP_WRITEBACK_CONNECTORS 時,回寫聯結器才對使用者空間可見。

  • 回寫聯結器沒有 EDID。

僅當幀緩衝區連線到 CRTC 時,才能將幀緩衝區連線到回寫聯結器。 設定幀緩衝區的 WRITEBACK_FB_ID 屬性僅適用於單個提交(請參見下文)。 當 CRTC 關閉時,不得附加幀緩衝區。

與平面不同,當用戶空間刪除回寫幀緩衝區時,DRM 不會嘗試將其從聯結器的活動使用中刪除。 這是因為沒有提供中止回寫操作的方法,並且在任何情況下,在回寫正在進行時進行新的提交都是未定義的(請參見下面的 WRITEBACK_OUT_FENCE_PTR)。 一旦當前的回寫完成,幀緩衝區將自動不再處於活動使用狀態。 由於它也已經從幀緩衝區列表中刪除,因此任何使用者空間應用程式都無法在中間期間檢索對其的引用。

回寫聯結器具有一些額外的屬性,使用者空間可以使用這些屬性來查詢和控制它們

“WRITEBACK_FB_ID”

只寫物件屬性,用於儲存 DRM_MODE_OBJECT_FB:它儲存要由回寫聯結器寫入的幀緩衝區。 此屬性類似於平面上的 FB_ID 屬性,但始終讀取為零,並且不會跨提交保留。 使用者空間每次希望填充緩衝區時都必須將此屬性設定為輸出緩衝區。

“WRITEBACK_PIXEL_FORMATS”

不可變 blob 屬性,用於儲存支援的畫素格式表。 資料是 u32 DRM_FORMAT_* fourcc 值的陣列。 使用者空間可以使用此 blob 查詢聯結器的回寫引擎支援哪些畫素格式。

“WRITEBACK_OUT_FENCE_PTR”

使用者空間可以使用此屬性為核心提供一個指標,以填充 sync_file 檔案描述符,該描述符將在回寫完成後發出訊號。 該值應為 32 位有符號整數的地址,轉換為 u64。 使用者空間應在等待此柵欄發出訊號後,再進行另一個影響任何相同 CRTC、Plane 或聯結器的提交。 否則將導致未定義的行為。 因此,強烈建議所有使用回寫聯結器的使用者空間應用程式始終檢索提交的出柵欄並適當使用它。 在使用者空間中,此屬性將始終讀取為零。

struct drm_writeback_connector

DRM 回寫聯結器

定義:

struct drm_writeback_connector {
    struct drm_connector base;
    struct drm_encoder encoder;
    struct drm_property_blob *pixel_formats_blob_ptr;
    spinlock_t job_lock;
    struct list_head job_queue;
    unsigned int fence_context;
    spinlock_t fence_lock;
    unsigned long fence_seqno;
    char timeline_name[32];
};

成員

基本

基本 drm_connector 物件

encoder

聯結器使用的內部編碼器,用於滿足 DRM 框架的需求。drm_writeback_connector 的使用者透過將 enc_funcs 引數傳遞給 drm_writeback_connector_init() 函式來控制 encoder 的行為。對於 drm_writeback_connector_init_with_encoder() 的使用者,此欄位無效,因為編碼器由其驅動程式管理。

pixel_formats_blob_ptr

用於回寫聯結器的畫素格式列表的 DRM Blob 屬性資料。另請參見 drm_writeback_connector_init()

job_lock

保護 job_queue

job_queue

儲存聯結器的回寫作業列表;最後一項是最近的。第一項可能正在等待硬體開始寫入,或者當前正在寫入。

另請參見:drm_writeback_queue_job()drm_writeback_signal_completion()

fence_context

用於柵欄操作的時間線上下文。

fence_lock

用於保護 fence_context 中柵欄的自旋鎖。

fence_seqno

Seqno 變數用作聯結器時間線上建立的 fence 的單調計數器。

timeline_name

聯結器的 fence 時間線的名稱。

struct drm_writeback_job

DRM 回寫作業

定義:

struct drm_writeback_job {
    struct drm_writeback_connector *connector;
    bool prepared;
    struct work_struct cleanup_work;
    struct list_head list_entry;
    struct drm_framebuffer *fb;
    struct dma_fence *out_fence;
    void *priv;
};

成員

connector

指向與作業關聯的回寫聯結器的後向指標

prepared

使用 drm_writeback_prepare_job() 準備作業時設定

cleanup_work

用於允許 drm_writeback_signal_completion 將幀緩衝區引用延遲到工作佇列

list_entry

回寫聯結器的 job_queue 的列表項

fb

要由回寫聯結器寫入的幀緩衝區。不要直接設定,請使用 drm_writeback_set_fb()

out_fence

一旦回寫完成,Fence 將發出訊號

priv

驅動程式私有資料

int drm_writeback_connector_init(struct drm_device *dev, struct drm_writeback_connector *wb_connector, const struct drm_connector_funcs *con_funcs, const struct drm_encoder_helper_funcs *enc_helper_funcs, const u32 *formats, int n_formats, u32 possible_crtcs)

初始化回寫聯結器及其屬性

引數

struct drm_device *dev

DRM 裝置

struct drm_writeback_connector *wb_connector

要初始化的回寫聯結器

const struct drm_connector_funcs *con_funcs

聯結器 funcs vtable

const struct drm_encoder_helper_funcs *enc_helper_funcs

內部編碼器使用的編碼器輔助函式 vtable

const u32 *formats

回寫引擎支援的畫素格式陣列

int n_formats

格式陣列的長度

u32 possible_crtcs

內部回寫編碼器的可能的 crtc

描述

如果尚未建立,則此函式將建立特定於回寫聯結器的屬性,將聯結器初始化為 DRM_MODE_CONNECTOR_WRITEBACK 型別,並正確初始化屬性值。它還將建立一個與 drm_writeback_connector 關聯的內部編碼器,並將其設定為使用 enc_helper_funcs vtable 作為編碼器輔助函式。

驅動程式應始終使用此函式而不是 drm_connector_init() 來設定回寫聯結器。

返回

成功時為 0,否則為負錯誤程式碼

int drm_writeback_connector_init_with_encoder(struct drm_device *dev, struct drm_writeback_connector *wb_connector, struct drm_encoder *enc, const struct drm_connector_funcs *con_funcs, const u32 *formats, int n_formats)

使用自定義編碼器初始化回寫聯結器

引數

struct drm_device *dev

DRM 裝置

struct drm_writeback_connector *wb_connector

要初始化的回寫聯結器

struct drm_encoder *enc

已初始化的 drm 編碼器的控制代碼

const struct drm_connector_funcs *con_funcs

聯結器 funcs vtable

const u32 *formats

回寫引擎支援的畫素格式陣列

int n_formats

格式陣列的長度

描述

如果尚未建立,則此函式將建立特定於回寫聯結器的屬性,將聯結器初始化為 DRM_MODE_CONNECTOR_WRITEBACK 型別,並正確初始化屬性值。

此函式假定在呼叫此函式之前,已經建立並初始化了 drm_writeback_connector 的編碼器。

此外,此函式還假定此 API 的呼叫者將管理分配編碼器輔助函式、possible_crtcs 和任何其他特定於編碼器的操作。

如果驅動程式想要自行管理關聯編碼器的生命週期,則應始終使用此函式而不是 drm_connector_init() 來設定回寫聯結器。

返回

成功時為 0,否則為負錯誤程式碼

int drmm_writeback_connector_init(struct drm_device *dev, struct drm_writeback_connector *wb_connector, const struct drm_connector_funcs *con_funcs, struct drm_encoder *enc, const u32 *formats, int n_formats)

使用自定義編碼器初始化回寫聯結器

引數

struct drm_device *dev

DRM 裝置

struct drm_writeback_connector *wb_connector

要初始化的回寫聯結器

const struct drm_connector_funcs *con_funcs

聯結器 funcs vtable

struct drm_encoder *enc

用於連線此回寫聯結器的編碼器

const u32 *formats

回寫引擎支援的畫素格式陣列

int n_formats

格式陣列的長度

描述

此函式初始化回寫聯結器並註冊其清理。

如果尚未建立,則此函式將建立特定於回寫聯結器的屬性,將聯結器初始化為 DRM_MODE_CONNECTOR_WRITEBACK 型別,並正確初始化屬性值。

返回

成功時為 0,否則為負錯誤程式碼

void drm_writeback_queue_job(struct drm_writeback_connector *wb_connector, struct drm_connector_state *conn_state)

排隊一個回寫作業以供稍後發出訊號

引數

struct drm_writeback_connector *wb_connector

要排隊作業的回寫聯結器

struct drm_connector_state *conn_state

包含要排隊的作業的聯結器狀態

描述

此函式將 conn_state 中包含的作業新增到回寫聯結器的 job_queue。它獲取回寫作業的所有權並將 conn_state->writeback_job 設定為 NULL,因此在此函式返回後,呼叫者不得訪問該作業。

驅動程式必須確保對於給定的回寫聯結器,作業的排隊順序與硬體完成的順序完全相同(並透過 drm_writeback_signal_completion 發出訊號)。

對於每次呼叫 drm_writeback_queue_job(),必須正好呼叫一次 drm_writeback_signal_completion()

另請參見:drm_writeback_signal_completion()

void drm_writeback_signal_completion(struct drm_writeback_connector *wb_connector, int status)

發出回寫作業完成的訊號

引數

struct drm_writeback_connector *wb_connector

其作業已完成的回寫聯結器

int status

要在回寫 out_fence 中設定的狀態程式碼(成功時為 0)

描述

驅動程式應呼叫此函式以發出先前排隊的回寫作業完成的訊號。應在硬體完成寫入後儘快呼叫它,並且可以從中斷上下文呼叫。驅動程式有責任確保對於給定的聯結器,硬體以與排隊順序相同的順序完成回寫作業。

除非驅動程式持有對幀緩衝區的引用,否則在呼叫此函式後不得訪問該幀緩衝區。

另請參見:drm_writeback_queue_job()

編碼器抽象

編碼器表示 CRTC(作為由 struct drm_crtc 表示的整體畫素管線)和聯結器(作為由 struct drm_connector 表示的通用接收器實體)之間的連線元素。編碼器從 CRTC 獲取畫素資料,並將其轉換為適合於任何連線的聯結器的格式。編碼器是暴露給使用者空間的物件,最初允許使用者空間推斷克隆和聯結器/CRTC 限制。不幸的是,幾乎所有驅動程式都弄錯了這一點,使得 uabi 幾乎毫無用處。最重要的是,暴露的限制對於今天的硬體來說太簡單了,推斷限制的推薦方法是使用 atomic IOCTL 的 DRM_MODE_ATOMIC_TEST_ONLY 標誌。

否則,編碼器根本不用於 uapi 中(來自使用者空間的任何 modeset 請求都直接將聯結器與 CRTC 連線),因此驅動程式可以隨意使用它們。Modeset 輔助庫強烈使用編碼器來促進程式碼共享。但是對於更復雜的設定,通常最好將共享程式碼移動到單獨的 drm_bridge 中。與編碼器相比,網橋的優勢還在於它們純粹是內部抽象,因為它們根本不暴露給使用者空間。

使用 drm_encoder_init() 初始化編碼器,並使用 drm_encoder_cleanup() 清理編碼器。

編碼器函式參考

struct drm_encoder_funcs

編碼器控制元件

定義:

struct drm_encoder_funcs {
    void (*reset)(struct drm_encoder *encoder);
    void (*destroy)(struct drm_encoder *encoder);
    int (*late_register)(struct drm_encoder *encoder);
    void (*early_unregister)(struct drm_encoder *encoder);
    void (*debugfs_init)(struct drm_encoder *encoder, struct dentry *root);
};

成員

重置

將編碼器硬體和軟體狀態重置為關閉。此函式不是由核心直接呼叫的,而是僅透過 drm_mode_config_reset() 呼叫的。它不是僅出於歷史原因的輔助鉤子。

destroy

清理編碼器資源。這僅在驅動程式解除安裝時透過 drm_mode_config_cleanup() 呼叫,因為編碼器無法在 DRM 中熱插拔。

late_register

此可選鉤子可用於註冊附加到編碼器的其他使用者空間介面。它在驅動程式載入序列的後期從 drm_dev_register() 呼叫。從此回撥新增的所有內容都應在 early_unregister 回撥中登出。

返回

成功時為 0,失敗時為負錯誤程式碼。

early_unregister

此可選鉤子應用於登出從 late_register 附加到編碼器的其他使用者空間介面。它從 drm_dev_unregister() 呼叫,在驅動程式解除安裝序列的早期停用使用者空間訪問,然後在資料結構被拆除之前。

debugfs_init

允許編碼器建立特定於編碼器的 debugfs 檔案。

描述

編碼器位於 CRTC 和聯結器之間。

struct drm_encoder

中央 DRM 編碼器結構

定義:

struct drm_encoder {
    struct drm_device *dev;
    struct list_head head;
    struct drm_mode_object base;
    char *name;
    int encoder_type;
    unsigned index;
    uint32_t possible_crtcs;
    uint32_t possible_clones;
    struct drm_crtc *crtc;
    struct list_head bridge_chain;
    const struct drm_encoder_funcs *funcs;
    const struct drm_encoder_helper_funcs *helper_private;
    struct dentry *debugfs_entry;
};

成員

dev

父 DRM 裝置

head

列表管理

基本

基本 KMS 物件

名稱

人類可讀的名稱,可以由驅動程式覆蓋

encoder_type

drm_mode.h 中的 DRM_MODE_ENCODER_<foo> 型別之一。到目前為止,已定義以下編碼器型別

  • 用於 VGA 和 DVI-I/DVI-A 上的模擬的 DRM_MODE_ENCODER_DAC。

  • 用於 DVI、HDMI 和(嵌入式)DisplayPort 的 DRM_MODE_ENCODER_TMDS。

  • 用於顯示面板的 DRM_MODE_ENCODER_LVDS,或者通常是具有專有並行聯結器的任何面板。

  • 用於電視輸出(複合、S-影片、分量、SCART)的 DRM_MODE_ENCODER_TVDAC。

  • 用於虛擬機器的 DRM_MODE_ENCODER_VIRTUAL 顯示器

  • 用於使用 DSI 序列匯流排連線的面板的 DRM_MODE_ENCODER_DSI。

  • 用於使用 DPI 並行匯流排連線的面板的 DRM_MODE_ENCODER_DPI。

  • 用於允許多個 DP MST 流共享一個物理編碼器的特殊偽編碼器的 DRM_MODE_ENCODER_DPMST。

索引

模式配置列表中的位置,可以用作陣列索引。它在編碼器的生命週期內是不變的。

possible_crtcs

潛在 CRTC 繫結的位掩碼,使用 drm_crtc_index() 作為位欄位的索引。驅動程式必須在呼叫 drm_dev_register() 之前,為該編碼器可以連線到的所有 drm_crtc 物件設定位。

如果驅動程式中出現錯誤,您將收到 WARN。

請注意,由於 CRTC 物件無法熱插拔,因此分配的索引是穩定的,因此在註冊所有物件之前是已知的。

possible_clones

用於克隆的潛在同級編碼器的位掩碼,使用 drm_encoder_index() 作為位欄位的索引。驅動程式必須在呼叫 drm_dev_register() 之前,為可以與此編碼器一起克隆 drm_crtc 的所有 drm_encoder 物件設定位。驅動程式也應設定表示編碼器本身的位。克隆位的設定方式應為:當兩個編碼器可以在克隆配置中使用時,它們都應設定彼此的位。

作為上述規則的例外,如果驅動程式未實現任何克隆,則可以將其 possible_clones 設定為 0。核心將透過設定編碼器本身的位來自動修復此問題。

如果驅動程式中出現錯誤,您將收到 WARN。

請注意,由於編碼器物件無法熱插拔,因此分配的索引是穩定的,因此在註冊所有物件之前是已知的。

crtc

當前繫結的 CRTC,僅對非原子驅動程式真正有意義。原子驅動程式應改為檢查 drm_connector_state.crtc

bridge_chain

附加到此編碼器的網橋。驅動程式不得直接訪問此欄位。

funcs

控制函式,對於簡單的託管編碼器可以為 NULL

helper_private

中間層私有資料

debugfs_entry

此 CRTC 的 Debugfs 目錄。

描述

CRTC 將畫素驅動到編碼器,編碼器將其轉換為適合於給定聯結器或一組聯結器的訊號。

drmm_encoder_alloc

drmm_encoder_alloc (dev, type, member, funcs, encoder_type, name, ...)

分配並初始化編碼器

引數

dev

drm 裝置

type

包含 struct drm_encoder 的結構體的型別

member

typedrm_encoder 的名稱

funcs

此編碼器的回撥(可選)

encoder_type

使用者可見的編碼器型別

名稱

編碼器名稱的 printf 樣式格式字串,如果為 NULL,則使用預設名稱

...

可變引數

描述

分配並初始化編碼器。編碼器應作為驅動程式編碼器物件的一部分進行子類化。清理透過使用 drmm_add_action() 註冊 drm_encoder_cleanup() 自動處理。

drm_encoder_funcs.destroy 鉤子必須為 NULL。

返回

指向新編碼器的指標,如果失敗,則為 ERR_PTR。

drmm_plain_encoder_alloc

drmm_plain_encoder_alloc (dev, funcs, encoder_type, name, ...)

分配並初始化編碼器

引數

dev

drm 裝置

funcs

此編碼器的回撥(可選)

encoder_type

使用者可見的編碼器型別

名稱

編碼器名稱的 printf 樣式格式字串,如果為 NULL,則使用預設名稱

...

可變引數

描述

這是 drmm_encoder_alloc() 的簡化版本,它只分配並返回一個 struct drm_encoder 例項,沒有子類化。

返回

指向新的 drm_encoder 結構的指標,如果失敗則返回 ERR_PTR。

unsigned int drm_encoder_index(const struct drm_encoder *encoder)

查詢已註冊編碼器的索引

引數

const struct drm_encoder *encoder

要查詢索引的編碼器

描述

給定一個已註冊的編碼器,返回該編碼器在 DRM 裝置編碼器列表中的索引。

u32 drm_encoder_mask(const struct drm_encoder *encoder)

查詢已註冊編碼器的掩碼

引數

const struct drm_encoder *encoder

要查詢掩碼的編碼器

描述

給定一個已註冊的編碼器,返回該編碼器在 encoder 的 possible_clones 欄位中的掩碼位。

bool drm_encoder_crtc_ok(struct drm_encoder *encoder, struct drm_crtc *crtc)

給定的 crtc 能否驅動給定的編碼器?

引數

struct drm_encoder *encoder

要測試的編碼器

struct drm_crtc *crtc

要測試的 crtc

描述

如果 **encoder** 不能被 **crtc** 驅動,則返回 false,否則返回 true。

struct drm_encoder *drm_encoder_find(struct drm_device *dev, struct drm_file *file_priv, uint32_t id)

查詢一個 drm_encoder

引數

struct drm_device *dev

DRM 裝置

struct drm_file *file_priv

用於檢查租賃的 DRM 檔案。

uint32_t id

編碼器 id

描述

返回具有 **id** 的編碼器,如果不存在則返回 NULL。 圍繞 drm_mode_object_find() 的簡單包裝器。

drm_for_each_encoder_mask

drm_for_each_encoder_mask (encoder, dev, encoder_mask)

迭代由位掩碼指定的編碼器

引數

encoder

循環遊標

dev

DRM 裝置

encoder_mask

編碼器索引的位掩碼

描述

迭代由位掩碼指定的所有編碼器。

drm_for_each_encoder

drm_for_each_encoder (encoder, dev)

迭代所有編碼器

引數

encoder

循環遊標

dev

DRM 裝置

描述

迭代 **dev** 的所有編碼器。

int drm_encoder_init(struct drm_device *dev, struct drm_encoder *encoder, const struct drm_encoder_funcs *funcs, int encoder_type, const char *name, ...)

初始化一個預先分配的編碼器

引數

struct drm_device *dev

drm 裝置

struct drm_encoder *encoder

要初始化的編碼器

const struct drm_encoder_funcs *funcs

此編碼器的回撥

int encoder_type

使用者可見的編碼器型別

const char *name

編碼器名稱的 printf 樣式格式字串,如果為 NULL,則使用預設名稱

...

可變引數

描述

初始化一個預先分配的編碼器。 編碼器應作為驅動程式編碼器物件的一部分進行子類化。 在驅動程式解除安裝時,驅動程式的 drm_encoder_funcs.destroy 鉤子應呼叫 drm_encoder_cleanup()kfree() 編碼器結構。 編碼器結構不應使用 devm_kzalloc() 分配。

注意

考慮使用 drmm_encoder_alloc()drmm_encoder_init() 而不是 drm_encoder_init(),以便讓 DRM 管理的資源基礎結構處理清理和釋放。

返回

成功時為零,失敗時為錯誤程式碼。

void drm_encoder_cleanup(struct drm_encoder *encoder)

清理已初始化的編碼器

引數

struct drm_encoder *encoder

要清理的編碼器

描述

清理編碼器,但不釋放物件。

int drmm_encoder_init(struct drm_device *dev, struct drm_encoder *encoder, const struct drm_encoder_funcs *funcs, int encoder_type, const char *name, ...)

初始化一個預先分配的編碼器

引數

struct drm_device *dev

drm 裝置

struct drm_encoder *encoder

要初始化的編碼器

const struct drm_encoder_funcs *funcs

此編碼器的回撥(可選)

int encoder_type

使用者可見的編碼器型別

const char *name

編碼器名稱的 printf 樣式格式字串,如果為 NULL,則使用預設名稱

...

可變引數

描述

初始化一個預先分配的編碼器。 編碼器應作為驅動程式編碼器物件的一部分進行子類化。 透過使用 drmm_add_action() 註冊 drm_encoder_cleanup(),可自動處理清理工作。 編碼器結構應使用 drmm_kzalloc() 進行分配。

drm_encoder_funcs.destroy 鉤子必須為 NULL。

返回

成功時為零,失敗時為錯誤程式碼。

KMS 鎖定

隨著 KMS 轉向更細粒度的鎖定和原子 ioctl,使用者空間可以間接控制鎖定順序,因此有必要使用 ww_mutex 和 acquire-contexts 來避免死鎖。 但是由於鎖定在驅動程式程式碼中分佈得更廣泛,因此我們希望從 acquire-ctx 中獲得一些額外的實用程式/跟蹤。 這由 struct drm_modeset_lockstruct drm_modeset_acquire_ctx 提供。

有關 ww_mutex 的基本原理,請參見:Wound/Wait 防死鎖互斥鎖設計

基本使用模式是

drm_modeset_acquire_init(ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE)
retry:
foreach (lock in random_ordered_set_of_locks) {
    ret = drm_modeset_lock(lock, ctx)
    if (ret == -EDEADLK) {
        ret = drm_modeset_backoff(ctx);
        if (!ret)
            goto retry;
    }
    if (ret)
        goto out;
}
... do stuff ...
out:
drm_modeset_drop_locks(ctx);
drm_modeset_acquire_fini(ctx);

為方便起見,當需要透過 drm_modeset_lock_all_ctx() 獲取所有 modeset 鎖時,此控制流在 DRM_MODESET_LOCK_ALL_BEGIN()DRM_MODESET_LOCK_ALL_END() 中實現。

如果只需要單個 modeset 鎖,則不需要 struct drm_modeset_acquire_ctx,並且可以透過在 drm_modeset_lock() 呼叫中傳遞 NULL 而不是 ctx 或呼叫 drm_modeset_lock_single_interruptible() 來簡化鎖定。 要在之後解鎖,請呼叫 drm_modeset_unlock()

除了使用 ww_mutex 的這些每個物件鎖之外,還有一個總體的 drm_mode_config.mutex,用於保護其他所有內容。 主要這意味著聯結器的探測狀態,並防止熱插拔新增/刪除聯結器。

最後,還有一堆專用鎖來保護 drm 核心內部列表和查詢資料結構。

struct drm_modeset_acquire_ctx

鎖定上下文(請參閱 ww_acquire_ctx)

定義:

struct drm_modeset_acquire_ctx {
    struct ww_acquire_ctx ww_ctx;
    struct drm_modeset_lock *contended;
    depot_stack_handle_t stack_depot;
    struct list_head locked;
    bool trylock_only;
    bool interruptible;
};

成員

ww_ctx

基本獲取 ctx

contended

內部用於 -EDEADLK 處理

stack_depot

內部用於爭用除錯

locked

持有的鎖的列表

trylock_only

原子上下文/panic 通知程式中使用的 tryLock 模式

interruptible

是否應使用可中斷鎖定。

描述

爭用一組鎖的每個執行緒都必須使用一個 acquire ctx。 並且如果任何鎖 fxn 返回 -EDEADLK,它必須退避並重試。

struct drm_modeset_lock

用於鎖定 modeset 資源。

定義:

struct drm_modeset_lock {
    struct ww_mutex mutex;
    struct list_head head;
};

成員

mutex

資源鎖定

head

用於在作為原子更新的一部分時,保持其在 drm_atomi_state.locked 列表中的位置

描述

用於鎖定 CRTC 和其他 modeset 資源。

void drm_modeset_lock_fini(struct drm_modeset_lock *lock)

清理鎖

引數

struct drm_modeset_lock *lock

要清理的鎖

bool drm_modeset_is_locked(struct drm_modeset_lock *lock)

等同於 mutex_is_locked()

引數

struct drm_modeset_lock *lock

要檢查的鎖

void drm_modeset_lock_assert_held(struct drm_modeset_lock *lock)

等同於 lockdep_assert_held()

引數

struct drm_modeset_lock *lock

要檢查的鎖

DRM_MODESET_LOCK_ALL_BEGIN

DRM_MODESET_LOCK_ALL_BEGIN (dev, ctx, flags, ret)

用於獲取 modeset 鎖的幫助程式

引數

dev

drm 裝置

ctx

本地 modeset 獲取上下文,將被取消引用

標誌

要傳遞給 drm_modeset_acquire_init() 的 DRM_MODESET_ACQUIRE_* 標誌

ret

用於跟蹤錯誤狀態的本地 ret/err/etc 變數

描述

使用這些宏可簡化使用本地上下文獲取所有 modeset 鎖。 這樣做的好處是減少了樣板程式碼,而且還正確地檢查了返回值(如果適用)。

在 BEGIN 和 END 之間執行的任何程式碼都將持有 modeset 鎖。

這必須與 DRM_MODESET_LOCK_ALL_END() 配對。 我們將在死鎖和錯誤條件下的標籤之間來回跳轉。

驅動程式可以獲取額外的 modeset 鎖。 如果任何鎖獲取失敗,則控制流需要跳轉到 DRM_MODESET_LOCK_ALL_END(),其中 **ret** 引數包含 drm_modeset_lock() 的返回值。

返回

緊接在 DRM_MODESET_LOCK_ALL_BEGIN() 之後的 ret 的唯一可能值為 0,因此無需進行錯誤檢查

DRM_MODESET_LOCK_ALL_END

DRM_MODESET_LOCK_ALL_END (dev, ctx, ret)

用於釋放和清理 modeset 鎖的幫助程式

引數

dev

drm 裝置

ctx

本地 modeset 獲取上下文,將被取消引用

ret

用於跟蹤錯誤狀態的本地 ret/err/etc 變數

描述

DRM_MODESET_LOCK_ALL_BEGIN() 的另一面。 如果 ret 為 -EDEADLK,它將彈回 BEGIN。

重要的是,BEGIN 和 END 使用相同的 ret 變數,以便正確處理死鎖條件。

返回

除非在輸入時為 -EDEADLK,否則 ret 將保持不變。 這意味著如果成功獲取鎖,ret 將是程式碼設定的任何值。 如果獲取或退避時出現死鎖或其他失敗,則 ret 將設定為該失敗。 在這兩種情況下,都不會執行 BEGIN/END 之間的程式碼,因此失敗將反映無法獲取鎖。

void drm_modeset_lock_all(struct drm_device *dev)

獲取所有 modeset 鎖

引數

struct drm_device *dev

DRM 裝置

描述

此函式獲取所有模式設定鎖,適用於尚未實現更細粒度方案的情況。必須透過呼叫 drm_modeset_unlock_all() 函式來釋放鎖。

此函式已棄用。它分配一個鎖獲取上下文並將其儲存在 drm_device.mode_config 中。這有助於轉換現有程式碼,因為它消除了手動處理獲取上下文的需要,但它也很脆弱,因為上下文是全域性的,必須注意不要巢狀呼叫。新程式碼應使用 drm_modeset_lock_all_ctx() 函式並顯式傳遞上下文。

void drm_modeset_unlock_all(struct drm_device *dev)

釋放所有模式設定鎖

引數

struct drm_device *dev

DRM 裝置

描述

此函式釋放之前呼叫 drm_modeset_lock_all() 函式所獲取的所有模式設定鎖。

此函式已棄用。它使用儲存在 drm_device.mode_config 中的鎖獲取上下文。這有助於轉換現有程式碼,因為它消除了手動處理獲取上下文的需要,但它也很脆弱,因為上下文是全域性的,必須注意不要巢狀呼叫。新程式碼應將獲取上下文直接傳遞給 drm_modeset_drop_locks() 函式。

void drm_warn_on_modeset_not_all_locked(struct drm_device *dev)

檢查是否所有模式設定鎖都已鎖定

引數

struct drm_device *dev

裝置

描述

可用作除錯斷言。

void drm_modeset_acquire_init(struct drm_modeset_acquire_ctx *ctx, uint32_t flags)

初始化獲取上下文

引數

struct drm_modeset_acquire_ctx *ctx

獲取上下文

uint32_t flags

0 或 DRM_MODESET_ACQUIRE_INTERRUPTIBLE

描述

當將 DRM_MODESET_ACQUIRE_INTERRUPTIBLE 傳遞給 flags 時,所有對 drm_modeset_lock() 的呼叫都將執行可中斷等待。

void drm_modeset_acquire_fini(struct drm_modeset_acquire_ctx *ctx)

清理獲取上下文

引數

struct drm_modeset_acquire_ctx *ctx

獲取上下文

void drm_modeset_drop_locks(struct drm_modeset_acquire_ctx *ctx)

釋放所有鎖

引數

struct drm_modeset_acquire_ctx *ctx

獲取上下文

描述

釋放當前針對此獲取上下文持有的所有鎖。

int drm_modeset_backoff(struct drm_modeset_acquire_ctx *ctx)

死鎖避免退避

引數

struct drm_modeset_acquire_ctx *ctx

獲取上下文

描述

如果檢測到死鎖(即 drm_modeset_lock() 返回 -EDEADLK),則必須呼叫此函式以釋放當前持有的所有鎖並阻塞,直到爭用的鎖變為可用。

此函式在成功時返回 0,如果此上下文使用 DRM_MODESET_ACQUIRE_INTERRUPTIBLE 初始化且等待已中斷,則返回 -ERESTARTSYS。

void drm_modeset_lock_init(struct drm_modeset_lock *lock)

初始化鎖

引數

struct drm_modeset_lock *lock

要初始化的鎖

int drm_modeset_lock(struct drm_modeset_lock *lock, struct drm_modeset_acquire_ctx *ctx)

獲取模式設定鎖

引數

struct drm_modeset_lock *lock

要獲取的鎖

struct drm_modeset_acquire_ctx *ctx

獲取上下文

描述

如果 ctx 不為 NULL,則使用其 ww 獲取上下文,並且該鎖將由上下文跟蹤,並且可以透過呼叫 drm_modeset_drop_locks() 來釋放。如果返回 -EDEADLK,則表示檢測到死鎖情況,並且在沒有首先呼叫 drm_modeset_backoff() 的情況下嘗試獲取更多鎖是錯誤的。

如果 ctx 不為 NULL 且使用 DRM_MODESET_ACQUIRE_INTERRUPTIBLE 初始化,則此函式將在中斷時失敗並返回 -ERESTARTSYS。

如果 ctx 為 NULL,則函式呼叫行為類似於正常的、不可中斷的非巢狀 mutex_lock() 呼叫。

int drm_modeset_lock_single_interruptible(struct drm_modeset_lock *lock)

獲取單個模式設定鎖

引數

struct drm_modeset_lock *lock

要獲取的鎖

描述

此函式的作用類似於具有 NULL 上下文的 drm_modeset_lock(),但執行可中斷等待。

此函式在成功時返回 0,在中斷時返回 -ERESTARTSYS。

void drm_modeset_unlock(struct drm_modeset_lock *lock)

釋放模式設定鎖

引數

struct drm_modeset_lock *lock

要釋放的鎖

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

獲取所有 modeset 鎖

引數

struct drm_device *dev

DRM 裝置

struct drm_modeset_acquire_ctx *ctx

鎖獲取上下文

描述

此函式獲取所有模式設定鎖,適用於尚未實現更細粒度方案的情況。

drm_modeset_lock_all() 不同,它不獲取 drm_mode_config.mutex,因為模式設定狀態更改不需要該鎖。也需要獲取該鎖的呼叫者需要在獲取上下文 ctx 之外執行此操作。

使用此函式獲取的鎖應透過在 ctx 上呼叫 drm_modeset_drop_locks() 函式來釋放。

另請參見:DRM_MODESET_LOCK_ALL_BEGIN()DRM_MODESET_LOCK_ALL_END()

返回

成功時返回 0,失敗時返回負錯誤程式碼。

KMS 屬性

文件的此部分主要針對使用者空間開發人員。有關驅動程式 API,請參見其他部分。

要求

KMS 驅動程式可能需要新增額外的屬性以支援新功能。驅動程式中引入的每個新屬性除了上面提到的屬性外,還需要滿足一些要求

  • 它必須是標準化的,並記錄

    • 完整的、準確的名稱字串;

    • 如果屬性是列舉,則所有有效的名稱字串;

    • 接受哪些值,以及這些值的含義;

    • 屬性的作用以及如何使用它;

    • 屬性如何與其他現有屬性互動。

  • 它必須在核心程式碼中提供一個通用助手,以便在它附加到的物件上註冊該屬性。

  • 其內容必須由核心解碼,並在物件的關聯狀態結構中提供。這包括驅動程式可能想要預計算的任何內容,例如平面的 struct drm_clip_rect。

  • 其初始狀態必須與引入屬性之前的行為匹配。這可能是與硬體執行的操作相匹配的固定值,或者可能是從韌體在啟動期間將系統留在的狀態繼承而來的。

  • 在合理的情況下,必須提交 IGT 測試。

由於歷史原因,存在非標準的、特定於驅動程式的屬性。如果 KMS 驅動程式想要新增對其中一個屬性的支援,則儘可能適用新屬性的要求。此外,記錄的行為必須與現有屬性的實際語義相匹配,以確保相容性。首次新增該屬性的驅動程式的開發人員應協助完成這些任務,並且必須確認(ACK)記錄的行為(如果可能)。

屬性型別和 Blob 屬性支援

drm_property 表示的屬性用於擴充套件暴露給使用者空間的模式設定介面。對於原子模式設定 IOCTL,屬性甚至是將有關所需的新模式設定配置的元資料從使用者空間傳輸到核心的唯一方法。屬性具有明確定義的值範圍,該範圍由 drm 核心強制執行。有關不同屬性型別和範圍的概述,請參見 struct drm_property 的 flags 成員的文件。

屬性不直接儲存當前值,而是需要透過使用 drm_object_attach_property() 將它們附加到 drm_mode_object 來例項化。

屬性值只有 64 位。為了支援更大的資料堆(例如 gamma 表、顏色校正矩陣或大型結構),屬性可以指向具有該附加資料的 drm_property_blob

屬性由其符號名稱定義,使用者空間必須維護從這些名稱到原子 IOCTL 和 get/set 屬性 IOCTL 中使用的屬性 ID 的每個物件的對映。

struct drm_property_enum

列舉的符號值

定義:

struct drm_property_enum {
    uint64_t value;
    struct list_head head;
    char name[DRM_PROP_NAME_LEN];
};

成員

此列舉條目的數字屬性值

如果屬性的型別為 DRM_MODE_PROP_BITMASK,則 value 儲存一個位移,而不是一個位掩碼。換句話說,如果屬性的值中設定了位編號 value,則啟用列舉條目。此列舉條目的位掩碼為 1 << value

head

列舉值列表,連結到 drm_property.enum_list

名稱

列舉的符號名稱

描述

對於列舉和位掩碼屬性,此結構儲存每個值的符號解碼。例如,這用於旋轉屬性。

struct drm_property

模式設定物件屬性

定義:

struct drm_property {
    struct list_head head;
    struct drm_mode_object base;
    uint32_t flags;
    char name[DRM_PROP_NAME_LEN];
    uint32_t num_values;
    uint64_t *values;
    struct drm_device *dev;
    struct list_head enum_list;
};

成員

head

每個裝置的屬性列表,用於清理。

基本

基本 KMS 物件

標誌

屬性標誌和型別。屬性需要是以下型別之一

DRM_MODE_PROP_RANGE

範圍屬性報告其最小和最大允許的無符號值。KMS 核心驗證應用程式設定的值是否在該範圍內。範圍是無符號的。範圍屬性使用 drm_property_create_range() 建立。

DRM_MODE_PROP_SIGNED_RANGE

範圍屬性報告其最小和最大允許的無符號值。KMS 核心驗證應用程式設定的值是否在該範圍內。範圍是有符號的。範圍屬性使用 drm_property_create_signed_range() 建立。

DRM_MODE_PROP_ENUM

列舉屬性採用一個數字值,該值範圍從 0 到由屬性定義的列舉值的數量減 1,並將一個自由格式的字串名稱與每個值關聯。應用程式可以檢索定義的鍵值對列表,並使用數值來獲取和設定屬性例項值。列舉屬性使用 drm_property_create_enum() 建立。

DRM_MODE_PROP_BITMASK

位掩碼屬性是列舉屬性,它還會將所有列舉值限制在 0..63 範圍內。位掩碼屬性例項值組合由屬性定義的一個或多個列舉位。位掩碼屬性使用 drm_property_create_bitmask() 建立。

DRM_MODE_PROP_OBJECT

物件屬性用於連結模式設定物件。這廣泛用於原子支援中,透過將 drm_framebuffer 連結到 drm_plane、將 drm_plane 連結到 drm_crtc 以及將 drm_connector 連結到 drm_crtc 來建立顯示管道。物件屬性只能連結到特定型別的 drm_mode_object,此限制由核心強制執行。物件屬性使用 drm_property_create_object() 建立。

物件屬性的工作方式類似於 blob 屬性,但方式更通用。它們僅限於原子驅動程式,並且必須設定 DRM_MODE_PROP_ATOMIC 標誌。

DRM_MODE_PROP_BLOB

Blob 屬性儲存沒有任何格式限制的二進位制 blob。二進位制 blob 建立為 KMS 獨立物件,blob 屬性例項值儲存其關聯的 blob 物件的 ID。Blob 屬性透過使用 DRM_MODE_PROP_BLOB 作為型別呼叫 drm_property_create() 建立。

用於包含 blob 資料的實際 blob 物件使用 drm_property_create_blob() 建立,或透過相應的 IOCTL 建立。

除了只接受 blob 物件的內建限制外,blob 屬性的工作方式與物件屬性完全相同。blob 屬性存在的唯一原因是與現有使用者空間的向後相容性。

此外,屬性可以具有以下標誌的任意組合

DRM_MODE_PROP_ATOMIC

為編碼原子模式設定狀態的屬性設定。此類屬性不向舊版使用者空間公開。

DRM_MODE_PROP_IMMUTABLE

為使用者空間無法更改其值的屬性設定。允許核心更新這些屬性的值。這通常用於向用戶空間公開探測狀態,例如 EDID 或 DP MST sink 上的聯結器路徑屬性。核心可以透過呼叫 drm_object_property_set_value() 來更新不可變屬性的值。

名稱

屬性的符號名稱

num_values

values 陣列的大小。

values

具有屬性限制和值的陣列。這些限制的解釋取決於 flags 的型別。

dev

DRM 裝置

enum_list

drm_prop_enum_list 結構的列表,其中包含列舉和位掩碼值的符號名稱。

描述

此結構表示一個模式集物件屬性。它將屬性的名稱與允許的值集合結合在一起。這意味著當驅動程式想要在不同的物件上使用具有相同名稱的屬性,但具有不同的值範圍時,它必須為每個物件建立一個屬性。一個例子是drm_plane的旋轉,例如,當主平面不能旋轉時。但是,如果名稱和值範圍都匹配,則可以為同一物件多次例項化相同的屬性結構。使用者空間必須能夠處理這種情況,並且不能假設相同的符號屬性在所有模式集物件上都具有相同的模式集物件 ID。

屬性由特殊的函式建立,詳細說明在 flags 結構成員中。

要實際公開一個屬性,必須使用drm_object_attach_property()將其附加到每個物件。目前,屬性只能附加到drm_connectordrm_crtcdrm_plane

屬性也被用作原子 IOCTL 的通用元資料傳輸。在傳統的模式集 IOCTL 中直接在結構中設定的所有內容(例如平面源或目標視窗,或例如與 CRTC 的連結)都作為設定了 DRM_MODE_PROP_ATOMIC 標誌的屬性公開。

struct drm_property_blob

drm_property的 Blob 資料

定義:

struct drm_property_blob {
    struct drm_mode_object base;
    struct drm_device *dev;
    struct list_head head_global;
    struct list_head head_file;
    size_t length;
    void *data;
};

成員

基本

基本 KMS 物件

dev

DRM 裝置

head_global

drm_mode_config.property_blob_list中的全域性 blob 列表上的條目。

head_file

drm_file.blobs列表中的每個檔案的 blob 列表上的條目。

length

blob 的大小(以位元組為單位),在物件的整個生命週期內是不變的

data

實際資料,嵌入在此結構的末尾

描述

Blob 用於儲存比drm_property可用的 64 位更大的值。

Blob 使用drm_property_blob_get()drm_property_blob_put()進行引用計數。它們使用drm_property_create_blob()建立。

bool drm_property_type_is(struct drm_property *property, uint32_t type)

檢查屬性的型別

引數

struct drm_property *property

要檢查的屬性

uint32_t type

要比較的屬性型別

描述

這是一個輔助函式,因為屬性型別的 uapi 編碼由於歷史原因有點特殊。

struct drm_property *drm_property_find(struct drm_device *dev, struct drm_file *file_priv, uint32_t id)

查詢屬性物件

引數

struct drm_device *dev

DRM 裝置

struct drm_file *file_priv

用於檢查租賃的 DRM 檔案。

uint32_t id

屬性物件 ID

描述

此函式查詢由 ID 指定的屬性物件並返回它。

struct drm_property *drm_property_create(struct drm_device *dev, u32 flags, const char *name, int num_values)

建立一個新的屬性型別

引數

struct drm_device *dev

drm 裝置

u32 flags

指定屬性型別的標誌

const char *name

屬性的名稱

int num_values

預定義值的數量

描述

這將建立一個新的通用 drm 屬性,然後可以使用drm_object_attach_property()將其附加到 drm 物件。返回的屬性物件必須使用drm_property_destroy()釋放,這在呼叫drm_mode_config_cleanup()時自動完成。

返回

成功時指向新建立的屬性的指標,失敗時為 NULL。

struct drm_property *drm_property_create_enum(struct drm_device *dev, u32 flags, const char *name, const struct drm_prop_enum_list *props, int num_values)

建立一個新的列舉屬性型別

引數

struct drm_device *dev

drm 裝置

u32 flags

指定屬性型別的標誌

const char *name

屬性的名稱

const struct drm_prop_enum_list *props

帶有屬性值的列舉列表

int num_values

預定義值的數量

描述

這將建立一個新的通用 drm 屬性,然後可以使用drm_object_attach_property()將其附加到 drm 物件。返回的屬性物件必須使用drm_property_destroy()釋放,這在呼叫drm_mode_config_cleanup()時自動完成。

使用者空間只允許為列舉屬性設定一個預定義的值。

返回

成功時指向新建立的屬性的指標,失敗時為 NULL。

struct drm_property *drm_property_create_bitmask(struct drm_device *dev, u32 flags, const char *name, const struct drm_prop_enum_list *props, int num_props, uint64_t supported_bits)

建立一個新的位掩碼屬性型別

引數

struct drm_device *dev

drm 裝置

u32 flags

指定屬性型別的標誌

const char *name

屬性的名稱

const struct drm_prop_enum_list *props

帶有屬性位標誌的列舉列表

int num_props

props 陣列的大小

uint64_t supported_bits

所有支援的列舉值的位掩碼

描述

這將建立一個新的位掩碼 drm 屬性,然後可以使用drm_object_attach_property()將其附加到 drm 物件。返回的屬性物件必須使用drm_property_destroy()釋放,這在呼叫drm_mode_config_cleanup()時自動完成。

與普通列舉屬性相比,使用者空間允許設定預定義的屬性位標誌值的任何或在一起的組合

返回

成功時指向新建立的屬性的指標,失敗時為 NULL。

struct drm_property *drm_property_create_range(struct drm_device *dev, u32 flags, const char *name, uint64_t min, uint64_t max)

建立一個新的無符號範圍屬性型別

引數

struct drm_device *dev

drm 裝置

u32 flags

指定屬性型別的標誌

const char *name

屬性的名稱

uint64_t min

屬性的最小值

uint64_t max

屬性的最大值

描述

這將建立一個新的通用 drm 屬性,然後可以使用drm_object_attach_property()將其附加到 drm 物件。返回的屬性物件必須使用drm_property_destroy()釋放,這在呼叫drm_mode_config_cleanup()時自動完成。

使用者空間允許設定 (min, max) 範圍內的任何無符號整數值,包括端點值。

返回

成功時指向新建立的屬性的指標,失敗時為 NULL。

struct drm_property *drm_property_create_signed_range(struct drm_device *dev, u32 flags, const char *name, int64_t min, int64_t max)

建立一個新的有符號範圍屬性型別

引數

struct drm_device *dev

drm 裝置

u32 flags

指定屬性型別的標誌

const char *name

屬性的名稱

int64_t min

屬性的最小值

int64_t max

屬性的最大值

描述

這將建立一個新的通用 drm 屬性,然後可以使用drm_object_attach_property()將其附加到 drm 物件。返回的屬性物件必須使用drm_property_destroy()釋放,這在呼叫drm_mode_config_cleanup()時自動完成。

使用者空間允許設定 (min, max) 範圍內的任何有符號整數值,包括端點值。

返回

成功時指向新建立的屬性的指標,失敗時為 NULL。

struct drm_property *drm_property_create_object(struct drm_device *dev, u32 flags, const char *name, uint32_t type)

建立一個新的物件屬性型別

引數

struct drm_device *dev

drm 裝置

u32 flags

指定屬性型別的標誌

const char *name

屬性的名稱

uint32_t type

來自 DRM_MODE_OBJECT_* 定義的物件型別

描述

這將建立一個新的通用 drm 屬性,然後可以使用drm_object_attach_property()將其附加到 drm 物件。返回的屬性物件必須使用drm_property_destroy()釋放,這在呼叫drm_mode_config_cleanup()時自動完成。

使用者空間只允許將其設定為給定 type 的任何屬性值。僅對強制執行的原子屬性有用。

返回

成功時指向新建立的屬性的指標,失敗時為 NULL。

struct drm_property *drm_property_create_bool(struct drm_device *dev, u32 flags, const char *name)

建立一個新的布林屬性型別

引數

struct drm_device *dev

drm 裝置

u32 flags

指定屬性型別的標誌

const char *name

屬性的名稱

描述

這將建立一個新的通用 drm 屬性,然後可以使用drm_object_attach_property()將其附加到 drm 物件。返回的屬性物件必須使用drm_property_destroy()釋放,這在呼叫drm_mode_config_cleanup()時自動完成。

這是作為只有 {0, 1} 作為有效值的範圍屬性實現的。

返回

成功時指向新建立的屬性的指標,失敗時為 NULL。

int drm_property_add_enum(struct drm_property *property, uint64_t value, const char *name)

向列舉屬性新增一個可能的值

引數

struct drm_property *property

要更改的列舉屬性

uint64_t value

新列舉的值

const char *name

新列舉的符號名稱

描述

此函式向屬性新增列舉。

它的使用已被棄用,驅動程式應該使用更具體的輔助函式來直接建立帶有所有已附加列舉的屬性。

返回

成功時為零,失敗時為錯誤程式碼。

void drm_property_destroy(struct drm_device *dev, struct drm_property *property)

銷燬一個 drm 屬性

引數

struct drm_device *dev

drm 裝置

struct drm_property *property

要銷燬的屬性

描述

此函式釋放一個屬性,包括任何附加的資源,如列舉值。

struct drm_property_blob *drm_property_create_blob(struct drm_device *dev, size_t length, const void *data)

建立新的 blob 屬性

引數

struct drm_device *dev

要為其建立屬性的 DRM 裝置

size_t length

要為 blob 資料分配的長度

const void *data

如果指定,將資料複製到 blob 中

描述

為指定的 DRM 裝置建立一個新的 blob 屬性,可以選擇複製資料。請注意,blob 屬性應該是不可變的,因此資料必須在 blob 用作任何屬性的值之前填充。

返回

成功時,具有單個引用計數的新 blob 屬性,失敗時為 ERR_PTR 值。

void drm_property_blob_put(struct drm_property_blob *blob)

釋放 blob 屬性引用

引數

struct drm_property_blob *blob

DRM blob 屬性

描述

釋放對 blob 屬性的引用。可能會釋放物件。

struct drm_property_blob *drm_property_blob_get(struct drm_property_blob *blob)

獲取 blob 屬性引用

引數

struct drm_property_blob *blob

DRM blob 屬性

描述

獲取現有 blob 屬性的引用。返回 blob,允許將其用作賦值的簡寫。

struct drm_property_blob *drm_property_lookup_blob(struct drm_device *dev, uint32_t id)

查詢 blob 屬性並獲取引用

引數

struct drm_device *dev

drm 裝置

uint32_t id

blob 屬性的 ID

描述

如果成功,則會獲取對 blob 屬性的額外引用。呼叫者需要確保最終再次取消引用返回的屬性,使用 drm_property_blob_put()

返回

失敗時為 NULL,成功時為指向 blob 的指標。

int drm_property_replace_global_blob(struct drm_device *dev, struct drm_property_blob **replace, size_t length, const void *data, struct drm_mode_object *obj_holds_id, struct drm_property *prop_holds_id)

替換現有 blob 屬性

引數

struct drm_device *dev

drm 裝置

struct drm_property_blob **replace

要替換的 blob 屬性指標的位置

size_t length

新 blob 的資料長度,如果無資料則為 0

const void *data

新 blob 的內容,如果無資料則為 NULL

struct drm_mode_object *obj_holds_id

可選物件,用於屬性儲存 blob ID

struct drm_property *prop_holds_id

可選屬性,用於儲存 blob ID 返回 成功時為 0,失敗時返回錯誤

描述

此函式將替換 blob 列表中的全域性屬性,可以選擇更新儲存該屬性 ID 的屬性。

如果 length 為 0 或 data 為 NULL,則不會建立新的 blob,並且儲存屬性(如果指定)將設定為 0。

假定對 replace 指標的訪問受到呼叫者的保護,例如,透過持有其父物件的相應模式設定物件鎖。

例如,drm_connector 具有一個“PATH”屬性,該屬性包含具有 MST 路徑資訊的 blob 屬性的 ID。使用 replace 指向聯結器的 path_blob_ptr、為新路徑資訊設定的 length 和 data、obj_holds_id 設定為聯結器的基本物件以及 prop_holds_id 設定為路徑屬性名稱呼叫此函式將執行完全原子的更新。對 path_blob_ptr 的訪問受到呼叫者持有聯結器上的鎖的保護。

bool drm_property_replace_blob(struct drm_property_blob **blob, struct drm_property_blob *new_blob)

替換 blob 屬性

引數

struct drm_property_blob **blob

指向要替換的成員 blob 的指標

struct drm_property_blob *new_blob

用於替換的新 blob

返回

如果 blob 實際上已被替換,則為 true。

int drm_property_replace_blob_from_id(struct drm_device *dev, struct drm_property_blob **blob, uint64_t blob_id, ssize_t expected_size, ssize_t expected_elem_size, bool *replaced)

替換 blob 屬性並獲取引用

引數

struct drm_device *dev

DRM 裝置

struct drm_property_blob **blob

指向要替換的成員 blob 的指標

uint64_t blob_id

用於替換的新 blob 的 ID

ssize_t expected_size

blob 屬性的預期大小

ssize_t expected_elem_size

blob 屬性中元素的預期大小

bool *replaced

如果 blob 實際上已被替換

描述

從 ID 查詢新 blob,獲取其引用,檢查 blob 及其元素的預期大小,然後用新 blob 替換舊 blob。告知替換操作是否成功。

返回

如果 blob 實際上已被替換,則為 true。如果未找到新 blob 或大小不匹配,則為 -EINVAL。

標準聯結器屬性

DRM 聯結器具有一些標準化的屬性

EDID

Blob 屬性,其中包含從接收器讀取的當前 EDID。這對於解析接收器識別資訊(如供應商、型號和序列號)很有用。驅動程式應透過呼叫 drm_connector_update_edid_property() 來更新此屬性,通常在使用 drm_add_edid_modes() 解析 EDID 後。使用者空間無法更改此屬性。

使用者空間不應解析 EDID 以獲取透過其他 KMS 屬性公開的資訊(因為核心可能會對 EDID 應用限制、怪癖或修復)。例如,使用者空間不應嘗試從 EDID 解析模式列表。

DPMS

用於設定聯結器的電源狀態的舊屬性。對於原子驅動程式,僅提供此屬性以向後相容現有驅動程式,它會重新對映到控制聯結器連結到的 CRTC 上的“ACTIVE”屬性。驅動程式絕不應直接設定此屬性,它由 DRM 核心透過呼叫 drm_connector_funcs.dpms 回撥來處理。對於原子驅動程式,到“ACTIVE”屬性的重新對映在 DRM 核心中實現。

在原子驅動程式上,任何值沒有更改的 DPMS setproperty ioctl 都會完全跳過,否則將發生完全原子提交。在舊驅動程式上,確切的行為是驅動程式特定的。

請注意,此屬性無法透過 MODE_ATOMIC ioctl 設定,使用者空間必須改為使用 CRTC 上的“ACTIVE”。

警告

對於也在舊驅動程式上執行的使用者空間,“DPMS”語義要複雜得多。首先,使用者空間不能依賴於 GETCONNECTOR 返回的“DPMS”值來實際反映現實,因為許多驅動程式無法更新它。對於原子驅動程式,這在 drm_atomic_helper_update_legacy_modeset_state() 中處理。

第二個問題是,DPMS 狀態僅在聯結器連線到 CRTC 時才明確定義。在原子中,DRM 核心強制在這種情況下“ACTIVE”為關閉,對於“DPMS”不存在此類檢查。

最後,當使用舊的 SETCONFIG ioctl 啟用輸出時,“DPMS”將被強制為 ON。但請參見上文,這可能不會反映在舊驅動程式上的軟體值中。

總結:僅在已知聯結器已啟用時才設定“DPMS”,假定成功的 SETCONFIG 呼叫也會將“DPMS”設定為 on,並且永遠不要讀回“DPMS”的值,因為它可能不正確。

PATH

聯結器路徑屬性,用於標識此接收器的物理連線方式。由 DP MST 使用。這應透過呼叫 drm_connector_set_path_property() 來設定,在 DP MST 的情況下,使用 MST 管理器建立的路徑屬性。使用者空間無法更改此屬性。

在 DP MST 的情況下,該屬性的格式為 mst:<parent>-<ports>,其中 <parent> 是父聯結器的 KMS 物件 ID,<ports> 是以連字元分隔的 DP MST 埠號列表。請注意,KMS 物件 ID 不能保證在重新啟動後保持穩定。

TILE

聯結器平鋪組屬性,用於指示一組 DRM 聯結器如何組合成一個邏輯螢幕。這由高解析度外部螢幕(通常僅使用一根電纜,但公開多個 DP MST 接收器)或高解析度整合面板(如雙鏈路 DSI)使用,這些面板未進行基因鎖定。請注意,對於基因鎖定的平鋪面板,如雙鏈路 LVDS 或雙鏈路 DSI,驅動程式應嘗試不公開平鋪並虛擬化 drm_crtcdrm_plane(如果需要)。驅動程式應使用 drm_connector_set_tile_property() 更新此值。使用者空間無法更改此屬性。

link-status

聯結器連結狀態屬性,用於指示連結的狀態。連結狀態的預設值為“GOOD”。如果在模式設定期間或之後發生某些錯誤,則核心驅動程式可能會將其設定為“BAD”併發出熱插拔 uevent。驅動程式應使用 drm_connector_set_link_status_property() 更新此值。

當用戶空間接收到熱插拔 uevent 並檢測到“BAD”連結狀態時,接收器不再接收畫素(例如,螢幕完全變黑)。可用模式的列表可能已更改。使用者空間應選擇一種新模式(如果當前模式已消失)並執行新的模式設定,並將連結狀態設定為“GOOD”以重新啟用聯結器。

如果多個聯結器共享同一個 CRTC,並且其中一個聯結器獲得“BAD”連結狀態,則其他聯結器不受影響(即,接收器仍繼續接收畫素)。

當用戶空間對具有“BAD”連結狀態的聯結器執行原子提交而不將該屬性重置為“GOOD”時,接收器可能仍然不接收畫素。當用戶空間執行將連結狀態屬性重置為“GOOD”的原子提交而不設定 ALLOW_MODESET 標誌時,它可能會失敗,因為需要模式設定。

使用者空間只能將連結狀態更改為“GOOD”,將其更改為“BAD”是空操作。

為了與非原子使用者空間向後相容,核心嘗試在 SETCRTC IOCTL 中自動將連結狀態設定回“GOOD”。如果該模式不再有效,則這可能會失敗,類似於在過渡期間連線了不同的螢幕時可能會失敗的情況。

non_desktop

指示應忽略輸出以用於顯示標準桌面環境或控制檯。這很可能是因為輸出裝置不是直線的。

內容保護

使用者空間使用此屬性來請求核心保護將來透過連結傳輸的內容。當請求時,核心將應用適當的保護方式(通常是 HDCP),並使用該屬性告訴使用者空間保護已啟用。

驅動程式可以透過在初始化時呼叫 drm_connector_attach_content_protection_property() 來進行設定。

此屬性的值可以是以下之一

DRM_MODE_CONTENT_PROTECTION_UNDESIRED = 0

連結未受保護,內容以明文形式傳輸。

DRM_MODE_CONTENT_PROTECTION_DESIRED = 1

使用者空間已請求內容保護,但連結當前未受保護。在此狀態下,核心應儘快啟用內容保護。

DRM_MODE_CONTENT_PROTECTION_ENABLED = 2

使用者空間已請求內容保護,並且連結已受保護。只有驅動程式可以將該屬性設定為此值。如果使用者空間嘗試設定為 ENABLED,核心將返回 -EINVAL。

一些準則

  • 在使用者空間透過將該屬性設定為 UNDESIRED 來取消斷言之前,應保留 DESIRED 狀態。這意味著只有在使用者明確請求時,ENABLED 才應轉換為 UNDESIRED。

  • 如果狀態為 DESIRED,核心應儘可能嘗試重新驗證連結。這包括跨停用/啟用、dpms、熱插拔、下游裝置更改、連結狀態失敗等。

  • 核心透過 drm_hdcp_update_content_protection 傳送帶有聯結器 ID 和屬性 ID 的 uevent,在以下核心觸發的場景中:

    • DESIRED -> ENABLED(身份驗證成功)

    • ENABLED -> DESIRED(終止身份驗證)

  • 請注意,對於使用者空間觸發的屬性狀態更改,沒有 uevent,這些更改不會失敗,例如

    • DESIRED/ENABLED -> UNDESIRED

    • UNDESIRED -> DESIRED

  • 使用者空間負責輪詢屬性或偵聽 uevent 以確定值何時從 ENABLED 轉換為 DESIRED。這表示連結不再受保護,使用者空間應採取適當的操作(無論可能是什麼)。

HDCP 內容型別

此列舉屬性由使用者空間用於向核心宣告顯示流的內容型別。此處,顯示流代表使用者空間打算透過 HDCP 加密顯示的任何顯示內容。

流的內容型別由流的所有者決定,作為“HDCP Type0”或“HDCP Type1”。

該屬性的值可以是以下之一
  • “HDCP Type0”:DRM_MODE_HDCP_CONTENT_TYPE0 = 0

  • “HDCP Type1”:DRM_MODE_HDCP_CONTENT_TYPE1 = 1

當核心啟動 HDCP 身份驗證(有關詳細資訊,請參見“內容保護”)時,它使用“HDCP 內容型別”中的內容型別來執行與顯示接收器的 HDCP 身份驗證。

請注意,在 HDCP 規範版本中,可以使用 HDCP 2.2 對連結進行內容型別 0/內容型別 1 的身份驗證。而只能使用 HDCP1.4 對連結進行內容型別 0 的身份驗證(儘管本質上是隱式的。因為在 HDCP1.4 中沒有對內容型別的引用)。

HDCP2.2 身份驗證協議本身將“內容型別”作為引數,該引數是 DP HDCP2.2 加密演算法的輸入。

對於型別 0 內容保護請求,核心驅動程式可以選擇 HDCP 規範版本 1.4 和 2.2 中的任一個。當 HDCP2.2 用於“HDCP Type 0”時,下游中支援 HDCP 2.2 的中繼器可以將該內容傳送到透過 HDCP 1.4 驗證的 HDCP 接收器(Type0 連結)。但是,如果內容被歸類為“HDCP Type 1”,則上述 HDCP 2.2 中繼器不會將內容傳送到 HDCP 接收器,因為它無法對“HDCP Type 1”的 HDCP1.4 接收器進行身份驗證。

請注意,使用者空間可以忽略核心驅動程式用於實現“HDCP 內容型別”的 HDCP 版本。

在當前情況下,將內容分類為 Type 1 可確保內容僅透過 HDCP2.2 加密連結顯示。

請注意,HDCP 內容型別屬性是在 HDCP 2.2 中引入的,預設型別為 0。它僅由支援 HDCP 2.2(因此支援 Type 0 和 Type 1)的驅動程式公開。根據 HDCP 規範的後續版本如何定義,內容型別也可以用於更高的版本。

如果在“內容保護”不是 UNDESIRED 時更改了內容型別,則核心將停用 HDCP,並在同一原子提交中使用新型別重新啟用 HDCP。當“內容保護”為 ENABLED 時,表示連結已透過 HDCP 驗證和加密,用於傳輸“HDCP 內容型別”中提到的流型別。

HDR_OUTPUT_METADATA

聯結器屬性,用於使使用者空間能夠將 HDR 元資料傳送到驅動程式。此元資料基於使用者決定的合成和混合策略,同時考慮了硬體和接收器的功能。驅動程式獲取此元資料,並在 HDMI 的情況下建立動態範圍和母帶資訊幀 (DRM),在 DP 的情況下建立 SDP 資料包(非音訊 INFOFRAME SDP v1.3)。然後將其傳送到接收器。這會將即將到來的幀的顏色編碼和亮度引數通知接收器。

使用者空間首先需要透過讀取和解析 EDID 來檢測接收器的 HDR 功能。有關 HDMI 的 HDR 元資料的詳細資訊已新增到 CTA 861.G 規範中。對於 DP,它在 VESA DP Standard v1.4 中定義。然後,它需要獲取影片/遊戲/應用程式內容(基本上是使用 HDR 傳輸函式進行編碼)的元資料資訊。有了這些資訊,它需要決定混合策略並將相關圖層/疊加層合成為一種通用格式。完成此混合後,使用者空間將知道要傳送到接收器的合成幀的元資料。然後,它使用此屬性將此元資料傳達給驅動程式,該驅動程式隨後根據連線的編碼器的型別製作資訊幀資料包併發送到接收器。

在以下情況下,使用者空間將負責進行色調對映操作
  • 某些圖層是 HDR,而其他圖層是 SDR

  • HDR 圖層的亮度與接收器的亮度不同

它甚至需要進行顏色空間轉換並將所有圖層轉換為一種通用顏色空間以進行混合。它可以基於相關硬體的功能使用 GL、媒體或顯示引擎來完成此操作。

驅動程式期望將元資料放入來自使用者空間的 struct hdr_output_metadata 結構中。這作為 blob 接收並存儲在 drm_connector_state.hdr_output_metadata 中。它解析 EDID 並將接收器元資料儲存在 struct hdr_sink_metadata 中,作為 drm_connector.hdr_sink_metadata。在 HDMI 編碼器的情況下,驅動程式使用 drm_hdmi_infoframe_set_hdr_metadata() 輔助函式設定 HDR 元資料,使用 hdmi_drm_infoframe_pack() 按照規範打包資訊幀。

max bpc

此範圍屬性由使用者空間用於限制位深度。使用時,驅動程式將根據硬體和接收器支援的有效範圍限制 bpc。驅動程式可以使用函式 drm_connector_attach_max_bpc_property() 在初始化期間建立屬性並將其附加到聯結器。

聯結器還具有一個標準化的原子屬性

CRTC_ID

此聯結器應連線到的 drm_crtc 的模式物件 ID。

LCD 面板的聯結器也可能具有一個標準化的屬性

panel orientation

在某些裝置上,LCD 面板以這樣一種方式安裝在外殼中,即面板的向上/頂部與裝置的頂部不匹配。使用者空間可以使用此屬性來檢查此情況。請注意,來自觸控式螢幕(帶有 INPUT_PROP_DIRECT 的輸入裝置)的輸入座標仍將 1:1 對映到實際的 LCD 面板座標,因此,如果使用者空間旋轉圖片以調整方向,則還必須對觸控式螢幕輸入座標應用相同的轉換。此屬性透過呼叫 drm_connector_set_panel_orientation()drm_connector_set_panel_orientation_with_quirk() 初始化

scaling mode

此屬性定義如何將非原生模式放大到 LCD 面板的本機模式

None

不發生放大,縮放留給面板。並非所有驅動程式都公開此模式。

Full

輸出被放大到面板的完整解析度,忽略縱橫比。

Center

不發生放大,輸出在面板的本機解析度內居中。

Full aspect

輸出被放大以最大化寬度或高度,同時保持寬高比。

此屬性應透過呼叫 drm_connector_attach_scaling_mode_property() 來設定。請注意,驅動程式也可以將此屬性暴露給外部輸出,在這種情況下,它們必須支援“None”,這應該是預設值(因為外部螢幕具有內建的縮放器)。

subconnector

此屬性由 DVI-I、TVout 和 DisplayPort 用於指示不同的聯結器子型別。列舉值或多或少與主要聯結器型別的列舉值匹配。對於 DVI-I 和 TVout,還有一個匹配的屬性“選擇子聯結器”,允許在訊號型別之間切換。DP 子聯結器對應於下游埠。

privacy-screen sw-state, privacy-screen hw-state

這兩個可選屬性可用於查詢某些顯示器上提供的電子隱私螢幕的狀態;在某些情況下,還可以控制狀態。如果驅動程式實現了這些屬性,則必須同時存在這兩個屬性。

“privacy-screen hw-state”是隻讀的,反映了隱私螢幕的實際狀態,可能的值:“Enabled”、“Disabled”、“Enabled-locked”、“Disabled-locked”。鎖定狀態表示無法透過 DRM API 更改狀態。例如,可能存在韌體設定選項或硬體滑塊開關提供始終開啟/關閉模式的裝置。

當未鎖定時,可以設定“privacy-screen sw-state”來更改隱私螢幕狀態。在這種情況下,驅動程式必須在 sw-state 屬性提交完成後更新 hw-state 屬性以反映新狀態。當 hw-state 被鎖定時,將 sw-state 屬性設定為某個值必須被驅動程式解釋為請求在 hw-state 變為解鎖狀態時將狀態更改為設定的狀態。例如,如果“privacy-screen hw-state”為“Enabled-locked”,並且 sw-state 被設定為“Disabled”,隨後使用者透過更改滑塊開關位置來解鎖狀態,則驅動程式必須在收到解鎖事件後將狀態設定為“Disabled”。

在某些情況下,隱私螢幕的實際狀態可能會在 DRM 程式碼控制之外發生更改。例如,可能存在韌體處理的熱鍵可以切換實際狀態,或者可以透過另一個使用者空間 API(例如寫入 /proc/acpi/ibm/lcdshadow)來更改實際狀態。在這種情況下,驅動程式必須更新 hw-state 和 sw-state 以反映新值,從而覆蓋 sw-state 中的任何掛起狀態請求。因此,任何掛起的 sw-state 請求都將被丟棄。

請注意,狀態可以在 DRM 主程序控制之外更改這一事實意味著使用者空間不得快取 sw-state 的值。快取 sw-state 值並將其包含在以後的原子提交中可能會導致覆蓋透過例如韌體處理的熱鍵完成的狀態更改。因此,除非使用者空間想要更改隱私螢幕的 sw-state 值,否則不得將其包含在原子提交中。

left margin, right margin, top margin, bottom margin

將邊距新增到聯結器的視口。這通常用於緩解電視上的過掃描。

該值是將新增的黑色邊框的大小(以畫素為單位)。附加的 CRTC 的內容將被縮放以填充邊距內的整個區域。

邊距配置可能會被髮送到接收器,例如透過 HDMI AVI InfoFrames。

驅動程式可以透過呼叫 drm_mode_create_tv_margin_properties() 來設定這些屬性。

Colorspace

此屬性用於通知驅動程式使用者空間配置畫素操作屬性以產生的顏色編碼。這些變體設定了色度、傳遞特性以及必要時應使用的 YCbCr 轉換。來自 HDR_OUTPUT_METADATA 的傳遞特性優先於此屬性。使用者空間始終配置畫素操作屬性以產生全量化範圍資料(請參閱 Broadcast RGB 屬性)。

驅動程式告知接收器期望的色度、傳遞特性、YCbCr 轉換和量化範圍(這可能取決於輸出模式、輸出格式和其他屬性)。驅動程式還將使用者空間提供的資料轉換為接收器期望的資料。

使用者空間必須透過解析 EDID 來檢查接收器是否支援驅動程式允許選擇的所有可能的色度。

由於歷史原因,此屬性暴露了許多會導致未定義行為的變體。

Default

該行為是特定於驅動程式的。

BT2020_RGB

BT2020_YCC

使用者空間配置畫素操作屬性以產生具有 Rec. ITU-R BT.2020 色度、Rec. ITU-R BT.2020(表 4,RGB)傳遞特性和全量化範圍的 RGB 內容。使用者空間可以使用 HDR_OUTPUT_METADATA 屬性將傳遞特性設定為 PQ(Rec. ITU-R BT.2100 表 4)或 HLG(Rec. ITU-R BT.2100 表 5),在這種情況下,使用者空間配置畫素操作屬性以產生具有相應傳遞特性的內容。使用者空間必須確保接收器支援 Rec. ITU-R BT.2020 R'G'B' 和 Rec. ITU-R BT.2020 Y'C'BC'R 色度。驅動程式可以將接收器配置為使用 RGB 格式,告訴接收器期望 Rec. ITU-R BT.2020 R'G'B' 色度,並轉換為適當的量化範圍。驅動程式可以將接收器配置為使用 YCbCr 格式,告訴接收器期望 Rec. ITU-R BT.2020 Y'C'BC'R 色度,使用 Rec. ITU-R BT.2020 非恆定亮度轉換矩陣轉換為 YCbCr,並轉換為適當的量化範圍。變體 BT2020_RGB 和 BT2020_YCC 是等效的,驅動程式自行選擇 RGB 和 YCbCr。

SMPTE_170M_YCC: BT709_YCC: XVYCC_601: XVYCC_709: SYCC_601: opYCC_601: opRGB: BT2020_CYCC: DCI-P3_RGB_D65: DCI-P3_RGB_Theater: RGB_WIDE_FIXED: RGB_WIDE_FLOAT

BT601_YCC

該行為未定義。

由於 HDMI 和 DP 具有不同的色彩空間,drm_mode_create_hdmi_colorspace_property() 用於 HDMI 聯結器,drm_mode_create_dp_colorspace_property() 用於 DP 聯結器。

HDMI 特定聯結器屬性

Broadcast RGB (HDMI specific)

指示使用的量化範圍(完整與有限)。顏色處理管道將被調整以匹配屬性的值,並且將相應地生成和傳送資訊幀。

僅當 HDMI 輸出格式為 RGB 時,此屬性才相關。如果是 YCbCr 變體之一,它將被忽略。

連線到聯結器的 CRTC 必須由使用者空間配置為始終產生全範圍畫素。

此屬性的值可以是以下之一

Automatic

根據 HDMI 規範(HDMI 1.4b - 第 6.6 節 - 影片量化範圍),根據模式自動選擇量化範圍。

Full

強制使用全量化範圍。

Limited 16:235

強制使用有限量化範圍。與名稱建議的不同,這適用於任何每分量位數。

除 Automatic 之外的屬性值可能會導致顏色偏差(如果選擇了 limited 但顯示器期望 full),或者黑屏(如果選擇了 full 但顯示器期望 limited)。

驅動程式可以透過呼叫 drm_connector_attach_broadcast_rgb_property() 來設定此屬性。

content type (HDMI specific)

指示要在 HDMI 資訊幀中使用的內容型別設定,以指示外部裝置的內容型別,以便它相應地調整其顯示設定。

此屬性的值可以是以下之一

No Data

內容型別未知

Graphics

內容型別是圖形

Photo

內容型別是照片

Cinema

內容型別是電影

Game

內容型別是遊戲

每種內容型別的含義在 CTA-861-G 表 15 中定義。

驅動程式可以透過呼叫 drm_connector_attach_content_type_property() 來設定此屬性。到資訊幀值的解碼透過 drm_hdmi_avi_infoframe_content_type() 完成。

模擬電視特定聯結器屬性

TV Mode

指示在模擬電視聯結器上使用的電視模式。此屬性的值可以是以下之一

NTSC

電視模式是 CCIR 系統 M(又名 525 行),與 NTSC 顏色編碼一起使用。

NTSC-443

電視模式是 CCIR 系統 M(又名 525 行),與 NTSC 顏色編碼一起使用,但顏色副載波頻率為 4.43MHz

NTSC-J

電視模式是 CCIR 系統 M(又名 525 行),與 NTSC 顏色編碼一起使用,但黑電平等於消隱電平。

PAL

電視模式是 CCIR 系統 B(又名 625 行),與 PAL 顏色編碼一起使用。

PAL-M

電視模式是 CCIR 系統 M(又名 525 行),與 PAL 顏色編碼一起使用。

PAL-N

電視模式是 CCIR 系統 N,與 PAL 顏色編碼一起使用,顏色副載波頻率為 3.58MHz,SECAM 色彩空間,並且通道比其他 PAL 變體窄。

SECAM

電視模式是 CCIR 系統 B(又名 625 行),與 SECAM 顏色編碼一起使用。

Mono

使用適合 DRM 模式的計時,包括用於 525 行或 625 行模式的均衡脈衝,沒有基座或顏色編碼。

驅動程式可以透過呼叫 drm_mode_create_tv_properties() 來設定此屬性。

標準 CRTC 屬性

DRM CRTC 具有一些標準化的屬性

ACTIVE

用於設定 CRTC 電源狀態的原子屬性。當設定為 1 時,CRTC 將主動顯示內容。當設定為 0 時,CRTC 將關閉電源。不期望使用者空間在將 ACTIVE 設定為 0 時重置 CRTC 資源,如模式和平面。

使用者空間可以依賴於 ACTIVE 更改為 1 永遠不會導致原子測試失敗,只要沒有其他屬性發生更改。如果對 ACTIVE 的更改導致原子測試失敗,這是一個驅動程式錯誤。因此,將 ACTIVE 設定為 0 不得釋放內部資源(如保留的記憶體頻寬或時鐘發生器)。

請注意,聯結器上的舊版 DPMS 屬性在內部被路由以控制原子驅動程式的此屬性。

MODE_ID

用於設定 CRTC 顯示時序的原子屬性。該值是包含 DRM 模式資訊的 blob 的 ID。要停用 CRTC,使用者空間必須將此屬性設定為 0。

將 MODE_ID 設定為 0 將釋放為 CRTC 保留的資源。

SCALING_FILTER

用於設定 CRTC 縮放器的縮放過濾器的原子屬性

此屬性的值可以是以下之一

Default

驅動程式的預設縮放濾波器

Nearest Neighbor

最近鄰縮放濾波器

標準平面屬性

DRM 平面具有一些標準化的屬性

type

描述平面型別的不可變屬性。

對於已啟用 DRM_CLIENT_CAP_ATOMIC 功能的使用者空間,平面型別只是一個提示,並且主要被原子測試提交所取代。型別提示仍然可以用來更容易地提出驅動程式接受的平面配置。

此屬性的值可以是以下之一

“Primary”

要點亮 CRTC,如果附加一個覆蓋整個 CRTC 且未設定縮放或裁剪的主平面,則最有可能有效。

驅動程式可以支援主平面的更多功能,使用者空間可以透過僅測試的原子提交來找出答案。

一些主平面由核心在舊版 IOCTL DRM_IOCTL_MODE_SETCRTCDRM_IOCTL_MODE_PAGE_FLIP 中隱式使用。因此,使用者空間不得將任何主平面的顯式用法(例如,透過原子提交)與這些舊版 IOCTL 混合使用。

“Cursor”

要啟用此平面,使用配置為不進行縮放或裁剪並具有以下屬性的幀緩衝區最有可能有效

  • 如果驅動程式提供功能 DRM_CAP_CURSOR_WIDTHDRM_CAP_CURSOR_HEIGHT,請使用此大小建立幀緩衝區。否則,建立一個大小為 64x64 的幀緩衝區。

  • 如果驅動程式不支援修飾符,請使用線性佈局建立幀緩衝區。否則,請使用 IN_FORMATS 平面屬性。

驅動程式可以支援游標平面的更多功能,使用者空間可以透過僅測試的原子提交來找出答案。

一些游標平面由核心在舊版 IOCTL DRM_IOCTL_MODE_CURSORDRM_IOCTL_MODE_CURSOR2 中隱式使用。因此,使用者空間不得將任何游標平面的顯式用法(例如,透過原子提交)與這些舊版 IOCTL 混合使用。

即使沒有暴露游標平面,一些驅動程式也可能支援游標。在這種情況下,可以使用舊版游標 IOCTL 來配置游標。

“Overlay”

既不是主平面也不是游標平面。

當停用 DRM_CLIENT_CAP_UNIVERSAL_PLANES 功能時,覆蓋平面是唯一暴露的平面。

IN_FORMATS

blob 屬性,包含此平面支援的緩衝區格式和修飾符對的集合。該 blob 是一個 struct drm_format_modifier_blob。沒有此屬性,平面不支援帶有修飾符的緩衝區。使用者空間無法更改此屬性。

請注意,使用者空間可以檢查 DRM_CAP_ADDFB2_MODIFIERS 驅動程式功能以獲得通用修飾符支援。如果設定了此標誌,則每個平面都將具有 IN_FORMATS 屬性,即使它僅支援 DRM_FORMAT_MOD_LINEAR。在 linux 核心版本 v5.1 之前,此區域存在各種錯誤,功能標誌和每個平面屬性之間存在不一致。

IN_FORMATS_ASYNC

blob 屬性,包含此平面支援的非同步翻轉的緩衝區格式和修飾符對的集合。該 blob 是一個 struct drm_format_modifier_blob。使用者空間無法更改此屬性。這是一個可選屬性,如果不存在,則使用者應該預期在使用原子 ioctl 時會失敗,因為非同步翻轉下該平面不支援修飾符/格式。

SIZE_HINTS

blob 屬性,包含建議的平面大小的集合,可用於簡單的“類似游標”的用例(例如,沒有縮放)。使用這些提示可以避免使用者空間透過原子/setcursor ioctl 大量探測支援的平面大小。

blob 包含一個 struct drm_plane_size_hint 陣列,按優先順序排序。為了獲得最佳使用效果,使用者空間應選擇滿足其自身要求的第一個大小。

驅動程式應僅將此屬性附加到支援非常有限的大小集合的平面。

請注意,屬性值 0(即沒有 blob)保留供將來潛在使用。當前的使用者空間應忽略該屬性(如果值為 0),並回退到其他方式(例如,DRM_CAP_CURSOR_WIDTHDRM_CAP_CURSOR_HEIGHT)來確定要使用的適當平面大小。

平面合成屬性

標準平面屬性支援的基本平面合成模型只有一個源矩形(在 drm_framebuffer 中的邏輯畫素中),具有亞畫素精度,該源矩形被放大到 drm_crtc 可見區域中的畫素對齊目標矩形。CRTC 的可見區域由請求的模式的水平和垂直可見畫素(儲存在 **hdisplay** 和 **vdisplay** 中)定義(儲存在 drm_crtc_state.mode 中)。這兩個矩形都儲存在 drm_plane_state 中。

對於原子 ioctl,平面物件上的以下標準(原子)屬性對基本平面合成模型進行編碼

SRC_X

源矩形在 drm_framebuffer 中的 X 座標偏移量,以 16.16 定點表示。必須為正數。

SRC_Y

源矩形在 drm_framebuffer 中的 Y 座標偏移量,以 16.16 定點表示。必須為正數。

SRC_W

源矩形在 drm_framebuffer 中的寬度,以 16.16 定點表示。SRC_X 加 SRC_W 必須在源幀緩衝區的寬度內。必須為正數。

SRC_H

源矩形在 drm_framebuffer 中的高度,以 16.16 定點表示。SRC_Y 加 SRC_H 必須在源幀緩衝區的高度內。必須為正數。

CRTC_X

目標矩形的 X 座標偏移量。可以為負數。

CRTC_Y

目標矩形的 Y 座標偏移量。可以為負數。

CRTC_W

目標矩形的寬度。CRTC_X 加 CRTC_W 可以超出 drm_crtc 的當前可見水平區域。

CRTC_H

目標矩形的高度。CRTC_Y 加 CRTC_H 可以超出 drm_crtc 的當前可見垂直區域。

FB_ID

此平面應掃描出的 drm_framebuffer 的模式物件 ID。

當 KMS 客戶端執行前緩衝區渲染時,它應該在每個原子提交上將 FB_ID 設定為相同的前緩衝區 FB。這意味著驅動程式需要再次重新讀取相同的 FB。否則,不採用連續重複掃描迴圈的驅動程式可能不會更新螢幕。

CRTC_ID

此平面應連線到的 drm_crtc 的模式物件 ID。

請注意,源矩形必須完全位於 drm_framebuffer 的邊界內。目標矩形可以位於 CRTC 當前模式的可見區域之外。它必須由驅動程式適當裁剪,可以透過呼叫 drm_plane_helper_check_update() 來完成。還允許驅動程式適當地舍入子畫素取樣位置,但只能舍入到下一個完整畫素。不得對源矩形之外的任何畫素進行取樣,這在應用比雙線性濾波更復雜的濾波進行縮放時非常重要。縮放時的濾波模式未指定。

除了此基本轉換之外,驅動程式還可以公開其他屬性

alpha

Alpha 透過 drm_plane_create_alpha_property() 設定。它控制整個平面的不透明度,從透明 (0) 到不透明 (0xffff)。它可以與畫素 alpha 結合使用。幀緩衝區中的畫素值預計不會與與平面關聯的全域性 alpha 預乘。

rotation

Rotation 透過 drm_plane_create_rotation_property() 設定。它在源矩形和目標矩形之間新增旋轉和反射步驟。沒有此屬性,矩形僅縮放,但不旋轉或反射。

可能的值

“rotate-<degrees>”

指示 DRM 平面以逆時針方向旋轉 <degrees> 度。

“reflect-<axis>”

指示 DRM 平面的內容沿 <axis> 軸反射,方式與映象相同。

reflect-x

|o |    | o|
|  | -> |  |
| v|    |v |

reflect-y

|o |    | ^|
|  | -> |  |
| v|    |o |
zpos

Z position 透過 drm_plane_create_zpos_immutable_property()drm_plane_create_zpos_property() 設定。它控制重疊平面的可見性。沒有此屬性,主平面始終位於游標平面下方,並且所有其他平面之間的排序未定義。正 Z 軸指向使用者,即,Z 位置值較低的平面位於 Z 位置值較高的平面下方。具有相同 Z 位置值的兩個平面具有未定義的排序。請注意,Z 位置值也可以是不可變的,以告知使用者空間平面的硬編碼堆疊,請參閱 drm_plane_create_zpos_immutable_property()。如果任何平面具有 zpos 屬性(可變或不可變),則所有平面都應具有 zpos 屬性。

pixel blend mode

Pixel blend mode 透過 drm_plane_create_blend_mode_property() 設定。它為 alpha 混合方程選擇添加了一個混合模式,描述了當前平面的畫素如何與背景合成。

定義了三個 alpha 混合方程

“None”

忽略畫素 alpha 的混合公式

out.rgb = plane_alpha * fg.rgb +
        (1 - plane_alpha) * bg.rgb
“Pre-multiplied”

假設畫素顏色值已經與 alpha 通道值預乘的混合公式

out.rgb = plane_alpha * fg.rgb +
        (1 - (plane_alpha * fg.alpha)) * bg.rgb
“Coverage”

假設畫素顏色值未預乘,並且在將它們混合到背景顏色值時將進行預乘的混合公式

out.rgb = plane_alpha * fg.alpha * fg.rgb +
        (1 - (plane_alpha * fg.alpha)) * bg.rgb

使用以下符號

“fg.rgb”

來自平面畫素的每個 RGB 分量值

“fg.alpha”

來自平面畫素的 Alpha 分量值。如果平面的畫素格式沒有 alpha 分量,則假定此值為 1.0。在這些情況下,此屬性無效,因為所有三個方程都變得等效。

“bg.rgb”

來自背景的每個 RGB 分量值

“plane_alpha”

由平面“alpha”屬性設定的平面 alpha 值。如果平面不暴露“alpha”屬性,則假定此值為 1.0

請注意,此處描述的所有屬性擴充套件都適用於平面或 CRTC(例如,對於背景顏色,當前未公開且假定為黑色)。

SCALING_FILTER

指示要用於平面縮放器的縮放濾波器

此屬性的值可以是以下之一

Default

驅動程式的預設縮放濾波器

Nearest Neighbor

最近鄰縮放濾波器

驅動程式可以透過呼叫 drm_plane_create_scaling_filter_property 為平面設定此屬性

損壞跟蹤屬性

FB_DAMAGE_CLIPS 是一個可選的平面屬性,它提供了一種在附加到平面的幀緩衝區的幀緩衝區座標中指定平面上損壞矩形列表的方法。在當前上下文中,損壞是指自上次平面更新(也稱為頁面翻轉)以來,平面幀緩衝區中已更改的區域,無論當前附加的幀緩衝區是否與上次平面更新期間附加的幀緩衝區相同。

FB_DAMAGE_CLIPS 是核心的一個提示,它可能有助於某些驅動程式在內部進行最佳化,特別是對於每個幀緩衝區更改都需要透過網路、USB 等傳輸的虛擬裝置。

由於 FB_DAMAGE_CLIPS 是一個提示,因此它是一個可選屬性。使用者空間可以忽略損壞剪輯屬性,在這種情況下,驅動程式將執行完整的平面更新。如果提供了損壞剪輯,則保證損壞剪輯內的區域將更新到平面。為了提高效率,驅動程式可以進行完整更新,或者可以更新比損壞剪輯中指定的更多的內容。由於驅動程式可以自由讀取更多內容,因此使用者空間必須始終渲染整個可見幀緩衝區。否則可能會出現損壞。此外,如果使用者空間提供的損壞剪輯未涵蓋幀緩衝區的實際損壞(自上次平面更新以來),可能會導致不正確的渲染。

FB_DAMAGE_CLIPS 是一個 Blob 屬性,Blob 資料的佈局只是一個 drm_mode_rect 陣列。與平面 drm_plane_state.src 座標不同,損壞剪輯不是 16.16 定點數。與幀緩衝區中的平面 src 類似,損壞剪輯不能為負數。在損壞剪輯中,x1/y1 是包含性的,而 x2/y2 是排他性的。雖然核心不會因重疊的損壞剪輯而報錯,但不鼓勵這樣做。

對平面損壞介面感興趣的驅動程式應透過呼叫 drm_plane_enable_fb_damage_clips() 啟用 FB_DAMAGE_CLIPS 屬性。實現損壞的驅動程式可以使用 drm_atomic_helper_damage_iter_init()drm_atomic_helper_damage_iter_next() 輔助迭代器函式來獲取剪輯到 drm_plane_state.src 的損壞矩形。

請注意,有兩種型別的損壞處理:幀損壞和緩衝區損壞,實現的損壞處理型別取決於驅動程式的上傳目標。實現每個平面或每個 CRTC 上傳目標的驅動程式需要處理幀損壞,而實現每個緩衝區上傳目標的驅動程式需要處理緩衝區損壞。

現有的損壞輔助程式僅支援幀損壞型別,目前還沒有實現緩衝區年齡支援或類似的損壞累積演算法。

只有處理幀損壞的驅動程式才能使用上述損壞輔助程式來迭代損壞區域。處理緩衝區損壞的驅動程式必須為 drm_atomic_helper_damage_iter_init() 設定 drm_plane_state.ignore_damage_clips,以瞭解應忽略損壞剪輯並將 drm_plane_state.src 作為損壞矩形返回,以強制進行完整的平面更新。

具有每個緩衝區上傳目標的驅動程式可以比較新舊平面狀態的 drm_plane_state.fb,以確定附加到平面的幀緩衝區自上次平面更新以來是否已更改。如果 drm_plane_state.fb 已更改,則必須將 drm_plane_state.ignore_damage_clips 設定為 true。

這是因為具有每個平面上傳目標的驅動程式期望後備儲存緩衝區對於給定的平面不會更改。如果在頁面翻轉之間上傳緩衝區發生更改,則必須整體更新新的上傳緩衝區。如果 DRM 損壞輔助程式添加了對幀損壞的支援,則可以改進這一點,類似於使用者空間已經如何處理這種情況,如下面的文件中所述

顏色管理屬性

顏色管理或顏色空間調整透過 drm_crtc 物件上的一組 5 個屬性來支援。它們透過呼叫 drm_crtc_enable_color_mgmt() 來設定。

“DEGAMMA_LUT”

Blob 屬性,用於設定反伽瑪查詢表 (LUT),該表在畫素資料提供給變換矩陣之前將畫素資料從幀緩衝區映射出來。該資料被解釋為 struct drm_color_lut 元素的陣列。硬體可能會選擇不使用 LUT 元素的完整精度,也不使用 LUT 的所有元素(例如,硬體可能會選擇在 LUT[0] 和 LUT[4] 之間進行插值)。

將此值設定為 NULL(Blob 屬性值設定為 0)意味著應使用線性/直通伽瑪表。這通常也是驅動程式的啟動狀態。驅動程式可以透過 drm_crtc_state.degamma_lut 訪問此 Blob。

“DEGAMMA_LUT_SIZE”

無符號範圍屬性,用於提供 DEGAMMA_LUT 屬性上設定的查詢表的大小(大小取決於底層硬體)。如果驅動程式支援多個 LUT 大小,則應釋出最大大小,並適當地對較小大小的 LUT 進行子取樣(例如,對於拆分伽瑪模式)。

“CTM”

Blob 屬性,用於設定當前變換矩陣 (CTM),該矩陣應用於透過反伽瑪 LUT 查詢後和透過伽瑪 LUT 查詢前的畫素資料。該資料被解釋為 struct drm_color_ctm

將此值設定為 NULL(Blob 屬性值設定為 0)意味著應使用單位/直通矩陣。這通常也是驅動程式的啟動狀態。驅動程式可以透過 drm_crtc_state.ctm 訪問顏色轉換矩陣的 Blob。

“GAMMA_LUT”

Blob 屬性,用於設定伽瑪查詢表 (LUT),該表將轉換矩陣後的畫素資料對映到傳送到聯結器的資料。該資料被解釋為 struct drm_color_lut 元素的陣列。硬體可能會選擇不使用 LUT 元素的完整精度,也不使用 LUT 的所有元素(例如,硬體可能會選擇在 LUT[0] 和 LUT[4] 之間進行插值)。

將此值設定為 NULL(Blob 屬性值設定為 0)意味著應使用線性/直通伽瑪表。這通常也是驅動程式的啟動狀態。驅動程式可以透過 drm_crtc_state.gamma_lut 訪問此 Blob。

請注意,由於主要來自Xorg傳承的歷史原因,它也用於儲存索引格式(如DRM_FORMAT_C8)的顏色對映(有時也稱為顏色lut、CLUT或調色盤)。

“GAMMA_LUT_SIZE”

無符號範圍屬性,用於提供 GAMMA_LUT 屬性上設定的查詢表的大小(大小取決於底層硬體)。如果驅動程式支援多個 LUT 大小,則應釋出最大大小,並適當地對較小大小的 LUT 進行子取樣(例如,對於拆分伽瑪模式)。

還支援舊版伽瑪表,該伽瑪表透過呼叫 drm_mode_crtc_set_gamma_size() 來設定。然後,DRM 核心將舊版伽瑪斜坡與“GAMMA_LUT”或(如果該值不可用)“DEGAMMA_LUT”別名。

對不同非 RGB 顏色編碼的支援透過 drm_plane 特定的 COLOR_ENCODING 和 COLOR_RANGE 屬性來控制。它們透過呼叫 drm_plane_create_color_properties() 來設定。

“COLOR_ENCODING”

可選的平面列舉屬性,用於支援不同的非 RGB 顏色編碼。驅動程式可以提供 DRM 平面支援的標準列舉值的子集。

“COLOR_RANGE”

可選的平面列舉屬性,用於支援不同的非 RGB 顏色引數範圍。驅動程式可以提供 DRM 平面支援的標準列舉值的子集。

平鋪組屬性

平鋪組用於表示具有唯一整數識別符號的平鋪監視器。使用 DisplayID v1.3 的平鋪監視器具有唯一的 8 位元組控制代碼,我們將其儲存在平鋪組中,因此我們為監視器組中的所有平鋪都有一個公共識別符號。該屬性稱為“TILE”。驅動程式可以使用 drm_mode_create_tile_group()drm_mode_put_tile_group()drm_mode_get_tile_group() 來管理平鋪組。但這僅對於透過非標準方式公開平鋪組資訊的內部面板是必需的。

顯式圍欄屬性

顯式圍欄允許使用者空間控制裝置之間的緩衝區同步。圍欄或一組圍欄使用同步檔案 fd 傳輸到/從使用者空間傳輸,並且有兩個 DRM 屬性用於此。每個 DRM 平面上的 IN_FENCE_FD 用於將圍欄傳送到核心,每個 DRM CRTC 上的 OUT_FENCE_PTR 用於從核心接收圍欄。

相比之下,使用隱式圍欄,核心會跟蹤任何正在進行的渲染,並自動確保原子更新等待任何掛起的渲染完成。這通常在 struct dma_resv 中跟蹤,該結構也可以包含強制性的核心圍欄。隱式同步是 Linux 傳統的工作方式(例如,X.org 上的 DRI2/3),而顯式圍欄是 Android 所需的。

“IN_FENCE_FD”

使用此屬性傳遞 DRM 應等待的圍欄,然後再繼續執行原子提交請求並在螢幕上顯示平面的幀緩衝區。圍欄可以是普通圍欄或合併圍欄,sync_file 框架將處理這兩種情況,如果收到合併圍欄,則使用 fence_array。在此處傳遞 -1 意味著沒有要等待的圍欄。

如果原子提交請求具有 DRM_MODE_ATOMIC_TEST_ONLY 標誌,它將僅檢查同步檔案是否有效。

在驅動程式端,圍欄儲存在 struct drm_plane_statefence 引數上。還支援隱式圍欄的驅動程式應使用 drm_gem_plane_helper_prepare_fb() 提取隱式圍欄,以確保在隱式圍欄與顯式圍欄的優先順序方面,驅動程式之間具有一致的行為。

“OUT_FENCE_PTR”

使用此屬性將檔案描述符指標傳遞給 DRM。原子提交請求呼叫返回後,OUT_FENCE_PTR 將填充同步檔案的檔案描述符編號。此同步檔案包含 CRTC 圍欄,當原子提交 * 請求中針對給定 CRTC 的所有幀緩衝區都在螢幕上掃描出來時,將發出訊號。

如果傳遞了無效的指標,則原子提交請求將失敗。如果原子提交請求因任何其他原因失敗,則返回的輸出圍欄 fd 將為 -1。在使用 DRM_MODE_ATOMIC_TEST_ONLY 標誌的原子提交上,輸出圍欄也將設定為 -1。

請注意,輸出圍欄沒有特殊的驅動程式介面,並且在內部由 struct drm_crtc_state 中的 struct drm_pending_vblank_event 表示,非阻塞原子提交輔助程式和現有使用者空間的 DRM 事件處理也使用該結構。

可變重新整理屬性

能夠動態調整重新整理率的可變重新整理率顯示器可以透過延長其垂直前沿的持續時間直到頁面翻轉或超時來動態調整其重新整理率。這可以減少或消除頁面翻轉與垂直消隱間隔不對齊的情況下的卡頓和延遲。

一個示例場景是應用程式在 60Hz 顯示器上以恆定的 48Hz 速率翻轉。頁面翻轉將經常錯過垂直消隱間隔,並且相同的內容將顯示兩次。對於具有運動的內容,可以觀察到卡頓。

如果在支援 35Hz 到 60Hz 的可變重新整理範圍的顯示器上激活了可變重新整理率,則對於示例場景,將無法觀察到卡頓。35Hz 的最小支援的可變重新整理率低於頁面翻轉頻率,並且可以延長垂直前沿,直到發生頁面翻轉。垂直消隱間隔將直接與頁面翻轉率對齊。

並非所有使用者空間內容都適合與可變重新整理率一起使用。垂直前沿持續時間的較大且頻繁的更改可能會使輸入敏感型應用程式的感知卡頓惡化。

面板亮度也會隨著垂直前沿持續時間而變化。某些面板在最小垂直前沿持續時間和最大垂直前沿持續時間之間可能具有明顯的亮度差異。垂直前沿持續時間的較大且頻繁的更改可能會產生此類面板的可觀察到的閃爍。

透過 drm_connectordrm_crtc 物件上的屬性支援可變重新整理率的使用者空間控制。

“vrr_capable”

可選的 drm_connector 布林屬性,驅動程式應使用 drm_connector_attach_vrr_capable_property() 將其附加到可能支援可變重新整理率的聯結器。驅動程式應透過呼叫 drm_connector_set_vrr_capable_property() 更新屬性值。

不存在該屬性應指示不存在支援。

“VRR_ENABLED”

預設的 drm_crtc 布林屬性,用於通知驅動程式 CRTC 上的內容適合可變重新整理率呈現。如果接收器支援,驅動程式將以此屬性作為啟用可變重新整理率支援的提示,即如果 drm_connector 物件上的“vrr_capable”屬性為 true。啟用後,垂直前沿持續時間將延長,直到頁面翻轉或超時。

最小垂直前沿持續時間定義為當前模式的垂直前沿持續時間。

最大垂直前沿持續時間大於或等於最小垂直前沿持續時間。該持續時間來自聯結器的最小支援的可變重新整理率。

驅動程式可能會在這些最小和最大邊界內設定進一步的限制。

游標熱點屬性

HOTSPOT_X:用於設定滑鼠熱點 x 偏移量的屬性。HOTSPOT_Y:用於設定滑鼠熱點 y 偏移量的屬性。

當平面用作游標影像以顯示滑鼠指標時,“熱點”是游標影像中預期滑鼠事件發生的位置的偏移量。

正值將熱點從游標平面的左上角向右和底部移動。

大多數顯示驅動程式不需要此資訊,因為熱點實際上未連線到螢幕上可見的任何內容。但是,這對於顯示驅動程式(如準虛擬化驅動程式(例如,qxl、vbox、virtio、vmwgfx))是必需的,這些驅動程式附加到具有滑鼠指標的使用者控制檯。由於這些控制檯通常透過網路進行遠端控制,因此否則他們必須等待向用戶顯示指標移動,直到發生完整的網路往返。必須透過網路從使用者的控制檯傳送新的滑鼠事件到虛擬輸入裝置,轉發到桌面進行處理,然後才能更新游標平面的位置並透過網路傳送回用戶的控制檯。相反,使用熱點資訊,控制檯可以預測新位置,並在確認傳入之前在那裡繪製滑鼠游標。為了正確地執行此操作,使用者的控制檯必須能夠預測桌面將如何處理滑鼠事件,這通常需要桌面的滑鼠拓撲資訊,即每個 CRTC 在滑鼠座標空間中的位置。這通常使用一些特定於驅動程式的方法傳送到準虛擬化驅動程式,然後驅動程式透過虛擬顯示裝置或虛擬機器管理程式將其轉發到控制檯。

通常假設一次只有使用一個游標平面,並且桌面正在將所有滑鼠裝置饋送到同一個全域性指標中。需要此功能的準虛擬化驅動程式應僅公開單個游標平面,或者找到其他一些方法與支援多個指標的使用者空間桌面進行協調。如果設定了熱點屬性,則假定游標平面僅用於顯示滑鼠游標影像,因此組合游標平面 + 偏移量的位置可用於與來自滑鼠裝置的輸入進行協調。

然後,游標將繪製在 CRTC 控制檯中平面所在的位置,或者作為使用者控制檯上與其桌面滑鼠位置相對應的自由浮動游標平面。

希望在公開熱點屬性的驅動程式上正確工作的 DRM 客戶端應通告 DRM_CLIENT_CAP_CURSOR_PLANE_HOTSPOT。在未專門處理游標平面的驅動程式上設定此屬性將返回 EOPNOTSUPP,使用者空間可以使用該屬性來衡量其執行的硬體/驅動程式的要求。通告 DRM_CLIENT_CAP_CURSOR_PLANE_HOTSPOT 意味著使用者空間客戶端將正確設定熱點屬性。

現有 KMS 屬性

下表給出了各種模組/驅動程式公開的 DRM 屬性的說明。由於此表非常笨拙,因此請勿在此處新增任何新屬性。而是在上面的部分中記錄它們。

所有者模組/驅動程式

屬性名稱

型別

屬性值

附加的物件

描述/限制

DVI-I

“子聯結器”

列舉

{ “未知”, “DVI-D”, “DVI-A” }

聯結器

待定

“選擇子聯結器”

列舉

{ “自動”, “DVI-D”, “DVI-A” }

聯結器

待定

電視

“子聯結器”

列舉

{ “未知”, “複合”, “SVIDEO”, “分量”, “SCART” }

聯結器

待定

“選擇子聯結器”

列舉

{ “自動”, “複合”, “SVIDEO”, “分量”, “SCART” }

聯結器

待定

“模式”

列舉

{ “NTSC_M”, “NTSC_J”, “NTSC_443”, “PAL_B” } 等。

聯結器

待定

“左邊距”

範圍

最小=0, 最大=100

聯結器

待定

“右邊距”

範圍

最小=0, 最大=100

聯結器

待定

“上邊距”

範圍

最小=0, 最大=100

聯結器

待定

“下邊距”

範圍

最小=0, 最大=100

聯結器

待定

“亮度”

範圍

最小=0, 最大=100

聯結器

待定

“對比度”

範圍

最小=0, 最大=100

聯結器

待定

“閃爍減少”

範圍

最小=0, 最大=100

聯結器

待定

“過掃描”

範圍

最小=0, 最大=100

聯結器

待定

“飽和度”

範圍

最小=0, 最大=100

聯結器

待定

“色調”

範圍

最小=0, 最大=100

聯結器

待定

虛擬 GPU

“建議的 X”

範圍

最小=0, 最大=0xffffffff

聯結器

用於建議聯結器的 X 偏移量的屬性

“建議的 Y”

範圍

最小=0, 最大=0xffffffff

聯結器

用於建議聯結器的 Y 偏移量的屬性

可選

“縱橫比”

列舉

{ “無”, “4:3”, “16:9” }

聯結器

待定

“音訊”

列舉

{ “強制 dvi”, “關閉”, “自動”, “開啟” }

聯結器

待定

SDVO-TV

“模式”

列舉

{ “NTSC_M”, “NTSC_J”, “NTSC_443”, “PAL_B” } 等。

聯結器

待定

“左邊距”

範圍

最小=0, 最大= SDVO 相關

聯結器

待定

“右邊距”

範圍

最小=0, 最大= SDVO 相關

聯結器

待定

“上邊距”

範圍

最小=0, 最大= SDVO 相關

聯結器

待定

“下邊距”

範圍

最小=0, 最大= SDVO 相關

聯結器

待定

“hpos”

範圍

最小=0, 最大= SDVO 相關

聯結器

待定

“vpos”

範圍

最小=0, 最大= SDVO 相關

聯結器

待定

“對比度”

範圍

最小=0, 最大= SDVO 相關

聯結器

待定

“飽和度”

範圍

最小=0, 最大= SDVO 相關

聯結器

待定

“色調”

範圍

最小=0, 最大= SDVO 相關

聯結器

待定

“清晰度”

範圍

最小=0, 最大= SDVO 相關

聯結器

待定

“閃爍_過濾器”

範圍

最小=0, 最大= SDVO 相關

聯結器

待定

“閃爍_過濾器_自適應”

範圍

最小=0, 最大= SDVO 相關

聯結器

待定

“閃爍_過濾器_2d”

範圍

最小=0, 最大= SDVO 相關

聯結器

待定

“電視_色度_過濾器”

範圍

最小=0, 最大= SDVO 相關

聯結器

待定

“電視_亮度_過濾器”

範圍

最小=0, 最大= SDVO 相關

聯結器

待定

“點_爬行”

範圍

最小=0, 最大=1

聯結器

待定

SDVO-TV/LVDS

“亮度”

範圍

最小=0, 最大= SDVO 相關

聯結器

待定

CDV gma-500

通用

“廣播 RGB”

列舉

{ “完整”, “有限 16:235” }

聯結器

待定

Poulsbo

通用

“背光”

範圍

最小=0, 最大=100

聯結器

待定

SDVO-TV

“模式”

列舉

{ “NTSC_M”, “NTSC_J”, “NTSC_443”, “PAL_B” } 等。

聯結器

待定

“左邊距”

範圍

最小=0, 最大= SDVO 相關

聯結器

待定

“右邊距”

範圍

最小=0, 最大= SDVO 相關

聯結器

待定

“上邊距”

範圍

最小=0, 最大= SDVO 相關

聯結器

待定

“下邊距”

範圍

最小=0, 最大= SDVO 相關

聯結器

待定

“hpos”

範圍

最小=0, 最大= SDVO 相關

聯結器

待定

“vpos”

範圍

最小=0, 最大= SDVO 相關

聯結器

待定

“對比度”

範圍

最小=0, 最大= SDVO 相關

聯結器

待定

“飽和度”

範圍

最小=0, 最大= SDVO 相關

聯結器

待定

“色調”

範圍

最小=0, 最大= SDVO 相關

聯結器

待定

“清晰度”

範圍

最小=0, 最大= SDVO 相關

聯結器

待定

“閃爍_過濾器”

範圍

最小=0, 最大= SDVO 相關

聯結器

待定

“閃爍_過濾器_自適應”

範圍

最小=0, 最大= SDVO 相關

聯結器

待定

“閃爍_過濾器_2d”

範圍

最小=0, 最大= SDVO 相關

聯結器

待定

“電視_色度_過濾器”

範圍

最小=0, 最大= SDVO 相關

聯結器

待定

“電視_亮度_過濾器”

範圍

最小=0, 最大= SDVO 相關

聯結器

待定

“點_爬行”

範圍

最小=0, 最大=1

聯結器

待定

SDVO-TV/LVDS

“亮度”

範圍

最小=0, 最大= SDVO 相關

聯結器

待定

armada

CRTC

“CSC_YUV”

列舉

{ “自動” , “CCIR601”, “CCIR709” }

CRTC

待定

“CSC_RGB”

列舉

{ “自動”, “計算機系統”, “工作室” }

CRTC

待定

覆蓋

“顏色鍵”

範圍

最小=0, 最大=0xffffff

平面

待定

“顏色鍵_最小”

範圍

最小=0, 最大=0xffffff

平面

待定

“顏色鍵_最大”

範圍

最小=0, 最大=0xffffff

平面

待定

“顏色鍵_值”

範圍

最小=0, 最大=0xffffff

平面

待定

“顏色鍵_alpha”

範圍

最小=0, 最大=0xffffff

平面

待定

“顏色鍵_模式”

列舉

{ “已停用”, “Y 分量”, “U 分量” , “V 分量”, “RGB”, “R 分量”, “G 分量”, “B 分量” }

平面

待定

“亮度”

範圍

最小=0, 最大=256 + 255

平面

待定

“對比度”

範圍

最小=0, 最大=0x7fff

平面

待定

“飽和度”

範圍

最小=0, 最大=0x7fff

平面

待定

exynos

CRTC

“模式”

列舉

{ “正常”, “空白” }

CRTC

待定

i2c/ch7006_drv

通用

“比例”

範圍

最小=0, 最大=2

聯結器

待定

電視

“模式”

列舉

{ “PAL”, “PAL-M”,”PAL-N”}, ”PAL-Nc” , “PAL-60”, “NTSC-M”, “NTSC-J” }

聯結器

待定

nouveau

NV10 覆蓋

“顏色鍵”

範圍

最小=0, 最大=0x01ffffff

平面

待定

“對比度”

範圍

最小=0, 最大=8192-1

平面

待定

“亮度”

範圍

最小=0, 最大=1024

平面

待定

“色調”

範圍

最小=0, 最大=359

平面

待定

“飽和度”

範圍

最小=0, 最大=8192-1

平面

待定

“iturbt_709”

範圍

最小=0, 最大=1

平面

待定

Nv04 覆蓋

“顏色鍵”

範圍

最小=0, 最大=0x01ffffff

平面

待定

“亮度”

範圍

最小=0, 最大=1024

平面

待定

顯示

“抖動模式”

列舉

{ “自動”, “關閉”, “開啟” }

聯結器

待定

“抖動深度”

列舉

{ “自動”, “關閉”, “開啟”, “靜態 2x2”, “動態 2x2”, “時序” }

聯結器

待定

“底邊掃描”

列舉

{ “自動”, “6 bpc”, “8 bpc” }

聯結器

待定

“底邊掃描水平邊框”

範圍

最小值=0, 最大值=128

聯結器

待定

“底邊掃描垂直邊框”

範圍

最小值=0, 最大值=128

聯結器

待定

“鮮豔色調”

範圍

最小值=0, 最大值=180

聯結器

待定

“顏色鮮豔度”

範圍

最小值=0, 最大值=200

聯結器

待定

omap

通用

“z序”

範圍

最小值=0, 最大值=3

CRTC, 平面

待定

qxl

通用

“熱插拔模式更新”

範圍

最小=0, 最大=1

聯結器

待定

radeon

DVI-I

“一致性”

範圍

最小=0, 最大=1

聯結器

待定

DAC 使能載入檢測

“載入檢測”

範圍

最小=0, 最大=1

聯結器

待定

電視標準

“電視標準”

列舉

{ “ntsc”, “pal”, “pal-m”, “pal-60”, “ntsc-j” , “scart-pal”, “pal-cn”, “secam” }

聯結器

待定

傳統 TMDS PLL 檢測

“tmds_pll”

列舉

{ “驅動”, “bios” }

待定

底邊掃描

“底邊掃描”

列舉

{ “關閉”, “開啟”, “自動” }

聯結器

待定

“底邊掃描水平邊框”

範圍

最小值=0, 最大值=128

聯結器

待定

“底邊掃描垂直邊框”

範圍

最小值=0, 最大值=128

聯結器

待定

音訊

“音訊”

列舉

{ “關閉”, “開啟”, “自動” }

聯結器

待定

FMT 抖動

“抖動”

列舉

{ “關閉”, “開啟” }

聯結器

待定

“顏色鍵”

範圍

最小=0, 最大=0x01ffffff

平面

待定

垂直消隱

從計算機的角度來看,每次監視器顯示新幀時,掃描引擎都會“掃描輸出”從上到下顯示的影像,一次一行畫素。當前行的畫素稱為當前掃描線。

除了顯示器的可視區域外,通常還有一些額外的掃描線實際上並未顯示在螢幕上。 這些額外的掃描線不包含影像資料,偶爾用於音訊和資訊幀等功能。 由這些掃描線組成的區域稱為垂直消隱區域,或簡稱為 vblank。

作為歷史參考,垂直消隱期的設計是為了讓電子槍(在 CRT 上)有足夠的時間移回螢幕頂部,以便開始掃描下一幀。 水平消隱期也是如此。 它們的設計目的是為了讓電子槍有足夠的時間移回螢幕的另一側,以便開始掃描下一條掃描線。

physical →   ⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽
top of      |                                        |
display     |                                        |
            |               New frame                |
            |                                        |
            |↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓|
            |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~| ← Scanline,
            |↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓|   updates the
            |                                        |   frame as it
            |                                        |   travels down
            |                                        |   ("scan out")
            |               Old frame                |
            |                                        |
            |                                        |
            |                                        |
            |                                        |   physical
            |                                        |   bottom of
vertical    |⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽| ← display
blanking    ┆xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx┆
region   →  ┆xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx┆
            ┆xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx┆
start of →   ⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽
new frame

“顯示器的物理頂部”是高精度/校正時間戳的參考點。

在許多顯示硬體上,程式設計需要在垂直消隱期間生效,以便可以安全地更改伽瑪、要掃描輸出的影像緩衝區等設定,而不會在螢幕上顯示任何視覺偽影。 在一些嚴苛的硬體中,某些程式設計必須在同一個 vblank 中開始和結束。 為了幫助進行硬體程式設計的計時,通常會提供一箇中斷來通知驅動程式何時可以開始更新暫存器。 在這種情況下,中斷被稱為 vblank 中斷。

vblank 中斷可能會在不同的時間點觸發,具體取決於硬體。 某些硬體實現將在新幀開始時觸發中斷,而其他實現將在不同的時間點觸發中斷。

垂直消隱在圖形渲染中起著重要作用。 要實現無撕裂顯示,使用者必須將頁面翻轉和/或渲染與垂直消隱同步。 DRM API 提供 ioctl 來執行與垂直消隱同步的頁面翻轉,並等待垂直消隱。

DRM 核心處理大部分垂直消隱管理邏輯,其中包括過濾掉虛假中斷、保持無競爭消隱計數器、處理計數器迴繞和重置以及保持使用計數。 它依靠驅動程式生成垂直消隱中斷,並可以選擇提供硬體垂直消隱計數器。

驅動程式必須透過呼叫 drm_vblank_init() 初始化垂直消隱處理核心。 至少,驅動程式需要實現 drm_crtc_funcs.enable_vblankdrm_crtc_funcs.disable_vblank,並呼叫 drm_crtc_handle_vblank() 以獲得有效的 vblank 支援。

垂直消隱中斷可以由 DRM 核心或驅動程式本身啟用(例如,處理頁面翻轉操作)。 DRM 核心維護一個垂直消隱使用計數,以確保在使用者仍然需要時不會停用中斷。 要增加使用計數,驅動程式呼叫 drm_crtc_vblank_get() 並使用 drm_crtc_vblank_put() 再次釋放 vblank 引用。 在這兩個呼叫之間,保證啟用 vblank 中斷。

在許多硬體上,無法以無競爭的方式停用 vblank 中斷,請參閱 drm_vblank_crtc_config.disable_immediatedrm_driver.max_vblank_count。 在這種情況下,vblank 核心僅在計時器到期後才停用 vblank,可以透過 vblankoffdelay 模組引數配置計時器。

對於不支援垂直消隱中斷的硬體的驅動程式不得呼叫 drm_vblank_init()。 對於此類驅動程式,原子輔助程式將自動生成偽 vblank 事件作為顯示更新的一部分。 驅動程式還可以透過啟用和停用 struct drm_crtc_state.no_vblank 來控制此功能。

垂直消隱和中斷處理函式參考

struct drm_pending_vblank_event

掛起的 vblank 事件跟蹤

定義:

struct drm_pending_vblank_event {
    struct drm_pending_event base;
    unsigned int pipe;
    u64 sequence;
    union {
        struct drm_event base;
        struct drm_event_vblank vbl;
        struct drm_event_crtc_sequence seq;
    } event;
};

成員

基本

用於跟蹤掛起的 DRM 事件的基本結構。

管道

此事件所對應的 drm_crtcdrm_crtc_index()

序列

應該觸發幀事件的時間

event

將傳送到使用者空間的實際事件。

event.base

DRM 事件基類。

event.vbl

透過 MODE_PAGE_FLIP 或 MODE_ATOMIC IOCTL 請求的 vblank 事件的事件有效負載。 也由傳統的 WAIT_VBLANK IOCTL 生成,但新的使用者空間應改用 MODE_QUEUE_SEQUENCE 和 event.seq

event.seq

MODE_QUEUEU_SEQUENCE IOCTL 的事件有效負載。

struct drm_vblank_crtc_config

CRTC 的 vblank 配置

定義:

struct drm_vblank_crtc_config {
    int offdelay_ms;
    bool disable_immediate;
};

成員

offdelay_ms

Vblank 關閉延遲(以毫秒為單位),用於確定 drm_vblank_crtc.disable_timer 在停用之前等待的時間。

預設為 drm_crtc_vblank_on() 中的 drm_vblank_offdelay 值。

disable_immediate

有關立即 vblank 停用的確切語義,請參閱 drm_device.vblank_disable_immediate

此外,這會跟蹤每個 crtc 的停用立即值,以防它需要不同於給定裝置的預設值。

預設為 drm_crtc_vblank_on() 中的 drm_device.vblank_disable_immediate 的值。

struct drm_vblank_crtc

CRTC 的 vblank 跟蹤

定義:

struct drm_vblank_crtc {
    struct drm_device *dev;
    wait_queue_head_t queue;
    struct timer_list disable_timer;
    seqlock_t seqlock;
    atomic64_t count;
    ktime_t time;
    atomic_t refcount;
    u32 last;
    u32 max_vblank_count;
    unsigned int inmodeset;
    unsigned int pipe;
    int framedur_ns;
    int linedur_ns;
    struct drm_display_mode hwmode;
    struct drm_vblank_crtc_config config;
    bool enabled;
    struct kthread_worker *worker;
    struct list_head pending_work;
    wait_queue_head_t work_wait_queue;
};

成員

dev

指向 drm_device 的指標。

佇列

vblank 等待者的等待佇列。

disable_timer

用於延遲 vblank 停用滯後邏輯的停用計時器。 Vblank 停用透過 drm_vblank_crtc_config.offdelay_msdrm_device.max_vblank_count 值的設定來控制。

seqlock

保護 vblank 計數和時間。

count

當前軟體 vblank 計數器。

請注意,對於給定的 vblank 計數器值,drm_crtc_handle_vblank()drm_crtc_vblank_count()drm_crtc_vblank_count_and_time() 提供了一個屏障:在呼叫 drm_crtc_handle_vblank() 之前完成的任何寫入對於後面的函式的呼叫者都是可見的,前提是 vblank 計數相同或更高。

重要提示:此保證需要屏障,因此切勿直接訪問此欄位。 請改用 drm_crtc_vblank_count()

時間

count 對應的 Vblank 時間戳。

refcount

vblank 中斷的使用者/等待者數量。 只有當此引用計數達到 0 時,才能使用 disable_timer 停用硬體中斷。

最後

drm_device.vbl_lock 保護,用於迴繞處理。

max_vblank_count

此 crtc 的 vblank 暫存器的最大值。 此值 +1 將導致 vblank 暫存器迴繞。 它由 vblank 核心用於處理迴繞。

如果設定為零,則 vblank 核心將嘗試透過高精度時間戳猜測透過停用 vblank 中斷時經過的 vblank。 這種方法會因較長時間內的小競爭和不精確而受到影響,因此始終建議公開硬體 vblank 計數器。

這是透過 drm_crtc_set_max_vblank_count() 設定的執行時可配置的每個 crtc 最大值。 如果使用此方法,則驅動程式必須將裝置範圍的 drm_device.max_vblank_count 保留為零。

如果非零,則必須設定 drm_crtc_funcs.get_vblank_counter

inmodeset

跟蹤由於模式設定而停用 vblank 的情況。 對於傳統驅動程式,位 2 還會額外跟蹤是否已獲取額外的臨時 vblank 引用以掩蓋硬體計數器重置/跳變。 KMS 驅動程式應改為呼叫 drm_crtc_vblank_off()drm_crtc_vblank_on(),它們顯式儲存和恢復 vblank 計數。

管道

與此結構對應的 drm_crtcdrm_crtc_index()

framedur_ns

幀/場持續時間(以納秒為單位),由 drm_crtc_vblank_helper_get_vblank_timestamp() 使用,並由 drm_calc_timestamping_constants() 計算。

linedur_ns

行持續時間(以納秒為單位),由 drm_crtc_vblank_helper_get_vblank_timestamp() 使用,並由 drm_calc_timestamping_constants() 計算。

hwmode

當前硬體顯示模式的快取。 僅當設定了 enabled 時才有效。 這由 drm_crtc_vblank_helper_get_vblank_timestamp() 等輔助程式使用。 我們不能僅僅透過檢視 drm_crtc_state.adjusted_mode 等來訪問硬體模式,因為從中斷上下文很難獲得該模式。

配置

儲存給定 CRTC 的 vblank 配置值。 另請參閱 drm_crtc_vblank_on_config()

已啟用

跟蹤相應 drm_crtc 的啟用狀態,以避免雙重停用,從而破壞儲存的狀態。 使用原子 KMS 的驅動程式需要這樣做,因為這些驅動程式可能會多次執行其 CRTC 停用功能。

worker

用於執行 vblank 工作的 kthread_worker

pending_work

等待未來 vblank 的計劃的 drm_vblank_work 項的列表。

work_wait_queue

用於發出訊號,表明 drm_vblank_work 項已完成執行或已被取消的等待佇列。

描述

此結構跟蹤一個 CRTC 的 vblank 狀態。

請注意,由於歷史原因 - vblank 處理程式碼仍然與傳統/非 kms 驅動程式共享 - 這是一個獨立的結構,不直接連線到 struct drm_crtc。 但是,所有公共介面函式都採用 struct drm_crtc 以隱藏此實現細節。

u64 drm_crtc_accurate_vblank_count(struct drm_crtc *crtc)

檢索主 vblank 計數器

引數

struct drm_crtc *crtc

要檢索哪個計數器

描述

此函式類似於 drm_crtc_vblank_count(),但此函式使用高精度時間戳支援進行插值以處理與 vblank 中斷的競爭。

這對於可以獲取掃描輸出位置但沒有硬體幀計數器的硬體最有用。

int drm_vblank_init(struct drm_device *dev, unsigned int num_crtcs)

初始化 vblank 支援

引數

struct drm_device *dev

DRM 裝置

unsigned int num_crtcs

dev 支援的 CRTC 數量

描述

此函式初始化 num_crtcs 顯示管道的 vblank 支援。 清理由透過 drmm_add_action_or_reset() 新增的清理函式自動處理。

返回

成功時為零,失敗時為負錯誤程式碼。

bool drm_dev_has_vblank(const struct drm_device *dev)

測試是否已初始化裝置的 vblank

引數

const struct drm_device *dev

裝置

描述

驅動程式可以呼叫此函式來測試是否已初始化裝置的 vblank 支援。 對於大多數硬體,這意味著也可以啟用 vblank。

原子輔助程式使用此函式來初始化 drm_crtc_state.no_vblank。 另請參閱 drm_atomic_helper_check_modeset()

返回

如果已初始化給定裝置的 vblank,則為 True;否則為 False。

wait_queue_head_t *drm_crtc_vblank_waitqueue(struct drm_crtc *crtc)

獲取 CRTC 的 vblank 等待佇列

引數

struct drm_crtc *crtc

要檢索哪個 CRTC 的 vblank 等待佇列

描述

此函式返回指向 CRTC 的 vblank 等待佇列的指標。 驅動程式可以使用它來使用 wait_event() 和相關函式實現 vblank 等待。

void drm_calc_timestamping_constants(struct drm_crtc *crtc, const struct drm_display_mode *mode)

計算垂直消隱時間戳常量

引數

struct drm_crtc *crtc

drm_crtc,其時間戳常量應被更新。

const struct drm_display_mode *mode

包含掃描輸出時序的顯示模式

描述

計算並存儲各種常量,這些常量稍後會被垂直消隱和交換完成時間戳使用,例如,透過 drm_crtc_vblank_helper_get_vblank_timestamp()。它們源自 CRTC 的真實掃描輸出時序,因此它們會考慮諸如面板縮放或其他調整之類的事情。

bool drm_crtc_vblank_helper_get_vblank_timestamp_internal(struct drm_crtc *crtc, int *max_error, ktime_t *vblank_time, bool in_vblank_irq, drm_vblank_get_scanout_position_func get_scanout_position)

精確的垂直消隱時間戳輔助函式

引數

struct drm_crtc *crtc

要檢索其垂直消隱時間戳的 CRTC

int *max_error

時間戳中允許的最大誤差(納秒)。返回時包含時間戳的真實最大誤差

ktime_t *vblank_time

指向應接收時間戳的時間的指標

bool in_vblank_irq

drm_crtc_handle_vblank() 呼叫時為 True。如果設定了標誌,某些驅動程式需要應用一些針對 gpu 特定垂直空白 irq 怪癖的解決方法。

drm_vblank_get_scanout_position_func get_scanout_position

用於檢索掃描輸出位置的回撥函式。參見 struct drm_crtc_helper_funcs.get_scanout_position。

描述

從給定的 drm_display_mode 時序和 CRTC 的當前影片掃描輸出位置實現精確的垂直消隱時間戳計算。

當前實現僅處理標準影片模式。對於雙掃描和隔行模式,驅動程式應該調整硬體模式(從 drm_crtc_state.adjusted 模式獲取,適用於原子模式設定驅動程式)以匹配報告的掃描輸出位置。

請注意,原子驅動程式必須在啟用 CRTC 之前呼叫 drm_calc_timestamping_constants()。原子輔助函式已經在 drm_atomic_helper_calc_timestamping_constants() 中處理了這個問題。

返回

成功時返回 true,失敗時返回 false,即無法獲取精確的時間戳。

bool drm_crtc_vblank_helper_get_vblank_timestamp(struct drm_crtc *crtc, int *max_error, ktime_t *vblank_time, bool in_vblank_irq)

精確的垂直消隱時間戳輔助函式

引數

struct drm_crtc *crtc

要檢索其垂直消隱時間戳的 CRTC

int *max_error

時間戳中允許的最大誤差(納秒)。返回時包含時間戳的真實最大誤差

ktime_t *vblank_time

指向應接收時間戳的時間的指標

bool in_vblank_irq

drm_crtc_handle_vblank() 呼叫時為 True。如果設定了標誌,某些驅動程式需要應用一些針對 gpu 特定垂直空白 irq 怪癖的解決方法。

描述

從給定的 drm_display_mode 時序和 CRTC 的當前影片掃描輸出位置實現精確的垂直消隱時間戳計算。如果實現了 drm_crtc_helper_funcs.get_scanout_position,則可以直接用作 KMS 驅動程式的 drm_crtc_funcs.get_vblank_timestamp 實現。

當前實現僅處理標準影片模式。對於雙掃描和隔行模式,驅動程式應該調整硬體模式(從 drm_crtc_state.adjusted 模式獲取,適用於原子模式設定驅動程式)以匹配報告的掃描輸出位置。

請注意,原子驅動程式必須在啟用 CRTC 之前呼叫 drm_calc_timestamping_constants()。原子輔助函式已經在 drm_atomic_helper_calc_timestamping_constants() 中處理了這個問題。

返回

成功時返回 true,失敗時返回 false,即無法獲取精確的時間戳。

u64 drm_crtc_vblank_count(struct drm_crtc *crtc)

檢索 “cooked” 垂直消隱計數器值

引數

struct drm_crtc *crtc

要檢索哪個計數器

描述

獲取 “cooked” 垂直消隱計數器值,該值表示自系統啟動以來發生的垂直消隱事件的數量,包括由於模式設定活動而丟失的事件。請注意,此計時器對於競爭的垂直消隱中斷是不正確的(因為它只報告軟體垂直消隱計數器),有關此類用例,請參見 drm_crtc_accurate_vblank_count()

請注意,對於給定的垂直消隱計數器值,drm_crtc_handle_vblank()drm_crtc_vblank_count()drm_crtc_vblank_count_and_time() 提供了一個屏障:在呼叫 drm_crtc_handle_vblank() 之前完成的任何寫入對於後一個函式的呼叫者都是可見的,如果垂直消隱計數是相同或更高。

另請參見 drm_vblank_crtc.count

返回

軟體垂直消隱計數器。

u64 drm_crtc_vblank_count_and_time(struct drm_crtc *crtc, ktime_t *vblanktime)

檢索 “cooked” 垂直消隱計數器值以及對應於該垂直消隱計數器值的系統時間戳

引數

struct drm_crtc *crtc

要檢索哪個計數器

ktime_t *vblanktime

指向接收垂直消隱時間戳的時間的指標。

描述

獲取 “cooked” 垂直消隱計數器值,該值表示自系統啟動以來發生的垂直消隱事件的數量,包括由於模式設定活動而丟失的事件。返回與當前垂直消隱計數器值相對應的垂直消隱間隔時間的相應系統時間戳。

請注意,對於給定的垂直消隱計數器值,drm_crtc_handle_vblank()drm_crtc_vblank_count()drm_crtc_vblank_count_and_time() 提供了一個屏障:在呼叫 drm_crtc_handle_vblank() 之前完成的任何寫入對於後一個函式的呼叫者都是可見的,如果垂直消隱計數是相同或更高。

另請參見 drm_vblank_crtc.count

int drm_crtc_next_vblank_start(struct drm_crtc *crtc, ktime_t *vblanktime)

計算下一個垂直消隱的時間

引數

struct drm_crtc *crtc

要計算下一個垂直消隱時間的 crtc

ktime_t *vblanktime

指向接收下一個垂直消隱時間戳的時間的指標。

描述

根據上一個垂直消隱時間和幀持續時間計算下一個垂直消隱週期開始的預期時間

void drm_crtc_arm_vblank_event(struct drm_crtc *crtc, struct drm_pending_vblank_event *e)

在頁面翻轉後準備垂直消隱事件

引數

struct drm_crtc *crtc

垂直消隱事件的源 CRTC

struct drm_pending_vblank_event *e

要傳送的事件

描述

許多驅動程式需要為下一個垂直消隱中斷生成垂直消隱事件。例如,當頁面翻轉中斷在頁面翻轉準備好時發生,而不是在實際在下一個垂直消隱週期內執行時發生。此輔助函式實現了完全所需的垂直消隱準備行為。

  1. 驅動程式將新的硬體狀態提交到垂直消隱同步的暫存器中。

  2. 發生垂直消隱,提交硬體狀態。此外,相應的垂直消隱中斷被觸發並由中斷處理程式完全處理。

  3. 原子提交操作繼續呼叫 drm_crtc_arm_vblank_event()

  4. 該事件僅為下一個垂直消隱傳送,這是錯誤的。

當驅動程式在寫出新的硬體狀態之前呼叫 drm_crtc_arm_vblank_event() 時,可能會發生等效的競爭。

使此方法安全工作的唯一方法是阻止垂直消隱觸發(以及硬體提交任何其他內容),直到整個原子提交序列執行完成。如果硬體沒有這樣的功能(例如,使用 “go” 位),則使用此函式是不安全的。相反,驅動程式需要透過呼叫 drm_crtc_send_vblank_event() 從其中斷處理程式手動傳送事件,並確保硬體提交原子更新時沒有可能的競爭。

呼叫者必須為事件 e 持有一個由 drm_crtc_vblank_get() 獲取的垂直消隱引用,該引用將在下一個垂直消隱到達時被丟棄。

注意

使用此方法傳送作為原子提交的一部分的 drm_crtc_state.event 的驅動程式必須確保下一個垂直消隱與原子提交提交到硬體的時間完全相同。此函式本身防止下一個垂直消隱中斷與此函式呼叫或原子提交操作發生競爭。一個可能的序列可能是

void drm_crtc_send_vblank_event(struct drm_crtc *crtc, struct drm_pending_vblank_event *e)

用於在頁面翻轉後傳送垂直消隱事件的輔助函式

引數

struct drm_crtc *crtc

垂直消隱事件的源 CRTC

struct drm_pending_vblank_event *e

要傳送的事件

描述

更新事件的序列號和時間戳以用於最近處理的垂直消隱,並將其傳送到使用者空間。呼叫者必須持有事件鎖。

有關可以在某些情況下使用的輔助函式,尤其是用於傳送原子提交操作的事件,請參見 drm_crtc_arm_vblank_event()

int drm_crtc_vblank_get(struct drm_crtc *crtc)

獲取垂直消隱事件的引用計數

引數

struct drm_crtc *crtc

要擁有的 CRTC

描述

獲取垂直消隱事件的引用計數,以避免在使用時停用它們。

返回

成功時為零,失敗時為負錯誤程式碼。

void drm_crtc_vblank_put(struct drm_crtc *crtc)

放棄垂直消隱事件的所有權

引數

struct drm_crtc *crtc

要放棄的計數器

描述

釋放給定垂直消隱計數器的所有權,如果可能,則關閉中斷。在 drm_vblank_crtc_config.offdelay_ms 毫秒後停用中斷。

void drm_wait_one_vblank(struct drm_device *dev, unsigned int pipe)

等待一個垂直消隱

引數

struct drm_device *dev

DRM 裝置

unsigned int pipe

CRTC 索引

描述

這會等待 pipe 上的一個垂直消隱過去,使用 irq 驅動程式介面。當停用 pipe 的垂直消隱 irq 時,例如由於缺少驅動程式支援或由於 crtc 關閉,呼叫此函式會失敗。

這是 drm_crtc_wait_one_vblank() 的舊版本。

void drm_crtc_wait_one_vblank(struct drm_crtc *crtc)

等待一個垂直消隱

引數

struct drm_crtc *crtc

DRM crtc

描述

這會等待 crtc 上的一個垂直消隱過去,使用 irq 驅動程式介面。當停用 crtc 的垂直消隱 irq 時,例如由於缺少驅動程式支援或由於 crtc 關閉,呼叫此函式會失敗。

void drm_crtc_vblank_off(struct drm_crtc *crtc)

停用 CRTC 上的垂直消隱事件

引數

struct drm_crtc *crtc

有問題的 CRTC

描述

驅動程式可以使用此函式在停用 crtc 時關閉垂直消隱中斷處理。此函式確保儲存最新的垂直消隱幀計數,以便 drm_vblank_on 可以再次恢復它。

當硬體垂直消隱計數器可以被重置時,例如在掛起或通常停用 crtc 時,驅動程式必須使用此函式。

void drm_crtc_vblank_reset(struct drm_crtc *crtc)

在 CRTC 上將垂直消隱狀態重置為關閉

引數

struct drm_crtc *crtc

有問題的 CRTC

描述

驅動程式可以使用此函式在載入時將垂直消隱狀態重置為關閉。驅動程式應將此函式與 drm_crtc_vblank_off()drm_crtc_vblank_on() 函式一起使用。與 drm_crtc_vblank_off() 相比,不同之處在於此函式不儲存垂直消隱計數器,因此不需要呼叫任何驅動程式掛鉤。

這對於恢復驅動程式狀態(例如,在驅動程式載入時或恢復時)非常有用。

void drm_crtc_set_max_vblank_count(struct drm_crtc *crtc, u32 max_vblank_count)

配置 hw 最大垂直消隱計數器值

引數

struct drm_crtc *crtc

有問題的 CRTC

u32 max_vblank_count

最大硬體垂直消隱計數器值

描述

在執行時更新 crtc 的最大硬體垂直消隱計數器值。對於硬體垂直消隱計數器的操作取決於當前活動的顯示配置的硬體很有用。

例如,如果硬體垂直消隱計數器在特定聯結器處於活動狀態時不工作,則最大值可以設定為零。並且當該特定聯結器不處於活動狀態時,最大值可以再次設定為適當的非零值。

如果使用,必須在 drm_vblank_on() 之前呼叫。

void drm_crtc_vblank_on_config(struct drm_crtc *crtc, const struct drm_vblank_crtc_config *config)

使用自定義配置選項啟用 CRTC 上的垂直消隱事件

引數

struct drm_crtc *crtc

有問題的 CRTC

const struct drm_vblank_crtc_config *config

垂直消隱配置值

描述

請參閱 drm_crtc_vblank_on()。 此外,此函式允許你為給定的 CRTC 提供自定義的垂直消隱配置。

請注意,config 會被複制,指標不需要在此函式呼叫後仍然有效。有關引數的詳細資訊,請參閱 struct drm_vblank_crtc_config

void drm_crtc_vblank_on(struct drm_crtc *crtc)

啟用 CRTC 上的垂直消隱事件

引數

struct drm_crtc *crtc

有問題的 CRTC

描述

此函式恢復使用 drm_crtc_vblank_off() 捕獲的垂直消隱中斷狀態,通常在啟用 crtc 時呼叫。請注意,對 drm_crtc_vblank_on()drm_crtc_vblank_off() 的呼叫可能是不平衡的,因此也可以在驅動程式載入程式碼中無條件呼叫,以反映 crtc 的當前硬體狀態。

請注意,與 drm_crtc_vblank_on_config() 不同,此處使用預設值。

void drm_crtc_vblank_restore(struct drm_crtc *crtc)

估計丟失的垂直消隱並更新垂直消隱計數。

引數

struct drm_crtc *crtc

有問題的 CRTC

描述

電源管理功能可能會導致在垂直消隱停用和啟用之間重置幀計數器。 驅動程式可以在他們的 drm_crtc_funcs.enable_vblank 實現中使用此函式來估計自上次 drm_crtc_funcs.disable_vblank 以來丟失的垂直消隱,使用時間戳並更新垂直消隱計數器。

請注意,驅動程式必須具有無競爭的高精度時間戳支援,即 drm_crtc_funcs.get_vblank_timestamp 必須被連線,並且 drm_vblank_crtc_config.disable_immediate 必須設定為指示時間戳函式相對於垂直消隱硬體計數器增量是無競爭的。

bool drm_handle_vblank(struct drm_device *dev, unsigned int pipe)

處理垂直消隱事件

引數

struct drm_device *dev

DRM 裝置

unsigned int pipe

發生此事件的 CRTC 的索引

描述

驅動程式應在其垂直消隱中斷處理程式中呼叫此例程,以更新垂直消隱計數器併發送任何可能掛起的訊號。

這是 drm_crtc_handle_vblank() 的舊版本。

bool drm_crtc_handle_vblank(struct drm_crtc *crtc)

處理垂直消隱事件

引數

struct drm_crtc *crtc

發生此事件的位置

描述

驅動程式應在其垂直消隱中斷處理程式中呼叫此例程,以更新垂直消隱計數器併發送任何可能掛起的訊號。

這是 drm_handle_vblank() 的原生 KMS 版本。

請注意,對於給定的垂直消隱計數器值,drm_crtc_handle_vblank()drm_crtc_vblank_count()drm_crtc_vblank_count_and_time() 提供了一個屏障:在呼叫 drm_crtc_handle_vblank() 之前完成的任何寫入對於後一個函式的呼叫者都是可見的,如果垂直消隱計數是相同或更高。

另請參見 drm_vblank_crtc.count

返回

如果事件成功處理則為 True,失敗則為 False。

垂直消隱工作

許多 DRM 驅動程式需要以時間敏感的方式程式設計硬體,很多時候需要在掃描輸出的某個區域內開始和完成,且具有截止日期。 完成此操作最安全的方法通常是在驅動程式的 IRQ 處理程式中簡單地執行所述時間敏感的程式設計,這允許驅動程式避免在這些關鍵區域中被搶佔。 或者更好的是,硬體甚至可以獨立於 CPU 處理此類時間關鍵的程式設計。

雖然有相當數量的硬體被設計為 CPU 不需要關注極其時間敏感的程式設計,但在少數情況下這是不可避免的。 一些不容情的硬體可能要求某些時間敏感的程式設計完全由 CPU 處理,並且所述程式設計甚至可能花費太長時間而無法在 IRQ 處理程式中處理。 另一種這樣的情況是,驅動程式需要執行一項需要在特定掃描輸出週期內完成的任務,但可能會阻塞,因此無法在 IRQ 上下文中處理。 所有這些情況都無法在 Linux 中完美解決,因為我們不是即時核心,因此如果排程程式決定搶佔我們,它可能會導致我們錯過截止日期。 但對於某些驅動程式來說,如果我們能將我們被搶佔的可能性降低到絕對最低限度,那就足夠好了。

這就是 drm_vblank_work 的用武之地。 drm_vblank_work 提供了一個簡單的通用延遲工作實現,它將工作執行延遲到特定的垂直消隱過去之後,然後在即時優先順序執行工作。 即使系統處於高負載狀態,這也能以最佳方式按時執行時間敏感的硬體程式設計。 drm_vblank_work 還支援重新排程,以便可以輕鬆實現自我重新武裝的工作項。

垂直消隱工作函式參考

struct drm_vblank_work

延遲的工作項,它會延遲到目標垂直消隱過去之後,然後在 IRQ 上下文之外以即時優先順序執行。

定義:

struct drm_vblank_work {
    struct kthread_work base;
    struct drm_vblank_crtc *vblank;
    u64 count;
    int cancelling;
    struct list_head node;
};

成員

基本

將由 drm_vblank_crtc.worker 執行的基礎 kthread_work 項。 驅動程式不應直接與此互動,而應依賴 drm_vblank_work_init() 來初始化它。

vblank

指向此工作項所屬的 drm_vblank_crtc 的指標。

count

此工作將執行的目標垂直消隱。 驅動程式不應直接修改此值,而應使用 drm_vblank_work_schedule()

cancelling

當前正在執行的 drm_vblank_work_cancel_sync() 呼叫的數量。 工作項在所有呼叫完成後才能重新排程。

node

此工作項在 drm_vblank_crtc.pending_work 中的位置。

描述

另請參閱: drm_vblank_work_schedule() drm_vblank_work_init() drm_vblank_work_cancel_sync() drm_vblank_work_flush() drm_vblank_work_flush_all()

to_drm_vblank_work

to_drm_vblank_work (_work)

kthread_work 中檢索相應的 drm_vblank_work

引數

_work

嵌入在 drm_vblank_work 中的 kthread_work

int drm_vblank_work_schedule(struct drm_vblank_work *work, u64 count, bool nextonmiss)

排程垂直消隱工作

引數

struct drm_vblank_work *work

要排程的垂直消隱工作

u64 count

目標垂直消隱計數

bool nextonmiss

如果錯過了目標垂直消隱,則延遲到下一個垂直消隱

描述

排程 work 以在 crtc 垂直消隱計數達到 count 後執行。

如果 crtc 垂直消隱計數已達到 count 並且 nextonmissfalse,則工作立即開始執行。

如果 crtc 垂直消隱計數已達到 count 並且 nextonmisstrue,則該工作將延遲到下一個垂直消隱(就像 count 已被指定為 crtc 垂直消隱計數 + 1 一樣)。

如果已排程 work,則此函式將使用新的 count 重新排程所述工作。 這可以用於自我重新武裝的工作項。

返回

如果 work 成功地(重新)排程則為 1,如果它已經排程或取消則為 0,或者失敗時為負錯誤程式碼。

bool drm_vblank_work_cancel_sync(struct drm_vblank_work *work)

取消垂直消隱工作並等待其完成執行

引數

struct drm_vblank_work *work

要取消的垂直消隱工作

描述

取消已排程的垂直消隱工作並等待其執行完成。

在返回時,保證 work 不再被排程或執行,即使它是自我武裝的。

返回

如果在工作開始執行之前取消了該工作,則為 True,否則為 false

void drm_vblank_work_flush(struct drm_vblank_work *work)

等待已排程的垂直消隱工作完成執行

引數

struct drm_vblank_work *work

要重新整理的垂直消隱工作

描述

等待 work 完成一次執行。

void drm_vblank_work_flush_all(struct drm_crtc *crtc)

重新整理 crtc 上所有當前掛起的垂直消隱工作。

引數

struct drm_crtc *crtc

要重新整理垂直消隱工作的 crtc

描述

等待 crtc 上所有當前排隊的垂直消隱工作完成一次執行。

void drm_vblank_work_init(struct drm_vblank_work *work, struct drm_crtc *crtc, void (*func)(struct kthread_work *work))

初始化垂直消隱工作項

引數

struct drm_vblank_work *work

垂直消隱工作項

struct drm_crtc *crtc

其垂直消隱將觸發工作執行的 CRTC

void (*func)(struct kthread_work *work)

要執行的工作函式

描述

初始化特定 crtc 的垂直消隱工作項。