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