mirror of
https://github.com/CTCaer/hekate
synced 2024-12-22 11:21:23 +00:00
bdk: sdmmc: refactor comments
This commit is contained in:
parent
b674624ad0
commit
d621d96af1
4 changed files with 66 additions and 49 deletions
|
@ -39,40 +39,40 @@ typedef struct _mbr_part_t
|
||||||
|
|
||||||
typedef struct _mbr_t
|
typedef struct _mbr_t
|
||||||
{
|
{
|
||||||
u8 bootstrap[440];
|
/* 0x000 */ u8 bootstrap[440];
|
||||||
u32 signature;
|
/* 0x1B8 */ u32 signature;
|
||||||
u16 copy_protected;
|
/* 0x1BC */ u16 copy_protected;
|
||||||
mbr_part_t partitions[4];
|
/* 0x1BE */ mbr_part_t partitions[4];
|
||||||
u16 boot_signature;
|
/* 0x1FE */ u16 boot_signature;
|
||||||
} __attribute__((packed)) mbr_t;
|
} __attribute__((packed)) mbr_t;
|
||||||
|
|
||||||
typedef struct _gpt_entry_t
|
typedef struct _gpt_entry_t
|
||||||
{
|
{
|
||||||
u8 type_guid[0x10];
|
/* 0x00 */ u8 type_guid[0x10];
|
||||||
u8 part_guid[0x10];
|
/* 0x10 */ u8 part_guid[0x10];
|
||||||
u64 lba_start;
|
/* 0x20 */ u64 lba_start;
|
||||||
u64 lba_end;
|
/* 0x28 */ u64 lba_end;
|
||||||
u64 attrs;
|
/* 0x30 */ u64 attrs;
|
||||||
u16 name[36];
|
/* 0x38 */ u16 name[36];
|
||||||
} gpt_entry_t;
|
} gpt_entry_t;
|
||||||
|
|
||||||
typedef struct _gpt_header_t
|
typedef struct _gpt_header_t
|
||||||
{
|
{
|
||||||
u64 signature; // "EFI PART"
|
/* 0x00 */ u64 signature; // "EFI PART"
|
||||||
u32 revision;
|
/* 0x08 */ u32 revision;
|
||||||
u32 size;
|
/* 0x0C */ u32 size;
|
||||||
u32 crc32;
|
/* 0x10 */ u32 crc32;
|
||||||
u32 res1;
|
/* 0x14 */ u32 res1;
|
||||||
u64 my_lba;
|
/* 0x18 */ u64 my_lba;
|
||||||
u64 alt_lba;
|
/* 0x20 */ u64 alt_lba;
|
||||||
u64 first_use_lba;
|
/* 0x28 */ u64 first_use_lba;
|
||||||
u64 last_use_lba;
|
/* 0x30 */ u64 last_use_lba;
|
||||||
u8 disk_guid[0x10];
|
/* 0x38 */ u8 disk_guid[0x10];
|
||||||
u64 part_ent_lba;
|
/* 0x48 */ u64 part_ent_lba;
|
||||||
u32 num_part_ents;
|
/* 0x50 */ u32 num_part_ents;
|
||||||
u32 part_ent_size;
|
/* 0x54 */ u32 part_ent_size;
|
||||||
u32 part_ents_crc32;
|
/* 0x58 */ u32 part_ents_crc32;
|
||||||
u8 res2[420]; // Used as first 3 partition entries backup for HOS.
|
/* 0x5C */ u8 res2[420]; // Used as first 3 partition entries backup for HOS.
|
||||||
} gpt_header_t;
|
} gpt_header_t;
|
||||||
|
|
||||||
typedef struct _gpt_t
|
typedef struct _gpt_t
|
||||||
|
|
|
@ -1187,29 +1187,40 @@ int _sd_storage_set_driver_type(sdmmc_storage_t *storage, u32 driver, u8 *buf)
|
||||||
/*
|
/*
|
||||||
* SD Card DDR200 (DDR208) support
|
* SD Card DDR200 (DDR208) support
|
||||||
*
|
*
|
||||||
* Proper procedure:
|
* DLL Tuning (a) or Tuning Window (b) procedure:
|
||||||
* 1. Check that Vendor Specific Command System is supported.
|
* 1. Check that Vendor Specific Command System is supported.
|
||||||
* Used as Enable DDR200 Bus.
|
* Used as Enable DDR200 Bus.
|
||||||
* 2. Enable DDR200 bus mode via setting 14 to Group 2 via CMD6.
|
* 2. Enable DDR200 bus mode via setting 14 to Group 2 via CMD6.
|
||||||
* Access Mode group is left to default 0 (SDR12).
|
* Access Mode group is left to default 0 (SDR12).
|
||||||
* 3. Setup clock to 200 or 208 MHz.
|
* 3. Setup clock to 200 or 208 MHz.
|
||||||
* 4. Set host to DDR bus mode that supports such high clocks.
|
* 4a. Set host to DDR200/HS400 bus mode that enables DLL syncing.
|
||||||
* Some hosts have special mode, others use DDR50 and others HS400.
|
* Actual implementation supported by all DDR200 cards.
|
||||||
* 5. Execute Tuning.
|
* --
|
||||||
|
* 4b. Set host to DDR50 bus mode that supports such high clocks.
|
||||||
|
* Execute Manual Tuning.
|
||||||
|
* Limited to non-Sandisk cards.
|
||||||
*
|
*
|
||||||
* The true validation that this value in Group 2 activates it, is that DDR50 bus
|
* On Tegra SoCs, that can be done with DDR50 host mode.
|
||||||
* and clocks/timings work fully after that point.
|
* That's because HS400 4-bit or HS400 generally, is not supported on SD SDMMC.
|
||||||
|
* And also, tuning can't be done automatically on any DDR mode.
|
||||||
|
* So it needs to be done manually and selected tap will be applied from the
|
||||||
|
* biggest sampling window.
|
||||||
|
* That allows DDR200 support on every DDR200 SD card, other than the original
|
||||||
|
* maker of DDR200, Sandisk.
|
||||||
*
|
*
|
||||||
* On Tegra X1, that can be done with DDR50 host mode.
|
* On the original implementation of DDR200 from Sandisk, a DLL mechanism,
|
||||||
* Tuning though can't be done automatically on any DDR mode.
|
* like the one in eMMC HS400 is mandatory.
|
||||||
* So it needs to be done manually and selected tap will be applied from the biggest
|
* So the card can start data signals whenever it wants, and the host should
|
||||||
* sampling window.
|
* synchronize to the first DAT signal edge change.
|
||||||
|
* Every single other vendor that implemented that, always starts data transfers
|
||||||
|
* aligned to clock. That basically makes DDR200 in such SD cards a SDR104 but
|
||||||
|
* sampled on both edges. So effectively, it's an in-spec signal with DDR50,
|
||||||
|
* only that is clocked at 200MHz, instead of 50MHz.
|
||||||
|
* So the extra needed thing is using a tuning window, which is absent from the
|
||||||
|
* original implementation, since DDL syncing does not use that.
|
||||||
*
|
*
|
||||||
* Finally, all that simply works, because the marketing materials for DDR200 are
|
* On DLL tuning method expected cards, the tuning window is tiny.
|
||||||
* basically overstatements to sell the feature. DDR200 is simply SDR104 in DDR mode,
|
* So check against a minimum of 8 taps window, to disallow DDR200.
|
||||||
* so sampling on rising and falling edge and with variable output data window.
|
|
||||||
* It can be supported by any host that is fast enough to support DDR at 200/208MHz
|
|
||||||
* and can do hw/sw tuning for finding the proper sampling window in that mode.
|
|
||||||
*/
|
*/
|
||||||
#ifdef BDK_SDMMC_UHS_DDR200_SUPPORT
|
#ifdef BDK_SDMMC_UHS_DDR200_SUPPORT
|
||||||
static int _sd_storage_enable_DDR200(sdmmc_storage_t *storage, u8 *buf)
|
static int _sd_storage_enable_DDR200(sdmmc_storage_t *storage, u8 *buf)
|
||||||
|
|
|
@ -344,6 +344,7 @@ int sdmmc_setup_clock(sdmmc_t *sdmmc, u32 type)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDHCI_TIMING_MMC_HS400:
|
case SDHCI_TIMING_MMC_HS400:
|
||||||
|
// Non standard.
|
||||||
sdmmc->regs->hostctl2 = (sdmmc->regs->hostctl2 & (~SDHCI_CTRL_UHS_MASK)) | HS400_BUS_SPEED;
|
sdmmc->regs->hostctl2 = (sdmmc->regs->hostctl2 & (~SDHCI_CTRL_UHS_MASK)) | HS400_BUS_SPEED;
|
||||||
sdmmc->regs->hostctl2 |= SDHCI_CTRL_VDD_180;
|
sdmmc->regs->hostctl2 |= SDHCI_CTRL_VDD_180;
|
||||||
break;
|
break;
|
||||||
|
@ -723,8 +724,9 @@ static int _sdmmc_manual_tuning_set_tap(sdmmc_t *sdmmc, sdmmc_manual_tuning_t *t
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if failed.
|
|
||||||
if (!best_tap)
|
// Check if failed or window too small.
|
||||||
|
if (!best_tap || best_size < SAMPLING_WINDOW_SIZE_MIN)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
sdmmc->regs->clkcon &= ~SDHCI_CLOCK_CARD_EN;
|
sdmmc->regs->clkcon &= ~SDHCI_CLOCK_CARD_EN;
|
||||||
|
@ -743,9 +745,12 @@ static int _sdmmc_manual_tuning_set_tap(sdmmc_t *sdmmc, sdmmc_manual_tuning_t *t
|
||||||
* SD Card DDR200 (DDR208) support
|
* SD Card DDR200 (DDR208) support
|
||||||
*
|
*
|
||||||
* On Tegra X1, that can be done with DDR50 host mode.
|
* On Tegra X1, that can be done with DDR50 host mode.
|
||||||
* Tuning though can't be done automatically on any DDR mode.
|
* That's because HS400 4-bit or HS400 generally, is not supported on SDMMC1/3.
|
||||||
|
* And also, tuning can't be done automatically on any DDR mode.
|
||||||
* So it needs to be done manually and selected tap will be applied from the biggest
|
* So it needs to be done manually and selected tap will be applied from the biggest
|
||||||
* sampling window.
|
* sampling window.
|
||||||
|
* That allows DDR200 support on every DDR200 sd card, other than the original maker
|
||||||
|
* of DDR200, Sandisk. Since Sandisk cards mandate DLL syncing.
|
||||||
*/
|
*/
|
||||||
static int sdmmc_tuning_execute_ddr200(sdmmc_t *sdmmc)
|
static int sdmmc_tuning_execute_ddr200(sdmmc_t *sdmmc)
|
||||||
{
|
{
|
||||||
|
@ -1041,7 +1046,7 @@ static int _sdmmc_config_sdma(sdmmc_t *sdmmc, u32 *blkcnt_out, sdmmc_req_t *req)
|
||||||
|
|
||||||
sdmmc->dma_addr_next = ALIGN_DOWN((admaaddr + SZ_512K), SZ_512K);
|
sdmmc->dma_addr_next = ALIGN_DOWN((admaaddr + SZ_512K), SZ_512K);
|
||||||
|
|
||||||
sdmmc->regs->blksize = req->blksize | (7 << 12); // SDMA DMA 512KB Boundary (Detects A18 carry out).
|
sdmmc->regs->blksize = req->blksize | (7u << 12); // SDMA DMA 512KB Boundary (Detects A18 carry out).
|
||||||
sdmmc->regs->blkcnt = blkcnt;
|
sdmmc->regs->blkcnt = blkcnt;
|
||||||
|
|
||||||
if (blkcnt_out)
|
if (blkcnt_out)
|
||||||
|
|
|
@ -23,9 +23,9 @@
|
||||||
|
|
||||||
/*! SDMMC controller IDs. */
|
/*! SDMMC controller IDs. */
|
||||||
#define SDMMC_1 0 // Version 4.00.
|
#define SDMMC_1 0 // Version 4.00.
|
||||||
#define SDMMC_2 1 // Version 5.1.
|
#define SDMMC_2 1 // Version 5.0 + SW CQE + Enhanced Strobe.
|
||||||
#define SDMMC_3 2 // Version 4.00.
|
#define SDMMC_3 2 // Version 4.00.
|
||||||
#define SDMMC_4 3 // Version 5.1.
|
#define SDMMC_4 3 // Version 5.0 + SW CQE + Enhanced Strobe.
|
||||||
|
|
||||||
/*! SDMMC power types. */
|
/*! SDMMC power types. */
|
||||||
#define SDMMC_POWER_OFF 0
|
#define SDMMC_POWER_OFF 0
|
||||||
|
@ -275,6 +275,7 @@
|
||||||
|
|
||||||
#define HW_TAP_TUNING 0x100
|
#define HW_TAP_TUNING 0x100
|
||||||
#define INVALID_TAP 0x100
|
#define INVALID_TAP 0x100
|
||||||
|
#define SAMPLING_WINDOW_SIZE_MIN 8
|
||||||
|
|
||||||
/*! SDMMC controller context. */
|
/*! SDMMC controller context. */
|
||||||
typedef struct _sdmmc_t
|
typedef struct _sdmmc_t
|
||||||
|
|
Loading…
Reference in a new issue