SLW: Add init for power9 power management

Submitted by Akshay Adiga on Feb. 27, 2017, 6:36 a.m.

Details

Message ID 1488177413-19642-1-git-send-email-akshay.adiga@linux.vnet.ibm.com
State Changes Requested
Headers show

Commit Message

Akshay Adiga Feb. 27, 2017, 6:36 a.m.
This patch adds new function to init core for power9 power management.
SPECIAL_WKUP_* SCOM registers, if set, can hold the cores from going into
idle states. Hence, clear PPM SPECIAL_WKUP_HYP_REG scom register for each
core during init.

Signed-off-by: Akshay Adiga <akshay.adiga@linux.vnet.ibm.com>
---
 hw/slw.c        | 53 ++++++++++++++++++++++++++++++++++++++++++++++-------
 include/xscom.h |  6 ++++++
 2 files changed, 52 insertions(+), 7 deletions(-)

Comments

Vaidyanathan Srinivasan March 8, 2017, 4:22 a.m.
* Akshay Adiga <akshay.adiga@linux.vnet.ibm.com> [2017-02-27 12:06:53]:

> This patch adds new function to init core for power9 power management.
> SPECIAL_WKUP_* SCOM registers, if set, can hold the cores from going into
> idle states. Hence, clear PPM SPECIAL_WKUP_HYP_REG scom register for each
> core during init.
> 
> Signed-off-by: Akshay Adiga <akshay.adiga@linux.vnet.ibm.com>

Reviewed-by: Vaidyanathan Srinivasan <svaidy@linux.vnet.ibm.com>


