1da7fbe58SPierre Ossman /* 270f10482SPierre Ossman * linux/drivers/mmc/core/mmc_ops.h 3da7fbe58SPierre Ossman * 4da7fbe58SPierre Ossman * Copyright 2006-2007 Pierre Ossman 5da7fbe58SPierre Ossman * 6da7fbe58SPierre Ossman * This program is free software; you can redistribute it and/or modify 7da7fbe58SPierre Ossman * it under the terms of the GNU General Public License as published by 8da7fbe58SPierre Ossman * the Free Software Foundation; either version 2 of the License, or (at 9da7fbe58SPierre Ossman * your option) any later version. 10da7fbe58SPierre Ossman */ 11da7fbe58SPierre Ossman 125a0e3ad6STejun Heo #include <linux/slab.h> 133ef77af1SPaul Gortmaker #include <linux/export.h> 14da7fbe58SPierre Ossman #include <linux/types.h> 15da7fbe58SPierre Ossman #include <linux/scatterlist.h> 16da7fbe58SPierre Ossman 17da7fbe58SPierre Ossman #include <linux/mmc/host.h> 18da7fbe58SPierre Ossman #include <linux/mmc/card.h> 19da7fbe58SPierre Ossman #include <linux/mmc/mmc.h> 20da7fbe58SPierre Ossman 21da7fbe58SPierre Ossman #include "core.h" 22da7fbe58SPierre Ossman #include "mmc_ops.h" 23da7fbe58SPierre Ossman 248fee476bSTrey Ramsay #define MMC_OPS_TIMEOUT_MS (10 * 60 * 1000) /* 10 minute timeout */ 258fee476bSTrey Ramsay 26a27fbf2fSSeungwon Jeon static inline int __mmc_send_status(struct mmc_card *card, u32 *status, 27a27fbf2fSSeungwon Jeon bool ignore_crc) 28a27fbf2fSSeungwon Jeon { 29a27fbf2fSSeungwon Jeon int err; 30a27fbf2fSSeungwon Jeon struct mmc_command cmd = {0}; 31a27fbf2fSSeungwon Jeon 32a27fbf2fSSeungwon Jeon BUG_ON(!card); 33a27fbf2fSSeungwon Jeon BUG_ON(!card->host); 34a27fbf2fSSeungwon Jeon 35a27fbf2fSSeungwon Jeon cmd.opcode = MMC_SEND_STATUS; 36a27fbf2fSSeungwon Jeon if (!mmc_host_is_spi(card->host)) 37a27fbf2fSSeungwon Jeon cmd.arg = card->rca << 16; 38a27fbf2fSSeungwon Jeon cmd.flags = MMC_RSP_SPI_R2 | MMC_RSP_R1 | MMC_CMD_AC; 39a27fbf2fSSeungwon Jeon if (ignore_crc) 40a27fbf2fSSeungwon Jeon cmd.flags &= ~MMC_RSP_CRC; 41a27fbf2fSSeungwon Jeon 42a27fbf2fSSeungwon Jeon err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES); 43a27fbf2fSSeungwon Jeon if (err) 44a27fbf2fSSeungwon Jeon return err; 45a27fbf2fSSeungwon Jeon 46a27fbf2fSSeungwon Jeon /* NOTE: callers are required to understand the difference 47a27fbf2fSSeungwon Jeon * between "native" and SPI format status words! 48a27fbf2fSSeungwon Jeon */ 49a27fbf2fSSeungwon Jeon if (status) 50a27fbf2fSSeungwon Jeon *status = cmd.resp[0]; 51a27fbf2fSSeungwon Jeon 52a27fbf2fSSeungwon Jeon return 0; 53a27fbf2fSSeungwon Jeon } 54a27fbf2fSSeungwon Jeon 55a27fbf2fSSeungwon Jeon int mmc_send_status(struct mmc_card *card, u32 *status) 56a27fbf2fSSeungwon Jeon { 57a27fbf2fSSeungwon Jeon return __mmc_send_status(card, status, false); 58a27fbf2fSSeungwon Jeon } 59a27fbf2fSSeungwon Jeon 60da7fbe58SPierre Ossman static int _mmc_select_card(struct mmc_host *host, struct mmc_card *card) 61da7fbe58SPierre Ossman { 62da7fbe58SPierre Ossman int err; 631278dba1SChris Ball struct mmc_command cmd = {0}; 64da7fbe58SPierre Ossman 65da7fbe58SPierre Ossman BUG_ON(!host); 66da7fbe58SPierre Ossman 67da7fbe58SPierre Ossman cmd.opcode = MMC_SELECT_CARD; 68da7fbe58SPierre Ossman 69da7fbe58SPierre Ossman if (card) { 70da7fbe58SPierre Ossman cmd.arg = card->rca << 16; 71da7fbe58SPierre Ossman cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; 72da7fbe58SPierre Ossman } else { 73da7fbe58SPierre Ossman cmd.arg = 0; 74da7fbe58SPierre Ossman cmd.flags = MMC_RSP_NONE | MMC_CMD_AC; 75da7fbe58SPierre Ossman } 76da7fbe58SPierre Ossman 77da7fbe58SPierre Ossman err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES); 7817b0429dSPierre Ossman if (err) 79da7fbe58SPierre Ossman return err; 80da7fbe58SPierre Ossman 8117b0429dSPierre Ossman return 0; 82da7fbe58SPierre Ossman } 83da7fbe58SPierre Ossman 84da7fbe58SPierre Ossman int mmc_select_card(struct mmc_card *card) 85da7fbe58SPierre Ossman { 86da7fbe58SPierre Ossman BUG_ON(!card); 87da7fbe58SPierre Ossman 88da7fbe58SPierre Ossman return _mmc_select_card(card->host, card); 89da7fbe58SPierre Ossman } 90da7fbe58SPierre Ossman 91da7fbe58SPierre Ossman int mmc_deselect_cards(struct mmc_host *host) 92da7fbe58SPierre Ossman { 93da7fbe58SPierre Ossman return _mmc_select_card(host, NULL); 94da7fbe58SPierre Ossman } 95da7fbe58SPierre Ossman 96da7fbe58SPierre Ossman int mmc_go_idle(struct mmc_host *host) 97da7fbe58SPierre Ossman { 98da7fbe58SPierre Ossman int err; 991278dba1SChris Ball struct mmc_command cmd = {0}; 100da7fbe58SPierre Ossman 101af517150SDavid Brownell /* 102af517150SDavid Brownell * Non-SPI hosts need to prevent chipselect going active during 103af517150SDavid Brownell * GO_IDLE; that would put chips into SPI mode. Remind them of 104af517150SDavid Brownell * that in case of hardware that won't pull up DAT3/nCS otherwise. 105af517150SDavid Brownell * 106af517150SDavid Brownell * SPI hosts ignore ios.chip_select; it's managed according to 10725985edcSLucas De Marchi * rules that must accommodate non-MMC slaves which this layer 108af517150SDavid Brownell * won't even know about. 109af517150SDavid Brownell */ 110af517150SDavid Brownell if (!mmc_host_is_spi(host)) { 111da7fbe58SPierre Ossman mmc_set_chip_select(host, MMC_CS_HIGH); 112da7fbe58SPierre Ossman mmc_delay(1); 113af517150SDavid Brownell } 114da7fbe58SPierre Ossman 115da7fbe58SPierre Ossman cmd.opcode = MMC_GO_IDLE_STATE; 116da7fbe58SPierre Ossman cmd.arg = 0; 117af517150SDavid Brownell cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_NONE | MMC_CMD_BC; 118da7fbe58SPierre Ossman 119da7fbe58SPierre Ossman err = mmc_wait_for_cmd(host, &cmd, 0); 120da7fbe58SPierre Ossman 121da7fbe58SPierre Ossman mmc_delay(1); 122da7fbe58SPierre Ossman 123af517150SDavid Brownell if (!mmc_host_is_spi(host)) { 124da7fbe58SPierre Ossman mmc_set_chip_select(host, MMC_CS_DONTCARE); 125da7fbe58SPierre Ossman mmc_delay(1); 126af517150SDavid Brownell } 127af517150SDavid Brownell 128af517150SDavid Brownell host->use_spi_crc = 0; 129da7fbe58SPierre Ossman 130da7fbe58SPierre Ossman return err; 131da7fbe58SPierre Ossman } 132da7fbe58SPierre Ossman 133da7fbe58SPierre Ossman int mmc_send_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr) 134da7fbe58SPierre Ossman { 1351278dba1SChris Ball struct mmc_command cmd = {0}; 136da7fbe58SPierre Ossman int i, err = 0; 137da7fbe58SPierre Ossman 138da7fbe58SPierre Ossman BUG_ON(!host); 139da7fbe58SPierre Ossman 140da7fbe58SPierre Ossman cmd.opcode = MMC_SEND_OP_COND; 141af517150SDavid Brownell cmd.arg = mmc_host_is_spi(host) ? 0 : ocr; 142af517150SDavid Brownell cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R3 | MMC_CMD_BCR; 143da7fbe58SPierre Ossman 144da7fbe58SPierre Ossman for (i = 100; i; i--) { 145da7fbe58SPierre Ossman err = mmc_wait_for_cmd(host, &cmd, 0); 14617b0429dSPierre Ossman if (err) 147da7fbe58SPierre Ossman break; 148da7fbe58SPierre Ossman 149af517150SDavid Brownell /* if we're just probing, do a single pass */ 150af517150SDavid Brownell if (ocr == 0) 151da7fbe58SPierre Ossman break; 152da7fbe58SPierre Ossman 153af517150SDavid Brownell /* otherwise wait until reset completes */ 154af517150SDavid Brownell if (mmc_host_is_spi(host)) { 155af517150SDavid Brownell if (!(cmd.resp[0] & R1_SPI_IDLE)) 156af517150SDavid Brownell break; 157af517150SDavid Brownell } else { 158af517150SDavid Brownell if (cmd.resp[0] & MMC_CARD_BUSY) 159af517150SDavid Brownell break; 160af517150SDavid Brownell } 161af517150SDavid Brownell 16217b0429dSPierre Ossman err = -ETIMEDOUT; 163da7fbe58SPierre Ossman 164da7fbe58SPierre Ossman mmc_delay(10); 165da7fbe58SPierre Ossman } 166da7fbe58SPierre Ossman 167af517150SDavid Brownell if (rocr && !mmc_host_is_spi(host)) 168da7fbe58SPierre Ossman *rocr = cmd.resp[0]; 169da7fbe58SPierre Ossman 170da7fbe58SPierre Ossman return err; 171da7fbe58SPierre Ossman } 172da7fbe58SPierre Ossman 173da7fbe58SPierre Ossman int mmc_all_send_cid(struct mmc_host *host, u32 *cid) 174da7fbe58SPierre Ossman { 175da7fbe58SPierre Ossman int err; 1761278dba1SChris Ball struct mmc_command cmd = {0}; 177da7fbe58SPierre Ossman 178da7fbe58SPierre Ossman BUG_ON(!host); 179da7fbe58SPierre Ossman BUG_ON(!cid); 180da7fbe58SPierre Ossman 181da7fbe58SPierre Ossman cmd.opcode = MMC_ALL_SEND_CID; 182da7fbe58SPierre Ossman cmd.arg = 0; 183da7fbe58SPierre Ossman cmd.flags = MMC_RSP_R2 | MMC_CMD_BCR; 184da7fbe58SPierre Ossman 185da7fbe58SPierre Ossman err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES); 18617b0429dSPierre Ossman if (err) 187da7fbe58SPierre Ossman return err; 188da7fbe58SPierre Ossman 189da7fbe58SPierre Ossman memcpy(cid, cmd.resp, sizeof(u32) * 4); 190da7fbe58SPierre Ossman 19117b0429dSPierre Ossman return 0; 192da7fbe58SPierre Ossman } 193da7fbe58SPierre Ossman 194da7fbe58SPierre Ossman int mmc_set_relative_addr(struct mmc_card *card) 195da7fbe58SPierre Ossman { 196da7fbe58SPierre Ossman int err; 1971278dba1SChris Ball struct mmc_command cmd = {0}; 198da7fbe58SPierre Ossman 199da7fbe58SPierre Ossman BUG_ON(!card); 200da7fbe58SPierre Ossman BUG_ON(!card->host); 201da7fbe58SPierre Ossman 202da7fbe58SPierre Ossman cmd.opcode = MMC_SET_RELATIVE_ADDR; 203da7fbe58SPierre Ossman cmd.arg = card->rca << 16; 204da7fbe58SPierre Ossman cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; 205da7fbe58SPierre Ossman 206da7fbe58SPierre Ossman err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES); 20717b0429dSPierre Ossman if (err) 208da7fbe58SPierre Ossman return err; 209da7fbe58SPierre Ossman 21017b0429dSPierre Ossman return 0; 211da7fbe58SPierre Ossman } 212da7fbe58SPierre Ossman 213af517150SDavid Brownell static int 214af517150SDavid Brownell mmc_send_cxd_native(struct mmc_host *host, u32 arg, u32 *cxd, int opcode) 215da7fbe58SPierre Ossman { 216da7fbe58SPierre Ossman int err; 2171278dba1SChris Ball struct mmc_command cmd = {0}; 218da7fbe58SPierre Ossman 219af517150SDavid Brownell BUG_ON(!host); 220af517150SDavid Brownell BUG_ON(!cxd); 221da7fbe58SPierre Ossman 222af517150SDavid Brownell cmd.opcode = opcode; 223af517150SDavid Brownell cmd.arg = arg; 224da7fbe58SPierre Ossman cmd.flags = MMC_RSP_R2 | MMC_CMD_AC; 225da7fbe58SPierre Ossman 226af517150SDavid Brownell err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES); 22717b0429dSPierre Ossman if (err) 228da7fbe58SPierre Ossman return err; 229da7fbe58SPierre Ossman 230af517150SDavid Brownell memcpy(cxd, cmd.resp, sizeof(u32) * 4); 231da7fbe58SPierre Ossman 23217b0429dSPierre Ossman return 0; 233da7fbe58SPierre Ossman } 234da7fbe58SPierre Ossman 2351a41313eSKyungsik Lee /* 2361a41313eSKyungsik Lee * NOTE: void *buf, caller for the buf is required to use DMA-capable 2371a41313eSKyungsik Lee * buffer or on-stack buffer (with some overhead in callee). 2381a41313eSKyungsik Lee */ 239af517150SDavid Brownell static int 240af517150SDavid Brownell mmc_send_cxd_data(struct mmc_card *card, struct mmc_host *host, 241af517150SDavid Brownell u32 opcode, void *buf, unsigned len) 242da7fbe58SPierre Ossman { 243ad5fd972SVenkatraman S struct mmc_request mrq = {NULL}; 2441278dba1SChris Ball struct mmc_command cmd = {0}; 245a61ad2b4SChris Ball struct mmc_data data = {0}; 246da7fbe58SPierre Ossman struct scatterlist sg; 247af517150SDavid Brownell void *data_buf; 2481a41313eSKyungsik Lee int is_on_stack; 249da7fbe58SPierre Ossman 2501a41313eSKyungsik Lee is_on_stack = object_is_on_stack(buf); 2511a41313eSKyungsik Lee if (is_on_stack) { 2521a41313eSKyungsik Lee /* 2531a41313eSKyungsik Lee * dma onto stack is unsafe/nonportable, but callers to this 254af517150SDavid Brownell * routine normally provide temporary on-stack buffers ... 255af517150SDavid Brownell */ 256af517150SDavid Brownell data_buf = kmalloc(len, GFP_KERNEL); 2571a41313eSKyungsik Lee if (!data_buf) 258af517150SDavid Brownell return -ENOMEM; 2591a41313eSKyungsik Lee } else 2601a41313eSKyungsik Lee data_buf = buf; 261da7fbe58SPierre Ossman 262da7fbe58SPierre Ossman mrq.cmd = &cmd; 263da7fbe58SPierre Ossman mrq.data = &data; 264da7fbe58SPierre Ossman 265af517150SDavid Brownell cmd.opcode = opcode; 266da7fbe58SPierre Ossman cmd.arg = 0; 267da7fbe58SPierre Ossman 268af517150SDavid Brownell /* NOTE HACK: the MMC_RSP_SPI_R1 is always correct here, but we 269af517150SDavid Brownell * rely on callers to never use this with "native" calls for reading 270af517150SDavid Brownell * CSD or CID. Native versions of those commands use the R2 type, 271af517150SDavid Brownell * not R1 plus a data block. 272af517150SDavid Brownell */ 273af517150SDavid Brownell cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC; 274af517150SDavid Brownell 275af517150SDavid Brownell data.blksz = len; 276da7fbe58SPierre Ossman data.blocks = 1; 277da7fbe58SPierre Ossman data.flags = MMC_DATA_READ; 278da7fbe58SPierre Ossman data.sg = &sg; 279da7fbe58SPierre Ossman data.sg_len = 1; 280da7fbe58SPierre Ossman 281af517150SDavid Brownell sg_init_one(&sg, data_buf, len); 282da7fbe58SPierre Ossman 283cda56ac2SAdrian Hunter if (opcode == MMC_SEND_CSD || opcode == MMC_SEND_CID) { 2840d3e0460SMatthew Fleming /* 2850d3e0460SMatthew Fleming * The spec states that CSR and CID accesses have a timeout 2860d3e0460SMatthew Fleming * of 64 clock cycles. 2870d3e0460SMatthew Fleming */ 2880d3e0460SMatthew Fleming data.timeout_ns = 0; 2890d3e0460SMatthew Fleming data.timeout_clks = 64; 290cda56ac2SAdrian Hunter } else 291cda56ac2SAdrian Hunter mmc_set_data_timeout(&data, card); 292da7fbe58SPierre Ossman 293af517150SDavid Brownell mmc_wait_for_req(host, &mrq); 294af517150SDavid Brownell 2951a41313eSKyungsik Lee if (is_on_stack) { 296af517150SDavid Brownell memcpy(buf, data_buf, len); 297af517150SDavid Brownell kfree(data_buf); 2981a41313eSKyungsik Lee } 299da7fbe58SPierre Ossman 30017b0429dSPierre Ossman if (cmd.error) 301da7fbe58SPierre Ossman return cmd.error; 30217b0429dSPierre Ossman if (data.error) 303da7fbe58SPierre Ossman return data.error; 304da7fbe58SPierre Ossman 30517b0429dSPierre Ossman return 0; 306da7fbe58SPierre Ossman } 307da7fbe58SPierre Ossman 308af517150SDavid Brownell int mmc_send_csd(struct mmc_card *card, u32 *csd) 309af517150SDavid Brownell { 31078e48073SPierre Ossman int ret, i; 3111a41313eSKyungsik Lee u32 *csd_tmp; 31278e48073SPierre Ossman 313af517150SDavid Brownell if (!mmc_host_is_spi(card->host)) 314af517150SDavid Brownell return mmc_send_cxd_native(card->host, card->rca << 16, 315af517150SDavid Brownell csd, MMC_SEND_CSD); 316af517150SDavid Brownell 3171a41313eSKyungsik Lee csd_tmp = kmalloc(16, GFP_KERNEL); 3181a41313eSKyungsik Lee if (!csd_tmp) 3191a41313eSKyungsik Lee return -ENOMEM; 3201a41313eSKyungsik Lee 3211a41313eSKyungsik Lee ret = mmc_send_cxd_data(card, card->host, MMC_SEND_CSD, csd_tmp, 16); 32278e48073SPierre Ossman if (ret) 3231a41313eSKyungsik Lee goto err; 32478e48073SPierre Ossman 32578e48073SPierre Ossman for (i = 0;i < 4;i++) 3261a41313eSKyungsik Lee csd[i] = be32_to_cpu(csd_tmp[i]); 32778e48073SPierre Ossman 3281a41313eSKyungsik Lee err: 3291a41313eSKyungsik Lee kfree(csd_tmp); 3301a41313eSKyungsik Lee return ret; 331af517150SDavid Brownell } 332af517150SDavid Brownell 333af517150SDavid Brownell int mmc_send_cid(struct mmc_host *host, u32 *cid) 334af517150SDavid Brownell { 33578e48073SPierre Ossman int ret, i; 3361a41313eSKyungsik Lee u32 *cid_tmp; 33778e48073SPierre Ossman 338af517150SDavid Brownell if (!mmc_host_is_spi(host)) { 339af517150SDavid Brownell if (!host->card) 340af517150SDavid Brownell return -EINVAL; 341af517150SDavid Brownell return mmc_send_cxd_native(host, host->card->rca << 16, 342af517150SDavid Brownell cid, MMC_SEND_CID); 343af517150SDavid Brownell } 344af517150SDavid Brownell 3451a41313eSKyungsik Lee cid_tmp = kmalloc(16, GFP_KERNEL); 3461a41313eSKyungsik Lee if (!cid_tmp) 3471a41313eSKyungsik Lee return -ENOMEM; 3481a41313eSKyungsik Lee 3491a41313eSKyungsik Lee ret = mmc_send_cxd_data(NULL, host, MMC_SEND_CID, cid_tmp, 16); 35078e48073SPierre Ossman if (ret) 3511a41313eSKyungsik Lee goto err; 35278e48073SPierre Ossman 35378e48073SPierre Ossman for (i = 0;i < 4;i++) 3541a41313eSKyungsik Lee cid[i] = be32_to_cpu(cid_tmp[i]); 35578e48073SPierre Ossman 3561a41313eSKyungsik Lee err: 3571a41313eSKyungsik Lee kfree(cid_tmp); 3581a41313eSKyungsik Lee return ret; 359af517150SDavid Brownell } 360af517150SDavid Brownell 361af517150SDavid Brownell int mmc_send_ext_csd(struct mmc_card *card, u8 *ext_csd) 362af517150SDavid Brownell { 363af517150SDavid Brownell return mmc_send_cxd_data(card, card->host, MMC_SEND_EXT_CSD, 364af517150SDavid Brownell ext_csd, 512); 365af517150SDavid Brownell } 366ce39f9d1SSeungwon Jeon EXPORT_SYMBOL_GPL(mmc_send_ext_csd); 367af517150SDavid Brownell 368af517150SDavid Brownell int mmc_spi_read_ocr(struct mmc_host *host, int highcap, u32 *ocrp) 369af517150SDavid Brownell { 3701278dba1SChris Ball struct mmc_command cmd = {0}; 371af517150SDavid Brownell int err; 372af517150SDavid Brownell 373af517150SDavid Brownell cmd.opcode = MMC_SPI_READ_OCR; 374af517150SDavid Brownell cmd.arg = highcap ? (1 << 30) : 0; 375af517150SDavid Brownell cmd.flags = MMC_RSP_SPI_R3; 376af517150SDavid Brownell 377af517150SDavid Brownell err = mmc_wait_for_cmd(host, &cmd, 0); 378af517150SDavid Brownell 379af517150SDavid Brownell *ocrp = cmd.resp[1]; 380af517150SDavid Brownell return err; 381af517150SDavid Brownell } 382af517150SDavid Brownell 383af517150SDavid Brownell int mmc_spi_set_crc(struct mmc_host *host, int use_crc) 384af517150SDavid Brownell { 3851278dba1SChris Ball struct mmc_command cmd = {0}; 386af517150SDavid Brownell int err; 387af517150SDavid Brownell 388af517150SDavid Brownell cmd.opcode = MMC_SPI_CRC_ON_OFF; 389af517150SDavid Brownell cmd.flags = MMC_RSP_SPI_R1; 390af517150SDavid Brownell cmd.arg = use_crc; 391af517150SDavid Brownell 392af517150SDavid Brownell err = mmc_wait_for_cmd(host, &cmd, 0); 393af517150SDavid Brownell if (!err) 394af517150SDavid Brownell host->use_spi_crc = use_crc; 395af517150SDavid Brownell return err; 396af517150SDavid Brownell } 397af517150SDavid Brownell 398d3a8d95dSAndrei Warkentin /** 399950d56acSJaehoon Chung * __mmc_switch - modify EXT_CSD register 400d3a8d95dSAndrei Warkentin * @card: the MMC card associated with the data transfer 401d3a8d95dSAndrei Warkentin * @set: cmd set values 402d3a8d95dSAndrei Warkentin * @index: EXT_CSD register index 403d3a8d95dSAndrei Warkentin * @value: value to program into EXT_CSD register 404d3a8d95dSAndrei Warkentin * @timeout_ms: timeout (ms) for operation performed by register write, 405d3a8d95dSAndrei Warkentin * timeout of zero implies maximum possible timeout 406950d56acSJaehoon Chung * @use_busy_signal: use the busy signal as response type 407878e200bSUlf Hansson * @send_status: send status cmd to poll for busy 4084509f847SUlf Hansson * @ignore_crc: ignore CRC errors when sending status cmd to poll for busy 409d3a8d95dSAndrei Warkentin * 410d3a8d95dSAndrei Warkentin * Modifies the EXT_CSD register for selected card. 411d3a8d95dSAndrei Warkentin */ 412950d56acSJaehoon Chung int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value, 4134509f847SUlf Hansson unsigned int timeout_ms, bool use_busy_signal, bool send_status, 4144509f847SUlf Hansson bool ignore_crc) 415da7fbe58SPierre Ossman { 416636bd13cSUlf Hansson struct mmc_host *host = card->host; 417da7fbe58SPierre Ossman int err; 4181278dba1SChris Ball struct mmc_command cmd = {0}; 4198fee476bSTrey Ramsay unsigned long timeout; 420ecd3a7daSUlf Hansson u32 status = 0; 421b9ec2616SUlf Hansson bool use_r1b_resp = use_busy_signal; 422b9ec2616SUlf Hansson 423b9ec2616SUlf Hansson /* 424b9ec2616SUlf Hansson * If the cmd timeout and the max_busy_timeout of the host are both 425b9ec2616SUlf Hansson * specified, let's validate them. A failure means we need to prevent 426b9ec2616SUlf Hansson * the host from doing hw busy detection, which is done by converting 427b9ec2616SUlf Hansson * to a R1 response instead of a R1B. 428b9ec2616SUlf Hansson */ 429b9ec2616SUlf Hansson if (timeout_ms && host->max_busy_timeout && 430b9ec2616SUlf Hansson (timeout_ms > host->max_busy_timeout)) 431b9ec2616SUlf Hansson use_r1b_resp = false; 432da7fbe58SPierre Ossman 433da7fbe58SPierre Ossman cmd.opcode = MMC_SWITCH; 434da7fbe58SPierre Ossman cmd.arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) | 435da7fbe58SPierre Ossman (index << 16) | 436da7fbe58SPierre Ossman (value << 8) | 437da7fbe58SPierre Ossman set; 438950d56acSJaehoon Chung cmd.flags = MMC_CMD_AC; 439b9ec2616SUlf Hansson if (use_r1b_resp) { 440950d56acSJaehoon Chung cmd.flags |= MMC_RSP_SPI_R1B | MMC_RSP_R1B; 441b9ec2616SUlf Hansson /* 442b9ec2616SUlf Hansson * A busy_timeout of zero means the host can decide to use 443b9ec2616SUlf Hansson * whatever value it finds suitable. 444b9ec2616SUlf Hansson */ 4451d4d7744SUlf Hansson cmd.busy_timeout = timeout_ms; 446b9ec2616SUlf Hansson } else { 447b9ec2616SUlf Hansson cmd.flags |= MMC_RSP_SPI_R1 | MMC_RSP_R1; 448b9ec2616SUlf Hansson } 449b9ec2616SUlf Hansson 450775a9362SMaya Erez if (index == EXT_CSD_SANITIZE_START) 451775a9362SMaya Erez cmd.sanitize_busy = true; 452da7fbe58SPierre Ossman 453636bd13cSUlf Hansson err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES); 45417b0429dSPierre Ossman if (err) 455da7fbe58SPierre Ossman return err; 456da7fbe58SPierre Ossman 457950d56acSJaehoon Chung /* No need to check card status in case of unblocking command */ 458950d56acSJaehoon Chung if (!use_busy_signal) 459950d56acSJaehoon Chung return 0; 460950d56acSJaehoon Chung 461a27fbf2fSSeungwon Jeon /* 4624509f847SUlf Hansson * CRC errors shall only be ignored in cases were CMD13 is used to poll 4634509f847SUlf Hansson * to detect busy completion. 464a27fbf2fSSeungwon Jeon */ 465b9ec2616SUlf Hansson if ((host->caps & MMC_CAP_WAIT_WHILE_BUSY) && use_r1b_resp) 4664509f847SUlf Hansson ignore_crc = false; 467a27fbf2fSSeungwon Jeon 468b9ec2616SUlf Hansson /* We have an unspecified cmd timeout, use the fallback value. */ 469b9ec2616SUlf Hansson if (!timeout_ms) 470b9ec2616SUlf Hansson timeout_ms = MMC_OPS_TIMEOUT_MS; 471b9ec2616SUlf Hansson 4724509f847SUlf Hansson /* Must check status to be sure of no errors. */ 473b9ec2616SUlf Hansson timeout = jiffies + msecs_to_jiffies(timeout_ms); 474ef0b27d4SAdrian Hunter do { 475878e200bSUlf Hansson if (send_status) { 476a27fbf2fSSeungwon Jeon err = __mmc_send_status(card, &status, ignore_crc); 477ef0b27d4SAdrian Hunter if (err) 478ef0b27d4SAdrian Hunter return err; 479878e200bSUlf Hansson } 480b9ec2616SUlf Hansson if ((host->caps & MMC_CAP_WAIT_WHILE_BUSY) && use_r1b_resp) 481ef0b27d4SAdrian Hunter break; 482636bd13cSUlf Hansson if (mmc_host_is_spi(host)) 483ef0b27d4SAdrian Hunter break; 4848fee476bSTrey Ramsay 485878e200bSUlf Hansson /* 486878e200bSUlf Hansson * We are not allowed to issue a status command and the host 487878e200bSUlf Hansson * does'nt support MMC_CAP_WAIT_WHILE_BUSY, then we can only 488878e200bSUlf Hansson * rely on waiting for the stated timeout to be sufficient. 489878e200bSUlf Hansson */ 490878e200bSUlf Hansson if (!send_status) { 491878e200bSUlf Hansson mmc_delay(timeout_ms); 492878e200bSUlf Hansson return 0; 493878e200bSUlf Hansson } 494878e200bSUlf Hansson 4958fee476bSTrey Ramsay /* Timeout if the device never leaves the program state. */ 4968fee476bSTrey Ramsay if (time_after(jiffies, timeout)) { 4978fee476bSTrey Ramsay pr_err("%s: Card stuck in programming state! %s\n", 498636bd13cSUlf Hansson mmc_hostname(host), __func__); 4998fee476bSTrey Ramsay return -ETIMEDOUT; 5008fee476bSTrey Ramsay } 5017435bb79SJaehoon Chung } while (R1_CURRENT_STATE(status) == R1_STATE_PRG); 502ef0b27d4SAdrian Hunter 503636bd13cSUlf Hansson if (mmc_host_is_spi(host)) { 504ef0b27d4SAdrian Hunter if (status & R1_SPI_ILLEGAL_COMMAND) 505ef0b27d4SAdrian Hunter return -EBADMSG; 506ef0b27d4SAdrian Hunter } else { 507ef0b27d4SAdrian Hunter if (status & 0xFDFFA000) 508636bd13cSUlf Hansson pr_warn("%s: unexpected status %#x after switch\n", 509636bd13cSUlf Hansson mmc_hostname(host), status); 510ef0b27d4SAdrian Hunter if (status & R1_SWITCH_ERROR) 511ef0b27d4SAdrian Hunter return -EBADMSG; 512ef0b27d4SAdrian Hunter } 513ef0b27d4SAdrian Hunter 51417b0429dSPierre Ossman return 0; 515da7fbe58SPierre Ossman } 516950d56acSJaehoon Chung EXPORT_SYMBOL_GPL(__mmc_switch); 517950d56acSJaehoon Chung 518950d56acSJaehoon Chung int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value, 519950d56acSJaehoon Chung unsigned int timeout_ms) 520950d56acSJaehoon Chung { 5214509f847SUlf Hansson return __mmc_switch(card, set, index, value, timeout_ms, true, true, 5224509f847SUlf Hansson false); 523950d56acSJaehoon Chung } 524d3a8d95dSAndrei Warkentin EXPORT_SYMBOL_GPL(mmc_switch); 525da7fbe58SPierre Ossman 52622113efdSAries Lee static int 52722113efdSAries Lee mmc_send_bus_test(struct mmc_card *card, struct mmc_host *host, u8 opcode, 52822113efdSAries Lee u8 len) 52922113efdSAries Lee { 530ad5fd972SVenkatraman S struct mmc_request mrq = {NULL}; 5311278dba1SChris Ball struct mmc_command cmd = {0}; 532a61ad2b4SChris Ball struct mmc_data data = {0}; 53322113efdSAries Lee struct scatterlist sg; 53422113efdSAries Lee u8 *data_buf; 53522113efdSAries Lee u8 *test_buf; 53622113efdSAries Lee int i, err; 53722113efdSAries Lee static u8 testdata_8bit[8] = { 0x55, 0xaa, 0, 0, 0, 0, 0, 0 }; 53822113efdSAries Lee static u8 testdata_4bit[4] = { 0x5a, 0, 0, 0 }; 53922113efdSAries Lee 54022113efdSAries Lee /* dma onto stack is unsafe/nonportable, but callers to this 54122113efdSAries Lee * routine normally provide temporary on-stack buffers ... 54222113efdSAries Lee */ 54322113efdSAries Lee data_buf = kmalloc(len, GFP_KERNEL); 54422113efdSAries Lee if (!data_buf) 54522113efdSAries Lee return -ENOMEM; 54622113efdSAries Lee 54722113efdSAries Lee if (len == 8) 54822113efdSAries Lee test_buf = testdata_8bit; 54922113efdSAries Lee else if (len == 4) 55022113efdSAries Lee test_buf = testdata_4bit; 55122113efdSAries Lee else { 552a3c76eb9SGirish K S pr_err("%s: Invalid bus_width %d\n", 55322113efdSAries Lee mmc_hostname(host), len); 55422113efdSAries Lee kfree(data_buf); 55522113efdSAries Lee return -EINVAL; 55622113efdSAries Lee } 55722113efdSAries Lee 55822113efdSAries Lee if (opcode == MMC_BUS_TEST_W) 55922113efdSAries Lee memcpy(data_buf, test_buf, len); 56022113efdSAries Lee 56122113efdSAries Lee mrq.cmd = &cmd; 56222113efdSAries Lee mrq.data = &data; 56322113efdSAries Lee cmd.opcode = opcode; 56422113efdSAries Lee cmd.arg = 0; 56522113efdSAries Lee 56622113efdSAries Lee /* NOTE HACK: the MMC_RSP_SPI_R1 is always correct here, but we 56722113efdSAries Lee * rely on callers to never use this with "native" calls for reading 56822113efdSAries Lee * CSD or CID. Native versions of those commands use the R2 type, 56922113efdSAries Lee * not R1 plus a data block. 57022113efdSAries Lee */ 57122113efdSAries Lee cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC; 57222113efdSAries Lee 57322113efdSAries Lee data.blksz = len; 57422113efdSAries Lee data.blocks = 1; 57522113efdSAries Lee if (opcode == MMC_BUS_TEST_R) 57622113efdSAries Lee data.flags = MMC_DATA_READ; 57722113efdSAries Lee else 57822113efdSAries Lee data.flags = MMC_DATA_WRITE; 57922113efdSAries Lee 58022113efdSAries Lee data.sg = &sg; 58122113efdSAries Lee data.sg_len = 1; 58284532e33SMinjian Wu mmc_set_data_timeout(&data, card); 58322113efdSAries Lee sg_init_one(&sg, data_buf, len); 58422113efdSAries Lee mmc_wait_for_req(host, &mrq); 58522113efdSAries Lee err = 0; 58622113efdSAries Lee if (opcode == MMC_BUS_TEST_R) { 58722113efdSAries Lee for (i = 0; i < len / 4; i++) 58822113efdSAries Lee if ((test_buf[i] ^ data_buf[i]) != 0xff) { 58922113efdSAries Lee err = -EIO; 59022113efdSAries Lee break; 59122113efdSAries Lee } 59222113efdSAries Lee } 59322113efdSAries Lee kfree(data_buf); 59422113efdSAries Lee 59522113efdSAries Lee if (cmd.error) 59622113efdSAries Lee return cmd.error; 59722113efdSAries Lee if (data.error) 59822113efdSAries Lee return data.error; 59922113efdSAries Lee 60022113efdSAries Lee return err; 60122113efdSAries Lee } 60222113efdSAries Lee 60322113efdSAries Lee int mmc_bus_test(struct mmc_card *card, u8 bus_width) 60422113efdSAries Lee { 60522113efdSAries Lee int err, width; 60622113efdSAries Lee 60722113efdSAries Lee if (bus_width == MMC_BUS_WIDTH_8) 60822113efdSAries Lee width = 8; 60922113efdSAries Lee else if (bus_width == MMC_BUS_WIDTH_4) 61022113efdSAries Lee width = 4; 61122113efdSAries Lee else if (bus_width == MMC_BUS_WIDTH_1) 61222113efdSAries Lee return 0; /* no need for test */ 61322113efdSAries Lee else 61422113efdSAries Lee return -EINVAL; 61522113efdSAries Lee 61622113efdSAries Lee /* 61722113efdSAries Lee * Ignore errors from BUS_TEST_W. BUS_TEST_R will fail if there 61822113efdSAries Lee * is a problem. This improves chances that the test will work. 61922113efdSAries Lee */ 62022113efdSAries Lee mmc_send_bus_test(card, card->host, MMC_BUS_TEST_W, width); 62122113efdSAries Lee err = mmc_send_bus_test(card, card->host, MMC_BUS_TEST_R, width); 62222113efdSAries Lee return err; 62322113efdSAries Lee } 624eb0d8f13SJaehoon Chung 625eb0d8f13SJaehoon Chung int mmc_send_hpi_cmd(struct mmc_card *card, u32 *status) 626eb0d8f13SJaehoon Chung { 627eb0d8f13SJaehoon Chung struct mmc_command cmd = {0}; 628eb0d8f13SJaehoon Chung unsigned int opcode; 629eb0d8f13SJaehoon Chung int err; 630eb0d8f13SJaehoon Chung 6312378975bSJaehoon Chung if (!card->ext_csd.hpi) { 6322378975bSJaehoon Chung pr_warning("%s: Card didn't support HPI command\n", 6332378975bSJaehoon Chung mmc_hostname(card->host)); 6342378975bSJaehoon Chung return -EINVAL; 6352378975bSJaehoon Chung } 6362378975bSJaehoon Chung 637eb0d8f13SJaehoon Chung opcode = card->ext_csd.hpi_cmd; 638eb0d8f13SJaehoon Chung if (opcode == MMC_STOP_TRANSMISSION) 6392378975bSJaehoon Chung cmd.flags = MMC_RSP_R1B | MMC_CMD_AC; 640eb0d8f13SJaehoon Chung else if (opcode == MMC_SEND_STATUS) 6412378975bSJaehoon Chung cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; 642eb0d8f13SJaehoon Chung 643eb0d8f13SJaehoon Chung cmd.opcode = opcode; 644eb0d8f13SJaehoon Chung cmd.arg = card->rca << 16 | 1; 645eb0d8f13SJaehoon Chung 646eb0d8f13SJaehoon Chung err = mmc_wait_for_cmd(card->host, &cmd, 0); 647eb0d8f13SJaehoon Chung if (err) { 648eb0d8f13SJaehoon Chung pr_warn("%s: error %d interrupting operation. " 649eb0d8f13SJaehoon Chung "HPI command response %#x\n", mmc_hostname(card->host), 650eb0d8f13SJaehoon Chung err, cmd.resp[0]); 651eb0d8f13SJaehoon Chung return err; 652eb0d8f13SJaehoon Chung } 653eb0d8f13SJaehoon Chung if (status) 654eb0d8f13SJaehoon Chung *status = cmd.resp[0]; 655eb0d8f13SJaehoon Chung 656eb0d8f13SJaehoon Chung return 0; 657eb0d8f13SJaehoon Chung } 658