diff options
author | Tom Rini <trini@konsulko.com> | 2024-10-27 17:14:22 -0600 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2024-10-27 18:44:13 -0600 |
commit | 2800aecce08b47b169d8e9824dd23b1297b2cedc (patch) | |
tree | 2f8b61eaee1520b6fd5bd6cedb111aa3ee13f2f7 /drivers/usb/host/xhci-generic.c | |
parent | 568407fab5336c00cf0265e9de6c507078988504 (diff) | |
parent | 25081abf081880930365ff2bc6afc6c0273ca4bf (diff) |
Merge patch series "Implement ACPI on aarch64"
Patrick Rudolph <patrick.rudolph@9elements.com> says:
Based on the existing work done by Simon Glass this series adds
support for booting aarch64 devices using ACPI only.
As first target QEMU SBSA support is added, which relies on ACPI
only to boot an OS. As secondary target the Raspberry Pi4 was used,
which is broadly available and allows easy testing of the proposed
solution.
The series is split into ACPI cleanups and code movements, adding
Arm specific ACPI tables and finally SoC and mainboard related
changes to boot a Linux on the QEMU SBSA and RPi4. Currently only the
mandatory ACPI tables are supported, allowing to boot into Linux
without errors.
The QEMU SBSA support is feature complete and provides the same
functionality as the EDK2 implementation.
The changes were tested on real hardware as well on QEMU v9.0:
qemu-system-aarch64 -machine sbsa-ref -nographic -cpu cortex-a57 \
-pflash secure-world.rom \
-pflash unsecure-world.rom
qemu-system-aarch64 -machine raspi4b -kernel u-boot.bin -cpu cortex-a72 \
-smp 4 -m 2G -drive file=raspbian.img,format=raw,index=0 \
-dtb bcm2711-rpi-4-b.dtb -nographic
Tested against FWTS V24.03.00.
Known issues:
- The QEMU rpi4 support is currently limited as it doesn't emulate PCI,
USB or ethernet devices!
- The SMP bringup doesn't work on RPi4, but works in QEMU (Possibly
cache related).
- PCI on RPI4 isn't working on real hardware since the pcie_brcmstb
Linux kernel module doesn't support ACPI yet.
Link: https://lore.kernel.org/r/20241023132116.970117-1-patrick.rudolph@9elements.com
Diffstat (limited to 'drivers/usb/host/xhci-generic.c')
-rw-r--r-- | drivers/usb/host/xhci-generic.c | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/drivers/usb/host/xhci-generic.c b/drivers/usb/host/xhci-generic.c new file mode 100644 index 00000000000..355d4883176 --- /dev/null +++ b/drivers/usb/host/xhci-generic.c @@ -0,0 +1,75 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2024 9elements GmbH + * + * GENERIC USB HOST xHCI Controller + */ +#include <dm.h> +#include <fdtdec.h> +#include <log.h> +#include <usb.h> +#include <asm/io.h> +#include <dm/device_compat.h> +#include <usb/xhci.h> + +struct generic_xhci_plat { + fdt_addr_t hcd_base; +}; + +/** + * Contains pointers to register base addresses + * for the usb controller. + */ +struct generic_xhci { + struct xhci_ctrl ctrl; /* Needs to come first in this struct! */ + struct usb_plat usb_plat; + struct xhci_hccr *hcd; +}; + +static int xhci_usb_probe(struct udevice *dev) +{ + struct generic_xhci_plat *plat = dev_get_plat(dev); + struct generic_xhci *ctx = dev_get_priv(dev); + struct xhci_hcor *hcor; + int len; + + ctx->hcd = (struct xhci_hccr *)phys_to_virt(plat->hcd_base); + len = HC_LENGTH(xhci_readl(&ctx->hcd->cr_capbase)); + hcor = (struct xhci_hcor *)((uintptr_t)ctx->hcd + len); + + return xhci_register(dev, ctx->hcd, hcor); +} + +static int xhci_usb_of_to_plat(struct udevice *dev) +{ + struct generic_xhci_plat *plat = dev_get_plat(dev); + + /* + * Get the base address for XHCI controller from the device node + */ + plat->hcd_base = dev_read_addr(dev); + if (plat->hcd_base == FDT_ADDR_T_NONE) { + dev_dbg(dev, "Can't get the XHCI register base address\n"); + return -ENXIO; + } + + return 0; +} + +static const struct udevice_id xhci_usb_ids[] = { + { .compatible = "generic-xhci" }, + { } +}; + +U_BOOT_DRIVER(usb_xhci) = { + .name = "xhci_generic", + .id = UCLASS_USB, + .of_match = xhci_usb_ids, + .of_to_plat = xhci_usb_of_to_plat, + .probe = xhci_usb_probe, + .remove = xhci_deregister, + .ops = &xhci_usb_ops, + .plat_auto = sizeof(struct generic_xhci_plat), + .priv_auto = sizeof(struct generic_xhci), + .flags = DM_FLAG_ALLOC_PRIV_DMA, +}; |