4. GPIO与PinMux配置:UFS相关引脚功能选择、上下拉、驱动强度、代码实现

4.1 原理概述

UFS控制器与UFS设备之间通过高速差分信号和控制信号进行通信。在SoC层面,这些信号必须通过多路复用器(PinMux)从通用I/O(GPIO)配置为专用功能。错误的PinMux配置会导致UFS链路无法训练、初始化失败或传输错误。

GPIO与PinMux配置的核心包括三个层次:

  • 功能选择:将特定引脚从GPIO状态切换为UFS、I2C(用于UFS供电协商)或复位等专用功能。
  • 电气特性:包括上下拉电阻、驱动强度(Drive Strength)、压摆率(Slew Rate)和开漏/推挽输出类型。
  • 电源域:确认引脚电压域(e.g., 1.8V或3.3V)与UFS PHY要求匹配。
调试提示:大多数量产板UFS连接失败,根本原因不是控制器驱动问题,而是SoC外围引脚复用配置有误。建议在Target Config(TARGET_xxx)中优先确认所有UFS相关GPIO的TLMM(Top-Level Mode Multiplex)寄存器初始值。

4.2 UFS引脚信号清单

UFS硬件接口涉及以下关键引脚,每个引脚都需要在XBL早期(Timer/GPIO初始化阶段)完成复用配置:

信号名 方向 功能说明 典型电气要求
UFS_REF_CLK 输出 UFS参考时钟(19.2MHz / 26MHz) 1.8V,驱动强度>4mA
UFS_RST_N 输出 UFS设备硬件复位,低电平有效 1.8V,内置上拉
UFS0/1_DP/DN 双向 MIPI M-PHY差分数据线 H/S模式,AC耦合
UFS_EN (或REGUFS_EN) 输出 UFS供电使能控制 1.8V/3.3V,推挽输出
I2C_SCL/SDA 双向 用于UFS VCCQ/VCC电压协商 1.8V,开漏+上拉

4.3 PinMux配置实现流程

  1. 查表确定对应GPIO号:根据芯片数据手册或TLMM映射表,找到UFS功能对应的GPIO BANK和引脚偏移。
  2. 配置功能选择寄存器:写入TLMM_PER_EN或GPIOx_CFG[FUNC_SEL]字段,将引脚切换为UFS模式。
  3. 配置上下拉:设置PULL_UP_EN/PULL_DOWN_EN位;UFS控制信号(RST_N)通常启用内部弱上拉,差分对通常不启用内部上下拉。
  4. 配置驱动强度:写入DRV_STR字段(2/4/6/8/12/16mA等档位);参考时钟和复位信号建议使用中等驱动强度(6~8mA)。
  5. 确认输出类型:I2C必须设为开漏(Open-Drain),其余信号设为推挽。
  6. 系统锁定:部分SoC写入TLMM后需置位LOCK寄存器防止Bootloader后期被意外篡改。
常见错误:UFS差分对DP/DN的AC耦合电容在SoC侧靠近PHY放置,不要在GPIO配置中为该对引脚启用内部上下拉,否则会破坏M-PHY端接阻抗(~50Ω),导致链路训练失败。

4.4 代码实现(Qualcomm平台示例)

以下代码片段展示在XBL平台代码中配置UFS相关GPIO的典型做法。以Qualcomm QCM6490为例,TLMM基地址通过芯片系统模块映射。

头文件定义:

// tlmm_ufs_cfg.h
#ifndef TLMM_UFS_CFG_H
#define TLMM_UFS_CFG_H

#define TLMM_BASE               0x0100F000
#define GPIO_UFS_REF_CLK        (GPIO_BASE + 0x14 * 4)   // 假设GPIO 20
#define GPIO_UFS_RST_N          (GPIO_BASE + 0x16 * 4)   // GPIO 22
#define GPIO_UFS_EN             (GPIO_BASE + 0x18 * 4)   // GPIO 24

// CFG寄存器偏移(TLMMv2风格)
#define CFG_OFFSET              0x00
#define INOUT_OFFSET            0x04

#define FUNC_SEL_UFS            0x02      // 功能代码:UFS模式
#define DRV_STR_8MA             0x03      // 8mA档位
#define PULL_UP_EN              0x01      // 使能内部上拉

#endif

实际配置代码:

// tlmm_ufs_init.c
#include "tlmm_ufs_cfg.h"
#include "hwio.h"      // 提供 writel/readl 寄存器访问

