KMS(2)
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);
void (*output_poll_changed)(struct drm_device *dev);
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
創建一個新的framebuffer對象。核心對請求的元數據進行基本檢查,但大部分檢查留給驅動程序。詳見結構drm_mode_fb_cmd2。
為了驗證像素格式和修飾符,驅動程序可以使用drm_any_plane_has_format()來確保至少有一個平面支持請求的值。注意,如果請求沒有指定modifier,即當(mode_cmd->flags & DRM_MODE_FB_MODIFIERS) == 0,驅動程序必須首先確定實際使用的修飾符。
重要提示:如果修飾符啟用了超出fourcc像素格式代碼的額外plane,這些原來用戶空間傳遞給內核的隱含修飾符必須存儲在drm_framebuffer結構中,包括所有相關的元數據,如drm_framebuffer.pitches和drm_framebuffer.offsets。這是GETFB2 ioctl所需要的。
如果參數被認為是有效的,并且底層內存管理器中的后備存儲對象都存在,那么驅動程序分配一個新的drm_framebuffer結構,子類化以包含驅動程序特定的信息(如內部本地緩沖區對象引用)。它還需要填寫所有相關的元數據,這應該通過調用drm_helper_mode_fill_fb_struct()來完成。
初始化通過調用drm_framebuffer_init()來完成,drm_framebuffer_init()注冊framebuffer并使其他線程可以訪問它。
返回值
一個新的framebuffer,其初始引用計數為1或一個用ERR_PTR()編碼的負錯誤碼。
get_format_info
允許驅動程序返回特定fb布局的自定義格式信息(例如帶有輔助壓縮控制平面的信息)。
返回值
特定于給定fb元數據的格式信息,如果沒有找到,則為NULL。
output_poll_changed
helper程序使用回調函數通知驅動程序輸出配置已經更改。
通過helper程序實現此函數的驅動程序可以從這個鉤子調用drm_fb_helper_hotplug_changed來通知fbdev助手輸出配置發生了變化。
FIXME:除了設備級helper回調沒有虛表之外,這沒有理由是一個核心函數。
mode_valid
具體設備的顯示模式驗證。可用于拒絕永遠不支持的模式。只有設備范圍的限制可以在這里檢查。對于每個特定的對象,應該在.mode_valid()鉤子中檢查特定的crtc/encoder/bridge/connector約束。
atomic_check
這是驗證原子模式集更新的唯一鉤子。該函數必須拒絕硬件或驅動程序不支持的任何模式集和狀態更改。這包括但當然不限于:
檢查模式、幀緩沖區、縮放和放置需求等是否在硬件的限制范圍內;
檢查任何隱藏的共享資源是否超額使用。這可以共享pll,共享通道,總體內存帶寬,顯示fifo空間(在planes之間共享,甚至crtc);
檢查導出到用戶空間的虛擬化資源是否超額使用。出于各種原因,我們可以導出比實際硬件更多的planes、crtcs或encoders。一個例子是雙管道操作(通常應該從用戶空間隱藏,和硬件保持一致),plane可能需要1個硬件plane(如果它只是一個管道),2個硬件plane(當它跨越兩個管道)甚至和第二平面共享硬件平面(如果有一個其他管道要求的兼容的plane);
檢查任何過渡狀態是否可能,如果有請求,更新確實可以在vblank期間完成,而不會暫時禁用一些功能。
檢查驅動程序或硬件可能有的任何其他約束;
這個回調函數還需要正確地填寫這個更新中的drm_crtc_state,以確保drm_atomic_crtc_needs_modeset()反映了可能更新的性質,并且當且僅當在該CRTC上的一個vblank中沒有被刪除而不能應用更新時返回true。如果用戶空間在其請求中不允許更新,核心將使用這些信息來拒絕需要完整模式集的更新(即,屏蔽屏幕,或至少暫停更新相當長的時間);
驅動程序也不需要像對相應的遺留入口點那樣重復基本的輸入驗證。core在調用這個鉤子之前做這個。
請參閱atomic_commit的文檔,了解不需要在這個回調中檢查的詳盡錯誤列表。
請參閱結構drm_atomic_state的文檔,了解如何準確地描述原子模式集更新。
使用原子幫助程序的驅動程序可以使用drm_atomic_helper_check()或它導出的子函數之一來實現這個鉤子函數。
返回值
0表示成功,或者下面的負錯誤碼之一:
-EINVAL,如果違反上述任何約束。
當試圖通過drm_modeset_lock()獲取額外的drm_modeset_lock時返回-EDEADLK。
-ENOMEM,如果由于缺乏內存而分配額外的狀態子結構失敗。
-EINTR、-EAGAIN或-ERESTARTSYS,如果IOCTL需要重新啟動。這可能是由于一個待定的信號,或者因為驅動程序需要完全退出,以從異常情況下恢復,如GPU掛起。從用戶空間的角度來看,所有的錯誤都是平等對待的。
atomic_commit
這是提交原子模式集更新的唯一鉤子。核心保證在調用這個函數之前已經成功地調用了atomic_check,并且在此期間沒有任何更改。
請參閱結構drm_atomic_state的文檔,了解如何準確地描述原子模式集更新。
使用原子幫助程序的驅動程序可以使用drm_atomic_helper_commit()或它導出的子函數之一來實現這個鉤子。
非阻塞提交(用nonblock參數表示)必須在回調的上下文中做任何可能導致不成功提交的準備工作。唯一的例外是導致-EIO的硬件錯誤。但即使在這種情況下,驅動程序也必須確保顯示管道至少正在運行,以避免當pageflips不起作用時compositors崩潰。其他任何事情,特別是將更新提交給硬件,都應該在不阻塞調用者的情況下完成。對于不需要修改模式設置的更新操作,必須保證這一點。
在執行flip之前,驅動程序必須等待framebuffer的渲染完成。如果底層緩沖區是共享dma-buf,它還應該等待來自其他驅動程序的未完成的渲染完成。非阻塞提交絕不能在這個回調的上下文中等待渲染。
當原子提交完成時,應用程序可以請求得到通知。這些事件是針對每個CRTC的,可以通過drm_event提供給用戶空間的CRTC索引來區分不同的crtc.
drm核心將在每個CRTC的drm_crtc_state.event中提供一個結構drm_event。請參閱drm_crtc_state.event以獲取有關此事件的精確語義的更多細節。
驅動程序不允許關閉任何通過原子提交成功啟用的顯示管道。如果因為管道關閉而突然拒絕page flip,那么這樣做可能會導致合成器崩潰。
返回:
0表示成功,或者下面的負錯誤碼之一:
-EBUSY,如果請求了一個非阻塞更新,并且有一個較早的更新等待處理。允許驅動程序支持一個未完成更新隊列,但目前還沒有驅動程序支持。注意,如果請求同步更新,驅動程序必須等待之前的更新完成,在這種情況下,它們不允許提交失敗。
-ENOMEM,如果驅動分配內存失敗。特別地,當試圖固定framebuffer時可能會發生這種情況,而這只能在提交狀態時才能完成.
-ENOSPC,作為更通用的-ENOMEM的一個改進,表明驅動程序已經用完vram, iommu空間或幀緩沖區所需的類似GPU地址空間。
-EIO,如果硬件完全死機。
-EINTR、-EAGAIN或-ERESTARTSYS,如果IOCTL需要重新啟動。這可能是由于一個待定的信號,或者因為驅動程序需要完全卸載,以從異常情況下恢復,如GPU掛起。從用戶空間的角度來看,所有的錯誤都是平等對待的。
這個列表是詳盡無遺的。特別地,這個鉤子不允許返回-EINVAL(任何無效的請求都應該被atomic_check捕獲)或-EDEADLK(這個函數不能獲得額外的modesset鎖)。
atomic_state_alloc
這個可選的鉤子可以被那些想要繼承drm_atomic_state結構的驅動程序使用,以便能夠輕松地跟蹤它們自己的驅動私有全局狀態。如果實現了這個鉤子,驅動程序也必須實現atomic_state_clear和atomic_state_free。
不贊成繼承drm_atomic_state,而贊成使用drm_private_state和drm_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_state和drm_private_obj。
atomic_state_free
這個鉤子需要驅動程序私有資源和drm_atomic_state本身。注意,核心首先調用drm_atomic_state_clear()來避免clear和free鉤子之間的代碼重復。
實現這個的驅動程序必須調用drm_atomic_state_default_release()來釋放公共資源。
不贊成繼承drm_atomic_state,而贊成使用drm_private_state和drm_private_obj.
總結
- 上一篇: corn表达式
- 下一篇: wget命令3(转载)