mb/google/nissa/var/rull: add ssd timing and modify ssd GPIO pins of rtd3
[coreboot2.git] / src / southbridge / intel / i82801gx / pcie.c
blobf4b3dbd4bb7f55e5f82597a5234dae5cd08607b0
1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <console/console.h>
4 #include <device/device.h>
5 #include <device/pci.h>
6 #include <device/pci_ops.h>
7 #include <device/pci_ids.h>
8 #include "chip.h"
9 #include "i82801gx.h"
11 /* Low Power variant has 6 root ports. */
12 #define NUM_ROOT_PORTS 6
14 struct root_port_config {
15 /* RPFN is a write-once register so keep a copy until it is written */
16 u32 orig_rpfn;
17 u32 new_rpfn;
18 int num_ports;
19 struct device *ports[NUM_ROOT_PORTS];
22 static struct root_port_config rpc;
24 static inline int root_port_is_first(struct device *dev)
26 return PCI_FUNC(dev->path.pci.devfn) == 0;
29 static inline int root_port_is_last(struct device *dev)
31 return PCI_FUNC(dev->path.pci.devfn) == (rpc.num_ports - 1);
34 /* Root ports are numbered 1..N in the documentation. */
35 static inline int root_port_number(struct device *dev)
37 return PCI_FUNC(dev->path.pci.devfn) + 1;
40 static void pci_init(struct device *dev)
42 u16 reg16;
44 printk(BIOS_DEBUG, "Initializing ICH7 PCIe bridge.\n");
46 /* Enable Bus Master */
47 pci_or_config16(dev, PCI_COMMAND, PCI_COMMAND_MASTER);
49 /* Set Cache Line Size to 0x10 */
50 // This has no effect but the OS might expect it
51 pci_write_config8(dev, PCI_CACHE_LINE_SIZE, 0x10);
53 pci_and_config16(dev, PCI_BRIDGE_CONTROL, ~PCI_BRIDGE_CTL_PARITY);
55 /* Enable IO xAPIC on this PCIe port */
56 pci_or_config32(dev, 0xd8, 1 << 7);
58 /* Enable Backbone Clock Gating */
59 pci_or_config32(dev, 0xe1, (1 << 3) | (1 << 2) | (1 << 1) | (1 << 0));
61 /* Set VC0 transaction class */
62 pci_update_config32(dev, 0x114, ~0x000000ff, 1);
64 /* Mask completion timeouts */
65 pci_or_config32(dev, 0x148, 1 << 14);
67 /* Enable common clock configuration */
68 // Are there cases when we don't want that?
69 pci_or_config16(dev, 0x50, 1 << 6);
71 /* Clear errors in status registers. FIXME: Do something? */
72 reg16 = pci_read_config16(dev, 0x06);
73 //reg16 |= 0xf900;
74 pci_write_config16(dev, 0x06, reg16);
76 reg16 = pci_read_config16(dev, 0x1e);
77 //reg16 |= 0xf900;
78 pci_write_config16(dev, 0x1e, reg16);
81 static int get_num_ports(void)
83 struct device *dev = pcidev_on_root(31, 0);
84 if (pci_read_config32(dev, FDVCT) & PCIE_4_PORTS_MAX)
85 return 4;
86 else
87 return 6;
90 static void root_port_init_config(struct device *dev)
92 int rp;
94 if (root_port_is_first(dev)) {
95 rpc.orig_rpfn = RCBA32(RPFN);
96 rpc.new_rpfn = rpc.orig_rpfn;
97 rpc.num_ports = get_num_ports();
100 rp = root_port_number(dev);
101 if (rp > rpc.num_ports) {
102 printk(BIOS_ERR, "Found Root Port %d, expecting %d\n", rp, rpc.num_ports);
103 return;
106 /* Cache pci device. */
107 rpc.ports[rp - 1] = dev;
110 /* Update devicetree with new Root Port function number assignment */
111 static void ich_pcie_device_set_func(int index, int pci_func)
113 struct device *dev;
114 unsigned int new_devfn;
116 dev = rpc.ports[index];
118 /* Set the new PCI function field for this Root Port. */
119 rpc.new_rpfn &= ~RPFN_FNMASK(index);
120 rpc.new_rpfn |= RPFN_FNSET(index, pci_func);
122 /* Determine the new devfn for this port */
123 new_devfn = PCI_DEVFN(ICH_PCIE_DEV_SLOT, pci_func);
125 if (dev->path.pci.devfn != new_devfn) {
126 printk(BIOS_DEBUG,
127 "ICH: PCIe map %02x.%1x -> %02x.%1x\n",
128 PCI_SLOT(dev->path.pci.devfn),
129 PCI_FUNC(dev->path.pci.devfn),
130 PCI_SLOT(new_devfn), PCI_FUNC(new_devfn));
132 dev->path.pci.devfn = new_devfn;
136 static void root_port_commit_config(struct device *dev)
138 int i;
139 bool coalesce = false;
141 if (dev->chip_info != nullptr) {
142 const struct southbridge_intel_i82801gx_config *config = dev->chip_info;
143 coalesce = config->pcie_port_coalesce;
146 if (!rpc.ports[0]->enabled)
147 coalesce = true;
149 for (i = 0; i < rpc.num_ports; i++) {
150 struct device *pcie_dev;
152 pcie_dev = rpc.ports[i];
154 if (pcie_dev == nullptr) {
155 printk(BIOS_ERR, "Root Port %d device is nullptr?\n", i + 1);
156 continue;
159 if (pcie_dev->enabled)
160 continue;
162 printk(BIOS_DEBUG, "%s: Disabling device\n", dev_path(pcie_dev));
164 /* Disable this device if possible */
165 i82801gx_enable(pcie_dev);
168 if (coalesce) {
169 int current_func;
171 /* For all Root Ports N enabled ports get assigned the lower
172 * PCI function number. The disabled ones get upper PCI
173 * function numbers. */
174 current_func = 0;
175 for (i = 0; i < rpc.num_ports; i++) {
176 if (!rpc.ports[i]->enabled)
177 continue;
178 ich_pcie_device_set_func(i, current_func);
179 current_func++;
182 /* Allocate the disabled devices' PCI function number. */
183 for (i = 0; i < rpc.num_ports; i++) {
184 if (rpc.ports[i]->enabled)
185 continue;
186 ich_pcie_device_set_func(i, current_func);
187 current_func++;
191 printk(BIOS_SPEW, "ICH: RPFN 0x%08x -> 0x%08x\n", rpc.orig_rpfn, rpc.new_rpfn);
192 RCBA32(RPFN) = rpc.new_rpfn;
195 static void ich_pcie_enable(struct device *dev)
197 /* Add this device to the root port config structure. */
198 root_port_init_config(dev);
201 * When processing the last PCIe root port we can now
202 * update the Root Port Function Number and Hide register.
204 if (root_port_is_last(dev))
205 root_port_commit_config(dev);
208 static struct device_operations device_ops = {
209 .read_resources = pci_bus_read_resources,
210 .set_resources = pci_dev_set_resources,
211 .enable_resources = pci_bus_enable_resources,
212 .init = pci_init,
213 .enable = ich_pcie_enable,
214 .scan_bus = pci_scan_bridge,
215 .ops_pci = &pci_dev_ops_pci,
218 static const unsigned short i82801gx_pcie_ids[] = {
219 0x27d0, /* 82801GB/GR/GDH/GBM/GHM (ICH7/ICH7R/ICH7DH/ICH7-M/ICH7-M DH) */
220 0x27d2, /* 82801GB/GR/GDH/GBM/GHM (ICH7/ICH7R/ICH7DH/ICH7-M/ICH7-M DH) */
221 0x27d4, /* 82801GB/GR/GDH/GBM/GHM (ICH7/ICH7R/ICH7DH/ICH7-M/ICH7-M DH) */
222 0x27d6, /* 82801GB/GR/GDH/GBM/GHM (ICH7/ICH7R/ICH7DH/ICH7-M/ICH7-M DH) */
223 0x27e0, /* 82801GR/GDH/GHM (ICH7R/ICH7DH/ICH7-M DH) */
224 0x27e2, /* 82801GR/GDH/GHM (ICH7R/ICH7DH/ICH7-M DH) */
228 static const struct pci_driver i82801gx_pcie __pci_driver = {
229 .ops = &device_ops,
230 .vendor = PCI_VID_INTEL,
231 .devices = i82801gx_pcie_ids,