iommu: Add IOMMU uclass

This uclass is intended to manage IOMMUs on systems where the
IOMMUs are not in bypass mode by default.  In that case U-Boot
cannot ignore the IOMMUs if it wants to use devices that need
to do DMA and sit behind such an IOMMU.

This initial IOMMU uclass implementation does not implement and
device ops and is intended for IOMMUs that have a bypass mode
that does not require address translation.  Support for IOMMUs
that do require address translation is planned and device ops
will be defined when support for such IOMMUs will be added.

Signed-off-by: Mark Kettenis <kettenis@openbsd.org>
Reviewed-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
Mark Kettenis
2021-10-23 16:58:01 +02:00
committed by Tom Rini
parent d73db30427
commit 40dbf03d7d
9 changed files with 299 additions and 0 deletions

View File

@@ -50,6 +50,8 @@ source "drivers/i2c/Kconfig"
source "drivers/input/Kconfig"
source "drivers/iommu/Kconfig"
source "drivers/led/Kconfig"
source "drivers/mailbox/Kconfig"

View File

@@ -102,6 +102,7 @@ obj-y += mtd/
obj-y += pwm/
obj-y += reset/
obj-y += input/
obj-y += iommu/
# SOC specific infrastructure drivers.
obj-y += smem/
obj-y += thermal/

View File

@@ -28,6 +28,7 @@
#include <dm/uclass.h>
#include <dm/uclass-internal.h>
#include <dm/util.h>
#include <iommu.h>
#include <linux/err.h>
#include <linux/list.h>
#include <power-domain.h>
@@ -543,6 +544,13 @@ int device_probe(struct udevice *dev)
goto fail;
}
if (CONFIG_IS_ENABLED(IOMMU) && dev->parent &&
(device_get_uclass_id(dev) != UCLASS_IOMMU)) {
ret = dev_iommu_enable(dev);
if (ret)
goto fail;
}
ret = device_get_dma_constraints(dev);
if (ret)
goto fail;

17
drivers/iommu/Kconfig Normal file
View File

@@ -0,0 +1,17 @@
#
# IOMMU devices
#
menu "IOMMU device drivers"
config IOMMU
bool "Enable Driver Model for IOMMU drivers"
depends on DM
help
Enable driver model for IOMMU devices. An IOMMU maps device
virtiual memory addresses to physical addresses. Devices
that sit behind an IOMMU can typically only access physical
memory if the IOMMU has been programmed to allow access to
that memory.
endmenu

3
drivers/iommu/Makefile Normal file
View File

@@ -0,0 +1,3 @@
# SPDX-License-Identifier: GPL-2.0+
obj-$(CONFIG_IOMMU) += iommu-uclass.o

View File

@@ -0,0 +1,45 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2021 Mark Kettenis <kettenis@openbsd.org>
*/
#define LOG_CATEGORY UCLASS_IOMMU
#include <common.h>
#include <dm.h>
#if (CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA))
int dev_iommu_enable(struct udevice *dev)
{
struct ofnode_phandle_args args;
struct udevice *dev_iommu;
int i, count, ret = 0;
count = dev_count_phandle_with_args(dev, "iommus",
"#iommu-cells", 0);
for (i = 0; i < count; i++) {
ret = dev_read_phandle_with_args(dev, "iommus",
"#iommu-cells", 0, i, &args);
if (ret) {
debug("%s: dev_read_phandle_with_args failed: %d\n",
__func__, ret);
return ret;
}
ret = uclass_get_device_by_ofnode(UCLASS_IOMMU, args.node,
&dev_iommu);
if (ret) {
debug("%s: uclass_get_device_by_ofnode failed: %d\n",
__func__, ret);
return ret;
}
}
return 0;
}
#endif
UCLASS_DRIVER(iommu) = {
.id = UCLASS_IOMMU,
.name = "iommu",
};