]>
Commit | Line | Data |
---|---|---|
9a8bcabd MS |
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 | ||
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 | ||
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 | }; |