Commit 23a12cb3d05ee2caa860bee7b6f0ebcb40afacce
Committed by
York Sun
1 parent
6f2d0a5020
Exists in
smarc_8mq_lf_v2020.04
and in
17 other branches
board: common: vid: Add support for LTC3882 voltage regulator chip
Restructures common driver to support LTC3882 voltage regulator chip. Signed-off-by: Ashish Kumar <Ashish.Kumar@nxp.com> Signed-off-by: Rajesh Bhagat <rajesh.bhagat@nxp.com> Reviewed-by: York Sun <york.sun@nxp.com>
Showing 4 changed files with 115 additions and 2 deletions Side-by-side Diff
arch/arm/include/asm/arch-fsl-layerscape/immap_lsch3.h
... | ... | @@ -201,10 +201,15 @@ |
201 | 201 | u32 gpporcr3; |
202 | 202 | u32 gpporcr4; |
203 | 203 | u8 res_030[0x60-0x30]; |
204 | -#define FSL_CHASSIS3_DCFG_FUSESR_VID_SHIFT 2 | |
205 | 204 | #define FSL_CHASSIS3_DCFG_FUSESR_VID_MASK 0x1F |
206 | -#define FSL_CHASSIS3_DCFG_FUSESR_ALTVID_SHIFT 7 | |
207 | 205 | #define FSL_CHASSIS3_DCFG_FUSESR_ALTVID_MASK 0x1F |
206 | +#if defined(CONFIG_ARCH_LS1088A) | |
207 | +#define FSL_CHASSIS3_DCFG_FUSESR_VID_SHIFT 25 | |
208 | +#define FSL_CHASSIS3_DCFG_FUSESR_ALTVID_SHIFT 20 | |
209 | +#else | |
210 | +#define FSL_CHASSIS3_DCFG_FUSESR_VID_SHIFT 2 | |
211 | +#define FSL_CHASSIS3_DCFG_FUSESR_ALTVID_SHIFT 7 | |
212 | +#endif | |
208 | 213 | u32 dcfg_fusesr; /* Fuse status register */ |
209 | 214 | u8 res_064[0x70-0x64]; |
210 | 215 | u32 devdisr; /* Device disable control 1 */ |
board/freescale/common/vid.c
... | ... | @@ -174,6 +174,36 @@ |
174 | 174 | } |
175 | 175 | #endif |
176 | 176 | |
177 | +#ifdef CONFIG_VOL_MONITOR_LTC3882_READ | |
178 | +/* read the current value of the LTC Regulator Voltage */ | |
179 | +static int read_voltage_from_LTC(int i2caddress) | |
180 | +{ | |
181 | + int ret, vcode = 0; | |
182 | + u8 chan = PWM_CHANNEL0; | |
183 | + | |
184 | + /* select the PAGE 0 using PMBus commands PAGE for VDD*/ | |
185 | + ret = i2c_write(I2C_VOL_MONITOR_ADDR, | |
186 | + PMBUS_CMD_PAGE, 1, &chan, 1); | |
187 | + if (ret) { | |
188 | + printf("VID: failed to select VDD Page 0\n"); | |
189 | + return ret; | |
190 | + } | |
191 | + | |
192 | + /*read the output voltage using PMBus command READ_VOUT*/ | |
193 | + ret = i2c_read(I2C_VOL_MONITOR_ADDR, | |
194 | + PMBUS_CMD_READ_VOUT, 1, (void *)&vcode, 2); | |
195 | + if (ret) { | |
196 | + printf("VID: failed to read the volatge\n"); | |
197 | + return ret; | |
198 | + } | |
199 | + | |
200 | + /* Scale down to the real mV as LTC resolution is 1/4096V,rounding up */ | |
201 | + vcode = DIV_ROUND_UP(vcode * 1000, 4096); | |
202 | + | |
203 | + return vcode; | |
204 | +} | |
205 | +#endif | |
206 | + | |
177 | 207 | static int read_voltage(int i2caddress) |
178 | 208 | { |
179 | 209 | int voltage_read; |
... | ... | @@ -181,6 +211,8 @@ |
181 | 211 | voltage_read = read_voltage_from_INA220(i2caddress); |
182 | 212 | #elif defined CONFIG_VOL_MONITOR_IR36021_READ |
183 | 213 | voltage_read = read_voltage_from_IR(i2caddress); |
214 | +#elif defined CONFIG_VOL_MONITOR_LTC3882_READ | |
215 | + voltage_read = read_voltage_from_LTC(i2caddress); | |
184 | 216 | #else |
185 | 217 | return -1; |
186 | 218 | #endif |
187 | 219 | |
188 | 220 | |
... | ... | @@ -281,14 +313,53 @@ |
281 | 313 | debug("VID: Current voltage is %d mV\n", vdd_last); |
282 | 314 | return vdd_last; |
283 | 315 | } |
316 | + | |
284 | 317 | #endif |
285 | 318 | |
319 | +#ifdef CONFIG_VOL_MONITOR_LTC3882_SET | |
320 | +/* this function sets the VDD and returns the value set */ | |
321 | +static int set_voltage_to_LTC(int i2caddress, int vdd) | |
322 | +{ | |
323 | + int ret, vdd_last, vdd_target = vdd; | |
324 | + | |
325 | + /* Scale up to the LTC resolution is 1/4096V */ | |
326 | + vdd = (vdd * 4096) / 1000; | |
327 | + | |
328 | + /* 5-byte buffer which needs to be sent following the | |
329 | + * PMBus command PAGE_PLUS_WRITE. | |
330 | + */ | |
331 | + u8 buff[5] = {0x04, PWM_CHANNEL0, PMBUS_CMD_VOUT_COMMAND, | |
332 | + vdd & 0xFF, (vdd & 0xFF00) >> 8}; | |
333 | + | |
334 | + /* Write the desired voltage code to the regulator */ | |
335 | + ret = i2c_write(I2C_VOL_MONITOR_ADDR, | |
336 | + PMBUS_CMD_PAGE_PLUS_WRITE, 1, (void *)&buff, 5); | |
337 | + if (ret) { | |
338 | + printf("VID: I2C failed to write to the volatge regulator\n"); | |
339 | + return -1; | |
340 | + } | |
341 | + | |
342 | + /* Wait for the volatge to get to the desired value */ | |
343 | + do { | |
344 | + vdd_last = read_voltage_from_LTC(i2caddress); | |
345 | + if (vdd_last < 0) { | |
346 | + printf("VID: Couldn't read sensor abort VID adjust\n"); | |
347 | + return -1; | |
348 | + } | |
349 | + } while (vdd_last != vdd_target); | |
350 | + | |
351 | + return vdd_last; | |
352 | +} | |
353 | +#endif | |
354 | + | |
286 | 355 | static int set_voltage(int i2caddress, int vdd) |
287 | 356 | { |
288 | 357 | int vdd_last = -1; |
289 | 358 | |
290 | 359 | #ifdef CONFIG_VOL_MONITOR_IR36021_SET |
291 | 360 | vdd_last = set_voltage_to_IR(i2caddress, vdd); |
361 | +#elif defined CONFIG_VOL_MONITOR_LTC3882_SET | |
362 | + vdd_last = set_voltage_to_LTC(i2caddress, vdd); | |
292 | 363 | #else |
293 | 364 | #error Specific voltage monitor must be defined |
294 | 365 | #endif |
... | ... | @@ -472,6 +543,11 @@ |
472 | 543 | } |
473 | 544 | vdd_current = vdd_last; |
474 | 545 | debug("VID: Core voltage is currently at %d mV\n", vdd_last); |
546 | + | |
547 | +#ifdef CONFIG_VOL_MONITOR_LTC3882_SET | |
548 | + /* Set the target voltage */ | |
549 | + vdd_last = vdd_current = set_voltage(i2caddress, vdd_target); | |
550 | +#else | |
475 | 551 | /* |
476 | 552 | * Adjust voltage to at or one step above target. |
477 | 553 | * As measurements are less precise than setting the values |
... | ... | @@ -489,6 +565,7 @@ |
489 | 565 | vdd_last = set_voltage(i2caddress, vdd_current); |
490 | 566 | } |
491 | 567 | |
568 | +#endif | |
492 | 569 | if (board_adjust_vdd(vdd_target) < 0) { |
493 | 570 | ret = -1; |
494 | 571 | goto exit; |
include/configs/ls1088aqds.h
... | ... | @@ -279,6 +279,22 @@ |
279 | 279 | #define I2C_MUX_CH_DEFAULT 0x8 |
280 | 280 | #define I2C_MUX_CH5 0xD |
281 | 281 | |
282 | +#define I2C_MUX_CH_VOL_MONITOR 0xA | |
283 | + | |
284 | +/* Voltage monitor on channel 2*/ | |
285 | +#define I2C_VOL_MONITOR_ADDR 0x63 | |
286 | +#define I2C_VOL_MONITOR_BUS_V_OFFSET 0x2 | |
287 | +#define I2C_VOL_MONITOR_BUS_V_OVF 0x1 | |
288 | +#define I2C_VOL_MONITOR_BUS_V_SHIFT 3 | |
289 | + | |
290 | +/* PM Bus commands code for LTC3882*/ | |
291 | +#define PMBUS_CMD_PAGE 0x0 | |
292 | +#define PMBUS_CMD_READ_VOUT 0x8B | |
293 | +#define PMBUS_CMD_PAGE_PLUS_WRITE 0x05 | |
294 | +#define PMBUS_CMD_VOUT_COMMAND 0x21 | |
295 | + | |
296 | +#define PWM_CHANNEL0 0x0 | |
297 | + | |
282 | 298 | /* |
283 | 299 | * RTC configuration |
284 | 300 | */ |
include/configs/ls1088ardb.h
... | ... | @@ -225,6 +225,21 @@ |
225 | 225 | |
226 | 226 | #define CONFIG_SYS_LS_MC_BOOT_TIMEOUT_MS 5000 |
227 | 227 | |
228 | +#define I2C_MUX_CH_VOL_MONITOR 0xA | |
229 | +/* Voltage monitor on channel 2*/ | |
230 | +#define I2C_VOL_MONITOR_ADDR 0x63 | |
231 | +#define I2C_VOL_MONITOR_BUS_V_OFFSET 0x2 | |
232 | +#define I2C_VOL_MONITOR_BUS_V_OVF 0x1 | |
233 | +#define I2C_VOL_MONITOR_BUS_V_SHIFT 3 | |
234 | + | |
235 | +/* PM Bus commands code for LTC3882*/ | |
236 | +#define PMBUS_CMD_PAGE 0x0 | |
237 | +#define PMBUS_CMD_READ_VOUT 0x8B | |
238 | +#define PMBUS_CMD_PAGE_PLUS_WRITE 0x05 | |
239 | +#define PMBUS_CMD_VOUT_COMMAND 0x21 | |
240 | + | |
241 | +#define PWM_CHANNEL0 0x0 | |
242 | + | |
228 | 243 | /* |
229 | 244 | * I2C bus multiplexer |
230 | 245 | */ |