summaryrefslogtreecommitdiffstats
path: root/firmware/target
diff options
context:
space:
mode:
authorAmaury Pouly <amaury.pouly@gmail.com>2013-08-21 11:11:36 +0200
committerAmaury Pouly <amaury.pouly@gmail.com>2013-08-21 20:18:36 +0200
commit96d355abba19f3f099f94a8b2d3e95be32c39be7 (patch)
treef7f7a31eb7f6d69430f9a2eda4e2dd5d8dcebdfe /firmware/target
parent462adf2a0fefbfdbccfafa11c999ac6beb114e8a (diff)
downloadrockbox-96d355abba19f3f099f94a8b2d3e95be32c39be7.tar.gz
rockbox-96d355abba19f3f099f94a8b2d3e95be32c39be7.zip
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
Diffstat (limited to 'firmware/target')
-rw-r--r--firmware/target/arm/imx233/sdmmc-imx233.c20
-rw-r--r--firmware/target/arm/imx233/ssp-imx233.c61
-rw-r--r--firmware/target/arm/imx233/ssp-imx233.h6
3 files changed, 47 insertions, 40 deletions
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