From aef8ee72b9a69b7290d5c85b40c95e9f2ace7544 Mon Sep 17 00:00:00 2001 From: CyrIng Date: Mon, 30 May 2022 17:01:28 +0000 Subject: [PATCH] [Intel] Routing the Haswell-EP devices (initial implementation) [SNB] Refactoring the count of IMC channels & DIMMs --- corefreq-api.h | 36 ++++--- corefreqd.c | 77 ++++++++++++++ corefreqk.c | 273 ++++++++++++++++++++++++++++++++++++++++++++++--- corefreqk.h | 120 ++++++++++++++++++++++ intelmsr.h | 49 ++++++++- 5 files changed, 524 insertions(+), 31 deletions(-) diff --git a/corefreq-api.h b/corefreq-api.h index 9d6a01d7..0c1bb35f 100644 --- a/corefreq-api.h +++ b/corefreq-api.h @@ -657,10 +657,14 @@ typedef struct /* 5008h */ MAD1; /* 32 bits */ } SNB; struct { - SNB_EP_MC_TECH TECH; /* 32 bits */ + /* 7Ch*/ SNB_EP_MC_TECH TECH; /* 32 bits */ /* 80h */ SNB_EP_TADWAYNESS TAD; /* 12x32 bits */ } SNB_EP; struct { + /* 7Ch*/ HSW_EP_MC_TECH TECH; /* 32 bits */ + /* 80h */ HSW_EP_TADWAYNESS TAD; /* 12x32 bits */ + } HSW_EP; + struct { /* 5000h */ SKL_IMC_MAD_MAPPING MADCH; /* 32 bits */ /* 5004h */ SKL_IMC_MAD_CHANNEL MADC0, /* 32 bits */ /* 5008h */ MADC1; /* 32 bits */ @@ -1193,21 +1197,23 @@ typedef struct /* QPIMISCSTAT: Device=8 - Function=0 */ #define DID_INTEL_HSW_EP_QPI_LINK0 0x2f80 /* Integrated Memory Controller # : General and MemHot Registers */ -/* Xeon E5 - CPGC: Device=19 - Function=0 */ -#define DID_INTEL_HSW_EP_IMC_CTRL0_CPGC 0x2fa8 -/* Xeon E7 - CPGC: Device=22 - Function=0 */ -#define DID_INTEL_HSW_EP_IMC_CTRL1_CPGC 0x2f68 +/* Xeon E7 - CPGC: Device=19 - Function=0,1 */ +#define DID_INTEL_HSW_E7_IMC_CTRL0_F0_CPGC 0x2fa8 +#define DID_INTEL_HSW_E7_IMC_CTRL0_F1_CPGC 0x2f71 +/* Xeon E7 - CPGC: Device=22 - Function=0,1 */ +#define DID_INTEL_HSW_E7_IMC_CTRL1_F0_CPGC 0x2f68 +#define DID_INTEL_HSW_E7_IMC_CTRL1_F1_CPGC 0x2f79 /* Integrated Memory Controller # : Channel [m-M] Thermal Registers*/ -/*TODO( Controller #0: Device=?? - Function=0,1,2,3 ) -#define DID_INTEL_HSW_EP_IMC_CTRL0_CH0 0x0 -#define DID_INTEL_HSW_EP_IMC_CTRL0_CH1 0x0 -#define DID_INTEL_HSW_EP_IMC_CTRL0_CH2 0x0 -#define DID_INTEL_HSW_EP_IMC_CTRL0_CH3 0x0 */ -/*TODO( Controller #1: Device=?? - Function=4,5,6,7 ) -#define DID_INTEL_HSW_EP_IMC_CTRL1_CH0 0x0 -#define DID_INTEL_HSW_EP_IMC_CTRL1_CH1 0x0 -#define DID_INTEL_HSW_EP_IMC_CTRL1_CH2 0x0 -#define DID_INTEL_HSW_EP_IMC_CTRL1_CH3 0x0 */ +/* Controller #0: Device=20,21 - Function=0,1 */ +#define DID_INTEL_HSW_EP_IMC_CTRL0_CH0 0x2fb4 +#define DID_INTEL_HSW_EP_IMC_CTRL0_CH1 0x2fb5 +#define DID_INTEL_HSW_EP_IMC_CTRL0_CH2 0x2fb0 +#define DID_INTEL_HSW_EP_IMC_CTRL0_CH3 0x2fb1 +/* Controller #1: Device=23,24 - Function=2,3 */ +#define DID_INTEL_HSW_EP_IMC_CTRL1_CH0 0x2fd6 +#define DID_INTEL_HSW_EP_IMC_CTRL1_CH1 0x2fd7 +#define DID_INTEL_HSW_EP_IMC_CTRL1_CH2 0x2fd2 +#define DID_INTEL_HSW_EP_IMC_CTRL1_CH3 0x2fd3 /* Integrated Memory Controller 0 : Channel # TAD Registers */ /* Xeon E5 - TAD Controller #0: Device=19 - Function=2,3,4,5 */ #define DID_INTEL_HSW_EP_TAD_CTRL0_CH0 0x2faa diff --git a/corefreqd.c b/corefreqd.c index c5ce547b..e64bb58e 100644 --- a/corefreqd.c +++ b/corefreqd.c @@ -3952,6 +3952,78 @@ void HSW_CAP(RO(SHM_STRUCT) *RO(Shm), RO(PROC) *RO(Proc), RO(CORE) *RO(Core)) } } +#define HSW_EP_IMC SNB_EP_IMC + +void HSW_EP_CAP(RO(SHM_STRUCT) *RO(Shm), RO(PROC) *RO(Proc), RO(CORE) *RO(Core)) +{ + switch (RO(Proc)->Uncore.Bus.SNB_EP_Cap1.DMFC) { + case 0b111: + RO(Shm)->Uncore.CtrlSpeed = 1066; + break; + case 0b110: + RO(Shm)->Uncore.CtrlSpeed = 1333; + break; + case 0b101: + RO(Shm)->Uncore.CtrlSpeed = 1600; + break; + case 0b100: + RO(Shm)->Uncore.CtrlSpeed = 1866; + break; + case 0b011: + RO(Shm)->Uncore.CtrlSpeed = 2133; + break; + case 0b010: + RO(Shm)->Uncore.CtrlSpeed = 2400; + break; + case 0b001: + RO(Shm)->Uncore.CtrlSpeed = 2666; + break; + case 0b000: + RO(Shm)->Uncore.CtrlSpeed = 2933; + break; + } + + RO(Shm)->Uncore.CtrlSpeed *= RO(Core)->Clock.Hz; + RO(Shm)->Uncore.CtrlSpeed /= RO(Shm)->Proc.Features.Factory.Clock.Hz; + + RO(Shm)->Uncore.Bus.Rate = \ + RO(Proc)->Uncore.Bus.QuickPath.IVB_EP.QPIFREQSEL == 0b010 ? + 5600 : RO(Proc)->Uncore.Bus.QuickPath.IVB_EP.QPIFREQSEL == 0b011 ? + 6400 : RO(Proc)->Uncore.Bus.QuickPath.IVB_EP.QPIFREQSEL == 0b100 ? + 7200 : RO(Proc)->Uncore.Bus.QuickPath.IVB_EP.QPIFREQSEL == 0b101 ? + 8000 : RO(Proc)->Uncore.Bus.QuickPath.IVB_EP.QPIFREQSEL == 0b111 ? + 9600 : 6400; + + RO(Shm)->Uncore.Bus.Speed = (RO(Core)->Clock.Hz + * RO(Shm)->Uncore.Bus.Rate) + / RO(Shm)->Proc.Features.Factory.Clock.Hz; + + RO(Shm)->Uncore.Unit.Bus_Rate = MC_MTS; + RO(Shm)->Uncore.Unit.BusSpeed = MC_MTS; + RO(Shm)->Uncore.Unit.DDR_Rate = MC_NIL; + RO(Shm)->Uncore.Unit.DDRSpeed = MC_MHZ; + + if (RO(Proc)->Uncore.MC[0].HSW_EP.TECH.DDR4_Mode) { + RO(Shm)->Uncore.Unit.DDR_Ver = 4; + } else { + RO(Shm)->Uncore.Unit.DDR_Ver = 3; + } + if (RO(Proc)->Uncore.Bus.SNB_EP_Cap3.RDIMM_DIS) + { + if (RO(Proc)->Uncore.Bus.SNB_EP_Cap3.UDIMM_DIS) { + RO(Shm)->Uncore.Unit.DDR_Std = RAM_STD_UNSPEC; + } else { + RO(Shm)->Uncore.Unit.DDR_Std = RAM_STD_SDRAM; + } + } else { + RO(Shm)->Uncore.Unit.DDR_Std = RAM_STD_RDIMM; + } +/*TODO(VT-d capability from device 30 in CAPID# registers among offsets 0x80)*/ + RO(Shm)->Proc.Technology.IOMMU = 0; + RO(Shm)->Proc.Technology.IOMMU_Ver_Major = 0; + RO(Shm)->Proc.Technology.IOMMU_Ver_Minor = 0; +} + unsigned int SKL_DimmWidthToRows(unsigned int width) { unsigned int rows = 0; @@ -5822,6 +5894,11 @@ void PCI_Intel(RO(SHM_STRUCT) *RO(Shm), RO(PROC) *RO(Proc), RO(CORE) *RO(Core), HSW_IMC(RO(Shm), RO(Proc)); SET_CHIPSET(IC_LYNXPOINT); break; + case DID_INTEL_HSW_EP_HOST_BRIDGE: + HSW_EP_CAP(RO(Shm), RO(Proc), RO(Core)); + HSW_EP_IMC(RO(Shm), RO(Proc)); + SET_CHIPSET(IC_WELLSBURG); + break; case DID_INTEL_BROADWELL_IMC_HA0: /* Broadwell/Y/U Core m */ IVB_CAP(RO(Shm), RO(Proc), RO(Core)); HSW_IMC(RO(Shm), RO(Proc)); diff --git a/corefreqk.c b/corefreqk.c index 07d0c49f..74324826 100644 --- a/corefreqk.c +++ b/corefreqk.c @@ -5018,7 +5018,7 @@ static PCI_CALLBACK IVB_IMC(struct pci_dev *dev) static PCI_CALLBACK SNB_EP_HB(struct pci_dev *dev) { UNUSED(dev); -/*TODO(Harware E5-2640 for testings) */ + /* For post decoding, record HostBridge as present */ return (PCI_CALLBACK) 0; } @@ -5049,14 +5049,12 @@ kernel_ulong_t SNB_EP_CTRL(struct pci_dev *dev, unsigned short mc) pci_read_config_dword(dev, 0x80, &PUBLIC(RO(Proc))->Uncore.MC[mc].SNB_EP.TAD.value); - +/*TODO(CleanUp) PUBLIC(RO(Proc))->Uncore.MC[mc].ChannelCount = \ PUBLIC(RO(Proc))->Uncore.MC[mc].SNB_EP.TAD.CH_WAY; PUBLIC(RO(Proc))->Uncore.MC[mc].ChannelCount++; -/*TODO(Specs missing)*/ - PUBLIC(RO(Proc))->Uncore.MC[mc].SlotCount = 2; - +*/ return 0; } @@ -5103,47 +5101,129 @@ kernel_ulong_t SNB_EP_IMC(struct pci_dev *dev , unsigned short mc, static PCI_CALLBACK SNB_EP_IMC_CTRL0_CHA0(struct pci_dev *dev) { - return (PCI_CALLBACK) SNB_EP_IMC(dev, 0, 0); + const unsigned short + channelMap = PUBLIC(RO(Proc))->Uncore.MC[0].SNB_EP.TECH.CHN_DISABLE; + + if (BITVAL(channelMap, 0) == 0) { + if (PUBLIC(RO(Proc))->Uncore.MC[0].ChannelCount < 1) { + PUBLIC(RO(Proc))->Uncore.MC[0].ChannelCount = 1; + } + return (PCI_CALLBACK) SNB_EP_IMC(dev, 0, 0); + } else { + return (PCI_CALLBACK) -ENODEV; + } } static PCI_CALLBACK SNB_EP_IMC_CTRL0_CHA1(struct pci_dev *dev) { - return (PCI_CALLBACK) SNB_EP_IMC(dev, 0, 1); + const unsigned short + channelMap = PUBLIC(RO(Proc))->Uncore.MC[0].SNB_EP.TECH.CHN_DISABLE; + + if (BITVAL(channelMap, 1) == 0) { + if (PUBLIC(RO(Proc))->Uncore.MC[0].ChannelCount < 2) { + PUBLIC(RO(Proc))->Uncore.MC[0].ChannelCount = 2; + } + return (PCI_CALLBACK) SNB_EP_IMC(dev, 0, 1); + } else { + return (PCI_CALLBACK) -ENODEV; + } } static PCI_CALLBACK SNB_EP_IMC_CTRL0_CHA2(struct pci_dev *dev) { - return (PCI_CALLBACK) SNB_EP_IMC(dev, 0, 2); + const unsigned short + channelMap = PUBLIC(RO(Proc))->Uncore.MC[0].SNB_EP.TECH.CHN_DISABLE; + + if (BITVAL(channelMap, 2) == 0) { + if (PUBLIC(RO(Proc))->Uncore.MC[0].ChannelCount < 3) { + PUBLIC(RO(Proc))->Uncore.MC[0].ChannelCount = 3; + } + return (PCI_CALLBACK) SNB_EP_IMC(dev, 0, 2); + } else { + return (PCI_CALLBACK) -ENODEV; + } } static PCI_CALLBACK SNB_EP_IMC_CTRL0_CHA3(struct pci_dev *dev) { - return (PCI_CALLBACK) SNB_EP_IMC(dev, 0, 3); + const unsigned short + channelMap = PUBLIC(RO(Proc))->Uncore.MC[0].SNB_EP.TECH.CHN_DISABLE; + + if (BITVAL(channelMap, 3) == 0) { + if (PUBLIC(RO(Proc))->Uncore.MC[0].ChannelCount < 4) { + PUBLIC(RO(Proc))->Uncore.MC[0].ChannelCount = 4; + } + return (PCI_CALLBACK) SNB_EP_IMC(dev, 0, 3); + } else { + return (PCI_CALLBACK) -ENODEV; + } } static PCI_CALLBACK SNB_EP_IMC_CTRL1_CHA0(struct pci_dev *dev) { - return (PCI_CALLBACK) SNB_EP_IMC(dev, 1, 0); + const unsigned short + channelMap = PUBLIC(RO(Proc))->Uncore.MC[1].SNB_EP.TECH.CHN_DISABLE; + + if (BITVAL(channelMap, 0) == 0) { + if (PUBLIC(RO(Proc))->Uncore.MC[1].ChannelCount < 1) { + PUBLIC(RO(Proc))->Uncore.MC[1].ChannelCount = 1; + } + return (PCI_CALLBACK) SNB_EP_IMC(dev, 1, 0); + } else { + return (PCI_CALLBACK) -ENODEV; + } } static PCI_CALLBACK SNB_EP_IMC_CTRL1_CHA1(struct pci_dev *dev) { - return (PCI_CALLBACK) SNB_EP_IMC(dev, 1, 1); + const unsigned short + channelMap = PUBLIC(RO(Proc))->Uncore.MC[1].SNB_EP.TECH.CHN_DISABLE; + + if (BITVAL(channelMap, 1) == 0) { + if (PUBLIC(RO(Proc))->Uncore.MC[1].ChannelCount < 2) { + PUBLIC(RO(Proc))->Uncore.MC[1].ChannelCount = 2; + } + return (PCI_CALLBACK) SNB_EP_IMC(dev, 1, 1); + } else { + return (PCI_CALLBACK) -ENODEV; + } } static PCI_CALLBACK SNB_EP_IMC_CTRL1_CHA2(struct pci_dev *dev) { - return (PCI_CALLBACK) SNB_EP_IMC(dev, 1, 2); + const unsigned short + channelMap = PUBLIC(RO(Proc))->Uncore.MC[1].SNB_EP.TECH.CHN_DISABLE; + + if (BITVAL(channelMap, 2) == 0) { + if (PUBLIC(RO(Proc))->Uncore.MC[1].ChannelCount < 3) { + PUBLIC(RO(Proc))->Uncore.MC[1].ChannelCount = 3; + } + return (PCI_CALLBACK) SNB_EP_IMC(dev, 1, 2); + } else { + return (PCI_CALLBACK) -ENODEV; + } } static PCI_CALLBACK SNB_EP_IMC_CTRL1_CHA3(struct pci_dev *dev) { - return (PCI_CALLBACK) SNB_EP_IMC(dev, 1, 3); + const unsigned short + channelMap = PUBLIC(RO(Proc))->Uncore.MC[1].SNB_EP.TECH.CHN_DISABLE; + + if (BITVAL(channelMap, 3) == 0) { + if (PUBLIC(RO(Proc))->Uncore.MC[1].ChannelCount < 4) { + PUBLIC(RO(Proc))->Uncore.MC[1].ChannelCount = 4; + } + return (PCI_CALLBACK) SNB_EP_IMC(dev, 1, 3); + } else { + return (PCI_CALLBACK) -ENODEV; + } } kernel_ulong_t SNB_EP_TAD(struct pci_dev *dev, unsigned short mc, unsigned short cha) { + unsigned short slotCount; + pci_read_config_dword(dev, 0x80, &PUBLIC(RO(Proc))->Uncore.MC[mc].Channel[cha].DIMM[0].MTR.value); @@ -5152,6 +5232,15 @@ kernel_ulong_t SNB_EP_TAD(struct pci_dev *dev, unsigned short mc, pci_read_config_dword(dev, 0x88, &PUBLIC(RO(Proc))->Uncore.MC[mc].Channel[cha].DIMM[2].MTR.value); + + slotCount = \ + PUBLIC(RO(Proc))->Uncore.MC[mc].Channel[cha].DIMM[0].MTR.DIMM_POP + + PUBLIC(RO(Proc))->Uncore.MC[mc].Channel[cha].DIMM[1].MTR.DIMM_POP + + PUBLIC(RO(Proc))->Uncore.MC[mc].Channel[cha].DIMM[2].MTR.DIMM_POP; + + if (slotCount > PUBLIC(RO(Proc))->Uncore.MC[mc].SlotCount) { + PUBLIC(RO(Proc))->Uncore.MC[mc].SlotCount = slotCount; + } return 0; } @@ -5226,6 +5315,164 @@ static PCI_CALLBACK HSW_CLK(struct pci_dev *dev) return HSW_HOST(dev, Query_HSW_CLK); } +kernel_ulong_t HSW_EP_CTRL(struct pci_dev *dev, unsigned short mc) +{ + pci_read_config_dword(dev, 0x7c, + &PUBLIC(RO(Proc))->Uncore.MC[mc].HSW_EP.TECH.value); + + pci_read_config_dword(dev, 0x80, + &PUBLIC(RO(Proc))->Uncore.MC[mc].HSW_EP.TAD.value); + + PUBLIC(RO(Proc))->Uncore.MC[mc].ChannelCount = \ + PUBLIC(RO(Proc))->Uncore.MC[mc].HSW_EP.TAD.CH_WAY; + + PUBLIC(RO(Proc))->Uncore.MC[mc].ChannelCount++; + + return 0; +} + +static PCI_CALLBACK HSW_EP_CTRL0(struct pci_dev *dev) +{ + if (PUBLIC(RO(Proc))->Uncore.CtrlCount < 1) { + PUBLIC(RO(Proc))->Uncore.CtrlCount = 1; + } + HSW_EP_CTRL(dev, 0); + + return (PCI_CALLBACK) 0; +} + +static PCI_CALLBACK HSW_EP_CTRL1(struct pci_dev *dev) +{ + if (PUBLIC(RO(Proc))->Uncore.CtrlCount < 2) { + PUBLIC(RO(Proc))->Uncore.CtrlCount = 2; + } + HSW_EP_CTRL(dev, 1); + + return (PCI_CALLBACK) 0; +} + +#define HSW_EP_IMC SNB_EP_IMC + +static PCI_CALLBACK HSW_EP_IMC_CTRL0_CHA0(struct pci_dev *dev) +{ + const unsigned short + channelMap = PUBLIC(RO(Proc))->Uncore.MC[0].HSW_EP.TECH.CHN_DISABLE; + + if (BITVAL(channelMap, 0) == 0) { + if (PUBLIC(RO(Proc))->Uncore.MC[0].ChannelCount < 1) { + PUBLIC(RO(Proc))->Uncore.MC[0].ChannelCount = 1; + } + return (PCI_CALLBACK) HSW_EP_IMC(dev, 0, 0); + } else { + return (PCI_CALLBACK) -ENODEV; + } +} + +static PCI_CALLBACK HSW_EP_IMC_CTRL0_CHA1(struct pci_dev *dev) +{ + const unsigned short + channelMap = PUBLIC(RO(Proc))->Uncore.MC[0].HSW_EP.TECH.CHN_DISABLE; + + if (BITVAL(channelMap, 1) == 0) { + if (PUBLIC(RO(Proc))->Uncore.MC[0].ChannelCount < 2) { + PUBLIC(RO(Proc))->Uncore.MC[0].ChannelCount = 2; + } + return (PCI_CALLBACK) HSW_EP_IMC(dev, 0, 1); + } else { + return (PCI_CALLBACK) -ENODEV; + } +} + +static PCI_CALLBACK HSW_EP_IMC_CTRL0_CHA2(struct pci_dev *dev) +{ + const unsigned short + channelMap = PUBLIC(RO(Proc))->Uncore.MC[0].HSW_EP.TECH.CHN_DISABLE; + + if (BITVAL(channelMap, 2) == 0) { + if (PUBLIC(RO(Proc))->Uncore.MC[0].ChannelCount < 3) { + PUBLIC(RO(Proc))->Uncore.MC[0].ChannelCount = 3; + } + return (PCI_CALLBACK) HSW_EP_IMC(dev, 0, 2); + } else { + return (PCI_CALLBACK) -ENODEV; + } +} + +static PCI_CALLBACK HSW_EP_IMC_CTRL0_CHA3(struct pci_dev *dev) +{ + const unsigned short + channelMap = PUBLIC(RO(Proc))->Uncore.MC[0].HSW_EP.TECH.CHN_DISABLE; + + if (BITVAL(channelMap, 3) == 0) { + if (PUBLIC(RO(Proc))->Uncore.MC[0].ChannelCount < 4) { + PUBLIC(RO(Proc))->Uncore.MC[0].ChannelCount = 4; + } + return (PCI_CALLBACK) HSW_EP_IMC(dev, 0, 3); + } else { + return (PCI_CALLBACK) -ENODEV; + } +} + +static PCI_CALLBACK HSW_EP_IMC_CTRL1_CHA0(struct pci_dev *dev) +{ + const unsigned short + channelMap = PUBLIC(RO(Proc))->Uncore.MC[1].HSW_EP.TECH.CHN_DISABLE; + + if (BITVAL(channelMap, 0) == 0) { + if (PUBLIC(RO(Proc))->Uncore.MC[1].ChannelCount < 1) { + PUBLIC(RO(Proc))->Uncore.MC[1].ChannelCount = 1; + } + return (PCI_CALLBACK) HSW_EP_IMC(dev, 1, 0); + } else { + return (PCI_CALLBACK) -ENODEV; + } +} + +static PCI_CALLBACK HSW_EP_IMC_CTRL1_CHA1(struct pci_dev *dev) +{ + const unsigned short + channelMap = PUBLIC(RO(Proc))->Uncore.MC[1].HSW_EP.TECH.CHN_DISABLE; + + if (BITVAL(channelMap, 1) == 0) { + if (PUBLIC(RO(Proc))->Uncore.MC[1].ChannelCount < 2) { + PUBLIC(RO(Proc))->Uncore.MC[1].ChannelCount = 2; + } + return (PCI_CALLBACK) HSW_EP_IMC(dev, 1, 1); + } else { + return (PCI_CALLBACK) -ENODEV; + } +} + +static PCI_CALLBACK HSW_EP_IMC_CTRL1_CHA2(struct pci_dev *dev) +{ + const unsigned short + channelMap = PUBLIC(RO(Proc))->Uncore.MC[1].HSW_EP.TECH.CHN_DISABLE; + + if (BITVAL(channelMap, 2) == 0) { + if (PUBLIC(RO(Proc))->Uncore.MC[1].ChannelCount < 3) { + PUBLIC(RO(Proc))->Uncore.MC[1].ChannelCount = 3; + } + return (PCI_CALLBACK) HSW_EP_IMC(dev, 1, 2); + } else { + return (PCI_CALLBACK) -ENODEV; + } +} + +static PCI_CALLBACK HSW_EP_IMC_CTRL1_CHA3(struct pci_dev *dev) +{ + const unsigned short + channelMap = PUBLIC(RO(Proc))->Uncore.MC[1].HSW_EP.TECH.CHN_DISABLE; + + if (BITVAL(channelMap, 3) == 0) { + if (PUBLIC(RO(Proc))->Uncore.MC[1].ChannelCount < 4) { + PUBLIC(RO(Proc))->Uncore.MC[1].ChannelCount = 4; + } + return (PCI_CALLBACK) HSW_EP_IMC(dev, 1, 3); + } else { + return (PCI_CALLBACK) -ENODEV; + } +} + void SoC_SKL_VTD(void) { if (PUBLIC(RO(Proc))->Uncore.Bus.SKL_Cap_A.VT_d == 0) diff --git a/corefreqk.h b/corefreqk.h index 234cfa61..1681046d 100644 --- a/corefreqk.h +++ b/corefreqk.h @@ -1993,6 +1993,27 @@ static PCI_CALLBACK SNB_EP_TAD_CTRL1_CHA2(struct pci_dev *dev) ; static PCI_CALLBACK SNB_EP_TAD_CTRL1_CHA3(struct pci_dev *dev) ; static PCI_CALLBACK HSW_IMC(struct pci_dev *dev) ; static PCI_CALLBACK HSW_CLK(struct pci_dev *dev) ; +#define HSW_EP_HB SNB_EP_HB +#define HSW_EP_QPI SNB_EP_QPI +#define HSW_EP_CAP SNB_EP_CAP +static PCI_CALLBACK HSW_EP_CTRL0(struct pci_dev *dev) ; +static PCI_CALLBACK HSW_EP_CTRL1(struct pci_dev *dev) ; +static PCI_CALLBACK HSW_EP_IMC_CTRL0_CHA0(struct pci_dev *dev) ; +static PCI_CALLBACK HSW_EP_IMC_CTRL0_CHA1(struct pci_dev *dev) ; +static PCI_CALLBACK HSW_EP_IMC_CTRL0_CHA2(struct pci_dev *dev) ; +static PCI_CALLBACK HSW_EP_IMC_CTRL0_CHA3(struct pci_dev *dev) ; +static PCI_CALLBACK HSW_EP_IMC_CTRL1_CHA0(struct pci_dev *dev) ; +static PCI_CALLBACK HSW_EP_IMC_CTRL1_CHA1(struct pci_dev *dev) ; +static PCI_CALLBACK HSW_EP_IMC_CTRL1_CHA2(struct pci_dev *dev) ; +static PCI_CALLBACK HSW_EP_IMC_CTRL1_CHA3(struct pci_dev *dev) ; +#define HSW_EP_TAD_CTRL0_CHA0 SNB_EP_TAD_CTRL0_CHA0 +#define HSW_EP_TAD_CTRL0_CHA1 SNB_EP_TAD_CTRL0_CHA1 +#define HSW_EP_TAD_CTRL0_CHA2 SNB_EP_TAD_CTRL0_CHA2 +#define HSW_EP_TAD_CTRL0_CHA3 SNB_EP_TAD_CTRL0_CHA3 +#define HSW_EP_TAD_CTRL1_CHA0 SNB_EP_TAD_CTRL1_CHA0 +#define HSW_EP_TAD_CTRL1_CHA1 SNB_EP_TAD_CTRL1_CHA1 +#define HSW_EP_TAD_CTRL1_CHA2 SNB_EP_TAD_CTRL1_CHA2 +#define HSW_EP_TAD_CTRL1_CHA3 SNB_EP_TAD_CTRL1_CHA3 static PCI_CALLBACK SKL_IMC(struct pci_dev *dev) ; static PCI_CALLBACK CML_PCH(struct pci_dev *dev) ; #define RKL_PCH CML_PCH @@ -2418,6 +2439,105 @@ static struct pci_device_id PCI_Haswell_ids[] = { PCI_VDEVICE(INTEL, DID_INTEL_HASWELL_UY_IMC_HA0), .driver_data = (kernel_ulong_t) HSW_IMC }, +/* Haswell-EP */ + { + PCI_VDEVICE(INTEL, DID_INTEL_HSW_EP_HOST_BRIDGE), + .driver_data = (kernel_ulong_t) HSW_EP_HB + }, +/* QPIMISCSTAT */ + { + PCI_VDEVICE(INTEL, DID_INTEL_HSW_EP_QPI_LINK0), + .driver_data = (kernel_ulong_t) HSW_EP_QPI + }, +/* Power Control Unit */ + { + PCI_VDEVICE(INTEL, DID_INTEL_HSW_EP_CAPABILITY), + .driver_data = (kernel_ulong_t) HSW_EP_CAP + }, +/* Integrated Memory Controller # : IMC Configuration Registers */ + { + PCI_VDEVICE(INTEL, DID_INTEL_HSW_E7_IMC_CTRL0_F0_CPGC), + .driver_data = (kernel_ulong_t) HSW_EP_CTRL0 + }, + { + PCI_VDEVICE(INTEL, DID_INTEL_HSW_E7_IMC_CTRL0_F1_CPGC), + .driver_data = (kernel_ulong_t) HSW_EP_CTRL0 + }, + { + PCI_VDEVICE(INTEL, DID_INTEL_HSW_E7_IMC_CTRL1_F0_CPGC), + .driver_data = (kernel_ulong_t) HSW_EP_CTRL1 + }, + { + PCI_VDEVICE(INTEL, DID_INTEL_HSW_E7_IMC_CTRL1_F1_CPGC), + .driver_data = (kernel_ulong_t) HSW_EP_CTRL1 + }, +/* Integrated Memory Controller # : Channel [m-M] Thermal Registers*/ + { + PCI_VDEVICE(INTEL, DID_INTEL_HSW_EP_IMC_CTRL0_CH0), + .driver_data = (kernel_ulong_t) HSW_EP_IMC_CTRL0_CHA0 + }, + { + PCI_VDEVICE(INTEL, DID_INTEL_HSW_EP_IMC_CTRL0_CH1), + .driver_data = (kernel_ulong_t) HSW_EP_IMC_CTRL0_CHA1 + }, + { + PCI_VDEVICE(INTEL, DID_INTEL_HSW_EP_IMC_CTRL0_CH2), + .driver_data = (kernel_ulong_t) HSW_EP_IMC_CTRL0_CHA2 + }, + { + PCI_VDEVICE(INTEL, DID_INTEL_HSW_EP_IMC_CTRL0_CH3), + .driver_data = (kernel_ulong_t) HSW_EP_IMC_CTRL0_CHA3 + }, + { + PCI_VDEVICE(INTEL, DID_INTEL_HSW_EP_IMC_CTRL1_CH0), + .driver_data = (kernel_ulong_t) HSW_EP_IMC_CTRL1_CHA0 + }, + { + PCI_VDEVICE(INTEL ,DID_INTEL_HSW_EP_IMC_CTRL1_CH1), + .driver_data = (kernel_ulong_t) HSW_EP_IMC_CTRL1_CHA1 + }, + { + PCI_VDEVICE(INTEL, DID_INTEL_HSW_EP_IMC_CTRL1_CH2), + .driver_data = (kernel_ulong_t) HSW_EP_IMC_CTRL1_CHA2 + }, + { + PCI_VDEVICE(INTEL, DID_INTEL_HSW_EP_IMC_CTRL1_CH3), + .driver_data = (kernel_ulong_t) HSW_EP_IMC_CTRL1_CHA3 + }, +/* Integrated Memory Controller 0 : Channel # TAD Registers */ + { + PCI_VDEVICE(INTEL, DID_INTEL_HSW_EP_TAD_CTRL0_CH0), + .driver_data = (kernel_ulong_t) HSW_EP_TAD_CTRL0_CHA0 + }, + { + PCI_VDEVICE(INTEL, DID_INTEL_HSW_EP_TAD_CTRL0_CH1), + .driver_data = (kernel_ulong_t) HSW_EP_TAD_CTRL0_CHA1 + }, + { + PCI_VDEVICE(INTEL, DID_INTEL_HSW_EP_TAD_CTRL0_CH2), + .driver_data = (kernel_ulong_t) HSW_EP_TAD_CTRL0_CHA2 + }, + { + PCI_VDEVICE(INTEL, DID_INTEL_HSW_EP_TAD_CTRL0_CH3), + .driver_data = (kernel_ulong_t) HSW_EP_TAD_CTRL0_CHA3 + }, + { +/* Integrated Memory Controller 1 : Channel # TAD Registers */ + PCI_VDEVICE(INTEL, DID_INTEL_HSW_EP_TAD_CTRL1_CH0), + .driver_data = (kernel_ulong_t) HSW_EP_TAD_CTRL1_CHA0 + }, + { + PCI_VDEVICE(INTEL, DID_INTEL_HSW_EP_TAD_CTRL1_CH1), + .driver_data = (kernel_ulong_t) HSW_EP_TAD_CTRL1_CHA1 + }, + { + PCI_VDEVICE(INTEL, DID_INTEL_HSW_EP_TAD_CTRL1_CH2), + .driver_data = (kernel_ulong_t) HSW_EP_TAD_CTRL1_CHA2 + }, + { + PCI_VDEVICE(INTEL, DID_INTEL_HSW_EP_TAD_CTRL1_CH3), + .driver_data = (kernel_ulong_t) HSW_EP_TAD_CTRL1_CHA3 + }, {0, } }; diff --git a/intelmsr.h b/intelmsr.h index b3d10a2e..1ba13d8f 100644 --- a/intelmsr.h +++ b/intelmsr.h @@ -2710,7 +2710,7 @@ typedef union ReservedBits1 : 4-3, Slow_Mode : 5-4, ReservedBits2 : 32-5; - } IVB_EP; /*TODO( was first defined in SNB_EP as QPIMISCSTAT ) */ + } IVB_EP; /* Defined in SNB_EP as QPIMISCSTAT. HSW_EP: 111=9600 */ } QPI_FREQUENCY; @@ -3077,13 +3077,13 @@ typedef union { /* Device: 15,29 - Function: 0 - Offset: 7Ch */ unsigned int value; struct { - unsigned int + unsigned int /* E5-1600/2400/2600/4600 */ CLOSE_PG : 1-0, LS_EN : 2-1, ECC_EN : 3-2, DIR_EN : 4-3, ReservedBits1 : 8-4, - Mode : 9-8, + Normal_Mode : 9-8, BANK_XOR_EN : 10-9, CPGC_IOSAV : 12-10, IMC_MODE : 14-12, @@ -3233,6 +3233,49 @@ typedef union }; } HSW_BIOS_MEMCLOCK; +typedef union +{ /* Device: 19,22 - Function: 0 - Offset: 7Ch */ + unsigned int value; + struct { + unsigned int /* E5-1600/2600 and E7 v3 (HSW-2015) */ + CLOSE_PG : 1-0, + LS_EN : 2-1, + ECC_EN : 3-2, + DIR_EN : 4-3, + ReservedBits1 : 8-4, + Normal_Mode : 9-8, /* 0: Training ; 1: Normal */ + ReservedBits2 : 12-9, + IMC_MODE : 14-12, /* 00:Native DDR; 10:SubCh; 11:Perf */ + DDR4_Mode : 15-14, + ReservedBits3 : 16-15, + Pass76 : 18-16, + CHN_DISABLE : 22-18, + ReservedBits4 : 32-22; + }; +} HSW_EP_MC_TECH; + +#define HSW_EP_TADWAYNESS SNB_EP_TADWAYNESS + +typedef union +{ /* Device: 19,22 - Function: 2,3,4,5 - Offset: 80h, 84h, 88h */ + unsigned int value; + struct { + unsigned int + CA_WIDTH : 2-0, + RA_WIDTH : 5-2, + DDR3_DNSTY : 7-5, + DDR3_WIDTH : 9-7, + ReservedBits1 : 12-9, + RANK_CNT : 14-12, + DIMM_POP : 15-14, + ReservedBits2 : 16-15, + RANK_DISABLE : 20-16, + DDR4_Mode : 21-20, /* Must be the same on all channels */ + HDRL : 22-21, /* High Density Reduced Load mode */ + HDRL_Parity : 23-22, + ReservedBits3 : 32-23; + }; +} HSW_EP_DIMM_MTR; typedef union { /* Device: 0 - Function: 0 - Offset Channel0: 4000h & Channel1: 4400h */