Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 442d1ba2 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'edac-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/bp/bp

* 'edac-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/bp/bp:
  amd64_edac: Disable DRAM ECC injection on K8
  EDAC: Fixup scrubrate manipulation
  amd64_edac: Remove two-stage initialization
  amd64_edac: Check ECC capabilities initially
  amd64_edac: Carve out ECC-related hw settings
  amd64_edac: Remove PCI ECS enabling functions
  amd64_edac: Remove explicit Kconfig PCI dependency
  amd64_edac: Allocate driver instances dynamically
  amd64_edac: Rework printk macros
  amd64_edac: Rename CPU PCI devices
  amd64_edac: Concentrate per-family init even more
  amd64_edac: Cleanup the CPU PCI device reservation
  amd64_edac: Simplify CPU family detection
  amd64_edac: Add per-family init function
  amd64_edac: Use cached extended CPU model
  amd64_edac: Remove F11h support
parents fb5131e1 a135cef7
Loading
Loading
Loading
Loading
+4 −4
Original line number Original line Diff line number Diff line
@@ -75,11 +75,11 @@ config EDAC_MCE
	bool
	bool


config EDAC_AMD64
config EDAC_AMD64
	tristate "AMD64 (Opteron, Athlon64) K8, F10h, F11h"
	tristate "AMD64 (Opteron, Athlon64) K8, F10h"
	depends on EDAC_MM_EDAC && AMD_NB && X86_64 && PCI && EDAC_DECODE_MCE
	depends on EDAC_MM_EDAC && AMD_NB && X86_64 && EDAC_DECODE_MCE
	help
	help
	  Support for error detection and correction on the AMD 64
	  Support for error detection and correction of DRAM ECC errors on
	  Families of Memory Controllers (K8, F10h and F11h)
	  the AMD64 families of memory controllers (K8 and F10h)


config EDAC_AMD64_ERROR_INJECTION
config EDAC_AMD64_ERROR_INJECTION
	bool "Sysfs HW Error injection facilities"
	bool "Sysfs HW Error injection facilities"
+341 −482

File changed.

Preview size limit exceeded, changes collapsed.

+39 −47
Original line number Original line Diff line number Diff line
@@ -74,11 +74,26 @@
#include "edac_core.h"
#include "edac_core.h"
#include "mce_amd.h"
#include "mce_amd.h"


