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 
8 #ifndef MOD_CMN700_H
9 #define MOD_CMN700_H
10 
11 #include <fwk_id.h>
12 
13 #include <stdbool.h>
14 #include <stddef.h>
15 #include <stdint.h>
16 
17 /*!
18  * \addtogroup GroupModules Modules
19  * @{
20  */
21 
22 /*!
23  * \defgroup GroupModuleCMN700 CMN700
24  *
25  * \brief Arm Coherent Mesh Network (CMN) 700 module
26  *
27  * \details This module adds support for the CMN700 interconnect
28  * @{
29  */
30 
31 /*! Maximum CCG Protocol Links supported */
32 #define CMN700_MAX_CCG_PROTOCOL_LINKS 3
33 
34 /*! Maximum RA SAM Address regions */
35 #define CMN700_MAX_RA_SAM_ADDR_REGION 8
36 
37 /*!
38  * \brief Memory region configuration type
39  */
40 enum mod_cmn700_mem_region_type {
41     /*! Input/Output region (serviced by dedicated HN-I and HN-D nodes) */
42     MOD_CMN700_MEM_REGION_TYPE_IO,
43 
44     /*!
45      * Region backed by the system cache (serviced by all HN-F nodes in the
46      * system)
47      */
48     MOD_CMN700_MEM_REGION_TYPE_SYSCACHE,
49 
50     /*!
51      * Sub region of the system cache for non-hashed access (serviced by
52      * dedicated SN-F nodes).
53      */
54     MOD_CMN700_REGION_TYPE_SYSCACHE_SUB,
55 
56     /*!
57      * Region used for CCG access (serviced by the CCRA nodes).
58      */
59     MOD_CMN700_REGION_TYPE_CCG,
60 };
61 
62 /*!
63  * \brief Coordinate (x, y, port no) of a node in the mesh
64  */
65 struct node_pos {
66     /*! x position of the node in the mesh */
67     unsigned int pos_x;
68 
69     /*! y position of the node in the mesh */
70     unsigned int pos_y;
71 
72     /*! port position of the node in the xp */
73     unsigned int port_num;
74 };
75 
76 /*!
77  * \brief Memory region map descriptor
78  */
79 struct mod_cmn700_mem_region_map {
80     /*! Base address */
81     uint64_t base;
82 
83     /*! Region size in bytes */
84     uint64_t size;
85 
86     /*! Region configuration type */
87     enum mod_cmn700_mem_region_type type;
88 
89     /*!
90      * \brief Target node identifier
91      *
92      * \note Not used for \ref
93      * mod_cmn700_mem_region_type.MOD_CMN700_REGION_TYPE_SYSCACHE_SUB
94      * memory regions as it uses the pool of HN-F nodes available in the
95      * system
96      */
97     unsigned int node_id;
98 
99     /*!
100      * \brief HN-F start and end positions of a SCG/HTG
101      *
102      * \details Each SCG/HTG covers an address range and this address range can
103      * be made to target a group of HN-Fs. These group of HN-Fs are typically
104      * bound by an arbitrary rectangle/square in the mesh. To aid automatic
105      * programming of the HN-Fs in SCG/HTG along with the discovery process,
106      * each SCG/HTG takes hnf_pos_start and hnf_pos_end. HN-F nodes which are
107      * bounded by this range will be assigned to the respective SCG/HTG. This
108      * eliminates the process of manually looking at the mesh and assigning the
109      * HN-F node ids to a SCG/HTG.
110      *
111      *                                        hnf_pos_end
112      *                                             xx
113      *                                            xx
114      *                                           xx
115      *                    ┌─────────────────────xx
116      *                    │                     │
117      *                    │                     │
118      *                    │                     │
119      *                    │                     │
120      *                    │    nth- SCG/HTG121      *                    │                     │
122      *                    │                     │
123      *                    │                     │
124      *                    │                     │
125      *                   xx─────────────────────┘
126      *                  xx
127      *                 xx
128      *                xx
129      *         hnf_pos_start
130      */
131 
132     /*!
133      * \brief HN-F's bottom left node position
134      *
135      * \details \ref hnf_pos_start is the HN-F's bottom left node position in
136      * the rectangle covering the HN-Fs for a SCG/HTG
137      *
138      * \note To be used only with \ref
139      * mod_cmn700_mem_region_type.MOD_CMN700_MEM_REGION_TYPE_SYSCACHE memory
140      * regions.
141      */
142     struct node_pos hnf_pos_start;
143 
144     /*!
145      * \brief HN-F's top right node position
146      *
147      * \details \ref hnf_pos_start is the HN-F's bottom left node position in
148      * the rectangle covering the HN-Fs for a SCG/HTG
149      *
150      * \note To be used only with \ref
151      * mod_cmn700_mem_region_type.MOD_CMN700_MEM_REGION_TYPE_SYSCACHE memory
152      * regions.
153      */
154     struct node_pos hnf_pos_end;
155 };
156 
157 /*!
158  * \brief HN-F to SN-F memory striping modes
159  */
160 enum mod_cmn700_hnf_to_snf_mem_strip_mode {
161     MOD_CMN700_1_SN_MODE,
162     MOD_CMN700_3_SN_MODE,
163     MOD_CMN700_6_SN_MODE,
164     MOD_CMN700_5_SN_MODE,
165 };
166 
167 /*!
168  * \brief Hierarchical hashing configuration
169  */
170 struct mod_cmn700_hierarchical_hashing {
171     /*!
172      * \brief Number of HN-Fs per cluster.
173      *
174      * \note The value should not account for \ref
175      * mod_cmn700_config.hnf_cal_mode
176      */
177     unsigned int hnf_cluster_count;
178 
179     /*!
180      * \brief HN-F to SN-F hashing mode.
181      */
182     enum mod_cmn700_hnf_to_snf_mem_strip_mode sn_mode;
183 
184     /*!
185      * \brief Top PA address bit 0 to use for striping
186      *
187      * \note top_address_bit0 should match with the value in HN-F to SN-F strip
188      * setting
189      */
190     unsigned int top_address_bit0;
191 
192     /*!
193      * \brief Top PA address bit 1 to use for striping
194      *
195      * \note top_address_bit1 should match with the value in HN-F to SN-F strip
196      * setting
197      */
198     unsigned int top_address_bit1;
199 
200     /*!
201      * \brief Top PA address bit 2 to use for striping
202      *
203      * \note top_address_bit2 should match with the value in HN-F to SN-F strip
204      * setting
205      */
206     unsigned int top_address_bit2;
207 };
208 
209 /*!
210  * \brief Remote Agent to Link ID mapping
211  *
212  * \details Each CCG nodes can communicate up to three remote CCG protocol
213  *      links. Each remote agent, identified by their AgentID (RAID or HAID)
214  *      will be behind one of these three links. This structure holds the start
215  *      and end Agent IDs for each link. The remote AgentID to LinkID LUT
216  *      registers (por_{ccg_ra,ccg_ha, ccla}_agentid_to_linkid_reg<X>) will be
217  *      configured sequentially from
218  *      ::mod_cmn700_agentid_to_linkid_map::remote_agentid_start and
219  *      ::mod_cmn700_agentid_to_linkid_map::remote_agentid_end values. For
220  *      all three links, corresponding to these remote Agent IDs, HN-F's
221  *      RN_PHYS_ID registers will be programmed with the node id of the CCG
222  *      block.
223  */
224 struct mod_cmn700_agentid_to_linkid_map {
225     /*! Remote Agent ID start */
226     unsigned int remote_agentid_start;
227 
228     /*! Remote Agent ID end */
229     unsigned int remote_agentid_end;
230 };
231 
232 /*!
233  * \brief Remote Memory region map descriptor which will be used by CCRA SAM
234  *      programming
235  */
236 struct mod_cmn700_ra_mem_region_map {
237     /*! Base address */
238     uint64_t base;
239 
240     /*! Region size in bytes */
241     uint64_t size;
242 
243     /*! Target HAID of remote CCG for CCRA SAM Address region */
244     unsigned int remote_haid;
245 };
246 
247 /*!
248  * \brief CCG block descriptor
249  *
250  * \details Each CCG block can have up to eight remote memory map
251  *      ::mod_cmn700_ra_mem_region_map descriptors and can have three links
252  *      which can target range of remote agent ids. User is expected to assign
253  *      an Home AgentID (HAID) ::mod_cmn700_ccg_config::haid for each
254  *      logical ids of the CCG blocks. Overall structure of the descriptor is
255  *      shown below:
256  *
257  *         +----------------------------------------------------------+
258  *         | mod_cmn700_ccg_config<ldid>                              |
259  *         |                                                          |
260  *         |   HAID = haid                                            |
261  *         +----------------------------------+-----------------------+
262  *         | ra_mmap_table0                   | agentid_to_linkid_map0|
263  *         |                                  |  remote_agent_id_start|
264  *         | base..base+size --> remote_haid  |  .                    |
265  *         |                                  |  .                    |
266  *         +----------------------------------+  .                    |
267  *         | ra_mmap_table1                   |  .                    |
268  *         |                                  |  remote_agent_id_end  |
269  *         | base..base+size --> remote_haid  |                       |
270  *         |                                  +-----------------------+
271  *         +----------------------------------+ agentid_to_linkid_map1|
272  *         | .                                |  remote_agent_id_start|
273  *         | .                                |  .                    |
274  *         | .                                |  .                    |
275  *         | .                                |  .                    |
276  *         | .                                |  .                    |
277  *         | .                                |  remote_agent_id_end  |
278  *         +----------------------------------+                       |
279  *         | ra_mmap_table6                   +-----------------------+
280  *         |                                  | agentid_to_linkid_map2|
281  *         | base..base+size --> remote_haid  |  remote_agent_id_start|
282  *         |                                  |  .                    |
283  *         +----------------------------------+  .                    |
284  *         | ra_mmap_table7                   |  .                    |
285  *         |                                  |  .                    |
286  *         | base..base+size --> remote_haid  |  remote_agent_id_end  |
287  *         |                                  |                       |
288  *         +----------------------------------+-----------------------+
289  */
290 struct mod_cmn700_ccg_config {
291     /*! Logical ID of the CCG block to which this configuration applies */
292     unsigned int ldid;
293 
294     /*! Unique HAID in a multi-chip system. This has to be assigned manually */
295     unsigned int haid;
296 
297     /*! Number of remote RN Caching agents. */
298     unsigned int remote_rnf_count;
299 
300     /*! Table of region memory map entries */
301     const struct mod_cmn700_mem_region_map remote_mmap_table;
302 
303     /*! Table of remote region memory map entries */
304     const struct mod_cmn700_ra_mem_region_map
305         ra_mmap_table[CMN700_MAX_RA_SAM_ADDR_REGION];
306 
307     /*! Number of entries in the ::mod_cmn700_ccg_config::ra_mmap_table */
308     size_t ra_mmap_count;
309 
310     /*! Table of remote agent ids start and end backed by the links */
311     struct mod_cmn700_agentid_to_linkid_map
312         remote_agentid_to_linkid_map[CMN700_MAX_CCG_PROTOCOL_LINKS];
313 
314     /*! SMP Mode */
315     bool smp_mode;
316 
317     /*!
318      * \brief CCLA to CCLA direct connect mode
319      *
320      * \details CCG enables direct connection of CXS interface from the CCLA on
321      * one CMN‑700 to the CXS interface of the other. When such connection is
322      * present, set this option to true in order to enable upper link layer to
323      * upper link layer connection between CCLAs.
324      */
325     bool ull_to_ull_mode;
326 
327     /*! Port Aggregation Mode */
328     bool port_aggregate;
329 
330     /*!
331      * \brief Logical ID (LDID) of the CCG to which port aggregation pair to be
332      *      created
333      */
334     unsigned int port_aggregate_ldid;
335 
336     /*! HAID of the CCG to which port aggregation pair to be created */
337     unsigned int port_aggregate_haid;
338 
339     /*!
340      * \brief Target HAID of remote CCG for CCRA SAM Address region for
341      *      the port aggregated CCG block
342      */
343     unsigned int port_aggregate_remote_haid[CMN700_MAX_RA_SAM_ADDR_REGION];
344 };
345 
346 /*!
347  * \brief CMN700 configuration data
348  */
349 struct mod_cmn700_config {
350     /*! Peripheral base address. */
351     uintptr_t base;
352 
353     /*! Size along x-axis of the interconnect mesh */
354     unsigned int mesh_size_x;
355 
356     /*! Size along y-axis of the interconnect mesh */
357     unsigned int mesh_size_y;
358 
359     /*! Default HN-D node identifier containing the global configuration */
360     unsigned int hnd_node_id;
361 
362     /*!
363      * \brief Table of SN-Fs used as targets for the HN-F nodes
364      *
365      * \details Each entry of this table corresponds to a HN-F node in the
366      *      system. The HN-F's logical identifiers are used as indices in this
367      *      table
368      */
369     const unsigned int *snf_table;
370 
371     /*! Number of entries in the \ref snf_table */
372     size_t snf_count;
373 
374     /*! Hierarchical hashing support */
375     bool hierarchical_hashing_enable;
376 
377     /*! Hierarchical hashing configuration */
378     struct mod_cmn700_hierarchical_hashing hierarchical_hashing_config;
379 
380     /*! Table of region memory map entries */
381     const struct mod_cmn700_mem_region_map *mmap_table;
382 
383     /*! Number of entries in the \ref mmap_table */
384     size_t mmap_count;
385 
386     /*! Table of CCG configuration */
387     const struct mod_cmn700_ccg_config *ccg_config_table;
388 
389     /*!
390      * \brief Number of entries in the
391      *      ::mod_cmn700_config::ccg_config_table table.
392      */
393     const size_t ccg_table_count;
394 
395     /*! Address space size of the chip */
396     uint64_t chip_addr_space;
397 
398     /*! Identifier of the clock that this device depends on */
399     fwk_id_t clock_id;
400 
401     /*!
402      * \brief HN-F with CAL support flag
403      * \details When set to true, enables HN-F with CAL support. This flag will
404      * be used only if HN-F is found to be connected to CAL (When connected to
405      * a CAL port, node id of HN-F will be a odd number).
406      */
407     bool hnf_cal_mode;
408 };
409 
410 /*!
411  * @}
412  */
413 
414 /*!
415  * @}
416  */
417 
418 #endif /* MOD_CMN700_H */
419