赞
踩
开发环境:ubuntu1804
toolchain:飞腾GCC4.9
UEFI:edk2-core-3.5
运行环境:kylin v10 | kernel-5.4 | aarch64 | arm64
CPU:飞腾 腾锐D2000
RTC:SD3077
硬件连接:CPU(I2C3) — RTC
RTC 这路的IIC要通信正常
UEFI 中完成RTC更新
linux中可手动更新date
腾锐D2000软件编程手册-V1.1.pdf // 官网下载:略
SD3077+datasheetv3.4.pdf // 官网下载:参考附件
D2000 核心板 通过I2C3接口外接RTC SD3077
RTC供电3V3
CPU可单独上下电,不影响RTC供电
ubuntu1804 搭建EDK2的环境,飞腾适配过的版本
安装对应toolchain:飞腾GCC4.9
制作bootloader的工程:略
vi PhytiumPkg/PhytiumD2000Pkg/PhytiumD2000Pkg.dsc
!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
- 使能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
驱动冲突,占用了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; }
编译后,测量I2C3这一路的信号,正常会产生RTC读写信号
使用上述修改,则需要修改的驱动为:./PhytiumPkg/PhytiumD2000Pkg/Library/Ds1339_RtcLib/*
- rtc-efi不需要依赖ACPI配置RTC,管脚引用可以直接放在驱动中执行。
- I2C3 管脚复用信息如下:
控制域 | … | Func2 |
---|---|---|
hdt_mb_done_state_pad | … | i2c_3_scl |
hdt_mb_fail_state_pad | … | i2c_3_sda |
- I2C3 引脚功能配置寄存器:
偏移 | 位域 | 说明 |
---|---|---|
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 << 0))) | (0x22 << 0));
+ Reg = MmioRead32(0x28180208);
+ MmioWrite32(0x28180208, (Reg & (~(0xff << 28))) | (0x22 << 28));
...
- 3077又写保护功能,要想在操作系统中正常使用hwclock之类的命令,需要提前禁止写保护功能(客户要求)
- 关于3077芯片写保护的禁止与使能说明如下:
2.1 寄存器说明:
3. 按文档说明,做如下设置禁止写保护功能:
先配置WRTC1 : 0x10 赋值 1xxx xxxx // 实际使用值为0x80
再配置WRTC2,3 : 0x0f 赋值 1xxx x1xx // 厂商建议值0xff,实际使用值为0x84
- 修改源码,加入上述配置寄存器禁止写保护的代码段:
vi PhytiumPkg/PhytiumD2000Pkg/Library/Ds1339_RtcLib/Ds1339_RtcLib.c
+#ifdef RTC_FIX
+ /* I2C3 :
+ SCL : 0x28180000 + 0x0204 : [3:0] : Pull FUNC2
+ SDA : 0x28180000 + 0x0208 : [31:28] : Pull FUNC2
+ */
+ Reg = MmioRead32(0x28180204);
+ MmioWrite32(0x28180204, (Reg & (~(0xff << 0))) | (0x22 << 0));
+ Reg = MmioRead32(0x28180208);
+ MmioWrite32(0x28180208, (Reg & (~(0xff << 28))) | (0x22 << 28));
+
+ if(mSlaveaddress == CONFIG_RTC_SD3068){
+ SD3068EnableRegWrite (mSlaveaddress);
+ }
+#endif
+#ifdef RTC_FIX +VOID +EFIAPI +SD3068EnableRegWrite ( + IN UINT32 mSlaveaddress + ) +{ + UINT8 Buffer; + Buffer = rtc_read (0x10, mSlaveaddress); + Buffer |= (1 << 7); + rtc_write (0x10, Buffer, mSlaveaddress); + + Buffer = rtc_read (0x0f, mSlaveaddress); + Buffer |= (1 << 2); + Buffer |= (1 << 7); + rtc_write (0x0f, Buffer, mSlaveaddress); + +} +#endif /* ifdef RTC_RIX */
- 启动到操作系统后,查看内核log,看一下rtc-efi打印
参考log:
root@kylin-pc:~# dmesg | grep rtc
[ 1.087034] rtc-efi rtc-efi: registered as rtc0
[ 1.093138] rtc-efi rtc-efi: setting system clock to 2024-04-12T12:13:51 UTC (1712924031)
- 启动到操作系统,使用date修改系统时间,使用hwclock修改RTC时间
- reboot操作系统
- 查看当前系统时间是否与RTC时间保持一致,即验证RTC功能是否正常
- 设备下电一段时间后,重新上电
- 上电后再次确认时间
参考log如下:
root@kylin-pc:~# date 1970年 01月 01日 星期四 08:00:19 CST root@kylin-pc:~# root@kylin-pc:~# date -s "2024-04-13 11:11:00" 2024年 04月 13日 星期六 11:11:00 CST root@kylin-pc:~# root@kylin-pc:~# hwclock -w root@kylin-pc:~# root@kylin-pc:~# hwclock -r 2024-04-13 11:11:14.212325+08:00 root@kylin-pc:~# root@kylin-pc:~# reboot // reboot root@kylin-pc:~# root@kylin-pc:~# date 2024年 04月 13日 星期六 11:13:12 CST root@kylin-pc:~# // 设备断电几分钟后,再次上电。RTC保持供电 root@kylin-pc:~# root@kylin-pc:~# date 2024年 04月 13日 星期六 11:27:48 CST root@kylin-pc:~# root@kylin-pc:~# dmesg | grep rtc [ 1.091921] rtc-efi rtc-efi: registered as rtc0 [ 1.098025] rtc-efi rtc-efi: setting system clock to 2024-04-13T11:27:26 UTC (1713007646) root@kylin-pc:~#
略
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。