Blame view

cmd/mmc.c 23.1 KB
71f951180   wdenk   * Fix CONFIG_NET_...
1
2
3
4
  /*
   * (C) Copyright 2003
   * Kyle Harris, kharris@nexus-tech.net
   *
1a4596601   Wolfgang Denk   Add GPL-2.0+ SPDX...
5
   * SPDX-License-Identifier:	GPL-2.0+
71f951180   wdenk   * Fix CONFIG_NET_...
6
7
8
9
   */
  
  #include <common.h>
  #include <command.h>
24b852a7a   Simon Glass   Move console defi...
10
  #include <console.h>
71f951180   wdenk   * Fix CONFIG_NET_...
11
  #include <mmc.h>
02e22c2de   Mike Frysinger   cmd_mmc: make cur...
12
  static int curr_device = -1;
272cc70b2   Andy Fleming   Add MMC Framework
13
14
15
  
  static void print_mmcinfo(struct mmc *mmc)
  {
c5f0d3f1c   Diego Santa Cruz   mmc: show hardwar...
16
  	int i;
93bfd6167   Pantelis Antoniou   mmc: Split mmc st...
17
18
  	printf("Device: %s
  ", mmc->cfg->name);
272cc70b2   Andy Fleming   Add MMC Framework
19
20
21
22
23
24
25
26
  	printf("Manufacturer ID: %x
  ", mmc->cid[0] >> 24);
  	printf("OEM: %x
  ", (mmc->cid[0] >> 8) & 0xffff);
  	printf("Name: %c%c%c%c%c 
  ", mmc->cid[0] & 0xff,
  			(mmc->cid[1] >> 24), (mmc->cid[1] >> 16) & 0xff,
  			(mmc->cid[1] >> 8) & 0xff, mmc->cid[1] & 0xff);
7a96ec745   Jean-Jacques Hiblot   cmd: mmc: display...
27
28
  	printf("Bus Speed: %d
  ", mmc->clock);
52d241dfb   Jean-Jacques Hiblot   mmc: dump card an...
29
  #if CONFIG_IS_ENABLED(MMC_VERBOSE)
7a96ec745   Jean-Jacques Hiblot   cmd: mmc: display...
30
31
  	printf("Mode : %s
  ", mmc_mode_name(mmc->selected_mode));
52d241dfb   Jean-Jacques Hiblot   mmc: dump card an...
32
33
34
  	mmc_dump_capabilities("card capabilities", mmc->card_caps);
  	mmc_dump_capabilities("host capabilities", mmc->host_caps);
  #endif
272cc70b2   Andy Fleming   Add MMC Framework
35
36
  	printf("Rd Block Len: %d
  ", mmc->read_bl_len);
4b7cee533   Pantelis Antoniou   mmc: Implement SD...
37
38
39
40
41
42
43
  	printf("%s version %d.%d", IS_SD(mmc) ? "SD" : "MMC",
  			EXTRACT_SDMMC_MAJOR_VERSION(mmc->version),
  			EXTRACT_SDMMC_MINOR_VERSION(mmc->version));
  	if (EXTRACT_SDMMC_CHANGE_VERSION(mmc->version) != 0)
  		printf(".%d", EXTRACT_SDMMC_CHANGE_VERSION(mmc->version));
  	printf("
  ");
272cc70b2   Andy Fleming   Add MMC Framework
44
45
46
  
  	printf("High Capacity: %s
  ", mmc->high_capacity ? "Yes" : "No");
940e07829   Minkyu Kang   mmc: show mmc cap...
47
48
49
  	puts("Capacity: ");
  	print_size(mmc->capacity, "
  ");
272cc70b2   Andy Fleming   Add MMC Framework
50

786e8f818   Andrew Gabbasov   mmc: Fix handling...
51
52
53
  	printf("Bus Width: %d-bit%s
  ", mmc->bus_width,
  			mmc->ddr_mode ? " DDR" : "");
c5f0d3f1c   Diego Santa Cruz   mmc: show hardwar...
54

e6fa5a546   Jean-Jacques Hiblot   mmc: compile out ...
55
  #if CONFIG_IS_ENABLED(MMC_WRITE)
b0361526d   Diego Santa Cruz   mmc: show the era...
56
57
58
  	puts("Erase Group Size: ");
  	print_size(((u64)mmc->erase_grp_size) << 9, "
  ");
e6fa5a546   Jean-Jacques Hiblot   mmc: compile out ...
59
  #endif
b0361526d   Diego Santa Cruz   mmc: show the era...
60

525ada217   Diego Santa Cruz   mmc: skip mmcinfo...
61
  	if (!IS_SD(mmc) && mmc->version >= MMC_VERSION_4_41) {
c3dbb4f9b   Diego Santa Cruz   mmc: extend mmcin...
62
  		bool has_enh = (mmc->part_support & ENHNCD_SUPPORT) != 0;
beb98a149   Diego Santa Cruz   mmc: display size...
63
  		bool usr_enh = has_enh && (mmc->part_attr & EXT_CSD_ENH_USR);
b0361526d   Diego Santa Cruz   mmc: show the era...
64

b7a6e2c9c   Jean-Jacques Hiblot   mmc: remove hc_wp...
65
  #if CONFIG_IS_ENABLED(MMC_HW_PARTITIONING)
b0361526d   Diego Santa Cruz   mmc: show the era...
66
67
68
  		puts("HC WP Group Size: ");
  		print_size(((u64)mmc->hc_wp_grp_size) << 9, "
  ");
b7a6e2c9c   Jean-Jacques Hiblot   mmc: remove hc_wp...
69
  #endif
b0361526d   Diego Santa Cruz   mmc: show the era...
70

c5f0d3f1c   Diego Santa Cruz   mmc: show hardwar...
71
  		puts("User Capacity: ");
9e41a00b5   Diego Santa Cruz   mmc: extend mmcin...
72
73
74
75
76
77
78
  		print_size(mmc->capacity_user, usr_enh ? " ENH" : "");
  		if (mmc->wr_rel_set & EXT_CSD_WR_DATA_REL_USR)
  			puts(" WRREL
  ");
  		else
  			putc('
  ');
beb98a149   Diego Santa Cruz   mmc: display size...
79
80
81
82
83
84
85
86
  		if (usr_enh) {
  			puts("User Enhanced Start: ");
  			print_size(mmc->enh_user_start, "
  ");
  			puts("User Enhanced Size: ");
  			print_size(mmc->enh_user_size, "
  ");
  		}
c5f0d3f1c   Diego Santa Cruz   mmc: show hardwar...
87
  		puts("Boot Capacity: ");
c3dbb4f9b   Diego Santa Cruz   mmc: extend mmcin...
88
89
90
  		print_size(mmc->capacity_boot, has_enh ? " ENH
  " : "
  ");
c5f0d3f1c   Diego Santa Cruz   mmc: show hardwar...
91
  		puts("RPMB Capacity: ");
c3dbb4f9b   Diego Santa Cruz   mmc: extend mmcin...
92
93
94
  		print_size(mmc->capacity_rpmb, has_enh ? " ENH
  " : "
  ");
b0361526d   Diego Santa Cruz   mmc: show the era...
95

c5f0d3f1c   Diego Santa Cruz   mmc: show hardwar...
96
  		for (i = 0; i < ARRAY_SIZE(mmc->capacity_gp); i++) {
c3dbb4f9b   Diego Santa Cruz   mmc: extend mmcin...
97
98
  			bool is_enh = has_enh &&
  				(mmc->part_attr & EXT_CSD_ENH_GP(i));
c5f0d3f1c   Diego Santa Cruz   mmc: show hardwar...
99
  			if (mmc->capacity_gp[i]) {
f289fd739   Diego Santa Cruz   mmc: make eMMC ge...
100
  				printf("GP%i Capacity: ", i+1);
c3dbb4f9b   Diego Santa Cruz   mmc: extend mmcin...
101
  				print_size(mmc->capacity_gp[i],
9e41a00b5   Diego Santa Cruz   mmc: extend mmcin...
102
103
104
105
106
107
108
  					   is_enh ? " ENH" : "");
  				if (mmc->wr_rel_set & EXT_CSD_WR_DATA_REL_GP(i))
  					puts(" WRREL
  ");
  				else
  					putc('
  ');
c5f0d3f1c   Diego Santa Cruz   mmc: show hardwar...
109
110
111
  			}
  		}
  	}
272cc70b2   Andy Fleming   Add MMC Framework
112
  }
1ae24a504   Stephen Warren   cmd_mmc: add forc...
113
  static struct mmc *init_mmc_device(int dev, bool force_init)
1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
114
115
116
117
118
119
120
121
  {
  	struct mmc *mmc;
  	mmc = find_mmc_device(dev);
  	if (!mmc) {
  		printf("no mmc device at slot %x
  ", dev);
  		return NULL;
  	}
bcfde7ffb   Eric Nelson   mmc: use block la...
122

1ae24a504   Stephen Warren   cmd_mmc: add forc...
123
124
  	if (force_init)
  		mmc->has_init = 0;
1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
125
126
127
128
  	if (mmc_init(mmc))
  		return NULL;
  	return mmc;
  }
088f1b199   Kim Phillips   common/cmd_*.c: s...
129
  static int do_mmcinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
272cc70b2   Andy Fleming   Add MMC Framework
130
131
  {
  	struct mmc *mmc;
272cc70b2   Andy Fleming   Add MMC Framework
132

ea6ebe217   Lei Wen   cmd_mmc: eliminat...
133
134
135
136
137
138
139
140
141
  	if (curr_device < 0) {
  		if (get_mmc_num() > 0)
  			curr_device = 0;
  		else {
  			puts("No MMC device available
  ");
  			return 1;
  		}
  	}
272cc70b2   Andy Fleming   Add MMC Framework
142

1ae24a504   Stephen Warren   cmd_mmc: add forc...
143
  	mmc = init_mmc_device(curr_device, false);
1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
144
145
  	if (!mmc)
  		return CMD_RET_FAILURE;
272cc70b2   Andy Fleming   Add MMC Framework
146

1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
147
148
149
  	print_mmcinfo(mmc);
  	return CMD_RET_SUCCESS;
  }
272cc70b2   Andy Fleming   Add MMC Framework
150

1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
151
152
153
154
155
156
157
158
159
  #ifdef CONFIG_SUPPORT_EMMC_RPMB
  static int confirm_key_prog(void)
  {
  	puts("Warning: Programming authentication key can be done only once !
  "
  	     "         Use this command only if you are sure of what you are doing,
  "
  	     "Really perform the key programming? <y/N> ");
  	if (confirm_yesno())
ea6ebe217   Lei Wen   cmd_mmc: eliminat...
160
  		return 1;
1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
  
  	puts("Authentication key programming aborted
  ");
  	return 0;
  }
  static int do_mmcrpmb_key(cmd_tbl_t *cmdtp, int flag,
  			  int argc, char * const argv[])
  {
  	void *key_addr;
  	struct mmc *mmc = find_mmc_device(curr_device);
  
  	if (argc != 2)
  		return CMD_RET_USAGE;
  
  	key_addr = (void *)simple_strtoul(argv[1], NULL, 16);
  	if (!confirm_key_prog())
  		return CMD_RET_FAILURE;
  	if (mmc_rpmb_set_key(mmc, key_addr)) {
  		printf("ERROR - Key already programmed ?
  ");
  		return CMD_RET_FAILURE;
272cc70b2   Andy Fleming   Add MMC Framework
182
  	}
1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
183
  	return CMD_RET_SUCCESS;
272cc70b2   Andy Fleming   Add MMC Framework
184
  }
1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
185
186
187
188
189
190
191
192
  static int do_mmcrpmb_read(cmd_tbl_t *cmdtp, int flag,
  			   int argc, char * const argv[])
  {
  	u16 blk, cnt;
  	void *addr;
  	int n;
  	void *key_addr = NULL;
  	struct mmc *mmc = find_mmc_device(curr_device);
272cc70b2   Andy Fleming   Add MMC Framework
193

1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
194
195
  	if (argc < 4)
  		return CMD_RET_USAGE;
272cc70b2   Andy Fleming   Add MMC Framework
196

1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
  	addr = (void *)simple_strtoul(argv[1], NULL, 16);
  	blk = simple_strtoul(argv[2], NULL, 16);
  	cnt = simple_strtoul(argv[3], NULL, 16);
  
  	if (argc == 5)
  		key_addr = (void *)simple_strtoul(argv[4], NULL, 16);
  
  	printf("
  MMC RPMB read: dev # %d, block # %d, count %d ... ",
  	       curr_device, blk, cnt);
  	n =  mmc_rpmb_read(mmc, addr, blk, cnt, key_addr);
  
  	printf("%d RPMB blocks read: %s
  ", n, (n == cnt) ? "OK" : "ERROR");
  	if (n != cnt)
  		return CMD_RET_FAILURE;
  	return CMD_RET_SUCCESS;
  }
  static int do_mmcrpmb_write(cmd_tbl_t *cmdtp, int flag,
  			    int argc, char * const argv[])
272cc70b2   Andy Fleming   Add MMC Framework
217
  {
1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
218
219
220
221
222
  	u16 blk, cnt;
  	void *addr;
  	int n;
  	void *key_addr;
  	struct mmc *mmc = find_mmc_device(curr_device);
6be95ccf9   Lei Wen   MMC: unify mmc re...
223

1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
224
  	if (argc != 5)
4c12eeb8b   Simon Glass   Convert cmd_usage...
225
  		return CMD_RET_USAGE;
272cc70b2   Andy Fleming   Add MMC Framework
226

1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
  	addr = (void *)simple_strtoul(argv[1], NULL, 16);
  	blk = simple_strtoul(argv[2], NULL, 16);
  	cnt = simple_strtoul(argv[3], NULL, 16);
  	key_addr = (void *)simple_strtoul(argv[4], NULL, 16);
  
  	printf("
  MMC RPMB write: dev # %d, block # %d, count %d ... ",
  	       curr_device, blk, cnt);
  	n =  mmc_rpmb_write(mmc, addr, blk, cnt, key_addr);
  
  	printf("%d RPMB blocks written: %s
  ", n, (n == cnt) ? "OK" : "ERROR");
  	if (n != cnt)
  		return CMD_RET_FAILURE;
  	return CMD_RET_SUCCESS;
  }
  static int do_mmcrpmb_counter(cmd_tbl_t *cmdtp, int flag,
  			      int argc, char * const argv[])
  {
  	unsigned long counter;
  	struct mmc *mmc = find_mmc_device(curr_device);
  
  	if (mmc_rpmb_get_counter(mmc, &counter))
  		return CMD_RET_FAILURE;
  	printf("RPMB Write counter= %lx
  ", counter);
  	return CMD_RET_SUCCESS;
  }
  
  static cmd_tbl_t cmd_rpmb[] = {
  	U_BOOT_CMD_MKENT(key, 2, 0, do_mmcrpmb_key, "", ""),
  	U_BOOT_CMD_MKENT(read, 5, 1, do_mmcrpmb_read, "", ""),
  	U_BOOT_CMD_MKENT(write, 5, 0, do_mmcrpmb_write, "", ""),
  	U_BOOT_CMD_MKENT(counter, 1, 1, do_mmcrpmb_counter, "", ""),
  };
  
  static int do_mmcrpmb(cmd_tbl_t *cmdtp, int flag,
  		      int argc, char * const argv[])
  {
  	cmd_tbl_t *cp;
  	struct mmc *mmc;
  	char original_part;
  	int ret;
  
  	cp = find_cmd_tbl(argv[1], cmd_rpmb, ARRAY_SIZE(cmd_rpmb));
  
  	/* Drop the rpmb subcommand */
  	argc--;
  	argv++;
  
  	if (cp == NULL || argc > cp->maxargs)
  		return CMD_RET_USAGE;
  	if (flag == CMD_FLAG_REPEAT && !cp->repeatable)
  		return CMD_RET_SUCCESS;
1ae24a504   Stephen Warren   cmd_mmc: add forc...
281
  	mmc = init_mmc_device(curr_device, false);
1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
282
283
284
285
286
287
288
289
290
291
292
293
  	if (!mmc)
  		return CMD_RET_FAILURE;
  
  	if (!(mmc->version & MMC_VERSION_MMC)) {
  		printf("It is not a EMMC device
  ");
  		return CMD_RET_FAILURE;
  	}
  	if (mmc->version < MMC_VERSION_4_41) {
  		printf("RPMB not supported before version 4.41
  ");
  		return CMD_RET_FAILURE;
ea6ebe217   Lei Wen   cmd_mmc: eliminat...
294
  	}
1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
295
  	/* Switch to the RPMB partition */
4dc80c873   Kever Yang   mmc: use new hwpa...
296
  #ifndef CONFIG_BLK
b955e42ba   Marek Vasut   mmc: Fix error in...
297
  	original_part = mmc->block_dev.hwpart;
4dc80c873   Kever Yang   mmc: use new hwpa...
298
299
300
  #else
  	original_part = mmc_get_blk_desc(mmc)->hwpart;
  #endif
69f45cd53   Simon Glass   dm: mmc: Use the ...
301
302
  	if (blk_select_hwpart_devnum(IF_TYPE_MMC, curr_device, MMC_PART_RPMB) !=
  	    0)
873cc1d77   Stephen Warren   mmc: store hwpart...
303
  		return CMD_RET_FAILURE;
1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
304
  	ret = cp->cmd(cmdtp, flag, argc, argv);
272cc70b2   Andy Fleming   Add MMC Framework
305

1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
306
  	/* Return to original partition */
69f45cd53   Simon Glass   dm: mmc: Use the ...
307
308
  	if (blk_select_hwpart_devnum(IF_TYPE_MMC, curr_device, original_part) !=
  	    0)
873cc1d77   Stephen Warren   mmc: store hwpart...
309
  		return CMD_RET_FAILURE;
1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
310
311
312
  	return ret;
  }
  #endif
9fd383724   Stephen Warren   mmc: don't allow ...
313

1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
314
315
316
317
318
319
  static int do_mmc_read(cmd_tbl_t *cmdtp, int flag,
  		       int argc, char * const argv[])
  {
  	struct mmc *mmc;
  	u32 blk, cnt, n;
  	void *addr;
e85649c7e   Rabin Vincent   mmc: check find_m...
320

1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
321
322
  	if (argc != 4)
  		return CMD_RET_USAGE;
ea6ebe217   Lei Wen   cmd_mmc: eliminat...
323

1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
324
325
326
  	addr = (void *)simple_strtoul(argv[1], NULL, 16);
  	blk = simple_strtoul(argv[2], NULL, 16);
  	cnt = simple_strtoul(argv[3], NULL, 16);
272cc70b2   Andy Fleming   Add MMC Framework
327

1ae24a504   Stephen Warren   cmd_mmc: add forc...
328
  	mmc = init_mmc_device(curr_device, false);
1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
329
330
  	if (!mmc)
  		return CMD_RET_FAILURE;
ea6ebe217   Lei Wen   cmd_mmc: eliminat...
331

1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
332
333
334
  	printf("
  MMC read: dev # %d, block # %d, count %d ... ",
  	       curr_device, blk, cnt);
9fd383724   Stephen Warren   mmc: don't allow ...
335

c40fdca6b   Simon Glass   dm: mmc: Move the...
336
  	n = blk_dread(mmc_get_blk_desc(mmc), blk, cnt, addr);
1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
337
338
  	printf("%d blocks read: %s
  ", n, (n == cnt) ? "OK" : "ERROR");
8f3b96427   Lei Wen   mmc: print out pa...
339

1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
340
341
  	return (n == cnt) ? CMD_RET_SUCCESS : CMD_RET_FAILURE;
  }
e6fa5a546   Jean-Jacques Hiblot   mmc: compile out ...
342
343
  
  #if CONFIG_IS_ENABLED(MMC_WRITE)
1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
344
345
346
347
348
349
  static int do_mmc_write(cmd_tbl_t *cmdtp, int flag,
  			int argc, char * const argv[])
  {
  	struct mmc *mmc;
  	u32 blk, cnt, n;
  	void *addr;
8f3b96427   Lei Wen   mmc: print out pa...
350

1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
351
352
  	if (argc != 4)
  		return CMD_RET_USAGE;
272cc70b2   Andy Fleming   Add MMC Framework
353

1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
354
355
356
  	addr = (void *)simple_strtoul(argv[1], NULL, 16);
  	blk = simple_strtoul(argv[2], NULL, 16);
  	cnt = simple_strtoul(argv[3], NULL, 16);
bc897b1d4   Lei Wen   mmc: enable parti...
357

1ae24a504   Stephen Warren   cmd_mmc: add forc...
358
  	mmc = init_mmc_device(curr_device, false);
1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
359
360
  	if (!mmc)
  		return CMD_RET_FAILURE;
bc897b1d4   Lei Wen   mmc: enable parti...
361

1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
362
363
364
  	printf("
  MMC write: dev # %d, block # %d, count %d ... ",
  	       curr_device, blk, cnt);
272cc70b2   Andy Fleming   Add MMC Framework
365

1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
366
367
368
369
370
  	if (mmc_getwp(mmc) == 1) {
  		printf("Error: card is write protected!
  ");
  		return CMD_RET_FAILURE;
  	}
c40fdca6b   Simon Glass   dm: mmc: Move the...
371
  	n = blk_dwrite(mmc_get_blk_desc(mmc), blk, cnt, addr);
1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
372
373
  	printf("%d blocks written: %s
  ", n, (n == cnt) ? "OK" : "ERROR");
792970b0a   Tom Rini   cmd_mmc.c: Add 'p...
374

1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
375
376
377
378
379
380
381
  	return (n == cnt) ? CMD_RET_SUCCESS : CMD_RET_FAILURE;
  }
  static int do_mmc_erase(cmd_tbl_t *cmdtp, int flag,
  			int argc, char * const argv[])
  {
  	struct mmc *mmc;
  	u32 blk, cnt, n;
2a91c9134   Amar   COMMON: MMC: Comm...
382

1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
383
384
  	if (argc != 3)
  		return CMD_RET_USAGE;
792970b0a   Tom Rini   cmd_mmc.c: Add 'p...
385

1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
386
387
  	blk = simple_strtoul(argv[1], NULL, 16);
  	cnt = simple_strtoul(argv[2], NULL, 16);
5a99b9de1   Tom Rini   cmd_mmc.c: Add bo...
388

1ae24a504   Stephen Warren   cmd_mmc: add forc...
389
  	mmc = init_mmc_device(curr_device, false);
1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
390
391
  	if (!mmc)
  		return CMD_RET_FAILURE;
5a99b9de1   Tom Rini   cmd_mmc.c: Add bo...
392

1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
393
394
395
  	printf("
  MMC erase: dev # %d, block # %d, count %d ... ",
  	       curr_device, blk, cnt);
5a99b9de1   Tom Rini   cmd_mmc.c: Add bo...
396

1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
397
398
399
400
401
  	if (mmc_getwp(mmc) == 1) {
  		printf("Error: card is write protected!
  ");
  		return CMD_RET_FAILURE;
  	}
c40fdca6b   Simon Glass   dm: mmc: Move the...
402
  	n = blk_derase(mmc_get_blk_desc(mmc), blk, cnt);
1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
403
404
  	printf("%d blocks erased: %s
  ", n, (n == cnt) ? "OK" : "ERROR");
b01e6fe6c   Tom Rini   cmd_mmc.c: Change...
405

1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
406
407
  	return (n == cnt) ? CMD_RET_SUCCESS : CMD_RET_FAILURE;
  }
e6fa5a546   Jean-Jacques Hiblot   mmc: compile out ...
408
  #endif
1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
409
410
411
412
  static int do_mmc_rescan(cmd_tbl_t *cmdtp, int flag,
  			 int argc, char * const argv[])
  {
  	struct mmc *mmc;
2a91c9134   Amar   COMMON: MMC: Comm...
413

941944e44   Stephen Warren   cmd_mmc: Use init...
414
415
  	mmc = init_mmc_device(curr_device, true);
  	if (!mmc)
1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
416
  		return CMD_RET_FAILURE;
2a91c9134   Amar   COMMON: MMC: Comm...
417

1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
418
419
420
421
422
  	return CMD_RET_SUCCESS;
  }
  static int do_mmc_part(cmd_tbl_t *cmdtp, int flag,
  		       int argc, char * const argv[])
  {
4101f6879   Simon Glass   dm: Drop the bloc...
423
  	struct blk_desc *mmc_dev;
1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
424
  	struct mmc *mmc;
1ae24a504   Stephen Warren   cmd_mmc: add forc...
425
  	mmc = init_mmc_device(curr_device, false);
1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
426
427
  	if (!mmc)
  		return CMD_RET_FAILURE;
3c457f4d2   Simon Glass   dm: mmc: Drop the...
428
  	mmc_dev = blk_get_devnum_by_type(IF_TYPE_MMC, curr_device);
1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
429
  	if (mmc_dev != NULL && mmc_dev->type != DEV_TYPE_UNKNOWN) {
3e8bd4695   Simon Glass   dm: part: Rename ...
430
  		part_print(mmc_dev);
1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
431
432
433
434
435
436
437
438
439
440
  		return CMD_RET_SUCCESS;
  	}
  
  	puts("get mmc type error!
  ");
  	return CMD_RET_FAILURE;
  }
  static int do_mmc_dev(cmd_tbl_t *cmdtp, int flag,
  		      int argc, char * const argv[])
  {
60dc58f73   Stephen Warren   cmd_mmc: default ...
441
  	int dev, part = 0, ret;
1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
442
443
444
445
446
447
448
449
450
451
452
453
454
455
  	struct mmc *mmc;
  
  	if (argc == 1) {
  		dev = curr_device;
  	} else if (argc == 2) {
  		dev = simple_strtoul(argv[1], NULL, 10);
  	} else if (argc == 3) {
  		dev = (int)simple_strtoul(argv[1], NULL, 10);
  		part = (int)simple_strtoul(argv[2], NULL, 10);
  		if (part > PART_ACCESS_MASK) {
  			printf("#part_num shouldn't be larger than %d
  ",
  			       PART_ACCESS_MASK);
  			return CMD_RET_FAILURE;
33ace362f   Tom Rini   mmc: Add 'mmc rst...
456
  		}
1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
457
458
459
  	} else {
  		return CMD_RET_USAGE;
  	}
33ace362f   Tom Rini   mmc: Add 'mmc rst...
460

a5710920b   Stephen Warren   cmd_mmc: make mmc...
461
  	mmc = init_mmc_device(dev, true);
1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
462
463
  	if (!mmc)
  		return CMD_RET_FAILURE;
69f45cd53   Simon Glass   dm: mmc: Use the ...
464
  	ret = blk_select_hwpart_devnum(IF_TYPE_MMC, dev, part);
60dc58f73   Stephen Warren   cmd_mmc: default ...
465
466
467
468
469
  	printf("switch to partitions #%d, %s
  ",
  	       part, (!ret) ? "OK" : "ERROR");
  	if (ret)
  		return 1;
1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
470
471
472
473
474
475
476
  	curr_device = dev;
  	if (mmc->part_config == MMCPART_NOAVAILABLE)
  		printf("mmc%d is current device
  ", curr_device);
  	else
  		printf("mmc%d(part %d) is current device
  ",
c40fdca6b   Simon Glass   dm: mmc: Move the...
477
  		       curr_device, mmc_get_blk_desc(mmc)->hwpart);
33ace362f   Tom Rini   mmc: Add 'mmc rst...
478

1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
479
480
481
482
483
484
485
486
487
  	return CMD_RET_SUCCESS;
  }
  static int do_mmc_list(cmd_tbl_t *cmdtp, int flag,
  		       int argc, char * const argv[])
  {
  	print_mmc_devices('
  ');
  	return CMD_RET_SUCCESS;
  }
c599f53b5   Diego Santa Cruz   mmc: add mmc hwpa...
488

cf17789e0   Jean-Jacques Hiblot   mmc: make optiona...
489
  #if CONFIG_IS_ENABLED(MMC_HW_PARTITIONING)
189f963ac   Diego Santa Cruz   mmc: extend the m...
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
  static int parse_hwpart_user(struct mmc_hwpart_conf *pconf,
  			     int argc, char * const argv[])
  {
  	int i = 0;
  
  	memset(&pconf->user, 0, sizeof(pconf->user));
  
  	while (i < argc) {
  		if (!strcmp(argv[i], "enh")) {
  			if (i + 2 >= argc)
  				return -1;
  			pconf->user.enh_start =
  				simple_strtoul(argv[i+1], NULL, 10);
  			pconf->user.enh_size =
  				simple_strtoul(argv[i+2], NULL, 10);
  			i += 3;
  		} else if (!strcmp(argv[i], "wrrel")) {
  			if (i + 1 >= argc)
  				return -1;
  			pconf->user.wr_rel_change = 1;
  			if (!strcmp(argv[i+1], "on"))
  				pconf->user.wr_rel_set = 1;
  			else if (!strcmp(argv[i+1], "off"))
  				pconf->user.wr_rel_set = 0;
  			else
  				return -1;
  			i += 2;
  		} else {
  			break;
  		}
  	}
  	return i;
  }
  
  static int parse_hwpart_gp(struct mmc_hwpart_conf *pconf, int pidx,
  			   int argc, char * const argv[])
  {
  	int i;
  
  	memset(&pconf->gp_part[pidx], 0, sizeof(pconf->gp_part[pidx]));
  
  	if (1 >= argc)
  		return -1;
  	pconf->gp_part[pidx].size = simple_strtoul(argv[0], NULL, 10);
  
  	i = 1;
  	while (i < argc) {
  		if (!strcmp(argv[i], "enh")) {
  			pconf->gp_part[pidx].enhanced = 1;
  			i += 1;
  		} else if (!strcmp(argv[i], "wrrel")) {
  			if (i + 1 >= argc)
  				return -1;
  			pconf->gp_part[pidx].wr_rel_change = 1;
  			if (!strcmp(argv[i+1], "on"))
  				pconf->gp_part[pidx].wr_rel_set = 1;
  			else if (!strcmp(argv[i+1], "off"))
  				pconf->gp_part[pidx].wr_rel_set = 0;
  			else
  				return -1;
  			i += 2;
  		} else {
  			break;
  		}
  	}
  	return i;
  }
c599f53b5   Diego Santa Cruz   mmc: add mmc hwpa...
557
558
559
560
561
562
  static int do_mmc_hwpartition(cmd_tbl_t *cmdtp, int flag,
  			      int argc, char * const argv[])
  {
  	struct mmc *mmc;
  	struct mmc_hwpart_conf pconf = { };
  	enum mmc_hwpart_conf_mode mode = MMC_HWPART_CONF_CHECK;
189f963ac   Diego Santa Cruz   mmc: extend the m...
563
  	int i, r, pidx;
c599f53b5   Diego Santa Cruz   mmc: add mmc hwpa...
564
565
566
567
568
569
570
571
572
  
  	mmc = init_mmc_device(curr_device, false);
  	if (!mmc)
  		return CMD_RET_FAILURE;
  
  	if (argc < 1)
  		return CMD_RET_USAGE;
  	i = 1;
  	while (i < argc) {
189f963ac   Diego Santa Cruz   mmc: extend the m...
573
574
575
576
  		if (!strcmp(argv[i], "user")) {
  			i++;
  			r = parse_hwpart_user(&pconf, argc-i, &argv[i]);
  			if (r < 0)
c599f53b5   Diego Santa Cruz   mmc: add mmc hwpa...
577
  				return CMD_RET_USAGE;
189f963ac   Diego Santa Cruz   mmc: extend the m...
578
  			i += r;
c599f53b5   Diego Santa Cruz   mmc: add mmc hwpa...
579
580
581
  		} else if (!strncmp(argv[i], "gp", 2) &&
  			   strlen(argv[i]) == 3 &&
  			   argv[i][2] >= '1' && argv[i][2] <= '4') {
c599f53b5   Diego Santa Cruz   mmc: add mmc hwpa...
582
  			pidx = argv[i][2] - '1';
189f963ac   Diego Santa Cruz   mmc: extend the m...
583
584
585
586
587
  			i++;
  			r = parse_hwpart_gp(&pconf, pidx, argc-i, &argv[i]);
  			if (r < 0)
  				return CMD_RET_USAGE;
  			i += r;
c599f53b5   Diego Santa Cruz   mmc: add mmc hwpa...
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
  		} else if (!strcmp(argv[i], "check")) {
  			mode = MMC_HWPART_CONF_CHECK;
  			i++;
  		} else if (!strcmp(argv[i], "set")) {
  			mode = MMC_HWPART_CONF_SET;
  			i++;
  		} else if (!strcmp(argv[i], "complete")) {
  			mode = MMC_HWPART_CONF_COMPLETE;
  			i++;
  		} else {
  			return CMD_RET_USAGE;
  		}
  	}
  
  	puts("Partition configuration:
  ");
  	if (pconf.user.enh_size) {
  		puts("\tUser Enhanced Start: ");
  		print_size(((u64)pconf.user.enh_start) << 9, "
  ");
  		puts("\tUser Enhanced Size: ");
  		print_size(((u64)pconf.user.enh_size) << 9, "
  ");
  	} else {
  		puts("\tNo enhanced user data area
  ");
  	}
189f963ac   Diego Santa Cruz   mmc: extend the m...
615
616
617
618
  	if (pconf.user.wr_rel_change)
  		printf("\tUser partition write reliability: %s
  ",
  		       pconf.user.wr_rel_set ? "on" : "off");
c599f53b5   Diego Santa Cruz   mmc: add mmc hwpa...
619
620
621
622
623
624
625
626
627
628
629
630
  	for (pidx = 0; pidx < 4; pidx++) {
  		if (pconf.gp_part[pidx].size) {
  			printf("\tGP%i Capacity: ", pidx+1);
  			print_size(((u64)pconf.gp_part[pidx].size) << 9,
  				   pconf.gp_part[pidx].enhanced ?
  				   " ENH
  " : "
  ");
  		} else {
  			printf("\tNo GP%i partition
  ", pidx+1);
  		}
189f963ac   Diego Santa Cruz   mmc: extend the m...
631
632
633
634
  		if (pconf.gp_part[pidx].wr_rel_change)
  			printf("\tGP%i write reliability: %s
  ", pidx+1,
  			       pconf.gp_part[pidx].wr_rel_set ? "on" : "off");
c599f53b5   Diego Santa Cruz   mmc: add mmc hwpa...
635
636
637
638
639
640
641
642
643
  	}
  
  	if (!mmc_hwpart_config(mmc, &pconf, mode)) {
  		if (mode == MMC_HWPART_CONF_COMPLETE)
  			puts("Partitioning successful, "
  			     "power-cycle to make effective
  ");
  		return CMD_RET_SUCCESS;
  	} else {
189f963ac   Diego Santa Cruz   mmc: extend the m...
644
645
  		puts("Failed!
  ");
c599f53b5   Diego Santa Cruz   mmc: add mmc hwpa...
646
647
648
  		return CMD_RET_FAILURE;
  	}
  }
cf17789e0   Jean-Jacques Hiblot   mmc: make optiona...
649
  #endif
c599f53b5   Diego Santa Cruz   mmc: add mmc hwpa...
650

1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
651
652
653
654
655
656
657
658
659
660
661
662
663
664
  #ifdef CONFIG_SUPPORT_EMMC_BOOT
  static int do_mmc_bootbus(cmd_tbl_t *cmdtp, int flag,
  			  int argc, char * const argv[])
  {
  	int dev;
  	struct mmc *mmc;
  	u8 width, reset, mode;
  
  	if (argc != 5)
  		return CMD_RET_USAGE;
  	dev = simple_strtoul(argv[1], NULL, 10);
  	width = simple_strtoul(argv[2], NULL, 10);
  	reset = simple_strtoul(argv[3], NULL, 10);
  	mode = simple_strtoul(argv[4], NULL, 10);
1ae24a504   Stephen Warren   cmd_mmc: add forc...
665
  	mmc = init_mmc_device(dev, false);
1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
666
667
668
669
670
671
672
  	if (!mmc)
  		return CMD_RET_FAILURE;
  
  	if (IS_SD(mmc)) {
  		puts("BOOT_BUS_WIDTH only exists on eMMC
  ");
  		return CMD_RET_FAILURE;
2a91c9134   Amar   COMMON: MMC: Comm...
673
  	}
ab71188ce   Markus Niebel   mmc: add setdsr s...
674

1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
675
676
677
678
679
680
681
682
683
  	/* acknowledge to be sent during boot operation */
  	return mmc_set_boot_bus_width(mmc, width, reset, mode);
  }
  static int do_mmc_boot_resize(cmd_tbl_t *cmdtp, int flag,
  			      int argc, char * const argv[])
  {
  	int dev;
  	struct mmc *mmc;
  	u32 bootsize, rpmbsize;
ab71188ce   Markus Niebel   mmc: add setdsr s...
684

1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
685
686
687
688
689
  	if (argc != 4)
  		return CMD_RET_USAGE;
  	dev = simple_strtoul(argv[1], NULL, 10);
  	bootsize = simple_strtoul(argv[2], NULL, 10);
  	rpmbsize = simple_strtoul(argv[3], NULL, 10);
1ae24a504   Stephen Warren   cmd_mmc: add forc...
690
  	mmc = init_mmc_device(dev, false);
1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
691
692
693
694
695
696
697
  	if (!mmc)
  		return CMD_RET_FAILURE;
  
  	if (IS_SD(mmc)) {
  		printf("It is not a EMMC device
  ");
  		return CMD_RET_FAILURE;
ab71188ce   Markus Niebel   mmc: add setdsr s...
698
  	}
1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
699
700
701
702
703
  	if (mmc_boot_partition_size_change(mmc, bootsize, rpmbsize)) {
  		printf("EMMC boot partition Size change Failed.
  ");
  		return CMD_RET_FAILURE;
  	}
e85649c7e   Rabin Vincent   mmc: check find_m...
704

1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
705
706
707
708
709
710
  	printf("EMMC boot partition Size %d MB
  ", bootsize);
  	printf("EMMC RPMB partition Size %d MB
  ", rpmbsize);
  	return CMD_RET_SUCCESS;
  }
bdb609966   Angelo Dureghello   cmd: mmc: add mmc...
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
  
  static int mmc_partconf_print(struct mmc *mmc)
  {
  	u8 ack, access, part;
  
  	if (mmc->part_config == MMCPART_NOAVAILABLE) {
  		printf("No part_config info for ver. 0x%x
  ", mmc->version);
  		return CMD_RET_FAILURE;
  	}
  
  	access = EXT_CSD_EXTRACT_PARTITION_ACCESS(mmc->part_config);
  	ack = EXT_CSD_EXTRACT_BOOT_ACK(mmc->part_config);
  	part = EXT_CSD_EXTRACT_BOOT_PART(mmc->part_config);
  
  	printf("EXT_CSD[179], PARTITION_CONFIG:
  "
  		"BOOT_ACK: 0x%x
  "
  		"BOOT_PARTITION_ENABLE: 0x%x
  "
  		"PARTITION_ACCESS: 0x%x
  ", ack, part, access);
  
  	return CMD_RET_SUCCESS;
  }
1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
737
738
739
740
741
742
  static int do_mmc_partconf(cmd_tbl_t *cmdtp, int flag,
  			   int argc, char * const argv[])
  {
  	int dev;
  	struct mmc *mmc;
  	u8 ack, part_num, access;
272cc70b2   Andy Fleming   Add MMC Framework
743

bdb609966   Angelo Dureghello   cmd: mmc: add mmc...
744
  	if (argc != 2 && argc != 5)
1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
745
  		return CMD_RET_USAGE;
272cc70b2   Andy Fleming   Add MMC Framework
746

1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
747
  	dev = simple_strtoul(argv[1], NULL, 10);
d23d8d7e0   Nikita Kiryanov   mmc: add support ...
748

1ae24a504   Stephen Warren   cmd_mmc: add forc...
749
  	mmc = init_mmc_device(dev, false);
1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
750
751
752
753
754
755
756
757
  	if (!mmc)
  		return CMD_RET_FAILURE;
  
  	if (IS_SD(mmc)) {
  		puts("PARTITION_CONFIG only exists on eMMC
  ");
  		return CMD_RET_FAILURE;
  	}
bdb609966   Angelo Dureghello   cmd: mmc: add mmc...
758
759
760
761
762
763
  	if (argc == 2)
  		return mmc_partconf_print(mmc);
  
  	ack = simple_strtoul(argv[2], NULL, 10);
  	part_num = simple_strtoul(argv[3], NULL, 10);
  	access = simple_strtoul(argv[4], NULL, 10);
1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
  	/* acknowledge to be sent during boot operation */
  	return mmc_set_part_conf(mmc, ack, part_num, access);
  }
  static int do_mmc_rst_func(cmd_tbl_t *cmdtp, int flag,
  			   int argc, char * const argv[])
  {
  	int dev;
  	struct mmc *mmc;
  	u8 enable;
  
  	/*
  	 * Set the RST_n_ENABLE bit of RST_n_FUNCTION
  	 * The only valid values are 0x0, 0x1 and 0x2 and writing
  	 * a value of 0x1 or 0x2 sets the value permanently.
  	 */
  	if (argc != 3)
  		return CMD_RET_USAGE;
  
  	dev = simple_strtoul(argv[1], NULL, 10);
  	enable = simple_strtoul(argv[2], NULL, 10);
678e9316d   Peng Fan   common: mmc: unsi...
784
  	if (enable > 2) {
1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
785
786
787
788
  		puts("Invalid RST_n_ENABLE value
  ");
  		return CMD_RET_USAGE;
  	}
1ae24a504   Stephen Warren   cmd_mmc: add forc...
789
  	mmc = init_mmc_device(dev, false);
1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
790
791
792
793
794
795
796
797
  	if (!mmc)
  		return CMD_RET_FAILURE;
  
  	if (IS_SD(mmc)) {
  		puts("RST_n_FUNCTION only exists on eMMC
  ");
  		return CMD_RET_FAILURE;
  	}
272cc70b2   Andy Fleming   Add MMC Framework
798

1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
799
800
801
802
803
804
805
806
807
808
809
810
  	return mmc_set_rst_n_function(mmc, enable);
  }
  #endif
  static int do_mmc_setdsr(cmd_tbl_t *cmdtp, int flag,
  			 int argc, char * const argv[])
  {
  	struct mmc *mmc;
  	u32 val;
  	int ret;
  
  	if (argc != 2)
  		return CMD_RET_USAGE;
84c1dfe42   Markus Niebel   cmd_mmc: fix arg ...
811
  	val = simple_strtoul(argv[1], NULL, 16);
1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
  
  	mmc = find_mmc_device(curr_device);
  	if (!mmc) {
  		printf("no mmc device at slot %x
  ", curr_device);
  		return CMD_RET_FAILURE;
  	}
  	ret = mmc_set_dsr(mmc, val);
  	printf("set dsr %s
  ", (!ret) ? "OK, force rescan" : "ERROR");
  	if (!ret) {
  		mmc->has_init = 0;
  		if (mmc_init(mmc))
  			return CMD_RET_FAILURE;
  		else
  			return CMD_RET_SUCCESS;
272cc70b2   Andy Fleming   Add MMC Framework
828
  	}
1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
829
830
  	return ret;
  }
cd3d48807   Tomas Melin   mmc: add bkops-en...
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
  #ifdef CONFIG_CMD_BKOPS_ENABLE
  static int do_mmc_bkops_enable(cmd_tbl_t *cmdtp, int flag,
  				   int argc, char * const argv[])
  {
  	int dev;
  	struct mmc *mmc;
  
  	if (argc != 2)
  		return CMD_RET_USAGE;
  
  	dev = simple_strtoul(argv[1], NULL, 10);
  
  	mmc = init_mmc_device(dev, false);
  	if (!mmc)
  		return CMD_RET_FAILURE;
  
  	if (IS_SD(mmc)) {
  		puts("BKOPS_EN only exists on eMMC
  ");
  		return CMD_RET_FAILURE;
  	}
  
  	return mmc_set_bkops_enable(mmc);
  }
  #endif
1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
856
857
858
  static cmd_tbl_t cmd_mmc[] = {
  	U_BOOT_CMD_MKENT(info, 1, 0, do_mmcinfo, "", ""),
  	U_BOOT_CMD_MKENT(read, 4, 1, do_mmc_read, "", ""),
e6fa5a546   Jean-Jacques Hiblot   mmc: compile out ...
859
  #if CONFIG_IS_ENABLED(MMC_WRITE)
1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
860
861
  	U_BOOT_CMD_MKENT(write, 4, 0, do_mmc_write, "", ""),
  	U_BOOT_CMD_MKENT(erase, 3, 0, do_mmc_erase, "", ""),
e6fa5a546   Jean-Jacques Hiblot   mmc: compile out ...
862
  #endif
1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
863
864
865
866
  	U_BOOT_CMD_MKENT(rescan, 1, 1, do_mmc_rescan, "", ""),
  	U_BOOT_CMD_MKENT(part, 1, 1, do_mmc_part, "", ""),
  	U_BOOT_CMD_MKENT(dev, 3, 0, do_mmc_dev, "", ""),
  	U_BOOT_CMD_MKENT(list, 1, 1, do_mmc_list, "", ""),
cf17789e0   Jean-Jacques Hiblot   mmc: make optiona...
867
  #if CONFIG_IS_ENABLED(MMC_HW_PARTITIONING)
189f963ac   Diego Santa Cruz   mmc: extend the m...
868
  	U_BOOT_CMD_MKENT(hwpartition, 28, 0, do_mmc_hwpartition, "", ""),
cf17789e0   Jean-Jacques Hiblot   mmc: make optiona...
869
  #endif
1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
870
871
  #ifdef CONFIG_SUPPORT_EMMC_BOOT
  	U_BOOT_CMD_MKENT(bootbus, 5, 0, do_mmc_bootbus, "", ""),
fa7b88519   Wally Yeh   cmd_mmc: fix boot...
872
  	U_BOOT_CMD_MKENT(bootpart-resize, 4, 0, do_mmc_boot_resize, "", ""),
1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
873
874
875
876
877
878
879
  	U_BOOT_CMD_MKENT(partconf, 5, 0, do_mmc_partconf, "", ""),
  	U_BOOT_CMD_MKENT(rst-function, 3, 0, do_mmc_rst_func, "", ""),
  #endif
  #ifdef CONFIG_SUPPORT_EMMC_RPMB
  	U_BOOT_CMD_MKENT(rpmb, CONFIG_SYS_MAXARGS, 1, do_mmcrpmb, "", ""),
  #endif
  	U_BOOT_CMD_MKENT(setdsr, 2, 0, do_mmc_setdsr, "", ""),
cd3d48807   Tomas Melin   mmc: add bkops-en...
880
881
882
  #ifdef CONFIG_CMD_BKOPS_ENABLE
  	U_BOOT_CMD_MKENT(bkops-enable, 2, 0, do_mmc_bkops_enable, "", ""),
  #endif
1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
  };
  
  static int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
  {
  	cmd_tbl_t *cp;
  
  	cp = find_cmd_tbl(argv[1], cmd_mmc, ARRAY_SIZE(cmd_mmc));
  
  	/* Drop the mmc command */
  	argc--;
  	argv++;
  
  	if (cp == NULL || argc > cp->maxargs)
  		return CMD_RET_USAGE;
  	if (flag == CMD_FLAG_REPEAT && !cp->repeatable)
  		return CMD_RET_SUCCESS;
ea6ebe217   Lei Wen   cmd_mmc: eliminat...
899

1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
900
901
902
903
904
905
906
907
908
909
  	if (curr_device < 0) {
  		if (get_mmc_num() > 0) {
  			curr_device = 0;
  		} else {
  			puts("No MMC device available
  ");
  			return CMD_RET_FAILURE;
  		}
  	}
  	return cp->cmd(cmdtp, flag, argc, argv);
272cc70b2   Andy Fleming   Add MMC Framework
910
911
912
  }
  
  U_BOOT_CMD(
189f963ac   Diego Santa Cruz   mmc: extend the m...
913
  	mmc, 29, 1, do_mmcops,
852dbfdd5   Mike Frysinger   more command usag...
914
  	"MMC sub system",
1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
915
916
917
918
  	"info - display info of the current MMC device
  "
  	"mmc read addr blk# cnt
  "
ea6ebe217   Lei Wen   cmd_mmc: eliminat...
919
920
  	"mmc write addr blk# cnt
  "
e6f99a561   Lei Wen   MMC: add erase fu...
921
922
  	"mmc erase blk# cnt
  "
ea6ebe217   Lei Wen   cmd_mmc: eliminat...
923
924
925
926
  	"mmc rescan
  "
  	"mmc part - lists available partition on current mmc device
  "
bc897b1d4   Lei Wen   mmc: enable parti...
927
928
  	"mmc dev [dev] [part] - show or set current mmc device [partition]
  "
2a91c9134   Amar   COMMON: MMC: Comm...
929
930
  	"mmc list - lists available devices
  "
c599f53b5   Diego Santa Cruz   mmc: add mmc hwpa...
931
932
933
934
  	"mmc hwpartition [args...] - does hardware partitioning
  "
  	"  arguments (sizes in 512-byte blocks):
  "
189f963ac   Diego Santa Cruz   mmc: extend the m...
935
936
937
938
  	"    [user [enh start cnt] [wrrel {on|off}]] - sets user data area attributes
  "
  	"    [gp1|gp2|gp3|gp4 cnt [enh] [wrrel {on|off}]] - general purpose partition
  "
c599f53b5   Diego Santa Cruz   mmc: add mmc hwpa...
939
940
  	"    [check|set|complete] - mode, complete set partitioning completed
  "
189f963ac   Diego Santa Cruz   mmc: extend the m...
941
942
943
944
  	"  WARNING: Partitioning is a write-once setting once it is set to complete.
  "
  	"  Power cycling is required to initialize partitions after set to complete.
  "
2a91c9134   Amar   COMMON: MMC: Comm...
945
  #ifdef CONFIG_SUPPORT_EMMC_BOOT
5a99b9de1   Tom Rini   cmd_mmc.c: Add bo...
946
947
948
949
  	"mmc bootbus dev boot_bus_width reset_boot_bus_width boot_mode
  "
  	" - Set the BOOT_BUS_WIDTH field of the specified device
  "
f1fd957e1   Tom Rini   cmd_mmc.c: Rename...
950
951
952
953
  	"mmc bootpart-resize <dev> <boot part size MB> <RPMB part size MB>
  "
  	" - Change sizes of boot and RPMB partitions of specified device
  "
bdb609966   Angelo Dureghello   cmd: mmc: add mmc...
954
955
956
957
  	"mmc partconf dev [boot_ack boot_partition partition_access]
  "
  	" - Show or change the bits of the PARTITION_CONFIG field of the specified device
  "
33ace362f   Tom Rini   mmc: Add 'mmc rst...
958
959
960
961
962
963
  	"mmc rst-function dev value
  "
  	" - Change the RST_n_FUNCTION field of the specified device
  "
  	"   WARNING: This is a write-once field and 0 / 1 / 2 are the only valid values.
  "
3511b4e20   Dirk Behme   MMC: Don't use ne...
964
  #endif
1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
965
966
967
968
969
970
971
972
973
974
975
976
  #ifdef CONFIG_SUPPORT_EMMC_RPMB
  	"mmc rpmb read addr blk# cnt [address of auth-key] - block size is 256 bytes
  "
  	"mmc rpmb write addr blk# cnt <address of auth-key> - block size is 256 bytes
  "
  	"mmc rpmb key <address of auth-key> - program the RPMB authentication key.
  "
  	"mmc rpmb counter - read the value of the write counter
  "
  #endif
  	"mmc setdsr <value> - set DSR register value
  "
cd3d48807   Tomas Melin   mmc: add bkops-en...
977
978
979
980
981
982
  #ifdef CONFIG_CMD_BKOPS_ENABLE
  	"mmc bkops-enable <dev> - enable background operations handshake on device
  "
  	"   WARNING: This is a write-once setting.
  "
  #endif
2a91c9134   Amar   COMMON: MMC: Comm...
983
  	);
1fd93c6e7   Pierre Aubert   eMMC: cmd_mmc.c a...
984
985
986
987
988
989
990
  
  /* Old command kept for compatibility. Same as 'mmc info' */
  U_BOOT_CMD(
  	mmcinfo, 1, 0, do_mmcinfo,
  	"display MMC info",
  	"- display info of the current MMC device"
  );