mirror of
https://github.com/apache/nuttx.git
synced 2026-08-01 20:28:58 +00:00
arch/arm/src/stm32{h7,f7,l4}: add 4-bit wide bus support for MMC/eMMC cards
The STM32H7, STM32F7, STM32L4 and common STM32 SDIO/SDMMC drivers failed to program the WIDBUS bits when switching MMC/eMMC cards to 4-bit mode, and the MMC transfer clock presets were hardwired to 1-bit bus width. Add CLOCK_MMC_TRANSFER_4BIT to the common SDIO clock enum, add 4-bit MMC clock presets, and update stm32_widebus() to use modifyreg32/ sdmmc_modifyreg32 to set the host controller bus width. Signed-off-by: DuoYuWang <thirteenking.wang@gmail.com>
This commit is contained in:
parent
85ad737463
commit
82ab33aed6
5 changed files with 72 additions and 2 deletions
|
|
@ -165,6 +165,8 @@
|
|||
SDIO_CLKCR_WIDBUS_D1)
|
||||
#define SDIO_CLKCR_MMCXFR (SDIO_MMCXFR_CLKDIV | SDIO_CLKCR_EDGE | \
|
||||
SDIO_CLKCR_WIDBUS_D1)
|
||||
#define SDIO_CLKCR_MMCXFR4 (SDIO_MMCXFR_CLKDIV | SDIO_CLKCR_EDGE | \
|
||||
SDIO_CLKCR_WIDBUS_D4)
|
||||
#define SDIO_CLCKR_SDXFR (SDIO_SDXFR_CLKDIV | SDIO_CLKCR_EDGE | \
|
||||
SDIO_CLKCR_WIDBUS_D1)
|
||||
#define SDIO_CLCKR_SDWIDEXFR (SDIO_SDXFR_CLKDIV | SDIO_CLKCR_EDGE | \
|
||||
|
|
@ -1734,7 +1736,11 @@ static sdio_statset_t stm32_status(struct sdio_dev_s *dev)
|
|||
static void stm32_widebus(struct sdio_dev_s *dev, bool wide)
|
||||
{
|
||||
struct stm32_dev_s *priv = (struct stm32_dev_s *)dev;
|
||||
uint32_t widbus = wide ? SDIO_CLKCR_WIDBUS_D4 : SDIO_CLKCR_WIDBUS_D1;
|
||||
|
||||
priv->widebus = wide;
|
||||
|
||||
modifyreg32(STM32_SDIO_CLKCR, SDIO_CLKCR_WIDBUS_MASK, widbus);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
@ -1777,6 +1783,12 @@ static void stm32_clock(struct sdio_dev_s *dev, enum sdio_clock_e rate)
|
|||
clckr = (SDIO_CLKCR_MMCXFR | SDIO_CLKCR_CLKEN);
|
||||
break;
|
||||
|
||||
/* Enable in MMC wide (4-bit) operation clocking */
|
||||
|
||||
case CLOCK_MMC_TRANSFER_4BIT:
|
||||
clckr = (SDIO_CLKCR_MMCXFR4 | SDIO_CLKCR_CLKEN);
|
||||
break;
|
||||
|
||||
/* SD normal operation clocking (wide 4-bit mode) */
|
||||
|
||||
case CLOCK_SD_TRANSFER_4BIT:
|
||||
|
|
|
|||
|
|
@ -204,6 +204,9 @@
|
|||
#define STM32_SDMMC_CLKCR_MMCXFR (STM32_SDMMC_MMCXFR_CLKDIV | \
|
||||
STM32_SDMMC_CLKCR_EDGE | \
|
||||
STM32_SDMMC_CLKCR_WIDBUS_D1)
|
||||
#define STM32_SDMMC_CLKCR_MMCXFR4 (STM32_SDMMC_MMCXFR_CLKDIV | \
|
||||
STM32_SDMMC_CLKCR_EDGE | \
|
||||
STM32_SDMMC_CLKCR_WIDBUS_D4)
|
||||
|
||||
#ifdef STM32_SDMMC_SDXFR_BYPCLKDIV
|
||||
# define STM32_SDMMC_CLCKR_SDXFR (STM32_SDMMC_CLKCR_BYPASS | \
|
||||
|
|
@ -1991,7 +1994,13 @@ static sdio_statset_t stm32_status(struct sdio_dev_s *dev)
|
|||
static void stm32_widebus(struct sdio_dev_s *dev, bool wide)
|
||||
{
|
||||
struct stm32_dev_s *priv = (struct stm32_dev_s *)dev;
|
||||
uint32_t widbus = wide ? STM32_SDMMC_CLKCR_WIDBUS_D4 :
|
||||
STM32_SDMMC_CLKCR_WIDBUS_D1;
|
||||
|
||||
priv->widebus = wide;
|
||||
|
||||
sdmmc_modifyreg32(priv, STM32_SDMMC_CLKCR_OFFSET,
|
||||
STM32_SDMMC_CLKCR_WIDBUS_MASK, widbus);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
@ -2035,6 +2044,12 @@ static void stm32_clock(struct sdio_dev_s *dev, enum sdio_clock_e rate)
|
|||
clckr = (STM32_SDMMC_CLKCR_MMCXFR | STM32_SDMMC_CLKCR_CLKEN);
|
||||
break;
|
||||
|
||||
/* Enable in MMC wide (4-bit) operation clocking */
|
||||
|
||||
case CLOCK_MMC_TRANSFER_4BIT:
|
||||
clckr = (STM32_SDMMC_CLKCR_MMCXFR4 | STM32_SDMMC_CLKCR_CLKEN);
|
||||
break;
|
||||
|
||||
/* SD normal operation clocking (wide 4-bit mode) */
|
||||
|
||||
case CLOCK_SD_TRANSFER_4BIT:
|
||||
|
|
|
|||
|
|
@ -210,6 +210,10 @@
|
|||
STM32_SDMMC_CLKCR_EDGE | \
|
||||
STM32_SDMMC_CLKCR_PWRSAV | \
|
||||
STM32_SDMMC_CLKCR_WIDBUS_D1)
|
||||
#define STM32_SDMMC_CLKCR_MMCXFR4 (STM32_SDMMC_MMCXFR_CLKDIV | \
|
||||
STM32_SDMMC_CLKCR_EDGE | \
|
||||
STM32_SDMMC_CLKCR_PWRSAV | \
|
||||
STM32_SDMMC_CLKCR_WIDBUS_D4)
|
||||
#define STM32_SDMMC_CLCKR_SDXFR (STM32_SDMMC_SDXFR_CLKDIV | \
|
||||
STM32_SDMMC_CLKCR_EDGE | \
|
||||
STM32_SDMMC_CLKCR_PWRSAV | \
|
||||
|
|
@ -2045,7 +2049,24 @@ static sdio_statset_t stm32_status(struct sdio_dev_s *dev)
|
|||
static void stm32_widebus(struct sdio_dev_s *dev, bool wide)
|
||||
{
|
||||
struct stm32_dev_s *priv = (struct stm32_dev_s *)dev;
|
||||
uint32_t regval;
|
||||
|
||||
priv->widebus = wide;
|
||||
|
||||
regval = sdmmc_getreg32(priv, STM32_SDMMC_CLKCR_OFFSET);
|
||||
regval &= ~STM32_SDMMC_CLKCR_WIDBUS_MASK;
|
||||
|
||||
if (wide)
|
||||
{
|
||||
regval |= STM32_SDMMC_CLKCR_WIDBUS_D4;
|
||||
regval &= ~STM32_SDMMC_CLKCR_PWRSAV;
|
||||
}
|
||||
else
|
||||
{
|
||||
regval |= STM32_SDMMC_CLKCR_WIDBUS_D1;
|
||||
}
|
||||
|
||||
sdmmc_putreg32(priv, regval, STM32_SDMMC_CLKCR_OFFSET);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
@ -2089,6 +2110,12 @@ static void stm32_clock(struct sdio_dev_s *dev, enum sdio_clock_e rate)
|
|||
clckr = STM32_SDMMC_CLKCR_MMCXFR;
|
||||
break;
|
||||
|
||||
/* Enable in MMC wide (4-bit) operation clocking */
|
||||
|
||||
case CLOCK_MMC_TRANSFER_4BIT:
|
||||
clckr = STM32_SDMMC_CLKCR_MMCXFR4;
|
||||
break;
|
||||
|
||||
/* SD normal operation clocking (wide 4-bit mode) */
|
||||
|
||||
case CLOCK_SD_TRANSFER_4BIT:
|
||||
|
|
|
|||
|
|
@ -155,6 +155,9 @@
|
|||
#define STM32_SDMMC_CLKCR_MMCXFR (STM32_SDMMC_MMCXFR_CLKDIV | \
|
||||
STM32_SDMMC_CLKCR_EDGE | \
|
||||
STM32_SDMMC_CLKCR_WIDBUS_D1)
|
||||
#define STM32_SDMMC_CLKCR_MMCXFR4 (STM32_SDMMC_MMCXFR_CLKDIV | \
|
||||
STM32_SDMMC_CLKCR_EDGE | \
|
||||
STM32_SDMMC_CLKCR_WIDBUS_D4)
|
||||
#define STM32_SDMMC_CLCKR_SDXFR (STM32_SDMMC_SDXFR_CLKDIV | \
|
||||
STM32_SDMMC_CLKCR_EDGE | \
|
||||
STM32_SDMMC_CLKCR_WIDBUS_D1)
|
||||
|
|
@ -1786,7 +1789,13 @@ static sdio_statset_t stm32_status(struct sdio_dev_s *dev)
|
|||
static void stm32_widebus(struct sdio_dev_s *dev, bool wide)
|
||||
{
|
||||
struct stm32_dev_s *priv = (struct stm32_dev_s *)dev;
|
||||
uint32_t widbus = wide ? STM32_SDMMC_CLKCR_WIDBUS_D4 :
|
||||
STM32_SDMMC_CLKCR_WIDBUS_D1;
|
||||
|
||||
priv->widebus = wide;
|
||||
|
||||
sdmmc_modifyreg32(priv, STM32_SDMMC_CLKCR_OFFSET,
|
||||
STM32_SDMMC_CLKCR_WIDBUS_MASK, widbus);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
@ -1830,6 +1839,12 @@ static void stm32_clock(struct sdio_dev_s *dev, enum sdio_clock_e rate)
|
|||
clckr = (STM32_SDMMC_CLKCR_MMCXFR | STM32_SDMMC_CLKCR_CLKEN);
|
||||
break;
|
||||
|
||||
/* Enable in MMC wide (4-bit) operation clocking */
|
||||
|
||||
case CLOCK_MMC_TRANSFER_4BIT:
|
||||
clckr = (STM32_SDMMC_CLKCR_MMCXFR4 | STM32_SDMMC_CLKCR_CLKEN);
|
||||
break;
|
||||
|
||||
/* SD normal operation clocking (wide 4-bit mode) */
|
||||
|
||||
case CLOCK_SD_TRANSFER_4BIT:
|
||||
|
|
|
|||
|
|
@ -942,9 +942,10 @@ enum sdio_clock_e
|
|||
{
|
||||
CLOCK_SDIO_DISABLED = 0, /* Clock is disabled */
|
||||
CLOCK_IDMODE, /* Initial ID mode clocking (<400KHz) */
|
||||
CLOCK_MMC_TRANSFER, /* MMC normal operation clocking */
|
||||
CLOCK_MMC_TRANSFER, /* MMC normal operation clocking (narrow 1-bit mode) */
|
||||
CLOCK_SD_TRANSFER_1BIT, /* SD normal operation clocking (narrow 1-bit mode) */
|
||||
CLOCK_SD_TRANSFER_4BIT /* SD normal operation clocking (wide 4-bit mode) */
|
||||
CLOCK_SD_TRANSFER_4BIT, /* SD normal operation clocking (wide 4-bit mode) */
|
||||
CLOCK_MMC_TRANSFER_4BIT /* MMC normal operation clocking (wide 4-bit mode) */
|
||||
};
|
||||
|
||||
/* Event set. A uint8_t is big enough to hold a set of 8-events. If more
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue