1 /* 2 * This file and its contents are supplied under the terms of the 3 * Common Development and Distribution License ("CDDL"), version 1.0. 4 * You may only use this file in accordance with the terms of version 5 * 1.0 of the CDDL. 6 * 7 * A full copy of the text of the CDDL should have accompanied this 8 * source. A copy of the CDDL is also available via the Internet at 9 * http://www.illumos.org/license/CDDL. 10 */ 11 12 /* 13 * Copyright 2022 Oxide Computer Company 14 */ 15 16 #ifndef _SYS_UMC_H 17 #define _SYS_UMC_H 18 19 #include <sys/bitext.h> 20 21 /* 22 * Various register definitions for accessing the AMD Unified Memory Controller 23 * (UMC) over SMN (the system management network). Note, that the SMN exists 24 * independently in each die and must be accessed through the appropriate 25 * IOHC. 26 * 27 * There are effectively four different revisions of the UMC that we know about 28 * and support querying: 29 * 30 * o DDR4 capable APUs 31 * o DDR4 capable CPUs 32 * o DDR5 capable APUs 33 * o DDR5 capable CPUs 34 * 35 * In general for a given revision and generation of a controller (DDR4 vs. 36 * DDR5), all of the address layouts are the same whether it is for an APU or a 37 * CPU. The main difference is generally in the number of features. For example, 38 * most APUs may not support the same rank multiplication bits and related in a 39 * device. However, unlike the DF where everything changes, the main difference 40 * within a generation is just which bits are implemented. This makes it much 41 * easier to define UMC information. 42 * 43 * Between DDR4 and DDR5 based devices, the register locations have shifted; 44 * however, generally speaking, the registers themselves are actually the same. 45 * Registers here, similar to the DF, have a common form: 46 * 47 * UMC_<reg name>_<vers> 48 * 49 * Here, <reg name> would be something like 'BASE', for the UMC 50 * UMC::CH::BaseAddr register. <vers> is one of DDR4 or DDR5. When the same 51 * register is supported at the same address between versions, then <vers> is 52 * elided. 53 * 54 * For fields inside of these registers, everything follows the same pattern in 55 * <sys/amdzen/df.h> which is: 56 * 57 * UMC_<reg name>_<vers>_GET_<field> 58 * 59 * Note, <vers> will be elided if the register is the same between the DDR4 and 60 * DDR5 versions. 61 * 62 * Finally, a cautionary note. While the DF provided a way for us to determine 63 * what version something is, we have not determined a way to programmatically 64 * determine what something supports outside of making notes based on the 65 * family, model, and stepping CPUID information. Unfortunately, you must look 66 * towards the documentation and find what you need in the PPR (processor 67 * programming reference). 68 */ 69 70 #ifdef __cplusplus 71 extern "C" { 72 #endif 73 74 /* 75 * UMC Channel registers. These are in SMN Space. DDR4 and DDR5 based UMCs share 76 * the same base address, somewhat surprisingly. This constructs the appropriate 77 * offset and ensures that a caller doesn't exceed the number of known instances 78 * of the register. 79 */ 80 static inline uint32_t 81 amdzen_umc_smn_addr(uint8_t umcno, uint32_t base_reg, uint32_t nents, 82 uint32_t reginst) 83 { 84 ASSERT3U(umcno, <, 12); 85 ASSERT3U(nents, >, reginst); 86 87 uint32_t base = 0x50000; 88 uint32_t reg = base_reg + reginst * 4; 89 return ((umcno << 20) + base + reg); 90 } 91 92 /* 93 * UMC::CH::BaseAddr, UMC::CH::BaseAddrSec -- determines the base address used 94 * to match a chip select. Instances 0/1 always refer to DIMM 0, while 95 * instances 2/3 always refer to DIMM 1. 96 */ 97 #define UMC_BASE(u, i) amdzen_umc_smn_addr(u, 0x00, 4, i) 98 #define UMC_BASE_SEC(u, i) amdzen_umc_smn_addr(u, 0x10, 4, i) 99 #define UMC_BASE_GET_ADDR(r) bitx32(r, 31, 1) 100 #define UMC_BASE_ADDR_SHIFT 9 101 #define UMC_BASE_GET_EN(r) bitx32(r, 0, 0) 102 103 /* 104 * UMC::BaseAddrExt, UMC::BaseAddrSecExt -- The first of several extensions to 105 * registers that allow more address bits. Note, only present in some DDR5 106 * capable SoCs. 107 */ 108 #define UMC_BASE_EXT_DDR5(u, i) amdzen_umc_smn_addr(u, 0xb00, 4, i) 109 #define UMC_BASE_EXT_SEC_DDR5(u, i) amdzen_umc_smn_addr(u, 0xb10, 4, i) 110 #define UMC_BASE_EXT_GET_ADDR(r) bitx32(r, 7, 0) 111 #define UMC_BASE_EXT_ADDR_SHIFT 40 112 113 114 /* 115 * UMC::CH::AddrMask, UMC::CH::AddrMaskSec -- This register is used to compare 116 * the incoming address to see it matches the base. Tweaking what is used for 117 * match is often part of the interleaving strategy. 118 */ 119 #define UMC_MASK_DDR4(u, i) amdzen_umc_smn_addr(u, 0x20, 2, i) 120 #define UMC_MASK_SEC_DDR4(u, i) amdzen_umc_smn_addr(u, 0x28, 2, i) 121 #define UMC_MASK_DDR5(u, i) amdzen_umc_smn_addr(u, 0x20, 4, i) 122 #define UMC_MASK_SEC_DDR5(u, i) amdzen_umc_smn_addr(u, 0x30, 4, i) 123 #define UMC_MASK_GET_ADDR(r) bitx32(r, 31, 1) 124 #define UMC_MASK_ADDR_SHIFT 9 125 126 /* 127 * UMC::AddrMaskExt, UMC::AddrMaskSecExt -- Extended mask addresses. 128 */ 129 #define UMC_MASK_EXT_DDR5(u, i) amdzen_umc_smn_addr(u, 0xb20, 4, i) 130 #define UMC_MASK_EXT_SEC_DDR5(u, i) amdzen_umc_smn_addr(u, 0xb30, 4, i) 131 #define UMC_MASK_EXT_GET_ADDR(r) bitx32(r, 7, 0) 132 #define UMC_MASK_EXT_ADDR_SHIFT 40 133 134 /* 135 * UMC::CH::AddrCfg -- This register contains a number of bits that describe how 136 * the address is actually used, one per DIMM. Note, not all members are valid 137 * for all classes of DIMMs. It's worth calling out that the total number of 138 * banks value here describes the total number of banks on the entire chip, e.g. 139 * it is bank groups * banks/groups. Therefore to determine the number of 140 * banks/group you must subtract the number of bank group bits from the total 141 * number of bank bits. 142 */ 143 #define UMC_ADDRCFG_DDR4(u, i) amdzen_umc_smn_addr(u, 0x30, 2, i) 144 #define UMC_ADDRCFG_DDR5(u, i) amdzen_umc_smn_addr(u, 0x40, 4, i) 145 #define UMC_ADDRCFG_GET_NBANK_BITS(r) bitx32(r, 21, 20) 146 #define UMC_ADDRCFG_NBANK_BITS_BASE 3 147 #define UMC_ADDRCFG_GET_NCOL_BITS(r) bitx32(r, 19, 16) 148 #define UMC_ADDRCFG_NCOL_BITS_BASE 5 149 #define UMC_ADDRCFG_GET_NROW_BITS_LO(r) bitx32(r, 11, 8) 150 #define UMC_ADDRCFG_NROW_BITS_LO_BASE 10 151 #define UMC_ADDRCFG_GET_NBANKGRP_BITS(r) bitx32(r, 3, 2) 152 153 #define UMC_ADDRCFG_DDR4_GET_NROW_BITS_HI(r) bitx32(r, 15, 12) 154 #define UMC_ADDRCFG_DDR4_GET_NRM_BITS(r) bitx32(r, 5, 4) 155 #define UMC_ADDRCFG_DDR5_GET_CSXOR(r) bitx32(r, 31, 30) 156 #define UMC_ADDRCFG_DDR5_GET_NRM_BITS(r) bitx32(r, 6, 4) 157 158 /* 159 * UMC::CH::AddrSel -- This register is used to program how the actual bits in 160 * the normalized address map to the row and bank. While the bank can select 161 * which bits in the normalized address are used to construct the bank number, 162 * row bits are contiguous from the starting number. 163 */ 164 #define UMC_ADDRSEL_DDR4(u, i) amdzen_umc_smn_addr(u, 0x40, 2, i) 165 #define UMC_ADDRSEL_DDR5(u, i) amdzen_umc_smn_addr(u, 0x50, 4, i) 166 #define UMC_ADDRSEL_GET_ROW_LO(r) bitx32(r, 27, 24) 167 #define UMC_ADDRSEL_ROW_LO_BASE 12 168 #define UMC_ADDRSEL_GET_BANK4(r) bitx32(r, 19, 16) 169 #define UMC_ADDRSEL_GET_BANK3(r) bitx32(r, 15, 12) 170 #define UMC_ADDRSEL_GET_BANK2(r) bitx32(r, 11, 8) 171 #define UMC_ADDRSEL_GET_BANK1(r) bitx32(r, 7, 4) 172 #define UMC_ADDRSEL_GET_BANK0(r) bitx32(r, 3, 0) 173 #define UMC_ADDRSEL_BANK_BASE 5 174 175 #define UMC_ADDRSEL_DDR4_GET_ROW_HI(r) bitx32(r, 31, 28) 176 #define UMC_ADDRSEL_DDR4_ROW_HI_BASE 24 177 178 /* 179 * UMC::CH::ColSelLo, UMC::CH::ColSelHi -- This register selects which address 180 * bits map to the various column select bits. These registers interleave so in 181 * the case of DDR4, it's 0x50, 0x54 for DIMM 0 lo, hi. Then 0x58, 0x5c for 182 * DIMM1. DDR5 based entries do something similar; however, instead of being 183 * per-DIMM, there is one of these for each CS. 184 * 185 * This leads to a somewhat odder construction for the maximum number of 186 * instances. Because amdzen_umc_smn_addr() assumes each register instance is 4 187 * bytes apart, we instead take the actual register instance and multiply it by 188 * 2. This means that in the DDR4 case we will always access what 189 * amdzen_umc_smn_addr() considers instance 0 and 2. In the DDR5 case this is 0, 190 * 2, 4, and 6. This means our maximum instance for both cases has to be one 191 * higher than this, 3 and 7 respectively. While technically you could use 4 and 192 * 8, this is a tighter bind. 193 */ 194 #define UMC_COLSEL_LO_DDR4(u, i) amdzen_umc_smn_addr(u, 0x50, 3, i * 2) 195 #define UMC_COLSEL_HI_DDR4(u, i) amdzen_umc_smn_addr(u, 0x54, 3, i * 2) 196 #define UMC_COLSEL_LO_DDR5(u, i) amdzen_umc_smn_addr(u, 0x60, 7, i * 2) 197 #define UMC_COLSEL_HI_DDR5(u, i) amdzen_umc_smn_addr(u, 0x64, 7, i * 2) 198 199 #define UMC_COLSEL_REMAP_GET_COL(r, x) bitx32(r, (3 + (4 * (x))), (4 * ((x)))) 200 #define UMC_COLSEL_LO_BASE 2 201 #define UMC_COLSEL_HI_BASE 8 202 203 /* 204 * UMC::CH::RmSel -- This register contains the bits that determine how the rank 205 * is determined. Which fields of this are valid vary a lot in the different 206 * parts. The DDR4 and DDR5 versions are different enough that we use totally 207 * disjoint definitions. It's also worth noting that DDR5 doesn't have a 208 * secondary version of this as it is included in the main register. 209 * 210 * In general, APUs have some of the MSBS (most significant bit swap) related 211 * fields; however, they do not have rank multiplication bits. 212 */ 213 #define UMC_RMSEL_DDR4(u, i) amdzen_umc_smn_addr(u, 0x70, 2, i) 214 #define UMC_RMSEL_SEC_DDR4(u, i) amdzen_umc_smn_addr(u, 0x78, 2, i) 215 #define UMC_RMSEL_DDR4_GET_INV_MSBO(r) bitx32(r, 19, 18) 216 #define UMC_RMSEL_DDR4_GET_INV_MSBE(r) bitx32(r, 17, 16) 217 #define UMC_RMSEL_DDR4_GET_RM2(r) bitx32(r, 11, 8) 218 #define UMC_RMSEL_DDR4_GET_RM1(r) bitx32(r, 7, 4) 219 #define UMC_RMSEL_DDR4_GET_RM0(r) bitx32(r, 3, 0) 220 #define UMC_RMSEL_BASE 12 221 222 #define UMC_RMSEL_DDR5(u, i) amdzen_umc_smn_addr(u, 0x80, 4, i) 223 #define UMC_RMSEL_DDR5_GET_INV_MSBS_SEC(r) bitx32(r, 31, 30) 224 #define UMC_RMSEL_DDR5_GET_INV_MSBS(r) bitx32(r, 29, 28) 225 #define UMC_RMSEL_DDR5_GET_SUBCHAN(r) bitx32(r, 19, 16) 226 #define UMC_RMSEL_DDR5_SUBCHAN_BASE 5 227 #define UMC_RMSEL_DDR5_GET_RM3(r) bitx32(r, 15, 12) 228 #define UMC_RMSEL_DDR5_GET_RM2(r) bitx32(r, 11, 8) 229 #define UMC_RMSEL_DDR5_GET_RM1(r) bitx32(r, 7, 4) 230 #define UMC_RMSEL_DDR5_GET_RM0(r) bitx32(r, 3, 0) 231 232 233 /* 234 * UMC::CH::DimmCfg -- This describes several properties of the DIMM that is 235 * installed, such as its overall width or type. 236 */ 237 #define UMC_DIMMCFG_DDR4(u, i) amdzen_umc_smn_addr(u, 0x80, 2, i) 238 #define UMC_DIMMCFG_DDR5(u, i) amdzen_umc_smn_addr(u, 0x90, 2, i) 239 #define UMC_DIMMCFG_GET_PKG_RALIGN(r) bitx32(r, 10, 10) 240 #define UMC_DIMMCFG_GET_REFRESH_DIS(r) bitx32(r, 9, 9) 241 #define UMC_DIMMCFG_GET_DQ_SWAP_DIS(r) bitx32(r, 8, 8) 242 #define UMC_DIMMCFG_GET_X16(r) bitx32(r, 7, 7) 243 #define UMC_DIMMCFG_GET_X4(r) bitx32(r, 6, 6) 244 #define UMC_DIMMCFG_GET_LRDIMM(r) bitx32(r, 5, 5) 245 #define UMC_DIMMCFG_GET_RDIMM(r) bitx32(r, 4, 4) 246 #define UMC_DIMMCFG_GET_CISCS(r) bitx32(r, 3, 3) 247 #define UMC_DIMMCFG_GET_3DS(r) bitx32(r, 2, 2) 248 249 #define UMC_DIMMCFG_DDR4_GET_NVDIMMP(r) bitx32(r, 12, 12) 250 #define UMC_DIMMCFG_DDR4_GET_DDR4e(r) bitx32(r, 11, 11) 251 #define UMC_DIMMCFG_DDR5_GET_RALIGN(r) bitx32(r, 13, 12) 252 #define UMC_DIMMCFG_DDR5_GET_ASYM(r) bitx32(r, 11, 11) 253 254 #define UMC_DIMMCFG_DDR4_GET_OUTPUT_INV(r) bitx32(r, 1, 1) 255 #define UMC_DIMMCFG_DDR4_GET_MRS_MIRROR(r) bitx32(r, 0, 0) 256 257 /* 258 * UMC::CH::AddrHashBank -- These registers contain various instructions about 259 * how to hash an address across a bank to influence which bank is used. 260 */ 261 #define UMC_BANK_HASH_DDR4(u, i) amdzen_umc_smn_addr(u, 0xc8, 5, i) 262 #define UMC_BANK_HASH_DDR5(u, i) amdzen_umc_smn_addr(u, 0x98, 5, i) 263 #define UMC_BANK_HASH_GET_ROW(r) bitx32(r, 31, 14) 264 #define UMC_BANK_HASH_GET_COL(r) bitx32(r, 13, 1) 265 #define UMC_BANK_HASH_GET_EN(r) bitx32(r, 0, 0) 266 267 /* 268 * UMC::CH::AddrHashRM -- This hash register describes how to transform a UMC 269 * address when trying to do rank hashing. Note, instance 3 is is reserved in 270 * DDR5 modes. 271 */ 272 #define UMC_RANK_HASH_DDR4(u, i) amdzen_umc_smn_addr(u, 0xdc, 3, i) 273 #define UMC_RANK_HASH_DDR5(u, i) amdzen_umc_smn_addr(u, 0xb0, 4, i) 274 #define UMC_RANK_HASH_GET_ADDR(r) bitx32(r, 31, 1) 275 #define UMC_RANK_HASH_SHIFT 9 276 #define UMC_RANK_HASH_GET_EN(r) bitx32(r, 0, 0) 277 278 /* 279 * UMC::AddrHashRMExt -- Extended rank hash addresses. 280 */ 281 #define UMC_RANK_HASH_EXT_DDR5(u, i) amdzen_umc_smn_addr(u, 0xbb0, 4, i) 282 #define UMC_RANK_HASH_EXT_GET_ADDR(r) bitx32(r, 7, 0) 283 #define UMC_RANK_HASH_EXT_ADDR_SHIFT 40 284 285 /* 286 * UMC::CH::AddrHashPC, UMC::CH::AddrHashPC2 -- These registers describe a hash 287 * to use for the DDR5 sub-channel. Note, in the DDR4 case this is actually the 288 * upper two rank hash registers defined above because on the systems where this 289 * occurs for DDR4, they only have up to one rank hash. 290 */ 291 #define UMC_PC_HASH_DDR4(u) UMC_RANK_HASH_DDR4(u, 1) 292 #define UMC_PC_HASH2_DDR4(u) UMC_RANK_HASH_DDR4(u, 2) 293 #define UMC_PC_HASH_DDR5(u) amdzen_umc_smn_addr(u, 0xc0, 1, 0) 294 #define UMC_PC_HASH2_DDR5(u) amdzen_umc_smn_addr(u, 0xc4, 1, 0) 295 #define UMC_PC_HASH_GET_ROW(r) bitx32(r, 31, 14) 296 #define UMC_PC_HASH_GET_COL(r) bitx32(r, 13, 1) 297 #define UMC_PC_HASH_GET_EN(r) bitx32(r, 0, 0) 298 #define UMC_PC_HASH2_GET_BANK(r) bitx32(r, 4, 0) 299 300 /* 301 * UMC::CH::AddrHashCS -- Hashing: chip-select edition. Note, these can 302 * ultimately cause you to change which DIMM is being actually accessed. 303 */ 304 #define UMC_CS_HASH_DDR4(u, i) amdzen_umc_smn_addr(u, 0xe8, 2, i) 305 #define UMC_CS_HASH_DDR5(u, i) amdzen_umc_smn_addr(u, 0xc8, 2, i) 306 #define UMC_CS_HASH_GET_ADDR(r) bitx32(r, 31, 1) 307 #define UMC_CS_HASH_SHIFT 9 308 #define UMC_CS_HASH_GET_EN(r) bitx32(r, 0, 0) 309 310 /* 311 * UMC::AddrHashExtCS -- Extended chip-select hash addresses. 312 */ 313 #define UMC_CS_HASH_EXT_DDR5(u, i) amdzen_umc_smn_addr(u, 0xbc8, 2, i) 314 #define UMC_CS_HASH_EXT_GET_ADDR(r) bitx32(r, 7, 0) 315 #define UMC_CS_HASH_EXT_ADDR_SHIFT 40 316 317 /* 318 * UMC::CH::UmcConfig -- This register controls various features of the device. 319 * For our purposes we mostly care about seeing if ECC is enabled and a DIMM 320 * type. 321 */ 322 #define UMC_UMCCFG(u) amdzen_umc_smn_addr(u, 0x100, 1, 0) 323 #define UMC_UMCCFG_GET_READY(r) bitx32(r, 31, 31) 324 #define UMC_UMCCFG_GET_ECC_EN(r) bitx32(r, 12, 12) 325 #define UMC_UMCCFG_GET_BURST_CTL(r) bitx32(r, 11, 10) 326 #define UMC_UMCCFG_GET_BURST_LEN(r) bitx32(r, 9, 8) 327 #define UMC_UMCCFG_GET_DDR_TYPE(r) bitx32(r, 2, 0) 328 #define UMC_UMCCFG_DDR4_T_DDR4 0 329 #define UMC_UMCCFG_DDR4_T_LPDDR4 5 330 331 #define UMC_UMCCFG_DDR5_T_DDR4 0 332 #define UMC_UMCCFG_DDR5_T_DDR5 1 333 #define UMC_UMCCFG_DDR5_T_LPDDR4 5 334 #define UMC_UMCCFG_DDR5_T_LPDDR5 6 335 336 /* 337 * UMC::CH::DataCtrl -- Various settings around whether data encryption or 338 * scrambling is enabled. Note, this register really changes a bunch from family 339 * to family. 340 */ 341 #define UMC_DATACTL(u) amdzen_umc_smn_addr(u, 0x144, 1, 0) 342 #define UMC_DATACTL_GET_ENCR_EN(r) bitx32(r, 8, 8) 343 #define UMC_DATACTL_GET_SCRAM_EN(r) bitx32(r, 0, 0) 344 345 #define UMC_DATACTL_DDR4_GET_TWEAK(r) bitx32(r, 19, 16) 346 #define UMC_DATACTL_DDR4_GET_VMG2M(r) bitx32(r, 12, 12) 347 #define UMC_DATACTL_DDR4_GET_FORCE_ENCR(r) bitx32(r, 11, 11) 348 349 #define UMC_DATACTL_DDR5_GET_TWEAK(r) bitx32(r, 16, 16) 350 #define UMC_DATACTL_DDR5_GET_XTS(r) bitx32(r, 14, 14) 351 #define UMC_DATACTL_DDR5_GET_AES256(r) bitx32(r, 13, 13) 352 353 /* 354 * UMC::CH:EccCtrl -- Various settings around how ECC operates. 355 */ 356 #define UMC_ECCCTL(u) amdzen_umc_smn_addr(u, 0x14c, 1, 0) 357 #define UMC_ECCCTL_GET_RD_EN(r) bitx32(x, 10, 10) 358 #define UMC_ECCCTL_GET_X16(r) bitx32(x, 9, 9) 359 #define UMC_ECCCTL_GET_UC_FATAL(r) bitx32(x, 8, 8) 360 #define UMC_ECCCTL_GET_SYM_SIZE(r) bitx32(x, 7, 7) 361 #define UMC_ECCCTL_GET_BIT_IL(r) bitx32(x, 6, 6) 362 #define UMC_ECCCTL_GET_HIST_EN(r) bitx32(x, 5, 5) 363 #define UMC_ECCCTL_GET_SW_SYM_EN(r) bitx32(x, 4, 4) 364 #define UMC_ECCCTL_GET_WR_EN(r) bitx32(x, 0, 0) 365 366 /* 367 * Note, while this group appears generic and is the same in both DDR4/DDR5 368 * systems, this is not always present on every SoC and seems to depend on 369 * something else inside the chip. 370 */ 371 #define UMC_ECCCTL_DDR_GET_PI(r) bitx32(r, 13, 13) 372 #define UMC_ECCCTL_DDR_GET_PF_DIS(r) bitx32(r, 12, 12) 373 #define UMC_ECCCTL_DDR_GET_SDP_OVR(r) bitx32(x, 11, 11) 374 #define UMC_ECCCTL_DDR_GET_REPLAY_EN(r) bitx32(x, 1, 1) 375 376 #define UMC_ECCCTL_DDR5_GET_PIN_RED(r) bitx32(r, 14, 14) 377 378 /* 379 * UMC::Ch::UmcCap, UMC::CH::UmcCapHi -- Various capability registers and 380 * feature disables. We mostly just record these for future us for debugging 381 * purposes. They aren't used as part of memory decoding. 382 */ 383 #define UMC_UMCCAP(u) amdzen_umc_smn_addr(u, 0xdf0, 1, 0) 384 #define UMC_UMCCAP_HI(u) amdzen_umc_smn_addr(u, 0xdf4, 1, 0) 385 386 #ifdef __cplusplus 387 } 388 #endif 389 390 #endif /* _SYS_UMC_H */ 391