/** Send command SD_SEND_OP_COND to the device to see whether it is SDIO device. Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details. @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance. @param[in] Slot The slot number of the SD card to send the command to. @param[in] Rca The relative device address of addressed device. @param[in] VoltageWindow The supply voltage window. @param[in] S18R The boolean to show if it should switch to 1.8v. @param[in] Xpc The boolean to show if it should provide 0.36w power control. @param[in] Hcs The boolean to show if it support host capacity info. @param[out] Ocr The buffer to store returned OCR register value. @retval EFI_SUCCESS The operation is done correctly. @retval Others The operation fails. **/ EFI_STATUS SdCardSendOpCond ( IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru, IN UINT8 Slot, IN UINT16 Rca, IN UINT32 VoltageWindow, IN BOOLEAN S18R, IN BOOLEAN Xpc, IN BOOLEAN Hcs, OUT UINT32 *Ocr ) { EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk; EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk; EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet; EFI_STATUS Status; UINT32 Switch; UINT32 MaxPower; UINT32 HostCapacity; ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk)); ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk)); ZeroMem (&Packet, sizeof (Packet)); Packet.SdMmcCmdBlk = &SdMmcCmdBlk; Packet.SdMmcStatusBlk = &SdMmcStatusBlk; Packet.Timeout = SD_MMC_HC_GENERIC_TIMEOUT; SdMmcCmdBlk.CommandIndex = SD_APP_CMD; SdMmcCmdBlk.CommandType = SdMmcCommandTypeAc; SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1; SdMmcCmdBlk.CommandArgument = (UINT32)Rca << 16; Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL); if (EFI_ERROR (Status)) { return Status; } SdMmcCmdBlk.CommandIndex = SD_SEND_OP_COND; SdMmcCmdBlk.CommandType = SdMmcCommandTypeBcr; SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR3; Switch = S18R ? BIT24 : 0; MaxPower = Xpc ? BIT28 : 0; HostCapacity = Hcs ? BIT30 : 0; SdMmcCmdBlk.CommandArgument = (VoltageWindow & 0xFFFFFF) | Switch | MaxPower | HostCapacity; Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL); if (!EFI_ERROR (Status)) { // // For details, refer to SD Host Controller Simplified Spec 3.0 Table 2-12. // *Ocr = SdMmcStatusBlk.Resp0; } return Status; }
/** Send command SET_RELATIVE_ADDR to the SD device to assign a Relative device Address (RCA). Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details. @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance. @param[in] Slot The slot number of the SD card to send the command to. @param[out] Rca The relative device address to assign. @retval EFI_SUCCESS The operation is done correctly. @retval Others The operation fails. **/ EFI_STATUS SdCardSetRca ( IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru, IN UINT8 Slot, OUT UINT16 *Rca ) { EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk; EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk; EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet; EFI_STATUS Status; ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk)); ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk)); ZeroMem (&Packet, sizeof (Packet)); Packet.SdMmcCmdBlk = &SdMmcCmdBlk; Packet.SdMmcStatusBlk = &SdMmcStatusBlk; Packet.Timeout = SD_MMC_HC_GENERIC_TIMEOUT; SdMmcCmdBlk.CommandIndex = SD_SET_RELATIVE_ADDR; SdMmcCmdBlk.CommandType = SdMmcCommandTypeBcr; SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR6; Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL); if (!EFI_ERROR (Status)) { *Rca = (UINT16)(SdMmcStatusBlk.Resp0 >> 16); }
/** Send command GO_IDLE_STATE to the device to make it go to Idle State. Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details. @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance. @param[in] Slot The slot number of the SD card to send the command to. @retval EFI_SUCCESS The SD device is reset correctly. @retval Others The device reset fails. **/ EFI_STATUS SdCardReset ( IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru, IN UINT8 Slot ) { EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk; EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk; EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet; EFI_STATUS Status; ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk)); ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk)); ZeroMem (&Packet, sizeof (Packet)); Packet.SdMmcCmdBlk = &SdMmcCmdBlk; Packet.SdMmcStatusBlk = &SdMmcStatusBlk; Packet.Timeout = SD_MMC_HC_GENERIC_TIMEOUT; SdMmcCmdBlk.CommandIndex = SD_GO_IDLE_STATE; SdMmcCmdBlk.CommandType = SdMmcCommandTypeBc; Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL); return Status; }
/** Broadcast command ALL_SEND_CID to the bus to ask all the SD devices to send the data of their CID registers. Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details. @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance. @param[in] Slot The slot number of the SD card to send the command to. @retval EFI_SUCCESS The operation is done correctly. @retval Others The operation fails. **/ EFI_STATUS SdCardAllSendCid ( IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru, IN UINT8 Slot ) { EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk; EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk; EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet; EFI_STATUS Status; ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk)); ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk)); ZeroMem (&Packet, sizeof (Packet)); Packet.SdMmcCmdBlk = &SdMmcCmdBlk; Packet.SdMmcStatusBlk = &SdMmcStatusBlk; Packet.Timeout = SD_MMC_HC_GENERIC_TIMEOUT; SdMmcCmdBlk.CommandIndex = SD_ALL_SEND_CID; SdMmcCmdBlk.CommandType = SdMmcCommandTypeBcr; SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR2; Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL); return Status; }
/** Send command SEND_OP_COND to the EMMC device to get the data of the OCR register. Refer to EMMC Electrical Standard Spec 5.1 Section 6.4 for details. @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance. @param[in] Slot The slot number of the SD card to send the command to. @param[in, out] Argument On input, the argument of SEND_OP_COND is to send to the device. On output, the argument is the value of OCR register. @retval EFI_SUCCESS The operation is done correctly. @retval Others The operation fails. **/ EFI_STATUS EmmcGetOcr ( IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru, IN UINT8 Slot, IN OUT UINT32 *Argument ) { EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk; EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk; EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet; EFI_STATUS Status; ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk)); ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk)); ZeroMem (&Packet, sizeof (Packet)); Packet.SdMmcCmdBlk = &SdMmcCmdBlk; Packet.SdMmcStatusBlk = &SdMmcStatusBlk; Packet.Timeout = SD_MMC_HC_GENERIC_TIMEOUT; SdMmcCmdBlk.CommandIndex = EMMC_SEND_OP_COND; SdMmcCmdBlk.CommandType = SdMmcCommandTypeBcr; SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR3; SdMmcCmdBlk.CommandArgument = *Argument; Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL); if (!EFI_ERROR (Status)) { // // For details, refer to SD Host Controller Simplified Spec 3.0 Table 2-12. // *Argument = SdMmcStatusBlk.Resp0; } return Status; }
/** Send command SDIO_SEND_OP_COND to the device to see whether it is SDIO device. Refer to SDIO Simplified Spec 3 Section 3.2 for details. @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance. @param[in] Slot The slot number of the SD card to send the command to. @param[in] VoltageWindow The supply voltage window. @param[in] S18R The boolean to show if it should switch to 1.8v. @retval EFI_SUCCESS The operation is done correctly. @retval Others The operation fails. **/ EFI_STATUS SdioSendOpCond ( IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru, IN UINT8 Slot, IN UINT32 VoltageWindow, IN BOOLEAN S18R ) { EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk; EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk; EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet; EFI_STATUS Status; UINT32 Switch; ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk)); ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk)); ZeroMem (&Packet, sizeof (Packet)); Packet.SdMmcCmdBlk = &SdMmcCmdBlk; Packet.SdMmcStatusBlk = &SdMmcStatusBlk; Packet.Timeout = SD_MMC_HC_GENERIC_TIMEOUT; SdMmcCmdBlk.CommandIndex = SDIO_SEND_OP_COND; SdMmcCmdBlk.CommandType = SdMmcCommandTypeBcr; SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR4; Switch = S18R ? BIT24 : 0; SdMmcCmdBlk.CommandArgument = (VoltageWindow & 0xFFFFFF) | Switch; Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL); return Status; }
/** Send command SEND_STATUS to the addressed EMMC device to get its status register. Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details. @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance. @param[in] Slot The slot number of the SD card to send the command to. @param[in] Rca The relative device address of addressed device. @param[out] DevStatus The returned device status. @retval EFI_SUCCESS The operation is done correctly. @retval Others The operation fails. **/ EFI_STATUS EmmcSendStatus ( IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru, IN UINT8 Slot, IN UINT16 Rca, OUT UINT32 *DevStatus ) { EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk; EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk; EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet; EFI_STATUS Status; ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk)); ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk)); ZeroMem (&Packet, sizeof (Packet)); Packet.SdMmcCmdBlk = &SdMmcCmdBlk; Packet.SdMmcStatusBlk = &SdMmcStatusBlk; Packet.Timeout = SD_MMC_HC_GENERIC_TIMEOUT; SdMmcCmdBlk.CommandIndex = EMMC_SEND_STATUS; SdMmcCmdBlk.CommandType = SdMmcCommandTypeAc; SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1; SdMmcCmdBlk.CommandArgument = (UINT32)Rca << 16; Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL); if (!EFI_ERROR (Status)) { *DevStatus = SdMmcStatusBlk.Resp0; } return Status; }
/** Send command SWITCH to the EMMC device to switch the mode of operation of the selected Device or modifies the EXT_CSD registers. Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details. @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance. @param[in] Slot The slot number of the SD card to send the command to. @param[in] Access The access mode of SWTICH command. @param[in] Index The offset of the field to be access. @param[in] Value The value to be set to the specified field of EXT_CSD register. @param[in] CmdSet The value of CmdSet field of EXT_CSD register. @retval EFI_SUCCESS The operation is done correctly. @retval Others The operation fails. **/ EFI_STATUS EmmcSwitch ( IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru, IN UINT8 Slot, IN UINT8 Access, IN UINT8 Index, IN UINT8 Value, IN UINT8 CmdSet ) { EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk; EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk; EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet; EFI_STATUS Status; ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk)); ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk)); ZeroMem (&Packet, sizeof (Packet)); Packet.SdMmcCmdBlk = &SdMmcCmdBlk; Packet.SdMmcStatusBlk = &SdMmcStatusBlk; Packet.Timeout = SD_MMC_HC_GENERIC_TIMEOUT; SdMmcCmdBlk.CommandIndex = EMMC_SWITCH; SdMmcCmdBlk.CommandType = SdMmcCommandTypeAc; SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1b; SdMmcCmdBlk.CommandArgument = (Access << 24) | (Index << 16) | (Value << 8) | CmdSet; Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL); return Status; }
/** Send command SEND_EXT_CSD to the EMMC device to get the data of the EXT_CSD register. Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details. @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance. @param[in] Slot The slot number of the SD card to send the command to. @param[out] ExtCsd The buffer to store the content of the EXT_CSD register. @retval EFI_SUCCESS The operation is done correctly. @retval Others The operation fails. **/ EFI_STATUS EmmcGetExtCsd ( IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru, IN UINT8 Slot, OUT EMMC_EXT_CSD *ExtCsd ) { EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk; EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk; EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet; EFI_STATUS Status; ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk)); ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk)); ZeroMem (&Packet, sizeof (Packet)); Packet.SdMmcCmdBlk = &SdMmcCmdBlk; Packet.SdMmcStatusBlk = &SdMmcStatusBlk; Packet.Timeout = SD_MMC_HC_GENERIC_TIMEOUT; SdMmcCmdBlk.CommandIndex = EMMC_SEND_EXT_CSD; SdMmcCmdBlk.CommandType = SdMmcCommandTypeAdtc; SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1; SdMmcCmdBlk.CommandArgument = 0x00000000; Packet.InDataBuffer = ExtCsd; Packet.InTransferLength = sizeof (EMMC_EXT_CSD); Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL); return Status; }
/** Send command SEND_TUNING_BLOCK to the EMMC device for HS200 optimal sampling point detection. It may be sent up to 40 times until the host finishes the tuning procedure. Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 for details. @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance. @param[in] Slot The slot number of the SD card to send the command to. @param[in] BusWidth The bus width to work. @retval EFI_SUCCESS The operation is done correctly. @retval Others The operation fails. **/ EFI_STATUS EmmcSendTuningBlk ( IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru, IN UINT8 Slot, IN UINT8 BusWidth ) { EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk; EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk; EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet; EFI_STATUS Status; UINT8 TuningBlock[128]; ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk)); ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk)); ZeroMem (&Packet, sizeof (Packet)); Packet.SdMmcCmdBlk = &SdMmcCmdBlk; Packet.SdMmcStatusBlk = &SdMmcStatusBlk; Packet.Timeout = SD_MMC_HC_GENERIC_TIMEOUT; SdMmcCmdBlk.CommandIndex = EMMC_SEND_TUNING_BLOCK; SdMmcCmdBlk.CommandType = SdMmcCommandTypeAdtc; SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1; SdMmcCmdBlk.CommandArgument = 0; Packet.InDataBuffer = TuningBlock; if (BusWidth == 8) { Packet.InTransferLength = sizeof (TuningBlock); } else { Packet.InTransferLength = 64; } Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL); return Status; }
/** Send command SEND_IF_COND to the device to inquiry the SD Memory Card interface condition. Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details. @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance. @param[in] Slot The slot number of the SD card to send the command to. @param[in] SupplyVoltage The supplied voltage by the host. @param[in] CheckPattern The check pattern to be sent to the device. @retval EFI_SUCCESS The operation is done correctly. @retval Others The operation fails. **/ EFI_STATUS SdCardVoltageCheck ( IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru, IN UINT8 Slot, IN UINT8 SupplyVoltage, IN UINT8 CheckPattern ) { EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk; EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk; EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet; EFI_STATUS Status; ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk)); ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk)); ZeroMem (&Packet, sizeof (Packet)); Packet.SdMmcCmdBlk = &SdMmcCmdBlk; Packet.SdMmcStatusBlk = &SdMmcStatusBlk; Packet.Timeout = SD_MMC_HC_GENERIC_TIMEOUT; SdMmcCmdBlk.CommandIndex = SD_SEND_IF_COND; SdMmcCmdBlk.CommandType = SdMmcCommandTypeBcr; SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR7; SdMmcCmdBlk.CommandArgument = (SupplyVoltage << 8) | CheckPattern; Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL); if (!EFI_ERROR (Status)) { if (SdMmcStatusBlk.Resp0 != SdMmcCmdBlk.CommandArgument) { return EFI_DEVICE_ERROR; } } return Status; }
/** Send command SEND_CSD to the EMMC device to get the data of the CSD register. Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details. @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance. @param[in] Slot The slot number of the SD card to send the command to. @param[in] Rca The relative device address of selected device. @param[out] Csd The buffer to store the content of the CSD register. Note the caller should ignore the lowest byte of this buffer as the content of this byte is meaningless even if the operation succeeds. @retval EFI_SUCCESS The operation is done correctly. @retval Others The operation fails. **/ EFI_STATUS EmmcGetCsd ( IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru, IN UINT8 Slot, IN UINT16 Rca, OUT EMMC_CSD *Csd ) { EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk; EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk; EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet; EFI_STATUS Status; ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk)); ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk)); ZeroMem (&Packet, sizeof (Packet)); Packet.SdMmcCmdBlk = &SdMmcCmdBlk; Packet.SdMmcStatusBlk = &SdMmcStatusBlk; Packet.Timeout = SD_MMC_HC_GENERIC_TIMEOUT; SdMmcCmdBlk.CommandIndex = EMMC_SEND_CSD; SdMmcCmdBlk.CommandType = SdMmcCommandTypeAc; SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR2; SdMmcCmdBlk.CommandArgument = (UINT32)Rca << 16; Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL); if (!EFI_ERROR (Status)) { // // For details, refer to SD Host Controller Simplified Spec 3.0 Table 2-12. // CopyMem (((UINT8*)Csd) + 1, &SdMmcStatusBlk.Resp0, sizeof (EMMC_CSD) - 1); } return Status; }