Message ID | 1491027219-5349-1-git-send-email-shilpa.bhat@linux.vnet.ibm.com |
---|---|
State | Changes Requested |
Headers | show |
On Sat, 2017-04-01 at 11:43 +0530, Shilpasri G Bhat wrote: > +#define P9_OCB_OCI_OCCMISC 0x6c080 > +#define P9_OCB_OCI_OCCMISC_AND 0x6c081 /* Write Clear */ Don't call it "AND", call it _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 There are a number of other OCC related bits in here which we need to understand the meaning. > 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); > } We need to implement a P9 version of the above. Right now that is writing a random SCOM somewhere, not a terribly good idea... > -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); >
On Sat, 2017-04-01 at 11:43 +0530, Shilpasri G Bhat wrote: > This patch fixes the SCOM address for OCC_MISC register which is used > for OCC interupts. What testing have you done on this? Mikey > Originally-from: Michael Neuling <mikey@neuling.org> > Signed-off-by: Shilpasri G Bhat <shilpa.bhat@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); >
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);
This patch fixes the SCOM address for OCC_MISC register which is used for OCC interupts. Originally-from: Michael Neuling <mikey@neuling.org> Signed-off-by: Shilpasri G Bhat <shilpa.bhat@linux.vnet.ibm.com> --- hw/occ.c | 61 +++++++++++++++++++++++++++++++++++++++++++++---------- hw/psi.c | 4 ++-- include/skiboot.h | 7 +++++-- 3 files changed, 57 insertions(+), 15 deletions(-)