> ---
>  hw/slw.c        | 53 ++++++++++++++++++++++++++++++++++++++++++++++-------
>  include/xscom.h |  6 ++++++
>  2 files changed, 52 insertions(+), 7 deletions(-)
> 
> diff --git a/hw/slw.c b/hw/slw.c
> index 1f59e83..3d94651 100644
> --- a/hw/slw.c
> +++ b/hw/slw.c
> @@ -287,6 +287,34 @@ static bool slw_set_overrides(struct proc_chip *chip, struct cpu_thread *c)
>  	return true;
>  }
>  
> +static bool slw_set_overrides_p9(struct proc_chip *chip, struct cpu_thread *c)
> +{
> +	uint64_t tmp;
> +	int rc;
> +	uint32_t core = pir_to_core_id(c->pir);
> +
> +	/* Clear special wakeup bits that could hold power mgt */
> +	rc = xscom_write(chip->id,
> +			 XSCOM_ADDR_P9_EC_SLAVE(core, EC_PPM_SPECIAL_WKUP_HYP),
> +			 0);
> +	if (rc) {
> +		log_simple_error(&e_info(OPAL_RC_SLW_SET),
> +			"SLW: Failed to write EC_PPM_SPECIAL_WKUP_HYP\n");
> +		return false;
> +	}
> +	/* Read back for debug */
> +	rc = xscom_read(chip->id,
> +			XSCOM_ADDR_P9_EC_SLAVE(core, EC_PPM_SPECIAL_WKUP_HYP),
> +			&tmp);
> +	prlog(PR_NOTICE, "SLW: EC_PPM_SPECIAL_WKUP_HYP read  0x%016llx\n", tmp);
> +	rc = xscom_read(chip->id,
> +			XSCOM_ADDR_P9_EC_SLAVE(core, EC_PPM_SPECIAL_WKUP_OTR),
> +			&tmp);
> +	if (tmp)
> +		prlog(PR_WARNING, "SLW: EC_PPM_SPECIAL_WKUP_OTR read  0x%016llx\n", tmp);
> +	return true;
> +}
> +
>  #ifdef __HAVE_LIBPORE__
>  static bool slw_unset_overrides(struct proc_chip *chip, struct cpu_thread *c)
>  {
> @@ -1085,6 +1113,16 @@ static void slw_patch_regs(struct proc_chip *chip)
>  }
>  #endif /* __HAVE_LIBPORE__ */
>  
> +static void slw_init_chip_p9(struct proc_chip *chip)
> +{
> +	struct cpu_thread *c;
> +
> +	prlog(PR_NOTICE, "SLW: Init chip 0x%x\n", chip->id);
> +
> +	/* At power ON setup inits for power-mgt */
> +	for_each_available_core_in_chip(c, chip->id)
> +		slw_set_overrides_p9(chip, c);
> +}
>  static void slw_init_chip(struct proc_chip *chip)
>  {
>  	int64_t rc;
> @@ -1444,11 +1482,12 @@ void slw_init(void)
>  {
>  	struct proc_chip *chip;
>  
> -	if (proc_gen != proc_gen_p8)
> -		return;
> -
> -	for_each_chip(chip)
> -		slw_init_chip(chip);
> -
> -	slw_init_timer();
> +	if (proc_gen == proc_gen_p8) {
> +		for_each_chip(chip)
> +			slw_init_chip(chip);
> +		slw_init_timer();
> +	} else if (proc_gen == proc_gen_p9) {
> +		for_each_chip(chip)
> +			slw_init_chip_p9(chip);
> +	}
>  }
> diff --git a/include/xscom.h b/include/xscom.h
> index bad9140..fae956d 100644
> --- a/include/xscom.h
> +++ b/include/xscom.h
> @@ -143,6 +143,12 @@
>  #define XSCOM_ADDR_P9_EC_SLAVE(core, addr) \
>  	XSCOM_ADDR_P9_EC(core, (addr) | 0xf0000)
>  
> +/* Power 9 EC slave per-core power mgt slave registers */
> +#define EC_PPM_SPECIAL_WKUP_OTR		0x010A
> +#define EC_PPM_SPECIAL_WKUP_FSP		0x010B
> +#define EC_PPM_SPECIAL_WKUP_OCC		0x010C
> +#define EC_PPM_SPECIAL_WKUP_HYP		0x010D
> +
>  /************* XXXX Move these P8 only registers elswhere !!! ****************/
>  
>  /* Per core power mgt registers */

Tesed on P9, clears special wakeups and sets up the chip for STOP
transitions.

--Vaidy
Stewart Smith March 23, 2017, 4:30 a.m.
Akshay Adiga <akshay.adiga@linux.vnet.ibm.com> writes:
> This patch adds new function to init core for power9 power management.
> SPECIAL_WKUP_* SCOM registers, if set, can hold the cores from going into
> idle states. Hence, clear PPM SPECIAL_WKUP_HYP_REG scom register for each
> core during init.
>
> Signed-off-by: Akshay Adiga <akshay.adiga@linux.vnet.ibm.com>
> ---
>  hw/slw.c        | 53 ++++++++++++++++++++++++++++++++++++++++++++++-------
>  include/xscom.h |  6 ++++++
>  2 files changed, 52 insertions(+), 7 deletions(-)

Hi! This breaks Mambo tests.

FYI, you can run them automatically yourself by pushing your code up to
github after enabling travis-ci.org for your personal repository. The
.travis.yml file in skiboot runs a wide variety of OSs and runs P8 and
P9 mambo boot tests.

The failure is this:

6352335: (6352335): [    0.006348678,5] SLW: Init chip 0x0
WARNING: 6352731: (6352731): Invalid address 0x0000000100780868 in XSCOM range,  SCOM=
0x01007808d
WARNING: 6352731: (6352731): Attempt to store non-existent address 0x00001A0100780868
6352731: (6352731): 0x000000003002E65C : stdcix  r26,r0,r3
FATAL ERROR: 6352731: (6352731): Check Stop for 0:0: Machine Check with ME bit of MSR 
off
Vaidyanathan Srinivasan March 23, 2017, 7:38 a.m.
* Stewart Smith <stewart@linux.vnet.ibm.com> [2017-03-23 15:30:09]:

> Akshay Adiga <akshay.adiga@linux.vnet.ibm.com> writes:
> > This patch adds new function to init core for power9 power management.
> > SPECIAL_WKUP_* SCOM registers, if set, can hold the cores from going into
> > idle states. Hence, clear PPM SPECIAL_WKUP_HYP_REG scom register for each
> > core during init.
> >
> > Signed-off-by: Akshay Adiga <akshay.adiga@linux.vnet.ibm.com>
> > ---
> >  hw/slw.c        | 53 ++++++++++++++++++++++++++++++++++++++++++++++-------
> >  include/xscom.h |  6 ++++++
> >  2 files changed, 52 insertions(+), 7 deletions(-)
> 
> Hi! This breaks Mambo tests.
> 
> FYI, you can run them automatically yourself by pushing your code up to
> github after enabling travis-ci.org for your personal repository. The
> .travis.yml file in skiboot runs a wide variety of OSs and runs P8 and
> P9 mambo boot tests.
> 
> The failure is this:
> 
> 6352335: (6352335): [    0.006348678,5] SLW: Init chip 0x0
> WARNING: 6352731: (6352731): Invalid address 0x0000000100780868 in XSCOM range,  SCOM=
> 0x01007808d
> WARNING: 6352731: (6352731): Attempt to store non-existent address 0x00001A0100780868
> 6352731: (6352731): 0x000000003002E65C : stdcix  r26,r0,r3
> FATAL ERROR: 6352731: (6352731): Check Stop for 0:0: Machine Check with ME bit of MSR 
> off

Hi Stewart,

Thanks for catching this issue.  We need to skip this xscoms access
and setup on mambo. We do on P8, need to fix that code path.

I will re-spin this patch with the fix so as to not break P9 mambo.

--Vaidy
Akshay Adiga March 23, 2017, 8:52 a.m.
On 03/23/2017 01:08 PM, Vaidyanathan Srinivasan wrote:
> * Stewart Smith <stewart@linux.vnet.ibm.com> [2017-03-23 15:30:09]:
>
> > Akshay Adiga <akshay.adiga@linux.vnet.ibm.com> writes:
> >> This patch adds new function to init core for power9 power management.
> >> SPECIAL_WKUP_* SCOM registers, if set, can hold the cores from going into
> >> idle states. Hence, clear PPM SPECIAL_WKUP_HYP_REG scom register for each
> >> core during init.
> >>
> >> Signed-off-by: Akshay Adiga <akshay.adiga@linux.vnet.ibm.com>
> >> ---
> >>  hw/slw.c        | 53 ++++++++++++++++++++++++++++++++++++++++++++++-------
> >>  include/xscom.h |  6 ++++++
> >>  2 files changed, 52 insertions(+), 7 deletions(-)
> >
> > Hi! This breaks Mambo tests.
> >
> > FYI, you can run them automatically yourself by pushing your code up to
> > github after enabling travis-ci.org for your personal repository. The
> > .travis.yml file in skiboot runs a wide variety of OSs and runs P8 and
> > P9 mambo boot tests.
> >
> > The failure is this:
> >
> > 6352335: (6352335): [    0.006348678,5] SLW: Init chip 0x0
> > WARNING: 6352731: (6352731): Invalid address 0x0000000100780868 in XSCOM range,  SCOM=
> > 0x01007808d
> > WARNING: 6352731: (6352731): Attempt to store non-existent address 0x00001A0100780868
> > 6352731: (6352731): 0x000000003002E65C : stdcix  r26,r0,r3
> > FATAL ERROR: 6352731: (6352731): Check Stop for 0:0: Machine Check with ME bit of MSR
> > off
>
> Hi Stewart,
>
> Thanks for catching this issue.  We need to skip this xscoms access
> and setup on mambo. We do on P8, need to fix that code path.
>
> I will re-spin this patch with the fix so as to not break P9 mambo.
>
> --Vaidy
>
Posted  v2 for the patch with the fix for p9 mambo.

--Akshay

Patch hide | download patch | download mbox

diff --git a/hw/slw.c b/hw/slw.c
index 1f59e83..3d94651 100644
--- a/hw/slw.c
+++ b/hw/slw.c
@@ -287,6 +287,34 @@  static bool slw_set_overrides(struct proc_chip *chip, struct cpu_thread *c)
 	return true;
 }
 
