1 /* Copyright 2013-2016 IBM Corp.
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
12 * implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #ifndef __PCI_SLOT_H
18 #define __PCI_SLOT_H
19
20 #include <opal.h>
21 #include <device.h>
22 #include <timebase.h>
23 #include <timer.h>
24 #include <ccan/list/list.h>
25
26 /*
27 * PCI Slot Info: Wired Lane Values
28 *
29 * Values 0 to 6 match slot map 1005. In case of *any* change here
30 * make sure to keep the lxvpd.c parsing code in sync *and* the
31 * corresponding label strings in pci.c
32 */
33 #define PCI_SLOT_WIRED_LANES_UNKNOWN 0x00
34 #define PCI_SLOT_WIRED_LANES_PCIE_X1 0x01
35 #define PCI_SLOT_WIRED_LANES_PCIE_X2 0x02
36 #define PCI_SLOT_WIRED_LANES_PCIE_X4 0x03
37 #define PCI_SLOT_WIRED_LANES_PCIE_X8 0x04
38 #define PCI_SLOT_WIRED_LANES_PCIE_X16 0x05
39 #define PCI_SLOT_WIRED_LANES_PCIE_X32 0x06
40 #define PCI_SLOT_WIRED_LANES_PCIX_32 0x07
41 #define PCI_SLOT_WIRED_LANES_PCIX_64 0x08
42
43 /* PCI Slot Info: Bus Clock Values */
44 #define PCI_SLOT_BUS_CLK_RESERVED 0x00
45 #define PCI_SLOT_BUS_CLK_GEN_1 0x01
46 #define PCI_SLOT_BUS_CLK_GEN_2 0x02
47 #define PCI_SLOT_BUS_CLK_GEN_3 0x03
48
49 /* PCI Slot Info: Connector Type Values */
50 #define PCI_SLOT_CONNECTOR_PCIE_EMBED 0x00
51 #define PCI_SLOT_CONNECTOR_PCIE_X1 0x01
52 #define PCI_SLOT_CONNECTOR_PCIE_X2 0x02
53 #define PCI_SLOT_CONNECTOR_PCIE_X4 0x03
54 #define PCI_SLOT_CONNECTOR_PCIE_X8 0x04
55 #define PCI_SLOT_CONNECTOR_PCIE_X16 0x05
56 #define PCI_SLOT_CONNECTOR_PCIE_NS 0x0E /* Non-Standard */
57
58 /* PCI Slot Info: Card Description Values */
59 #define PCI_SLOT_DESC_NON_STANDARD 0x00 /* Embed/Non-Standard */
60 #define PCI_SLOT_DESC_PCIE_FH_FL 0x00 /* Full Height, Full Length */
61 #define PCI_SLOT_DESC_PCIE_FH_HL 0x01 /* Full Height, Half Length */
62 #define PCI_SLOT_DESC_PCIE_HH_FL 0x02 /* Half Height, Full Length */
63 #define PCI_SLOT_DESC_PCIE_HH_HL 0x03 /* Half Height, Half Length */
64
65 /* PCI Slot Info: Mechanicals Values */
66 #define PCI_SLOT_MECH_NONE 0x00
67 #define PCI_SLOT_MECH_RIGHT 0x01
68 #define PCI_SLOT_MECH_LEFT 0x02
69 #define PCI_SLOT_MECH_RIGHT_LEFT 0x03
70
71 /* PCI Slot Info: Power LED Control Values */
72 #define PCI_SLOT_PWR_LED_CTL_NONE 0x00 /* No Control */
73 #define PCI_SLOT_PWR_LED_CTL_FSP 0x01 /* FSP Controlled */
74 #define PCI_SLOT_PWR_LED_CTL_KERNEL 0x02 /* Kernel Controlled */
75
76 /* PCI Slot Info: ATTN LED Control Values */
77 #define PCI_SLOT_ATTN_LED_CTL_NONE 0x00 /* No Control */
78 #define PCI_SLOT_ATTN_LED_CTL_FSP 0x01 /* FSP Controlled */
79 #define PCI_SLOT_ATTN_LED_CTL_KERNEL 0x02 /* Kernel Controlled */
80
81 /* Attention LED */
82 #define PCI_SLOT_ATTN_LED_OFF 0
83 #define PCI_SLOT_ATTN_LED_ON 1
84 #define PCI_SLOT_ATTN_LED_BLINK 2
85
86 /* Power state */
87 #define PCI_SLOT_POWER_OFF 0
88 #define PCI_SLOT_POWER_ON 1
89
90 /*
91 * We have hard and soft reset for slot. Hard reset requires
92 * power-off and then power-on, but soft reset only resets
93 * secondary bus.
94 */
95 struct pci_slot;
96 struct pci_slot_ops {
97 /* For slot management */
98 int64_t (*get_presence_state)(struct pci_slot *slot, uint8_t *val);
99 int64_t (*get_link_state)(struct pci_slot *slot, uint8_t *val);
100 int64_t (*get_power_state)(struct pci_slot *slot, uint8_t *val);
101 int64_t (*get_attention_state)(struct pci_slot *slot, uint8_t *val);
102 int64_t (*get_latch_state)(struct pci_slot *slot, uint8_t *val);
103 int64_t (*set_power_state)(struct pci_slot *slot, uint8_t val);
104 int64_t (*set_attention_state)(struct pci_slot *slot, uint8_t val);
105
106 /* SM based functions for reset */
107 void (*prepare_link_change)(struct pci_slot *slot, bool is_up);
108 int64_t (*poll_link)(struct pci_slot *slot);
109 int64_t (*creset)(struct pci_slot *slot);
110 int64_t (*freset)(struct pci_slot *slot);
111 int64_t (*hreset)(struct pci_slot *slot);
112 int64_t (*run_sm)(struct pci_slot *slot);
113 int64_t (*completed_sm_run)(struct pci_slot *slot, uint64_t err);
114
115 /* Auxillary functions */
116 void (*add_properties)(struct pci_slot *slot, struct dt_node *np);
117 };
118
119 /*
120 * The PCI slot state is split up into base and number. With this
121 * design, the individual platforms can introduce their own PCI
122 * slot states with addition to the base. Eventually, the base
123 * state can be recognized by PCI slot core.
124 */
125 #define PCI_SLOT_STATE_MASK 0xFFFFFF00
126 #define PCI_SLOT_STATE_NORMAL 0x00000000
127 #define PCI_SLOT_STATE_LINK 0x00000100
128 #define PCI_SLOT_STATE_LINK_START_POLL (PCI_SLOT_STATE_LINK + 1)
129 #define PCI_SLOT_STATE_LINK_DELAY_FINALIZED (PCI_SLOT_STATE_LINK + 2)
130 #define PCI_SLOT_STATE_LINK_POLLING (PCI_SLOT_STATE_LINK + 3)
131 #define PCI_SLOT_STATE_HRESET 0x00000200
132 #define PCI_SLOT_STATE_HRESET_START (PCI_SLOT_STATE_HRESET + 1)
133 #define PCI_SLOT_STATE_HRESET_HOLD (PCI_SLOT_STATE_HRESET + 2)
134 #define PCI_SLOT_STATE_FRESET 0x00000300
135 #define PCI_SLOT_STATE_FRESET_POWER_OFF (PCI_SLOT_STATE_FRESET + 1)
136 #define PCI_SLOT_STATE_CRESET 0x00000400
137 #define PCI_SLOT_STATE_CRESET_START (PCI_SLOT_STATE_CRESET + 1)
138 #define PCI_SLOT_STATE_GPOWER 0x00000500
139 #define PCI_SLOT_STATE_GPOWER_START (PCI_SLOT_STATE_GPOWER + 1)
140 #define PCI_SLOT_STATE_SPOWER 0x00000600
141 #define PCI_SLOT_STATE_SPOWER_START (PCI_SLOT_STATE_SPOWER + 1)
142 #define PCI_SLOT_STATE_SPOWER_DONE (PCI_SLOT_STATE_SPOWER + 2)
143 #define PCI_SLOT_STATE_GPRESENCE 0x00000700
144 #define PCI_SLOT_STATE_GPRESENCE_START (PCI_SLOT_STATE_GPRESENCE + 1)
145
146
147 struct pci_slot {
148 uint32_t flags;
149 #define PCI_SLOT_FLAG_BOOTUP 0x1
150 #define PCI_SLOT_FLAG_FORCE_POWERON 0x2
151 #define PCI_SLOT_FLAG_BROKEN_PDC 0x4
152 #define PCI_SLOT_FLAG_ENFORCE 0x8
153
154 struct phb *phb;
155 struct pci_device *pd;
156
157 /* Identifier */
158 uint64_t id;
159 struct timer timer;
160 uint64_t async_token;
161 uint8_t power_state;
162
163 /* Slot information */
164 uint8_t pluggable;
165 uint8_t surprise_pluggable;
166 uint8_t power_ctl;
167 uint8_t power_led_ctl;
168 uint8_t attn_led_ctl;
169 uint8_t connector_type;
170 uint8_t card_desc;
171 uint8_t card_mech;
172 uint8_t wired_lanes;
173 uint8_t power_limit;
174
175 /*
176 * PCI slot is driven by state machine with polling function.
177 * @delay_tgt_tb tracks the current delay while @retries has
178 * the left rounds of delays. They should be set prior to
179 * switching next PCI slot state and changed (decreased)
180 * accordingly in the polling function.
181 */
182 uint32_t state;
183 uint32_t retry_state;
184 uint16_t pcie_cap;
185 uint32_t link_cap;
186 uint32_t slot_cap;
187 uint64_t delay_tgt_tb;
188 uint64_t retries;
189 uint64_t link_retries;
190 struct pci_slot_ops ops;
191 struct pci_slot *peer_slot;
192 void *data;
193 };
194
195 #define PCI_SLOT_ID_PREFIX 0x8000000000000000UL
196 #define PCI_SLOT_ID(phb, bdfn) \
197 (PCI_SLOT_ID_PREFIX | ((uint64_t)(bdfn) << 16) | (phb)->opal_id)
198 #define PCI_PHB_SLOT_ID(phb) ((phb)->opal_id)
199 #define PCI_SLOT_PHB_INDEX(id) ((id) & 0xfffful)
200 #define PCI_SLOT_BDFN(id) (((id) >> 16) & 0xfffful)
201
pci_slot_add_flags(struct pci_slot * slot,uint32_t flags)202 static inline uint32_t pci_slot_add_flags(struct pci_slot *slot,
203 uint32_t flags)
204 {
205 uint32_t old = 0;
206
207 if (slot) {
208 old = slot->flags;
209 slot->flags |= flags;
210 }
211
212 return old;
213 }
214
pci_slot_has_flags(struct pci_slot * slot,uint32_t flags)215 static inline bool pci_slot_has_flags(struct pci_slot *slot,
216 uint32_t flags)
217 {
218 if (!slot)
219 return false;
220
221 if ((slot->flags & flags) == flags)
222 return true;
223
224 return false;
225 }
226
pci_slot_remove_flags(struct pci_slot * slot,uint32_t flags)227 static inline uint32_t pci_slot_remove_flags(struct pci_slot *slot,
228 uint32_t flags)
229 {
230 uint32_t old = 0;
231
232 if (slot) {
233 old = slot->flags;
234 slot->flags &= ~flags;
235 }
236
237 return old;
238 }
239
pci_slot_set_state(struct pci_slot * slot,uint32_t state)240 static inline void pci_slot_set_state(struct pci_slot *slot, uint32_t state)
241 {
242 if (slot)
243 slot->state = state;
244 }
245
pci_slot_set_sm_timeout(struct pci_slot * slot,uint64_t dur)246 static inline uint64_t pci_slot_set_sm_timeout(struct pci_slot *slot,
247 uint64_t dur)
248 {
249 if (slot)
250 slot->delay_tgt_tb = mftb() + dur;
251 return dur;
252 }
253
254 extern struct pci_slot *pci_slot_alloc(struct phb *phb,
255 struct pci_device *pd);
256 extern struct pci_slot *pcie_slot_create(struct phb *phb,
257 struct pci_device *pd);
258 extern struct pci_slot *pcie_slot_create_dynamic(struct phb *phb,
259 struct pci_device *pd);
260
261 extern void pci_slot_add_dt_properties(struct pci_slot *slot,
262 struct dt_node *np);
263 extern struct pci_slot *pci_slot_find(uint64_t id);
264
265 extern void pci_slot_add_loc(struct pci_slot *slot,
266 struct dt_node *np, const char *label);
267
268 /* DT based slot map */
269
270 extern struct dt_node *dt_slots;
271 extern struct dt_node *map_pci_dev_to_slot(struct phb *phb,
272 struct pci_device *pd);
273
274 #endif /* __PCI_SLOT_H */
275