/*
 * Intel X38 Memory Controller kernel module
 * Copyright (C) 2008 Cluster Computing, Inc.
 *
 * This file may be distributed under the terms of the
 * GNU General Public License.
 *
 * This file is based on i3200_edac.c
 *
 */

#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 X38_REVISION		"1.1"

#define EDAC_MOD_STR		"x38_edac"

#define PCI_DEVICE_ID_INTEL_X38_HB	0x29e0

#define X38_RANKS		8
#define X38_RANKS_PER_CHANNEL	4
#define X38_CHANNELS		2

/* Intel X38 register addresses - device 0 function 0 - DRAM Controller */

#define X38_MCHBAR_LOW	0x48	/* MCH Memory Mapped Register BAR */
#define X38_MCHBAR_HIGH	0x4c
#define X38_MCHBAR_MASK	0xfffffc000ULL	/* bits 35:14 */
#define X38_MMR_WINDOW_SIZE	16384

#define X38_TOM	0xa0	/* Top of Memory (16b)
				 *
				 * 15:10 reserved
				 *  9:0  total populated physical memory
				 */
#define X38_TOM_MASK	0x3ff	/* bits 9:0 */
#define X38_TOM_SHIFT 26	/* 64MiB grain */

#define X38_ERRSTS	0xc8	/* Error Status Register (16b)
				 *
				 * 15    reserved
				 * 14    Isochronous TBWRR Run Behind FIFO Full
				 *       (ITCV)
				 * 13    Isochronous TBWRR Run Behind FIFO Put
				 *       (ITSTV)
				 * 12    reserved
				 * 11    MCH Thermal Sensor Event
				 *       for SMI/SCI/SERR (GTSE)
				 * 10    reserved
				 *  9    LOCK to non-DRAM Memory Flag (LCKF)
				 *  8    reserved
				 *  7    DRAM Throttle Flag (DTF)
				 *  6:2  reserved
				 *  1    Multi-bit DRAM ECC Error Flag (DMERR)
				 *  0    Single-bit DRAM ECC Error Flag (DSERR)
				 */
#define X38_ERRSTS_UE		0x0002
#define X38_ERRSTS_CE		0x0001
#define X38_ERRSTS_BITS	(X38_ERRSTS_UE | X38_ERRSTS_CE)


/* Intel  MMIO register space - device 0 function 0 - MMR space */

#define X38_C0DRB	0x200	/* Channel 0 DRAM Rank Boundary (16b x 4)
				 *
				 * 15:10 reserved
				 *  9:0  Channel 0 DRAM Rank Boundary Address
				 */
#define X38_C1DRB	0x600	/* Channel 1 DRAM Rank Boundary (16b x 4) */
#define X38_DRB_MASK	0x3ff	/* bits 9:0 */
#define X38_DRB_SHIFT 26	/* 64MiB grain */

#define X38_C0ECCERRLOG 0x280	/* Channel 0 ECC Error Log (64b)
				 *
				 * 63:48 Error Column Address (ERRCOL)
				 * 47:32 Error Row Address (ERRROW)
				 * 31:29 Error Bank Address (ERRBANK)
				 * 28:27 Error Rank Address (ERRRANK)
				 * 26:24 reserved
				 * 23:16 Error Syndrome (ERRSYND)
				 * 15: 2 reserved
				 *    1  Multiple Bit Error Status (MERRSTS)
				 *    0  Correctable Error Status (CERRSTS)
				 */
#define X38_C1ECCERRLOG 0x680	/* Channel 1 ECC Error Log (64b) */
#define X38_ECCERRLOG_CE	0x1
#define X38_ECCERRLOG_UE	0x2
#define X38_ECCERRLOG_RANK_BITS	0x18000000
#define X38_ECCERRLOG_SYNDROME_BITS	0xff0000

#define X38_CAPID0 0xe0	/* see P.94 of spec for details */

static int x38_channel_num;

static int how_many_channel(struct pci_dev *pdev)
{
	unsigned char capid0_8b; /* 8th byte of CAPID0 */

	pci_read_config_byte(pdev, X38_CAPID0 + 8, &capid0_8b);
	if (capid0_8b & 0x20) {	/* check DCD: Dual Channel Disable */
		debugf0("In single channel mode.\n");
		x38_channel_num = 1;
	} else {
		debugf0("In dual channel mode.\n");
		x38_channel_num = 2;
	}

	return x38_channel_num;
}

