本文是分析了显卡初始化和启动的函数调用以及每个函数的功能。

初始化显卡

int r600_init(struct radeon_device *rdev)//debuffsr600_debugfs_mc_info_init(rdev)**************************BIOS********************************//读取GPU硬件启动的biosradeon_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.binr600_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)//接着就刷新TLBr600_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,UVDradeon_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也不会产生中断写入ringr600_disable_interrupts(struct radeon_device *rdev)//先r600_rlc_stop(rdev);然后设置相关的一些寄存器值,再r600_rlc_start(rdev);大致就是设置GPU reset以及restore功能的硬件支持r600_rlc_init(struct radeon_device *rdev)//强制将所有中断的状态设置为disabler600_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驱动的相关数据结构。下面是调用流程

GPU初始化和启动流程(r600)相关推荐

  1. 第1章 ZigBee协议栈初始化网络启动流程

    igBee的基本流程:由协调器的组网(创建PAN ID),终端设备和路由设备发现网络以及加入网络. 基本流程:main()->osal_init_system()->osalInitTas ...

  2. Orangepi Zero2 全志H616(一):配置初始化和启动流程

    目录 一,Orangepi简单说明 ①为什么使用全志H616 ②基本特性 ③配套操作系统支持 二,刷机和系统启动 ①准备工具 ②登录系统 ● 开发板供电 ● 登录 ● 开发板上板载LED灯测试说明 ③ ...

  3. SpringBoot启动流程分析(四):IoC容器的初始化过程

    SpringBoot系列文章简介 SpringBoot源码阅读辅助篇: Spring IoC容器与应用上下文的设计与实现 SpringBoot启动流程源码分析: SpringBoot启动流程分析(一) ...

  4. 分析Spring容器启动流程 Spring初始化

    分析Spring容器启动流程 Spring初始化 每当启动Web容器时(例如Tomcat),会读取Web应用中的web.xml文件.以下这段代码就是启动Spring容器的关键代码. ContextLo ...

  5. Android 8.0学习(27)--- SystemUI(二)启动流程和初始化

    Android 8.0 SystemUI(二):启动流程和初始化 这篇的话,将对SystemUI的启动和大体的初始化作描述.篇幅应该比上篇多了些.哈哈. 老样子,先上目录,简洁明了. 概述 由于需要实 ...

  6. 【SemiDrive源码分析】【X9芯片启动流程】12 - freertos_safetyos目录Cortex-R5 DIL2.bin 之 sdm_display_init 显示初始化源码分析

    [SemiDrive源码分析][X9芯片启动流程]12 - freertos_safetyos目录Cortex-R5 DIL2.bin 之 sdm_display_init 显示初始化源码分析 一.s ...

  7. Launcher启动流程及初始化

    前言 前面我们学习了SystemServer的启动流程,也了解了AMS是如何启动起来并通过Binder注册到ServiceManger内的,OK,本文基于这俩篇基础继续来学习Launcher. Lau ...

  8. Melis4.0[D1s]:1.启动流程(与adc按键初始化相关部分)跟踪笔记

    文章目录 1.启动流程 1.1 最先进入的文件:head_s.S 1.2 start_kernel()函数所在的文件:init.c 1.3 input_init()函数所在文件:sys_input.c ...

  9. JPOM - Server启动流程脚本初始化源码解析

    文章目录 地址 版本 Server启动流程&脚本初始化流程 地址 Gitee: https://gitee.com/dromara/Jpom 官网: https://jpom.io/ 一款简而 ...

最新文章

  1. 平滑迁移 Dubbo 服务的思考
  2. 【物联网智能网关-15】WAV播放器(WinForm+WavPlay库实例)
  3. Python学习(13)函数
  4. centos7下解决tomcat启动慢的问题
  5. linux 脚本 expected,Linux | shell与expect结合使用
  6. 2021年香河一中高考成绩查询,2021年廊坊高考状元名单公布,廊坊文理科状元是谁多少分...
  7. mysql skip-grant-tables my.cnf_skip-grant-tables:修改mysql密码
  8. [转载] c++list遍历_List、Set、数据结构、Collections
  9. linux查看根目录的大小,linux下查看根目录或当前目录大小
  10. JS学习总结(10)——Windows对象
  11. 阶段3 3.SpringMVC·_02.参数绑定及自定义类型转换_2 请求参数绑定实体类型
  12. 小米路由器mini刷Breed,安装固件教程
  13. 如何破解HIT的孤岛效应,一起关于患者主索引的案例分享
  14. IT售前工程师需要掌握哪些技术
  15. CASH软件分析差异性可变剪接
  16. 基于maven自动构建和部署工具-JDeploy
  17. 对比Excel两个sheet的数据是否相同
  18. DoT/DoH/DoQ 之 CoreDNS配置
  19. 根据汉字,获取拼音首字母(转)
  20. 2016年linux认证考试,2016年Linux认证考试模拟练习及答案

热门文章

  1. 内地人去香港旅游注意事项
  2. Unity5权威讲解之菜鸟读书笔记(一)
  3. 七大原则+23种设计模式
  4. php 小程序即时聊天,小程序组件:聊天会话组件的介绍(附代码)
  5. 现在做网站到底需要多少钱?
  6. linux收发包内核进程名称,Linux内核IP Queue机制的分析(一)——用户态接收数据包...
  7. 静止轨道卫星角度效应校正方法
  8. HTML项目心得500字,心得体会作文500字(精选10篇)
  9. 请别再问我什么是分布式事务
  10. Windows下cmd(命令提示符)中的复制粘贴操作