morello_bl2_setup.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. /*
  2. * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. */
  6. #include <common/debug.h>
  7. #include <drivers/arm/css/sds.h>
  8. #include <lib/mmio.h>
  9. #include <lib/utils.h>
  10. #include <plat/arm/common/plat_arm.h>
  11. #include "morello_def.h"
  12. #include <platform_def.h>
  13. #ifdef TARGET_PLATFORM_SOC
  14. /*
  15. * Morello platform supports RDIMMs with ECC capability. To use the ECC
  16. * capability, the entire DDR memory space has to be zeroed out before
  17. * enabling the ECC bits in DMC-Bing. Zeroing out several gigabytes of
  18. * memory from SCP is quite time consuming so the following function
  19. * is added to zero out the DDR memory from application processor which is
  20. * much faster compared to SCP.
  21. */
  22. static void dmc_ecc_setup(struct morello_plat_info *plat_info)
  23. {
  24. uint64_t dram2_size;
  25. uint32_t val;
  26. uint64_t tag_mem_base;
  27. uint64_t usable_mem_size;
  28. INFO("Total DIMM size: %uGB\n",
  29. (uint32_t)(plat_info->local_ddr_size / 0x40000000));
  30. assert(plat_info->local_ddr_size > ARM_DRAM1_SIZE);
  31. dram2_size = plat_info->local_ddr_size - ARM_DRAM1_SIZE;
  32. INFO("Zeroing DDR memory range 0x80000000 - 0xFFFFFFFF\n");
  33. zero_normalmem((void *)ARM_DRAM1_BASE, ARM_DRAM1_SIZE);
  34. flush_dcache_range(ARM_DRAM1_BASE, ARM_DRAM1_SIZE);
  35. INFO("Zeroing DDR memory range 0x%llx - 0x%llx\n",
  36. ARM_DRAM2_BASE, ARM_DRAM2_BASE + dram2_size);
  37. zero_normalmem((void *)ARM_DRAM2_BASE, dram2_size);
  38. flush_dcache_range(ARM_DRAM2_BASE, dram2_size);
  39. /* Clear previous ECC errors while zeroing out the memory */
  40. val = mmio_read_32(MORELLO_DMC0_ERR2STATUS_REG);
  41. mmio_write_32(MORELLO_DMC0_ERR2STATUS_REG, val);
  42. val = mmio_read_32(MORELLO_DMC1_ERR2STATUS_REG);
  43. mmio_write_32(MORELLO_DMC1_ERR2STATUS_REG, val);
  44. /* Set DMCs to CONFIG state before writing ERR0CTLR0 register */
  45. mmio_write_32(MORELLO_DMC0_MEMC_CMD_REG, MORELLO_DMC_MEMC_CMD_CONFIG);
  46. mmio_write_32(MORELLO_DMC1_MEMC_CMD_REG, MORELLO_DMC_MEMC_CMD_CONFIG);
  47. while ((mmio_read_32(MORELLO_DMC0_MEMC_STATUS_REG) &
  48. MORELLO_DMC_MEMC_STATUS_MASK) !=
  49. MORELLO_DMC_MEMC_CMD_CONFIG) {
  50. continue;
  51. }
  52. while ((mmio_read_32(MORELLO_DMC1_MEMC_STATUS_REG) &
  53. MORELLO_DMC_MEMC_STATUS_MASK) !=
  54. MORELLO_DMC_MEMC_CMD_CONFIG) {
  55. continue;
  56. }
  57. /* Configure Bing client/server mode based on SCC configuration */
  58. if (plat_info->scc_config & MORELLO_SCC_CLIENT_MODE_MASK) {
  59. INFO("Configuring DMC Bing in client mode\n");
  60. usable_mem_size = plat_info->local_ddr_size -
  61. (plat_info->local_ddr_size / 128ULL);
  62. /* Linear DDR address */
  63. tag_mem_base = usable_mem_size;
  64. tag_mem_base = tag_mem_base / 4;
  65. /* Reverse translation */
  66. if (tag_mem_base < ARM_DRAM1_BASE) {
  67. tag_mem_base += ARM_DRAM1_BASE;
  68. } else {
  69. tag_mem_base = tag_mem_base - ARM_DRAM1_BASE +
  70. ARM_DRAM2_BASE;
  71. }
  72. mmio_write_32(MORELLO_DMC0_CAP_CTRL_REG, 0x1);
  73. mmio_write_32(MORELLO_DMC1_CAP_CTRL_REG, 0x1);
  74. mmio_write_32(MORELLO_DMC0_TAG_CACHE_CFG, 0x1);
  75. mmio_write_32(MORELLO_DMC1_TAG_CACHE_CFG, 0x1);
  76. if (plat_info->scc_config & MORELLO_SCC_C1_TAG_CACHE_EN_MASK) {
  77. mmio_setbits_32(MORELLO_DMC0_TAG_CACHE_CFG, 0x2);
  78. mmio_setbits_32(MORELLO_DMC1_TAG_CACHE_CFG, 0x2);
  79. INFO("C1 Tag Cache Enabled\n");
  80. }
  81. if (plat_info->scc_config & MORELLO_SCC_C2_TAG_CACHE_EN_MASK) {
  82. mmio_setbits_32(MORELLO_DMC0_TAG_CACHE_CFG, 0x4);
  83. mmio_setbits_32(MORELLO_DMC1_TAG_CACHE_CFG, 0x4);
  84. INFO("C2 Tag Cache Enabled\n");
  85. }
  86. mmio_write_32(MORELLO_DMC0_MEM_ADDR_CTL,
  87. (uint32_t)tag_mem_base);
  88. mmio_write_32(MORELLO_DMC1_MEM_ADDR_CTL,
  89. (uint32_t)tag_mem_base);
  90. mmio_write_32(MORELLO_DMC0_MEM_ADDR_CTL2,
  91. (uint32_t)(tag_mem_base >> 32));
  92. mmio_write_32(MORELLO_DMC1_MEM_ADDR_CTL2,
  93. (uint32_t)(tag_mem_base >> 32));
  94. mmio_setbits_32(MORELLO_DMC0_MEM_ACCESS_CTL,
  95. MORELLO_DMC_MEM_ACCESS_DIS);
  96. mmio_setbits_32(MORELLO_DMC1_MEM_ACCESS_CTL,
  97. MORELLO_DMC_MEM_ACCESS_DIS);
  98. INFO("Tag base set to 0x%lx\n", tag_mem_base);
  99. plat_info->local_ddr_size = usable_mem_size;
  100. } else {
  101. INFO("Configuring DMC Bing in server mode\n");
  102. mmio_write_32(MORELLO_DMC0_CAP_CTRL_REG, 0x0);
  103. mmio_write_32(MORELLO_DMC1_CAP_CTRL_REG, 0x0);
  104. }
  105. INFO("Enabling ECC on DMCs\n");
  106. /* Enable ECC in DMCs */
  107. mmio_setbits_32(MORELLO_DMC0_ERR0CTLR0_REG,
  108. MORELLO_DMC_ERR0CTLR0_ECC_EN);
  109. mmio_setbits_32(MORELLO_DMC1_ERR0CTLR0_REG,
  110. MORELLO_DMC_ERR0CTLR0_ECC_EN);
  111. /* Set DMCs to READY state */
  112. mmio_write_32(MORELLO_DMC0_MEMC_CMD_REG, MORELLO_DMC_MEMC_CMD_READY);
  113. mmio_write_32(MORELLO_DMC1_MEMC_CMD_REG, MORELLO_DMC_MEMC_CMD_READY);
  114. while ((mmio_read_32(MORELLO_DMC0_MEMC_STATUS_REG) &
  115. MORELLO_DMC_MEMC_STATUS_MASK) !=
  116. MORELLO_DMC_MEMC_CMD_READY) {
  117. continue;
  118. }
  119. while ((mmio_read_32(MORELLO_DMC1_MEMC_STATUS_REG) &
  120. MORELLO_DMC_MEMC_STATUS_MASK) !=
  121. MORELLO_DMC_MEMC_CMD_READY) {
  122. continue;
  123. }
  124. }
  125. #endif
  126. void bl2_platform_setup(void)
  127. {
  128. int ret;
  129. struct morello_plat_info plat_info;
  130. ret = sds_init(SDS_SCP_AP_REGION_ID);
  131. if (ret != SDS_OK) {
  132. ERROR("SDS initialization failed. ret:%d\n", ret);
  133. panic();
  134. }
  135. ret = sds_struct_read(SDS_SCP_AP_REGION_ID,
  136. MORELLO_SDS_PLATFORM_INFO_STRUCT_ID,
  137. MORELLO_SDS_PLATFORM_INFO_OFFSET,
  138. &plat_info,
  139. MORELLO_SDS_PLATFORM_INFO_SIZE,
  140. SDS_ACCESS_MODE_NON_CACHED);
  141. if (ret != SDS_OK) {
  142. ERROR("Error getting platform info from SDS. ret:%d\n", ret);
  143. panic();
  144. }
  145. /* Validate plat_info SDS */
  146. #ifdef TARGET_PLATFORM_FVP
  147. if (plat_info.local_ddr_size == 0U) {
  148. #else
  149. if ((plat_info.local_ddr_size == 0U)
  150. || (plat_info.local_ddr_size > MORELLO_MAX_DDR_CAPACITY)
  151. || (plat_info.remote_ddr_size > MORELLO_MAX_DDR_CAPACITY)
  152. || (plat_info.remote_chip_count > MORELLO_MAX_REMOTE_CHIP_COUNT)
  153. ) {
  154. #endif
  155. ERROR("platform info SDS is corrupted\n");
  156. panic();
  157. }
  158. #ifdef TARGET_PLATFORM_SOC
  159. dmc_ecc_setup(&plat_info);
  160. #endif
  161. arm_bl2_platform_setup();
  162. }