summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/crypto/fsl/jr.c8
-rw-r--r--drivers/ddr/fsl/ctrl_regs.c48
-rw-r--r--drivers/ddr/fsl/fsl_ddr_gen4.c65
-rw-r--r--drivers/ddr/fsl/options.c237
-rw-r--r--drivers/net/fsl-mc/dpio/qbman_portal.c2
-rw-r--r--drivers/serial/serial_stm32.c203
-rw-r--r--drivers/spi/fsl_qspi.c5
7 files changed, 402 insertions, 166 deletions
diff --git a/drivers/crypto/fsl/jr.c b/drivers/crypto/fsl/jr.c
index f63eacb..b553e3c 100644
--- a/drivers/crypto/fsl/jr.c
+++ b/drivers/crypto/fsl/jr.c
@@ -470,17 +470,13 @@ static void kick_trng(int ent_delay)
sec_out32(&rng->rtfreqmin, ent_delay >> 2);
/* disable maximum frequency count */
sec_out32(&rng->rtfreqmax, RTFRQMAX_DISABLE);
- /* read the control register */
- val = sec_in32(&rng->rtmctl);
/*
* select raw sampling in both entropy shifter
* and statistical checker
*/
- sec_setbits32(&val, RTMCTL_SAMP_MODE_RAW_ES_SC);
+ sec_setbits32(&rng->rtmctl, RTMCTL_SAMP_MODE_RAW_ES_SC);
/* put RNG4 into run mode */
- sec_clrbits32(&val, RTMCTL_PRGM);
- /* write back the control register */
- sec_out32(&rng->rtmctl, val);
+ sec_clrbits32(&rng->rtmctl, RTMCTL_PRGM);
}
static int rng_init(void)
diff --git a/drivers/ddr/fsl/ctrl_regs.c b/drivers/ddr/fsl/ctrl_regs.c
index 8543679..0bfcd34 100644
--- a/drivers/ddr/fsl/ctrl_regs.c
+++ b/drivers/ddr/fsl/ctrl_regs.c
@@ -317,7 +317,24 @@ static void set_timing_cfg_0(const unsigned int ctrl_num,
/* for faster clock, need more time for data setup */
trwt_mclk = (data_rate/1000000 > 1900) ? 3 : 2;
- twrt_mclk = 1;
+
+ /*
+ * for single quad-rank DIMM and two-slot DIMMs
+ * to avoid ODT overlap
+ */
+ switch (avoid_odt_overlap(dimm_params)) {
+ case 2:
+ twrt_mclk = 2;
+ twwt_mclk = 2;
+ trrt_mclk = 2;
+ break;
+ default:
+ twrt_mclk = 1;
+ twwt_mclk = 1;
+ trrt_mclk = 0;
+ break;
+ }
+
act_pd_exit_mclk = picos_to_mclk(ctrl_num, txp);
pre_pd_exit_mclk = act_pd_exit_mclk;
/*
@@ -1117,10 +1134,18 @@ static void set_ddr_sdram_mode_9(fsl_ddr_cfg_regs_t *ddr,
unsigned short esdmode4 = 0; /* Extended SDRAM mode 4 */
unsigned short esdmode5; /* Extended SDRAM mode 5 */
int rtt_park = 0;
-
+ bool four_cs = false;
+
+#if CONFIG_CHIP_SELECTS_PER_CTRL == 4
+ if ((ddr->cs[0].config & SDRAM_CS_CONFIG_EN) &&
+ (ddr->cs[1].config & SDRAM_CS_CONFIG_EN) &&
+ (ddr->cs[2].config & SDRAM_CS_CONFIG_EN) &&
+ (ddr->cs[3].config & SDRAM_CS_CONFIG_EN))
+ four_cs = true;
+#endif
if (ddr->cs[0].config & SDRAM_CS_CONFIG_EN) {
esdmode5 = 0x00000500; /* Data mask enable, RTT_PARK CS0 */
- rtt_park = 1;
+ rtt_park = four_cs ? 0 : 1;
} else {
esdmode5 = 0x00000400; /* Data mask enabled */
}
@@ -1130,7 +1155,10 @@ static void set_ddr_sdram_mode_9(fsl_ddr_cfg_regs_t *ddr,
| ((esdmode5 & 0xffff) << 0)
);
- /* only mode_9 use 0x500, others use 0x400 */
+ /* Normally only the first enabled CS use 0x500, others use 0x400
+ * But when four chip-selects are all enabled, all mode registers
+ * need 0x500 to park.
+ */
debug("FSLDDR: ddr_sdram_mode_9) = 0x%08x\n", ddr->ddr_sdram_mode_9);
if (unq_mrs_en) { /* unique mode registers are supported */
@@ -1138,7 +1166,7 @@ static void set_ddr_sdram_mode_9(fsl_ddr_cfg_regs_t *ddr,
if (!rtt_park &&
(ddr->cs[i].config & SDRAM_CS_CONFIG_EN)) {
esdmode5 |= 0x00000500; /* RTT_PARK */
- rtt_park = 1;
+ rtt_park = four_cs ? 0 : 1;
} else {
esdmode5 = 0x00000400;
}
@@ -1186,6 +1214,9 @@ static void set_ddr_sdram_mode_10(const unsigned int ctrl_num,
esdmode6 = ((tccdl_min - 4) & 0x7) << 10;
+ if (popts->ddr_cdr2 & DDR_CDR2_VREF_RANGE_2)
+ esdmode6 |= 1 << 6; /* Range 2 */
+
ddr->ddr_sdram_mode_10 = (0
| ((esdmode6 & 0xffff) << 16)
| ((esdmode7 & 0xffff) << 0)
@@ -1808,6 +1839,7 @@ static void set_timing_cfg_4(fsl_ddr_cfg_regs_t *ddr,
unsigned int wrt = 0; /* Write-to-read turnaround for same CS */
unsigned int rrt = 0; /* Read-to-read turnaround for same CS */
unsigned int wwt = 0; /* Write-to-write turnaround for same CS */
+ unsigned int trwt_mclk = 0; /* ext_rwt */
unsigned int dll_lock = 0; /* DDR SDRAM DLL Lock Time */
#if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4)
@@ -1821,17 +1853,21 @@ static void set_timing_cfg_4(fsl_ddr_cfg_regs_t *ddr,
wwt = 2; /* BL/2 + 2 clocks */
}
#endif
-
#ifdef CONFIG_SYS_FSL_DDR4
dll_lock = 2; /* tDLLK = 1024 clocks */
#elif defined(CONFIG_SYS_FSL_DDR3)
dll_lock = 1; /* tDLLK = 512 clocks from spec */
#endif
+
+ if (popts->trwt_override)
+ trwt_mclk = popts->trwt;
+
ddr->timing_cfg_4 = (0
| ((rwt & 0xf) << 28)
| ((wrt & 0xf) << 24)
| ((rrt & 0xf) << 20)
| ((wwt & 0xf) << 16)
+ | ((trwt_mclk & 0xc) << 12)
| (dll_lock & 0x3)
);
debug("FSLDDR: timing_cfg_4 = 0x%08x\n", ddr->timing_cfg_4);
diff --git a/drivers/ddr/fsl/fsl_ddr_gen4.c b/drivers/ddr/fsl/fsl_ddr_gen4.c
index 1de7b72..3fca5c2 100644
--- a/drivers/ddr/fsl/fsl_ddr_gen4.c
+++ b/drivers/ddr/fsl/fsl_ddr_gen4.c
@@ -10,6 +10,7 @@
#include <asm/processor.h>
#include <fsl_immap.h>
#include <fsl_ddr.h>
+#include <fsl_errata.h>
#ifdef CONFIG_SYS_FSL_ERRATUM_A008511
static void set_wait_for_bits_clear(void *ptr, u32 value, u32 bits)
@@ -48,12 +49,11 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
u32 temp_sdram_cfg;
u32 total_gb_size_per_controller;
int timeout;
-#if defined(CONFIG_SYS_FSL_ERRATUM_A008336) || \
- defined(CONFIG_SYS_FSL_ERRATUM_A008514)
- u32 *eddrtqcr1;
-#endif
#ifdef CONFIG_SYS_FSL_ERRATUM_A008511
u32 temp32, mr6;
+ u32 vref_seq1[3] = {0x80, 0x96, 0x16}; /* for range 1 */
+ u32 vref_seq2[3] = {0xc0, 0xf0, 0x70}; /* for range 2 */
+ u32 *vref_seq = vref_seq1;
#endif
#ifdef CONFIG_FSL_DDR_BIST
u32 mtcr, err_detect, err_sbe;
@@ -66,36 +66,20 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
switch (ctrl_num) {
case 0:
ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR;
-#if defined(CONFIG_SYS_FSL_ERRATUM_A008336) || \
- defined(CONFIG_SYS_FSL_ERRATUM_A008514)
- eddrtqcr1 = (void *)CONFIG_SYS_FSL_DCSR_DDR_ADDR + 0x800;
-#endif
break;
#if defined(CONFIG_SYS_FSL_DDR2_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 1)
case 1:
ddr = (void *)CONFIG_SYS_FSL_DDR2_ADDR;
-#if defined(CONFIG_SYS_FSL_ERRATUM_A008336) || \
- defined(CONFIG_SYS_FSL_ERRATUM_A008514)
- eddrtqcr1 = (void *)CONFIG_SYS_FSL_DCSR_DDR2_ADDR + 0x800;
-#endif
break;
#endif
#if defined(CONFIG_SYS_FSL_DDR3_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 2)
case 2:
ddr = (void *)CONFIG_SYS_FSL_DDR3_ADDR;
-#if defined(CONFIG_SYS_FSL_ERRATUM_A008336) || \
- defined(CONFIG_SYS_FSL_ERRATUM_A008514)
- eddrtqcr1 = (void *)CONFIG_SYS_FSL_DCSR_DDR3_ADDR + 0x800;
-#endif
break;
#endif
#if defined(CONFIG_SYS_FSL_DDR4_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 3)
case 3:
ddr = (void *)CONFIG_SYS_FSL_DDR4_ADDR;
-#if defined(CONFIG_SYS_FSL_ERRATUM_A008336) || \
- defined(CONFIG_SYS_FSL_ERRATUM_A008514)
- eddrtqcr1 = (void *)CONFIG_SYS_FSL_DCSR_DDR4_ADDR + 0x800;
-#endif
break;
#endif
default:
@@ -106,20 +90,6 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
if (step == 2)
goto step2;
-#ifdef CONFIG_SYS_FSL_ERRATUM_A008336
-#if defined(CONFIG_LS2080A) || defined(CONFIG_LS2085A)
- /* A008336 only applies to general DDR controllers */
- if ((ctrl_num == 0) || (ctrl_num == 1))
-#endif
- ddr_out32(eddrtqcr1, 0x63b30002);
-#endif
-#ifdef CONFIG_SYS_FSL_ERRATUM_A008514
-#if defined(CONFIG_LS2080A) || defined(CONFIG_LS2085A)
- /* A008514 only applies to DP-DDR controler */
- if (ctrl_num == 2)
-#endif
- ddr_out32(eddrtqcr1, 0x63b20002);
-#endif
if (regs->ddr_eor)
ddr_out32(&ddr->eor, regs->ddr_eor);
@@ -235,9 +205,11 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
/* Erratum applies when accumulated ECC is used, or DBI is enabled */
#define IS_ACC_ECC_EN(v) ((v) & 0x4)
#define IS_DBI(v) ((((v) >> 12) & 0x3) == 0x2)
- if (IS_ACC_ECC_EN(regs->ddr_sdram_cfg) ||
- IS_DBI(regs->ddr_sdram_cfg_3))
- ddr_setbits32(ddr->debug[28], 0x9 << 20);
+ if (has_erratum_a008378()) {
+ if (IS_ACC_ECC_EN(regs->ddr_sdram_cfg) ||
+ IS_DBI(regs->ddr_sdram_cfg_3))
+ ddr_setbits32(&ddr->debug[28], 0x9 << 20);
+ }
#endif
#ifdef CONFIG_SYS_FSL_ERRATUM_A008511
@@ -307,16 +279,21 @@ step2:
/* This erraum only applies to verion 5.2.0 */
if (fsl_ddr_get_version(ctrl_num) == 0x50200) {
/* Wait for idle */
- timeout = 200;
+ timeout = 40;
while (!(ddr_in32(&ddr->debug[1]) & 0x2) &&
(timeout > 0)) {
- udelay(100);
+ udelay(1000);
timeout--;
}
if (timeout <= 0) {
printf("Controler %d timeout, debug_2 = %x\n",
ctrl_num, ddr_in32(&ddr->debug[1]));
}
+
+ /* The vref setting sequence is different for range 2 */
+ if (regs->ddr_cdr2 & DDR_CDR2_VREF_RANGE_2)
+ vref_seq = vref_seq2;
+
/* Set VREF */
for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
if (!(regs->cs[i].config & SDRAM_CS_CONFIG_EN))
@@ -327,17 +304,17 @@ step2:
MD_CNTL_CS_SEL(i) |
MD_CNTL_MD_SEL(6) |
0x00200000;
- temp32 = mr6 | 0xc0;
+ temp32 = mr6 | vref_seq[0];
set_wait_for_bits_clear(&ddr->sdram_md_cntl,
temp32, MD_CNTL_MD_EN);
udelay(1);
debug("MR6 = 0x%08x\n", temp32);
- temp32 = mr6 | 0xf0;
+ temp32 = mr6 | vref_seq[1];
set_wait_for_bits_clear(&ddr->sdram_md_cntl,
temp32, MD_CNTL_MD_EN);
udelay(1);
debug("MR6 = 0x%08x\n", temp32);
- temp32 = mr6 | 0x70;
+ temp32 = mr6 | vref_seq[2];
set_wait_for_bits_clear(&ddr->sdram_md_cntl,
temp32, MD_CNTL_MD_EN);
udelay(1);
@@ -347,10 +324,10 @@ step2:
ddr_out32(&ddr->debug[28], 0); /* Enable deskew */
ddr_out32(&ddr->debug[1], 0x400); /* restart deskew */
/* wait for idle */
- timeout = 200;
+ timeout = 40;
while (!(ddr_in32(&ddr->debug[1]) & 0x2) &&
(timeout > 0)) {
- udelay(100);
+ udelay(1000);
timeout--;
}
if (timeout <= 0) {
diff --git a/drivers/ddr/fsl/options.c b/drivers/ddr/fsl/options.c
index 3c09c64..791d644 100644
--- a/drivers/ddr/fsl/options.c
+++ b/drivers/ddr/fsl/options.c
@@ -29,7 +29,240 @@ struct dynamic_odt {
unsigned int odt_rtt_wr;
};
-#if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4)
+#ifdef CONFIG_SYS_FSL_DDR4
+/* Quad rank is not verified yet due availability.
+ * Replacing 20 OHM with 34 OHM since DDR4 doesn't have 20 OHM option
+ */
+static const struct dynamic_odt single_Q[4] = {
+ { /* cs0 */
+ FSL_DDR_ODT_NEVER,
+ FSL_DDR_ODT_CS_AND_OTHER_DIMM,
+ DDR4_RTT_34_OHM, /* unverified */
+ DDR4_RTT_120_OHM
+ },
+ { /* cs1 */
+ FSL_DDR_ODT_NEVER,
+ FSL_DDR_ODT_NEVER,
+ DDR4_RTT_OFF,
+ DDR4_RTT_120_OHM
+ },
+ { /* cs2 */
+ FSL_DDR_ODT_NEVER,
+ FSL_DDR_ODT_CS_AND_OTHER_DIMM,
+ DDR4_RTT_34_OHM,
+ DDR4_RTT_120_OHM
+ },
+ { /* cs3 */
+ FSL_DDR_ODT_NEVER,
+ FSL_DDR_ODT_NEVER, /* tied high */
+ DDR4_RTT_OFF,
+ DDR4_RTT_120_OHM
+ }
+};
+
+static const struct dynamic_odt single_D[4] = {
+ { /* cs0 */
+ FSL_DDR_ODT_NEVER,
+ FSL_DDR_ODT_ALL,
+ DDR4_RTT_40_OHM,
+ DDR4_RTT_OFF
+ },
+ { /* cs1 */
+ FSL_DDR_ODT_NEVER,
+ FSL_DDR_ODT_NEVER,
+ DDR4_RTT_OFF,
+ DDR4_RTT_OFF
+ },
+ {0, 0, 0, 0},
+ {0, 0, 0, 0}
+};
+
+static const struct dynamic_odt single_S[4] = {
+ { /* cs0 */
+ FSL_DDR_ODT_NEVER,
+ FSL_DDR_ODT_ALL,
+ DDR4_RTT_40_OHM,
+ DDR4_RTT_OFF
+ },
+ {0, 0, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0},
+};
+
+static const struct dynamic_odt dual_DD[4] = {
+ { /* cs0 */
+ FSL_DDR_ODT_NEVER,
+ FSL_DDR_ODT_SAME_DIMM,
+ DDR4_RTT_120_OHM,
+ DDR4_RTT_OFF
+ },
+ { /* cs1 */
+ FSL_DDR_ODT_OTHER_DIMM,
+ FSL_DDR_ODT_OTHER_DIMM,
+ DDR4_RTT_34_OHM,
+ DDR4_RTT_OFF
+ },
+ { /* cs2 */
+ FSL_DDR_ODT_NEVER,
+ FSL_DDR_ODT_SAME_DIMM,
+ DDR4_RTT_120_OHM,
+ DDR4_RTT_OFF
+ },
+ { /* cs3 */
+ FSL_DDR_ODT_OTHER_DIMM,
+ FSL_DDR_ODT_OTHER_DIMM,
+ DDR4_RTT_34_OHM,
+ DDR4_RTT_OFF
+ }
+};
+
+static const struct dynamic_odt dual_DS[4] = {
+ { /* cs0 */
+ FSL_DDR_ODT_NEVER,
+ FSL_DDR_ODT_SAME_DIMM,
+ DDR4_RTT_120_OHM,
+ DDR4_RTT_OFF
+ },
+ { /* cs1 */
+ FSL_DDR_ODT_OTHER_DIMM,
+ FSL_DDR_ODT_OTHER_DIMM,
+ DDR4_RTT_34_OHM,
+ DDR4_RTT_OFF
+ },
+ { /* cs2 */
+ FSL_DDR_ODT_OTHER_DIMM,
+ FSL_DDR_ODT_ALL,
+ DDR4_RTT_34_OHM,
+ DDR4_RTT_120_OHM
+ },
+ {0, 0, 0, 0}
+};
+static const struct dynamic_odt dual_SD[4] = {
+ { /* cs0 */
+ FSL_DDR_ODT_OTHER_DIMM,
+ FSL_DDR_ODT_ALL,
+ DDR4_RTT_34_OHM,
+ DDR4_RTT_120_OHM
+ },
+ {0, 0, 0, 0},
+ { /* cs2 */
+ FSL_DDR_ODT_NEVER,
+ FSL_DDR_ODT_SAME_DIMM,
+ DDR4_RTT_120_OHM,
+ DDR4_RTT_OFF
+ },
+ { /* cs3 */
+ FSL_DDR_ODT_OTHER_DIMM,
+ FSL_DDR_ODT_OTHER_DIMM,
+ DDR4_RTT_34_OHM,
+ DDR4_RTT_OFF
+ }
+};
+
+static const struct dynamic_odt dual_SS[4] = {
+ { /* cs0 */
+ FSL_DDR_ODT_OTHER_DIMM,
+ FSL_DDR_ODT_ALL,
+ DDR4_RTT_34_OHM,
+ DDR4_RTT_120_OHM
+ },
+ {0, 0, 0, 0},
+ { /* cs2 */
+ FSL_DDR_ODT_OTHER_DIMM,
+ FSL_DDR_ODT_ALL,
+ DDR4_RTT_34_OHM,
+ DDR4_RTT_120_OHM
+ },
+ {0, 0, 0, 0}
+};
+
+static const struct dynamic_odt dual_D0[4] = {
+ { /* cs0 */
+ FSL_DDR_ODT_NEVER,
+ FSL_DDR_ODT_SAME_DIMM,
+ DDR4_RTT_40_OHM,
+ DDR4_RTT_OFF
+ },
+ { /* cs1 */
+ FSL_DDR_ODT_NEVER,
+ FSL_DDR_ODT_NEVER,
+ DDR4_RTT_OFF,
+ DDR4_RTT_OFF
+ },
+ {0, 0, 0, 0},
+ {0, 0, 0, 0}
+};
+
+static const struct dynamic_odt dual_0D[4] = {
+ {0, 0, 0, 0},
+ {0, 0, 0, 0},
+ { /* cs2 */
+ FSL_DDR_ODT_NEVER,
+ FSL_DDR_ODT_SAME_DIMM,
+ DDR4_RTT_40_OHM,
+ DDR4_RTT_OFF
+ },
+ { /* cs3 */
+ FSL_DDR_ODT_NEVER,
+ FSL_DDR_ODT_NEVER,
+ DDR4_RTT_OFF,
+ DDR4_RTT_OFF
+ }
+};
+
+static const struct dynamic_odt dual_S0[4] = {
+ { /* cs0 */
+ FSL_DDR_ODT_NEVER,
+ FSL_DDR_ODT_CS,
+ DDR4_RTT_40_OHM,
+ DDR4_RTT_OFF
+ },
+ {0, 0, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0}
+
+};
+
+static const struct dynamic_odt dual_0S[4] = {
+ {0, 0, 0, 0},
+ {0, 0, 0, 0},
+ { /* cs2 */
+ FSL_DDR_ODT_NEVER,
+ FSL_DDR_ODT_CS,
+ DDR4_RTT_40_OHM,
+ DDR4_RTT_OFF
+ },
+ {0, 0, 0, 0}
+
+};
+
+static const struct dynamic_odt odt_unknown[4] = {
+ { /* cs0 */
+ FSL_DDR_ODT_NEVER,
+ FSL_DDR_ODT_CS,
+ DDR4_RTT_120_OHM,
+ DDR4_RTT_OFF
+ },
+ { /* cs1 */
+ FSL_DDR_ODT_NEVER,
+ FSL_DDR_ODT_CS,
+ DDR4_RTT_120_OHM,
+ DDR4_RTT_OFF
+ },
+ { /* cs2 */
+ FSL_DDR_ODT_NEVER,
+ FSL_DDR_ODT_CS,
+ DDR4_RTT_120_OHM,
+ DDR4_RTT_OFF
+ },
+ { /* cs3 */
+ FSL_DDR_ODT_NEVER,
+ FSL_DDR_ODT_CS,
+ DDR4_RTT_120_OHM,
+ DDR4_RTT_OFF
+ }
+};
+#elif defined(CONFIG_SYS_FSL_DDR3)
static const struct dynamic_odt single_Q[4] = {
{ /* cs0 */
FSL_DDR_ODT_NEVER,
@@ -259,7 +492,7 @@ static const struct dynamic_odt odt_unknown[4] = {
DDR3_RTT_OFF
}
};
-#else /* CONFIG_SYS_FSL_DDR3 || CONFIG_SYS_FSL_DDR4 */
+#else /* CONFIG_SYS_FSL_DDR3 */
static const struct dynamic_odt single_Q[4] = {
{0, 0, 0, 0},
{0, 0, 0, 0},
diff --git a/drivers/net/fsl-mc/dpio/qbman_portal.c b/drivers/net/fsl-mc/dpio/qbman_portal.c
index 5fa8d95..449ff8a 100644
--- a/drivers/net/fsl-mc/dpio/qbman_portal.c
+++ b/drivers/net/fsl-mc/dpio/qbman_portal.c
@@ -117,7 +117,7 @@ void qbman_swp_mc_submit(struct qbman_swp *p, void *cmd, uint32_t cmd_verb)
{
uint32_t *v = cmd;
#ifdef QBMAN_CHECKING
- BUG_ON(!p->mc.check != swp_mc_can_submit);
+ BUG_ON(p->mc.check != swp_mc_can_submit);
#endif
lwsync();
/* TBD: "|=" is going to hurt performance. Need to move as many fields
diff --git a/drivers/serial/serial_stm32.c b/drivers/serial/serial_stm32.c
index 8b2830b..91a5dde 100644
--- a/drivers/serial/serial_stm32.c
+++ b/drivers/serial/serial_stm32.c
@@ -1,45 +1,18 @@
/*
* (C) Copyright 2015
- * Kamil Lulko, <rev13@wp.pl>
+ * Kamil Lulko, <kamil.lulko@gmail.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
+#include <dm.h>
#include <asm/io.h>
#include <serial.h>
#include <asm/arch/stm32.h>
+#include <dm/platform_data/serial_stm32.h>
-/*
- * Set up the usart port
- */
-#if (CONFIG_STM32_USART >= 1) && (CONFIG_STM32_USART <= 6)
-#define USART_PORT (CONFIG_STM32_USART - 1)
-#else
-#define USART_PORT 0
-#endif
-/*
- * Set up the usart base address
- *
- * --STM32_USARTD_BASE means default setting
- */
-#define STM32_USART1_BASE (STM32_APB2PERIPH_BASE + 0x1000)
-#define STM32_USART2_BASE (STM32_APB1PERIPH_BASE + 0x4400)
-#define STM32_USART3_BASE (STM32_APB1PERIPH_BASE + 0x4800)
-#define STM32_USART6_BASE (STM32_APB2PERIPH_BASE + 0x1400)
-#define STM32_USARTD_BASE STM32_USART1_BASE
-/*
- * RCC USART specific definitions
- *
- * --RCC_ENR_USARTDEN means default setting
- */
-#define RCC_ENR_USART1EN (1 << 4)
-#define RCC_ENR_USART2EN (1 << 17)
-#define RCC_ENR_USART3EN (1 << 18)
-#define RCC_ENR_USART6EN (1 << 5)
-#define RCC_ENR_USARTDEN RCC_ENR_USART1EN
-
-struct stm32_serial {
+struct stm32_usart {
u32 sr;
u32 dr;
u32 brr;
@@ -49,120 +22,136 @@ struct stm32_serial {
u32 gtpr;
};
-#define USART_CR1_RE (1 << 2)
-#define USART_CR1_TE (1 << 3)
-#define USART_CR1_UE (1 << 13)
+#define USART_CR1_RE (1 << 2)
+#define USART_CR1_TE (1 << 3)
+#define USART_CR1_UE (1 << 13)
#define USART_SR_FLAG_RXNE (1 << 5)
-#define USART_SR_FLAG_TXE (1 << 7)
+#define USART_SR_FLAG_TXE (1 << 7)
-#define USART_BRR_F_MASK 0xF
+#define USART_BRR_F_MASK 0xF
#define USART_BRR_M_SHIFT 4
#define USART_BRR_M_MASK 0xFFF0
DECLARE_GLOBAL_DATA_PTR;
-static const unsigned long usart_base[] = {
- STM32_USART1_BASE,
- STM32_USART2_BASE,
- STM32_USART3_BASE,
- STM32_USARTD_BASE,
- STM32_USARTD_BASE,
- STM32_USART6_BASE
-};
+#define MAX_SERIAL_PORTS 4
-static const unsigned long rcc_enr_en[] = {
- RCC_ENR_USART1EN,
- RCC_ENR_USART2EN,
- RCC_ENR_USART3EN,
- RCC_ENR_USARTDEN,
- RCC_ENR_USARTDEN,
- RCC_ENR_USART6EN
+/*
+ * RCC USART specific definitions
+ */
+#define RCC_ENR_USART1EN (1 << 4)
+#define RCC_ENR_USART2EN (1 << 17)
+#define RCC_ENR_USART3EN (1 << 18)
+#define RCC_ENR_USART6EN (1 << 5)
+
+/* Array used to figure out which RCC bit needs to be set */
+static const unsigned long usart_port_rcc_pairs[MAX_SERIAL_PORTS][2] = {
+ { STM32_USART1_BASE, RCC_ENR_USART1EN },
+ { STM32_USART2_BASE, RCC_ENR_USART2EN },
+ { STM32_USART3_BASE, RCC_ENR_USART3EN },
+ { STM32_USART6_BASE, RCC_ENR_USART6EN }
};
-static void stm32_serial_setbrg(void)
+static int stm32_serial_setbrg(struct udevice *dev, int baudrate)
{
- serial_init();
-}
+ struct stm32_serial_platdata *plat = dev->platdata;
+ struct stm32_usart *const usart = plat->base;
+ u32 clock, int_div, frac_div, tmp;
-static int stm32_serial_init(void)
-{
- struct stm32_serial *usart =
- (struct stm32_serial *)usart_base[USART_PORT];
- u32 clock, int_div, frac_div, tmp;
-
- if ((usart_base[USART_PORT] & STM32_BUS_MASK) ==
- STM32_APB1PERIPH_BASE) {
- setbits_le32(&STM32_RCC->apb1enr, rcc_enr_en[USART_PORT]);
+ if (((u32)usart & STM32_BUS_MASK) == STM32_APB1PERIPH_BASE)
clock = clock_get(CLOCK_APB1);
- } else if ((usart_base[USART_PORT] & STM32_BUS_MASK) ==
- STM32_APB2PERIPH_BASE) {
- setbits_le32(&STM32_RCC->apb2enr, rcc_enr_en[USART_PORT]);
+ else if (((u32)usart & STM32_BUS_MASK) == STM32_APB2PERIPH_BASE)
clock = clock_get(CLOCK_APB2);
- } else {
- return -1;
- }
+ else
+ return -EINVAL;
- int_div = (25 * clock) / (4 * gd->baudrate);
+ int_div = (25 * clock) / (4 * baudrate);
tmp = ((int_div / 100) << USART_BRR_M_SHIFT) & USART_BRR_M_MASK;
frac_div = int_div - (100 * (tmp >> USART_BRR_M_SHIFT));
tmp |= (((frac_div * 16) + 50) / 100) & USART_BRR_F_MASK;
-
writel(tmp, &usart->brr);
- setbits_le32(&usart->cr1, USART_CR1_RE | USART_CR1_TE | USART_CR1_UE);
return 0;
}
-static int stm32_serial_getc(void)
+static int stm32_serial_getc(struct udevice *dev)
{
- struct stm32_serial *usart =
- (struct stm32_serial *)usart_base[USART_PORT];
- while ((readl(&usart->sr) & USART_SR_FLAG_RXNE) == 0)
- ;
+ struct stm32_serial_platdata *plat = dev->platdata;
+ struct stm32_usart *const usart = plat->base;
+
+ if ((readl(&usart->sr) & USART_SR_FLAG_RXNE) == 0)
+ return -EAGAIN;
+
return readl(&usart->dr);
}
-static void stm32_serial_putc(const char c)
+static int stm32_serial_putc(struct udevice *dev, const char c)
{
- struct stm32_serial *usart =
- (struct stm32_serial *)usart_base[USART_PORT];
+ struct stm32_serial_platdata *plat = dev->platdata;
+ struct stm32_usart *const usart = plat->base;
- if (c == '\n')
- stm32_serial_putc('\r');
+ if ((readl(&usart->sr) & USART_SR_FLAG_TXE) == 0)
+ return -EAGAIN;
- while ((readl(&usart->sr) & USART_SR_FLAG_TXE) == 0)
- ;
writel(c, &usart->dr);
+
+ return 0;
}
-static int stm32_serial_tstc(void)
+static int stm32_serial_pending(struct udevice *dev, bool input)
{
- struct stm32_serial *usart =
- (struct stm32_serial *)usart_base[USART_PORT];
- u8 ret;
+ struct stm32_serial_platdata *plat = dev->platdata;
+ struct stm32_usart *const usart = plat->base;
- ret = readl(&usart->sr) & USART_SR_FLAG_RXNE;
- return ret;
+ if (input)
+ return readl(&usart->sr) & USART_SR_FLAG_RXNE ? 1 : 0;
+ else
+ return readl(&usart->sr) & USART_SR_FLAG_TXE ? 0 : 1;
}
-static struct serial_device stm32_serial_drv = {
- .name = "stm32_serial",
- .start = stm32_serial_init,
- .stop = NULL,
- .setbrg = stm32_serial_setbrg,
- .putc = stm32_serial_putc,
- .puts = default_serial_puts,
- .getc = stm32_serial_getc,
- .tstc = stm32_serial_tstc,
-};
-
-void stm32_serial_initialize(void)
+static int stm32_serial_probe(struct udevice *dev)
{
- serial_register(&stm32_serial_drv);
-}
+ struct stm32_serial_platdata *plat = dev->platdata;
+ struct stm32_usart *const usart = plat->base;
+ int usart_port = -1;
+ int i;
+
+ for (i = 0; i < MAX_SERIAL_PORTS; i++) {
+ if ((u32)usart == usart_port_rcc_pairs[i][0]) {
+ usart_port = i;
+ break;
+ }
+ }
-__weak struct serial_device *default_serial_console(void)
-{
- return &stm32_serial_drv;
+ if (usart_port == -1)
+ return -EINVAL;
+
+ if (((u32)usart & STM32_BUS_MASK) == STM32_APB1PERIPH_BASE)
+ setbits_le32(&STM32_RCC->apb1enr,
+ usart_port_rcc_pairs[usart_port][1]);
+ else if (((u32)usart & STM32_BUS_MASK) == STM32_APB2PERIPH_BASE)
+ setbits_le32(&STM32_RCC->apb2enr,
+ usart_port_rcc_pairs[usart_port][1]);
+ else
+ return -EINVAL;
+
+ setbits_le32(&usart->cr1, USART_CR1_RE | USART_CR1_TE | USART_CR1_UE);
+
+ return 0;
}
+
+static const struct dm_serial_ops stm32_serial_ops = {
+ .putc = stm32_serial_putc,
+ .pending = stm32_serial_pending,
+ .getc = stm32_serial_getc,
+ .setbrg = stm32_serial_setbrg,
+};
+
+U_BOOT_DRIVER(serial_stm32) = {
+ .name = "serial_stm32",
+ .id = UCLASS_SERIAL,
+ .ops = &stm32_serial_ops,
+ .probe = stm32_serial_probe,
+ .flags = DM_FLAG_PRE_RELOC,
+};
diff --git a/drivers/spi/fsl_qspi.c b/drivers/spi/fsl_qspi.c
index ed39114..feec3e8 100644
--- a/drivers/spi/fsl_qspi.c
+++ b/drivers/spi/fsl_qspi.c
@@ -13,6 +13,7 @@
#include <linux/sizes.h>
#include <dm.h>
#include <errno.h>
+#include <watchdog.h>
#include "fsl_qspi.h"
DECLARE_GLOBAL_DATA_PTR;
@@ -527,6 +528,8 @@ static void qspi_op_read(struct fsl_qspi_priv *priv, u32 *rxbuf, u32 len)
to_or_from = priv->sf_addr + priv->cur_amba_base;
while (len > 0) {
+ WATCHDOG_RESET();
+
qspi_write32(priv->flags, &regs->sfar, to_or_from);
size = (len > RX_BUFFER_SIZE) ?
@@ -574,6 +577,8 @@ static void qspi_op_write(struct fsl_qspi_priv *priv, u8 *txbuf, u32 len)
status_reg = 0;
while ((status_reg & FLASH_STATUS_WEL) != FLASH_STATUS_WEL) {
+ WATCHDOG_RESET();
+
qspi_write32(priv->flags, &regs->ipcr,
(SEQID_WREN << QSPI_IPCR_SEQID_SHIFT) | 0);
while (qspi_read32(priv->flags, &regs->sr) & QSPI_SR_BUSY_MASK)