diff mbox series

drivers/perf: hisi: update the sccl_id/ccl_id for certain HiSilicon platform

Message ID 1573113364-32531-1-git-send-email-zhangshaokun@hisilicon.com (mailing list archive)
State Mainlined
Commit 8703317ae576c9bf3e07e5b97275e3f957e8d74b
Headers show
Series drivers/perf: hisi: update the sccl_id/ccl_id for certain HiSilicon platform | expand

Commit Message

Shaokun Zhang Nov. 7, 2019, 7:56 a.m. UTC
For some HiSilicon platform, the originally designed SCCL_ID and CCL_ID
are not satisfied with much rich topology when the MT is set, so we
extend the SCCL_ID to MPIDR[aff3] and CCL_ID to MPIDR[aff2]. Let's
update this for HiSilicon uncore PMU driver.

Cc: John Garry <john.garry@huawei.com>
Cc: Hanjun Guo <guohanjun@huawei.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Will Deacon <will@kernel.org>
Signed-off-by: Shaokun Zhang <zhangshaokun@hisilicon.com>
---
 drivers/perf/hisilicon/hisi_uncore_pmu.c | 26 ++++++++++++++++++--------
 1 file changed, 18 insertions(+), 8 deletions(-)

Comments

Mark Rutland Nov. 7, 2019, 11:31 a.m. UTC | #1
On Thu, Nov 07, 2019 at 03:56:04PM +0800, Shaokun Zhang wrote:
> For some HiSilicon platform, the originally designed SCCL_ID and CCL_ID
> are not satisfied with much rich topology when the MT is set, so we
> extend the SCCL_ID to MPIDR[aff3] and CCL_ID to MPIDR[aff2]. Let's
> update this for HiSilicon uncore PMU driver.
> 
> Cc: John Garry <john.garry@huawei.com>
> Cc: Hanjun Guo <guohanjun@huawei.com>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Cc: Will Deacon <will@kernel.org>
> Signed-off-by: Shaokun Zhang <zhangshaokun@hisilicon.com>
> ---
>  drivers/perf/hisilicon/hisi_uncore_pmu.c | 26 ++++++++++++++++++--------
>  1 file changed, 18 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.c b/drivers/perf/hisilicon/hisi_uncore_pmu.c
> index 79f76f8dda8e..96183e31b96a 100644
> --- a/drivers/perf/hisilicon/hisi_uncore_pmu.c
> +++ b/drivers/perf/hisilicon/hisi_uncore_pmu.c
> @@ -15,6 +15,7 @@
>  #include <linux/errno.h>
>  #include <linux/interrupt.h>
>  
> +#include <asm/cputype.h>
>  #include <asm/local64.h>
>  
>  #include "hisi_uncore_pmu.h"
> @@ -338,8 +339,10 @@ void hisi_uncore_pmu_disable(struct pmu *pmu)
>  
>  /*
>   * Read Super CPU cluster and CPU cluster ID from MPIDR_EL1.
> - * If multi-threading is supported, CCL_ID is the low 3-bits in MPIDR[Aff2]
> - * and SCCL_ID is the upper 5-bits of Aff2 field; if not, SCCL_ID
> + * If multi-threading is supported, On Huawei Kunpeng 920 SoC whose cpu
> + * core is tsv110, CCL_ID is the low 3-bits in MPIDR[Aff2] and SCCL_ID
> + * is the upper 5-bits of Aff2 field; while for other cpu types, SCCL_ID
> + * is in MPIDR[Aff3] and CCL_ID is in MPIDR[Aff2], if not, SCCL_ID
>   * is in MPIDR[Aff2] and CCL_ID is in MPIDR[Aff1].
>   */

Is TSV110 in any other SoCs, where the mapping of MPIDR to SCCL/CCL IDs
differs?

The comment would be much easier to read as something like:

/*
 * The Super CPU Cluster (SCCL) and CPU Cluster (CCL) IDs can be
 * determined from the MPIDR_EL1, but the encoding varies by CPU:
 *
 * - For TSV110 (e.g. found in Kunpeng 920):
 *   SCCL is Aff2[7:3], CCL is Aff2[2:0]
 *
 * - For other MT parts:
 *   SCCL is Aff3[7:0], CCL is Aff2[7:0]
 *
 * - For other (non-MT) parts:
 *   SCCL is Aff2[7:0], CCL is Aff1[7:0]
 */

If TSV110 is always MT, then it would be better to structure the code
similarly to that comment:

static void hisi_read_sccl_and_ccl_id(int *scclp, int *cclp)
{
	u64 mpidr = read_cpuid_mpidr();
	int aff3 = MPIDR_AFFINITY_LEVEL(mpidr, 3);
	int aff2 = MPIDR_AFFINITY_LEVEL(mpidr, 2);
	int aff1 = MPIDR_AFFINITY_LEVEL(mpidr, 1);
	int sccl, ccl;

	if (read_cpuid_part_number() == HISI_CPU_PART_TSV110) {
		sccl = aff2 >> 3;
		ccl = aff2 & 0x7;
	} else if (mpidr & MPIDR_MT_BITMASK) {
		sccl = aff3;
		ccl = aff2;
	} else {
		sccl = aff2;
		ccl = aff1;
	}

	if (scclp)
		*scclp = sccl;
	if (cclp)
		*cclp = ccl;
}

Thanks,
Mark.

