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
This commit is contained in:
parent
462adf2a0f
commit
96d355abba
3 changed files with 47 additions and 40 deletions
|
@ -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
|
||||
|
|
|
@ -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!");
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue