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 193148bcab2SUlf Hansson if (!mmc_can_ext_csd(card)) 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); 201a1fc444eSUlf Hansson if (!ext_csd) 20217b0429dSPierre Ossman return -ENOMEM; 2037ea239d9SPierre Ossman 2047ea239d9SPierre Ossman err = mmc_send_ext_csd(card, ext_csd); 20517b0429dSPierre Ossman if (err) { 20608ee80ccSPhilip Rakity kfree(ext_csd); 20708ee80ccSPhilip Rakity *new_ext_csd = NULL; 20808ee80ccSPhilip Rakity 209d08ebeddSWolfgang Muees /* If the host or the card can't do the switch, 210d08ebeddSWolfgang Muees * fail more gracefully. */ 211d08ebeddSWolfgang Muees if ((err != -EINVAL) 212d08ebeddSWolfgang Muees && (err != -ENOSYS) 213d08ebeddSWolfgang Muees && (err != -EFAULT)) 21408ee80ccSPhilip Rakity return err; 215adf66a0dSPierre Ossman 216adf66a0dSPierre Ossman /* 2177ea239d9SPierre Ossman * High capacity cards should have this "magic" size 2187ea239d9SPierre Ossman * stored in their CSD. 2197ea239d9SPierre Ossman */ 2207ea239d9SPierre Ossman if (card->csd.capacity == (4096 * 512)) { 221a3c76eb9SGirish K S pr_err("%s: unable to read EXT_CSD " 2227ea239d9SPierre Ossman "on a possible high capacity card. " 2237ea239d9SPierre Ossman "Card will be ignored.\n", 2247ea239d9SPierre Ossman mmc_hostname(card->host)); 2257ea239d9SPierre Ossman } else { 2266606110dSJoe Perches pr_warn("%s: unable to read EXT_CSD, performance might suffer\n", 2277ea239d9SPierre Ossman mmc_hostname(card->host)); 22817b0429dSPierre Ossman err = 0; 2297ea239d9SPierre Ossman } 23008ee80ccSPhilip Rakity } else 23108ee80ccSPhilip Rakity *new_ext_csd = ext_csd; 232adf66a0dSPierre Ossman 23308ee80ccSPhilip Rakity return err; 2347ea239d9SPierre Ossman } 2357ea239d9SPierre Ossman 23696cf5f02SSeungwon Jeon static void mmc_select_card_type(struct mmc_card *card) 23796cf5f02SSeungwon Jeon { 23896cf5f02SSeungwon Jeon struct mmc_host *host = card->host; 2390a5b6438SSeungwon Jeon u8 card_type = card->ext_csd.raw_card_type; 2405f1a4dd0SLee Jones u32 caps = host->caps, caps2 = host->caps2; 241577fb131SSeungwon Jeon unsigned int hs_max_dtr = 0, hs200_max_dtr = 0; 2422415c0efSSeungwon Jeon unsigned int avail_type = 0; 24396cf5f02SSeungwon Jeon 24496cf5f02SSeungwon Jeon if (caps & MMC_CAP_MMC_HIGHSPEED && 2452415c0efSSeungwon Jeon card_type & EXT_CSD_CARD_TYPE_HS_26) { 2462415c0efSSeungwon Jeon hs_max_dtr = MMC_HIGH_26_MAX_DTR; 2472415c0efSSeungwon Jeon avail_type |= EXT_CSD_CARD_TYPE_HS_26; 2482415c0efSSeungwon Jeon } 2492415c0efSSeungwon Jeon 2502415c0efSSeungwon Jeon if (caps & MMC_CAP_MMC_HIGHSPEED && 2512415c0efSSeungwon Jeon card_type & EXT_CSD_CARD_TYPE_HS_52) { 25296cf5f02SSeungwon Jeon hs_max_dtr = MMC_HIGH_52_MAX_DTR; 2532415c0efSSeungwon Jeon avail_type |= EXT_CSD_CARD_TYPE_HS_52; 2542415c0efSSeungwon Jeon } 25596cf5f02SSeungwon Jeon 2562415c0efSSeungwon Jeon if (caps & MMC_CAP_1_8V_DDR && 2572415c0efSSeungwon Jeon card_type & EXT_CSD_CARD_TYPE_DDR_1_8V) { 25896cf5f02SSeungwon Jeon hs_max_dtr = MMC_HIGH_DDR_MAX_DTR; 2592415c0efSSeungwon Jeon avail_type |= EXT_CSD_CARD_TYPE_DDR_1_8V; 2602415c0efSSeungwon Jeon } 26196cf5f02SSeungwon Jeon 2622415c0efSSeungwon Jeon if (caps & MMC_CAP_1_2V_DDR && 2632415c0efSSeungwon Jeon card_type & EXT_CSD_CARD_TYPE_DDR_1_2V) { 2642415c0efSSeungwon Jeon hs_max_dtr = MMC_HIGH_DDR_MAX_DTR; 2652415c0efSSeungwon Jeon avail_type |= EXT_CSD_CARD_TYPE_DDR_1_2V; 2662415c0efSSeungwon Jeon } 2672415c0efSSeungwon Jeon 2682415c0efSSeungwon Jeon if (caps2 & MMC_CAP2_HS200_1_8V_SDR && 2692415c0efSSeungwon Jeon card_type & EXT_CSD_CARD_TYPE_HS200_1_8V) { 270577fb131SSeungwon Jeon hs200_max_dtr = MMC_HS200_MAX_DTR; 2712415c0efSSeungwon Jeon avail_type |= EXT_CSD_CARD_TYPE_HS200_1_8V; 2722415c0efSSeungwon Jeon } 2732415c0efSSeungwon Jeon 2742415c0efSSeungwon Jeon if (caps2 & MMC_CAP2_HS200_1_2V_SDR && 2752415c0efSSeungwon Jeon card_type & EXT_CSD_CARD_TYPE_HS200_1_2V) { 276577fb131SSeungwon Jeon hs200_max_dtr = MMC_HS200_MAX_DTR; 2772415c0efSSeungwon Jeon avail_type |= EXT_CSD_CARD_TYPE_HS200_1_2V; 2782415c0efSSeungwon Jeon } 27996cf5f02SSeungwon Jeon 2800a5b6438SSeungwon Jeon if (caps2 & MMC_CAP2_HS400_1_8V && 2810a5b6438SSeungwon Jeon card_type & EXT_CSD_CARD_TYPE_HS400_1_8V) { 2820a5b6438SSeungwon Jeon hs200_max_dtr = MMC_HS200_MAX_DTR; 2830a5b6438SSeungwon Jeon avail_type |= EXT_CSD_CARD_TYPE_HS400_1_8V; 2840a5b6438SSeungwon Jeon } 2850a5b6438SSeungwon Jeon 2860a5b6438SSeungwon Jeon if (caps2 & MMC_CAP2_HS400_1_2V && 2870a5b6438SSeungwon Jeon card_type & EXT_CSD_CARD_TYPE_HS400_1_2V) { 2880a5b6438SSeungwon Jeon hs200_max_dtr = MMC_HS200_MAX_DTR; 2890a5b6438SSeungwon Jeon avail_type |= EXT_CSD_CARD_TYPE_HS400_1_2V; 2900a5b6438SSeungwon Jeon } 2910a5b6438SSeungwon Jeon 29296cf5f02SSeungwon Jeon card->ext_csd.hs_max_dtr = hs_max_dtr; 293577fb131SSeungwon Jeon card->ext_csd.hs200_max_dtr = hs200_max_dtr; 2942415c0efSSeungwon Jeon card->mmc_avail_type = avail_type; 29596cf5f02SSeungwon Jeon } 29696cf5f02SSeungwon Jeon 297b4493eeaSGrégory Soutadé static void mmc_manage_enhanced_area(struct mmc_card *card, u8 *ext_csd) 298b4493eeaSGrégory Soutadé { 299994324bbSGrégory Soutadé u8 hc_erase_grp_sz, hc_wp_grp_sz; 300994324bbSGrégory Soutadé 301994324bbSGrégory Soutadé /* 302994324bbSGrégory Soutadé * Disable these attributes by default 303994324bbSGrégory Soutadé */ 304994324bbSGrégory Soutadé card->ext_csd.enhanced_area_offset = -EINVAL; 305994324bbSGrégory Soutadé card->ext_csd.enhanced_area_size = -EINVAL; 306b4493eeaSGrégory Soutadé 307b4493eeaSGrégory Soutadé /* 308b4493eeaSGrégory Soutadé * Enhanced area feature support -- check whether the eMMC 309b4493eeaSGrégory Soutadé * card has the Enhanced area enabled. If so, export enhanced 310b4493eeaSGrégory Soutadé * area offset and size to user by adding sysfs interface. 311b4493eeaSGrégory Soutadé */ 312b4493eeaSGrégory Soutadé if ((ext_csd[EXT_CSD_PARTITION_SUPPORT] & 0x2) && 313b4493eeaSGrégory Soutadé (ext_csd[EXT_CSD_PARTITION_ATTRIBUTE] & 0x1)) { 314994324bbSGrégory Soutadé if (card->ext_csd.partition_setting_completed) { 315b4493eeaSGrégory Soutadé hc_erase_grp_sz = 316b4493eeaSGrégory Soutadé ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]; 317b4493eeaSGrégory Soutadé hc_wp_grp_sz = 318b4493eeaSGrégory Soutadé ext_csd[EXT_CSD_HC_WP_GRP_SIZE]; 319b4493eeaSGrégory Soutadé 320b4493eeaSGrégory Soutadé /* 321b4493eeaSGrégory Soutadé * calculate the enhanced data area offset, in bytes 322b4493eeaSGrégory Soutadé */ 323b4493eeaSGrégory Soutadé card->ext_csd.enhanced_area_offset = 324b4493eeaSGrégory Soutadé (ext_csd[139] << 24) + (ext_csd[138] << 16) + 325b4493eeaSGrégory Soutadé (ext_csd[137] << 8) + ext_csd[136]; 326b4493eeaSGrégory Soutadé if (mmc_card_blockaddr(card)) 327b4493eeaSGrégory Soutadé card->ext_csd.enhanced_area_offset <<= 9; 328b4493eeaSGrégory Soutadé /* 329b4493eeaSGrégory Soutadé * calculate the enhanced data area size, in kilobytes 330b4493eeaSGrégory Soutadé */ 331b4493eeaSGrégory Soutadé card->ext_csd.enhanced_area_size = 332b4493eeaSGrégory Soutadé (ext_csd[142] << 16) + (ext_csd[141] << 8) + 333b4493eeaSGrégory Soutadé ext_csd[140]; 334b4493eeaSGrégory Soutadé card->ext_csd.enhanced_area_size *= 335b4493eeaSGrégory Soutadé (size_t)(hc_erase_grp_sz * hc_wp_grp_sz); 336b4493eeaSGrégory Soutadé card->ext_csd.enhanced_area_size <<= 9; 337b4493eeaSGrégory Soutadé } else { 338994324bbSGrégory Soutadé pr_warn("%s: defines enhanced area without partition setting complete\n", 339994324bbSGrégory Soutadé mmc_hostname(card->host)); 340994324bbSGrégory Soutadé } 341b4493eeaSGrégory Soutadé } 342b4493eeaSGrégory Soutadé } 343b4493eeaSGrégory Soutadé 344b4493eeaSGrégory Soutadé static void mmc_manage_gp_partitions(struct mmc_card *card, u8 *ext_csd) 345b4493eeaSGrégory Soutadé { 346b4493eeaSGrégory Soutadé int idx; 347994324bbSGrégory Soutadé u8 hc_erase_grp_sz, hc_wp_grp_sz; 348994324bbSGrégory Soutadé unsigned int part_size; 349b4493eeaSGrégory Soutadé 350b4493eeaSGrégory Soutadé /* 351b4493eeaSGrégory Soutadé * General purpose partition feature support -- 352b4493eeaSGrégory Soutadé * If ext_csd has the size of general purpose partitions, 353b4493eeaSGrégory Soutadé * set size, part_cfg, partition name in mmc_part. 354b4493eeaSGrégory Soutadé */ 355b4493eeaSGrégory Soutadé if (ext_csd[EXT_CSD_PARTITION_SUPPORT] & 356b4493eeaSGrégory Soutadé EXT_CSD_PART_SUPPORT_PART_EN) { 357b4493eeaSGrégory Soutadé hc_erase_grp_sz = 358b4493eeaSGrégory Soutadé ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]; 359b4493eeaSGrégory Soutadé hc_wp_grp_sz = 360b4493eeaSGrégory Soutadé ext_csd[EXT_CSD_HC_WP_GRP_SIZE]; 361b4493eeaSGrégory Soutadé 362b4493eeaSGrégory Soutadé for (idx = 0; idx < MMC_NUM_GP_PARTITION; idx++) { 363b4493eeaSGrégory Soutadé if (!ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3] && 364b4493eeaSGrégory Soutadé !ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3 + 1] && 365b4493eeaSGrégory Soutadé !ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3 + 2]) 366b4493eeaSGrégory Soutadé continue; 367994324bbSGrégory Soutadé if (card->ext_csd.partition_setting_completed == 0) { 368994324bbSGrégory Soutadé pr_warn("%s: has partition size defined without partition complete\n", 369994324bbSGrégory Soutadé mmc_hostname(card->host)); 370994324bbSGrégory Soutadé break; 371994324bbSGrégory Soutadé } 372b4493eeaSGrégory Soutadé part_size = 373b4493eeaSGrégory Soutadé (ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3 + 2] 374b4493eeaSGrégory Soutadé << 16) + 375b4493eeaSGrégory Soutadé (ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3 + 1] 376b4493eeaSGrégory Soutadé << 8) + 377b4493eeaSGrégory Soutadé ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3]; 378b4493eeaSGrégory Soutadé part_size *= (size_t)(hc_erase_grp_sz * 379b4493eeaSGrégory Soutadé hc_wp_grp_sz); 380b4493eeaSGrégory Soutadé mmc_part_add(card, part_size << 19, 381b4493eeaSGrégory Soutadé EXT_CSD_PART_CONFIG_ACC_GP0 + idx, 382b4493eeaSGrégory Soutadé "gp%d", idx, false, 383b4493eeaSGrégory Soutadé MMC_BLK_DATA_AREA_GP); 384b4493eeaSGrégory Soutadé } 385b4493eeaSGrégory Soutadé } 386b4493eeaSGrégory Soutadé } 387b4493eeaSGrégory Soutadé 38808ee80ccSPhilip Rakity /* 38908ee80ccSPhilip Rakity * Decode extended CSD. 39008ee80ccSPhilip Rakity */ 39108ee80ccSPhilip Rakity static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) 39208ee80ccSPhilip Rakity { 393e0c368d5SNamjae Jeon int err = 0, idx; 394e0c368d5SNamjae Jeon unsigned int part_size; 39508ee80ccSPhilip Rakity 39608ee80ccSPhilip Rakity BUG_ON(!card); 39708ee80ccSPhilip Rakity 39808ee80ccSPhilip Rakity if (!ext_csd) 39908ee80ccSPhilip Rakity return 0; 40008ee80ccSPhilip Rakity 4016da24b78SKyungmin Park /* Version is coded in the CSD_STRUCTURE byte in the EXT_CSD register */ 402f39b2dd9SPhilip Rakity card->ext_csd.raw_ext_csd_structure = ext_csd[EXT_CSD_STRUCTURE]; 4036da24b78SKyungmin Park if (card->csd.structure == 3) { 404f39b2dd9SPhilip Rakity if (card->ext_csd.raw_ext_csd_structure > 2) { 405a3c76eb9SGirish K S pr_err("%s: unrecognised EXT_CSD structure " 4068fdd8521SPierre Ossman "version %d\n", mmc_hostname(card->host), 407f39b2dd9SPhilip Rakity card->ext_csd.raw_ext_csd_structure); 4086da24b78SKyungmin Park err = -EINVAL; 4096da24b78SKyungmin Park goto out; 4106da24b78SKyungmin Park } 4116da24b78SKyungmin Park } 4126da24b78SKyungmin Park 41303a59437SRomain Izard /* 41403a59437SRomain Izard * The EXT_CSD format is meant to be forward compatible. As long 41503a59437SRomain Izard * as CSD_STRUCTURE does not change, all values for EXT_CSD_REV 41603a59437SRomain Izard * are authorized, see JEDEC JESD84-B50 section B.8. 41703a59437SRomain Izard */ 4186da24b78SKyungmin Park card->ext_csd.rev = ext_csd[EXT_CSD_REV]; 419d7604d76SPierre Ossman 420f39b2dd9SPhilip Rakity card->ext_csd.raw_sectors[0] = ext_csd[EXT_CSD_SEC_CNT + 0]; 421f39b2dd9SPhilip Rakity card->ext_csd.raw_sectors[1] = ext_csd[EXT_CSD_SEC_CNT + 1]; 422f39b2dd9SPhilip Rakity card->ext_csd.raw_sectors[2] = ext_csd[EXT_CSD_SEC_CNT + 2]; 423f39b2dd9SPhilip Rakity card->ext_csd.raw_sectors[3] = ext_csd[EXT_CSD_SEC_CNT + 3]; 424b1ebe384SJarkko Lavinen if (card->ext_csd.rev >= 2) { 4257ea239d9SPierre Ossman card->ext_csd.sectors = 4267ea239d9SPierre Ossman ext_csd[EXT_CSD_SEC_CNT + 0] << 0 | 4277ea239d9SPierre Ossman ext_csd[EXT_CSD_SEC_CNT + 1] << 8 | 4287ea239d9SPierre Ossman ext_csd[EXT_CSD_SEC_CNT + 2] << 16 | 4297ea239d9SPierre Ossman ext_csd[EXT_CSD_SEC_CNT + 3] << 24; 430fc8a0985SHanumath Prasad 431fc8a0985SHanumath Prasad /* Cards with density > 2GiB are sector addressed */ 432fc8a0985SHanumath Prasad if (card->ext_csd.sectors > (2u * 1024 * 1024 * 1024) / 512) 4337ea239d9SPierre Ossman mmc_card_set_blockaddr(card); 434d7604d76SPierre Ossman } 43596cf5f02SSeungwon Jeon 436f39b2dd9SPhilip Rakity card->ext_csd.raw_card_type = ext_csd[EXT_CSD_CARD_TYPE]; 43796cf5f02SSeungwon Jeon mmc_select_card_type(card); 4387ea239d9SPierre Ossman 439f39b2dd9SPhilip Rakity card->ext_csd.raw_s_a_timeout = ext_csd[EXT_CSD_S_A_TIMEOUT]; 440f39b2dd9SPhilip Rakity card->ext_csd.raw_erase_timeout_mult = 441f39b2dd9SPhilip Rakity ext_csd[EXT_CSD_ERASE_TIMEOUT_MULT]; 442f39b2dd9SPhilip Rakity card->ext_csd.raw_hc_erase_grp_size = 443f39b2dd9SPhilip Rakity ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]; 444b1ebe384SJarkko Lavinen if (card->ext_csd.rev >= 3) { 445b1ebe384SJarkko Lavinen u8 sa_shift = ext_csd[EXT_CSD_S_A_TIMEOUT]; 446371a689fSAndrei Warkentin card->ext_csd.part_config = ext_csd[EXT_CSD_PART_CONFIG]; 447371a689fSAndrei Warkentin 448371a689fSAndrei Warkentin /* EXT_CSD value is in units of 10ms, but we store in ms */ 449371a689fSAndrei Warkentin card->ext_csd.part_time = 10 * ext_csd[EXT_CSD_PART_SWITCH_TIME]; 450b1ebe384SJarkko Lavinen 451b1ebe384SJarkko Lavinen /* Sleep / awake timeout in 100ns units */ 452b1ebe384SJarkko Lavinen if (sa_shift > 0 && sa_shift <= 0x17) 453b1ebe384SJarkko Lavinen card->ext_csd.sa_timeout = 454b1ebe384SJarkko Lavinen 1 << ext_csd[EXT_CSD_S_A_TIMEOUT]; 455dfe86cbaSAdrian Hunter card->ext_csd.erase_group_def = 456dfe86cbaSAdrian Hunter ext_csd[EXT_CSD_ERASE_GROUP_DEF]; 457dfe86cbaSAdrian Hunter card->ext_csd.hc_erase_timeout = 300 * 458dfe86cbaSAdrian Hunter ext_csd[EXT_CSD_ERASE_TIMEOUT_MULT]; 459dfe86cbaSAdrian Hunter card->ext_csd.hc_erase_size = 460dfe86cbaSAdrian Hunter ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] << 10; 461f4c5522bSAndrei Warkentin 462f4c5522bSAndrei Warkentin card->ext_csd.rel_sectors = ext_csd[EXT_CSD_REL_WR_SEC_C]; 463371a689fSAndrei Warkentin 464371a689fSAndrei Warkentin /* 465371a689fSAndrei Warkentin * There are two boot regions of equal size, defined in 466371a689fSAndrei Warkentin * multiples of 128K. 467371a689fSAndrei Warkentin */ 468e0c368d5SNamjae Jeon if (ext_csd[EXT_CSD_BOOT_MULT] && mmc_boot_partition_access(card->host)) { 469e0c368d5SNamjae Jeon for (idx = 0; idx < MMC_NUM_BOOT_PARTITION; idx++) { 470e0c368d5SNamjae Jeon part_size = ext_csd[EXT_CSD_BOOT_MULT] << 17; 471e0c368d5SNamjae Jeon mmc_part_add(card, part_size, 472e0c368d5SNamjae Jeon EXT_CSD_PART_CONFIG_ACC_BOOT0 + idx, 473add710eaSJohan Rudholm "boot%d", idx, true, 474add710eaSJohan Rudholm MMC_BLK_DATA_AREA_BOOT); 475e0c368d5SNamjae Jeon } 476e0c368d5SNamjae Jeon } 477b1ebe384SJarkko Lavinen } 478b1ebe384SJarkko Lavinen 479f39b2dd9SPhilip Rakity card->ext_csd.raw_hc_erase_gap_size = 480dd13b4edSJurgen Heeks ext_csd[EXT_CSD_HC_WP_GRP_SIZE]; 481f39b2dd9SPhilip Rakity card->ext_csd.raw_sec_trim_mult = 482f39b2dd9SPhilip Rakity ext_csd[EXT_CSD_SEC_TRIM_MULT]; 483f39b2dd9SPhilip Rakity card->ext_csd.raw_sec_erase_mult = 484f39b2dd9SPhilip Rakity ext_csd[EXT_CSD_SEC_ERASE_MULT]; 485f39b2dd9SPhilip Rakity card->ext_csd.raw_sec_feature_support = 486f39b2dd9SPhilip Rakity ext_csd[EXT_CSD_SEC_FEATURE_SUPPORT]; 487f39b2dd9SPhilip Rakity card->ext_csd.raw_trim_mult = 488f39b2dd9SPhilip Rakity ext_csd[EXT_CSD_TRIM_MULT]; 489836dc2feSPhilip Rakity card->ext_csd.raw_partition_support = ext_csd[EXT_CSD_PARTITION_SUPPORT]; 490dfe86cbaSAdrian Hunter if (card->ext_csd.rev >= 4) { 49169803d4fSGrégory Soutadé if (ext_csd[EXT_CSD_PARTITION_SETTING_COMPLETED] & 49269803d4fSGrégory Soutadé EXT_CSD_PART_SETTING_COMPLETED) 49369803d4fSGrégory Soutadé card->ext_csd.partition_setting_completed = 1; 49469803d4fSGrégory Soutadé else 49569803d4fSGrégory Soutadé card->ext_csd.partition_setting_completed = 0; 49669803d4fSGrégory Soutadé 497b4493eeaSGrégory Soutadé mmc_manage_enhanced_area(card, ext_csd); 498709de99dSChuanxiao Dong 499b4493eeaSGrégory Soutadé mmc_manage_gp_partitions(card, ext_csd); 500e0c368d5SNamjae Jeon 501dfe86cbaSAdrian Hunter card->ext_csd.sec_trim_mult = 502dfe86cbaSAdrian Hunter ext_csd[EXT_CSD_SEC_TRIM_MULT]; 503dfe86cbaSAdrian Hunter card->ext_csd.sec_erase_mult = 504dfe86cbaSAdrian Hunter ext_csd[EXT_CSD_SEC_ERASE_MULT]; 505dfe86cbaSAdrian Hunter card->ext_csd.sec_feature_support = 506dfe86cbaSAdrian Hunter ext_csd[EXT_CSD_SEC_FEATURE_SUPPORT]; 507dfe86cbaSAdrian Hunter card->ext_csd.trim_timeout = 300 * 508dfe86cbaSAdrian Hunter ext_csd[EXT_CSD_TRIM_MULT]; 509add710eaSJohan Rudholm 510add710eaSJohan Rudholm /* 511add710eaSJohan Rudholm * Note that the call to mmc_part_add above defaults to read 512add710eaSJohan Rudholm * only. If this default assumption is changed, the call must 513add710eaSJohan Rudholm * take into account the value of boot_locked below. 514add710eaSJohan Rudholm */ 515add710eaSJohan Rudholm card->ext_csd.boot_ro_lock = ext_csd[EXT_CSD_BOOT_WP]; 516add710eaSJohan Rudholm card->ext_csd.boot_ro_lockable = true; 51760443712SFredrik Soderstedt 51860443712SFredrik Soderstedt /* Save power class values */ 51960443712SFredrik Soderstedt card->ext_csd.raw_pwr_cl_52_195 = 52060443712SFredrik Soderstedt ext_csd[EXT_CSD_PWR_CL_52_195]; 52160443712SFredrik Soderstedt card->ext_csd.raw_pwr_cl_26_195 = 52260443712SFredrik Soderstedt ext_csd[EXT_CSD_PWR_CL_26_195]; 52360443712SFredrik Soderstedt card->ext_csd.raw_pwr_cl_52_360 = 52460443712SFredrik Soderstedt ext_csd[EXT_CSD_PWR_CL_52_360]; 52560443712SFredrik Soderstedt card->ext_csd.raw_pwr_cl_26_360 = 52660443712SFredrik Soderstedt ext_csd[EXT_CSD_PWR_CL_26_360]; 52760443712SFredrik Soderstedt card->ext_csd.raw_pwr_cl_200_195 = 52860443712SFredrik Soderstedt ext_csd[EXT_CSD_PWR_CL_200_195]; 52960443712SFredrik Soderstedt card->ext_csd.raw_pwr_cl_200_360 = 53060443712SFredrik Soderstedt ext_csd[EXT_CSD_PWR_CL_200_360]; 53160443712SFredrik Soderstedt card->ext_csd.raw_pwr_cl_ddr_52_195 = 53260443712SFredrik Soderstedt ext_csd[EXT_CSD_PWR_CL_DDR_52_195]; 53360443712SFredrik Soderstedt card->ext_csd.raw_pwr_cl_ddr_52_360 = 53460443712SFredrik Soderstedt ext_csd[EXT_CSD_PWR_CL_DDR_52_360]; 5350a5b6438SSeungwon Jeon card->ext_csd.raw_pwr_cl_ddr_200_360 = 5360a5b6438SSeungwon Jeon ext_csd[EXT_CSD_PWR_CL_DDR_200_360]; 537dfe86cbaSAdrian Hunter } 538dfe86cbaSAdrian Hunter 539b2499518SAdrian Hunter if (card->ext_csd.rev >= 5) { 5407c4f10acSRomain Izard /* Adjust production date as per JEDEC JESD84-B451 */ 5417c4f10acSRomain Izard if (card->cid.year < 2010) 5427c4f10acSRomain Izard card->cid.year += 16; 5437c4f10acSRomain Izard 544950d56acSJaehoon Chung /* check whether the eMMC card supports BKOPS */ 545950d56acSJaehoon Chung if (ext_csd[EXT_CSD_BKOPS_SUPPORT] & 0x1) { 546950d56acSJaehoon Chung card->ext_csd.bkops = 1; 547950d56acSJaehoon Chung card->ext_csd.bkops_en = ext_csd[EXT_CSD_BKOPS_EN]; 548950d56acSJaehoon Chung card->ext_csd.raw_bkops_status = 549950d56acSJaehoon Chung ext_csd[EXT_CSD_BKOPS_STATUS]; 550950d56acSJaehoon Chung if (!card->ext_csd.bkops_en) 551950d56acSJaehoon Chung pr_info("%s: BKOPS_EN bit is not set\n", 552950d56acSJaehoon Chung mmc_hostname(card->host)); 553950d56acSJaehoon Chung } 554950d56acSJaehoon Chung 555eb0d8f13SJaehoon Chung /* check whether the eMMC card supports HPI */ 556eb0d8f13SJaehoon Chung if (ext_csd[EXT_CSD_HPI_FEATURES] & 0x1) { 557eb0d8f13SJaehoon Chung card->ext_csd.hpi = 1; 558eb0d8f13SJaehoon Chung if (ext_csd[EXT_CSD_HPI_FEATURES] & 0x2) 559eb0d8f13SJaehoon Chung card->ext_csd.hpi_cmd = MMC_STOP_TRANSMISSION; 560eb0d8f13SJaehoon Chung else 561eb0d8f13SJaehoon Chung card->ext_csd.hpi_cmd = MMC_SEND_STATUS; 562eb0d8f13SJaehoon Chung /* 563eb0d8f13SJaehoon Chung * Indicate the maximum timeout to close 564eb0d8f13SJaehoon Chung * a command interrupted by HPI 565eb0d8f13SJaehoon Chung */ 566eb0d8f13SJaehoon Chung card->ext_csd.out_of_int_time = 567eb0d8f13SJaehoon Chung ext_csd[EXT_CSD_OUT_OF_INTERRUPT_TIME] * 10; 568eb0d8f13SJaehoon Chung } 569eb0d8f13SJaehoon Chung 570f4c5522bSAndrei Warkentin card->ext_csd.rel_param = ext_csd[EXT_CSD_WR_REL_PARAM]; 571b2499518SAdrian Hunter card->ext_csd.rst_n_function = ext_csd[EXT_CSD_RST_N_FUNCTION]; 572090d25feSLoic Pallardy 573090d25feSLoic Pallardy /* 574090d25feSLoic Pallardy * RPMB regions are defined in multiples of 128K. 575090d25feSLoic Pallardy */ 576090d25feSLoic Pallardy card->ext_csd.raw_rpmb_size_mult = ext_csd[EXT_CSD_RPMB_MULT]; 577d0123ccaSBalaji T K if (ext_csd[EXT_CSD_RPMB_MULT] && mmc_host_cmd23(card->host)) { 578090d25feSLoic Pallardy mmc_part_add(card, ext_csd[EXT_CSD_RPMB_MULT] << 17, 579090d25feSLoic Pallardy EXT_CSD_PART_CONFIG_ACC_RPMB, 580090d25feSLoic Pallardy "rpmb", 0, false, 581090d25feSLoic Pallardy MMC_BLK_DATA_AREA_RPMB); 582090d25feSLoic Pallardy } 583b2499518SAdrian Hunter } 584f4c5522bSAndrei Warkentin 5855238acbeSAndrei Warkentin card->ext_csd.raw_erased_mem_count = ext_csd[EXT_CSD_ERASED_MEM_CONT]; 586dfe86cbaSAdrian Hunter if (ext_csd[EXT_CSD_ERASED_MEM_CONT]) 587dfe86cbaSAdrian Hunter card->erased_byte = 0xFF; 588dfe86cbaSAdrian Hunter else 589dfe86cbaSAdrian Hunter card->erased_byte = 0x0; 590dfe86cbaSAdrian Hunter 591336c716aSSeungwon Jeon /* eMMC v4.5 or later */ 592bec8726aSGirish K S if (card->ext_csd.rev >= 6) { 593336c716aSSeungwon Jeon card->ext_csd.feature_support |= MMC_DISCARD_FEATURE; 594336c716aSSeungwon Jeon 595b23cf0bdSSeungwon Jeon card->ext_csd.generic_cmd6_time = 10 * 596b23cf0bdSSeungwon Jeon ext_csd[EXT_CSD_GENERIC_CMD6_TIME]; 597bec8726aSGirish K S card->ext_csd.power_off_longtime = 10 * 598bec8726aSGirish K S ext_csd[EXT_CSD_POWER_OFF_LONG_TIME]; 599b23cf0bdSSeungwon Jeon 600881d1c25SSeungwon Jeon card->ext_csd.cache_size = 601881d1c25SSeungwon Jeon ext_csd[EXT_CSD_CACHE_SIZE + 0] << 0 | 602881d1c25SSeungwon Jeon ext_csd[EXT_CSD_CACHE_SIZE + 1] << 8 | 603881d1c25SSeungwon Jeon ext_csd[EXT_CSD_CACHE_SIZE + 2] << 16 | 604881d1c25SSeungwon Jeon ext_csd[EXT_CSD_CACHE_SIZE + 3] << 24; 6054265900eSSaugata Das 6064265900eSSaugata Das if (ext_csd[EXT_CSD_DATA_SECTOR_SIZE] == 1) 6074265900eSSaugata Das card->ext_csd.data_sector_size = 4096; 6084265900eSSaugata Das else 6094265900eSSaugata Das card->ext_csd.data_sector_size = 512; 6104265900eSSaugata Das 6114265900eSSaugata Das if ((ext_csd[EXT_CSD_DATA_TAG_SUPPORT] & 1) && 6124265900eSSaugata Das (ext_csd[EXT_CSD_TAG_UNIT_SIZE] <= 8)) { 6134265900eSSaugata Das card->ext_csd.data_tag_unit_size = 6144265900eSSaugata Das ((unsigned int) 1 << ext_csd[EXT_CSD_TAG_UNIT_SIZE]) * 6154265900eSSaugata Das (card->ext_csd.data_sector_size); 6164265900eSSaugata Das } else { 6174265900eSSaugata Das card->ext_csd.data_tag_unit_size = 0; 6184265900eSSaugata Das } 619abd9ac14SSeungwon Jeon 620abd9ac14SSeungwon Jeon card->ext_csd.max_packed_writes = 621abd9ac14SSeungwon Jeon ext_csd[EXT_CSD_MAX_PACKED_WRITES]; 622abd9ac14SSeungwon Jeon card->ext_csd.max_packed_reads = 623abd9ac14SSeungwon Jeon ext_csd[EXT_CSD_MAX_PACKED_READS]; 624a5075eb9SSaugata Das } else { 625a5075eb9SSaugata Das card->ext_csd.data_sector_size = 512; 626336c716aSSeungwon Jeon } 627881d1c25SSeungwon Jeon 6280f762426SGwendal Grignou /* eMMC v5 or later */ 6290f762426SGwendal Grignou if (card->ext_csd.rev >= 7) { 6300f762426SGwendal Grignou memcpy(card->ext_csd.fwrev, &ext_csd[EXT_CSD_FIRMWARE_VERSION], 6310f762426SGwendal Grignou MMC_FIRMWARE_LEN); 6320f762426SGwendal Grignou card->ext_csd.ffu_capable = 6330f762426SGwendal Grignou (ext_csd[EXT_CSD_SUPPORTED_MODE] & 0x1) && 6340f762426SGwendal Grignou !(ext_csd[EXT_CSD_FW_CONFIG] & 0x1); 6350f762426SGwendal Grignou } 6367ea239d9SPierre Ossman out: 63708ee80ccSPhilip Rakity return err; 63808ee80ccSPhilip Rakity } 6397ea239d9SPierre Ossman 640f39b2dd9SPhilip Rakity static int mmc_compare_ext_csds(struct mmc_card *card, unsigned bus_width) 64108ee80ccSPhilip Rakity { 64208ee80ccSPhilip Rakity u8 *bw_ext_csd; 64308ee80ccSPhilip Rakity int err; 64408ee80ccSPhilip Rakity 645f39b2dd9SPhilip Rakity if (bus_width == MMC_BUS_WIDTH_1) 646f39b2dd9SPhilip Rakity return 0; 64708ee80ccSPhilip Rakity 648f39b2dd9SPhilip Rakity err = mmc_get_ext_csd(card, &bw_ext_csd); 649f39b2dd9SPhilip Rakity 650f39b2dd9SPhilip Rakity if (err || bw_ext_csd == NULL) { 65108ee80ccSPhilip Rakity err = -EINVAL; 65208ee80ccSPhilip Rakity goto out; 65308ee80ccSPhilip Rakity } 65408ee80ccSPhilip Rakity 65508ee80ccSPhilip Rakity /* only compare read only fields */ 656dd13b4edSJurgen Heeks err = !((card->ext_csd.raw_partition_support == 65708ee80ccSPhilip Rakity bw_ext_csd[EXT_CSD_PARTITION_SUPPORT]) && 658f39b2dd9SPhilip Rakity (card->ext_csd.raw_erased_mem_count == 65908ee80ccSPhilip Rakity bw_ext_csd[EXT_CSD_ERASED_MEM_CONT]) && 660f39b2dd9SPhilip Rakity (card->ext_csd.rev == 66108ee80ccSPhilip Rakity bw_ext_csd[EXT_CSD_REV]) && 662f39b2dd9SPhilip Rakity (card->ext_csd.raw_ext_csd_structure == 66308ee80ccSPhilip Rakity bw_ext_csd[EXT_CSD_STRUCTURE]) && 664f39b2dd9SPhilip Rakity (card->ext_csd.raw_card_type == 66508ee80ccSPhilip Rakity bw_ext_csd[EXT_CSD_CARD_TYPE]) && 666f39b2dd9SPhilip Rakity (card->ext_csd.raw_s_a_timeout == 66708ee80ccSPhilip Rakity bw_ext_csd[EXT_CSD_S_A_TIMEOUT]) && 668f39b2dd9SPhilip Rakity (card->ext_csd.raw_hc_erase_gap_size == 66908ee80ccSPhilip Rakity bw_ext_csd[EXT_CSD_HC_WP_GRP_SIZE]) && 670f39b2dd9SPhilip Rakity (card->ext_csd.raw_erase_timeout_mult == 67108ee80ccSPhilip Rakity bw_ext_csd[EXT_CSD_ERASE_TIMEOUT_MULT]) && 672f39b2dd9SPhilip Rakity (card->ext_csd.raw_hc_erase_grp_size == 67308ee80ccSPhilip Rakity bw_ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]) && 674f39b2dd9SPhilip Rakity (card->ext_csd.raw_sec_trim_mult == 67508ee80ccSPhilip Rakity bw_ext_csd[EXT_CSD_SEC_TRIM_MULT]) && 676f39b2dd9SPhilip Rakity (card->ext_csd.raw_sec_erase_mult == 67708ee80ccSPhilip Rakity bw_ext_csd[EXT_CSD_SEC_ERASE_MULT]) && 678f39b2dd9SPhilip Rakity (card->ext_csd.raw_sec_feature_support == 67908ee80ccSPhilip Rakity bw_ext_csd[EXT_CSD_SEC_FEATURE_SUPPORT]) && 680f39b2dd9SPhilip Rakity (card->ext_csd.raw_trim_mult == 68108ee80ccSPhilip Rakity bw_ext_csd[EXT_CSD_TRIM_MULT]) && 682f39b2dd9SPhilip Rakity (card->ext_csd.raw_sectors[0] == 683f39b2dd9SPhilip Rakity bw_ext_csd[EXT_CSD_SEC_CNT + 0]) && 684f39b2dd9SPhilip Rakity (card->ext_csd.raw_sectors[1] == 685f39b2dd9SPhilip Rakity bw_ext_csd[EXT_CSD_SEC_CNT + 1]) && 686f39b2dd9SPhilip Rakity (card->ext_csd.raw_sectors[2] == 687f39b2dd9SPhilip Rakity bw_ext_csd[EXT_CSD_SEC_CNT + 2]) && 688f39b2dd9SPhilip Rakity (card->ext_csd.raw_sectors[3] == 68960443712SFredrik Soderstedt bw_ext_csd[EXT_CSD_SEC_CNT + 3]) && 69060443712SFredrik Soderstedt (card->ext_csd.raw_pwr_cl_52_195 == 69160443712SFredrik Soderstedt bw_ext_csd[EXT_CSD_PWR_CL_52_195]) && 69260443712SFredrik Soderstedt (card->ext_csd.raw_pwr_cl_26_195 == 69360443712SFredrik Soderstedt bw_ext_csd[EXT_CSD_PWR_CL_26_195]) && 69460443712SFredrik Soderstedt (card->ext_csd.raw_pwr_cl_52_360 == 69560443712SFredrik Soderstedt bw_ext_csd[EXT_CSD_PWR_CL_52_360]) && 69660443712SFredrik Soderstedt (card->ext_csd.raw_pwr_cl_26_360 == 69760443712SFredrik Soderstedt bw_ext_csd[EXT_CSD_PWR_CL_26_360]) && 69860443712SFredrik Soderstedt (card->ext_csd.raw_pwr_cl_200_195 == 69960443712SFredrik Soderstedt bw_ext_csd[EXT_CSD_PWR_CL_200_195]) && 70060443712SFredrik Soderstedt (card->ext_csd.raw_pwr_cl_200_360 == 70160443712SFredrik Soderstedt bw_ext_csd[EXT_CSD_PWR_CL_200_360]) && 70260443712SFredrik Soderstedt (card->ext_csd.raw_pwr_cl_ddr_52_195 == 70360443712SFredrik Soderstedt bw_ext_csd[EXT_CSD_PWR_CL_DDR_52_195]) && 70460443712SFredrik Soderstedt (card->ext_csd.raw_pwr_cl_ddr_52_360 == 7050a5b6438SSeungwon Jeon bw_ext_csd[EXT_CSD_PWR_CL_DDR_52_360]) && 7060a5b6438SSeungwon Jeon (card->ext_csd.raw_pwr_cl_ddr_200_360 == 7070a5b6438SSeungwon Jeon bw_ext_csd[EXT_CSD_PWR_CL_DDR_200_360])); 7080a5b6438SSeungwon Jeon 70908ee80ccSPhilip Rakity if (err) 71008ee80ccSPhilip Rakity err = -EINVAL; 71108ee80ccSPhilip Rakity 71208ee80ccSPhilip Rakity out: 71300b41b58SUlf Hansson kfree(bw_ext_csd); 7147ea239d9SPierre Ossman return err; 7157ea239d9SPierre Ossman } 7167ea239d9SPierre Ossman 71751ec92e2SPierre Ossman MMC_DEV_ATTR(cid, "%08x%08x%08x%08x\n", card->raw_cid[0], card->raw_cid[1], 71851ec92e2SPierre Ossman card->raw_cid[2], card->raw_cid[3]); 71951ec92e2SPierre Ossman MMC_DEV_ATTR(csd, "%08x%08x%08x%08x\n", card->raw_csd[0], card->raw_csd[1], 72051ec92e2SPierre Ossman card->raw_csd[2], card->raw_csd[3]); 72151ec92e2SPierre Ossman MMC_DEV_ATTR(date, "%02d/%04d\n", card->cid.month, card->cid.year); 722dfe86cbaSAdrian Hunter MMC_DEV_ATTR(erase_size, "%u\n", card->erase_size << 9); 723dfe86cbaSAdrian Hunter MMC_DEV_ATTR(preferred_erase_size, "%u\n", card->pref_erase << 9); 7240f762426SGwendal Grignou MMC_DEV_ATTR(ffu_capable, "%d\n", card->ext_csd.ffu_capable); 72551ec92e2SPierre Ossman MMC_DEV_ATTR(hwrev, "0x%x\n", card->cid.hwrev); 72651ec92e2SPierre Ossman MMC_DEV_ATTR(manfid, "0x%06x\n", card->cid.manfid); 72751ec92e2SPierre Ossman MMC_DEV_ATTR(name, "%s\n", card->cid.prod_name); 72851ec92e2SPierre Ossman MMC_DEV_ATTR(oemid, "0x%04x\n", card->cid.oemid); 72951e7e8b6SBernie Thompson MMC_DEV_ATTR(prv, "0x%x\n", card->cid.prv); 73051ec92e2SPierre Ossman MMC_DEV_ATTR(serial, "0x%08x\n", card->cid.serial); 731709de99dSChuanxiao Dong MMC_DEV_ATTR(enhanced_area_offset, "%llu\n", 732709de99dSChuanxiao Dong card->ext_csd.enhanced_area_offset); 733709de99dSChuanxiao Dong MMC_DEV_ATTR(enhanced_area_size, "%u\n", card->ext_csd.enhanced_area_size); 734188cc042SLoic Pallardy MMC_DEV_ATTR(raw_rpmb_size_mult, "%#x\n", card->ext_csd.raw_rpmb_size_mult); 735188cc042SLoic Pallardy MMC_DEV_ATTR(rel_sectors, "%#x\n", card->ext_csd.rel_sectors); 73651ec92e2SPierre Ossman 7370f762426SGwendal Grignou static ssize_t mmc_fwrev_show(struct device *dev, 7380f762426SGwendal Grignou struct device_attribute *attr, 7390f762426SGwendal Grignou char *buf) 7400f762426SGwendal Grignou { 7410f762426SGwendal Grignou struct mmc_card *card = mmc_dev_to_card(dev); 7420f762426SGwendal Grignou 7430f762426SGwendal Grignou if (card->ext_csd.rev < 7) { 7440f762426SGwendal Grignou return sprintf(buf, "0x%x\n", card->cid.fwrev); 7450f762426SGwendal Grignou } else { 7460f762426SGwendal Grignou return sprintf(buf, "0x%*phN\n", MMC_FIRMWARE_LEN, 7470f762426SGwendal Grignou card->ext_csd.fwrev); 7480f762426SGwendal Grignou } 7490f762426SGwendal Grignou } 7500f762426SGwendal Grignou 7510f762426SGwendal Grignou static DEVICE_ATTR(fwrev, S_IRUGO, mmc_fwrev_show, NULL); 7520f762426SGwendal Grignou 75351ec92e2SPierre Ossman static struct attribute *mmc_std_attrs[] = { 75451ec92e2SPierre Ossman &dev_attr_cid.attr, 75551ec92e2SPierre Ossman &dev_attr_csd.attr, 75651ec92e2SPierre Ossman &dev_attr_date.attr, 757dfe86cbaSAdrian Hunter &dev_attr_erase_size.attr, 758dfe86cbaSAdrian Hunter &dev_attr_preferred_erase_size.attr, 75951ec92e2SPierre Ossman &dev_attr_fwrev.attr, 7600f762426SGwendal Grignou &dev_attr_ffu_capable.attr, 76151ec92e2SPierre Ossman &dev_attr_hwrev.attr, 76251ec92e2SPierre Ossman &dev_attr_manfid.attr, 76351ec92e2SPierre Ossman &dev_attr_name.attr, 76451ec92e2SPierre Ossman &dev_attr_oemid.attr, 76551e7e8b6SBernie Thompson &dev_attr_prv.attr, 76651ec92e2SPierre Ossman &dev_attr_serial.attr, 767709de99dSChuanxiao Dong &dev_attr_enhanced_area_offset.attr, 768709de99dSChuanxiao Dong &dev_attr_enhanced_area_size.attr, 769188cc042SLoic Pallardy &dev_attr_raw_rpmb_size_mult.attr, 770188cc042SLoic Pallardy &dev_attr_rel_sectors.attr, 77151ec92e2SPierre Ossman NULL, 77251ec92e2SPierre Ossman }; 773d1e58212SAxel Lin ATTRIBUTE_GROUPS(mmc_std); 77451ec92e2SPierre Ossman 77551ec92e2SPierre Ossman static struct device_type mmc_type = { 776d1e58212SAxel Lin .groups = mmc_std_groups, 77751ec92e2SPierre Ossman }; 77851ec92e2SPierre Ossman 7797ea239d9SPierre Ossman /* 780b87d8dbfSGirish K S * Select the PowerClass for the current bus width 781b87d8dbfSGirish K S * If power class is defined for 4/8 bit bus in the 782b87d8dbfSGirish K S * extended CSD register, select it by executing the 783b87d8dbfSGirish K S * mmc_switch command. 784b87d8dbfSGirish K S */ 7852385049dSSeungwon Jeon static int __mmc_select_powerclass(struct mmc_card *card, 78660443712SFredrik Soderstedt unsigned int bus_width) 787b87d8dbfSGirish K S { 7882385049dSSeungwon Jeon struct mmc_host *host = card->host; 7892385049dSSeungwon Jeon struct mmc_ext_csd *ext_csd = &card->ext_csd; 79060443712SFredrik Soderstedt unsigned int pwrclass_val = 0; 7912385049dSSeungwon Jeon int err = 0; 792b87d8dbfSGirish K S 793b87d8dbfSGirish K S switch (1 << host->ios.vdd) { 794b87d8dbfSGirish K S case MMC_VDD_165_195: 7952385049dSSeungwon Jeon if (host->ios.clock <= MMC_HIGH_26_MAX_DTR) 7962385049dSSeungwon Jeon pwrclass_val = ext_csd->raw_pwr_cl_26_195; 7972385049dSSeungwon Jeon else if (host->ios.clock <= MMC_HIGH_52_MAX_DTR) 79860443712SFredrik Soderstedt pwrclass_val = (bus_width <= EXT_CSD_BUS_WIDTH_8) ? 7992385049dSSeungwon Jeon ext_csd->raw_pwr_cl_52_195 : 8002385049dSSeungwon Jeon ext_csd->raw_pwr_cl_ddr_52_195; 8012385049dSSeungwon Jeon else if (host->ios.clock <= MMC_HS200_MAX_DTR) 8022385049dSSeungwon Jeon pwrclass_val = ext_csd->raw_pwr_cl_200_195; 803b87d8dbfSGirish K S break; 80493fc5a47SSubhash Jadavani case MMC_VDD_27_28: 80593fc5a47SSubhash Jadavani case MMC_VDD_28_29: 80693fc5a47SSubhash Jadavani case MMC_VDD_29_30: 80793fc5a47SSubhash Jadavani case MMC_VDD_30_31: 80893fc5a47SSubhash Jadavani case MMC_VDD_31_32: 809b87d8dbfSGirish K S case MMC_VDD_32_33: 810b87d8dbfSGirish K S case MMC_VDD_33_34: 811b87d8dbfSGirish K S case MMC_VDD_34_35: 812b87d8dbfSGirish K S case MMC_VDD_35_36: 8132385049dSSeungwon Jeon if (host->ios.clock <= MMC_HIGH_26_MAX_DTR) 8142385049dSSeungwon Jeon pwrclass_val = ext_csd->raw_pwr_cl_26_360; 8152385049dSSeungwon Jeon else if (host->ios.clock <= MMC_HIGH_52_MAX_DTR) 81660443712SFredrik Soderstedt pwrclass_val = (bus_width <= EXT_CSD_BUS_WIDTH_8) ? 8172385049dSSeungwon Jeon ext_csd->raw_pwr_cl_52_360 : 8182385049dSSeungwon Jeon ext_csd->raw_pwr_cl_ddr_52_360; 8192385049dSSeungwon Jeon else if (host->ios.clock <= MMC_HS200_MAX_DTR) 8200a5b6438SSeungwon Jeon pwrclass_val = (bus_width == EXT_CSD_DDR_BUS_WIDTH_8) ? 8210a5b6438SSeungwon Jeon ext_csd->raw_pwr_cl_ddr_200_360 : 8220a5b6438SSeungwon Jeon ext_csd->raw_pwr_cl_200_360; 823b87d8dbfSGirish K S break; 824b87d8dbfSGirish K S default: 8256606110dSJoe Perches pr_warn("%s: Voltage range not supported for power class\n", 8266606110dSJoe Perches mmc_hostname(host)); 827b87d8dbfSGirish K S return -EINVAL; 828b87d8dbfSGirish K S } 829b87d8dbfSGirish K S 830b87d8dbfSGirish K S if (bus_width & (EXT_CSD_BUS_WIDTH_8 | EXT_CSD_DDR_BUS_WIDTH_8)) 831b87d8dbfSGirish K S pwrclass_val = (pwrclass_val & EXT_CSD_PWR_CL_8BIT_MASK) >> 832b87d8dbfSGirish K S EXT_CSD_PWR_CL_8BIT_SHIFT; 833b87d8dbfSGirish K S else 834b87d8dbfSGirish K S pwrclass_val = (pwrclass_val & EXT_CSD_PWR_CL_4BIT_MASK) >> 835b87d8dbfSGirish K S EXT_CSD_PWR_CL_4BIT_SHIFT; 836b87d8dbfSGirish K S 837b87d8dbfSGirish K S /* If the power class is different from the default value */ 838b87d8dbfSGirish K S if (pwrclass_val > 0) { 839b87d8dbfSGirish K S err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, 840b87d8dbfSGirish K S EXT_CSD_POWER_CLASS, 841b87d8dbfSGirish K S pwrclass_val, 84271fe3eb0SSeungwon Jeon card->ext_csd.generic_cmd6_time); 843b87d8dbfSGirish K S } 844b87d8dbfSGirish K S 845b87d8dbfSGirish K S return err; 846b87d8dbfSGirish K S } 847b87d8dbfSGirish K S 8482385049dSSeungwon Jeon static int mmc_select_powerclass(struct mmc_card *card) 8492385049dSSeungwon Jeon { 8502385049dSSeungwon Jeon struct mmc_host *host = card->host; 8512385049dSSeungwon Jeon u32 bus_width, ext_csd_bits; 8522385049dSSeungwon Jeon int err, ddr; 8532385049dSSeungwon Jeon 8542385049dSSeungwon Jeon /* Power class selection is supported for versions >= 4.0 */ 855148bcab2SUlf Hansson if (!mmc_can_ext_csd(card)) 8562385049dSSeungwon Jeon return 0; 8572385049dSSeungwon Jeon 8582385049dSSeungwon Jeon bus_width = host->ios.bus_width; 8592385049dSSeungwon Jeon /* Power class values are defined only for 4/8 bit bus */ 8602385049dSSeungwon Jeon if (bus_width == MMC_BUS_WIDTH_1) 8612385049dSSeungwon Jeon return 0; 8622385049dSSeungwon Jeon 8632385049dSSeungwon Jeon ddr = card->mmc_avail_type & EXT_CSD_CARD_TYPE_DDR_52; 8642385049dSSeungwon Jeon if (ddr) 8652385049dSSeungwon Jeon ext_csd_bits = (bus_width == MMC_BUS_WIDTH_8) ? 8662385049dSSeungwon Jeon EXT_CSD_DDR_BUS_WIDTH_8 : EXT_CSD_DDR_BUS_WIDTH_4; 8672385049dSSeungwon Jeon else 8682385049dSSeungwon Jeon ext_csd_bits = (bus_width == MMC_BUS_WIDTH_8) ? 8692385049dSSeungwon Jeon EXT_CSD_BUS_WIDTH_8 : EXT_CSD_BUS_WIDTH_4; 8702385049dSSeungwon Jeon 8712385049dSSeungwon Jeon err = __mmc_select_powerclass(card, ext_csd_bits); 8722385049dSSeungwon Jeon if (err) 8732385049dSSeungwon Jeon pr_warn("%s: power class selection to bus width %d ddr %d failed\n", 8742385049dSSeungwon Jeon mmc_hostname(host), 1 << bus_width, ddr); 8752385049dSSeungwon Jeon 8762385049dSSeungwon Jeon return err; 8772385049dSSeungwon Jeon } 8782385049dSSeungwon Jeon 879b87d8dbfSGirish K S /* 880577fb131SSeungwon Jeon * Set the bus speed for the selected speed mode. 881a4924c71SGirish K S */ 882577fb131SSeungwon Jeon static void mmc_set_bus_speed(struct mmc_card *card) 883a4924c71SGirish K S { 884577fb131SSeungwon Jeon unsigned int max_dtr = (unsigned int)-1; 885577fb131SSeungwon Jeon 8860a5b6438SSeungwon Jeon if ((mmc_card_hs200(card) || mmc_card_hs400(card)) && 8870a5b6438SSeungwon Jeon max_dtr > card->ext_csd.hs200_max_dtr) 888577fb131SSeungwon Jeon max_dtr = card->ext_csd.hs200_max_dtr; 889577fb131SSeungwon Jeon else if (mmc_card_hs(card) && max_dtr > card->ext_csd.hs_max_dtr) 890577fb131SSeungwon Jeon max_dtr = card->ext_csd.hs_max_dtr; 891577fb131SSeungwon Jeon else if (max_dtr > card->csd.max_dtr) 892577fb131SSeungwon Jeon max_dtr = card->csd.max_dtr; 893577fb131SSeungwon Jeon 894577fb131SSeungwon Jeon mmc_set_clock(card->host, max_dtr); 895577fb131SSeungwon Jeon } 896577fb131SSeungwon Jeon 897577fb131SSeungwon Jeon /* 898577fb131SSeungwon Jeon * Select the bus width amoung 4-bit and 8-bit(SDR). 899577fb131SSeungwon Jeon * If the bus width is changed successfully, return the selected width value. 900577fb131SSeungwon Jeon * Zero is returned instead of error value if the wide width is not supported. 901577fb131SSeungwon Jeon */ 902577fb131SSeungwon Jeon static int mmc_select_bus_width(struct mmc_card *card) 903577fb131SSeungwon Jeon { 904a4924c71SGirish K S static unsigned ext_csd_bits[] = { 905a4924c71SGirish K S EXT_CSD_BUS_WIDTH_8, 906577fb131SSeungwon Jeon EXT_CSD_BUS_WIDTH_4, 907a4924c71SGirish K S }; 908a4924c71SGirish K S static unsigned bus_widths[] = { 909a4924c71SGirish K S MMC_BUS_WIDTH_8, 910577fb131SSeungwon Jeon MMC_BUS_WIDTH_4, 911a4924c71SGirish K S }; 912577fb131SSeungwon Jeon struct mmc_host *host = card->host; 913577fb131SSeungwon Jeon unsigned idx, bus_width = 0; 914577fb131SSeungwon Jeon int err = 0; 915a4924c71SGirish K S 916148bcab2SUlf Hansson if (!mmc_can_ext_csd(card) && 917577fb131SSeungwon Jeon !(host->caps & (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA))) 918577fb131SSeungwon Jeon return 0; 919a4924c71SGirish K S 920577fb131SSeungwon Jeon idx = (host->caps & MMC_CAP_8_BIT_DATA) ? 0 : 1; 921a4924c71SGirish K S 922a4924c71SGirish K S /* 923a4924c71SGirish K S * Unlike SD, MMC cards dont have a configuration register to notify 924a4924c71SGirish K S * supported bus width. So bus test command should be run to identify 925a4924c71SGirish K S * the supported bus width or compare the ext csd values of current 926a4924c71SGirish K S * bus width and ext csd values of 1 bit mode read earlier. 927a4924c71SGirish K S */ 928577fb131SSeungwon Jeon for (; idx < ARRAY_SIZE(bus_widths); idx++) { 929a4924c71SGirish K S /* 930a4924c71SGirish K S * Host is capable of 8bit transfer, then switch 931a4924c71SGirish K S * the device to work in 8bit transfer mode. If the 932a4924c71SGirish K S * mmc switch command returns error then switch to 933a4924c71SGirish K S * 4bit transfer mode. On success set the corresponding 934a4924c71SGirish K S * bus width on the host. 935a4924c71SGirish K S */ 936a4924c71SGirish K S err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, 937a4924c71SGirish K S EXT_CSD_BUS_WIDTH, 938a4924c71SGirish K S ext_csd_bits[idx], 939a4924c71SGirish K S card->ext_csd.generic_cmd6_time); 940a4924c71SGirish K S if (err) 941a4924c71SGirish K S continue; 942a4924c71SGirish K S 943577fb131SSeungwon Jeon bus_width = bus_widths[idx]; 944577fb131SSeungwon Jeon mmc_set_bus_width(host, bus_width); 945a4924c71SGirish K S 946577fb131SSeungwon Jeon /* 947577fb131SSeungwon Jeon * If controller can't handle bus width test, 948577fb131SSeungwon Jeon * compare ext_csd previously read in 1 bit mode 949577fb131SSeungwon Jeon * against ext_csd at new bus width 950577fb131SSeungwon Jeon */ 951a4924c71SGirish K S if (!(host->caps & MMC_CAP_BUS_WIDTH_TEST)) 952577fb131SSeungwon Jeon err = mmc_compare_ext_csds(card, bus_width); 953a4924c71SGirish K S else 954577fb131SSeungwon Jeon err = mmc_bus_test(card, bus_width); 955577fb131SSeungwon Jeon 956577fb131SSeungwon Jeon if (!err) { 957577fb131SSeungwon Jeon err = bus_width; 958a4924c71SGirish K S break; 959577fb131SSeungwon Jeon } else { 960577fb131SSeungwon Jeon pr_warn("%s: switch to bus width %d failed\n", 961577fb131SSeungwon Jeon mmc_hostname(host), ext_csd_bits[idx]); 962577fb131SSeungwon Jeon } 963a4924c71SGirish K S } 964a4924c71SGirish K S 965577fb131SSeungwon Jeon return err; 966577fb131SSeungwon Jeon } 967577fb131SSeungwon Jeon 968577fb131SSeungwon Jeon /* 969577fb131SSeungwon Jeon * Switch to the high-speed mode 970577fb131SSeungwon Jeon */ 971577fb131SSeungwon Jeon static int mmc_select_hs(struct mmc_card *card) 972577fb131SSeungwon Jeon { 973577fb131SSeungwon Jeon int err; 974577fb131SSeungwon Jeon 9754509f847SUlf Hansson err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, 976577fb131SSeungwon Jeon EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS, 97757de31f6SUlf Hansson card->ext_csd.generic_cmd6_time, 97857de31f6SUlf Hansson true, true, true); 979577fb131SSeungwon Jeon if (!err) 980577fb131SSeungwon Jeon mmc_set_timing(card->host, MMC_TIMING_MMC_HS); 981577fb131SSeungwon Jeon 982577fb131SSeungwon Jeon return err; 983577fb131SSeungwon Jeon } 984577fb131SSeungwon Jeon 985577fb131SSeungwon Jeon /* 986577fb131SSeungwon Jeon * Activate wide bus and DDR if supported. 987577fb131SSeungwon Jeon */ 988577fb131SSeungwon Jeon static int mmc_select_hs_ddr(struct mmc_card *card) 989577fb131SSeungwon Jeon { 990577fb131SSeungwon Jeon struct mmc_host *host = card->host; 991577fb131SSeungwon Jeon u32 bus_width, ext_csd_bits; 992577fb131SSeungwon Jeon int err = 0; 993577fb131SSeungwon Jeon 994577fb131SSeungwon Jeon if (!(card->mmc_avail_type & EXT_CSD_CARD_TYPE_DDR_52)) 995577fb131SSeungwon Jeon return 0; 996577fb131SSeungwon Jeon 997577fb131SSeungwon Jeon bus_width = host->ios.bus_width; 998577fb131SSeungwon Jeon if (bus_width == MMC_BUS_WIDTH_1) 999577fb131SSeungwon Jeon return 0; 1000577fb131SSeungwon Jeon 1001577fb131SSeungwon Jeon ext_csd_bits = (bus_width == MMC_BUS_WIDTH_8) ? 1002577fb131SSeungwon Jeon EXT_CSD_DDR_BUS_WIDTH_8 : EXT_CSD_DDR_BUS_WIDTH_4; 1003577fb131SSeungwon Jeon 1004577fb131SSeungwon Jeon err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, 1005577fb131SSeungwon Jeon EXT_CSD_BUS_WIDTH, 1006577fb131SSeungwon Jeon ext_csd_bits, 1007577fb131SSeungwon Jeon card->ext_csd.generic_cmd6_time); 1008577fb131SSeungwon Jeon if (err) { 10094b75bffcSAndrew Gabbasov pr_err("%s: switch to bus width %d ddr failed\n", 1010577fb131SSeungwon Jeon mmc_hostname(host), 1 << bus_width); 1011577fb131SSeungwon Jeon return err; 1012577fb131SSeungwon Jeon } 1013577fb131SSeungwon Jeon 1014577fb131SSeungwon Jeon /* 1015577fb131SSeungwon Jeon * eMMC cards can support 3.3V to 1.2V i/o (vccq) 1016577fb131SSeungwon Jeon * signaling. 1017577fb131SSeungwon Jeon * 1018577fb131SSeungwon Jeon * EXT_CSD_CARD_TYPE_DDR_1_8V means 3.3V or 1.8V vccq. 1019577fb131SSeungwon Jeon * 1020577fb131SSeungwon Jeon * 1.8V vccq at 3.3V core voltage (vcc) is not required 1021577fb131SSeungwon Jeon * in the JEDEC spec for DDR. 1022577fb131SSeungwon Jeon * 1023312449efSChuanxiao.Dong * Even (e)MMC card can support 3.3v to 1.2v vccq, but not all 1024312449efSChuanxiao.Dong * host controller can support this, like some of the SDHCI 1025312449efSChuanxiao.Dong * controller which connect to an eMMC device. Some of these 1026312449efSChuanxiao.Dong * host controller still needs to use 1.8v vccq for supporting 1027312449efSChuanxiao.Dong * DDR mode. 1028312449efSChuanxiao.Dong * 1029312449efSChuanxiao.Dong * So the sequence will be: 1030312449efSChuanxiao.Dong * if (host and device can both support 1.2v IO) 1031312449efSChuanxiao.Dong * use 1.2v IO; 1032312449efSChuanxiao.Dong * else if (host and device can both support 1.8v IO) 1033312449efSChuanxiao.Dong * use 1.8v IO; 1034312449efSChuanxiao.Dong * so if host and device can only support 3.3v IO, this is the 1035312449efSChuanxiao.Dong * last choice. 1036577fb131SSeungwon Jeon * 1037577fb131SSeungwon Jeon * WARNING: eMMC rules are NOT the same as SD DDR 1038577fb131SSeungwon Jeon */ 1039312449efSChuanxiao.Dong err = -EINVAL; 1040312449efSChuanxiao.Dong if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_DDR_1_2V) 1041312449efSChuanxiao.Dong err = __mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_120); 1042577fb131SSeungwon Jeon 1043312449efSChuanxiao.Dong if (err && (card->mmc_avail_type & EXT_CSD_CARD_TYPE_DDR_1_8V)) 1044312449efSChuanxiao.Dong err = __mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180); 1045312449efSChuanxiao.Dong 1046312449efSChuanxiao.Dong /* make sure vccq is 3.3v after switching disaster */ 1047312449efSChuanxiao.Dong if (err) 1048312449efSChuanxiao.Dong err = __mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_330); 1049312449efSChuanxiao.Dong 1050312449efSChuanxiao.Dong if (!err) 1051577fb131SSeungwon Jeon mmc_set_timing(host, MMC_TIMING_MMC_DDR52); 1052577fb131SSeungwon Jeon 1053577fb131SSeungwon Jeon return err; 1054577fb131SSeungwon Jeon } 1055577fb131SSeungwon Jeon 10560a5b6438SSeungwon Jeon static int mmc_select_hs400(struct mmc_card *card) 10570a5b6438SSeungwon Jeon { 10580a5b6438SSeungwon Jeon struct mmc_host *host = card->host; 10590a5b6438SSeungwon Jeon int err = 0; 10600a5b6438SSeungwon Jeon 10610a5b6438SSeungwon Jeon /* 10620a5b6438SSeungwon Jeon * HS400 mode requires 8-bit bus width 10630a5b6438SSeungwon Jeon */ 10640a5b6438SSeungwon Jeon if (!(card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400 && 10650a5b6438SSeungwon Jeon host->ios.bus_width == MMC_BUS_WIDTH_8)) 10660a5b6438SSeungwon Jeon return 0; 10670a5b6438SSeungwon Jeon 10680a5b6438SSeungwon Jeon /* 10690a5b6438SSeungwon Jeon * Before switching to dual data rate operation for HS400, 10700a5b6438SSeungwon Jeon * it is required to convert from HS200 mode to HS mode. 10710a5b6438SSeungwon Jeon */ 10720a5b6438SSeungwon Jeon mmc_set_timing(card->host, MMC_TIMING_MMC_HS); 10730a5b6438SSeungwon Jeon mmc_set_bus_speed(card); 10740a5b6438SSeungwon Jeon 10750a5b6438SSeungwon Jeon err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, 10760a5b6438SSeungwon Jeon EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS, 10770a5b6438SSeungwon Jeon card->ext_csd.generic_cmd6_time, 10780a5b6438SSeungwon Jeon true, true, true); 10790a5b6438SSeungwon Jeon if (err) { 10804b75bffcSAndrew Gabbasov pr_err("%s: switch to high-speed from hs200 failed, err:%d\n", 10810a5b6438SSeungwon Jeon mmc_hostname(host), err); 10820a5b6438SSeungwon Jeon return err; 10830a5b6438SSeungwon Jeon } 10840a5b6438SSeungwon Jeon 10850a5b6438SSeungwon Jeon err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, 10860a5b6438SSeungwon Jeon EXT_CSD_BUS_WIDTH, 10870a5b6438SSeungwon Jeon EXT_CSD_DDR_BUS_WIDTH_8, 10880a5b6438SSeungwon Jeon card->ext_csd.generic_cmd6_time); 10890a5b6438SSeungwon Jeon if (err) { 10904b75bffcSAndrew Gabbasov pr_err("%s: switch to bus width for hs400 failed, err:%d\n", 10910a5b6438SSeungwon Jeon mmc_hostname(host), err); 10920a5b6438SSeungwon Jeon return err; 10930a5b6438SSeungwon Jeon } 10940a5b6438SSeungwon Jeon 10950a5b6438SSeungwon Jeon err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, 10960a5b6438SSeungwon Jeon EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS400, 10970a5b6438SSeungwon Jeon card->ext_csd.generic_cmd6_time, 10980a5b6438SSeungwon Jeon true, true, true); 10990a5b6438SSeungwon Jeon if (err) { 11004b75bffcSAndrew Gabbasov pr_err("%s: switch to hs400 failed, err:%d\n", 11010a5b6438SSeungwon Jeon mmc_hostname(host), err); 11020a5b6438SSeungwon Jeon return err; 11030a5b6438SSeungwon Jeon } 11040a5b6438SSeungwon Jeon 11050a5b6438SSeungwon Jeon mmc_set_timing(host, MMC_TIMING_MMC_HS400); 11060a5b6438SSeungwon Jeon mmc_set_bus_speed(card); 11070a5b6438SSeungwon Jeon 11080a5b6438SSeungwon Jeon return 0; 11090a5b6438SSeungwon Jeon } 11100a5b6438SSeungwon Jeon 1111577fb131SSeungwon Jeon /* 1112577fb131SSeungwon Jeon * For device supporting HS200 mode, the following sequence 1113577fb131SSeungwon Jeon * should be done before executing the tuning process. 1114577fb131SSeungwon Jeon * 1. set the desired bus width(4-bit or 8-bit, 1-bit is not supported) 1115577fb131SSeungwon Jeon * 2. switch to HS200 mode 1116577fb131SSeungwon Jeon * 3. set the clock to > 52Mhz and <=200MHz 1117577fb131SSeungwon Jeon */ 1118577fb131SSeungwon Jeon static int mmc_select_hs200(struct mmc_card *card) 1119577fb131SSeungwon Jeon { 1120577fb131SSeungwon Jeon struct mmc_host *host = card->host; 1121577fb131SSeungwon Jeon int err = -EINVAL; 1122577fb131SSeungwon Jeon 1123577fb131SSeungwon Jeon if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS200_1_2V) 1124577fb131SSeungwon Jeon err = __mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_120); 1125577fb131SSeungwon Jeon 1126577fb131SSeungwon Jeon if (err && card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS200_1_8V) 1127577fb131SSeungwon Jeon err = __mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180); 1128577fb131SSeungwon Jeon 1129577fb131SSeungwon Jeon /* If fails try again during next card power cycle */ 1130577fb131SSeungwon Jeon if (err) 1131577fb131SSeungwon Jeon goto err; 1132577fb131SSeungwon Jeon 1133577fb131SSeungwon Jeon /* 1134577fb131SSeungwon Jeon * Set the bus width(4 or 8) with host's support and 1135577fb131SSeungwon Jeon * switch to HS200 mode if bus width is set successfully. 1136577fb131SSeungwon Jeon */ 1137577fb131SSeungwon Jeon err = mmc_select_bus_width(card); 1138577fb131SSeungwon Jeon if (!IS_ERR_VALUE(err)) { 1139577fb131SSeungwon Jeon err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, 1140577fb131SSeungwon Jeon EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS200, 1141577fb131SSeungwon Jeon card->ext_csd.generic_cmd6_time, 1142577fb131SSeungwon Jeon true, true, true); 1143577fb131SSeungwon Jeon if (!err) 1144577fb131SSeungwon Jeon mmc_set_timing(host, MMC_TIMING_MMC_HS200); 1145577fb131SSeungwon Jeon } 1146a4924c71SGirish K S err: 1147a4924c71SGirish K S return err; 1148a4924c71SGirish K S } 1149a4924c71SGirish K S 1150a4924c71SGirish K S /* 1151577fb131SSeungwon Jeon * Activate High Speed or HS200 mode if supported. 1152577fb131SSeungwon Jeon */ 1153577fb131SSeungwon Jeon static int mmc_select_timing(struct mmc_card *card) 1154577fb131SSeungwon Jeon { 1155577fb131SSeungwon Jeon int err = 0; 1156577fb131SSeungwon Jeon 1157148bcab2SUlf Hansson if (!mmc_can_ext_csd(card)) 1158577fb131SSeungwon Jeon goto bus_speed; 1159577fb131SSeungwon Jeon 1160577fb131SSeungwon Jeon if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS200) 1161577fb131SSeungwon Jeon err = mmc_select_hs200(card); 1162577fb131SSeungwon Jeon else if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS) 1163577fb131SSeungwon Jeon err = mmc_select_hs(card); 1164577fb131SSeungwon Jeon 1165577fb131SSeungwon Jeon if (err && err != -EBADMSG) 1166577fb131SSeungwon Jeon return err; 1167577fb131SSeungwon Jeon 1168577fb131SSeungwon Jeon if (err) { 1169577fb131SSeungwon Jeon pr_warn("%s: switch to %s failed\n", 1170577fb131SSeungwon Jeon mmc_card_hs(card) ? "high-speed" : 1171577fb131SSeungwon Jeon (mmc_card_hs200(card) ? "hs200" : ""), 1172577fb131SSeungwon Jeon mmc_hostname(card->host)); 1173577fb131SSeungwon Jeon err = 0; 1174577fb131SSeungwon Jeon } 1175577fb131SSeungwon Jeon 1176577fb131SSeungwon Jeon bus_speed: 1177577fb131SSeungwon Jeon /* 1178577fb131SSeungwon Jeon * Set the bus speed to the selected bus timing. 1179577fb131SSeungwon Jeon * If timing is not selected, backward compatible is the default. 1180577fb131SSeungwon Jeon */ 1181577fb131SSeungwon Jeon mmc_set_bus_speed(card); 1182577fb131SSeungwon Jeon return err; 1183577fb131SSeungwon Jeon } 1184577fb131SSeungwon Jeon 118548d11e06SStephen Boyd const u8 tuning_blk_pattern_4bit[MMC_TUNING_BLK_PATTERN_4BIT_SIZE] = { 118648d11e06SStephen Boyd 0xff, 0x0f, 0xff, 0x00, 0xff, 0xcc, 0xc3, 0xcc, 118748d11e06SStephen Boyd 0xc3, 0x3c, 0xcc, 0xff, 0xfe, 0xff, 0xfe, 0xef, 118848d11e06SStephen Boyd 0xff, 0xdf, 0xff, 0xdd, 0xff, 0xfb, 0xff, 0xfb, 118948d11e06SStephen Boyd 0xbf, 0xff, 0x7f, 0xff, 0x77, 0xf7, 0xbd, 0xef, 119048d11e06SStephen Boyd 0xff, 0xf0, 0xff, 0xf0, 0x0f, 0xfc, 0xcc, 0x3c, 119148d11e06SStephen Boyd 0xcc, 0x33, 0xcc, 0xcf, 0xff, 0xef, 0xff, 0xee, 119248d11e06SStephen Boyd 0xff, 0xfd, 0xff, 0xfd, 0xdf, 0xff, 0xbf, 0xff, 119348d11e06SStephen Boyd 0xbb, 0xff, 0xf7, 0xff, 0xf7, 0x7f, 0x7b, 0xde, 119448d11e06SStephen Boyd }; 119548d11e06SStephen Boyd EXPORT_SYMBOL(tuning_blk_pattern_4bit); 119648d11e06SStephen Boyd 119748d11e06SStephen Boyd const u8 tuning_blk_pattern_8bit[MMC_TUNING_BLK_PATTERN_8BIT_SIZE] = { 119848d11e06SStephen Boyd 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 119948d11e06SStephen Boyd 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc, 0xcc, 120048d11e06SStephen Boyd 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff, 0xff, 120148d11e06SStephen Boyd 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee, 0xff, 120248d11e06SStephen Boyd 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd, 0xdd, 120348d11e06SStephen Boyd 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb, 120448d11e06SStephen Boyd 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff, 0xff, 120548d11e06SStephen Boyd 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee, 0xff, 120648d11e06SStephen Boyd 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 120748d11e06SStephen Boyd 0x00, 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc, 120848d11e06SStephen Boyd 0xcc, 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff, 120948d11e06SStephen Boyd 0xff, 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee, 121048d11e06SStephen Boyd 0xff, 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd, 121148d11e06SStephen Boyd 0xdd, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, 121248d11e06SStephen Boyd 0xbb, 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff, 121348d11e06SStephen Boyd 0xff, 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee, 121448d11e06SStephen Boyd }; 121548d11e06SStephen Boyd EXPORT_SYMBOL(tuning_blk_pattern_8bit); 121648d11e06SStephen Boyd 1217577fb131SSeungwon Jeon /* 1218577fb131SSeungwon Jeon * Execute tuning sequence to seek the proper bus operating 12190a5b6438SSeungwon Jeon * conditions for HS200 and HS400, which sends CMD21 to the device. 1220577fb131SSeungwon Jeon */ 1221577fb131SSeungwon Jeon static int mmc_hs200_tuning(struct mmc_card *card) 1222577fb131SSeungwon Jeon { 1223577fb131SSeungwon Jeon struct mmc_host *host = card->host; 1224577fb131SSeungwon Jeon int err = 0; 1225577fb131SSeungwon Jeon 12260a5b6438SSeungwon Jeon /* 12270a5b6438SSeungwon Jeon * Timing should be adjusted to the HS400 target 12280a5b6438SSeungwon Jeon * operation frequency for tuning process 12290a5b6438SSeungwon Jeon */ 12300a5b6438SSeungwon Jeon if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400 && 12310a5b6438SSeungwon Jeon host->ios.bus_width == MMC_BUS_WIDTH_8) 12320a5b6438SSeungwon Jeon if (host->ops->prepare_hs400_tuning) 12330a5b6438SSeungwon Jeon host->ops->prepare_hs400_tuning(host, &host->ios); 12340a5b6438SSeungwon Jeon 1235577fb131SSeungwon Jeon if (host->ops->execute_tuning) { 1236577fb131SSeungwon Jeon mmc_host_clk_hold(host); 1237577fb131SSeungwon Jeon err = host->ops->execute_tuning(host, 1238577fb131SSeungwon Jeon MMC_SEND_TUNING_BLOCK_HS200); 1239577fb131SSeungwon Jeon mmc_host_clk_release(host); 1240577fb131SSeungwon Jeon 1241577fb131SSeungwon Jeon if (err) 12424b75bffcSAndrew Gabbasov pr_err("%s: tuning execution failed\n", 1243577fb131SSeungwon Jeon mmc_hostname(host)); 1244577fb131SSeungwon Jeon } 1245577fb131SSeungwon Jeon 1246577fb131SSeungwon Jeon return err; 1247577fb131SSeungwon Jeon } 1248577fb131SSeungwon Jeon 1249577fb131SSeungwon Jeon /* 12506abaa0c9SPierre Ossman * Handle the detection and initialisation of a card. 12516abaa0c9SPierre Ossman * 12528769392bSDeepak Saxena * In the case of a resume, "oldcard" will contain the card 12536abaa0c9SPierre Ossman * we're trying to reinitialise. 12547ea239d9SPierre Ossman */ 12558c75deaeSPierre Ossman static int mmc_init_card(struct mmc_host *host, u32 ocr, 12566abaa0c9SPierre Ossman struct mmc_card *oldcard) 12577ea239d9SPierre Ossman { 12587ea239d9SPierre Ossman struct mmc_card *card; 1259577fb131SSeungwon Jeon int err; 12607ea239d9SPierre Ossman u32 cid[4]; 1261b676f039SPhilip Rakity u32 rocr; 126208ee80ccSPhilip Rakity u8 *ext_csd = NULL; 12637ea239d9SPierre Ossman 12647ea239d9SPierre Ossman BUG_ON(!host); 1265d84075c8SPierre Ossman WARN_ON(!host->claimed); 12667ea239d9SPierre Ossman 126744669034SStefan Nilsson XK /* Set correct bus mode for MMC before attempting init */ 126844669034SStefan Nilsson XK if (!mmc_host_is_spi(host)) 126944669034SStefan Nilsson XK mmc_set_bus_mode(host, MMC_BUSMODE_OPENDRAIN); 127044669034SStefan Nilsson XK 12717ea239d9SPierre Ossman /* 12727ea239d9SPierre Ossman * Since we're changing the OCR value, we seem to 12737ea239d9SPierre Ossman * need to tell some cards to go back to the idle 12747ea239d9SPierre Ossman * state. We wait 1ms to give cards time to 12757ea239d9SPierre Ossman * respond. 1276c3805467SBalaji T K * mmc_go_idle is needed for eMMC that are asleep 12777ea239d9SPierre Ossman */ 12787ea239d9SPierre Ossman mmc_go_idle(host); 12797ea239d9SPierre Ossman 12807ea239d9SPierre Ossman /* The extra bit indicates that we support high capacity */ 1281b676f039SPhilip Rakity err = mmc_send_op_cond(host, ocr | (1 << 30), &rocr); 128217b0429dSPierre Ossman if (err) 12836abaa0c9SPierre Ossman goto err; 12847ea239d9SPierre Ossman 12857ea239d9SPierre Ossman /* 1286af517150SDavid Brownell * For SPI, enable CRC as appropriate. 1287af517150SDavid Brownell */ 1288af517150SDavid Brownell if (mmc_host_is_spi(host)) { 1289af517150SDavid Brownell err = mmc_spi_set_crc(host, use_spi_crc); 1290af517150SDavid Brownell if (err) 1291af517150SDavid Brownell goto err; 1292af517150SDavid Brownell } 1293af517150SDavid Brownell 1294af517150SDavid Brownell /* 12957ea239d9SPierre Ossman * Fetch CID from card. 12967ea239d9SPierre Ossman */ 1297af517150SDavid Brownell if (mmc_host_is_spi(host)) 1298af517150SDavid Brownell err = mmc_send_cid(host, cid); 1299af517150SDavid Brownell else 13007ea239d9SPierre Ossman err = mmc_all_send_cid(host, cid); 130117b0429dSPierre Ossman if (err) 13027ea239d9SPierre Ossman goto err; 13037ea239d9SPierre Ossman 13046abaa0c9SPierre Ossman if (oldcard) { 1305adf66a0dSPierre Ossman if (memcmp(cid, oldcard->raw_cid, sizeof(cid)) != 0) { 1306adf66a0dSPierre Ossman err = -ENOENT; 13076abaa0c9SPierre Ossman goto err; 1308adf66a0dSPierre Ossman } 13096abaa0c9SPierre Ossman 13106abaa0c9SPierre Ossman card = oldcard; 13116abaa0c9SPierre Ossman } else { 13127ea239d9SPierre Ossman /* 13137ea239d9SPierre Ossman * Allocate card structure. 13147ea239d9SPierre Ossman */ 131551ec92e2SPierre Ossman card = mmc_alloc_card(host, &mmc_type); 1316adf66a0dSPierre Ossman if (IS_ERR(card)) { 1317adf66a0dSPierre Ossman err = PTR_ERR(card); 13187ea239d9SPierre Ossman goto err; 1319adf66a0dSPierre Ossman } 13207ea239d9SPierre Ossman 132169041150SUlf Hansson card->ocr = ocr; 13227ea239d9SPierre Ossman card->type = MMC_TYPE_MMC; 13237ea239d9SPierre Ossman card->rca = 1; 13247ea239d9SPierre Ossman memcpy(card->raw_cid, cid, sizeof(card->raw_cid)); 13256abaa0c9SPierre Ossman } 13267ea239d9SPierre Ossman 13277ea239d9SPierre Ossman /* 1328af517150SDavid Brownell * For native busses: set card RCA and quit open drain mode. 13297ea239d9SPierre Ossman */ 1330af517150SDavid Brownell if (!mmc_host_is_spi(host)) { 13317ea239d9SPierre Ossman err = mmc_set_relative_addr(card); 133217b0429dSPierre Ossman if (err) 13337ea239d9SPierre Ossman goto free_card; 13347ea239d9SPierre Ossman 13357ea239d9SPierre Ossman mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL); 1336af517150SDavid Brownell } 13377ea239d9SPierre Ossman 13386abaa0c9SPierre Ossman if (!oldcard) { 13397ea239d9SPierre Ossman /* 13407ea239d9SPierre Ossman * Fetch CSD from card. 13417ea239d9SPierre Ossman */ 13427ea239d9SPierre Ossman err = mmc_send_csd(card, card->raw_csd); 134317b0429dSPierre Ossman if (err) 13447ea239d9SPierre Ossman goto free_card; 13457ea239d9SPierre Ossman 1346bd766312SPierre Ossman err = mmc_decode_csd(card); 1347adf66a0dSPierre Ossman if (err) 1348bd766312SPierre Ossman goto free_card; 1349bd766312SPierre Ossman err = mmc_decode_cid(card); 1350adf66a0dSPierre Ossman if (err) 1351bd766312SPierre Ossman goto free_card; 13526abaa0c9SPierre Ossman } 13537ea239d9SPierre Ossman 13547ea239d9SPierre Ossman /* 13553d705d14SSascha Hauer * handling only for cards supporting DSR and hosts requesting 13563d705d14SSascha Hauer * DSR configuration 13573d705d14SSascha Hauer */ 13583d705d14SSascha Hauer if (card->csd.dsr_imp && host->dsr_req) 13593d705d14SSascha Hauer mmc_set_dsr(host); 13603d705d14SSascha Hauer 13613d705d14SSascha Hauer /* 136289a73cf5SPierre Ossman * Select card, as all following commands rely on that. 13637ea239d9SPierre Ossman */ 1364af517150SDavid Brownell if (!mmc_host_is_spi(host)) { 13657ea239d9SPierre Ossman err = mmc_select_card(card); 136617b0429dSPierre Ossman if (err) 13677ea239d9SPierre Ossman goto free_card; 1368af517150SDavid Brownell } 13697ea239d9SPierre Ossman 13706abaa0c9SPierre Ossman if (!oldcard) { 137189a73cf5SPierre Ossman /* 1372af517150SDavid Brownell * Fetch and process extended CSD. 137389a73cf5SPierre Ossman */ 137408ee80ccSPhilip Rakity 137508ee80ccSPhilip Rakity err = mmc_get_ext_csd(card, &ext_csd); 137608ee80ccSPhilip Rakity if (err) 137708ee80ccSPhilip Rakity goto free_card; 137808ee80ccSPhilip Rakity err = mmc_read_ext_csd(card, ext_csd); 137917b0429dSPierre Ossman if (err) 13807ea239d9SPierre Ossman goto free_card; 1381b676f039SPhilip Rakity 1382b676f039SPhilip Rakity /* If doing byte addressing, check if required to do sector 1383b676f039SPhilip Rakity * addressing. Handle the case of <2GB cards needing sector 1384b676f039SPhilip Rakity * addressing. See section 8.1 JEDEC Standard JED84-A441; 1385b676f039SPhilip Rakity * ocr register has bit 30 set for sector addressing. 1386b676f039SPhilip Rakity */ 1387b676f039SPhilip Rakity if (!(mmc_card_blockaddr(card)) && (rocr & (1<<30))) 1388b676f039SPhilip Rakity mmc_card_set_blockaddr(card); 1389b676f039SPhilip Rakity 1390dfe86cbaSAdrian Hunter /* Erase size depends on CSD and Extended CSD */ 1391dfe86cbaSAdrian Hunter mmc_set_erase_size(card); 13926abaa0c9SPierre Ossman } 13937ea239d9SPierre Ossman 13947ea239d9SPierre Ossman /* 1395709de99dSChuanxiao Dong * If enhanced_area_en is TRUE, host needs to enable ERASE_GRP_DEF 1396709de99dSChuanxiao Dong * bit. This bit will be lost every time after a reset or power off. 1397709de99dSChuanxiao Dong */ 139869803d4fSGrégory Soutadé if (card->ext_csd.partition_setting_completed || 139983bb24aaSAdrian Hunter (card->ext_csd.rev >= 3 && (host->caps2 & MMC_CAP2_HC_ERASE_SZ))) { 1400709de99dSChuanxiao Dong err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, 1401b23cf0bdSSeungwon Jeon EXT_CSD_ERASE_GROUP_DEF, 1, 1402b23cf0bdSSeungwon Jeon card->ext_csd.generic_cmd6_time); 1403709de99dSChuanxiao Dong 1404709de99dSChuanxiao Dong if (err && err != -EBADMSG) 1405709de99dSChuanxiao Dong goto free_card; 1406709de99dSChuanxiao Dong 1407709de99dSChuanxiao Dong if (err) { 1408709de99dSChuanxiao Dong err = 0; 1409709de99dSChuanxiao Dong /* 1410709de99dSChuanxiao Dong * Just disable enhanced area off & sz 1411709de99dSChuanxiao Dong * will try to enable ERASE_GROUP_DEF 1412709de99dSChuanxiao Dong * during next time reinit 1413709de99dSChuanxiao Dong */ 1414709de99dSChuanxiao Dong card->ext_csd.enhanced_area_offset = -EINVAL; 1415709de99dSChuanxiao Dong card->ext_csd.enhanced_area_size = -EINVAL; 1416709de99dSChuanxiao Dong } else { 1417709de99dSChuanxiao Dong card->ext_csd.erase_group_def = 1; 1418709de99dSChuanxiao Dong /* 1419709de99dSChuanxiao Dong * enable ERASE_GRP_DEF successfully. 1420709de99dSChuanxiao Dong * This will affect the erase size, so 1421709de99dSChuanxiao Dong * here need to reset erase size 1422709de99dSChuanxiao Dong */ 1423709de99dSChuanxiao Dong mmc_set_erase_size(card); 1424709de99dSChuanxiao Dong } 1425709de99dSChuanxiao Dong } 1426709de99dSChuanxiao Dong 1427709de99dSChuanxiao Dong /* 142841e2a489SPhilip Rakity * Ensure eMMC user default partition is enabled 142941e2a489SPhilip Rakity */ 1430371a689fSAndrei Warkentin if (card->ext_csd.part_config & EXT_CSD_PART_CONFIG_ACC_MASK) { 1431371a689fSAndrei Warkentin card->ext_csd.part_config &= ~EXT_CSD_PART_CONFIG_ACC_MASK; 1432371a689fSAndrei Warkentin err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONFIG, 1433371a689fSAndrei Warkentin card->ext_csd.part_config, 1434371a689fSAndrei Warkentin card->ext_csd.part_time); 1435371a689fSAndrei Warkentin if (err && err != -EBADMSG) 1436371a689fSAndrei Warkentin goto free_card; 143741e2a489SPhilip Rakity } 143841e2a489SPhilip Rakity 143941e2a489SPhilip Rakity /* 144043235679SUlf Hansson * Enable power_off_notification byte in the ext_csd register 1441bec8726aSGirish K S */ 144243235679SUlf Hansson if (card->ext_csd.rev >= 6) { 1443bec8726aSGirish K S err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, 1444bec8726aSGirish K S EXT_CSD_POWER_OFF_NOTIFICATION, 1445bec8726aSGirish K S EXT_CSD_POWER_ON, 1446bec8726aSGirish K S card->ext_csd.generic_cmd6_time); 1447bec8726aSGirish K S if (err && err != -EBADMSG) 1448bec8726aSGirish K S goto free_card; 1449bec8726aSGirish K S 145096a85d54SGirish K S /* 145196a85d54SGirish K S * The err can be -EBADMSG or 0, 145296a85d54SGirish K S * so check for success and update the flag 145396a85d54SGirish K S */ 1454bec8726aSGirish K S if (!err) 1455e6c08586SUlf Hansson card->ext_csd.power_off_notification = EXT_CSD_POWER_ON; 145696a85d54SGirish K S } 1457bec8726aSGirish K S 1458bec8726aSGirish K S /* 1459577fb131SSeungwon Jeon * Select timing interface 146089a73cf5SPierre Ossman */ 1461577fb131SSeungwon Jeon err = mmc_select_timing(card); 1462577fb131SSeungwon Jeon if (err) 146389a73cf5SPierre Ossman goto free_card; 146489a73cf5SPierre Ossman 1465a4924c71SGirish K S if (mmc_card_hs200(card)) { 1466577fb131SSeungwon Jeon err = mmc_hs200_tuning(card); 14674c4cb171SPhilip Rakity if (err) 14684b75bffcSAndrew Gabbasov goto free_card; 14690a5b6438SSeungwon Jeon 14700a5b6438SSeungwon Jeon err = mmc_select_hs400(card); 14710a5b6438SSeungwon Jeon if (err) 14724b75bffcSAndrew Gabbasov goto free_card; 1473577fb131SSeungwon Jeon } else if (mmc_card_hs(card)) { 1474577fb131SSeungwon Jeon /* Select the desired bus width optionally */ 1475577fb131SSeungwon Jeon err = mmc_select_bus_width(card); 1476577fb131SSeungwon Jeon if (!IS_ERR_VALUE(err)) { 1477577fb131SSeungwon Jeon err = mmc_select_hs_ddr(card); 1478577fb131SSeungwon Jeon if (err) 14794b75bffcSAndrew Gabbasov goto free_card; 148089a73cf5SPierre Ossman } 1481ef0b27d4SAdrian Hunter } 148289a73cf5SPierre Ossman 1483881d1c25SSeungwon Jeon /* 14842385049dSSeungwon Jeon * Choose the power class with selected bus interface 14852385049dSSeungwon Jeon */ 14862385049dSSeungwon Jeon mmc_select_powerclass(card); 14872385049dSSeungwon Jeon 14882385049dSSeungwon Jeon /* 148952d0974eSSubhash Jadavani * Enable HPI feature (if supported) 149052d0974eSSubhash Jadavani */ 149152d0974eSSubhash Jadavani if (card->ext_csd.hpi) { 149252d0974eSSubhash Jadavani err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, 149352d0974eSSubhash Jadavani EXT_CSD_HPI_MGMT, 1, 149452d0974eSSubhash Jadavani card->ext_csd.generic_cmd6_time); 149552d0974eSSubhash Jadavani if (err && err != -EBADMSG) 149652d0974eSSubhash Jadavani goto free_card; 149752d0974eSSubhash Jadavani if (err) { 14986606110dSJoe Perches pr_warn("%s: Enabling HPI failed\n", 149952d0974eSSubhash Jadavani mmc_hostname(card->host)); 150052d0974eSSubhash Jadavani err = 0; 150152d0974eSSubhash Jadavani } else 150252d0974eSSubhash Jadavani card->ext_csd.hpi_en = 1; 150352d0974eSSubhash Jadavani } 150452d0974eSSubhash Jadavani 150552d0974eSSubhash Jadavani /* 1506881d1c25SSeungwon Jeon * If cache size is higher than 0, this indicates 1507881d1c25SSeungwon Jeon * the existence of cache and it can be turned on. 1508881d1c25SSeungwon Jeon */ 15097536d3f8SUlf Hansson if (card->ext_csd.cache_size > 0) { 1510881d1c25SSeungwon Jeon err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, 15118bc0678bSSeungwon Jeon EXT_CSD_CACHE_CTRL, 1, 15128bc0678bSSeungwon Jeon card->ext_csd.generic_cmd6_time); 1513881d1c25SSeungwon Jeon if (err && err != -EBADMSG) 1514881d1c25SSeungwon Jeon goto free_card; 1515881d1c25SSeungwon Jeon 1516881d1c25SSeungwon Jeon /* 1517881d1c25SSeungwon Jeon * Only if no error, cache is turned on successfully. 1518881d1c25SSeungwon Jeon */ 15198bc0678bSSeungwon Jeon if (err) { 15206606110dSJoe Perches pr_warn("%s: Cache is supported, but failed to turn on (%d)\n", 15218bc0678bSSeungwon Jeon mmc_hostname(card->host), err); 15228bc0678bSSeungwon Jeon card->ext_csd.cache_ctrl = 0; 15238bc0678bSSeungwon Jeon err = 0; 15248bc0678bSSeungwon Jeon } else { 15258bc0678bSSeungwon Jeon card->ext_csd.cache_ctrl = 1; 15268bc0678bSSeungwon Jeon } 1527881d1c25SSeungwon Jeon } 1528881d1c25SSeungwon Jeon 1529abd9ac14SSeungwon Jeon /* 1530abd9ac14SSeungwon Jeon * The mandatory minimum values are defined for packed command. 1531abd9ac14SSeungwon Jeon * read: 5, write: 3 1532abd9ac14SSeungwon Jeon */ 1533abd9ac14SSeungwon Jeon if (card->ext_csd.max_packed_writes >= 3 && 1534abd9ac14SSeungwon Jeon card->ext_csd.max_packed_reads >= 5 && 1535abd9ac14SSeungwon Jeon host->caps2 & MMC_CAP2_PACKED_CMD) { 1536abd9ac14SSeungwon Jeon err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, 1537abd9ac14SSeungwon Jeon EXT_CSD_EXP_EVENTS_CTRL, 1538abd9ac14SSeungwon Jeon EXT_CSD_PACKED_EVENT_EN, 1539abd9ac14SSeungwon Jeon card->ext_csd.generic_cmd6_time); 1540abd9ac14SSeungwon Jeon if (err && err != -EBADMSG) 1541abd9ac14SSeungwon Jeon goto free_card; 1542abd9ac14SSeungwon Jeon if (err) { 1543abd9ac14SSeungwon Jeon pr_warn("%s: Enabling packed event failed\n", 1544abd9ac14SSeungwon Jeon mmc_hostname(card->host)); 1545abd9ac14SSeungwon Jeon card->ext_csd.packed_event_en = 0; 1546abd9ac14SSeungwon Jeon err = 0; 1547abd9ac14SSeungwon Jeon } else { 1548abd9ac14SSeungwon Jeon card->ext_csd.packed_event_en = 1; 1549abd9ac14SSeungwon Jeon } 1550abd9ac14SSeungwon Jeon } 1551abd9ac14SSeungwon Jeon 15526abaa0c9SPierre Ossman if (!oldcard) 15537ea239d9SPierre Ossman host->card = card; 15547ea239d9SPierre Ossman 155500b41b58SUlf Hansson kfree(ext_csd); 155617b0429dSPierre Ossman return 0; 15576abaa0c9SPierre Ossman 15586abaa0c9SPierre Ossman free_card: 15596abaa0c9SPierre Ossman if (!oldcard) 15606abaa0c9SPierre Ossman mmc_remove_card(card); 15616abaa0c9SPierre Ossman err: 156200b41b58SUlf Hansson kfree(ext_csd); 15636abaa0c9SPierre Ossman 1564adf66a0dSPierre Ossman return err; 15656abaa0c9SPierre Ossman } 15666abaa0c9SPierre Ossman 156707a68216SUlf Hansson static int mmc_can_sleep(struct mmc_card *card) 156807a68216SUlf Hansson { 156907a68216SUlf Hansson return (card && card->ext_csd.rev >= 3); 157007a68216SUlf Hansson } 157107a68216SUlf Hansson 157207a68216SUlf Hansson static int mmc_sleep(struct mmc_host *host) 157307a68216SUlf Hansson { 157407a68216SUlf Hansson struct mmc_command cmd = {0}; 157507a68216SUlf Hansson struct mmc_card *card = host->card; 1576cb962e04SUlf Hansson unsigned int timeout_ms = DIV_ROUND_UP(card->ext_csd.sa_timeout, 10000); 157707a68216SUlf Hansson int err; 157807a68216SUlf Hansson 157907a68216SUlf Hansson err = mmc_deselect_cards(host); 158007a68216SUlf Hansson if (err) 158107a68216SUlf Hansson return err; 158207a68216SUlf Hansson 158307a68216SUlf Hansson cmd.opcode = MMC_SLEEP_AWAKE; 158407a68216SUlf Hansson cmd.arg = card->rca << 16; 158507a68216SUlf Hansson cmd.arg |= 1 << 15; 158607a68216SUlf Hansson 1587cb962e04SUlf Hansson /* 1588cb962e04SUlf Hansson * If the max_busy_timeout of the host is specified, validate it against 1589cb962e04SUlf Hansson * the sleep cmd timeout. A failure means we need to prevent the host 1590cb962e04SUlf Hansson * from doing hw busy detection, which is done by converting to a R1 1591cb962e04SUlf Hansson * response instead of a R1B. 1592cb962e04SUlf Hansson */ 1593cb962e04SUlf Hansson if (host->max_busy_timeout && (timeout_ms > host->max_busy_timeout)) { 1594cb962e04SUlf Hansson cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; 1595cb962e04SUlf Hansson } else { 159607a68216SUlf Hansson cmd.flags = MMC_RSP_R1B | MMC_CMD_AC; 1597cb962e04SUlf Hansson cmd.busy_timeout = timeout_ms; 1598cb962e04SUlf Hansson } 1599cb962e04SUlf Hansson 160007a68216SUlf Hansson err = mmc_wait_for_cmd(host, &cmd, 0); 160107a68216SUlf Hansson if (err) 160207a68216SUlf Hansson return err; 160307a68216SUlf Hansson 160407a68216SUlf Hansson /* 160507a68216SUlf Hansson * If the host does not wait while the card signals busy, then we will 160607a68216SUlf Hansson * will have to wait the sleep/awake timeout. Note, we cannot use the 160707a68216SUlf Hansson * SEND_STATUS command to poll the status because that command (and most 160807a68216SUlf Hansson * others) is invalid while the card sleeps. 160907a68216SUlf Hansson */ 1610cb962e04SUlf Hansson if (!cmd.busy_timeout || !(host->caps & MMC_CAP_WAIT_WHILE_BUSY)) 1611cb962e04SUlf Hansson mmc_delay(timeout_ms); 161207a68216SUlf Hansson 161307a68216SUlf Hansson return err; 161407a68216SUlf Hansson } 161507a68216SUlf Hansson 1616e6c08586SUlf Hansson static int mmc_can_poweroff_notify(const struct mmc_card *card) 1617e6c08586SUlf Hansson { 1618e6c08586SUlf Hansson return card && 1619e6c08586SUlf Hansson mmc_card_mmc(card) && 1620e6c08586SUlf Hansson (card->ext_csd.power_off_notification == EXT_CSD_POWER_ON); 1621e6c08586SUlf Hansson } 1622e6c08586SUlf Hansson 1623e6c08586SUlf Hansson static int mmc_poweroff_notify(struct mmc_card *card, unsigned int notify_type) 1624e6c08586SUlf Hansson { 1625e6c08586SUlf Hansson unsigned int timeout = card->ext_csd.generic_cmd6_time; 1626e6c08586SUlf Hansson int err; 1627e6c08586SUlf Hansson 1628e6c08586SUlf Hansson /* Use EXT_CSD_POWER_OFF_SHORT as default notification type. */ 1629e6c08586SUlf Hansson if (notify_type == EXT_CSD_POWER_OFF_LONG) 1630e6c08586SUlf Hansson timeout = card->ext_csd.power_off_longtime; 1631e6c08586SUlf Hansson 1632878e200bSUlf Hansson err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, 1633e6c08586SUlf Hansson EXT_CSD_POWER_OFF_NOTIFICATION, 16344509f847SUlf Hansson notify_type, timeout, true, false, false); 1635e6c08586SUlf Hansson if (err) 1636e6c08586SUlf Hansson pr_err("%s: Power Off Notification timed out, %u\n", 1637e6c08586SUlf Hansson mmc_hostname(card->host), timeout); 1638e6c08586SUlf Hansson 1639e6c08586SUlf Hansson /* Disable the power off notification after the switch operation. */ 1640e6c08586SUlf Hansson card->ext_csd.power_off_notification = EXT_CSD_NO_POWER_NOTIFICATION; 1641e6c08586SUlf Hansson 1642e6c08586SUlf Hansson return err; 1643e6c08586SUlf Hansson } 1644e6c08586SUlf Hansson 16456abaa0c9SPierre Ossman /* 16466abaa0c9SPierre Ossman * Host is being removed. Free up the current card. 16476abaa0c9SPierre Ossman */ 16486abaa0c9SPierre Ossman static void mmc_remove(struct mmc_host *host) 16496abaa0c9SPierre Ossman { 16506abaa0c9SPierre Ossman BUG_ON(!host); 16516abaa0c9SPierre Ossman BUG_ON(!host->card); 16526abaa0c9SPierre Ossman 16536abaa0c9SPierre Ossman mmc_remove_card(host->card); 16546abaa0c9SPierre Ossman host->card = NULL; 16556abaa0c9SPierre Ossman } 16566abaa0c9SPierre Ossman 16576abaa0c9SPierre Ossman /* 1658d3049504SAdrian Hunter * Card detection - card is alive. 1659d3049504SAdrian Hunter */ 1660d3049504SAdrian Hunter static int mmc_alive(struct mmc_host *host) 1661d3049504SAdrian Hunter { 1662d3049504SAdrian Hunter return mmc_send_status(host->card, NULL); 1663d3049504SAdrian Hunter } 1664d3049504SAdrian Hunter 1665d3049504SAdrian Hunter /* 16666abaa0c9SPierre Ossman * Card detection callback from host. 16676abaa0c9SPierre Ossman */ 16686abaa0c9SPierre Ossman static void mmc_detect(struct mmc_host *host) 16696abaa0c9SPierre Ossman { 16706abaa0c9SPierre Ossman int err; 16716abaa0c9SPierre Ossman 16726abaa0c9SPierre Ossman BUG_ON(!host); 16736abaa0c9SPierre Ossman BUG_ON(!host->card); 16746abaa0c9SPierre Ossman 1675e94cfef6SUlf Hansson mmc_get_card(host->card); 16766abaa0c9SPierre Ossman 16776abaa0c9SPierre Ossman /* 16786abaa0c9SPierre Ossman * Just check if our card has been removed. 16796abaa0c9SPierre Ossman */ 1680d3049504SAdrian Hunter err = _mmc_detect_card_removed(host); 16816abaa0c9SPierre Ossman 1682e94cfef6SUlf Hansson mmc_put_card(host->card); 16837ea239d9SPierre Ossman 168417b0429dSPierre Ossman if (err) { 16854101c16aSPierre Ossman mmc_remove(host); 16866abaa0c9SPierre Ossman 16876abaa0c9SPierre Ossman mmc_claim_host(host); 16886abaa0c9SPierre Ossman mmc_detach_bus(host); 16897f7e4129SUlf Hansson mmc_power_off(host); 16906abaa0c9SPierre Ossman mmc_release_host(host); 16916abaa0c9SPierre Ossman } 16926abaa0c9SPierre Ossman } 16936abaa0c9SPierre Ossman 169403d071fcSUlf Hansson static int _mmc_suspend(struct mmc_host *host, bool is_suspend) 16956abaa0c9SPierre Ossman { 1696c3805467SBalaji T K int err = 0; 169703d071fcSUlf Hansson unsigned int notify_type = is_suspend ? EXT_CSD_POWER_OFF_SHORT : 169803d071fcSUlf Hansson EXT_CSD_POWER_OFF_LONG; 1699c3805467SBalaji T K 17006abaa0c9SPierre Ossman BUG_ON(!host); 17016abaa0c9SPierre Ossman BUG_ON(!host->card); 17026abaa0c9SPierre Ossman 17036abaa0c9SPierre Ossman mmc_claim_host(host); 1704881d926dSMaya Erez 17059ec775f7SUlf Hansson if (mmc_card_suspended(host->card)) 17069ec775f7SUlf Hansson goto out; 17079ec775f7SUlf Hansson 170839b9431bSUlf Hansson if (mmc_card_doing_bkops(host->card)) { 170939b9431bSUlf Hansson err = mmc_stop_bkops(host->card); 171039b9431bSUlf Hansson if (err) 171139b9431bSUlf Hansson goto out; 171239b9431bSUlf Hansson } 171339b9431bSUlf Hansson 171410e5d965SUlf Hansson err = mmc_flush_cache(host->card); 1715881d926dSMaya Erez if (err) 1716881d926dSMaya Erez goto out; 1717881d926dSMaya Erez 171843235679SUlf Hansson if (mmc_can_poweroff_notify(host->card) && 171953275c21SUlf Hansson ((host->caps2 & MMC_CAP2_FULL_PWR_CYCLE) || !is_suspend)) 172003d071fcSUlf Hansson err = mmc_poweroff_notify(host->card, notify_type); 172107a68216SUlf Hansson else if (mmc_can_sleep(host->card)) 172207a68216SUlf Hansson err = mmc_sleep(host); 1723e6c08586SUlf Hansson else if (!mmc_host_is_spi(host)) 172485e727edSJaehoon Chung err = mmc_deselect_cards(host); 172595cdfb72SNicolas Pitre 17269ec775f7SUlf Hansson if (!err) { 172774590263SUlf Hansson mmc_power_off(host); 17289ec775f7SUlf Hansson mmc_card_set_suspended(host->card); 17299ec775f7SUlf Hansson } 1730881d926dSMaya Erez out: 1731881d926dSMaya Erez mmc_release_host(host); 1732c3805467SBalaji T K return err; 17336abaa0c9SPierre Ossman } 17346abaa0c9SPierre Ossman 17356abaa0c9SPierre Ossman /* 17360cb403a2SUlf Hansson * Suspend callback 173703d071fcSUlf Hansson */ 173803d071fcSUlf Hansson static int mmc_suspend(struct mmc_host *host) 173903d071fcSUlf Hansson { 17400cb403a2SUlf Hansson int err; 17410cb403a2SUlf Hansson 17420cb403a2SUlf Hansson err = _mmc_suspend(host, true); 17430cb403a2SUlf Hansson if (!err) { 17440cb403a2SUlf Hansson pm_runtime_disable(&host->card->dev); 17450cb403a2SUlf Hansson pm_runtime_set_suspended(&host->card->dev); 17460cb403a2SUlf Hansson } 17470cb403a2SUlf Hansson 17480cb403a2SUlf Hansson return err; 174903d071fcSUlf Hansson } 175003d071fcSUlf Hansson 175103d071fcSUlf Hansson /* 17526abaa0c9SPierre Ossman * This function tries to determine if the same card is still present 17536abaa0c9SPierre Ossman * and, if so, restore all state to it. 17546abaa0c9SPierre Ossman */ 17550cb403a2SUlf Hansson static int _mmc_resume(struct mmc_host *host) 17566abaa0c9SPierre Ossman { 17579ec775f7SUlf Hansson int err = 0; 17586abaa0c9SPierre Ossman 17596abaa0c9SPierre Ossman BUG_ON(!host); 17606abaa0c9SPierre Ossman BUG_ON(!host->card); 17616abaa0c9SPierre Ossman 17626abaa0c9SPierre Ossman mmc_claim_host(host); 17639ec775f7SUlf Hansson 17649ec775f7SUlf Hansson if (!mmc_card_suspended(host->card)) 17659ec775f7SUlf Hansson goto out; 17669ec775f7SUlf Hansson 176769041150SUlf Hansson mmc_power_up(host, host->card->ocr); 176869041150SUlf Hansson err = mmc_init_card(host, host->card->ocr, host->card); 17699ec775f7SUlf Hansson mmc_card_clr_suspended(host->card); 17702986d0bfSPierre Ossman 17719ec775f7SUlf Hansson out: 17729ec775f7SUlf Hansson mmc_release_host(host); 177395cdfb72SNicolas Pitre return err; 17746abaa0c9SPierre Ossman } 17756abaa0c9SPierre Ossman 17769ec775f7SUlf Hansson /* 17779ec775f7SUlf Hansson * Shutdown callback 17789ec775f7SUlf Hansson */ 17799ec775f7SUlf Hansson static int mmc_shutdown(struct mmc_host *host) 17809ec775f7SUlf Hansson { 17819ec775f7SUlf Hansson int err = 0; 17829ec775f7SUlf Hansson 17839ec775f7SUlf Hansson /* 17849ec775f7SUlf Hansson * In a specific case for poweroff notify, we need to resume the card 17859ec775f7SUlf Hansson * before we can shutdown it properly. 17869ec775f7SUlf Hansson */ 17879ec775f7SUlf Hansson if (mmc_can_poweroff_notify(host->card) && 17889ec775f7SUlf Hansson !(host->caps2 & MMC_CAP2_FULL_PWR_CYCLE)) 17890cb403a2SUlf Hansson err = _mmc_resume(host); 17909ec775f7SUlf Hansson 17919ec775f7SUlf Hansson if (!err) 17929ec775f7SUlf Hansson err = _mmc_suspend(host, false); 17939ec775f7SUlf Hansson 17949ec775f7SUlf Hansson return err; 17959ec775f7SUlf Hansson } 1796c4d770d7SUlf Hansson 1797c4d770d7SUlf Hansson /* 17980cb403a2SUlf Hansson * Callback for resume. 17990cb403a2SUlf Hansson */ 18000cb403a2SUlf Hansson static int mmc_resume(struct mmc_host *host) 18010cb403a2SUlf Hansson { 18024d223782SUlf Hansson int err = 0; 18030cb403a2SUlf Hansson 18044d223782SUlf Hansson if (!(host->caps & MMC_CAP_RUNTIME_RESUME)) { 18050cb403a2SUlf Hansson err = _mmc_resume(host); 18060cb403a2SUlf Hansson pm_runtime_set_active(&host->card->dev); 18070cb403a2SUlf Hansson pm_runtime_mark_last_busy(&host->card->dev); 18084d223782SUlf Hansson } 18090cb403a2SUlf Hansson pm_runtime_enable(&host->card->dev); 18100cb403a2SUlf Hansson 18110cb403a2SUlf Hansson return err; 18120cb403a2SUlf Hansson } 18130cb403a2SUlf Hansson 18140cb403a2SUlf Hansson /* 1815c4d770d7SUlf Hansson * Callback for runtime_suspend. 1816c4d770d7SUlf Hansson */ 1817c4d770d7SUlf Hansson static int mmc_runtime_suspend(struct mmc_host *host) 1818c4d770d7SUlf Hansson { 1819c4d770d7SUlf Hansson int err; 1820c4d770d7SUlf Hansson 1821c4d770d7SUlf Hansson if (!(host->caps & MMC_CAP_AGGRESSIVE_PM)) 1822c4d770d7SUlf Hansson return 0; 1823c4d770d7SUlf Hansson 18240cb403a2SUlf Hansson err = _mmc_suspend(host, true); 18250cc81a8cSUlf Hansson if (err) 1826c4d770d7SUlf Hansson pr_err("%s: error %d doing aggessive suspend\n", 1827c4d770d7SUlf Hansson mmc_hostname(host), err); 1828c4d770d7SUlf Hansson 1829c4d770d7SUlf Hansson return err; 1830c4d770d7SUlf Hansson } 1831c4d770d7SUlf Hansson 1832c4d770d7SUlf Hansson /* 1833c4d770d7SUlf Hansson * Callback for runtime_resume. 1834c4d770d7SUlf Hansson */ 1835c4d770d7SUlf Hansson static int mmc_runtime_resume(struct mmc_host *host) 1836c4d770d7SUlf Hansson { 1837c4d770d7SUlf Hansson int err; 1838c4d770d7SUlf Hansson 18394d223782SUlf Hansson if (!(host->caps & (MMC_CAP_AGGRESSIVE_PM | MMC_CAP_RUNTIME_RESUME))) 1840c4d770d7SUlf Hansson return 0; 1841c4d770d7SUlf Hansson 18420cb403a2SUlf Hansson err = _mmc_resume(host); 1843c4d770d7SUlf Hansson if (err) 1844c4d770d7SUlf Hansson pr_err("%s: error %d doing aggessive resume\n", 1845c4d770d7SUlf Hansson mmc_hostname(host), err); 1846c4d770d7SUlf Hansson 1847c4d770d7SUlf Hansson return 0; 1848c4d770d7SUlf Hansson } 1849c4d770d7SUlf Hansson 185012ae637fSOhad Ben-Cohen static int mmc_power_restore(struct mmc_host *host) 1851eae1aeeeSAdrian Hunter { 185212ae637fSOhad Ben-Cohen int ret; 185312ae637fSOhad Ben-Cohen 1854eae1aeeeSAdrian Hunter mmc_claim_host(host); 185569041150SUlf Hansson ret = mmc_init_card(host, host->card->ocr, host->card); 1856eae1aeeeSAdrian Hunter mmc_release_host(host); 185712ae637fSOhad Ben-Cohen 185812ae637fSOhad Ben-Cohen return ret; 1859eae1aeeeSAdrian Hunter } 1860eae1aeeeSAdrian Hunter 18619feae246SAdrian Hunter static const struct mmc_bus_ops mmc_ops = { 18629feae246SAdrian Hunter .remove = mmc_remove, 18639feae246SAdrian Hunter .detect = mmc_detect, 18649feae246SAdrian Hunter .suspend = mmc_suspend, 18659feae246SAdrian Hunter .resume = mmc_resume, 1866c4d770d7SUlf Hansson .runtime_suspend = mmc_runtime_suspend, 1867c4d770d7SUlf Hansson .runtime_resume = mmc_runtime_resume, 1868eae1aeeeSAdrian Hunter .power_restore = mmc_power_restore, 1869d3049504SAdrian Hunter .alive = mmc_alive, 1870486fdbbcSUlf Hansson .shutdown = mmc_shutdown, 18719feae246SAdrian Hunter }; 18729feae246SAdrian Hunter 18736abaa0c9SPierre Ossman /* 18746abaa0c9SPierre Ossman * Starting point for MMC card init. 18756abaa0c9SPierre Ossman */ 1876807e8e40SAndy Ross int mmc_attach_mmc(struct mmc_host *host) 18776abaa0c9SPierre Ossman { 18786abaa0c9SPierre Ossman int err; 187969041150SUlf Hansson u32 ocr, rocr; 18806abaa0c9SPierre Ossman 18816abaa0c9SPierre Ossman BUG_ON(!host); 1882d84075c8SPierre Ossman WARN_ON(!host->claimed); 18836abaa0c9SPierre Ossman 188444669034SStefan Nilsson XK /* Set correct bus mode for MMC before attempting attach */ 188544669034SStefan Nilsson XK if (!mmc_host_is_spi(host)) 188644669034SStefan Nilsson XK mmc_set_bus_mode(host, MMC_BUSMODE_OPENDRAIN); 188744669034SStefan Nilsson XK 1888807e8e40SAndy Ross err = mmc_send_op_cond(host, 0, &ocr); 1889807e8e40SAndy Ross if (err) 1890807e8e40SAndy Ross return err; 1891807e8e40SAndy Ross 18922501c917SUlf Hansson mmc_attach_bus(host, &mmc_ops); 18938f230f45STakashi Iwai if (host->ocr_avail_mmc) 18948f230f45STakashi Iwai host->ocr_avail = host->ocr_avail_mmc; 18956abaa0c9SPierre Ossman 18966abaa0c9SPierre Ossman /* 1897af517150SDavid Brownell * We need to get OCR a different way for SPI. 1898af517150SDavid Brownell */ 1899af517150SDavid Brownell if (mmc_host_is_spi(host)) { 1900af517150SDavid Brownell err = mmc_spi_read_ocr(host, 1, &ocr); 1901af517150SDavid Brownell if (err) 1902af517150SDavid Brownell goto err; 1903af517150SDavid Brownell } 1904af517150SDavid Brownell 190569041150SUlf Hansson rocr = mmc_select_voltage(host, ocr); 19066abaa0c9SPierre Ossman 19076abaa0c9SPierre Ossman /* 19086abaa0c9SPierre Ossman * Can we support the voltage of the card? 19096abaa0c9SPierre Ossman */ 191069041150SUlf Hansson if (!rocr) { 1911109b5bedSPierre Ossman err = -EINVAL; 19126abaa0c9SPierre Ossman goto err; 1913109b5bedSPierre Ossman } 19146abaa0c9SPierre Ossman 19156abaa0c9SPierre Ossman /* 19166abaa0c9SPierre Ossman * Detect and init the card. 19176abaa0c9SPierre Ossman */ 191869041150SUlf Hansson err = mmc_init_card(host, rocr, NULL); 191917b0429dSPierre Ossman if (err) 19206abaa0c9SPierre Ossman goto err; 19216abaa0c9SPierre Ossman 19226abaa0c9SPierre Ossman mmc_release_host(host); 19234101c16aSPierre Ossman err = mmc_add_card(host->card); 1924807e8e40SAndy Ross mmc_claim_host(host); 19257ea239d9SPierre Ossman if (err) 19262986d0bfSPierre Ossman goto remove_card; 19277ea239d9SPierre Ossman 19287ea239d9SPierre Ossman return 0; 19297ea239d9SPierre Ossman 19302986d0bfSPierre Ossman remove_card: 1931807e8e40SAndy Ross mmc_release_host(host); 19326abaa0c9SPierre Ossman mmc_remove_card(host->card); 19332986d0bfSPierre Ossman mmc_claim_host(host); 1934807e8e40SAndy Ross host->card = NULL; 19357ea239d9SPierre Ossman err: 19367ea239d9SPierre Ossman mmc_detach_bus(host); 19377ea239d9SPierre Ossman 1938a3c76eb9SGirish K S pr_err("%s: error %d whilst initialising MMC card\n", 1939109b5bedSPierre Ossman mmc_hostname(host), err); 1940109b5bedSPierre Ossman 1941adf66a0dSPierre Ossman return err; 19427ea239d9SPierre Ossman } 1943