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