【Phytium】飞腾D2000 UEFI/EDK2 适配 RTC(IIC SD3077)
文章目录
- 0. env
- 1. 软件
- 2. 硬件
- 10. 需求
- 1. 硬件
- 2. 软件
- 20. Datasheet
- CPU
- RTC
- 30. 调试步骤
- 1. 硬件环境搭建
- 2. UEFI 开发环境搭建
- 3. 修改步骤
- 1. UEFI 中使能RTC驱动、配置RTC信息等
- 1.1 使能RTC驱动
- 1.2 修改RTC对应的IIC配置信息
- 1.3 解决驱动冲突
- 1.4 验证波形
- 2. 修改对应RTC驱动,适配SD3077
- 1.1 修改IIC3的引脚复用
- 1.2 允许SD3077的写使能功能
- 1.3 验证时间
- 4. 验证
- 90. 附件
- 1. CPU 参考手册
- 2. RTC 参考手册
0. env
1. 软件
开发环境:ubuntu1804
toolchain:飞腾GCC4.9
UEFI:edk2-core-3.5
运行环境:kylin v10 | kernel-5.4 | aarch64 | arm64
2. 硬件
CPU:飞腾 腾锐D2000
RTC:SD3077
硬件连接:CPU(I2C3) — RTC
10. 需求
1. 硬件
RTC 这路的IIC要通信正常
2. 软件
UEFI 中完成RTC更新
linux中可手动更新date
20. Datasheet
CPU
腾锐D2000软件编程手册-V1.1.pdf // 官网下载:略
RTC
SD3077+datasheetv3.4.pdf // 官网下载:参考附件
30. 调试步骤
1. 硬件环境搭建
D2000 核心板 通过I2C3接口外接RTC SD3077
RTC供电3V3
CPU可单独上下电,不影响RTC供电
2. UEFI 开发环境搭建
ubuntu1804 搭建EDK2的环境,飞腾适配过的版本
安装对应toolchain:飞腾GCC4.9
制作bootloader的工程:略
3. 修改步骤
1. UEFI 中使能RTC驱动、配置RTC信息等
vi PhytiumPkg/PhytiumD2000Pkg/PhytiumD2000Pkg.dsc
1.1 使能RTC驱动
!if $(BOARD) == "DEMO" DEFINE HDA_SUPPORT = TRUE - DEFINE SD3068 = FALSE + DEFINE SD3068 = TRUE
remark: 1. 使能这里的SD3068,
从而配置I2C slave addr 为:0x32
配置RTC使用的I2C controller Base Address 为:0x28009000 即I2C3的控制器
1. 如果I2C_RTC_USE没使能,使能后即可使用RTC-efi 53 DEFINE I2C_RTC_USE = TRUE
1.2 修改RTC对应的IIC配置信息
- 使能SD3068后
1. 则RTC使用的slave address修改为:0x32 529 !if $(SD3068) == TRUE 530 gPhytiumPlatformTokenSpaceGuid.PcdRtcI2cControllerSlaveAddress|0x32 531 !else 532 gPhytiumPlatformTokenSpaceGuid.PcdRtcI2cControllerSlaveAddress|0x68 533 !endif
2. 默认使用的是I2C0、I2C1的控制器来操作RTC;实际使用的是I2C3,所以这里的RTC使用的I2C controller的基质要修改为I2C3,即0x28009000 // 参考手册说明 # RTC I2C Controller Register Base Address and Speed # ... - gPhytiumPlatformTokenSpaceGuid.PcdRtcI2cControllerBaseAddress|0x28007000 // IIC1 飞腾空出了I2C0、I2C1 + gPhytiumPlatformTokenSpaceGuid.PcdRtcI2cControllerBaseAddress|0x28009000 // IIC3 实际使用的是I2C3
- 使能I2C_RTC_USE后
1. 则使用的事Ds1339_RtcLib.inf,对应驱动:./PhytiumPkg/PhytiumD2000Pkg/Library/Ds1339_RtcLib/ 253 # Board Specific RealTimeClock Library 254 !if $(I2C_RTC_USE) == TRUE 255 RealTimeClockLib|$(PLATFORM_PACKAGE)/Library/Ds1339_RtcLib/Ds1339_RtcLib.inf 256 !else 257 RealTimeClockLib|$(PLATFORM_PACKAGE)/Library/XgeneRealTimeClockLib/XgeneRealTimeClockLib.inf 258 !endif 259 TimeBaseLib|EmbeddedPkg/Library/TimeBaseLib/TimeBaseLib.inf
1.3 解决驱动冲突
驱动冲突,占用了0x28000000,+0x5000的位置,正好囊括了i2c3的地址
1. 如果不用也可以不使能该功能 --- a/PhytiumPkg/PhytiumD2000Pkg/Drivers/FixGcdDxe/FixGcdDxe.c +++ b/PhytiumPkg/PhytiumD2000Pkg/Drivers/FixGcdDxe/FixGcdDxe.c @@ -54,18 +54,18 @@ InitializeFixGcdDxe ( ); ASSERT_EFI_ERROR (Status); - Status = gDS->AddMemorySpace ( - EfiGcdMemoryTypeReserved, - 0x28008000, 0x5000, - EFI_MEMORY_UC - ); - ASSERT_EFI_ERROR (Status); + //Status = gDS->AddMemorySpace ( + // EfiGcdMemoryTypeReserved, + // 0x28008000, 0x5000, + // EFI_MEMORY_UC + // );^M + //ASSERT_EFI_ERROR (Status); - Status = gDS->SetMemorySpaceAttributes ( - 0x28008000, 0x5000, - EFI_MEMORY_UC - ); - ASSERT_EFI_ERROR (Status); + //Status = gDS->SetMemorySpaceAttributes ( + // 0x28008000, 0x5000, + // EFI_MEMORY_UC + // ); + //ASSERT_EFI_ERROR (Status); return Status; }
1.4 验证波形
编译后,测量I2C3这一路的信号,正常会产生RTC读写信号
2. 修改对应RTC驱动,适配SD3077
使用上述修改,则需要修改的驱动为:./PhytiumPkg/PhytiumD2000Pkg/Library/Ds1339_RtcLib/*
1.1 修改IIC3的引脚复用
- rtc-efi不需要依赖ACPI配置RTC,管脚引用可以直接放在驱动中执行。
- I2C3 管脚复用信息如下:
控制域 … Func2 hdt_mb_done_state_pad … i2c_3_scl hdt_mb_fail_state_pad … i2c_3_sda 偏移 位域 说明 0x0204 [3 : 2] 控制 hdt_mb_done_state_pad 的上下拉 0x0204 [1 : 0] 控制 hdt_mb_done_state_pad 的复用功能 0x0208 [31 : 30] 控制 hdt_mb_fail_state_pad 的上下拉 0x0208 [29 : 28] 控制 hdt_mb_fail_state_pad 的复用功能 实际使用:I2C3,则需要复用 这两个pin为Func2
即:
SCL : 0x28180000 + 0x0204 : [3:0] : 写入0010
SDA : 0x28180000 + 0x0208 : [31:28] : 写入0010
- 在源码驱动初始化程序段中添加管脚复用
vi PhytiumPkg/PhytiumD2000Pkg/Library/Ds1339_RtcLib/Ds1339_RtcLib.c
1. 在LibRtcInitialize中添加服用程序 @@ -980,8 +1016,20 @@ LibRtcInitialize ( mRtcBase = PcdGet64 (PcdRtcI2cControllerBaseAddress); mSlaveaddress = PcdGet32 (PcdRtcI2cControllerSlaveAddress); + /* I2C3 : + SCL : 0x28180000 + 0x0204 : [3:0] : Pll FUNC2 + SDA : 0x28180000 + 0x0208 : [31:28] : Pll FUNC2 + */ + Reg = MmioRead32(0x28180204); + MmioWrite32(0x28180204, (Reg & (~(0xff + SD3068EnableRegWrite (mSlaveaddress); + } +#endif + UINT8 Buffer; + Buffer = rtc_read (0x10, mSlaveaddress); + Buffer |= (1
还没有评论,来说两句吧...