/*
 * Synopsys DDR ECC Driver
 * This driver is based on ppc4xx_edac.c drivers
 *
 * Copyright (C) 2012 - 2014 Xilinx, Inc.
 *
 * 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, either version 2 of the License, or
 * (at your option) any later version.
 *
 * 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.  See the
 * GNU General Public License for more details.
 *
 * 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
 */

#include <linux/edac.h>
#include <linux/module.h>
#include <linux/platform_device.h>

#include "edac_core.h"

/* Number of cs_rows needed per memory controller */
#define SYNPS_EDAC_NR_CSROWS	1

/* Number of channels per memory controller */
#define SYNPS_EDAC_NR_CHANS	1

/* Granularity of reported error in bytes */
#define SYNPS_EDAC_ERR_GRAIN	1

#define SYNPS_EDAC_MSG_SIZE	256

#define SYNPS_EDAC_MOD_STRING	"synps_edac"
#define SYNPS_EDAC_MOD_VER	"1"

/* Synopsys DDR memory controller registers that are relevant to ECC */
#define CTRL_OFST		0x0
#define T_ZQ_OFST		0xA4

/* ECC control register */
#define ECC_CTRL_OFST		0xC4
/* ECC log register */
#define CE_LOG_OFST		0xC8
/* ECC address register */
#define CE_ADDR_OFST		0xCC
/* ECC data[31:0] register */
#define CE_DATA_31_0_OFST	0xD0

/* Uncorrectable error info registers */
#define UE_LOG_OFST		0xDC
#define UE_ADDR_OFST		0xE0
#define UE_DATA_31_0_OFST	0xE4

#define STAT_OFST		0xF0
#define SCRUB_OFST		0xF4

/* Control register bit field definitions */
#define CTRL_BW_MASK		0xC
#define CTRL_BW_SHIFT		2

#define DDRCTL_WDTH_16		1
#define DDRCTL_WDTH_32		0

/* ZQ register bit field definitions */
#define T_ZQ_DDRMODE_MASK	0x2

/* ECC control register bit field definitions */
#define ECC_CTRL_CLR_CE_ERR	0x2
#define ECC_CTRL_CLR_UE_ERR	0x1

/* ECC correctable/uncorrectable error log register definitions */
#define LOG_VALID		0x1
#define CE_LOG_BITPOS_MASK	0xFE
#define CE_LOG_BITPOS_SHIFT	1

/* ECC correctable/uncorrectable error address register definitions */
#define ADDR_COL_MASK		0xFFF
#define ADDR_ROW_MASK		0xFFFF000
#define ADDR_ROW_SHIFT		12
#define ADDR_BANK_MASK		0x70000000
#define ADDR_BANK_SHIFT		28

/* ECC statistic register definitions */
#define STAT_UECNT_MASK		0xFF
#define STAT_CECNT_MASK		0xFF00
#define STAT_CECNT_SHIFT	8

/* ECC scrub register definitions */
#define SCRUB_MODE_MASK		0x7
#define SCRUB_MODE_SECDED	0x4

/**
 * struct ecc_error_info - ECC error log information
 * @row:	Row number
 * @col:	Column number
 * @bank:	Bank number
 * @bitpos:	Bit position
 * @data:	Data causing the error
 */
struct ecc_error_info {
	u32 row;
	u32 col;
	u32 bank;
	u32 bitpos;
	u32 data;
};

/**
 * struct synps_ecc_status - ECC status information to report
 * @ce_cnt:	Correctable error count
 * @ue_cnt:	Uncorrectable error count
 * @ceinfo:	Correctable error log information
 * @ueinfo:	Uncorrectable error log information
 */
struct synps_ecc_status {
	u32 ce_cnt;
	u32 ue_cnt;
	struct ecc_error_info ceinfo;
	struct ecc_error_info ueinfo;
};

/**
 * struct synps_edac_priv - DDR memory controller private instance data
 * @baseaddr:	Base address of the DDR controller
 * @message:	Buffer for framing the event specific info
 * @stat:	ECC status information
 * @ce_cnt:	Correctable Error count
 * @ue_cnt:	Uncorrectable Error count
 */
struct synps_edac_priv {
	void __iomem *baseaddr;
	char message[SYNPS_EDAC_MSG_SIZE];
	struct synps_ecc_status stat;
	u32 ce_cnt;
	u32 ue_cnt;
};

