drv_sdram.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. /*
  2. * Copyright 2017 NXP
  3. * All rights reserved.
  4. *
  5. * SPDX-License-Identifier: BSD-3-Clause
  6. */
  7. #include <rtthread.h>
  8. #ifdef BSP_USING_SDRAM
  9. #include "sdram_port.h"
  10. #include "board.h"
  11. #include "fsl_semc.h"
  12. #include "drv_sdram.h"
  13. //#define DBG_COLOR
  14. //#define DRV_DEBUG
  15. //#define LOG_TAG "drv.sdram"
  16. //#include <drv_log.h>
  17. #define DBG_ENABLE
  18. #define DBG_SECTION_NAME "[drv.sdram]"
  19. #define DBG_COLOR
  20. #define DBG_LEVEL DBG_INFO
  21. #include <rtdbg.h>
  22. #ifdef RT_USING_MEMHEAP
  23. static struct rt_memheap system_heap;
  24. #endif
  25. int rt_hw_sdram_init(void)
  26. {
  27. int result = RT_EOK;
  28. semc_config_t config;
  29. semc_sdram_config_t sdramconfig;
  30. #if defined(SOC_IMXRT1170_SERIES)
  31. rt_uint32_t clockFrq = CLOCK_GetRootClockFreq(kCLOCK_Root_Semc);
  32. #else
  33. rt_uint32_t clockFrq = CLOCK_GetFreq(kCLOCK_SemcClk);
  34. #endif
  35. /* Initializes the MAC configure structure to zero. */
  36. rt_memset(&config, 0, sizeof(semc_config_t));
  37. rt_memset(&sdramconfig, 0, sizeof(semc_sdram_config_t));
  38. /* Initialize SEMC. */
  39. SEMC_GetDefaultConfig(&config);
  40. config.dqsMode = kSEMC_Loopbackdqspad; /* For more accurate timing. */
  41. SEMC_Init(SEMC, &config);
  42. /* Configure SDRAM. */
  43. sdramconfig.csxPinMux = SDRAM_CS_PIN;
  44. sdramconfig.address = SDRAM_BANK_ADDR;
  45. sdramconfig.memsize_kbytes = SDRAM_SIZE;
  46. sdramconfig.portSize = SDRAM_DATA_WIDTH;
  47. sdramconfig.burstLen = kSEMC_Sdram_BurstLen8;
  48. sdramconfig.columnAddrBitNum = SDRAM_COLUMN_BITS;
  49. sdramconfig.casLatency = SDRAM_CAS_LATENCY;
  50. sdramconfig.tPrecharge2Act_Ns = SDRAM_TRP;
  51. sdramconfig.tAct2ReadWrite_Ns = SDRAM_TRCD;
  52. sdramconfig.tRefreshRecovery_Ns = SDRAM_REFRESH_RECOVERY;
  53. sdramconfig.tWriteRecovery_Ns = SDRAM_TWR;
  54. sdramconfig.tCkeOff_Ns = 42; /* The minimum cycle of SDRAM CLK off state. CKE is off in self refresh at a minimum period tRAS.*/
  55. sdramconfig.tAct2Prechage_Ns = SDRAM_TRAS;
  56. sdramconfig.tSelfRefRecovery_Ns = 67;
  57. sdramconfig.tRefresh2Refresh_Ns = SDRAM_TRC;
  58. sdramconfig.tAct2Act_Ns = SDRAM_ACT2ACT;
  59. sdramconfig.tPrescalePeriod_Ns = 160 * (1000000000 / clockFrq);
  60. sdramconfig.refreshPeriod_nsPerRow = SDRAM_REFRESH_ROW;
  61. sdramconfig.refreshUrgThreshold = sdramconfig.refreshPeriod_nsPerRow;
  62. sdramconfig.refreshBurstLen = 1;
  63. result = SEMC_ConfigureSDRAM(SEMC, SDRAM_REGION, &sdramconfig, clockFrq);
  64. if(result != kStatus_Success)
  65. {
  66. LOG_E("SDRAM init failed!");
  67. result = -RT_ERROR;
  68. }
  69. else
  70. {
  71. LOG_I("sdram init success, mapped at 0x%X, size is %d Kbytes.", SDRAM_BANK_ADDR, SDRAM_SIZE);
  72. #ifdef RT_USING_MEMHEAP
  73. /*
  74. * If RT_USING_MEMHEAP is enabled, SDRAM is initialized to the heap.
  75. * The heap start address is (base + half size), and the size is (half size - 2M).
  76. * The reasons are:
  77. * 1. Reserve the half space for SDRAM link case
  78. * 2. Reserve the 2M for non-cache space
  79. */
  80. rt_memheap_init(&system_heap, "sdram", (void *)(SDRAM_BANK_ADDR + (SDRAM_SIZE * 1024)/2),
  81. (SDRAM_SIZE * 1024)/2 - (2 * 1024 * 1024));
  82. #endif
  83. }
  84. return result;
  85. }
  86. INIT_PREV_EXPORT(rt_hw_sdram_init);
  87. #ifdef DBG_ENABLE
  88. #ifdef FINSH_USING_MSH
  89. #define SEMC_DATALEN (0x1000U)
  90. rt_uint32_t sdram_writeBuffer[SEMC_DATALEN];
  91. rt_uint32_t sdram_readBuffer[SEMC_DATALEN];
  92. /* read write 32bit test */
  93. static void sdram_test(void)
  94. {
  95. rt_uint32_t index;
  96. rt_uint32_t datalen = SEMC_DATALEN;
  97. rt_uint32_t *sdram = (rt_uint32_t *)SDRAM_BANK_ADDR; /* SDRAM start address. */
  98. bool result = true;
  99. LOG_D("SEMC SDRAM Memory 32 bit Write Start, Start Address 0x%x, Data Length %d !", sdram, datalen);
  100. /* Prepare data and write to SDRAM. */
  101. for (index = 0; index < datalen; index++)
  102. {
  103. sdram_writeBuffer[index] = index;
  104. sdram[index] = sdram_writeBuffer[index];
  105. }
  106. LOG_D("SEMC SDRAM Read 32 bit Data Start, Start Address 0x%x, Data Length %d !", sdram, datalen);
  107. /* Read data from the SDRAM. */
  108. for (index = 0; index < datalen; index++)
  109. {
  110. sdram_readBuffer[index] = sdram[index];
  111. }
  112. LOG_I("SEMC SDRAM 32 bit Data Write and Read Compare Start!");
  113. /* Compare the two buffers. */
  114. while (datalen--)
  115. {
  116. if (sdram_writeBuffer[datalen] != sdram_readBuffer[datalen])
  117. {
  118. result = false;
  119. break;
  120. }
  121. }
  122. if (!result)
  123. {
  124. LOG_E("SEMC SDRAM 32 bit Data Write and Read Compare Failed!");
  125. }
  126. else
  127. {
  128. LOG_I("SEMC SDRAM 32 bit Data Write and Read Compare Succeed!");
  129. }
  130. }
  131. MSH_CMD_EXPORT(sdram_test, sdram test)
  132. #endif /* DRV_DEBUG */
  133. #endif /* FINSH_USING_MSH */
  134. #endif /* BSP_USING_SDRAM */