1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * (C) Copyright 2018
4 * Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc
5 */
6
7 #include <common.h>
8 #include <axi.h>
9 #include <dm.h>
10 #include <asm/axi.h>
11
12 /*
13 * This driver implements a AXI bus for the sandbox architecture for testing
14 * purposes.
15 *
16 * The bus forwards every access to it to a special AXI emulation device (which
17 * it gets via the axi_emul_get_ops function) that implements a simple
18 * read/write storage.
19 *
20 * The emulator device must still be contained in the device tree in the usual
21 * way, since configuration data for the storage is read from the DT.
22 */
23
axi_sandbox_read(struct udevice * bus,ulong address,void * data,enum axi_size_t size)24 static int axi_sandbox_read(struct udevice *bus, ulong address, void *data,
25 enum axi_size_t size)
26 {
27 struct axi_emul_ops *ops;
28 struct udevice *emul;
29 int ret;
30
31 /* Get emulator device */
32 ret = axi_sandbox_get_emul(bus, address, size, &emul);
33 if (ret)
34 return ret == -ENODEV ? 0 : ret;
35 /* Forward all reads to the AXI emulator */
36 ops = axi_emul_get_ops(emul);
37 if (!ops || !ops->read)
38 return -ENOSYS;
39
40 return ops->read(emul, address, data, size);
41 }
42
axi_sandbox_write(struct udevice * bus,ulong address,void * data,enum axi_size_t size)43 static int axi_sandbox_write(struct udevice *bus, ulong address, void *data,
44 enum axi_size_t size)
45 {
46 struct axi_emul_ops *ops;
47 struct udevice *emul;
48 int ret;
49
50 /* Get emulator device */
51 ret = axi_sandbox_get_emul(bus, address, size, &emul);
52 if (ret)
53 return ret == -ENODEV ? 0 : ret;
54 /* Forward all writes to the AXI emulator */
55 ops = axi_emul_get_ops(emul);
56 if (!ops || !ops->write)
57 return -ENOSYS;
58
59 return ops->write(emul, address, data, size);
60 }
61
62 static const struct udevice_id axi_sandbox_ids[] = {
63 { .compatible = "sandbox,axi" },
64 { /* sentinel */ }
65 };
66
67 static const struct axi_ops axi_sandbox_ops = {
68 .read = axi_sandbox_read,
69 .write = axi_sandbox_write,
70 };
71
72 U_BOOT_DRIVER(axi_sandbox_bus) = {
73 .name = "axi_sandbox_bus",
74 .id = UCLASS_AXI,
75 .of_match = axi_sandbox_ids,
76 .ops = &axi_sandbox_ops,
77 };
78