1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <device/pci.h>
4 #include <device/pci_ops.h>
7 void pci_s_assert_secondary_reset(pci_devfn_t p2p_bridge
)
10 reg16
= pci_s_read_config16(p2p_bridge
, PCI_BRIDGE_CONTROL
);
11 reg16
|= PCI_BRIDGE_CTL_BUS_RESET
;
12 pci_s_write_config16(p2p_bridge
, PCI_BRIDGE_CONTROL
, reg16
);
15 void pci_s_deassert_secondary_reset(pci_devfn_t p2p_bridge
)
18 reg16
= pci_s_read_config16(p2p_bridge
, PCI_BRIDGE_CONTROL
);
19 reg16
&= ~PCI_BRIDGE_CTL_BUS_RESET
;
20 pci_s_write_config16(p2p_bridge
, PCI_BRIDGE_CONTROL
, reg16
);
23 void pci_s_bridge_set_secondary(pci_devfn_t p2p_bridge
, u8 secondary
)
25 /* Disable config transaction forwarding. */
26 pci_s_write_config8(p2p_bridge
, PCI_SECONDARY_BUS
, 0x00);
27 pci_s_write_config8(p2p_bridge
, PCI_SUBORDINATE_BUS
, 0x00);
28 /* Enable config transaction forwarding. */
29 pci_s_write_config8(p2p_bridge
, PCI_SECONDARY_BUS
, secondary
);
30 pci_s_write_config8(p2p_bridge
, PCI_SUBORDINATE_BUS
, secondary
);
33 static void pci_s_bridge_set_mmio(pci_devfn_t p2p_bridge
, u32 base
, u32 size
)
37 /* Disable MMIO window behind the bridge. */
38 reg16
= pci_s_read_config16(p2p_bridge
, PCI_COMMAND
);
39 reg16
&= ~PCI_COMMAND_MEMORY
;
40 pci_s_write_config16(p2p_bridge
, PCI_COMMAND
, reg16
);
41 pci_s_write_config32(p2p_bridge
, PCI_MEMORY_BASE
, 0x10);
46 /* Enable MMIO window behind the bridge. */
47 pci_s_write_config32(p2p_bridge
, PCI_MEMORY_BASE
,
48 ((base
+ size
- 1) & 0xfff00000) | ((base
>> 16) & 0xfff0));
50 reg16
= pci_s_read_config16(p2p_bridge
, PCI_COMMAND
);
51 reg16
|= PCI_COMMAND_MEMORY
;
52 pci_s_write_config16(p2p_bridge
, PCI_COMMAND
, reg16
);
55 static void pci_s_early_mmio_window(pci_devfn_t p2p_bridge
, u32 mmio_base
, u32 mmio_size
)
57 int timeout
, ret
= -1;
59 /* Secondary bus number is mostly irrelevant as we disable
60 * configuration transactions right after the probe.
65 /* Enable configuration and MMIO over bridge. */
66 pci_s_assert_secondary_reset(p2p_bridge
);
67 pci_s_deassert_secondary_reset(p2p_bridge
);
68 pci_s_bridge_set_secondary(p2p_bridge
, secondary
);
69 pci_s_bridge_set_mmio(p2p_bridge
, mmio_base
, mmio_size
);
71 for (timeout
= 20000; timeout
; timeout
--) {
72 pci_devfn_t dbg_dev
= PCI_DEV(secondary
, dev
, 0);
73 u32 id
= pci_s_read_config32(dbg_dev
, PCI_VENDOR_ID
);
74 if (id
!= 0 && id
!= 0xffffffff && id
!= 0xffff0001)
80 ret
= pci_early_device_probe(secondary
, dev
, mmio_base
);
82 /* Disable MMIO window if we found no suitable device. */
84 pci_s_bridge_set_mmio(p2p_bridge
, 0, 0);
86 /* Resource allocator will reconfigure bridges and secondary bus
87 * number may change. Thus early device cannot reliably use config
88 * transactions from here on, so we may as well disable them.
90 pci_s_bridge_set_secondary(p2p_bridge
, 0);
93 void pci_early_bridge_init(void)
95 /* No PCI-to-PCI bridges are enabled yet, so the one we try to
96 * configure must have its primary on bus 0.
98 pci_devfn_t p2p_bridge
= PCI_DEV(0, CONFIG_EARLY_PCI_BRIDGE_DEVICE
,
99 CONFIG_EARLY_PCI_BRIDGE_FUNCTION
);
101 pci_s_early_mmio_window(p2p_bridge
, CONFIG_EARLY_PCI_MMIO_BASE
, 0x4000);
104 /* FIXME: A lot of issues using the following, please avoid.
105 * Assumes 256 PCI buses, scans them all even when PCI bridges are still
106 * disabled. Probes all functions even if 0 is not present.
108 pci_devfn_t
pci_locate_device(unsigned int pci_id
, pci_devfn_t dev
)
110 for (; dev
<= PCI_DEV(255, 31, 7); dev
+= PCI_DEV(0, 0, 1)) {
112 id
= pci_s_read_config32(dev
, 0);
116 return PCI_DEV_INVALID
;
119 pci_devfn_t
pci_locate_device_on_bus(unsigned int pci_id
, unsigned int bus
)
121 pci_devfn_t dev
, last
;
123 dev
= PCI_DEV(bus
, 0, 0);
124 last
= PCI_DEV(bus
, 31, 7);
126 for (; dev
<= last
; dev
+= PCI_DEV(0, 0, 1)) {
128 id
= pci_s_read_config32(dev
, 0);
132 return PCI_DEV_INVALID
;