Patchwork [U-Boot,v2] ARM: OMAP: Enable 8-bit eMMC access for OMAP4/5/DRA7xx

login
register
mail settings
Submitter Lubomir Popov
Date Aug. 14, 2013, 3:59 p.m.
Message ID <520BA956.7030406@mm-sol.com>
Download mbox | patch
Permalink /patch/267149/
State Accepted
Delegated to: Pantelis Antoniou
Headers show

Comments

Lubomir Popov - Aug. 14, 2013, 3:59 p.m.
Enable 8-bit host capability for HSMMC2 and/or HSMMC3. CONFIG_HSMMC2_8BIT
(for OMAP4/5/DRA7xx) and/or CONFIG_HSMMC3_8BIT (for DRA7xx only) must be
defined in the board header if an 8-bit eMMC device is connected to the
corresponding port.

Fix the "No status update" error that appeared for eMMC devices by
inserting a 20 us delay between writing arguments and command. This
solution has been proposed by Michael Cashwell <mboards@prograde.net>.

A minor cosmetic fix in a comment as well.

Signed-off-by: Lubomir Popov <lpopov@mm-sol.com>
---
V2 fixes the actual write to mmc->host_caps (missed in V1; tests were
performed with U-Boot 2013.04, where it was patched initially).

Tested on a custom OMAP5430 board with a SanDisk 8 GB eMMC, and on a TI
750-2172 Processor Board (with OMAP4460 ES1.1 and a 32 GB SanDisk eMMC),
mounted on a custom main board. Actual performance gain is negligible as
compared to 4-bit mode (about 2 ms faster FAT loading for a 4 MB image on
the 4460, that is in the range of 1%), but the advantage is that the eMMC
interface can be electrically validated in U-Boot.

 drivers/mmc/omap_hsmmc.c |   17 ++++++++++++++---
 1 file changed, 14 insertions(+), 3 deletions(-)

Patch

diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c
index 975b2c5..9a0d7c9 100644
--- a/drivers/mmc/omap_hsmmc.c
+++ b/drivers/mmc/omap_hsmmc.c
@@ -376,6 +376,7 @@  static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
 	}
 
 	writel(cmd->cmdarg, &mmc_base->arg);
+	udelay(20);		/* To fix "No status update" error on eMMC */
 	writel((cmd->cmdidx << 24) | flags, &mmc_base->cmd);
 
 	start = get_timer(0);
@@ -480,7 +481,7 @@  static int mmc_write_data(struct hsmmc *mmc_base, const char *buf,
 	unsigned int count;
 
 	/*
-	 * Start Polled Read
+	 * Start Polled Write
 	 */
 	count = (size > MMCSD_SECTOR_SIZE) ? MMCSD_SECTOR_SIZE : size;
 	count /= 4;
@@ -586,6 +587,8 @@  int omap_mmc_init(int dev_index, uint host_caps_mask, uint f_max, int cd_gpio,
 {
 	struct mmc *mmc = &hsmmc_dev[dev_index];
 	struct omap_hsmmc_data *priv_data = &hsmmc_dev_data[dev_index];
+	uint host_caps_val = MMC_MODE_4BIT | MMC_MODE_HS_52MHz | MMC_MODE_HS |
+			     MMC_MODE_HC;
 
 	sprintf(mmc->name, "OMAP SD/MMC");
 	mmc->send_cmd = mmc_send_cmd;
@@ -600,11 +603,20 @@  int omap_mmc_init(int dev_index, uint host_caps_mask, uint f_max, int cd_gpio,
 #ifdef OMAP_HSMMC2_BASE
 	case 1:
 		priv_data->base_addr = (struct hsmmc *)OMAP_HSMMC2_BASE;
+#if (defined(CONFIG_OMAP44XX) || defined(CONFIG_OMAP54XX) || \
+     defined(CONFIG_DRA7XX)) && defined(CONFIG_HSMMC2_8BIT)
+		/* Enable 8-bit interface for eMMC on OMAP4/5 or DRA7XX */
+		host_caps_val |= MMC_MODE_8BIT;
+#endif
 		break;
 #endif
 #ifdef OMAP_HSMMC3_BASE
 	case 2:
 		priv_data->base_addr = (struct hsmmc *)OMAP_HSMMC3_BASE;
+#if defined(CONFIG_DRA7XX) && defined(CONFIG_HSMMC3_8BIT)
+		/* Enable 8-bit interface for eMMC on DRA7XX */
+		host_caps_val |= MMC_MODE_8BIT;
+#endif
 		break;
 #endif
 	default:
@@ -620,8 +632,7 @@  int omap_mmc_init(int dev_index, uint host_caps_mask, uint f_max, int cd_gpio,
 		mmc->getwp = omap_mmc_getwp;
 
 	mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
-	mmc->host_caps = (MMC_MODE_4BIT | MMC_MODE_HS_52MHz | MMC_MODE_HS |
-				MMC_MODE_HC) & ~host_caps_mask;
+	mmc->host_caps = host_caps_val & ~host_caps_mask;
 
 	mmc->f_min = 400000;