bdk: sdmmc: refactor comments

This commit is contained in:
CTCaer 2023-06-09 10:36:29 +03:00
parent b674624ad0
commit d621d96af1
4 changed files with 66 additions and 49 deletions

View file

@ -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

View file

@ -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)

View file

@ -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)

View file

@ -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
@ -273,8 +273,9 @@
/*! Helper for SWITCH command argument. */ /*! Helper for SWITCH command argument. */
#define SDMMC_SWITCH(mode, index, value) (((mode) << 24) | ((index) << 16) | ((value) << 8)) #define SDMMC_SWITCH(mode, index, value) (((mode) << 24) | ((index) << 16) | ((value) << 8))
#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