/*
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 *
 * Copyright (C) 2009 Wind River Systems,
 *   written by Ralf Baechle <ralf@linux-mips.org>
 *
 * Copyright (c) 2013 by Cisco Systems, Inc.
 * All rights reserved.
 */
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/io.h>
#include <linux/edac.h>
#include <linux/ctype.h>

#include <asm/octeon/octeon.h>
#include <asm/octeon/cvmx-lmcx-defs.h>

#include "edac_core.h"
#include "edac_module.h"

#define OCTEON_MAX_MC 4

#define to_mci(k) container_of(k, struct mem_ctl_info, dev)

struct octeon_lmc_pvt {
	unsigned long inject;
	unsigned long error_type;
	unsigned long dimm;
	unsigned long rank;
	unsigned long bank;
	unsigned long row;
	unsigned long col;
};

static void octeon_lmc_edac_poll(struct mem_ctl_info *mci)
{
	union cvmx_lmcx_mem_cfg0 cfg0;
	bool do_clear = false;
	char msg[64];

	cfg0.u64 = cvmx_read_csr(CVMX_LMCX_MEM_CFG0(mci->mc_idx));
	if (cfg0.s.sec_err || cfg0.s.ded_err) {
		union cvmx_lmcx_fadr fadr;
		fadr.u64 = cvmx_read_csr(CVMX_LMCX_FADR(mci->mc_idx));
		snprintf(msg, sizeof(msg),
			 "DIMM %d rank %d bank %d row %d col %d",
			 fadr.cn30xx.fdimm, fadr.cn30xx.fbunk,
			 fadr.cn30xx.fbank, fadr.cn30xx.frow, fadr.cn30xx.fcol);
	}

	if (cfg0.s.sec_err) {
		edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, 1, 0, 0, 0,
				     -1, -1, -1, msg, "");
		cfg0.s.sec_err = -1;	/* Done, re-arm */
		do_clear = true;
	}

	if (cfg0.s.ded_err) {
		edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci, 1, 0, 0, 0,
				     -1, -1, -1, msg, "");
		cfg0.s.ded_err = -1;	/* Done, re-arm */
		do_clear = true;
	}
	if (do_clear)
		cvmx_write_csr(CVMX_LMCX_MEM_CFG0(mci->mc_idx), cfg0.u64);
}

static void octeon_lmc_edac_poll_o2(struct mem_ctl_info *mci)
{
	struct octeon_lmc_pvt *pvt = mci->pvt_info;
	union cvmx_lmcx_int int_reg;
	bool do_clear = false;
	char msg[64];

	if (!pvt->inject)
		int_reg.u64 = cvmx_read_csr(CVMX_LMCX_INT(mci->mc_idx));
	else {
		int_reg.u64 = 0;
		if (pvt->error_type == 1)
			int_reg.s.sec_err = 1;
		if (pvt->error_type == 2)
			int_reg.s.ded_err = 1;
	}

	if (int_reg.s.sec_err || int_reg.s.ded_err) {
		union cvmx_lmcx_fadr fadr;
		if (likely(!pvt->inject))
			fadr.u64 = cvmx_read_csr(CVMX_LMCX_FADR(mci->mc_idx));
		else {
			fadr.cn61xx.fdimm = pvt->dimm;
			fadr.cn61xx.fbunk = pvt->rank;
			fadr.cn61xx.fbank = pvt->bank;
			fadr.cn61xx.frow = pvt->row;
			fadr.cn61xx.fcol = pvt->col;
		}
		snprintf(msg, sizeof(msg),
			 "DIMM %d rank %d bank %d row %d col %d",
			 fadr.cn61xx.fdimm, fadr.cn61xx.fbunk,
			 fadr.cn61xx.fbank, fadr.cn61xx.frow, fadr.cn61xx.fcol);
	}

	if (int_reg.s.sec_err) {
		edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, 1, 0, 0, 0,
				     -1, -1, -1, msg, "");
		int_reg.s.sec_err = -1;	/* Done, re-arm */
		do_clear = true;
	}

	if (int_reg.s.ded_err) {
		edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci, 1, 0, 0, 0,
				     -1, -1, -1, msg, "");
		int_reg.s.ded_err = -1;	/* Done, re-arm */
		do_clear = true;
	}

	if (do_clear) {
		if (likely(!pvt->inject))
			cvmx_write_csr(CVMX_LMCX_INT(mci->mc_idx), int_reg.u64);
		else
			pvt->inject = 0;
	}
}

