GPU初始化和启动流程(r600)
来源:互联网 发布:不好意思网络中断日语 编辑:程序博客网 时间:2024/06/06 01:05
本文是分析了显卡初始化和启动的函数调用以及每个函数的功能。
初始化显卡
int r600_init(struct radeon_device *rdev) //debuffs r600_debugfs_mc_info_init(rdev) **************************BIOS******************************** //读取GPU硬件启动的bios radeon_get_bios(struct radeon_device *rdev) loongson3_read_bios(rdev) //由于一个GPU系列中部分硬件架构的修改,而由硬件厂商提供的一组硬件访问方法,被翻译成了字节码 //有一个翻译表,提供给注册的驱动来调用,从而对硬件进行操作 radeon_atombios_init(struct radeon_device *rdev) *************************************************************** //判断显卡是否已经被初始化过了,检查所有的电路是否已将被初始化,通过读取相应寄存器的值判断 radeon_card_posted(rdev) //初始化划痕寄存器,设置设备划痕寄存器的基地址,这一组寄存器的地址是连续的,由一个数组来维护记录 r600_scratch_init(struct radeon_device *rdev) //surface寄存器,r600之后都没有了 radeon_surface_init(struct radeon_device *rdev) //初始化时钟,并设置 radeon_get_clock_info(struct drm_device *dev) //初始化所有的ring中的fence驱动,准备一些所需要的基础设施 radeon_fence_driver_init(struct radeon_device *rdev) radeon_fence_driver_init_ring(struct radeon_device *rdev, int ring) //如果有AGP,那么就需要进行初始化,图形加速卡 radeon_agp_init(struct radeon_device *rdev) //初始化显卡的内存控制器结构,获取所支持的带宽,映射在PCIE中的基地址,gtt的位置,支持的通道数量 r600_mc_init(struct radeon_device *rdev) //确定显存和GTT的位置 r600_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc) radeon_vram_location(struct radeon_device *rdev, struct radeon_mc *mc, u64 base) radeon_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc) **************************************************************************************************************** //初始化memory manager,后期所有内存的申请和管理都是通过这里创建的数据结构 radeon_bo_init(struct radeon_device *rdev) radeon_ttm_init(struct radeon_device *rdev) radeon_ttm_global_init(rdev); ttm_bo_device_init(struct ttm_bo_device *bdev,struct ttm_bo_global *glob, struct ttm_bo_driver *driver, uint64_t file_page_offset, bool need_dma32) ttm_bo_init_mm(struct ttm_bo_device *bdev, unsigned type, unsigned long p_size) **************************************************************************************************************** //对RADEON_RING_TYPE_GFX_INDEX,R600_RING_TYPE_DMA_INDEX两个ring进行初始化设置 r600_ring_init(struct radeon_device *rdev, struct radeon_ring *ring, unsigned ring_size) //通用视频解码单元的初始化,载入相应的固件,以及bo的申请,映射等,同样接下来需要调用r600_ring_init对R600_RING_TYPE_UVD_INDEX进行初始化设置 radeon_uvd_init(struct radeon_device *rdev) //对中断使用的ring的初始化设置, r600_ih_ring_init(struct radeon_device *rdev, unsigned ring_size) //对GART页表结构进行初始化,注意是通过前面的ttm机制申请对应的bo对象,填写也表现,一开始对应的都是无效页 r600_pcie_gart_init(struct radeon_device *rdev) radeon_gart_init(struct radeon_device *rdev) //为gart表分配显存页 radeon_gart_table_vram_alloc(struct radeon_device *rdev) *************************************************STARTUP********************************************************* //如果启动失败,那么说明GPU加速失败,驱动不可用 r600_startup(struct radeon_device *rdev)
启动显卡
r600_startup(struct radeon_device *rdev) // r600_pcie_gen2_enable(struct radeon_device *rdev) //对显存控制器进行设置,写相关寄存器,获得显存的基地址,大小,gtt的基地址,大小等等。完全的接管显存。 r600_mc_program(struct radeon_device *rdev) //初始化微码,从指定的目录载入三个二进制文件到内存中,***_pfp.bin,***_me.bin,***_rlc.bin r600_init_microcode(struct radeon_device *rdev) //分配一个显存页,用作划痕页,创建了一个bo,用作radeon_device* 的一个属性 r600_vram_scratch_init(struct radeon_device *rdev) //启动GART机制 r600_pcie_gart_enable(struct radeon_device *rdev) /* pin操作固定用作GART的存储页,作为常驻存储,在显卡的整个使用过程中都不会被显存控制器所管理,换出或者回收,只有在卸载驱动的时候会被回收。 */ radeon_gart_table_vram_pin(struct radeon_device *rdev) //重建gart页表中的每个页的基地址,然后刷新TLB。接下来就会设置二级cache等等控制寄存器,当前这些页表中都指向一个dummy page,就是GPU访问每个页表项 //都是无效页 radeon_gart_restore(struct radeon_device *rdev) //接着就刷新TLB r600_pcie_gart_tlb_flush(rdev) //设置GPU的一些功能部件:初始化rdev中GPU相关的一些参数,然后设置GPU的一些寄存器,这时GPU的的初始状态就设置的差不多了 r600_gpu_init(struct radeon_device *rdev) //对拷屏操作的初始化,指的是一个图形从屏幕上一个位置移动到另一个位置。 //设置相关参数以及注册相关函数(顶点资源,纹理资源,shader等等的设置) r600_blit_init(struct radeon_device *rdev) //初始化回写驱动信息并分配内存,创建了一个bo,作为wb对象,并没有实际的硬件wb机制。官方注释为:分配回写缓冲 radeon_wb_init(struct radeon_device *rdev) //先释放当前fence所对应的划痕寄存器,然后分配一个,设置fence序列号回写地址(GPU,CPU地址都需要设置), //最后将fence序列号回写到划痕寄存器或者wb回写buffer中 //需要连续调用三次,分别为GFX,DMA,UVD radeon_fence_driver_start_ring(struct radeon_device *rdev, int ring) //释放一个划痕寄存器,一个device会有多个fence,这样也就对应多个fence driver。每个fence driver会拥有一个划痕寄存器用于回写fence序列号 radeon_scratch_free(struct radeon_device *rdev, uint32_t reg) radeon_scratch_get(struct radeon_device *rdev, uint32_t *reg) //将fence值写回到划痕寄存器,如果直接支持回写机制,那么会回写到回写buffer中 radeon_fence_write(struct radeon_device *rdev, u32 seq, int ring) ********************************************************************************************************************************************** //中断 radeon_irq_kms_init(struct radeon_device *rdev) //初始化用于处理垂直同步机制的所有数据结构 //垂直同步的作用是防止画面撕裂,由于存在多个CRTC,所有每个CRTC都会有一个对应的等待队列 //对应需要处理的中断就是vblank中断,设置的数据结构包括定时器,引用计数,vblank各个阶段时间间隔 drm_vblank_init(struct drm_device *dev, int num_crtcs) //MSI (Message Signaled Interrupts) //判断当前GPU是否支持MSI,如果支持,调用pci_enable_msi(rdev->pdev) radeon_msi_ok(struct radeon_device *rdev) //安装中断处理函数,向系统中断处理机制中注册中断服务,?? drm_irq_install(struct drm_device *dev) //中断ring的读写指针地址的设置,相关的中断控制,reset以及restore等的处理 r600_irq_init(struct radeon_device *rdev) //创建一个bo,座位中断环形缓冲 r600_ih_ring_alloc(struct radeon_device *rdev) //设置状态位和控制寄存器的值,使得CPU不会从irq ring中处理中断,GPU也不会产生中断写入ring r600_disable_interrupts(struct radeon_device *rdev) //先r600_rlc_stop(rdev);然后设置相关的一些寄存器值,再r600_rlc_start(rdev);大致就是设置GPU reset以及restore功能的硬件支持 r600_rlc_init(struct radeon_device *rdev) //强制将所有中断的状态设置为disable r600_disable_interrupt_state(rdev); //没有实现,大致实现的功能应该为正确设置设备挂载到master管理链中接受管理 pci_set_master(rdev->pdev); r600_enable_interrupts(rdev); //设置相应的中断列表以及对应的中断处理程序,中断号《--》中断处理程序 r600_irq_set(struct radeon_device *rdev) ******************************************************************************************************************************** //初始化GFX和DMA 环形缓冲大大小和位置,读写指针 radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET, R600_CP_RB_RPTR, R600_CP_RB_WPTR, 0, 0xfffff, RADEON_CP_PACKET2); ******************************************************************************************************************************** //加载微码,使得CP能够开始动起来。这些微码已经在之前加载到了内存中 //首先将CP停止,软重置,然后从主存中载入ME和PFP的微码,仅仅是写入到对应的端口 r600_cp_load_microcode(struct radeon_device *rdev) //将CP复位,如果在某次被停止,那么就需要调用复位函数resume,首先会对CP进行软重置,设置CP相依寄存器的值,包括ring的读写指针,延迟等等。 //最后启动r600_cp_start(rdev);并进行测试r600_ring_test(struct radeon_device *rdev, struct radeon_ring *ring) //测试过程就是首先往划痕寄存器中写入一个初始值,再让CP处理一个命令,往划痕寄存器中回写一个值,判断值是否正确被写入,需要被注意的就是 //验证的过程中设置了一定的延迟 r600_cp_resume(struct radeon_device *rdev) //设置并驱动异步dma引擎,设置DMA环形缓冲并打开。初始化读写指针以及回写地址等等,同样也进行了ring test,更新实际可用的显存大小 //radeon_ttm_set_active_vram_size(struct radeon_device *rdev, u64 size) r600_dma_resume(struct radeon_device *rdev) //对UVC的ring进行初始化 radeon_ring_init(rdev, ring, ring->ring_size, R600_WB_UVD_RPTR_OFFSET, UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR, 0, 0xfffff, RADEON_CP_PACKET2); //初始化间接缓冲池。初始化二级分配器用于管理一个内存池,用于间接缓冲 radeon_ib_pool_init(struct radeon_device *rdev) //初始化一个二级分配器以及管理器等数据结构,指定pool的domain,size以及对齐方式等等 radeon_sa_bo_manager_init(struct radeon_device *rdev, struct radeon_sa_manager *sa_manager, unsigned size, u32 align, u32 domain) //启动二级分配器,其实就是申请一块存储作为pool,并映射到虚拟地址空间,GPU和CPU地址 radeon_sa_bo_manager_start(struct radeon_device *rdev, struct radeon_sa_manager *sa_manager) //打开音频引擎,并设置音频的相关变量 r600_audio_init(struct radeon_device *rdev) r600_audio_engine_enable(struct radeon_device *rdev, bool enable)
显卡驱动入口
module_init(drm_core_int);
drm_core_init是在系统启动的时候进行调用,用于初始化drm驱动的相关数据结构。下面是调用流程
0 0
- GPU初始化和启动流程(r600)
- tomcat6源码分析二(初始化和启动流程)
- tomcat6源码分析二(初始化和启动流程)
- Nginx启动初始化流程
- 介绍Linux系统如何初始化和启动系统服务的(Linux的开机流程)
- bootload启动流程(一)----硬件的初始化和基本配置
- 介绍Linux系统如何初始化和启动系统服务的(Linux的开机流程)
- 介绍Linux系统如何初始化和启动系统服务的(Linux的开机流程)
- 介绍Linux系统如何初始化和启动系统服务的(Linux的开机流程)
- trafficserver的ICP初始化和启动流程源码注释
- WebKit之GPU进程启动流程说明
- Windows CE初始化启动流程
- PackageManagerService启动及初始化流程
- PackageManagerService启动及初始化流程
- PackageManagerService启动及初始化流程
- Linux启动流程以及初始化
- 系统初始化流程 跟着启动代码走 !
- Android 4.0 WIFI初始化与启动流程
- SAP Basis系统管理中重置用户缓冲哪些需要注意
- 虚拟机深入学习
- Linux下对MySql数据库备份与恢复
- oracle11g单机静默安装
- git设置忽略文件
- GPU初始化和启动流程(r600)
- Java NIO系列教程(八) SocketChannel
- wifidog 源码初分析(三)
- nginx-nginx环境下润乾报表“+”号重复请求
- Java虚拟机的JVM垃圾回收机制
- iOS-Bug收集:CocoaPods 错误 target overrides the `OTHER_LDFLAGS`...
- Android 反编译二进制AndroidManifest.xml文件的方法
- 全屏 去除标题栏 窗口模式Activity
- setNeedsDisplay和setNeedsDisplay和layoutIfNeeded关系