sdrc.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. /*
  2. * Functions related to OMAP3 SDRC.
  3. *
  4. * This file has been created after exctracting and consolidating
  5. * the SDRC related content from mem.c and board.c, also created
  6. * generic init function (mem_init).
  7. *
  8. * Copyright (C) 2004-2010
  9. * Texas Instruments Incorporated - http://www.ti.com/
  10. *
  11. * Copyright (C) 2011
  12. * Corscience GmbH & Co. KG - Simon Schwarz <schwarz@corscience.de>
  13. *
  14. * Author :
  15. * Vaibhav Hiremath <hvaibhav@ti.com>
  16. *
  17. * Original implementation by (mem.c, board.c) :
  18. * Sunil Kumar <sunilsaini05@gmail.com>
  19. * Shashi Ranjan <shashiranjanmca05@gmail.com>
  20. * Manikandan Pillai <mani.pillai@ti.com>
  21. *
  22. * This program is free software; you can redistribute it and/or
  23. * modify it under the terms of the GNU General Public License as
  24. * published by the Free Software Foundation; either version 2 of
  25. * the License, or (at your option) any later version.
  26. *
  27. * This program is distributed in the hope that it will be useful,
  28. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  29. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  30. * GNU General Public License for more details.
  31. *
  32. * You should have received a copy of the GNU General Public License
  33. * along with this program; if not, write to the Free Software
  34. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  35. * MA 02111-1307 USA
  36. */
  37. #include <common.h>
  38. #include <asm/io.h>
  39. #include <asm/arch/mem.h>
  40. #include <asm/arch/sys_proto.h>
  41. DECLARE_GLOBAL_DATA_PTR;
  42. extern omap3_sysinfo sysinfo;
  43. static struct sdrc *sdrc_base = (struct sdrc *)OMAP34XX_SDRC_BASE;
  44. /*
  45. * is_mem_sdr -
  46. * - Return 1 if mem type in use is SDR
  47. */
  48. u32 is_mem_sdr(void)
  49. {
  50. if (readl(&sdrc_base->cs[CS0].mr) == SDRC_MR_0_SDR)
  51. return 1;
  52. return 0;
  53. }
  54. /*
  55. * make_cs1_contiguous -
  56. * - When we have CS1 populated we want to have it mapped after cs0 to allow
  57. * command line mem=xyz use all memory with out discontinuous support
  58. * compiled in. We could do it in the ATAG, but there really is two banks...
  59. */
  60. void make_cs1_contiguous(void)
  61. {
  62. u32 size, a_add_low, a_add_high;
  63. size = get_sdr_cs_size(CS0);
  64. size >>= 25; /* divide by 32 MiB to find size to offset CS1 */
  65. a_add_high = (size & 3) << 8; /* set up low field */
  66. a_add_low = (size & 0x3C) >> 2; /* set up high field */
  67. writel((a_add_high | a_add_low), &sdrc_base->cs_cfg);
  68. }
  69. /*
  70. * get_sdr_cs_size -
  71. * - Get size of chip select 0/1
  72. */
  73. u32 get_sdr_cs_size(u32 cs)
  74. {
  75. u32 size;
  76. /* get ram size field */
  77. size = readl(&sdrc_base->cs[cs].mcfg) >> 8;
  78. size &= 0x3FF; /* remove unwanted bits */
  79. size <<= 21; /* multiply by 2 MiB to find size in MB */
  80. return size;
  81. }
  82. /*
  83. * get_sdr_cs_offset -
  84. * - Get offset of cs from cs0 start
  85. */
  86. u32 get_sdr_cs_offset(u32 cs)
  87. {
  88. u32 offset;
  89. if (!cs)
  90. return 0;
  91. offset = readl(&sdrc_base->cs_cfg);
  92. offset = (offset & 15) << 27 | (offset & 0x300) << 17;
  93. return offset;
  94. }
  95. /*
  96. * write_sdrc_timings -
  97. * - Takes CS and associated timings and initalize SDRAM
  98. * - Test CS to make sure it's OK for use
  99. */
  100. static void write_sdrc_timings(u32 cs, struct sdrc_actim *sdrc_actim_base,
  101. struct board_sdrc_timings *timings)
  102. {
  103. /* Setup timings we got from the board. */
  104. writel(timings->mcfg, &sdrc_base->cs[cs].mcfg);
  105. writel(timings->ctrla, &sdrc_actim_base->ctrla);
  106. writel(timings->ctrlb, &sdrc_actim_base->ctrlb);
  107. writel(timings->rfr_ctrl, &sdrc_base->cs[cs].rfr_ctrl);
  108. writel(CMD_NOP, &sdrc_base->cs[cs].manual);
  109. writel(CMD_PRECHARGE, &sdrc_base->cs[cs].manual);
  110. writel(CMD_AUTOREFRESH, &sdrc_base->cs[cs].manual);
  111. writel(CMD_AUTOREFRESH, &sdrc_base->cs[cs].manual);
  112. writel(timings->mr, &sdrc_base->cs[cs].mr);
  113. /*
  114. * Test ram in this bank
  115. * Disable if bad or not present
  116. */
  117. if (!mem_ok(cs))
  118. writel(0, &sdrc_base->cs[cs].mcfg);
  119. }
  120. /*
  121. * do_sdrc_init -
  122. * - Code called once in C-Stack only context for CS0 and with early being
  123. * true and a possible 2nd time depending on memory configuration from
  124. * stack+global context.
  125. */
  126. void do_sdrc_init(u32 cs, u32 early)
  127. {
  128. struct sdrc_actim *sdrc_actim_base0, *sdrc_actim_base1;
  129. struct board_sdrc_timings timings;
  130. sdrc_actim_base0 = (struct sdrc_actim *)SDRC_ACTIM_CTRL0_BASE;
  131. sdrc_actim_base1 = (struct sdrc_actim *)SDRC_ACTIM_CTRL1_BASE;
  132. /*
  133. * When called in the early context this may be SPL and we will
  134. * need to set all of the timings. This ends up being board
  135. * specific so we call a helper function to take care of this
  136. * for us. Otherwise, to be safe, we need to copy the settings
  137. * from the first bank to the second. We will setup CS0,
  138. * then set cs_cfg to the appropriate value then try and
  139. * setup CS1.
  140. */
  141. #ifdef CONFIG_SPL_BUILD
  142. get_board_mem_timings(&timings);
  143. #endif
  144. if (early) {
  145. /* reset sdrc controller */
  146. writel(SOFTRESET, &sdrc_base->sysconfig);
  147. wait_on_value(RESETDONE, RESETDONE, &sdrc_base->status,
  148. 12000000);
  149. writel(0, &sdrc_base->sysconfig);
  150. /* setup sdrc to ball mux */
  151. writel(SDRC_SHARING, &sdrc_base->sharing);
  152. /* Disable Power Down of CKE because of 1 CKE on combo part */
  153. writel(WAKEUPPROC | SRFRONRESET | PAGEPOLICY_HIGH,
  154. &sdrc_base->power);
  155. writel(ENADLL | DLLPHASE_90, &sdrc_base->dlla_ctrl);
  156. sdelay(0x20000);
  157. #ifdef CONFIG_SPL_BUILD
  158. write_sdrc_timings(CS0, sdrc_actim_base0, &timings);
  159. make_cs1_contiguous();
  160. write_sdrc_timings(CS1, sdrc_actim_base1, &timings);
  161. #endif
  162. }
  163. /*
  164. * If we aren't using SPL we have been loaded by some
  165. * other means which may not have correctly initialized
  166. * both CS0 and CS1 (such as some older versions of x-loader)
  167. * so we may be asked now to setup CS1.
  168. */
  169. if (cs == CS1) {
  170. timings.mcfg = readl(&sdrc_base->cs[CS0].mcfg),
  171. timings.rfr_ctrl = readl(&sdrc_base->cs[CS0].rfr_ctrl);
  172. timings.ctrla = readl(&sdrc_actim_base0->ctrla);
  173. timings.ctrlb = readl(&sdrc_actim_base0->ctrlb);
  174. timings.mr = readl(&sdrc_base->cs[CS0].mr);
  175. write_sdrc_timings(cs, sdrc_actim_base1, &timings);
  176. }
  177. }
  178. /*
  179. * dram_init -
  180. * - Sets uboots idea of sdram size
  181. */
  182. int dram_init(void)
  183. {
  184. unsigned int size0 = 0, size1 = 0;
  185. size0 = get_sdr_cs_size(CS0);
  186. /*
  187. * We always need to have cs_cfg point at where the second
  188. * bank would be, if present. Failure to do so can lead to
  189. * strange situations where memory isn't detected and
  190. * configured correctly. CS0 will already have been setup
  191. * at this point.
  192. */
  193. make_cs1_contiguous();
  194. do_sdrc_init(CS1, NOT_EARLY);
  195. size1 = get_sdr_cs_size(CS1);
  196. gd->ram_size = size0 + size1;
  197. return 0;
  198. }
  199. void dram_init_banksize (void)
  200. {
  201. unsigned int size0 = 0, size1 = 0;
  202. size0 = get_sdr_cs_size(CS0);
  203. size1 = get_sdr_cs_size(CS1);
  204. gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
  205. gd->bd->bi_dram[0].size = size0;
  206. gd->bd->bi_dram[1].start = PHYS_SDRAM_1 + get_sdr_cs_offset(CS1);
  207. gd->bd->bi_dram[1].size = size1;
  208. }
  209. /*
  210. * mem_init -
  211. * - Init the sdrc chip,
  212. * - Selects CS0 and CS1,
  213. */
  214. void mem_init(void)
  215. {
  216. /* only init up first bank here */
  217. do_sdrc_init(CS0, EARLY_INIT);
  218. }