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