/*
 * 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 <linux/io-64-nonatomic-lo-hi.h>
#include "edac_module.h"

#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 */
		edac_dbg(0, "In single channel mode\n");
		x38_channel_num = 1;
	} else {
		edac_dbg(0, "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->pdev);

	/*
	 * 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 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->pdev);

	/*
	 * 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] = lo_hi_readq(window + X38_C0ECCERRLOG);
	if (x38_channel_num == 2)
		info->eccerrlog[1] = lo_hi_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] = lo_hi_readq(window + X38_C0ECCERRLOG);
		if (x38_channel_num == 2)
			info->eccerrlog[1] =
				lo_hi_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, 1, 0, 0, 0,
				     -1, -1, -1,
				     "UE overwrote CE", "");
		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, 1,
					     0, 0, 0,
					     eccerrlog_row(channel, log),
					     -1, -1,
					     "x38 UE", "");
		} else if (log & X38_ECCERRLOG_CE) {
			edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, 1,
					     0, 0, eccerrlog_syndrome(log),
					     eccerrlog_row(channel, log),
					     -1, -1,
					     "x38 CE", "");
		}
	}
}

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

	edac_dbg(1, "MC%d\n", mci->mc_idx);
	x38_get_and_clear_error_info(mci, &info);
	x38_process_error_info(mci, &info);
}

static 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(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;

	edac_dbg(0, "MC:\n");

	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;

	edac_dbg(3, "MC: init mci\n");

	mci->pdev = &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->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)) {
		edac_dbg(3, "MC: failed edac_mc_add_mc()\n");
		goto fail;
	}

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

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

	return rc;
}

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

	edac_dbg(0, "MC:\n");

	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 x38_remove_one(struct pci_dev *pdev)
{
	struct mem_ctl_info *mci;

	edac_dbg(0, "\n");

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

	iounmap(mci->pvt_info);

	edac_mc_free(mci);
}

static const struct pci_device_id 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 = x38_remove_one,
	.id_table = x38_pci_tbl,
};

static int __init x38_init(void)
{
	int pci_rc;

	edac_dbg(3, "MC:\n");

	/* 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) {
			edac_dbg(0, "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) {
			edac_dbg(0, "x38 init fail\n");
			pci_rc = -ENODEV;
			goto fail1;
		}
	}

	return 0;

fail1:
	pci_unregister_driver(&x38_driver);

fail0:
	pci_dev_put(mci_pdev);

	return pci_rc;
}

static void __exit x38_exit(void)
{
	edac_dbg(3, "MC:\n");

	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");
