blob: 4904c68bb7319c718eb01bc497335ee9f1aacb15 [file] [log] [blame]
Angel Ponsc74dae92020-04-02 23:48:16 +02001/* SPDX-License-Identifier: GPL-2.0-only */
2/* This file is part of the coreboot project. */
Kyösti Mälkki2161c1d2014-02-11 19:56:57 +02003
Kyösti Mälkki2161c1d2014-02-11 19:56:57 +02004#include <device/pci.h>
5#include <device/pci_def.h>
Kyösti Mälkki5b141162019-01-23 16:02:28 +02006#include <device/pci_ops.h>
7#include <device/pci_type.h>
Kyösti Mälkki4c686f22014-02-14 12:45:09 +02008#include <delay.h>
9
Kyösti Mälkkia0b366d2019-09-26 22:33:51 +030010void pci_s_assert_secondary_reset(pci_devfn_t p2p_bridge)
Kyösti Mälkki4c686f22014-02-14 12:45:09 +020011{
12 u16 reg16;
Kyösti Mälkkia0b366d2019-09-26 22:33:51 +030013 reg16 = pci_s_read_config16(p2p_bridge, PCI_BRIDGE_CONTROL);
14 reg16 |= PCI_BRIDGE_CTL_BUS_RESET;
15 pci_s_write_config16(p2p_bridge, PCI_BRIDGE_CONTROL, reg16);
Kyösti Mälkki4c686f22014-02-14 12:45:09 +020016}
17
Kyösti Mälkkia0b366d2019-09-26 22:33:51 +030018void pci_s_deassert_secondary_reset(pci_devfn_t p2p_bridge)
19{
20 u16 reg16;
21 reg16 = pci_s_read_config16(p2p_bridge, PCI_BRIDGE_CONTROL);
22 reg16 &= ~PCI_BRIDGE_CTL_BUS_RESET;
23 pci_s_write_config16(p2p_bridge, PCI_BRIDGE_CONTROL, reg16);
24}
25
26void pci_s_bridge_set_secondary(pci_devfn_t p2p_bridge, u8 secondary)
Kyösti Mälkki4c686f22014-02-14 12:45:09 +020027{
28 /* Disable config transaction forwarding. */
Kyösti Mälkkia0b366d2019-09-26 22:33:51 +030029 pci_s_write_config8(p2p_bridge, PCI_SECONDARY_BUS, 0x00);
30 pci_s_write_config8(p2p_bridge, PCI_SUBORDINATE_BUS, 0x00);
Kyösti Mälkki4c686f22014-02-14 12:45:09 +020031 /* Enable config transaction forwarding. */
Kyösti Mälkkia0b366d2019-09-26 22:33:51 +030032 pci_s_write_config8(p2p_bridge, PCI_SECONDARY_BUS, secondary);
33 pci_s_write_config8(p2p_bridge, PCI_SUBORDINATE_BUS, secondary);
Kyösti Mälkki4c686f22014-02-14 12:45:09 +020034}
35
Kyösti Mälkkia0b366d2019-09-26 22:33:51 +030036static void pci_s_bridge_set_mmio(pci_devfn_t p2p_bridge, u32 base, u32 size)
Kyösti Mälkki4c686f22014-02-14 12:45:09 +020037{
38 u16 reg16;
39
40 /* Disable MMIO window behind the bridge. */
Kyösti Mälkkia0b366d2019-09-26 22:33:51 +030041 reg16 = pci_s_read_config16(p2p_bridge, PCI_COMMAND);
Kyösti Mälkki4c686f22014-02-14 12:45:09 +020042 reg16 &= ~PCI_COMMAND_MEMORY;
Kyösti Mälkkia0b366d2019-09-26 22:33:51 +030043 pci_s_write_config16(p2p_bridge, PCI_COMMAND, reg16);
44 pci_s_write_config32(p2p_bridge, PCI_MEMORY_BASE, 0x10);
Kyösti Mälkki4c686f22014-02-14 12:45:09 +020045
46 if (!size)
47 return;
48
49 /* Enable MMIO window behind the bridge. */
Kyösti Mälkkia0b366d2019-09-26 22:33:51 +030050 pci_s_write_config32(p2p_bridge, PCI_MEMORY_BASE,
Kyösti Mälkki4c686f22014-02-14 12:45:09 +020051 ((base + size - 1) & 0xfff00000) | ((base >> 16) & 0xfff0));
52
Kyösti Mälkkia0b366d2019-09-26 22:33:51 +030053 reg16 = pci_s_read_config16(p2p_bridge, PCI_COMMAND);
Kyösti Mälkki4c686f22014-02-14 12:45:09 +020054 reg16 |= PCI_COMMAND_MEMORY;
Kyösti Mälkkia0b366d2019-09-26 22:33:51 +030055 pci_s_write_config16(p2p_bridge, PCI_COMMAND, reg16);
Kyösti Mälkki4c686f22014-02-14 12:45:09 +020056}
57
Kyösti Mälkkia0b366d2019-09-26 22:33:51 +030058static void pci_s_early_mmio_window(pci_devfn_t p2p_bridge, u32 mmio_base, u32 mmio_size)
Kyösti Mälkki4c686f22014-02-14 12:45:09 +020059{
60 int timeout, ret = -1;
61
Kyösti Mälkki4c686f22014-02-14 12:45:09 +020062 /* Secondary bus number is mostly irrelevant as we disable
63 * configuration transactions right after the probe.
64 */
65 u8 secondary = 15;
66 u8 dev = 0;
Kyösti Mälkki4c686f22014-02-14 12:45:09 +020067
68 /* Enable configuration and MMIO over bridge. */
Kyösti Mälkkia0b366d2019-09-26 22:33:51 +030069 pci_s_assert_secondary_reset(p2p_bridge);
70 pci_s_deassert_secondary_reset(p2p_bridge);
71 pci_s_bridge_set_secondary(p2p_bridge, secondary);
72 pci_s_bridge_set_mmio(p2p_bridge, mmio_base, mmio_size);
Kyösti Mälkki4c686f22014-02-14 12:45:09 +020073
74 for (timeout = 20000; timeout; timeout--) {
Kyösti Mälkkia0b366d2019-09-26 22:33:51 +030075 pci_devfn_t dbg_dev = PCI_DEV(secondary, dev, 0);
76 u32 id = pci_s_read_config32(dbg_dev, PCI_VENDOR_ID);
Kyösti Mälkki4c686f22014-02-14 12:45:09 +020077 if (id != 0 && id != 0xffffffff && id != 0xffff0001)
78 break;
79 udelay(10);
80 }
81
82 if (timeout != 0)
83 ret = pci_early_device_probe(secondary, dev, mmio_base);
84
85 /* Disable MMIO window if we found no suitable device. */
86 if (ret)
Kyösti Mälkkia0b366d2019-09-26 22:33:51 +030087 pci_s_bridge_set_mmio(p2p_bridge, 0, 0);
Kyösti Mälkki4c686f22014-02-14 12:45:09 +020088
89 /* Resource allocator will reconfigure bridges and secondary bus
90 * number may change. Thus early device cannot reliably use config
91 * transactions from here on, so we may as well disable them.
92 */
Kyösti Mälkkia0b366d2019-09-26 22:33:51 +030093 pci_s_bridge_set_secondary(p2p_bridge, 0);
Kyösti Mälkki4c686f22014-02-14 12:45:09 +020094}
Kyösti Mälkki3521e262018-12-26 19:33:28 +020095
96void pci_early_bridge_init(void)
97{
98 /* No PCI-to-PCI bridges are enabled yet, so the one we try to
99 * configure must have its primary on bus 0.
100 */
101 pci_devfn_t p2p_bridge = PCI_DEV(0, CONFIG_EARLY_PCI_BRIDGE_DEVICE,
102 CONFIG_EARLY_PCI_BRIDGE_FUNCTION);
103
Kyösti Mälkkia0b366d2019-09-26 22:33:51 +0300104 pci_s_early_mmio_window(p2p_bridge, CONFIG_EARLY_PCI_MMIO_BASE, 0x4000);
Kyösti Mälkki3521e262018-12-26 19:33:28 +0200105}
Kyösti Mälkki8a41f4b2019-02-08 18:14:34 +0200106
107/* FIXME: A lot of issues using the following, please avoid.
108 * Assumes 256 PCI busses, scans them all even when PCI bridges are still
109 * disabled. Probes all functions even if 0 is not present.
110 */
111pci_devfn_t pci_locate_device(unsigned int pci_id, pci_devfn_t dev)
112{
113 for (; dev <= PCI_DEV(255, 31, 7); dev += PCI_DEV(0, 0, 1)) {
114 unsigned int id;
Kyösti Mälkkia0b366d2019-09-26 22:33:51 +0300115 id = pci_s_read_config32(dev, 0);
Kyösti Mälkki8a41f4b2019-02-08 18:14:34 +0200116 if (id == pci_id)
117 return dev;
118 }
119 return PCI_DEV_INVALID;
120}
121
122pci_devfn_t pci_locate_device_on_bus(unsigned int pci_id, unsigned int bus)
123{
124 pci_devfn_t dev, last;
125
126 dev = PCI_DEV(bus, 0, 0);
127 last = PCI_DEV(bus, 31, 7);
128
129 for (; dev <= last; dev += PCI_DEV(0, 0, 1)) {
130 unsigned int id;
Kyösti Mälkkia0b366d2019-09-26 22:33:51 +0300131 id = pci_s_read_config32(dev, 0);
Kyösti Mälkki8a41f4b2019-02-08 18:14:34 +0200132 if (id == pci_id)
133 return dev;
134 }
135 return PCI_DEV_INVALID;
136}