+static bool slw_set_overrides_p9(struct proc_chip *chip, struct cpu_thread *c)
+{
+	uint64_t tmp;
+	int rc;
+	uint32_t core = pir_to_core_id(c->pir);
+
+	/* Clear special wakeup bits that could hold power mgt */
+	rc = xscom_write(chip->id,
+			 XSCOM_ADDR_P9_EC_SLAVE(core, EC_PPM_SPECIAL_WKUP_HYP),
+			 0);
+	if (rc) {
+		log_simple_error(&e_info(OPAL_RC_SLW_SET),
+			"SLW: Failed to write EC_PPM_SPECIAL_WKUP_HYP\n");
+		return false;
+	}
+	/* Read back for debug */
+	rc = xscom_read(chip->id,
+			XSCOM_ADDR_P9_EC_SLAVE(core, EC_PPM_SPECIAL_WKUP_HYP),
+			&tmp);
+	prlog(PR_NOTICE, "SLW: EC_PPM_SPECIAL_WKUP_HYP read  0x%016llx\n", tmp);
+	rc = xscom_read(chip->id,
+			XSCOM_ADDR_P9_EC_SLAVE(core, EC_PPM_SPECIAL_WKUP_OTR),
+			&tmp);
+	if (tmp)
+		prlog(PR_WARNING, "SLW: EC_PPM_SPECIAL_WKUP_OTR read  0x%016llx\n", tmp);
+	return true;
+}
+
 #ifdef __HAVE_LIBPORE__
 static bool slw_unset_overrides(struct proc_chip *chip, struct cpu_thread *c)
 {
@@ -1085,6 +1113,16 @@  static void slw_patch_regs(struct proc_chip *chip)
 }
 #endif /* __HAVE_LIBPORE__ */
 
