]> git.ipfire.org Git - people/ms/u-boot.git/blobdiff - board/freescale/ls1088a/ls1088a.c
ls1088a: Add VID support for QDS and RDB platforms
[people/ms/u-boot.git] / board / freescale / ls1088a / ls1088a.c
index d12bcaed8f81f1b3350fada363a739b93927a50c..188f76dcd2f53232f0df81228867f5eebe6af17c 100644 (file)
 #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)
 {
@@ -323,6 +337,119 @@ int misc_init_r(void)
 }
 #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;
+}
+
 int board_init(void)
 {
        init_final_memctl_regs();