xref: /openbmc/linux/drivers/mmc/core/mmc_ops.c (revision 636bd13c)
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;
421da7fbe58SPierre Ossman 
422da7fbe58SPierre Ossman 	cmd.opcode = MMC_SWITCH;
423da7fbe58SPierre Ossman 	cmd.arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
424da7fbe58SPierre Ossman 		  (index << 16) |
425da7fbe58SPierre Ossman 		  (value << 8) |
426da7fbe58SPierre Ossman 		  set;
427950d56acSJaehoon Chung 	cmd.flags = MMC_CMD_AC;
428950d56acSJaehoon Chung 	if (use_busy_signal)
429950d56acSJaehoon Chung 		cmd.flags |= MMC_RSP_SPI_R1B | MMC_RSP_R1B;
430950d56acSJaehoon Chung 	else
431950d56acSJaehoon Chung 		cmd.flags |= MMC_RSP_SPI_R1 | MMC_RSP_R1;
432950d56acSJaehoon Chung 
433950d56acSJaehoon Chung 
4341d4d7744SUlf Hansson 	cmd.busy_timeout = timeout_ms;
435775a9362SMaya Erez 	if (index == EXT_CSD_SANITIZE_START)
436775a9362SMaya Erez 		cmd.sanitize_busy = true;
437da7fbe58SPierre Ossman 
438636bd13cSUlf Hansson 	err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES);
43917b0429dSPierre Ossman 	if (err)
440da7fbe58SPierre Ossman 		return err;
441da7fbe58SPierre Ossman 
442950d56acSJaehoon Chung 	/* No need to check card status in case of unblocking command */
443950d56acSJaehoon Chung 	if (!use_busy_signal)
444950d56acSJaehoon Chung 		return 0;
445950d56acSJaehoon Chung 
446a27fbf2fSSeungwon Jeon 	/*
4474509f847SUlf Hansson 	 * CRC errors shall only be ignored in cases were CMD13 is used to poll
4484509f847SUlf Hansson 	 * to detect busy completion.
449a27fbf2fSSeungwon Jeon 	 */
450636bd13cSUlf Hansson 	if (host->caps & MMC_CAP_WAIT_WHILE_BUSY)
4514509f847SUlf Hansson 		ignore_crc = false;
452a27fbf2fSSeungwon Jeon 
4534509f847SUlf Hansson 	/* Must check status to be sure of no errors. */
4548fee476bSTrey Ramsay 	timeout = jiffies + msecs_to_jiffies(MMC_OPS_TIMEOUT_MS);
455ef0b27d4SAdrian Hunter 	do {
456878e200bSUlf Hansson 		if (send_status) {
457a27fbf2fSSeungwon Jeon 			err = __mmc_send_status(card, &status, ignore_crc);
458ef0b27d4SAdrian Hunter 			if (err)
459ef0b27d4SAdrian Hunter 				return err;
460878e200bSUlf Hansson 		}
461636bd13cSUlf Hansson 		if (host->caps & MMC_CAP_WAIT_WHILE_BUSY)
462ef0b27d4SAdrian Hunter 			break;
463636bd13cSUlf Hansson 		if (mmc_host_is_spi(host))
464ef0b27d4SAdrian Hunter 			break;
4658fee476bSTrey Ramsay 
466878e200bSUlf Hansson 		/*
467878e200bSUlf Hansson 		 * We are not allowed to issue a status command and the host
468878e200bSUlf Hansson 		 * does'nt support MMC_CAP_WAIT_WHILE_BUSY, then we can only
469878e200bSUlf Hansson 		 * rely on waiting for the stated timeout to be sufficient.
470878e200bSUlf Hansson 		 */
471878e200bSUlf Hansson 		if (!send_status) {
472878e200bSUlf Hansson 			mmc_delay(timeout_ms);
473878e200bSUlf Hansson 			return 0;
474878e200bSUlf Hansson 		}
475878e200bSUlf Hansson 
4768fee476bSTrey Ramsay 		/* Timeout if the device never leaves the program state. */
4778fee476bSTrey Ramsay 		if (time_after(jiffies, timeout)) {
4788fee476bSTrey Ramsay 			pr_err("%s: Card stuck in programming state! %s\n",
479636bd13cSUlf Hansson 				mmc_hostname(host), __func__);
4808fee476bSTrey Ramsay 			return -ETIMEDOUT;
4818fee476bSTrey Ramsay 		}
4827435bb79SJaehoon Chung 	} while (R1_CURRENT_STATE(status) == R1_STATE_PRG);
483ef0b27d4SAdrian Hunter 
484636bd13cSUlf Hansson 	if (mmc_host_is_spi(host)) {
485ef0b27d4SAdrian Hunter 		if (status & R1_SPI_ILLEGAL_COMMAND)
486ef0b27d4SAdrian Hunter 			return -EBADMSG;
487ef0b27d4SAdrian Hunter 	} else {
488ef0b27d4SAdrian Hunter 		if (status & 0xFDFFA000)
489636bd13cSUlf Hansson 			pr_warn("%s: unexpected status %#x after switch\n",
490636bd13cSUlf Hansson 				mmc_hostname(host), status);
491ef0b27d4SAdrian Hunter 		if (status & R1_SWITCH_ERROR)
492ef0b27d4SAdrian Hunter 			return -EBADMSG;
493ef0b27d4SAdrian Hunter 	}
494ef0b27d4SAdrian Hunter 
49517b0429dSPierre Ossman 	return 0;
496da7fbe58SPierre Ossman }
497950d56acSJaehoon Chung EXPORT_SYMBOL_GPL(__mmc_switch);
498950d56acSJaehoon Chung 
499950d56acSJaehoon Chung int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
500950d56acSJaehoon Chung 		unsigned int timeout_ms)
501950d56acSJaehoon Chung {
5024509f847SUlf Hansson 	return __mmc_switch(card, set, index, value, timeout_ms, true, true,
5034509f847SUlf Hansson 				false);
504950d56acSJaehoon Chung }
505d3a8d95dSAndrei Warkentin EXPORT_SYMBOL_GPL(mmc_switch);
506da7fbe58SPierre Ossman 
50722113efdSAries Lee static int
50822113efdSAries Lee mmc_send_bus_test(struct mmc_card *card, struct mmc_host *host, u8 opcode,
50922113efdSAries Lee 		  u8 len)
51022113efdSAries Lee {
511ad5fd972SVenkatraman S 	struct mmc_request mrq = {NULL};
5121278dba1SChris Ball 	struct mmc_command cmd = {0};
513a61ad2b4SChris Ball 	struct mmc_data data = {0};
51422113efdSAries Lee 	struct scatterlist sg;
51522113efdSAries Lee 	u8 *data_buf;
51622113efdSAries Lee 	u8 *test_buf;
51722113efdSAries Lee 	int i, err;
51822113efdSAries Lee 	static u8 testdata_8bit[8] = { 0x55, 0xaa, 0, 0, 0, 0, 0, 0 };
51922113efdSAries Lee 	static u8 testdata_4bit[4] = { 0x5a, 0, 0, 0 };
52022113efdSAries Lee 
52122113efdSAries Lee 	/* dma onto stack is unsafe/nonportable, but callers to this
52222113efdSAries Lee 	 * routine normally provide temporary on-stack buffers ...
52322113efdSAries Lee 	 */
52422113efdSAries Lee 	data_buf = kmalloc(len, GFP_KERNEL);
52522113efdSAries Lee 	if (!data_buf)
52622113efdSAries Lee 		return -ENOMEM;
52722113efdSAries Lee 
52822113efdSAries Lee 	if (len == 8)
52922113efdSAries Lee 		test_buf = testdata_8bit;
53022113efdSAries Lee 	else if (len == 4)
53122113efdSAries Lee 		test_buf = testdata_4bit;
53222113efdSAries Lee 	else {
533a3c76eb9SGirish K S 		pr_err("%s: Invalid bus_width %d\n",
53422113efdSAries Lee 		       mmc_hostname(host), len);
53522113efdSAries Lee 		kfree(data_buf);
53622113efdSAries Lee 		return -EINVAL;
53722113efdSAries Lee 	}
53822113efdSAries Lee 
53922113efdSAries Lee 	if (opcode == MMC_BUS_TEST_W)
54022113efdSAries Lee 		memcpy(data_buf, test_buf, len);
54122113efdSAries Lee 
54222113efdSAries Lee 	mrq.cmd = &cmd;
54322113efdSAries Lee 	mrq.data = &data;
54422113efdSAries Lee 	cmd.opcode = opcode;
54522113efdSAries Lee 	cmd.arg = 0;
54622113efdSAries Lee 
54722113efdSAries Lee 	/* NOTE HACK:  the MMC_RSP_SPI_R1 is always correct here, but we
54822113efdSAries Lee 	 * rely on callers to never use this with "native" calls for reading
54922113efdSAries Lee 	 * CSD or CID.  Native versions of those commands use the R2 type,
55022113efdSAries Lee 	 * not R1 plus a data block.
55122113efdSAries Lee 	 */
55222113efdSAries Lee 	cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;
55322113efdSAries Lee 
55422113efdSAries Lee 	data.blksz = len;
55522113efdSAries Lee 	data.blocks = 1;
55622113efdSAries Lee 	if (opcode == MMC_BUS_TEST_R)
55722113efdSAries Lee 		data.flags = MMC_DATA_READ;
55822113efdSAries Lee 	else
55922113efdSAries Lee 		data.flags = MMC_DATA_WRITE;
56022113efdSAries Lee 
56122113efdSAries Lee 	data.sg = &sg;
56222113efdSAries Lee 	data.sg_len = 1;
56384532e33SMinjian Wu 	mmc_set_data_timeout(&data, card);
56422113efdSAries Lee 	sg_init_one(&sg, data_buf, len);
56522113efdSAries Lee 	mmc_wait_for_req(host, &mrq);
56622113efdSAries Lee 	err = 0;
56722113efdSAries Lee 	if (opcode == MMC_BUS_TEST_R) {
56822113efdSAries Lee 		for (i = 0; i < len / 4; i++)
56922113efdSAries Lee 			if ((test_buf[i] ^ data_buf[i]) != 0xff) {
57022113efdSAries Lee 				err = -EIO;
57122113efdSAries Lee 				break;
57222113efdSAries Lee 			}
57322113efdSAries Lee 	}
57422113efdSAries Lee 	kfree(data_buf);
57522113efdSAries Lee 
57622113efdSAries Lee 	if (cmd.error)
57722113efdSAries Lee 		return cmd.error;
57822113efdSAries Lee 	if (data.error)
57922113efdSAries Lee 		return data.error;
58022113efdSAries Lee 
58122113efdSAries Lee 	return err;
58222113efdSAries Lee }
58322113efdSAries Lee 
58422113efdSAries Lee int mmc_bus_test(struct mmc_card *card, u8 bus_width)
58522113efdSAries Lee {
58622113efdSAries Lee 	int err, width;
58722113efdSAries Lee 
58822113efdSAries Lee 	if (bus_width == MMC_BUS_WIDTH_8)
58922113efdSAries Lee 		width = 8;
59022113efdSAries Lee 	else if (bus_width == MMC_BUS_WIDTH_4)
59122113efdSAries Lee 		width = 4;
59222113efdSAries Lee 	else if (bus_width == MMC_BUS_WIDTH_1)
59322113efdSAries Lee 		return 0; /* no need for test */
59422113efdSAries Lee 	else
59522113efdSAries Lee 		return -EINVAL;
59622113efdSAries Lee 
59722113efdSAries Lee 	/*
59822113efdSAries Lee 	 * Ignore errors from BUS_TEST_W.  BUS_TEST_R will fail if there
59922113efdSAries Lee 	 * is a problem.  This improves chances that the test will work.
60022113efdSAries Lee 	 */
60122113efdSAries Lee 	mmc_send_bus_test(card, card->host, MMC_BUS_TEST_W, width);
60222113efdSAries Lee 	err = mmc_send_bus_test(card, card->host, MMC_BUS_TEST_R, width);
60322113efdSAries Lee 	return err;
60422113efdSAries Lee }
605eb0d8f13SJaehoon Chung 
606eb0d8f13SJaehoon Chung int mmc_send_hpi_cmd(struct mmc_card *card, u32 *status)
607eb0d8f13SJaehoon Chung {
608eb0d8f13SJaehoon Chung 	struct mmc_command cmd = {0};
609eb0d8f13SJaehoon Chung 	unsigned int opcode;
610eb0d8f13SJaehoon Chung 	int err;
611eb0d8f13SJaehoon Chung 
6122378975bSJaehoon Chung 	if (!card->ext_csd.hpi) {
6132378975bSJaehoon Chung 		pr_warning("%s: Card didn't support HPI command\n",
6142378975bSJaehoon Chung 			   mmc_hostname(card->host));
6152378975bSJaehoon Chung 		return -EINVAL;
6162378975bSJaehoon Chung 	}
6172378975bSJaehoon Chung 
618eb0d8f13SJaehoon Chung 	opcode = card->ext_csd.hpi_cmd;
619eb0d8f13SJaehoon Chung 	if (opcode == MMC_STOP_TRANSMISSION)
6202378975bSJaehoon Chung 		cmd.flags = MMC_RSP_R1B | MMC_CMD_AC;
621eb0d8f13SJaehoon Chung 	else if (opcode == MMC_SEND_STATUS)
6222378975bSJaehoon Chung 		cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
623eb0d8f13SJaehoon Chung 
624eb0d8f13SJaehoon Chung 	cmd.opcode = opcode;
625eb0d8f13SJaehoon Chung 	cmd.arg = card->rca << 16 | 1;
626eb0d8f13SJaehoon Chung 
627eb0d8f13SJaehoon Chung 	err = mmc_wait_for_cmd(card->host, &cmd, 0);
628eb0d8f13SJaehoon Chung 	if (err) {
629eb0d8f13SJaehoon Chung 		pr_warn("%s: error %d interrupting operation. "
630eb0d8f13SJaehoon Chung 			"HPI command response %#x\n", mmc_hostname(card->host),
631eb0d8f13SJaehoon Chung 			err, cmd.resp[0]);
632eb0d8f13SJaehoon Chung 		return err;
633eb0d8f13SJaehoon Chung 	}
634eb0d8f13SJaehoon Chung 	if (status)
635eb0d8f13SJaehoon Chung 		*status = cmd.resp[0];
636eb0d8f13SJaehoon Chung 
637eb0d8f13SJaehoon Chung 	return 0;
638eb0d8f13SJaehoon Chung }
639