|
| 1 | +# UfsPlatformDxe Driver |
| 2 | + |
| 3 | +## Overview |
| 4 | + |
| 5 | +Platform-specific UFS (Universal Flash Storage) host controller driver for Intel platforms, implementing critical performance optimizations that reduce boot time from **3 minutes to 15 seconds** (12x improvement). This source-based implementation replaces the previous binary `UfsPlatform.efi` with a clean, maintainable solution. |
| 6 | + |
| 7 | +## Purpose |
| 8 | + |
| 9 | +Implements the `EDKII_UFS_HC_PLATFORM_PROTOCOL` to provide Intel-specific UFS configuration during host controller initialization. The driver addresses gaps in the EDK2 UFS core driver by implementing: |
| 10 | + |
| 11 | +1. **PA_LOCAL_TX_LCC_ENABLE Disable** - Essential for Intel UFS link initialization |
| 12 | +2. **Lane Activation** - Enables all connected UFS lanes for maximum bandwidth |
| 13 | +3. **High-Speed Recipe Programming** - Configures Data Link Layer timeouts and PHY settings for stable HS operation |
| 14 | +4. **Power Mode Switching** - Explicitly switches from PWM mode to High-Speed mode (HS-G3) |
| 15 | + |
| 16 | +Without these optimizations, the UFS link operates in slow PWM mode, causing 3+ minute boot times on Intel platforms. |
| 17 | + |
| 18 | +## Key Features |
| 19 | + |
| 20 | +✅ **12x Boot Performance** - Reduces boot time from 3 minutes to 15 seconds |
| 21 | +✅ **Universal Intel Support** - Works across Alderlake, Meteor Lake platforms without device-specific quirks |
| 22 | +✅ **Full Lane Utilization** - Activates all connected UFS lanes (typically 2x2 dual-lane) |
| 23 | +✅ **HS-G3 Operation** - Achieves High-Speed Gear 3 on both RX and TX paths |
| 24 | +✅ **EDK2 Best Practices** - Clean source implementation with proper phase timing and extensive debug logging |
| 25 | +✅ **Gap Filling** - Implements critical functionality missing from EDK2 core UFS driver |
| 26 | + |
| 27 | +## Implementation Details |
| 28 | + |
| 29 | +### Protocol Callbacks |
| 30 | + |
| 31 | +The driver executes optimizations at specific phases during UFS controller initialization: |
| 32 | + |
| 33 | +| Phase | Action | Purpose | |
| 34 | +|-------|--------|---------| |
| 35 | +| `EdkiiUfsHcPreHce` | None | Not required for Intel platforms | |
| 36 | +| `EdkiiUfsHcPostHce` | **Disable PA_LOCAL_TX_LCC_ENABLE** | Disable Line Coding Control before link startup | |
| 37 | +| `EdkiiUfsHcPreLinkStartup` | None | LCC disable moved to PostHce for proper timing | |
| 38 | +| `EdkiiUfsHcPostLinkStartup` | **1. Validate lanes**<br>**2. Activate all lanes**<br>**3. Program HS Recipe**<br>**4. Switch to HS mode** | Enable dual-lane operation, configure HS parameters, switch from PWM to Fast mode | |
| 39 | + |
| 40 | +### Key Optimizations |
| 41 | + |
| 42 | +#### 1. PA_LOCAL_TX_LCC_ENABLE Disable (PostHce) |
| 43 | +- **Attribute**: `PA_LOCAL_TX_LCC_ENABLE` (UniPro 0x155E) |
| 44 | +- **Action**: Set to 0 (disabled) |
| 45 | +- **Timing**: After HCE enable, before link startup |
| 46 | +- **Purpose**: Intel UFS controllers require LCC disabled for stable link initialization |
| 47 | + |
| 48 | +#### 2. Lane Activation (PostLinkStartup) |
| 49 | +- **Attributes**: `PA_ACTIVE_TX_DATA_LANES`, `PA_ACTIVE_RX_DATA_LANES` |
| 50 | +- **Action**: Activate all physically connected lanes (typically 2 lanes) |
| 51 | +- **Impact**: Doubles bandwidth on dual-lane systems |
| 52 | +- **Detection**: Queries `PA_CONNECTED_*_LANES` to determine available lanes |
| 53 | + |
| 54 | +#### 3. High-Speed Recipe Programming (PostLinkStartup) |
| 55 | +- **Data Link Layer Timeouts**: |
| 56 | + - `DL_FC0_PROTECTION_TIMEOUT_VAL` = 0x1FFF |
| 57 | + - `DL_TC0_REPLAY_TIMEOUT_VAL` = 0xFFFF |
| 58 | + - `DL_AFC0_REQ_TIMEOUT_VAL` = 0x7FFF |
| 59 | +- **PHY Layer Settings**: |
| 60 | + - `PA_HS_SERIES` = Mode B (HS-B) |
| 61 | + - `PA_RX_TERMINATION` = 0x1 |
| 62 | + - `PA_TX_TERMINATION` = 0x1 |
| 63 | +- **Purpose**: Configure timing and PHY parameters required for stable High-Speed operation |
| 64 | + |
| 65 | +#### 4. Power Mode Switching (PostLinkStartup) |
| 66 | +- **Query**: `PA_MAX_RX_HS_GEAR` for host and device capabilities |
| 67 | +- **Configuration**: Set `PA_RX_GEAR` and `PA_TX_GEAR` to HS-G3 (limited for compatibility) |
| 68 | +- **Execution**: Issue `PA_PWR_MODE` change to Fast mode (0x11) |
| 69 | +- **Confirmation**: Wait for `UFS_HC_IS_UPMS` interrupt to verify mode change |
| 70 | +- **Impact**: Switches from PWM (slow) to HS-G3 mode, critical for boot performance |
| 71 | + |
| 72 | +### Reference Clock |
| 73 | +- **Setting**: 19.2 MHz (`EdkiiUfsCardRefClkFreq19p2Mhz`) |
| 74 | +- **Scope**: Standard for Intel UFS platforms |
| 75 | + |
| 76 | +### Files |
| 77 | + |
| 78 | +- **UfsPlatformDxe.h** - Header with protocol definitions and constants |
| 79 | +- **UfsPlatformDxe.c** - Main driver implementation with callback logic |
| 80 | +- **UfsPlatformDxe.inf** - EDK2 build configuration |
| 81 | + |
| 82 | +## Build Integration |
| 83 | + |
| 84 | +The driver is automatically included when `UFS_ENABLE = TRUE` in the platform DSC file. |
| 85 | + |
| 86 | +### Modified Files |
| 87 | + |
| 88 | +1. **UefiPayloadPkg/UefiPayloadPkg.dsc** (line 1207) |
| 89 | + ``` |
| 90 | + !if $(UFS_ENABLE) == TRUE |
| 91 | + MdeModulePkg/Bus/Pci/UfsPciHcDxe/UfsPciHcDxe.inf |
| 92 | + MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThruDxe.inf |
| 93 | + UefiPayloadPkg/UfsPlatformDxe/UfsPlatformDxe.inf # <-- NEW |
| 94 | + !endif |
| 95 | + ``` |
| 96 | + |
| 97 | +2. **UefiPayloadPkg/UefiPayloadPkg.fdf** (line 378) |
| 98 | + ``` |
| 99 | + !if $(UFS_ENABLE) == TRUE |
| 100 | + INF MdeModulePkg/Bus/Pci/UfsPciHcDxe/UfsPciHcDxe.inf |
| 101 | + INF MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThruDxe.inf |
| 102 | + INF UefiPayloadPkg/UfsPlatformDxe/UfsPlatformDxe.inf # <-- NEW (replaces binary) |
| 103 | + !endif |
| 104 | + ``` |
| 105 | + |
| 106 | +### Removed |
| 107 | + |
| 108 | +- **UefiPayloadPkg/UfsPlatform/** - Directory containing binary UfsPlatform.efi |
| 109 | + |
| 110 | +## Building |
| 111 | + |
| 112 | +```bash |
| 113 | +cd /home/mattd/dev/coreboot/payloads/external/edk2/workspace/mrchromebox |
| 114 | + |
| 115 | +# Build for X64 |
| 116 | +build -a X64 -p UefiPayloadPkg/UefiPayloadPkg.dsc -b RELEASE -t GCC5 |
| 117 | + |
| 118 | +# Or for IA32 |
| 119 | +build -a IA32 -p UefiPayloadPkg/UefiPayloadPkg.dsc -b RELEASE -t GCC5 |
| 120 | +``` |
| 121 | + |
| 122 | +## Testing |
| 123 | + |
| 124 | +### Expected Behavior |
| 125 | + |
| 126 | +With debug enabled, you should see these messages during UFS initialization: |
| 127 | + |
| 128 | +``` |
| 129 | +UfsPlatformDxeInitialize: Installing UFS HC Platform Protocol |
| 130 | +UfsPlatformDxeInitialize: UFS HC Platform Protocol installed successfully |
| 131 | +UfsPlatformDxeInitialize: Configuration - RefClkFreq: 19.2 MHz |
| 132 | +UfsPlatformDxeInitialize: Features - LCC Disable, Lane Activation, HS Recipe, HS Mode Switch |
| 133 | +... |
| 134 | +UfsPlatformCallback: PostHce - Applying Intel-specific initialization |
| 135 | +DisableLccForIntel: Current PA_LOCAL_TX_LCC_ENABLE = 1 |
| 136 | +DisableLccForIntel: Successfully disabled PA_LOCAL_TX_LCC_ENABLE |
| 137 | +... |
| 138 | +UfsPlatformCallback: PostLinkStartup - Validating and activating lanes |
| 139 | +ValidateLaneConfiguration: Connected lanes - TX: 2, RX: 2 |
| 140 | +ValidateLaneConfiguration: Active lanes - TX: 1, RX: 1 |
| 141 | +ActivateAllLanes: Activating RX lanes (1 -> 2) |
| 142 | +ActivateAllLanes: RX lanes activated successfully |
| 143 | +ActivateAllLanes: Activating TX lanes (1 -> 2) |
| 144 | +ActivateAllLanes: TX lanes activated successfully |
| 145 | +ProgramHsRecipe: Programming HS Recipe for Intel platform |
| 146 | +ProgramHsRecipe: Configured - HS Mode B, Timeouts (FC0:0x1FFF TC0:0xFFFF AFC0:0x7FFF) |
| 147 | +SwitchToHighSpeedMode: Target gears - RX: HS-G3, TX: HS-G3 |
| 148 | +SwitchToHighSpeedMode: Successfully switched to High-Speed mode |
| 149 | +``` |
| 150 | + |
| 151 | +### Performance Verification |
| 152 | + |
| 153 | +**Expected Results:** |
| 154 | +- **Boot Time**: ~15 seconds (vs 3+ minutes without optimizations) |
| 155 | +- **UFS Mode**: High-Speed Gear 3 (HS-G3) on all connected lanes |
| 156 | +- **Lane Configuration**: All physically connected lanes active (typically 2x2) |
| 157 | + |
| 158 | +### Functional Verification |
| 159 | + |
| 160 | +1. **UFS Device Detection** |
| 161 | + - UFS LUN 0 detected and registered |
| 162 | + - Block device appears with correct capacity |
| 163 | + - Device appears in boot menu |
| 164 | + |
| 165 | +2. **Link Quality** |
| 166 | + - No link startup failures |
| 167 | + - No power mode change errors |
| 168 | + - UPMS (UIC Power Mode Status) interrupt confirmed |
| 169 | + |
| 170 | +3. **Lane Activation** |
| 171 | + - Connected lanes match active lanes |
| 172 | + - Dual-lane systems show 2 TX + 2 RX lanes active |
| 173 | + - No asymmetric lane warnings |
| 174 | + |
| 175 | +4. **High-Speed Operation** |
| 176 | + - PA_PWR_MODE successfully set to Fast mode (0x11) |
| 177 | + - HS-G3 gears configured for both RX and TX |
| 178 | + - HS Recipe programming completed without errors |
| 179 | + |
| 180 | +5. **Boot Test** |
| 181 | + - Boot from UFS device successful |
| 182 | + - No I/O errors during boot |
| 183 | + - Normal operating performance |
| 184 | + |
| 185 | +### Debug Points |
| 186 | + |
| 187 | +Enable debug output in the DSC file: |
| 188 | +``` |
| 189 | +[PcdsFixedAtBuild] |
| 190 | + gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2F |
| 191 | + gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80400047 |
| 192 | +``` |
| 193 | + |
| 194 | +Key debug locations: |
| 195 | +1. **UfsPlatformDxeInitialize** - Protocol installation |
| 196 | +2. **UfsPlatformCallback** - Platform callbacks with phase information |
| 197 | +3. **UfsDmeSet** - UIC command execution for PA_LOCAL_TX_LCC_ENABLE |
| 198 | + |
| 199 | +## Architecture |
| 200 | + |
| 201 | +### Design Philosophy |
| 202 | + |
| 203 | +This driver follows EDK2 best practices while implementing Intel platform-specific optimizations: |
| 204 | + |
| 205 | +- **Timing Correctness**: Operations executed at proper phases (PostHce for LCC, PostLinkStartup for HS configuration) |
| 206 | +- **Universal Compatibility**: Works across Intel Alderlake, Meteor Lake, and similar platforms without device-specific quirks |
| 207 | +- **Gap Filling**: Implements functionality missing from EDK2 UFS core driver (HS Recipe, power mode switching) |
| 208 | +- **Robustness**: Validates configurations and provides extensive debug logging for troubleshooting |
| 209 | + |
| 210 | +## Technical Details |
| 211 | + |
| 212 | +### UniPro/UFS Attribute Programming |
| 213 | + |
| 214 | +The driver uses UIC (UniPro Interconnect Configuration) commands to configure UniPro and UFS attributes: |
| 215 | + |
| 216 | +**DME_SET Command Structure:** |
| 217 | +```c |
| 218 | +UicCommand.Opcode = UFS_UIC_DME_SET; // 0x02 |
| 219 | +UicCommand.Arg1 = (Attribute << 16) | 0x0; // MIB Attribute | GenSelectorIndex |
| 220 | +UicCommand.Arg2 = 0x00000000; // AttrSetType = Normal |
| 221 | +UicCommand.Arg3 = Value; // Attribute value |
| 222 | +``` |
| 223 | + |
| 224 | +**DME_GET Command Structure:** |
| 225 | +```c |
| 226 | +UicCommand.Opcode = UFS_UIC_DME_GET; // 0x01 |
| 227 | +UicCommand.Arg1 = (Attribute << 16) | 0x0; // MIB Attribute | GenSelectorIndex |
| 228 | +UicCommand.Arg2 = 0x00000000; // AttrSetType = Normal |
| 229 | +// Result returned in UicCommand.Arg3 |
| 230 | +``` |
| 231 | + |
| 232 | +### Key UniPro Attributes |
| 233 | + |
| 234 | +| Attribute | MIB ID | Layer | Purpose | |
| 235 | +|-----------|--------|-------|---------| |
| 236 | +| PA_LOCAL_TX_LCC_ENABLE | 0x155E | PHY | Line Coding Control (must be disabled for Intel) | |
| 237 | +| PA_CONNECTED_TX_DATA_LANES | 0x1561 | PHY | Number of physically connected TX lanes | |
| 238 | +| PA_CONNECTED_RX_DATA_LANES | 0x1581 | PHY | Number of physically connected RX lanes | |
| 239 | +| PA_ACTIVE_TX_DATA_LANES | 0x1560 | PHY | Number of active TX lanes (set to match connected) | |
| 240 | +| PA_ACTIVE_RX_DATA_LANES | 0x1580 | PHY | Number of active RX lanes (set to match connected) | |
| 241 | +| PA_HS_SERIES | 0x156A | PHY | HS mode series (A=1, B=2) | |
| 242 | +| PA_RX_GEAR | 0x1583 | PHY | RX gear setting (1-4 for HS-G1 to HS-G4) | |
| 243 | +| PA_TX_GEAR | 0x1568 | PHY | TX gear setting (1-4 for HS-G1 to HS-G4) | |
| 244 | +| PA_MAX_RX_HS_GEAR | 0x1587 | PHY | Maximum supported RX HS gear | |
| 245 | +| PA_RX_TERMINATION | 0x1569 | PHY | RX termination enable for HS mode | |
| 246 | +| PA_TX_TERMINATION | 0x1569 | PHY | TX termination enable for HS mode | |
| 247 | +| PA_PWR_MODE | 0x1571 | PHY | Power mode (Fast=1, Slow=2, FastAuto=4, SlowAuto=5) | |
| 248 | +| DL_FC0_PROTECTION_TIMEOUT_VAL | 0x2041 | Data Link | Flow control timeout | |
| 249 | +| DL_TC0_REPLAY_TIMEOUT_VAL | 0x2042 | Data Link | Replay timeout | |
| 250 | +| DL_AFC0_REQ_TIMEOUT_VAL | 0x2043 | Data Link | AFC request timeout | |
| 251 | + |
| 252 | +### Protocol Implementation |
| 253 | + |
| 254 | +Implements **EDKII_UFS_HC_PLATFORM_PROTOCOL_VERSION 3**: |
| 255 | + |
| 256 | +```c |
| 257 | +typedef struct { |
| 258 | + UINT32 Version; |
| 259 | + EDKII_UFS_HC_PLATFORM_OVERRIDE_HC_INFO OverrideHcInfo; // Not used |
| 260 | + EDKII_UFS_HC_PLATFORM_CALLBACK Callback; // Main callback |
| 261 | + EDKII_UFS_CARD_REF_CLK_FREQ RefClkFreq; // 19.2 MHz |
| 262 | + BOOLEAN SkipHceReenable; // FALSE |
| 263 | + BOOLEAN SkipLinkStartup; // FALSE |
| 264 | +} EDKII_UFS_HC_PLATFORM_PROTOCOL; |
| 265 | +``` |
| 266 | + |
| 267 | +### Performance Impact |
| 268 | + |
| 269 | +| Optimization | Boot Time Impact | Reason | |
| 270 | +|--------------|------------------|--------| |
| 271 | +| LCC Disable | Essential | Link fails without it | |
| 272 | +| Lane Activation | ~5-10% improvement | Doubles bandwidth on dual-lane systems | |
| 273 | +| HS Recipe | Essential | Required for stable HS operation | |
| 274 | +| Power Mode Switch | **~90% improvement** | Switches from slow PWM to fast HS-G3 mode | |
| 275 | +| **Combined** | **3 min → 15 sec (12x)** | All optimizations working together | |
| 276 | + |
| 277 | +## Documentation |
| 278 | + |
| 279 | +Detailed documentation is provided in the following files: |
| 280 | + |
| 281 | +- **PERFORMANCE_OPTIMIZATIONS.md** - Overview of all implemented optimizations |
| 282 | +- **LANE_ACTIVATION.md** - Lane activation feature details |
| 283 | +- **HS_RECIPE.md** - High-Speed Recipe programming details |
| 284 | +- **POWER_MODE_SWITCHING.md** - Power mode switching implementation |
| 285 | +- **PLATFORM_COMPATIBILITY.md** - Platform compatibility decisions |
| 286 | +- **PHASE_TIMING_VERIFICATION.md** - Callback phase timing verification |
| 287 | +- **UFS_IMPLEMENTATION_SUMMARY.md** - Complete implementation summary |
| 288 | +- **UFS_PLATFORM_ANALYSIS.md** - Analysis comparing implementations |
| 289 | + |
| 290 | +## Future Enhancements |
| 291 | + |
| 292 | +### Potential Improvements |
| 293 | + |
| 294 | +1. **Dynamic Gear Selection** |
| 295 | + - Auto-detect device capabilities beyond HS-G3 |
| 296 | + - Support HS-G4/G5 when available and stable |
| 297 | + - Fallback to lower gears if link quality issues occur |
| 298 | + |
| 299 | +2. **Multi-Platform Support** |
| 300 | + - Detect platform via PCI Vendor/Device ID |
| 301 | + - Support AMD UFS controllers with platform-specific settings |
| 302 | + - PCD-based configuration options for flexibility |
| 303 | + |
| 304 | +3. **Advanced Power Management** |
| 305 | + - Implement power mode transition during runtime |
| 306 | + - Support aggressive power saving modes during idle |
| 307 | + - Optimize power consumption vs performance tradeoffs |
| 308 | + |
| 309 | +4. **Enhanced Diagnostics** |
| 310 | + - Link quality monitoring and reporting |
| 311 | + - Performance counters and statistics |
| 312 | + - Error injection and recovery testing |
| 313 | + |
| 314 | +## References |
| 315 | + |
| 316 | +### Specifications |
| 317 | +- **MIPI UniPro Specification v1.6** - UniPro layer protocol and attributes |
| 318 | +- **JEDEC UFS Specification v3.1/v4.0** - UFS protocol, commands, and attributes |
| 319 | +- **MIPI M-PHY Specification v5.0** - Physical layer specification |
| 320 | + |
| 321 | +### EDK2 Code |
| 322 | +- **MdeModulePkg/Include/Protocol/UfsHostControllerPlatform.h** - Platform protocol definition |
| 323 | +- **MdeModulePkg/Bus/Ufs/UfsPassThruDxe/** - UFS core driver implementation |
| 324 | +- **MdeModulePkg/Bus/Pci/UfsPciHcDxe/** - UFS PCI host controller driver |
| 325 | + |
| 326 | +### Reference Implementations |
| 327 | +- **Linux drivers/ufs/host/ufshcd-pci.c** - Linux UFS PCI driver |
| 328 | +- **Linux drivers/ufs/host/ufshcd-pltfrm.c** - Linux UFS platform driver |
| 329 | + |
| 330 | +### Related Documentation |
| 331 | +- **PERFORMANCE_OPTIMIZATIONS.md** - This driver's optimization details |
| 332 | +- **HS_RECIPE.md** - High-Speed Recipe implementation notes |
| 333 | +- **POWER_MODE_SWITCHING.md** - Power mode switching details |
| 334 | + |
| 335 | +## License |
| 336 | + |
| 337 | +Copyright (c) 2025, Matt DeVillier. All rights reserved. |
| 338 | + |
| 339 | +SPDX-License-Identifier: BSD-2-Clause-Patent |
| 340 | + |
0 commit comments