summaryrefslogtreecommitdiffstats
path: root/src/soc/intel/common/block/include/intelblocks/pcie_rp.h
blob: 2f3b83ce4c55dec5bb74237d228730cb12c1f2b0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
/* SPDX-License-Identifier: GPL-2.0-only */

#ifndef SOC_INTEL_COMMON_BLOCK_PCIE_RP_H
#define SOC_INTEL_COMMON_BLOCK_PCIE_RP_H

#include <stdint.h>

/*
 * In schematic PCIe root port numbers are 1-based, but FSP use 0-based indexes for
 * the configuration arrays and so this macro subtracts 1 to convert RP# to array index.
 */
#define PCIE_RP(x)      ((x) - 1)
#define PCH_RP(x)       PCIE_RP(x)
#define CPU_RP(x)       PCIE_RP(x)

enum pcie_rp_flags {
	PCIE_RP_HOTPLUG = (1 << 0),
	PCIE_RP_LTR = (1 << 1),
	/* PCIE RP Advanced Error Report */
	PCIE_RP_AER = (1 << 2),
	/* Clock source is not used by the root port. */
	PCIE_RP_CLK_SRC_UNUSED = (1 << 3),
	/*
	 * Clock request signal requires probing before enabling CLKREQ# based power
	 * management.
	 */
	PCIE_RP_CLK_REQ_DETECT = (1 << 4),
	/* Clock request signal is not used by the root port. */
	PCIE_RP_CLK_REQ_UNUSED = (1 << 5),
};

enum pcie_clk_src_flags {
	PCIE_CLK_FREE_RUNNING = (1 << 0),
	PCIE_CLK_LAN = (1 << 1),
};

/* This enum is for passing into an FSP UPD, typically PcieRpL1Substates */
enum L1_substates_control {
	L1_SS_FSP_DEFAULT,
	L1_SS_DISABLED,
	L1_SS_L1_1,
	L1_SS_L1_2,
};

/* PCIe Root Ports */
struct pcie_rp_config {
	/* CLKOUT_PCIE_P/N# used by this root port as per schematics. */
	uint8_t clk_src;
	/* SRCCLKREQ# used by this root port as per schematics. */
	uint8_t clk_req;
	enum pcie_rp_flags flags;
	/* PCIe RP L1 substate */
	enum L1_substates_control PcieRpL1Substates;
};

/*
 * The PCIe Root Ports usually come in groups of up to 8 PCI-device
 * functions.
 *
 * `slot` is the PCI device/slot number of such a group.
 * `start` is the initial PCI function number within the group. This is useful
 * in case the root port numbers are not contiguous within the slot.
 * `count` is the number of functions within the group starting with the `start`
 * function number.
 * `lcap_port_base` is the starting index of physical port as described in LCAP
 * register in PCIe config space. coreboot always uses 0 based indexing while
 * referring to the PCIe port but LCAP registers uses 1-based indexing in
 * most of the cases. Remapping logic needs to correctly map LCAP port number
 * (1-based or n-based) to coreboot indexing (0-based).
 */
struct pcie_rp_group {
	unsigned int slot;
	unsigned int start;
	unsigned int count;
	unsigned int lcap_port_base;
};

static inline unsigned int rp_start_fn(const struct pcie_rp_group *group)
{
	return group->start;
}

static inline unsigned int rp_end_fn(const struct pcie_rp_group *group)
{
	return group->start + group->count - 1;
}

/*
 * Update PCI paths of the root ports in the devicetree.
 *
 * Depending on the board layout and physical presence of downstream
 * devices, individual root-port functions can be hidden and reordered.
 * If we have device nodes for root ports in the static `devicetree.cb`,
 * we need to update their PCI paths, so the nodes still control the
 * correct root port. Device nodes for disabled root ports will be
 * unlinked from the bus, to not interfere with PCI enumeration.
 *
 * Call this once, after root ports have been reordered, but before PCI
 * enumeration.
 *
 * `groups` points to a list of groups terminated by an entry with `count == 0`.
 * It is assumed that the first group includes the RPs 1 to the first group's
 * `count` and that adjacent groups follow without gaps in the numbering.
 */
void pcie_rp_update_devicetree(const struct pcie_rp_group *groups);

/*
 * Return mask of PCIe root ports that are enabled by mainboard. Mask is set in
 * the same order as the root ports in pcie_rp_group groups table.
 *
 * Thus, the status of first root port in the groups table is indicated by bit 0
 * in the returned mask, second root port by bit 1 and so on.

 * 1 in the bit position indicates root port is enabled, whereas 0 indicates root
 * port is disabled. This function assumes that the maximum count of root ports
 * in the groups table is <= 32.
 */
uint32_t pcie_rp_enable_mask(const struct pcie_rp_group *groups);

/* Get PCH root port groups */
const struct pcie_rp_group *soc_get_pch_rp_groups(void);

enum pcie_rp_type {
	PCIE_RP_UNKNOWN,
	PCIE_RP_CPU,
	PCIE_RP_PCH,
};

/* For PCIe RTD3 support, each SoC that uses it must implement this function. */
struct device; /* Not necessary to include all of device/device.h */
enum pcie_rp_type soc_get_pcie_rp_type(const struct device *dev);

/* Return the virtual wire index that represents CPU-side PCIe root ports */
int soc_get_cpu_rp_vw_idx(const struct device *dev);

#endif /* SOC_INTEL_COMMON_BLOCK_PCIE_RP_H */