- Main Page
- Related Pages
- Data Structures
- Files

- File List
- Globals

# drivers/sdmmc/card.c

Go to the documentation of this file.

    00001
    00044 #include <bitops.h>
    00045 #include <byteorder.h>
    00046 #include <debug.h>
    00047 #include <errno.h>
    00048 #include <stdbool.h>
    00049 #include <string.h>
    00050 #include <util.h>
    00051 #include <sdmmc/sdmmc.h>
    00052 #include "protocol.h"
    00053
    00054 static inline bool sdmmc_card_is_sd(struct sdmmc_card *card)
    00055 {
    00056         return card->type == SDMMC_CARD_TYPE_SD;
    00057 }
    00058
    00059 static inline bool sdmmc_card_is_sdhc(struct sdmmc_card *card)
    00060 {
    00061         return card->type == SDMMC_CARD_TYPE_SDHC;
    00062 }
    00063
    00064 static const unsigned int tran_exp[] = {
    00065         10000,          100000,         1000000,        10000000,
    00066         0,              0,              0,              0
    00067 };
    00068
    00069 static const unsigned char tran_mant[] = {
    00070         0,      10,     12,     13,     15,     20,     25,     30,
    00071         35,     40,     45,     50,     55,     60,     70,     80,
    00072 };
    00073
    00074 static const unsigned int tacc_exp[] = {
    00075         1,      10,     100,    1000,   10000,  100000, 1000000, 10000000,
    00076 };
    00077
    00078 static const unsigned int tacc_mant[] = {
    00079         0,      10,     12,     13,     15,     20,     25,     30,
    00080         35,     40,     45,     50,     55,     60,     70,     80,
    00081 };
    00082
    00083 static void sdmmc_dump_cid(const struct sdmmc_cid *cid)
    00084 {
    00085         dbg_printf("CID dump:\n");
    00086         dbg_printf("  Manuacturer ID:  0x%x\n", cid->manufacturer_id);
    00087         dbg_printf("  Application ID:  0x%x\n", cid->application_id);
    00088         dbg_printf("  Name:            %c%c%c%c%c\n",
    00089                         cid->name[0], cid->name[1],
    00090                         cid->name[2], cid->name[3],
    00091                         cid->name[4]);
    00092         dbg_printf("  Revision:        0x%x\n", cid->revision);
    00093         dbg_printf("  Serial:          0x%x\n", cid->serial);
    00094         dbg_printf("  Manufacturing date: %u/%u\n",
    00095                         cid->manu_year, cid->manu_month);
    00096 }
    00097
    00098 /*
    00099  * Given the decoded CSD structure, decode the raw CID to our CID structure.
    00100  */
    00101 void sdmmc_decode_sd_cid(struct sdmmc_card *card, const be32_t *raw_cid)
    00102 {
    00103         uint32_t        resp[4];
    00104         unsigned int    i;
    00105
    00106         for (i = 0; i < 4; i++)
    00107                 resp[3 - i] = be32_to_cpu(raw_cid[i]);
    00108
    00109         card->cid.manufacturer_id =
    00110                 extract_bitfield(120, 8, resp);
    00111         card->cid.application_id =
    00112                 extract_bitfield(104, 16, resp);
    00113         card->cid.name[0]    = extract_bitfield(96, 8, resp);
    00114         card->cid.name[1]    = extract_bitfield(88, 8, resp);
    00115         card->cid.name[2]    = extract_bitfield(80, 8, resp);
    00116         card->cid.name[3]    = extract_bitfield(72, 8, resp);
    00117         card->cid.name[4]    = extract_bitfield(64, 8, resp);
    00118         card->cid.revision   = extract_bitfield(56, 8, resp);
    00119         card->cid.serial     = extract_bitfield(24, 32, resp);
    00120         card->cid.manu_year  = extract_bitfield(12, 8, resp) + 2000;
    00121         card->cid.manu_month = extract_bitfield(8, 4, resp);
    00122         card->cid.checksum   = extract_bitfield(1, 7, resp);
    00123
    00124         sdmmc_dump_cid(&card->cid);
    00125 }
    00126
    00127 int sdmmc_decode_mmc_cid(struct sdmmc_card *card, const be32_t *raw_cid)
    00128 {
    00129         uint32_t        resp[4];
    00130         unsigned int    i;
    00131
    00132         for (i = 0; i < 4; i++)
    00133                 resp[3 - i] = be32_to_cpu(raw_cid[i]);
    00134
    00135         switch (card->csd.mmc_version) {
    00136         case 0: /* MMC v1.0 - v1.2 */
    00137         case 1: /* MMC v1.4 */
    00138                 card->cid.manufacturer_id =
    00139                         extract_bitfield(104, 24, resp);
    00140                 card->cid.name[0] =
    00141                         extract_bitfield(96, 8, resp);
    00142                 card->cid.name[1] =
    00143                         extract_bitfield(88, 8, resp);
    00144                 card->cid.name[2] =
    00145                         extract_bitfield(80, 8, resp);
    00146                 card->cid.name[3] =
    00147                         extract_bitfield(72, 8, resp);
    00148                 card->cid.name[4] =
    00149                         extract_bitfield(64, 8, resp);
    00150                 card->cid.name[5] =
    00151                         extract_bitfield(56, 8, resp);
    00152                 card->cid.name[6] =
    00153                         extract_bitfield(48, 8, resp);
    00154                 card->cid.revision =
    00155                         extract_bitfield(40, 8, resp);
    00156                 card->cid.serial =
    00157                         extract_bitfield(16, 24, resp);
    00158                 card->cid.manu_month =
    00159                         extract_bitfield(12, 4, resp);
    00160                 card->cid.manu_year =
    00161                         extract_bitfield(8, 4, resp) + 1997;
    00162                 break;
    00163
    00164         case 2: /* MMC v2.0 - v2.2 */
    00165         case 3: /* MMC v3.1 - v3.3 */
    00166         case 4: /* MMC v4 */
    00167                 card->cid.manufacturer_id =
    00168                         extract_bitfield(120, 8, resp);
    00169                 card->cid.application_id =
    00170                         extract_bitfield(104, 16, resp);
    00171                 card->cid.name[0] =
    00172                         extract_bitfield(96, 8, resp);
    00173                 card->cid.name[1] =
    00174                         extract_bitfield(88, 8, resp);
    00175                 card->cid.name[2] =
    00176                         extract_bitfield(80, 8, resp);
    00177                 card->cid.name[3] =
    00178                         extract_bitfield(72, 8, resp);
    00179                 card->cid.name[4] =
    00180                         extract_bitfield(64, 8, resp);
    00181                 card->cid.name[5] =
    00182                         extract_bitfield(56, 8, resp);
    00183                 card->cid.serial =
    00184                         extract_bitfield(16, 32, resp);
    00185                 card->cid.manu_month =
    00186                         extract_bitfield(12, 4, resp);
    00187                 card->cid.manu_year =
    00188                         extract_bitfield(8, 4, resp) + 1997;
    00189                 card->cid.checksum =
    00190                         extract_bitfield(1, 7, resp);
    00191                 break;
    00192
    00193         default:
    00194                 dbg_printf("mmc: card has unknown MMCA version %d\n",
    00195                         card->csd.mmc_version);
    00196                 return -EINVAL;
    00197         }
    00198
    00199         sdmmc_dump_cid(&card->cid);
    00200
    00201         return 0;
    00202 }
    00203
    00204 /*
    00205  * Given a 128-bit response, decode to our card CSD structure.
    00206  */
    00207 int sdmmc_decode_sd_csd(struct sdmmc_card *card, const be32_t *raw_csd)
    00208 {
    00209         struct sdmmc_csd *csd = &card->csd;
    00210         unsigned int exp, mul, csd_structure;
    00211         uint32_t resp[4];
    00212         unsigned int i;
    00213
    00214         for (i = 0; i < 4; i++)
    00215                 resp[3 - i] = be32_to_cpu(raw_csd[i]);
    00216
    00217         dbg_printf("mmc csd: %08x %08x %08x %08x\n",
    00218                         resp[0], resp[1], resp[2], resp[3]);
    00219
    00220         csd_structure = extract_bitfield(126, 2, resp);
    00221
    00222         switch (csd_structure) {
    00223         case 0:
    00224                 mul = extract_bitfield(115, 4, resp);
    00225                 exp = extract_bitfield(112, 3, resp);
    00226                 csd->read_access_time_ns =
    00227                         (tacc_exp[exp] * tacc_mant[mul] + 9) / 10;
    00228                 csd->read_access_time_clks =
    00229                         extract_bitfield(104, 8, resp) * 100;
    00230
    00231                 mul = extract_bitfield(99, 4, resp);
    00232                 exp = extract_bitfield(96, 3, resp);
    00233                 csd->max_transfer_rate =
    00234                         tran_exp[exp] * tran_mant[mul];
    00235                 csd->command_classes =
    00236                         extract_bitfield(84, 12, resp);
    00237
    00238                 mul = extract_bitfield(62, 12, resp);
    00239                 exp = extract_bitfield(47, 3, resp);
    00240                 csd->capacity = (mul + 1) << (exp + 2);
    00241
    00242                 csd->read_block_length =
    00243                         extract_bitfield(80, 4, resp);
    00244                 csd->can_read_partial =
    00245                         extract_bitfield(79, 1, resp);
    00246                 csd->can_write_misaligned =
    00247                         extract_bitfield(78, 1, resp);
    00248                 csd->can_read_misaligned =
    00249                         extract_bitfield(77, 1, resp);
    00250                 csd->write_speed_factor =
    00251                         extract_bitfield(26, 3, resp);
    00252                 csd->write_block_length =
    00253                         extract_bitfield(22, 4, resp);
    00254                 csd->can_write_partial =
    00255                         extract_bitfield(21, 1, resp);
    00256                 break;
    00257         case 1:
    00258                 /*
    00259                  * This is a block-addressed SDHC card. Most
    00260                  * interesting fields are unused and have fixed
    00261                  * values. To avoid getting tripped by buggy cards,
    00262                  * we assume those fixed values ourselves.
    00263                  */
    00264                 csd->read_access_time_ns         = 0; /* Unused */
    00265                 csd->read_access_time_clks       = 0; /* Unused */
    00266
    00267                 mul = extract_bitfield(99, 4, resp);
    00268                 exp = extract_bitfield(96, 3, resp);
    00269                 csd->max_transfer_rate = tran_exp[exp] * tran_mant[mul];
    00270                 csd->command_classes =
    00271                         extract_bitfield(84, 12, resp);
    00272
    00273                 mul = extract_bitfield(48, 22, resp);
    00274                 csd->capacity = (mul + 1) << 10;
    00275
    00276                 csd->read_block_length = 9;
    00277                 csd->can_read_partial = 0;
    00278                 csd->can_write_misaligned = 0;
    00279                 csd->can_read_misaligned = 0;
    00280                 csd->write_speed_factor = 4; /* Unused */
    00281                 csd->write_block_length = 9;
    00282                 csd->can_write_partial = 0;
    00283                 break;
    00284         default:
    00285                 dbg_printf("mmc: unrecognised CSD structure version %d\n",
    00286                                 csd_structure);
    00287                 return -EINVAL;
    00288         }
    00289
    00290         /* Card timeouts might have changed so flush them */
    00291         sdmmc_slot_update(sdmmc_card_get_slot(card));
    00292
    00293         return 0;
    00294 }
    00295
    00296 int sdmmc_decode_mmc_csd(struct sdmmc_card *card, const be32_t *raw_csd)
    00297 {
    00298         struct sdmmc_csd *csd = &card->csd;
    00299         unsigned int exp, mul, csd_structure;
    00300         uint32_t resp[4];
    00301         unsigned int i;
    00302
    00303         for (i = 0; i < 4; i++)
    00304                 resp[3 - i] = be32_to_cpu(raw_csd[i]);
    00305
    00306         dbg_printf("mmc csd: %08x %08x %08x %08x\n",
    00307                         resp[0], resp[1], resp[2], resp[3]);
    00308
    00309         csd_structure = extract_bitfield(126, 2, resp);
    00310         if (csd_structure != 1 && csd_structure != 2) {
    00311                 dbg_printf("mmc: unrecognised CSD structure version %d\n",
    00312                         csd_structure);
    00313                 return -EINVAL;
    00314         }
    00315
    00316         csd->mmc_version = extract_bitfield(122, 4, resp);
    00317         mul = extract_bitfield(115, 4, resp);
    00318         exp = extract_bitfield(112, 3, resp);
    00319         csd->read_access_time_ns =
    00320                 (tacc_exp[exp] * tacc_mant[mul] + 9) / 10;
    00321         csd->read_access_time_clks =
    00322                 extract_bitfield(104, 8, resp) * 100;
    00323
    00324         /* Card timeouts might have changed so flush them */
    00325         sdmmc_slot_update(sdmmc_card_get_slot(card));
    00326
    00327         mul = extract_bitfield(99, 4, resp);
    00328         exp = extract_bitfield(96, 3, resp);
    00329         csd->max_transfer_rate = tran_exp[exp] * tran_mant[mul];
    00330         csd->command_classes = extract_bitfield(84, 12, resp);
    00331
    00332         exp = extract_bitfield(47, 3, resp);
    00333         mul = extract_bitfield(62, 12, resp);
    00334         csd->capacity = (mul + 1) << (exp + 2);
    00335
    00336         csd->read_block_length = extract_bitfield(80, 4, resp);
    00337         csd->can_read_partial = extract_bitfield(79, 1, resp);
    00338         csd->can_write_misaligned = extract_bitfield(78, 1, resp);
    00339         csd->can_read_misaligned = extract_bitfield(77, 1, resp);
    00340         csd->write_speed_factor = extract_bitfield(26, 3, resp);
    00341         csd->write_block_length = extract_bitfield(22, 4, resp);
    00342         csd->can_write_partial = extract_bitfield(21, 1, resp);
    00343
    00344         return 0;
    00345 }
    00346
    00347 static void sdmmc_card_calc_timeout(struct sdmmc_card *card, uint32_t f_cur,
    00348                 bool write)
    00349 {
    00350         uint32_t                *timeout_ns;
    00351         uint32_t                *timeout_clks;
    00352         uint32_t                mult;
    00353
    00354         if (write) {
    00355                 timeout_ns = &card->write_timeout_ns;
    00356                 timeout_clks = &card->write_timeout_clks;
    00357         } else {
    00358                 timeout_ns = &card->read_timeout_ns;
    00359                 timeout_clks = &card->read_timeout_clks;
    00360         }
    00361
    00362         if (sdmmc_card_is_sdhc(card)) {
    00363                 /* SDHC cards use fixed values */
    00364                 if (write)
    00365                         *timeout_ns = 2500000000;
    00366                 else
    00367                         *timeout_ns = 1000000000;
    00368                 *timeout_clks = 0;
    00369         } else {
    00370                 mult = sdmmc_card_is_sd(card) ? 100 : 10;
    00371                 if (write)
    00372                         mult <<= card->csd.read_access_time_ns;
    00373
    00374                 *timeout_ns = card->csd.read_access_time_ns * mult;
    00375                 *timeout_clks = card->csd.read_access_time_clks * mult;
    00376
    00377                 if (sdmmc_card_is_sd(card)) {
    00378                         unsigned int timeout_us, limit_us;
    00379
    00380                         timeout_us = *timeout_ns / 1000;
    00381                         timeout_us += *timeout_clks * 1000 / (f_cur / 1000);
    00382
    00383                         if (write)
    00384                                 limit_us = 2500000;
    00385                         else
    00386                                 limit_us = 1000000;
    00387
    00388                         if (timeout_us > limit_us) {
    00389                                 *timeout_ns = limit_us * 1000;
    00390                                 *timeout_clks = 0;
    00391                         }
    00392                 }
    00393         }
    00394 }
    00395
    00396 void sdmmc_card_update_timeouts(struct sdmmc_card *card, uint32_t mmc_hz)
    00397 {
    00398         sdmmc_card_calc_timeout(card, mmc_hz, true);
    00399         sdmmc_card_calc_timeout(card, mmc_hz, false);
    00400 }