/*
 * AMD 76x Memory Controller kernel module
 * (C) 2003 Linux Networx (http://lnxi.com)
 * This file may be distributed under the terms of the
 * GNU General Public License.
 *
 * Written by Thayne Harbaugh
 * Based on work by Dan Hollis <goemon at anime dot net> and others.
 *	http://www.anime.net/~goemon/linux-ecc/
 *
 * $Id: edac_amd76x.c,v 1.4.2.5 2005/10/05 00:43:44 dsp_llnl Exp $
 *
 */

#include <linux/module.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/pci_ids.h>
#include <linux/edac.h>
#include "edac_core.h"

#define AMD76X_REVISION	" Ver: 2.0.2 "  __DATE__
#define EDAC_MOD_STR	"amd76x_edac"

#define amd76x_printk(level, fmt, arg...) \
	edac_printk(level, "amd76x", fmt, ##arg)

#define amd76x_mc_printk(mci, level, fmt, arg...) \
	edac_mc_chipset_printk(mci, level, "amd76x", fmt, ##arg)

#define AMD76X_NR_CSROWS 8
#define AMD76X_NR_CHANS  1
#define AMD76X_NR_DIMMS  4

/* AMD 76x register addresses - device 0 function 0 - PCI bridge */

#define AMD76X_ECC_MODE_STATUS	0x48	/* Mode and status of ECC (32b)
					 *
					 * 31:16 reserved
					 * 15:14 SERR enabled: x1=ue 1x=ce
					 * 13    reserved
					 * 12    diag: disabled, enabled
					 * 11:10 mode: dis, EC, ECC, ECC+scrub
					 *  9:8  status: x1=ue 1x=ce
					 *  7:4  UE cs row
					 *  3:0  CE cs row
					 */

#define AMD76X_DRAM_MODE_STATUS	0x58	/* DRAM Mode and status (32b)
					 *
					 * 31:26 clock disable 5 - 0
					 * 25    SDRAM init
					 * 24    reserved
					 * 23    mode register service
					 * 22:21 suspend to RAM
					 * 20    burst refresh enable
					 * 19    refresh disable
					 * 18    reserved
					 * 17:16 cycles-per-refresh
					 * 15:8  reserved
					 *  7:0  x4 mode enable 7 - 0
					 */

#define AMD76X_MEM_BASE_ADDR	0xC0	/* Memory base address (8 x 32b)
					 *
					 * 31:23 chip-select base
					 * 22:16 reserved
					 * 15:7  chip-select mask
					 *  6:3  reserved
					 *  2:1  address mode
					 *  0    chip-select enable
					 */

struct amd76x_error_info {
	u32 ecc_mode_status;
};

enum amd76x_chips {
	AMD761 = 0,
	AMD762
};

struct amd76x_dev_info {
	const char *ctl_name;
};

static const struct amd76x_dev_info amd76x_devs[] = {
	[AMD761] = {
		.ctl_name = "AMD761"},
	[AMD762] = {
		.ctl_name = "AMD762"},
};

static struct edac_pci_ctl_info *amd76x_pci;

/**
 *	amd76x_get_error_info	-	fetch error information
 *	@mci: Memory controller
 *	@info: Info to fill in
 *
 *	Fetch and store the AMD76x ECC status. Clear pending status
 *	on the chip so that further errors will be reported
 */
static void amd76x_get_error_info(struct mem_ctl_info *mci,
				struct amd76x_error_info *info)
{
	struct pci_dev *pdev;

	pdev = to_pci_dev(mci->dev);
	pci_read_config_dword(pdev, AMD76X_ECC_MODE_STATUS,
			&info->ecc_mode_status);

	if (info->ecc_mode_status & BIT(8))
		pci_write_bits32(pdev, AMD76X_ECC_MODE_STATUS,
				 (u32) BIT(8), (u32) BIT(8));

	if (info->ecc_mode_status & BIT(9))
		pci_write_bits32(pdev, AMD76X_ECC_MODE_STATUS,
				 (u32) BIT(9), (u32) BIT(9));
}

/**
 *	amd76x_process_error_info	-	Error check
 *	@mci: Memory controller
 *	@info: Previously fetched information from chip
 *	@handle_errors: 1 if we should do recovery
 *
 *	Process the chip state and decide if an error has occurred.
 *	A return of 1 indicates an error. Also if handle_errors is true
 *	then attempt to handle and clean up after the error
 */
static int amd76x_process_error_info(struct mem_ctl_info *mci,
				struct amd76x_error_info *info,
				int handle_errors)
{
	int error_found;
	u32 row;

	error_found = 0;

	/*
	 *      Check for an uncorrectable error
	 */
	if (info->ecc_mode_status & BIT(8)) {
		error_found = 1;

		if (handle_errors) {
			row = (info->ecc_mode_status >> 4) & 0xf;
			edac_mc_handle_ue(mci, mci->csrows[row].first_page, 0,
					row, mci->ctl_name);
		}
	}

	/*
	 *      Check for a correctable error
	 */
	if (info->ecc_mode_status & BIT(9)) {
		error_found = 1;

		if (handle_errors) {
			row = info->ecc_mode_status & 0xf;
			edac_mc_handle_ce(mci, mci->csrows[row].first_page, 0,
					0, row, 0, mci->ctl_name);
		}
	}

	return error_found;
}

/**
 *	amd76x_check	-	Poll the controller
 *	@mci: Memory controller
 *
 *	Called by the poll handlers this function reads the status
 *	from the controller and checks for errors.
 */
static void amd76x_check(struct mem_ctl_info *mci)
{
	struct amd76x_error_info info;
	debugf3("%s()\n", __func__);
	amd76x_get_error_info(mci, &info);
	amd76x_process_error_info(mci, &info, 1);
}

static void amd76x_init_csrows(struct mem_ctl_info *mci, struct pci_dev *pdev,
			enum edac_type edac_mode)
{
	struct csrow_info *csrow;
	u32 mba, mba_base, mba_mask, dms;
	int index;

	for (index = 0; index < mci->nr_csrows; index++) {
		csrow = &mci->csrows[index];

		/* find the DRAM Chip Select Base address and mask */
		pci_read_config_dword(pdev,
				AMD76X_MEM_BASE_ADDR + (index * 4), &mba);

		if (!(mba & BIT(0)))
			continue;

		mba_base = mba & 0xff800000UL;
		mba_mask = ((mba & 0xff80) << 16) | 0x7fffffUL;
		pci_read_config_dword(pdev, AMD76X_DRAM_MODE_STATUS, &dms);
		csrow->first_page = mba_base >> PAGE_SHIFT;
		csrow->nr_pages = (mba_mask + 1) >> PAGE_SHIFT;
		csrow->last_page = csrow->first_page + csrow->nr_pages - 1;
		csrow->page_mask = mba_mask >> PAGE_SHIFT;
		csrow->grain = csrow->nr_pages << PAGE_SHIFT;
		csrow->mtype = MEM_RDDR;
		csrow->dtype = ((dms >> index) & 0x1) ? DEV_X4 : DEV_UNKNOWN;
		csrow->edac_mode = edac_mode;
	}
}

/**
 *	amd76x_probe1	-	Perform set up for detected device
 *	@pdev; PCI device detected
 *	@dev_idx: Device type index
 *
 *	We have found an AMD76x and now need to set up the memory
 *	controller status reporting. We configure and set up the
 *	memory controller reporting and claim the device.
 */
static int amd76x_probe1(struct pci_dev *pdev, int dev_idx)
{
	static const enum edac_type ems_modes[] = {
		EDAC_NONE,
		EDAC_EC,
		EDAC_SECDED,
		EDAC_SECDED
	};
	struct mem_ctl_info *mci = NULL;
	u32 ems;
	u32 ems_mode;
	struct amd76x_error_info discard;

	debugf0("%s()\n", __func__);
	pci_read_config_dword(pdev, AMD76X_ECC_MODE_STATUS, &ems);
	ems_mode = (ems >> 10) & 0x3;
	mci = edac_mc_alloc(0, AMD76X_NR_CSROWS, AMD76X_NR_CHANS, 0);

	if (mci == NULL) {
		return -ENOMEM;
	}

	debugf0("%s(): mci = %p\n", __func__, mci);
	mci->dev = &pdev->dev;
	mci->mtype_cap = MEM_FLAG_RDDR;
	mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_EC | EDAC_FLAG_SECDED;
	mci->edac_cap = ems_mode ?
		(EDAC_FLAG_EC | EDAC_FLAG_SECDED) : EDAC_FLAG_NONE;
	mci->mod_name = EDAC_MOD_STR;
	mci->mod_ver = AMD76X_REVISION;
	mci->ctl_name = amd76x_devs[dev_idx].ctl_name;
	mci->dev_name = pci_name(pdev);
	mci->edac_check = amd76x_check;
	mci->ctl_page_to_phys = NULL;

	amd76x_init_csrows(mci, pdev, ems_modes[ems_mode]);
	amd76x_get_error_info(mci, &discard);	/* clear counters */

	/* Here we assume that we will never see multiple instances of this
	 * type of memory controller.  The ID is therefore hardcoded to 0.
	 */
	if (edac_mc_add_mc(mci)) {
		debugf3("%s(): failed edac_mc_add_mc()\n", __func__);
		goto fail;
	}

	/* allocating generic PCI control info */
	amd76x_pci = edac_pci_create_generic_ctl(&pdev->dev, EDAC_MOD_STR);
	if (!amd76x_pci) {
		printk(KERN_WARNING
			"%s(): Unable to create PCI control\n",
			__func__);
		printk(KERN_WARNING
			"%s(): PCI error report via EDAC not setup\n",
			__func__);
	}

	/* get this far and it's successful */
	debugf3("%s(): success\n", __func__);
	return 0;

fail:
	edac_mc_free(mci);
	return -ENODEV;
}

/* returns count (>= 0), or negative on error */
static int __devinit amd76x_init_one(struct pci_dev *pdev,
				const struct pci_device_id *ent)
{
	debugf0("%s()\n", __func__);

	/* don't need to call pci_enable_device() */
	return amd76x_probe1(pdev, ent->driver_data);
}

/**
 *	amd76x_remove_one	-	driver shutdown
 *	@pdev: PCI device being handed back
 *
 *	Called when the driver is unloaded. Find the matching mci
 *	structure for the device then delete the mci and free the
 *	resources.
 */
static void __devexit amd76x_remove_one(struct pci_dev *pdev)
{
	struct mem_ctl_info *mci;

	debugf0("%s()\n", __func__);

	if (amd76x_pci)
		edac_pci_release_generic_ctl(amd76x_pci);

	if ((mci = edac_mc_del_mc(&pdev->dev)) == NULL)
		return;

	edac_mc_free(mci);
}

static const struct pci_device_id amd76x_pci_tbl[] __devinitdata = {
	{
	 PCI_VEND_DEV(AMD, FE_GATE_700C), PCI_ANY_ID, PCI_ANY_ID, 0, 0,
	 AMD762},
	{
	 PCI_VEND_DEV(AMD, FE_GATE_700E), PCI_ANY_ID, PCI_ANY_ID, 0, 0,
	 AMD761},
	{
	 0,
	 }			/* 0 terminated list. */
};

MODULE_DEVICE_TABLE(pci, amd76x_pci_tbl);

static struct pci_driver amd76x_driver = {
	.name = EDAC_MOD_STR,
	.probe = amd76x_init_one,
	.remove = __devexit_p(amd76x_remove_one),
	.id_table = amd76x_pci_tbl,
};

static int __init amd76x_init(void)
{
       /* Ensure that the OPSTATE is set correctly for POLL or NMI */
       opstate_init();

	return pci_register_driver(&amd76x_driver);
}

static void __exit amd76x_exit(void)
{
	pci_unregister_driver(&amd76x_driver);
}

module_init(amd76x_init);
module_exit(amd76x_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Linux Networx (http://lnxi.com) Thayne Harbaugh");
MODULE_DESCRIPTION("MC support for AMD 76x memory controllers");

module_param(edac_op_state, int, 0444);
MODULE_PARM_DESC(edac_op_state, "EDAC Error Reporting state: 0=Poll,1=NMI");
