blob: e37976f86f02b35d88de203984ccb0a720b22926 [file] [log] [blame]
Mark Kettenis67748ee2021-10-23 16:58:02 +02001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright (C) 2021 Mark Kettenis <kettenis@openbsd.org>
4 */
5
Mark Kettenis67748ee2021-10-23 16:58:02 +02006#include <dm.h>
Mark Kettenis15518962023-01-21 20:27:53 +01007#include <iommu.h>
8#include <lmb.h>
9#include <asm/io.h>
10#include <linux/sizes.h>
11
12#define IOMMU_PAGE_SIZE SZ_4K
13
14struct sandbox_iommu_priv {
15 struct lmb lmb;
16};
17
18static dma_addr_t sandbox_iommu_map(struct udevice *dev, void *addr,
19 size_t size)
20{
21 struct sandbox_iommu_priv *priv = dev_get_priv(dev);
22 phys_addr_t paddr, dva;
23 phys_size_t psize, off;
24
25 paddr = ALIGN_DOWN(virt_to_phys(addr), IOMMU_PAGE_SIZE);
26 off = virt_to_phys(addr) - paddr;
27 psize = ALIGN(size + off, IOMMU_PAGE_SIZE);
28
29 dva = lmb_alloc(&priv->lmb, psize, IOMMU_PAGE_SIZE);
30
31 return dva + off;
32}
33
34static void sandbox_iommu_unmap(struct udevice *dev, dma_addr_t addr,
35 size_t size)
36{
37 struct sandbox_iommu_priv *priv = dev_get_priv(dev);
38 phys_addr_t dva;
39 phys_size_t psize;
40
41 dva = ALIGN_DOWN(addr, IOMMU_PAGE_SIZE);
42 psize = size + (addr - dva);
43 psize = ALIGN(psize, IOMMU_PAGE_SIZE);
44
45 lmb_free(&priv->lmb, dva, psize);
46}
47
48static struct iommu_ops sandbox_iommu_ops = {
49 .map = sandbox_iommu_map,
50 .unmap = sandbox_iommu_unmap,
51};
52
53static int sandbox_iommu_probe(struct udevice *dev)
54{
55 struct sandbox_iommu_priv *priv = dev_get_priv(dev);
56
57 lmb_init(&priv->lmb);
58 lmb_add(&priv->lmb, 0x89abc000, SZ_16K);
59
60 return 0;
61}
Mark Kettenis67748ee2021-10-23 16:58:02 +020062
63static const struct udevice_id sandbox_iommu_ids[] = {
64 { .compatible = "sandbox,iommu" },
65 { /* sentinel */ }
66};
67
68U_BOOT_DRIVER(sandbox_iommu) = {
69 .name = "sandbox_iommu",
70 .id = UCLASS_IOMMU,
71 .of_match = sandbox_iommu_ids,
Mark Kettenis15518962023-01-21 20:27:53 +010072 .priv_auto = sizeof(struct sandbox_iommu_priv),
73 .ops = &sandbox_iommu_ops,
74 .probe = sandbox_iommu_probe,
Mark Kettenis67748ee2021-10-23 16:58:02 +020075};