From 206c10f3332adde2ee1296dad54f14da9c6ee1e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mo=C5=84?= Date: Tue, 12 Jun 2018 17:20:15 +0200 Subject: [PATCH] Rework sdmmc clocking configuration Use 204 MHz as host clock in SDR104 mode instead of 136 MHz. Due to this, also change the frequency init divider so the initialization frequency is below 400 kHz. This makes the clocks for SDMMC1 in all modes to match the TRM table. Make it clear in the code that HS200/HS400 modes in fact use PLLP_OUT0 and not PLLC4_OUT2_LJ like the comment suggest. In fact selecting the PLLC4_OUT2_LJ as clock source results in freeze after switching to HS200/HS400 mode. This is most likely related to the PLLC4 not being enabled, but it should be checked later. Set the HS200/HS400 divider to 3, as this is what the code really did set prior to this change - so this commit does not change that. Configure Legacy 12 MHz clock to run at 12 MHz using the SW default configuration (as per TRM) for the SDMMC legacy timer. Introduce initial version of sdmmc_host_clock_delay() in order to use it in places where the wait is host clock dependent. The way it is implemented now does not change the sleep that was used instead. --- fusee/fusee-primary/src/car.h | 11 ++-- fusee/fusee-primary/src/sdmmc.c | 92 ++++++++++++++++++++----------- fusee/fusee-primary/src/sdmmc.h | 2 +- fusee/fusee-secondary/src/car.h | 11 ++-- fusee/fusee-secondary/src/sdmmc.c | 92 ++++++++++++++++++++----------- fusee/fusee-secondary/src/sdmmc.h | 2 +- 6 files changed, 138 insertions(+), 72 deletions(-) diff --git a/fusee/fusee-primary/src/car.h b/fusee/fusee-primary/src/car.h index 9f62ad2a6..593c7a78a 100644 --- a/fusee/fusee-primary/src/car.h +++ b/fusee/fusee-primary/src/car.h @@ -48,11 +48,14 @@ enum { * Masks for TEGRA_CLK_SOURCE elements. */ enum { - CLK_SOURCE_MASK = (0b111 << 29), - CLK_SOURCE_FIRST = (0b000 << 29), + CLK_SOURCE_MASK = (0b111 << 29), + CLK_SOURCE_SDMMC1_PLLP_OUT0 = (0b000 << 29), /* Fixed 408 MHz */ + CLK_SOURCE_SDMMC4_PLLP_OUT0 = (0b000 << 29), /* Fixed 408 MHz */ + CLK_SOURCE_SDMMC4_PLLC4_OUT2_LJ = (0b001 << 29), /* 199.68 MHz */ + CLK_SOURCE_SDMMC_LEGACY_PLLP_OUT0 = (0b100 << 29), /* Fixed 408 MHz */ - CLK_DIVIDER_MASK = (0xff << 0), - CLK_DIVIDER_UNITY = (0x00 << 0), + CLK_DIVIDER_MASK = (0xff << 0), + CLK_DIVIDER_UNITY = (0x00 << 0), }; diff --git a/fusee/fusee-primary/src/sdmmc.c b/fusee/fusee-primary/src/sdmmc.c index 4deb1066d..cc57b0513 100644 --- a/fusee/fusee-primary/src/sdmmc.c +++ b/fusee/fusee-primary/src/sdmmc.c @@ -142,34 +142,52 @@ enum sdmmc_clock_dividers { MMC_CLOCK_DIVIDER_SDR12 = 31, // 16.5, from the TRM table MMC_CLOCK_DIVIDER_SDR25 = 15, // 8.5, from the table MMC_CLOCK_DIVIDER_SDR50 = 7, // 4.5, from the table - MMC_CLOCK_DIVIDER_SDR104 = 4, // 2, from the datasheet + MMC_CLOCK_DIVIDER_SDR104 = 2, // 2, from the table /* Clock dividers: MMC */ MMC_CLOCK_DIVIDER_HS26 = 30, // 16, from the TRM table MMC_CLOCK_DIVIDER_HS52 = 14, // 8, from the table - MMC_CLOCK_DIVIDER_HS200 = 2, // 1 -- NOTE THIS IS WITH RESPECT TO PLLC4_OUT2_LJ - MMC_CLOCK_DIVIDER_HS400 = 2, // 1 -- NOTE THIS IS WITH RESPECT TO PLLC4_OUT2_LJ -}; +#if 0 + // TODO: Figure out why PLLC4_OUT2_LJ doesn't work, most likely need to be enabled in hwinit + MMC_CLOCK_DIVIDER_HS200 = 0, // 1 -- NOTE THIS IS WITH RESPECT TO PLLC4_OUT2_LJ + MMC_CLOCK_DIVIDER_HS400 = 0, // 1 -- NOTE THIS IS WITH RESPECT TO PLLC4_OUT2_LJ +#else + MMC_CLOCK_DIVIDER_HS200 = 3, + MMC_CLOCK_DIVIDER_HS400 = 3, +#endif + /* Clock dividers: Legacy 12 MHz timer */ + MMC_CLOCK_DIVIDER_LEGACY = 66, // 34 - to get 12 MHz out of 408 MHz +}; /** * SDMMC clock divider constants */ enum sdmmc_clock_sources { - /* Clock dividers: SD */ - MMC_CLOCK_SOURCE_SDR12 = 0, // PLLP - MMC_CLOCK_SOURCE_SDR25 = 0, - MMC_CLOCK_SOURCE_SDR50 = 0, - MMC_CLOCK_SOURCE_SDR104 = 0, + /* Clock sources: SD */ + MMC_CLOCK_SOURCE_SDR12 = CLK_SOURCE_SDMMC1_PLLP_OUT0, // PLLP + MMC_CLOCK_SOURCE_SDR25 = CLK_SOURCE_SDMMC1_PLLP_OUT0, + MMC_CLOCK_SOURCE_SDR50 = CLK_SOURCE_SDMMC1_PLLP_OUT0, + MMC_CLOCK_SOURCE_SDR104 = CLK_SOURCE_SDMMC1_PLLP_OUT0, - /* Clock dividers: MMC */ - MMC_CLOCK_SOURCE_HS26 = 0, // PLLP - MMC_CLOCK_SOURCE_HS52 = 0, - MMC_CLOCK_SOURCE_HS200 = 1, // PLLC4_OUT2_LJ - MMC_CLOCK_SOURCE_HS400 = 1, + /* Clock sources: MMC */ + MMC_CLOCK_SOURCE_HS26 = CLK_SOURCE_SDMMC4_PLLP_OUT0, // PLLP + MMC_CLOCK_SOURCE_HS52 = CLK_SOURCE_SDMMC4_PLLP_OUT0, +#if 0 + // TODO: Figure out why PLLC4_OUT2_LJ doesn't work, most likely need to be enabled in hwinit + MMC_CLOCK_SOURCE_HS200 = CLK_SOURCE_SDMMC4_PLLC4_OUT2_LJ, // PLLC4_OUT2_LJ + MMC_CLOCK_SOURCE_HS400 = CLK_SOURCE_SDMMC4_PLLC4_OUT2_LJ, +#else + // For the time being, use PLLP_OUT0 + MMC_CLOCK_SOURCE_HS200 = CLK_SOURCE_SDMMC4_PLLP_OUT0, + MMC_CLOCK_SOURCE_HS400 = CLK_SOURCE_SDMMC4_PLLP_OUT0, +#endif + + /* Clock sources: Legacy 12 MHz timer */ + MMC_CLOCK_SOURCE_LEGACY = CLK_SOURCE_SDMMC_LEGACY_PLLP_OUT0, }; /** @@ -240,7 +258,7 @@ enum sdmmc_register_bits { MMC_CLOCK_CONTROL_CARD_CLOCK_ENABLE = (1 << 2), MMC_CLOCK_CONTROL_FREQUENCY_MASK = (0x3FF << 6), MMC_CLOCK_CONTROL_FREQUENCY_SHIFT = 8, - MMC_CLOCK_CONTROL_FREQUENCY_INIT = 0x18, // generates 400kHz from the TRM dividers + MMC_CLOCK_CONTROL_FREQUENCY_INIT = 0x1F, // generates 400kHz from the TRM dividers MMC_CLOCK_CONTROL_FREQUENCY_PASSTHROUGH = 0x00, // passes through the CAR clock unmodified /* Host control */ @@ -796,6 +814,20 @@ static int sdmmc_hardware_reset(struct mmc *mmc, uint32_t reset_flags) return 0; } +/** + * Delays for a given amount of host clock cycles. + * + * @param mmc The MMC controller whose clock cycles should be waited upon. + * @param clocks The number of clock cycles to wait. + */ +static void sdmmc_host_clock_delay(struct mmc *mmc, unsigned int clocks) +{ + // For the time being simply wait for clocks * 50 us + // This covers clocks as slow as 20 kHz and hence should always be safe + // TODO: determine the actual wait time based on clock source and divider + udelay(50 * clocks); +} + /** * Performs low-level initialization for SDMMC4, used for the eMMC. */ @@ -803,23 +835,22 @@ static int sdmmc4_set_up_clock_and_io(struct mmc *mmc) { volatile struct tegra_car *car = car_get_regs(); volatile struct tegra_padctl *padctl = padctl_get_regs(); - (void)mmc; // Put SDMMC4 in reset car->rst_dev_l_set |= 0x8000; // Configure the clock to place the device into the initial mode. - car->clk_src[CLK_SOURCE_SDMMC4] = CLK_SOURCE_FIRST | MMC_CLOCK_DIVIDER_SDR12; + car->clk_src[CLK_SOURCE_SDMMC4] = MMC_CLOCK_SOURCE_SDR12 | MMC_CLOCK_DIVIDER_SDR12; // Set the legacy divier used for detecting timeouts. - car->clk_src_y[CLK_SOURCE_SDMMC_LEGACY] = CLK_SOURCE_FIRST | MMC_CLOCK_DIVIDER_SDR12; + car->clk_src_y[CLK_SOURCE_SDMMC_LEGACY] = MMC_CLOCK_SOURCE_LEGACY | MMC_CLOCK_DIVIDER_LEGACY; // Set SDMMC4 clock enable car->clk_enb_l_set |= 0x8000; car->clk_enb_y_set |= CAR_CONTROL_SDMMC_LEGACY; - // host_clk_delay(0x64, clk_freq) -> Delay 100 host clock cycles - udelay(5000); + // Delay 100 host clock cycles + sdmmc_host_clock_delay(mmc, 100); // Take SDMMC4 out of reset car->rst_dev_l_clr |= 0x8000; @@ -1102,11 +1133,11 @@ static int sdmmc_always_fail(struct mmc *mmc) * a divider of N results in a clock that's (N/2) + 1 slower. * @param sdmmc_divisor An additional divisor applied in the SDMMC controller. */ -static void sdmmc4_configure_clock(struct mmc *mmc, int source, int car_divisor, int sdmmc_divisor) +static void sdmmc4_configure_clock(struct mmc *mmc, uint32_t source, int car_divisor, int sdmmc_divisor) { volatile struct tegra_car *car = car_get_regs(); - // Set up the CAR aspect of the clock, and wait 2uS per change per the TRM. + // Set up the CAR aspect of the clock, and wait 2us per change per the TRM. car->clk_enb_l_clr = CAR_CONTROL_SDMMC4; car->clk_src[CLK_SOURCE_SDMMC4] = source | car_divisor; udelay(2); @@ -1128,11 +1159,11 @@ static void sdmmc4_configure_clock(struct mmc *mmc, int source, int car_divisor, * a divider of N results in a clock that's (N/2) + 1 slower. * @param sdmmc_divisor An additional divisor applied in the SDMMC controller. */ -static void sdmmc1_configure_clock(struct mmc *mmc, int source, int car_divisor, int sdmmc_divisor) +static void sdmmc1_configure_clock(struct mmc *mmc, uint32_t source, int car_divisor, int sdmmc_divisor) { volatile struct tegra_car *car = car_get_regs(); - // Set up the CAR aspect of the clock, and wait 2uS per change per the TRM. + // Set up the CAR aspect of the clock, and wait 2us per change per the TRM. car->clk_enb_l_clr = CAR_CONTROL_SDMMC1; car->clk_src[CLK_SOURCE_SDMMC1] = source | car_divisor; udelay(2); @@ -1469,7 +1500,6 @@ static int sdmmc1_set_up_clock_and_io(struct mmc *mmc) volatile struct tegra_car *car = car_get_regs(); volatile struct tegra_pinmux *pinmux = pinmux_get_regs(); volatile struct tegra_padctl *padctl = padctl_get_regs(); - (void)mmc; // Set up each of the relevant pins to be connected to output drivers, // and selected for SDMMC use. @@ -1493,19 +1523,19 @@ static int sdmmc1_set_up_clock_and_io(struct mmc *mmc) car->rst_dev_l_set = CAR_CONTROL_SDMMC1; // Configure the clock to place the device into the initial mode. - car->clk_src[CLK_SOURCE_SDMMC1] = CLK_SOURCE_FIRST | MMC_CLOCK_DIVIDER_SDR12; + car->clk_src[CLK_SOURCE_SDMMC1] = MMC_CLOCK_SOURCE_SDR12 | MMC_CLOCK_DIVIDER_SDR12; // Set the legacy divier used for detecting timeouts. - car->clk_src_y[CLK_SOURCE_SDMMC_LEGACY] = CLK_SOURCE_FIRST | MMC_CLOCK_DIVIDER_SDR12; + car->clk_src_y[CLK_SOURCE_SDMMC_LEGACY] = MMC_CLOCK_SOURCE_LEGACY | MMC_CLOCK_DIVIDER_LEGACY; // Set SDMMC1 clock enable car->clk_enb_l_set = CAR_CONTROL_SDMMC1; car->clk_enb_y_set = CAR_CONTROL_SDMMC_LEGACY; - // host_clk_delay(0x64, clk_freq) -> Delay 100 host clock cycles - udelay(5000); + // Delay 100 host clock cycles + sdmmc_host_clock_delay(mmc, 100); - // Take SDMMC4 out of reset + // Take SDMMC1 out of reset car->rst_dev_l_clr |= CAR_CONTROL_SDMMC1; // Enable clock loopback. @@ -3443,7 +3473,7 @@ int sdmmc_init(struct mmc *mmc, enum sdmmc_controller controller, bool allow_vol return rc; } - // Default to a timeout of 1S. + // Default to a timeout of 1s. mmc->timeout = 1000000; mmc->partition_switch_time = 1000; diff --git a/fusee/fusee-primary/src/sdmmc.h b/fusee/fusee-primary/src/sdmmc.h index 97fc69f65..63538a405 100644 --- a/fusee/fusee-primary/src/sdmmc.h +++ b/fusee/fusee-primary/src/sdmmc.h @@ -157,7 +157,7 @@ struct mmc { /* Per-controller operations. */ int (*set_up_clock_and_io)(struct mmc *mmc); - void (*configure_clock)(struct mmc *mmc, int source, int car_divisor, int sdmmc_divisor); + void (*configure_clock)(struct mmc *mmc, uint32_t source, int car_divisor, int sdmmc_divisor); int (*enable_supplies)(struct mmc *mmc); int (*switch_to_low_voltage)(struct mmc *mmc); bool (*card_present)(struct mmc *mmc); diff --git a/fusee/fusee-secondary/src/car.h b/fusee/fusee-secondary/src/car.h index 9f62ad2a6..593c7a78a 100644 --- a/fusee/fusee-secondary/src/car.h +++ b/fusee/fusee-secondary/src/car.h @@ -48,11 +48,14 @@ enum { * Masks for TEGRA_CLK_SOURCE elements. */ enum { - CLK_SOURCE_MASK = (0b111 << 29), - CLK_SOURCE_FIRST = (0b000 << 29), + CLK_SOURCE_MASK = (0b111 << 29), + CLK_SOURCE_SDMMC1_PLLP_OUT0 = (0b000 << 29), /* Fixed 408 MHz */ + CLK_SOURCE_SDMMC4_PLLP_OUT0 = (0b000 << 29), /* Fixed 408 MHz */ + CLK_SOURCE_SDMMC4_PLLC4_OUT2_LJ = (0b001 << 29), /* 199.68 MHz */ + CLK_SOURCE_SDMMC_LEGACY_PLLP_OUT0 = (0b100 << 29), /* Fixed 408 MHz */ - CLK_DIVIDER_MASK = (0xff << 0), - CLK_DIVIDER_UNITY = (0x00 << 0), + CLK_DIVIDER_MASK = (0xff << 0), + CLK_DIVIDER_UNITY = (0x00 << 0), }; diff --git a/fusee/fusee-secondary/src/sdmmc.c b/fusee/fusee-secondary/src/sdmmc.c index 1f6879e3a..e34b17f60 100644 --- a/fusee/fusee-secondary/src/sdmmc.c +++ b/fusee/fusee-secondary/src/sdmmc.c @@ -141,34 +141,52 @@ enum sdmmc_clock_dividers { MMC_CLOCK_DIVIDER_SDR12 = 31, // 16.5, from the TRM table MMC_CLOCK_DIVIDER_SDR25 = 15, // 8.5, from the table MMC_CLOCK_DIVIDER_SDR50 = 7, // 4.5, from the table - MMC_CLOCK_DIVIDER_SDR104 = 4, // 2, from the datasheet + MMC_CLOCK_DIVIDER_SDR104 = 2, // 2, from the table /* Clock dividers: MMC */ MMC_CLOCK_DIVIDER_HS26 = 30, // 16, from the TRM table MMC_CLOCK_DIVIDER_HS52 = 14, // 8, from the table - MMC_CLOCK_DIVIDER_HS200 = 2, // 1 -- NOTE THIS IS WITH RESPECT TO PLLC4_OUT2_LJ - MMC_CLOCK_DIVIDER_HS400 = 2, // 1 -- NOTE THIS IS WITH RESPECT TO PLLC4_OUT2_LJ -}; +#if 0 + // TODO: Figure out why PLLC4_OUT2_LJ doesn't work, most likely need to be enabled in hwinit + MMC_CLOCK_DIVIDER_HS200 = 0, // 1 -- NOTE THIS IS WITH RESPECT TO PLLC4_OUT2_LJ + MMC_CLOCK_DIVIDER_HS400 = 0, // 1 -- NOTE THIS IS WITH RESPECT TO PLLC4_OUT2_LJ +#else + MMC_CLOCK_DIVIDER_HS200 = 3, + MMC_CLOCK_DIVIDER_HS400 = 3, +#endif + /* Clock dividers: Legacy 12 MHz timer */ + MMC_CLOCK_DIVIDER_LEGACY = 66, // 34 - to get 12 MHz out of 408 MHz +}; /** * SDMMC clock divider constants */ enum sdmmc_clock_sources { - /* Clock dividers: SD */ - MMC_CLOCK_SOURCE_SDR12 = 0, // PLLP - MMC_CLOCK_SOURCE_SDR25 = 0, - MMC_CLOCK_SOURCE_SDR50 = 0, - MMC_CLOCK_SOURCE_SDR104 = 0, + /* Clock sources: SD */ + MMC_CLOCK_SOURCE_SDR12 = CLK_SOURCE_SDMMC1_PLLP_OUT0, // PLLP + MMC_CLOCK_SOURCE_SDR25 = CLK_SOURCE_SDMMC1_PLLP_OUT0, + MMC_CLOCK_SOURCE_SDR50 = CLK_SOURCE_SDMMC1_PLLP_OUT0, + MMC_CLOCK_SOURCE_SDR104 = CLK_SOURCE_SDMMC1_PLLP_OUT0, - /* Clock dividers: MMC */ - MMC_CLOCK_SOURCE_HS26 = 0, // PLLP - MMC_CLOCK_SOURCE_HS52 = 0, - MMC_CLOCK_SOURCE_HS200 = 1, // PLLC4_OUT2_LJ - MMC_CLOCK_SOURCE_HS400 = 1, + /* Clock sources: MMC */ + MMC_CLOCK_SOURCE_HS26 = CLK_SOURCE_SDMMC4_PLLP_OUT0, // PLLP + MMC_CLOCK_SOURCE_HS52 = CLK_SOURCE_SDMMC4_PLLP_OUT0, +#if 0 + // TODO: Figure out why PLLC4_OUT2_LJ doesn't work, most likely need to be enabled in hwinit + MMC_CLOCK_SOURCE_HS200 = CLK_SOURCE_SDMMC4_PLLC4_OUT2_LJ, // PLLC4_OUT2_LJ + MMC_CLOCK_SOURCE_HS400 = CLK_SOURCE_SDMMC4_PLLC4_OUT2_LJ, +#else + // For the time being, use PLLP_OUT0 + MMC_CLOCK_SOURCE_HS200 = CLK_SOURCE_SDMMC4_PLLP_OUT0, + MMC_CLOCK_SOURCE_HS400 = CLK_SOURCE_SDMMC4_PLLP_OUT0, +#endif + + /* Clock sources: Legacy 12 MHz timer */ + MMC_CLOCK_SOURCE_LEGACY = CLK_SOURCE_SDMMC_LEGACY_PLLP_OUT0, }; /** @@ -239,7 +257,7 @@ enum sdmmc_register_bits { MMC_CLOCK_CONTROL_CARD_CLOCK_ENABLE = (1 << 2), MMC_CLOCK_CONTROL_FREQUENCY_MASK = (0x3FF << 6), MMC_CLOCK_CONTROL_FREQUENCY_SHIFT = 8, - MMC_CLOCK_CONTROL_FREQUENCY_INIT = 0x18, // generates 400kHz from the TRM dividers + MMC_CLOCK_CONTROL_FREQUENCY_INIT = 0x1F, // generates 400kHz from the TRM dividers MMC_CLOCK_CONTROL_FREQUENCY_PASSTHROUGH = 0x00, // passes through the CAR clock unmodified /* Host control */ @@ -797,6 +815,20 @@ static int sdmmc_hardware_reset(struct mmc *mmc, uint32_t reset_flags) return 0; } +/** + * Delays for a given amount of host clock cycles. + * + * @param mmc The MMC controller whose clock cycles should be waited upon. + * @param clocks The number of clock cycles to wait. + */ +static void sdmmc_host_clock_delay(struct mmc *mmc, unsigned int clocks) +{ + // For the time being simply wait for clocks * 50 us + // This covers clocks as slow as 20 kHz and hence should always be safe + // TODO: determine the actual wait time based on clock source and divider + udelay(50 * clocks); +} + /** * Performs low-level initialization for SDMMC4, used for the eMMC. */ @@ -804,23 +836,22 @@ static int sdmmc4_set_up_clock_and_io(struct mmc *mmc) { volatile struct tegra_car *car = car_get_regs(); volatile struct tegra_padctl *padctl = padctl_get_regs(); - (void)mmc; // Put SDMMC4 in reset car->rst_dev_l_set |= 0x8000; // Configure the clock to place the device into the initial mode. - car->clk_src[CLK_SOURCE_SDMMC4] = CLK_SOURCE_FIRST | MMC_CLOCK_DIVIDER_SDR12; + car->clk_src[CLK_SOURCE_SDMMC4] = MMC_CLOCK_SOURCE_SDR12 | MMC_CLOCK_DIVIDER_SDR12; // Set the legacy divier used for detecting timeouts. - car->clk_src_y[CLK_SOURCE_SDMMC_LEGACY] = CLK_SOURCE_FIRST | MMC_CLOCK_DIVIDER_SDR12; + car->clk_src_y[CLK_SOURCE_SDMMC_LEGACY] = MMC_CLOCK_SOURCE_LEGACY | MMC_CLOCK_DIVIDER_LEGACY; // Set SDMMC4 clock enable car->clk_enb_l_set |= 0x8000; car->clk_enb_y_set |= CAR_CONTROL_SDMMC_LEGACY; - // host_clk_delay(0x64, clk_freq) -> Delay 100 host clock cycles - udelay(5000); + // Delay 100 host clock cycles + sdmmc_host_clock_delay(mmc, 100); // Take SDMMC4 out of reset car->rst_dev_l_clr |= 0x8000; @@ -1103,11 +1134,11 @@ static int sdmmc_always_fail(struct mmc *mmc) * a divider of N results in a clock that's (N/2) + 1 slower. * @param sdmmc_divisor An additional divisor applied in the SDMMC controller. */ -static void sdmmc4_configure_clock(struct mmc *mmc, int source, int car_divisor, int sdmmc_divisor) +static void sdmmc4_configure_clock(struct mmc *mmc, uint32_t source, int car_divisor, int sdmmc_divisor) { volatile struct tegra_car *car = car_get_regs(); - // Set up the CAR aspect of the clock, and wait 2uS per change per the TRM. + // Set up the CAR aspect of the clock, and wait 2us per change per the TRM. car->clk_enb_l_clr = CAR_CONTROL_SDMMC4; car->clk_src[CLK_SOURCE_SDMMC4] = source | car_divisor; udelay(2); @@ -1129,11 +1160,11 @@ static void sdmmc4_configure_clock(struct mmc *mmc, int source, int car_divisor, * a divider of N results in a clock that's (N/2) + 1 slower. * @param sdmmc_divisor An additional divisor applied in the SDMMC controller. */ -static void sdmmc1_configure_clock(struct mmc *mmc, int source, int car_divisor, int sdmmc_divisor) +static void sdmmc1_configure_clock(struct mmc *mmc, uint32_t source, int car_divisor, int sdmmc_divisor) { volatile struct tegra_car *car = car_get_regs(); - // Set up the CAR aspect of the clock, and wait 2uS per change per the TRM. + // Set up the CAR aspect of the clock, and wait 2us per change per the TRM. car->clk_enb_l_clr = CAR_CONTROL_SDMMC1; car->clk_src[CLK_SOURCE_SDMMC1] = source | car_divisor; udelay(2); @@ -1470,7 +1501,6 @@ static int sdmmc1_set_up_clock_and_io(struct mmc *mmc) volatile struct tegra_car *car = car_get_regs(); volatile struct tegra_pinmux *pinmux = pinmux_get_regs(); volatile struct tegra_padctl *padctl = padctl_get_regs(); - (void)mmc; // Set up each of the relevant pins to be connected to output drivers, // and selected for SDMMC use. @@ -1494,19 +1524,19 @@ static int sdmmc1_set_up_clock_and_io(struct mmc *mmc) car->rst_dev_l_set = CAR_CONTROL_SDMMC1; // Configure the clock to place the device into the initial mode. - car->clk_src[CLK_SOURCE_SDMMC1] = CLK_SOURCE_FIRST | MMC_CLOCK_DIVIDER_SDR12; + car->clk_src[CLK_SOURCE_SDMMC1] = MMC_CLOCK_SOURCE_SDR12 | MMC_CLOCK_DIVIDER_SDR12; // Set the legacy divier used for detecting timeouts. - car->clk_src_y[CLK_SOURCE_SDMMC_LEGACY] = CLK_SOURCE_FIRST | MMC_CLOCK_DIVIDER_SDR12; + car->clk_src_y[CLK_SOURCE_SDMMC_LEGACY] = MMC_CLOCK_SOURCE_LEGACY | MMC_CLOCK_DIVIDER_LEGACY; // Set SDMMC1 clock enable car->clk_enb_l_set = CAR_CONTROL_SDMMC1; car->clk_enb_y_set = CAR_CONTROL_SDMMC_LEGACY; - // host_clk_delay(0x64, clk_freq) -> Delay 100 host clock cycles - udelay(5000); + // Delay 100 host clock cycles + sdmmc_host_clock_delay(mmc, 100); - // Take SDMMC4 out of reset + // Take SDMMC1 out of reset car->rst_dev_l_clr |= CAR_CONTROL_SDMMC1; // Enable clock loopback. @@ -3444,7 +3474,7 @@ int sdmmc_init(struct mmc *mmc, enum sdmmc_controller controller, bool allow_vol return rc; } - // Default to a timeout of 1S. + // Default to a timeout of 1s. mmc->timeout = 1000000; mmc->partition_switch_time = 1000; diff --git a/fusee/fusee-secondary/src/sdmmc.h b/fusee/fusee-secondary/src/sdmmc.h index 97fc69f65..63538a405 100644 --- a/fusee/fusee-secondary/src/sdmmc.h +++ b/fusee/fusee-secondary/src/sdmmc.h @@ -157,7 +157,7 @@ struct mmc { /* Per-controller operations. */ int (*set_up_clock_and_io)(struct mmc *mmc); - void (*configure_clock)(struct mmc *mmc, int source, int car_divisor, int sdmmc_divisor); + void (*configure_clock)(struct mmc *mmc, uint32_t source, int car_divisor, int sdmmc_divisor); int (*enable_supplies)(struct mmc *mmc); int (*switch_to_low_voltage)(struct mmc *mmc); bool (*card_present)(struct mmc *mmc);