3. DDR控制器寄存器配置基础:控制器类型、主要寄存器字段含义、配置前的上电序列检查

DDR初始化成功与否,核心取决于控制器寄存器的正确配置。当前主流SoC使用的DDR控制器IP主要来自Synopsys(DesignWare DDR)和Cadence(DDR Controller/PHY)两家。两类控制器在寄存器布局、访问时序、PHY接口上有显著差异,但配置逻辑均围绕“上电序列 → PLL/Training → 时序/阻抗 → DQ/DQS延迟”这一主线。本章从控制器类型出发,详解关键寄存器字段含义,并给出上电序列的必检清单。

3.1 控制器类型概述:Synopsys vs Cadence

两类控制器的结构对比如表3‑1所示。理解差异有助于快速定位寄存器手册中的物理层(PHY)与逻辑层(CTL)寄存区域。

对比项 Synopsys DesignWare DDR Cadence DDR Controller
IP体系 DDRCTL + DDRPHY(统一协议) CDCTL + DWC_DDRPHY(分离式)
寄存器基址 0xFD000000 ~ 0xFD00FFFF(典型) 0xFD300000 ~ 0xFD30FFFF(典型)
PHY初始化方式 内部状态机 + 驱动校准(ZQ) 固件序列(PHY Firmware) + 手动训练
主要寄存器组 DDR_PHY_REG, DDR_CTRL_REG CDN_CTL, CDN_PHY, CDN_TRAINING
常见应用 Qualcomm, MediaTek, 部分Intel Qualcomm (SA8155), Allwinner, Rockchip
🔍 判断方法:从Boot ROM或XBL代码中搜索“DDR_PHY_”或“CDN_”前缀。若寄存器名以 DDR_PHY_ 或 DDR_CTRL_ 开头,则为Synopsys;若包含 CDN_ 或 DWC_DDRPHY,则为Cadence。

3.2 主要寄存器字段含义(以Synopsys为例)

两类控制器寄存器数量均在300–500个,但XBL阶段真正需要配置的不足30个。表3‑2列举Synopsys控制器在配置时必须显式写入的关键字段。

寄存器(偏移) 字段名 位域 值示例 说明
DDR_PHY_REG_00 PLL_BYPASS [0] 0 0: 启用PLL;1: 旁路(调试用)
DDR_PHY_REG_04 VREF_DAC [15:8] 0x3F 参考电压DAC值,通常63(1.0V VDDQ)
DDR_PHY_REG_10 DQ_DRV_STR [5:0] 0x1B DQ驱动强度,27Ω(DDR4典型)
DDR_PHY_REG_1C DQS_SLEW [11:8] 0x2 DQS压摆率控制
DDR_CTRL_REG_30 CAS_LATENCY [7:4] 0xB CAS延迟(11 cycles @ 2133 MT/s)
DDR_CTRL_REG_34 ADDR_MAP [31:0] 0x1324 行列地址映射,取决于容量/颗粒配置

对于Cadence控制器,核心字段集中在 CDN_PHY_PLL_CTL(PLL倍频)、CDN_CTL_TIMING_ 系列(时序寄存器)、CDN_TRAINING_*(训练门控与眼图偏移)。两者共通的黄金法则是:先配PHY(物理层),再配CTL(逻辑层),最后启动训练。

3.3 配置前的上电序列检查(Power-Up Sequence Checklist)

寄存器写入前必须确认SoC与外设DDR颗粒之间的电源、时钟、复位已达标。以下步骤可在XBL入口点(如 TargetEarlyInit)执行,并使用GPIO或UART打印检查结果。

  1. VDDQ/VPP/VDD 电源检测
    使用ADC或PMIC状态寄存器读取DDR专用电压轨:VDDQ (1.2V ±3%)、VPP (2.5V ±2%)、VDD (1.1V ±3%)。电压超容差会导致寄存器编程后颗粒不响应。
  2. 参考电压VREFCA
    对于DDR4,测量VREFCA是否在0.5×VDDQ ±1%范围内;对于LPDDR4/5,VREF由PHY内部产生,需检查状态位VREF_READY。
  3. 时钟域检查
    确认DDR_CLK、DDR_CLK#差分对已有效振荡(频率误差 < ±100 ppm)。可通过读取PLL锁定位(如 DDR_PHY_REG_08[31] 的PLL_LOCK)判断。
  4. 复位信号
    验证DRAM_RESET_N已从低变高(保持>200μs后释放)。常用方法:配置GPIO为输出并手动拉高,再回读GPIO状态。
  5. ZQ校准电阻连接
    检查ZQ pin是否外接240Ω电阻(精度±1%),并通过读取ZQ_CAL_DONE(如 CDN_PHY_ZQ_CTL[0])确认校准完成。
⚠️ 常见陷阱:若上电序列未严格按JEDEC标准(电源稳定→时钟稳定→复位释放→ZQ校准→CKE拉高)执行,控制器寄存器即使写入正确值,DDR颗粒也可能处于未知状态,导致枚举失败。

3.4 DDR控制器类型判断与配置流程(SVG)

图3‑1展示了XBL阶段从识别控制器类型到完成初始化的典型流程。判断分支决定后续寄存器集合与PHY初始化调用方式。

DDR控制器类型判断与配置流程 图3‑1 DDR控制器类型判断与配置流程 开始:上电序列检查 判断控制器类型(读ID寄存器) Synopsys Cadence Synopsys寄存器配置 PLL / VREF / DQ_DRV Cadence寄存器配置 PHY_FW / CDN_CTL_TIMING DDR训练 / 校准 配置完成 说明:无论Synopsys还是Cadence,配置前均需完成上电序列检查(电压/时钟/复位/ZQ)

3.5 上电序列检查的代码实现示例

以下XBL代码片段(伪C语言)演示了如何以寄存器读写方式执行上电序列检查。实际芯片需替换为对应的基址和寄存器偏移。

#include "ddr_plat.h"

static int power_up_sequence_check(void)
{
    uint32_t status;

    // 1. 检查VDDQ电压(读PMIC状态寄存器)
    if (pmic_get_voltage(PMIC_VDDQ) < 1160 || pmic_get_voltage(PMIC_VDDQ) > 1240) {
        dprintf(CRITICAL, "VDDQ out of range!\n");
        return -1;
    }

    // 2. 等待PLL锁定(Synopsys示例)
    status = readl(DDR_PHY_BASE + 0x08);
    if (!(status & BIT(31))) {
        dprintf(CRITICAL, "DDR PLL not locked!\n");
        return -1;
    }

    // 3. 释放DRAM复位
    writel(0x1, GPIO_BASE + GPIO_OUT_SET);  // 拉高reset_n
    delay_us(200);                          // 保持至少200μs

    // 4. 等待ZQ校准完成(Cadence示例)
    status = readl(CDN_PHY_BASE + CDN_PHY_ZQ_CTL);
    if (!(status & BIT(0))) {
        dprintf(CRITICAL, "ZQ Calibration not done!\n");
        return -1;
    }

    dprintf(INFO, "DDR power-up sequence check PASS\n");
    return 0;
}
📌 调试技巧:若上电序列检查某一步失败,不要直接写入DDR寄存器。先通过UART打印错误类型,用示波器测量对应引脚波形(如VDDQ纹波、时钟摆幅、复位上升沿斜率)。XBL中可在每个检查点插入 dprintf 并配合 spin() 停留,便于单步观测。