static unsigned long eccerrlog_syndrome(u64 log)
{
	return (log & X38_ECCERRLOG_SYNDROME_BITS) >> 16;
}

static int eccerrlog_row(int channel, u64 log)
{
	return ((log & X38_ECCERRLOG_RANK_BITS) >> 27) |
		(channel * X38_RANKS_PER_CHANNEL);
}

enum x38_chips {
	X38 = 0,
};

struct x38_dev_info {
	const char *ctl_name;
};

struct x38_error_info {
	u16 errsts;
	u16 errsts2;
	u64 eccerrlog[X38_CHANNELS];
};

static const struct x38_dev_info x38_devs[] = {
	[X38] = {
		.ctl_name = "x38"},
};

static struct pci_dev *mci_pdev;
static int x38_registered = 1;


static void x38_clear_error_info(struct mem_ctl_info *mci)
{
	struct pci_dev *pdev;

	pdev = to_pci_dev(mci->dev);

	/*
	 * Clear any error bits.
	 * (Yes, we really clear bits by writing 1 to them.)
	 */
	pci_write_bits16(pdev, X38_ERRSTS, X38_ERRSTS_BITS,
			 X38_ERRSTS_BITS);
}

static u64 x38_readq(const void __iomem *addr)
{
	return readl(addr) | (((u64)readl(addr + 4)) << 32);
}

static void x38_get_and_clear_error_info(struct mem_ctl_info *mci,
				 struct x38_error_info *info)
{
	struct pci_dev *pdev;
	void __iomem *window = mci->pvt_info;

	pdev = to_pci_dev(mci->dev);

	/*
	 * This is a mess because there is no atomic way to read all the
	 * registers at once and the registers can transition from CE being
	 * overwritten by UE.
	 */
	pci_read_config_word(pdev, X38_ERRSTS, &info->errsts);
	if (!(info->errsts & X38_ERRSTS_BITS))
		return;

	info->eccerrlog[0] = x38_readq(window + X38_C0ECCERRLOG);
	if (x38_channel_num == 2)
		info->eccerrlog[1] = x38_readq(window + X38_C1ECCERRLOG);

	pci_read_config_word(pdev, X38_ERRSTS, &info->errsts2);

	/*
	 * If the error is the same for both reads then the first set
	 * of reads is valid.  If there is a change then there is a CE
	 * with no info and the second set of reads is valid and
	 * should be UE info.
	 */
	if ((info->errsts ^ info->errsts2) & X38_ERRSTS_BITS) {
		info->eccerrlog[0] = x38_readq(window + X38_C0ECCERRLOG);
		if (x38_channel_num == 2)
			info->eccerrlog[1] =
				x38_readq(window + X38_C1ECCERRLOG);
	}

	x38_clear_error_info(mci);
}

static void x38_process_error_info(struct mem_ctl_info *mci,
				struct x38_error_info *info)
{
	int channel;
	u64 log;

	if (!(info->errsts & X38_ERRSTS_BITS))
		return;

	if ((info->errsts ^ info->errsts2) & X38_ERRSTS_BITS) {
		edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci, 0, 0, 0,
				     -1, -1, -1,
				     "UE overwrote CE", "", NULL);
		info->errsts = info->errsts2;
	}

	for (channel = 0; channel < x38_channel_num; channel++) {
		log = info->eccerrlog[channel];
		if (log & X38_ECCERRLOG_UE) {
			edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci,
					     0, 0, 0,
					     eccerrlog_row(channel, log),
					     -1, -1,
					     "x38 UE", "", NULL);
		} else if (log & X38_ECCERRLOG_CE) {
			edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci,
					     0, 0, eccerrlog_syndrome(log),
					     eccerrlog_row(channel, log),
					     -1, -1,
					     "x38 CE", "", NULL);
		}
	}
}

static void x38_check(struct mem_ctl_info *mci)
{
	struct x38_error_info info;

	debugf1("MC%d: %s()\n", mci->mc_idx, __func__);
	x38_get_and_clear_error_info(mci, &info);
	x38_process_error_info(mci, &info);
}


