emmc_read.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. /*
  2. * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. */
  6. #include <arch_helpers.h>
  7. #include "emmc_config.h"
  8. #include "emmc_def.h"
  9. #include "emmc_hal.h"
  10. #include "emmc_registers.h"
  11. #include "emmc_std.h"
  12. #define MIN_EMMC(a, b) (((a) < (b)) ? (a) : (b))
  13. #define EMMC_RW_SECTOR_COUNT_MAX 0x0000ffffU
  14. static EMMC_ERROR_CODE emmc_multiple_block_read(uint32_t *buff_address_virtual,
  15. uint32_t sector_number, uint32_t count,
  16. HAL_MEMCARD_DATA_TRANSFER_MODE transfer_mode)
  17. {
  18. EMMC_ERROR_CODE result;
  19. /* parameter check */
  20. if ((count > EMMC_RW_SECTOR_COUNT_MAX)
  21. || (count == 0)
  22. || ((transfer_mode != HAL_MEMCARD_DMA)
  23. && (transfer_mode != HAL_MEMCARD_NOT_DMA))
  24. ) {
  25. emmc_write_error_info(EMMC_FUNCNO_READ_SECTOR, EMMC_ERR_PARAM);
  26. return EMMC_ERR_PARAM;
  27. }
  28. /* CMD23 */
  29. emmc_make_nontrans_cmd(CMD23_SET_BLOCK_COUNT, count);
  30. result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
  31. if (result != EMMC_SUCCESS) {
  32. return result;
  33. }
  34. SETR_32(SD_SECCNT, count);
  35. SETR_32(SD_STOP, 0x00000100);
  36. /* SD_BUF Read/Write DMA Transfer enable */
  37. SETR_32(CC_EXT_MODE, (CC_EXT_MODE_CLEAR | CC_EXT_MODE_DMASDRW_ENABLE));
  38. /* CMD18 */
  39. emmc_make_trans_cmd(CMD18_READ_MULTIPLE_BLOCK, sector_number,
  40. buff_address_virtual,
  41. count << EMMC_SECTOR_SIZE_SHIFT, HAL_MEMCARD_READ,
  42. transfer_mode);
  43. result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
  44. if (result != EMMC_SUCCESS) {
  45. return result; /* CMD18 error code */
  46. }
  47. /* CMD13 */
  48. emmc_make_nontrans_cmd(CMD13_SEND_STATUS, EMMC_RCA << 16);
  49. result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
  50. if (result != EMMC_SUCCESS) {
  51. return result;
  52. }
  53. #if RCAR_BL2_DCACHE == 1
  54. if (transfer_mode == HAL_MEMCARD_NOT_DMA) {
  55. flush_dcache_range((uint64_t) buff_address_virtual,
  56. ((size_t) count << EMMC_SECTOR_SIZE_SHIFT));
  57. }
  58. #endif /* RCAR_BL2_DCACHE == 1 */
  59. /* ready status check */
  60. if ((mmc_drv_obj.r1_card_status & EMMC_R1_READY) == 0) {
  61. emmc_write_error_info(EMMC_FUNCNO_READ_SECTOR,
  62. EMMC_ERR_CARD_BUSY);
  63. return EMMC_ERR_CARD_BUSY;
  64. }
  65. /* state check */
  66. if (mmc_drv_obj.current_state != EMMC_R1_STATE_TRAN) {
  67. emmc_write_error_info(EMMC_FUNCNO_READ_SECTOR,
  68. EMMC_ERR_CARD_STATE);
  69. return EMMC_ERR_CARD_STATE;
  70. }
  71. return EMMC_SUCCESS;
  72. }
  73. EMMC_ERROR_CODE emmc_read_sector(uint32_t *buff_address_virtual,
  74. uint32_t sector_number,
  75. uint32_t count, uint32_t feature_flags)
  76. {
  77. uint32_t trans_count;
  78. uint32_t remain;
  79. EMMC_ERROR_CODE result;
  80. HAL_MEMCARD_DATA_TRANSFER_MODE transfer_mode;
  81. /* parameter check */
  82. if (count == 0) {
  83. emmc_write_error_info(EMMC_FUNCNO_READ_SECTOR, EMMC_ERR_PARAM);
  84. return EMMC_ERR_PARAM;
  85. }
  86. /* state check */
  87. if (mmc_drv_obj.mount != TRUE) {
  88. emmc_write_error_info(EMMC_FUNCNO_READ_SECTOR, EMMC_ERR_STATE);
  89. return EMMC_ERR_STATE;
  90. }
  91. /* DMA? */
  92. if ((feature_flags & LOADIMAGE_FLAGS_DMA_ENABLE) != 0) {
  93. transfer_mode = HAL_MEMCARD_DMA;
  94. } else {
  95. transfer_mode = HAL_MEMCARD_NOT_DMA;
  96. }
  97. remain = count;
  98. while (remain != 0) {
  99. trans_count = MIN_EMMC(remain, EMMC_RW_SECTOR_COUNT_MAX);
  100. result =
  101. emmc_multiple_block_read(buff_address_virtual,
  102. sector_number, trans_count,
  103. transfer_mode);
  104. if (result != EMMC_SUCCESS) {
  105. return result;
  106. }
  107. buff_address_virtual += (EMMC_BLOCK_LENGTH_DW * trans_count);
  108. sector_number += trans_count;
  109. remain -= trans_count;
  110. }
  111. return EMMC_SUCCESS;
  112. }