blob: bd23b7f70c08c4eb32300e5ee649600541254adf [file] [log] [blame]
Lee Leahyeef40eb2017-03-23 10:54:57 -07001/*
2 * Copyright 2008, Freescale Semiconductor, Inc
3 * Andy Fleming
4 *
5 * Copyright 2013 Google Inc. All rights reserved.
6 * Copyright 2017 Intel Corporation
7 *
8 * Secure Digital (SD) card specific support code
9 * This code is controller independent
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License as
13 * published by the Free Software Foundation; either version 2 of
14 * the License, or (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 */
21
22#include <assert.h>
Lee Leahy48dbc662017-05-08 16:56:03 -070023#include <commonlib/sd_mmc_ctrlr.h>
24#include <commonlib/storage.h>
Lee Leahyeef40eb2017-03-23 10:54:57 -070025#include <delay.h>
Lee Leahyeef40eb2017-03-23 10:54:57 -070026#include <endian.h>
27#include "sd_mmc.h"
28#include "storage.h"
29#include <string.h>
30#include <timer.h>
31
32int sd_send_if_cond(struct storage_media *media)
33{
34 struct mmc_command cmd;
35 struct sd_mmc_ctrlr *ctrlr = media->ctrlr;
36
37 cmd.cmdidx = SD_CMD_SEND_IF_COND;
38 /* Set if controller supports voltages between 2.7 and 3.6 V. */
39 cmd.cmdarg = ((ctrlr->voltages & 0xff8000) != 0) << 8 | 0xaa;
40 cmd.resp_type = CARD_RSP_R7;
41 cmd.flags = 0;
42 int err = ctrlr->send_cmd(ctrlr, &cmd, NULL);
43 if (err)
44 return err;
45
46 if ((cmd.response[0] & 0xff) != 0xaa)
47 return CARD_UNUSABLE_ERR;
48 media->version = SD_VERSION_2;
49 return 0;
50}
51
52int sd_send_op_cond(struct storage_media *media)
53{
54 int err;
55 struct mmc_command cmd;
56 struct sd_mmc_ctrlr *ctrlr = media->ctrlr;
57
58 int tries = SD_MMC_IO_RETRIES;
59 while (tries--) {
60 cmd.cmdidx = MMC_CMD_APP_CMD;
61 cmd.resp_type = CARD_RSP_R1;
62 cmd.cmdarg = 0;
63 cmd.flags = 0;
64
65 err = ctrlr->send_cmd(ctrlr, &cmd, NULL);
66 if (err)
67 return err;
68
69 cmd.cmdidx = SD_CMD_APP_SEND_OP_COND;
70 cmd.resp_type = CARD_RSP_R3;
71
72 /*
73 * Most cards do not answer if some reserved bits
74 * in the ocr are set. However, Some controller
75 * can set bit 7 (reserved for low voltages), but
76 * how to manage low voltages SD card is not yet
77 * specified.
78 */
79 cmd.cmdarg = (ctrlr->voltages & 0xff8000);
80
81 if (media->version == SD_VERSION_2)
82 cmd.cmdarg |= OCR_HCS;
83
84 err = ctrlr->send_cmd(ctrlr, &cmd, NULL);
85 if (err)
86 return err;
87
88 // OCR_BUSY means "initialization complete".
89 if (cmd.response[0] & OCR_BUSY)
90 break;
91
92 udelay(100);
93 }
94 if (tries < 0)
95 return CARD_UNUSABLE_ERR;
96
97 if (media->version != SD_VERSION_2)
98 media->version = SD_VERSION_1_0;
99
100 media->ocr = cmd.response[0];
101 media->high_capacity = ((media->ocr & OCR_HCS) == OCR_HCS);
102 media->rca = 0;
103 return 0;
104}
105
106static int sd_switch(struct sd_mmc_ctrlr *ctrlr, int mode, int group,
107 uint8_t value, uint8_t *resp)
108{
109 /* Switch the frequency */
110 struct mmc_command cmd;
111 cmd.cmdidx = SD_CMD_SWITCH_FUNC;
112 cmd.resp_type = CARD_RSP_R1;
113 cmd.cmdarg = (mode << 31) | (0xffffff & ~(0xf << (group * 4))) |
114 (value << (group * 4));
115 cmd.flags = 0;
116
117 struct mmc_data data;
118 data.dest = (char *)resp;
119 data.blocksize = 64;
120 data.blocks = 1;
121 data.flags = DATA_FLAG_READ;
122
123 return ctrlr->send_cmd(ctrlr, &cmd, &data);
124}
125
126static void sd_recalculate_clock(struct storage_media *media)
127{
128 uint32_t clock = 1;
129
130 if (media->caps & DRVR_CAP_HS)
131 clock = CLOCK_50MHZ;
132 else
133 clock = CLOCK_25MHZ;
134 SET_CLOCK(media->ctrlr, clock);
135}
136
137int sd_change_freq(struct storage_media *media)
138{
Lee Leahyf542aca2017-05-11 14:51:25 -0700139 int delay;
Lee Leahyeef40eb2017-03-23 10:54:57 -0700140 int err, timeout;
141 struct mmc_command cmd;
142 struct sd_mmc_ctrlr *ctrlr = media->ctrlr;
143 struct mmc_data data;
144 ALLOC_CACHE_ALIGN_BUFFER(uint32_t, scr, 2);
145 ALLOC_CACHE_ALIGN_BUFFER(uint32_t, switch_status, 16);
146
147 media->caps = 0;
148
149 /* Read the SCR to find out if this card supports higher speeds */
150 cmd.cmdidx = MMC_CMD_APP_CMD;
151 cmd.resp_type = CARD_RSP_R1;
152 cmd.cmdarg = media->rca << 16;
153 cmd.flags = 0;
154
155 err = ctrlr->send_cmd(ctrlr, &cmd, NULL);
156 if (err)
157 return err;
158
159 cmd.cmdidx = SD_CMD_APP_SEND_SCR;
160 cmd.resp_type = CARD_RSP_R1;
161 cmd.cmdarg = 0;
162 cmd.flags = 0;
163
164 timeout = 3;
165 while (timeout--) {
166 data.dest = (char *)scr;
167 data.blocksize = 8;
168 data.blocks = 1;
169 data.flags = DATA_FLAG_READ;
170 err = ctrlr->send_cmd(ctrlr, &cmd, &data);
171 if (!err)
172 break;
173 }
174 if (err) {
175 sd_mmc_error("%s returning %d\n", __func__, err);
176 return err;
177 }
178
179 media->scr[0] = be32toh(scr[0]);
180 media->scr[1] = be32toh(scr[1]);
181
182 switch ((media->scr[0] >> 24) & 0xf) {
183 case 0:
184 media->version = SD_VERSION_1_0;
185 break;
186 case 1:
187 media->version = SD_VERSION_1_10;
188 break;
189 case 2:
190 media->version = SD_VERSION_2;
191 break;
192 default:
193 media->version = SD_VERSION_1_0;
194 break;
195 }
196
197 if (media->scr[0] & SD_DATA_4BIT)
198 media->caps |= DRVR_CAP_4BIT;
199
200 /* Version 1.0 doesn't support switching */
201 if (media->version == SD_VERSION_1_0)
202 goto out;
203
204 timeout = 4;
205 while (timeout--) {
206 err = sd_switch(ctrlr, SD_SWITCH_CHECK, 0, 1,
207 (uint8_t *)switch_status);
208 if (err)
209 return err;
210
211 /* The high-speed function is busy. Try again */
212 if (!(ntohl(switch_status[7]) & SD_HIGHSPEED_BUSY))
213 break;
214 }
215
216 /* If high-speed isn't supported, we return */
217 if (!(ntohl(switch_status[3]) & SD_HIGHSPEED_SUPPORTED))
218 goto out;
219
220 /*
221 * If the controller doesn't support SD_HIGHSPEED, do not switch the
222 * card to HIGHSPEED mode even if the card support SD_HIGHSPPED.
223 * This can avoid a further problem when the card runs in different
224 * mode than the controller.
225 */
226 if (!((ctrlr->caps & DRVR_CAP_HS52) && (ctrlr->caps & DRVR_CAP_HS)))
227 goto out;
228
Lee Leahyf542aca2017-05-11 14:51:25 -0700229 /* Give the card time to recover afer the switch operation. Wait for
230 * 9 (>= 8) clock cycles receiving the switch status.
231 */
232 delay = (9000000 + ctrlr->bus_hz - 1) / ctrlr->bus_hz;
233 udelay(delay);
234
235 /* Switch to high speed */
Lee Leahyeef40eb2017-03-23 10:54:57 -0700236 err = sd_switch(ctrlr, SD_SWITCH_SWITCH, 0, 1,
237 (uint8_t *)switch_status);
238 if (err)
239 return err;
240
Lee Leahyf542aca2017-05-11 14:51:25 -0700241 /* Give the card time to perform the switch operation. Wait for 9
242 * (>= 8) clock cycles receiving the switch status.
243 */
244 udelay(delay);
245
Lee Leahyeef40eb2017-03-23 10:54:57 -0700246 if ((ntohl(switch_status[4]) & 0x0f000000) == 0x01000000) {
247 media->caps |= DRVR_CAP_HS;
248 SET_TIMING(ctrlr, BUS_TIMING_SD_HS);
249 }
250
251out:
252 sd_recalculate_clock(media);
253 return 0;
254}
255
256int sd_set_bus_width(struct storage_media *media)
257{
258 int err;
259 struct mmc_command cmd;
260 struct sd_mmc_ctrlr *ctrlr = media->ctrlr;
261
262 if (media->caps & DRVR_CAP_4BIT) {
263 cmd.cmdidx = MMC_CMD_APP_CMD;
264 cmd.resp_type = CARD_RSP_R1;
265 cmd.cmdarg = media->rca << 16;
266 cmd.flags = 0;
267
268 err = ctrlr->send_cmd(ctrlr, &cmd, NULL);
269 if (err)
270 return err;
271
272 cmd.cmdidx = SD_CMD_APP_SET_BUS_WIDTH;
273 cmd.resp_type = CARD_RSP_R1;
274 cmd.cmdarg = 2;
275 cmd.flags = 0;
276 err = ctrlr->send_cmd(ctrlr, &cmd, NULL);
277 if (err)
278 return err;
279
280 SET_BUS_WIDTH(ctrlr, 4);
281 }
282 return 0;
283}
284
285
286int sd_set_partition(struct storage_media *media,
287 unsigned int partition_number)
288{
289 /* Validate the partition number */
290 if (partition_number)
291 return -1;
292
293 /* Update the partition number */
294 media->partition_config = partition_number;
295 return 0;
296}
297
298const char *sd_partition_name(struct storage_media *media,
299 unsigned int partition_number)
300{
301 return "";
302}