From 815ce125a4a0a2f17ed5fee900b80954542b360c Mon Sep 17 00:00:00 2001 From: Mark Kettenis Date: Fri, 14 Jul 2023 21:15:16 +0200 Subject: pci: apple: Enable CONFIG_SYS_PCI_64BIT The Apple hardware supports 64-bit prefetchable memory windows so enable CONFIG_SYS_PCI_64BIT. This fixes BAR assignments for the Broadcom Ethernet controller used in some of the desktop machines. Signed-off-by: Mark Kettenis --- drivers/pci/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index a0bf44d38a9..74e514adbe0 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -121,6 +121,7 @@ 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 -- cgit v1.2.3 From b99c6357877da2829dc7fd73a50048e83abc53e2 Mon Sep 17 00:00:00 2001 From: Mark Kettenis Date: Fri, 14 Jul 2023 22:21:42 +0200 Subject: phy: Add support for the Apple Type-C PHY This is merely a dummy driver that makes sure the DWC3 XHCI driver finds its reset and PHY controllers. We rely on iBoot to set up the PHY for us. Signed-off-by: Mark Kettenis --- drivers/phy/Kconfig | 10 ++++++++ drivers/phy/Makefile | 1 + drivers/phy/phy-apple-atc.c | 56 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+) create mode 100644 drivers/phy/phy-apple-atc.c (limited to 'drivers') diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index 7a2d54f71d2..8ac5769ed9a 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 aca365d219c..5d4de86e71a 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 00000000000..15c5b8a1c2d --- /dev/null +++ b/drivers/phy/phy-apple-atc.c @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2022 Mark Kettenis + */ + +#include +#include +#include +#include +#include + +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, +}; -- cgit v1.2.3 From 8ee830d8983763575aad62c37394ec954a76abc4 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 16 Jul 2023 17:53:24 +0200 Subject: pci: Fix device_find_first_child() return value handling This function only ever returns 0, but may not assign the second parameter. Same thing for device_find_next_child(). Do not assign ret to stop proliferation of this misuse. Reported-by: Jonas Karlman Signed-off-by: Marek Vasut Reviewed-by: Simon Glass --- drivers/pci/pci-uclass.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c index 7f3d6ddf91c..0adcdceb1d3 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; -- cgit v1.2.3 From 852467de92c38c6c5b9338dd75989e306461dd08 Mon Sep 17 00:00:00 2001 From: Sergei Antonov Date: Sun, 30 Jul 2023 21:17:09 +0300 Subject: pci: ftpci100: add new driver implementation Add a new DM driver supporting FTPCI100 IP used in SoC designs. This implementation is not based on the old non-DM ftpci100 code dropped from U-Boot. Enable the driver in sandbox_defconfig to test compilability. Signed-off-by: Sergei Antonov --- drivers/pci/Kconfig | 6 +++ drivers/pci/Makefile | 1 + drivers/pci/pci_ftpci100.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 102 insertions(+) create mode 100644 drivers/pci/pci_ftpci100.c (limited to 'drivers') diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index 74e514adbe0..463ec47eb92 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -127,6 +127,12 @@ config PCIE_APPLE 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 a712a317a39..72ef8b4bc77 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_ftpci100.c b/drivers/pci/pci_ftpci100.c new file mode 100644 index 00000000000..a1775445005 --- /dev/null +++ b/drivers/pci/pci_ftpci100.c @@ -0,0 +1,95 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include +#include +#include + +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), +}; -- cgit v1.2.3 From aaf5b5923054efbf1244dc7fbae68d0bd2a03cf7 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Wed, 2 Aug 2023 01:26:02 +0200 Subject: gpio: Use separate bitfield array to indicate GPIO is claimed The current gpio-uclass design uses name field in struct gpio_dev_priv as an indicator that GPIO is claimed by consumer. This overloads the function of name field and does not work well for named pins not configured as GPIO pins. Introduce separate bitfield array as the claim indicator. This unbreaks dual-purpose AF and GPIO operation on STM32MP since commit 2c38f7c31806 ("pinctrl: pinctrl_stm32: Populate uc_priv->name[] with pinmux node's name") where any pin which has already been configured as AF could no longer be claimed as dual-purpose GPIO. This is important for pins like STM32 MMCI st,cmd-gpios . Signed-off-by: Marek Vasut Reviewed-by: Simon Glass --- drivers/gpio/gpio-uclass.c | 64 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 59 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c index 31027f3d990..fc395c97a28 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); -- cgit v1.2.3