mmc_boot.c 3.1 KB

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