掀開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
-
drivers/gpu/Makefile
ui在Makefile中能夠看到:
obj-y += drm/
,說明直接編譯drm目錄。thisA.小知識點:atom
obj-y、obj-m 是Makefile變量。在Makefile中爲這些變量賦值後,Kbuild會自動把對象編譯到內核或者編譯成模塊。spa
obj-y:表示編譯進內核;obj-m:表示編譯成模塊。debug
後續會專門介紹Linux內核Kbuild系統。code
-
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服務 -
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/
-
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