Merge branch 'master' of git://git.denx.de/u-boot-socfpga
- Gen 5 and Watchdog fixes
This commit is contained in:
commit
457faef262
@ -56,3 +56,7 @@
|
||||
&portc {
|
||||
bank-name = "portc";
|
||||
};
|
||||
|
||||
&watchdog0 {
|
||||
u-boot,dm-pre-reloc;
|
||||
};
|
||||
|
@ -31,3 +31,7 @@
|
||||
&sysmgr {
|
||||
u-boot,dm-pre-reloc;
|
||||
};
|
||||
|
||||
&watchdog0 {
|
||||
u-boot,dm-pre-reloc;
|
||||
};
|
||||
|
@ -146,24 +146,51 @@ struct socfpga_sdram_rw_mgr_config {
|
||||
u8 lfsr_wr_rd_dm_bank_0_nop;
|
||||
u8 lfsr_wr_rd_dm_bank_0_wait;
|
||||
u8 lfsr_wr_rd_dm_bank_0_wl_1;
|
||||
u8 mrs0_dll_reset;
|
||||
u8 mrs0_dll_reset_mirr;
|
||||
u8 mrs0_user;
|
||||
u8 mrs0_user_mirr;
|
||||
u8 mrs1;
|
||||
union {
|
||||
u8 mrs0_dll_reset;
|
||||
u8 mr_dll_reset;
|
||||
};
|
||||
union {
|
||||
u8 mrs0_dll_reset_mirr;
|
||||
u8 emr_ocd_enable;
|
||||
};
|
||||
union {
|
||||
u8 mrs0_user;
|
||||
u8 mr_user;
|
||||
};
|
||||
union {
|
||||
u8 mrs0_user_mirr;
|
||||
u8 mr_calib;
|
||||
};
|
||||
union {
|
||||
u8 mrs1;
|
||||
u8 emr;
|
||||
};
|
||||
union {
|
||||
u8 mrs2;
|
||||
u8 emr2;
|
||||
};
|
||||
union {
|
||||
u8 mrs3;
|
||||
u8 emr3;
|
||||
};
|
||||
u8 mrs1_mirr;
|
||||
u8 mrs2;
|
||||
u8 mrs2_mirr;
|
||||
u8 mrs3;
|
||||
u8 mrs3_mirr;
|
||||
u8 precharge_all;
|
||||
u8 read_b2b;
|
||||
u8 read_b2b_wait1;
|
||||
u8 read_b2b_wait2;
|
||||
u8 refresh_all;
|
||||
union {
|
||||
u8 refresh;
|
||||
u8 refresh_all;
|
||||
};
|
||||
u8 rreturn;
|
||||
u8 sgle_read;
|
||||
u8 zqcl;
|
||||
union {
|
||||
u8 zqcl;
|
||||
u8 nop;
|
||||
};
|
||||
|
||||
u8 true_mem_data_mask_width;
|
||||
u8 mem_address_mirroring;
|
||||
@ -199,6 +226,7 @@ struct socfpga_sdram_io_config {
|
||||
|
||||
struct socfpga_sdram_misc_config {
|
||||
u32 reg_file_init_seq_signature;
|
||||
u16 afi_clk_freq;
|
||||
u8 afi_rate_ratio;
|
||||
u8 calib_lfifo_offset;
|
||||
u8 calib_vfifo_offset;
|
||||
|
File diff suppressed because one or more lines are too long
@ -138,10 +138,7 @@ void board_init_f(ulong dummy)
|
||||
debug("Reset init failed: %d\n", ret);
|
||||
|
||||
#ifdef CONFIG_SPL_NAND_DENALI
|
||||
struct socfpga_reset_manager *reset_manager_base =
|
||||
(struct socfpga_reset_manager *)SOCFPGA_RSTMGR_ADDRESS;
|
||||
|
||||
clrbits_le32(&reset_manager_base->per_mod_reset, BIT(4));
|
||||
clrbits_le32(SOCFPGA_RSTMGR_ADDRESS + RSTMGR_GEN5_PERMODRST, BIT(4));
|
||||
#endif
|
||||
|
||||
/* enable console uart printing */
|
||||
|
@ -80,13 +80,15 @@ static const struct socfpga_sdram_config sdram_config = {
|
||||
SDR_CTRLGRP_DRAMODT_READ_LSB) |
|
||||
(CONFIG_HPS_SDR_CTRLCFG_DRAMODT_WRITE <<
|
||||
SDR_CTRLGRP_DRAMODT_WRITE_LSB),
|
||||
#if (CONFIG_HPS_SDR_CTRLCFG_CTRLCFG_MEMTYPE == 2) /* DDR3 */
|
||||
.extratime1 =
|
||||
(CONFIG_HPS_SDR_CTRLCFG_EXTRATIME1_CFG_EXTRA_CTL_CLK_RD_TO_WR <<
|
||||
SDR_CTRLGRP_EXTRATIME1_RD_TO_WR_LSB) |
|
||||
(CONFIG_HPS_SDR_CTRLCFG_EXTRATIME1_CFG_EXTRA_CTL_CLK_RD_TO_WR_BC <<
|
||||
SDR_CTRLGRP_EXTRATIME1_RD_TO_WR_BC_LSB) |
|
||||
(CONFIG_HPS_SDR_CTRLCFG_EXTRATIME1_CFG_EXTRA_CTL_CLK_RD_TO_WR_DIFF_CHIP <<
|
||||
SDR_CTRLGRP_EXTRATIME1_RD_TO_WR_DIFF_LSB),
|
||||
(CONFIG_HPS_SDR_CTRLCFG_EXTRATIME1_CFG_EXTRA_CTL_CLK_RD_TO_WR <<
|
||||
SDR_CTRLGRP_EXTRATIME1_RD_TO_WR_LSB) |
|
||||
(CONFIG_HPS_SDR_CTRLCFG_EXTRATIME1_CFG_EXTRA_CTL_CLK_RD_TO_WR_BC <<
|
||||
SDR_CTRLGRP_EXTRATIME1_RD_TO_WR_BC_LSB) |
|
||||
(CONFIG_HPS_SDR_CTRLCFG_EXTRATIME1_CFG_EXTRA_CTL_CLK_RD_TO_WR_DIFF_CHIP <<
|
||||
SDR_CTRLGRP_EXTRATIME1_RD_TO_WR_DIFF_LSB),
|
||||
#endif
|
||||
.dram_addrw =
|
||||
(CONFIG_HPS_SDR_CTRLCFG_DRAMADDRW_COLBITS <<
|
||||
SDR_CTRLGRP_DRAMADDRW_COLBITS_LSB) |
|
||||
@ -190,7 +192,6 @@ static const struct socfpga_sdram_rw_mgr_config rw_mgr_config = {
|
||||
.activate_0_and_1 = RW_MGR_ACTIVATE_0_AND_1,
|
||||
.activate_0_and_1_wait1 = RW_MGR_ACTIVATE_0_AND_1_WAIT1,
|
||||
.activate_0_and_1_wait2 = RW_MGR_ACTIVATE_0_AND_1_WAIT2,
|
||||
.activate_1 = RW_MGR_ACTIVATE_1,
|
||||
.clear_dqs_enable = RW_MGR_CLEAR_DQS_ENABLE,
|
||||
.guaranteed_read = RW_MGR_GUARANTEED_READ,
|
||||
.guaranteed_read_cont = RW_MGR_GUARANTEED_READ_CONT,
|
||||
@ -199,11 +200,41 @@ static const struct socfpga_sdram_rw_mgr_config rw_mgr_config = {
|
||||
.guaranteed_write_wait1 = RW_MGR_GUARANTEED_WRITE_WAIT1,
|
||||
.guaranteed_write_wait2 = RW_MGR_GUARANTEED_WRITE_WAIT2,
|
||||
.guaranteed_write_wait3 = RW_MGR_GUARANTEED_WRITE_WAIT3,
|
||||
.idle = RW_MGR_IDLE,
|
||||
.idle_loop1 = RW_MGR_IDLE_LOOP1,
|
||||
.idle_loop2 = RW_MGR_IDLE_LOOP2,
|
||||
#if (CONFIG_HPS_SDR_CTRLCFG_CTRLCFG_MEMTYPE == 1) /* DDR2 */
|
||||
.emr = RW_MGR_EMR,
|
||||
.emr2 = RW_MGR_EMR2,
|
||||
.emr3 = RW_MGR_EMR3,
|
||||
.init_reset_0_cke_0 = RW_MGR_INIT_CKE_0,
|
||||
.nop = RW_MGR_NOP,
|
||||
.refresh = RW_MGR_REFRESH,
|
||||
.mr_calib = RW_MGR_MR_CALIB,
|
||||
.mr_user = RW_MGR_MR_USER,
|
||||
.mr_dll_reset = RW_MGR_MR_DLL_RESET,
|
||||
.emr_ocd_enable = RW_MGR_EMR_OCD_ENABLE,
|
||||
#elif (CONFIG_HPS_SDR_CTRLCFG_CTRLCFG_MEMTYPE == 2) /* DDR3 */
|
||||
.activate_1 = RW_MGR_ACTIVATE_1,
|
||||
.idle = RW_MGR_IDLE,
|
||||
.init_reset_0_cke_0 = RW_MGR_INIT_RESET_0_CKE_0,
|
||||
.init_reset_1_cke_0 = RW_MGR_INIT_RESET_1_CKE_0,
|
||||
.mrs1 = RW_MGR_MRS1,
|
||||
.mrs1_mirr = RW_MGR_MRS1_MIRR,
|
||||
.mrs2 = RW_MGR_MRS2,
|
||||
.mrs2_mirr = RW_MGR_MRS2_MIRR,
|
||||
.mrs3 = RW_MGR_MRS3,
|
||||
.mrs3_mirr = RW_MGR_MRS3_MIRR,
|
||||
.refresh_all = RW_MGR_REFRESH_ALL,
|
||||
.rreturn = RW_MGR_RETURN,
|
||||
.sgle_read = RW_MGR_SGLE_READ,
|
||||
.zqcl = RW_MGR_ZQCL,
|
||||
.mrs0_dll_reset = RW_MGR_MRS0_DLL_RESET,
|
||||
.mrs0_dll_reset_mirr = RW_MGR_MRS0_DLL_RESET_MIRR,
|
||||
.mrs0_user = RW_MGR_MRS0_USER,
|
||||
.mrs0_user_mirr = RW_MGR_MRS0_USER_MIRR,
|
||||
#else
|
||||
#error LPDDR2 and other DRAM types are not yet supported
|
||||
#endif
|
||||
.lfsr_wr_rd_bank_0 = RW_MGR_LFSR_WR_RD_BANK_0,
|
||||
.lfsr_wr_rd_bank_0_data = RW_MGR_LFSR_WR_RD_BANK_0_DATA,
|
||||
.lfsr_wr_rd_bank_0_dqs = RW_MGR_LFSR_WR_RD_BANK_0_DQS,
|
||||
@ -216,24 +247,10 @@ static const struct socfpga_sdram_rw_mgr_config rw_mgr_config = {
|
||||
.lfsr_wr_rd_dm_bank_0_nop = RW_MGR_LFSR_WR_RD_DM_BANK_0_NOP,
|
||||
.lfsr_wr_rd_dm_bank_0_wait = RW_MGR_LFSR_WR_RD_DM_BANK_0_WAIT,
|
||||
.lfsr_wr_rd_dm_bank_0_wl_1 = RW_MGR_LFSR_WR_RD_DM_BANK_0_WL_1,
|
||||
.mrs0_dll_reset = RW_MGR_MRS0_DLL_RESET,
|
||||
.mrs0_dll_reset_mirr = RW_MGR_MRS0_DLL_RESET_MIRR,
|
||||
.mrs0_user = RW_MGR_MRS0_USER,
|
||||
.mrs0_user_mirr = RW_MGR_MRS0_USER_MIRR,
|
||||
.mrs1 = RW_MGR_MRS1,
|
||||
.mrs1_mirr = RW_MGR_MRS1_MIRR,
|
||||
.mrs2 = RW_MGR_MRS2,
|
||||
.mrs2_mirr = RW_MGR_MRS2_MIRR,
|
||||
.mrs3 = RW_MGR_MRS3,
|
||||
.mrs3_mirr = RW_MGR_MRS3_MIRR,
|
||||
.precharge_all = RW_MGR_PRECHARGE_ALL,
|
||||
.read_b2b = RW_MGR_READ_B2B,
|
||||
.read_b2b_wait1 = RW_MGR_READ_B2B_WAIT1,
|
||||
.read_b2b_wait2 = RW_MGR_READ_B2B_WAIT2,
|
||||
.refresh_all = RW_MGR_REFRESH_ALL,
|
||||
.rreturn = RW_MGR_RETURN,
|
||||
.sgle_read = RW_MGR_SGLE_READ,
|
||||
.zqcl = RW_MGR_ZQCL,
|
||||
|
||||
.true_mem_data_mask_width = RW_MGR_TRUE_MEM_DATA_MASK_WIDTH,
|
||||
.mem_address_mirroring = RW_MGR_MEM_ADDRESS_MIRRORING,
|
||||
@ -270,6 +287,9 @@ static const struct socfpga_sdram_io_config io_config = {
|
||||
};
|
||||
|
||||
static const struct socfpga_sdram_misc_config misc_config = {
|
||||
#if (CONFIG_HPS_SDR_CTRLCFG_CTRLCFG_MEMTYPE == 1) /* DDR2 */
|
||||
.afi_clk_freq = AFI_CLK_FREQ,
|
||||
#endif
|
||||
.afi_rate_ratio = AFI_RATE_RATIO,
|
||||
.calib_lfifo_offset = CALIB_LFIFO_OFFSET,
|
||||
.calib_vfifo_offset = CALIB_VFIFO_OFFSET,
|
||||
|
@ -58,4 +58,6 @@ CONFIG_USB=y
|
||||
CONFIG_DM_USB=y
|
||||
CONFIG_USB_DWC2=y
|
||||
CONFIG_USB_STORAGE=y
|
||||
CONFIG_DESIGNWARE_WATCHDOG=y
|
||||
CONFIG_WDT=y
|
||||
# CONFIG_SPL_USE_TINY_PRINTF is not set
|
||||
|
@ -96,4 +96,5 @@ CONFIG_USB_GADGET_VENDOR_NUM=0x0525
|
||||
CONFIG_USB_GADGET_PRODUCT_NUM=0xa4a5
|
||||
CONFIG_USB_GADGET_DWC2_OTG=y
|
||||
CONFIG_USB_GADGET_DOWNLOAD=y
|
||||
# CONFIG_SPL_WDT is not set
|
||||
CONFIG_DESIGNWARE_WATCHDOG=y
|
||||
CONFIG_WDT=y
|
||||
|
@ -434,8 +434,10 @@ static void sdr_load_regs(struct socfpga_sdr_ctrl *sdr_ctrl,
|
||||
debug("Configuring DRAMODT\n");
|
||||
writel(cfg->dram_odt, &sdr_ctrl->dram_odt);
|
||||
|
||||
debug("Configuring EXTRATIME1\n");
|
||||
writel(cfg->extratime1, &sdr_ctrl->extratime1);
|
||||
if (dram_is_ddr(3)) {
|
||||
debug("Configuring EXTRATIME1\n");
|
||||
writel(cfg->extratime1, &sdr_ctrl->extratime1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/sdram.h>
|
||||
#include <errno.h>
|
||||
#include <hang.h>
|
||||
#include "sequencer.h"
|
||||
|
||||
static const struct socfpga_sdr_rw_load_manager *sdr_rw_load_mgr_regs =
|
||||
@ -54,6 +55,21 @@ static const struct socfpga_sdr_ctrl *sdr_ctrl =
|
||||
#define SKIP_DELAY_LOOP_VALUE_OR_ZERO(non_skip_value) \
|
||||
((non_skip_value) & seq->skip_delay_mask)
|
||||
|
||||
bool dram_is_ddr(const u8 ddr)
|
||||
{
|
||||
const struct socfpga_sdram_config *cfg = socfpga_get_sdram_config();
|
||||
const u8 type = (cfg->ctrl_cfg >> SDR_CTRLGRP_CTRLCFG_MEMTYPE_LSB) &
|
||||
SDR_CTRLGRP_CTRLCFG_MEMTYPE_MASK;
|
||||
|
||||
if (ddr == 2 && type == 1) /* DDR2 */
|
||||
return true;
|
||||
|
||||
if (ddr == 3 && type == 2) /* DDR3 */
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void set_failing_group_stage(struct socfpga_sdrseq *seq,
|
||||
u32 group, u32 stage, u32 substage)
|
||||
{
|
||||
@ -164,6 +180,8 @@ static void set_rank_and_odt_mask(struct socfpga_sdrseq *seq,
|
||||
*/
|
||||
odt_mask_0 = 0x3 & ~(1 << rank);
|
||||
odt_mask_1 = 0x3;
|
||||
if (dram_is_ddr(2))
|
||||
odt_mask_1 &= ~(1 << rank);
|
||||
} else {
|
||||
/*
|
||||
* - Single-Slot , Dual-Rank (2 CS per DIMM)
|
||||
@ -176,10 +194,11 @@ static void set_rank_and_odt_mask(struct socfpga_sdrseq *seq,
|
||||
}
|
||||
break;
|
||||
case 4: /* 4 Ranks */
|
||||
/* Read:
|
||||
/*
|
||||
* DDR3 Read, DDR2 Read/Write:
|
||||
* ----------+-----------------------+
|
||||
* | ODT |
|
||||
* Read From +-----------------------+
|
||||
* +-----------------------+
|
||||
* Rank | 3 | 2 | 1 | 0 |
|
||||
* ----------+-----+-----+-----+-----+
|
||||
* 0 | 0 | 1 | 0 | 0 |
|
||||
@ -188,7 +207,7 @@ static void set_rank_and_odt_mask(struct socfpga_sdrseq *seq,
|
||||
* 3 | 0 | 0 | 1 | 0 |
|
||||
* ----------+-----+-----+-----+-----+
|
||||
*
|
||||
* Write:
|
||||
* DDR3 Write:
|
||||
* ----------+-----------------------+
|
||||
* | ODT |
|
||||
* Write To +-----------------------+
|
||||
@ -203,19 +222,31 @@ static void set_rank_and_odt_mask(struct socfpga_sdrseq *seq,
|
||||
switch (rank) {
|
||||
case 0:
|
||||
odt_mask_0 = 0x4;
|
||||
odt_mask_1 = 0x5;
|
||||
if (dram_is_ddr(2))
|
||||
odt_mask_1 = 0x4;
|
||||
else if (dram_is_ddr(3))
|
||||
odt_mask_1 = 0x5;
|
||||
break;
|
||||
case 1:
|
||||
odt_mask_0 = 0x8;
|
||||
odt_mask_1 = 0xA;
|
||||
if (dram_is_ddr(2))
|
||||
odt_mask_1 = 0x8;
|
||||
else if (dram_is_ddr(3))
|
||||
odt_mask_1 = 0xA;
|
||||
break;
|
||||
case 2:
|
||||
odt_mask_0 = 0x1;
|
||||
odt_mask_1 = 0x5;
|
||||
if (dram_is_ddr(2))
|
||||
odt_mask_1 = 0x1;
|
||||
else if (dram_is_ddr(3))
|
||||
odt_mask_1 = 0x5;
|
||||
break;
|
||||
case 3:
|
||||
odt_mask_0 = 0x2;
|
||||
odt_mask_1 = 0xA;
|
||||
if (dram_is_ddr(2))
|
||||
odt_mask_1 = 0x2;
|
||||
else if (dram_is_ddr(3))
|
||||
odt_mask_1 = 0xA;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@ -839,6 +870,12 @@ static void delay_for_n_mem_clocks(struct socfpga_sdrseq *seq,
|
||||
debug("%s:%d clocks=%u ... end\n", __func__, __LINE__, clocks);
|
||||
}
|
||||
|
||||
static void delay_for_n_ns(struct socfpga_sdrseq *seq, const u32 ns)
|
||||
{
|
||||
delay_for_n_mem_clocks(seq, (ns * seq->misccfg->afi_clk_freq *
|
||||
seq->misccfg->afi_rate_ratio) / 1000);
|
||||
}
|
||||
|
||||
/**
|
||||
* rw_mgr_mem_init_load_regs() - Load instruction registers
|
||||
* @cntr0: Counter 0 value
|
||||
@ -872,14 +909,59 @@ static void rw_mgr_mem_init_load_regs(struct socfpga_sdrseq *seq,
|
||||
}
|
||||
|
||||
/**
|
||||
* rw_mgr_mem_load_user() - Load user calibration values
|
||||
* rw_mgr_mem_load_user_ddr2() - Load user calibration values for DDR2
|
||||
* @handoff: Indicate whether this is initialization or handoff phase
|
||||
*
|
||||
* Load user calibration values and optionally precharge the banks.
|
||||
*/
|
||||
static void rw_mgr_mem_load_user_ddr2(struct socfpga_sdrseq *seq,
|
||||
const int handoff)
|
||||
{
|
||||
u32 grpaddr = SDR_PHYGRP_RWMGRGRP_ADDRESS |
|
||||
RW_MGR_RUN_SINGLE_GROUP_OFFSET;
|
||||
u32 r;
|
||||
|
||||
for (r = 0; r < seq->rwcfg->mem_number_of_ranks; r++) {
|
||||
/* set rank */
|
||||
set_rank_and_odt_mask(seq, r, RW_MGR_ODT_MODE_OFF);
|
||||
|
||||
/* precharge all banks ... */
|
||||
writel(seq->rwcfg->precharge_all, grpaddr);
|
||||
|
||||
writel(seq->rwcfg->emr2, grpaddr);
|
||||
writel(seq->rwcfg->emr3, grpaddr);
|
||||
writel(seq->rwcfg->emr, grpaddr);
|
||||
|
||||
if (handoff) {
|
||||
writel(seq->rwcfg->mr_user, grpaddr);
|
||||
continue;
|
||||
}
|
||||
|
||||
writel(seq->rwcfg->mr_dll_reset, grpaddr);
|
||||
|
||||
writel(seq->rwcfg->precharge_all, grpaddr);
|
||||
|
||||
writel(seq->rwcfg->refresh, grpaddr);
|
||||
delay_for_n_ns(seq, 200);
|
||||
writel(seq->rwcfg->refresh, grpaddr);
|
||||
delay_for_n_ns(seq, 200);
|
||||
|
||||
writel(seq->rwcfg->mr_calib, grpaddr);
|
||||
writel(/*seq->rwcfg->*/0x0b, grpaddr); // EMR_OCD_ENABLE
|
||||
writel(seq->rwcfg->emr, grpaddr);
|
||||
delay_for_n_mem_clocks(seq, 200);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* rw_mgr_mem_load_user_ddr3() - Load user calibration values
|
||||
* @fin1: Final instruction 1
|
||||
* @fin2: Final instruction 2
|
||||
* @precharge: If 1, precharge the banks at the end
|
||||
*
|
||||
* Load user calibration values and optionally precharge the banks.
|
||||
*/
|
||||
static void rw_mgr_mem_load_user(struct socfpga_sdrseq *seq,
|
||||
static void rw_mgr_mem_load_user_ddr3(struct socfpga_sdrseq *seq,
|
||||
const u32 fin1, const u32 fin2,
|
||||
const int precharge)
|
||||
{
|
||||
@ -935,6 +1017,25 @@ static void rw_mgr_mem_load_user(struct socfpga_sdrseq *seq,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* rw_mgr_mem_load_user() - Load user calibration values
|
||||
* @fin1: Final instruction 1
|
||||
* @fin2: Final instruction 2
|
||||
* @precharge: If 1, precharge the banks at the end
|
||||
*
|
||||
* Load user calibration values and optionally precharge the banks.
|
||||
*/
|
||||
static void rw_mgr_mem_load_user(struct socfpga_sdrseq *seq,
|
||||
const u32 fin1, const u32 fin2,
|
||||
const int precharge)
|
||||
{
|
||||
if (dram_is_ddr(2))
|
||||
rw_mgr_mem_load_user_ddr2(seq, precharge);
|
||||
else if (dram_is_ddr(3))
|
||||
rw_mgr_mem_load_user_ddr3(seq, fin1, fin2, precharge);
|
||||
else
|
||||
hang();
|
||||
}
|
||||
/**
|
||||
* rw_mgr_mem_initialize() - Initialize RW Manager
|
||||
*
|
||||
@ -945,8 +1046,10 @@ static void rw_mgr_mem_initialize(struct socfpga_sdrseq *seq)
|
||||
debug("%s:%d\n", __func__, __LINE__);
|
||||
|
||||
/* The reset / cke part of initialization is broadcasted to all ranks */
|
||||
writel(RW_MGR_RANK_ALL, SDR_PHYGRP_RWMGRGRP_ADDRESS |
|
||||
RW_MGR_SET_CS_AND_ODT_MASK_OFFSET);
|
||||
if (dram_is_ddr(3)) {
|
||||
writel(RW_MGR_RANK_ALL, SDR_PHYGRP_RWMGRGRP_ADDRESS |
|
||||
RW_MGR_SET_CS_AND_ODT_MASK_OFFSET);
|
||||
}
|
||||
|
||||
/*
|
||||
* Here's how you load register for a loop
|
||||
@ -979,29 +1082,38 @@ static void rw_mgr_mem_initialize(struct socfpga_sdrseq *seq)
|
||||
/* Indicate that memory is stable. */
|
||||
writel(1, &phy_mgr_cfg->reset_mem_stbl);
|
||||
|
||||
/*
|
||||
* transition the RESET to high
|
||||
* Wait for 500us
|
||||
*/
|
||||
if (dram_is_ddr(2)) {
|
||||
writel(seq->rwcfg->nop, SDR_PHYGRP_RWMGRGRP_ADDRESS |
|
||||
RW_MGR_RUN_SINGLE_GROUP_OFFSET);
|
||||
|
||||
/*
|
||||
* 500us @ 266MHz (3.75 ns) ~ 134000 clock cycles
|
||||
* If a and b are the number of iteration in 2 nested loops
|
||||
* it takes the following number of cycles to complete the operation
|
||||
* number_of_cycles = ((2 + n) * a + 2) * b
|
||||
* where n is the number of instruction in the inner loop
|
||||
* One possible solution is n = 2 , a = 131 , b = 256 => a = 83,
|
||||
* b = FF
|
||||
*/
|
||||
rw_mgr_mem_init_load_regs(seq, seq->misccfg->treset_cntr0_val,
|
||||
seq->misccfg->treset_cntr1_val,
|
||||
seq->misccfg->treset_cntr2_val,
|
||||
seq->rwcfg->init_reset_1_cke_0);
|
||||
/* Bring up clock enable. */
|
||||
|
||||
/* Bring up clock enable. */
|
||||
/* tXRP < 400 ck cycles */
|
||||
delay_for_n_ns(seq, 400);
|
||||
} else if (dram_is_ddr(3)) {
|
||||
/*
|
||||
* transition the RESET to high
|
||||
* Wait for 500us
|
||||
*/
|
||||
|
||||
/* tXRP < 250 ck cycles */
|
||||
delay_for_n_mem_clocks(seq, 250);
|
||||
/*
|
||||
* 500us @ 266MHz (3.75 ns) ~ 134000 clock cycles
|
||||
* If a and b are the number of iteration in 2 nested loops
|
||||
* it takes the following number of cycles to complete the
|
||||
* operation number_of_cycles = ((2 + n) * a + 2) * b
|
||||
* where n is the number of instruction in the inner loop
|
||||
* One possible solution is
|
||||
* n = 2 , a = 131 , b = 256 => a = 83, b = FF
|
||||
*/
|
||||
rw_mgr_mem_init_load_regs(seq, seq->misccfg->treset_cntr0_val,
|
||||
seq->misccfg->treset_cntr1_val,
|
||||
seq->misccfg->treset_cntr2_val,
|
||||
seq->rwcfg->init_reset_1_cke_0);
|
||||
/* Bring up clock enable. */
|
||||
|
||||
/* tXRP < 250 ck cycles */
|
||||
delay_for_n_mem_clocks(seq, 250);
|
||||
}
|
||||
|
||||
rw_mgr_mem_load_user(seq, seq->rwcfg->mrs0_dll_reset_mirr,
|
||||
seq->rwcfg->mrs0_dll_reset, 0);
|
||||
@ -3769,16 +3881,26 @@ static void initialize_tracking(struct socfpga_sdrseq *seq)
|
||||
&sdr_reg_file->delays);
|
||||
|
||||
/* mux delay */
|
||||
writel((seq->rwcfg->idle << 24) | (seq->rwcfg->activate_1 << 16) |
|
||||
(seq->rwcfg->sgle_read << 8) | (seq->rwcfg->precharge_all << 0),
|
||||
&sdr_reg_file->trk_rw_mgr_addr);
|
||||
if (dram_is_ddr(2)) {
|
||||
writel(0, &sdr_reg_file->trk_rw_mgr_addr);
|
||||
} else if (dram_is_ddr(3)) {
|
||||
writel((seq->rwcfg->idle << 24) |
|
||||
(seq->rwcfg->activate_1 << 16) |
|
||||
(seq->rwcfg->sgle_read << 8) |
|
||||
(seq->rwcfg->precharge_all << 0),
|
||||
&sdr_reg_file->trk_rw_mgr_addr);
|
||||
}
|
||||
|
||||
writel(seq->rwcfg->mem_if_read_dqs_width,
|
||||
&sdr_reg_file->trk_read_dqs_width);
|
||||
|
||||
/* trefi [7:0] */
|
||||
writel((seq->rwcfg->refresh_all << 24) | (1000 << 0),
|
||||
&sdr_reg_file->trk_rfsh);
|
||||
if (dram_is_ddr(2)) {
|
||||
writel(1000 << 0, &sdr_reg_file->trk_rfsh);
|
||||
} else if (dram_is_ddr(3)) {
|
||||
writel((seq->rwcfg->refresh_all << 24) | (1000 << 0),
|
||||
&sdr_reg_file->trk_rfsh);
|
||||
}
|
||||
}
|
||||
|
||||
int sdram_calibration_full(struct socfpga_sdr *sdr)
|
||||
|
@ -279,5 +279,6 @@ struct socfpga_sdrseq {
|
||||
};
|
||||
|
||||
int sdram_calibration_full(struct socfpga_sdr *sdr);
|
||||
bool dram_is_ddr(const u8 ddr);
|
||||
|
||||
#endif /* _SEQUENCER_H_ */
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include <dm/of_access.h>
|
||||
#include <env.h>
|
||||
#include <reset-uclass.h>
|
||||
#include <wait_bit.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/sizes.h>
|
||||
@ -80,7 +81,10 @@ static int socfpga_reset_deassert(struct reset_ctl *reset_ctl)
|
||||
int offset = id % (reg_width * BITS_PER_BYTE);
|
||||
|
||||
clrbits_le32(data->modrst_base + (bank * BANK_INCREMENT), BIT(offset));
|
||||
return 0;
|
||||
|
||||
return wait_for_bit_le32(data->modrst_base + (bank * BANK_INCREMENT),
|
||||
BIT(offset),
|
||||
false, 500, false);
|
||||
}
|
||||
|
||||
static int socfpga_reset_request(struct reset_ctl *reset_ctl)
|
||||
|
@ -45,6 +45,13 @@ config ULP_WATCHDOG
|
||||
help
|
||||
Say Y here to enable i.MX7ULP watchdog driver.
|
||||
|
||||
config DESIGNWARE_WATCHDOG
|
||||
bool "Designware watchdog timer support"
|
||||
select HW_WATCHDOG if !WDT
|
||||
help
|
||||
Enable this to support Designware Watchdog Timer IP, present e.g.
|
||||
on Altera SoCFPGA SoCs.
|
||||
|
||||
config WDT
|
||||
bool "Enable driver model for watchdog timer drivers"
|
||||
depends on DM
|
||||
|
@ -3,8 +3,11 @@
|
||||
* Copyright (C) 2013 Altera Corporation <www.altera.com>
|
||||
*/
|
||||
|
||||
#include <clk.h>
|
||||
#include <common.h>
|
||||
#include <watchdog.h>
|
||||
#include <dm.h>
|
||||
#include <reset.h>
|
||||
#include <wdt.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/utils.h>
|
||||
|
||||
@ -14,49 +17,52 @@
|
||||
|
||||
#define DW_WDT_CR_EN_OFFSET 0x00
|
||||
#define DW_WDT_CR_RMOD_OFFSET 0x01
|
||||
#define DW_WDT_CR_RMOD_VAL 0x00
|
||||
#define DW_WDT_CRR_RESTART_VAL 0x76
|
||||
|
||||
struct designware_wdt_priv {
|
||||
void __iomem *base;
|
||||
unsigned int clk_khz;
|
||||
};
|
||||
|
||||
/*
|
||||
* Set the watchdog time interval.
|
||||
* Counter is 32 bit.
|
||||
*/
|
||||
static int designware_wdt_settimeout(unsigned int timeout)
|
||||
static int designware_wdt_settimeout(void __iomem *base, unsigned int clk_khz,
|
||||
unsigned int timeout)
|
||||
{
|
||||
signed int i;
|
||||
|
||||
/* calculate the timeout range value */
|
||||
i = (log_2_n_round_up(timeout * CONFIG_DW_WDT_CLOCK_KHZ)) - 16;
|
||||
if (i > 15)
|
||||
i = 15;
|
||||
if (i < 0)
|
||||
i = 0;
|
||||
i = log_2_n_round_up(timeout * clk_khz) - 16;
|
||||
i = clamp(i, 0, 15);
|
||||
|
||||
writel(i | (i << 4), base + DW_WDT_TORR);
|
||||
|
||||
writel((i | (i << 4)), (CONFIG_DW_WDT_BASE + DW_WDT_TORR));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void designware_wdt_enable(void)
|
||||
static void designware_wdt_enable(void __iomem *base)
|
||||
{
|
||||
writel(((DW_WDT_CR_RMOD_VAL << DW_WDT_CR_RMOD_OFFSET) |
|
||||
(0x1 << DW_WDT_CR_EN_OFFSET)),
|
||||
(CONFIG_DW_WDT_BASE + DW_WDT_CR));
|
||||
writel(BIT(DW_WDT_CR_EN_OFFSET), base + DW_WDT_CR);
|
||||
}
|
||||
|
||||
static unsigned int designware_wdt_is_enabled(void)
|
||||
static unsigned int designware_wdt_is_enabled(void __iomem *base)
|
||||
{
|
||||
unsigned long val;
|
||||
val = readl((CONFIG_DW_WDT_BASE + DW_WDT_CR));
|
||||
return val & 0x1;
|
||||
return readl(base + DW_WDT_CR) & BIT(0);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_HW_WATCHDOG)
|
||||
static void designware_wdt_reset_common(void __iomem *base)
|
||||
{
|
||||
if (designware_wdt_is_enabled(base))
|
||||
/* restart the watchdog counter */
|
||||
writel(DW_WDT_CRR_RESTART_VAL, base + DW_WDT_CRR);
|
||||
}
|
||||
|
||||
#if !CONFIG_IS_ENABLED(WDT)
|
||||
void hw_watchdog_reset(void)
|
||||
{
|
||||
if (designware_wdt_is_enabled())
|
||||
/* restart the watchdog counter */
|
||||
writel(DW_WDT_CRR_RESTART_VAL,
|
||||
(CONFIG_DW_WDT_BASE + DW_WDT_CRR));
|
||||
designware_wdt_reset_common((void __iomem *)CONFIG_DW_WDT_BASE);
|
||||
}
|
||||
|
||||
void hw_watchdog_init(void)
|
||||
@ -64,10 +70,106 @@ void hw_watchdog_init(void)
|
||||
/* reset to disable the watchdog */
|
||||
hw_watchdog_reset();
|
||||
/* set timer in miliseconds */
|
||||
designware_wdt_settimeout(CONFIG_WATCHDOG_TIMEOUT_MSECS);
|
||||
designware_wdt_settimeout((void __iomem *)CONFIG_DW_WDT_BASE,
|
||||
CONFIG_DW_WDT_CLOCK_KHZ,
|
||||
CONFIG_WATCHDOG_TIMEOUT_MSECS);
|
||||
/* enable the watchdog */
|
||||
designware_wdt_enable();
|
||||
designware_wdt_enable((void __iomem *)CONFIG_DW_WDT_BASE);
|
||||
/* reset the watchdog */
|
||||
hw_watchdog_reset();
|
||||
}
|
||||
#else
|
||||
static int designware_wdt_reset(struct udevice *dev)
|
||||
{
|
||||
struct designware_wdt_priv *priv = dev_get_priv(dev);
|
||||
|
||||
designware_wdt_reset_common(priv->base);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int designware_wdt_stop(struct udevice *dev)
|
||||
{
|
||||
struct designware_wdt_priv *priv = dev_get_priv(dev);
|
||||
|
||||
designware_wdt_reset(dev);
|
||||
writel(0, priv->base + DW_WDT_CR);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int designware_wdt_start(struct udevice *dev, u64 timeout, ulong flags)
|
||||
{
|
||||
struct designware_wdt_priv *priv = dev_get_priv(dev);
|
||||
|
||||
designware_wdt_stop(dev);
|
||||
|
||||
/* set timer in miliseconds */
|
||||
designware_wdt_settimeout(priv->base, priv->clk_khz, timeout);
|
||||
|
||||
designware_wdt_enable(priv->base);
|
||||
|
||||
/* reset the watchdog */
|
||||
return designware_wdt_reset(dev);
|
||||
}
|
||||
|
||||
static int designware_wdt_probe(struct udevice *dev)
|
||||
{
|
||||
struct designware_wdt_priv *priv = dev_get_priv(dev);
|
||||
__maybe_unused int ret;
|
||||
|
||||
priv->base = dev_remap_addr(dev);
|
||||
if (!priv->base)
|
||||
return -EINVAL;
|
||||
|
||||
#if CONFIG_IS_ENABLED(CLK)
|
||||
struct clk clk;
|
||||
|
||||
ret = clk_get_by_index(dev, 0, &clk);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
priv->clk_khz = clk_get_rate(&clk);
|
||||
if (!priv->clk_khz)
|
||||
return -EINVAL;
|
||||
#else
|
||||
priv->clk_khz = CONFIG_DW_WDT_CLOCK_KHZ;
|
||||
#endif
|
||||
|
||||
#if CONFIG_IS_ENABLED(DM_RESET)
|
||||
struct reset_ctl_bulk resets;
|
||||
|
||||
ret = reset_get_bulk(dev, &resets);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = reset_deassert_bulk(&resets);
|
||||
if (ret)
|
||||
return ret;
|
||||
#endif
|
||||
|
||||
/* reset to disable the watchdog */
|
||||
return designware_wdt_stop(dev);
|
||||
}
|
||||
|
||||
static const struct wdt_ops designware_wdt_ops = {
|
||||
.start = designware_wdt_start,
|
||||
.reset = designware_wdt_reset,
|
||||
.stop = designware_wdt_stop,
|
||||
};
|
||||
|
||||
static const struct udevice_id designware_wdt_ids[] = {
|
||||
{ .compatible = "snps,dw-wdt"},
|
||||
{}
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(designware_wdt) = {
|
||||
.name = "designware_wdt",
|
||||
.id = UCLASS_WDT,
|
||||
.of_match = designware_wdt_ids,
|
||||
.priv_auto_alloc_size = sizeof(struct designware_wdt_priv),
|
||||
.probe = designware_wdt_probe,
|
||||
.ops = &designware_wdt_ops,
|
||||
.flags = DM_FLAG_PRE_RELOC,
|
||||
};
|
||||
#endif
|
||||
|
@ -104,11 +104,8 @@
|
||||
/*
|
||||
* L4 Watchdog
|
||||
*/
|
||||
#ifdef CONFIG_HW_WATCHDOG
|
||||
#define CONFIG_DESIGNWARE_WATCHDOG
|
||||
#define CONFIG_DW_WDT_BASE SOCFPGA_L4WD0_ADDRESS
|
||||
#define CONFIG_DW_WDT_CLOCK_KHZ 25000
|
||||
#endif
|
||||
|
||||
/*
|
||||
* MMC Driver
|
||||
|
@ -150,9 +150,10 @@ unsigned int cm_get_qspi_controller_clk_hz(void);
|
||||
/*
|
||||
* L4 Watchdog
|
||||
*/
|
||||
#ifdef CONFIG_SPL_BUILD
|
||||
#define CONFIG_HW_WATCHDOG
|
||||
#define CONFIG_DESIGNWARE_WATCHDOG
|
||||
#ifndef CONFIG_SPL_BUILD
|
||||
#undef CONFIG_HW_WATCHDOG
|
||||
#undef CONFIG_DESIGNWARE_WATCHDOG
|
||||
#endif
|
||||
#define CONFIG_DW_WDT_BASE SOCFPGA_L4WD0_ADDRESS
|
||||
#ifdef CONFIG_TARGET_SOCFPGA_STRATIX10
|
||||
#ifndef __ASSEMBLY__
|
||||
@ -162,7 +163,6 @@ unsigned int cm_get_l4_sys_free_clk_hz(void);
|
||||
#else
|
||||
#define CONFIG_DW_WDT_CLOCK_KHZ 100000
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* SPL memory layout
|
||||
|
@ -311,7 +311,6 @@ CONFIG_DEFAULT_IMMR
|
||||
CONFIG_DEF_HWCONFIG
|
||||
CONFIG_DELAY_ENVIRONMENT
|
||||
CONFIG_DESIGNWARE_ETH
|
||||
CONFIG_DESIGNWARE_WATCHDOG
|
||||
CONFIG_DEVELOP
|
||||
CONFIG_DEVICE_TREE_LIST
|
||||
CONFIG_DFU_ALT
|
||||
|
Loading…
Reference in New Issue
Block a user