Skip to content

Commit fac0c32

Browse files
committed
Revert "Revert "drivers: iommu: Add BCM2712 IOMMU""
This reverts commit 9ef6dbb.
1 parent bd0197e commit fac0c32

File tree

5 files changed

+795
-0
lines changed

5 files changed

+795
-0
lines changed

drivers/iommu/Kconfig

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -487,4 +487,11 @@ config SPRD_IOMMU
487487

488488
Say Y here if you want to use the multimedia devices listed above.
489489

490+
config BCM2712_IOMMU
491+
tristate "BCM2712 IOMMU driver"
492+
depends on ARM64 && ARCH_BCM
493+
select IOMMU_API
494+
help
495+
IOMMU driver for BCM2712
496+
490497
endif # IOMMU_SUPPORT

drivers/iommu/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,4 @@ obj-$(CONFIG_VIRTIO_IOMMU) += virtio-iommu.o
2929
obj-$(CONFIG_IOMMU_SVA) += iommu-sva.o io-pgfault.o
3030
obj-$(CONFIG_SPRD_IOMMU) += sprd-iommu.o
3131
obj-$(CONFIG_APPLE_DART) += apple-dart.o
32+
obj-$(CONFIG_BCM2712_IOMMU) += bcm2712-iommu.o bcm2712-iommu-cache.o

drivers/iommu/bcm2712-iommu-cache.c

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
// SPDX-License-Identifier: GPL-2.0-only
2+
/*
3+
* IOMMU driver for BCM2712
4+
*
5+
* Copyright (c) 2023 Raspberry Pi Ltd.
6+
*/
7+
8+
#include "bcm2712-iommu.h"
9+
10+
#include <linux/err.h>
11+
#include <linux/of_platform.h>
12+
#include <linux/platform_device.h>
13+
#include <linux/spinlock.h>
14+
15+
#define MMUC_CONTROL_ENABLE 1
16+
#define MMUC_CONTROL_FLUSH 2
17+
#define MMUC_CONTROL_FLUSHING 4
18+
19+
void bcm2712_iommu_cache_flush(struct bcm2712_iommu_cache *cache)
20+
{
21+
unsigned long flags;
22+
int i;
23+
24+
spin_lock_irqsave(&cache->hw_lock, flags);
25+
if (cache->reg_base) {
26+
/* Enable and flush the TLB cache */
27+
writel(MMUC_CONTROL_ENABLE | MMUC_CONTROL_FLUSH,
28+
cache->reg_base);
29+
30+
/* Wait for flush to complete: it should be very quick */
31+
for (i = 0; i < 1024; i++) {
32+
if (!(MMUC_CONTROL_FLUSHING & readl(cache->reg_base)))
33+
break;
34+
cpu_relax();
35+
}
36+
}
37+
spin_unlock_irqrestore(&cache->hw_lock, flags);
38+
}
39+
40+
static int bcm2712_iommu_cache_probe(struct platform_device *pdev)
41+
{
42+
struct bcm2712_iommu_cache *cache;
43+
44+
dev_info(&pdev->dev, __func__);
45+
cache = devm_kzalloc(&pdev->dev, sizeof(*cache), GFP_KERNEL);
46+
if (!cache)
47+
return -ENOMEM;
48+
49+
cache->dev = &pdev->dev;
50+
platform_set_drvdata(pdev, cache);
51+
spin_lock_init(&cache->hw_lock);
52+
53+
/* Get IOMMUC registers; we only use the first register (IOMMUC_CTRL) */
54+
cache->reg_base = devm_platform_ioremap_resource(pdev, 0);
55+
if (IS_ERR(cache->reg_base)) {
56+
dev_err(&pdev->dev, "Failed to get IOMMU Cache registers address\n");
57+
cache->reg_base = NULL;
58+
}
59+
return 0;
60+
}
61+
62+
static const struct of_device_id bcm2712_iommu_cache_of_match[] = {
63+
{
64+
. compatible = "brcm,bcm2712-iommuc"
65+
},
66+
{ /* sentinel */ },
67+
};
68+
69+
static struct platform_driver bcm2712_iommu_cache_driver = {
70+
.probe = bcm2712_iommu_cache_probe,
71+
.driver = {
72+
.name = "bcm2712-iommu-cache",
73+
.of_match_table = bcm2712_iommu_cache_of_match
74+
},
75+
};
76+
77+
builtin_platform_driver(bcm2712_iommu_cache_driver);

0 commit comments

Comments
 (0)