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