| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * linux/drivers/mmc/core/sd.c |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright (C) 2003-2004 Russell King, All Rights Reserved. |
|---|
| 5 | 6 | * SD support Copyright (C) 2004 Ian Molton, All Rights Reserved. |
|---|
| 6 | 7 | * Copyright (C) 2005-2007 Pierre Ossman, All Rights Reserved. |
|---|
| 7 | | - * |
|---|
| 8 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 9 | | - * it under the terms of the GNU General Public License version 2 as |
|---|
| 10 | | - * published by the Free Software Foundation. |
|---|
| 11 | 8 | */ |
|---|
| 12 | 9 | |
|---|
| 13 | 10 | #include <linux/err.h> |
|---|
| .. | .. |
|---|
| 20 | 17 | #include <linux/mmc/card.h> |
|---|
| 21 | 18 | #include <linux/mmc/mmc.h> |
|---|
| 22 | 19 | #include <linux/mmc/sd.h> |
|---|
| 20 | + |
|---|
| 21 | +#include <trace/hooks/mmc_core.h> |
|---|
| 23 | 22 | |
|---|
| 24 | 23 | #include "core.h" |
|---|
| 25 | 24 | #include "card.h" |
|---|
| .. | .. |
|---|
| 215 | 214 | /* Check if Physical Layer Spec v3.0 is supported */ |
|---|
| 216 | 215 | scr->sda_spec3 = UNSTUFF_BITS(resp, 47, 1); |
|---|
| 217 | 216 | |
|---|
| 217 | + if (scr->sda_spec3) { |
|---|
| 218 | + scr->sda_spec4 = UNSTUFF_BITS(resp, 42, 1); |
|---|
| 219 | + scr->sda_specx = UNSTUFF_BITS(resp, 38, 4); |
|---|
| 220 | + } |
|---|
| 221 | + |
|---|
| 218 | 222 | if (UNSTUFF_BITS(resp, 55, 1)) |
|---|
| 219 | 223 | card->erased_byte = 0xFF; |
|---|
| 220 | 224 | else |
|---|
| .. | .. |
|---|
| 240 | 244 | { |
|---|
| 241 | 245 | unsigned int au, es, et, eo; |
|---|
| 242 | 246 | __be32 *raw_ssr; |
|---|
| 247 | + u32 resp[4] = {}; |
|---|
| 248 | + u8 discard_support; |
|---|
| 243 | 249 | int i; |
|---|
| 244 | 250 | |
|---|
| 245 | 251 | if (!(card->csd.cmdclass & CCC_APP_SPEC)) { |
|---|
| .. | .. |
|---|
| 284 | 290 | mmc_hostname(card->host)); |
|---|
| 285 | 291 | } |
|---|
| 286 | 292 | } |
|---|
| 293 | + |
|---|
| 294 | + /* |
|---|
| 295 | + * starting SD5.1 discard is supported if DISCARD_SUPPORT (b313) is set |
|---|
| 296 | + */ |
|---|
| 297 | + resp[3] = card->raw_ssr[6]; |
|---|
| 298 | + discard_support = UNSTUFF_BITS(resp, 313 - 288, 1); |
|---|
| 299 | + card->erase_arg = (card->scr.sda_specx && discard_support) ? |
|---|
| 300 | + SD_DISCARD_ARG : SD_ERASE_ARG; |
|---|
| 287 | 301 | |
|---|
| 288 | 302 | return 0; |
|---|
| 289 | 303 | } |
|---|
| .. | .. |
|---|
| 370 | 384 | if (!status) |
|---|
| 371 | 385 | return -ENOMEM; |
|---|
| 372 | 386 | |
|---|
| 373 | | - err = mmc_sd_switch(card, 1, 0, 1, status); |
|---|
| 387 | + err = mmc_sd_switch(card, 1, 0, HIGH_SPEED_BUS_SPEED, status); |
|---|
| 374 | 388 | if (err) |
|---|
| 375 | 389 | goto out; |
|---|
| 376 | 390 | |
|---|
| 377 | | - if ((status[16] & 0xF) != 1) { |
|---|
| 391 | + if ((status[16] & 0xF) != HIGH_SPEED_BUS_SPEED) { |
|---|
| 378 | 392 | pr_warn("%s: Problem switching card into high-speed mode!\n", |
|---|
| 379 | 393 | mmc_hostname(card->host)); |
|---|
| 380 | 394 | err = 0; |
|---|
| .. | .. |
|---|
| 450 | 464 | SD_MODE_UHS_SDR12)) { |
|---|
| 451 | 465 | card->sd_bus_speed = UHS_SDR12_BUS_SPEED; |
|---|
| 452 | 466 | } |
|---|
| 467 | + |
|---|
| 468 | + trace_android_vh_sd_update_bus_speed_mode(card); |
|---|
| 453 | 469 | } |
|---|
| 454 | 470 | |
|---|
| 455 | 471 | static int sd_set_bus_speed_mode(struct mmc_card *card, u8 *status) |
|---|
| .. | .. |
|---|
| 701 | 717 | |
|---|
| 702 | 718 | static DEVICE_ATTR(dsr, S_IRUGO, mmc_dsr_show, NULL); |
|---|
| 703 | 719 | |
|---|
| 720 | +MMC_DEV_ATTR(vendor, "0x%04x\n", card->cis.vendor); |
|---|
| 721 | +MMC_DEV_ATTR(device, "0x%04x\n", card->cis.device); |
|---|
| 722 | +MMC_DEV_ATTR(revision, "%u.%u\n", card->major_rev, card->minor_rev); |
|---|
| 723 | + |
|---|
| 724 | +#define sdio_info_attr(num) \ |
|---|
| 725 | +static ssize_t info##num##_show(struct device *dev, struct device_attribute *attr, char *buf) \ |
|---|
| 726 | +{ \ |
|---|
| 727 | + struct mmc_card *card = mmc_dev_to_card(dev); \ |
|---|
| 728 | + \ |
|---|
| 729 | + if (num > card->num_info) \ |
|---|
| 730 | + return -ENODATA; \ |
|---|
| 731 | + if (!card->info[num-1][0]) \ |
|---|
| 732 | + return 0; \ |
|---|
| 733 | + return sprintf(buf, "%s\n", card->info[num-1]); \ |
|---|
| 734 | +} \ |
|---|
| 735 | +static DEVICE_ATTR_RO(info##num) |
|---|
| 736 | + |
|---|
| 737 | +sdio_info_attr(1); |
|---|
| 738 | +sdio_info_attr(2); |
|---|
| 739 | +sdio_info_attr(3); |
|---|
| 740 | +sdio_info_attr(4); |
|---|
| 741 | + |
|---|
| 704 | 742 | static struct attribute *sd_std_attrs[] = { |
|---|
| 743 | + &dev_attr_vendor.attr, |
|---|
| 744 | + &dev_attr_device.attr, |
|---|
| 745 | + &dev_attr_revision.attr, |
|---|
| 746 | + &dev_attr_info1.attr, |
|---|
| 747 | + &dev_attr_info2.attr, |
|---|
| 748 | + &dev_attr_info3.attr, |
|---|
| 749 | + &dev_attr_info4.attr, |
|---|
| 705 | 750 | &dev_attr_cid.attr, |
|---|
| 706 | 751 | &dev_attr_csd.attr, |
|---|
| 707 | 752 | &dev_attr_scr.attr, |
|---|
| .. | .. |
|---|
| 720 | 765 | &dev_attr_dsr.attr, |
|---|
| 721 | 766 | NULL, |
|---|
| 722 | 767 | }; |
|---|
| 723 | | -ATTRIBUTE_GROUPS(sd_std); |
|---|
| 768 | + |
|---|
| 769 | +static umode_t sd_std_is_visible(struct kobject *kobj, struct attribute *attr, |
|---|
| 770 | + int index) |
|---|
| 771 | +{ |
|---|
| 772 | + struct device *dev = kobj_to_dev(kobj); |
|---|
| 773 | + struct mmc_card *card = mmc_dev_to_card(dev); |
|---|
| 774 | + |
|---|
| 775 | + /* CIS vendor and device ids, revision and info string are available only for Combo cards */ |
|---|
| 776 | + if ((attr == &dev_attr_vendor.attr || |
|---|
| 777 | + attr == &dev_attr_device.attr || |
|---|
| 778 | + attr == &dev_attr_revision.attr || |
|---|
| 779 | + attr == &dev_attr_info1.attr || |
|---|
| 780 | + attr == &dev_attr_info2.attr || |
|---|
| 781 | + attr == &dev_attr_info3.attr || |
|---|
| 782 | + attr == &dev_attr_info4.attr |
|---|
| 783 | + ) && card->type != MMC_TYPE_SD_COMBO) |
|---|
| 784 | + return 0; |
|---|
| 785 | + |
|---|
| 786 | + return attr->mode; |
|---|
| 787 | +} |
|---|
| 788 | + |
|---|
| 789 | +static const struct attribute_group sd_std_group = { |
|---|
| 790 | + .attrs = sd_std_attrs, |
|---|
| 791 | + .is_visible = sd_std_is_visible, |
|---|
| 792 | +}; |
|---|
| 793 | +__ATTRIBUTE_GROUPS(sd_std); |
|---|
| 724 | 794 | |
|---|
| 725 | 795 | struct device_type sd_type = { |
|---|
| 726 | 796 | .groups = sd_std_groups, |
|---|
| .. | .. |
|---|
| 787 | 857 | * the CCS bit is set as well. We deliberately deviate from the spec in |
|---|
| 788 | 858 | * regards to this, which allows UHS-I to be supported for SDSC cards. |
|---|
| 789 | 859 | */ |
|---|
| 790 | | - if (!mmc_host_is_spi(host) && rocr && (*rocr & 0x01000000)) { |
|---|
| 860 | + if (!mmc_host_is_spi(host) && (ocr & SD_OCR_S18R) && |
|---|
| 861 | + rocr && (*rocr & SD_ROCR_S18A)) { |
|---|
| 791 | 862 | err = mmc_set_uhs_voltage(host, pocr); |
|---|
| 792 | 863 | if (err == -EAGAIN) { |
|---|
| 793 | 864 | retries--; |
|---|
| .. | .. |
|---|
| 866 | 937 | |
|---|
| 867 | 938 | /* Erase init depends on CSD and SSR */ |
|---|
| 868 | 939 | mmc_init_erase(card); |
|---|
| 869 | | - |
|---|
| 870 | | - /* |
|---|
| 871 | | - * Fetch switch information from card. |
|---|
| 872 | | - */ |
|---|
| 873 | | - err = mmc_read_switch(card); |
|---|
| 874 | | - if (err) |
|---|
| 875 | | - return err; |
|---|
| 876 | 940 | } |
|---|
| 941 | + |
|---|
| 942 | + /* |
|---|
| 943 | + * Fetch switch information from card. Note, sd3_bus_mode can change if |
|---|
| 944 | + * voltage switch outcome changes, so do this always. |
|---|
| 945 | + */ |
|---|
| 946 | + err = mmc_read_switch(card); |
|---|
| 947 | + if (err) |
|---|
| 948 | + return err; |
|---|
| 877 | 949 | |
|---|
| 878 | 950 | /* |
|---|
| 879 | 951 | * For SPI, enable CRC as appropriate. |
|---|
| .. | .. |
|---|
| 952 | 1024 | return err; |
|---|
| 953 | 1025 | |
|---|
| 954 | 1026 | if (oldcard) { |
|---|
| 955 | | - if (memcmp(cid, oldcard->raw_cid, sizeof(cid)) != 0) |
|---|
| 1027 | + if (memcmp(cid, oldcard->raw_cid, sizeof(cid)) != 0) { |
|---|
| 1028 | + pr_debug("%s: Perhaps the card was replaced\n", |
|---|
| 1029 | + mmc_hostname(host)); |
|---|
| 956 | 1030 | return -ENOENT; |
|---|
| 1031 | + } |
|---|
| 957 | 1032 | |
|---|
| 958 | 1033 | card = oldcard; |
|---|
| 959 | 1034 | } else { |
|---|
| .. | .. |
|---|
| 1020 | 1095 | if (!v18_fixup_failed && !mmc_host_is_spi(host) && mmc_host_uhs(host) && |
|---|
| 1021 | 1096 | mmc_sd_card_using_v18(card) && |
|---|
| 1022 | 1097 | host->ios.signal_voltage != MMC_SIGNAL_VOLTAGE_180) { |
|---|
| 1023 | | - /* |
|---|
| 1024 | | - * Re-read switch information in case it has changed since |
|---|
| 1025 | | - * oldcard was initialized. |
|---|
| 1026 | | - */ |
|---|
| 1027 | | - if (oldcard) { |
|---|
| 1028 | | - err = mmc_read_switch(card); |
|---|
| 1029 | | - if (err) |
|---|
| 1030 | | - goto free_card; |
|---|
| 1098 | + if (mmc_host_set_uhs_voltage(host) || |
|---|
| 1099 | + mmc_sd_init_uhs_card(card)) { |
|---|
| 1100 | + v18_fixup_failed = true; |
|---|
| 1101 | + mmc_power_cycle(host, ocr); |
|---|
| 1102 | + if (!oldcard) |
|---|
| 1103 | + mmc_remove_card(card); |
|---|
| 1104 | + goto retry; |
|---|
| 1031 | 1105 | } |
|---|
| 1032 | | - if (mmc_sd_card_using_v18(card)) { |
|---|
| 1033 | | - if (mmc_host_set_uhs_voltage(host) || |
|---|
| 1034 | | - mmc_sd_init_uhs_card(card)) { |
|---|
| 1035 | | - v18_fixup_failed = true; |
|---|
| 1036 | | - mmc_power_cycle(host, ocr); |
|---|
| 1037 | | - if (!oldcard) |
|---|
| 1038 | | - mmc_remove_card(card); |
|---|
| 1039 | | - goto retry; |
|---|
| 1040 | | - } |
|---|
| 1041 | | - goto done; |
|---|
| 1042 | | - } |
|---|
| 1106 | + goto cont; |
|---|
| 1043 | 1107 | } |
|---|
| 1044 | 1108 | |
|---|
| 1045 | 1109 | /* Initialization sequence for UHS-I cards */ |
|---|
| .. | .. |
|---|
| 1074 | 1138 | mmc_set_bus_width(host, MMC_BUS_WIDTH_4); |
|---|
| 1075 | 1139 | } |
|---|
| 1076 | 1140 | } |
|---|
| 1141 | +cont: |
|---|
| 1142 | + if (host->cqe_ops && !host->cqe_enabled) { |
|---|
| 1143 | + err = host->cqe_ops->cqe_enable(host, card); |
|---|
| 1144 | + if (!err) { |
|---|
| 1145 | + host->cqe_enabled = true; |
|---|
| 1146 | + host->hsq_enabled = true; |
|---|
| 1147 | + pr_info("%s: Host Software Queue enabled\n", |
|---|
| 1148 | + mmc_hostname(host)); |
|---|
| 1149 | + } |
|---|
| 1150 | + } |
|---|
| 1077 | 1151 | |
|---|
| 1078 | 1152 | if (host->caps2 & MMC_CAP2_AVOID_3_3V && |
|---|
| 1079 | 1153 | host->ios.signal_voltage == MMC_SIGNAL_VOLTAGE_330) { |
|---|
| .. | .. |
|---|
| 1082 | 1156 | err = -EINVAL; |
|---|
| 1083 | 1157 | goto free_card; |
|---|
| 1084 | 1158 | } |
|---|
| 1085 | | -done: |
|---|
| 1159 | + |
|---|
| 1086 | 1160 | host->card = card; |
|---|
| 1087 | 1161 | return 0; |
|---|
| 1088 | 1162 | |
|---|
| .. | .. |
|---|
| 1162 | 1236 | { |
|---|
| 1163 | 1237 | int err = 0; |
|---|
| 1164 | 1238 | |
|---|
| 1165 | | - BUG_ON(!host); |
|---|
| 1166 | | - BUG_ON(!host->card); |
|---|
| 1239 | + if (WARN_ON(!host) || WARN_ON(!host->card)) |
|---|
| 1240 | + return 0; |
|---|
| 1167 | 1241 | |
|---|
| 1168 | 1242 | mmc_claim_host(host); |
|---|
| 1169 | 1243 | |
|---|
| .. | .. |
|---|
| 1178 | 1252 | mmc_card_set_suspended(host->card); |
|---|
| 1179 | 1253 | } |
|---|
| 1180 | 1254 | |
|---|
| 1181 | | - /* |
|---|
| 1182 | | - * mmc_sd_shutdown is used for SD card, so what we need |
|---|
| 1183 | | - * is to make sure we set signal voltage to initial state |
|---|
| 1184 | | - * if it's used as main disk. RESTRICT_CARD_TYPE_MMC is |
|---|
| 1185 | | - * combined into host->restrict_caps via DT for SD cards |
|---|
| 1186 | | - * running system image. |
|---|
| 1187 | | - */ |
|---|
| 1188 | | - if (host->restrict_caps & RESTRICT_CARD_TYPE_EMMC) { |
|---|
| 1189 | | - host->ios.signal_voltage = MMC_SIGNAL_VOLTAGE_330; |
|---|
| 1190 | | - host->ios.vdd = fls(host->ocr_avail) - 1; |
|---|
| 1191 | | - mmc_regulator_set_vqmmc(host, &host->ios); |
|---|
| 1192 | | - pr_info("Set signal voltage to initial state\n"); |
|---|
| 1193 | | - } |
|---|
| 1255 | + host->ios.signal_voltage = MMC_SIGNAL_VOLTAGE_330; |
|---|
| 1256 | + host->ios.vdd = fls(host->ocr_avail) - 1; |
|---|
| 1257 | + mmc_regulator_set_vqmmc(host, &host->ios); |
|---|
| 1258 | + pr_info("Set signal voltage to initial state\n"); |
|---|
| 1194 | 1259 | |
|---|
| 1195 | 1260 | out: |
|---|
| 1196 | 1261 | mmc_release_host(host); |
|---|
| .. | .. |
|---|
| 1378 | 1443 | pr_err("%s: error %d whilst initialising SD card\n", |
|---|
| 1379 | 1444 | mmc_hostname(host), err); |
|---|
| 1380 | 1445 | |
|---|
| 1446 | + trace_android_vh_mmc_attach_sd(host, ocr, err); |
|---|
| 1447 | + |
|---|
| 1381 | 1448 | return err; |
|---|
| 1382 | 1449 | } |
|---|