1e4b86885SCheng Sean Ye /* 2e4b86885SCheng Sean Ye * CDDL HEADER START 3e4b86885SCheng Sean Ye * 4e4b86885SCheng Sean Ye * The contents of this file are subject to the terms of the 5e4b86885SCheng Sean Ye * Common Development and Distribution License (the "License"). 6e4b86885SCheng Sean Ye * You may not use this file except in compliance with the License. 7e4b86885SCheng Sean Ye * 8e4b86885SCheng Sean Ye * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9e4b86885SCheng Sean Ye * or http://www.opensolaris.org/os/licensing. 10e4b86885SCheng Sean Ye * See the License for the specific language governing permissions 11e4b86885SCheng Sean Ye * and limitations under the License. 12e4b86885SCheng Sean Ye * 13e4b86885SCheng Sean Ye * When distributing Covered Code, include this CDDL HEADER in each 14e4b86885SCheng Sean Ye * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15e4b86885SCheng Sean Ye * If applicable, add the following below this CDDL HEADER, with the 16e4b86885SCheng Sean Ye * fields enclosed by brackets "[]" replaced with your own identifying 17e4b86885SCheng Sean Ye * information: Portions Copyright [yyyy] [name of copyright owner] 18e4b86885SCheng Sean Ye * 19e4b86885SCheng Sean Ye * CDDL HEADER END 20e4b86885SCheng Sean Ye */ 21e4b86885SCheng Sean Ye 22e4b86885SCheng Sean Ye /* 23*074bb90dSTom Pothier * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24e4b86885SCheng Sean Ye * Use is subject to license terms. 25e4b86885SCheng Sean Ye */ 26e4b86885SCheng Sean Ye 27e4b86885SCheng Sean Ye #ifndef _MCAMD_H 28e4b86885SCheng Sean Ye #define _MCAMD_H 29e4b86885SCheng Sean Ye 30e4b86885SCheng Sean Ye /* 31e4b86885SCheng Sean Ye * Header file for the mc-amd AMD memory-controller driver. This should be 32e4b86885SCheng Sean Ye * included from that driver source alone - any more-widely useful definitions 33e4b86885SCheng Sean Ye * belong in mc_amd.h. 34e4b86885SCheng Sean Ye */ 35e4b86885SCheng Sean Ye 36e4b86885SCheng Sean Ye #include <sys/types.h> 37e4b86885SCheng Sean Ye #include <sys/ddi.h> 38e4b86885SCheng Sean Ye #include <sys/sunddi.h> 39e4b86885SCheng Sean Ye #include <sys/ksynch.h> 40e4b86885SCheng Sean Ye #include <sys/mc_amd.h> 41e4b86885SCheng Sean Ye #include <sys/cpu_module.h> 42e4b86885SCheng Sean Ye #include <mcamd_api.h> 43e4b86885SCheng Sean Ye #include <mcamd_err.h> 44e4b86885SCheng Sean Ye #include <mcamd_dimmcfg.h> 45e4b86885SCheng Sean Ye 46e4b86885SCheng Sean Ye #ifdef __cplusplus 47e4b86885SCheng Sean Ye extern "C" { 48e4b86885SCheng Sean Ye #endif 49e4b86885SCheng Sean Ye 50e4b86885SCheng Sean Ye #if MC_CHIP_DIMMPERCS > MC_UNUM_NDIMM 51e4b86885SCheng Sean Ye #error "MC_CHIP_DIMMPERCS exceeds MC_UNUM_NDIMM" 52e4b86885SCheng Sean Ye #endif 53e4b86885SCheng Sean Ye 54e4b86885SCheng Sean Ye /* 55e4b86885SCheng Sean Ye * The memory controller configuration registers are accessed via PCI bus 0, 56e4b86885SCheng Sean Ye * device 0x18 + nodeid, functions 0 to 3. The function numbers are 57e4b86885SCheng Sean Ye * MC_FUNC_*, defined in mc_amd.h. 58e4b86885SCheng Sean Ye * 59e4b86885SCheng Sean Ye * We do not attach to function 3 "Miscellaneous Control" pci1022,1103 60e4b86885SCheng Sean Ye * since the agpgart driver already attaches to that function; instead we 61e4b86885SCheng Sean Ye * retrieve what function 3 parameters we require via direct PCI Mechanism 1 62e4b86885SCheng Sean Ye * accesses 63e4b86885SCheng Sean Ye * 64e4b86885SCheng Sean Ye * The memory controller driver attaches to these device nodes, but publishes 65e4b86885SCheng Sean Ye * a single minor node. We need to ensure that the minor node can be 66e4b86885SCheng Sean Ye * consistently mapped back to a single (and the same) device node, so we 67e4b86885SCheng Sean Ye * need to pick one to be used. We'll use the dram address map device node, 68e4b86885SCheng Sean Ye * as it'll be the last to be attached. 69e4b86885SCheng Sean Ye */ 70e4b86885SCheng Sean Ye #define MC_FUNC_DEVIMAP MC_FUNC_DRAMCTL 71e4b86885SCheng Sean Ye #define MC_FUNC_NUM (MC_FUNC_MISCCTL + 1) 72e4b86885SCheng Sean Ye 73e4b86885SCheng Sean Ye #define MC_FUNC_HTCONFIG_BINDNM "pci1022,1100" 74e4b86885SCheng Sean Ye #define MC_FUNC_ADDRMAP_BINDNM "pci1022,1101" 75e4b86885SCheng Sean Ye #define MC_FUNC_DRAMCTL_BINDNM "pci1022,1102" 76e4b86885SCheng Sean Ye 77e4b86885SCheng Sean Ye typedef struct mc_func { 78e4b86885SCheng Sean Ye uint_t mcf_instance; 79e4b86885SCheng Sean Ye dev_info_t *mcf_devi; 80e4b86885SCheng Sean Ye } mc_func_t; 81e4b86885SCheng Sean Ye 82e4b86885SCheng Sean Ye typedef struct mc_dimm mc_dimm_t; 83e4b86885SCheng Sean Ye typedef struct mc_cs mc_cs_t; 84e4b86885SCheng Sean Ye typedef struct mc mc_t; 85e4b86885SCheng Sean Ye 86e4b86885SCheng Sean Ye /* 87e4b86885SCheng Sean Ye * Node types for mch_type below. These are used in array indexing. 88e4b86885SCheng Sean Ye */ 89e4b86885SCheng Sean Ye #define MC_NT_MC 0 90e4b86885SCheng Sean Ye #define MC_NT_CS 1 91e4b86885SCheng Sean Ye #define MC_NT_DIMM 2 92e4b86885SCheng Sean Ye #define MC_NT_NTYPES 3 93e4b86885SCheng Sean Ye 94e4b86885SCheng Sean Ye typedef struct mc_hdr { 95e4b86885SCheng Sean Ye uint_t mch_type; 96e4b86885SCheng Sean Ye union { 97e4b86885SCheng Sean Ye mc_t *_mch_mc; 98e4b86885SCheng Sean Ye mc_cs_t *_mch_cs; 99e4b86885SCheng Sean Ye } _mch_ptr; 100e4b86885SCheng Sean Ye } mc_hdr_t; 101e4b86885SCheng Sean Ye 102e4b86885SCheng Sean Ye #define mch_mc _mch_ptr._mch_mc 103e4b86885SCheng Sean Ye 104e4b86885SCheng Sean Ye struct mc_dimm { 105e4b86885SCheng Sean Ye mc_hdr_t mcd_hdr; /* id, pointer to parent */ 106e4b86885SCheng Sean Ye mc_dimm_t *mcd_next; /* next dimm for this MC */ 107e4b86885SCheng Sean Ye mc_cs_t *mcd_cs[MC_CHIP_DIMMRANKMAX]; /* associated chip-selects */ 108e4b86885SCheng Sean Ye const mcdcfg_csl_t *mcd_csl[MC_CHIP_DIMMRANKMAX]; /* cs lines */ 109e4b86885SCheng Sean Ye mcamd_prop_t mcd_num; /* dimm number */ 110e4b86885SCheng Sean Ye mcamd_prop_t mcd_size; /* dimm size in bytes */ 111e4b86885SCheng Sean Ye }; 112e4b86885SCheng Sean Ye 113e4b86885SCheng Sean Ye #define mcd_mc mcd_hdr.mch_mc 114e4b86885SCheng Sean Ye 115e4b86885SCheng Sean Ye /* 116e4b86885SCheng Sean Ye * Chip-select properties. If a chip-select is associated with just one 117e4b86885SCheng Sean Ye * dimm (whether it be on the A or B dram channel) that number will be 118e4b86885SCheng Sean Ye * in csp_dimmnums[0]; if the chip-select is associated with two dimms 119e4b86885SCheng Sean Ye * then csp_dimmnums[0] has the dimm from channel A and csp_dimmnums[1] has 120e4b86885SCheng Sean Ye * the partner dimm from channel B. 121e4b86885SCheng Sean Ye */ 122e4b86885SCheng Sean Ye typedef struct mccs_props { 123e4b86885SCheng Sean Ye mcamd_prop_t csp_num; /* Chip-select number */ 124e4b86885SCheng Sean Ye mcamd_prop_t csp_base; /* DRAM CS Base */ 125e4b86885SCheng Sean Ye mcamd_prop_t csp_mask; /* DRAM CS Mask */ 126e4b86885SCheng Sean Ye mcamd_prop_t csp_size; /* Chip-select bank size */ 127e4b86885SCheng Sean Ye mcamd_prop_t csp_csbe; /* Chip-select bank enable */ 128e4b86885SCheng Sean Ye mcamd_prop_t csp_spare; /* Spare */ 129e4b86885SCheng Sean Ye mcamd_prop_t csp_testfail; /* TestFail */ 130e4b86885SCheng Sean Ye mcamd_prop_t csp_dimmnums[MC_CHIP_DIMMPERCS]; /* dimm(s) in cs */ 131e4b86885SCheng Sean Ye mcamd_prop_t csp_dimmrank; /* rank # on dimms */ 132e4b86885SCheng Sean Ye } mccs_props_t; 133e4b86885SCheng Sean Ye 134e4b86885SCheng Sean Ye /* 135e4b86885SCheng Sean Ye * Chip-select config register values 136e4b86885SCheng Sean Ye */ 137e4b86885SCheng Sean Ye typedef struct mccs_cfgrefs { 138e4b86885SCheng Sean Ye mcamd_cfgreg_t csr_csbase; /* Raw CS base reg */ 139e4b86885SCheng Sean Ye mcamd_cfgreg_t csr_csmask; /* Raw CS mask reg */ 140e4b86885SCheng Sean Ye } mccs_cfgregs_t; 141e4b86885SCheng Sean Ye 142e4b86885SCheng Sean Ye struct mc_cs { 143e4b86885SCheng Sean Ye mc_hdr_t mccs_hdr; /* id, pointer to parent */ 144e4b86885SCheng Sean Ye mc_cs_t *mccs_next; /* Next chip-select of MC */ 145e4b86885SCheng Sean Ye mc_dimm_t *mccs_dimm[MC_CHIP_DIMMPERCS]; /* dimms for this cs */ 146e4b86885SCheng Sean Ye const mcdcfg_csl_t *mccs_csl[MC_CHIP_DIMMPERCS]; /* cs lines */ 147e4b86885SCheng Sean Ye mccs_props_t mccs_props; /* Properties */ 148e4b86885SCheng Sean Ye mccs_cfgregs_t mccs_cfgregs; /* Raw config values */ 149e4b86885SCheng Sean Ye }; 150e4b86885SCheng Sean Ye 151e4b86885SCheng Sean Ye #define mccs_mc mccs_hdr.mch_mc 152e4b86885SCheng Sean Ye 153e4b86885SCheng Sean Ye /* 154e4b86885SCheng Sean Ye * Memory controller properties. 155e4b86885SCheng Sean Ye */ 156e4b86885SCheng Sean Ye typedef struct mc_props { 157e4b86885SCheng Sean Ye mcamd_prop_t mcp_num; /* Associated *chip* number */ 158e4b86885SCheng Sean Ye mcamd_prop_t mcp_rev; /* Chip revision (MC_REV_*) */ 159e4b86885SCheng Sean Ye mcamd_prop_t mcp_base; /* base address for mc's drams */ 160e4b86885SCheng Sean Ye mcamd_prop_t mcp_lim; /* limit address for mc's drams */ 161e4b86885SCheng Sean Ye mcamd_prop_t mcp_ilen; /* interleave enable */ 162e4b86885SCheng Sean Ye mcamd_prop_t mcp_ilsel; /* interleave select */ 163e4b86885SCheng Sean Ye mcamd_prop_t mcp_csintlvfctr; /* cs bank interleave factor */ 164e4b86885SCheng Sean Ye mcamd_prop_t mcp_dramhole_size; /* DRAM Hole Size */ 165e4b86885SCheng Sean Ye mcamd_prop_t mcp_accwidth; /* dram access width (64 or 128) */ 166e4b86885SCheng Sean Ye mcamd_prop_t mcp_csbankmapreg; /* chip-select bank mapping reg */ 167e4b86885SCheng Sean Ye mcamd_prop_t mcp_bnkswzl; /* BankSwizzle enabled */ 168e4b86885SCheng Sean Ye mcamd_prop_t mcp_mod64mux; /* Mismtached DIMMs support enabled */ 169e4b86885SCheng Sean Ye mcamd_prop_t mcp_sparecs; /* cs# replaced by online spare */ 170e4b86885SCheng Sean Ye mcamd_prop_t mcp_badcs; /* cs# replaced by online spare */ 171e4b86885SCheng Sean Ye } mc_props_t; 172e4b86885SCheng Sean Ye 173e4b86885SCheng Sean Ye /* 174e4b86885SCheng Sean Ye * Memory controller config register values 175e4b86885SCheng Sean Ye */ 176e4b86885SCheng Sean Ye typedef struct mc_cfgregs { 177e4b86885SCheng Sean Ye mcamd_cfgreg_t mcr_htroute[MC_CHIP_MAXNODES]; 178e4b86885SCheng Sean Ye mcamd_cfgreg_t mcr_htnodeid; 179e4b86885SCheng Sean Ye mcamd_cfgreg_t mcr_htunitid; 180e4b86885SCheng Sean Ye mcamd_cfgreg_t mcr_drambase; 181e4b86885SCheng Sean Ye mcamd_cfgreg_t mcr_dramlimit; 182e4b86885SCheng Sean Ye mcamd_cfgreg_t mcr_dramhole; 183e4b86885SCheng Sean Ye mcamd_cfgreg_t mcr_dramcfglo; 184e4b86885SCheng Sean Ye mcamd_cfgreg_t mcr_dramcfghi; 185e4b86885SCheng Sean Ye mcamd_cfgreg_t mcr_drammisc; 186e4b86885SCheng Sean Ye mcamd_cfgreg_t mcr_nbcfg; 187e4b86885SCheng Sean Ye mcamd_cfgreg_t mcr_sparectl; 188e4b86885SCheng Sean Ye mcamd_cfgreg_t mcr_scrubctl; 189e4b86885SCheng Sean Ye mcamd_cfgreg_t mcr_scrubaddrlo; 190e4b86885SCheng Sean Ye mcamd_cfgreg_t mcr_scrubaddrhi; 191e4b86885SCheng Sean Ye } mc_cfgregs_t; 192e4b86885SCheng Sean Ye 193e4b86885SCheng Sean Ye struct mc { 194e4b86885SCheng Sean Ye mc_hdr_t mc_hdr; /* id */ 195e4b86885SCheng Sean Ye struct mc *mc_next; /* next MC instance */ 196e4b86885SCheng Sean Ye const char *mc_revname; /* revision name string */ 197e4b86885SCheng Sean Ye uint32_t mc_socket; /* Package type */ 198e4b86885SCheng Sean Ye uint_t mc_ref; /* reference (attach) count */ 199e4b86885SCheng Sean Ye mc_func_t mc_funcs[MC_FUNC_NUM]; /* Instance, devinfo, ... */ 200e4b86885SCheng Sean Ye mc_cs_t *mc_cslist; /* All active chip-selects */ 201e4b86885SCheng Sean Ye mc_cs_t *mc_cslast; /* End of chip-select list */ 202e4b86885SCheng Sean Ye mc_dimm_t *mc_dimmlist; /* List of all logical DIMMs, */ 203e4b86885SCheng Sean Ye mc_dimm_t *mc_dimmlast; /* linked via mcd_mcnext */ 204e4b86885SCheng Sean Ye mc_props_t mc_props; /* Properties */ 205e4b86885SCheng Sean Ye mc_cfgregs_t mc_cfgregs; /* Raw config values */ 206e4b86885SCheng Sean Ye hrtime_t mc_spareswaptime; /* If initiated by us */ 207e4b86885SCheng Sean Ye nvlist_t *mc_nvl; /* nvlist for export */ 208e4b86885SCheng Sean Ye char *mc_snapshot; /* packed nvlist for libmc */ 209e4b86885SCheng Sean Ye size_t mc_snapshotsz; /* packed nvlist buffer size */ 210e4b86885SCheng Sean Ye uint_t mc_snapshotgen; /* snapshot generation number */ 211e4b86885SCheng Sean Ye int mc_csdiscontig; /* chip-selects discontiguous */ 212*074bb90dSTom Pothier uint_t smb_chipid; /* smbios chip instance */ 213*074bb90dSTom Pothier nvlist_t *smb_bboard; /* smbios chip's parent */ 214e4b86885SCheng Sean Ye }; 215e4b86885SCheng Sean Ye 216e4b86885SCheng Sean Ye typedef struct mcamd_hdl { 217e4b86885SCheng Sean Ye int mcamd_errno; 218e4b86885SCheng Sean Ye int mcamd_debug; 219e4b86885SCheng Sean Ye } mcamd_hdl_t; 220e4b86885SCheng Sean Ye 221e4b86885SCheng Sean Ye extern mc_t *mc_list; 222e4b86885SCheng Sean Ye extern krwlock_t mc_lock; 223e4b86885SCheng Sean Ye 224e4b86885SCheng Sean Ye extern void mcamd_mkhdl(mcamd_hdl_t *); 225e4b86885SCheng Sean Ye extern void mcamd_mc_register(cmi_hdl_t, mc_t *); 226e4b86885SCheng Sean Ye extern void mcamd_ereport_post(mc_t *, const char *, mc_unum_t *, uint64_t); 227e4b86885SCheng Sean Ye 228e4b86885SCheng Sean Ye /* 229e4b86885SCheng Sean Ye * mcamd_mc_ops prototypes 230e4b86885SCheng Sean Ye */ 231e4b86885SCheng Sean Ye extern cmi_errno_t mcamd_patounum_wrap(void *, uint64_t, uint8_t, uint8_t, 232e4b86885SCheng Sean Ye uint32_t, int, mc_unum_t *); 233e4b86885SCheng Sean Ye extern cmi_errno_t mcamd_unumtopa_wrap(void *, mc_unum_t *, nvlist_t *, 234e4b86885SCheng Sean Ye uint64_t *); 235e4b86885SCheng Sean Ye 236e4b86885SCheng Sean Ye /* 237e4b86885SCheng Sean Ye * Internal functions 238e4b86885SCheng Sean Ye */ 239e4b86885SCheng Sean Ye cmi_errno_t mcamd_cmierr(int, mcamd_hdl_t *); 240e4b86885SCheng Sean Ye 241e4b86885SCheng Sean Ye #ifdef __cplusplus 242e4b86885SCheng Sean Ye } 243e4b86885SCheng Sean Ye #endif 244e4b86885SCheng Sean Ye 245e4b86885SCheng Sean Ye #endif /* _MCAMD_H */ 246