18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright (C) 2016 Imagination Technologies 48c2ecf20Sopenharmony_ci * Author: Paul Burton <paul.burton@mips.com> 58c2ecf20Sopenharmony_ci * 68c2ecf20Sopenharmony_ci * pcibios_align_resource taken from arch/arm/kernel/bios32.c. 78c2ecf20Sopenharmony_ci */ 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci#include <linux/pci.h> 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci/* 128c2ecf20Sopenharmony_ci * We need to avoid collisions with `mirrored' VGA ports 138c2ecf20Sopenharmony_ci * and other strange ISA hardware, so we always want the 148c2ecf20Sopenharmony_ci * addresses to be allocated in the 0x000-0x0ff region 158c2ecf20Sopenharmony_ci * modulo 0x400. 168c2ecf20Sopenharmony_ci * 178c2ecf20Sopenharmony_ci * Why? Because some silly external IO cards only decode 188c2ecf20Sopenharmony_ci * the low 10 bits of the IO address. The 0x00-0xff region 198c2ecf20Sopenharmony_ci * is reserved for motherboard devices that decode all 16 208c2ecf20Sopenharmony_ci * bits, so it's ok to allocate at, say, 0x2800-0x28ff, 218c2ecf20Sopenharmony_ci * but we want to try to avoid allocating at 0x2900-0x2bff 228c2ecf20Sopenharmony_ci * which might have be mirrored at 0x0100-0x03ff.. 238c2ecf20Sopenharmony_ci */ 248c2ecf20Sopenharmony_ciresource_size_t pcibios_align_resource(void *data, const struct resource *res, 258c2ecf20Sopenharmony_ci resource_size_t size, resource_size_t align) 268c2ecf20Sopenharmony_ci{ 278c2ecf20Sopenharmony_ci struct pci_dev *dev = data; 288c2ecf20Sopenharmony_ci resource_size_t start = res->start; 298c2ecf20Sopenharmony_ci struct pci_host_bridge *host_bridge; 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci if (res->flags & IORESOURCE_IO && start & 0x300) 328c2ecf20Sopenharmony_ci start = (start + 0x3ff) & ~0x3ff; 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_ci start = (start + align - 1) & ~(align - 1); 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_ci host_bridge = pci_find_host_bridge(dev->bus); 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_ci if (host_bridge->align_resource) 398c2ecf20Sopenharmony_ci return host_bridge->align_resource(dev, res, 408c2ecf20Sopenharmony_ci start, size, align); 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_ci return start; 438c2ecf20Sopenharmony_ci} 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_civoid pcibios_fixup_bus(struct pci_bus *bus) 468c2ecf20Sopenharmony_ci{ 478c2ecf20Sopenharmony_ci pci_read_bridge_bases(bus); 488c2ecf20Sopenharmony_ci} 49