[Skiboot] [PATCH] occ: irq: Fix SCOM address for OCC_MISC register
Shilpasri G Bhat
shilpa.bhat at linux.vnet.ibm.com
Sat Apr 1 17:13:39 AEDT 2017
This patch fixes the SCOM address for OCC_MISC register which is used
for OCC interupts.
Originally-from: Michael Neuling <mikey at neuling.org>
Signed-off-by: Shilpasri G Bhat <shilpa.bhat at linux.vnet.ibm.com>
---
hw/occ.c | 61 +++++++++++++++++++++++++++++++++++++++++++++----------
hw/psi.c | 4 ++--
include/skiboot.h | 7 +++++--
3 files changed, 57 insertions(+), 15 deletions(-)
diff --git a/hw/occ.c b/hw/occ.c
index 7b502b4..2ffb677 100644
--- a/hw/occ.c
+++ b/hw/occ.c
@@ -1279,17 +1279,25 @@ static struct fsp_client fsp_occ_client = {
.message = fsp_occ_msg,
};
-#define OCB_OCI_OCCMISC 0x6a020
-#define OCB_OCI_OCCMISC_AND 0x6a021
-#define OCB_OCI_OCCMISC_OR 0x6a022
+#define P8_OCB_OCI_OCCMISC 0x6a020
+#define P8_OCB_OCI_OCCMISC_AND 0x6a021
+#define P8_OCB_OCI_OCCMISC_OR 0x6a022
+
+#define P9_OCB_OCI_OCCMISC 0x6c080
+#define P9_OCB_OCI_OCCMISC_AND 0x6c081 /* Write Clear */
+#define P9_OCB_OCI_OCCMISC_OR 0x6c082
+
#define OCB_OCI_OCIMISC_IRQ PPC_BIT(0)
#define OCB_OCI_OCIMISC_IRQ_TMGT PPC_BIT(1)
#define OCB_OCI_OCIMISC_IRQ_SLW_TMR PPC_BIT(14)
#define OCB_OCI_OCIMISC_IRQ_OPAL_DUMMY PPC_BIT(15)
-#define OCB_OCI_OCIMISC_MASK (OCB_OCI_OCIMISC_IRQ_TMGT | \
+
+#define P8_OCB_OCI_OCIMISC_MASK (OCB_OCI_OCIMISC_IRQ_TMGT | \
OCB_OCI_OCIMISC_IRQ_OPAL_DUMMY | \
OCB_OCI_OCIMISC_IRQ_SLW_TMR)
+#define P9_OCB_OCI_OCIMISC_MASK OCB_OCI_OCIMISC_IRQ_TMGT
+
void occ_send_dummy_interrupt(void)
{
struct psi *psi;
@@ -1312,17 +1320,17 @@ void occ_send_dummy_interrupt(void)
return;
}
- xscom_write(psi->chip_id, OCB_OCI_OCCMISC_OR,
+ xscom_write(psi->chip_id, P8_OCB_OCI_OCCMISC_OR,
OCB_OCI_OCIMISC_IRQ | OCB_OCI_OCIMISC_IRQ_OPAL_DUMMY);
}
-void occ_interrupt(uint32_t chip_id)
+void occ_p8_interrupt(uint32_t chip_id)
{
uint64_t ireg;
int64_t rc;
/* The OCC interrupt is used to mux up to 15 different sources */
- rc = xscom_read(chip_id, OCB_OCI_OCCMISC, &ireg);
+ rc = xscom_read(chip_id, P8_OCB_OCI_OCCMISC, &ireg);
if (rc) {
prerror("OCC: Failed to read interrupt status !\n");
/* Should we mask it in the XIVR ? */
@@ -1331,7 +1339,7 @@ void occ_interrupt(uint32_t chip_id)
prlog(PR_TRACE, "OCC: IRQ received: %04llx\n", ireg >> 48);
/* Clear the bits */
- xscom_write(chip_id, OCB_OCI_OCCMISC_AND, ~ireg);
+ xscom_write(chip_id, P8_OCB_OCI_OCCMISC_AND, ~ireg);
/* Dispatch */
if (ireg & OCB_OCI_OCIMISC_IRQ_TMGT)
@@ -1343,9 +1351,40 @@ void occ_interrupt(uint32_t chip_id)
* OCCMISC_AND write. Check if there are any new source bits set,
* and trigger another interrupt if so.
*/
- rc = xscom_read(chip_id, OCB_OCI_OCCMISC, &ireg);
- if (!rc && (ireg & OCB_OCI_OCIMISC_MASK))
- xscom_write(chip_id, OCB_OCI_OCCMISC_OR, OCB_OCI_OCIMISC_IRQ);
+ rc = xscom_read(chip_id, P8_OCB_OCI_OCCMISC, &ireg);
+ if (!rc && (ireg & P8_OCB_OCI_OCIMISC_MASK))
+ xscom_write(chip_id, P8_OCB_OCI_OCCMISC_OR,
+ OCB_OCI_OCIMISC_IRQ);
+}
+
+void occ_p9_interrupt(uint32_t chip_id)
+{
+ u64 ireg;
+ s64 rc;
+
+ /* The OCC interrupt is used to mux up to 15 different sources */
+ rc = xscom_read(chip_id, P9_OCB_OCI_OCCMISC, &ireg);
+ if (rc) {
+ prerror("OCC: Failed to read interrupt status !\n");
+ return;
+ }
+ prlog(PR_TRACE, "OCC: IRQ received: %04llx\n", ireg >> 48);
+
+ /* Clear the bits */
+ xscom_write(chip_id, P9_OCB_OCI_OCCMISC_AND, ireg);
+
+ /* Dispatch */
+ if (ireg & OCB_OCI_OCIMISC_IRQ_TMGT)
+ prd_tmgt_interrupt(chip_id);
+
+ /* We may have masked-out OCB_OCI_OCIMISC_IRQ in the previous
+ * OCCMISC_AND write. Check if there are any new source bits set,
+ * and trigger another interrupt if so.
+ */
+ rc = xscom_read(chip_id, P9_OCB_OCI_OCCMISC, &ireg);
+ if (!rc && (ireg & P9_OCB_OCI_OCIMISC_MASK))
+ xscom_write(chip_id, P9_OCB_OCI_OCCMISC_OR,
+ OCB_OCI_OCIMISC_IRQ);
}
void occ_fsp_init(void)
diff --git a/hw/psi.c b/hw/psi.c
index 089f429..cc7db44 100644
--- a/hw/psi.c
+++ b/hw/psi.c
@@ -485,7 +485,7 @@ static void psihb_p8_interrupt(struct irq_source *is, uint32_t isn)
psihb_interrupt(is, isn);
break;
case P8_IRQ_PSI_OCC:
- occ_interrupt(psi->chip_id);
+ occ_p8_interrupt(psi->chip_id);
break;
case P8_IRQ_PSI_FSI:
printf("PSI: FSI irq received\n");
@@ -572,7 +572,7 @@ static void psihb_p9_interrupt(struct irq_source *is, uint32_t isn)
psihb_interrupt(is, isn);
break;
case P9_PSI_IRQ_OCC:
- occ_interrupt(psi->chip_id);
+ occ_p9_interrupt(psi->chip_id);
break;
case P9_PSI_IRQ_FSI:
printf("PSI: FSI irq received\n");
diff --git a/include/skiboot.h b/include/skiboot.h
index 8bc767a..2b1f8a5 100644
--- a/include/skiboot.h
+++ b/include/skiboot.h
@@ -254,10 +254,13 @@ enum {
extern void uart_set_console_policy(int policy);
extern bool uart_enabled(void);
-/* OCC interrupt */
-extern void occ_interrupt(uint32_t chip_id);
+/* OCC interrupt for P8 */
+extern void occ_p8_interrupt(uint32_t chip_id);
extern void occ_send_dummy_interrupt(void);
+/* OCC interrupt for P9 */
+extern void occ_p9_interrupt(uint32_t chip_id);
+
/* OCC load support */
extern void occ_poke_load_queue(void);
--
1.8.3.1
More information about the Skiboot
mailing list