From 1c7d6584a7811b7785ae5c1e378f14b5ba0971cf Mon Sep 17 00:00:00 2001 From: takeshi_hoshina Date: Mon, 2 Nov 2020 11:07:33 +0900 Subject: basesystem-jj recipes --- ...a-cex7-move-from-lsdk-19.06-to-lsdk-19.09.patch | 923 +++++++++++++++++++++ 1 file changed, 923 insertions(+) create mode 100644 bsp/meta-freescale-3rdparty/recipes-bsp/u-boot/u-boot-qoriq-lx2160acex7/0013-lx2160a-cex7-move-from-lsdk-19.06-to-lsdk-19.09.patch (limited to 'bsp/meta-freescale-3rdparty/recipes-bsp/u-boot/u-boot-qoriq-lx2160acex7/0013-lx2160a-cex7-move-from-lsdk-19.06-to-lsdk-19.09.patch') diff --git a/bsp/meta-freescale-3rdparty/recipes-bsp/u-boot/u-boot-qoriq-lx2160acex7/0013-lx2160a-cex7-move-from-lsdk-19.06-to-lsdk-19.09.patch b/bsp/meta-freescale-3rdparty/recipes-bsp/u-boot/u-boot-qoriq-lx2160acex7/0013-lx2160a-cex7-move-from-lsdk-19.06-to-lsdk-19.09.patch new file mode 100644 index 00000000..0ccb2eb9 --- /dev/null +++ b/bsp/meta-freescale-3rdparty/recipes-bsp/u-boot/u-boot-qoriq-lx2160acex7/0013-lx2160a-cex7-move-from-lsdk-19.06-to-lsdk-19.09.patch @@ -0,0 +1,923 @@ +From 4672d506d0abfba7890b2719b7b53f3694b88d06 Mon Sep 17 00:00:00 2001 +From: Rabeeh Khoury +Date: Mon, 3 Feb 2020 14:26:55 +0200 +Subject: [PATCH 13/17] lx2160a-cex7 : move from lsdk-19.06 to lsdk-19.09 + +Following is a list of changes - +1. I2C moved to DM model +2. removed emc2301 support +3. synchronized vid.c with NXP's driver. But it is still not functional +in u-boot +4. Added eMMC to distroboot target list + +Upstream-Status: Inappropriate [Solid-Run BSP] + +Signed-off-by: Rabeeh Khoury +--- + arch/arm/dts/fsl-lx2160a-cex7.dts | 14 + + board/solidrun/common/Makefile | 1 - + board/solidrun/common/emc2301.c | 31 -- + board/solidrun/common/vid.c | 638 +++++++++++++++++++++++++++++- + board/solidrun/lx2160a/lx2160a.c | 8 + + configs/lx2160acex7_tfa_defconfig | 8 +- + 6 files changed, 665 insertions(+), 35 deletions(-) + delete mode 100644 board/solidrun/common/emc2301.c + +diff --git a/arch/arm/dts/fsl-lx2160a-cex7.dts b/arch/arm/dts/fsl-lx2160a-cex7.dts +index 4fbcaafb0e..4ca67df25a 100644 +--- a/arch/arm/dts/fsl-lx2160a-cex7.dts ++++ b/arch/arm/dts/fsl-lx2160a-cex7.dts +@@ -46,6 +46,20 @@ + status = "okay"; + }; + ++&i2c0 { ++ status = "okay"; ++ u-boot,dm-pre-reloc; ++}; ++ ++&i2c4 { ++ status = "okay"; ++ ++ rtc@51 { ++ compatible = "pcf2127-rtc"; ++ reg = <0x51>; ++ }; ++}; ++ + &sata0 { + status = "okay"; + }; +diff --git a/board/solidrun/common/Makefile b/board/solidrun/common/Makefile +index 454a18e2f9..c335c658d4 100644 +--- a/board/solidrun/common/Makefile ++++ b/board/solidrun/common/Makefile +@@ -16,7 +16,6 @@ ifdef MINIMAL + obj- := __dummy__.o + else + obj-$(CONFIG_VID) += vid.o +-obj-$(CONFIG_EMC2301) += emc2301.o + ifdef CONFIG_SECURE_BOOT + obj-$(CONFIG_CMD_ESBC_VALIDATE) += fsl_validate.o cmd_esbc_validate.o + endif +diff --git a/board/solidrun/common/emc2301.c b/board/solidrun/common/emc2301.c +deleted file mode 100644 +index a4780dbfcc..0000000000 +--- a/board/solidrun/common/emc2301.c ++++ /dev/null +@@ -1,31 +0,0 @@ +-// SPDX-License-Identifier: GPL-2.0+ +-/* +- * Copyright 2019 SolidRun ltd. Based on code from NXP LX2160A RDB +- * +- * SPDX-License-Identifier: GPL-2.0+ +- */ +- +-#include +-#include +-#include +-#include +- +-#include "emc2301.h" +- +-DECLARE_GLOBAL_DATA_PTR; +- +-void set_fan_speed(u8 data) +-{ +- if (i2c_write(I2C_EMC2301_ADDR, I2C_EMC2301_FAN, 1, &data, 1) != 0) { +- puts("Error: failed to change fan speed\n"); +- } +-} +- +-void emc2301_init(void) +-{ +- u8 data; +- +- data = I2C_EMC2301_CMD; +- if (i2c_write(I2C_EMC2301_ADDR, I2C_EMC2301_CONF, 1, &data, 1) != 0) +- puts("Error: failed to configure EMC2301\n"); +-} +diff --git a/board/solidrun/common/vid.c b/board/solidrun/common/vid.c +index cc81e80c37..c7a626fd4f 100644 +--- a/board/solidrun/common/vid.c ++++ b/board/solidrun/common/vid.c +@@ -1,8 +1,9 @@ + // SPDX-License-Identifier: GPL-2.0+ + /* + * Copyright 2014 Freescale Semiconductor, Inc. +- * Copyright 2018 NXP ++ * Copyright 2019 NXP + */ ++ + #include + #include + #include +@@ -38,6 +39,52 @@ 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 ++ * for the IR regulator chip, which is likely a problem of external resistor ++ * accuracy. So we just check each address in a hopefully non-intrusive mode ++ * and use the first one that seems to work ++ * ++ * The IR chip can show up under the following addresses: ++ * 0x08 (Verified on T1040RDB-PA,T4240RDB-PB,X-T4240RDB-16GPA) ++ * 0x09 (Verified on T1040RDB-PA) ++ * 0x38 (Verified on T2080QDS, T2081QDS, T4240RDB) ++ */ ++static int find_ir_chip_on_i2c(void) ++{ ++ int i2caddress; ++ int ret; ++ u8 byte; ++ int i; ++ const int ir_i2c_addr[] = {0x38, 0x08, 0x09}; ++#ifdef CONFIG_DM_I2C ++ struct udevice *dev; ++#endif ++ ++ /* Check all the address */ ++ for (i = 0; i < (sizeof(ir_i2c_addr)/sizeof(ir_i2c_addr[0])); i++) { ++ i2caddress = ir_i2c_addr[i]; ++#ifndef CONFIG_DM_I2C ++ ret = i2c_read(i2caddress, ++ IR36021_MFR_ID_OFFSET, 1, (void *)&byte, ++ sizeof(byte)); ++#else ++ ret = i2c_get_chip_for_busnum(0, i2caddress, 1, &dev); ++ if (!ret) ++ ret = dm_i2c_read(dev, IR36021_MFR_ID_OFFSET, ++ (void *)&byte, sizeof(byte)); ++#endif ++ if ((ret >= 0) && (byte == IR36021_MFR_ID)) ++ return i2caddress; ++ } ++ return -1; ++} ++#endif ++ + /* Maximum loop count waiting for new voltage to take effect */ + #define MAX_LOOP_WAIT_NEW_VOL 100 + /* Maximum loop count waiting for the voltage to be stable */ +@@ -60,23 +107,135 @@ int __weak board_adjust_vdd(int vdd) + #define ADC_MIN_ACCURACY 4 + #endif + ++#ifdef CONFIG_VOL_MONITOR_INA220 ++static int read_voltage_from_INA220(int i2caddress) ++{ ++ int i, ret, voltage_read = 0; ++ u16 vol_mon; ++ u8 buf[2]; ++#ifdef CONFIG_DM_I2C ++ struct udevice *dev; ++#endif ++ ++ for (i = 0; i < NUM_READINGS; i++) { ++#ifndef CONFIG_DM_I2C ++ ret = i2c_read(I2C_VOL_MONITOR_ADDR, ++ I2C_VOL_MONITOR_BUS_V_OFFSET, 1, ++ (void *)&buf, 2); ++#else ++ ret = i2c_get_chip_for_busnum(0, I2C_VOL_MONITOR_ADDR, 1, &dev); ++ if (!ret) ++ ret = dm_i2c_read(dev, I2C_VOL_MONITOR_BUS_V_OFFSET, ++ (void *)&buf, 2); ++#endif ++ if (ret) { ++ printf("VID: failed to read core voltage\n"); ++ return ret; ++ } ++ vol_mon = (buf[0] << 8) | buf[1]; ++ if (vol_mon & I2C_VOL_MONITOR_BUS_V_OVF) { ++ printf("VID: Core voltage sensor error\n"); ++ return -1; ++ } ++ debug("VID: bus voltage reads 0x%04x\n", vol_mon); ++ /* LSB = 4mv */ ++ voltage_read += (vol_mon >> I2C_VOL_MONITOR_BUS_V_SHIFT) * 4; ++ udelay(WAIT_FOR_ADC); ++ } ++ /* calculate the average */ ++ voltage_read /= NUM_READINGS; ++ ++ return voltage_read; ++} ++#endif ++ ++/* read voltage from IR */ ++#ifdef CONFIG_VOL_MONITOR_IR36021_READ ++static int read_voltage_from_IR(int i2caddress) ++{ ++ int i, ret, voltage_read = 0; ++ u16 vol_mon; ++ u8 buf; ++#ifdef CONFIG_DM_I2C ++ struct udevice *dev; ++#endif ++ ++ for (i = 0; i < NUM_READINGS; i++) { ++#ifndef CONFIG_DM_I2C ++ ret = i2c_read(i2caddress, ++ IR36021_LOOP1_VOUT_OFFSET, ++ 1, (void *)&buf, 1); ++#else ++ ret = i2c_get_chip_for_busnum(0, i2caddress, 1, &dev); ++ if (!ret) ++ ret = dm_i2c_read(dev, IR36021_LOOP1_VOUT_OFFSET, ++ (void *)&buf, 1); ++#endif ++ if (ret) { ++ printf("VID: failed to read vcpu\n"); ++ return ret; ++ } ++ vol_mon = buf; ++ if (!vol_mon) { ++ printf("VID: Core voltage sensor error\n"); ++ return -1; ++ } ++ debug("VID: bus voltage reads 0x%02x\n", vol_mon); ++ /* Resolution is 1/128V. We scale up here to get 1/128mV ++ * and divide at the end ++ */ ++ voltage_read += vol_mon * 1000; ++ udelay(WAIT_FOR_ADC); ++ } ++ /* Scale down to the real mV as IR resolution is 1/128V, rounding up */ ++ voltage_read = DIV_ROUND_UP(voltage_read, 128); ++ ++ /* calculate the average */ ++ voltage_read /= NUM_READINGS; ++ ++ /* Compensate for a board specific voltage drop between regulator and ++ * SoC before converting into an IR VID value ++ */ ++ voltage_read -= board_vdd_drop_compensation(); ++ ++ return voltage_read; ++} ++#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; + ++#ifndef CONFIG_DM_I2C + /* select the PAGE 0 using PMBus commands PAGE for VDD*/ + ret = i2c_write(I2C_VOL_MONITOR_ADDR, + PMBUS_CMD_PAGE, 1, &chan, 1); ++#else ++ struct udevice *dev; ++ ++ ret = i2c_get_chip_for_busnum(0, I2C_VOL_MONITOR_ADDR, 1, &dev); ++ if (!ret) ++ ret = dm_i2c_write(dev, PMBUS_CMD_PAGE, &chan, 1); ++#endif + if (ret) { + printf("VID: failed to select VDD Page 0\n"); + return ret; + } + ++#ifndef CONFIG_DM_I2C + /*read the output voltage using PMBus command READ_VOUT*/ + ret = i2c_read(I2C_VOL_MONITOR_ADDR, + PMBUS_CMD_READ_VOUT, 1, (void *)&vcode, 2); ++#else ++ ret = dm_i2c_read(dev, PMBUS_CMD_READ_VOUT, (void *)&vcode, 2); ++ if (ret) { ++ printf("VID: failed to read the volatge\n"); ++ return ret; ++ } ++#endif + if (ret) { + printf("VID: failed to read the volatge\n"); + return ret; +@@ -87,14 +246,131 @@ static int read_voltage_from_LTC(int i2caddress) + + return vcode; + } ++#endif + + static int read_voltage(int i2caddress) + { + int voltage_read; ++#ifdef CONFIG_VOL_MONITOR_INA220 ++ 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 ++ * several readings (WAIT_FOR_ADC) ++ */ ++static int wait_for_new_voltage(int vdd, int i2caddress) ++{ ++ int timeout, vdd_current; ++ ++ vdd_current = read_voltage(i2caddress); ++ /* wait until voltage starts to reach the target. Voltage slew ++ * rates by typical regulators will always lead to stable readings ++ * within each fairly long ADC interval in comparison to the ++ * intended voltage delta change until the target voltage is ++ * reached. The fairly small voltage delta change to any target ++ * VID voltage also means that this function will always complete ++ * within few iterations. If the timeout was ever reached, it would ++ * point to a serious failure in the regulator system. ++ */ ++ for (timeout = 0; ++ abs(vdd - vdd_current) > (IR_VDD_STEP_UP + IR_VDD_STEP_DOWN) && ++ timeout < MAX_LOOP_WAIT_NEW_VOL; timeout++) { ++ vdd_current = read_voltage(i2caddress); ++ } ++ if (timeout >= MAX_LOOP_WAIT_NEW_VOL) { ++ printf("VID: Voltage adjustment timeout\n"); ++ return -1; ++ } ++ return timeout; ++} ++ ++/* ++ * this function keeps reading the voltage until it is stable or until the ++ * timeout expires ++ */ ++static int wait_for_voltage_stable(int i2caddress) ++{ ++ int timeout, vdd_current, vdd; ++ ++ vdd = read_voltage(i2caddress); ++ udelay(NUM_READINGS * WAIT_FOR_ADC); ++ ++ /* wait until voltage is stable */ ++ vdd_current = read_voltage(i2caddress); ++ /* The maximum timeout is ++ * MAX_LOOP_WAIT_VOL_STABLE * NUM_READINGS * WAIT_FOR_ADC ++ */ ++ for (timeout = MAX_LOOP_WAIT_VOL_STABLE; ++ abs(vdd - vdd_current) > ADC_MIN_ACCURACY && ++ timeout > 0; timeout--) { ++ vdd = vdd_current; ++ udelay(NUM_READINGS * WAIT_FOR_ADC); ++ vdd_current = read_voltage(i2caddress); ++ } ++ if (timeout == 0) ++ return -1; ++ return vdd_current; ++} ++ ++/* Set the voltage to the IR chip */ ++static int set_voltage_to_IR(int i2caddress, int vdd) ++{ ++ int wait, vdd_last; ++ int ret; ++ u8 vid; ++ ++ /* Compensate for a board specific voltage drop between regulator and ++ * SoC before converting into an IR VID value ++ */ ++ vdd += board_vdd_drop_compensation(); ++#ifdef CONFIG_FSL_LSCH2 ++ vid = DIV_ROUND_UP(vdd - 265, 5); ++#else ++ vid = DIV_ROUND_UP(vdd - 245, 5); ++#endif ++ ++#ifndef CONFIG_DM_I2C ++ ret = i2c_write(i2caddress, IR36021_LOOP1_MANUAL_ID_OFFSET, ++ 1, (void *)&vid, sizeof(vid)); ++#else ++ struct udevice *dev; ++ ++ ret = i2c_get_chip_for_busnum(0, i2caddress, 1, &dev); ++ if (!ret) ++ ret = dm_i2c_write(dev, IR36021_LOOP1_MANUAL_ID_OFFSET, ++ (void *)&vid, sizeof(vid)); ++ ++#endif ++ if (ret) { ++ printf("VID: failed to write VID\n"); ++ return -1; ++ } ++ wait = wait_for_new_voltage(vdd, i2caddress); ++ if (wait < 0) ++ return -1; ++ debug("VID: Waited %d us\n", wait * NUM_READINGS * WAIT_FOR_ADC); ++ ++ vdd_last = wait_for_voltage_stable(i2caddress); ++ if (vdd_last < 0) ++ return -1; ++ 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) + { +@@ -111,8 +387,17 @@ static int set_voltage_to_LTC(int i2caddress, int vdd) + vdd & 0xFF, (vdd & 0xFF00) >> 8}; + + /* Write the desired voltage code to the regulator */ ++#ifndef CONFIG_DM_I2C + ret = i2c_write(I2C_VOL_MONITOR_ADDR, + PMBUS_CMD_PAGE_PLUS_WRITE, 1, (void *)&buff, 5); ++#else ++ struct udevice *dev; ++ ++ ret = i2c_get_chip_for_busnum(0, I2C_VOL_MONITOR_ADDR, 1, &dev); ++ if (!ret) ++ ret = dm_i2c_write(dev, PMBUS_CMD_PAGE_PLUS_WRITE, ++ (void *)&buff, 5); ++#endif + if (ret) { + printf("VID: I2C failed to write to the volatge regulator\n"); + return -1; +@@ -131,25 +416,39 @@ static int set_voltage_to_LTC(int i2caddress, int vdd) + + return vdd_last; + } ++#endif + + static int set_voltage(int i2caddress, int vdd) + { + int vdd_last = -1; + ++#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 + return vdd_last; + } + ++#ifdef CONFIG_FSL_LSCH3 + 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_LX2160A + static const u16 vdd[32] = { + 8250, + 7875, +@@ -184,16 +483,129 @@ int adjust_vdd(ulong vdd_override) + 0, /* reserved */ + 0, /* reserved */ + }; ++#else ++#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 */ ++ 9750, ++ 0, /* reserved */ ++ 9500, ++ 0, /* reserved */ ++ 0, /* reserved */ ++ 0, /* reserved */ ++ 0, /* reserved */ ++ 0, /* reserved */ ++ 0, /* reserved */ ++ 9000, /* reserved */ ++ 0, /* reserved */ ++ 0, /* reserved */ ++ 0, /* reserved */ ++ 0, /* reserved */ ++ 10000, /* 1.0000V */ ++ 0, /* reserved */ ++ 10250, ++ 0, /* reserved */ ++ 10500, ++ 0, /* reserved */ ++ 0, /* reserved */ ++ 0, /* reserved */ ++ 0, /* reserved */ ++ 0, /* reserved */ ++ 0, /* reserved */ ++ 0, /* reserved */ ++ 0, /* reserved */ ++ 0, /* reserved */ ++ 0, /* reserved */ ++ 0, /* reserved */ ++ }; ++#endif ++#endif + struct vdd_drive { + u8 vid; + unsigned voltage; + }; ++ + ret = i2c_multiplexer_select_vid_channel(I2C_MUX_CH_VOL_MONITOR); + if (ret) { + debug("VID: I2C failed to switch channel\n"); + 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"); ++ ret = -1; ++ goto exit; ++ } else { ++ i2caddress = ret; ++ debug("VID: IR Chip found on I2C address 0x%02x\n", i2caddress); ++ } ++ ++ /* check IR chip work on Intel mode*/ ++#ifndef CONFIG_DM_I2C ++ ret = i2c_read(i2caddress, ++ IR36021_INTEL_MODE_OOFSET, ++ 1, (void *)&buf, 1); ++#else ++ struct udevice *dev; ++ ++ ret = i2c_get_chip_for_busnum(0, i2caddress, 1, &dev); ++ if (!ret) ++ ret = dm_i2c_read(dev, IR36021_INTEL_MODE_OOFSET, ++ (void *)&buf, 1); ++#endif ++ if (ret) { ++ printf("VID: failed to read IR chip mode.\n"); ++ ret = -1; ++ goto exit; ++ } ++ ++ if ((buf & IR36021_MODE_MASK) != IR36021_INTEL_MODE) { ++ printf("VID: IR Chip is not used in Intel mode.\n"); ++ ret = -1; ++ goto exit; ++ } ++#endif ++ + /* get the voltage ID from fuse status register */ + fusesr = in_le32(&gur->dcfg_fusesr); + vid = (fusesr >> FSL_CHASSIS3_DCFG_FUSESR_ALTVID_SHIFT) & +@@ -203,7 +615,6 @@ int adjust_vdd(ulong vdd_override) + FSL_CHASSIS3_DCFG_FUSESR_VID_MASK; + } + vdd_target = vdd[vid]; +- printf ("vid FUSE index %d (vdd_target = %d)\n",vid,vdd_target); + + /* check override variable for overriding VDD */ + vdd_string = env_get(CONFIG_VID_FLS_ENV); +@@ -246,8 +657,28 @@ 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 ++ * we may run through dummy steps that cancel each other ++ * when stepping up and then down. ++ */ ++ while (vdd_last > 0 && ++ vdd_last < vdd_target) { ++ vdd_current += IR_VDD_STEP_UP; ++ vdd_last = set_voltage(i2caddress, vdd_current); ++ } ++ while (vdd_last > 0 && ++ vdd_last > vdd_target + (IR_VDD_STEP_DOWN - 1)) { ++ vdd_current -= IR_VDD_STEP_DOWN; ++ vdd_last = set_voltage(i2caddress, vdd_current); ++ } ++ ++#endif + if (board_adjust_vdd(vdd_target) < 0) { + ret = -1; + goto exit; +@@ -264,6 +695,197 @@ exit: + i2c_multiplexer_select_vid_channel(I2C_MUX_CH_DEFAULT); + return ret; + } ++#else /* !CONFIG_FSL_LSCH3 */ ++int adjust_vdd(ulong vdd_override) ++{ ++ int re_enable = disable_interrupts(); ++#if defined(CONFIG_FSL_LSCH2) ++ struct ccsr_gur *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); ++#else ++ ccsr_gur_t __iomem *gur = ++ (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); ++#endif ++ u32 fusesr; ++ u8 vid, buf; ++ int vdd_target, vdd_current, vdd_last; ++ int ret, i2caddress; ++ unsigned long vdd_string_override; ++ char *vdd_string; ++ static const uint16_t vdd[32] = { ++ 0, /* unused */ ++ 9875, /* 0.9875V */ ++ 9750, ++ 9625, ++ 9500, ++ 9375, ++ 9250, ++ 9125, ++ 9000, ++ 8875, ++ 8750, ++ 8625, ++ 8500, ++ 8375, ++ 8250, ++ 8125, ++ 10000, /* 1.0000V */ ++ 10125, ++ 10250, ++ 10375, ++ 10500, ++ 10625, ++ 10750, ++ 10875, ++ 11000, ++ 0, /* reserved */ ++ }; ++ struct vdd_drive { ++ u8 vid; ++ unsigned voltage; ++ }; ++ ++ ret = i2c_multiplexer_select_vid_channel(I2C_MUX_CH_VOL_MONITOR); ++ if (ret) { ++ debug("VID: I2C failed to switch channel\n"); ++ 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"); ++ ret = -1; ++ goto exit; ++ } else { ++ i2caddress = ret; ++ debug("VID: IR Chip found on I2C address 0x%02x\n", i2caddress); ++ } ++ ++ /* check IR chip work on Intel mode*/ ++#ifndef CONFIG_DM_I2C ++ ret = i2c_read(i2caddress, ++ IR36021_INTEL_MODE_OOFSET, ++ 1, (void *)&buf, 1); ++#else ++ struct udevice *dev; ++ ++ ret = i2c_get_chip_for_busnum(0, i2caddress, 1, &dev); ++ if (!ret) ++ ret = dm_i2c_read(dev, IR36021_INTEL_MODE_OOFSET, ++ (void *)&buf, 1); ++#endif ++ if (ret) { ++ printf("VID: failed to read IR chip mode.\n"); ++ ret = -1; ++ goto exit; ++ } ++ if ((buf & IR36021_MODE_MASK) != IR36021_INTEL_MODE) { ++ printf("VID: IR Chip is not used in Intel mode.\n"); ++ ret = -1; ++ goto exit; ++ } ++#endif ++ ++ /* get the voltage ID from fuse status register */ ++ fusesr = in_be32(&gur->dcfg_fusesr); ++ /* ++ * VID is used according to the table below ++ * --------------------------------------- ++ * | DA_V | ++ * |-------------------------------------| ++ * | 5b00000 | 5b00001-5b11110 | 5b11111 | ++ * ---------------+---------+-----------------+---------| ++ * | D | 5b00000 | NO VID | VID = DA_V | NO VID | ++ * | A |----------+---------+-----------------+---------| ++ * | _ | 5b00001 |VID = | VID = |VID = | ++ * | V | ~ | DA_V_ALT| DA_V_ALT | DA_A_VLT| ++ * | _ | 5b11110 | | | | ++ * | A |----------+---------+-----------------+---------| ++ * | L | 5b11111 | No VID | VID = DA_V | NO VID | ++ * | T | | | | | ++ * ------------------------------------------------------ ++ */ ++#ifdef CONFIG_FSL_LSCH2 ++ vid = (fusesr >> FSL_CHASSIS2_DCFG_FUSESR_ALTVID_SHIFT) & ++ FSL_CHASSIS2_DCFG_FUSESR_ALTVID_MASK; ++ if ((vid == 0) || (vid == FSL_CHASSIS2_DCFG_FUSESR_ALTVID_MASK)) { ++ vid = (fusesr >> FSL_CHASSIS2_DCFG_FUSESR_VID_SHIFT) & ++ FSL_CHASSIS2_DCFG_FUSESR_VID_MASK; ++ } ++#else ++ vid = (fusesr >> FSL_CORENET_DCFG_FUSESR_ALTVID_SHIFT) & ++ FSL_CORENET_DCFG_FUSESR_ALTVID_MASK; ++ if ((vid == 0) || (vid == FSL_CORENET_DCFG_FUSESR_ALTVID_MASK)) { ++ vid = (fusesr >> FSL_CORENET_DCFG_FUSESR_VID_SHIFT) & ++ FSL_CORENET_DCFG_FUSESR_VID_MASK; ++ } ++#endif ++ vdd_target = vdd[vid]; ++ ++ /* check override variable for overriding VDD */ ++ vdd_string = env_get(CONFIG_VID_FLS_ENV); ++ if (vdd_override == 0 && vdd_string && ++ !strict_strtoul(vdd_string, 10, &vdd_string_override)) ++ vdd_override = vdd_string_override; ++ if (vdd_override >= VDD_MV_MIN && vdd_override <= VDD_MV_MAX) { ++ vdd_target = vdd_override * 10; /* convert to 1/10 mV */ ++ debug("VDD override is %lu\n", vdd_override); ++ } else if (vdd_override != 0) { ++ printf("Invalid value.\n"); ++ } ++ if (vdd_target == 0) { ++ debug("VID: VID not used\n"); ++ ret = 0; ++ goto exit; ++ } else { ++ /* divide and round up by 10 to get a value in mV */ ++ vdd_target = DIV_ROUND_UP(vdd_target, 10); ++ debug("VID: vid = %d mV\n", vdd_target); ++ } ++ ++ /* ++ * Read voltage monitor to check real voltage. ++ */ ++ vdd_last = read_voltage(i2caddress); ++ if (vdd_last < 0) { ++ printf("VID: Couldn't read sensor abort VID adjustment\n"); ++ ret = -1; ++ goto exit; ++ } ++ vdd_current = vdd_last; ++ debug("VID: Core voltage is currently at %d mV\n", vdd_last); ++ /* ++ * Adjust voltage to at or one step above target. ++ * As measurements are less precise than setting the values ++ * we may run through dummy steps that cancel each other ++ * when stepping up and then down. ++ */ ++ while (vdd_last > 0 && ++ vdd_last < vdd_target) { ++ vdd_current += IR_VDD_STEP_UP; ++ vdd_last = set_voltage(i2caddress, vdd_current); ++ } ++ while (vdd_last > 0 && ++ vdd_last > vdd_target + (IR_VDD_STEP_DOWN - 1)) { ++ vdd_current -= IR_VDD_STEP_DOWN; ++ vdd_last = set_voltage(i2caddress, vdd_current); ++ } ++ ++ if (vdd_last > 0) ++ printf("VID: Core voltage after adjustment is at %d mV\n", ++ vdd_last); ++ else ++ ret = -1; ++exit: ++ if (re_enable) ++ enable_interrupts(); ++ ++ i2c_multiplexer_select_vid_channel(I2C_MUX_CH_DEFAULT); ++ ++ return ret; ++} ++#endif + + static int print_vdd(void) + { +@@ -274,6 +896,18 @@ 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"); ++ goto exit; ++ } else { ++ 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/solidrun/lx2160a/lx2160a.c b/board/solidrun/lx2160a/lx2160a.c +index b0d9f1012e..3713e91351 100644 +--- a/board/solidrun/lx2160a/lx2160a.c ++++ b/board/solidrun/lx2160a/lx2160a.c +@@ -62,7 +62,15 @@ int select_i2c_ch_pca9547(u8 ch) + { + int ret; + ++#ifndef CONFIG_DM_I2C + ret = i2c_write(I2C_MUX_PCA_ADDR_PRI, 0, 1, &ch, 1); ++#else ++ struct udevice *dev; ++ ++ ret = i2c_get_chip_for_busnum(0, I2C_MUX_PCA_ADDR_PRI, 1, &dev); ++ if (!ret) ++ ret = dm_i2c_write(dev, 0, &ch, 1); ++#endif + if (ret) { + puts("PCA: failed to select proper channel\n"); + return ret; +diff --git a/configs/lx2160acex7_tfa_defconfig b/configs/lx2160acex7_tfa_defconfig +index 3891d2a7c4..89a47adb23 100644 +--- a/configs/lx2160acex7_tfa_defconfig ++++ b/configs/lx2160acex7_tfa_defconfig +@@ -2,7 +2,6 @@ CONFIG_ARM=y + CONFIG_TARGET_LX2160ACEX7=y + CONFIG_SYS_TEXT_BASE=0x82000000 + CONFIG_SYS_MALLOC_F_LEN=0x6000 +-CONFIG_EMC2301=y + CONFIG_TFABOOT=y + CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT=y + CONFIG_SEC_FIRMWARE_ARMV8_PSCI=y +@@ -73,3 +72,10 @@ CONFIG_DM_USB=y + CONFIG_USB_XHCI_HCD=y + CONFIG_USB_XHCI_DWC3=y + CONFIG_EFI_LOADER_BOUNCE_BUFFER=y ++CONFIG_DM_I2C=y ++CONFIG_I2C_SET_DEFAULT_BUS_NUM=y ++CONFIG_I2C_DEFAULT_BUS_NUMBER=0 ++CONFIG_DM_RTC=y ++CONFIG_DM_GPIO=y ++CONFIG_CMD_DATE=y ++CONFIG_RTC_PCF2127=y +-- +2.17.1 + -- cgit 1.2.3-korg