xref: /rk3399_ARM-atf/drivers/arm/ccn/ccn.c (revision 051cf88962f0d0e7d95961bb7a4b99e432611419)
1 /*
2  * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <arch.h>
8 #include <assert.h>
9 #include <bakery_lock.h>
10 #include <ccn.h>
11 #include <debug.h>
12 #include <errno.h>
13 #include <mmio.h>
14 #include <stdbool.h>
15 #include "ccn_private.h"
16 
17 static const ccn_desc_t *ccn_plat_desc;
18 #if defined(IMAGE_BL31) || (defined(AARCH32) && defined(IMAGE_BL32))
19 DEFINE_BAKERY_LOCK(ccn_lock);
20 #endif
21 
22 /*******************************************************************************
23  * This function takes the base address of the CCN's programmer's view (PV), a
24  * region ID of one of the 256 regions (0-255) and a register offset within the
25  * region. It converts the first two parameters into a base address and uses it
26  * to read the register at the offset.
27  ******************************************************************************/
28 static inline unsigned long long ccn_reg_read(uintptr_t periphbase,
29 			     unsigned int region_id,
30 			     unsigned int register_offset)
31 {
32 	uintptr_t region_base;
33 
34 	assert(periphbase);
35 	assert(region_id < REGION_ID_LIMIT);
36 
37 	region_base = periphbase + region_id_to_base(region_id);
38 	return mmio_read_64(region_base + register_offset);
39 }
40 
41 /*******************************************************************************
42  * This function takes the base address of the CCN's programmer's view (PV), a
43  * region ID of one of the 256 regions (0-255), a register offset within the
44  * region and a value. It converts the first two parameters into a base address
45  * and uses it to write the value in the register at the offset.
46  ******************************************************************************/
47 static inline void ccn_reg_write(uintptr_t periphbase,
48 			  unsigned int region_id,
49 			  unsigned int register_offset,
50 			  unsigned long long value)
51 {
52 	uintptr_t region_base;
53 
54 	assert(periphbase);
55 	assert(region_id < REGION_ID_LIMIT);
56 
57 	region_base = periphbase + region_id_to_base(region_id);
58 	mmio_write_64(region_base + register_offset, value);
59 }
60 
61 #if ENABLE_ASSERTIONS
62 
63 typedef struct rn_info {
64 		unsigned char node_desc[MAX_RN_NODES];
65 	} rn_info_t;
66 
67 /*******************************************************************************
68  * This function takes the base address of the CCN's programmer's view (PV) and
69  * the node ID of a Request Node (RN-D or RN-I). It returns the maximum number
70  * of master interfaces resident on that node. This number is equal to the least
71  * significant two bits of the node type ID + 1.
72  ******************************************************************************/
73 static unsigned int ccn_get_rni_mcount(uintptr_t periphbase,
74 				       unsigned int rn_id)
75 {
76 	unsigned int rn_type_id;
77 
78 	/* Use the node id to find the type of RN-I/D node */
79 	rn_type_id = get_node_type(ccn_reg_read(periphbase,
80 						rn_id + RNI_REGION_ID_START,
81 						REGION_ID_OFFSET));
82 
83 	/* Return the number master interfaces based on node type */
84 	return rn_type_id_to_master_cnt(rn_type_id);
85 }
86 
87 /*******************************************************************************
88  * This function reads the CCN registers to find the following information about
89  * the ACE/ACELite/ACELite+DVM/CHI interfaces resident on the various types of
90  * Request Nodes (RN-Fs, RN-Is and RN-Ds) in the system:
91  *
92  * 1. The total number of such interfaces that this CCN IP supports. This is the
93  *    cumulative number of interfaces across all Request node types. It is
94  *    passed back as the return value of this function.
95  *
96  * 2. The maximum number of interfaces of a type resident on a Request node of
97  *    one of the three types. This information is populated in the 'info'
98  *    array provided by the caller as described next.
99  *
100  *    The array has 64 entries. Each entry corresponds to a Request node. The
101  *    Miscellaneous node's programmer's view has RN-F, RN-I and RN-D ID
102  *    registers. For each RN-I and RN-D ID indicated as being present in these
103  *    registers, its identification register (offset 0xFF00) is read. This
104  *    register specifies the maximum number of master interfaces the node
105  *    supports. For RN-Fs it is assumed that there can be only a single fully
106  *    coherent master resident on each node. The counts for each type of node
107  *    are use to populate the array entry at the index corresponding to the node
108  *    ID i.e. rn_info[node ID] = <number of master interfaces>
109  ******************************************************************************/
110 static unsigned int ccn_get_rn_master_info(uintptr_t periphbase,
111 					   rn_info_t *info)
112 {
113 	unsigned int num_masters = 0;
114 	rn_types_t rn_type;
115 
116 	assert (info);
117 
118 	for (rn_type = RN_TYPE_RNF; rn_type < NUM_RN_TYPES; rn_type++) {
119 		unsigned int mn_reg_off, node_id;
120 		unsigned long long rn_bitmap;
121 
122 		/*
123 		 * RN-F, RN-I, RN-D node registers in the MN region occupy
124 		 * contiguous 16 byte apart offsets.
125 		 */
126 		mn_reg_off = MN_RNF_NODEID_OFFSET + (rn_type << 4);
127 		rn_bitmap = ccn_reg_read(periphbase, MN_REGION_ID, mn_reg_off);
128 
129 		FOR_EACH_PRESENT_NODE_ID(node_id, rn_bitmap) {
130 			unsigned int node_mcount;
131 
132 			/*
133 			 * A RN-F does not have a node type since it does not
134 			 * export a programmer's interface. It can only have a
135 			 * single fully coherent master residing on it. If the
136 			 * offset of the MN(Miscellaneous Node) register points
137 			 * to a RN-I/D node then the master count is set to the
138 			 * maximum number of master interfaces that can possibly
139 			 * reside on the node.
140 			 */
141 			node_mcount = (mn_reg_off == MN_RNF_NODEID_OFFSET ? 1 :
142 				       ccn_get_rni_mcount(periphbase, node_id));
143 
144 			/*
145 			 * Use this value to increment the maximum possible
146 			 * master interfaces in the system.
147 			 */
148 			num_masters += node_mcount;
149 
150 			/*
151 			 * Update the entry in 'info' for this node ID with
152 			 * the maximum number of masters than can sit on
153 			 * it. This information will be used to validate the
154 			 * node information passed by the platform later.
155 			 */
156 			info->node_desc[node_id] = node_mcount;
157 		}
158 	}
159 
160 	return num_masters;
161 }
162 
163 /*******************************************************************************
164  * This function validates parameters passed by the platform (in a debug build).
165  * It collects information about the maximum number of master interfaces that:
166  * a) the CCN IP can accommodate and
167  * b) can exist on each Request node.
168  * It compares this with the information provided by the platform to determine
169  * the validity of the latter.
170  ******************************************************************************/
171 static void __init ccn_validate_plat_params(const ccn_desc_t *plat_desc)
172 {
173 	unsigned int master_id, num_rn_masters;
174 	rn_info_t info = { {0} };
175 
176 	assert(plat_desc);
177 	assert(plat_desc->periphbase);
178 	assert(plat_desc->master_to_rn_id_map);
179 	assert(plat_desc->num_masters);
180 	assert(plat_desc->num_masters < CCN_MAX_RN_MASTERS);
181 
182 	/*
183 	 * Find the number and properties of fully coherent, IO coherent and IO
184 	 * coherent + DVM master interfaces
185 	 */
186 	num_rn_masters = ccn_get_rn_master_info(plat_desc->periphbase, &info);
187 	assert(plat_desc->num_masters < num_rn_masters);
188 
189 	/*
190 	 * Iterate through the Request nodes specified by the platform.
191 	 * Decrement the count of the masters in the 'info' array for each
192 	 * Request node encountered. If the count would drop below 0 then the
193 	 * platform's view of this aspect of CCN configuration is incorrect.
194 	 */
195 	for (master_id = 0; master_id < plat_desc->num_masters; master_id++) {
196 		unsigned int node_id;
197 
198 		node_id = plat_desc->master_to_rn_id_map[master_id];
199 		assert(node_id < MAX_RN_NODES);
200 		assert(info.node_desc[node_id]);
201 		info.node_desc[node_id]--;
202 	}
203 }
204 #endif /* ENABLE_ASSERTIONS */
205 
206 /*******************************************************************************
207  * This function validates parameters passed by the platform (in a debug build)
208  * and initialises its internal data structures. A lock is required to prevent
209  * simultaneous CCN operations at runtime (only BL31) to add and remove Request
210  * nodes from coherency.
211  ******************************************************************************/
212 void __init ccn_init(const ccn_desc_t *plat_desc)
213 {
214 #if ENABLE_ASSERTIONS
215 	ccn_validate_plat_params(plat_desc);
216 #endif
217 
218 	ccn_plat_desc = plat_desc;
219 }
220 
221 /*******************************************************************************
222  * This function converts a bit map of master interface IDs to a bit map of the
223  * Request node IDs that they reside on.
224  ******************************************************************************/
225 static unsigned long long ccn_master_to_rn_id_map(unsigned long long master_map)
226 {
227 	unsigned long long rn_id_map = 0;
228 	unsigned int node_id, iface_id;
229 
230 	assert(master_map);
231 	assert(ccn_plat_desc);
232 
233 	FOR_EACH_PRESENT_MASTER_INTERFACE(iface_id, master_map) {
234 		assert(iface_id < ccn_plat_desc->num_masters);
235 
236 		/* Convert the master ID into the node ID */
237 		node_id = ccn_plat_desc->master_to_rn_id_map[iface_id];
238 
239 		/* Set the bit corresponding to this node ID */
240 		rn_id_map |= (1ULL << node_id);
241 	}
242 
243 	return rn_id_map;
244 }
245 
246 /*******************************************************************************
247  * This function executes the necessary operations to add or remove Request node
248  * IDs specified in the 'rn_id_map' bitmap from the snoop/DVM domains specified
249  * in the 'hn_id_map'. The 'region_id' specifies the ID of the first HN-F/MN
250  * on which the operation should be performed. 'op_reg_offset' specifies the
251  * type of operation (add/remove). 'stat_reg_offset' specifies the register
252  * which should be polled to determine if the operation has completed or not.
253  ******************************************************************************/
254 static void ccn_snoop_dvm_do_op(unsigned long long rn_id_map,
255 				unsigned long long hn_id_map,
256 				unsigned int region_id,
257 				unsigned int op_reg_offset,
258 				unsigned int stat_reg_offset)
259 {
260 	unsigned int start_region_id;
261 
262 	assert(ccn_plat_desc);
263 	assert(ccn_plat_desc->periphbase);
264 
265 #if defined(IMAGE_BL31) || (defined(AARCH32) && defined(IMAGE_BL32))
266 	bakery_lock_get(&ccn_lock);
267 #endif
268 	start_region_id = region_id;
269 	FOR_EACH_PRESENT_REGION_ID(start_region_id, hn_id_map) {
270 		ccn_reg_write(ccn_plat_desc->periphbase,
271 			      start_region_id,
272 			      op_reg_offset,
273 			      rn_id_map);
274 	}
275 
276 	start_region_id = region_id;
277 
278 	FOR_EACH_PRESENT_REGION_ID(start_region_id, hn_id_map) {
279 		WAIT_FOR_DOMAIN_CTRL_OP_COMPLETION(start_region_id,
280 						   stat_reg_offset,
281 						   op_reg_offset,
282 						   rn_id_map);
283 	}
284 
285 #if defined(IMAGE_BL31) || (defined(AARCH32) && defined(IMAGE_BL32))
286 	bakery_lock_release(&ccn_lock);
287 #endif
288 }
289 
290 /*******************************************************************************
291  * The following functions provide the boot and runtime API to the platform for
292  * adding and removing master interfaces from the snoop/DVM domains. A bitmap of
293  * master interfaces IDs is passed as a parameter. It is converted into a bitmap
294  * of Request node IDs using the mapping provided by the platform while
295  * initialising the driver.
296  * For example, consider a dual cluster system where the clusters have values 0
297  * & 1 in the affinity level 1 field of their respective MPIDRs. While
298  * initialising this driver, the platform provides the mapping between each
299  * cluster and the corresponding Request node. To add or remove a cluster from
300  * the snoop and dvm domain, the bit position corresponding to the cluster ID
301  * should be set in the 'master_iface_map' i.e. to remove both clusters the
302  * bitmap would equal 0x11.
303  ******************************************************************************/
304 void ccn_enter_snoop_dvm_domain(unsigned long long master_iface_map)
305 {
306 	unsigned long long rn_id_map;
307 
308 	rn_id_map = ccn_master_to_rn_id_map(master_iface_map);
309 	ccn_snoop_dvm_do_op(rn_id_map,
310 			    CCN_GET_HN_NODEID_MAP(ccn_plat_desc->periphbase,
311 						  MN_HNF_NODEID_OFFSET),
312 			    HNF_REGION_ID_START,
313 			    HNF_SDC_SET_OFFSET,
314 			    HNF_SDC_STAT_OFFSET);
315 
316 	ccn_snoop_dvm_do_op(rn_id_map,
317 			    CCN_GET_MN_NODEID_MAP(ccn_plat_desc->periphbase),
318 			    MN_REGION_ID,
319 			    MN_DDC_SET_OFFSET,
320 			    MN_DDC_STAT_OFFSET);
321 }
322 
323 void ccn_exit_snoop_dvm_domain(unsigned long long master_iface_map)
324 {
325 	unsigned long long rn_id_map;
326 
327 	rn_id_map = ccn_master_to_rn_id_map(master_iface_map);
328 	ccn_snoop_dvm_do_op(rn_id_map,
329 			    CCN_GET_HN_NODEID_MAP(ccn_plat_desc->periphbase,
330 						  MN_HNF_NODEID_OFFSET),
331 			    HNF_REGION_ID_START,
332 			    HNF_SDC_CLR_OFFSET,
333 			    HNF_SDC_STAT_OFFSET);
334 
335 	ccn_snoop_dvm_do_op(rn_id_map,
336 			    CCN_GET_MN_NODEID_MAP(ccn_plat_desc->periphbase),
337 			    MN_REGION_ID,
338 			    MN_DDC_CLR_OFFSET,
339 			    MN_DDC_STAT_OFFSET);
340 }
341 
342 void ccn_enter_dvm_domain(unsigned long long master_iface_map)
343 {
344 	unsigned long long rn_id_map;
345 
346 	rn_id_map = ccn_master_to_rn_id_map(master_iface_map);
347 	ccn_snoop_dvm_do_op(rn_id_map,
348 			    CCN_GET_MN_NODEID_MAP(ccn_plat_desc->periphbase),
349 			    MN_REGION_ID,
350 			    MN_DDC_SET_OFFSET,
351 			    MN_DDC_STAT_OFFSET);
352 }
353 
354 void ccn_exit_dvm_domain(unsigned long long master_iface_map)
355 {
356 	unsigned long long rn_id_map;
357 
358 	rn_id_map = ccn_master_to_rn_id_map(master_iface_map);
359 	ccn_snoop_dvm_do_op(rn_id_map,
360 			    CCN_GET_MN_NODEID_MAP(ccn_plat_desc->periphbase),
361 			    MN_REGION_ID,
362 			    MN_DDC_CLR_OFFSET,
363 			    MN_DDC_STAT_OFFSET);
364 }
365 
366 /*******************************************************************************
367  * This function returns the run mode of all the L3 cache partitions in the
368  * system. The state is expected to be one of NO_L3, SF_ONLY, L3_HAM or
369  * L3_FAM. Instead of comparing the states reported by all HN-Fs, the state of
370  * the first present HN-F node is reported. Since the driver does not export an
371  * interface to program them seperately, there is no reason to perform this
372  * check. An HN-F could report that the L3 cache is transitioning from one mode
373  * to another e.g. HNF_PM_NOL3_2_SFONLY. In this case, the function waits for
374  * the transition to complete and reports the final state.
375  ******************************************************************************/
376 unsigned int ccn_get_l3_run_mode(void)
377 {
378 	unsigned long long hnf_pstate_stat;
379 
380 	assert(ccn_plat_desc);
381 	assert(ccn_plat_desc->periphbase);
382 
383 	/*
384 	 * Wait for a L3 cache paritition to enter any run mode. The pstate
385 	 * parameter is read from an HN-F P-state status register. A non-zero
386 	 * value in bits[1:0] means that the cache is transitioning to a run
387 	 * mode.
388 	 */
389 	do {
390 		hnf_pstate_stat = ccn_reg_read(ccn_plat_desc->periphbase,
391 					       HNF_REGION_ID_START,
392 					       HNF_PSTATE_STAT_OFFSET);
393 	} while (hnf_pstate_stat & 0x3);
394 
395 	return PSTATE_TO_RUN_MODE(hnf_pstate_stat);
396 }
397 
398 /*******************************************************************************
399  * This function sets the run mode of all the L3 cache partitions in the
400  * system to one of NO_L3, SF_ONLY, L3_HAM or L3_FAM depending upon the state
401  * specified by the 'mode' argument.
402  ******************************************************************************/
403 void ccn_set_l3_run_mode(unsigned int mode)
404 {
405 	unsigned long long mn_hnf_id_map, hnf_pstate_stat;
406 	unsigned int region_id;
407 
408 	assert(ccn_plat_desc);
409 	assert(ccn_plat_desc->periphbase);
410 	assert(mode <= CCN_L3_RUN_MODE_FAM);
411 
412 	mn_hnf_id_map = ccn_reg_read(ccn_plat_desc->periphbase,
413 				     MN_REGION_ID,
414 				     MN_HNF_NODEID_OFFSET);
415 	region_id = HNF_REGION_ID_START;
416 
417 	/* Program the desired run mode */
418 	FOR_EACH_PRESENT_REGION_ID(region_id, mn_hnf_id_map) {
419 		ccn_reg_write(ccn_plat_desc->periphbase,
420 			      region_id,
421 			      HNF_PSTATE_REQ_OFFSET,
422 			      mode);
423 	}
424 
425 	/* Wait for the caches to transition to the run mode */
426 	region_id = HNF_REGION_ID_START;
427 	FOR_EACH_PRESENT_REGION_ID(region_id, mn_hnf_id_map) {
428 		/*
429 		 * Wait for a L3 cache paritition to enter a target run
430 		 * mode. The pstate parameter is read from an HN-F P-state
431 		 * status register.
432 		 */
433 		do {
434 			hnf_pstate_stat = ccn_reg_read(ccn_plat_desc->periphbase,
435 					       region_id,
436 					       HNF_PSTATE_STAT_OFFSET);
437 		} while (((hnf_pstate_stat & HNF_PSTATE_MASK) >> 2) != mode);
438 	}
439 }
440 
441 /*******************************************************************************
442  * This function configures system address map and provides option to enable the
443  * 3SN striping mode of Slave node operation. The Slave node IDs and the Top
444  * Address bit1 and bit0 are provided as parameters to this function. This
445  * configuration is needed only if network contains a single SN-F or 3 SN-F and
446  * must be completed before the first request by the system to normal memory.
447  ******************************************************************************/
448 void ccn_program_sys_addrmap(unsigned int sn0_id,
449 		 unsigned int sn1_id,
450 		 unsigned int sn2_id,
451 		 unsigned int top_addr_bit0,
452 		 unsigned int top_addr_bit1,
453 		 unsigned char three_sn_en)
454 {
455 	unsigned long long mn_hnf_id_map, hnf_sam_ctrl_value;
456 	unsigned int region_id;
457 
458 	assert(ccn_plat_desc);
459 	assert(ccn_plat_desc->periphbase);
460 
461 	mn_hnf_id_map = ccn_reg_read(ccn_plat_desc->periphbase,
462 				     MN_REGION_ID,
463 				     MN_HNF_NODEID_OFFSET);
464 	region_id = HNF_REGION_ID_START;
465 	hnf_sam_ctrl_value = MAKE_HNF_SAM_CTRL_VALUE(sn0_id,
466 						     sn1_id,
467 						     sn2_id,
468 						     top_addr_bit0,
469 						     top_addr_bit1,
470 						     three_sn_en);
471 
472 	FOR_EACH_PRESENT_REGION_ID(region_id, mn_hnf_id_map) {
473 
474 		/* Program the SAM control register */
475 		ccn_reg_write(ccn_plat_desc->periphbase,
476 			      region_id,
477 			      HNF_SAM_CTRL_OFFSET,
478 			      hnf_sam_ctrl_value);
479 	}
480 
481 }
482 
483 /*******************************************************************************
484  * This function returns the part0 id from the peripheralID 0 register
485  * in CCN. This id can be used to distinguish the CCN variant present in the
486  * system.
487  ******************************************************************************/
488 int ccn_get_part0_id(uintptr_t periphbase)
489 {
490 	assert(periphbase);
491 	return (int)(mmio_read_64(periphbase
492 			+ MN_PERIPH_ID_0_1_OFFSET) & 0xFF);
493 }
494 
495 /*******************************************************************************
496  * This function returns the region id corresponding to a node_id of node_type.
497  ******************************************************************************/
498 static unsigned int get_region_id_for_node(node_types_t node_type,
499 						unsigned int node_id)
500 {
501 	unsigned int mn_reg_off, region_id;
502 	unsigned long long node_bitmap;
503 	unsigned int loc_node_id, node_pos_in_map = 0;
504 
505 	assert(node_type < NUM_NODE_TYPES);
506 	assert(node_id < MAX_RN_NODES);
507 
508 	switch (node_type) {
509 	case NODE_TYPE_RNI:
510 		region_id = RNI_REGION_ID_START;
511 		break;
512 	case NODE_TYPE_HNF:
513 		region_id = HNF_REGION_ID_START;
514 		break;
515 	case NODE_TYPE_HNI:
516 		region_id = HNI_REGION_ID_START;
517 		break;
518 	case NODE_TYPE_SN:
519 		region_id = SBSX_REGION_ID_START;
520 		break;
521 	default:
522 		ERROR("Un-supported Node Type = %d.\n", node_type);
523 		assert(false);
524 		return REGION_ID_LIMIT;
525 	}
526 	/*
527 	 * RN-I, HN-F, HN-I, SN node registers in the MN region
528 	 * occupy contiguous 16 byte apart offsets.
529 	 *
530 	 * RN-F and RN-D node are not supported as
531 	 * none of them exposes any memory map to
532 	 * configure any of their offset registers.
533 	 */
534 
535 	mn_reg_off = MN_RNF_NODEID_OFFSET + (node_type << 4);
536 	node_bitmap = ccn_reg_read(ccn_plat_desc->periphbase,
537 					MN_REGION_ID, mn_reg_off);
538 
539 	assert((node_bitmap & (1ULL << (node_id))) != 0U);
540 
541 
542 	FOR_EACH_PRESENT_NODE_ID(loc_node_id, node_bitmap) {
543 		INFO("Index = %u with loc_nod=%u and input nod=%u\n",
544 					node_pos_in_map, loc_node_id, node_id);
545 		if (loc_node_id == node_id)
546 			break;
547 		node_pos_in_map++;
548 	}
549 
550 	if (node_pos_in_map == CCN_MAX_RN_MASTERS) {
551 		ERROR("Node Id = %d, is not found.\n", node_id);
552 		assert(false);
553 		return REGION_ID_LIMIT;
554 	}
555 
556 	region_id += node_pos_in_map;
557 
558 	return region_id;
559 }
560 
561 /*******************************************************************************
562  * This function sets the value 'val' to the register at register_offset from
563  * the base address pointed to by the region_id.
564  * where, region id is mapped to a node_id of node_type.
565  ******************************************************************************/
566 void ccn_write_node_reg(node_types_t node_type, unsigned int node_id,
567 			unsigned int reg_offset, unsigned long long val)
568 {
569 	unsigned int region_id = get_region_id_for_node(node_type, node_id);
570 
571 	if (reg_offset > REGION_ID_OFFSET) {
572 		ERROR("Invalid Register offset 0x%x is provided.\n",
573 								reg_offset);
574 		assert(false);
575 		return;
576 	}
577 
578 	/* Setting the value of Auxilary Control Register of the Node */
579 	ccn_reg_write(ccn_plat_desc->periphbase, region_id, reg_offset, val);
580 	VERBOSE("Value is successfully written at address 0x%lx.\n",
581 			(ccn_plat_desc->periphbase
582 			+ region_id_to_base(region_id))
583 			+ reg_offset);
584 }
585 
586 /*******************************************************************************
587  * This function read the value 'val' stored in the register at register_offset
588  * from the base address pointed to by the region_id.
589  * where, region id is mapped to a node_id of node_type.
590  ******************************************************************************/
591 unsigned long long ccn_read_node_reg(node_types_t node_type,
592 					unsigned int node_id,
593 					unsigned int reg_offset)
594 {
595 	unsigned long long val;
596 	unsigned int region_id = get_region_id_for_node(node_type, node_id);
597 
598 	if (reg_offset > REGION_ID_OFFSET) {
599 		ERROR("Invalid Register offset 0x%x is provided.\n",
600 								reg_offset);
601 		assert(false);
602 		return ULL(0);
603 	}
604 
605 	/* Setting the value of Auxilary Control Register of the Node */
606 	val = ccn_reg_read(ccn_plat_desc->periphbase, region_id, reg_offset);
607 	VERBOSE("Value is successfully read from address 0x%lx.\n",
608 			(ccn_plat_desc->periphbase
609 			+ region_id_to_base(region_id))
610 			+ reg_offset);
611 
612 	return val;
613 }
614