eMMC: add support to 8-bit mode.
Change-Id: I0470130eb5f8de319cd55c448a9aa1b9131e8e07
This commit is contained in:
parent
3e07920fe2
commit
4796287659
|
@ -742,6 +742,7 @@ service emmc
|
||||||
system
|
system
|
||||||
PRIVCTL
|
PRIVCTL
|
||||||
IRQCTL
|
IRQCTL
|
||||||
|
PADCONF
|
||||||
;
|
;
|
||||||
irq
|
irq
|
||||||
28 # MMCSD1INT
|
28 # MMCSD1INT
|
||||||
|
|
|
@ -48,12 +48,22 @@
|
||||||
/* The card sector size is 512B. */
|
/* The card sector size is 512B. */
|
||||||
#define SEC_SIZE 512
|
#define SEC_SIZE 512
|
||||||
|
|
||||||
|
/*
|
||||||
|
* AM335x Control Module registers CONF_GPMC_ADn.
|
||||||
|
* Configuration do multiplex CONF_GPMC_ADn to signals MMC1_DATn (Mode 1).
|
||||||
|
*/
|
||||||
|
#define CONF_GPMC_AD(N) (0x800 + 4*(N))
|
||||||
|
#define CONF_GPMC_AD_MASK 0x7F
|
||||||
|
#define CONF_GPMC_AD_VAL 0x31
|
||||||
|
|
||||||
/* AM335x MMC1 memory map (physical start address and size). */
|
/* AM335x MMC1 memory map (physical start address and size). */
|
||||||
#define AM335X_MMC1_BASE_ADDR 0x481D8000
|
#define AM335X_MMC1_BASE_ADDR 0x481D8000
|
||||||
#define AM335X_MMC1_SIZE (4 << 10)
|
#define AM335X_MMC1_SIZE (4 << 10)
|
||||||
/* AM335x MMC1 interrupt number. */
|
/* AM335x MMC1 interrupt number. */
|
||||||
#define AM335X_MMCSD1INT 28
|
#define AM335X_MMCSD1INT 28
|
||||||
|
|
||||||
|
static uint32_t bus_width;
|
||||||
|
|
||||||
/* AM335x MMCHS registers virtual addresses: virtual base + offset. */
|
/* AM335x MMCHS registers virtual addresses: virtual base + offset. */
|
||||||
static struct omap_mmchs_registers *reg;
|
static struct omap_mmchs_registers *reg;
|
||||||
|
|
||||||
|
@ -439,8 +449,8 @@ read_busy(void)
|
||||||
{
|
{
|
||||||
uint32_t stat;
|
uint32_t stat;
|
||||||
/*
|
/*
|
||||||
* The busy signal is optional, but the host controller will assert
|
* The busy signal is optional, but the host controller will assert
|
||||||
* SD_STAT[1] TC even if the card does not send it.
|
* SD_STAT[1] TC even if the card does not send it.
|
||||||
*/
|
*/
|
||||||
if (irq_wait() < 0)
|
if (irq_wait() < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -619,6 +629,24 @@ minix_init(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Configure the Control Module registers CONF_GPMC_AD4-7.
|
||||||
|
* Multiplex pins GPMC_AD4-7 to signals MMC1_DAT4-7 (Mode 1).
|
||||||
|
* Return 0 on success, a negative integer on error.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
conf_gpmc_ad(void)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
for (i=4; i<8; i++) {
|
||||||
|
if (sys_padconf(CONF_GPMC_AD(i), CONF_GPMC_AD_MASK,
|
||||||
|
CONF_GPMC_AD_VAL) != OK)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Interface to the MINIX block device driver.
|
* Interface to the MINIX block device driver.
|
||||||
* Host controller initialization.
|
* Host controller initialization.
|
||||||
|
@ -638,6 +666,16 @@ emmc_host_init(struct mmc_host *host)
|
||||||
if (minix_init() < 0)
|
if (minix_init() < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Multiplex pins GPMC_AD4-7 to signals MMC1_DAT4-7 (Mode 1), in order
|
||||||
|
* to allow the use of 8-bit mode.
|
||||||
|
* U-Boot multiplexes only pins GPMC_AD0-3 to signals MMC1_DAT0-3.
|
||||||
|
*/
|
||||||
|
if (conf_gpmc_ad() < 0)
|
||||||
|
bus_width = EXT_CSD_BUS_WIDTH_4;
|
||||||
|
else
|
||||||
|
bus_width = EXT_CSD_BUS_WIDTH_8;
|
||||||
|
|
||||||
/* Reset the host controller. */
|
/* Reset the host controller. */
|
||||||
set32(reg->SYSCONFIG, MMCHS_SD_SYSCONFIG_SOFTRESET,
|
set32(reg->SYSCONFIG, MMCHS_SD_SYSCONFIG_SOFTRESET,
|
||||||
MMCHS_SD_SYSCONFIG_SOFTRESET);
|
MMCHS_SD_SYSCONFIG_SOFTRESET);
|
||||||
|
@ -676,7 +714,7 @@ emmc_host_init(struct mmc_host *host)
|
||||||
|
|
||||||
/* Enable the bus clock. */
|
/* Enable the bus clock. */
|
||||||
set32(reg->SYSCTL, MMCHS_SD_SYSCTL_CEN, MMCHS_SD_SYSCTL_CEN_EN);
|
set32(reg->SYSCTL, MMCHS_SD_SYSCTL_CEN, MMCHS_SD_SYSCTL_CEN_EN);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set the internal clock gating strategy to automatic, and enable
|
* Set the internal clock gating strategy to automatic, and enable
|
||||||
* Smart Idle mode. The host controller does not implement wake-up
|
* Smart Idle mode. The host controller does not implement wake-up
|
||||||
|
@ -810,7 +848,7 @@ emmc_card_initialize(struct sd_slot *slot)
|
||||||
/* Card capacity for densities greater than 2GB. */
|
/* Card capacity for densities greater than 2GB. */
|
||||||
if (MMC_EXT_CSD_SEC_COUNT > 0)
|
if (MMC_EXT_CSD_SEC_COUNT > 0)
|
||||||
card_size = (uint64_t)MMC_EXT_CSD_SEC_COUNT * SEC_SIZE;
|
card_size = (uint64_t)MMC_EXT_CSD_SEC_COUNT * SEC_SIZE;
|
||||||
|
|
||||||
/* CMD6. Switch to high-speed mode: EXT_CSD[185] HS_TIMING = 1. */
|
/* CMD6. Switch to high-speed mode: EXT_CSD[185] HS_TIMING = 1. */
|
||||||
if (mmc_switch(MMC_SWITCH_MODE_WRITE_BYTE, EXT_CSD_HS_TIMING, 1) < 0)
|
if (mmc_switch(MMC_SWITCH_MODE_WRITE_BYTE, EXT_CSD_HS_TIMING, 1) < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -832,9 +870,9 @@ emmc_card_initialize(struct sd_slot *slot)
|
||||||
/* Set data and busy time-out: ~ 2,8s @ 48MHz.*/
|
/* Set data and busy time-out: ~ 2,8s @ 48MHz.*/
|
||||||
set32(reg->SYSCTL, MMCHS_SD_SYSCTL_DTO, MMCHS_SD_SYSCTL_DTO_2POW27);
|
set32(reg->SYSCTL, MMCHS_SD_SYSCTL_DTO, MMCHS_SD_SYSCTL_DTO_2POW27);
|
||||||
|
|
||||||
/* CMD6. Set data bus width to 4. */
|
/* CMD6. Set data bus width. */
|
||||||
if (mmc_switch(MMC_SWITCH_MODE_WRITE_BYTE, EXT_CSD_BUS_WIDTH,
|
if (mmc_switch(MMC_SWITCH_MODE_WRITE_BYTE, EXT_CSD_BUS_WIDTH,
|
||||||
EXT_CSD_BUS_WIDTH_4) < 0)
|
bus_width) < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
/* Wait for the (optional) busy signal. */
|
/* Wait for the (optional) busy signal. */
|
||||||
if (read_busy() < 0)
|
if (read_busy() < 0)
|
||||||
|
@ -843,8 +881,11 @@ emmc_card_initialize(struct sd_slot *slot)
|
||||||
if (send_status() < 0)
|
if (send_status() < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* Host controller: set 4-bit data bus width. */
|
/* Host controller: set data bus width. */
|
||||||
set32(reg->HCTL, MMCHS_SD_HCTL_DTW, MMCHS_SD_HCTL_DTW_4BIT);
|
if (bus_width == EXT_CSD_BUS_WIDTH_4)
|
||||||
|
set32(reg->HCTL, MMCHS_SD_HCTL_DTW, MMCHS_SD_HCTL_DTW_4BIT);
|
||||||
|
else
|
||||||
|
set32(reg->CON, MMCHS_SD_CON_DW8, MMCHS_SD_CON_DW8_8BITS);
|
||||||
|
|
||||||
/* CMD16. Set block length to sector size (512B). */
|
/* CMD16. Set block length to sector size (512B). */
|
||||||
if (set_blocklen() < 0)
|
if (set_blocklen() < 0)
|
||||||
|
|
|
@ -1,17 +1,18 @@
|
||||||
The eMMC driver was designed to be linked to the existing MMC/SD block device driver (mmcblk.c).
|
The eMMC driver was designed to be linked to the existing MMC/SD block device
|
||||||
|
driver (mmcblk.c).
|
||||||
|
|
||||||
* Mini how-to
|
* Mini how-to
|
||||||
On the BeagleBone Black, the block device files /dev/c1d* (major = 8) are free. The driver can use /dev/c1d0.
|
On the BeagleBone Black, the block device files /dev/c1d* (major = 8) are free.
|
||||||
|
The driver can use /dev/c1d0.
|
||||||
# service up /service/emmc -dev /dev/c1d0
|
# service up /service/emmc -dev /dev/c1d0
|
||||||
|
|
||||||
* 4-bit mode (data bus width)
|
|
||||||
On the BeagleBone Black, the eMMC data lines are connected to the AM335x GPMC_AD[0-7] pins. After PoR, these pins are multiplexed to signals GPIO1_[0-7], and U-Boot only multiplexes pins GPMC_AD[0-3] to signals MMC1_DAT[0-3]. Consequently, 8-bit mode (signals MMC1_DAT[4-7]) can not be used.
|
|
||||||
|
|
||||||
* Programmed Input/Output
|
* Programmed Input/Output
|
||||||
The driver does not have support for DMA.
|
The driver does not have support for DMA.
|
||||||
|
|
||||||
* High capacity cards
|
* High capacity cards
|
||||||
Data address for media =< 2GB is byte address, and data address for media > 2GB is sector (512B) address. The driver was designed to handle both address modes, but it was tested on a 2GB card.
|
Data address for media =< 2GB is byte address, and data address for media > 2GB
|
||||||
|
is sector (512B) address. The driver was designed to handle both address modes,
|
||||||
|
but it was tested on a 2GB card.
|
||||||
|
|
||||||
* References
|
* References
|
||||||
BeagleBone Black System Reference Manual, Revision A5.6.
|
BeagleBone Black System Reference Manual, Revision A5.6.
|
||||||
|
|
Loading…
Reference in a new issue