[U-Boot] [PATCH] MCI support for AT91 family processors.

Sami Kantoluoto sami.kantoluoto at embedtronics.fi
Sat Aug 29 19:18:32 CEST 2009


Fixed to parse CSD correctly on little endian processors as gcc orders
bitfields differently between big and little endian ones.

Signed-off-by: Sami Kantoluoto <sami.kantoluoto at embedtronics.fi>
---
 drivers/mmc/atmel_mci.c         |   55 ++++++++++++++++++++++++++++++++++++--
 include/asm-arm/arch-at91/clk.h |    5 +++
 2 files changed, 57 insertions(+), 3 deletions(-)

diff --git a/drivers/mmc/atmel_mci.c b/drivers/mmc/atmel_mci.c
index 3946ffe..c2837a8 100644
--- a/drivers/mmc/atmel_mci.c
+++ b/drivers/mmc/atmel_mci.c
@@ -282,6 +282,53 @@ static void sd_parse_cid(struct mmc_cid *cid, unsigned long *resp)
 	cid->mdt = (resp[3] >> 8) & 0x0fff;
 }
 
+static void mmc_parse_csd(struct mmc_csd *csd, unsigned long *resp)
+{
+#if	__BYTE_ORDER == __BIG_ENDIAN
+	memcpy(csd, resp, sizeof(csd));
+#elif	__BYTE_ORDER == __LITTLE_ENDIAN
+	csd->csd_structure = resp[0] >> 30;
+	csd->spec_vers = resp[0] >> 26;
+	csd->rsvd1 = resp[0] >> 24;
+	csd->taac = resp[0] >> 16;
+	csd->nsac = resp[0] >> 8;
+	csd->tran_speed = resp[0] & 0xff;
+	csd->ccc = resp[1] >> 20;
+	csd->read_bl_len = resp[1] >> 16;
+	csd->read_bl_partial = resp[1] >> 15;
+	csd->write_blk_misalign = resp[1] >> 14;
+	csd->read_blk_misalign = resp[1] >> 13;
+	csd->dsr_imp = resp[1] >> 12;
+	csd->rsvd2 = resp[1] >> 10;
+	csd->c_size = (resp[1] << 2) | (resp[2] >> 30);
+	csd->vdd_r_curr_min = resp[2] >> 27;
+	csd->vdd_r_curr_max = resp[2] >> 24;
+	csd->vdd_w_curr_min = resp[2] >> 21;
+	csd->vdd_w_curr_max = resp[2] >> 18;
+	csd->c_size_mult = resp[2] >> 15;
+	csd->sector_size = resp[2] >> 10;
+	csd->erase_grp_size = resp[2] >> 5;
+	csd->wp_grp_size = resp[2] & 0x1f;
+	csd->wp_grp_enable = resp[3] >> 31;
+	csd->default_ecc = resp[3] >> 29;
+	csd->r2w_factor = resp[3] >> 26;
+	csd->write_bl_len = resp[3] >> 22;
+	csd->write_bl_partial = resp[3] >> 21;
+	csd->rsvd3 = resp[3] >> 16;
+
+	csd->file_format_grp = resp[3] >> 15;
+	csd->copy = resp[3] >> 14;
+	csd->perm_write_protect = resp[3] >> 13;
+	csd->tmp_write_protect = resp[3] >> 12;
+	csd->file_format = resp[3] >> 10;
+	csd->ecc = resp[3] >> 8;
+	csd->crc = resp[3] >> 1;
+	csd->one = resp[3] & 1;
+#else
+#error	Unsupported __BYTE_ORDER
+#endif
+}
+
 static void mmc_dump_cid(const struct mmc_cid *cid)
 {
 	printf("Manufacturer ID:       %02X\n", cid->mid);
@@ -298,7 +345,7 @@ static void mmc_dump_csd(const struct mmc_csd *csd)
 {
 	unsigned long *csd_raw = (unsigned long *)csd;
 	printf("CSD data: %08lx %08lx %08lx %08lx\n",
-	       csd_raw[0], csd_raw[1], csd_raw[2], csd_raw[3]);
+	       ntohl(csd_raw[0]), ntohl(csd_raw[1]), ntohl(csd_raw[2]), ntohl(csd_raw[3]));
 	printf("CSD structure version:   1.%u\n", csd->csd_structure);
 	printf("MMC System Spec version: %u\n", csd->spec_vers);
 	printf("Card command classes:    %03x\n", csd->ccc);
@@ -368,7 +415,7 @@ static int sd_init_card(struct mmc_cid *cid, int verbose)
 
 	/* Get RCA of the card that responded */
 	ret = mmc_cmd(SD_CMD_SEND_RELATIVE_ADDR, 0, resp, R6 | NCR);
-	if (ret)
+  	if (ret)
 		return ret;
 
 	mmc_rca = resp[0] >> 16;
@@ -468,6 +515,7 @@ int mmc_legacy_init(int verbose)
 	struct mmc_cid cid;
 	struct mmc_csd csd;
 	unsigned int max_blksz;
+	unsigned long resp[4];
 	int ret;
 
 	/* Initialize controller */
@@ -488,9 +536,10 @@ int mmc_legacy_init(int verbose)
 		return ret;
 
 	/* Get CSD from the card */
-	ret = mmc_cmd(MMC_CMD_SEND_CSD, mmc_rca << 16, &csd, R2 | NCR);
+	ret = mmc_cmd(MMC_CMD_SEND_CSD, mmc_rca << 16, resp, R2 | NCR);
 	if (ret)
 		return ret;
+	mmc_parse_csd(&csd, resp);
 	if (verbose)
 		mmc_dump_csd(&csd);
 
diff --git a/include/asm-arm/arch-at91/clk.h b/include/asm-arm/arch-at91/clk.h
index f642dd9..26b537c 100644
--- a/include/asm-arm/arch-at91/clk.h
+++ b/include/asm-arm/arch-at91/clk.h
@@ -54,6 +54,11 @@ static inline unsigned long get_spi_clk_rate(unsigned int dev_id)
 	return get_mck_clk_rate();
 }
 
+static inline unsigned long get_mci_clk_rate(void)
+{
+	return get_mck_clk_rate();
+}
+
 static inline unsigned long get_twi_clk_rate(unsigned int dev_id)
 {
 	return get_mck_clk_rate();
-- 
1.6.0.4



More information about the U-Boot mailing list