• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <console/console.h>
4 #include <device/device.h>
5 #include <device/pci.h>
6 #include <device/pci_ops.h>
7 #include <device/pciexp.h>
8 #include <device/pci_ids.h>
9 #include <reg_script.h>
10 
11 #include <soc/pci_devs.h>
12 #include <soc/pcie.h>
13 #include <soc/ramstage.h>
14 #include <soc/smm.h>
15 
16 #include "chip.h"
17 
18 static int pll_en_off;
19 static uint32_t strpfusecfg;
20 
root_port_offset(struct device * dev)21 static inline int root_port_offset(struct device *dev)
22 {
23 	return PCI_FUNC(dev->path.pci.devfn);
24 }
25 
is_first_port(struct device * dev)26 static inline int is_first_port(struct device *dev)
27 {
28 	return root_port_offset(dev) == PCIE_PORT1_FUNC;
29 }
30 
31 static const struct reg_script init_static_before_exit_latency[] = {
32 	/* Disable optimized buffer flush fill and latency tolerant reporting */
33 	REG_PCI_RMW32(DCAP2, ~(OBFFS | LTRMS), 0),
34 	REG_PCI_RMW32(DSTS2, ~(OBFFEN| LTRME), 0),
35 	/* Set maximum payload size. */
36 	REG_PCI_RMW32(DCAP, ~MPS_MASK, 0),
37 	/* Disable transmit datapath flush timer, clear transmit config change
38 	 * wait time, clear sideband interface idle counter. */
39 	REG_PCI_RMW32(PHYCTL2_IOSFBCTL, ~(TDFT | TXCFGCHWAIT | SIID), 0),
40 	REG_SCRIPT_END,
41 };
42 
43 static const struct reg_script init_static_after_exit_latency[] = {
44 	/* Set common clock configuration. */
45 	REG_PCI_OR16(LCTL, CCC),
46 	/* Set NFTS to 0x743a361b */
47 	REG_PCI_WRITE32(NFTS, 0x743a361b),
48 	/* Set common clock latency to 0x3 */
49 	REG_PCI_RMW32(MPC, ~CCEL_MASK, (0x3 << CCEL_SHIFT)),
50 	/* Set relay timer policy. */
51 	REG_PCI_RMW32(RTP, 0xff000000, 0x854c74),
52 	/* Set IOSF packet fast transmit mode and link speed training policy. */
53 	REG_PCI_OR16(MPC2, IPF | LSTP),
54 	/* Channel configuration - enable upstream posted split, set non-posted
55 	 * and posted request size */
56 	REG_PCI_RMW32(CHCFG, ~UPSD, UNRS | UPRS),
57 	/* Completion status replay enable and set TLP grant count */
58 	REG_PCI_RMW32(CFG2, ~(LATGC_MASK), CSREN | (3 << LATGC_SHIFT)),
59 	/* Assume no IOAPIC behind root port -- disable EOI forwarding. */
60 	REG_PCI_OR16(MPC2, EOIFD),
61 	/* Expose AER */
62 	REG_PCI_RMW32(AERCH, ~0, (1 << 16) | (1 << 0)),
63 	/* set completion timeout to 160ms to 170ms */
64 	REG_PCI_RMW16(DSTS2, ~CTD, 0x6),
65 	/* Enable AER */
66 	REG_PCI_OR16(DCTL_DSTS, URE | FEE | NFE | CEE),
67 	/* Read and write back capability registers. */
68 	REG_PCI_OR32(0x34, 0),
69 	REG_PCI_OR32(0x80, 0),
70 	/* Retrain the link. */
71 	REG_PCI_OR16(LCTL, RL),
72 	REG_SCRIPT_END,
73 };
74 
byt_pcie_init(struct device * dev)75 static void byt_pcie_init(struct device *dev)
76 {
77 	struct reg_script init_script[] = {
78 		REG_SCRIPT_NEXT(init_static_before_exit_latency),
79 		/* Exit latency configuration based on
80 		 * PHYCTL2_IOSFBCTL[PLL_OFF_EN] set in root port 1*/
81 		REG_PCI_RMW32(LCAP, ~L1EXIT_MASK,
82 			2 << (L1EXIT_SHIFT + pll_en_off)),
83 		REG_SCRIPT_NEXT(init_static_after_exit_latency),
84 		/* Disable hot plug, set power to 10W, set slot number. */
85 		REG_PCI_RMW32(SLCAP, ~(HPC | HPS),
86 			(1 << SLS_SHIFT) | (100 << SLV_SHIFT) |
87 			(root_port_offset(dev) << SLN_SHIFT)),
88 		/* Dynamic clock gating. */
89 		REG_PCI_OR32(RPPGEN, RPDLCGEN | RPDBCGEN | RPSCGEN),
90 		REG_PCI_OR32(PWRCTL, RPL1SQPOL | RPDTSQPOL),
91 		REG_PCI_OR32(PCIEDBG, SPCE),
92 		REG_SCRIPT_END,
93 	};
94 
95 	reg_script_run_on_dev(dev, init_script);
96 
97 	if (is_first_port(dev)) {
98 		struct soc_intel_baytrail_config *config = config_of(dev);
99 		uint32_t reg = pci_read_config32(dev, RPPGEN);
100 		reg |= SRDLCGEN | SRDBCGEN;
101 
102 		if (config->clkreq_enable)
103 			reg |= LCLKREQEN | BBCLKREQEN;
104 
105 		pci_write_config32(dev, RPPGEN, reg);
106 	}
107 }
108 
109 static const struct reg_script no_dev_behind_port[] = {
110 	REG_PCI_OR32(PCIEALC, (1 << 26)),
111 	REG_PCI_POLL32(PCIESTS1, 0x1f000000, (1 << 24), 50000),
112 	REG_PCI_OR32(PHYCTL4, SQDIS),
113 	REG_SCRIPT_END,
114 };
115 
check_port_enabled(struct device * dev)116 static void check_port_enabled(struct device *dev)
117 {
118 	int rp_config = (strpfusecfg & LANECFG_MASK) >> LANECFG_SHIFT;
119 
120 	switch (root_port_offset(dev)) {
121 	case PCIE_PORT1_FUNC:
122 		/* Port 1 cannot be disabled from strapping config. */
123 		break;
124 	case PCIE_PORT2_FUNC:
125 		/* Port 2 disabled in all configs but 4x1. */
126 		if (rp_config != 0x0)
127 			dev->enabled = 0;
128 		break;
129 	case PCIE_PORT3_FUNC:
130 		/* Port 3 disabled only in 1x4 config. */
131 		if (rp_config == 0x3)
132 			dev->enabled = 0;
133 		break;
134 	case PCIE_PORT4_FUNC:
135 		/* Port 4 disabled in 1x4 and 2x2 config. */
136 		if (rp_config >= 0x2)
137 			dev->enabled = 0;
138 		break;
139 	}
140 }
141 
all_ports_no_dev_present(struct device * dev)142 static u8 all_ports_no_dev_present(struct device *dev)
143 {
144 	u8 func;
145 	u8 temp = dev->path.pci.devfn;
146 	u8 device_not_present = 1;
147 	u8 data;
148 
149 	for (func = 1; func < PCIE_ROOT_PORT_COUNT; func++) {
150 		dev->path.pci.devfn &= ~0x7;
151 		dev->path.pci.devfn |= func;
152 
153 		/* is PCIe device there */
154 		if (pci_read_config32(dev, 0) == 0xFFFFFFFF)
155 			continue;
156 
157 		data = pci_read_config8(dev, XCAP + 3) | (SI >> 24);
158 		pci_write_config8(dev, XCAP + 3, data);
159 
160 		/* is any device present */
161 		if ((pci_read_config32(dev, SLCTL_SLSTS) & PDS)) {
162 			device_not_present = 0;
163 			break;
164 		}
165 	}
166 
167 	dev->path.pci.devfn = temp;
168 	return device_not_present;
169 }
170 
check_device_present(struct device * dev)171 static void check_device_present(struct device *dev)
172 {
173 	/* Set slot implemented. */
174 	pci_write_config32(dev, XCAP, pci_read_config32(dev, XCAP) | SI);
175 
176 	/* No device present. */
177 	if (!(pci_read_config32(dev, SLCTL_SLSTS) & PDS)) {
178 		printk(BIOS_DEBUG, "No PCIe device present.\n");
179 		if (is_first_port(dev)) {
180 			if (all_ports_no_dev_present(dev)) {
181 				reg_script_run_on_dev(dev, no_dev_behind_port);
182 				dev->enabled = 0;
183 			}
184 		} else {
185 			reg_script_run_on_dev(dev, no_dev_behind_port);
186 			dev->enabled = 0;
187 		}
188 	} else if (!dev->enabled) {
189 		/* Port is disabled, but device present. Disable link. */
190 		pci_write_config32(dev, LCTL,
191 			pci_read_config32(dev, LCTL) | LD);
192 	}
193 }
194 
byt_pcie_enable(struct device * dev)195 static void byt_pcie_enable(struct device *dev)
196 {
197 	if (is_first_port(dev)) {
198 		struct soc_intel_baytrail_config *config = config_of(dev);
199 		uint32_t reg = pci_read_config32(dev, PHYCTL2_IOSFBCTL);
200 		pll_en_off = !!(reg & PLL_OFF_EN);
201 
202 		strpfusecfg = pci_read_config32(dev, STRPFUSECFG);
203 
204 		if (config->pcie_wake_enable)
205 			smm_southcluster_save_param(
206 				SMM_SAVE_PARAM_PCIE_WAKE_ENABLE, 1);
207 	}
208 
209 	/* Check if device is enabled in strapping. */
210 	check_port_enabled(dev);
211 	/* Determine if device is behind port. */
212 	check_device_present(dev);
213 
214 	southcluster_enable_dev(dev);
215 }
216 
byt_pciexp_scan_bridge(struct device * dev)217 static void byt_pciexp_scan_bridge(struct device *dev)
218 {
219 	static const struct reg_script wait_for_link_active[] = {
220 		REG_PCI_POLL32(LCTL, (1 << 29), (1 << 29), 50000),
221 		REG_SCRIPT_END,
222 	};
223 
224 	/* wait for Link Active with 50ms timeout */
225 	reg_script_run_on_dev(dev, wait_for_link_active);
226 
227 	do_pci_scan_bridge(dev, pciexp_scan_bus);
228 }
229 
230 static struct device_operations device_ops = {
231 	.read_resources		= pci_bus_read_resources,
232 	.set_resources		= pci_dev_set_resources,
233 	.enable_resources	= pci_bus_enable_resources,
234 	.init			= byt_pcie_init,
235 	.scan_bus		= byt_pciexp_scan_bridge,
236 	.enable			= byt_pcie_enable,
237 	.ops_pci		= &pci_dev_ops_pci,
238 };
239 
240 static const unsigned short pci_device_ids[] = {
241 	PCIE_PORT1_DEVID, PCIE_PORT2_DEVID, PCIE_PORT3_DEVID, PCIE_PORT4_DEVID,
242 	0
243 };
244 
245 static const struct pci_driver pcie_root_ports __pci_driver = {
246 	.ops	 = &device_ops,
247 	.vendor	 = PCI_VID_INTEL,
248 	.devices = pci_device_ids,
249 };
250