diff mbox series

perf/arm-cmn: Fix port detection for CMN-700

Message ID 68ff05869f6dae06a92c5d320e535d8a2f75a0cd.1680522619.git.robin.murphy@arm.com (mailing list archive)
State New, archived
Headers show
Series perf/arm-cmn: Fix port detection for CMN-700 | expand

Commit Message

Robin Murphy April 3, 2023, 11:50 a.m. UTC
When the "extra device ports" configuration was first added, the
additional mxp_device_port_connect_info registers were added around the
existing mxp_mesh_port_connect_info registers. What I missed about
CMN-700 is that it shuffled them around to remove this discontinuity.
As such, tweak the definitions and factor out a helper for reading these
registers so we can deal with this discrepancy easily, which does at
least allow nicely tidying up the callsites. With this we can then also
do the nice thing and skip accesses completely rather than relying on
RES0 behaviour where we know the extra registers aren't defined.

Fixes: 23760a014417 ("perf/arm-cmn: Add CMN-700 support")
Reported-by: Jing Zhang <renyu.zj@linux.alibaba.com>
Signed-off-by: Robin Murphy <robin.murphy@arm.com>
---
 drivers/perf/arm-cmn.c | 55 ++++++++++++++++++++++--------------------
 1 file changed, 29 insertions(+), 26 deletions(-)

Comments

Robin Murphy April 3, 2023, 12:47 p.m. UTC | #1
On 2023-04-03 12:50, Robin Murphy wrote:
> When the "extra device ports" configuration was first added, the
> additional mxp_device_port_connect_info registers were added around the
> existing mxp_mesh_port_connect_info registers. What I missed about
> CMN-700 is that it shuffled them around to remove this discontinuity.
> As such, tweak the definitions and factor out a helper for reading these
> registers so we can deal with this discrepancy easily, which does at
> least allow nicely tidying up the callsites. With this we can then also
> do the nice thing and skip accesses completely rather than relying on
> RES0 behaviour where we know the extra registers aren't defined.
> 
> Fixes: 23760a014417 ("perf/arm-cmn: Add CMN-700 support")
> Reported-by: Jing Zhang <renyu.zj@linux.alibaba.com>
> Signed-off-by: Robin Murphy <robin.murphy@arm.com>
> ---
>   drivers/perf/arm-cmn.c | 55 ++++++++++++++++++++++--------------------
>   1 file changed, 29 insertions(+), 26 deletions(-)
> 
> diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c
> index c9689861be3f..367d41c5d983 100644
> --- a/drivers/perf/arm-cmn.c
> +++ b/drivers/perf/arm-cmn.c
> @@ -57,14 +57,12 @@
>   #define CMN_INFO_REQ_VC_NUM		GENMASK_ULL(1, 0)
>   
>   /* XPs also have some local topology info which has uses too */
> -#define CMN_MXP__CONNECT_INFO_P0	0x0008
> -#define CMN_MXP__CONNECT_INFO_P1	0x0010
> -#define CMN_MXP__CONNECT_INFO_P2	0x0028
> -#define CMN_MXP__CONNECT_INFO_P3	0x0030
> -#define CMN_MXP__CONNECT_INFO_P4	0x0038
> -#define CMN_MXP__CONNECT_INFO_P5	0x0040
> +#define CMN_MXP__CONNECT_INFO(p)	(0x0008 + 8 * (p))
>   #define CMN__CONNECT_INFO_DEVICE_TYPE	GENMASK_ULL(4, 0)
>   
> +#define CMN_MAX_PORTS			6
> +#define CI700_CONNECT_INFO_P2_5_OFFSET	0x20

...which of course should be 0x10 for the way the code below ended up, 
sigh. I'll wait for any further review before resending.

Cheers,
Robin.

