diff mbox

occ: irq: Fix SCOM address for OCC_MISC register

Message ID 1491027219-5349-1-git-send-email-shilpa.bhat@linux.vnet.ibm.com
State Changes Requested
Headers show

Commit Message

Shilpasri G Bhat April 1, 2017, 6:13 a.m. UTC
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(-)

Comments

Benjamin Herrenschmidt April 1, 2017, 8:50 a.m. UTC | #1
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);
>
Michael Neuling April 3, 2017, 9:21 a.m. UTC | #2
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 mbox

Patch

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);