From b5ee48c099e4036fc0336cf66a0d324b8225d53e Mon Sep 17 00:00:00 2001 From: Stephen Carlson Date: Mon, 8 Feb 2021 11:11:29 +0100 Subject: [PATCH 01/59] arm: fsl: common: Improve NXP VID driver PMBus support This patch adds support for more PMBus compatible devices to the NXP drivers for its QorIQ family devices. At runtime, the voltage regulator is queried over I2C, and the required voltage multiplier determined. This change supports the DIRECT and LINEAR PMBus voltage reporting modes. Previously, the driver only supported a few specific devices such as the IR36021 and LTC3882, so this change allows the QorIQ series to be used with a much larger variety of core voltage regulator devices. checkpatch warning "Use if (IS_DEFINED (...))" was ignored to maintain consistency with the existing code. Signed-off-by: Stephen Carlson Signed-off-by: Wasim Khan Tested-by: Wasim Khan [Rebased] Signed-off-by: Priyanka Jain --- board/freescale/common/Kconfig | 27 +- board/freescale/common/vid.c | 842 ++++++++++-------------- board/freescale/common/vid.h | 11 +- board/freescale/ls1088a/ls1088a.c | 40 ++ board/freescale/ls2080ardb/ls2080ardb.c | 42 ++ board/freescale/lx2160a/lx2160a.c | 42 ++ include/configs/ls1088aqds.h | 6 - include/configs/ls1088ardb.h | 8 +- 8 files changed, 488 insertions(+), 530 deletions(-) diff --git a/board/freescale/common/Kconfig b/board/freescale/common/Kconfig index 1b1fd69cb2..17db755951 100644 --- a/board/freescale/common/Kconfig +++ b/board/freescale/common/Kconfig @@ -21,18 +21,37 @@ config CMD_ESBC_VALIDATE esbc_validate - validate signature using RSA verification esbc_halt - put the core in spin loop (Secure Boot Only) +config VID + depends on DM_I2C + bool "Enable Freescale VID" + help + This option enables setting core voltage based on individual + values saved in SoC fuses. + 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. + functionality. It is used by the 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. + functionality. It is used by the common VID driver. + +config VOL_MONITOR_ISL68233_READ + depends on VID + bool "Enable the ISL68233 voltage monitor read" + help + This option enables ISL68233 voltage monitor read + functionality. It is used by the common VID driver. + +config VOL_MONITOR_ISL68233_SET + depends on VID + bool "Enable the ISL68233 voltage monitor set" + help + This option enables ISL68233 voltage monitor set + functionality. It is used by the common VID driver. diff --git a/board/freescale/common/vid.c b/board/freescale/common/vid.c index 20f5421da0..6e8296293b 100644 --- a/board/freescale/common/vid.c +++ b/board/freescale/common/vid.c @@ -2,6 +2,7 @@ /* * Copyright 2014 Freescale Semiconductor, Inc. * Copyright 2020 NXP + * Copyright 2020 Stephen Carlson */ #include @@ -21,14 +22,22 @@ #include #include "vid.h" +/* Voltages are generally handled in mV to keep them as integers */ +#define MV_PER_V 1000 + +/* + * Select the channel on the I2C mux (on some NXP boards) that contains + * the voltage regulator to use for VID. Return 0 for success or nonzero + * for failure. + */ int __weak i2c_multiplexer_select_vid_channel(u8 channel) { return 0; } /* - * Compensate for a board specific voltage drop between regulator and SoC - * return a value in mV + * Compensate for a board specific voltage drop between regulator and SoC. + * Returns the voltage offset in mV. */ int __weak board_vdd_drop_compensation(void) { @@ -36,13 +45,94 @@ int __weak board_vdd_drop_compensation(void) } /* - * Board specific settings for specific voltage value + * Performs any board specific adjustments after the VID voltage has been + * set. Return 0 for success or nonzero for failure. */ int __weak board_adjust_vdd(int vdd) { return 0; } +/* + * Processor specific method of converting the fuse value read from VID + * registers into the core voltage to supply. Return the voltage in mV. + */ +u16 __weak soc_get_fuse_vid(int vid_index) +{ + /* Default VDD for Layerscape Chassis 1 devices */ + static const u16 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 */ + }; + return vdd[vid_index]; +} + +#ifndef I2C_VOL_MONITOR_ADDR +#define I2C_VOL_MONITOR_ADDR 0 +#endif + +#if CONFIG_IS_ENABLED(DM_I2C) +#define DEVICE_HANDLE_T struct udevice * + +#ifndef I2C_VOL_MONITOR_BUS +#define I2C_VOL_MONITOR_BUS 0 +#endif + +/* If DM is in use, retrieve the udevice chip for the specified bus number */ +static int vid_get_device(int address, DEVICE_HANDLE_T *dev) +{ + int ret = i2c_get_chip_for_busnum(I2C_VOL_MONITOR_BUS, address, 1, dev); + + if (ret) + printf("VID: Bus %d has no device with address 0x%02X\n", + I2C_VOL_MONITOR_BUS, address); + return ret; +} + +#define I2C_READ(dev, register, data, length) \ + dm_i2c_read(dev, register, data, length) +#define I2C_WRITE(dev, register, data, length) \ + dm_i2c_write(dev, register, data, length) +#else +#define DEVICE_HANDLE_T int + +/* If DM is not in use, I2C addresses are passed directly */ +static int vid_get_device(int address, DEVICE_HANDLE_T *dev) +{ + *dev = address; + return 0; +} + +#define I2C_READ(dev, register, data, length) \ + i2c_read(dev, register, 1, data, length) +#define I2C_WRITE(dev, register, data, length) \ + i2c_write(dev, register, 1, data, length) +#endif + #if defined(CONFIG_VOL_MONITOR_IR36021_SET) || \ defined(CONFIG_VOL_MONITOR_IR36021_READ) /* @@ -60,30 +150,22 @@ int __weak board_adjust_vdd(int vdd) */ static int find_ir_chip_on_i2c(void) { - int i2caddress; - int ret; - u8 byte; - int i; + int i2caddress, ret, i; + u8 mfrID; const int ir_i2c_addr[] = {0x38, 0x08, 0x09}; -#if CONFIG_IS_ENABLED(DM_I2C) - struct udevice *dev; -#endif + DEVICE_HANDLE_T dev; /* Check all the address */ for (i = 0; i < (sizeof(ir_i2c_addr)/sizeof(ir_i2c_addr[0])); i++) { i2caddress = ir_i2c_addr[i]; -#if !CONFIG_IS_ENABLED(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; + ret = vid_get_device(i2caddress, &dev); + if (!ret) { + ret = I2C_READ(dev, IR36021_MFR_ID_OFFSET, + (void *)&mfrID, sizeof(mfrID)); + /* If manufacturer ID matches the IR36021 */ + if (!ret && mfrID == IR36021_MFR_ID) + return i2caddress; + } } return -1; } @@ -117,35 +199,33 @@ static int read_voltage_from_INA220(int i2caddress) int i, ret, voltage_read = 0; u16 vol_mon; u8 buf[2]; -#if CONFIG_IS_ENABLED(DM_I2C) - struct udevice *dev; -#endif + DEVICE_HANDLE_T dev; + + /* Open device handle */ + ret = vid_get_device(i2caddress, &dev); + if (ret) + return ret; for (i = 0; i < NUM_READINGS; i++) { -#if !CONFIG_IS_ENABLED(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 + ret = I2C_READ(dev, I2C_VOL_MONITOR_BUS_V_OFFSET, + (void *)&buf[0], sizeof(buf)); 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; @@ -153,30 +233,25 @@ static int read_voltage_from_INA220(int i2caddress) } #endif -/* read voltage from IR */ #ifdef CONFIG_VOL_MONITOR_IR36021_READ +/* read voltage from IR */ static int read_voltage_from_IR(int i2caddress) { int i, ret, voltage_read = 0; u16 vol_mon; u8 buf; -#if CONFIG_IS_ENABLED(DM_I2C) - struct udevice *dev; -#endif + DEVICE_HANDLE_T dev; + + /* Open device handle */ + ret = vid_get_device(i2caddress, &dev); + if (ret) + return ret; for (i = 0; i < NUM_READINGS; i++) { -#if !CONFIG_IS_ENABLED(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 + ret = I2C_READ(dev, IR36021_LOOP1_VOUT_OFFSET, (void *)&buf, + sizeof(buf)); if (ret) { - printf("VID: failed to read vcpu\n"); + printf("VID: failed to read core voltage\n"); return ret; } vol_mon = buf; @@ -188,7 +263,7 @@ static int read_voltage_from_IR(int i2caddress) /* Resolution is 1/128V. We scale up here to get 1/128mV * and divide at the end */ - voltage_read += vol_mon * 1000; + voltage_read += vol_mon * MV_PER_V; udelay(WAIT_FOR_ADC); } /* Scale down to the real mV as IR resolution is 1/128V, rounding up */ @@ -206,49 +281,94 @@ 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) +#if defined(CONFIG_VOL_MONITOR_ISL68233_READ) || \ + defined(CONFIG_VOL_MONITOR_LTC3882_READ) || \ + defined(CONFIG_VOL_MONITOR_ISL68233_SET) || \ + defined(CONFIG_VOL_MONITOR_LTC3882_SET) + +/* + * The message displayed if the VOUT exponent causes a resolution + * worse than 1.0 V (if exponent is >= 0). + */ +#define VOUT_WARNING "VID: VOUT_MODE exponent has resolution worse than 1 V!\n" + +/* Checks the PMBus voltage monitor for the format used for voltage values */ +static int get_pmbus_multiplier(DEVICE_HANDLE_T dev) { - int ret, vcode = 0; - u8 chan = PWM_CHANNEL0; + u8 mode; + int exponent, multiplier, ret; -#if !CONFIG_IS_ENABLED(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_READ(dev, PMBUS_CMD_VOUT_MODE, &mode, sizeof(mode)); + if (ret) { + printf("VID: unable to determine voltage multiplier\n"); + return 1; + } - 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); + /* Upper 3 bits is mode, lower 5 bits is exponent */ + exponent = (int)mode & 0x1F; + mode >>= 5; + switch (mode) { + case 0: + /* Linear, 5 bit twos component exponent */ + if (exponent & 0x10) { + multiplier = 1 << (16 - (exponent & 0xF)); + } else { + /* If exponent is >= 0, then resolution is 1 V! */ + printf(VOUT_WARNING); + multiplier = 1; + } + break; + case 1: + /* VID code identifier */ + printf("VID: custom VID codes are not supported\n"); + multiplier = MV_PER_V; + break; + default: + /* Direct, in mV */ + multiplier = MV_PER_V; + break; + } + + debug("VID: calculated multiplier is %d\n", multiplier); + return multiplier; +} #endif + +#if defined(CONFIG_VOL_MONITOR_ISL68233_READ) || \ + defined(CONFIG_VOL_MONITOR_LTC3882_READ) +static int read_voltage_from_pmbus(int i2caddress) +{ + int ret, multiplier, vout; + u8 channel = PWM_CHANNEL0; + u16 vcode; + DEVICE_HANDLE_T dev; + + /* Open device handle */ + ret = vid_get_device(i2caddress, &dev); + if (ret) + return ret; + + /* Select the right page */ + ret = I2C_WRITE(dev, PMBUS_CMD_PAGE, &channel, sizeof(channel)); if (ret) { - printf("VID: failed to select VDD Page 0\n"); + printf("VID: failed to select VDD page %d\n", channel); return ret; } -#if !CONFIG_IS_ENABLED(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); + /* VOUT is little endian */ + ret = I2C_READ(dev, PMBUS_CMD_READ_VOUT, (void *)&vcode, sizeof(vcode)); if (ret) { - printf("VID: failed to read the volatge\n"); - return ret; - } -#endif - if (ret) { - printf("VID: failed to read the volatge\n"); + printf("VID: failed to read core voltage\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; + /* Scale down to the real mV */ + multiplier = get_pmbus_multiplier(dev); + vout = (int)vcode; + /* Multiplier 1000 (direct mode) requires no change to convert */ + if (multiplier != MV_PER_V) + vout = DIV_ROUND_UP(vout * MV_PER_V, multiplier); + return vout - board_vdd_drop_compensation(); } #endif @@ -256,13 +376,14 @@ static int read_voltage(int i2caddress) { int voltage_read; #ifdef CONFIG_VOL_MONITOR_INA220 - voltage_read = read_voltage_from_INA220(i2caddress); + voltage_read = read_voltage_from_INA220(I2C_VOL_MONITOR_ADDR); #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); +#elif defined(CONFIG_VOL_MONITOR_ISL68233_READ) || \ + defined(CONFIG_VOL_MONITOR_LTC3882_READ) + voltage_read = read_voltage_from_pmbus(i2caddress); #else - return -1; + voltage_read = -1; #endif return voltage_read; } @@ -300,7 +421,7 @@ static int wait_for_new_voltage(int vdd, int i2caddress) } /* - * this function keeps reading the voltage until it is stable or until the + * Blocks and reads the VID voltage until it stabilizes, or the * timeout expires */ static int wait_for_voltage_stable(int i2caddress) @@ -310,9 +431,9 @@ static int wait_for_voltage_stable(int i2caddress) vdd = read_voltage(i2caddress); udelay(NUM_READINGS * WAIT_FOR_ADC); - /* wait until voltage is stable */ vdd_current = read_voltage(i2caddress); - /* The maximum timeout is + /* + * The maximum timeout is * MAX_LOOP_WAIT_VOL_STABLE * NUM_READINGS * WAIT_FOR_ADC */ for (timeout = MAX_LOOP_WAIT_VOL_STABLE; @@ -327,12 +448,18 @@ static int wait_for_voltage_stable(int i2caddress) return vdd_current; } -/* Set the voltage to the IR chip */ +/* Sets the VID voltage using the IR36021 */ static int set_voltage_to_IR(int i2caddress, int vdd) { int wait, vdd_last; int ret; u8 vid; + DEVICE_HANDLE_T dev; + + /* Open device handle */ + ret = vid_get_device(i2caddress, &dev); + if (ret) + return ret; /* Compensate for a board specific voltage drop between regulator and * SoC before converting into an IR VID value @@ -344,20 +471,10 @@ static int set_voltage_to_IR(int i2caddress, int vdd) vid = DIV_ROUND_UP(vdd - 245, 5); #endif -#if !CONFIG_IS_ENABLED(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 + ret = I2C_WRITE(dev, IR36021_LOOP1_MANUAL_ID_OFFSET, (void *)&vid, + sizeof(vid)); if (ret) { - printf("VID: failed to write VID\n"); + printf("VID: failed to write new voltage\n"); return -1; } wait = wait_for_new_voltage(vdd, i2caddress); @@ -371,81 +488,59 @@ 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) +#if defined(CONFIG_VOL_MONITOR_ISL68233_SET) || \ + defined(CONFIG_VOL_MONITOR_LTC3882_SET) +static int set_voltage_to_pmbus(int i2caddress, int vdd) { int ret, vdd_last, vdd_target = vdd; - int count = 100, temp = 0; + int count = MAX_LOOP_WAIT_NEW_VOL, temp = 0, multiplier; unsigned char value; - /* Scale up to the LTC resolution is 1/4096V */ - vdd = (vdd * 4096) / 1000; + /* The data to be sent with the PMBus command PAGE_PLUS_WRITE */ + u8 buffer[5] = { 0x04, PWM_CHANNEL0, PMBUS_CMD_VOUT_COMMAND, 0, 0 }; + DEVICE_HANDLE_T dev; - /* 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}; + /* Open device handle */ + ret = vid_get_device(i2caddress, &dev); + if (ret) + return ret; + + /* Scale up to the proper value for the VOUT command, little endian */ + multiplier = get_pmbus_multiplier(dev); + vdd += board_vdd_drop_compensation(); + if (multiplier != MV_PER_V) + vdd = DIV_ROUND_UP(vdd * multiplier, MV_PER_V); + buffer[3] = vdd & 0xFF; + buffer[4] = (vdd & 0xFF00) >> 8; - /* Write the desired voltage code to the regulator */ -#if !CONFIG_IS_ENABLED(DM_I2C) /* Check write protect state */ - ret = i2c_read(I2C_VOL_MONITOR_ADDR, - PMBUS_CMD_WRITE_PROTECT, 1, - (void *)&value, sizeof(value)); + ret = I2C_READ(dev, PMBUS_CMD_WRITE_PROTECT, (void *)&value, + sizeof(value)); if (ret) goto exit; if (value != EN_WRITE_ALL_CMD) { value = EN_WRITE_ALL_CMD; - ret = i2c_write(I2C_VOL_MONITOR_ADDR, - PMBUS_CMD_WRITE_PROTECT, 1, + ret = I2C_WRITE(dev, PMBUS_CMD_WRITE_PROTECT, (void *)&value, sizeof(value)); if (ret) goto exit; } - ret = i2c_write(I2C_VOL_MONITOR_ADDR, - PMBUS_CMD_PAGE_PLUS_WRITE, 1, - (void *)&buff, sizeof(buff)); -#else - struct udevice *dev; - - ret = i2c_get_chip_for_busnum(0, I2C_VOL_MONITOR_ADDR, 1, &dev); - if (!ret) { - /* Check write protect state */ - ret = dm_i2c_read(dev, - PMBUS_CMD_WRITE_PROTECT, - (void *)&value, sizeof(value)); - if (ret) - goto exit; - - if (value != EN_WRITE_ALL_CMD) { - value = EN_WRITE_ALL_CMD; - ret = dm_i2c_write(dev, - PMBUS_CMD_WRITE_PROTECT, - (void *)&value, sizeof(value)); - if (ret) - goto exit; - } - - ret = dm_i2c_write(dev, PMBUS_CMD_PAGE_PLUS_WRITE, - (void *)&buff, sizeof(buff)); - } -#endif -exit: + /* Write the desired voltage code to the regulator */ + ret = I2C_WRITE(dev, PMBUS_CMD_PAGE_PLUS_WRITE, (void *)&buffer[0], + sizeof(buffer)); if (ret) { - printf("VID: I2C failed to write to the volatge regulator\n"); + printf("VID: I2C failed to write to the voltage regulator\n"); return -1; } - /* Wait for the volatge to get to the desired value */ +exit: + /* Wait for the voltage to get to the desired value */ do { - vdd_last = read_voltage_from_LTC(i2caddress); + vdd_last = read_voltage_from_pmbus(i2caddress); if (vdd_last < 0) { printf("VID: Couldn't read sensor abort VID adjust\n"); return -1; @@ -464,371 +559,37 @@ 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); +#elif defined(CONFIG_VOL_MONITOR_ISL68233_SET) || \ + defined(CONFIG_VOL_MONITOR_LTC3882_SET) + vdd_last = set_voltage_to_pmbus(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 = 0; - unsigned long vdd_string_override; - char *vdd_string; -#if defined(CONFIG_ARCH_LX2160A) || defined(CONFIG_ARCH_LX2162A) - static const u16 vdd[32] = { - 8250, - 7875, - 7750, - 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 */ - 8000, - 8125, - 8250, - 0, /* reserved */ - 8500, - 0, /* reserved */ - 0, /* reserved */ - 0, /* reserved */ - 0, /* reserved */ - 0, /* reserved */ - 0, /* reserved */ - 0, /* reserved */ - 0, /* reserved */ - 0, /* reserved */ - 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 */ - 9000, /* reserved */ - 0, /* reserved */ - 0, /* reserved */ - 0, /* 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*/ -#if !CONFIG_IS_ENABLED(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) & - FSL_CHASSIS3_DCFG_FUSESR_ALTVID_MASK; - if ((vid == 0) || (vid == FSL_CHASSIS3_DCFG_FUSESR_ALTVID_MASK)) { - vid = (fusesr >> FSL_CHASSIS3_DCFG_FUSESR_VID_SHIFT) & - FSL_CHASSIS3_DCFG_FUSESR_VID_MASK; - } - 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"); - } - - /* divide and round up by 10 to get a value in mV */ - vdd_target = DIV_ROUND_UP(vdd_target, 10); - if (vdd_target == 0) { - debug("VID: VID not used\n"); - ret = 0; - goto exit; - } else if (vdd_target < VDD_MV_MIN || vdd_target > VDD_MV_MAX) { - /* Check vdd_target is in valid range */ - printf("VID: Target VID %d mV is not in range.\n", - vdd_target); - ret = -1; - goto exit; - } else { - 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); - -#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; - } - - 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; -} -#else /* !CONFIG_FSL_LSCH3 */ -int adjust_vdd(ulong vdd_override) -{ - int re_enable = disable_interrupts(); -#if defined(CONFIG_FSL_LSCH2) +#if defined(CONFIG_FSL_LSCH2) || defined(CONFIG_FSL_LSCH3) struct ccsr_gur *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); #else ccsr_gur_t __iomem *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); #endif + u8 vid; u32 fusesr; - u8 vid, buf; - int vdd_target, vdd_current, vdd_last; - int ret, i2caddress; + int vdd_current, vdd_last, vdd_target; + int ret, i2caddress = I2C_VOL_MONITOR_ADDR; 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*/ -#if !CONFIG_IS_ENABLED(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; - } + u8 buf; + DEVICE_HANDLE_T dev; #endif - /* get the voltage ID from fuse status register */ - fusesr = in_be32(&gur->dcfg_fusesr); /* * VID is used according to the table below * --------------------------------------- @@ -846,33 +607,83 @@ int adjust_vdd(ulong vdd_override) * | T | | | | | * ------------------------------------------------------ */ -#ifdef CONFIG_FSL_LSCH2 +#if defined(CONFIG_FSL_LSCH3) + fusesr = in_le32(&gur->dcfg_fusesr); + vid = (fusesr >> FSL_CHASSIS3_DCFG_FUSESR_ALTVID_SHIFT) & + FSL_CHASSIS3_DCFG_FUSESR_ALTVID_MASK; + if (vid == 0 || vid == FSL_CHASSIS3_DCFG_FUSESR_ALTVID_MASK) { + vid = (fusesr >> FSL_CHASSIS3_DCFG_FUSESR_VID_SHIFT) & + FSL_CHASSIS3_DCFG_FUSESR_VID_MASK; + } +#elif defined(CONFIG_FSL_LSCH2) + fusesr = in_be32(&gur->dcfg_fusesr); vid = (fusesr >> FSL_CHASSIS2_DCFG_FUSESR_ALTVID_SHIFT) & - FSL_CHASSIS2_DCFG_FUSESR_ALTVID_MASK; - if ((vid == 0) || (vid == FSL_CHASSIS2_DCFG_FUSESR_ALTVID_MASK)) { + 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; + FSL_CHASSIS2_DCFG_FUSESR_VID_MASK; } #else + fusesr = in_be32(&gur->dcfg_fusesr); vid = (fusesr >> FSL_CORENET_DCFG_FUSESR_ALTVID_SHIFT) & - FSL_CORENET_DCFG_FUSESR_ALTVID_MASK; - if ((vid == 0) || (vid == FSL_CORENET_DCFG_FUSESR_ALTVID_MASK)) { + 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; + FSL_CORENET_DCFG_FUSESR_VID_MASK; + } +#endif + vdd_target = soc_get_fuse_vid((int)vid); + + 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); + } + + ret = vid_get_device(i2caddress, &dev); + if (ret) + return ret; + + /* check IR chip work on Intel mode */ + ret = I2C_READ(dev, IR36021_INTEL_MODE_OFFSET, (void *)&buf, + sizeof(buf)); + 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 - vdd_target = vdd[vid]; /* check override variable for overriding VDD */ vdd_string = env_get(CONFIG_VID_FLS_ENV); + debug("VID: Initial VDD value is %d mV\n", + DIV_ROUND_UP(vdd_target, 10)); 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); + debug("VID: VDD override is %lu\n", vdd_override); } else if (vdd_override != 0) { - printf("Invalid value.\n"); + printf("VID: Invalid VDD value.\n"); } if (vdd_target == 0) { debug("VID: VID not used\n"); @@ -895,6 +706,13 @@ int adjust_vdd(ulong vdd_override) } vdd_current = vdd_last; debug("VID: Core voltage is currently at %d mV\n", vdd_last); + +#if defined(CONFIG_VOL_MONITOR_LTC3882_SET) || \ + defined(CONFIG_VOL_MONITOR_ISL68233_SET) + /* Set the target voltage */ + vdd_current = set_voltage(i2caddress, vdd_target); + vdd_last = vdd_current; +#else /* * Adjust voltage to at or one step above target. * As measurements are less precise than setting the values @@ -911,6 +729,13 @@ int adjust_vdd(ulong vdd_override) vdd_current -= IR_VDD_STEP_DOWN; vdd_last = set_voltage(i2caddress, vdd_current); } +#endif + + /* Board specific adjustments */ + 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", @@ -925,11 +750,10 @@ exit: return ret; } -#endif static int print_vdd(void) { - int vdd_last, ret, i2caddress = 0; + int vdd_last, ret, i2caddress = I2C_VOL_MONITOR_ADDR; ret = i2c_multiplexer_select_vid_channel(I2C_MUX_CH_VOL_MONITOR); if (ret) { diff --git a/board/freescale/common/vid.h b/board/freescale/common/vid.h index 5bbaecace4..b34c080b4b 100644 --- a/board/freescale/common/vid.h +++ b/board/freescale/common/vid.h @@ -7,16 +7,17 @@ #ifndef __VID_H_ #define __VID_H_ +/* IR36021 command codes */ #define IR36021_LOOP1_MANUAL_ID_OFFSET 0x6A #define IR36021_LOOP1_VOUT_OFFSET 0x9A #define IR36021_MFR_ID_OFFSET 0x92 #define IR36021_MFR_ID 0x43 -#define IR36021_INTEL_MODE_OOFSET 0x14 +#define IR36021_INTEL_MODE_OFFSET 0x14 #define IR36021_MODE_MASK 0x20 #define IR36021_INTEL_MODE 0x00 #define IR36021_AMD_MODE 0x20 -/* step the IR regulator in 5mV increments */ +/* Step the IR regulator in 5mV increments */ #define IR_VDD_STEP_DOWN 5 #define IR_VDD_STEP_UP 5 @@ -50,15 +51,16 @@ #define VDD_MV_MAX 925 #endif -#if defined(CONFIG_TARGET_LX2160AQDS) || defined(CONFIG_TARGET_LX2162AQDS) || \ -defined(CONFIG_TARGET_LX2160ARDB) /* PM Bus commands code for LTC3882*/ #define PWM_CHANNEL0 0x0 #define PMBUS_CMD_PAGE 0x0 #define PMBUS_CMD_READ_VOUT 0x8B +#define PMBUS_CMD_VOUT_MODE 0x20 #define PMBUS_CMD_VOUT_COMMAND 0x21 #define PMBUS_CMD_PAGE_PLUS_WRITE 0x05 +#if defined(CONFIG_TARGET_LX2160AQDS) || defined(CONFIG_TARGET_LX2162AQDS) || \ +defined(CONFIG_TARGET_LX2160ARDB) /* Voltage monitor on channel 2*/ #define I2C_VOL_MONITOR_BUS_V_OFFSET 0x2 #define I2C_VOL_MONITOR_BUS_V_OVF 0x1 @@ -68,5 +70,6 @@ defined(CONFIG_TARGET_LX2160ARDB) #endif int adjust_vdd(ulong vdd_override); +u16 soc_get_fuse_vid(int vid_index); #endif /* __VID_H_ */ diff --git a/board/freescale/ls1088a/ls1088a.c b/board/freescale/ls1088a/ls1088a.c index e76ea01914..f5dc449d89 100644 --- a/board/freescale/ls1088a/ls1088a.c +++ b/board/freescale/ls1088a/ls1088a.c @@ -186,6 +186,46 @@ int init_func_vid(void) return 0; } + +u16 soc_get_fuse_vid(int vid_index) +{ + static const u16 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 */ + }; + + return vdd[vid_index]; +}; #endif int is_pb_board(void) diff --git a/board/freescale/ls2080ardb/ls2080ardb.c b/board/freescale/ls2080ardb/ls2080ardb.c index c5ae02bc93..3a026b0827 100644 --- a/board/freescale/ls2080ardb/ls2080ardb.c +++ b/board/freescale/ls2080ardb/ls2080ardb.c @@ -43,6 +43,48 @@ enum { MUX_TYPE_DSPI, }; +#ifdef CONFIG_VID +u16 soc_get_fuse_vid(int vid_index) +{ + static const u16 vdd[32] = { + 10500, + 0, /* reserved */ + 9750, + 0, /* reserved */ + 9500, + 0, /* reserved */ + 0, /* reserved */ + 0, /* reserved */ + 9000, /* reserved */ + 0, /* reserved */ + 0, /* reserved */ + 0, /* 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 */ + }; + + return vdd[vid_index]; +}; +#endif + unsigned long long get_qixis_addr(void) { unsigned long long addr; diff --git a/board/freescale/lx2160a/lx2160a.c b/board/freescale/lx2160a/lx2160a.c index b32e487e76..47a7024f33 100644 --- a/board/freescale/lx2160a/lx2160a.c +++ b/board/freescale/lx2160a/lx2160a.c @@ -649,6 +649,48 @@ int misc_init_r(void) } #endif +#ifdef CONFIG_VID +u16 soc_get_fuse_vid(int vid_index) +{ + static const u16 vdd[32] = { + 8250, + 7875, + 7750, + 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 */ + 8000, + 8125, + 8250, + 0, /* reserved */ + 8500, + 0, /* reserved */ + 0, /* reserved */ + 0, /* reserved */ + 0, /* reserved */ + 0, /* reserved */ + 0, /* reserved */ + 0, /* reserved */ + 0, /* reserved */ + 0, /* reserved */ + 0, /* reserved */ + 0, /* reserved */ + }; + + return vdd[vid_index]; +}; +#endif + #ifdef CONFIG_FSL_MC_ENET extern int fdt_fixup_board_phy(void *fdt); diff --git a/include/configs/ls1088aqds.h b/include/configs/ls1088aqds.h index 0dcf844303..4d04833c50 100644 --- a/include/configs/ls1088aqds.h +++ b/include/configs/ls1088aqds.h @@ -326,12 +326,6 @@ unsigned long get_board_ddr_clk(void); #define CONFIG_VOL_MONITOR_LTC3882_SET #define CONFIG_VOL_MONITOR_LTC3882_READ -/* 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 /* diff --git a/include/configs/ls1088ardb.h b/include/configs/ls1088ardb.h index f59a9f5574..6f36dd417a 100644 --- a/include/configs/ls1088ardb.h +++ b/include/configs/ls1088ardb.h @@ -203,7 +203,7 @@ #define CONFIG_SYS_LS_MC_BOOT_TIMEOUT_MS 5000 -#define I2C_MUX_CH_VOL_MONITOR 0xA +#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 @@ -221,12 +221,6 @@ #define CONFIG_VOL_MONITOR_LTC3882_SET #define CONFIG_VOL_MONITOR_LTC3882_READ -/* 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 /* From 504debcd8c1f4d86682ed8f3c7472284a2b6e822 Mon Sep 17 00:00:00 2001 From: Rajesh Bhagat Date: Thu, 11 Feb 2021 13:28:49 +0100 Subject: [PATCH 02/59] configs: fsl: move bootrom specific defines to Kconfig Moves below bootrom specific defines to Kconfig: CONFIG_SYS_FSL_BOOTROM_BASE CONFIG_SYS_FSL_BOOTROM_SIZE Signed-off-by: Rajesh Bhagat Reviewed-by: Priyanka Jain --- arch/arm/cpu/armv8/fsl-layerscape/Kconfig | 10 ++++++++++ arch/arm/include/asm/arch-fsl-layerscape/cpu.h | 2 -- scripts/config_whitelist.txt | 2 -- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/arch/arm/cpu/armv8/fsl-layerscape/Kconfig b/arch/arm/cpu/armv8/fsl-layerscape/Kconfig index 4d46587214..ae0b7b21e8 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/Kconfig +++ b/arch/arm/cpu/armv8/fsl-layerscape/Kconfig @@ -640,3 +640,13 @@ config HAS_FSL_XHCI_USB help For some SoC(such as LS1043A and LS1046A), USB and QE-HDLC multiplex use pins, select it when the pins are assigned to USB. + +config SYS_FSL_BOOTROM_BASE + hex + depends on FSL_LSCH2 + default 0 + +config SYS_FSL_BOOTROM_SIZE + hex + depends on FSL_LSCH2 + default 0x1000000 diff --git a/arch/arm/include/asm/arch-fsl-layerscape/cpu.h b/arch/arm/include/asm/arch-fsl-layerscape/cpu.h index 4335aa0ec2..c51b65ea36 100644 --- a/arch/arm/include/asm/arch-fsl-layerscape/cpu.h +++ b/arch/arm/include/asm/arch-fsl-layerscape/cpu.h @@ -69,8 +69,6 @@ #define CONFIG_SYS_FSL_DRAM_SIZE2 0x7F80000000 #endif #elif defined(CONFIG_FSL_LSCH2) -#define CONFIG_SYS_FSL_BOOTROM_BASE 0x0 -#define CONFIG_SYS_FSL_BOOTROM_SIZE 0x1000000 #define CONFIG_SYS_FSL_CCSR_BASE 0x1000000 #define CONFIG_SYS_FSL_CCSR_SIZE 0xf000000 #define CONFIG_SYS_FSL_DCSR_BASE 0x20000000 diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt index e98185c064..3ba2781e5a 100644 --- a/scripts/config_whitelist.txt +++ b/scripts/config_whitelist.txt @@ -2251,8 +2251,6 @@ CONFIG_SYS_FSL_AIOP1_SIZE CONFIG_SYS_FSL_B4860QDS_XFI_ERR CONFIG_SYS_FSL_BMAN_ADDR CONFIG_SYS_FSL_BMAN_OFFSET -CONFIG_SYS_FSL_BOOTROM_BASE -CONFIG_SYS_FSL_BOOTROM_SIZE CONFIG_SYS_FSL_CCSR_BASE CONFIG_SYS_FSL_CCSR_GUR_BE CONFIG_SYS_FSL_CCSR_GUR_LE From c8c0170f192e975c85aadb8ebcfb4d1ac3cfc5f2 Mon Sep 17 00:00:00 2001 From: Rajesh Bhagat Date: Mon, 15 Feb 2021 09:46:14 +0100 Subject: [PATCH 03/59] configs: fsl: move via specific defines to Kconfig Moves below via specific defines to Kconfig: CONFIG_FSL_VIA Signed-off-by: Rajesh Bhagat [Rebased] Signed-off-by: Priyanka Jain --- arch/powerpc/cpu/mpc85xx/Kconfig | 6 ++++++ include/configs/MPC8541CDS.h | 2 -- include/configs/MPC8548CDS.h | 2 -- include/configs/MPC8555CDS.h | 2 -- scripts/config_whitelist.txt | 1 - 5 files changed, 6 insertions(+), 7 deletions(-) diff --git a/arch/powerpc/cpu/mpc85xx/Kconfig b/arch/powerpc/cpu/mpc85xx/Kconfig index 6f90518927..1a4e0b93a6 100644 --- a/arch/powerpc/cpu/mpc85xx/Kconfig +++ b/arch/powerpc/cpu/mpc85xx/Kconfig @@ -51,14 +51,17 @@ config TARGET_P5040DS config TARGET_MPC8541CDS bool "Support MPC8541CDS" select ARCH_MPC8541 + select FSL_VIA config TARGET_MPC8548CDS bool "Support MPC8548CDS" select ARCH_MPC8548 + select FSL_VIA config TARGET_MPC8555CDS bool "Support MPC8555CDS" select ARCH_MPC8555 + select FSL_VIA config TARGET_MPC8568MDS bool "Support MPC8568MDS" @@ -1409,6 +1412,9 @@ config SYS_FSL_LBC_CLK_DIV Defines divider of platform clock(clock input to eLBC controller). +config FSL_VIA + bool + source "board/freescale/corenet_ds/Kconfig" source "board/freescale/mpc8541cds/Kconfig" source "board/freescale/mpc8548cds/Kconfig" diff --git a/include/configs/MPC8541CDS.h b/include/configs/MPC8541CDS.h index b1c8917f21..ea4da6a5fe 100644 --- a/include/configs/MPC8541CDS.h +++ b/include/configs/MPC8541CDS.h @@ -18,8 +18,6 @@ #define CONFIG_PCI_INDIRECT_BRIDGE #define CONFIG_SYS_PCI_64BIT 1 /* enable 64-bit PCI resources */ -#define CONFIG_FSL_VIA - #ifndef __ASSEMBLY__ extern unsigned long get_clock_freq(void); #endif diff --git a/include/configs/MPC8548CDS.h b/include/configs/MPC8548CDS.h index 0605f70ffc..9f83931bed 100644 --- a/include/configs/MPC8548CDS.h +++ b/include/configs/MPC8548CDS.h @@ -23,8 +23,6 @@ #define CONFIG_INTERRUPTS /* enable pci, srio, ddr interrupts */ -#define CONFIG_FSL_VIA - #ifndef __ASSEMBLY__ #include extern unsigned long get_clock_freq(void); diff --git a/include/configs/MPC8555CDS.h b/include/configs/MPC8555CDS.h index 88999ef2b8..79e309c95c 100644 --- a/include/configs/MPC8555CDS.h +++ b/include/configs/MPC8555CDS.h @@ -18,8 +18,6 @@ #define CONFIG_PCI_INDIRECT_BRIDGE #define CONFIG_SYS_PCI_64BIT 1 /* enable 64-bit PCI resources */ -#define CONFIG_FSL_VIA - #ifndef __ASSEMBLY__ extern unsigned long get_clock_freq(void); #endif diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt index 3ba2781e5a..e793cd1169 100644 --- a/scripts/config_whitelist.txt +++ b/scripts/config_whitelist.txt @@ -551,7 +551,6 @@ CONFIG_FSL_SERDES2 CONFIG_FSL_SGMII_RISER CONFIG_FSL_TBCLK_EXTRA_DIV CONFIG_FSL_TRUST_ARCH_v1 -CONFIG_FSL_VIA CONFIG_FSMC_NAND_BASE CONFIG_FSMTDBLK CONFIG_FSNOTIFY From ebc0730bc7df494a817a3560eff92dd1a2ea00c5 Mon Sep 17 00:00:00 2001 From: Priyanka Jain Date: Fri, 19 Feb 2021 17:50:10 +0530 Subject: [PATCH 04/59] board: corenet_ds: MAINTAINERS: Remove redundant entries Remove MAINTAINERS entries for P3041DS_NAND_SECURE_BOOT_defconfig and P5040DS_NAND_SECURE_BOOT_defconfig as these configs support have been removed. Signed-off-by: Priyanka Jain --- board/freescale/corenet_ds/MAINTAINERS | 6 ------ 1 file changed, 6 deletions(-) diff --git a/board/freescale/corenet_ds/MAINTAINERS b/board/freescale/corenet_ds/MAINTAINERS index e22cf703b7..f0da86a34c 100644 --- a/board/freescale/corenet_ds/MAINTAINERS +++ b/board/freescale/corenet_ds/MAINTAINERS @@ -19,9 +19,3 @@ F: configs/P5040DS_NAND_defconfig F: configs/P5040DS_SDCARD_defconfig F: configs/P5040DS_SPIFLASH_defconfig F: configs/P5040DS_SECURE_BOOT_defconfig - -CORENET_DS_SECURE_BOOT BOARD -M: Ruchika Gupta -S: Maintained -F: configs/P3041DS_NAND_SECURE_BOOT_defconfig -F: configs/P5040DS_NAND_SECURE_BOOT_defconfig From c245727d31a93c3e561440622c54b7e5ae3574ab Mon Sep 17 00:00:00 2001 From: Priyanka Jain Date: Fri, 19 Feb 2021 17:50:11 +0530 Subject: [PATCH 05/59] board: ls1012afrdm: Update MAINTAINERS Update LS1012AFRWY BOARD MAINTAINER entry to current MAINTAINER. Signed-off-by: Priyanka Jain --- board/freescale/ls1012afrdm/MAINTAINERS | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/board/freescale/ls1012afrdm/MAINTAINERS b/board/freescale/ls1012afrdm/MAINTAINERS index 480b6bb325..5fc7e93850 100644 --- a/board/freescale/ls1012afrdm/MAINTAINERS +++ b/board/freescale/ls1012afrdm/MAINTAINERS @@ -1,5 +1,4 @@ LS1012AFRDM BOARD -M: Prabhakar Kushwaha M: Rajesh Bhagat S: Maintained F: board/freescale/ls1012afrdm/ @@ -10,12 +9,9 @@ F: configs/ls1012afrwy_tfa_defconfig F: configs/ls1012afrwy_tfa_SECURE_BOOT_defconfig LS1012AFRWY BOARD -M: Bhaskar Upadhaya +M: Pramod Kumar S: Maintained F: board/freescale/ls1012afrwy/ F: include/configs/ls1012afrwy.h F: configs/ls1012afrwy_qspi_defconfig - -M: Vinitha V Pillai -S: Maintained F: configs/ls1012afrwy_qspi_SECURE_BOOT_defconfig From caa18f046fc1c835ed76b3efd20d81e36f55598c Mon Sep 17 00:00:00 2001 From: Priyanka Jain Date: Fri, 19 Feb 2021 17:50:12 +0530 Subject: [PATCH 06/59] board: ls1012ardb: Update MAINTAINERS Update LS1012ARDB BOARD MAINTAINERS entries to current MAINTAINERS. Signed-off-by: Priyanka Jain --- board/freescale/ls1012ardb/MAINTAINERS | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/board/freescale/ls1012ardb/MAINTAINERS b/board/freescale/ls1012ardb/MAINTAINERS index 60e184d10f..b0c008b5fc 100644 --- a/board/freescale/ls1012ardb/MAINTAINERS +++ b/board/freescale/ls1012ardb/MAINTAINERS @@ -1,6 +1,6 @@ LS1012ARDB BOARD -M: Prabhakar Kushwaha M: Rajesh Bhagat +M: Pramod Kumar S: Maintained F: board/freescale/ls1012ardb/ F: include/configs/ls1012ardb.h @@ -8,13 +8,10 @@ F: configs/ls1012ardb_qspi_defconfig F: configs/ls1012ardb_tfa_defconfig F: configs/ls1012ardb_tfa_SECURE_BOOT_defconfig F: configs/ls1012a2g5rdb_tfa_defconfig - -M: Sumit Garg -S: Maintained F: configs/ls1012ardb_qspi_SECURE_BOOT_defconfig LS1012A2G5RDB BOARD -M: Bhaskar Upadhaya +M: Pramod Kumar S: Maintained F: board/freescale/ls1012ardb/ F: include/configs/ls1012a2g5rdb.h From 2e4dbeffabe264cf266397bb1b3fc3819f47eb16 Mon Sep 17 00:00:00 2001 From: Priyanka Jain Date: Fri, 19 Feb 2021 17:50:13 +0530 Subject: [PATCH 07/59] board: ls1021aiot: Update MAINTAINERS Update LS1021AIOT BOARD MAINTAINERS entries to current MAINTAINERS. Signed-off-by: Priyanka Jain --- board/freescale/ls1021aiot/MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/board/freescale/ls1021aiot/MAINTAINERS b/board/freescale/ls1021aiot/MAINTAINERS index 2dab7988ee..65f21bee34 100644 --- a/board/freescale/ls1021aiot/MAINTAINERS +++ b/board/freescale/ls1021aiot/MAINTAINERS @@ -1,5 +1,5 @@ LS1021AIOT BOARD -M: Feng Li +M: Alison Wang S: Maintained F: board/freescale/ls1021aiot/ F: include/configs/ls1021aiot.h From 1729147c5a2b87f6d8959277d5581dc47181f3c0 Mon Sep 17 00:00:00 2001 From: Priyanka Jain Date: Fri, 19 Feb 2021 17:50:14 +0530 Subject: [PATCH 08/59] board: ls1021atwr: Update MAINTAINERS Update LS1021ATWR BOARD MAINTAINERS entries to current MAINTAINERS. Signed-off-by: Priyanka Jain --- board/freescale/ls1021atwr/MAINTAINERS | 3 --- 1 file changed, 3 deletions(-) diff --git a/board/freescale/ls1021atwr/MAINTAINERS b/board/freescale/ls1021atwr/MAINTAINERS index c8b93c6469..7ab8347e9e 100644 --- a/board/freescale/ls1021atwr/MAINTAINERS +++ b/board/freescale/ls1021atwr/MAINTAINERS @@ -9,7 +9,4 @@ F: configs/ls1021atwr_nor_lpuart_defconfig F: configs/ls1021atwr_sdcard_ifc_defconfig F: configs/ls1021atwr_sdcard_qspi_defconfig F: configs/ls1021atwr_qspi_defconfig - -M: Sumit Garg -S: Maintained F: configs/ls1021atwr_sdcard_ifc_SECURE_BOOT_defconfig From 9a558e3c28abb5c76af325c13d3a490a1c3d3e18 Mon Sep 17 00:00:00 2001 From: Priyanka Jain Date: Fri, 19 Feb 2021 17:50:15 +0530 Subject: [PATCH 09/59] board: ls1028a: Update MAINTAINERS Update LS1028AQDS, LS10128ARDB board MAINTAINERS entries to current MAINTAINERS. Signed-off-by: Priyanka Jain --- board/freescale/ls1028a/MAINTAINERS | 4 ---- 1 file changed, 4 deletions(-) diff --git a/board/freescale/ls1028a/MAINTAINERS b/board/freescale/ls1028a/MAINTAINERS index 5b7a8db2fa..9e7b0697ff 100644 --- a/board/freescale/ls1028a/MAINTAINERS +++ b/board/freescale/ls1028a/MAINTAINERS @@ -1,6 +1,4 @@ LS1028AQDS BOARD -M: Sudhanshu Gupta -M: Rai Harninder M: Rajesh Bhagat M: Tang Yuantian S: Maintained @@ -11,8 +9,6 @@ F: configs/ls1028aqds_tfa_defconfig F: configs/ls1028aqds_tfa_lpuart_defconfig LS1028ARDB BOARD -M: Sudhanshu Gupta -M: Rai Harninder M: Rajesh Bhagat M: Tang Yuantian S: Maintained From b4d5d84484c0eeb91fa504712f701333d345e820 Mon Sep 17 00:00:00 2001 From: Priyanka Jain Date: Fri, 19 Feb 2021 17:50:16 +0530 Subject: [PATCH 10/59] board: ls1043ardb: Update MAINTAINERS Update LS1043ARDB BOARD MAINTAINERS entries to current MAINTAINERS. Signed-off-by: Priyanka Jain --- board/freescale/ls1043ardb/MAINTAINERS | 4 ---- 1 file changed, 4 deletions(-) diff --git a/board/freescale/ls1043ardb/MAINTAINERS b/board/freescale/ls1043ardb/MAINTAINERS index ed62396760..36e7331538 100644 --- a/board/freescale/ls1043ardb/MAINTAINERS +++ b/board/freescale/ls1043ardb/MAINTAINERS @@ -10,10 +10,6 @@ F: configs/ls1043ardb_nand_defconfig F: configs/ls1043ardb_sdcard_defconfig F: configs/ls1043ardb_tfa_defconfig F: configs/ls1043ardb_tfa_SECURE_BOOT_defconfig - -LS1043A_SECURE_BOOT BOARD -M: Ruchika Gupta -S: Maintained F: configs/ls1043ardb_SECURE_BOOT_defconfig F: configs/ls1043ardb_sdcard_SECURE_BOOT_defconfig F: configs/ls1043ardb_nand_SECURE_BOOT_defconfig From 8f75c959e9a9d3ec2dc39d7535263259fcd24f75 Mon Sep 17 00:00:00 2001 From: Priyanka Jain Date: Fri, 19 Feb 2021 17:50:17 +0530 Subject: [PATCH 11/59] board: ls1088a: Update MAINTAINERS Update LS1088ARDB, LS1088AQDS BOARD MAINTAINERS entries to current MAINTAINERS. Signed-off-by: Priyanka Jain --- board/freescale/ls1088a/MAINTAINERS | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/board/freescale/ls1088a/MAINTAINERS b/board/freescale/ls1088a/MAINTAINERS index 98ecb88e3b..5c7925a95f 100644 --- a/board/freescale/ls1088a/MAINTAINERS +++ b/board/freescale/ls1088a/MAINTAINERS @@ -1,5 +1,4 @@ LS1088ARDB BOARD -M: Prabhakar Kushwaha M: Ashish Kumar M: Rajesh Bhagat S: Maintained @@ -11,7 +10,6 @@ F: configs/ls1088ardb_tfa_defconfig F: configs/ls1088ardb_tfa_SECURE_BOOT_defconfig LS1088AQDS BOARD -M: Prabhakar Kushwaha M: Ashish Kumar M: Rajesh Bhagat S: Maintained @@ -25,17 +23,15 @@ F: configs/ls1088aqds_tfa_defconfig LS1088AQDS_QSPI_SECURE_BOOT BOARD M: Udit Agarwal -M: Vinitha Pillai-B57223 S: Maintained F: configs/ls1088aqds_qspi_SECURE_BOOT_defconfig LS1088ARDB_QSPI_SECURE_BOOT BOARD M: Udit Agarwal -M: Vinitha Pillai-B57223 S: Maintained F: configs/ls1088ardb_qspi_SECURE_BOOT_defconfig LS1088ARDB_SD_SECURE_BOOT BOARD -M: Sumit Garg +M: Udit Agarwal S: Maintained F: configs/ls1088ardb_sdcard_qspi_SECURE_BOOT_defconfig From 033743d7edf5f0e2dcb26726e103eed84381cc69 Mon Sep 17 00:00:00 2001 From: Priyanka Jain Date: Fri, 19 Feb 2021 17:50:18 +0530 Subject: [PATCH 12/59] board: ls2080aqds: Update MAINTAINERS Update LS2080AQDS BOARD MAINTAINERS entries to current MAINTAINERS. Signed-off-by: Priyanka Jain --- board/freescale/ls2080aqds/MAINTAINERS | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/board/freescale/ls2080aqds/MAINTAINERS b/board/freescale/ls2080aqds/MAINTAINERS index e3d7635476..84735dce28 100644 --- a/board/freescale/ls2080aqds/MAINTAINERS +++ b/board/freescale/ls2080aqds/MAINTAINERS @@ -1,5 +1,5 @@ LS2080A BOARD -M: Prabhakar Kushwaha , Priyanka Jain +M: Priyanka Jain M: Rajesh Bhagat S: Maintained F: board/freescale/ls2080aqds/ @@ -10,8 +10,4 @@ F: configs/ls2080aqds_nand_defconfig F: configs/ls2080aqds_qspi_defconfig F: configs/ls2080aqds_sdcard_defconfig F: configs/ls2088aqds_tfa_defconfig - -LS2080A_SECURE_BOOT BOARD -#M: Saksham Jain -S: Orphan (since 2018-05) F: configs/ls2080aqds_SECURE_BOOT_defconfig From f94911ed8fa3c86420b5f1c736b0896e3e363b1a Mon Sep 17 00:00:00 2001 From: Priyanka Jain Date: Fri, 19 Feb 2021 17:50:19 +0530 Subject: [PATCH 13/59] board: ls2080ardb: Update MAINTAINERS Update LS2080ARDB BOARD MAINTAINERS entries to current MAINTAINERS. Signed-off-by: Priyanka Jain --- board/freescale/ls2080ardb/MAINTAINERS | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/board/freescale/ls2080ardb/MAINTAINERS b/board/freescale/ls2080ardb/MAINTAINERS index 113b7ab3fd..6e25b82db5 100644 --- a/board/freescale/ls2080ardb/MAINTAINERS +++ b/board/freescale/ls2080ardb/MAINTAINERS @@ -1,5 +1,5 @@ LS2080A BOARD -M: Prabhakar Kushwaha , Priyanka Jain +M: Priyanka Jain S: Maintained F: board/freescale/ls2080ardb/ F: board/freescale/ls2080a/ls2080ardb.c @@ -21,8 +21,8 @@ S: Maintained F: configs/ls2081ardb_defconfig LS2080A_SECURE_BOOT BOARD -#M: Saksham Jain -S: Orphan (since 2018-05) +M: Udit Agarwal +S: Maintained F: configs/ls2080ardb_SECURE_BOOT_defconfig LS2088A_QSPI_SECURE_BOOT BOARD From b0289d99515645647698296e6c122a135b58145a Mon Sep 17 00:00:00 2001 From: Priyanka Jain Date: Fri, 19 Feb 2021 17:50:20 +0530 Subject: [PATCH 14/59] board: ls1046aqds: Update MAINTAINERS Update LS1046AQDS BOARD MAINTAINERS entries to current MAINTAINERS. Signed-off-by: Priyanka Jain --- board/freescale/ls1046aqds/MAINTAINERS | 3 --- 1 file changed, 3 deletions(-) diff --git a/board/freescale/ls1046aqds/MAINTAINERS b/board/freescale/ls1046aqds/MAINTAINERS index 39a48da95a..72c4253fcf 100644 --- a/board/freescale/ls1046aqds/MAINTAINERS +++ b/board/freescale/ls1046aqds/MAINTAINERS @@ -12,7 +12,4 @@ F: configs/ls1046aqds_qspi_defconfig F: configs/ls1046aqds_lpuart_defconfig F: configs/ls1046aqds_tfa_defconfig F: configs/ls1046aqds_tfa_SECURE_BOOT_defconfig - -M: Sumit Garg -S: Maintained F: configs/ls1046aqds_SECURE_BOOT_defconfig From 088fad9941f73d48266ce7bb220bcfce751571ad Mon Sep 17 00:00:00 2001 From: Priyanka Jain Date: Fri, 19 Feb 2021 17:50:21 +0530 Subject: [PATCH 15/59] board: ls1046ardb: Update MAINTAINERS Update LS1046ARDB BOARD MAINTAINERS entries to current MAINTAINERS. Signed-off-by: Priyanka Jain --- board/freescale/ls1046ardb/MAINTAINERS | 7 ------- 1 file changed, 7 deletions(-) diff --git a/board/freescale/ls1046ardb/MAINTAINERS b/board/freescale/ls1046ardb/MAINTAINERS index 8b4b45e9ed..efdea22bde 100644 --- a/board/freescale/ls1046ardb/MAINTAINERS +++ b/board/freescale/ls1046ardb/MAINTAINERS @@ -11,13 +11,6 @@ F: configs/ls1046ardb_sdcard_defconfig F: configs/ls1046ardb_emmc_defconfig F: configs/ls1046ardb_tfa_defconfig F: configs/ls1046ardb_tfa_SECURE_BOOT_defconfig - -LS1046A_SECURE_BOOT BOARD -M: Ruchika Gupta -S: Maintained F: configs/ls1046ardb_SECURE_BOOT_defconfig F: configs/ls1046ardb_sdcard_SECURE_BOOT_defconfig - -M: Sumit Garg -S: Maintained F: configs/ls1046ardb_qspi_SECURE_BOOT_defconfig From 044732a9033b04b242824bab84741fbbc74073ab Mon Sep 17 00:00:00 2001 From: Priyanka Jain Date: Fri, 19 Feb 2021 17:50:22 +0530 Subject: [PATCH 16/59] board: lx2160a: Update MAINTAINERS Update LX2160AQDS BOARD MAINTAINER entry to current MAINTAINER. Signed-off-by: Priyanka Jain --- board/freescale/lx2160a/MAINTAINERS | 1 - 1 file changed, 1 deletion(-) diff --git a/board/freescale/lx2160a/MAINTAINERS b/board/freescale/lx2160a/MAINTAINERS index c627417cf7..cc69de2970 100644 --- a/board/freescale/lx2160a/MAINTAINERS +++ b/board/freescale/lx2160a/MAINTAINERS @@ -16,7 +16,6 @@ F: configs/lx2160ardb_tfa_SECURE_BOOT_defconfig LX2160AQDS BOARD M: Meenakshi Aggarwal -M: Pankaj Bansal S: Maintained F: board/freescale/lx2160a/eth_lx2160aqds.h F: include/configs/lx2160aqds.h From 6ce33e228859126c87a2027d39b16e5c1b2292e1 Mon Sep 17 00:00:00 2001 From: Priyanka Jain Date: Fri, 19 Feb 2021 17:50:23 +0530 Subject: [PATCH 17/59] board: ls1012aqds: Update MAINTAINERS Update LS1012AQDS Board MAINTAINERS entries to current MAINTAINERS. Signed-off-by: Priyanka Jain --- board/freescale/ls1012aqds/MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/board/freescale/ls1012aqds/MAINTAINERS b/board/freescale/ls1012aqds/MAINTAINERS index dbd4670c3b..c1bb8d5150 100644 --- a/board/freescale/ls1012aqds/MAINTAINERS +++ b/board/freescale/ls1012aqds/MAINTAINERS @@ -1,6 +1,6 @@ LS1012AQDS BOARD -M: Prabhakar Kushwaha M: Rajesh Bhagat +M: Pramod Kumar S: Maintained F: board/freescale/ls1012aqds/ F: include/configs/ls1012aqds.h From a02dcbbb5a8e24a3f6cd3e7f158e1953b82d5e2e Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Wed, 24 Feb 2021 17:40:39 +0100 Subject: [PATCH 18/59] net: dsa: return early if there is no master It doesn't make sense to have DSA without a master port. Error out early if there is no master port. Fixes: fc054d563bfb ("net: Introduce DSA class for Ethernet switches") Signed-off-by: Michael Walle Reviewed-by: Vladimir Oltean Reviewed-by: Ramon Fried Reviewed-by: Priyanka Jain --- net/dsa-uclass.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/net/dsa-uclass.c b/net/dsa-uclass.c index 2ce9ddb90d..88a8ea9352 100644 --- a/net/dsa-uclass.c +++ b/net/dsa-uclass.c @@ -280,6 +280,10 @@ static int dsa_port_probe(struct udevice *pdev) if (!port_pdata->phy) return -ENODEV; + master = dsa_get_master(dev); + if (!master) + return -ENODEV; + /* * Inherit port's hwaddr from the DSA master, unless the port already * has a unique MAC address specified in the environment. @@ -288,10 +292,6 @@ static int dsa_port_probe(struct udevice *pdev) if (!is_zero_ethaddr(env_enetaddr)) return 0; - master = dsa_get_master(dev); - if (!master) - return 0; - master_pdata = dev_get_plat(master); eth_pdata = dev_get_plat(pdev); memcpy(eth_pdata->enetaddr, master_pdata->enetaddr, ARP_HLEN); From e5d7d119287ed1bc867e77225660c1ac9bb51072 Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Wed, 24 Feb 2021 17:40:40 +0100 Subject: [PATCH 19/59] net: dsa: probe master device DSA needs to have the master device probed first for MAC inheritance. Until now, it only works by chance because the only user (LS1028A SoC) will probe the master device first. The probe order is given by the PCI device ordering, thus it works because the master device has a "smaller" BDF then the switch device. Explicitly probe the master device in dsa_port_probe(). Fixes: fc054d563bfb ("net: Introduce DSA class for Ethernet switches") Signed-off-by: Michael Walle Reviewed-by: Vladimir Oltean Reviewed-by: Ramon Fried Reviewed-by: Priyanka Jain --- net/dsa-uclass.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/net/dsa-uclass.c b/net/dsa-uclass.c index 88a8ea9352..7898f30e15 100644 --- a/net/dsa-uclass.c +++ b/net/dsa-uclass.c @@ -272,6 +272,7 @@ static int dsa_port_probe(struct udevice *pdev) struct dsa_port_pdata *port_pdata; struct dsa_priv *dsa_priv; struct udevice *master; + int ret; port_pdata = dev_get_parent_plat(pdev); dsa_priv = dev_get_uclass_priv(dev); @@ -284,6 +285,14 @@ static int dsa_port_probe(struct udevice *pdev) if (!master) return -ENODEV; + /* + * Probe the master device. We depend on the master device for proper + * operation and we also need it for MAC inheritance below. + */ + ret = device_probe(master); + if (ret) + return ret; + /* * Inherit port's hwaddr from the DSA master, unless the port already * has a unique MAC address specified in the environment. From 108157c468eed8291c866415b8708eb2a8735dc4 Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Wed, 24 Feb 2021 17:40:41 +0100 Subject: [PATCH 20/59] net: dsa: remove NULL check for priv and platform data Because the uclass has the "*_auto" properties set, the driver model will take care of allocating the private structures for us and they can't be NULL. Drop the checks. Signed-off-by: Michael Walle Reviewed-by: Vladimir Oltean Reviewed-by: Ramon Fried Reviewed-by: Priyanka Jain --- net/dsa-uclass.c | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/net/dsa-uclass.c b/net/dsa-uclass.c index 7898f30e15..d453cc6930 100644 --- a/net/dsa-uclass.c +++ b/net/dsa-uclass.c @@ -28,8 +28,8 @@ int dsa_set_tagging(struct udevice *dev, ushort headroom, ushort tailroom) { struct dsa_priv *priv; - if (!dev || !dev_get_uclass_priv(dev)) - return -ENODEV; + if (!dev) + return -EINVAL; if (headroom + tailroom > DSA_MAX_OVR) return -EINVAL; @@ -47,11 +47,13 @@ int dsa_set_tagging(struct udevice *dev, ushort headroom, ushort tailroom) /* returns the DSA master Ethernet device */ struct udevice *dsa_get_master(struct udevice *dev) { - struct dsa_priv *priv = dev_get_uclass_priv(dev); + struct dsa_priv *priv; - if (!priv) + if (!dev) return NULL; + priv = dev_get_uclass_priv(dev); + return priv->master_dev; } @@ -67,9 +69,6 @@ static int dsa_port_start(struct udevice *pdev) struct dsa_ops *ops = dsa_get_ops(dev); int err; - if (!priv) - return -ENODEV; - if (!master) { dev_err(pdev, "DSA master Ethernet device not found!\n"); return -EINVAL; @@ -101,9 +100,6 @@ static void dsa_port_stop(struct udevice *pdev) struct udevice *master = dsa_get_master(dev); struct dsa_ops *ops = dsa_get_ops(dev); - if (!priv) - return; - if (ops->port_disable) { struct dsa_port_pdata *port_pdata; @@ -347,7 +343,7 @@ static int dsa_post_bind(struct udevice *dev) ofnode node = dev_ofnode(dev), pnode; int i, err, first_err = 0; - if (!pdata || !ofnode_valid(node)) + if (!ofnode_valid(node)) return -ENODEV; pdata->master_node = ofnode_null(); @@ -459,9 +455,6 @@ static int dsa_pre_probe(struct udevice *dev) struct dsa_pdata *pdata = dev_get_uclass_plat(dev); struct dsa_priv *priv = dev_get_uclass_priv(dev); - if (!pdata || !priv) - return -ENODEV; - priv->num_ports = pdata->num_ports; priv->cpu_port = pdata->cpu_port; priv->cpu_port_fixed_phy = fixed_phy_create(pdata->cpu_port_node); From 714555374f2ff889cecbde62938a17e9678a0f09 Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Wed, 24 Feb 2021 17:40:42 +0100 Subject: [PATCH 21/59] net: dsa: remove master santiy check Because we probe the master ourselves (and fail if there is no master), it is not possible that we don't have a master device. There is one catch though: device removal. We don't support that. It wasn't supported neither before this patch. Because the master device was only set in .pre_probe(), if a device was removed master_dev was a dangling pointer and transmitting a frame cause a panic. I don't see a good solution without having some sort of notify machanism when a udevice is removed. Signed-off-by: Michael Walle Reviewed-by: Vladimir Oltean Tested-by: Michael Walle [DSA unit tests] Reviewed-by: Priyanka Jain --- net/dsa-uclass.c | 25 ++++--------------------- 1 file changed, 4 insertions(+), 21 deletions(-) diff --git a/net/dsa-uclass.c b/net/dsa-uclass.c index d453cc6930..7ea1cb6949 100644 --- a/net/dsa-uclass.c +++ b/net/dsa-uclass.c @@ -69,11 +69,6 @@ static int dsa_port_start(struct udevice *pdev) struct dsa_ops *ops = dsa_get_ops(dev); int err; - if (!master) { - dev_err(pdev, "DSA master Ethernet device not found!\n"); - return -EINVAL; - } - if (ops->port_enable) { struct dsa_port_pdata *port_pdata; @@ -108,13 +103,7 @@ static void dsa_port_stop(struct udevice *pdev) ops->port_disable(dev, priv->cpu_port, NULL); } - /* - * stop master only if it's active, don't probe it otherwise. - * Under normal usage it would be active because we're using it, but - * during tear-down it may have been removed ahead of us. - */ - if (master && device_active(master)) - eth_get_ops(master)->stop(master); + eth_get_ops(master)->stop(master); } /* @@ -133,9 +122,6 @@ static int dsa_port_send(struct udevice *pdev, void *packet, int length) struct dsa_port_pdata *port_pdata; int err; - if (!master) - return -EINVAL; - if (length + head + tail > PKTSIZE_ALIGN) return -EINVAL; @@ -165,9 +151,6 @@ static int dsa_port_recv(struct udevice *pdev, int flags, uchar **packetp) struct dsa_port_pdata *port_pdata; int length, port_index, err; - if (!master) - return -EINVAL; - length = eth_get_ops(master)->recv(master, flags, packetp); if (length <= 0) return length; @@ -201,9 +184,6 @@ static int dsa_port_free_pkt(struct udevice *pdev, uchar *packet, int length) struct udevice *master = dsa_get_master(dev); struct dsa_priv *priv; - if (!master) - return -EINVAL; - priv = dev_get_uclass_priv(dev); if (eth_get_ops(master)->free_pkt) { /* return the original pointer and length to master Eth */ @@ -284,6 +264,9 @@ static int dsa_port_probe(struct udevice *pdev) /* * Probe the master device. We depend on the master device for proper * operation and we also need it for MAC inheritance below. + * + * TODO: we assume the master device is always there and doesn't get + * removed during runtime. */ ret = device_probe(master); if (ret) From 7365a03804ed48a827e91141f3b07f11e20572eb Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 25 Feb 2021 17:22:22 +0800 Subject: [PATCH 22/59] pci: fsl_pci_init: Dynamically allocate the PCI regions Commit e002474158d1 ("pci: pci-uclass: Dynamically allocate the PCI regions") changes 'struct pci_controller'.regions from pre-allocated array of regions to dynamically allocated, which unfortunately broken lots of boards that still use the non-DM PCI driver. This patch changes the non-DM fsl_pci_init driver to dynamically allocate the regions, just like what's done in the pci uclass driver. Fixes: e002474158d1 ("pci: pci-uclass: Dynamically allocate the PCI regions") Signed-off-by: Bin Meng Reviewed-by: Simon Glass Reviewed-by: Priyanka Jain --- drivers/pci/fsl_pci_init.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/pci/fsl_pci_init.c b/drivers/pci/fsl_pci_init.c index e72a60c131..fc3327ec53 100644 --- a/drivers/pci/fsl_pci_init.c +++ b/drivers/pci/fsl_pci_init.c @@ -32,6 +32,8 @@ DECLARE_GLOBAL_DATA_PTR; #include #include +#define MAX_PCI_REGIONS 7 + #ifndef CONFIG_SYS_PCI_MEMORY_BUS #define CONFIG_SYS_PCI_MEMORY_BUS 0 #endif @@ -80,6 +82,9 @@ int fsl_setup_hose(struct pci_controller *hose, unsigned long addr) /* Reset hose to make sure its in a clean state */ memset(hose, 0, sizeof(struct pci_controller)); + hose->regions = (struct pci_region *) + calloc(1, MAX_PCI_REGIONS * sizeof(struct pci_region)); + pci_setup_indirect(hose, (u32)&pci->cfg_addr, (u32)&pci->cfg_data); return fsl_is_pci_agent(hose); From 5cd1ecb994904365018f64132a85144625017fb9 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 25 Feb 2021 17:22:23 +0800 Subject: [PATCH 23/59] ppc: qemu: Update MAINTAINERS for correct email address Alex's previous email address is no longer reachable. Signed-off-by: Bin Meng Reviewed-by: Simon Glass Reviewed-by: Priyanka Jain --- board/freescale/qemu-ppce500/MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/board/freescale/qemu-ppce500/MAINTAINERS b/board/freescale/qemu-ppce500/MAINTAINERS index 77d0a4a13c..e70c095b65 100644 --- a/board/freescale/qemu-ppce500/MAINTAINERS +++ b/board/freescale/qemu-ppce500/MAINTAINERS @@ -1,5 +1,5 @@ QEMU-PPCE500 BOARD -M: Alexander Graf +M: Alexander Graf S: Maintained F: board/freescale/qemu-ppce500/ F: include/configs/qemu-ppce500.h From a932aa3c692606d6ada803de966b1aee09257993 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 25 Feb 2021 17:22:24 +0800 Subject: [PATCH 24/59] common: fdt_support: Support special case of PCI address in fdt_read_prop() At present fdt_read_prop() can only handle 1 or 2 cells. It is called by fdt_read_range() which may be used to read PCI address from for a PCI bus node where the number of PCI address cell is 3. The property is an array of: { } When trying to read from a PCI bus node using fdt_read_prop(), as the codes below: /* Read */ if (child_addr) { r = fdt_read_prop(ranges, ranges_len, cell, child_addr, acells); if (r) return r; } it will fail, because the PCI child address is made up of 3 cells but fdt_read_prop() cannot handle it. We advance the cell offset by 1 so that the can be correctly read. This adds the special handling of such case. Signed-off-by: Bin Meng Reviewed-by: Simon Glass Reviewed-by: Priyanka Jain --- common/fdt_support.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/common/fdt_support.c b/common/fdt_support.c index 08d540bfc8..e624bbdf40 100644 --- a/common/fdt_support.c +++ b/common/fdt_support.c @@ -1668,22 +1668,36 @@ u64 fdt_get_base_address(const void *fdt, int node) } /* - * Read a property of size . Currently only supports 1 or 2 cells. + * Read a property of size . Currently only supports 1 or 2 cells, + * or 3 cells specially for a PCI address. */ static int fdt_read_prop(const fdt32_t *prop, int prop_len, int cell_off, uint64_t *val, int cells) { - const fdt32_t *prop32 = &prop[cell_off]; - const unaligned_fdt64_t *prop64 = (const fdt64_t *)&prop[cell_off]; + const fdt32_t *prop32; + const unaligned_fdt64_t *prop64; if ((cell_off + cells) > prop_len) return -FDT_ERR_NOSPACE; + prop32 = &prop[cell_off]; + + /* + * Special handling for PCI address in PCI bus + * + * PCI child address is made up of 3 cells. Advance the cell offset + * by 1 so that the PCI child address can be correctly read. + */ + if (cells == 3) + cell_off += 1; + prop64 = (const fdt64_t *)&prop[cell_off]; + switch (cells) { case 1: *val = fdt32_to_cpu(*prop32); break; case 2: + case 3: *val = fdt64_to_cpu(*prop64); break; default: From 84912a78644b68de4117dab2570f71cea2bd745a Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 25 Feb 2021 17:22:25 +0800 Subject: [PATCH 25/59] ppc: qemu: Support non-identity PCI bus address When QEMU originally supported the ppce500 machine back in Jan 2014, it was created with a 1:1 mapping of PCI bus address. Things seemed to change rapidly that in Nov 2014 with the following QEMU commits: commit e6b4e5f4795b ("PPC: e500: Move CCSR and MMIO space to upper end of address space") and commit cb3778a0455a ("PPC: e500 pci host: Add support for ATMUs") the PCI memory and IO physical address were moved to beyond 4 GiB, but PCI bus address remained below 4 GiB, hence a non-identity mapping was created. Unfortunately corresponding U-Boot updates were missed along with the QEMU changes and the U-Boot QEMU ppce500 PCI support has been broken since then. This commit makes the PCI (non-DM version) work again. Signed-off-by: Bin Meng Reviewed-by: Priyanka Jain --- board/freescale/qemu-ppce500/qemu-ppce500.c | 29 ++++++++++----------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/board/freescale/qemu-ppce500/qemu-ppce500.c b/board/freescale/qemu-ppce500/qemu-ppce500.c index aa5774fd79..1d68d30b6f 100644 --- a/board/freescale/qemu-ppce500/qemu-ppce500.c +++ b/board/freescale/qemu-ppce500/qemu-ppce500.c @@ -85,20 +85,24 @@ int checkboard(void) } static int pci_map_region(void *fdt, int pci_node, int range_id, - phys_size_t *ppaddr, pci_addr_t *pvaddr, - pci_size_t *psize, ulong *pmap_addr) + phys_addr_t *pbaddr, phys_size_t *ppaddr, + pci_addr_t *pvaddr, pci_size_t *psize, + ulong *pmap_addr) { - uint64_t addr; + uint64_t baddr; + uint64_t paddr; uint64_t size; ulong map_addr; int r; - r = fdt_read_range(fdt, pci_node, range_id, NULL, &addr, &size); + r = fdt_read_range(fdt, pci_node, range_id, &baddr, &paddr, &size); if (r) return r; + if (pbaddr) + *pbaddr = baddr; if (ppaddr) - *ppaddr = addr; + *ppaddr = paddr; if (psize) *psize = size; @@ -115,7 +119,7 @@ static int pci_map_region(void *fdt, int pci_node, int range_id, return -1; /* Map virtual memory for range */ - assert(!tlb_map_range(map_addr, addr, size, TLB_MAP_IO)); + assert(!tlb_map_range(map_addr, paddr, size, TLB_MAP_IO)); *pmap_addr = map_addr + size; if (pvaddr) @@ -166,24 +170,19 @@ void pci_init_board(void) pci_info.regs = fdt_translate_address(fdt, pci_node, reg); /* Map MMIO range */ - r = pci_map_region(fdt, pci_node, 0, &pci_info.mem_phys, NULL, + r = pci_map_region(fdt, pci_node, 0, &pci_info.mem_bus, + &pci_info.mem_phys, NULL, &pci_info.mem_size, &map_addr); if (r) break; /* Map PIO range */ - r = pci_map_region(fdt, pci_node, 1, &pci_info.io_phys, NULL, + r = pci_map_region(fdt, pci_node, 1, &pci_info.io_bus, + &pci_info.io_phys, NULL, &pci_info.io_size, &map_addr); if (r) break; - /* - * The PCI framework finds virtual addresses for the buses - * through our address map, so tell it the physical addresses. - */ - pci_info.mem_bus = pci_info.mem_phys; - pci_info.io_bus = pci_info.io_phys; - /* Instantiate */ pci_info.pci_num = pci_num + 1; From fc5af5c9d58b59ab708cdc2bddb62b9404f7cf75 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 25 Feb 2021 17:22:26 +0800 Subject: [PATCH 26/59] ppc: qemu: Fix CONFIG_SYS_PCI_MAP_END CONFIG_SYS_PCI_MAP_END currently points to 0xe8000000, which means the upper end of the virtual address mapped to PCI bus address ends at 0xe8000000. But this is wrong as the CCSBAR was already mapped at 0xe0000000 with a 1 MiB size. Fixes: fa08d3951777 ("PPC 85xx: Add qemu-ppce500 machine") Signed-off-by: Bin Meng Reviewed-by: Priyanka Jain --- include/configs/qemu-ppce500.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/configs/qemu-ppce500.h b/include/configs/qemu-ppce500.h index ee6ef18224..f13e4ea5cf 100644 --- a/include/configs/qemu-ppce500.h +++ b/include/configs/qemu-ppce500.h @@ -35,7 +35,7 @@ extern unsigned long long get_phys_ccsrbar_addr_early(void); /* Virtual address range for PCI region maps */ #define CONFIG_SYS_PCI_MAP_START 0x80000000 -#define CONFIG_SYS_PCI_MAP_END 0xe8000000 +#define CONFIG_SYS_PCI_MAP_END 0xe0000000 /* Virtual address to a temporary map if we need it (max 128MB) */ #define CONFIG_SYS_TMPVIRT 0xe8000000 From 907568e895eaef745664a81b8e45e05b72cc90b5 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 25 Feb 2021 17:22:27 +0800 Subject: [PATCH 27/59] ppc: mpc85xx: Wrap LAW related codes with CONFIG_FSL_LAW LAW related codes should be wrapped with CONFIG_FSL_LAW. Signed-off-by: Bin Meng Reviewed-by: Priyanka Jain --- arch/powerpc/cpu/mpc85xx/cpu.c | 2 ++ arch/powerpc/cpu/mpc85xx/cpu_init_early.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/arch/powerpc/cpu/mpc85xx/cpu.c b/arch/powerpc/cpu/mpc85xx/cpu.c index 5170610f04..fc25bb28ad 100644 --- a/arch/powerpc/cpu/mpc85xx/cpu.c +++ b/arch/powerpc/cpu/mpc85xx/cpu.c @@ -395,7 +395,9 @@ int cpu_mmc_init(struct bd_info *bis) void print_reginfo(void) { print_tlbcam(); +#ifdef CONFIG_FSL_LAW print_laws(); +#endif #if defined(CONFIG_FSL_LBC) print_lbc_regs(); #endif diff --git a/arch/powerpc/cpu/mpc85xx/cpu_init_early.c b/arch/powerpc/cpu/mpc85xx/cpu_init_early.c index 4195ecc5c9..5a0d33b1b3 100644 --- a/arch/powerpc/cpu/mpc85xx/cpu_init_early.c +++ b/arch/powerpc/cpu/mpc85xx/cpu_init_early.c @@ -123,7 +123,9 @@ void cpu_init_early_f(void *fdt) setbits_be32(&gur->pmuxcr, MPC85xx_PMUXCR_LCLK_IFC_CS3); #endif +#ifdef CONFIG_FSL_LAW init_laws(); +#endif /* * Work Around for IFC Erratum A003399, issue will hit only when execution From 49b5cd16eb4251431c363d3ef2a0d5025e5bae42 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 25 Feb 2021 17:22:28 +0800 Subject: [PATCH 28/59] ppc: qemu: Drop init_laws() and print_laws() These are no longer needed. Drop them. Signed-off-by: Bin Meng Reviewed-by: Priyanka Jain --- board/freescale/qemu-ppce500/qemu-ppce500.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/board/freescale/qemu-ppce500/qemu-ppce500.c b/board/freescale/qemu-ppce500/qemu-ppce500.c index 1d68d30b6f..dba5e0f489 100644 --- a/board/freescale/qemu-ppce500/qemu-ppce500.c +++ b/board/freescale/qemu-ppce500/qemu-ppce500.c @@ -254,11 +254,6 @@ int ft_board_setup(void *blob, struct bd_info *bd) } #endif -void print_laws(void) -{ - /* We don't emulate LAWs yet */ -} - phys_size_t fixed_sdram(void) { return get_linear_ram_size(); @@ -302,11 +297,6 @@ void init_tlbs(void) 1024 * 1024, TLB_MAP_RAM)); } -void init_laws(void) -{ - /* We don't emulate LAWs yet */ -} - static uint32_t get_cpu_freq(void) { void *fdt = get_fdt_virt(); From 91617d2865dcb31d3e70165861eb9c0a0c450ab8 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 25 Feb 2021 17:22:29 +0800 Subject: [PATCH 29/59] ppc: qemu: Drop board_early_init_f() This function does nothing. Drop it. Signed-off-by: Bin Meng Reviewed-by: Priyanka Jain --- board/freescale/qemu-ppce500/qemu-ppce500.c | 5 ----- configs/qemu-ppce500_defconfig | 1 - 2 files changed, 6 deletions(-) diff --git a/board/freescale/qemu-ppce500/qemu-ppce500.c b/board/freescale/qemu-ppce500/qemu-ppce500.c index dba5e0f489..4719d98584 100644 --- a/board/freescale/qemu-ppce500/qemu-ppce500.c +++ b/board/freescale/qemu-ppce500/qemu-ppce500.c @@ -74,11 +74,6 @@ uint64_t get_phys_ccsrbar_addr_early(void) return r; } -int board_early_init_f(void) -{ - return 0; -} - int checkboard(void) { return 0; diff --git a/configs/qemu-ppce500_defconfig b/configs/qemu-ppce500_defconfig index d17c556dba..25fcd41986 100644 --- a/configs/qemu-ppce500_defconfig +++ b/configs/qemu-ppce500_defconfig @@ -10,7 +10,6 @@ CONFIG_OF_BOARD_SETUP=y CONFIG_OF_STDOUT_VIA_ALIAS=y CONFIG_BOOTDELAY=1 # CONFIG_DISPLAY_BOARDINFO is not set -CONFIG_BOARD_EARLY_INIT_F=y CONFIG_LAST_STAGE_INIT=y # CONFIG_MISC_INIT_R is not set CONFIG_HUSH_PARSER=y From c1979d74bc52a727a1c09d4592f18e2226e45af6 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 25 Feb 2021 17:22:30 +0800 Subject: [PATCH 30/59] ppc: qemu: Enable OF_CONTROL The QEMU ppce500 machine generates a device tree blob and passes it to U-Boot during boot. Let's enable OF_CONTROL with OF_BOARD and provide board_fdt_blob_setup() in the board codes. Signed-off-by: Bin Meng Reviewed-by: Simon Glass Reviewed-by: Priyanka Jain --- board/freescale/qemu-ppce500/qemu-ppce500.c | 10 ++++++++++ configs/qemu-ppce500_defconfig | 3 ++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/board/freescale/qemu-ppce500/qemu-ppce500.c b/board/freescale/qemu-ppce500/qemu-ppce500.c index 4719d98584..50167d546f 100644 --- a/board/freescale/qemu-ppce500/qemu-ppce500.c +++ b/board/freescale/qemu-ppce500/qemu-ppce500.c @@ -364,3 +364,13 @@ u32 cpu_mask(void) { return (1 << cpu_numcores()) - 1; } + +/** + * Return the virtual address of FDT that was passed by QEMU + * + * @return virtual address of FDT received from QEMU in r3 register + */ +void *board_fdt_blob_setup(void) +{ + return get_fdt_virt(); +} diff --git a/configs/qemu-ppce500_defconfig b/configs/qemu-ppce500_defconfig index 25fcd41986..4522e18c7b 100644 --- a/configs/qemu-ppce500_defconfig +++ b/configs/qemu-ppce500_defconfig @@ -22,6 +22,8 @@ CONFIG_CMD_PING=y # CONFIG_CMD_HASH is not set CONFIG_CMD_EXT2=y CONFIG_DOS_PARTITION=y +CONFIG_OF_CONTROL=y +CONFIG_OF_BOARD=y CONFIG_ENV_OVERWRITE=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y # CONFIG_MMC is not set @@ -29,4 +31,3 @@ CONFIG_E1000=y CONFIG_SYS_NS16550=y CONFIG_ADDR_MAP=y CONFIG_PANIC_HANG=y -CONFIG_OF_LIBFDT=y From d8a61a7f32e724613ba6be117160b29641bfbd49 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 25 Feb 2021 17:22:31 +0800 Subject: [PATCH 31/59] ppc: qemu: Enable driver model At present QEMU ppce500 target has not been migrated to driver model yet. As a start, let's enable driver model and the 'dm' command. Signed-off-by: Bin Meng Reviewed-by: Simon Glass Reviewed-by: Priyanka Jain --- configs/qemu-ppce500_defconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/configs/qemu-ppce500_defconfig b/configs/qemu-ppce500_defconfig index 4522e18c7b..f2a8b83bcf 100644 --- a/configs/qemu-ppce500_defconfig +++ b/configs/qemu-ppce500_defconfig @@ -16,6 +16,7 @@ CONFIG_HUSH_PARSER=y CONFIG_CMD_REGINFO=y CONFIG_CMD_BOOTZ=y CONFIG_CMD_GREPENV=y +CONFIG_CMD_DM=y CONFIG_CMD_PCI=y CONFIG_CMD_DHCP=y CONFIG_CMD_PING=y @@ -26,6 +27,7 @@ CONFIG_OF_CONTROL=y CONFIG_OF_BOARD=y CONFIG_ENV_OVERWRITE=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y +CONFIG_DM=y # CONFIG_MMC is not set CONFIG_E1000=y CONFIG_SYS_NS16550=y From c40131acc030ac9b1bf0704306aa18295d44ff2a Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 25 Feb 2021 17:22:32 +0800 Subject: [PATCH 32/59] include: Remove extern from addr_map.h Remove the extern of the header because they are useless. Signed-off-by: Bin Meng Reviewed-by: Simon Glass Reviewed-by: Priyanka Jain --- include/addr_map.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/addr_map.h b/include/addr_map.h index d322dd222a..85e737d0f6 100644 --- a/include/addr_map.h +++ b/include/addr_map.h @@ -8,9 +8,9 @@ #include -extern phys_addr_t addrmap_virt_to_phys(void *vaddr); -extern void *addrmap_phys_to_virt(phys_addr_t paddr); -extern void addrmap_set_entry(unsigned long vaddr, phys_addr_t paddr, - phys_size_t size, int idx); +phys_addr_t addrmap_virt_to_phys(void *vaddr); +void *addrmap_phys_to_virt(phys_addr_t paddr); +void addrmap_set_entry(unsigned long vaddr, phys_addr_t paddr, + phys_size_t size, int idx); #endif From b56156331693856aceb76e6aa3d61e58f7ae8dd4 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 25 Feb 2021 17:22:33 +0800 Subject: [PATCH 33/59] lib: addr_map: Move address_map[] type to the header file At present address_map[] is static and its type is unknown to external modules. In preparation to create a command to list its contents, this patch moves its type definition and declaration to the header file. Signed-off-by: Bin Meng Reviewed-by: Simon Glass Reviewed-by: Priyanka Jain --- include/addr_map.h | 8 ++++++++ lib/addr_map.c | 6 +----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/include/addr_map.h b/include/addr_map.h index 85e737d0f6..55d3a6a165 100644 --- a/include/addr_map.h +++ b/include/addr_map.h @@ -8,6 +8,14 @@ #include +struct addrmap { + phys_addr_t paddr; + phys_size_t size; + unsigned long vaddr; +}; + +extern struct addrmap address_map[CONFIG_SYS_NUM_ADDR_MAP]; + phys_addr_t addrmap_virt_to_phys(void *vaddr); void *addrmap_phys_to_virt(phys_addr_t paddr); void addrmap_set_entry(unsigned long vaddr, phys_addr_t paddr, diff --git a/lib/addr_map.c b/lib/addr_map.c index 09771f3a5a..fb2ef40007 100644 --- a/lib/addr_map.c +++ b/lib/addr_map.c @@ -6,11 +6,7 @@ #include #include -static struct { - phys_addr_t paddr; - phys_size_t size; - unsigned long vaddr; -} address_map[CONFIG_SYS_NUM_ADDR_MAP]; +struct addrmap address_map[CONFIG_SYS_NUM_ADDR_MAP]; phys_addr_t addrmap_virt_to_phys(void * vaddr) { From 56d0635f18def8b4bd7b6b5af5f2b0efa98a2a12 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 25 Feb 2021 17:22:34 +0800 Subject: [PATCH 34/59] cmd: Add a command to display the address map This adds a new command 'addrmap' to display the address map for non-identity virtual-physical memory mappings. Signed-off-by: Bin Meng Reviewed-by: Simon Glass Reviewed-by: Priyanka Jain --- cmd/Kconfig | 7 +++++++ cmd/Makefile | 1 + cmd/addrmap.c | 35 +++++++++++++++++++++++++++++++++++ doc/usage/addrmap.rst | 41 +++++++++++++++++++++++++++++++++++++++++ doc/usage/index.rst | 1 + 5 files changed, 85 insertions(+) create mode 100644 cmd/addrmap.c create mode 100644 doc/usage/addrmap.rst diff --git a/cmd/Kconfig b/cmd/Kconfig index 4defbd9cf9..fcf59cd238 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -97,6 +97,13 @@ config CMD_ACPI between the firmware and OS, and is particularly useful when you want to make hardware changes without the OS needing to be adjusted. +config CMD_ADDRMAP + bool "addrmap" + depends on ADDR_MAP + default y + help + List non-identity virtual-physical memory mappings for 32-bit CPUs. + config CMD_BDI bool "bdinfo" default y diff --git a/cmd/Makefile b/cmd/Makefile index 176bf925fd..567e2b79d2 100644 --- a/cmd/Makefile +++ b/cmd/Makefile @@ -13,6 +13,7 @@ obj-y += version.o # command obj-$(CONFIG_CMD_ACPI) += acpi.o +obj-$(CONFIG_CMD_ADDRMAP) += addrmap.o obj-$(CONFIG_CMD_AES) += aes.o obj-$(CONFIG_CMD_AB_SELECT) += ab_select.o obj-$(CONFIG_CMD_ADC) += adc.o diff --git a/cmd/addrmap.c b/cmd/addrmap.c new file mode 100644 index 0000000000..bd23549f3a --- /dev/null +++ b/cmd/addrmap.c @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2021, Bin Meng + */ + +#include +#include +#include + +static int do_addrmap(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + int i; + + printf(" vaddr paddr size\n"); + printf("================ ================ ================\n"); + + for (i = 0; i < CONFIG_SYS_NUM_ADDR_MAP; i++) { + if (address_map[i].size == 0) + continue; + + printf("%16.8lx %16.8llx %16.8llx\n", + address_map[i].vaddr, + (unsigned long long)address_map[i].paddr, + (unsigned long long)address_map[i].size); + } + + return 0; +} + +U_BOOT_CMD( + addrmap, 1, 1, do_addrmap, + "List non-identity virtual-physical memory mappings for 32-bit CPUs", + "" +); diff --git a/doc/usage/addrmap.rst b/doc/usage/addrmap.rst new file mode 100644 index 0000000000..472fd547f3 --- /dev/null +++ b/doc/usage/addrmap.rst @@ -0,0 +1,41 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +addrmap command +=============== + +Synopsis +-------- + +:: + + addrmap + +Description +----------- + +The addrmap command is used to display non-identity virtual-physical memory +mappings for 32-bit CPUs. + +The output may look like: + +:: + + => addrmap + vaddr paddr size + ================ ================ ================ + e0000000 fe0000000 00100000 + 00000000 00000000 04000000 + 04000000 04000000 04000000 + 80000000 c00000000 10000000 + 90000000 c10000000 10000000 + a0000000 fe1000000 00010000 + +The first column indicates the virtual address. +The second column indicates the physical address. +The third column indicates the mapped size. + +Configuration +------------- + +To use the addrmap command you must specify CONFIG_CMD_ADDRMAP=y. +It is automatically turned on when CONFIG_ADDR_MAP is set. diff --git a/doc/usage/index.rst b/doc/usage/index.rst index 09372d4a96..9169fff0be 100644 --- a/doc/usage/index.rst +++ b/doc/usage/index.rst @@ -14,6 +14,7 @@ Shell commands .. toctree:: :maxdepth: 1 + addrmap base bootefi booti From ea309212fe7b0baf02a09cc6c30a80ae13d1b681 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 25 Feb 2021 17:22:35 +0800 Subject: [PATCH 35/59] test: cmd: Add a basic test for 'addrmap' command This adds a basic test for the newly introduced 'addrmap' command. Signed-off-by: Bin Meng Reviewed-by: Simon Glass [Rebase] Signed-off-by: Priyanka Jain --- include/test/suites.h | 2 ++ test/cmd/Makefile | 1 + test/cmd/addrmap.c | 38 ++++++++++++++++++++++++++++++++++++++ test/cmd_ut.c | 6 ++++++ 4 files changed, 47 insertions(+) create mode 100644 test/cmd/addrmap.c diff --git a/include/test/suites.h b/include/test/suites.h index 52e8fc8155..f5d8e139ce 100644 --- a/include/test/suites.h +++ b/include/test/suites.h @@ -26,6 +26,8 @@ int cmd_ut_category(const char *name, const char *prefix, struct unit_test *tests, int n_ents, int argc, char *const argv[]); +int do_ut_addrmap(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]); int do_ut_bootm(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]); int do_ut_bloblist(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]); diff --git a/test/cmd/Makefile b/test/cmd/Makefile index c84df60395..2cfe43a6bd 100644 --- a/test/cmd/Makefile +++ b/test/cmd/Makefile @@ -6,6 +6,7 @@ ifdef CONFIG_HUSH_PARSER obj-$(CONFIG_CONSOLE_RECORD) += test_echo.o endif obj-y += mem.o +obj-$(CONFIG_CMD_ADDRMAP) += addrmap.o obj-$(CONFIG_CMD_MEM_SEARCH) += mem_search.o obj-$(CONFIG_CMD_PWM) += pwm.o obj-$(CONFIG_CMD_SETEXPR) += setexpr.o diff --git a/test/cmd/addrmap.c b/test/cmd/addrmap.c new file mode 100644 index 0000000000..fb744485bb --- /dev/null +++ b/test/cmd/addrmap.c @@ -0,0 +1,38 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Tests for addrmap command + * + * Copyright (C) 2021, Bin Meng + */ + +#include +#include +#include +#include + +/* Declare a new addrmap test */ +#define ADDRMAP_TEST(_name, _flags) UNIT_TEST(_name, _flags, addrmap_test) + +/* Test 'addrmap' command output */ +static int addrmap_test_basic(struct unit_test_state *uts) +{ + ut_assertok(console_record_reset_enable()); + ut_assertok(run_command("addrmap", 0)); + ut_assert_nextline(" vaddr paddr size"); + ut_assert_nextline("================ ================ ================"); + /* There should be at least one entry */ + ut_assertok(!ut_check_console_end(uts)); + + return 0; +} +ADDRMAP_TEST(addrmap_test_basic, UT_TESTF_CONSOLE_REC); + +int do_ut_addrmap(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) +{ + struct unit_test *tests = ll_entry_start(struct unit_test, + addrmap_test); + const int n_ents = ll_entry_count(struct unit_test, addrmap_test); + + return cmd_ut_category("cmd_addrmap", "cmd_addrmap_", tests, n_ents, + argc, argv); +} diff --git a/test/cmd_ut.c b/test/cmd_ut.c index 8f3089890e..8728cc8650 100644 --- a/test/cmd_ut.c +++ b/test/cmd_ut.c @@ -93,6 +93,9 @@ static struct cmd_tbl cmd_ut_sub[] = { U_BOOT_CMD_MKENT(bootm, CONFIG_SYS_MAXARGS, 1, do_ut_bootm, "", ""), #endif U_BOOT_CMD_MKENT(str, CONFIG_SYS_MAXARGS, 1, do_ut_str, "", ""), +#ifdef CONFIG_CMD_ADDRMAP + U_BOOT_CMD_MKENT(addrmap, CONFIG_SYS_MAXARGS, 1, do_ut_addrmap, "", ""), +#endif }; static int do_ut_all(struct cmd_tbl *cmdtp, int flag, int argc, @@ -167,6 +170,9 @@ static char ut_help_text[] = #if defined(CONFIG_UT_UNICODE) && \ !defined(CONFIG_SPL_BUILD) && !defined(API_BUILD) "ut unicode [test-name] - test Unicode functions\n" +#endif +#ifdef CONFIG_CMD_ADDRMAP + "ut addrmap - Very basic test of addrmap command\n" #endif ; #endif /* CONFIG_SYS_LONGHELP */ From e010315899b2dc5e74fec313e9de73d689b92631 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 25 Feb 2021 17:22:36 +0800 Subject: [PATCH 36/59] lib: kconfig: Mention CONFIG_ADDR_MAP limitation in the help Mention that CONFIG_ADDR_MAP only works in the post-relocation phase. Signed-off-by: Bin Meng Reviewed-by: Simon Glass Reviewed-by: Priyanka Jain --- lib/Kconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/Kconfig b/lib/Kconfig index 7f4c30ec0d..7288340614 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -6,6 +6,8 @@ config ADDR_MAP Enables helper code for implementing non-identity virtual-physical memory mappings for 32bit CPUs. + This library only works in the post-relocation phase. + config SYS_NUM_ADDR_MAP int "Size of the address-map table" depends on ADDR_MAP From 3320656944707aff7838b1ccb4c630143a67fe08 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 25 Feb 2021 17:22:37 +0800 Subject: [PATCH 37/59] ppc: io.h: Use addrmap_ translation APIs only in post-relocation phase In phys_to_virt() and virt_to_phys(), if CONFIG_ADDR_MAP is defined, they use addrmap_ translation APIs to do the address translation. However these APIs only work in post-relocation phase. Update the code logic to fall back to use the default one when in pre-relocation phase. Signed-off-by: Bin Meng Reviewed-by: Priyanka Jain --- arch/powerpc/include/asm/io.h | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/arch/powerpc/include/asm/io.h b/arch/powerpc/include/asm/io.h index 6d76e3e99c..998a82aa0d 100644 --- a/arch/powerpc/include/asm/io.h +++ b/arch/powerpc/include/asm/io.h @@ -10,7 +10,10 @@ #include #ifdef CONFIG_ADDR_MAP +#include #include + +DECLARE_GLOBAL_DATA_PTR; #endif #define SIO_CONFIG_RA 0x398 @@ -303,20 +306,20 @@ static inline void out_be32(volatile unsigned __iomem *addr, u32 val) static inline void *phys_to_virt(phys_addr_t paddr) { #ifdef CONFIG_ADDR_MAP - return addrmap_phys_to_virt(paddr); -#else - return (void *)((unsigned long)paddr); + if (gd->flags & GD_FLG_RELOC) + return addrmap_phys_to_virt(paddr); #endif + return (void *)((unsigned long)paddr); } #define phys_to_virt phys_to_virt static inline phys_addr_t virt_to_phys(void * vaddr) { #ifdef CONFIG_ADDR_MAP - return addrmap_virt_to_phys(vaddr); -#else - return (phys_addr_t)((unsigned long)vaddr); + if (gd->flags & GD_FLG_RELOC) + return addrmap_virt_to_phys(vaddr); #endif + return (phys_addr_t)((unsigned long)vaddr); } #define virt_to_phys virt_to_phys From a43b598cc15ae101438a0412d0a8c134b428f71e Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 25 Feb 2021 17:22:38 +0800 Subject: [PATCH 38/59] common: Move initr_addr_map() to a bit earlier At present initr_addr_map() is put at a late stage in the init_sequence_r[] calls. This won't work because lot of device driver initialization (e.g.: serial port) happens before it but is lack of the address translation support. This moves the call to a bit earlier, right after the DM initialization. Signed-off-by: Bin Meng Reviewed-by: Simon Glass Reviewed-by: Priyanka Jain --- common/board_r.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/common/board_r.c b/common/board_r.c index 9793439adf..c835ff8e26 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -626,6 +626,9 @@ static init_fnc_t init_sequence_r[] = { #ifdef CONFIG_DM initr_dm, #endif +#ifdef CONFIG_ADDR_MAP + initr_addr_map, +#endif #if defined(CONFIG_ARM) || defined(CONFIG_NDS32) || defined(CONFIG_RISCV) || \ defined(CONFIG_SANDBOX) board_init, /* Setup chipselects */ @@ -661,9 +664,6 @@ static init_fnc_t init_sequence_r[] = { initr_manual_reloc_cmdtable, #endif arch_initr_trap, -#ifdef CONFIG_ADDR_MAP - initr_addr_map, -#endif #if defined(CONFIG_BOARD_EARLY_INIT_R) board_early_init_r, #endif From 2e91e8b3327015af4fc8b99bc81d9268a65eb559 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 25 Feb 2021 17:22:39 +0800 Subject: [PATCH 39/59] ppc: qemu: Switch over to use DM serial The QEMU ppce500 target integrates 2 NS16550 serial ports. Switch over to use the DM version of the driver by: - drop unnecessary ad-hoc config macros - add get_serial_clock() in the board codes Signed-off-by: Bin Meng Reviewed-by: Simon Glass Reviewed-by: Priyanka Jain --- board/freescale/qemu-ppce500/qemu-ppce500.c | 6 ++++++ configs/qemu-ppce500_defconfig | 1 + include/configs/qemu-ppce500.h | 10 ---------- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/board/freescale/qemu-ppce500/qemu-ppce500.c b/board/freescale/qemu-ppce500/qemu-ppce500.c index 50167d546f..db13582f0f 100644 --- a/board/freescale/qemu-ppce500/qemu-ppce500.c +++ b/board/freescale/qemu-ppce500/qemu-ppce500.c @@ -374,3 +374,9 @@ void *board_fdt_blob_setup(void) { return get_fdt_virt(); } + +/* See CONFIG_SYS_NS16550_CLK in arch/powerpc/include/asm/config.h */ +int get_serial_clock(void) +{ + return get_bus_freq(0); +} diff --git a/configs/qemu-ppce500_defconfig b/configs/qemu-ppce500_defconfig index f2a8b83bcf..c528a68bfa 100644 --- a/configs/qemu-ppce500_defconfig +++ b/configs/qemu-ppce500_defconfig @@ -30,6 +30,7 @@ CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_DM=y # CONFIG_MMC is not set CONFIG_E1000=y +CONFIG_DM_SERIAL=y CONFIG_SYS_NS16550=y CONFIG_ADDR_MAP=y CONFIG_PANIC_HANG=y diff --git a/include/configs/qemu-ppce500.h b/include/configs/qemu-ppce500.h index f13e4ea5cf..feac6ef8fa 100644 --- a/include/configs/qemu-ppce500.h +++ b/include/configs/qemu-ppce500.h @@ -73,16 +73,6 @@ extern unsigned long long get_phys_ccsrbar_addr_early(void); #define CONFIG_SYS_MONITOR_LEN (512 * 1024) #define CONFIG_SYS_MALLOC_LEN (4 * 1024 * 1024) -#define CONFIG_SYS_NS16550_SERIAL -#define CONFIG_SYS_NS16550_REG_SIZE 1 -#define CONFIG_SYS_NS16550_CLK (get_bus_freq(0)) - -#define CONFIG_SYS_BAUDRATE_TABLE \ - {300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200} - -#define CONFIG_SYS_NS16550_COM1 (CONFIG_SYS_CCSRBAR+0x4500) -#define CONFIG_SYS_NS16550_COM2 (CONFIG_SYS_CCSRBAR+0x4600) - /* * General PCI * Memory space is mapped 1-1, but I/O space must start from 0. From 5a40f5c09dfdc1ddc9413584d5a99f2879e10de8 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 25 Feb 2021 17:22:40 +0800 Subject: [PATCH 40/59] pci: mpc85xx: Wrap LAW programming with CONFIG_FSL_LAW For the QEMU ppce500 machine, LAW registers are not implemented hence CONFIG_FSL_LAW is not turned on and all LAW APIs are not available. We should wrap all LAW registers programming in the mpc85xx PCI driver with CONFIG_FSL_LAW. Signed-off-by: Bin Meng Reviewed-by: Heiko Schocher Reviewed-by: Priyanka Jain --- drivers/pci/pci_mpc85xx.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/pci/pci_mpc85xx.c b/drivers/pci/pci_mpc85xx.c index ab6ff45a51..7387a1edd9 100644 --- a/drivers/pci/pci_mpc85xx.c +++ b/drivers/pci/pci_mpc85xx.c @@ -46,6 +46,7 @@ static int mpc85xx_pci_dm_write_config(struct udevice *dev, pci_dev_t bdf, return 0; } +#ifdef CONFIG_FSL_LAW static int mpc85xx_pci_dm_setup_laws(struct pci_region *io, struct pci_region *mem, struct pci_region *pre) @@ -68,6 +69,7 @@ mpc85xx_pci_dm_setup_laws(struct pci_region *io, struct pci_region *mem, return 0; } +#endif static int mpc85xx_pci_dm_probe(struct udevice *dev) { @@ -85,7 +87,9 @@ static int mpc85xx_pci_dm_probe(struct udevice *dev) return -EINVAL; } +#ifdef CONFIG_FSL_LAW mpc85xx_pci_dm_setup_laws(io, mem, pre); +#endif pcix = priv->cfg_addr; /* BAR 1: memory */ From 03ff970a1b5a07f0814adf8156e2fb520ffb322a Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 25 Feb 2021 17:22:41 +0800 Subject: [PATCH 41/59] pci: mpc85xx: Support controller register physical address beyond 32-bit devfdt_get_addr_index() returns fdt_addr_t which might be a 64-bit physical address. Use map_physmem() to return the virtual address that can be used by a 32-bit machine. Signed-off-by: Bin Meng Reviewed-by: Heiko Schocher Reviewed-by: Priyanka Jain --- drivers/pci/pci_mpc85xx.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/pci/pci_mpc85xx.c b/drivers/pci/pci_mpc85xx.c index 7387a1edd9..f0d469a8fa 100644 --- a/drivers/pci/pci_mpc85xx.c +++ b/drivers/pci/pci_mpc85xx.c @@ -134,9 +134,8 @@ static int mpc85xx_pci_of_to_plat(struct udevice *dev) addr = devfdt_get_addr_index(dev, 0); if (addr == FDT_ADDR_T_NONE) return -EINVAL; - priv->cfg_addr = (void __iomem *)addr; - addr += 4; - priv->cfg_data = (void __iomem *)addr; + priv->cfg_addr = (void __iomem *)map_physmem(addr, 0, MAP_NOCACHE); + priv->cfg_data = (void __iomem *)((ulong)priv->cfg_addr + 4); return 0; } From 8461ee51151e153045eb3ce97eb334a1921e1d5c Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 25 Feb 2021 17:22:42 +0800 Subject: [PATCH 42/59] pci: mpc85xx: Support 64-bit bus and cpu address At present the driver only supports 32-bit bus and cpu address. The controller's outbound registers/fields for extended address are not programmed. Let's program them to support 64-bit bus and cpu address. Signed-off-by: Bin Meng Reviewed-by: Heiko Schocher Reviewed-by: Priyanka Jain --- drivers/pci/pci_mpc85xx.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/pci/pci_mpc85xx.c b/drivers/pci/pci_mpc85xx.c index f0d469a8fa..574cb784a8 100644 --- a/drivers/pci/pci_mpc85xx.c +++ b/drivers/pci/pci_mpc85xx.c @@ -93,18 +93,18 @@ static int mpc85xx_pci_dm_probe(struct udevice *dev) pcix = priv->cfg_addr; /* BAR 1: memory */ - out_be32(&pcix->potar1, (mem->bus_start >> 12) & 0x000fffff); - out_be32(&pcix->potear1, 0); - out_be32(&pcix->powbar1, (mem->phys_start >> 12) & 0x000fffff); - out_be32(&pcix->powbear1, 0); + out_be32(&pcix->potar1, mem->bus_start >> 12); + out_be32(&pcix->potear1, (u64)mem->bus_start >> 44); + out_be32(&pcix->powbar1, mem->phys_start >> 12); + out_be32(&pcix->powbear1, (u64)mem->phys_start >> 44); out_be32(&pcix->powar1, (POWAR_EN | POWAR_MEM_READ | POWAR_MEM_WRITE | (__ilog2(mem->size) - 1))); /* BAR 1: IO */ - out_be32(&pcix->potar2, (io->bus_start >> 12) & 0x000fffff); - out_be32(&pcix->potear2, 0); - out_be32(&pcix->powbar2, (io->phys_start >> 12) & 0x000fffff); - out_be32(&pcix->powbear2, 0); + out_be32(&pcix->potar2, io->bus_start >> 12); + out_be32(&pcix->potear2, (u64)io->bus_start >> 44); + out_be32(&pcix->powbar2, io->phys_start >> 12); + out_be32(&pcix->powbear2, (u64)io->phys_start >> 44); out_be32(&pcix->powar2, (POWAR_EN | POWAR_IO_READ | POWAR_IO_WRITE | (__ilog2(io->size) - 1))); From 8ee401670a53307e7e0e2754f09e0126bfaa11da Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 25 Feb 2021 17:22:43 +0800 Subject: [PATCH 43/59] ppc: qemu: Switch over to use DM ETH and PCI At present the board supports non-DM version PCI and E1000 drivers. Switch over to use DM ETH and PCI by: - Rewrite the PCI address map functions using DM APIs - Enable CONFIG_MISC_INIT_R to do the PCI initialization and address map - Drop unnecessary ad-hoc config macros - Remove board_eth_init() in the board codes Signed-off-by: Bin Meng Reviewed-by: Simon Glass Reviewed-by: Priyanka Jain --- board/freescale/qemu-ppce500/qemu-ppce500.c | 111 ++++---------------- configs/qemu-ppce500_defconfig | 4 +- include/configs/qemu-ppce500.h | 13 --- 3 files changed, 24 insertions(+), 104 deletions(-) diff --git a/board/freescale/qemu-ppce500/qemu-ppce500.c b/board/freescale/qemu-ppce500/qemu-ppce500.c index db13582f0f..659f794317 100644 --- a/board/freescale/qemu-ppce500/qemu-ppce500.c +++ b/board/freescale/qemu-ppce500/qemu-ppce500.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -79,27 +80,9 @@ int checkboard(void) return 0; } -static int pci_map_region(void *fdt, int pci_node, int range_id, - phys_addr_t *pbaddr, phys_size_t *ppaddr, - pci_addr_t *pvaddr, pci_size_t *psize, - ulong *pmap_addr) +static int pci_map_region(phys_addr_t paddr, phys_size_t size, ulong *pmap_addr) { - uint64_t baddr; - uint64_t paddr; - uint64_t size; ulong map_addr; - int r; - - r = fdt_read_range(fdt, pci_node, range_id, &baddr, &paddr, &size); - if (r) - return r; - - if (pbaddr) - *pbaddr = baddr; - if (ppaddr) - *ppaddr = paddr; - if (psize) - *psize = size; if (!pmap_addr) return 0; @@ -117,82 +100,37 @@ static int pci_map_region(void *fdt, int pci_node, int range_id, assert(!tlb_map_range(map_addr, paddr, size, TLB_MAP_IO)); *pmap_addr = map_addr + size; - if (pvaddr) - *pvaddr = map_addr; - return 0; } -void pci_init_board(void) +int misc_init_r(void) { - struct pci_controller *pci_hoses; - void *fdt = get_fdt_virt(); - int pci_node = -1; - int pci_num = 0; - int pci_count = 0; + struct udevice *dev; + struct pci_region *io; + struct pci_region *mem; + struct pci_region *pre; ulong map_addr; + int ret; - puts("\n"); + /* Ensure PCI is probed */ + uclass_first_device(UCLASS_PCI, &dev); + + pci_get_regions(dev, &io, &mem, &pre); /* Start MMIO and PIO range maps above RAM */ map_addr = CONFIG_SYS_PCI_MAP_START; - /* Count and allocate PCI buses */ - pci_node = fdt_node_offset_by_prop_value(fdt, pci_node, - "device_type", "pci", 4); - while (pci_node != -FDT_ERR_NOTFOUND) { - pci_node = fdt_node_offset_by_prop_value(fdt, pci_node, - "device_type", "pci", 4); - pci_count++; - } + /* Map MMIO range */ + ret = pci_map_region(mem->phys_start, mem->size, &map_addr); + if (ret) + return ret; - if (pci_count) { - pci_hoses = malloc(sizeof(struct pci_controller) * pci_count); - } else { - printf("PCI: disabled\n\n"); - return; - } + /* Map PIO range */ + ret = pci_map_region(io->phys_start, io->size, &map_addr); + if (ret) + return ret; - /* Spawn PCI buses based on device tree */ - pci_node = fdt_node_offset_by_prop_value(fdt, pci_node, - "device_type", "pci", 4); - while (pci_node != -FDT_ERR_NOTFOUND) { - struct fsl_pci_info pci_info = { }; - const fdt32_t *reg; - int r; - - reg = fdt_getprop(fdt, pci_node, "reg", NULL); - pci_info.regs = fdt_translate_address(fdt, pci_node, reg); - - /* Map MMIO range */ - r = pci_map_region(fdt, pci_node, 0, &pci_info.mem_bus, - &pci_info.mem_phys, NULL, - &pci_info.mem_size, &map_addr); - if (r) - break; - - /* Map PIO range */ - r = pci_map_region(fdt, pci_node, 1, &pci_info.io_bus, - &pci_info.io_phys, NULL, - &pci_info.io_size, &map_addr); - if (r) - break; - - /* Instantiate */ - pci_info.pci_num = pci_num + 1; - - fsl_setup_hose(&pci_hoses[pci_num], pci_info.regs); - printf("PCI: base address %lx\n", pci_info.regs); - - fsl_pci_init_port(&pci_info, &pci_hoses[pci_num], pci_num); - - /* Jump to next PCI node */ - pci_node = fdt_node_offset_by_prop_value(fdt, pci_node, - "device_type", "pci", 4); - pci_num++; - } - - puts("\n"); + return 0; } int last_stage_init(void) @@ -235,16 +173,9 @@ static uint64_t get_linear_ram_size(void) panic("Couldn't determine RAM size"); } -int board_eth_init(struct bd_info *bis) -{ - return pci_eth_init(bis); -} - #if defined(CONFIG_OF_BOARD_SETUP) int ft_board_setup(void *blob, struct bd_info *bd) { - FT_FSL_PCI_SETUP; - return 0; } #endif diff --git a/configs/qemu-ppce500_defconfig b/configs/qemu-ppce500_defconfig index c528a68bfa..4a4b3699b5 100644 --- a/configs/qemu-ppce500_defconfig +++ b/configs/qemu-ppce500_defconfig @@ -11,7 +11,6 @@ CONFIG_OF_STDOUT_VIA_ALIAS=y CONFIG_BOOTDELAY=1 # CONFIG_DISPLAY_BOARDINFO is not set CONFIG_LAST_STAGE_INIT=y -# CONFIG_MISC_INIT_R is not set CONFIG_HUSH_PARSER=y CONFIG_CMD_REGINFO=y CONFIG_CMD_BOOTZ=y @@ -29,7 +28,10 @@ CONFIG_ENV_OVERWRITE=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_DM=y # CONFIG_MMC is not set +CONFIG_DM_ETH=y CONFIG_E1000=y +CONFIG_DM_PCI=y +CONFIG_PCI_MPC85XX=y CONFIG_DM_SERIAL=y CONFIG_SYS_NS16550=y CONFIG_ADDR_MAP=y diff --git a/include/configs/qemu-ppce500.h b/include/configs/qemu-ppce500.h index feac6ef8fa..b1ee810f01 100644 --- a/include/configs/qemu-ppce500.h +++ b/include/configs/qemu-ppce500.h @@ -13,8 +13,6 @@ #define CONFIG_SYS_RAMBOOT -#define CONFIG_PCI1 1 /* PCI controller 1 */ -#define CONFIG_FSL_PCI_INIT /* Use common FSL init code */ #define CONFIG_SYS_PCI_64BIT /* enable 64-bit PCI resources */ #define CONFIG_ENABLE_36BIT_PHYS @@ -73,17 +71,6 @@ extern unsigned long long get_phys_ccsrbar_addr_early(void); #define CONFIG_SYS_MONITOR_LEN (512 * 1024) #define CONFIG_SYS_MALLOC_LEN (4 * 1024 * 1024) -/* - * General PCI - * Memory space is mapped 1-1, but I/O space must start from 0. - */ - -#ifdef CONFIG_PCI -#define CONFIG_PCI_INDIRECT_BRIDGE - -#define CONFIG_PCI_SCAN_SHOW /* show pci devices on startup */ -#endif /* CONFIG_PCI */ - #define CONFIG_LBA48 /* From 3fc735d4a5dcca334e65485fdd22ca1b5bf793fe Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 25 Feb 2021 17:22:44 +0800 Subject: [PATCH 44/59] ppc: qemu: Drop CONFIG_OF_BOARD_SETUP ft_board_setup() is now empty. Drop it. Signed-off-by: Bin Meng Reviewed-by: Priyanka Jain --- board/freescale/qemu-ppce500/qemu-ppce500.c | 7 ------- configs/qemu-ppce500_defconfig | 1 - 2 files changed, 8 deletions(-) diff --git a/board/freescale/qemu-ppce500/qemu-ppce500.c b/board/freescale/qemu-ppce500/qemu-ppce500.c index 659f794317..79a698671c 100644 --- a/board/freescale/qemu-ppce500/qemu-ppce500.c +++ b/board/freescale/qemu-ppce500/qemu-ppce500.c @@ -173,13 +173,6 @@ static uint64_t get_linear_ram_size(void) panic("Couldn't determine RAM size"); } -#if defined(CONFIG_OF_BOARD_SETUP) -int ft_board_setup(void *blob, struct bd_info *bd) -{ - return 0; -} -#endif - phys_size_t fixed_sdram(void) { return get_linear_ram_size(); diff --git a/configs/qemu-ppce500_defconfig b/configs/qemu-ppce500_defconfig index 4a4b3699b5..918739b615 100644 --- a/configs/qemu-ppce500_defconfig +++ b/configs/qemu-ppce500_defconfig @@ -6,7 +6,6 @@ CONFIG_MPC85xx=y CONFIG_TARGET_QEMU_PPCE500=y CONFIG_FIT=y CONFIG_FIT_VERBOSE=y -CONFIG_OF_BOARD_SETUP=y CONFIG_OF_STDOUT_VIA_ALIAS=y CONFIG_BOOTDELAY=1 # CONFIG_DISPLAY_BOARDINFO is not set From 05173eca33510b76629fd2c87c969c8db619bb73 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 25 Feb 2021 17:22:45 +0800 Subject: [PATCH 45/59] cmd: Fix virtio command dependency The 'virtio' command calls blk_common_cmd() which is only available when CONFIG_HAVE_BLOCK_DEVICE is on. Fix the Kconfig dependency. Signed-off-by: Bin Meng Reviewed-by: Simon Glass Reviewed-by: Priyanka Jain --- cmd/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/cmd/Kconfig b/cmd/Kconfig index fcf59cd238..eff238cb38 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -1345,6 +1345,7 @@ config CMD_PVBLOCK config CMD_VIRTIO bool "virtio" depends on VIRTIO + depends on HAVE_BLOCK_DEVICE default y if VIRTIO help VirtIO block device support From 46c9b595369170bc011e56dfb0c26d834f3e5e60 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 25 Feb 2021 17:22:46 +0800 Subject: [PATCH 46/59] ppc: qemu: Enable VirtIO NET support By default the QEMU ppce500 machine connects a VirtIO NET to the PCI controller, although it can be replaced to an e1000 NIC via additional command line options. Now that we have switched over to DM PCI, VirtIO support becomes possible. This commit enables the support. Signed-off-by: Bin Meng Reviewed-by: Priyanka Jain --- board/freescale/qemu-ppce500/qemu-ppce500.c | 8 ++++++++ configs/qemu-ppce500_defconfig | 2 ++ 2 files changed, 10 insertions(+) diff --git a/board/freescale/qemu-ppce500/qemu-ppce500.c b/board/freescale/qemu-ppce500/qemu-ppce500.c index 79a698671c..9c30c12d4f 100644 --- a/board/freescale/qemu-ppce500/qemu-ppce500.c +++ b/board/freescale/qemu-ppce500/qemu-ppce500.c @@ -24,6 +24,8 @@ #include #include #include +#include +#include DECLARE_GLOBAL_DATA_PTR; @@ -130,6 +132,12 @@ int misc_init_r(void) if (ret) return ret; + /* + * Make sure virtio bus is enumerated so that peripherals + * on the virtio bus can be discovered by their drivers. + */ + virtio_init(); + return 0; } diff --git a/configs/qemu-ppce500_defconfig b/configs/qemu-ppce500_defconfig index 918739b615..202e97e8ec 100644 --- a/configs/qemu-ppce500_defconfig +++ b/configs/qemu-ppce500_defconfig @@ -33,5 +33,7 @@ CONFIG_DM_PCI=y CONFIG_PCI_MPC85XX=y CONFIG_DM_SERIAL=y CONFIG_SYS_NS16550=y +CONFIG_VIRTIO_PCI=y +CONFIG_VIRTIO_NET=y CONFIG_ADDR_MAP=y CONFIG_PANIC_HANG=y From 5474ef886c971f925d5ce1f2e57adfeb8e7865e4 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 25 Feb 2021 17:22:47 +0800 Subject: [PATCH 47/59] virtio: Fix VirtIO BLK driver dependency The VirtIO BLK driver depends on the blk uclass driver. Add the dependency in the Kconfig. Signed-off-by: Bin Meng Reviewed-by: Simon Glass Reviewed-by: Priyanka Jain --- drivers/virtio/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/virtio/Kconfig b/drivers/virtio/Kconfig index e800720657..1835607083 100644 --- a/drivers/virtio/Kconfig +++ b/drivers/virtio/Kconfig @@ -55,6 +55,7 @@ config VIRTIO_NET config VIRTIO_BLK bool "virtio block driver" depends on VIRTIO + depends on BLK help This is the virtual block driver for virtio. It can be used with QEMU based targets. From 843d9b8d03163d6e5f95cb1d1a9831b84861447c Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 25 Feb 2021 17:22:48 +0800 Subject: [PATCH 48/59] ppc: qemu: Enable VirtIO BLK support Enable VirtIO BLK driver so that we can store a kernel image to a disk image and boot from there. Signed-off-by: Bin Meng Reviewed-by: Priyanka Jain --- configs/qemu-ppce500_defconfig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/configs/qemu-ppce500_defconfig b/configs/qemu-ppce500_defconfig index 202e97e8ec..b2510c8390 100644 --- a/configs/qemu-ppce500_defconfig +++ b/configs/qemu-ppce500_defconfig @@ -26,6 +26,8 @@ CONFIG_OF_BOARD=y CONFIG_ENV_OVERWRITE=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_DM=y +CONFIG_BLK=y +CONFIG_HAVE_BLOCK_DEVICE=y # CONFIG_MMC is not set CONFIG_DM_ETH=y CONFIG_E1000=y @@ -35,5 +37,6 @@ CONFIG_DM_SERIAL=y CONFIG_SYS_NS16550=y CONFIG_VIRTIO_PCI=y CONFIG_VIRTIO_NET=y +CONFIG_VIRTIO_BLK=y CONFIG_ADDR_MAP=y CONFIG_PANIC_HANG=y From f94cbb5b87e19ad4316966b581bd40f70ee80c93 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 25 Feb 2021 17:22:49 +0800 Subject: [PATCH 49/59] ppc: mpc85xx: Add 'gpibe' register to 'struct ccsr_gpio' Without this, the DM GPIO driver for MPC8xxx does not compile for MPC85xx SoCs. Signed-off-by: Bin Meng Reviewed-by: Priyanka Jain --- arch/powerpc/include/asm/immap_85xx.h | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/powerpc/include/asm/immap_85xx.h b/arch/powerpc/include/asm/immap_85xx.h index c6c009261d..905613fa31 100644 --- a/arch/powerpc/include/asm/immap_85xx.h +++ b/arch/powerpc/include/asm/immap_85xx.h @@ -272,6 +272,7 @@ typedef struct ccsr_gpio { u32 gpier; u32 gpimr; u32 gpicr; + u32 gpibe; } ccsr_gpio_t; #endif From 271a87b4ecc498cf718738b1a5271c911eec17ff Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 25 Feb 2021 17:22:50 +0800 Subject: [PATCH 50/59] gpio: mpc8xxx: Support controller register physical address beyond 32-bit dev_read_addr_size_index() returns fdt_addr_t which might be a 64-bit physical address. This might be true for some 85xx SoCs whose CCSBAR is mapped beyond 4 GiB. Signed-off-by: Bin Meng Reviewed-by: Priyanka Jain --- arch/powerpc/include/asm/arch-mpc85xx/gpio.h | 2 +- drivers/gpio/mpc8xxx_gpio.c | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/include/asm/arch-mpc85xx/gpio.h b/arch/powerpc/include/asm/arch-mpc85xx/gpio.h index c7086a8361..79ba7868c2 100644 --- a/arch/powerpc/include/asm/arch-mpc85xx/gpio.h +++ b/arch/powerpc/include/asm/arch-mpc85xx/gpio.h @@ -18,7 +18,7 @@ #endif struct mpc8xxx_gpio_plat { - ulong addr; + phys_addr_t addr; unsigned long size; uint ngpios; }; diff --git a/drivers/gpio/mpc8xxx_gpio.c b/drivers/gpio/mpc8xxx_gpio.c index c733603289..f7ffd8926a 100644 --- a/drivers/gpio/mpc8xxx_gpio.c +++ b/drivers/gpio/mpc8xxx_gpio.c @@ -20,7 +20,7 @@ struct mpc8xxx_gpio_data { /* The bank's register base in memory */ struct ccsr_gpio __iomem *base; /* The address of the registers; used to identify the bank */ - ulong addr; + phys_addr_t addr; /* The GPIO count of the bank */ uint gpio_count; /* The GPDAT register cannot be used to determine the value of output @@ -181,7 +181,7 @@ static int mpc8xxx_gpio_of_to_plat(struct udevice *dev) if (dev_read_bool(dev, "little-endian")) data->little_endian = true; - plat->addr = (ulong)dev_read_addr_size_index(dev, 0, (fdt_size_t *)&plat->size); + plat->addr = dev_read_addr_size_index(dev, 0, (fdt_size_t *)&plat->size); plat->ngpios = dev_read_u32_default(dev, "ngpios", 32); return 0; @@ -220,7 +220,8 @@ static int mpc8xxx_gpio_probe(struct udevice *dev) mpc8xxx_gpio_plat_to_priv(dev); - snprintf(name, sizeof(name), "MPC@%lx_", data->addr); + snprintf(name, sizeof(name), "MPC@%.8llx", + (unsigned long long)data->addr); str = strdup(name); if (!str) From e022403adb6e4df6dad449322aa9323aa9d16f20 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 25 Feb 2021 17:22:51 +0800 Subject: [PATCH 51/59] ppc: qemu: Enable GPIO support QEMU ppce500 target integrates a GPIO controller that is compatible with the QorIQ GPIO controller. Enable the DM GPIO driver for it and the 'gpio' command. Signed-off-by: Bin Meng Reviewed-by: Priyanka Jain --- configs/qemu-ppce500_defconfig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/configs/qemu-ppce500_defconfig b/configs/qemu-ppce500_defconfig index b2510c8390..c5e2ad39bf 100644 --- a/configs/qemu-ppce500_defconfig +++ b/configs/qemu-ppce500_defconfig @@ -1,6 +1,7 @@ CONFIG_PPC=y CONFIG_SYS_TEXT_BASE=0xf01000 CONFIG_ENV_SIZE=0x2000 +CONFIG_DM_GPIO=y CONFIG_MPC85xx=y # CONFIG_CMD_ERRATA is not set CONFIG_TARGET_QEMU_PPCE500=y @@ -15,6 +16,7 @@ CONFIG_CMD_REGINFO=y CONFIG_CMD_BOOTZ=y CONFIG_CMD_GREPENV=y CONFIG_CMD_DM=y +CONFIG_CMD_GPIO=y CONFIG_CMD_PCI=y CONFIG_CMD_DHCP=y CONFIG_CMD_PING=y @@ -28,6 +30,7 @@ CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_DM=y CONFIG_BLK=y CONFIG_HAVE_BLOCK_DEVICE=y +CONFIG_MPC8XXX_GPIO=y # CONFIG_MMC is not set CONFIG_DM_ETH=y CONFIG_E1000=y From 5f1a08b6ab1c3923735edb676a4de87df4bb96f7 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 25 Feb 2021 17:22:52 +0800 Subject: [PATCH 52/59] dm: sysreset: Add a Kconfig option for the 'reset' command sysreset uclass driver provides an implementation of 'reset' command using the sysreset_ APIs unconditionally. It also supports the 'poweroff' command using the sysreset_ APIs, but under a Kconfig option CONFIG_SYSRESET_CMD_POWEROFF. Let's do the same for the 'reset' command, by introducing a new Kconfig option CONFIG_SYSRESET_CMD_RESET, and set it to on by default, to allow a board that don't have a sysreset reset driver yet, but have a sysreset poweroff driver to compile without any issue. Signed-off-by: Bin Meng Reviewed-by: Simon Glass Reviewed-by: Priyanka Jain --- drivers/sysreset/Kconfig | 6 ++++++ drivers/sysreset/sysreset-uclass.c | 2 ++ 2 files changed, 8 insertions(+) diff --git a/drivers/sysreset/Kconfig b/drivers/sysreset/Kconfig index 0e5c7c9971..968dfa4831 100644 --- a/drivers/sysreset/Kconfig +++ b/drivers/sysreset/Kconfig @@ -33,6 +33,12 @@ config TPL_SYSRESET if SYSRESET +config SYSRESET_CMD_RESET + bool "sysreset implementation of the reset command" + default y + help + Enable sysreset implementation of the reset command. + if CMD_POWEROFF config SYSRESET_CMD_POWEROFF diff --git a/drivers/sysreset/sysreset-uclass.c b/drivers/sysreset/sysreset-uclass.c index a9908ebf79..6c9dc7a384 100644 --- a/drivers/sysreset/sysreset-uclass.c +++ b/drivers/sysreset/sysreset-uclass.c @@ -119,6 +119,7 @@ void reset_cpu(ulong addr) } +#if IS_ENABLED(CONFIG_SYSRESET_CMD_RESET) int do_reset(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { printf("resetting ...\n"); @@ -128,6 +129,7 @@ int do_reset(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) return 0; } +#endif #if IS_ENABLED(CONFIG_SYSRESET_CMD_POWEROFF) int do_poweroff(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) From 037b17d29c2fa4d143ff129a43ffb131cce19674 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 25 Feb 2021 17:22:53 +0800 Subject: [PATCH 53/59] ppc: qemu: Enable support for power off via GPIO The QEMU ppce500 target provides the power off functionality via the GPIO pin#0, and we can support this using the sysreset gpio poweroff driver. Let's enable it. Signed-off-by: Bin Meng Reviewed-by: Priyanka Jain --- configs/qemu-ppce500_defconfig | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/configs/qemu-ppce500_defconfig b/configs/qemu-ppce500_defconfig index c5e2ad39bf..8798db69a8 100644 --- a/configs/qemu-ppce500_defconfig +++ b/configs/qemu-ppce500_defconfig @@ -1,7 +1,6 @@ CONFIG_PPC=y CONFIG_SYS_TEXT_BASE=0xf01000 CONFIG_ENV_SIZE=0x2000 -CONFIG_DM_GPIO=y CONFIG_MPC85xx=y # CONFIG_CMD_ERRATA is not set CONFIG_TARGET_QEMU_PPCE500=y @@ -18,6 +17,7 @@ CONFIG_CMD_GREPENV=y CONFIG_CMD_DM=y CONFIG_CMD_GPIO=y CONFIG_CMD_PCI=y +CONFIG_CMD_POWEROFF=y CONFIG_CMD_DHCP=y CONFIG_CMD_PING=y # CONFIG_CMD_HASH is not set @@ -38,6 +38,10 @@ CONFIG_DM_PCI=y CONFIG_PCI_MPC85XX=y CONFIG_DM_SERIAL=y CONFIG_SYS_NS16550=y +CONFIG_SYSRESET=y +# CONFIG_SYSRESET_CMD_RESET is not set +CONFIG_SYSRESET_CMD_POWEROFF=y +CONFIG_POWEROFF_GPIO=y CONFIG_VIRTIO_PCI=y CONFIG_VIRTIO_NET=y CONFIG_VIRTIO_BLK=y From 9a39f76c7ac06ba04235b4192c1f4daf5094a924 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 25 Feb 2021 17:22:54 +0800 Subject: [PATCH 54/59] ppc: qemu: Enable RTC support via I2C The QEMU ppce500 target integrates a Freescale I2C controller and has a Pericom pt7c4338 RTC connected to it. Enable corresponding DM drivers so that 'date' command is actually useful. Signed-off-by: Bin Meng Reviewed-by: Priyanka Jain --- configs/qemu-ppce500_defconfig | 3 +++ include/configs/qemu-ppce500.h | 3 +++ 2 files changed, 6 insertions(+) diff --git a/configs/qemu-ppce500_defconfig b/configs/qemu-ppce500_defconfig index 8798db69a8..536fe7d6e1 100644 --- a/configs/qemu-ppce500_defconfig +++ b/configs/qemu-ppce500_defconfig @@ -31,11 +31,14 @@ CONFIG_DM=y CONFIG_BLK=y CONFIG_HAVE_BLOCK_DEVICE=y CONFIG_MPC8XXX_GPIO=y +CONFIG_DM_I2C=y +CONFIG_SYS_I2C_FSL=y # CONFIG_MMC is not set CONFIG_DM_ETH=y CONFIG_E1000=y CONFIG_DM_PCI=y CONFIG_PCI_MPC85XX=y +CONFIG_DM_RTC=y CONFIG_DM_SERIAL=y CONFIG_SYS_NS16550=y CONFIG_SYSRESET=y diff --git a/include/configs/qemu-ppce500.h b/include/configs/qemu-ppce500.h index b1ee810f01..7c65e64d75 100644 --- a/include/configs/qemu-ppce500.h +++ b/include/configs/qemu-ppce500.h @@ -73,6 +73,9 @@ extern unsigned long long get_phys_ccsrbar_addr_early(void); #define CONFIG_LBA48 +/* RTC */ +#define CONFIG_RTC_PT7C4338 + /* * Environment */ From c8f911cb08fcb6216424be5a6904a1ed237c4318 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 25 Feb 2021 17:22:55 +0800 Subject: [PATCH 55/59] ppc: qemu: Delete the temporary FDT virtual-physical mapping after U-Boot is relocated After U-Boot is relocated to RAM already, the previous temporary FDT virtual-physical mapping that was used in the pre-relocation phase is no longer needed. Let's delete the mapping. get_fdt_virt() might be used before and after relocation, update it to return different virtual address of FDT. Signed-off-by: Bin Meng Reviewed-by: Priyanka Jain --- board/freescale/qemu-ppce500/qemu-ppce500.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/board/freescale/qemu-ppce500/qemu-ppce500.c b/board/freescale/qemu-ppce500/qemu-ppce500.c index 9c30c12d4f..480776a21d 100644 --- a/board/freescale/qemu-ppce500/qemu-ppce500.c +++ b/board/freescale/qemu-ppce500/qemu-ppce500.c @@ -31,7 +31,10 @@ DECLARE_GLOBAL_DATA_PTR; static void *get_fdt_virt(void) { - return (void *)CONFIG_SYS_TMPVIRT; + if (gd->flags & GD_FLG_RELOC) + return (void *)gd->fdt_blob; + else + return (void *)CONFIG_SYS_TMPVIRT; } static uint64_t get_fdt_phys(void) @@ -138,6 +141,12 @@ int misc_init_r(void) */ virtio_init(); + /* + * U-Boot is relocated to RAM already, let's delete the temporary FDT + * virtual-physical mapping that was used in the pre-relocation phase. + */ + disable_tlb(find_tlb_idx((void *)CONFIG_SYS_TMPVIRT, 1)); + return 0; } From b516dd5af714dabff5e0b20a280a0f0ec91dcecb Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 25 Feb 2021 17:22:56 +0800 Subject: [PATCH 56/59] ppc: qemu: Drop a custom env variable 'fdt_addr_r' Now that we have switched to CONFIG_OF_CONTROL, and we can use the env variable 'fdtcontroladdr' directly instead of creating one that is duplicated. Signed-off-by: Bin Meng Reviewed-by: Priyanka Jain --- board/freescale/qemu-ppce500/qemu-ppce500.c | 3 --- include/configs/qemu-ppce500.h | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/board/freescale/qemu-ppce500/qemu-ppce500.c b/board/freescale/qemu-ppce500/qemu-ppce500.c index 480776a21d..202b7f657d 100644 --- a/board/freescale/qemu-ppce500/qemu-ppce500.c +++ b/board/freescale/qemu-ppce500/qemu-ppce500.c @@ -168,9 +168,6 @@ int last_stage_init(void) if (prop && (len >= 8)) env_set_hex("qemu_kernel_addr", *prop); - /* Give the user a variable for the host fdt */ - env_set_hex("fdt_addr_r", (ulong)fdt); - return 0; } diff --git a/include/configs/qemu-ppce500.h b/include/configs/qemu-ppce500.h index 7c65e64d75..b2e1204e0f 100644 --- a/include/configs/qemu-ppce500.h +++ b/include/configs/qemu-ppce500.h @@ -106,6 +106,6 @@ extern unsigned long long get_phys_ccsrbar_addr_early(void); #define CONFIG_LOADADDR 1000000 #define CONFIG_BOOTCOMMAND \ - "test -n \"$qemu_kernel_addr\" && bootm $qemu_kernel_addr - $fdt_addr_r\0" + "test -n \"$qemu_kernel_addr\" && bootm $qemu_kernel_addr - $fdtcontroladdr\0" #endif /* __QEMU_PPCE500_H */ From 37c6ceb1b20494ebb8a18bb2dc59a94d02dd878e Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 25 Feb 2021 17:22:57 +0800 Subject: [PATCH 57/59] ppc: qemu: Drop fixed_sdram() This function is not called anywhere. Only fsl_ddr_sdram_size() is necessary [1] for QEMU. Drop it. [1] arch/powerpc/cpu/mpc85xx/cpu.c::dram_init() Signed-off-by: Bin Meng Reviewed-by: Priyanka Jain --- board/freescale/qemu-ppce500/qemu-ppce500.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/board/freescale/qemu-ppce500/qemu-ppce500.c b/board/freescale/qemu-ppce500/qemu-ppce500.c index 202b7f657d..7d711b8328 100644 --- a/board/freescale/qemu-ppce500/qemu-ppce500.c +++ b/board/freescale/qemu-ppce500/qemu-ppce500.c @@ -187,11 +187,6 @@ static uint64_t get_linear_ram_size(void) panic("Couldn't determine RAM size"); } -phys_size_t fixed_sdram(void) -{ - return get_linear_ram_size(); -} - phys_size_t fsl_ddr_sdram_size(void) { return get_linear_ram_size(); From 1d636a0cd581f80edbb0ce7ad087a198132c2d46 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 25 Feb 2021 17:22:58 +0800 Subject: [PATCH 58/59] ppc: qemu: Move board directory from board/freescale to board/emulation board/emulation is the place for other QEMU targets like x86, arm, riscv. Let's move the qemu-ppce500 board codes there. List me as a co-maintainer for this board. Signed-off-by: Bin Meng Reviewed-by: Priyanka Jain --- arch/powerpc/cpu/mpc85xx/Kconfig | 2 +- board/{freescale => emulation}/qemu-ppce500/Kconfig | 2 +- board/{freescale => emulation}/qemu-ppce500/MAINTAINERS | 3 ++- board/{freescale => emulation}/qemu-ppce500/Makefile | 0 board/{freescale => emulation}/qemu-ppce500/qemu-ppce500.c | 1 + 5 files changed, 5 insertions(+), 3 deletions(-) rename board/{freescale => emulation}/qemu-ppce500/Kconfig (86%) rename board/{freescale => emulation}/qemu-ppce500/MAINTAINERS (67%) rename board/{freescale => emulation}/qemu-ppce500/Makefile (100%) rename board/{freescale => emulation}/qemu-ppce500/qemu-ppce500.c (99%) diff --git a/arch/powerpc/cpu/mpc85xx/Kconfig b/arch/powerpc/cpu/mpc85xx/Kconfig index 1a4e0b93a6..124c22f58a 100644 --- a/arch/powerpc/cpu/mpc85xx/Kconfig +++ b/arch/powerpc/cpu/mpc85xx/Kconfig @@ -1415,6 +1415,7 @@ config SYS_FSL_LBC_CLK_DIV config FSL_VIA bool +source "board/emulation/qemu-ppce500/Kconfig" source "board/freescale/corenet_ds/Kconfig" source "board/freescale/mpc8541cds/Kconfig" source "board/freescale/mpc8548cds/Kconfig" @@ -1423,7 +1424,6 @@ source "board/freescale/mpc8568mds/Kconfig" source "board/freescale/p1010rdb/Kconfig" source "board/freescale/p1_p2_rdb_pc/Kconfig" source "board/freescale/p2041rdb/Kconfig" -source "board/freescale/qemu-ppce500/Kconfig" source "board/freescale/t102xrdb/Kconfig" source "board/freescale/t104xrdb/Kconfig" source "board/freescale/t208xqds/Kconfig" diff --git a/board/freescale/qemu-ppce500/Kconfig b/board/emulation/qemu-ppce500/Kconfig similarity index 86% rename from board/freescale/qemu-ppce500/Kconfig rename to board/emulation/qemu-ppce500/Kconfig index 236cd17f99..4312d986d8 100644 --- a/board/freescale/qemu-ppce500/Kconfig +++ b/board/emulation/qemu-ppce500/Kconfig @@ -4,7 +4,7 @@ config SYS_BOARD default "qemu-ppce500" config SYS_VENDOR - default "freescale" + default "emulation" config SYS_CONFIG_NAME default "qemu-ppce500" diff --git a/board/freescale/qemu-ppce500/MAINTAINERS b/board/emulation/qemu-ppce500/MAINTAINERS similarity index 67% rename from board/freescale/qemu-ppce500/MAINTAINERS rename to board/emulation/qemu-ppce500/MAINTAINERS index e70c095b65..7317983d6a 100644 --- a/board/freescale/qemu-ppce500/MAINTAINERS +++ b/board/emulation/qemu-ppce500/MAINTAINERS @@ -1,6 +1,7 @@ QEMU-PPCE500 BOARD M: Alexander Graf +M: Bin Meng S: Maintained -F: board/freescale/qemu-ppce500/ +F: board/emulation/qemu-ppce500/ F: include/configs/qemu-ppce500.h F: configs/qemu-ppce500_defconfig diff --git a/board/freescale/qemu-ppce500/Makefile b/board/emulation/qemu-ppce500/Makefile similarity index 100% rename from board/freescale/qemu-ppce500/Makefile rename to board/emulation/qemu-ppce500/Makefile diff --git a/board/freescale/qemu-ppce500/qemu-ppce500.c b/board/emulation/qemu-ppce500/qemu-ppce500.c similarity index 99% rename from board/freescale/qemu-ppce500/qemu-ppce500.c rename to board/emulation/qemu-ppce500/qemu-ppce500.c index 7d711b8328..daa103c564 100644 --- a/board/freescale/qemu-ppce500/qemu-ppce500.c +++ b/board/emulation/qemu-ppce500/qemu-ppce500.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0+ /* * Copyright 2007,2009-2014 Freescale Semiconductor, Inc. + * Copyright (C) 2021, Bin Meng */ #include From b75ca06836567a467b8b5a9ee8ce0a8efde45e08 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 25 Feb 2021 17:22:59 +0800 Subject: [PATCH 59/59] doc: Add a reST document for qemu-ppce500 Add a reST document to describe how to build and run U-Boot for the QEMU ppce500 machine. Signed-off-by: Bin Meng Reviewed-by: Simon Glass Reviewed-by: Priyanka Jain --- doc/board/emulation/index.rst | 1 + doc/board/emulation/qemu-ppce500.rst | 88 ++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+) create mode 100644 doc/board/emulation/qemu-ppce500.rst diff --git a/doc/board/emulation/index.rst b/doc/board/emulation/index.rst index a09ead1c35..be66b6bb67 100644 --- a/doc/board/emulation/index.rst +++ b/doc/board/emulation/index.rst @@ -8,6 +8,7 @@ Emulation qemu-arm qemu-mips + qemu-ppce500 qemu-riscv qemu-x86 qemu_capsule_update diff --git a/doc/board/emulation/qemu-ppce500.rst b/doc/board/emulation/qemu-ppce500.rst new file mode 100644 index 0000000000..0a5c86c61a --- /dev/null +++ b/doc/board/emulation/qemu-ppce500.rst @@ -0,0 +1,88 @@ +.. SPDX-License-Identifier: GPL-2.0+ +.. Copyright (C) 2021, Bin Meng + +QEMU PPC E500 +============= + +QEMU for PPC supports a special 'ppce500' machine designed for emulation and +virtualization purposes. This document describes how to run U-Boot under it. + +The QEMU ppce500 machine models a generic PowerPC E500 virtual machine with +support for the VirtIO standard networking device connected to the built-in +PCI host controller. Some common devices in the CCSBAR space are modeled, +including MPIC, 16550A UART devices, GPIO, I2C and PCI host controller with +MSI delivery to MPIC. It uses device-tree to pass configuration information +to guest software. + +Building U-Boot +--------------- +Set the CROSS_COMPILE environment variable as usual, and run:: + + $ make qemu-ppce500_defconfig + $ make + +Running U-Boot +-------------- +The minimal QEMU command line to get U-Boot up and running is:: + + $ qemu-system-ppc -nographic -machine ppce500 -bios u-boot + +You can also run U-Boot using 'qemu-system-ppc64':: + + $ qemu-system-ppc64 -nographic -machine ppce500 -bios u-boot + +The commands above create a target with 128 MiB memory by default. A freely +configurable amount of RAM can be created via the '-m' parameter. For example, +'-m 2G' creates 2 GiB memory for the target, and the memory node in the +embedded DTB created by QEMU reflects the new setting. + +Both qemu-system-ppc and qemu-system-ppc64 provide emulation for the following +32-bit PowerPC CPUs: + +* e500v2 +* e500mc + +Additionally qemu-system-ppc64 provides support for the following 64-bit CPUs: + +* e5500 +* e6500 + +The CPU type can be specified via the '-cpu' command line. If not specified, +it creates a machine with e500v2 core. The following example shows an e6500 +based machine creation:: + + $ qemu-system-ppc64 -nographic -machine ppce500 -cpu e6500 -bios u-boot + +When U-Boot boots, you will notice the following:: + + CPU: Unknown, Version: 0.0, (0x00000000) + Core: e6500, Version: 2.0, (0x80400020) + +This is because we only specified a core name to QEMU and it does not have a +meaningful SVR value which represents an actual SoC that integrates such core. +You can specify a real world SoC device that QEMU has built-in support but all +these SoCs are e500v2 based MPC85xx series, hence you cannot test anything +built for P4080 (e500mc), P5020 (e5500) and T2080 (e6500). + +By default a VirtIO standard PCI networking device is connected as an ethernet +interface at PCI address 0.1.0, but we can switch that to an e1000 NIC by:: + + $ qemu-system-ppc -nographic -machine ppce500 -bios u-boot \ + -nic tap,ifname=tap0,script=no,downscript=no,model=e1000 + +VirtIO BLK driver is also enabled to support booting from a disk image where +a kernel image is stored. Append the following to QEMU:: + + -drive file=disk.img,format=raw,id=disk0 -device virtio-blk-pci,drive=disk0 + +Pericom pt7c4338 RTC is supported so we can use the 'date' command:: + + => date + Date: 2021-02-18 (Thursday) Time: 15:33:20 + +Additionally, 'poweroff' command is supported to shut down the QEMU session:: + + => poweroff + poweroff ... + +These have been tested in QEMU 5.2.0.