1
0

sddwc.c 40 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649
  1. /*++
  2. Copyright (c) 2015 Minoca Corp.
  3. This file is licensed under the terms of the GNU General Public License
  4. version 3. Alternative licensing terms are available. Contact
  5. info@minocacorp.com for details. See the LICENSE file at the root of this
  6. project for complete licensing information.
  7. Module Name:
  8. sddwc.c
  9. Abstract:
  10. This module implements the library functionality for the DesignWare SD/MMC
  11. device.
  12. Author:
  13. Chris Stevens 16-Jul-2015
  14. Environment:
  15. Firmware
  16. --*/
  17. //
  18. // ------------------------------------------------------------------- Includes
  19. //
  20. #include <uefifw.h>
  21. #include <dev/sddwc.h>
  22. //
  23. // --------------------------------------------------------------------- Macros
  24. //
  25. //
  26. // ---------------------------------------------------------------- Definitions
  27. //
  28. //
  29. // ------------------------------------------------------ Data Type Definitions
  30. //
  31. //
  32. // ----------------------------------------------- Internal Function Prototypes
  33. //
  34. EFI_STATUS
  35. EfipSdDwcInitializeController (
  36. PEFI_SD_CONTROLLER Controller,
  37. VOID *Context,
  38. UINT32 Phase
  39. );
  40. EFI_STATUS
  41. EfipSdDwcResetController (
  42. PEFI_SD_CONTROLLER Controller,
  43. VOID *Context,
  44. UINT32 Flags
  45. );
  46. EFI_STATUS
  47. EfipSdDwcSendCommand (
  48. PEFI_SD_CONTROLLER Controller,
  49. VOID *Context,
  50. PSD_COMMAND Command
  51. );
  52. EFI_STATUS
  53. EfipSdDwcGetSetBusWidth (
  54. PEFI_SD_CONTROLLER Controller,
  55. VOID *Context,
  56. UINT16 *BusWidth,
  57. BOOLEAN Set
  58. );
  59. EFI_STATUS
  60. EfipSdDwcGetSetClockSpeed (
  61. PEFI_SD_CONTROLLER Controller,
  62. VOID *Context,
  63. UINT32 *ClockSpeed,
  64. BOOLEAN Set
  65. );
  66. EFI_STATUS
  67. EfipSdDwcReadData (
  68. PEFI_SD_CONTROLLER Controller,
  69. VOID *Context,
  70. VOID *Data,
  71. UINT32 Size
  72. );
  73. EFI_STATUS
  74. EfipSdDwcWriteData (
  75. PEFI_SD_CONTROLLER Controller,
  76. VOID *Context,
  77. VOID *Data,
  78. UINT32 Size
  79. );
  80. //
  81. // -------------------------------------------------------------------- Globals
  82. //
  83. SD_FUNCTION_TABLE EfiSdDwcFunctionTable = {
  84. EfipSdDwcInitializeController,
  85. EfipSdDwcResetController,
  86. EfipSdDwcSendCommand,
  87. EfipSdDwcGetSetBusWidth,
  88. EfipSdDwcGetSetClockSpeed
  89. };
  90. //
  91. // ------------------------------------------------------------------ Functions
  92. //
  93. PEFI_SD_DWC_CONTROLLER
  94. EfiSdDwcCreateController (
  95. PEFI_SD_DWC_INITIALIZATION_BLOCK Parameters
  96. )
  97. /*++
  98. Routine Description:
  99. This routine creates a new DesignWare SD controller object.
  100. Arguments:
  101. Parameters - Supplies a pointer to the parameters to use when creating the
  102. controller. This can be stack allocated, as the DesignWare SD device
  103. won't use this memory after this routine returns.
  104. Return Value:
  105. Returns a pointer to the controller structure on success.
  106. NULL on allocation failure or if a required parameter was not filled in.
  107. --*/
  108. {
  109. PEFI_SD_DWC_CONTROLLER Controller;
  110. PEFI_SD_CONTROLLER SdController;
  111. EFI_SD_INITIALIZATION_BLOCK SdParameters;
  112. EFI_STATUS Status;
  113. if (Parameters->ControllerBase == NULL) {
  114. return NULL;
  115. }
  116. SdController = NULL;
  117. Status = EfiAllocatePool(EfiBootServicesData,
  118. sizeof(EFI_SD_DWC_CONTROLLER),
  119. (VOID **)&Controller);
  120. if (EFI_ERROR(Status)) {
  121. goto CreateControllerEnd;
  122. }
  123. EfiSetMem(Controller, sizeof(EFI_SD_DWC_CONTROLLER), 0);
  124. Controller->ControllerBase = Parameters->ControllerBase;
  125. Controller->Voltages = Parameters->Voltages;
  126. Controller->HostCapabilities = Parameters->HostCapabilities;
  127. Controller->FundamentalClock = Parameters->FundamentalClock;
  128. if (Parameters->OverrideFunctionTable != NULL) {
  129. EfiCopyMem(&(Controller->OverrideFunctionTable),
  130. Parameters->OverrideFunctionTable,
  131. sizeof(SD_FUNCTION_TABLE));
  132. }
  133. Controller->OverrideContext = Parameters->OverrideContext;
  134. //
  135. // Forward this call onto the core SD library for creation.
  136. //
  137. EfiSetMem(&SdParameters, sizeof(EFI_SD_INITIALIZATION_BLOCK), 0);
  138. SdParameters.ConsumerContext = Controller;
  139. SdParameters.OverrideFunctionTable = &EfiSdDwcFunctionTable;
  140. SdParameters.Voltages = Parameters->Voltages;
  141. SdParameters.FundamentalClock = Parameters->FundamentalClock;
  142. SdParameters.HostCapabilities = Parameters->HostCapabilities;
  143. SdController = EfiSdCreateController(&SdParameters);
  144. if (SdController == NULL) {
  145. Status = EFI_OUT_OF_RESOURCES;
  146. goto CreateControllerEnd;
  147. }
  148. Controller->SdController = SdController;
  149. Status = EFI_SUCCESS;
  150. CreateControllerEnd:
  151. if (EFI_ERROR(Status)) {
  152. if (SdController != NULL) {
  153. EfiSdDestroyController(SdController);
  154. }
  155. if (Controller != NULL) {
  156. EfiFreePool(Controller);
  157. Controller = NULL;
  158. }
  159. }
  160. return Controller;
  161. }
  162. VOID
  163. EfiSdDwcDestroyController (
  164. PEFI_SD_DWC_CONTROLLER Controller
  165. )
  166. /*++
  167. Routine Description:
  168. This routine destroys a DesignWare SD controller object.
  169. Arguments:
  170. Controller - Supplies a pointer to the controller to destroy.
  171. Return Value:
  172. None.
  173. --*/
  174. {
  175. EfiSdDestroyController(Controller->SdController);
  176. EfiFreePool(Controller);
  177. return;
  178. }
  179. EFI_STATUS
  180. EfiSdDwcInitializeController (
  181. PEFI_SD_DWC_CONTROLLER Controller,
  182. BOOLEAN SoftReset
  183. )
  184. /*++
  185. Routine Description:
  186. This routine resets and initializes the DesignWare SD host controller.
  187. Arguments:
  188. Controller - Supplies a pointer to the controller to initialize.
  189. SoftReset - Supplies a boolean indicating whether or not to perform a soft
  190. reset on the controller.
  191. Return Value:
  192. Status code.
  193. --*/
  194. {
  195. EFI_STATUS Status;
  196. Status = EfiSdInitializeController(Controller->SdController, SoftReset);
  197. if (EFI_ERROR(Status)) {
  198. goto InitializeControllerEnd;
  199. }
  200. InitializeControllerEnd:
  201. return Status;
  202. }
  203. EFI_STATUS
  204. EfiSdDwcBlockIoPolled (
  205. PEFI_SD_DWC_CONTROLLER Controller,
  206. UINT64 BlockOffset,
  207. UINTN BlockCount,
  208. VOID *Buffer,
  209. BOOLEAN Write
  210. )
  211. /*++
  212. Routine Description:
  213. This routine performs a block I/O read or write using the CPU and not
  214. DMA.
  215. Arguments:
  216. Controller - Supplies a pointer to the controller.
  217. BlockOffset - Supplies the logical block address of the I/O.
  218. BlockCount - Supplies the number of blocks to read or write.
  219. Buffer - Supplies the virtual address of the I/O buffer.
  220. Write - Supplies a boolean indicating if this is a read operation (FALSE)
  221. or a write operation.
  222. Return Value:
  223. Status code.
  224. --*/
  225. {
  226. EFI_STATUS Status;
  227. Status = EfiSdBlockIoPolled(Controller->SdController,
  228. BlockOffset,
  229. BlockCount,
  230. Buffer,
  231. Write);
  232. return Status;
  233. }
  234. EFI_STATUS
  235. EfiSdDwcGetMediaParameters (
  236. PEFI_SD_DWC_CONTROLLER Controller,
  237. UINT64 *BlockCount,
  238. UINT32 *BlockSize
  239. )
  240. /*++
  241. Routine Description:
  242. This routine returns information about the media card.
  243. Arguments:
  244. Controller - Supplies a pointer to the controller.
  245. BlockCount - Supplies a pointer where the number of blocks in the user
  246. area of the medium will be returned.
  247. BlockSize - Supplies a pointer where the block size of the medium will be
  248. returned.
  249. Return Value:
  250. EFI_SUCCESS on success.
  251. EFI_NO_MEDIA if there is no card in the slot.
  252. --*/
  253. {
  254. EFI_STATUS Status;
  255. Status = EfiSdGetMediaParameters(Controller->SdController,
  256. BlockCount,
  257. BlockSize);
  258. return Status;
  259. }
  260. EFI_STATUS
  261. EfiSdDwcSetClockSpeed (
  262. PEFI_SD_DWC_CONTROLLER DwcController,
  263. UINT32 ClockSpeed
  264. )
  265. /*++
  266. Routine Description:
  267. This routine sets the controller's clock speed.
  268. Arguments:
  269. DwcController - Supplies a pointer to this DesignWare SD controller.
  270. ClockSpeed - Supplies the desired clock speed in Hertz.
  271. Return Value:
  272. Status code.
  273. --*/
  274. {
  275. UINT32 Divisor;
  276. EFI_STATUS Status;
  277. UINT64 Time;
  278. UINT64 Timeout;
  279. UINT32 Value;
  280. if (DwcController->FundamentalClock == 0) {
  281. return EFI_INVALID_PARAMETER;
  282. }
  283. //
  284. // Wait for the card to not be busy.
  285. //
  286. Timeout = EFI_SD_DWC_CONTROLLER_TIMEOUT;
  287. Time = 0;
  288. Status = EFI_TIMEOUT;
  289. do {
  290. Value = SD_DWC_READ_REGISTER(DwcController, SdDwcStatus);
  291. if ((Value & SD_DWC_STATUS_DATA_BUSY) == 0) {
  292. Status = EFI_SUCCESS;
  293. break;
  294. }
  295. EfiStall(50);
  296. Time += 50;
  297. } while (Time <= Timeout);
  298. if (EFI_ERROR(Status)) {
  299. return Status;
  300. }
  301. //
  302. // Disable all clocks.
  303. //
  304. SD_DWC_WRITE_REGISTER(DwcController, SdDwcClockEnable, 0);
  305. //
  306. // Send the command to indicate that the clock enable register is being
  307. // updated.
  308. //
  309. Value = SD_DWC_COMMAND_START |
  310. SD_DWC_COMMAND_UPDATE_CLOCK_REGISTERS |
  311. SD_DWC_COMMAND_WAIT_PREVIOUS_DATA_COMPLETE;
  312. SD_DWC_WRITE_REGISTER(DwcController, SdDwcCommand, Value);
  313. Timeout = EFI_SD_DWC_CONTROLLER_TIMEOUT;
  314. Time = 0;
  315. Status = EFI_TIMEOUT;
  316. do {
  317. Value = SD_DWC_READ_REGISTER(DwcController, SdDwcCommand);
  318. if ((Value & SD_DWC_COMMAND_START) == 0) {
  319. Status = EFI_SUCCESS;
  320. break;
  321. }
  322. EfiStall(50);
  323. Time += 50;
  324. } while (Time <= Timeout);
  325. if (EFI_ERROR(Status)) {
  326. return Status;
  327. }
  328. //
  329. // Get the appropriate divisor without going over the desired clock speed.
  330. //
  331. if (ClockSpeed >= DwcController->FundamentalClock) {
  332. Divisor = 0;
  333. } else {
  334. Divisor = 2;
  335. while (Divisor < SD_DWC_MAX_DIVISOR) {
  336. if ((DwcController->FundamentalClock / Divisor) <= ClockSpeed) {
  337. break;
  338. }
  339. Divisor += 2;
  340. }
  341. Divisor >>= 1;
  342. }
  343. SD_DWC_WRITE_REGISTER(DwcController, SdDwcClockDivider, Divisor);
  344. SD_DWC_WRITE_REGISTER(DwcController,
  345. SdDwcClockSource,
  346. SD_DWC_CLOCK_SOURCE_DIVIDER_0);
  347. //
  348. // Send the command to indicate that the clock source and divider are is
  349. // being updated.
  350. //
  351. Value = SD_DWC_COMMAND_START |
  352. SD_DWC_COMMAND_UPDATE_CLOCK_REGISTERS |
  353. SD_DWC_COMMAND_WAIT_PREVIOUS_DATA_COMPLETE;
  354. SD_DWC_WRITE_REGISTER(DwcController, SdDwcCommand, Value);
  355. Timeout = EFI_SD_DWC_CONTROLLER_TIMEOUT;
  356. Time = 0;
  357. Status = EFI_TIMEOUT;
  358. do {
  359. Value = SD_DWC_READ_REGISTER(DwcController, SdDwcCommand);
  360. if ((Value & SD_DWC_COMMAND_START) == 0) {
  361. Status = EFI_SUCCESS;
  362. break;
  363. }
  364. EfiStall(50);
  365. Time += 50;
  366. } while (Time <= Timeout);
  367. if (EFI_ERROR(Status)) {
  368. return Status;
  369. }
  370. //
  371. // Enable the clocks in lower power mode.
  372. //
  373. SD_DWC_WRITE_REGISTER(DwcController,
  374. SdDwcClockEnable,
  375. (SD_DWC_CLOCK_ENABLE_LOW_POWER |
  376. SD_DWC_CLOCK_ENABLE_ON));
  377. //
  378. // Send the command to indicate that the clock is enable register being
  379. // updated.
  380. //
  381. Value = SD_DWC_COMMAND_START |
  382. SD_DWC_COMMAND_UPDATE_CLOCK_REGISTERS |
  383. SD_DWC_COMMAND_WAIT_PREVIOUS_DATA_COMPLETE;
  384. SD_DWC_WRITE_REGISTER(DwcController, SdDwcCommand, Value);
  385. Timeout = EFI_SD_DWC_CONTROLLER_TIMEOUT;
  386. Time = 0;
  387. Status = EFI_TIMEOUT;
  388. do {
  389. Value = SD_DWC_READ_REGISTER(DwcController, SdDwcCommand);
  390. if ((Value & SD_DWC_COMMAND_START) == 0) {
  391. Status = EFI_SUCCESS;
  392. break;
  393. }
  394. EfiStall(50);
  395. Time += 50;
  396. } while (Time <= Timeout);
  397. if (EFI_ERROR(Status)) {
  398. return Status;
  399. }
  400. return EFI_SUCCESS;
  401. }
  402. EFI_STATUS
  403. EfipSdDwcInitializeController (
  404. PEFI_SD_CONTROLLER Controller,
  405. VOID *Context,
  406. UINT32 Phase
  407. )
  408. /*++
  409. Routine Description:
  410. This routine performs any controller specific initialization steps.
  411. Arguments:
  412. Controller - Supplies a pointer to the controller.
  413. Context - Supplies a context pointer passed to the SD/MMC library upon
  414. creation of the controller.
  415. Phase - Supplies the phase of initialization. Phase 0 happens after the
  416. initial software reset and Phase 1 happens after the bus width has been
  417. set to 1 and the speed to 400KHz.
  418. Return Value:
  419. Status code.
  420. --*/
  421. {
  422. PEFI_SD_DWC_CONTROLLER DwcController;
  423. UINT32 Mask;
  424. EFI_STATUS Status;
  425. UINT32 Value;
  426. UINT32 Voltage;
  427. DwcController = (PEFI_SD_DWC_CONTROLLER)Context;
  428. if (DwcController->OverrideFunctionTable.InitializeController != NULL) {
  429. Status = DwcController->OverrideFunctionTable.InitializeController(
  430. Controller,
  431. DwcController->OverrideContext,
  432. Phase);
  433. return Status;
  434. }
  435. //
  436. // Phase 0 is an early initialization phase that happens after the
  437. // controller has been set. It is used to gather capabilities and set
  438. // certain parameters in the hardware.
  439. //
  440. if (Phase == 0) {
  441. Mask = SD_DWC_CONTROL_FIFO_RESET | SD_DWC_CONTROL_CONTROLLER_RESET;
  442. SD_DWC_WRITE_REGISTER(DwcController, SdDwcControl, Mask);
  443. do {
  444. Value = SD_DWC_READ_REGISTER(DwcController, SdDwcControl);
  445. } while ((Value & Mask) != 0);
  446. //
  447. // Set the default burst length.
  448. //
  449. Value = (SD_DWC_BUS_MODE_BURST_LENGTH_16 <<
  450. SD_DWC_BUS_MODE_BURST_LENGTH_SHIFT) |
  451. SD_DWC_BUS_MODE_FIXED_BURST;
  452. SD_DWC_WRITE_REGISTER(DwcController, SdDwcBusMode, Value);
  453. //
  454. // Set the default FIFO threshold.
  455. //
  456. SD_DWC_WRITE_REGISTER(DwcController,
  457. SdDwcFifoThreshold,
  458. SD_DWC_FIFO_THRESHOLD_DEFAULT);
  459. //
  460. // Set the default timeout.
  461. //
  462. SD_DWC_WRITE_REGISTER(DwcController,
  463. SdDwcTimeout,
  464. SD_DWC_TIMEOUT_DEFAULT);
  465. //
  466. // Set the voltages based on the supported values supplied when the
  467. // controller was created.
  468. //
  469. Voltage = SD_DWC_READ_REGISTER(DwcController, SdDwcUhs);
  470. Voltage &= ~SD_DWC_UHS_VOLTAGE_MASK;
  471. if ((DwcController->Voltages &
  472. (SD_VOLTAGE_32_33 | SD_VOLTAGE_33_34)) ==
  473. (SD_VOLTAGE_32_33 | SD_VOLTAGE_33_34)) {
  474. Voltage |= SD_DWC_UHS_VOLTAGE_3V3;
  475. } else if ((DwcController->Voltages &
  476. (SD_VOLTAGE_165_195 | SD_VOLTAGE_18)) != 0) {
  477. Voltage |= SD_DWC_UHS_VOLTAGE_1V8;
  478. } else {
  479. Status = EFI_DEVICE_ERROR;
  480. goto InitializeControllerEnd;
  481. }
  482. SD_DWC_WRITE_REGISTER(DwcController, SdDwcUhs, Voltage);
  483. //
  484. // Phase 1 happens right before the initialization command sequence is
  485. // about to begin. The clock and bus width have been program and the device
  486. // is just about read to go.
  487. //
  488. } else if (Phase == 1) {
  489. //
  490. // Turn on the power.
  491. //
  492. SD_DWC_WRITE_REGISTER(DwcController, SdDwcPower, SD_DWC_POWER_ENABLE);
  493. //
  494. // Set the interrupt mask, clear any pending state, and enable the
  495. // interrupts.
  496. //
  497. SD_DWC_WRITE_REGISTER(DwcController, SdDwcInterruptMask, 0);
  498. SD_DWC_WRITE_REGISTER(DwcController,
  499. SdDwcInterruptStatus,
  500. SD_DWC_INTERRUPT_STATUS_ALL_MASK);
  501. Value = SD_DWC_READ_REGISTER(DwcController, SdDwcControl);
  502. Value |= SD_DWC_CONTROL_INTERRUPT_ENABLE;
  503. SD_DWC_WRITE_REGISTER(DwcController, SdDwcControl, Value);
  504. }
  505. Status = EFI_SUCCESS;
  506. InitializeControllerEnd:
  507. return Status;
  508. }
  509. EFI_STATUS
  510. EfipSdDwcResetController (
  511. PEFI_SD_CONTROLLER Controller,
  512. VOID *Context,
  513. UINT32 Flags
  514. )
  515. /*++
  516. Routine Description:
  517. This routine performs a soft reset of the SD controller.
  518. Arguments:
  519. Controller - Supplies a pointer to the controller.
  520. Context - Supplies a context pointer passed to the SD/MMC library upon
  521. creation of the controller.
  522. Flags - Supplies a bitmask of reset flags. See SD_RESET_FLAG_* for
  523. definitions.
  524. Return Value:
  525. Status code.
  526. --*/
  527. {
  528. PEFI_SD_DWC_CONTROLLER DwcController;
  529. UINT32 ResetMask;
  530. EFI_STATUS Status;
  531. UINT64 Time;
  532. UINT64 Timeout;
  533. UINT32 Value;
  534. DwcController = (PEFI_SD_DWC_CONTROLLER)Context;
  535. if (DwcController->OverrideFunctionTable.ResetController != NULL) {
  536. Status = DwcController->OverrideFunctionTable.ResetController(
  537. Controller,
  538. DwcController->OverrideContext,
  539. Flags);
  540. return Status;
  541. }
  542. //
  543. // Always reset the FIFO, but only reset the whole controller if the all
  544. // flag was specified.
  545. //
  546. ResetMask = SD_DWC_CONTROL_FIFO_RESET;
  547. if ((Flags & SD_RESET_FLAG_ALL) != 0) {
  548. ResetMask |= SD_DWC_CONTROL_CONTROLLER_RESET;
  549. }
  550. SD_DWC_WRITE_REGISTER(DwcController, SdDwcControl, ResetMask);
  551. Status = EFI_TIMEOUT;
  552. Timeout = EFI_SD_DWC_CONTROLLER_TIMEOUT;
  553. Time = 0;
  554. do {
  555. Value = SD_DWC_READ_REGISTER(DwcController, SdDwcControl);
  556. if ((Value & ResetMask) == 0) {
  557. Status = EFI_SUCCESS;
  558. break;
  559. }
  560. EfiStall(50);
  561. Time += 50;
  562. } while (Time <= Timeout);
  563. if (EFI_ERROR(Status)) {
  564. return Status;
  565. }
  566. return EFI_SUCCESS;
  567. }
  568. EFI_STATUS
  569. EfipSdDwcSendCommand (
  570. PEFI_SD_CONTROLLER Controller,
  571. VOID *Context,
  572. PSD_COMMAND Command
  573. )
  574. /*++
  575. Routine Description:
  576. This routine sends the given command to the card.
  577. Arguments:
  578. Controller - Supplies a pointer to the controller.
  579. Context - Supplies a context pointer passed to the SD/MMC library upon
  580. creation of the controller.
  581. Command - Supplies a pointer to the command parameters.
  582. Return Value:
  583. Status code.
  584. --*/
  585. {
  586. UINT32 CommandValue;
  587. PEFI_SD_DWC_CONTROLLER DwcController;
  588. UINT32 Flags;
  589. EFI_STATUS Status;
  590. UINT64 Time;
  591. UINT64 Timeout;
  592. UINT32 Value;
  593. DwcController = (PEFI_SD_DWC_CONTROLLER)Context;
  594. if (DwcController->OverrideFunctionTable.SendCommand != NULL) {
  595. Status = DwcController->OverrideFunctionTable.SendCommand(
  596. Controller,
  597. DwcController->OverrideContext,
  598. Command);
  599. return Status;
  600. }
  601. //
  602. // Wait for the last command to complete.
  603. //
  604. Value = SD_DWC_READ_REGISTER(DwcController, SdDwcStatus);
  605. if ((Value & SD_DWC_STATUS_FIFO_EMPTY) == 0) {
  606. Value = SD_DWC_READ_REGISTER(DwcController, SdDwcControl);
  607. Value |= SD_DWC_CONTROL_FIFO_RESET;
  608. SD_DWC_WRITE_REGISTER(DwcController, SdDwcControl, Value);
  609. Timeout = EFI_SD_DWC_CONTROLLER_TIMEOUT;
  610. Time = 0;
  611. Status = EFI_TIMEOUT;
  612. do {
  613. Value = SD_DWC_READ_REGISTER(DwcController, SdDwcControl);
  614. if ((Value & SD_DWC_CONTROL_FIFO_RESET) == 0) {
  615. Status = EFI_SUCCESS;
  616. break;
  617. }
  618. EfiStall(50);
  619. Time += 50;
  620. } while (Time <= Timeout);
  621. if (EFI_ERROR(Status)) {
  622. goto SendCommandEnd;
  623. }
  624. }
  625. //
  626. // Clear any old interrupt status.
  627. //
  628. SD_DWC_WRITE_REGISTER(DwcController,
  629. SdDwcInterruptStatus,
  630. SD_DWC_INTERRUPT_STATUS_ALL_MASK);
  631. //
  632. // Set up the response flags.
  633. //
  634. Flags = SD_DWC_COMMAND_WAIT_PREVIOUS_DATA_COMPLETE;
  635. if (Command->Command == SdCommandReset) {
  636. Flags |= SD_DWC_COMMAND_SEND_INITIALIZATION;
  637. }
  638. if ((Command->ResponseType & SD_RESPONSE_PRESENT) != 0) {
  639. if ((Command->ResponseType & SD_RESPONSE_136_BIT) != 0) {
  640. Flags |= SD_DWC_COMMAND_LONG_RESPONSE;
  641. }
  642. Flags |= SD_DWC_COMMAND_RESPONSE_EXPECTED;
  643. }
  644. //
  645. // Set up the remainder of the command flags.
  646. //
  647. if ((Command->ResponseType & SD_RESPONSE_VALID_CRC) != 0) {
  648. Flags |= SD_DWC_COMMAND_CHECK_RESPONSE_CRC;
  649. }
  650. //
  651. // If there's a data buffer, program the block count.
  652. //
  653. if (Command->BufferSize != 0) {
  654. Flags |= SD_DWC_COMMAND_DATA_EXPECTED;
  655. if (Command->Write != FALSE) {
  656. Flags |= SD_DWC_COMMAND_WRITE;
  657. } else {
  658. Flags |= SD_DWC_COMMAND_READ;
  659. }
  660. //
  661. // If reading or writing multiple blocks, the block size register
  662. // should be set to the default block size and the byte count should be
  663. // a multiple of the block size.
  664. //
  665. if ((Command->Command == SdCommandReadMultipleBlocks) ||
  666. (Command->Command == SdCommandWriteMultipleBlocks)) {
  667. if ((DwcController->HostCapabilities & SD_MODE_AUTO_CMD12) != 0) {
  668. Flags |= SD_DWC_COMMAND_SEND_AUTO_STOP;
  669. }
  670. SD_DWC_WRITE_REGISTER(DwcController,
  671. SdDwcBlockSize,
  672. SD_DWC_BLOCK_SIZE);
  673. SD_DWC_WRITE_REGISTER(DwcController,
  674. SdDwcByteCount,
  675. Command->BufferSize);
  676. //
  677. // Otherwise set the block size to total number of bytes to be
  678. // processed.
  679. //
  680. } else {
  681. SD_DWC_WRITE_REGISTER(DwcController,
  682. SdDwcBlockSize,
  683. Command->BufferSize);
  684. SD_DWC_WRITE_REGISTER(DwcController,
  685. SdDwcByteCount,
  686. Command->BufferSize);
  687. }
  688. }
  689. SD_DWC_WRITE_REGISTER(DwcController, SdDwcTimeout, 0xFFFFFFFF);
  690. //
  691. // Write the command argument.
  692. //
  693. SD_DWC_WRITE_REGISTER(DwcController,
  694. SdDwcCommandArgument,
  695. Command->CommandArgument);
  696. //
  697. // Set the command and wait for it to be accepted.
  698. //
  699. CommandValue = (Command->Command << SD_DWC_COMMAND_INDEX_SHIFT) &
  700. SD_DWC_COMMAND_INDEX_MASK;
  701. CommandValue |= SD_DWC_COMMAND_START |
  702. SD_DWC_COMMAND_USE_HOLD_REGISTER |
  703. Flags;
  704. SD_DWC_WRITE_REGISTER(DwcController, SdDwcCommand, CommandValue);
  705. Timeout = EFI_SD_DWC_CONTROLLER_TIMEOUT;
  706. Time = 0;
  707. Status = EFI_TIMEOUT;
  708. do {
  709. Value = SD_DWC_READ_REGISTER(DwcController, SdDwcCommand);
  710. if ((Value & SD_DWC_COMMAND_START) == 0) {
  711. Status = EFI_SUCCESS;
  712. break;
  713. }
  714. EfiStall(50);
  715. Time += 50;
  716. } while (Time <= Timeout);
  717. if (EFI_ERROR(Status)) {
  718. goto SendCommandEnd;
  719. }
  720. //
  721. // Check the interrupt status.
  722. //
  723. Timeout = EFI_SD_DWC_CONTROLLER_TIMEOUT;
  724. Time = 0;
  725. Status = EFI_TIMEOUT;
  726. do {
  727. Value = SD_DWC_READ_REGISTER(DwcController, SdDwcInterruptStatus);
  728. if ((Value & SD_DWC_INTERRUPT_STATUS_COMMAND_DONE) != 0) {
  729. Status = EFI_SUCCESS;
  730. break;
  731. }
  732. EfiStall(50);
  733. Time += 50;
  734. } while (Time <= Timeout);
  735. if (EFI_ERROR(Status)) {
  736. goto SendCommandEnd;
  737. }
  738. if ((Value & SD_DWC_INTERRUPT_STATUS_ERROR_RESPONSE_TIMEOUT) != 0) {
  739. SD_DWC_WRITE_REGISTER(DwcController,
  740. SdDwcInterruptStatus,
  741. SD_DWC_INTERRUPT_STATUS_ALL_MASK);
  742. EfipSdDwcResetController(Controller,
  743. DwcController,
  744. SD_RESET_FLAG_COMMAND_LINE);
  745. Status = EFI_TIMEOUT;
  746. goto SendCommandEnd;
  747. } else if ((Value & SD_DWC_INTERRUPT_STATUS_COMMAND_ERROR_MASK) != 0) {
  748. SD_DWC_WRITE_REGISTER(DwcController,
  749. SdDwcInterruptStatus,
  750. SD_DWC_INTERRUPT_STATUS_ALL_MASK);
  751. Status = EFI_DEVICE_ERROR;
  752. goto SendCommandEnd;
  753. }
  754. //
  755. // Acknowledge the completed command.
  756. //
  757. SD_DWC_WRITE_REGISTER(DwcController,
  758. SdDwcInterruptStatus,
  759. SD_DWC_INTERRUPT_STATUS_COMMAND_DONE);
  760. //
  761. // Get the response if there is one.
  762. //
  763. if ((Command->ResponseType & SD_RESPONSE_PRESENT) != 0) {
  764. if ((Command->ResponseType & SD_RESPONSE_136_BIT) != 0) {
  765. Command->Response[3] = SD_DWC_READ_REGISTER(DwcController,
  766. SdDwcResponse0);
  767. Command->Response[2] = SD_DWC_READ_REGISTER(DwcController,
  768. SdDwcResponse1);
  769. Command->Response[1] = SD_DWC_READ_REGISTER(DwcController,
  770. SdDwcResponse2);
  771. Command->Response[0] = SD_DWC_READ_REGISTER(DwcController,
  772. SdDwcResponse3);
  773. if ((DwcController->HostCapabilities &
  774. SD_MODE_RESPONSE136_SHIFTED) != 0) {
  775. Command->Response[0] = (Command->Response[0] << 8) |
  776. ((Command->Response[1] >> 24) & 0xFF);
  777. Command->Response[1] = (Command->Response[1] << 8) |
  778. ((Command->Response[2] >> 24) & 0xFF);
  779. Command->Response[2] = (Command->Response[2] << 8) |
  780. ((Command->Response[3] >> 24) & 0xFF);
  781. Command->Response[3] = Command->Response[3] << 8;
  782. }
  783. } else {
  784. Command->Response[0] = SD_DWC_READ_REGISTER(DwcController,
  785. SdDwcResponse0);
  786. }
  787. }
  788. //
  789. // Read/write the data.
  790. //
  791. if (Command->BufferSize != 0) {
  792. if (Command->Write != FALSE) {
  793. Status = EfipSdDwcWriteData(Controller,
  794. Context,
  795. Command->Buffer,
  796. Command->BufferSize);
  797. } else {
  798. Status = EfipSdDwcReadData(Controller,
  799. Context,
  800. Command->Buffer,
  801. Command->BufferSize);
  802. }
  803. if (EFI_ERROR(Status)) {
  804. goto SendCommandEnd;
  805. }
  806. }
  807. Status = EFI_SUCCESS;
  808. SendCommandEnd:
  809. return Status;
  810. }
  811. EFI_STATUS
  812. EfipSdDwcGetSetBusWidth (
  813. PEFI_SD_CONTROLLER Controller,
  814. VOID *Context,
  815. UINT16 *BusWidth,
  816. BOOLEAN Set
  817. )
  818. /*++
  819. Routine Description:
  820. This routine gets or sets the controller's bus width.
  821. Arguments:
  822. Controller - Supplies a pointer to the controller.
  823. Context - Supplies a context pointer passed to the SD/MMC library upon
  824. creation of the controller.
  825. BusWidth - Supplies a pointer that receives bus width information on get
  826. and contains bus width information on set.
  827. Set - Supplies a boolean indicating whether the bus width should be queried
  828. or set.
  829. Return Value:
  830. Status code.
  831. --*/
  832. {
  833. PEFI_SD_DWC_CONTROLLER DwcController;
  834. EFI_STATUS Status;
  835. UINT32 Value;
  836. DwcController = (PEFI_SD_DWC_CONTROLLER)Context;
  837. if (DwcController->OverrideFunctionTable.GetSetBusWidth != NULL) {
  838. Status = DwcController->OverrideFunctionTable.GetSetBusWidth(
  839. Controller,
  840. DwcController->OverrideContext,
  841. BusWidth,
  842. Set);
  843. return Status;
  844. }
  845. if (Set != FALSE) {
  846. switch (*BusWidth) {
  847. case 1:
  848. Value = SD_DWC_CARD_TYPE_1_BIT_WIDTH;
  849. break;
  850. case 4:
  851. Value = SD_DWC_CARD_TYPE_4_BIT_WIDTH;
  852. break;
  853. case 8:
  854. Value = SD_DWC_CARD_TYPE_8_BIT_WIDTH;
  855. break;
  856. default:
  857. return EFI_INVALID_PARAMETER;
  858. }
  859. SD_DWC_WRITE_REGISTER(DwcController, SdDwcCardType, Value);
  860. } else {
  861. Value = SD_DWC_READ_REGISTER(DwcController, SdDwcCardType);
  862. if ((Value & SD_DWC_CARD_TYPE_8_BIT_WIDTH) != 0) {
  863. *BusWidth = 8;
  864. } else if ((Value & SD_DWC_CARD_TYPE_4_BIT_WIDTH) != 0) {
  865. *BusWidth = 4;
  866. } else {
  867. *BusWidth = 1;
  868. }
  869. }
  870. return EFI_SUCCESS;
  871. }
  872. EFI_STATUS
  873. EfipSdDwcGetSetClockSpeed (
  874. PEFI_SD_CONTROLLER Controller,
  875. VOID *Context,
  876. UINT32 *ClockSpeed,
  877. BOOLEAN Set
  878. )
  879. /*++
  880. Routine Description:
  881. This routine gets or sets the controller's clock speed.
  882. Arguments:
  883. Controller - Supplies a pointer to the controller.
  884. Context - Supplies a context pointer passed to the SD/MMC library upon
  885. creation of the controller.
  886. ClockSpeed - Supplies a pointer that receives the current clock speed on
  887. get and contains the desired clock speed on set.
  888. Set - Supplies a boolean indicating whether the bus width should be queried
  889. or set.
  890. Return Value:
  891. Status code.
  892. --*/
  893. {
  894. PEFI_SD_DWC_CONTROLLER DwcController;
  895. EFI_STATUS Status;
  896. DwcController = (PEFI_SD_DWC_CONTROLLER)Context;
  897. if (DwcController->OverrideFunctionTable.GetSetClockSpeed != NULL) {
  898. Status = DwcController->OverrideFunctionTable.GetSetClockSpeed(
  899. Controller,
  900. DwcController->OverrideContext,
  901. ClockSpeed,
  902. Set);
  903. return Status;
  904. }
  905. if (DwcController->FundamentalClock == 0) {
  906. return EFI_INVALID_PARAMETER;
  907. }
  908. //
  909. // Getting the clock speed is not implemented as the divisor math might not
  910. // work out precisely in reverse.
  911. //
  912. if (Set == FALSE) {
  913. return EFI_UNSUPPORTED;
  914. }
  915. return EfiSdDwcSetClockSpeed(DwcController, *ClockSpeed);
  916. }
  917. //
  918. // --------------------------------------------------------- Internal Functions
  919. //
  920. EFI_STATUS
  921. EfipSdDwcReadData (
  922. PEFI_SD_CONTROLLER Controller,
  923. VOID *Context,
  924. VOID *Data,
  925. UINT32 Size
  926. )
  927. /*++
  928. Routine Description:
  929. This routine reads polled data from the SD controller.
  930. Arguments:
  931. Controller - Supplies a pointer to the controller.
  932. Context - Supplies a context pointer passed to the SD/MMC library upon
  933. creation of the controller.
  934. Data - Supplies a pointer to the buffer where the data will be read into.
  935. Size - Supplies the size in bytes. This must be a multiple of four bytes.
  936. Return Value:
  937. Status code.
  938. --*/
  939. {
  940. UINT32 *Buffer32;
  941. UINT32 BusyMask;
  942. UINT32 Count;
  943. UINT32 DataReadyMask;
  944. BOOLEAN DataTransferOver;
  945. PEFI_SD_DWC_CONTROLLER DwcController;
  946. UINT32 Interrupts;
  947. UINT32 IoIndex;
  948. EFI_STATUS Status;
  949. UINT64 Time;
  950. UINT64 Timeout;
  951. UINT32 Value;
  952. DwcController = (PEFI_SD_DWC_CONTROLLER)Context;
  953. DataTransferOver = FALSE;
  954. Buffer32 = (UINT32 *)Data;
  955. Size /= sizeof(UINT32);
  956. while (Size != 0) {
  957. //
  958. // Get the interrupt status register.
  959. //
  960. Time = 0;
  961. Timeout = EFI_SD_DWC_CONTROLLER_TIMEOUT;
  962. Status = EFI_TIMEOUT;
  963. do {
  964. Interrupts = SD_DWC_READ_REGISTER(DwcController,
  965. SdDwcInterruptStatus);
  966. if (Interrupts != 0) {
  967. Status = EFI_SUCCESS;
  968. break;
  969. }
  970. EfiStall(50);
  971. Time += 50;
  972. } while (Time <= Timeout);
  973. if (EFI_ERROR(Status)) {
  974. return Status;
  975. }
  976. //
  977. // Reset the controller if any error bits are set.
  978. //
  979. if ((Interrupts & SD_DWC_INTERRUPT_STATUS_DATA_ERROR_MASK) != 0) {
  980. EfipSdDwcResetController(Controller,
  981. Context,
  982. SD_RESET_FLAG_DATA_LINE);
  983. return EFI_DEVICE_ERROR;
  984. }
  985. //
  986. // Check for received data status. If data is ready, the status
  987. // register holds the number of 32-bit elements to be read.
  988. //
  989. DataReadyMask = SD_DWC_INTERRUPT_STATUS_RECEIVE_FIFO_DATA_REQUEST;
  990. if ((Interrupts & DataReadyMask) != 0) {
  991. Count = SD_DWC_READ_REGISTER(DwcController, SdDwcStatus);
  992. Count = (Count & SD_DWC_STATUS_FIFO_COUNT_MASK) >>
  993. SD_DWC_STATUS_FIFO_COUNT_SHIFT;
  994. for (IoIndex = 0; IoIndex < Count; IoIndex += 1) {
  995. *Buffer32 = SD_DWC_READ_REGISTER(DwcController, SdDwcFifoBase);
  996. Buffer32 += 1;
  997. }
  998. Size -= Count;
  999. SD_DWC_WRITE_REGISTER(DwcController,
  1000. SdDwcInterruptStatus,
  1001. DataReadyMask);
  1002. }
  1003. //
  1004. // Check for the transfer over bit. If it is set, then read the rest of
  1005. // the bytes from the FIFO.
  1006. //
  1007. if ((Interrupts & SD_DWC_INTERRUPT_STATUS_DATA_TRANSFER_OVER) != 0) {
  1008. for (IoIndex = 0; IoIndex < Size; IoIndex += 1) {
  1009. *Buffer32 = SD_DWC_READ_REGISTER(DwcController, SdDwcFifoBase);
  1010. Buffer32 += 1;
  1011. }
  1012. SD_DWC_WRITE_REGISTER(DwcController,
  1013. SdDwcInterruptStatus,
  1014. SD_DWC_INTERRUPT_STATUS_DATA_TRANSFER_OVER);
  1015. Size = 0;
  1016. DataTransferOver = TRUE;
  1017. break;
  1018. }
  1019. }
  1020. //
  1021. // If the data transfer over interrupt has not yet been seen, wait for it
  1022. // to be asserted.
  1023. //
  1024. if (DataTransferOver == FALSE) {
  1025. Time = 0;
  1026. Timeout = EFI_SD_DWC_CONTROLLER_TIMEOUT;
  1027. Status = EFI_TIMEOUT;
  1028. do {
  1029. Interrupts = SD_DWC_READ_REGISTER(DwcController,
  1030. SdDwcInterruptStatus);
  1031. if ((Interrupts &
  1032. SD_DWC_INTERRUPT_STATUS_DATA_TRANSFER_OVER) != 0) {
  1033. Status = EFI_SUCCESS;
  1034. break;
  1035. }
  1036. EfiStall(50);
  1037. Time += 50;
  1038. } while (Time <= Timeout);
  1039. if (EFI_ERROR(Status)) {
  1040. return Status;
  1041. }
  1042. SD_DWC_WRITE_REGISTER(DwcController,
  1043. SdDwcInterruptStatus,
  1044. SD_DWC_INTERRUPT_STATUS_DATA_TRANSFER_OVER);
  1045. }
  1046. //
  1047. // Wait until the state machine and data stop being busy.
  1048. //
  1049. Timeout = EFI_SD_DWC_CONTROLLER_TIMEOUT;
  1050. Time = 0;
  1051. Status = EFI_TIMEOUT;
  1052. BusyMask = SD_DWC_STATUS_DATA_STATE_MACHINE_BUSY |
  1053. SD_DWC_STATUS_DATA_BUSY;
  1054. do {
  1055. Value = SD_DWC_READ_REGISTER(DwcController, SdDwcStatus);
  1056. if ((Value & BusyMask) == 0) {
  1057. Status = EFI_SUCCESS;
  1058. break;
  1059. }
  1060. EfiStall(50);
  1061. Time += 50;
  1062. } while (Time <= Timeout);
  1063. if (EFI_ERROR(Status)) {
  1064. return Status;
  1065. }
  1066. return EFI_SUCCESS;
  1067. }
  1068. EFI_STATUS
  1069. EfipSdDwcWriteData (
  1070. PEFI_SD_CONTROLLER Controller,
  1071. VOID *Context,
  1072. VOID *Data,
  1073. UINT32 Size
  1074. )
  1075. /*++
  1076. Routine Description:
  1077. This routine writes polled data to the SD controller.
  1078. Arguments:
  1079. Controller - Supplies a pointer to the controller.
  1080. Context - Supplies a context pointer passed to the SD/MMC library upon
  1081. creation of the controller.
  1082. Data - Supplies a pointer to the buffer containing the data to write.
  1083. Size - Supplies the size in bytes. This must be a multiple of 4 bytes.
  1084. Return Value:
  1085. Status code.
  1086. --*/
  1087. {
  1088. UINT32 *Buffer32;
  1089. UINT32 BusyMask;
  1090. UINT32 Count;
  1091. UINT32 DataRequestMask;
  1092. BOOLEAN DataTransferOver;
  1093. PEFI_SD_DWC_CONTROLLER DwcController;
  1094. UINT32 Interrupts;
  1095. UINT32 IoIndex;
  1096. EFI_STATUS Status;
  1097. UINT64 Time;
  1098. UINT64 Timeout;
  1099. UINT32 Value;
  1100. DwcController = (PEFI_SD_DWC_CONTROLLER)Context;
  1101. DataTransferOver = FALSE;
  1102. Buffer32 = (UINT32 *)Data;
  1103. Size /= sizeof(UINT32);
  1104. while (Size != 0) {
  1105. //
  1106. // Get the interrupt status register.
  1107. //
  1108. Time = 0;
  1109. Timeout = EFI_SD_DWC_CONTROLLER_TIMEOUT;
  1110. Status = EFI_TIMEOUT;
  1111. do {
  1112. Interrupts = SD_DWC_READ_REGISTER(DwcController,
  1113. SdDwcInterruptStatus);
  1114. if (Interrupts != 0) {
  1115. Status = EFI_SUCCESS;
  1116. break;
  1117. }
  1118. EfiStall(50);
  1119. Time += 50;
  1120. } while (Time <= Timeout);
  1121. if (EFI_ERROR(Status)) {
  1122. return Status;
  1123. }
  1124. //
  1125. // Reset the controller if any error bits are set.
  1126. //
  1127. if ((Interrupts & SD_DWC_INTERRUPT_STATUS_DATA_ERROR_MASK) != 0) {
  1128. EfipSdDwcResetController(Controller,
  1129. Context,
  1130. SD_RESET_FLAG_DATA_LINE);
  1131. return EFI_DEVICE_ERROR;
  1132. }
  1133. //
  1134. // If the controller is ready for data to be written, the number of
  1135. // 4-byte elements consumed in the FIFO is stored in the status
  1136. // register. The available bytes is the total FIFO size minus that
  1137. // amount.
  1138. //
  1139. DataRequestMask = SD_DWC_INTERRUPT_STATUS_TRANSMIT_FIFO_DATA_REQUEST;
  1140. if ((Interrupts & DataRequestMask) != 0) {
  1141. Count = SD_DWC_READ_REGISTER(DwcController, SdDwcStatus);
  1142. Count = (Count & SD_DWC_STATUS_FIFO_COUNT_MASK) >>
  1143. SD_DWC_STATUS_FIFO_COUNT_SHIFT;
  1144. Count = (SD_DWC_FIFO_DEPTH / sizeof(UINT32)) - Count;
  1145. for (IoIndex = 0; IoIndex < Count; IoIndex += 1) {
  1146. SD_DWC_WRITE_REGISTER(DwcController, SdDwcFifoBase, *Buffer32);
  1147. Buffer32 += 1;
  1148. }
  1149. Size -= Count;
  1150. SD_DWC_WRITE_REGISTER(DwcController,
  1151. SdDwcInterruptStatus,
  1152. DataRequestMask);
  1153. }
  1154. //
  1155. // Check for the transfer over bit. If it is set, then exit.
  1156. //
  1157. if ((Interrupts & SD_DWC_INTERRUPT_STATUS_DATA_TRANSFER_OVER) != 0) {
  1158. SD_DWC_WRITE_REGISTER(DwcController,
  1159. SdDwcInterruptStatus,
  1160. SD_DWC_INTERRUPT_STATUS_DATA_TRANSFER_OVER);
  1161. Size = 0;
  1162. DataTransferOver = TRUE;
  1163. break;
  1164. }
  1165. }
  1166. //
  1167. // If the data transfer over interrupt has not yet been seen, wait for it
  1168. // to be asserted.
  1169. //
  1170. if (DataTransferOver == FALSE) {
  1171. Timeout = EFI_SD_DWC_CONTROLLER_TIMEOUT;
  1172. Time = 0;
  1173. Status = EFI_TIMEOUT;
  1174. do {
  1175. Interrupts = SD_DWC_READ_REGISTER(DwcController,
  1176. SdDwcInterruptStatus);
  1177. if ((Interrupts &
  1178. SD_DWC_INTERRUPT_STATUS_DATA_TRANSFER_OVER) != 0) {
  1179. Status = EFI_SUCCESS;
  1180. break;
  1181. }
  1182. EfiStall(50);
  1183. Time += 50;
  1184. } while (Time <= Timeout);
  1185. if (EFI_ERROR(Status)) {
  1186. return Status;
  1187. }
  1188. SD_DWC_WRITE_REGISTER(DwcController,
  1189. SdDwcInterruptStatus,
  1190. SD_DWC_INTERRUPT_STATUS_DATA_TRANSFER_OVER);
  1191. }
  1192. //
  1193. // Wait until the state machine and data stop being busy.
  1194. //
  1195. Timeout = EFI_SD_DWC_CONTROLLER_TIMEOUT;
  1196. Time = 0;
  1197. Status = EFI_TIMEOUT;
  1198. BusyMask = SD_DWC_STATUS_DATA_STATE_MACHINE_BUSY |
  1199. SD_DWC_STATUS_DATA_BUSY;
  1200. do {
  1201. Value = SD_DWC_READ_REGISTER(DwcController, SdDwcStatus);
  1202. if ((Value & BusyMask) == 0) {
  1203. Status = EFI_SUCCESS;
  1204. break;
  1205. }
  1206. EfiStall(50);
  1207. Time += 50;
  1208. } while (Time <= Timeout);
  1209. if (EFI_ERROR(Status)) {
  1210. return Status;
  1211. }
  1212. return EFI_SUCCESS;
  1213. }