xref: /OK3568_Linux_fs/kernel/arch/mips/pci/pci-generic.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Copyright (C) 2016 Imagination Technologies
4*4882a593Smuzhiyun  * Author: Paul Burton <paul.burton@mips.com>
5*4882a593Smuzhiyun  *
6*4882a593Smuzhiyun  * pcibios_align_resource taken from arch/arm/kernel/bios32.c.
7*4882a593Smuzhiyun  */
8*4882a593Smuzhiyun 
9*4882a593Smuzhiyun #include <linux/pci.h>
10*4882a593Smuzhiyun 
11*4882a593Smuzhiyun /*
12*4882a593Smuzhiyun  * We need to avoid collisions with `mirrored' VGA ports
13*4882a593Smuzhiyun  * and other strange ISA hardware, so we always want the
14*4882a593Smuzhiyun  * addresses to be allocated in the 0x000-0x0ff region
15*4882a593Smuzhiyun  * modulo 0x400.
16*4882a593Smuzhiyun  *
17*4882a593Smuzhiyun  * Why? Because some silly external IO cards only decode
18*4882a593Smuzhiyun  * the low 10 bits of the IO address. The 0x00-0xff region
19*4882a593Smuzhiyun  * is reserved for motherboard devices that decode all 16
20*4882a593Smuzhiyun  * bits, so it's ok to allocate at, say, 0x2800-0x28ff,
21*4882a593Smuzhiyun  * but we want to try to avoid allocating at 0x2900-0x2bff
22*4882a593Smuzhiyun  * which might have be mirrored at 0x0100-0x03ff..
23*4882a593Smuzhiyun  */
pcibios_align_resource(void * data,const struct resource * res,resource_size_t size,resource_size_t align)24*4882a593Smuzhiyun resource_size_t pcibios_align_resource(void *data, const struct resource *res,
25*4882a593Smuzhiyun 				resource_size_t size, resource_size_t align)
26*4882a593Smuzhiyun {
27*4882a593Smuzhiyun 	struct pci_dev *dev = data;
28*4882a593Smuzhiyun 	resource_size_t start = res->start;
29*4882a593Smuzhiyun 	struct pci_host_bridge *host_bridge;
30*4882a593Smuzhiyun 
31*4882a593Smuzhiyun 	if (res->flags & IORESOURCE_IO && start & 0x300)
32*4882a593Smuzhiyun 		start = (start + 0x3ff) & ~0x3ff;
33*4882a593Smuzhiyun 
34*4882a593Smuzhiyun 	start = (start + align - 1) & ~(align - 1);
35*4882a593Smuzhiyun 
36*4882a593Smuzhiyun 	host_bridge = pci_find_host_bridge(dev->bus);
37*4882a593Smuzhiyun 
38*4882a593Smuzhiyun 	if (host_bridge->align_resource)
39*4882a593Smuzhiyun 		return host_bridge->align_resource(dev, res,
40*4882a593Smuzhiyun 				start, size, align);
41*4882a593Smuzhiyun 
42*4882a593Smuzhiyun 	return start;
43*4882a593Smuzhiyun }
44*4882a593Smuzhiyun 
pcibios_fixup_bus(struct pci_bus * bus)45*4882a593Smuzhiyun void pcibios_fixup_bus(struct pci_bus *bus)
46*4882a593Smuzhiyun {
47*4882a593Smuzhiyun 	pci_read_bridge_bases(bus);
48*4882a593Smuzhiyun }
49