diff options
Diffstat (limited to 'board')
-rw-r--r-- | board/freescale/common/Kconfig | 16 | ||||
-rw-r--r-- | board/freescale/common/Makefile | 2 | ||||
-rw-r--r-- | board/freescale/common/qixis.c | 22 | ||||
-rw-r--r-- | board/freescale/common/vid.c | 147 | ||||
-rw-r--r-- | board/freescale/ls1088a/ddr.c | 21 | ||||
-rw-r--r-- | board/freescale/ls1088a/ls1088a.c | 131 | ||||
-rw-r--r-- | board/logicpd/omap3som/omap3logic.c | 15 |
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 |