#define amd64_printk(level, fmt, arg...) \
#define amd64_debug(fmt, arg...) \
	edac_printk(level, "amd64", fmt, ##arg)
	edac_printk(KERN_DEBUG, "amd64", fmt, ##arg)


#define amd64_mc_printk(mci, level, fmt, arg...) \
#define amd64_info(fmt, arg...) \
	edac_mc_chipset_printk(mci, level, "amd64", fmt, ##arg)
	edac_printk(KERN_INFO, "amd64", fmt, ##arg)

#define amd64_notice(fmt, arg...) \
	edac_printk(KERN_NOTICE, "amd64", fmt, ##arg)

#define amd64_warn(fmt, arg...) \
	edac_printk(KERN_WARNING, "amd64", fmt, ##arg)

#define amd64_err(fmt, arg...) \
	edac_printk(KERN_ERR, "amd64", fmt, ##arg)

#define amd64_mc_warn(mci, fmt, arg...) \
	edac_mc_chipset_printk(mci, KERN_WARNING, "amd64", fmt, ##arg)

#define amd64_mc_err(mci, fmt, arg...) \
	edac_mc_chipset_printk(mci, KERN_ERR, "amd64", fmt, ##arg)


/*
/*
 * Throughout the comments in this code, the following terms are used:
 * Throughout the comments in this code, the following terms are used:
@@ -129,11 +144,9 @@
 *         sections 3.5.4 and 3.5.5 for more information.
 *         sections 3.5.4 and 3.5.5 for more information.
 */
 */


#define EDAC_AMD64_VERSION		" Ver: 3.3.0 " __DATE__
#define EDAC_AMD64_VERSION		"v3.3.0"
#define EDAC_MOD_STR			"amd64_edac"
#define EDAC_MOD_STR			"amd64_edac"


#define EDAC_MAX_NUMNODES		8

/* Extended Model from CPUID, for CPU Revision numbers */
/* Extended Model from CPUID, for CPU Revision numbers */
#define K8_REV_D			1
#define K8_REV_D			1
#define K8_REV_E			2
#define K8_REV_E			2
@@ -322,9 +335,6 @@
#define K8_SCRCTRL			0x58
#define K8_SCRCTRL			0x58


#define F10_NB_CFG_LOW			0x88
#define F10_NB_CFG_LOW			0x88
#define	F10_NB_CFG_LOW_ENABLE_EXT_CFG	BIT(14)

#define F10_NB_CFG_HIGH			0x8C


#define F10_ONLINE_SPARE		0xB0
#define F10_ONLINE_SPARE		0xB0
#define F10_ONLINE_SPARE_SWAPDONE0(x)	((x) & BIT(1))
#define F10_ONLINE_SPARE_SWAPDONE0(x)	((x) & BIT(1))
@@ -373,7 +383,6 @@ static inline int get_node_id(struct pci_dev *pdev)
enum amd64_chipset_families {
enum amd64_chipset_families {
	K8_CPUS = 0,
	K8_CPUS = 0,
	F10_CPUS,
	F10_CPUS,
	F11_CPUS,
};
};


/* Error injection control structure */
/* Error injection control structure */
@@ -384,16 +393,13 @@ struct error_injection {
};
};


struct amd64_pvt {
struct amd64_pvt {
	struct low_ops *ops;

	/* pci_device handles which we utilize */
	/* pci_device handles which we utilize */
	struct pci_dev *addr_f1_ctl;
	struct pci_dev *F1, *F2, *F3;
	struct pci_dev *dram_f2_ctl;
	struct pci_dev *misc_f3_ctl;


	int mc_node_id;		/* MC index of this MC node */
	int mc_node_id;		/* MC index of this MC node */
	int ext_model;		/* extended model value of this node */
	int ext_model;		/* extended model value of this node */

	struct low_ops *ops;	/* pointer to per PCI Device ID func table */

	int channel_count;
	int channel_count;


	/* Raw registers */
	/* Raw registers */
@@ -455,27 +461,27 @@ struct amd64_pvt {
	/* place to store error injection parameters prior to issue */
	/* place to store error injection parameters prior to issue */
	struct error_injection injection;
	struct error_injection injection;


	/* Save old hw registers' values before we modified them */
	/* DCT per-family scrubrate setting */
	u32 nbctl_mcgctl_saved;		/* When true, following 2 are valid */
	u32 min_scrubrate;
	u32 old_nbctl;


	/* MC Type Index value: socket F vs Family 10h */
	/* family name this instance is running on */
	u32 mc_type_index;
	const char *ctl_name;

};

/*
 * per-node ECC settings descriptor
 */
struct ecc_settings {
	u32 old_nbctl;
	bool nbctl_valid;


	/* misc settings */
	struct flags {
	struct flags {
		unsigned long cf8_extcfg:1;
		unsigned long nb_mce_enable:1;
		unsigned long nb_mce_enable:1;
		unsigned long nb_ecc_prev:1;
		unsigned long nb_ecc_prev:1;
	} flags;
	} flags;
};
};


struct scrubrate {
       u32 scrubval;           /* bit pattern for scrub rate */
       u32 bandwidth;          /* bandwidth consumed (bytes/sec) */
};

extern struct scrubrate scrubrates[23];
extern const char *tt_msgs[4];
extern const char *tt_msgs[4];
extern const char *ll_msgs[4];
extern const char *ll_msgs[4];
extern const char *rrrr_msgs[16];
extern const char *rrrr_msgs[16];
@@ -517,23 +523,10 @@ struct low_ops {


struct amd64_family_type {
struct amd64_family_type {
	const char *ctl_name;
	const char *ctl_name;
	u16 addr_f1_ctl;
	u16 f1_id, f3_id;
	u16 misc_f3_ctl;
	struct low_ops ops;
	struct low_ops ops;
};
};


static struct amd64_family_type amd64_family_types[];

static inline const char *get_amd_family_name(int index)
{
	return amd64_family_types[index].ctl_name;
}

static inline struct low_ops *family_ops(int index)
{
	return &amd64_family_types[index].ops;
}

static inline int amd64_read_pci_cfg_dword(struct pci_dev *pdev, int offset,
static inline int amd64_read_pci_cfg_dword(struct pci_dev *pdev, int offset,
					   u32 *val, const char *func)
					   u32 *val, const char *func)
{
{
@@ -541,7 +534,7 @@ static inline int amd64_read_pci_cfg_dword(struct pci_dev *pdev, int offset,


	err = pci_read_config_dword(pdev, offset, val);
	err = pci_read_config_dword(pdev, offset, val);
	if (err)
	if (err)
		amd64_printk(KERN_WARNING, "%s: error reading F%dx%x.\n",
		amd64_warn("%s: error reading F%dx%x.\n",
			   func, PCI_FUNC(pdev->devfn), offset);
			   func, PCI_FUNC(pdev->devfn), offset);


	return err;
	return err;
@@ -556,7 +549,6 @@ static inline int amd64_read_pci_cfg_dword(struct pci_dev *pdev, int offset,
 */
 */
#define K8_MIN_SCRUB_RATE_BITS	0x0
#define K8_MIN_SCRUB_RATE_BITS	0x0
#define F10_MIN_SCRUB_RATE_BITS	0x5
#define F10_MIN_SCRUB_RATE_BITS	0x5
#define F11_MIN_SCRUB_RATE_BITS	0x6


int amd64_get_dram_hole_info(struct mem_ctl_info *mci, u64 *hole_base,
int amd64_get_dram_hole_info(struct mem_ctl_info *mci, u64 *hole_base,
			     u64 *hole_offset, u64 *hole_size);
			     u64 *hole_offset, u64 *hole_size);
+8 −17
Original line number Original line Diff line number Diff line
@@ -23,9 +23,7 @@ static ssize_t amd64_inject_section_store(struct mem_ctl_info *mci,
	if (ret != -EINVAL) {
	if (ret != -EINVAL) {


		if (value > 3) {
		if (value > 3) {
			amd64_printk(KERN_WARNING,
			amd64_warn("%s: invalid section 0x%lx\n", __func__, value);
				     "%s: invalid section 0x%lx\n",
				     __func__, value);
			return -EINVAL;
			return -EINVAL;
		}
		}


@@ -58,9 +56,7 @@ static ssize_t amd64_inject_word_store(struct mem_ctl_info *mci,
	if (ret != -EINVAL) {
	if (ret != -EINVAL) {


		if (value > 8) {
		if (value > 8) {
			amd64_printk(KERN_WARNING,
			amd64_warn("%s: invalid word 0x%lx\n", __func__, value);
				     "%s: invalid word 0x%lx\n",
				     __func__, value);
			return -EINVAL;
			return -EINVAL;
		}
		}


@@ -92,8 +88,7 @@ static ssize_t amd64_inject_ecc_vector_store(struct mem_ctl_info *mci,
	if (ret != -EINVAL) {
	if (ret != -EINVAL) {


		if (value & 0xFFFF0000) {
		if (value & 0xFFFF0000) {
			amd64_printk(KERN_WARNING,
			amd64_warn("%s: invalid EccVector: 0x%lx\n",
				     "%s: invalid EccVector: 0x%lx\n",
				   __func__, value);
				   __func__, value);
			return -EINVAL;
			return -EINVAL;
		}
		}
@@ -122,15 +117,13 @@ static ssize_t amd64_inject_read_store(struct mem_ctl_info *mci,
		/* Form value to choose 16-byte section of cacheline */
		/* Form value to choose 16-byte section of cacheline */
		section = F10_NB_ARRAY_DRAM_ECC |
		section = F10_NB_ARRAY_DRAM_ECC |
				SET_NB_ARRAY_ADDRESS(pvt->injection.section);
				SET_NB_ARRAY_ADDRESS(pvt->injection.section);
		pci_write_config_dword(pvt->misc_f3_ctl,
		pci_write_config_dword(pvt->F3, F10_NB_ARRAY_ADDR, section);
					F10_NB_ARRAY_ADDR, section);


		word_bits = SET_NB_DRAM_INJECTION_READ(pvt->injection.word,
		word_bits = SET_NB_DRAM_INJECTION_READ(pvt->injection.word,
						pvt->injection.bit_map);
						pvt->injection.bit_map);


		/* Issue 'word' and 'bit' along with the READ request */
		/* Issue 'word' and 'bit' along with the READ request */
		pci_write_config_dword(pvt->misc_f3_ctl,
		pci_write_config_dword(pvt->F3, F10_NB_ARRAY_DATA, word_bits);
					F10_NB_ARRAY_DATA, word_bits);


		debugf0("section=0x%x word_bits=0x%x\n", section, word_bits);
		debugf0("section=0x%x word_bits=0x%x\n", section, word_bits);


@@ -157,15 +150,13 @@ static ssize_t amd64_inject_write_store(struct mem_ctl_info *mci,
		/* Form value to choose 16-byte section of cacheline */
		/* Form value to choose 16-byte section of cacheline */
		section = F10_NB_ARRAY_DRAM_ECC |
		section = F10_NB_ARRAY_DRAM_ECC |
				SET_NB_ARRAY_ADDRESS(pvt->injection.section);
				SET_NB_ARRAY_ADDRESS(pvt->injection.section);
		pci_write_config_dword(pvt->misc_f3_ctl,
		pci_write_config_dword(pvt->F3, F10_NB_ARRAY_ADDR, section);
					F10_NB_ARRAY_ADDR, section);


		word_bits = SET_NB_DRAM_INJECTION_WRITE(pvt->injection.word,
		word_bits = SET_NB_DRAM_INJECTION_WRITE(pvt->injection.word,
						pvt->injection.bit_map);
						pvt->injection.bit_map);


		/* Issue 'word' and 'bit' along with the READ request */
		/* Issue 'word' and 'bit' along with the READ request */
		pci_write_config_dword(pvt->misc_f3_ctl,
		pci_write_config_dword(pvt->F3, F10_NB_ARRAY_DATA, word_bits);
					F10_NB_ARRAY_DATA, word_bits);


		debugf0("section=0x%x word_bits=0x%x\n", section, word_bits);
		debugf0("section=0x%x word_bits=0x%x\n", section, word_bits);


+5 −4
Original line number Original line Diff line number Diff line
@@ -818,9 +818,10 @@ static void cpc925_del_edac_devices(void)
}
}


/* Convert current back-ground scrub rate into byte/sec bandwith */
/* Convert current back-ground scrub rate into byte/sec bandwith */
static int cpc925_get_sdram_scrub_rate(struct mem_ctl_info *mci, u32 *bw)
static int cpc925_get_sdram_scrub_rate(struct mem_ctl_info *mci)
{
{
	struct cpc925_mc_pdata *pdata = mci->pvt_info;
	struct cpc925_mc_pdata *pdata = mci->pvt_info;
	int bw;
	u32 mscr;
	u32 mscr;
	u8 si;
	u8 si;


@@ -832,11 +833,11 @@ static int cpc925_get_sdram_scrub_rate(struct mem_ctl_info *mci, u32 *bw)
	if (((mscr & MSCR_SCRUB_MOD_MASK) != MSCR_BACKGR_SCRUB) ||
	if (((mscr & MSCR_SCRUB_MOD_MASK) != MSCR_BACKGR_SCRUB) ||
	    (si == 0)) {
	    (si == 0)) {
		cpc925_mc_printk(mci, KERN_INFO, "Scrub mode not enabled\n");
		cpc925_mc_printk(mci, KERN_INFO, "Scrub mode not enabled\n");
		*bw = 0;
		bw = 0;
	} else
	} else
		*bw = CPC925_SCRUB_BLOCK_SIZE * 0xFA67 / si;
		bw = CPC925_SCRUB_BLOCK_SIZE * 0xFA67 / si;


	return 0;
	return bw;
}
}


/* Return 0 for single channel; 1 for dual channel */
/* Return 0 for single channel; 1 for dual channel */
Loading