WIP

Signed-off-by: Marc Zyngier <maz@kernel.org>
diff --git a/arch/arm64/boot/dts/apple/t8103.dtsi b/arch/arm64/boot/dts/apple/t8103.dtsi
index 24e9cb9..3b77b47 100644
--- a/arch/arm64/boot/dts/apple/t8103.dtsi
+++ b/arch/arm64/boot/dts/apple/t8103.dtsi
@@ -13,6 +13,7 @@
 / {
 	compatible = "apple,t8103", "apple,arm-platform";
 
+	interrupt-parent = <&aic>;
 	#address-cells = <2>;
 	#size-cells = <2>;
 
@@ -132,6 +133,27 @@
 			status = "disabled";
 		};
 
+		dart0: dart@681008000 {
+			compatible = "apple,t8103-dart";
+			reg = <0x6 0x81008000 0x0 0x4000>;
+			#iommu-cells = <1>;
+			interrupts = <AIC_IRQ 696 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		dart1: dart@682008000 {
+			compatible = "apple,t8103-dart";
+			reg = <0x6 0x82008000 0x0 0x4000>;
+			#iommu-cells = <1>;
+			interrupts = <AIC_IRQ 699 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		dart2: dart@683008000 {
+			compatible = "apple,t8103-dart";
+			reg = <0x6 0x83008000 0x0 0x4000>;
+			#iommu-cells = <1>;
+			interrupts = <AIC_IRQ 702 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
 		pcie0: pcie@690000000 {
 			compatible = "apple,pcie-m1";
 			reg = <0x6 0x90000000 0x0 0x1000000>,
@@ -141,7 +163,6 @@
 			      <0x6 0x82000000 0x0 0x20000>,
 			      <0x6 0x83000000 0x0 0x20000>;
 
-			interrupt-parent = <&aic>;
 			interrupts = <AIC_IRQ 695 IRQ_TYPE_LEVEL_HIGH>,
 				     <AIC_IRQ 698 IRQ_TYPE_LEVEL_HIGH>,
 				     <AIC_IRQ 701 IRQ_TYPE_LEVEL_HIGH>;
@@ -149,7 +170,12 @@
 			msi-controller;
 			msi-interrupts = <704 32>;
 
-			msi-doorbell = <0x0 0xfffff000>;
+			iommu-map = <0x0 &dart0 0x0 0x100>,
+				    <0x100 &dart0 0x1 0x100>,
+				    <0x200 &dart1 0x2 0x100>,
+				    <0x300 &dart2 0x3 0x100>;
+			iommu-map-mask = <0xfff8>;
+
 			bus-range = <0 15>;
 			#address-cells = <3>;
 			#size-cells = <2>;
diff --git a/drivers/iommu/apple-dart-iommu.c b/drivers/iommu/apple-dart-iommu.c
index 59c2d4d..b46edff 100644
--- a/drivers/iommu/apple-dart-iommu.c
+++ b/drivers/iommu/apple-dart-iommu.c
@@ -21,6 +21,7 @@
 #include <linux/of_address.h>
 #include <linux/of_iommu.h>
 #include <linux/of_platform.h>
+#include <linux/pci.h>
 #include <linux/platform_device.h>
 #include <linux/ratelimit.h>
 
@@ -356,6 +357,7 @@
 	struct apple_dart_domain *dart_domain = to_dart_domain(domain);
 	struct io_pgtable_ops *ops = dart_domain->pgtbl_ops;
 
+	pr_warn("mapping %lx %llx %lx\n", iova, paddr, size);
 	if (!ops)
 		return -ENODEV;
 	if (prot & IOMMU_MMIO)
@@ -421,6 +423,8 @@
 		&io_pgtable_ops_to_pgtable(domain->pgtbl_ops)->cfg;
 	int ret;
 
+	dev_warn(dart->dev, "enabling sid %d\n", sid);
+
 	list_for_each_entry(stream, &domain->streams, stream_head) {
 		if (stream->dart == dart && stream->sid == sid) {
 			stream->num_devices++;
@@ -430,6 +434,8 @@
 
 	spin_lock_irqsave(&dart->lock, flags);
 
+	dev_warn(dart->dev, "used sids %x\n", dart->used_sids);
+
 	if (WARN_ON(dart->used_sids & BIT(sid))) {
 		ret = -EINVAL;
 		goto error;
@@ -449,6 +455,7 @@
 	dart->used_sids |= BIT(sid);
 	spin_unlock_irqrestore(&dart->lock, flags);
 
+	dev_warn(domain->dart->dev, "enabling sid %d\n", stream->sid);
 	apple_dart_hw_clear_all_ttbrs(stream->dart, stream->sid);
 	apple_dart_hw_set_ttbr(stream->dart, stream->sid, 0,
 			       pgtbl_cfg->apple_dart_cfg.ttbr);
@@ -653,8 +660,15 @@
 
 static struct iommu_group *apple_dart_device_group(struct device *dev)
 {
-	/* once we have PCI support this needs to use pci_device_group conditionally */
-	return generic_device_group(dev);
+	struct iommu_group *group;
+
+	dev_warn(dev, "apple_dart_device_group called\n");
+	if (dev_is_pci(dev))
+		group = pci_device_group(dev);
+	else
+		group = generic_device_group(dev);
+
+	return group;
 }
 
 static const struct iommu_ops apple_dart_iommu_ops = {
@@ -722,6 +736,7 @@
 	struct apple_dart *dart;
 	struct device *dev = &pdev->dev;
 
+	dev_warn(&pdev->dev, "probing\n");
 	dart = devm_kzalloc(dev, sizeof(*dart), GFP_KERNEL);
 	if (!dart)
 		return -ENOMEM;
@@ -783,7 +798,13 @@
 		if (ret)
 			return ret;
 	}
+	if (dev->bus->iommu_ops != pci_bus_type.iommu_ops) {
+		ret = bus_set_iommu(&pci_bus_type, &apple_dart_iommu_ops);
+		if (ret)
+			return ret;
+	}
 
+	dev_warn(&pdev->dev, "probed\n");
 	return 0;
 }
 
diff --git a/drivers/pci/controller/pcie-apple-m1.c b/drivers/pci/controller/pcie-apple-m1.c
index d4799e3..ff1b28a 100644
--- a/drivers/pci/controller/pcie-apple-m1.c
+++ b/drivers/pci/controller/pcie-apple-m1.c
@@ -30,21 +30,29 @@
 
 static void apple_msi_top_irq_mask(struct irq_data *d)
 {
+	pr_info("IRQ%d (%ld) masked\n", d->irq, d->parent_data->hwirq);
 	pci_msi_mask_irq(d);
 	irq_chip_mask_parent(d);
 }
 
 static void apple_msi_top_irq_unmask(struct irq_data *d)
 {
+	pr_info("IRQ%d (%ld) unmasked\n", d->irq, d->parent_data->hwirq);
 	pci_msi_unmask_irq(d);
 	irq_chip_unmask_parent(d);
 }
 
+static void apple_msi_top_irq_eoi(struct irq_data *d)
+{
+	pr_info("IRQ%d (%ld) eoi\n", d->irq, d->parent_data->hwirq);
+	irq_chip_eoi_parent(d);
+}
+
 static struct irq_chip apple_msi_top_chip = {
 	.name			= "PCIe MSI",
 	.irq_mask		= apple_msi_top_irq_mask,
 	.irq_unmask		= apple_msi_top_irq_unmask,
-	.irq_eoi		= irq_chip_eoi_parent,
+	.irq_eoi		= apple_msi_top_irq_eoi,
 	.irq_set_affinity	= irq_chip_set_affinity_parent,
 	.irq_set_type		= irq_chip_set_type_parent,
 };
@@ -133,7 +141,22 @@
 	struct fwnode_handle *fwnode = dev_fwnode(pcie->dev);
 	struct device_node *parent_intc;
 	struct irq_domain *parent;
-	int ret;
+	void __iomem *port;
+	int ret, i = 0;
+
+	do {
+		port = devm_of_iomap(pcie->dev, to_of_node(fwnode), i + 3, NULL);
+		if (!IS_ERR(port)) {
+			/* OpenBSD magic */
+			writel(0xfffff000, port + 0x168);
+			writel(0, port + 0x128);
+			writel((5 << 4) | 1, port + 0x124);
+			i++;
+		}
+	} while (!IS_ERR(port));
+
+	if (i == 0)
+		return -ENODEV;
 
 	ret = of_property_read_u32_index(to_of_node(fwnode), "msi-interrupts",
 					 0, &pcie->msi_base);