From 96d355abba19f3f099f94a8b2d3e95be32c39be7 Mon Sep 17 00:00:00 2001 From: Amaury Pouly Date: Wed, 21 Aug 2013 11:11:36 +0200 Subject: imx233: fix drive strength for sd/mmc At high speed, we need a drive strength of 8mA on the clock line to get stable transfers. Change-Id: Ida668db10cd3e10ad5740e35fd973f2fa394edb2 --- firmware/target/arm/imx233/sdmmc-imx233.c | 20 ++++++---- firmware/target/arm/imx233/ssp-imx233.c | 61 ++++++++++++++++--------------- firmware/target/arm/imx233/ssp-imx233.h | 6 +-- 3 files changed, 47 insertions(+), 40 deletions(-) (limited to 'firmware/target/arm') diff --git a/firmware/target/arm/imx233/sdmmc-imx233.c b/firmware/target/arm/imx233/sdmmc-imx233.c index 99dd817ec6..164bf79eee 100644 --- a/firmware/target/arm/imx233/sdmmc-imx233.c +++ b/firmware/target/arm/imx233/sdmmc-imx233.c @@ -206,6 +206,17 @@ static void sdmmc_detect_callback(int ssp) imx233_ssp_sdmmc_is_detect_inverted(ssp)); } +static void sdmmc_enable_pullups(int drive, bool pullup) +{ + /* setup pins, never use alternatives pin on SSP1 because no device use it + * but this could be made a flag */ + int bus_width = SDMMC_MODE(drive) == MMC_MODE ? 8 : 4; + if(SDMMC_SSP(drive) == 1) + imx233_ssp_setup_ssp1_sd_mmc_pins(pullup, bus_width, false); + else + imx233_ssp_setup_ssp2_sd_mmc_pins(pullup, bus_width); +} + static void sdmmc_power(int drive, bool on) { /* power chip if needed */ @@ -223,13 +234,8 @@ static void sdmmc_power(int drive, bool on) } if(SDMMC_FLAGS(drive) & POWER_DELAY) sleep(SDMMC_CONF(drive).power_delay); - /* setup pins, never use alternatives pin on SSP1 because no device use it - * but this could be made a flag */ - int bus_width = SDMMC_MODE(drive) == MMC_MODE ? 8 : 4; - if(SDMMC_SSP(drive) == 1) - imx233_ssp_setup_ssp1_sd_mmc_pins(on, bus_width, PINCTRL_DRIVE_4mA, false); - else - imx233_ssp_setup_ssp2_sd_mmc_pins(on, bus_width, PINCTRL_DRIVE_4mA); + /* enable pullups for identification */ + sdmmc_enable_pullups(drive, true); } #define MCI_NO_RESP 0 diff --git a/firmware/target/arm/imx233/ssp-imx233.c b/firmware/target/arm/imx233/ssp-imx233.c index e73c09bfca..2873ab9604 100644 --- a/firmware/target/arm/imx233/ssp-imx233.c +++ b/firmware/target/arm/imx233/ssp-imx233.c @@ -168,24 +168,27 @@ void imx233_ssp_softreset(int ssp) void imx233_ssp_set_timings(int ssp, int divide, int rate, int timeout) { ASSERT_SSP(ssp) + if(divide == 0 || (divide % 2) == 1) + panicf("SSP timing divide must be event"); SSP_REGn(SSP_TIMING, ssp) = BF_OR3(SSP_TIMING, CLOCK_DIVIDE(divide), CLOCK_RATE(rate), TIMEOUT(timeout)); } -void imx233_ssp_setup_ssp1_sd_mmc_pins(bool enable_pullups, unsigned bus_width, - unsigned drive_strength, bool use_alt) +void imx233_ssp_setup_ssp1_sd_mmc_pins(bool enable_pullups, unsigned bus_width, bool use_alt) { (void) use_alt; + unsigned clk_drive = PINCTRL_DRIVE_8mA; + unsigned dat_drive = PINCTRL_DRIVE_4mA; /* SSP_{CMD,SCK} */ - imx233_pinctrl_setup_vpin(VPIN_SSP1_CMD, "ssp1_cmd", drive_strength, enable_pullups); - imx233_pinctrl_setup_vpin(VPIN_SSP1_SCK, "ssp1_sck", drive_strength, false); + imx233_pinctrl_setup_vpin(VPIN_SSP1_CMD, "ssp1_cmd", dat_drive, enable_pullups); + imx233_pinctrl_setup_vpin(VPIN_SSP1_SCK, "ssp1_sck", clk_drive, false); /* SSP_DATA{0-3} */ - imx233_pinctrl_setup_vpin(VPIN_SSP1_D0, "ssp1_d0", drive_strength, enable_pullups); + imx233_pinctrl_setup_vpin(VPIN_SSP1_D0, "ssp1_d0", dat_drive, enable_pullups); if(bus_width >= 4) { - imx233_pinctrl_setup_vpin(VPIN_SSP1_D1, "ssp1_d1", drive_strength, enable_pullups); - imx233_pinctrl_setup_vpin(VPIN_SSP1_D2, "ssp1_d2", drive_strength, enable_pullups); - imx233_pinctrl_setup_vpin(VPIN_SSP1_D3, "ssp1_d3", drive_strength, enable_pullups); + imx233_pinctrl_setup_vpin(VPIN_SSP1_D1, "ssp1_d1", dat_drive, enable_pullups); + imx233_pinctrl_setup_vpin(VPIN_SSP1_D2, "ssp1_d2", dat_drive, enable_pullups); + imx233_pinctrl_setup_vpin(VPIN_SSP1_D3, "ssp1_d3", dat_drive, enable_pullups); } if(bus_width >= 8) { @@ -193,20 +196,20 @@ void imx233_ssp_setup_ssp1_sd_mmc_pins(bool enable_pullups, unsigned bus_width, if(use_alt) { #ifdef VPIN_SSP1_D4_ALT - imx233_pinctrl_setup_vpin(VPIN_SSP1_D4_ALT, "ssp1_d4", drive_strength, enable_pullups); - imx233_pinctrl_setup_vpin(VPIN_SSP1_D5_ALT, "ssp1_d5", drive_strength, enable_pullups); - imx233_pinctrl_setup_vpin(VPIN_SSP1_D6_ALT, "ssp1_d6", drive_strength, enable_pullups); - imx233_pinctrl_setup_vpin(VPIN_SSP1_D7_ALT, "ssp1_d7", drive_strength, enable_pullups); + imx233_pinctrl_setup_vpin(VPIN_SSP1_D4_ALT, "ssp1_d4", dat_drive, enable_pullups); + imx233_pinctrl_setup_vpin(VPIN_SSP1_D5_ALT, "ssp1_d5", dat_drive, enable_pullups); + imx233_pinctrl_setup_vpin(VPIN_SSP1_D6_ALT, "ssp1_d6", dat_drive, enable_pullups); + imx233_pinctrl_setup_vpin(VPIN_SSP1_D7_ALT, "ssp1_d7", dat_drive, enable_pullups); #else panicf("there is ssp1 alt on this soc!"); #endif } else { - imx233_pinctrl_setup_vpin(VPIN_SSP1_D4, "ssp1_d4", drive_strength, enable_pullups); - imx233_pinctrl_setup_vpin(VPIN_SSP1_D5, "ssp1_d5", drive_strength, enable_pullups); - imx233_pinctrl_setup_vpin(VPIN_SSP1_D6, "ssp1_d6", drive_strength, enable_pullups); - imx233_pinctrl_setup_vpin(VPIN_SSP1_D7, "ssp1_d7", drive_strength, enable_pullups); + imx233_pinctrl_setup_vpin(VPIN_SSP1_D4, "ssp1_d4", dat_drive, enable_pullups); + imx233_pinctrl_setup_vpin(VPIN_SSP1_D5, "ssp1_d5", dat_drive, enable_pullups); + imx233_pinctrl_setup_vpin(VPIN_SSP1_D6, "ssp1_d6", dat_drive, enable_pullups); + imx233_pinctrl_setup_vpin(VPIN_SSP1_D7, "ssp1_d7", dat_drive, enable_pullups); } #else panicf("ssp1 bus width is limited to 4 on this soc!"); @@ -214,30 +217,30 @@ void imx233_ssp_setup_ssp1_sd_mmc_pins(bool enable_pullups, unsigned bus_width, } } -void imx233_ssp_setup_ssp2_sd_mmc_pins(bool enable_pullups, unsigned bus_width, - unsigned drive_strength) +void imx233_ssp_setup_ssp2_sd_mmc_pins(bool enable_pullups, unsigned bus_width) { (void) enable_pullups; (void) bus_width; - (void) drive_strength; + unsigned clk_drive = PINCTRL_DRIVE_8mA; + unsigned dat_drive = PINCTRL_DRIVE_4mA; #ifdef VPIN_SSP2_CMD /* SSP_{CMD,SCK} */ - imx233_pinctrl_setup_vpin(VPIN_SSP2_CMD, "ssp2_cmd", drive_strength, enable_pullups); - imx233_pinctrl_setup_vpin(VPIN_SSP2_SCK, "ssp2_sck", drive_strength, false); + imx233_pinctrl_setup_vpin(VPIN_SSP2_CMD, "ssp2_cmd", dat_drive, enable_pullups); + imx233_pinctrl_setup_vpin(VPIN_SSP2_SCK, "ssp2_sck", clk_drive, false); /* SSP_DATA{0-3} */ - imx233_pinctrl_setup_vpin(VPIN_SSP2_D0, "ssp2_d0", drive_strength, enable_pullups); + imx233_pinctrl_setup_vpin(VPIN_SSP2_D0, "ssp2_d0", dat_drive, enable_pullups); if(bus_width >= 4) { - imx233_pinctrl_setup_vpin(VPIN_SSP2_D1, "ssp2_d1", drive_strength, enable_pullups); - imx233_pinctrl_setup_vpin(VPIN_SSP2_D2, "ssp2_d2", drive_strength, enable_pullups); - imx233_pinctrl_setup_vpin(VPIN_SSP2_D3, "ssp2_d3", drive_strength, enable_pullups); + imx233_pinctrl_setup_vpin(VPIN_SSP2_D1, "ssp2_d1", dat_drive, enable_pullups); + imx233_pinctrl_setup_vpin(VPIN_SSP2_D2, "ssp2_d2", dat_drive, enable_pullups); + imx233_pinctrl_setup_vpin(VPIN_SSP2_D3, "ssp2_d3", dat_drive, enable_pullups); } if(bus_width >= 8) { - imx233_pinctrl_setup_vpin(VPIN_SSP2_D4, "ssp2_d4", drive_strength, enable_pullups); - imx233_pinctrl_setup_vpin(VPIN_SSP2_D5, "ssp2_d5", drive_strength, enable_pullups); - imx233_pinctrl_setup_vpin(VPIN_SSP2_D6, "ssp2_d6", drive_strength, enable_pullups); - imx233_pinctrl_setup_vpin(VPIN_SSP2_D7, "ssp2_d7", drive_strength, enable_pullups); + imx233_pinctrl_setup_vpin(VPIN_SSP2_D4, "ssp2_d4", dat_drive, enable_pullups); + imx233_pinctrl_setup_vpin(VPIN_SSP2_D5, "ssp2_d5", dat_drive, enable_pullups); + imx233_pinctrl_setup_vpin(VPIN_SSP2_D6, "ssp2_d6", dat_drive, enable_pullups); + imx233_pinctrl_setup_vpin(VPIN_SSP2_D7, "ssp2_d7", dat_drive, enable_pullups); } #else panicf("there is no ssp2 on this soc!"); diff --git a/firmware/target/arm/imx233/ssp-imx233.h b/firmware/target/arm/imx233/ssp-imx233.h index e58c9e1c09..42c8d1fe7b 100644 --- a/firmware/target/arm/imx233/ssp-imx233.h +++ b/firmware/target/arm/imx233/ssp-imx233.h @@ -98,10 +98,8 @@ enum imx233_ssp_error_t imx233_ssp_sd_mmc_transfer(int ssp, uint8_t cmd, uint32_t cmd_arg, enum imx233_ssp_resp_t resp, void *buffer, unsigned block_count, bool wait4irq, bool read, uint32_t *resp_ptr); /* pullups/alternative are ignored on targets which don't support it */ -void imx233_ssp_setup_ssp1_sd_mmc_pins(bool enable_pullups, unsigned bus_width, - unsigned drive_strength, bool use_alt); -void imx233_ssp_setup_ssp2_sd_mmc_pins(bool enable_pullups, unsigned bus_width, - unsigned drive_strength); +void imx233_ssp_setup_ssp1_sd_mmc_pins(bool enable_pullups, unsigned bus_width, bool use_alt); +void imx233_ssp_setup_ssp2_sd_mmc_pins(bool enable_pullups, unsigned bus_width); /* after callback is fired, imx233_ssp_sdmmc_setup_detect needs to be called * to enable detection again. If first_time is true, the callback will * be called if the sd card is inserted when the function is called, otherwise -- cgit v1.2.3