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)
@@ -280,8 +272,11 @@ struct arm_cmn_node {
280272 u16 id , logid ;
281273 enum cmn_node_type type ;
282274
275+ /* XP properties really, but replicated to children for convenience */
283276 u8 dtm ;
284277 s8 dtc ;
278+ u8 portid_bits :4 ;
279+ u8 deviceid_bits :4 ;
285280 /* DN/HN-F/CXHA */
286281 struct {
287282 u8 val : 4 ;
@@ -357,49 +352,33 @@ struct arm_cmn {
357352static int arm_cmn_hp_state ;
358353
359354struct arm_cmn_nodeid {
360- u8 x ;
361- u8 y ;
362355 u8 port ;
363356 u8 dev ;
364357};
365358
366359static int arm_cmn_xyidbits (const struct arm_cmn * cmn )
367360{
368- return fls ((cmn -> mesh_x - 1 ) | (cmn -> mesh_y - 1 ) | 2 );
361+ return fls ((cmn -> mesh_x - 1 ) | (cmn -> mesh_y - 1 ));
369362}
370363
371- static struct arm_cmn_nodeid arm_cmn_nid (const struct arm_cmn * cmn , u16 id )
364+ static struct arm_cmn_nodeid arm_cmn_nid (const struct arm_cmn_node * dn )
372365{
373366 struct arm_cmn_nodeid nid ;
374367
375- if (cmn -> num_xps == 1 ) {
376- nid .x = 0 ;
377- nid .y = 0 ;
378- nid .port = CMN_NODEID_1x1_PID (id );
379- nid .dev = CMN_NODEID_DEVID (id );
380- } else {
381- int bits = arm_cmn_xyidbits (cmn );
382-
383- nid .x = CMN_NODEID_X (id , bits );
384- nid .y = CMN_NODEID_Y (id , bits );
385- if (cmn -> ports_used & 0xc ) {
386- nid .port = CMN_NODEID_EXT_PID (id );
387- nid .dev = CMN_NODEID_EXT_DEVID (id );
388- } else {
389- nid .port = CMN_NODEID_PID (id );
390- nid .dev = CMN_NODEID_DEVID (id );
391- }
392- }
368+ nid .dev = dn -> id & ((1U << dn -> deviceid_bits ) - 1 );
369+ nid .port = (dn -> id >> dn -> deviceid_bits ) & ((1U << dn -> portid_bits ) - 1 );
393370 return nid ;
394371}
395372
396373static struct arm_cmn_node * arm_cmn_node_to_xp (const struct arm_cmn * cmn ,
397374 const struct arm_cmn_node * dn )
398375{
399- struct arm_cmn_nodeid nid = arm_cmn_nid (cmn , dn -> id );
400- int xp_idx = cmn -> mesh_x * nid .y + nid .x ;
376+ int id = dn -> id >> (dn -> portid_bits + dn -> deviceid_bits );
377+ int bits = arm_cmn_xyidbits (cmn );
378+ int x = id >> bits ;
379+ int y = id & ((1U << bits ) - 1 );
401380
402- return cmn -> xps + xp_idx ;
381+ return cmn -> xps + cmn -> mesh_x * y + x ;
403382}
404383static struct arm_cmn_node * arm_cmn_node (const struct arm_cmn * cmn ,
405384 enum cmn_node_type type )
@@ -485,13 +464,13 @@ static const char *arm_cmn_device_type(u8 type)
485464 }
486465}
487466
488- static void arm_cmn_show_logid (struct seq_file * s , int x , int y , int p , int d )
467+ static void arm_cmn_show_logid (struct seq_file * s , const struct arm_cmn_node * xp , int p , int d )
489468{
490469 struct arm_cmn * cmn = s -> private ;
491470 struct arm_cmn_node * dn ;
471+ u16 id = xp -> id | d | (p << xp -> deviceid_bits );
492472
493473 for (dn = cmn -> dns ; dn -> type ; dn ++ ) {
494- struct arm_cmn_nodeid nid = arm_cmn_nid (cmn , dn -> id );
495474 int pad = dn -> logid < 10 ;
496475
497476 if (dn -> type == CMN_TYPE_XP )
@@ -500,7 +479,7 @@ static void arm_cmn_show_logid(struct seq_file *s, int x, int y, int p, int d)
500479 if (dn -> type < CMN_TYPE_HNI )
501480 continue ;
502481
503- if (nid . x != x || nid . y != y || nid . port != p || nid . dev != d )
482+ if (dn -> id != id )
504483 continue ;
505484
506485 seq_printf (s , " %*c#%-*d |" , pad + 1 , ' ' , 3 - pad , dn -> logid );
@@ -521,23 +500,22 @@ static int arm_cmn_map_show(struct seq_file *s, void *data)
521500 y = cmn -> mesh_y ;
522501 while (y -- ) {
523502 int xp_base = cmn -> mesh_x * y ;
503+ struct arm_cmn_node * xp = cmn -> xps + xp_base ;
524504 u8 port [CMN_MAX_PORTS ][CMN_MAX_DIMENSION ];
525505
526506 for (x = 0 ; x < cmn -> mesh_x ; x ++ )
527507 seq_puts (s , "--------+" );
528508
529509 seq_printf (s , "\n%-2d |" , y );
530510 for (x = 0 ; x < cmn -> mesh_x ; x ++ ) {
531- struct arm_cmn_node * xp = cmn -> xps + xp_base + x ;
532-
533511 for (p = 0 ; p < CMN_MAX_PORTS ; p ++ )
534- port [p ][x ] = arm_cmn_device_connect_info (cmn , xp , p );
512+ port [p ][x ] = arm_cmn_device_connect_info (cmn , xp + x , p );
535513 seq_printf (s , " XP #%-3d|" , xp_base + x );
536514 }
537515
538516 seq_puts (s , "\n |" );
539517 for (x = 0 ; x < cmn -> mesh_x ; x ++ ) {
540- s8 dtc = cmn -> xps [ xp_base + x ].dtc ;
518+ s8 dtc = xp [ x ].dtc ;
541519
542520 if (dtc < 0 )
543521 seq_puts (s , " DTC ?? |" );
@@ -554,10 +532,10 @@ static int arm_cmn_map_show(struct seq_file *s, void *data)
554532 seq_puts (s , arm_cmn_device_type (port [p ][x ]));
555533 seq_puts (s , "\n 0|" );
556534 for (x = 0 ; x < cmn -> mesh_x ; x ++ )
557- arm_cmn_show_logid (s , x , y , p , 0 );
535+ arm_cmn_show_logid (s , xp + x , p , 0 );
558536 seq_puts (s , "\n 1|" );
559537 for (x = 0 ; x < cmn -> mesh_x ; x ++ )
560- arm_cmn_show_logid (s , x , y , p , 1 );
538+ arm_cmn_show_logid (s , xp + x , p , 1 );
561539 }
562540 seq_puts (s , "\n-----+" );
563541 }
@@ -1815,10 +1793,7 @@ static int arm_cmn_event_init(struct perf_event *event)
18151793 }
18161794
18171795 if (!hw -> num_dns ) {
1818- struct arm_cmn_nodeid nid = arm_cmn_nid (cmn , nodeid );
1819-
1820- dev_dbg (cmn -> dev , "invalid node 0x%x (%d,%d,%d,%d) type 0x%x\n" ,
1821- nodeid , nid .x , nid .y , nid .port , nid .dev , type );
1796+ dev_dbg (cmn -> dev , "invalid node 0x%x type 0x%x\n" , nodeid , type );
18221797 return - EINVAL ;
18231798 }
18241799
@@ -1921,7 +1896,7 @@ static int arm_cmn_event_add(struct perf_event *event, int flags)
19211896 arm_cmn_claim_wp_idx (dtm , event , d , wp_idx , i );
19221897 writel_relaxed (cfg , dtm -> base + CMN_DTM_WPn_CONFIG (wp_idx ));
19231898 } else {
1924- struct arm_cmn_nodeid nid = arm_cmn_nid (cmn , dn -> id );
1899+ struct arm_cmn_nodeid nid = arm_cmn_nid (dn );
19251900
19261901 if (cmn -> multi_dtm )
19271902 nid .port %= 2 ;
@@ -2168,10 +2143,12 @@ static int arm_cmn_init_dtcs(struct arm_cmn *cmn)
21682143 continue ;
21692144
21702145 xp = arm_cmn_node_to_xp (cmn , dn );
2146+ dn -> portid_bits = xp -> portid_bits ;
2147+ dn -> deviceid_bits = xp -> deviceid_bits ;
21712148 dn -> dtc = xp -> dtc ;
21722149 dn -> dtm = xp -> dtm ;
21732150 if (cmn -> multi_dtm )
2174- dn -> dtm += arm_cmn_nid (cmn , dn -> id ).port / 2 ;
2151+ dn -> dtm += arm_cmn_nid (dn ).port / 2 ;
21752152
21762153 if (dn -> type == CMN_TYPE_DTC ) {
21772154 int err = arm_cmn_init_dtc (cmn , dn , dtc_idx ++ );
@@ -2341,18 +2318,27 @@ static int arm_cmn_discover(struct arm_cmn *cmn, unsigned int rgn_offset)
23412318 arm_cmn_init_dtm (dtm ++ , xp , 0 );
23422319 /*
23432320 * Keeping track of connected ports will let us filter out
2344- * unnecessary XP events easily. We can also reliably infer the
2345- * "extra device ports" configuration for the node ID format
2346- * from this, since in that case we will see at least one XP
2347- * with port 2 connected, for the HN-D.
2321+ * unnecessary XP events easily, and also infer the per-XP
2322+ * part of the node ID format.
23482323 */
23492324 for (int p = 0 ; p < CMN_MAX_PORTS ; p ++ )
23502325 if (arm_cmn_device_connect_info (cmn , xp , p ))
23512326 xp_ports |= BIT (p );
23522327
2353- if (cmn -> multi_dtm && (xp_ports & 0xc ))
2328+ if (cmn -> num_xps == 1 ) {
2329+ xp -> portid_bits = 3 ;
2330+ xp -> deviceid_bits = 2 ;
2331+ } else if (xp_ports > 0x3 ) {
2332+ xp -> portid_bits = 2 ;
2333+ xp -> deviceid_bits = 1 ;
2334+ } else {
2335+ xp -> portid_bits = 1 ;
2336+ xp -> deviceid_bits = 2 ;
2337+ }
2338+
2339+ if (cmn -> multi_dtm && (xp_ports > 0x3 ))
23542340 arm_cmn_init_dtm (dtm ++ , xp , 1 );
2355- if (cmn -> multi_dtm && (xp_ports & 0x30 ))
2341+ if (cmn -> multi_dtm && (xp_ports > 0xf ))
23562342 arm_cmn_init_dtm (dtm ++ , xp , 2 );
23572343
23582344 cmn -> ports_used |= xp_ports ;
0 commit comments