void __iomem *x38_map_mchbar(struct pci_dev *pdev)
{
	union {
		u64 mchbar;
		struct {
			u32 mchbar_low;
			u32 mchbar_high;
		};
	} u;
	void __iomem *window;

	pci_read_config_dword(pdev, X38_MCHBAR_LOW, &u.mchbar_low);
	pci_write_config_dword(pdev, X38_MCHBAR_LOW, u.mchbar_low | 0x1);
	pci_read_config_dword(pdev, X38_MCHBAR_HIGH, &u.mchbar_high);
	u.mchbar &= X38_MCHBAR_MASK;

	if (u.mchbar != (resource_size_t)u.mchbar) {
		printk(KERN_ERR
			"x38: mmio space beyond accessible range (0x%llx)\n",
			(unsigned long long)u.mchbar);
		return NULL;
	}

	window = ioremap_nocache(u.mchbar, X38_MMR_WINDOW_SIZE);
	if (!window)
		printk(KERN_ERR "x38: cannot map mmio space at 0x%llx\n",
			(unsigned long long)u.mchbar);

	return window;
}


static void x38_get_drbs(void __iomem *window,
			u16 drbs[X38_CHANNELS][X38_RANKS_PER_CHANNEL])
{
	int i;

	for (i = 0; i < X38_RANKS_PER_CHANNEL; i++) {
		drbs[0][i] = readw(window + X38_C0DRB + 2*i) & X38_DRB_MASK;
		drbs[1][i] = readw(window + X38_C1DRB + 2*i) & X38_DRB_MASK;
	}
}

static bool x38_is_stacked(struct pci_dev *pdev,
			u16 drbs[X38_CHANNELS][X38_RANKS_PER_CHANNEL])
{
	u16 tom;

	pci_read_config_word(pdev, X38_TOM, &tom);
	tom &= X38_TOM_MASK;

	return drbs[X38_CHANNELS - 1][X38_RANKS_PER_CHANNEL - 1] == tom;
}

static unsigned long drb_to_nr_pages(
			u16 drbs[X38_CHANNELS][X38_RANKS_PER_CHANNEL],
			bool stacked, int channel, int rank)
{
	int n;

	n = drbs[channel][rank];
	if (rank > 0)
		n -= drbs[channel][rank - 1];
	if (stacked && (channel == 1) && drbs[channel][rank] ==
				drbs[channel][X38_RANKS_PER_CHANNEL - 1]) {
		n -= drbs[0][X38_RANKS_PER_CHANNEL - 1];
	}

	n <<= (X38_DRB_SHIFT - PAGE_SHIFT);
	return n;
}

static int x38_probe1(struct pci_dev *pdev, int dev_idx)
{
	int rc;
	int i, j;
	struct mem_ctl_info *mci = NULL;
	struct edac_mc_layer layers[2];
	u16 drbs[X38_CHANNELS][X38_RANKS_PER_CHANNEL];
	bool stacked;
	void __iomem *window;

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

	window = x38_map_mchbar(pdev);
	if (!window)
		return -ENODEV;

	x38_get_drbs(window, drbs);

	how_many_channel(pdev);

	/* FIXME: unconventional pvt_info usage */
	layers[0].type = EDAC_MC_LAYER_CHIP_SELECT;
	layers[0].size = X38_RANKS;
	layers[0].is_virt_csrow = true;
	layers[1].type = EDAC_MC_LAYER_CHANNEL;
	layers[1].size = x38_channel_num;
	layers[1].is_virt_csrow = false;
	mci = edac_mc_alloc(0, ARRAY_SIZE(layers), layers, 0);
	if (!mci)
		return -ENOMEM;

	debugf3("MC: %s(): init mci\n", __func__);

	mci->dev = &pdev->dev;
	mci->mtype_cap = MEM_FLAG_DDR2;

	mci->edac_ctl_cap = EDAC_FLAG_SECDED;
	mci->edac_cap = EDAC_FLAG_SECDED;

	mci->mod_name = EDAC_MOD_STR;
	mci->mod_ver = X38_REVISION;
	mci->ctl_name = x38_devs[dev_idx].ctl_name;
	mci->dev_name = pci_name(pdev);
	mci->edac_check = x38_check;
	mci->ctl_page_to_phys = NULL;
	mci->pvt_info = window;

	stacked = x38_is_stacked(pdev, drbs);

	/*
	 * The dram rank boundary (DRB) reg values are boundary addresses
	 * for each DRAM rank with a granularity of 64MB.  DRB regs are
	 * cumulative; the last one will contain the total memory
	 * contained in all ranks.
	 */
	for (i = 0; i < mci->nr_csrows; i++) {
		unsigned long nr_pages;
		struct csrow_info *csrow = &mci->csrows[i];

		nr_pages = drb_to_nr_pages(drbs, stacked,
			i / X38_RANKS_PER_CHANNEL,
			i % X38_RANKS_PER_CHANNEL);

		if (nr_pages == 0)
			continue;

		for (j = 0; j < x38_channel_num; j++) {
			struct dimm_info *dimm = csrow->channels[j].dimm;

			dimm->nr_pages = nr_pages / x38_channel_num;
			dimm->grain = nr_pages << PAGE_SHIFT;
			dimm->mtype = MEM_DDR2;
			dimm->dtype = DEV_UNKNOWN;
			dimm->edac_mode = EDAC_UNKNOWN;
		}
	}

	x38_clear_error_info(mci);

	rc = -ENODEV;
	if (edac_mc_add_mc(mci)) {
		debugf3("MC: %s(): failed edac_mc_add_mc()\n", __func__);
		goto fail;
	}

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

fail:
	iounmap(window);
	if (mci)
		edac_mc_free(mci);

	return rc;
}

