]> git.proxmox.com Git - mirror_edk2.git/blame - QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/CEATA.c
QuarkSocPkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / QuarkSocPkg / QuarkSouthCluster / Sdio / Dxe / SDMediaDeviceDxe / CEATA.c
CommitLineData
9b6bbcdb
MK
1/** @file\r
2\r
3CEATA specific functions implementation\r
4\r
5Copyright (c) 2013-2015 Intel Corporation.\r
6\r
c9f231d0 7SPDX-License-Identifier: BSD-2-Clause-Patent\r
9b6bbcdb
MK
8\r
9**/\r
10\r
11#include "SDMediaDevice.h"\r
12\r
13/**\r
14 Send RW_MULTIPLE_REGISTER command\r
15\r
16 @param CardData Pointer to CARD_DATA.\r
17 @param Address Register address.\r
18 @param ByteCount Buffer size.\r
19 @param Write TRUE means write, FALSE means read.\r
20 @param Buffer Buffer pointer.\r
21\r
22 @retval EFI_SUCCESS Success\r
23 @retval EFI_DEVICE_ERROR Hardware Error\r
24 @retval EFI_INVALID_PARAMETER Parameter is error\r
25 @retval EFI_NO_MEDIA No media\r
26 @retval EFI_MEDIA_CHANGED Media Change\r
27 @retval EFI_BAD_BUFFER_SIZE Buffer size is bad\r
28\r
29**/\r
30EFI_STATUS\r
31ReadWriteMultipleRegister (\r
32 IN CARD_DATA *CardData,\r
33 IN UINT16 Address,\r
34 IN UINT8 ByteCount,\r
35 IN BOOLEAN Write,\r
36 IN UINT8 *Buffer\r
37 )\r
38{\r
39 EFI_STATUS Status;\r
40 UINT32 Argument;\r
41\r
42 Status = EFI_SUCCESS;\r
43\r
44 if ((Address % 4 != 0) || (ByteCount % 4 != 0)) {\r
45 Status = EFI_INVALID_PARAMETER;\r
46 goto Exit;\r
47 }\r
48\r
49 Argument = (Address << 16) | ByteCount;\r
50 if (Write) {\r
51 Argument |= BIT31;\r
52 }\r
53\r
54\r
55 if (Write) {\r
56 CopyMem (CardData->AlignedBuffer, Buffer, ByteCount);\r
57\r
58 Status = SendCommand (\r
59 CardData,\r
60 RW_MULTIPLE_REGISTER,\r
61 Argument,\r
62 OutData,\r
63 CardData->AlignedBuffer,\r
64 ByteCount,\r
65 ResponseR1b,\r
66 TIMEOUT_DATA,\r
67 (UINT32*)&(CardData->CardStatus)\r
68 );\r
69 } else {\r
70 Status = SendCommand (\r
71 CardData,\r
72 RW_MULTIPLE_REGISTER,\r
73 Argument,\r
74 InData,\r
75 CardData->AlignedBuffer,\r
76 ByteCount,\r
77 ResponseR1,\r
78 TIMEOUT_DATA,\r
79 (UINT32*)&(CardData->CardStatus)\r
80 );\r
81 if (!EFI_ERROR (Status)) {\r
82 CopyMem (Buffer, CardData->AlignedBuffer, ByteCount);\r
83 }\r
84\r
85 }\r
86Exit:\r
87 return Status;\r
88}\r
89\r
90/**\r
91 Send ReadWriteMultipleBlock command with RW_MULTIPLE_REGISTER command\r
92\r
93 @param CardData Pointer to CARD_DATA.\r
94 @param DataUnitCount Buffer size in 512 bytes unit.\r
95 @param Write TRUE means write, FALSE means read.\r
96 @param Buffer Buffer pointer.\r
97\r
98 @retval EFI_SUCCESS Success\r
99 @retval EFI_DEVICE_ERROR Hardware Error\r
100 @retval EFI_INVALID_PARAMETER Parameter is error\r
101 @retval EFI_NO_MEDIA No media\r
102 @retval EFI_MEDIA_CHANGED Media Change\r
103 @retval EFI_BAD_BUFFER_SIZE Buffer size is bad\r
104\r
105**/\r
106EFI_STATUS\r
107ReadWriteMultipleBlock (\r
108 IN CARD_DATA *CardData,\r
109 IN UINT16 DataUnitCount,\r
110 IN BOOLEAN Write,\r
111 IN UINT8 *Buffer\r
112 )\r
113{\r
114 EFI_STATUS Status;\r
115 EFI_SD_HOST_IO_PROTOCOL *SDHostIo;\r
116 UINT32 TransferLength;\r
117\r
118 Status = EFI_SUCCESS;\r
119 SDHostIo = CardData->SDHostIo;\r
120\r
121 TransferLength = DataUnitCount * DATA_UNIT_SIZE;\r
122 if (TransferLength > SDHostIo->HostCapability.BoundarySize) {\r
123 return EFI_INVALID_PARAMETER;\r
124 }\r
125\r
126 if (Write) {\r
127 CopyMem (CardData->AlignedBuffer, Buffer, TransferLength);\r
128\r
129 Status = SendCommand (\r
130 CardData,\r
131 RW_MULTIPLE_BLOCK,\r
132 (DataUnitCount | BIT31),\r
133 OutData,\r
134 CardData->AlignedBuffer,\r
135 TransferLength,\r
136 ResponseR1b,\r
137 TIMEOUT_DATA,\r
138 (UINT32*)&(CardData->CardStatus)\r
139 );\r
140 } else {\r
141 Status = SendCommand (\r
142 CardData,\r
143 RW_MULTIPLE_BLOCK,\r
144 DataUnitCount,\r
145 InData,\r
146 CardData->AlignedBuffer,\r
147 TransferLength,\r
148 ResponseR1,\r
149 TIMEOUT_DATA,\r
150 (UINT32*)&(CardData->CardStatus)\r
151 );\r
152 if (!EFI_ERROR (Status)) {\r
153 CopyMem (Buffer, CardData->AlignedBuffer, TransferLength);\r
154 }\r
155 }\r
156\r
157 return Status;\r
158}\r
159\r
160/**\r
161 Send software reset\r
162\r
163 @param CardData Pointer to CARD_DATA.\r
164\r
165 @retval EFI_SUCCESS Success\r
166 @retval EFI_DEVICE_ERROR Hardware Error\r
167 @retval EFI_INVALID_PARAMETER Parameter is error\r
168 @retval EFI_NO_MEDIA No media\r
169 @retval EFI_MEDIA_CHANGED Media Change\r
170 @retval EFI_BAD_BUFFER_SIZE Buffer size is bad\r
171\r
172**/\r
173EFI_STATUS\r
174SoftwareReset (\r
175 IN CARD_DATA *CardData\r
176 )\r
177{\r
178 EFI_STATUS Status;\r
179 UINT8 Data;\r
180 UINT32 TimeOut;\r
181\r
182 Data = BIT2;\r
183\r
184 Status = FastIO (CardData, Reg_Control, &Data, TRUE);\r
185 if (EFI_ERROR (Status)) {\r
186 goto Exit;\r
187 }\r
188\r
189 TimeOut = 5 * 1000;\r
190\r
191 do {\r
192 gBS->Stall (1 * 1000);\r
193 Status = FastIO (CardData, Reg_Control, &Data, FALSE);\r
194 if (EFI_ERROR (Status)) {\r
195 goto Exit;\r
196 }\r
197 if ((Data & BIT2) == BIT2) {\r
198 break;\r
199 }\r
200\r
201 TimeOut--;\r
202 } while (TimeOut > 0);\r
203\r
204 if (TimeOut == 0) {\r
205 Status = EFI_TIMEOUT;\r
206 goto Exit;\r
207 }\r
208\r
209 Data &= ~BIT2;\r
210 Status = FastIO (CardData, Reg_Control, &Data, TRUE);\r
211\r
212 TimeOut = 5 * 1000;\r
213\r
214 do {\r
215 gBS->Stall (1 * 1000);\r
216 Status = FastIO (CardData, Reg_Control, &Data, FALSE);\r
217 if (EFI_ERROR (Status)) {\r
218 goto Exit;\r
219 }\r
220 if ((Data & BIT2) != BIT2) {\r
221 break;\r
222 }\r
223\r
224 TimeOut--;\r
225 } while (TimeOut > 0);\r
226\r
227\r
228 if (TimeOut == 0) {\r
229 Status = EFI_TIMEOUT;\r
230 goto Exit;\r
231 }\r
232\r
233\r
234Exit:\r
235 return Status;\r
236}\r
237\r
238\r
239/**\r
240 SendATACommand specificed in Taskfile\r
241\r
242 @param CardData Pointer to CARD_DATA.\r
243 @param TaskFile Pointer to TASK_FILE.\r
244 @param Write TRUE means write, FALSE means read.\r
245 @param Buffer If NULL, means no data transfer, neither read nor write.\r
246 @param SectorCount Buffer size in 512 bytes unit.\r
247\r
248 @retval EFI_SUCCESS Success\r
249 @retval EFI_DEVICE_ERROR Hardware Error\r
250 @retval EFI_INVALID_PARAMETER Parameter is error\r
251 @retval EFI_NO_MEDIA No media\r
252 @retval EFI_MEDIA_CHANGED Media Change\r
253 @retval EFI_BAD_BUFFER_SIZE Buffer size is bad\r
254\r
255**/\r
256EFI_STATUS\r
257SendATACommand (\r
258 IN CARD_DATA *CardData,\r
259 IN TASK_FILE *TaskFile,\r
260 IN BOOLEAN Write,\r
261 IN UINT8 *Buffer,\r
262 IN UINT16 SectorCount\r
263 )\r
264{\r
265 EFI_STATUS Status;\r
9b6bbcdb
MK
266 UINT8 Data;\r
267 UINT32 TimeOut;\r
268\r
9b6bbcdb
MK
269 //\r
270 //Write register\r
271 //\r
272 Status = ReadWriteMultipleRegister (\r
273 CardData,\r
274 0,\r
275 sizeof (TASK_FILE),\r
276 TRUE,\r
277 (UINT8*)TaskFile\r
278 );\r
279 if (EFI_ERROR (Status)) {\r
280 DEBUG((EFI_D_ERROR, "ReadWriteMultipleRegister 0x%x\n", Status));\r
281 goto Exit;\r
282 }\r
283\r
284 TimeOut = 5000;\r
285 do {\r
286 gBS->Stall (1 * 1000);\r
287 Data = 0;\r
288 Status = FastIO (\r
289 CardData,\r
290 Reg_Command_Status,\r
291 &Data,\r
292 FALSE\r
293 );\r
294 if (EFI_ERROR (Status)) {\r
295 return Status;\r
296 }\r
297\r
298 if (((Data & BIT7) == 0) && ((Data & BIT6) == BIT6)) {\r
299 break;\r
300 }\r
301\r
302 TimeOut --;\r
303 } while (TimeOut > 0);\r
304\r
305 if (TimeOut == 0) {\r
306 DEBUG((EFI_D_ERROR, "ReadWriteMultipleRegister FastIO EFI_TIMEOUT 0x%x\n", Data));\r
307 Status = EFI_TIMEOUT;\r
308 goto Exit;\r
309 }\r
310\r
311\r
312 if (Buffer != NULL) {\r
313 Status = ReadWriteMultipleBlock (\r
314 CardData,\r
315 SectorCount,\r
316 Write,\r
317 (UINT8*)Buffer\r
318 );\r
319 if (EFI_ERROR (Status)) {\r
320 DEBUG((EFI_D_ERROR, "ReadWriteMultipleBlock EFI_TIMEOUT 0x%x\n", Status));\r
321 goto Exit;\r
322 }\r
323\r
324 TimeOut = 5 * 1000;\r
325 do {\r
326 gBS->Stall (1 * 1000);\r
327\r
328 Data = 0;\r
329 Status = FastIO (\r
330 CardData,\r
331 Reg_Command_Status,\r
332 &Data,\r
333 FALSE\r
334 );\r
335 if (EFI_ERROR (Status)) {\r
336 return Status;\r
337 }\r
338\r
339 if (((Data & BIT7) == 0) && ((Data & BIT3) == 0)) {\r
340 break;\r
341 }\r
342\r
343 TimeOut --;\r
344 } while (TimeOut > 0);\r
345 if (TimeOut == 0) {\r
346 DEBUG((EFI_D_ERROR, "ReadWriteMultipleBlock FastIO EFI_TIMEOUT 0x%x\n", Data));\r
347 Status = EFI_TIMEOUT;\r
348 goto Exit;\r
349 }\r
350\r
351\r
352 if (((Data & BIT6) == BIT6) && (Data & BIT0) == 0) {\r
353 Status = EFI_SUCCESS;\r
354 } else {\r
355 Status = EFI_DEVICE_ERROR;\r
356 }\r
357 }\r
358\r
359Exit:\r
360 if (EFI_ERROR (Status)) {\r
361 SoftwareReset (CardData);\r
362 }\r
363\r
364 return Status;\r
365}\r
366\r
367/**\r
368 IDENTIFY_DEVICE command\r
369\r
370 @param CardData Pointer to CARD_DATA.\r
371\r
372 @retval EFI_SUCCESS Success\r
373 @retval EFI_DEVICE_ERROR Hardware Error\r
374 @retval EFI_INVALID_PARAMETER Parameter is error\r
375 @retval EFI_NO_MEDIA No media\r
376 @retval EFI_MEDIA_CHANGED Media Change\r
377 @retval EFI_BAD_BUFFER_SIZE Buffer size is bad\r
378\r
379**/\r
380EFI_STATUS\r
381IndentifyDevice (\r
382 IN CARD_DATA *CardData\r
383 )\r
384{\r
385 EFI_STATUS Status;\r
386\r
387 ZeroMem (&CardData->TaskFile, sizeof (TASK_FILE));\r
388\r
389 //\r
390 //The host only supports nIEN = 0\r
391 //\r
392 CardData->TaskFile.Command_Status = IDENTIFY_DEVICE;\r
393\r
394\r
395 Status = SendATACommand (\r
396 CardData,\r
397 &CardData->TaskFile,\r
398 FALSE,\r
399 (UINT8*)&(CardData->IndentifyDeviceData),\r
400 1\r
401 );\r
402\r
403\r
404 return Status;\r
405}\r
406\r
407/**\r
408 FLUSH_CACHE_EXT command\r
409\r
410 @param CardData Pointer to CARD_DATA.\r
411\r
412 @retval EFI_SUCCESS Success\r
413 @retval EFI_DEVICE_ERROR Hardware Error\r
414 @retval EFI_INVALID_PARAMETER Parameter is error\r
415 @retval EFI_NO_MEDIA No media\r
416 @retval EFI_MEDIA_CHANGED Media Change\r
417 @retval EFI_BAD_BUFFER_SIZE Buffer size is bad\r
418\r
419**/\r
420EFI_STATUS\r
421FlushCache (\r
422 IN CARD_DATA *CardData\r
423 )\r
424{\r
425\r
426 //\r
427 //Hitachi CE-ATA will always make the busy high after\r
428 //receving this command\r
429 //\r
430/*\r
431 EFI_STATUS Status;\r
432 ZeroMem (&CardData->TaskFile, sizeof (TASK_FILE));\r
433 //\r
434 //The host only supports nIEN = 0\r
435 //\r
436 CardData->TaskFile.Command_Status = FLUSH_CACHE_EXT;\r
437\r
438 Status = SendATACommand (\r
439 CardData,\r
440 &CardData->TaskFile,\r
441 FALSE,\r
442 NULL,\r
443 0\r
444 );\r
445*/\r
446 return EFI_SUCCESS;\r
447}\r
448\r
449/**\r
450 STANDBY_IMMEDIATE command\r
451\r
452 @param CardData Pointer to CARD_DATA.\r
453\r
454 @retval EFI_SUCCESS Success\r
455 @retval EFI_DEVICE_ERROR Hardware Error\r
456 @retval EFI_INVALID_PARAMETER Parameter is error\r
457 @retval EFI_NO_MEDIA No media\r
458 @retval EFI_MEDIA_CHANGED Media Change\r
459 @retval EFI_BAD_BUFFER_SIZE Buffer size is bad\r
460\r
461**/\r
462EFI_STATUS\r
463StandByImmediate (\r
464 IN CARD_DATA *CardData\r
465 )\r
466{\r
467 EFI_STATUS Status;\r
468\r
469 ZeroMem (&CardData->TaskFile, sizeof (TASK_FILE));\r
470 //\r
471 //The host only supports nIEN = 0\r
472 //\r
473 CardData->TaskFile.Command_Status = STANDBY_IMMEDIATE;\r
474\r
475\r
476 Status = SendATACommand (\r
477 CardData,\r
478 &CardData->TaskFile,\r
479 FALSE,\r
480 NULL,\r
481 0\r
482 );\r
483 return Status;\r
484}\r
485\r
486/**\r
487 READ_DMA_EXT command\r
488\r
489 @param CardData Pointer to CARD_DATA.\r
490 @param LBA The starting logical block address to read from on the device.\r
491 @param Buffer A pointer to the destination buffer for the data. The caller\r
492 is responsible for either having implicit or explicit ownership\r
493 of the buffer.\r
494 @param SectorCount Size in 512 bytes unit.\r
495\r
496 @retval EFI_SUCCESS Success\r
497 @retval EFI_DEVICE_ERROR Hardware Error\r
498 @retval EFI_INVALID_PARAMETER Parameter is error\r
499 @retval EFI_NO_MEDIA No media\r
500 @retval EFI_MEDIA_CHANGED Media Change\r
501 @retval EFI_BAD_BUFFER_SIZE Buffer size is bad\r
502\r
503**/\r
504EFI_STATUS\r
505ReadDMAExt (\r
506 IN CARD_DATA *CardData,\r
507 IN EFI_LBA LBA,\r
508 IN UINT8 *Buffer,\r
509 IN UINT16 SectorCount\r
510 )\r
511{\r
512\r
513 EFI_STATUS Status;\r
514\r
515 ZeroMem (&CardData->TaskFile, sizeof (TASK_FILE));\r
516 //\r
517 //The host only supports nIEN = 0\r
518 //\r
519 CardData->TaskFile.Command_Status = READ_DMA_EXT;\r
520\r
521 CardData->TaskFile.SectorCount = (UINT8)SectorCount;\r
522 CardData->TaskFile.SectorCount_Exp = (UINT8)(SectorCount >> 8);\r
523\r
524 CardData->TaskFile.LBALow = (UINT8)LBA;\r
525 CardData->TaskFile.LBAMid = (UINT8)RShiftU64(LBA, 8);\r
526 CardData->TaskFile.LBAHigh = (UINT8)RShiftU64(LBA, 16);\r
527\r
528 CardData->TaskFile.LBALow_Exp = (UINT8)RShiftU64(LBA, 24);\r
529 CardData->TaskFile.LBAMid_Exp = (UINT8)RShiftU64(LBA, 32);\r
530 CardData->TaskFile.LBAHigh_Exp = (UINT8)RShiftU64(LBA, 40);\r
531\r
532 Status = SendATACommand (\r
533 CardData,\r
534 &CardData->TaskFile,\r
535 FALSE,\r
536 Buffer,\r
537 SectorCount\r
538 );\r
539 return Status;\r
540\r
541}\r
542\r
543/**\r
544 WRITE_DMA_EXT command\r
545\r
546 @param CardData Pointer to CARD_DATA.\r
547 @param LBA The starting logical block address to read from on the device.\r
548 @param Buffer A pointer to the destination buffer for the data. The caller\r
549 is responsible for either having implicit or explicit ownership\r
550 of the buffer.\r
551 @param SectorCount Size in 512 bytes unit.\r
552\r
553 @retval EFI_SUCCESS Success\r
554 @retval EFI_DEVICE_ERROR Hardware Error\r
555 @retval EFI_INVALID_PARAMETER Parameter is error\r
556 @retval EFI_NO_MEDIA No media\r
557 @retval EFI_MEDIA_CHANGED Media Change\r
558 @retval EFI_BAD_BUFFER_SIZE Buffer size is bad\r
559\r
560**/\r
561EFI_STATUS\r
562WriteDMAExt (\r
563 IN CARD_DATA *CardData,\r
564 IN EFI_LBA LBA,\r
565 IN UINT8 *Buffer,\r
566 IN UINT16 SectorCount\r
567 )\r
568{\r
569\r
570 EFI_STATUS Status;\r
571\r
572 ZeroMem (&CardData->TaskFile, sizeof (TASK_FILE));\r
573 //\r
574 //The host only supports nIEN = 0\r
575 //\r
576 CardData->TaskFile.Command_Status = WRITE_DMA_EXT;\r
577\r
578 CardData->TaskFile.SectorCount = (UINT8)SectorCount;\r
579 CardData->TaskFile.SectorCount_Exp = (UINT8)(SectorCount >> 8);\r
580\r
581 CardData->TaskFile.LBALow = (UINT8)LBA;\r
582 CardData->TaskFile.LBAMid = (UINT8)RShiftU64(LBA, 8);\r
583 CardData->TaskFile.LBAHigh = (UINT8)RShiftU64(LBA, 16);\r
584\r
585 CardData->TaskFile.LBALow_Exp = (UINT8)RShiftU64(LBA, 24);\r
586 CardData->TaskFile.LBAMid_Exp = (UINT8)RShiftU64(LBA, 32);\r
587 CardData->TaskFile.LBAHigh_Exp = (UINT8)RShiftU64(LBA, 40);\r
588\r
589 Status = SendATACommand (\r
590 CardData,\r
591 &CardData->TaskFile,\r
592 TRUE,\r
593 Buffer,\r
594 SectorCount\r
595 );\r
596 return Status;\r
597\r
598}\r
599\r
600\r
601/**\r
602 Judge whether it is CE-ATA device or not.\r
603\r
604 @param CardData Pointer to CARD_DATA.\r
605\r
606 @retval TRUE\r
607 @retval FALSE\r
608\r
609**/\r
610BOOLEAN\r
611IsCEATADevice (\r
612 IN CARD_DATA *CardData\r
613 )\r
614{\r
615 EFI_STATUS Status;\r
616\r
617 Status = ReadWriteMultipleRegister (\r
618 CardData,\r
619 0,\r
620 sizeof (TASK_FILE),\r
621 FALSE,\r
622 (UINT8*)&CardData->TaskFile\r
623 );\r
624 if (EFI_ERROR (Status)) {\r
625 //\r
626 //To bring back the normal MMC card to work\r
627 //\r
628 CardData->SDHostIo->ResetSDHost (CardData->SDHostIo, Reset_DAT_CMD);\r
629 return FALSE;\r
630 }\r
631\r
632 if (CardData->TaskFile.LBAMid == CE_ATA_SIG_CE &&\r
633 CardData->TaskFile.LBAHigh == CE_ATA_SIG_AA\r
634 ) {\r
635 //\r
636 //Disable Auto CMD for CE-ATA\r
637 //\r
638 CardData->SDHostIo->EnableAutoStopCmd (CardData->SDHostIo, FALSE);\r
639\r
640 return TRUE;\r
641 }\r
642\r
643 return FALSE;\r
644}\r
645\r
646\r
647\r