arch/arm/src/lpc54xx and configs/lpcxpresso-lpc54628: Correct some SD/MMC clock divider logic.

This commit is contained in:
Gregory Nutt 2017-12-19 14:05:36 -06:00
parent 93b28017ab
commit 321a7a64af
3 changed files with 51 additions and 28 deletions

View File

@ -154,10 +154,16 @@
#define SDMMC_PWREN (1 << 0) /* Bit 0: Power on/off switch */
/* Bits 1-31: Reserved */
/* Clock divider register CLKDIV */
/* Clock divider register CLKDIV
*
* Clock division is 2*n. For example, value of 0 means divide by 2 * 0 = 0 (no division,
* bypass), value of 1 means divide by 2 * 1 = 2, value of 255 means divide by 2 * 255 = 510,
* and so on.
*/
#define SDMMC_CLKDIV0_SHIFT (0) /* Bits 0-7: Clock divider 0 value */
#define SDMMC_CLKDIV0_MASK (255 << SDMMC_CLKDIV0_SHIFT)
# define SDMMC_CLKDIV0_MASK(n) ((((n) + 1) >> 1) << SDMMC_CLKDIV0_SHIFT)
/* Bits 8-31: Reserved */
/* Clock enable register CLKENA */
@ -166,7 +172,7 @@
/* Bits 1-15: Reserved */
#define SDMMC_CLKENA_LOWPOWER (1 << 16) /* Bit 16: Low-power mode */
/* Bits 17-31: Reserved */
/*Timeout register TMOUT */
/* Timeout register TMOUT */
#define SDMMC_TMOUT_RESPONSE_SHIFT (0) /* Bits 0-7: Response timeout value */
#define SDMMC_TMOUT_RESPONSE_MASK (255 << SDMMC_TMOUT_RESPONSE_SHIFT)

View File

@ -115,13 +115,6 @@
# error "Callback support requires CONFIG_SCHED_WORKQUEUE"
#endif
/* Clock Division */
#define LPC54_CLKDIV_INIT 165 /* Divide by 165 = 400KHz */
#define SDCARD_CLOCK_MMCXFR 2 /* SDCARD_MMCXFR_CLKDIV */
#define SDCARD_CLOCK_SDWIDEXFR 2 /* SDCARD_SDXFR_CLKDIV */
#define SDCARD_CLOCK_SDXFR 2 /* SDCARD_SDXFR_CLKDIV */
/* Timing */
#define SDCARD_CMDTIMEOUT (10000)
@ -536,7 +529,7 @@ static inline void lpc54_setclock(uint32_t clkdiv)
/* Set Divider0 to desired value */
lpc54_putreg(clkdiv & SDMMC_CLKDIV0_MASK, LPC54_SDMMC_CLKDIV);
lpc54_putreg(clkdiv, LPC54_SDMMC_CLKDIV);
/* Inform CIU */
@ -555,7 +548,7 @@ static inline void lpc54_setclock(uint32_t clkdiv)
* Name: lpc54_settype
*
* Description: Define the Bus Size of SDCard (1, 4 or 8-bit)
*
*
* Input Parameters:
* ctype - A new CTYPE (Card Type Register) value
*
@ -574,7 +567,7 @@ static inline void lpc54_settype(uint32_t ctype)
* Name: lpc54_sdcard_clock
*
* Description: Enable/Disable the SDCard clock
*
*
* Input Parameters:
* enable - False = clock disabled; True = clock enabled.
*
@ -1145,7 +1138,7 @@ static void lpc54_reset(FAR struct sdio_dev_s *dev)
regval = SDMMC_BMOD_DE;
regval |= SDMMC_BMOD_PBL_4XFRS;
regval |= ((4) << SDMMC_BMOD_DSL_SHIFT) & SDMMC_BMOD_DSL_MASK;
regval |= ((4) << SDMMC_BMOD_DSL_SHIFT);
lpc54_putreg(regval, LPC54_SDMMC_BMOD);
/* Disable clock to CIU (needs latch) */
@ -1260,8 +1253,8 @@ static void lpc54_clock(FAR struct sdio_dev_s *dev, enum sdio_clock_e rate)
default:
case CLOCK_SDIO_DISABLED:
clkdiv = LPC54_CLKDIV_INIT;
ctype = SDCARD_BUS_D1;
clkdiv = SDMMC_CLKDIV0(BOARD_CLKDIV_INIT);
ctype = SDCARD_BUS_D1;
enabled = false;
return;
break;
@ -1269,16 +1262,16 @@ static void lpc54_clock(FAR struct sdio_dev_s *dev, enum sdio_clock_e rate)
/* Enable in initial ID mode clocking (<400KHz) */
case CLOCK_IDMODE:
clkdiv = LPC54_CLKDIV_INIT;
ctype = SDCARD_BUS_D1;
clkdiv = SDMMC_CLKDIV0(BOARD_CLKDIV_INIT);
ctype = SDCARD_BUS_D1;
enabled = true;
break;
/* Enable in MMC normal operation clocking */
case CLOCK_MMC_TRANSFER:
clkdiv = SDCARD_CLOCK_MMCXFR;
ctype = SDCARD_BUS_D1;
clkdiv = SDMMC_CLKDIV0(BOARD_CLKDIV_MMCXFR);
ctype = SDCARD_BUS_D1;
enabled = true;
break;
@ -1286,8 +1279,8 @@ static void lpc54_clock(FAR struct sdio_dev_s *dev, enum sdio_clock_e rate)
case CLOCK_SD_TRANSFER_4BIT:
#ifndef CONFIG_LPC54_SDMMC_WIDTH_D1_ONLY
clkdiv = SDCARD_CLOCK_SDWIDEXFR;
ctype = SDCARD_BUS_D4;
clkdiv = SDMMC_CLKDIV0(BOARD_CLKDIV_SDWIDEXFR);
ctype = SDCARD_BUS_D4;
enabled = true;
break;
#endif
@ -1295,8 +1288,8 @@ static void lpc54_clock(FAR struct sdio_dev_s *dev, enum sdio_clock_e rate)
/* SD normal operation clocking (narrow 1-bit mode) */
case CLOCK_SD_TRANSFER_1BIT:
clkdiv = SDCARD_CLOCK_SDXFR;
ctype = SDCARD_BUS_D1;
clkdiv = SDMMC_CLKDIV0(BOARD_CLKDIV_SDXFR);
ctype = SDCARD_BUS_D1;
enabled = true;
break;
}
@ -2318,7 +2311,7 @@ static int lpc54_dmasendsetup(FAR struct sdio_dev_s *dev,
g_sdmmc_dmadd[0].des1 = 512;
g_sdmmc_dmadd[0].des2 = priv->buffer;
g_sdmmc_dmadd[0].des3 = (uint32_t) &g_sdmmc_dmadd[1];
lpc54_putreg((uint32_t) &g_sdmmc_dmadd[0], LPC54_SDMMC_DBADDR);
}
@ -2443,7 +2436,7 @@ FAR struct sdio_dev_s *sdio_initialize(int slotno)
lpc54_putreg(BOARD_SDMMC_CLKSRC, LPC54_SYSCON_SDIOCLKSEL);
/* Set up the clock divider to obtain the desired clock rate.
/* Set up the clock divider to obtain the desired clock rate.
* NOTE: The SDIO function clock to the interface can be up to 50 MHZ.
*/

