stm32mp1_ram.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. // SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
  2. /*
  3. * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
  4. */
  5. #include <common.h>
  6. #include <clk.h>
  7. #include <dm.h>
  8. #include <ram.h>
  9. #include <regmap.h>
  10. #include <syscon.h>
  11. #include <asm/io.h>
  12. #include "stm32mp1_ddr.h"
  13. static const char *const clkname[] = {
  14. "ddrc1",
  15. "ddrc2",
  16. "ddrcapb",
  17. "ddrphycapb",
  18. "ddrphyc" /* LAST clock => used for get_rate() */
  19. };
  20. int stm32mp1_ddr_clk_enable(struct ddr_info *priv, uint16_t mem_speed)
  21. {
  22. unsigned long ddrphy_clk;
  23. unsigned long ddr_clk;
  24. struct clk clk;
  25. int ret;
  26. int idx;
  27. for (idx = 0; idx < ARRAY_SIZE(clkname); idx++) {
  28. ret = clk_get_by_name(priv->dev, clkname[idx], &clk);
  29. if (!ret)
  30. ret = clk_enable(&clk);
  31. if (ret) {
  32. printf("error for %s : %d\n", clkname[idx], ret);
  33. return ret;
  34. }
  35. }
  36. priv->clk = clk;
  37. ddrphy_clk = clk_get_rate(&priv->clk);
  38. debug("DDR: mem_speed (%d MHz), RCC %d MHz\n",
  39. mem_speed, (u32)(ddrphy_clk / 1000 / 1000));
  40. /* max 10% frequency delta */
  41. ddr_clk = abs(ddrphy_clk - mem_speed * 1000 * 1000);
  42. if (ddr_clk > (mem_speed * 1000 * 100)) {
  43. pr_err("DDR expected freq %d MHz, current is %d MHz\n",
  44. mem_speed, (u32)(ddrphy_clk / 1000 / 1000));
  45. return -EINVAL;
  46. }
  47. return 0;
  48. }
  49. static __maybe_unused int stm32mp1_ddr_setup(struct udevice *dev)
  50. {
  51. struct ddr_info *priv = dev_get_priv(dev);
  52. int ret, idx;
  53. struct clk axidcg;
  54. struct stm32mp1_ddr_config config;
  55. #define PARAM(x, y) \
  56. { x,\
  57. offsetof(struct stm32mp1_ddr_config, y),\
  58. sizeof(config.y) / sizeof(u32)}
  59. #define CTL_PARAM(x) PARAM("st,ctl-"#x, c_##x)
  60. #define PHY_PARAM(x) PARAM("st,phy-"#x, p_##x)
  61. const struct {
  62. const char *name; /* name in DT */
  63. const u32 offset; /* offset in config struct */
  64. const u32 size; /* size of parameters */
  65. } param[] = {
  66. CTL_PARAM(reg),
  67. CTL_PARAM(timing),
  68. CTL_PARAM(map),
  69. CTL_PARAM(perf),
  70. PHY_PARAM(reg),
  71. PHY_PARAM(timing),
  72. PHY_PARAM(cal)
  73. };
  74. config.info.speed = dev_read_u32_default(dev, "st,mem-speed", 0);
  75. config.info.size = dev_read_u32_default(dev, "st,mem-size", 0);
  76. config.info.name = dev_read_string(dev, "st,mem-name");
  77. if (!config.info.name) {
  78. debug("%s: no st,mem-name\n", __func__);
  79. return -EINVAL;
  80. }
  81. printf("RAM: %s\n", config.info.name);
  82. for (idx = 0; idx < ARRAY_SIZE(param); idx++) {
  83. ret = dev_read_u32_array(dev, param[idx].name,
  84. (void *)((u32)&config +
  85. param[idx].offset),
  86. param[idx].size);
  87. debug("%s: %s[0x%x] = %d\n", __func__,
  88. param[idx].name, param[idx].size, ret);
  89. if (ret) {
  90. pr_err("%s: Cannot read %s\n",
  91. __func__, param[idx].name);
  92. return -EINVAL;
  93. }
  94. }
  95. ret = clk_get_by_name(dev, "axidcg", &axidcg);
  96. if (ret) {
  97. debug("%s: Cannot found axidcg\n", __func__);
  98. return -EINVAL;
  99. }
  100. clk_disable(&axidcg); /* disable clock gating during init */
  101. stm32mp1_ddr_init(priv, &config);
  102. clk_enable(&axidcg); /* enable clock gating */
  103. /* check size */
  104. debug("%s : get_ram_size(%x, %x)\n", __func__,
  105. (u32)priv->info.base, (u32)STM32_DDR_SIZE);
  106. priv->info.size = get_ram_size((long *)priv->info.base,
  107. STM32_DDR_SIZE);
  108. debug("%s : %x\n", __func__, (u32)priv->info.size);
  109. /* check memory access for all memory */
  110. if (config.info.size != priv->info.size) {
  111. printf("DDR invalid size : 0x%x, expected 0x%x\n",
  112. priv->info.size, config.info.size);
  113. return -EINVAL;
  114. }
  115. return 0;
  116. }
  117. static int stm32mp1_ddr_probe(struct udevice *dev)
  118. {
  119. struct ddr_info *priv = dev_get_priv(dev);
  120. struct regmap *map;
  121. int ret;
  122. debug("STM32MP1 DDR probe\n");
  123. priv->dev = dev;
  124. ret = regmap_init_mem(dev_ofnode(dev), &map);
  125. if (ret)
  126. return ret;
  127. priv->ctl = regmap_get_range(map, 0);
  128. priv->phy = regmap_get_range(map, 1);
  129. priv->rcc = STM32_RCC_BASE;
  130. priv->info.base = STM32_DDR_BASE;
  131. #if !defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD)
  132. priv->info.size = 0;
  133. return stm32mp1_ddr_setup(dev);
  134. #else
  135. priv->info.size = dev_read_u32_default(dev, "st,mem-size", 0);
  136. return 0;
  137. #endif
  138. }
  139. static int stm32mp1_ddr_get_info(struct udevice *dev, struct ram_info *info)
  140. {
  141. struct ddr_info *priv = dev_get_priv(dev);
  142. *info = priv->info;
  143. return 0;
  144. }
  145. static struct ram_ops stm32mp1_ddr_ops = {
  146. .get_info = stm32mp1_ddr_get_info,
  147. };
  148. static const struct udevice_id stm32mp1_ddr_ids[] = {
  149. { .compatible = "st,stm32mp1-ddr" },
  150. { }
  151. };
  152. U_BOOT_DRIVER(ddr_stm32mp1) = {
  153. .name = "stm32mp1_ddr",
  154. .id = UCLASS_RAM,
  155. .of_match = stm32mp1_ddr_ids,
  156. .ops = &stm32mp1_ddr_ops,
  157. .probe = stm32mp1_ddr_probe,
  158. .priv_auto_alloc_size = sizeof(struct ddr_info),
  159. };