/**
 * synps_edac_geterror_info - Get the current ecc error info
 * @base:	Pointer to the base address of the ddr memory controller
 * @p:		Pointer to the synopsys ecc status structure
 *
 * Determines there is any ecc error or not
 *
 * Return: one if there is no error otherwise returns zero
 */
static int synps_edac_geterror_info(void __iomem *base,
				    struct synps_ecc_status *p)
{
	u32 regval, clearval = 0;

	regval = readl(base + STAT_OFST);
	if (!regval)
		return 1;

	p->ce_cnt = (regval & STAT_CECNT_MASK) >> STAT_CECNT_SHIFT;
	p->ue_cnt = regval & STAT_UECNT_MASK;

	regval = readl(base + CE_LOG_OFST);
	if (!(p->ce_cnt && (regval & LOG_VALID)))
		goto ue_err;

	p->ceinfo.bitpos = (regval & CE_LOG_BITPOS_MASK) >> CE_LOG_BITPOS_SHIFT;
	regval = readl(base + CE_ADDR_OFST);
	p->ceinfo.row = (regval & ADDR_ROW_MASK) >> ADDR_ROW_SHIFT;
	p->ceinfo.col = regval & ADDR_COL_MASK;
	p->ceinfo.bank = (regval & ADDR_BANK_MASK) >> ADDR_BANK_SHIFT;
	p->ceinfo.data = readl(base + CE_DATA_31_0_OFST);
	edac_dbg(3, "ce bit position: %d data: %d\n", p->ceinfo.bitpos,
		 p->ceinfo.data);
	clearval = ECC_CTRL_CLR_CE_ERR;

ue_err:
	regval = readl(base + UE_LOG_OFST);
	if (!(p->ue_cnt && (regval & LOG_VALID)))
		goto out;

	regval = readl(base + UE_ADDR_OFST);
	p->ueinfo.row = (regval & ADDR_ROW_MASK) >> ADDR_ROW_SHIFT;
	p->ueinfo.col = regval & ADDR_COL_MASK;
	p->ueinfo.bank = (regval & ADDR_BANK_MASK) >> ADDR_BANK_SHIFT;
	p->ueinfo.data = readl(base + UE_DATA_31_0_OFST);
	clearval |= ECC_CTRL_CLR_UE_ERR;

out:
	writel(clearval, base + ECC_CTRL_OFST);
	writel(0x0, base + ECC_CTRL_OFST);

	return 0;
}

/**
 * synps_edac_handle_error - Handle controller error types CE and UE
 * @mci:	Pointer to the edac memory controller instance
 * @p:		Pointer to the synopsys ecc status structure
 *
 * Handles the controller ECC correctable and un correctable error.
 */
static void synps_edac_handle_error(struct mem_ctl_info *mci,
				    struct synps_ecc_status *p)
{
	struct synps_edac_priv *priv = mci->pvt_info;
	struct ecc_error_info *pinf;

	if (p->ce_cnt) {
		pinf = &p->ceinfo;
		snprintf(priv->message, SYNPS_EDAC_MSG_SIZE,
			 "DDR ECC error type :%s Row %d Bank %d Col %d ",
			 "CE", pinf->row, pinf->bank, pinf->col);
		edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci,
				     p->ce_cnt, 0, 0, 0, 0, 0, -1,
				     priv->message, "");
	}

	if (p->ue_cnt) {
		pinf = &p->ueinfo;
		snprintf(priv->message, SYNPS_EDAC_MSG_SIZE,
			 "DDR ECC error type :%s Row %d Bank %d Col %d ",
			 "UE", pinf->row, pinf->bank, pinf->col);
		edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci,
				     p->ue_cnt, 0, 0, 0, 0, 0, -1,
				     priv->message, "");
	}

	memset(p, 0, sizeof(*p));
}

/**
 * synps_edac_check - Check controller for ECC errors
 * @mci:	Pointer to the edac memory controller instance
 *
 * Used to check and post ECC errors. Called by the polling thread
 */
