Merge git://git.denx.de/u-boot-fsl-qoriq

This commit is contained in:
Tom Rini
2018-01-23 21:48:53 -05:00
44 changed files with 835 additions and 47 deletions

View File

@@ -20,3 +20,19 @@ config CMD_ESBC_VALIDATE
esbc_validate - validate signature using RSA verification
esbc_halt - put the core in spin loop (Secure Boot Only)
config VOL_MONITOR_LTC3882_READ
depends on VID
bool "Enable the LTC3882 voltage monitor read"
default n
help
This option enables LTC3882 voltage monitor read
functionality. It is used by common VID driver.
config VOL_MONITOR_LTC3882_SET
depends on VID
bool "Enable the LTC3882 voltage monitor set"
default n
help
This option enables LTC3882 voltage monitor set
functionality. It is used by common VID driver.

View File

@@ -23,8 +23,8 @@ obj-$(CONFIG_FMAN_ENET) += fman.o
obj-$(CONFIG_FSL_PIXIS) += pixis.o
ifndef CONFIG_SPL_BUILD
obj-$(CONFIG_FSL_NGPIXIS) += ngpixis.o
obj-$(CONFIG_VID) += vid.o
endif
obj-$(CONFIG_VID) += vid.o
obj-$(CONFIG_FSL_QIXIS) += qixis.o
obj-$(CONFIG_PQ_MDS_PIB) += pq-mds-pib.o
ifndef CONFIG_SPL_BUILD

View File

