xref: /openbmc/linux/drivers/mmc/core/mmc_ops.c (revision 716bdb89)
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"
22c6dbab9cSAdrian Hunter #include "host.h"
23da7fbe58SPierre Ossman #include "mmc_ops.h"
24da7fbe58SPierre Ossman 
258fee476bSTrey Ramsay #define MMC_OPS_TIMEOUT_MS	(10 * 60 * 1000) /* 10 minute timeout */
268fee476bSTrey Ramsay 
2704cdbbfaSUlf Hansson static const u8 tuning_blk_pattern_4bit[] = {
2804cdbbfaSUlf Hansson 	0xff, 0x0f, 0xff, 0x00, 0xff, 0xcc, 0xc3, 0xcc,
2904cdbbfaSUlf Hansson 	0xc3, 0x3c, 0xcc, 0xff, 0xfe, 0xff, 0xfe, 0xef,
3004cdbbfaSUlf Hansson 	0xff, 0xdf, 0xff, 0xdd, 0xff, 0xfb, 0xff, 0xfb,
3104cdbbfaSUlf Hansson 	0xbf, 0xff, 0x7f, 0xff, 0x77, 0xf7, 0xbd, 0xef,
3204cdbbfaSUlf Hansson 	0xff, 0xf0, 0xff, 0xf0, 0x0f, 0xfc, 0xcc, 0x3c,
3304cdbbfaSUlf Hansson 	0xcc, 0x33, 0xcc, 0xcf, 0xff, 0xef, 0xff, 0xee,
3404cdbbfaSUlf Hansson 	0xff, 0xfd, 0xff, 0xfd, 0xdf, 0xff, 0xbf, 0xff,
3504cdbbfaSUlf Hansson 	0xbb, 0xff, 0xf7, 0xff, 0xf7, 0x7f, 0x7b, 0xde,
3604cdbbfaSUlf Hansson };
3704cdbbfaSUlf Hansson 
3804cdbbfaSUlf Hansson static const u8 tuning_blk_pattern_8bit[] = {
3904cdbbfaSUlf Hansson 	0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00,
4004cdbbfaSUlf Hansson 	0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc, 0xcc,
4104cdbbfaSUlf Hansson 	0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff, 0xff,
4204cdbbfaSUlf Hansson 	0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee, 0xff,
4304cdbbfaSUlf Hansson 	0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd, 0xdd,
4404cdbbfaSUlf Hansson 	0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb,
4504cdbbfaSUlf Hansson 	0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff, 0xff,
4604cdbbfaSUlf Hansson 	0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee, 0xff,
4704cdbbfaSUlf Hansson 	0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00,
4804cdbbfaSUlf Hansson 	0x00, 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc,
4904cdbbfaSUlf Hansson 	0xcc, 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff,
5004cdbbfaSUlf Hansson 	0xff, 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee,
5104cdbbfaSUlf Hansson 	0xff, 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd,
5204cdbbfaSUlf Hansson 	0xdd, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff,
5304cdbbfaSUlf Hansson 	0xbb, 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff,
5404cdbbfaSUlf Hansson 	0xff, 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee,
5504cdbbfaSUlf Hansson };
5604cdbbfaSUlf Hansson 
57a27fbf2fSSeungwon Jeon static inline int __mmc_send_status(struct mmc_card *card, u32 *status,
58a27fbf2fSSeungwon Jeon 				    bool ignore_crc)
59a27fbf2fSSeungwon Jeon {
60a27fbf2fSSeungwon Jeon 	int err;
61a27fbf2fSSeungwon Jeon 	struct mmc_command cmd = {0};
62a27fbf2fSSeungwon Jeon 
63a27fbf2fSSeungwon Jeon 	BUG_ON(!card);
64a27fbf2fSSeungwon Jeon 	BUG_ON(!card->host);
65a27fbf2fSSeungwon Jeon 
66a27fbf2fSSeungwon Jeon 	cmd.opcode = MMC_SEND_STATUS;
67a27fbf2fSSeungwon Jeon 	if (!mmc_host_is_spi(card->host))
68a27fbf2fSSeungwon Jeon 		cmd.arg = card->rca << 16;
69a27fbf2fSSeungwon Jeon 	cmd.flags = MMC_RSP_SPI_R2 | MMC_RSP_R1 | MMC_CMD_AC;
70a27fbf2fSSeungwon Jeon 	if (ignore_crc)
71a27fbf2fSSeungwon Jeon 		cmd.flags &= ~MMC_RSP_CRC;
72a27fbf2fSSeungwon Jeon 
73a27fbf2fSSeungwon Jeon 	err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES);
74a27fbf2fSSeungwon Jeon 	if (err)
75a27fbf2fSSeungwon Jeon 		return err;
76a27fbf2fSSeungwon Jeon 
77a27fbf2fSSeungwon Jeon 	/* NOTE: callers are required to understand the difference
78a27fbf2fSSeungwon Jeon 	 * between "native" and SPI format status words!
79a27fbf2fSSeungwon Jeon 	 */
80a27fbf2fSSeungwon Jeon 	if (status)
81a27fbf2fSSeungwon Jeon 		*status = cmd.resp[0];
82a27fbf2fSSeungwon Jeon 
83a27fbf2fSSeungwon Jeon 	return 0;
84a27fbf2fSSeungwon Jeon }
85a27fbf2fSSeungwon Jeon 
86a27fbf2fSSeungwon Jeon int mmc_send_status(struct mmc_card *card, u32 *status)
87a27fbf2fSSeungwon Jeon {
88a27fbf2fSSeungwon Jeon 	return __mmc_send_status(card, status, false);
89a27fbf2fSSeungwon Jeon }
90a27fbf2fSSeungwon Jeon 
91da7fbe58SPierre Ossman static int _mmc_select_card(struct mmc_host *host, struct mmc_card *card)
92da7fbe58SPierre Ossman {
931278dba1SChris Ball 	struct mmc_command cmd = {0};
94da7fbe58SPierre Ossman 
95da7fbe58SPierre Ossman 	BUG_ON(!host);
96da7fbe58SPierre Ossman 
97da7fbe58SPierre Ossman 	cmd.opcode = MMC_SELECT_CARD;
98da7fbe58SPierre Ossman 
99da7fbe58SPierre Ossman 	if (card) {
100da7fbe58SPierre Ossman 		cmd.arg = card->rca << 16;
101da7fbe58SPierre Ossman 		cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
102da7fbe58SPierre Ossman 	} else {
103da7fbe58SPierre Ossman 		cmd.arg = 0;
104da7fbe58SPierre Ossman 		cmd.flags = MMC_RSP_NONE | MMC_CMD_AC;
105da7fbe58SPierre Ossman 	}
106da7fbe58SPierre Ossman 
1070899e741SMasahiro Yamada 	return mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES);
108da7fbe58SPierre Ossman }
109da7fbe58SPierre Ossman 
110da7fbe58SPierre Ossman int mmc_select_card(struct mmc_card *card)
111da7fbe58SPierre Ossman {
112da7fbe58SPierre Ossman 	BUG_ON(!card);
113da7fbe58SPierre Ossman 
114da7fbe58SPierre Ossman 	return _mmc_select_card(card->host, card);
115da7fbe58SPierre Ossman }
116da7fbe58SPierre Ossman 
117da7fbe58SPierre Ossman int mmc_deselect_cards(struct mmc_host *host)
118da7fbe58SPierre Ossman {
119da7fbe58SPierre Ossman 	return _mmc_select_card(host, NULL);
120da7fbe58SPierre Ossman }
121da7fbe58SPierre Ossman 
1223d705d14SSascha Hauer /*
1233d705d14SSascha Hauer  * Write the value specified in the device tree or board code into the optional
1243d705d14SSascha Hauer  * 16 bit Driver Stage Register. This can be used to tune raise/fall times and
1253d705d14SSascha Hauer  * drive strength of the DAT and CMD outputs. The actual meaning of a given
1263d705d14SSascha Hauer  * value is hardware dependant.
1273d705d14SSascha Hauer  * The presence of the DSR register can be determined from the CSD register,
1283d705d14SSascha Hauer  * bit 76.
1293d705d14SSascha Hauer  */
1303d705d14SSascha Hauer int mmc_set_dsr(struct mmc_host *host)
1313d705d14SSascha Hauer {
1323d705d14SSascha Hauer 	struct mmc_command cmd = {0};
1333d705d14SSascha Hauer 
1343d705d14SSascha Hauer 	cmd.opcode = MMC_SET_DSR;
1353d705d14SSascha Hauer 
1363d705d14SSascha Hauer 	cmd.arg = (host->dsr << 16) | 0xffff;
1373d705d14SSascha Hauer 	cmd.flags = MMC_RSP_NONE | MMC_CMD_AC;
1383d705d14SSascha Hauer 
1393d705d14SSascha Hauer 	return mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES);
1403d705d14SSascha Hauer }
1413d705d14SSascha Hauer 
142da7fbe58SPierre Ossman int mmc_go_idle(struct mmc_host *host)
143da7fbe58SPierre Ossman {
144da7fbe58SPierre Ossman 	int err;
1451278dba1SChris Ball 	struct mmc_command cmd = {0};
146da7fbe58SPierre Ossman 
147af517150SDavid Brownell 	/*
148af517150SDavid Brownell 	 * Non-SPI hosts need to prevent chipselect going active during
149af517150SDavid Brownell 	 * GO_IDLE; that would put chips into SPI mode.  Remind them of
150af517150SDavid Brownell 	 * that in case of hardware that won't pull up DAT3/nCS otherwise.
151af517150SDavid Brownell 	 *
152af517150SDavid Brownell 	 * SPI hosts ignore ios.chip_select; it's managed according to
15325985edcSLucas De Marchi 	 * rules that must accommodate non-MMC slaves which this layer
154af517150SDavid Brownell 	 * won't even know about.
155af517150SDavid Brownell 	 */
156af517150SDavid Brownell 	if (!mmc_host_is_spi(host)) {
157da7fbe58SPierre Ossman 		mmc_set_chip_select(host, MMC_CS_HIGH);
158da7fbe58SPierre Ossman 		mmc_delay(1);
159af517150SDavid Brownell 	}
160da7fbe58SPierre Ossman 
161da7fbe58SPierre Ossman 	cmd.opcode = MMC_GO_IDLE_STATE;
162da7fbe58SPierre Ossman 	cmd.arg = 0;
163af517150SDavid Brownell 	cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_NONE | MMC_CMD_BC;
164da7fbe58SPierre Ossman 
165da7fbe58SPierre Ossman 	err = mmc_wait_for_cmd(host, &cmd, 0);
166da7fbe58SPierre Ossman 
167da7fbe58SPierre Ossman 	mmc_delay(1);
168da7fbe58SPierre Ossman 
169af517150SDavid Brownell 	if (!mmc_host_is_spi(host)) {
170da7fbe58SPierre Ossman 		mmc_set_chip_select(host, MMC_CS_DONTCARE);
171da7fbe58SPierre Ossman 		mmc_delay(1);
172af517150SDavid Brownell 	}
173af517150SDavid Brownell 
174af517150SDavid Brownell 	host->use_spi_crc = 0;
175da7fbe58SPierre Ossman 
176da7fbe58SPierre Ossman 	return err;
177da7fbe58SPierre Ossman }
178da7fbe58SPierre Ossman 
179da7fbe58SPierre Ossman int mmc_send_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr)
180da7fbe58SPierre Ossman {
1811278dba1SChris Ball 	struct mmc_command cmd = {0};
182da7fbe58SPierre Ossman 	int i, err = 0;
183da7fbe58SPierre Ossman 
184da7fbe58SPierre Ossman 	BUG_ON(!host);
185da7fbe58SPierre Ossman 
186da7fbe58SPierre Ossman 	cmd.opcode = MMC_SEND_OP_COND;
187af517150SDavid Brownell 	cmd.arg = mmc_host_is_spi(host) ? 0 : ocr;
188af517150SDavid Brownell 	cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R3 | MMC_CMD_BCR;
189da7fbe58SPierre Ossman 
190da7fbe58SPierre Ossman 	for (i = 100; i; i--) {
191da7fbe58SPierre Ossman 		err = mmc_wait_for_cmd(host, &cmd, 0);
19217b0429dSPierre Ossman 		if (err)
193da7fbe58SPierre Ossman 			break;
194da7fbe58SPierre Ossman 
195af517150SDavid Brownell 		/* if we're just probing, do a single pass */
196af517150SDavid Brownell 		if (ocr == 0)
197da7fbe58SPierre Ossman 			break;
198da7fbe58SPierre Ossman 
199af517150SDavid Brownell 		/* otherwise wait until reset completes */
200af517150SDavid Brownell 		if (mmc_host_is_spi(host)) {
201af517150SDavid Brownell 			if (!(cmd.resp[0] & R1_SPI_IDLE))
202af517150SDavid Brownell 				break;
203af517150SDavid Brownell 		} else {
204af517150SDavid Brownell 			if (cmd.resp[0] & MMC_CARD_BUSY)
205af517150SDavid Brownell 				break;
206af517150SDavid Brownell 		}
207af517150SDavid Brownell 
20817b0429dSPierre Ossman 		err = -ETIMEDOUT;
209da7fbe58SPierre Ossman 
210da7fbe58SPierre Ossman 		mmc_delay(10);
211da7fbe58SPierre Ossman 	}
212da7fbe58SPierre Ossman 
213af517150SDavid Brownell 	if (rocr && !mmc_host_is_spi(host))
214da7fbe58SPierre Ossman 		*rocr = cmd.resp[0];
215da7fbe58SPierre Ossman 
216da7fbe58SPierre Ossman 	return err;
217da7fbe58SPierre Ossman }
218da7fbe58SPierre Ossman 
219da7fbe58SPierre Ossman int mmc_all_send_cid(struct mmc_host *host, u32 *cid)
220da7fbe58SPierre Ossman {
221da7fbe58SPierre Ossman 	int err;
2221278dba1SChris Ball 	struct mmc_command cmd = {0};
223da7fbe58SPierre Ossman 
224da7fbe58SPierre Ossman 	BUG_ON(!host);
225da7fbe58SPierre Ossman 	BUG_ON(!cid);
226da7fbe58SPierre Ossman 
227da7fbe58SPierre Ossman 	cmd.opcode = MMC_ALL_SEND_CID;
228da7fbe58SPierre Ossman 	cmd.arg = 0;
229da7fbe58SPierre Ossman 	cmd.flags = MMC_RSP_R2 | MMC_CMD_BCR;
230da7fbe58SPierre Ossman 
231da7fbe58SPierre Ossman 	err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES);
23217b0429dSPierre Ossman 	if (err)
233da7fbe58SPierre Ossman 		return err;
234da7fbe58SPierre Ossman 
235da7fbe58SPierre Ossman 	memcpy(cid, cmd.resp, sizeof(u32) * 4);
236da7fbe58SPierre Ossman 
23717b0429dSPierre Ossman 	return 0;
238da7fbe58SPierre Ossman }
239da7fbe58SPierre Ossman 
240da7fbe58SPierre Ossman int mmc_set_relative_addr(struct mmc_card *card)
241da7fbe58SPierre Ossman {
2421278dba1SChris Ball 	struct mmc_command cmd = {0};
243da7fbe58SPierre Ossman 
244da7fbe58SPierre Ossman 	BUG_ON(!card);
245da7fbe58SPierre Ossman 	BUG_ON(!card->host);
246da7fbe58SPierre Ossman 
247da7fbe58SPierre Ossman 	cmd.opcode = MMC_SET_RELATIVE_ADDR;
248da7fbe58SPierre Ossman 	cmd.arg = card->rca << 16;
249da7fbe58SPierre Ossman 	cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
250da7fbe58SPierre Ossman 
2510899e741SMasahiro Yamada 	return mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES);
252da7fbe58SPierre Ossman }
253da7fbe58SPierre Ossman 
254af517150SDavid Brownell static int
255af517150SDavid Brownell mmc_send_cxd_native(struct mmc_host *host, u32 arg, u32 *cxd, int opcode)
256da7fbe58SPierre Ossman {
257da7fbe58SPierre Ossman 	int err;
2581278dba1SChris Ball 	struct mmc_command cmd = {0};
259da7fbe58SPierre Ossman 
260af517150SDavid Brownell 	BUG_ON(!host);
261af517150SDavid Brownell 	BUG_ON(!cxd);
262da7fbe58SPierre Ossman 
263af517150SDavid Brownell 	cmd.opcode = opcode;
264af517150SDavid Brownell 	cmd.arg = arg;
265da7fbe58SPierre Ossman 	cmd.flags = MMC_RSP_R2 | MMC_CMD_AC;
266da7fbe58SPierre Ossman 
267af517150SDavid Brownell 	err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES);
26817b0429dSPierre Ossman 	if (err)
269da7fbe58SPierre Ossman 		return err;
270da7fbe58SPierre Ossman 
271af517150SDavid Brownell 	memcpy(cxd, cmd.resp, sizeof(u32) * 4);
272da7fbe58SPierre Ossman 
27317b0429dSPierre Ossman 	return 0;
274da7fbe58SPierre Ossman }
275da7fbe58SPierre Ossman 
2761a41313eSKyungsik Lee /*
2771a41313eSKyungsik Lee  * NOTE: void *buf, caller for the buf is required to use DMA-capable
2781a41313eSKyungsik Lee  * buffer or on-stack buffer (with some overhead in callee).
2791a41313eSKyungsik Lee  */
280af517150SDavid Brownell static int
281af517150SDavid Brownell mmc_send_cxd_data(struct mmc_card *card, struct mmc_host *host,
282af517150SDavid Brownell 		u32 opcode, void *buf, unsigned len)
283da7fbe58SPierre Ossman {
284ad5fd972SVenkatraman S 	struct mmc_request mrq = {NULL};
2851278dba1SChris Ball 	struct mmc_command cmd = {0};
286a61ad2b4SChris Ball 	struct mmc_data data = {0};
287da7fbe58SPierre Ossman 	struct scatterlist sg;
288da7fbe58SPierre Ossman 
289da7fbe58SPierre Ossman 	mrq.cmd = &cmd;
290da7fbe58SPierre Ossman 	mrq.data = &data;
291da7fbe58SPierre Ossman 
292af517150SDavid Brownell 	cmd.opcode = opcode;
293da7fbe58SPierre Ossman 	cmd.arg = 0;
294da7fbe58SPierre Ossman 
295af517150SDavid Brownell 	/* NOTE HACK:  the MMC_RSP_SPI_R1 is always correct here, but we
296af517150SDavid Brownell 	 * rely on callers to never use this with "native" calls for reading
297af517150SDavid Brownell 	 * CSD or CID.  Native versions of those commands use the R2 type,
298af517150SDavid Brownell 	 * not R1 plus a data block.
299af517150SDavid Brownell 	 */
300af517150SDavid Brownell 	cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;
301af517150SDavid Brownell 
302af517150SDavid Brownell 	data.blksz = len;
303da7fbe58SPierre Ossman 	data.blocks = 1;
304da7fbe58SPierre Ossman 	data.flags = MMC_DATA_READ;
305da7fbe58SPierre Ossman 	data.sg = &sg;
306da7fbe58SPierre Ossman 	data.sg_len = 1;
307da7fbe58SPierre Ossman 
308601ed60cSUlf Hansson 	sg_init_one(&sg, buf, len);
309da7fbe58SPierre Ossman 
310cda56ac2SAdrian Hunter 	if (opcode == MMC_SEND_CSD || opcode == MMC_SEND_CID) {
3110d3e0460SMatthew Fleming 		/*
3120d3e0460SMatthew Fleming 		 * The spec states that CSR and CID accesses have a timeout
3130d3e0460SMatthew Fleming 		 * of 64 clock cycles.
3140d3e0460SMatthew Fleming 		 */
3150d3e0460SMatthew Fleming 		data.timeout_ns = 0;
3160d3e0460SMatthew Fleming 		data.timeout_clks = 64;
317cda56ac2SAdrian Hunter 	} else
318cda56ac2SAdrian Hunter 		mmc_set_data_timeout(&data, card);
319da7fbe58SPierre Ossman 
320af517150SDavid Brownell 	mmc_wait_for_req(host, &mrq);
321af517150SDavid Brownell 
32217b0429dSPierre Ossman 	if (cmd.error)
323da7fbe58SPierre Ossman 		return cmd.error;
32417b0429dSPierre Ossman 	if (data.error)
325da7fbe58SPierre Ossman 		return data.error;
326da7fbe58SPierre Ossman 
32717b0429dSPierre Ossman 	return 0;
328da7fbe58SPierre Ossman }
329da7fbe58SPierre Ossman 
330af517150SDavid Brownell int mmc_send_csd(struct mmc_card *card, u32 *csd)
331af517150SDavid Brownell {
33278e48073SPierre Ossman 	int ret, i;
3331a41313eSKyungsik Lee 	u32 *csd_tmp;
33478e48073SPierre Ossman 
335af517150SDavid Brownell 	if (!mmc_host_is_spi(card->host))
336af517150SDavid Brownell 		return mmc_send_cxd_native(card->host, card->rca << 16,
337af517150SDavid Brownell 				csd, MMC_SEND_CSD);
338af517150SDavid Brownell 
33922b78700SUlf Hansson 	csd_tmp = kzalloc(16, GFP_KERNEL);
3401a41313eSKyungsik Lee 	if (!csd_tmp)
3411a41313eSKyungsik Lee 		return -ENOMEM;
3421a41313eSKyungsik Lee 
3431a41313eSKyungsik Lee 	ret = mmc_send_cxd_data(card, card->host, MMC_SEND_CSD, csd_tmp, 16);
34478e48073SPierre Ossman 	if (ret)
3451a41313eSKyungsik Lee 		goto err;
34678e48073SPierre Ossman 
34778e48073SPierre Ossman 	for (i = 0;i < 4;i++)
3481a41313eSKyungsik Lee 		csd[i] = be32_to_cpu(csd_tmp[i]);
34978e48073SPierre Ossman 
3501a41313eSKyungsik Lee err:
3511a41313eSKyungsik Lee 	kfree(csd_tmp);
3521a41313eSKyungsik Lee 	return ret;
353af517150SDavid Brownell }
354af517150SDavid Brownell 
355af517150SDavid Brownell int mmc_send_cid(struct mmc_host *host, u32 *cid)
356af517150SDavid Brownell {
35778e48073SPierre Ossman 	int ret, i;
3581a41313eSKyungsik Lee 	u32 *cid_tmp;
35978e48073SPierre Ossman 
360af517150SDavid Brownell 	if (!mmc_host_is_spi(host)) {
361af517150SDavid Brownell 		if (!host->card)
362af517150SDavid Brownell 			return -EINVAL;
363af517150SDavid Brownell 		return mmc_send_cxd_native(host, host->card->rca << 16,
364af517150SDavid Brownell 				cid, MMC_SEND_CID);
365af517150SDavid Brownell 	}
366af517150SDavid Brownell 
36722b78700SUlf Hansson 	cid_tmp = kzalloc(16, GFP_KERNEL);
3681a41313eSKyungsik Lee 	if (!cid_tmp)
3691a41313eSKyungsik Lee 		return -ENOMEM;
3701a41313eSKyungsik Lee 
3711a41313eSKyungsik Lee 	ret = mmc_send_cxd_data(NULL, host, MMC_SEND_CID, cid_tmp, 16);
37278e48073SPierre Ossman 	if (ret)
3731a41313eSKyungsik Lee 		goto err;
37478e48073SPierre Ossman 
37578e48073SPierre Ossman 	for (i = 0;i < 4;i++)
3761a41313eSKyungsik Lee 		cid[i] = be32_to_cpu(cid_tmp[i]);
37778e48073SPierre Ossman 
3781a41313eSKyungsik Lee err:
3791a41313eSKyungsik Lee 	kfree(cid_tmp);
3801a41313eSKyungsik Lee 	return ret;
381af517150SDavid Brownell }
382af517150SDavid Brownell 
383e21aa519SUlf Hansson int mmc_get_ext_csd(struct mmc_card *card, u8 **new_ext_csd)
384e21aa519SUlf Hansson {
385e21aa519SUlf Hansson 	int err;
386e21aa519SUlf Hansson 	u8 *ext_csd;
387e21aa519SUlf Hansson 
388e21aa519SUlf Hansson 	if (!card || !new_ext_csd)
389e21aa519SUlf Hansson 		return -EINVAL;
390e21aa519SUlf Hansson 
391e21aa519SUlf Hansson 	if (!mmc_can_ext_csd(card))
392e21aa519SUlf Hansson 		return -EOPNOTSUPP;
393e21aa519SUlf Hansson 
394e21aa519SUlf Hansson 	/*
395e21aa519SUlf Hansson 	 * As the ext_csd is so large and mostly unused, we don't store the
396e21aa519SUlf Hansson 	 * raw block in mmc_card.
397e21aa519SUlf Hansson 	 */
39822b78700SUlf Hansson 	ext_csd = kzalloc(512, GFP_KERNEL);
399e21aa519SUlf Hansson 	if (!ext_csd)
400e21aa519SUlf Hansson 		return -ENOMEM;
401e21aa519SUlf Hansson 
4022fc91e8bSUlf Hansson 	err = mmc_send_cxd_data(card, card->host, MMC_SEND_EXT_CSD, ext_csd,
4032fc91e8bSUlf Hansson 				512);
404e21aa519SUlf Hansson 	if (err)
405e21aa519SUlf Hansson 		kfree(ext_csd);
406e21aa519SUlf Hansson 	else
407e21aa519SUlf Hansson 		*new_ext_csd = ext_csd;
408e21aa519SUlf Hansson 
409e21aa519SUlf Hansson 	return err;
410e21aa519SUlf Hansson }
411e21aa519SUlf Hansson EXPORT_SYMBOL_GPL(mmc_get_ext_csd);
412e21aa519SUlf Hansson 
413af517150SDavid Brownell int mmc_spi_read_ocr(struct mmc_host *host, int highcap, u32 *ocrp)
414af517150SDavid Brownell {
4151278dba1SChris Ball 	struct mmc_command cmd = {0};
416af517150SDavid Brownell 	int err;
417af517150SDavid Brownell 
418af517150SDavid Brownell 	cmd.opcode = MMC_SPI_READ_OCR;
419af517150SDavid Brownell 	cmd.arg = highcap ? (1 << 30) : 0;
420af517150SDavid Brownell 	cmd.flags = MMC_RSP_SPI_R3;
421af517150SDavid Brownell 
422af517150SDavid Brownell 	err = mmc_wait_for_cmd(host, &cmd, 0);
423af517150SDavid Brownell 
424af517150SDavid Brownell 	*ocrp = cmd.resp[1];
425af517150SDavid Brownell 	return err;
426af517150SDavid Brownell }
427af517150SDavid Brownell 
428af517150SDavid Brownell int mmc_spi_set_crc(struct mmc_host *host, int use_crc)
429af517150SDavid Brownell {
4301278dba1SChris Ball 	struct mmc_command cmd = {0};
431af517150SDavid Brownell 	int err;
432af517150SDavid Brownell 
433af517150SDavid Brownell 	cmd.opcode = MMC_SPI_CRC_ON_OFF;
434af517150SDavid Brownell 	cmd.flags = MMC_RSP_SPI_R1;
435af517150SDavid Brownell 	cmd.arg = use_crc;
436af517150SDavid Brownell 
437af517150SDavid Brownell 	err = mmc_wait_for_cmd(host, &cmd, 0);
438af517150SDavid Brownell 	if (!err)
439af517150SDavid Brownell 		host->use_spi_crc = use_crc;
440af517150SDavid Brownell 	return err;
441af517150SDavid Brownell }
442af517150SDavid Brownell 
44320348d19SUlf Hansson static int mmc_switch_status_error(struct mmc_host *host, u32 status)
444ed16f58dSAdrian Hunter {
445ed16f58dSAdrian Hunter 	if (mmc_host_is_spi(host)) {
446ed16f58dSAdrian Hunter 		if (status & R1_SPI_ILLEGAL_COMMAND)
447ed16f58dSAdrian Hunter 			return -EBADMSG;
448ed16f58dSAdrian Hunter 	} else {
449ed16f58dSAdrian Hunter 		if (status & 0xFDFFA000)
450ed16f58dSAdrian Hunter 			pr_warn("%s: unexpected status %#x after switch\n",
451ed16f58dSAdrian Hunter 				mmc_hostname(host), status);
452ed16f58dSAdrian Hunter 		if (status & R1_SWITCH_ERROR)
453ed16f58dSAdrian Hunter 			return -EBADMSG;
454ed16f58dSAdrian Hunter 	}
455ed16f58dSAdrian Hunter 	return 0;
456ed16f58dSAdrian Hunter }
457ed16f58dSAdrian Hunter 
45820348d19SUlf Hansson /* Caller must hold re-tuning */
45920348d19SUlf Hansson int mmc_switch_status(struct mmc_card *card)
46020348d19SUlf Hansson {
46120348d19SUlf Hansson 	u32 status;
46220348d19SUlf Hansson 	int err;
46320348d19SUlf Hansson 
46420348d19SUlf Hansson 	err = mmc_send_status(card, &status);
46520348d19SUlf Hansson 	if (err)
46620348d19SUlf Hansson 		return err;
46720348d19SUlf Hansson 
46820348d19SUlf Hansson 	return mmc_switch_status_error(card->host, status);
46920348d19SUlf Hansson }
47020348d19SUlf Hansson 
471716bdb89SUlf Hansson static int mmc_poll_for_busy(struct mmc_card *card, unsigned int timeout_ms,
472716bdb89SUlf Hansson 			bool send_status, bool ignore_crc)
473716bdb89SUlf Hansson {
474716bdb89SUlf Hansson 	struct mmc_host *host = card->host;
475716bdb89SUlf Hansson 	int err;
476716bdb89SUlf Hansson 	unsigned long timeout;
477716bdb89SUlf Hansson 	u32 status = 0;
478716bdb89SUlf Hansson 	bool expired = false;
479716bdb89SUlf Hansson 	bool busy = false;
480716bdb89SUlf Hansson 
481716bdb89SUlf Hansson 	/* We have an unspecified cmd timeout, use the fallback value. */
482716bdb89SUlf Hansson 	if (!timeout_ms)
483716bdb89SUlf Hansson 		timeout_ms = MMC_OPS_TIMEOUT_MS;
484716bdb89SUlf Hansson 
485716bdb89SUlf Hansson 	/*
486716bdb89SUlf Hansson 	 * In cases when not allowed to poll by using CMD13 or because we aren't
487716bdb89SUlf Hansson 	 * capable of polling by using ->card_busy(), then rely on waiting the
488716bdb89SUlf Hansson 	 * stated timeout to be sufficient.
489716bdb89SUlf Hansson 	 */
490716bdb89SUlf Hansson 	if (!send_status && !host->ops->card_busy) {
491716bdb89SUlf Hansson 		mmc_delay(timeout_ms);
492716bdb89SUlf Hansson 		return 0;
493716bdb89SUlf Hansson 	}
494716bdb89SUlf Hansson 
495716bdb89SUlf Hansson 	timeout = jiffies + msecs_to_jiffies(timeout_ms) + 1;
496716bdb89SUlf Hansson 	do {
497716bdb89SUlf Hansson 		/*
498716bdb89SUlf Hansson 		 * Due to the possibility of being preempted after
499716bdb89SUlf Hansson 		 * sending the status command, check the expiration
500716bdb89SUlf Hansson 		 * time first.
501716bdb89SUlf Hansson 		 */
502716bdb89SUlf Hansson 		expired = time_after(jiffies, timeout);
503716bdb89SUlf Hansson 		if (send_status) {
504716bdb89SUlf Hansson 			err = __mmc_send_status(card, &status, ignore_crc);
505716bdb89SUlf Hansson 			if (err)
506716bdb89SUlf Hansson 				return err;
507716bdb89SUlf Hansson 		}
508716bdb89SUlf Hansson 		if (host->ops->card_busy) {
509716bdb89SUlf Hansson 			if (!host->ops->card_busy(host))
510716bdb89SUlf Hansson 				break;
511716bdb89SUlf Hansson 			busy = true;
512716bdb89SUlf Hansson 		}
513716bdb89SUlf Hansson 
514716bdb89SUlf Hansson 		/* Timeout if the device never leaves the program state. */
515716bdb89SUlf Hansson 		if (expired &&
516716bdb89SUlf Hansson 		    (R1_CURRENT_STATE(status) == R1_STATE_PRG || busy)) {
517716bdb89SUlf Hansson 			pr_err("%s: Card stuck in programming state! %s\n",
518716bdb89SUlf Hansson 				mmc_hostname(host), __func__);
519716bdb89SUlf Hansson 			return -ETIMEDOUT;
520716bdb89SUlf Hansson 		}
521716bdb89SUlf Hansson 	} while (R1_CURRENT_STATE(status) == R1_STATE_PRG || busy);
522716bdb89SUlf Hansson 
523716bdb89SUlf Hansson 	err = mmc_switch_status_error(host, status);
524716bdb89SUlf Hansson 
525716bdb89SUlf Hansson 	return err;
526716bdb89SUlf Hansson }
527716bdb89SUlf Hansson 
528d3a8d95dSAndrei Warkentin /**
529950d56acSJaehoon Chung  *	__mmc_switch - modify EXT_CSD register
530d3a8d95dSAndrei Warkentin  *	@card: the MMC card associated with the data transfer
531d3a8d95dSAndrei Warkentin  *	@set: cmd set values
532d3a8d95dSAndrei Warkentin  *	@index: EXT_CSD register index
533d3a8d95dSAndrei Warkentin  *	@value: value to program into EXT_CSD register
534d3a8d95dSAndrei Warkentin  *	@timeout_ms: timeout (ms) for operation performed by register write,
535d3a8d95dSAndrei Warkentin  *                   timeout of zero implies maximum possible timeout
536950d56acSJaehoon Chung  *	@use_busy_signal: use the busy signal as response type
537878e200bSUlf Hansson  *	@send_status: send status cmd to poll for busy
5384509f847SUlf Hansson  *	@ignore_crc: ignore CRC errors when sending status cmd to poll for busy
539d3a8d95dSAndrei Warkentin  *
540d3a8d95dSAndrei Warkentin  *	Modifies the EXT_CSD register for selected card.
541d3a8d95dSAndrei Warkentin  */
542950d56acSJaehoon Chung int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
5434509f847SUlf Hansson 		unsigned int timeout_ms, bool use_busy_signal, bool send_status,
5444509f847SUlf Hansson 		bool ignore_crc)
545da7fbe58SPierre Ossman {
546636bd13cSUlf Hansson 	struct mmc_host *host = card->host;
547da7fbe58SPierre Ossman 	int err;
5481278dba1SChris Ball 	struct mmc_command cmd = {0};
549b9ec2616SUlf Hansson 	bool use_r1b_resp = use_busy_signal;
550b9ec2616SUlf Hansson 
551c6dbab9cSAdrian Hunter 	mmc_retune_hold(host);
552c6dbab9cSAdrian Hunter 
553b9ec2616SUlf Hansson 	/*
554b9ec2616SUlf Hansson 	 * If the cmd timeout and the max_busy_timeout of the host are both
555b9ec2616SUlf Hansson 	 * specified, let's validate them. A failure means we need to prevent
556b9ec2616SUlf Hansson 	 * the host from doing hw busy detection, which is done by converting
557b9ec2616SUlf Hansson 	 * to a R1 response instead of a R1B.
558b9ec2616SUlf Hansson 	 */
559b9ec2616SUlf Hansson 	if (timeout_ms && host->max_busy_timeout &&
560b9ec2616SUlf Hansson 		(timeout_ms > host->max_busy_timeout))
561b9ec2616SUlf Hansson 		use_r1b_resp = false;
562da7fbe58SPierre Ossman 
563da7fbe58SPierre Ossman 	cmd.opcode = MMC_SWITCH;
564da7fbe58SPierre Ossman 	cmd.arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
565da7fbe58SPierre Ossman 		  (index << 16) |
566da7fbe58SPierre Ossman 		  (value << 8) |
567da7fbe58SPierre Ossman 		  set;
568950d56acSJaehoon Chung 	cmd.flags = MMC_CMD_AC;
569b9ec2616SUlf Hansson 	if (use_r1b_resp) {
570950d56acSJaehoon Chung 		cmd.flags |= MMC_RSP_SPI_R1B | MMC_RSP_R1B;
571b9ec2616SUlf Hansson 		/*
572b9ec2616SUlf Hansson 		 * A busy_timeout of zero means the host can decide to use
573b9ec2616SUlf Hansson 		 * whatever value it finds suitable.
574b9ec2616SUlf Hansson 		 */
5751d4d7744SUlf Hansson 		cmd.busy_timeout = timeout_ms;
576b9ec2616SUlf Hansson 	} else {
577b9ec2616SUlf Hansson 		cmd.flags |= MMC_RSP_SPI_R1 | MMC_RSP_R1;
578b9ec2616SUlf Hansson 	}
579b9ec2616SUlf Hansson 
580775a9362SMaya Erez 	if (index == EXT_CSD_SANITIZE_START)
581775a9362SMaya Erez 		cmd.sanitize_busy = true;
582da7fbe58SPierre Ossman 
583636bd13cSUlf Hansson 	err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES);
58417b0429dSPierre Ossman 	if (err)
585c6dbab9cSAdrian Hunter 		goto out;
586da7fbe58SPierre Ossman 
587950d56acSJaehoon Chung 	/* No need to check card status in case of unblocking command */
588950d56acSJaehoon Chung 	if (!use_busy_signal)
589c6dbab9cSAdrian Hunter 		goto out;
590950d56acSJaehoon Chung 
591cb26ce06SUlf Hansson 	/*If SPI or used HW busy detection above, then we don't need to poll. */
592cb26ce06SUlf Hansson 	if (((host->caps & MMC_CAP_WAIT_WHILE_BUSY) && use_r1b_resp) ||
593cb26ce06SUlf Hansson 		mmc_host_is_spi(host)) {
594cb26ce06SUlf Hansson 		if (send_status)
595cb26ce06SUlf Hansson 			err = mmc_switch_status(card);
596cb26ce06SUlf Hansson 		goto out;
597cb26ce06SUlf Hansson 	}
598a27fbf2fSSeungwon Jeon 
599716bdb89SUlf Hansson 	/* Let's try to poll to find out when the command is completed. */
600716bdb89SUlf Hansson 	err = mmc_poll_for_busy(card, timeout_ms, send_status, ignore_crc);
601c6dbab9cSAdrian Hunter out:
602c6dbab9cSAdrian Hunter 	mmc_retune_release(host);
603ef0b27d4SAdrian Hunter 
604c6dbab9cSAdrian Hunter 	return err;
605da7fbe58SPierre Ossman }
606950d56acSJaehoon Chung 
607950d56acSJaehoon Chung int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
608950d56acSJaehoon Chung 		unsigned int timeout_ms)
609950d56acSJaehoon Chung {
6104509f847SUlf Hansson 	return __mmc_switch(card, set, index, value, timeout_ms, true, true,
6114509f847SUlf Hansson 				false);
612950d56acSJaehoon Chung }
613d3a8d95dSAndrei Warkentin EXPORT_SYMBOL_GPL(mmc_switch);
614da7fbe58SPierre Ossman 
6159979dbe5SChaotian Jing int mmc_send_tuning(struct mmc_host *host, u32 opcode, int *cmd_error)
616996903deSMinda Chen {
617996903deSMinda Chen 	struct mmc_request mrq = {NULL};
618996903deSMinda Chen 	struct mmc_command cmd = {0};
619996903deSMinda Chen 	struct mmc_data data = {0};
620996903deSMinda Chen 	struct scatterlist sg;
621fe5afb13SUlf Hansson 	struct mmc_ios *ios = &host->ios;
622996903deSMinda Chen 	const u8 *tuning_block_pattern;
623996903deSMinda Chen 	int size, err = 0;
624996903deSMinda Chen 	u8 *data_buf;
625996903deSMinda Chen 
626996903deSMinda Chen 	if (ios->bus_width == MMC_BUS_WIDTH_8) {
627996903deSMinda Chen 		tuning_block_pattern = tuning_blk_pattern_8bit;
628996903deSMinda Chen 		size = sizeof(tuning_blk_pattern_8bit);
629996903deSMinda Chen 	} else if (ios->bus_width == MMC_BUS_WIDTH_4) {
630996903deSMinda Chen 		tuning_block_pattern = tuning_blk_pattern_4bit;
631996903deSMinda Chen 		size = sizeof(tuning_blk_pattern_4bit);
632996903deSMinda Chen 	} else
633996903deSMinda Chen 		return -EINVAL;
634996903deSMinda Chen 
635996903deSMinda Chen 	data_buf = kzalloc(size, GFP_KERNEL);
636996903deSMinda Chen 	if (!data_buf)
637996903deSMinda Chen 		return -ENOMEM;
638996903deSMinda Chen 
639996903deSMinda Chen 	mrq.cmd = &cmd;
640996903deSMinda Chen 	mrq.data = &data;
641996903deSMinda Chen 
642996903deSMinda Chen 	cmd.opcode = opcode;
643996903deSMinda Chen 	cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
644996903deSMinda Chen 
645996903deSMinda Chen 	data.blksz = size;
646996903deSMinda Chen 	data.blocks = 1;
647996903deSMinda Chen 	data.flags = MMC_DATA_READ;
648996903deSMinda Chen 
649996903deSMinda Chen 	/*
650996903deSMinda Chen 	 * According to the tuning specs, Tuning process
651996903deSMinda Chen 	 * is normally shorter 40 executions of CMD19,
652996903deSMinda Chen 	 * and timeout value should be shorter than 150 ms
653996903deSMinda Chen 	 */
654996903deSMinda Chen 	data.timeout_ns = 150 * NSEC_PER_MSEC;
655996903deSMinda Chen 
656996903deSMinda Chen 	data.sg = &sg;
657996903deSMinda Chen 	data.sg_len = 1;
658996903deSMinda Chen 	sg_init_one(&sg, data_buf, size);
659996903deSMinda Chen 
660fe5afb13SUlf Hansson 	mmc_wait_for_req(host, &mrq);
661996903deSMinda Chen 
6629979dbe5SChaotian Jing 	if (cmd_error)
6639979dbe5SChaotian Jing 		*cmd_error = cmd.error;
6649979dbe5SChaotian Jing 
665996903deSMinda Chen 	if (cmd.error) {
666996903deSMinda Chen 		err = cmd.error;
667996903deSMinda Chen 		goto out;
668996903deSMinda Chen 	}
669996903deSMinda Chen 
670996903deSMinda Chen 	if (data.error) {
671996903deSMinda Chen 		err = data.error;
672996903deSMinda Chen 		goto out;
673996903deSMinda Chen 	}
674996903deSMinda Chen 
675996903deSMinda Chen 	if (memcmp(data_buf, tuning_block_pattern, size))
676996903deSMinda Chen 		err = -EIO;
677996903deSMinda Chen 
678996903deSMinda Chen out:
679996903deSMinda Chen 	kfree(data_buf);
680996903deSMinda Chen 	return err;
681996903deSMinda Chen }
682996903deSMinda Chen EXPORT_SYMBOL_GPL(mmc_send_tuning);
683996903deSMinda Chen 
68422113efdSAries Lee static int
68522113efdSAries Lee mmc_send_bus_test(struct mmc_card *card, struct mmc_host *host, u8 opcode,
68622113efdSAries Lee 		  u8 len)
68722113efdSAries Lee {
688ad5fd972SVenkatraman S 	struct mmc_request mrq = {NULL};
6891278dba1SChris Ball 	struct mmc_command cmd = {0};
690a61ad2b4SChris Ball 	struct mmc_data data = {0};
69122113efdSAries Lee 	struct scatterlist sg;
69222113efdSAries Lee 	u8 *data_buf;
69322113efdSAries Lee 	u8 *test_buf;
69422113efdSAries Lee 	int i, err;
69522113efdSAries Lee 	static u8 testdata_8bit[8] = { 0x55, 0xaa, 0, 0, 0, 0, 0, 0 };
69622113efdSAries Lee 	static u8 testdata_4bit[4] = { 0x5a, 0, 0, 0 };
69722113efdSAries Lee 
69822113efdSAries Lee 	/* dma onto stack is unsafe/nonportable, but callers to this
69922113efdSAries Lee 	 * routine normally provide temporary on-stack buffers ...
70022113efdSAries Lee 	 */
70122113efdSAries Lee 	data_buf = kmalloc(len, GFP_KERNEL);
70222113efdSAries Lee 	if (!data_buf)
70322113efdSAries Lee 		return -ENOMEM;
70422113efdSAries Lee 
70522113efdSAries Lee 	if (len == 8)
70622113efdSAries Lee 		test_buf = testdata_8bit;
70722113efdSAries Lee 	else if (len == 4)
70822113efdSAries Lee 		test_buf = testdata_4bit;
70922113efdSAries Lee 	else {
710a3c76eb9SGirish K S 		pr_err("%s: Invalid bus_width %d\n",
71122113efdSAries Lee 		       mmc_hostname(host), len);
71222113efdSAries Lee 		kfree(data_buf);
71322113efdSAries Lee 		return -EINVAL;
71422113efdSAries Lee 	}
71522113efdSAries Lee 
71622113efdSAries Lee 	if (opcode == MMC_BUS_TEST_W)
71722113efdSAries Lee 		memcpy(data_buf, test_buf, len);
71822113efdSAries Lee 
71922113efdSAries Lee 	mrq.cmd = &cmd;
72022113efdSAries Lee 	mrq.data = &data;
72122113efdSAries Lee 	cmd.opcode = opcode;
72222113efdSAries Lee 	cmd.arg = 0;
72322113efdSAries Lee 
72422113efdSAries Lee 	/* NOTE HACK:  the MMC_RSP_SPI_R1 is always correct here, but we
72522113efdSAries Lee 	 * rely on callers to never use this with "native" calls for reading
72622113efdSAries Lee 	 * CSD or CID.  Native versions of those commands use the R2 type,
72722113efdSAries Lee 	 * not R1 plus a data block.
72822113efdSAries Lee 	 */
72922113efdSAries Lee 	cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;
73022113efdSAries Lee 
73122113efdSAries Lee 	data.blksz = len;
73222113efdSAries Lee 	data.blocks = 1;
73322113efdSAries Lee 	if (opcode == MMC_BUS_TEST_R)
73422113efdSAries Lee 		data.flags = MMC_DATA_READ;
73522113efdSAries Lee 	else
73622113efdSAries Lee 		data.flags = MMC_DATA_WRITE;
73722113efdSAries Lee 
73822113efdSAries Lee 	data.sg = &sg;
73922113efdSAries Lee 	data.sg_len = 1;
74084532e33SMinjian Wu 	mmc_set_data_timeout(&data, card);
74122113efdSAries Lee 	sg_init_one(&sg, data_buf, len);
74222113efdSAries Lee 	mmc_wait_for_req(host, &mrq);
74322113efdSAries Lee 	err = 0;
74422113efdSAries Lee 	if (opcode == MMC_BUS_TEST_R) {
74522113efdSAries Lee 		for (i = 0; i < len / 4; i++)
74622113efdSAries Lee 			if ((test_buf[i] ^ data_buf[i]) != 0xff) {
74722113efdSAries Lee 				err = -EIO;
74822113efdSAries Lee 				break;
74922113efdSAries Lee 			}
75022113efdSAries Lee 	}
75122113efdSAries Lee 	kfree(data_buf);
75222113efdSAries Lee 
75322113efdSAries Lee 	if (cmd.error)
75422113efdSAries Lee 		return cmd.error;
75522113efdSAries Lee 	if (data.error)
75622113efdSAries Lee 		return data.error;
75722113efdSAries Lee 
75822113efdSAries Lee 	return err;
75922113efdSAries Lee }
76022113efdSAries Lee 
76122113efdSAries Lee int mmc_bus_test(struct mmc_card *card, u8 bus_width)
76222113efdSAries Lee {
7630899e741SMasahiro Yamada 	int width;
76422113efdSAries Lee 
76522113efdSAries Lee 	if (bus_width == MMC_BUS_WIDTH_8)
76622113efdSAries Lee 		width = 8;
76722113efdSAries Lee 	else if (bus_width == MMC_BUS_WIDTH_4)
76822113efdSAries Lee 		width = 4;
76922113efdSAries Lee 	else if (bus_width == MMC_BUS_WIDTH_1)
77022113efdSAries Lee 		return 0; /* no need for test */
77122113efdSAries Lee 	else
77222113efdSAries Lee 		return -EINVAL;
77322113efdSAries Lee 
77422113efdSAries Lee 	/*
77522113efdSAries Lee 	 * Ignore errors from BUS_TEST_W.  BUS_TEST_R will fail if there
77622113efdSAries Lee 	 * is a problem.  This improves chances that the test will work.
77722113efdSAries Lee 	 */
77822113efdSAries Lee 	mmc_send_bus_test(card, card->host, MMC_BUS_TEST_W, width);
7790899e741SMasahiro Yamada 	return mmc_send_bus_test(card, card->host, MMC_BUS_TEST_R, width);
78022113efdSAries Lee }
781eb0d8f13SJaehoon Chung 
782eb0d8f13SJaehoon Chung int mmc_send_hpi_cmd(struct mmc_card *card, u32 *status)
783eb0d8f13SJaehoon Chung {
784eb0d8f13SJaehoon Chung 	struct mmc_command cmd = {0};
785eb0d8f13SJaehoon Chung 	unsigned int opcode;
786eb0d8f13SJaehoon Chung 	int err;
787eb0d8f13SJaehoon Chung 
7882378975bSJaehoon Chung 	if (!card->ext_csd.hpi) {
7896606110dSJoe Perches 		pr_warn("%s: Card didn't support HPI command\n",
7902378975bSJaehoon Chung 			mmc_hostname(card->host));
7912378975bSJaehoon Chung 		return -EINVAL;
7922378975bSJaehoon Chung 	}
7932378975bSJaehoon Chung 
794eb0d8f13SJaehoon Chung 	opcode = card->ext_csd.hpi_cmd;
795eb0d8f13SJaehoon Chung 	if (opcode == MMC_STOP_TRANSMISSION)
7962378975bSJaehoon Chung 		cmd.flags = MMC_RSP_R1B | MMC_CMD_AC;
797eb0d8f13SJaehoon Chung 	else if (opcode == MMC_SEND_STATUS)
7982378975bSJaehoon Chung 		cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
799eb0d8f13SJaehoon Chung 
800eb0d8f13SJaehoon Chung 	cmd.opcode = opcode;
801eb0d8f13SJaehoon Chung 	cmd.arg = card->rca << 16 | 1;
802eb0d8f13SJaehoon Chung 
803eb0d8f13SJaehoon Chung 	err = mmc_wait_for_cmd(card->host, &cmd, 0);
804eb0d8f13SJaehoon Chung 	if (err) {
805eb0d8f13SJaehoon Chung 		pr_warn("%s: error %d interrupting operation. "
806eb0d8f13SJaehoon Chung 			"HPI command response %#x\n", mmc_hostname(card->host),
807eb0d8f13SJaehoon Chung 			err, cmd.resp[0]);
808eb0d8f13SJaehoon Chung 		return err;
809eb0d8f13SJaehoon Chung 	}
810eb0d8f13SJaehoon Chung 	if (status)
811eb0d8f13SJaehoon Chung 		*status = cmd.resp[0];
812eb0d8f13SJaehoon Chung 
813eb0d8f13SJaehoon Chung 	return 0;
814eb0d8f13SJaehoon Chung }
815148bcab2SUlf Hansson 
816148bcab2SUlf Hansson int mmc_can_ext_csd(struct mmc_card *card)
817148bcab2SUlf Hansson {
818148bcab2SUlf Hansson 	return (card && card->csd.mmca_vsn > CSD_SPEC_VER_3);
819148bcab2SUlf Hansson }
820