static void synps_edac_check(struct mem_ctl_info *mci)
{
	struct synps_edac_priv *priv = mci->pvt_info;
	int status;

	status = synps_edac_geterror_info(priv->baseaddr, &priv->stat);
	if (status)
		return;

	priv->ce_cnt += priv->stat.ce_cnt;
	priv->ue_cnt += priv->stat.ue_cnt;
	synps_edac_handle_error(mci, &priv->stat);

	edac_dbg(3, "Total error count ce %d ue %d\n",
		 priv->ce_cnt, priv->ue_cnt);
}

/**
 * synps_edac_get_dtype - Return the controller memory width
 * @base:	Pointer to the ddr memory controller base address
 *
 * Get the EDAC device type width appropriate for the current controller
 * configuration.
 *
 * Return: a device type width enumeration.
 */
static enum dev_type synps_edac_get_dtype(const void __iomem *base)
{
	enum dev_type dt;
	u32 width;

	width = readl(base + CTRL_OFST);
	width = (width & CTRL_BW_MASK) >> CTRL_BW_SHIFT;

	switch (width) {
	case DDRCTL_WDTH_16:
		dt = DEV_X2;
		break;
	case DDRCTL_WDTH_32:
		dt = DEV_X4;
		break;
	default:
		dt = DEV_UNKNOWN;
	}

	return dt;
}

/**
 * synps_edac_get_eccstate - Return the controller ecc enable/disable status
 * @base:	Pointer to the ddr memory controller base address
 *
 * Get the ECC enable/disable status for the controller
 *
 * Return: a ecc status boolean i.e true/false - enabled/disabled.
 */
static bool synps_edac_get_eccstate(void __iomem *base)
{
	enum dev_type dt;
	u32 ecctype;
	bool state = false;

	dt = synps_edac_get_dtype(base);
	if (dt == DEV_UNKNOWN)
		return state;

	ecctype = readl(base + SCRUB_OFST) & SCRUB_MODE_MASK;
	if ((ecctype == SCRUB_MODE_SECDED) && (dt == DEV_X2))
		state = true;

	return state;
}

/**
 * synps_edac_get_memsize - reads the size of the attached memory device
 *
 * Return: the memory size in bytes
 */
static u32 synps_edac_get_memsize(void)
{
	struct sysinfo inf;

	si_meminfo(&inf);

	return inf.totalram * inf.mem_unit;
}

/**
 * synps_edac_get_mtype - Returns controller memory type
 * @base:	pointer to the synopsys ecc status structure
 *
 * Get the EDAC memory type appropriate for the current controller
 * configuration.
 *
 * Return: a memory type enumeration.
 */
static enum mem_type synps_edac_get_mtype(const void __iomem *base)
{
	enum mem_type mt;
	u32 memtype;

	memtype = readl(base + T_ZQ_OFST);

	if (memtype & T_ZQ_DDRMODE_MASK)
		mt = MEM_DDR3;
	else
		mt = MEM_DDR2;

	return mt;
}

/**
 * synps_edac_init_csrows - Initialize the cs row data
 * @mci:	Pointer to the edac memory controller instance
 *
 * Initializes the chip select rows associated with the EDAC memory
 * controller instance
 *
 * Return: Unconditionally 0.
 */
static int synps_edac_init_csrows(struct mem_ctl_info *mci)
{
	struct csrow_info *csi;
	struct dimm_info *dimm;
	struct synps_edac_priv *priv = mci->pvt_info;
	u32 size;
	int row, j;

	for (row = 0; row < mci->nr_csrows; row++) {
		csi = mci->csrows[row];
		size = synps_edac_get_memsize();

		for (j = 0; j < csi->nr_channels; j++) {
			dimm            = csi->channels[j]->dimm;
			dimm->edac_mode = EDAC_SECDED;
			dimm->mtype     = synps_edac_get_mtype(priv->baseaddr);
			dimm->nr_pages  = (size >> PAGE_SHIFT) / csi->nr_channels;
			dimm->grain     = SYNPS_EDAC_ERR_GRAIN;
			dimm->dtype     = synps_edac_get_dtype(priv->baseaddr);
		}
	}

	return 0;
}

/**
 * synps_edac_mc_init - Initialize driver instance
 * @mci:	Pointer to the edac memory controller instance
 * @pdev:	Pointer to the platform_device struct
 *
 * Performs initialization of the EDAC memory controller instance and
 * related driver-private data associated with the memory controller the
 * instance is bound to.
 *
 * Return: Always zero.
 */
