static void __init socfpga_arria10_init_irq(void)
{
	irqchip_init();
	socfpga_sysmgr_init();
	if (IS_ENABLED(CONFIG_EDAC_ALTERA_L2C))
		socfpga_init_arria10_l2_ecc();
	if (IS_ENABLED(CONFIG_EDAC_ALTERA_OCRAM))
		socfpga_init_arria10_ocram_ecc();
}
예제 #2
0
void socfpga_init_ocram_ecc(void)
{
	struct device_node *np;
	const __be32 *prop;
	u32 ocr_edac_addr, iram_addr, len;
	void __iomem  *mapped_ocr_edac_addr;
	size_t size;
	struct gen_pool *gp;

	if (of_machine_is_compatible("altr,socfpga-arria10")) {
		if (socfpga_init_arria10_ocram_ecc() == 0)
			pr_alert("SOCFPGA: Success Initializing OCRAM ECC for Arria10");
		return;
	}

	np = of_find_compatible_node(NULL, NULL, "altr,ocram-edac");
	if (!np) {
		pr_err("SOCFPGA: Unable to find altr,ocram-edac in dtb\n");
		return;
	}

	prop = of_get_property(np, "reg", &size);
	ocr_edac_addr = be32_to_cpup(prop++);
	len = be32_to_cpup(prop);
	if (!prop || size < sizeof(*prop)) {
		pr_err("SOCFPGA: Unable to find OCRAM ECC mapping in dtb\n");
		return;
	}

	gp = of_gen_pool_get(np, "iram", 0);
	if (!gp) {
		pr_err("SOCFPGA: OCRAM cannot find gen pool\n");
		return;
	}

	np = of_find_compatible_node(NULL, NULL, "mmio-sram");
	if (!np) {
		pr_err("SOCFPGA: Unable to find mmio-sram in dtb\n");
		return;
	}
	/* Determine the OCRAM address and size */
	prop = of_get_property(np, "reg", &size);
	iram_addr = be32_to_cpup(prop++);
	len = be32_to_cpup(prop);

	if (!prop || size < sizeof(*prop)) {
		pr_err("SOCFPGA: Unable to find OCRAM mapping in dtb\n");
		return;
	}

	iram_addr = gen_pool_alloc(gp, len);
	if (iram_addr == 0) {
		pr_err("SOCFPGA: cannot alloc from gen pool\n");
		return;
	}

	memset((void *)iram_addr, 0, len);

	mapped_ocr_edac_addr = ioremap(ocr_edac_addr, 4);

	gen_pool_free(gp, iram_addr, len);

	/* Clear any pending OCRAM ECC interrupts, then enable ECC */
	writel(0x18, mapped_ocr_edac_addr);
	writel(0x19, mapped_ocr_edac_addr);

	iounmap(mapped_ocr_edac_addr);

	pr_alert("SOCFPGA: Success Initializing OCRAM");

	return;
}