1 /* Copyright 2013-2014 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 /*
18 * Service Processor serial console handling code
19 */
20 #include <io.h>
21 #include <psi.h>
22 #include <fsp.h>
23 #include <opal.h>
24 #include <interrupts.h>
25 #include <cpu.h>
26 #include <dio-p9.h>
27 #include <trace.h>
28 #include <xscom.h>
29 #include <chip.h>
30 #include <lpc.h>
31 #include <i2c.h>
32 #include <timebase.h>
33 #include <platform.h>
34 #include <errorlog.h>
35 #include <xive.h>
36 #include <sbe-p9.h>
37 #include <phys-map.h>
38 #include <occ.h>
39
40 static LIST_HEAD(psis);
41 static u64 psi_link_timer;
42 static u64 psi_link_timeout;
43 static bool psi_link_poll_active;
44 static bool psi_ext_irq_policy = EXTERNAL_IRQ_POLICY_LINUX;
45
46 static void psi_activate_phb(struct psi *psi);
47
48 struct lock psi_lock = LOCK_UNLOCKED;
49
50 DEFINE_LOG_ENTRY(OPAL_RC_PSI_TIMEOUT, OPAL_PLATFORM_ERR_EVT, OPAL_PSI,
51 OPAL_PLATFORM_FIRMWARE,
52 OPAL_UNRECOVERABLE_ERR_LOSS_OF_FUNCTION, OPAL_NA);
53
psi_set_link_polling(bool active)54 void psi_set_link_polling(bool active)
55 {
56 printf("PSI: %sing link polling\n",
57 active ? "start" : "stopp");
58 psi_link_poll_active = active;
59 }
60
psi_disable_link(struct psi * psi)61 void psi_disable_link(struct psi *psi)
62 {
63 lock(&psi_lock);
64
65 /*
66 * Note: This can be called with the link already down but
67 * not detected as such yet by this layer since psi_check_link_active()
68 * operates locklessly and thus won't update the PSI structure. This
69 * is a non-issue, the only consequence is the messages in the log
70 * mentioning first the link having gone down then being disabled.
71 */
72 if (psi->active) {
73 u64 reg;
74 psi->active = false;
75
76 /* Mask errors in SEMR */
77 reg = in_be64(psi->regs + PSIHB_SEMR);
78 reg &= ((0xfffull << 36) | (0xfffull << 20));
79 out_be64(psi->regs + PSIHB_SEMR, reg);
80 printf("PSI: SEMR set to %llx\n", reg);
81
82 /* Reset all the error bits in PSIHB_CR and
83 * disable FSP interrupts
84 */
85 reg = in_be64(psi->regs + PSIHB_CR);
86 reg &= ~(0x7ffull << 20);
87 reg &= ~PSIHB_CR_PSI_LINK_ENABLE; /* flip link enable */
88 /*
89 * Ensure no commands/spurious interrupts reach
90 * the processor, by flipping the command enable.
91 */
92 reg &= ~PSIHB_CR_FSP_CMD_ENABLE;
93 reg &= ~PSIHB_CR_FSP_IRQ_ENABLE;
94 reg &= ~PSIHB_CR_FSP_IRQ; /* Clear interrupt state too */
95 printf("PSI[0x%03x]: Disabling link!\n", psi->chip_id);
96 out_be64(psi->regs + PSIHB_CR, reg);
97 printf("PSI: PSIHB_CR (error bits) set to %llx\n",
98 in_be64(psi->regs + PSIHB_CR));
99 psi_set_link_polling(true);
100 }
101
102 unlock(&psi_lock);
103 }
104
105 /*
106 * Resetting the FSP is a multi step sequence:
107 * 1. Read the PSIHBCR
108 * 2. Set the PSIHBCR[6] -- write register back.
109 * 3. Read PSIHBCR again
110 * 4. Reset PSIHBCR[6] -- write register back.
111 */
psi_reset_fsp(struct psi * psi)112 void psi_reset_fsp(struct psi *psi)
113 {
114 lock(&psi_lock);
115
116 if (psi->active) {
117 u64 reg;
118
119 printf("PSI: Driving FSP reset via PSI\n");
120 reg = in_be64(psi->regs + PSIHB_CR);
121 reg &= ~(0xfffull << 20); /* Reset error bits */
122 reg |= PSIHB_CR_FSP_RESET; /* FSP reset trigger start */
123 out_be64(psi->regs + PSIHB_CR, reg);
124 printf("PSI[0x%03x]: FSP reset start PSIHBCR set to %llx\n",
125 psi->chip_id, in_be64(psi->regs + PSIHB_CR));
126
127 reg = in_be64(psi->regs + PSIHB_CR);
128 reg &= ~PSIHB_CR_FSP_RESET; /* Clear FSP reset bit */
129 out_be64(psi->regs + PSIHB_CR, reg); /* Complete reset */
130 printf("PSI[0x%03x]: FSP reset complete. PSIHBCR set to %llx\n",
131 psi->chip_id, in_be64(psi->regs + PSIHB_CR));
132 }
133 unlock(&psi_lock);
134
135 /* Now bring down the PSI link too... */
136 psi_disable_link(psi);
137 }
138
psi_check_link_active(struct psi * psi)139 bool psi_check_link_active(struct psi *psi)
140 {
141 u64 val = in_be64(psi->regs + PSIHB_CR);
142
143 /*
144 * Unlocked, used during fsp_poke_msg so we really want
145 * to avoid fancy link re-entrancy and deadlocks here
146 */
147 if (!psi->active)
148 return false;
149 return (val & PSIHB_CR_PSI_LINK_ENABLE) &&
150 (val & PSIHB_CR_FSP_LINK_ACTIVE);
151 }
152
psi_find_link(uint32_t chip_id)153 struct psi *psi_find_link(uint32_t chip_id)
154 {
155 struct psi *psi;
156
157 list_for_each(&psis, psi, list) {
158 if (psi->chip_id == chip_id)
159 return psi;
160 }
161 return NULL;
162 }
163
164 #define PSI_LINK_CHECK_INTERVAL 10 /* Interval in secs */
165 #define PSI_LINK_RECOVERY_TIMEOUT 1800 /* 30 minutes */
166
psi_link_poll(void * data __unused)167 static void psi_link_poll(void *data __unused)
168 {
169 struct psi *psi;
170 u64 now;
171
172 if (!psi_link_poll_active)
173 return;
174
175 now = mftb();
176 if (psi_link_timer == 0 ||
177 (tb_compare(now, psi_link_timer) == TB_AAFTERB) ||
178 (tb_compare(now, psi_link_timer) == TB_AEQUALB)) {
179
180 lock(&psi_lock);
181
182 list_for_each(&psis, psi, list) {
183 u64 val;
184
185 if (psi->active)
186 continue;
187
188 val = in_be64(psi->regs + PSIHB_CR);
189
190 printf("PSI[0x%03x]: Poll CR=0x%016llx\n",
191 psi->chip_id, val);
192
193 if ((val & PSIHB_CR_PSI_LINK_ENABLE) &&
194 (val & PSIHB_CR_FSP_LINK_ACTIVE)) {
195 printf("PSI[0x%03x]: Found active link!\n",
196 psi->chip_id);
197 psi_link_timeout = 0;
198 psi->active = true;
199 psi_activate_phb(psi);
200 psi_set_link_polling(false);
201 unlock(&psi_lock);
202 if (platform.psi && platform.psi->link_established)
203 platform.psi->link_established();
204 return;
205 }
206 }
207 if (!psi_link_timeout)
208 psi_link_timeout =
209 now + secs_to_tb(PSI_LINK_RECOVERY_TIMEOUT);
210
211 if (tb_compare(now, psi_link_timeout) == TB_AAFTERB) {
212 log_simple_error(&e_info(OPAL_RC_PSI_TIMEOUT),
213 "PSI: Link timeout -- loss of FSP\n");
214 /* Reset the link timeout and continue looking */
215 psi_link_timeout = 0;
216 }
217
218 /* Poll every 10 seconds */
219 psi_link_timer = now + secs_to_tb(PSI_LINK_CHECK_INTERVAL);
220
221 unlock(&psi_lock);
222 }
223 }
224
psi_enable_fsp_interrupt(struct psi * psi)225 void psi_enable_fsp_interrupt(struct psi *psi)
226 {
227 /* Enable FSP interrupts in the GXHB */
228 lock(&psi_lock);
229 out_be64(psi->regs + PSIHB_CR,
230 in_be64(psi->regs + PSIHB_CR) | PSIHB_CR_FSP_IRQ_ENABLE);
231 unlock(&psi_lock);
232 }
233
234 /* Multiple bits can be set on errors */
decode_psihb_error(u64 val)235 static void decode_psihb_error(u64 val)
236 {
237 if (val & PSIHB_CR_PSI_ERROR)
238 printf("PSI: PSI Reported Error\n");
239 if (val & PSIHB_CR_PSI_LINK_INACTIVE)
240 printf("PSI: PSI Link Inactive Transition\n");
241 if (val & PSIHB_CR_FSP_ACK_TIMEOUT)
242 printf("PSI: FSP Ack Timeout\n");
243 if (val & PSIHB_CR_MMIO_LOAD_TIMEOUT)
244 printf("PSI: MMIO Load Timeout\n");
245 if (val & PSIHB_CR_MMIO_LENGTH_ERROR)
246 printf("PSI: MMIO Length Error\n");
247 if (val & PSIHB_CR_MMIO_ADDRESS_ERROR)
248 printf("PSI: MMIO Address Error\n");
249 if (val & PSIHB_CR_MMIO_TYPE_ERROR)
250 printf("PSI: MMIO Type Error\n");
251 if (val & PSIHB_CR_UE)
252 printf("PSI: UE Detected\n");
253 if (val & PSIHB_CR_PARITY_ERROR)
254 printf("PSI: Internal Parity Error\n");
255 if (val & PSIHB_CR_SYNC_ERR_ALERT1)
256 printf("PSI: Sync Error Alert1\n");
257 if (val & PSIHB_CR_SYNC_ERR_ALERT2)
258 printf("PSI: Sync Error Alert2\n");
259 if (val & PSIHB_CR_FSP_COMMAND_ERROR)
260 printf("PSI: FSP Command Error\n");
261 }
262
263
handle_psi_interrupt(struct psi * psi,u64 val)264 static void handle_psi_interrupt(struct psi *psi, u64 val)
265 {
266 printf("PSI[0x%03x]: PSI mgmnt interrupt CR=0x%016llx\n",
267 psi->chip_id, val);
268
269 if (val & (0xfffull << 20)) {
270 decode_psihb_error(val);
271 psi_disable_link(psi);
272 } else if (val & (0x1full << 11))
273 printf("PSI: FSP error detected\n");
274 }
275
psi_spurious_fsp_irq(struct psi * psi)276 static void psi_spurious_fsp_irq(struct psi *psi)
277 {
278 u64 reg, bit;
279
280 prerror("PSI: Spurious interrupt, attempting clear\n");
281
282 if (proc_gen == proc_gen_p9) {
283 reg = PSIHB_XSCOM_P9_HBCSR_CLR;
284 bit = PSIHB_XSCOM_P9_HBSCR_FSP_IRQ;
285 } else if (proc_gen == proc_gen_p8) {
286 reg = PSIHB_XSCOM_P8_HBCSR_CLR;
287 bit = PSIHB_XSCOM_P8_HBSCR_FSP_IRQ;
288 } else {
289 assert(false);
290 }
291 xscom_write(psi->chip_id, psi->xscom_base + reg, bit);
292 }
293
psi_poll_fsp_interrupt(struct psi * psi)294 bool psi_poll_fsp_interrupt(struct psi *psi)
295 {
296 return !!(in_be64(psi->regs + PSIHB_CR) & PSIHB_CR_FSP_IRQ);
297 }
298
psihb_interrupt(struct irq_source * is,uint32_t isn __unused)299 static void psihb_interrupt(struct irq_source *is, uint32_t isn __unused)
300 {
301 struct psi *psi = is->data;
302 u64 val;
303
304 val = in_be64(psi->regs + PSIHB_CR);
305
306 if (psi_link_poll_active) {
307 printf("PSI[0x%03x]: PSI interrupt CR=0x%016llx (A=%d)\n",
308 psi->chip_id, val, psi->active);
309 }
310
311 /* Handle PSI interrupts first in case it's a link down */
312 if (val & PSIHB_CR_PSI_IRQ) {
313 handle_psi_interrupt(psi, val);
314
315 /*
316 * If the link went down, re-read PSIHB_CR as
317 * the FSP interrupt might have been cleared.
318 */
319 if (!psi->active)
320 val = in_be64(psi->regs + PSIHB_CR);
321 }
322
323
324 /*
325 * We avoid forwarding FSP interrupts if the link isn't
326 * active. They should be masked anyway but it looks
327 * like the CR bit can remain set.
328 */
329 if (val & PSIHB_CR_FSP_IRQ) {
330 /*
331 * We have a case a flood with FSP mailbox interrupts
332 * when the link is down, see if we manage to clear
333 * the condition
334 */
335 if (!psi->active)
336 psi_spurious_fsp_irq(psi);
337 else {
338 if (platform.psi && platform.psi->fsp_interrupt)
339 platform.psi->fsp_interrupt();
340 }
341 }
342
343 if (platform.psi && platform.psi->psihb_interrupt)
344 platform.psi->psihb_interrupt();
345 }
346
347
348 static const uint32_t psi_p8_irq_to_xivr[P8_IRQ_PSI_IRQ_COUNT] = {
349 [P8_IRQ_PSI_FSP] = PSIHB_XIVR_FSP,
350 [P8_IRQ_PSI_OCC] = PSIHB_XIVR_OCC,
351 [P8_IRQ_PSI_FSI] = PSIHB_XIVR_FSI,
352 [P8_IRQ_PSI_LPC] = PSIHB_XIVR_LPC,
353 [P8_IRQ_PSI_LOCAL_ERR] = PSIHB_XIVR_LOCAL_ERR,
354 [P8_IRQ_PSI_EXTERNAL]= PSIHB_XIVR_HOST_ERR,
355 };
356
psi_cleanup_irq(struct psi * psi)357 static void psi_cleanup_irq(struct psi *psi)
358 {
359 uint32_t irq;
360 uint64_t xivr, xivr_p;
361
362 for (irq = 0; irq < P8_IRQ_PSI_IRQ_COUNT; irq++) {
363 prlog(PR_DEBUG, "PSI[0x%03x]: Cleaning up IRQ %d\n",
364 psi->chip_id, irq);
365
366 xivr_p = psi_p8_irq_to_xivr[irq];
367 xivr = in_be64(psi->regs + xivr_p);
368 xivr |= (0xffull << 32);
369 out_be64(psi->regs + xivr_p, xivr);
370 time_wait_ms_nopoll(10);
371 xivr = in_be64(psi->regs + xivr_p);
372 if (xivr & PPC_BIT(39)) {
373 printf(" Need EOI !\n");
374 icp_send_eoi(psi->interrupt + irq);
375 }
376 }
377 }
378
379 /* Called on a fast reset, make sure we aren't stuck with
380 * an accepted and never EOId PSI interrupt
381 */
psi_irq_reset(void)382 void psi_irq_reset(void)
383 {
384 struct psi *psi;
385
386 printf("PSI: Hot reset!\n");
387
388 assert(proc_gen == proc_gen_p8);
389
390 list_for_each(&psis, psi, list) {
391 psi_cleanup_irq(psi);
392 }
393 }
394
psi_p8_set_xive(struct irq_source * is,uint32_t isn,uint16_t server,uint8_t priority)395 static int64_t psi_p8_set_xive(struct irq_source *is, uint32_t isn,
396 uint16_t server, uint8_t priority)
397 {
398 struct psi *psi = is->data;
399 uint64_t xivr_p, xivr;
400 uint32_t irq_idx = isn & 7;
401
402 if (irq_idx >= P8_IRQ_PSI_IRQ_COUNT)
403 return OPAL_PARAMETER;
404 xivr_p = psi_p8_irq_to_xivr[irq_idx];
405
406 /* Populate the XIVR */
407 xivr = (uint64_t)server << 40;
408 xivr |= (uint64_t)priority << 32;
409 xivr |= (uint64_t)(isn & 7) << 29;
410
411 out_be64(psi->regs + xivr_p, xivr);
412
413 return OPAL_SUCCESS;
414 }
415
psi_p8_get_xive(struct irq_source * is,uint32_t isn __unused,uint16_t * server,uint8_t * priority)416 static int64_t psi_p8_get_xive(struct irq_source *is, uint32_t isn __unused,
417 uint16_t *server, uint8_t *priority)
418 {
419 struct psi *psi = is->data;
420 uint64_t xivr_p, xivr;
421 uint32_t irq_idx = isn & 7;
422
423 if (irq_idx >= P8_IRQ_PSI_IRQ_COUNT)
424 return OPAL_PARAMETER;
425
426 xivr_p = psi_p8_irq_to_xivr[irq_idx];
427
428 /* Read & decode the XIVR */
429 xivr = in_be64(psi->regs + xivr_p);
430
431 *server = (xivr >> 40) & 0xffff;
432 *priority = (xivr >> 32) & 0xff;
433
434 return OPAL_SUCCESS;
435 }
436
psihb_p8_interrupt(struct irq_source * is,uint32_t isn)437 static void psihb_p8_interrupt(struct irq_source *is, uint32_t isn)
438 {
439 struct psi *psi = is->data;
440 uint32_t idx = isn - psi->interrupt;
441
442 switch (idx) {
443 case P8_IRQ_PSI_FSP:
444 psihb_interrupt(is, isn);
445 break;
446 case P8_IRQ_PSI_OCC:
447 occ_p8_interrupt(psi->chip_id);
448 break;
449 case P8_IRQ_PSI_FSI:
450 printf("PSI: FSI irq received\n");
451 break;
452 case P8_IRQ_PSI_LPC:
453 lpc_interrupt(psi->chip_id);
454
455 /*
456 * i2c interrupts are ORed with the LPC ones on
457 * Murano DD2.1 and Venice DD2.0
458 */
459 p8_i2c_interrupt(psi->chip_id);
460 break;
461 case P8_IRQ_PSI_LOCAL_ERR:
462 prd_psi_interrupt(psi->chip_id);
463 break;
464 case P8_IRQ_PSI_EXTERNAL:
465 if (platform.external_irq)
466 platform.external_irq(psi->chip_id);
467 break;
468 }
469
470 /*
471 * TODO: Per Vicente Chung, CRESPs don't generate interrupts,
472 * and are just informational. Need to define the policy
473 * to handle them.
474 */
475 }
476
psi_p8_irq_attributes(struct irq_source * is,uint32_t isn)477 static uint64_t psi_p8_irq_attributes(struct irq_source *is, uint32_t isn)
478 {
479 struct psi *psi = is->data;
480 uint32_t idx = isn - psi->interrupt;
481 uint64_t attr;
482
483 if (psi->no_lpc_irqs && idx == P8_IRQ_PSI_LPC)
484 return IRQ_ATTR_TARGET_LINUX;
485
486 if (idx == P8_IRQ_PSI_EXTERNAL &&
487 psi_ext_irq_policy == EXTERNAL_IRQ_POLICY_LINUX)
488 return IRQ_ATTR_TARGET_LINUX;
489
490 attr = IRQ_ATTR_TARGET_OPAL | IRQ_ATTR_TYPE_LSI;
491 if (idx == P8_IRQ_PSI_EXTERNAL || idx == P8_IRQ_PSI_LPC ||
492 idx == P8_IRQ_PSI_FSP)
493 attr |= IRQ_ATTR_TARGET_FREQUENT;
494 return attr;
495 }
496
psi_p8_irq_name(struct irq_source * is,uint32_t isn)497 static char *psi_p8_irq_name(struct irq_source *is, uint32_t isn)
498 {
499 struct psi *psi = is->data;
500 uint32_t idx = isn - psi->interrupt;
501
502 static const char *names[P8_IRQ_PSI_IRQ_COUNT] = {
503 "psi:fsp",
504 "psi:occ",
505 "psi:fsi",
506 "psi:lpchc",
507 "psi:local_err",
508 "psi:external",
509 };
510
511 if (idx >= P8_IRQ_PSI_IRQ_COUNT)
512 return NULL;
513 return strdup(names[idx]);
514 }
515
516 static const struct irq_source_ops psi_p8_irq_ops = {
517 .get_xive = psi_p8_get_xive,
518 .set_xive = psi_p8_set_xive,
519 .interrupt = psihb_p8_interrupt,
520 .attributes = psi_p8_irq_attributes,
521 .name = psi_p8_irq_name,
522 };
523
psihb_p9_interrupt(struct irq_source * is,uint32_t isn)524 static void psihb_p9_interrupt(struct irq_source *is, uint32_t isn)
525 {
526 struct psi *psi = is->data;
527 uint32_t idx = isn - psi->interrupt;
528
529 switch (idx) {
530 case P9_PSI_IRQ_PSI:
531 psihb_interrupt(is, isn);
532 break;
533 case P9_PSI_IRQ_OCC:
534 occ_p9_interrupt(psi->chip_id);
535 break;
536 case P9_PSI_IRQ_FSI:
537 printf("PSI: FSI irq received\n");
538 break;
539 case P9_PSI_IRQ_LPCHC:
540 lpc_interrupt(psi->chip_id);
541 break;
542 case P9_PSI_IRQ_LOCAL_ERR:
543 prd_psi_interrupt(psi->chip_id);
544 break;
545 case P9_PSI_IRQ_GLOBAL_ERR:
546 printf("PSI: Global error irq received\n");
547 break;
548 case P9_PSI_IRQ_EXTERNAL:
549 if (platform.external_irq)
550 platform.external_irq(psi->chip_id);
551 break;
552 case P9_PSI_IRQ_LPC_SIRQ0:
553 case P9_PSI_IRQ_LPC_SIRQ1:
554 case P9_PSI_IRQ_LPC_SIRQ2:
555 case P9_PSI_IRQ_LPC_SIRQ3:
556 lpc_serirq(psi->chip_id, idx - P9_PSI_IRQ_LPC_SIRQ0);
557 break;
558 case P9_PSI_IRQ_SBE_I2C:
559 p8_i2c_interrupt(psi->chip_id);
560 break;
561 case P9_PSI_IRQ_DIO:
562 printf("PSI: DIO irq received\n");
563 dio_interrupt_handler(psi->chip_id);
564 break;
565 case P9_PSI_IRQ_PSU:
566 p9_sbe_interrupt(psi->chip_id);
567 break;
568 }
569 }
570
psi_p9_irq_attributes(struct irq_source * is __unused,uint32_t isn)571 static uint64_t psi_p9_irq_attributes(struct irq_source *is __unused,
572 uint32_t isn)
573 {
574 struct psi *psi = is->data;
575 unsigned int idx = isn & 0xf;
576 bool is_lpc_serirq;
577
578 is_lpc_serirq =
579 (idx == P9_PSI_IRQ_LPC_SIRQ0 ||
580 idx == P9_PSI_IRQ_LPC_SIRQ1 ||
581 idx == P9_PSI_IRQ_LPC_SIRQ2 ||
582 idx == P9_PSI_IRQ_LPC_SIRQ3);
583
584 /* If LPC interrupts are disabled, route them to Linux
585 * (who will not request them since they aren't referenced
586 * in the device tree)
587 */
588 if (is_lpc_serirq && psi->no_lpc_irqs)
589 return IRQ_ATTR_TARGET_LINUX;
590
591 /* For serirq, check the LPC layer for policy */
592 if (is_lpc_serirq)
593 return lpc_get_irq_policy(psi->chip_id, idx - P9_PSI_IRQ_LPC_SIRQ0);
594
595 return IRQ_ATTR_TARGET_OPAL | IRQ_ATTR_TYPE_LSI;
596 }
597
psi_p9_irq_name(struct irq_source * is,uint32_t isn)598 static char *psi_p9_irq_name(struct irq_source *is, uint32_t isn)
599 {
600 struct psi *psi = is->data;
601 uint32_t idx = isn - psi->interrupt;
602
603 static const char *names[P9_PSI_NUM_IRQS] = {
604 "psi:fsp",
605 "psi:occ",
606 "psi:fsi",
607 "psi:lpchc",
608 "psi:local_err",
609 "psi:global_err",
610 "psi:external",
611 "psi:lpc_serirq_mux0", /* Have a callback to get name ? */
612 "psi:lpc_serirq_mux1", /* Have a callback to get name ? */
613 "psi:lpc_serirq_mux2", /* Have a callback to get name ? */
614 "psi:lpc_serirq_mux3", /* Have a callback to get name ? */
615 "psi:i2c",
616 "psi:dio",
617 "psi:psu"
618 };
619
620 if (idx >= P9_PSI_NUM_IRQS)
621 return NULL;
622 return strdup(names[idx]);
623 }
624
625 static const struct irq_source_ops psi_p9_irq_ops = {
626 .interrupt = psihb_p9_interrupt,
627 .attributes = psi_p9_irq_attributes,
628 .name = psi_p9_irq_name,
629 };
630
psi_set_external_irq_policy(bool policy)631 void psi_set_external_irq_policy(bool policy)
632 {
633 psi_ext_irq_policy = policy;
634 }
635
psi_init_p8_interrupts(struct psi * psi)636 static void psi_init_p8_interrupts(struct psi *psi)
637 {
638 uint32_t irq;
639 uint64_t xivr_p;
640
641 /* On P8 we get a block of 8, set up the base/mask
642 * and mask all the sources for now
643 */
644 out_be64(psi->regs + PSIHB_IRSN,
645 SETFIELD(PSIHB_IRSN_COMP, 0ul, psi->interrupt) |
646 SETFIELD(PSIHB_IRSN_MASK, 0ul, 0x7fff8ul) |
647 PSIHB_IRSN_DOWNSTREAM_EN |
648 PSIHB_IRSN_UPSTREAM_EN);
649
650 for (irq = 0; irq < P8_IRQ_PSI_IRQ_COUNT; irq++) {
651 xivr_p = psi_p8_irq_to_xivr[irq];
652 out_be64(psi->regs + xivr_p, (0xffull << 32) | (irq << 29));
653 }
654
655 /*
656 * Register the IRQ sources FSP, OCC, FSI, LPC
657 * and Local Error. Host Error is actually the
658 * external interrupt and the policy for that comes
659 * from the platform
660 */
661 register_irq_source(&psi_p8_irq_ops, psi,
662 psi->interrupt, P8_IRQ_PSI_IRQ_COUNT);
663 }
664
psi_init_p9_interrupts(struct psi * psi)665 static void psi_init_p9_interrupts(struct psi *psi)
666 {
667 struct proc_chip *chip;
668 u64 val;
669
670 /* Grab chip */
671 chip = get_chip(psi->chip_id);
672 if (!chip)
673 return;
674
675 /* Configure the CI BAR */
676 phys_map_get(chip->id, PSIHB_ESB, 0, &val, NULL);
677 val |= PSIHB_ESB_CI_VALID;
678 out_be64(psi->regs + PSIHB_ESB_CI_BASE, val);
679
680 val = in_be64(psi->regs + PSIHB_ESB_CI_BASE);
681 psi->esb_mmio = (void *)(val & ~PSIHB_ESB_CI_VALID);
682 prlog(PR_DEBUG, "PSI[0x%03x]: ESB MMIO at @%p\n",
683 psi->chip_id, psi->esb_mmio);
684
685 /* Grab and configure the notification port */
686 val = xive_get_notify_port(psi->chip_id, XIVE_HW_SRC_PSI);
687 val |= PSIHB_ESB_NOTIF_VALID;
688 out_be64(psi->regs + PSIHB_ESB_NOTIF_ADDR, val);
689
690 /* Setup interrupt offset */
691 val = xive_get_notify_base(psi->interrupt);
692 val <<= 32;
693 out_be64(psi->regs + PSIHB_IVT_OFFSET, val);
694
695 /* Register sources */
696 prlog(PR_DEBUG,
697 "PSI[0x%03x]: Interrupts sources registered for P9 DD2.x\n",
698 psi->chip_id);
699 xive_register_hw_source(psi->interrupt, P9_PSI_NUM_IRQS,
700 12, psi->esb_mmio, XIVE_SRC_LSI,
701 psi, &psi_p9_irq_ops);
702
703 /* Reset irq handling and switch to ESB mode */
704 out_be64(psi->regs + PSIHB_INTERRUPT_CONTROL, PSIHB_IRQ_RESET);
705 out_be64(psi->regs + PSIHB_INTERRUPT_CONTROL, 0);
706 }
707
psi_init_interrupts(struct psi * psi)708 static void psi_init_interrupts(struct psi *psi)
709 {
710 /* Configure the interrupt BUID and mask it */
711 switch (proc_gen) {
712 case proc_gen_p8:
713 psi_init_p8_interrupts(psi);
714 break;
715 case proc_gen_p9:
716 psi_init_p9_interrupts(psi);
717 break;
718 default:
719 /* Unknown: just no interrupts */
720 prerror("PSI: Unknown interrupt type\n");
721 }
722 }
723
psi_activate_phb(struct psi * psi)724 static void psi_activate_phb(struct psi *psi)
725 {
726 u64 reg;
727
728 /*
729 * Disable interrupt emission in the control register,
730 * it will be re-enabled later, after the mailbox one
731 * will have been enabled.
732 */
733 reg = in_be64(psi->regs + PSIHB_CR);
734 reg &= ~PSIHB_CR_FSP_IRQ_ENABLE;
735 out_be64(psi->regs + PSIHB_CR, reg);
736
737 /* Enable interrupts in the mask register. We enable everything
738 * except for bit "FSP command error detected" which the doc
739 * (P7 BookIV) says should be masked for normal ops. It also
740 * seems to be masked under OPAL.
741 */
742 reg = 0x0000010000100000ull;
743 out_be64(psi->regs + PSIHB_SEMR, reg);
744
745 #if 0
746 /* Dump the GXHB registers */
747 printf(" PSIHB_BBAR : %llx\n",
748 in_be64(psi->regs + PSIHB_BBAR));
749 printf(" PSIHB_FSPBAR : %llx\n",
750 in_be64(psi->regs + PSIHB_FSPBAR));
751 printf(" PSIHB_FSPMMR : %llx\n",
752 in_be64(psi->regs + PSIHB_FSPMMR));
753 printf(" PSIHB_TAR : %llx\n",
754 in_be64(psi->regs + PSIHB_TAR));
755 printf(" PSIHB_CR : %llx\n",
756 in_be64(psi->regs + PSIHB_CR));
757 printf(" PSIHB_SEMR : %llx\n",
758 in_be64(psi->regs + PSIHB_SEMR));
759 printf(" PSIHB_XIVR : %llx\n",
760 in_be64(psi->regs + PSIHB_XIVR));
761 #endif
762 }
763
psi_create_p9_int_map(struct psi * psi,struct dt_node * np)764 static void psi_create_p9_int_map(struct psi *psi, struct dt_node *np)
765 {
766 uint32_t map[P9_PSI_NUM_IRQS][4];
767 int i;
768
769 for (i = 0; i < P9_PSI_NUM_IRQS; i++) {
770 map[i][0] = i;
771 map[i][1] = get_ics_phandle();
772 map[i][2] = psi->interrupt + i;
773 map[i][3] = 1;
774 }
775 dt_add_property(np, "interrupt-map", map, sizeof(map));
776 dt_add_property_cells(np, "#address-cells", 0);
777 dt_add_property_cells(np, "#interrupt-cells", 1);
778 }
779
psi_create_mm_dtnode(struct psi * psi)780 static void psi_create_mm_dtnode(struct psi *psi)
781 {
782 struct dt_node *np;
783 uint64_t addr = (uint64_t)psi->regs;
784
785 np = dt_new_addr(dt_root, "psi", addr);
786 if (!np)
787 return;
788
789 /* Hard wire size to 4G */
790 dt_add_property_u64s(np, "reg", addr, 0x100000000ull);
791 switch (proc_gen) {
792 case proc_gen_p8:
793 dt_add_property_strings(np, "compatible", "ibm,psi",
794 "ibm,power8-psi");
795 break;
796 case proc_gen_p9:
797 dt_add_property_strings(np, "compatible", "ibm,psi",
798 "ibm,power9-psi");
799 psi_create_p9_int_map(psi, np);
800 break;
801 default:
802 dt_add_property_strings(np, "compatible", "ibm,psi");
803 }
804 dt_add_property_cells(np, "interrupt-parent", get_ics_phandle());
805 dt_add_property_cells(np, "interrupts", psi->interrupt, 1);
806 dt_add_property_cells(np, "ibm,chip-id", psi->chip_id);
807 psi->node = np;
808 }
809
alloc_psi(struct proc_chip * chip,uint64_t base)810 static struct psi *alloc_psi(struct proc_chip *chip, uint64_t base)
811 {
812 struct psi *psi;
813
814 psi = zalloc(sizeof(struct psi));
815 if (!psi) {
816 prerror("PSI: Could not allocate memory\n");
817 return NULL;
818 }
819 psi->xscom_base = base;
820 psi->chip_id = chip->id;
821 return psi;
822 }
823
psi_probe_p8(struct proc_chip * chip,u64 base)824 static struct psi *psi_probe_p8(struct proc_chip *chip, u64 base)
825 {
826 struct psi *psi = NULL;
827 uint64_t rc, val;
828
829 rc = xscom_read(chip->id, base + PSIHB_XSCOM_P8_BASE, &val);
830 if (rc) {
831 prerror("PSI[0x%03x]: Error %llx reading PSIHB BAR\n",
832 chip->id, rc);
833 return NULL;
834 }
835 if (val & PSIHB_XSCOM_P8_HBBAR_EN) {
836 psi = alloc_psi(chip, base);
837 if (!psi)
838 return NULL;
839 psi->regs = (void *)(val & ~PSIHB_XSCOM_P8_HBBAR_EN);
840 psi->interrupt = get_psi_interrupt(chip->id);
841 } else
842 printf("PSI[0x%03x]: Working chip not found\n", chip->id);
843
844 return psi;
845 }
846
psi_probe_p9(struct proc_chip * chip,u64 base)847 static struct psi *psi_probe_p9(struct proc_chip *chip, u64 base)
848 {
849 struct psi *psi = NULL;
850 uint64_t addr;
851
852 phys_map_get(chip->id, PSIHB_REG, 0, &addr, NULL);
853 xscom_write(chip->id, base + PSIHB_XSCOM_P9_BASE,
854 addr | PSIHB_XSCOM_P9_HBBAR_EN);
855
856 psi = alloc_psi(chip, base);
857 if (!psi)
858 return NULL;
859 psi->regs = (void *)addr;
860 psi->interrupt = xive_alloc_hw_irqs(chip->id, P9_PSI_NUM_IRQS, 16);
861 return psi;
862 }
863
psi_init_psihb(struct dt_node * psihb)864 static bool psi_init_psihb(struct dt_node *psihb)
865 {
866 uint32_t chip_id = dt_get_chip_id(psihb);
867 struct proc_chip *chip = get_chip(chip_id);
868 struct psi *psi = NULL;
869 u64 base, val;
870
871 if (!chip) {
872 prerror("PSI: Can't find chip!\n");
873 return false;
874 }
875
876 base = dt_get_address(psihb, 0, NULL);
877
878 if (dt_node_is_compatible(psihb, "ibm,power8-psihb-x"))
879 psi = psi_probe_p8(chip, base);
880 else if (dt_node_is_compatible(psihb, "ibm,power9-psihb-x"))
881 psi = psi_probe_p9(chip, base);
882 else {
883 prerror("PSI: Unknown processor type\n");
884 return false;
885 }
886 if (!psi)
887 return false;
888
889 list_add(&psis, &psi->list);
890
891 val = in_be64(psi->regs + PSIHB_CR);
892 if (val & PSIHB_CR_FSP_LINK_ACTIVE) {
893 lock(&psi_lock);
894 psi->active = true;
895 unlock(&psi_lock);
896 }
897 chip->psi = psi;
898
899 if (dt_has_node_property(psihb, "no-lpc-interrupts", NULL))
900 psi->no_lpc_irqs = true;
901
902 psi_activate_phb(psi);
903 psi_init_interrupts(psi);
904 psi_create_mm_dtnode(psi);
905
906 prlog(PR_INFO, "PSI[0x%03x]: Found PSI bridge [active=%d]\n",
907 psi->chip_id, psi->active);
908 return true;
909 }
910
psi_fsp_link_in_use(struct psi * psi __unused)911 void psi_fsp_link_in_use(struct psi *psi __unused)
912 {
913 static bool poller_created = false;
914
915 /* Do this once only */
916 if (!poller_created) {
917 poller_created = true;
918 opal_add_poller(psi_link_poll, NULL);
919 }
920 }
921
psi_find_functional_chip(void)922 struct psi *psi_find_functional_chip(void)
923 {
924 return list_top(&psis, struct psi, list);
925 }
926
psi_init(void)927 void psi_init(void)
928 {
929 struct dt_node *np;
930
931 dt_for_each_compatible(dt_root, np, "ibm,psihb-x")
932 psi_init_psihb(np);
933 }
934
935
936