summaryrefslogtreecommitdiff
path: root/board
diff options
context:
space:
mode:
Diffstat (limited to 'board')
-rw-r--r--board/freescale/common/Kconfig16
-rw-r--r--board/freescale/common/Makefile2
-rw-r--r--board/freescale/common/qixis.c22
-rw-r--r--board/freescale/common/vid.c147
-rw-r--r--board/freescale/ls1088a/ddr.c21
-rw-r--r--board/freescale/ls1088a/ls1088a.c131
-rw-r--r--board/logicpd/omap3som/omap3logic.c15
7 files changed, 337 insertions, 17 deletions
diff --git a/board/freescale/common/Kconfig b/board/freescale/common/Kconfig
index 280f7d46b8..8b89c10aba 100644
--- a/board/freescale/common/Kconfig
+++ b/board/freescale/common/Kconfig
@@ -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.
diff --git a/board/freescale/common/Makefile b/board/freescale/common/Makefile
index e13cb2063c..939e9c66a5 100644
--- a/board/freescale/common/Makefile
+++ b/board/freescale/common/Makefile
@@ -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
diff --git a/board/freescale/common/qixis.c b/board/freescale/common/qixis.c
index 24459f8635..844c00a9e3 100644
--- a/board/freescale/common/qixis.c
+++ b/board/freescale/common/qixis.c
@@ -235,6 +235,28 @@ static int qixis_reset_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const ar
#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
QIXIS_WRITE(rst_ctl, 0x30);
diff --git a/board/freescale/common/vid.c b/board/freescale/common/vid.c
index d6d1bfc861..a9451c5c6e 100644
--- a/board/freescale/common/vid.c
+++ b/board/freescale/common/vid.c
@@ -34,6 +34,16 @@ int __weak board_vdd_drop_compensation(void)
}
/*
+ * 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
*
* There are some variance in the RDB HW regarding the I2C address configuration
@@ -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.
diff --git a/board/freescale/ls1088a/ddr.c b/board/freescale/ls1088a/ddr.c
index e24bfd557c..2240454ec8 100644
--- a/board/freescale/ls1088a/ddr.c
+++ b/board/freescale/ls1088a/ddr.c
@@ -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;
}
diff --git a/board/freescale/ls1088a/ls1088a.c b/board/freescale/ls1088a/ls1088a.c
index d12bcaed8f..0769e9069b 100644
--- a/board/freescale/ls1088a/ls1088a.c
+++ b/board/freescale/ls1088a/ls1088a.c
@@ -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();
diff --git a/board/logicpd/omap3som/omap3logic.c b/board/logicpd/omap3som/omap3logic.c
index b30fa24a32..4cbbf96faa 100644
--- a/board/logicpd/omap3som/omap3logic.c
+++ b/board/logicpd/omap3som/omap3logic.c
@@ -40,21 +40,6 @@
DECLARE_GLOBAL_DATA_PTR;
-/* This is only needed until SPL gets OF support */
-#ifdef CONFIG_SPL_BUILD
-static const struct ns16550_platdata omap3logic_serial = {
- .base = OMAP34XX_UART1,
- .reg_shift = 2,
- .clock = V_NS16550_CLK,
- .fcr = UART_FCR_DEFVAL,
-};
-
-U_BOOT_DEVICE(omap3logic_uart) = {
- "ns16550_serial",
- &omap3logic_serial
-};
-#endif
-
/*
* two dimensional array of strucures containining board name and Linux
* machine IDs; row it selected based on CPU column is slected based