+static void slw_init_chip_p9(struct proc_chip *chip)
+{
+	struct cpu_thread *c;
+
+	prlog(PR_NOTICE, "SLW: Init chip 0x%x\n", chip->id);
+
+	/* At power ON setup inits for power-mgt */
+	for_each_available_core_in_chip(c, chip->id)
+		slw_set_overrides_p9(chip, c);
+}
 static void slw_init_chip(struct proc_chip *chip)
 {
 	int64_t rc;
@@ -1444,11 +1482,12 @@  void slw_init(void)
 {
 	struct proc_chip *chip;
 
-	if (proc_gen != proc_gen_p8)
-		return;
-
-	for_each_chip(chip)
-		slw_init_chip(chip);
-
-	slw_init_timer();
+	if (proc_gen == proc_gen_p8) {
+		for_each_chip(chip)
+			slw_init_chip(chip);
+		slw_init_timer();
+	} else if (proc_gen == proc_gen_p9) {
+		for_each_chip(chip)
+			slw_init_chip_p9(chip);
+	}
 }
diff --git a/include/xscom.h b/include/xscom.h
index bad9140..fae956d 100644
--- a/include/xscom.h
+++ b/include/xscom.h
@@ -143,6 +143,12 @@ 
 #define XSCOM_ADDR_P9_EC_SLAVE(core, addr) \
 	XSCOM_ADDR_P9_EC(core, (addr) | 0xf0000)
 
+/* Power 9 EC slave per-core power mgt slave registers */
+#define EC_PPM_SPECIAL_WKUP_OTR		0x010A
+#define EC_PPM_SPECIAL_WKUP_FSP		0x010B
+#define EC_PPM_SPECIAL_WKUP_OCC		0x010C
+#define EC_PPM_SPECIAL_WKUP_HYP		0x010D
+
 /************* XXXX Move these P8 only registers elswhere !!! ****************/
 
 /* Per core power mgt registers */