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#define LOG_CATEGORY UCLASS_AXI_EMUL 8 9#include <common.h> 10#include <axi.h> 11#include <dm.h> 12#include <log.h> 13#include <dm/device-internal.h> 14#include <asm/axi.h> 15 16int axi_sandbox_get_emul(struct udevice *bus, ulong address, 17 const enum axi_size_t size, struct udevice **emulp) 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 75int 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 85UCLASS_DRIVER(axi_emul) = { 86 .id = UCLASS_AXI_EMUL, 87 .name = "axi_emul", 88}; 89