17aec1d6eScindi /* 27aec1d6eScindi * CDDL HEADER START 37aec1d6eScindi * 47aec1d6eScindi * The contents of this file are subject to the terms of the 58a40a695Sgavinm * Common Development and Distribution License (the "License"). 68a40a695Sgavinm * You may not use this file except in compliance with the License. 77aec1d6eScindi * 87aec1d6eScindi * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97aec1d6eScindi * or http://www.opensolaris.org/os/licensing. 107aec1d6eScindi * See the License for the specific language governing permissions 117aec1d6eScindi * and limitations under the License. 127aec1d6eScindi * 137aec1d6eScindi * When distributing Covered Code, include this CDDL HEADER in each 147aec1d6eScindi * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157aec1d6eScindi * If applicable, add the following below this CDDL HEADER, with the 167aec1d6eScindi * fields enclosed by brackets "[]" replaced with your own identifying 177aec1d6eScindi * information: Portions Copyright [yyyy] [name of copyright owner] 187aec1d6eScindi * 197aec1d6eScindi * CDDL HEADER END 207aec1d6eScindi * 217aec1d6eScindi * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 227aec1d6eScindi * Use is subject to license terms. 237aec1d6eScindi */ 247aec1d6eScindi 257aec1d6eScindi #ifndef _MC_AMD_H 267aec1d6eScindi #define _MC_AMD_H 277aec1d6eScindi 287aec1d6eScindi #pragma ident "%Z%%M% %I% %E% SMI" 297aec1d6eScindi 308a40a695Sgavinm #include <sys/mc.h> 318a40a695Sgavinm #include <sys/x86_archext.h> 328a40a695Sgavinm 338a40a695Sgavinm /* 348a40a695Sgavinm * The mc-amd driver exports an nvlist to userland, where the primary 358a40a695Sgavinm * consumer is the "chip" topology enumerator for this platform type which 368a40a695Sgavinm * builds a full topology subtree from this information. Others can use 37*4156fc34Sgavinm * it, too, but don't depend on it not changing without an ARC contract 38*4156fc34Sgavinm * (and the contract should probably concern the topology, not this nvlist). 398a40a695Sgavinm * 408a40a695Sgavinm * In the initial mc-amd implementation this nvlist was not versioned; 418a40a695Sgavinm * we'll think of that as version 0 and it may be recognised by the absence 428a40a695Sgavinm * of a "mcamd-nvlist-version member. 438a40a695Sgavinm * 448a40a695Sgavinm * Version 1 is defined as follows. A name in square brackets indicates 458a40a695Sgavinm * that member is optional (only present if the actual value is valid). 468a40a695Sgavinm * 478a40a695Sgavinm * Name Type Description 488a40a695Sgavinm * -------------------- --------------- --------------------------------------- 498a40a695Sgavinm * mcamd-nvlist-version uint8 Exported nvlist version number 508a40a695Sgavinm * num uint64 Chip id of this memory controller 518a40a695Sgavinm * revision uint64 cpuid_getchiprev() result 528a40a695Sgavinm * revname string cpuid_getchiprevstr() result 538a40a695Sgavinm * socket string "Socket 755|939|940|AM2|F(1207)|S1g1" 548a40a695Sgavinm * ecc-type string "ChipKill 128/16" or "Normal 64/8" 558a40a695Sgavinm * base-addr uint64 Node base address 568a40a695Sgavinm * lim-addr uint64 Node limit address 578a40a695Sgavinm * node-ilen uint64 0|1|3|7 for 0/2/4/8 way node interleave 588a40a695Sgavinm * node-ilsel uint64 Node interleave position of this node 598a40a695Sgavinm * cs-intlv-factor uint64 chip-select interleave: 1/2/4/8 608a40a695Sgavinm * dram-hole-size uint64 size in bytes from dram hole addr reg 618a40a695Sgavinm * access-width uint64 MC mode, 64 or 128 bit 628a40a695Sgavinm * bank-mapping uint64 Raw DRAM Bank Address Mapping Register 638a40a695Sgavinm * bankswizzle uint64 1 if bank swizzling enabled; else 0 648a40a695Sgavinm * mismatched-dimm-support uint64 1 if active; else 0 658a40a695Sgavinm * [spare-csnum] uint64 Chip-select pair number of any spare 668a40a695Sgavinm * [bad-csnum] uint64 Chip-select pair number of swapped cs 678a40a695Sgavinm * cslist nvlist array See below; may have 0 members 688a40a695Sgavinm * dimmlist nvlist array See below; may have 0 members 698a40a695Sgavinm * 708a40a695Sgavinm * cslist is an array of nvlist, each as follows: 718a40a695Sgavinm * 728a40a695Sgavinm * Name Type Description 738a40a695Sgavinm * -------------------- --------------- --------------------------------------- 748a40a695Sgavinm * num uint64 Chip-select base/mask pair number 758a40a695Sgavinm * base-addr uint64 Chip-select base address (rel to node) 768a40a695Sgavinm * mask uint64 Chip-select mask 778a40a695Sgavinm * size uint64 Chip-select size in bytes 788a40a695Sgavinm * dimm1-num uint64 First dimm (lodimm if a pair) 798a40a695Sgavinm * dimm1-csname string Socket cs# line name for 1st dimm rank 808a40a695Sgavinm * [dimm2-num] uint64 Second dimm if applicable (updimm) 818a40a695Sgavinm * [dimm2-csname] string Socket cs# line name for 2nd dimm rank 828a40a695Sgavinm * 838a40a695Sgavinm * dimmlist is an array of nvlist, each as follows: 848a40a695Sgavinm * 858a40a695Sgavinm * Name Type Description 868a40a695Sgavinm * -------------------- --------------- --------------------------------------- 878a40a695Sgavinm * num uint64 DIMM instance number 888a40a695Sgavinm * size uint64 DIMM size in bytes 898a40a695Sgavinm * csnums uint64 array CS base/mask pair(s) on this DIMM 908a40a695Sgavinm * csnames string array Socket cs# line name(s) on this DIMM 918a40a695Sgavinm * 928a40a695Sgavinm * The n'th csnums entry corresponds to the n'th csnames entry 938a40a695Sgavinm */ 948a40a695Sgavinm #define MC_NVLIST_VERSTR "mcamd-nvlist-version" 958a40a695Sgavinm #define MC_NVLIST_VERS0 0 968a40a695Sgavinm #define MC_NVLIST_VERS1 1 978a40a695Sgavinm #define MC_NVLIST_VERS MC_NVLIST_VERS1 988a40a695Sgavinm 997aec1d6eScindi /* 1007aec1d6eScindi * Definitions describing various memory controller constant properties and 1017aec1d6eScindi * the structure of configuration registers. 1027aec1d6eScindi */ 1037aec1d6eScindi 1047aec1d6eScindi #ifdef __cplusplus 1057aec1d6eScindi extern "C" { 1067aec1d6eScindi #endif 1077aec1d6eScindi 1088a40a695Sgavinm /* 1098a40a695Sgavinm * Constants and feature/revision test macros that are not expected to vary 1108a40a695Sgavinm * among different AMD family 0xf processor revisions. 1118a40a695Sgavinm */ 1128a40a695Sgavinm 1137aec1d6eScindi /* 1147aec1d6eScindi * Configuration constants 1157aec1d6eScindi */ 1168a40a695Sgavinm #define MC_CHIP_MAXNODES 8 /* max number of MCs in system */ 1177aec1d6eScindi #define MC_CHIP_NDIMM 8 /* max dimms per MC */ 1187aec1d6eScindi #define MC_CHIP_NCS 8 /* number of chip-selects per MC */ 1198a40a695Sgavinm #define MC_CHIP_NDRAMCHAN 2 /* maximum number of dram channels */ 1207aec1d6eScindi #define MC_CHIP_DIMMRANKMAX 4 /* largest number of ranks per dimm */ 1217aec1d6eScindi #define MC_CHIP_DIMMPERCS 2 /* max number of dimms per cs */ 1227aec1d6eScindi #define MC_CHIP_DIMMPAIR(csnum) (csnum / MC_CHIP_DIMMPERCS) 1237aec1d6eScindi 1248a40a695Sgavinm #if MC_CHIP_DIMMPERCS > MC_UNUM_NDIMM 1258a40a695Sgavinm #error "MC_CHIP_DIMMPERCS exceeds MC_UNUM_NDIMM" 1268a40a695Sgavinm #endif 1278a40a695Sgavinm 1288a40a695Sgavinm /* 1298a40a695Sgavinm * MC_REV_* are used a a convenient shorter form of the X86_CHIPREV 1308a40a695Sgavinm * counterparts; these must map directly as we fill mcp_rev from 1318a40a695Sgavinm * a cpuid_getchiprev call. 1328a40a695Sgavinm */ 1338a40a695Sgavinm #define MC_REV_UNKNOWN X86_CHIPREV_UNKNOWN 1348a40a695Sgavinm #define MC_REV_B X86_CHIPREV_AMD_F_REV_B 1358a40a695Sgavinm #define MC_REV_C (X86_CHIPREV_AMD_F_REV_C0 | X86_CHIPREV_AMD_F_REV_CG) 1368a40a695Sgavinm #define MC_REV_D X86_CHIPREV_AMD_F_REV_D 1378a40a695Sgavinm #define MC_REV_E X86_CHIPREV_AMD_F_REV_E 1388a40a695Sgavinm #define MC_REV_F X86_CHIPREV_AMD_F_REV_F 1398a40a695Sgavinm #define MC_REV_G X86_CHIPREV_AMD_F_REV_G 1408a40a695Sgavinm 1417aec1d6eScindi /* 1428a40a695Sgavinm * The most common groupings for memory controller features. 1437aec1d6eScindi */ 1448a40a695Sgavinm #define MC_REVS_BC (MC_REV_B | MC_REV_C) 1458a40a695Sgavinm #define MC_REVS_DE (MC_REV_D | MC_REV_E) 1468a40a695Sgavinm #define MC_REVS_BCDE (MC_REVS_BC | MC_REVS_DE) 1478a40a695Sgavinm #define MC_REVS_FG (MC_REV_F | MC_REV_G) 1487aec1d6eScindi 1497aec1d6eScindi /* 1508a40a695Sgavinm * Is 'rev' included in the 'revmask' bitmask? 1517aec1d6eScindi */ 1528a40a695Sgavinm #define MC_REV_MATCH(rev, revmask) X86_CHIPREV_MATCH(rev, revmask) 1537aec1d6eScindi 1547aec1d6eScindi /* 1558a40a695Sgavinm * Is 'rev' at least revision 'revmin' or greater 1567aec1d6eScindi */ 1578a40a695Sgavinm #define MC_REV_ATLEAST(rev, minrev) X86_CHIPREV_ATLEAST(rev, minrev) 1587aec1d6eScindi 1597aec1d6eScindi /* 1608a40a695Sgavinm * Chip socket types 1618a40a695Sgavinm */ 1628a40a695Sgavinm #define MC_SKT_UNKNOWN 0x0 1638a40a695Sgavinm #define MC_SKT_754 0x1 1648a40a695Sgavinm #define MC_SKT_939 0x2 1658a40a695Sgavinm #define MC_SKT_940 0x3 1668a40a695Sgavinm #define MC_SKT_S1g1 0x4 1678a40a695Sgavinm #define MC_SKT_AM2 0x5 1688a40a695Sgavinm #define MC_SKT_F1207 0x6 1698a40a695Sgavinm 1708a40a695Sgavinm /* 1718a40a695Sgavinm * Memory controller registers are read via PCI config space accesses on 1728a40a695Sgavinm * bus 0, device 24 + NodeId, and function as follows: 1738a40a695Sgavinm * 1748a40a695Sgavinm * Function 0: HyperTransport Technology Configuration 1758a40a695Sgavinm * Function 1: Address Map 1768a40a695Sgavinm * Function 2: DRAM Controller & HyperTransport Technology Trace Mode 1778a40a695Sgavinm * Function 3: Miscellaneous Control 1788a40a695Sgavinm * 1798a40a695Sgavinm * For a given (bus, device, function) a particular offset selects the 1808a40a695Sgavinm * desired register. All registers are 32-bits wide. 1817aec1d6eScindi * 1828a40a695Sgavinm * Different family 0xf processor revisions vary slightly in the content 1838a40a695Sgavinm * of these configuration registers. The biggest change is with rev F 1848a40a695Sgavinm * where DDR2 support has been introduced along with some hardware-controlled 1858a40a695Sgavinm * correctable memory error thresholding. Fortunately most of the config info 1868a40a695Sgavinm * required by the mc-amd driver is similar across revisions. 1878a40a695Sgavinm * 1888a40a695Sgavinm * We will try to insulate most of the driver code from config register 1898a40a695Sgavinm * details by reading all memory-controller PCI config registers that we 1908a40a695Sgavinm * will need at driver attach time for each of functions 0 through 3, and 1918a40a695Sgavinm * storing them in a "cooked" form as memory controller properties. 1928a40a695Sgavinm * These are to be accessed directly where we have an mc_t to hand, otherwise 1938a40a695Sgavinm * through mcamd_get_numprop. As such we expect most/all use of the 1948a40a695Sgavinm * structures and macros defined below to be in those attach codepaths. 1957aec1d6eScindi */ 1967aec1d6eScindi 1978a40a695Sgavinm /* 1988a40a695Sgavinm * Registers will be represented as unions, with one fixed-width unsigned 1998a40a695Sgavinm * integer member providing access to the raw register value and one or more 2008a40a695Sgavinm * structs breaking the register out into bitfields (more than one struct if 2018a40a695Sgavinm * the register definitions varies across processor revisions). 2028a40a695Sgavinm * 2038a40a695Sgavinm * The "raw" union member will always be '_val32'. Use MCREG_VAL32 to 2048a40a695Sgavinm * access this member. 2058a40a695Sgavinm * 2068a40a695Sgavinm * The bitfield structs are all named _fmt_xxx where xxx identifies the 2078a40a695Sgavinm * processor revision to which it applies. At this point the only xxx 2088a40a695Sgavinm * values in use are: 2098a40a695Sgavinm * 'cmn' - applies to all revisions 2108a40a695Sgavinm * 'preF' - applies to revisions E and earlier 2118a40a695Sgavinm * 'revFG' - applies to revisions F and G 2128a40a695Sgavinm * Variants such as 'preD', 'revDE', 'postCG' etc should be introduced 2138a40a695Sgavinm * as requirements arise. The MC_REV_* and MC_REV_MATCH etc macros 2148a40a695Sgavinm * will also need to grow to match. Use MCREG_FIELD_* to access the 2158a40a695Sgavinm * individual bitfields of a register, perhaps using MC_REV_* and MC_REV_MATCH 2168a40a695Sgavinm * to decide which revision suffix to provide. Where a bitfield appears 2178a40a695Sgavinm * in different revisions but has the same use it should be named identically 2188a40a695Sgavinm * (even if the BKDG varies a little) so that the MC_REG_FIELD_* macros 2198a40a695Sgavinm * can lookup that member based on revision only. 2208a40a695Sgavinm */ 2217aec1d6eScindi 2228a40a695Sgavinm #define _MCREG_FIELD(up, revsuffix, field) ((up)->_fmt_##revsuffix.field) 2237aec1d6eScindi 2248a40a695Sgavinm #define MCREG_VAL32(up) ((up)->_val32) 2258a40a695Sgavinm 2268a40a695Sgavinm #define MCREG_FIELD_CMN(up, field) _MCREG_FIELD(up, cmn, field) 2278a40a695Sgavinm #define MCREG_FIELD_preF(up, field) _MCREG_FIELD(up, preF, field) 2288a40a695Sgavinm #define MCREG_FIELD_revFG(up, field) _MCREG_FIELD(up, revFG, field) 2297aec1d6eScindi 2307aec1d6eScindi /* 2318a40a695Sgavinm * Function 1 - DRAM Address Map: DRAM Base i Registers 2327aec1d6eScindi * 2337aec1d6eScindi */ 2347aec1d6eScindi 2358a40a695Sgavinm union mcreg_drambase { 2368a40a695Sgavinm uint32_t _val32; 2378a40a695Sgavinm struct { 2388a40a695Sgavinm uint32_t RE:1; /* 0:0 - Read Enable */ 2398a40a695Sgavinm uint32_t WE:1; /* 1:1 - Write Enable */ 2408a40a695Sgavinm uint32_t reserved1:6; /* 7:2 */ 2418a40a695Sgavinm uint32_t IntlvEn:3; /* 10:8 - Interleave Enable */ 2428a40a695Sgavinm uint32_t reserved2:5; /* 15:11 */ 2438a40a695Sgavinm uint32_t DRAMBasei:16; /* 31:16 - Base Addr 39:24 */ 2448a40a695Sgavinm } _fmt_cmn; 2458a40a695Sgavinm }; 2468a40a695Sgavinm 2478a40a695Sgavinm #define MC_DRAMBASE(up) ((uint64_t)MCREG_FIELD_CMN(up, DRAMBasei) << 24) 2488a40a695Sgavinm 2498a40a695Sgavinm /* 2508a40a695Sgavinm * Function 1 - DRAM Address Map: DRAM Limit i Registers 2518a40a695Sgavinm * 2528a40a695Sgavinm */ 2538a40a695Sgavinm 2548a40a695Sgavinm union mcreg_dramlimit { 2558a40a695Sgavinm uint32_t _val32; 2568a40a695Sgavinm struct { 2578a40a695Sgavinm uint32_t DstNode:3; /* 2:0 - Destination Node */ 2588a40a695Sgavinm uint32_t reserved1:5; /* 7:3 */ 2598a40a695Sgavinm uint32_t IntlvSel:3; /* 10:8 - Interleave Select */ 2608a40a695Sgavinm uint32_t reserved2:5; /* 15:11 */ 2618a40a695Sgavinm uint32_t DRAMLimiti:16; /* 31:16 - Limit Addr 39:24 */ 2628a40a695Sgavinm } _fmt_cmn; 2638a40a695Sgavinm }; 2648a40a695Sgavinm 2658a40a695Sgavinm #define MC_DRAMLIM(up) \ 2668a40a695Sgavinm ((uint64_t)MCREG_FIELD_CMN(up, DRAMLimiti) << 24 | \ 2678a40a695Sgavinm (MCREG_FIELD_CMN(up, DRAMLimiti) ? ((1 << 24) - 1) : 0)) 2688a40a695Sgavinm 2698a40a695Sgavinm /* 2708a40a695Sgavinm * Function 1 - DRAM Address Map: DRAM Hole Address Register 2718a40a695Sgavinm */ 2728a40a695Sgavinm 2738a40a695Sgavinm union mcreg_dramhole { 2748a40a695Sgavinm uint32_t _val32; 2758a40a695Sgavinm struct { 2768a40a695Sgavinm uint32_t DramHoleValid:1; /* 0:0 */ 2778a40a695Sgavinm uint32_t reserved1:7; /* 7:1 */ 2788a40a695Sgavinm uint32_t DramHoleOffset:8; /* 15:8 */ 2798a40a695Sgavinm uint32_t reserved2:8; /* 23:16 */ 2808a40a695Sgavinm uint32_t DramHoleBase:8; /* 31:24 */ 2818a40a695Sgavinm } _fmt_cmn; 2828a40a695Sgavinm }; 2838a40a695Sgavinm 2848a40a695Sgavinm #define MC_DRAMHOLE_SIZE(up) (MCREG_FIELD_CMN(up, DramHoleOffset) << 24) 2858a40a695Sgavinm 2868a40a695Sgavinm /* 2878a40a695Sgavinm * Function 2 - DRAM Controller: DRAM CS Base Address Registers 2888a40a695Sgavinm */ 2898a40a695Sgavinm 2908a40a695Sgavinm union mcreg_csbase { 2918a40a695Sgavinm uint32_t _val32; 2928a40a695Sgavinm /* 2938a40a695Sgavinm * Register format in revisions E and earlier 2948a40a695Sgavinm */ 2958a40a695Sgavinm struct { 2968a40a695Sgavinm uint32_t CSEnable:1; /* 0:0 - CS Bank Enable */ 2978a40a695Sgavinm uint32_t reserved1:8; /* 8:1 */ 2988a40a695Sgavinm uint32_t BaseAddrLo:7; /* 15:9 - Base Addr 19:13 */ 2998a40a695Sgavinm uint32_t reserved2:5; /* 20:16 */ 3008a40a695Sgavinm uint32_t BaseAddrHi:11; /* 31:21 - Base Addr 35:25 */ 3018a40a695Sgavinm } _fmt_preF; 3028a40a695Sgavinm /* 3038a40a695Sgavinm * Register format in revisions F and G 3048a40a695Sgavinm */ 3058a40a695Sgavinm struct { 3068a40a695Sgavinm uint32_t CSEnable:1; /* 0:0 - CS Bank Enable */ 3078a40a695Sgavinm uint32_t Spare:1; /* 1:1 - Spare Rank */ 3088a40a695Sgavinm uint32_t TestFail:1; /* 2:2 - Memory Test Failed */ 3098a40a695Sgavinm uint32_t reserved1:2; /* 4:3 */ 3108a40a695Sgavinm uint32_t BaseAddrLo:9; /* 13:5 - Base Addr 21:13 */ 3118a40a695Sgavinm uint32_t reserved2:5; /* 18:14 */ 3128a40a695Sgavinm uint32_t BaseAddrHi:10; /* 28:19 - Base Addr 36:27 */ 3138a40a695Sgavinm uint32_t reserved3:3; /* 31:39 */ 3148a40a695Sgavinm } _fmt_revFG; 3158a40a695Sgavinm }; 3168a40a695Sgavinm 317*4156fc34Sgavinm #define MC_CSBASE(up, rev) (MC_REV_MATCH(rev, MC_REVS_FG) ? \ 3188a40a695Sgavinm (uint64_t)MCREG_FIELD_revFG(up, BaseAddrHi) << 27 | \ 3198a40a695Sgavinm (uint64_t)MCREG_FIELD_revFG(up, BaseAddrLo) << 13 : \ 3208a40a695Sgavinm (uint64_t)MCREG_FIELD_preF(up, BaseAddrHi) << 25 | \ 3218a40a695Sgavinm (uint64_t)MCREG_FIELD_preF(up, BaseAddrLo) << 13) 3228a40a695Sgavinm 3238a40a695Sgavinm /* 3248a40a695Sgavinm * Function 2 - DRAM Controller: DRAM CS Mask Registers 3258a40a695Sgavinm */ 3268a40a695Sgavinm 3278a40a695Sgavinm union mcreg_csmask { 3288a40a695Sgavinm uint32_t _val32; 3298a40a695Sgavinm /* 3308a40a695Sgavinm * Register format in revisions E and earlier 3318a40a695Sgavinm */ 3328a40a695Sgavinm struct { 3338a40a695Sgavinm uint32_t reserved1:9; /* 8:0 */ 3348a40a695Sgavinm uint32_t AddrMaskLo:7; /* 15:9 - Addr Mask 19:13 */ 3358a40a695Sgavinm uint32_t reserved2:5; /* 20:16 */ 3368a40a695Sgavinm uint32_t AddrMaskHi:9; /* 29:21 - Addr Mask 33:25 */ 3378a40a695Sgavinm uint32_t reserved3:2; /* 31:30 */ 3388a40a695Sgavinm } _fmt_preF; 3398a40a695Sgavinm /* 3408a40a695Sgavinm * Register format in revisions F and G 3418a40a695Sgavinm */ 3428a40a695Sgavinm struct { 3438a40a695Sgavinm uint32_t reserved1:5; /* 4:0 */ 3448a40a695Sgavinm uint32_t AddrMaskLo:9; /* 13:5 - Addr Mask 21:13 */ 3458a40a695Sgavinm uint32_t reserved2:5; /* 18:14 */ 3468a40a695Sgavinm uint32_t AddrMaskHi:10; /* 28:19 - Addr Mask 36:27 */ 3478a40a695Sgavinm uint32_t reserved3:3; /* 31:29 */ 3488a40a695Sgavinm } _fmt_revFG; 3498a40a695Sgavinm }; 3507aec1d6eScindi 351*4156fc34Sgavinm #define MC_CSMASKLO_LOBIT(rev) (MC_REV_MATCH(rev, MC_REVS_FG) ? 13 : 13) 352*4156fc34Sgavinm #define MC_CSMASKLO_HIBIT(rev) (MC_REV_MATCH(rev, MC_REVS_FG) ? 21 : 19) 3537aec1d6eScindi 354*4156fc34Sgavinm #define MC_CSMASKHI_LOBIT(rev) (MC_REV_MATCH(rev, MC_REVS_FG) ? 27 : 25) 355*4156fc34Sgavinm #define MC_CSMASKHI_HIBIT(rev) (MC_REV_MATCH(rev, MC_REVS_FG) ? 36 : 33) 3567aec1d6eScindi 357*4156fc34Sgavinm #define MC_CSMASK_UNMASKABLE(rev) (MC_REV_MATCH(rev, MC_REVS_FG) ? 0 : 2) 3588a40a695Sgavinm 359*4156fc34Sgavinm #define MC_CSMASK(up, rev) (MC_REV_MATCH(rev, MC_REVS_FG) ? \ 3608a40a695Sgavinm (uint64_t)MCREG_FIELD_revFG(up, AddrMaskHi) << 27 | \ 3618a40a695Sgavinm (uint64_t)MCREG_FIELD_revFG(up, AddrMaskLo) << 13 | 0x7c01fff : \ 3628a40a695Sgavinm (uint64_t)MCREG_FIELD_preF(up, AddrMaskHi) << 25 | \ 3638a40a695Sgavinm (uint64_t)MCREG_FIELD_preF(up, AddrMaskLo) << 13 | 0x1f01fff) 3647aec1d6eScindi 3657aec1d6eScindi /* 3668a40a695Sgavinm * Function 2 - DRAM Controller: DRAM Bank Address Mapping Registers 3677aec1d6eScindi */ 3688a40a695Sgavinm 3698a40a695Sgavinm union mcreg_bankaddrmap { 3708a40a695Sgavinm uint32_t _val32; 3718a40a695Sgavinm /* 3728a40a695Sgavinm * Register format in revisions E and earlier 3738a40a695Sgavinm */ 3748a40a695Sgavinm struct { 3758a40a695Sgavinm uint32_t cs10:4; /* 3:0 - CS1/0 */ 3768a40a695Sgavinm uint32_t cs32:4; /* 7:4 - CS3/2 */ 3778a40a695Sgavinm uint32_t cs54:4; /* 11:8 - CS5/4 */ 3788a40a695Sgavinm uint32_t cs76:4; /* 15:12 - CS7/6 */ 3798a40a695Sgavinm uint32_t reserved1:14; /* 29:16 */ 3808a40a695Sgavinm uint32_t BankSwizzleMode:1; /* 30:30 */ 3818a40a695Sgavinm uint32_t reserved2:1; /* 31:31 */ 3828a40a695Sgavinm } _fmt_preF; 3838a40a695Sgavinm /* 3848a40a695Sgavinm * Register format in revisions F and G 3858a40a695Sgavinm */ 3868a40a695Sgavinm struct { 3878a40a695Sgavinm uint32_t cs10:4; /* 3:0 - CS1/0 */ 3888a40a695Sgavinm uint32_t cs32:4; /* 7:4 - CS3/2 */ 3898a40a695Sgavinm uint32_t cs54:4; /* 11:8 - CS5/4 */ 3908a40a695Sgavinm uint32_t cs76:4; /* 15:12 - CS7/6 */ 3918a40a695Sgavinm uint32_t reserved1:16; /* 31:16 */ 3928a40a695Sgavinm } _fmt_revFG; 3938a40a695Sgavinm /* 3948a40a695Sgavinm * Accessing all mode encodings as one uint16 3958a40a695Sgavinm */ 3968a40a695Sgavinm struct { 3978a40a695Sgavinm uint32_t allcsmodes:16; /* 15:0 */ 3988a40a695Sgavinm uint32_t pad:16; /* 31:16 */ 3998a40a695Sgavinm } _fmt_bankmodes; 4008a40a695Sgavinm }; 4018a40a695Sgavinm 4027aec1d6eScindi #define MC_DC_BAM_CSBANK_MASK 0x0000000f 4037aec1d6eScindi #define MC_DC_BAM_CSBANK_SHIFT 4 4048a40a695Sgavinm 4058a40a695Sgavinm #define MC_CSBANKMODE(up, csnum) ((up)->_fmt_bankmodes.allcsmodes >> \ 4068a40a695Sgavinm MC_DC_BAM_CSBANK_SHIFT * MC_CHIP_DIMMPAIR(csnum) & MC_DC_BAM_CSBANK_MASK) 4078a40a695Sgavinm 4088a40a695Sgavinm /* 4098a40a695Sgavinm * Function 2 - DRAM Controller: DRAM Configuration Low and High 4108a40a695Sgavinm */ 4118a40a695Sgavinm 4128a40a695Sgavinm union mcreg_dramcfg_lo { 4138a40a695Sgavinm uint32_t _val32; 4148a40a695Sgavinm /* 4158a40a695Sgavinm * Register format in revisions E and earlier. 4168a40a695Sgavinm * Bit 7 is a BIOS ScratchBit in revs D and earlier, 4178a40a695Sgavinm * PwrDwnTriEn in revision E; we don't use it so 4188a40a695Sgavinm * we'll call it ambig1. 4198a40a695Sgavinm */ 4208a40a695Sgavinm struct { 4218a40a695Sgavinm uint32_t DLL_Dis:1; /* 0 */ 4228a40a695Sgavinm uint32_t D_DRV:1; /* 1 */ 4238a40a695Sgavinm uint32_t QFC_EN:1; /* 2 */ 4248a40a695Sgavinm uint32_t DisDqsHys:1; /* 3 */ 4258a40a695Sgavinm uint32_t reserved1:1; /* 4 */ 4268a40a695Sgavinm uint32_t Burst2Opt:1; /* 5 */ 4278a40a695Sgavinm uint32_t Mod64BitMux:1; /* 6 */ 4288a40a695Sgavinm uint32_t ambig1:1; /* 7 */ 4298a40a695Sgavinm uint32_t DramInit:1; /* 8 */ 4308a40a695Sgavinm uint32_t DualDimmEn:1; /* 9 */ 4318a40a695Sgavinm uint32_t DramEnable:1; /* 10 */ 4328a40a695Sgavinm uint32_t MemClrStatus:1; /* 11 */ 4338a40a695Sgavinm uint32_t ESR:1; /* 12 */ 4348a40a695Sgavinm uint32_t SR_S:1; /* 13 */ 4358a40a695Sgavinm uint32_t RdWrQByp:2; /* 15:14 */ 4368a40a695Sgavinm uint32_t Width128:1; /* 16 */ 4378a40a695Sgavinm uint32_t DimmEcEn:1; /* 17 */ 4388a40a695Sgavinm uint32_t UnBufDimm:1; /* 18 */ 4398a40a695Sgavinm uint32_t ByteEn32:1; /* 19 */ 4408a40a695Sgavinm uint32_t x4DIMMs:4; /* 23:20 */ 4418a40a695Sgavinm uint32_t DisInRcvrs:1; /* 24 */ 4428a40a695Sgavinm uint32_t BypMax:3; /* 27:25 */ 4438a40a695Sgavinm uint32_t En2T:1; /* 28 */ 4448a40a695Sgavinm uint32_t UpperCSMap:1; /* 29 */ 4458a40a695Sgavinm uint32_t PwrDownCtl:2; /* 31:30 */ 4468a40a695Sgavinm } _fmt_preF; 4478a40a695Sgavinm /* 4488a40a695Sgavinm * Register format in revisions F and G 4498a40a695Sgavinm */ 4508a40a695Sgavinm struct { 4518a40a695Sgavinm uint32_t InitDram:1; /* 0 */ 4528a40a695Sgavinm uint32_t ExitSelfRef:1; /* 1 */ 4538a40a695Sgavinm uint32_t reserved1:2; /* 3:2 */ 4548a40a695Sgavinm uint32_t DramTerm:2; /* 5:4 */ 4558a40a695Sgavinm uint32_t reserved2:1; /* 6 */ 4568a40a695Sgavinm uint32_t DramDrvWeak:1; /* 7 */ 4578a40a695Sgavinm uint32_t ParEn:1; /* 8 */ 4588a40a695Sgavinm uint32_t SelRefRateEn:1; /* 9 */ 4598a40a695Sgavinm uint32_t BurstLength32:1; /* 10 */ 4608a40a695Sgavinm uint32_t Width128:1; /* 11 */ 4618a40a695Sgavinm uint32_t x4DIMMs:4; /* 15:12 */ 4628a40a695Sgavinm uint32_t UnBuffDimm:1; /* 16 */ 4638a40a695Sgavinm uint32_t reserved3:2; /* 18:17 */ 4648a40a695Sgavinm uint32_t DimmEccEn:1; /* 19 */ 4658a40a695Sgavinm uint32_t reserved4:12; /* 31:20 */ 4668a40a695Sgavinm } _fmt_revFG; 4678a40a695Sgavinm }; 4688a40a695Sgavinm 4698a40a695Sgavinm /* 4708a40a695Sgavinm * Function 2 - DRAM Controller: DRAM Controller Miscellaneous Data 4718a40a695Sgavinm */ 4728a40a695Sgavinm 4738a40a695Sgavinm union mcreg_drammisc { 4748a40a695Sgavinm uint32_t _val32; 4758a40a695Sgavinm /* 4768a40a695Sgavinm * Register format in revisions F and G 4778a40a695Sgavinm */ 4788a40a695Sgavinm struct { 4798a40a695Sgavinm uint32_t reserved2:1; /* 0 */ 4808a40a695Sgavinm uint32_t DisableJitter:1; /* 1 */ 4818a40a695Sgavinm uint32_t RdWrQByp:2; /* 3:2 */ 4828a40a695Sgavinm uint32_t Mod64Mux:1; /* 4 */ 4838a40a695Sgavinm uint32_t DCC_EN:1; /* 5 */ 4848a40a695Sgavinm uint32_t ILD_lmt:3; /* 8:6 */ 4858a40a695Sgavinm uint32_t DramEnabled:1; /* 9 */ 4868a40a695Sgavinm uint32_t PwrSavingsEn:1; /* 10 */ 4878a40a695Sgavinm uint32_t reserved1:13; /* 23:11 */ 4888a40a695Sgavinm uint32_t MemClkDis:8; /* 31:24 */ 4898a40a695Sgavinm } _fmt_revFG; 4908a40a695Sgavinm }; 4918a40a695Sgavinm 4928a40a695Sgavinm union mcreg_dramcfg_hi { 4938a40a695Sgavinm uint32_t _val32; 4948a40a695Sgavinm /* 4958a40a695Sgavinm * Register format in revisions E and earlier. 4968a40a695Sgavinm */ 4978a40a695Sgavinm struct { 4988a40a695Sgavinm uint32_t AsyncLat:4; /* 3:0 */ 4998a40a695Sgavinm uint32_t reserved1:4; /* 7:4 */ 5008a40a695Sgavinm uint32_t RdPreamble:4; /* 11:8 */ 5018a40a695Sgavinm uint32_t reserved2:1; /* 12 */ 5028a40a695Sgavinm uint32_t MemDQDrvStren:2; /* 14:13 */ 5038a40a695Sgavinm uint32_t DisableJitter:1; /* 15 */ 5048a40a695Sgavinm uint32_t ILD_lmt:3; /* 18:16 */ 5058a40a695Sgavinm uint32_t DCC_EN:1; /* 19 */ 5068a40a695Sgavinm uint32_t MemClk:3; /* 22:20 */ 5078a40a695Sgavinm uint32_t reserved3:2; /* 24:23 */ 5088a40a695Sgavinm uint32_t MCR:1; /* 25 */ 5098a40a695Sgavinm uint32_t MC0_EN:1; /* 26 */ 5108a40a695Sgavinm uint32_t MC1_EN:1; /* 27 */ 5118a40a695Sgavinm uint32_t MC2_EN:1; /* 28 */ 5128a40a695Sgavinm uint32_t MC3_EN:1; /* 29 */ 5138a40a695Sgavinm uint32_t reserved4:1; /* 30 */ 5148a40a695Sgavinm uint32_t OddDivisorCorrect:1; /* 31 */ 5158a40a695Sgavinm } _fmt_preF; 5168a40a695Sgavinm /* 5178a40a695Sgavinm * Register format in revisions F and G 5188a40a695Sgavinm */ 5198a40a695Sgavinm struct { 5208a40a695Sgavinm uint32_t MemClkFreq:3; /* 2:0 */ 5218a40a695Sgavinm uint32_t MemClkFreqVal:1; /* 3 */ 5228a40a695Sgavinm uint32_t MaxAsyncLat:4; /* 7:4 */ 5238a40a695Sgavinm uint32_t reserved1:4; /* 11:8 */ 5248a40a695Sgavinm uint32_t RDqsEn:1; /* 12 */ 5258a40a695Sgavinm uint32_t reserved2:1; /* 13 */ 5268a40a695Sgavinm uint32_t DisDramInterface:1; /* 14 */ 5278a40a695Sgavinm uint32_t PowerDownEn:1; /* 15 */ 5288a40a695Sgavinm uint32_t PowerDownMode:1; /* 16 */ 5298a40a695Sgavinm uint32_t FourRankSODimm:1; /* 17 */ 5308a40a695Sgavinm uint32_t FourRankRDimm:1; /* 18 */ 5318a40a695Sgavinm uint32_t reserved3:1; /* 19 */ 5328a40a695Sgavinm uint32_t SlowAccessMode:1; /* 20 */ 5338a40a695Sgavinm uint32_t reserved4:1; /* 21 */ 5348a40a695Sgavinm uint32_t BankSwizzleMode:1; /* 22 */ 5358a40a695Sgavinm uint32_t undocumented1:1; /* 23 */ 5368a40a695Sgavinm uint32_t DcqBypassMax:4; /* 27:24 */ 5378a40a695Sgavinm uint32_t FourActWindow:4; /* 31:28 */ 5388a40a695Sgavinm } _fmt_revFG; 5398a40a695Sgavinm }; 5408a40a695Sgavinm 5418a40a695Sgavinm /* 5428a40a695Sgavinm * Function 3 - Miscellaneous Control: Scrub Control Register 5438a40a695Sgavinm */ 5448a40a695Sgavinm 5458a40a695Sgavinm union mcreg_scrubctl { 5468a40a695Sgavinm uint32_t _val32; 5478a40a695Sgavinm struct { 5488a40a695Sgavinm uint32_t DramScrub:5; /* 4:0 */ 5498a40a695Sgavinm uint32_t reserved3:3; /* 7:5 */ 5508a40a695Sgavinm uint32_t L2Scrub:5; /* 12:8 */ 5518a40a695Sgavinm uint32_t reserved2:3; /* 15:13 */ 5528a40a695Sgavinm uint32_t DcacheScrub:5; /* 20:16 */ 5538a40a695Sgavinm uint32_t reserved1:11; /* 31:21 */ 5548a40a695Sgavinm } _fmt_cmn; 5558a40a695Sgavinm }; 5568a40a695Sgavinm 5578a40a695Sgavinm /* 5588a40a695Sgavinm * Function 3 - Miscellaneous Control: On-Line Spare Control Register 5598a40a695Sgavinm */ 5608a40a695Sgavinm 5618a40a695Sgavinm union mcreg_nbcfg { 5628a40a695Sgavinm uint32_t _val32; 5638a40a695Sgavinm /* 5648a40a695Sgavinm * Register format in revisions E and earlier. 5658a40a695Sgavinm */ 5668a40a695Sgavinm struct { 5678a40a695Sgavinm uint32_t CpuEccErrEn:1; /* 0 */ 5688a40a695Sgavinm uint32_t CpuRdDatErrEn:1; /* 1 */ 5698a40a695Sgavinm uint32_t SyncOnUcEccEn:1; /* 2 */ 5708a40a695Sgavinm uint32_t SyncPktGenDis:1; /* 3 */ 5718a40a695Sgavinm uint32_t SyncPktPropDis:1; /* 4 */ 5728a40a695Sgavinm uint32_t IoMstAbortDis:1; /* 5 */ 5738a40a695Sgavinm uint32_t CpuErrDis:1; /* 6 */ 5748a40a695Sgavinm uint32_t IoErrDis:1; /* 7 */ 5758a40a695Sgavinm uint32_t WdogTmrDis:1; /* 8 */ 5768a40a695Sgavinm uint32_t WdogTmrCntSel:3; /* 11:9 */ 5778a40a695Sgavinm uint32_t WdogTmrBaseSel:2; /* 13:12 */ 5788a40a695Sgavinm uint32_t LdtLinkSel:2; /* 15:14 */ 5798a40a695Sgavinm uint32_t GenCrcErrByte0:1; /* 16 */ 5808a40a695Sgavinm uint32_t GenCrcErrByte1:1; /* 17 */ 5818a40a695Sgavinm uint32_t reserved1:2; /* 19:18 */ 5828a40a695Sgavinm uint32_t SyncOnWdogEn:1; /* 20 */ 5838a40a695Sgavinm uint32_t SyncOnAnyErrEn:1; /* 21 */ 5848a40a695Sgavinm uint32_t EccEn:1; /* 22 */ 5858a40a695Sgavinm uint32_t ChipKillEccEn:1; /* 23 */ 5868a40a695Sgavinm uint32_t IoRdDatErrEn:1; /* 24 */ 5878a40a695Sgavinm uint32_t DisPciCfgCpuErrRsp:1; /* 25 */ 5888a40a695Sgavinm uint32_t reserved2:1; /* 26 */ 5898a40a695Sgavinm uint32_t NbMcaToMstCpuEn:1; /* 27 */ 5908a40a695Sgavinm uint32_t reserved3:4; /* 31:28 */ 5918a40a695Sgavinm } _fmt_preF; 5928a40a695Sgavinm /* 5938a40a695Sgavinm * Register format in revisions F and G 5948a40a695Sgavinm */ 5958a40a695Sgavinm struct { 5968a40a695Sgavinm uint32_t CpuEccErrEn:1; /* 0 */ 5978a40a695Sgavinm uint32_t CpuRdDatErrEn:1; /* 1 */ 5988a40a695Sgavinm uint32_t SyncOnUcEccEn:1; /* 2 */ 5998a40a695Sgavinm uint32_t SyncPktGenDis:1; /* 3 */ 6008a40a695Sgavinm uint32_t SyncPktPropDis:1; /* 4 */ 6018a40a695Sgavinm uint32_t IoMstAbortDis:1; /* 5 */ 6028a40a695Sgavinm uint32_t CpuErrDis:1; /* 6 */ 6038a40a695Sgavinm uint32_t IoErrDis:1; /* 7 */ 6048a40a695Sgavinm uint32_t WdogTmrDis:1; /* 8 */ 6058a40a695Sgavinm uint32_t WdogTmrCntSel:3; /* 11:9 */ 6068a40a695Sgavinm uint32_t WdogTmrBaseSel:2; /* 13:12 */ 6078a40a695Sgavinm uint32_t LdtLinkSel:2; /* 15:14 */ 6088a40a695Sgavinm uint32_t GenCrcErrByte0:1; /* 16 */ 6098a40a695Sgavinm uint32_t GenCrcErrByte1:1; /* 17 */ 6108a40a695Sgavinm uint32_t reserved1:2; /* 19:18 */ 6118a40a695Sgavinm uint32_t SyncOnWdogEn:1; /* 20 */ 6128a40a695Sgavinm uint32_t SyncOnAnyErrEn:1; /* 21 */ 6138a40a695Sgavinm uint32_t EccEn:1; /* 22 */ 6148a40a695Sgavinm uint32_t ChipKillEccEn:1; /* 23 */ 6158a40a695Sgavinm uint32_t IoRdDatErrEn:1; /* 24 */ 6168a40a695Sgavinm uint32_t DisPciCfgCpuErrRsp:1; /* 25 */ 6178a40a695Sgavinm uint32_t reserved2:1; /* 26 */ 6188a40a695Sgavinm uint32_t NbMcaToMstCpuEn:1; /* 27 */ 6198a40a695Sgavinm uint32_t DisTgtAbtCpuErrRsp:1; /* 28 */ 6208a40a695Sgavinm uint32_t DisMstAbtCpuErrRsp:1; /* 29 */ 6218a40a695Sgavinm uint32_t SyncOnDramAdrParErrEn:1; /* 30 */ 6228a40a695Sgavinm uint32_t reserved3:1; /* 31 */ 6238a40a695Sgavinm 6248a40a695Sgavinm } _fmt_revFG; 6258a40a695Sgavinm }; 6268a40a695Sgavinm 6278a40a695Sgavinm /* 6288a40a695Sgavinm * Function 3 - Miscellaneous Control: On-Line Spare Control Register 6298a40a695Sgavinm */ 6308a40a695Sgavinm 6318a40a695Sgavinm union mcreg_sparectl { 6328a40a695Sgavinm uint32_t _val32; 6338a40a695Sgavinm /* 6348a40a695Sgavinm * Register format in revisions F and G 6358a40a695Sgavinm */ 6368a40a695Sgavinm struct { 6378a40a695Sgavinm uint32_t SwapEn:1; /* 0 */ 6388a40a695Sgavinm uint32_t SwapDone:1; /* 1 */ 6398a40a695Sgavinm uint32_t reserved1:2; /* 3:2 */ 6408a40a695Sgavinm uint32_t BadDramCs:3; /* 6:4 */ 6418a40a695Sgavinm uint32_t reserved2:5; /* 11:7 */ 6428a40a695Sgavinm uint32_t SwapDoneInt:2; /* 13:12 */ 6438a40a695Sgavinm uint32_t EccErrInt:2; /* 15:14 */ 6448a40a695Sgavinm uint32_t EccErrCntDramCs:3; /* 18:16 */ 6458a40a695Sgavinm uint32_t reserved3:1; /* 19 */ 6468a40a695Sgavinm uint32_t EccErrCntDramChan:1; /* 20 */ 6478a40a695Sgavinm uint32_t reserved4:2; /* 22:21 */ 6488a40a695Sgavinm uint32_t EccErrCntWrEn:1; /* 23 */ 6498a40a695Sgavinm uint32_t EccErrCnt:4; /* 27:24 */ 6508a40a695Sgavinm uint32_t reserved5:4; /* 31:28 */ 6518a40a695Sgavinm } _fmt_revFG; 6528a40a695Sgavinm }; 6537aec1d6eScindi 6547aec1d6eScindi #ifdef __cplusplus 6557aec1d6eScindi } 6567aec1d6eScindi #endif 6577aec1d6eScindi 6587aec1d6eScindi #endif /* _MC_AMD_H */ 659