@@ -234,6 +234,28 @@ static int qixis_reset_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const ar
QIXIS_WRITE(rcfg_ctl, 0x21);
#else
printf("Not implemented\n");
#endif
} else if (strcmp(argv[1], "ifc") == 0) {
#ifdef QIXIS_LBMAP_IFC
QIXIS_WRITE(rst_ctl, 0x30);
QIXIS_WRITE(rcfg_ctl, 0);
set_lbmap(QIXIS_LBMAP_IFC);
set_rcw_src(QIXIS_RCW_SRC_IFC);
QIXIS_WRITE(rcfg_ctl, 0x20);
QIXIS_WRITE(rcfg_ctl, 0x21);
#else
printf("Not implemented\n");
#endif
} else if (strcmp(argv[1], "emmc") == 0) {
#ifdef QIXIS_LBMAP_EMMC
QIXIS_WRITE(rst_ctl, 0x30);
QIXIS_WRITE(rcfg_ctl, 0);
set_lbmap(QIXIS_LBMAP_EMMC);
set_rcw_src(QIXIS_RCW_SRC_EMMC);
QIXIS_WRITE(rcfg_ctl, 0x20);
QIXIS_WRITE(rcfg_ctl, 0x21);
#else
printf("Not implemented\n");
#endif
} else if (strcmp(argv[1], "sd_qspi") == 0) {
#ifdef QIXIS_LBMAP_SD_QSPI

View File

@@ -33,6 +33,16 @@ int __weak board_vdd_drop_compensation(void)
return 0;
}
/*
* Board specific settings for specific voltage value
*/
int __weak board_adjust_vdd(int vdd)
{
return 0;
}
#if defined(CONFIG_VOL_MONITOR_IR36021_SET) || \
defined(CONFIG_VOL_MONITOR_IR36021_READ)
/*
* Get the i2c address configuration for the IR regulator chip
*
@@ -65,6 +75,7 @@ static int find_ir_chip_on_i2c(void)
}
return -1;
}
#endif
/* Maximum loop count waiting for new voltage to take effect */
#define MAX_LOOP_WAIT_NEW_VOL 100
@@ -163,6 +174,36 @@ static int read_voltage_from_IR(int i2caddress)
}
#endif
#ifdef CONFIG_VOL_MONITOR_LTC3882_READ
/* read the current value of the LTC Regulator Voltage */
static int read_voltage_from_LTC(int i2caddress)
{
int ret, vcode = 0;
u8 chan = PWM_CHANNEL0;
/* select the PAGE 0 using PMBus commands PAGE for VDD*/
ret = i2c_write(I2C_VOL_MONITOR_ADDR,
PMBUS_CMD_PAGE, 1, &chan, 1);
if (ret) {
printf("VID: failed to select VDD Page 0\n");
return ret;
}
/*read the output voltage using PMBus command READ_VOUT*/
ret = i2c_read(I2C_VOL_MONITOR_ADDR,
PMBUS_CMD_READ_VOUT, 1, (void *)&vcode, 2);
if (ret) {
printf("VID: failed to read the volatge\n");
return ret;
}
/* Scale down to the real mV as LTC resolution is 1/4096V,rounding up */
vcode = DIV_ROUND_UP(vcode * 1000, 4096);
return vcode;
}
#endif
static int read_voltage(int i2caddress)
{
int voltage_read;
@@ -170,12 +211,15 @@ static int read_voltage(int i2caddress)
voltage_read = read_voltage_from_INA220(i2caddress);
#elif defined CONFIG_VOL_MONITOR_IR36021_READ
voltage_read = read_voltage_from_IR(i2caddress);
#elif defined CONFIG_VOL_MONITOR_LTC3882_READ
voltage_read = read_voltage_from_LTC(i2caddress);
#else
return -1;
#endif
return voltage_read;
}
#ifdef CONFIG_VOL_MONITOR_IR36021_SET
/*
* We need to calculate how long before the voltage stops to drop
* or increase. It returns with the loop count. Each loop takes
@@ -235,7 +279,6 @@ static int wait_for_voltage_stable(int i2caddress)
return vdd_current;
}
#ifdef CONFIG_VOL_MONITOR_IR36021_SET
/* Set the voltage to the IR chip */
static int set_voltage_to_IR(int i2caddress, int vdd)
{
@@ -270,6 +313,43 @@ static int set_voltage_to_IR(int i2caddress, int vdd)
debug("VID: Current voltage is %d mV\n", vdd_last);
return vdd_last;
}
#endif
#ifdef CONFIG_VOL_MONITOR_LTC3882_SET
/* this function sets the VDD and returns the value set */
static int set_voltage_to_LTC(int i2caddress, int vdd)
{
int ret, vdd_last, vdd_target = vdd;
/* Scale up to the LTC resolution is 1/4096V */
vdd = (vdd * 4096) / 1000;
/* 5-byte buffer which needs to be sent following the
* PMBus command PAGE_PLUS_WRITE.
*/
u8 buff[5] = {0x04, PWM_CHANNEL0, PMBUS_CMD_VOUT_COMMAND,
vdd & 0xFF, (vdd & 0xFF00) >> 8};
/* Write the desired voltage code to the regulator */
ret = i2c_write(I2C_VOL_MONITOR_ADDR,
PMBUS_CMD_PAGE_PLUS_WRITE, 1, (void *)&buff, 5);
if (ret) {
printf("VID: I2C failed to write to the volatge regulator\n");
return -1;
}
/* Wait for the volatge to get to the desired value */
do {
vdd_last = read_voltage_from_LTC(i2caddress);
if (vdd_last < 0) {
printf("VID: Couldn't read sensor abort VID adjust\n");
return -1;
}
} while (vdd_last != vdd_target);
return vdd_last;
}
#endif
static int set_voltage(int i2caddress, int vdd)
@@ -278,6 +358,8 @@ static int set_voltage(int i2caddress, int vdd)
#ifdef CONFIG_VOL_MONITOR_IR36021_SET
vdd_last = set_voltage_to_IR(i2caddress, vdd);
#elif defined CONFIG_VOL_MONITOR_LTC3882_SET
vdd_last = set_voltage_to_LTC(i2caddress, vdd);
#else
#error Specific voltage monitor must be defined
#endif
@@ -290,11 +372,53 @@ int adjust_vdd(ulong vdd_override)
int re_enable = disable_interrupts();
struct ccsr_gur *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
u32 fusesr;
#if defined(CONFIG_VOL_MONITOR_IR36021_SET) || \
defined(CONFIG_VOL_MONITOR_IR36021_READ)
u8 vid, buf;
#else
u8 vid;
#endif
int vdd_target, vdd_current, vdd_last;
int ret, i2caddress;
unsigned long vdd_string_override;
char *vdd_string;
#ifdef CONFIG_ARCH_LS1088A
static const uint16_t vdd[32] = {
10250,
9875,
9750,
0, /* reserved */
0, /* reserved */
0, /* reserved */
0, /* reserved */
0, /* reserved */
9000,
0, /* reserved */
0, /* reserved */
0, /* reserved */
0, /* reserved */
0, /* reserved */
0, /* reserved */
0, /* reserved */
10000, /* 1.0000V */
10125,
10250,
0, /* reserved */
0, /* reserved */
0, /* reserved */
0, /* reserved */
0, /* reserved */
0, /* reserved */
0, /* reserved */
0, /* reserved */
0, /* reserved */
0, /* reserved */
0, /* reserved */
0, /* reserved */
0, /* reserved */
};
#else
static const uint16_t vdd[32] = {
10500,
0, /* reserved */
@@ -329,6 +453,7 @@ int adjust_vdd(ulong vdd_override)
0, /* reserved */
0, /* reserved */
};
#endif
struct vdd_drive {
u8 vid;
unsigned voltage;
@@ -340,6 +465,8 @@ int adjust_vdd(ulong vdd_override)
ret = -1;
goto exit;
}
#if defined(CONFIG_VOL_MONITOR_IR36021_SET) || \
defined(CONFIG_VOL_MONITOR_IR36021_READ)
ret = find_ir_chip_on_i2c();
if (ret < 0) {
printf("VID: Could not find voltage regulator on I2C.\n");
@@ -364,6 +491,7 @@ int adjust_vdd(ulong vdd_override)
ret = -1;
goto exit;
}
#endif
/* get the voltage ID from fuse status register */
fusesr = in_le32(&gur->dcfg_fusesr);
@@ -415,6 +543,11 @@ int adjust_vdd(ulong vdd_override)
}
vdd_current = vdd_last;
debug("VID: Core voltage is currently at %d mV\n", vdd_last);
#ifdef CONFIG_VOL_MONITOR_LTC3882_SET
/* Set the target voltage */
vdd_last = vdd_current = set_voltage(i2caddress, vdd_target);
#else
/*
* Adjust voltage to at or one step above target.
* As measurements are less precise than setting the values
@@ -432,6 +565,12 @@ int adjust_vdd(ulong vdd_override)
vdd_last = set_voltage(i2caddress, vdd_current);
}
#endif
if (board_adjust_vdd(vdd_target) < 0) {
ret = -1;
goto exit;
}
if (vdd_last > 0)
printf("VID: Core voltage after adjustment is at %d mV\n",
vdd_last);
@@ -498,6 +637,8 @@ int adjust_vdd(ulong vdd_override)
ret = -1;
goto exit;
}
#if defined(CONFIG_VOL_MONITOR_IR36021_SET) || \
defined(CONFIG_VOL_MONITOR_IR36021_READ)
ret = find_ir_chip_on_i2c();
if (ret < 0) {
printf("VID: Could not find voltage regulator on I2C.\n");
@@ -522,6 +663,7 @@ int adjust_vdd(ulong vdd_override)
ret = -1;
goto exit;
}
#endif
/* get the voltage ID from fuse status register */
fusesr = in_be32(&gur->dcfg_fusesr);
@@ -632,6 +774,8 @@ static int print_vdd(void)
debug("VID : I2c failed to switch channel\n");
return -1;
}
#if defined(CONFIG_VOL_MONITOR_IR36021_SET) || \
defined(CONFIG_VOL_MONITOR_IR36021_READ)
ret = find_ir_chip_on_i2c();
if (ret < 0) {
printf("VID: Could not find voltage regulator on I2C.\n");
@@ -640,6 +784,7 @@ static int print_vdd(void)
i2caddress = ret;
debug("VID: IR Chip found on I2C address 0x%02x\n", i2caddress);
}
#endif
/*
* Read voltage monitor to check real voltage.

View File

@@ -13,6 +13,23 @@
DECLARE_GLOBAL_DATA_PTR;
#if defined(CONFIG_VID) && (!defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD))
static void fsl_ddr_setup_0v9_volt(memctl_options_t *popts)
{
int vdd;
vdd = get_core_volt_from_fuse();
/* Nothing to do for silicons doesn't support VID */
if (vdd < 0)
return;
if (vdd == 900) {
popts->ddr_cdr1 |= DDR_CDR1_V0PT9_EN;
debug("VID: configure DDR to support 900 mV\n");
}
}
#endif
void fsl_ddr_board_options(memctl_options_t *popts,
dimm_params_t *pdimm,
unsigned int ctrl_num)
@@ -87,6 +104,10 @@ found:
popts->addr_hash = 1;
popts->ddr_cdr1 = DDR_CDR1_DHC_EN | DDR_CDR1_ODT(DDR_CDR_ODT_60ohm);
#if defined(CONFIG_VID) && (!defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD))
fsl_ddr_setup_0v9_volt(popts);
#endif
popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_60ohm) |
DDR_CDR2_VREF_TRAIN_EN | DDR_CDR2_VREF_RANGE_2;
}

