1313#include "edac_module.h"
1414#include "skx_common.h"
1515
16- #define I10NM_REVISION "v0.0.4 "
16+ #define I10NM_REVISION "v0.0.5 "
1717#define EDAC_MOD_STR "i10nm_edac"
1818
1919/* Debug macros */
2626 pci_read_config_dword((d)->uracu, 0xd8 + (i) * 4, &(reg))
2727#define I10NM_GET_SAD (d , offset , i , reg )\
2828 pci_read_config_dword((d)->sad_all, (offset) + (i) * 8, &(reg))
29+ #define I10NM_GET_HBM_IMC_BAR (d , reg ) \
30+ pci_read_config_dword((d)->uracu, 0xd4, &(reg))
31+ #define I10NM_GET_CAPID3_CFG (d , reg ) \
32+ pci_read_config_dword((d)->pcu_cr3, 0x90, &(reg))
2933#define I10NM_GET_DIMMMTR (m , i , j ) \
30- readl((m)->mbase + 0x2080c + (i) * (m)->chan_mmio_sz + (j) * 4)
34+ readl((m)->mbase + ((m)->hbm_mc ? 0x80c : 0x2080c) + \
35+ (i) * (m)->chan_mmio_sz + (j) * 4)
3136#define I10NM_GET_MCDDRTCFG (m , i , j ) \
32- readl((m)->mbase + 0x20970 + (i) * (m)->chan_mmio_sz + (j) * 4)
37+ readl((m)->mbase + ((m)->hbm_mc ? 0x970 : 0x20970) + \
38+ (i) * (m)->chan_mmio_sz + (j) * 4)
3339#define I10NM_GET_MCMTR (m , i ) \
34- readl((m)->mbase + 0x20ef8 + (i) * (m)->chan_mmio_sz)
40+ readl((m)->mbase + ((m)->hbm_mc ? 0xef8 : 0x20ef8) + \
41+ (i) * (m)->chan_mmio_sz)
3542#define I10NM_GET_AMAP (m , i ) \
36- readl((m)->mbase + 0x20814 + (i) * (m)->chan_mmio_sz)
43+ readl((m)->mbase + ((m)->hbm_mc ? 0x814 : 0x20814) + \
44+ (i) * (m)->chan_mmio_sz)
3745
3846#define I10NM_GET_SCK_MMIO_BASE (reg ) (GET_BITFIELD(reg, 0, 28) << 23)
3947#define I10NM_GET_IMC_MMIO_OFFSET (reg ) (GET_BITFIELD(reg, 0, 10) << 12)
4048#define I10NM_GET_IMC_MMIO_SIZE (reg ) ((GET_BITFIELD(reg, 13, 23) - \
4149 GET_BITFIELD(reg, 0, 10) + 1) << 12)
50+ #define I10NM_GET_HBM_IMC_MMIO_OFFSET (reg ) \
51+ ((GET_BITFIELD(reg, 0, 10) << 12) + 0x140000)
52+
53+ #define I10NM_HBM_IMC_MMIO_SIZE 0x9000
54+ #define I10NM_IS_HBM_PRESENT (reg ) GET_BITFIELD(reg, 27, 30)
55+ #define I10NM_IS_HBM_IMC (reg ) GET_BITFIELD(reg, 29, 29)
4256
4357#define I10NM_MAX_SAD 16
4458#define I10NM_SAD_ENABLE (reg ) GET_BITFIELD(reg, 0, 0)
@@ -94,7 +108,7 @@ static bool i10nm_check_2lm(struct res_config *cfg)
94108 return false;
95109}
96110
97- static int i10nm_get_all_munits (void )
111+ static int i10nm_get_ddr_munits (void )
98112{
99113 struct pci_dev * mdev ;
100114 void __iomem * mbase ;
@@ -122,7 +136,7 @@ static int i10nm_get_all_munits(void)
122136 edac_dbg (2 , "socket%d mmio base 0x%llx (reg 0x%x)\n" ,
123137 j ++ , base , reg );
124138
125- for (i = 0 ; i < I10NM_NUM_IMC ; i ++ ) {
139+ for (i = 0 ; i < I10NM_NUM_DDR_IMC ; i ++ ) {
126140 mdev = pci_get_dev_wrapper (d -> seg , d -> bus [0 ],
127141 12 + i , 0 );
128142 if (i == 0 && !mdev ) {
@@ -158,6 +172,90 @@ static int i10nm_get_all_munits(void)
158172 return 0 ;
159173}
160174
175+ static bool i10nm_check_hbm_imc (struct skx_dev * d )
176+ {
177+ u32 reg ;
178+
179+ if (I10NM_GET_CAPID3_CFG (d , reg )) {
180+ i10nm_printk (KERN_ERR , "Failed to get capid3_cfg\n" );
181+ return false;
182+ }
183+
184+ return I10NM_IS_HBM_PRESENT (reg ) != 0 ;
185+ }
186+
187+ static int i10nm_get_hbm_munits (void )
188+ {
189+ struct pci_dev * mdev ;
190+ void __iomem * mbase ;
191+ u32 reg , off , mcmtr ;
192+ struct skx_dev * d ;
193+ int i , lmc ;
194+ u64 base ;
195+
196+ list_for_each_entry (d , i10nm_edac_list , list ) {
197+ d -> pcu_cr3 = pci_get_dev_wrapper (d -> seg , d -> bus [1 ], 30 , 3 );
198+ if (!d -> pcu_cr3 )
199+ return - ENODEV ;
200+
201+ if (!i10nm_check_hbm_imc (d )) {
202+ i10nm_printk (KERN_DEBUG , "No hbm memory\n" );
203+ return - ENODEV ;
204+ }
205+
206+ if (I10NM_GET_SCK_BAR (d , reg )) {
207+ i10nm_printk (KERN_ERR , "Failed to get socket bar\n" );
208+ return - ENODEV ;
209+ }
210+ base = I10NM_GET_SCK_MMIO_BASE (reg );
211+
212+ if (I10NM_GET_HBM_IMC_BAR (d , reg )) {
213+ i10nm_printk (KERN_ERR , "Failed to get hbm mc bar\n" );
214+ return - ENODEV ;
215+ }
216+ base += I10NM_GET_HBM_IMC_MMIO_OFFSET (reg );
217+
218+ lmc = I10NM_NUM_DDR_IMC ;
219+
220+ for (i = 0 ; i < I10NM_NUM_HBM_IMC ; i ++ ) {
221+ mdev = pci_get_dev_wrapper (d -> seg , d -> bus [0 ],
222+ 12 + i / 4 , 1 + i % 4 );
223+ if (i == 0 && !mdev ) {
224+ i10nm_printk (KERN_ERR , "No hbm mc found\n" );
225+ return - ENODEV ;
226+ }
227+ if (!mdev )
228+ continue ;
229+
230+ d -> imc [lmc ].mdev = mdev ;
231+ off = i * I10NM_HBM_IMC_MMIO_SIZE ;
232+
233+ edac_dbg (2 , "hbm mc%d mmio base 0x%llx size 0x%x\n" ,
234+ lmc , base + off , I10NM_HBM_IMC_MMIO_SIZE );
235+
236+ mbase = ioremap (base + off , I10NM_HBM_IMC_MMIO_SIZE );
237+ if (!mbase ) {
238+ i10nm_printk (KERN_ERR , "Failed to ioremap for hbm mc 0x%llx\n" ,
239+ base + off );
240+ return - ENOMEM ;
241+ }
242+
243+ d -> imc [lmc ].mbase = mbase ;
244+ d -> imc [lmc ].hbm_mc = true;
245+
246+ mcmtr = I10NM_GET_MCMTR (& d -> imc [lmc ], 0 );
247+ if (!I10NM_IS_HBM_IMC (mcmtr )) {
248+ i10nm_printk (KERN_ERR , "This isn't an hbm mc!\n" );
249+ return - ENODEV ;
250+ }
251+
252+ lmc ++ ;
253+ }
254+ }
255+
256+ return 0 ;
257+ }
258+
161259static struct res_config i10nm_cfg0 = {
162260 .type = I10NM ,
163261 .decs_did = 0x3452 ,
@@ -181,6 +279,7 @@ static struct res_config spr_cfg = {
181279 .decs_did = 0x3252 ,
182280 .busno_cfg_offset = 0xd0 ,
183281 .ddr_chan_mmio_sz = 0x8000 ,
282+ .hbm_chan_mmio_sz = 0x4000 ,
184283 .support_ddr5 = true,
185284 .sad_all_devfn = PCI_DEVFN (10 , 0 ),
186285 .sad_all_offset = 0x300 ,
@@ -216,13 +315,13 @@ static int i10nm_get_dimm_config(struct mem_ctl_info *mci,
216315 struct dimm_info * dimm ;
217316 int i , j , ndimms ;
218317
219- for (i = 0 ; i < I10NM_NUM_CHANNELS ; i ++ ) {
318+ for (i = 0 ; i < imc -> num_channels ; i ++ ) {
220319 if (!imc -> mbase )
221320 continue ;
222321
223322 ndimms = 0 ;
224323 amap = I10NM_GET_AMAP (imc , i );
225- for (j = 0 ; j < I10NM_NUM_DIMMS ; j ++ ) {
324+ for (j = 0 ; j < imc -> num_dimms ; j ++ ) {
226325 dimm = edac_get_dimm (mci , i , j , 0 );
227326 mtr = I10NM_GET_DIMMMTR (imc , i , j );
228327 mcddrtcfg = I10NM_GET_MCDDRTCFG (imc , i , j );
@@ -335,8 +434,9 @@ static int __init i10nm_init(void)
335434
336435 skx_set_mem_cfg (i10nm_check_2lm (cfg ));
337436
338- rc = i10nm_get_all_munits ();
339- if (rc < 0 )
437+ rc = i10nm_get_ddr_munits ();
438+
439+ if (i10nm_get_hbm_munits () && rc )
340440 goto fail ;
341441
342442 list_for_each_entry (d , i10nm_edac_list , list ) {
@@ -357,7 +457,15 @@ static int __init i10nm_init(void)
357457 d -> imc [i ].lmc = i ;
358458 d -> imc [i ].src_id = src_id ;
359459 d -> imc [i ].node_id = node_id ;
360- d -> imc [i ].chan_mmio_sz = cfg -> ddr_chan_mmio_sz ;
460+ if (d -> imc [i ].hbm_mc ) {
461+ d -> imc [i ].chan_mmio_sz = cfg -> hbm_chan_mmio_sz ;
462+ d -> imc [i ].num_channels = I10NM_NUM_HBM_CHANNELS ;
463+ d -> imc [i ].num_dimms = I10NM_NUM_HBM_DIMMS ;
464+ } else {
465+ d -> imc [i ].chan_mmio_sz = cfg -> ddr_chan_mmio_sz ;
466+ d -> imc [i ].num_channels = I10NM_NUM_DDR_CHANNELS ;
467+ d -> imc [i ].num_dimms = I10NM_NUM_DDR_DIMMS ;
468+ }
361469
362470 rc = skx_register_mci (& d -> imc [i ], d -> imc [i ].mdev ,
363471 "Intel_10nm Socket" , EDAC_MOD_STR ,
0 commit comments