]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdDevice.c
MdeModulePkg/SdMmcPciHcDxe: Add V3 64b DMA Support
[mirror_edk2.git] / MdeModulePkg / Bus / Pci / SdMmcPciHcDxe / SdDevice.c
CommitLineData
48555339
FT
1/** @file\r
2 This file provides some helper functions which are specific for SD card device.\r
3\r
b5547b9c 4 Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.\r
ac30e4c1 5 Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>\r
48555339
FT
6 This program and the accompanying materials\r
7 are licensed and made available under the terms and conditions of the BSD License\r
8 which accompanies this distribution. The full text of the license may be found at\r
9 http://opensource.org/licenses/bsd-license.php\r
10\r
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
14**/\r
15\r
16#include "SdMmcPciHcDxe.h"\r
17\r
18/**\r
19 Send command GO_IDLE_STATE to the device to make it go to Idle State.\r
20\r
21 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.\r
22\r
23 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.\r
24 @param[in] Slot The slot number of the SD card to send the command to.\r
25\r
26 @retval EFI_SUCCESS The SD device is reset correctly.\r
27 @retval Others The device reset fails.\r
28\r
29**/\r
30EFI_STATUS\r
31SdCardReset (\r
32 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,\r
33 IN UINT8 Slot\r
34 )\r
35{\r
36 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk;\r
37 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk;\r
38 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet;\r
39 EFI_STATUS Status;\r
40\r
41 ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));\r
42 ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));\r
43 ZeroMem (&Packet, sizeof (Packet));\r
44\r
45 Packet.SdMmcCmdBlk = &SdMmcCmdBlk;\r
46 Packet.SdMmcStatusBlk = &SdMmcStatusBlk;\r
47 Packet.Timeout = SD_MMC_HC_GENERIC_TIMEOUT;\r
48\r
49 SdMmcCmdBlk.CommandIndex = SD_GO_IDLE_STATE;\r
50 SdMmcCmdBlk.CommandType = SdMmcCommandTypeBc;\r
51\r
52 Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);\r
53\r
54 return Status;\r
55}\r
56\r
57/**\r
58 Send command SEND_IF_COND to the device to inquiry the SD Memory Card interface\r
59 condition.\r
60\r
61 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.\r
62\r
63 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.\r
64 @param[in] Slot The slot number of the SD card to send the command to.\r
65 @param[in] SupplyVoltage The supplied voltage by the host.\r
66 @param[in] CheckPattern The check pattern to be sent to the device.\r
67\r
68 @retval EFI_SUCCESS The operation is done correctly.\r
69 @retval Others The operation fails.\r
70\r
71**/\r
72EFI_STATUS\r
73SdCardVoltageCheck (\r
74 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,\r
75 IN UINT8 Slot,\r
76 IN UINT8 SupplyVoltage,\r
77 IN UINT8 CheckPattern\r
78 )\r
79{\r
80 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk;\r
81 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk;\r
82 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet;\r
83 EFI_STATUS Status;\r
84\r
85 ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));\r
86 ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));\r
87 ZeroMem (&Packet, sizeof (Packet));\r
88\r
89 Packet.SdMmcCmdBlk = &SdMmcCmdBlk;\r
90 Packet.SdMmcStatusBlk = &SdMmcStatusBlk;\r
91 Packet.Timeout = SD_MMC_HC_GENERIC_TIMEOUT;\r
92\r
93 SdMmcCmdBlk.CommandIndex = SD_SEND_IF_COND;\r
94 SdMmcCmdBlk.CommandType = SdMmcCommandTypeBcr;\r
95 SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR7;\r
96 SdMmcCmdBlk.CommandArgument = (SupplyVoltage << 8) | CheckPattern;\r
97\r
98 Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);\r
99\r
100 if (!EFI_ERROR (Status)) {\r
101 if (SdMmcStatusBlk.Resp0 != SdMmcCmdBlk.CommandArgument) {\r
102 return EFI_DEVICE_ERROR;\r
103 }\r
104 }\r
105\r
106 return Status;\r
107}\r
108\r
109/**\r
110 Send command SDIO_SEND_OP_COND to the device to see whether it is SDIO device.\r
111\r
112 Refer to SDIO Simplified Spec 3 Section 3.2 for details.\r
113\r
114 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.\r
115 @param[in] Slot The slot number of the SD card to send the command to.\r
116 @param[in] VoltageWindow The supply voltage window.\r
117 @param[in] S18R The boolean to show if it should switch to 1.8v.\r
118\r
119 @retval EFI_SUCCESS The operation is done correctly.\r
120 @retval Others The operation fails.\r
121\r
122**/\r
123EFI_STATUS\r
124SdioSendOpCond (\r
125 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,\r
126 IN UINT8 Slot,\r
127 IN UINT32 VoltageWindow,\r
128 IN BOOLEAN S18R\r
129 )\r
130{\r
131 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk;\r
132 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk;\r
133 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet;\r
134 EFI_STATUS Status;\r
135 UINT32 Switch;\r
136\r
137 ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));\r
138 ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));\r
139 ZeroMem (&Packet, sizeof (Packet));\r
140\r
141 Packet.SdMmcCmdBlk = &SdMmcCmdBlk;\r
142 Packet.SdMmcStatusBlk = &SdMmcStatusBlk;\r
143 Packet.Timeout = SD_MMC_HC_GENERIC_TIMEOUT;\r
144\r
145 SdMmcCmdBlk.CommandIndex = SDIO_SEND_OP_COND;\r
146 SdMmcCmdBlk.CommandType = SdMmcCommandTypeBcr;\r
147 SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR4;\r
148\r
149 Switch = S18R ? BIT24 : 0;\r
150\r
151 SdMmcCmdBlk.CommandArgument = (VoltageWindow & 0xFFFFFF) | Switch;\r
152\r
153 Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);\r
154\r
155 return Status;\r
156}\r
157\r
158/**\r
159 Send command SD_SEND_OP_COND to the device to see whether it is SDIO device.\r
160\r
161 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.\r
162\r
163 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.\r
164 @param[in] Slot The slot number of the SD card to send the command to.\r
165 @param[in] Rca The relative device address of addressed device.\r
166 @param[in] VoltageWindow The supply voltage window.\r
167 @param[in] S18R The boolean to show if it should switch to 1.8v.\r
168 @param[in] Xpc The boolean to show if it should provide 0.36w power control.\r
169 @param[in] Hcs The boolean to show if it support host capacity info.\r
170 @param[out] Ocr The buffer to store returned OCR register value.\r
171\r
172 @retval EFI_SUCCESS The operation is done correctly.\r
173 @retval Others The operation fails.\r
174\r
175**/\r
176EFI_STATUS\r
177SdCardSendOpCond (\r
178 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,\r
179 IN UINT8 Slot,\r
180 IN UINT16 Rca,\r
181 IN UINT32 VoltageWindow,\r
182 IN BOOLEAN S18R,\r
183 IN BOOLEAN Xpc,\r
184 IN BOOLEAN Hcs,\r
185 OUT UINT32 *Ocr\r
186 )\r
187{\r
188 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk;\r
189 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk;\r
190 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet;\r
191 EFI_STATUS Status;\r
192 UINT32 Switch;\r
193 UINT32 MaxPower;\r
194 UINT32 HostCapacity;\r
195\r
196 ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));\r
197 ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));\r
198 ZeroMem (&Packet, sizeof (Packet));\r
199\r
200 Packet.SdMmcCmdBlk = &SdMmcCmdBlk;\r
201 Packet.SdMmcStatusBlk = &SdMmcStatusBlk;\r
202 Packet.Timeout = SD_MMC_HC_GENERIC_TIMEOUT;\r
203\r
204 SdMmcCmdBlk.CommandIndex = SD_APP_CMD;\r
205 SdMmcCmdBlk.CommandType = SdMmcCommandTypeAc;\r
206 SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1;\r
207 SdMmcCmdBlk.CommandArgument = (UINT32)Rca << 16;\r
208\r
209 Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);\r
210 if (EFI_ERROR (Status)) {\r
211 return Status;\r
212 }\r
213\r
214 SdMmcCmdBlk.CommandIndex = SD_SEND_OP_COND;\r
215 SdMmcCmdBlk.CommandType = SdMmcCommandTypeBcr;\r
216 SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR3;\r
217\r
218 Switch = S18R ? BIT24 : 0;\r
219 MaxPower = Xpc ? BIT28 : 0;\r
220 HostCapacity = Hcs ? BIT30 : 0;\r
221\r
222 SdMmcCmdBlk.CommandArgument = (VoltageWindow & 0xFFFFFF) | Switch | MaxPower | HostCapacity;\r
223\r
224 Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);\r
225 if (!EFI_ERROR (Status)) {\r
226 //\r
227 // For details, refer to SD Host Controller Simplified Spec 3.0 Table 2-12.\r
228 //\r
229 *Ocr = SdMmcStatusBlk.Resp0;\r
230 }\r
231\r
232 return Status;\r
233}\r
234\r
235/**\r
236 Broadcast command ALL_SEND_CID to the bus to ask all the SD devices to send the\r
237 data of their CID registers.\r
238\r
239 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.\r
240\r
241 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.\r
242 @param[in] Slot The slot number of the SD card to send the command to.\r
243\r
244 @retval EFI_SUCCESS The operation is done correctly.\r
245 @retval Others The operation fails.\r
246\r
247**/\r
248EFI_STATUS\r
249SdCardAllSendCid (\r
250 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,\r
251 IN UINT8 Slot\r
252 )\r
253{\r
254 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk;\r
255 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk;\r
256 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet;\r
257 EFI_STATUS Status;\r
258\r
259 ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));\r
260 ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));\r
261 ZeroMem (&Packet, sizeof (Packet));\r
262\r
263 Packet.SdMmcCmdBlk = &SdMmcCmdBlk;\r
264 Packet.SdMmcStatusBlk = &SdMmcStatusBlk;\r
265 Packet.Timeout = SD_MMC_HC_GENERIC_TIMEOUT;\r
266\r
267 SdMmcCmdBlk.CommandIndex = SD_ALL_SEND_CID;\r
268 SdMmcCmdBlk.CommandType = SdMmcCommandTypeBcr;\r
269 SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR2;\r
270\r
271 Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);\r
272\r
273 return Status;\r
274}\r
275\r
276/**\r
277 Send command SET_RELATIVE_ADDR to the SD device to assign a Relative device\r
278 Address (RCA).\r
279\r
280 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.\r
281\r
282 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.\r
283 @param[in] Slot The slot number of the SD card to send the command to.\r
284 @param[out] Rca The relative device address to assign.\r
285\r
286 @retval EFI_SUCCESS The operation is done correctly.\r
287 @retval Others The operation fails.\r
288\r
289**/\r
290EFI_STATUS\r
291SdCardSetRca (\r
292 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,\r
293 IN UINT8 Slot,\r
294 OUT UINT16 *Rca\r
295 )\r
296{\r
297 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk;\r
298 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk;\r
299 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet;\r
300 EFI_STATUS Status;\r
301\r
302 ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));\r
303 ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));\r
304 ZeroMem (&Packet, sizeof (Packet));\r
305\r
306 Packet.SdMmcCmdBlk = &SdMmcCmdBlk;\r
307 Packet.SdMmcStatusBlk = &SdMmcStatusBlk;\r
308 Packet.Timeout = SD_MMC_HC_GENERIC_TIMEOUT;\r
309\r
310 SdMmcCmdBlk.CommandIndex = SD_SET_RELATIVE_ADDR;\r
311 SdMmcCmdBlk.CommandType = SdMmcCommandTypeBcr;\r
312 SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR6;\r
313\r
314 Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);\r
315 if (!EFI_ERROR (Status)) {\r
316 *Rca = (UINT16)(SdMmcStatusBlk.Resp0 >> 16);\r
317 }\r
318\r
319 return Status;\r
320}\r
321\r
48555339 322\r
48555339 323\r
48555339 324\r
48555339
FT
325\r
326/**\r
327 Send command SELECT_DESELECT_CARD to the SD device to select/deselect it.\r
328\r
329 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.\r
330\r
331 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.\r
332 @param[in] Slot The slot number of the SD card to send the command to.\r
333 @param[in] Rca The relative device address of selected device.\r
334\r
335 @retval EFI_SUCCESS The operation is done correctly.\r
336 @retval Others The operation fails.\r
337\r
338**/\r
339EFI_STATUS\r
340SdCardSelect (\r
341 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,\r
342 IN UINT8 Slot,\r
343 IN UINT16 Rca\r
344 )\r
345{\r
346 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk;\r
347 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk;\r
348 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet;\r
349 EFI_STATUS Status;\r
350\r
351 ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));\r
352 ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));\r
353 ZeroMem (&Packet, sizeof (Packet));\r
354\r
355 Packet.SdMmcCmdBlk = &SdMmcCmdBlk;\r
356 Packet.SdMmcStatusBlk = &SdMmcStatusBlk;\r
357 Packet.Timeout = SD_MMC_HC_GENERIC_TIMEOUT;\r
358\r
359 SdMmcCmdBlk.CommandIndex = SD_SELECT_DESELECT_CARD;\r
360 SdMmcCmdBlk.CommandType = SdMmcCommandTypeAc;\r
ac30e4c1
FT
361 if (Rca != 0) {\r
362 SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1b;\r
363 }\r
48555339
FT
364 SdMmcCmdBlk.CommandArgument = (UINT32)Rca << 16;\r
365\r
366 Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);\r
367\r
368 return Status;\r
369}\r
370\r
371/**\r
372 Send command VOLTAGE_SWITCH to the SD device to switch the voltage of the device.\r
373\r
374 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.\r
375\r
376 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.\r
377 @param[in] Slot The slot number of the SD card to send the command to.\r
378\r
379 @retval EFI_SUCCESS The operation is done correctly.\r
380 @retval Others The operation fails.\r
381\r
382**/\r
383EFI_STATUS\r
384SdCardVoltageSwitch (\r
385 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,\r
386 IN UINT8 Slot\r
387 )\r
388{\r
389 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk;\r
390 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk;\r
391 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet;\r
392 EFI_STATUS Status;\r
393\r
394 ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));\r
395 ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));\r
396 ZeroMem (&Packet, sizeof (Packet));\r
397\r
398 Packet.SdMmcCmdBlk = &SdMmcCmdBlk;\r
399 Packet.SdMmcStatusBlk = &SdMmcStatusBlk;\r
400 Packet.Timeout = SD_MMC_HC_GENERIC_TIMEOUT;\r
401\r
402 SdMmcCmdBlk.CommandIndex = SD_VOLTAGE_SWITCH;\r
403 SdMmcCmdBlk.CommandType = SdMmcCommandTypeAc;\r
404 SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1;\r
405 SdMmcCmdBlk.CommandArgument = 0;\r
406\r
407 Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);\r
408\r
409 return Status;\r
410}\r
411\r
412/**\r
413 Send command SET_BUS_WIDTH to the SD device to set the bus width.\r
414\r
415 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.\r
416\r
417 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.\r
418 @param[in] Slot The slot number of the SD card to send the command to.\r
419 @param[in] Rca The relative device address of addressed device.\r
420 @param[in] BusWidth The bus width to be set, it could be 1 or 4.\r
421\r
422 @retval EFI_SUCCESS The operation is done correctly.\r
423 @retval Others The operation fails.\r
424\r
425**/\r
426EFI_STATUS\r
427SdCardSetBusWidth (\r
428 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,\r
429 IN UINT8 Slot,\r
430 IN UINT16 Rca,\r
431 IN UINT8 BusWidth\r
432 )\r
433{\r
434 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk;\r
435 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk;\r
436 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet;\r
437 EFI_STATUS Status;\r
438 UINT8 Value;\r
439\r
440 ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));\r
441 ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));\r
442 ZeroMem (&Packet, sizeof (Packet));\r
443\r
444 Packet.SdMmcCmdBlk = &SdMmcCmdBlk;\r
445 Packet.SdMmcStatusBlk = &SdMmcStatusBlk;\r
446 Packet.Timeout = SD_MMC_HC_GENERIC_TIMEOUT;\r
447\r
448 SdMmcCmdBlk.CommandIndex = SD_APP_CMD;\r
449 SdMmcCmdBlk.CommandType = SdMmcCommandTypeAc;\r
450 SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1;\r
451 SdMmcCmdBlk.CommandArgument = (UINT32)Rca << 16;\r
452\r
453 Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);\r
454 if (EFI_ERROR (Status)) {\r
455 return Status;\r
456 }\r
457\r
458 SdMmcCmdBlk.CommandIndex = SD_SET_BUS_WIDTH;\r
459 SdMmcCmdBlk.CommandType = SdMmcCommandTypeAc;\r
460 SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1;\r
461\r
462 if (BusWidth == 1) {\r
463 Value = 0;\r
464 } else if (BusWidth == 4) {\r
465 Value = 2;\r
466 } else {\r
467 return EFI_INVALID_PARAMETER;\r
468 }\r
469\r
470 SdMmcCmdBlk.CommandArgument = Value & 0x3;\r
471\r
472 Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);\r
473 return Status;\r
474}\r
475\r
476/**\r
477 Send command SWITCH_FUNC to the SD device to check switchable function or switch card function.\r
478\r
479 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.\r
480\r
481 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.\r
482 @param[in] Slot The slot number of the SD card to send the command to.\r
483 @param[in] AccessMode The value for access mode group.\r
484 @param[in] CommandSystem The value for command set group.\r
485 @param[in] DriveStrength The value for drive length group.\r
486 @param[in] PowerLimit The value for power limit group.\r
487 @param[in] Mode Switch or check function.\r
6263ae93 488 @param[out] SwitchResp The return switch function status.\r
48555339
FT
489\r
490 @retval EFI_SUCCESS The operation is done correctly.\r
491 @retval Others The operation fails.\r
492\r
493**/\r
494EFI_STATUS\r
495SdCardSwitch (\r
6263ae93
FT
496 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,\r
497 IN UINT8 Slot,\r
498 IN UINT8 AccessMode,\r
499 IN UINT8 CommandSystem,\r
500 IN UINT8 DriveStrength,\r
501 IN UINT8 PowerLimit,\r
502 IN BOOLEAN Mode,\r
503 OUT UINT8 *SwitchResp\r
48555339
FT
504 )\r
505{\r
506 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk;\r
507 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk;\r
508 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet;\r
509 EFI_STATUS Status;\r
510 UINT32 ModeValue;\r
48555339
FT
511\r
512 ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));\r
513 ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));\r
514 ZeroMem (&Packet, sizeof (Packet));\r
515\r
516 Packet.SdMmcCmdBlk = &SdMmcCmdBlk;\r
517 Packet.SdMmcStatusBlk = &SdMmcStatusBlk;\r
518 Packet.Timeout = SD_MMC_HC_GENERIC_TIMEOUT;\r
519\r
520 SdMmcCmdBlk.CommandIndex = SD_SWITCH_FUNC;\r
521 SdMmcCmdBlk.CommandType = SdMmcCommandTypeAdtc;\r
522 SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1;\r
523\r
524 ModeValue = Mode ? BIT31 : 0;\r
525 SdMmcCmdBlk.CommandArgument = (AccessMode & 0xF) | ((PowerLimit & 0xF) << 4) | \\r
526 ((DriveStrength & 0xF) << 8) | ((DriveStrength & 0xF) << 12) | \\r
527 ModeValue;\r
528\r
6263ae93
FT
529 Packet.InDataBuffer = SwitchResp;\r
530 Packet.InTransferLength = 64;\r
48555339
FT
531\r
532 Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);\r
533\r
534 return Status;\r
535}\r
536\r
537/**\r
538 Send command SEND_STATUS to the addressed SD device to get its status register.\r
539\r
540 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.\r
541\r
542 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.\r
543 @param[in] Slot The slot number of the SD card to send the command to.\r
544 @param[in] Rca The relative device address of addressed device.\r
545 @param[out] DevStatus The returned device status.\r
546\r
547 @retval EFI_SUCCESS The operation is done correctly.\r
548 @retval Others The operation fails.\r
549\r
550**/\r
551EFI_STATUS\r
552SdCardSendStatus (\r
553 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,\r
554 IN UINT8 Slot,\r
555 IN UINT16 Rca,\r
556 OUT UINT32 *DevStatus\r
557 )\r
558{\r
559 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk;\r
560 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk;\r
561 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet;\r
562 EFI_STATUS Status;\r
563\r
564 ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));\r
565 ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));\r
566 ZeroMem (&Packet, sizeof (Packet));\r
567\r
568 Packet.SdMmcCmdBlk = &SdMmcCmdBlk;\r
569 Packet.SdMmcStatusBlk = &SdMmcStatusBlk;\r
570 Packet.Timeout = SD_MMC_HC_GENERIC_TIMEOUT;\r
571\r
572 SdMmcCmdBlk.CommandIndex = SD_SEND_STATUS;\r
573 SdMmcCmdBlk.CommandType = SdMmcCommandTypeAc;\r
574 SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1;\r
575 SdMmcCmdBlk.CommandArgument = (UINT32)Rca << 16;\r
576\r
577 Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);\r
578 if (!EFI_ERROR (Status)) {\r
579 *DevStatus = SdMmcStatusBlk.Resp0;\r
580 }\r
581\r
582 return Status;\r
583}\r
584\r
585/**\r
586 Send command SEND_TUNING_BLOCK to the SD device for HS200 optimal sampling point\r
587 detection.\r
588\r
589 It may be sent up to 40 times until the host finishes the tuning procedure.\r
590\r
591 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.\r
592\r
593 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.\r
594 @param[in] Slot The slot number of the SD card to send the command to.\r
595\r
596 @retval EFI_SUCCESS The operation is done correctly.\r
597 @retval Others The operation fails.\r
598\r
599**/\r
600EFI_STATUS\r
601SdCardSendTuningBlk (\r
602 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,\r
603 IN UINT8 Slot\r
604 )\r
605{\r
606 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk;\r
607 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk;\r
608 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet;\r
609 EFI_STATUS Status;\r
610 UINT8 TuningBlock[64];\r
611\r
612 ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));\r
613 ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));\r
614 ZeroMem (&Packet, sizeof (Packet));\r
615\r
616 Packet.SdMmcCmdBlk = &SdMmcCmdBlk;\r
617 Packet.SdMmcStatusBlk = &SdMmcStatusBlk;\r
618 Packet.Timeout = SD_MMC_HC_GENERIC_TIMEOUT;\r
619\r
620 SdMmcCmdBlk.CommandIndex = SD_SEND_TUNING_BLOCK;\r
621 SdMmcCmdBlk.CommandType = SdMmcCommandTypeAdtc;\r
622 SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1;\r
623 SdMmcCmdBlk.CommandArgument = 0;\r
624\r
625 Packet.InDataBuffer = TuningBlock;\r
626 Packet.InTransferLength = sizeof (TuningBlock);\r
627\r
628 Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);\r
629\r
630 return Status;\r
631}\r
632\r
633/**\r
634 Tunning the sampling point of SDR104 or SDR50 bus speed mode.\r
635\r
636 Command SD_SEND_TUNING_BLOCK may be sent up to 40 times until the host finishes the\r
637 tuning procedure.\r
638\r
639 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 and\r
640 SD Host Controller Simplified Spec 3.0 section Figure 3-7 for details.\r
641\r
642 @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.\r
643 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.\r
644 @param[in] Slot The slot number of the SD card to send the command to.\r
645\r
646 @retval EFI_SUCCESS The operation is done correctly.\r
647 @retval Others The operation fails.\r
648\r
649**/\r
650EFI_STATUS\r
651SdCardTuningClock (\r
652 IN EFI_PCI_IO_PROTOCOL *PciIo,\r
653 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,\r
654 IN UINT8 Slot\r
655 )\r
656{\r
657 EFI_STATUS Status;\r
658 UINT8 HostCtrl2;\r
659 UINT8 Retry;\r
660\r
661 //\r
662 // Notify the host that the sampling clock tuning procedure starts.\r
663 //\r
664 HostCtrl2 = BIT6;\r
665 Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);\r
666 if (EFI_ERROR (Status)) {\r
667 return Status;\r
668 }\r
669 //\r
670 // Ask the device to send a sequence of tuning blocks till the tuning procedure is done.\r
671 //\r
672 Retry = 0;\r
673 do {\r
674 Status = SdCardSendTuningBlk (PassThru, Slot);\r
675 if (EFI_ERROR (Status)) {\r
e27ccaba 676 DEBUG ((DEBUG_ERROR, "SdCardSendTuningBlk: Send tuning block fails with %r\n", Status));\r
48555339
FT
677 return Status;\r
678 }\r
679\r
680 Status = SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, TRUE, sizeof (HostCtrl2), &HostCtrl2);\r
681 if (EFI_ERROR (Status)) {\r
682 return Status;\r
683 }\r
684\r
8c983d3e 685 if ((HostCtrl2 & (BIT6 | BIT7)) == 0) {\r
48555339
FT
686 break;\r
687 }\r
8c983d3e
FT
688 if ((HostCtrl2 & (BIT6 | BIT7)) == BIT7) {\r
689 return EFI_SUCCESS;\r
690 }\r
48555339
FT
691 } while (++Retry < 40);\r
692\r
e27ccaba 693 DEBUG ((DEBUG_ERROR, "SdCardTuningClock: Send tuning block fails at %d times with HostCtrl2 %02x\n", Retry, HostCtrl2));\r
8c983d3e
FT
694 //\r
695 // Abort the tuning procedure and reset the tuning circuit.\r
696 //\r
697 HostCtrl2 = (UINT8)~(BIT6 | BIT7);\r
698 Status = SdMmcHcAndMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);\r
699 if (EFI_ERROR (Status)) {\r
700 return Status;\r
48555339 701 }\r
8c983d3e 702 return EFI_DEVICE_ERROR;\r
48555339
FT
703}\r
704\r
705/**\r
706 Switch the bus width to specified width.\r
707\r
708 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 and\r
709 SD Host Controller Simplified Spec 3.0 section Figure 3-7 for details.\r
710\r
711 @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.\r
712 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.\r
713 @param[in] Slot The slot number of the SD card to send the command to.\r
714 @param[in] Rca The relative device address to be assigned.\r
715 @param[in] BusWidth The bus width to be set, it could be 4 or 8.\r
716\r
717 @retval EFI_SUCCESS The operation is done correctly.\r
718 @retval Others The operation fails.\r
719\r
720**/\r
721EFI_STATUS\r
722SdCardSwitchBusWidth (\r
723 IN EFI_PCI_IO_PROTOCOL *PciIo,\r
724 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,\r
725 IN UINT8 Slot,\r
726 IN UINT16 Rca,\r
727 IN UINT8 BusWidth\r
728 )\r
729{\r
730 EFI_STATUS Status;\r
731 UINT32 DevStatus;\r
732\r
733 Status = SdCardSetBusWidth (PassThru, Slot, Rca, BusWidth);\r
734 if (EFI_ERROR (Status)) {\r
e27ccaba 735 DEBUG ((DEBUG_ERROR, "SdCardSwitchBusWidth: Switch to bus width %d fails with %r\n", BusWidth, Status));\r
48555339
FT
736 return Status;\r
737 }\r
738\r
739 Status = SdCardSendStatus (PassThru, Slot, Rca, &DevStatus);\r
740 if (EFI_ERROR (Status)) {\r
e27ccaba 741 DEBUG ((DEBUG_ERROR, "SdCardSwitchBusWidth: Send status fails with %r\n", Status));\r
48555339
FT
742 return Status;\r
743 }\r
744 //\r
745 // Check the switch operation is really successful or not.\r
746 //\r
747 if ((DevStatus >> 16) != 0) {\r
e27ccaba 748 DEBUG ((DEBUG_ERROR, "SdCardSwitchBusWidth: The switch operation fails as DevStatus is 0x%08x\n", DevStatus));\r
48555339
FT
749 return EFI_DEVICE_ERROR;\r
750 }\r
751\r
752 Status = SdMmcHcSetBusWidth (PciIo, Slot, BusWidth);\r
753\r
754 return Status;\r
755}\r
756\r
757/**\r
758 Switch the high speed timing according to request.\r
759\r
760 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 and\r
761 SD Host Controller Simplified Spec 3.0 section Figure 2-29 for details.\r
762\r
763 @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.\r
764 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.\r
765 @param[in] Slot The slot number of the SD card to send the command to.\r
766 @param[in] Rca The relative device address to be assigned.\r
767 @param[in] S18A The boolean to show if it's a UHS-I SD card.\r
768\r
769 @retval EFI_SUCCESS The operation is done correctly.\r
770 @retval Others The operation fails.\r
771\r
772**/\r
773EFI_STATUS\r
774SdCardSetBusMode (\r
775 IN EFI_PCI_IO_PROTOCOL *PciIo,\r
776 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,\r
777 IN UINT8 Slot,\r
778 IN UINT16 Rca,\r
779 IN BOOLEAN S18A\r
780 )\r
781{\r
782 EFI_STATUS Status;\r
783 SD_MMC_HC_SLOT_CAP *Capability;\r
784 UINT32 ClockFreq;\r
785 UINT8 BusWidth;\r
786 UINT8 AccessMode;\r
787 UINT8 HostCtrl1;\r
6263ae93 788 UINT8 SwitchResp[64];\r
a4708009 789 SD_MMC_BUS_MODE Timing;\r
48555339
FT
790 SD_MMC_HC_PRIVATE_DATA *Private;\r
791\r
792 Private = SD_MMC_HC_PRIVATE_FROM_THIS (PassThru);\r
793\r
794 Capability = &Private->Capability[Slot];\r
795\r
796 Status = SdCardSelect (PassThru, Slot, Rca);\r
797 if (EFI_ERROR (Status)) {\r
798 return Status;\r
799 }\r
800\r
801 BusWidth = 4;\r
802\r
803 Status = SdCardSwitchBusWidth (PciIo, PassThru, Slot, Rca, BusWidth);\r
804 if (EFI_ERROR (Status)) {\r
805 return Status;\r
806 }\r
48555339 807 //\r
6263ae93
FT
808 // Get the supported bus speed from SWITCH cmd return data group #1.\r
809 //\r
810 Status = SdCardSwitch (PassThru, Slot, 0xF, 0xF, 0xF, 0xF, FALSE, SwitchResp);\r
811 if (EFI_ERROR (Status)) {\r
812 return Status;\r
813 }\r
814 //\r
815 // Calculate supported bus speed/bus width/clock frequency by host and device capability.\r
48555339
FT
816 //\r
817 ClockFreq = 0;\r
6263ae93 818 if (S18A && (Capability->Sdr104 != 0) && ((SwitchResp[13] & BIT3) != 0)) {\r
48555339
FT
819 ClockFreq = 208;\r
820 AccessMode = 3;\r
a4708009 821 Timing = SdMmcUhsSdr104;\r
6263ae93 822 } else if (S18A && (Capability->Sdr50 != 0) && ((SwitchResp[13] & BIT2) != 0)) {\r
48555339
FT
823 ClockFreq = 100;\r
824 AccessMode = 2;\r
a4708009 825 Timing = SdMmcUhsSdr50;\r
6263ae93 826 } else if (S18A && (Capability->Ddr50 != 0) && ((SwitchResp[13] & BIT4) != 0)) {\r
48555339
FT
827 ClockFreq = 50;\r
828 AccessMode = 4;\r
a4708009 829 Timing = SdMmcUhsDdr50;\r
6263ae93 830 } else if ((SwitchResp[13] & BIT1) != 0) {\r
48555339
FT
831 ClockFreq = 50;\r
832 AccessMode = 1;\r
a4708009 833 Timing = SdMmcUhsSdr25;\r
6263ae93
FT
834 } else {\r
835 ClockFreq = 25;\r
836 AccessMode = 0;\r
a4708009 837 Timing = SdMmcUhsSdr12;\r
48555339
FT
838 }\r
839\r
6263ae93 840 Status = SdCardSwitch (PassThru, Slot, AccessMode, 0xF, 0xF, 0xF, TRUE, SwitchResp);\r
48555339
FT
841 if (EFI_ERROR (Status)) {\r
842 return Status;\r
843 }\r
844\r
6263ae93 845 if ((SwitchResp[16] & 0xF) != AccessMode) {\r
e27ccaba 846 DEBUG ((DEBUG_ERROR, "SdCardSetBusMode: Switch to AccessMode %d ClockFreq %d BusWidth %d fails! The Switch response is 0x%1x\n", AccessMode, ClockFreq, BusWidth, SwitchResp[16] & 0xF));\r
6263ae93
FT
847 return EFI_DEVICE_ERROR;\r
848 }\r
849\r
e27ccaba 850 DEBUG ((DEBUG_INFO, "SdCardSetBusMode: Switch to AccessMode %d ClockFreq %d BusWidth %d\n", AccessMode, ClockFreq, BusWidth));\r
6263ae93 851\r
48555339
FT
852 //\r
853 // Set to Hight Speed timing\r
854 //\r
855 if (AccessMode == 1) {\r
856 HostCtrl1 = BIT2;\r
857 Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL1, sizeof (HostCtrl1), &HostCtrl1);\r
858 if (EFI_ERROR (Status)) {\r
859 return Status;\r
860 }\r
861 }\r
862\r
a4708009 863 Status = SdMmcHcUhsSignaling (Private->ControllerHandle, PciIo, Slot, Timing);\r
48555339
FT
864 if (EFI_ERROR (Status)) {\r
865 return Status;\r
866 }\r
867\r
b5547b9c 868 Status = SdMmcHcClockSupply (PciIo, Slot, ClockFreq * 1000, Private->BaseClkFreq[Slot], Private->ControllerVersion[Slot]);\r
48555339
FT
869 if (EFI_ERROR (Status)) {\r
870 return Status;\r
871 }\r
872\r
b7b803a6
TM
873 if (mOverride != NULL && mOverride->NotifyPhase != NULL) {\r
874 Status = mOverride->NotifyPhase (\r
875 Private->ControllerHandle,\r
876 Slot,\r
877 EdkiiSdMmcSwitchClockFreqPost,\r
878 &Timing\r
879 );\r
880 if (EFI_ERROR (Status)) {\r
881 DEBUG ((\r
882 DEBUG_ERROR,\r
883 "%a: SD/MMC switch clock freq post notifier callback failed - %r\n",\r
884 __FUNCTION__,\r
885 Status\r
886 ));\r
887 return Status;\r
888 }\r
889 }\r
890\r
48555339
FT
891 if ((AccessMode == 3) || ((AccessMode == 2) && (Capability->TuningSDR50 != 0))) {\r
892 Status = SdCardTuningClock (PciIo, PassThru, Slot);\r
893 if (EFI_ERROR (Status)) {\r
894 return Status;\r
895 }\r
896 }\r
897\r
898 return Status;\r
899}\r
900\r
901/**\r
902 Execute SD device identification procedure.\r
903\r
904 Refer to SD Physical Layer Simplified Spec 4.1 Section 3.6 for details.\r
905\r
906 @param[in] Private A pointer to the SD_MMC_HC_PRIVATE_DATA instance.\r
907 @param[in] Slot The slot number of the SD card to send the command to.\r
908\r
909 @retval EFI_SUCCESS There is a SD card.\r
910 @retval Others There is not a SD card.\r
911\r
912**/\r
913EFI_STATUS\r
914SdCardIdentification (\r
915 IN SD_MMC_HC_PRIVATE_DATA *Private,\r
916 IN UINT8 Slot\r
917 )\r
918{\r
919 EFI_STATUS Status;\r
920 EFI_PCI_IO_PROTOCOL *PciIo;\r
921 EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru;\r
922 UINT32 Ocr;\r
923 UINT16 Rca;\r
924 BOOLEAN Xpc;\r
925 BOOLEAN S18r;\r
926 UINT64 MaxCurrent;\r
927 UINT16 ControllerVer;\r
928 UINT8 PowerCtrl;\r
929 UINT32 PresentState;\r
930 UINT8 HostCtrl2;\r
ec86d285 931 UINTN Retry;\r
48555339
FT
932\r
933 PciIo = Private->PciIo;\r
934 PassThru = &Private->PassThru;\r
935 //\r
936 // 1. Send Cmd0 to the device\r
937 //\r
938 Status = SdCardReset (PassThru, Slot);\r
939 if (EFI_ERROR (Status)) {\r
e27ccaba 940 DEBUG ((DEBUG_INFO, "SdCardIdentification: Executing Cmd0 fails with %r\n", Status));\r
48555339
FT
941 return Status;\r
942 }\r
943 //\r
944 // 2. Send Cmd8 to the device\r
945 //\r
946 Status = SdCardVoltageCheck (PassThru, Slot, 0x1, 0xFF);\r
947 if (EFI_ERROR (Status)) {\r
e27ccaba 948 DEBUG ((DEBUG_INFO, "SdCardIdentification: Executing Cmd8 fails with %r\n", Status));\r
48555339
FT
949 return Status;\r
950 }\r
951 //\r
952 // 3. Send SDIO Cmd5 to the device to the SDIO device OCR register.\r
953 //\r
954 Status = SdioSendOpCond (PassThru, Slot, 0, FALSE);\r
955 if (!EFI_ERROR (Status)) {\r
e27ccaba 956 DEBUG ((DEBUG_INFO, "SdCardIdentification: Found SDIO device, ignore it as we don't support\n"));\r
48555339
FT
957 return EFI_DEVICE_ERROR;\r
958 }\r
959 //\r
960 // 4. Send Acmd41 with voltage window 0 to the device\r
961 //\r
962 Status = SdCardSendOpCond (PassThru, Slot, 0, 0, FALSE, FALSE, FALSE, &Ocr);\r
963 if (EFI_ERROR (Status)) {\r
e27ccaba 964 DEBUG ((DEBUG_INFO, "SdCardIdentification: Executing SdCardSendOpCond fails with %r\n", Status));\r
48555339
FT
965 return EFI_DEVICE_ERROR;\r
966 }\r
967\r
968 if (Private->Capability[Slot].Voltage33 != 0) {\r
969 //\r
970 // Support 3.3V\r
971 //\r
972 MaxCurrent = ((UINT32)Private->MaxCurrent[Slot] & 0xFF) * 4;\r
973 } else if (Private->Capability[Slot].Voltage30 != 0) {\r
974 //\r
975 // Support 3.0V\r
976 //\r
977 MaxCurrent = (((UINT32)Private->MaxCurrent[Slot] >> 8) & 0xFF) * 4;\r
978 } else if (Private->Capability[Slot].Voltage18 != 0) {\r
979 //\r
980 // Support 1.8V\r
981 //\r
982 MaxCurrent = (((UINT32)Private->MaxCurrent[Slot] >> 16) & 0xFF) * 4;\r
983 } else {\r
984 ASSERT (FALSE);\r
985 return EFI_DEVICE_ERROR;\r
986 }\r
987\r
988 if (MaxCurrent >= 150) {\r
989 Xpc = TRUE;\r
990 } else {\r
991 Xpc = FALSE;\r
992 }\r
993\r
994 Status = SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_CTRL_VER, TRUE, sizeof (ControllerVer), &ControllerVer);\r
995 if (EFI_ERROR (Status)) {\r
996 return Status;\r
997 }\r
998\r
bbce0015
JB
999 if (((ControllerVer & 0xFF) >= SD_MMC_HC_CTRL_VER_300) &&\r
1000 ((ControllerVer & 0xFF) <= SD_MMC_HC_CTRL_VER_420)) {\r
48555339 1001 S18r = TRUE;\r
bdf038cc 1002 } else if (((ControllerVer & 0xFF) == SD_MMC_HC_CTRL_VER_100) || ((ControllerVer & 0xFF) == SD_MMC_HC_CTRL_VER_200)) {\r
48555339
FT
1003 S18r = FALSE;\r
1004 } else {\r
1005 ASSERT (FALSE);\r
1006 return EFI_UNSUPPORTED;\r
1007 }\r
1008 //\r
1009 // 5. Repeatly send Acmd41 with supply voltage window to the device.\r
1010 // Note here we only support the cards complied with SD physical\r
1011 // layer simplified spec version 2.0 and version 3.0 and above.\r
1012 //\r
ec86d285
FT
1013 Ocr = 0;\r
1014 Retry = 0;\r
48555339
FT
1015 do {\r
1016 Status = SdCardSendOpCond (PassThru, Slot, 0, Ocr, S18r, Xpc, TRUE, &Ocr);\r
1017 if (EFI_ERROR (Status)) {\r
e27ccaba 1018 DEBUG ((DEBUG_ERROR, "SdCardIdentification: SdCardSendOpCond fails with %r Ocr %x, S18r %x, Xpc %x\n", Status, Ocr, S18r, Xpc));\r
48555339
FT
1019 return EFI_DEVICE_ERROR;\r
1020 }\r
ec86d285
FT
1021\r
1022 if (Retry++ == 100) {\r
1023 DEBUG ((DEBUG_ERROR, "SdCardIdentification: SdCardSendOpCond fails too many times\n"));\r
1024 return EFI_DEVICE_ERROR;\r
1025 }\r
1026 gBS->Stall(10 * 1000);\r
48555339
FT
1027 } while ((Ocr & BIT31) == 0);\r
1028\r
1029 //\r
1030 // 6. If the S18A bit is set and the Host Controller supports 1.8V signaling\r
1031 // (One of support bits is set to 1: SDR50, SDR104 or DDR50 in the\r
1032 // Capabilities register), switch its voltage to 1.8V.\r
1033 //\r
1034 if ((Private->Capability[Slot].Sdr50 != 0 ||\r
1035 Private->Capability[Slot].Sdr104 != 0 ||\r
1036 Private->Capability[Slot].Ddr50 != 0) &&\r
1037 ((Ocr & BIT24) != 0)) {\r
1038 Status = SdCardVoltageSwitch (PassThru, Slot);\r
1039 if (EFI_ERROR (Status)) {\r
e27ccaba 1040 DEBUG ((DEBUG_ERROR, "SdCardIdentification: Executing SdCardVoltageSwitch fails with %r\n", Status));\r
48555339
FT
1041 Status = EFI_DEVICE_ERROR;\r
1042 goto Error;\r
1043 } else {\r
1044 Status = SdMmcHcStopClock (PciIo, Slot);\r
1045 if (EFI_ERROR (Status)) {\r
1046 Status = EFI_DEVICE_ERROR;\r
1047 goto Error;\r
1048 }\r
1049\r
1050 SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_PRESENT_STATE, TRUE, sizeof (PresentState), &PresentState);\r
1051 if (((PresentState >> 20) & 0xF) != 0) {\r
e27ccaba 1052 DEBUG ((DEBUG_ERROR, "SdCardIdentification: SwitchVoltage fails with PresentState = 0x%x\n", PresentState));\r
48555339
FT
1053 Status = EFI_DEVICE_ERROR;\r
1054 goto Error;\r
1055 }\r
1056 HostCtrl2 = BIT3;\r
1057 SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);\r
1058\r
1059 gBS->Stall (5000);\r
1060\r
1061 SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, TRUE, sizeof (HostCtrl2), &HostCtrl2);\r
1062 if ((HostCtrl2 & BIT3) == 0) {\r
e27ccaba 1063 DEBUG ((DEBUG_ERROR, "SdCardIdentification: SwitchVoltage fails with HostCtrl2 = 0x%x\n", HostCtrl2));\r
48555339
FT
1064 Status = EFI_DEVICE_ERROR;\r
1065 goto Error;\r
1066 }\r
1067\r
b5547b9c 1068 SdMmcHcInitClockFreq (PciIo, Slot, Private->BaseClkFreq[Slot], Private->ControllerVersion[Slot]);\r
48555339 1069\r
2a8b78cf 1070 gBS->Stall (1000);\r
48555339
FT
1071\r
1072 SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_PRESENT_STATE, TRUE, sizeof (PresentState), &PresentState);\r
1073 if (((PresentState >> 20) & 0xF) != 0xF) {\r
e27ccaba 1074 DEBUG ((DEBUG_ERROR, "SdCardIdentification: SwitchVoltage fails with PresentState = 0x%x, It should be 0xF\n", PresentState));\r
48555339
FT
1075 Status = EFI_DEVICE_ERROR;\r
1076 goto Error;\r
1077 }\r
1078 }\r
e27ccaba 1079 DEBUG ((DEBUG_INFO, "SdCardIdentification: Switch to 1.8v signal voltage success\n"));\r
48555339
FT
1080 }\r
1081\r
1082 Status = SdCardAllSendCid (PassThru, Slot);\r
1083 if (EFI_ERROR (Status)) {\r
e27ccaba 1084 DEBUG ((DEBUG_ERROR, "SdCardIdentification: Executing SdCardAllSendCid fails with %r\n", Status));\r
48555339
FT
1085 return Status;\r
1086 }\r
1087\r
1088 Status = SdCardSetRca (PassThru, Slot, &Rca);\r
1089 if (EFI_ERROR (Status)) {\r
e27ccaba 1090 DEBUG ((DEBUG_ERROR, "SdCardIdentification: Executing SdCardSetRca fails with %r\n", Status));\r
48555339
FT
1091 return Status;\r
1092 }\r
1093 //\r
1094 // Enter Data Tranfer Mode.\r
1095 //\r
e27ccaba 1096 DEBUG ((DEBUG_INFO, "SdCardIdentification: Found a SD device at slot [%d]\n", Slot));\r
48555339
FT
1097 Private->Slot[Slot].CardType = SdCardType;\r
1098\r
1099 Status = SdCardSetBusMode (PciIo, PassThru, Slot, Rca, ((Ocr & BIT24) != 0));\r
1100\r
1101 return Status;\r
1102\r
1103Error:\r
1104 //\r
1105 // Set SD Bus Power = 0\r
1106 //\r
1107 PowerCtrl = (UINT8)~BIT0;\r
1108 Status = SdMmcHcAndMmio (PciIo, Slot, SD_MMC_HC_POWER_CTRL, sizeof (PowerCtrl), &PowerCtrl);\r
1109 return EFI_DEVICE_ERROR;\r
1110}\r
1111\r