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