blob: 6fe51f443d7c9bbff7dd7513eb241ba2d115ca38 [file] [log] [blame]
Yann Gautierbb836ee2018-07-16 17:55:07 +02001/*
Yann Gautiera45433b2019-01-16 18:31:00 +01002 * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved
Yann Gautierbb836ee2018-07-16 17:55:07 +02003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
Yann Gautierbb836ee2018-07-16 17:55:07 +02007#include <errno.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +00008
Yann Gautierbb836ee2018-07-16 17:55:07 +02009#include <libfdt.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000010
Yann Gautierbb836ee2018-07-16 17:55:07 +020011#include <platform_def.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000012
13#include <common/debug.h>
14#include <drivers/delay_timer.h>
Yann Gautierf3928f62019-02-14 11:15:03 +010015#include <drivers/st/stm32_i2c.h>
Yann Gautiera45433b2019-01-16 18:31:00 +010016#include <drivers/st/stm32mp_pmic.h>
Yann Gautiera45433b2019-01-16 18:31:00 +010017#include <drivers/st/stpmic1.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000018#include <lib/mmio.h>
19#include <lib/utils_def.h>
20
Yann Gautiera45433b2019-01-16 18:31:00 +010021#define STPMIC1_LDO12356_OUTPUT_MASK (uint8_t)(GENMASK(6, 2))
22#define STPMIC1_LDO12356_OUTPUT_SHIFT 2
23#define STPMIC1_LDO3_MODE (uint8_t)(BIT(7))
24#define STPMIC1_LDO3_DDR_SEL 31U
25#define STPMIC1_LDO3_1800000 (9U << STPMIC1_LDO12356_OUTPUT_SHIFT)
Yann Gautierbb836ee2018-07-16 17:55:07 +020026
Yann Gautiera45433b2019-01-16 18:31:00 +010027#define STPMIC1_BUCK_OUTPUT_SHIFT 2
28#define STPMIC1_BUCK3_1V8 (39U << STPMIC1_BUCK_OUTPUT_SHIFT)
Yann Gautierbb836ee2018-07-16 17:55:07 +020029
Yann Gautiera45433b2019-01-16 18:31:00 +010030#define STPMIC1_DEFAULT_START_UP_DELAY_MS 1
Yann Gautierbb836ee2018-07-16 17:55:07 +020031
32static struct i2c_handle_s i2c_handle;
33static uint32_t pmic_i2c_addr;
34
35static int dt_get_pmic_node(void *fdt)
36{
Yann Gautiera45433b2019-01-16 18:31:00 +010037 return fdt_node_offset_by_compatible(fdt, -1, "st,stpmic1");
Yann Gautierbb836ee2018-07-16 17:55:07 +020038}
39
Yann Gautierf3928f62019-02-14 11:15:03 +010040int dt_pmic_status(void)
Yann Gautierbb836ee2018-07-16 17:55:07 +020041{
42 int node;
43 void *fdt;
44
45 if (fdt_get_address(&fdt) == 0) {
Yann Gautierf3928f62019-02-14 11:15:03 +010046 return -ENOENT;
Yann Gautierbb836ee2018-07-16 17:55:07 +020047 }
48
49 node = dt_get_pmic_node(fdt);
Yann Gautierf3928f62019-02-14 11:15:03 +010050 if (node <= 0) {
51 return -FDT_ERR_NOTFOUND;
Yann Gautierbb836ee2018-07-16 17:55:07 +020052 }
53
Yann Gautier038bff22019-01-17 19:17:47 +010054 return fdt_get_status(node);
Yann Gautierbb836ee2018-07-16 17:55:07 +020055}
56
Yann Gautierf3928f62019-02-14 11:15:03 +010057/*
58 * Get PMIC and its I2C bus configuration from the device tree.
59 * Return 0 on success, negative on error, 1 if no PMIC node is found.
60 */
61static int dt_pmic_i2c_config(struct dt_node_info *i2c_info,
62 struct stm32_i2c_init_s *init)
Yann Gautierbb836ee2018-07-16 17:55:07 +020063{
64 int pmic_node, i2c_node;
65 void *fdt;
66 const fdt32_t *cuint;
67
68 if (fdt_get_address(&fdt) == 0) {
69 return -ENOENT;
70 }
71
72 pmic_node = dt_get_pmic_node(fdt);
73 if (pmic_node < 0) {
Yann Gautierf3928f62019-02-14 11:15:03 +010074 return 1;
Yann Gautierbb836ee2018-07-16 17:55:07 +020075 }
76
77 cuint = fdt_getprop(fdt, pmic_node, "reg", NULL);
78 if (cuint == NULL) {
79 return -FDT_ERR_NOTFOUND;
80 }
81
82 pmic_i2c_addr = fdt32_to_cpu(*cuint) << 1;
83 if (pmic_i2c_addr > UINT16_MAX) {
84 return -EINVAL;
85 }
86
87 i2c_node = fdt_parent_offset(fdt, pmic_node);
88 if (i2c_node < 0) {
89 return -FDT_ERR_NOTFOUND;
90 }
91
92 dt_fill_device_info(i2c_info, i2c_node);
93 if (i2c_info->base == 0U) {
94 return -FDT_ERR_NOTFOUND;
95 }
96
Yann Gautierf3928f62019-02-14 11:15:03 +010097 return stm32_i2c_get_setup_from_fdt(fdt, i2c_node, init);
Yann Gautierbb836ee2018-07-16 17:55:07 +020098}
99
Yann Gautierf3928f62019-02-14 11:15:03 +0100100int dt_pmic_configure_boot_on_regulators(void)
Yann Gautierbb836ee2018-07-16 17:55:07 +0200101{
102 int pmic_node, regulators_node, regulator_node;
103 void *fdt;
104
105 if (fdt_get_address(&fdt) == 0) {
106 return -ENOENT;
107 }
108
109 pmic_node = dt_get_pmic_node(fdt);
110 if (pmic_node < 0) {
111 return -FDT_ERR_NOTFOUND;
112 }
113
114 regulators_node = fdt_subnode_offset(fdt, pmic_node, "regulators");
115
116 fdt_for_each_subnode(regulator_node, fdt, regulators_node) {
117 const fdt32_t *cuint;
Yann Gautierf3928f62019-02-14 11:15:03 +0100118 const char *node_name = fdt_get_name(fdt, regulator_node, NULL);
Yann Gautierbb836ee2018-07-16 17:55:07 +0200119 uint16_t voltage;
Yann Gautierf3928f62019-02-14 11:15:03 +0100120 int status;
Yann Gautierbb836ee2018-07-16 17:55:07 +0200121
Yann Gautierf3928f62019-02-14 11:15:03 +0100122#if defined(IMAGE_BL2)
123 if ((fdt_getprop(fdt, regulator_node, "regulator-boot-on",
124 NULL) == NULL) &&
125 (fdt_getprop(fdt, regulator_node, "regulator-always-on",
126 NULL) == NULL)) {
127#else
Yann Gautierbb836ee2018-07-16 17:55:07 +0200128 if (fdt_getprop(fdt, regulator_node, "regulator-boot-on",
129 NULL) == NULL) {
Yann Gautierf3928f62019-02-14 11:15:03 +0100130#endif
Yann Gautierbb836ee2018-07-16 17:55:07 +0200131 continue;
132 }
133
Yann Gautierf3928f62019-02-14 11:15:03 +0100134 if (fdt_getprop(fdt, regulator_node, "regulator-pull-down",
135 NULL) != NULL) {
136
137 status = stpmic1_regulator_pull_down_set(node_name);
138 if (status != 0) {
139 return status;
140 }
141 }
142
143 if (fdt_getprop(fdt, regulator_node, "st,mask-reset",
144 NULL) != NULL) {
145
146 status = stpmic1_regulator_mask_reset_set(node_name);
147 if (status != 0) {
148 return status;
149 }
150 }
151
Yann Gautierbb836ee2018-07-16 17:55:07 +0200152 cuint = fdt_getprop(fdt, regulator_node,
153 "regulator-min-microvolt", NULL);
154 if (cuint == NULL) {
155 continue;
156 }
157
158 /* DT uses microvolts, whereas driver awaits millivolts */
159 voltage = (uint16_t)(fdt32_to_cpu(*cuint) / 1000U);
Yann Gautierbb836ee2018-07-16 17:55:07 +0200160
Yann Gautierf3928f62019-02-14 11:15:03 +0100161 status = stpmic1_regulator_voltage_set(node_name, voltage);
162 if (status != 0) {
163 return status;
164 }
Yann Gautierbb836ee2018-07-16 17:55:07 +0200165
Yann Gautierf3928f62019-02-14 11:15:03 +0100166 if (stpmic1_is_regulator_enabled(node_name) == 0U) {
Yann Gautiera45433b2019-01-16 18:31:00 +0100167 status = stpmic1_regulator_enable(node_name);
Yann Gautierbb836ee2018-07-16 17:55:07 +0200168 if (status != 0) {
169 return status;
170 }
171 }
172 }
173
174 return 0;
175}
176
Yann Gautierf3928f62019-02-14 11:15:03 +0100177bool initialize_pmic_i2c(void)
Yann Gautierbb836ee2018-07-16 17:55:07 +0200178{
179 int ret;
180 struct dt_node_info i2c_info;
Yann Gautierf3928f62019-02-14 11:15:03 +0100181 struct i2c_handle_s *i2c = &i2c_handle;
182 struct stm32_i2c_init_s i2c_init;
Yann Gautierbb836ee2018-07-16 17:55:07 +0200183
Yann Gautierf3928f62019-02-14 11:15:03 +0100184 ret = dt_pmic_i2c_config(&i2c_info, &i2c_init);
185 if (ret < 0) {
186 ERROR("I2C configuration failed %d\n", ret);
Yann Gautierbb836ee2018-07-16 17:55:07 +0200187 panic();
188 }
189
Yann Gautierf3928f62019-02-14 11:15:03 +0100190 if (ret != 0) {
191 return false;
Yann Gautierbb836ee2018-07-16 17:55:07 +0200192 }
193
194 /* Initialize PMIC I2C */
Yann Gautierf3928f62019-02-14 11:15:03 +0100195 i2c->i2c_base_addr = i2c_info.base;
196 i2c->dt_status = i2c_info.status;
197 i2c->clock = i2c_info.clock;
198 i2c_init.own_address1 = pmic_i2c_addr;
199 i2c_init.addressing_mode = I2C_ADDRESSINGMODE_7BIT;
200 i2c_init.dual_address_mode = I2C_DUALADDRESS_DISABLE;
201 i2c_init.own_address2 = 0;
202 i2c_init.own_address2_masks = I2C_OAR2_OA2NOMASK;
203 i2c_init.general_call_mode = I2C_GENERALCALL_DISABLE;
204 i2c_init.no_stretch_mode = I2C_NOSTRETCH_DISABLE;
205 i2c_init.analog_filter = 1;
206 i2c_init.digital_filter_coef = 0;
Yann Gautierbb836ee2018-07-16 17:55:07 +0200207
Yann Gautierf3928f62019-02-14 11:15:03 +0100208 ret = stm32_i2c_init(i2c, &i2c_init);
Yann Gautierbb836ee2018-07-16 17:55:07 +0200209 if (ret != 0) {
210 ERROR("Cannot initialize I2C %x (%d)\n",
Yann Gautierf3928f62019-02-14 11:15:03 +0100211 i2c->i2c_base_addr, ret);
Yann Gautierbb836ee2018-07-16 17:55:07 +0200212 panic();
213 }
214
Yann Gautierf3928f62019-02-14 11:15:03 +0100215 if (!stm32_i2c_is_device_ready(i2c, pmic_i2c_addr, 1,
216 I2C_TIMEOUT_BUSY_MS)) {
217 ERROR("I2C device not ready\n");
Yann Gautierbb836ee2018-07-16 17:55:07 +0200218 panic();
219 }
220
Yann Gautierf3928f62019-02-14 11:15:03 +0100221 stpmic1_bind_i2c(i2c, (uint16_t)pmic_i2c_addr);
Yann Gautierbb836ee2018-07-16 17:55:07 +0200222
Yann Gautierf3928f62019-02-14 11:15:03 +0100223 return true;
Yann Gautierbb836ee2018-07-16 17:55:07 +0200224}
225
226void initialize_pmic(void)
227{
Yann Gautierf3928f62019-02-14 11:15:03 +0100228 unsigned long pmic_version;
Yann Gautierbb836ee2018-07-16 17:55:07 +0200229
Yann Gautierf3928f62019-02-14 11:15:03 +0100230 if (!initialize_pmic_i2c()) {
231 VERBOSE("No PMIC\n");
232 return;
233 }
Yann Gautierbb836ee2018-07-16 17:55:07 +0200234
Yann Gautierf3928f62019-02-14 11:15:03 +0100235 if (stpmic1_get_version(&pmic_version) != 0) {
236 ERROR("Failed to access PMIC\n");
Yann Gautierbb836ee2018-07-16 17:55:07 +0200237 panic();
238 }
239
Yann Gautierf3928f62019-02-14 11:15:03 +0100240 INFO("PMIC version = 0x%02lx\n", pmic_version);
241 stpmic1_dump_regulators();
Yann Gautierbb836ee2018-07-16 17:55:07 +0200242
Yann Gautierf3928f62019-02-14 11:15:03 +0100243#if defined(IMAGE_BL2)
244 if (dt_pmic_configure_boot_on_regulators() != 0) {
Yann Gautierbb836ee2018-07-16 17:55:07 +0200245 panic();
Yann Gautierf3928f62019-02-14 11:15:03 +0100246 };
247#endif
Yann Gautierbb836ee2018-07-16 17:55:07 +0200248}
249
250int pmic_ddr_power_init(enum ddr_type ddr_type)
251{
252 bool buck3_at_1v8 = false;
253 uint8_t read_val;
254 int status;
255
256 switch (ddr_type) {
257 case STM32MP_DDR3:
258 /* Set LDO3 to sync mode */
Yann Gautiera45433b2019-01-16 18:31:00 +0100259 status = stpmic1_register_read(LDO3_CONTROL_REG, &read_val);
Yann Gautierbb836ee2018-07-16 17:55:07 +0200260 if (status != 0) {
261 return status;
262 }
263
Yann Gautiera45433b2019-01-16 18:31:00 +0100264 read_val &= ~STPMIC1_LDO3_MODE;
265 read_val &= ~STPMIC1_LDO12356_OUTPUT_MASK;
266 read_val |= STPMIC1_LDO3_DDR_SEL <<
267 STPMIC1_LDO12356_OUTPUT_SHIFT;
Yann Gautierbb836ee2018-07-16 17:55:07 +0200268
Yann Gautiera45433b2019-01-16 18:31:00 +0100269 status = stpmic1_register_write(LDO3_CONTROL_REG, read_val);
Yann Gautierbb836ee2018-07-16 17:55:07 +0200270 if (status != 0) {
271 return status;
272 }
273
Yann Gautiera45433b2019-01-16 18:31:00 +0100274 status = stpmic1_regulator_voltage_set("buck2", 1350);
Yann Gautierbb836ee2018-07-16 17:55:07 +0200275 if (status != 0) {
276 return status;
277 }
278
Yann Gautiera45433b2019-01-16 18:31:00 +0100279 status = stpmic1_regulator_enable("buck2");
Yann Gautierbb836ee2018-07-16 17:55:07 +0200280 if (status != 0) {
281 return status;
282 }
283
Yann Gautiera45433b2019-01-16 18:31:00 +0100284 mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
Yann Gautierbb836ee2018-07-16 17:55:07 +0200285
Yann Gautiera45433b2019-01-16 18:31:00 +0100286 status = stpmic1_regulator_enable("vref_ddr");
Yann Gautierbb836ee2018-07-16 17:55:07 +0200287 if (status != 0) {
288 return status;
289 }
290
Yann Gautiera45433b2019-01-16 18:31:00 +0100291 mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
Yann Gautierbb836ee2018-07-16 17:55:07 +0200292
Yann Gautiera45433b2019-01-16 18:31:00 +0100293 status = stpmic1_regulator_enable("ldo3");
Yann Gautierbb836ee2018-07-16 17:55:07 +0200294 if (status != 0) {
295 return status;
296 }
297
Yann Gautiera45433b2019-01-16 18:31:00 +0100298 mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
Yann Gautierbb836ee2018-07-16 17:55:07 +0200299 break;
300
301 case STM32MP_LPDDR2:
302 /*
303 * Set LDO3 to 1.8V
304 * Set LDO3 to bypass mode if BUCK3 = 1.8V
305 * Set LDO3 to normal mode if BUCK3 != 1.8V
306 */
Yann Gautiera45433b2019-01-16 18:31:00 +0100307 status = stpmic1_register_read(BUCK3_CONTROL_REG, &read_val);
Yann Gautierbb836ee2018-07-16 17:55:07 +0200308 if (status != 0) {
309 return status;
310 }
311
Yann Gautiera45433b2019-01-16 18:31:00 +0100312 if ((read_val & STPMIC1_BUCK3_1V8) == STPMIC1_BUCK3_1V8) {
Yann Gautierbb836ee2018-07-16 17:55:07 +0200313 buck3_at_1v8 = true;
314 }
315
Yann Gautiera45433b2019-01-16 18:31:00 +0100316 status = stpmic1_register_read(LDO3_CONTROL_REG, &read_val);
Yann Gautierbb836ee2018-07-16 17:55:07 +0200317 if (status != 0) {
318 return status;
319 }
320
Yann Gautiera45433b2019-01-16 18:31:00 +0100321 read_val &= ~STPMIC1_LDO3_MODE;
322 read_val &= ~STPMIC1_LDO12356_OUTPUT_MASK;
323 read_val |= STPMIC1_LDO3_1800000;
Yann Gautierbb836ee2018-07-16 17:55:07 +0200324 if (buck3_at_1v8) {
Yann Gautiera45433b2019-01-16 18:31:00 +0100325 read_val |= STPMIC1_LDO3_MODE;
Yann Gautierbb836ee2018-07-16 17:55:07 +0200326 }
327
Yann Gautiera45433b2019-01-16 18:31:00 +0100328 status = stpmic1_register_write(LDO3_CONTROL_REG, read_val);
Yann Gautierbb836ee2018-07-16 17:55:07 +0200329 if (status != 0) {
330 return status;
331 }
332
Yann Gautiera45433b2019-01-16 18:31:00 +0100333 status = stpmic1_regulator_voltage_set("buck2", 1200);
Yann Gautierbb836ee2018-07-16 17:55:07 +0200334 if (status != 0) {
335 return status;
336 }
337
Yann Gautiera45433b2019-01-16 18:31:00 +0100338 status = stpmic1_regulator_enable("ldo3");
Yann Gautierbb836ee2018-07-16 17:55:07 +0200339 if (status != 0) {
340 return status;
341 }
342
Yann Gautiera45433b2019-01-16 18:31:00 +0100343 mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
Yann Gautierbb836ee2018-07-16 17:55:07 +0200344
Yann Gautiera45433b2019-01-16 18:31:00 +0100345 status = stpmic1_regulator_enable("buck2");
Yann Gautierbb836ee2018-07-16 17:55:07 +0200346 if (status != 0) {
347 return status;
348 }
349
Yann Gautiera45433b2019-01-16 18:31:00 +0100350 mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
Yann Gautierbb836ee2018-07-16 17:55:07 +0200351
Yann Gautiera45433b2019-01-16 18:31:00 +0100352 status = stpmic1_regulator_enable("vref_ddr");
Yann Gautierbb836ee2018-07-16 17:55:07 +0200353 if (status != 0) {
354 return status;
355 }
356
Yann Gautiera45433b2019-01-16 18:31:00 +0100357 mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
Yann Gautierbb836ee2018-07-16 17:55:07 +0200358 break;
359
360 default:
361 break;
362 };
363
364 return 0;
365}