// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright Altera Corporation (C) 2016. All rights reserved.
 */
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/genalloc.h>
#include <linux/module.h>
#include <linux/of_address.h>
#include <linux/of_platform.h>

#include "core.h"

#define ALTR_OCRAM_CLEAR_ECC          0x00000018
#define ALTR_OCRAM_ECC_EN             0x00000019

void socfpga_init_ocram_ecc(void)
{
	struct device_node *np;
	void __iomem *mapped_ocr_edac_addr;

	/* Find the OCRAM EDAC device tree node */
	np = of_find_compatible_node(NULL, NULL, "altr,socfpga-ocram-ecc");
	if (!np) {
		pr_err("Unable to find socfpga-ocram-ecc\n");
		return;
	}

	mapped_ocr_edac_addr = of_iomap(np, 0);
	of_node_put(np);
	if (!mapped_ocr_edac_addr) {
		pr_err("Unable to map OCRAM ecc regs.\n");
		return;
	}

	/* Clear any pending OCRAM ECC interrupts, then enable ECC */
	writel(ALTR_OCRAM_CLEAR_ECC, mapped_ocr_edac_addr);
	writel(ALTR_OCRAM_ECC_EN, mapped_ocr_edac_addr);

	iounmap(mapped_ocr_edac_addr);
}

/* Arria10 OCRAM Section */
#define ALTR_A10_ECC_CTRL_OFST          0x08
#define ALTR_A10_OCRAM_ECC_EN_CTL       (BIT(1) | BIT(0))
#define ALTR_A10_ECC_INITA              BIT(16)

#define ALTR_A10_ECC_INITSTAT_OFST      0x0C
#define ALTR_A10_ECC_INITCOMPLETEA      BIT(0)
#define ALTR_A10_ECC_INITCOMPLETEB      BIT(8)

#define ALTR_A10_ECC_ERRINTEN_OFST      0x10
#define ALTR_A10_ECC_SERRINTEN          BIT(0)

#define ALTR_A10_ECC_INTSTAT_OFST       0x20
#define ALTR_A10_ECC_SERRPENA           BIT(0)
#define ALTR_A10_ECC_DERRPENA           BIT(8)
#define ALTR_A10_ECC_ERRPENA_MASK       (ALTR_A10_ECC_SERRPENA | \
					 ALTR_A10_ECC_DERRPENA)
/* ECC Manager Defines */
#define A10_SYSMGR_ECC_INTMASK_SET_OFST   0x94
#define A10_SYSMGR_ECC_INTMASK_CLR_OFST   0x98
#define A10_SYSMGR_ECC_INTMASK_OCRAM      BIT(1)

#define ALTR_A10_ECC_INIT_WATCHDOG_10US   10000

static inline void ecc_set_bits(u32 bit_mask, void __iomem *ioaddr)
{
	u32 value = readl(ioaddr);

	value |= bit_mask;
	writel(value, ioaddr);
}

static inline void ecc_clear_bits(u32 bit_mask, void __iomem *ioaddr)
{
	u32 value = readl(ioaddr);

	value &= ~bit_mask;
	writel(value, ioaddr);
}

static inline int ecc_test_bits(u32 bit_mask, void __iomem *ioaddr)
{
	u32 value = readl(ioaddr);

	return (value & bit_mask) ? 1 : 0;
}

/*
 * This function uses the memory initialization block in the Arria10 ECC
 * controller to initialize/clear the entire memory data and ECC data.
 */
static int altr_init_memory_port(void __iomem *ioaddr)
{
	int limit = ALTR_A10_ECC_INIT_WATCHDOG_10US;

	ecc_set_bits(ALTR_A10_ECC_INITA, (ioaddr + ALTR_A10_ECC_CTRL_OFST));
	while (limit--) {
		if (ecc_test_bits(ALTR_A10_ECC_INITCOMPLETEA,
				  (ioaddr + ALTR_A10_ECC_INITSTAT_OFST)))
			break;
		udelay(1);
	}
	if (limit < 0)
		return -EBUSY;

	/* Clear any pending ECC interrupts */
	writel(ALTR_A10_ECC_ERRPENA_MASK,
	       (ioaddr + ALTR_A10_ECC_INTSTAT_OFST));

	return 0;
}

void socfpga_init_arria10_ocram_ecc(void)
{
	struct device_node *np;
	int ret = 0;
	void __iomem *ecc_block_base;

	if (!sys_manager_base_addr) {
		pr_err("SOCFPGA: sys-mgr is not initialized\n");
		return;
	}

	/* Find the OCRAM EDAC device tree node */
	np = of_find_compatible_node(NULL, NULL, "altr,socfpga-a10-ocram-ecc");
	if (!np) {
		pr_err("Unable to find socfpga-a10-ocram-ecc\n");
		return;
	}

	/* Map the ECC Block */
	ecc_block_base = of_iomap(np, 0);
	of_node_put(np);
	if (!ecc_block_base) {
		pr_err("Unable to map OCRAM ECC block\n");
		return;
	}

	/* Disable ECC */
	writel(ALTR_A10_OCRAM_ECC_EN_CTL,
	       sys_manager_base_addr + A10_SYSMGR_ECC_INTMASK_SET_OFST);
	ecc_clear_bits(ALTR_A10_ECC_SERRINTEN,
		       (ecc_block_base + ALTR_A10_ECC_ERRINTEN_OFST));
	ecc_clear_bits(ALTR_A10_OCRAM_ECC_EN_CTL,
		       (ecc_block_base + ALTR_A10_ECC_CTRL_OFST));

	/* Ensure all writes complete */
	wmb();

	/* Use HW initialization block to initialize memory for ECC */
	ret = altr_init_memory_port(ecc_block_base);
	if (ret) {
		pr_err("ECC: cannot init OCRAM PORTA memory\n");
		goto exit;
	}

	/* Enable ECC */
	ecc_set_bits(ALTR_A10_OCRAM_ECC_EN_CTL,
		     (ecc_block_base + ALTR_A10_ECC_CTRL_OFST));
	ecc_set_bits(ALTR_A10_ECC_SERRINTEN,
		     (ecc_block_base + ALTR_A10_ECC_ERRINTEN_OFST));
	writel(ALTR_A10_OCRAM_ECC_EN_CTL,
	       sys_manager_base_addr + A10_SYSMGR_ECC_INTMASK_CLR_OFST);

	/* Ensure all writes complete */
	wmb();
exit:
	iounmap(ecc_block_base);
}
