blob: 71077385ab878fbbccc5cefcf47c4194b1a88709 [file] [log] [blame]
Kyösti Mälkki2161c1d2014-02-11 19:56:57 +02001/*
2 * This file is part of the coreboot project.
3 *
Kyösti Mälkki4c686f22014-02-14 12:45:09 +02004 * Copyright (C) 2011 Google Inc
5 *
Kyösti Mälkki2161c1d2014-02-11 19:56:57 +02006 * 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.
9 *
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.
Kyösti Mälkki2161c1d2014-02-11 19:56:57 +020014 */
15
Kyösti Mälkki4c686f22014-02-14 12:45:09 +020016#define __SIMPLE_DEVICE__
17
Kyösti Mälkki2161c1d2014-02-11 19:56:57 +020018#include <arch/io.h>
19#include <device/pci.h>
20#include <device/pci_def.h>
Kyösti Mälkki4c686f22014-02-14 12:45:09 +020021#include <delay.h>
22
23#ifdef __PRE_RAM__
Edward O'Callaghanc2956e72014-07-09 04:55:16 +100024unsigned pci_find_next_capability(pci_devfn_t dev, unsigned cap, unsigned last)
Kyösti Mälkki2161c1d2014-02-11 19:56:57 +020025{
26 unsigned pos = 0;
27 u16 status;
28 unsigned reps = 48;
29
30 status = pci_read_config16(dev, PCI_STATUS);
31 if (!(status & PCI_STATUS_CAP_LIST))
32 return 0;
33
34 u8 hdr_type = pci_read_config8(dev, PCI_HEADER_TYPE);
35 switch (hdr_type & 0x7f) {
36 case PCI_HEADER_TYPE_NORMAL:
37 case PCI_HEADER_TYPE_BRIDGE:
38 pos = PCI_CAPABILITY_LIST;
39 break;
40 case PCI_HEADER_TYPE_CARDBUS:
41 pos = PCI_CB_CAPABILITY_LIST;
42 break;
43 default:
44 return 0;
45 }
46
47 pos = pci_read_config8(dev, pos);
48 while (reps-- && (pos >= 0x40)) { /* Loop through the linked list. */
49 int this_cap;
50
51 pos &= ~3;
52 this_cap = pci_read_config8(dev, pos + PCI_CAP_LIST_ID);
53 if (this_cap == 0xff)
54 break;
55
56 if (!last && (this_cap == cap))
57 return pos;
58
59 if (last == pos)
60 last = 0;
61
62 pos = pci_read_config8(dev, pos + PCI_CAP_LIST_NEXT);
63 }
64 return 0;
65}
66
Edward O'Callaghanc2956e72014-07-09 04:55:16 +100067unsigned pci_find_capability(pci_devfn_t dev, unsigned cap)
Kyösti Mälkki2161c1d2014-02-11 19:56:57 +020068{
69 return pci_find_next_capability(dev, cap, 0);
70}
Edward O'Callaghanc2956e72014-07-09 04:55:16 +100071#endif /* __PRE_RAM__ */
Kyösti Mälkki4c686f22014-02-14 12:45:09 +020072
73
74#if CONFIG_EARLY_PCI_BRIDGE
75
76static void pci_bridge_reset_secondary(device_t p2p_bridge)
77{
78 u16 reg16;
79
80 /* First we reset the secondary bus. */
81 reg16 = pci_read_config16(p2p_bridge, PCI_BRIDGE_CONTROL);
82 reg16 |= (1 << 6); /* SRESET */
83 pci_write_config16(p2p_bridge, PCI_BRIDGE_CONTROL, reg16);
84
85 /* Assume we don't have to wait here forever */
86
87 /* Read back and clear reset bit. */
88 reg16 = pci_read_config16(p2p_bridge, PCI_BRIDGE_CONTROL);
89 reg16 &= ~(1 << 6); /* SRESET */
90 pci_write_config16(p2p_bridge, PCI_BRIDGE_CONTROL, reg16);
91}
92
93static void pci_bridge_set_secondary(device_t p2p_bridge, u8 secondary)
94{
95 /* Disable config transaction forwarding. */
96 pci_write_config8(p2p_bridge, PCI_SECONDARY_BUS, 0x00);
97 pci_write_config8(p2p_bridge, PCI_SUBORDINATE_BUS, 0x00);
98 /* Enable config transaction forwarding. */
99 pci_write_config8(p2p_bridge, PCI_SECONDARY_BUS, secondary);
100 pci_write_config8(p2p_bridge, PCI_SUBORDINATE_BUS, secondary);
101}
102
103static void pci_bridge_set_mmio(device_t p2p_bridge, u32 base, u32 size)
104{
105 u16 reg16;
106
107 /* Disable MMIO window behind the bridge. */
108 reg16 = pci_read_config16(p2p_bridge, PCI_COMMAND);
109 reg16 &= ~PCI_COMMAND_MEMORY;
110 pci_write_config16(p2p_bridge, PCI_COMMAND, reg16);
111 pci_write_config32(p2p_bridge, PCI_MEMORY_BASE, 0x10);
112
113 if (!size)
114 return;
115
116 /* Enable MMIO window behind the bridge. */
117 pci_write_config32(p2p_bridge, PCI_MEMORY_BASE,
118 ((base + size - 1) & 0xfff00000) | ((base >> 16) & 0xfff0));
119
120 reg16 = pci_read_config16(p2p_bridge, PCI_COMMAND);
121 reg16 |= PCI_COMMAND_MEMORY;
122 pci_write_config16(p2p_bridge, PCI_COMMAND, reg16);
123}
124
125void pci_early_bridge_init(void)
126{
127 int timeout, ret = -1;
128
129 /* No PCI-to-PCI bridges are enabled yet, so the one we try to
130 * configure must have its primary on bus 0.
131 */
132 pci_devfn_t p2p_bridge = PCI_DEV(0, CONFIG_EARLY_PCI_BRIDGE_DEVICE,
133 CONFIG_EARLY_PCI_BRIDGE_FUNCTION);
134
135 /* Secondary bus number is mostly irrelevant as we disable
136 * configuration transactions right after the probe.
137 */
138 u8 secondary = 15;
139 u8 dev = 0;
140 u32 mmio_base = CONFIG_EARLY_PCI_MMIO_BASE;
141
142 /* Enable configuration and MMIO over bridge. */
143 pci_bridge_reset_secondary(p2p_bridge);
144 pci_bridge_set_secondary(p2p_bridge, secondary);
145 pci_bridge_set_mmio(p2p_bridge, mmio_base, 0x4000);
146
147 for (timeout = 20000; timeout; timeout--) {
148 u32 id = pci_read_config32(PCI_DEV(secondary, dev, 0), PCI_VENDOR_ID);
149 if (id != 0 && id != 0xffffffff && id != 0xffff0001)
150 break;
151 udelay(10);
152 }
153
154 if (timeout != 0)
155 ret = pci_early_device_probe(secondary, dev, mmio_base);
156
157 /* Disable MMIO window if we found no suitable device. */
158 if (ret)
159 pci_bridge_set_mmio(p2p_bridge, 0, 0);
160
161 /* Resource allocator will reconfigure bridges and secondary bus
162 * number may change. Thus early device cannot reliably use config
163 * transactions from here on, so we may as well disable them.
164 */
165 pci_bridge_set_secondary(p2p_bridge, 0);
166}
167#endif /* CONFIG_EARLY_PCI_BRIDGE */