> +
>   /* PMU registers occupy the 3rd 4KB page of each node's region */
>   #define CMN_PMU_OFFSET			0x2000
>   
> @@ -396,6 +394,25 @@ static struct arm_cmn_node *arm_cmn_node(const struct arm_cmn *cmn,
>   	return NULL;
>   }
>   
> +static u32 arm_cmn_device_connect_info(const struct arm_cmn *cmn,
> +				       const struct arm_cmn_node *xp, int port)
> +{
> +	int offset = CMN_MXP__CONNECT_INFO(port);
> +
> +	if (port >= 2) {
> +		if (cmn->model & (CMN600 | CMN650))
> +			return 0;
> +		/*
> +		 * CI-700 may have extra ports, but still has the
> +		 * mesh_port_connect_info registers in the way.
> +		 */
> +		if (cmn->model == CI700)
> +			offset += CI700_CONNECT_INFO_P2_5_OFFSET;
> +	}
> +
> +	return readl_relaxed(xp->pmu_base - CMN_PMU_OFFSET + offset);
> +}
> +
>   static struct dentry *arm_cmn_debugfs;
>   
>   #ifdef CONFIG_DEBUG_FS
> @@ -469,7 +486,7 @@ static int arm_cmn_map_show(struct seq_file *s, void *data)
>   	y = cmn->mesh_y;
>   	while (y--) {
>   		int xp_base = cmn->mesh_x * y;
> -		u8 port[6][CMN_MAX_DIMENSION];
> +		u8 port[CMN_MAX_PORTS][CMN_MAX_DIMENSION];
>   
>   		for (x = 0; x < cmn->mesh_x; x++)
>   			seq_puts(s, "--------+");
> @@ -477,14 +494,9 @@ static int arm_cmn_map_show(struct seq_file *s, void *data)
>   		seq_printf(s, "\n%d    |", y);
>   		for (x = 0; x < cmn->mesh_x; x++) {
>   			struct arm_cmn_node *xp = cmn->xps + xp_base + x;
> -			void __iomem *base = xp->pmu_base - CMN_PMU_OFFSET;
>   
> -			port[0][x] = readl_relaxed(base + CMN_MXP__CONNECT_INFO_P0);
> -			port[1][x] = readl_relaxed(base + CMN_MXP__CONNECT_INFO_P1);
> -			port[2][x] = readl_relaxed(base + CMN_MXP__CONNECT_INFO_P2);
> -			port[3][x] = readl_relaxed(base + CMN_MXP__CONNECT_INFO_P3);
> -			port[4][x] = readl_relaxed(base + CMN_MXP__CONNECT_INFO_P4);
> -			port[5][x] = readl_relaxed(base + CMN_MXP__CONNECT_INFO_P5);
> +			for (p = 0; p < CMN_MAX_PORTS; p++)
> +				port[p][x] = arm_cmn_device_connect_info(cmn, xp, p);
>   			seq_printf(s, " XP #%-2d |", xp_base + x);
>   		}
>   
> @@ -2083,18 +2095,9 @@ static int arm_cmn_discover(struct arm_cmn *cmn, unsigned int rgn_offset)
>   		 * from this, since in that case we will see at least one XP
>   		 * with port 2 connected, for the HN-D.
>   		 */
> -		if (readq_relaxed(xp_region + CMN_MXP__CONNECT_INFO_P0))
> -			xp_ports |= BIT(0);
> -		if (readq_relaxed(xp_region + CMN_MXP__CONNECT_INFO_P1))
> -			xp_ports |= BIT(1);
> -		if (readq_relaxed(xp_region + CMN_MXP__CONNECT_INFO_P2))
> -			xp_ports |= BIT(2);
> -		if (readq_relaxed(xp_region + CMN_MXP__CONNECT_INFO_P3))
> -			xp_ports |= BIT(3);
> -		if (readq_relaxed(xp_region + CMN_MXP__CONNECT_INFO_P4))
> -			xp_ports |= BIT(4);
> -		if (readq_relaxed(xp_region + CMN_MXP__CONNECT_INFO_P5))
> -			xp_ports |= BIT(5);
> +		for (int p = 0; p < CMN_MAX_PORTS; p++)
> +			if (arm_cmn_device_connect_info(cmn, xp, p))
> +				xp_ports |= BIT(p);
>   
>   		if (cmn->multi_dtm && (xp_ports & 0xc))
>   			arm_cmn_init_dtm(dtm++, xp, 1);
Ilkka Koskinen April 4, 2023, 6:12 a.m. UTC | #2
Hi Robin,

On Mon, 3 Apr 2023, Robin Murphy wrote:
> On 2023-04-03 12:50, Robin Murphy wrote:
>> When the "extra device ports" configuration was first added, the
>> additional mxp_device_port_connect_info registers were added around the
>> existing mxp_mesh_port_connect_info registers. What I missed about
>> CMN-700 is that it shuffled them around to remove this discontinuity.
>> As such, tweak the definitions and factor out a helper for reading these
>> registers so we can deal with this discrepancy easily, which does at
>> least allow nicely tidying up the callsites. With this we can then also
>> do the nice thing and skip accesses completely rather than relying on
>> RES0 behaviour where we know the extra registers aren't defined.
>> 
>> Fixes: 23760a014417 ("perf/arm-cmn: Add CMN-700 support")
>> Reported-by: Jing Zhang <renyu.zj@linux.alibaba.com>
>> Signed-off-by: Robin Murphy <robin.murphy@arm.com>
>> ---
>>   drivers/perf/arm-cmn.c | 55 ++++++++++++++++++++++--------------------
>>   1 file changed, 29 insertions(+), 26 deletions(-)
>> 
>> diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c
>> index c9689861be3f..367d41c5d983 100644
>> --- a/drivers/perf/arm-cmn.c
>> +++ b/drivers/perf/arm-cmn.c
>> @@ -57,14 +57,12 @@
>>   #define CMN_INFO_REQ_VC_NUM		GENMASK_ULL(1, 0)
>>     /* XPs also have some local topology info which has uses too */
>> -#define CMN_MXP__CONNECT_INFO_P0	0x0008
>> -#define CMN_MXP__CONNECT_INFO_P1	0x0010
>> -#define CMN_MXP__CONNECT_INFO_P2	0x0028
>> -#define CMN_MXP__CONNECT_INFO_P3	0x0030
>> -#define CMN_MXP__CONNECT_INFO_P4	0x0038
>> -#define CMN_MXP__CONNECT_INFO_P5	0x0040
>> +#define CMN_MXP__CONNECT_INFO(p)	(0x0008 + 8 * (p))
>>   #define CMN__CONNECT_INFO_DEVICE_TYPE	GENMASK_ULL(4, 0)
>>   +#define CMN_MAX_PORTS			6
>> +#define CI700_CONNECT_INFO_P2_5_OFFSET	0x20
>
> ...which of course should be 0x10 for the way the code below ended up, sigh. 
> I'll wait for any further review before resending.
>
> Cheers,
> Robin.

I quickly checked cmn650, cmn700, ci700 TRMs and the change looks good to 
me. I also tested the patch briefly on cmn650 and it was working fine just 
like I expected.

Cheers, Ilkka

>> +
>>   /* PMU registers occupy the 3rd 4KB page of each node's region */
>>   #define CMN_PMU_OFFSET			0x2000
>>   @@ -396,6 +394,25 @@ static struct arm_cmn_node *arm_cmn_node(const 
>> struct arm_cmn *cmn,
>>   	return NULL;
>>   }
>>   +static u32 arm_cmn_device_connect_info(const struct arm_cmn *cmn,
>> +				       const struct arm_cmn_node *xp, int 
>> port)
>> +{
>> +	int offset = CMN_MXP__CONNECT_INFO(port);
>> +
>> +	if (port >= 2) {
>> +		if (cmn->model & (CMN600 | CMN650))
>> +			return 0;
>> +		/*
>> +		 * CI-700 may have extra ports, but still has the
>> +		 * mesh_port_connect_info registers in the way.
>> +		 */
>> +		if (cmn->model == CI700)
>> +			offset += CI700_CONNECT_INFO_P2_5_OFFSET;
>> +	}
>> +
>> +	return readl_relaxed(xp->pmu_base - CMN_PMU_OFFSET + offset);
>> +}
>> +
>>   static struct dentry *arm_cmn_debugfs;
>>     #ifdef CONFIG_DEBUG_FS
>> @@ -469,7 +486,7 @@ static int arm_cmn_map_show(struct seq_file *s, void 
>> *data)
>>   	y = cmn->mesh_y;
>>   	while (y--) {
>>   		int xp_base = cmn->mesh_x * y;
>> -		u8 port[6][CMN_MAX_DIMENSION];
>> +		u8 port[CMN_MAX_PORTS][CMN_MAX_DIMENSION];
>>     		for (x = 0; x < cmn->mesh_x; x++)
>>   			seq_puts(s, "--------+");
>> @@ -477,14 +494,9 @@ static int arm_cmn_map_show(struct seq_file *s, void 
>> *data)
>>   		seq_printf(s, "\n%d    |", y);
>>   		for (x = 0; x < cmn->mesh_x; x++) {
>>   			struct arm_cmn_node *xp = cmn->xps + xp_base + x;
>> -			void __iomem *base = xp->pmu_base - CMN_PMU_OFFSET;
>>   -			port[0][x] = readl_relaxed(base + 
>> CMN_MXP__CONNECT_INFO_P0);
>> -			port[1][x] = readl_relaxed(base + 
>> CMN_MXP__CONNECT_INFO_P1);
>> -			port[2][x] = readl_relaxed(base + 
>> CMN_MXP__CONNECT_INFO_P2);
>> -			port[3][x] = readl_relaxed(base + 
>> CMN_MXP__CONNECT_INFO_P3);
>> -			port[4][x] = readl_relaxed(base + 
>> CMN_MXP__CONNECT_INFO_P4);
>> -			port[5][x] = readl_relaxed(base + 
>> CMN_MXP__CONNECT_INFO_P5);
>> +			for (p = 0; p < CMN_MAX_PORTS; p++)
>> +				port[p][x] = arm_cmn_device_connect_info(cmn, 
>> xp, p);
>>   			seq_printf(s, " XP #%-2d |", xp_base + x);
>>   		}
>>   @@ -2083,18 +2095,9 @@ static int arm_cmn_discover(struct arm_cmn *cmn, 
>> unsigned int rgn_offset)
>>   		 * from this, since in that case we will see at least one XP
>>   		 * with port 2 connected, for the HN-D.
>>   		 */
>> -		if (readq_relaxed(xp_region + CMN_MXP__CONNECT_INFO_P0))
>> -			xp_ports |= BIT(0);
>> -		if (readq_relaxed(xp_region + CMN_MXP__CONNECT_INFO_P1))
>> -			xp_ports |= BIT(1);
>> -		if (readq_relaxed(xp_region + CMN_MXP__CONNECT_INFO_P2))
>> -			xp_ports |= BIT(2);
>> -		if (readq_relaxed(xp_region + CMN_MXP__CONNECT_INFO_P3))
>> -			xp_ports |= BIT(3);
>> -		if (readq_relaxed(xp_region + CMN_MXP__CONNECT_INFO_P4))
>> -			xp_ports |= BIT(4);
>> -		if (readq_relaxed(xp_region + CMN_MXP__CONNECT_INFO_P5))
>> -			xp_ports |= BIT(5);
>> +		for (int p = 0; p < CMN_MAX_PORTS; p++)
>> +			if (arm_cmn_device_connect_info(cmn, xp, p))
>> +				xp_ports |= BIT(p);
>>     		if (cmn->multi_dtm && (xp_ports & 0xc))
>>   			arm_cmn_init_dtm(dtm++, xp, 1);
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>
Jing Zhang April 10, 2023, 8:19 a.m. UTC | #3
在 2023/4/3 下午8:47, Robin Murphy 写道:
> On 2023-04-03 12:50, Robin Murphy wrote:
>> When the "extra device ports" configuration was first added, the
>> additional mxp_device_port_connect_info registers were added around the
>> existing mxp_mesh_port_connect_info registers. What I missed about
>> CMN-700 is that it shuffled them around to remove this discontinuity.
>> As such, tweak the definitions and factor out a helper for reading these
>> registers so we can deal with this discrepancy easily, which does at
>> least allow nicely tidying up the callsites. With this we can then also
>> do the nice thing and skip accesses completely rather than relying on
>> RES0 behaviour where we know the extra registers aren't defined.
>>
>> Fixes: 23760a014417 ("perf/arm-cmn: Add CMN-700 support")
>> Reported-by: Jing Zhang <renyu.zj@linux.alibaba.com>
>> Signed-off-by: Robin Murphy <robin.murphy@arm.com>
>> ---
>>   drivers/perf/arm-cmn.c | 55 ++++++++++++++++++++++--------------------
>>   1 file changed, 29 insertions(+), 26 deletions(-)
>>
>> diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c
>> index c9689861be3f..367d41c5d983 100644
>> --- a/drivers/perf/arm-cmn.c
>> +++ b/drivers/perf/arm-cmn.c
>> @@ -57,14 +57,12 @@
>>   #define CMN_INFO_REQ_VC_NUM        GENMASK_ULL(1, 0)
>>     /* XPs also have some local topology info which has uses too */
>> -#define CMN_MXP__CONNECT_INFO_P0    0x0008
>> -#define CMN_MXP__CONNECT_INFO_P1    0x0010
>> -#define CMN_MXP__CONNECT_INFO_P2    0x0028
>> -#define CMN_MXP__CONNECT_INFO_P3    0x0030
>> -#define CMN_MXP__CONNECT_INFO_P4    0x0038
>> -#define CMN_MXP__CONNECT_INFO_P5    0x0040
>> +#define CMN_MXP__CONNECT_INFO(p)    (0x0008 + 8 * (p))
>>   #define CMN__CONNECT_INFO_DEVICE_TYPE    GENMASK_ULL(4, 0)
>>   +#define CMN_MAX_PORTS            6
>> +#define CI700_CONNECT_INFO_P2_5_OFFSET    0x20
> 
> ...which of course should be 0x10 for the way the code below ended up, sigh. I'll wait for any further review before resending.
> 
> Cheers,
> Robin.
> 
>> +
>>   /* PMU registers occupy the 3rd 4KB page of each node's region */
>>   #define CMN_PMU_OFFSET            0x2000
>>   @@ -396,6 +394,25 @@ static struct arm_cmn_node *arm_cmn_node(const struct arm_cmn *cmn,
>>       return NULL;
>>   }
>>   +static u32 arm_cmn_device_connect_info(const struct arm_cmn *cmn,
>> +                       const struct arm_cmn_node *xp, int port)
>> +{
>> +    int offset = CMN_MXP__CONNECT_INFO(port);
>> +
>> +    if (port >= 2) {
>> +        if (cmn->model & (CMN600 | CMN650))
>> +            return 0;
>> +        /*
>> +         * CI-700 may have extra ports, but still has the
>> +         * mesh_port_connect_info registers in the way.
>> +         */
>> +        if (cmn->model == CI700)
>> +            offset += CI700_CONNECT_INFO_P2_5_OFFSET;
>> +    }
>> +
>> +    return readl_relaxed(xp->pmu_base - CMN_PMU_OFFSET + offset);
>> +}
>> +
>>   static struct dentry *arm_cmn_debugfs;
>>     #ifdef CONFIG_DEBUG_FS
>> @@ -469,7 +486,7 @@ static int arm_cmn_map_show(struct seq_file *s, void *data)
>>       y = cmn->mesh_y;
>>       while (y--) {
>>           int xp_base = cmn->mesh_x * y;
>> -        u8 port[6][CMN_MAX_DIMENSION];
>> +        u8 port[CMN_MAX_PORTS][CMN_MAX_DIMENSION];
>>             for (x = 0; x < cmn->mesh_x; x++)
>>               seq_puts(s, "--------+");
>> @@ -477,14 +494,9 @@ static int arm_cmn_map_show(struct seq_file *s, void *data)
>>           seq_printf(s, "\n%d    |", y);
>>           for (x = 0; x < cmn->mesh_x; x++) {
>>               struct arm_cmn_node *xp = cmn->xps + xp_base + x;
>> -            void __iomem *base = xp->pmu_base - CMN_PMU_OFFSET;
>>   -            port[0][x] = readl_relaxed(base + CMN_MXP__CONNECT_INFO_P0);
>> -            port[1][x] = readl_relaxed(base + CMN_MXP__CONNECT_INFO_P1);
>> -            port[2][x] = readl_relaxed(base + CMN_MXP__CONNECT_INFO_P2);
>> -            port[3][x] = readl_relaxed(base + CMN_MXP__CONNECT_INFO_P3);
>> -            port[4][x] = readl_relaxed(base + CMN_MXP__CONNECT_INFO_P4);
>> -            port[5][x] = readl_relaxed(base + CMN_MXP__CONNECT_INFO_P5);
>> +            for (p = 0; p < CMN_MAX_PORTS; p++)
>> +                port[p][x] = arm_cmn_device_connect_info(cmn, xp, p);
>>               seq_printf(s, " XP #%-2d |", xp_base + x);
>>           }
>>   @@ -2083,18 +2095,9 @@ static int arm_cmn_discover(struct arm_cmn *cmn, unsigned int rgn_offset)
>>            * from this, since in that case we will see at least one XP
>>            * with port 2 connected, for the HN-D.
>>            */
>> -        if (readq_relaxed(xp_region + CMN_MXP__CONNECT_INFO_P0))
>> -            xp_ports |= BIT(0);
>> -        if (readq_relaxed(xp_region + CMN_MXP__CONNECT_INFO_P1))
>> -            xp_ports |= BIT(1);
>> -        if (readq_relaxed(xp_region + CMN_MXP__CONNECT_INFO_P2))
>> -            xp_ports |= BIT(2);
>> -        if (readq_relaxed(xp_region + CMN_MXP__CONNECT_INFO_P3))
>> -            xp_ports |= BIT(3);
>> -        if (readq_relaxed(xp_region + CMN_MXP__CONNECT_INFO_P4))
>> -            xp_ports |= BIT(4);
>> -        if (readq_relaxed(xp_region + CMN_MXP__CONNECT_INFO_P5))
>> -            xp_ports |= BIT(5);
>> +        for (int p = 0; p < CMN_MAX_PORTS; p++)


Hi Robin,

I tested the patch on CMN700, it works fine as I expected.
And maybe the variable 'p' should be defined to the front?

Thanks,
Jing


>> +            if (arm_cmn_device_connect_info(cmn, xp, p))
>> +                xp_ports |= BIT(p);
>>             if (cmn->multi_dtm && (xp_ports & 0xc))
>>               arm_cmn_init_dtm(dtm++, xp, 1);
diff mbox series

Patch

diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c
index c9689861be3f..367d41c5d983 100644
--- a/drivers/perf/arm-cmn.c
+++ b/drivers/perf/arm-cmn.c
@@ -57,14 +57,12 @@ 
 #define CMN_INFO_REQ_VC_NUM		GENMASK_ULL(1, 0)
 
 /* XPs also have some local topology info which has uses too */
-#define CMN_MXP__CONNECT_INFO_P0	0x0008
-#define CMN_MXP__CONNECT_INFO_P1	0x0010
-#define CMN_MXP__CONNECT_INFO_P2	0x0028
-#define CMN_MXP__CONNECT_INFO_P3	0x0030
-#define CMN_MXP__CONNECT_INFO_P4	0x0038
-#define CMN_MXP__CONNECT_INFO_P5	0x0040
+#define CMN_MXP__CONNECT_INFO(p)	(0x0008 + 8 * (p))
 #define CMN__CONNECT_INFO_DEVICE_TYPE	GENMASK_ULL(4, 0)
 
+#define CMN_MAX_PORTS			6
+#define CI700_CONNECT_INFO_P2_5_OFFSET	0x20
+
 /* PMU registers occupy the 3rd 4KB page of each node's region */
 #define CMN_PMU_OFFSET			0x2000
 
@@ -396,6 +394,25 @@  static struct arm_cmn_node *arm_cmn_node(const struct arm_cmn *cmn,
 	return NULL;
 }
 
+static u32 arm_cmn_device_connect_info(const struct arm_cmn *cmn,
+				       const struct arm_cmn_node *xp, int port)
+{
+	int offset = CMN_MXP__CONNECT_INFO(port);
+
+	if (port >= 2) {
+		if (cmn->model & (CMN600 | CMN650))
+			return 0;
+		/*
+		 * CI-700 may have extra ports, but still has the
+		 * mesh_port_connect_info registers in the way.
+		 */
+		if (cmn->model == CI700)
+			offset += CI700_CONNECT_INFO_P2_5_OFFSET;
+	}
+
+	return readl_relaxed(xp->pmu_base - CMN_PMU_OFFSET + offset);
+}
+
 static struct dentry *arm_cmn_debugfs;
 
 #ifdef CONFIG_DEBUG_FS
@@ -469,7 +486,7 @@  static int arm_cmn_map_show(struct seq_file *s, void *data)
 	y = cmn->mesh_y;
 	while (y--) {
 		int xp_base = cmn->mesh_x * y;
-		u8 port[6][CMN_MAX_DIMENSION];
+		u8 port[CMN_MAX_PORTS][CMN_MAX_DIMENSION];
 
 		for (x = 0; x < cmn->mesh_x; x++)
 			seq_puts(s, "--------+");
@@ -477,14 +494,9 @@  static int arm_cmn_map_show(struct seq_file *s, void *data)
 		seq_printf(s, "\n%d    |", y);
 		for (x = 0; x < cmn->mesh_x; x++) {
 			struct arm_cmn_node *xp = cmn->xps + xp_base + x;
-			void __iomem *base = xp->pmu_base - CMN_PMU_OFFSET;
 
-			port[0][x] = readl_relaxed(base + CMN_MXP__CONNECT_INFO_P0);
-			port[1][x] = readl_relaxed(base + CMN_MXP__CONNECT_INFO_P1);
-			port[2][x] = readl_relaxed(base + CMN_MXP__CONNECT_INFO_P2);
-			port[3][x] = readl_relaxed(base + CMN_MXP__CONNECT_INFO_P3);
-			port[4][x] = readl_relaxed(base + CMN_MXP__CONNECT_INFO_P4);
-			port[5][x] = readl_relaxed(base + CMN_MXP__CONNECT_INFO_P5);
+			for (p = 0; p < CMN_MAX_PORTS; p++)
+				port[p][x] = arm_cmn_device_connect_info(cmn, xp, p);
 			seq_printf(s, " XP #%-2d |", xp_base + x);
 		}
 
@@ -2083,18 +2095,9 @@  static int arm_cmn_discover(struct arm_cmn *cmn, unsigned int rgn_offset)
 		 * from this, since in that case we will see at least one XP
 		 * with port 2 connected, for the HN-D.
 		 */
-		if (readq_relaxed(xp_region + CMN_MXP__CONNECT_INFO_P0))
-			xp_ports |= BIT(0);
-		if (readq_relaxed(xp_region + CMN_MXP__CONNECT_INFO_P1))
-			xp_ports |= BIT(1);
-		if (readq_relaxed(xp_region + CMN_MXP__CONNECT_INFO_P2))
-			xp_ports |= BIT(2);
-		if (readq_relaxed(xp_region + CMN_MXP__CONNECT_INFO_P3))
-			xp_ports |= BIT(3);
-		if (readq_relaxed(xp_region + CMN_MXP__CONNECT_INFO_P4))
-			xp_ports |= BIT(4);
-		if (readq_relaxed(xp_region + CMN_MXP__CONNECT_INFO_P5))
-			xp_ports |= BIT(5);
+		for (int p = 0; p < CMN_MAX_PORTS; p++)
+			if (arm_cmn_device_connect_info(cmn, xp, p))
+				xp_ports |= BIT(p);
 
 		if (cmn->multi_dtm && (xp_ports & 0xc))
 			arm_cmn_init_dtm(dtm++, xp, 1);