DDR2 DDR3 retention方案
目录
2.2.2 DDR phy进入低功耗与retention恢复流程
2.2.5.1冷启动初始化流程(retention flag 非0xAA):
2.5.2.2 retention恢复启动流程(retention flag 0xAA):
2.3 DDR retention flag 与training值存储位置如下:
一、背景介绍
最近在做IPC类摄像头芯片,其中AOV设备是最近很火的产品,主要使用太阳能电池板+锂电池代替常规供电设备,实现节能+AI识别+方便部署的能力。其中此功能涉及到一个重要的点,就是DDR的深度休眠功能。
最开始评估使用钰创DDR2(32MBx16位宽)颗粒来完成此功能,后续启动速度等原因需要更大内存,后来又换成了紫光DDR3(64MBx16位宽)来完成此功能。
本文重点介绍DDR2 DDR3 retention原理与retention实现方案,以及应用过程中遇到的技术难点。
二、DDR retention方案介绍
最近准备研发一款新型号芯片DT57B(包括DDR2和DDR3版本),此芯片计划支持低功耗AOV功能,为了提前摸清retention方案的技术难点,首先在已有的DT57芯片上进行功能验证。因为设备深度休眠进入retention模式的时候,会把除DDR颗粒外的其他电源都断电,DT57B计划去掉always on电源域,需要将retention标记flag保存到掉电不丢失的IP中,经过开会讨论,最终决定将retention flag与retention恢复后的跳转PC值存放到LPRTC模块中。
offset 0x3 的REG_NEW保存retention flag标记,0xAA代表需要用retention方式启动。
Alarm 2 Register 32bit 用于保存跳转PC值。
最先使用tx5112cv300 evb132开发板进行验证,此开发板上的芯片是钰创DDR2型号。先在二级bootloader ddr_init中验证retention功能,开发完成后再跑业务验证。因为ddr2 初始化流程简单,只包含了一项读方向的RX DQS Gating training,只涉及cycsel delay、ophsel delay和dllsel delay,不会进行读写training操作,也就不会破坏DDR中的数,并且在DDR2初始化过程中也不会对颗粒做复位操作,所以针对DDR2的retention过程中的training功能可以选择重新training方式或bypass training方式,当前DDR2 retention方案我们选的是重新training方式。这样的好处是无需向存储介质(如spi-nor flash)中保存数据。
后来业务层评估DDR2容量不够,需要改用ddr3,根据业务层需求,先将DDR2 retention流程移植到了DDR3上面,自测ok后转给业务层使用,业务层发现AOV设备无法保存LPRTC的值,后面检查发现AOV设备没有连接LPRTC也就无法使用LPRTC保存retention标记。在此期间由于其他高优先级任务插入,后面与业务层协商先使用在DDR中的标记作为retention的标记,但是会引入一个问题就是无法使用正规的DDR3 retention流程去恢复DDR,只能用沿用之前DDR2的重新training方案。与业务层沟通此方案的弊端,业务层觉得可以接受此风险,决定先用重新training方案试试看。
后来在实际业务使用过程中发现在DDR3的个别设备中出现DDR中保存的kernel代码段有数据错乱现象,经过分析此问题与DDR3重新training有关,经过仿真看波形与打印training各阶段的时间,发现有三点风险:1)控制phy上电的buffer_core_en线造成cke拉高的时机有些靠前,有提前退出自刷新的风险。2)使用重新training方案会将DDR3颗粒进行初始化,导致颗粒中的数据不可靠。3)使用重新training方案时,training过程耗时较长,超过了tREFI刷新周期(7.8us),有掉数据风险。针对以上三点风险,分别做了修正,调整buffer_core_en时机,在training阶段增加phy控制的补自刷新流程,但始终无法解决第二点风险。所以综合评估后只能想办法使用正规retention流程来解决此问题。正规retention方案会将training数据保存到spi-nor flash上,执行retention恢复时使用此training数据跳过training步骤,所以在DDR初始化阶段将会有两条初始化序列。
因为aov设备改版缓慢,临时将retention标记放在spi-nor flash上继续做方案验证。等后面改版后,再将retention标记放在lprtc寄存器中。
2.1 硬件电路修改支持retention功能
将DDR颗粒的VDD常供电
VDD_DDR_VDDQ是给 ddr phy与ddr颗粒供电的电源。
DDR颗粒中供电引脚名字叫VDD,对应DDR phy中则是VDDQ,因为是合封芯片,DDR phy VDDQ模拟电路为ddr颗粒供电。DDR PHY的VDD是VDD_CHIP 0.9V,将VDD_CHIP断电,那么phy的core电源(数字电路)就会断电。
在DDR2 EVB板子上验证LP_RTC方案(ddr颗粒不断电,其他包括always on、ddr phy core等全断电)流程如下:
- 系统上电初始化ddr和时钟
- 写入ddr pattern数据
- 进入芯片休眠逻辑
- ddr休眠逻辑
- 向lp-rtc寄存器中写入休眠标记
- 拨码开关断电
- 等待一段时间波动拨码开关重新整体上电
- 芯片进入唤醒逻辑
- 根据lp-rtc中标记的休眠标记信息判断进入唤醒逻辑代码(重新初始化ddrc与ddr phy)
- 执行ddr相关唤醒逻辑
- 校验休眠前写入ddr的pattern数据,测试ddr
2.2 软件修改支持retention方案
2.2.1 DDR控制器retention下电处理流程
Step | Description | Comment | |
1 | Write ‘0’ to PCTRL_n.port_en | Blocks AXI ports from taking anymore transactions 禁用各个port口 | |
2 | Poll PSTAT.rd_port_busy_n = 0 Poll PSTAT.wr_port_busy_n = 0 | Waits unit all AXI ports are idle 等待各port口读写状态变idle | |
3 | Write ’0’ to SBRCTL.scrub_en | Disables SBR, only required if SBR instantiated 禁用 SBR,仅当 SBR 实例化时才需要 | |
4 | Poll SBRSTAT.scrub_busy = 0 | Indicates that there are no outstanding SBR read commands, only required if SBR instantiated. 指示没有未完成的 SBR 读取命令,仅在 SBR 实例化时才需要。 | |
5 | Write ’1’ to PWRCTL.selfref_sw | Causes system to move to Self Refresh state For LPDDR4, PWRCTL.stay_in_selfref must be set to ’0’ to enter Self Refresh Power down. 导致系统进入自我刷新状态 对于 LPDDR4,必须将 PWRCTL.stay_in_selfref设为“0”才能进入自刷新关机状态。 | |
6 | Poll STAT.selfref_type= 2’b10 Poll STAT.selfref_state = 2'b10 (LPDDR4 only) | Waits until Self Refresh state is entered If DDR4 retry is enabled by CRCPARCTL1.crc_parity_retry_enableand software intervention is enabled by CRCPARCTL1.alert_wait_for_sw. Also monitor CRCPARSTAT.dfi_alert_err_intand CRCPARSTAT.dfi_alert_err_fatl_intduring the polling STAT.selfref_type. If one or more of them are asserted before the polling is done, complete the retry procedure prior to the subsequent steps. For LPDDR4, wait until Self Refresh Power Down state is entered. | |
7 | Place IOs in retention mode 将 IO 置于retention模式 | Refer to relevant PHY databook for more information phy 进入retention流程 | |
8 | Remove power | ||
2.2.2 DDR phy进入低功耗与retention恢复流程
有三种方式使芯动phy进入低功耗模式,分别为核心电源断电、停止时钟(dfi_4x/dfi_1x)进入低功耗模式和配置DFI低功耗接口模式(dfi_1x时钟保持)。我们尝试第一种核心电源断电模式。
信号bufferen_core用于控制DDRn/LPDDRn IO的工作状态,并由核心电源域提供。当信号bufferen_core高电平时,DDRn/LPDDRn IO将在正常模式下工作。当信号bufferen_core低电平时,PHY将保持IO CKE低,IO RESETN高,并关闭其他RESETN。
phy 断电步骤:
1. DDRn/LPDDRn控制器发送进入自刷新命令,使SDRAM进入自刷新模式,然后读取每个通道的校准结果和其他training参数,并保存下来以供后面使用。
2. 信号bufferen_core变为低电平。然后,所有 DDRn/LPDDRn IO 输出仅与 VDDQ 电源相关,IO CKE 将保持低电平,而 IO RESETN 将保持高电平。
3. 核心电源断电
4. 核心电源仍处于断电状态。
phy 恢复步骤:
- 核心电源等待并开始上电:
- 恢复参数设置,并将校准值(在步骤1中读出)写入校准旁路寄存器,并将其他训练结果值写入其他训练旁路寄存器,或再次进行所有训练。
- 如果PHY包含PLL,则启用PLL并等待PLL锁定并输出稳定时钟。
- 设置dfi_init_start信号高,等待dfi_init_complete变为高,然后完成PHY初始化。
- 发送自刷新命令,使PHY进入自刷新模式。
- 将bufferen_core信号调高以启用IO。当从DDR控制器接收到退出自刷新命令时,SDRAM退出自刷新状态
注意:
- 校准结果寄存器是只读的,它们与校准旁路寄存器不同。
- 在phy断电步骤2,在phy恢复步骤2 bufferen_core信号变为高之前,保持控制器在DFI接口上输出自刷新命令。
2.2.3 控制器电源恢复流程:
Step | Description | Comment | |
1 | 通过以下方式启用电源并重置控制器/PHY Enable power and reset controller/PHY by driving core_ddrc_rstn = 1'b0, areset_n = 1'b0, presetn = 1'b0 | ||
2 | 如果时钟在断电后被禁用,则重新启用时钟 Re-enable clocks if clocks were disabled after power removal | ||
3 | 移除 APB 复位,presetn = 1'b1,并将寄存器重新编程为断电前的值 Remove APB reset, presetn = 1’b1, and re-reprogram the registers to pre-power removal values | ||
4 | Program INIT0.skip_dram_init = 2’b11 | 跳过 DRAM 初始化进程,以自刷新模式启动 ?? Skips the DRAM init routine and starts up in self-refresh mode | |
5 | Programs PWRCTL.selfref_sw = 1’b1 | 使控制器保持在自刷新模式 Keeps the controller in self-refresh mode | |
6 | Program DFIMISC.dfi_init_complete_en to 1’b0 | 需要重新运行 PHY 初始化,因此请设置为“0”,直到初始化完成 PHY initialization needs to be rerun so set to ’0’ until initialization complete | |
7 | 移除控制器复位 Remove the controller reset core_ddrc_rstn = 1’b1 aresetn_n = 1’b1 | ||
8 | 根据需要运行 PHY 初始化/training训练,包括从retention模式中删除 IO Run PHY initialization/training as required, including removing the IOs from retention mode | Synopsys 传统 PHY 可能需要更多步骤。有关详细信息,请参阅相关的 PHY 数据手册 Synopsys legacy PHYs may require more steps. Refer to the relevant PHY Databook for more information. | |
9 | Program DFIMISC.dfi_init_complete_en to 1’b1 | 向控制器指示 PHY 已完成重新training训练/初始化 Indicates to controller that PHY has completed re-training/initialization | |
10 | Program PWRCTL.selfref_sw = 1’b0 | 触发退出自刷新 trigger self-refresh exit | |
11 | Poll STAT.selfref_type = 2’b00 | 检查变为退出自刷新状态 Wait until self-refresh state is exited | |
12 | Poll STAT.operating_mode for Normal Mode entry | 检查模式,准备进入normal模式 | |
13 | Write PCTRL.port_en = 1 | 打开AXI 各port口 AXI ports are no longer blocked from taking transactions | |
14 | Write ’1’ to SBRCTL.scrub_en | 如果需要,启用 SBR,仅当 SBR 实例化时才需要 Enable SBR if desired, only required if SBR instantiated | |
构建ddr retention测试case:先向ddr写入1MB固定的数据,配置休眠,延时5分钟,再配置唤醒,检查ddr数据是否是正常数据。
2.2.4 DDR2重新training(冷启动)流程
1. 使能ddr pll时钟
2. 进入ddr初始化函数入口
3. 复位控制器与phy
4. 执行phy初始化
5. 解复位控制器apb时钟
6.配置DDR控制器时序等参数
7.正式全部解复位ddr控制器
8.将dfi_start 信号拉高,等待dfi初始化完成
9.使能bufferen_core打开phy的io
10.执行phy training初始化(只有RX DQS Gating training调整时序delay)
11.配置phy为自动刷新
2.2.5 DDR3 retention初始化流程
DDR3有两种初始化流程,通过判断retention flag来确定用哪一条。
2.2.5.1冷启动初始化流程(retention flag 非0xAA):
1. 使能ddr pll时钟
2. 进入ddr初始化函数入口(判断retention flag是否为非0xAA,如果非0xAA则走当前流程)
3. 复位控制器与phy
4. 执行phy初始化
5. 解复位控制器apb时钟
6.配置DDR控制器时序等参数(ADDRMAP/DRAMTMG/ODT/SCHED/QOS/PCFG/PWR)
7.正式全部解复位ddr控制器
8.将dfi_start 信号拉高,等待dfi初始化完成
9.使能bufferen_core打开phy的io
10.执行phy training初始化,并保存training值(RX DQS Gating、write_leveling、read training、write training)
11.配置phy为自动刷新
12.检查是否更新存储介质中的training数据(training 中心点偏差5则更新,在介质中默认保存两份且有crc校验)
注:
1. 使用DDR3 evb测试过零下20摄氏度training值与常温training值变化情况,只有有很少数据中心点有1~2的变化(窗口范围50)
2. 使用DDR3 evb测试高温93摄氏度training值与常温training值变化情况,training中新点偏差小于5。
3. 使用AOV设备测试过通过此测试数据来看,小系统运行时芯片表面温度60.5℃,大系统kernel启动后两小时一直运行温度稳定后的温度为92.6℃,基本达不到更新存储介质的阈值,存储介质被频繁擦写导致异常的风险较小。
2.5.2.2 retention恢复启动流程(retention flag 0xAA):
1. 使能ddr pll时钟
2. 进入ddr retention恢复函数入口(判断retention flag是否为0xAA,如果是0xAA则走当前流程)
3. 复位控制器与phy
4. 解复位控制器apb时钟
5.配置DDR控制器时序等参数,需要配置skip dram init功能(ADDRMAP/DRAMTMG/ODT/SCHED/QOS/PCFG/PWR)
6.正式全部解复位ddr控制器
7. 执行phy上电流程,phy初始化
8.恢复phy training参数(RX DQS Gating、write_leveling、read training、write training)
9.将dfi_init_start 信号拉高,等待dfi初始化完成
10.发送自刷新命令,使phy保持在自刷新模式
11.使能bufferen_core打开phy的io功能
12.配置软件自刷新
13.检查operating_mode变为Normal
14.配置phy为自动刷新
正规ddr3 retention恢复流程关键信号仿真波形:
在DDR3 evb开发板上加打印,实测各个关键点耗时,bufferen_core拉高到配置自动刷新完成所需时间为3us,低于tREFI 7.8us要求,满足retention过程自刷新与自动刷新切换的要求。
2.3 DDR retention flag 与training值存储位置如下:
注意: 因为ddr training data比较重要,在保存的时候增加了crc校验,并存储两份,当第一份crc校验不过时,取第二份结果,同时也会使用loop reg中读出来的信息做对比,确保写入的值正确。
2.4 当前DDR retention业务流程图:
2.5 整体业务流程图:
三、遇到的问题
1.在使用DDR2 EVB板子验证的时候遇到如下问题:
1)always on 0.9v未断电,导致cpu无法正常运行。smu如果不进入ext模式,那么cpu无法再次运行,硬件同事将always on 都断电后正常。
2)lp_rtc alarm2寄存器读出来数据为0xcb,写入数据后不能正常保存: 将纽扣电池换到另外板子上实验后,再次安装纽扣电池后变正常,疑似纽扣电池亏电,需要充电。
2.在使用DDR3 AOV设备的时候,使用重新training的retention方案遇到ddr内存数据异常的问题,改用正规ddr3 retention bypass training方案后问题消失。本文中也做了大量针对此问题的描述。