stm32mp1_ram.c 4.5 KB

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