1 /*
2  * Arm SCP/MCP Software
3  * Copyright (c) 2020-2022, Arm Limited and Contributors. All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  *
7  * Description:
8  *     Definitions and utility functions for the CMN-700 module.
9  */
10 
11 /* The use of "manager" may not be in sync with older versions of TRM */
12 
13 #ifndef CMN700_H
14 #define CMN700_H
15 
16 #include <mod_cmn700.h>
17 
18 #include <fwk_macros.h>
19 
20 #include <stdbool.h>
21 #include <stdint.h>
22 
23 /* Max Node Counts */
24 #define MAX_HNF_COUNT 128
25 #define MAX_RND_COUNT 40
26 #define MAX_RNI_COUNT 40
27 #define MAX_RNF_COUNT 256
28 
29 /* Maximum System Cache Group regions supported by CMN-700 */
30 #define MAX_SCG_COUNT 4
31 /* Maximum Non Hash Mem Group regions supported by CMN-700 */
32 #define MAX_NON_HASH_MEM_COUNT 60
33 /* Maximum Non Hash Mem Group regions in first group */
34 #define NON_HASH_MEM_REG_COUNT 24
35 /* Maximum Non Hash Mem Group regions in second group */
36 #define NON_HASH_MEM_REG_GRP2_COUNT 40
37 
38 /* SAM Granularity of RN-SAM and HN-F SAM */
39 #define SAM_GRANULARITY (64 * FWK_MIB)
40 
41 /* External nodes that require RN-SAM mapping during run-time */
42 struct external_rnsam_tuple {
43     unsigned int node_id;
44     struct cmn700_rnsam_reg *node;
45 };
46 
47 /* Pair of CCG Request Agent (CCG_RA) register and its node-id */
48 struct ccg_ra_reg_tuple {
49     unsigned int node_id;
50     struct cmn700_ccg_ra_reg *ccg_ra_reg;
51 };
52 
53 /* Pair of CCG Request Agent (CCG_HA) register and its node-id */
54 struct ccg_ha_reg_tuple {
55     unsigned int node_id;
56     struct cmn700_ccg_ha_reg *ccg_ha_reg;
57 };
58 
59 /* Pair of CCG Link Agent (CCLA) register and its node-id */
60 struct ccla_reg_tuple {
61     unsigned int node_id;
62     struct cmn700_ccla_reg *ccla_reg;
63 };
64 
65 enum node_type {
66     NODE_TYPE_INVALID   = 0x0,
67     NODE_TYPE_DVM       = 0x1,
68     NODE_TYPE_CFG       = 0x2,
69     NODE_TYPE_DTC       = 0x3,
70     NODE_TYPE_HN_I      = 0x4,
71     NODE_TYPE_HN_F      = 0x5,
72     NODE_TYPE_XP        = 0x6,
73     NODE_TYPE_SBSX      = 0x7,
74     NODE_TYPE_MPAM_S    = 0x8,
75     NODE_TYPE_MPAM_NS   = 0x9,
76     NODE_TYPE_RN_I      = 0xA,
77     NODE_TYPE_RN_D      = 0xD,
78     NODE_TYPE_RN_SAM    = 0xF,
79     NODE_TYPE_HN_P      = 0x11,
80     /* Coherent Multichip Link (CML) node types */
81     NODE_TYPE_CML_BASE  = 0x100,
82     NODE_TYPE_CXRA      = 0x100,
83     NODE_TYPE_CXHA      = 0x101,
84     NODE_TYPE_CXLA      = 0x102,
85     NODE_TYPE_CCRA      = 0x103,
86     NODE_TYPE_CCHA      = 0x104,
87     NODE_TYPE_CCLA      = 0x105,
88 };
89 
90 enum device_type {
91     DEVICE_TYPE_RN_F_CHIB_ESAM  = 0x5, // 0b00101
92     DEVICE_TYPE_CXHA            = 0x11, // 0b10001
93     DEVICE_TYPE_CXRA            = 0x12, // 0b10010
94     DEVICE_TYPE_CXRH            = 0x13, // 0b10011
95     DEVICE_TYPE_CCG             = 0x1E, // 0b11110
96     DEVICE_TYPE_RN_F_CHID_ESAM  = 0x15, // 0b10101
97     DEVICE_TYPE_RN_F_CHIC_ESAM  = 0x17, // 0b10111
98     DEVICE_TYPE_RN_F_CHIE_ESAM  = 0x19, // 0b11001
99 };
100 
101 /* Common node header */
102 struct node_header {
103     FWK_R uint64_t NODE_INFO;
104           uint8_t  RESERVED0[0x80 - 0x8];
105     FWK_R uint64_t CHILD_INFO;
106           uint8_t  RESERVED1[0x100 - 0x88];
107     FWK_R uint64_t CHILD_POINTER[256];
108 };
109 
110 enum sam_type {
111     SAM_TYPE_NON_HASH_MEM_REGION,
112     SAM_TYPE_SYS_CACHE_GRP_REGION,
113 };
114 
115 enum sam_node_type {
116     SAM_NODE_TYPE_HN_F = 0,
117     SAM_NODE_TYPE_HN_I = 1,
118     SAM_NODE_TYPE_CXRA = 2,
119     SAM_NODE_TYPE_COUNT
120 };
121 
122 enum sam_scg_index {
123     SAM_SCG0 = 0,
124     SAM_SCG1,
125     SAM_SCG2,
126     SAM_SCG3,
127     SAM_SCG_COUNT
128 };
129 
130 /*
131  * Request Node System Address Map (RN-SAM) registers
132  */
133 struct cmn700_rnsam_reg {
134     FWK_R   uint64_t  NODE_INFO;
135             uint8_t   RESERVED0[0x80 - 0x8];
136     FWK_R   uint64_t  CHILD_INFO;
137             uint8_t   RESERVED1[0x900 - 0x88];
138     FWK_R   uint64_t  UNIT_INFO[2];
139             uint8_t   RESERVED2[0xC00 - 0x910];
140     FWK_RW  uint64_t  NON_HASH_MEM_REGION[NON_HASH_MEM_REG_COUNT];
141     FWK_RW  uint64_t  NON_HASH_MEM_REGION_CFG2[NON_HASH_MEM_REG_COUNT];
142     FWK_RW  uint64_t  NON_HASH_TGT_NODEID[16];
143     FWK_RW  uint64_t  SYS_CACHE_GRP_REGION[4];
144     FWK_RW  uint64_t  HASHED_TGT_GRP_CFG1_REGION[4];
145             uint8_t   RESERVED5[0xEA0 - 0xE40];
146     FWK_RW  uint64_t  SYS_CACHE_GRP_HN_COUNT;
147             uint8_t   RESERVED6[0xEB0 - 0xEA8];
148     FWK_RW  uint64_t  SYS_CACHE_GRP_SN_ATTR[2];
149             uint8_t   RESERVED7[0xF00 - 0xEC0];
150     FWK_RW  uint64_t  SYS_CACHE_GRP_HN_NODEID[16];
151             uint8_t   RESERVED8[0x1000 - 0xF80];
152     FWK_RW  uint64_t  SYS_CACHE_GRP_SN_NODEID[32];
153     FWK_RW  uint64_t  STATUS;
154             uint64_t  GIC_MEM_REGION;
155             uint8_t   RESERVED9[0x1120 - 0x1110];
156     FWK_RW  uint64_t  SYS_CACHE_GRP_CAL_MODE;
157     FWK_RW  uint64_t  HASHED_TARGET_GRP_CAL_MODE[3];
158     FWK_RW  uint64_t  SYS_CACHE_GRP_SN_SAM_CFG[4];
159             uint8_t   RESERVED10[0x20C0 - 0x1160];
160     FWK_RW  uint64_t  NON_HASH_MEM_REGION_GRP2[NON_HASH_MEM_REG_GRP2_COUNT];
161             uint8_t   RESERVED11[0x24C0 - 0x2200];
162     FWK_RW  uint64_t  NON_HASH_MEM_REGION_CFG2_GRP2[NON_HASH_MEM_REG_GRP2_COUNT];
163             uint8_t   RESERVED12[0x3100 - 0x2600];
164     FWK_RW  uint64_t  HASHED_TGT_GRP_CFG2_REGION[32];
165             uint8_t   RESERVED13[0x3400 - 0x3200];
166     FWK_RW  uint64_t  HASHED_TARGET_GRP_HASH_CNTL[32];
167 };
168 
169 #define HNF_RN_CLUSTER_MAX    128
170 #define HNF_RN_PHYIDS_REG_MAX 4
171 
172 /*
173  * Fully Coherent Home Node (HN-F) registers
174  */
175 struct cmn700_hnf_reg {
176     FWK_R   uint64_t  NODE_INFO;
177             uint8_t   RESERVED0[0x80 - 0x8];
178     FWK_R   uint64_t  CHILD_INFO;
179             uint8_t   RESERVED1[0x900 - 0x88];
180     FWK_R   uint64_t  UNIT_INFO[2];
181             uint8_t   RESERVED2[0xD00 - 0x910];
182     FWK_RW  uint64_t  SAM_CONTROL;
183     FWK_RW  uint64_t  SAM_MEMREGION[2];
184             uint8_t   RESERVED3[0xD28 - 0xD18];
185     FWK_RW  uint64_t  SAM_CONTROL_2;
186             uint8_t   RESERVED4[0xD38 - 0xD30];
187     FWK_RW  uint64_t  SAM_MEMREGION_END_ADDR[2];
188             uint8_t   RESERVED5[0x1C00 - 0xD48];
189     FWK_RW  uint64_t  PPU_PWPR;
190             uint8_t   RESERVED6[0x3C00 - 0x1C08];
191     FWK_RW  uint64_t
192         HNF_RN_CLUSTER_PHYSID[HNF_RN_CLUSTER_MAX][HNF_RN_PHYIDS_REG_MAX];
193 };
194 
195 /*
196  * CCG Gateway (CCG) protocol link control & status registers
197  */
198 struct ccg_link_regs {
199     FWK_RW uint64_t CCG_CCPRTCL_LINK_CTRL;
200     FWK_R uint64_t CCG_CCPRTCL_LINK_STATUS;
201 };
202 
203 /*
204  * CCG Requesting Agent (RA) registers
205  */
206 struct cmn700_ccg_ra_reg {
207     FWK_R  uint64_t CCG_RA_NODE_INFO;
208            uint8_t  RESERVED0[0x80 - 0x8];
209     FWK_R  uint64_t CCG_RA_CHILD_INFO;
210            uint8_t  RESERVED1[0x900 - 0x88];
211     FWK_R  uint64_t CCG_RA_UNIT_INFO;
212            uint8_t  RESERVED2[0x980 - 0x908];
213     FWK_RW uint64_t CCG_RA_SEC_REG_GRP_OVERRIDE;
214            uint8_t  RESERVED3[0xA00 - 0x988];
215     FWK_RW uint64_t CCG_RA_CFG_CTRL;
216     FWK_RW uint64_t CCG_RA_AUX_CTRL;
217            uint8_t  RESERVED4[0xC00 - 0xA10];
218     FWK_RW uint64_t CCG_RA_SAM_ADDR_REGION_REG[8];
219            uint8_t  RESERVED5[0xD00 - 0xC40];
220     FWK_RW uint64_t CCG_RA_AGENTID_TO_LINKID_VAL;
221            uint8_t  RESERVED6[0xD10 - 0xD08];
222     FWK_RW uint64_t CCG_RA_AGENTID_TO_LINKID_REG[8];
223            uint8_t  RESERVED7[0xE00 - 0xD50];
224     FWK_RW uint64_t CCG_RA_RNI_LDID_TO_EXP_RAID_REG[10];
225            uint8_t  RESERVED8[0xF00 - 0xE50];
226     FWK_RW uint64_t CCG_RA_RND_LDID_TO_EXP_RAID_REG[10];
227            uint8_t  RESERVED9[0x1000 - 0xF50];
228     FWK_RW uint64_t CCG_RA_RNF_LDID_TO_EXP_RAID_REG[128];
229     FWK_RW uint64_t CCG_RA_RNF_LDID_TO_NODEID_REG[128];
230     FWK_RW uint64_t CCG_RA_RNF_LDID_TO_OVRD_LDID_REG[128];
231            struct ccg_link_regs LINK_REGS[3];
232            uint8_t  RESERVED10[0x2000 - 0x1C30];
233     FWK_RW uint64_t CCG_RA_PMU_EVENT_SEL;
234 };
235 
236 /*
237  * CCG Gateway (CCG) Home Agent (HA) registers
238  */
239 struct cmn700_ccg_ha_reg {
240     FWK_R  uint64_t CCG_HA_NODE_INFO;
241     FWK_RW uint64_t CCG_HA_ID;
242            uint8_t  RESERVED0[0x80 - 0x10];
243     FWK_R  uint64_t CCG_HA_CHILD_INFO;
244            uint8_t  RESERVED1[0x900 - 0x88];
245     FWK_R  uint64_t CCG_HA_UNIT_INFO[2];
246            uint8_t  RESERVED2[0x980 - 0x910];
247     FWK_RW uint64_t CCG_HA_SEC_REG_GRP_OVERRIDE;
248            uint8_t  RESERVED3[0xA00 - 0x988];
249     FWK_RW uint64_t CCG_HA_CFG_CTRL;
250     FWK_RW uint64_t CCG_HA_AUX_CTRL;
251            uint8_t  RESERVED4[0xC00 - 0xA10];
252     FWK_RW uint64_t CCG_HA_RNF_EXP_RAID_TO_LDID_REG[256];
253            uint8_t  RESERVED5[0x1C00 - 0x1400];
254            struct ccg_link_regs LINK_REGS[3];
255            uint8_t  RESERVED6[0x1F00 - 0x1C30];
256     FWK_RW uint64_t CCG_HA_AGENTID_TO_LINKID_REG[8];
257            uint8_t  RESERVED7[0x1FF8 - 0x1F40];
258     FWK_RW uint64_t CCG_HA_AGENTID_TO_LINKID_VAL;
259     FWK_RW uint64_t CCG_HA_PMU_EVENT_SEL;
260 };
261 
262 /*
263  * CCG Gateway (CCG) Link Agent (LA) registers
264  */
265 struct cmn700_ccla_reg {
266     FWK_R  uint64_t CCLA_NODE_INFO;
267            uint8_t  RESERVED0[0x80 - 0x8];
268     FWK_R  uint64_t CCLA_CHILD_INFO;
269            uint8_t  RESERVED1[0x910 - 0x88];
270     FWK_R  uint64_t CCLA_UNIT_INFO;
271            uint8_t  RESERVED2[0x988 - 0x918];
272     FWK_RW uint64_t CCLA_SEC_REG_GRP_OVERRIDE;
273            uint8_t  RESERVED3[0xB00 - 0x990];
274     FWK_RW uint64_t CCLA_CFG_CTL;
275     FWK_RW uint64_t CCLA_AUX_CTRL;
276            uint8_t  RESERVED4[0xC00 - 0xB10];
277     FWK_R  uint64_t CCLA_CCIX_PROP_CAPABILITIES;
278     FWK_RW uint64_t CCLA_CXS_ATTR_CAPABILITIES;
279            uint8_t  RESERVED5[0xD00 - 0xC10];
280     FWK_RW uint64_t CCLA_PERMSG_PYLD_0_63;
281     FWK_RW uint64_t CCLA_PERMSG_PYLD_64_127;
282     FWK_RW uint64_t CCLA_PERMSG_PYLD_128_191;
283     FWK_RW uint64_t CCLA_PERMSG_PYLD_192_255;
284     FWK_RW uint64_t CCLA_PERMSG_CTL;
285     FWK_RW uint64_t CCLA_ERR_AGENT_ID;
286     FWK_RW uint64_t CCLA_AGENTID_TO_PORTID_REG[8];
287     FWK_RW uint64_t CCLA_AGENTID_TO_PORTID_VAL;
288            uint8_t  RESERVED6[0xE00 - 0xD88];
289     FWK_RW uint64_t CCLA_PORTFWD_CTL;
290     FWK_R  uint64_t CCLA_PORTFWD_STATUS;
291     FWK_RW uint64_t CCLA_CXL_LINK_RX_CREDIT_CTL;
292     FWK_R  uint64_t CCLA_CXL_LINK_RX_CREDIT_RETURN_STAT;
293     FWK_R  uint64_t CCLA_CXL_LINK_TX_CREDIT_STAT;
294     FWK_RW uint64_t CCLA_CXL_LINK_LAYER_DEFEATURE;
295     FWK_RW uint64_t CCLA_ULL_CTL;
296     FWK_R  uint64_t CCLA_ULL_STATUS;
297     FWK_RW uint64_t CCLA_CXL_LL_ERRINJECT_CTL;
298     FWK_R  uint64_t CCLA_CXL_LL_ERRINJECT_STAT;
299            uint8_t  RESERVED7[0x2008 - 0xE40];
300     FWK_RW uint64_t CCLA_PMU_EVENT_SEL;
301            uint8_t  RESERVED8[0x3000 - 0x2010];
302     FWK_R  uint64_t CCLA_ERRFR;
303     FWK_RW uint64_t CCLA_ERRCTLR;
304     FWK_W  uint64_t CCLA_ERRSTATUS;
305     FWK_RW uint64_t CCLA_ERRADDR;
306     FWK_RW uint64_t CCLA_ERRMISC;
307            uint8_t  RESERVED9[0x3100 - 0x3028];
308     FWK_R  uint64_t CCLA_ERRFR_NS;
309     FWK_RW uint64_t CCLA_ERRCTLR_NS;
310     FWK_W  uint64_t CCLA_ERRSTATUS_NS;
311     FWK_RW uint64_t CCLA_ERRADDR_NS;
312     FWK_RW uint64_t CCLA_ERRMISC_NS;
313 };
314 
315 /*
316  * Configuration manager registers
317  */
318 struct cmn700_cfgm_reg {
319     FWK_R   uint64_t  NODE_INFO;
320     FWK_RW  uint64_t  PERIPH_ID[4];
321     FWK_RW  uint64_t  COMPONENT_ID[2];
322             uint8_t   RESERVED0[0x80 - 0x38];
323     FWK_R   uint64_t  CHILD_INFO;
324 };
325 
326 /*
327  * Crosspoint (XP) registers
328  */
329 struct cmn700_mxp_reg {
330     FWK_R  uint64_t  NODE_INFO;
331     FWK_R  uint64_t  PORT_CONNECT_INFO[6];
332     FWK_R  uint64_t  PORT_CONNECT_INFO_EAST;
333     FWK_R  uint64_t  PORT_CONNECT_INFO_NORTH;
334            uint8_t   RESERVED0[0x80 - 0x28];
335     FWK_R  uint64_t  CHILD_INFO;
336            uint8_t   RESERVED1[0x100 - 0x88];
337     FWK_R  uint64_t  CHILD_POINTER[32];
338 };
339 
340 #define CMN700_NODE_INFO_TYPE           UINT64_C(0x000000000000FFFF)
341 #define CMN700_NODE_INFO_ID             UINT64_C(0x00000000FFFF0000)
342 #define CMN700_NODE_INFO_ID_POS         16
343 #define CMN700_NODE_INFO_LOGICAL_ID     UINT64_C(0x0000FFFF00000000)
344 #define CMN700_NODE_INFO_LOGICAL_ID_POS 32
345 
346 #define CMN700_CHILD_INFO_COUNT     UINT64_C(0x000000000000FFFF)
347 #define CMN700_CHILD_POINTER_OFFSET UINT64_C(0x000000003FFFFFFF)
348 #define CMN700_CHILD_POINTER_EXT    UINT64_C(0x0000000080000000)
349 
350 /* External child node */
351 #define CMN700_CHILD_POINTER_EXT_REGISTER_OFFSET  UINT64_C(0x00003FFF)
352 #define CMN700_CHILD_POINTER_EXT_NODE_POINTER     UINT64_C(0x3FFF0000)
353 #define CMN700_CHILD_POINTER_EXT_NODE_POINTER_POS 16
354 
355 #define CMN700_RNSAM_UNIT_INFO_HTG_RCOMP_LSB_PARAM_MASK     UINT64_C(0x1F)
356 #define CMN700_RNSAM_UNIT_INFO_HTG_RANGE_COMP_EN_MASK       UINT64_C(0x8000000)
357 #define CMN700_RNSAM_UNIT_INFO_HTG_RANGE_COMP_EN_POS        27
358 #define CMN700_RNSAM_UNIT_INFO_NONHASH_RCOMP_LSB_PARAM_MASK UINT64_C(0x3E0)
359 #define CMN700_RNSAM_UNIT_INFO_NONHASH_RCOMP_LSB_PARAM_POS  5
360 #define CMN700_RNSAM_UNIT_INFO_NONHASH_RANGE_COMP_EN_MASK   UINT64_C(0x80000000)
361 #define CMN700_RNSAM_UNIT_INFO_NONHASH_RANGE_COMP_EN_POS    31
362 
363 /* Used by NON_HASH_MEM_REGIONx and SYS_CACHE_GRP_REGIONx group registers */
364 #define CMN700_RNSAM_REGION_ENTRY_TYPE_POS                     2
365 #define CMN700_RNSAM_REGION_ENTRY_SIZE_POS                     56
366 #define CMN700_RNSAM_REGION_ENTRY_BASE_POS                     26
367 #define CMN700_RNSAM_REGION_ENTRY_BITS_WIDTH                   64
368 #define CMN700_RNSAM_REGION_ENTRY_VALID                        UINT64_C(0x01)
369 #define CMN700_RNSAM_REGION_ENTRIES_PER_GROUP                  1
370 #define CMN700_RNSAM_SYS_CACHE_GRP_SN_NODEID_ENTRIES_PER_GROUP 4
371 #define CMN700_RNSAM_SYS_CACHE_GRP_HN_CNT_POS(scg_grp)         (8 * (scg_grp))
372 #define CMN700_RNSAM_SCG_HNF_CAL_MODE_EN                       UINT64_C(0x01)
373 #define CMN700_RNSAM_SCG_HNF_CAL_MODE_SHIFT                    16
374 #define CMN700_RNSAM_STATUS_UNSTALL                            UINT64_C(0x02)
375 #define CMN700_RNSAM_STATUS_USE_DEFAULT_TARGET_ID              UINT64_C(0x01)
376 #define CMN700_RNSAM_STATUS_DEFAULT_NODEID_POS                 48
377 #define CMN700_RNSAM_NON_HASH_TGT_NODEID_ENTRY_BITS_WIDTH      12
378 #define CMN700_RNSAM_NON_HASH_TGT_NODEID_ENTRY_MASK            UINT64_C(0x0FFF)
379 #define CMN700_RNSAM_NON_HASH_TGT_NODEID_ENTRIES_PER_GROUP     4
380 
381 /* Used by RNSAM Hierarchical hashing registers */
382 #define CMN700_RNSAM_HIERARCHICAL_HASH_EN_POS         2
383 #define CMN700_RNSAM_HIERARCHICAL_HASH_EN_MASK        UINT64_C(0x01)
384 #define CMN700_RNSAM_HIER_ENABLE_ADDRESS_STRIPING_POS 3
385 #define CMN700_RNSAM_HIER_HASH_CLUSTERS_POS           8
386 #define CMN700_RNSAM_HIER_HASH_NODES_POS              16
387 #define CMN700_RNSAM_SN_MODE_SYS_CACHE_POS(scg_grp)   ((4 + ((scg_grp)*16)) % 64)
388 #define CMN700_RNSAM_TOP_ADDRESS_BIT0_POS(scg_grp)    ((0 + ((scg_grp)*24)) % 64)
389 #define CMN700_RNSAM_TOP_ADDRESS_BIT1_POS(scg_grp)    ((8 + ((scg_grp)*24)) % 64)
390 #define CMN700_RNSAM_TOP_ADDRESS_BIT2_POS(scg_grp)    ((16 + ((scg_grp)*24)) % 64)
391 
392 #define CMN700_RNSAM_SYS_CACHE_GRP_SN_ATTR_ENTRIES_PER_GRP    4
393 #define CMN700_RNSAM_SYS_CACHE_GRP_SN_SAM_CFG_ENTRIES_PER_GRP 2
394 
395 #define CMN700_HNF_UNIT_INFO_HNSAM_RCOMP_EN_MASK 0x10000000
396 #define CMN700_HNF_UNIT_INFO_HNSAM_RCOMP_EN_POS  28
397 #define CMN700_HNF_SAM_MEMREGION_SIZE_POS        12
398 #define CMN700_HNF_SAM_MEMREGION_BASE_POS        26
399 #define CMN700_HNF_SAM_MEMREGION_VALID           UINT64_C(0x8000000000000000)
400 
401 /* Used by HN-F SAM_CONTROL register */
402 #define CMN700_HNF_SAM_CONTROL_SN_MODE_POS(sn_mode)   (36 + sn_mode - 1)
403 #define CMN700_HNF_SAM_CONTROL_TOP_ADDR_BIT0_POS      40
404 #define CMN700_HNF_SAM_CONTROL_TOP_ADDR_BIT1_POS      48
405 #define CMN700_HNF_SAM_CONTROL_TOP_ADDR_BIT2_POS      56
406 #define CMN700_HNF_SAM_CONTROL_SN_NODE_ID_POS(sn_idx) (sn_idx * 12)
407 
408 #define CMN700_HNF_CACHE_GROUP_ENTRIES_MAX       128
409 #define CMN700_HNF_CACHE_GROUP_ENTRIES_PER_GROUP 4
410 #define CMN700_HNF_CACHE_GROUP_ENTRY_BITS_WIDTH  12
411 
412 #define CMN700_PPU_PWPR_POLICY_OFF      UINT64_C(0x0000000000000000)
413 #define CMN700_PPU_PWPR_POLICY_MEM_RET  UINT64_C(0x0000000000000002)
414 #define CMN700_PPU_PWPR_POLICY_FUNC_RET UINT64_C(0x0000000000000007)
415 #define CMN700_PPU_PWPR_POLICY_ON       UINT64_C(0x0000000000000008)
416 #define CMN700_PPU_PWPR_OPMODE_NOSFSLC  UINT64_C(0x0000000000000000)
417 #define CMN700_PPU_PWPR_OPMODE_SFONLY   UINT64_C(0x0000000000000010)
418 #define CMN700_PPU_PWPR_OPMODE_HAM      UINT64_C(0x0000000000000020)
419 #define CMN700_PPU_PWPR_OPMODE_FAM      UINT64_C(0x0000000000000030)
420 #define CMN700_PPU_PWPR_DYN_EN          UINT64_C(0x0000000000000100)
421 
422 /* Mesh and Node ID mapping */
423 #define CMN700_MESH_X_MAX 12
424 #define CMN700_MESH_Y_MAX 12
425 
426 #define CMN700_NODE_ID_PORT_POS  2
427 #define CMN700_NODE_ID_PORT_MASK 0x1
428 #define CMN700_NODE_ID_Y_POS     3
429 
430 /* For XP with 3 or 4 ports */
431 #define CMN700_MULTI_PORTS_NODE_ID_PORT_POS  1
432 #define CMN700_MULTI_PORTS_NODE_ID_PORT_MASK 0x3
433 
434 #define CMN700_MXP_NODE_INFO_NUM_DEVICE_PORT_MASK UINT64_C(0xF000000000000)
435 #define CMN700_MXP_NODE_INFO_NUM_DEVICE_PORT_POS  48
436 
437 #define CMN700_MXP_PORT_CONNECT_INFO_CAL_CONNECTED_MASK UINT64_C(0x80)
438 #define CMN700_MXP_PORT_CONNECT_INFO_CAL_CONNECTED_POS  7
439 #define CMN700_MXP_PORT_CONNECT_INFO_DEVICE_TYPE_MASK   UINT64_C(0x1F)
440 
441 #define CMN700_ROOT_NODE_OFFSET_PORT_POS     16
442 #define CMN700_ROOT_NODE_4_BIT_ENCODING_MASK 0x30
443 #define CMN700_ROOT_NODE_OFFSET_Y_POS        22
444 
445 /* Peripheral ID Revision Numbers */
446 #define CMN700_PERIPH_ID_2_REV_R0_P0 (0x00)
447 #define CMN700_PERIPH_ID_2_REV_R1_P0 (0x01)
448 #define CMN700_PERIPH_ID_2_REV_R1_P1 (0x02)
449 #define CMN700_PERIPH_ID_2_REV_R2_P0 (0x03)
450 #define CMN700_PERIPH_ID_UNKNOWN_REV (CMN700_PERIPH_ID_2_REV_R2_P0 + 1)
451 
452 /* Peripheral ID Revision Numbers */
453 #define CMN700_PERIPH_ID_2_MASK    UINT64_C(0xFF)
454 #define CMN700_PERIPH_ID_2_REV_POS 4
455 
456 /*
457  * Retrieve the number of device ports connected to the cross point
458  *
459  * \param xp_base Pointer to the cross point (xp)
460  *      \pre The xp pointer must be valid
461  *
462  * \return Number of device ports connected to the cross point
463  */
464 unsigned int get_node_device_port_count(void *xp_base);
465 
466 /*
467  * Retrieve the number of child nodes of a given node
468  *
469  * \param node_base Pointer to the node descriptor
470  *      \pre The node pointer must be valid
471  *
472  * \return Number of child nodes
473  */
474 unsigned int get_node_child_count(void *node_base);
475 
476 /*
477  * Retrieve node type identifier
478  *
479  * \param node_base Pointer to the node descriptor
480  *      \pre The node pointer must be valid
481  *
482  * \return Node's type identifier
483  */
484 enum node_type get_node_type(void *node_base);
485 
486 /*
487  * Retrieve the physical identifier of a node from its hardware node descriptor.
488  * This identifier encodes the node's position in the mesh.
489  *
490  * Note: Multiple node descriptors can share the same identifier if they are
491  * related to the same device node in the mesh.
492  *
493  * \param node_base Pointer to the node descriptor
494  *      \pre The node pointer must be valid
495  *
496  * \return Node's physical identifier
497  */
498 unsigned int get_node_id(void *node_base);
499 
500 /*
501  * Retrieve the logical identifier of a node from its hardware node descriptor.
502  * This is an unique identifier (index) among nodes of the same type in the
503  * system.
504  *
505  * \param node_base Pointer to the node base address
506  *      \pre The node pointer must be valid
507  *
508  * \return An integer representing the node's logical identifier
509  */
510 unsigned int get_node_logical_id(void *node_base);
511 
512 /*
513  * Retrieve a child node given a node and child index
514  *
515  * \param node_base Pointer to the node descriptor
516  *      \pre The node pointer must be valid
517  * \param child_index Child index
518  *      \pre The child index must be valid
519  *
520  * \return Pointer to the child's node descriptor
521  */
522 void *get_child_node(uintptr_t base, void *node_base, unsigned int child_index);
523 
524 /*
525  * Retrieve the physical identifier of a node using its child pointer in the
526  * parent's node hardware descriptor
527  *
528  * This function is used to extract a node's identifier without accessing the
529  * node descriptor. This is specially useful for external nodes that are in an
530  * unavailable power or clock domain.
531  *
532  * \param node_base Pointer to the parent node descriptor
533  *      \pre The node pointer must be valid
534  * \param child_index Child index
535  *      \pre The child index must be valid
536  *
537  * \return Physical child node identifier
538  */
539 unsigned int get_child_node_id(void *node_base, unsigned int child_index);
540 
541 /*
542  * Retrieve the revision name of CMN-700.
543  *
544  * \param root Pointer to the CMN-700 configuration master register base.
545  *
546  * \return Pointer to the CMN-700 revision name string.
547  */
548 const char *get_cmn700_revision_name(struct cmn700_cfgm_reg *root);
549 
550 /*
551  * Verify if a child node (given a parent node base and child index) is an
552  * external node from the CMN-700 instance point of view.
553  *
554  * \param node_base Pointer to the parent node descriptor
555  *      \pre The node pointer must be valid
556  * \param child_index Child index
557  *      \pre The child index must be valid
558  *
559  * \retval true if the node is external
560  * \retval false if the node is internal
561  */
562 bool is_child_external(void *node_base, unsigned int child_index);
563 
564 /*
565  * Returns the port number from the child node id.
566  *
567  * \param child_node_id Child node id calculated from the child pointer.
568  * \param xp_port_cnt Number of ports in the XP.
569  *
570  * \retval port number
571  */
572 unsigned int get_port_number(
573     unsigned int child_node_id,
574     unsigned int xp_port_cnt);
575 
576 /*
577  * Returns the device type from the MXP's port connect info register.
578  *
579  * \param mxp_base Pointer to the cross point node descriptor
580  *      \pre The cross point node pointer must be valid
581  * \param port Port number
582  *      \pre The port number should be either 0, 1 or 2.
583  *
584  * \retval device type (por_mxp_por_mxp_device_port_connect_info_p[port] & 0x1F)
585  */
586 unsigned int get_device_type(void *mxp_base, int port);
587 
588 /*
589  * Verify if the MXP port has CAL connected to it.
590  *
591  * \param mxp_base Pointer to the cross point node descriptor
592  *      \pre The cross point node pointer must be valid
593  * \param port Port number
594  *      \pre The port number should be either 0 or 1.
595  *
596  * \retval true if CAL is connected to \param port
597  * \retval false if CAL is non connected to \param port
598  */
599 bool is_cal_connected(void *mxp_base, bool port);
600 
601 /*
602  * Verify if the device type connected to the MXP's port is of one of the RN-F
603  * type.
604  *
605  * \param mxp_base Pointer to the cross point node descriptor
606  *      \pre The cross point node pointer must be valid
607  * \param port Port number
608  *      \pre The port number should be either 0 or 1.
609  *
610  * \retval true if the device connected to \param port is one of the RN-F types
611  * \retval false if the device connected to \param port not an RN-F type
612  */
613 bool is_device_type_rnf(void *mxp_base, bool port);
614 
615 /*
616  * Returns if the rnsam nonhash memory region programming requires start and end
617  * address programming
618  *
619  * \param rnsam_reg Pointer to the RNSAM register
620  *      \pre RNSAM register pointer must be valid
621  *
622  * \retval true if rnsam non-hashed memory region requires start and end address
623  * programing
624  * \retval false if rnsam non-hashed memory region requires start and region
625  * size programming
626  */
627 bool get_rnsam_nonhash_range_comp_en_mode(void *rnsam_reg);
628 
629 /*
630  * Returns if the rnsam hashed target memory region programming requires start
631  * and end address programming
632  *
633  * \param rnsam_reg Pointer to the RNSAM register
634  *      \pre RNSAM register pointer must be valid
635  *
636  * \retval true if rnsam hashed target memory region requires start and end
637  * address programing
638  * \retval false if rnsam hashed target memory region requires start and region
639  * size programming
640  */
641 bool get_rnsam_htg_range_comp_en_mode(void *rnsam_reg);
642 
643 /*
644  * Returns if the hnsam memory region programming requires start and end address
645  * programming
646  *
647  * \param hnf_reg Pointer to the HN-F register
648  *      \pre HN-F register pointer must be valid
649  *
650  * \retval true if hnsam memory region requires start and end address programing
651  * \retval false if hnsam memory region requires start and region size
652  * programming
653  */
654 bool get_hnsam_range_comp_en_mode(void *hnf_reg);
655 
656 /*
657  * Convert a memory region size into a size format used by the CMN-700
658  * registers. The format is the binary logarithm of the memory region size
659  * represented as blocks multiple of the CMN-700's granularity:
660  * n =  log2(size / SAM_GRANULARITY)
661  *
662  * \param size Memory region size to be converted
663  *      \pre size must be a multiple of SAM_GRANULARITY
664  *
665  * \return log2(size / SAM_GRANULARITY)
666  */
667 uint64_t sam_encode_region_size(uint64_t size);
668 
669 /*
670  * Configure a NON-HASH or SYS-CACHE memory region
671  *
672  * \param reg Pointer to the RNSAM register
673  * \param region_idx Index of the memory region
674  * \param base Region base address
675  * \param size Region size
676  * \param node_type Type of the target node
677  * \param sam_type Type of the region register to program (NON-HASH or
678  * SYS-CACHE)
679  *
680  * \return None
681  */
682 void configure_region(
683     void *rnsam_reg,
684     unsigned int region_idx,
685     uint64_t base,
686     uint64_t size,
687     enum sam_node_type node_type,
688     enum sam_type sam_type);
689 
690 /*
691  * Retrieve the node type name
692  *
693  * \param node_type Node type
694  *
695  * \return Pointer to the node type name string
696  */
697 const char *get_node_type_name(enum node_type node_type);
698 
699 /*
700  * Retrieve the node's position in the mesh along the X-axis
701  *
702  * \param node_base Pointer to the node descriptor
703  *
704  * \return Zero-indexed position along the X-axis
705  */
706 unsigned int get_node_pos_x(void *node_base);
707 
708 /*
709  * Retrieve the node's position in the mesh along the Y-axis
710  *
711  * \param node_base Pointer to the node descriptor
712  *
713  * \return Zero-indexed position along the Y-axis
714  */
715 unsigned int get_node_pos_y(void *node_base);
716 
717 /*
718  * Set encoding and masking bits based on the mesh size. These are used while
719  * calculating the x and y pos based on the node_id.
720  *
721  * \param config Config data of this module.
722  *
723  * \return None
724  */
725 void set_encoding_and_masking_bits(const struct mod_cmn700_config *config);
726 
727 #endif /* CMN700_H */
728