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(); }
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; }