hsdramc.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  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. tmp = (HSDRAMC1_BF(NC, info->col_bits - 8)
  37. | HSDRAMC1_BF(NR, info->row_bits - 11)
  38. | HSDRAMC1_BF(NB, info->bank_bits - 1)
  39. | HSDRAMC1_BF(CAS, info->cas)
  40. | HSDRAMC1_BF(TWR, info->twr)
  41. | HSDRAMC1_BF(TRC, info->trc)
  42. | HSDRAMC1_BF(TRP, info->trp)
  43. | HSDRAMC1_BF(TRCD, info->trcd)
  44. | HSDRAMC1_BF(TRAS, info->tras)
  45. | HSDRAMC1_BF(TXSR, info->txsr));
  46. #ifdef CFG_SDRAM_16BIT
  47. tmp |= HSDRAMC1_BIT(DBW);
  48. sdram_size = 1 << (info->row_bits + info->col_bits
  49. + info->bank_bits + 1);
  50. #else
  51. sdram_size = 1 << (info->row_bits + info->col_bits
  52. + info->bank_bits + 2);
  53. #endif
  54. hsdramc1_writel(CR, tmp);
  55. /*
  56. * Initialization sequence for SDRAM, from the data sheet:
  57. *
  58. * 1. A minimum pause of 200 us is provided to precede any
  59. * signal toggle.
  60. */
  61. udelay(200);
  62. /*
  63. * 2. A Precharge All command is issued to the SDRAM
  64. */
  65. hsdramc1_writel(MR, HSDRAMC1_MODE_BANKS_PRECHARGE);
  66. hsdramc1_readl(MR);
  67. writel(0, sdram);
  68. /*
  69. * 3. Eight auto-refresh (CBR) cycles are provided
  70. */
  71. hsdramc1_writel(MR, HSDRAMC1_MODE_AUTO_REFRESH);
  72. hsdramc1_readl(MR);
  73. for (i = 0; i < 8; i++)
  74. writel(0, sdram);
  75. /*
  76. * 4. A mode register set (MRS) cycle is issued to program
  77. * SDRAM parameters, in particular CAS latency and burst
  78. * length.
  79. *
  80. * CAS from info struct, burst length 1, serial burst type
  81. */
  82. hsdramc1_writel(MR, HSDRAMC1_MODE_LOAD_MODE);
  83. hsdramc1_readl(MR);
  84. writel(0, sdram + (info->cas << 4));
  85. /*
  86. * 5. A Normal Mode command is provided, 3 clocks after tMRD
  87. * is met.
  88. *
  89. * From the timing diagram, it looks like tMRD is 3
  90. * cycles...try a dummy read from the peripheral bus.
  91. */
  92. hsdramc1_readl(MR);
  93. hsdramc1_writel(MR, HSDRAMC1_MODE_NORMAL);
  94. hsdramc1_readl(MR);
  95. writel(0, sdram);
  96. /*
  97. * 6. Write refresh rate into SDRAMC refresh timer count
  98. * register (refresh rate = timing between refresh cycles).
  99. *
  100. * 15.6 us is a typical value for a burst of length one
  101. */
  102. bus_hz = get_sdram_clk_rate();
  103. hsdramc1_writel(TR, (156 * (bus_hz / 1000)) / 10000);
  104. printf("SDRAM: %u MB at address 0x%08lx\n",
  105. sdram_size >> 20, info->phys_addr);
  106. printf("Testing SDRAM...");
  107. for (i = 0; i < sdram_size / 4; i++)
  108. sdram[i] = i;
  109. for (i = 0; i < sdram_size / 4; i++) {
  110. tmp = sdram[i];
  111. if (tmp != i) {
  112. printf("FAILED at address 0x%08lx\n",
  113. info->phys_addr + i * 4);
  114. printf("SDRAM: read 0x%lx, expected 0x%lx\n", tmp, i);
  115. return 0;
  116. }
  117. }
  118. puts("OK\n");
  119. return sdram_size;
  120. }
  121. #endif /* CFG_HSDRAMC */