1fd6007deSAchin Gupta /* 24c0d0390SSoby Mathew * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. 3fd6007deSAchin Gupta * 4*82cb2c1aSdp-arm * SPDX-License-Identifier: BSD-3-Clause 5fd6007deSAchin Gupta */ 6fd6007deSAchin Gupta 7fd6007deSAchin Gupta #ifndef __CCN_PRIVATE_H__ 8fd6007deSAchin Gupta #define __CCN_PRIVATE_H__ 9fd6007deSAchin Gupta 10fd6007deSAchin Gupta /* 11fd6007deSAchin Gupta * A CCN implementation can have a maximum of 64 Request nodes with node IDs 12fd6007deSAchin Gupta * from 0-63. These IDs are split across the three types of Request nodes 13fd6007deSAchin Gupta * i.e. RN-F, RN-D and RN-I. 14fd6007deSAchin Gupta */ 15fd6007deSAchin Gupta #define MAX_RN_NODES 64 16fd6007deSAchin Gupta 17fd6007deSAchin Gupta /* Enum used to loop through the 3 types of Request nodes */ 18fd6007deSAchin Gupta typedef enum rn_types { 19fd6007deSAchin Gupta RN_TYPE_RNF = 0, 20fd6007deSAchin Gupta RN_TYPE_RNI, 21fd6007deSAchin Gupta RN_TYPE_RND, 22fd6007deSAchin Gupta NUM_RN_TYPES 23fd6007deSAchin Gupta } rn_types_t; 24fd6007deSAchin Gupta 25fd6007deSAchin Gupta /* Macro to convert a region id to its base address */ 26fd6007deSAchin Gupta #define region_id_to_base(id) ((id) << 16) 27fd6007deSAchin Gupta 28fd6007deSAchin Gupta /* 29fd6007deSAchin Gupta * Macro to calculate the number of master interfaces resident on a RN-I/RN-D. 30fd6007deSAchin Gupta * Value of first two bits of the RN-I/D node type + 1 == Maximum number of 31fd6007deSAchin Gupta * ACE-Lite or ACE-Lite+DVM interfaces supported on this node. E.g. 32fd6007deSAchin Gupta * 33fd6007deSAchin Gupta * 0x14 : RN-I with 1 ACE-Lite interface 34fd6007deSAchin Gupta * 0x15 : RN-I with 2 ACE-Lite interfaces 35fd6007deSAchin Gupta * 0x16 : RN-I with 3 ACE-Lite interfaces 36fd6007deSAchin Gupta */ 37fd6007deSAchin Gupta #define rn_type_id_to_master_cnt(id) (((id) & 0x3) + 1) 38fd6007deSAchin Gupta 39fd6007deSAchin Gupta /* 40fd6007deSAchin Gupta * Constants used to identify a region in the programmer's view. These are 41fd6007deSAchin Gupta * common for all regions. 42fd6007deSAchin Gupta */ 43fd6007deSAchin Gupta #define REGION_ID_LIMIT 256 44fd6007deSAchin Gupta #define REGION_ID_OFFSET 0xFF00 45fd6007deSAchin Gupta 46fd6007deSAchin Gupta #define REGION_NODE_ID_SHIFT 8 47fd6007deSAchin Gupta #define REGION_NODE_ID_MASK 0x7f 48fd6007deSAchin Gupta #define get_node_id(id_reg) (((id_reg) >> REGION_NODE_ID_SHIFT) \ 49fd6007deSAchin Gupta & REGION_NODE_ID_MASK) 50fd6007deSAchin Gupta 51fd6007deSAchin Gupta #define REGION_NODE_TYPE_SHIFT 0 52fd6007deSAchin Gupta #define REGION_NODE_TYPE_MASK 0x1f 53fd6007deSAchin Gupta #define get_node_type(id_reg) (((id_reg) >> REGION_NODE_TYPE_SHIFT) \ 54fd6007deSAchin Gupta & REGION_NODE_TYPE_MASK) 55fd6007deSAchin Gupta 56fd6007deSAchin Gupta /* Common offsets of registers to enter or exit a snoop/dvm domain */ 57fd6007deSAchin Gupta #define DOMAIN_CTRL_STAT_OFFSET 0x0200 58fd6007deSAchin Gupta #define DOMAIN_CTRL_SET_OFFSET 0x0210 59fd6007deSAchin Gupta #define DOMAIN_CTRL_CLR_OFFSET 0x0220 60fd6007deSAchin Gupta 61fd6007deSAchin Gupta /* 62fd6007deSAchin Gupta * Thess macros are used to determine if an operation to add or remove a Request 63fd6007deSAchin Gupta * node from the snoop/dvm domain has completed. 'rn_id_map' is a bit map of 64fd6007deSAchin Gupta * nodes. It was used to program the SET or CLEAR control register. The type of 65fd6007deSAchin Gupta * register is specified by 'op_reg_offset'. 'status_reg' is the bit map of 66fd6007deSAchin Gupta * nodes currently present in the snoop/dvm domain. 'rn_id_map' and 'status_reg' 67fd6007deSAchin Gupta * are logically ANDed and the result it stored back in the 'status_reg'. There 68fd6007deSAchin Gupta * are two outcomes of this operation: 69fd6007deSAchin Gupta * 70fd6007deSAchin Gupta * 1. If the DOMAIN_CTRL_SET_OFFSET register was programmed, then the set bits in 71fd6007deSAchin Gupta * 'rn_id_map' should appear in 'status_reg' when the operation completes. So 72fd6007deSAchin Gupta * after the AND operation, at some point of time 'status_reg' should equal 73fd6007deSAchin Gupta * 'rn_id_map'. 74fd6007deSAchin Gupta * 75fd6007deSAchin Gupta * 2. If the DOMAIN_CTRL_CLR_OFFSET register was programmed, then the set bits in 76fd6007deSAchin Gupta * 'rn_id_map' should disappear in 'status_reg' when the operation 77fd6007deSAchin Gupta * completes. So after the AND operation, at some point of time 'status_reg' 78fd6007deSAchin Gupta * should equal 0. 79fd6007deSAchin Gupta */ 80fd6007deSAchin Gupta #define WAIT_FOR_DOMAIN_CTRL_OP_COMPLETION(region_id, stat_reg_offset, \ 81fd6007deSAchin Gupta op_reg_offset, rn_id_map) \ 82fd6007deSAchin Gupta { \ 834c0d0390SSoby Mathew unsigned long long status_reg; \ 84fd6007deSAchin Gupta do { \ 85fd6007deSAchin Gupta status_reg = ccn_reg_read((ccn_plat_desc->periphbase), \ 86fd6007deSAchin Gupta (region_id), \ 87fd6007deSAchin Gupta (stat_reg_offset)); \ 88fd6007deSAchin Gupta status_reg &= (rn_id_map); \ 89fd6007deSAchin Gupta } while ((op_reg_offset) == DOMAIN_CTRL_SET_OFFSET ? \ 90fd6007deSAchin Gupta (rn_id_map) != status_reg : status_reg); \ 91fd6007deSAchin Gupta } 92fd6007deSAchin Gupta 93fd6007deSAchin Gupta /* 94fd6007deSAchin Gupta * Region ID of the Miscellaneous Node is always 0 as its located at the base of 95fd6007deSAchin Gupta * the programmer's view. 96fd6007deSAchin Gupta */ 97fd6007deSAchin Gupta #define MN_REGION_ID 0 98fd6007deSAchin Gupta 99fd6007deSAchin Gupta #define MN_REGION_ID_START 0 100fd6007deSAchin Gupta #define DEBUG_REGION_ID_START 1 101fd6007deSAchin Gupta #define HNI_REGION_ID_START 8 102fd6007deSAchin Gupta #define SBSX_REGION_ID_START 16 103fd6007deSAchin Gupta #define HNF_REGION_ID_START 32 104fd6007deSAchin Gupta #define XP_REGION_ID_START 64 105fd6007deSAchin Gupta #define RNI_REGION_ID_START 128 106fd6007deSAchin Gupta 107fd6007deSAchin Gupta /* Selected register offsets from the base of a HNF region */ 108fd6007deSAchin Gupta #define HNF_CFG_CTRL_OFFSET 0x0000 109fd6007deSAchin Gupta #define HNF_SAM_CTRL_OFFSET 0x0008 110fd6007deSAchin Gupta #define HNF_PSTATE_REQ_OFFSET 0x0010 111fd6007deSAchin Gupta #define HNF_PSTATE_STAT_OFFSET 0x0018 112fd6007deSAchin Gupta #define HNF_SDC_STAT_OFFSET DOMAIN_CTRL_STAT_OFFSET 113fd6007deSAchin Gupta #define HNF_SDC_SET_OFFSET DOMAIN_CTRL_SET_OFFSET 114fd6007deSAchin Gupta #define HNF_SDC_CLR_OFFSET DOMAIN_CTRL_CLR_OFFSET 115fd6007deSAchin Gupta #define HNF_AUX_CTRL_OFFSET 0x0500 116fd6007deSAchin Gupta 117fd6007deSAchin Gupta /* Selected register offsets from the base of a MN region */ 118fd6007deSAchin Gupta #define MN_SAR_OFFSET 0x0000 119fd6007deSAchin Gupta #define MN_RNF_NODEID_OFFSET 0x0180 120fd6007deSAchin Gupta #define MN_RNI_NODEID_OFFSET 0x0190 121fd6007deSAchin Gupta #define MN_RND_NODEID_OFFSET 0x01A0 122fd6007deSAchin Gupta #define MN_HNF_NODEID_OFFSET 0x01B0 123fd6007deSAchin Gupta #define MN_HNI_NODEID_OFFSET 0x01C0 124fd6007deSAchin Gupta #define MN_SN_NODEID_OFFSET 0x01D0 125fd6007deSAchin Gupta #define MN_DDC_STAT_OFFSET DOMAIN_CTRL_STAT_OFFSET 1263105f7baSVikram Kanigiri #define MN_DDC_SET_OFFSET DOMAIN_CTRL_SET_OFFSET 127fd6007deSAchin Gupta #define MN_DDC_CLR_OFFSET DOMAIN_CTRL_CLR_OFFSET 1286331a31aSSoby Mathew #define MN_PERIPH_ID_0_1_OFFSET 0xFE0 129fd6007deSAchin Gupta #define MN_ID_OFFSET REGION_ID_OFFSET 130fd6007deSAchin Gupta 131fd6007deSAchin Gupta /* HNF System Address Map register bit masks and shifts */ 132fd6007deSAchin Gupta #define HNF_SAM_CTRL_SN_ID_MASK 0x7f 133fd6007deSAchin Gupta #define HNF_SAM_CTRL_SN0_ID_SHIFT 0 134fd6007deSAchin Gupta #define HNF_SAM_CTRL_SN1_ID_SHIFT 8 135fd6007deSAchin Gupta #define HNF_SAM_CTRL_SN2_ID_SHIFT 16 136fd6007deSAchin Gupta 137fd6007deSAchin Gupta #define HNF_SAM_CTRL_TAB0_MASK 0x3fUL 138fd6007deSAchin Gupta #define HNF_SAM_CTRL_TAB0_SHIFT 48 139fd6007deSAchin Gupta #define HNF_SAM_CTRL_TAB1_MASK 0x3fUL 140fd6007deSAchin Gupta #define HNF_SAM_CTRL_TAB1_SHIFT 56 141fd6007deSAchin Gupta 142fd6007deSAchin Gupta #define HNF_SAM_CTRL_3SN_ENB_SHIFT 32 143fd6007deSAchin Gupta #define HNF_SAM_CTRL_3SN_ENB_MASK 0x01UL 144fd6007deSAchin Gupta 145fd6007deSAchin Gupta /* 146fd6007deSAchin Gupta * Macro to create a value suitable for programming into a HNF SAM Control 147fd6007deSAchin Gupta * register for enabling 3SN striping. 148fd6007deSAchin Gupta */ 149fd6007deSAchin Gupta #define MAKE_HNF_SAM_CTRL_VALUE(sn0, sn1, sn2, tab0, tab1, three_sn_en) \ 150fd6007deSAchin Gupta ((((sn0) & HNF_SAM_CTRL_SN_ID_MASK) << HNF_SAM_CTRL_SN0_ID_SHIFT) | \ 151fd6007deSAchin Gupta (((sn1) & HNF_SAM_CTRL_SN_ID_MASK) << HNF_SAM_CTRL_SN1_ID_SHIFT) | \ 152fd6007deSAchin Gupta (((sn2) & HNF_SAM_CTRL_SN_ID_MASK) << HNF_SAM_CTRL_SN2_ID_SHIFT) | \ 153fd6007deSAchin Gupta (((tab0) & HNF_SAM_CTRL_TAB0_MASK) << HNF_SAM_CTRL_TAB0_SHIFT) | \ 154fd6007deSAchin Gupta (((tab1) & HNF_SAM_CTRL_TAB1_MASK) << HNF_SAM_CTRL_TAB1_SHIFT) | \ 155fd6007deSAchin Gupta (((three_sn_en) & HNF_SAM_CTRL_3SN_ENB_MASK) << HNF_SAM_CTRL_3SN_ENB_SHIFT)) 156fd6007deSAchin Gupta 157fd6007deSAchin Gupta /* Mask to read the power state value from an HN-F P-state register */ 158fd6007deSAchin Gupta #define HNF_PSTATE_MASK 0xf 159fd6007deSAchin Gupta 160fd6007deSAchin Gupta /* Macro to extract the run mode from a p-state value */ 161fd6007deSAchin Gupta #define PSTATE_TO_RUN_MODE(pstate) (((pstate) & HNF_PSTATE_MASK) >> 2) 162fd6007deSAchin Gupta 163fd6007deSAchin Gupta /* 164fd6007deSAchin Gupta * Helper macro that iterates through a given bit map. In each iteration, 165fd6007deSAchin Gupta * it returns the position of the set bit. 166fd6007deSAchin Gupta * It can be used by other utility macros to iterates through all nodes 167fd6007deSAchin Gupta * or masters given a bit map of them. 168fd6007deSAchin Gupta */ 169fd6007deSAchin Gupta #define FOR_EACH_BIT(bit_pos, bit_map) \ 170fd6007deSAchin Gupta for (bit_pos = __builtin_ctzll(bit_map); \ 171fd6007deSAchin Gupta bit_map; \ 172fd6007deSAchin Gupta bit_map &= ~(1UL << bit_pos), \ 173fd6007deSAchin Gupta bit_pos = __builtin_ctzll(bit_map)) 174fd6007deSAchin Gupta 175fd6007deSAchin Gupta /* 176fd6007deSAchin Gupta * Utility macro that iterates through a bit map of node IDs. In each 177fd6007deSAchin Gupta * iteration, it returns the ID of the next present node in the bit map. Node 178fd6007deSAchin Gupta * ID of a present node == Position of set bit == Number of zeroes trailing the 179fd6007deSAchin Gupta * bit. 180fd6007deSAchin Gupta */ 181fd6007deSAchin Gupta #define FOR_EACH_PRESENT_NODE_ID(node_id, bit_map) \ 182fd6007deSAchin Gupta FOR_EACH_BIT(node_id, bit_map) 183fd6007deSAchin Gupta 184fd6007deSAchin Gupta /* 185fd6007deSAchin Gupta * Helper function to return number of set bits in bitmap 186fd6007deSAchin Gupta */ 1874c0d0390SSoby Mathew static inline unsigned int count_set_bits(unsigned long long bitmap) 188fd6007deSAchin Gupta { 189fd6007deSAchin Gupta unsigned int count = 0; 190fd6007deSAchin Gupta 191fd6007deSAchin Gupta for (; bitmap; bitmap &= bitmap - 1) 192fd6007deSAchin Gupta ++count; 193fd6007deSAchin Gupta 194fd6007deSAchin Gupta return count; 195fd6007deSAchin Gupta } 196fd6007deSAchin Gupta 197fd6007deSAchin Gupta /* 198fd6007deSAchin Gupta * Utility macro that iterates through a bit map of node IDs. In each iteration, 199fd6007deSAchin Gupta * it returns the ID of the next present region corresponding to a node present 200fd6007deSAchin Gupta * in the bit map. Region ID of a present node is in between passed region id 201fd6007deSAchin Gupta * and region id + number of set bits in the bitmap i.e. the number of present 202fd6007deSAchin Gupta * nodes. 203fd6007deSAchin Gupta */ 204fd6007deSAchin Gupta #define FOR_EACH_PRESENT_REGION_ID(region_id, bit_map) \ 205fd6007deSAchin Gupta for (unsigned long long region_id_limit = count_set_bits(bit_map) \ 206fd6007deSAchin Gupta + region_id; \ 207fd6007deSAchin Gupta region_id < region_id_limit; \ 208fd6007deSAchin Gupta region_id++) 209fd6007deSAchin Gupta 210fd6007deSAchin Gupta /* 211fd6007deSAchin Gupta * Same macro as FOR_EACH_PRESENT_NODE, but renamed to indicate it traverses 212fd6007deSAchin Gupta * through a bit map of master interfaces. 213fd6007deSAchin Gupta */ 214fd6007deSAchin Gupta #define FOR_EACH_PRESENT_MASTER_INTERFACE(iface_id, bit_map) \ 215fd6007deSAchin Gupta FOR_EACH_BIT(iface_id, bit_map) 2163105f7baSVikram Kanigiri 2173105f7baSVikram Kanigiri /* 2183105f7baSVikram Kanigiri * Macro that returns the node id bit map for the Miscellaneous Node 2193105f7baSVikram Kanigiri */ 2203105f7baSVikram Kanigiri #define CCN_GET_MN_NODEID_MAP(periphbase) \ 2213105f7baSVikram Kanigiri (1 << get_node_id(ccn_reg_read(periphbase, MN_REGION_ID, \ 2223105f7baSVikram Kanigiri REGION_ID_OFFSET))) 2233105f7baSVikram Kanigiri 2243105f7baSVikram Kanigiri /* 2253105f7baSVikram Kanigiri * This macro returns the bitmap of Home nodes on the basis of the 2263105f7baSVikram Kanigiri * 'mn_hn_id_reg_offset' parameter from the Miscellaneous node's (MN) 2273105f7baSVikram Kanigiri * programmer's view. The MN has a register which carries the bitmap of present 2283105f7baSVikram Kanigiri * Home nodes of each type i.e. HN-Fs, HN-Is & HN-Ds. 2293105f7baSVikram Kanigiri */ 2303105f7baSVikram Kanigiri #define CCN_GET_HN_NODEID_MAP(periphbase, mn_hn_id_reg_offset) \ 2313105f7baSVikram Kanigiri ccn_reg_read(periphbase, MN_REGION_ID, mn_hn_id_reg_offset) 2323105f7baSVikram Kanigiri 233fd6007deSAchin Gupta #endif /* __CCN_PRIVATE_H__ */ 234