[RK3399][Android7.1] Display中的DRM和Framebuffer註冊流程
阿新 • • 發佈:2019-01-06
OS: Android 7.1
Board: Firefly-RK3399
Kernel: v4.4.55
核心驅動提供了兩種方法給使用者空間完成顯示功能。
一種是通過DRM,可以通過ioctl,也可以通過使用者空間封裝的DRM庫libdrm來完成。
還有一種方法是通過以往標準的framebuffer去做,也是通過ioctl完成。
通過DRM:
驅動檔案:rockchip_drm_drv.c
註冊流程:
rockchip_drm_platform_probe ->
component_master_add_with_match ->
try_to_bring_up_master -> //當所有component被bind之後,會呼叫master ops->bind,這塊見前面drm內容介紹文章
rockchip_drm_bind ->
drm_dev_alloc -> //後續對drm的操作都包含在rockchip_drm_driver中,也包含了要註冊裝置節點對應的file_operations
drm_dev_register
rockchip_drm_driver:
static struct drm_driver rockchip_drm_driver = {
.driver_features = DRIVER_MODESET | DRIVER_GEM |
DRIVER_PRIME | DRIVER_ATOMIC |
DRIVER_RENDER,
.preclose = rockchip_drm_preclose,
.lastclose = rockchip_drm_lastclose,
.get_vblank_counter = drm_vblank_no_hw_counter,
.open = rockchip_drm_open,
.postclose = rockchip_drm_postclose,
.enable_vblank = rockchip_drm_crtc_enable_vblank,
.disable_vblank = rockchip_drm_crtc_disable_vblank,
.gem _vm_ops = &rockchip_drm_vm_ops,
.gem_free_object = rockchip_gem_free_object,
.dumb_create = rockchip_gem_dumb_create,
.dumb_map_offset = rockchip_gem_dumb_map_offset,
.dumb_destroy = drm_gem_dumb_destroy,
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
.gem_prime_import = drm_gem_prime_import,
.gem_prime_export = drm_gem_prime_export,
.gem_prime_get_sg_table = rockchip_gem_prime_get_sg_table,
.gem_prime_import_sg_table = rockchip_gem_prime_import_sg_table,
.gem_prime_vmap = rockchip_gem_prime_vmap,
.gem_prime_vunmap = rockchip_gem_prime_vunmap,
.gem_prime_mmap = rockchip_gem_mmap_buf,
#ifdef CONFIG_DEBUG_FS
.debugfs_init = rockchip_drm_debugfs_init,
.debugfs_cleanup = rockchip_drm_debugfs_cleanup,
#endif
.ioctls = rockchip_ioctls,
.num_ioctls = ARRAY_SIZE(rockchip_ioctls),
.fops = &rockchip_drm_driver_fops,
.name = DRIVER_NAME,
.desc = DRIVER_DESC,
.date = DRIVER_DATE,
.major = DRIVER_MAJOR,
.minor = DRIVER_MINOR,
};
暴露給使用者空間的file_operations是
static const struct file_operations rockchip_drm_driver_fops = {
.owner = THIS_MODULE,
.open = drm_open,
.mmap = rockchip_gem_mmap,
.poll = drm_poll,
.read = drm_read,
.unlocked_ioctl = drm_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = drm_compat_ioctl,
#endif
.release = drm_release,
};
rockchip_drm_driver裡的一些回撥通過rockchip_drm_driver_fops呼叫到,比如
drm_open -> drm_open_helper -> dev->driver->open -> rockchip_drm_open
通過framebuffer:
framebuffer的註冊也從以往的 kernel/drivers/video/rockchip 挪到了 kernel/drivers/gpu/drm/rockchip 下面。
相關檔案:
rockchip_drm_fbdev.c: rk framebuffer配置
rockchip_drm_fb.c: rk DRM fb相關
drm_fb_helper.c: DRM fb標準介面
註冊流程:
rockchip_drm_bind ->
rockchip_drm_fbdev_init ->
drm_fb_helper_init //關聯crtc
drm_fb_helper_single_add_all_connectors //關聯connector
drm_fb_helper_initial_config ->
drm_fb_helper_probe_connector_modes -> //配置connector的模式
connector->funcs->fill_modes -> //當前用的是edp panel, 所以呼叫的是analogix_dp_connector_funcs裡的函式指標
drm_helper_probe_single_connector_modes analogix_dp_core.c
drm_setup_crtcs //配置crtc
drm_fb_helper_single_fb_probe -> //註冊fb
fb_helper->funcs->fb_probe //註冊之前先配置fb_info
rockchip_drm_fbdev_create -> rockchip_drm_fbdev.c
drm_fb_helper_alloc_fbi ->
framebuffer_alloc //分配一個標準struct fb_info
rockchip_drm_framebuffer_init -> //初始化drm的framebuffer,注意不是之前說的標準顯示框架中的framebuffer, 結構是struct drm_framebuffer
rockchip_fb_alloc ->
drm_helper_mode_fill_fb_struct //獲取pitches,offsets, pixel_format等引數填充到fb中。
drm_framebuffer_init //記錄當前fb個數,並且關聯建立fb記憶體的回撥函式,主要是rockchip_drm_fb_funcs變數裡的rockchip_drm_fb_create_handle(),使用GEM分配記憶體
register_framebuffer
暴露給使用者空間的file_operations是
static struct fb_ops rockchip_drm_fbdev_ops = {
.owner = THIS_MODULE,
.fb_mmap = rockchip_fbdev_mmap,
.fb_fillrect = drm_fb_helper_cfb_fillrect,
.fb_copyarea = drm_fb_helper_cfb_copyarea,
.fb_imageblit = drm_fb_helper_cfb_imageblit,
.fb_check_var = drm_fb_helper_check_var,
.fb_set_par = drm_fb_helper_set_par,
.fb_blank = drm_fb_helper_blank,
.fb_pan_display = drm_fb_helper_pan_display,
.fb_setcmap = drm_fb_helper_setcmap,
};
在display HAL層預設使用的是DRM,可以從Android.mk中得出結論。
hardware/rockchip/hwcomposer/Android.mk:
BOARD_USES_DRM_HWCOMPOSER=true
ifeq ($(strip $(BOARD_USES_DRM_HWCOMPOSER)),true)
LOCAL_SHARED_LIBRARIES := \
libcutils \
libdrm \
......
LOCAL_SRC_FILES := \
autolock.cpp \
drmresources.cpp \
......
else
......
endif
其中也用到了libdrm庫,位於external/libdrm下面。