xref: /aosp_15_r20/external/coreboot/src/commonlib/storage/storage.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /*
3  * MultiMediaCard (MMC), eMMC and Secure Digital (SD) common code which
4  * transitions the card from the standby state to the transfer state.  The
5  * common code supports read operations, erase and write operations are in
6  * a separate modules.  This code is controller independent.
7  */
8 
9 #include <commonlib/storage.h>
10 #include "sd_mmc.h"
11 #include "storage.h"
12 #include <string.h>
13 
14 #define DECIMAL_CAPACITY_MULTIPLIER	1000ULL
15 #define HEX_CAPACITY_MULTIPLIER		1024ULL
16 
17 struct capacity {
18 	const char *const units;
19 	uint64_t bytes;
20 };
21 
display_capacity(struct storage_media * media,int partition_number)22 static void display_capacity(struct storage_media *media, int partition_number)
23 {
24 	uint64_t capacity;
25 	uint64_t decimal_divisor;
26 	const char *decimal_units;
27 	uint64_t hex_divisor;
28 	const char *hex_units;
29 	int index;
30 	const char *name;
31 	const char *separator;
32 	const struct capacity decimal_list[] = {
33 		{"TB", DECIMAL_CAPACITY_MULTIPLIER * DECIMAL_CAPACITY_MULTIPLIER
34 			* DECIMAL_CAPACITY_MULTIPLIER
35 			* DECIMAL_CAPACITY_MULTIPLIER},
36 		{"GB", DECIMAL_CAPACITY_MULTIPLIER * DECIMAL_CAPACITY_MULTIPLIER
37 			* DECIMAL_CAPACITY_MULTIPLIER},
38 		{"MB", DECIMAL_CAPACITY_MULTIPLIER
39 			* DECIMAL_CAPACITY_MULTIPLIER},
40 		{"KB", DECIMAL_CAPACITY_MULTIPLIER},
41 		{"B", 1}
42 	};
43 	const struct capacity hex_list[] = {
44 		{"TiB", HEX_CAPACITY_MULTIPLIER * HEX_CAPACITY_MULTIPLIER
45 			* HEX_CAPACITY_MULTIPLIER * HEX_CAPACITY_MULTIPLIER},
46 		{"GiB", HEX_CAPACITY_MULTIPLIER * HEX_CAPACITY_MULTIPLIER
47 			* HEX_CAPACITY_MULTIPLIER},
48 		{"MiB", HEX_CAPACITY_MULTIPLIER * HEX_CAPACITY_MULTIPLIER},
49 		{"KiB", HEX_CAPACITY_MULTIPLIER},
50 		{"B", 1}
51 	};
52 
53 	/* Get the partition name */
54 	capacity = media->capacity[partition_number];
55 	name = storage_partition_name(media, partition_number);
56 	separator = "";
57 	if (CONFIG(COMMONLIB_STORAGE_MMC) && !IS_SD(media))
58 		separator = ": ";
59 
60 	/* Determine the decimal divisor for the capacity */
61 	for (index = 0; index < ARRAY_SIZE(decimal_list) - 1; index++) {
62 		if (capacity >= decimal_list[index].bytes)
63 			break;
64 	}
65 	decimal_divisor = decimal_list[index].bytes;
66 	decimal_units = decimal_list[index].units;
67 
68 	/* Determine the hex divisor for the capacity */
69 	for (index = 0; index < ARRAY_SIZE(hex_list) - 1; index++) {
70 		if (capacity >= hex_list[index].bytes)
71 			break;
72 	}
73 	hex_divisor = hex_list[index].bytes;
74 	hex_units = hex_list[index].units;
75 
76 	/* Display the capacity */
77 	sdhc_debug("%3lld.%03lld %sytes (%3lld.%03lld %sytes)%s%s\n",
78 		capacity / decimal_divisor,
79 		(capacity / (decimal_divisor / 1000)) % 1000,
80 		decimal_units,
81 		capacity / hex_divisor,
82 		((capacity / (hex_divisor / 1024)) * 1000 / 1024) % 1000,
83 		hex_units,
84 		separator,
85 		name);
86 }
87 
storage_display_setup(struct storage_media * media)88 void storage_display_setup(struct storage_media *media)
89 {
90 	int partition_number;
91 
92 	/* Display the device info */
93 	sd_mmc_debug("Man %06x Snr %u ",
94 	       media->cid[0] >> 24,
95 	       (((media->cid[2] & 0xffff) << 16) |
96 		((media->cid[3] >> 16) & 0xffff)));
97 	sd_mmc_debug("Product %c%c%c%c", media->cid[0] & 0xff,
98 	       (media->cid[1] >> 24), (media->cid[1] >> 16) & 0xff,
99 	       (media->cid[1] >> 8) & 0xff);
100 	if (!IS_SD(media)) /* eMMC product string is longer */
101 		sd_mmc_debug("%c%c", media->cid[1] & 0xff,
102 		       (media->cid[2] >> 24) & 0xff);
103 	sd_mmc_debug(" Revision %d.%d\n", (media->cid[2] >> 20) & 0xf,
104 	       (media->cid[2] >> 16) & 0xf);
105 
106 	/* Display the erase block size */
107 	sdhc_debug("Erase block size: 0x%08x\n", media->erase_blocks
108 		* media->write_bl_len);
109 
110 	/* Display the partition capacities */
111 	if (CONFIG(SDHC_DEBUG)) {
112 		for (partition_number = 0; partition_number
113 			< ARRAY_SIZE(media->capacity); partition_number++) {
114 			if (!media->capacity[partition_number])
115 				continue;
116 			display_capacity(media, partition_number);
117 		}
118 	}
119 }
120 
storage_startup(struct storage_media * media)121 int storage_startup(struct storage_media *media)
122 {
123 	int err;
124 	uint64_t capacity;
125 	uint64_t cmult, csize;
126 	struct mmc_command cmd;
127 	struct sd_mmc_ctrlr *ctrlr = media->ctrlr;
128 
129 	/* Determine the storage capacity */
130 	if (media->high_capacity) {
131 		cmult = 8;
132 		csize = sd_mmc_extract_uint32_bits(media->csd, 58, 22);
133 	} else {
134 		csize = sd_mmc_extract_uint32_bits(media->csd, 54, 12);
135 		cmult = sd_mmc_extract_uint32_bits(media->csd, 78, 3);
136 	}
137 	capacity = (csize + 1) << (cmult + 2);
138 	capacity *= media->read_bl_len;
139 	media->capacity[0] = capacity;
140 
141 	/* Limit the block size to 512 bytes */
142 	if (media->read_bl_len > 512)
143 		media->read_bl_len = 512;
144 	if (media->write_bl_len > 512)
145 		media->write_bl_len = 512;
146 
147 	/* Get the erase size in blocks */
148 	media->erase_blocks =
149 		(sd_mmc_extract_uint32_bits(media->csd, 47, 3) + 1)
150 		* (sd_mmc_extract_uint32_bits(media->csd, 42, 5) + 1);
151 
152 	/* Select the card, and put it into Transfer Mode */
153 	cmd.cmdidx = MMC_CMD_SELECT_CARD;
154 	cmd.resp_type = CARD_RSP_R1;
155 	cmd.cmdarg = media->rca << 16;
156 	cmd.flags = 0;
157 	err = ctrlr->send_cmd(ctrlr, &cmd, NULL);
158 	if (err)
159 		return err;
160 
161 	/* Increase the bus frequency */
162 	if (CONFIG(COMMONLIB_STORAGE_SD) && IS_SD(media))
163 		err = sd_change_freq(media);
164 	else if (CONFIG(COMMONLIB_STORAGE_MMC)) {
165 		err = mmc_change_freq(media);
166 		if (!err)
167 			mmc_update_capacity(media);
168 	}
169 	if (err)
170 		return err;
171 
172 	/* Restrict card's capabilities by what the controller can do */
173 	media->caps &= ctrlr->caps;
174 
175 	/* Increase the bus width if possible */
176 	if (CONFIG(COMMONLIB_STORAGE_SD) && IS_SD(media))
177 		err = sd_set_bus_width(media);
178 	else if (CONFIG(COMMONLIB_STORAGE_MMC))
179 		err = mmc_set_bus_width(media);
180 	if (err)
181 		return err;
182 
183 	/* Display the card setup */
184 	storage_display_setup(media);
185 	return 0;
186 }
187 
storage_setup_media(struct storage_media * media,struct sd_mmc_ctrlr * ctrlr)188 int storage_setup_media(struct storage_media *media, struct sd_mmc_ctrlr *ctrlr)
189 {
190 	int err;
191 
192 	memset(media, 0, sizeof(*media));
193 	media->ctrlr = ctrlr;
194 
195 	err = sd_mmc_enter_standby(media);
196 	if (err)
197 		return err;
198 	return storage_startup(media);
199 }
200 
storage_read(struct storage_media * media,void * dest,uint32_t start,uint32_t block_count)201 static int storage_read(struct storage_media *media, void *dest, uint32_t start,
202 	uint32_t block_count)
203 {
204 	struct mmc_command cmd;
205 	struct sd_mmc_ctrlr *ctrlr = media->ctrlr;
206 
207 	cmd.resp_type = CARD_RSP_R1;
208 	cmd.flags = 0;
209 
210 	if (block_count > 1)
211 		cmd.cmdidx = MMC_CMD_READ_MULTIPLE_BLOCK;
212 	else
213 		cmd.cmdidx = MMC_CMD_READ_SINGLE_BLOCK;
214 
215 	if (media->high_capacity)
216 		cmd.cmdarg = start;
217 	else
218 		cmd.cmdarg = start * media->read_bl_len;
219 
220 	struct mmc_data data;
221 	data.dest = dest;
222 	data.blocks = block_count;
223 	data.blocksize = media->read_bl_len;
224 	data.flags = DATA_FLAG_READ;
225 
226 	if (ctrlr->send_cmd(ctrlr, &cmd, &data))
227 		return 0;
228 
229 	if ((block_count > 1) && !(ctrlr->caps
230 		& DRVR_CAP_AUTO_CMD12)) {
231 		cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION;
232 		cmd.cmdarg = 0;
233 		cmd.resp_type = CARD_RSP_R1b;
234 		cmd.flags = CMD_FLAG_IGNORE_INHIBIT;
235 		if (ctrlr->send_cmd(ctrlr, &cmd, NULL)) {
236 			sd_mmc_error("Failed to send stop cmd\n");
237 			return 0;
238 		}
239 
240 		/* Waiting for the ready status */
241 		sd_mmc_send_status(media, SD_MMC_IO_RETRIES);
242 	}
243 
244 	return block_count;
245 }
246 
247 /////////////////////////////////////////////////////////////////////////////
248 // BlockDevice utilities and callbacks
249 
storage_block_setup(struct storage_media * media,uint64_t start,uint64_t count,int is_read)250 int storage_block_setup(struct storage_media *media, uint64_t start,
251 	uint64_t count, int is_read)
252 {
253 	struct sd_mmc_ctrlr *ctrlr = media->ctrlr;
254 	int partition_number;
255 
256 	if (count == 0)
257 		return 0;
258 
259 	uint32_t bl_len = is_read ? media->read_bl_len :
260 		media->write_bl_len;
261 
262 	/* Validate the block range */
263 	partition_number = media->partition_config & EXT_CSD_PART_ACCESS_MASK;
264 	if (((start * bl_len) > media->capacity[partition_number])
265 		|| (((start + count) * bl_len) >
266 		media->capacity[partition_number])) {
267 		sd_mmc_error("Block range exceeds device capacity\n");
268 		return 0;
269 	}
270 
271 	/*
272 	 * CMD16 only applies to single data rate mode, and block
273 	 * length for double data rate is always 512 bytes.
274 	 */
275 	if ((ctrlr->timing == BUS_TIMING_UHS_DDR50) ||
276 	    (ctrlr->timing == BUS_TIMING_MMC_DDR52) ||
277 	    (ctrlr->timing == BUS_TIMING_MMC_HS400) ||
278 	    (ctrlr->timing == BUS_TIMING_MMC_HS400ES))
279 		return 1;
280 	if (sd_mmc_set_blocklen(ctrlr, bl_len))
281 		return 0;
282 
283 	return 1;
284 }
285 
storage_block_read(struct storage_media * media,uint64_t start,uint64_t count,void * buffer)286 uint64_t storage_block_read(struct storage_media *media, uint64_t start,
287 	uint64_t count, void *buffer)
288 {
289 	uint8_t *dest = (uint8_t *)buffer;
290 
291 	if (storage_block_setup(media, start, count, 1) == 0)
292 		return 0;
293 
294 	uint64_t todo = count;
295 	struct sd_mmc_ctrlr *ctrlr = media->ctrlr;
296 	do {
297 		uint32_t cur = (uint32_t)MIN(todo, ctrlr->b_max);
298 		if (storage_read(media, dest, start, cur) != cur)
299 			return 0;
300 		todo -= cur;
301 		sd_mmc_trace("%s: Got %d blocks, more %d (total %d) to go.\n",
302 			  __func__, (int)cur, (int)todo, (int)count);
303 		start += cur;
304 		dest += cur * media->read_bl_len;
305 	} while (todo > 0);
306 	return count;
307 }
308 
storage_set_partition(struct storage_media * media,unsigned int partition_number)309 int storage_set_partition(struct storage_media *media,
310 	unsigned int partition_number)
311 {
312 	int err;
313 
314 	/* Select the partition */
315 	err = -1;
316 	if (CONFIG(COMMONLIB_STORAGE_SD) && IS_SD(media))
317 		err = sd_set_partition(media, partition_number);
318 	else if (CONFIG(COMMONLIB_STORAGE_MMC))
319 		err = mmc_set_partition(media, partition_number);
320 	if (err)
321 		sd_mmc_error("Invalid partition number!\n");
322 	return err;
323 }
324 
storage_partition_name(struct storage_media * media,unsigned int partition_number)325 const char *storage_partition_name(struct storage_media *media,
326 	unsigned int partition_number)
327 {
328 	const char *name;
329 
330 	/* Get the partition name */
331 	name = NULL;
332 	if (CONFIG(COMMONLIB_STORAGE_SD) && IS_SD(media))
333 		name = sd_partition_name(media, partition_number);
334 	else if (CONFIG(COMMONLIB_STORAGE_MMC))
335 		name = mmc_partition_name(media, partition_number);
336 	return name;
337 }
338 
storage_get_current_partition(struct storage_media * media)339 unsigned int storage_get_current_partition(struct storage_media *media)
340 {
341 	return media->partition_config & EXT_CSD_PART_ACCESS_MASK;
342 }
343