diff mbox

[RFC,3/5] hdat: parse and export STOP levels

Message ID 1474008303-20365-4-git-send-email-oohall@gmail.com
State RFC
Headers show

Commit Message

Oliver O'Halloran Sept. 16, 2016, 6:45 a.m. UTC
ISAv3 added the STOP instruction to act as a front end to the various
power saving modes. The exact function of the stop instruction is
implementation dependent and the firmware must advertise which "stop
levels" are supported.

This patch adds the required HDAT parsing and exports the
"ibm,enabled-stop-levels" devicetree node for use inside of skiboot.

Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
---
 hdata/spira.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 58 insertions(+)

Comments

Vasant Hegde Sept. 16, 2016, 9:06 a.m. UTC | #1
On 09/16/2016 12:15 PM, Oliver O'Halloran wrote:
> ISAv3 added the STOP instruction to act as a front end to the various
> power saving modes. The exact function of the stop instruction is
> implementation dependent and the firmware must advertise which "stop
> levels" are supported.
>
> This patch adds the required HDAT parsing and exports the
> "ibm,enabled-stop-levels" devicetree node for use inside of skiboot.

Patch looks good. But probably its better to fold patch 3 & 4. Otherwise we may 
hit issues during git bisect...

Reviewed-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>


-Vasant

>
> Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
> ---
>   hdata/spira.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>   1 file changed, 58 insertions(+)
>
> diff --git a/hdata/spira.c b/hdata/spira.c
> index e4e6b2d5830c..ed918a376adf 100644
> --- a/hdata/spira.c
> +++ b/hdata/spira.c
> @@ -1049,6 +1049,62 @@ static void hostservices_parse(void)
>   	hservices_from_hdat(dt_blob, size);
>   }
>
> +static void add_stop_levels(void)
> +{
> +	struct spira_ntuple *t = &spira.ntuples.proc_chip;
> +	struct HDIF_common_hdr *hdif;
> +	u32 stop_levels = ~0;
> +	bool valid = false;
> +	int i;
> +
> +	if (proc_gen < proc_gen_p9)
> +		return;
> +
> +	/*
> +	 * OPAL only exports a single set of flags to indicate the supported
> +	 * STOP modes while the HDAT descibes the support top levels *per chip*
> +	 * We parse the list of chips to find a common set of STOP levels to
> +	 * export.
> +	 */
> +	for_each_ntuple_idx(t, hdif, i, SPPCRD_HDIF_SIG) {
> +		const struct sppcrd_chip_info *cinfo =
> +			HDIF_get_idata(hdif, SPPCRD_IDATA_CHIP_INFO, NULL);
> +		u32 ve, chip_levels;
> +
> +		if (!cinfo)
> +			continue;
> +
> +		/*
> +		 * If the HDAT is too old contain the support STOP level then
> +		 * assume we have none.
> +		 */
> +		if (be16_to_cpu(hdif->version) < 0x20) {
> +			stop_levels = 0;
> +			break;
> +		}
> +
> +		ve = be32_to_cpu(cinfo->verif_exist_flags) & CPU_ID_VERIFY_MASK;
> +		ve >>= CPU_ID_VERIFY_SHIFT;
> +		if (ve == CHIP_VERIFY_NOT_INSTALLED ||
> +		    ve == CHIP_VERIFY_UNUSABLE)
> +			continue;
> +
> +		chip_levels = be32_to_cpu(cinfo->stop_levels);
> +
> +		prlog(PR_INSANE, "CHIP[%x] supported STOP mask 0x%.8x\n",
> +			be32_to_cpu(cinfo->proc_chip_id), chip_levels);
> +
> +		stop_levels &= chip_levels;
> +		valid = true;
> +	}
> +
> +	if (!valid)
> +		stop_levels = 0;
> +
> +	dt_add_property_cells(dt_new_check(opal_node, "power-mgt"),
> +		"ibm,enabled-stop-levels", stop_levels);
> +}
> +
>   /*
>    * Legacy SPIRA is being deprecated and we have new SPIRA-H/S structures.
>    * But on older system (p7?) we will continue to get legacy SPIRA.
> @@ -1151,6 +1207,8 @@ int parse_hdat(bool is_opal, uint32_t master_cpu)
>   	/* Parse System Attention Indicator inforamtion */
>   	slca_dt_add_sai_node();
>
> +	add_stop_levels();
> +
>   	prlog(PR_INFO, "Parsing HDAT...done\n");
>
>   	return 0;
>
Shilpasri G Bhat Sept. 16, 2016, 2:21 p.m. UTC | #2
Hi,

