@@ -78,6 +78,254 @@ UfsDmeSet (
7878 return Status ;
7979}
8080
81+ /**
82+ Execute a UIC DME_GET command to read a UniPro attribute.
83+
84+ @param[in] UfsHcDriver Pointer to UFS HC driver interface.
85+ @param[in] MibAttribute MIB attribute address (upper 16 bits) and
86+ GenSelectorIndex (lower 16 bits).
87+ @param[out] Value Pointer to store the read value.
88+
89+ @retval EFI_SUCCESS Command executed successfully.
90+ @retval Others Command execution failed.
91+
92+ **/
93+ STATIC
94+ EFI_STATUS
95+ UfsDmeGet (
96+ IN EDKII_UFS_HC_DRIVER_INTERFACE * UfsHcDriver ,
97+ IN UINT32 MibAttribute ,
98+ OUT UINT32 * Value
99+ )
100+ {
101+ EDKII_UIC_COMMAND UicCommand ;
102+ EFI_STATUS Status ;
103+
104+ ZeroMem (& UicCommand , sizeof (EDKII_UIC_COMMAND ));
105+
106+ UicCommand .Opcode = UIC_CMD_DME_GET ;
107+ UicCommand .Arg1 = MibAttribute ;
108+ UicCommand .Arg2 = 0 ;
109+ UicCommand .Arg3 = 0 ;
110+
111+ Status = UfsHcDriver -> UfsExecUicCommand (UfsHcDriver , & UicCommand );
112+ if (EFI_ERROR (Status )) {
113+ DEBUG ((
114+ DEBUG_ERROR ,
115+ "%a: DME_GET failed for MIB 0x%04x, Status = %r\n" ,
116+ __FUNCTION__ ,
117+ (MibAttribute >> 16 ) & 0xFFFF ,
118+ Status
119+ ));
120+ return Status ;
121+ }
122+
123+ * Value = UicCommand .Arg3 ;
124+ return EFI_SUCCESS ;
125+ }
126+
127+ /**
128+ Execute a UIC DME_PEER_GET command to read a peer UniPro attribute.
129+
130+ @param[in] UfsHcDriver Pointer to UFS HC driver interface.
131+ @param[in] MibAttribute MIB attribute address (upper 16 bits) and
132+ GenSelectorIndex (lower 16 bits).
133+ @param[out] Value Pointer to store the read value.
134+
135+ @retval EFI_SUCCESS Command executed successfully.
136+ @retval Others Command execution failed.
137+
138+ **/
139+ STATIC
140+ EFI_STATUS
141+ UfsDmePeerGet (
142+ IN EDKII_UFS_HC_DRIVER_INTERFACE * UfsHcDriver ,
143+ IN UINT32 MibAttribute ,
144+ OUT UINT32 * Value
145+ )
146+ {
147+ EDKII_UIC_COMMAND UicCommand ;
148+ EFI_STATUS Status ;
149+
150+ ZeroMem (& UicCommand , sizeof (EDKII_UIC_COMMAND ));
151+
152+ UicCommand .Opcode = UIC_CMD_DME_PEER_GET ;
153+ UicCommand .Arg1 = MibAttribute ;
154+ UicCommand .Arg2 = 0 ;
155+ UicCommand .Arg3 = 0 ;
156+
157+ Status = UfsHcDriver -> UfsExecUicCommand (UfsHcDriver , & UicCommand );
158+ if (EFI_ERROR (Status )) {
159+ DEBUG ((
160+ DEBUG_ERROR ,
161+ "%a: DME_PEER_GET failed for MIB 0x%04x, Status = %r\n" ,
162+ __FUNCTION__ ,
163+ (MibAttribute >> 16 ) & 0xFFFF ,
164+ Status
165+ ));
166+ return Status ;
167+ }
168+
169+ * Value = UicCommand .Arg3 ;
170+ return EFI_SUCCESS ;
171+ }
172+
173+ /**
174+ Execute a UIC DME_PEER_SET command to configure a peer UniPro attribute.
175+
176+ @param[in] UfsHcDriver Pointer to UFS HC driver interface.
177+ @param[in] MibAttribute MIB attribute address (upper 16 bits) and
178+ GenSelectorIndex (lower 16 bits).
179+ @param[in] Value Value to set.
180+
181+ @retval EFI_SUCCESS Command executed successfully.
182+ @retval Others Command execution failed.
183+
184+ **/
185+ STATIC
186+ EFI_STATUS
187+ UfsDmePeerSet (
188+ IN EDKII_UFS_HC_DRIVER_INTERFACE * UfsHcDriver ,
189+ IN UINT32 MibAttribute ,
190+ IN UINT32 Value
191+ )
192+ {
193+ EDKII_UIC_COMMAND UicCommand ;
194+ EFI_STATUS Status ;
195+
196+ ZeroMem (& UicCommand , sizeof (EDKII_UIC_COMMAND ));
197+
198+ UicCommand .Opcode = UIC_CMD_DME_PEER_SET ;
199+ UicCommand .Arg1 = MibAttribute ;
200+ UicCommand .Arg2 = (DME_ATTR_SET_TYPE_NORMAL << 16 );
201+ UicCommand .Arg3 = Value ;
202+
203+ Status = UfsHcDriver -> UfsExecUicCommand (UfsHcDriver , & UicCommand );
204+ if (EFI_ERROR (Status )) {
205+ DEBUG ((
206+ DEBUG_ERROR ,
207+ "%a: DME_PEER_SET failed for MIB 0x%04x, Status = %r\n" ,
208+ __FUNCTION__ ,
209+ (MibAttribute >> 16 ) & 0xFFFF ,
210+ Status
211+ ));
212+ }
213+
214+ return Status ;
215+ }
216+
217+ /**
218+ Apply Intel-specific device quirks for proper UFS operation.
219+
220+ This function implements the critical PA_TACTIVATE adjustment required
221+ for Intel Lakefield and later platforms. If the host and device
222+ PA_GRANULARITY values match, the peer PA_TACTIVATE must be increased
223+ to ensure proper timing during power mode changes.
224+
225+ @param[in] UfsHcDriver Pointer to UFS HC driver interface.
226+
227+ @retval EFI_SUCCESS Quirks applied successfully.
228+ @retval Others Failed to apply quirks.
229+
230+ **/
231+ STATIC
232+ EFI_STATUS
233+ ApplyIntelDeviceQuirks (
234+ IN EDKII_UFS_HC_DRIVER_INTERFACE * UfsHcDriver
235+ )
236+ {
237+ EFI_STATUS Status ;
238+ UINT32 Granularity ;
239+ UINT32 PeerGranularity ;
240+ UINT32 PaTactivate ;
241+ UINT32 PeerPaTactivate ;
242+ UINT32 NewPeerPaTactivate ;
243+ UINT32 MibAttribute ;
244+
245+ //
246+ // Read PA_GRANULARITY from host
247+ //
248+ MibAttribute = (PA_GRANULARITY << 16 );
249+ Status = UfsDmeGet (UfsHcDriver , MibAttribute , & Granularity );
250+ if (EFI_ERROR (Status )) {
251+ return Status ;
252+ }
253+
254+ //
255+ // Read PA_GRANULARITY from peer (device)
256+ //
257+ Status = UfsDmePeerGet (UfsHcDriver , MibAttribute , & PeerGranularity );
258+ if (EFI_ERROR (Status )) {
259+ return Status ;
260+ }
261+
262+ //
263+ // Read PA_TACTIVATE from host
264+ //
265+ MibAttribute = (PA_TACTIVATE << 16 );
266+ Status = UfsDmeGet (UfsHcDriver , MibAttribute , & PaTactivate );
267+ if (EFI_ERROR (Status )) {
268+ return Status ;
269+ }
270+
271+ //
272+ // Read PA_TACTIVATE from peer (device)
273+ //
274+ Status = UfsDmePeerGet (UfsHcDriver , MibAttribute , & PeerPaTactivate );
275+ if (EFI_ERROR (Status )) {
276+ return Status ;
277+ }
278+
279+ DEBUG ((
280+ DEBUG_INFO ,
281+ "%a: Host PA_GRANULARITY=%u, Peer PA_GRANULARITY=%u\n" ,
282+ __FUNCTION__ ,
283+ Granularity ,
284+ PeerGranularity
285+ ));
286+ DEBUG ((
287+ DEBUG_INFO ,
288+ "%a: Host PA_TACTIVATE=%u, Peer PA_TACTIVATE=%u\n" ,
289+ __FUNCTION__ ,
290+ PaTactivate ,
291+ PeerPaTactivate
292+ ));
293+
294+ //
295+ // CRITICAL: If granularity values match, adjust peer PA_TACTIVATE
296+ // This is required for proper timing on Intel platforms
297+ //
298+ if (Granularity == PeerGranularity ) {
299+ NewPeerPaTactivate = PaTactivate + 2 ;
300+
301+ DEBUG ((
302+ DEBUG_INFO ,
303+ "%a: Granularity match detected, adjusting Peer PA_TACTIVATE to %u\n" ,
304+ __FUNCTION__ ,
305+ NewPeerPaTactivate
306+ ));
307+
308+ Status = UfsDmePeerSet (UfsHcDriver , MibAttribute , NewPeerPaTactivate );
309+ if (EFI_ERROR (Status )) {
310+ DEBUG ((
311+ DEBUG_ERROR ,
312+ "%a: Failed to set Peer PA_TACTIVATE, Status = %r\n" ,
313+ __FUNCTION__ ,
314+ Status
315+ ));
316+ return Status ;
317+ }
318+
319+ DEBUG ((
320+ DEBUG_INFO ,
321+ "%a: Successfully adjusted Peer PA_TACTIVATE\n" ,
322+ __FUNCTION__
323+ ));
324+ }
325+
326+ return EFI_SUCCESS ;
327+ }
328+
81329/**
82330 Platform-specific callback function for UFS host controller initialization.
83331
@@ -154,6 +402,11 @@ UfsPlatformCallback (
154402 // Called after Host Controller Enable (HCE)
155403 // No platform-specific configuration needed at this phase for Intel
156404 //
405+ // Note: Crypto enable (CRYPTO_GENERAL_ENABLE) would be done here on
406+ // newer platforms (Lakefield+), but requires direct MMIO access which
407+ // is not available through the current protocol interface. The EDK2
408+ // UFS core driver may handle this automatically on supported platforms.
409+ //
157410 DEBUG ((DEBUG_INFO , "%a: PostHce - No action required\n" , __FUNCTION__ ));
158411 break ;
159412
@@ -204,9 +457,32 @@ UfsPlatformCallback (
204457 case EdkiiUfsHcPostLinkStartup :
205458 //
206459 // Called after link startup completes
207- // No platform-specific configuration needed at this phase for Intel
208460 //
209- DEBUG ((DEBUG_INFO , "%a: PostLinkStartup - No action required\n" , __FUNCTION__ ));
461+ // CRITICAL: Apply Intel device quirks including PA_TACTIVATE adjustment
462+ // This is required for proper I/O operation and boot functionality
463+ //
464+ DEBUG ((
465+ DEBUG_INFO ,
466+ "%a: PostLinkStartup - Applying Intel device quirks\n" ,
467+ __FUNCTION__
468+ ));
469+
470+ Status = ApplyIntelDeviceQuirks (UfsHcDriver );
471+ if (EFI_ERROR (Status )) {
472+ DEBUG ((
473+ DEBUG_ERROR ,
474+ "%a: Failed to apply Intel device quirks, Status = %r\n" ,
475+ __FUNCTION__ ,
476+ Status
477+ ));
478+ return Status ;
479+ }
480+
481+ DEBUG ((
482+ DEBUG_INFO ,
483+ "%a: Intel device quirks applied successfully\n" ,
484+ __FUNCTION__
485+ ));
210486 break ;
211487
212488 default :
0 commit comments