blob: 45c2bb5bceacbc77989a9ddbf65ea792934d96b6 [file] [log] [blame]
Patrick Delaunayff0c0bc2020-05-25 12:19:43 +02001// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
2/*
3 * Copyright (C) 2020, STMicroelectronics - All Rights Reserved
4 */
5
Patrick Delaunay9742bee2020-11-06 19:02:00 +01006#define LOG_CATEGORY LOGC_BOARD
7
Patrick Delaunayff0c0bc2020-05-25 12:19:43 +02008#include <dm.h>
Patrick Delaunay9742bee2020-11-06 19:02:00 +01009#include <log.h>
Patrick Delaunayf2f25c32020-05-25 12:19:46 +020010#include <asm/io.h>
Patrick Delaunayff0c0bc2020-05-25 12:19:43 +020011#include <asm/arch/ddr.h>
12#include <linux/bitops.h>
13#include <linux/delay.h>
14#include <power/pmic.h>
15#include <power/stpmic1.h>
16
17int board_ddr_power_init(enum ddr_type ddr_type)
18{
19 struct udevice *dev;
20 bool buck3_at_1800000v = false;
21 int ret;
22 u32 buck2;
23
24 ret = uclass_get_device_by_driver(UCLASS_PMIC,
Simon Glass65130cd2020-12-28 20:34:56 -070025 DM_DRIVER_GET(pmic_stpmic1), &dev);
Patrick Delaunayff0c0bc2020-05-25 12:19:43 +020026 if (ret)
27 /* No PMIC on board */
28 return 0;
29
30 switch (ddr_type) {
31 case STM32MP_DDR3:
32 /* VTT = Set LDO3 to sync mode */
33 ret = pmic_reg_read(dev, STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3));
34 if (ret < 0)
35 return ret;
36
37 ret &= ~STPMIC1_LDO3_MODE;
38 ret &= ~STPMIC1_LDO12356_VOUT_MASK;
39 ret |= STPMIC1_LDO_VOUT(STPMIC1_LDO3_DDR_SEL);
40
41 ret = pmic_reg_write(dev, STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3),
42 ret);
43 if (ret < 0)
44 return ret;
45
46 /* VDD_DDR = Set BUCK2 to 1.35V */
47 ret = pmic_clrsetbits(dev,
48 STPMIC1_BUCKX_MAIN_CR(STPMIC1_BUCK2),
49 STPMIC1_BUCK_VOUT_MASK,
50 STPMIC1_BUCK2_1350000V);
51 if (ret < 0)
52 return ret;
53
54 /* Enable VDD_DDR = BUCK2 */
55 ret = pmic_clrsetbits(dev,
56 STPMIC1_BUCKX_MAIN_CR(STPMIC1_BUCK2),
57 STPMIC1_BUCK_ENA, STPMIC1_BUCK_ENA);
58 if (ret < 0)
59 return ret;
60
61 mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
62
63 /* Enable VREF */
64 ret = pmic_clrsetbits(dev, STPMIC1_REFDDR_MAIN_CR,
65 STPMIC1_VREF_ENA, STPMIC1_VREF_ENA);
66 if (ret < 0)
67 return ret;
68
69 mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
70
71 /* Enable VTT = LDO3 */
72 ret = pmic_clrsetbits(dev,
73 STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3),
74 STPMIC1_LDO_ENA, STPMIC1_LDO_ENA);
75 if (ret < 0)
76 return ret;
77
78 mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
79
80 break;
81
82 case STM32MP_LPDDR2_16:
83 case STM32MP_LPDDR2_32:
84 case STM32MP_LPDDR3_16:
85 case STM32MP_LPDDR3_32:
86 /*
87 * configure VDD_DDR1 = LDO3
88 * Set LDO3 to 1.8V
89 * + bypass mode if BUCK3 = 1.8V
90 * + normal mode if BUCK3 != 1.8V
91 */
92 ret = pmic_reg_read(dev,
93 STPMIC1_BUCKX_MAIN_CR(STPMIC1_BUCK3));
94 if (ret < 0)
95 return ret;
96
97 if ((ret & STPMIC1_BUCK3_1800000V) == STPMIC1_BUCK3_1800000V)
98 buck3_at_1800000v = true;
99
100 ret = pmic_reg_read(dev, STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3));
101 if (ret < 0)
102 return ret;
103
104 ret &= ~STPMIC1_LDO3_MODE;
105 ret &= ~STPMIC1_LDO12356_VOUT_MASK;
106 ret |= STPMIC1_LDO3_1800000;
107 if (buck3_at_1800000v)
108 ret |= STPMIC1_LDO3_MODE;
109
110 ret = pmic_reg_write(dev, STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3),
111 ret);
112 if (ret < 0)
113 return ret;
114
115 /* VDD_DDR2 : Set BUCK2 to 1.2V (16bits) or 1.25V (32 bits)*/
116 switch (ddr_type) {
117 case STM32MP_LPDDR2_32:
118 case STM32MP_LPDDR3_32:
119 buck2 = STPMIC1_BUCK2_1250000V;
120 break;
121 default:
122 case STM32MP_LPDDR2_16:
123 case STM32MP_LPDDR3_16:
124 buck2 = STPMIC1_BUCK2_1200000V;
125 break;
126 }
127
128 ret = pmic_clrsetbits(dev,
129 STPMIC1_BUCKX_MAIN_CR(STPMIC1_BUCK2),
130 STPMIC1_BUCK_VOUT_MASK,
131 buck2);
132 if (ret < 0)
133 return ret;
134
135 /* Enable VDD_DDR1 = LDO3 */
136 ret = pmic_clrsetbits(dev, STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3),
137 STPMIC1_LDO_ENA, STPMIC1_LDO_ENA);
138 if (ret < 0)
139 return ret;
140
141 mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
142
143 /* Enable VDD_DDR2 =BUCK2 */
144 ret = pmic_clrsetbits(dev,
145 STPMIC1_BUCKX_MAIN_CR(STPMIC1_BUCK2),
146 STPMIC1_BUCK_ENA, STPMIC1_BUCK_ENA);
147 if (ret < 0)
148 return ret;
149
150 mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
151
152 /* Enable VREF */
153 ret = pmic_clrsetbits(dev, STPMIC1_REFDDR_MAIN_CR,
154 STPMIC1_VREF_ENA, STPMIC1_VREF_ENA);
155 if (ret < 0)
156 return ret;
157
158 mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
159
160 break;
161
162 default:
163 break;
164 };
165
166 return 0;
167}
Patrick Delaunayf2f25c32020-05-25 12:19:46 +0200168
Patrick Delaunay08c891a2020-05-25 12:19:47 +0200169static int stmpic_buck1_set(struct udevice *dev, u32 voltage_mv)
170{
171 u32 value;
172
173 /* VDDCORE= STMPCI1 BUCK1 ramp=+25mV, 5 => 725mV, 36 => 1500mV */
174 value = ((voltage_mv - 725) / 25) + 5;
175 if (value < 5)
176 value = 5;
177 if (value > 36)
178 value = 36;
179
180 return pmic_clrsetbits(dev,
181 STPMIC1_BUCKX_MAIN_CR(STPMIC1_BUCK1),
182 STPMIC1_BUCK_VOUT_MASK,
183 STPMIC1_BUCK_VOUT(value));
184}
185
Patrick Delaunayf2f25c32020-05-25 12:19:46 +0200186/* early init of PMIC */
Marek Vasut5bfe0a12023-05-18 00:02:39 +0200187struct udevice *stpmic1_init(u32 voltage_mv)
Patrick Delaunayf2f25c32020-05-25 12:19:46 +0200188{
189 struct udevice *dev;
190
191 if (uclass_get_device_by_driver(UCLASS_PMIC,
Simon Glass65130cd2020-12-28 20:34:56 -0700192 DM_DRIVER_GET(pmic_stpmic1), &dev))
Marek Vasut5bfe0a12023-05-18 00:02:39 +0200193 return NULL;
Patrick Delaunayf2f25c32020-05-25 12:19:46 +0200194
Patrick Delaunay08c891a2020-05-25 12:19:47 +0200195 /* update VDDCORE = BUCK1 */
196 if (voltage_mv)
197 stmpic_buck1_set(dev, voltage_mv);
198
Marek Vasut5bfe0a12023-05-18 00:02:39 +0200199 return dev;
Patrick Delaunayf2f25c32020-05-25 12:19:46 +0200200}