1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* 3 * AMD Address Translation Library 4 * 5 * internal.h : Helper functions and common defines 6 * 7 * Copyright (c) 2023, Advanced Micro Devices, Inc. 8 * All Rights Reserved. 9 * 10 * Author: Yazen Ghannam <Yazen.Ghannam@amd.com> 11 */ 12 13 #ifndef __AMD_ATL_INTERNAL_H__ 14 #define __AMD_ATL_INTERNAL_H__ 15 16 #include <linux/bitfield.h> 17 #include <linux/bitops.h> 18 #include <linux/ras.h> 19 20 #include <asm/amd_nb.h> 21 22 #include "reg_fields.h" 23 24 #undef pr_fmt 25 #define pr_fmt(fmt) "amd_atl: " fmt 26 27 /* Maximum possible number of Coherent Stations within a single Data Fabric. */ 28 #define MAX_COH_ST_CHANNELS 32 29 30 /* PCI ID for Zen4 Server DF Function 0. */ 31 #define DF_FUNC0_ID_ZEN4_SERVER 0x14AD1022 32 33 /* PCI IDs for MI300 DF Function 0. */ 34 #define DF_FUNC0_ID_MI300 0x15281022 35 36 /* Shift needed for adjusting register values to true values. */ 37 #define DF_DRAM_BASE_LIMIT_LSB 28 38 #define MI300_DRAM_LIMIT_LSB 20 39 40 enum df_revisions { 41 UNKNOWN, 42 DF2, 43 DF3, 44 DF3p5, 45 DF4, 46 DF4p5, 47 }; 48 49 /* These are mapped 1:1 to the hardware values. Special cases are set at > 0x20. */ 50 enum intlv_modes { 51 NONE = 0x00, 52 NOHASH_2CHAN = 0x01, 53 NOHASH_4CHAN = 0x03, 54 NOHASH_8CHAN = 0x05, 55 DF3_6CHAN = 0x06, 56 NOHASH_16CHAN = 0x07, 57 NOHASH_32CHAN = 0x08, 58 DF3_COD4_2CHAN_HASH = 0x0C, 59 DF3_COD2_4CHAN_HASH = 0x0D, 60 DF3_COD1_8CHAN_HASH = 0x0E, 61 DF4_NPS4_2CHAN_HASH = 0x10, 62 DF4_NPS2_4CHAN_HASH = 0x11, 63 DF4_NPS1_8CHAN_HASH = 0x12, 64 DF4_NPS4_3CHAN_HASH = 0x13, 65 DF4_NPS2_6CHAN_HASH = 0x14, 66 DF4_NPS1_12CHAN_HASH = 0x15, 67 DF4_NPS2_5CHAN_HASH = 0x16, 68 DF4_NPS1_10CHAN_HASH = 0x17, 69 MI3_HASH_8CHAN = 0x18, 70 MI3_HASH_16CHAN = 0x19, 71 MI3_HASH_32CHAN = 0x1A, 72 DF2_2CHAN_HASH = 0x21, 73 /* DF4.5 modes are all IntLvNumChan + 0x20 */ 74 DF4p5_NPS1_16CHAN_1K_HASH = 0x2C, 75 DF4p5_NPS0_24CHAN_1K_HASH = 0x2E, 76 DF4p5_NPS4_2CHAN_1K_HASH = 0x30, 77 DF4p5_NPS2_4CHAN_1K_HASH = 0x31, 78 DF4p5_NPS1_8CHAN_1K_HASH = 0x32, 79 DF4p5_NPS4_3CHAN_1K_HASH = 0x33, 80 DF4p5_NPS2_6CHAN_1K_HASH = 0x34, 81 DF4p5_NPS1_12CHAN_1K_HASH = 0x35, 82 DF4p5_NPS2_5CHAN_1K_HASH = 0x36, 83 DF4p5_NPS1_10CHAN_1K_HASH = 0x37, 84 DF4p5_NPS4_2CHAN_2K_HASH = 0x40, 85 DF4p5_NPS2_4CHAN_2K_HASH = 0x41, 86 DF4p5_NPS1_8CHAN_2K_HASH = 0x42, 87 DF4p5_NPS1_16CHAN_2K_HASH = 0x43, 88 DF4p5_NPS4_3CHAN_2K_HASH = 0x44, 89 DF4p5_NPS2_6CHAN_2K_HASH = 0x45, 90 DF4p5_NPS1_12CHAN_2K_HASH = 0x46, 91 DF4p5_NPS0_24CHAN_2K_HASH = 0x47, 92 DF4p5_NPS2_5CHAN_2K_HASH = 0x48, 93 DF4p5_NPS1_10CHAN_2K_HASH = 0x49, 94 }; 95 96 struct df_flags { 97 __u8 legacy_ficaa : 1, 98 socket_id_shift_quirk : 1, 99 heterogeneous : 1, 100 __reserved_0 : 5; 101 }; 102 103 struct df_config { 104 enum df_revisions rev; 105 106 /* 107 * These masks operate on the 16-bit Coherent Station IDs, 108 * e.g. Instance, Fabric, Destination, etc. 109 */ 110 u16 component_id_mask; 111 u16 die_id_mask; 112 u16 node_id_mask; 113 u16 socket_id_mask; 114 115 /* 116 * Least-significant bit of Node ID portion of the 117 * system-wide Coherent Station Fabric ID. 118 */ 119 u8 node_id_shift; 120 121 /* 122 * Least-significant bit of Die portion of the Node ID. 123 * Adjusted to include the Node ID shift in order to apply 124 * to the Coherent Station Fabric ID. 125 */ 126 u8 die_id_shift; 127 128 /* 129 * Least-significant bit of Socket portion of the Node ID. 130 * Adjusted to include the Node ID shift in order to apply 131 * to the Coherent Station Fabric ID. 132 */ 133 u8 socket_id_shift; 134 135 /* Number of DRAM Address maps visible in a Coherent Station. */ 136 u8 num_coh_st_maps; 137 138 /* Global flags to handle special cases. */ 139 struct df_flags flags; 140 }; 141 142 extern struct df_config df_cfg; 143 144 struct dram_addr_map { 145 /* 146 * Each DRAM Address Map can operate independently 147 * in different interleaving modes. 148 */ 149 enum intlv_modes intlv_mode; 150 151 /* System-wide number for this address map. */ 152 u8 num; 153 154 /* Raw register values */ 155 u32 base; 156 u32 limit; 157 u32 ctl; 158 u32 intlv; 159 160 /* 161 * Logical to Physical Coherent Station Remapping array 162 * 163 * Index: Logical Coherent Station Instance ID 164 * Value: Physical Coherent Station Instance ID 165 * 166 * phys_coh_st_inst_id = remap_array[log_coh_st_inst_id] 167 */ 168 u8 remap_array[MAX_COH_ST_CHANNELS]; 169 170 /* 171 * Number of bits covering DRAM Address map 0 172 * when interleaving is non-power-of-2. 173 * 174 * Used only for DF3_6CHAN. 175 */ 176 u8 np2_bits; 177 178 /* Position of the 'interleave bit'. */ 179 u8 intlv_bit_pos; 180 /* Number of channels interleaved in this map. */ 181 u8 num_intlv_chan; 182 /* Number of dies interleaved in this map. */ 183 u8 num_intlv_dies; 184 /* Number of sockets interleaved in this map. */ 185 u8 num_intlv_sockets; 186 /* 187 * Total number of channels interleaved accounting 188 * for die and socket interleaving. 189 */ 190 u8 total_intlv_chan; 191 /* Total bits needed to cover 'total_intlv_chan'. */ 192 u8 total_intlv_bits; 193 }; 194 195 /* Original input values cached for debug printing. */ 196 struct addr_ctx_inputs { 197 u64 norm_addr; 198 u8 socket_id; 199 u8 die_id; 200 u8 coh_st_inst_id; 201 }; 202 203 struct addr_ctx { 204 u64 ret_addr; 205 206 struct addr_ctx_inputs inputs; 207 struct dram_addr_map map; 208 209 /* AMD Node ID calculated from Socket and Die IDs. */ 210 u8 node_id; 211 212 /* 213 * Coherent Station Instance ID 214 * Local ID used within a 'node'. 215 */ 216 u16 inst_id; 217 218 /* 219 * Coherent Station Fabric ID 220 * System-wide ID that includes 'node' bits. 221 */ 222 u16 coh_st_fabric_id; 223 }; 224 225 int df_indirect_read_instance(u16 node, u8 func, u16 reg, u8 instance_id, u32 *lo); 226 int df_indirect_read_broadcast(u16 node, u8 func, u16 reg, u32 *lo); 227 228 int get_df_system_info(void); 229 int determine_node_id(struct addr_ctx *ctx, u8 socket_num, u8 die_num); 230 int get_addr_hash_mi300(void); 231 232 int get_address_map(struct addr_ctx *ctx); 233 234 int denormalize_address(struct addr_ctx *ctx); 235 int dehash_address(struct addr_ctx *ctx); 236 237 unsigned long norm_to_sys_addr(u8 socket_id, u8 die_id, u8 coh_st_inst_id, unsigned long addr); 238 unsigned long convert_umc_mca_addr_to_sys_addr(struct atl_err *err); 239 240 /* 241 * Make a gap in @data that is @num_bits long starting at @bit_num. 242 * e.g. data = 11111111'b 243 * bit_num = 3 244 * num_bits = 2 245 * result = 1111100111'b 246 */ 247 static inline u64 expand_bits(u8 bit_num, u8 num_bits, u64 data) 248 { 249 u64 temp1, temp2; 250 251 if (!num_bits) 252 return data; 253 254 if (!bit_num) { 255 WARN_ON_ONCE(num_bits >= BITS_PER_LONG); 256 return data << num_bits; 257 } 258 259 WARN_ON_ONCE(bit_num >= BITS_PER_LONG); 260 261 temp1 = data & GENMASK_ULL(bit_num - 1, 0); 262 263 temp2 = data & GENMASK_ULL(63, bit_num); 264 temp2 <<= num_bits; 265 266 return temp1 | temp2; 267 } 268 269 /* 270 * Remove bits in @data between @low_bit and @high_bit inclusive. 271 * e.g. data = XXXYYZZZ'b 272 * low_bit = 3 273 * high_bit = 4 274 * result = XXXZZZ'b 275 */ 276 static inline u64 remove_bits(u8 low_bit, u8 high_bit, u64 data) 277 { 278 u64 temp1, temp2; 279 280 WARN_ON_ONCE(high_bit >= BITS_PER_LONG); 281 WARN_ON_ONCE(low_bit >= BITS_PER_LONG); 282 WARN_ON_ONCE(low_bit > high_bit); 283 284 if (!low_bit) 285 return data >> (high_bit++); 286 287 temp1 = GENMASK_ULL(low_bit - 1, 0) & data; 288 temp2 = GENMASK_ULL(63, high_bit + 1) & data; 289 temp2 >>= high_bit - low_bit + 1; 290 291 return temp1 | temp2; 292 } 293 294 #define atl_debug(ctx, fmt, arg...) \ 295 pr_debug("socket_id=%u die_id=%u coh_st_inst_id=%u norm_addr=0x%016llx: " fmt,\ 296 (ctx)->inputs.socket_id, (ctx)->inputs.die_id,\ 297 (ctx)->inputs.coh_st_inst_id, (ctx)->inputs.norm_addr, ##arg) 298 299 static inline void atl_debug_on_bad_df_rev(void) 300 { 301 pr_debug("Unrecognized DF rev: %u", df_cfg.rev); 302 } 303 304 static inline void atl_debug_on_bad_intlv_mode(struct addr_ctx *ctx) 305 { 306 atl_debug(ctx, "Unrecognized interleave mode: %u", ctx->map.intlv_mode); 307 } 308 309 #endif /* __AMD_ATL_INTERNAL_H__ */ 310