diff options
Diffstat (limited to 'board/nxp/common')
| -rw-r--r-- | board/nxp/common/Makefile | 2 | ||||
| -rw-r--r-- | board/nxp/common/i2c_mux.h | 5 | ||||
| -rw-r--r-- | board/nxp/common/pfuze.c | 96 | ||||
| -rw-r--r-- | board/nxp/common/pfuze.h | 2 | ||||
| -rw-r--r-- | board/nxp/common/vid.c | 110 | ||||
| -rw-r--r-- | board/nxp/common/vid.h | 15 |
6 files changed, 125 insertions, 105 deletions
diff --git a/board/nxp/common/Makefile b/board/nxp/common/Makefile index ed102ae7bf7..dafd3717948 100644 --- a/board/nxp/common/Makefile +++ b/board/nxp/common/Makefile @@ -57,7 +57,7 @@ obj-$(CONFIG_TARGET_P5040DS) += ics307_clk.o ifeq ($(CONFIG_$(PHASE_)POWER_LEGACY),y) obj-$(CONFIG_POWER_PFUZE100) += pfuze.o endif -obj-$(CONFIG_DM_PMIC_PFUZE100) += pfuze.o +obj-$(CONFIG_$(PHASE_)DM_PMIC_PFUZE100) += pfuze.o obj-$(CONFIG_POWER_MC34VR500) += mc34vr500.o ifneq (,$(filter $(SOC), imx8m imx8ulp imx9)) obj-y += mmc.o diff --git a/board/nxp/common/i2c_mux.h b/board/nxp/common/i2c_mux.h index 0870c1918e6..ef7ce8e2e51 100644 --- a/board/nxp/common/i2c_mux.h +++ b/board/nxp/common/i2c_mux.h @@ -10,6 +10,11 @@ #ifdef CONFIG_FSL_USE_PCA9547_MUX int select_i2c_ch_pca9547(u8 ch, int bus); +#else +static inline int select_i2c_ch_pca9547(u8 ch, int bus) +{ + return -EOPNOTSUPP; +} #endif #endif diff --git a/board/nxp/common/pfuze.c b/board/nxp/common/pfuze.c index 0d7a94fd232..179cc605da0 100644 --- a/board/nxp/common/pfuze.c +++ b/board/nxp/common/pfuze.c @@ -7,14 +7,14 @@ #include <power/pmic.h> #include <power/pfuze100_pmic.h> -#ifndef CONFIG_DM_PMIC_PFUZE100 -int pfuze_mode_init(struct pmic *p, u32 mode) +#if CONFIG_IS_ENABLED(DM_PMIC_PFUZE100) +int pfuze_mode_init(struct udevice *dev, u32 mode) { unsigned char offset, i, switch_num; u32 id; int ret; - pmic_reg_read(p, PFUZE100_DEVICEID, &id); + id = pmic_reg_read(dev, PFUZE100_DEVICEID); id = id & 0xf; if (id == 0) { @@ -28,14 +28,14 @@ int pfuze_mode_init(struct pmic *p, u32 mode) return -EINVAL; } - ret = pmic_reg_write(p, PFUZE100_SW1ABMODE, mode); + ret = pmic_reg_write(dev, PFUZE100_SW1ABMODE, mode); if (ret < 0) { printf("Set SW1AB mode error!\n"); return ret; } for (i = 0; i < switch_num - 1; i++) { - ret = pmic_reg_write(p, offset + i * SWITCH_SIZE, mode); + ret = pmic_reg_write(dev, offset + i * SWITCH_SIZE, mode); if (ret < 0) { printf("Set switch 0x%x mode error!\n", offset + i * SWITCH_SIZE); @@ -46,58 +46,54 @@ int pfuze_mode_init(struct pmic *p, u32 mode) return ret; } -struct pmic *pfuze_common_init(unsigned char i2cbus) +struct udevice *pfuze_common_init(void) { - struct pmic *p; + struct udevice *dev; int ret; - unsigned int reg; - - ret = power_pfuze100_init(i2cbus); - if (ret) - return NULL; + unsigned int reg, dev_id, rev_id; - p = pmic_get("PFUZE100"); - ret = pmic_probe(p); - if (ret) + ret = pmic_get("pfuze100@8", &dev); + if (ret == -ENODEV) return NULL; - pmic_reg_read(p, PFUZE100_DEVICEID, ®); - printf("PMIC: PFUZE100 ID=0x%02x\n", reg); + dev_id = pmic_reg_read(dev, PFUZE100_DEVICEID); + rev_id = pmic_reg_read(dev, PFUZE100_REVID); + printf("PMIC: PFUZE100! DEV_ID=0x%x REV_ID=0x%x\n", dev_id, rev_id); /* Set SW1AB stanby volage to 0.975V */ - pmic_reg_read(p, PFUZE100_SW1ABSTBY, ®); + reg = pmic_reg_read(dev, PFUZE100_SW1ABSTBY); reg &= ~SW1x_STBY_MASK; reg |= SW1x_0_975V; - pmic_reg_write(p, PFUZE100_SW1ABSTBY, reg); + pmic_reg_write(dev, PFUZE100_SW1ABSTBY, reg); /* Set SW1AB/VDDARM step ramp up time from 16us to 4us/25mV */ - pmic_reg_read(p, PFUZE100_SW1ABCONF, ®); + reg = pmic_reg_read(dev, PFUZE100_SW1ABCONF); reg &= ~SW1xCONF_DVSSPEED_MASK; reg |= SW1xCONF_DVSSPEED_4US; - pmic_reg_write(p, PFUZE100_SW1ABCONF, reg); + pmic_reg_write(dev, PFUZE100_SW1ABCONF, reg); /* Set SW1C standby voltage to 0.975V */ - pmic_reg_read(p, PFUZE100_SW1CSTBY, ®); + reg = pmic_reg_read(dev, PFUZE100_SW1CSTBY); reg &= ~SW1x_STBY_MASK; reg |= SW1x_0_975V; - pmic_reg_write(p, PFUZE100_SW1CSTBY, reg); + pmic_reg_write(dev, PFUZE100_SW1CSTBY, reg); /* Set SW1C/VDDSOC step ramp up time from 16us to 4us/25mV */ - pmic_reg_read(p, PFUZE100_SW1CCONF, ®); + reg = pmic_reg_read(dev, PFUZE100_SW1CCONF); reg &= ~SW1xCONF_DVSSPEED_MASK; reg |= SW1xCONF_DVSSPEED_4US; - pmic_reg_write(p, PFUZE100_SW1CCONF, reg); + pmic_reg_write(dev, PFUZE100_SW1CCONF, reg); - return p; + return dev; } -#elif defined(CONFIG_DM_PMIC) -int pfuze_mode_init(struct udevice *dev, u32 mode) +#else +int pfuze_mode_init(struct pmic *p, u32 mode) { unsigned char offset, i, switch_num; u32 id; int ret; - id = pmic_reg_read(dev, PFUZE100_DEVICEID); + pmic_reg_read(p, PFUZE100_DEVICEID, &id); id = id & 0xf; if (id == 0) { @@ -111,14 +107,14 @@ int pfuze_mode_init(struct udevice *dev, u32 mode) return -EINVAL; } - ret = pmic_reg_write(dev, PFUZE100_SW1ABMODE, mode); + ret = pmic_reg_write(p, PFUZE100_SW1ABMODE, mode); if (ret < 0) { printf("Set SW1AB mode error!\n"); return ret; } for (i = 0; i < switch_num - 1; i++) { - ret = pmic_reg_write(dev, offset + i * SWITCH_SIZE, mode); + ret = pmic_reg_write(p, offset + i * SWITCH_SIZE, mode); if (ret < 0) { printf("Set switch 0x%x mode error!\n", offset + i * SWITCH_SIZE); @@ -129,44 +125,48 @@ int pfuze_mode_init(struct udevice *dev, u32 mode) return ret; } -struct udevice *pfuze_common_init(void) +struct pmic *pfuze_common_init(unsigned char i2cbus) { - struct udevice *dev; + struct pmic *p; int ret; - unsigned int reg, dev_id, rev_id; + unsigned int reg; - ret = pmic_get("pfuze100@8", &dev); - if (ret == -ENODEV) + ret = power_pfuze100_init(i2cbus); + if (ret) return NULL; - dev_id = pmic_reg_read(dev, PFUZE100_DEVICEID); - rev_id = pmic_reg_read(dev, PFUZE100_REVID); - printf("PMIC: PFUZE100! DEV_ID=0x%x REV_ID=0x%x\n", dev_id, rev_id); + p = pmic_get("PFUZE100"); + ret = pmic_probe(p); + if (ret) + return NULL; + + pmic_reg_read(p, PFUZE100_DEVICEID, ®); + printf("PMIC: PFUZE100 ID=0x%02x\n", reg); /* Set SW1AB stanby volage to 0.975V */ - reg = pmic_reg_read(dev, PFUZE100_SW1ABSTBY); + pmic_reg_read(p, PFUZE100_SW1ABSTBY, ®); reg &= ~SW1x_STBY_MASK; reg |= SW1x_0_975V; - pmic_reg_write(dev, PFUZE100_SW1ABSTBY, reg); + pmic_reg_write(p, PFUZE100_SW1ABSTBY, reg); /* Set SW1AB/VDDARM step ramp up time from 16us to 4us/25mV */ - reg = pmic_reg_read(dev, PFUZE100_SW1ABCONF); + pmic_reg_read(p, PFUZE100_SW1ABCONF, ®); reg &= ~SW1xCONF_DVSSPEED_MASK; reg |= SW1xCONF_DVSSPEED_4US; - pmic_reg_write(dev, PFUZE100_SW1ABCONF, reg); + pmic_reg_write(p, PFUZE100_SW1ABCONF, reg); /* Set SW1C standby voltage to 0.975V */ - reg = pmic_reg_read(dev, PFUZE100_SW1CSTBY); + pmic_reg_read(p, PFUZE100_SW1CSTBY, ®); reg &= ~SW1x_STBY_MASK; reg |= SW1x_0_975V; - pmic_reg_write(dev, PFUZE100_SW1CSTBY, reg); + pmic_reg_write(p, PFUZE100_SW1CSTBY, reg); /* Set SW1C/VDDSOC step ramp up time from 16us to 4us/25mV */ - reg = pmic_reg_read(dev, PFUZE100_SW1CCONF); + pmic_reg_read(p, PFUZE100_SW1CCONF, ®); reg &= ~SW1xCONF_DVSSPEED_MASK; reg |= SW1xCONF_DVSSPEED_4US; - pmic_reg_write(dev, PFUZE100_SW1CCONF, reg); + pmic_reg_write(p, PFUZE100_SW1CCONF, reg); - return dev; + return p; } #endif diff --git a/board/nxp/common/pfuze.h b/board/nxp/common/pfuze.h index 45b49afaeb7..da89853bd20 100644 --- a/board/nxp/common/pfuze.h +++ b/board/nxp/common/pfuze.h @@ -6,7 +6,7 @@ #ifndef __PFUZE_BOARD_HELPER__ #define __PFUZE_BOARD_HELPER__ -#ifdef CONFIG_DM_PMIC_PFUZE100 +#if CONFIG_IS_ENABLED(DM_PMIC_PFUZE100) struct udevice *pfuze_common_init(void); int pfuze_mode_init(struct udevice *dev, u32 mode); #else diff --git a/board/nxp/common/vid.c b/board/nxp/common/vid.c index 84cb43fad56..70c3b3ecfd8 100644 --- a/board/nxp/common/vid.c +++ b/board/nxp/common/vid.c @@ -11,6 +11,7 @@ #include <i2c.h> #include <irq_func.h> #include <log.h> +#include <pmbus.h> #include <vsprintf.h> #include <asm/io.h> #ifdef CONFIG_FSL_LSCH2 @@ -260,45 +261,38 @@ static int read_voltage_from_IR(int i2caddress) */ #define VOUT_WARNING "VID: VOUT_MODE exponent has resolution worse than 1 V!\n" -/* Checks the PMBus voltage monitor for the format used for voltage values */ -static int get_pmbus_multiplier(DEVICE_HANDLE_T dev) +/* + * Read VOUT_MODE for downstream LINEAR16 decode/encode through the + * tree level <pmbus.h> helpers (pmbus_reg2data_linear16, + * pmbus_data2reg_linear16). Stores the raw VOUT_MODE byte in *mode + * and returns 0 on success, or the negative bus error (a failed read + * must not be decoded: raw 0 aliases Linear mode with exponent 0). + * Emits VOUT_WARNING on Linear mode chips with a non negative + * exponent (resolution >= 1 V is unusable for sub volt SoC rails) + * and an informational note on the unsupported VID format. + */ +static int vid_read_vout_mode(DEVICE_HANDLE_T dev, u8 *mode) { - u8 mode; - int exponent, multiplier, ret; + int ret; - ret = I2C_READ(dev, PMBUS_CMD_VOUT_MODE, &mode, sizeof(mode)); + ret = pmbus_read_byte(dev, PMBUS_VOUT_MODE, mode); if (ret) { printf("VID: unable to determine voltage multiplier\n"); - return 1; + return ret; } - /* Upper 3 bits is mode, lower 5 bits is exponent */ - exponent = (int)mode & 0x1F; - mode >>= 5; - switch (mode) { - case 0: - /* Linear, 5 bit twos component exponent */ - if (exponent & 0x10) { - multiplier = 1 << (16 - (exponent & 0xF)); - } else { - /* If exponent is >= 0, then resolution is 1 V! */ + switch (*mode & PB_VOUT_MODE_MODE_MASK) { + case PB_VOUT_MODE_LINEAR: + if (!(*mode & 0x10)) printf(VOUT_WARNING); - multiplier = 1; - } break; - case 1: - /* VID code identifier */ + case PB_VOUT_MODE_VID: printf("VID: custom VID codes are not supported\n"); - multiplier = MV_PER_V; break; default: - /* Direct, in mV */ - multiplier = MV_PER_V; break; } - - debug("VID: calculated multiplier is %d\n", multiplier); - return multiplier; + return 0; } #endif @@ -306,8 +300,8 @@ static int get_pmbus_multiplier(DEVICE_HANDLE_T dev) defined(CONFIG_VOL_MONITOR_LTC3882_READ) static int read_voltage_from_pmbus(int i2caddress) { - int ret, multiplier, vout; - u8 channel = PWM_CHANNEL0; + int ret, vout; + u8 channel = PWM_CHANNEL0, vout_mode; u16 vcode; DEVICE_HANDLE_T dev; @@ -317,25 +311,33 @@ static int read_voltage_from_pmbus(int i2caddress) return ret; /* Select the right page */ - ret = I2C_WRITE(dev, PMBUS_CMD_PAGE, &channel, sizeof(channel)); + ret = pmbus_write_byte(dev, PMBUS_PAGE, channel); if (ret) { printf("VID: failed to select VDD page %d\n", channel); return ret; } - /* VOUT is little endian */ - ret = I2C_READ(dev, PMBUS_CMD_READ_VOUT, (void *)&vcode, sizeof(vcode)); + ret = pmbus_read_word(dev, PMBUS_READ_VOUT, &vcode); if (ret) { printf("VID: failed to read core voltage\n"); return ret; } - /* Scale down to the real mV */ - multiplier = get_pmbus_multiplier(dev); - vout = (int)vcode; - /* Multiplier 1000 (direct mode) requires no change to convert */ - if (multiplier != MV_PER_V) - vout = DIV_ROUND_UP(vout * MV_PER_V, multiplier); + /* + * Decode LINEAR16 via the tree level helper from <pmbus.h>. For + * non Linear VOUT_MODE settings the helper returns 0; fall back + * to the historic mV pass through so existing LSCH boards keep. + */ + ret = vid_read_vout_mode(dev, &vout_mode); + if (ret) + return ret; + if ((vout_mode & PB_VOUT_MODE_MODE_MASK) == PB_VOUT_MODE_LINEAR) { + s64 uv = pmbus_reg2data_linear16(vcode, vout_mode); + + vout = (int)((uv + 500) / 1000); /* round to mV */ + } else { + vout = (int)vcode; + } return vout - board_vdd_drop_compensation(); } #endif @@ -463,11 +465,13 @@ static int set_voltage_to_IR(int i2caddress, int vdd) static int set_voltage_to_pmbus(int i2caddress, int vdd) { int ret, vdd_last, vdd_target = vdd; - int count = MAX_LOOP_WAIT_NEW_VOL, temp = 0, multiplier; + int count = MAX_LOOP_WAIT_NEW_VOL, temp = 0; + u8 vout_mode; + u16 raw; unsigned char value; /* The data to be sent with the PMBus command PAGE_PLUS_WRITE */ - u8 buffer[5] = { 0x04, PWM_CHANNEL0, PMBUS_CMD_VOUT_COMMAND, 0, 0 }; + u8 buffer[5] = { 0x04, PWM_CHANNEL0, PMBUS_VOUT_COMMAND, 0, 0 }; DEVICE_HANDLE_T dev; /* Open device handle */ @@ -475,24 +479,32 @@ static int set_voltage_to_pmbus(int i2caddress, int vdd) if (ret) return ret; - /* Scale up to the proper value for the VOUT command, little endian */ - multiplier = get_pmbus_multiplier(dev); + /* + * Encode target mV as LINEAR16 raw via the tree level helper + * from <pmbus.h>. For non Linear VOUT_MODE settings the helper + * returns 0; fall back to the historic mV pass through. A failed + * VOUT_MODE read aborts: never write a voltage code whose + * encoding could not be determined. + */ vdd += board_vdd_drop_compensation(); - if (multiplier != MV_PER_V) - vdd = DIV_ROUND_UP(vdd * multiplier, MV_PER_V); - buffer[3] = vdd & 0xFF; - buffer[4] = (vdd & 0xFF00) >> 8; + ret = vid_read_vout_mode(dev, &vout_mode); + if (ret) + return ret; + if ((vout_mode & PB_VOUT_MODE_MODE_MASK) == PB_VOUT_MODE_LINEAR) + raw = pmbus_data2reg_linear16((s64)vdd * 1000LL, vout_mode); + else + raw = (u16)vdd; + buffer[3] = raw & 0xFF; + buffer[4] = (raw & 0xFF00) >> 8; /* Check write protect state */ - ret = I2C_READ(dev, PMBUS_CMD_WRITE_PROTECT, (void *)&value, - sizeof(value)); + ret = pmbus_read_byte(dev, PMBUS_WRITE_PROTECT, &value); if (ret) goto exit; if (value != EN_WRITE_ALL_CMD) { value = EN_WRITE_ALL_CMD; - ret = I2C_WRITE(dev, PMBUS_CMD_WRITE_PROTECT, - (void *)&value, sizeof(value)); + ret = pmbus_write_byte(dev, PMBUS_WRITE_PROTECT, value); if (ret) goto exit; } diff --git a/board/nxp/common/vid.h b/board/nxp/common/vid.h index b34c080b4ba..72c1c089aa1 100644 --- a/board/nxp/common/vid.h +++ b/board/nxp/common/vid.h @@ -22,8 +22,9 @@ #define IR_VDD_STEP_UP 5 /* LTC3882 */ -#define PMBUS_CMD_WRITE_PROTECT 0x10 /* + * PMBUS_WRITE_PROTECT (10h) provided by <pmbus.h> + * * WRITE_PROTECT command supported values * 0x80: Disable all writes except WRITE_PROTECT, PAGE, * STORE_USER_ALL and MFR_EE_UNLOCK commands. @@ -51,12 +52,14 @@ #define VDD_MV_MAX 925 #endif -/* PM Bus commands code for LTC3882*/ +/* + * PM Bus commands code for LTC3882. PMBUS_PAGE / PMBUS_READ_VOUT / + * PMBUS_VOUT_MODE / PMBUS_VOUT_COMMAND are provided by <pmbus.h>. + * PMBUS_CMD_PAGE_PLUS_WRITE (05h) is the LTC3882 SMBus block write + * transaction not in <pmbus.h>'s standard subset, so keep its + * definition here. + */ #define PWM_CHANNEL0 0x0 -#define PMBUS_CMD_PAGE 0x0 -#define PMBUS_CMD_READ_VOUT 0x8B -#define PMBUS_CMD_VOUT_MODE 0x20 -#define PMBUS_CMD_VOUT_COMMAND 0x21 #define PMBUS_CMD_PAGE_PLUS_WRITE 0x05 #if defined(CONFIG_TARGET_LX2160AQDS) || defined(CONFIG_TARGET_LX2162AQDS) || \ |
