From 09bd3d0b0a954f250bac61fee7e3c6d037914569 Mon Sep 17 00:00:00 2001 From: Samuel Mendoza-Jonas Date: Mon, 8 Aug 2022 21:46:03 +0930 Subject: [PATCH 01/15] net: NC-SI setup and handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the handling of NC-SI ethernet frames, and add a check at the start of net_loop() to configure NC-SI before starting other network commands. Signed-off-by: Samuel Mendoza-Jonas Signed-off-by: Joel Stanley Reviewed-by: Cédric Le Goater Reviewed-by: Ramon Fried --- drivers/net/phy/ncsi.c | 1 + drivers/net/phy/phy.c | 9 ++++++++- include/net.h | 2 +- include/phy.h | 2 ++ net/net.c | 26 +++++++++++++++++++++++++- 5 files changed, 37 insertions(+), 3 deletions(-) diff --git a/drivers/net/phy/ncsi.c b/drivers/net/phy/ncsi.c index bf1e832be9..bb7ecebed3 100644 --- a/drivers/net/phy/ncsi.c +++ b/drivers/net/phy/ncsi.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 0350afdd1b..9087663053 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -1026,7 +1026,7 @@ struct phy_device *phy_connect(struct mii_dev *bus, int addr, #endif #ifdef CONFIG_PHY_NCSI - if (!phydev) + if (!phydev && interface == PHY_INTERFACE_MODE_NCSI) phydev = phy_device_create(bus, 0, PHY_NCSI_ID, false); #endif @@ -1275,3 +1275,10 @@ int phy_clear_bits_mmd(struct phy_device *phydev, int devad, u32 regnum, u16 val return 0; } + +bool phy_interface_is_ncsi(void) +{ + struct eth_pdata *pdata = dev_get_plat(eth_get_dev()); + + return pdata->phy_interface == PHY_INTERFACE_MODE_NCSI; +} diff --git a/include/net.h b/include/net.h index c06b577808..32364ed0ce 100644 --- a/include/net.h +++ b/include/net.h @@ -560,7 +560,7 @@ extern int net_restart_wrap; /* Tried all network devices */ enum proto_t { BOOTP, RARP, ARP, TFTPGET, DHCP, PING, DNS, NFS, CDP, NETCONS, SNTP, - TFTPSRV, TFTPPUT, LINKLOCAL, FASTBOOT, WOL, UDP + TFTPSRV, TFTPPUT, LINKLOCAL, FASTBOOT, WOL, UDP, NCSI }; extern char net_boot_file_name[1024];/* Boot File name */ diff --git a/include/phy.h b/include/phy.h index ad2096ca84..0737c4e8f9 100644 --- a/include/phy.h +++ b/include/phy.h @@ -412,6 +412,8 @@ static inline bool phy_interface_is_sgmii(struct phy_device *phydev) phydev->interface <= PHY_INTERFACE_MODE_QSGMII; } +bool phy_interface_is_ncsi(void); + /* PHY UIDs for various PHYs that are referenced in external code */ #define PHY_UID_CS4340 0x13e51002 #define PHY_UID_CS4223 0x03e57003 diff --git a/net/net.c b/net/net.c index f9d11c08d2..6987a3817b 100644 --- a/net/net.c +++ b/net/net.c @@ -93,6 +93,7 @@ #include #include #include +#include #if defined(CONFIG_CMD_PCAP) #include #endif @@ -410,6 +411,16 @@ int net_loop(enum proto_t protocol) net_try_count = 1; debug_cond(DEBUG_INT_STATE, "--- net_loop Entry\n"); +#ifdef CONFIG_PHY_NCSI + if (phy_interface_is_ncsi() && protocol != NCSI && !ncsi_active()) { + printf("%s: configuring NCSI first\n", __func__); + if (net_loop(NCSI) < 0) + return ret; + eth_init_state_only(); + goto restart; + } +#endif + bootstage_mark_name(BOOTSTAGE_ID_ETH_START, "eth_start"); net_init(); if (eth_is_on_demand_init()) { @@ -526,6 +537,11 @@ restart: case WOL: wol_start(); break; +#endif +#if defined(CONFIG_PHY_NCSI) + case NCSI: + ncsi_probe_packages(); + break; #endif default: break; @@ -637,7 +653,7 @@ restart: env_set_hex("filesize", net_boot_file_size); env_set_hex("fileaddr", image_load_addr); } - if (protocol != NETCONS) + if (protocol != NETCONS && protocol != NCSI) eth_halt(); else eth_halt_state_only(); @@ -1321,6 +1337,11 @@ void net_process_received_packet(uchar *in_packet, int len) case PROT_WOL: wol_receive(ip, len); break; +#endif +#ifdef CONFIG_PHY_NCSI + case PROT_NCSI: + ncsi_receive(et, ip, len); + break; #endif } } @@ -1381,6 +1402,9 @@ common: #ifdef CONFIG_CMD_RARP case RARP: +#endif +#ifdef CONFIG_PHY_NCSI + case NCSI: #endif case BOOTP: case CDP: From 4b290d4a757caaf5efedc74ea3db9974b51f35f2 Mon Sep 17 00:00:00 2001 From: Samuel Mendoza-Jonas Date: Mon, 8 Aug 2022 21:46:04 +0930 Subject: [PATCH 02/15] cmd: Add ncsi command MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds an "ncsi" command to manually start NC-SI configuration. Signed-off-by: Samuel Mendoza-Jonas Signed-off-by: Joel Stanley Reviewed-by: Cédric Le Goater --- cmd/Kconfig | 8 ++++++++ cmd/net.c | 22 ++++++++++++++++++++++ net/net.c | 1 + 3 files changed, 31 insertions(+) diff --git a/cmd/Kconfig b/cmd/Kconfig index 16030e34a1..41cf1d46fb 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -1842,6 +1842,14 @@ config CMD_LINK_LOCAL help Acquire a network IP address using the link-local protocol +config CMD_NCSI + bool "ncsi" + depends on PHY_NCSI + help + Manually configure the attached NIC via NC-SI. + Normally this happens automatically before other network + operations. + endif config CMD_ETHSW diff --git a/cmd/net.c b/cmd/net.c index 46f8c87b69..addcad3ac1 100644 --- a/cmd/net.c +++ b/cmd/net.c @@ -16,6 +16,7 @@ #include #include #include +#include static int netboot_common(enum proto_t, struct cmd_tbl *, int, char * const []); @@ -566,3 +567,24 @@ U_BOOT_CMD( "list - list available devices\n" ); #endif // CONFIG_DM_ETH + +#if defined(CONFIG_CMD_NCSI) +static int do_ncsi(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[]) +{ + if (!phy_interface_is_ncsi() || !ncsi_active()) { + printf("Device not configured for NC-SI\n"); + return CMD_RET_FAILURE; + } + + if (net_loop(NCSI) < 0) + return CMD_RET_FAILURE; + + return CMD_RET_SUCCESS; +} + +U_BOOT_CMD( + ncsi, 1, 1, do_ncsi, + "Configure attached NIC via NC-SI", + "" +); +#endif /* CONFIG_CMD_NCSI */ diff --git a/net/net.c b/net/net.c index 6987a3817b..b27b021d07 100644 --- a/net/net.c +++ b/net/net.c @@ -434,6 +434,7 @@ int net_loop(enum proto_t protocol) } else { eth_init_state_only(); } + restart: #ifdef CONFIG_USB_KEYBOARD net_busy_flag = 0; From 3b400e84baa2c4f5e90b7291c6658d821199806c Mon Sep 17 00:00:00 2001 From: Samuel Mendoza-Jonas Date: Mon, 8 Aug 2022 21:46:05 +0930 Subject: [PATCH 03/15] net/ftgmac100: Add NC-SI mode support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update the ftgmac100 driver to support NC-SI instead of an mdio phy where available. This is a common setup for Aspeed AST2x00 platforms. NC-SI mode is determined from the device-tree if either phy-mode sets it or the use-ncsi property exists. If set then normal mdio setup is skipped in favour of the NC-SI phy. Signed-off-by: Samuel Mendoza-Jonas Signed-off-by: Joel Stanley Reviewed-by: Cédric Le Goater Reviewed-by: Ramon Fried --- drivers/net/ftgmac100.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/net/ftgmac100.c b/drivers/net/ftgmac100.c index 74261d14e5..a50cde338a 100644 --- a/drivers/net/ftgmac100.c +++ b/drivers/net/ftgmac100.c @@ -188,7 +188,7 @@ static int ftgmac100_phy_adjust_link(struct ftgmac100_data *priv) struct phy_device *phydev = priv->phydev; u32 maccr; - if (!phydev->link) { + if (!phydev->link && priv->phy_mode != PHY_INTERFACE_MODE_NCSI) { dev_err(phydev->dev, "No link\n"); return -EREMOTEIO; } @@ -228,7 +228,8 @@ static int ftgmac100_phy_init(struct udevice *dev) if (!phydev) return -ENODEV; - phydev->supported &= PHY_GBIT_FEATURES; + if (priv->phy_mode != PHY_INTERFACE_MODE_NCSI) + phydev->supported &= PHY_GBIT_FEATURES; if (priv->max_speed) { ret = phy_set_supported(phydev, priv->max_speed); if (ret) @@ -308,7 +309,8 @@ static void ftgmac100_stop(struct udevice *dev) writel(0, &ftgmac100->maccr); - phy_shutdown(priv->phydev); + if (priv->phy_mode != PHY_INTERFACE_MODE_NCSI) + phy_shutdown(priv->phydev); } static int ftgmac100_start(struct udevice *dev) @@ -580,6 +582,9 @@ static int ftgmac100_probe(struct udevice *dev) priv->max_speed = pdata->max_speed; priv->phy_addr = 0; + if (dev_read_bool(dev, "use-ncsi")) + priv->phy_mode = PHY_INTERFACE_MODE_NCSI; + #ifdef CONFIG_PHY_ADDR priv->phy_addr = CONFIG_PHY_ADDR; #endif @@ -592,7 +597,8 @@ static int ftgmac100_probe(struct udevice *dev) * If DM MDIO is enabled, the MDIO bus will be initialized later in * dm_eth_phy_connect */ - if (!IS_ENABLED(CONFIG_DM_MDIO)) { + if (priv->phy_mode != PHY_INTERFACE_MODE_NCSI && + !IS_ENABLED(CONFIG_DM_MDIO)) { ret = ftgmac100_mdio_init(dev); if (ret) { dev_err(dev, "Failed to initialize mdiobus: %d\n", ret); From e8f58df17861c6175797815d44f48eee8a527ec6 Mon Sep 17 00:00:00 2001 From: Joel Stanley Date: Mon, 8 Aug 2022 21:46:06 +0930 Subject: [PATCH 04/15] config/aspeed: Enable NC-SI support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Aspeed BMCs are commonly used with NC-SI. A system indicates the driver should configure the link over NC-SI using the device tree. Add it to the defconfig so we get compile coverage of the driver, even if the EVBs do not normally use it. Signed-off-by: Joel Stanley Reviewed-by: Ramon Fried Reviewed-by: Cédric Le Goater --- configs/evb-ast2500_defconfig | 2 ++ configs/evb-ast2600_defconfig | 2 ++ 2 files changed, 4 insertions(+) diff --git a/configs/evb-ast2500_defconfig b/configs/evb-ast2500_defconfig index 3061cbec41..500c85b8d5 100644 --- a/configs/evb-ast2500_defconfig +++ b/configs/evb-ast2500_defconfig @@ -28,6 +28,7 @@ CONFIG_CMD_DHCP=y CONFIG_BOOTP_BOOTFILESIZE=y CONFIG_CMD_MII=y CONFIG_CMD_PING=y +CONFIG_CMD_NCSI=y CONFIG_ENV_OVERWRITE=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_NET_RANDOM_ETHADDR=y @@ -50,6 +51,7 @@ CONFIG_SPI_FLASH_SST=y CONFIG_SPI_FLASH_WINBOND=y # CONFIG_SPI_FLASH_USE_4K_SECTORS is not set CONFIG_PHY_REALTEK=y +CONFIG_PHY_NCSI=y CONFIG_FTGMAC100=y CONFIG_PHY=y CONFIG_PINCTRL=y diff --git a/configs/evb-ast2600_defconfig b/configs/evb-ast2600_defconfig index 1981f895d6..a80513f81b 100644 --- a/configs/evb-ast2600_defconfig +++ b/configs/evb-ast2600_defconfig @@ -66,6 +66,7 @@ CONFIG_CMD_DHCP=y CONFIG_BOOTP_BOOTFILESIZE=y CONFIG_CMD_MII=y CONFIG_CMD_PING=y +CONFIG_CMD_NCSI=y CONFIG_CMD_EXT4=y CONFIG_DOS_PARTITION=y # CONFIG_SPL_DOS_PARTITION is not set @@ -98,6 +99,7 @@ CONFIG_SPI_FLASH_SST=y CONFIG_SPI_FLASH_WINBOND=y # CONFIG_SPI_FLASH_USE_4K_SECTORS is not set CONFIG_PHY_REALTEK=y +CONFIG_PHY_NCSI=y CONFIG_DM_MDIO=y CONFIG_FTGMAC100=y CONFIG_ASPEED_MDIO=y From 71858454fedd1e9d975d43e82f2fbaf2640460b0 Mon Sep 17 00:00:00 2001 From: Alice Guo Date: Sun, 9 Oct 2022 11:19:22 +0800 Subject: [PATCH 05/15] gpio: adp5585: add gpio driver for ADP5585 I/O Expander Controller Add gpio driver for ADP5585 I/O Expander Controller. The ADP5585 is a 10 input/output port expander and can be used to increase the number of I/Os available to a processor. Signed-off-by: Alice Guo --- drivers/gpio/Kconfig | 6 + drivers/gpio/Makefile | 1 + drivers/gpio/adp5585_gpio.c | 238 ++++++++++++++++++++++++++++++++++++ 3 files changed, 245 insertions(+) create mode 100644 drivers/gpio/adp5585_gpio.c diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 2a60478b47..220e2cb162 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -611,4 +611,10 @@ config FTGPIO010 help Support for GPIOs on Faraday Technology's FTGPIO010 controller. +config ADP5585_GPIO + bool "ADP5585 GPIO driver" + depends on DM_GPIO && DM_I2C + help + Support ADP5585 GPIO expander. + endif diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index eee7908871..7235714fcc 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -76,3 +76,4 @@ obj-$(CONFIG_ZYNQMP_GPIO_MODEPIN) += zynqmp_gpio_modepin.o obj-$(CONFIG_SLG7XL45106_I2C_GPO) += gpio_slg7xl45106.o obj-$(CONFIG_$(SPL_TPL_)TURRIS_OMNIA_MCU) += turris_omnia_mcu.o obj-$(CONFIG_FTGPIO010) += ftgpio010.o +obj-$(CONFIG_ADP5585_GPIO) += adp5585_gpio.o diff --git a/drivers/gpio/adp5585_gpio.c b/drivers/gpio/adp5585_gpio.c new file mode 100644 index 0000000000..ea0cb75459 --- /dev/null +++ b/drivers/gpio/adp5585_gpio.c @@ -0,0 +1,238 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2022 NXP + * + * ADP5585 I/O Expander Controller + * + * Author: Alice Guo + */ + +#include +#include +#include +#include + +#define ADP5585_ID 0x00 +#define ADP5585_INT_STATUS 0x01 +#define ADP5585_STATUS 0x02 +#define ADP5585_FIFO_1 0x03 +#define ADP5585_FIFO_2 0x04 +#define ADP5585_FIFO_3 0x05 +#define ADP5585_FIFO_4 0x06 +#define ADP5585_FIFO_5 0x07 +#define ADP5585_FIFO_6 0x08 +#define ADP5585_FIFO_7 0x09 +#define ADP5585_FIFO_8 0x0A +#define ADP5585_FIFO_9 0x0B +#define ADP5585_FIFO_10 0x0C +#define ADP5585_FIFO_11 0x0D +#define ADP5585_FIFO_12 0x0E +#define ADP5585_FIFO_13 0x0F +#define ADP5585_FIFO_14 0x10 +#define ADP5585_FIFO_15 0x11 +#define ADP5585_FIFO_16 0x12 +#define ADP5585_GPI_INT_STAT_A 0x13 +#define ADP5585_GPI_INT_STAT_B 0x14 +#define ADP5585_GPI_STATUS_A 0x15 +#define ADP5585_GPI_STATUS_B 0x16 +#define ADP5585_RPULL_CONFIG_A 0x17 +#define ADP5585_RPULL_CONFIG_B 0x18 +#define ADP5585_RPULL_CONFIG_C 0x19 +#define ADP5585_RPULL_CONFIG_D 0x1A +#define ADP5585_GPI_INT_LEVEL_A 0x1B +#define ADP5585_GPI_INT_LEVEL_B 0x1C +#define ADP5585_GPI_EVENT_EN_A 0x1D +#define ADP5585_GPI_EVENT_EN_B 0x1E +#define ADP5585_GPI_INTERRUPT_EN_A 0x1F +#define ADP5585_GPI_INTERRUPT_EN_B 0x20 +#define ADP5585_DEBOUNCE_DIS_A 0x21 +#define ADP5585_DEBOUNCE_DIS_B 0x22 +#define ADP5585_GPO_DATA_OUT_A 0x23 +#define ADP5585_GPO_DATA_OUT_B 0x24 +#define ADP5585_GPO_OUT_MODE_A 0x25 +#define ADP5585_GPO_OUT_MODE_B 0x26 +#define ADP5585_GPIO_DIRECTION_A 0x27 +#define ADP5585_GPIO_DIRECTION_B 0x28 +#define ADP5585_RESET1_EVENT_A 0x29 +#define ADP5585_RESET1_EVENT_B 0x2A +#define ADP5585_RESET1_EVENT_C 0x2B +#define ADP5585_RESET2_EVENT_A 0x2C +#define ADP5585_RESET2_EVENT_B 0x2D +#define ADP5585_RESET_CFG 0x2E +#define ADP5585_PWM_OFFT_LOW 0x2F +#define ADP5585_PWM_OFFT_HIGH 0x30 +#define ADP5585_PWM_ONT_LOW 0x31 +#define ADP5585_PWM_ONT_HIGH 0x32 +#define ADP5585_PWM_CFG 0x33 +#define ADP5585_LOGIC_CFG 0x34 +#define ADP5585_LOGIC_FF_CFG 0x35 +#define ADP5585_LOGIC_INT_EVENT_EN 0x36 +#define ADP5585_POLL_PTIME_CFG 0x37 +#define ADP5585_PIN_CONFIG_A 0x38 +#define ADP5585_PIN_CONFIG_B 0x39 +#define ADP5585_PIN_CONFIG_D 0x3A +#define ADP5585_GENERAL_CFG 0x3B +#define ADP5585_INT_EN 0x3C + +#define ADP5585_MAXGPIO 10 +#define ADP5585_BANK(offs) ((offs) > 4) +#define ADP5585_BIT(offs) ((offs) > 4 ? \ + 1u << ((offs) - 5) : 1u << (offs)) + +struct adp5585_plat { + fdt_addr_t addr; + u8 id; + u8 dat_out[2]; + u8 dir[2]; +}; + +static int adp5585_direction_input(struct udevice *dev, unsigned int offset) +{ + int ret; + unsigned int bank; + struct adp5585_plat *plat = dev_get_plat(dev); + + bank = ADP5585_BANK(offset); + + plat->dir[bank] &= ~ADP5585_BIT(offset); + ret = dm_i2c_write(dev, ADP5585_GPIO_DIRECTION_A + bank, &plat->dir[bank], 1); + + return ret; +} + +static int adp5585_direction_output(struct udevice *dev, unsigned int offset, + int value) +{ + int ret; + unsigned int bank, bit; + struct adp5585_plat *plat = dev_get_plat(dev); + + bank = ADP5585_BANK(offset); + bit = ADP5585_BIT(offset); + + plat->dir[bank] |= bit; + + if (value) + plat->dat_out[bank] |= bit; + else + plat->dat_out[bank] &= ~bit; + + ret = dm_i2c_write(dev, ADP5585_GPO_DATA_OUT_A + bank, &plat->dat_out[bank], 1); + ret |= dm_i2c_write(dev, ADP5585_GPIO_DIRECTION_A + bank, &plat->dir[bank], 1); + + return ret; +} + +static int adp5585_get_value(struct udevice *dev, unsigned int offset) +{ + struct adp5585_plat *plat = dev_get_plat(dev); + unsigned int bank = ADP5585_BANK(offset); + unsigned int bit = ADP5585_BIT(offset); + u8 val; + + if (plat->dir[bank] & bit) + val = plat->dat_out[bank]; + else + dm_i2c_read(dev, ADP5585_GPI_STATUS_A + bank, &val, 1); + + return !!(val & bit); +} + +static int adp5585_set_value(struct udevice *dev, unsigned int offset, int value) +{ + int ret; + unsigned int bank, bit; + struct adp5585_plat *plat = dev_get_plat(dev); + + bank = ADP5585_BANK(offset); + bit = ADP5585_BIT(offset); + + if (value) + plat->dat_out[bank] |= bit; + else + plat->dat_out[bank] &= ~bit; + + ret = dm_i2c_write(dev, ADP5585_GPO_DATA_OUT_A + bank, &plat->dat_out[bank], 1); + + return ret; +} + +static int adp5585_get_function(struct udevice *dev, unsigned int offset) +{ + unsigned int bank, bit, dir; + struct adp5585_plat *plat = dev_get_plat(dev); + + bank = ADP5585_BANK(offset); + bit = ADP5585_BIT(offset); + dir = plat->dir[bank] & bit; + + if (!dir) + return GPIOF_INPUT; + else + return GPIOF_OUTPUT; +} + +static int adp5585_xlate(struct udevice *dev, struct gpio_desc *desc, + struct ofnode_phandle_args *args) +{ + desc->offset = args->args[0]; + desc->flags = args->args[1] & GPIO_ACTIVE_LOW ? GPIOD_ACTIVE_LOW : 0; + + return 0; +} + +static const struct dm_gpio_ops adp5585_ops = { + .direction_input = adp5585_direction_input, + .direction_output = adp5585_direction_output, + .get_value = adp5585_get_value, + .set_value = adp5585_set_value, + .get_function = adp5585_get_function, + .xlate = adp5585_xlate, +}; + +static int adp5585_probe(struct udevice *dev) +{ + struct adp5585_plat *plat = dev_get_plat(dev); + struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); + int ret; + + if (!plat) + return 0; + + plat->addr = dev_read_addr(dev); + if (plat->addr == FDT_ADDR_T_NONE) + return -EINVAL; + + ret = dm_i2c_read(dev, ADP5585_ID, &plat->id, 1); + if (ret < 0) + return ret; + + uc_priv->gpio_count = ADP5585_MAXGPIO; + uc_priv->bank_name = "adp5585-gpio"; + + for (int i = 0; i < 2; i++) { + ret = dm_i2c_read(dev, ADP5585_GPO_DATA_OUT_A + i, &plat->dat_out[i], 1); + if (ret) + return ret; + + ret = dm_i2c_read(dev, ADP5585_GPIO_DIRECTION_A + i, &plat->dir[i], 1); + if (ret) + return ret; + } + + return 0; +} + +static const struct udevice_id adp5585_ids[] = { + { .compatible = "adp5585" }, + { } +}; + +U_BOOT_DRIVER(adp5585) = { + .name = "adp5585", + .id = UCLASS_GPIO, + .of_match = adp5585_ids, + .probe = adp5585_probe, + .ops = &adp5585_ops, + .plat_auto = sizeof(struct adp5585_plat), +}; From 163fb376695661620f13839ec35d860e7e7ff504 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Mon, 10 Oct 2022 18:01:20 +0100 Subject: [PATCH 06/15] qfw: store loaded file size in environment variable At the moment the QEMU firmware command just prints the size of the loaded binaries on the console. To go with all the other load methods, and many boot scripts' expectations, also store the size of the file loaded last in the environment variable "filesize". We first put the kernel size in there, but overwrite this with the initrd size, should we have one, because this is probably the more prominent user of $filesize (in the booti or bootz command). Signed-off-by: Andre Przywara --- cmd/qfw.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cmd/qfw.c b/cmd/qfw.c index ccbc967ca9..c61001b771 100644 --- a/cmd/qfw.c +++ b/cmd/qfw.c @@ -40,6 +40,7 @@ static int qemu_fwcfg_cmd_setup_kernel(void *load_addr, void *initrd_addr) qfw_read_entry(qfw_dev, FW_CFG_KERNEL_DATA, le32_to_cpu(kernel_size), data_addr); data_addr += le32_to_cpu(kernel_size); + env_set_hex("filesize", le32_to_cpu(kernel_size)); data_addr = initrd_addr; qfw_read_entry(qfw_dev, FW_CFG_INITRD_SIZE, 4, &initrd_size); @@ -49,6 +50,7 @@ static int qemu_fwcfg_cmd_setup_kernel(void *load_addr, void *initrd_addr) qfw_read_entry(qfw_dev, FW_CFG_INITRD_DATA, le32_to_cpu(initrd_size), data_addr); data_addr += le32_to_cpu(initrd_size); + env_set_hex("filesize", le32_to_cpu(initrd_size)); } qfw_read_entry(qfw_dev, FW_CFG_CMDLINE_SIZE, 4, &cmdline_size); From 2f6c45eb6870989372d62afa365380aa44448bf3 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Mon, 10 Oct 2022 18:01:21 +0100 Subject: [PATCH 07/15] qfw: return failure when no kernel could be loaded When we try to load a kernel via the QEMU firmware device, we currently "return -1;" if no kernel was specified on the QEMU command line. This leads to the usage output, which is confusing (since nothing on the command line was really wrong), but also somewhat hides the actual error message. Return CMD_RET_FAILURE (1), as it's a proper error, and make the message more clear that this is not only a "warning". This helps to call this command in boot scripts, and to gracefully continue if this doesn't work. Signed-off-by: Andre Przywara --- cmd/qfw.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/qfw.c b/cmd/qfw.c index c61001b771..95ddc4b79e 100644 --- a/cmd/qfw.c +++ b/cmd/qfw.c @@ -26,8 +26,8 @@ static int qemu_fwcfg_cmd_setup_kernel(void *load_addr, void *initrd_addr) qfw_read_entry(qfw_dev, FW_CFG_KERNEL_SIZE, 4, &kernel_size); if (kernel_size == 0) { - printf("warning: no kernel available\n"); - return -1; + printf("fatal: no kernel available\n"); + return CMD_RET_FAILURE; } data_addr = load_addr; From d6d8720c3f273f412ca1e2f6436b1ae11904161d Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Mon, 10 Oct 2022 18:01:22 +0100 Subject: [PATCH 08/15] qemu: Try to automatically boot from the QEMU firmware device (qfw) At the moment the QEMU boot sequence tries various (storage) devices when trying to find a payload to boot. To simplify starting a specific kernel and initrd, there is also the qfw command, which can use the files specified on the QEMU command line, via the -kernel and -initrd options. Add this command to the list of boot options to try. Since users specifying those options on the command line probably explicitly want to run them, let's place the new command first. Without those options, the qfw command will just gracefully fail, and we continue with the existing order. This allows auto-booting of specific kernels in QEMU, for instance in CI systems. Signed-off-by: Andre Przywara --- include/configs/qemu-arm.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/include/configs/qemu-arm.h b/include/configs/qemu-arm.h index dd2faebbbb..535762ecb2 100644 --- a/include/configs/qemu-arm.h +++ b/include/configs/qemu-arm.h @@ -21,6 +21,17 @@ EFI_GUID(0x058b7d83, 0x50d5, 0x4c47, 0xa1, 0x95, \ 0x60, 0xd8, 0x6a, 0xd3, 0x41, 0xc4) +/* Try files from QEMU's -kernel/-initrd, through the QEMU firmware device. */ +#define BOOTENV_DEV_QFW(devtypeu, devtypel, instance) \ + "bootcmd_qfw= " \ + "if qfw load $kernel_addr_r $ramdisk_addr_r; then " \ + " booti $kernel_addr_r $ramdisk_addr_r:$filesize $fdtcontroladdr; " \ + " if test $? -eq 1; then " \ + " bootz $kernel_addr_r $ramdisk_addr_r:$filesize $fdtcontroladdr; " \ + " fi ; " \ + "fi\0" +#define BOOTENV_DEV_NAME_QFW(devtypeu, devtypel, instance) "qfw " + /* For timer, QEMU emulates an ARMv7/ARMv8 architected timer */ /* Environment options */ @@ -56,6 +67,7 @@ #endif #define BOOT_TARGET_DEVICES(func) \ + func(QFW, qfw, na) \ BOOT_TARGET_USB(func) \ BOOT_TARGET_SCSI(func) \ BOOT_TARGET_VIRTIO(func) \ From 5b2f49c033d6b6d48fff203d6f154acc8153320a Mon Sep 17 00:00:00 2001 From: Michal Suchanek Date: Mon, 10 Oct 2022 20:29:39 +0200 Subject: [PATCH 09/15] sandbox: Initialize sysreset before relocation Without this the early sysreset code cannot be tested. Signed-off-by: Michal Suchanek Reviewed-by: Simon Glass --- arch/sandbox/dts/sandbox.dtsi | 1 + arch/sandbox/dts/test.dts | 2 ++ 2 files changed, 3 insertions(+) diff --git a/arch/sandbox/dts/sandbox.dtsi b/arch/sandbox/dts/sandbox.dtsi index d2db1ea522..7387b54bbd 100644 --- a/arch/sandbox/dts/sandbox.dtsi +++ b/arch/sandbox/dts/sandbox.dtsi @@ -239,6 +239,7 @@ reset@1 { compatible = "sandbox,reset"; + u-boot,dm-pre-proper; }; rng { diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts index b853e13f92..70e27cd6a8 100644 --- a/arch/sandbox/dts/test.dts +++ b/arch/sandbox/dts/test.dts @@ -1125,10 +1125,12 @@ reset@0 { compatible = "sandbox,warm-reset"; + u-boot,dm-pre-proper; }; reset@1 { compatible = "sandbox,reset"; + u-boot,dm-pre-proper; }; resetc: reset-ctl { From 9259bd1735990ca07473ceb03ca667d7d0caddfc Mon Sep 17 00:00:00 2001 From: Michal Suchanek Date: Mon, 10 Oct 2022 20:29:40 +0200 Subject: [PATCH 10/15] common: board_f: Print information for all sysresets Boards can have multiple sysresets, iterate all when printing sysreset info. Fixes: 23471aed5c ("board_f: Add reset status printing") Signed-off-by: Michal Suchanek Reviewed-by: Simon Glass --- common/board_f.c | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/common/board_f.c b/common/board_f.c index 5f1711181c..4355d1c82d 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -146,20 +146,27 @@ static int print_resetinfo(void) { struct udevice *dev; char status[256]; + bool status_printed = false; int ret; - ret = uclass_first_device_err(UCLASS_SYSRESET, &dev); - if (ret) { - debug("%s: No sysreset device found (error: %d)\n", - __func__, ret); - /* Not all boards have sysreset drivers available during early - * boot, so don't fail if one can't be found. - */ - return 0; - } + /* Not all boards have sysreset drivers available during early + * boot, so don't fail if one can't be found. + */ + for (ret = uclass_first_device_check(UCLASS_SYSRESET, &dev); dev; + ret = uclass_next_device_check(&dev)) { + if (ret) { + debug("%s: %s sysreset device (error: %d)\n", + __func__, dev->name, ret); + continue; + } - if (!sysreset_get_status(dev, status, sizeof(status))) - printf("%s", status); + if (!sysreset_get_status(dev, status, sizeof(status))) { + printf("%s%s", status_printed ? " " : "", status); + status_printed = true; + } + } + if (status_printed) + printf("\n"); return 0; } From 65e8b64d237a8a6e9062568412fae03c1673885c Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Wed, 12 Oct 2022 18:59:27 +0200 Subject: [PATCH 11/15] board: gateworks: gw_ventana: fix building with GCC 12.2 Building with GCC 12.2 results in an error board/gateworks/gw_ventana/gw_ventana.c:636:68: error: the comparison will always evaluate as 'true' for the address of 'pwm_padmux' will never be NULL [-Werror=address] 636 | } else if (hwconfig_subarg_cmp(arg, "mode", "pwm") && | ^~ Remove the superfluous check. Signed-off-by: Heinrich Schuchardt Reviewed-By: Tim Harvey Reviewed-by: Fabio Estevam --- board/gateworks/gw_ventana/gw_ventana.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/board/gateworks/gw_ventana/gw_ventana.c b/board/gateworks/gw_ventana/gw_ventana.c index 99f52b9953..78d317d864 100644 --- a/board/gateworks/gw_ventana/gw_ventana.c +++ b/board/gateworks/gw_ventana/gw_ventana.c @@ -633,8 +633,7 @@ void setup_board_gpio(int board, struct ventana_board_info *info) ctrl); gpio_requestf(cfg->gpio_param, "dio%d", i); gpio_direction_input(cfg->gpio_param); - } else if (hwconfig_subarg_cmp(arg, "mode", "pwm") && - cfg->pwm_padmux) { + } else if (hwconfig_subarg_cmp(arg, "mode", "pwm")) { if (!cfg->pwm_param) { printf("DIO%d: Error: pwm config invalid\n", i); From 64a11fb8c9a1a5ae385043e5f5e197fa213cc702 Mon Sep 17 00:00:00 2001 From: Mattijs Korpershoek Date: Thu, 13 Oct 2022 14:25:59 +0200 Subject: [PATCH 12/15] cmd: bcb: select user(0) hwpart in __bcb_load() For some blk operations, it's possible that a different hw partition gets selected via blk_dselect_hwpart(). In that case, only the region of the device covered by that partition is accessible. This breaks "bcb load" which attempts to read the gpt and assumes it's on the user(0) hw partition: => bcb load 2 misc GUID Partition Table Header signature is wrong: 0xDE7B17AD07D9E5D6 != 0x5452415020494645 find_valid_gpt: *** ERROR: Invalid GPT *** GUID Partition Table Header signature is wrong: 0x0 != 0x5452415020494645 find_valid_gpt: *** ERROR: Invalid Backup GPT *** Error: mmc 2:misc read failed (-2) Add a fail-safe in __bcb_load() to ensure we will always read from the user(0) hwpartition. This fixes the following fastboot sequence: $ fastboot erase mmc2boot1 # switch to hwpart1 $ fastboot reboot bootloader # switch to hwpart0, then reads GPT Signed-off-by: Mattijs Korpershoek Reviewed-by: Sean Anderson --- cmd/bcb.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/cmd/bcb.c b/cmd/bcb.c index 1622a90c97..02d0c70d87 100644 --- a/cmd/bcb.c +++ b/cmd/bcb.c @@ -14,6 +14,7 @@ #include #include #include +#include enum bcb_cmd { BCB_CMD_LOAD, @@ -128,6 +129,16 @@ static int __bcb_load(int devnum, const char *partp) goto err_read_fail; } + /* + * always select the USER mmc hwpart in case another + * blk operation selected a different hwpart + */ + ret = blk_dselect_hwpart(desc, 0); + if (IS_ERR_VALUE(ret)) { + ret = -ENODEV; + goto err_read_fail; + } + part = simple_strtoul(partp, &endp, 0); if (*endp == '\0') { ret = part_get_info(desc, part, &info); From 59c585e9c6ca1d0ac08cf79b21a09f8b1eb424d0 Mon Sep 17 00:00:00 2001 From: Michal Suchanek Date: Sat, 15 Oct 2022 11:30:37 +0200 Subject: [PATCH 13/15] test: Fix typo in test name For other sandbox tests the printed test name corresponds to the configuration except for this one. Signed-off-by: Michal Suchanek Reviewed-by: Simon Glass Reviewed-by: Simon Glass --- test/run | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/run b/test/run index 810b47e08d..c4ab046ce8 100755 --- a/test/run +++ b/test/run @@ -51,9 +51,9 @@ echo "${prompt}" run_test "sandbox_spl" ./test/py/test.py --bd sandbox_spl --build ${para} \ -k 'test_ofplatdata or test_handoff or test_spl' -# Run the sane tests with sandbox_noinst (i.e. without OF_PLATDATA_INST) +# Run the same tests with sandbox_noinst (i.e. without OF_PLATDATA_INST) echo "${prompt}" -run_test "sandbox_spl" ./test/py/test.py --bd sandbox_noinst --build ${para} \ +run_test "sandbox_noinst" ./test/py/test.py --bd sandbox_noinst --build ${para} \ -k 'test_ofplatdata or test_handoff or test_spl' if [ -z "$tools_only" ]; then From 601d4e1af65cafcc5490589cc775b882996f6f87 Mon Sep 17 00:00:00 2001 From: Mattijs Korpershoek Date: Mon, 17 Oct 2022 09:35:04 +0200 Subject: [PATCH 14/15] blk: fix a couple of trivial documentation typos In some cases, the param variable is wrong, and in other cases we have undocumented arguments. Fix the docs. Signed-off-by: Mattijs Korpershoek Reviewed-by: Simon Glass --- include/blk.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/include/blk.h b/include/blk.h index 8806c382d4..d3ab9a10b9 100644 --- a/include/blk.h +++ b/include/blk.h @@ -119,7 +119,7 @@ int blkcache_init(void); * @param start - starting block number * @param blkcnt - number of blocks to read * @param blksz - size in bytes of each block - * @param buf - buffer to contain cached data + * @param buffer - buffer to contain cached data * * Return: - 1 if block returned from cache, 0 otherwise. */ @@ -136,7 +136,7 @@ int blkcache_read(int iftype, int dev, * @param start - starting block number * @param blkcnt - number of blocks available * @param blksz - size in bytes of each block - * @param buf - buffer containing data to cache + * @param buffer - buffer containing data to cache * */ void blkcache_fill(int iftype, int dev, @@ -250,7 +250,7 @@ struct blk_ops { * The MMC standard provides for two boot partitions (numbered 1 and 2), * rpmb (3), and up to 4 addition general-purpose partitions (4-7). * - * @desc: Block device to update + * @dev: Block device to update * @hwpart: Hardware partition number to select. 0 means the raw * device, 1 is the first partition, 2 is the second, etc. * @return 0 if OK, -ve on error @@ -642,6 +642,7 @@ int blk_print_part_devnum(enum uclass_id uclass_id, int devnum); * * @uclass_id: Block device type * @devnum: Device number + * @start: Start block number to read (0=first) * @blkcnt: Number of blocks to read * @buffer: Address to write data to * Return: number of blocks read, or -ve error number on error @@ -654,6 +655,7 @@ ulong blk_read_devnum(enum uclass_id uclass_id, int devnum, lbaint_t start, * * @uclass_id: Block device type * @devnum: Device number + * @start: Start block number to write (0=first) * @blkcnt: Number of blocks to write * @buffer: Address to read data from * Return: number of blocks written, or -ve error number on error From 4344c113c4fc1e48be58dbd55ac8922edb0d5c79 Mon Sep 17 00:00:00 2001 From: Holger Brunck Date: Mon, 17 Oct 2022 11:45:21 +0200 Subject: [PATCH 15/15] board/km: drop CONFIG_KM_ROOTFSSIZE This unused nowadays and can be dropped. Signed-off-by: Holger Brunck --- include/configs/km/km-powerpc.h | 3 --- include/configs/kmcent2.h | 3 --- scripts/config_whitelist.txt | 1 - 3 files changed, 7 deletions(-) diff --git a/include/configs/km/km-powerpc.h b/include/configs/km/km-powerpc.h index 20a36fbe11..424caa0df9 100644 --- a/include/configs/km/km-powerpc.h +++ b/include/configs/km/km-powerpc.h @@ -21,11 +21,8 @@ * @CONFIG_KM_RESERVED_PRAM: reserved pram for special purpose * @CONFIG_KM_PHRAM: address for /var * @CONFIG_KM_PNVRAM: address for PNVRAM (for the application) - * @CONFIG_KM_ROOTFSSIZE: address for rootfilesystem in RAM */ -/* size of rootfs in RAM */ -#define CONFIG_KM_ROOTFSSIZE 0x0 /* set the default PRAM value to at least PNVRAM + PHRAM when pram env variable * is not valid yet, which is the case for when u-boot copies itself to RAM */ #define CONFIG_PRAM ((CONFIG_KM_PNVRAM + CONFIG_KM_PHRAM)>>10) diff --git a/include/configs/kmcent2.h b/include/configs/kmcent2.h index 0d470c4b4a..1b1900179e 100644 --- a/include/configs/kmcent2.h +++ b/include/configs/kmcent2.h @@ -179,11 +179,8 @@ * @CONFIG_KM_RESERVED_PRAM: reserved pram for special purpose * @CONFIG_KM_PHRAM: address for /var * @CONFIG_KM_PNVRAM: address for PNVRAM (for the application) - * @CONFIG_KM_ROOTFSSIZE: address for rootfilesystem in RAM */ -/* size of rootfs in RAM */ -#define CONFIG_KM_ROOTFSSIZE 0x0 /* set the default PRAM value to at least PNVRAM + PHRAM when pram env variable * is not valid yet, which is the case for when u-boot copies itself to RAM */ diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt index 15d39a6fc1..4c760fe62c 100644 --- a/scripts/config_whitelist.txt +++ b/scripts/config_whitelist.txt @@ -246,7 +246,6 @@ CONFIG_KM_DEF_ENV_FLASH_BOOT CONFIG_KM_DEV_ENV_FLASH_BOOT_UBI CONFIG_KM_ECC_MODE CONFIG_KM_NEW_ENV -CONFIG_KM_ROOTFSSIZE CONFIG_KM_UBI_LINUX_MTD CONFIG_KM_UBI_PARTITION_NAME_APP CONFIG_KM_UBI_PARTITION_NAME_BOOT