mmc_boot.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (C) 2016 Google, Inc
  4. * Written by Amar <amarendra.xt@samsung.com>
  5. */
  6. #include <common.h>
  7. #include <mmc.h>
  8. #include "mmc_private.h"
  9. /*
  10. * This function changes the size of boot partition and the size of rpmb
  11. * partition present on EMMC devices.
  12. *
  13. * Input Parameters:
  14. * struct *mmc: pointer for the mmc device strcuture
  15. * bootsize: size of boot partition
  16. * rpmbsize: size of rpmb partition
  17. *
  18. * Returns 0 on success.
  19. */
  20. int mmc_boot_partition_size_change(struct mmc *mmc, unsigned long bootsize,
  21. unsigned long rpmbsize)
  22. {
  23. int err;
  24. struct mmc_cmd cmd;
  25. /* Only use this command for raw EMMC moviNAND. Enter backdoor mode */
  26. cmd.cmdidx = MMC_CMD_RES_MAN;
  27. cmd.resp_type = MMC_RSP_R1b;
  28. cmd.cmdarg = MMC_CMD62_ARG1;
  29. err = mmc_send_cmd(mmc, &cmd, NULL);
  30. if (err) {
  31. debug("mmc_boot_partition_size_change: Error1 = %d\n", err);
  32. return err;
  33. }
  34. /* Boot partition changing mode */
  35. cmd.cmdidx = MMC_CMD_RES_MAN;
  36. cmd.resp_type = MMC_RSP_R1b;
  37. cmd.cmdarg = MMC_CMD62_ARG2;
  38. err = mmc_send_cmd(mmc, &cmd, NULL);
  39. if (err) {
  40. debug("mmc_boot_partition_size_change: Error2 = %d\n", err);
  41. return err;
  42. }
  43. /* boot partition size is multiple of 128KB */
  44. bootsize = (bootsize * 1024) / 128;
  45. /* Arg: boot partition size */
  46. cmd.cmdidx = MMC_CMD_RES_MAN;
  47. cmd.resp_type = MMC_RSP_R1b;
  48. cmd.cmdarg = bootsize;
  49. err = mmc_send_cmd(mmc, &cmd, NULL);
  50. if (err) {
  51. debug("mmc_boot_partition_size_change: Error3 = %d\n", err);
  52. return err;
  53. }
  54. /* RPMB partition size is multiple of 128KB */
  55. rpmbsize = (rpmbsize * 1024) / 128;
  56. /* Arg: RPMB partition size */
  57. cmd.cmdidx = MMC_CMD_RES_MAN;
  58. cmd.resp_type = MMC_RSP_R1b;
  59. cmd.cmdarg = rpmbsize;
  60. err = mmc_send_cmd(mmc, &cmd, NULL);
  61. if (err) {
  62. debug("mmc_boot_partition_size_change: Error4 = %d\n", err);
  63. return err;
  64. }
  65. return 0;
  66. }
  67. /*
  68. * Modify EXT_CSD[177] which is BOOT_BUS_WIDTH
  69. * based on the passed in values for BOOT_BUS_WIDTH, RESET_BOOT_BUS_WIDTH
  70. * and BOOT_MODE.
  71. *
  72. * Returns 0 on success.
  73. */
  74. int mmc_set_boot_bus_width(struct mmc *mmc, u8 width, u8 reset, u8 mode)
  75. {
  76. return mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BOOT_BUS_WIDTH,
  77. EXT_CSD_BOOT_BUS_WIDTH_MODE(mode) |
  78. EXT_CSD_BOOT_BUS_WIDTH_RESET(reset) |
  79. EXT_CSD_BOOT_BUS_WIDTH_WIDTH(width));
  80. }
  81. /*
  82. * Modify EXT_CSD[179] which is PARTITION_CONFIG (formerly BOOT_CONFIG)
  83. * based on the passed in values for BOOT_ACK, BOOT_PARTITION_ENABLE and
  84. * PARTITION_ACCESS.
  85. *
  86. * Returns 0 on success.
  87. */
  88. int mmc_set_part_conf(struct mmc *mmc, u8 ack, u8 part_num, u8 access)
  89. {
  90. int ret;
  91. u8 part_conf;
  92. part_conf = EXT_CSD_BOOT_ACK(ack) |
  93. EXT_CSD_BOOT_PART_NUM(part_num) |
  94. EXT_CSD_PARTITION_ACCESS(access);
  95. ret = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF,
  96. part_conf);
  97. if (!ret)
  98. mmc->part_config = part_conf;
  99. return ret;
  100. }
  101. /*
  102. * Modify EXT_CSD[162] which is RST_n_FUNCTION based on the given value
  103. * for enable. Note that this is a write-once field for non-zero values.
  104. *
  105. * Returns 0 on success.
  106. */
  107. int mmc_set_rst_n_function(struct mmc *mmc, u8 enable)
  108. {
  109. return mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_RST_N_FUNCTION,
  110. enable);
  111. }