/************************ MC SYSFS parts ***********************************/

/* Only a couple naming differences per template, so very similar */
#define TEMPLATE_SHOW(reg)						\
static ssize_t octeon_mc_inject_##reg##_show(struct device *dev,	\
			       struct device_attribute *attr,		\
			       char *data)				\
{									\
	struct mem_ctl_info *mci = to_mci(dev);				\
	struct octeon_lmc_pvt *pvt = mci->pvt_info;			\
	return sprintf(data, "%016llu\n", (u64)pvt->reg);		\
}

#define TEMPLATE_STORE(reg)						\
static ssize_t octeon_mc_inject_##reg##_store(struct device *dev,	\
			       struct device_attribute *attr,		\
			       const char *data, size_t count)		\
{									\
	struct mem_ctl_info *mci = to_mci(dev);				\
	struct octeon_lmc_pvt *pvt = mci->pvt_info;			\
	if (isdigit(*data)) {						\
		if (!kstrtoul(data, 0, &pvt->reg))			\
			return count;					\
	}								\
	return 0;							\
}

TEMPLATE_SHOW(inject);
TEMPLATE_STORE(inject);
TEMPLATE_SHOW(dimm);
TEMPLATE_STORE(dimm);
TEMPLATE_SHOW(bank);
TEMPLATE_STORE(bank);
TEMPLATE_SHOW(rank);
TEMPLATE_STORE(rank);
TEMPLATE_SHOW(row);
TEMPLATE_STORE(row);
TEMPLATE_SHOW(col);
TEMPLATE_STORE(col);

static ssize_t octeon_mc_inject_error_type_store(struct device *dev,
					  struct device_attribute *attr,
					  const char *data,
					  size_t count)
{
	struct mem_ctl_info *mci = to_mci(dev);
	struct octeon_lmc_pvt *pvt = mci->pvt_info;

	if (!strncmp(data, "single", 6))
		pvt->error_type = 1;
	else if (!strncmp(data, "double", 6))
		pvt->error_type = 2;

	return count;
}

static ssize_t octeon_mc_inject_error_type_show(struct device *dev,
					 struct device_attribute *attr,
					 char *data)
{
	struct mem_ctl_info *mci = to_mci(dev);
	struct octeon_lmc_pvt *pvt = mci->pvt_info;
	if (pvt->error_type == 1)
		return sprintf(data, "single");
	else if (pvt->error_type == 2)
		return sprintf(data, "double");

	return 0;
}

static DEVICE_ATTR(inject, S_IRUGO | S_IWUSR,
		   octeon_mc_inject_inject_show, octeon_mc_inject_inject_store);
static DEVICE_ATTR(error_type, S_IRUGO | S_IWUSR,
		   octeon_mc_inject_error_type_show, octeon_mc_inject_error_type_store);
static DEVICE_ATTR(dimm, S_IRUGO | S_IWUSR,
		   octeon_mc_inject_dimm_show, octeon_mc_inject_dimm_store);
static DEVICE_ATTR(rank, S_IRUGO | S_IWUSR,
		   octeon_mc_inject_rank_show, octeon_mc_inject_rank_store);
static DEVICE_ATTR(bank, S_IRUGO | S_IWUSR,
		   octeon_mc_inject_bank_show, octeon_mc_inject_bank_store);
static DEVICE_ATTR(row, S_IRUGO | S_IWUSR,
		   octeon_mc_inject_row_show, octeon_mc_inject_row_store);
static DEVICE_ATTR(col, S_IRUGO | S_IWUSR,
		   octeon_mc_inject_col_show, octeon_mc_inject_col_store);


static int octeon_set_mc_sysfs_attributes(struct mem_ctl_info *mci)
{
	int rc;

	rc = device_create_file(&mci->dev, &dev_attr_inject);
	if (rc < 0)
		return rc;
	rc = device_create_file(&mci->dev, &dev_attr_error_type);
	if (rc < 0)
		return rc;
	rc = device_create_file(&mci->dev, &dev_attr_dimm);
	if (rc < 0)
		return rc;
	rc = device_create_file(&mci->dev, &dev_attr_rank);
	if (rc < 0)
		return rc;
	rc = device_create_file(&mci->dev, &dev_attr_bank);
	if (rc < 0)
		return rc;
	rc = device_create_file(&mci->dev, &dev_attr_row);
	if (rc < 0)
		return rc;
	rc = device_create_file(&mci->dev, &dev_attr_col);
	if (rc < 0)
		return rc;

	return 0;
}

