/*
 * Copyright 2011 Tilera Corporation. All Rights Reserved.
 *
 *   This program is free software; you can redistribute it and/or
 *   modify it under the terms of the GNU General Public License
 *   as published by the Free Software Foundation, version 2.
 *
 *   This program is distributed in the hope that it will be useful, but
 *   WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
 *   NON INFRINGEMENT.  See the GNU General Public License for
 *   more details.
 * Tilera-specific EDAC driver.
 *
 * This source code is derived from the following driver:
 *
 * Cell MIC driver for ECC counting
 *
 * Copyright 2007 Benjamin Herrenschmidt, IBM Corp.
 *                <benh@kernel.crashing.org>
 *
 */

#include <linux/module.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/uaccess.h>
#include <linux/edac.h>
#include <hv/hypervisor.h>
#include <hv/drv_mshim_intf.h>

#include "edac_module.h"

#define DRV_NAME	"tile-edac"

/* Number of cs_rows needed per memory controller on TILEPro. */
#define TILE_EDAC_NR_CSROWS	1

/* Number of channels per memory controller on TILEPro. */
#define TILE_EDAC_NR_CHANS	1

/* Granularity of reported error in bytes on TILEPro. */
#define TILE_EDAC_ERROR_GRAIN	8

/* TILE processor has multiple independent memory controllers. */
struct platform_device *mshim_pdev[TILE_MAX_MSHIMS];

struct tile_edac_priv {
	int		hv_devhdl;	/* Hypervisor device handle. */
	int		node;		/* Memory controller instance #. */
	unsigned int	ce_count;	/*
					 * Correctable-error counter
					 * kept by the driver.
					 */
};

static void tile_edac_check(struct mem_ctl_info *mci)
{
	struct tile_edac_priv	*priv = mci->pvt_info;
	struct mshim_mem_error	mem_error;

	if (hv_dev_pread(priv->hv_devhdl, 0, (HV_VirtAddr)&mem_error,
		sizeof(struct mshim_mem_error), MSHIM_MEM_ERROR_OFF) !=
		sizeof(struct mshim_mem_error)) {
		pr_err(DRV_NAME ": MSHIM_MEM_ERROR_OFF pread failure.\n");
		return;
	}

	/* Check if the current error count is different from the saved one. */
	if (mem_error.sbe_count != priv->ce_count) {
		dev_dbg(mci->pdev, "ECC CE err on node %d\n", priv->node);
		priv->ce_count = mem_error.sbe_count;
		edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, 1,
				     0, 0, 0,
				     0, 0, -1,
				     mci->ctl_name, "");
	}
}

/*
 * Initialize the 'csrows' table within the mci control structure with the
 * addressing of memory.
 */
static int tile_edac_init_csrows(struct mem_ctl_info *mci)
{
	struct csrow_info	*csrow = mci->csrows[0];
	struct tile_edac_priv	*priv = mci->pvt_info;
	struct mshim_mem_info	mem_info;
	struct dimm_info *dimm = csrow->channels[0]->dimm;

	if (hv_dev_pread(priv->hv_devhdl, 0, (HV_VirtAddr)&mem_info,
		sizeof(struct mshim_mem_info), MSHIM_MEM_INFO_OFF) !=
		sizeof(struct mshim_mem_info)) {
		pr_err(DRV_NAME ": MSHIM_MEM_INFO_OFF pread failure.\n");
		return -1;
	}

	if (mem_info.mem_ecc)
		dimm->edac_mode = EDAC_SECDED;
	else
		dimm->edac_mode = EDAC_NONE;
	switch (mem_info.mem_type) {
	case DDR2:
		dimm->mtype = MEM_DDR2;
		break;

	case DDR3:
		dimm->mtype = MEM_DDR3;
		break;

	default:
		return -1;
	}

	dimm->nr_pages = mem_info.mem_size >> PAGE_SHIFT;
	dimm->grain = TILE_EDAC_ERROR_GRAIN;
	dimm->dtype = DEV_UNKNOWN;

	return 0;
}

