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 {
|
&portc {
|
||||||
bank-name = "portc";
|
bank-name = "portc";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
&watchdog0 {
|
||||||
|
u-boot,dm-pre-reloc;
|
||||||
|
};
|
||||||
|
@ -31,3 +31,7 @@
|
|||||||
&sysmgr {
|
&sysmgr {
|
||||||
u-boot,dm-pre-reloc;
|
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_nop;
|
||||||
u8 lfsr_wr_rd_dm_bank_0_wait;
|
u8 lfsr_wr_rd_dm_bank_0_wait;
|
||||||
u8 lfsr_wr_rd_dm_bank_0_wl_1;
|
u8 lfsr_wr_rd_dm_bank_0_wl_1;
|
||||||
u8 mrs0_dll_reset;
|
union {
|
||||||
u8 mrs0_dll_reset_mirr;
|
u8 mrs0_dll_reset;
|
||||||
u8 mrs0_user;
|
u8 mr_dll_reset;
|
||||||
u8 mrs0_user_mirr;
|
};
|
||||||
u8 mrs1;
|
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 mrs1_mirr;
|
||||||
u8 mrs2;
|
|
||||||
u8 mrs2_mirr;
|
u8 mrs2_mirr;
|
||||||
u8 mrs3;
|
|
||||||
u8 mrs3_mirr;
|
u8 mrs3_mirr;
|
||||||
u8 precharge_all;
|
u8 precharge_all;
|
||||||
u8 read_b2b;
|
u8 read_b2b;
|
||||||
u8 read_b2b_wait1;
|
u8 read_b2b_wait1;
|
||||||
u8 read_b2b_wait2;
|
u8 read_b2b_wait2;
|
||||||
u8 refresh_all;
|
union {
|
||||||
|
u8 refresh;
|
||||||
|
u8 refresh_all;
|
||||||
|
};
|
||||||
u8 rreturn;
|
u8 rreturn;
|
||||||
u8 sgle_read;
|
u8 sgle_read;
|
||||||
u8 zqcl;
|
union {
|
||||||
|
u8 zqcl;
|
||||||
|
u8 nop;
|
||||||
|
};
|
||||||
|
|
||||||
u8 true_mem_data_mask_width;
|
u8 true_mem_data_mask_width;
|
||||||
u8 mem_address_mirroring;
|
u8 mem_address_mirroring;
|
||||||
@ -199,6 +226,7 @@ struct socfpga_sdram_io_config {
|
|||||||
|
|
||||||
struct socfpga_sdram_misc_config {
|
struct socfpga_sdram_misc_config {
|
||||||
u32 reg_file_init_seq_signature;
|
u32 reg_file_init_seq_signature;
|
||||||
|
u16 afi_clk_freq;
|
||||||
u8 afi_rate_ratio;
|
u8 afi_rate_ratio;
|
||||||
u8 calib_lfifo_offset;
|
u8 calib_lfifo_offset;
|
||||||
u8 calib_vfifo_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);
|
debug("Reset init failed: %d\n", ret);
|
||||||
|
|
||||||
#ifdef CONFIG_SPL_NAND_DENALI
|
#ifdef CONFIG_SPL_NAND_DENALI
|
||||||
struct socfpga_reset_manager *reset_manager_base =
|
clrbits_le32(SOCFPGA_RSTMGR_ADDRESS + RSTMGR_GEN5_PERMODRST, BIT(4));
|
||||||
(struct socfpga_reset_manager *)SOCFPGA_RSTMGR_ADDRESS;
|
|
||||||
|
|
||||||
clrbits_le32(&reset_manager_base->per_mod_reset, BIT(4));
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* enable console uart printing */
|
/* enable console uart printing */
|
||||||
|
@ -80,13 +80,15 @@ static const struct socfpga_sdram_config sdram_config = {
|
|||||||
SDR_CTRLGRP_DRAMODT_READ_LSB) |
|
SDR_CTRLGRP_DRAMODT_READ_LSB) |
|
||||||
(CONFIG_HPS_SDR_CTRLCFG_DRAMODT_WRITE <<
|
(CONFIG_HPS_SDR_CTRLCFG_DRAMODT_WRITE <<
|
||||||
SDR_CTRLGRP_DRAMODT_WRITE_LSB),
|
SDR_CTRLGRP_DRAMODT_WRITE_LSB),
|
||||||
|
#if (CONFIG_HPS_SDR_CTRLCFG_CTRLCFG_MEMTYPE == 2) /* DDR3 */
|
||||||
.extratime1 =
|
.extratime1 =
|
||||||
(CONFIG_HPS_SDR_CTRLCFG_EXTRATIME1_CFG_EXTRA_CTL_CLK_RD_TO_WR <<
|
(CONFIG_HPS_SDR_CTRLCFG_EXTRATIME1_CFG_EXTRA_CTL_CLK_RD_TO_WR <<
|
||||||
SDR_CTRLGRP_EXTRATIME1_RD_TO_WR_LSB) |
|
SDR_CTRLGRP_EXTRATIME1_RD_TO_WR_LSB) |
|
||||||
(CONFIG_HPS_SDR_CTRLCFG_EXTRATIME1_CFG_EXTRA_CTL_CLK_RD_TO_WR_BC <<
|
(CONFIG_HPS_SDR_CTRLCFG_EXTRATIME1_CFG_EXTRA_CTL_CLK_RD_TO_WR_BC <<
|
||||||
SDR_CTRLGRP_EXTRATIME1_RD_TO_WR_BC_LSB) |
|
SDR_CTRLGRP_EXTRATIME1_RD_TO_WR_BC_LSB) |
|
||||||
(CONFIG_HPS_SDR_CTRLCFG_EXTRATIME1_CFG_EXTRA_CTL_CLK_RD_TO_WR_DIFF_CHIP <<
|
(CONFIG_HPS_SDR_CTRLCFG_EXTRATIME1_CFG_EXTRA_CTL_CLK_RD_TO_WR_DIFF_CHIP <<
|
||||||
SDR_CTRLGRP_EXTRATIME1_RD_TO_WR_DIFF_LSB),
|
SDR_CTRLGRP_EXTRATIME1_RD_TO_WR_DIFF_LSB),
|
||||||
|
#endif
|
||||||
.dram_addrw =
|
.dram_addrw =
|
||||||
(CONFIG_HPS_SDR_CTRLCFG_DRAMADDRW_COLBITS <<
|
(CONFIG_HPS_SDR_CTRLCFG_DRAMADDRW_COLBITS <<
|
||||||
SDR_CTRLGRP_DRAMADDRW_COLBITS_LSB) |
|
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 = RW_MGR_ACTIVATE_0_AND_1,
|
||||||
.activate_0_and_1_wait1 = RW_MGR_ACTIVATE_0_AND_1_WAIT1,
|
.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_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,
|
.clear_dqs_enable = RW_MGR_CLEAR_DQS_ENABLE,
|
||||||
.guaranteed_read = RW_MGR_GUARANTEED_READ,
|
.guaranteed_read = RW_MGR_GUARANTEED_READ,
|
||||||
.guaranteed_read_cont = RW_MGR_GUARANTEED_READ_CONT,
|
.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_wait1 = RW_MGR_GUARANTEED_WRITE_WAIT1,
|
||||||
.guaranteed_write_wait2 = RW_MGR_GUARANTEED_WRITE_WAIT2,
|
.guaranteed_write_wait2 = RW_MGR_GUARANTEED_WRITE_WAIT2,
|
||||||
.guaranteed_write_wait3 = RW_MGR_GUARANTEED_WRITE_WAIT3,
|
.guaranteed_write_wait3 = RW_MGR_GUARANTEED_WRITE_WAIT3,
|
||||||
.idle = RW_MGR_IDLE,
|
|
||||||
.idle_loop1 = RW_MGR_IDLE_LOOP1,
|
.idle_loop1 = RW_MGR_IDLE_LOOP1,
|
||||||
.idle_loop2 = RW_MGR_IDLE_LOOP2,
|
.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_0_cke_0 = RW_MGR_INIT_RESET_0_CKE_0,
|
||||||
.init_reset_1_cke_0 = RW_MGR_INIT_RESET_1_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 = 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_data = RW_MGR_LFSR_WR_RD_BANK_0_DATA,
|
||||||
.lfsr_wr_rd_bank_0_dqs = RW_MGR_LFSR_WR_RD_BANK_0_DQS,
|
.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_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_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,
|
.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,
|
.precharge_all = RW_MGR_PRECHARGE_ALL,
|
||||||
.read_b2b = RW_MGR_READ_B2B,
|
.read_b2b = RW_MGR_READ_B2B,
|
||||||
.read_b2b_wait1 = RW_MGR_READ_B2B_WAIT1,
|
.read_b2b_wait1 = RW_MGR_READ_B2B_WAIT1,
|
||||||
.read_b2b_wait2 = RW_MGR_READ_B2B_WAIT2,
|
.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,
|
.true_mem_data_mask_width = RW_MGR_TRUE_MEM_DATA_MASK_WIDTH,
|
||||||
.mem_address_mirroring = RW_MGR_MEM_ADDRESS_MIRRORING,
|
.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 = {
|
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,
|
.afi_rate_ratio = AFI_RATE_RATIO,
|
||||||
.calib_lfifo_offset = CALIB_LFIFO_OFFSET,
|
.calib_lfifo_offset = CALIB_LFIFO_OFFSET,
|
||||||
.calib_vfifo_offset = CALIB_VFIFO_OFFSET,
|
.calib_vfifo_offset = CALIB_VFIFO_OFFSET,
|
||||||
|
@ -58,4 +58,6 @@ CONFIG_USB=y
|
|||||||
CONFIG_DM_USB=y
|
CONFIG_DM_USB=y
|
||||||
CONFIG_USB_DWC2=y
|
CONFIG_USB_DWC2=y
|
||||||
CONFIG_USB_STORAGE=y
|
CONFIG_USB_STORAGE=y
|
||||||
|
CONFIG_DESIGNWARE_WATCHDOG=y
|
||||||
|
CONFIG_WDT=y
|
||||||
# CONFIG_SPL_USE_TINY_PRINTF is not set
|
# 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_PRODUCT_NUM=0xa4a5
|
||||||
CONFIG_USB_GADGET_DWC2_OTG=y
|
CONFIG_USB_GADGET_DWC2_OTG=y
|
||||||
CONFIG_USB_GADGET_DOWNLOAD=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");
|
debug("Configuring DRAMODT\n");
|
||||||
writel(cfg->dram_odt, &sdr_ctrl->dram_odt);
|
writel(cfg->dram_odt, &sdr_ctrl->dram_odt);
|
||||||
|
|
||||||
debug("Configuring EXTRATIME1\n");
|
if (dram_is_ddr(3)) {
|
||||||
writel(cfg->extratime1, &sdr_ctrl->extratime1);
|
debug("Configuring EXTRATIME1\n");
|
||||||
|
writel(cfg->extratime1, &sdr_ctrl->extratime1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
#include <asm/arch/sdram.h>
|
#include <asm/arch/sdram.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <hang.h>
|
||||||
#include "sequencer.h"
|
#include "sequencer.h"
|
||||||
|
|
||||||
static const struct socfpga_sdr_rw_load_manager *sdr_rw_load_mgr_regs =
|
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) \
|
#define SKIP_DELAY_LOOP_VALUE_OR_ZERO(non_skip_value) \
|
||||||
((non_skip_value) & seq->skip_delay_mask)
|
((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,
|
static void set_failing_group_stage(struct socfpga_sdrseq *seq,
|
||||||
u32 group, u32 stage, u32 substage)
|
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_0 = 0x3 & ~(1 << rank);
|
||||||
odt_mask_1 = 0x3;
|
odt_mask_1 = 0x3;
|
||||||
|
if (dram_is_ddr(2))
|
||||||
|
odt_mask_1 &= ~(1 << rank);
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* - Single-Slot , Dual-Rank (2 CS per DIMM)
|
* - Single-Slot , Dual-Rank (2 CS per DIMM)
|
||||||
@ -176,10 +194,11 @@ static void set_rank_and_odt_mask(struct socfpga_sdrseq *seq,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 4: /* 4 Ranks */
|
case 4: /* 4 Ranks */
|
||||||
/* Read:
|
/*
|
||||||
|
* DDR3 Read, DDR2 Read/Write:
|
||||||
* ----------+-----------------------+
|
* ----------+-----------------------+
|
||||||
* | ODT |
|
* | ODT |
|
||||||
* Read From +-----------------------+
|
* +-----------------------+
|
||||||
* Rank | 3 | 2 | 1 | 0 |
|
* Rank | 3 | 2 | 1 | 0 |
|
||||||
* ----------+-----+-----+-----+-----+
|
* ----------+-----+-----+-----+-----+
|
||||||
* 0 | 0 | 1 | 0 | 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 |
|
* 3 | 0 | 0 | 1 | 0 |
|
||||||
* ----------+-----+-----+-----+-----+
|
* ----------+-----+-----+-----+-----+
|
||||||
*
|
*
|
||||||
* Write:
|
* DDR3 Write:
|
||||||
* ----------+-----------------------+
|
* ----------+-----------------------+
|
||||||
* | ODT |
|
* | ODT |
|
||||||
* Write To +-----------------------+
|
* Write To +-----------------------+
|
||||||
@ -203,19 +222,31 @@ static void set_rank_and_odt_mask(struct socfpga_sdrseq *seq,
|
|||||||
switch (rank) {
|
switch (rank) {
|
||||||
case 0:
|
case 0:
|
||||||
odt_mask_0 = 0x4;
|
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;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
odt_mask_0 = 0x8;
|
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;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
odt_mask_0 = 0x1;
|
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;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
odt_mask_0 = 0x2;
|
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;
|
||||||
}
|
}
|
||||||
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);
|
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
|
* rw_mgr_mem_init_load_regs() - Load instruction registers
|
||||||
* @cntr0: Counter 0 value
|
* @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
|
* @fin1: Final instruction 1
|
||||||
* @fin2: Final instruction 2
|
* @fin2: Final instruction 2
|
||||||
* @precharge: If 1, precharge the banks at the end
|
* @precharge: If 1, precharge the banks at the end
|
||||||
*
|
*
|
||||||
* Load user calibration values and optionally precharge the banks.
|
* 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 u32 fin1, const u32 fin2,
|
||||||
const int precharge)
|
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
|
* 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__);
|
debug("%s:%d\n", __func__, __LINE__);
|
||||||
|
|
||||||
/* The reset / cke part of initialization is broadcasted to all ranks */
|
/* The reset / cke part of initialization is broadcasted to all ranks */
|
||||||
writel(RW_MGR_RANK_ALL, SDR_PHYGRP_RWMGRGRP_ADDRESS |
|
if (dram_is_ddr(3)) {
|
||||||
RW_MGR_SET_CS_AND_ODT_MASK_OFFSET);
|
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
|
* 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. */
|
/* Indicate that memory is stable. */
|
||||||
writel(1, &phy_mgr_cfg->reset_mem_stbl);
|
writel(1, &phy_mgr_cfg->reset_mem_stbl);
|
||||||
|
|
||||||
/*
|
if (dram_is_ddr(2)) {
|
||||||
* transition the RESET to high
|
writel(seq->rwcfg->nop, SDR_PHYGRP_RWMGRGRP_ADDRESS |
|
||||||
* Wait for 500us
|
RW_MGR_RUN_SINGLE_GROUP_OFFSET);
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
/* Bring up clock enable. */
|
||||||
* 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 < 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,
|
rw_mgr_mem_load_user(seq, seq->rwcfg->mrs0_dll_reset_mirr,
|
||||||
seq->rwcfg->mrs0_dll_reset, 0);
|
seq->rwcfg->mrs0_dll_reset, 0);
|
||||||
@ -3769,16 +3881,26 @@ static void initialize_tracking(struct socfpga_sdrseq *seq)
|
|||||||
&sdr_reg_file->delays);
|
&sdr_reg_file->delays);
|
||||||
|
|
||||||
/* mux delay */
|
/* mux delay */
|
||||||
writel((seq->rwcfg->idle << 24) | (seq->rwcfg->activate_1 << 16) |
|
if (dram_is_ddr(2)) {
|
||||||
(seq->rwcfg->sgle_read << 8) | (seq->rwcfg->precharge_all << 0),
|
writel(0, &sdr_reg_file->trk_rw_mgr_addr);
|
||||||
&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,
|
writel(seq->rwcfg->mem_if_read_dqs_width,
|
||||||
&sdr_reg_file->trk_read_dqs_width);
|
&sdr_reg_file->trk_read_dqs_width);
|
||||||
|
|
||||||
/* trefi [7:0] */
|
/* trefi [7:0] */
|
||||||
writel((seq->rwcfg->refresh_all << 24) | (1000 << 0),
|
if (dram_is_ddr(2)) {
|
||||||
&sdr_reg_file->trk_rfsh);
|
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)
|
int sdram_calibration_full(struct socfpga_sdr *sdr)
|
||||||
|
@ -279,5 +279,6 @@ struct socfpga_sdrseq {
|
|||||||
};
|
};
|
||||||
|
|
||||||
int sdram_calibration_full(struct socfpga_sdr *sdr);
|
int sdram_calibration_full(struct socfpga_sdr *sdr);
|
||||||
|
bool dram_is_ddr(const u8 ddr);
|
||||||
|
|
||||||
#endif /* _SEQUENCER_H_ */
|
#endif /* _SEQUENCER_H_ */
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include <dm/of_access.h>
|
#include <dm/of_access.h>
|
||||||
#include <env.h>
|
#include <env.h>
|
||||||
#include <reset-uclass.h>
|
#include <reset-uclass.h>
|
||||||
|
#include <wait_bit.h>
|
||||||
#include <linux/bitops.h>
|
#include <linux/bitops.h>
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
#include <linux/sizes.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);
|
int offset = id % (reg_width * BITS_PER_BYTE);
|
||||||
|
|
||||||
clrbits_le32(data->modrst_base + (bank * BANK_INCREMENT), BIT(offset));
|
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)
|
static int socfpga_reset_request(struct reset_ctl *reset_ctl)
|
||||||
|
@ -45,6 +45,13 @@ config ULP_WATCHDOG
|
|||||||
help
|
help
|
||||||
Say Y here to enable i.MX7ULP watchdog driver.
|
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
|
config WDT
|
||||||
bool "Enable driver model for watchdog timer drivers"
|
bool "Enable driver model for watchdog timer drivers"
|
||||||
depends on DM
|
depends on DM
|
||||||
|
@ -3,8 +3,11 @@
|
|||||||
* Copyright (C) 2013 Altera Corporation <www.altera.com>
|
* Copyright (C) 2013 Altera Corporation <www.altera.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <clk.h>
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
#include <watchdog.h>
|
#include <dm.h>
|
||||||
|
#include <reset.h>
|
||||||
|
#include <wdt.h>
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
#include <asm/utils.h>
|
#include <asm/utils.h>
|
||||||
|
|
||||||
@ -14,49 +17,52 @@
|
|||||||
|
|
||||||
#define DW_WDT_CR_EN_OFFSET 0x00
|
#define DW_WDT_CR_EN_OFFSET 0x00
|
||||||
#define DW_WDT_CR_RMOD_OFFSET 0x01
|
#define DW_WDT_CR_RMOD_OFFSET 0x01
|
||||||
#define DW_WDT_CR_RMOD_VAL 0x00
|
|
||||||
#define DW_WDT_CRR_RESTART_VAL 0x76
|
#define DW_WDT_CRR_RESTART_VAL 0x76
|
||||||
|
|
||||||
|
struct designware_wdt_priv {
|
||||||
|
void __iomem *base;
|
||||||
|
unsigned int clk_khz;
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set the watchdog time interval.
|
* Set the watchdog time interval.
|
||||||
* Counter is 32 bit.
|
* 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;
|
signed int i;
|
||||||
|
|
||||||
/* calculate the timeout range value */
|
/* calculate the timeout range value */
|
||||||
i = (log_2_n_round_up(timeout * CONFIG_DW_WDT_CLOCK_KHZ)) - 16;
|
i = log_2_n_round_up(timeout * clk_khz) - 16;
|
||||||
if (i > 15)
|
i = clamp(i, 0, 15);
|
||||||
i = 15;
|
|
||||||
if (i < 0)
|
writel(i | (i << 4), base + DW_WDT_TORR);
|
||||||
i = 0;
|
|
||||||
|
|
||||||
writel((i | (i << 4)), (CONFIG_DW_WDT_BASE + DW_WDT_TORR));
|
|
||||||
return 0;
|
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) |
|
writel(BIT(DW_WDT_CR_EN_OFFSET), base + DW_WDT_CR);
|
||||||
(0x1 << DW_WDT_CR_EN_OFFSET)),
|
|
||||||
(CONFIG_DW_WDT_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;
|
return readl(base + DW_WDT_CR) & BIT(0);
|
||||||
val = readl((CONFIG_DW_WDT_BASE + DW_WDT_CR));
|
|
||||||
return val & 0x1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#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)
|
void hw_watchdog_reset(void)
|
||||||
{
|
{
|
||||||
if (designware_wdt_is_enabled())
|
designware_wdt_reset_common((void __iomem *)CONFIG_DW_WDT_BASE);
|
||||||
/* restart the watchdog counter */
|
|
||||||
writel(DW_WDT_CRR_RESTART_VAL,
|
|
||||||
(CONFIG_DW_WDT_BASE + DW_WDT_CRR));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void hw_watchdog_init(void)
|
void hw_watchdog_init(void)
|
||||||
@ -64,10 +70,106 @@ void hw_watchdog_init(void)
|
|||||||
/* reset to disable the watchdog */
|
/* reset to disable the watchdog */
|
||||||
hw_watchdog_reset();
|
hw_watchdog_reset();
|
||||||
/* set timer in miliseconds */
|
/* 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 */
|
/* enable the watchdog */
|
||||||
designware_wdt_enable();
|
designware_wdt_enable((void __iomem *)CONFIG_DW_WDT_BASE);
|
||||||
/* reset the watchdog */
|
/* reset the watchdog */
|
||||||
hw_watchdog_reset();
|
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
|
#endif
|
||||||
|
@ -104,11 +104,8 @@
|
|||||||
/*
|
/*
|
||||||
* L4 Watchdog
|
* L4 Watchdog
|
||||||
*/
|
*/
|
||||||
#ifdef CONFIG_HW_WATCHDOG
|
|
||||||
#define CONFIG_DESIGNWARE_WATCHDOG
|
|
||||||
#define CONFIG_DW_WDT_BASE SOCFPGA_L4WD0_ADDRESS
|
#define CONFIG_DW_WDT_BASE SOCFPGA_L4WD0_ADDRESS
|
||||||
#define CONFIG_DW_WDT_CLOCK_KHZ 25000
|
#define CONFIG_DW_WDT_CLOCK_KHZ 25000
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MMC Driver
|
* MMC Driver
|
||||||
|
@ -150,9 +150,10 @@ unsigned int cm_get_qspi_controller_clk_hz(void);
|
|||||||
/*
|
/*
|
||||||
* L4 Watchdog
|
* L4 Watchdog
|
||||||
*/
|
*/
|
||||||
#ifdef CONFIG_SPL_BUILD
|
#ifndef CONFIG_SPL_BUILD
|
||||||
#define CONFIG_HW_WATCHDOG
|
#undef CONFIG_HW_WATCHDOG
|
||||||
#define CONFIG_DESIGNWARE_WATCHDOG
|
#undef CONFIG_DESIGNWARE_WATCHDOG
|
||||||
|
#endif
|
||||||
#define CONFIG_DW_WDT_BASE SOCFPGA_L4WD0_ADDRESS
|
#define CONFIG_DW_WDT_BASE SOCFPGA_L4WD0_ADDRESS
|
||||||
#ifdef CONFIG_TARGET_SOCFPGA_STRATIX10
|
#ifdef CONFIG_TARGET_SOCFPGA_STRATIX10
|
||||||
#ifndef __ASSEMBLY__
|
#ifndef __ASSEMBLY__
|
||||||
@ -162,7 +163,6 @@ unsigned int cm_get_l4_sys_free_clk_hz(void);
|
|||||||
#else
|
#else
|
||||||
#define CONFIG_DW_WDT_CLOCK_KHZ 100000
|
#define CONFIG_DW_WDT_CLOCK_KHZ 100000
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SPL memory layout
|
* SPL memory layout
|
||||||
|
@ -311,7 +311,6 @@ CONFIG_DEFAULT_IMMR
|
|||||||
CONFIG_DEF_HWCONFIG
|
CONFIG_DEF_HWCONFIG
|
||||||
CONFIG_DELAY_ENVIRONMENT
|
CONFIG_DELAY_ENVIRONMENT
|
||||||
CONFIG_DESIGNWARE_ETH
|
CONFIG_DESIGNWARE_ETH
|
||||||
CONFIG_DESIGNWARE_WATCHDOG
|
|
||||||
CONFIG_DEVELOP
|
CONFIG_DEVELOP
|
||||||
CONFIG_DEVICE_TREE_LIST
|
CONFIG_DEVICE_TREE_LIST
|
||||||
CONFIG_DFU_ALT
|
CONFIG_DFU_ALT
|
||||||
|
Loading…
Reference in New Issue
Block a user