Lines Matching +full:lo +full:- +full:sideband
1 // SPDX-License-Identifier: GPL-2.0-only
32 #include <asm/intel-family.h>
109 #define SELECTOR_DISABLED (-1)
123 #define GET_BITFIELD(v, lo, hi) (((v) & GENMASK_ULL(hi, lo)) >> (lo)) argument
128 * side-band mailbox style interface in a hidden PCI device
166 ret = -EAGAIN; in _apl_rd_reg()
177 if (retries-- == 0) { in _apl_rd_reg()
178 ret = -EBUSY; in _apl_rd_reg()
214 struct b_cr_mchbar_lo_pci lo; in get_mem_ctrl_hub_base_addr() local
220 pci_read_config_dword(pdev, 0x48, (u32 *)&lo); in get_mem_ctrl_hub_base_addr()
227 if (!lo.enable) { in get_mem_ctrl_hub_base_addr()
232 return U64_LSHIFT(hi.base, 32) | U64_LSHIFT(lo.base, 15); in get_mem_ctrl_hub_base_addr()
238 u32 hi, lo; in get_sideband_reg_base_addr() local
248 pci_read_config_dword(pdev, 0x10, &lo); in get_sideband_reg_base_addr()
250 lo &= 0xfffffff0; in get_sideband_reg_base_addr()
257 return (U64_LSHIFT(hi, 32) | U64_LSHIFT(lo, 0)); in get_sideband_reg_base_addr()
275 return -ENODEV; in dnv_rd_reg()
284 return -ENODEV; in dnv_rd_reg()
287 /* MMIO via sideband register base address */ in dnv_rd_reg()
290 return -ENODEV; in dnv_rd_reg()
297 return -ENODEV; in dnv_rd_reg()
313 ops->rd_reg(port, \
320 ops->rd_reg(regname ## _port, \
334 static int slice_selector = -1;
335 static int chan_selector = -1;
341 rp->enabled = 1; in mk_region()
342 rp->base = base; in mk_region()
343 rp->limit = limit; in mk_region()
361 rp->base = base; in mk_region_mask()
362 rp->limit = (base | ~mask) & GENMASK_ULL(PND_MAX_PHYS_BIT, 0); in mk_region_mask()
363 rp->enabled = 1; in mk_region_mask()
364 edac_dbg(2, "Region:%s [%llx, %llx]\n", name, base, rp->limit); in mk_region_mask()
369 if (!rp->enabled) in in_region()
372 return rp->base <= addr && addr <= rp->limit; in in_region()
379 if (!p->slice_0_mem_disabled) in gen_sym_mask()
380 mask |= p->sym_slice0_channel_enabled; in gen_sym_mask()
382 if (!p->slice_1_disabled) in gen_sym_mask()
383 mask |= p->sym_slice1_channel_enabled << 2; in gen_sym_mask()
385 if (p->ch_1_disabled || p->enable_pmi_dual_data_mode) in gen_sym_mask()
399 if (as2way->asym_2way_interleave_enable) in gen_asym_mask()
400 mask = intlv[as2way->asym_2way_intlv_mode]; in gen_asym_mask()
401 if (as0->slice0_asym_enable) in gen_asym_mask()
402 mask |= (1 << as0->slice0_asym_channel_select); in gen_asym_mask()
403 if (as1->slice1_asym_enable) in gen_asym_mask()
404 mask |= (4 << as1->slice1_asym_channel_select); in gen_asym_mask()
405 if (p->slice_0_mem_disabled) in gen_asym_mask()
407 if (p->slice_1_disabled) in gen_asym_mask()
409 if (p->ch_1_disabled || p->enable_pmi_dual_data_mode) in gen_asym_mask()
451 U64_LSHIFT(a->slice0_asym_base, APL_ASYMSHIFT), in apl_mk_region()
452 U64_LSHIFT(a->slice0_asym_limit, APL_ASYMSHIFT) + in apl_mk_region()
453 GENMASK_ULL(APL_ASYMSHIFT - 1, 0)); in apl_mk_region()
461 U64_LSHIFT(a->slice_asym_base, DNV_ASYMSHIFT), in dnv_mk_region()
462 U64_LSHIFT(a->slice_asym_limit, DNV_ASYMSHIFT) + in dnv_mk_region()
463 GENMASK_ULL(DNV_ASYMSHIFT - 1, 0)); in dnv_mk_region()
468 int ret = -ENODEV; in apl_get_registers()
472 return -ENODEV; in apl_get_registers()
475 * RD_REGP() will fail for unpopulated or non-existent in apl_get_registers()
490 return -ENODEV; in dnv_get_registers()
501 return -ENODEV; in dnv_get_registers()
523 return -ENODEV; in get_registers()
525 if (ops->get_registers()) in get_registers()
526 return -ENODEV; in get_registers()
528 if (ops->type == DNV) { in get_registers()
538 ops->mk_region("as0", &as0, &asym0); in get_registers()
541 ops->mk_region("as1", &as1, &asym1); in get_registers()
547 GENMASK_ULL(APL_ASYMSHIFT - 1, 0)); in get_registers()
612 return (sys < _4GB) ? sys : sys - (_4GB - top_lm); in remove_mmio_gap()
620 if (bitidx == -1) in remove_addr_bit()
623 mask = (1ull << bitidx) - 1; in remove_addr_bit()
662 * to do a 3-way interleave. in sys2pmi()
670 return -EINVAL; in sys2pmi()
680 contig_offset = contig_addr - contig_base; in sys2pmi()
688 contig_offset = contig_addr - contig_base; in sys2pmi()
703 contig_offset = contig_addr - contig_base; in sys2pmi()
930 struct pnd2_pvt *pvt = mci->pvt_info; in apl_pmi2mem()
931 int g = pvt->dimm_geom[pmiidx]; in apl_pmi2mem()
941 return -EINVAL; in apl_pmi2mem()
944 type = d->bits[i + skiprs] & ~0xf; in apl_pmi2mem()
945 idx = d->bits[i + skiprs] & 0xf; in apl_pmi2mem()
951 if (type == RS && (cr_drp0->rken0 + cr_drp0->rken1) == 1) { in apl_pmi2mem()
953 type = d->bits[i + skiprs] & ~0xf; in apl_pmi2mem()
954 idx = d->bits[i + skiprs] & 0xf; in apl_pmi2mem()
963 if (cr_drp0->bahen) in apl_pmi2mem()
964 bank ^= bank_hash(pmiaddr, idx, d->addrdec); in apl_pmi2mem()
971 if (cr_drp0->rsien) in apl_pmi2mem()
977 return -EINVAL; in apl_pmi2mem()
984 daddr->col = column; in apl_pmi2mem()
985 daddr->bank = bank; in apl_pmi2mem()
986 daddr->row = row; in apl_pmi2mem()
987 daddr->rank = rank; in apl_pmi2mem()
988 daddr->dimm = 0; in apl_pmi2mem()
1000 daddr->rank = dnv_get_bit(pmiaddr, dmap[pmiidx].rs0 + 13, 0); in dnv_pmi2mem()
1002 daddr->rank |= dnv_get_bit(pmiaddr, dmap[pmiidx].rs1 + 13, 1); in dnv_pmi2mem()
1008 daddr->dimm = (daddr->rank >= 2) ^ drp[pmiidx].dimmflip; in dnv_pmi2mem()
1010 daddr->bank = dnv_get_bit(pmiaddr, dmap[pmiidx].ba0 + 6, 0); in dnv_pmi2mem()
1011 daddr->bank |= dnv_get_bit(pmiaddr, dmap[pmiidx].ba1 + 6, 1); in dnv_pmi2mem()
1012 daddr->bank |= dnv_get_bit(pmiaddr, dmap[pmiidx].bg0 + 6, 2); in dnv_pmi2mem()
1014 daddr->bank |= dnv_get_bit(pmiaddr, dmap[pmiidx].bg1 + 6, 3); in dnv_pmi2mem()
1017 daddr->bank ^= dnv_get_bit(pmiaddr, dmap3[pmiidx].row6 + 6, 0); in dnv_pmi2mem()
1018 daddr->bank ^= dnv_get_bit(pmiaddr, dmap3[pmiidx].row7 + 6, 1); in dnv_pmi2mem()
1021 daddr->bank ^= dnv_get_bit(pmiaddr, dmap5[pmiidx].ca3 + 6, 2); in dnv_pmi2mem()
1024 daddr->bank ^= dnv_get_bit(pmiaddr, dmap5[pmiidx].ca4 + 6, 2); in dnv_pmi2mem()
1025 daddr->bank ^= dnv_get_bit(pmiaddr, dmap2[pmiidx].row2 + 6, 3); in dnv_pmi2mem()
1027 daddr->bank ^= dnv_get_bit(pmiaddr, dmap2[pmiidx].row2 + 6, 0); in dnv_pmi2mem()
1028 daddr->bank ^= dnv_get_bit(pmiaddr, dmap3[pmiidx].row6 + 6, 1); in dnv_pmi2mem()
1030 daddr->bank ^= dnv_get_bit(pmiaddr, dmap5[pmiidx].ca3 + 6, 2); in dnv_pmi2mem()
1032 daddr->bank ^= dnv_get_bit(pmiaddr, dmap5[pmiidx].ca4 + 6, 2); in dnv_pmi2mem()
1036 daddr->row = dnv_get_bit(pmiaddr, dmap2[pmiidx].row0 + 6, 0); in dnv_pmi2mem()
1037 daddr->row |= dnv_get_bit(pmiaddr, dmap2[pmiidx].row1 + 6, 1); in dnv_pmi2mem()
1038 daddr->row |= dnv_get_bit(pmiaddr, dmap2[pmiidx].row2 + 6, 2); in dnv_pmi2mem()
1039 daddr->row |= dnv_get_bit(pmiaddr, dmap2[pmiidx].row3 + 6, 3); in dnv_pmi2mem()
1040 daddr->row |= dnv_get_bit(pmiaddr, dmap2[pmiidx].row4 + 6, 4); in dnv_pmi2mem()
1041 daddr->row |= dnv_get_bit(pmiaddr, dmap2[pmiidx].row5 + 6, 5); in dnv_pmi2mem()
1042 daddr->row |= dnv_get_bit(pmiaddr, dmap3[pmiidx].row6 + 6, 6); in dnv_pmi2mem()
1043 daddr->row |= dnv_get_bit(pmiaddr, dmap3[pmiidx].row7 + 6, 7); in dnv_pmi2mem()
1044 daddr->row |= dnv_get_bit(pmiaddr, dmap3[pmiidx].row8 + 6, 8); in dnv_pmi2mem()
1045 daddr->row |= dnv_get_bit(pmiaddr, dmap3[pmiidx].row9 + 6, 9); in dnv_pmi2mem()
1046 daddr->row |= dnv_get_bit(pmiaddr, dmap3[pmiidx].row10 + 6, 10); in dnv_pmi2mem()
1047 daddr->row |= dnv_get_bit(pmiaddr, dmap3[pmiidx].row11 + 6, 11); in dnv_pmi2mem()
1048 daddr->row |= dnv_get_bit(pmiaddr, dmap4[pmiidx].row12 + 6, 12); in dnv_pmi2mem()
1049 daddr->row |= dnv_get_bit(pmiaddr, dmap4[pmiidx].row13 + 6, 13); in dnv_pmi2mem()
1051 daddr->row |= dnv_get_bit(pmiaddr, dmap4[pmiidx].row14 + 6, 14); in dnv_pmi2mem()
1053 daddr->row |= dnv_get_bit(pmiaddr, dmap4[pmiidx].row15 + 6, 15); in dnv_pmi2mem()
1055 daddr->row |= dnv_get_bit(pmiaddr, dmap4[pmiidx].row16 + 6, 16); in dnv_pmi2mem()
1057 daddr->row |= dnv_get_bit(pmiaddr, dmap4[pmiidx].row17 + 6, 17); in dnv_pmi2mem()
1059 daddr->col = dnv_get_bit(pmiaddr, dmap5[pmiidx].ca3 + 6, 3); in dnv_pmi2mem()
1060 daddr->col |= dnv_get_bit(pmiaddr, dmap5[pmiidx].ca4 + 6, 4); in dnv_pmi2mem()
1061 daddr->col |= dnv_get_bit(pmiaddr, dmap5[pmiidx].ca5 + 6, 5); in dnv_pmi2mem()
1062 daddr->col |= dnv_get_bit(pmiaddr, dmap5[pmiidx].ca6 + 6, 6); in dnv_pmi2mem()
1063 daddr->col |= dnv_get_bit(pmiaddr, dmap5[pmiidx].ca7 + 6, 7); in dnv_pmi2mem()
1064 daddr->col |= dnv_get_bit(pmiaddr, dmap5[pmiidx].ca8 + 6, 8); in dnv_pmi2mem()
1065 daddr->col |= dnv_get_bit(pmiaddr, dmap5[pmiidx].ca9 + 6, 9); in dnv_pmi2mem()
1067 daddr->col |= dnv_get_bit(pmiaddr, dmap1[pmiidx].ca11 + 13, 11); in dnv_pmi2mem()
1092 return ret ? -EINVAL : 0; in apl_check_ecc_active()
1095 #define DIMMS_PRESENT(d) ((d)->rken0 + (d)->rken1 + (d)->rken2 + (d)->rken3)
1114 return ret ? -EINVAL : 0; in dnv_check_ecc_active()
1128 pmiaddr >>= ops->pmiaddr_shift; in get_memory_error_data()
1130 pmiidx >>= ops->pmiidx_shift; in get_memory_error_data()
1131 daddr->chan = pmiidx; in get_memory_error_data()
1133 ret = ops->pmi2mem(mci, pmiaddr, pmiidx, daddr, msg); in get_memory_error_data()
1138 addr, pmiaddr, daddr->chan, daddr->dimm, daddr->rank, daddr->bank, daddr->row, daddr->col); in get_memory_error_data()
1148 bool ripv = m->mcgstatus & MCG_STATUS_RIPV; in pnd2_mce_output_error()
1149 bool overflow = m->status & MCI_STATUS_OVER; in pnd2_mce_output_error()
1150 bool uc_err = m->status & MCI_STATUS_UC; in pnd2_mce_output_error()
1151 bool recov = m->status & MCI_STATUS_S; in pnd2_mce_output_error()
1152 u32 core_err_cnt = GET_BITFIELD(m->status, 38, 52); in pnd2_mce_output_error()
1153 u32 mscod = GET_BITFIELD(m->status, 16, 31); in pnd2_mce_output_error()
1154 u32 errcode = GET_BITFIELD(m->status, 0, 15); in pnd2_mce_output_error()
1155 u32 optypenum = GET_BITFIELD(m->status, 4, 6); in pnd2_mce_output_error()
1162 * According with Table 15-9 of the Intel Architecture spec vol 3A, in pnd2_mce_output_error()
1198 if (!(m->status & MCI_STATUS_ADDRV)) in pnd2_mce_output_error()
1201 rc = get_memory_error_data(mci, m->addr, daddr, msg); in pnd2_mce_output_error()
1208 errcode, daddr->chan, daddr->dimm, daddr->rank, daddr->row, daddr->bank, daddr->col); in pnd2_mce_output_error()
1213 edac_mc_handle_error(tp_event, mci, core_err_cnt, m->addr >> PAGE_SHIFT, in pnd2_mce_output_error()
1214 m->addr & ~PAGE_MASK, 0, daddr->chan, daddr->dimm, -1, optype, msg); in pnd2_mce_output_error()
1219 edac_mc_handle_error(tp_event, mci, core_err_cnt, 0, 0, 0, -1, -1, -1, msg, ""); in pnd2_mce_output_error()
1224 struct pnd2_pvt *pvt = mci->pvt_info; in apl_get_dimm_config()
1242 if (dimms[g].addrdec == d->addrdec && in apl_get_dimm_config()
1243 dimms[g].dden == d->dden && in apl_get_dimm_config()
1244 dimms[g].dwid == d->dwid) in apl_get_dimm_config()
1252 pvt->dimm_geom[i] = g; in apl_get_dimm_config()
1253 capacity = (d->rken0 + d->rken1) * 8 * (1ul << dimms[g].rowbits) * in apl_get_dimm_config()
1255 edac_dbg(0, "Channel %d: %lld MByte DIMM\n", i, capacity >> (20 - 3)); in apl_get_dimm_config()
1256 dimm->nr_pages = MiB_TO_PAGES(capacity >> (20 - 3)); in apl_get_dimm_config()
1257 dimm->grain = 32; in apl_get_dimm_config()
1258 dimm->dtype = (d->dwid == 0) ? DEV_X8 : DEV_X16; in apl_get_dimm_config()
1259 dimm->mtype = MEM_DDR3; in apl_get_dimm_config()
1260 dimm->edac_mode = EDAC_SECDED; in apl_get_dimm_config()
1261 snprintf(dimm->label, sizeof(dimm->label), "Slice#%d_Chan#%d", i / 2, i % 2); in apl_get_dimm_config()
1306 ranks_of_dimm[0] = d->rken0 + d->rken1; in dnv_get_dimm_config()
1308 ranks_of_dimm[1] = d->rken2 + d->rken3; in dnv_get_dimm_config()
1321 edac_dbg(0, "Channel %d DIMM %d: %lld MByte DIMM\n", i, j, capacity >> (20 - 3)); in dnv_get_dimm_config()
1322 dimm->nr_pages = MiB_TO_PAGES(capacity >> (20 - 3)); in dnv_get_dimm_config()
1323 dimm->grain = 32; in dnv_get_dimm_config()
1324 dimm->dtype = dnv_dtypes[j ? d->dimmdwid0 : d->dimmdwid1]; in dnv_get_dimm_config()
1325 dimm->mtype = memtype; in dnv_get_dimm_config()
1326 dimm->edac_mode = EDAC_SECDED; in dnv_get_dimm_config()
1327 snprintf(dimm->label, sizeof(dimm->label), "Chan#%d_DIMM#%d", i, j); in dnv_get_dimm_config()
1339 rc = ops->check_ecc(); in pnd2_register_mci()
1345 layers[0].size = ops->channels; in pnd2_register_mci()
1348 layers[1].size = ops->dimms_per_channel; in pnd2_register_mci()
1352 return -ENOMEM; in pnd2_register_mci()
1354 pvt = mci->pvt_info; in pnd2_register_mci()
1357 mci->mod_name = EDAC_MOD_STR; in pnd2_register_mci()
1358 mci->dev_name = ops->name; in pnd2_register_mci()
1359 mci->ctl_name = "Pondicherry2"; in pnd2_register_mci()
1362 ops->get_dimm_config(mci); in pnd2_register_mci()
1367 return -EINVAL; in pnd2_register_mci()
1377 if (unlikely(!mci || !mci->pvt_info)) { in pnd2_unregister_mci()
1384 edac_dbg(1, "%s: free mci struct\n", mci->ctl_name); in pnd2_unregister_mci()
1400 if (!mci || (mce->kflags & MCE_HANDLED_CEC)) in pnd2_mce_check_error()
1406 * is indicated by bit 7 = 1 and bits = 8-11,13-15 = 0. in pnd2_mce_check_error()
1409 if ((mce->status & 0xefff) >> 7 != 1) in pnd2_mce_check_error()
1412 if (mce->mcgstatus & MCG_STATUS_MCIP) in pnd2_mce_check_error()
1419 mce->extcpu, type, mce->mcgstatus, mce->bank, mce->status); in pnd2_mce_check_error()
1420 pnd2_mc_printk(mci, KERN_INFO, "TSC %llx ", mce->tsc); in pnd2_mce_check_error()
1421 pnd2_mc_printk(mci, KERN_INFO, "ADDR %llx ", mce->addr); in pnd2_mce_check_error()
1422 pnd2_mc_printk(mci, KERN_INFO, "MISC %llx ", mce->misc); in pnd2_mce_check_error()
1424 mce->cpuvendor, mce->cpuid, mce->time, mce->socketid, mce->apicid); in pnd2_mce_check_error()
1429 mce->kflags |= MCE_HANDLED_EDAC; in pnd2_mce_check_error()
1555 return -EBUSY; in pnd2_init()
1558 return -ENODEV; in pnd2_init()
1562 return -ENODEV; in pnd2_init()
1564 ops = (struct dunit_ops *)id->driver_data; in pnd2_init()
1566 if (ops->type == APL) { in pnd2_init()
1569 return -ENODEV; in pnd2_init()
1582 return -ENODEV; in pnd2_init()