hsdramc.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. /*
  2. * Copyright (C) 2005-2006 Atmel Corporation
  3. *
  4. * See file CREDITS for list of people who contributed to this
  5. * project.
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License as
  9. * published by the Free Software Foundation; either version 2 of
  10. * the License, or (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  20. * MA 02111-1307 USA
  21. */
  22. #include <common.h>
  23. #ifdef CFG_HSDRAMC
  24. #include <asm/io.h>
  25. #include <asm/sdram.h>
  26. #include <asm/arch/clk.h>
  27. #include <asm/arch/memory-map.h>
  28. #include "hsdramc1.h"
  29. unsigned long sdram_init(const struct sdram_info *info)
  30. {
  31. unsigned long *sdram = (unsigned long *)uncached(info->phys_addr);
  32. unsigned long sdram_size;
  33. unsigned long tmp;
  34. unsigned long bus_hz;
  35. unsigned int i;
  36. if (!info->refresh_period)
  37. panic("ERROR: SDRAM refresh period == 0. "
  38. "Please update the board code\n");
  39. tmp = (HSDRAMC1_BF(NC, info->col_bits - 8)
  40. | HSDRAMC1_BF(NR, info->row_bits - 11)
  41. | HSDRAMC1_BF(NB, info->bank_bits - 1)
  42. | HSDRAMC1_BF(CAS, info->cas)
  43. | HSDRAMC1_BF(TWR, info->twr)
  44. | HSDRAMC1_BF(TRC, info->trc)
  45. | HSDRAMC1_BF(TRP, info->trp)
  46. | HSDRAMC1_BF(TRCD, info->trcd)
  47. | HSDRAMC1_BF(TRAS, info->tras)
  48. | HSDRAMC1_BF(TXSR, info->txsr));
  49. #ifdef CFG_SDRAM_16BIT
  50. tmp |= HSDRAMC1_BIT(DBW);
  51. sdram_size = 1 << (info->row_bits + info->col_bits
  52. + info->bank_bits + 1);
  53. #else
  54. sdram_size = 1 << (info->row_bits + info->col_bits
  55. + info->bank_bits + 2);
  56. #endif
  57. hsdramc1_writel(CR, tmp);
  58. /*
  59. * Initialization sequence for SDRAM, from the data sheet:
  60. *
  61. * 1. A minimum pause of 200 us is provided to precede any
  62. * signal toggle.
  63. */
  64. udelay(200);
  65. /*
  66. * 2. A Precharge All command is issued to the SDRAM
  67. */
  68. hsdramc1_writel(MR, HSDRAMC1_MODE_BANKS_PRECHARGE);
  69. hsdramc1_readl(MR);
  70. writel(0, sdram);
  71. /*
  72. * 3. Eight auto-refresh (CBR) cycles are provided
  73. */
  74. hsdramc1_writel(MR, HSDRAMC1_MODE_AUTO_REFRESH);
  75. hsdramc1_readl(MR);
  76. for (i = 0; i < 8; i++)
  77. writel(0, sdram);
  78. /*
  79. * 4. A mode register set (MRS) cycle is issued to program
  80. * SDRAM parameters, in particular CAS latency and burst
  81. * length.
  82. *
  83. * CAS from info struct, burst length 1, serial burst type
  84. */
  85. hsdramc1_writel(MR, HSDRAMC1_MODE_LOAD_MODE);
  86. hsdramc1_readl(MR);
  87. writel(0, sdram + (info->cas << 4));
  88. /*
  89. * 5. A Normal Mode command is provided, 3 clocks after tMRD
  90. * is met.
  91. *
  92. * From the timing diagram, it looks like tMRD is 3
  93. * cycles...try a dummy read from the peripheral bus.
  94. */
  95. hsdramc1_readl(MR);
  96. hsdramc1_writel(MR, HSDRAMC1_MODE_NORMAL);
  97. hsdramc1_readl(MR);
  98. writel(0, sdram);
  99. /*
  100. * 6. Write refresh rate into SDRAMC refresh timer count
  101. * register (refresh rate = timing between refresh cycles).
  102. *
  103. * 15.6 us is a typical value for a burst of length one
  104. */
  105. bus_hz = get_sdram_clk_rate();
  106. hsdramc1_writel(TR, info->refresh_period);
  107. printf("SDRAM: %u MB at address 0x%08lx\n",
  108. sdram_size >> 20, info->phys_addr);
  109. printf("Testing SDRAM...");
  110. for (i = 0; i < sdram_size / 4; i++)
  111. sdram[i] = i;
  112. for (i = 0; i < sdram_size / 4; i++) {
  113. tmp = sdram[i];
  114. if (tmp != i) {
  115. printf("FAILED at address 0x%08lx\n",
  116. info->phys_addr + i * 4);
  117. printf("SDRAM: read 0x%lx, expected 0x%lx\n", tmp, i);
  118. return 0;
  119. }
  120. }
  121. puts("OK\n");
  122. return sdram_size;
  123. }
  124. #endif /* CFG_HSDRAMC */