coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
mmc.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /*
3  * MultiMediaCard (MMC) and eMMC specific support code
4  * This code is controller independent
5  */
6 
7 #include <commonlib/storage.h>
8 #include <delay.h>
9 #include "mmc.h"
10 #include "sd_mmc.h"
11 #include "storage.h"
12 #include <string.h>
13 #include <timer.h>
14 
15 /* We pass in the cmd since otherwise the init seems to fail */
17  struct mmc_command *cmd, int use_arg)
18 {
19  struct sd_mmc_ctrlr *ctrlr = media->ctrlr;
20 
22  cmd->resp_type = CARD_RSP_R3;
23 
24  /* Set the controller's operating conditions */
25  if (use_arg) {
28  cmd->cmdarg = ctrlr->voltages & mask;
29 
30  /* Always request high capacity if supported by the
31  * controller
32  */
33  if (ctrlr->caps & DRVR_CAP_HC)
34  cmd->cmdarg |= OCR_HCS;
35  }
36  cmd->flags = 0;
37  int err = ctrlr->send_cmd(ctrlr, cmd, NULL);
38  if (err)
39  return err;
40 
41  media->op_cond_response = cmd->response[0];
42  return 0;
43 }
44 
46 {
47  struct mmc_command cmd;
48  int max_iters = 2;
49 
50  /* Ask the card for its operating conditions */
51  cmd.cmdarg = 0;
52  for (int i = 0; i < max_iters; i++) {
53  int err = mmc_send_op_cond_iter(media, &cmd, i != 0);
54  if (err)
55  return err;
56 
57  // OCR_BUSY is active low, this bit set means
58  // "initialization complete".
60  return 0;
61  }
62  return CARD_IN_PROGRESS;
63 }
64 
66 {
67  struct mmc_command cmd;
68  struct stopwatch sw;
69 
71  while (1) {
72  // CMD1 queries whether initialization is done.
73  int err = mmc_send_op_cond_iter(media, &cmd, 1);
74  if (err)
75  return err;
76 
77  // OCR_BUSY means "initialization complete".
79  break;
80 
81  // Check if init timeout has expired.
82  if (stopwatch_expired(&sw))
83  return CARD_UNUSABLE_ERR;
84 
85  udelay(100);
86  }
87 
89  media->ocr = cmd.response[0];
90 
92  media->rca = 0;
93  return 0;
94 }
95 
96 int mmc_send_ext_csd(struct sd_mmc_ctrlr *ctrlr, unsigned char *ext_csd)
97 {
98  struct mmc_command cmd;
99  struct mmc_data data;
100  int rv;
101 
102  /* Get the Card Status Register */
104  cmd.resp_type = CARD_RSP_R1;
105  cmd.cmdarg = 0;
106  cmd.flags = 0;
107 
108  data.dest = (char *)ext_csd;
109  data.blocks = 1;
110  data.blocksize = 512;
111  data.flags = DATA_FLAG_READ;
112 
113  rv = ctrlr->send_cmd(ctrlr, &cmd, &data);
114 
115  if (!rv && CONFIG(SD_MMC_TRACE)) {
116  int i, size;
117 
118  size = data.blocks * data.blocksize;
119  sd_mmc_trace("\t%p ext_csd:", ctrlr);
120  for (i = 0; i < size; i++) {
121  if (!(i % 32))
122  sd_mmc_trace("\n");
123  sd_mmc_trace(" %2.2x", ext_csd[i]);
124  }
125  sd_mmc_trace("\n");
126  }
127  return rv;
128 }
129 
130 static int mmc_switch(struct storage_media *media, uint8_t index, uint8_t value)
131 {
132  struct mmc_command cmd;
133  struct sd_mmc_ctrlr *ctrlr = media->ctrlr;
134 
135  cmd.cmdidx = MMC_CMD_SWITCH;
136  cmd.resp_type = CARD_RSP_R1b;
137  cmd.cmdarg = ((MMC_SWITCH_MODE_WRITE_BYTE << 24) |
138  (index << 16) | (value << 8));
139  cmd.flags = 0;
140 
141  int ret = ctrlr->send_cmd(ctrlr, &cmd, NULL);
142 
143  /* Waiting for the ready status */
145  return ret;
146 
147 }
148 
150 {
151  uint32_t clock;
152 
153  clock = CLOCK_26MHZ;
154  if (media->caps & DRVR_CAP_HS) {
155  if ((media->caps & DRVR_CAP_HS200) ||
157  clock = CLOCK_200MHZ;
158  else if (media->caps & DRVR_CAP_HS52)
159  clock = CLOCK_52MHZ;
160  }
161  SET_CLOCK(media->ctrlr, clock);
162 }
163 
164 static int mmc_select_hs(struct storage_media *media)
165 {
166  int ret;
167 
168  /* Switch the MMC device into high speed mode */
170  if (ret) {
171  sd_mmc_error("Timing switch to high speed failed\n");
172  return ret;
173  }
174  sdhc_debug("SDHCI switched MMC to high speed\n");
175 
176  /* Increase the controller clock speed */
182  return ret;
183 }
184 
185 static int mmc_send_tuning_seq(struct sd_mmc_ctrlr *ctrlr, char *buffer)
186 {
187  struct mmc_command cmd;
188  struct mmc_data data;
189 
190  /* Request the device send the tuning sequence to the host */
192  cmd.resp_type = CARD_RSP_R1;
193  cmd.cmdarg = 0;
195 
196  data.dest = buffer;
197  data.blocks = 1;
198  data.blocksize = (ctrlr->bus_width == 8) ? 128 : 64;
199  data.flags = DATA_FLAG_READ;
200  return ctrlr->send_cmd(ctrlr, &cmd, &data);
201 }
202 
203 static int mmc_bus_tuning(struct storage_media *media)
204 {
205  ALLOC_CACHE_ALIGN_BUFFER(char, buffer, 128);
206  struct sd_mmc_ctrlr *ctrlr = media->ctrlr;
207  int index;
208  int successful;
209 
210  /* Request the device send the tuning sequence up to 40 times */
211  ctrlr->tuning_start(ctrlr, 0);
212  for (index = 0; index < 40; index++) {
213  mmc_send_tuning_seq(ctrlr, buffer);
214  if (ctrlr->is_tuning_complete(ctrlr, &successful)) {
215  if (successful)
216  return 0;
217  break;
218  }
219  }
220  sd_mmc_error("Bus tuning failed!\n");
221  return -1;
222 }
223 
225 {
227  uint32_t caps;
228  struct sd_mmc_ctrlr *ctrlr = media->ctrlr;
229  int ret;
231 
232  /* Switch the MMC device into high speed mode */
233  ret = mmc_select_hs(media);
234  if (ret)
235  return ret;
236 
237  /* Switch MMC device to 8-bit DDR with strobe */
241  if ((ctrlr->caps & DRVR_CAP_ENHANCED_STROBE)
246  }
248  if (ret) {
249  sd_mmc_error("Switching bus width for HS400 failed\n");
250  return ret;
251  }
252  sdhc_debug("SDHCI switched MMC to 8-bit DDR\n");
253 
254  /* Set controller to 8-bit mode */
255  SET_BUS_WIDTH(ctrlr, 8);
257 
258  /* Switch MMC device to HS400 */
260  if (ret) {
261  sd_mmc_error("Switch to HS400 timing failed\n");
262  return ret;
263  }
264 
265  /* Set controller to 200 MHz and use receive strobe */
266  SET_TIMING(ctrlr, timing);
267  media->caps |= caps;
270  return ret;
271 }
272 
274 {
275  struct sd_mmc_ctrlr *ctrlr = media->ctrlr;
276  int ret;
277 
278  /* Switch the MMC device to 8-bit SDR */
280  if (ret) {
281  sd_mmc_error("Switching bus width for HS200 failed\n");
282  return ret;
283  }
284 
285  /* Set controller to 8-bit mode */
286  SET_BUS_WIDTH(ctrlr, 8);
288 
289  /* Switch to HS200 */
291 
292  if (ret) {
293  sd_mmc_error("Switch to HS200 failed\n");
294  return ret;
295  }
296  sdhc_debug("SDHCI switched MMC to 8-bit SDR\n");
297 
298  /* Set controller to 200 MHz */
302 
303  /* Tune the receive sampling point for the bus */
304  if ((!ret) && (ctrlr->caps & DRVR_CAP_HS200_TUNING))
305  ret = mmc_bus_tuning(media);
306  return ret;
307 }
308 
310 {
311  struct sd_mmc_ctrlr *ctrlr = media->ctrlr;
312  int err;
313  ALLOC_CACHE_ALIGN_BUFFER(unsigned char, ext_csd, 512);
314 
315  media->caps = 0;
316 
317  /* Only version 4 supports high-speed */
318  if (media->version < MMC_VERSION_4)
319  return 0;
320 
321  err = mmc_send_ext_csd(ctrlr, ext_csd);
322  if (err)
323  return err;
324 
325  /* Determine if the device supports enhanced strobe */
326  media->caps |= ext_csd[EXT_CSD_STROBE_SUPPORT]
328 
329  if ((ctrlr->caps & DRVR_CAP_HS400) &&
330  (ext_csd[EXT_CSD_CARD_TYPE] & MMC_HS400))
331  err = mmc_select_hs400(media);
332  else if ((ctrlr->caps & DRVR_CAP_HS200) &&
333  (ext_csd[EXT_CSD_CARD_TYPE] & MMC_HS_200MHZ))
334  err = mmc_select_hs200(media);
335  else
336  err = mmc_select_hs(media);
337 
338  return err;
339 }
340 
342 {
343  struct sd_mmc_ctrlr *ctrlr = media->ctrlr;
344  int err;
345  int width;
346 
347  ALLOC_CACHE_ALIGN_BUFFER(unsigned char, ext_csd, EXT_CSD_SIZE);
348  ALLOC_CACHE_ALIGN_BUFFER(unsigned char, test_csd, EXT_CSD_SIZE);
349 
350  /* Set the bus width */
351  err = 0;
352  for (width = EXT_CSD_BUS_WIDTH_8; width >= 0; width--) {
353  /* If HS200 is switched, Bus Width has been 8-bit */
354  if ((media->caps & DRVR_CAP_HS200) ||
356  break;
357 
358  /* Set the card to use 4 bit*/
360  if (err)
361  continue;
362 
363  if (!width) {
364  SET_BUS_WIDTH(ctrlr, 1);
365  break;
366  }
367  SET_BUS_WIDTH(ctrlr, 4 * width);
368 
369  err = mmc_send_ext_csd(ctrlr, test_csd);
370  if (!err &&
371  (ext_csd[EXT_CSD_PARTITIONING_SUPPORT] ==
372  test_csd[EXT_CSD_PARTITIONING_SUPPORT]) &&
373  (ext_csd[EXT_CSD_ERASE_GROUP_DEF] ==
374  test_csd[EXT_CSD_ERASE_GROUP_DEF]) &&
375  (ext_csd[EXT_CSD_REV] ==
376  test_csd[EXT_CSD_REV]) &&
377  (ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] ==
378  test_csd[EXT_CSD_HC_ERASE_GRP_SIZE]) &&
379  memcmp(&ext_csd[EXT_CSD_SEC_CNT],
380  &test_csd[EXT_CSD_SEC_CNT], 4) == 0) {
381  media->caps |= width;
382  break;
383  }
384  }
385  return err;
386 }
387 
389 {
391  struct sd_mmc_ctrlr *ctrlr = media->ctrlr;
392  int err;
393  ALLOC_CACHE_ALIGN_BUFFER(unsigned char, ext_csd, EXT_CSD_SIZE);
394  uint32_t erase_size;
395  uint32_t hc_erase_size;
396  uint64_t hc_wp_size;
397  int index;
398 
399  if (media->version < MMC_VERSION_4)
400  return 0;
401 
402  /* check ext_csd version and capacity */
403  err = mmc_send_ext_csd(ctrlr, ext_csd);
404  if (err)
405  return err;
406 
407  if (ext_csd[EXT_CSD_REV] < 2)
408  return 0;
409 
410  /* Determine the eMMC device information */
413 
414  /* Determine the user partition size
415  *
416  * According to the JEDEC Standard, the value of
417  * ext_csd's capacity is valid if the value is
418  * more than 2GB
419  */
420  capacity = (uint32_t)(ext_csd[EXT_CSD_SEC_CNT + 0] << 0 |
421  ext_csd[EXT_CSD_SEC_CNT + 1] << 8 |
422  ext_csd[EXT_CSD_SEC_CNT + 2] << 16 |
423  ext_csd[EXT_CSD_SEC_CNT + 3] << 24);
424  capacity *= 512;
425  if ((capacity >> 20) > 2 * 1024)
427 
428  /* Determine the boot partition sizes */
429  hc_erase_size = ext_csd[224] * 512 * KiB;
430  capacity = ext_csd[EXT_CSD_BOOT_SIZE_MULT] * 128 * KiB;
433 
434  /* Determine the RPMB size */
435  hc_wp_size = ext_csd[EXT_CSD_HC_WP_GRP_SIZE] * hc_erase_size;
436  capacity = 128 * KiB * ext_csd[EXT_CSD_RPMB_SIZE_MULT];
438 
439  /* Determine the general partition sizes */
440  capacity = (ext_csd[EXT_CSD_GP_SIZE_MULT_GP0 + 2] << 16)
441  | (ext_csd[EXT_CSD_GP_SIZE_MULT_GP0 + 1] << 8)
442  | ext_csd[EXT_CSD_GP_SIZE_MULT_GP0];
443  capacity *= hc_wp_size;
445 
446  capacity = (ext_csd[EXT_CSD_GP_SIZE_MULT_GP1 + 2] << 16)
447  | (ext_csd[EXT_CSD_GP_SIZE_MULT_GP1 + 1] << 8)
448  | ext_csd[EXT_CSD_GP_SIZE_MULT_GP1];
449  capacity *= hc_wp_size;
451 
452  capacity = (ext_csd[EXT_CSD_GP_SIZE_MULT_GP2 + 2] << 16)
453  | (ext_csd[EXT_CSD_GP_SIZE_MULT_GP2 + 1] << 8)
454  | ext_csd[EXT_CSD_GP_SIZE_MULT_GP2];
455  capacity *= hc_wp_size;
457 
458  capacity = (ext_csd[EXT_CSD_GP_SIZE_MULT_GP3 + 2] << 16)
459  | (ext_csd[EXT_CSD_GP_SIZE_MULT_GP3 + 1] << 8)
460  | ext_csd[EXT_CSD_GP_SIZE_MULT_GP3];
461  capacity *= hc_wp_size;
463 
464  /* Determine the erase size */
465  erase_size = (sd_mmc_extract_uint32_bits(media->csd,
466  81, 5) + 1) *
468  + 1);
469  for (index = MMC_PARTITION_BOOT_1; index <= MMC_PARTITION_GP4;
470  index++) {
471  if (media->capacity[index] != 0) {
472  /* Enable the partitions */
475  if (err) {
476  sdhc_error("Failed to enable partition access\n");
477  return err;
478  }
479 
480  /* Use HC erase group size */
481  erase_size = hc_erase_size / media->write_bl_len;
482  break;
483  }
484  }
485  media->erase_blocks = erase_size;
486  media->trim_mult = ext_csd[EXT_CSD_TRIM_MULT];
487 
488  return 0;
489 }
490 
492  unsigned int partition_number)
493 {
494  uint8_t partition_config;
495 
496  /* Validate the partition number */
497  if ((partition_number > MMC_PARTITION_GP4)
498  || (!media->capacity[partition_number]))
499  return -1;
500 
501  /* Update the partition register */
502  partition_config = media->partition_config;
503  partition_config &= ~EXT_CSD_PART_ACCESS_MASK;
504  partition_config |= partition_number;
505 
506  /* Select the new partition */
507  int ret = mmc_switch(media, EXT_CSD_PART_CONF, partition_config);
508  if (!ret)
509  media->partition_config = partition_config;
510 
511  return ret;
512 }
513 
515  unsigned int partition_number)
516 {
517  static const char *const partition_name[8] = {
518  "User", /* 0 */
519  "Boot 1", /* 1 */
520  "Boot 2", /* 2 */
521  "RPMB", /* 3 */
522  "GP 1", /* 4 */
523  "GP 2", /* 5 */
524  "GP 3", /* 6 */
525  "GP 4" /* 7 */
526  };
527 
528  if (partition_number >= ARRAY_SIZE(partition_name))
529  return "";
530  return partition_name[partition_number];
531 }
pte_t value
Definition: mmu.c:91
static int width
Definition: bochs.c:42
#define ALLOC_CACHE_ALIGN_BUFFER(type, name, size)
Definition: bouncebuf.h:76
#define ARRAY_SIZE(a)
Definition: helpers.h:12
#define KiB
Definition: helpers.h:75
static int mmc_switch(struct storage_media *media, uint8_t index, uint8_t value)
Definition: mmc.c:130
int mmc_set_partition(struct storage_media *media, unsigned int partition_number)
Definition: mmc.c:491
static int mmc_send_op_cond_iter(struct storage_media *media, struct mmc_command *cmd, int use_arg)
Definition: mmc.c:16
static int mmc_bus_tuning(struct storage_media *media)
Definition: mmc.c:203
int mmc_update_capacity(struct storage_media *media)
Definition: mmc.c:388
int mmc_change_freq(struct storage_media *media)
Definition: mmc.c:309
static int mmc_select_hs200(struct storage_media *media)
Definition: mmc.c:273
int mmc_set_bus_width(struct storage_media *media)
Definition: mmc.c:341
const char * mmc_partition_name(struct storage_media *media, unsigned int partition_number)
Definition: mmc.c:514
static int mmc_select_hs(struct storage_media *media)
Definition: mmc.c:164
static int mmc_select_hs400(struct storage_media *media)
Definition: mmc.c:224
int mmc_complete_op_cond(struct storage_media *media)
Definition: mmc.c:65
int mmc_send_ext_csd(struct sd_mmc_ctrlr *ctrlr, unsigned char *ext_csd)
Definition: mmc.c:96
int mmc_send_op_cond(struct storage_media *media)
Definition: mmc.c:45
static int mmc_send_tuning_seq(struct sd_mmc_ctrlr *ctrlr, char *buffer)
Definition: mmc.c:185
static void mmc_recalculate_clock(struct storage_media *media)
Definition: mmc.c:149
#define MMC_INIT_TIMEOUT_US_MS
Definition: mmc.h:29
#define MMC_HS400
Definition: mmc.h:11
#define MMC_HS_200MHZ
Definition: mmc.h:10
#define MMC_SWITCH_MODE_WRITE_BYTE
Definition: mmc.h:23
@ CONFIG
Definition: dsi_common.h:201
#define EXT_CSD_HC_ERASE_GRP_SIZE
Definition: storage.h:26
#define MMC_PARTITION_GP1
Definition: storage.h:69
#define MMC_PARTITION_GP4
Definition: storage.h:72
#define EXT_CSD_GP_SIZE_MULT_GP1
Definition: storage.h:12
#define EXT_CSD_BUS_WIDTH
Definition: storage.h:19
#define EXT_CSD_DDR_BUS_WIDTH_8
Definition: storage.h:45
#define EXT_CSD_PART_CONF
Definition: storage.h:18
#define MMC_PARTITION_RPMB
Definition: storage.h:68
#define MMC_PARTITION_BOOT_1
Definition: storage.h:66
#define EXT_CSD_RPMB_SIZE_MULT
Definition: storage.h:16
#define EXT_CSD_BOOT_SIZE_MULT
Definition: storage.h:27
#define EXT_CSD_TIMING_HS
Definition: storage.h:49
#define EXT_CSD_TRIM_MULT
Definition: storage.h:28
#define EXT_CSD_BUS_WIDTH_8
Definition: storage.h:43
#define EXT_CSD_TIMING_HS200
Definition: storage.h:50
#define EXT_CSD_TIMING_HS400
Definition: storage.h:51
#define OCR_ACCESS_MODE
Definition: storage.h:103
#define EXT_CSD_GP_SIZE_MULT_GP3
Definition: storage.h:14
#define EXT_CSD_HC_WP_GRP_SIZE
Definition: storage.h:25
#define EXT_CSD_GP_SIZE_MULT_GP0
Definition: storage.h:11
#define OCR_BUSY
Definition: storage.h:100
#define EXT_CSD_SIZE
Definition: storage.h:53
#define EXT_CSD_REV
Definition: storage.h:22
#define OCR_VOLTAGE_MASK
Definition: storage.h:102
#define EXT_CSD_BUS_WIDTH_STROBE
Definition: storage.h:46
#define OCR_HCS
Definition: storage.h:101
#define EXT_CSD_HS_TIMING
Definition: storage.h:21
#define EXT_CSD_GP_SIZE_MULT_GP2
Definition: storage.h:13
#define EXT_CSD_PARTITION_ENABLE
Definition: storage.h:59
#define EXT_CSD_SEC_CNT
Definition: storage.h:24
#define MMC_PARTITION_BOOT_2
Definition: storage.h:67
#define EXT_CSD_ERASE_GROUP_DEF
Definition: storage.h:17
#define MMC_VERSION_4
Definition: storage.h:87
#define EXT_CSD_STROBE_SUPPORT
Definition: storage.h:20
#define MMC_PARTITION_GP2
Definition: storage.h:70
#define MMC_VERSION_UNKNOWN
Definition: storage.h:82
#define EXT_CSD_CARD_TYPE
Definition: storage.h:23
#define EXT_CSD_PARTITIONING_SUPPORT
Definition: storage.h:15
#define MMC_PARTITION_GP3
Definition: storage.h:71
#define MMC_PARTITION_USER
Definition: storage.h:65
#define EXT_CSD_PART_ACCESS_MASK
Definition: storage.h:56
static int stopwatch_expired(struct stopwatch *sw)
Definition: timer.h:152
static void stopwatch_init_msecs_expire(struct stopwatch *sw, long ms)
Definition: timer.h:133
u8 buffer[C2P_BUFFER_MAXSIZE]
Definition: psp_smm.c:18
static struct storage_media media
Definition: sd_media.c:21
uint64_t sd_mmc_extract_uint32_bits(const uint32_t *array, int start, int count)
Definition: sd_mmc.c:17
int sd_mmc_send_status(struct storage_media *media, ssize_t tries)
Definition: sd_mmc.c:94
#define SET_TIMING(ctrlr, timing_value)
Definition: sd_mmc.h:27
#define sdhc_debug(format...)
Definition: sd_mmc.h:64
#define sd_mmc_trace(format...)
Definition: sd_mmc.h:82
#define SET_BUS_WIDTH(ctrlr, width)
Definition: sd_mmc.h:15
#define sdhc_error(format...)
Definition: sd_mmc.h:74
#define SD_MMC_IO_RETRIES
Definition: sd_mmc.h:11
#define sd_mmc_error(format...)
Definition: sd_mmc.h:87
#define SET_CLOCK(ctrlr, clock_hz)
Definition: sd_mmc.h:21
#define DRVR_CAP_HS200_TUNING
Definition: sd_mmc_ctrlr.h:183
#define CLOCK_200MHZ
Definition: sd_mmc_ctrlr.h:164
#define DRVR_CAP_HS200
Definition: sd_mmc_ctrlr.h:178
#define CMD_FLAG_IGNORE_INHIBIT
Definition: sd_mmc_ctrlr.h:94
#define DATA_FLAG_READ
Definition: sd_mmc_ctrlr.h:113
#define CARD_RSP_R1
Definition: sd_mmc_ctrlr.h:76
#define DRVR_CAP_HS52
Definition: sd_mmc_ctrlr.h:177
#define CARD_RSP_R3
Definition: sd_mmc_ctrlr.h:80
#define CARD_IN_PROGRESS
Definition: sd_mmc_ctrlr.h:14
#define CLOCK_52MHZ
Definition: sd_mmc_ctrlr.h:163
#define BUS_TIMING_MMC_HS400ES
Definition: sd_mmc_ctrlr.h:199
#define BUS_TIMING_MMC_HS
Definition: sd_mmc_ctrlr.h:189
#define CARD_UNUSABLE_ERR
Definition: sd_mmc_ctrlr.h:11
#define CLOCK_26MHZ
Definition: sd_mmc_ctrlr.h:161
#define DRVR_CAP_ENHANCED_STROBE
Definition: sd_mmc_ctrlr.h:180
#define BUS_TIMING_MMC_HS400
Definition: sd_mmc_ctrlr.h:198
#define MMC_CMD_AUTO_TUNING_SEQUENCE
Definition: sd_mmc_ctrlr.h:48
#define MMC_CMD_SEND_OP_COND
Definition: sd_mmc_ctrlr.h:29
#define MMC_CMD_SEND_EXT_CSD
Definition: sd_mmc_ctrlr.h:47
#define MMC_CMD_SWITCH
Definition: sd_mmc_ctrlr.h:46
#define DRVR_CAP_HS
Definition: sd_mmc_ctrlr.h:176
#define CARD_RSP_R1b
Definition: sd_mmc_ctrlr.h:77
#define DRVR_CAP_HC
Definition: sd_mmc_ctrlr.h:175
#define DRVR_CAP_HS400
Definition: sd_mmc_ctrlr.h:179
#define BUS_TIMING_MMC_HS200
Definition: sd_mmc_ctrlr.h:197
static const int mask[4]
Definition: gpio.c:308
#define NULL
Definition: stddef.h:19
unsigned int uint32_t
Definition: stdint.h:14
unsigned long long uint64_t
Definition: stdint.h:17
unsigned char uint8_t
Definition: stdint.h:8
int memcmp(const void *s1, const void *s2, size_t n)
Definition: memcmp.c:3
uint32_t response[4]
Definition: sd_mmc_ctrlr.h:91
uint32_t cmdarg
Definition: sd_mmc_ctrlr.h:86
uint16_t cmdidx
Definition: sd_mmc_ctrlr.h:25
uint32_t flags
Definition: sd_mmc_ctrlr.h:92
uint32_t resp_type
Definition: sd_mmc_ctrlr.h:67
char * dest
Definition: sd_mmc_ctrlr.h:108
uint32_t blocksize
Definition: sd_mmc_ctrlr.h:117
uint32_t flags
Definition: sd_mmc_ctrlr.h:111
uint32_t blocks
Definition: sd_mmc_ctrlr.h:116
void(* tuning_start)(struct sd_mmc_ctrlr *ctrlr, int retune)
Definition: sd_mmc_ctrlr.h:124
uint32_t voltages
Definition: sd_mmc_ctrlr.h:129
uint32_t bus_width
Definition: sd_mmc_ctrlr.h:166
uint32_t caps
Definition: sd_mmc_ctrlr.h:167
int(* send_cmd)(struct sd_mmc_ctrlr *ctrlr, struct mmc_command *cmd, struct mmc_data *data)
Definition: sd_mmc_ctrlr.h:121
uint32_t timing
Definition: sd_mmc_ctrlr.h:186
int(* is_tuning_complete)(struct sd_mmc_ctrlr *ctrlr, int *successful)
Definition: sd_mmc_ctrlr.h:125
uint32_t ocr
Definition: storage.h:98
uint32_t trim_mult
Definition: storage.h:96
uint8_t partition_config
Definition: storage.h:112
uint32_t version
Definition: storage.h:75
uint32_t write_bl_len
Definition: storage.h:90
uint32_t csd[4]
Definition: storage.h:108
struct sd_mmc_ctrlr * ctrlr
Definition: storage.h:63
uint64_t capacity[8]
Definition: storage.h:62
uint32_t op_cond_response
Definition: storage.h:105
int high_capacity
Definition: storage.h:91
uint32_t erase_blocks
Definition: storage.h:94
uint16_t rca
Definition: storage.h:110
uint32_t caps
Definition: storage.h:74
void udelay(uint32_t us)
Definition: udelay.c:15