static int __devinit x38_init_one(struct pci_dev *pdev,
				const struct pci_device_id *ent)
{
	int rc;

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

	if (pci_enable_device(pdev) < 0)
		return -EIO;

	rc = x38_probe1(pdev, ent->driver_data);
	if (!mci_pdev)
		mci_pdev = pci_dev_get(pdev);

	return rc;
}

static void __devexit x38_remove_one(struct pci_dev *pdev)
{
	struct mem_ctl_info *mci;

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

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

	iounmap(mci->pvt_info);

	edac_mc_free(mci);
}

static DEFINE_PCI_DEVICE_TABLE(x38_pci_tbl) = {
	{
	 PCI_VEND_DEV(INTEL, X38_HB), PCI_ANY_ID, PCI_ANY_ID, 0, 0,
	 X38},
	{
	 0,
	 }			/* 0 terminated list. */
};

MODULE_DEVICE_TABLE(pci, x38_pci_tbl);

static struct pci_driver x38_driver = {
	.name = EDAC_MOD_STR,
	.probe = x38_init_one,
	.remove = __devexit_p(x38_remove_one),
	.id_table = x38_pci_tbl,
};

static int __init x38_init(void)
{
	int pci_rc;

	debugf3("MC: %s()\n", __func__);

	/* Ensure that the OPSTATE is set correctly for POLL or NMI */
	opstate_init();

	pci_rc = pci_register_driver(&x38_driver);
	if (pci_rc < 0)
		goto fail0;

	if (!mci_pdev) {
		x38_registered = 0;
		mci_pdev = pci_get_device(PCI_VENDOR_ID_INTEL,
					PCI_DEVICE_ID_INTEL_X38_HB, NULL);
		if (!mci_pdev) {
			debugf0("x38 pci_get_device fail\n");
			pci_rc = -ENODEV;
			goto fail1;
		}

		pci_rc = x38_init_one(mci_pdev, x38_pci_tbl);
		if (pci_rc < 0) {
			debugf0("x38 init fail\n");
			pci_rc = -ENODEV;
			goto fail1;
		}
	}

	return 0;

fail1:
	pci_unregister_driver(&x38_driver);

fail0:
	if (mci_pdev)
		pci_dev_put(mci_pdev);

	return pci_rc;
}

static void __exit x38_exit(void)
{
	debugf3("MC: %s()\n", __func__);

	pci_unregister_driver(&x38_driver);
	if (!x38_registered) {
		x38_remove_one(mci_pdev);
		pci_dev_put(mci_pdev);
	}
}

module_init(x38_init);
module_exit(x38_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Cluster Computing, Inc. Hitoshi Mitake");
MODULE_DESCRIPTION("MC support for Intel X38 memory hub controllers");

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