plat_ddr.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. /*
  2. * Copyright (C) 2023-2024, STMicroelectronics - All Rights Reserved
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. */
  6. #include <assert.h>
  7. #include <errno.h>
  8. #include <stdint.h>
  9. #include <common/fdt_wrappers.h>
  10. #include <drivers/delay_timer.h>
  11. #include <drivers/st/regulator.h>
  12. #include <drivers/st/stm32mp_ddr.h>
  13. #include <libfdt.h>
  14. #include <platform_def.h>
  15. #if STM32MP_DDR3_TYPE
  16. struct ddr3_supply {
  17. struct rdev *vdd;
  18. struct rdev *vref;
  19. struct rdev *vtt;
  20. };
  21. static void ddr3_supply_read(void *fdt, int node, struct ddr3_supply *supply)
  22. {
  23. supply->vdd = regulator_get_by_supply_name(fdt, node, "vdd");
  24. supply->vref = regulator_get_by_supply_name(fdt, node, "vref");
  25. supply->vtt = regulator_get_by_supply_name(fdt, node, "vtt");
  26. }
  27. static int ddr_power_init(void *fdt, int node)
  28. {
  29. int status;
  30. struct ddr3_supply supply;
  31. ddr3_supply_read(fdt, node, &supply);
  32. if ((supply.vdd == NULL) || (supply.vref == NULL) || (supply.vtt == NULL)) {
  33. return -ENOENT;
  34. }
  35. /*
  36. * DDR3 power on sequence is:
  37. * enable VREF_DDR, VTT_DDR, VPP_DDR
  38. */
  39. status = regulator_set_min_voltage(supply.vdd);
  40. if (status != 0) {
  41. return status;
  42. }
  43. status = regulator_enable(supply.vdd);
  44. if (status != 0) {
  45. return status;
  46. }
  47. status = regulator_enable(supply.vref);
  48. if (status != 0) {
  49. return status;
  50. }
  51. return regulator_enable(supply.vtt);
  52. }
  53. #endif /* STM32MP_DDR3_TYPE */
  54. #if STM32MP_DDR4_TYPE
  55. struct ddr4_supply {
  56. struct rdev *vdd;
  57. struct rdev *vref;
  58. struct rdev *vtt;
  59. struct rdev *vpp;
  60. };
  61. static void ddr4_supply_read(void *fdt, int node, struct ddr4_supply *supply)
  62. {
  63. supply->vpp = regulator_get_by_supply_name(fdt, node, "vpp");
  64. supply->vdd = regulator_get_by_supply_name(fdt, node, "vdd");
  65. supply->vref = regulator_get_by_supply_name(fdt, node, "vref");
  66. supply->vtt = regulator_get_by_supply_name(fdt, node, "vtt");
  67. }
  68. static int ddr_power_init(void *fdt, int node)
  69. {
  70. int status;
  71. struct ddr4_supply supply;
  72. ddr4_supply_read(fdt, node, &supply);
  73. if ((supply.vpp == NULL) || (supply.vdd == NULL) || (supply.vref == NULL) ||
  74. (supply.vtt == NULL)) {
  75. return -ENOENT;
  76. }
  77. /*
  78. * DDR4 power on sequence is:
  79. * enable VPP_DDR
  80. * enable VREF_DDR, VTT_DDR, VPP_DDR
  81. */
  82. status = regulator_set_min_voltage(supply.vpp);
  83. if (status != 0) {
  84. return status;
  85. }
  86. status = regulator_set_min_voltage(supply.vdd);
  87. if (status != 0) {
  88. return status;
  89. }
  90. status = regulator_enable(supply.vpp);
  91. if (status != 0) {
  92. return status;
  93. }
  94. status = regulator_enable(supply.vdd);
  95. if (status != 0) {
  96. return status;
  97. }
  98. status = regulator_enable(supply.vref);
  99. if (status != 0) {
  100. return status;
  101. }
  102. return regulator_enable(supply.vtt);
  103. }
  104. #endif /* STM32MP_DDR4_TYPE */
  105. #if STM32MP_LPDDR4_TYPE
  106. struct lpddr4_supply {
  107. struct rdev *vdd1;
  108. struct rdev *vdd2;
  109. struct rdev *vddq;
  110. };
  111. static void lpddr4_supply_read(void *fdt, int node, struct lpddr4_supply *supply)
  112. {
  113. supply->vdd1 = regulator_get_by_supply_name(fdt, node, "vdd1");
  114. supply->vdd2 = regulator_get_by_supply_name(fdt, node, "vdd2");
  115. supply->vddq = regulator_get_by_supply_name(fdt, node, "vddq");
  116. }
  117. static int ddr_power_init(void *fdt, int node)
  118. {
  119. int status;
  120. struct lpddr4_supply supply;
  121. lpddr4_supply_read(fdt, node, &supply);
  122. if ((supply.vdd1 == NULL) || (supply.vdd2 == NULL) || (supply.vddq == NULL)) {
  123. return -ENOENT;
  124. }
  125. /*
  126. * LPDDR4 power on sequence is:
  127. * enable VDD1_DDR
  128. * enable VDD2_DDR
  129. * enable VDDQ_DDR
  130. */
  131. status = regulator_set_min_voltage(supply.vdd1);
  132. if (status != 0) {
  133. return status;
  134. }
  135. status = regulator_set_min_voltage(supply.vdd2);
  136. if (status != 0) {
  137. return status;
  138. }
  139. status = regulator_set_min_voltage(supply.vddq);
  140. if (status != 0) {
  141. return status;
  142. }
  143. status = regulator_enable(supply.vdd1);
  144. if (status != 0) {
  145. return status;
  146. }
  147. status = regulator_enable(supply.vdd2);
  148. if (status != 0) {
  149. return status;
  150. }
  151. return regulator_enable(supply.vddq);
  152. }
  153. #endif /* STM32MP_LPDDR4_TYPE */
  154. int stm32mp_board_ddr_power_init(enum ddr_type ddr_type)
  155. {
  156. void *fdt = NULL;
  157. int node;
  158. VERBOSE("DDR power init, ddr_type = %u\n", ddr_type);
  159. #if STM32MP_DDR3_TYPE
  160. assert(ddr_type == STM32MP_DDR3);
  161. #elif STM32MP_DDR4_TYPE
  162. assert(ddr_type == STM32MP_DDR4);
  163. #elif STM32MP_LPDDR4_TYPE
  164. assert(ddr_type == STM32MP_LPDDR4);
  165. #else
  166. ERROR("DDR type (%u) not supported\n", ddr_type);
  167. panic();
  168. #endif
  169. if (fdt_get_address(&fdt) == 0) {
  170. return -FDT_ERR_NOTFOUND;
  171. }
  172. node = fdt_node_offset_by_compatible(fdt, -1, DT_DDR_COMPAT);
  173. if (node < 0) {
  174. ERROR("%s: Cannot read DDR node in DT\n", __func__);
  175. return -EINVAL;
  176. }
  177. return ddr_power_init(fdt, node);
  178. }