dram_init.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. /*
  2. * Copyright (C) 2012-2015 Masahiro Yamada <yamada.masahiro@socionext.com>
  3. *
  4. * SPDX-License-Identifier: GPL-2.0+
  5. */
  6. #include <common.h>
  7. #include <libfdt.h>
  8. #include <fdtdec.h>
  9. #include <linux/err.h>
  10. #include "init.h"
  11. #include "soc-info.h"
  12. DECLARE_GLOBAL_DATA_PTR;
  13. static const void *get_memory_reg_prop(const void *fdt, int *lenp)
  14. {
  15. int offset;
  16. offset = fdt_path_offset(fdt, "/memory");
  17. if (offset < 0)
  18. return NULL;
  19. return fdt_getprop(fdt, offset, "reg", lenp);
  20. }
  21. int dram_init(void)
  22. {
  23. const void *fdt = gd->fdt_blob;
  24. const fdt32_t *val;
  25. int ac, sc, len;
  26. ac = fdt_address_cells(fdt, 0);
  27. sc = fdt_size_cells(fdt, 0);
  28. if (ac < 0 || sc < 1 || sc > 2) {
  29. printf("invalid address/size cells\n");
  30. return -EINVAL;
  31. }
  32. val = get_memory_reg_prop(fdt, &len);
  33. if (len / sizeof(*val) < ac + sc)
  34. return -EINVAL;
  35. val += ac;
  36. gd->ram_size = fdtdec_get_number(val, sc);
  37. debug("DRAM size = %08lx\n", (unsigned long)gd->ram_size);
  38. return 0;
  39. }
  40. void dram_init_banksize(void)
  41. {
  42. const void *fdt = gd->fdt_blob;
  43. const fdt32_t *val;
  44. int ac, sc, cells, len, i;
  45. val = get_memory_reg_prop(fdt, &len);
  46. if (len < 0)
  47. return;
  48. ac = fdt_address_cells(fdt, 0);
  49. sc = fdt_size_cells(fdt, 0);
  50. if (ac < 1 || sc > 2 || sc < 1 || sc > 2) {
  51. printf("invalid address/size cells\n");
  52. return;
  53. }
  54. cells = ac + sc;
  55. len /= sizeof(*val);
  56. for (i = 0; i < CONFIG_NR_DRAM_BANKS && len >= cells;
  57. i++, len -= cells) {
  58. gd->bd->bi_dram[i].start = fdtdec_get_number(val, ac);
  59. val += ac;
  60. gd->bd->bi_dram[i].size = fdtdec_get_number(val, sc);
  61. val += sc;
  62. debug("DRAM bank %d: start = %08lx, size = %08lx\n",
  63. i, (unsigned long)gd->bd->bi_dram[i].start,
  64. (unsigned long)gd->bd->bi_dram[i].size);
  65. }
  66. }
  67. #ifdef CONFIG_OF_BOARD_SETUP
  68. /*
  69. * The DRAM PHY requires 64 byte scratch area in each DRAM channel
  70. * for its dynamic PHY training feature.
  71. */
  72. int ft_board_setup(void *fdt, bd_t *bd)
  73. {
  74. const struct uniphier_board_data *param;
  75. unsigned long rsv_addr;
  76. const unsigned long rsv_size = 64;
  77. int ch, ret;
  78. if (uniphier_get_soc_type() != SOC_UNIPHIER_LD20)
  79. return 0;
  80. param = uniphier_get_board_param();
  81. if (!param) {
  82. printf("failed to get board parameter\n");
  83. return -ENODEV;
  84. }
  85. for (ch = 0; ch < param->dram_nr_ch; ch++) {
  86. rsv_addr = param->dram_ch[ch].base + param->dram_ch[ch].size;
  87. rsv_addr -= rsv_size;
  88. ret = fdt_add_mem_rsv(fdt, rsv_addr, rsv_size);
  89. if (ret)
  90. return -ENOSPC;
  91. printf(" Reserved memory region for DRAM PHY training: addr=%lx size=%lx\n",
  92. rsv_addr, rsv_size);
  93. }
  94. return 0;
  95. }
  96. #endif