From 7eb62cb7165791a9a98a2d498f88b0ef2192f4c9 Mon Sep 17 00:00:00 2001 From: Minda Chen Date: Tue, 25 Jul 2023 17:46:47 +0800 Subject: [PATCH 01/18] i2c: designware: Add Kconfig for designware_i2c_pci.c As the Designware_i2c_pci.c uses ACPI APIs, If some SoCs (StarFive JH7110) contain Designware i2c and PCI but do not use ACPI, This file cannot be compiled. So add a new Kconfig for designware_i2c_pci.c, which depends on ACPIGEN Signed-off-by: Minda Chen Reviewed-by: Leo Yu-Chi Liang --- drivers/i2c/Kconfig | 9 +++++++++ drivers/i2c/Makefile | 4 +--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig index 5e81698143a..4c76fd7e415 100644 --- a/drivers/i2c/Kconfig +++ b/drivers/i2c/Kconfig @@ -231,6 +231,15 @@ config SYS_I2C_DW controller is used in various SoCs, e.g. the ST SPEAr, Altera SoCFPGA, Synopsys ARC700 and some Intel x86 SoCs. +config SYS_I2C_DW_PCI + bool "Designware PCI I2C Controller" + depends on SYS_I2C_DW && PCI && ACPIGEN + default y + help + Say yes here to select the Designware PCI I2C Host Controller. + This PCI I2C controller is the base on Desigware I2C host + controller. + config SYS_I2C_AST2600 bool "AST2600 I2C Controller" depends on DM_I2C && ARCH_ASPEED diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile index 99545df2e55..d5b85f398db 100644 --- a/drivers/i2c/Makefile +++ b/drivers/i2c/Makefile @@ -18,9 +18,7 @@ obj-$(CONFIG_SYS_I2C_CADENCE) += i2c-cdns.o obj-$(CONFIG_SYS_I2C_CA) += i2c-cortina.o obj-$(CONFIG_SYS_I2C_DAVINCI) += davinci_i2c.o obj-$(CONFIG_SYS_I2C_DW) += designware_i2c.o -ifdef CONFIG_PCI -obj-$(CONFIG_SYS_I2C_DW) += designware_i2c_pci.o -endif +obj-$(CONFIG_SYS_I2C_DW_PCI) += designware_i2c_pci.o obj-$(CONFIG_SYS_I2C_FSL) += fsl_i2c.o obj-$(CONFIG_SYS_I2C_IHS) += ihs_i2c.o obj-$(CONFIG_SYS_I2C_INTEL) += intel_i2c.o From 7870a05581243b510f6a1feedce1243ddcd49637 Mon Sep 17 00:00:00 2001 From: Mason Huo Date: Tue, 25 Jul 2023 17:46:48 +0800 Subject: [PATCH 02/18] starfive: pci: Add StarFive JH7110 pcie driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add pcie driver for StarFive JH7110, Also add PLDA PCIe controller common driver functions. Several devices are tested: a) M.2 NVMe SSD b) Realtek 8169 Ethernet adapter. Signed-off-by: Mason Huo Signed-off-by: Minda Chen Acked-by: Pali Rohár Reviewed-by: Leo Yu-Chi Liang --- drivers/pci/Kconfig | 13 ++ drivers/pci/Makefile | 2 + drivers/pci/pcie_plda_common.c | 116 +++++++++++ drivers/pci/pcie_plda_common.h | 118 +++++++++++ drivers/pci/pcie_starfive_jh7110.c | 317 +++++++++++++++++++++++++++++ 5 files changed, 566 insertions(+) create mode 100644 drivers/pci/pcie_plda_common.c create mode 100644 drivers/pci/pcie_plda_common.h create mode 100644 drivers/pci/pcie_starfive_jh7110.c diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index 93e6f500000..a0bf44d38a9 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -393,4 +393,17 @@ config PCIE_XILINX_NWL Say 'Y' here if you want support for Xilinx / AMD NWL PCIe controller as Root Port. +config PCIE_PLDA_COMMON + bool + +config PCIE_STARFIVE_JH7110 + bool "Enable Starfive JH7110 PCIe driver" + select PCIE_PLDA_COMMON + imply STARFIVE_JH7110 + imply CLK_JH7110 + imply RESET_JH7110 + help + Say Y here if you want to enable PLDA XpressRich PCIe controller + support on StarFive JH7110 SoC. + endif diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index 11f60c6991d..a712a317a39 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -50,3 +50,5 @@ obj-$(CONFIG_PCIE_OCTEON) += pcie_octeon.o obj-$(CONFIG_PCIE_DW_SIFIVE) += pcie_dw_sifive.o obj-$(CONFIG_PCIE_UNIPHIER) += pcie_uniphier.o obj-$(CONFIG_PCIE_XILINX_NWL) += pcie-xilinx-nwl.o +obj-$(CONFIG_PCIE_PLDA_COMMON) += pcie_plda_common.o +obj-$(CONFIG_PCIE_STARFIVE_JH7110) += pcie_starfive_jh7110.o diff --git a/drivers/pci/pcie_plda_common.c b/drivers/pci/pcie_plda_common.c new file mode 100644 index 00000000000..005b92616a7 --- /dev/null +++ b/drivers/pci/pcie_plda_common.c @@ -0,0 +1,116 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * PLDA XpressRich PCIe host controller common functions. + * + * Copyright (C) 2023 StarFive Technology Co., Ltd. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "pcie_plda_common.h" + +static bool plda_pcie_addr_valid(struct pcie_plda *plda, pci_dev_t bdf) +{ + /* + * Single device limitation. + * PCIe controller contain HW issue that secondary bus of + * host bridge emumerate duplicate devices. + * Only can access device 0 in secondary bus. + */ + if (PCI_BUS(bdf) == plda->sec_busno && PCI_DEV(bdf) > 0) + return false; + + return true; +} + +static int plda_pcie_conf_address(const struct udevice *udev, pci_dev_t bdf, + uint offset, void **paddr) +{ + struct pcie_plda *priv = dev_get_priv(udev); + int where = PCIE_ECAM_OFFSET(PCI_BUS(bdf), PCI_DEV(bdf), + PCI_FUNC(bdf), offset); + + if (!plda_pcie_addr_valid(priv, bdf)) + return -ENODEV; + + *paddr = (void *)(priv->cfg_base + where); + return 0; +} + +int plda_pcie_config_read(const struct udevice *udev, pci_dev_t bdf, + uint offset, ulong *valuep, + enum pci_size_t size) +{ + return pci_generic_mmap_read_config(udev, plda_pcie_conf_address, + bdf, offset, valuep, size); +} + +int plda_pcie_config_write(struct udevice *udev, pci_dev_t bdf, + uint offset, ulong value, + enum pci_size_t size) +{ + struct pcie_plda *priv = dev_get_priv(udev); + int ret; + + ret = pci_generic_mmap_write_config(udev, plda_pcie_conf_address, + bdf, offset, value, size); + + /* record secondary bus number */ + if (!ret && PCI_BUS(bdf) == dev_seq(udev) && + PCI_DEV(bdf) == 0 && PCI_FUNC(bdf) == 0 && + (offset == PCI_SECONDARY_BUS || + (offset == PCI_PRIMARY_BUS && size != PCI_SIZE_8))) { + priv->sec_busno = + ((offset == PCI_PRIMARY_BUS) ? (value >> 8) : value) & 0xff; + debug("Secondary bus number was changed to %d\n", + priv->sec_busno); + } + return ret; +} + +int plda_pcie_set_atr_entry(struct pcie_plda *plda, phys_addr_t src_addr, + phys_addr_t trsl_addr, phys_size_t window_size, + int trsl_param) +{ + void __iomem *base = + plda->reg_base + XR3PCI_ATR_AXI4_SLV0; + + /* Support AXI4 Slave 0 Address Translation Tables 0-7. */ + if (plda->atr_table_num >= XR3PCI_ATR_MAX_TABLE_NUM) { + dev_err(plda->dev, "ATR table number %d exceeds max num\n", + plda->atr_table_num); + return -EINVAL; + } + base += XR3PCI_ATR_TABLE_OFFSET * plda->atr_table_num; + plda->atr_table_num++; + + /* + * X3PCI_ATR_SRC_ADDR_LOW: + * - bit 0: enable entry, + * - bits 1-6: ATR window size: total size in bytes: 2^(ATR_WSIZE + 1) + * - bits 7-11: reserved + * - bits 12-31: start of source address + */ + writel((lower_32_bits(src_addr) & XR3PCI_ATR_SRC_ADDR_MASK) | + (fls(window_size) - 1) << XR3PCI_ATR_SRC_WIN_SIZE_SHIFT | 1, + base + XR3PCI_ATR_SRC_ADDR_LOW); + writel(upper_32_bits(src_addr), base + XR3PCI_ATR_SRC_ADDR_HIGH); + writel((lower_32_bits(trsl_addr) & XR3PCI_ATR_TRSL_ADDR_MASK), + base + XR3PCI_ATR_TRSL_ADDR_LOW); + writel(upper_32_bits(trsl_addr), base + XR3PCI_ATR_TRSL_ADDR_HIGH); + writel(trsl_param, base + XR3PCI_ATR_TRSL_PARAM); + + dev_dbg(plda->dev, "ATR entry: 0x%010llx %s 0x%010llx [0x%010llx] (param: 0x%06x)\n", + src_addr, (trsl_param & XR3PCI_ATR_TRSL_DIR) ? "<-" : "->", + trsl_addr, (u64)window_size, trsl_param); + return 0; +} diff --git a/drivers/pci/pcie_plda_common.h b/drivers/pci/pcie_plda_common.h new file mode 100644 index 00000000000..409949f5342 --- /dev/null +++ b/drivers/pci/pcie_plda_common.h @@ -0,0 +1,118 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2023 StarFive Technology Co., Ltd. + * Author: Minda Chen + * + */ + +#ifndef PCIE_PLDA_COMMON_H +#define PCIE_PLDA_COMMON_H + +#define GEN_SETTINGS 0x80 +#define PCIE_PCI_IDS 0x9C +#define PCIE_WINROM 0xFC +#define PMSG_SUPPORT_RX 0x3F0 +#define PCI_MISC 0xB4 + +#define PLDA_EP_ENABLE 0 +#define PLDA_RP_ENABLE 1 + +#define IDS_CLASS_CODE_SHIFT 8 + +#define PREF_MEM_WIN_64_SUPPORT BIT(3) +#define PMSG_LTR_SUPPORT BIT(2) +#define PLDA_FUNCTION_DIS BIT(15) +#define PLDA_FUNC_NUM 4 +#define PLDA_PHY_FUNC_SHIFT 9 + +#define XR3PCI_ATR_AXI4_SLV0 0x800 +#define XR3PCI_ATR_SRC_ADDR_LOW 0x0 +#define XR3PCI_ATR_SRC_ADDR_HIGH 0x4 +#define XR3PCI_ATR_TRSL_ADDR_LOW 0x8 +#define XR3PCI_ATR_TRSL_ADDR_HIGH 0xc +#define XR3PCI_ATR_TRSL_PARAM 0x10 +#define XR3PCI_ATR_TABLE_OFFSET 0x20 +#define XR3PCI_ATR_MAX_TABLE_NUM 8 + +#define XR3PCI_ATR_SRC_WIN_SIZE_SHIFT 1 +#define XR3PCI_ATR_SRC_ADDR_MASK GENMASK(31, 12) +#define XR3PCI_ATR_TRSL_ADDR_MASK GENMASK(31, 12) +#define XR3PCI_ATR_TRSL_DIR BIT(22) +/* IDs used in the XR3PCI_ATR_TRSL_PARAM */ +#define XR3PCI_ATR_TRSLID_PCIE_MEMORY 0x0 +#define XR3PCI_ATR_TRSLID_PCIE_CONFIG 0x1 + +/** + * struct pcie_plda - PLDA PCIe controller state + * + * @reg_base: The base address of controller register space + * @cfg_base: The base address of configuration space + * @cfg_size: The size of configuration space + * @sec_busno: Secondary bus number. + * @atr_table_num: Total ATR table numbers. + */ +struct pcie_plda { + struct udevice *dev; + void __iomem *reg_base; + void __iomem *cfg_base; + phys_size_t cfg_size; + int sec_busno; + int atr_table_num; +}; + +int plda_pcie_config_read(const struct udevice *udev, pci_dev_t bdf, + uint offset, ulong *valuep, + enum pci_size_t size); +int plda_pcie_config_write(struct udevice *udev, pci_dev_t bdf, + uint offset, ulong value, + enum pci_size_t size); +int plda_pcie_set_atr_entry(struct pcie_plda *plda, phys_addr_t src_addr, + phys_addr_t trsl_addr, phys_size_t window_size, + int trsl_param); + +static inline void plda_pcie_enable_root_port(struct pcie_plda *plda) +{ + u32 value; + + value = readl(plda->reg_base + GEN_SETTINGS); + value |= PLDA_RP_ENABLE; + writel(value, plda->reg_base + GEN_SETTINGS); +} + +static inline void plda_pcie_set_standard_class(struct pcie_plda *plda) +{ + u32 value; + + value = readl(plda->reg_base + PCIE_PCI_IDS); + value &= 0xff; + value |= (PCI_CLASS_BRIDGE_PCI_NORMAL << IDS_CLASS_CODE_SHIFT); + writel(value, plda->reg_base + PCIE_PCI_IDS); +} + +static inline void plda_pcie_set_pref_win_64bit(struct pcie_plda *plda) +{ + u32 value; + + value = readl(plda->reg_base + PCIE_WINROM); + value |= PREF_MEM_WIN_64_SUPPORT; + writel(value, plda->reg_base + PCIE_WINROM); +} + +static inline void plda_pcie_disable_ltr(struct pcie_plda *plda) +{ + u32 value; + + value = readl(plda->reg_base + PMSG_SUPPORT_RX); + value &= ~PMSG_LTR_SUPPORT; + writel(value, plda->reg_base + PMSG_SUPPORT_RX); +} + +static inline void plda_pcie_disable_func(struct pcie_plda *plda) +{ + u32 value; + + value = readl(plda->reg_base + PCI_MISC); + value |= PLDA_FUNCTION_DIS; + writel(value, plda->reg_base + PCI_MISC); +} +#endif diff --git a/drivers/pci/pcie_starfive_jh7110.c b/drivers/pci/pcie_starfive_jh7110.c new file mode 100644 index 00000000000..903a544d37f --- /dev/null +++ b/drivers/pci/pcie_starfive_jh7110.c @@ -0,0 +1,317 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * StarFive PLDA PCIe host controller driver + * + * Copyright (C) 2023 StarFive Technology Co., Ltd. + * Author: Mason Huo + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "pcie_plda_common.h" + +/* system control */ +#define STG_SYSCON_K_RP_NEP_MASK BIT(8) +#define STG_SYSCON_AXI4_SLVL_ARFUNC_MASK GENMASK(22, 8) +#define STG_SYSCON_AXI4_SLVL_ARFUNC_SHIFT 8 +#define STG_SYSCON_AXI4_SLVL_AWFUNC_MASK GENMASK(14, 0) +#define STG_SYSCON_CLKREQ_MASK BIT(22) +#define STG_SYSCON_CKREF_SRC_SHIFT 18 +#define STG_SYSCON_CKREF_SRC_MASK GENMASK(19, 18) + +DECLARE_GLOBAL_DATA_PTR; + +struct starfive_pcie { + struct pcie_plda plda; + struct clk_bulk clks; + struct reset_ctl_bulk rsts; + struct gpio_desc reset_gpio; + struct regmap *regmap; + u32 stg_arfun; + u32 stg_awfun; + u32 stg_rp_nep; +}; + +static int starfive_pcie_atr_init(struct starfive_pcie *priv) +{ + struct udevice *ctlr = pci_get_controller(priv->plda.dev); + struct pci_controller *hose = dev_get_uclass_priv(ctlr); + int i, ret; + + /* + * As the two host bridges in JH7110 soc have the same default + * address translation table, this cause the second root port can't + * access it's host bridge config space correctly. + * To workaround, config the ATR of host bridge config space by SW. + */ + + ret = plda_pcie_set_atr_entry(&priv->plda, + (phys_addr_t)priv->plda.cfg_base, 0, + priv->plda.cfg_size, + XR3PCI_ATR_TRSLID_PCIE_CONFIG); + if (ret) + return ret; + + for (i = 0; i < hose->region_count; i++) { + if (hose->regions[i].flags == PCI_REGION_SYS_MEMORY) + continue; + + /* Only support identity mappings. */ + if (hose->regions[i].bus_start != + hose->regions[i].phys_start) + return -EINVAL; + + ret = plda_pcie_set_atr_entry(&priv->plda, + hose->regions[i].phys_start, + hose->regions[i].bus_start, + hose->regions[i].size, + XR3PCI_ATR_TRSLID_PCIE_MEMORY); + if (ret) + return ret; + } + + return 0; +} + +static int starfive_pcie_get_syscon(struct udevice *dev) +{ + struct starfive_pcie *priv = dev_get_priv(dev); + struct udevice *syscon; + struct ofnode_phandle_args syscfg_phandle; + u32 cells[4]; + int ret; + + /* get corresponding syscon phandle */ + ret = dev_read_phandle_with_args(dev, "starfive,stg-syscon", NULL, 0, 0, + &syscfg_phandle); + + if (ret < 0) { + dev_err(dev, "Can't get syscfg phandle: %d\n", ret); + return ret; + } + + ret = uclass_get_device_by_ofnode(UCLASS_SYSCON, syscfg_phandle.node, + &syscon); + if (ret) { + dev_err(dev, "Unable to find syscon device (%d)\n", ret); + return ret; + } + + priv->regmap = syscon_get_regmap(syscon); + if (!priv->regmap) { + dev_err(dev, "Unable to find regmap\n"); + return -ENODEV; + } + + /* get syscon register offset */ + ret = dev_read_u32_array(dev, "starfive,stg-syscon", + cells, ARRAY_SIZE(cells)); + if (ret) { + dev_err(dev, "Get syscon register err %d\n", ret); + return -EINVAL; + } + + dev_dbg(dev, "Get syscon values: %x, %x, %x\n", + cells[1], cells[2], cells[3]); + priv->stg_arfun = cells[1]; + priv->stg_awfun = cells[2]; + priv->stg_rp_nep = cells[3]; + + return 0; +} + +static int starfive_pcie_parse_dt(struct udevice *dev) +{ + struct starfive_pcie *priv = dev_get_priv(dev); + int ret; + + priv->plda.reg_base = (void *)dev_read_addr_name(dev, "reg"); + if (priv->plda.reg_base == (void __iomem *)FDT_ADDR_T_NONE) { + dev_err(dev, "Missing required reg address range\n"); + return -EINVAL; + } + + priv->plda.cfg_base = + (void *)dev_read_addr_size_name(dev, + "config", + &priv->plda.cfg_size); + if (priv->plda.cfg_base == (void __iomem *)FDT_ADDR_T_NONE) { + dev_err(dev, "Missing required config address range"); + return -EINVAL; + } + + ret = starfive_pcie_get_syscon(dev); + if (ret) { + dev_err(dev, "Can't get syscon: %d\n", ret); + return ret; + } + + ret = reset_get_bulk(dev, &priv->rsts); + if (ret) { + dev_err(dev, "Can't get reset: %d\n", ret); + return ret; + } + + ret = clk_get_bulk(dev, &priv->clks); + if (ret) { + dev_err(dev, "Can't get clock: %d\n", ret); + return ret; + } + + ret = gpio_request_by_name(dev, "reset-gpios", 0, &priv->reset_gpio, + GPIOD_IS_OUT); + if (ret) { + dev_err(dev, "Can't get reset-gpio: %d\n", ret); + return ret; + } + + if (!dm_gpio_is_valid(&priv->reset_gpio)) { + dev_err(dev, "reset-gpio is not valid\n"); + return -EINVAL; + } + return 0; +} + +static int starfive_pcie_init_port(struct udevice *dev) +{ + int ret, i; + struct starfive_pcie *priv = dev_get_priv(dev); + struct pcie_plda *plda = &priv->plda; + + ret = clk_enable_bulk(&priv->clks); + if (ret) { + dev_err(dev, "Failed to enable clks (ret=%d)\n", ret); + return ret; + } + + ret = reset_deassert_bulk(&priv->rsts); + if (ret) { + dev_err(dev, "Failed to deassert resets (ret=%d)\n", ret); + goto err_deassert_clk; + } + + dm_gpio_set_value(&priv->reset_gpio, 1); + /* Disable physical functions except #0 */ + for (i = 1; i < PLDA_FUNC_NUM; i++) { + regmap_update_bits(priv->regmap, + priv->stg_arfun, + STG_SYSCON_AXI4_SLVL_ARFUNC_MASK, + (i << PLDA_PHY_FUNC_SHIFT) << + STG_SYSCON_AXI4_SLVL_ARFUNC_SHIFT); + regmap_update_bits(priv->regmap, + priv->stg_awfun, + STG_SYSCON_AXI4_SLVL_AWFUNC_MASK, + i << PLDA_PHY_FUNC_SHIFT); + + plda_pcie_disable_func(plda); + } + + /* Disable physical functions */ + regmap_update_bits(priv->regmap, + priv->stg_arfun, + STG_SYSCON_AXI4_SLVL_ARFUNC_MASK, + 0); + regmap_update_bits(priv->regmap, + priv->stg_awfun, + STG_SYSCON_AXI4_SLVL_AWFUNC_MASK, + 0); + + plda_pcie_enable_root_port(plda); + + /* PCIe PCI Standard Configuration Identification Settings. */ + plda_pcie_set_standard_class(plda); + + /* + * The LTR message forwarding of PCIe Message Reception was set by core + * as default, but the forward id & addr are also need to be reset. + * If we do not disable LTR message forwarding here, or set a legal + * forwarding address, the kernel will get stuck after this driver probe. + * To workaround, disable the LTR message forwarding support on + * PCIe Message Reception. + */ + plda_pcie_disable_ltr(plda); + + /* Prefetchable memory window 64-bit addressing support */ + plda_pcie_set_pref_win_64bit(plda); + starfive_pcie_atr_init(priv); + + dm_gpio_set_value(&priv->reset_gpio, 0); + /* Ensure that PERST in default at least 300 ms */ + mdelay(300); + + return 0; + +err_deassert_clk: + clk_disable_bulk(&priv->clks); + return ret; +} + +static int starfive_pcie_probe(struct udevice *dev) +{ + struct starfive_pcie *priv = dev_get_priv(dev); + int ret; + + priv->plda.atr_table_num = 0; + priv->plda.dev = dev; + + ret = starfive_pcie_parse_dt(dev); + if (ret) + return ret; + + regmap_update_bits(priv->regmap, + priv->stg_rp_nep, + STG_SYSCON_K_RP_NEP_MASK, + STG_SYSCON_K_RP_NEP_MASK); + + regmap_update_bits(priv->regmap, + priv->stg_awfun, + STG_SYSCON_CKREF_SRC_MASK, + 2 << STG_SYSCON_CKREF_SRC_SHIFT); + + regmap_update_bits(priv->regmap, + priv->stg_awfun, + STG_SYSCON_CLKREQ_MASK, + STG_SYSCON_CLKREQ_MASK); + + ret = starfive_pcie_init_port(dev); + if (ret) + return ret; + + dev_err(dev, "Starfive PCIe bus probed.\n"); + + return 0; +} + +static const struct dm_pci_ops starfive_pcie_ops = { + .read_config = plda_pcie_config_read, + .write_config = plda_pcie_config_write, +}; + +static const struct udevice_id starfive_pcie_ids[] = { + { .compatible = "starfive,jh7110-pcie" }, + { } +}; + +U_BOOT_DRIVER(starfive_pcie_drv) = { + .name = "starfive_7110_pcie", + .id = UCLASS_PCI, + .of_match = starfive_pcie_ids, + .ops = &starfive_pcie_ops, + .probe = starfive_pcie_probe, + .priv_auto = sizeof(struct starfive_pcie), +}; From cb2750e10b3acd8d8283e2c8488540bdcd19c691 Mon Sep 17 00:00:00 2001 From: Mason Huo Date: Tue, 25 Jul 2023 17:46:49 +0800 Subject: [PATCH 03/18] configs: starfive-jh7110: Add support for PCIe host driver Add PCIe host driver and nvme driver in configure file. Signed-off-by: Mason Huo Signed-off-by: Minda Chen Reviewed-by: Leo Yu-Chi Liang --- configs/starfive_visionfive2_defconfig | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/configs/starfive_visionfive2_defconfig b/configs/starfive_visionfive2_defconfig index 75b727472da..3534f52851e 100644 --- a/configs/starfive_visionfive2_defconfig +++ b/configs/starfive_visionfive2_defconfig @@ -19,6 +19,8 @@ CONFIG_SPL=y CONFIG_SPL_SPI_FLASH_SUPPORT=y CONFIG_SPL_SPI=y CONFIG_SYS_LOAD_ADDR=0x82000000 +CONFIG_SYS_PCI_64BIT=y +CONFIG_PCI=y CONFIG_TARGET_STARFIVE_VISIONFIVE2=y CONFIG_SPL_OPENSBI_LOAD_ADDR=0x40000000 CONFIG_ARCH_RV64I=y @@ -62,6 +64,7 @@ CONFIG_SYS_EEPROM_PAGE_WRITE_BITS=4 CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS=5 CONFIG_CMD_MEMINFO=y CONFIG_CMD_I2C=y +CONFIG_CMD_PCI=y CONFIG_CMD_TFTPPUT=y CONFIG_OF_BOARD=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y @@ -92,6 +95,10 @@ CONFIG_DWC_ETH_QOS=y CONFIG_DWC_ETH_QOS_STARFIVE=y CONFIG_RGMII=y CONFIG_RMII=y +CONFIG_NVME_PCI=y +CONFIG_DM_PCI_COMPAT=y +CONFIG_PCI_REGION_MULTI_ENTRY=y +CONFIG_PCIE_STARFIVE_JH7110=y CONFIG_PINCTRL=y CONFIG_PINCONF=y CONFIG_SPL_PINCTRL=y From 8db2224ffca24aab3f933618bf27d747a1a4c161 Mon Sep 17 00:00:00 2001 From: Mason Huo Date: Tue, 25 Jul 2023 17:46:50 +0800 Subject: [PATCH 04/18] riscv: dts: starfive: Enable PCIe host controller Enable and add pinctrl configuration for PCIe host controller. Signed-off-by: Mason Huo Signed-off-by: Minda Chen Reviewed-by: Leo Yu-Chi Liang --- .../dts/jh7110-starfive-visionfive-2.dtsi | 11 +++ arch/riscv/dts/jh7110.dtsi | 74 +++++++++++++++++++ 2 files changed, 85 insertions(+) diff --git a/arch/riscv/dts/jh7110-starfive-visionfive-2.dtsi b/arch/riscv/dts/jh7110-starfive-visionfive-2.dtsi index b90e7f89954..bf7fdb4dd61 100644 --- a/arch/riscv/dts/jh7110-starfive-visionfive-2.dtsi +++ b/arch/riscv/dts/jh7110-starfive-visionfive-2.dtsi @@ -7,6 +7,7 @@ #include "jh7110.dtsi" #include +#include / { aliases { serial0 = &uart0; @@ -308,6 +309,16 @@ }; }; +&pcie0 { + reset-gpios = <&sysgpio 26 GPIO_ACTIVE_LOW>; + status = "disabled"; +}; + +&pcie1 { + reset-gpios = <&sysgpio 28 GPIO_ACTIVE_LOW>; + status = "okay"; +}; + &syscrg { assigned-clocks = <&syscrg JH7110_SYSCLK_CPU_ROOT>, <&syscrg JH7110_SYSCLK_BUS_ROOT>, diff --git a/arch/riscv/dts/jh7110.dtsi b/arch/riscv/dts/jh7110.dtsi index 825fbb7198f..081b833331b 100644 --- a/arch/riscv/dts/jh7110.dtsi +++ b/arch/riscv/dts/jh7110.dtsi @@ -648,5 +648,79 @@ gpio-controller; #gpio-cells = <2>; }; + + pcie0: pcie@2b000000 { + compatible = "starfive,jh7110-pcie"; + reg = <0x0 0x2b000000 0x0 0x1000000 + 0x9 0x40000000 0x0 0x10000000>; + reg-names = "reg", "config"; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + ranges = <0x82000000 0x0 0x30000000 0x0 0x30000000 0x0 0x08000000>, + <0xc3000000 0x9 0x00000000 0x9 0x00000000 0x0 0x40000000>; + interrupts = <56>; + interrupt-parent = <&plic>; + interrupt-map-mask = <0x0 0x0 0x0 0x7>; + interrupt-map = <0x0 0x0 0x0 0x1 &plic 0x1>, + <0x0 0x0 0x0 0x2 &plic 0x2>, + <0x0 0x0 0x0 0x3 &plic 0x3>, + <0x0 0x0 0x0 0x4 &plic 0x4>; + msi-parent = <&plic>; + device_type = "pci"; + starfive,stg-syscon = <&stg_syscon 0xc0 0xc4 0x130 0x1b8>; + bus-range = <0x0 0xff>; + clocks = <&syscrg JH7110_SYSCLK_NOC_BUS_STG_AXI>, + <&stgcrg JH7110_STGCLK_PCIE0_TL>, + <&stgcrg JH7110_STGCLK_PCIE0_AXI>, + <&stgcrg JH7110_STGCLK_PCIE0_APB>; + clock-names = "noc", "tl", "axi", "apb"; + resets = <&stgcrg JH7110_STGRST_PCIE0_MST0>, + <&stgcrg JH7110_STGRST_PCIE0_SLV0>, + <&stgcrg JH7110_STGRST_PCIE0_SLV>, + <&stgcrg JH7110_STGRST_PCIE0_BRG>, + <&stgcrg JH7110_STGRST_PCIE0_CORE>, + <&stgcrg JH7110_STGRST_PCIE0_APB>; + reset-names = "mst0", "slv0", "slv", "brg", + "core", "apb"; + status = "disabled"; + }; + + pcie1: pcie@2c000000 { + compatible = "starfive,jh7110-pcie"; + reg = <0x0 0x2c000000 0x0 0x1000000 + 0x9 0xc0000000 0x0 0x10000000>; + reg-names = "reg", "config"; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + ranges = <0x82000000 0x0 0x38000000 0x0 0x38000000 0x0 0x08000000>, + <0xc3000000 0x9 0x80000000 0x9 0x80000000 0x0 0x40000000>; + interrupts = <57>; + interrupt-parent = <&plic>; + interrupt-map-mask = <0x0 0x0 0x0 0x7>; + interrupt-map = <0x0 0x0 0x0 0x1 &plic 0x1>, + <0x0 0x0 0x0 0x2 &plic 0x2>, + <0x0 0x0 0x0 0x3 &plic 0x3>, + <0x0 0x0 0x0 0x4 &plic 0x4>; + msi-parent = <&plic>; + device_type = "pci"; + starfive,stg-syscon = <&stg_syscon 0x270 0x274 0x2e0 0x368>; + bus-range = <0x0 0xff>; + clocks = <&syscrg JH7110_SYSCLK_NOC_BUS_STG_AXI>, + <&stgcrg JH7110_STGCLK_PCIE1_TL>, + <&stgcrg JH7110_STGCLK_PCIE1_AXI>, + <&stgcrg JH7110_STGCLK_PCIE1_APB>; + clock-names = "noc", "tl", "axi", "apb"; + resets = <&stgcrg JH7110_STGRST_PCIE1_MST0>, + <&stgcrg JH7110_STGRST_PCIE1_SLV0>, + <&stgcrg JH7110_STGRST_PCIE1_SLV>, + <&stgcrg JH7110_STGRST_PCIE1_BRG>, + <&stgcrg JH7110_STGRST_PCIE1_CORE>, + <&stgcrg JH7110_STGRST_PCIE1_APB>; + reset-names = "mst0", "slv0", "slv", "brg", + "core", "apb"; + status = "disabled"; + }; }; }; From a6a0d6a19121c722a263714eae4d511bb2580f3c Mon Sep 17 00:00:00 2001 From: Minda Chen Date: Thu, 20 Jul 2023 19:37:26 +0800 Subject: [PATCH 05/18] net: rtl8169: Fix compile warning in rtl8169 While compiling rtl8169.c, There are many "make pointer from integer without a cast" compile warnings. fix them with adding cast. Signed-off-by: Minda Chen Reviewed-by: Ramon Fried Reviewed-by: Leo Yu-Chi Liang --- drivers/net/rtl8169.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/net/rtl8169.c b/drivers/net/rtl8169.c index 2276a465e78..dcba51590d1 100644 --- a/drivers/net/rtl8169.c +++ b/drivers/net/rtl8169.c @@ -96,12 +96,12 @@ static int media[MAX_UNITS] = { -1, -1, -1, -1, -1, -1, -1, -1 }; #define TX_TIMEOUT (6*HZ) /* write/read MMIO register. Notice: {read,write}[wl] do the necessary swapping */ -#define RTL_W8(reg, val8) writeb((val8), ioaddr + (reg)) -#define RTL_W16(reg, val16) writew((val16), ioaddr + (reg)) -#define RTL_W32(reg, val32) writel((val32), ioaddr + (reg)) -#define RTL_R8(reg) readb(ioaddr + (reg)) -#define RTL_R16(reg) readw(ioaddr + (reg)) -#define RTL_R32(reg) readl(ioaddr + (reg)) +#define RTL_W8(reg, val8) writeb((val8), (void *)(ioaddr + (reg))) +#define RTL_W16(reg, val16) writew((val16), (void *)(ioaddr + (reg))) +#define RTL_W32(reg, val32) writel((val32), (void *)(ioaddr + (reg))) +#define RTL_R8(reg) readb((void *)(ioaddr + (reg))) +#define RTL_R16(reg) readw((void *)(ioaddr + (reg))) +#define RTL_R32(reg) readl((void *)(ioaddr + (reg))) #define bus_to_phys(a) pci_mem_to_phys((pci_dev_t)(unsigned long)dev->priv, \ (pci_addr_t)(unsigned long)a) From 309484516576d74e0868ac6399b36e56e9d30a3e Mon Sep 17 00:00:00 2001 From: Minda Chen Date: Thu, 20 Jul 2023 19:37:27 +0800 Subject: [PATCH 06/18] net: rtl8169: Fix DMA minimal aligned compile warning in RISC-V For RISC-V architeture, hardware maintain the dcache coherency. Software do not flush the cache. So even cache-line size larger than descriptor size, driver can work. Signed-off-by: Minda Chen Reviewed-by: Ramon Fried Reviewed-by: Leo Yu-Chi Liang --- drivers/net/rtl8169.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/rtl8169.c b/drivers/net/rtl8169.c index dcba51590d1..34e4cff1e9c 100644 --- a/drivers/net/rtl8169.c +++ b/drivers/net/rtl8169.c @@ -311,10 +311,12 @@ static unsigned char rxdata[RX_BUF_LEN]; * * This can be fixed by defining CONFIG_SYS_NONCACHED_MEMORY which will cause * the driver to allocate descriptors from a pool of non-cached memory. + * + * Hardware maintain D-cache coherency in RISC-V architecture. */ #if RTL8169_DESC_SIZE < ARCH_DMA_MINALIGN #if !defined(CONFIG_SYS_NONCACHED_MEMORY) && \ - !CONFIG_IS_ENABLED(SYS_DCACHE_OFF) && !defined(CONFIG_X86) + !CONFIG_IS_ENABLED(SYS_DCACHE_OFF) && !defined(CONFIG_X86) && !defined(CONFIG_RISCV) #warning cache-line size is larger than descriptor size #endif #endif From ff8590a225d86b457e1aa2807fedffba5fc8bd4c Mon Sep 17 00:00:00 2001 From: Minda Chen Date: Thu, 20 Jul 2023 19:37:28 +0800 Subject: [PATCH 07/18] net: rtl8169: Add one device ID 0x8161 Add rtl8169 NIC device ID and reorder the device ID. Signed-off-by: Minda Chen Reviewed-by: Ramon Fried Reviewed-by: Leo Yu-Chi Liang --- drivers/net/rtl8169.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/rtl8169.c b/drivers/net/rtl8169.c index 34e4cff1e9c..963702777c2 100644 --- a/drivers/net/rtl8169.c +++ b/drivers/net/rtl8169.c @@ -353,10 +353,11 @@ static const unsigned int rtl8169_rx_config = (RX_FIFO_THRESH << RxCfgFIFOShift) | (RX_DMA_BURST << RxCfgDMAShift); static struct pci_device_id supported[] = { + { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8125) }, + { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8161) }, { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8167) }, { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8168) }, { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8169) }, - { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8125) }, {} }; @@ -1051,8 +1052,9 @@ static int rtl8169_eth_probe(struct udevice *dev) int ret; switch (pplat->device) { - case 0x8168: case 0x8125: + case 0x8161: + case 0x8168: region = 2; break; default: From 493c03f82065ac67b3e7b1cde3c719bbd0e86514 Mon Sep 17 00:00:00 2001 From: Minda Chen Date: Thu, 20 Jul 2023 19:37:29 +0800 Subject: [PATCH 08/18] configs: starfive-jh7110: Add CONFIG_RTL8169 Add PCIe device rtl8169 net adapter driver support. Signed-off-by: Minda Chen Reviewed-by: Leo Yu-Chi Liang --- configs/starfive_visionfive2_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/configs/starfive_visionfive2_defconfig b/configs/starfive_visionfive2_defconfig index 3534f52851e..5d8a8e28cbb 100644 --- a/configs/starfive_visionfive2_defconfig +++ b/configs/starfive_visionfive2_defconfig @@ -95,6 +95,7 @@ CONFIG_DWC_ETH_QOS=y CONFIG_DWC_ETH_QOS_STARFIVE=y CONFIG_RGMII=y CONFIG_RMII=y +CONFIG_RTL8169=y CONFIG_NVME_PCI=y CONFIG_DM_PCI_COMPAT=y CONFIG_PCI_REGION_MULTI_ENTRY=y From cd24d0722a554f18a85076353b6d816d9afc3ade Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Tue, 25 Jul 2023 12:41:30 +0200 Subject: [PATCH 09/18] riscv: sifive: initialize PCI on Unmatched The Unmatched board is typically booted from NVMe which requires PCI. When dropping to a console PCI is not initialized yet. 'pci enum' has to be called. Change the configuration to call pci_init() in board_init_r(). Signed-off-by: Heinrich Schuchardt Reviewed-by: Rick Chen --- configs/sifive_unmatched_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/configs/sifive_unmatched_defconfig b/configs/sifive_unmatched_defconfig index ffae8655c98..867611b6b4e 100644 --- a/configs/sifive_unmatched_defconfig +++ b/configs/sifive_unmatched_defconfig @@ -31,6 +31,7 @@ CONFIG_DISPLAY_CPUINFO=y CONFIG_DISPLAY_BOARDINFO=y CONFIG_DISPLAY_BOARDINFO_LATE=y CONFIG_ID_EEPROM=y +CONFIG_PCI_INIT_R=y CONFIG_SPL_MAX_SIZE=0x100000 CONFIG_SPL_BSS_START_ADDR=0x85000000 # CONFIG_SPL_SHARES_INIT_SP_ADDR is not set From 093bd0354e5b947b0bd634bf5ed4041ba075b57d Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Wed, 26 Jul 2023 08:05:13 +0200 Subject: [PATCH 10/18] acpi: Add missing RISC-V acpi_table header The pci_mmc.c driver can generate ACPI info and therefore includes asm/acpi_table.h. This file does not exist for the RISC-V architecture and thus code compilation fails when using this driver on RISC-V Create an empty include file. Signed-off-by: Heinrich Schuchardt Reviewed-by: Leo Yu-Chi Liang Reviewed-by: Rick Chen --- arch/riscv/include/asm/acpi_table.h | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 arch/riscv/include/asm/acpi_table.h diff --git a/arch/riscv/include/asm/acpi_table.h b/arch/riscv/include/asm/acpi_table.h new file mode 100644 index 00000000000..cd851998b22 --- /dev/null +++ b/arch/riscv/include/asm/acpi_table.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#ifndef __ASM_ACPI_TABLE_H__ +#define __ASM_ACPI_TABLE_H__ + +/* + * This file is needed by some drivers. + * We will fill it when adding ACPI support for RISC-V. + */ + +#endif /* __ASM_ACPI_TABLE_H__ */ From 716161663ec4904f0487308dd428ceb8b42bcf5d Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Sun, 23 Jul 2023 12:40:33 +0800 Subject: [PATCH 11/18] riscv: qemu: Enable Bochs video support Enable video console using the emulated Bochs VGA card. Signed-off-by: Bin Meng Reviewed-by: Simon Glass --- board/emulation/qemu-riscv/Kconfig | 3 +++ doc/board/emulation/qemu-riscv.rst | 5 +++++ include/configs/qemu-riscv.h | 5 +++++ 3 files changed, 13 insertions(+) diff --git a/board/emulation/qemu-riscv/Kconfig b/board/emulation/qemu-riscv/Kconfig index 6114e1b8120..976c350e50b 100644 --- a/board/emulation/qemu-riscv/Kconfig +++ b/board/emulation/qemu-riscv/Kconfig @@ -68,5 +68,8 @@ config BOARD_SPECIFIC_OPTIONS # dummy imply MTD_NOR_FLASH imply CFI_FLASH imply OF_HAS_PRIOR_STAGE + imply VIDEO + imply VIDEO_BOCHS + imply SYS_WHITE_ON_BLACK endif diff --git a/doc/board/emulation/qemu-riscv.rst b/doc/board/emulation/qemu-riscv.rst index 509bf7c4a6c..9d21f3270c6 100644 --- a/doc/board/emulation/qemu-riscv.rst +++ b/doc/board/emulation/qemu-riscv.rst @@ -133,6 +133,11 @@ An attached disk can be emulated in RISC-V virt machine by adding:: You will have to run 'scsi scan' to use it. +A video console can be emulated in RISC-V virt machine by removing "-nographic" +and adding:: + + -serial stdio -device VGA + Running with KVM ---------------- diff --git a/include/configs/qemu-riscv.h b/include/configs/qemu-riscv.h index f6d326bda0d..7ec3d12ce10 100644 --- a/include/configs/qemu-riscv.h +++ b/include/configs/qemu-riscv.h @@ -17,6 +17,10 @@ /* Environment options */ +#define CFG_STD_DEVICES_SETTINGS "stdin=serial\0" \ + "stdout=serial,vidconsole\0" \ + "stderr=serial,vidconsole\0" + #define BOOT_TARGET_DEVICES(func) \ func(QEMU, qemu, na) \ func(VIRTIO, virtio, 0) \ @@ -35,6 +39,7 @@ "qemu " #define CFG_EXTRA_ENV_SETTINGS \ + CFG_STD_DEVICES_SETTINGS \ "fdt_high=0xffffffffffffffff\0" \ "initrd_high=0xffffffffffffffff\0" \ "kernel_addr_r=0x84000000\0" \ From 142276ce51ba97eade1b70c7c7c91e0ada428284 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Sun, 23 Jul 2023 12:40:34 +0800 Subject: [PATCH 12/18] console: kconfig: Drop the redundant VIDEO dependency The VIDEO dependency is described twice in CONSOLE_MUX. Signed-off-by: Bin Meng Reviewed-by: Heinrich Schuchardt Reviewed-by: Simon Glass --- common/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/Kconfig b/common/Kconfig index 973482f0756..d103bc6ddb8 100644 --- a/common/Kconfig +++ b/common/Kconfig @@ -226,7 +226,7 @@ config CONSOLE_FLUSH_SUPPORT config CONSOLE_MUX bool "Enable console multiplexing" - default y if VIDEO || VIDEO || LCD + default y if VIDEO || LCD help This allows multiple devices to be used for each console 'file'. For example, stdout can be set to go to serial and video. From 75bfc6fac5918eba48ddfe608f0a1c6a89d47168 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Sun, 23 Jul 2023 12:40:35 +0800 Subject: [PATCH 13/18] console: Make stdio_print_current_devices() static As it is only called in common/console.c Signed-off-by: Bin Meng Reviewed-by: Simon Glass Tested-by: Simon Glass # qemu-x86_64 --- common/console.c | 2 +- include/stdio_dev.h | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/common/console.c b/common/console.c index 71ad8efd6f4..d0640ba05a9 100644 --- a/common/console.c +++ b/common/console.c @@ -1010,7 +1010,7 @@ int console_init_f(void) return 0; } -void stdio_print_current_devices(void) +static void stdio_print_current_devices(void) { /* Print information */ puts("In: "); diff --git a/include/stdio_dev.h b/include/stdio_dev.h index 77bf8a8970f..7f181020524 100644 --- a/include/stdio_dev.h +++ b/include/stdio_dev.h @@ -84,8 +84,6 @@ int stdio_init_tables(void); */ int stdio_add_devices(void); -void stdio_print_current_devices(void); - /** * stdio_deregister_dev() - deregister the device "devname". * From f30fd55e82ae82b720649cc67744308a8356a874 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Sun, 23 Jul 2023 12:40:36 +0800 Subject: [PATCH 14/18] console: Refactor stdio_print_current_devices() a little bit In preparation to future changes, refactor this routine a little bit. Signed-off-by: Bin Meng --- common/console.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/common/console.c b/common/console.c index d0640ba05a9..af52897ec38 100644 --- a/common/console.c +++ b/common/console.c @@ -1012,27 +1012,27 @@ int console_init_f(void) static void stdio_print_current_devices(void) { + char *stdinname, *stdoutname, *stderrname; + + stdinname = stdio_devices[stdin] ? + stdio_devices[stdin]->name : + "No input devices available!"; + stdoutname = stdio_devices[stdout] ? + stdio_devices[stdout]->name : + "No output devices available!"; + stderrname = stdio_devices[stderr] ? + stdio_devices[stderr]->name : + "No error devices available!"; + /* Print information */ puts("In: "); - if (stdio_devices[stdin] == NULL) { - puts("No input devices available!\n"); - } else { - printf ("%s\n", stdio_devices[stdin]->name); - } + printf("%s\n", stdinname); puts("Out: "); - if (stdio_devices[stdout] == NULL) { - puts("No output devices available!\n"); - } else { - printf ("%s\n", stdio_devices[stdout]->name); - } + printf("%s\n", stdoutname); puts("Err: "); - if (stdio_devices[stderr] == NULL) { - puts("No error devices available!\n"); - } else { - printf ("%s\n", stdio_devices[stderr]->name); - } + printf("%s\n", stderrname); } #if CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV) From 6b343ab38d9665e5062134549323f998c60c35d6 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Sun, 23 Jul 2023 12:40:37 +0800 Subject: [PATCH 15/18] console: Print out complete stdio device list At present if both CONSOLE_MUX and SYS_CONSOLE_IS_IN_ENV are on, during boot, the printed out stdio devices are incomplete, e.g.: with "stdout=serial,vidconsole", only "vidconsole" is printed. For such case, we can print out the stdio device name from the environment variables. Signed-off-by: Bin Meng Reviewed-by: Simon Glass Reviewed-by: Tom Rini --- common/console.c | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/common/console.c b/common/console.c index af52897ec38..98c3ee6ca6b 100644 --- a/common/console.c +++ b/common/console.c @@ -1014,15 +1014,27 @@ static void stdio_print_current_devices(void) { char *stdinname, *stdoutname, *stderrname; - stdinname = stdio_devices[stdin] ? - stdio_devices[stdin]->name : - "No input devices available!"; - stdoutname = stdio_devices[stdout] ? - stdio_devices[stdout]->name : - "No output devices available!"; - stderrname = stdio_devices[stderr] ? - stdio_devices[stderr]->name : - "No error devices available!"; + if (CONFIG_IS_ENABLED(CONSOLE_MUX) && + CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV)) { + /* stdin stdout and stderr are in environment */ + stdinname = env_get("stdin"); + stdoutname = env_get("stdout"); + stderrname = env_get("stderr"); + + stdinname = stdinname ? : "No input devices available!"; + stdoutname = stdoutname ? : "No output devices available!"; + stderrname = stderrname ? : "No error devices available!"; + } else { + stdinname = stdio_devices[stdin] ? + stdio_devices[stdin]->name : + "No input devices available!"; + stdoutname = stdio_devices[stdout] ? + stdio_devices[stdout]->name : + "No output devices available!"; + stderrname = stdio_devices[stderr] ? + stdio_devices[stderr]->name : + "No error devices available!"; + } /* Print information */ puts("In: "); From 608b80b5b855d0c55a5fa7de11c1338bf2541855 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Sun, 23 Jul 2023 12:40:38 +0800 Subject: [PATCH 16/18] riscv: qemu: Enable PRE_CONSOLE_BUFFER By default the video console only outputs messages after it's ready. Messages before that won't show on the video console, but U-Boot has an option to buffer the console messages before it's ready. Enable this support, and carefully select an address for the buffer. Signed-off-by: Bin Meng Reviewed-by: Rick Chen Reviewed-by: Simon Glass --- board/emulation/qemu-riscv/Kconfig | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/board/emulation/qemu-riscv/Kconfig b/board/emulation/qemu-riscv/Kconfig index 976c350e50b..7220c55350e 100644 --- a/board/emulation/qemu-riscv/Kconfig +++ b/board/emulation/qemu-riscv/Kconfig @@ -25,6 +25,10 @@ config SPL_OPENSBI_LOAD_ADDR hex default 0x80100000 +config PRE_CON_BUF_ADDR + hex + default 0x81000000 + config BOARD_SPECIFIC_OPTIONS # dummy def_bool y select GENERIC_RISCV @@ -71,5 +75,6 @@ config BOARD_SPECIFIC_OPTIONS # dummy imply VIDEO imply VIDEO_BOCHS imply SYS_WHITE_ON_BLACK + imply PRE_CONSOLE_BUFFER endif From 124308e67b6e1b6597ef34899211abac9bf7fd60 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Sun, 23 Jul 2023 12:40:40 +0800 Subject: [PATCH 17/18] riscv: qemu: Remove out-of-date "riscv, kernel-start" handling Commit 66ffe57 ("riscv: qemu: detect and boot the kernel passed by QEMU") added some logic to handle "riscv,kernel-start" in DT and stored the address to an environment variable kernel_start. However this "riscv,kernel-start" has never been an upstream DT binding. The upstream QEMU never generates such a DT either. Presumably U-Boot development was based on a downstream QEMU fork. Now we drop all codes in commit 66ffe57, except that BOARD_LATE_INIT is kept for later use. Signed-off-by: Bin Meng Reviewed-by: Rick Chen Reviewed-by: Simon Glass --- board/emulation/qemu-riscv/qemu-riscv.c | 24 ------------------------ include/configs/qemu-riscv.h | 10 ---------- 2 files changed, 34 deletions(-) diff --git a/board/emulation/qemu-riscv/qemu-riscv.c b/board/emulation/qemu-riscv/qemu-riscv.c index ae3b7a3295c..f39f3be3663 100644 --- a/board/emulation/qemu-riscv/qemu-riscv.c +++ b/board/emulation/qemu-riscv/qemu-riscv.c @@ -41,30 +41,6 @@ int board_init(void) int board_late_init(void) { - ulong kernel_start; - ofnode chosen_node; - int ret; - - chosen_node = ofnode_path("/chosen"); - if (!ofnode_valid(chosen_node)) { - debug("No chosen node found, can't get kernel start address\n"); - return 0; - } - -#ifdef CONFIG_ARCH_RV64I - ret = ofnode_read_u64(chosen_node, "riscv,kernel-start", - (u64 *)&kernel_start); -#else - ret = ofnode_read_u32(chosen_node, "riscv,kernel-start", - (u32 *)&kernel_start); -#endif - if (ret) { - debug("Can't find kernel start address in device tree\n"); - return 0; - } - - env_set_hex("kernel_start", kernel_start); - return 0; } diff --git a/include/configs/qemu-riscv.h b/include/configs/qemu-riscv.h index 7ec3d12ce10..d5146e70f7b 100644 --- a/include/configs/qemu-riscv.h +++ b/include/configs/qemu-riscv.h @@ -22,22 +22,12 @@ "stderr=serial,vidconsole\0" #define BOOT_TARGET_DEVICES(func) \ - func(QEMU, qemu, na) \ func(VIRTIO, virtio, 0) \ func(SCSI, scsi, 0) \ func(DHCP, dhcp, na) #include -#define BOOTENV_DEV_QEMU(devtypeu, devtypel, instance) \ - "bootcmd_qemu=" \ - "if env exists kernel_start; then " \ - "bootm ${kernel_start} - ${fdtcontroladdr};" \ - "fi;\0" - -#define BOOTENV_DEV_NAME_QEMU(devtypeu, devtypel, instance) \ - "qemu " - #define CFG_EXTRA_ENV_SETTINGS \ CFG_STD_DEVICES_SETTINGS \ "fdt_high=0xffffffffffffffff\0" \ From 02be57caf730e2213bc844bf1dbe58bedd2c3734 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Sun, 23 Jul 2023 12:40:41 +0800 Subject: [PATCH 18/18] riscv: qemu: Enable usb keyboard as an input device This brings PCI xHCI support to QEMU RISC-V and uses a usb keyboard as one of the input devices. Signed-off-by: Bin Meng Reviewed-by: Rick Chen Reviewed-by: Simon Glass --- board/emulation/qemu-riscv/Kconfig | 5 +++++ board/emulation/qemu-riscv/qemu-riscv.c | 5 +++++ doc/board/emulation/qemu-riscv.rst | 5 +++++ include/configs/qemu-riscv.h | 2 +- 4 files changed, 16 insertions(+), 1 deletion(-) diff --git a/board/emulation/qemu-riscv/Kconfig b/board/emulation/qemu-riscv/Kconfig index 7220c55350e..b503578d274 100644 --- a/board/emulation/qemu-riscv/Kconfig +++ b/board/emulation/qemu-riscv/Kconfig @@ -76,5 +76,10 @@ config BOARD_SPECIFIC_OPTIONS # dummy imply VIDEO_BOCHS imply SYS_WHITE_ON_BLACK imply PRE_CONSOLE_BUFFER + imply USB + imply USB_XHCI_HCD + imply USB_XHCI_PCI + imply USB_KEYBOARD + imply CMD_USB endif diff --git a/board/emulation/qemu-riscv/qemu-riscv.c b/board/emulation/qemu-riscv/qemu-riscv.c index f39f3be3663..181abbbf97d 100644 --- a/board/emulation/qemu-riscv/qemu-riscv.c +++ b/board/emulation/qemu-riscv/qemu-riscv.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -41,6 +42,10 @@ int board_init(void) int board_late_init(void) { + /* start usb so that usb keyboard can be used as input device */ + if (CONFIG_IS_ENABLED(USB_KEYBOARD)) + usb_init(); + return 0; } diff --git a/doc/board/emulation/qemu-riscv.rst b/doc/board/emulation/qemu-riscv.rst index 9d21f3270c6..61137bcbf1c 100644 --- a/doc/board/emulation/qemu-riscv.rst +++ b/doc/board/emulation/qemu-riscv.rst @@ -138,6 +138,11 @@ and adding:: -serial stdio -device VGA +In addition, a usb keyboard can be attached to an emulated xHCI controller in +RISC-V virt machine as an option of input devices by adding:: + + -device qemu-xhci,id=xhci -device usb-kbd,bus=xhci.0 + Running with KVM ---------------- diff --git a/include/configs/qemu-riscv.h b/include/configs/qemu-riscv.h index d5146e70f7b..584559cfa32 100644 --- a/include/configs/qemu-riscv.h +++ b/include/configs/qemu-riscv.h @@ -17,7 +17,7 @@ /* Environment options */ -#define CFG_STD_DEVICES_SETTINGS "stdin=serial\0" \ +#define CFG_STD_DEVICES_SETTINGS "stdin=serial,usbkbd\0" \ "stdout=serial,vidconsole\0" \ "stderr=serial,vidconsole\0"