diff options
-rw-r--r-- | MAINTAINERS | 1 | ||||
-rw-r--r-- | arch/arm/Kconfig | 1 | ||||
-rw-r--r-- | cmd/pxe.c | 3 | ||||
-rw-r--r-- | common/spl/spl_semihosting.c | 31 | ||||
-rw-r--r-- | configs/apple_m1_defconfig | 1 | ||||
-rw-r--r-- | configs/qemu_arm64_defconfig | 1 | ||||
-rw-r--r-- | configs/sandbox_defconfig | 1 | ||||
-rw-r--r-- | drivers/gpio/gpio-uclass.c | 64 | ||||
-rw-r--r-- | drivers/pci/Kconfig | 7 | ||||
-rw-r--r-- | drivers/pci/Makefile | 1 | ||||
-rw-r--r-- | drivers/pci/pci-uclass.c | 7 | ||||
-rw-r--r-- | drivers/pci/pci_ftpci100.c | 95 | ||||
-rw-r--r-- | drivers/phy/Kconfig | 10 | ||||
-rw-r--r-- | drivers/phy/Makefile | 1 | ||||
-rw-r--r-- | drivers/phy/phy-apple-atc.c | 56 | ||||
-rw-r--r-- | fs/fat/fat_write.c | 4 | ||||
-rw-r--r-- | include/asm-generic/gpio.h | 2 | ||||
-rw-r--r-- | test/py/tests/test_semihosting/conftest.py | 23 | ||||
-rw-r--r-- | test/py/tests/test_semihosting/test_hostfs.py | 33 |
19 files changed, 329 insertions, 13 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 2db052961b..77a8b0ac21 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -123,6 +123,7 @@ F: configs/apple_m1_defconfig F: drivers/iommu/apple_dart.c F: drivers/nvme/nvme_apple.c F: drivers/pci/pcie_apple.c +F: drivers/phy/phy-apple-atc.c F: drivers/pinctrl/pinctrl-apple.c F: drivers/watchdog/apple_wdt.c F: include/configs/apple.h diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 97c25b4f14..36ee1e9a3c 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -998,6 +998,7 @@ config ARCH_APPLE select OF_BOARD_SETUP select OF_CONTROL select PCI + select PHY select PINCTRL select POSITION_INDEPENDENT select POWER_DOMAIN @@ -333,8 +333,7 @@ static int do_pxe(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) } U_BOOT_CMD(pxe, 4, 1, do_pxe, - "commands to get and boot from pxe files\n" - "To use IPv6 add -ipv6 parameter", + "get and boot from pxe files", "get [" USE_IP6_CMD_PARAM "] - try to retrieve a pxe file using tftp\n" "pxe boot [pxefile_addr_r] [-ipv6] - boot from the pxe file at pxefile_addr_r\n" ); diff --git a/common/spl/spl_semihosting.c b/common/spl/spl_semihosting.c index 5b5e842a11..f7dd289286 100644 --- a/common/spl/spl_semihosting.c +++ b/common/spl/spl_semihosting.c @@ -21,6 +21,23 @@ static int smh_read_full(long fd, void *memp, size_t len) return 0; } +static ulong smh_fit_read(struct spl_load_info *load, ulong file_offset, + ulong size, void *buf) +{ + long fd; + ulong ret; + + fd = smh_open(load->filename, MODE_READ | MODE_BINARY); + if (fd < 0) { + log_debug("could not open %s: %ld\n", load->filename, fd); + return 0; + } + ret = smh_read(fd, buf, size); + smh_close(fd); + + return ret; +} + static int spl_smh_load_image(struct spl_image_info *spl_image, struct spl_boot_device *bootdev) { @@ -49,6 +66,20 @@ static int spl_smh_load_image(struct spl_image_info *spl_image, goto out; } + if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) && + image_get_magic(header) == FDT_MAGIC) { + struct spl_load_info load; + + debug("Found FIT\n"); + load.read = smh_fit_read; + load.bl_len = 1; + load.filename = filename; + load.priv = NULL; + smh_close(fd); + + return spl_load_simple_fit(spl_image, &load, 0, header); + } + ret = spl_parse_image_header(spl_image, bootdev, header); if (ret) { log_debug("failed to parse image header: %d\n", ret); diff --git a/configs/apple_m1_defconfig b/configs/apple_m1_defconfig index 755560971e..d58a9030db 100644 --- a/configs/apple_m1_defconfig +++ b/configs/apple_m1_defconfig @@ -16,6 +16,7 @@ CONFIG_NVME_APPLE=y CONFIG_USB_XHCI_HCD=y CONFIG_USB_XHCI_DWC3=y CONFIG_USB_XHCI_PCI=y +CONFIG_USB_DWC3=y CONFIG_USB_KEYBOARD=y CONFIG_SYS_WHITE_ON_BLACK=y CONFIG_NO_FB_CLEAR=y diff --git a/configs/qemu_arm64_defconfig b/configs/qemu_arm64_defconfig index 94bd966784..2080f5ee9a 100644 --- a/configs/qemu_arm64_defconfig +++ b/configs/qemu_arm64_defconfig @@ -71,4 +71,5 @@ CONFIG_TPM2_MMIO=y CONFIG_USB=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_PCI=y +CONFIG_SEMIHOSTING=y CONFIG_TPM=y diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index f031b50910..259f31f26c 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -231,6 +231,7 @@ CONFIG_MUX_MMIO=y CONFIG_NVME_PCI=y CONFIG_PCI_REGION_MULTI_ENTRY=y CONFIG_PCI_SANDBOX=y +CONFIG_PCI_FTPCI100=y CONFIG_PHY=y CONFIG_PHY_SANDBOX=y CONFIG_PINCTRL=y diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c index 31027f3d99..fc395c97a2 100644 --- a/drivers/gpio/gpio-uclass.c +++ b/drivers/gpio/gpio-uclass.c @@ -28,6 +28,8 @@ DECLARE_GLOBAL_DATA_PTR; +#define GPIO_ALLOC_BITS 32 + /** * gpio_desc_init() - Initialize the GPIO descriptor * @@ -75,6 +77,46 @@ static int gpio_to_device(unsigned int gpio, struct gpio_desc *desc) return -ENOENT; } +/** + * gpio_is_claimed() - Test whether GPIO is claimed by consumer + * + * Test whether GPIO is claimed by consumer already. + * + * @uc_priv: gpio_dev_priv pointer. + * @offset: gpio offset within the device + * @return: true if claimed, false if not claimed + */ +static bool gpio_is_claimed(struct gpio_dev_priv *uc_priv, unsigned int offset) +{ + return !!(uc_priv->claimed[offset / GPIO_ALLOC_BITS] & BIT(offset % GPIO_ALLOC_BITS)); +} + +/** + * gpio_set_claim() - Set GPIO claimed by consumer + * + * Set a bit which indicate the GPIO is claimed by consumer + * + * @uc_priv: gpio_dev_priv pointer. + * @offset: gpio offset within the device + */ +static void gpio_set_claim(struct gpio_dev_priv *uc_priv, unsigned int offset) +{ + uc_priv->claimed[offset / GPIO_ALLOC_BITS] |= BIT(offset % GPIO_ALLOC_BITS); +} + +/** + * gpio_clear_claim() - Clear GPIO claimed by consumer + * + * Clear a bit which indicate the GPIO is claimed by consumer + * + * @uc_priv: gpio_dev_priv pointer. + * @offset: gpio offset within the device + */ +static void gpio_clear_claim(struct gpio_dev_priv *uc_priv, unsigned int offset) +{ + uc_priv->claimed[offset / GPIO_ALLOC_BITS] &= ~BIT(offset % GPIO_ALLOC_BITS); +} + #if CONFIG_IS_ENABLED(DM_GPIO_LOOKUP_LABEL) /** * dm_gpio_lookup_label() - look for name in gpio device @@ -94,7 +136,7 @@ static int dm_gpio_lookup_label(const char *name, *offset = -1; for (i = 0; i < uc_priv->gpio_count; i++) { - if (!uc_priv->name[i]) + if (!gpio_is_claimed(uc_priv, i)) continue; if (!strcmp(name, uc_priv->name[i])) { *offset = i; @@ -350,7 +392,7 @@ int dm_gpio_request(struct gpio_desc *desc, const char *label) int ret; uc_priv = dev_get_uclass_priv(dev); - if (uc_priv->name[desc->offset]) + if (gpio_is_claimed(uc_priv, desc->offset)) return -EBUSY; str = strdup(label); if (!str) @@ -362,6 +404,8 @@ int dm_gpio_request(struct gpio_desc *desc, const char *label) return ret; } } + + gpio_set_claim(uc_priv, desc->offset); uc_priv->name[desc->offset] = str; return 0; @@ -438,7 +482,7 @@ int _dm_gpio_free(struct udevice *dev, uint offset) int ret; uc_priv = dev_get_uclass_priv(dev); - if (!uc_priv->name[offset]) + if (!gpio_is_claimed(uc_priv, offset)) return -ENXIO; if (ops->rfree) { ret = ops->rfree(dev, offset); @@ -446,6 +490,7 @@ int _dm_gpio_free(struct udevice *dev, uint offset) return ret; } + gpio_clear_claim(uc_priv, offset); free(uc_priv->name[offset]); uc_priv->name[offset] = NULL; @@ -480,7 +525,7 @@ static int check_reserved(const struct gpio_desc *desc, const char *func) return -ENOENT; uc_priv = dev_get_uclass_priv(desc->dev); - if (!uc_priv->name[desc->offset]) { + if (!gpio_is_claimed(uc_priv, desc->offset)) { printf("%s: %s: error: gpio %s%d not reserved\n", desc->dev->name, func, uc_priv->bank_name ? uc_priv->bank_name : "", @@ -826,7 +871,7 @@ static int get_function(struct udevice *dev, int offset, bool skip_unused, return -EINVAL; if (namep) *namep = uc_priv->name[offset]; - if (skip_unused && !uc_priv->name[offset]) + if (skip_unused && !gpio_is_claimed(uc_priv, offset)) return GPIOF_UNUSED; if (ops->get_function) { int ret; @@ -1341,6 +1386,14 @@ static int gpio_post_probe(struct udevice *dev) if (!uc_priv->name) return -ENOMEM; + uc_priv->claimed = calloc(DIV_ROUND_UP(uc_priv->gpio_count, + GPIO_ALLOC_BITS), + GPIO_ALLOC_BITS / 8); + if (!uc_priv->claimed) { + free(uc_priv->name); + return -ENOMEM; + } + return gpio_renumber(NULL); } @@ -1353,6 +1406,7 @@ static int gpio_pre_remove(struct udevice *dev) if (uc_priv->name[i]) free(uc_priv->name[i]); } + free(uc_priv->claimed); free(uc_priv->name); return gpio_renumber(dev); diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index a0bf44d38a..463ec47eb9 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -121,11 +121,18 @@ config PCIE_APPLE bool "Enable Apple PCIe driver" depends on ARCH_APPLE imply PCI_INIT_R + select SYS_PCI_64BIT default y help Say Y here if you want to enable PCIe controller support on Apple SoCs. +config PCI_FTPCI100 + bool "Enable Faraday FTPCI100 PCI Bridge Controller driver" + help + Say Y here if you want to enable Faraday FTPCI100 PCI. + FTPCI100 IP is used in SoC chip designs. + config PCI_GT64120 bool "GT64120 PCI support" depends on MIPS diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index a712a317a3..72ef8b4bc7 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -14,6 +14,7 @@ obj-$(CONFIG_PCI) += pci_auto_common.o pci_common.o obj-$(CONFIG_PCIE_ECAM_GENERIC) += pcie_ecam_generic.o obj-$(CONFIG_PCIE_ECAM_SYNQUACER) += pcie_ecam_synquacer.o obj-$(CONFIG_PCIE_APPLE) += pcie_apple.o +obj-$(CONFIG_PCI_FTPCI100) += pci_ftpci100.o obj-$(CONFIG_PCI_GT64120) += pci_gt64120.o obj-$(CONFIG_PCI_MPC85XX) += pci_mpc85xx.o obj-$(CONFIG_PCI_MSC01) += pci_msc01.o diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c index 7f3d6ddf91..0adcdceb1d 100644 --- a/drivers/pci/pci-uclass.c +++ b/drivers/pci/pci-uclass.c @@ -541,14 +541,13 @@ int pci_auto_config_devices(struct udevice *bus) struct pci_child_plat *pplat; unsigned int sub_bus; struct udevice *dev; - int ret; sub_bus = dev_seq(bus); debug("%s: start\n", __func__); pciauto_config_init(hose); - for (ret = device_find_first_child(bus, &dev); - !ret && dev; - ret = device_find_next_child(&dev)) { + for (device_find_first_child(bus, &dev); + dev; + device_find_next_child(&dev)) { unsigned int max_bus; int ret; diff --git a/drivers/pci/pci_ftpci100.c b/drivers/pci/pci_ftpci100.c new file mode 100644 index 0000000000..a177544500 --- /dev/null +++ b/drivers/pci/pci_ftpci100.c @@ -0,0 +1,95 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +#include <common.h> +#include <pci.h> +#include <dm.h> +#include <asm/io.h> + +struct ftpci100_data { + void *reg_base; +}; + +/* AHB Control Registers */ +struct ftpci100_ahbc { + u32 iosize; /* 0x00 - I/O Space Size Signal */ + u32 prot; /* 0x04 - AHB Protection */ + u32 rsved[8]; /* 0x08-0x24 - Reserved */ + u32 conf; /* 0x28 - PCI Configuration */ + u32 data; /* 0x2c - PCI Configuration DATA */ +}; + +static int ftpci100_read_config(const struct udevice *dev, pci_dev_t bdf, + uint offset, ulong *valuep, + enum pci_size_t size) +{ + struct ftpci100_data *priv = dev_get_priv(dev); + struct ftpci100_ahbc *regs = priv->reg_base; + u32 data; + + out_le32(®s->conf, PCI_CONF1_ADDRESS(PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf), offset)); + data = in_le32(®s->data); + *valuep = pci_conv_32_to_size(data, offset, size); + + return 0; +} + +static int ftpci100_write_config(struct udevice *dev, pci_dev_t bdf, + uint offset, ulong value, + enum pci_size_t size) +{ + struct ftpci100_data *priv = dev_get_priv(dev); + struct ftpci100_ahbc *regs = priv->reg_base; + u32 data; + + out_le32(®s->conf, PCI_CONF1_ADDRESS(PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf), offset)); + + if (size == PCI_SIZE_32) { + data = value; + } else { + u32 old = in_le32(®s->data); + + data = pci_conv_size_to_32(old, value, offset, size); + } + + out_le32(®s->data, data); + + return 0; +} + +static int ftpci100_probe(struct udevice *dev) +{ + struct ftpci100_data *priv = dev_get_priv(dev); + struct pci_region *io, *mem; + int count; + + count = pci_get_regions(dev, &io, &mem, NULL); + if (count != 2) { + printf("%s: wrong count of regions: %d != 2\n", dev->name, count); + return -EINVAL; + } + + priv->reg_base = phys_to_virt(io->phys_start); + if (!priv->reg_base) + return -EINVAL; + + return 0; +} + +static const struct dm_pci_ops ftpci100_ops = { + .read_config = ftpci100_read_config, + .write_config = ftpci100_write_config, +}; + +static const struct udevice_id ftpci100_ids[] = { + { .compatible = "faraday,ftpci100" }, + { } +}; + +U_BOOT_DRIVER(ftpci100_pci) = { + .name = "ftpci100_pci", + .id = UCLASS_PCI, + .of_match = ftpci100_ids, + .ops = &ftpci100_ops, + .probe = ftpci100_probe, + .priv_auto = sizeof(struct ftpci100_data), +}; diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index 7a2d54f71d..8ac5769ed9 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig @@ -70,6 +70,16 @@ config AB8500_USB_PHY help Support for the USB OTG PHY in ST-Ericsson AB8500. +config APPLE_ATCPHY + bool "Apple Type-C PHY Driver" + depends on PHY && ARCH_APPLE + default y + help + Support for the Apple Type-C PHY. + + This is a dummy driver since the PHY is initialized + sufficiently by previous stage firmware. + config BCM6318_USBH_PHY bool "BCM6318 USBH PHY support" depends on PHY && ARCH_BMIPS diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile index aca365d219..5d4de86e71 100644 --- a/drivers/phy/Makefile +++ b/drivers/phy/Makefile @@ -12,6 +12,7 @@ obj-$(CONFIG_$(SPL_)PHY) += phy-uclass.o obj-$(CONFIG_$(SPL_)NOP_PHY) += nop-phy.o obj-$(CONFIG_MIPI_DPHY_HELPERS) += phy-core-mipi-dphy.o obj-$(CONFIG_AB8500_USB_PHY) += phy-ab8500-usb.o +obj-$(CONFIG_APPLE_ATCPHY) += phy-apple-atc.o obj-$(CONFIG_BCM6318_USBH_PHY) += bcm6318-usbh-phy.o obj-$(CONFIG_BCM6348_USBH_PHY) += bcm6348-usbh-phy.o obj-$(CONFIG_BCM6358_USBH_PHY) += bcm6358-usbh-phy.o diff --git a/drivers/phy/phy-apple-atc.c b/drivers/phy/phy-apple-atc.c new file mode 100644 index 0000000000..15c5b8a1c2 --- /dev/null +++ b/drivers/phy/phy-apple-atc.c @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2022 Mark Kettenis <kettenis@openbsd.org> + */ + +#include <common.h> +#include <dm.h> +#include <dm/device-internal.h> +#include <generic-phy.h> +#include <reset-uclass.h> + +static const struct phy_ops apple_atcphy_ops = { +}; + +static struct driver apple_atcphy_driver = { + .name = "apple-atcphy", + .id = UCLASS_PHY, + .ops = &apple_atcphy_ops, +}; + +static int apple_atcphy_reset_of_xlate(struct reset_ctl *reset_ctl, + struct ofnode_phandle_args *args) +{ + if (args->args_count != 0) + return -EINVAL; + + return 0; +} + +static const struct reset_ops apple_atcphy_reset_ops = { + .of_xlate = apple_atcphy_reset_of_xlate, +}; + +static int apple_atcphy_reset_probe(struct udevice *dev) +{ + struct udevice *child; + + device_bind(dev, &apple_atcphy_driver, "apple-atcphy", NULL, + dev_ofnode(dev), &child); + + return 0; +} + +static const struct udevice_id apple_atcphy_ids[] = { + { .compatible = "apple,t6000-atcphy" }, + { .compatible = "apple,t8103-atcphy" }, + { } +}; + +U_BOOT_DRIVER(apple_atcphy_reset) = { + .name = "apple-atcphy-reset", + .id = UCLASS_RESET, + .of_match = apple_atcphy_ids, + .ops = &apple_atcphy_reset_ops, + .probe = apple_atcphy_reset_probe, +}; diff --git a/fs/fat/fat_write.c b/fs/fat/fat_write.c index a6294419b8..8b5d669b00 100644 --- a/fs/fat/fat_write.c +++ b/fs/fat/fat_write.c @@ -690,8 +690,8 @@ get_set_cluster(fsdata *mydata, __u32 clustnum, loff_t pos, __u8 *buffer, static u8 *tmpbuf_cluster; unsigned int bytesperclust = mydata->clust_size * mydata->sect_size; __u32 startsect; - loff_t wsize; - int clustcount, i, ret; + loff_t clustcount, wsize; + int i, ret; *gotsize = 0; if (!size) diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h index c4a7fd2843..a21c606f2b 100644 --- a/include/asm-generic/gpio.h +++ b/include/asm-generic/gpio.h @@ -414,6 +414,7 @@ struct dm_gpio_ops { * @gpio_base: Base GPIO number for this device. For the first active device * this will be 0; the numbering for others will follow sequentially so that * @gpio_base for device 1 will equal the number of GPIOs in device 0. + * @claimed: Array of bits indicating which GPIOs in the bank are claimed. * @name: Array of pointers to the name for each GPIO in this bank. The * value of the pointer will be NULL if the GPIO has not been claimed. */ @@ -421,6 +422,7 @@ struct gpio_dev_priv { const char *bank_name; unsigned gpio_count; unsigned gpio_base; + u32 *claimed; char **name; }; diff --git a/test/py/tests/test_semihosting/conftest.py b/test/py/tests/test_semihosting/conftest.py new file mode 100644 index 0000000000..b00d8f4ea9 --- /dev/null +++ b/test/py/tests/test_semihosting/conftest.py @@ -0,0 +1,23 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +"""Fixture for semihosting command test +""" + +import os +import pytest + +@pytest.fixture(scope='session') +def semihosting_data(u_boot_config): + """Set up a file system to be used in semihosting tests + + Args: + u_boot_config -- U-Boot configuration. + """ + image_path = u_boot_config.persistent_data_dir + '/semihosting.txt' + + with open(image_path, 'w', encoding = 'utf-8') as file: + file.write('Das U-Boot\n') + + yield image_path + + os.remove(image_path) diff --git a/test/py/tests/test_semihosting/test_hostfs.py b/test/py/tests/test_semihosting/test_hostfs.py new file mode 100644 index 0000000000..51f6fa7702 --- /dev/null +++ b/test/py/tests/test_semihosting/test_hostfs.py @@ -0,0 +1,33 @@ +# SPDX-License-Identifier: GPL-2.0+ + +""" Unit test for semihosting +""" + +import pytest + +@pytest.mark.buildconfigspec('semihosting') +def test_semihosting_hostfs(u_boot_console, semihosting_data): + """ Unit test for semihosting + + Args: + u_boot_console -- U-Boot console + semihosting_data -- Path to the disk image used for testing. + """ + response = u_boot_console.run_command( + f'load hostfs - $loadaddr {semihosting_data}') + assert '11 bytes read' in response + + response = u_boot_console.run_command( + 'crc32 $loadaddr $filesize') + assert '==> 60cfccfc' in response + + u_boot_console.run_command( + f'save hostfs - $loadaddr {semihosting_data} 11 11') + + response = u_boot_console.run_command( + f'load hostfs - $loadaddr {semihosting_data} 4 13') + assert '4 bytes read' in response + + response = u_boot_console.run_command( + 'crc32 $loadaddr $filesize') + assert '==> e29063ea' in response |