device/pci_ops: Move questionable pci_locate() variants
[coreboot.git] / src / device / pci_early.c
blobea2ebd50339c176465fe446104c30cf28509c271
1 /*
2 * This file is part of the coreboot project.
4 * Copyright (C) 2011 Google Inc
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
16 #define __SIMPLE_DEVICE__
18 #include <arch/io.h>
19 #include <device/pci.h>
20 #include <device/pci_def.h>
21 #include <device/pci_ops.h>
22 #include <device/pci_type.h>
23 #include <delay.h>
25 unsigned pci_find_next_capability(pci_devfn_t dev, unsigned cap, unsigned last)
27 unsigned pos = 0;
28 u16 status;
29 unsigned reps = 48;
31 status = pci_read_config16(dev, PCI_STATUS);
32 if (!(status & PCI_STATUS_CAP_LIST))
33 return 0;
35 u8 hdr_type = pci_read_config8(dev, PCI_HEADER_TYPE);
36 switch (hdr_type & 0x7f) {
37 case PCI_HEADER_TYPE_NORMAL:
38 case PCI_HEADER_TYPE_BRIDGE:
39 pos = PCI_CAPABILITY_LIST;
40 break;
41 case PCI_HEADER_TYPE_CARDBUS:
42 pos = PCI_CB_CAPABILITY_LIST;
43 break;
44 default:
45 return 0;
48 pos = pci_read_config8(dev, pos);
49 while (reps-- && (pos >= 0x40)) { /* Loop through the linked list. */
50 int this_cap;
52 pos &= ~3;
53 this_cap = pci_read_config8(dev, pos + PCI_CAP_LIST_ID);
54 if (this_cap == 0xff)
55 break;
57 if (!last && (this_cap == cap))
58 return pos;
60 if (last == pos)
61 last = 0;
63 pos = pci_read_config8(dev, pos + PCI_CAP_LIST_NEXT);
65 return 0;
68 unsigned pci_find_capability(pci_devfn_t dev, unsigned cap)
70 return pci_find_next_capability(dev, cap, 0);
73 static void pci_bridge_reset_secondary(pci_devfn_t p2p_bridge)
75 u16 reg16;
77 /* First we reset the secondary bus. */
78 reg16 = pci_read_config16(p2p_bridge, PCI_BRIDGE_CONTROL);
79 reg16 |= (1 << 6); /* SRESET */
80 pci_write_config16(p2p_bridge, PCI_BRIDGE_CONTROL, reg16);
82 /* Assume we don't have to wait here forever */
84 /* Read back and clear reset bit. */
85 reg16 = pci_read_config16(p2p_bridge, PCI_BRIDGE_CONTROL);
86 reg16 &= ~(1 << 6); /* SRESET */
87 pci_write_config16(p2p_bridge, PCI_BRIDGE_CONTROL, reg16);
90 static void pci_bridge_set_secondary(pci_devfn_t p2p_bridge, u8 secondary)
92 /* Disable config transaction forwarding. */
93 pci_write_config8(p2p_bridge, PCI_SECONDARY_BUS, 0x00);
94 pci_write_config8(p2p_bridge, PCI_SUBORDINATE_BUS, 0x00);
95 /* Enable config transaction forwarding. */
96 pci_write_config8(p2p_bridge, PCI_SECONDARY_BUS, secondary);
97 pci_write_config8(p2p_bridge, PCI_SUBORDINATE_BUS, secondary);
100 static void pci_bridge_set_mmio(pci_devfn_t p2p_bridge, u32 base, u32 size)
102 u16 reg16;
104 /* Disable MMIO window behind the bridge. */
105 reg16 = pci_read_config16(p2p_bridge, PCI_COMMAND);
106 reg16 &= ~PCI_COMMAND_MEMORY;
107 pci_write_config16(p2p_bridge, PCI_COMMAND, reg16);
108 pci_write_config32(p2p_bridge, PCI_MEMORY_BASE, 0x10);
110 if (!size)
111 return;
113 /* Enable MMIO window behind the bridge. */
114 pci_write_config32(p2p_bridge, PCI_MEMORY_BASE,
115 ((base + size - 1) & 0xfff00000) | ((base >> 16) & 0xfff0));
117 reg16 = pci_read_config16(p2p_bridge, PCI_COMMAND);
118 reg16 |= PCI_COMMAND_MEMORY;
119 pci_write_config16(p2p_bridge, PCI_COMMAND, reg16);
122 void pci_early_mmio_window(pci_devfn_t p2p_bridge, u32 mmio_base, u32 mmio_size)
124 int timeout, ret = -1;
126 /* Secondary bus number is mostly irrelevant as we disable
127 * configuration transactions right after the probe.
129 u8 secondary = 15;
130 u8 dev = 0;
132 /* Enable configuration and MMIO over bridge. */
133 pci_bridge_reset_secondary(p2p_bridge);
134 pci_bridge_set_secondary(p2p_bridge, secondary);
135 pci_bridge_set_mmio(p2p_bridge, mmio_base, mmio_size);
137 for (timeout = 20000; timeout; timeout--) {
138 u32 id = pci_read_config32(PCI_DEV(secondary, dev, 0), PCI_VENDOR_ID);
139 if (id != 0 && id != 0xffffffff && id != 0xffff0001)
140 break;
141 udelay(10);
144 if (timeout != 0)
145 ret = pci_early_device_probe(secondary, dev, mmio_base);
147 /* Disable MMIO window if we found no suitable device. */
148 if (ret)
149 pci_bridge_set_mmio(p2p_bridge, 0, 0);
151 /* Resource allocator will reconfigure bridges and secondary bus
152 * number may change. Thus early device cannot reliably use config
153 * transactions from here on, so we may as well disable them.
155 pci_bridge_set_secondary(p2p_bridge, 0);
158 void pci_early_bridge_init(void)
160 /* No PCI-to-PCI bridges are enabled yet, so the one we try to
161 * configure must have its primary on bus 0.
163 pci_devfn_t p2p_bridge = PCI_DEV(0, CONFIG_EARLY_PCI_BRIDGE_DEVICE,
164 CONFIG_EARLY_PCI_BRIDGE_FUNCTION);
166 pci_early_mmio_window(p2p_bridge, CONFIG_EARLY_PCI_MMIO_BASE, 0x4000);
169 /* FIXME: A lot of issues using the following, please avoid.
170 * Assumes 256 PCI busses, scans them all even when PCI bridges are still
171 * disabled. Probes all functions even if 0 is not present.
173 pci_devfn_t pci_locate_device(unsigned int pci_id, pci_devfn_t dev)
175 for (; dev <= PCI_DEV(255, 31, 7); dev += PCI_DEV(0, 0, 1)) {
176 unsigned int id;
177 id = pci_read_config32(dev, 0);
178 if (id == pci_id)
179 return dev;
181 return PCI_DEV_INVALID;
184 pci_devfn_t pci_locate_device_on_bus(unsigned int pci_id, unsigned int bus)
186 pci_devfn_t dev, last;
188 dev = PCI_DEV(bus, 0, 0);
189 last = PCI_DEV(bus, 31, 7);
191 for (; dev <= last; dev += PCI_DEV(0, 0, 1)) {
192 unsigned int id;
193 id = pci_read_config32(dev, 0);
194 if (id == pci_id)
195 return dev;
197 return PCI_DEV_INVALID;