View File

@ -193,10 +193,11 @@
#endif
#define BOARD_EMC_FREQUENCY (BOARD_CPU_FREQUENCY / BOARD_EMC_CLKDIV)
/* SD/MMC or SDIO interface
/* SD/MMC or SDIO interface/
/* SD/MMC function clock
*
* NOTE: The SDIO function clock to the interface can be up to 50 MHZ.
* Example: BOARD_MAIN_CLK=220MHz, CLKDIV=5, Fsdmmc=44MHz.
* Example: BOARD_MAIN_CLK=220MHz, CLKDIV=5, Finput=44MHz.
*/
#define BOARD_SDMMC_MAXFREQ 50000000
@ -206,6 +207,29 @@
#define BOARD_SDMMC_CLKDIV BOARD_SDMMC_CEIL(BOARD_MAIN_CLK, BOARD_SDMMC_MAXFREQ)
#define BOARD_SDMMC_FREQUENCY (BOARD_MAIN_CLK / BOARD_SDMMC_CLKDIV)
/* Mode-dependent function clock division
*
* Example: BOARD_SDMMC_FREQUENCY=44MHz
* BOARD_CLKDIV_INIT=110, Fsdmmc=400KHz (400KHz max)
* BOARD_CLKDIV_MMCXFR=4[3], Fsdmmc=11Mhz (20MHz max) See NOTE:
* BOARD_CLKDIV_SDWIDEXFR=2, Fsdmmc=22MHz (25MHz max)
* BOARD_CLKDIV_SDXFR=2, Fsdmmc=22MHz (25MHz max)
*
* NOTE: *lock division is 2*n. For example, value of 0 means divide by
* 2 * 0 = 0 (no division, bypass), value of 1 means divide by 2 * 1 = 2, value
* of 255 means divide by 2 * 255 = 510, and so on.
*
* SD/MMC logic will write the value ((clkdiv + 1) >> 1) as the divisor. So an
* odd value calculated below will be moved up to next higher divider value. So
* the value 3 will cause 2 to be written as the divider value and the effective
* divider will be 4.
*/
#define BOARD_CLKDIV_INIT BOARD_SDMMC_CEIL(BOARD_SDMMC_FREQUENCY, 400000)
#define BOARD_CLKDIV_MMCXFR BOARD_SDMMC_CEIL(BOARD_SDMMC_FREQUENCY, 20000000)
#define BOARD_CLKDIV_SDWIDEXFR BOARD_SDMMC_CEIL(BOARD_SDMMC_FREQUENCY, 25000000)
#define BOARD_CLKDIV_SDXFR BOARD_SDMMC_CEIL(BOARD_SDMMC_FREQUENCY, 25000000)
/* LED definitions *********************************************************/
/* The LPCXpress-LPC54628 has three user LEDs: D9, D11, and D12. These
* LEDs are for application use. They are illuminated when the driving
@ -352,7 +376,7 @@
/* LCD
*
* There are no alternatives for LCD pins except for the VD0-VD3 pins.
* There are no alternatives for LCD pins except for the VD0-VD3 pins.
* VD0-VD2 are not used in this hardware configuration. VD3 is on
* P2.21.
*/