static int octeon_lmc_edac_probe(struct platform_device *pdev)
{
	struct mem_ctl_info *mci;
	struct edac_mc_layer layers[1];
	int mc = pdev->id;

	opstate_init();

	layers[0].type = EDAC_MC_LAYER_CHANNEL;
	layers[0].size = 1;
	layers[0].is_virt_csrow = false;

	if (OCTEON_IS_MODEL(OCTEON_FAM_1_PLUS)) {
		union cvmx_lmcx_mem_cfg0 cfg0;

		cfg0.u64 = cvmx_read_csr(CVMX_LMCX_MEM_CFG0(0));
		if (!cfg0.s.ecc_ena) {
			dev_info(&pdev->dev, "Disabled (ECC not enabled)\n");
			return 0;
		}

		mci = edac_mc_alloc(mc, ARRAY_SIZE(layers), layers, sizeof(struct octeon_lmc_pvt));
		if (!mci)
			return -ENXIO;

		mci->pdev = &pdev->dev;
		mci->dev_name = dev_name(&pdev->dev);

		mci->mod_name = "octeon-lmc";
		mci->ctl_name = "octeon-lmc-err";
		mci->edac_check = octeon_lmc_edac_poll;

		if (edac_mc_add_mc(mci)) {
			dev_err(&pdev->dev, "edac_mc_add_mc() failed\n");
			edac_mc_free(mci);
			return -ENXIO;
		}

		if (octeon_set_mc_sysfs_attributes(mci)) {
			dev_err(&pdev->dev, "octeon_set_mc_sysfs_attributes() failed\n");
			return -ENXIO;
		}


		cfg0.u64 = cvmx_read_csr(CVMX_LMCX_MEM_CFG0(mc));
		cfg0.s.intr_ded_ena = 0;	/* We poll */
		cfg0.s.intr_sec_ena = 0;
		cvmx_write_csr(CVMX_LMCX_MEM_CFG0(mc), cfg0.u64);
	} else {
		/* OCTEON II */
		union cvmx_lmcx_int_en en;
		union cvmx_lmcx_config config;

		config.u64 = cvmx_read_csr(CVMX_LMCX_CONFIG(0));
		if (!config.s.ecc_ena) {
			dev_info(&pdev->dev, "Disabled (ECC not enabled)\n");
			return 0;
		}

		mci = edac_mc_alloc(mc, ARRAY_SIZE(layers), layers, sizeof(struct octeon_lmc_pvt));
		if (!mci)
			return -ENXIO;

		mci->pdev = &pdev->dev;
		mci->dev_name = dev_name(&pdev->dev);

		mci->mod_name = "octeon-lmc";
		mci->ctl_name = "co_lmc_err";
		mci->edac_check = octeon_lmc_edac_poll_o2;

		if (edac_mc_add_mc(mci)) {
			dev_err(&pdev->dev, "edac_mc_add_mc() failed\n");
			edac_mc_free(mci);
			return -ENXIO;
		}

		if (octeon_set_mc_sysfs_attributes(mci)) {
			dev_err(&pdev->dev, "octeon_set_mc_sysfs_attributes() failed\n");
			return -ENXIO;
		}


		en.u64 = cvmx_read_csr(CVMX_LMCX_MEM_CFG0(mc));
		en.s.intr_ded_ena = 0;	/* We poll */
		en.s.intr_sec_ena = 0;
		cvmx_write_csr(CVMX_LMCX_MEM_CFG0(mc), en.u64);
	}
	platform_set_drvdata(pdev, mci);

	return 0;
}

static int octeon_lmc_edac_remove(struct platform_device *pdev)
{
	struct mem_ctl_info *mci = platform_get_drvdata(pdev);

	edac_mc_del_mc(&pdev->dev);
	edac_mc_free(mci);
	return 0;
}

static struct platform_driver octeon_lmc_edac_driver = {
	.probe = octeon_lmc_edac_probe,
	.remove = octeon_lmc_edac_remove,
	.driver = {
		   .name = "octeon_lmc_edac",
	}
};
module_platform_driver(octeon_lmc_edac_driver);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Ralf Baechle <ralf@linux-mips.org>");
