17ea239d9SPierre Ossman /* 270f10482SPierre Ossman * linux/drivers/mmc/core/mmc.c 37ea239d9SPierre Ossman * 47ea239d9SPierre Ossman * Copyright (C) 2003-2004 Russell King, All Rights Reserved. 57ea239d9SPierre Ossman * Copyright (C) 2005-2007 Pierre Ossman, All Rights Reserved. 67ea239d9SPierre Ossman * MMCv4 support Copyright (C) 2006 Philip Langdale, All Rights Reserved. 77ea239d9SPierre Ossman * 87ea239d9SPierre Ossman * This program is free software; you can redistribute it and/or modify 97ea239d9SPierre Ossman * it under the terms of the GNU General Public License version 2 as 107ea239d9SPierre Ossman * published by the Free Software Foundation. 117ea239d9SPierre Ossman */ 127ea239d9SPierre Ossman 137ea239d9SPierre Ossman #include <linux/err.h> 145a0e3ad6STejun Heo #include <linux/slab.h> 150205a904SPaul Gortmaker #include <linux/stat.h> 160cb403a2SUlf Hansson #include <linux/pm_runtime.h> 177ea239d9SPierre Ossman 187ea239d9SPierre Ossman #include <linux/mmc/host.h> 197ea239d9SPierre Ossman #include <linux/mmc/card.h> 207ea239d9SPierre Ossman #include <linux/mmc/mmc.h> 217ea239d9SPierre Ossman 227ea239d9SPierre Ossman #include "core.h" 234101c16aSPierre Ossman #include "bus.h" 247ea239d9SPierre Ossman #include "mmc_ops.h" 254c4cb171SPhilip Rakity #include "sd_ops.h" 267ea239d9SPierre Ossman 277ea239d9SPierre Ossman static const unsigned int tran_exp[] = { 287ea239d9SPierre Ossman 10000, 100000, 1000000, 10000000, 297ea239d9SPierre Ossman 0, 0, 0, 0 307ea239d9SPierre Ossman }; 317ea239d9SPierre Ossman 327ea239d9SPierre Ossman static const unsigned char tran_mant[] = { 337ea239d9SPierre Ossman 0, 10, 12, 13, 15, 20, 25, 30, 347ea239d9SPierre Ossman 35, 40, 45, 50, 55, 60, 70, 80, 357ea239d9SPierre Ossman }; 367ea239d9SPierre Ossman 377ea239d9SPierre Ossman static const unsigned int tacc_exp[] = { 387ea239d9SPierre Ossman 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 397ea239d9SPierre Ossman }; 407ea239d9SPierre Ossman 417ea239d9SPierre Ossman static const unsigned int tacc_mant[] = { 427ea239d9SPierre Ossman 0, 10, 12, 13, 15, 20, 25, 30, 437ea239d9SPierre Ossman 35, 40, 45, 50, 55, 60, 70, 80, 447ea239d9SPierre Ossman }; 457ea239d9SPierre Ossman 467ea239d9SPierre Ossman #define UNSTUFF_BITS(resp,start,size) \ 477ea239d9SPierre Ossman ({ \ 487ea239d9SPierre Ossman const int __size = size; \ 497ea239d9SPierre Ossman const u32 __mask = (__size < 32 ? 1 << __size : 0) - 1; \ 507ea239d9SPierre Ossman const int __off = 3 - ((start) / 32); \ 517ea239d9SPierre Ossman const int __shft = (start) & 31; \ 527ea239d9SPierre Ossman u32 __res; \ 537ea239d9SPierre Ossman \ 547ea239d9SPierre Ossman __res = resp[__off] >> __shft; \ 557ea239d9SPierre Ossman if (__size + __shft > 32) \ 567ea239d9SPierre Ossman __res |= resp[__off-1] << ((32 - __shft) % 32); \ 577ea239d9SPierre Ossman __res & __mask; \ 587ea239d9SPierre Ossman }) 597ea239d9SPierre Ossman 607ea239d9SPierre Ossman /* 617ea239d9SPierre Ossman * Given the decoded CSD structure, decode the raw CID to our CID structure. 627ea239d9SPierre Ossman */ 63bd766312SPierre Ossman static int mmc_decode_cid(struct mmc_card *card) 647ea239d9SPierre Ossman { 657ea239d9SPierre Ossman u32 *resp = card->raw_cid; 667ea239d9SPierre Ossman 677ea239d9SPierre Ossman /* 687ea239d9SPierre Ossman * The selection of the format here is based upon published 697ea239d9SPierre Ossman * specs from sandisk and from what people have reported. 707ea239d9SPierre Ossman */ 717ea239d9SPierre Ossman switch (card->csd.mmca_vsn) { 727ea239d9SPierre Ossman case 0: /* MMC v1.0 - v1.2 */ 737ea239d9SPierre Ossman case 1: /* MMC v1.4 */ 747ea239d9SPierre Ossman card->cid.manfid = UNSTUFF_BITS(resp, 104, 24); 757ea239d9SPierre Ossman card->cid.prod_name[0] = UNSTUFF_BITS(resp, 96, 8); 767ea239d9SPierre Ossman card->cid.prod_name[1] = UNSTUFF_BITS(resp, 88, 8); 777ea239d9SPierre Ossman card->cid.prod_name[2] = UNSTUFF_BITS(resp, 80, 8); 787ea239d9SPierre Ossman card->cid.prod_name[3] = UNSTUFF_BITS(resp, 72, 8); 797ea239d9SPierre Ossman card->cid.prod_name[4] = UNSTUFF_BITS(resp, 64, 8); 807ea239d9SPierre Ossman card->cid.prod_name[5] = UNSTUFF_BITS(resp, 56, 8); 817ea239d9SPierre Ossman card->cid.prod_name[6] = UNSTUFF_BITS(resp, 48, 8); 827ea239d9SPierre Ossman card->cid.hwrev = UNSTUFF_BITS(resp, 44, 4); 837ea239d9SPierre Ossman card->cid.fwrev = UNSTUFF_BITS(resp, 40, 4); 847ea239d9SPierre Ossman card->cid.serial = UNSTUFF_BITS(resp, 16, 24); 857ea239d9SPierre Ossman card->cid.month = UNSTUFF_BITS(resp, 12, 4); 867ea239d9SPierre Ossman card->cid.year = UNSTUFF_BITS(resp, 8, 4) + 1997; 877ea239d9SPierre Ossman break; 887ea239d9SPierre Ossman 897ea239d9SPierre Ossman case 2: /* MMC v2.0 - v2.2 */ 907ea239d9SPierre Ossman case 3: /* MMC v3.1 - v3.3 */ 917ea239d9SPierre Ossman case 4: /* MMC v4 */ 927ea239d9SPierre Ossman card->cid.manfid = UNSTUFF_BITS(resp, 120, 8); 937ea239d9SPierre Ossman card->cid.oemid = UNSTUFF_BITS(resp, 104, 16); 947ea239d9SPierre Ossman card->cid.prod_name[0] = UNSTUFF_BITS(resp, 96, 8); 957ea239d9SPierre Ossman card->cid.prod_name[1] = UNSTUFF_BITS(resp, 88, 8); 967ea239d9SPierre Ossman card->cid.prod_name[2] = UNSTUFF_BITS(resp, 80, 8); 977ea239d9SPierre Ossman card->cid.prod_name[3] = UNSTUFF_BITS(resp, 72, 8); 987ea239d9SPierre Ossman card->cid.prod_name[4] = UNSTUFF_BITS(resp, 64, 8); 997ea239d9SPierre Ossman card->cid.prod_name[5] = UNSTUFF_BITS(resp, 56, 8); 10051e7e8b6SBernie Thompson card->cid.prv = UNSTUFF_BITS(resp, 48, 8); 1017ea239d9SPierre Ossman card->cid.serial = UNSTUFF_BITS(resp, 16, 32); 1027ea239d9SPierre Ossman card->cid.month = UNSTUFF_BITS(resp, 12, 4); 1037ea239d9SPierre Ossman card->cid.year = UNSTUFF_BITS(resp, 8, 4) + 1997; 1047ea239d9SPierre Ossman break; 1057ea239d9SPierre Ossman 1067ea239d9SPierre Ossman default: 107a3c76eb9SGirish K S pr_err("%s: card has unknown MMCA version %d\n", 1087ea239d9SPierre Ossman mmc_hostname(card->host), card->csd.mmca_vsn); 109bd766312SPierre Ossman return -EINVAL; 1107ea239d9SPierre Ossman } 111bd766312SPierre Ossman 112bd766312SPierre Ossman return 0; 1137ea239d9SPierre Ossman } 1147ea239d9SPierre Ossman 115dfe86cbaSAdrian Hunter static void mmc_set_erase_size(struct mmc_card *card) 116dfe86cbaSAdrian Hunter { 117dfe86cbaSAdrian Hunter if (card->ext_csd.erase_group_def & 1) 118dfe86cbaSAdrian Hunter card->erase_size = card->ext_csd.hc_erase_size; 119dfe86cbaSAdrian Hunter else 120dfe86cbaSAdrian Hunter card->erase_size = card->csd.erase_size; 121dfe86cbaSAdrian Hunter 122dfe86cbaSAdrian Hunter mmc_init_erase(card); 123dfe86cbaSAdrian Hunter } 124dfe86cbaSAdrian Hunter 1257ea239d9SPierre Ossman /* 1267ea239d9SPierre Ossman * Given a 128-bit response, decode to our card CSD structure. 1277ea239d9SPierre Ossman */ 128bd766312SPierre Ossman static int mmc_decode_csd(struct mmc_card *card) 1297ea239d9SPierre Ossman { 1307ea239d9SPierre Ossman struct mmc_csd *csd = &card->csd; 131dfe86cbaSAdrian Hunter unsigned int e, m, a, b; 1327ea239d9SPierre Ossman u32 *resp = card->raw_csd; 1337ea239d9SPierre Ossman 1347ea239d9SPierre Ossman /* 1357ea239d9SPierre Ossman * We only understand CSD structure v1.1 and v1.2. 1367ea239d9SPierre Ossman * v1.2 has extra information in bits 15, 11 and 10. 1376da24b78SKyungmin Park * We also support eMMC v4.4 & v4.41. 1387ea239d9SPierre Ossman */ 1396da24b78SKyungmin Park csd->structure = UNSTUFF_BITS(resp, 126, 2); 1406da24b78SKyungmin Park if (csd->structure == 0) { 141a3c76eb9SGirish K S pr_err("%s: unrecognised CSD structure version %d\n", 1426da24b78SKyungmin Park mmc_hostname(card->host), csd->structure); 143bd766312SPierre Ossman return -EINVAL; 1447ea239d9SPierre Ossman } 1457ea239d9SPierre Ossman 1467ea239d9SPierre Ossman csd->mmca_vsn = UNSTUFF_BITS(resp, 122, 4); 1477ea239d9SPierre Ossman m = UNSTUFF_BITS(resp, 115, 4); 1487ea239d9SPierre Ossman e = UNSTUFF_BITS(resp, 112, 3); 1497ea239d9SPierre Ossman csd->tacc_ns = (tacc_exp[e] * tacc_mant[m] + 9) / 10; 1507ea239d9SPierre Ossman csd->tacc_clks = UNSTUFF_BITS(resp, 104, 8) * 100; 1517ea239d9SPierre Ossman 1527ea239d9SPierre Ossman m = UNSTUFF_BITS(resp, 99, 4); 1537ea239d9SPierre Ossman e = UNSTUFF_BITS(resp, 96, 3); 1547ea239d9SPierre Ossman csd->max_dtr = tran_exp[e] * tran_mant[m]; 1557ea239d9SPierre Ossman csd->cmdclass = UNSTUFF_BITS(resp, 84, 12); 1567ea239d9SPierre Ossman 1577ea239d9SPierre Ossman e = UNSTUFF_BITS(resp, 47, 3); 1587ea239d9SPierre Ossman m = UNSTUFF_BITS(resp, 62, 12); 1597ea239d9SPierre Ossman csd->capacity = (1 + m) << (e + 2); 1607ea239d9SPierre Ossman 1617ea239d9SPierre Ossman csd->read_blkbits = UNSTUFF_BITS(resp, 80, 4); 1627ea239d9SPierre Ossman csd->read_partial = UNSTUFF_BITS(resp, 79, 1); 1637ea239d9SPierre Ossman csd->write_misalign = UNSTUFF_BITS(resp, 78, 1); 1647ea239d9SPierre Ossman csd->read_misalign = UNSTUFF_BITS(resp, 77, 1); 1653d705d14SSascha Hauer csd->dsr_imp = UNSTUFF_BITS(resp, 76, 1); 1667ea239d9SPierre Ossman csd->r2w_factor = UNSTUFF_BITS(resp, 26, 3); 1677ea239d9SPierre Ossman csd->write_blkbits = UNSTUFF_BITS(resp, 22, 4); 1687ea239d9SPierre Ossman csd->write_partial = UNSTUFF_BITS(resp, 21, 1); 169bd766312SPierre Ossman 170dfe86cbaSAdrian Hunter if (csd->write_blkbits >= 9) { 171dfe86cbaSAdrian Hunter a = UNSTUFF_BITS(resp, 42, 5); 172dfe86cbaSAdrian Hunter b = UNSTUFF_BITS(resp, 37, 5); 173dfe86cbaSAdrian Hunter csd->erase_size = (a + 1) * (b + 1); 174dfe86cbaSAdrian Hunter csd->erase_size <<= csd->write_blkbits - 9; 175dfe86cbaSAdrian Hunter } 176dfe86cbaSAdrian Hunter 177bd766312SPierre Ossman return 0; 1787ea239d9SPierre Ossman } 1797ea239d9SPierre Ossman 1807ea239d9SPierre Ossman /* 18108ee80ccSPhilip Rakity * Read extended CSD. 1827ea239d9SPierre Ossman */ 18308ee80ccSPhilip Rakity static int mmc_get_ext_csd(struct mmc_card *card, u8 **new_ext_csd) 1847ea239d9SPierre Ossman { 1857ea239d9SPierre Ossman int err; 1867ea239d9SPierre Ossman u8 *ext_csd; 1877ea239d9SPierre Ossman 1887ea239d9SPierre Ossman BUG_ON(!card); 18908ee80ccSPhilip Rakity BUG_ON(!new_ext_csd); 19008ee80ccSPhilip Rakity 191148bcab2SUlf Hansson if (!mmc_can_ext_csd(card)) 192c197787cSUlf Hansson return -EOPNOTSUPP; 1937ea239d9SPierre Ossman 1947ea239d9SPierre Ossman /* 1957ea239d9SPierre Ossman * As the ext_csd is so large and mostly unused, we don't store the 1967ea239d9SPierre Ossman * raw block in mmc_card. 1977ea239d9SPierre Ossman */ 1987ea239d9SPierre Ossman ext_csd = kmalloc(512, GFP_KERNEL); 199a1fc444eSUlf Hansson if (!ext_csd) 20017b0429dSPierre Ossman return -ENOMEM; 2017ea239d9SPierre Ossman 2027ea239d9SPierre Ossman err = mmc_send_ext_csd(card, ext_csd); 203c197787cSUlf Hansson if (err) 20408ee80ccSPhilip Rakity kfree(ext_csd); 205c197787cSUlf Hansson else 20608ee80ccSPhilip Rakity *new_ext_csd = ext_csd; 207adf66a0dSPierre Ossman 20808ee80ccSPhilip Rakity return err; 2097ea239d9SPierre Ossman } 2107ea239d9SPierre Ossman 21196cf5f02SSeungwon Jeon static void mmc_select_card_type(struct mmc_card *card) 21296cf5f02SSeungwon Jeon { 21396cf5f02SSeungwon Jeon struct mmc_host *host = card->host; 2140a5b6438SSeungwon Jeon u8 card_type = card->ext_csd.raw_card_type; 2155f1a4dd0SLee Jones u32 caps = host->caps, caps2 = host->caps2; 216577fb131SSeungwon Jeon unsigned int hs_max_dtr = 0, hs200_max_dtr = 0; 2172415c0efSSeungwon Jeon unsigned int avail_type = 0; 21896cf5f02SSeungwon Jeon 21996cf5f02SSeungwon Jeon if (caps & MMC_CAP_MMC_HIGHSPEED && 2202415c0efSSeungwon Jeon card_type & EXT_CSD_CARD_TYPE_HS_26) { 2212415c0efSSeungwon Jeon hs_max_dtr = MMC_HIGH_26_MAX_DTR; 2222415c0efSSeungwon Jeon avail_type |= EXT_CSD_CARD_TYPE_HS_26; 2232415c0efSSeungwon Jeon } 2242415c0efSSeungwon Jeon 2252415c0efSSeungwon Jeon if (caps & MMC_CAP_MMC_HIGHSPEED && 2262415c0efSSeungwon Jeon card_type & EXT_CSD_CARD_TYPE_HS_52) { 22796cf5f02SSeungwon Jeon hs_max_dtr = MMC_HIGH_52_MAX_DTR; 2282415c0efSSeungwon Jeon avail_type |= EXT_CSD_CARD_TYPE_HS_52; 2292415c0efSSeungwon Jeon } 23096cf5f02SSeungwon Jeon 2312415c0efSSeungwon Jeon if (caps & MMC_CAP_1_8V_DDR && 2322415c0efSSeungwon Jeon card_type & EXT_CSD_CARD_TYPE_DDR_1_8V) { 23396cf5f02SSeungwon Jeon hs_max_dtr = MMC_HIGH_DDR_MAX_DTR; 2342415c0efSSeungwon Jeon avail_type |= EXT_CSD_CARD_TYPE_DDR_1_8V; 2352415c0efSSeungwon Jeon } 23696cf5f02SSeungwon Jeon 2372415c0efSSeungwon Jeon if (caps & MMC_CAP_1_2V_DDR && 2382415c0efSSeungwon Jeon card_type & EXT_CSD_CARD_TYPE_DDR_1_2V) { 2392415c0efSSeungwon Jeon hs_max_dtr = MMC_HIGH_DDR_MAX_DTR; 2402415c0efSSeungwon Jeon avail_type |= EXT_CSD_CARD_TYPE_DDR_1_2V; 2412415c0efSSeungwon Jeon } 2422415c0efSSeungwon Jeon 2432415c0efSSeungwon Jeon if (caps2 & MMC_CAP2_HS200_1_8V_SDR && 2442415c0efSSeungwon Jeon card_type & EXT_CSD_CARD_TYPE_HS200_1_8V) { 245577fb131SSeungwon Jeon hs200_max_dtr = MMC_HS200_MAX_DTR; 2462415c0efSSeungwon Jeon avail_type |= EXT_CSD_CARD_TYPE_HS200_1_8V; 2472415c0efSSeungwon Jeon } 2482415c0efSSeungwon Jeon 2492415c0efSSeungwon Jeon if (caps2 & MMC_CAP2_HS200_1_2V_SDR && 2502415c0efSSeungwon Jeon card_type & EXT_CSD_CARD_TYPE_HS200_1_2V) { 251577fb131SSeungwon Jeon hs200_max_dtr = MMC_HS200_MAX_DTR; 2522415c0efSSeungwon Jeon avail_type |= EXT_CSD_CARD_TYPE_HS200_1_2V; 2532415c0efSSeungwon Jeon } 25496cf5f02SSeungwon Jeon 2550a5b6438SSeungwon Jeon if (caps2 & MMC_CAP2_HS400_1_8V && 2560a5b6438SSeungwon Jeon card_type & EXT_CSD_CARD_TYPE_HS400_1_8V) { 2570a5b6438SSeungwon Jeon hs200_max_dtr = MMC_HS200_MAX_DTR; 2580a5b6438SSeungwon Jeon avail_type |= EXT_CSD_CARD_TYPE_HS400_1_8V; 2590a5b6438SSeungwon Jeon } 2600a5b6438SSeungwon Jeon 2610a5b6438SSeungwon Jeon if (caps2 & MMC_CAP2_HS400_1_2V && 2620a5b6438SSeungwon Jeon card_type & EXT_CSD_CARD_TYPE_HS400_1_2V) { 2630a5b6438SSeungwon Jeon hs200_max_dtr = MMC_HS200_MAX_DTR; 2640a5b6438SSeungwon Jeon avail_type |= EXT_CSD_CARD_TYPE_HS400_1_2V; 2650a5b6438SSeungwon Jeon } 2660a5b6438SSeungwon Jeon 26796cf5f02SSeungwon Jeon card->ext_csd.hs_max_dtr = hs_max_dtr; 268577fb131SSeungwon Jeon card->ext_csd.hs200_max_dtr = hs200_max_dtr; 2692415c0efSSeungwon Jeon card->mmc_avail_type = avail_type; 27096cf5f02SSeungwon Jeon } 27196cf5f02SSeungwon Jeon 272b4493eeaSGrégory Soutadé static void mmc_manage_enhanced_area(struct mmc_card *card, u8 *ext_csd) 273b4493eeaSGrégory Soutadé { 274994324bbSGrégory Soutadé u8 hc_erase_grp_sz, hc_wp_grp_sz; 275994324bbSGrégory Soutadé 276994324bbSGrégory Soutadé /* 277994324bbSGrégory Soutadé * Disable these attributes by default 278994324bbSGrégory Soutadé */ 279994324bbSGrégory Soutadé card->ext_csd.enhanced_area_offset = -EINVAL; 280994324bbSGrégory Soutadé card->ext_csd.enhanced_area_size = -EINVAL; 281b4493eeaSGrégory Soutadé 282b4493eeaSGrégory Soutadé /* 283b4493eeaSGrégory Soutadé * Enhanced area feature support -- check whether the eMMC 284b4493eeaSGrégory Soutadé * card has the Enhanced area enabled. If so, export enhanced 285b4493eeaSGrégory Soutadé * area offset and size to user by adding sysfs interface. 286b4493eeaSGrégory Soutadé */ 287b4493eeaSGrégory Soutadé if ((ext_csd[EXT_CSD_PARTITION_SUPPORT] & 0x2) && 288b4493eeaSGrégory Soutadé (ext_csd[EXT_CSD_PARTITION_ATTRIBUTE] & 0x1)) { 289994324bbSGrégory Soutadé if (card->ext_csd.partition_setting_completed) { 290b4493eeaSGrégory Soutadé hc_erase_grp_sz = 291b4493eeaSGrégory Soutadé ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]; 292b4493eeaSGrégory Soutadé hc_wp_grp_sz = 293b4493eeaSGrégory Soutadé ext_csd[EXT_CSD_HC_WP_GRP_SIZE]; 294b4493eeaSGrégory Soutadé 295b4493eeaSGrégory Soutadé /* 296b4493eeaSGrégory Soutadé * calculate the enhanced data area offset, in bytes 297b4493eeaSGrégory Soutadé */ 298b4493eeaSGrégory Soutadé card->ext_csd.enhanced_area_offset = 299b4493eeaSGrégory Soutadé (ext_csd[139] << 24) + (ext_csd[138] << 16) + 300b4493eeaSGrégory Soutadé (ext_csd[137] << 8) + ext_csd[136]; 301b4493eeaSGrégory Soutadé if (mmc_card_blockaddr(card)) 302b4493eeaSGrégory Soutadé card->ext_csd.enhanced_area_offset <<= 9; 303b4493eeaSGrégory Soutadé /* 304b4493eeaSGrégory Soutadé * calculate the enhanced data area size, in kilobytes 305b4493eeaSGrégory Soutadé */ 306b4493eeaSGrégory Soutadé card->ext_csd.enhanced_area_size = 307b4493eeaSGrégory Soutadé (ext_csd[142] << 16) + (ext_csd[141] << 8) + 308b4493eeaSGrégory Soutadé ext_csd[140]; 309b4493eeaSGrégory Soutadé card->ext_csd.enhanced_area_size *= 310b4493eeaSGrégory Soutadé (size_t)(hc_erase_grp_sz * hc_wp_grp_sz); 311b4493eeaSGrégory Soutadé card->ext_csd.enhanced_area_size <<= 9; 312b4493eeaSGrégory Soutadé } else { 313994324bbSGrégory Soutadé pr_warn("%s: defines enhanced area without partition setting complete\n", 314994324bbSGrégory Soutadé mmc_hostname(card->host)); 315994324bbSGrégory Soutadé } 316b4493eeaSGrégory Soutadé } 317b4493eeaSGrégory Soutadé } 318b4493eeaSGrégory Soutadé 319b4493eeaSGrégory Soutadé static void mmc_manage_gp_partitions(struct mmc_card *card, u8 *ext_csd) 320b4493eeaSGrégory Soutadé { 321b4493eeaSGrégory Soutadé int idx; 322994324bbSGrégory Soutadé u8 hc_erase_grp_sz, hc_wp_grp_sz; 323994324bbSGrégory Soutadé unsigned int part_size; 324b4493eeaSGrégory Soutadé 325b4493eeaSGrégory Soutadé /* 326b4493eeaSGrégory Soutadé * General purpose partition feature support -- 327b4493eeaSGrégory Soutadé * If ext_csd has the size of general purpose partitions, 328b4493eeaSGrégory Soutadé * set size, part_cfg, partition name in mmc_part. 329b4493eeaSGrégory Soutadé */ 330b4493eeaSGrégory Soutadé if (ext_csd[EXT_CSD_PARTITION_SUPPORT] & 331b4493eeaSGrégory Soutadé EXT_CSD_PART_SUPPORT_PART_EN) { 332b4493eeaSGrégory Soutadé hc_erase_grp_sz = 333b4493eeaSGrégory Soutadé ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]; 334b4493eeaSGrégory Soutadé hc_wp_grp_sz = 335b4493eeaSGrégory Soutadé ext_csd[EXT_CSD_HC_WP_GRP_SIZE]; 336b4493eeaSGrégory Soutadé 337b4493eeaSGrégory Soutadé for (idx = 0; idx < MMC_NUM_GP_PARTITION; idx++) { 338b4493eeaSGrégory Soutadé if (!ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3] && 339b4493eeaSGrégory Soutadé !ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3 + 1] && 340b4493eeaSGrégory Soutadé !ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3 + 2]) 341b4493eeaSGrégory Soutadé continue; 342994324bbSGrégory Soutadé if (card->ext_csd.partition_setting_completed == 0) { 343994324bbSGrégory Soutadé pr_warn("%s: has partition size defined without partition complete\n", 344994324bbSGrégory Soutadé mmc_hostname(card->host)); 345994324bbSGrégory Soutadé break; 346994324bbSGrégory Soutadé } 347b4493eeaSGrégory Soutadé part_size = 348b4493eeaSGrégory Soutadé (ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3 + 2] 349b4493eeaSGrégory Soutadé << 16) + 350b4493eeaSGrégory Soutadé (ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3 + 1] 351b4493eeaSGrégory Soutadé << 8) + 352b4493eeaSGrégory Soutadé ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3]; 353b4493eeaSGrégory Soutadé part_size *= (size_t)(hc_erase_grp_sz * 354b4493eeaSGrégory Soutadé hc_wp_grp_sz); 355b4493eeaSGrégory Soutadé mmc_part_add(card, part_size << 19, 356b4493eeaSGrégory Soutadé EXT_CSD_PART_CONFIG_ACC_GP0 + idx, 357b4493eeaSGrégory Soutadé "gp%d", idx, false, 358b4493eeaSGrégory Soutadé MMC_BLK_DATA_AREA_GP); 359b4493eeaSGrégory Soutadé } 360b4493eeaSGrégory Soutadé } 361b4493eeaSGrégory Soutadé } 362b4493eeaSGrégory Soutadé 36308ee80ccSPhilip Rakity /* 36408ee80ccSPhilip Rakity * Decode extended CSD. 36508ee80ccSPhilip Rakity */ 366076ec38aSUlf Hansson static int mmc_decode_ext_csd(struct mmc_card *card, u8 *ext_csd) 36708ee80ccSPhilip Rakity { 368e0c368d5SNamjae Jeon int err = 0, idx; 369e0c368d5SNamjae Jeon unsigned int part_size; 37008ee80ccSPhilip Rakity 37108ee80ccSPhilip Rakity BUG_ON(!card); 37208ee80ccSPhilip Rakity 3736da24b78SKyungmin Park /* Version is coded in the CSD_STRUCTURE byte in the EXT_CSD register */ 374f39b2dd9SPhilip Rakity card->ext_csd.raw_ext_csd_structure = ext_csd[EXT_CSD_STRUCTURE]; 3756da24b78SKyungmin Park if (card->csd.structure == 3) { 376f39b2dd9SPhilip Rakity if (card->ext_csd.raw_ext_csd_structure > 2) { 377a3c76eb9SGirish K S pr_err("%s: unrecognised EXT_CSD structure " 3788fdd8521SPierre Ossman "version %d\n", mmc_hostname(card->host), 379f39b2dd9SPhilip Rakity card->ext_csd.raw_ext_csd_structure); 3806da24b78SKyungmin Park err = -EINVAL; 3816da24b78SKyungmin Park goto out; 3826da24b78SKyungmin Park } 3836da24b78SKyungmin Park } 3846da24b78SKyungmin Park 38503a59437SRomain Izard /* 38603a59437SRomain Izard * The EXT_CSD format is meant to be forward compatible. As long 38703a59437SRomain Izard * as CSD_STRUCTURE does not change, all values for EXT_CSD_REV 38803a59437SRomain Izard * are authorized, see JEDEC JESD84-B50 section B.8. 38903a59437SRomain Izard */ 3906da24b78SKyungmin Park card->ext_csd.rev = ext_csd[EXT_CSD_REV]; 391d7604d76SPierre Ossman 392f39b2dd9SPhilip Rakity card->ext_csd.raw_sectors[0] = ext_csd[EXT_CSD_SEC_CNT + 0]; 393f39b2dd9SPhilip Rakity card->ext_csd.raw_sectors[1] = ext_csd[EXT_CSD_SEC_CNT + 1]; 394f39b2dd9SPhilip Rakity card->ext_csd.raw_sectors[2] = ext_csd[EXT_CSD_SEC_CNT + 2]; 395f39b2dd9SPhilip Rakity card->ext_csd.raw_sectors[3] = ext_csd[EXT_CSD_SEC_CNT + 3]; 396b1ebe384SJarkko Lavinen if (card->ext_csd.rev >= 2) { 3977ea239d9SPierre Ossman card->ext_csd.sectors = 3987ea239d9SPierre Ossman ext_csd[EXT_CSD_SEC_CNT + 0] << 0 | 3997ea239d9SPierre Ossman ext_csd[EXT_CSD_SEC_CNT + 1] << 8 | 4007ea239d9SPierre Ossman ext_csd[EXT_CSD_SEC_CNT + 2] << 16 | 4017ea239d9SPierre Ossman ext_csd[EXT_CSD_SEC_CNT + 3] << 24; 402fc8a0985SHanumath Prasad 403fc8a0985SHanumath Prasad /* Cards with density > 2GiB are sector addressed */ 404fc8a0985SHanumath Prasad if (card->ext_csd.sectors > (2u * 1024 * 1024 * 1024) / 512) 4057ea239d9SPierre Ossman mmc_card_set_blockaddr(card); 406d7604d76SPierre Ossman } 40796cf5f02SSeungwon Jeon 408f39b2dd9SPhilip Rakity card->ext_csd.raw_card_type = ext_csd[EXT_CSD_CARD_TYPE]; 40996cf5f02SSeungwon Jeon mmc_select_card_type(card); 4107ea239d9SPierre Ossman 411f39b2dd9SPhilip Rakity card->ext_csd.raw_s_a_timeout = ext_csd[EXT_CSD_S_A_TIMEOUT]; 412f39b2dd9SPhilip Rakity card->ext_csd.raw_erase_timeout_mult = 413f39b2dd9SPhilip Rakity ext_csd[EXT_CSD_ERASE_TIMEOUT_MULT]; 414f39b2dd9SPhilip Rakity card->ext_csd.raw_hc_erase_grp_size = 415f39b2dd9SPhilip Rakity ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]; 416b1ebe384SJarkko Lavinen if (card->ext_csd.rev >= 3) { 417b1ebe384SJarkko Lavinen u8 sa_shift = ext_csd[EXT_CSD_S_A_TIMEOUT]; 418371a689fSAndrei Warkentin card->ext_csd.part_config = ext_csd[EXT_CSD_PART_CONFIG]; 419371a689fSAndrei Warkentin 420371a689fSAndrei Warkentin /* EXT_CSD value is in units of 10ms, but we store in ms */ 421371a689fSAndrei Warkentin card->ext_csd.part_time = 10 * ext_csd[EXT_CSD_PART_SWITCH_TIME]; 422b1ebe384SJarkko Lavinen 423b1ebe384SJarkko Lavinen /* Sleep / awake timeout in 100ns units */ 424b1ebe384SJarkko Lavinen if (sa_shift > 0 && sa_shift <= 0x17) 425b1ebe384SJarkko Lavinen card->ext_csd.sa_timeout = 426b1ebe384SJarkko Lavinen 1 << ext_csd[EXT_CSD_S_A_TIMEOUT]; 427dfe86cbaSAdrian Hunter card->ext_csd.erase_group_def = 428dfe86cbaSAdrian Hunter ext_csd[EXT_CSD_ERASE_GROUP_DEF]; 429dfe86cbaSAdrian Hunter card->ext_csd.hc_erase_timeout = 300 * 430dfe86cbaSAdrian Hunter ext_csd[EXT_CSD_ERASE_TIMEOUT_MULT]; 431dfe86cbaSAdrian Hunter card->ext_csd.hc_erase_size = 432dfe86cbaSAdrian Hunter ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] << 10; 433f4c5522bSAndrei Warkentin 434f4c5522bSAndrei Warkentin card->ext_csd.rel_sectors = ext_csd[EXT_CSD_REL_WR_SEC_C]; 435371a689fSAndrei Warkentin 436371a689fSAndrei Warkentin /* 437371a689fSAndrei Warkentin * There are two boot regions of equal size, defined in 438371a689fSAndrei Warkentin * multiples of 128K. 439371a689fSAndrei Warkentin */ 440e0c368d5SNamjae Jeon if (ext_csd[EXT_CSD_BOOT_MULT] && mmc_boot_partition_access(card->host)) { 441e0c368d5SNamjae Jeon for (idx = 0; idx < MMC_NUM_BOOT_PARTITION; idx++) { 442e0c368d5SNamjae Jeon part_size = ext_csd[EXT_CSD_BOOT_MULT] << 17; 443e0c368d5SNamjae Jeon mmc_part_add(card, part_size, 444e0c368d5SNamjae Jeon EXT_CSD_PART_CONFIG_ACC_BOOT0 + idx, 445add710eaSJohan Rudholm "boot%d", idx, true, 446add710eaSJohan Rudholm MMC_BLK_DATA_AREA_BOOT); 447e0c368d5SNamjae Jeon } 448e0c368d5SNamjae Jeon } 449b1ebe384SJarkko Lavinen } 450b1ebe384SJarkko Lavinen 451f39b2dd9SPhilip Rakity card->ext_csd.raw_hc_erase_gap_size = 452dd13b4edSJurgen Heeks ext_csd[EXT_CSD_HC_WP_GRP_SIZE]; 453f39b2dd9SPhilip Rakity card->ext_csd.raw_sec_trim_mult = 454f39b2dd9SPhilip Rakity ext_csd[EXT_CSD_SEC_TRIM_MULT]; 455f39b2dd9SPhilip Rakity card->ext_csd.raw_sec_erase_mult = 456f39b2dd9SPhilip Rakity ext_csd[EXT_CSD_SEC_ERASE_MULT]; 457f39b2dd9SPhilip Rakity card->ext_csd.raw_sec_feature_support = 458f39b2dd9SPhilip Rakity ext_csd[EXT_CSD_SEC_FEATURE_SUPPORT]; 459f39b2dd9SPhilip Rakity card->ext_csd.raw_trim_mult = 460f39b2dd9SPhilip Rakity ext_csd[EXT_CSD_TRIM_MULT]; 461836dc2feSPhilip Rakity card->ext_csd.raw_partition_support = ext_csd[EXT_CSD_PARTITION_SUPPORT]; 462dfe86cbaSAdrian Hunter if (card->ext_csd.rev >= 4) { 46369803d4fSGrégory Soutadé if (ext_csd[EXT_CSD_PARTITION_SETTING_COMPLETED] & 46469803d4fSGrégory Soutadé EXT_CSD_PART_SETTING_COMPLETED) 46569803d4fSGrégory Soutadé card->ext_csd.partition_setting_completed = 1; 46669803d4fSGrégory Soutadé else 46769803d4fSGrégory Soutadé card->ext_csd.partition_setting_completed = 0; 46869803d4fSGrégory Soutadé 469b4493eeaSGrégory Soutadé mmc_manage_enhanced_area(card, ext_csd); 470709de99dSChuanxiao Dong 471b4493eeaSGrégory Soutadé mmc_manage_gp_partitions(card, ext_csd); 472e0c368d5SNamjae Jeon 473dfe86cbaSAdrian Hunter card->ext_csd.sec_trim_mult = 474dfe86cbaSAdrian Hunter ext_csd[EXT_CSD_SEC_TRIM_MULT]; 475dfe86cbaSAdrian Hunter card->ext_csd.sec_erase_mult = 476dfe86cbaSAdrian Hunter ext_csd[EXT_CSD_SEC_ERASE_MULT]; 477dfe86cbaSAdrian Hunter card->ext_csd.sec_feature_support = 478dfe86cbaSAdrian Hunter ext_csd[EXT_CSD_SEC_FEATURE_SUPPORT]; 479dfe86cbaSAdrian Hunter card->ext_csd.trim_timeout = 300 * 480dfe86cbaSAdrian Hunter ext_csd[EXT_CSD_TRIM_MULT]; 481add710eaSJohan Rudholm 482add710eaSJohan Rudholm /* 483add710eaSJohan Rudholm * Note that the call to mmc_part_add above defaults to read 484add710eaSJohan Rudholm * only. If this default assumption is changed, the call must 485add710eaSJohan Rudholm * take into account the value of boot_locked below. 486add710eaSJohan Rudholm */ 487add710eaSJohan Rudholm card->ext_csd.boot_ro_lock = ext_csd[EXT_CSD_BOOT_WP]; 488add710eaSJohan Rudholm card->ext_csd.boot_ro_lockable = true; 48960443712SFredrik Soderstedt 49060443712SFredrik Soderstedt /* Save power class values */ 49160443712SFredrik Soderstedt card->ext_csd.raw_pwr_cl_52_195 = 49260443712SFredrik Soderstedt ext_csd[EXT_CSD_PWR_CL_52_195]; 49360443712SFredrik Soderstedt card->ext_csd.raw_pwr_cl_26_195 = 49460443712SFredrik Soderstedt ext_csd[EXT_CSD_PWR_CL_26_195]; 49560443712SFredrik Soderstedt card->ext_csd.raw_pwr_cl_52_360 = 49660443712SFredrik Soderstedt ext_csd[EXT_CSD_PWR_CL_52_360]; 49760443712SFredrik Soderstedt card->ext_csd.raw_pwr_cl_26_360 = 49860443712SFredrik Soderstedt ext_csd[EXT_CSD_PWR_CL_26_360]; 49960443712SFredrik Soderstedt card->ext_csd.raw_pwr_cl_200_195 = 50060443712SFredrik Soderstedt ext_csd[EXT_CSD_PWR_CL_200_195]; 50160443712SFredrik Soderstedt card->ext_csd.raw_pwr_cl_200_360 = 50260443712SFredrik Soderstedt ext_csd[EXT_CSD_PWR_CL_200_360]; 50360443712SFredrik Soderstedt card->ext_csd.raw_pwr_cl_ddr_52_195 = 50460443712SFredrik Soderstedt ext_csd[EXT_CSD_PWR_CL_DDR_52_195]; 50560443712SFredrik Soderstedt card->ext_csd.raw_pwr_cl_ddr_52_360 = 50660443712SFredrik Soderstedt ext_csd[EXT_CSD_PWR_CL_DDR_52_360]; 5070a5b6438SSeungwon Jeon card->ext_csd.raw_pwr_cl_ddr_200_360 = 5080a5b6438SSeungwon Jeon ext_csd[EXT_CSD_PWR_CL_DDR_200_360]; 509dfe86cbaSAdrian Hunter } 510dfe86cbaSAdrian Hunter 511b2499518SAdrian Hunter if (card->ext_csd.rev >= 5) { 5127c4f10acSRomain Izard /* Adjust production date as per JEDEC JESD84-B451 */ 5137c4f10acSRomain Izard if (card->cid.year < 2010) 5147c4f10acSRomain Izard card->cid.year += 16; 5157c4f10acSRomain Izard 516950d56acSJaehoon Chung /* check whether the eMMC card supports BKOPS */ 517950d56acSJaehoon Chung if (ext_csd[EXT_CSD_BKOPS_SUPPORT] & 0x1) { 518950d56acSJaehoon Chung card->ext_csd.bkops = 1; 519950d56acSJaehoon Chung card->ext_csd.bkops_en = ext_csd[EXT_CSD_BKOPS_EN]; 520950d56acSJaehoon Chung card->ext_csd.raw_bkops_status = 521950d56acSJaehoon Chung ext_csd[EXT_CSD_BKOPS_STATUS]; 522950d56acSJaehoon Chung if (!card->ext_csd.bkops_en) 523950d56acSJaehoon Chung pr_info("%s: BKOPS_EN bit is not set\n", 524950d56acSJaehoon Chung mmc_hostname(card->host)); 525950d56acSJaehoon Chung } 526950d56acSJaehoon Chung 527eb0d8f13SJaehoon Chung /* check whether the eMMC card supports HPI */ 528eb0d8f13SJaehoon Chung if (ext_csd[EXT_CSD_HPI_FEATURES] & 0x1) { 529eb0d8f13SJaehoon Chung card->ext_csd.hpi = 1; 530eb0d8f13SJaehoon Chung if (ext_csd[EXT_CSD_HPI_FEATURES] & 0x2) 531eb0d8f13SJaehoon Chung card->ext_csd.hpi_cmd = MMC_STOP_TRANSMISSION; 532eb0d8f13SJaehoon Chung else 533eb0d8f13SJaehoon Chung card->ext_csd.hpi_cmd = MMC_SEND_STATUS; 534eb0d8f13SJaehoon Chung /* 535eb0d8f13SJaehoon Chung * Indicate the maximum timeout to close 536eb0d8f13SJaehoon Chung * a command interrupted by HPI 537eb0d8f13SJaehoon Chung */ 538eb0d8f13SJaehoon Chung card->ext_csd.out_of_int_time = 539eb0d8f13SJaehoon Chung ext_csd[EXT_CSD_OUT_OF_INTERRUPT_TIME] * 10; 540eb0d8f13SJaehoon Chung } 541eb0d8f13SJaehoon Chung 542f4c5522bSAndrei Warkentin card->ext_csd.rel_param = ext_csd[EXT_CSD_WR_REL_PARAM]; 543b2499518SAdrian Hunter card->ext_csd.rst_n_function = ext_csd[EXT_CSD_RST_N_FUNCTION]; 544090d25feSLoic Pallardy 545090d25feSLoic Pallardy /* 546090d25feSLoic Pallardy * RPMB regions are defined in multiples of 128K. 547090d25feSLoic Pallardy */ 548090d25feSLoic Pallardy card->ext_csd.raw_rpmb_size_mult = ext_csd[EXT_CSD_RPMB_MULT]; 549d0123ccaSBalaji T K if (ext_csd[EXT_CSD_RPMB_MULT] && mmc_host_cmd23(card->host)) { 550090d25feSLoic Pallardy mmc_part_add(card, ext_csd[EXT_CSD_RPMB_MULT] << 17, 551090d25feSLoic Pallardy EXT_CSD_PART_CONFIG_ACC_RPMB, 552090d25feSLoic Pallardy "rpmb", 0, false, 553090d25feSLoic Pallardy MMC_BLK_DATA_AREA_RPMB); 554090d25feSLoic Pallardy } 555b2499518SAdrian Hunter } 556f4c5522bSAndrei Warkentin 5575238acbeSAndrei Warkentin card->ext_csd.raw_erased_mem_count = ext_csd[EXT_CSD_ERASED_MEM_CONT]; 558dfe86cbaSAdrian Hunter if (ext_csd[EXT_CSD_ERASED_MEM_CONT]) 559dfe86cbaSAdrian Hunter card->erased_byte = 0xFF; 560dfe86cbaSAdrian Hunter else 561dfe86cbaSAdrian Hunter card->erased_byte = 0x0; 562dfe86cbaSAdrian Hunter 563336c716aSSeungwon Jeon /* eMMC v4.5 or later */ 564bec8726aSGirish K S if (card->ext_csd.rev >= 6) { 565336c716aSSeungwon Jeon card->ext_csd.feature_support |= MMC_DISCARD_FEATURE; 566336c716aSSeungwon Jeon 567b23cf0bdSSeungwon Jeon card->ext_csd.generic_cmd6_time = 10 * 568b23cf0bdSSeungwon Jeon ext_csd[EXT_CSD_GENERIC_CMD6_TIME]; 569bec8726aSGirish K S card->ext_csd.power_off_longtime = 10 * 570bec8726aSGirish K S ext_csd[EXT_CSD_POWER_OFF_LONG_TIME]; 571b23cf0bdSSeungwon Jeon 572881d1c25SSeungwon Jeon card->ext_csd.cache_size = 573881d1c25SSeungwon Jeon ext_csd[EXT_CSD_CACHE_SIZE + 0] << 0 | 574881d1c25SSeungwon Jeon ext_csd[EXT_CSD_CACHE_SIZE + 1] << 8 | 575881d1c25SSeungwon Jeon ext_csd[EXT_CSD_CACHE_SIZE + 2] << 16 | 576881d1c25SSeungwon Jeon ext_csd[EXT_CSD_CACHE_SIZE + 3] << 24; 5774265900eSSaugata Das 5784265900eSSaugata Das if (ext_csd[EXT_CSD_DATA_SECTOR_SIZE] == 1) 5794265900eSSaugata Das card->ext_csd.data_sector_size = 4096; 5804265900eSSaugata Das else 5814265900eSSaugata Das card->ext_csd.data_sector_size = 512; 5824265900eSSaugata Das 5834265900eSSaugata Das if ((ext_csd[EXT_CSD_DATA_TAG_SUPPORT] & 1) && 5844265900eSSaugata Das (ext_csd[EXT_CSD_TAG_UNIT_SIZE] <= 8)) { 5854265900eSSaugata Das card->ext_csd.data_tag_unit_size = 5864265900eSSaugata Das ((unsigned int) 1 << ext_csd[EXT_CSD_TAG_UNIT_SIZE]) * 5874265900eSSaugata Das (card->ext_csd.data_sector_size); 5884265900eSSaugata Das } else { 5894265900eSSaugata Das card->ext_csd.data_tag_unit_size = 0; 5904265900eSSaugata Das } 591abd9ac14SSeungwon Jeon 592abd9ac14SSeungwon Jeon card->ext_csd.max_packed_writes = 593abd9ac14SSeungwon Jeon ext_csd[EXT_CSD_MAX_PACKED_WRITES]; 594abd9ac14SSeungwon Jeon card->ext_csd.max_packed_reads = 595abd9ac14SSeungwon Jeon ext_csd[EXT_CSD_MAX_PACKED_READS]; 596a5075eb9SSaugata Das } else { 597a5075eb9SSaugata Das card->ext_csd.data_sector_size = 512; 598336c716aSSeungwon Jeon } 599881d1c25SSeungwon Jeon 6000f762426SGwendal Grignou /* eMMC v5 or later */ 6010f762426SGwendal Grignou if (card->ext_csd.rev >= 7) { 6020f762426SGwendal Grignou memcpy(card->ext_csd.fwrev, &ext_csd[EXT_CSD_FIRMWARE_VERSION], 6030f762426SGwendal Grignou MMC_FIRMWARE_LEN); 6040f762426SGwendal Grignou card->ext_csd.ffu_capable = 6050f762426SGwendal Grignou (ext_csd[EXT_CSD_SUPPORTED_MODE] & 0x1) && 6060f762426SGwendal Grignou !(ext_csd[EXT_CSD_FW_CONFIG] & 0x1); 6070f762426SGwendal Grignou } 6087ea239d9SPierre Ossman out: 60908ee80ccSPhilip Rakity return err; 61008ee80ccSPhilip Rakity } 6117ea239d9SPierre Ossman 612076ec38aSUlf Hansson static int mmc_read_ext_csd(struct mmc_card *card) 613076ec38aSUlf Hansson { 614c197787cSUlf Hansson u8 *ext_csd; 615076ec38aSUlf Hansson int err; 616076ec38aSUlf Hansson 617c197787cSUlf Hansson if (!mmc_can_ext_csd(card)) 618c197787cSUlf Hansson return 0; 619c197787cSUlf Hansson 620076ec38aSUlf Hansson err = mmc_get_ext_csd(card, &ext_csd); 621c197787cSUlf Hansson if (err) { 622c197787cSUlf Hansson /* If the host or the card can't do the switch, 623c197787cSUlf Hansson * fail more gracefully. */ 624c197787cSUlf Hansson if ((err != -EINVAL) 625c197787cSUlf Hansson && (err != -ENOSYS) 626c197787cSUlf Hansson && (err != -EFAULT)) 627076ec38aSUlf Hansson return err; 628076ec38aSUlf Hansson 629c197787cSUlf Hansson /* 630c197787cSUlf Hansson * High capacity cards should have this "magic" size 631c197787cSUlf Hansson * stored in their CSD. 632c197787cSUlf Hansson */ 633c197787cSUlf Hansson if (card->csd.capacity == (4096 * 512)) { 634c197787cSUlf Hansson pr_err("%s: unable to read EXT_CSD on a possible high capacity card. Card will be ignored.\n", 635c197787cSUlf Hansson mmc_hostname(card->host)); 636c197787cSUlf Hansson } else { 637c197787cSUlf Hansson pr_warn("%s: unable to read EXT_CSD, performance might suffer\n", 638c197787cSUlf Hansson mmc_hostname(card->host)); 639c197787cSUlf Hansson err = 0; 640c197787cSUlf Hansson } 641c197787cSUlf Hansson 642c197787cSUlf Hansson return err; 643c197787cSUlf Hansson } 644c197787cSUlf Hansson 645076ec38aSUlf Hansson err = mmc_decode_ext_csd(card, ext_csd); 646076ec38aSUlf Hansson kfree(ext_csd); 647076ec38aSUlf Hansson return err; 648076ec38aSUlf Hansson } 649076ec38aSUlf Hansson 650f39b2dd9SPhilip Rakity static int mmc_compare_ext_csds(struct mmc_card *card, unsigned bus_width) 65108ee80ccSPhilip Rakity { 65208ee80ccSPhilip Rakity u8 *bw_ext_csd; 65308ee80ccSPhilip Rakity int err; 65408ee80ccSPhilip Rakity 655f39b2dd9SPhilip Rakity if (bus_width == MMC_BUS_WIDTH_1) 656f39b2dd9SPhilip Rakity return 0; 65708ee80ccSPhilip Rakity 658f39b2dd9SPhilip Rakity err = mmc_get_ext_csd(card, &bw_ext_csd); 659c197787cSUlf Hansson if (err) 660c197787cSUlf Hansson return err; 66108ee80ccSPhilip Rakity 66208ee80ccSPhilip Rakity /* only compare read only fields */ 663dd13b4edSJurgen Heeks err = !((card->ext_csd.raw_partition_support == 66408ee80ccSPhilip Rakity bw_ext_csd[EXT_CSD_PARTITION_SUPPORT]) && 665f39b2dd9SPhilip Rakity (card->ext_csd.raw_erased_mem_count == 66608ee80ccSPhilip Rakity bw_ext_csd[EXT_CSD_ERASED_MEM_CONT]) && 667f39b2dd9SPhilip Rakity (card->ext_csd.rev == 66808ee80ccSPhilip Rakity bw_ext_csd[EXT_CSD_REV]) && 669f39b2dd9SPhilip Rakity (card->ext_csd.raw_ext_csd_structure == 67008ee80ccSPhilip Rakity bw_ext_csd[EXT_CSD_STRUCTURE]) && 671f39b2dd9SPhilip Rakity (card->ext_csd.raw_card_type == 67208ee80ccSPhilip Rakity bw_ext_csd[EXT_CSD_CARD_TYPE]) && 673f39b2dd9SPhilip Rakity (card->ext_csd.raw_s_a_timeout == 67408ee80ccSPhilip Rakity bw_ext_csd[EXT_CSD_S_A_TIMEOUT]) && 675f39b2dd9SPhilip Rakity (card->ext_csd.raw_hc_erase_gap_size == 67608ee80ccSPhilip Rakity bw_ext_csd[EXT_CSD_HC_WP_GRP_SIZE]) && 677f39b2dd9SPhilip Rakity (card->ext_csd.raw_erase_timeout_mult == 67808ee80ccSPhilip Rakity bw_ext_csd[EXT_CSD_ERASE_TIMEOUT_MULT]) && 679f39b2dd9SPhilip Rakity (card->ext_csd.raw_hc_erase_grp_size == 68008ee80ccSPhilip Rakity bw_ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]) && 681f39b2dd9SPhilip Rakity (card->ext_csd.raw_sec_trim_mult == 68208ee80ccSPhilip Rakity bw_ext_csd[EXT_CSD_SEC_TRIM_MULT]) && 683f39b2dd9SPhilip Rakity (card->ext_csd.raw_sec_erase_mult == 68408ee80ccSPhilip Rakity bw_ext_csd[EXT_CSD_SEC_ERASE_MULT]) && 685f39b2dd9SPhilip Rakity (card->ext_csd.raw_sec_feature_support == 68608ee80ccSPhilip Rakity bw_ext_csd[EXT_CSD_SEC_FEATURE_SUPPORT]) && 687f39b2dd9SPhilip Rakity (card->ext_csd.raw_trim_mult == 68808ee80ccSPhilip Rakity bw_ext_csd[EXT_CSD_TRIM_MULT]) && 689f39b2dd9SPhilip Rakity (card->ext_csd.raw_sectors[0] == 690f39b2dd9SPhilip Rakity bw_ext_csd[EXT_CSD_SEC_CNT + 0]) && 691f39b2dd9SPhilip Rakity (card->ext_csd.raw_sectors[1] == 692f39b2dd9SPhilip Rakity bw_ext_csd[EXT_CSD_SEC_CNT + 1]) && 693f39b2dd9SPhilip Rakity (card->ext_csd.raw_sectors[2] == 694f39b2dd9SPhilip Rakity bw_ext_csd[EXT_CSD_SEC_CNT + 2]) && 695f39b2dd9SPhilip Rakity (card->ext_csd.raw_sectors[3] == 69660443712SFredrik Soderstedt bw_ext_csd[EXT_CSD_SEC_CNT + 3]) && 69760443712SFredrik Soderstedt (card->ext_csd.raw_pwr_cl_52_195 == 69860443712SFredrik Soderstedt bw_ext_csd[EXT_CSD_PWR_CL_52_195]) && 69960443712SFredrik Soderstedt (card->ext_csd.raw_pwr_cl_26_195 == 70060443712SFredrik Soderstedt bw_ext_csd[EXT_CSD_PWR_CL_26_195]) && 70160443712SFredrik Soderstedt (card->ext_csd.raw_pwr_cl_52_360 == 70260443712SFredrik Soderstedt bw_ext_csd[EXT_CSD_PWR_CL_52_360]) && 70360443712SFredrik Soderstedt (card->ext_csd.raw_pwr_cl_26_360 == 70460443712SFredrik Soderstedt bw_ext_csd[EXT_CSD_PWR_CL_26_360]) && 70560443712SFredrik Soderstedt (card->ext_csd.raw_pwr_cl_200_195 == 70660443712SFredrik Soderstedt bw_ext_csd[EXT_CSD_PWR_CL_200_195]) && 70760443712SFredrik Soderstedt (card->ext_csd.raw_pwr_cl_200_360 == 70860443712SFredrik Soderstedt bw_ext_csd[EXT_CSD_PWR_CL_200_360]) && 70960443712SFredrik Soderstedt (card->ext_csd.raw_pwr_cl_ddr_52_195 == 71060443712SFredrik Soderstedt bw_ext_csd[EXT_CSD_PWR_CL_DDR_52_195]) && 71160443712SFredrik Soderstedt (card->ext_csd.raw_pwr_cl_ddr_52_360 == 7120a5b6438SSeungwon Jeon bw_ext_csd[EXT_CSD_PWR_CL_DDR_52_360]) && 7130a5b6438SSeungwon Jeon (card->ext_csd.raw_pwr_cl_ddr_200_360 == 7140a5b6438SSeungwon Jeon bw_ext_csd[EXT_CSD_PWR_CL_DDR_200_360])); 7150a5b6438SSeungwon Jeon 71608ee80ccSPhilip Rakity if (err) 71708ee80ccSPhilip Rakity err = -EINVAL; 71808ee80ccSPhilip Rakity 71900b41b58SUlf Hansson kfree(bw_ext_csd); 7207ea239d9SPierre Ossman return err; 7217ea239d9SPierre Ossman } 7227ea239d9SPierre Ossman 72351ec92e2SPierre Ossman MMC_DEV_ATTR(cid, "%08x%08x%08x%08x\n", card->raw_cid[0], card->raw_cid[1], 72451ec92e2SPierre Ossman card->raw_cid[2], card->raw_cid[3]); 72551ec92e2SPierre Ossman MMC_DEV_ATTR(csd, "%08x%08x%08x%08x\n", card->raw_csd[0], card->raw_csd[1], 72651ec92e2SPierre Ossman card->raw_csd[2], card->raw_csd[3]); 72751ec92e2SPierre Ossman MMC_DEV_ATTR(date, "%02d/%04d\n", card->cid.month, card->cid.year); 728dfe86cbaSAdrian Hunter MMC_DEV_ATTR(erase_size, "%u\n", card->erase_size << 9); 729dfe86cbaSAdrian Hunter MMC_DEV_ATTR(preferred_erase_size, "%u\n", card->pref_erase << 9); 7300f762426SGwendal Grignou MMC_DEV_ATTR(ffu_capable, "%d\n", card->ext_csd.ffu_capable); 73151ec92e2SPierre Ossman MMC_DEV_ATTR(hwrev, "0x%x\n", card->cid.hwrev); 73251ec92e2SPierre Ossman MMC_DEV_ATTR(manfid, "0x%06x\n", card->cid.manfid); 73351ec92e2SPierre Ossman MMC_DEV_ATTR(name, "%s\n", card->cid.prod_name); 73451ec92e2SPierre Ossman MMC_DEV_ATTR(oemid, "0x%04x\n", card->cid.oemid); 73551e7e8b6SBernie Thompson MMC_DEV_ATTR(prv, "0x%x\n", card->cid.prv); 73651ec92e2SPierre Ossman MMC_DEV_ATTR(serial, "0x%08x\n", card->cid.serial); 737709de99dSChuanxiao Dong MMC_DEV_ATTR(enhanced_area_offset, "%llu\n", 738709de99dSChuanxiao Dong card->ext_csd.enhanced_area_offset); 739709de99dSChuanxiao Dong MMC_DEV_ATTR(enhanced_area_size, "%u\n", card->ext_csd.enhanced_area_size); 740188cc042SLoic Pallardy MMC_DEV_ATTR(raw_rpmb_size_mult, "%#x\n", card->ext_csd.raw_rpmb_size_mult); 741188cc042SLoic Pallardy MMC_DEV_ATTR(rel_sectors, "%#x\n", card->ext_csd.rel_sectors); 74251ec92e2SPierre Ossman 7430f762426SGwendal Grignou static ssize_t mmc_fwrev_show(struct device *dev, 7440f762426SGwendal Grignou struct device_attribute *attr, 7450f762426SGwendal Grignou char *buf) 7460f762426SGwendal Grignou { 7470f762426SGwendal Grignou struct mmc_card *card = mmc_dev_to_card(dev); 7480f762426SGwendal Grignou 7490f762426SGwendal Grignou if (card->ext_csd.rev < 7) { 7500f762426SGwendal Grignou return sprintf(buf, "0x%x\n", card->cid.fwrev); 7510f762426SGwendal Grignou } else { 7520f762426SGwendal Grignou return sprintf(buf, "0x%*phN\n", MMC_FIRMWARE_LEN, 7530f762426SGwendal Grignou card->ext_csd.fwrev); 7540f762426SGwendal Grignou } 7550f762426SGwendal Grignou } 7560f762426SGwendal Grignou 7570f762426SGwendal Grignou static DEVICE_ATTR(fwrev, S_IRUGO, mmc_fwrev_show, NULL); 7580f762426SGwendal Grignou 75951ec92e2SPierre Ossman static struct attribute *mmc_std_attrs[] = { 76051ec92e2SPierre Ossman &dev_attr_cid.attr, 76151ec92e2SPierre Ossman &dev_attr_csd.attr, 76251ec92e2SPierre Ossman &dev_attr_date.attr, 763dfe86cbaSAdrian Hunter &dev_attr_erase_size.attr, 764dfe86cbaSAdrian Hunter &dev_attr_preferred_erase_size.attr, 76551ec92e2SPierre Ossman &dev_attr_fwrev.attr, 7660f762426SGwendal Grignou &dev_attr_ffu_capable.attr, 76751ec92e2SPierre Ossman &dev_attr_hwrev.attr, 76851ec92e2SPierre Ossman &dev_attr_manfid.attr, 76951ec92e2SPierre Ossman &dev_attr_name.attr, 77051ec92e2SPierre Ossman &dev_attr_oemid.attr, 77151e7e8b6SBernie Thompson &dev_attr_prv.attr, 77251ec92e2SPierre Ossman &dev_attr_serial.attr, 773709de99dSChuanxiao Dong &dev_attr_enhanced_area_offset.attr, 774709de99dSChuanxiao Dong &dev_attr_enhanced_area_size.attr, 775188cc042SLoic Pallardy &dev_attr_raw_rpmb_size_mult.attr, 776188cc042SLoic Pallardy &dev_attr_rel_sectors.attr, 77751ec92e2SPierre Ossman NULL, 77851ec92e2SPierre Ossman }; 779d1e58212SAxel Lin ATTRIBUTE_GROUPS(mmc_std); 78051ec92e2SPierre Ossman 78151ec92e2SPierre Ossman static struct device_type mmc_type = { 782d1e58212SAxel Lin .groups = mmc_std_groups, 78351ec92e2SPierre Ossman }; 78451ec92e2SPierre Ossman 7857ea239d9SPierre Ossman /* 786b87d8dbfSGirish K S * Select the PowerClass for the current bus width 787b87d8dbfSGirish K S * If power class is defined for 4/8 bit bus in the 788b87d8dbfSGirish K S * extended CSD register, select it by executing the 789b87d8dbfSGirish K S * mmc_switch command. 790b87d8dbfSGirish K S */ 7912385049dSSeungwon Jeon static int __mmc_select_powerclass(struct mmc_card *card, 79260443712SFredrik Soderstedt unsigned int bus_width) 793b87d8dbfSGirish K S { 7942385049dSSeungwon Jeon struct mmc_host *host = card->host; 7952385049dSSeungwon Jeon struct mmc_ext_csd *ext_csd = &card->ext_csd; 79660443712SFredrik Soderstedt unsigned int pwrclass_val = 0; 7972385049dSSeungwon Jeon int err = 0; 798b87d8dbfSGirish K S 799b87d8dbfSGirish K S switch (1 << host->ios.vdd) { 800b87d8dbfSGirish K S case MMC_VDD_165_195: 8012385049dSSeungwon Jeon if (host->ios.clock <= MMC_HIGH_26_MAX_DTR) 8022385049dSSeungwon Jeon pwrclass_val = ext_csd->raw_pwr_cl_26_195; 8032385049dSSeungwon Jeon else if (host->ios.clock <= MMC_HIGH_52_MAX_DTR) 80460443712SFredrik Soderstedt pwrclass_val = (bus_width <= EXT_CSD_BUS_WIDTH_8) ? 8052385049dSSeungwon Jeon ext_csd->raw_pwr_cl_52_195 : 8062385049dSSeungwon Jeon ext_csd->raw_pwr_cl_ddr_52_195; 8072385049dSSeungwon Jeon else if (host->ios.clock <= MMC_HS200_MAX_DTR) 8082385049dSSeungwon Jeon pwrclass_val = ext_csd->raw_pwr_cl_200_195; 809b87d8dbfSGirish K S break; 81093fc5a47SSubhash Jadavani case MMC_VDD_27_28: 81193fc5a47SSubhash Jadavani case MMC_VDD_28_29: 81293fc5a47SSubhash Jadavani case MMC_VDD_29_30: 81393fc5a47SSubhash Jadavani case MMC_VDD_30_31: 81493fc5a47SSubhash Jadavani case MMC_VDD_31_32: 815b87d8dbfSGirish K S case MMC_VDD_32_33: 816b87d8dbfSGirish K S case MMC_VDD_33_34: 817b87d8dbfSGirish K S case MMC_VDD_34_35: 818b87d8dbfSGirish K S case MMC_VDD_35_36: 8192385049dSSeungwon Jeon if (host->ios.clock <= MMC_HIGH_26_MAX_DTR) 8202385049dSSeungwon Jeon pwrclass_val = ext_csd->raw_pwr_cl_26_360; 8212385049dSSeungwon Jeon else if (host->ios.clock <= MMC_HIGH_52_MAX_DTR) 82260443712SFredrik Soderstedt pwrclass_val = (bus_width <= EXT_CSD_BUS_WIDTH_8) ? 8232385049dSSeungwon Jeon ext_csd->raw_pwr_cl_52_360 : 8242385049dSSeungwon Jeon ext_csd->raw_pwr_cl_ddr_52_360; 8252385049dSSeungwon Jeon else if (host->ios.clock <= MMC_HS200_MAX_DTR) 8260a5b6438SSeungwon Jeon pwrclass_val = (bus_width == EXT_CSD_DDR_BUS_WIDTH_8) ? 8270a5b6438SSeungwon Jeon ext_csd->raw_pwr_cl_ddr_200_360 : 8280a5b6438SSeungwon Jeon ext_csd->raw_pwr_cl_200_360; 829b87d8dbfSGirish K S break; 830b87d8dbfSGirish K S default: 8316606110dSJoe Perches pr_warn("%s: Voltage range not supported for power class\n", 8326606110dSJoe Perches mmc_hostname(host)); 833b87d8dbfSGirish K S return -EINVAL; 834b87d8dbfSGirish K S } 835b87d8dbfSGirish K S 836b87d8dbfSGirish K S if (bus_width & (EXT_CSD_BUS_WIDTH_8 | EXT_CSD_DDR_BUS_WIDTH_8)) 837b87d8dbfSGirish K S pwrclass_val = (pwrclass_val & EXT_CSD_PWR_CL_8BIT_MASK) >> 838b87d8dbfSGirish K S EXT_CSD_PWR_CL_8BIT_SHIFT; 839b87d8dbfSGirish K S else 840b87d8dbfSGirish K S pwrclass_val = (pwrclass_val & EXT_CSD_PWR_CL_4BIT_MASK) >> 841b87d8dbfSGirish K S EXT_CSD_PWR_CL_4BIT_SHIFT; 842b87d8dbfSGirish K S 843b87d8dbfSGirish K S /* If the power class is different from the default value */ 844b87d8dbfSGirish K S if (pwrclass_val > 0) { 845b87d8dbfSGirish K S err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, 846b87d8dbfSGirish K S EXT_CSD_POWER_CLASS, 847b87d8dbfSGirish K S pwrclass_val, 84871fe3eb0SSeungwon Jeon card->ext_csd.generic_cmd6_time); 849b87d8dbfSGirish K S } 850b87d8dbfSGirish K S 851b87d8dbfSGirish K S return err; 852b87d8dbfSGirish K S } 853b87d8dbfSGirish K S 8542385049dSSeungwon Jeon static int mmc_select_powerclass(struct mmc_card *card) 8552385049dSSeungwon Jeon { 8562385049dSSeungwon Jeon struct mmc_host *host = card->host; 8572385049dSSeungwon Jeon u32 bus_width, ext_csd_bits; 8582385049dSSeungwon Jeon int err, ddr; 8592385049dSSeungwon Jeon 8602385049dSSeungwon Jeon /* Power class selection is supported for versions >= 4.0 */ 861148bcab2SUlf Hansson if (!mmc_can_ext_csd(card)) 8622385049dSSeungwon Jeon return 0; 8632385049dSSeungwon Jeon 8642385049dSSeungwon Jeon bus_width = host->ios.bus_width; 8652385049dSSeungwon Jeon /* Power class values are defined only for 4/8 bit bus */ 8662385049dSSeungwon Jeon if (bus_width == MMC_BUS_WIDTH_1) 8672385049dSSeungwon Jeon return 0; 8682385049dSSeungwon Jeon 8692385049dSSeungwon Jeon ddr = card->mmc_avail_type & EXT_CSD_CARD_TYPE_DDR_52; 8702385049dSSeungwon Jeon if (ddr) 8712385049dSSeungwon Jeon ext_csd_bits = (bus_width == MMC_BUS_WIDTH_8) ? 8722385049dSSeungwon Jeon EXT_CSD_DDR_BUS_WIDTH_8 : EXT_CSD_DDR_BUS_WIDTH_4; 8732385049dSSeungwon Jeon else 8742385049dSSeungwon Jeon ext_csd_bits = (bus_width == MMC_BUS_WIDTH_8) ? 8752385049dSSeungwon Jeon EXT_CSD_BUS_WIDTH_8 : EXT_CSD_BUS_WIDTH_4; 8762385049dSSeungwon Jeon 8772385049dSSeungwon Jeon err = __mmc_select_powerclass(card, ext_csd_bits); 8782385049dSSeungwon Jeon if (err) 8792385049dSSeungwon Jeon pr_warn("%s: power class selection to bus width %d ddr %d failed\n", 8802385049dSSeungwon Jeon mmc_hostname(host), 1 << bus_width, ddr); 8812385049dSSeungwon Jeon 8822385049dSSeungwon Jeon return err; 8832385049dSSeungwon Jeon } 8842385049dSSeungwon Jeon 885b87d8dbfSGirish K S /* 886577fb131SSeungwon Jeon * Set the bus speed for the selected speed mode. 887a4924c71SGirish K S */ 888577fb131SSeungwon Jeon static void mmc_set_bus_speed(struct mmc_card *card) 889a4924c71SGirish K S { 890577fb131SSeungwon Jeon unsigned int max_dtr = (unsigned int)-1; 891577fb131SSeungwon Jeon 8920a5b6438SSeungwon Jeon if ((mmc_card_hs200(card) || mmc_card_hs400(card)) && 8930a5b6438SSeungwon Jeon max_dtr > card->ext_csd.hs200_max_dtr) 894577fb131SSeungwon Jeon max_dtr = card->ext_csd.hs200_max_dtr; 895577fb131SSeungwon Jeon else if (mmc_card_hs(card) && max_dtr > card->ext_csd.hs_max_dtr) 896577fb131SSeungwon Jeon max_dtr = card->ext_csd.hs_max_dtr; 897577fb131SSeungwon Jeon else if (max_dtr > card->csd.max_dtr) 898577fb131SSeungwon Jeon max_dtr = card->csd.max_dtr; 899577fb131SSeungwon Jeon 900577fb131SSeungwon Jeon mmc_set_clock(card->host, max_dtr); 901577fb131SSeungwon Jeon } 902577fb131SSeungwon Jeon 903577fb131SSeungwon Jeon /* 904577fb131SSeungwon Jeon * Select the bus width amoung 4-bit and 8-bit(SDR). 905577fb131SSeungwon Jeon * If the bus width is changed successfully, return the selected width value. 906577fb131SSeungwon Jeon * Zero is returned instead of error value if the wide width is not supported. 907577fb131SSeungwon Jeon */ 908577fb131SSeungwon Jeon static int mmc_select_bus_width(struct mmc_card *card) 909577fb131SSeungwon Jeon { 910a4924c71SGirish K S static unsigned ext_csd_bits[] = { 911a4924c71SGirish K S EXT_CSD_BUS_WIDTH_8, 912577fb131SSeungwon Jeon EXT_CSD_BUS_WIDTH_4, 913a4924c71SGirish K S }; 914a4924c71SGirish K S static unsigned bus_widths[] = { 915a4924c71SGirish K S MMC_BUS_WIDTH_8, 916577fb131SSeungwon Jeon MMC_BUS_WIDTH_4, 917a4924c71SGirish K S }; 918577fb131SSeungwon Jeon struct mmc_host *host = card->host; 919577fb131SSeungwon Jeon unsigned idx, bus_width = 0; 920577fb131SSeungwon Jeon int err = 0; 921a4924c71SGirish K S 922148bcab2SUlf Hansson if (!mmc_can_ext_csd(card) && 923577fb131SSeungwon Jeon !(host->caps & (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA))) 924577fb131SSeungwon Jeon return 0; 925a4924c71SGirish K S 926577fb131SSeungwon Jeon idx = (host->caps & MMC_CAP_8_BIT_DATA) ? 0 : 1; 927a4924c71SGirish K S 928a4924c71SGirish K S /* 929a4924c71SGirish K S * Unlike SD, MMC cards dont have a configuration register to notify 930a4924c71SGirish K S * supported bus width. So bus test command should be run to identify 931a4924c71SGirish K S * the supported bus width or compare the ext csd values of current 932a4924c71SGirish K S * bus width and ext csd values of 1 bit mode read earlier. 933a4924c71SGirish K S */ 934577fb131SSeungwon Jeon for (; idx < ARRAY_SIZE(bus_widths); idx++) { 935a4924c71SGirish K S /* 936a4924c71SGirish K S * Host is capable of 8bit transfer, then switch 937a4924c71SGirish K S * the device to work in 8bit transfer mode. If the 938a4924c71SGirish K S * mmc switch command returns error then switch to 939a4924c71SGirish K S * 4bit transfer mode. On success set the corresponding 940a4924c71SGirish K S * bus width on the host. 941a4924c71SGirish K S */ 942a4924c71SGirish K S err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, 943a4924c71SGirish K S EXT_CSD_BUS_WIDTH, 944a4924c71SGirish K S ext_csd_bits[idx], 945a4924c71SGirish K S card->ext_csd.generic_cmd6_time); 946a4924c71SGirish K S if (err) 947a4924c71SGirish K S continue; 948a4924c71SGirish K S 949577fb131SSeungwon Jeon bus_width = bus_widths[idx]; 950577fb131SSeungwon Jeon mmc_set_bus_width(host, bus_width); 951a4924c71SGirish K S 952577fb131SSeungwon Jeon /* 953577fb131SSeungwon Jeon * If controller can't handle bus width test, 954577fb131SSeungwon Jeon * compare ext_csd previously read in 1 bit mode 955577fb131SSeungwon Jeon * against ext_csd at new bus width 956577fb131SSeungwon Jeon */ 957a4924c71SGirish K S if (!(host->caps & MMC_CAP_BUS_WIDTH_TEST)) 958577fb131SSeungwon Jeon err = mmc_compare_ext_csds(card, bus_width); 959a4924c71SGirish K S else 960577fb131SSeungwon Jeon err = mmc_bus_test(card, bus_width); 961577fb131SSeungwon Jeon 962577fb131SSeungwon Jeon if (!err) { 963577fb131SSeungwon Jeon err = bus_width; 964a4924c71SGirish K S break; 965577fb131SSeungwon Jeon } else { 966577fb131SSeungwon Jeon pr_warn("%s: switch to bus width %d failed\n", 967577fb131SSeungwon Jeon mmc_hostname(host), ext_csd_bits[idx]); 968577fb131SSeungwon Jeon } 969a4924c71SGirish K S } 970a4924c71SGirish K S 971577fb131SSeungwon Jeon return err; 972577fb131SSeungwon Jeon } 973577fb131SSeungwon Jeon 974577fb131SSeungwon Jeon /* 975577fb131SSeungwon Jeon * Switch to the high-speed mode 976577fb131SSeungwon Jeon */ 977577fb131SSeungwon Jeon static int mmc_select_hs(struct mmc_card *card) 978577fb131SSeungwon Jeon { 979577fb131SSeungwon Jeon int err; 980577fb131SSeungwon Jeon 9814509f847SUlf Hansson err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, 982577fb131SSeungwon Jeon EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS, 98357de31f6SUlf Hansson card->ext_csd.generic_cmd6_time, 98457de31f6SUlf Hansson true, true, true); 985577fb131SSeungwon Jeon if (!err) 986577fb131SSeungwon Jeon mmc_set_timing(card->host, MMC_TIMING_MMC_HS); 987577fb131SSeungwon Jeon 988577fb131SSeungwon Jeon return err; 989577fb131SSeungwon Jeon } 990577fb131SSeungwon Jeon 991577fb131SSeungwon Jeon /* 992577fb131SSeungwon Jeon * Activate wide bus and DDR if supported. 993577fb131SSeungwon Jeon */ 994577fb131SSeungwon Jeon static int mmc_select_hs_ddr(struct mmc_card *card) 995577fb131SSeungwon Jeon { 996577fb131SSeungwon Jeon struct mmc_host *host = card->host; 997577fb131SSeungwon Jeon u32 bus_width, ext_csd_bits; 998577fb131SSeungwon Jeon int err = 0; 999577fb131SSeungwon Jeon 1000577fb131SSeungwon Jeon if (!(card->mmc_avail_type & EXT_CSD_CARD_TYPE_DDR_52)) 1001577fb131SSeungwon Jeon return 0; 1002577fb131SSeungwon Jeon 1003577fb131SSeungwon Jeon bus_width = host->ios.bus_width; 1004577fb131SSeungwon Jeon if (bus_width == MMC_BUS_WIDTH_1) 1005577fb131SSeungwon Jeon return 0; 1006577fb131SSeungwon Jeon 1007577fb131SSeungwon Jeon ext_csd_bits = (bus_width == MMC_BUS_WIDTH_8) ? 1008577fb131SSeungwon Jeon EXT_CSD_DDR_BUS_WIDTH_8 : EXT_CSD_DDR_BUS_WIDTH_4; 1009577fb131SSeungwon Jeon 1010577fb131SSeungwon Jeon err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, 1011577fb131SSeungwon Jeon EXT_CSD_BUS_WIDTH, 1012577fb131SSeungwon Jeon ext_csd_bits, 1013577fb131SSeungwon Jeon card->ext_csd.generic_cmd6_time); 1014577fb131SSeungwon Jeon if (err) { 10154b75bffcSAndrew Gabbasov pr_err("%s: switch to bus width %d ddr failed\n", 1016577fb131SSeungwon Jeon mmc_hostname(host), 1 << bus_width); 1017577fb131SSeungwon Jeon return err; 1018577fb131SSeungwon Jeon } 1019577fb131SSeungwon Jeon 1020577fb131SSeungwon Jeon /* 1021577fb131SSeungwon Jeon * eMMC cards can support 3.3V to 1.2V i/o (vccq) 1022577fb131SSeungwon Jeon * signaling. 1023577fb131SSeungwon Jeon * 1024577fb131SSeungwon Jeon * EXT_CSD_CARD_TYPE_DDR_1_8V means 3.3V or 1.8V vccq. 1025577fb131SSeungwon Jeon * 1026577fb131SSeungwon Jeon * 1.8V vccq at 3.3V core voltage (vcc) is not required 1027577fb131SSeungwon Jeon * in the JEDEC spec for DDR. 1028577fb131SSeungwon Jeon * 1029312449efSChuanxiao.Dong * Even (e)MMC card can support 3.3v to 1.2v vccq, but not all 1030312449efSChuanxiao.Dong * host controller can support this, like some of the SDHCI 1031312449efSChuanxiao.Dong * controller which connect to an eMMC device. Some of these 1032312449efSChuanxiao.Dong * host controller still needs to use 1.8v vccq for supporting 1033312449efSChuanxiao.Dong * DDR mode. 1034312449efSChuanxiao.Dong * 1035312449efSChuanxiao.Dong * So the sequence will be: 1036312449efSChuanxiao.Dong * if (host and device can both support 1.2v IO) 1037312449efSChuanxiao.Dong * use 1.2v IO; 1038312449efSChuanxiao.Dong * else if (host and device can both support 1.8v IO) 1039312449efSChuanxiao.Dong * use 1.8v IO; 1040312449efSChuanxiao.Dong * so if host and device can only support 3.3v IO, this is the 1041312449efSChuanxiao.Dong * last choice. 1042577fb131SSeungwon Jeon * 1043577fb131SSeungwon Jeon * WARNING: eMMC rules are NOT the same as SD DDR 1044577fb131SSeungwon Jeon */ 1045312449efSChuanxiao.Dong err = -EINVAL; 1046312449efSChuanxiao.Dong if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_DDR_1_2V) 1047312449efSChuanxiao.Dong err = __mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_120); 1048577fb131SSeungwon Jeon 1049312449efSChuanxiao.Dong if (err && (card->mmc_avail_type & EXT_CSD_CARD_TYPE_DDR_1_8V)) 1050312449efSChuanxiao.Dong err = __mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180); 1051312449efSChuanxiao.Dong 1052312449efSChuanxiao.Dong /* make sure vccq is 3.3v after switching disaster */ 1053312449efSChuanxiao.Dong if (err) 1054312449efSChuanxiao.Dong err = __mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_330); 1055312449efSChuanxiao.Dong 1056312449efSChuanxiao.Dong if (!err) 1057577fb131SSeungwon Jeon mmc_set_timing(host, MMC_TIMING_MMC_DDR52); 1058577fb131SSeungwon Jeon 1059577fb131SSeungwon Jeon return err; 1060577fb131SSeungwon Jeon } 1061577fb131SSeungwon Jeon 10620a5b6438SSeungwon Jeon static int mmc_select_hs400(struct mmc_card *card) 10630a5b6438SSeungwon Jeon { 10640a5b6438SSeungwon Jeon struct mmc_host *host = card->host; 10650a5b6438SSeungwon Jeon int err = 0; 10660a5b6438SSeungwon Jeon 10670a5b6438SSeungwon Jeon /* 10680a5b6438SSeungwon Jeon * HS400 mode requires 8-bit bus width 10690a5b6438SSeungwon Jeon */ 10700a5b6438SSeungwon Jeon if (!(card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400 && 10710a5b6438SSeungwon Jeon host->ios.bus_width == MMC_BUS_WIDTH_8)) 10720a5b6438SSeungwon Jeon return 0; 10730a5b6438SSeungwon Jeon 10740a5b6438SSeungwon Jeon /* 10750a5b6438SSeungwon Jeon * Before switching to dual data rate operation for HS400, 10760a5b6438SSeungwon Jeon * it is required to convert from HS200 mode to HS mode. 10770a5b6438SSeungwon Jeon */ 10780a5b6438SSeungwon Jeon mmc_set_timing(card->host, MMC_TIMING_MMC_HS); 10790a5b6438SSeungwon Jeon mmc_set_bus_speed(card); 10800a5b6438SSeungwon Jeon 10810a5b6438SSeungwon Jeon err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, 10820a5b6438SSeungwon Jeon EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS, 10830a5b6438SSeungwon Jeon card->ext_csd.generic_cmd6_time, 10840a5b6438SSeungwon Jeon true, true, true); 10850a5b6438SSeungwon Jeon if (err) { 10864b75bffcSAndrew Gabbasov pr_err("%s: switch to high-speed from hs200 failed, err:%d\n", 10870a5b6438SSeungwon Jeon mmc_hostname(host), err); 10880a5b6438SSeungwon Jeon return err; 10890a5b6438SSeungwon Jeon } 10900a5b6438SSeungwon Jeon 10910a5b6438SSeungwon Jeon err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, 10920a5b6438SSeungwon Jeon EXT_CSD_BUS_WIDTH, 10930a5b6438SSeungwon Jeon EXT_CSD_DDR_BUS_WIDTH_8, 10940a5b6438SSeungwon Jeon card->ext_csd.generic_cmd6_time); 10950a5b6438SSeungwon Jeon if (err) { 10964b75bffcSAndrew Gabbasov pr_err("%s: switch to bus width for hs400 failed, err:%d\n", 10970a5b6438SSeungwon Jeon mmc_hostname(host), err); 10980a5b6438SSeungwon Jeon return err; 10990a5b6438SSeungwon Jeon } 11000a5b6438SSeungwon Jeon 11010a5b6438SSeungwon Jeon err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, 11020a5b6438SSeungwon Jeon EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS400, 11030a5b6438SSeungwon Jeon card->ext_csd.generic_cmd6_time, 11040a5b6438SSeungwon Jeon true, true, true); 11050a5b6438SSeungwon Jeon if (err) { 11064b75bffcSAndrew Gabbasov pr_err("%s: switch to hs400 failed, err:%d\n", 11070a5b6438SSeungwon Jeon mmc_hostname(host), err); 11080a5b6438SSeungwon Jeon return err; 11090a5b6438SSeungwon Jeon } 11100a5b6438SSeungwon Jeon 11110a5b6438SSeungwon Jeon mmc_set_timing(host, MMC_TIMING_MMC_HS400); 11120a5b6438SSeungwon Jeon mmc_set_bus_speed(card); 11130a5b6438SSeungwon Jeon 11140a5b6438SSeungwon Jeon return 0; 11150a5b6438SSeungwon Jeon } 11160a5b6438SSeungwon Jeon 1117577fb131SSeungwon Jeon /* 1118577fb131SSeungwon Jeon * For device supporting HS200 mode, the following sequence 1119577fb131SSeungwon Jeon * should be done before executing the tuning process. 1120577fb131SSeungwon Jeon * 1. set the desired bus width(4-bit or 8-bit, 1-bit is not supported) 1121577fb131SSeungwon Jeon * 2. switch to HS200 mode 1122577fb131SSeungwon Jeon * 3. set the clock to > 52Mhz and <=200MHz 1123577fb131SSeungwon Jeon */ 1124577fb131SSeungwon Jeon static int mmc_select_hs200(struct mmc_card *card) 1125577fb131SSeungwon Jeon { 1126577fb131SSeungwon Jeon struct mmc_host *host = card->host; 1127577fb131SSeungwon Jeon int err = -EINVAL; 1128577fb131SSeungwon Jeon 1129577fb131SSeungwon Jeon if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS200_1_2V) 1130577fb131SSeungwon Jeon err = __mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_120); 1131577fb131SSeungwon Jeon 1132577fb131SSeungwon Jeon if (err && card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS200_1_8V) 1133577fb131SSeungwon Jeon err = __mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180); 1134577fb131SSeungwon Jeon 1135577fb131SSeungwon Jeon /* If fails try again during next card power cycle */ 1136577fb131SSeungwon Jeon if (err) 1137577fb131SSeungwon Jeon goto err; 1138577fb131SSeungwon Jeon 1139577fb131SSeungwon Jeon /* 1140577fb131SSeungwon Jeon * Set the bus width(4 or 8) with host's support and 1141577fb131SSeungwon Jeon * switch to HS200 mode if bus width is set successfully. 1142577fb131SSeungwon Jeon */ 1143577fb131SSeungwon Jeon err = mmc_select_bus_width(card); 1144577fb131SSeungwon Jeon if (!IS_ERR_VALUE(err)) { 1145577fb131SSeungwon Jeon err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, 1146577fb131SSeungwon Jeon EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS200, 1147577fb131SSeungwon Jeon card->ext_csd.generic_cmd6_time, 1148577fb131SSeungwon Jeon true, true, true); 1149577fb131SSeungwon Jeon if (!err) 1150577fb131SSeungwon Jeon mmc_set_timing(host, MMC_TIMING_MMC_HS200); 1151577fb131SSeungwon Jeon } 1152a4924c71SGirish K S err: 1153a4924c71SGirish K S return err; 1154a4924c71SGirish K S } 1155a4924c71SGirish K S 1156a4924c71SGirish K S /* 1157577fb131SSeungwon Jeon * Activate High Speed or HS200 mode if supported. 1158577fb131SSeungwon Jeon */ 1159577fb131SSeungwon Jeon static int mmc_select_timing(struct mmc_card *card) 1160577fb131SSeungwon Jeon { 1161577fb131SSeungwon Jeon int err = 0; 1162577fb131SSeungwon Jeon 1163148bcab2SUlf Hansson if (!mmc_can_ext_csd(card)) 1164577fb131SSeungwon Jeon goto bus_speed; 1165577fb131SSeungwon Jeon 1166577fb131SSeungwon Jeon if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS200) 1167577fb131SSeungwon Jeon err = mmc_select_hs200(card); 1168577fb131SSeungwon Jeon else if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS) 1169577fb131SSeungwon Jeon err = mmc_select_hs(card); 1170577fb131SSeungwon Jeon 1171577fb131SSeungwon Jeon if (err && err != -EBADMSG) 1172577fb131SSeungwon Jeon return err; 1173577fb131SSeungwon Jeon 1174577fb131SSeungwon Jeon if (err) { 1175577fb131SSeungwon Jeon pr_warn("%s: switch to %s failed\n", 1176577fb131SSeungwon Jeon mmc_card_hs(card) ? "high-speed" : 1177577fb131SSeungwon Jeon (mmc_card_hs200(card) ? "hs200" : ""), 1178577fb131SSeungwon Jeon mmc_hostname(card->host)); 1179577fb131SSeungwon Jeon err = 0; 1180577fb131SSeungwon Jeon } 1181577fb131SSeungwon Jeon 1182577fb131SSeungwon Jeon bus_speed: 1183577fb131SSeungwon Jeon /* 1184577fb131SSeungwon Jeon * Set the bus speed to the selected bus timing. 1185577fb131SSeungwon Jeon * If timing is not selected, backward compatible is the default. 1186577fb131SSeungwon Jeon */ 1187577fb131SSeungwon Jeon mmc_set_bus_speed(card); 1188577fb131SSeungwon Jeon return err; 1189577fb131SSeungwon Jeon } 1190577fb131SSeungwon Jeon 119148d11e06SStephen Boyd const u8 tuning_blk_pattern_4bit[MMC_TUNING_BLK_PATTERN_4BIT_SIZE] = { 119248d11e06SStephen Boyd 0xff, 0x0f, 0xff, 0x00, 0xff, 0xcc, 0xc3, 0xcc, 119348d11e06SStephen Boyd 0xc3, 0x3c, 0xcc, 0xff, 0xfe, 0xff, 0xfe, 0xef, 119448d11e06SStephen Boyd 0xff, 0xdf, 0xff, 0xdd, 0xff, 0xfb, 0xff, 0xfb, 119548d11e06SStephen Boyd 0xbf, 0xff, 0x7f, 0xff, 0x77, 0xf7, 0xbd, 0xef, 119648d11e06SStephen Boyd 0xff, 0xf0, 0xff, 0xf0, 0x0f, 0xfc, 0xcc, 0x3c, 119748d11e06SStephen Boyd 0xcc, 0x33, 0xcc, 0xcf, 0xff, 0xef, 0xff, 0xee, 119848d11e06SStephen Boyd 0xff, 0xfd, 0xff, 0xfd, 0xdf, 0xff, 0xbf, 0xff, 119948d11e06SStephen Boyd 0xbb, 0xff, 0xf7, 0xff, 0xf7, 0x7f, 0x7b, 0xde, 120048d11e06SStephen Boyd }; 120148d11e06SStephen Boyd EXPORT_SYMBOL(tuning_blk_pattern_4bit); 120248d11e06SStephen Boyd 120348d11e06SStephen Boyd const u8 tuning_blk_pattern_8bit[MMC_TUNING_BLK_PATTERN_8BIT_SIZE] = { 120448d11e06SStephen Boyd 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 120548d11e06SStephen Boyd 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc, 0xcc, 120648d11e06SStephen Boyd 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff, 0xff, 120748d11e06SStephen Boyd 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee, 0xff, 120848d11e06SStephen Boyd 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd, 0xdd, 120948d11e06SStephen Boyd 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb, 121048d11e06SStephen Boyd 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff, 0xff, 121148d11e06SStephen Boyd 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee, 0xff, 121248d11e06SStephen Boyd 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 121348d11e06SStephen Boyd 0x00, 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc, 121448d11e06SStephen Boyd 0xcc, 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff, 121548d11e06SStephen Boyd 0xff, 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee, 121648d11e06SStephen Boyd 0xff, 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd, 121748d11e06SStephen Boyd 0xdd, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, 121848d11e06SStephen Boyd 0xbb, 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff, 121948d11e06SStephen Boyd 0xff, 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee, 122048d11e06SStephen Boyd }; 122148d11e06SStephen Boyd EXPORT_SYMBOL(tuning_blk_pattern_8bit); 122248d11e06SStephen Boyd 1223577fb131SSeungwon Jeon /* 1224577fb131SSeungwon Jeon * Execute tuning sequence to seek the proper bus operating 12250a5b6438SSeungwon Jeon * conditions for HS200 and HS400, which sends CMD21 to the device. 1226577fb131SSeungwon Jeon */ 1227577fb131SSeungwon Jeon static int mmc_hs200_tuning(struct mmc_card *card) 1228577fb131SSeungwon Jeon { 1229577fb131SSeungwon Jeon struct mmc_host *host = card->host; 1230577fb131SSeungwon Jeon int err = 0; 1231577fb131SSeungwon Jeon 12320a5b6438SSeungwon Jeon /* 12330a5b6438SSeungwon Jeon * Timing should be adjusted to the HS400 target 12340a5b6438SSeungwon Jeon * operation frequency for tuning process 12350a5b6438SSeungwon Jeon */ 12360a5b6438SSeungwon Jeon if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400 && 12370a5b6438SSeungwon Jeon host->ios.bus_width == MMC_BUS_WIDTH_8) 12380a5b6438SSeungwon Jeon if (host->ops->prepare_hs400_tuning) 12390a5b6438SSeungwon Jeon host->ops->prepare_hs400_tuning(host, &host->ios); 12400a5b6438SSeungwon Jeon 1241577fb131SSeungwon Jeon if (host->ops->execute_tuning) { 1242577fb131SSeungwon Jeon mmc_host_clk_hold(host); 1243577fb131SSeungwon Jeon err = host->ops->execute_tuning(host, 1244577fb131SSeungwon Jeon MMC_SEND_TUNING_BLOCK_HS200); 1245577fb131SSeungwon Jeon mmc_host_clk_release(host); 1246577fb131SSeungwon Jeon 1247577fb131SSeungwon Jeon if (err) 12484b75bffcSAndrew Gabbasov pr_err("%s: tuning execution failed\n", 1249577fb131SSeungwon Jeon mmc_hostname(host)); 1250577fb131SSeungwon Jeon } 1251577fb131SSeungwon Jeon 1252577fb131SSeungwon Jeon return err; 1253577fb131SSeungwon Jeon } 1254577fb131SSeungwon Jeon 1255577fb131SSeungwon Jeon /* 12566abaa0c9SPierre Ossman * Handle the detection and initialisation of a card. 12576abaa0c9SPierre Ossman * 12588769392bSDeepak Saxena * In the case of a resume, "oldcard" will contain the card 12596abaa0c9SPierre Ossman * we're trying to reinitialise. 12607ea239d9SPierre Ossman */ 12618c75deaeSPierre Ossman static int mmc_init_card(struct mmc_host *host, u32 ocr, 12626abaa0c9SPierre Ossman struct mmc_card *oldcard) 12637ea239d9SPierre Ossman { 12647ea239d9SPierre Ossman struct mmc_card *card; 1265577fb131SSeungwon Jeon int err; 12667ea239d9SPierre Ossman u32 cid[4]; 1267b676f039SPhilip Rakity u32 rocr; 12687ea239d9SPierre Ossman 12697ea239d9SPierre Ossman BUG_ON(!host); 1270d84075c8SPierre Ossman WARN_ON(!host->claimed); 12717ea239d9SPierre Ossman 127244669034SStefan Nilsson XK /* Set correct bus mode for MMC before attempting init */ 127344669034SStefan Nilsson XK if (!mmc_host_is_spi(host)) 127444669034SStefan Nilsson XK mmc_set_bus_mode(host, MMC_BUSMODE_OPENDRAIN); 127544669034SStefan Nilsson XK 12767ea239d9SPierre Ossman /* 12777ea239d9SPierre Ossman * Since we're changing the OCR value, we seem to 12787ea239d9SPierre Ossman * need to tell some cards to go back to the idle 12797ea239d9SPierre Ossman * state. We wait 1ms to give cards time to 12807ea239d9SPierre Ossman * respond. 1281c3805467SBalaji T K * mmc_go_idle is needed for eMMC that are asleep 12827ea239d9SPierre Ossman */ 12837ea239d9SPierre Ossman mmc_go_idle(host); 12847ea239d9SPierre Ossman 12857ea239d9SPierre Ossman /* The extra bit indicates that we support high capacity */ 1286b676f039SPhilip Rakity err = mmc_send_op_cond(host, ocr | (1 << 30), &rocr); 128717b0429dSPierre Ossman if (err) 12886abaa0c9SPierre Ossman goto err; 12897ea239d9SPierre Ossman 12907ea239d9SPierre Ossman /* 1291af517150SDavid Brownell * For SPI, enable CRC as appropriate. 1292af517150SDavid Brownell */ 1293af517150SDavid Brownell if (mmc_host_is_spi(host)) { 1294af517150SDavid Brownell err = mmc_spi_set_crc(host, use_spi_crc); 1295af517150SDavid Brownell if (err) 1296af517150SDavid Brownell goto err; 1297af517150SDavid Brownell } 1298af517150SDavid Brownell 1299af517150SDavid Brownell /* 13007ea239d9SPierre Ossman * Fetch CID from card. 13017ea239d9SPierre Ossman */ 1302af517150SDavid Brownell if (mmc_host_is_spi(host)) 1303af517150SDavid Brownell err = mmc_send_cid(host, cid); 1304af517150SDavid Brownell else 13057ea239d9SPierre Ossman err = mmc_all_send_cid(host, cid); 130617b0429dSPierre Ossman if (err) 13077ea239d9SPierre Ossman goto err; 13087ea239d9SPierre Ossman 13096abaa0c9SPierre Ossman if (oldcard) { 1310adf66a0dSPierre Ossman if (memcmp(cid, oldcard->raw_cid, sizeof(cid)) != 0) { 1311adf66a0dSPierre Ossman err = -ENOENT; 13126abaa0c9SPierre Ossman goto err; 1313adf66a0dSPierre Ossman } 13146abaa0c9SPierre Ossman 13156abaa0c9SPierre Ossman card = oldcard; 13166abaa0c9SPierre Ossman } else { 13177ea239d9SPierre Ossman /* 13187ea239d9SPierre Ossman * Allocate card structure. 13197ea239d9SPierre Ossman */ 132051ec92e2SPierre Ossman card = mmc_alloc_card(host, &mmc_type); 1321adf66a0dSPierre Ossman if (IS_ERR(card)) { 1322adf66a0dSPierre Ossman err = PTR_ERR(card); 13237ea239d9SPierre Ossman goto err; 1324adf66a0dSPierre Ossman } 13257ea239d9SPierre Ossman 132669041150SUlf Hansson card->ocr = ocr; 13277ea239d9SPierre Ossman card->type = MMC_TYPE_MMC; 13287ea239d9SPierre Ossman card->rca = 1; 13297ea239d9SPierre Ossman memcpy(card->raw_cid, cid, sizeof(card->raw_cid)); 13306abaa0c9SPierre Ossman } 13317ea239d9SPierre Ossman 13327ea239d9SPierre Ossman /* 1333af517150SDavid Brownell * For native busses: set card RCA and quit open drain mode. 13347ea239d9SPierre Ossman */ 1335af517150SDavid Brownell if (!mmc_host_is_spi(host)) { 13367ea239d9SPierre Ossman err = mmc_set_relative_addr(card); 133717b0429dSPierre Ossman if (err) 13387ea239d9SPierre Ossman goto free_card; 13397ea239d9SPierre Ossman 13407ea239d9SPierre Ossman mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL); 1341af517150SDavid Brownell } 13427ea239d9SPierre Ossman 13436abaa0c9SPierre Ossman if (!oldcard) { 13447ea239d9SPierre Ossman /* 13457ea239d9SPierre Ossman * Fetch CSD from card. 13467ea239d9SPierre Ossman */ 13477ea239d9SPierre Ossman err = mmc_send_csd(card, card->raw_csd); 134817b0429dSPierre Ossman if (err) 13497ea239d9SPierre Ossman goto free_card; 13507ea239d9SPierre Ossman 1351bd766312SPierre Ossman err = mmc_decode_csd(card); 1352adf66a0dSPierre Ossman if (err) 1353bd766312SPierre Ossman goto free_card; 1354bd766312SPierre Ossman err = mmc_decode_cid(card); 1355adf66a0dSPierre Ossman if (err) 1356bd766312SPierre Ossman goto free_card; 13576abaa0c9SPierre Ossman } 13587ea239d9SPierre Ossman 13597ea239d9SPierre Ossman /* 13603d705d14SSascha Hauer * handling only for cards supporting DSR and hosts requesting 13613d705d14SSascha Hauer * DSR configuration 13623d705d14SSascha Hauer */ 13633d705d14SSascha Hauer if (card->csd.dsr_imp && host->dsr_req) 13643d705d14SSascha Hauer mmc_set_dsr(host); 13653d705d14SSascha Hauer 13663d705d14SSascha Hauer /* 136789a73cf5SPierre Ossman * Select card, as all following commands rely on that. 13687ea239d9SPierre Ossman */ 1369af517150SDavid Brownell if (!mmc_host_is_spi(host)) { 13707ea239d9SPierre Ossman err = mmc_select_card(card); 137117b0429dSPierre Ossman if (err) 13727ea239d9SPierre Ossman goto free_card; 1373af517150SDavid Brownell } 13747ea239d9SPierre Ossman 13756abaa0c9SPierre Ossman if (!oldcard) { 1376076ec38aSUlf Hansson /* Read extended CSD. */ 1377076ec38aSUlf Hansson err = mmc_read_ext_csd(card); 137817b0429dSPierre Ossman if (err) 13797ea239d9SPierre Ossman goto free_card; 1380b676f039SPhilip Rakity 1381b676f039SPhilip Rakity /* If doing byte addressing, check if required to do sector 1382b676f039SPhilip Rakity * addressing. Handle the case of <2GB cards needing sector 1383b676f039SPhilip Rakity * addressing. See section 8.1 JEDEC Standard JED84-A441; 1384b676f039SPhilip Rakity * ocr register has bit 30 set for sector addressing. 1385b676f039SPhilip Rakity */ 1386b676f039SPhilip Rakity if (!(mmc_card_blockaddr(card)) && (rocr & (1<<30))) 1387b676f039SPhilip Rakity mmc_card_set_blockaddr(card); 1388b676f039SPhilip Rakity 1389dfe86cbaSAdrian Hunter /* Erase size depends on CSD and Extended CSD */ 1390dfe86cbaSAdrian Hunter mmc_set_erase_size(card); 13916abaa0c9SPierre Ossman } 13927ea239d9SPierre Ossman 13937ea239d9SPierre Ossman /* 1394709de99dSChuanxiao Dong * If enhanced_area_en is TRUE, host needs to enable ERASE_GRP_DEF 1395709de99dSChuanxiao Dong * bit. This bit will be lost every time after a reset or power off. 1396709de99dSChuanxiao Dong */ 139769803d4fSGrégory Soutadé if (card->ext_csd.partition_setting_completed || 139883bb24aaSAdrian Hunter (card->ext_csd.rev >= 3 && (host->caps2 & MMC_CAP2_HC_ERASE_SZ))) { 1399709de99dSChuanxiao Dong err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, 1400b23cf0bdSSeungwon Jeon EXT_CSD_ERASE_GROUP_DEF, 1, 1401b23cf0bdSSeungwon Jeon card->ext_csd.generic_cmd6_time); 1402709de99dSChuanxiao Dong 1403709de99dSChuanxiao Dong if (err && err != -EBADMSG) 1404709de99dSChuanxiao Dong goto free_card; 1405709de99dSChuanxiao Dong 1406709de99dSChuanxiao Dong if (err) { 1407709de99dSChuanxiao Dong err = 0; 1408709de99dSChuanxiao Dong /* 1409709de99dSChuanxiao Dong * Just disable enhanced area off & sz 1410709de99dSChuanxiao Dong * will try to enable ERASE_GROUP_DEF 1411709de99dSChuanxiao Dong * during next time reinit 1412709de99dSChuanxiao Dong */ 1413709de99dSChuanxiao Dong card->ext_csd.enhanced_area_offset = -EINVAL; 1414709de99dSChuanxiao Dong card->ext_csd.enhanced_area_size = -EINVAL; 1415709de99dSChuanxiao Dong } else { 1416709de99dSChuanxiao Dong card->ext_csd.erase_group_def = 1; 1417709de99dSChuanxiao Dong /* 1418709de99dSChuanxiao Dong * enable ERASE_GRP_DEF successfully. 1419709de99dSChuanxiao Dong * This will affect the erase size, so 1420709de99dSChuanxiao Dong * here need to reset erase size 1421709de99dSChuanxiao Dong */ 1422709de99dSChuanxiao Dong mmc_set_erase_size(card); 1423709de99dSChuanxiao Dong } 1424709de99dSChuanxiao Dong } 1425709de99dSChuanxiao Dong 1426709de99dSChuanxiao Dong /* 142741e2a489SPhilip Rakity * Ensure eMMC user default partition is enabled 142841e2a489SPhilip Rakity */ 1429371a689fSAndrei Warkentin if (card->ext_csd.part_config & EXT_CSD_PART_CONFIG_ACC_MASK) { 1430371a689fSAndrei Warkentin card->ext_csd.part_config &= ~EXT_CSD_PART_CONFIG_ACC_MASK; 1431371a689fSAndrei Warkentin err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONFIG, 1432371a689fSAndrei Warkentin card->ext_csd.part_config, 1433371a689fSAndrei Warkentin card->ext_csd.part_time); 1434371a689fSAndrei Warkentin if (err && err != -EBADMSG) 1435371a689fSAndrei Warkentin goto free_card; 143641e2a489SPhilip Rakity } 143741e2a489SPhilip Rakity 143841e2a489SPhilip Rakity /* 143943235679SUlf Hansson * Enable power_off_notification byte in the ext_csd register 1440bec8726aSGirish K S */ 144143235679SUlf Hansson if (card->ext_csd.rev >= 6) { 1442bec8726aSGirish K S err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, 1443bec8726aSGirish K S EXT_CSD_POWER_OFF_NOTIFICATION, 1444bec8726aSGirish K S EXT_CSD_POWER_ON, 1445bec8726aSGirish K S card->ext_csd.generic_cmd6_time); 1446bec8726aSGirish K S if (err && err != -EBADMSG) 1447bec8726aSGirish K S goto free_card; 1448bec8726aSGirish K S 144996a85d54SGirish K S /* 145096a85d54SGirish K S * The err can be -EBADMSG or 0, 145196a85d54SGirish K S * so check for success and update the flag 145296a85d54SGirish K S */ 1453bec8726aSGirish K S if (!err) 1454e6c08586SUlf Hansson card->ext_csd.power_off_notification = EXT_CSD_POWER_ON; 145596a85d54SGirish K S } 1456bec8726aSGirish K S 1457bec8726aSGirish K S /* 1458577fb131SSeungwon Jeon * Select timing interface 145989a73cf5SPierre Ossman */ 1460577fb131SSeungwon Jeon err = mmc_select_timing(card); 1461577fb131SSeungwon Jeon if (err) 146289a73cf5SPierre Ossman goto free_card; 146389a73cf5SPierre Ossman 1464a4924c71SGirish K S if (mmc_card_hs200(card)) { 1465577fb131SSeungwon Jeon err = mmc_hs200_tuning(card); 14664c4cb171SPhilip Rakity if (err) 14674b75bffcSAndrew Gabbasov goto free_card; 14680a5b6438SSeungwon Jeon 14690a5b6438SSeungwon Jeon err = mmc_select_hs400(card); 14700a5b6438SSeungwon Jeon if (err) 14714b75bffcSAndrew Gabbasov goto free_card; 1472577fb131SSeungwon Jeon } else if (mmc_card_hs(card)) { 1473577fb131SSeungwon Jeon /* Select the desired bus width optionally */ 1474577fb131SSeungwon Jeon err = mmc_select_bus_width(card); 1475577fb131SSeungwon Jeon if (!IS_ERR_VALUE(err)) { 1476577fb131SSeungwon Jeon err = mmc_select_hs_ddr(card); 1477577fb131SSeungwon Jeon if (err) 14784b75bffcSAndrew Gabbasov goto free_card; 147989a73cf5SPierre Ossman } 1480ef0b27d4SAdrian Hunter } 148189a73cf5SPierre Ossman 1482881d1c25SSeungwon Jeon /* 14832385049dSSeungwon Jeon * Choose the power class with selected bus interface 14842385049dSSeungwon Jeon */ 14852385049dSSeungwon Jeon mmc_select_powerclass(card); 14862385049dSSeungwon Jeon 14872385049dSSeungwon Jeon /* 148852d0974eSSubhash Jadavani * Enable HPI feature (if supported) 148952d0974eSSubhash Jadavani */ 149052d0974eSSubhash Jadavani if (card->ext_csd.hpi) { 149152d0974eSSubhash Jadavani err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, 149252d0974eSSubhash Jadavani EXT_CSD_HPI_MGMT, 1, 149352d0974eSSubhash Jadavani card->ext_csd.generic_cmd6_time); 149452d0974eSSubhash Jadavani if (err && err != -EBADMSG) 149552d0974eSSubhash Jadavani goto free_card; 149652d0974eSSubhash Jadavani if (err) { 14976606110dSJoe Perches pr_warn("%s: Enabling HPI failed\n", 149852d0974eSSubhash Jadavani mmc_hostname(card->host)); 149952d0974eSSubhash Jadavani err = 0; 150052d0974eSSubhash Jadavani } else 150152d0974eSSubhash Jadavani card->ext_csd.hpi_en = 1; 150252d0974eSSubhash Jadavani } 150352d0974eSSubhash Jadavani 150452d0974eSSubhash Jadavani /* 1505881d1c25SSeungwon Jeon * If cache size is higher than 0, this indicates 1506881d1c25SSeungwon Jeon * the existence of cache and it can be turned on. 1507881d1c25SSeungwon Jeon */ 15087536d3f8SUlf Hansson if (card->ext_csd.cache_size > 0) { 1509881d1c25SSeungwon Jeon err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, 15108bc0678bSSeungwon Jeon EXT_CSD_CACHE_CTRL, 1, 15118bc0678bSSeungwon Jeon card->ext_csd.generic_cmd6_time); 1512881d1c25SSeungwon Jeon if (err && err != -EBADMSG) 1513881d1c25SSeungwon Jeon goto free_card; 1514881d1c25SSeungwon Jeon 1515881d1c25SSeungwon Jeon /* 1516881d1c25SSeungwon Jeon * Only if no error, cache is turned on successfully. 1517881d1c25SSeungwon Jeon */ 15188bc0678bSSeungwon Jeon if (err) { 15196606110dSJoe Perches pr_warn("%s: Cache is supported, but failed to turn on (%d)\n", 15208bc0678bSSeungwon Jeon mmc_hostname(card->host), err); 15218bc0678bSSeungwon Jeon card->ext_csd.cache_ctrl = 0; 15228bc0678bSSeungwon Jeon err = 0; 15238bc0678bSSeungwon Jeon } else { 15248bc0678bSSeungwon Jeon card->ext_csd.cache_ctrl = 1; 15258bc0678bSSeungwon Jeon } 1526881d1c25SSeungwon Jeon } 1527881d1c25SSeungwon Jeon 1528abd9ac14SSeungwon Jeon /* 1529abd9ac14SSeungwon Jeon * The mandatory minimum values are defined for packed command. 1530abd9ac14SSeungwon Jeon * read: 5, write: 3 1531abd9ac14SSeungwon Jeon */ 1532abd9ac14SSeungwon Jeon if (card->ext_csd.max_packed_writes >= 3 && 1533abd9ac14SSeungwon Jeon card->ext_csd.max_packed_reads >= 5 && 1534abd9ac14SSeungwon Jeon host->caps2 & MMC_CAP2_PACKED_CMD) { 1535abd9ac14SSeungwon Jeon err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, 1536abd9ac14SSeungwon Jeon EXT_CSD_EXP_EVENTS_CTRL, 1537abd9ac14SSeungwon Jeon EXT_CSD_PACKED_EVENT_EN, 1538abd9ac14SSeungwon Jeon card->ext_csd.generic_cmd6_time); 1539abd9ac14SSeungwon Jeon if (err && err != -EBADMSG) 1540abd9ac14SSeungwon Jeon goto free_card; 1541abd9ac14SSeungwon Jeon if (err) { 1542abd9ac14SSeungwon Jeon pr_warn("%s: Enabling packed event failed\n", 1543abd9ac14SSeungwon Jeon mmc_hostname(card->host)); 1544abd9ac14SSeungwon Jeon card->ext_csd.packed_event_en = 0; 1545abd9ac14SSeungwon Jeon err = 0; 1546abd9ac14SSeungwon Jeon } else { 1547abd9ac14SSeungwon Jeon card->ext_csd.packed_event_en = 1; 1548abd9ac14SSeungwon Jeon } 1549abd9ac14SSeungwon Jeon } 1550abd9ac14SSeungwon Jeon 15516abaa0c9SPierre Ossman if (!oldcard) 15527ea239d9SPierre Ossman host->card = card; 15537ea239d9SPierre Ossman 155417b0429dSPierre Ossman return 0; 15556abaa0c9SPierre Ossman 15566abaa0c9SPierre Ossman free_card: 15576abaa0c9SPierre Ossman if (!oldcard) 15586abaa0c9SPierre Ossman mmc_remove_card(card); 15596abaa0c9SPierre Ossman err: 1560adf66a0dSPierre Ossman return err; 15616abaa0c9SPierre Ossman } 15626abaa0c9SPierre Ossman 156307a68216SUlf Hansson static int mmc_can_sleep(struct mmc_card *card) 156407a68216SUlf Hansson { 156507a68216SUlf Hansson return (card && card->ext_csd.rev >= 3); 156607a68216SUlf Hansson } 156707a68216SUlf Hansson 156807a68216SUlf Hansson static int mmc_sleep(struct mmc_host *host) 156907a68216SUlf Hansson { 157007a68216SUlf Hansson struct mmc_command cmd = {0}; 157107a68216SUlf Hansson struct mmc_card *card = host->card; 1572cb962e04SUlf Hansson unsigned int timeout_ms = DIV_ROUND_UP(card->ext_csd.sa_timeout, 10000); 157307a68216SUlf Hansson int err; 157407a68216SUlf Hansson 157507a68216SUlf Hansson err = mmc_deselect_cards(host); 157607a68216SUlf Hansson if (err) 157707a68216SUlf Hansson return err; 157807a68216SUlf Hansson 157907a68216SUlf Hansson cmd.opcode = MMC_SLEEP_AWAKE; 158007a68216SUlf Hansson cmd.arg = card->rca << 16; 158107a68216SUlf Hansson cmd.arg |= 1 << 15; 158207a68216SUlf Hansson 1583cb962e04SUlf Hansson /* 1584cb962e04SUlf Hansson * If the max_busy_timeout of the host is specified, validate it against 1585cb962e04SUlf Hansson * the sleep cmd timeout. A failure means we need to prevent the host 1586cb962e04SUlf Hansson * from doing hw busy detection, which is done by converting to a R1 1587cb962e04SUlf Hansson * response instead of a R1B. 1588cb962e04SUlf Hansson */ 1589cb962e04SUlf Hansson if (host->max_busy_timeout && (timeout_ms > host->max_busy_timeout)) { 1590cb962e04SUlf Hansson cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; 1591cb962e04SUlf Hansson } else { 159207a68216SUlf Hansson cmd.flags = MMC_RSP_R1B | MMC_CMD_AC; 1593cb962e04SUlf Hansson cmd.busy_timeout = timeout_ms; 1594cb962e04SUlf Hansson } 1595cb962e04SUlf Hansson 159607a68216SUlf Hansson err = mmc_wait_for_cmd(host, &cmd, 0); 159707a68216SUlf Hansson if (err) 159807a68216SUlf Hansson return err; 159907a68216SUlf Hansson 160007a68216SUlf Hansson /* 160107a68216SUlf Hansson * If the host does not wait while the card signals busy, then we will 160207a68216SUlf Hansson * will have to wait the sleep/awake timeout. Note, we cannot use the 160307a68216SUlf Hansson * SEND_STATUS command to poll the status because that command (and most 160407a68216SUlf Hansson * others) is invalid while the card sleeps. 160507a68216SUlf Hansson */ 1606cb962e04SUlf Hansson if (!cmd.busy_timeout || !(host->caps & MMC_CAP_WAIT_WHILE_BUSY)) 1607cb962e04SUlf Hansson mmc_delay(timeout_ms); 160807a68216SUlf Hansson 160907a68216SUlf Hansson return err; 161007a68216SUlf Hansson } 161107a68216SUlf Hansson 1612e6c08586SUlf Hansson static int mmc_can_poweroff_notify(const struct mmc_card *card) 1613e6c08586SUlf Hansson { 1614e6c08586SUlf Hansson return card && 1615e6c08586SUlf Hansson mmc_card_mmc(card) && 1616e6c08586SUlf Hansson (card->ext_csd.power_off_notification == EXT_CSD_POWER_ON); 1617e6c08586SUlf Hansson } 1618e6c08586SUlf Hansson 1619e6c08586SUlf Hansson static int mmc_poweroff_notify(struct mmc_card *card, unsigned int notify_type) 1620e6c08586SUlf Hansson { 1621e6c08586SUlf Hansson unsigned int timeout = card->ext_csd.generic_cmd6_time; 1622e6c08586SUlf Hansson int err; 1623e6c08586SUlf Hansson 1624e6c08586SUlf Hansson /* Use EXT_CSD_POWER_OFF_SHORT as default notification type. */ 1625e6c08586SUlf Hansson if (notify_type == EXT_CSD_POWER_OFF_LONG) 1626e6c08586SUlf Hansson timeout = card->ext_csd.power_off_longtime; 1627e6c08586SUlf Hansson 1628878e200bSUlf Hansson err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, 1629e6c08586SUlf Hansson EXT_CSD_POWER_OFF_NOTIFICATION, 16304509f847SUlf Hansson notify_type, timeout, true, false, false); 1631e6c08586SUlf Hansson if (err) 1632e6c08586SUlf Hansson pr_err("%s: Power Off Notification timed out, %u\n", 1633e6c08586SUlf Hansson mmc_hostname(card->host), timeout); 1634e6c08586SUlf Hansson 1635e6c08586SUlf Hansson /* Disable the power off notification after the switch operation. */ 1636e6c08586SUlf Hansson card->ext_csd.power_off_notification = EXT_CSD_NO_POWER_NOTIFICATION; 1637e6c08586SUlf Hansson 1638e6c08586SUlf Hansson return err; 1639e6c08586SUlf Hansson } 1640e6c08586SUlf Hansson 16416abaa0c9SPierre Ossman /* 16426abaa0c9SPierre Ossman * Host is being removed. Free up the current card. 16436abaa0c9SPierre Ossman */ 16446abaa0c9SPierre Ossman static void mmc_remove(struct mmc_host *host) 16456abaa0c9SPierre Ossman { 16466abaa0c9SPierre Ossman BUG_ON(!host); 16476abaa0c9SPierre Ossman BUG_ON(!host->card); 16486abaa0c9SPierre Ossman 16496abaa0c9SPierre Ossman mmc_remove_card(host->card); 16506abaa0c9SPierre Ossman host->card = NULL; 16516abaa0c9SPierre Ossman } 16526abaa0c9SPierre Ossman 16536abaa0c9SPierre Ossman /* 1654d3049504SAdrian Hunter * Card detection - card is alive. 1655d3049504SAdrian Hunter */ 1656d3049504SAdrian Hunter static int mmc_alive(struct mmc_host *host) 1657d3049504SAdrian Hunter { 1658d3049504SAdrian Hunter return mmc_send_status(host->card, NULL); 1659d3049504SAdrian Hunter } 1660d3049504SAdrian Hunter 1661d3049504SAdrian Hunter /* 16626abaa0c9SPierre Ossman * Card detection callback from host. 16636abaa0c9SPierre Ossman */ 16646abaa0c9SPierre Ossman static void mmc_detect(struct mmc_host *host) 16656abaa0c9SPierre Ossman { 16666abaa0c9SPierre Ossman int err; 16676abaa0c9SPierre Ossman 16686abaa0c9SPierre Ossman BUG_ON(!host); 16696abaa0c9SPierre Ossman BUG_ON(!host->card); 16706abaa0c9SPierre Ossman 1671e94cfef6SUlf Hansson mmc_get_card(host->card); 16726abaa0c9SPierre Ossman 16736abaa0c9SPierre Ossman /* 16746abaa0c9SPierre Ossman * Just check if our card has been removed. 16756abaa0c9SPierre Ossman */ 1676d3049504SAdrian Hunter err = _mmc_detect_card_removed(host); 16776abaa0c9SPierre Ossman 1678e94cfef6SUlf Hansson mmc_put_card(host->card); 16797ea239d9SPierre Ossman 168017b0429dSPierre Ossman if (err) { 16814101c16aSPierre Ossman mmc_remove(host); 16826abaa0c9SPierre Ossman 16836abaa0c9SPierre Ossman mmc_claim_host(host); 16846abaa0c9SPierre Ossman mmc_detach_bus(host); 16857f7e4129SUlf Hansson mmc_power_off(host); 16866abaa0c9SPierre Ossman mmc_release_host(host); 16876abaa0c9SPierre Ossman } 16886abaa0c9SPierre Ossman } 16896abaa0c9SPierre Ossman 169003d071fcSUlf Hansson static int _mmc_suspend(struct mmc_host *host, bool is_suspend) 16916abaa0c9SPierre Ossman { 1692c3805467SBalaji T K int err = 0; 169303d071fcSUlf Hansson unsigned int notify_type = is_suspend ? EXT_CSD_POWER_OFF_SHORT : 169403d071fcSUlf Hansson EXT_CSD_POWER_OFF_LONG; 1695c3805467SBalaji T K 16966abaa0c9SPierre Ossman BUG_ON(!host); 16976abaa0c9SPierre Ossman BUG_ON(!host->card); 16986abaa0c9SPierre Ossman 16996abaa0c9SPierre Ossman mmc_claim_host(host); 1700881d926dSMaya Erez 17019ec775f7SUlf Hansson if (mmc_card_suspended(host->card)) 17029ec775f7SUlf Hansson goto out; 17039ec775f7SUlf Hansson 170439b9431bSUlf Hansson if (mmc_card_doing_bkops(host->card)) { 170539b9431bSUlf Hansson err = mmc_stop_bkops(host->card); 170639b9431bSUlf Hansson if (err) 170739b9431bSUlf Hansson goto out; 170839b9431bSUlf Hansson } 170939b9431bSUlf Hansson 171010e5d965SUlf Hansson err = mmc_flush_cache(host->card); 1711881d926dSMaya Erez if (err) 1712881d926dSMaya Erez goto out; 1713881d926dSMaya Erez 171443235679SUlf Hansson if (mmc_can_poweroff_notify(host->card) && 171553275c21SUlf Hansson ((host->caps2 & MMC_CAP2_FULL_PWR_CYCLE) || !is_suspend)) 171603d071fcSUlf Hansson err = mmc_poweroff_notify(host->card, notify_type); 171707a68216SUlf Hansson else if (mmc_can_sleep(host->card)) 171807a68216SUlf Hansson err = mmc_sleep(host); 1719e6c08586SUlf Hansson else if (!mmc_host_is_spi(host)) 172085e727edSJaehoon Chung err = mmc_deselect_cards(host); 172195cdfb72SNicolas Pitre 17229ec775f7SUlf Hansson if (!err) { 172374590263SUlf Hansson mmc_power_off(host); 17249ec775f7SUlf Hansson mmc_card_set_suspended(host->card); 17259ec775f7SUlf Hansson } 1726881d926dSMaya Erez out: 1727881d926dSMaya Erez mmc_release_host(host); 1728c3805467SBalaji T K return err; 17296abaa0c9SPierre Ossman } 17306abaa0c9SPierre Ossman 17316abaa0c9SPierre Ossman /* 17320cb403a2SUlf Hansson * Suspend callback 173303d071fcSUlf Hansson */ 173403d071fcSUlf Hansson static int mmc_suspend(struct mmc_host *host) 173503d071fcSUlf Hansson { 17360cb403a2SUlf Hansson int err; 17370cb403a2SUlf Hansson 17380cb403a2SUlf Hansson err = _mmc_suspend(host, true); 17390cb403a2SUlf Hansson if (!err) { 17400cb403a2SUlf Hansson pm_runtime_disable(&host->card->dev); 17410cb403a2SUlf Hansson pm_runtime_set_suspended(&host->card->dev); 17420cb403a2SUlf Hansson } 17430cb403a2SUlf Hansson 17440cb403a2SUlf Hansson return err; 174503d071fcSUlf Hansson } 174603d071fcSUlf Hansson 174703d071fcSUlf Hansson /* 17486abaa0c9SPierre Ossman * This function tries to determine if the same card is still present 17496abaa0c9SPierre Ossman * and, if so, restore all state to it. 17506abaa0c9SPierre Ossman */ 17510cb403a2SUlf Hansson static int _mmc_resume(struct mmc_host *host) 17526abaa0c9SPierre Ossman { 17539ec775f7SUlf Hansson int err = 0; 17546abaa0c9SPierre Ossman 17556abaa0c9SPierre Ossman BUG_ON(!host); 17566abaa0c9SPierre Ossman BUG_ON(!host->card); 17576abaa0c9SPierre Ossman 17586abaa0c9SPierre Ossman mmc_claim_host(host); 17599ec775f7SUlf Hansson 17609ec775f7SUlf Hansson if (!mmc_card_suspended(host->card)) 17619ec775f7SUlf Hansson goto out; 17629ec775f7SUlf Hansson 176369041150SUlf Hansson mmc_power_up(host, host->card->ocr); 176469041150SUlf Hansson err = mmc_init_card(host, host->card->ocr, host->card); 17659ec775f7SUlf Hansson mmc_card_clr_suspended(host->card); 17662986d0bfSPierre Ossman 17679ec775f7SUlf Hansson out: 17689ec775f7SUlf Hansson mmc_release_host(host); 176995cdfb72SNicolas Pitre return err; 17706abaa0c9SPierre Ossman } 17716abaa0c9SPierre Ossman 17729ec775f7SUlf Hansson /* 17739ec775f7SUlf Hansson * Shutdown callback 17749ec775f7SUlf Hansson */ 17759ec775f7SUlf Hansson static int mmc_shutdown(struct mmc_host *host) 17769ec775f7SUlf Hansson { 17779ec775f7SUlf Hansson int err = 0; 17789ec775f7SUlf Hansson 17799ec775f7SUlf Hansson /* 17809ec775f7SUlf Hansson * In a specific case for poweroff notify, we need to resume the card 17819ec775f7SUlf Hansson * before we can shutdown it properly. 17829ec775f7SUlf Hansson */ 17839ec775f7SUlf Hansson if (mmc_can_poweroff_notify(host->card) && 17849ec775f7SUlf Hansson !(host->caps2 & MMC_CAP2_FULL_PWR_CYCLE)) 17850cb403a2SUlf Hansson err = _mmc_resume(host); 17869ec775f7SUlf Hansson 17879ec775f7SUlf Hansson if (!err) 17889ec775f7SUlf Hansson err = _mmc_suspend(host, false); 17899ec775f7SUlf Hansson 17909ec775f7SUlf Hansson return err; 17919ec775f7SUlf Hansson } 1792c4d770d7SUlf Hansson 1793c4d770d7SUlf Hansson /* 17940cb403a2SUlf Hansson * Callback for resume. 17950cb403a2SUlf Hansson */ 17960cb403a2SUlf Hansson static int mmc_resume(struct mmc_host *host) 17970cb403a2SUlf Hansson { 17984d223782SUlf Hansson int err = 0; 17990cb403a2SUlf Hansson 18004d223782SUlf Hansson if (!(host->caps & MMC_CAP_RUNTIME_RESUME)) { 18010cb403a2SUlf Hansson err = _mmc_resume(host); 18020cb403a2SUlf Hansson pm_runtime_set_active(&host->card->dev); 18030cb403a2SUlf Hansson pm_runtime_mark_last_busy(&host->card->dev); 18044d223782SUlf Hansson } 18050cb403a2SUlf Hansson pm_runtime_enable(&host->card->dev); 18060cb403a2SUlf Hansson 18070cb403a2SUlf Hansson return err; 18080cb403a2SUlf Hansson } 18090cb403a2SUlf Hansson 18100cb403a2SUlf Hansson /* 1811c4d770d7SUlf Hansson * Callback for runtime_suspend. 1812c4d770d7SUlf Hansson */ 1813c4d770d7SUlf Hansson static int mmc_runtime_suspend(struct mmc_host *host) 1814c4d770d7SUlf Hansson { 1815c4d770d7SUlf Hansson int err; 1816c4d770d7SUlf Hansson 1817c4d770d7SUlf Hansson if (!(host->caps & MMC_CAP_AGGRESSIVE_PM)) 1818c4d770d7SUlf Hansson return 0; 1819c4d770d7SUlf Hansson 18200cb403a2SUlf Hansson err = _mmc_suspend(host, true); 18210cc81a8cSUlf Hansson if (err) 1822c4d770d7SUlf Hansson pr_err("%s: error %d doing aggessive suspend\n", 1823c4d770d7SUlf Hansson mmc_hostname(host), err); 1824c4d770d7SUlf Hansson 1825c4d770d7SUlf Hansson return err; 1826c4d770d7SUlf Hansson } 1827c4d770d7SUlf Hansson 1828c4d770d7SUlf Hansson /* 1829c4d770d7SUlf Hansson * Callback for runtime_resume. 1830c4d770d7SUlf Hansson */ 1831c4d770d7SUlf Hansson static int mmc_runtime_resume(struct mmc_host *host) 1832c4d770d7SUlf Hansson { 1833c4d770d7SUlf Hansson int err; 1834c4d770d7SUlf Hansson 18354d223782SUlf Hansson if (!(host->caps & (MMC_CAP_AGGRESSIVE_PM | MMC_CAP_RUNTIME_RESUME))) 1836c4d770d7SUlf Hansson return 0; 1837c4d770d7SUlf Hansson 18380cb403a2SUlf Hansson err = _mmc_resume(host); 1839c4d770d7SUlf Hansson if (err) 1840c4d770d7SUlf Hansson pr_err("%s: error %d doing aggessive resume\n", 1841c4d770d7SUlf Hansson mmc_hostname(host), err); 1842c4d770d7SUlf Hansson 1843c4d770d7SUlf Hansson return 0; 1844c4d770d7SUlf Hansson } 1845c4d770d7SUlf Hansson 184612ae637fSOhad Ben-Cohen static int mmc_power_restore(struct mmc_host *host) 1847eae1aeeeSAdrian Hunter { 184812ae637fSOhad Ben-Cohen int ret; 184912ae637fSOhad Ben-Cohen 1850eae1aeeeSAdrian Hunter mmc_claim_host(host); 185169041150SUlf Hansson ret = mmc_init_card(host, host->card->ocr, host->card); 1852eae1aeeeSAdrian Hunter mmc_release_host(host); 185312ae637fSOhad Ben-Cohen 185412ae637fSOhad Ben-Cohen return ret; 1855eae1aeeeSAdrian Hunter } 1856eae1aeeeSAdrian Hunter 18579feae246SAdrian Hunter static const struct mmc_bus_ops mmc_ops = { 18589feae246SAdrian Hunter .remove = mmc_remove, 18599feae246SAdrian Hunter .detect = mmc_detect, 18609feae246SAdrian Hunter .suspend = mmc_suspend, 18619feae246SAdrian Hunter .resume = mmc_resume, 1862c4d770d7SUlf Hansson .runtime_suspend = mmc_runtime_suspend, 1863c4d770d7SUlf Hansson .runtime_resume = mmc_runtime_resume, 1864eae1aeeeSAdrian Hunter .power_restore = mmc_power_restore, 1865d3049504SAdrian Hunter .alive = mmc_alive, 1866486fdbbcSUlf Hansson .shutdown = mmc_shutdown, 18679feae246SAdrian Hunter }; 18689feae246SAdrian Hunter 18696abaa0c9SPierre Ossman /* 18706abaa0c9SPierre Ossman * Starting point for MMC card init. 18716abaa0c9SPierre Ossman */ 1872807e8e40SAndy Ross int mmc_attach_mmc(struct mmc_host *host) 18736abaa0c9SPierre Ossman { 18746abaa0c9SPierre Ossman int err; 187569041150SUlf Hansson u32 ocr, rocr; 18766abaa0c9SPierre Ossman 18776abaa0c9SPierre Ossman BUG_ON(!host); 1878d84075c8SPierre Ossman WARN_ON(!host->claimed); 18796abaa0c9SPierre Ossman 188044669034SStefan Nilsson XK /* Set correct bus mode for MMC before attempting attach */ 188144669034SStefan Nilsson XK if (!mmc_host_is_spi(host)) 188244669034SStefan Nilsson XK mmc_set_bus_mode(host, MMC_BUSMODE_OPENDRAIN); 188344669034SStefan Nilsson XK 1884807e8e40SAndy Ross err = mmc_send_op_cond(host, 0, &ocr); 1885807e8e40SAndy Ross if (err) 1886807e8e40SAndy Ross return err; 1887807e8e40SAndy Ross 18882501c917SUlf Hansson mmc_attach_bus(host, &mmc_ops); 18898f230f45STakashi Iwai if (host->ocr_avail_mmc) 18908f230f45STakashi Iwai host->ocr_avail = host->ocr_avail_mmc; 18916abaa0c9SPierre Ossman 18926abaa0c9SPierre Ossman /* 1893af517150SDavid Brownell * We need to get OCR a different way for SPI. 1894af517150SDavid Brownell */ 1895af517150SDavid Brownell if (mmc_host_is_spi(host)) { 1896af517150SDavid Brownell err = mmc_spi_read_ocr(host, 1, &ocr); 1897af517150SDavid Brownell if (err) 1898af517150SDavid Brownell goto err; 1899af517150SDavid Brownell } 1900af517150SDavid Brownell 190169041150SUlf Hansson rocr = mmc_select_voltage(host, ocr); 19026abaa0c9SPierre Ossman 19036abaa0c9SPierre Ossman /* 19046abaa0c9SPierre Ossman * Can we support the voltage of the card? 19056abaa0c9SPierre Ossman */ 190669041150SUlf Hansson if (!rocr) { 1907109b5bedSPierre Ossman err = -EINVAL; 19086abaa0c9SPierre Ossman goto err; 1909109b5bedSPierre Ossman } 19106abaa0c9SPierre Ossman 19116abaa0c9SPierre Ossman /* 19126abaa0c9SPierre Ossman * Detect and init the card. 19136abaa0c9SPierre Ossman */ 191469041150SUlf Hansson err = mmc_init_card(host, rocr, NULL); 191517b0429dSPierre Ossman if (err) 19166abaa0c9SPierre Ossman goto err; 19176abaa0c9SPierre Ossman 19186abaa0c9SPierre Ossman mmc_release_host(host); 19194101c16aSPierre Ossman err = mmc_add_card(host->card); 1920807e8e40SAndy Ross mmc_claim_host(host); 19217ea239d9SPierre Ossman if (err) 19222986d0bfSPierre Ossman goto remove_card; 19237ea239d9SPierre Ossman 19247ea239d9SPierre Ossman return 0; 19257ea239d9SPierre Ossman 19262986d0bfSPierre Ossman remove_card: 1927807e8e40SAndy Ross mmc_release_host(host); 19286abaa0c9SPierre Ossman mmc_remove_card(host->card); 19292986d0bfSPierre Ossman mmc_claim_host(host); 1930807e8e40SAndy Ross host->card = NULL; 19317ea239d9SPierre Ossman err: 19327ea239d9SPierre Ossman mmc_detach_bus(host); 19337ea239d9SPierre Ossman 1934a3c76eb9SGirish K S pr_err("%s: error %d whilst initialising MMC card\n", 1935109b5bedSPierre Ossman mmc_hostname(host), err); 1936109b5bedSPierre Ossman 1937adf66a0dSPierre Ossman return err; 19387ea239d9SPierre Ossman } 1939