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