blob: 06c42006ee851f7835c8568b655316a6a0f8ab10 [file] [log] [blame]
Mario Six9a8bcab2018-08-09 14:51:18 +02001// 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 <dm/device-internal.h>
11#include <asm/axi.h>
12
13int axi_sandbox_get_emul(struct udevice *bus, ulong address,
14 enum axi_size_t size, struct udevice **emulp)
15{
16 struct udevice *dev;
17 u32 reg[2];
18 uint offset;
19
20 switch (size) {
21 case AXI_SIZE_8:
22 offset = 1;
23 break;
24 case AXI_SIZE_16:
25 offset = 2;
26 break;
27 case AXI_SIZE_32:
28 offset = 4;
29 break;
30 default:
31 debug("%s: Unknown AXI transfer size '%d'", bus->name, size);
32 offset = 0;
33 }
34
35 /*
36 * Note: device_find_* don't activate the devices; they're activated
37 * as-needed below.
38 */
39 for (device_find_first_child(bus, &dev);
40 dev;
41 device_find_next_child(&dev)) {
42 int ret;
43
44 ret = dev_read_u32_array(dev, "reg", reg, ARRAY_SIZE(reg));
45 if (ret) {
46 debug("%s: Could not read 'reg' property of %s\n",
47 bus->name, dev->name);
48 continue;
49 }
50
51 /*
52 * Does the transfer's address fall into this device's address
53 * space?
54 */
55 if (address >= reg[0] && address <= reg[0] + reg[1] - offset) {
56 /* If yes, activate it... */
57 if (device_probe(dev)) {
58 debug("%s: Could not activate %s\n",
59 bus->name, dev->name);
60 return -ENODEV;
61 }
62
63 /* ...and return it */
64 *emulp = dev;
65 return 0;
66 }
67 }
68
69 return -ENODEV;
70}
71
72int axi_get_store(struct udevice *dev, u8 **storep)
73{
74 struct axi_emul_ops *ops = axi_emul_get_ops(dev);
75
76 if (!ops->get_store)
77 return -ENOSYS;
78
79 return ops->get_store(dev, storep);
80}
81
82UCLASS_DRIVER(axi_emul) = {
83 .id = UCLASS_AXI_EMUL,
84 .name = "axi_emul",
85};