stm32f7_sdram.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. /*
  2. *
  3. * Modified from unicore-mx SDRAM support
  4. *
  5. * Copyright (C) 2014 Chuck McManis <cmcmanis@mcmanis.com>
  6. * Copyright (C) 2016 Maxime Vincent <maxime.vince@gmail.com>
  7. * Copyright (C) 2016-2023 Daniele Lacamera <root@danielinux.net>
  8. *
  9. * This program is free software: you can redistribute it and/or modify
  10. * it under the terms of the GNU Lesser General Public License as published by
  11. * the Free Software Foundation, either version 3 of the License, or
  12. * (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public License
  20. * along with this library. If not, see <http://www.gnu.org/licenses/>.
  21. */
  22. /*
  23. * Original authors:
  24. * Maxime Vincent <maxime.vince@gmail.com>
  25. * Chuck McManis <cmcmanis@mcmanis.com>
  26. * Daniele Lacamera <root@danielinux.net>
  27. *
  28. *
  29. */
  30. #include <stdint.h>
  31. #include <unicore-mx/stm32/gpio.h>
  32. #include <unicore-mx/stm32/rcc.h>
  33. #include <unicore-mx/stm32/fsmc.h>
  34. extern volatile uint32_t jiffies;
  35. #define SDRAM_BASE_ADDRESS ((uint8_t *)(0xC0000000))
  36. /*
  37. * This is just syntactic sugar but it helps, all of these
  38. * GPIO pins get configured in exactly the same way.
  39. */
  40. static const struct {
  41. uint32_t gpio;
  42. uint16_t pins;
  43. } sdram_pins[6] = {
  44. {GPIOC, GPIO3 },
  45. {GPIOD, GPIO0 | GPIO1 | GPIO3 | GPIO8 | GPIO9 | GPIO10 | GPIO14 | GPIO15},
  46. {GPIOE, GPIO0 | GPIO1 | GPIO7 | GPIO8 | GPIO9 | GPIO10 |
  47. GPIO11 | GPIO12 | GPIO13 | GPIO14 | GPIO15 },
  48. {GPIOF, GPIO0 | GPIO1 | GPIO2 | GPIO3 | GPIO4 | GPIO5 | GPIO11 |
  49. GPIO12 | GPIO13 | GPIO14 | GPIO15 },
  50. {GPIOG, GPIO0 | GPIO1 | GPIO4 | GPIO5 | GPIO8 | GPIO15},
  51. {GPIOH, GPIO3 | GPIO5 }
  52. };
  53. static struct sdram_timing timing = {
  54. .trcd = 2, /* RCD Delay */
  55. .trp = 2, /* RP Delay */
  56. .twr = 2, /* Write Recovery Time */
  57. .trc = 7, /* Row Cycle Delay */
  58. .tras = 4, /* Self Refresh Time */
  59. .txsr = 7, /* Exit Self Refresh Time */
  60. .tmrd = 2, /* Load to Active Delay */
  61. };
  62. /*
  63. * Initialize the SD RAM controller.
  64. */
  65. void sdram_init(void)
  66. {
  67. int i, now;
  68. uint32_t cr_tmp, tr_tmp; /* control, timing registers */
  69. /*
  70. * First all the GPIO pins that end up as SDRAM pins
  71. */
  72. rcc_periph_clock_enable(RCC_GPIOC);
  73. rcc_periph_clock_enable(RCC_GPIOD);
  74. rcc_periph_clock_enable(RCC_GPIOE);
  75. rcc_periph_clock_enable(RCC_GPIOF);
  76. rcc_periph_clock_enable(RCC_GPIOG);
  77. rcc_periph_clock_enable(RCC_GPIOH);
  78. for (i = 0; i < 6; i++) {
  79. gpio_mode_setup(sdram_pins[i].gpio,
  80. GPIO_MODE_AF, GPIO_PUPD_NONE,
  81. sdram_pins[i].pins);
  82. gpio_set_output_options(sdram_pins[i].gpio, GPIO_OTYPE_PP,
  83. GPIO_OSPEED_100MHZ, sdram_pins[i].pins);
  84. gpio_set_af(sdram_pins[i].gpio, GPIO_AF12, sdram_pins[i].pins);
  85. }
  86. /* Enable the SDRAM Controller */
  87. #if 1
  88. rcc_periph_clock_enable(RCC_FMC);
  89. #else
  90. rcc_peripheral_enable_clock(&RCC_AHB3ENR, RCC_AHB3ENR_FMCEN);
  91. #endif
  92. /* Note the STM32F746G-DISCO board has the ram attached to bank 1 */
  93. /* Timing parameters computed for a ~200 MHz clock */
  94. /* These parameters are specific to the SDRAM chip on the board */
  95. cr_tmp = FMC_SDCR_RPIPE_NONE;
  96. cr_tmp |= FMC_SDCR_SDCLK_2HCLK;
  97. cr_tmp |= FMC_SDCR_CAS_2CYC;
  98. cr_tmp |= FMC_SDCR_NB4;
  99. cr_tmp |= FMC_SDCR_MWID_16b;
  100. cr_tmp |= FMC_SDCR_NR_12;
  101. cr_tmp |= FMC_SDCR_NC_8;
  102. /* We're programming BANK 1
  103. * Per the manual some of the parameters only work in CR1 and TR1
  104. * So when using BANK2: we need pull those off and put them in the right place.
  105. * FMC_SDCR1 |= (cr_tmp); // & FMC_SDCR_DNC_MASK);
  106. * FMC_SDCR2 = cr_tmp;
  107. */
  108. FMC_SDCR1 = (cr_tmp);
  109. tr_tmp = sdram_timing(&timing);
  110. FMC_SDTR1 = (tr_tmp);
  111. /* Now start up the Controller per the manual
  112. * - Clock config enable
  113. * - PALL state
  114. * - set auto refresh
  115. * - Load the Mode Register
  116. */
  117. sdram_command(SDRAM_BANK1, SDRAM_CLK_CONF, 1, 0);
  118. /* sleep at least 100uS */
  119. now = jiffies;
  120. //while (now + 2 > jiffies) {};
  121. sdram_command(SDRAM_BANK1, SDRAM_PALL, 1, 0);
  122. sdram_command(SDRAM_BANK1, SDRAM_AUTO_REFRESH, 8, 0);
  123. tr_tmp = SDRAM_MODE_BURST_LENGTH_1 |
  124. SDRAM_MODE_BURST_TYPE_SEQUENTIAL |
  125. SDRAM_MODE_CAS_LATENCY_2 |
  126. SDRAM_MODE_OPERATING_MODE_STANDARD |
  127. SDRAM_MODE_WRITEBURST_MODE_SINGLE;
  128. sdram_command(SDRAM_BANK1, SDRAM_LOAD_MODE, 1, tr_tmp);
  129. /*
  130. * set the refresh counter to insure we kick off an
  131. * auto refresh often enough to prevent data loss.
  132. */
  133. FMC_SDRTR = ((uint32_t)0x0603); /* SDRAM refresh counter (100Mhz SD clock) */
  134. /* and Poof! a 8 megabytes of ram shows up in the address space */
  135. /* Disable write protection */
  136. FMC_SDCR1 &= ~FMC_SDCR_WP_ENABLE;
  137. }