1 // SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
3 * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
11 #include <dm/device_compat.h>
12 #include <linux/err.h>
13 #include <power/pmic.h>
14 #include <power/regulator.h>
16 #define STM32MP_PWR_CR3 0xc
17 #define STM32MP_PWR_CR3_USB33DEN BIT(24)
18 #define STM32MP_PWR_CR3_USB33RDY BIT(26)
19 #define STM32MP_PWR_CR3_REG18DEN BIT(28)
20 #define STM32MP_PWR_CR3_REG18RDY BIT(29)
21 #define STM32MP_PWR_CR3_REG11DEN BIT(30)
22 #define STM32MP_PWR_CR3_REG11RDY BIT(31)
24 struct stm32mp_pwr_reg_info {
30 struct stm32mp_pwr_priv {
34 static int stm32mp_pwr_write(struct udevice *dev, uint reg,
35 const uint8_t *buff, int len)
37 struct stm32mp_pwr_priv *priv = dev_get_priv(dev);
38 u32 val = *(u32 *)buff;
43 writel(val, priv->base + STM32MP_PWR_CR3);
48 static int stm32mp_pwr_read(struct udevice *dev, uint reg, uint8_t *buff,
51 struct stm32mp_pwr_priv *priv = dev_get_priv(dev);
56 *(u32 *)buff = readl(priv->base + STM32MP_PWR_CR3);
61 static int stm32mp_pwr_ofdata_to_platdata(struct udevice *dev)
63 struct stm32mp_pwr_priv *priv = dev_get_priv(dev);
65 priv->base = dev_read_addr(dev);
66 if (priv->base == FDT_ADDR_T_NONE)
72 static const struct pmic_child_info pwr_children_info[] = {
73 { .prefix = "reg", .driver = "stm32mp_pwr_regulator"},
74 { .prefix = "usb", .driver = "stm32mp_pwr_regulator"},
78 static int stm32mp_pwr_bind(struct udevice *dev)
82 children = pmic_bind_children(dev, dev->node, pwr_children_info);
84 dev_dbg(dev, "no child found\n");
89 static struct dm_pmic_ops stm32mp_pwr_ops = {
90 .read = stm32mp_pwr_read,
91 .write = stm32mp_pwr_write,
94 static const struct udevice_id stm32mp_pwr_ids[] = {
95 { .compatible = "st,stm32mp1,pwr-reg" },
99 U_BOOT_DRIVER(stm32mp_pwr_pmic) = {
100 .name = "stm32mp_pwr_pmic",
102 .of_match = stm32mp_pwr_ids,
103 .bind = stm32mp_pwr_bind,
104 .ops = &stm32mp_pwr_ops,
105 .ofdata_to_platdata = stm32mp_pwr_ofdata_to_platdata,
106 .priv_auto_alloc_size = sizeof(struct stm32mp_pwr_priv),
109 static const struct stm32mp_pwr_reg_info stm32mp_pwr_reg11 = {
110 .enable = STM32MP_PWR_CR3_REG11DEN,
111 .ready = STM32MP_PWR_CR3_REG11RDY,
115 static const struct stm32mp_pwr_reg_info stm32mp_pwr_reg18 = {
116 .enable = STM32MP_PWR_CR3_REG18DEN,
117 .ready = STM32MP_PWR_CR3_REG18RDY,
121 static const struct stm32mp_pwr_reg_info stm32mp_pwr_usb33 = {
122 .enable = STM32MP_PWR_CR3_USB33DEN,
123 .ready = STM32MP_PWR_CR3_USB33RDY,
127 static const struct stm32mp_pwr_reg_info *stm32mp_pwr_reg_infos[] = {
134 static int stm32mp_pwr_regulator_probe(struct udevice *dev)
136 const struct stm32mp_pwr_reg_info **p = stm32mp_pwr_reg_infos;
137 struct dm_regulator_uclass_platdata *uc_pdata;
139 uc_pdata = dev_get_uclass_platdata(dev);
144 rc = dev_read_stringlist_search(dev, "regulator-name",
147 dev_dbg(dev, "found regulator %s\n", (*p)->name);
149 } else if (rc != -ENODATA) {
158 dev_dbg(dev, "regulator ");
159 while (dev_read_string_index(dev, "regulator-name",
161 dev_dbg(dev, "%s'%s' ", (i > 1) ? ", " : "", s);
162 dev_dbg(dev, "%s not supported\n", (i > 2) ? "are" : "is");
166 uc_pdata->type = REGULATOR_TYPE_FIXED;
167 dev->priv = (void *)*p;
172 static int stm32mp_pwr_regulator_set_value(struct udevice *dev, int uV)
174 struct dm_regulator_uclass_platdata *uc_pdata;
176 uc_pdata = dev_get_uclass_platdata(dev);
180 if (uc_pdata->min_uV != uV) {
181 dev_dbg(dev, "Invalid uV=%d for: %s\n", uV, uc_pdata->name);
188 static int stm32mp_pwr_regulator_get_value(struct udevice *dev)
190 struct dm_regulator_uclass_platdata *uc_pdata;
192 uc_pdata = dev_get_uclass_platdata(dev);
196 if (uc_pdata->min_uV != uc_pdata->max_uV) {
197 dev_dbg(dev, "Invalid constraints for: %s\n", uc_pdata->name);
201 return uc_pdata->min_uV;
204 static int stm32mp_pwr_regulator_get_enable(struct udevice *dev)
206 const struct stm32mp_pwr_reg_info *p = dev_get_priv(dev);
210 rc = pmic_read(dev->parent, 0, (uint8_t *)®, sizeof(reg));
214 dev_dbg(dev, "%s id %s\n", p->name, (reg & p->enable) ? "on" : "off");
216 return (reg & p->enable) != 0;
219 static int stm32mp_pwr_regulator_set_enable(struct udevice *dev, bool enable)
221 const struct stm32mp_pwr_reg_info *p = dev_get_priv(dev);
226 dev_dbg(dev, "Turning %s %s\n", enable ? "on" : "off", p->name);
228 rc = pmic_read(dev->parent, 0, (uint8_t *)®, sizeof(reg));
232 /* if regulator is already in the wanted state, nothing to do */
233 if (!!(reg & p->enable) == enable)
240 rc = pmic_write(dev->parent, 0, (uint8_t *)®, sizeof(reg));
247 /* waiting ready for enable */
248 time_start = get_timer(0);
250 rc = pmic_read(dev->parent, 0, (uint8_t *)®, sizeof(reg));
255 if (get_timer(time_start) > CONFIG_SYS_HZ) {
256 dev_dbg(dev, "%s: timeout\n", p->name);
263 static const struct dm_regulator_ops stm32mp_pwr_regulator_ops = {
264 .set_value = stm32mp_pwr_regulator_set_value,
265 .get_value = stm32mp_pwr_regulator_get_value,
266 .get_enable = stm32mp_pwr_regulator_get_enable,
267 .set_enable = stm32mp_pwr_regulator_set_enable,
270 U_BOOT_DRIVER(stm32mp_pwr_regulator) = {
271 .name = "stm32mp_pwr_regulator",
272 .id = UCLASS_REGULATOR,
273 .ops = &stm32mp_pwr_regulator_ops,
274 .probe = stm32mp_pwr_regulator_probe,