dram.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. /*
  2. * (C) Copyright 2009
  3. * Marvell Semiconductor <www.marvell.com>
  4. * Written-by: Prafulla Wadaskar <prafulla@marvell.com>
  5. *
  6. * SPDX-License-Identifier: GPL-2.0+
  7. */
  8. #include <config.h>
  9. #include <common.h>
  10. #include <asm/io.h>
  11. #include <asm/arch/cpu.h>
  12. #include <asm/arch/soc.h>
  13. DECLARE_GLOBAL_DATA_PTR;
  14. struct sdram_bank {
  15. u32 win_bar;
  16. u32 win_sz;
  17. };
  18. struct sdram_addr_dec {
  19. struct sdram_bank sdram_bank[4];
  20. };
  21. #define REG_CPUCS_WIN_ENABLE (1 << 0)
  22. #define REG_CPUCS_WIN_WR_PROTECT (1 << 1)
  23. #define REG_CPUCS_WIN_WIN0_CS(x) (((x) & 0x3) << 2)
  24. #define REG_CPUCS_WIN_SIZE(x) (((x) & 0xff) << 24)
  25. /*
  26. * mvebu_sdram_bar - reads SDRAM Base Address Register
  27. */
  28. u32 mvebu_sdram_bar(enum memory_bank bank)
  29. {
  30. struct sdram_addr_dec *base =
  31. (struct sdram_addr_dec *)MVEBU_SDRAM_BASE;
  32. u32 result = 0;
  33. u32 enable = 0x01 & readl(&base->sdram_bank[bank].win_sz);
  34. if ((!enable) || (bank > BANK3))
  35. return 0;
  36. result = readl(&base->sdram_bank[bank].win_bar);
  37. return result;
  38. }
  39. /*
  40. * mvebu_sdram_bs_set - writes SDRAM Bank size
  41. */
  42. static void mvebu_sdram_bs_set(enum memory_bank bank, u32 size)
  43. {
  44. struct sdram_addr_dec *base =
  45. (struct sdram_addr_dec *)MVEBU_SDRAM_BASE;
  46. /* Read current register value */
  47. u32 reg = readl(&base->sdram_bank[bank].win_sz);
  48. /* Clear window size */
  49. reg &= ~REG_CPUCS_WIN_SIZE(0xFF);
  50. /* Set new window size */
  51. reg |= REG_CPUCS_WIN_SIZE((size - 1) >> 24);
  52. writel(reg, &base->sdram_bank[bank].win_sz);
  53. }
  54. /*
  55. * mvebu_sdram_bs - reads SDRAM Bank size
  56. */
  57. u32 mvebu_sdram_bs(enum memory_bank bank)
  58. {
  59. struct sdram_addr_dec *base =
  60. (struct sdram_addr_dec *)MVEBU_SDRAM_BASE;
  61. u32 result = 0;
  62. u32 enable = 0x01 & readl(&base->sdram_bank[bank].win_sz);
  63. if ((!enable) || (bank > BANK3))
  64. return 0;
  65. result = 0xff000000 & readl(&base->sdram_bank[bank].win_sz);
  66. result += 0x01000000;
  67. return result;
  68. }
  69. void mvebu_sdram_size_adjust(enum memory_bank bank)
  70. {
  71. u32 size;
  72. /* probe currently equipped RAM size */
  73. size = get_ram_size((void *)mvebu_sdram_bar(bank),
  74. mvebu_sdram_bs(bank));
  75. /* adjust SDRAM window size accordingly */
  76. mvebu_sdram_bs_set(bank, size);
  77. }
  78. #ifndef CONFIG_SYS_BOARD_DRAM_INIT
  79. int dram_init(void)
  80. {
  81. int i;
  82. gd->ram_size = 0;
  83. for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
  84. gd->bd->bi_dram[i].start = mvebu_sdram_bar(i);
  85. gd->bd->bi_dram[i].size = mvebu_sdram_bs(i);
  86. /*
  87. * It is assumed that all memory banks are consecutive
  88. * and without gaps.
  89. * If the gap is found, ram_size will be reported for
  90. * consecutive memory only
  91. */
  92. if (gd->bd->bi_dram[i].start != gd->ram_size)
  93. break;
  94. /*
  95. * Don't report more than 3GiB of SDRAM, otherwise there is no
  96. * address space left for the internal registers etc.
  97. */
  98. if ((gd->ram_size + gd->bd->bi_dram[i].size != 0) &&
  99. (gd->ram_size + gd->bd->bi_dram[i].size <= (3 << 30)))
  100. gd->ram_size += gd->bd->bi_dram[i].size;
  101. }
  102. for (; i < CONFIG_NR_DRAM_BANKS; i++) {
  103. /* If above loop terminated prematurely, we need to set
  104. * remaining banks' start address & size as 0. Otherwise other
  105. * u-boot functions and Linux kernel gets wrong values which
  106. * could result in crash */
  107. gd->bd->bi_dram[i].start = 0;
  108. gd->bd->bi_dram[i].size = 0;
  109. }
  110. return 0;
  111. }
  112. /*
  113. * If this function is not defined here,
  114. * board.c alters dram bank zero configuration defined above.
  115. */
  116. void dram_init_banksize(void)
  117. {
  118. dram_init();
  119. }
  120. #endif /* CONFIG_SYS_BOARD_DRAM_INIT */