Linux DRM那些事-內核代碼

掀開DRM基本概念的面紗後,咱們把「罪惡」的小手伸向DRM內核代碼。linux

注:本文和後續DRM驅動系列基於Linux4.4內核、Rockchip RK3399進行介紹。ubuntu

Linux DRM內核代碼路徑:drivers/gpu/drm。 使用ls命令查看該目錄,顯示以下:框架

root@ubuntu:/home/run/code/rockchip-bsp/kernel/drivers/gpu/drm# ls
amd               drm_atomic.c         drm_crtc_internal.h    drm_fb_cma_helper.c   drm_internal.h  drm_modes.c         drm_rect.c          exynos    mga      rcar-du   ttm
armada            drm_atomic_helper.c  drm_debugfs.c          drm_fb_helper.c       drm_ioc32.c     drm_modeset_lock.c  drm_scatter.c       fsl-dcu   mgag200  rockchip  udl
ast               drm_auth.c           drm_dma.c              drm_flip_work.c       drm_ioctl.c     drm_of.c            drm_scdc_helper.c   gma500    msm      savage    vc4
ati_pcigart.c     drm_bridge.c         drm_dp_helper.c        drm_fops.c            drm_irq.c       drm_panel.c         drm_sync_helper.c   i2c       nouveau  shmobile  vgem
atmel-hlcdc       drm_bufs.c           drm_dp_mst_topology.c  drm_gem.c             drm_legacy.h    drm_pci.c           drm_sysfs.c         i810      omapdrm  sis       via
bochs             drm_cache.c          drm_drv.c              drm_gem_cma_helper.c  drm_lock.c      drm_plane_helper.c  drm_trace.h         i915      panel    sti       virtio
bridge            drm_context.c        drm_edid.c             drm_global.c          drm_memory.c    drm_platform.c      drm_trace_points.c  imx       qxl      tdfx      vmwgfx
cirrus            drm_crtc.c           drm_edid_load.c        drm_hashtab.c         drm_mipi_dsi.c  drm_prime.c         drm_vma_manager.c   Kconfig   r128     tegra
drm_agpsupport.c  drm_crtc_helper.c    drm_encoder_slave.c    drm_info.c            drm_mm.c        drm_probe_helper.c  drm_vm.c            Makefile  radeon   tilcdc

