xref: /openbmc/u-boot/drivers/axi/axi_sandbox.c (revision b71d9e8b)
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