blob: c5fa76c730b6c490496fd2a42ee9111470b775c7 [file] [log] [blame]
Lee Leahyeef40eb2017-03-23 10:54:57 -07001/*
Martin Roth0443ac22019-08-30 21:29:41 -06002 * This file is part of the coreboot project.
Lee Leahyeef40eb2017-03-23 10:54:57 -07003 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of
7 * the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
Martin Roth0443ac22019-08-30 21:29:41 -060013 *
14 * MultiMediaCard (MMC), eMMC and Secure Digital (SD) common initialization
15 * code which brings the card into the standby state. This code is controller
16 * independent.
Lee Leahyeef40eb2017-03-23 10:54:57 -070017 */
18
Lee Leahy48dbc662017-05-08 16:56:03 -070019#include <commonlib/storage.h>
Lee Leahyeef40eb2017-03-23 10:54:57 -070020#include <delay.h>
Lee Leahyeef40eb2017-03-23 10:54:57 -070021#include <endian.h>
Elyes HAOUASadd76f92019-03-21 09:55:49 +010022#include <string.h>
23
Lee Leahyeef40eb2017-03-23 10:54:57 -070024#include "mmc.h"
25#include "sd_mmc.h"
26#include "storage.h"
Lee Leahyeef40eb2017-03-23 10:54:57 -070027
28uint64_t sd_mmc_extract_uint32_bits(const uint32_t *array, int start, int count)
29{
30 int i;
31 uint64_t value = 0;
32
33 for (i = 0; i < count; i++, start++) {
34 value <<= 1;
35 value |= (array[start / 32] >> (31 - (start % 32))) & 0x1;
36 }
37 return value;
38}
39
40static uint32_t sd_mmc_calculate_transfer_speed(uint32_t csd0)
41{
42 uint32_t mult, freq;
43
44 /* frequency bases, divided by 10 to be nice to platforms without
45 * floating point */
46 static const int fbase[] = {
47 10000,
48 100000,
49 1000000,
50 10000000,
51 };
52 /* Multiplier values for TRAN_SPEED. Multiplied by 10 to be nice
53 * to platforms without floating point. */
54 static const int multipliers[] = {
55 0, // reserved
56 10,
57 12,
58 13,
59 15,
60 20,
61 25,
62 30,
63 35,
64 40,
65 45,
66 50,
67 55,
68 60,
69 70,
70 80,
71 };
72
73 /* divide frequency by 10, since the mults are 10x bigger */
74 freq = fbase[csd0 & 0x7];
75 mult = multipliers[(csd0 >> 3) & 0xf];
76 return freq * mult;
77}
78
Bora Guvendike1416fd2018-03-08 16:18:54 -080079int sd_mmc_go_idle(struct storage_media *media)
Lee Leahyeef40eb2017-03-23 10:54:57 -070080{
81 struct sd_mmc_ctrlr *ctrlr = media->ctrlr;
82
83 // Some cards can't accept idle commands without delay.
84 if (ctrlr->mdelay_before_cmd0)
85 mdelay(ctrlr->mdelay_before_cmd0);
86
87 struct mmc_command cmd;
88 cmd.cmdidx = MMC_CMD_GO_IDLE_STATE;
89 cmd.cmdarg = 0;
90 cmd.resp_type = CARD_RSP_NONE;
91 cmd.flags = 0;
92
93 int err = ctrlr->send_cmd(ctrlr, &cmd, NULL);
94 if (err)
95 return err;
96
97 // Some cards need more than half second to respond to next command (ex,
98 // SEND_OP_COND).
99 if (ctrlr->mdelay_after_cmd0)
100 mdelay(ctrlr->mdelay_after_cmd0);
101
102 return 0;
103}
104
105int sd_mmc_send_status(struct storage_media *media, ssize_t tries)
106{
107 struct mmc_command cmd;
108 struct sd_mmc_ctrlr *ctrlr = media->ctrlr;
109
110 cmd.cmdidx = MMC_CMD_SEND_STATUS;
111 cmd.resp_type = CARD_RSP_R1;
112 cmd.cmdarg = media->rca << 16;
113 cmd.flags = 0;
114
115 while (tries--) {
116 int err = ctrlr->send_cmd(ctrlr, &cmd, NULL);
117 if (err)
118 return err;
119 else if (cmd.response[0] & MMC_STATUS_RDY_FOR_DATA)
120 break;
121 else if (cmd.response[0] & MMC_STATUS_MASK) {
122 sd_mmc_error("Status Error: %#8.8x\n", cmd.response[0]);
123 return CARD_COMM_ERR;
124 }
125
126 udelay(100);
127 }
128
129 sd_mmc_trace("CURR STATE:%d\n",
130 (cmd.response[0] & MMC_STATUS_CURR_STATE) >> 9);
131
132 if (tries < 0) {
133 sd_mmc_error("Timeout waiting card ready\n");
134 return CARD_TIMEOUT;
135 }
136 return 0;
137}
138
139int sd_mmc_set_blocklen(struct sd_mmc_ctrlr *ctrlr, int len)
140{
141 struct mmc_command cmd;
142 cmd.cmdidx = MMC_CMD_SET_BLOCKLEN;
143 cmd.resp_type = CARD_RSP_R1;
144 cmd.cmdarg = len;
145 cmd.flags = 0;
146
147 return ctrlr->send_cmd(ctrlr, &cmd, NULL);
148}
149
150int sd_mmc_enter_standby(struct storage_media *media)
151{
152 struct mmc_command cmd;
153 struct sd_mmc_ctrlr *ctrlr = media->ctrlr;
154 int err;
155
156 SET_BUS_WIDTH(ctrlr, 1);
157 SET_CLOCK(ctrlr, 1);
158
159 /* Reset the Card */
160 err = sd_mmc_go_idle(media);
161 if (err)
162 return err;
163
164 /* Test for SD version 2 */
165 err = CARD_TIMEOUT;
Julius Wernercd49cce2019-03-05 16:53:33 -0800166 if (CONFIG(COMMONLIB_STORAGE_SD)) {
Lee Leahyeef40eb2017-03-23 10:54:57 -0700167 err = sd_send_if_cond(media);
168
169 /* Get SD card operating condition */
170 if (!err)
171 err = sd_send_op_cond(media);
172 }
173
174 /* If the command timed out, we check for an MMC card */
Julius Wernercd49cce2019-03-05 16:53:33 -0800175 if (CONFIG(COMMONLIB_STORAGE_MMC) && (err == CARD_TIMEOUT)) {
Lee Leahyeef40eb2017-03-23 10:54:57 -0700176 /* Some cards seem to need this */
177 sd_mmc_go_idle(media);
178
179 err = mmc_send_op_cond(media);
180 if (err == CARD_IN_PROGRESS)
181 err = mmc_complete_op_cond(media);
182 }
183
184 if (err) {
185 sd_mmc_error(
186 "Card did not respond to voltage select!\n");
187 return CARD_UNUSABLE_ERR;
188 }
189
190 /* Put the Card in Identify Mode */
191 cmd.cmdidx = MMC_CMD_ALL_SEND_CID;
192 cmd.resp_type = CARD_RSP_R2;
193 cmd.cmdarg = 0;
194 cmd.flags = 0;
195 err = ctrlr->send_cmd(ctrlr, &cmd, NULL);
196 if (err)
197 return err;
198 memcpy(media->cid, cmd.response, sizeof(media->cid));
199
200 /*
201 * For MMC cards, set the Relative Address.
Elyes HAOUASb8473d02020-01-08 15:39:34 +0100202 * For SD cards, get the Relative Address.
Lee Leahyeef40eb2017-03-23 10:54:57 -0700203 * This also puts the cards into Standby State
204 */
205 cmd.cmdidx = SD_CMD_SEND_RELATIVE_ADDR;
206 cmd.cmdarg = media->rca << 16;
207 cmd.resp_type = CARD_RSP_R6;
208 cmd.flags = 0;
209 err = ctrlr->send_cmd(ctrlr, &cmd, NULL);
210 if (err)
211 return err;
212 if (IS_SD(media))
213 media->rca = (cmd.response[0] >> 16) & 0xffff;
214
215 /* Get the Card-Specific Data */
216 cmd.cmdidx = MMC_CMD_SEND_CSD;
217 cmd.resp_type = CARD_RSP_R2;
218 cmd.cmdarg = media->rca << 16;
219 cmd.flags = 0;
220 err = ctrlr->send_cmd(ctrlr, &cmd, NULL);
221
222 /* Waiting for the ready status */
223 sd_mmc_send_status(media, SD_MMC_IO_RETRIES);
224 if (err)
225 return err;
226
227 memcpy(media->csd, cmd.response, sizeof(media->csd));
228 if (media->version == MMC_VERSION_UNKNOWN) {
229 int version = sd_mmc_extract_uint32_bits(media->csd, 2, 4);
230 switch (version) {
231 case 0:
232 media->version = MMC_VERSION_1_2;
233 break;
234 case 1:
235 media->version = MMC_VERSION_1_4;
236 break;
237 case 2:
238 media->version = MMC_VERSION_2_2;
239 break;
240 case 3:
241 media->version = MMC_VERSION_3;
242 break;
243 case 4:
244 media->version = MMC_VERSION_4;
245 break;
246 default:
247 media->version = MMC_VERSION_1_2;
248 break;
249 }
250 }
251 media->tran_speed = sd_mmc_calculate_transfer_speed(media->csd[0]);
252
253 /* Determine the read and write block lengths */
254 media->read_bl_len = 1 << sd_mmc_extract_uint32_bits(media->csd, 44, 4);
255 if (IS_SD(media))
256 media->write_bl_len = media->read_bl_len;
257 else
258 media->write_bl_len =
259 1 << sd_mmc_extract_uint32_bits(media->csd, 102, 4);
260
261 sd_mmc_debug("mmc media info: version=%#x, tran_speed=%d\n",
262 media->version, (int)media->tran_speed);
263
264 return 0;
265}