board: common: vid: Add support for LTC3882 voltage regulator chip
authorRajesh Bhagat <rajesh.bhagat@nxp.com>
Wed, 17 Jan 2018 10:43:05 +0000 (16:13 +0530)
committerYork Sun <york.sun@nxp.com>
Tue, 23 Jan 2018 19:19:56 +0000 (11:19 -0800)
Restructures common driver to support LTC3882 voltage regulator
chip.

Signed-off-by: Ashish Kumar <Ashish.Kumar@nxp.com>
Signed-off-by: Rajesh Bhagat <rajesh.bhagat@nxp.com>
Reviewed-by: York Sun <york.sun@nxp.com>
arch/arm/include/asm/arch-fsl-layerscape/immap_lsch3.h
board/freescale/common/vid.c
include/configs/ls1088aqds.h
include/configs/ls1088ardb.h

index 47e8b5a62e50ec9bfde8ef3b1373433c523f470f..642df2f50a921eeaba52ad8126eb5bdf0392a7c1 100644 (file)
@@ -201,10 +201,15 @@ struct ccsr_gur {
        u32     gpporcr3;
        u32     gpporcr4;
        u8      res_030[0x60-0x30];
-#define FSL_CHASSIS3_DCFG_FUSESR_VID_SHIFT     2
 #define FSL_CHASSIS3_DCFG_FUSESR_VID_MASK      0x1F
-#define FSL_CHASSIS3_DCFG_FUSESR_ALTVID_SHIFT  7
 #define FSL_CHASSIS3_DCFG_FUSESR_ALTVID_MASK   0x1F
+#if defined(CONFIG_ARCH_LS1088A)
+#define FSL_CHASSIS3_DCFG_FUSESR_VID_SHIFT     25
+#define FSL_CHASSIS3_DCFG_FUSESR_ALTVID_SHIFT  20
+#else
+#define FSL_CHASSIS3_DCFG_FUSESR_VID_SHIFT     2
+#define FSL_CHASSIS3_DCFG_FUSESR_ALTVID_SHIFT  7
+#endif
        u32     dcfg_fusesr;    /* Fuse status register */
        u8      res_064[0x70-0x64];
        u32     devdisr;        /* Device disable control 1 */
index f68068eaf896b601bc71e942c141fab95ec16a81..a9451c5c6ee5de5383c530a7f78038324f4ff86c 100644 (file)
@@ -174,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;
@@ -181,6 +211,8 @@ 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
@@ -281,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)
@@ -289,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
@@ -472,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
@@ -489,6 +565,7 @@ 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;
index 8fbf89001efdb2e640b926f156a825351950740b..ff2f916e56d0c19e147a0bb52dba830a4ec6750a 100644 (file)
@@ -279,6 +279,22 @@ unsigned long get_board_ddr_clk(void);
 #define I2C_MUX_CH_DEFAULT             0x8
 #define I2C_MUX_CH5                    0xD
 
+#define I2C_MUX_CH_VOL_MONITOR          0xA
+
+/* Voltage monitor on channel 2*/
+#define I2C_VOL_MONITOR_ADDR           0x63
+#define I2C_VOL_MONITOR_BUS_V_OFFSET   0x2
+#define I2C_VOL_MONITOR_BUS_V_OVF      0x1
+#define I2C_VOL_MONITOR_BUS_V_SHIFT    3
+
+/* PM Bus commands code for LTC3882*/
+#define PMBUS_CMD_PAGE                  0x0
+#define PMBUS_CMD_READ_VOUT             0x8B
+#define PMBUS_CMD_PAGE_PLUS_WRITE       0x05
+#define PMBUS_CMD_VOUT_COMMAND          0x21
+
+#define PWM_CHANNEL0                    0x0
+
 /*
 * RTC configuration
 */
index d0066e3551fdbb4ae837bb33d2a4eb4b5657295c..4c290c5cbe323fee78d20f1e85781c7839bc0d98 100644 (file)
 
 #define CONFIG_SYS_LS_MC_BOOT_TIMEOUT_MS 5000
 
+#define I2C_MUX_CH_VOL_MONITOR          0xA
+/* Voltage monitor on channel 2*/
+#define I2C_VOL_MONITOR_ADDR           0x63
+#define I2C_VOL_MONITOR_BUS_V_OFFSET   0x2
+#define I2C_VOL_MONITOR_BUS_V_OVF      0x1
+#define I2C_VOL_MONITOR_BUS_V_SHIFT    3
+
+/* PM Bus commands code for LTC3882*/
+#define PMBUS_CMD_PAGE                  0x0
+#define PMBUS_CMD_READ_VOUT             0x8B
+#define PMBUS_CMD_PAGE_PLUS_WRITE       0x05
+#define PMBUS_CMD_VOUT_COMMAND          0x21
+
+#define PWM_CHANNEL0                    0x0
+
 /*
  * I2C bus multiplexer
  */