From: Patrick Wildt Subject: Qualcomm Snapdragon X Elite minimal support To: tech@openbsd.org Date: Wed, 19 Jun 2024 22:28:08 +0200 Hi there, the Qualcomm Snapdragon Elite X machines were released yesterday, I got a Lenovo Yoga Slim 7 today, and it's already booting up with working NVMe, USB and keyboard. Wonder if I beat my last record. This is focused on ACPI mode, which we will only make use of until we can switch to device trees. The GIC bits will require some additional work, but hey, it's day 1. Cheers, Patrick diff --git a/sys/arch/arm64/dev/agintc.c b/sys/arch/arm64/dev/agintc.c index fbd2ec77d9d..e3e72bf24f2 100644 --- a/sys/arch/arm64/dev/agintc.c +++ b/sys/arch/arm64/dev/agintc.c @@ -312,6 +312,7 @@ agintc_attach(struct device *parent, struct device *self, void *aux) uint32_t pmr, oldpmr; uint32_t ctrl, bits; uint32_t affinity; + uint64_t redist_stride; int i, nbits, nintr; int offset, nredist; #ifdef MULTIPROCESSOR @@ -434,15 +435,19 @@ agintc_attach(struct device *parent, struct device *self, void *aux) /* find the redistributors. */ offset = 0; + redist_stride = OF_getpropint64(faa->fa_node, "redistributor-stride", 0); for (nredist = 0; ; nredist++) { - int32_t sz = (64 * 1024 * 2); uint64_t typer; + int32_t sz; typer = bus_space_read_8(sc->sc_iot, sc->sc_redist_base, offset + GICR_TYPER); + sz = (64 * 1024 * 2); if (typer & GICR_TYPER_VLPIS) sz += (64 * 1024 * 2); + if (redist_stride) + sz = redist_stride; #ifdef DEBUG_AGINTC printf("probing redistributor %d %x\n", nredist, offset); @@ -466,14 +471,17 @@ agintc_attach(struct device *parent, struct device *self, void *aux) /* submap and configure the redistributors. */ offset = 0; for (nredist = 0; nredist < sc->sc_num_redist; nredist++) { - int32_t sz = (64 * 1024 * 2); uint64_t typer; + int32_t sz; typer = bus_space_read_8(sc->sc_iot, sc->sc_redist_base, offset + GICR_TYPER); + sz = (64 * 1024 * 2); if (typer & GICR_TYPER_VLPIS) sz += (64 * 1024 * 2); + if (redist_stride) + sz = redist_stride; affinity = bus_space_read_8(sc->sc_iot, sc->sc_redist_base, offset + GICR_TYPER) >> 32; @@ -1605,6 +1613,9 @@ agintc_msi_attach(struct device *parent, struct device *self, void *aux) uint64_t typer; int i, hwcpu; + printf(": skipping\n"); + return; + if (faa->fa_nreg < 1) { printf(": no registers\n"); return; diff --git a/sys/arch/arm64/dev/smmu_acpi.c b/sys/arch/arm64/dev/smmu_acpi.c index b56ac927d88..105e7b68dfe 100644 --- a/sys/arch/arm64/dev/smmu_acpi.c +++ b/sys/arch/arm64/dev/smmu_acpi.c @@ -152,7 +152,8 @@ smmu_acpi_foundqcom(struct aml_node *node, void *arg) if (strcmp(dev, "QCOM0409") == 0 || /* SC8180X/XP */ strcmp(dev, "QCOM0609") == 0 || /* SC8280XP */ - strcmp(dev, "QCOM0809") == 0) /* SC7180 */ + strcmp(dev, "QCOM0809") == 0 || /* SC7180 */ + strcmp(dev, "QCOM0C09") == 0) /* X1E80100 */ sc->sc_is_qcom = 1; return 0; diff --git a/sys/arch/arm64/stand/efiboot/efiacpi.c b/sys/arch/arm64/stand/efiboot/efiacpi.c index 889b6f430d0..2f1d76b8339 100644 --- a/sys/arch/arm64/stand/efiboot/efiacpi.c +++ b/sys/arch/arm64/stand/efiboot/efiacpi.c @@ -400,6 +400,8 @@ efi_acpi_gtdt(struct acpi_table_header *hdr) static int gic_version; static uint64_t gicc_base; +static uint64_t giccr_base; +static uint64_t giccr_size; static uint64_t gicd_base; static uint64_t gicr_base; static uint32_t gicr_size; @@ -436,6 +438,13 @@ efi_acpi_madt_gicc(struct acpi_madt_gicc *gicc) /* Stash GIC information. */ gicc_base = gicc->base_address; + if (gicc->gicr_base_address) { + if (!giccr_base) + giccr_base = gicc->gicr_base_address; + else if (gicc->gicr_base_address) + giccr_base = min(giccr_base, gicc->gicr_base_address); + giccr_size += 0x60000; + } } void @@ -496,7 +505,7 @@ efi_acpi_madt_gic_its(struct acpi_madt_gic_its *its) snprintf(name, sizeof(name), "gic-its@%llx", its->base_address); reg[0] = htobe64(its->base_address); - reg[1] = htobe64(0x20000); + reg[1] = htobe64(0x40000); its_id = htobe32(its->gic_its_id); /* Create "gic-its" node. */ @@ -578,8 +587,13 @@ efi_acpi_madt(struct acpi_table_header *hdr) compat = "arm,gic-v3"; reg[0] = htobe64(gicd_base); reg[1] = htobe64(0x10000); - reg[2] = htobe64(gicr_base); - reg[3] = htobe64(gicr_size); + if (gicr_base) { + reg[2] = htobe64(gicr_base); + reg[3] = htobe64(gicr_size); + } else { + reg[2] = htobe64(giccr_base); + reg[3] = htobe64(giccr_size); + } break; default: return; @@ -590,6 +604,9 @@ efi_acpi_madt(struct acpi_table_header *hdr) fdt_node_set_string_property(node, "compatible", compat); fdt_node_set_property(node, "reg", reg, sizeof(reg)); fdt_node_set_string_property(node, "status", "okay"); + + reg[0] = htobe64(0x40000); + fdt_node_add_property(node, "redistributor-stride", ®[0], sizeof(reg[0])); } static int serial = 0; diff --git a/sys/dev/acpi/qciic.c b/sys/dev/acpi/qciic.c index 8f1eaaccc71..0295a66c6bf 100644 --- a/sys/dev/acpi/qciic.c +++ b/sys/dev/acpi/qciic.c @@ -107,6 +107,7 @@ int qciic_acpi_found_ihidev(struct qciic_softc *, const char *qciic_hids[] = { "QCOM0610", "QCOM0811", + "QCOM0C10", NULL }; diff --git a/sys/dev/acpi/xhci_acpi.c b/sys/dev/acpi/xhci_acpi.c index a1d696e156e..4191d0efc3b 100644 --- a/sys/dev/acpi/xhci_acpi.c +++ b/sys/dev/acpi/xhci_acpi.c @@ -62,6 +62,9 @@ const char *xhci_hids[] = { "QCOM0826", /* SC7180 USB */ "QCOM24B6", /* SDM850 URS */ "QCOM24B7", + "QCOM0C8B", /* X1E80100 URS */ + "QCOM0C8C", + "QCOM0D07", NULL }; @@ -108,7 +111,10 @@ xhci_acpi_attach(struct device *parent, struct device *self, void *aux) strcmp(aaa->aaa_dev, "QCOM068B") == 0 || strcmp(aaa->aaa_dev, "QCOM068C") == 0 || strcmp(aaa->aaa_dev, "QCOM24B6") == 0 || - strcmp(aaa->aaa_dev, "QCOM24B7") == 0) { + strcmp(aaa->aaa_dev, "QCOM24B7") == 0 || + strcmp(aaa->aaa_dev, "QCOM0C8B") == 0 || + strcmp(aaa->aaa_dev, "QCOM0C8C") == 0 || + strcmp(aaa->aaa_dev, "QCOM0D07") == 0) { SIMPLEQ_FOREACH(node, &sc->sc_node->son, sib) { if (strncmp(node->name, "USB", 3) == 0) { aaa->aaa_node = node;