[RK3399][Android7.1] Display中的DRM和Framebuffer注册流程

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下面。

你可能感兴趣的:(Rk3399-Display)