目录
一、概述
芯片的 PCI Express (或简称 PCIe )主要应用于 PCIe 外扩 SATA 、网口、 WiFi 以及片间级联等。
芯片中 PCI Express 控制器具有以下特点:
支持一个 PCI Express Gen2X1 控制器。
支持 1 VC , 1 TC 。
支持 RC 模式。 RC(Root-Complex)模式。芯片的 PCIe 接口在RC模式下可与其它 PCIe EP 设备进行对接以实现功能扩展。
支持 EP 模式。 EP(End-Point)模式。芯片的 PCIe 接口可以设置为EP模式,以实现与 PCIe RC 或 SWITCH 设备对接。
支持 DMA 功能。
目前 Hi35xxVxxx 级联均支持两种启动方式:
− 主片与从片均从Flash启动。
− 工作在 PCIE 主模式的 Hi35xxVxxx 从 Flash 启动,工作在 PCIE 从模式的Hi35xxVxxx 需要将启动模式更改为 DDR 启动模式(由主片来引导从片启动)。
我们选择的是主片与从片均从Flash启动的方式。
二、信号描述
PCI Express 接口信号描述
在芯片中,PCIE 与 USB3.0 接口信号是复用的,应用时需要根据场景选择复用模式。复用模式由 COMBO_PHY_MODE (与 SENSOR_HS2 复用)管脚上电时的上下拉决定。请参考 Hi35xxVxxx_PINOUT_CN.xlsx 中管脚信息表页面。
COMBO_PHY_MODE的取值如下:
需将 COMBO_PHY_MODE配置为0表示启用PCIe模式;
另外系统通过PCIE_CLK_REQ_N来控制时钟源的选择。
三、接线方式
3.1 PCIe接线方式
PCIe发送接口和时钟线连接方式如下:
板子A的Pcie0_rx_m 接 板子B的Pcie0_tx_m
板子A的Pcie0_rx_p 接 板子B的Pcie0_tx_p
板子A的Pcie0_tx_m 接 板子B的Pcie0_rx_m
板子A的Pcie0_tx_p 接 板子B的Pcie0_rx_p
板子A的Pcie_refclk_m接 板子B的Pcie_refclk_m
板子A的Pcie_refclk_p 接 板子B的Pcie_refclk_p
PCIe上述接线的位置在原理图的如下位置:
3.2 PCIE接口复用
在芯片中,PCIE与USB3.0接口信号是复用的,应用时需要根据场景选择复用模式。
复用模式由 COMBO_PHY_MODE(与SENSOR_HS2复用)管脚上电时的上下拉决
定。请参考 Hi35xxVxxx_PINOUT_CN.xlsx 中管脚信息表页面。
由上面的文档可以看出,COMBO_PHY_MODE需要物理拉低,并且软件配置正确。
3.3 PCIe 时钟源选择
3.3.1 从启动硬件配置
BOOT源选择为PCIe启动,要求将BOOT_SEL4,配置为 1。由于我们选择的是主片和从片均从flash启动的方式,所以此处不需要修改BOOT_SEL4的值。
PCIe从启动时,注意时钟硬件选择管脚的设置。
PCIE_CLK_REQ_N主模式需要拉低,从模式需要拉高。
3.3.2 时钟设置和复位
PCIe PHY 工作时需要一个 100MHz 的参考时钟,此参考时钟有两个来源: 芯片内部CRG,外部PCIe差分时钟管脚输入。
3.3.2.1 芯片内部 CRG
配置以下寄存器和信号,PCIe PHY 将采用芯片内部提供的 100MHz 时钟作为参考时钟。
COMBO_PHY_REFCLK_SEL信号(和管脚 SENSOR_HS0 复用)下拉。
− CRG 控制寄存器 PERI_CRG98[10:9] :设置为 2’b10;
− CRG 控制寄存器 PERI_CRG98[8] :设置为 1’b1;
− CRG 控制寄存器 PERI_CRG98[1] :设置为 1’b1;
− CRG 控制寄存器 PERI_CRG98[0] :设置为 1’b0;
当 PCIe 采用内部 CRG 提供参考时钟时,
COMBO_PHY_REFCLKP/COMBO_PHY_REFCLKM 管脚可以设置为输出模式,用来给外部 PCIe 设备提供参考时钟。
− 配置以下寄存器可以由 COMBO_PHY_REFCLKP/COMBO_PHY_REFCLKM 输出 PCIe 参考时钟:
− CRG控制寄存器PERI_CRG99[10:8]:设置为3’b000。
COMBO_PHY_REFCLK_SEL物理上外接的口叫SENSOR_HS0/PRCLKSEL
COMBO_PHY_REFCLK_SEL主模式需要拉低,从模式需要拉高。
PERI_CRG98控制的实现
PERI_CRG98
PERI_CRG98为COMB PHY相关时钟复位控制寄存器。
Offset Address: 0x0188 Total Reset Value: 0x0000_0500 CRG寄存器概览(基址是 0x0451_0000 )
修改boot中PERI_CRG98的默认值,使得开机时配置就是正确的。
PERI_CRG99
PERI_CRG99为PCIE CTRL相关的时钟及软复位控制寄存器。
Offset Address: 0x018C Total Reset Value: 0x0001_00F0 CRG寄存器概览(基址是 0x0451_0000 )
修改boot中PERI_CRG99的默认值,使得开机时配置就是正确的。
3.3.2.2 外部 PCIe 差分时钟管脚输入
− 配置以下信号,PCIe PHY将采用COMBO_PHY_REFCLKP/COMBO_PHY_REFCLKM管脚的差分时钟作为PCIe PHY的参考时钟。
COMBO_PHY_REFCLK_SEL(和管脚 SENSOR_HS0 复用)上拉。
注意:当通过 COMBO_PHY_REFCLKP/COMBO_PHY_REFCLKM 输入参考时钟时,外供参考时钟源须保证频偏在 ±300ppm 内。
COMBO_PHY_REFCLK_SEL从模式需要拉高。
3.4 使能 PCIe 控制器
按如下步骤使能PCIe控制器:
步骤1. 通过向PCIe内部系统控制寄存器PCIE_SYS_CTRL7[pcie_app_ltssm_enable]写入0,关闭PCIe控制器。
步骤2. 通过CRG寄存器PERI_CRG98和PERI_CRG99设置PCIePHY和控制器时钟。
步骤3. 通过PCIe内部系统控制寄存器中的PCIE_SYS_CTRL0[pcie_device_type]寄存器设置PCIe控制器的工作模式(RC模式/EP模式)。
步骤4. 向CRG寄存器PERI_CRG99[pcie_srst_req]写1,以复位PCIe控制器。
步骤5. 向CRG寄存器PERI_CRG99[pcie_srst_req]写0,以撤销PCIe控制器复位。
步骤6. 当工作在RC模式时,需要配置控制器的类代码寄存器(CLASSCodeRegister)为0x060400(对应为PCI到PCI桥设备)。PCIe控制器的类代码寄存器位于PCIe配置寄存器空间内。
步骤7. 通过向PCIe内部系统控制寄存器PCIE_SYS_CTRL7[pcie_app_ltssm_enable]写入1,使能PCIe控制器。PCIe控制器使能后,PCIe控制器开始链路建立过程。
注意:在没有初始化好相关的PCIe内部系统控制寄存器之前不要使能PCIe控制器。链路初始化和定向是配置和初始化设备物理层、端口和相关链路的物理层的过程,使链路可以传输正常的数据包流量。链路的建立均是由硬件自动完成的,完成PCIe控制器的初始化和使能后,PCIe链路的建立自动发起,无需软件参与。PCIe控制器与对端设备之间的连接未建立,不可向对端设备发起任何PCIe事务(软件不可访问PCIe对端设备)。软件通过查询PCIe内部系统控制寄存器PERI_PCIE_STAT[pcie_rdlh_link_up]可以确定PCIe控制器是否已与对端设备建立连接。请参考PCIe内部系统控制器中关于PERI_PCIE_STAT寄存器的定义。
PCIE_SYS_CTRL7接口配置:
PCIE_SYS_CTRL0寄存器配置:
CLASS Code Register值配置:
3.5 在级联场景时钟设计注意事项
3.5.1 主片对地电阻
作为主片的时候,时钟输出管脚靠近芯片必须加 49.9 欧姆电阻对地。
图 PCIe 主片场景时钟图
3.5.2 从片对地电阻
作为从片且设置为外部时钟时,时钟输入管脚不需加 49.9 欧姆电阻对地。
图PCIE 从片场景时钟图
3.5.3 PCIe 级联模式
文档自己给出的PCIE级联模式
文档里面的图片是有四种模式,但是我从给出来的寄存器里面查只有两种模式,比较费解。
下面这个是我在寄存器里面查出来的
自己查出来的PCIE_USB3_MODE寄存器的值
个人理解,通过用户指南查出来的寄存器的值应该是比较准确的表述,也就是我们支持的模式只有两种,而且默认就是我们需要的PCIeX1模式。可以得出结论,级联模式的配置默认就是我们需要的,不需要再特意配置。
下面我们介绍PCIeX1模式级联,如下是几种典型的 PCIe 级联示意图。
图 两片 PCIe X1 级联示意图
图 两片 PCIe X2 级联示意图
四、编译IMG
4.1 打开PCIE驱动
编译主片内核镜像需打开 pcie 驱动
打开如下选项:
Bus support --->
[*] Hisilicon PCI Express support --->
然后将config与arch/arm/configs/hi3519av100_XXX_defconfig文件对比合入。hi3519av100_XXX_defconfig为我们编译时使用的defconfig文件。
然后重新打包linux的kernel打包,再进行整体系统编译。
4.2 编译主从驱动
先到Hi3519AV100_SDK_V2.0.2.0\osdrv\components\pcie_mcc\目录下,
编译主片:make CROSS_COMPILE=arm-himix200-linux- PCIE_KERNEL_MAKE=../../opensource/kernel/linux-4.9.y-smp VER=2 SLAVE_CHIP=hi3519av100
编译从片:make CROSS_COMPILE=arm-himix200-linux- PCIE_KERNEL_MAKE=../../opensource/kernel/linux-4.9.y-smp VER=2 target=slave
(请注意:编译主片时,请将参数 PCIE_KERNEL_MAKE 指定为 PCI 配置为 RC 的内核源码的路径;编译从片时,请教参数 PCIE_KERNEL_MAKE 指定为 PCI 配置为 EP 模式的内核源码路径,切忌不要弄错;CROSS_COMPILE参数指定芯片对应的编译工具链。)。
4.3 使用本模块编译出的ko
步骤1:准备好硬件环境,确保主从片同时上电;
步骤2:在主片起来后,在其文件系统下创建目录 “/hisi-pci”,并将从片使用的镜像文件(u-boot.bin,uImage,cramfs.initrd.img)拷贝到该目录下;
步骤3:在主片端,插入相关的内核模块:
# insmod hi35xx_dev_host.ko
# insmod irq_map_host.ko
# insmod boot_device.ko (我们是双flash启动,个人感觉不需要这一步)
步骤4:运行booter程序,启动从片:
# ./booter start_device (我们是双flash启动,个人感觉不需要这一步)
步骤5:等待从片启动完成,在主片端,插入以下模块:
# insmod pcit_dma_host.ko
# insmod mcc_drv_host.ko
# insmod mcc_usrdev_host.ko
步骤6:在从片端,插入相关的内核模块:
# insmod hi35xx_dev_slv.ko
# insmod irq_map_slv.ko
# insmod pcit_dma_slv.ko
# insmod mcc_drv_slv.ko shm_phys_addr=[消息共享内存的基址] shm_size=[消息共享内存的大小]
# insmod mcc_usrdev_slv.ko
(共享内存在从片时,每个从片共享内存大小至少为768K)。
上面的内容了解一下就可以了,如果需要可以直接通过到ko目录下面的load3519av100_slave和load3519av100文件配置,相应的函数海思已经写好,我们直接打开使用即可。