From: "Leif Lindholm" <quic_llindhol@quicinc.com>
To: <caiyuqing_hz@163.com>
Cc: <devel@edk2.groups.io>, <sunilvl@ventanamicro.com>,
<libing1202@outlook.com>, <inochiama@outlook.com>
Subject: Re: [edk2-devel] [PATCH v3 3/8] Sophgo/SG2042Pkg: Add Sophgo SDHCI driver.
Date: Fri, 15 Sep 2023 15:23:06 +0100 [thread overview]
Message-ID: <ZQRoyg7q7jQqyomB@qc-i7.hemma.eciton.net> (raw)
In-Reply-To: <062132b714c4e151fe0348ba47de8d7c513a243d.1694010673.git.202235273@mail.sdu.edu.cn>
On Thu, Sep 07, 2023 at 18:25:46 +0800, caiyuqing_hz@163.com wrote:
> From: caiyuqing379 <202235273@mail.sdu.edu.cn>
>
> This driver implements Sophgo SDHCI controller, which provides
> the necessary interfaces for handling communication and data
> transfer with SD cards.
>
> Signed-off-by: caiyuqing379 <202235273@mail.sdu.edu.cn>
> Co-authored-by: USER0FISH <libing1202@outlook.com>
> Cc: dahogn <dahogn@hotmail.com>
> Cc: meng-cz <mengcz1126@gmail.com>
> Cc: yli147 <yong.li@intel.com>
> Cc: ChaiEvan <evan.chai@intel.com>
> Cc: Sunil V L <sunilvl@ventanamicro.com>
> Cc: Leif Lindholm <quic_llindhol@quicinc.com>
> ---
> .../SG2042Pkg/Drivers/SdHostDxe/SdHostDxe.inf | 47 +
> .../SG2042Pkg/Drivers/SdHostDxe/SdHci.h | 309 ++++++
> .../SG2042Pkg/Drivers/SdHostDxe/SdHci.c | 929 ++++++++++++++++++
> .../SG2042Pkg/Drivers/SdHostDxe/SdHostDxe.c | 450 +++++++++
> 4 files changed, 1735 insertions(+)
> create mode 100644 Silicon/Sophgo/SG2042Pkg/Drivers/SdHostDxe/SdHostDxe.inf
> create mode 100644 Silicon/Sophgo/SG2042Pkg/Drivers/SdHostDxe/SdHci.h
> create mode 100755 Silicon/Sophgo/SG2042Pkg/Drivers/SdHostDxe/SdHci.c
> create mode 100644 Silicon/Sophgo/SG2042Pkg/Drivers/SdHostDxe/SdHostDxe.c
>
> diff --git a/Silicon/Sophgo/SG2042Pkg/Drivers/SdHostDxe/SdHci.h b/Silicon/Sophgo/SG2042Pkg/Drivers/SdHostDxe/SdHci.h
> new file mode 100644
> index 000000000000..d9a9c88674e6
> --- /dev/null
> +++ b/Silicon/Sophgo/SG2042Pkg/Drivers/SdHostDxe/SdHci.h
> @@ -0,0 +1,309 @@
> +/** @file
> + The header file that provides definitions and function declarations
> + related to the SD Host Controller Interface (SDHCI) for SD card host controllers.
> +
> + Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
> + Copyright (c) 2023, Academy of Intelligent Innovation, Shandong Universiy, China.P.R. All rights reserved.<BR>
> + SPDX-License-Identifier: BSD-3-Clause
The license for this whole repository is BSD-2-Clause-Patent.
What is the origin code that this is based on?
> +
> +**/
> +
> +#ifndef _SD_HCI_H_
> +#define _SD_HCI_H_
> +
> +#define SDIO_BASE (FixedPcdGet64(PcdSG2042SDIOBase))
> +#define SDHCI_DMA_ADDRESS 0x00
> +#define SDHCI_BLOCK_SIZE 0x04
> +#define SDHCI_MAKE_BLKSZ(dma, blksz) ((((dma) & 0x7) << 12) | ((blksz) & 0xFFF))
> +#define SDHCI_BLOCK_COUNT 0x06
> +#define SDHCI_ARGUMENT 0x08
> +#define SDHCI_TRANSFER_MODE 0x0C
> +#define SDHCI_TRNS_DMA BIT0
> +#define SDHCI_TRNS_BLK_CNT_EN BIT1
> +#define SDHCI_TRNS_ACMD12 BIT2
> +#define SDHCI_TRNS_READ BIT4
> +#define SDHCI_TRNS_MULTI BIT5
> +#define SDHCI_TRNS_RESP_INT BIT8
> +#define SDHCI_COMMAND 0x0E
> +#define SDHCI_CMD_RESP_MASK 0x03
> +#define SDHCI_CMD_CRC 0x08
> +#define SDHCI_CMD_INDEX 0x10
> +#define SDHCI_CMD_DATA 0x20
> +#define SDHCI_CMD_ABORTCMD 0xC0
> +#define SDHCI_CMD_RESP_NONE 0x00
> +#define SDHCI_CMD_RESP_LONG 0x01
> +#define SDHCI_CMD_RESP_SHORT 0x02
> +#define SDHCI_CMD_RESP_SHORT_BUSY 0x03
> +#define SDHCI_MAKE_CMD(c, f) ((((c) & 0xff) << 8) | ((f) & 0xff))
> +#define SDHCI_RESPONSE_01 0x10
> +#define SDHCI_RESPONSE_23 0x14
> +#define SDHCI_RESPONSE_45 0x18
> +#define SDHCI_RESPONSE_67 0x1C
> +#define SDHCI_PSTATE 0x24
> +#define SDHCI_CMD_INHIBIT BIT0
> +#define SDHCI_CMD_INHIBIT_DAT BIT1
> +#define SDHCI_BUF_WR_ENABLE BIT10
> +#define SDHCI_BUF_RD_ENABLE BIT11
> +#define SDHCI_CARD_INSERTED BIT16
> +#define SDHCI_HOST_CONTROL 0x28
> +#define SDHCI_DAT_XFER_WIDTH BIT1
> +#define SDHCI_EXT_DAT_XFER BIT5
> +#define SDHCI_CTRL_DMA_MASK 0x18
> +#define SDHCI_CTRL_SDMA 0x00
> +#define SDHCI_PWR_CONTROL 0x29
> +#define SDHCI_BUS_VOL_VDD1_1_8V 0xC
> +#define SDHCI_BUS_VOL_VDD1_3_0V 0xE
> +#define SDHCI_BUF_DATA_R 0x20
> +#define SDHCI_BLOCK_GAP_CONTROL 0x2A
> +#define SDHCI_CLK_CTRL 0x2C
> +#define SDHCI_TOUT_CTRL 0x2E
> +#define SDHCI_SOFTWARE_RESET 0x2F
> +#define SDHCI_RESET_CMD 0x02
> +#define SDHCI_RESET_DATA 0x04
> +#define SDHCI_INT_STATUS 0x30
> +#define SDHCI_ERR_INT_STATUS 0x32
> +#define SDHCI_INT_CMD_COMPLETE BIT0
> +#define SDHCI_INT_XFER_COMPLETE BIT1
> +#define SDHCI_INT_DMA_END BIT3
> +#define SDHCI_INT_BUF_WR_READY BIT4
> +#define SDHCI_INT_BUF_RD_READY BIT5
> +#define SDHCI_INT_ERROR BIT15
> +#define SDHCI_INT_STATUS_EN 0x34
> +#define SDHCI_ERR_INT_STATUS_EN 0x36
> +#define SDHCI_INT_CMD_COMPLETE_EN BIT0
> +#define SDHCI_INT_XFER_COMPLETE_EN BIT1
> +#define SDHCI_INT_DMA_END_EN BIT3
> +#define SDHCI_INT_CARD_INSERTION_EN BIT6
> +#define SDHCI_INT_ERROR_EN BIT15
> +#define SDHCI_SIGNAL_ENABLE 0x38
> +#define SDHCI_HOST_CONTROL2 0x3E
> +#define SDHCI_HOST_VER4_ENABLE BIT12
> +#define SDHCI_CAPABILITIES1 0x40
> +#define SDHCI_CAPABILITIES2 0x44
> +#define SDHCI_ADMA_SA_LOW 0x58
> +#define SDHCI_ADMA_SA_HIGH 0x5C
> +#define SDHCI_HOST_CNTRL_VERS 0xFE
> +#define SDHCI_UHS_2_TIMER_CNTRL 0xC2
> +
> +#define P_VENDOR_SPECIFIC_AREA 0xE8
> +#define P_VENDOR2_SPECIFIC_AREA 0xEA
> +#define VENDOR_SD_CTRL 0x2C
> +
> +#define SDHCI_PHY_R_OFFSET 0x300
> +
> +#define SDHCI_P_PHY_CNFG (SDHCI_PHY_R_OFFSET + 0x00)
> +#define SDHCI_P_CMDPAD_CNFG (SDHCI_PHY_R_OFFSET + 0x04)
> +#define SDHCI_P_DATPAD_CNFG (SDHCI_PHY_R_OFFSET + 0x06)
> +#define SDHCI_P_CLKPAD_CNFG (SDHCI_PHY_R_OFFSET + 0x08)
> +#define SDHCI_P_STBPAD_CNFG (SDHCI_PHY_R_OFFSET + 0x0A)
> +#define SDHCI_P_RSTNPAD_CNFG (SDHCI_PHY_R_OFFSET + 0x0C)
> +#define SDHCI_P_PADTEST_CNFG (SDHCI_PHY_R_OFFSET + 0x0E)
> +#define SDHCI_P_PADTEST_OUT (SDHCI_PHY_R_OFFSET + 0x10)
> +#define SDHCI_P_PADTEST_IN (SDHCI_PHY_R_OFFSET + 0x12)
> +#define SDHCI_P_COMMDL_CNFG (SDHCI_PHY_R_OFFSET + 0x1C)
> +#define SDHCI_P_SDCLKDL_CNFG (SDHCI_PHY_R_OFFSET + 0x1D)
> +#define SDHCI_P_SDCLKDL_DC (SDHCI_PHY_R_OFFSET + 0x1E)
> +#define SDHCI_P_SMPLDL_CNFG (SDHCI_PHY_R_OFFSET + 0x20)
> +#define SDHCI_P_ATDL_CNFG (SDHCI_PHY_R_OFFSET + 0x21)
> +#define SDHCI_P_DLL_CTRL (SDHCI_PHY_R_OFFSET + 0x24)
> +#define SDHCI_P_DLL_CNFG1 (SDHCI_PHY_R_OFFSET + 0x25)
> +#define SDHCI_P_DLL_CNFG2 (SDHCI_PHY_R_OFFSET + 0x26)
> +#define SDHCI_P_DLLDL_CNFG (SDHCI_PHY_R_OFFSET + 0x28)
> +#define SDHCI_P_DLL_OFFST (SDHCI_PHY_R_OFFSET + 0x29)
> +#define SDHCI_P_DLLMST_TSTDC (SDHCI_PHY_R_OFFSET + 0x2A)
> +#define SDHCI_P_DLLLBT_CNFG (SDHCI_PHY_R_OFFSET + 0x2C)
> +#define SDHCI_P_DLL_STATUS (SDHCI_PHY_R_OFFSET + 0x2E)
> +#define SDHCI_P_DLLDBG_MLKDC (SDHCI_PHY_R_OFFSET + 0x30)
> +#define SDHCI_P_DLLDBG_SLKDC (SDHCI_PHY_R_OFFSET + 0x32)
> +
> +#define PHY_CNFG_PHY_RSTN 0
> +#define PHY_CNFG_PHY_PWRGOOD 1
> +#define PHY_CNFG_PAD_SP 16
> +#define PHY_CNFG_PAD_SP_MSK 0xf
> +#define PHY_CNFG_PAD_SN 20
> +#define PHY_CNFG_PAD_SN_MSK 0xf
> +
> +#define PAD_CNFG_RXSEL 0
> +#define PAD_CNFG_RXSEL_MSK 0x7
> +#define PAD_CNFG_WEAKPULL_EN 3
> +#define PAD_CNFG_WEAKPULL_EN_MSK 0x3
> +#define PAD_CNFG_TXSLEW_CTRL_P 5
> +#define PAD_CNFG_TXSLEW_CTRL_P_MSK 0xf
> +#define PAD_CNFG_TXSLEW_CTRL_N 9
> +#define PAD_CNFG_TXSLEW_CTRL_N_MSK 0xf
> +
> +#define COMMDL_CNFG_DLSTEP_SEL 0
> +#define COMMDL_CNFG_DLOUT_EN 1
> +
> +#define SDCLKDL_CNFG_EXTDLY_EN 0
> +#define SDCLKDL_CNFG_BYPASS_EN 1
> +#define SDCLKDL_CNFG_INPSEL_CNFG 2
> +#define SDCLKDL_CNFG_INPSEL_CNFG_MSK 0x3
> +#define SDCLKDL_CNFG_UPDATE_DC 4
> +
> +#define SMPLDL_CNFG_EXTDLY_EN 0
> +#define SMPLDL_CNFG_BYPASS_EN 1
> +#define SMPLDL_CNFG_INPSEL_CNFG 2
> +#define SMPLDL_CNFG_INPSEL_CNFG_MSK 0x3
> +#define SMPLDL_CNFG_INPSEL_OVERRIDE 4
> +
> +#define ATDL_CNFG_EXTDLY_EN 0
> +#define ATDL_CNFG_BYPASS_EN 1
> +#define ATDL_CNFG_INPSEL_CNFG 2
> +#define ATDL_CNFG_INPSEL_CNFG_MSK 0x3
> +
> +#define SD_USE_PIO 0x1
> +
> +/**
> + card detect status
> + -1: haven't check the card detect register
> + 0 : no card detected
> + 1 : card detected
> +**/
> +#define SDCARD_STATUS_UNKNOWN (-1)
> +#define SDCARD_STATUS_INSERTED (1)
> +#define SDCARD_STATUS_NOT_INSERTED (0)
> +
> +typedef struct {
> + UINT32 CmdIdx;
> + UINT32 CmdArg;
> + UINT32 ResponseType;
> + UINT32 Response[4];
> +} MMC_CMD;
> +
> +typedef struct {
> + UINTN RegBase;
> + UINTN VendorBase;
> + UINTN DescBase;
> + UINTN DescSize;
> + INT32 ClkRate;
> + INT32 BusWidth;
> + UINT32 Flags;
> + INT32 CardIn;
> +} BM_SD_PARAMS;
> +
> +extern BM_SD_PARAMS BmParams;
> +
> +/**
> + SD card sends command.
> +
> + @param[in] Idx Command ID.
> + @param[in] Arg Command argument.
> + @param[in] RespType Type of response data.
> + @param[out] Response Response data.
> +
> + @retval EFI_SUCCESS The command was sent successfully.
> + @retval EFI_DEVICE_ERROR There was an error during the command transmission or response handling.
> + @retval EFI_TIMEOUT The command transmission or response handling timed out.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +BmSdSendCmd (
> + IN UINT32 Idx,
> + IN UINT32 Arg,
> + IN UINT32 RespType,
> + OUT UINT32 *Response
> + );
> +
> +/**
> + Detect the status of the SD card.
> +
> + @return The status of the SD card:
> + - SDCARD_STATUS_INSERTED: The SD card is inserted.
> + - SDCARD_STATUS_NOT_INSERTED: The SD card is not inserted.
> + - SDCARD_STATUS_UNKNOWN: The status of the SD card is unknown.
> +
> +**/
> +INT32
> +BmSdCardDetect (
> + VOID
> + );
> +
> +/**
> + Set the input/output settings for the SD card.
> +
> + @param[in] Clk The clock frequency for the SD card.
> + @param[in] Width The bus width for data transfer.
> +
> + @retval EFI_SUCCESS The input/output settings were set successfully.
> + @retval EFI_UNSUPPORTED The specified bus width is not supported.
> +
> +**/
> +EFI_STATUS
> +BmSdSetIos (
> + IN UINT32 Clk,
> + IN UINT32 Width
> + );
> +
> +/**
> + Prepare the SD card for data transfer.
> + Set the number and size of data blocks before sending IO commands to the SD card.
> +
> + @param[in] Lba Logical Block Address.
> + @param[in] Buf Buffer Address.
> + @param[in] Size Size of Data Blocks.
> +
> + @retval EFI_SUCCESS The SD card was prepared successfully.
> + @retval Other An error occurred during the preparation of the SD card.
> +
> +**/
> +EFI_STATUS
> +BmSdPrepare (
> + IN INT32 Lba,
> + IN UINTN Buf,
> + IN UINTN Size
> + );
> +
> +/**
> + SD card sends command to read data blocks.
> +
> + @param[in] Lba Logical Block Address.
> + @param[in] Buf Buffer Address.
> + @param[in] Size Size of Data Blocks.
> +
> + @retval EFI_SUCCESS The command to read data blocks was sent successfully.
> + @retval EFI_TIMEOUT The command transmission or data transfer timed out.
> +
> +**/
> +EFI_STATUS
> +BmSdRead (
> + IN INT32 Lba,
> + IN UINT32* Buf,
> + IN UINTN Size
> + );
> +
> +/**
> + SD card sends commands to write data blocks.
> +
> + @param[in] Lba Logical Block Address.
> + @param[in] Buf Buffer Address.
> + @param[in] Size Size of Data Blocks.
> +
> + @retval EFI_SUCCESS The command to write data blocks was sent successfully.
> + @retval EFI_TIMEOUT The command transmission or data transfer timed out.
> +
> +**/
> +EFI_STATUS
> +BmSdWrite (
> + IN INT32 Lba,
> + IN UINT32* Buf,
> + IN UINTN Size
> + );
> +
> +/**
> + Initialize the SD card.
> +
> + This function performs the initialization of the SD card hardware and settings.
> +
> + @param[in] Flags Initialization flags.
> +
> + @retval EFI_SUCCESS The SD card was initialized successfully.
> +
> +**/
> +EFI_STATUS
> +SdInit (
> + IN UINT32 flags
> + );
> +
> +#endif
> diff --git a/Silicon/Sophgo/SG2042Pkg/Drivers/SdHostDxe/SdHci.c b/Silicon/Sophgo/SG2042Pkg/Drivers/SdHostDxe/SdHci.c
> new file mode 100755
> index 000000000000..efa9f6397a1e
> --- /dev/null
> +++ b/Silicon/Sophgo/SG2042Pkg/Drivers/SdHostDxe/SdHci.c
> @@ -0,0 +1,929 @@
> +/** @file
> + The implementation for handling SD card operations using the SD Host Controller Interface (SDHCI).
> +
> + Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
> + Copyright (c) 2023, Academy of Intelligent Innovation, Shandong Universiy, China.P.R. All rights reserved.<BR>
> + SPDX-License-Identifier: BSD-3-Clause
Same as above.
/
Leif
> +
> +**/
> +
> +#include <Uefi.h>
> +#include <Base.h>
> +#include <Library/BaseLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Include/MmcHost.h>
> +
> +#include "SdHci.h"
> +
> +#define SDCARD_INIT_FREQ (200 * 1000)
> +#define SDCARD_TRAN_FREQ (6 * 1000 * 1000)
> +
> +/**
> + Return the clock rate of SD card.
> +
> + @retval the clock rate of SD card.
> +
> +**/
> +INT32
> +BmGetSdClk (
> + VOID
> + )
> +{
> + return 100*1000*1000;
> +}
> +
> +/**
> + SD card sends command with response block data.
> +
> + @param Cmd Command sent by SD card.
> +
> + @retval EFI_SUCCESS The command with response block data was sent successfully.
> + @retval EFI_DEVICE_ERROR There was an error during the command transmission or response handling.
> + @retval EFI_TIMEOUT The command transmission or response handling timed out.
> +
> +**/
> +STATIC
> +EFI_STATUS
> +SdSendCmdWithData (
> + IN OUT MMC_CMD *Cmd
> + )
> +{
> + UINTN Base;
> + UINT32 Mode;
> + UINT32 State;
> + UINT32 DmaAddr;
> + UINT32 Flags;
> + UINT32 Timeout;
> +
> + Base = BmParams.RegBase;
> + Mode = 0;
> + Flags = 0;
> +
> + // Make sure Cmd line is clear
> + while (1) {
> + if (!(MmioRead32 (Base + SDHCI_PSTATE) & SDHCI_CMD_INHIBIT))
> + break;
> + }
> +
> + switch (Cmd->CmdIdx) {
> + case MMC_CMD17:
> + case MMC_CMD18:
> + case MMC_ACMD51:
> + Mode = SDHCI_TRNS_BLK_CNT_EN | SDHCI_TRNS_MULTI | SDHCI_TRNS_READ;
> + if (!(BmParams.Flags & SD_USE_PIO))
> + Mode |= SDHCI_TRNS_DMA;
> + break;
> + case MMC_CMD24:
> + case MMC_CMD25:
> + Mode = (SDHCI_TRNS_BLK_CNT_EN | SDHCI_TRNS_MULTI) & ~SDHCI_TRNS_READ;
> + if (!(BmParams.Flags & SD_USE_PIO))
> + Mode |= SDHCI_TRNS_DMA;
> + break;
> + default:
> + ASSERT(0);
> + }
> +
> + MmioWrite16 (Base + SDHCI_TRANSFER_MODE, Mode);
> + MmioWrite32 (Base + SDHCI_ARGUMENT, Cmd->CmdArg);
> +
> + // set Cmd Flags
> + if (Cmd->CmdIdx == MMC_CMD0)
> + Flags |= SDHCI_CMD_RESP_NONE;
> + else {
> + if (Cmd->ResponseType & MMC_RSP_136)
> + Flags |= SDHCI_CMD_RESP_LONG;
> + else
> + Flags |= SDHCI_CMD_RESP_SHORT;
> + if (Cmd->ResponseType & MMC_RSP_CRC)
> + Flags |= SDHCI_CMD_CRC;
> + if (Cmd->ResponseType & MMC_RSP_CMD_IDX)
> + Flags |= SDHCI_CMD_INDEX;
> + }
> +
> + Flags |= SDHCI_CMD_DATA;
> +
> + // issue the Cmd
> + MmioWrite16 (Base + SDHCI_COMMAND, SDHCI_MAKE_CMD(Cmd->CmdIdx, Flags));
> +
> + // check Cmd complete if necessary
> + if ((MmioRead16 (Base + SDHCI_TRANSFER_MODE) & SDHCI_TRNS_RESP_INT) == 0) {
> + Timeout = 100000;
> + while (1) {
> + State = MmioRead16 (Base + SDHCI_INT_STATUS);
> + if (State & SDHCI_INT_ERROR) {
> + DEBUG ((DEBUG_ERROR, "%a: interrupt error: 0x%x 0x%x\n", __func__, MmioRead16 (Base + SDHCI_INT_STATUS),
> + MmioRead16 (Base + SDHCI_ERR_INT_STATUS)));
> + return EFI_DEVICE_ERROR;
> + }
> + if (State & SDHCI_INT_CMD_COMPLETE) {
> + MmioWrite16 (Base + SDHCI_INT_STATUS, State | SDHCI_INT_CMD_COMPLETE);
> + break;
> + }
> +
> + gBS->Stall (1);
> + if (!Timeout--) {
> + DEBUG ((DEBUG_ERROR, "%a: Timeout!\n", __func__));
> + return EFI_TIMEOUT;
> + }
> + }
> +
> + // get Cmd respond
> + if (Flags != SDHCI_CMD_RESP_NONE)
> + Cmd->Response[0] = MmioRead32 (Base + SDHCI_RESPONSE_01);
> + if (Flags & SDHCI_CMD_RESP_LONG) {
> + Cmd->Response[1] = MmioRead32 (Base + SDHCI_RESPONSE_23);
> + Cmd->Response[2] = MmioRead32 (Base + SDHCI_RESPONSE_45);
> + Cmd->Response[3] = MmioRead32 (Base + SDHCI_RESPONSE_67);
> + }
> + }
> +
> + // check dma/transfer complete
> + if (!(BmParams.Flags & SD_USE_PIO)) {
> + while (1) {
> + State = MmioRead16 (Base + SDHCI_INT_STATUS);
> + if (State & SDHCI_INT_ERROR) {
> + DEBUG ((DEBUG_ERROR, "%a: interrupt error: 0x%x 0x%x\n", __func__, MmioRead16 (Base + SDHCI_INT_STATUS),
> + MmioRead16 (Base + SDHCI_ERR_INT_STATUS)));
> + return EFI_DEVICE_ERROR;
> + }
> +
> + if (State & SDHCI_INT_XFER_COMPLETE) {
> + MmioWrite16 (Base + SDHCI_INT_STATUS, State);
> + break;
> + }
> +
> + if (State & SDHCI_INT_DMA_END) {
> + MmioWrite16 (Base + SDHCI_INT_STATUS, State);
> + if (MmioRead16 (Base + SDHCI_HOST_CONTROL2) & SDHCI_HOST_VER4_ENABLE) {
> + DmaAddr = MmioRead32 (Base + SDHCI_ADMA_SA_LOW);
> + MmioWrite32 (Base + SDHCI_ADMA_SA_LOW, DmaAddr);
> + MmioWrite32 (Base + SDHCI_ADMA_SA_HIGH, 0);
> + } else {
> + DmaAddr = MmioRead32 (Base + SDHCI_DMA_ADDRESS);
> + MmioWrite32 (Base + SDHCI_DMA_ADDRESS, DmaAddr);
> + }
> + }
> +
> + }
> + }
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + SD card sends command without response block data.
> +
> + @param Cmd Command sent by SD card.
> +
> + @retval EFI_SUCCESS The command without response block data was sent successfully.
> + @retval EFI_DEVICE_ERROR There was an error during the command transmission or response handling.
> + @retval EFI_TIMEOUT The command transmission or response handling timed out.
> +
> +**/
> +STATIC
> +EFI_STATUS
> +SdSendCmdWithoutData (
> + IN OUT MMC_CMD *Cmd
> + )
> +{
> + UINTN Base;
> + UINT32 State;
> + UINT32 Flags;
> + UINT32 Timeout;
> +
> + Base = BmParams.RegBase;
> + Flags = 0x0;
> + Timeout = 10000;
> +
> + // make sure Cmd line is clear
> + while (1) {
> + if (!(MmioRead32 (Base + SDHCI_PSTATE) & SDHCI_CMD_INHIBIT))
> + break;
> + }
> +
> + // set Cmd Flags
> + if (Cmd->CmdIdx == MMC_CMD0)
> + Flags |= SDHCI_CMD_RESP_NONE;
> + else if (Cmd->CmdIdx == MMC_CMD1)
> + Flags |= SDHCI_CMD_RESP_SHORT;
> + else if (Cmd->CmdIdx == MMC_ACMD41)
> + Flags |= SDHCI_CMD_RESP_SHORT;
> + else {
> + if (Cmd->ResponseType & MMC_RSP_136)
> + Flags |= SDHCI_CMD_RESP_LONG;
> + else
> + Flags |= SDHCI_CMD_RESP_SHORT;
> + if (Cmd->ResponseType & MMC_RSP_CRC)
> + Flags |= SDHCI_CMD_CRC;
> + if (Cmd->ResponseType & MMC_RSP_CMD_IDX)
> + Flags |= SDHCI_CMD_INDEX;
> + }
> +
> + // make sure dat line is clear if necessary
> + if (Flags != SDHCI_CMD_RESP_NONE) {
> + while (1) {
> + if (!(MmioRead32 (Base + SDHCI_PSTATE) & SDHCI_CMD_INHIBIT_DAT))
> + break;
> + }
> + }
> +
> + // issue the Cmd
> + MmioWrite32 (Base + SDHCI_ARGUMENT, Cmd->CmdArg);
> + MmioWrite16 (Base + SDHCI_COMMAND, SDHCI_MAKE_CMD(Cmd->CmdIdx, Flags));
> +
> + // check Cmd complete
> + Timeout = 100000;
> + while (1) {
> + State = MmioRead16 (Base + SDHCI_INT_STATUS);
> + if (State & SDHCI_INT_ERROR) {
> + DEBUG ((DEBUG_ERROR, "%a: interrupt error: 0x%x 0x%x\n", __func__, MmioRead16 (Base + SDHCI_INT_STATUS),
> + MmioRead16 (Base + SDHCI_ERR_INT_STATUS)));
> + return EFI_DEVICE_ERROR;
> + }
> + if (State & SDHCI_INT_CMD_COMPLETE) {
> + MmioWrite16 (Base + SDHCI_INT_STATUS, State | SDHCI_INT_CMD_COMPLETE);
> + break;
> + }
> +
> + gBS->Stall (1);
> + if (!Timeout--) {
> + DEBUG ((DEBUG_ERROR, "%a: Timeout!\n", __func__));
> + return EFI_TIMEOUT;
> + }
> + }
> +
> + // get Cmd respond
> + if (!(Flags & SDHCI_CMD_RESP_NONE))
> + Cmd->Response[0] = MmioRead32 (Base + SDHCI_RESPONSE_01);
> + if (Flags & SDHCI_CMD_RESP_LONG) {
> + Cmd->Response[1] = MmioRead32 (Base + SDHCI_RESPONSE_23);
> + Cmd->Response[2] = MmioRead32 (Base + SDHCI_RESPONSE_45);
> + Cmd->Response[3] = MmioRead32 (Base + SDHCI_RESPONSE_67);
> + }
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + SD card sends command.
> +
> + @param[in] Idx Command ID.
> + @param[in] Arg Command argument.
> + @param[in] RespType Type of response data.
> + @param[out] Response Response data.
> +
> + @retval EFI_SUCCESS The command was sent successfully.
> + @retval EFI_DEVICE_ERROR There was an error during the command transmission or response handling.
> + @retval EFI_TIMEOUT The command transmission or response handling timed out.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +BmSdSendCmd (
> + IN UINT32 Idx,
> + IN UINT32 Arg,
> + IN UINT32 RespType,
> + OUT UINT32 *Response
> + )
> +{
> + EFI_STATUS Status;
> + MMC_CMD Cmd;
> +
> + // DEBUG ((DEBUG_INFO, "%a: SDHCI Cmd, Idx=%d, Arg=0x%x, ResponseType=0x%x\n", __func__, Idx, Arg, RespType));
> +
> + ZeroMem(&Cmd,sizeof(MMC_CMD));
> +
> + Cmd.CmdIdx = Idx;
> + Cmd.CmdArg = Arg;
> + Cmd.ResponseType = RespType;
> +
> + switch (Cmd.CmdIdx) {
> + case MMC_CMD17:
> + case MMC_CMD18:
> + case MMC_CMD24:
> + case MMC_CMD25:
> + case MMC_ACMD51:
> + Status = SdSendCmdWithData(&Cmd);
> + break;
> + default:
> + Status = SdSendCmdWithoutData(&Cmd);
> + }
> +
> + if ((Status == EFI_SUCCESS) && (Response != NULL)) {
> + for (INT32 I = 0; I < 4; I++) {
> + *Response = Cmd.Response[I];
> + Response++;
> + }
> + }
> + return Status;
> +}
> +
> +/**
> + Set clock frequency of SD card.
> +
> + @param[in] Clk The clock frequency of SD card.
> +
> +**/
> +VOID
> +SdSetClk (
> + IN INT32 Clk
> + )
> +{
> + INT32 I;
> + INT32 Div;
> + UINTN Base;
> +
> + ASSERT (Clk > 0);
> +
> + if (BmParams.ClkRate <= Clk) {
> + Div = 0;
> + } else {
> + for (Div = 0x1; Div < 0xFF; Div++) {
> + if (BmParams.ClkRate / (2 * Div) <= Clk)
> + break;
> + }
> + }
> + ASSERT (Div <= 0xFF);
> +
> + Base = BmParams.RegBase;
> + if (MmioRead16 (Base + SDHCI_HOST_CONTROL2) & (1 << 15)) {
> + //verbose("Use SDCLK Preset Value\n");
> + } else {
> + //verbose("Set SDCLK by driver. Div=0x%x(%d)\n", Div, Div);
> + MmioWrite16 (Base + SDHCI_CLK_CTRL,
> + MmioRead16 (Base + SDHCI_CLK_CTRL) & ~0x9); // disable INTERNAL_CLK_EN and PLL_ENABLE
> + MmioWrite16 (Base + SDHCI_CLK_CTRL,
> + (MmioRead16 (Base + SDHCI_CLK_CTRL) & 0xDF) | Div << 8); // set Clk Div
> + MmioWrite16 (Base + SDHCI_CLK_CTRL,
> + MmioRead16 (Base + SDHCI_CLK_CTRL) | 0x1); // set INTERNAL_CLK_EN
> +
> + for (I = 0; I <= 150000; I += 100) {
> + if (MmioRead16 (Base + SDHCI_CLK_CTRL) & 0x2)
> + break;
> + gBS->Stall (100);
> + }
> +
> + if (I > 150000) {
> + DEBUG ((DEBUG_ERROR, "%a: SD INTERNAL_CLK_EN setting FAILED!\n", __func__));
> + ASSERT(0);
> + }
> +
> + MmioWrite16 (Base + SDHCI_CLK_CTRL, MmioRead16 (Base + SDHCI_CLK_CTRL) | 0x8); // set PLL_ENABLE
> +
> + for (I = 0; I <= 150000; I += 100) {
> + if (MmioRead16 (Base + SDHCI_CLK_CTRL) & 0x2)
> + return;
> + gBS->Stall (100);
> + }
> + }
> +
> + DEBUG ((DEBUG_INFO, "%a: SD PLL setting FAILED!\n", __func__));
> +}
> +
> +/**
> + Change clock frequency of SD card.
> +
> + @param[in] Clk The clock frequency of SD card.
> +
> +**/
> +VOID
> +SdChangeClk (
> + IN INT32 Clk
> + )
> +{
> + INT32 I;
> + INT32 Div;
> + UINTN Base;
> +
> + ASSERT (Clk > 0);
> +
> + if (BmParams.ClkRate <= Clk) {
> + Div = 0;
> + } else {
> + for (Div = 0x1; Div < 0xFF; Div++) {
> + if (BmParams.ClkRate / (2 * Div) <= Clk)
> + break;
> + }
> + }
> + ASSERT (Div <= 0xFF);
> +
> + Base = BmParams.RegBase;
> +
> + MmioWrite16 (Base + SDHCI_CLK_CTRL,
> + MmioRead16 (Base + SDHCI_CLK_CTRL) & ~(0x1 << 2)); // stop SD clock
> +
> + MmioWrite16 (Base + SDHCI_CLK_CTRL,
> + MmioRead16 (Base + SDHCI_CLK_CTRL) & ~0x8); // disable PLL_ENABLE
> +
> + if (MmioRead16 (Base + SDHCI_HOST_CONTROL2) & (1 << 15)) {
> + MmioWrite16 (Base + SDHCI_HOST_CONTROL2,
> + MmioRead16 (Base + SDHCI_HOST_CONTROL2) & ~0x7); // clr UHS_MODE_SEL
> + } else {
> + MmioWrite16 (Base + SDHCI_CLK_CTRL,
> + (MmioRead16 (Base + SDHCI_CLK_CTRL) & 0xDF) | Div << 8); // set Clk Div
> + MmioWrite16 (Base + SDHCI_CLK_CTRL,
> + MmioRead16 (Base + SDHCI_CLK_CTRL) & ~(0x1 << 5)); // CLK_GEN_SELECT
> + }
> +
> + MmioWrite16 (Base + SDHCI_CLK_CTRL,
> + MmioRead16 (Base + SDHCI_CLK_CTRL) | 0xc); // enable PLL_ENABLE
> +
> + for (I = 0; I <= 150000; I += 100) {
> + if (MmioRead16 (Base + SDHCI_CLK_CTRL) & 0x2)
> + return;
> + gBS->Stall (100);
> + }
> +
> + DEBUG ((DEBUG_INFO, "%a: SD PLL setting FAILED!\n", __func__));
> +}
> +
> +/**
> + Detect the status of the SD card.
> +
> + @return The status of the SD card:
> + - SDCARD_STATUS_INSERTED: The SD card is inserted.
> + - SDCARD_STATUS_NOT_INSERTED: The SD card is not inserted.
> + - SDCARD_STATUS_UNKNOWN: The status of the SD card is unknown.
> +
> +**/
> +INT32
> +BmSdCardDetect (
> + VOID
> + )
> +{
> + UINTN Base;
> + UINTN Reg;
> +
> + Base = BmParams.RegBase;
> +
> + if (BmParams.CardIn != SDCARD_STATUS_UNKNOWN)
> + return BmParams.CardIn;
> +
> + MmioWrite16 (Base + SDHCI_INT_STATUS_EN,
> + MmioRead16 (Base + SDHCI_INT_STATUS_EN) | SDHCI_INT_CARD_INSERTION_EN);
> +
> + Reg = MmioRead32 (Base + SDHCI_PSTATE);
> +
> + if (Reg & SDHCI_CARD_INSERTED)
> + BmParams.CardIn = SDCARD_STATUS_INSERTED;
> + else
> + BmParams.CardIn = SDCARD_STATUS_NOT_INSERTED;
> +
> + return BmParams.CardIn;
> +}
> +
> +/**
> + SD card hardware initialization.
> +
> +**/
> +STATIC
> +VOID
> +SdHwInit (
> + VOID
> + )
> +{
> + UINTN Base;
> +
> + Base = BmParams.RegBase;
> + BmParams.VendorBase = Base + (MmioRead16 (Base + P_VENDOR_SPECIFIC_AREA) & ((1 << 12) - 1));
> +
> + // deasset reset of phy
> + MmioWrite32 (Base + SDHCI_P_PHY_CNFG, MmioRead32 (Base + SDHCI_P_PHY_CNFG) | (1 << PHY_CNFG_PHY_RSTN));
> +
> + // reset data & Cmd
> + MmioWrite8 (Base + SDHCI_SOFTWARE_RESET, 0x6);
> +
> + // init common parameters
> + MmioWrite8 (Base + SDHCI_PWR_CONTROL, (0x7 << 1));
> + MmioWrite8 (Base + SDHCI_TOUT_CTRL, 0xe); // for TMCLK 50Khz
> + MmioWrite16 (Base + SDHCI_HOST_CONTROL2,
> + MmioRead16 (Base + SDHCI_HOST_CONTROL2) | 1 << 11); // set cmd23 support
> + MmioWrite16 (Base + SDHCI_CLK_CTRL, MmioRead16 (Base + SDHCI_CLK_CTRL) & ~(0x1 << 5)); // divided clock Mode
> +
> + // set host version 4 parameters
> + MmioWrite16 (Base + SDHCI_HOST_CONTROL2,
> + MmioRead16 (Base + SDHCI_HOST_CONTROL2) | (1 << 12)); // set HOST_VER4_ENABLE
> + if (MmioRead32 (Base + SDHCI_CAPABILITIES1) & (0x1 << 27)) {
> + MmioWrite16 (Base + SDHCI_HOST_CONTROL2,
> + MmioRead16 (Base + SDHCI_HOST_CONTROL2) | 0x1 << 13); // set 64bit addressing
> + }
> +
> + // if support asynchronous int
> + if (MmioRead32 (Base + SDHCI_CAPABILITIES1) & (0x1 << 29))
> + MmioWrite16 (Base + SDHCI_HOST_CONTROL2,
> + MmioRead16 (Base + SDHCI_HOST_CONTROL2) | (0x1 << 14)); // enable async int
> + // give some time to power down card
> + gBS->Stall (20000);
> +
> + MmioWrite16 (Base + SDHCI_HOST_CONTROL2,
> + MmioRead16 (Base + SDHCI_HOST_CONTROL2) & ~(0x1 << 8)); // clr UHS2_IF_ENABLE
> + MmioWrite8 (Base + SDHCI_PWR_CONTROL,
> + MmioRead8 (Base + SDHCI_PWR_CONTROL) | 0x1); // set SD_BUS_PWR_VDD1
> + MmioWrite16 (Base + SDHCI_HOST_CONTROL2,
> + MmioRead16 (Base + SDHCI_HOST_CONTROL2) & ~0x7); // clr UHS_MODE_SEL
> + SdSetClk (SDCARD_INIT_FREQ);
> + gBS->Stall (50000);
> +
> + MmioWrite16 (Base + SDHCI_CLK_CTRL,
> + MmioRead16 (Base + SDHCI_CLK_CTRL) | (0x1 << 2)); // supply SD clock
> + gBS->Stall (400); // wait for voltage ramp up time at least 74 cycle, 400us is 80 cycles for 200Khz
> +
> + MmioWrite16 (Base + SDHCI_INT_STATUS, MmioRead16 (Base + SDHCI_INT_STATUS) | (0x1 << 6));
> +
> + // we enable all interrupt Status here for testing
> + MmioWrite16 (Base + SDHCI_INT_STATUS_EN, MmioRead16 (Base + SDHCI_INT_STATUS_EN) | 0xFFFF);
> + MmioWrite16 (Base + SDHCI_ERR_INT_STATUS_EN, MmioRead16 (Base + SDHCI_ERR_INT_STATUS_EN) | 0xFFFF);
> +
> + //verbose("SD init done\n");
> +}
> +
> +/**
> + Set the input/output settings for the SD card.
> +
> + @param[in] Clk The clock frequency for the SD card.
> + @param[in] Width The bus width for data transfer.
> +
> + @retval EFI_SUCCESS The input/output settings were set successfully.
> + @retval EFI_UNSUPPORTED The specified bus width is not supported.
> +
> +**/
> +EFI_STATUS
> +BmSdSetIos (
> + IN UINT32 Clk,
> + IN UINT32 Width
> + )
> +{
> + switch (Width) {
> + case MMC_BUS_WIDTH_1:
> + MmioWrite8 (BmParams.RegBase + SDHCI_HOST_CONTROL,
> + MmioRead8 (BmParams.RegBase + SDHCI_HOST_CONTROL) &
> + ~SDHCI_DAT_XFER_WIDTH);
> + break;
> + case MMC_BUS_WIDTH_4:
> + MmioWrite8 (BmParams.RegBase + SDHCI_HOST_CONTROL,
> + MmioRead8 (BmParams.RegBase + SDHCI_HOST_CONTROL) |
> + SDHCI_DAT_XFER_WIDTH);
> + break;
> + default:
> + ASSERT (0);
> + }
> +
> + SdChangeClk (Clk);
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + Prepare the SD card for data transfer.
> + Set the number and size of data blocks before sending IO commands to the SD card.
> +
> + @param[in] Lba Logical Block Address.
> + @param[in] Buf Buffer Address.
> + @param[in] Size Size of Data Blocks.
> +
> + @retval EFI_SUCCESS The SD card was prepared successfully.
> + @retval Other An error occurred during the preparation of the SD card.
> +
> +**/
> +EFI_STATUS
> +BmSdPrepare (
> + IN INT32 Lba,
> + IN UINTN Buf,
> + IN UINTN Size
> + )
> +{
> + UINTN LoadAddr;
> + UINTN Base;
> + UINT32 BlockCnt;
> + UINT32 BlockSize;
> + UINT8 Tmp;
> +
> + LoadAddr = Buf;
> +
> + if (Size >= MMC_BLOCK_SIZE) {
> + // CMD17, 18, 24, 25
> + // ASSERT (((LoadAddr & MMC_BLOCK_MASK) == 0) && ((Size % MMC_BLOCK_SIZE) == 0));
> + BlockSize = MMC_BLOCK_SIZE;
> + BlockCnt = Size / MMC_BLOCK_SIZE;
> + } else {
> + // ACMD51
> + ASSERT (((LoadAddr & 8) == 0) && ((Size % 8) == 0));
> + BlockSize = 8;
> + BlockCnt = Size / 8;
> + }
> +
> + Base = BmParams.RegBase;
> +
> + if (!(BmParams.Flags & SD_USE_PIO)) {
> + if (MmioRead16 (Base + SDHCI_HOST_CONTROL2) & SDHCI_HOST_VER4_ENABLE) {
> + MmioWrite32 (Base + SDHCI_ADMA_SA_LOW, LoadAddr);
> + MmioWrite32 (Base + SDHCI_ADMA_SA_HIGH, (LoadAddr >> 32));
> + MmioWrite32 (Base + SDHCI_DMA_ADDRESS, BlockCnt);
> + MmioWrite16 (Base + SDHCI_BLOCK_COUNT, 0);
> + } else {
> + ASSERT((LoadAddr >> 32) == 0);
> + MmioWrite32 (Base + SDHCI_DMA_ADDRESS, LoadAddr);
> + MmioWrite16 (Base + SDHCI_BLOCK_COUNT, BlockCnt);
> + }
> +
> + // 512K bytes SDMA buffer boundary
> + MmioWrite16 (Base + SDHCI_BLOCK_SIZE, SDHCI_MAKE_BLKSZ(7, BlockSize));
> +
> + // select SDMA
> + Tmp = MmioRead8 (Base + SDHCI_HOST_CONTROL);
> + Tmp &= ~SDHCI_CTRL_DMA_MASK;
> + Tmp |= SDHCI_CTRL_SDMA;
> + MmioWrite8 (Base + SDHCI_HOST_CONTROL, Tmp);
> + } else {
> + MmioWrite16 (Base + SDHCI_BLOCK_SIZE, BlockSize);
> + MmioWrite16 (Base + SDHCI_BLOCK_COUNT, BlockCnt);
> + }
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + SD card sends command to read data blocks.
> +
> + @param[in] Lba Logical Block Address.
> + @param[in] Buf Buffer Address.
> + @param[in] Size Size of Data Blocks.
> +
> + @retval EFI_SUCCESS The command to read data blocks was sent successfully.
> + @retval EFI_TIMEOUT The command transmission or data transfer timed out.
> +
> +**/
> +EFI_STATUS
> +BmSdRead (
> + IN INT32 Lba,
> + IN UINT32* Buf,
> + IN UINTN Size
> + )
> +{
> + UINT32 Timeout;
> + UINTN Base;
> + UINT32 *Data;
> + UINT32 BlockSize;
> + UINT32 BlockCnt;
> + UINT32 Status;
> +
> + Timeout = 0;
> + Base = BmParams.RegBase;
> + Data = Buf;
> + BlockSize = 0;
> + BlockCnt = 0;
> + Status = 0;
> +
> + if (BmParams.Flags & SD_USE_PIO) {
> + BlockSize = MmioRead16 (Base + SDHCI_BLOCK_SIZE);
> + BlockCnt = Size / BlockSize;
> + BlockSize /= 4;
> +
> + for (INT32 I = 0; I < BlockCnt; ) {
> + Status = MmioRead16 (Base + SDHCI_INT_STATUS);
> + if ((Status & SDHCI_INT_BUF_RD_READY) &&
> + (MmioRead32 (Base + SDHCI_PSTATE) & SDHCI_BUF_RD_ENABLE)) {
> + MmioWrite16 (Base + SDHCI_INT_STATUS, SDHCI_INT_BUF_RD_READY);
> + for (INT32 j = 0; j < BlockSize; j++) {
> + *(Data++) = MmioRead32 (Base + SDHCI_BUF_DATA_R);
> + }
> +
> + Timeout = 0;
> + I++;
> + } else {
> + gBS->Stall (1);
> + Timeout++;
> + }
> +
> + if (Timeout >= 10000) {
> + DEBUG ((DEBUG_INFO, "%a: sdhci read data Timeout\n", __func__));
> + goto Timeout;
> + }
> + }
> +
> + Timeout = 0;
> + while (1) {
> + Status = MmioRead16 (Base + SDHCI_INT_STATUS);
> + if (Status & SDHCI_INT_XFER_COMPLETE) {
> + MmioWrite16 (Base + SDHCI_INT_STATUS,
> + Status | SDHCI_INT_XFER_COMPLETE);
> +
> + return EFI_SUCCESS;
> + } else {
> + gBS->Stall (1);
> + Timeout++;
> + }
> +
> + if (Timeout >= 10000) {
> + DEBUG ((DEBUG_INFO, "%a:wait xfer complete Timeout\n", __func__));
> + goto Timeout;
> + }
> + }
> + } else {
> + return EFI_SUCCESS;
> + }
> +
> +Timeout:
> + return EFI_TIMEOUT;
> +
> +}
> +
> +/**
> + SD card sends commands to write data blocks.
> +
> + @param[in] Lba Logical Block Address.
> + @param[in] Buf Buffer Address.
> + @param[in] Size Size of Data Blocks.
> +
> + @retval EFI_SUCCESS The command to write data blocks was sent successfully.
> + @retval EFI_TIMEOUT The command transmission or data transfer timed out.
> +
> +**/
> +EFI_STATUS
> +BmSdWrite (
> + IN INT32 Lba,
> + IN UINT32* Buf,
> + IN UINTN Size
> + )
> +{
> + UINT32 Timeout;
> + UINTN Base;
> + UINT32 *Data;
> + UINT32 BlockSize;
> + UINT32 BlockCnt;
> + UINT32 Status;
> +
> + Timeout = 0;
> + Base = BmParams.RegBase;
> + Data = Buf;
> + BlockSize = 0;
> + BlockCnt = 0;
> + Status = 0;
> +
> + if (BmParams.Flags & SD_USE_PIO) {
> + BlockSize = MmioRead16 (Base + SDHCI_BLOCK_SIZE);
> + BlockCnt = Size / BlockSize;
> + BlockSize /= 4;
> +
> + for (INT32 j = 0; j < BlockSize; j++) {
> + MmioWrite32 (Base + SDHCI_BUF_DATA_R, *(Data++));
> + }
> +
> + for (INT32 I = 0; I < BlockCnt-1; ) {
> + Status = MmioRead16 (Base + SDHCI_INT_STATUS);
> + if ((Status & SDHCI_INT_BUF_WR_READY) &&
> + (MmioRead32 (Base + SDHCI_PSTATE) &
> + SDHCI_BUF_WR_ENABLE)) {
> + MmioWrite16 (Base + SDHCI_INT_STATUS, SDHCI_INT_BUF_WR_READY);
> + for (INT32 j = 0; j < BlockSize; j++) {
> + MmioWrite32 (Base + SDHCI_BUF_DATA_R, *(Data++));
> + }
> +
> + Timeout = 0;
> + I++;
> + } else {
> + gBS->Stall (1);
> + Timeout++;
> + }
> +
> + if (Timeout >= 10000000) {
> + DEBUG ((DEBUG_INFO, "%a:sdhci write data Timeout\n", __func__));
> + goto Timeout;
> + }
> + }
> +
> + Timeout = 0;
> + while (1) {
> + Status = MmioRead16 (Base + SDHCI_INT_STATUS);
> + if (Status & SDHCI_INT_XFER_COMPLETE) {
> + MmioWrite16 (Base + SDHCI_INT_STATUS,
> + Status | SDHCI_INT_XFER_COMPLETE);
> +
> + return EFI_SUCCESS;
> + } else {
> + gBS->Stall (1);
> + Timeout++;
> + }
> +
> + if (Timeout >= 10000) {
> + DEBUG ((DEBUG_INFO, "%a:wait xfer complete Timeout\n", __func__));
> + goto Timeout;
> + }
> + }
> + } else
> + return EFI_SUCCESS;
> +
> +Timeout:
> + return EFI_TIMEOUT;
> +}
> +
> +/**
> + Initialize the SD PHY.
> +
> + This function performs the initialization of the SD PHY hardware.
> +
> +**/
> +VOID
> +SdPhyInit (
> + VOID
> + )
> +{
> + UINTN Base;
> + INT32 RetryCount;
> +
> + Base = BmParams.RegBase;
> + RetryCount = 100;
> +
> + // reset hardware
> + MmioWrite8 (Base + SDHCI_SOFTWARE_RESET, 0x7);
> + while (MmioRead8 (Base + SDHCI_SOFTWARE_RESET)) {
> + if (RetryCount-- > 0)
> + gBS->Stall (10000);
> + else
> + break;
> + }
> +
> + // Wait for the PHY power on ready
> + RetryCount = 100;
> + while (!(MmioRead32 (Base + SDHCI_P_PHY_CNFG) & (1 << PHY_CNFG_PHY_PWRGOOD))) {
> + if (RetryCount-- > 0)
> + gBS->Stall (10000);
> + else
> + break;
> + }
> +
> + // Asset reset of phy
> + MmioAnd32 (Base + SDHCI_P_PHY_CNFG, ~(1 << PHY_CNFG_PHY_RSTN));
> +
> + // Set PAD_SN PAD_SP
> + MmioWrite32 (Base + SDHCI_P_PHY_CNFG,
> + (1 << PHY_CNFG_PHY_PWRGOOD) | (0x9 << PHY_CNFG_PAD_SP) | (0x8 << PHY_CNFG_PAD_SN));
> +
> + // Set CMDPAD
> + MmioWrite16 (Base + SDHCI_P_CMDPAD_CNFG,
> + (0x2 << PAD_CNFG_RXSEL) | (1 << PAD_CNFG_WEAKPULL_EN) |
> + (0x3 << PAD_CNFG_TXSLEW_CTRL_P) | (0x2 << PAD_CNFG_TXSLEW_CTRL_N));
> +
> + // Set DATAPAD
> + MmioWrite16 (Base + SDHCI_P_DATPAD_CNFG,
> + (0x2 << PAD_CNFG_RXSEL) | (1 << PAD_CNFG_WEAKPULL_EN) |
> + (0x3 << PAD_CNFG_TXSLEW_CTRL_P) | (0x2 << PAD_CNFG_TXSLEW_CTRL_N));
> +
> + // Set CLKPAD
> + MmioWrite16 (Base + SDHCI_P_CLKPAD_CNFG,
> + (0x2 << PAD_CNFG_RXSEL) | (0x3 << PAD_CNFG_TXSLEW_CTRL_P) | (0x2 << PAD_CNFG_TXSLEW_CTRL_N));
> +
> + // Set STB_PAD
> + MmioWrite16 (Base + SDHCI_P_STBPAD_CNFG,
> + (0x2 << PAD_CNFG_RXSEL) | (0x2 << PAD_CNFG_WEAKPULL_EN) |
> + (0x3 << PAD_CNFG_TXSLEW_CTRL_P) | (0x2 << PAD_CNFG_TXSLEW_CTRL_N));
> +
> + // Set RSTPAD
> + MmioWrite16 (Base + SDHCI_P_RSTNPAD_CNFG,
> + (0x2 << PAD_CNFG_RXSEL) | (1 << PAD_CNFG_WEAKPULL_EN) |
> + (0x3 << PAD_CNFG_TXSLEW_CTRL_P) | (0x2 << PAD_CNFG_TXSLEW_CTRL_N));
> +
> + // Set SDCLKDL_CNFG, EXTDLY_EN = 1, fix delay
> + MmioWrite8 (Base + SDHCI_P_SDCLKDL_CNFG, (1 << SDCLKDL_CNFG_EXTDLY_EN));
> +
> + // Set SMPLDL_CNFG, Bypass
> + MmioWrite8 (Base + SDHCI_P_SMPLDL_CNFG, (1 << SMPLDL_CNFG_BYPASS_EN));
> +
> + // Set ATDL_CNFG, tuning Clk not use for init
> + MmioWrite8 (Base + SDHCI_P_ATDL_CNFG, (2 << ATDL_CNFG_INPSEL_CNFG));
> +
> + return;
> +}
> +
> +/**
> + Initialize the SD card.
> +
> + This function performs the initialization of the SD card hardware and settings.
> +
> + @param[in] Flags Initialization flags.
> +
> + @retval EFI_SUCCESS The SD card was initialized successfully.
> +
> +**/
> +EFI_STATUS
> +SdInit (
> + IN UINT32 Flags
> +)
> +{
> + BmParams.ClkRate = BmGetSdClk ();
> +
> + DEBUG ((DEBUG_INFO, "SD initializing %dHz\n", BmParams.ClkRate));
> +
> + BmParams.Flags = Flags;
> +
> + SdPhyInit ();
> +
> + SdHwInit ();
> +
> + return EFI_SUCCESS;
> +}
> diff --git a/Silicon/Sophgo/SG2042Pkg/Drivers/SdHostDxe/SdHostDxe.c b/Silicon/Sophgo/SG2042Pkg/Drivers/SdHostDxe/SdHostDxe.c
> new file mode 100644
> index 000000000000..3bb04344320a
> --- /dev/null
> +++ b/Silicon/Sophgo/SG2042Pkg/Drivers/SdHostDxe/SdHostDxe.c
> @@ -0,0 +1,450 @@
> +/** @file
> + This file implements the SD host controller driver for UEFI systems.
> + The file contains the implementation of the EFI_MMC_HOST_PROTOCOL, which provides
> + the necessary interfaces for handling communication and data transfer with SD cards.
> +
> + Copyright (c) 2017, Andrei Warkentin <andrey.warkentin@gmail.com>
> + Copyright (c) Microsoft Corporation. All rights reserved.
> + Copyright (c) 2023, Academy of Intelligent Innovation, Shandong Universiy, China.P.R. All rights reserved.<BR>
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Uefi.h>
> +#include <Library/BaseLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/DevicePathLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DmaLib.h>
> +#include <Library/TimerLib.h>
> +
> +#include <Protocol/EmbeddedExternalDevice.h>
> +#include <Protocol/BlockIo.h>
> +#include <Protocol/DevicePath.h>
> +#include <Include/MmcHost.h>
> +
> +#include "SdHci.h"
> +
> +#define SDHOST_BLOCK_BYTE_LENGTH 512
> +
> +#define DEBUG_MMCHOST_SD DEBUG_VERBOSE
> +#define DEBUG_MMCHOST_SD_INFO DEBUG_INFO
> +#define DEBUG_MMCHOST_SD_ERROR DEBUG_ERROR
> +
> +STATIC BOOLEAN mCardIsPresent = FALSE;
> +STATIC CARD_DETECT_STATE mCardDetectState = CardDetectRequired;
> +BM_SD_PARAMS BmParams;
> +
> +/**
> + Check if the SD card is read-only.
> +
> + @param[in] This Pointer to the EFI_MMC_HOST_PROTOCOL instance.
> +
> + @retval FALSE The SD card is not read-only.
> +
> +**/
> +STATIC
> +BOOLEAN
> +SdIsReadOnly (
> + IN EFI_MMC_HOST_PROTOCOL *This
> + )
> +{
> + return FALSE;
> +}
> +
> +/**
> + Build the device path for the SD card.
> +
> + @param[in] This Pointer to the EFI_MMC_HOST_PROTOCOL instance.
> + @param[out] DevicePath Pointer to the location to store the newly created device path.
> +
> + @retval EFI_SUCCESS The device path is built successfully.
> +
> +**/
> +STATIC
> +EFI_STATUS
> +SdBuildDevicePath (
> + IN EFI_MMC_HOST_PROTOCOL *This,
> + OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath
> + )
> +{
> + EFI_DEVICE_PATH_PROTOCOL *NewDevicePathNode;
> + EFI_GUID DevicePathGuid = EFI_CALLER_ID_GUID;
> +
> + DEBUG ((DEBUG_MMCHOST_SD, "SdHost: SdBuildDevicePath ()\n"));
> +
> + NewDevicePathNode = CreateDeviceNode (HARDWARE_DEVICE_PATH, HW_VENDOR_DP, sizeof (VENDOR_DEVICE_PATH));
> + CopyGuid (&((VENDOR_DEVICE_PATH*)NewDevicePathNode)->Guid, &DevicePathGuid);
> + *DevicePath = NewDevicePathNode;
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + Send a command to the SD card.
> +
> + @param[in] This Pointer to the EFI_MMC_HOST_PROTOCOL instance.
> + @param[in] MmcCmd The MMC command to send.
> + @param[in] Argument The argument for the command.
> + @param[in] Type The type of response expected.
> + @param[in] Buffer Pointer to the buffer to store the response.
> +
> + @retval EFI_SUCCESS The command was sent successfully and the response was retrieved.
> + @retval Other An error occurred while sending a command.
> +**/
> +STATIC
> +EFI_STATUS
> +SdSendCommand (
> + IN EFI_MMC_HOST_PROTOCOL *This,
> + IN MMC_IDX MmcCmd,
> + IN UINT32 Argument,
> + IN MMC_RESPONSE_TYPE Type,
> + IN UINT32* Buffer
> + )
> +{
> + EFI_STATUS Status;
> +
> + Status = BmSdSendCmd (MmcCmd, Argument, Type, Buffer);
> +
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_MMCHOST_SD_ERROR, "SdSendCommand Error, Status=%r.\n", Status));
> + return Status;
> + }
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + Read block data from an SD card.
> +
> + @param[in] This Pointer to the EFI_MMC_HOST_PROTOCOL instance.
> + @param[in] Lba Logical Block Address of the starting block to read.
> + @param[in] Length Number of blocks to read.
> + @param[in] Buffer Pointer to the buffer to store the read data.
> +
> + @retval EFI_SUCCESS The operation completed successfully.
> + @retval Other The operation failed.
> +
> +**/
> +STATIC
> +EFI_STATUS
> +SdReadBlockData (
> + IN EFI_MMC_HOST_PROTOCOL *This,
> + IN EFI_LBA Lba,
> + IN UINTN Length,
> + OUT UINT32* Buffer
> + )
> +{
> + EFI_STATUS Status;
> +
> + ASSERT (Buffer != NULL);
> + ASSERT (Length % 4 == 0);
> +
> + Status = BmSdRead (Lba, Buffer, Length);
> +
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_MMCHOST_SD_ERROR, "SdReadBlockData Error, Status=%r.\n", Status));
> + return Status;
> + }
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + Write block data to an SD card.
> +
> + @param[in] This Pointer to the EFI_MMC_HOST_PROTOCOL instance.
> + @param[in] Lba Logical Block Address of the starting block to write.
> + @param[in] Length Number of blocks to write.
> + @param[in] Buffer Pointer to the buffer containing the data to be written.
> +
> + @retval EFI_SUCCESS The operation completed successfully.
> + @retval Other The operation failed.
> +
> +**/
> +STATIC
> +EFI_STATUS
> +SdWriteBlockData (
> + IN EFI_MMC_HOST_PROTOCOL *This,
> + IN EFI_LBA Lba,
> + IN UINTN Length,
> + IN UINT32* Buffer
> + )
> +{
> + EFI_STATUS Status;
> +
> + DEBUG ((DEBUG_MMCHOST_SD, "SdHost: SdWriteBlockData(LBA: 0x%x, Length: 0x%x, Buffer: 0x%x)\n",(UINT32)Lba, Length, Buffer));
> +
> + ASSERT (Buffer != NULL);
> + ASSERT (Length % SDHOST_BLOCK_BYTE_LENGTH == 0);
> +
> + Status = BmSdWrite (Lba, Buffer, Length);
> +
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_MMCHOST_SD_ERROR, "SdWriteBlockData Error, Status=%r.\n", Status));
> + return Status;
> + }
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + Set the I/O settings for an SD card.
> +
> + @param[in] This Pointer to the EFI_MMC_HOST_PROTOCOL instance.
> + @param[in] BusClockFreq Bus clock frequency in Hz.
> + @param[in] BusWidth Bus width setting.
> +
> + @retval EFI_SUCCESS The operation completed successfully.
> + @retval Other The operation failed.
> +
> +**/
> +STATIC
> +EFI_STATUS
> +SdSetIos (
> + IN EFI_MMC_HOST_PROTOCOL *This,
> + IN UINT32 BusClockFreq,
> + IN UINT32 BusWidth
> + )
> +{
> + EFI_STATUS Status;
> +
> + DEBUG ((DEBUG_MMCHOST_SD_INFO, "%a: Setting Freq %u Hz\n", __func__, BusClockFreq));
> + DEBUG ((DEBUG_MMCHOST_SD_INFO, "%a: Setting BusWidth %u\n", __func__, BusWidth));
> +
> + Status = BmSdSetIos (BusClockFreq,BusWidth);
> +
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_MMCHOST_SD_ERROR, "SdSetIos Error, Status=%r.\n", Status));
> + return Status;
> + }
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + Prepare the SD card for data transfer.
> +
> + @param[in] This Pointer to the EFI_MMC_HOST_PROTOCOL instance.
> + @param[in] Lba Logical Block Address of the starting block to prepare.
> + @param[in] Length Number of blocks to prepare.
> + @param[in] Buffer Buffer containing the data to be prepared.
> +
> + @retval EFI_SUCCESS The operation completed successfully.
> + @retval Other The operation failed.
> +
> +**/
> +STATIC
> +EFI_STATUS
> +SdPrepare (
> + IN EFI_MMC_HOST_PROTOCOL *This,
> + IN EFI_LBA Lba,
> + IN UINTN Length,
> + IN UINTN Buffer
> + )
> +{
> + EFI_STATUS Status;
> +
> + Status = BmSdPrepare (Lba, Buffer, Length);
> +
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_MMCHOST_SD_ERROR, "SdPrepare Error, Status=%r.\n", Status));
> + return Status;
> + }
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + Notify the state of the SD card.
> +
> + @param[in] This Pointer to the EFI_MMC_HOST_PROTOCOL instance.
> + @param[in] State State of the SD card.
> +
> + @retval EFI_SUCCESS The operation completed successfully.
> + @retval EFI_NOT_READY The card detection has not completed yet.
> + @retval Other The operation failed.
> +
> +**/
> +STATIC
> +EFI_STATUS
> +SdNotifyState (
> + IN EFI_MMC_HOST_PROTOCOL *This,
> + IN MMC_STATE State
> + )
> +{
> + // Stall all operations except init until card detection has occurred.
> + if (State != MmcHwInitializationState && mCardDetectState != CardDetectCompleted) {
> + return EFI_NOT_READY;
> + }
> +
> + switch (State) {
> + case MmcHwInitializationState:
> + DEBUG ((DEBUG_MMCHOST_SD, "MmcHwInitializationState\n", State));
> +
> + EFI_STATUS Status = SdInit (SD_USE_PIO);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_MMCHOST_SD_ERROR,"SdHost: SdNotifyState(): Fail to initialize!\n"));
> + return Status;
> + }
> + break;
> + case MmcIdleState:
> + DEBUG ((DEBUG_MMCHOST_SD, "MmcIdleState\n", State));
> + break;
> + case MmcReadyState:
> + DEBUG ((DEBUG_MMCHOST_SD, "MmcReadyState\n", State));
> + break;
> + case MmcIdentificationState:
> + DEBUG ((DEBUG_MMCHOST_SD, "MmcIdentificationState\n", State));
> + break;
> + case MmcStandByState:
> + DEBUG ((DEBUG_MMCHOST_SD, "MmcStandByState\n", State));
> + break;
> + case MmcTransferState:
> + DEBUG ((DEBUG_MMCHOST_SD, "MmcTransferState\n", State));
> + break;
> + case MmcSendingDataState:
> + DEBUG ((DEBUG_MMCHOST_SD, "MmcSendingDataState\n", State));
> + break;
> + case MmcReceiveDataState:
> + DEBUG ((DEBUG_MMCHOST_SD, "MmcReceiveDataState\n", State));
> + break;
> + case MmcProgrammingState:
> + DEBUG ((DEBUG_MMCHOST_SD, "MmcProgrammingState\n", State));
> + break;
> + case MmcDisconnectState:
> + case MmcInvalidState:
> + default:
> + DEBUG ((DEBUG_MMCHOST_SD_ERROR, "SdHost: SdNotifyState(): Invalid State: %d\n", State));
> + ASSERT (0);
> + }
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + Check if an SD card is present.
> +
> + @param[in] This Pointer to the EFI_MMC_HOST_PROTOCOL instance.
> +
> + @retval TRUE An SD card is present.
> + @retval FALSE No SD card is present.
> +
> +**/
> +STATIC
> +BOOLEAN
> +SdIsCardPresent (
> + IN EFI_MMC_HOST_PROTOCOL *This
> + )
> +{
> + //
> + // If we are already in progress (we may get concurrent calls)
> + // or completed the detection, just return the current value.
> + //
> + if (mCardDetectState != CardDetectRequired) {
> + return mCardIsPresent;
> + }
> +
> + mCardDetectState = CardDetectInProgress;
> + mCardIsPresent = FALSE;
> +
> + if (BmSdCardDetect () == 1) {
> + mCardIsPresent = TRUE;
> + goto out;
> + }
> + else {
> + DEBUG ((DEBUG_MMCHOST_SD_ERROR, "SdIsCardPresent: Error SdCardDetect.\n"));
> + mCardDetectState = CardDetectRequired;
> + return FALSE;
> + }
> +
> + DEBUG ((DEBUG_MMCHOST_SD_INFO, "SdIsCardPresent: Not detected.\n"));
> +
> +out:
> + mCardDetectState = CardDetectCompleted;
> + return mCardIsPresent;
> +}
> +
> +/**
> + Check if the SD card supports multi-block transfers.
> +
> + @param[in] This Pointer to the EFI_MMC_HOST_PROTOCOL instance.
> +
> + @retval TRUE The SD card supports multi-block transfers.
> +
> +**/
> +BOOLEAN
> +SdIsMultiBlock (
> + IN EFI_MMC_HOST_PROTOCOL *This
> + )
> +{
> + return TRUE;
> +}
> +
> +EFI_MMC_HOST_PROTOCOL gMmcHost = {
> + MMC_HOST_PROTOCOL_REVISION,
> + SdIsCardPresent,
> + SdIsReadOnly,
> + SdBuildDevicePath,
> + SdNotifyState,
> + SdSendCommand,
> + SdReadBlockData,
> + SdWriteBlockData,
> + SdSetIos,
> + SdPrepare,
> + SdIsMultiBlock
> +};
> +
> +/**
> + Initialize the SD host.
> +
> + @param[in] ImageHandle The image handle.
> + @param[in] SystemTable The system table.
> +
> + @retval EFI_SUCCESS The operation completed successfully.
> + @retval Other The operation failed.
> +**/
> +EFI_STATUS
> +SdHostInitialize (
> + IN EFI_HANDLE ImageHandle,
> + IN EFI_SYSTEM_TABLE *SystemTable
> + )
> +{
> + EFI_STATUS Status;
> + EFI_HANDLE Handle;
> + UINTN Base;
> +
> + DEBUG ((DEBUG_MMCHOST_SD, "SdHost: Initialize\n"));
> +
> + Handle = NULL;
> + Base = SDIO_BASE;
> +
> + if(!PcdGetBool (PcdForceNoMMU)){
> + for (INT32 I = 39; I < 64; I++) {
> + if (Base & (1ULL << 38)) {
> + Base |= (1ULL << I);
> + } else {
> + Base &= ~(1ULL << I);
> + }
> + }
> + }
> +
> + BmParams.RegBase = Base;
> + BmParams.ClkRate = 50 * 1000 * 1000;
> + BmParams.BusWidth = MMC_BUS_WIDTH_4;
> + BmParams.Flags = 0;
> + BmParams.CardIn = SDCARD_STATUS_UNKNOWN;
> +
> + Status = gBS->InstallMultipleProtocolInterfaces (
> + &Handle,
> + &gSophgoMmcHostProtocolGuid,
> + &gMmcHost,
> + NULL
> + );
> + ASSERT_EFI_ERROR (Status);
> + return Status;
> +}
> --
> 2.34.1
>
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#108729): https://edk2.groups.io/g/devel/message/108729
Mute This Topic: https://groups.io/mt/101213491/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/leave/12367111/7686176/1913456212/xyzzy [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
next prev parent reply other threads:[~2023-09-15 14:23 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-09-07 10:25 [edk2-devel] [PATCH v3 0/8] EDK2 on RISC-V Sophgo SG2042 platform caiyuqing_hz
2023-09-07 10:25 ` [edk2-devel] [PATCH v3 1/8] Sophgo/SG2042Pkg: Add SmbiosPlatformDxe module caiyuqing_hz
2023-09-15 10:36 ` Sunil V L
2023-09-07 10:25 ` [edk2-devel] [PATCH v3 2/8] Sophgo/SG2042Pkg: Add PlatformUpdateMmuDxe module caiyuqing_hz
2023-09-15 10:41 ` Sunil V L
2023-09-07 10:25 ` [edk2-devel] [PATCH v3 3/8] Sophgo/SG2042Pkg: Add Sophgo SDHCI driver caiyuqing_hz
2023-09-15 10:47 ` Sunil V L
2023-09-15 14:23 ` Leif Lindholm [this message]
2023-09-07 10:25 ` [edk2-devel] [PATCH v3 4/8] Sophgo/SG2042Pkg: Add base MMC driver caiyuqing_hz
2023-09-15 10:53 ` Sunil V L
2023-09-15 14:25 ` Leif Lindholm
2023-09-07 10:25 ` [edk2-devel] [PATCH v3 5/8] Sophgo/SG2042Pkg: Add SEC module caiyuqing_hz
2023-09-15 10:57 ` Sunil V L
2023-09-07 10:25 ` [edk2-devel] [PATCH v3 6/8] Sophgo/SG2042_EVB_Board: Add Sophgo SG2042 platform caiyuqing_hz
2023-09-15 11:03 ` Sunil V L
2023-09-07 10:25 ` [edk2-devel] [PATCH v3 7/8] Sophgo/SG2042Pkg: Add SG2042Pkg caiyuqing_hz
2023-09-07 10:25 ` [edk2-devel] [PATCH v3 8/8] Sophgo/SG2042Pkg: Add platform readme and document caiyuqing_hz
2023-09-15 10:35 ` [edk2-devel] [PATCH v3 0/8] EDK2 on RISC-V Sophgo SG2042 platform Sunil V L
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=ZQRoyg7q7jQqyomB@qc-i7.hemma.eciton.net \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox