Commit 3690d6d66b8f2d33402ce7c0f0478c8075885291
Committed by
Minkyu Kang
1 parent
752f4c4a9c
Exists in
master
and in
53 other branches
MMC: APIs to support resize of EMMC boot partition
This patch adds APIs to access(open / close) and to resize boot partiton of EMMC. Signed-off-by: Amar <amarendra.xt@samsung.com> Signed-off-by: Minkyu Kang <mk7.kang@samsung.com>
Showing 2 changed files with 160 additions and 0 deletions Side-by-side Diff
drivers/mmc/mmc.c
... | ... | @@ -1374,4 +1374,138 @@ |
1374 | 1374 | |
1375 | 1375 | return 0; |
1376 | 1376 | } |
1377 | + | |
1378 | +#ifdef CONFIG_SUPPORT_EMMC_BOOT | |
1379 | +/* | |
1380 | + * This function changes the size of boot partition and the size of rpmb | |
1381 | + * partition present on EMMC devices. | |
1382 | + * | |
1383 | + * Input Parameters: | |
1384 | + * struct *mmc: pointer for the mmc device strcuture | |
1385 | + * bootsize: size of boot partition | |
1386 | + * rpmbsize: size of rpmb partition | |
1387 | + * | |
1388 | + * Returns 0 on success. | |
1389 | + */ | |
1390 | + | |
1391 | +int mmc_boot_partition_size_change(struct mmc *mmc, unsigned long bootsize, | |
1392 | + unsigned long rpmbsize) | |
1393 | +{ | |
1394 | + int err; | |
1395 | + struct mmc_cmd cmd; | |
1396 | + | |
1397 | + /* Only use this command for raw EMMC moviNAND. Enter backdoor mode */ | |
1398 | + cmd.cmdidx = MMC_CMD_RES_MAN; | |
1399 | + cmd.resp_type = MMC_RSP_R1b; | |
1400 | + cmd.cmdarg = MMC_CMD62_ARG1; | |
1401 | + | |
1402 | + err = mmc_send_cmd(mmc, &cmd, NULL); | |
1403 | + if (err) { | |
1404 | + debug("mmc_boot_partition_size_change: Error1 = %d\n", err); | |
1405 | + return err; | |
1406 | + } | |
1407 | + | |
1408 | + /* Boot partition changing mode */ | |
1409 | + cmd.cmdidx = MMC_CMD_RES_MAN; | |
1410 | + cmd.resp_type = MMC_RSP_R1b; | |
1411 | + cmd.cmdarg = MMC_CMD62_ARG2; | |
1412 | + | |
1413 | + err = mmc_send_cmd(mmc, &cmd, NULL); | |
1414 | + if (err) { | |
1415 | + debug("mmc_boot_partition_size_change: Error2 = %d\n", err); | |
1416 | + return err; | |
1417 | + } | |
1418 | + /* boot partition size is multiple of 128KB */ | |
1419 | + bootsize = (bootsize * 1024) / 128; | |
1420 | + | |
1421 | + /* Arg: boot partition size */ | |
1422 | + cmd.cmdidx = MMC_CMD_RES_MAN; | |
1423 | + cmd.resp_type = MMC_RSP_R1b; | |
1424 | + cmd.cmdarg = bootsize; | |
1425 | + | |
1426 | + err = mmc_send_cmd(mmc, &cmd, NULL); | |
1427 | + if (err) { | |
1428 | + debug("mmc_boot_partition_size_change: Error3 = %d\n", err); | |
1429 | + return err; | |
1430 | + } | |
1431 | + /* RPMB partition size is multiple of 128KB */ | |
1432 | + rpmbsize = (rpmbsize * 1024) / 128; | |
1433 | + /* Arg: RPMB partition size */ | |
1434 | + cmd.cmdidx = MMC_CMD_RES_MAN; | |
1435 | + cmd.resp_type = MMC_RSP_R1b; | |
1436 | + cmd.cmdarg = rpmbsize; | |
1437 | + | |
1438 | + err = mmc_send_cmd(mmc, &cmd, NULL); | |
1439 | + if (err) { | |
1440 | + debug("mmc_boot_partition_size_change: Error4 = %d\n", err); | |
1441 | + return err; | |
1442 | + } | |
1443 | + return 0; | |
1444 | +} | |
1445 | + | |
1446 | +/* | |
1447 | + * This function shall form and send the commands to open / close the | |
1448 | + * boot partition specified by user. | |
1449 | + * | |
1450 | + * Input Parameters: | |
1451 | + * ack: 0x0 - No boot acknowledge sent (default) | |
1452 | + * 0x1 - Boot acknowledge sent during boot operation | |
1453 | + * part_num: User selects boot data that will be sent to master | |
1454 | + * 0x0 - Device not boot enabled (default) | |
1455 | + * 0x1 - Boot partition 1 enabled for boot | |
1456 | + * 0x2 - Boot partition 2 enabled for boot | |
1457 | + * access: User selects partitions to access | |
1458 | + * 0x0 : No access to boot partition (default) | |
1459 | + * 0x1 : R/W boot partition 1 | |
1460 | + * 0x2 : R/W boot partition 2 | |
1461 | + * 0x3 : R/W Replay Protected Memory Block (RPMB) | |
1462 | + * | |
1463 | + * Returns 0 on success. | |
1464 | + */ | |
1465 | +int mmc_boot_part_access(struct mmc *mmc, u8 ack, u8 part_num, u8 access) | |
1466 | +{ | |
1467 | + int err; | |
1468 | + struct mmc_cmd cmd; | |
1469 | + | |
1470 | + /* Boot ack enable, boot partition enable , boot partition access */ | |
1471 | + cmd.cmdidx = MMC_CMD_SWITCH; | |
1472 | + cmd.resp_type = MMC_RSP_R1b; | |
1473 | + | |
1474 | + cmd.cmdarg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) | | |
1475 | + (EXT_CSD_PART_CONF << 16) | | |
1476 | + ((EXT_CSD_BOOT_ACK(ack) | | |
1477 | + EXT_CSD_BOOT_PART_NUM(part_num) | | |
1478 | + EXT_CSD_PARTITION_ACCESS(access)) << 8); | |
1479 | + | |
1480 | + err = mmc_send_cmd(mmc, &cmd, NULL); | |
1481 | + if (err) { | |
1482 | + if (access) { | |
1483 | + debug("mmc boot partition#%d open fail:Error1 = %d\n", | |
1484 | + part_num, err); | |
1485 | + } else { | |
1486 | + debug("mmc boot partition#%d close fail:Error = %d\n", | |
1487 | + part_num, err); | |
1488 | + } | |
1489 | + return err; | |
1490 | + } | |
1491 | + | |
1492 | + if (access) { | |
1493 | + /* 4bit transfer mode at booting time. */ | |
1494 | + cmd.cmdidx = MMC_CMD_SWITCH; | |
1495 | + cmd.resp_type = MMC_RSP_R1b; | |
1496 | + | |
1497 | + cmd.cmdarg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) | | |
1498 | + (EXT_CSD_BOOT_BUS_WIDTH << 16) | | |
1499 | + ((1 << 0) << 8); | |
1500 | + | |
1501 | + err = mmc_send_cmd(mmc, &cmd, NULL); | |
1502 | + if (err) { | |
1503 | + debug("mmc boot partition#%d open fail:Error2 = %d\n", | |
1504 | + part_num, err); | |
1505 | + return err; | |
1506 | + } | |
1507 | + } | |
1508 | + return 0; | |
1509 | +} | |
1510 | +#endif |
include/mmc.h
... | ... | @@ -92,7 +92,12 @@ |
92 | 92 | #define MMC_CMD_APP_CMD 55 |
93 | 93 | #define MMC_CMD_SPI_READ_OCR 58 |
94 | 94 | #define MMC_CMD_SPI_CRC_ON_OFF 59 |
95 | +#define MMC_CMD_RES_MAN 62 | |
95 | 96 | |
97 | +#define MMC_CMD62_ARG1 0xefac62ec | |
98 | +#define MMC_CMD62_ARG2 0xcbaea7 | |
99 | + | |
100 | + | |
96 | 101 | #define SD_CMD_SEND_RELATIVE_ADDR 3 |
97 | 102 | #define SD_CMD_SWITCH_FUNC 6 |
98 | 103 | #define SD_CMD_SEND_IF_COND 8 |
... | ... | @@ -159,6 +164,7 @@ |
159 | 164 | */ |
160 | 165 | #define EXT_CSD_PARTITIONING_SUPPORT 160 /* RO */ |
161 | 166 | #define EXT_CSD_ERASE_GROUP_DEF 175 /* R/W */ |
167 | +#define EXT_CSD_BOOT_BUS_WIDTH 177 | |
162 | 168 | #define EXT_CSD_PART_CONF 179 /* R/W */ |
163 | 169 | #define EXT_CSD_BUS_WIDTH 183 /* R/W */ |
164 | 170 | #define EXT_CSD_HS_TIMING 185 /* R/W */ |
... | ... | @@ -183,6 +189,16 @@ |
183 | 189 | #define EXT_CSD_BUS_WIDTH_4 1 /* Card is in 4 bit mode */ |
184 | 190 | #define EXT_CSD_BUS_WIDTH_8 2 /* Card is in 8 bit mode */ |
185 | 191 | |
192 | +#define EXT_CSD_BOOT_ACK_ENABLE (1 << 6) | |
193 | +#define EXT_CSD_BOOT_PARTITION_ENABLE (1 << 3) | |
194 | +#define EXT_CSD_PARTITION_ACCESS_ENABLE (1 << 0) | |
195 | +#define EXT_CSD_PARTITION_ACCESS_DISABLE (0 << 0) | |
196 | + | |
197 | +#define EXT_CSD_BOOT_ACK(x) (x << 6) | |
198 | +#define EXT_CSD_BOOT_PART_NUM(x) (x << 3) | |
199 | +#define EXT_CSD_PARTITION_ACCESS(x) (x << 0) | |
200 | + | |
201 | + | |
186 | 202 | #define R1_ILLEGAL_COMMAND (1 << 22) |
187 | 203 | #define R1_APP_CMD (1 << 5) |
188 | 204 | |
... | ... | @@ -210,6 +226,11 @@ |
210 | 226 | /* Maximum block size for MMC */ |
211 | 227 | #define MMC_MAX_BLOCK_LEN 512 |
212 | 228 | |
229 | +/* The number of MMC physical partitions. These consist of: | |
230 | + * boot partitions (2), general purpose partitions (4) in MMC v4.4. | |
231 | + */ | |
232 | +#define MMC_NUM_BOOT_PARTITION 2 | |
233 | + | |
213 | 234 | struct mmc_cid { |
214 | 235 | unsigned long psn; |
215 | 236 | unsigned short oid; |
... | ... | @@ -286,6 +307,11 @@ |
286 | 307 | int mmc_getcd(struct mmc *mmc); |
287 | 308 | int mmc_getwp(struct mmc *mmc); |
288 | 309 | void spl_mmc_load(void) __noreturn; |
310 | +/* Function to change the size of boot partition and rpmb partitions */ | |
311 | +int mmc_boot_partition_size_change(struct mmc *mmc, unsigned long bootsize, | |
312 | + unsigned long rpmbsize); | |
313 | +/* Function to send commands to open/close the specified boot partition */ | |
314 | +int mmc_boot_part_access(struct mmc *mmc, u8 ack, u8 part_num, u8 access); | |
289 | 315 | |
290 | 316 | #ifdef CONFIG_GENERIC_MMC |
291 | 317 | #define mmc_host_is_spi(mmc) ((mmc)->host_caps & MMC_MODE_SPI) |