blob: 590b170142da93c3a3919dad1be25ebfe1194697 [file] [log] [blame]
Angel Ponsc74dae92020-04-02 23:48:16 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Kyösti Mälkki2161c1d2014-02-11 19:56:57 +02002
Kyösti Mälkki2161c1d2014-02-11 19:56:57 +02003#include <device/pci.h>
4#include <device/pci_def.h>
Kyösti Mälkki5b141162019-01-23 16:02:28 +02005#include <device/pci_ops.h>
6#include <device/pci_type.h>
Kyösti Mälkki4c686f22014-02-14 12:45:09 +02007#include <delay.h>
8
Kyösti Mälkkia0b366d2019-09-26 22:33:51 +03009void pci_s_assert_secondary_reset(pci_devfn_t p2p_bridge)
Kyösti Mälkki4c686f22014-02-14 12:45:09 +020010{
11 u16 reg16;
Kyösti Mälkkia0b366d2019-09-26 22:33:51 +030012 reg16 = pci_s_read_config16(p2p_bridge, PCI_BRIDGE_CONTROL);
13 reg16 |= PCI_BRIDGE_CTL_BUS_RESET;
14 pci_s_write_config16(p2p_bridge, PCI_BRIDGE_CONTROL, reg16);
Kyösti Mälkki4c686f22014-02-14 12:45:09 +020015}
16
Kyösti Mälkkia0b366d2019-09-26 22:33:51 +030017void pci_s_deassert_secondary_reset(pci_devfn_t p2p_bridge)
18{
19 u16 reg16;
20 reg16 = pci_s_read_config16(p2p_bridge, PCI_BRIDGE_CONTROL);
21 reg16 &= ~PCI_BRIDGE_CTL_BUS_RESET;
22 pci_s_write_config16(p2p_bridge, PCI_BRIDGE_CONTROL, reg16);
23}
24
25void pci_s_bridge_set_secondary(pci_devfn_t p2p_bridge, u8 secondary)
Kyösti Mälkki4c686f22014-02-14 12:45:09 +020026{
27 /* Disable config transaction forwarding. */
Kyösti Mälkkia0b366d2019-09-26 22:33:51 +030028 pci_s_write_config8(p2p_bridge, PCI_SECONDARY_BUS, 0x00);
29 pci_s_write_config8(p2p_bridge, PCI_SUBORDINATE_BUS, 0x00);
Kyösti Mälkki4c686f22014-02-14 12:45:09 +020030 /* Enable config transaction forwarding. */
Kyösti Mälkkia0b366d2019-09-26 22:33:51 +030031 pci_s_write_config8(p2p_bridge, PCI_SECONDARY_BUS, secondary);
32 pci_s_write_config8(p2p_bridge, PCI_SUBORDINATE_BUS, secondary);
Kyösti Mälkki4c686f22014-02-14 12:45:09 +020033}
34
Kyösti Mälkkia0b366d2019-09-26 22:33:51 +030035static void pci_s_bridge_set_mmio(pci_devfn_t p2p_bridge, u32 base, u32 size)
Kyösti Mälkki4c686f22014-02-14 12:45:09 +020036{
37 u16 reg16;
38
39 /* Disable MMIO window behind the bridge. */
Kyösti Mälkkia0b366d2019-09-26 22:33:51 +030040 reg16 = pci_s_read_config16(p2p_bridge, PCI_COMMAND);
Kyösti Mälkki4c686f22014-02-14 12:45:09 +020041 reg16 &= ~PCI_COMMAND_MEMORY;
Kyösti Mälkkia0b366d2019-09-26 22:33:51 +030042 pci_s_write_config16(p2p_bridge, PCI_COMMAND, reg16);
43 pci_s_write_config32(p2p_bridge, PCI_MEMORY_BASE, 0x10);
Kyösti Mälkki4c686f22014-02-14 12:45:09 +020044
45 if (!size)
46 return;
47
48 /* Enable MMIO window behind the bridge. */
Kyösti Mälkkia0b366d2019-09-26 22:33:51 +030049 pci_s_write_config32(p2p_bridge, PCI_MEMORY_BASE,
Kyösti Mälkki4c686f22014-02-14 12:45:09 +020050 ((base + size - 1) & 0xfff00000) | ((base >> 16) & 0xfff0));
51
Kyösti Mälkkia0b366d2019-09-26 22:33:51 +030052 reg16 = pci_s_read_config16(p2p_bridge, PCI_COMMAND);
Kyösti Mälkki4c686f22014-02-14 12:45:09 +020053 reg16 |= PCI_COMMAND_MEMORY;
Kyösti Mälkkia0b366d2019-09-26 22:33:51 +030054 pci_s_write_config16(p2p_bridge, PCI_COMMAND, reg16);
Kyösti Mälkki4c686f22014-02-14 12:45:09 +020055}
56
Kyösti Mälkkia0b366d2019-09-26 22:33:51 +030057static 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 +020058{
59 int timeout, ret = -1;
60
Kyösti Mälkki4c686f22014-02-14 12:45:09 +020061 /* Secondary bus number is mostly irrelevant as we disable
62 * configuration transactions right after the probe.
63 */
64 u8 secondary = 15;
65 u8 dev = 0;
Kyösti Mälkki4c686f22014-02-14 12:45:09 +020066
67 /* Enable configuration and MMIO over bridge. */
Kyösti Mälkkia0b366d2019-09-26 22:33:51 +030068 pci_s_assert_secondary_reset(p2p_bridge);
69 pci_s_deassert_secondary_reset(p2p_bridge);
70 pci_s_bridge_set_secondary(p2p_bridge, secondary);
71 pci_s_bridge_set_mmio(p2p_bridge, mmio_base, mmio_size);
Kyösti Mälkki4c686f22014-02-14 12:45:09 +020072
73 for (timeout = 20000; timeout; timeout--) {
Kyösti Mälkkia0b366d2019-09-26 22:33:51 +030074 pci_devfn_t dbg_dev = PCI_DEV(secondary, dev, 0);
75 u32 id = pci_s_read_config32(dbg_dev, PCI_VENDOR_ID);
Kyösti Mälkki4c686f22014-02-14 12:45:09 +020076 if (id != 0 && id != 0xffffffff && id != 0xffff0001)
77 break;
78 udelay(10);
79 }
80
81 if (timeout != 0)
82 ret = pci_early_device_probe(secondary, dev, mmio_base);
83
84 /* Disable MMIO window if we found no suitable device. */
85 if (ret)
Kyösti Mälkkia0b366d2019-09-26 22:33:51 +030086 pci_s_bridge_set_mmio(p2p_bridge, 0, 0);
Kyösti Mälkki4c686f22014-02-14 12:45:09 +020087
88 /* Resource allocator will reconfigure bridges and secondary bus
89 * number may change. Thus early device cannot reliably use config
90 * transactions from here on, so we may as well disable them.
91 */
Kyösti Mälkkia0b366d2019-09-26 22:33:51 +030092 pci_s_bridge_set_secondary(p2p_bridge, 0);
Kyösti Mälkki4c686f22014-02-14 12:45:09 +020093}
Kyösti Mälkki3521e262018-12-26 19:33:28 +020094
95void pci_early_bridge_init(void)
96{
97 /* No PCI-to-PCI bridges are enabled yet, so the one we try to
98 * configure must have its primary on bus 0.
99 */
100 pci_devfn_t p2p_bridge = PCI_DEV(0, CONFIG_EARLY_PCI_BRIDGE_DEVICE,
101 CONFIG_EARLY_PCI_BRIDGE_FUNCTION);
102
Kyösti Mälkkia0b366d2019-09-26 22:33:51 +0300103 pci_s_early_mmio_window(p2p_bridge, CONFIG_EARLY_PCI_MMIO_BASE, 0x4000);
Kyösti Mälkki3521e262018-12-26 19:33:28 +0200104}
Kyösti Mälkki8a41f4b2019-02-08 18:14:34 +0200105
106/* FIXME: A lot of issues using the following, please avoid.
Martin Roth0949e732021-10-01 14:28:22 -0600107 * Assumes 256 PCI buses, scans them all even when PCI bridges are still
Kyösti Mälkki8a41f4b2019-02-08 18:14:34 +0200108 * disabled. Probes all functions even if 0 is not present.
109 */
110pci_devfn_t pci_locate_device(unsigned int pci_id, pci_devfn_t dev)
111{
112 for (; dev <= PCI_DEV(255, 31, 7); dev += PCI_DEV(0, 0, 1)) {
113 unsigned int id;
Kyösti Mälkkia0b366d2019-09-26 22:33:51 +0300114 id = pci_s_read_config32(dev, 0);
Kyösti Mälkki8a41f4b2019-02-08 18:14:34 +0200115 if (id == pci_id)
116 return dev;
117 }
118 return PCI_DEV_INVALID;
119}
120
121pci_devfn_t pci_locate_device_on_bus(unsigned int pci_id, unsigned int bus)
122{
123 pci_devfn_t dev, last;
124
125 dev = PCI_DEV(bus, 0, 0);
126 last = PCI_DEV(bus, 31, 7);
127
128 for (; dev <= last; dev += PCI_DEV(0, 0, 1)) {
129 unsigned int id;
Kyösti Mälkkia0b366d2019-09-26 22:33:51 +0300130 id = pci_s_read_config32(dev, 0);
Kyösti Mälkki8a41f4b2019-02-08 18:14:34 +0200131 if (id == pci_id)
132 return dev;
133 }
134 return PCI_DEV_INVALID;
135}