1 // SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause 2 /* 3 * Copyright (C) 2018, STMicroelectronics - All Rights Reserved 4 */ 5 6 #include <common.h> 7 #include <dm.h> 8 #include <errno.h> 9 #include <regmap.h> 10 #include <syscon.h> 11 #include <power/pmic.h> 12 #include <power/regulator.h> 13 14 #define STM32MP_PWR_CR3 0xc 15 #define STM32MP_PWR_CR3_USB33DEN BIT(24) 16 #define STM32MP_PWR_CR3_USB33RDY BIT(26) 17 #define STM32MP_PWR_CR3_REG18DEN BIT(28) 18 #define STM32MP_PWR_CR3_REG18RDY BIT(29) 19 #define STM32MP_PWR_CR3_REG11DEN BIT(30) 20 #define STM32MP_PWR_CR3_REG11RDY BIT(31) 21 22 struct stm32mp_pwr_reg_info { 23 u32 enable; 24 u32 ready; 25 char *name; 26 }; 27 28 struct stm32mp_pwr_priv { 29 struct regmap *regmap; 30 }; 31 32 static int stm32mp_pwr_write(struct udevice *dev, uint reg, 33 const uint8_t *buff, int len) 34 { 35 struct stm32mp_pwr_priv *priv = dev_get_priv(dev); 36 u32 val = *(u32 *)buff; 37 38 if (len != 4) 39 return -EINVAL; 40 41 return regmap_write(priv->regmap, STM32MP_PWR_CR3, val); 42 } 43 44 static int stm32mp_pwr_read(struct udevice *dev, uint reg, uint8_t *buff, 45 int len) 46 { 47 struct stm32mp_pwr_priv *priv = dev_get_priv(dev); 48 49 if (len != 4) 50 return -EINVAL; 51 52 return regmap_read(priv->regmap, STM32MP_PWR_CR3, (u32 *)buff); 53 } 54 55 static int stm32mp_pwr_ofdata_to_platdata(struct udevice *dev) 56 { 57 struct stm32mp_pwr_priv *priv = dev_get_priv(dev); 58 struct regmap *regmap; 59 60 regmap = syscon_get_regmap_by_driver_data(STM32MP_SYSCON_PWR); 61 if (IS_ERR(regmap)) { 62 pr_err("%s: unable to find regmap (%ld)\n", __func__, 63 PTR_ERR(regmap)); 64 return PTR_ERR(regmap); 65 } 66 priv->regmap = regmap; 67 68 return 0; 69 } 70 71 static const struct pmic_child_info pwr_children_info[] = { 72 { .prefix = "reg", .driver = "stm32mp_pwr_regulator"}, 73 { .prefix = "usb", .driver = "stm32mp_pwr_regulator"}, 74 { }, 75 }; 76 77 static int stm32mp_pwr_bind(struct udevice *dev) 78 { 79 int children; 80 81 children = pmic_bind_children(dev, dev->node, pwr_children_info); 82 if (!children) 83 dev_dbg(dev, "no child found\n"); 84 85 return 0; 86 } 87 88 static struct dm_pmic_ops stm32mp_pwr_ops = { 89 .read = stm32mp_pwr_read, 90 .write = stm32mp_pwr_write, 91 }; 92 93 static const struct udevice_id stm32mp_pwr_ids[] = { 94 { .compatible = "st,stm32mp1,pwr-reg" }, 95 { } 96 }; 97 98 U_BOOT_DRIVER(stm32mp_pwr_pmic) = { 99 .name = "stm32mp_pwr_pmic", 100 .id = UCLASS_PMIC, 101 .of_match = stm32mp_pwr_ids, 102 .bind = stm32mp_pwr_bind, 103 .ops = &stm32mp_pwr_ops, 104 .ofdata_to_platdata = stm32mp_pwr_ofdata_to_platdata, 105 .priv_auto_alloc_size = sizeof(struct stm32mp_pwr_priv), 106 }; 107 108 static const struct stm32mp_pwr_reg_info stm32mp_pwr_reg11 = { 109 .enable = STM32MP_PWR_CR3_REG11DEN, 110 .ready = STM32MP_PWR_CR3_REG11RDY, 111 .name = "reg11" 112 }; 113 114 static const struct stm32mp_pwr_reg_info stm32mp_pwr_reg18 = { 115 .enable = STM32MP_PWR_CR3_REG18DEN, 116 .ready = STM32MP_PWR_CR3_REG18RDY, 117 .name = "reg18" 118 }; 119 120 static const struct stm32mp_pwr_reg_info stm32mp_pwr_usb33 = { 121 .enable = STM32MP_PWR_CR3_USB33DEN, 122 .ready = STM32MP_PWR_CR3_USB33RDY, 123 .name = "usb33" 124 }; 125 126 static const struct stm32mp_pwr_reg_info *stm32mp_pwr_reg_infos[] = { 127 &stm32mp_pwr_reg11, 128 &stm32mp_pwr_reg18, 129 &stm32mp_pwr_usb33, 130 NULL 131 }; 132 133 static int stm32mp_pwr_regulator_probe(struct udevice *dev) 134 { 135 const struct stm32mp_pwr_reg_info **p = stm32mp_pwr_reg_infos; 136 struct dm_regulator_uclass_platdata *uc_pdata; 137 138 uc_pdata = dev_get_uclass_platdata(dev); 139 140 while (*p) { 141 int rc; 142 143 rc = dev_read_stringlist_search(dev, "regulator-name", 144 (*p)->name); 145 if (rc >= 0) { 146 dev_dbg(dev, "found regulator %s\n", (*p)->name); 147 break; 148 } else if (rc != -ENODATA) { 149 return rc; 150 } 151 p++; 152 } 153 if (!*p) { 154 int i = 0; 155 const char *s; 156 157 dev_dbg(dev, "regulator "); 158 while (dev_read_string_index(dev, "regulator-name", 159 i++, &s) >= 0) 160 dev_dbg(dev, "%s'%s' ", (i > 1) ? ", " : "", s); 161 dev_dbg(dev, "%s not supported\n", (i > 2) ? "are" : "is"); 162 return -EINVAL; 163 } 164 165 uc_pdata->type = REGULATOR_TYPE_FIXED; 166 dev->priv = (void *)*p; 167 168 return 0; 169 } 170 171 static int stm32mp_pwr_regulator_set_value(struct udevice *dev, int uV) 172 { 173 struct dm_regulator_uclass_platdata *uc_pdata; 174 175 uc_pdata = dev_get_uclass_platdata(dev); 176 if (!uc_pdata) 177 return -ENXIO; 178 179 if (uc_pdata->min_uV != uV) { 180 dev_dbg(dev, "Invalid uV=%d for: %s\n", uV, uc_pdata->name); 181 return -EINVAL; 182 } 183 184 return 0; 185 } 186 187 static int stm32mp_pwr_regulator_get_value(struct udevice *dev) 188 { 189 struct dm_regulator_uclass_platdata *uc_pdata; 190 191 uc_pdata = dev_get_uclass_platdata(dev); 192 if (!uc_pdata) 193 return -ENXIO; 194 195 if (uc_pdata->min_uV != uc_pdata->max_uV) { 196 dev_dbg(dev, "Invalid constraints for: %s\n", uc_pdata->name); 197 return -EINVAL; 198 } 199 200 return uc_pdata->min_uV; 201 } 202 203 static int stm32mp_pwr_regulator_get_enable(struct udevice *dev) 204 { 205 const struct stm32mp_pwr_reg_info *p = dev_get_priv(dev); 206 int rc; 207 u32 reg; 208 209 rc = pmic_read(dev->parent, 0, (uint8_t *)®, sizeof(reg)); 210 if (rc) 211 return rc; 212 213 dev_dbg(dev, "%s id %s\n", p->name, (reg & p->enable) ? "on" : "off"); 214 215 return (reg & p->enable) != 0; 216 } 217 218 static int stm32mp_pwr_regulator_set_enable(struct udevice *dev, bool enable) 219 { 220 const struct stm32mp_pwr_reg_info *p = dev_get_priv(dev); 221 int rc; 222 u32 reg; 223 u32 time_start; 224 225 dev_dbg(dev, "Turning %s %s\n", enable ? "on" : "off", p->name); 226 227 rc = pmic_read(dev->parent, 0, (uint8_t *)®, sizeof(reg)); 228 if (rc) 229 return rc; 230 231 /* if regulator is already in the wanted state, nothing to do */ 232 if (!!(reg & p->enable) == enable) 233 return 0; 234 235 reg &= ~p->enable; 236 if (enable) 237 reg |= p->enable; 238 239 rc = pmic_write(dev->parent, 0, (uint8_t *)®, sizeof(reg)); 240 if (rc) 241 return rc; 242 243 if (!enable) 244 return 0; 245 246 /* waiting ready for enable */ 247 time_start = get_timer(0); 248 while (1) { 249 rc = pmic_read(dev->parent, 0, (uint8_t *)®, sizeof(reg)); 250 if (rc) 251 return rc; 252 if (reg & p->ready) 253 break; 254 if (get_timer(time_start) > CONFIG_SYS_HZ) { 255 dev_dbg(dev, "%s: timeout\n", p->name); 256 return -ETIMEDOUT; 257 } 258 } 259 return 0; 260 } 261 262 static const struct dm_regulator_ops stm32mp_pwr_regulator_ops = { 263 .set_value = stm32mp_pwr_regulator_set_value, 264 .get_value = stm32mp_pwr_regulator_get_value, 265 .get_enable = stm32mp_pwr_regulator_get_enable, 266 .set_enable = stm32mp_pwr_regulator_set_enable, 267 }; 268 269 U_BOOT_DRIVER(stm32mp_pwr_regulator) = { 270 .name = "stm32mp_pwr_regulator", 271 .id = UCLASS_REGULATOR, 272 .ops = &stm32mp_pwr_regulator_ops, 273 .probe = stm32mp_pwr_regulator_probe, 274 }; 275