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.kantolu...@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

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to