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