From: Nicolin Chen <nicolinc@nvidia.com>
Add ACPI DSDT support for Tegra241 CMDQV when the SMMUv3 instance is
created with tegra241-cmdqv.
The SMMUv3 device identifier is used as the ACPI _UID. This matches
the Identifier field of the corresponding SMMUv3 IORT node, allowing
the CMDQV DSDT device to be correctly associated with its SMMU.
Because virt-acpi-build.c now includes CONFIG_DEVICES via the Tegra241
CMDQV header, the Meson file entry is updated to build it as part of
arm_ss instead of arm_common_ss
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
---
hw/arm/virt-acpi-build.c | 52 ++++++++++++++++++++++++++++++++++++++++
hw/arm/trace-events | 1 +
2 files changed, 53 insertions(+)
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 20605185c5..462faa6a2b 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -65,6 +65,9 @@
#include "target/arm/cpu.h"
#include "target/arm/multiprocessing.h"
+#include "smmuv3-accel.h"
+#include "tegra241-cmdqv.h"
+
#define ARM_SPI_BASE 32
#define ACPI_BUILD_TABLE_SIZE 0x20000
@@ -1113,6 +1116,51 @@ static void build_fadt_rev6(GArray *table_data, BIOSLinker *linker,
build_fadt(table_data, linker, &fadt, vms->oem_id, vms->oem_table_id);
}
+static void acpi_dsdt_add_tegra241_cmdqv(Aml *scope, VirtMachineState *vms)
+{
+ for (int i = 0; i < vms->smmuv3_devices->len; i++) {
+ Object *obj = OBJECT(g_ptr_array_index(vms->smmuv3_devices, i));
+ PlatformBusDevice *pbus;
+ Aml *dev, *crs, *addr;
+ SysBusDevice *sbdev;
+ hwaddr base;
+ uint32_t id;
+ int irq;
+
+ if (smmuv3_accel_cmdqv_type(obj) != SMMUV3_CMDQV_TEGRA241) {
+ continue;
+ }
+ id = object_property_get_uint(obj, "identifier", &error_abort);
+ pbus = PLATFORM_BUS_DEVICE(vms->platform_bus_dev);
+ sbdev = SYS_BUS_DEVICE(obj);
+ base = platform_bus_get_mmio_addr(pbus, sbdev, 1);
+ base += vms->memmap[VIRT_PLATFORM_BUS].base;
+ irq = platform_bus_get_irqn(pbus, sbdev, NUM_SMMU_IRQS);
+ irq += vms->irqmap[VIRT_PLATFORM_BUS];
+ irq += ARM_SPI_BASE;
+
+ dev = aml_device("CV%.02u", id);
+ aml_append(dev, aml_name_decl("_HID", aml_string("NVDA200C")));
+ aml_append(dev, aml_name_decl("_UID", aml_int(id)));
+ 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, base,
+ 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 *)&irq, 1));
+ aml_append(dev, aml_name_decl("_CRS", crs));
+
+ aml_append(scope, dev);
+
+ trace_virt_acpi_dsdt_tegra241_cmdqv(id, base, irq);
+ }
+}
+
/* DSDT */
static void
build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
@@ -1177,6 +1225,10 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
acpi_dsdt_add_tpm(scope, vms);
#endif
+ if (!vms->legacy_smmuv3_present) {
+ acpi_dsdt_add_tegra241_cmdqv(scope, vms);
+ }
+
aml_append(dsdt, scope);
pci0_scope = aml_scope("\\_SB.PCI0");
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"
--
2.43.0