From: Nicolin Chen <[email protected]> Add ACPI DSDT support for Tegra241 CMDQV when the SMMUv3 instance is created with tegra241-cmdqv=on.
Signed-off-by: Nicolin Chen <[email protected]> Signed-off-by: Shameer Kolothum <[email protected]> --- hw/arm/trace-events | 1 + hw/arm/virt-acpi-build.c | 74 ++++++++++++++++++++++++++++++++++++++++ include/hw/arm/virt.h | 2 ++ 3 files changed, 77 insertions(+) diff --git a/hw/arm/trace-events b/hw/arm/trace-events index ef495c040c..e7e3ccfe9f 100644 --- a/hw/arm/trace-events +++ b/hw/arm/trace-events @@ -9,6 +9,7 @@ omap1_lpg_led(const char *onoff) "omap1 LPG: LED is %s" # virt-acpi-build.c virt_acpi_setup(void) "No fw cfg or ACPI disabled. Bailing out." +virt_acpi_dsdt_tegra241_cmdqv(int smmu_id, uint64_t base, uint32_t irq) "DSDT: add cmdqv node for (id=%d), base=0x%" PRIx64 ", irq=%d" # smmu-common.c smmu_add_mr(const char *name) "%s" diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c index 4f8d36dae0..11494b29ad 100644 --- a/hw/arm/virt-acpi-build.c +++ b/hw/arm/virt-acpi-build.c @@ -1115,6 +1115,78 @@ static void build_fadt_rev6(GArray *table_data, BIOSLinker *linker, build_fadt(table_data, linker, &fadt, vms->oem_id, vms->oem_table_id); } +static int smmuv3_cmdqv_devices(Object *obj, void *opaque) +{ + VirtMachineState *vms = VIRT_MACHINE(qdev_get_machine()); + GArray *sdev_blob = opaque; + PlatformBusDevice *pbus; + AcpiSMMUv3Dev sdev; + SysBusDevice *sbdev; + + if (!object_dynamic_cast(obj, TYPE_ARM_SMMUV3)) { + return 0; + } + + if (!object_property_get_bool(obj, "tegra241-cmdqv", NULL)) { + return 0; + } + + pbus = PLATFORM_BUS_DEVICE(vms->platform_bus_dev); + sbdev = SYS_BUS_DEVICE(obj); + sdev.base = platform_bus_get_mmio_addr(pbus, sbdev, 1); + sdev.base += vms->memmap[VIRT_PLATFORM_BUS].base; + sdev.irq = platform_bus_get_irqn(pbus, sbdev, NUM_SMMU_IRQS); + sdev.irq += vms->irqmap[VIRT_PLATFORM_BUS]; + sdev.irq += ARM_SPI_BASE; + g_array_append_val(sdev_blob, sdev); + return 0; +} + +static void acpi_dsdt_add_tegra241_cmdqv(Aml *scope, VirtMachineState *vms) +{ + GArray *smmuv3_devs = g_array_new(false, true, sizeof(AcpiSMMUv3Dev)); + int i; + + if (vms->legacy_smmuv3_present) { + return; + } + + object_child_foreach_recursive(object_get_root(), smmuv3_cmdqv_devices, + smmuv3_devs); + + for (i = 0; i < smmuv3_devs->len; i++) { + uint32_t identifier = i; + AcpiSMMUv3Dev *sdev; + Aml *dev, *crs, *addr; + + sdev = &g_array_index(smmuv3_devs, AcpiSMMUv3Dev, i); + + dev = aml_device("CV%.02u", identifier); + aml_append(dev, aml_name_decl("_HID", aml_string("NVDA200C"))); + if (vms->its) { + identifier++; + } + aml_append(dev, aml_name_decl("_UID", aml_int(identifier))); + aml_append(dev, aml_name_decl("_CCA", aml_int(1))); + + crs = aml_resource_template(); + addr = aml_qword_memory(AML_POS_DECODE, AML_MIN_FIXED, AML_MAX_FIXED, + AML_CACHEABLE, AML_READ_WRITE, 0x0, sdev->base, + sdev->base + TEGRA241_CMDQV_IO_LEN - 0x1, 0x0, + TEGRA241_CMDQV_IO_LEN); + aml_append(crs, addr); + aml_append(crs, aml_interrupt(AML_CONSUMER, AML_EDGE, + AML_ACTIVE_HIGH, AML_EXCLUSIVE, + (uint32_t *)&sdev->irq, 1)); + aml_append(dev, aml_name_decl("_CRS", crs)); + + aml_append(scope, dev); + + trace_virt_acpi_dsdt_tegra241_cmdqv(identifier, sdev->base, sdev->irq); + } + g_array_free(smmuv3_devs, true); +} + /* DSDT */ static void build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) @@ -1179,6 +1251,8 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) acpi_dsdt_add_tpm(scope, vms); #endif + acpi_dsdt_add_tegra241_cmdqv(scope, vms); + aml_append(dsdt, scope); pci0_scope = aml_scope("\\_SB.PCI0"); diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h index efbc1758c5..842143cc85 100644 --- a/include/hw/arm/virt.h +++ b/include/hw/arm/virt.h @@ -46,6 +46,8 @@ #define NUM_VIRTIO_TRANSPORTS 32 #define NUM_SMMU_IRQS 4 +#define TEGRA241_CMDQV_IO_LEN 0x50000 + /* See Linux kernel arch/arm64/include/asm/pvclock-abi.h */ #define PVTIME_SIZE_PER_CPU 64 -- 2.43.0