static int tile_edac_mc_probe(struct platform_device *pdev)
{
	char			hv_file[32];
	int			hv_devhdl;
	struct mem_ctl_info	*mci;
	struct edac_mc_layer	layers[2];
	struct tile_edac_priv	*priv;
	int			rc;

	sprintf(hv_file, "mshim/%d", pdev->id);
	hv_devhdl = hv_dev_open((HV_VirtAddr)hv_file, 0);
	if (hv_devhdl < 0)
		return -EINVAL;

	/* A TILE MC has a single channel and one chip-select row. */
	layers[0].type = EDAC_MC_LAYER_CHIP_SELECT;
	layers[0].size = TILE_EDAC_NR_CSROWS;
	layers[0].is_virt_csrow = true;
	layers[1].type = EDAC_MC_LAYER_CHANNEL;
	layers[1].size = TILE_EDAC_NR_CHANS;
	layers[1].is_virt_csrow = false;
	mci = edac_mc_alloc(pdev->id, ARRAY_SIZE(layers), layers,
			    sizeof(struct tile_edac_priv));
	if (mci == NULL)
		return -ENOMEM;
	priv = mci->pvt_info;
	priv->node = pdev->id;
	priv->hv_devhdl = hv_devhdl;

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

	mci->mod_name = DRV_NAME;
#ifdef __tilegx__
	mci->ctl_name = "TILEGx_Memory_Controller";
#else
	mci->ctl_name = "TILEPro_Memory_Controller";
#endif
	mci->dev_name = dev_name(&pdev->dev);
	mci->edac_check = tile_edac_check;

	/*
	 * Initialize the MC control structure 'csrows' table
	 * with the mapping and control information.
	 */
	if (tile_edac_init_csrows(mci)) {
		/* No csrows found. */
		mci->edac_cap = EDAC_FLAG_NONE;
	} else {
		mci->edac_cap = EDAC_FLAG_SECDED;
	}

	platform_set_drvdata(pdev, mci);

	/* Register with EDAC core */
	rc = edac_mc_add_mc(mci);
	if (rc) {
		dev_err(&pdev->dev, "failed to register with EDAC core\n");
		edac_mc_free(mci);
		return rc;
	}

	return 0;
}

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

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

static struct platform_driver tile_edac_mc_driver = {
	.driver		= {
		.name	= DRV_NAME,
	},
	.probe		= tile_edac_mc_probe,
	.remove		= tile_edac_mc_remove,
};

/*
 * Driver init routine.
 */
static int __init tile_edac_init(void)
{
	char	hv_file[32];
	struct platform_device *pdev;
	int i, err, num = 0;

	/* Only support POLL mode. */
	edac_op_state = EDAC_OPSTATE_POLL;

	err = platform_driver_register(&tile_edac_mc_driver);
	if (err)
		return err;

	for (i = 0; i < TILE_MAX_MSHIMS; i++) {
		/*
		 * Not all memory controllers are configured such as in the
		 * case of a simulator. So we register only those mshims
		 * that are configured by the hypervisor.
		 */
		sprintf(hv_file, "mshim/%d", i);
		if (hv_dev_open((HV_VirtAddr)hv_file, 0) < 0)
			continue;

		pdev = platform_device_register_simple(DRV_NAME, i, NULL, 0);
		if (IS_ERR(pdev))
			continue;
		mshim_pdev[i] = pdev;
		num++;
	}

	if (num == 0) {
		platform_driver_unregister(&tile_edac_mc_driver);
		return -ENODEV;
	}
	return 0;
}

/*
 * Driver cleanup routine.
 */
static void __exit tile_edac_exit(void)
{
	int i;

	for (i = 0; i < TILE_MAX_MSHIMS; i++) {
		struct platform_device *pdev = mshim_pdev[i];
		if (!pdev)
			continue;

		platform_device_unregister(pdev);
	}
	platform_driver_unregister(&tile_edac_mc_driver);
}

module_init(tile_edac_init);
module_exit(tile_edac_exit);
