+// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2017 Intel Corporation <www.intel.com>
- *
- * SPDX-License-Identifier: GPL-2.0
*/
#include <common.h>
#define DDR_REG_CORE2SEQ 0xFFD05078
#define DDR_READ_LATENCY_DELAY 40
#define DDR_SIZE_2GB_HEX 0x80000000
-#define DDR_MAX_TRIES 0x00100000
#define IO48_MMR_DRAMSTS 0xFFCFA0EC
#define IO48_MMR_NIOS2_RESERVE0 0xFFCFA110
return 0;
}
-/* Check whether SDRAM is successfully Calibrated */
-static int is_sdram_cal_success(void)
-{
- return readl(&socfpga_ecc_hmc_base->ddrcalstat);
-}
-
-static unsigned char ddr_get_bit(u32 ereg, unsigned char bit)
-{
- u32 reg = readl(ereg);
-
- return (reg & BIT(bit)) ? 1 : 0;
-}
-
-static unsigned char ddr_wait_bit(u32 ereg, u32 bit,
- u32 expected, u32 timeout_usec)
-{
- u32 tmr;
-
- for (tmr = 0; tmr < timeout_usec; tmr += 100) {
- udelay(100);
- WATCHDOG_RESET();
- if (ddr_get_bit(ereg, bit) == expected)
- return 0;
- }
-
- return 1;
-}
-
static int emif_clear(void)
{
- u32 i = DDR_MAX_TRIES;
- u8 ret = 0;
-
writel(0, DDR_REG_CORE2SEQ);
- do {
- ret = !wait_for_bit_le32((u32 *)DDR_REG_SEQ2CORE,
- SEQ2CORE_MASK, 1, 50, 0);
- } while (ret && (--i > 0));
-
- return !i;
+ return wait_for_bit_le32((u32 *)DDR_REG_SEQ2CORE,
+ SEQ2CORE_MASK, 0, 1000, 0);
}
static int emif_reset(void)
{
u32 c2s, s2c;
+ int ret;
c2s = readl(DDR_REG_CORE2SEQ);
s2c = readl(DDR_REG_SEQ2CORE);
readl(IO48_MMR_NIOS2_RESERVE2),
readl(IO48_MMR_DRAMSTS));
- if ((s2c & SEQ2CORE_MASK) && emif_clear()) {
- debug("failed emif_clear()\n");
- return -EPERM;
+ if (s2c & SEQ2CORE_MASK) {
+ ret = emif_clear();
+ if (ret) {
+ debug("failed emif_clear()\n");
+ return -EPERM;
+ }
}
writel(CORE2SEQ_INT_REQ, DDR_REG_CORE2SEQ);
- if (ddr_wait_bit(DDR_REG_SEQ2CORE, SEQ2CORE_INT_RESP_BIT, 0, 1000000)) {
+ ret = wait_for_bit_le32((u32 *)DDR_REG_SEQ2CORE,
+ SEQ2CORE_INT_RESP_BIT, false, 1000, false);
+ if (ret) {
debug("emif_reset failed to see interrupt acknowledge\n");
- return -EPERM;
- } else {
- debug("emif_reset interrupt acknowledged\n");
+ emif_clear();
+ return ret;
}
- if (emif_clear()) {
+ mdelay(1);
+
+ ret = emif_clear();
+ if (ret) {
debug("emif_clear() failed\n");
return -EPERM;
}
static int ddr_setup(void)
{
- int i, j, ddr_setup_complete = 0;
+ int i, ret;
+
+ /* Try 32 times to do a calibration */
+ for (i = 0; i < 32; i++) {
+ mdelay(500);
+ ret = wait_for_bit_le32(&socfpga_ecc_hmc_base->ddrcalstat,
+ BIT(0), true, 500, false);
+ if (!ret)
+ return 0;
- /* Try 3 times to do a calibration */
- for (i = 0; (i < 3) && !ddr_setup_complete; i++) {
- WATCHDOG_RESET();
+ ret = emif_reset();
+ if (ret)
+ puts("Error: Failed to reset EMIF\n");
+ }
- /* A delay to wait for calibration bit to set */
- for (j = 0; (j < 10) && !ddr_setup_complete; j++) {
- mdelay(500);
- ddr_setup_complete = is_sdram_cal_success();
- }
+ puts("Error: Could Not Calibrate SDRAM\n");
+ return -EPERM;
+}
- if (!ddr_setup_complete)
- if (emif_reset())
- puts("Error: Failed to reset EMIF\n");
- }
+static int sdram_is_ecc_enabled(void)
+{
+ return !!(readl(&socfpga_ecc_hmc_base->eccctrl) &
+ ALT_ECC_HMC_OCP_ECCCTL_ECC_EN_SET_MSK);
+}
- /* After 3 times trying calibration */
- if (!ddr_setup_complete) {
- puts("Error: Could Not Calibrate SDRAM\n");
- return -EPERM;
- }
+/* Initialize SDRAM ECC bits to avoid false DBE */
+static void sdram_init_ecc_bits(u32 size)
+{
+ icache_enable();
- return 0;
+ memset(0, 0, 0x8000);
+ gd->arch.tlb_addr = 0x4000;
+ gd->arch.tlb_size = PGTABLE_SIZE;
+
+ dcache_enable();
+
+ printf("DDRCAL: Scrubbing ECC RAM (%i MiB).\n", size >> 20);
+ memset((void *)0x8000, 0, size - 0x8000);
+ flush_dcache_all();
+ printf("DDRCAL: Scrubbing ECC RAM done.\n");
+ dcache_disable();
}
/* Function to startup the SDRAM*/
size *= (2 << (readl(&socfpga_ecc_hmc_base->ddrioctrl) &
ALT_ECC_HMC_OCP_DDRIOCTRL_IO_SIZE_MSK));
- debug("SDRAM size=%llu", size);
+ debug("SDRAM size=%llu\n", size);
return size;
}
* bit[9:6] = Minor Release #
* bit[14:10] = Major Release #
*/
- if ((socfpga_io48_mmr_base->niosreserve1 >> 6) & 0x1FF) {
+ if ((readl(&socfpga_io48_mmr_base->niosreserve1) >> 6) & 0x1FF) {
update_value = readl(&socfpga_io48_mmr_base->niosreserve0);
writel(((update_value & 0xFF) >> 5),
&socfpga_ecc_hmc_base->ddrioctrl);
caltim0_cfg_act_to_rdwr -
(ctrlcfg0_cfg_ctrl_burst_len >> 2));
- io48_value = ((((socfpga_io48_mmr_base->dramtiming0 &
+ io48_value = ((((readl(&socfpga_io48_mmr_base->dramtiming0) &
ALT_IO48_DRAMTIME_MEM_READ_LATENCY_MASK) + 2 + 15 +
(ctrlcfg0_cfg_ctrl_burst_len >> 1)) >> 1) -
/* Up to here was in memory cycles so divide by 2 */
&socfpga_noc_ddr_scheduler_base->ddr_t_main_scheduler_ddrmode);
/* Configure the read latency [0xFFD12414] */
- writel(((socfpga_io48_mmr_base->dramtiming0 &
+ writel(((readl(&socfpga_io48_mmr_base->dramtiming0) &
ALT_IO48_DRAMTIME_MEM_READ_LATENCY_MASK) >> 1) +
DDR_READ_LATENCY_DELAY,
&socfpga_noc_ddr_scheduler_base->
if (of_sdram_firewall_setup(gd->fdt_blob))
puts("FW: Error Configuring Firewall\n");
- return 0;
-}
-
-void dram_bank_mmu_setup(int bank)
-{
- bd_t *bd = gd->bd;
- int i;
-
- debug("%s: bank: %d\n", __func__, bank);
- for (i = bd->bi_dram[bank].start >> 20;
- i < (bd->bi_dram[bank].start + bd->bi_dram[bank].size) >> 20;
- i++) {
-#if defined(CONFIG_SYS_ARM_CACHE_WRITETHROUGH)
- set_section_dcache(i, DCACHE_WRITETHROUGH);
-#else
- set_section_dcache(i, DCACHE_WRITEBACK);
-#endif
- }
+ if (sdram_is_ecc_enabled())
+ sdram_init_ecc_bits(gd->ram_size);
- /* same as above but just that we would want cacheable for ocram too */
- i = CONFIG_SYS_INIT_RAM_ADDR >> 20;
-#if defined(CONFIG_SYS_ARM_CACHE_WRITETHROUGH)
- set_section_dcache(i, DCACHE_WRITETHROUGH);
-#else
- set_section_dcache(i, DCACHE_WRITEBACK);
-#endif
+ return 0;
}