:UFS UMCP 软件设计规范)
面向UFS 3.1 LPDDR4X 合封JEDEC uMCP的固件驱动设计约定 —— 覆盖双器件独立初始化、LUN 与 Boot LU、UTP 命令队列、WriteBooster 掉电风险、LPDDR4X 训练与刷新与热耦合温控逐条给出可落地的流程、判据与超时预算。2套独立总线6路电源域11.67Gbps / lane297ball FBGA文档编号uMCP-SW-SPEC-001版本 / 状态V1.0 · 正式发布适用器件JEDEC uMCPUFS 2.1 / 2.2 / 3.0 / 3.1 LPDDR4 / LPDDR4X / LPDDR5典型配置 UFS 3.1 LPDDR4X254 / 297 / 315-ball FBGA参考标准JESD220CUFS 3.1· UFSHCI 3.0 · UniPro 1.8 · M-PHY 4.1 · JESD209-4BLPDDR4 / 4X配套文档uMCP_电路设计指南.html原理图 / 电源时序 / PCB Layout / 热设计 / 焊接0. 目的与范围本规范约束 uMCP 器件在嵌入式固件中的软件行为初始化顺序、LUN 与 Boot 配置、 命令提交与同步语义、掉电与热管理、DRAM 训练与刷新。凡本文与器件 datasheet / JEDEC 规范冲突以 datasheet 为准。统一启动顺序固化「电源 → REF_CLK → 释放复位 → UFS 链路训练 → 读 SPL → 训练 DRAM → 加载系统」这条不可颠倒的链。统一同步语义明确 WriteBooster 开启时「写完成 ≠ 已落盘」关键数据必须SYNCHRONIZE CACHE。统一错误恢复阶梯任务 → LUN → 器件 → 链路 → 硬件复位逐级升级不越级、不静默。统一掉电与热策略给出写窗口、提交协议、休眠唤醒顺序以及 UFS 与 DRAM 之间的双向热耦合对策。不在本规范范围原理图、电源时序、PCB Layout 与焊接见《uMCP 电路设计指南》 文件系统与 FTL 的算法选型UFS Host 控制器 IP 的 RTL 设计与 PHY 寄存器级调试细节。一句话结论uMCP 是「一颗封装里两个互不认识的世界」—— UFS 走M-PHY UniPro UTP SCSI四层协议栈LPDDR4X 走并行训练总线两者封装内部没有任何信号互连。没有 SYNCHRONIZE CACHE 的写入不等于落盘没有完整训练的 DRAM 在高低温下必然出错带着未初始化 DRAM 继续启动会在后续随机崩溃。文档使用说明本文是《uMCP 电路设计指南》的软件配套篇硬件篇解决「怎么供电、怎么走线、怎么散热」本文解决「驱动怎么写、两侧怎么配合、异常怎么救」。协议分层、命令集、描述符与属性均按JEDEC JESD220CUFS 3.1与UFSHCI 3.0描述。不同料号在 LUN 数量、Gear 档位、WriteBooster 支持上存在差异移植前必须逐条核对器件 Device Descriptor。文中 C 代码为协议骨架伪代码演示流程与判断条件非特定平台可直接编译的完整实现ufshci_*、dram_mr_write()等为平台相关底层。贯穿全文的三条铁律①先 UFS 后 DRAM顺序不可颠倒——BootROM 只有片内 SRAM必须先从 UFS 的 Boot LU 取到 SPL才可能训练 DRAM ②开了 WriteBooster 就必须显式同步——写入返回成功只代表进了 SLC 缓存不等于持久化 ③两侧都要有独立的超时与失败处理——任一侧失败都必须给出明确指示点灯 / 串口日志 / 进下载模式不能静默继续。1 · 器件定位与双器件架构uMCP 不是「更快的 eMMC」。它把 UFS 存储与 LPDDR 内存装进同一个封装对外呈现两组电气与协议完全独立的接口。软件设计的第一件事是认清「哪些是共用的、哪些是分开的」。1.1 一颗封装、两套总线uMCP 内部两颗独立芯片UFS存储与 LPDDR内存封装内无信号互连PMIC六路电源 上电时序SoC / AP• UFS HostM-PHY UniPro• LPDDR4X 控制器• REF_CLK 输出常供• GPIORST_n 等• 掉电检测中断uMCP · 297-ball FBGAUFS dieNAND UFS 控制器VCC / VCCQ / VCCQ2M-PHY 差分 TX / RX协议SCSI over UTP软件UFS 驱动必须先初始化LPDDR4X dieDRAM 阵列 控制逻辑VDD1 / VDD2 / VDDQCA / DQ / DQS / CLK协议命令真值表软件训练 MRS由 SPL 训练TX/RXCA/DQ封装内部 UFS 与 DRAM 无任何信号互连仅 VSS 共地 —— 必须分别初始化、分别超时、分别失败处理图 1 · uMCP 双器件架构共用封装与地各自独立的电源、总线与协议栈1.2 关键参数与软件视角2 套完全独立的总线UFS 串行差分 LPDDR 并行封装内仅共地6 路需独立管理的电源轨VCC / VCCQ / VCCQ2 / VDD1 / VDD2 / VDDQ11.67Gbps / laneHS-G42 lane 全双工聚合 23.3 Gbps297焊球数UFS 3.1 LPDDR4X0.4 / 0.5 mm pitch约 12 × 12 mm0.6 VLPDDR4X 的 VDDQ裕量最小混料会直接烧器件32UTP 命令队列深度上限MCQ 模式下更高需按描述符确认80 %建议容量使用率上限给 FTL 留 GC 与磨损均衡空间200随机掉电测试次数下限关键数据可恢复率须 100 %参数取自《uMCP 电路设计指南》第 1~3 章与 JEDEC JESD220C具体料号以 Device Descriptor 读回值为准。1.3 六路电源域的软件可见性电源是硬件的事但每一路都会以某种形式反映到软件行为上。驱动必须知道哪些现象对应哪一路电源的问题电源轨归属典型电压软件可见的失效表现VCCUFS2.5 / 3.3 V链路能建但读写报介质错误写入中途 VCC 跌落 → 映射结构损坏VCCQUFS1.2 VUFS 3.xUFS 控制器不响应Host 寄存器读写返回全 FVCCQ2UFS1.8 VM-PHY 模拟链路训练直接失败存储「完全不存在」VDD1LPDDR1.8 V训练不收敛降速后仍不稳定VDD2LPDDR1.1 V大电流突发下压降 → 高负载时才出现读写错VDDQLPDDRLPDDR4: 1.1 V / 4X:0.6 VVref 训练找不到有效窗口读写零星比特错误软件排查的基本原则先看电源与时钟再怀疑协议uMCP 的 Bring-up 故障里绝大多数不是协议问题。按《uMCP 电路设计指南》5.3 的 Bring-up 顺序查 六路电源实测 → REF_CLK 实测 → RST_n 实测 → UFS 能否枚举 → 链路档位 → DRAM 训练。前三项占实际故障的绝大多数第 4 项只在设计本身有缺陷时才是主因。1.4 与 eMCP 的关键差异移植必读维度eMCPeMMC LPDDRuMCPUFS LPDDR移植后果存储接口11 根并行单端半双工2~3 对串行差分全双工驱动栈完全不同不可复用时钟主控给 CLK可随时降频 / 暂停REF_CLK 固定频率必须常供休眠时关时钟 → 唤醒后链路重训上电可用上电后给时钟即可发命令必须完成M-PHY Link Startup未训练前存储完全不可访问命令模型CMD / 响应单命令串行UTP UTRD 队列可多命令并发需管理每个命令的完成回调与超时Boot 区硬件固定 Boot PartitionBoot LU 需配置并使能bBootLunEn量产漏配 → 完全不启动写缓存eMMC Cache需 flushWriteBoosterSLC 缓存需同步未同步掉电 → 数据丢失省电态Sleep / PowerDown增加Hibern8链路休眠退出需唤醒时序有恢复延迟DRAM 侧LPDDR3 / 4 / 4XLPDDR4 / 4X / 5训练流程与刷新率需重新适配一句话区分eMCP 与 uMCP 的区别只在存储那一半eMMC 是并行单端UFS 是串行差分。 DRAM 那一半LPDDR的设计规则基本一致。所以从 eMCP 转到 uMCP要重学的是 UFS 侧DRAM 侧的经验可以平移。2 · 术语与缩写UFS 的术语体系与 eMMC 几乎不重叠。本章统一口径避免「LU / LUN / Boot / 描述符」在文档与代码里指的不是同一件事。2.1 协议与命令术语缩写 / 术语全称本文中的含义uMCPUFS-based Multi-Chip PackageUFS 存储 die LPDDR DRAM die 合封在一个 FBGA 内M-PHY—物理层PWM 模式用于初始化HS-G1~G4 用于正常工作Gear速率档M-PHY 的工作速率档位HS-G11.46 HS-G411.67 Gbps/laneUniProUnified Protocol数据链路 / 传输层负责端口、流控与电源模式协商UTPUFS Transport Protocol传输层用 UTRD 描述一个命令用 UPIU 承载具体内容UTRDUTP Transfer Request Descriptor命令描述符位于主机内存写门铃寄存器即提交命令UPIUUFS Protocol Information Unit协议信息单元COMMAND / RESPONSE / DATA-IN / DATA-OUT / TASK MGMT 等LUNLogical Unit Number逻辑单元编号0~7其中 0xB0 系列为 Well-Known LULULogical Unit逻辑单元本体一个独立的 SCSI 逻辑设备与 LUN 常被混用Boot LUBoot Logical Unit存放 SPL 的专用 LUA / B 两份互为备份RPMBReplay Protected Memory Block防重放认证存储HMAC-SHA256 认证密钥一次性烧写WriteBooster—UFS 3.x 的 SLC 写缓存加速写入先进缓存返回后再搬运Hibern8HibernateUniPro 链路休眠M-PHY 进入省电态退出需唤醒时序Descriptor描述符只读的结构化信息块Device / Configuration / Unit / Geometry / HealthFlag标志布尔型开关读 / 写 / 置位 / 清零 / 切换bBootLunEn、fPowerOnWPEnAttribute属性数值型参数bCurrentPowerMode、bAvailableWriteBoosterBufferSizeUNMAP—SCSI 命令等价于 eMMC 的 Trim告知器件数据块不再需要FFUField Firmware Update器件固件在线升级过程绝对不能掉电ZQZQ CalibrationDRAM 输出驱动强度与 ODT 的校准基准电阻 240 Ω ±1 %WL / DQS GateWrite Leveling / DQS Gate TrainingDRAM 训练项补偿 CLK-DQS 偏差 / 确定 DQS 有效采样窗口tREFIRefresh IntervalDRAM 刷新间隔随温度档缩短SPLSecondary Program Loader二级引导程序存放在 Boot LU由 BootROM 读入片内 SRAM2.2 本文书写约定命令名沿用 SCSI / UFS 规范的大写形式如READ (10)、SYNCHRONIZE CACHE (10)、UNMAP不带h后缀——UFS 没有「命令码字节」的概念命令以 CDB 形式封装在 UPIU 里。描述符 / 标志 / 属性按其命名前缀书写b 1 字节、w 2 字节、d 4 字节、q 8 字节f开头的标志为布尔型。速率档写作HS-G4/PWM-G1「11.67 Gbps」均指单 lane 线速率2 lane 聚合值会显式标注。时序量级以「数 ms / 数十 ms / 数百 ms」给出——不同料号与不同 SoC 差异较大绝对值须以实测与手册为准。代码示例为 C 伪代码省略控制器寄存器底层实现只表达流程与判据。3 · 驱动架构与配置载体UFS 驱动比 eMMC 多两层命令队列管理和设备配置管理。这两层放错位置后面所有优化都是白做。3.1 分层职责层职责禁止做的事应用层业务读写文件 / 分区不感知 LUN 与缓存直接拼 CDB、直接操作门铃寄存器文件系统层日志 / 事务删除时下发UNMAP绕过 sync 语义宣称数据已持久化块设备与 LUN 管理层LUN 枚举与映射、Boot LU 选择、RPMB 认证、健康度轮询硬编码 LUN 编号忽略 WriteBooster 状态UFS 协议层UTP构造 UTRD / UPIU、提交门铃、管理完成回调与超时提交命令后不做超时回收忽略 RESPONSE UPIU 状态Host 控制器层UFSHCI寄存器配置、中断、DMA 描述符环在链路活动期间门控 REF_CLKUniPro M-PHY 层Link Startup、Power Mode Change、Hibern8 进出不做降档重试直接判定器件损坏DRAM 驱动 / 训练模块MRS 配置、ZQ 校准、各项训练、刷新率调节、自刷新进出跳过训练项固定刷新率不随温度调整3.2 UFS 协议栈四层分工UFS 协议栈四层软件直接打交道的只有最上两层软件Application / SCSI 命令集READ(10/16) · WRITE(10/16) · UNMAP · SYNCHRONIZE CACHE · FORMAT UNIT文件系统块设备层软件UTPUFS Transport ProtocolUTRD 门铃提交 · UPIU 承载命令/数据/响应 · 任务管理 · 队列并发UFS 驱动UTP 层软硬UniPro数据链路 / 传输层L4 端口 · 流控 · 错误恢复 · 电源模式Hibern8协商主控硬件 固件硬件M-PHY物理层PWM-G1 初始化 · HS-G1~G4 协商 · 差分链路 · Link StartupPHY PCB阻抗 / REF_CLK分层排查原则性能问题看上两层「存储完全不存在」看下两层电源 / REF_CLK / 链路图 2 · UFS 协议栈四层硬件只需把 M-PHY 做对软件只需把 UTP 写对3.3 描述符 / 标志 / 属性三种配置载体UFS 的配置没有「一个寄存器搞定」这回事而是分成三类载体访问方式各不相同。分不清这三类是所有 UFS 配置错误的根源。三类配置载体只读信息用描述符布尔开关用标志数值参数用属性Descriptor描述符 · 只读访问方式QUERY REQUEST读典型成员Device / ConfigurationUnit / GeometryHealth / String用途能力探查Flag标志 · 布尔开关访问方式SET / CLEAR / TOGGLE典型成员bBootLunEnfPowerOnWPEnfPermanentWPEn用途功能开关Attribute属性 · 数值参数访问方式WRITE / READ按位宽典型成员bCurrentPowerModebActiveICCLevelbAvailWriteBoosterBufSize用途运行期调节配置改变通常需要器件复位后才生效部分配置永久写保护、OTP 类不可逆图 3 · 描述符 / 标志 / 属性三类载体的访问方式与典型成员命名前缀就是位宽说明UFS 的标识符前缀直接告诉你它的大小b 1 字节、w 2 字节、d 4 字节、q 8 字节f开头的是布尔标志。 写代码时不要凭感觉定义变量宽度——把dNumDynamicLU4 字节用uint8_t去读读回来的是截断值。4 · 上电初始化与 Bring-upuMCP 的启动有一条不可颠倒的链路。任何一步没过后面都不可能发生——这是它与分立式方案最大的不同。4.1 不可颠倒的启动链冷启动全链路任何一步不过后面都不可能发生① PMIC 六路上电VCC → VCCQ → VCCQ2 → VDD1 / VDD2 / VDDQ 依次斜升每路单调② REF_CLK 起振稳定19.2 / 26 / 38.4 MHz必须在 RST_n 释放之前稳定且持续供给③ 释放 RST_n低有效所有电源稳定后再释放留足余量④ M-PHY Link Startup器件自动完成链路训练未完成时存储完全不可访问⑤ BootROM 从 Boot LU 读 SPLbBootLunEn 必须已使能A / B 双份失败自动切换另一份⑥ SPL 训练 LPDDR4X 并加载后续镜像ZQ → Write Leveling → DQS Gate → Read/Write Training → Vref → 校验容量顺序不可颠倒必须先从 UFS 取到 SPL才可能训练 DRAM图 4 · uMCP 冷启动链UFS 通了再谈 DRAM4.2 UFS 侧初始化流程上电后器件处于未配置状态链路刚跑在最低速的 PWM-G1Boot LU 未使能WriteBooster 状态未定LUN 布局需自行读取。初始化必须按下列顺序执行等待 Link Startup 完成轮询 Host 控制器状态确认链路已从 PWM-G1 协商到目标 Gear。此步不由软件驱动硬件自动完成软件只做确认与超时。读 Device Descriptor拿到版本、LUN 数、容量、支持的 Gear、WriteBooster 支持位等见 4.3。校验能力是否达标若协商到的 Gear 低于预期先记日志再继续不要直接判定失败——降档运行比不启动好。枚举 Unit Descriptor逐个 LUN 读单元描述符建立lun_id → 用途映射不硬编码编号。配置 Boot LU 并使能写bBootLunEnBoot LU 建议同时设fPowerOnWPEn上电写保护。配置 WriteBooster按产品策略决定开关见第 7 章若开启同步配置缓存水位监控。读 Health Descriptor记录bDeviceLifeTimeEstA/B与bPreEOLInfo作为基线。验证读写对 User LU 做一次小规模读写回环确认链路与协议均可用。/* uMCP 冷启动UFS 先行返回 0 表示成功 */ int umcp_boot_init(void) { ufs_dev_t dev; /* ① 电源与时钟由硬件 / PMIC 完成软件只做确认 */ if (!power_rails_ready()) return -E_POWER; if (!refclk_stable()) return -E_CLK; /* ② 等待 M-PHY Link Startup硬件自动完成软件只看结果 */ if (ufshci_wait_linkup(LINKUP_TIMEOUT_MS) ! 0) return -E_LINKUP; /* 绝大多数是电源 / REF_CLK / RST_n 问题 */ /* ③ 读 Device Descriptor 识别器件能力 */ if (ufs_read_dev_desc(dev) ! 0) return -E_NODEV; if (dev.b_num_lu 0) return -E_NODEV; /* ④ 枚举 LUN从描述符读不硬编码 */ if (ufs_enum_units(dev) ! 0) return -E_LUNCFG; /* ⑤ 配置并使能 Boot LU同时开上电写保护 */ if (ufs_write_flag(F_BOOT_LUN_EN, 1) ! 0) return -E_BOOTCFG; if (ufs_set_boot_wp() ! 0) return -E_BOOTCFG; /* ⑥ 按产品策略配置 WriteBooster */ if (g_wb_enable) { if (ufs_write_attr(B_WB_BUF_RESIZE, g_wb_size) ! 0) return -E_FEATURE; } ufs_write_flag(F_WRITE_BOOSTER_EN, g_wb_enable); /* ⑦ 记录健康度基线 */ ufs_read_health_desc(dev.health); return 0; /* 此后才由 SPL 训练 DRAM */ }初始化里最容易漏的两件事①bBootLunEn没有使能。UFS 与 eMMC 不同eMMC 的 Boot 分区是硬件固定的而UFS 的 Boot LU 必须先配置并使能。 量产时只烧数据、漏配 Boot LU板子上电后 BootROM 找不到 SPL表现为「完全不启动」。首次点亮新料号时尤其容易踩——器件是新的Boot LU 可能还是出厂默认状态。② Link Startup 超时被当成「器件坏了」。链路训练失败的表现是「存储完全不存在」而不是「速率慢」。遇到它先查六路电源、REF_CLK、RST_n 这三项前三项占实际故障的绝大多数。4.3 器件识别读 Device DescriptorDescriptor 是唯一可靠的能力来源。把页大小、LUN 数、Gear 硬编码进驱动换料就要改代码。字段含义软件用途bLength / bDescriptorIDN描述符长度与类型校验读到的是不是想要的描述符bDeviceSubClass / bDeviceClass设备类别确认是 UFS 存储设备Embedded / Removable / DiskwSpecVersionUFS 版本判定支持哪些特性3.1 才有 WriteBooster 完整能力bNumberLULUN 数量枚举范围不可硬编码bBootEnableBoot 功能是否使能与bBootLunEn联动判断 Boot 可用性dNumDynamicLU / wNumberOfBlocks可配置 LU 数 / 逻辑块数容量与分区规划依据bSupportedWriteBoosterWriteBooster 支持位决定第 7 章策略是否可执行bSupportedGear / bMaxGear支持的速率档与实际协商档位比对判断是否存在硬件降档iManufacturerName / iProductName厂商 / 型号字符串索引配合 String Descriptor 读出可读型号用 String Descriptor 做型号识别读 ID 类命令在 UFS 里没有等价物。要识别具体料号应读String Descriptor由iProductName索引把型号字符串解析出来并记入日志。 现场返修时这条日志能直接区分「换了料号」还是「同一料号批量退化」。4.4 LPDDR4X 侧初始化与训练DRAM 训练由 SPL 软件完成硬件的职责是提供足够的信号裕量。五个训练项一个都不能省LPDDR4X 训练五步任一项跳过常温下可能能跑高低温下必然出错① ZQ 校准240 Ω ±1 %驱动强度 / ODT基准② Write Leveling补偿 CLK 与DQS 飞行时间偏差③ DQS Gate确定 DQS有效采样窗口位置④ 读写训练寻找 DQ 相对DQS 最佳采样点数据眼图⑤ Vref 训练寻找接收端参考电压最佳值含 DQ CA训练失败 → 降速重试先降一档频率重试完整流程多档都失败才报硬件故障训练通过 ≠ 稳定ZQ 用 5 % 电阻时训练可能勉强通过但读写不稳定结束后校验容量位宽与预期不符 → 贴错料 / 混料LPDDR4 vs 4XVDDQ 不同绝不允许「跳过训练直接用默认参数跑」常温下可能能跑高低温、高负载、老化后必然出现零星比特错误 —— 这类错误无法定位代价最高图 5 · LPDDR4X 训练五步与三条硬约束/* DRAM 初始化完整训练 降速重试 */ int dram_init(void) { const uint32_t freqs[] { TARGET_FREQ, TARGET_FREQ / 2, SAFE_FREQ }; int i; dram_power_up(); /* 电源斜升 - 时钟稳定 - 复位 - 释放 */ dram_mr_init(); /* 模式寄存器基本配置 */ for (i 0; i 3; i) { dram_set_freq(freqs[i]); if (zq_calibrate() ! 0) continue; /* ① */ if (write_leveling() ! 0) continue; /* ② */ if (dqs_gate_training() ! 0) continue; /* ③ */ if (read_write_training() ! 0) continue; /* ④ */ if (vref_training() ! 0) continue; /* ⑤ */ if (dram_check_size() ! 0) /* 容量 / 位宽校验 */ return -E_DRAM_MISMATCH; return 0; /* 训练成功记录实际运行频率 */ } return -E_DRAM_TRAIN; /* 三档全失败 - 硬件问题不静默继续 */ }4.5 失败分级处理uMCP 两侧各自都要有明确的失败出口。带着未初始化的 DRAM 继续启动会在后续以随机崩溃的形式暴露是最难查的一类故障。失败阶段典型原因推荐动作禁止动作六路电源未就绪PMIC 未使能 / 某路漏设计串口打印具体缺失的电源轨停机重试几次后继续Link Startup 超时VCCQ2 处理错 / REF_CLK 缺失或频率错打印电源与时钟实测结果进下载模式判定器件损坏器件识别失败描述符读取异常 / 型号不符打印读回的原始描述符停机用默认值兜底继续Boot LU 读取失败bBootLunEn未使能 / A 份损坏自动切换到 B 份两份都失败进下载模式只重试 A 份DRAM 训练失败参数表与料号不符 / 三路 DRAM 电源异常降速重试全部档位仍失败则停机并打印训练日志跳过训练继续启动容量位宽不符贴错料 / LPDDR4 与 4X 混料停机并明确指出「料号不符」按实际容量继续跑两侧都要有可观测的失败指示上电后 BootROM 只有片内 SRAM 可用很多平台连串口都还没初始化。此时失败指示要靠点灯 / GPIO 电平 / 进入下载模式这些最朴素的手段。 「板子上电毫无反应」和「板子上电后闪三下灯」在产线上的排查效率差一个数量级——这一点必须在固件设计阶段规划好而不是等量产卡住了再补。后续章节请下载「芯参谋」查看……篇幅原因, 还有16章· 详见芯参谋→方案设计当前分享仅开放前5章正文。详细资料请在芯参谋客户端中打开完整文档。打开路径解决方案应用市场分析 - 原理方案设计 - uMCP_软件设计规范 下载芯参谋客户端