1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Copyright (c) 2014 Google, Inc 4 */ 5 6#define LOG_CATEGORY UCLASS_SIMPLE_BUS 7 8#include <common.h> 9#include <asm/global_data.h> 10#include <dm.h> 11#include <dm/simple_bus.h> 12#include <fdt_support.h> 13 14DECLARE_GLOBAL_DATA_PTR; 15 16fdt_addr_t simple_bus_translate(struct udevice *dev, fdt_addr_t addr) 17{ 18 struct simple_bus_plat *plat = dev_get_uclass_plat(dev); 19 20 if (addr >= plat->base && addr < plat->base + plat->size) 21 addr = (addr - plat->base) + plat->target; 22 23 return addr; 24} 25 26static int simple_bus_post_bind(struct udevice *dev) 27{ 28#if CONFIG_IS_ENABLED(OF_PLATDATA) 29 return 0; 30#else 31 struct simple_bus_plat *plat = dev_get_uclass_plat(dev); 32 int ret; 33 34 if (CONFIG_IS_ENABLED(SIMPLE_BUS_CORRECT_RANGE)) { 35 uint64_t caddr, paddr, len; 36 37 /* only read range index 0 */ 38 ret = fdt_read_range((void *)gd->fdt_blob, dev_of_offset(dev), 39 0, &caddr, &paddr, &len); 40 if (!ret) { 41 plat->base = caddr; 42 plat->target = paddr; 43 plat->size = len; 44 } 45 } else { 46 u32 cell[3]; 47 48 ret = dev_read_u32_array(dev, "ranges", cell, 49 ARRAY_SIZE(cell)); 50 if (!ret) { 51 plat->base = cell[0]; 52 plat->target = cell[1]; 53 plat->size = cell[2]; 54 } 55 } 56 57 return dm_scan_fdt_dev(dev); 58#endif 59} 60 61UCLASS_DRIVER(simple_bus) = { 62 .id = UCLASS_SIMPLE_BUS, 63 .name = "simple_bus", 64 .post_bind = simple_bus_post_bind, 65 .per_device_plat_auto = sizeof(struct simple_bus_plat), 66}; 67 68#if CONFIG_IS_ENABLED(OF_REAL) 69static const struct udevice_id generic_simple_bus_ids[] = { 70 { .compatible = "simple-bus" }, 71 { .compatible = "simple-mfd" }, 72 { } 73}; 74#endif 75 76U_BOOT_DRIVER(simple_bus) = { 77 .name = "simple_bus", 78 .id = UCLASS_SIMPLE_BUS, 79 .of_match = of_match_ptr(generic_simple_bus_ids), 80 .flags = DM_FLAG_PRE_RELOC, 81}; 82