void tlmm_configure_ufs_pins(void)
{
    uint32_t reg_val;

    // 1. 配置UFS参考时钟引脚(功能选择+驱动强度,无上拉)
    reg_val = readl(GPIO_UFS_REF_CLK + CFG_OFFSET);
    reg_val &= ~0x7F;                     // 清除低7位(功能+驱动+上拉)
    reg_val |= (FUNC_SEL_UFS << 0);       // FUNC_SEL位于bit[2:0]
    reg_val |= (DRV_STR_8MA << 4);        // 驱动强度位于bit[6:4]
    reg_val &= ~(1 << 3);                // 不启用上拉 (bit3 = 0)
    writel(reg_val, GPIO_UFS_REF_CLK + CFG_OFFSET);

    // 2. 配置UFS复位引脚(功能选择+内部上拉+中等驱动)
    reg_val = readl(GPIO_UFS_RST_N + CFG_OFFSET);
    reg_val &= ~0x7F;
    reg_val |= (FUNC_SEL_UFS << 0);
    reg_val |= (DRV_STR_8MA << 4);
    reg_val |= (PULL_UP_EN << 3);          // 启用内部上拉
    writel(reg_val, GPIO_UFS_RST_N + CFG_OFFSET);

    // 3. 配置UFS供电使能(功能选择+推挽输出,初始低电平)
    reg_val = readl(GPIO_UFS_EN + CFG_OFFSET);
    reg_val &= ~0x7F;
    reg_val |= (FUNC_SEL_UFS << 0);
    reg_val |= (DRV_STR_8MA << 4);
    reg_val &= ~(1 << 3);                 // 不上拉
    writel(reg_val, GPIO_UFS_EN + CFG_OFFSET);

    // 设定输出为低电平(禁止供电)
    writel(0x00, GPIO_UFS_EN + INOUT_OFFSET);

    // 4. 锁定TLMM(防止后续误修改)
    writel(0x1, TLMM_BASE + 0x1000);       // TLMM LOCK寄存器
}
实现要点:
  • 务必在XBL UFS核心时钟初始化 之前 调用 tlmm_configure_ufs_pins()。
  • I2C引脚应单独处理为开漏(OD)模式:写GPIOx_CFG寄存器中的OD_EN位(bit 9)。
  • 驱动强度不要超过PHY芯片规格,一般参考时钟和复位不超过8mA,普通GPIO不超过4mA。

4.5 调试与验证

完成配置后,可通过寄存器回读和逻辑分析仪验证引脚状态:

  • 回读TLMM寄存器:通过JTAG或XBL的early serial dump,确认目标GPIO的FUNC_SEL字段是否为UFS代码。
  • 测量引脚电平:UFS_RST_N应在XBL阶段被拉高(内部上拉),UFS_EN应保持低电平直到UFS供电就绪。
  • Sysfs接口(Linux侧辅助验证):在后续操作系统启动后,通过/sys/kernel/debug/gpio或pinctrl工具查看是否已正确占用。
调试命令速查:
通过XBL串口打印TLMM寄存器值:APR> register_read 0x0100F054(举例地址,替换为实际GPIO偏移)。
观察UFS_RST_N电平:若为低电平持续>1秒,检查内部上拉是否使能或外部上拉电阻是否焊接。

4.6 性能与稳定性优化

  • 分组配置:将UFS相关引脚配置集中在同一个.c文件中,避免散落在不同的平台初始化模块中,方便审计。
  • 寄存器缓存:在频繁访问的TLMM配置场景中,使用局部缓存变量而非重复readl/writel,减少对低速APB总线的访问延迟。
  • 静电防护:UFS参考时钟引脚在PCB设计时应串联22Ω电阻衰减振铃;驱动强度不宜超过10mA,否则引入EMI干扰。
  • 避免浮动:长期未使用但未屏蔽的UFS功能引脚应配置为GPIO输入+下拉,防止漏电和电平跳变。
平台差异提示:不同SoC的TLMM寄存器布局不同(例如QTI TLMMv1 vs TLMMv2),访问偏移和字段位宽差异大。务必以当前芯片的TRM/PinMux Excel表格为准,不可直接套用其他平台的偏移值。

 

UFS GPIO配置流程与信号关系 SoC PinMux 模块 TLMM 配置寄存器 GPIO 控制器 UFS M-PHY UFS 设备 功能/电气参数写入 MIPI M-PHY 差分对 配置关键顺序: 1. 确认GPIO号 → 2. 写FUNC_SEL字段 → 3. 配置上下拉与驱动强度 → 4. 锁存寄存器 UFS_RST_N必须在XBL阶段拉高,UFS_EN在电压协商前保持低电平