xref: /linux/arch/m68k/kernel/pcibios.c (revision 7a5f1cd22d47f8ca4b760b6334378ae42c1bd24b)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * pci.c -- basic PCI support code
4  *
5  * (C) Copyright 2011, Greg Ungerer <gerg@uclinux.org>
6  */
7 
8 #include <linux/kernel.h>
9 #include <linux/types.h>
10 #include <linux/mm.h>
11 #include <linux/init.h>
12 #include <linux/pci.h>
13 
14 /*
15  * From arch/i386/kernel/pci-i386.c:
16  *
17  * We need to avoid collisions with `mirrored' VGA ports
18  * and other strange ISA hardware, so we always want the
19  * addresses to be allocated in the 0x000-0x0ff region
20  * modulo 0x400.
21  *
22  * Why? Because some silly external IO cards only decode
23  * the low 10 bits of the IO address. The 0x00-0xff region
24  * is reserved for motherboard devices that decode all 16
25  * bits, so it's ok to allocate at, say, 0x2800-0x28ff,
26  * but we want to try to avoid allocating at 0x2900-0x2bff
27  * which might be mirrored at 0x0100-0x03ff..
28  */
29 resource_size_t pcibios_align_resource(void *data, const struct resource *res,
30 				       const struct resource *empty_res,
31 				       resource_size_t size,
32 				       resource_size_t align)
33 {
34 	struct pci_dev *dev = data;
35 	resource_size_t start = res->start;
36 
37 	if ((res->flags & IORESOURCE_IO) && (start & 0x300))
38 		start = (start + 0x3ff) & ~0x3ff;
39 
40 	if (res->flags & IORESOURCE_MEM)
41 		return pci_align_resource(dev, res, empty_res, size, align);
42 
43 	return start;
44 }
45 
46 /*
47  * This is taken from the ARM code for this.
48  */
49 int pcibios_enable_device(struct pci_dev *dev, int mask)
50 {
51 	u16 cmd, newcmd;
52 	int ret;
53 
54 	ret = pci_enable_resources(dev, mask);
55 	if (ret < 0)
56 		return ret;
57 
58 	/*
59 	 * Bridges (eg, cardbus bridges) need to be fully enabled
60 	 */
61 	if ((dev->class >> 16) == PCI_BASE_CLASS_BRIDGE) {
62 		pci_read_config_word(dev, PCI_COMMAND, &cmd);
63 		newcmd |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
64 		if (newcmd != cmd) {
65 			pr_info("PCI: enabling bridge %s (0x%04x -> 0x%04x)\n",
66 				pci_name(dev), cmd, newcmd);
67 			pci_write_config_word(dev, PCI_COMMAND, newcmd);
68 		}
69 	}
70 	return 0;
71 }
72 
73 void pcibios_fixup_bus(struct pci_bus *bus)
74 {
75 	struct pci_dev *dev;
76 
77 	list_for_each_entry(dev, &bus->devices, bus_list) {
78 		pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 8);
79 		pci_write_config_byte(dev, PCI_LATENCY_TIMER, 32);
80 	}
81 }
82