Lines Matching +full:memory +full:- +full:width

1 // SPDX-License-Identifier: GPL-2.0
3 * Driver for Intel(R) servers with Integrated Memory/IO Hub-based memory controller.
10 #include <asm/intel-family.h>
30 /* Memory Controller */
42 * struct local_reg - A register as described in the local package view.
48 * @width: (input) The register width in byte.
57 u8 width; member
65 .pbase = (north ? (cfg)->mmio_base_l_north : \
66 (cfg)->mmio_base_l_south) + \
67 (cfg)->ip_name##_base + \
68 (cfg)->ip_name##_size * (ip_idx), \
69 .size = (cfg)->ip_name##_size, \
70 .offset = (cfg)->ip_name##_reg_##reg_name##_offset, \
71 .width = (cfg)->ip_name##_reg_##reg_name##_width, \
74 static u64 readx(void __iomem *addr, u8 width) in readx() argument
76 switch (width) { in readx()
86 imh_printk(KERN_ERR, "Invalid reg 0x%p width %d\n", addr, width); in readx()
95 r->val = readx(r->vbase + r->offset, r->width); in __read_local_reg()
98 /* Read a local-view register. */
103 /* Get the target CPU in the package @reg->pkg. */ in read_local_reg()
105 if (reg->pkg == topology_physical_package_id(cpu)) in read_local_reg()
112 reg->vbase = ioremap(reg->pbase, reg->size); in read_local_reg()
113 if (!reg->vbase) { in read_local_reg()
114 imh_printk(KERN_ERR, "Failed to ioremap 0x%llx\n", reg->pbase); in read_local_reg()
120 iounmap(reg->vbase); in read_local_reg()
125 /* Get the bitmap of memory controller instances in package @pkg. */
149 unsigned long size = cfg->ddr_chan_mmio_sz * cfg->ddr_chan_num; in __get_ddr_munits()
150 unsigned long bitmap = get_imc_bitmap(cfg, d->pkg, north); in __get_ddr_munits()
157 base = north ? d->mmio_base_h_north : d->mmio_base_h_south; in __get_ddr_munits()
158 base += cfg->ddr_imc_base + size * i; in __get_ddr_munits()
161 d->pkg, lmc, base, size); in __get_ddr_munits()
167 return -ENOMEM; in __get_ddr_munits()
170 d->imc[lmc].mbase = mbase; in __get_ddr_munits()
171 d->imc[lmc].lmc = lmc; in __get_ddr_munits()
176 return -ENOMEM; in __get_ddr_munits()
178 dev->release = imc_release; in __get_ddr_munits()
187 d->imc[lmc].dev = dev; in __get_ddr_munits()
215 DEFINE_LOCAL_REG(reg, cfg, d->pkg, true, ubox, 0, socket_id); in get_socket_id()
225 for (i = 0; i < cfg->ddr_imc_num; i++) in get_socket_id()
226 d->imc[i].src_id = src_id; in get_socket_id()
231 /* Get TOLM (Top Of Low Memory) and TOHM (Top Of High Memory) parameters. */
253 /* Get the system-view MMIO_BASE_H for {north,south}-IMH. */
256 int i, n = topology_max_packages(), imc_num = cfg->ddr_imc_num + cfg->hbm_imc_num; in imh_get_all_mmio_base_h()
262 return -ENOMEM; in imh_get_all_mmio_base_h()
266 /* Get MMIO_BASE_H for the north-IMH. */ in imh_get_all_mmio_base_h()
270 return -ENODEV; in imh_get_all_mmio_base_h()
273 d->mmio_base_h_north = MMIO_BASE_H(reg.val); in imh_get_all_mmio_base_h()
275 i, d->mmio_base_h_north, reg.val); in imh_get_all_mmio_base_h()
277 /* Get MMIO_BASE_H for the south-IMH (optional). */ in imh_get_all_mmio_base_h()
281 d->mmio_base_h_south = MMIO_BASE_H(reg2.val); in imh_get_all_mmio_base_h()
283 i, d->mmio_base_h_south, reg2.val); in imh_get_all_mmio_base_h()
286 d->pkg = i; in imh_get_all_mmio_base_h()
287 d->num_imc = imc_num; in imh_get_all_mmio_base_h()
289 list_add_tail(&d->list, edac_list); in imh_get_all_mmio_base_h()
295 /* Get the number of per-package memory controllers. */
303 return -ENODEV; in imh_get_imc_num()
306 if (cfg->ddr_imc_num != imc_num) { in imh_get_imc_num()
309 * present DDR memory controllers. in imh_get_imc_num()
311 cfg->ddr_imc_num = imc_num; in imh_get_imc_num()
318 /* Get all memory controllers' parameters. */
329 return -ENODEV; in imh_get_munits()
334 return -ENODEV; in imh_get_munits()
337 for (i = 0; i < cfg->ddr_imc_num; i++) { in imh_get_munits()
338 imc = &d->imc[i]; in imh_get_munits()
339 if (!imc->mbase) in imh_get_munits()
342 imc->chan_mmio_sz = cfg->ddr_chan_mmio_sz; in imh_get_munits()
343 imc->num_channels = cfg->ddr_chan_num; in imh_get_munits()
344 imc->num_dimms = cfg->ddr_dimm_num; in imh_get_munits()
345 imc->mc = mc++; in imh_get_munits()
354 DEFINE_LOCAL_REG(reg, cfg, d->pkg, true, ha, ha_idx, mode); in check_2lm_enabled()
362 edac_dbg(2, "2-level memory configuration (reg 0x%llx, ha idx %d)\n", reg.val, ha_idx); in check_2lm_enabled()
366 /* Check whether the system has a 2-level memory configuration. */
373 for (i = 0; i < cfg->ddr_imc_num; i++) in imh_2lm_enabled()
381 /* Helpers to read memory controller registers */
382 static u64 read_imc_reg(struct skx_imc *imc, int chan, u32 offset, u8 width) in read_imc_reg() argument
384 return readx(imc->mbase + imc->chan_mmio_sz * chan + offset, width); in read_imc_reg()
389 return (u32)read_imc_reg(imc, chan, cfg->ddr_reg_mcmtr_offset, cfg->ddr_reg_mcmtr_width); in read_imc_mcmtr()
394 return (u32)read_imc_reg(imc, chan, cfg->ddr_reg_dimmmtr_offset + in read_imc_dimmmtr()
395 cfg->ddr_reg_dimmmtr_width * dimm, in read_imc_dimmmtr()
396 cfg->ddr_reg_dimmmtr_width); in read_imc_dimmmtr()
409 /* Get each DIMM's configurations of the memory controller @mci. */
412 struct skx_pvt *pvt = mci->pvt_info; in imh_get_dimm_config()
413 struct skx_imc *imc = pvt->imc; in imh_get_dimm_config()
418 for (i = 0; i < imc->num_channels; i++) { in imh_get_dimm_config()
419 if (!imc->mbase) in imh_get_dimm_config()
424 for (ndimms = 0, j = 0; j < imc->num_dimms; j++) { in imh_get_dimm_config()
427 mcmtr, dimmmtr, imc->mc, i, j); in imh_get_dimm_config()
439 imc->mc, i); in imh_get_dimm_config()
440 return -ENODEV; in imh_get_dimm_config()
447 /* Register all memory controllers to the EDAC core. */
455 for (i = 0; i < cfg->ddr_imc_num; i++) { in imh_register_mci()
456 imc = &d->imc[i]; in imh_register_mci()
457 if (!imc->mbase) in imh_register_mci()
460 rc = skx_register_mci(imc, imc->dev, in imh_register_mci()
461 dev_name(imc->dev), in imh_register_mci()
462 "Intel IMH-based Socket", in imh_register_mci()
531 return -EBUSY; in imh_init()
535 return -EBUSY; in imh_init()
538 return -ENODEV; in imh_init()
542 return -ENODEV; in imh_init()
543 cfg = (struct res_config *)id->driver_data; in imh_init()
547 return -ENODEV; in imh_init()
602 MODULE_DESCRIPTION("MC Driver for Intel servers using IMH-based memory controller");