On 09/16/2016 12:15 PM, Oliver O'Halloran wrote:
> +		chip_levels = be32_to_cpu(cinfo->stop_levels);
> +
> +		prlog(PR_INSANE, "CHIP[%x] supported STOP mask 0x%.8x\n",
		      ^^^^^^^^^
Can this be a PR_INFO instead of PR_INSANE?
Or Can we raise a PR_WARNING when the STOP mask differs across chips?

Thanks and Regards,
Shilpa
Oliver O'Halloran Sept. 17, 2016, 2:41 a.m. UTC | #3
On Fri, Sep 16, 2016 at 7:06 PM, Vasant Hegde
<hegdevasant@linux.vnet.ibm.com> wrote:
> On 09/16/2016 12:15 PM, Oliver O'Halloran wrote:
>>
>> ISAv3 added the STOP instruction to act as a front end to the various
>> power saving modes. The exact function of the stop instruction is
>> implementation dependent and the firmware must advertise which "stop
>> levels" are supported.
>>
>> This patch adds the required HDAT parsing and exports the
>> "ibm,enabled-stop-levels" devicetree node for use inside of skiboot.
>
>
> Patch looks good. But probably its better to fold patch 3 & 4. Otherwise we
> may hit issues during git bisect...

I'd rather they remained seperate. I'll re-order the series so patch 4
comes before 3. That way we should never bisect to a broken state.

>
> Reviewed-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
>
Oliver O'Halloran Sept. 17, 2016, 2:42 a.m. UTC | #4
On Sat, Sep 17, 2016 at 12:21 AM, Shilpasri G Bhat
<shilpa.bhat@linux.vnet.ibm.com> wrote:
> Hi,
>
> On 09/16/2016 12:15 PM, Oliver O'Halloran wrote:
>> +             chip_levels = be32_to_cpu(cinfo->stop_levels);
>> +
>> +             prlog(PR_INSANE, "CHIP[%x] supported STOP mask 0x%.8x\n",
>                       ^^^^^^^^^
> Can this be a PR_INFO instead of PR_INSANE?

I was thinking that the mask was per core rather than per chip when I
wrote that. I'll change it to INFO.

> Or Can we raise a PR_WARNING when the STOP mask differs across chips?

Will do.

>
> Thanks and Regards,
> Shilpa
>
diff mbox

Patch

diff --git a/hdata/spira.c b/hdata/spira.c
index e4e6b2d5830c..ed918a376adf 100644
--- a/hdata/spira.c
+++ b/hdata/spira.c
@@ -1049,6 +1049,62 @@  static void hostservices_parse(void)
 	hservices_from_hdat(dt_blob, size);
 }
 
+static void add_stop_levels(void)
+{
+	struct spira_ntuple *t = &spira.ntuples.proc_chip;
+	struct HDIF_common_hdr *hdif;
+	u32 stop_levels = ~0;
+	bool valid = false;
+	int i;
+
+	if (proc_gen < proc_gen_p9)
+		return;
+
+	/*
+	 * OPAL only exports a single set of flags to indicate the supported
+	 * STOP modes while the HDAT descibes the support top levels *per chip*
+	 * We parse the list of chips to find a common set of STOP levels to
+	 * export.
+	 */
+	for_each_ntuple_idx(t, hdif, i, SPPCRD_HDIF_SIG) {
+		const struct sppcrd_chip_info *cinfo =
+			HDIF_get_idata(hdif, SPPCRD_IDATA_CHIP_INFO, NULL);
+		u32 ve, chip_levels;
+
+		if (!cinfo)
+			continue;
+
+		/*
+		 * If the HDAT is too old contain the support STOP level then
+		 * assume we have none.
+		 */
+		if (be16_to_cpu(hdif->version) < 0x20) {
+			stop_levels = 0;
+			break;
+		}
+
+		ve = be32_to_cpu(cinfo->verif_exist_flags) & CPU_ID_VERIFY_MASK;
+		ve >>= CPU_ID_VERIFY_SHIFT;
+		if (ve == CHIP_VERIFY_NOT_INSTALLED ||
+		    ve == CHIP_VERIFY_UNUSABLE)
+			continue;
+
+		chip_levels = be32_to_cpu(cinfo->stop_levels);
+
+		prlog(PR_INSANE, "CHIP[%x] supported STOP mask 0x%.8x\n",
+			be32_to_cpu(cinfo->proc_chip_id), chip_levels);
+
+		stop_levels &= chip_levels;
+		valid = true;
+	}
+
+	if (!valid)
+		stop_levels = 0;
+
+	dt_add_property_cells(dt_new_check(opal_node, "power-mgt"),
+		"ibm,enabled-stop-levels", stop_levels);
+}
+
 /*
  * Legacy SPIRA is being deprecated and we have new SPIRA-H/S structures.
  * But on older system (p7?) we will continue to get legacy SPIRA.
@@ -1151,6 +1207,8 @@  int parse_hdat(bool is_opal, uint32_t master_cpu)
 	/* Parse System Attention Indicator inforamtion */
 	slca_dt_add_sai_node();
 
+	add_stop_levels();
+
 	prlog(PR_INFO, "Parsing HDAT...done\n");
 
 	return 0;