>  static void hisi_read_sccl_and_ccl_id(int *sccl_id, int *ccl_id)
> @@ -347,12 +350,19 @@ static void hisi_read_sccl_and_ccl_id(int *sccl_id, int *ccl_id)
>  	u64 mpidr = read_cpuid_mpidr();
>  
>  	if (mpidr & MPIDR_MT_BITMASK) {
> -		int aff2 = MPIDR_AFFINITY_LEVEL(mpidr, 2);
> -
> -		if (sccl_id)
> -			*sccl_id = aff2 >> 3;
> -		if (ccl_id)
> -			*ccl_id = aff2 & 0x7;
> +		if (read_cpuid_part_number() == HISI_CPU_PART_TSV110) {
> +			int aff2 = MPIDR_AFFINITY_LEVEL(mpidr, 2);
> +
> +			if (sccl_id)
> +				*sccl_id = aff2 >> 3;
> +			if (ccl_id)
> +				*ccl_id = aff2 & 0x7;
> +		} else {
> +			if (sccl_id)
> +				*sccl_id = MPIDR_AFFINITY_LEVEL(mpidr, 3);
> +			if (ccl_id)
> +				*ccl_id = MPIDR_AFFINITY_LEVEL(mpidr, 2);
> +		}
>  	} else {
>  		if (sccl_id)
>  			*sccl_id = MPIDR_AFFINITY_LEVEL(mpidr, 2);
> -- 
> 2.7.4
>
Will Deacon Nov. 7, 2019, 11:40 a.m. UTC | #2
Hi,

On Thu, Nov 07, 2019 at 03:56:04PM +0800, Shaokun Zhang wrote:
> @@ -338,8 +339,10 @@ void hisi_uncore_pmu_disable(struct pmu *pmu)
>  
>  /*
>   * Read Super CPU cluster and CPU cluster ID from MPIDR_EL1.
> - * If multi-threading is supported, CCL_ID is the low 3-bits in MPIDR[Aff2]
> - * and SCCL_ID is the upper 5-bits of Aff2 field; if not, SCCL_ID
> + * If multi-threading is supported, On Huawei Kunpeng 920 SoC whose cpu
> + * core is tsv110, CCL_ID is the low 3-bits in MPIDR[Aff2] and SCCL_ID
> + * is the upper 5-bits of Aff2 field; while for other cpu types, SCCL_ID
> + * is in MPIDR[Aff3] and CCL_ID is in MPIDR[Aff2], if not, SCCL_ID
>   * is in MPIDR[Aff2] and CCL_ID is in MPIDR[Aff1].
>   */
>  static void hisi_read_sccl_and_ccl_id(int *sccl_id, int *ccl_id)
> @@ -347,12 +350,19 @@ static void hisi_read_sccl_and_ccl_id(int *sccl_id, int *ccl_id)
>  	u64 mpidr = read_cpuid_mpidr();
>  
>  	if (mpidr & MPIDR_MT_BITMASK) {
> -		int aff2 = MPIDR_AFFINITY_LEVEL(mpidr, 2);
> -
> -		if (sccl_id)
> -			*sccl_id = aff2 >> 3;
> -		if (ccl_id)
> -			*ccl_id = aff2 & 0x7;
> +		if (read_cpuid_part_number() == HISI_CPU_PART_TSV110) {
> +			int aff2 = MPIDR_AFFINITY_LEVEL(mpidr, 2);
> +
> +			if (sccl_id)
> +				*sccl_id = aff2 >> 3;
> +			if (ccl_id)
> +				*ccl_id = aff2 & 0x7;
> +		} else {
> +			if (sccl_id)
> +				*sccl_id = MPIDR_AFFINITY_LEVEL(mpidr, 3);
> +			if (ccl_id)
> +				*ccl_id = MPIDR_AFFINITY_LEVEL(mpidr, 2);
> +		}

[I prefer Mark's version, so please reply to indicate whether or not it
 works for you]

So I'll take this, but the lesson here seems to be that it's a terrible idea
to infer system topology from CPU ID registers. In future, I'm going to
insist that this comes from firmware tables because hacks like the above are
not sustainable.

Will
John Garry Nov. 7, 2019, 11:50 a.m. UTC | #3
On 07/11/2019 11:40, Will Deacon wrote:
> Hi,
> 
> On Thu, Nov 07, 2019 at 03:56:04PM +0800, Shaokun Zhang wrote:
>> @@ -338,8 +339,10 @@ void hisi_uncore_pmu_disable(struct pmu *pmu)
>>   
>>   /*
>>    * Read Super CPU cluster and CPU cluster ID from MPIDR_EL1.
>> - * If multi-threading is supported, CCL_ID is the low 3-bits in MPIDR[Aff2]
>> - * and SCCL_ID is the upper 5-bits of Aff2 field; if not, SCCL_ID
>> + * If multi-threading is supported, On Huawei Kunpeng 920 SoC whose cpu
>> + * core is tsv110, CCL_ID is the low 3-bits in MPIDR[Aff2] and SCCL_ID
>> + * is the upper 5-bits of Aff2 field; while for other cpu types, SCCL_ID
>> + * is in MPIDR[Aff3] and CCL_ID is in MPIDR[Aff2], if not, SCCL_ID
>>    * is in MPIDR[Aff2] and CCL_ID is in MPIDR[Aff1].
>>    */
>>   static void hisi_read_sccl_and_ccl_id(int *sccl_id, int *ccl_id)
>> @@ -347,12 +350,19 @@ static void hisi_read_sccl_and_ccl_id(int *sccl_id, int *ccl_id)
>>   	u64 mpidr = read_cpuid_mpidr();
>>   
>>   	if (mpidr & MPIDR_MT_BITMASK) {
>> -		int aff2 = MPIDR_AFFINITY_LEVEL(mpidr, 2);
>> -
>> -		if (sccl_id)
>> -			*sccl_id = aff2 >> 3;
>> -		if (ccl_id)
>> -			*ccl_id = aff2 & 0x7;
>> +		if (read_cpuid_part_number() == HISI_CPU_PART_TSV110) {
>> +			int aff2 = MPIDR_AFFINITY_LEVEL(mpidr, 2);
>> +
>> +			if (sccl_id)
>> +				*sccl_id = aff2 >> 3;
>> +			if (ccl_id)
>> +				*ccl_id = aff2 & 0x7;
>> +		} else {
>> +			if (sccl_id)
>> +				*sccl_id = MPIDR_AFFINITY_LEVEL(mpidr, 3);
>> +			if (ccl_id)
>> +				*ccl_id = MPIDR_AFFINITY_LEVEL(mpidr, 2);
>> +		}
> 
> [I prefer Mark's version, so please reply to indicate whether or not it
>   works for you]

Replying on Shaokun's behalf as he appears offline now.

In response to "> If TSV110 is always MT, ":

It isn't. There are 2 spins of Huawei Kunpeng 920 SoC which includes 
TaishanV110 aka TSV110: one has the MT bit set and the other without.

We did ask for this not to be changed...

> 
> So I'll take this, but the lesson here seems to be that it's a terrible idea
> to infer system topology from CPU ID registers. In future, I'm going to
> insist that this comes from firmware tables because hacks like the above are
> not sustainable.
> 

Hopefully it will not change again, but maybe we can use PPTT instead.

Thanks,
John

> Will
> .
>
Mark Rutland Nov. 7, 2019, 11:56 a.m. UTC | #4
On Thu, Nov 07, 2019 at 11:50:30AM +0000, John Garry wrote:
> On 07/11/2019 11:40, Will Deacon wrote:
> > Hi,
> > 
> > On Thu, Nov 07, 2019 at 03:56:04PM +0800, Shaokun Zhang wrote:
> > > @@ -338,8 +339,10 @@ void hisi_uncore_pmu_disable(struct pmu *pmu)
> > >   /*
> > >    * Read Super CPU cluster and CPU cluster ID from MPIDR_EL1.
> > > - * If multi-threading is supported, CCL_ID is the low 3-bits in MPIDR[Aff2]
> > > - * and SCCL_ID is the upper 5-bits of Aff2 field; if not, SCCL_ID
> > > + * If multi-threading is supported, On Huawei Kunpeng 920 SoC whose cpu
> > > + * core is tsv110, CCL_ID is the low 3-bits in MPIDR[Aff2] and SCCL_ID
> > > + * is the upper 5-bits of Aff2 field; while for other cpu types, SCCL_ID
> > > + * is in MPIDR[Aff3] and CCL_ID is in MPIDR[Aff2], if not, SCCL_ID
> > >    * is in MPIDR[Aff2] and CCL_ID is in MPIDR[Aff1].
> > >    */
> > >   static void hisi_read_sccl_and_ccl_id(int *sccl_id, int *ccl_id)
> > > @@ -347,12 +350,19 @@ static void hisi_read_sccl_and_ccl_id(int *sccl_id, int *ccl_id)
> > >   	u64 mpidr = read_cpuid_mpidr();
> > >   	if (mpidr & MPIDR_MT_BITMASK) {
> > > -		int aff2 = MPIDR_AFFINITY_LEVEL(mpidr, 2);
> > > -
> > > -		if (sccl_id)
> > > -			*sccl_id = aff2 >> 3;
> > > -		if (ccl_id)
> > > -			*ccl_id = aff2 & 0x7;
> > > +		if (read_cpuid_part_number() == HISI_CPU_PART_TSV110) {
> > > +			int aff2 = MPIDR_AFFINITY_LEVEL(mpidr, 2);
> > > +
> > > +			if (sccl_id)
> > > +				*sccl_id = aff2 >> 3;
> > > +			if (ccl_id)
> > > +				*ccl_id = aff2 & 0x7;
> > > +		} else {
> > > +			if (sccl_id)
> > > +				*sccl_id = MPIDR_AFFINITY_LEVEL(mpidr, 3);
> > > +			if (ccl_id)
> > > +				*ccl_id = MPIDR_AFFINITY_LEVEL(mpidr, 2);
> > > +		}
> > 
> > [I prefer Mark's version, so please reply to indicate whether or not it
> >   works for you]
> 
> Replying on Shaokun's behalf as he appears offline now.
> 
> In response to "> If TSV110 is always MT, ":
> 
> It isn't. There are 2 spins of Huawei Kunpeng 920 SoC which includes
> TaishanV110 aka TSV110: one has the MT bit set and the other without.

Just to check, for the non-MT variant is the SCCL/CCL assignment
Aff2/Aff1 as with other non-MT parts?

Thanks,
Mark.
John Garry Nov. 7, 2019, 12:06 p.m. UTC | #5
On 07/11/2019 11:56, Mark Rutland wrote:
> On Thu, Nov 07, 2019 at 11:50:30AM +0000, John Garry wrote:
>> On 07/11/2019 11:40, Will Deacon wrote:
>>> Hi,
>>>
>>> On Thu, Nov 07, 2019 at 03:56:04PM +0800, Shaokun Zhang wrote:
>>>> @@ -338,8 +339,10 @@ void hisi_uncore_pmu_disable(struct pmu *pmu)
>>>>    /*
>>>>     * Read Super CPU cluster and CPU cluster ID from MPIDR_EL1.
>>>> - * If multi-threading is supported, CCL_ID is the low 3-bits in MPIDR[Aff2]
>>>> - * and SCCL_ID is the upper 5-bits of Aff2 field; if not, SCCL_ID
>>>> + * If multi-threading is supported, On Huawei Kunpeng 920 SoC whose cpu
>>>> + * core is tsv110, CCL_ID is the low 3-bits in MPIDR[Aff2] and SCCL_ID
>>>> + * is the upper 5-bits of Aff2 field; while for other cpu types, SCCL_ID
>>>> + * is in MPIDR[Aff3] and CCL_ID is in MPIDR[Aff2], if not, SCCL_ID
>>>>     * is in MPIDR[Aff2] and CCL_ID is in MPIDR[Aff1].
>>>>     */
>>>>    static void hisi_read_sccl_and_ccl_id(int *sccl_id, int *ccl_id)
>>>> @@ -347,12 +350,19 @@ static void hisi_read_sccl_and_ccl_id(int *sccl_id, int *ccl_id)
>>>>    	u64 mpidr = read_cpuid_mpidr();
>>>>    	if (mpidr & MPIDR_MT_BITMASK) {
>>>> -		int aff2 = MPIDR_AFFINITY_LEVEL(mpidr, 2);
>>>> -
>>>> -		if (sccl_id)
>>>> -			*sccl_id = aff2 >> 3;
>>>> -		if (ccl_id)
>>>> -			*ccl_id = aff2 & 0x7;
>>>> +		if (read_cpuid_part_number() == HISI_CPU_PART_TSV110) {
>>>> +			int aff2 = MPIDR_AFFINITY_LEVEL(mpidr, 2);
>>>> +
>>>> +			if (sccl_id)
>>>> +				*sccl_id = aff2 >> 3;
>>>> +			if (ccl_id)
>>>> +				*ccl_id = aff2 & 0x7;
>>>> +		} else {
>>>> +			if (sccl_id)
>>>> +				*sccl_id = MPIDR_AFFINITY_LEVEL(mpidr, 3);
>>>> +			if (ccl_id)
>>>> +				*ccl_id = MPIDR_AFFINITY_LEVEL(mpidr, 2);
>>>> +		}
>>>
>>> [I prefer Mark's version, so please reply to indicate whether or not it
>>>    works for you]
>>
>> Replying on Shaokun's behalf as he appears offline now.
>>
>> In response to "> If TSV110 is always MT, ":
>>
>> It isn't. There are 2 spins of Huawei Kunpeng 920 SoC which includes
>> TaishanV110 aka TSV110: one has the MT bit set and the other without.
> 
> Just to check, for the non-MT variant is the SCCL/CCL assignment
> Aff2/Aff1 as with other non-MT parts?

We don't support any other non-MT parts for this driver.

Thanks,
John
Mark Rutland Nov. 7, 2019, 12:11 p.m. UTC | #6
On Thu, Nov 07, 2019 at 12:06:24PM +0000, John Garry wrote:
> On 07/11/2019 11:56, Mark Rutland wrote:
> > On Thu, Nov 07, 2019 at 11:50:30AM +0000, John Garry wrote:
> > > On 07/11/2019 11:40, Will Deacon wrote:
> > > > Hi,
> > > > 
> > > > On Thu, Nov 07, 2019 at 03:56:04PM +0800, Shaokun Zhang wrote:
> > > > > @@ -338,8 +339,10 @@ void hisi_uncore_pmu_disable(struct pmu *pmu)
> > > > >    /*
> > > > >     * Read Super CPU cluster and CPU cluster ID from MPIDR_EL1.
> > > > > - * If multi-threading is supported, CCL_ID is the low 3-bits in MPIDR[Aff2]
> > > > > - * and SCCL_ID is the upper 5-bits of Aff2 field; if not, SCCL_ID
> > > > > + * If multi-threading is supported, On Huawei Kunpeng 920 SoC whose cpu
> > > > > + * core is tsv110, CCL_ID is the low 3-bits in MPIDR[Aff2] and SCCL_ID
> > > > > + * is the upper 5-bits of Aff2 field; while for other cpu types, SCCL_ID
> > > > > + * is in MPIDR[Aff3] and CCL_ID is in MPIDR[Aff2], if not, SCCL_ID
> > > > >     * is in MPIDR[Aff2] and CCL_ID is in MPIDR[Aff1].
> > > > >     */
> > > > >    static void hisi_read_sccl_and_ccl_id(int *sccl_id, int *ccl_id)
> > > > > @@ -347,12 +350,19 @@ static void hisi_read_sccl_and_ccl_id(int *sccl_id, int *ccl_id)
> > > > >    	u64 mpidr = read_cpuid_mpidr();
> > > > >    	if (mpidr & MPIDR_MT_BITMASK) {
> > > > > -		int aff2 = MPIDR_AFFINITY_LEVEL(mpidr, 2);
> > > > > -
> > > > > -		if (sccl_id)
> > > > > -			*sccl_id = aff2 >> 3;
> > > > > -		if (ccl_id)
> > > > > -			*ccl_id = aff2 & 0x7;
> > > > > +		if (read_cpuid_part_number() == HISI_CPU_PART_TSV110) {
> > > > > +			int aff2 = MPIDR_AFFINITY_LEVEL(mpidr, 2);
> > > > > +
> > > > > +			if (sccl_id)
> > > > > +				*sccl_id = aff2 >> 3;
> > > > > +			if (ccl_id)
> > > > > +				*ccl_id = aff2 & 0x7;
> > > > > +		} else {
> > > > > +			if (sccl_id)
> > > > > +				*sccl_id = MPIDR_AFFINITY_LEVEL(mpidr, 3);
> > > > > +			if (ccl_id)
> > > > > +				*ccl_id = MPIDR_AFFINITY_LEVEL(mpidr, 2);
> > > > > +		}
> > > > 
> > > > [I prefer Mark's version, so please reply to indicate whether or not it
> > > >    works for you]
> > > 
> > > Replying on Shaokun's behalf as he appears offline now.
> > > 
> > > In response to "> If TSV110 is always MT, ":
> > > 
> > > It isn't. There are 2 spins of Huawei Kunpeng 920 SoC which includes
> > > TaishanV110 aka TSV110: one has the MT bit set and the other without.
> > 
> > Just to check, for the non-MT variant is the SCCL/CCL assignment
> > Aff2/Aff1 as with other non-MT parts?
> 
> We don't support any other non-MT parts for this driver.

The driver claimed to support non-MT parts before TSV110 came around, so that
statement confuses me.

For a non-MT TSV110, is Aff2 the SCCL and Aff1 the CCL? That's what the
existing code (and Shaokun's patch) assumed.

Assuming that is the case, I'd suggest we have the following:

/*
 * The Super CPU Cluster (SCCL) and CPU Cluster (CCL) IDs can be
 * determined from the MPIDR_EL1, but the encoding varies by CPU:
 *
 * - For MT variants of TSV110 (e.g. found in Kunpeng 920):
 *   SCCL is Aff2[7:3], CCL is Aff2[2:0]
 *
 * - For other MT parts:
 *   SCCL is Aff3[7:0], CCL is Aff2[7:0]
 *
 * - For non-MT parts:
 *   SCCL is Aff2[7:0], CCL is Aff1[7:0]
 */
static void hisi_read_sccl_and_ccl_id(int *scclp, int *cclp)
{
	u64 mpidr = read_cpuid_mpidr();
	int aff3 = MPIDR_AFFINITY_LEVEL(mpidr, 3);
	int aff2 = MPIDR_AFFINITY_LEVEL(mpidr, 2);
	int aff1 = MPIDR_AFFINITY_LEVEL(mpidr, 1);
	bool mt = mpdir & MPIDR_MT_BITMASK;
	int sccl, ccl;

	if (mt && read_cpuid_part_number() == HISI_CPU_PART_TSV110) {
		sccl = aff2 >> 3;
		ccl = aff2 & 0x7;
	} else if (mt) {
		sccl = aff3;
		ccl = aff2;
	} else {
		sccl = aff2;
		ccl = aff1;
	}

	if (scclp)
		*scclp = sccl;
	if (cclp)
		*cclp = ccl;
}

Thanks,
Mark.
John Garry Nov. 7, 2019, 1:04 p.m. UTC | #7
>>>>> On Thu, Nov 07, 2019 at 03:56:04PM +0800, Shaokun Zhang wrote:
>>>>>> @@ -338,8 +339,10 @@ void hisi_uncore_pmu_disable(struct pmu *pmu)
>>>>>>     /*
>>>>>>      * Read Super CPU cluster and CPU cluster ID from MPIDR_EL1.
>>>>>> - * If multi-threading is supported, CCL_ID is the low 3-bits in MPIDR[Aff2]
>>>>>> - * and SCCL_ID is the upper 5-bits of Aff2 field; if not, SCCL_ID
>>>>>> + * If multi-threading is supported, On Huawei Kunpeng 920 SoC whose cpu
>>>>>> + * core is tsv110, CCL_ID is the low 3-bits in MPIDR[Aff2] and SCCL_ID
>>>>>> + * is the upper 5-bits of Aff2 field; while for other cpu types, SCCL_ID
>>>>>> + * is in MPIDR[Aff3] and CCL_ID is in MPIDR[Aff2], if not, SCCL_ID
>>>>>>      * is in MPIDR[Aff2] and CCL_ID is in MPIDR[Aff1].
>>>>>>      */
>>>>>>     static void hisi_read_sccl_and_ccl_id(int *sccl_id, int *ccl_id)
>>>>>> @@ -347,12 +350,19 @@ static void hisi_read_sccl_and_ccl_id(int *sccl_id, int *ccl_id)
>>>>>>     	u64 mpidr = read_cpuid_mpidr();
>>>>>>     	if (mpidr & MPIDR_MT_BITMASK) {
>>>>>> -		int aff2 = MPIDR_AFFINITY_LEVEL(mpidr, 2);
>>>>>> -
>>>>>> -		if (sccl_id)
>>>>>> -			*sccl_id = aff2 >> 3;
>>>>>> -		if (ccl_id)
>>>>>> -			*ccl_id = aff2 & 0x7;
>>>>>> +		if (read_cpuid_part_number() == HISI_CPU_PART_TSV110) {
>>>>>> +			int aff2 = MPIDR_AFFINITY_LEVEL(mpidr, 2);
>>>>>> +
>>>>>> +			if (sccl_id)
>>>>>> +				*sccl_id = aff2 >> 3;
>>>>>> +			if (ccl_id)
>>>>>> +				*ccl_id = aff2 & 0x7;
>>>>>> +		} else {
>>>>>> +			if (sccl_id)
>>>>>> +				*sccl_id = MPIDR_AFFINITY_LEVEL(mpidr, 3);
>>>>>> +			if (ccl_id)
>>>>>> +				*ccl_id = MPIDR_AFFINITY_LEVEL(mpidr, 2);
>>>>>> +		}
>>>>>
>>>>> [I prefer Mark's version, so please reply to indicate whether or not it
>>>>>     works for you]
>>>>
>>>> Replying on Shaokun's behalf as he appears offline now.
>>>>
>>>> In response to "> If TSV110 is always MT, ":
>>>>
>>>> It isn't. There are 2 spins of Huawei Kunpeng 920 SoC which includes
>>>> TaishanV110 aka TSV110: one has the MT bit set and the other without.
>>>
>>> Just to check, for the non-MT variant is the SCCL/CCL assignment
>>> Aff2/Aff1 as with other non-MT parts?
>>
>> We don't support any other non-MT parts for this driver.
> 
> The driver claimed to support non-MT parts before TSV110 came around, so that
> statement confuses me.

A couple of points on this:

- We gave up on upstreaming support in this driver for the predecessor 
SoC, which included an A72. You may remember the infamous djtag bus.

- The wording in the comment "If multi-threading is supported, On Huawei 
Kunpeng 920 SoC " is misleading, as it implies that the part found in 
Huawei Kunpeng 920 is MT, which it isn't always.

> 
> For a non-MT TSV110, is Aff2 the SCCL and Aff1 the CCL? 

Yes,

That's what the
> existing code (and Shaokun's patch) assumed.

well I'm going with that as well. Shaokun can confirm the layout.

> 
> Assuming that is the case, I'd suggest we have the following:
> 
> /*
>   * The Super CPU Cluster (SCCL) and CPU Cluster (CCL) IDs can be
>   * determined from the MPIDR_EL1, but the encoding varies by CPU:
>   *
>   * - For MT variants of TSV110 (e.g. found in Kunpeng 920):

Again, this implies that the part found in Kunpeng 920 is MT, which it 
isn't always.

BTW, As I understand, the MIDR variant bits differ between the 2 revs of 
TSV110, so maybe that is a better method to differentiate, but I don't 
see an API exported for this.

>   *   SCCL is Aff2[7:3], CCL is Aff2[2:0]
>   *
>   * - For other MT parts:
>   *   SCCL is Aff3[7:0], CCL is Aff2[7:0]
>   *
>   * - For non-MT parts:
>   *   SCCL is Aff2[7:0], CCL is Aff1[7:0]
>   */
> static void hisi_read_sccl_and_ccl_id(int *scclp, int *cclp)
> {
> 	u64 mpidr = read_cpuid_mpidr();
> 	int aff3 = MPIDR_AFFINITY_LEVEL(mpidr, 3);
> 	int aff2 = MPIDR_AFFINITY_LEVEL(mpidr, 2);
> 	int aff1 = MPIDR_AFFINITY_LEVEL(mpidr, 1);
> 	bool mt = mpdir & MPIDR_MT_BITMASK;
> 	int sccl, ccl;
> 
> 	if (mt && read_cpuid_part_number() == HISI_CPU_PART_TSV110) {
> 		sccl = aff2 >> 3;
> 		ccl = aff2 & 0x7;
> 	} else if (mt) {
> 		sccl = aff3;
> 		ccl = aff2;
> 	} else {
> 		sccl = aff2;
> 		ccl = aff1;
> 	}
> 
> 	if (scclp)
> 		*scclp = sccl;
> 	if (cclp)
> 		*cclp = ccl;
> }
> 
> Thanks,
> Mark.

Thanks,
John

> .
>
Will Deacon Nov. 7, 2019, 1:09 p.m. UTC | #8
On Thu, Nov 07, 2019 at 01:04:34PM +0000, John Garry wrote:
> > > > > > On Thu, Nov 07, 2019 at 03:56:04PM +0800, Shaokun Zhang wrote:
> > > > > > [I prefer Mark's version, so please reply to indicate whether or not it
> > > > > >     works for you]
> > > > > 
> > > > > Replying on Shaokun's behalf as he appears offline now.
> > > > > 
> > > > > In response to "> If TSV110 is always MT, ":
> > > > > 
> > > > > It isn't. There are 2 spins of Huawei Kunpeng 920 SoC which includes
> > > > > TaishanV110 aka TSV110: one has the MT bit set and the other without.
> > > > 
> > > > Just to check, for the non-MT variant is the SCCL/CCL assignment
> > > > Aff2/Aff1 as with other non-MT parts?
> > > 
> > > We don't support any other non-MT parts for this driver.
> > 
> > The driver claimed to support non-MT parts before TSV110 came around, so that
> > statement confuses me.
> 
> A couple of points on this:
> 
> - We gave up on upstreaming support in this driver for the predecessor SoC,
> which included an A72. You may remember the infamous djtag bus.
> 
> - The wording in the comment "If multi-threading is supported, On Huawei
> Kunpeng 920 SoC " is misleading, as it implies that the part found in Huawei
> Kunpeng 920 is MT, which it isn't always.
> 
> > 
> > For a non-MT TSV110, is Aff2 the SCCL and Aff1 the CCL?
> 
> Yes,
> 
> That's what the
> > existing code (and Shaokun's patch) assumed.
> 
> well I'm going with that as well. Shaokun can confirm the layout.

I'll queue Shaokun's patch for now, since I want to get this to Catalin
tomorrow for 5.5 after spending the night in -next. We can always simplify
the logic later if Mark's patch ends up working out.

Thanks,

Will
Shaokun Zhang Nov. 8, 2019, 1:15 a.m. UTC | #9
Hi Mark,

On 2019/11/7 20:11, Mark Rutland wrote:
> On Thu, Nov 07, 2019 at 12:06:24PM +0000, John Garry wrote:
>> On 07/11/2019 11:56, Mark Rutland wrote:
>>> On Thu, Nov 07, 2019 at 11:50:30AM +0000, John Garry wrote:
>>>> On 07/11/2019 11:40, Will Deacon wrote:
>>>>> Hi,
>>>>>
>>>>> On Thu, Nov 07, 2019 at 03:56:04PM +0800, Shaokun Zhang wrote:
>>>>>> @@ -338,8 +339,10 @@ void hisi_uncore_pmu_disable(struct pmu *pmu)
>>>>>>    /*
>>>>>>     * Read Super CPU cluster and CPU cluster ID from MPIDR_EL1.
>>>>>> - * If multi-threading is supported, CCL_ID is the low 3-bits in MPIDR[Aff2]
>>>>>> - * and SCCL_ID is the upper 5-bits of Aff2 field; if not, SCCL_ID
>>>>>> + * If multi-threading is supported, On Huawei Kunpeng 920 SoC whose cpu
>>>>>> + * core is tsv110, CCL_ID is the low 3-bits in MPIDR[Aff2] and SCCL_ID
>>>>>> + * is the upper 5-bits of Aff2 field; while for other cpu types, SCCL_ID
>>>>>> + * is in MPIDR[Aff3] and CCL_ID is in MPIDR[Aff2], if not, SCCL_ID
>>>>>>     * is in MPIDR[Aff2] and CCL_ID is in MPIDR[Aff1].
>>>>>>     */
>>>>>>    static void hisi_read_sccl_and_ccl_id(int *sccl_id, int *ccl_id)
>>>>>> @@ -347,12 +350,19 @@ static void hisi_read_sccl_and_ccl_id(int *sccl_id, int *ccl_id)
>>>>>>    	u64 mpidr = read_cpuid_mpidr();
>>>>>>    	if (mpidr & MPIDR_MT_BITMASK) {
>>>>>> -		int aff2 = MPIDR_AFFINITY_LEVEL(mpidr, 2);
>>>>>> -
>>>>>> -		if (sccl_id)
>>>>>> -			*sccl_id = aff2 >> 3;
>>>>>> -		if (ccl_id)
>>>>>> -			*ccl_id = aff2 & 0x7;
>>>>>> +		if (read_cpuid_part_number() == HISI_CPU_PART_TSV110) {
>>>>>> +			int aff2 = MPIDR_AFFINITY_LEVEL(mpidr, 2);
>>>>>> +
>>>>>> +			if (sccl_id)
>>>>>> +				*sccl_id = aff2 >> 3;
>>>>>> +			if (ccl_id)
>>>>>> +				*ccl_id = aff2 & 0x7;
>>>>>> +		} else {
>>>>>> +			if (sccl_id)
>>>>>> +				*sccl_id = MPIDR_AFFINITY_LEVEL(mpidr, 3);
>>>>>> +			if (ccl_id)
>>>>>> +				*ccl_id = MPIDR_AFFINITY_LEVEL(mpidr, 2);
>>>>>> +		}
>>>>>
>>>>> [I prefer Mark's version, so please reply to indicate whether or not it
>>>>>    works for you]
>>>>
>>>> Replying on Shaokun's behalf as he appears offline now.
>>>>
>>>> In response to "> If TSV110 is always MT, ":
>>>>
>>>> It isn't. There are 2 spins of Huawei Kunpeng 920 SoC which includes
>>>> TaishanV110 aka TSV110: one has the MT bit set and the other without.
>>>
>>> Just to check, for the non-MT variant is the SCCL/CCL assignment
>>> Aff2/Aff1 as with other non-MT parts?
>>
>> We don't support any other non-MT parts for this driver.
> 
> The driver claimed to support non-MT parts before TSV110 came around, so that
> statement confuses me.
> 

Apologies that I reply a little later because of stepout and other things, I was
not online.

My description is a little obscure so the comment is really confused:
Under the condition that MT field is set, TSV110 core on Kunpeng 920:
SCCL is Aff2[7:3], CCL is Aff2[2:0];

If MT field is not, TSV110 core on Kunpeng 920:
SCCL is Aff2[7:0], CCL is Aff1[7:0]
And as John said that "We don't support any other non-MT parts for this driver."

> For a non-MT TSV110, is Aff2 the SCCL and Aff1 the CCL? That's what the

Right.

> existing code (and Shaokun's patch) assumed.
> 
> Assuming that is the case, I'd suggest we have the following:
> 
> /*
>  * The Super CPU Cluster (SCCL) and CPU Cluster (CCL) IDs can be
>  * determined from the MPIDR_EL1, but the encoding varies by CPU:
>  *
>  * - For MT variants of TSV110 (e.g. found in Kunpeng 920):
>  *   SCCL is Aff2[7:3], CCL is Aff2[2:0]
>  *
>  * - For other MT parts:
>  *   SCCL is Aff3[7:0], CCL is Aff2[7:0]
>  *
>  * - For non-MT parts:
>  *   SCCL is Aff2[7:0], CCL is Aff1[7:0]
>  */
> static void hisi_read_sccl_and_ccl_id(int *scclp, int *cclp)
> {
> 	u64 mpidr = read_cpuid_mpidr();
> 	int aff3 = MPIDR_AFFINITY_LEVEL(mpidr, 3);
> 	int aff2 = MPIDR_AFFINITY_LEVEL(mpidr, 2);
> 	int aff1 = MPIDR_AFFINITY_LEVEL(mpidr, 1);
> 	bool mt = mpdir & MPIDR_MT_BITMASK;
> 	int sccl, ccl;
> 
> 	if (mt && read_cpuid_part_number() == HISI_CPU_PART_TSV110) {
> 		sccl = aff2 >> 3;
> 		ccl = aff2 & 0x7;
> 	} else if (mt) {
> 		sccl = aff3;
> 		ccl = aff2;
> 	} else {
> 		sccl = aff2;
> 		ccl = aff1;
> 	}
> 
> 	if (scclp)
> 		*scclp = sccl;
> 	if (cclp)
> 		*cclp = ccl;
> }
> 

It works and Thanks your nice comment.

> Thanks,
> Mark.
> 
> .
>
Shaokun Zhang Nov. 8, 2019, 1:18 a.m. UTC | #10
Hi John,

On 2019/11/7 21:04, John Garry wrote:
> 
>>>>>> On Thu, Nov 07, 2019 at 03:56:04PM +0800, Shaokun Zhang wrote:
>>>>>>> @@ -338,8 +339,10 @@ void hisi_uncore_pmu_disable(struct pmu *pmu)
>>>>>>>     /*
>>>>>>>      * Read Super CPU cluster and CPU cluster ID from MPIDR_EL1.
>>>>>>> - * If multi-threading is supported, CCL_ID is the low 3-bits in MPIDR[Aff2]
>>>>>>> - * and SCCL_ID is the upper 5-bits of Aff2 field; if not, SCCL_ID
>>>>>>> + * If multi-threading is supported, On Huawei Kunpeng 920 SoC whose cpu
>>>>>>> + * core is tsv110, CCL_ID is the low 3-bits in MPIDR[Aff2] and SCCL_ID
>>>>>>> + * is the upper 5-bits of Aff2 field; while for other cpu types, SCCL_ID
>>>>>>> + * is in MPIDR[Aff3] and CCL_ID is in MPIDR[Aff2], if not, SCCL_ID
>>>>>>>      * is in MPIDR[Aff2] and CCL_ID is in MPIDR[Aff1].
>>>>>>>      */
>>>>>>>     static void hisi_read_sccl_and_ccl_id(int *sccl_id, int *ccl_id)
>>>>>>> @@ -347,12 +350,19 @@ static void hisi_read_sccl_and_ccl_id(int *sccl_id, int *ccl_id)
>>>>>>>         u64 mpidr = read_cpuid_mpidr();
>>>>>>>         if (mpidr & MPIDR_MT_BITMASK) {
>>>>>>> -        int aff2 = MPIDR_AFFINITY_LEVEL(mpidr, 2);
>>>>>>> -
>>>>>>> -        if (sccl_id)
>>>>>>> -            *sccl_id = aff2 >> 3;
>>>>>>> -        if (ccl_id)
>>>>>>> -            *ccl_id = aff2 & 0x7;
>>>>>>> +        if (read_cpuid_part_number() == HISI_CPU_PART_TSV110) {
>>>>>>> +            int aff2 = MPIDR_AFFINITY_LEVEL(mpidr, 2);
>>>>>>> +
>>>>>>> +            if (sccl_id)
>>>>>>> +                *sccl_id = aff2 >> 3;
>>>>>>> +            if (ccl_id)
>>>>>>> +                *ccl_id = aff2 & 0x7;
>>>>>>> +        } else {
>>>>>>> +            if (sccl_id)
>>>>>>> +                *sccl_id = MPIDR_AFFINITY_LEVEL(mpidr, 3);
>>>>>>> +            if (ccl_id)
>>>>>>> +                *ccl_id = MPIDR_AFFINITY_LEVEL(mpidr, 2);
>>>>>>> +        }
>>>>>>
>>>>>> [I prefer Mark's version, so please reply to indicate whether or not it
>>>>>>     works for you]
>>>>>
>>>>> Replying on Shaokun's behalf as he appears offline now.
>>>>>
>>>>> In response to "> If TSV110 is always MT, ":
>>>>>
>>>>> It isn't. There are 2 spins of Huawei Kunpeng 920 SoC which includes
>>>>> TaishanV110 aka TSV110: one has the MT bit set and the other without.
>>>>
>>>> Just to check, for the non-MT variant is the SCCL/CCL assignment
>>>> Aff2/Aff1 as with other non-MT parts?
>>>
>>> We don't support any other non-MT parts for this driver.
>>
>> The driver claimed to support non-MT parts before TSV110 came around, so that
>> statement confuses me.
> 
> A couple of points on this:
> 
> - We gave up on upstreaming support in this driver for the predecessor SoC, which included an A72. You may remember the infamous djtag bus.
> 
> - The wording in the comment "If multi-threading is supported, On Huawei Kunpeng 920 SoC " is misleading, as it implies that the part found in Huawei Kunpeng 920 is MT, which it isn't always.
> 
>>
>> For a non-MT TSV110, is Aff2 the SCCL and Aff1 the CCL? 
> 
> Yes,
> 
> That's what the
>> existing code (and Shaokun's patch) assumed.
> 
> well I'm going with that as well. Shaokun can confirm the layout.
> 

Right, it works.

>>
>> Assuming that is the case, I'd suggest we have the following:
>>
>> /*
>>   * The Super CPU Cluster (SCCL) and CPU Cluster (CCL) IDs can be
>>   * determined from the MPIDR_EL1, but the encoding varies by CPU:
>>   *
>>   * - For MT variants of TSV110 (e.g. found in Kunpeng 920):
> 
> Again, this implies that the part found in Kunpeng 920 is MT, which it isn't always.
> 
> BTW, As I understand, the MIDR variant bits differ between the 2 revs of TSV110, so maybe that is a better method to differentiate, but I don't see an API exported for this.
> 

Yes, the CPU variant is different.

Thanks,
Shaokun

>>   *   SCCL is Aff2[7:3], CCL is Aff2[2:0]
>>   *
>>   * - For other MT parts:
>>   *   SCCL is Aff3[7:0], CCL is Aff2[7:0]
>>   *
>>   * - For non-MT parts:
>>   *   SCCL is Aff2[7:0], CCL is Aff1[7:0]
>>   */
>> static void hisi_read_sccl_and_ccl_id(int *scclp, int *cclp)
>> {
>>     u64 mpidr = read_cpuid_mpidr();
>>     int aff3 = MPIDR_AFFINITY_LEVEL(mpidr, 3);
>>     int aff2 = MPIDR_AFFINITY_LEVEL(mpidr, 2);
>>     int aff1 = MPIDR_AFFINITY_LEVEL(mpidr, 1);
>>     bool mt = mpdir & MPIDR_MT_BITMASK;
>>     int sccl, ccl;
>>
>>     if (mt && read_cpuid_part_number() == HISI_CPU_PART_TSV110) {
>>         sccl = aff2 >> 3;
>>         ccl = aff2 & 0x7;
>>     } else if (mt) {
>>         sccl = aff3;
>>         ccl = aff2;
>>     } else {
>>         sccl = aff2;
>>         ccl = aff1;
>>     }
>>
>>     if (scclp)
>>         *scclp = sccl;
>>     if (cclp)
>>         *cclp = ccl;
>> }
>>
>> Thanks,
>> Mark.
> 
> Thanks,
> John
> 
>> .
>>
> 
> 
> .
>
Shaokun Zhang Nov. 8, 2019, 1:25 a.m. UTC | #11
Hi Will,

On 2019/11/7 21:09, Will Deacon wrote:
> On Thu, Nov 07, 2019 at 01:04:34PM +0000, John Garry wrote:
>>>>>>> On Thu, Nov 07, 2019 at 03:56:04PM +0800, Shaokun Zhang wrote:
>>>>>>> [I prefer Mark's version, so please reply to indicate whether or not it
>>>>>>>     works for you]
>>>>>>
>>>>>> Replying on Shaokun's behalf as he appears offline now.
>>>>>>
>>>>>> In response to "> If TSV110 is always MT, ":
>>>>>>
>>>>>> It isn't. There are 2 spins of Huawei Kunpeng 920 SoC which includes
>>>>>> TaishanV110 aka TSV110: one has the MT bit set and the other without.
>>>>>
>>>>> Just to check, for the non-MT variant is the SCCL/CCL assignment
>>>>> Aff2/Aff1 as with other non-MT parts?
>>>>
>>>> We don't support any other non-MT parts for this driver.
>>>
>>> The driver claimed to support non-MT parts before TSV110 came around, so that
>>> statement confuses me.
>>
>> A couple of points on this:
>>
>> - We gave up on upstreaming support in this driver for the predecessor SoC,
>> which included an A72. You may remember the infamous djtag bus.
>>
>> - The wording in the comment "If multi-threading is supported, On Huawei
>> Kunpeng 920 SoC " is misleading, as it implies that the part found in Huawei
>> Kunpeng 920 is MT, which it isn't always.
>>
>>>
>>> For a non-MT TSV110, is Aff2 the SCCL and Aff1 the CCL?
>>
>> Yes,
>>
>> That's what the
>>> existing code (and Shaokun's patch) assumed.
>>
>> well I'm going with that as well. Shaokun can confirm the layout.
> 
> I'll queue Shaokun's patch for now, since I want to get this to Catalin

Thanks Will.

> tomorrow for 5.5 after spending the night in -next. We can always simplify
> the logic later if Mark's patch ends up working out.

I have checked that it has been in your for-next/perf branch. I will simplify
it later as Mark's suggestion.
Or if it is permitted, I can post v2 and simplify this.

Thanks,
Shaokun

> 
> Thanks,
> 
> Will
> 
> .
>
Shaokun Zhang Nov. 8, 2019, 1:28 a.m. UTC | #12
Hi Will,

On 2019/11/7 19:40, Will Deacon wrote:
> Hi,
> 
> On Thu, Nov 07, 2019 at 03:56:04PM +0800, Shaokun Zhang wrote:
>> @@ -338,8 +339,10 @@ void hisi_uncore_pmu_disable(struct pmu *pmu)
>>  
>>  /*
>>   * Read Super CPU cluster and CPU cluster ID from MPIDR_EL1.
>> - * If multi-threading is supported, CCL_ID is the low 3-bits in MPIDR[Aff2]
>> - * and SCCL_ID is the upper 5-bits of Aff2 field; if not, SCCL_ID
>> + * If multi-threading is supported, On Huawei Kunpeng 920 SoC whose cpu
>> + * core is tsv110, CCL_ID is the low 3-bits in MPIDR[Aff2] and SCCL_ID
>> + * is the upper 5-bits of Aff2 field; while for other cpu types, SCCL_ID
>> + * is in MPIDR[Aff3] and CCL_ID is in MPIDR[Aff2], if not, SCCL_ID
>>   * is in MPIDR[Aff2] and CCL_ID is in MPIDR[Aff1].
>>   */
>>  static void hisi_read_sccl_and_ccl_id(int *sccl_id, int *ccl_id)
>> @@ -347,12 +350,19 @@ static void hisi_read_sccl_and_ccl_id(int *sccl_id, int *ccl_id)
>>  	u64 mpidr = read_cpuid_mpidr();
>>  
>>  	if (mpidr & MPIDR_MT_BITMASK) {
>> -		int aff2 = MPIDR_AFFINITY_LEVEL(mpidr, 2);
>> -
>> -		if (sccl_id)
>> -			*sccl_id = aff2 >> 3;
>> -		if (ccl_id)
>> -			*ccl_id = aff2 & 0x7;
>> +		if (read_cpuid_part_number() == HISI_CPU_PART_TSV110) {
>> +			int aff2 = MPIDR_AFFINITY_LEVEL(mpidr, 2);
>> +
>> +			if (sccl_id)
>> +				*sccl_id = aff2 >> 3;
>> +			if (ccl_id)
>> +				*ccl_id = aff2 & 0x7;
>> +		} else {
>> +			if (sccl_id)
>> +				*sccl_id = MPIDR_AFFINITY_LEVEL(mpidr, 3);
>> +			if (ccl_id)
>> +				*ccl_id = MPIDR_AFFINITY_LEVEL(mpidr, 2);
>> +		}
> 
> [I prefer Mark's version, so please reply to indicate whether or not it
>  works for you]
> 
> So I'll take this, but the lesson here seems to be that it's a terrible idea
> to infer system topology from CPU ID registers. In future, I'm going to
> insist that this comes from firmware tables because hacks like the above are

My bad, I shall do it in future.

Thanks,
Shaokun

> not sustainable.
> 
> Will
> 
> .
>
Will Deacon Nov. 8, 2019, 9:49 a.m. UTC | #13
On Fri, Nov 08, 2019 at 09:25:29AM +0800, Shaokun Zhang wrote:
> On 2019/11/7 21:09, Will Deacon wrote:
> > I'll queue Shaokun's patch for now, since I want to get this to Catalin
> 
> Thanks Will.
> 
> > tomorrow for 5.5 after spending the night in -next. We can always simplify
> > the logic later if Mark's patch ends up working out.
> 
> I have checked that it has been in your for-next/perf branch. I will simplify
> it later as Mark's suggestion.
> Or if it is permitted, I can post v2 and simplify this.

Please just send a patch on top, since I don't want to rebase that branch
now.

Cheers,

Will
diff mbox series

Patch

diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.c b/drivers/perf/hisilicon/hisi_uncore_pmu.c
index 79f76f8dda8e..96183e31b96a 100644
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.c
@@ -15,6 +15,7 @@ 
 #include <linux/errno.h>
 #include <linux/interrupt.h>
 
+#include <asm/cputype.h>
 #include <asm/local64.h>
 
 #include "hisi_uncore_pmu.h"
@@ -338,8 +339,10 @@  void hisi_uncore_pmu_disable(struct pmu *pmu)
 
 /*
  * Read Super CPU cluster and CPU cluster ID from MPIDR_EL1.
- * If multi-threading is supported, CCL_ID is the low 3-bits in MPIDR[Aff2]
- * and SCCL_ID is the upper 5-bits of Aff2 field; if not, SCCL_ID
+ * If multi-threading is supported, On Huawei Kunpeng 920 SoC whose cpu
+ * core is tsv110, CCL_ID is the low 3-bits in MPIDR[Aff2] and SCCL_ID
+ * is the upper 5-bits of Aff2 field; while for other cpu types, SCCL_ID
+ * is in MPIDR[Aff3] and CCL_ID is in MPIDR[Aff2], if not, SCCL_ID
  * is in MPIDR[Aff2] and CCL_ID is in MPIDR[Aff1].
  */
 static void hisi_read_sccl_and_ccl_id(int *sccl_id, int *ccl_id)
@@ -347,12 +350,19 @@  static void hisi_read_sccl_and_ccl_id(int *sccl_id, int *ccl_id)
 	u64 mpidr = read_cpuid_mpidr();
 
 	if (mpidr & MPIDR_MT_BITMASK) {
-		int aff2 = MPIDR_AFFINITY_LEVEL(mpidr, 2);
-
-		if (sccl_id)
-			*sccl_id = aff2 >> 3;
-		if (ccl_id)
-			*ccl_id = aff2 & 0x7;
+		if (read_cpuid_part_number() == HISI_CPU_PART_TSV110) {
+			int aff2 = MPIDR_AFFINITY_LEVEL(mpidr, 2);
+
+			if (sccl_id)
+				*sccl_id = aff2 >> 3;
+			if (ccl_id)
+				*ccl_id = aff2 & 0x7;
+		} else {
+			if (sccl_id)
+				*sccl_id = MPIDR_AFFINITY_LEVEL(mpidr, 3);
+			if (ccl_id)
+				*ccl_id = MPIDR_AFFINITY_LEVEL(mpidr, 2);
+		}
 	} else {
 		if (sccl_id)
 			*sccl_id = MPIDR_AFFINITY_LEVEL(mpidr, 2);