linux/drivers/ras/amd/atl/umc.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * AMD Address Translation Library
 *
 * umc.c : Unified Memory Controller (UMC) topology helpers
 *
 * Copyright (c) 2023, Advanced Micro Devices, Inc.
 * All Rights Reserved.
 *
 * Author: Yazen Ghannam <[email protected]>
 */

#include "internal.h"

/*
 * MI300 has a fixed, model-specific mapping between a UMC instance and
 * its related Data Fabric Coherent Station instance.
 *
 * The MCA_IPID_UMC[InstanceId] field holds a unique identifier for the
 * UMC instance within a Node. Use this to find the appropriate Coherent
 * Station ID.
 *
 * Redundant bits were removed from the map below.
 */
static const u16 umc_coh_st_map[32] =;

#define UMC_ID_MI300
static u8 get_coh_st_inst_id_mi300(struct atl_err *err)
{}

/* XOR the bits in @val. */
static u16 bitwise_xor_bits(u16 val)
{}

struct xor_bits {};

#define NUM_BANK_BITS
#define NUM_COL_BITS
#define NUM_SID_BITS

static struct {} addr_hash;

static struct {} bit_shifts;

#define MI300_UMC_CH_BASE
#define MI300_ADDR_CFG
#define MI300_ADDR_SEL
#define MI300_COL_SEL_LO
#define MI300_ADDR_SEL_2
#define MI300_ADDR_HASH_BANK0
#define MI300_ADDR_HASH_PC
#define MI300_ADDR_HASH_PC2

#define ADDR_HASH_XOR_EN
#define ADDR_HASH_COL_XOR
#define ADDR_HASH_ROW_XOR
#define ADDR_HASH_BANK_XOR

#define ADDR_CFG_NUM_ROW_LO
#define ADDR_CFG_NUM_ROW_HI

#define ADDR_SEL_BANK0
#define ADDR_SEL_BANK1
#define ADDR_SEL_BANK2
#define ADDR_SEL_BANK3
#define ADDR_SEL_BANK4
#define ADDR_SEL_ROW_LO
#define ADDR_SEL_ROW_HI

#define COL_SEL_LO_COL0
#define COL_SEL_LO_COL1
#define COL_SEL_LO_COL2
#define COL_SEL_LO_COL3
#define COL_SEL_LO_COL4

#define ADDR_SEL_2_BANK5
#define ADDR_SEL_2_CHAN

/*
 * Read UMC::CH::AddrHash{Bank,PC,PC2} registers to get XOR bits used
 * for hashing.
 *
 * Also, read UMC::CH::Addr{Cfg,Sel,Sel2} and UMC::CH:ColSelLo registers to
 * get the values needed to reconstruct the normalized address. Apply additional
 * offsets to the raw register values, as needed.
 *
 * Do this during module init, since the values will not change during run time.
 *
 * These registers are instantiated for each UMC across each AMD Node.
 * However, they should be identically programmed due to the fixed hardware
 * design of MI300 systems. So read the values from Node 0 UMC 0 and keep a
 * single global structure for simplicity.
 */
int get_umc_info_mi300(void)
{}

/*
 * MI300 systems report a DRAM address in MCA_ADDR for DRAM ECC errors. This must
 * be converted to the intermediate normalized address (NA) before translating to a
 * system physical address.
 *
 * The DRAM address includes bank, row, and column. Also included are bits for
 * pseudochannel (PC) and stack ID (SID).
 *
 * Abbreviations: (S)tack ID, (P)seudochannel, (R)ow, (B)ank, (C)olumn, (Z)ero
 *
 * The MCA address format is as follows:
 *	MCA_ADDR[27:0] = {S[1:0], P[0], R[14:0], B[3:0], C[4:0], Z[0]}
 *
 * Additionally, the PC and Bank bits may be hashed. This must be accounted for before
 * reconstructing the normalized address.
 */
#define MI300_UMC_MCA_COL
#define MI300_UMC_MCA_BANK
#define MI300_UMC_MCA_ROW
#define MI300_UMC_MCA_PC
#define MI300_UMC_MCA_SID

static unsigned long convert_dram_to_norm_addr_mi300(unsigned long addr)
{}

/*
 * When a DRAM ECC error occurs on MI300 systems, it is recommended to retire
 * all memory within that DRAM row. This applies to the memory with a DRAM
 * bank.
 *
 * To find the memory addresses, loop through permutations of the DRAM column
 * bits and find the System Physical address of each. The column bits are used
 * to calculate the intermediate Normalized address, so all permutations should
 * be checked.
 *
 * See amd_atl::convert_dram_to_norm_addr_mi300() for MI300 address formats.
 */
#define MI300_NUM_COL
static void retire_row_mi300(struct atl_err *a_err)
{}

void amd_retire_dram_row(struct atl_err *a_err)
{}
EXPORT_SYMBOL_GPL();

static unsigned long get_addr(unsigned long addr)
{}

#define MCA_IPID_INST_ID_HI
static u8 get_die_id(struct atl_err *err)
{}

#define UMC_CHANNEL_NUM
static u8 get_coh_st_inst_id(struct atl_err *err)
{}

unsigned long convert_umc_mca_addr_to_sys_addr(struct atl_err *err)
{}