View File

@@ -19,9 +19,13 @@
#include <asm/arch-fsl-layerscape/soc.h>
#include <asm/arch/ppa.h>
#include <hwconfig.h>
#include <asm/arch/fsl_serdes.h>
#include <asm/arch/soc.h>
#include "../common/qixis.h"
#include "ls1088a_qixis.h"
#include "../common/vid.h"
#include <fsl_immap.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -51,6 +55,16 @@ unsigned long long get_qixis_addr(void)
}
#endif
#if defined(CONFIG_VID)
int init_func_vid(void)
{
if (adjust_vdd(0) < 0)
printf("core voltage not adjusted\n");
return 0;
}
#endif
#if !defined(CONFIG_SPL_BUILD)
int checkboard(void)
{
@@ -207,6 +221,7 @@ unsigned long get_board_ddr_clk(void)
return 66666666;
}
#endif
int select_i2c_ch_pca9547(u8 ch)
{
@@ -221,6 +236,7 @@ int select_i2c_ch_pca9547(u8 ch)
return 0;
}
#if !defined(CONFIG_SPL_BUILD)
void board_retimer_init(void)
{
u8 reg;
@@ -322,7 +338,122 @@ int misc_init_r(void)
return 0;
}
#endif
#endif
int i2c_multiplexer_select_vid_channel(u8 channel)
{
return select_i2c_ch_pca9547(channel);
}
#ifdef CONFIG_TARGET_LS1088AQDS
/* read the current value(SVDD) of the LTM Regulator Voltage */
int get_serdes_volt(void)
{
int ret, vcode = 0;
u8 chan = PWM_CHANNEL0;
/* Select the PAGE 0 using PMBus commands PAGE for VDD */
ret = i2c_write(I2C_SVDD_MONITOR_ADDR,
PMBUS_CMD_PAGE, 1, &chan, 1);
if (ret) {
printf("VID: failed to select VDD Page 0\n");
return ret;
}
/* Read the output voltage using PMBus command READ_VOUT */
ret = i2c_read(I2C_SVDD_MONITOR_ADDR,
PMBUS_CMD_READ_VOUT, 1, (void *)&vcode, 2);
if (ret) {
printf("VID: failed to read the volatge\n");
return ret;
}
return vcode;
}
int set_serdes_volt(int svdd)
{
int ret, vdd_last;
u8 buff[5] = {0x04, PWM_CHANNEL0, PMBUS_CMD_VOUT_COMMAND,
svdd & 0xFF, (svdd & 0xFF00) >> 8};
/* Write the desired voltage code to the SVDD regulator */
ret = i2c_write(I2C_SVDD_MONITOR_ADDR,
PMBUS_CMD_PAGE_PLUS_WRITE, 1, (void *)&buff, 5);
if (ret) {
printf("VID: I2C failed to write to the volatge regulator\n");
return -1;
}
/* Wait for the volatge to get to the desired value */
do {
vdd_last = get_serdes_volt();
if (vdd_last < 0) {
printf("VID: Couldn't read sensor abort VID adjust\n");
return -1;
}
} while (vdd_last != svdd);
return 1;
}
#else
int get_serdes_volt(void)
{
return 0;
}
int set_serdes_volt(int svdd)
{
int ret;
u8 brdcfg4;
printf("SVDD changing of RDB\n");
/* Read the BRDCFG54 via CLPD */
ret = i2c_read(CONFIG_SYS_I2C_FPGA_ADDR,
QIXIS_BRDCFG4_OFFSET, 1, (void *)&brdcfg4, 1);
if (ret) {
printf("VID: I2C failed to read the CPLD BRDCFG4\n");
return -1;
}
brdcfg4 = brdcfg4 | 0x08;
/* Write to the BRDCFG4 */
ret = i2c_write(CONFIG_SYS_I2C_FPGA_ADDR,
QIXIS_BRDCFG4_OFFSET, 1, (void *)&brdcfg4, 1);
if (ret) {
debug("VID: I2C failed to set the SVDD CPLD BRDCFG4\n");
return -1;
}
/* Wait for the volatge to get to the desired value */
udelay(10000);
return 1;
}
#endif
/* this function disables the SERDES, changes the SVDD Voltage and enables it*/
int board_adjust_vdd(int vdd)
{
int ret = 0;
debug("%s: vdd = %d\n", __func__, vdd);
/* Special settings to be performed when voltage is 900mV */
if (vdd == 900) {
ret = setup_serdes_volt(vdd);
if (ret < 0) {
ret = -1;
goto exit;
}
}
exit:
return ret;
}
#if !defined(CONFIG_SPL_BUILD)
int board_init(void)
{
init_final_memctl_regs();