1 /** @file
2
3 Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
4 This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php.
8
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12 **/
13
14 #include "EmmcBlockIoPei.h"
15
16 /**
17 Read/Write specified EMMC host controller mmio register.
18
19 @param[in] Address The address of the mmio register to be read/written.
20 @param[in] Read A boolean to indicate it's read or write operation.
21 @param[in] Count The width of the mmio register in bytes.
22 Must be 1, 2 , 4 or 8 bytes.
23 @param[in, out] Data For read operations, the destination buffer to store
24 the results. For write operations, the source buffer
25 to write data from. The caller is responsible for
26 having ownership of the data buffer and ensuring its
27 size not less than Count bytes.
28
29 @retval EFI_INVALID_PARAMETER The Address or the Data or the Count is not valid.
30 @retval EFI_SUCCESS The read/write operation succeeds.
31 @retval Others The read/write operation fails.
32
33 **/
34 EFI_STATUS
35 EFIAPI
EmmcPeimHcRwMmio(IN UINTN Address,IN BOOLEAN Read,IN UINT8 Count,IN OUT VOID * Data)36 EmmcPeimHcRwMmio (
37 IN UINTN Address,
38 IN BOOLEAN Read,
39 IN UINT8 Count,
40 IN OUT VOID *Data
41 )
42 {
43 if ((Address == 0) || (Data == NULL)) {
44 return EFI_INVALID_PARAMETER;
45 }
46
47 if ((Count != 1) && (Count != 2) && (Count != 4) && (Count != 8)) {
48 return EFI_INVALID_PARAMETER;
49 }
50
51 switch (Count) {
52 case 1:
53 if (Read) {
54 *(UINT8*)Data = MmioRead8 (Address);
55 } else {
56 MmioWrite8 (Address, *(UINT8*)Data);
57 }
58 break;
59 case 2:
60 if (Read) {
61 *(UINT16*)Data = MmioRead16 (Address);
62 } else {
63 MmioWrite16 (Address, *(UINT16*)Data);
64 }
65 break;
66 case 4:
67 if (Read) {
68 *(UINT32*)Data = MmioRead32 (Address);
69 } else {
70 MmioWrite32 (Address, *(UINT32*)Data);
71 }
72 break;
73 case 8:
74 if (Read) {
75 *(UINT64*)Data = MmioRead64 (Address);
76 } else {
77 MmioWrite64 (Address, *(UINT64*)Data);
78 }
79 break;
80 default:
81 ASSERT (FALSE);
82 return EFI_INVALID_PARAMETER;
83 }
84
85 return EFI_SUCCESS;
86 }
87
88 /**
89 Do OR operation with the value of the specified EMMC host controller mmio register.
90
91 @param[in] Address The address of the mmio register to be read/written.
92 @param[in] Count The width of the mmio register in bytes.
93 Must be 1, 2 , 4 or 8 bytes.
94 @param[in] OrData The pointer to the data used to do OR operation.
95 The caller is responsible for having ownership of
96 the data buffer and ensuring its size not less than
97 Count bytes.
98
99 @retval EFI_INVALID_PARAMETER The Address or the OrData or the Count is not valid.
100 @retval EFI_SUCCESS The OR operation succeeds.
101 @retval Others The OR operation fails.
102
103 **/
104 EFI_STATUS
105 EFIAPI
EmmcPeimHcOrMmio(IN UINTN Address,IN UINT8 Count,IN VOID * OrData)106 EmmcPeimHcOrMmio (
107 IN UINTN Address,
108 IN UINT8 Count,
109 IN VOID *OrData
110 )
111 {
112 EFI_STATUS Status;
113 UINT64 Data;
114 UINT64 Or;
115
116 Status = EmmcPeimHcRwMmio (Address, TRUE, Count, &Data);
117 if (EFI_ERROR (Status)) {
118 return Status;
119 }
120
121 if (Count == 1) {
122 Or = *(UINT8*) OrData;
123 } else if (Count == 2) {
124 Or = *(UINT16*) OrData;
125 } else if (Count == 4) {
126 Or = *(UINT32*) OrData;
127 } else if (Count == 8) {
128 Or = *(UINT64*) OrData;
129 } else {
130 return EFI_INVALID_PARAMETER;
131 }
132
133 Data |= Or;
134 Status = EmmcPeimHcRwMmio (Address, FALSE, Count, &Data);
135
136 return Status;
137 }
138
139 /**
140 Do AND operation with the value of the specified EMMC host controller mmio register.
141
142 @param[in] Address The address of the mmio register to be read/written.
143 @param[in] Count The width of the mmio register in bytes.
144 Must be 1, 2 , 4 or 8 bytes.
145 @param[in] AndData The pointer to the data used to do AND operation.
146 The caller is responsible for having ownership of
147 the data buffer and ensuring its size not less than
148 Count bytes.
149
150 @retval EFI_INVALID_PARAMETER The Address or the AndData or the Count is not valid.
151 @retval EFI_SUCCESS The AND operation succeeds.
152 @retval Others The AND operation fails.
153
154 **/
155 EFI_STATUS
156 EFIAPI
EmmcPeimHcAndMmio(IN UINTN Address,IN UINT8 Count,IN VOID * AndData)157 EmmcPeimHcAndMmio (
158 IN UINTN Address,
159 IN UINT8 Count,
160 IN VOID *AndData
161 )
162 {
163 EFI_STATUS Status;
164 UINT64 Data;
165 UINT64 And;
166
167 Status = EmmcPeimHcRwMmio (Address, TRUE, Count, &Data);
168 if (EFI_ERROR (Status)) {
169 return Status;
170 }
171
172 if (Count == 1) {
173 And = *(UINT8*) AndData;
174 } else if (Count == 2) {
175 And = *(UINT16*) AndData;
176 } else if (Count == 4) {
177 And = *(UINT32*) AndData;
178 } else if (Count == 8) {
179 And = *(UINT64*) AndData;
180 } else {
181 return EFI_INVALID_PARAMETER;
182 }
183
184 Data &= And;
185 Status = EmmcPeimHcRwMmio (Address, FALSE, Count, &Data);
186
187 return Status;
188 }
189
190 /**
191 Wait for the value of the specified MMIO register set to the test value.
192
193 @param[in] Address The address of the mmio register to be checked.
194 @param[in] Count The width of the mmio register in bytes.
195 Must be 1, 2, 4 or 8 bytes.
196 @param[in] MaskValue The mask value of memory.
197 @param[in] TestValue The test value of memory.
198
199 @retval EFI_NOT_READY The MMIO register hasn't set to the expected value.
200 @retval EFI_SUCCESS The MMIO register has expected value.
201 @retval Others The MMIO operation fails.
202
203 **/
204 EFI_STATUS
205 EFIAPI
EmmcPeimHcCheckMmioSet(IN UINTN Address,IN UINT8 Count,IN UINT64 MaskValue,IN UINT64 TestValue)206 EmmcPeimHcCheckMmioSet (
207 IN UINTN Address,
208 IN UINT8 Count,
209 IN UINT64 MaskValue,
210 IN UINT64 TestValue
211 )
212 {
213 EFI_STATUS Status;
214 UINT64 Value;
215
216 //
217 // Access PCI MMIO space to see if the value is the tested one.
218 //
219 Value = 0;
220 Status = EmmcPeimHcRwMmio (Address, TRUE, Count, &Value);
221 if (EFI_ERROR (Status)) {
222 return Status;
223 }
224
225 Value &= MaskValue;
226
227 if (Value == TestValue) {
228 return EFI_SUCCESS;
229 }
230
231 return EFI_NOT_READY;
232 }
233
234 /**
235 Wait for the value of the specified MMIO register set to the test value.
236
237 @param[in] Address The address of the mmio register to wait.
238 @param[in] Count The width of the mmio register in bytes.
239 Must be 1, 2, 4 or 8 bytes.
240 @param[in] MaskValue The mask value of memory.
241 @param[in] TestValue The test value of memory.
242 @param[in] Timeout The time out value for wait memory set, uses 1
243 microsecond as a unit.
244
245 @retval EFI_TIMEOUT The MMIO register hasn't expected value in timeout
246 range.
247 @retval EFI_SUCCESS The MMIO register has expected value.
248 @retval Others The MMIO operation fails.
249
250 **/
251 EFI_STATUS
252 EFIAPI
EmmcPeimHcWaitMmioSet(IN UINTN Address,IN UINT8 Count,IN UINT64 MaskValue,IN UINT64 TestValue,IN UINT64 Timeout)253 EmmcPeimHcWaitMmioSet (
254 IN UINTN Address,
255 IN UINT8 Count,
256 IN UINT64 MaskValue,
257 IN UINT64 TestValue,
258 IN UINT64 Timeout
259 )
260 {
261 EFI_STATUS Status;
262 BOOLEAN InfiniteWait;
263
264 if (Timeout == 0) {
265 InfiniteWait = TRUE;
266 } else {
267 InfiniteWait = FALSE;
268 }
269
270 while (InfiniteWait || (Timeout > 0)) {
271 Status = EmmcPeimHcCheckMmioSet (
272 Address,
273 Count,
274 MaskValue,
275 TestValue
276 );
277 if (Status != EFI_NOT_READY) {
278 return Status;
279 }
280
281 //
282 // Stall for 1 microsecond.
283 //
284 MicroSecondDelay (1);
285
286 Timeout--;
287 }
288
289 return EFI_TIMEOUT;
290 }
291
292 /**
293 Software reset the specified EMMC host controller and enable all interrupts.
294
295 @param[in] Bar The mmio base address of the slot to be accessed.
296
297 @retval EFI_SUCCESS The software reset executes successfully.
298 @retval Others The software reset fails.
299
300 **/
301 EFI_STATUS
EmmcPeimHcReset(IN UINTN Bar)302 EmmcPeimHcReset (
303 IN UINTN Bar
304 )
305 {
306 EFI_STATUS Status;
307 UINT8 SwReset;
308
309 SwReset = 0xFF;
310 Status = EmmcPeimHcRwMmio (Bar + EMMC_HC_SW_RST, FALSE, sizeof (SwReset), &SwReset);
311
312 if (EFI_ERROR (Status)) {
313 DEBUG ((EFI_D_ERROR, "EmmcPeimHcReset: write full 1 fails: %r\n", Status));
314 return Status;
315 }
316
317 Status = EmmcPeimHcWaitMmioSet (
318 Bar + EMMC_HC_SW_RST,
319 sizeof (SwReset),
320 0xFF,
321 0x00,
322 EMMC_TIMEOUT
323 );
324 if (EFI_ERROR (Status)) {
325 DEBUG ((EFI_D_INFO, "EmmcPeimHcReset: reset done with %r\n", Status));
326 return Status;
327 }
328 //
329 // Enable all interrupt after reset all.
330 //
331 Status = EmmcPeimHcEnableInterrupt (Bar);
332
333 return Status;
334 }
335
336 /**
337 Set all interrupt status bits in Normal and Error Interrupt Status Enable
338 register.
339
340 @param[in] Bar The mmio base address of the slot to be accessed.
341
342 @retval EFI_SUCCESS The operation executes successfully.
343 @retval Others The operation fails.
344
345 **/
346 EFI_STATUS
EmmcPeimHcEnableInterrupt(IN UINTN Bar)347 EmmcPeimHcEnableInterrupt (
348 IN UINTN Bar
349 )
350 {
351 EFI_STATUS Status;
352 UINT16 IntStatus;
353
354 //
355 // Enable all bits in Error Interrupt Status Enable Register
356 //
357 IntStatus = 0xFFFF;
358 Status = EmmcPeimHcRwMmio (Bar + EMMC_HC_ERR_INT_STS_EN, FALSE, sizeof (IntStatus), &IntStatus);
359 if (EFI_ERROR (Status)) {
360 return Status;
361 }
362 //
363 // Enable all bits in Normal Interrupt Status Enable Register
364 //
365 IntStatus = 0xFFFF;
366 Status = EmmcPeimHcRwMmio (Bar + EMMC_HC_NOR_INT_STS_EN, FALSE, sizeof (IntStatus), &IntStatus);
367
368 return Status;
369 }
370
371 /**
372 Get the capability data from the specified slot.
373
374 @param[in] Bar The mmio base address of the slot to be accessed.
375 @param[out] Capability The buffer to store the capability data.
376
377 @retval EFI_SUCCESS The operation executes successfully.
378 @retval Others The operation fails.
379
380 **/
381 EFI_STATUS
EmmcPeimHcGetCapability(IN UINTN Bar,OUT EMMC_HC_SLOT_CAP * Capability)382 EmmcPeimHcGetCapability (
383 IN UINTN Bar,
384 OUT EMMC_HC_SLOT_CAP *Capability
385 )
386 {
387 EFI_STATUS Status;
388 UINT64 Cap;
389
390 Status = EmmcPeimHcRwMmio (Bar + EMMC_HC_CAP, TRUE, sizeof (Cap), &Cap);
391 if (EFI_ERROR (Status)) {
392 return Status;
393 }
394
395 CopyMem (Capability, &Cap, sizeof (Cap));
396
397 return EFI_SUCCESS;
398 }
399
400 /**
401 Detect whether there is a EMMC card attached at the specified EMMC host controller
402 slot.
403
404 Refer to SD Host Controller Simplified spec 3.0 Section 3.1 for details.
405
406 @param[in] Bar The mmio base address of the slot to be accessed.
407
408 @retval EFI_SUCCESS There is a EMMC card attached.
409 @retval EFI_NO_MEDIA There is not a EMMC card attached.
410 @retval Others The detection fails.
411
412 **/
413 EFI_STATUS
EmmcPeimHcCardDetect(IN UINTN Bar)414 EmmcPeimHcCardDetect (
415 IN UINTN Bar
416 )
417 {
418 EFI_STATUS Status;
419 UINT16 Data;
420 UINT32 PresentState;
421
422 //
423 // Check Normal Interrupt Status Register
424 //
425 Status = EmmcPeimHcRwMmio (Bar + EMMC_HC_NOR_INT_STS, TRUE, sizeof (Data), &Data);
426 if (EFI_ERROR (Status)) {
427 return Status;
428 }
429
430 if ((Data & (BIT6 | BIT7)) != 0) {
431 //
432 // Clear BIT6 and BIT7 by writing 1 to these two bits if set.
433 //
434 Data &= BIT6 | BIT7;
435 Status = EmmcPeimHcRwMmio (Bar + EMMC_HC_NOR_INT_STS, FALSE, sizeof (Data), &Data);
436 if (EFI_ERROR (Status)) {
437 return Status;
438 }
439 }
440
441 //
442 // Check Present State Register to see if there is a card presented.
443 //
444 Status = EmmcPeimHcRwMmio (Bar + EMMC_HC_PRESENT_STATE, TRUE, sizeof (PresentState), &PresentState);
445 if (EFI_ERROR (Status)) {
446 return Status;
447 }
448
449 if ((PresentState & BIT16) != 0) {
450 return EFI_SUCCESS;
451 } else {
452 return EFI_NO_MEDIA;
453 }
454 }
455
456 /**
457 Stop EMMC card clock.
458
459 Refer to SD Host Controller Simplified spec 3.0 Section 3.2.2 for details.
460
461 @param[in] Bar The mmio base address of the slot to be accessed.
462
463 @retval EFI_SUCCESS Succeed to stop EMMC clock.
464 @retval Others Fail to stop EMMC clock.
465
466 **/
467 EFI_STATUS
EmmcPeimHcStopClock(IN UINTN Bar)468 EmmcPeimHcStopClock (
469 IN UINTN Bar
470 )
471 {
472 EFI_STATUS Status;
473 UINT32 PresentState;
474 UINT16 ClockCtrl;
475
476 //
477 // Ensure no SD transactions are occurring on the SD Bus by
478 // waiting for Command Inhibit (DAT) and Command Inhibit (CMD)
479 // in the Present State register to be 0.
480 //
481 Status = EmmcPeimHcWaitMmioSet (
482 Bar + EMMC_HC_PRESENT_STATE,
483 sizeof (PresentState),
484 BIT0 | BIT1,
485 0,
486 EMMC_TIMEOUT
487 );
488 if (EFI_ERROR (Status)) {
489 return Status;
490 }
491
492 //
493 // Set SD Clock Enable in the Clock Control register to 0
494 //
495 ClockCtrl = (UINT16)~BIT2;
496 Status = EmmcPeimHcAndMmio (Bar + EMMC_HC_CLOCK_CTRL, sizeof (ClockCtrl), &ClockCtrl);
497
498 return Status;
499 }
500
501 /**
502 EMMC card clock supply.
503
504 Refer to SD Host Controller Simplified spec 3.0 Section 3.2.1 for details.
505
506 @param[in] Bar The mmio base address of the slot to be accessed.
507 @param[in] ClockFreq The max clock frequency to be set. The unit is KHz.
508
509 @retval EFI_SUCCESS The clock is supplied successfully.
510 @retval Others The clock isn't supplied successfully.
511
512 **/
513 EFI_STATUS
EmmcPeimHcClockSupply(IN UINTN Bar,IN UINT64 ClockFreq)514 EmmcPeimHcClockSupply (
515 IN UINTN Bar,
516 IN UINT64 ClockFreq
517 )
518 {
519 EFI_STATUS Status;
520 EMMC_HC_SLOT_CAP Capability;
521 UINT32 BaseClkFreq;
522 UINT32 SettingFreq;
523 UINT32 Divisor;
524 UINT32 Remainder;
525 UINT16 ControllerVer;
526 UINT16 ClockCtrl;
527
528 //
529 // Calculate a divisor for SD clock frequency
530 //
531 Status = EmmcPeimHcGetCapability (Bar, &Capability);
532 if (EFI_ERROR (Status)) {
533 return Status;
534 }
535 ASSERT (Capability.BaseClkFreq != 0);
536
537 BaseClkFreq = Capability.BaseClkFreq;
538
539 if (ClockFreq == 0) {
540 return EFI_INVALID_PARAMETER;
541 }
542
543 if (ClockFreq > (BaseClkFreq * 1000)) {
544 ClockFreq = BaseClkFreq * 1000;
545 }
546
547 //
548 // Calculate the divisor of base frequency.
549 //
550 Divisor = 0;
551 SettingFreq = BaseClkFreq * 1000;
552 while (ClockFreq < SettingFreq) {
553 Divisor++;
554
555 SettingFreq = (BaseClkFreq * 1000) / (2 * Divisor);
556 Remainder = (BaseClkFreq * 1000) % (2 * Divisor);
557 if ((ClockFreq == SettingFreq) && (Remainder == 0)) {
558 break;
559 }
560 if ((ClockFreq == SettingFreq) && (Remainder != 0)) {
561 SettingFreq ++;
562 }
563 }
564
565 DEBUG ((EFI_D_INFO, "BaseClkFreq %dMHz Divisor %d ClockFreq %dKhz\n", BaseClkFreq, Divisor, ClockFreq));
566
567 Status = EmmcPeimHcRwMmio (Bar + EMMC_HC_CTRL_VER, TRUE, sizeof (ControllerVer), &ControllerVer);
568 if (EFI_ERROR (Status)) {
569 return Status;
570 }
571 //
572 // Set SDCLK Frequency Select and Internal Clock Enable fields in Clock Control register.
573 //
574 if ((ControllerVer & 0xFF) == 2) {
575 ASSERT (Divisor <= 0x3FF);
576 ClockCtrl = ((Divisor & 0xFF) << 8) | ((Divisor & 0x300) >> 2);
577 } else if (((ControllerVer & 0xFF) == 0) || ((ControllerVer & 0xFF) == 1)) {
578 //
579 // Only the most significant bit can be used as divisor.
580 //
581 if (((Divisor - 1) & Divisor) != 0) {
582 Divisor = 1 << (HighBitSet32 (Divisor) + 1);
583 }
584 ASSERT (Divisor <= 0x80);
585 ClockCtrl = (Divisor & 0xFF) << 8;
586 } else {
587 DEBUG ((EFI_D_ERROR, "Unknown SD Host Controller Spec version [0x%x]!!!\n", ControllerVer));
588 return EFI_UNSUPPORTED;
589 }
590
591 //
592 // Stop bus clock at first
593 //
594 Status = EmmcPeimHcStopClock (Bar);
595 if (EFI_ERROR (Status)) {
596 return Status;
597 }
598
599 //
600 // Supply clock frequency with specified divisor
601 //
602 ClockCtrl |= BIT0;
603 Status = EmmcPeimHcRwMmio (Bar + EMMC_HC_CLOCK_CTRL, FALSE, sizeof (ClockCtrl), &ClockCtrl);
604 if (EFI_ERROR (Status)) {
605 DEBUG ((EFI_D_ERROR, "Set SDCLK Frequency Select and Internal Clock Enable fields fails\n"));
606 return Status;
607 }
608
609 //
610 // Wait Internal Clock Stable in the Clock Control register to be 1
611 //
612 Status = EmmcPeimHcWaitMmioSet (
613 Bar + EMMC_HC_CLOCK_CTRL,
614 sizeof (ClockCtrl),
615 BIT1,
616 BIT1,
617 EMMC_TIMEOUT
618 );
619 if (EFI_ERROR (Status)) {
620 return Status;
621 }
622
623 //
624 // Set SD Clock Enable in the Clock Control register to 1
625 //
626 ClockCtrl = BIT2;
627 Status = EmmcPeimHcOrMmio (Bar + EMMC_HC_CLOCK_CTRL, sizeof (ClockCtrl), &ClockCtrl);
628
629 return Status;
630 }
631
632 /**
633 EMMC bus power control.
634
635 Refer to SD Host Controller Simplified spec 3.0 Section 3.3 for details.
636
637 @param[in] Bar The mmio base address of the slot to be accessed.
638 @param[in] PowerCtrl The value setting to the power control register.
639
640 @retval TRUE There is a EMMC card attached.
641 @retval FALSE There is no a EMMC card attached.
642
643 **/
644 EFI_STATUS
EmmcPeimHcPowerControl(IN UINTN Bar,IN UINT8 PowerCtrl)645 EmmcPeimHcPowerControl (
646 IN UINTN Bar,
647 IN UINT8 PowerCtrl
648 )
649 {
650 EFI_STATUS Status;
651
652 //
653 // Clr SD Bus Power
654 //
655 PowerCtrl &= (UINT8)~BIT0;
656 Status = EmmcPeimHcRwMmio (Bar + EMMC_HC_POWER_CTRL, FALSE, sizeof (PowerCtrl), &PowerCtrl);
657 if (EFI_ERROR (Status)) {
658 return Status;
659 }
660
661 //
662 // Set SD Bus Voltage Select and SD Bus Power fields in Power Control Register
663 //
664 PowerCtrl |= BIT0;
665 Status = EmmcPeimHcRwMmio (Bar + EMMC_HC_POWER_CTRL, FALSE, sizeof (PowerCtrl), &PowerCtrl);
666
667 return Status;
668 }
669
670 /**
671 Set the EMMC bus width.
672
673 Refer to SD Host Controller Simplified spec 3.0 Section 3.4 for details.
674
675 @param[in] Bar The mmio base address of the slot to be accessed.
676 @param[in] BusWidth The bus width used by the EMMC device, it must be 1, 4 or 8.
677
678 @retval EFI_SUCCESS The bus width is set successfully.
679 @retval Others The bus width isn't set successfully.
680
681 **/
682 EFI_STATUS
EmmcPeimHcSetBusWidth(IN UINTN Bar,IN UINT16 BusWidth)683 EmmcPeimHcSetBusWidth (
684 IN UINTN Bar,
685 IN UINT16 BusWidth
686 )
687 {
688 EFI_STATUS Status;
689 UINT8 HostCtrl1;
690
691 if (BusWidth == 1) {
692 HostCtrl1 = (UINT8)~(BIT5 | BIT1);
693 Status = EmmcPeimHcAndMmio (Bar + EMMC_HC_HOST_CTRL1, sizeof (HostCtrl1), &HostCtrl1);
694 } else if (BusWidth == 4) {
695 Status = EmmcPeimHcRwMmio (Bar + EMMC_HC_HOST_CTRL1, TRUE, sizeof (HostCtrl1), &HostCtrl1);
696 if (EFI_ERROR (Status)) {
697 return Status;
698 }
699 HostCtrl1 |= BIT1;
700 HostCtrl1 &= (UINT8)~BIT5;
701 Status = EmmcPeimHcRwMmio (Bar + EMMC_HC_HOST_CTRL1, FALSE, sizeof (HostCtrl1), &HostCtrl1);
702 } else if (BusWidth == 8) {
703 Status = EmmcPeimHcRwMmio (Bar + EMMC_HC_HOST_CTRL1, TRUE, sizeof (HostCtrl1), &HostCtrl1);
704 if (EFI_ERROR (Status)) {
705 return Status;
706 }
707 HostCtrl1 &= (UINT8)~BIT1;
708 HostCtrl1 |= BIT5;
709 Status = EmmcPeimHcRwMmio (Bar + EMMC_HC_HOST_CTRL1, FALSE, sizeof (HostCtrl1), &HostCtrl1);
710 } else {
711 ASSERT (FALSE);
712 return EFI_INVALID_PARAMETER;
713 }
714
715 return Status;
716 }
717
718 /**
719 Supply EMMC card with lowest clock frequency at initialization.
720
721 @param[in] Bar The mmio base address of the slot to be accessed.
722
723 @retval EFI_SUCCESS The clock is supplied successfully.
724 @retval Others The clock isn't supplied successfully.
725
726 **/
727 EFI_STATUS
EmmcPeimHcInitClockFreq(IN UINTN Bar)728 EmmcPeimHcInitClockFreq (
729 IN UINTN Bar
730 )
731 {
732 EFI_STATUS Status;
733 EMMC_HC_SLOT_CAP Capability;
734 UINT32 InitFreq;
735
736 //
737 // Calculate a divisor for SD clock frequency
738 //
739 Status = EmmcPeimHcGetCapability (Bar, &Capability);
740 if (EFI_ERROR (Status)) {
741 return Status;
742 }
743
744 if (Capability.BaseClkFreq == 0) {
745 //
746 // Don't support get Base Clock Frequency information via another method
747 //
748 return EFI_UNSUPPORTED;
749 }
750 //
751 // Supply 400KHz clock frequency at initialization phase.
752 //
753 InitFreq = 400;
754 Status = EmmcPeimHcClockSupply (Bar, InitFreq);
755 return Status;
756 }
757
758 /**
759 Supply EMMC card with maximum voltage at initialization.
760
761 Refer to SD Host Controller Simplified spec 3.0 Section 3.3 for details.
762
763 @param[in] Bar The mmio base address of the slot to be accessed.
764
765 @retval EFI_SUCCESS The voltage is supplied successfully.
766 @retval Others The voltage isn't supplied successfully.
767
768 **/
769 EFI_STATUS
EmmcPeimHcInitPowerVoltage(IN UINTN Bar)770 EmmcPeimHcInitPowerVoltage (
771 IN UINTN Bar
772 )
773 {
774 EFI_STATUS Status;
775 EMMC_HC_SLOT_CAP Capability;
776 UINT8 MaxVoltage;
777 UINT8 HostCtrl2;
778
779 //
780 // Get the support voltage of the Host Controller
781 //
782 Status = EmmcPeimHcGetCapability (Bar, &Capability);
783 if (EFI_ERROR (Status)) {
784 return Status;
785 }
786 //
787 // Calculate supported maximum voltage according to SD Bus Voltage Select
788 //
789 if (Capability.Voltage33 != 0) {
790 //
791 // Support 3.3V
792 //
793 MaxVoltage = 0x0E;
794 } else if (Capability.Voltage30 != 0) {
795 //
796 // Support 3.0V
797 //
798 MaxVoltage = 0x0C;
799 } else if (Capability.Voltage18 != 0) {
800 //
801 // Support 1.8V
802 //
803 MaxVoltage = 0x0A;
804 HostCtrl2 = BIT3;
805 Status = EmmcPeimHcOrMmio (Bar + EMMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);
806 if (EFI_ERROR (Status)) {
807 return Status;
808 }
809 MicroSecondDelay (5000);
810 } else {
811 ASSERT (FALSE);
812 return EFI_DEVICE_ERROR;
813 }
814
815 //
816 // Set SD Bus Voltage Select and SD Bus Power fields in Power Control Register
817 //
818 Status = EmmcPeimHcPowerControl (Bar, MaxVoltage);
819
820 return Status;
821 }
822
823 /**
824 Initialize the Timeout Control register with most conservative value at initialization.
825
826 Refer to SD Host Controller Simplified spec 3.0 Section 2.2.15 for details.
827
828 @param[in] Bar The mmio base address of the slot to be accessed.
829
830 @retval EFI_SUCCESS The timeout control register is configured successfully.
831 @retval Others The timeout control register isn't configured successfully.
832
833 **/
834 EFI_STATUS
EmmcPeimHcInitTimeoutCtrl(IN UINTN Bar)835 EmmcPeimHcInitTimeoutCtrl (
836 IN UINTN Bar
837 )
838 {
839 EFI_STATUS Status;
840 UINT8 Timeout;
841
842 Timeout = 0x0E;
843 Status = EmmcPeimHcRwMmio (Bar + EMMC_HC_TIMEOUT_CTRL, FALSE, sizeof (Timeout), &Timeout);
844
845 return Status;
846 }
847
848 /**
849 Initial EMMC host controller with lowest clock frequency, max power and max timeout value
850 at initialization.
851
852 @param[in] Bar The mmio base address of the slot to be accessed.
853
854 @retval EFI_SUCCESS The host controller is initialized successfully.
855 @retval Others The host controller isn't initialized successfully.
856
857 **/
858 EFI_STATUS
EmmcPeimHcInitHost(IN UINTN Bar)859 EmmcPeimHcInitHost (
860 IN UINTN Bar
861 )
862 {
863 EFI_STATUS Status;
864
865 Status = EmmcPeimHcInitClockFreq (Bar);
866 if (EFI_ERROR (Status)) {
867 return Status;
868 }
869
870 Status = EmmcPeimHcInitPowerVoltage (Bar);
871 if (EFI_ERROR (Status)) {
872 return Status;
873 }
874
875 Status = EmmcPeimHcInitTimeoutCtrl (Bar);
876 return Status;
877 }
878
879 /**
880 Turn on/off LED.
881
882 @param[in] Bar The mmio base address of the slot to be accessed.
883 @param[in] On The boolean to turn on/off LED.
884
885 @retval EFI_SUCCESS The LED is turned on/off successfully.
886 @retval Others The LED isn't turned on/off successfully.
887
888 **/
889 EFI_STATUS
EmmcPeimHcLedOnOff(IN UINTN Bar,IN BOOLEAN On)890 EmmcPeimHcLedOnOff (
891 IN UINTN Bar,
892 IN BOOLEAN On
893 )
894 {
895 EFI_STATUS Status;
896 UINT8 HostCtrl1;
897
898 if (On) {
899 HostCtrl1 = BIT0;
900 Status = EmmcPeimHcOrMmio (Bar + EMMC_HC_HOST_CTRL1, sizeof (HostCtrl1), &HostCtrl1);
901 } else {
902 HostCtrl1 = (UINT8)~BIT0;
903 Status = EmmcPeimHcAndMmio (Bar + EMMC_HC_HOST_CTRL1, sizeof (HostCtrl1), &HostCtrl1);
904 }
905
906 return Status;
907 }
908
909 /**
910 Build ADMA descriptor table for transfer.
911
912 Refer to SD Host Controller Simplified spec 3.0 Section 1.13 for details.
913
914 @param[in] Trb The pointer to the EMMC_TRB instance.
915
916 @retval EFI_SUCCESS The ADMA descriptor table is created successfully.
917 @retval Others The ADMA descriptor table isn't created successfully.
918
919 **/
920 EFI_STATUS
BuildAdmaDescTable(IN EMMC_TRB * Trb)921 BuildAdmaDescTable (
922 IN EMMC_TRB *Trb
923 )
924 {
925 EFI_PHYSICAL_ADDRESS Data;
926 UINT64 DataLen;
927 UINT64 Entries;
928 UINT32 Index;
929 UINT64 Remaining;
930 UINT32 Address;
931
932 Data = (EFI_PHYSICAL_ADDRESS)(UINTN)Trb->Data;
933 DataLen = Trb->DataLen;
934 //
935 // Only support 32bit ADMA Descriptor Table
936 //
937 if ((Data >= 0x100000000ul) || ((Data + DataLen) > 0x100000000ul)) {
938 return EFI_INVALID_PARAMETER;
939 }
940 //
941 // Address field shall be set on 32-bit boundary (Lower 2-bit is always set to 0)
942 // for 32-bit address descriptor table.
943 //
944 if ((Data & (BIT0 | BIT1)) != 0) {
945 DEBUG ((EFI_D_INFO, "The buffer [0x%x] to construct ADMA desc is not aligned to 4 bytes boundary!\n", Data));
946 }
947
948 Entries = DivU64x32 ((DataLen + ADMA_MAX_DATA_PER_LINE - 1), ADMA_MAX_DATA_PER_LINE);
949
950 Trb->AdmaDescSize = (UINTN)MultU64x32 (Entries, sizeof (EMMC_HC_ADMA_DESC_LINE));
951 Trb->AdmaDesc = EmmcPeimAllocateMem (Trb->Slot->Private->Pool, Trb->AdmaDescSize);
952 if (Trb->AdmaDesc == NULL) {
953 return EFI_OUT_OF_RESOURCES;
954 }
955
956 Remaining = DataLen;
957 Address = (UINT32)Data;
958 for (Index = 0; Index < Entries; Index++) {
959 if (Remaining <= ADMA_MAX_DATA_PER_LINE) {
960 Trb->AdmaDesc[Index].Valid = 1;
961 Trb->AdmaDesc[Index].Act = 2;
962 Trb->AdmaDesc[Index].Length = (UINT16)Remaining;
963 Trb->AdmaDesc[Index].Address = Address;
964 break;
965 } else {
966 Trb->AdmaDesc[Index].Valid = 1;
967 Trb->AdmaDesc[Index].Act = 2;
968 Trb->AdmaDesc[Index].Length = 0;
969 Trb->AdmaDesc[Index].Address = Address;
970 }
971
972 Remaining -= ADMA_MAX_DATA_PER_LINE;
973 Address += ADMA_MAX_DATA_PER_LINE;
974 }
975
976 //
977 // Set the last descriptor line as end of descriptor table
978 //
979 Trb->AdmaDesc[Index].End = 1;
980 return EFI_SUCCESS;
981 }
982
983 /**
984 Create a new TRB for the EMMC cmd request.
985
986 @param[in] Slot The slot number of the EMMC card to send the command to.
987 @param[in] Packet A pointer to the SD command data structure.
988
989 @return Created Trb or NULL.
990
991 **/
992 EMMC_TRB *
EmmcPeimCreateTrb(IN EMMC_PEIM_HC_SLOT * Slot,IN EMMC_COMMAND_PACKET * Packet)993 EmmcPeimCreateTrb (
994 IN EMMC_PEIM_HC_SLOT *Slot,
995 IN EMMC_COMMAND_PACKET *Packet
996 )
997 {
998 EMMC_TRB *Trb;
999 EFI_STATUS Status;
1000 EMMC_HC_SLOT_CAP Capability;
1001
1002 //
1003 // Calculate a divisor for SD clock frequency
1004 //
1005 Status = EmmcPeimHcGetCapability (Slot->EmmcHcBase, &Capability);
1006 if (EFI_ERROR (Status)) {
1007 return NULL;
1008 }
1009
1010 Trb = EmmcPeimAllocateMem (Slot->Private->Pool, sizeof (EMMC_TRB));
1011 if (Trb == NULL) {
1012 return NULL;
1013 }
1014
1015 Trb->Slot = Slot;
1016 Trb->BlockSize = 0x200;
1017 Trb->Packet = Packet;
1018 Trb->Timeout = Packet->Timeout;
1019
1020 if ((Packet->InTransferLength != 0) && (Packet->InDataBuffer != NULL)) {
1021 Trb->Data = Packet->InDataBuffer;
1022 Trb->DataLen = Packet->InTransferLength;
1023 Trb->Read = TRUE;
1024 } else if ((Packet->OutTransferLength != 0) && (Packet->OutDataBuffer != NULL)) {
1025 Trb->Data = Packet->OutDataBuffer;
1026 Trb->DataLen = Packet->OutTransferLength;
1027 Trb->Read = FALSE;
1028 } else if ((Packet->InTransferLength == 0) && (Packet->OutTransferLength == 0)) {
1029 Trb->Data = NULL;
1030 Trb->DataLen = 0;
1031 } else {
1032 goto Error;
1033 }
1034
1035 if (Trb->DataLen < Trb->BlockSize) {
1036 Trb->BlockSize = (UINT16)Trb->DataLen;
1037 }
1038
1039 if (Packet->EmmcCmdBlk->CommandIndex == EMMC_SEND_TUNING_BLOCK) {
1040 Trb->Mode = EmmcPioMode;
1041 } else {
1042 if (Trb->DataLen == 0) {
1043 Trb->Mode = EmmcNoData;
1044 } else if (Capability.Adma2 != 0) {
1045 Trb->Mode = EmmcAdmaMode;
1046 Status = BuildAdmaDescTable (Trb);
1047 if (EFI_ERROR (Status)) {
1048 goto Error;
1049 }
1050 } else if (Capability.Sdma != 0) {
1051 Trb->Mode = EmmcSdmaMode;
1052 } else {
1053 Trb->Mode = EmmcPioMode;
1054 }
1055 }
1056 return Trb;
1057
1058 Error:
1059 EmmcPeimFreeTrb (Trb);
1060 return NULL;
1061 }
1062
1063 /**
1064 Free the resource used by the TRB.
1065
1066 @param[in] Trb The pointer to the EMMC_TRB instance.
1067
1068 **/
1069 VOID
EmmcPeimFreeTrb(IN EMMC_TRB * Trb)1070 EmmcPeimFreeTrb (
1071 IN EMMC_TRB *Trb
1072 )
1073 {
1074 if ((Trb != NULL) && (Trb->AdmaDesc != NULL)) {
1075 EmmcPeimFreeMem (Trb->Slot->Private->Pool, Trb->AdmaDesc, Trb->AdmaDescSize);
1076 }
1077
1078 if (Trb != NULL) {
1079 EmmcPeimFreeMem (Trb->Slot->Private->Pool, Trb, sizeof (EMMC_TRB));
1080 }
1081 return;
1082 }
1083
1084 /**
1085 Check if the env is ready for execute specified TRB.
1086
1087 @param[in] Bar The mmio base address of the slot to be accessed.
1088 @param[in] Trb The pointer to the EMMC_TRB instance.
1089
1090 @retval EFI_SUCCESS The env is ready for TRB execution.
1091 @retval EFI_NOT_READY The env is not ready for TRB execution.
1092 @retval Others Some erros happen.
1093
1094 **/
1095 EFI_STATUS
EmmcPeimCheckTrbEnv(IN UINTN Bar,IN EMMC_TRB * Trb)1096 EmmcPeimCheckTrbEnv (
1097 IN UINTN Bar,
1098 IN EMMC_TRB *Trb
1099 )
1100 {
1101 EFI_STATUS Status;
1102 EMMC_COMMAND_PACKET *Packet;
1103 UINT32 PresentState;
1104
1105 Packet = Trb->Packet;
1106
1107 if ((Packet->EmmcCmdBlk->CommandType == EmmcCommandTypeAdtc) ||
1108 (Packet->EmmcCmdBlk->ResponseType == EmmcResponceTypeR1b) ||
1109 (Packet->EmmcCmdBlk->ResponseType == EmmcResponceTypeR5b)) {
1110 //
1111 // Wait Command Inhibit (CMD) and Command Inhibit (DAT) in
1112 // the Present State register to be 0
1113 //
1114 PresentState = BIT0 | BIT1;
1115 } else {
1116 //
1117 // Wait Command Inhibit (CMD) in the Present State register
1118 // to be 0
1119 //
1120 PresentState = BIT0;
1121 }
1122
1123 Status = EmmcPeimHcCheckMmioSet (
1124 Bar + EMMC_HC_PRESENT_STATE,
1125 sizeof (PresentState),
1126 PresentState,
1127 0
1128 );
1129
1130 return Status;
1131 }
1132
1133 /**
1134 Wait for the env to be ready for execute specified TRB.
1135
1136 @param[in] Bar The mmio base address of the slot to be accessed.
1137 @param[in] Trb The pointer to the EMMC_TRB instance.
1138
1139 @retval EFI_SUCCESS The env is ready for TRB execution.
1140 @retval EFI_TIMEOUT The env is not ready for TRB execution in time.
1141 @retval Others Some erros happen.
1142
1143 **/
1144 EFI_STATUS
EmmcPeimWaitTrbEnv(IN UINTN Bar,IN EMMC_TRB * Trb)1145 EmmcPeimWaitTrbEnv (
1146 IN UINTN Bar,
1147 IN EMMC_TRB *Trb
1148 )
1149 {
1150 EFI_STATUS Status;
1151 EMMC_COMMAND_PACKET *Packet;
1152 UINT64 Timeout;
1153 BOOLEAN InfiniteWait;
1154
1155 //
1156 // Wait Command Complete Interrupt Status bit in Normal Interrupt Status Register
1157 //
1158 Packet = Trb->Packet;
1159 Timeout = Packet->Timeout;
1160 if (Timeout == 0) {
1161 InfiniteWait = TRUE;
1162 } else {
1163 InfiniteWait = FALSE;
1164 }
1165
1166 while (InfiniteWait || (Timeout > 0)) {
1167 //
1168 // Check Trb execution result by reading Normal Interrupt Status register.
1169 //
1170 Status = EmmcPeimCheckTrbEnv (Bar, Trb);
1171 if (Status != EFI_NOT_READY) {
1172 return Status;
1173 }
1174 //
1175 // Stall for 1 microsecond.
1176 //
1177 MicroSecondDelay (1);
1178
1179 Timeout--;
1180 }
1181
1182 return EFI_TIMEOUT;
1183 }
1184
1185 /**
1186 Execute the specified TRB.
1187
1188 @param[in] Bar The mmio base address of the slot to be accessed.
1189 @param[in] Trb The pointer to the EMMC_TRB instance.
1190
1191 @retval EFI_SUCCESS The TRB is sent to host controller successfully.
1192 @retval Others Some erros happen when sending this request to the host controller.
1193
1194 **/
1195 EFI_STATUS
EmmcPeimExecTrb(IN UINTN Bar,IN EMMC_TRB * Trb)1196 EmmcPeimExecTrb (
1197 IN UINTN Bar,
1198 IN EMMC_TRB *Trb
1199 )
1200 {
1201 EFI_STATUS Status;
1202 EMMC_COMMAND_PACKET *Packet;
1203 UINT16 Cmd;
1204 UINT16 IntStatus;
1205 UINT32 Argument;
1206 UINT16 BlkCount;
1207 UINT16 BlkSize;
1208 UINT16 TransMode;
1209 UINT8 HostCtrl1;
1210 UINT32 SdmaAddr;
1211 UINT64 AdmaAddr;
1212
1213 Packet = Trb->Packet;
1214 //
1215 // Clear all bits in Error Interrupt Status Register
1216 //
1217 IntStatus = 0xFFFF;
1218 Status = EmmcPeimHcRwMmio (Bar + EMMC_HC_ERR_INT_STS, FALSE, sizeof (IntStatus), &IntStatus);
1219 if (EFI_ERROR (Status)) {
1220 return Status;
1221 }
1222 //
1223 // Clear all bits in Normal Interrupt Status Register
1224 //
1225 IntStatus = 0xFFFF;
1226 Status = EmmcPeimHcRwMmio (Bar + EMMC_HC_NOR_INT_STS, FALSE, sizeof (IntStatus), &IntStatus);
1227 if (EFI_ERROR (Status)) {
1228 return Status;
1229 }
1230 //
1231 // Set Host Control 1 register DMA Select field
1232 //
1233 if (Trb->Mode == EmmcAdmaMode) {
1234 HostCtrl1 = BIT4;
1235 Status = EmmcPeimHcOrMmio (Bar + EMMC_HC_HOST_CTRL1, sizeof (HostCtrl1), &HostCtrl1);
1236 if (EFI_ERROR (Status)) {
1237 return Status;
1238 }
1239 }
1240
1241 EmmcPeimHcLedOnOff (Bar, TRUE);
1242
1243 if (Trb->Mode == EmmcSdmaMode) {
1244 if ((UINT64)(UINTN)Trb->Data >= 0x100000000ul) {
1245 return EFI_INVALID_PARAMETER;
1246 }
1247
1248 SdmaAddr = (UINT32)(UINTN)Trb->Data;
1249 Status = EmmcPeimHcRwMmio (Bar + EMMC_HC_SDMA_ADDR, FALSE, sizeof (SdmaAddr), &SdmaAddr);
1250 if (EFI_ERROR (Status)) {
1251 return Status;
1252 }
1253 } else if (Trb->Mode == EmmcAdmaMode) {
1254 AdmaAddr = (UINT64)(UINTN)Trb->AdmaDesc;
1255 Status = EmmcPeimHcRwMmio (Bar + EMMC_HC_ADMA_SYS_ADDR, FALSE, sizeof (AdmaAddr), &AdmaAddr);
1256 if (EFI_ERROR (Status)) {
1257 return Status;
1258 }
1259 }
1260
1261 BlkSize = Trb->BlockSize;
1262 if (Trb->Mode == EmmcSdmaMode) {
1263 //
1264 // Set SDMA boundary to be 512K bytes.
1265 //
1266 BlkSize |= 0x7000;
1267 }
1268
1269 Status = EmmcPeimHcRwMmio (Bar + EMMC_HC_BLK_SIZE, FALSE, sizeof (BlkSize), &BlkSize);
1270 if (EFI_ERROR (Status)) {
1271 return Status;
1272 }
1273
1274 BlkCount = 0;
1275 if (Trb->Mode != EmmcNoData) {
1276 //
1277 // Calcuate Block Count.
1278 //
1279 BlkCount = (UINT16)(Trb->DataLen / Trb->BlockSize);
1280 }
1281
1282 Status = EmmcPeimHcRwMmio (Bar + EMMC_HC_BLK_COUNT, FALSE, sizeof (BlkCount), &BlkCount);
1283 if (EFI_ERROR (Status)) {
1284 return Status;
1285 }
1286
1287 Argument = Packet->EmmcCmdBlk->CommandArgument;
1288 Status = EmmcPeimHcRwMmio (Bar + EMMC_HC_ARG1, FALSE, sizeof (Argument), &Argument);
1289 if (EFI_ERROR (Status)) {
1290 return Status;
1291 }
1292
1293 TransMode = 0;
1294 if (Trb->Mode != EmmcNoData) {
1295 if (Trb->Mode != EmmcPioMode) {
1296 TransMode |= BIT0;
1297 }
1298 if (Trb->Read) {
1299 TransMode |= BIT4;
1300 }
1301 if (BlkCount > 1) {
1302 TransMode |= BIT5 | BIT1;
1303 }
1304 }
1305
1306 Status = EmmcPeimHcRwMmio (Bar + EMMC_HC_TRANS_MOD, FALSE, sizeof (TransMode), &TransMode);
1307 if (EFI_ERROR (Status)) {
1308 return Status;
1309 }
1310
1311 Cmd = (UINT16)LShiftU64(Packet->EmmcCmdBlk->CommandIndex, 8);
1312 if (Packet->EmmcCmdBlk->CommandType == EmmcCommandTypeAdtc) {
1313 Cmd |= BIT5;
1314 }
1315 //
1316 // Convert ResponseType to value
1317 //
1318 if (Packet->EmmcCmdBlk->CommandType != EmmcCommandTypeBc) {
1319 switch (Packet->EmmcCmdBlk->ResponseType) {
1320 case EmmcResponceTypeR1:
1321 case EmmcResponceTypeR5:
1322 case EmmcResponceTypeR6:
1323 case EmmcResponceTypeR7:
1324 Cmd |= (BIT1 | BIT3 | BIT4);
1325 break;
1326 case EmmcResponceTypeR2:
1327 Cmd |= (BIT0 | BIT3);
1328 break;
1329 case EmmcResponceTypeR3:
1330 case EmmcResponceTypeR4:
1331 Cmd |= BIT1;
1332 break;
1333 case EmmcResponceTypeR1b:
1334 case EmmcResponceTypeR5b:
1335 Cmd |= (BIT0 | BIT1 | BIT3 | BIT4);
1336 break;
1337 default:
1338 ASSERT (FALSE);
1339 break;
1340 }
1341 }
1342 //
1343 // Execute cmd
1344 //
1345 Status = EmmcPeimHcRwMmio (Bar + EMMC_HC_COMMAND, FALSE, sizeof (Cmd), &Cmd);
1346 return Status;
1347 }
1348
1349 /**
1350 Check the TRB execution result.
1351
1352 @param[in] Bar The mmio base address of the slot to be accessed.
1353 @param[in] Trb The pointer to the EMMC_TRB instance.
1354
1355 @retval EFI_SUCCESS The TRB is executed successfully.
1356 @retval EFI_NOT_READY The TRB is not completed for execution.
1357 @retval Others Some erros happen when executing this request.
1358
1359 **/
1360 EFI_STATUS
EmmcPeimCheckTrbResult(IN UINTN Bar,IN EMMC_TRB * Trb)1361 EmmcPeimCheckTrbResult (
1362 IN UINTN Bar,
1363 IN EMMC_TRB *Trb
1364 )
1365 {
1366 EFI_STATUS Status;
1367 EMMC_COMMAND_PACKET *Packet;
1368 UINT16 IntStatus;
1369 UINT32 Response[4];
1370 UINT32 SdmaAddr;
1371 UINT8 Index;
1372 UINT8 SwReset;
1373 UINT32 PioLength;
1374
1375 SwReset = 0;
1376 Packet = Trb->Packet;
1377 //
1378 // Check Trb execution result by reading Normal Interrupt Status register.
1379 //
1380 Status = EmmcPeimHcRwMmio (
1381 Bar + EMMC_HC_NOR_INT_STS,
1382 TRUE,
1383 sizeof (IntStatus),
1384 &IntStatus
1385 );
1386 if (EFI_ERROR (Status)) {
1387 goto Done;
1388 }
1389 //
1390 // Check Transfer Complete bit is set or not.
1391 //
1392 if ((IntStatus & BIT1) == BIT1) {
1393 if ((IntStatus & BIT15) == BIT15) {
1394 //
1395 // Read Error Interrupt Status register to check if the error is
1396 // Data Timeout Error.
1397 // If yes, treat it as success as Transfer Complete has higher
1398 // priority than Data Timeout Error.
1399 //
1400 Status = EmmcPeimHcRwMmio (
1401 Bar + EMMC_HC_ERR_INT_STS,
1402 TRUE,
1403 sizeof (IntStatus),
1404 &IntStatus
1405 );
1406 if (!EFI_ERROR (Status)) {
1407 if ((IntStatus & BIT4) == BIT4) {
1408 Status = EFI_SUCCESS;
1409 } else {
1410 Status = EFI_DEVICE_ERROR;
1411 }
1412 }
1413 }
1414
1415 goto Done;
1416 }
1417 //
1418 // Check if there is a error happened during cmd execution.
1419 // If yes, then do error recovery procedure to follow SD Host Controller
1420 // Simplified Spec 3.0 section 3.10.1.
1421 //
1422 if ((IntStatus & BIT15) == BIT15) {
1423 Status = EmmcPeimHcRwMmio (
1424 Bar + EMMC_HC_ERR_INT_STS,
1425 TRUE,
1426 sizeof (IntStatus),
1427 &IntStatus
1428 );
1429 if (EFI_ERROR (Status)) {
1430 goto Done;
1431 }
1432
1433 if ((IntStatus & 0x0F) != 0) {
1434 SwReset |= BIT1;
1435 }
1436 if ((IntStatus & 0xF0) != 0) {
1437 SwReset |= BIT2;
1438 }
1439
1440 Status = EmmcPeimHcRwMmio (
1441 Bar + EMMC_HC_SW_RST,
1442 FALSE,
1443 sizeof (SwReset),
1444 &SwReset
1445 );
1446 if (EFI_ERROR (Status)) {
1447 goto Done;
1448 }
1449 Status = EmmcPeimHcWaitMmioSet (
1450 Bar + EMMC_HC_SW_RST,
1451 sizeof (SwReset),
1452 0xFF,
1453 0,
1454 EMMC_TIMEOUT
1455 );
1456 if (EFI_ERROR (Status)) {
1457 goto Done;
1458 }
1459
1460 Status = EFI_DEVICE_ERROR;
1461 goto Done;
1462 }
1463 //
1464 // Check if DMA interrupt is signalled for the SDMA transfer.
1465 //
1466 if ((Trb->Mode == EmmcSdmaMode) && ((IntStatus & BIT3) == BIT3)) {
1467 //
1468 // Clear DMA interrupt bit.
1469 //
1470 IntStatus = BIT3;
1471 Status = EmmcPeimHcRwMmio (
1472 Bar + EMMC_HC_NOR_INT_STS,
1473 FALSE,
1474 sizeof (IntStatus),
1475 &IntStatus
1476 );
1477 if (EFI_ERROR (Status)) {
1478 goto Done;
1479 }
1480 //
1481 // Update SDMA Address register.
1482 //
1483 SdmaAddr = EMMC_SDMA_ROUND_UP ((UINT32)(UINTN)Trb->Data, EMMC_SDMA_BOUNDARY);
1484 Status = EmmcPeimHcRwMmio (
1485 Bar + EMMC_HC_SDMA_ADDR,
1486 FALSE,
1487 sizeof (UINT32),
1488 &SdmaAddr
1489 );
1490 if (EFI_ERROR (Status)) {
1491 goto Done;
1492 }
1493 Trb->Data = (VOID*)(UINTN)SdmaAddr;
1494 }
1495
1496 if ((Packet->EmmcCmdBlk->CommandType != EmmcCommandTypeAdtc) &&
1497 (Packet->EmmcCmdBlk->ResponseType != EmmcResponceTypeR1b) &&
1498 (Packet->EmmcCmdBlk->ResponseType != EmmcResponceTypeR5b)) {
1499 if ((IntStatus & BIT0) == BIT0) {
1500 Status = EFI_SUCCESS;
1501 goto Done;
1502 }
1503 }
1504
1505 if (Packet->EmmcCmdBlk->CommandIndex == EMMC_SEND_TUNING_BLOCK) {
1506 //
1507 // When performing tuning procedure (Execute Tuning is set to 1) through PIO mode,
1508 // wait Buffer Read Ready bit of Normal Interrupt Status Register to be 1.
1509 // Refer to SD Host Controller Simplified Specification 3.0 figure 2-29 for details.
1510 //
1511 if ((IntStatus & BIT5) == BIT5) {
1512 //
1513 // Clear Buffer Read Ready interrupt at first.
1514 //
1515 IntStatus = BIT5;
1516 EmmcPeimHcRwMmio (Bar + EMMC_HC_NOR_INT_STS, FALSE, sizeof (IntStatus), &IntStatus);
1517 //
1518 // Read data out from Buffer Port register
1519 //
1520 for (PioLength = 0; PioLength < Trb->DataLen; PioLength += 4) {
1521 EmmcPeimHcRwMmio (Bar + EMMC_HC_BUF_DAT_PORT, TRUE, 4, (UINT8*)Trb->Data + PioLength);
1522 }
1523 Status = EFI_SUCCESS;
1524 goto Done;
1525 }
1526 }
1527
1528 Status = EFI_NOT_READY;
1529 Done:
1530 //
1531 // Get response data when the cmd is executed successfully.
1532 //
1533 if (!EFI_ERROR (Status)) {
1534 if (Packet->EmmcCmdBlk->CommandType != EmmcCommandTypeBc) {
1535 for (Index = 0; Index < 4; Index++) {
1536 Status = EmmcPeimHcRwMmio (
1537 Bar + EMMC_HC_RESPONSE + Index * 4,
1538 TRUE,
1539 sizeof (UINT32),
1540 &Response[Index]
1541 );
1542 if (EFI_ERROR (Status)) {
1543 EmmcPeimHcLedOnOff (Bar, FALSE);
1544 return Status;
1545 }
1546 }
1547 CopyMem (Packet->EmmcStatusBlk, Response, sizeof (Response));
1548 }
1549 }
1550
1551 if (Status != EFI_NOT_READY) {
1552 EmmcPeimHcLedOnOff (Bar, FALSE);
1553 }
1554
1555 return Status;
1556 }
1557
1558 /**
1559 Wait for the TRB execution result.
1560
1561 @param[in] Bar The mmio base address of the slot to be accessed.
1562 @param[in] Trb The pointer to the EMMC_TRB instance.
1563
1564 @retval EFI_SUCCESS The TRB is executed successfully.
1565 @retval Others Some erros happen when executing this request.
1566
1567 **/
1568 EFI_STATUS
EmmcPeimWaitTrbResult(IN UINTN Bar,IN EMMC_TRB * Trb)1569 EmmcPeimWaitTrbResult (
1570 IN UINTN Bar,
1571 IN EMMC_TRB *Trb
1572 )
1573 {
1574 EFI_STATUS Status;
1575 EMMC_COMMAND_PACKET *Packet;
1576 UINT64 Timeout;
1577 BOOLEAN InfiniteWait;
1578
1579 Packet = Trb->Packet;
1580 //
1581 // Wait Command Complete Interrupt Status bit in Normal Interrupt Status Register
1582 //
1583 Timeout = Packet->Timeout;
1584 if (Timeout == 0) {
1585 InfiniteWait = TRUE;
1586 } else {
1587 InfiniteWait = FALSE;
1588 }
1589
1590 while (InfiniteWait || (Timeout > 0)) {
1591 //
1592 // Check Trb execution result by reading Normal Interrupt Status register.
1593 //
1594 Status = EmmcPeimCheckTrbResult (Bar, Trb);
1595 if (Status != EFI_NOT_READY) {
1596 return Status;
1597 }
1598 //
1599 // Stall for 1 microsecond.
1600 //
1601 MicroSecondDelay (1);
1602
1603 Timeout--;
1604 }
1605
1606 return EFI_TIMEOUT;
1607 }
1608
1609 /**
1610 Sends EMMC command to an EMMC card that is attached to the EMMC controller.
1611
1612 If Packet is successfully sent to the EMMC card, then EFI_SUCCESS is returned.
1613
1614 If a device error occurs while sending the Packet, then EFI_DEVICE_ERROR is returned.
1615
1616 If Slot is not in a valid range for the EMMC controller, then EFI_INVALID_PARAMETER
1617 is returned.
1618
1619 If Packet defines a data command but both InDataBuffer and OutDataBuffer are NULL,
1620 EFI_INVALID_PARAMETER is returned.
1621
1622 @param[in] Slot The slot number of the Emmc card to send the command to.
1623 @param[in,out] Packet A pointer to the EMMC command data structure.
1624
1625 @retval EFI_SUCCESS The EMMC Command Packet was sent by the host.
1626 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send the SD
1627 command Packet.
1628 @retval EFI_INVALID_PARAMETER Packet, Slot, or the contents of the Packet is invalid.
1629 @retval EFI_INVALID_PARAMETER Packet defines a data command but both InDataBuffer and
1630 OutDataBuffer are NULL.
1631 @retval EFI_NO_MEDIA SD Device not present in the Slot.
1632 @retval EFI_UNSUPPORTED The command described by the EMMC Command Packet is not
1633 supported by the host controller.
1634 @retval EFI_BAD_BUFFER_SIZE The InTransferLength or OutTransferLength exceeds the
1635 limit supported by EMMC card ( i.e. if the number of bytes
1636 exceed the Last LBA).
1637
1638 **/
1639 EFI_STATUS
1640 EFIAPI
EmmcPeimExecCmd(IN EMMC_PEIM_HC_SLOT * Slot,IN OUT EMMC_COMMAND_PACKET * Packet)1641 EmmcPeimExecCmd (
1642 IN EMMC_PEIM_HC_SLOT *Slot,
1643 IN OUT EMMC_COMMAND_PACKET *Packet
1644 )
1645 {
1646 EFI_STATUS Status;
1647 EMMC_TRB *Trb;
1648
1649 if (Packet == NULL) {
1650 return EFI_INVALID_PARAMETER;
1651 }
1652
1653 if ((Packet->EmmcCmdBlk == NULL) || (Packet->EmmcStatusBlk == NULL)) {
1654 return EFI_INVALID_PARAMETER;
1655 }
1656
1657 if ((Packet->OutDataBuffer == NULL) && (Packet->OutTransferLength != 0)) {
1658 return EFI_INVALID_PARAMETER;
1659 }
1660
1661 if ((Packet->InDataBuffer == NULL) && (Packet->InTransferLength != 0)) {
1662 return EFI_INVALID_PARAMETER;
1663 }
1664
1665 Trb = EmmcPeimCreateTrb (Slot, Packet);
1666 if (Trb == NULL) {
1667 return EFI_OUT_OF_RESOURCES;
1668 }
1669
1670 Status = EmmcPeimWaitTrbEnv (Slot->EmmcHcBase, Trb);
1671 if (EFI_ERROR (Status)) {
1672 goto Done;
1673 }
1674
1675 Status = EmmcPeimExecTrb (Slot->EmmcHcBase, Trb);
1676 if (EFI_ERROR (Status)) {
1677 goto Done;
1678 }
1679
1680 Status = EmmcPeimWaitTrbResult (Slot->EmmcHcBase, Trb);
1681 if (EFI_ERROR (Status)) {
1682 goto Done;
1683 }
1684
1685 Done:
1686 EmmcPeimFreeTrb (Trb);
1687
1688 return Status;
1689 }
1690
1691 /**
1692 Send command GO_IDLE_STATE (CMD0 with argument of 0x00000000) to the device to
1693 make it go to Idle State.
1694
1695 Refer to EMMC Electrical Standard Spec 5.1 Section 6.4 for details.
1696
1697 @param[in] Slot The slot number of the Emmc card to send the command to.
1698
1699 @retval EFI_SUCCESS The EMMC device is reset correctly.
1700 @retval Others The device reset fails.
1701
1702 **/
1703 EFI_STATUS
EmmcPeimReset(IN EMMC_PEIM_HC_SLOT * Slot)1704 EmmcPeimReset (
1705 IN EMMC_PEIM_HC_SLOT *Slot
1706 )
1707 {
1708 EMMC_COMMAND_BLOCK EmmcCmdBlk;
1709 EMMC_STATUS_BLOCK EmmcStatusBlk;
1710 EMMC_COMMAND_PACKET Packet;
1711 EFI_STATUS Status;
1712
1713 ZeroMem (&EmmcCmdBlk, sizeof (EmmcCmdBlk));
1714 ZeroMem (&EmmcStatusBlk, sizeof (EmmcStatusBlk));
1715 ZeroMem (&Packet, sizeof (Packet));
1716
1717 Packet.EmmcCmdBlk = &EmmcCmdBlk;
1718 Packet.EmmcStatusBlk = &EmmcStatusBlk;
1719 Packet.Timeout = EMMC_TIMEOUT;
1720
1721 EmmcCmdBlk.CommandIndex = EMMC_GO_IDLE_STATE;
1722 EmmcCmdBlk.CommandType = EmmcCommandTypeBc;
1723 EmmcCmdBlk.ResponseType = 0;
1724 EmmcCmdBlk.CommandArgument = 0;
1725
1726 Status = EmmcPeimExecCmd (Slot, &Packet);
1727
1728 return Status;
1729 }
1730
1731 /**
1732 Send command SEND_OP_COND to the EMMC device to get the data of the OCR register.
1733
1734 Refer to EMMC Electrical Standard Spec 5.1 Section 6.4 for details.
1735
1736 @param[in] Slot The slot number of the Emmc card to send the command to.
1737 @param[in, out] Argument On input, the argument of SEND_OP_COND is to send to the device.
1738 On output, the argument is the value of OCR register.
1739
1740 @retval EFI_SUCCESS The operation is done correctly.
1741 @retval Others The operation fails.
1742
1743 **/
1744 EFI_STATUS
EmmcPeimGetOcr(IN EMMC_PEIM_HC_SLOT * Slot,IN OUT UINT32 * Argument)1745 EmmcPeimGetOcr (
1746 IN EMMC_PEIM_HC_SLOT *Slot,
1747 IN OUT UINT32 *Argument
1748 )
1749 {
1750 EMMC_COMMAND_BLOCK EmmcCmdBlk;
1751 EMMC_STATUS_BLOCK EmmcStatusBlk;
1752 EMMC_COMMAND_PACKET Packet;
1753 EFI_STATUS Status;
1754
1755 ZeroMem (&EmmcCmdBlk, sizeof (EmmcCmdBlk));
1756 ZeroMem (&EmmcStatusBlk, sizeof (EmmcStatusBlk));
1757 ZeroMem (&Packet, sizeof (Packet));
1758
1759 Packet.EmmcCmdBlk = &EmmcCmdBlk;
1760 Packet.EmmcStatusBlk = &EmmcStatusBlk;
1761 Packet.Timeout = EMMC_TIMEOUT;
1762
1763 EmmcCmdBlk.CommandIndex = EMMC_SEND_OP_COND;
1764 EmmcCmdBlk.CommandType = EmmcCommandTypeBcr;
1765 EmmcCmdBlk.ResponseType = EmmcResponceTypeR3;
1766 EmmcCmdBlk.CommandArgument = *Argument;
1767
1768 Status = EmmcPeimExecCmd (Slot, &Packet);
1769 if (!EFI_ERROR (Status)) {
1770 //
1771 // For details, refer to SD Host Controller Simplified Spec 3.0 Table 2-12.
1772 //
1773 *Argument = EmmcStatusBlk.Resp0;
1774 }
1775
1776 return Status;
1777 }
1778
1779 /**
1780 Broadcast command ALL_SEND_CID to the bus to ask all the EMMC devices to send the
1781 data of their CID registers.
1782
1783 Refer to EMMC Electrical Standard Spec 5.1 Section 6.4 for details.
1784
1785 @param[in] Slot The slot number of the Emmc card to send the command to.
1786
1787 @retval EFI_SUCCESS The operation is done correctly.
1788 @retval Others The operation fails.
1789
1790 **/
1791 EFI_STATUS
EmmcPeimGetAllCid(IN EMMC_PEIM_HC_SLOT * Slot)1792 EmmcPeimGetAllCid (
1793 IN EMMC_PEIM_HC_SLOT *Slot
1794 )
1795 {
1796 EMMC_COMMAND_BLOCK EmmcCmdBlk;
1797 EMMC_STATUS_BLOCK EmmcStatusBlk;
1798 EMMC_COMMAND_PACKET Packet;
1799 EFI_STATUS Status;
1800
1801 ZeroMem (&EmmcCmdBlk, sizeof (EmmcCmdBlk));
1802 ZeroMem (&EmmcStatusBlk, sizeof (EmmcStatusBlk));
1803 ZeroMem (&Packet, sizeof (Packet));
1804
1805 Packet.EmmcCmdBlk = &EmmcCmdBlk;
1806 Packet.EmmcStatusBlk = &EmmcStatusBlk;
1807 Packet.Timeout = EMMC_TIMEOUT;
1808
1809 EmmcCmdBlk.CommandIndex = EMMC_ALL_SEND_CID;
1810 EmmcCmdBlk.CommandType = EmmcCommandTypeBcr;
1811 EmmcCmdBlk.ResponseType = EmmcResponceTypeR2;
1812 EmmcCmdBlk.CommandArgument = 0;
1813
1814 Status = EmmcPeimExecCmd (Slot, &Packet);
1815
1816 return Status;
1817 }
1818
1819 /**
1820 Send command SET_RELATIVE_ADDR to the EMMC device to assign a Relative device
1821 Address (RCA).
1822
1823 Refer to EMMC Electrical Standard Spec 5.1 Section 6.4 for details.
1824
1825 @param[in] Slot The slot number of the Emmc card to send the command to.
1826 @param[in] Rca The relative device address to be assigned.
1827
1828 @retval EFI_SUCCESS The operation is done correctly.
1829 @retval Others The operation fails.
1830
1831 **/
1832 EFI_STATUS
EmmcPeimSetRca(IN EMMC_PEIM_HC_SLOT * Slot,IN UINT32 Rca)1833 EmmcPeimSetRca (
1834 IN EMMC_PEIM_HC_SLOT *Slot,
1835 IN UINT32 Rca
1836 )
1837 {
1838 EMMC_COMMAND_BLOCK EmmcCmdBlk;
1839 EMMC_STATUS_BLOCK EmmcStatusBlk;
1840 EMMC_COMMAND_PACKET Packet;
1841 EFI_STATUS Status;
1842
1843 ZeroMem (&EmmcCmdBlk, sizeof (EmmcCmdBlk));
1844 ZeroMem (&EmmcStatusBlk, sizeof (EmmcStatusBlk));
1845 ZeroMem (&Packet, sizeof (Packet));
1846
1847 Packet.EmmcCmdBlk = &EmmcCmdBlk;
1848 Packet.EmmcStatusBlk = &EmmcStatusBlk;
1849 Packet.Timeout = EMMC_TIMEOUT;
1850
1851 EmmcCmdBlk.CommandIndex = EMMC_SET_RELATIVE_ADDR;
1852 EmmcCmdBlk.CommandType = EmmcCommandTypeAc;
1853 EmmcCmdBlk.ResponseType = EmmcResponceTypeR1;
1854 EmmcCmdBlk.CommandArgument = Rca << 16;
1855
1856 Status = EmmcPeimExecCmd (Slot, &Packet);
1857
1858 return Status;
1859 }
1860
1861 /**
1862 Send command SEND_CSD to the EMMC device to get the data of the CSD register.
1863
1864 Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details.
1865
1866 @param[in] Slot The slot number of the Emmc card to send the command to.
1867 @param[in] Rca The relative device address of selected device.
1868 @param[out] Csd The buffer to store the content of the CSD register.
1869 Note the caller should ignore the lowest byte of this
1870 buffer as the content of this byte is meaningless even
1871 if the operation succeeds.
1872
1873 @retval EFI_SUCCESS The operation is done correctly.
1874 @retval Others The operation fails.
1875
1876 **/
1877 EFI_STATUS
EmmcPeimGetCsd(IN EMMC_PEIM_HC_SLOT * Slot,IN UINT32 Rca,OUT EMMC_CSD * Csd)1878 EmmcPeimGetCsd (
1879 IN EMMC_PEIM_HC_SLOT *Slot,
1880 IN UINT32 Rca,
1881 OUT EMMC_CSD *Csd
1882 )
1883 {
1884 EMMC_COMMAND_BLOCK EmmcCmdBlk;
1885 EMMC_STATUS_BLOCK EmmcStatusBlk;
1886 EMMC_COMMAND_PACKET Packet;
1887 EFI_STATUS Status;
1888
1889 ZeroMem (&EmmcCmdBlk, sizeof (EmmcCmdBlk));
1890 ZeroMem (&EmmcStatusBlk, sizeof (EmmcStatusBlk));
1891 ZeroMem (&Packet, sizeof (Packet));
1892
1893 Packet.EmmcCmdBlk = &EmmcCmdBlk;
1894 Packet.EmmcStatusBlk = &EmmcStatusBlk;
1895 Packet.Timeout = EMMC_TIMEOUT;
1896
1897 EmmcCmdBlk.CommandIndex = EMMC_SEND_CSD;
1898 EmmcCmdBlk.CommandType = EmmcCommandTypeAc;
1899 EmmcCmdBlk.ResponseType = EmmcResponceTypeR2;
1900 EmmcCmdBlk.CommandArgument = Rca << 16;
1901
1902 Status = EmmcPeimExecCmd (Slot, &Packet);
1903 if (!EFI_ERROR (Status)) {
1904 //
1905 // For details, refer to SD Host Controller Simplified Spec 3.0 Table 2-12.
1906 //
1907 CopyMem (((UINT8*)Csd) + 1, &EmmcStatusBlk.Resp0, sizeof (EMMC_CSD) - 1);
1908 }
1909
1910 return Status;
1911 }
1912
1913 /**
1914 Send command SELECT_DESELECT_CARD to the EMMC device to select/deselect it.
1915
1916 Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details.
1917
1918 @param[in] Slot The slot number of the Emmc card to send the command to.
1919 @param[in] Rca The relative device address of selected device.
1920
1921 @retval EFI_SUCCESS The operation is done correctly.
1922 @retval Others The operation fails.
1923
1924 **/
1925 EFI_STATUS
EmmcPeimSelect(IN EMMC_PEIM_HC_SLOT * Slot,IN UINT32 Rca)1926 EmmcPeimSelect (
1927 IN EMMC_PEIM_HC_SLOT *Slot,
1928 IN UINT32 Rca
1929 )
1930 {
1931 EMMC_COMMAND_BLOCK EmmcCmdBlk;
1932 EMMC_STATUS_BLOCK EmmcStatusBlk;
1933 EMMC_COMMAND_PACKET Packet;
1934 EFI_STATUS Status;
1935
1936 ZeroMem (&EmmcCmdBlk, sizeof (EmmcCmdBlk));
1937 ZeroMem (&EmmcStatusBlk, sizeof (EmmcStatusBlk));
1938 ZeroMem (&Packet, sizeof (Packet));
1939
1940 Packet.EmmcCmdBlk = &EmmcCmdBlk;
1941 Packet.EmmcStatusBlk = &EmmcStatusBlk;
1942 Packet.Timeout = EMMC_TIMEOUT;
1943
1944 EmmcCmdBlk.CommandIndex = EMMC_SELECT_DESELECT_CARD;
1945 EmmcCmdBlk.CommandType = EmmcCommandTypeAc;
1946 EmmcCmdBlk.ResponseType = EmmcResponceTypeR1;
1947 EmmcCmdBlk.CommandArgument = Rca << 16;
1948
1949 Status = EmmcPeimExecCmd (Slot, &Packet);
1950
1951 return Status;
1952 }
1953
1954 /**
1955 Send command SEND_EXT_CSD to the EMMC device to get the data of the EXT_CSD register.
1956
1957 Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details.
1958
1959 @param[in] Slot The slot number of the Emmc card to send the command to.
1960 @param[out] ExtCsd The buffer to store the content of the EXT_CSD register.
1961
1962 @retval EFI_SUCCESS The operation is done correctly.
1963 @retval Others The operation fails.
1964
1965 **/
1966 EFI_STATUS
EmmcPeimGetExtCsd(IN EMMC_PEIM_HC_SLOT * Slot,OUT EMMC_EXT_CSD * ExtCsd)1967 EmmcPeimGetExtCsd (
1968 IN EMMC_PEIM_HC_SLOT *Slot,
1969 OUT EMMC_EXT_CSD *ExtCsd
1970 )
1971 {
1972 EMMC_COMMAND_BLOCK EmmcCmdBlk;
1973 EMMC_STATUS_BLOCK EmmcStatusBlk;
1974 EMMC_COMMAND_PACKET Packet;
1975 EFI_STATUS Status;
1976
1977 ZeroMem (&EmmcCmdBlk, sizeof (EmmcCmdBlk));
1978 ZeroMem (&EmmcStatusBlk, sizeof (EmmcStatusBlk));
1979 ZeroMem (&Packet, sizeof (Packet));
1980
1981 Packet.EmmcCmdBlk = &EmmcCmdBlk;
1982 Packet.EmmcStatusBlk = &EmmcStatusBlk;
1983 Packet.Timeout = EMMC_TIMEOUT;
1984
1985 EmmcCmdBlk.CommandIndex = EMMC_SEND_EXT_CSD;
1986 EmmcCmdBlk.CommandType = EmmcCommandTypeAdtc;
1987 EmmcCmdBlk.ResponseType = EmmcResponceTypeR1;
1988 EmmcCmdBlk.CommandArgument = 0x00000000;
1989
1990 Packet.InDataBuffer = ExtCsd;
1991 Packet.InTransferLength = sizeof (EMMC_EXT_CSD);
1992
1993 Status = EmmcPeimExecCmd (Slot, &Packet);
1994 return Status;
1995 }
1996
1997 /**
1998 Send command SWITCH to the EMMC device to switch the mode of operation of the
1999 selected Device or modifies the EXT_CSD registers.
2000
2001 Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details.
2002
2003 @param[in] Slot The slot number of the Emmc card to send the command to.
2004 @param[in] Access The access mode of SWTICH command.
2005 @param[in] Index The offset of the field to be access.
2006 @param[in] Value The value to be set to the specified field of EXT_CSD register.
2007 @param[in] CmdSet The value of CmdSet field of EXT_CSD register.
2008
2009 @retval EFI_SUCCESS The operation is done correctly.
2010 @retval Others The operation fails.
2011
2012 **/
2013 EFI_STATUS
EmmcPeimSwitch(IN EMMC_PEIM_HC_SLOT * Slot,IN UINT8 Access,IN UINT8 Index,IN UINT8 Value,IN UINT8 CmdSet)2014 EmmcPeimSwitch (
2015 IN EMMC_PEIM_HC_SLOT *Slot,
2016 IN UINT8 Access,
2017 IN UINT8 Index,
2018 IN UINT8 Value,
2019 IN UINT8 CmdSet
2020 )
2021 {
2022 EMMC_COMMAND_BLOCK EmmcCmdBlk;
2023 EMMC_STATUS_BLOCK EmmcStatusBlk;
2024 EMMC_COMMAND_PACKET Packet;
2025 EFI_STATUS Status;
2026
2027 ZeroMem (&EmmcCmdBlk, sizeof (EmmcCmdBlk));
2028 ZeroMem (&EmmcStatusBlk, sizeof (EmmcStatusBlk));
2029 ZeroMem (&Packet, sizeof (Packet));
2030
2031 Packet.EmmcCmdBlk = &EmmcCmdBlk;
2032 Packet.EmmcStatusBlk = &EmmcStatusBlk;
2033 Packet.Timeout = EMMC_TIMEOUT;
2034
2035 EmmcCmdBlk.CommandIndex = EMMC_SWITCH;
2036 EmmcCmdBlk.CommandType = EmmcCommandTypeAc;
2037 EmmcCmdBlk.ResponseType = EmmcResponceTypeR1b;
2038 EmmcCmdBlk.CommandArgument = (Access << 24) | (Index << 16) | (Value << 8) | CmdSet;
2039
2040 Status = EmmcPeimExecCmd (Slot, &Packet);
2041
2042 return Status;
2043 }
2044
2045 /**
2046 Send command SEND_STATUS to the addressed EMMC device to get its status register.
2047
2048 Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details.
2049
2050 @param[in] Slot The slot number of the Emmc card to send the command to.
2051 @param[in] Rca The relative device address of addressed device.
2052 @param[out] DevStatus The returned device status.
2053
2054 @retval EFI_SUCCESS The operation is done correctly.
2055 @retval Others The operation fails.
2056
2057 **/
2058 EFI_STATUS
EmmcPeimSendStatus(IN EMMC_PEIM_HC_SLOT * Slot,IN UINT32 Rca,OUT UINT32 * DevStatus)2059 EmmcPeimSendStatus (
2060 IN EMMC_PEIM_HC_SLOT *Slot,
2061 IN UINT32 Rca,
2062 OUT UINT32 *DevStatus
2063 )
2064 {
2065 EMMC_COMMAND_BLOCK EmmcCmdBlk;
2066 EMMC_STATUS_BLOCK EmmcStatusBlk;
2067 EMMC_COMMAND_PACKET Packet;
2068 EFI_STATUS Status;
2069
2070 ZeroMem (&EmmcCmdBlk, sizeof (EmmcCmdBlk));
2071 ZeroMem (&EmmcStatusBlk, sizeof (EmmcStatusBlk));
2072 ZeroMem (&Packet, sizeof (Packet));
2073
2074 Packet.EmmcCmdBlk = &EmmcCmdBlk;
2075 Packet.EmmcStatusBlk = &EmmcStatusBlk;
2076 Packet.Timeout = EMMC_TIMEOUT;
2077
2078 EmmcCmdBlk.CommandIndex = EMMC_SEND_STATUS;
2079 EmmcCmdBlk.CommandType = EmmcCommandTypeAc;
2080 EmmcCmdBlk.ResponseType = EmmcResponceTypeR1;
2081 EmmcCmdBlk.CommandArgument = Rca << 16;
2082
2083 Status = EmmcPeimExecCmd (Slot, &Packet);
2084 if (!EFI_ERROR (Status)) {
2085 *DevStatus = EmmcStatusBlk.Resp0;
2086 }
2087
2088 return Status;
2089 }
2090
2091 /**
2092 Send command SET_BLOCK_COUNT to the addressed EMMC device to set the number of
2093 blocks for the following block read/write cmd.
2094
2095 Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details.
2096
2097 @param[in] Slot The slot number of the Emmc card to send the command to.
2098 @param[in] BlockCount The number of the logical block to access.
2099
2100 @retval EFI_SUCCESS The operation is done correctly.
2101 @retval Others The operation fails.
2102
2103 **/
2104 EFI_STATUS
EmmcPeimSetBlkCount(IN EMMC_PEIM_HC_SLOT * Slot,IN UINT16 BlockCount)2105 EmmcPeimSetBlkCount (
2106 IN EMMC_PEIM_HC_SLOT *Slot,
2107 IN UINT16 BlockCount
2108 )
2109 {
2110 EMMC_COMMAND_BLOCK EmmcCmdBlk;
2111 EMMC_STATUS_BLOCK EmmcStatusBlk;
2112 EMMC_COMMAND_PACKET Packet;
2113 EFI_STATUS Status;
2114
2115 ZeroMem (&EmmcCmdBlk, sizeof (EmmcCmdBlk));
2116 ZeroMem (&EmmcStatusBlk, sizeof (EmmcStatusBlk));
2117 ZeroMem (&Packet, sizeof (Packet));
2118
2119 Packet.EmmcCmdBlk = &EmmcCmdBlk;
2120 Packet.EmmcStatusBlk = &EmmcStatusBlk;
2121 Packet.Timeout = EMMC_TIMEOUT;
2122
2123 EmmcCmdBlk.CommandIndex = EMMC_SET_BLOCK_COUNT;
2124 EmmcCmdBlk.CommandType = EmmcCommandTypeAc;
2125 EmmcCmdBlk.ResponseType = EmmcResponceTypeR1;
2126 EmmcCmdBlk.CommandArgument = BlockCount;
2127
2128 Status = EmmcPeimExecCmd (Slot, &Packet);
2129
2130 return Status;
2131 }
2132
2133 /**
2134 Send command READ_MULTIPLE_BLOCK/WRITE_MULTIPLE_BLOCK to the addressed EMMC device
2135 to read/write the specified number of blocks.
2136
2137 Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details.
2138
2139 @param[in] Slot The slot number of the Emmc card to send the command to.
2140 @param[in] Lba The logical block address of starting access.
2141 @param[in] BlockSize The block size of specified EMMC device partition.
2142 @param[in] Buffer The pointer to the transfer buffer.
2143 @param[in] BufferSize The size of transfer buffer.
2144 @param[in] IsRead Boolean to show the operation direction.
2145
2146 @retval EFI_SUCCESS The operation is done correctly.
2147 @retval Others The operation fails.
2148
2149 **/
2150 EFI_STATUS
EmmcPeimRwMultiBlocks(IN EMMC_PEIM_HC_SLOT * Slot,IN EFI_LBA Lba,IN UINT32 BlockSize,IN VOID * Buffer,IN UINTN BufferSize,IN BOOLEAN IsRead)2151 EmmcPeimRwMultiBlocks (
2152 IN EMMC_PEIM_HC_SLOT *Slot,
2153 IN EFI_LBA Lba,
2154 IN UINT32 BlockSize,
2155 IN VOID *Buffer,
2156 IN UINTN BufferSize,
2157 IN BOOLEAN IsRead
2158 )
2159 {
2160 EMMC_COMMAND_BLOCK EmmcCmdBlk;
2161 EMMC_STATUS_BLOCK EmmcStatusBlk;
2162 EMMC_COMMAND_PACKET Packet;
2163 EFI_STATUS Status;
2164
2165 ZeroMem (&EmmcCmdBlk, sizeof (EmmcCmdBlk));
2166 ZeroMem (&EmmcStatusBlk, sizeof (EmmcStatusBlk));
2167 ZeroMem (&Packet, sizeof (Packet));
2168
2169 Packet.EmmcCmdBlk = &EmmcCmdBlk;
2170 Packet.EmmcStatusBlk = &EmmcStatusBlk;
2171 //
2172 // Calculate timeout value through the below formula.
2173 // Timeout = (transfer size) / (2MB/s).
2174 // Taking 2MB/s as divisor is because it's nearest to the eMMC lowest
2175 // transfer speed (2.4MB/s).
2176 // Refer to eMMC 5.0 spec section 6.9.1 for details.
2177 //
2178 Packet.Timeout = (BufferSize / (2 * 1024 * 1024) + 1) * 1000 * 1000;;
2179
2180 if (IsRead) {
2181 Packet.InDataBuffer = Buffer;
2182 Packet.InTransferLength = (UINT32)BufferSize;
2183
2184 EmmcCmdBlk.CommandIndex = EMMC_READ_MULTIPLE_BLOCK;
2185 EmmcCmdBlk.CommandType = EmmcCommandTypeAdtc;
2186 EmmcCmdBlk.ResponseType = EmmcResponceTypeR1;
2187 } else {
2188 Packet.OutDataBuffer = Buffer;
2189 Packet.OutTransferLength = (UINT32)BufferSize;
2190
2191 EmmcCmdBlk.CommandIndex = EMMC_WRITE_MULTIPLE_BLOCK;
2192 EmmcCmdBlk.CommandType = EmmcCommandTypeAdtc;
2193 EmmcCmdBlk.ResponseType = EmmcResponceTypeR1;
2194 }
2195
2196 if (Slot->SectorAddressing) {
2197 EmmcCmdBlk.CommandArgument = (UINT32)Lba;
2198 } else {
2199 EmmcCmdBlk.CommandArgument = (UINT32)MultU64x32 (Lba, BlockSize);
2200 }
2201
2202 Status = EmmcPeimExecCmd (Slot, &Packet);
2203
2204 return Status;
2205 }
2206
2207 /**
2208 Send command SEND_TUNING_BLOCK to the EMMC device for HS200 optimal sampling point
2209 detection.
2210
2211 It may be sent up to 40 times until the host finishes the tuning procedure.
2212
2213 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 for details.
2214
2215 @param[in] Slot The slot number of the Emmc card to send the command to.
2216 @param[in] BusWidth The bus width to work.
2217
2218 @retval EFI_SUCCESS The operation is done correctly.
2219 @retval Others The operation fails.
2220
2221 **/
2222 EFI_STATUS
EmmcPeimSendTuningBlk(IN EMMC_PEIM_HC_SLOT * Slot,IN UINT8 BusWidth)2223 EmmcPeimSendTuningBlk (
2224 IN EMMC_PEIM_HC_SLOT *Slot,
2225 IN UINT8 BusWidth
2226 )
2227 {
2228 EMMC_COMMAND_BLOCK EmmcCmdBlk;
2229 EMMC_STATUS_BLOCK EmmcStatusBlk;
2230 EMMC_COMMAND_PACKET Packet;
2231 EFI_STATUS Status;
2232 UINT8 TuningBlock[128];
2233
2234 ZeroMem (&EmmcCmdBlk, sizeof (EmmcCmdBlk));
2235 ZeroMem (&EmmcStatusBlk, sizeof (EmmcStatusBlk));
2236 ZeroMem (&Packet, sizeof (Packet));
2237
2238 Packet.EmmcCmdBlk = &EmmcCmdBlk;
2239 Packet.EmmcStatusBlk = &EmmcStatusBlk;
2240 Packet.Timeout = EMMC_TIMEOUT;
2241
2242 EmmcCmdBlk.CommandIndex = EMMC_SEND_TUNING_BLOCK;
2243 EmmcCmdBlk.CommandType = EmmcCommandTypeAdtc;
2244 EmmcCmdBlk.ResponseType = EmmcResponceTypeR1;
2245 EmmcCmdBlk.CommandArgument = 0;
2246
2247 Packet.InDataBuffer = TuningBlock;
2248 if (BusWidth == 8) {
2249 Packet.InTransferLength = sizeof (TuningBlock);
2250 } else {
2251 Packet.InTransferLength = 64;
2252 }
2253
2254 Status = EmmcPeimExecCmd (Slot, &Packet);
2255
2256 return Status;
2257 }
2258
2259 /**
2260 Tunning the clock to get HS200 optimal sampling point.
2261
2262 Command SEND_TUNING_BLOCK may be sent up to 40 times until the host finishes the
2263 tuning procedure.
2264
2265 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 and SD Host Controller
2266 Simplified Spec 3.0 section Figure 2-29 for details.
2267
2268 @param[in] Slot The slot number of the Emmc card to send the command to.
2269 @param[in] BusWidth The bus width to work.
2270
2271 @retval EFI_SUCCESS The operation is done correctly.
2272 @retval Others The operation fails.
2273
2274 **/
2275 EFI_STATUS
EmmcPeimTuningClkForHs200(IN EMMC_PEIM_HC_SLOT * Slot,IN UINT8 BusWidth)2276 EmmcPeimTuningClkForHs200 (
2277 IN EMMC_PEIM_HC_SLOT *Slot,
2278 IN UINT8 BusWidth
2279 )
2280 {
2281 EFI_STATUS Status;
2282 UINT8 HostCtrl2;
2283 UINT8 Retry;
2284
2285 //
2286 // Notify the host that the sampling clock tuning procedure starts.
2287 //
2288 HostCtrl2 = BIT6;
2289 Status = EmmcPeimHcOrMmio (Slot->EmmcHcBase + EMMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);
2290 if (EFI_ERROR (Status)) {
2291 return Status;
2292 }
2293 //
2294 // Ask the device to send a sequence of tuning blocks till the tuning procedure is done.
2295 //
2296 Retry = 0;
2297 do {
2298 Status = EmmcPeimSendTuningBlk (Slot, BusWidth);
2299 if (EFI_ERROR (Status)) {
2300 return Status;
2301 }
2302
2303 Status = EmmcPeimHcRwMmio (Slot->EmmcHcBase + EMMC_HC_HOST_CTRL2, TRUE, sizeof (HostCtrl2), &HostCtrl2);
2304 if (EFI_ERROR (Status)) {
2305 return Status;
2306 }
2307
2308 if ((HostCtrl2 & (BIT6 | BIT7)) == 0) {
2309 break;
2310 }
2311
2312 if ((HostCtrl2 & (BIT6 | BIT7)) == BIT7) {
2313 return EFI_SUCCESS;
2314 }
2315 } while (++Retry < 40);
2316
2317 DEBUG ((EFI_D_ERROR, "EmmcPeimTuningClkForHs200: Send tuning block fails at %d times with HostCtrl2 %02x\n", Retry, HostCtrl2));
2318 //
2319 // Abort the tuning procedure and reset the tuning circuit.
2320 //
2321 HostCtrl2 = (UINT8)~(BIT6 | BIT7);
2322 Status = EmmcPeimHcAndMmio (Slot->EmmcHcBase + EMMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);
2323 if (EFI_ERROR (Status)) {
2324 return Status;
2325 }
2326 return EFI_DEVICE_ERROR;
2327 }
2328
2329 /**
2330 Switch the bus width to specified width.
2331
2332 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.9 and SD Host Controller
2333 Simplified Spec 3.0 section Figure 3-7 for details.
2334
2335 @param[in] Slot The slot number of the Emmc card to send the command to.
2336 @param[in] Rca The relative device address to be assigned.
2337 @param[in] IsDdr If TRUE, use dual data rate data simpling method. Otherwise
2338 use single data rate data simpling method.
2339 @param[in] BusWidth The bus width to be set, it could be 4 or 8.
2340
2341 @retval EFI_SUCCESS The operation is done correctly.
2342 @retval Others The operation fails.
2343
2344 **/
2345 EFI_STATUS
EmmcPeimSwitchBusWidth(IN EMMC_PEIM_HC_SLOT * Slot,IN UINT32 Rca,IN BOOLEAN IsDdr,IN UINT8 BusWidth)2346 EmmcPeimSwitchBusWidth (
2347 IN EMMC_PEIM_HC_SLOT *Slot,
2348 IN UINT32 Rca,
2349 IN BOOLEAN IsDdr,
2350 IN UINT8 BusWidth
2351 )
2352 {
2353 EFI_STATUS Status;
2354 UINT8 Access;
2355 UINT8 Index;
2356 UINT8 Value;
2357 UINT8 CmdSet;
2358 UINT32 DevStatus;
2359
2360 //
2361 // Write Byte, the Value field is written into the byte pointed by Index.
2362 //
2363 Access = 0x03;
2364 Index = OFFSET_OF (EMMC_EXT_CSD, BusWidth);
2365 if (BusWidth == 4) {
2366 Value = 1;
2367 } else if (BusWidth == 8) {
2368 Value = 2;
2369 } else {
2370 return EFI_INVALID_PARAMETER;
2371 }
2372
2373 if (IsDdr) {
2374 Value += 4;
2375 }
2376
2377 CmdSet = 0;
2378 Status = EmmcPeimSwitch (Slot, Access, Index, Value, CmdSet);
2379 if (EFI_ERROR (Status)) {
2380 return Status;
2381 }
2382
2383 Status = EmmcPeimSendStatus (Slot, Rca, &DevStatus);
2384 if (EFI_ERROR (Status)) {
2385 return Status;
2386 }
2387 //
2388 // Check the switch operation is really successful or not.
2389 //
2390 if ((DevStatus & BIT7) != 0) {
2391 return EFI_DEVICE_ERROR;
2392 }
2393
2394 Status = EmmcPeimHcSetBusWidth (Slot->EmmcHcBase, BusWidth);
2395
2396 return Status;
2397 }
2398
2399 /**
2400 Switch the clock frequency to the specified value.
2401
2402 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6 and SD Host Controller
2403 Simplified Spec 3.0 section Figure 3-3 for details.
2404
2405 @param[in] Slot The slot number of the Emmc card to send the command to.
2406 @param[in] Rca The relative device address to be assigned.
2407 @param[in] HsTiming The value to be written to HS_TIMING field of EXT_CSD register.
2408 @param[in] ClockFreq The max clock frequency to be set, the unit is MHz.
2409
2410 @retval EFI_SUCCESS The operation is done correctly.
2411 @retval Others The operation fails.
2412
2413 **/
2414 EFI_STATUS
EmmcPeimSwitchClockFreq(IN EMMC_PEIM_HC_SLOT * Slot,IN UINT32 Rca,IN UINT8 HsTiming,IN UINT32 ClockFreq)2415 EmmcPeimSwitchClockFreq (
2416 IN EMMC_PEIM_HC_SLOT *Slot,
2417 IN UINT32 Rca,
2418 IN UINT8 HsTiming,
2419 IN UINT32 ClockFreq
2420 )
2421 {
2422 EFI_STATUS Status;
2423 UINT8 Access;
2424 UINT8 Index;
2425 UINT8 Value;
2426 UINT8 CmdSet;
2427 UINT32 DevStatus;
2428
2429 //
2430 // Write Byte, the Value field is written into the byte pointed by Index.
2431 //
2432 Access = 0x03;
2433 Index = OFFSET_OF (EMMC_EXT_CSD, HsTiming);
2434 Value = HsTiming;
2435 CmdSet = 0;
2436
2437 Status = EmmcPeimSwitch (Slot, Access, Index, Value, CmdSet);
2438 if (EFI_ERROR (Status)) {
2439 return Status;
2440 }
2441
2442 Status = EmmcPeimSendStatus (Slot, Rca, &DevStatus);
2443 if (EFI_ERROR (Status)) {
2444 return Status;
2445 }
2446 //
2447 // Check the switch operation is really successful or not.
2448 //
2449 if ((DevStatus & BIT7) != 0) {
2450 return EFI_DEVICE_ERROR;
2451 }
2452 //
2453 // Convert the clock freq unit from MHz to KHz.
2454 //
2455 Status = EmmcPeimHcClockSupply (Slot->EmmcHcBase, ClockFreq * 1000);
2456
2457 return Status;
2458 }
2459
2460 /**
2461 Switch to the High Speed timing according to request.
2462
2463 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 and SD Host Controller
2464 Simplified Spec 3.0 section Figure 2-29 for details.
2465
2466 @param[in] Slot The slot number of the Emmc card to send the command to.
2467 @param[in] Rca The relative device address to be assigned.
2468 @param[in] ClockFreq The max clock frequency to be set.
2469 @param[in] IsDdr If TRUE, use dual data rate data simpling method. Otherwise
2470 use single data rate data simpling method.
2471 @param[in] BusWidth The bus width to be set, it could be 4 or 8.
2472
2473 @retval EFI_SUCCESS The operation is done correctly.
2474 @retval Others The operation fails.
2475
2476 **/
2477 EFI_STATUS
EmmcPeimSwitchToHighSpeed(IN EMMC_PEIM_HC_SLOT * Slot,IN UINT32 Rca,IN UINT32 ClockFreq,IN BOOLEAN IsDdr,IN UINT8 BusWidth)2478 EmmcPeimSwitchToHighSpeed (
2479 IN EMMC_PEIM_HC_SLOT *Slot,
2480 IN UINT32 Rca,
2481 IN UINT32 ClockFreq,
2482 IN BOOLEAN IsDdr,
2483 IN UINT8 BusWidth
2484 )
2485 {
2486 EFI_STATUS Status;
2487 UINT8 HsTiming;
2488 UINT8 HostCtrl1;
2489 UINT8 HostCtrl2;
2490
2491 Status = EmmcPeimSwitchBusWidth (Slot, Rca, IsDdr, BusWidth);
2492 if (EFI_ERROR (Status)) {
2493 return Status;
2494 }
2495 //
2496 // Set to Hight Speed timing
2497 //
2498 HostCtrl1 = BIT2;
2499 Status = EmmcPeimHcOrMmio (Slot->EmmcHcBase + EMMC_HC_HOST_CTRL1, sizeof (HostCtrl1), &HostCtrl1);
2500 if (EFI_ERROR (Status)) {
2501 return Status;
2502 }
2503
2504 HostCtrl2 = (UINT8)~0x7;
2505 Status = EmmcPeimHcAndMmio (Slot->EmmcHcBase + EMMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);
2506 if (EFI_ERROR (Status)) {
2507 return Status;
2508 }
2509 if (IsDdr) {
2510 HostCtrl2 = BIT2;
2511 } else if (ClockFreq == 52) {
2512 HostCtrl2 = BIT0;
2513 } else {
2514 HostCtrl2 = 0;
2515 }
2516 Status = EmmcPeimHcOrMmio (Slot->EmmcHcBase + EMMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);
2517 if (EFI_ERROR (Status)) {
2518 return Status;
2519 }
2520
2521 HsTiming = 1;
2522 Status = EmmcPeimSwitchClockFreq (Slot, Rca, HsTiming, ClockFreq);
2523 if (EFI_ERROR (Status)) {
2524 return Status;
2525 }
2526
2527 return Status;
2528 }
2529
2530 /**
2531 Switch to the HS200 timing according to request.
2532
2533 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 and SD Host Controller
2534 Simplified Spec 3.0 section Figure 2-29 for details.
2535
2536 @param[in] Slot The slot number of the Emmc card to send the command to.
2537 @param[in] Rca The relative device address to be assigned.
2538 @param[in] ClockFreq The max clock frequency to be set.
2539 @param[in] BusWidth The bus width to be set, it could be 4 or 8.
2540
2541 @retval EFI_SUCCESS The operation is done correctly.
2542 @retval Others The operation fails.
2543
2544 **/
2545 EFI_STATUS
EmmcPeimSwitchToHS200(IN EMMC_PEIM_HC_SLOT * Slot,IN UINT32 Rca,IN UINT32 ClockFreq,IN UINT8 BusWidth)2546 EmmcPeimSwitchToHS200 (
2547 IN EMMC_PEIM_HC_SLOT *Slot,
2548 IN UINT32 Rca,
2549 IN UINT32 ClockFreq,
2550 IN UINT8 BusWidth
2551 )
2552 {
2553 EFI_STATUS Status;
2554 UINT8 HsTiming;
2555 UINT8 HostCtrl2;
2556 UINT16 ClockCtrl;
2557
2558 if ((BusWidth != 4) && (BusWidth != 8)) {
2559 return EFI_INVALID_PARAMETER;
2560 }
2561
2562 Status = EmmcPeimSwitchBusWidth (Slot, Rca, FALSE, BusWidth);
2563 if (EFI_ERROR (Status)) {
2564 return Status;
2565 }
2566 //
2567 // Set to HS200/SDR104 timing
2568 //
2569 //
2570 // Stop bus clock at first
2571 //
2572 Status = EmmcPeimHcStopClock (Slot->EmmcHcBase);
2573 if (EFI_ERROR (Status)) {
2574 return Status;
2575 }
2576
2577 HostCtrl2 = (UINT8)~0x7;
2578 Status = EmmcPeimHcAndMmio (Slot->EmmcHcBase + EMMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);
2579 if (EFI_ERROR (Status)) {
2580 return Status;
2581 }
2582 HostCtrl2 = BIT0 | BIT1;
2583 Status = EmmcPeimHcOrMmio (Slot->EmmcHcBase + EMMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);
2584 if (EFI_ERROR (Status)) {
2585 return Status;
2586 }
2587
2588 //
2589 // Wait Internal Clock Stable in the Clock Control register to be 1 before set SD Clock Enable bit
2590 //
2591 Status = EmmcPeimHcWaitMmioSet (
2592 Slot->EmmcHcBase + EMMC_HC_CLOCK_CTRL,
2593 sizeof (ClockCtrl),
2594 BIT1,
2595 BIT1,
2596 EMMC_TIMEOUT
2597 );
2598 if (EFI_ERROR (Status)) {
2599 return Status;
2600 }
2601 //
2602 // Set SD Clock Enable in the Clock Control register to 1
2603 //
2604 ClockCtrl = BIT2;
2605 Status = EmmcPeimHcOrMmio (Slot->EmmcHcBase + EMMC_HC_CLOCK_CTRL, sizeof (ClockCtrl), &ClockCtrl);
2606
2607 HsTiming = 2;
2608 Status = EmmcPeimSwitchClockFreq (Slot, Rca, HsTiming, ClockFreq);
2609 if (EFI_ERROR (Status)) {
2610 return Status;
2611 }
2612
2613 Status = EmmcPeimTuningClkForHs200 (Slot, BusWidth);
2614
2615 return Status;
2616 }
2617
2618 /**
2619 Switch to the HS400 timing according to request.
2620
2621 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 and SD Host Controller
2622 Simplified Spec 3.0 section Figure 2-29 for details.
2623
2624 @param[in] Slot The slot number of the Emmc card to send the command to.
2625 @param[in] Rca The relative device address to be assigned.
2626 @param[in] ClockFreq The max clock frequency to be set.
2627
2628 @retval EFI_SUCCESS The operation is done correctly.
2629 @retval Others The operation fails.
2630
2631 **/
2632 EFI_STATUS
EmmcPeimSwitchToHS400(IN EMMC_PEIM_HC_SLOT * Slot,IN UINT32 Rca,IN UINT32 ClockFreq)2633 EmmcPeimSwitchToHS400 (
2634 IN EMMC_PEIM_HC_SLOT *Slot,
2635 IN UINT32 Rca,
2636 IN UINT32 ClockFreq
2637 )
2638 {
2639 EFI_STATUS Status;
2640 UINT8 HsTiming;
2641 UINT8 HostCtrl2;
2642
2643 Status = EmmcPeimSwitchToHS200 (Slot, Rca, ClockFreq, 8);
2644 if (EFI_ERROR (Status)) {
2645 return Status;
2646 }
2647 //
2648 // Set to Hight Speed timing and set the clock frequency to a value less than 52MHz.
2649 //
2650 HsTiming = 1;
2651 Status = EmmcPeimSwitchClockFreq (Slot, Rca, HsTiming, 52);
2652 if (EFI_ERROR (Status)) {
2653 return Status;
2654 }
2655 //
2656 // HS400 mode must use 8 data lines.
2657 //
2658 Status = EmmcPeimSwitchBusWidth (Slot, Rca, TRUE, 8);
2659 if (EFI_ERROR (Status)) {
2660 return Status;
2661 }
2662 //
2663 // Set to HS400 timing
2664 //
2665 HostCtrl2 = (UINT8)~0x7;
2666 Status = EmmcPeimHcAndMmio (Slot->EmmcHcBase + EMMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);
2667 if (EFI_ERROR (Status)) {
2668 return Status;
2669 }
2670 HostCtrl2 = BIT0 | BIT2;
2671 Status = EmmcPeimHcOrMmio (Slot->EmmcHcBase + EMMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);
2672 if (EFI_ERROR (Status)) {
2673 return Status;
2674 }
2675
2676 HsTiming = 3;
2677 Status = EmmcPeimSwitchClockFreq (Slot, Rca, HsTiming, ClockFreq);
2678
2679 return Status;
2680 }
2681
2682 /**
2683 Switch the high speed timing according to request.
2684
2685 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 and SD Host Controller
2686 Simplified Spec 3.0 section Figure 2-29 for details.
2687
2688 @param[in] Slot The slot number of the Emmc card to send the command to.
2689 @param[in] Rca The relative device address to be assigned.
2690
2691 @retval EFI_SUCCESS The operation is done correctly.
2692 @retval Others The operation fails.
2693
2694 **/
2695 EFI_STATUS
EmmcPeimSetBusMode(IN EMMC_PEIM_HC_SLOT * Slot,IN UINT32 Rca)2696 EmmcPeimSetBusMode (
2697 IN EMMC_PEIM_HC_SLOT *Slot,
2698 IN UINT32 Rca
2699 )
2700 {
2701 EFI_STATUS Status;
2702 EMMC_HC_SLOT_CAP Capability;
2703 UINT8 HsTiming;
2704 BOOLEAN IsDdr;
2705 UINT32 ClockFreq;
2706 UINT8 BusWidth;
2707
2708 Status = EmmcPeimGetCsd (Slot, Rca, &Slot->Csd);
2709 if (EFI_ERROR (Status)) {
2710 DEBUG ((EFI_D_ERROR, "EmmcPeimSetBusMode: EmmcPeimGetCsd fails with %r\n", Status));
2711 return Status;
2712 }
2713
2714 if ((Slot->Csd.CSizeLow | Slot->Csd.CSizeHigh << 2) == 0xFFF) {
2715 Slot->SectorAddressing = TRUE;
2716 } else {
2717 Slot->SectorAddressing = FALSE;
2718 }
2719
2720 Status = EmmcPeimSelect (Slot, Rca);
2721 if (EFI_ERROR (Status)) {
2722 DEBUG ((EFI_D_ERROR, "EmmcPeimSetBusMode: EmmcPeimSelect fails with %r\n", Status));
2723 return Status;
2724 }
2725
2726 Status = EmmcPeimHcGetCapability (Slot->EmmcHcBase, &Capability);
2727 if (EFI_ERROR (Status)) {
2728 DEBUG ((EFI_D_ERROR, "EmmcPeimSetBusMode: EmmcPeimHcGetCapability fails with %r\n", Status));
2729 return Status;
2730 }
2731
2732 ASSERT (Capability.BaseClkFreq != 0);
2733 //
2734 // Check if the Host Controller support 8bits bus width.
2735 //
2736 if (Capability.BusWidth8 != 0) {
2737 BusWidth = 8;
2738 } else {
2739 BusWidth = 4;
2740 }
2741 //
2742 // Get Deivce_Type from EXT_CSD register.
2743 //
2744 Status = EmmcPeimGetExtCsd (Slot, &Slot->ExtCsd);
2745 if (EFI_ERROR (Status)) {
2746 DEBUG ((EFI_D_ERROR, "EmmcPeimSetBusMode: EmmcPeimGetExtCsd fails with %r\n", Status));
2747 return Status;
2748 }
2749 //
2750 // Calculate supported bus speed/bus width/clock frequency.
2751 //
2752 HsTiming = 0;
2753 IsDdr = FALSE;
2754 ClockFreq = 0;
2755 if (((Slot->ExtCsd.DeviceType & (BIT4 | BIT5)) != 0) && (Capability.Sdr104 != 0)) {
2756 HsTiming = 2;
2757 IsDdr = FALSE;
2758 ClockFreq = 200;
2759 } else if (((Slot->ExtCsd.DeviceType & (BIT2 | BIT3)) != 0) && (Capability.Ddr50 != 0)) {
2760 HsTiming = 1;
2761 IsDdr = TRUE;
2762 ClockFreq = 52;
2763 } else if (((Slot->ExtCsd.DeviceType & BIT1) != 0) && (Capability.HighSpeed != 0)) {
2764 HsTiming = 1;
2765 IsDdr = FALSE;
2766 ClockFreq = 52;
2767 } else if (((Slot->ExtCsd.DeviceType & BIT0) != 0) && (Capability.HighSpeed != 0)) {
2768 HsTiming = 1;
2769 IsDdr = FALSE;
2770 ClockFreq = 26;
2771 }
2772 //
2773 // Check if both of the device and the host controller support HS400 DDR mode.
2774 //
2775 if (((Slot->ExtCsd.DeviceType & (BIT6 | BIT7)) != 0) && (Capability.Hs400 != 0)) {
2776 //
2777 // The host controller supports 8bits bus.
2778 //
2779 ASSERT (BusWidth == 8);
2780 HsTiming = 3;
2781 IsDdr = TRUE;
2782 ClockFreq = 200;
2783 }
2784
2785 if ((ClockFreq == 0) || (HsTiming == 0)) {
2786 //
2787 // Continue using default setting.
2788 //
2789 return EFI_SUCCESS;
2790 }
2791
2792 DEBUG ((EFI_D_INFO, "HsTiming %d ClockFreq %d BusWidth %d Ddr %a\n", HsTiming, ClockFreq, BusWidth, IsDdr ? "TRUE":"FALSE"));
2793
2794 if (HsTiming == 3) {
2795 //
2796 // Execute HS400 timing switch procedure
2797 //
2798 Status = EmmcPeimSwitchToHS400 (Slot, Rca, ClockFreq);
2799 } else if (HsTiming == 2) {
2800 //
2801 // Execute HS200 timing switch procedure
2802 //
2803 Status = EmmcPeimSwitchToHS200 (Slot, Rca, ClockFreq, BusWidth);
2804 } else {
2805 //
2806 // Execute High Speed timing switch procedure
2807 //
2808 Status = EmmcPeimSwitchToHighSpeed (Slot, Rca, ClockFreq, IsDdr, BusWidth);
2809 }
2810
2811 return Status;
2812 }
2813
2814 /**
2815 Execute EMMC device identification procedure.
2816
2817 Refer to EMMC Electrical Standard Spec 5.1 Section 6.4 for details.
2818
2819 @param[in] Slot The slot number of the Emmc card to send the command to.
2820
2821 @retval EFI_SUCCESS There is a EMMC card.
2822 @retval Others There is not a EMMC card.
2823
2824 **/
2825 EFI_STATUS
EmmcPeimIdentification(IN EMMC_PEIM_HC_SLOT * Slot)2826 EmmcPeimIdentification (
2827 IN EMMC_PEIM_HC_SLOT *Slot
2828 )
2829 {
2830 EFI_STATUS Status;
2831 UINT32 Ocr;
2832 UINT32 Rca;
2833
2834 Status = EmmcPeimReset (Slot);
2835 if (EFI_ERROR (Status)) {
2836 DEBUG ((EFI_D_ERROR, "EmmcPeimIdentification: EmmcPeimReset fails with %r\n", Status));
2837 return Status;
2838 }
2839
2840 Ocr = 0;
2841 do {
2842 Status = EmmcPeimGetOcr (Slot, &Ocr);
2843 if (EFI_ERROR (Status)) {
2844 DEBUG ((EFI_D_ERROR, "EmmcPeimIdentification: EmmcPeimGetOcr fails with %r\n", Status));
2845 return Status;
2846 }
2847 } while ((Ocr & BIT31) == 0);
2848
2849 Status = EmmcPeimGetAllCid (Slot);
2850 if (EFI_ERROR (Status)) {
2851 DEBUG ((EFI_D_ERROR, "EmmcPeimIdentification: EmmcPeimGetAllCid fails with %r\n", Status));
2852 return Status;
2853 }
2854 //
2855 // Don't support multiple devices on the slot, that is
2856 // shared bus slot feature.
2857 //
2858 Rca = 1;
2859 Status = EmmcPeimSetRca (Slot, Rca);
2860 if (EFI_ERROR (Status)) {
2861 DEBUG ((EFI_D_ERROR, "EmmcPeimIdentification: EmmcPeimSetRca fails with %r\n", Status));
2862 return Status;
2863 }
2864 //
2865 // Enter Data Tranfer Mode.
2866 //
2867 DEBUG ((EFI_D_INFO, "Found a EMMC device at slot [%d], RCA [%d]\n", Slot, Rca));
2868
2869 Status = EmmcPeimSetBusMode (Slot, Rca);
2870
2871 return Status;
2872 }
2873
2874