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 19108ee80ccSPhilip Rakity *new_ext_csd = NULL; 1927ea239d9SPierre Ossman 1937ea239d9SPierre Ossman if (card->csd.mmca_vsn < CSD_SPEC_VER_4) 19417b0429dSPierre Ossman return 0; 1957ea239d9SPierre Ossman 1967ea239d9SPierre Ossman /* 1977ea239d9SPierre Ossman * As the ext_csd is so large and mostly unused, we don't store the 1987ea239d9SPierre Ossman * raw block in mmc_card. 1997ea239d9SPierre Ossman */ 2007ea239d9SPierre Ossman ext_csd = kmalloc(512, GFP_KERNEL); 2017ea239d9SPierre Ossman if (!ext_csd) { 202a3c76eb9SGirish K S pr_err("%s: could not allocate a buffer to " 203adf66a0dSPierre Ossman "receive the ext_csd.\n", mmc_hostname(card->host)); 20417b0429dSPierre Ossman return -ENOMEM; 2057ea239d9SPierre Ossman } 2067ea239d9SPierre Ossman 2077ea239d9SPierre Ossman err = mmc_send_ext_csd(card, ext_csd); 20817b0429dSPierre Ossman if (err) { 20908ee80ccSPhilip Rakity kfree(ext_csd); 21008ee80ccSPhilip Rakity *new_ext_csd = NULL; 21108ee80ccSPhilip Rakity 212d08ebeddSWolfgang Muees /* If the host or the card can't do the switch, 213d08ebeddSWolfgang Muees * fail more gracefully. */ 214d08ebeddSWolfgang Muees if ((err != -EINVAL) 215d08ebeddSWolfgang Muees && (err != -ENOSYS) 216d08ebeddSWolfgang Muees && (err != -EFAULT)) 21708ee80ccSPhilip Rakity return err; 218adf66a0dSPierre Ossman 219adf66a0dSPierre Ossman /* 2207ea239d9SPierre Ossman * High capacity cards should have this "magic" size 2217ea239d9SPierre Ossman * stored in their CSD. 2227ea239d9SPierre Ossman */ 2237ea239d9SPierre Ossman if (card->csd.capacity == (4096 * 512)) { 224a3c76eb9SGirish K S pr_err("%s: unable to read EXT_CSD " 2257ea239d9SPierre Ossman "on a possible high capacity card. " 2267ea239d9SPierre Ossman "Card will be ignored.\n", 2277ea239d9SPierre Ossman mmc_hostname(card->host)); 2287ea239d9SPierre Ossman } else { 2296606110dSJoe Perches pr_warn("%s: unable to read EXT_CSD, performance might suffer\n", 2307ea239d9SPierre Ossman mmc_hostname(card->host)); 23117b0429dSPierre Ossman err = 0; 2327ea239d9SPierre Ossman } 23308ee80ccSPhilip Rakity } else 23408ee80ccSPhilip Rakity *new_ext_csd = ext_csd; 235adf66a0dSPierre Ossman 23608ee80ccSPhilip Rakity return err; 2377ea239d9SPierre Ossman } 2387ea239d9SPierre Ossman 23996cf5f02SSeungwon Jeon static void mmc_select_card_type(struct mmc_card *card) 24096cf5f02SSeungwon Jeon { 24196cf5f02SSeungwon Jeon struct mmc_host *host = card->host; 2420a5b6438SSeungwon Jeon u8 card_type = card->ext_csd.raw_card_type; 2435f1a4dd0SLee Jones u32 caps = host->caps, caps2 = host->caps2; 244577fb131SSeungwon Jeon unsigned int hs_max_dtr = 0, hs200_max_dtr = 0; 2452415c0efSSeungwon Jeon unsigned int avail_type = 0; 24696cf5f02SSeungwon Jeon 24796cf5f02SSeungwon Jeon if (caps & MMC_CAP_MMC_HIGHSPEED && 2482415c0efSSeungwon Jeon card_type & EXT_CSD_CARD_TYPE_HS_26) { 2492415c0efSSeungwon Jeon hs_max_dtr = MMC_HIGH_26_MAX_DTR; 2502415c0efSSeungwon Jeon avail_type |= EXT_CSD_CARD_TYPE_HS_26; 2512415c0efSSeungwon Jeon } 2522415c0efSSeungwon Jeon 2532415c0efSSeungwon Jeon if (caps & MMC_CAP_MMC_HIGHSPEED && 2542415c0efSSeungwon Jeon card_type & EXT_CSD_CARD_TYPE_HS_52) { 25596cf5f02SSeungwon Jeon hs_max_dtr = MMC_HIGH_52_MAX_DTR; 2562415c0efSSeungwon Jeon avail_type |= EXT_CSD_CARD_TYPE_HS_52; 2572415c0efSSeungwon Jeon } 25896cf5f02SSeungwon Jeon 2592415c0efSSeungwon Jeon if (caps & MMC_CAP_1_8V_DDR && 2602415c0efSSeungwon Jeon card_type & EXT_CSD_CARD_TYPE_DDR_1_8V) { 26196cf5f02SSeungwon Jeon hs_max_dtr = MMC_HIGH_DDR_MAX_DTR; 2622415c0efSSeungwon Jeon avail_type |= EXT_CSD_CARD_TYPE_DDR_1_8V; 2632415c0efSSeungwon Jeon } 26496cf5f02SSeungwon Jeon 2652415c0efSSeungwon Jeon if (caps & MMC_CAP_1_2V_DDR && 2662415c0efSSeungwon Jeon card_type & EXT_CSD_CARD_TYPE_DDR_1_2V) { 2672415c0efSSeungwon Jeon hs_max_dtr = MMC_HIGH_DDR_MAX_DTR; 2682415c0efSSeungwon Jeon avail_type |= EXT_CSD_CARD_TYPE_DDR_1_2V; 2692415c0efSSeungwon Jeon } 2702415c0efSSeungwon Jeon 2712415c0efSSeungwon Jeon if (caps2 & MMC_CAP2_HS200_1_8V_SDR && 2722415c0efSSeungwon Jeon card_type & EXT_CSD_CARD_TYPE_HS200_1_8V) { 273577fb131SSeungwon Jeon hs200_max_dtr = MMC_HS200_MAX_DTR; 2742415c0efSSeungwon Jeon avail_type |= EXT_CSD_CARD_TYPE_HS200_1_8V; 2752415c0efSSeungwon Jeon } 2762415c0efSSeungwon Jeon 2772415c0efSSeungwon Jeon if (caps2 & MMC_CAP2_HS200_1_2V_SDR && 2782415c0efSSeungwon Jeon card_type & EXT_CSD_CARD_TYPE_HS200_1_2V) { 279577fb131SSeungwon Jeon hs200_max_dtr = MMC_HS200_MAX_DTR; 2802415c0efSSeungwon Jeon avail_type |= EXT_CSD_CARD_TYPE_HS200_1_2V; 2812415c0efSSeungwon Jeon } 28296cf5f02SSeungwon Jeon 2830a5b6438SSeungwon Jeon if (caps2 & MMC_CAP2_HS400_1_8V && 2840a5b6438SSeungwon Jeon card_type & EXT_CSD_CARD_TYPE_HS400_1_8V) { 2850a5b6438SSeungwon Jeon hs200_max_dtr = MMC_HS200_MAX_DTR; 2860a5b6438SSeungwon Jeon avail_type |= EXT_CSD_CARD_TYPE_HS400_1_8V; 2870a5b6438SSeungwon Jeon } 2880a5b6438SSeungwon Jeon 2890a5b6438SSeungwon Jeon if (caps2 & MMC_CAP2_HS400_1_2V && 2900a5b6438SSeungwon Jeon card_type & EXT_CSD_CARD_TYPE_HS400_1_2V) { 2910a5b6438SSeungwon Jeon hs200_max_dtr = MMC_HS200_MAX_DTR; 2920a5b6438SSeungwon Jeon avail_type |= EXT_CSD_CARD_TYPE_HS400_1_2V; 2930a5b6438SSeungwon Jeon } 2940a5b6438SSeungwon Jeon 29596cf5f02SSeungwon Jeon card->ext_csd.hs_max_dtr = hs_max_dtr; 296577fb131SSeungwon Jeon card->ext_csd.hs200_max_dtr = hs200_max_dtr; 2972415c0efSSeungwon Jeon card->mmc_avail_type = avail_type; 29896cf5f02SSeungwon Jeon } 29996cf5f02SSeungwon Jeon 300b4493eeaSGrégory Soutadé static void mmc_manage_enhanced_area(struct mmc_card *card, u8 *ext_csd) 301b4493eeaSGrégory Soutadé { 302994324bbSGrégory Soutadé u8 hc_erase_grp_sz, hc_wp_grp_sz; 303994324bbSGrégory Soutadé 304994324bbSGrégory Soutadé /* 305994324bbSGrégory Soutadé * Disable these attributes by default 306994324bbSGrégory Soutadé */ 307994324bbSGrégory Soutadé card->ext_csd.enhanced_area_offset = -EINVAL; 308994324bbSGrégory Soutadé card->ext_csd.enhanced_area_size = -EINVAL; 309b4493eeaSGrégory Soutadé 310b4493eeaSGrégory Soutadé /* 311b4493eeaSGrégory Soutadé * Enhanced area feature support -- check whether the eMMC 312b4493eeaSGrégory Soutadé * card has the Enhanced area enabled. If so, export enhanced 313b4493eeaSGrégory Soutadé * area offset and size to user by adding sysfs interface. 314b4493eeaSGrégory Soutadé */ 315b4493eeaSGrégory Soutadé if ((ext_csd[EXT_CSD_PARTITION_SUPPORT] & 0x2) && 316b4493eeaSGrégory Soutadé (ext_csd[EXT_CSD_PARTITION_ATTRIBUTE] & 0x1)) { 317994324bbSGrégory Soutadé if (card->ext_csd.partition_setting_completed) { 318b4493eeaSGrégory Soutadé hc_erase_grp_sz = 319b4493eeaSGrégory Soutadé ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]; 320b4493eeaSGrégory Soutadé hc_wp_grp_sz = 321b4493eeaSGrégory Soutadé ext_csd[EXT_CSD_HC_WP_GRP_SIZE]; 322b4493eeaSGrégory Soutadé 323b4493eeaSGrégory Soutadé /* 324b4493eeaSGrégory Soutadé * calculate the enhanced data area offset, in bytes 325b4493eeaSGrégory Soutadé */ 326b4493eeaSGrégory Soutadé card->ext_csd.enhanced_area_offset = 327b4493eeaSGrégory Soutadé (ext_csd[139] << 24) + (ext_csd[138] << 16) + 328b4493eeaSGrégory Soutadé (ext_csd[137] << 8) + ext_csd[136]; 329b4493eeaSGrégory Soutadé if (mmc_card_blockaddr(card)) 330b4493eeaSGrégory Soutadé card->ext_csd.enhanced_area_offset <<= 9; 331b4493eeaSGrégory Soutadé /* 332b4493eeaSGrégory Soutadé * calculate the enhanced data area size, in kilobytes 333b4493eeaSGrégory Soutadé */ 334b4493eeaSGrégory Soutadé card->ext_csd.enhanced_area_size = 335b4493eeaSGrégory Soutadé (ext_csd[142] << 16) + (ext_csd[141] << 8) + 336b4493eeaSGrégory Soutadé ext_csd[140]; 337b4493eeaSGrégory Soutadé card->ext_csd.enhanced_area_size *= 338b4493eeaSGrégory Soutadé (size_t)(hc_erase_grp_sz * hc_wp_grp_sz); 339b4493eeaSGrégory Soutadé card->ext_csd.enhanced_area_size <<= 9; 340b4493eeaSGrégory Soutadé } else { 341994324bbSGrégory Soutadé pr_warn("%s: defines enhanced area without partition setting complete\n", 342994324bbSGrégory Soutadé mmc_hostname(card->host)); 343994324bbSGrégory Soutadé } 344b4493eeaSGrégory Soutadé } 345b4493eeaSGrégory Soutadé } 346b4493eeaSGrégory Soutadé 347b4493eeaSGrégory Soutadé static void mmc_manage_gp_partitions(struct mmc_card *card, u8 *ext_csd) 348b4493eeaSGrégory Soutadé { 349b4493eeaSGrégory Soutadé int idx; 350994324bbSGrégory Soutadé u8 hc_erase_grp_sz, hc_wp_grp_sz; 351994324bbSGrégory Soutadé unsigned int part_size; 352b4493eeaSGrégory Soutadé 353b4493eeaSGrégory Soutadé /* 354b4493eeaSGrégory Soutadé * General purpose partition feature support -- 355b4493eeaSGrégory Soutadé * If ext_csd has the size of general purpose partitions, 356b4493eeaSGrégory Soutadé * set size, part_cfg, partition name in mmc_part. 357b4493eeaSGrégory Soutadé */ 358b4493eeaSGrégory Soutadé if (ext_csd[EXT_CSD_PARTITION_SUPPORT] & 359b4493eeaSGrégory Soutadé EXT_CSD_PART_SUPPORT_PART_EN) { 360b4493eeaSGrégory Soutadé hc_erase_grp_sz = 361b4493eeaSGrégory Soutadé ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]; 362b4493eeaSGrégory Soutadé hc_wp_grp_sz = 363b4493eeaSGrégory Soutadé ext_csd[EXT_CSD_HC_WP_GRP_SIZE]; 364b4493eeaSGrégory Soutadé 365b4493eeaSGrégory Soutadé for (idx = 0; idx < MMC_NUM_GP_PARTITION; idx++) { 366b4493eeaSGrégory Soutadé if (!ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3] && 367b4493eeaSGrégory Soutadé !ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3 + 1] && 368b4493eeaSGrégory Soutadé !ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3 + 2]) 369b4493eeaSGrégory Soutadé continue; 370994324bbSGrégory Soutadé if (card->ext_csd.partition_setting_completed == 0) { 371994324bbSGrégory Soutadé pr_warn("%s: has partition size defined without partition complete\n", 372994324bbSGrégory Soutadé mmc_hostname(card->host)); 373994324bbSGrégory Soutadé break; 374994324bbSGrégory Soutadé } 375b4493eeaSGrégory Soutadé part_size = 376b4493eeaSGrégory Soutadé (ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3 + 2] 377b4493eeaSGrégory Soutadé << 16) + 378b4493eeaSGrégory Soutadé (ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3 + 1] 379b4493eeaSGrégory Soutadé << 8) + 380b4493eeaSGrégory Soutadé ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3]; 381b4493eeaSGrégory Soutadé part_size *= (size_t)(hc_erase_grp_sz * 382b4493eeaSGrégory Soutadé hc_wp_grp_sz); 383b4493eeaSGrégory Soutadé mmc_part_add(card, part_size << 19, 384b4493eeaSGrégory Soutadé EXT_CSD_PART_CONFIG_ACC_GP0 + idx, 385b4493eeaSGrégory Soutadé "gp%d", idx, false, 386b4493eeaSGrégory Soutadé MMC_BLK_DATA_AREA_GP); 387b4493eeaSGrégory Soutadé } 388b4493eeaSGrégory Soutadé } 389b4493eeaSGrégory Soutadé } 390b4493eeaSGrégory Soutadé 39108ee80ccSPhilip Rakity /* 39208ee80ccSPhilip Rakity * Decode extended CSD. 39308ee80ccSPhilip Rakity */ 39408ee80ccSPhilip Rakity static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) 39508ee80ccSPhilip Rakity { 396e0c368d5SNamjae Jeon int err = 0, idx; 397e0c368d5SNamjae Jeon unsigned int part_size; 39808ee80ccSPhilip Rakity 39908ee80ccSPhilip Rakity BUG_ON(!card); 40008ee80ccSPhilip Rakity 40108ee80ccSPhilip Rakity if (!ext_csd) 40208ee80ccSPhilip Rakity return 0; 40308ee80ccSPhilip Rakity 4046da24b78SKyungmin Park /* Version is coded in the CSD_STRUCTURE byte in the EXT_CSD register */ 405f39b2dd9SPhilip Rakity card->ext_csd.raw_ext_csd_structure = ext_csd[EXT_CSD_STRUCTURE]; 4066da24b78SKyungmin Park if (card->csd.structure == 3) { 407f39b2dd9SPhilip Rakity if (card->ext_csd.raw_ext_csd_structure > 2) { 408a3c76eb9SGirish K S pr_err("%s: unrecognised EXT_CSD structure " 4098fdd8521SPierre Ossman "version %d\n", mmc_hostname(card->host), 410f39b2dd9SPhilip Rakity card->ext_csd.raw_ext_csd_structure); 4116da24b78SKyungmin Park err = -EINVAL; 4126da24b78SKyungmin Park goto out; 4136da24b78SKyungmin Park } 4146da24b78SKyungmin Park } 4156da24b78SKyungmin Park 41603a59437SRomain Izard /* 41703a59437SRomain Izard * The EXT_CSD format is meant to be forward compatible. As long 41803a59437SRomain Izard * as CSD_STRUCTURE does not change, all values for EXT_CSD_REV 41903a59437SRomain Izard * are authorized, see JEDEC JESD84-B50 section B.8. 42003a59437SRomain Izard */ 4216da24b78SKyungmin Park card->ext_csd.rev = ext_csd[EXT_CSD_REV]; 422d7604d76SPierre Ossman 423f39b2dd9SPhilip Rakity card->ext_csd.raw_sectors[0] = ext_csd[EXT_CSD_SEC_CNT + 0]; 424f39b2dd9SPhilip Rakity card->ext_csd.raw_sectors[1] = ext_csd[EXT_CSD_SEC_CNT + 1]; 425f39b2dd9SPhilip Rakity card->ext_csd.raw_sectors[2] = ext_csd[EXT_CSD_SEC_CNT + 2]; 426f39b2dd9SPhilip Rakity card->ext_csd.raw_sectors[3] = ext_csd[EXT_CSD_SEC_CNT + 3]; 427b1ebe384SJarkko Lavinen if (card->ext_csd.rev >= 2) { 4287ea239d9SPierre Ossman card->ext_csd.sectors = 4297ea239d9SPierre Ossman ext_csd[EXT_CSD_SEC_CNT + 0] << 0 | 4307ea239d9SPierre Ossman ext_csd[EXT_CSD_SEC_CNT + 1] << 8 | 4317ea239d9SPierre Ossman ext_csd[EXT_CSD_SEC_CNT + 2] << 16 | 4327ea239d9SPierre Ossman ext_csd[EXT_CSD_SEC_CNT + 3] << 24; 433fc8a0985SHanumath Prasad 434fc8a0985SHanumath Prasad /* Cards with density > 2GiB are sector addressed */ 435fc8a0985SHanumath Prasad if (card->ext_csd.sectors > (2u * 1024 * 1024 * 1024) / 512) 4367ea239d9SPierre Ossman mmc_card_set_blockaddr(card); 437d7604d76SPierre Ossman } 43896cf5f02SSeungwon Jeon 439f39b2dd9SPhilip Rakity card->ext_csd.raw_card_type = ext_csd[EXT_CSD_CARD_TYPE]; 44096cf5f02SSeungwon Jeon mmc_select_card_type(card); 4417ea239d9SPierre Ossman 442f39b2dd9SPhilip Rakity card->ext_csd.raw_s_a_timeout = ext_csd[EXT_CSD_S_A_TIMEOUT]; 443f39b2dd9SPhilip Rakity card->ext_csd.raw_erase_timeout_mult = 444f39b2dd9SPhilip Rakity ext_csd[EXT_CSD_ERASE_TIMEOUT_MULT]; 445f39b2dd9SPhilip Rakity card->ext_csd.raw_hc_erase_grp_size = 446f39b2dd9SPhilip Rakity ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]; 447b1ebe384SJarkko Lavinen if (card->ext_csd.rev >= 3) { 448b1ebe384SJarkko Lavinen u8 sa_shift = ext_csd[EXT_CSD_S_A_TIMEOUT]; 449371a689fSAndrei Warkentin card->ext_csd.part_config = ext_csd[EXT_CSD_PART_CONFIG]; 450371a689fSAndrei Warkentin 451371a689fSAndrei Warkentin /* EXT_CSD value is in units of 10ms, but we store in ms */ 452371a689fSAndrei Warkentin card->ext_csd.part_time = 10 * ext_csd[EXT_CSD_PART_SWITCH_TIME]; 453b1ebe384SJarkko Lavinen 454b1ebe384SJarkko Lavinen /* Sleep / awake timeout in 100ns units */ 455b1ebe384SJarkko Lavinen if (sa_shift > 0 && sa_shift <= 0x17) 456b1ebe384SJarkko Lavinen card->ext_csd.sa_timeout = 457b1ebe384SJarkko Lavinen 1 << ext_csd[EXT_CSD_S_A_TIMEOUT]; 458dfe86cbaSAdrian Hunter card->ext_csd.erase_group_def = 459dfe86cbaSAdrian Hunter ext_csd[EXT_CSD_ERASE_GROUP_DEF]; 460dfe86cbaSAdrian Hunter card->ext_csd.hc_erase_timeout = 300 * 461dfe86cbaSAdrian Hunter ext_csd[EXT_CSD_ERASE_TIMEOUT_MULT]; 462dfe86cbaSAdrian Hunter card->ext_csd.hc_erase_size = 463dfe86cbaSAdrian Hunter ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] << 10; 464f4c5522bSAndrei Warkentin 465f4c5522bSAndrei Warkentin card->ext_csd.rel_sectors = ext_csd[EXT_CSD_REL_WR_SEC_C]; 466371a689fSAndrei Warkentin 467371a689fSAndrei Warkentin /* 468371a689fSAndrei Warkentin * There are two boot regions of equal size, defined in 469371a689fSAndrei Warkentin * multiples of 128K. 470371a689fSAndrei Warkentin */ 471e0c368d5SNamjae Jeon if (ext_csd[EXT_CSD_BOOT_MULT] && mmc_boot_partition_access(card->host)) { 472e0c368d5SNamjae Jeon for (idx = 0; idx < MMC_NUM_BOOT_PARTITION; idx++) { 473e0c368d5SNamjae Jeon part_size = ext_csd[EXT_CSD_BOOT_MULT] << 17; 474e0c368d5SNamjae Jeon mmc_part_add(card, part_size, 475e0c368d5SNamjae Jeon EXT_CSD_PART_CONFIG_ACC_BOOT0 + idx, 476add710eaSJohan Rudholm "boot%d", idx, true, 477add710eaSJohan Rudholm MMC_BLK_DATA_AREA_BOOT); 478e0c368d5SNamjae Jeon } 479e0c368d5SNamjae Jeon } 480b1ebe384SJarkko Lavinen } 481b1ebe384SJarkko Lavinen 482f39b2dd9SPhilip Rakity card->ext_csd.raw_hc_erase_gap_size = 483dd13b4edSJurgen Heeks ext_csd[EXT_CSD_HC_WP_GRP_SIZE]; 484f39b2dd9SPhilip Rakity card->ext_csd.raw_sec_trim_mult = 485f39b2dd9SPhilip Rakity ext_csd[EXT_CSD_SEC_TRIM_MULT]; 486f39b2dd9SPhilip Rakity card->ext_csd.raw_sec_erase_mult = 487f39b2dd9SPhilip Rakity ext_csd[EXT_CSD_SEC_ERASE_MULT]; 488f39b2dd9SPhilip Rakity card->ext_csd.raw_sec_feature_support = 489f39b2dd9SPhilip Rakity ext_csd[EXT_CSD_SEC_FEATURE_SUPPORT]; 490f39b2dd9SPhilip Rakity card->ext_csd.raw_trim_mult = 491f39b2dd9SPhilip Rakity ext_csd[EXT_CSD_TRIM_MULT]; 492836dc2feSPhilip Rakity card->ext_csd.raw_partition_support = ext_csd[EXT_CSD_PARTITION_SUPPORT]; 493dfe86cbaSAdrian Hunter if (card->ext_csd.rev >= 4) { 49469803d4fSGrégory Soutadé if (ext_csd[EXT_CSD_PARTITION_SETTING_COMPLETED] & 49569803d4fSGrégory Soutadé EXT_CSD_PART_SETTING_COMPLETED) 49669803d4fSGrégory Soutadé card->ext_csd.partition_setting_completed = 1; 49769803d4fSGrégory Soutadé else 49869803d4fSGrégory Soutadé card->ext_csd.partition_setting_completed = 0; 49969803d4fSGrégory Soutadé 500b4493eeaSGrégory Soutadé mmc_manage_enhanced_area(card, ext_csd); 501709de99dSChuanxiao Dong 502b4493eeaSGrégory Soutadé mmc_manage_gp_partitions(card, ext_csd); 503e0c368d5SNamjae Jeon 504dfe86cbaSAdrian Hunter card->ext_csd.sec_trim_mult = 505dfe86cbaSAdrian Hunter ext_csd[EXT_CSD_SEC_TRIM_MULT]; 506dfe86cbaSAdrian Hunter card->ext_csd.sec_erase_mult = 507dfe86cbaSAdrian Hunter ext_csd[EXT_CSD_SEC_ERASE_MULT]; 508dfe86cbaSAdrian Hunter card->ext_csd.sec_feature_support = 509dfe86cbaSAdrian Hunter ext_csd[EXT_CSD_SEC_FEATURE_SUPPORT]; 510dfe86cbaSAdrian Hunter card->ext_csd.trim_timeout = 300 * 511dfe86cbaSAdrian Hunter ext_csd[EXT_CSD_TRIM_MULT]; 512add710eaSJohan Rudholm 513add710eaSJohan Rudholm /* 514add710eaSJohan Rudholm * Note that the call to mmc_part_add above defaults to read 515add710eaSJohan Rudholm * only. If this default assumption is changed, the call must 516add710eaSJohan Rudholm * take into account the value of boot_locked below. 517add710eaSJohan Rudholm */ 518add710eaSJohan Rudholm card->ext_csd.boot_ro_lock = ext_csd[EXT_CSD_BOOT_WP]; 519add710eaSJohan Rudholm card->ext_csd.boot_ro_lockable = true; 52060443712SFredrik Soderstedt 52160443712SFredrik Soderstedt /* Save power class values */ 52260443712SFredrik Soderstedt card->ext_csd.raw_pwr_cl_52_195 = 52360443712SFredrik Soderstedt ext_csd[EXT_CSD_PWR_CL_52_195]; 52460443712SFredrik Soderstedt card->ext_csd.raw_pwr_cl_26_195 = 52560443712SFredrik Soderstedt ext_csd[EXT_CSD_PWR_CL_26_195]; 52660443712SFredrik Soderstedt card->ext_csd.raw_pwr_cl_52_360 = 52760443712SFredrik Soderstedt ext_csd[EXT_CSD_PWR_CL_52_360]; 52860443712SFredrik Soderstedt card->ext_csd.raw_pwr_cl_26_360 = 52960443712SFredrik Soderstedt ext_csd[EXT_CSD_PWR_CL_26_360]; 53060443712SFredrik Soderstedt card->ext_csd.raw_pwr_cl_200_195 = 53160443712SFredrik Soderstedt ext_csd[EXT_CSD_PWR_CL_200_195]; 53260443712SFredrik Soderstedt card->ext_csd.raw_pwr_cl_200_360 = 53360443712SFredrik Soderstedt ext_csd[EXT_CSD_PWR_CL_200_360]; 53460443712SFredrik Soderstedt card->ext_csd.raw_pwr_cl_ddr_52_195 = 53560443712SFredrik Soderstedt ext_csd[EXT_CSD_PWR_CL_DDR_52_195]; 53660443712SFredrik Soderstedt card->ext_csd.raw_pwr_cl_ddr_52_360 = 53760443712SFredrik Soderstedt ext_csd[EXT_CSD_PWR_CL_DDR_52_360]; 5380a5b6438SSeungwon Jeon card->ext_csd.raw_pwr_cl_ddr_200_360 = 5390a5b6438SSeungwon Jeon ext_csd[EXT_CSD_PWR_CL_DDR_200_360]; 540dfe86cbaSAdrian Hunter } 541dfe86cbaSAdrian Hunter 542b2499518SAdrian Hunter if (card->ext_csd.rev >= 5) { 5437c4f10acSRomain Izard /* Adjust production date as per JEDEC JESD84-B451 */ 5447c4f10acSRomain Izard if (card->cid.year < 2010) 5457c4f10acSRomain Izard card->cid.year += 16; 5467c4f10acSRomain Izard 547950d56acSJaehoon Chung /* check whether the eMMC card supports BKOPS */ 548950d56acSJaehoon Chung if (ext_csd[EXT_CSD_BKOPS_SUPPORT] & 0x1) { 549950d56acSJaehoon Chung card->ext_csd.bkops = 1; 550950d56acSJaehoon Chung card->ext_csd.bkops_en = ext_csd[EXT_CSD_BKOPS_EN]; 551950d56acSJaehoon Chung card->ext_csd.raw_bkops_status = 552950d56acSJaehoon Chung ext_csd[EXT_CSD_BKOPS_STATUS]; 553950d56acSJaehoon Chung if (!card->ext_csd.bkops_en) 554950d56acSJaehoon Chung pr_info("%s: BKOPS_EN bit is not set\n", 555950d56acSJaehoon Chung mmc_hostname(card->host)); 556950d56acSJaehoon Chung } 557950d56acSJaehoon Chung 558eb0d8f13SJaehoon Chung /* check whether the eMMC card supports HPI */ 559eb0d8f13SJaehoon Chung if (ext_csd[EXT_CSD_HPI_FEATURES] & 0x1) { 560eb0d8f13SJaehoon Chung card->ext_csd.hpi = 1; 561eb0d8f13SJaehoon Chung if (ext_csd[EXT_CSD_HPI_FEATURES] & 0x2) 562eb0d8f13SJaehoon Chung card->ext_csd.hpi_cmd = MMC_STOP_TRANSMISSION; 563eb0d8f13SJaehoon Chung else 564eb0d8f13SJaehoon Chung card->ext_csd.hpi_cmd = MMC_SEND_STATUS; 565eb0d8f13SJaehoon Chung /* 566eb0d8f13SJaehoon Chung * Indicate the maximum timeout to close 567eb0d8f13SJaehoon Chung * a command interrupted by HPI 568eb0d8f13SJaehoon Chung */ 569eb0d8f13SJaehoon Chung card->ext_csd.out_of_int_time = 570eb0d8f13SJaehoon Chung ext_csd[EXT_CSD_OUT_OF_INTERRUPT_TIME] * 10; 571eb0d8f13SJaehoon Chung } 572eb0d8f13SJaehoon Chung 573f4c5522bSAndrei Warkentin card->ext_csd.rel_param = ext_csd[EXT_CSD_WR_REL_PARAM]; 574b2499518SAdrian Hunter card->ext_csd.rst_n_function = ext_csd[EXT_CSD_RST_N_FUNCTION]; 575090d25feSLoic Pallardy 576090d25feSLoic Pallardy /* 577090d25feSLoic Pallardy * RPMB regions are defined in multiples of 128K. 578090d25feSLoic Pallardy */ 579090d25feSLoic Pallardy card->ext_csd.raw_rpmb_size_mult = ext_csd[EXT_CSD_RPMB_MULT]; 580d0123ccaSBalaji T K if (ext_csd[EXT_CSD_RPMB_MULT] && mmc_host_cmd23(card->host)) { 581090d25feSLoic Pallardy mmc_part_add(card, ext_csd[EXT_CSD_RPMB_MULT] << 17, 582090d25feSLoic Pallardy EXT_CSD_PART_CONFIG_ACC_RPMB, 583090d25feSLoic Pallardy "rpmb", 0, false, 584090d25feSLoic Pallardy MMC_BLK_DATA_AREA_RPMB); 585090d25feSLoic Pallardy } 586b2499518SAdrian Hunter } 587f4c5522bSAndrei Warkentin 5885238acbeSAndrei Warkentin card->ext_csd.raw_erased_mem_count = ext_csd[EXT_CSD_ERASED_MEM_CONT]; 589dfe86cbaSAdrian Hunter if (ext_csd[EXT_CSD_ERASED_MEM_CONT]) 590dfe86cbaSAdrian Hunter card->erased_byte = 0xFF; 591dfe86cbaSAdrian Hunter else 592dfe86cbaSAdrian Hunter card->erased_byte = 0x0; 593dfe86cbaSAdrian Hunter 594336c716aSSeungwon Jeon /* eMMC v4.5 or later */ 595bec8726aSGirish K S if (card->ext_csd.rev >= 6) { 596336c716aSSeungwon Jeon card->ext_csd.feature_support |= MMC_DISCARD_FEATURE; 597336c716aSSeungwon Jeon 598b23cf0bdSSeungwon Jeon card->ext_csd.generic_cmd6_time = 10 * 599b23cf0bdSSeungwon Jeon ext_csd[EXT_CSD_GENERIC_CMD6_TIME]; 600bec8726aSGirish K S card->ext_csd.power_off_longtime = 10 * 601bec8726aSGirish K S ext_csd[EXT_CSD_POWER_OFF_LONG_TIME]; 602b23cf0bdSSeungwon Jeon 603881d1c25SSeungwon Jeon card->ext_csd.cache_size = 604881d1c25SSeungwon Jeon ext_csd[EXT_CSD_CACHE_SIZE + 0] << 0 | 605881d1c25SSeungwon Jeon ext_csd[EXT_CSD_CACHE_SIZE + 1] << 8 | 606881d1c25SSeungwon Jeon ext_csd[EXT_CSD_CACHE_SIZE + 2] << 16 | 607881d1c25SSeungwon Jeon ext_csd[EXT_CSD_CACHE_SIZE + 3] << 24; 6084265900eSSaugata Das 6094265900eSSaugata Das if (ext_csd[EXT_CSD_DATA_SECTOR_SIZE] == 1) 6104265900eSSaugata Das card->ext_csd.data_sector_size = 4096; 6114265900eSSaugata Das else 6124265900eSSaugata Das card->ext_csd.data_sector_size = 512; 6134265900eSSaugata Das 6144265900eSSaugata Das if ((ext_csd[EXT_CSD_DATA_TAG_SUPPORT] & 1) && 6154265900eSSaugata Das (ext_csd[EXT_CSD_TAG_UNIT_SIZE] <= 8)) { 6164265900eSSaugata Das card->ext_csd.data_tag_unit_size = 6174265900eSSaugata Das ((unsigned int) 1 << ext_csd[EXT_CSD_TAG_UNIT_SIZE]) * 6184265900eSSaugata Das (card->ext_csd.data_sector_size); 6194265900eSSaugata Das } else { 6204265900eSSaugata Das card->ext_csd.data_tag_unit_size = 0; 6214265900eSSaugata Das } 622abd9ac14SSeungwon Jeon 623abd9ac14SSeungwon Jeon card->ext_csd.max_packed_writes = 624abd9ac14SSeungwon Jeon ext_csd[EXT_CSD_MAX_PACKED_WRITES]; 625abd9ac14SSeungwon Jeon card->ext_csd.max_packed_reads = 626abd9ac14SSeungwon Jeon ext_csd[EXT_CSD_MAX_PACKED_READS]; 627a5075eb9SSaugata Das } else { 628a5075eb9SSaugata Das card->ext_csd.data_sector_size = 512; 629336c716aSSeungwon Jeon } 630881d1c25SSeungwon Jeon 6317ea239d9SPierre Ossman out: 63208ee80ccSPhilip Rakity return err; 63308ee80ccSPhilip Rakity } 6347ea239d9SPierre Ossman 63508ee80ccSPhilip Rakity static inline void mmc_free_ext_csd(u8 *ext_csd) 63608ee80ccSPhilip Rakity { 63708ee80ccSPhilip Rakity kfree(ext_csd); 63808ee80ccSPhilip Rakity } 63908ee80ccSPhilip Rakity 64008ee80ccSPhilip Rakity 641f39b2dd9SPhilip Rakity static int mmc_compare_ext_csds(struct mmc_card *card, unsigned bus_width) 64208ee80ccSPhilip Rakity { 64308ee80ccSPhilip Rakity u8 *bw_ext_csd; 64408ee80ccSPhilip Rakity int err; 64508ee80ccSPhilip Rakity 646f39b2dd9SPhilip Rakity if (bus_width == MMC_BUS_WIDTH_1) 647f39b2dd9SPhilip Rakity return 0; 64808ee80ccSPhilip Rakity 649f39b2dd9SPhilip Rakity err = mmc_get_ext_csd(card, &bw_ext_csd); 650f39b2dd9SPhilip Rakity 651f39b2dd9SPhilip Rakity if (err || bw_ext_csd == NULL) { 65208ee80ccSPhilip Rakity err = -EINVAL; 65308ee80ccSPhilip Rakity goto out; 65408ee80ccSPhilip Rakity } 65508ee80ccSPhilip Rakity 65608ee80ccSPhilip Rakity /* only compare read only fields */ 657dd13b4edSJurgen Heeks err = !((card->ext_csd.raw_partition_support == 65808ee80ccSPhilip Rakity bw_ext_csd[EXT_CSD_PARTITION_SUPPORT]) && 659f39b2dd9SPhilip Rakity (card->ext_csd.raw_erased_mem_count == 66008ee80ccSPhilip Rakity bw_ext_csd[EXT_CSD_ERASED_MEM_CONT]) && 661f39b2dd9SPhilip Rakity (card->ext_csd.rev == 66208ee80ccSPhilip Rakity bw_ext_csd[EXT_CSD_REV]) && 663f39b2dd9SPhilip Rakity (card->ext_csd.raw_ext_csd_structure == 66408ee80ccSPhilip Rakity bw_ext_csd[EXT_CSD_STRUCTURE]) && 665f39b2dd9SPhilip Rakity (card->ext_csd.raw_card_type == 66608ee80ccSPhilip Rakity bw_ext_csd[EXT_CSD_CARD_TYPE]) && 667f39b2dd9SPhilip Rakity (card->ext_csd.raw_s_a_timeout == 66808ee80ccSPhilip Rakity bw_ext_csd[EXT_CSD_S_A_TIMEOUT]) && 669f39b2dd9SPhilip Rakity (card->ext_csd.raw_hc_erase_gap_size == 67008ee80ccSPhilip Rakity bw_ext_csd[EXT_CSD_HC_WP_GRP_SIZE]) && 671f39b2dd9SPhilip Rakity (card->ext_csd.raw_erase_timeout_mult == 67208ee80ccSPhilip Rakity bw_ext_csd[EXT_CSD_ERASE_TIMEOUT_MULT]) && 673f39b2dd9SPhilip Rakity (card->ext_csd.raw_hc_erase_grp_size == 67408ee80ccSPhilip Rakity bw_ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]) && 675f39b2dd9SPhilip Rakity (card->ext_csd.raw_sec_trim_mult == 67608ee80ccSPhilip Rakity bw_ext_csd[EXT_CSD_SEC_TRIM_MULT]) && 677f39b2dd9SPhilip Rakity (card->ext_csd.raw_sec_erase_mult == 67808ee80ccSPhilip Rakity bw_ext_csd[EXT_CSD_SEC_ERASE_MULT]) && 679f39b2dd9SPhilip Rakity (card->ext_csd.raw_sec_feature_support == 68008ee80ccSPhilip Rakity bw_ext_csd[EXT_CSD_SEC_FEATURE_SUPPORT]) && 681f39b2dd9SPhilip Rakity (card->ext_csd.raw_trim_mult == 68208ee80ccSPhilip Rakity bw_ext_csd[EXT_CSD_TRIM_MULT]) && 683f39b2dd9SPhilip Rakity (card->ext_csd.raw_sectors[0] == 684f39b2dd9SPhilip Rakity bw_ext_csd[EXT_CSD_SEC_CNT + 0]) && 685f39b2dd9SPhilip Rakity (card->ext_csd.raw_sectors[1] == 686f39b2dd9SPhilip Rakity bw_ext_csd[EXT_CSD_SEC_CNT + 1]) && 687f39b2dd9SPhilip Rakity (card->ext_csd.raw_sectors[2] == 688f39b2dd9SPhilip Rakity bw_ext_csd[EXT_CSD_SEC_CNT + 2]) && 689f39b2dd9SPhilip Rakity (card->ext_csd.raw_sectors[3] == 69060443712SFredrik Soderstedt bw_ext_csd[EXT_CSD_SEC_CNT + 3]) && 69160443712SFredrik Soderstedt (card->ext_csd.raw_pwr_cl_52_195 == 69260443712SFredrik Soderstedt bw_ext_csd[EXT_CSD_PWR_CL_52_195]) && 69360443712SFredrik Soderstedt (card->ext_csd.raw_pwr_cl_26_195 == 69460443712SFredrik Soderstedt bw_ext_csd[EXT_CSD_PWR_CL_26_195]) && 69560443712SFredrik Soderstedt (card->ext_csd.raw_pwr_cl_52_360 == 69660443712SFredrik Soderstedt bw_ext_csd[EXT_CSD_PWR_CL_52_360]) && 69760443712SFredrik Soderstedt (card->ext_csd.raw_pwr_cl_26_360 == 69860443712SFredrik Soderstedt bw_ext_csd[EXT_CSD_PWR_CL_26_360]) && 69960443712SFredrik Soderstedt (card->ext_csd.raw_pwr_cl_200_195 == 70060443712SFredrik Soderstedt bw_ext_csd[EXT_CSD_PWR_CL_200_195]) && 70160443712SFredrik Soderstedt (card->ext_csd.raw_pwr_cl_200_360 == 70260443712SFredrik Soderstedt bw_ext_csd[EXT_CSD_PWR_CL_200_360]) && 70360443712SFredrik Soderstedt (card->ext_csd.raw_pwr_cl_ddr_52_195 == 70460443712SFredrik Soderstedt bw_ext_csd[EXT_CSD_PWR_CL_DDR_52_195]) && 70560443712SFredrik Soderstedt (card->ext_csd.raw_pwr_cl_ddr_52_360 == 7060a5b6438SSeungwon Jeon bw_ext_csd[EXT_CSD_PWR_CL_DDR_52_360]) && 7070a5b6438SSeungwon Jeon (card->ext_csd.raw_pwr_cl_ddr_200_360 == 7080a5b6438SSeungwon Jeon bw_ext_csd[EXT_CSD_PWR_CL_DDR_200_360])); 7090a5b6438SSeungwon Jeon 71008ee80ccSPhilip Rakity if (err) 71108ee80ccSPhilip Rakity err = -EINVAL; 71208ee80ccSPhilip Rakity 71308ee80ccSPhilip Rakity out: 71408ee80ccSPhilip Rakity mmc_free_ext_csd(bw_ext_csd); 7157ea239d9SPierre Ossman return err; 7167ea239d9SPierre Ossman } 7177ea239d9SPierre Ossman 71851ec92e2SPierre Ossman MMC_DEV_ATTR(cid, "%08x%08x%08x%08x\n", card->raw_cid[0], card->raw_cid[1], 71951ec92e2SPierre Ossman card->raw_cid[2], card->raw_cid[3]); 72051ec92e2SPierre Ossman MMC_DEV_ATTR(csd, "%08x%08x%08x%08x\n", card->raw_csd[0], card->raw_csd[1], 72151ec92e2SPierre Ossman card->raw_csd[2], card->raw_csd[3]); 72251ec92e2SPierre Ossman MMC_DEV_ATTR(date, "%02d/%04d\n", card->cid.month, card->cid.year); 723dfe86cbaSAdrian Hunter MMC_DEV_ATTR(erase_size, "%u\n", card->erase_size << 9); 724dfe86cbaSAdrian Hunter MMC_DEV_ATTR(preferred_erase_size, "%u\n", card->pref_erase << 9); 72551ec92e2SPierre Ossman MMC_DEV_ATTR(fwrev, "0x%x\n", card->cid.fwrev); 72651ec92e2SPierre Ossman MMC_DEV_ATTR(hwrev, "0x%x\n", card->cid.hwrev); 72751ec92e2SPierre Ossman MMC_DEV_ATTR(manfid, "0x%06x\n", card->cid.manfid); 72851ec92e2SPierre Ossman MMC_DEV_ATTR(name, "%s\n", card->cid.prod_name); 72951ec92e2SPierre Ossman MMC_DEV_ATTR(oemid, "0x%04x\n", card->cid.oemid); 73051e7e8b6SBernie Thompson MMC_DEV_ATTR(prv, "0x%x\n", card->cid.prv); 73151ec92e2SPierre Ossman MMC_DEV_ATTR(serial, "0x%08x\n", card->cid.serial); 732709de99dSChuanxiao Dong MMC_DEV_ATTR(enhanced_area_offset, "%llu\n", 733709de99dSChuanxiao Dong card->ext_csd.enhanced_area_offset); 734709de99dSChuanxiao Dong MMC_DEV_ATTR(enhanced_area_size, "%u\n", card->ext_csd.enhanced_area_size); 735188cc042SLoic Pallardy MMC_DEV_ATTR(raw_rpmb_size_mult, "%#x\n", card->ext_csd.raw_rpmb_size_mult); 736188cc042SLoic Pallardy MMC_DEV_ATTR(rel_sectors, "%#x\n", card->ext_csd.rel_sectors); 73751ec92e2SPierre Ossman 73851ec92e2SPierre Ossman static struct attribute *mmc_std_attrs[] = { 73951ec92e2SPierre Ossman &dev_attr_cid.attr, 74051ec92e2SPierre Ossman &dev_attr_csd.attr, 74151ec92e2SPierre Ossman &dev_attr_date.attr, 742dfe86cbaSAdrian Hunter &dev_attr_erase_size.attr, 743dfe86cbaSAdrian Hunter &dev_attr_preferred_erase_size.attr, 74451ec92e2SPierre Ossman &dev_attr_fwrev.attr, 74551ec92e2SPierre Ossman &dev_attr_hwrev.attr, 74651ec92e2SPierre Ossman &dev_attr_manfid.attr, 74751ec92e2SPierre Ossman &dev_attr_name.attr, 74851ec92e2SPierre Ossman &dev_attr_oemid.attr, 74951e7e8b6SBernie Thompson &dev_attr_prv.attr, 75051ec92e2SPierre Ossman &dev_attr_serial.attr, 751709de99dSChuanxiao Dong &dev_attr_enhanced_area_offset.attr, 752709de99dSChuanxiao Dong &dev_attr_enhanced_area_size.attr, 753188cc042SLoic Pallardy &dev_attr_raw_rpmb_size_mult.attr, 754188cc042SLoic Pallardy &dev_attr_rel_sectors.attr, 75551ec92e2SPierre Ossman NULL, 75651ec92e2SPierre Ossman }; 757d1e58212SAxel Lin ATTRIBUTE_GROUPS(mmc_std); 75851ec92e2SPierre Ossman 75951ec92e2SPierre Ossman static struct device_type mmc_type = { 760d1e58212SAxel Lin .groups = mmc_std_groups, 76151ec92e2SPierre Ossman }; 76251ec92e2SPierre Ossman 7637ea239d9SPierre Ossman /* 764b87d8dbfSGirish K S * Select the PowerClass for the current bus width 765b87d8dbfSGirish K S * If power class is defined for 4/8 bit bus in the 766b87d8dbfSGirish K S * extended CSD register, select it by executing the 767b87d8dbfSGirish K S * mmc_switch command. 768b87d8dbfSGirish K S */ 7692385049dSSeungwon Jeon static int __mmc_select_powerclass(struct mmc_card *card, 77060443712SFredrik Soderstedt unsigned int bus_width) 771b87d8dbfSGirish K S { 7722385049dSSeungwon Jeon struct mmc_host *host = card->host; 7732385049dSSeungwon Jeon struct mmc_ext_csd *ext_csd = &card->ext_csd; 77460443712SFredrik Soderstedt unsigned int pwrclass_val = 0; 7752385049dSSeungwon Jeon int err = 0; 776b87d8dbfSGirish K S 777b87d8dbfSGirish K S /* Power class selection is supported for versions >= 4.0 */ 778b87d8dbfSGirish K S if (card->csd.mmca_vsn < CSD_SPEC_VER_4) 779b87d8dbfSGirish K S return 0; 780b87d8dbfSGirish K S 781b87d8dbfSGirish K S /* Power class values are defined only for 4/8 bit bus */ 782b87d8dbfSGirish K S if (bus_width == EXT_CSD_BUS_WIDTH_1) 783b87d8dbfSGirish K S return 0; 784b87d8dbfSGirish K S 785b87d8dbfSGirish K S switch (1 << host->ios.vdd) { 786b87d8dbfSGirish K S case MMC_VDD_165_195: 7872385049dSSeungwon Jeon if (host->ios.clock <= MMC_HIGH_26_MAX_DTR) 7882385049dSSeungwon Jeon pwrclass_val = ext_csd->raw_pwr_cl_26_195; 7892385049dSSeungwon Jeon else if (host->ios.clock <= MMC_HIGH_52_MAX_DTR) 79060443712SFredrik Soderstedt pwrclass_val = (bus_width <= EXT_CSD_BUS_WIDTH_8) ? 7912385049dSSeungwon Jeon ext_csd->raw_pwr_cl_52_195 : 7922385049dSSeungwon Jeon ext_csd->raw_pwr_cl_ddr_52_195; 7932385049dSSeungwon Jeon else if (host->ios.clock <= MMC_HS200_MAX_DTR) 7942385049dSSeungwon Jeon pwrclass_val = ext_csd->raw_pwr_cl_200_195; 795b87d8dbfSGirish K S break; 79693fc5a47SSubhash Jadavani case MMC_VDD_27_28: 79793fc5a47SSubhash Jadavani case MMC_VDD_28_29: 79893fc5a47SSubhash Jadavani case MMC_VDD_29_30: 79993fc5a47SSubhash Jadavani case MMC_VDD_30_31: 80093fc5a47SSubhash Jadavani case MMC_VDD_31_32: 801b87d8dbfSGirish K S case MMC_VDD_32_33: 802b87d8dbfSGirish K S case MMC_VDD_33_34: 803b87d8dbfSGirish K S case MMC_VDD_34_35: 804b87d8dbfSGirish K S case MMC_VDD_35_36: 8052385049dSSeungwon Jeon if (host->ios.clock <= MMC_HIGH_26_MAX_DTR) 8062385049dSSeungwon Jeon pwrclass_val = ext_csd->raw_pwr_cl_26_360; 8072385049dSSeungwon Jeon else if (host->ios.clock <= MMC_HIGH_52_MAX_DTR) 80860443712SFredrik Soderstedt pwrclass_val = (bus_width <= EXT_CSD_BUS_WIDTH_8) ? 8092385049dSSeungwon Jeon ext_csd->raw_pwr_cl_52_360 : 8102385049dSSeungwon Jeon ext_csd->raw_pwr_cl_ddr_52_360; 8112385049dSSeungwon Jeon else if (host->ios.clock <= MMC_HS200_MAX_DTR) 8120a5b6438SSeungwon Jeon pwrclass_val = (bus_width == EXT_CSD_DDR_BUS_WIDTH_8) ? 8130a5b6438SSeungwon Jeon ext_csd->raw_pwr_cl_ddr_200_360 : 8140a5b6438SSeungwon Jeon ext_csd->raw_pwr_cl_200_360; 815b87d8dbfSGirish K S break; 816b87d8dbfSGirish K S default: 8176606110dSJoe Perches pr_warn("%s: Voltage range not supported for power class\n", 8186606110dSJoe Perches mmc_hostname(host)); 819b87d8dbfSGirish K S return -EINVAL; 820b87d8dbfSGirish K S } 821b87d8dbfSGirish K S 822b87d8dbfSGirish K S if (bus_width & (EXT_CSD_BUS_WIDTH_8 | EXT_CSD_DDR_BUS_WIDTH_8)) 823b87d8dbfSGirish K S pwrclass_val = (pwrclass_val & EXT_CSD_PWR_CL_8BIT_MASK) >> 824b87d8dbfSGirish K S EXT_CSD_PWR_CL_8BIT_SHIFT; 825b87d8dbfSGirish K S else 826b87d8dbfSGirish K S pwrclass_val = (pwrclass_val & EXT_CSD_PWR_CL_4BIT_MASK) >> 827b87d8dbfSGirish K S EXT_CSD_PWR_CL_4BIT_SHIFT; 828b87d8dbfSGirish K S 829b87d8dbfSGirish K S /* If the power class is different from the default value */ 830b87d8dbfSGirish K S if (pwrclass_val > 0) { 831b87d8dbfSGirish K S err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, 832b87d8dbfSGirish K S EXT_CSD_POWER_CLASS, 833b87d8dbfSGirish K S pwrclass_val, 83471fe3eb0SSeungwon Jeon card->ext_csd.generic_cmd6_time); 835b87d8dbfSGirish K S } 836b87d8dbfSGirish K S 837b87d8dbfSGirish K S return err; 838b87d8dbfSGirish K S } 839b87d8dbfSGirish K S 8402385049dSSeungwon Jeon static int mmc_select_powerclass(struct mmc_card *card) 8412385049dSSeungwon Jeon { 8422385049dSSeungwon Jeon struct mmc_host *host = card->host; 8432385049dSSeungwon Jeon u32 bus_width, ext_csd_bits; 8442385049dSSeungwon Jeon int err, ddr; 8452385049dSSeungwon Jeon 8462385049dSSeungwon Jeon /* Power class selection is supported for versions >= 4.0 */ 8472385049dSSeungwon Jeon if (card->csd.mmca_vsn < CSD_SPEC_VER_4) 8482385049dSSeungwon Jeon return 0; 8492385049dSSeungwon Jeon 8502385049dSSeungwon Jeon bus_width = host->ios.bus_width; 8512385049dSSeungwon Jeon /* Power class values are defined only for 4/8 bit bus */ 8522385049dSSeungwon Jeon if (bus_width == MMC_BUS_WIDTH_1) 8532385049dSSeungwon Jeon return 0; 8542385049dSSeungwon Jeon 8552385049dSSeungwon Jeon ddr = card->mmc_avail_type & EXT_CSD_CARD_TYPE_DDR_52; 8562385049dSSeungwon Jeon if (ddr) 8572385049dSSeungwon Jeon ext_csd_bits = (bus_width == MMC_BUS_WIDTH_8) ? 8582385049dSSeungwon Jeon EXT_CSD_DDR_BUS_WIDTH_8 : EXT_CSD_DDR_BUS_WIDTH_4; 8592385049dSSeungwon Jeon else 8602385049dSSeungwon Jeon ext_csd_bits = (bus_width == MMC_BUS_WIDTH_8) ? 8612385049dSSeungwon Jeon EXT_CSD_BUS_WIDTH_8 : EXT_CSD_BUS_WIDTH_4; 8622385049dSSeungwon Jeon 8632385049dSSeungwon Jeon err = __mmc_select_powerclass(card, ext_csd_bits); 8642385049dSSeungwon Jeon if (err) 8652385049dSSeungwon Jeon pr_warn("%s: power class selection to bus width %d ddr %d failed\n", 8662385049dSSeungwon Jeon mmc_hostname(host), 1 << bus_width, ddr); 8672385049dSSeungwon Jeon 8682385049dSSeungwon Jeon return err; 8692385049dSSeungwon Jeon } 8702385049dSSeungwon Jeon 871b87d8dbfSGirish K S /* 872577fb131SSeungwon Jeon * Set the bus speed for the selected speed mode. 873a4924c71SGirish K S */ 874577fb131SSeungwon Jeon static void mmc_set_bus_speed(struct mmc_card *card) 875a4924c71SGirish K S { 876577fb131SSeungwon Jeon unsigned int max_dtr = (unsigned int)-1; 877577fb131SSeungwon Jeon 8780a5b6438SSeungwon Jeon if ((mmc_card_hs200(card) || mmc_card_hs400(card)) && 8790a5b6438SSeungwon Jeon max_dtr > card->ext_csd.hs200_max_dtr) 880577fb131SSeungwon Jeon max_dtr = card->ext_csd.hs200_max_dtr; 881577fb131SSeungwon Jeon else if (mmc_card_hs(card) && max_dtr > card->ext_csd.hs_max_dtr) 882577fb131SSeungwon Jeon max_dtr = card->ext_csd.hs_max_dtr; 883577fb131SSeungwon Jeon else if (max_dtr > card->csd.max_dtr) 884577fb131SSeungwon Jeon max_dtr = card->csd.max_dtr; 885577fb131SSeungwon Jeon 886577fb131SSeungwon Jeon mmc_set_clock(card->host, max_dtr); 887577fb131SSeungwon Jeon } 888577fb131SSeungwon Jeon 889577fb131SSeungwon Jeon /* 890577fb131SSeungwon Jeon * Select the bus width amoung 4-bit and 8-bit(SDR). 891577fb131SSeungwon Jeon * If the bus width is changed successfully, return the selected width value. 892577fb131SSeungwon Jeon * Zero is returned instead of error value if the wide width is not supported. 893577fb131SSeungwon Jeon */ 894577fb131SSeungwon Jeon static int mmc_select_bus_width(struct mmc_card *card) 895577fb131SSeungwon Jeon { 896a4924c71SGirish K S static unsigned ext_csd_bits[] = { 897a4924c71SGirish K S EXT_CSD_BUS_WIDTH_8, 898577fb131SSeungwon Jeon EXT_CSD_BUS_WIDTH_4, 899a4924c71SGirish K S }; 900a4924c71SGirish K S static unsigned bus_widths[] = { 901a4924c71SGirish K S MMC_BUS_WIDTH_8, 902577fb131SSeungwon Jeon MMC_BUS_WIDTH_4, 903a4924c71SGirish K S }; 904577fb131SSeungwon Jeon struct mmc_host *host = card->host; 905577fb131SSeungwon Jeon unsigned idx, bus_width = 0; 906577fb131SSeungwon Jeon int err = 0; 907a4924c71SGirish K S 908577fb131SSeungwon Jeon if ((card->csd.mmca_vsn < CSD_SPEC_VER_4) && 909577fb131SSeungwon Jeon !(host->caps & (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA))) 910577fb131SSeungwon Jeon return 0; 911a4924c71SGirish K S 912577fb131SSeungwon Jeon idx = (host->caps & MMC_CAP_8_BIT_DATA) ? 0 : 1; 913a4924c71SGirish K S 914a4924c71SGirish K S /* 915a4924c71SGirish K S * Unlike SD, MMC cards dont have a configuration register to notify 916a4924c71SGirish K S * supported bus width. So bus test command should be run to identify 917a4924c71SGirish K S * the supported bus width or compare the ext csd values of current 918a4924c71SGirish K S * bus width and ext csd values of 1 bit mode read earlier. 919a4924c71SGirish K S */ 920577fb131SSeungwon Jeon for (; idx < ARRAY_SIZE(bus_widths); idx++) { 921a4924c71SGirish K S /* 922a4924c71SGirish K S * Host is capable of 8bit transfer, then switch 923a4924c71SGirish K S * the device to work in 8bit transfer mode. If the 924a4924c71SGirish K S * mmc switch command returns error then switch to 925a4924c71SGirish K S * 4bit transfer mode. On success set the corresponding 926a4924c71SGirish K S * bus width on the host. 927a4924c71SGirish K S */ 928a4924c71SGirish K S err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, 929a4924c71SGirish K S EXT_CSD_BUS_WIDTH, 930a4924c71SGirish K S ext_csd_bits[idx], 931a4924c71SGirish K S card->ext_csd.generic_cmd6_time); 932a4924c71SGirish K S if (err) 933a4924c71SGirish K S continue; 934a4924c71SGirish K S 935577fb131SSeungwon Jeon bus_width = bus_widths[idx]; 936577fb131SSeungwon Jeon mmc_set_bus_width(host, bus_width); 937a4924c71SGirish K S 938577fb131SSeungwon Jeon /* 939577fb131SSeungwon Jeon * If controller can't handle bus width test, 940577fb131SSeungwon Jeon * compare ext_csd previously read in 1 bit mode 941577fb131SSeungwon Jeon * against ext_csd at new bus width 942577fb131SSeungwon Jeon */ 943a4924c71SGirish K S if (!(host->caps & MMC_CAP_BUS_WIDTH_TEST)) 944577fb131SSeungwon Jeon err = mmc_compare_ext_csds(card, bus_width); 945a4924c71SGirish K S else 946577fb131SSeungwon Jeon err = mmc_bus_test(card, bus_width); 947577fb131SSeungwon Jeon 948577fb131SSeungwon Jeon if (!err) { 949577fb131SSeungwon Jeon err = bus_width; 950a4924c71SGirish K S break; 951577fb131SSeungwon Jeon } else { 952577fb131SSeungwon Jeon pr_warn("%s: switch to bus width %d failed\n", 953577fb131SSeungwon Jeon mmc_hostname(host), ext_csd_bits[idx]); 954577fb131SSeungwon Jeon } 955a4924c71SGirish K S } 956a4924c71SGirish K S 957577fb131SSeungwon Jeon return err; 958577fb131SSeungwon Jeon } 959577fb131SSeungwon Jeon 960577fb131SSeungwon Jeon /* 961577fb131SSeungwon Jeon * Switch to the high-speed mode 962577fb131SSeungwon Jeon */ 963577fb131SSeungwon Jeon static int mmc_select_hs(struct mmc_card *card) 964577fb131SSeungwon Jeon { 965577fb131SSeungwon Jeon int err; 966577fb131SSeungwon Jeon 9674509f847SUlf Hansson err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, 968577fb131SSeungwon Jeon EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS, 96957de31f6SUlf Hansson card->ext_csd.generic_cmd6_time, 97057de31f6SUlf Hansson true, true, true); 971577fb131SSeungwon Jeon if (!err) 972577fb131SSeungwon Jeon mmc_set_timing(card->host, MMC_TIMING_MMC_HS); 973577fb131SSeungwon Jeon 974577fb131SSeungwon Jeon return err; 975577fb131SSeungwon Jeon } 976577fb131SSeungwon Jeon 977577fb131SSeungwon Jeon /* 978577fb131SSeungwon Jeon * Activate wide bus and DDR if supported. 979577fb131SSeungwon Jeon */ 980577fb131SSeungwon Jeon static int mmc_select_hs_ddr(struct mmc_card *card) 981577fb131SSeungwon Jeon { 982577fb131SSeungwon Jeon struct mmc_host *host = card->host; 983577fb131SSeungwon Jeon u32 bus_width, ext_csd_bits; 984577fb131SSeungwon Jeon int err = 0; 985577fb131SSeungwon Jeon 986577fb131SSeungwon Jeon if (!(card->mmc_avail_type & EXT_CSD_CARD_TYPE_DDR_52)) 987577fb131SSeungwon Jeon return 0; 988577fb131SSeungwon Jeon 989577fb131SSeungwon Jeon bus_width = host->ios.bus_width; 990577fb131SSeungwon Jeon if (bus_width == MMC_BUS_WIDTH_1) 991577fb131SSeungwon Jeon return 0; 992577fb131SSeungwon Jeon 993577fb131SSeungwon Jeon ext_csd_bits = (bus_width == MMC_BUS_WIDTH_8) ? 994577fb131SSeungwon Jeon EXT_CSD_DDR_BUS_WIDTH_8 : EXT_CSD_DDR_BUS_WIDTH_4; 995577fb131SSeungwon Jeon 996577fb131SSeungwon Jeon err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, 997577fb131SSeungwon Jeon EXT_CSD_BUS_WIDTH, 998577fb131SSeungwon Jeon ext_csd_bits, 999577fb131SSeungwon Jeon card->ext_csd.generic_cmd6_time); 1000577fb131SSeungwon Jeon if (err) { 10014b75bffcSAndrew Gabbasov pr_err("%s: switch to bus width %d ddr failed\n", 1002577fb131SSeungwon Jeon mmc_hostname(host), 1 << bus_width); 1003577fb131SSeungwon Jeon return err; 1004577fb131SSeungwon Jeon } 1005577fb131SSeungwon Jeon 1006577fb131SSeungwon Jeon /* 1007577fb131SSeungwon Jeon * eMMC cards can support 3.3V to 1.2V i/o (vccq) 1008577fb131SSeungwon Jeon * signaling. 1009577fb131SSeungwon Jeon * 1010577fb131SSeungwon Jeon * EXT_CSD_CARD_TYPE_DDR_1_8V means 3.3V or 1.8V vccq. 1011577fb131SSeungwon Jeon * 1012577fb131SSeungwon Jeon * 1.8V vccq at 3.3V core voltage (vcc) is not required 1013577fb131SSeungwon Jeon * in the JEDEC spec for DDR. 1014577fb131SSeungwon Jeon * 1015312449efSChuanxiao.Dong * Even (e)MMC card can support 3.3v to 1.2v vccq, but not all 1016312449efSChuanxiao.Dong * host controller can support this, like some of the SDHCI 1017312449efSChuanxiao.Dong * controller which connect to an eMMC device. Some of these 1018312449efSChuanxiao.Dong * host controller still needs to use 1.8v vccq for supporting 1019312449efSChuanxiao.Dong * DDR mode. 1020312449efSChuanxiao.Dong * 1021312449efSChuanxiao.Dong * So the sequence will be: 1022312449efSChuanxiao.Dong * if (host and device can both support 1.2v IO) 1023312449efSChuanxiao.Dong * use 1.2v IO; 1024312449efSChuanxiao.Dong * else if (host and device can both support 1.8v IO) 1025312449efSChuanxiao.Dong * use 1.8v IO; 1026312449efSChuanxiao.Dong * so if host and device can only support 3.3v IO, this is the 1027312449efSChuanxiao.Dong * last choice. 1028577fb131SSeungwon Jeon * 1029577fb131SSeungwon Jeon * WARNING: eMMC rules are NOT the same as SD DDR 1030577fb131SSeungwon Jeon */ 1031312449efSChuanxiao.Dong err = -EINVAL; 1032312449efSChuanxiao.Dong if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_DDR_1_2V) 1033312449efSChuanxiao.Dong err = __mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_120); 1034577fb131SSeungwon Jeon 1035312449efSChuanxiao.Dong if (err && (card->mmc_avail_type & EXT_CSD_CARD_TYPE_DDR_1_8V)) 1036312449efSChuanxiao.Dong err = __mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180); 1037312449efSChuanxiao.Dong 1038312449efSChuanxiao.Dong /* make sure vccq is 3.3v after switching disaster */ 1039312449efSChuanxiao.Dong if (err) 1040312449efSChuanxiao.Dong err = __mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_330); 1041312449efSChuanxiao.Dong 1042312449efSChuanxiao.Dong if (!err) 1043577fb131SSeungwon Jeon mmc_set_timing(host, MMC_TIMING_MMC_DDR52); 1044577fb131SSeungwon Jeon 1045577fb131SSeungwon Jeon return err; 1046577fb131SSeungwon Jeon } 1047577fb131SSeungwon Jeon 10480a5b6438SSeungwon Jeon static int mmc_select_hs400(struct mmc_card *card) 10490a5b6438SSeungwon Jeon { 10500a5b6438SSeungwon Jeon struct mmc_host *host = card->host; 10510a5b6438SSeungwon Jeon int err = 0; 10520a5b6438SSeungwon Jeon 10530a5b6438SSeungwon Jeon /* 10540a5b6438SSeungwon Jeon * HS400 mode requires 8-bit bus width 10550a5b6438SSeungwon Jeon */ 10560a5b6438SSeungwon Jeon if (!(card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400 && 10570a5b6438SSeungwon Jeon host->ios.bus_width == MMC_BUS_WIDTH_8)) 10580a5b6438SSeungwon Jeon return 0; 10590a5b6438SSeungwon Jeon 10600a5b6438SSeungwon Jeon /* 10610a5b6438SSeungwon Jeon * Before switching to dual data rate operation for HS400, 10620a5b6438SSeungwon Jeon * it is required to convert from HS200 mode to HS mode. 10630a5b6438SSeungwon Jeon */ 10640a5b6438SSeungwon Jeon mmc_set_timing(card->host, MMC_TIMING_MMC_HS); 10650a5b6438SSeungwon Jeon mmc_set_bus_speed(card); 10660a5b6438SSeungwon Jeon 10670a5b6438SSeungwon Jeon err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, 10680a5b6438SSeungwon Jeon EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS, 10690a5b6438SSeungwon Jeon card->ext_csd.generic_cmd6_time, 10700a5b6438SSeungwon Jeon true, true, true); 10710a5b6438SSeungwon Jeon if (err) { 10724b75bffcSAndrew Gabbasov pr_err("%s: switch to high-speed from hs200 failed, err:%d\n", 10730a5b6438SSeungwon Jeon mmc_hostname(host), err); 10740a5b6438SSeungwon Jeon return err; 10750a5b6438SSeungwon Jeon } 10760a5b6438SSeungwon Jeon 10770a5b6438SSeungwon Jeon err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, 10780a5b6438SSeungwon Jeon EXT_CSD_BUS_WIDTH, 10790a5b6438SSeungwon Jeon EXT_CSD_DDR_BUS_WIDTH_8, 10800a5b6438SSeungwon Jeon card->ext_csd.generic_cmd6_time); 10810a5b6438SSeungwon Jeon if (err) { 10824b75bffcSAndrew Gabbasov pr_err("%s: switch to bus width for hs400 failed, err:%d\n", 10830a5b6438SSeungwon Jeon mmc_hostname(host), err); 10840a5b6438SSeungwon Jeon return err; 10850a5b6438SSeungwon Jeon } 10860a5b6438SSeungwon Jeon 10870a5b6438SSeungwon Jeon err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, 10880a5b6438SSeungwon Jeon EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS400, 10890a5b6438SSeungwon Jeon card->ext_csd.generic_cmd6_time, 10900a5b6438SSeungwon Jeon true, true, true); 10910a5b6438SSeungwon Jeon if (err) { 10924b75bffcSAndrew Gabbasov pr_err("%s: switch to hs400 failed, err:%d\n", 10930a5b6438SSeungwon Jeon mmc_hostname(host), err); 10940a5b6438SSeungwon Jeon return err; 10950a5b6438SSeungwon Jeon } 10960a5b6438SSeungwon Jeon 10970a5b6438SSeungwon Jeon mmc_set_timing(host, MMC_TIMING_MMC_HS400); 10980a5b6438SSeungwon Jeon mmc_set_bus_speed(card); 10990a5b6438SSeungwon Jeon 11000a5b6438SSeungwon Jeon return 0; 11010a5b6438SSeungwon Jeon } 11020a5b6438SSeungwon Jeon 1103577fb131SSeungwon Jeon /* 1104577fb131SSeungwon Jeon * For device supporting HS200 mode, the following sequence 1105577fb131SSeungwon Jeon * should be done before executing the tuning process. 1106577fb131SSeungwon Jeon * 1. set the desired bus width(4-bit or 8-bit, 1-bit is not supported) 1107577fb131SSeungwon Jeon * 2. switch to HS200 mode 1108577fb131SSeungwon Jeon * 3. set the clock to > 52Mhz and <=200MHz 1109577fb131SSeungwon Jeon */ 1110577fb131SSeungwon Jeon static int mmc_select_hs200(struct mmc_card *card) 1111577fb131SSeungwon Jeon { 1112577fb131SSeungwon Jeon struct mmc_host *host = card->host; 1113577fb131SSeungwon Jeon int err = -EINVAL; 1114577fb131SSeungwon Jeon 1115577fb131SSeungwon Jeon if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS200_1_2V) 1116577fb131SSeungwon Jeon err = __mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_120); 1117577fb131SSeungwon Jeon 1118577fb131SSeungwon Jeon if (err && card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS200_1_8V) 1119577fb131SSeungwon Jeon err = __mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180); 1120577fb131SSeungwon Jeon 1121577fb131SSeungwon Jeon /* If fails try again during next card power cycle */ 1122577fb131SSeungwon Jeon if (err) 1123577fb131SSeungwon Jeon goto err; 1124577fb131SSeungwon Jeon 1125577fb131SSeungwon Jeon /* 1126577fb131SSeungwon Jeon * Set the bus width(4 or 8) with host's support and 1127577fb131SSeungwon Jeon * switch to HS200 mode if bus width is set successfully. 1128577fb131SSeungwon Jeon */ 1129577fb131SSeungwon Jeon err = mmc_select_bus_width(card); 1130577fb131SSeungwon Jeon if (!IS_ERR_VALUE(err)) { 1131577fb131SSeungwon Jeon err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, 1132577fb131SSeungwon Jeon EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS200, 1133577fb131SSeungwon Jeon card->ext_csd.generic_cmd6_time, 1134577fb131SSeungwon Jeon true, true, true); 1135577fb131SSeungwon Jeon if (!err) 1136577fb131SSeungwon Jeon mmc_set_timing(host, MMC_TIMING_MMC_HS200); 1137577fb131SSeungwon Jeon } 1138a4924c71SGirish K S err: 1139a4924c71SGirish K S return err; 1140a4924c71SGirish K S } 1141a4924c71SGirish K S 1142a4924c71SGirish K S /* 1143577fb131SSeungwon Jeon * Activate High Speed or HS200 mode if supported. 1144577fb131SSeungwon Jeon */ 1145577fb131SSeungwon Jeon static int mmc_select_timing(struct mmc_card *card) 1146577fb131SSeungwon Jeon { 1147577fb131SSeungwon Jeon int err = 0; 1148577fb131SSeungwon Jeon 1149577fb131SSeungwon Jeon if ((card->csd.mmca_vsn < CSD_SPEC_VER_4 && 1150577fb131SSeungwon Jeon card->ext_csd.hs_max_dtr == 0)) 1151577fb131SSeungwon Jeon goto bus_speed; 1152577fb131SSeungwon Jeon 1153577fb131SSeungwon Jeon if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS200) 1154577fb131SSeungwon Jeon err = mmc_select_hs200(card); 1155577fb131SSeungwon Jeon else if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS) 1156577fb131SSeungwon Jeon err = mmc_select_hs(card); 1157577fb131SSeungwon Jeon 1158577fb131SSeungwon Jeon if (err && err != -EBADMSG) 1159577fb131SSeungwon Jeon return err; 1160577fb131SSeungwon Jeon 1161577fb131SSeungwon Jeon if (err) { 1162577fb131SSeungwon Jeon pr_warn("%s: switch to %s failed\n", 1163577fb131SSeungwon Jeon mmc_card_hs(card) ? "high-speed" : 1164577fb131SSeungwon Jeon (mmc_card_hs200(card) ? "hs200" : ""), 1165577fb131SSeungwon Jeon mmc_hostname(card->host)); 1166577fb131SSeungwon Jeon err = 0; 1167577fb131SSeungwon Jeon } 1168577fb131SSeungwon Jeon 1169577fb131SSeungwon Jeon bus_speed: 1170577fb131SSeungwon Jeon /* 1171577fb131SSeungwon Jeon * Set the bus speed to the selected bus timing. 1172577fb131SSeungwon Jeon * If timing is not selected, backward compatible is the default. 1173577fb131SSeungwon Jeon */ 1174577fb131SSeungwon Jeon mmc_set_bus_speed(card); 1175577fb131SSeungwon Jeon return err; 1176577fb131SSeungwon Jeon } 1177577fb131SSeungwon Jeon 117848d11e06SStephen Boyd const u8 tuning_blk_pattern_4bit[MMC_TUNING_BLK_PATTERN_4BIT_SIZE] = { 117948d11e06SStephen Boyd 0xff, 0x0f, 0xff, 0x00, 0xff, 0xcc, 0xc3, 0xcc, 118048d11e06SStephen Boyd 0xc3, 0x3c, 0xcc, 0xff, 0xfe, 0xff, 0xfe, 0xef, 118148d11e06SStephen Boyd 0xff, 0xdf, 0xff, 0xdd, 0xff, 0xfb, 0xff, 0xfb, 118248d11e06SStephen Boyd 0xbf, 0xff, 0x7f, 0xff, 0x77, 0xf7, 0xbd, 0xef, 118348d11e06SStephen Boyd 0xff, 0xf0, 0xff, 0xf0, 0x0f, 0xfc, 0xcc, 0x3c, 118448d11e06SStephen Boyd 0xcc, 0x33, 0xcc, 0xcf, 0xff, 0xef, 0xff, 0xee, 118548d11e06SStephen Boyd 0xff, 0xfd, 0xff, 0xfd, 0xdf, 0xff, 0xbf, 0xff, 118648d11e06SStephen Boyd 0xbb, 0xff, 0xf7, 0xff, 0xf7, 0x7f, 0x7b, 0xde, 118748d11e06SStephen Boyd }; 118848d11e06SStephen Boyd EXPORT_SYMBOL(tuning_blk_pattern_4bit); 118948d11e06SStephen Boyd 119048d11e06SStephen Boyd const u8 tuning_blk_pattern_8bit[MMC_TUNING_BLK_PATTERN_8BIT_SIZE] = { 119148d11e06SStephen Boyd 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 119248d11e06SStephen Boyd 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc, 0xcc, 119348d11e06SStephen Boyd 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff, 0xff, 119448d11e06SStephen Boyd 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee, 0xff, 119548d11e06SStephen Boyd 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd, 0xdd, 119648d11e06SStephen Boyd 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb, 119748d11e06SStephen Boyd 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff, 0xff, 119848d11e06SStephen Boyd 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee, 0xff, 119948d11e06SStephen Boyd 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 120048d11e06SStephen Boyd 0x00, 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc, 120148d11e06SStephen Boyd 0xcc, 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff, 120248d11e06SStephen Boyd 0xff, 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee, 120348d11e06SStephen Boyd 0xff, 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd, 120448d11e06SStephen Boyd 0xdd, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, 120548d11e06SStephen Boyd 0xbb, 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff, 120648d11e06SStephen Boyd 0xff, 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee, 120748d11e06SStephen Boyd }; 120848d11e06SStephen Boyd EXPORT_SYMBOL(tuning_blk_pattern_8bit); 120948d11e06SStephen Boyd 1210577fb131SSeungwon Jeon /* 1211577fb131SSeungwon Jeon * Execute tuning sequence to seek the proper bus operating 12120a5b6438SSeungwon Jeon * conditions for HS200 and HS400, which sends CMD21 to the device. 1213577fb131SSeungwon Jeon */ 1214577fb131SSeungwon Jeon static int mmc_hs200_tuning(struct mmc_card *card) 1215577fb131SSeungwon Jeon { 1216577fb131SSeungwon Jeon struct mmc_host *host = card->host; 1217577fb131SSeungwon Jeon int err = 0; 1218577fb131SSeungwon Jeon 12190a5b6438SSeungwon Jeon /* 12200a5b6438SSeungwon Jeon * Timing should be adjusted to the HS400 target 12210a5b6438SSeungwon Jeon * operation frequency for tuning process 12220a5b6438SSeungwon Jeon */ 12230a5b6438SSeungwon Jeon if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400 && 12240a5b6438SSeungwon Jeon host->ios.bus_width == MMC_BUS_WIDTH_8) 12250a5b6438SSeungwon Jeon if (host->ops->prepare_hs400_tuning) 12260a5b6438SSeungwon Jeon host->ops->prepare_hs400_tuning(host, &host->ios); 12270a5b6438SSeungwon Jeon 1228577fb131SSeungwon Jeon if (host->ops->execute_tuning) { 1229577fb131SSeungwon Jeon mmc_host_clk_hold(host); 1230577fb131SSeungwon Jeon err = host->ops->execute_tuning(host, 1231577fb131SSeungwon Jeon MMC_SEND_TUNING_BLOCK_HS200); 1232577fb131SSeungwon Jeon mmc_host_clk_release(host); 1233577fb131SSeungwon Jeon 1234577fb131SSeungwon Jeon if (err) 12354b75bffcSAndrew Gabbasov pr_err("%s: tuning execution failed\n", 1236577fb131SSeungwon Jeon mmc_hostname(host)); 1237577fb131SSeungwon Jeon } 1238577fb131SSeungwon Jeon 1239577fb131SSeungwon Jeon return err; 1240577fb131SSeungwon Jeon } 1241577fb131SSeungwon Jeon 1242577fb131SSeungwon Jeon /* 12436abaa0c9SPierre Ossman * Handle the detection and initialisation of a card. 12446abaa0c9SPierre Ossman * 12458769392bSDeepak Saxena * In the case of a resume, "oldcard" will contain the card 12466abaa0c9SPierre Ossman * we're trying to reinitialise. 12477ea239d9SPierre Ossman */ 12488c75deaeSPierre Ossman static int mmc_init_card(struct mmc_host *host, u32 ocr, 12496abaa0c9SPierre Ossman struct mmc_card *oldcard) 12507ea239d9SPierre Ossman { 12517ea239d9SPierre Ossman struct mmc_card *card; 1252577fb131SSeungwon Jeon int err; 12537ea239d9SPierre Ossman u32 cid[4]; 1254b676f039SPhilip Rakity u32 rocr; 125508ee80ccSPhilip Rakity u8 *ext_csd = NULL; 12567ea239d9SPierre Ossman 12577ea239d9SPierre Ossman BUG_ON(!host); 1258d84075c8SPierre Ossman WARN_ON(!host->claimed); 12597ea239d9SPierre Ossman 126044669034SStefan Nilsson XK /* Set correct bus mode for MMC before attempting init */ 126144669034SStefan Nilsson XK if (!mmc_host_is_spi(host)) 126244669034SStefan Nilsson XK mmc_set_bus_mode(host, MMC_BUSMODE_OPENDRAIN); 126344669034SStefan Nilsson XK 12647ea239d9SPierre Ossman /* 12657ea239d9SPierre Ossman * Since we're changing the OCR value, we seem to 12667ea239d9SPierre Ossman * need to tell some cards to go back to the idle 12677ea239d9SPierre Ossman * state. We wait 1ms to give cards time to 12687ea239d9SPierre Ossman * respond. 1269c3805467SBalaji T K * mmc_go_idle is needed for eMMC that are asleep 12707ea239d9SPierre Ossman */ 12717ea239d9SPierre Ossman mmc_go_idle(host); 12727ea239d9SPierre Ossman 12737ea239d9SPierre Ossman /* The extra bit indicates that we support high capacity */ 1274b676f039SPhilip Rakity err = mmc_send_op_cond(host, ocr | (1 << 30), &rocr); 127517b0429dSPierre Ossman if (err) 12766abaa0c9SPierre Ossman goto err; 12777ea239d9SPierre Ossman 12787ea239d9SPierre Ossman /* 1279af517150SDavid Brownell * For SPI, enable CRC as appropriate. 1280af517150SDavid Brownell */ 1281af517150SDavid Brownell if (mmc_host_is_spi(host)) { 1282af517150SDavid Brownell err = mmc_spi_set_crc(host, use_spi_crc); 1283af517150SDavid Brownell if (err) 1284af517150SDavid Brownell goto err; 1285af517150SDavid Brownell } 1286af517150SDavid Brownell 1287af517150SDavid Brownell /* 12887ea239d9SPierre Ossman * Fetch CID from card. 12897ea239d9SPierre Ossman */ 1290af517150SDavid Brownell if (mmc_host_is_spi(host)) 1291af517150SDavid Brownell err = mmc_send_cid(host, cid); 1292af517150SDavid Brownell else 12937ea239d9SPierre Ossman err = mmc_all_send_cid(host, cid); 129417b0429dSPierre Ossman if (err) 12957ea239d9SPierre Ossman goto err; 12967ea239d9SPierre Ossman 12976abaa0c9SPierre Ossman if (oldcard) { 1298adf66a0dSPierre Ossman if (memcmp(cid, oldcard->raw_cid, sizeof(cid)) != 0) { 1299adf66a0dSPierre Ossman err = -ENOENT; 13006abaa0c9SPierre Ossman goto err; 1301adf66a0dSPierre Ossman } 13026abaa0c9SPierre Ossman 13036abaa0c9SPierre Ossman card = oldcard; 13046abaa0c9SPierre Ossman } else { 13057ea239d9SPierre Ossman /* 13067ea239d9SPierre Ossman * Allocate card structure. 13077ea239d9SPierre Ossman */ 130851ec92e2SPierre Ossman card = mmc_alloc_card(host, &mmc_type); 1309adf66a0dSPierre Ossman if (IS_ERR(card)) { 1310adf66a0dSPierre Ossman err = PTR_ERR(card); 13117ea239d9SPierre Ossman goto err; 1312adf66a0dSPierre Ossman } 13137ea239d9SPierre Ossman 131469041150SUlf Hansson card->ocr = ocr; 13157ea239d9SPierre Ossman card->type = MMC_TYPE_MMC; 13167ea239d9SPierre Ossman card->rca = 1; 13177ea239d9SPierre Ossman memcpy(card->raw_cid, cid, sizeof(card->raw_cid)); 13186abaa0c9SPierre Ossman } 13197ea239d9SPierre Ossman 13207ea239d9SPierre Ossman /* 1321af517150SDavid Brownell * For native busses: set card RCA and quit open drain mode. 13227ea239d9SPierre Ossman */ 1323af517150SDavid Brownell if (!mmc_host_is_spi(host)) { 13247ea239d9SPierre Ossman err = mmc_set_relative_addr(card); 132517b0429dSPierre Ossman if (err) 13267ea239d9SPierre Ossman goto free_card; 13277ea239d9SPierre Ossman 13287ea239d9SPierre Ossman mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL); 1329af517150SDavid Brownell } 13307ea239d9SPierre Ossman 13316abaa0c9SPierre Ossman if (!oldcard) { 13327ea239d9SPierre Ossman /* 13337ea239d9SPierre Ossman * Fetch CSD from card. 13347ea239d9SPierre Ossman */ 13357ea239d9SPierre Ossman err = mmc_send_csd(card, card->raw_csd); 133617b0429dSPierre Ossman if (err) 13377ea239d9SPierre Ossman goto free_card; 13387ea239d9SPierre Ossman 1339bd766312SPierre Ossman err = mmc_decode_csd(card); 1340adf66a0dSPierre Ossman if (err) 1341bd766312SPierre Ossman goto free_card; 1342bd766312SPierre Ossman err = mmc_decode_cid(card); 1343adf66a0dSPierre Ossman if (err) 1344bd766312SPierre Ossman goto free_card; 13456abaa0c9SPierre Ossman } 13467ea239d9SPierre Ossman 13477ea239d9SPierre Ossman /* 13483d705d14SSascha Hauer * handling only for cards supporting DSR and hosts requesting 13493d705d14SSascha Hauer * DSR configuration 13503d705d14SSascha Hauer */ 13513d705d14SSascha Hauer if (card->csd.dsr_imp && host->dsr_req) 13523d705d14SSascha Hauer mmc_set_dsr(host); 13533d705d14SSascha Hauer 13543d705d14SSascha Hauer /* 135589a73cf5SPierre Ossman * Select card, as all following commands rely on that. 13567ea239d9SPierre Ossman */ 1357af517150SDavid Brownell if (!mmc_host_is_spi(host)) { 13587ea239d9SPierre Ossman err = mmc_select_card(card); 135917b0429dSPierre Ossman if (err) 13607ea239d9SPierre Ossman goto free_card; 1361af517150SDavid Brownell } 13627ea239d9SPierre Ossman 13636abaa0c9SPierre Ossman if (!oldcard) { 136489a73cf5SPierre Ossman /* 1365af517150SDavid Brownell * Fetch and process extended CSD. 136689a73cf5SPierre Ossman */ 136708ee80ccSPhilip Rakity 136808ee80ccSPhilip Rakity err = mmc_get_ext_csd(card, &ext_csd); 136908ee80ccSPhilip Rakity if (err) 137008ee80ccSPhilip Rakity goto free_card; 137108ee80ccSPhilip Rakity err = mmc_read_ext_csd(card, ext_csd); 137217b0429dSPierre Ossman if (err) 13737ea239d9SPierre Ossman goto free_card; 1374b676f039SPhilip Rakity 1375b676f039SPhilip Rakity /* If doing byte addressing, check if required to do sector 1376b676f039SPhilip Rakity * addressing. Handle the case of <2GB cards needing sector 1377b676f039SPhilip Rakity * addressing. See section 8.1 JEDEC Standard JED84-A441; 1378b676f039SPhilip Rakity * ocr register has bit 30 set for sector addressing. 1379b676f039SPhilip Rakity */ 1380b676f039SPhilip Rakity if (!(mmc_card_blockaddr(card)) && (rocr & (1<<30))) 1381b676f039SPhilip Rakity mmc_card_set_blockaddr(card); 1382b676f039SPhilip Rakity 1383dfe86cbaSAdrian Hunter /* Erase size depends on CSD and Extended CSD */ 1384dfe86cbaSAdrian Hunter mmc_set_erase_size(card); 13856abaa0c9SPierre Ossman } 13867ea239d9SPierre Ossman 13877ea239d9SPierre Ossman /* 1388709de99dSChuanxiao Dong * If enhanced_area_en is TRUE, host needs to enable ERASE_GRP_DEF 1389709de99dSChuanxiao Dong * bit. This bit will be lost every time after a reset or power off. 1390709de99dSChuanxiao Dong */ 139169803d4fSGrégory Soutadé if (card->ext_csd.partition_setting_completed || 139283bb24aaSAdrian Hunter (card->ext_csd.rev >= 3 && (host->caps2 & MMC_CAP2_HC_ERASE_SZ))) { 1393709de99dSChuanxiao Dong err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, 1394b23cf0bdSSeungwon Jeon EXT_CSD_ERASE_GROUP_DEF, 1, 1395b23cf0bdSSeungwon Jeon card->ext_csd.generic_cmd6_time); 1396709de99dSChuanxiao Dong 1397709de99dSChuanxiao Dong if (err && err != -EBADMSG) 1398709de99dSChuanxiao Dong goto free_card; 1399709de99dSChuanxiao Dong 1400709de99dSChuanxiao Dong if (err) { 1401709de99dSChuanxiao Dong err = 0; 1402709de99dSChuanxiao Dong /* 1403709de99dSChuanxiao Dong * Just disable enhanced area off & sz 1404709de99dSChuanxiao Dong * will try to enable ERASE_GROUP_DEF 1405709de99dSChuanxiao Dong * during next time reinit 1406709de99dSChuanxiao Dong */ 1407709de99dSChuanxiao Dong card->ext_csd.enhanced_area_offset = -EINVAL; 1408709de99dSChuanxiao Dong card->ext_csd.enhanced_area_size = -EINVAL; 1409709de99dSChuanxiao Dong } else { 1410709de99dSChuanxiao Dong card->ext_csd.erase_group_def = 1; 1411709de99dSChuanxiao Dong /* 1412709de99dSChuanxiao Dong * enable ERASE_GRP_DEF successfully. 1413709de99dSChuanxiao Dong * This will affect the erase size, so 1414709de99dSChuanxiao Dong * here need to reset erase size 1415709de99dSChuanxiao Dong */ 1416709de99dSChuanxiao Dong mmc_set_erase_size(card); 1417709de99dSChuanxiao Dong } 1418709de99dSChuanxiao Dong } 1419709de99dSChuanxiao Dong 1420709de99dSChuanxiao Dong /* 142141e2a489SPhilip Rakity * Ensure eMMC user default partition is enabled 142241e2a489SPhilip Rakity */ 1423371a689fSAndrei Warkentin if (card->ext_csd.part_config & EXT_CSD_PART_CONFIG_ACC_MASK) { 1424371a689fSAndrei Warkentin card->ext_csd.part_config &= ~EXT_CSD_PART_CONFIG_ACC_MASK; 1425371a689fSAndrei Warkentin err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONFIG, 1426371a689fSAndrei Warkentin card->ext_csd.part_config, 1427371a689fSAndrei Warkentin card->ext_csd.part_time); 1428371a689fSAndrei Warkentin if (err && err != -EBADMSG) 1429371a689fSAndrei Warkentin goto free_card; 143041e2a489SPhilip Rakity } 143141e2a489SPhilip Rakity 143241e2a489SPhilip Rakity /* 143343235679SUlf Hansson * Enable power_off_notification byte in the ext_csd register 1434bec8726aSGirish K S */ 143543235679SUlf Hansson if (card->ext_csd.rev >= 6) { 1436bec8726aSGirish K S err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, 1437bec8726aSGirish K S EXT_CSD_POWER_OFF_NOTIFICATION, 1438bec8726aSGirish K S EXT_CSD_POWER_ON, 1439bec8726aSGirish K S card->ext_csd.generic_cmd6_time); 1440bec8726aSGirish K S if (err && err != -EBADMSG) 1441bec8726aSGirish K S goto free_card; 1442bec8726aSGirish K S 144396a85d54SGirish K S /* 144496a85d54SGirish K S * The err can be -EBADMSG or 0, 144596a85d54SGirish K S * so check for success and update the flag 144696a85d54SGirish K S */ 1447bec8726aSGirish K S if (!err) 1448e6c08586SUlf Hansson card->ext_csd.power_off_notification = EXT_CSD_POWER_ON; 144996a85d54SGirish K S } 1450bec8726aSGirish K S 1451bec8726aSGirish K S /* 1452577fb131SSeungwon Jeon * Select timing interface 145389a73cf5SPierre Ossman */ 1454577fb131SSeungwon Jeon err = mmc_select_timing(card); 1455577fb131SSeungwon Jeon if (err) 145689a73cf5SPierre Ossman goto free_card; 145789a73cf5SPierre Ossman 1458a4924c71SGirish K S if (mmc_card_hs200(card)) { 1459577fb131SSeungwon Jeon err = mmc_hs200_tuning(card); 14604c4cb171SPhilip Rakity if (err) 14614b75bffcSAndrew Gabbasov goto free_card; 14620a5b6438SSeungwon Jeon 14630a5b6438SSeungwon Jeon err = mmc_select_hs400(card); 14640a5b6438SSeungwon Jeon if (err) 14654b75bffcSAndrew Gabbasov goto free_card; 1466577fb131SSeungwon Jeon } else if (mmc_card_hs(card)) { 1467577fb131SSeungwon Jeon /* Select the desired bus width optionally */ 1468577fb131SSeungwon Jeon err = mmc_select_bus_width(card); 1469577fb131SSeungwon Jeon if (!IS_ERR_VALUE(err)) { 1470577fb131SSeungwon Jeon err = mmc_select_hs_ddr(card); 1471577fb131SSeungwon Jeon if (err) 14724b75bffcSAndrew Gabbasov goto free_card; 147389a73cf5SPierre Ossman } 1474ef0b27d4SAdrian Hunter } 147589a73cf5SPierre Ossman 1476881d1c25SSeungwon Jeon /* 14772385049dSSeungwon Jeon * Choose the power class with selected bus interface 14782385049dSSeungwon Jeon */ 14792385049dSSeungwon Jeon mmc_select_powerclass(card); 14802385049dSSeungwon Jeon 14812385049dSSeungwon Jeon /* 148252d0974eSSubhash Jadavani * Enable HPI feature (if supported) 148352d0974eSSubhash Jadavani */ 148452d0974eSSubhash Jadavani if (card->ext_csd.hpi) { 148552d0974eSSubhash Jadavani err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, 148652d0974eSSubhash Jadavani EXT_CSD_HPI_MGMT, 1, 148752d0974eSSubhash Jadavani card->ext_csd.generic_cmd6_time); 148852d0974eSSubhash Jadavani if (err && err != -EBADMSG) 148952d0974eSSubhash Jadavani goto free_card; 149052d0974eSSubhash Jadavani if (err) { 14916606110dSJoe Perches pr_warn("%s: Enabling HPI failed\n", 149252d0974eSSubhash Jadavani mmc_hostname(card->host)); 149352d0974eSSubhash Jadavani err = 0; 149452d0974eSSubhash Jadavani } else 149552d0974eSSubhash Jadavani card->ext_csd.hpi_en = 1; 149652d0974eSSubhash Jadavani } 149752d0974eSSubhash Jadavani 149852d0974eSSubhash Jadavani /* 1499881d1c25SSeungwon Jeon * If cache size is higher than 0, this indicates 1500881d1c25SSeungwon Jeon * the existence of cache and it can be turned on. 1501881d1c25SSeungwon Jeon */ 15027536d3f8SUlf Hansson if (card->ext_csd.cache_size > 0) { 1503881d1c25SSeungwon Jeon err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, 15048bc0678bSSeungwon Jeon EXT_CSD_CACHE_CTRL, 1, 15058bc0678bSSeungwon Jeon card->ext_csd.generic_cmd6_time); 1506881d1c25SSeungwon Jeon if (err && err != -EBADMSG) 1507881d1c25SSeungwon Jeon goto free_card; 1508881d1c25SSeungwon Jeon 1509881d1c25SSeungwon Jeon /* 1510881d1c25SSeungwon Jeon * Only if no error, cache is turned on successfully. 1511881d1c25SSeungwon Jeon */ 15128bc0678bSSeungwon Jeon if (err) { 15136606110dSJoe Perches pr_warn("%s: Cache is supported, but failed to turn on (%d)\n", 15148bc0678bSSeungwon Jeon mmc_hostname(card->host), err); 15158bc0678bSSeungwon Jeon card->ext_csd.cache_ctrl = 0; 15168bc0678bSSeungwon Jeon err = 0; 15178bc0678bSSeungwon Jeon } else { 15188bc0678bSSeungwon Jeon card->ext_csd.cache_ctrl = 1; 15198bc0678bSSeungwon Jeon } 1520881d1c25SSeungwon Jeon } 1521881d1c25SSeungwon Jeon 1522abd9ac14SSeungwon Jeon /* 1523abd9ac14SSeungwon Jeon * The mandatory minimum values are defined for packed command. 1524abd9ac14SSeungwon Jeon * read: 5, write: 3 1525abd9ac14SSeungwon Jeon */ 1526abd9ac14SSeungwon Jeon if (card->ext_csd.max_packed_writes >= 3 && 1527abd9ac14SSeungwon Jeon card->ext_csd.max_packed_reads >= 5 && 1528abd9ac14SSeungwon Jeon host->caps2 & MMC_CAP2_PACKED_CMD) { 1529abd9ac14SSeungwon Jeon err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, 1530abd9ac14SSeungwon Jeon EXT_CSD_EXP_EVENTS_CTRL, 1531abd9ac14SSeungwon Jeon EXT_CSD_PACKED_EVENT_EN, 1532abd9ac14SSeungwon Jeon card->ext_csd.generic_cmd6_time); 1533abd9ac14SSeungwon Jeon if (err && err != -EBADMSG) 1534abd9ac14SSeungwon Jeon goto free_card; 1535abd9ac14SSeungwon Jeon if (err) { 1536abd9ac14SSeungwon Jeon pr_warn("%s: Enabling packed event failed\n", 1537abd9ac14SSeungwon Jeon mmc_hostname(card->host)); 1538abd9ac14SSeungwon Jeon card->ext_csd.packed_event_en = 0; 1539abd9ac14SSeungwon Jeon err = 0; 1540abd9ac14SSeungwon Jeon } else { 1541abd9ac14SSeungwon Jeon card->ext_csd.packed_event_en = 1; 1542abd9ac14SSeungwon Jeon } 1543abd9ac14SSeungwon Jeon } 1544abd9ac14SSeungwon Jeon 15456abaa0c9SPierre Ossman if (!oldcard) 15467ea239d9SPierre Ossman host->card = card; 15477ea239d9SPierre Ossman 154808ee80ccSPhilip Rakity mmc_free_ext_csd(ext_csd); 154917b0429dSPierre Ossman return 0; 15506abaa0c9SPierre Ossman 15516abaa0c9SPierre Ossman free_card: 15526abaa0c9SPierre Ossman if (!oldcard) 15536abaa0c9SPierre Ossman mmc_remove_card(card); 15546abaa0c9SPierre Ossman err: 155508ee80ccSPhilip Rakity mmc_free_ext_csd(ext_csd); 15566abaa0c9SPierre Ossman 1557adf66a0dSPierre Ossman return err; 15586abaa0c9SPierre Ossman } 15596abaa0c9SPierre Ossman 156007a68216SUlf Hansson static int mmc_can_sleep(struct mmc_card *card) 156107a68216SUlf Hansson { 156207a68216SUlf Hansson return (card && card->ext_csd.rev >= 3); 156307a68216SUlf Hansson } 156407a68216SUlf Hansson 156507a68216SUlf Hansson static int mmc_sleep(struct mmc_host *host) 156607a68216SUlf Hansson { 156707a68216SUlf Hansson struct mmc_command cmd = {0}; 156807a68216SUlf Hansson struct mmc_card *card = host->card; 1569cb962e04SUlf Hansson unsigned int timeout_ms = DIV_ROUND_UP(card->ext_csd.sa_timeout, 10000); 157007a68216SUlf Hansson int err; 157107a68216SUlf Hansson 157207a68216SUlf Hansson err = mmc_deselect_cards(host); 157307a68216SUlf Hansson if (err) 157407a68216SUlf Hansson return err; 157507a68216SUlf Hansson 157607a68216SUlf Hansson cmd.opcode = MMC_SLEEP_AWAKE; 157707a68216SUlf Hansson cmd.arg = card->rca << 16; 157807a68216SUlf Hansson cmd.arg |= 1 << 15; 157907a68216SUlf Hansson 1580cb962e04SUlf Hansson /* 1581cb962e04SUlf Hansson * If the max_busy_timeout of the host is specified, validate it against 1582cb962e04SUlf Hansson * the sleep cmd timeout. A failure means we need to prevent the host 1583cb962e04SUlf Hansson * from doing hw busy detection, which is done by converting to a R1 1584cb962e04SUlf Hansson * response instead of a R1B. 1585cb962e04SUlf Hansson */ 1586cb962e04SUlf Hansson if (host->max_busy_timeout && (timeout_ms > host->max_busy_timeout)) { 1587cb962e04SUlf Hansson cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; 1588cb962e04SUlf Hansson } else { 158907a68216SUlf Hansson cmd.flags = MMC_RSP_R1B | MMC_CMD_AC; 1590cb962e04SUlf Hansson cmd.busy_timeout = timeout_ms; 1591cb962e04SUlf Hansson } 1592cb962e04SUlf Hansson 159307a68216SUlf Hansson err = mmc_wait_for_cmd(host, &cmd, 0); 159407a68216SUlf Hansson if (err) 159507a68216SUlf Hansson return err; 159607a68216SUlf Hansson 159707a68216SUlf Hansson /* 159807a68216SUlf Hansson * If the host does not wait while the card signals busy, then we will 159907a68216SUlf Hansson * will have to wait the sleep/awake timeout. Note, we cannot use the 160007a68216SUlf Hansson * SEND_STATUS command to poll the status because that command (and most 160107a68216SUlf Hansson * others) is invalid while the card sleeps. 160207a68216SUlf Hansson */ 1603cb962e04SUlf Hansson if (!cmd.busy_timeout || !(host->caps & MMC_CAP_WAIT_WHILE_BUSY)) 1604cb962e04SUlf Hansson mmc_delay(timeout_ms); 160507a68216SUlf Hansson 160607a68216SUlf Hansson return err; 160707a68216SUlf Hansson } 160807a68216SUlf Hansson 1609e6c08586SUlf Hansson static int mmc_can_poweroff_notify(const struct mmc_card *card) 1610e6c08586SUlf Hansson { 1611e6c08586SUlf Hansson return card && 1612e6c08586SUlf Hansson mmc_card_mmc(card) && 1613e6c08586SUlf Hansson (card->ext_csd.power_off_notification == EXT_CSD_POWER_ON); 1614e6c08586SUlf Hansson } 1615e6c08586SUlf Hansson 1616e6c08586SUlf Hansson static int mmc_poweroff_notify(struct mmc_card *card, unsigned int notify_type) 1617e6c08586SUlf Hansson { 1618e6c08586SUlf Hansson unsigned int timeout = card->ext_csd.generic_cmd6_time; 1619e6c08586SUlf Hansson int err; 1620e6c08586SUlf Hansson 1621e6c08586SUlf Hansson /* Use EXT_CSD_POWER_OFF_SHORT as default notification type. */ 1622e6c08586SUlf Hansson if (notify_type == EXT_CSD_POWER_OFF_LONG) 1623e6c08586SUlf Hansson timeout = card->ext_csd.power_off_longtime; 1624e6c08586SUlf Hansson 1625878e200bSUlf Hansson err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, 1626e6c08586SUlf Hansson EXT_CSD_POWER_OFF_NOTIFICATION, 16274509f847SUlf Hansson notify_type, timeout, true, false, false); 1628e6c08586SUlf Hansson if (err) 1629e6c08586SUlf Hansson pr_err("%s: Power Off Notification timed out, %u\n", 1630e6c08586SUlf Hansson mmc_hostname(card->host), timeout); 1631e6c08586SUlf Hansson 1632e6c08586SUlf Hansson /* Disable the power off notification after the switch operation. */ 1633e6c08586SUlf Hansson card->ext_csd.power_off_notification = EXT_CSD_NO_POWER_NOTIFICATION; 1634e6c08586SUlf Hansson 1635e6c08586SUlf Hansson return err; 1636e6c08586SUlf Hansson } 1637e6c08586SUlf Hansson 16386abaa0c9SPierre Ossman /* 16396abaa0c9SPierre Ossman * Host is being removed. Free up the current card. 16406abaa0c9SPierre Ossman */ 16416abaa0c9SPierre Ossman static void mmc_remove(struct mmc_host *host) 16426abaa0c9SPierre Ossman { 16436abaa0c9SPierre Ossman BUG_ON(!host); 16446abaa0c9SPierre Ossman BUG_ON(!host->card); 16456abaa0c9SPierre Ossman 16466abaa0c9SPierre Ossman mmc_remove_card(host->card); 16476abaa0c9SPierre Ossman host->card = NULL; 16486abaa0c9SPierre Ossman } 16496abaa0c9SPierre Ossman 16506abaa0c9SPierre Ossman /* 1651d3049504SAdrian Hunter * Card detection - card is alive. 1652d3049504SAdrian Hunter */ 1653d3049504SAdrian Hunter static int mmc_alive(struct mmc_host *host) 1654d3049504SAdrian Hunter { 1655d3049504SAdrian Hunter return mmc_send_status(host->card, NULL); 1656d3049504SAdrian Hunter } 1657d3049504SAdrian Hunter 1658d3049504SAdrian Hunter /* 16596abaa0c9SPierre Ossman * Card detection callback from host. 16606abaa0c9SPierre Ossman */ 16616abaa0c9SPierre Ossman static void mmc_detect(struct mmc_host *host) 16626abaa0c9SPierre Ossman { 16636abaa0c9SPierre Ossman int err; 16646abaa0c9SPierre Ossman 16656abaa0c9SPierre Ossman BUG_ON(!host); 16666abaa0c9SPierre Ossman BUG_ON(!host->card); 16676abaa0c9SPierre Ossman 1668e94cfef6SUlf Hansson mmc_get_card(host->card); 16696abaa0c9SPierre Ossman 16706abaa0c9SPierre Ossman /* 16716abaa0c9SPierre Ossman * Just check if our card has been removed. 16726abaa0c9SPierre Ossman */ 1673d3049504SAdrian Hunter err = _mmc_detect_card_removed(host); 16746abaa0c9SPierre Ossman 1675e94cfef6SUlf Hansson mmc_put_card(host->card); 16767ea239d9SPierre Ossman 167717b0429dSPierre Ossman if (err) { 16784101c16aSPierre Ossman mmc_remove(host); 16796abaa0c9SPierre Ossman 16806abaa0c9SPierre Ossman mmc_claim_host(host); 16816abaa0c9SPierre Ossman mmc_detach_bus(host); 16827f7e4129SUlf Hansson mmc_power_off(host); 16836abaa0c9SPierre Ossman mmc_release_host(host); 16846abaa0c9SPierre Ossman } 16856abaa0c9SPierre Ossman } 16866abaa0c9SPierre Ossman 168703d071fcSUlf Hansson static int _mmc_suspend(struct mmc_host *host, bool is_suspend) 16886abaa0c9SPierre Ossman { 1689c3805467SBalaji T K int err = 0; 169003d071fcSUlf Hansson unsigned int notify_type = is_suspend ? EXT_CSD_POWER_OFF_SHORT : 169103d071fcSUlf Hansson EXT_CSD_POWER_OFF_LONG; 1692c3805467SBalaji T K 16936abaa0c9SPierre Ossman BUG_ON(!host); 16946abaa0c9SPierre Ossman BUG_ON(!host->card); 16956abaa0c9SPierre Ossman 16966abaa0c9SPierre Ossman mmc_claim_host(host); 1697881d926dSMaya Erez 16989ec775f7SUlf Hansson if (mmc_card_suspended(host->card)) 16999ec775f7SUlf Hansson goto out; 17009ec775f7SUlf Hansson 170139b9431bSUlf Hansson if (mmc_card_doing_bkops(host->card)) { 170239b9431bSUlf Hansson err = mmc_stop_bkops(host->card); 170339b9431bSUlf Hansson if (err) 170439b9431bSUlf Hansson goto out; 170539b9431bSUlf Hansson } 170639b9431bSUlf Hansson 170710e5d965SUlf Hansson err = mmc_flush_cache(host->card); 1708881d926dSMaya Erez if (err) 1709881d926dSMaya Erez goto out; 1710881d926dSMaya Erez 171143235679SUlf Hansson if (mmc_can_poweroff_notify(host->card) && 171253275c21SUlf Hansson ((host->caps2 & MMC_CAP2_FULL_PWR_CYCLE) || !is_suspend)) 171303d071fcSUlf Hansson err = mmc_poweroff_notify(host->card, notify_type); 171407a68216SUlf Hansson else if (mmc_can_sleep(host->card)) 171507a68216SUlf Hansson err = mmc_sleep(host); 1716e6c08586SUlf Hansson else if (!mmc_host_is_spi(host)) 171785e727edSJaehoon Chung err = mmc_deselect_cards(host); 171895cdfb72SNicolas Pitre 17199ec775f7SUlf Hansson if (!err) { 172074590263SUlf Hansson mmc_power_off(host); 17219ec775f7SUlf Hansson mmc_card_set_suspended(host->card); 17229ec775f7SUlf Hansson } 1723881d926dSMaya Erez out: 1724881d926dSMaya Erez mmc_release_host(host); 1725c3805467SBalaji T K return err; 17266abaa0c9SPierre Ossman } 17276abaa0c9SPierre Ossman 17286abaa0c9SPierre Ossman /* 17290cb403a2SUlf Hansson * Suspend callback 173003d071fcSUlf Hansson */ 173103d071fcSUlf Hansson static int mmc_suspend(struct mmc_host *host) 173203d071fcSUlf Hansson { 17330cb403a2SUlf Hansson int err; 17340cb403a2SUlf Hansson 17350cb403a2SUlf Hansson err = _mmc_suspend(host, true); 17360cb403a2SUlf Hansson if (!err) { 17370cb403a2SUlf Hansson pm_runtime_disable(&host->card->dev); 17380cb403a2SUlf Hansson pm_runtime_set_suspended(&host->card->dev); 17390cb403a2SUlf Hansson } 17400cb403a2SUlf Hansson 17410cb403a2SUlf Hansson return err; 174203d071fcSUlf Hansson } 174303d071fcSUlf Hansson 174403d071fcSUlf Hansson /* 17456abaa0c9SPierre Ossman * This function tries to determine if the same card is still present 17466abaa0c9SPierre Ossman * and, if so, restore all state to it. 17476abaa0c9SPierre Ossman */ 17480cb403a2SUlf Hansson static int _mmc_resume(struct mmc_host *host) 17496abaa0c9SPierre Ossman { 17509ec775f7SUlf Hansson int err = 0; 17516abaa0c9SPierre Ossman 17526abaa0c9SPierre Ossman BUG_ON(!host); 17536abaa0c9SPierre Ossman BUG_ON(!host->card); 17546abaa0c9SPierre Ossman 17556abaa0c9SPierre Ossman mmc_claim_host(host); 17569ec775f7SUlf Hansson 17579ec775f7SUlf Hansson if (!mmc_card_suspended(host->card)) 17589ec775f7SUlf Hansson goto out; 17599ec775f7SUlf Hansson 176069041150SUlf Hansson mmc_power_up(host, host->card->ocr); 176169041150SUlf Hansson err = mmc_init_card(host, host->card->ocr, host->card); 17629ec775f7SUlf Hansson mmc_card_clr_suspended(host->card); 17632986d0bfSPierre Ossman 17649ec775f7SUlf Hansson out: 17659ec775f7SUlf Hansson mmc_release_host(host); 176695cdfb72SNicolas Pitre return err; 17676abaa0c9SPierre Ossman } 17686abaa0c9SPierre Ossman 17699ec775f7SUlf Hansson /* 17709ec775f7SUlf Hansson * Shutdown callback 17719ec775f7SUlf Hansson */ 17729ec775f7SUlf Hansson static int mmc_shutdown(struct mmc_host *host) 17739ec775f7SUlf Hansson { 17749ec775f7SUlf Hansson int err = 0; 17759ec775f7SUlf Hansson 17769ec775f7SUlf Hansson /* 17779ec775f7SUlf Hansson * In a specific case for poweroff notify, we need to resume the card 17789ec775f7SUlf Hansson * before we can shutdown it properly. 17799ec775f7SUlf Hansson */ 17809ec775f7SUlf Hansson if (mmc_can_poweroff_notify(host->card) && 17819ec775f7SUlf Hansson !(host->caps2 & MMC_CAP2_FULL_PWR_CYCLE)) 17820cb403a2SUlf Hansson err = _mmc_resume(host); 17839ec775f7SUlf Hansson 17849ec775f7SUlf Hansson if (!err) 17859ec775f7SUlf Hansson err = _mmc_suspend(host, false); 17869ec775f7SUlf Hansson 17879ec775f7SUlf Hansson return err; 17889ec775f7SUlf Hansson } 1789c4d770d7SUlf Hansson 1790c4d770d7SUlf Hansson /* 17910cb403a2SUlf Hansson * Callback for resume. 17920cb403a2SUlf Hansson */ 17930cb403a2SUlf Hansson static int mmc_resume(struct mmc_host *host) 17940cb403a2SUlf Hansson { 17954d223782SUlf Hansson int err = 0; 17960cb403a2SUlf Hansson 17974d223782SUlf Hansson if (!(host->caps & MMC_CAP_RUNTIME_RESUME)) { 17980cb403a2SUlf Hansson err = _mmc_resume(host); 17990cb403a2SUlf Hansson pm_runtime_set_active(&host->card->dev); 18000cb403a2SUlf Hansson pm_runtime_mark_last_busy(&host->card->dev); 18014d223782SUlf Hansson } 18020cb403a2SUlf Hansson pm_runtime_enable(&host->card->dev); 18030cb403a2SUlf Hansson 18040cb403a2SUlf Hansson return err; 18050cb403a2SUlf Hansson } 18060cb403a2SUlf Hansson 18070cb403a2SUlf Hansson /* 1808c4d770d7SUlf Hansson * Callback for runtime_suspend. 1809c4d770d7SUlf Hansson */ 1810c4d770d7SUlf Hansson static int mmc_runtime_suspend(struct mmc_host *host) 1811c4d770d7SUlf Hansson { 1812c4d770d7SUlf Hansson int err; 1813c4d770d7SUlf Hansson 1814c4d770d7SUlf Hansson if (!(host->caps & MMC_CAP_AGGRESSIVE_PM)) 1815c4d770d7SUlf Hansson return 0; 1816c4d770d7SUlf Hansson 18170cb403a2SUlf Hansson err = _mmc_suspend(host, true); 18180cc81a8cSUlf Hansson if (err) 1819c4d770d7SUlf Hansson pr_err("%s: error %d doing aggessive suspend\n", 1820c4d770d7SUlf Hansson mmc_hostname(host), err); 1821c4d770d7SUlf Hansson 1822c4d770d7SUlf Hansson return err; 1823c4d770d7SUlf Hansson } 1824c4d770d7SUlf Hansson 1825c4d770d7SUlf Hansson /* 1826c4d770d7SUlf Hansson * Callback for runtime_resume. 1827c4d770d7SUlf Hansson */ 1828c4d770d7SUlf Hansson static int mmc_runtime_resume(struct mmc_host *host) 1829c4d770d7SUlf Hansson { 1830c4d770d7SUlf Hansson int err; 1831c4d770d7SUlf Hansson 18324d223782SUlf Hansson if (!(host->caps & (MMC_CAP_AGGRESSIVE_PM | MMC_CAP_RUNTIME_RESUME))) 1833c4d770d7SUlf Hansson return 0; 1834c4d770d7SUlf Hansson 18350cb403a2SUlf Hansson err = _mmc_resume(host); 1836c4d770d7SUlf Hansson if (err) 1837c4d770d7SUlf Hansson pr_err("%s: error %d doing aggessive resume\n", 1838c4d770d7SUlf Hansson mmc_hostname(host), err); 1839c4d770d7SUlf Hansson 1840c4d770d7SUlf Hansson return 0; 1841c4d770d7SUlf Hansson } 1842c4d770d7SUlf Hansson 184312ae637fSOhad Ben-Cohen static int mmc_power_restore(struct mmc_host *host) 1844eae1aeeeSAdrian Hunter { 184512ae637fSOhad Ben-Cohen int ret; 184612ae637fSOhad Ben-Cohen 1847eae1aeeeSAdrian Hunter mmc_claim_host(host); 184869041150SUlf Hansson ret = mmc_init_card(host, host->card->ocr, host->card); 1849eae1aeeeSAdrian Hunter mmc_release_host(host); 185012ae637fSOhad Ben-Cohen 185112ae637fSOhad Ben-Cohen return ret; 1852eae1aeeeSAdrian Hunter } 1853eae1aeeeSAdrian Hunter 18549feae246SAdrian Hunter static const struct mmc_bus_ops mmc_ops = { 18559feae246SAdrian Hunter .remove = mmc_remove, 18569feae246SAdrian Hunter .detect = mmc_detect, 18579feae246SAdrian Hunter .suspend = mmc_suspend, 18589feae246SAdrian Hunter .resume = mmc_resume, 1859c4d770d7SUlf Hansson .runtime_suspend = mmc_runtime_suspend, 1860c4d770d7SUlf Hansson .runtime_resume = mmc_runtime_resume, 1861eae1aeeeSAdrian Hunter .power_restore = mmc_power_restore, 1862d3049504SAdrian Hunter .alive = mmc_alive, 1863486fdbbcSUlf Hansson .shutdown = mmc_shutdown, 18649feae246SAdrian Hunter }; 18659feae246SAdrian Hunter 18666abaa0c9SPierre Ossman /* 18676abaa0c9SPierre Ossman * Starting point for MMC card init. 18686abaa0c9SPierre Ossman */ 1869807e8e40SAndy Ross int mmc_attach_mmc(struct mmc_host *host) 18706abaa0c9SPierre Ossman { 18716abaa0c9SPierre Ossman int err; 187269041150SUlf Hansson u32 ocr, rocr; 18736abaa0c9SPierre Ossman 18746abaa0c9SPierre Ossman BUG_ON(!host); 1875d84075c8SPierre Ossman WARN_ON(!host->claimed); 18766abaa0c9SPierre Ossman 187744669034SStefan Nilsson XK /* Set correct bus mode for MMC before attempting attach */ 187844669034SStefan Nilsson XK if (!mmc_host_is_spi(host)) 187944669034SStefan Nilsson XK mmc_set_bus_mode(host, MMC_BUSMODE_OPENDRAIN); 188044669034SStefan Nilsson XK 1881807e8e40SAndy Ross err = mmc_send_op_cond(host, 0, &ocr); 1882807e8e40SAndy Ross if (err) 1883807e8e40SAndy Ross return err; 1884807e8e40SAndy Ross 18852501c917SUlf Hansson mmc_attach_bus(host, &mmc_ops); 18868f230f45STakashi Iwai if (host->ocr_avail_mmc) 18878f230f45STakashi Iwai host->ocr_avail = host->ocr_avail_mmc; 18886abaa0c9SPierre Ossman 18896abaa0c9SPierre Ossman /* 1890af517150SDavid Brownell * We need to get OCR a different way for SPI. 1891af517150SDavid Brownell */ 1892af517150SDavid Brownell if (mmc_host_is_spi(host)) { 1893af517150SDavid Brownell err = mmc_spi_read_ocr(host, 1, &ocr); 1894af517150SDavid Brownell if (err) 1895af517150SDavid Brownell goto err; 1896af517150SDavid Brownell } 1897af517150SDavid Brownell 189869041150SUlf Hansson rocr = mmc_select_voltage(host, ocr); 18996abaa0c9SPierre Ossman 19006abaa0c9SPierre Ossman /* 19016abaa0c9SPierre Ossman * Can we support the voltage of the card? 19026abaa0c9SPierre Ossman */ 190369041150SUlf Hansson if (!rocr) { 1904109b5bedSPierre Ossman err = -EINVAL; 19056abaa0c9SPierre Ossman goto err; 1906109b5bedSPierre Ossman } 19076abaa0c9SPierre Ossman 19086abaa0c9SPierre Ossman /* 19096abaa0c9SPierre Ossman * Detect and init the card. 19106abaa0c9SPierre Ossman */ 191169041150SUlf Hansson err = mmc_init_card(host, rocr, NULL); 191217b0429dSPierre Ossman if (err) 19136abaa0c9SPierre Ossman goto err; 19146abaa0c9SPierre Ossman 19156abaa0c9SPierre Ossman mmc_release_host(host); 19164101c16aSPierre Ossman err = mmc_add_card(host->card); 1917807e8e40SAndy Ross mmc_claim_host(host); 19187ea239d9SPierre Ossman if (err) 19192986d0bfSPierre Ossman goto remove_card; 19207ea239d9SPierre Ossman 19217ea239d9SPierre Ossman return 0; 19227ea239d9SPierre Ossman 19232986d0bfSPierre Ossman remove_card: 1924807e8e40SAndy Ross mmc_release_host(host); 19256abaa0c9SPierre Ossman mmc_remove_card(host->card); 19262986d0bfSPierre Ossman mmc_claim_host(host); 1927807e8e40SAndy Ross host->card = NULL; 19287ea239d9SPierre Ossman err: 19297ea239d9SPierre Ossman mmc_detach_bus(host); 19307ea239d9SPierre Ossman 1931a3c76eb9SGirish K S pr_err("%s: error %d whilst initialising MMC card\n", 1932109b5bedSPierre Ossman mmc_hostname(host), err); 1933109b5bedSPierre Ossman 1934adf66a0dSPierre Ossman return err; 19357ea239d9SPierre Ossman } 1936