2424#define CMN_NI_NODE_ID GENMASK_ULL(31, 16)
2525#define CMN_NI_LOGICAL_ID GENMASK_ULL(47, 32)
2626
27- #define CMN_NODEID_DEVID (reg ) ((reg) & 3)
28- #define CMN_NODEID_EXT_DEVID (reg ) ((reg) & 1)
29- #define CMN_NODEID_PID (reg ) (((reg) >> 2) & 1)
30- #define CMN_NODEID_EXT_PID (reg ) (((reg) >> 1) & 3)
31- #define CMN_NODEID_1x1_PID (reg ) (((reg) >> 2) & 7)
32- #define CMN_NODEID_X (reg , bits ) ((reg) >> (3 + (bits)))
33- #define CMN_NODEID_Y (reg , bits ) (((reg) >> 3) & ((1U << (bits)) - 1))
34-
3527#define CMN_CHILD_INFO 0x0080
3628#define CMN_CI_CHILD_COUNT GENMASK_ULL(15, 0)
3729#define CMN_CI_CHILD_PTR_OFFSET GENMASK_ULL(31, 16)
@@ -281,8 +273,11 @@ struct arm_cmn_node {
281273 u16 id , logid ;
282274 enum cmn_node_type type ;
283275
276+ /* XP properties really, but replicated to children for convenience */
284277 u8 dtm ;
285278 s8 dtc ;
279+ u8 portid_bits :4 ;
280+ u8 deviceid_bits :4 ;
286281 /* DN/HN-F/CXHA */
287282 struct {
288283 u8 val : 4 ;
@@ -358,49 +353,33 @@ struct arm_cmn {
358353static int arm_cmn_hp_state ;
359354
360355struct arm_cmn_nodeid {
361- u8 x ;
362- u8 y ;
363356 u8 port ;
364357 u8 dev ;
365358};
366359
367360static int arm_cmn_xyidbits (const struct arm_cmn * cmn )
368361{
369- return fls ((cmn -> mesh_x - 1 ) | (cmn -> mesh_y - 1 ) | 2 );
362+ return fls ((cmn -> mesh_x - 1 ) | (cmn -> mesh_y - 1 ));
370363}
371364
372- static struct arm_cmn_nodeid arm_cmn_nid (const struct arm_cmn * cmn , u16 id )
365+ static struct arm_cmn_nodeid arm_cmn_nid (const struct arm_cmn_node * dn )
373366{
374367 struct arm_cmn_nodeid nid ;
375368
376- if (cmn -> num_xps == 1 ) {
377- nid .x = 0 ;
378- nid .y = 0 ;
379- nid .port = CMN_NODEID_1x1_PID (id );
380- nid .dev = CMN_NODEID_DEVID (id );
381- } else {
382- int bits = arm_cmn_xyidbits (cmn );
383-
384- nid .x = CMN_NODEID_X (id , bits );
385- nid .y = CMN_NODEID_Y (id , bits );
386- if (cmn -> ports_used & 0xc ) {
387- nid .port = CMN_NODEID_EXT_PID (id );
388- nid .dev = CMN_NODEID_EXT_DEVID (id );
389- } else {
390- nid .port = CMN_NODEID_PID (id );
391- nid .dev = CMN_NODEID_DEVID (id );
392- }
393- }
369+ nid .dev = dn -> id & ((1U << dn -> deviceid_bits ) - 1 );
370+ nid .port = (dn -> id >> dn -> deviceid_bits ) & ((1U << dn -> portid_bits ) - 1 );
394371 return nid ;
395372}
396373
397374static struct arm_cmn_node * arm_cmn_node_to_xp (const struct arm_cmn * cmn ,
398375 const struct arm_cmn_node * dn )
399376{
400- struct arm_cmn_nodeid nid = arm_cmn_nid (cmn , dn -> id );
401- int xp_idx = cmn -> mesh_x * nid .y + nid .x ;
377+ int id = dn -> id >> (dn -> portid_bits + dn -> deviceid_bits );
378+ int bits = arm_cmn_xyidbits (cmn );
379+ int x = id >> bits ;
380+ int y = id & ((1U << bits ) - 1 );
402381
403- return cmn -> xps + xp_idx ;
382+ return cmn -> xps + cmn -> mesh_x * y + x ;
404383}
405384static struct arm_cmn_node * arm_cmn_node (const struct arm_cmn * cmn ,
406385 enum cmn_node_type type )
@@ -486,13 +465,13 @@ static const char *arm_cmn_device_type(u8 type)
486465 }
487466}
488467
489- static void arm_cmn_show_logid (struct seq_file * s , int x , int y , int p , int d )
468+ static void arm_cmn_show_logid (struct seq_file * s , const struct arm_cmn_node * xp , int p , int d )
490469{
491470 struct arm_cmn * cmn = s -> private ;
492471 struct arm_cmn_node * dn ;
472+ u16 id = xp -> id | d | (p << xp -> deviceid_bits );
493473
494474 for (dn = cmn -> dns ; dn -> type ; dn ++ ) {
495- struct arm_cmn_nodeid nid = arm_cmn_nid (cmn , dn -> id );
496475 int pad = dn -> logid < 10 ;
497476
498477 if (dn -> type == CMN_TYPE_XP )
@@ -501,7 +480,7 @@ static void arm_cmn_show_logid(struct seq_file *s, int x, int y, int p, int d)
501480 if (dn -> type < CMN_TYPE_HNI )
502481 continue ;
503482
504- if (nid . x != x || nid . y != y || nid . port != p || nid . dev != d )
483+ if (dn -> id != id )
505484 continue ;
506485
507486 seq_printf (s , " %*c#%-*d |" , pad + 1 , ' ' , 3 - pad , dn -> logid );
@@ -522,23 +501,22 @@ static int arm_cmn_map_show(struct seq_file *s, void *data)
522501 y = cmn -> mesh_y ;
523502 while (y -- ) {
524503 int xp_base = cmn -> mesh_x * y ;
504+ struct arm_cmn_node * xp = cmn -> xps + xp_base ;
525505 u8 port [CMN_MAX_PORTS ][CMN_MAX_DIMENSION ];
526506
527507 for (x = 0 ; x < cmn -> mesh_x ; x ++ )
528508 seq_puts (s , "--------+" );
529509
530510 seq_printf (s , "\n%-2d |" , y );
531511 for (x = 0 ; x < cmn -> mesh_x ; x ++ ) {
532- struct arm_cmn_node * xp = cmn -> xps + xp_base + x ;
533-
534512 for (p = 0 ; p < CMN_MAX_PORTS ; p ++ )
535- port [p ][x ] = arm_cmn_device_connect_info (cmn , xp , p );
513+ port [p ][x ] = arm_cmn_device_connect_info (cmn , xp + x , p );
536514 seq_printf (s , " XP #%-3d|" , xp_base + x );
537515 }
538516
539517 seq_puts (s , "\n |" );
540518 for (x = 0 ; x < cmn -> mesh_x ; x ++ ) {
541- s8 dtc = cmn -> xps [ xp_base + x ].dtc ;
519+ s8 dtc = xp [ x ].dtc ;
542520
543521 if (dtc < 0 )
544522 seq_puts (s , " DTC ?? |" );
@@ -555,10 +533,10 @@ static int arm_cmn_map_show(struct seq_file *s, void *data)
555533 seq_puts (s , arm_cmn_device_type (port [p ][x ]));
556534 seq_puts (s , "\n 0|" );
557535 for (x = 0 ; x < cmn -> mesh_x ; x ++ )
558- arm_cmn_show_logid (s , x , y , p , 0 );
536+ arm_cmn_show_logid (s , xp + x , p , 0 );
559537 seq_puts (s , "\n 1|" );
560538 for (x = 0 ; x < cmn -> mesh_x ; x ++ )
561- arm_cmn_show_logid (s , x , y , p , 1 );
539+ arm_cmn_show_logid (s , xp + x , p , 1 );
562540 }
563541 seq_puts (s , "\n-----+" );
564542 }
@@ -1751,10 +1729,7 @@ static int arm_cmn_event_init(struct perf_event *event)
17511729 }
17521730
17531731 if (!hw -> num_dns ) {
1754- struct arm_cmn_nodeid nid = arm_cmn_nid (cmn , nodeid );
1755-
1756- dev_dbg (cmn -> dev , "invalid node 0x%x (%d,%d,%d,%d) type 0x%x\n" ,
1757- nodeid , nid .x , nid .y , nid .port , nid .dev , type );
1732+ dev_dbg (cmn -> dev , "invalid node 0x%x type 0x%x\n" , nodeid , type );
17581733 return - EINVAL ;
17591734 }
17601735
@@ -1849,7 +1824,7 @@ static int arm_cmn_event_add(struct perf_event *event, int flags)
18491824 dtm -> wp_event [wp_idx ] = hw -> dtc_idx [d ];
18501825 writel_relaxed (cfg , dtm -> base + CMN_DTM_WPn_CONFIG (wp_idx ));
18511826 } else {
1852- struct arm_cmn_nodeid nid = arm_cmn_nid (cmn , dn -> id );
1827+ struct arm_cmn_nodeid nid = arm_cmn_nid (dn );
18531828
18541829 if (cmn -> multi_dtm )
18551830 nid .port %= 2 ;
@@ -2096,10 +2071,12 @@ static int arm_cmn_init_dtcs(struct arm_cmn *cmn)
20962071 continue ;
20972072
20982073 xp = arm_cmn_node_to_xp (cmn , dn );
2074+ dn -> portid_bits = xp -> portid_bits ;
2075+ dn -> deviceid_bits = xp -> deviceid_bits ;
20992076 dn -> dtc = xp -> dtc ;
21002077 dn -> dtm = xp -> dtm ;
21012078 if (cmn -> multi_dtm )
2102- dn -> dtm += arm_cmn_nid (cmn , dn -> id ).port / 2 ;
2079+ dn -> dtm += arm_cmn_nid (dn ).port / 2 ;
21032080
21042081 if (dn -> type == CMN_TYPE_DTC ) {
21052082 int err = arm_cmn_init_dtc (cmn , dn , dtc_idx ++ );
@@ -2269,18 +2246,27 @@ static int arm_cmn_discover(struct arm_cmn *cmn, unsigned int rgn_offset)
22692246 arm_cmn_init_dtm (dtm ++ , xp , 0 );
22702247 /*
22712248 * Keeping track of connected ports will let us filter out
2272- * unnecessary XP events easily. We can also reliably infer the
2273- * "extra device ports" configuration for the node ID format
2274- * from this, since in that case we will see at least one XP
2275- * with port 2 connected, for the HN-D.
2249+ * unnecessary XP events easily, and also infer the per-XP
2250+ * part of the node ID format.
22762251 */
22772252 for (int p = 0 ; p < CMN_MAX_PORTS ; p ++ )
22782253 if (arm_cmn_device_connect_info (cmn , xp , p ))
22792254 xp_ports |= BIT (p );
22802255
2281- if (cmn -> multi_dtm && (xp_ports & 0xc ))
2256+ if (cmn -> num_xps == 1 ) {
2257+ xp -> portid_bits = 3 ;
2258+ xp -> deviceid_bits = 2 ;
2259+ } else if (xp_ports > 0x3 ) {
2260+ xp -> portid_bits = 2 ;
2261+ xp -> deviceid_bits = 1 ;
2262+ } else {
2263+ xp -> portid_bits = 1 ;
2264+ xp -> deviceid_bits = 2 ;
2265+ }
2266+
2267+ if (cmn -> multi_dtm && (xp_ports > 0x3 ))
22822268 arm_cmn_init_dtm (dtm ++ , xp , 1 );
2283- if (cmn -> multi_dtm && (xp_ports & 0x30 ))
2269+ if (cmn -> multi_dtm && (xp_ports > 0xf ))
22842270 arm_cmn_init_dtm (dtm ++ , xp , 2 );
22852271
22862272 cmn -> ports_used |= xp_ports ;
0 commit comments