]> git.proxmox.com Git - mirror_edk2.git/blame - ArmPkg/Drivers/PL180MciDxe/PL180Mci.c
EmbeddedPkg: Removed unused PCD values
[mirror_edk2.git] / ArmPkg / Drivers / PL180MciDxe / PL180Mci.c
CommitLineData
1bfda055 1/** @file\r
2 This file implement the MMC Host Protocol for the ARM PrimeCell PL180.\r
3\r
4 Copyright (c) 2011, ARM Limited. All rights reserved.\r
5 \r
6 This program and the accompanying materials \r
7 are licensed and made available under the terms and conditions of the BSD License \r
8 which accompanies this distribution. The full text of the license may be found at \r
9 http://opensource.org/licenses/bsd-license.php \r
10\r
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
13\r
14**/\r
15\r
16#include "PL180Mci.h"\r
17\r
18#include <Library/DevicePathLib.h>\r
19#include <Library/BaseMemoryLib.h>\r
20\r
21EFI_MMC_HOST_PROTOCOL *gpMmcHost;\r
22\r
23// Untested ...\r
24//#define USE_STREAM\r
25\r
26#define MMCI0_BLOCKLEN 512\r
27#define MMCI0_POW2_BLOCKLEN 9\r
28#define MMCI0_TIMEOUT 1000\r
29\r
2ed2ed29 30BOOLEAN\r
31MciIsPowerOn (\r
32 VOID\r
33 )\r
34{\r
35 return ((MmioRead32(MCI_POWER_CONTROL_REG) & 0x3) == MCI_POWER_ON);\r
1bfda055 36}\r
37\r
2ed2ed29 38EFI_STATUS\r
39MciInitialize (\r
40 VOID\r
41 )\r
42{\r
43 MCI_TRACE("MciInitialize()");\r
44 return EFI_SUCCESS;\r
1bfda055 45}\r
46\r
2ed2ed29 47BOOLEAN\r
48MciIsCardPresent (\r
49 VOID\r
50 )\r
51{\r
52 return (MmioRead32(FixedPcdGet32(PcdPL180SysMciRegAddress)) & 1);\r
1bfda055 53}\r
54\r
2ed2ed29 55BOOLEAN\r
56MciIsReadOnly (\r
57 VOID\r
58 )\r
59{\r
60 return (MmioRead32(FixedPcdGet32(PcdPL180SysMciRegAddress)) & 2);\r
1bfda055 61}\r
62\r
e862cd50 63#if 0\r
64//Note: This function has been commented out because it is not used yet.\r
65// This function could be used to remove the hardcoded BlockLen used\r
66// in MciPrepareDataPath\r
67\r
1bfda055 68// Convert block size to 2^n\r
2ed2ed29 69STATIC\r
70UINT32\r
71GetPow2BlockLen (\r
72 IN UINT32 BlockLen\r
73 )\r
74{\r
75 UINTN Loop;\r
76 UINTN Pow2BlockLen;\r
77\r
78 Loop = 0x8000;\r
79 Pow2BlockLen = 15;\r
80 do {\r
81 Loop = (Loop >> 1) & 0xFFFF;\r
82 Pow2BlockLen--;\r
83 } while (Pow2BlockLen && (!(Loop & BlockLen)));\r
84\r
85 return Pow2BlockLen;\r
1bfda055 86}\r
e862cd50 87#endif\r
1bfda055 88\r
2ed2ed29 89VOID\r
90MciPrepareDataPath (\r
91 IN UINTN TransferDirection\r
92 )\r
93{\r
94 // Set Data Length & Data Timer\r
95 MmioWrite32(MCI_DATA_TIMER_REG,0xFFFFFFF);\r
96 MmioWrite32(MCI_DATA_LENGTH_REG,MMCI0_BLOCKLEN);\r
1bfda055 97\r
98#ifndef USE_STREAM\r
2ed2ed29 99 //Note: we are using a hardcoded BlockLen (=512). If we decide to use a variable size, we could\r
100 // compute the pow2 of BlockLen with the above function GetPow2BlockLen()\r
101 MmioWrite32(MCI_DATA_CTL_REG, MCI_DATACTL_ENABLE | MCI_DATACTL_DMA_ENABLE | TransferDirection | (MMCI0_POW2_BLOCKLEN << 4));\r
1bfda055 102#else\r
2ed2ed29 103 MmioWrite32(MCI_DATA_CTL_REG, MCI_DATACTL_ENABLE | MCI_DATACTL_DMA_ENABLE | TransferDirection | MCI_DATACTL_STREAM_TRANS);\r
1bfda055 104#endif\r
105}\r
106\r
2ed2ed29 107EFI_STATUS\r
108MciSendCommand (\r
109 IN MMC_CMD MmcCmd,\r
110 IN UINT32 Argument\r
111 )\r
112{\r
113 UINT32 Status;\r
114 UINT32 Cmd;\r
115 UINTN RetVal;\r
116 UINTN CmdCtrlReg;\r
117\r
118 RetVal = EFI_SUCCESS;\r
119\r
120 if ((MmcCmd == MMC_CMD17) || (MmcCmd == MMC_CMD11)) {\r
121 MciPrepareDataPath(MCI_DATACTL_CARD_TO_CONT);\r
122 } else if ((MmcCmd == MMC_CMD24) || (MmcCmd == MMC_CMD20)) {\r
123 MciPrepareDataPath(MCI_DATACTL_CONT_TO_CARD);\r
124 }\r
125\r
126 // Create Command for PL180\r
50c5f187 127 Cmd = (MMC_GET_INDX(MmcCmd) & INDX_MASK) | MCI_CPSM_ENABLED;\r
2ed2ed29 128 if (MmcCmd & MMC_CMD_WAIT_RESPONSE) {\r
129 Cmd |= MCI_CPSM_WAIT_RESPONSE;\r
130 }\r
131\r
132 if (MmcCmd & MMC_CMD_LONG_RESPONSE) {\r
133 Cmd |= MCI_CPSM_LONG_RESPONSE;\r
134 }\r
1bfda055 135\r
2ed2ed29 136 // Clear Status register static flags\r
137 MmioWrite32(MCI_CLEAR_STATUS_REG,0x7FF);\r
138\r
139 //Write to command argument register\r
140 MmioWrite32(MCI_ARGUMENT_REG,Argument);\r
141\r
142 //Write to command register\r
143 MmioWrite32(MCI_COMMAND_REG,Cmd);\r
144\r
145 if (Cmd & MCI_CPSM_WAIT_RESPONSE) {\r
146 Status = MmioRead32(MCI_STATUS_REG);\r
147 while (!(Status & (MCI_STATUS_CMD_RESPEND | MCI_STATUS_CMD_CMDCRCFAIL | MCI_STATUS_CMD_CMDTIMEOUT | MCI_STATUS_CMD_START_BIT_ERROR))) {\r
148 Status = MmioRead32(MCI_STATUS_REG);\r
1bfda055 149 }\r
150\r
2ed2ed29 151 if ((Status & MCI_STATUS_CMD_START_BIT_ERROR)) {\r
152 DEBUG ((EFI_D_ERROR, "MciSendCommand(CmdIndex:%d) Start bit Error! Response:0x%X Status:0x%x\n",(Cmd & 0x3F),MmioRead32(MCI_RESPONSE0_REG),Status));\r
153 RetVal = EFI_NO_RESPONSE;\r
154 goto Exit;\r
155 } else if ((Status & MCI_STATUS_CMD_CMDTIMEOUT)) {\r
156 //DEBUG ((EFI_D_ERROR, "MciSendCommand(CmdIndex:%d) TIMEOUT! Response:0x%X Status:0x%x\n",(Cmd & 0x3F),MmioRead32(MCI_RESPONSE0_REG),Status));\r
157 RetVal = EFI_TIMEOUT;\r
158 goto Exit;\r
50c5f187 159 } else if ((!(MmcCmd & MMC_CMD_NO_CRC_RESPONSE)) && (Status & MCI_STATUS_CMD_CMDCRCFAIL)) {\r
160 // The CMD1 and response type R3 do not contain CRC. We should ignore the CRC failed Status.\r
2ed2ed29 161 RetVal = EFI_CRC_ERROR;\r
162 goto Exit;\r
1bfda055 163 } else {\r
2ed2ed29 164 RetVal = EFI_SUCCESS;\r
165 goto Exit;\r
1bfda055 166 }\r
2ed2ed29 167 } else {\r
168 Status = MmioRead32(MCI_STATUS_REG);\r
169 while (!(Status & (MCI_STATUS_CMD_SENT | MCI_STATUS_CMD_CMDCRCFAIL | MCI_STATUS_CMD_CMDTIMEOUT| MCI_STATUS_CMD_START_BIT_ERROR))) {\r
170 Status = MmioRead32(MCI_STATUS_REG);\r
1bfda055 171 }\r
172\r
2ed2ed29 173 if ((Status & MCI_STATUS_CMD_START_BIT_ERROR)) {\r
174 DEBUG ((EFI_D_ERROR, "MciSendCommand(CmdIndex:%d) Start bit Error! Response:0x%X Status:0x%x\n",(Cmd & 0x3F),MmioRead32(MCI_RESPONSE0_REG),Status));\r
175 RetVal = EFI_NO_RESPONSE;\r
176 goto Exit;\r
177 } else if ((Status & MCI_STATUS_CMD_CMDTIMEOUT)) {\r
178 //DEBUG ((EFI_D_ERROR, "MciSendCommand(CmdIndex:%d) TIMEOUT! Response:0x%X Status:0x%x\n",(Cmd & 0x3F),MmioRead32(MCI_RESPONSE0_REG),Status));\r
179 RetVal = EFI_TIMEOUT;\r
180 goto Exit;\r
181 } else\r
50c5f187 182 if ((!(MmcCmd & MMC_CMD_NO_CRC_RESPONSE)) && (Status & MCI_STATUS_CMD_CMDCRCFAIL)) {\r
2ed2ed29 183 // The CMD1 does not contain CRC. We should ignore the CRC failed Status.\r
184 RetVal = EFI_CRC_ERROR;\r
185 goto Exit;\r
186 } else {\r
187 RetVal = EFI_SUCCESS;\r
188 goto Exit;\r
1bfda055 189 }\r
2ed2ed29 190 }\r
1bfda055 191\r
2ed2ed29 192Exit:\r
193 //Disable Command Path\r
194 CmdCtrlReg = MmioRead32(MCI_COMMAND_REG);\r
195 MmioWrite32(MCI_COMMAND_REG, (CmdCtrlReg & ~MCI_CPSM_ENABLED));\r
196 return RetVal;\r
1bfda055 197}\r
198\r
2ed2ed29 199EFI_STATUS\r
200MciReceiveResponse (\r
201 IN MMC_RESPONSE_TYPE Type,\r
202 IN UINT32* Buffer\r
203 )\r
204{\r
205 if (Buffer == NULL) {\r
206 return EFI_INVALID_PARAMETER;\r
207 }\r
208\r
209 if ((Type == MMC_RESPONSE_TYPE_R1) || (Type == MMC_RESPONSE_TYPE_R1b) ||\r
210 (Type == MMC_RESPONSE_TYPE_R3) || (Type == MMC_RESPONSE_TYPE_R6) ||\r
211 (Type == MMC_RESPONSE_TYPE_R7))\r
212 {\r
213 Buffer[0] = MmioRead32(MCI_RESPONSE0_REG);\r
214 Buffer[1] = MmioRead32(MCI_RESPONSE1_REG);\r
215 } else if (Type == MMC_RESPONSE_TYPE_R2) {\r
216 Buffer[0] = MmioRead32(MCI_RESPONSE0_REG);\r
217 Buffer[1] = MmioRead32(MCI_RESPONSE1_REG);\r
218 Buffer[2] = MmioRead32(MCI_RESPONSE2_REG);\r
219 Buffer[3] = MmioRead32(MCI_RESPONSE3_REG);\r
220 }\r
1bfda055 221\r
2ed2ed29 222 return EFI_SUCCESS;\r
223}\r
1bfda055 224\r
2ed2ed29 225EFI_STATUS\r
226MciReadBlockData (\r
227 IN EFI_LBA Lba,\r
228 IN UINTN Length,\r
229 IN UINT32* Buffer\r
230 )\r
231{\r
232 UINTN Loop;\r
233 UINTN Finish;\r
234 UINTN Status;\r
235 EFI_STATUS RetVal;\r
236 UINTN DataCtrlReg;\r
237\r
238 RetVal = EFI_SUCCESS;\r
239\r
240 // Read data from the RX FIFO\r
241 Loop = 0;\r
242 Finish = MMCI0_BLOCKLEN / 4;\r
243 do {\r
244 // Read the Status flags\r
1bfda055 245 Status = MmioRead32(MCI_STATUS_REG);\r
2ed2ed29 246\r
247 // Do eight reads if possible else a single read\r
248 if (Status & MCI_STATUS_CMD_RXFIFOHALFFULL) {\r
249 Buffer[Loop] = MmioRead32(MCI_FIFO_REG);\r
250 Loop++;\r
251 Buffer[Loop] = MmioRead32(MCI_FIFO_REG);\r
252 Loop++;\r
253 Buffer[Loop] = MmioRead32(MCI_FIFO_REG);\r
254 Loop++;\r
255 Buffer[Loop] = MmioRead32(MCI_FIFO_REG);\r
256 Loop++;\r
257 Buffer[Loop] = MmioRead32(MCI_FIFO_REG);\r
258 Loop++;\r
259 Buffer[Loop] = MmioRead32(MCI_FIFO_REG);\r
260 Loop++;\r
261 Buffer[Loop] = MmioRead32(MCI_FIFO_REG);\r
262 Loop++;\r
263 Buffer[Loop] = MmioRead32(MCI_FIFO_REG);\r
264 Loop++;\r
265 } else if (Status & MCI_STATUS_CMD_RXDATAAVAILBL) {\r
50c5f187 266 Buffer[Loop] = MmioRead32(MCI_FIFO_REG);\r
267 Loop++;\r
2ed2ed29 268 } else {\r
269 //Check for error conditions and timeouts\r
270 if(Status & MCI_STATUS_CMD_DATATIMEOUT) {\r
271 DEBUG ((EFI_D_ERROR, "MciReadBlockData(): TIMEOUT! Response:0x%X Status:0x%x\n",MmioRead32(MCI_RESPONSE0_REG),Status));\r
272 RetVal = EFI_TIMEOUT;\r
273 break;\r
274 } else if(Status & MCI_STATUS_CMD_DATACRCFAIL) {\r
275 DEBUG ((EFI_D_ERROR, "MciReadBlockData(): CRC Error! Response:0x%X Status:0x%x\n",MmioRead32(MCI_RESPONSE0_REG),Status));\r
276 RetVal = EFI_CRC_ERROR;\r
277 break;\r
278 } else if(Status & MCI_STATUS_CMD_START_BIT_ERROR) {\r
279 DEBUG ((EFI_D_ERROR, "MciReadBlockData(): Start-bit Error! Response:0x%X Status:0x%x\n",MmioRead32(MCI_RESPONSE0_REG),Status));\r
280 RetVal = EFI_NO_RESPONSE;\r
281 break;\r
282 }\r
1bfda055 283 }\r
2ed2ed29 284 //clear RX over run flag\r
285 if(Status & MCI_STATUS_CMD_RXOVERRUN) {\r
286 MmioWrite32(MCI_CLEAR_STATUS_REG, MCI_STATUS_CMD_RXOVERRUN);\r
287 }\r
288 } while ((Loop < Finish));\r
1bfda055 289\r
2ed2ed29 290 //Clear Status flags\r
291 MmioWrite32(MCI_CLEAR_STATUS_REG, 0x7FF);\r
292\r
293 //Disable Data path\r
294 DataCtrlReg = MmioRead32(MCI_DATA_CTL_REG);\r
295 MmioWrite32(MCI_DATA_CTL_REG, (DataCtrlReg & 0xFE));\r
1bfda055 296\r
2ed2ed29 297 return RetVal;\r
1bfda055 298}\r
299\r
2ed2ed29 300EFI_STATUS\r
301MciWriteBlockData (\r
302 IN EFI_LBA Lba,\r
303 IN UINTN Length,\r
304 IN UINT32* Buffer\r
305 )\r
306{\r
307 UINTN Loop;\r
308 UINTN Finish;\r
309 UINTN Timer;\r
310 UINTN Status;\r
311 EFI_STATUS RetVal;\r
312 UINTN DataCtrlReg;\r
313\r
314 RetVal = EFI_SUCCESS;\r
315\r
316 // Write the data to the TX FIFO\r
317 Loop = 0;\r
318 Finish = MMCI0_BLOCKLEN / 4;\r
319 Timer = MMCI0_TIMEOUT * 100;\r
320 do {\r
321 // Read the Status flags\r
322 Status = MmioRead32(MCI_STATUS_REG);\r
1bfda055 323\r
2ed2ed29 324 // Do eight writes if possible else a single write\r
325 if (Status & MCI_STATUS_CMD_TXFIFOHALFEMPTY) {\r
326 MmioWrite32(MCI_FIFO_REG, Buffer[Loop]);\r
327 Loop++;\r
328 MmioWrite32(MCI_FIFO_REG, Buffer[Loop]);\r
329 Loop++;\r
330 MmioWrite32(MCI_FIFO_REG, Buffer[Loop]);\r
331 Loop++;\r
332 MmioWrite32(MCI_FIFO_REG, Buffer[Loop]);\r
333 Loop++;\r
334 MmioWrite32(MCI_FIFO_REG, Buffer[Loop]);\r
335 Loop++;\r
336 MmioWrite32(MCI_FIFO_REG, Buffer[Loop]);\r
337 Loop++;\r
338 MmioWrite32(MCI_FIFO_REG, Buffer[Loop]);\r
339 Loop++;\r
340 MmioWrite32(MCI_FIFO_REG, Buffer[Loop]);\r
341 Loop++;\r
342 } else if ((Status & MCI_STATUS_CMD_TXFIFOEMPTY)) {\r
343 MmioWrite32(MCI_FIFO_REG, Buffer[Loop]);\r
344 Loop++;\r
345 } else {\r
346 //Check for error conditions and timeouts\r
347 if(Status & MCI_STATUS_CMD_DATATIMEOUT) {\r
348 DEBUG ((EFI_D_ERROR, "MciWriteBlockData(): TIMEOUT! Response:0x%X Status:0x%x\n",MmioRead32(MCI_RESPONSE0_REG),Status));\r
349 RetVal = EFI_TIMEOUT;\r
350 goto Exit;\r
351 } else if(Status & MCI_STATUS_CMD_DATACRCFAIL) {\r
352 DEBUG ((EFI_D_ERROR, "MciWriteBlockData(): CRC Error! Response:0x%X Status:0x%x\n",MmioRead32(MCI_RESPONSE0_REG),Status));\r
353 RetVal = EFI_CRC_ERROR;\r
354 goto Exit;\r
355 } else if(Status & MCI_STATUS_CMD_TX_UNDERRUN) {\r
356 DEBUG ((EFI_D_ERROR, "MciWriteBlockData(): TX buffer Underrun! Response:0x%X Status:0x%x, Number of bytes written 0x%x\n",MmioRead32(MCI_RESPONSE0_REG),Status, Loop));\r
357 RetVal = EFI_BUFFER_TOO_SMALL;\r
1bfda055 358 ASSERT(0);\r
2ed2ed29 359 goto Exit;\r
360 }\r
1bfda055 361 }\r
2ed2ed29 362 } while (Loop < Finish);\r
363\r
364 // Wait for FIFO to drain\r
365 Timer = MMCI0_TIMEOUT * 60;\r
366 Status = MmioRead32(MCI_STATUS_REG);\r
367#ifndef USE_STREAM\r
368 // Single block\r
369 while (((Status & MCI_STATUS_CMD_TXDONE) != MCI_STATUS_CMD_TXDONE) && Timer) {\r
370#else\r
371 // Stream\r
372 while (((Status & MCI_STATUS_CMD_DATAEND) != MCI_STATUS_CMD_DATAEND) && Timer) {\r
373#endif\r
374 NanoSecondDelay(10);\r
375 Status = MmioRead32(MCI_STATUS_REG);\r
376 Timer--;\r
377 }\r
378\r
379 if(Timer == 0) {\r
380 DEBUG ((EFI_D_ERROR, "MciWriteBlockData(): Data End timeout Number of bytes written 0x%x\n",Loop));\r
381 ASSERT(Timer > 0);\r
382 return EFI_TIMEOUT;\r
383 }\r
384\r
385 //Clear Status flags\r
386 MmioWrite32(MCI_CLEAR_STATUS_REG, 0x7FF);\r
387 if (Timer == 0) {\r
388 RetVal = EFI_TIMEOUT;\r
389 }\r
390\r
391Exit:\r
392 //Disable Data path\r
393 DataCtrlReg = MmioRead32(MCI_DATA_CTL_REG);\r
394 MmioWrite32(MCI_DATA_CTL_REG, (DataCtrlReg & 0xFE));\r
395 return RetVal;\r
396}\r
397\r
398EFI_STATUS\r
399MciNotifyState (\r
400 IN MMC_STATE State\r
401 )\r
402{\r
403 UINT32 Data32;\r
404\r
405 switch(State) {\r
406 case MmcInvalidState:\r
407 ASSERT(0);\r
408 break;\r
409 case MmcHwInitializationState:\r
410 // If device already turn on then restart it\r
411 Data32 = MmioRead32(MCI_POWER_CONTROL_REG);\r
412 if ((Data32 & 0x2) == MCI_POWER_UP) {\r
413 MCI_TRACE("MciNotifyState(MmcHwInitializationState): TurnOff MCI");\r
414\r
415 // Turn off\r
416 MmioWrite32(MCI_CLOCK_CONTROL_REG, 0);\r
417 MmioWrite32(MCI_POWER_CONTROL_REG, 0);\r
418 MicroSecondDelay(100);\r
419 }\r
420\r
421 MCI_TRACE("MciNotifyState(MmcHwInitializationState): TurnOn MCI");\r
422 // Setup clock\r
423 // - 0x1D = 29 => should be the clock divider to be less than 400kHz at MCLK = 24Mhz\r
424 MmioWrite32(MCI_CLOCK_CONTROL_REG,0x1D | MCI_CLOCK_ENABLE | MCI_CLOCK_POWERSAVE);\r
425 //MmioWrite32(MCI_CLOCK_CONTROL_REG,0x1D | MCI_CLOCK_ENABLE);\r
426\r
427 // Set the voltage\r
428 MmioWrite32(MCI_POWER_CONTROL_REG,MCI_POWER_OPENDRAIN | (15<<2));\r
429 MmioWrite32(MCI_POWER_CONTROL_REG,MCI_POWER_ROD | MCI_POWER_OPENDRAIN | (15<<2) | MCI_POWER_UP);\r
430 MicroSecondDelay(10);\r
431 MmioWrite32(MCI_POWER_CONTROL_REG,MCI_POWER_ROD | MCI_POWER_OPENDRAIN | (15<<2) | MCI_POWER_ON);\r
432 MicroSecondDelay(100);\r
433\r
434 // Set Data Length & Data Timer\r
435 MmioWrite32(MCI_DATA_TIMER_REG,0xFFFFF);\r
436 MmioWrite32(MCI_DATA_LENGTH_REG,8);\r
437\r
438 ASSERT((MmioRead32(MCI_POWER_CONTROL_REG) & 0x3) == MCI_POWER_ON);\r
439 break;\r
440 case MmcIdleState:\r
441 MCI_TRACE("MciNotifyState(MmcIdleState)");\r
442 break;\r
443 case MmcReadyState:\r
444 MCI_TRACE("MciNotifyState(MmcReadyState)");\r
445 break;\r
446 case MmcIdentificationState:\r
447 MCI_TRACE("MciNotifyState(MmcIdentificationState)");\r
448 break;\r
449 case MmcStandByState:{\r
450 volatile UINT32 PwrCtrlReg;\r
451 MCI_TRACE("MciNotifyState(MmcStandByState)");\r
452\r
453 // Enable MCICMD push-pull drive\r
454 PwrCtrlReg = MmioRead32(MCI_POWER_CONTROL_REG);\r
455 //Disable Open Drain output\r
456 PwrCtrlReg &=~(MCI_POWER_OPENDRAIN);\r
457 MmioWrite32(MCI_POWER_CONTROL_REG,PwrCtrlReg);\r
458\r
459 // Set MMCI0 clock to 4MHz (24MHz may be possible with cache enabled)\r
460 //\r
461 // Note: Increasing clock speed causes TX FIFO under-run errors.\r
462 // So careful when optimising this driver for higher performance.\r
463 //\r
464 MmioWrite32(MCI_CLOCK_CONTROL_REG,0x02 | MCI_CLOCK_ENABLE | MCI_CLOCK_POWERSAVE);\r
465 // Set MMCI0 clock to 24MHz (by bypassing the divider)\r
466 //MmioWrite32(MCI_CLOCK_CONTROL_REG,MCI_CLOCK_BYPASS | MCI_CLOCK_ENABLE);\r
467 break;\r
468 }\r
469 case MmcTransferState:\r
470 //MCI_TRACE("MciNotifyState(MmcTransferState)");\r
471 break;\r
472 case MmcSendingDataState:\r
473 MCI_TRACE("MciNotifyState(MmcSendingDataState)");\r
474 break;\r
475 case MmcReceiveDataState:\r
476 MCI_TRACE("MciNotifyState(MmcReceiveDataState)");\r
477 break;\r
478 case MmcProgrammingState:\r
479 MCI_TRACE("MciNotifyState(MmcProgrammingState)");\r
480 break;\r
481 case MmcDisconnectState:\r
482 MCI_TRACE("MciNotifyState(MmcDisconnectState)");\r
483 break;\r
484 default:\r
485 ASSERT(0);\r
486 }\r
487 return EFI_SUCCESS;\r
1bfda055 488}\r
489\r
838725ab 490EFI_GUID mPL180MciDevicePathGuid = EFI_CALLER_ID_GUID;\r
1bfda055 491\r
2ed2ed29 492EFI_STATUS\r
493MciBuildDevicePath (\r
494 IN EFI_DEVICE_PATH_PROTOCOL **DevicePath\r
495 )\r
496{\r
497 EFI_DEVICE_PATH_PROTOCOL *NewDevicePathNode;\r
1bfda055 498\r
2ed2ed29 499 NewDevicePathNode = CreateDeviceNode(HARDWARE_DEVICE_PATH,HW_VENDOR_DP,sizeof(VENDOR_DEVICE_PATH));\r
500 CopyGuid(&((VENDOR_DEVICE_PATH*)NewDevicePathNode)->Guid,&mPL180MciDevicePathGuid);\r
501\r
502 *DevicePath = NewDevicePathNode;\r
503 return EFI_SUCCESS;\r
1bfda055 504}\r
505\r
506EFI_MMC_HOST_PROTOCOL gMciHost = {\r
2ed2ed29 507 MciIsCardPresent,\r
508 MciIsReadOnly,\r
509 MciBuildDevicePath,\r
510 MciNotifyState,\r
511 MciSendCommand,\r
512 MciReceiveResponse,\r
513 MciReadBlockData,\r
514 MciWriteBlockData\r
1bfda055 515};\r
516\r
517EFI_STATUS\r
518PL180MciDxeInitialize (\r
519 IN EFI_HANDLE ImageHandle,\r
520 IN EFI_SYSTEM_TABLE *SystemTable\r
521 )\r
522{\r
523 EFI_STATUS Status;\r
524 EFI_HANDLE Handle = NULL;\r
525\r
526 MCI_TRACE("PL180MciDxeInitialize()");\r
527\r
528 //Publish Component Name, BlockIO protocol interfaces\r
529 Status = gBS->InstallMultipleProtocolInterfaces (\r
530 &Handle, \r
531 &gEfiMmcHostProtocolGuid, &gMciHost,\r
532 NULL\r
533 );\r
534 ASSERT_EFI_ERROR (Status);\r
535\r
536 return EFI_SUCCESS;\r
537}\r