coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
pcie.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include "chip.h"
4 #include <console/console.h>
5 #include <device/device.h>
6 #include <device/pci.h>
7 #include <device/pci_ops.h>
8 #include <device/pciexp.h>
9 #include <device/pci_ids.h>
10 #include <reg_script.h>
11 #include <soc/pci_devs.h>
12 #include <soc/pcie.h>
13 #include <soc/ramstage.h>
14 #include <soc/smm.h>
15 
16 static int pll_en_off;
18 
19 static inline int root_port_offset(struct device *dev)
20 {
21  return PCI_FUNC(dev->path.pci.devfn);
22 }
23 
24 static inline int is_first_port(struct device *dev)
25 {
26  return root_port_offset(dev) == PCIE_PORT1_FUNC;
27 }
28 
29 static void pcie_init(struct device *dev)
30 {
31 }
32 
33 static const struct reg_script no_dev_behind_port[] = {
34  REG_PCI_OR32(PCIEALC, (1 << 26)),
35  REG_PCI_POLL32(PCIESTS1, 0x1f000000, (1 << 24), 50000),
38 };
39 
40 static void check_port_enabled(struct device *dev)
41 {
42  int rp_config = (strpfusecfg & LANECFG_MASK) >> LANECFG_SHIFT;
43 
44  switch (root_port_offset(dev)) {
45  case PCIE_PORT1_FUNC:
46  /* Port 1 cannot be disabled from strapping config. */
47  break;
48  case PCIE_PORT2_FUNC:
49  /* Port 2 disabled in all configs but 4x1. */
50  if (rp_config != 0x0)
51  dev->enabled = 0;
52  break;
53  case PCIE_PORT3_FUNC:
54  /* Port 3 disabled only in 1x4 config. */
55  if (rp_config == 0x3)
56  dev->enabled = 0;
57  break;
58  case PCIE_PORT4_FUNC:
59  /* Port 4 disabled in 1x4 and 2x2 config. */
60  if (rp_config >= 0x2)
61  dev->enabled = 0;
62  break;
63  }
64 }
65 
66 static void check_device_present(struct device *dev)
67 {
68  /* port1_dev will store the dev struct pointer of the PORT1 */
69  static struct device *port1_dev;
70 
71  /*
72  * The SOC has 4 ROOT ports defined with MAX_ROOT_PORTS_BSW. For each port initial
73  * assumption is that, each port will have devices connected to it. Later we will
74  * scan each PORT and if the device is not attached to that port we will update
75  * rootports_in_use. If none of the root port is in use we will disable PORT1
76  * otherwise we will keep PORT1 enabled per spec. In future if the SoC has more
77  * number of PCIe Root ports then change MAX_ROOT_PORTS_BSW value accordingly.
78  */
79 
80  static uint32_t rootports_in_use = MAX_ROOT_PORTS_BSW;
81 
82  /* Set slot implemented. */
84 
85  /* No device present. */
86  if (!(pci_read_config32(dev, SLCTL_SLSTS) & PDS)) {
87  rootports_in_use--;
88  printk(BIOS_DEBUG, "No PCIe device present.");
89 
90  /*
91  * Defer PORT1 disabling for now. When we are at Last port we will check
92  * rootports_in_use and disable PORT1 if none of the ports have any device
93  * connected to it.
94  */
95  if (!is_first_port(dev)) {
97  dev->enabled = 0;
98  } else
99  port1_dev = dev;
100  /*
101  * If none of the ROOT PORT has devices connected then disable PORT1.
102  * Else, keep the PORT1 enabled.
103  */
104  if (!rootports_in_use) {
106  port1_dev->enabled = 0;
107  southcluster_enable_dev(port1_dev);
108  }
109  } else if (!dev->enabled) {
110  /* Port is disabled, but device present. Disable link. */
112  pci_read_config32(dev, LCTL) | LD);
113  }
114 }
115 
116 static void pcie_enable(struct device *dev)
117 {
118  if (is_first_port(dev)) {
121  pll_en_off = !!(reg & PLL_OFF_EN);
122 
124 
125  if (config->pcie_wake_enable)
127  }
128 
129  /* Check if device is enabled in strapping. */
130  check_port_enabled(dev);
131  /* Determine if device is behind port. */
133 
135 }
136 
137 static struct device_operations device_ops = {
139  .set_resources = pci_dev_set_resources,
140  .enable_resources = pci_bus_enable_resources,
141  .init = pcie_init,
142  .scan_bus = pciexp_scan_bridge,
143  .enable = pcie_enable,
144  .ops_pci = &pci_dev_ops_pci,
145 };
146 
147 static const unsigned short pci_device_ids[] = {
149  0
150 };
151 
152 static const struct pci_driver pcie_root_ports __pci_driver = {
153  .ops = &device_ops,
154  .vendor = PCI_VID_INTEL,
155  .devices = pci_device_ids,
156 };
#define printk(level,...)
Definition: stdlib.h:16
static DEVTREE_CONST void * config_of(const struct device *dev)
Definition: device.h:382
static __always_inline void pci_write_config32(const struct device *dev, u16 reg, u32 val)
Definition: pci_ops.h:76
static __always_inline u32 pci_read_config32(const struct device *dev, u16 reg)
Definition: pci_ops.h:58
#define PDS
Definition: pcie.h:31
#define SLCTL_SLSTS
Definition: pcie.h:30
#define PLL_OFF_EN
Definition: pcie.h:62
#define LANECFG_MASK
Definition: pcie.h:68
#define LANECFG_SHIFT
Definition: pcie.h:67
#define PCIESTS1
Definition: pcie.h:78
#define PHYCTL2_IOSFBCTL
Definition: pcie.h:61
#define LD
Definition: pcie.h:22
#define SI
Definition: pcie.h:8
#define XCAP
Definition: pcie.h:7
#define STRPFUSECFG
Definition: pcie.h:66
#define SQDIS
Definition: pcie.h:82
#define PHYCTL4
Definition: pcie.h:81
#define PCIEALC
Definition: pcie.h:79
#define LCTL
Definition: pcie.h:19
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
enum board_config config
Definition: memory.c:448
#define PCI_FUNC(devfn)
Definition: pci_def.h:550
void pci_bus_enable_resources(struct device *dev)
Definition: pci_device.c:758
void pci_bus_read_resources(struct device *dev)
Definition: pci_device.c:540
struct pci_operations pci_dev_ops_pci
Default device operation for PCI devices.
Definition: pci_device.c:911
void pci_dev_set_resources(struct device *dev)
Definition: pci_device.c:691
#define PCI_VID_INTEL
Definition: pci_ids.h:2157
void pciexp_scan_bridge(struct device *dev)
#define REG_PCI_OR32(reg_, value_)
Definition: reg_script.h:187
void reg_script_run_on_dev(struct device *dev, const struct reg_script *step)
Definition: reg_script.c:689
#define REG_SCRIPT_END
Definition: reg_script.h:427
#define REG_PCI_POLL32(reg_, mask_, value_, timeout_)
Definition: reg_script.h:193
#define PCIE_PORT1_FUNC
Definition: pci_devs.h:74
#define PCIE_PORT3_FUNC
Definition: pci_devs.h:78
#define PCIE_PORT1_DEVID
Definition: pci_devs.h:130
#define PCIE_PORT2_FUNC
Definition: pci_devs.h:76
#define PCIE_PORT3_DEVID
Definition: pci_devs.h:132
#define PCIE_PORT2_DEVID
Definition: pci_devs.h:131
#define PCIE_PORT4_FUNC
Definition: pci_devs.h:80
#define PCIE_PORT4_DEVID
Definition: pci_devs.h:133
void southcluster_enable_dev(struct device *dev)
Definition: southcluster.c:452
void smm_southcluster_save_param(int param, uint32_t data)
Definition: smm.c:17
@ SMM_SAVE_PARAM_PCIE_WAKE_ENABLE
Definition: smm.h:10
#define MAX_ROOT_PORTS_BSW
Definition: pci_devs.h:82
static void pcie_enable(struct device *dev)
Definition: pcie.c:116
static struct device_operations device_ops
Definition: pcie.c:137
static const struct reg_script no_dev_behind_port[]
Definition: pcie.c:33
static int is_first_port(struct device *dev)
Definition: pcie.c:24
static void check_device_present(struct device *dev)
Definition: pcie.c:66
static int root_port_offset(struct device *dev)
Definition: pcie.c:19
static const struct pci_driver pcie_root_ports __pci_driver
Definition: pcie.c:152
static int pll_en_off
Definition: pcie.c:16
static void check_port_enabled(struct device *dev)
Definition: pcie.c:40
static const unsigned short pci_device_ids[]
Definition: pcie.c:147
static void pcie_init(struct device *dev)
Definition: pcie.c:29
static uint32_t strpfusecfg
Definition: pcie.c:17
unsigned int uint32_t
Definition: stdint.h:14
void(* read_resources)(struct device *dev)
Definition: device.h:39
struct pci_path pci
Definition: path.h:116
Definition: device.h:107
struct device_path path
Definition: device.h:115
unsigned int enabled
Definition: device.h:122
unsigned int devfn
Definition: path.h:54
struct device * dev
Definition: reg_script.h:78