xref: /openbmc/linux/drivers/mmc/core/sd_ops.c (revision 64c70b1c)
1 /*
2  *  linux/drivers/mmc/sd_ops.h
3  *
4  *  Copyright 2006-2007 Pierre Ossman
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or (at
9  * your option) any later version.
10  */
11 
12 #include <linux/types.h>
13 #include <asm/scatterlist.h>
14 #include <linux/scatterlist.h>
15 
16 #include <linux/mmc/host.h>
17 #include <linux/mmc/card.h>
18 #include <linux/mmc/mmc.h>
19 #include <linux/mmc/sd.h>
20 
21 #include "core.h"
22 #include "sd_ops.h"
23 
24 /**
25  *	mmc_wait_for_app_cmd - start an application command and wait for
26  			       completion
27  *	@host: MMC host to start command
28  *	@rca: RCA to send MMC_APP_CMD to
29  *	@cmd: MMC command to start
30  *	@retries: maximum number of retries
31  *
32  *	Sends a MMC_APP_CMD, checks the card response, sends the command
33  *	in the parameter and waits for it to complete. Return any error
34  *	that occurred while the command was executing.  Do not attempt to
35  *	parse the response.
36  */
37 int mmc_wait_for_app_cmd(struct mmc_host *host, struct mmc_card *card,
38 	struct mmc_command *cmd, int retries)
39 {
40 	struct mmc_request mrq;
41 
42 	int i, err;
43 
44 	BUG_ON(!cmd);
45 	BUG_ON(retries < 0);
46 
47 	err = MMC_ERR_INVALID;
48 
49 	/*
50 	 * We have to resend MMC_APP_CMD for each attempt so
51 	 * we cannot use the retries field in mmc_command.
52 	 */
53 	for (i = 0;i <= retries;i++) {
54 		memset(&mrq, 0, sizeof(struct mmc_request));
55 
56 		err = mmc_app_cmd(host, card);
57 		if (err != MMC_ERR_NONE)
58 			continue;
59 
60 		memset(&mrq, 0, sizeof(struct mmc_request));
61 
62 		memset(cmd->resp, 0, sizeof(cmd->resp));
63 		cmd->retries = 0;
64 
65 		mrq.cmd = cmd;
66 		cmd->data = NULL;
67 
68 		mmc_wait_for_req(host, &mrq);
69 
70 		err = cmd->error;
71 		if (cmd->error == MMC_ERR_NONE)
72 			break;
73 	}
74 
75 	return err;
76 }
77 
78 EXPORT_SYMBOL(mmc_wait_for_app_cmd);
79 
80 int mmc_app_cmd(struct mmc_host *host, struct mmc_card *card)
81 {
82 	int err;
83 	struct mmc_command cmd;
84 
85 	BUG_ON(!host);
86 	BUG_ON(card && (card->host != host));
87 
88 	cmd.opcode = MMC_APP_CMD;
89 
90 	if (card) {
91 		cmd.arg = card->rca << 16;
92 		cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
93 	} else {
94 		cmd.arg = 0;
95 		cmd.flags = MMC_RSP_R1 | MMC_CMD_BCR;
96 	}
97 
98 	err = mmc_wait_for_cmd(host, &cmd, 0);
99 	if (err != MMC_ERR_NONE)
100 		return err;
101 
102 	/* Check that card supported application commands */
103 	if (!(cmd.resp[0] & R1_APP_CMD))
104 		return MMC_ERR_FAILED;
105 
106 	return MMC_ERR_NONE;
107 }
108 
109 int mmc_app_set_bus_width(struct mmc_card *card, int width)
110 {
111 	int err;
112 	struct mmc_command cmd;
113 
114 	BUG_ON(!card);
115 	BUG_ON(!card->host);
116 
117 	memset(&cmd, 0, sizeof(struct mmc_command));
118 
119 	cmd.opcode = SD_APP_SET_BUS_WIDTH;
120 	cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
121 
122 	switch (width) {
123 	case MMC_BUS_WIDTH_1:
124 		cmd.arg = SD_BUS_WIDTH_1;
125 		break;
126 	case MMC_BUS_WIDTH_4:
127 		cmd.arg = SD_BUS_WIDTH_4;
128 		break;
129 	default:
130 		return MMC_ERR_INVALID;
131 	}
132 
133 	err = mmc_wait_for_app_cmd(card->host, card, &cmd, MMC_CMD_RETRIES);
134 	if (err != MMC_ERR_NONE)
135 		return err;
136 
137 	return MMC_ERR_NONE;
138 }
139 
140 int mmc_send_app_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr)
141 {
142 	struct mmc_command cmd;
143 	int i, err = 0;
144 
145 	BUG_ON(!host);
146 
147 	memset(&cmd, 0, sizeof(struct mmc_command));
148 
149 	cmd.opcode = SD_APP_OP_COND;
150 	cmd.arg = ocr;
151 	cmd.flags = MMC_RSP_R3 | MMC_CMD_BCR;
152 
153 	for (i = 100; i; i--) {
154 		err = mmc_wait_for_app_cmd(host, NULL, &cmd, MMC_CMD_RETRIES);
155 		if (err != MMC_ERR_NONE)
156 			break;
157 
158 		if (cmd.resp[0] & MMC_CARD_BUSY || ocr == 0)
159 			break;
160 
161 		err = MMC_ERR_TIMEOUT;
162 
163 		mmc_delay(10);
164 	}
165 
166 	if (rocr)
167 		*rocr = cmd.resp[0];
168 
169 	return err;
170 }
171 
172 int mmc_send_if_cond(struct mmc_host *host, u32 ocr)
173 {
174 	struct mmc_command cmd;
175 	int err;
176 	static const u8 test_pattern = 0xAA;
177 
178 	/*
179 	 * To support SD 2.0 cards, we must always invoke SD_SEND_IF_COND
180 	 * before SD_APP_OP_COND. This command will harmlessly fail for
181 	 * SD 1.0 cards.
182 	 */
183 	cmd.opcode = SD_SEND_IF_COND;
184 	cmd.arg = ((ocr & 0xFF8000) != 0) << 8 | test_pattern;
185 	cmd.flags = MMC_RSP_R7 | MMC_CMD_BCR;
186 
187 	err = mmc_wait_for_cmd(host, &cmd, 0);
188 	if (err != MMC_ERR_NONE)
189 		return err;
190 
191 	if ((cmd.resp[0] & 0xFF) != test_pattern)
192 		return MMC_ERR_FAILED;
193 
194 	return MMC_ERR_NONE;
195 }
196 
197 int mmc_send_relative_addr(struct mmc_host *host, unsigned int *rca)
198 {
199 	int err;
200 	struct mmc_command cmd;
201 
202 	BUG_ON(!host);
203 	BUG_ON(!rca);
204 
205 	memset(&cmd, 0, sizeof(struct mmc_command));
206 
207 	cmd.opcode = SD_SEND_RELATIVE_ADDR;
208 	cmd.arg = 0;
209 	cmd.flags = MMC_RSP_R6 | MMC_CMD_BCR;
210 
211 	err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES);
212 	if (err != MMC_ERR_NONE)
213 		return err;
214 
215 	*rca = cmd.resp[0] >> 16;
216 
217 	return MMC_ERR_NONE;
218 }
219 
220 int mmc_app_send_scr(struct mmc_card *card, u32 *scr)
221 {
222 	int err;
223 	struct mmc_request mrq;
224 	struct mmc_command cmd;
225 	struct mmc_data data;
226 	struct scatterlist sg;
227 
228 	BUG_ON(!card);
229 	BUG_ON(!card->host);
230 	BUG_ON(!scr);
231 
232 	err = mmc_app_cmd(card->host, card);
233 	if (err != MMC_ERR_NONE)
234 		return err;
235 
236 	memset(&mrq, 0, sizeof(struct mmc_request));
237 	memset(&cmd, 0, sizeof(struct mmc_command));
238 	memset(&data, 0, sizeof(struct mmc_data));
239 
240 	mrq.cmd = &cmd;
241 	mrq.data = &data;
242 
243 	cmd.opcode = SD_APP_SEND_SCR;
244 	cmd.arg = 0;
245 	cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
246 
247 	data.blksz = 8;
248 	data.blocks = 1;
249 	data.flags = MMC_DATA_READ;
250 	data.sg = &sg;
251 	data.sg_len = 1;
252 
253 	sg_init_one(&sg, scr, 8);
254 
255 	mmc_set_data_timeout(&data, card, 0);
256 
257 	mmc_wait_for_req(card->host, &mrq);
258 
259 	if (cmd.error != MMC_ERR_NONE)
260 		return cmd.error;
261 	if (data.error != MMC_ERR_NONE)
262 		return data.error;
263 
264 	scr[0] = ntohl(scr[0]);
265 	scr[1] = ntohl(scr[1]);
266 
267 	return MMC_ERR_NONE;
268 }
269 
270 int mmc_sd_switch(struct mmc_card *card, int mode, int group,
271 	u8 value, u8 *resp)
272 {
273 	struct mmc_request mrq;
274 	struct mmc_command cmd;
275 	struct mmc_data data;
276 	struct scatterlist sg;
277 
278 	BUG_ON(!card);
279 	BUG_ON(!card->host);
280 
281 	mode = !!mode;
282 	value &= 0xF;
283 
284 	memset(&mrq, 0, sizeof(struct mmc_request));
285 	memset(&cmd, 0, sizeof(struct mmc_command));
286 	memset(&data, 0, sizeof(struct mmc_data));
287 
288 	mrq.cmd = &cmd;
289 	mrq.data = &data;
290 
291 	cmd.opcode = SD_SWITCH;
292 	cmd.arg = mode << 31 | 0x00FFFFFF;
293 	cmd.arg &= ~(0xF << (group * 4));
294 	cmd.arg |= value << (group * 4);
295 	cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
296 
297 	data.blksz = 64;
298 	data.blocks = 1;
299 	data.flags = MMC_DATA_READ;
300 	data.sg = &sg;
301 	data.sg_len = 1;
302 
303 	sg_init_one(&sg, resp, 64);
304 
305 	mmc_set_data_timeout(&data, card, 0);
306 
307 	mmc_wait_for_req(card->host, &mrq);
308 
309 	if (cmd.error != MMC_ERR_NONE)
310 		return cmd.error;
311 	if (data.error != MMC_ERR_NONE)
312 		return data.error;
313 
314 	return MMC_ERR_NONE;
315 }
316 
317