static int synps_edac_mc_init(struct mem_ctl_info *mci,
				 struct platform_device *pdev)
{
	int status;
	struct synps_edac_priv *priv;

	mci->pdev = &pdev->dev;
	priv = mci->pvt_info;
	platform_set_drvdata(pdev, mci);

	/* Initialize controller capabilities and configuration */
	mci->mtype_cap = MEM_FLAG_DDR3 | MEM_FLAG_DDR2;
	mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_SECDED;
	mci->scrub_cap = SCRUB_HW_SRC;
	mci->scrub_mode = SCRUB_NONE;

	mci->edac_cap = EDAC_FLAG_SECDED;
	mci->ctl_name = "synps_ddr_controller";
	mci->dev_name = SYNPS_EDAC_MOD_STRING;
	mci->mod_name = SYNPS_EDAC_MOD_VER;
	mci->mod_ver = "1";

	edac_op_state = EDAC_OPSTATE_POLL;
	mci->edac_check = synps_edac_check;
	mci->ctl_page_to_phys = NULL;

	status = synps_edac_init_csrows(mci);

	return status;
}

/**
 * synps_edac_mc_probe - Check controller and bind driver
 * @pdev:	Pointer to the platform_device struct
 *
 * Probes a specific controller instance for binding with the driver.
 *
 * Return: 0 if the controller instance was successfully bound to the
 * driver; otherwise, < 0 on error.
 */
static int synps_edac_mc_probe(struct platform_device *pdev)
{
	struct mem_ctl_info *mci;
	struct edac_mc_layer layers[2];
	struct synps_edac_priv *priv;
	int rc;
	struct resource *res;
	void __iomem *baseaddr;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	baseaddr = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(baseaddr))
		return PTR_ERR(baseaddr);

	if (!synps_edac_get_eccstate(baseaddr)) {
		edac_printk(KERN_INFO, EDAC_MC, "ECC not enabled\n");
		return -ENXIO;
	}

	layers[0].type = EDAC_MC_LAYER_CHIP_SELECT;
	layers[0].size = SYNPS_EDAC_NR_CSROWS;
	layers[0].is_virt_csrow = true;
	layers[1].type = EDAC_MC_LAYER_CHANNEL;
	layers[1].size = SYNPS_EDAC_NR_CHANS;
	layers[1].is_virt_csrow = false;

	mci = edac_mc_alloc(0, ARRAY_SIZE(layers), layers,
			    sizeof(struct synps_edac_priv));
	if (!mci) {
		edac_printk(KERN_ERR, EDAC_MC,
			    "Failed memory allocation for mc instance\n");
		return -ENOMEM;
	}

	priv = mci->pvt_info;
	priv->baseaddr = baseaddr;
	rc = synps_edac_mc_init(mci, pdev);
	if (rc) {
		edac_printk(KERN_ERR, EDAC_MC,
			    "Failed to initialize instance\n");
		goto free_edac_mc;
	}

	rc = edac_mc_add_mc(mci);
	if (rc) {
		edac_printk(KERN_ERR, EDAC_MC,
			    "Failed to register with EDAC core\n");
		goto free_edac_mc;
	}

	/*
	 * Start capturing the correctable and uncorrectable errors. A write of
	 * 0 starts the counters.
	 */
	writel(0x0, baseaddr + ECC_CTRL_OFST);
	return rc;

free_edac_mc:
	edac_mc_free(mci);

	return rc;
}

/**
 * synps_edac_mc_remove - Unbind driver from controller
 * @pdev:	Pointer to the platform_device struct
 *
 * Return: Unconditionally 0
 */
static int synps_edac_mc_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 const struct of_device_id synps_edac_match[] = {
	{ .compatible = "xlnx,zynq-ddrc-a05", },
	{ /* end of table */ }
};

MODULE_DEVICE_TABLE(of, synps_edac_match);

static struct platform_driver synps_edac_mc_driver = {
	.driver = {
		   .name = "synopsys-edac",
		   .of_match_table = synps_edac_match,
		   },
	.probe = synps_edac_mc_probe,
	.remove = synps_edac_mc_remove,
};

module_platform_driver(synps_edac_mc_driver);

MODULE_AUTHOR("Xilinx Inc");
MODULE_DESCRIPTION("Synopsys DDR ECC driver");
MODULE_LICENSE("GPL v2");
