aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2023-08-15 10:39:41 -0400
committerTom Rini <trini@konsulko.com>2023-08-15 10:39:41 -0400
commitbdc682437a67b47a382edfa30f58f8271b8acfed (patch)
treea57e22d5bb8a7b789878f455397d9d76b6fdb170 /drivers
parent51171cdd6dc9af8e74bbdb1f3e46c15187f7e979 (diff)
parentaaf5b5923054efbf1244dc7fbae68d0bd2a03cf7 (diff)
Merge branch '2023-08-14-assorted-general-updates' into next
- Assorted PCI-related fixes, add Apple Type-C PHY support, semihosting updates, fix a FAT corner-case, update the help on the pxe cmd and clean up the gpio uclass slightly.
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpio/gpio-uclass.c64
-rw-r--r--drivers/pci/Kconfig7
-rw-r--r--drivers/pci/Makefile1
-rw-r--r--drivers/pci/pci-uclass.c7
-rw-r--r--drivers/pci/pci_ftpci100.c95
-rw-r--r--drivers/phy/Kconfig10
-rw-r--r--drivers/phy/Makefile1
-rw-r--r--drivers/phy/phy-apple-atc.c56
8 files changed, 232 insertions, 9 deletions
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(&regs->conf, PCI_CONF1_ADDRESS(PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf), offset));
+ data = in_le32(&regs->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(&regs->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(&regs->data);
+
+ data = pci_conv_size_to_32(old, value, offset, size);
+ }
+
+ out_le32(&regs->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,
+};