Merge git://git.denx.de/u-boot-fsl-qoriq
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user