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);