在Linux 內核中,經過Makefile、Kconfig和SOC廠商對應的*defconfig文件配合完成DRM代碼編譯。在DRM驅動程序中,主要涉及到的文件有:ide

  1. drivers/gpu/Makefileui

    在Makefile中能夠看到:obj-y += drm/,說明直接編譯drm目錄。this

    A.小知識點:atom

    obj-y、obj-m 是Makefile變量。在Makefile中爲這些變量賦值後,Kbuild會自動把對象編譯到內核或者編譯成模塊。spa

    obj-y:表示編譯進內核;obj-m:表示編譯成模塊。debug

    後續會專門介紹Linux內核Kbuild系統。code

  2. drivers/gpu/drm/Makefile、Kconfig

    在Makefile中區分了DRM core和SOC DRM driver的編譯。

    1)DRM core對應的部分文件

    drm-y       :=  drm_auth.o drm_bufs.o drm_cache.o \
                    drm_context.o drm_dma.o \
                    drm_fops.o drm_gem.o drm_ioctl.o drm_irq.o \
                    drm_lock.o drm_memory.o drm_drv.o drm_vm.o \
                    drm_scatter.o drm_pci.o \
                    drm_platform.o drm_sysfs.o drm_hashtab.o drm_mm.o \
                    drm_crtc.o drm_modes.o drm_edid.o \
                    drm_info.o drm_debugfs.o drm_encoder_slave.o \
                    drm_trace_points.o drm_global.o drm_prime.o \
                    drm_rect.o drm_vma_manager.o drm_flip_work.o \
                    drm_modeset_lock.o drm_atomic.o drm_bridge.o \
                    drm_sync_helper.o drm_scdc_helper.o

    2)SOC DRM driver對應的部分文件

    obj-$(CONFIG_DRM_TTM)   += ttm/
    obj-$(CONFIG_DRM_R128)  += r128/
    obj-$(CONFIG_HSA_AMD) += amd/amdkfd/
    obj-$(CONFIG_DRM_RADEON)+= radeon/
    obj-$(CONFIG_DRM_AMDGPU)+= amd/amdgpu/
    obj-$(CONFIG_DRM_MGA)   += mga/
    obj-$(CONFIG_DRM_I810)  += i810/
    obj-$(CONFIG_DRM_I915)  += i915/
    obj-$(CONFIG_DRM_MGAG200) += mgag200/
    obj-$(CONFIG_DRM_VC4)  += vc4/
    obj-$(CONFIG_DRM_CIRRUS_QEMU) += cirrus/
    obj-$(CONFIG_DRM_SIS)   += sis/
    obj-$(CONFIG_DRM_SAVAGE)+= savage/
    obj-$(CONFIG_DRM_VMWGFX)+= vmwgfx/
    obj-$(CONFIG_DRM_VIA)   +=via/
    obj-$(CONFIG_DRM_VGEM)  += vgem/
    obj-$(CONFIG_DRM_NOUVEAU) +=nouveau/
    obj-$(CONFIG_DRM_EXYNOS) +=exynos/
    obj-$(CONFIG_DRM_ROCKCHIP) +=rockchip/
    obj-$(CONFIG_DRM_GMA500) += gma500/
    obj-$(CONFIG_DRM_UDL) += udl/
    obj-$(CONFIG_DRM_AST) += ast/
    obj-$(CONFIG_DRM_ARMADA) += armada/
    obj-$(CONFIG_DRM_ATMEL_HLCDC)   += atmel-hlcdc/
    obj-$(CONFIG_DRM_RCAR_DU) += rcar-du/
    obj-$(CONFIG_DRM_SHMOBILE) +=shmobile/
    obj-$(CONFIG_DRM_OMAP)  += omapdrm/
    obj-$(CONFIG_DRM_QXL) += qxl/
    obj-$(CONFIG_DRM_BOCHS) += bochs/
    obj-$(CONFIG_DRM_VIRTIO_GPU) += virtio/
    obj-$(CONFIG_DRM_MSM) += msm/
    obj-$(CONFIG_DRM_TEGRA) += tegra/
    obj-$(CONFIG_DRM_STI) += sti/
    obj-$(CONFIG_DRM_IMX) += imx/

    在每一個文件夾中的Kconfig文件中能夠看到對應文件夾實現的功能。以RK3399爲例,在drivers/gpu/drm/rockchip/Kconfig中:

    config DRM_ROCKCHIP
            tristate "DRM Support for Rockchip"
            depends on DRM
            depends on RESET_CONTROLLER
            select DRM_KMS_HELPER
            select DRM_KMS_FB_HELPER
            select DRM_PANEL
            select FB_CFB_FILLRECT
            select FB_CFB_COPYAREA
            select FB_CFB_IMAGEBLIT
            select VIDEOMODE_HELPERS
            help
              Choose this option if you have a Rockchip soc chipset.
              This driver provides kernel mode setting and buffer
              management to userspace. This driver does not provide
              2D or 3D acceleration; acceleration is performed by other
              IP found on the SoC.

    drivers/gpu/drm/中非SOC DRM driver作個簡單說明,見下表。

    文件夾 簡介
    bridge 接口轉換驅動
    i2c I2C接口的encoder或transmitter芯片驅動
    ttm GEM和TTM是DRM的兩套內存管理子系統
    vgem 非硬件支持的GEM服務
  3. drivers/gpu/drm/rockchip/Makefile、Kconfig

    在Makefile文件中,區分了RK3399 DRM驅動和RK3399 各類接口(hdmi、lvds、dp、mipi等)驅動,例:

    rockchipdrm-y := rockchip_drm_drv.o rockchip_drm_fb.o \
                    rockchip_drm_gem.o rockchip_drm_vop.o
    rockchipdrm-$(CONFIG_DRM_FBDEV_EMULATION) += rockchip_drm_fbdev.o
    
    obj-$(CONFIG_ROCKCHIP_DW_HDMI) += dw_hdmi-rockchip.o
    obj-$(CONFIG_ROCKCHIP_CDN_DP) += cdn-dp.o
    cdn-dp-objs := cdn-dp-core.o cdn-dp-reg.o cdn-dp-link-training.o
    obj-$(CONFIG_ROCKCHIP_DW_MIPI_DSI) += dw-mipi-dsi.o
    obj-$(CONFIG_ROCKCHIP_ANALOGIX_DP) += analogix_dp-rockchip.o
    obj-$(CONFIG_ROCKCHIP_INNO_HDMI) += inno_hdmi.o
    obj-$(CONFIG_ROCKCHIP_LVDS) += rockchip_lvds.o
    obj-$(CONFIG_ROCKCHIP_RGB) += rockchip_rgb.o
    
    obj-$(CONFIG_ROCKCHIP_DRM_BACKLIGHT) += rockchip_drm_backlight.o
    obj-$(CONFIG_DRM_ROCKCHIP) += rockchip_vop_reg.o rockchipdrm.o
    obj-$(CONFIG_ROCKCHIP_DRM_TVE) += rockchip_drm_tve.o
    
    obj-$(CONFIG_ROCKCHIP_RK3066_HDMI) += rk3066_hdmi.o
    obj-$(CONFIG_DRM_ROCKCHIP_RK618) += rk618/
  4. arch/arm64/configs/rockchip_linux_defconfig

    rockchip_linux_defconfig文件在內核開始編譯時會生成.config文件,在該文件中定義的宏,配合2和3進行編譯。例:

    CONFIG_DRM=y
    CONFIG_DRM_LOAD_EDID_FIRMWARE=y
    CONFIG_DRM_DMA_SYNC=y
    CONFIG_DRM_ROCKCHIP=y
    CONFIG_ROCKCHIP_DW_HDMI=y

注:使用其它SOC廠商的DRM驅動時,3和4選擇對應SOC廠商目錄下的Makefile、Kconfig和*_defcofig。

B.小知識點:

在defconfig文件中,配置宏的值只有y和m。若是不定義配置宏,使用# CONFIG_* is not set

前文中提到:Linux DRM包括: DRM core和DRM Driver。DRM core提供基礎框架,爲不一樣SOC DRM driver提供註冊接口,同時也給用戶態提供一個硬件無關的ioctl調用。DRM driver實現硬件相關部分,負責硬件相關的ioctl調用。下篇文章開始介紹RK3399 DRM driver

相關文章
相關標籤/搜索