xref: /openbmc/linux/drivers/mmc/core/mmc_ops.c (revision b9ec2616)
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