blob: 6beabc15360f7a1853947af2143f88c36fe66761 [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#include <stdbool.h>
9
Yann Gautierbb836ee2018-07-16 17:55:07 +020010#include <libfdt.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000011
Yann Gautierbb836ee2018-07-16 17:55:07 +020012#include <platform_def.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000013
14#include <common/debug.h>
15#include <drivers/delay_timer.h>
Yann Gautiera45433b2019-01-16 18:31:00 +010016#include <drivers/st/stm32mp_pmic.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000017#include <drivers/st/stm32_gpio.h>
18#include <drivers/st/stm32mp1_clk.h>
Yann Gautiera45433b2019-01-16 18:31:00 +010019#include <drivers/st/stpmic1.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000020#include <lib/mmio.h>
21#include <lib/utils_def.h>
22
Yann Gautierbb836ee2018-07-16 17:55:07 +020023/* I2C Timing hard-coded value, for I2C clock source is HSI at 64MHz */
24#define I2C_TIMING 0x10D07DB5
25
26#define I2C_TIMEOUT 0xFFFFF
27
28#define MASK_RESET_BUCK3 BIT(2)
29
Yann Gautiera45433b2019-01-16 18:31:00 +010030#define STPMIC1_LDO12356_OUTPUT_MASK (uint8_t)(GENMASK(6, 2))
31#define STPMIC1_LDO12356_OUTPUT_SHIFT 2
32#define STPMIC1_LDO3_MODE (uint8_t)(BIT(7))
33#define STPMIC1_LDO3_DDR_SEL 31U
34#define STPMIC1_LDO3_1800000 (9U << STPMIC1_LDO12356_OUTPUT_SHIFT)
Yann Gautierbb836ee2018-07-16 17:55:07 +020035
Yann Gautiera45433b2019-01-16 18:31:00 +010036#define STPMIC1_BUCK_OUTPUT_SHIFT 2
37#define STPMIC1_BUCK3_1V8 (39U << STPMIC1_BUCK_OUTPUT_SHIFT)
Yann Gautierbb836ee2018-07-16 17:55:07 +020038
Yann Gautiera45433b2019-01-16 18:31:00 +010039#define STPMIC1_DEFAULT_START_UP_DELAY_MS 1
Yann Gautierbb836ee2018-07-16 17:55:07 +020040
41static struct i2c_handle_s i2c_handle;
42static uint32_t pmic_i2c_addr;
43
44static int dt_get_pmic_node(void *fdt)
45{
Yann Gautiera45433b2019-01-16 18:31:00 +010046 return fdt_node_offset_by_compatible(fdt, -1, "st,stpmic1");
Yann Gautierbb836ee2018-07-16 17:55:07 +020047}
48
49bool dt_check_pmic(void)
50{
51 int node;
52 void *fdt;
53
54 if (fdt_get_address(&fdt) == 0) {
55 return false;
56 }
57
58 node = dt_get_pmic_node(fdt);
59 if (node < 0) {
60 VERBOSE("%s: No PMIC node found in DT\n", __func__);
61 return false;
62 }
63
Yann Gautier038bff22019-01-17 19:17:47 +010064 return fdt_get_status(node);
Yann Gautierbb836ee2018-07-16 17:55:07 +020065}
66
67static int dt_pmic_i2c_config(struct dt_node_info *i2c_info)
68{
69 int pmic_node, i2c_node;
70 void *fdt;
71 const fdt32_t *cuint;
72
73 if (fdt_get_address(&fdt) == 0) {
74 return -ENOENT;
75 }
76
77 pmic_node = dt_get_pmic_node(fdt);
78 if (pmic_node < 0) {
79 return -FDT_ERR_NOTFOUND;
80 }
81
82 cuint = fdt_getprop(fdt, pmic_node, "reg", NULL);
83 if (cuint == NULL) {
84 return -FDT_ERR_NOTFOUND;
85 }
86
87 pmic_i2c_addr = fdt32_to_cpu(*cuint) << 1;
88 if (pmic_i2c_addr > UINT16_MAX) {
89 return -EINVAL;
90 }
91
92 i2c_node = fdt_parent_offset(fdt, pmic_node);
93 if (i2c_node < 0) {
94 return -FDT_ERR_NOTFOUND;
95 }
96
97 dt_fill_device_info(i2c_info, i2c_node);
98 if (i2c_info->base == 0U) {
99 return -FDT_ERR_NOTFOUND;
100 }
101
102 return dt_set_pinctrl_config(i2c_node);
103}
104
105int dt_pmic_enable_boot_on_regulators(void)
106{
107 int pmic_node, regulators_node, regulator_node;
108 void *fdt;
109
110 if (fdt_get_address(&fdt) == 0) {
111 return -ENOENT;
112 }
113
114 pmic_node = dt_get_pmic_node(fdt);
115 if (pmic_node < 0) {
116 return -FDT_ERR_NOTFOUND;
117 }
118
119 regulators_node = fdt_subnode_offset(fdt, pmic_node, "regulators");
120
121 fdt_for_each_subnode(regulator_node, fdt, regulators_node) {
122 const fdt32_t *cuint;
123 const char *node_name;
124 uint16_t voltage;
125
126 if (fdt_getprop(fdt, regulator_node, "regulator-boot-on",
127 NULL) == NULL) {
128 continue;
129 }
130
131 cuint = fdt_getprop(fdt, regulator_node,
132 "regulator-min-microvolt", NULL);
133 if (cuint == NULL) {
134 continue;
135 }
136
137 /* DT uses microvolts, whereas driver awaits millivolts */
138 voltage = (uint16_t)(fdt32_to_cpu(*cuint) / 1000U);
139 node_name = fdt_get_name(fdt, regulator_node, NULL);
140
Yann Gautiera45433b2019-01-16 18:31:00 +0100141 if (stpmic1_is_regulator_enabled(node_name) == 0U) {
Yann Gautierbb836ee2018-07-16 17:55:07 +0200142 int status;
143
Yann Gautiera45433b2019-01-16 18:31:00 +0100144 status = stpmic1_regulator_voltage_set(node_name,
145 voltage);
Yann Gautierbb836ee2018-07-16 17:55:07 +0200146 if (status != 0) {
147 return status;
148 }
149
Yann Gautiera45433b2019-01-16 18:31:00 +0100150 status = stpmic1_regulator_enable(node_name);
Yann Gautierbb836ee2018-07-16 17:55:07 +0200151 if (status != 0) {
152 return status;
153 }
154 }
155 }
156
157 return 0;
158}
159
160void initialize_pmic_i2c(void)
161{
162 int ret;
163 struct dt_node_info i2c_info;
164
165 if (dt_pmic_i2c_config(&i2c_info) != 0) {
166 ERROR("I2C configuration failed\n");
167 panic();
168 }
169
170 if (stm32mp1_clk_enable((uint32_t)i2c_info.clock) < 0) {
171 ERROR("I2C clock enable failed\n");
172 panic();
173 }
174
175 /* Initialize PMIC I2C */
176 i2c_handle.i2c_base_addr = i2c_info.base;
177 i2c_handle.i2c_init.timing = I2C_TIMING;
178 i2c_handle.i2c_init.own_address1 = pmic_i2c_addr;
179 i2c_handle.i2c_init.addressing_mode = I2C_ADDRESSINGMODE_7BIT;
180 i2c_handle.i2c_init.dual_address_mode = I2C_DUALADDRESS_DISABLE;
181 i2c_handle.i2c_init.own_address2 = 0;
182 i2c_handle.i2c_init.own_address2_masks = I2C_OAR2_OA2NOMASK;
183 i2c_handle.i2c_init.general_call_mode = I2C_GENERALCALL_DISABLE;
184 i2c_handle.i2c_init.no_stretch_mode = I2C_NOSTRETCH_DISABLE;
185
186 ret = stm32_i2c_init(&i2c_handle);
187 if (ret != 0) {
188 ERROR("Cannot initialize I2C %x (%d)\n",
189 i2c_handle.i2c_base_addr, ret);
190 panic();
191 }
192
193 ret = stm32_i2c_config_analog_filter(&i2c_handle,
194 I2C_ANALOGFILTER_ENABLE);
195 if (ret != 0) {
196 ERROR("Cannot initialize I2C analog filter (%d)\n", ret);
197 panic();
198 }
199
200 ret = stm32_i2c_is_device_ready(&i2c_handle, (uint16_t)pmic_i2c_addr, 1,
201 I2C_TIMEOUT);
202 if (ret != 0) {
203 ERROR("I2C device not ready (%d)\n", ret);
204 panic();
205 }
206
Yann Gautiera45433b2019-01-16 18:31:00 +0100207 stpmic1_bind_i2c(&i2c_handle, (uint16_t)pmic_i2c_addr);
Yann Gautierbb836ee2018-07-16 17:55:07 +0200208}
209
210void initialize_pmic(void)
211{
212 int status;
213 uint8_t read_val;
214
215 initialize_pmic_i2c();
216
Yann Gautiera45433b2019-01-16 18:31:00 +0100217 status = stpmic1_register_read(VERSION_STATUS_REG, &read_val);
Yann Gautierbb836ee2018-07-16 17:55:07 +0200218 if (status != 0) {
219 panic();
220 }
221
222 INFO("PMIC version = 0x%x\n", read_val);
223
224 /* Keep VDD on during the reset cycle */
Yann Gautiera45433b2019-01-16 18:31:00 +0100225 status = stpmic1_register_update(MASK_RESET_BUCK_REG,
Yann Gautierbb836ee2018-07-16 17:55:07 +0200226 MASK_RESET_BUCK3,
227 MASK_RESET_BUCK3);
228 if (status != 0) {
229 panic();
230 }
231}
232
233int pmic_ddr_power_init(enum ddr_type ddr_type)
234{
235 bool buck3_at_1v8 = false;
236 uint8_t read_val;
237 int status;
238
239 switch (ddr_type) {
240 case STM32MP_DDR3:
241 /* Set LDO3 to sync mode */
Yann Gautiera45433b2019-01-16 18:31:00 +0100242 status = stpmic1_register_read(LDO3_CONTROL_REG, &read_val);
Yann Gautierbb836ee2018-07-16 17:55:07 +0200243 if (status != 0) {
244 return status;
245 }
246
Yann Gautiera45433b2019-01-16 18:31:00 +0100247 read_val &= ~STPMIC1_LDO3_MODE;
248 read_val &= ~STPMIC1_LDO12356_OUTPUT_MASK;
249 read_val |= STPMIC1_LDO3_DDR_SEL <<
250 STPMIC1_LDO12356_OUTPUT_SHIFT;
Yann Gautierbb836ee2018-07-16 17:55:07 +0200251
Yann Gautiera45433b2019-01-16 18:31:00 +0100252 status = stpmic1_register_write(LDO3_CONTROL_REG, read_val);
Yann Gautierbb836ee2018-07-16 17:55:07 +0200253 if (status != 0) {
254 return status;
255 }
256
Yann Gautiera45433b2019-01-16 18:31:00 +0100257 status = stpmic1_regulator_voltage_set("buck2", 1350);
Yann Gautierbb836ee2018-07-16 17:55:07 +0200258 if (status != 0) {
259 return status;
260 }
261
Yann Gautiera45433b2019-01-16 18:31:00 +0100262 status = stpmic1_regulator_enable("buck2");
Yann Gautierbb836ee2018-07-16 17:55:07 +0200263 if (status != 0) {
264 return status;
265 }
266
Yann Gautiera45433b2019-01-16 18:31:00 +0100267 mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
Yann Gautierbb836ee2018-07-16 17:55:07 +0200268
Yann Gautiera45433b2019-01-16 18:31:00 +0100269 status = stpmic1_regulator_enable("vref_ddr");
Yann Gautierbb836ee2018-07-16 17:55:07 +0200270 if (status != 0) {
271 return status;
272 }
273
Yann Gautiera45433b2019-01-16 18:31:00 +0100274 mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
Yann Gautierbb836ee2018-07-16 17:55:07 +0200275
Yann Gautiera45433b2019-01-16 18:31:00 +0100276 status = stpmic1_regulator_enable("ldo3");
Yann Gautierbb836ee2018-07-16 17:55:07 +0200277 if (status != 0) {
278 return status;
279 }
280
Yann Gautiera45433b2019-01-16 18:31:00 +0100281 mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
Yann Gautierbb836ee2018-07-16 17:55:07 +0200282 break;
283
284 case STM32MP_LPDDR2:
285 /*
286 * Set LDO3 to 1.8V
287 * Set LDO3 to bypass mode if BUCK3 = 1.8V
288 * Set LDO3 to normal mode if BUCK3 != 1.8V
289 */
Yann Gautiera45433b2019-01-16 18:31:00 +0100290 status = stpmic1_register_read(BUCK3_CONTROL_REG, &read_val);
Yann Gautierbb836ee2018-07-16 17:55:07 +0200291 if (status != 0) {
292 return status;
293 }
294
Yann Gautiera45433b2019-01-16 18:31:00 +0100295 if ((read_val & STPMIC1_BUCK3_1V8) == STPMIC1_BUCK3_1V8) {
Yann Gautierbb836ee2018-07-16 17:55:07 +0200296 buck3_at_1v8 = true;
297 }
298
Yann Gautiera45433b2019-01-16 18:31:00 +0100299 status = stpmic1_register_read(LDO3_CONTROL_REG, &read_val);
Yann Gautierbb836ee2018-07-16 17:55:07 +0200300 if (status != 0) {
301 return status;
302 }
303
Yann Gautiera45433b2019-01-16 18:31:00 +0100304 read_val &= ~STPMIC1_LDO3_MODE;
305 read_val &= ~STPMIC1_LDO12356_OUTPUT_MASK;
306 read_val |= STPMIC1_LDO3_1800000;
Yann Gautierbb836ee2018-07-16 17:55:07 +0200307 if (buck3_at_1v8) {
Yann Gautiera45433b2019-01-16 18:31:00 +0100308 read_val |= STPMIC1_LDO3_MODE;
Yann Gautierbb836ee2018-07-16 17:55:07 +0200309 }
310
Yann Gautiera45433b2019-01-16 18:31:00 +0100311 status = stpmic1_register_write(LDO3_CONTROL_REG, read_val);
Yann Gautierbb836ee2018-07-16 17:55:07 +0200312 if (status != 0) {
313 return status;
314 }
315
Yann Gautiera45433b2019-01-16 18:31:00 +0100316 status = stpmic1_regulator_voltage_set("buck2", 1200);
Yann Gautierbb836ee2018-07-16 17:55:07 +0200317 if (status != 0) {
318 return status;
319 }
320
Yann Gautiera45433b2019-01-16 18:31:00 +0100321 status = stpmic1_regulator_enable("ldo3");
Yann Gautierbb836ee2018-07-16 17:55:07 +0200322 if (status != 0) {
323 return status;
324 }
325
Yann Gautiera45433b2019-01-16 18:31:00 +0100326 mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
Yann Gautierbb836ee2018-07-16 17:55:07 +0200327
Yann Gautiera45433b2019-01-16 18:31:00 +0100328 status = stpmic1_regulator_enable("buck2");
Yann Gautierbb836ee2018-07-16 17:55:07 +0200329 if (status != 0) {
330 return status;
331 }
332
Yann Gautiera45433b2019-01-16 18:31:00 +0100333 mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
Yann Gautierbb836ee2018-07-16 17:55:07 +0200334
Yann Gautiera45433b2019-01-16 18:31:00 +0100335 status = stpmic1_regulator_enable("vref_ddr");
Yann Gautierbb836ee2018-07-16 17:55:07 +0200336 if (status != 0) {
337 return status;
338 }
339
Yann Gautiera45433b2019-01-16 18:31:00 +0100340 mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
Yann Gautierbb836ee2018-07-16 17:55:07 +0200341 break;
342
343 default:
344 break;
345 };
346
347 return 0;
348}