From 19601dd99c8169e27457a96f03f0c3fef908a4c6 Mon Sep 17 00:00:00 2001 From: York Sun Date: Wed, 4 Nov 2015 10:03:17 -0800 Subject: [PATCH 01/31] driver/ddr/fsl: Update DDR4 RTT values DDR4 has different RTT value and code according to JEDEC spec. Update the macros and options . Signed-off-by: York Sun --- drivers/ddr/fsl/options.c | 237 +++++++++++++++++++++++++++++++++++++- include/fsl_ddr_sdram.h | 9 ++ 2 files changed, 244 insertions(+), 2 deletions(-) diff --git a/drivers/ddr/fsl/options.c b/drivers/ddr/fsl/options.c index 3c09c643fe..791d644101 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/include/fsl_ddr_sdram.h b/include/fsl_ddr_sdram.h index c79fce0898..4b022d4639 100644 --- a/include/fsl_ddr_sdram.h +++ b/include/fsl_ddr_sdram.h @@ -33,6 +33,15 @@ #define DDR3_RTT_20_OHM 4 /* RTT_Nom = RZQ/12 */ #define DDR3_RTT_30_OHM 5 /* RTT_Nom = RZQ/8 */ +#define DDR4_RTT_OFF 0 +#define DDR4_RTT_60_OHM 1 /* RZQ/4 */ +#define DDR4_RTT_120_OHM 2 /* RZQ/2 */ +#define DDR4_RTT_40_OHM 3 /* RZQ/6 */ +#define DDR4_RTT_240_OHM 4 /* RZQ/1 */ +#define DDR4_RTT_48_OHM 5 /* RZQ/5 */ +#define DDR4_RTT_80_OHM 6 /* RZQ/3 */ +#define DDR4_RTT_34_OHM 7 /* RZQ/7 */ + #define DDR2_RTT_OFF 0 #define DDR2_RTT_75_OHM 1 #define DDR2_RTT_150_OHM 2 From 0fb7197436378eeb92ff8e2c6a6f6490b31eef1c Mon Sep 17 00:00:00 2001 From: York Sun Date: Wed, 4 Nov 2015 10:03:18 -0800 Subject: [PATCH 02/31] driver/ddr/fsl: Update DDR4 MR6 for Vref range MR6 bit 6 is set accrodingly for range 1 or 2, per JEDEC spec. Signed-off-by: York Sun --- drivers/ddr/fsl/ctrl_regs.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/ddr/fsl/ctrl_regs.c b/drivers/ddr/fsl/ctrl_regs.c index 8543679108..36bf647791 100644 --- a/drivers/ddr/fsl/ctrl_regs.c +++ b/drivers/ddr/fsl/ctrl_regs.c @@ -1186,6 +1186,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) From 8a51429e0094746c035ba96af5999432b3b3480b Mon Sep 17 00:00:00 2001 From: York Sun Date: Wed, 4 Nov 2015 10:03:19 -0800 Subject: [PATCH 03/31] driver/ddr/fsl: Update MR5 RTT park For four chip-selects enabled case, RTT is parked on all of them. Signed-off-by: York Sun --- drivers/ddr/fsl/ctrl_regs.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/drivers/ddr/fsl/ctrl_regs.c b/drivers/ddr/fsl/ctrl_regs.c index 36bf647791..99714bf4c1 100644 --- a/drivers/ddr/fsl/ctrl_regs.c +++ b/drivers/ddr/fsl/ctrl_regs.c @@ -1117,10 +1117,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 +1138,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 +1149,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; } From 7cc079989d4e99968f0efb08eff1cd342ce26ac3 Mon Sep 17 00:00:00 2001 From: York Sun Date: Wed, 4 Nov 2015 10:03:20 -0800 Subject: [PATCH 04/31] driver/ddr/fsl: Update workaround for A008511 for vref range The workaround requires different setting for range 1 vs 2. Also adjust timeout value for waiting for controller to be idle. Signed-off-by: York Sun --- drivers/ddr/fsl/fsl_ddr_gen4.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/drivers/ddr/fsl/fsl_ddr_gen4.c b/drivers/ddr/fsl/fsl_ddr_gen4.c index 1de7b72b4c..50f4671c8f 100644 --- a/drivers/ddr/fsl/fsl_ddr_gen4.c +++ b/drivers/ddr/fsl/fsl_ddr_gen4.c @@ -54,6 +54,9 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, #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; @@ -307,16 +310,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 +335,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 +355,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) { From 6c6e006a2083f2da7b4f66c6bb82ce8b3fb713a3 Mon Sep 17 00:00:00 2001 From: York Sun Date: Wed, 4 Nov 2015 10:03:21 -0800 Subject: [PATCH 05/31] driver/ddr/fsl: Update timing config for heavy load In case four chip-selects are all active, the turnaround times need to increase to avoid overlapping under heavy load. Signed-off-by: York Sun --- drivers/ddr/fsl/ctrl_regs.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/drivers/ddr/fsl/ctrl_regs.c b/drivers/ddr/fsl/ctrl_regs.c index 99714bf4c1..0bfcd3413c 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; /* @@ -1822,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) @@ -1835,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); From c4243ac9e2713897a63dcdc3a96bf088fdb49866 Mon Sep 17 00:00:00 2001 From: York Sun Date: Wed, 4 Nov 2015 10:03:22 -0800 Subject: [PATCH 06/31] armv8/ls2080aqds: Update DDR settings for four chip-select case When 4 chip-selects are used, vref should use range 1 and CDT uses 80 ohm, and 2T timing is enabled. Signed-off-by: York Sun --- board/freescale/ls2080aqds/ddr.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/board/freescale/ls2080aqds/ddr.c b/board/freescale/ls2080aqds/ddr.c index ae681de35e..7e67ee0335 100644 --- a/board/freescale/ls2080aqds/ddr.c +++ b/board/freescale/ls2080aqds/ddr.c @@ -134,10 +134,18 @@ found: popts->zq_en = 1; if (ddr_freq < 2350) { - popts->ddr_cdr1 = DDR_CDR1_DHC_EN | - DDR_CDR1_ODT(DDR_CDR_ODT_60ohm); - popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_60ohm) | - DDR_CDR2_VREF_RANGE_2; + if (pdimm[0].n_ranks == 2 && pdimm[1].n_ranks == 2) { + /* four chip-selects */ + popts->ddr_cdr1 = DDR_CDR1_DHC_EN | + DDR_CDR1_ODT(DDR_CDR_ODT_80ohm); + popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_80ohm); + popts->twot_en = 1; /* enable 2T timing */ + } else { + popts->ddr_cdr1 = DDR_CDR1_DHC_EN | + DDR_CDR1_ODT(DDR_CDR_ODT_60ohm); + popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_60ohm) | + DDR_CDR2_VREF_RANGE_2; + } } else { popts->ddr_cdr1 = DDR_CDR1_DHC_EN | DDR_CDR1_ODT(DDR_CDR_ODT_100ohm); From 3901978d42b7008b13e7e9b67bea12a51cc5847b Mon Sep 17 00:00:00 2001 From: York Sun Date: Wed, 4 Nov 2015 10:03:23 -0800 Subject: [PATCH 07/31] armv8/ls2080ardb: Update DDR settings for four chip-select case When 4 chip-selects are used, vref should use range 1 and CDT uses 80 ohm, and 2T timing is enabled. Signed-off-by: York Sun --- board/freescale/ls2080ardb/ddr.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/board/freescale/ls2080ardb/ddr.c b/board/freescale/ls2080ardb/ddr.c index ae681de35e..76f3b59e4e 100644 --- a/board/freescale/ls2080ardb/ddr.c +++ b/board/freescale/ls2080ardb/ddr.c @@ -134,10 +134,18 @@ found: popts->zq_en = 1; if (ddr_freq < 2350) { - popts->ddr_cdr1 = DDR_CDR1_DHC_EN | - DDR_CDR1_ODT(DDR_CDR_ODT_60ohm); - popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_60ohm) | - DDR_CDR2_VREF_RANGE_2; + if (pdimm[0].n_ranks == 2 && pdimm[1].n_ranks == 2) { + /* four chip-selects */ + popts->ddr_cdr1 = DDR_CDR1_DHC_EN | + DDR_CDR1_ODT(DDR_CDR_ODT_80ohm); + popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_80ohm); + popts->twot_en = 1; /* enable 2T timing */ + } else { + popts->ddr_cdr1 = DDR_CDR1_DHC_EN | + DDR_CDR1_ODT(DDR_CDR_ODT_60ohm); + popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_60ohm) | + DDR_CDR2_VREF_RANGE_2; + } } else { popts->ddr_cdr1 = DDR_CDR1_DHC_EN | DDR_CDR1_ODT(DDR_CDR_ODT_100ohm); From 1aaf3f9ae471929a70509f86a48a61da6fbfb19f Mon Sep 17 00:00:00 2001 From: Shaohui Xie Date: Tue, 10 Nov 2015 19:20:16 +0800 Subject: [PATCH 08/31] freescale: fman: make sure phy-handle property is big endian When creating phy-handle property, an unsigned int value is created by fdt_create_phandle, and memcpy is used to get the value, since DTS is big endian, the value cannot be used directly on little endian SoCs, it should be converted by cpu_to_fdt32. Signed-off-by: Shaohui Xie Reviewed-by: York Sun --- board/freescale/common/fman.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/board/freescale/common/fman.c b/board/freescale/common/fman.c index 26cf5175c7..b5025ab14e 100644 --- a/board/freescale/common/fman.c +++ b/board/freescale/common/fman.c @@ -52,6 +52,8 @@ int fdt_set_phy_handle(void *fdt, char *compat, phys_addr_t addr, if (!ph) return -FDT_ERR_BADPHANDLE; + ph = cpu_to_fdt32(ph); + offset = fdt_node_offset_by_compat_reg(fdt, compat, addr); if (offset < 0) return offset; From 0c028a03284aabceb89a85736e23661d6fe7915e Mon Sep 17 00:00:00 2001 From: Shengzhou Liu Date: Fri, 20 Nov 2015 15:52:02 +0800 Subject: [PATCH 09/31] arm: ls102x: add get_svr and IS_SVR_REV helper Signed-off-by: Shengzhou Liu Reviewed-by: York Sun --- arch/arm/cpu/armv7/ls102xa/cpu.c | 8 ++++++++ arch/arm/include/asm/arch-ls102xa/immap_ls102xa.h | 5 +++++ 2 files changed, 13 insertions(+) diff --git a/arch/arm/cpu/armv7/ls102xa/cpu.c b/arch/arm/cpu/armv7/ls102xa/cpu.c index 2215fe93cf..2f0df65582 100644 --- a/arch/arm/cpu/armv7/ls102xa/cpu.c +++ b/arch/arm/cpu/armv7/ls102xa/cpu.c @@ -218,6 +218,14 @@ void enable_caches(void) } #endif /* #ifndef CONFIG_SYS_DCACHE_OFF */ + +uint get_svr(void) +{ + struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); + + return in_be32(&gur->svr); +} + #if defined(CONFIG_DISPLAY_CPUINFO) int print_cpuinfo(void) { diff --git a/arch/arm/include/asm/arch-ls102xa/immap_ls102xa.h b/arch/arm/include/asm/arch-ls102xa/immap_ls102xa.h index 1bcdf04dd4..c12706d908 100644 --- a/arch/arm/include/asm/arch-ls102xa/immap_ls102xa.h +++ b/arch/arm/include/asm/arch-ls102xa/immap_ls102xa.h @@ -11,6 +11,8 @@ #define SVR_MIN(svr) (((svr) >> 0) & 0xf) #define SVR_SOC_VER(svr) (((svr) >> 8) & 0x7ff) #define IS_E_PROCESSOR(svr) (svr & 0x80000) +#define IS_SVR_REV(svr, maj, min) \ + ((SVR_MAJ(svr) == maj) && (SVR_MIN(svr) == min)) #define SOC_VER_SLS1020 0x00 #define SOC_VER_LS1020 0x10 @@ -422,4 +424,7 @@ struct ccsr_ahci { u32 pberr; /* port 0/1 BIST error */ u32 cmds; /* port 0/1 CMD status error */ }; + +uint get_svr(void); + #endif /* __ASM_ARCH_LS102XA_IMMAP_H_ */ From a07bdad749ea080e009a82ba40e791dc7361ab54 Mon Sep 17 00:00:00 2001 From: Shengzhou Liu Date: Fri, 20 Nov 2015 15:52:03 +0800 Subject: [PATCH 10/31] fsl/errata: move fsl_errata.h to common directory move arch/powerpc/include/asm/fsl_errata.h to include/fsl_errata.h to make it public for both ARM and POWER SoCs. Signed-off-by: Shengzhou Liu [York Sun: fix soc.h path in fsl_errata.h] Reviewed-by: York Sun --- arch/powerpc/cpu/mpc85xx/cmd_errata.c | 2 +- arch/powerpc/cpu/mpc85xx/cpu_init.c | 2 +- arch/powerpc/cpu/mpc85xx/fsl_corenet2_serdes.c | 2 +- .../powerpc/include/asm => include}/fsl_errata.h | 16 ++++++++++++---- 4 files changed, 15 insertions(+), 7 deletions(-) rename {arch/powerpc/include/asm => include}/fsl_errata.h (79%) diff --git a/arch/powerpc/cpu/mpc85xx/cmd_errata.c b/arch/powerpc/cpu/mpc85xx/cmd_errata.c index b368562a24..a4935567f6 100644 --- a/arch/powerpc/cpu/mpc85xx/cmd_errata.c +++ b/arch/powerpc/cpu/mpc85xx/cmd_errata.c @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include #include #include "fsl_corenet_serdes.h" diff --git a/arch/powerpc/cpu/mpc85xx/cpu_init.c b/arch/powerpc/cpu/mpc85xx/cpu_init.c index 4cf8853b72..13a7d0f664 100644 --- a/arch/powerpc/cpu/mpc85xx/cpu_init.c +++ b/arch/powerpc/cpu/mpc85xx/cpu_init.c @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/powerpc/cpu/mpc85xx/fsl_corenet2_serdes.c b/arch/powerpc/cpu/mpc85xx/fsl_corenet2_serdes.c index acb1353e5d..f89c94e7b3 100644 --- a/arch/powerpc/cpu/mpc85xx/fsl_corenet2_serdes.c +++ b/arch/powerpc/cpu/mpc85xx/fsl_corenet2_serdes.c @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include "fsl_corenet2_serdes.h" #ifdef CONFIG_SYS_FSL_SRDS_1 diff --git a/arch/powerpc/include/asm/fsl_errata.h b/include/fsl_errata.h similarity index 79% rename from arch/powerpc/include/asm/fsl_errata.h rename to include/fsl_errata.h index 4861e3bf8d..aebe3d2925 100644 --- a/arch/powerpc/include/asm/fsl_errata.h +++ b/include/fsl_errata.h @@ -1,14 +1,21 @@ /* - * Copyright 2013 Freescale Semiconductor, Inc. + * Copyright 2013 - 2015 Freescale Semiconductor, Inc. * * SPDX-License-Identifier: GPL-2.0+ */ -#ifndef _ASM_FSL_ERRATA_H -#define _ASM_FSL_ERRATA_H +#ifndef _FSL_ERRATA_H +#define _FSL_ERRATA_H #include +#if defined(CONFIG_PPC) #include +#elif defined(CONFIG_LS102XA) +#include +#elif defined(CONFIG_FSL_LAYERSCAPE) +#include +#endif + #ifdef CONFIG_SYS_FSL_ERRATUM_A006379 static inline bool has_erratum_a006379(void) @@ -26,7 +33,6 @@ static inline bool has_erratum_a006379(void) return false; } #endif -#endif #ifdef CONFIG_SYS_FSL_ERRATUM_A007186 static inline bool has_erratum_a007186(void) @@ -51,3 +57,5 @@ static inline bool has_erratum_a007186(void) return false; } #endif + +#endif /* _FSL_ERRATA_H */ From a46b1852de967f8a7de26e0b46e864c794a18c16 Mon Sep 17 00:00:00 2001 From: Shengzhou Liu Date: Fri, 20 Nov 2015 15:52:04 +0800 Subject: [PATCH 11/31] fsl/ddr: updated ddr errata-A008378 for arm and power SoCs DDR errata-A008378 applies to LS1021-20-22A-R1.0, T1023-R1.0, T1024-R1.0, T1040-42-20-22-R1.0/R1.1, it has been fixed on LS102x Rev2. Signed-off-by: Shengzhou Liu Reviewed-by: York Sun --- arch/powerpc/include/asm/config_mpc85xx.h | 2 ++ drivers/ddr/fsl/fsl_ddr_gen4.c | 9 ++++--- include/fsl_errata.h | 31 +++++++++++++++++++++++ 3 files changed, 39 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/include/asm/config_mpc85xx.h b/arch/powerpc/include/asm/config_mpc85xx.h index 7a5487be88..674fac8828 100644 --- a/arch/powerpc/include/asm/config_mpc85xx.h +++ b/arch/powerpc/include/asm/config_mpc85xx.h @@ -807,6 +807,7 @@ defined(CONFIG_PPC_T1020) || defined(CONFIG_PPC_T1022) #define MAX_QE_RISC 1 #define QE_NUM_OF_SNUM 28 #define CONFIG_SYS_FSL_SFP_VER_3_0 +#define CONFIG_SYS_FSL_ERRATUM_A008378 #elif defined(CONFIG_PPC_T1024) || defined(CONFIG_PPC_T1023) ||\ defined(CONFIG_PPC_T1014) || defined(CONFIG_PPC_T1013) @@ -854,6 +855,7 @@ defined(CONFIG_PPC_T1014) || defined(CONFIG_PPC_T1013) #define MAX_QE_RISC 1 #define QE_NUM_OF_SNUM 28 #define CONFIG_SYS_FSL_SFP_VER_3_0 +#define CONFIG_SYS_FSL_ERRATUM_A008378 #elif defined(CONFIG_PPC_T2080) || defined(CONFIG_PPC_T2081) #define CONFIG_E6500 diff --git a/drivers/ddr/fsl/fsl_ddr_gen4.c b/drivers/ddr/fsl/fsl_ddr_gen4.c index 50f4671c8f..0755ff7c24 100644 --- a/drivers/ddr/fsl/fsl_ddr_gen4.c +++ b/drivers/ddr/fsl/fsl_ddr_gen4.c @@ -10,6 +10,7 @@ #include #include #include +#include #ifdef CONFIG_SYS_FSL_ERRATUM_A008511 static void set_wait_for_bits_clear(void *ptr, u32 value, u32 bits) @@ -238,9 +239,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 diff --git a/include/fsl_errata.h b/include/fsl_errata.h index aebe3d2925..8441f91029 100644 --- a/include/fsl_errata.h +++ b/include/fsl_errata.h @@ -58,4 +58,35 @@ static inline bool has_erratum_a007186(void) } #endif +#ifdef CONFIG_SYS_FSL_ERRATUM_A008378 +static inline bool has_erratum_a008378(void) +{ + u32 svr = get_svr(); + u32 soc = SVR_SOC_VER(svr); + + + switch (soc) { +#ifdef CONFIG_LS102XA + case SOC_VER_LS1020: + case SOC_VER_LS1021: + case SOC_VER_LS1022: + case SOC_VER_SLS1020: + return IS_SVR_REV(svr, 1, 0); +#endif +#ifdef CONFIG_PPC + case SVR_T1023: + case SVR_T1024: + return IS_SVR_REV(svr, 1, 0); + case SVR_T1020: + case SVR_T1022: + case SVR_T1040: + case SVR_T1042: + return IS_SVR_REV(svr, 1, 0) || IS_SVR_REV(svr, 1, 1); +#endif + default: + return false; + } +} +#endif + #endif /* _FSL_ERRATA_H */ From e994dddbbe031c818758b2ea91f59697b07d94b6 Mon Sep 17 00:00:00 2001 From: Shaohui Xie Date: Mon, 23 Nov 2015 15:23:48 +0800 Subject: [PATCH 12/31] armv8/ls1043ardb: Add support for >2GB memory This patch also expose the complete DDR region(s) to Linux. Signed-off-by: Shaohui Xie Signed-off-by: Mingkai Hu Reviewed-by: York Sun --- arch/arm/include/asm/arch-fsl-layerscape/config.h | 4 ++-- board/freescale/ls1043ardb/ddr.c | 9 ++++++++- board/freescale/ls1043ardb/ls1043ardb.c | 10 ++++++++++ include/configs/ls1043a_common.h | 1 + include/configs/ls1043ardb.h | 2 +- 5 files changed, 22 insertions(+), 4 deletions(-) diff --git a/arch/arm/include/asm/arch-fsl-layerscape/config.h b/arch/arm/include/asm/arch-fsl-layerscape/config.h index b5a2d28c08..7217a87502 100644 --- a/arch/arm/include/asm/arch-fsl-layerscape/config.h +++ b/arch/arm/include/asm/arch-fsl-layerscape/config.h @@ -126,8 +126,8 @@ #define CONFIG_SYS_FSL_OCRAM_BASE 0x10000000 /* initial RAM */ #define CONFIG_SYS_FSL_OCRAM_SIZE 0x200000 /* 2 MiB */ #define CONFIG_SYS_FSL_DDR_BE -#define CONFIG_SYS_LS1_DDR_BLOCK1_SIZE ((phys_size_t)2 << 30) -#define CONFIG_MAX_MEM_MAPPED CONFIG_SYS_LS1_DDR_BLOCK1_SIZE +#define CONFIG_SYS_DDR_BLOCK1_SIZE ((phys_size_t)2 << 30) +#define CONFIG_MAX_MEM_MAPPED CONFIG_SYS_DDR_BLOCK1_SIZE #define CONFIG_SYS_FSL_CCSR_GUR_BE #define CONFIG_SYS_FSL_CCSR_SCFG_BE diff --git a/board/freescale/ls1043ardb/ddr.c b/board/freescale/ls1043ardb/ddr.c index b181579e8e..249d0565fc 100644 --- a/board/freescale/ls1043ardb/ddr.c +++ b/board/freescale/ls1043ardb/ddr.c @@ -187,5 +187,12 @@ phys_size_t initdram(int board_type) void dram_init_banksize(void) { gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE; - gd->bd->bi_dram[0].size = gd->ram_size; + if (gd->ram_size > CONFIG_SYS_DDR_BLOCK1_SIZE) { + gd->bd->bi_dram[0].size = CONFIG_SYS_DDR_BLOCK1_SIZE; + gd->bd->bi_dram[1].start = CONFIG_SYS_DDR_BLOCK2_BASE; + gd->bd->bi_dram[1].size = gd->ram_size - + CONFIG_SYS_DDR_BLOCK1_SIZE; + } else { + gd->bd->bi_dram[0].size = gd->ram_size; + } } diff --git a/board/freescale/ls1043ardb/ls1043ardb.c b/board/freescale/ls1043ardb/ls1043ardb.c index cdd50d6d18..4556ea8ad1 100644 --- a/board/freescale/ls1043ardb/ls1043ardb.c +++ b/board/freescale/ls1043ardb/ls1043ardb.c @@ -130,6 +130,16 @@ int misc_init_r(void) int ft_board_setup(void *blob, bd_t *bd) { + u64 base[CONFIG_NR_DRAM_BANKS]; + u64 size[CONFIG_NR_DRAM_BANKS]; + + /* fixup DT for the two DDR banks */ + base[0] = gd->bd->bi_dram[0].start; + size[0] = gd->bd->bi_dram[0].size; + base[1] = gd->bd->bi_dram[1].start; + size[1] = gd->bd->bi_dram[1].size; + + fdt_fixup_memory_banks(blob, base, size, 2); ft_cpu_setup(blob, bd); #ifdef CONFIG_SYS_DPAA_FMAN diff --git a/include/configs/ls1043a_common.h b/include/configs/ls1043a_common.h index 6b9856a18f..677d28113c 100644 --- a/include/configs/ls1043a_common.h +++ b/include/configs/ls1043a_common.h @@ -44,6 +44,7 @@ #define CONFIG_SYS_DDR_SDRAM_BASE 0x80000000 #define CONFIG_SYS_FSL_DDR_SDRAM_BASE_PHY 0 #define CONFIG_SYS_SDRAM_BASE CONFIG_SYS_DDR_SDRAM_BASE +#define CONFIG_SYS_DDR_BLOCK2_BASE 0x880000000ULL #define CPU_RELEASE_ADDR secondary_boot_func diff --git a/include/configs/ls1043ardb.h b/include/configs/ls1043ardb.h index 7d113a0737..683407499a 100644 --- a/include/configs/ls1043ardb.h +++ b/include/configs/ls1043ardb.h @@ -27,7 +27,7 @@ #define CONFIG_DIMM_SLOTS_PER_CTLR 1 /* Physical Memory Map */ #define CONFIG_CHIP_SELECTS_PER_CTRL 4 -#define CONFIG_NR_DRAM_BANKS 1 +#define CONFIG_NR_DRAM_BANKS 2 #define CONFIG_SYS_SPD_BUS_NUM 0 From b22b1dc6b7b5a74c7655a85b312ff3df0e69c4fe Mon Sep 17 00:00:00 2001 From: Pratiyush Mohan Srivastava Date: Sat, 31 Oct 2015 15:50:18 +0530 Subject: [PATCH 13/31] Enable console log from earlyconsole in Linux bootargs Remove 115200 from "earlycon" to avoid loss of initial log messages during linux kernel 4.1 bootup Signed-off-by: Pratiyush Mohan Srivastava Reviewed-by: York Sun --- include/configs/ls2080a_common.h | 2 +- include/configs/ls2080ardb.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/configs/ls2080a_common.h b/include/configs/ls2080a_common.h index 2e1fe7a4b1..969aed698c 100644 --- a/include/configs/ls2080a_common.h +++ b/include/configs/ls2080a_common.h @@ -271,7 +271,7 @@ unsigned long long get_qixis_addr(void); "console=ttyAMA0,38400n8\0" #define CONFIG_BOOTARGS "console=ttyS0,115200 root=/dev/ram0 " \ - "earlycon=uart8250,mmio,0x21c0500,115200 " \ + "earlycon=uart8250,mmio,0x21c0500" \ "ramdisk_size=0x2000000 default_hugepagesz=2m" \ " hugepagesz=2m hugepages=16" #define CONFIG_BOOTCOMMAND "cp.b $kernel_start $kernel_load " \ diff --git a/include/configs/ls2080ardb.h b/include/configs/ls2080ardb.h index 44a47d5889..faccc6f35b 100644 --- a/include/configs/ls2080ardb.h +++ b/include/configs/ls2080ardb.h @@ -313,7 +313,7 @@ unsigned long get_board_sys_clk(void); #undef CONFIG_BOOTARGS #define CONFIG_BOOTARGS "console=ttyS1,115200 root=/dev/ram0 " \ - "earlycon=uart8250,mmio,0x21c0600,115200 " \ + "earlycon=uart8250,mmio,0x21c0600" \ "ramdisk_size=0x2000000 default_hugepagesz=2m" \ " hugepagesz=2m hugepages=16" From 1a338921642bf622230d91e5eb16b8b5250b44a5 Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Sat, 28 Nov 2015 08:04:41 -0500 Subject: [PATCH 14/31] fsl_*_serdes.c: Modify memset call in serdes_init GCC 5.x does not like sizeof(array_variable) and errors out. Change these calls to be instead sizeof(u8) (as that's what serdes_prtcl_map is) * SERDES_PRCTL_COUNT (the number of array elements). Cc: York Sun Signed-off-by: Tom Rini Reviewed-by: Bin Meng Reviewed-by: York Sun --- arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch2_serdes.c | 2 +- arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch3_serdes.c | 2 +- arch/powerpc/cpu/mpc85xx/fsl_corenet2_serdes.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch2_serdes.c b/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch2_serdes.c index f7178d1470..fe3444a91e 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch2_serdes.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch2_serdes.c @@ -86,7 +86,7 @@ void serdes_init(u32 sd, u32 sd_addr, u32 sd_prctl_mask, u32 sd_prctl_shift, u32 cfg; int lane; - memset(serdes_prtcl_map, 0, sizeof(serdes_prtcl_map)); + memset(serdes_prtcl_map, 0, sizeof(u8) * SERDES_PRCTL_COUNT); cfg = gur_in32(&gur->rcwsr[4]) & sd_prctl_mask; cfg >>= sd_prctl_shift; diff --git a/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch3_serdes.c b/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch3_serdes.c index 918e889052..be6acc63fe 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch3_serdes.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch3_serdes.c @@ -79,7 +79,7 @@ void serdes_init(u32 sd, u32 sd_addr, u32 sd_prctl_mask, u32 sd_prctl_shift, u32 cfg; int lane; - memset(serdes_prtcl_map, 0, sizeof(serdes_prtcl_map)); + memset(serdes_prtcl_map, 0, sizeof(u8) * SERDES_PRCTL_COUNT); cfg = gur_in32(&gur->rcwsr[28]) & sd_prctl_mask; cfg >>= sd_prctl_shift; diff --git a/arch/powerpc/cpu/mpc85xx/fsl_corenet2_serdes.c b/arch/powerpc/cpu/mpc85xx/fsl_corenet2_serdes.c index f89c94e7b3..9920839d68 100644 --- a/arch/powerpc/cpu/mpc85xx/fsl_corenet2_serdes.c +++ b/arch/powerpc/cpu/mpc85xx/fsl_corenet2_serdes.c @@ -184,7 +184,7 @@ void serdes_init(u32 sd, u32 sd_addr, u32 sd_prctl_mask, u32 sd_prctl_shift, u32 cfg; int lane; - memset(serdes_prtcl_map, 0, sizeof(serdes_prtcl_map)); + memset(serdes_prtcl_map, 0, sizeof(u8) * SERDES_PRCTL_COUNT); #ifdef CONFIG_SYS_FSL_ERRATUM_A007186 struct ccsr_sfp_regs __iomem *sfp_regs = (struct ccsr_sfp_regs __iomem *)(CONFIG_SYS_SFP_ADDR); From b1f6be5ac8d657e312528ec3c4138c22c54d3f12 Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Sat, 28 Nov 2015 08:04:42 -0500 Subject: [PATCH 15/31] qbman_portal.c: Update BUG_ON() call in qbman_swp_mc_submit With gcc-5.x we get a warning about the ambiguity of BUG_ON(!a != b) and becomes BUG_ON((!a) != b). In this case reading of the function leads to us wanting to rewrite this as BUG_ON(a != b). Cc: Prabhakar Kushwaha Cc: Geoff Thorpe Cc: Haiying Wang Cc: Roy Pledge Cc: York Sun Signed-off-by: Tom Rini Reviewed-by: Bin Meng Reviewed-by: York Sun --- drivers/net/fsl-mc/dpio/qbman_portal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/fsl-mc/dpio/qbman_portal.c b/drivers/net/fsl-mc/dpio/qbman_portal.c index 5fa8d953e5..449ff8a8ba 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 From 7ba0261810dd8924f0aeeb4cf2f12253106170b3 Mon Sep 17 00:00:00 2001 From: Yao Yuan Date: Sat, 5 Dec 2015 14:59:10 +0800 Subject: [PATCH 16/31] arm: ls1021a: merge SoC specific code in a separate file Create a soc.c file to put the code for soc special settings. Signed-off-by: Yuan Yao Reviewed-by: York Sun --- arch/arm/cpu/armv7/ls102xa/Makefile | 1 + arch/arm/cpu/armv7/ls102xa/soc.c | 66 +++++++++++++++++++ .../include/asm/arch-ls102xa/ls102xa_soc.h | 12 ++++ board/freescale/ls1021aqds/ls1021aqds.c | 49 +------------- board/freescale/ls1021atwr/ls1021atwr.c | 42 +----------- 5 files changed, 83 insertions(+), 87 deletions(-) create mode 100644 arch/arm/cpu/armv7/ls102xa/soc.c create mode 100644 arch/arm/include/asm/arch-ls102xa/ls102xa_soc.h diff --git a/arch/arm/cpu/armv7/ls102xa/Makefile b/arch/arm/cpu/armv7/ls102xa/Makefile index 2311468ac9..02283009ab 100644 --- a/arch/arm/cpu/armv7/ls102xa/Makefile +++ b/arch/arm/cpu/armv7/ls102xa/Makefile @@ -8,6 +8,7 @@ obj-y += cpu.o obj-y += clock.o obj-y += timer.o obj-y += fsl_epu.o +obj-y += soc.o obj-$(CONFIG_SCSI_AHCI_PLAT) += ls102xa_sata.o obj-$(CONFIG_OF_LIBFDT) += fdt.o diff --git a/arch/arm/cpu/armv7/ls102xa/soc.c b/arch/arm/cpu/armv7/ls102xa/soc.c new file mode 100644 index 0000000000..0fdd6d4c86 --- /dev/null +++ b/arch/arm/cpu/armv7/ls102xa/soc.c @@ -0,0 +1,66 @@ +/* + * Copyright 2015 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include + +unsigned int get_soc_major_rev(void) +{ + struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); + unsigned int svr, major; + + svr = in_be32(&gur->svr); + major = SVR_MAJ(svr); + + return major; +} + +int arch_soc_init(void) +{ + struct ccsr_scfg *scfg = (struct ccsr_scfg *)CONFIG_SYS_FSL_SCFG_ADDR; + struct ccsr_cci400 *cci = (struct ccsr_cci400 *)CONFIG_SYS_CCI400_ADDR; + unsigned int major; + +#ifdef CONFIG_FSL_QSPI + out_be32(&scfg->qspi_cfg, SCFG_QSPI_CLKSEL); +#endif + +#ifdef CONFIG_FSL_DCU_FB + out_be32(&scfg->pixclkcr, SCFG_PIXCLKCR_PXCKEN); +#endif + + /* Configure Little endian for SAI, ASRC and SPDIF */ + out_be32(&scfg->endiancr, SCFG_ENDIANCR_LE); + + /* + * Enable snoop requests and DVM message requests for + * Slave insterface S4 (A7 core cluster) + */ + out_le32(&cci->slave[4].snoop_ctrl, + CCI400_DVM_MESSAGE_REQ_EN | CCI400_SNOOP_REQ_EN); + + major = get_soc_major_rev(); + if (major == SOC_MAJOR_VER_1_0) { + /* + * Set CCI-400 Slave interface S1, S2 Shareable Override + * Register All transactions are treated as non-shareable + */ + out_le32(&cci->slave[1].sha_ord, CCI400_SHAORD_NON_SHAREABLE); + out_le32(&cci->slave[2].sha_ord, CCI400_SHAORD_NON_SHAREABLE); + + /* Workaround for the issue that DDR could not respond to + * barrier transaction which is generated by executing DSB/ISB + * instruction. Set CCI-400 control override register to + * terminate the barrier transaction. After DDR is initialized, + * allow barrier transaction to DDR again */ + out_le32(&cci->ctrl_ord, CCI400_CTRLORD_TERM_BARRIER); + } + + return 0; +} diff --git a/arch/arm/include/asm/arch-ls102xa/ls102xa_soc.h b/arch/arm/include/asm/arch-ls102xa/ls102xa_soc.h new file mode 100644 index 0000000000..f10cb91f4b --- /dev/null +++ b/arch/arm/include/asm/arch-ls102xa/ls102xa_soc.h @@ -0,0 +1,12 @@ +/* + * Copyright 2015 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __FSL_LS102XA_SOC_H +#define __FSL_LS102XA_SOC_H + +unsigned int get_soc_major_rev(void); +int arch_soc_init(void); +#endif /* __FSL_LS102XA_SOC_H */ diff --git a/board/freescale/ls1021aqds/ls1021aqds.c b/board/freescale/ls1021aqds/ls1021aqds.c index d889ad50fd..be3358a564 100644 --- a/board/freescale/ls1021aqds/ls1021aqds.c +++ b/board/freescale/ls1021aqds/ls1021aqds.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -140,17 +141,6 @@ unsigned long get_board_ddr_clk(void) return 66666666; } -unsigned int get_soc_major_rev(void) -{ - struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); - unsigned int svr, major; - - svr = in_be32(&gur->svr); - major = SVR_MAJ(svr); - - return major; -} - int select_i2c_ch_pca9547(u8 ch) { int ret; @@ -193,8 +183,6 @@ int board_mmc_init(bd_t *bis) int board_early_init_f(void) { struct ccsr_scfg *scfg = (struct ccsr_scfg *)CONFIG_SYS_FSL_SCFG_ADDR; - struct ccsr_cci400 *cci = (struct ccsr_cci400 *)CONFIG_SYS_CCI400_ADDR; - unsigned int major; #ifdef CONFIG_TSEC_ENET /* clear BD & FR bits for BE BD's and frame data */ @@ -205,40 +193,7 @@ int board_early_init_f(void) init_early_memctl_regs(); #endif -#ifdef CONFIG_FSL_QSPI - out_be32(&scfg->qspi_cfg, SCFG_QSPI_CLKSEL); -#endif - -#ifdef CONFIG_FSL_DCU_FB - out_be32(&scfg->pixclkcr, SCFG_PIXCLKCR_PXCKEN); -#endif - - /* Configure Little endian for SAI, ASRC and SPDIF */ - out_be32(&scfg->endiancr, SCFG_ENDIANCR_LE); - - /* - * Enable snoop requests and DVM message requests for - * Slave insterface S4 (A7 core cluster) - */ - out_le32(&cci->slave[4].snoop_ctrl, - CCI400_DVM_MESSAGE_REQ_EN | CCI400_SNOOP_REQ_EN); - - major = get_soc_major_rev(); - if (major == SOC_MAJOR_VER_1_0) { - /* - * Set CCI-400 Slave interface S1, S2 Shareable Override - * Register All transactions are treated as non-shareable - */ - out_le32(&cci->slave[1].sha_ord, CCI400_SHAORD_NON_SHAREABLE); - out_le32(&cci->slave[2].sha_ord, CCI400_SHAORD_NON_SHAREABLE); - - /* Workaround for the issue that DDR could not respond to - * barrier transaction which is generated by executing DSB/ISB - * instruction. Set CCI-400 control override register to - * terminate the barrier transaction. After DDR is initialized, - * allow barrier transaction to DDR again */ - out_le32(&cci->ctrl_ord, CCI400_CTRLORD_TERM_BARRIER); - } + arch_soc_init(); #if defined(CONFIG_DEEP_SLEEP) if (is_warm_boot()) diff --git a/board/freescale/ls1021atwr/ls1021atwr.c b/board/freescale/ls1021atwr/ls1021atwr.c index 4918c1192e..8eaff5f0ce 100644 --- a/board/freescale/ls1021atwr/ls1021atwr.c +++ b/board/freescale/ls1021atwr/ls1021atwr.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -138,17 +139,6 @@ int checkboard(void) return 0; } -unsigned int get_soc_major_rev(void) -{ - struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); - unsigned int svr, major; - - svr = in_be32(&gur->svr); - major = SVR_MAJ(svr); - - return major; -} - void ddrmc_init(void) { struct ccsr_ddr *ddr = (struct ccsr_ddr *)CONFIG_SYS_FSL_DDR_ADDR; @@ -394,8 +384,6 @@ conflict: int board_early_init_f(void) { struct ccsr_scfg *scfg = (struct ccsr_scfg *)CONFIG_SYS_FSL_SCFG_ADDR; - struct ccsr_cci400 *cci = (struct ccsr_cci400 *)CONFIG_SYS_CCI400_ADDR; - unsigned int major; #ifdef CONFIG_TSEC_ENET /* clear BD & FR bits for BE BD's and frame data */ @@ -407,33 +395,7 @@ int board_early_init_f(void) init_early_memctl_regs(); #endif -#ifdef CONFIG_FSL_DCU_FB - out_be32(&scfg->pixclkcr, SCFG_PIXCLKCR_PXCKEN); -#endif - -#ifdef CONFIG_FSL_QSPI - out_be32(&scfg->qspi_cfg, SCFG_QSPI_CLKSEL); -#endif - - /* Configure Little endian for SAI, ASRC and SPDIF */ - out_be32(&scfg->endiancr, SCFG_ENDIANCR_LE); - - /* - * Enable snoop requests and DVM message requests for - * Slave insterface S4 (A7 core cluster) - */ - out_le32(&cci->slave[4].snoop_ctrl, - CCI400_DVM_MESSAGE_REQ_EN | CCI400_SNOOP_REQ_EN); - - major = get_soc_major_rev(); - if (major == SOC_MAJOR_VER_1_0) { - /* - * Set CCI-400 Slave interface S1, S2 Shareable Override - * Register All transactions are treated as non-shareable - */ - out_le32(&cci->slave[1].sha_ord, CCI400_SHAORD_NON_SHAREABLE); - out_le32(&cci->slave[2].sha_ord, CCI400_SHAORD_NON_SHAREABLE); - } + arch_soc_init(); #if defined(CONFIG_DEEP_SLEEP) if (is_warm_boot()) { From 762b3535467202ee216dce81f13eec42cd2ac2e3 Mon Sep 17 00:00:00 2001 From: Yao Yuan Date: Sat, 5 Dec 2015 14:59:11 +0800 Subject: [PATCH 17/31] arm: ls102xa: enable all the snoop signal for masters. Enable the IP feature's snoop signal to support hardware snoop for cache coherence. SNPCNFGCR contains the bits to drive snoop signal for various masters. Signed-off-by: Yuan Yao Reviewed-by: York Sun --- arch/arm/cpu/armv7/ls102xa/soc.c | 8 ++++++++ arch/arm/include/asm/arch-ls102xa/immap_ls102xa.h | 6 ++++++ 2 files changed, 14 insertions(+) diff --git a/arch/arm/cpu/armv7/ls102xa/soc.c b/arch/arm/cpu/armv7/ls102xa/soc.c index 0fdd6d4c86..6036473a50 100644 --- a/arch/arm/cpu/armv7/ls102xa/soc.c +++ b/arch/arm/cpu/armv7/ls102xa/soc.c @@ -62,5 +62,13 @@ int arch_soc_init(void) out_le32(&cci->ctrl_ord, CCI400_CTRLORD_TERM_BARRIER); } + /* Enable all the snoop signal for various masters */ + out_be32(&scfg->snpcnfgcr, SCFG_SNPCNFGCR_SEC_RD_WR | + SCFG_SNPCNFGCR_DCU_RD_WR | + SCFG_SNPCNFGCR_SATA_RD_WR | + SCFG_SNPCNFGCR_USB3_RD_WR | + SCFG_SNPCNFGCR_DBG_RD_WR | + SCFG_SNPCNFGCR_EDMA_SNP); + return 0; } diff --git a/arch/arm/include/asm/arch-ls102xa/immap_ls102xa.h b/arch/arm/include/asm/arch-ls102xa/immap_ls102xa.h index c12706d908..931727275c 100644 --- a/arch/arm/include/asm/arch-ls102xa/immap_ls102xa.h +++ b/arch/arm/include/asm/arch-ls102xa/immap_ls102xa.h @@ -152,6 +152,12 @@ struct ccsr_gur { #define SCFG_ETSECCMCR_GE1_CLK125 0x08000000 #define SCFG_PIXCLKCR_PXCKEN 0x80000000 #define SCFG_QSPI_CLKSEL 0xc0100000 +#define SCFG_SNPCNFGCR_SEC_RD_WR 0xc0000000 +#define SCFG_SNPCNFGCR_DCU_RD_WR 0x03000000 +#define SCFG_SNPCNFGCR_SATA_RD_WR 0x00c00000 +#define SCFG_SNPCNFGCR_USB3_RD_WR 0x00300000 +#define SCFG_SNPCNFGCR_DBG_RD_WR 0x000c0000 +#define SCFG_SNPCNFGCR_EDMA_SNP 0x00020000 #define SCFG_ENDIANCR_LE 0x80000000 /* Supplemental Configuration Unit */ From 0b8bc6314e1abc4379cc00f93f949257e0b1b196 Mon Sep 17 00:00:00 2001 From: Yao Yuan Date: Sat, 5 Dec 2015 14:59:12 +0800 Subject: [PATCH 18/31] armv7: ls102xa: cci-400: Enable snoop and DVM message requests. Enable snoop and DVM message on all CCI-400 slave ports. Setting on disabled feature (snoop or DVM) is ignored by CCI-400. Signed-off-by: Yuan Yao [York Sun: Add commit message] Reviewed-by: York Sun --- arch/arm/cpu/armv7/ls102xa/soc.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/arch/arm/cpu/armv7/ls102xa/soc.c b/arch/arm/cpu/armv7/ls102xa/soc.c index 6036473a50..97ba6d5179 100644 --- a/arch/arm/cpu/armv7/ls102xa/soc.c +++ b/arch/arm/cpu/armv7/ls102xa/soc.c @@ -40,8 +40,14 @@ int arch_soc_init(void) /* * Enable snoop requests and DVM message requests for - * Slave insterface S4 (A7 core cluster) + * All the slave insterfaces. */ + out_le32(&cci->slave[0].snoop_ctrl, + CCI400_DVM_MESSAGE_REQ_EN | CCI400_SNOOP_REQ_EN); + out_le32(&cci->slave[1].snoop_ctrl, + CCI400_DVM_MESSAGE_REQ_EN | CCI400_SNOOP_REQ_EN); + out_le32(&cci->slave[2].snoop_ctrl, + CCI400_DVM_MESSAGE_REQ_EN | CCI400_SNOOP_REQ_EN); out_le32(&cci->slave[4].snoop_ctrl, CCI400_DVM_MESSAGE_REQ_EN | CCI400_SNOOP_REQ_EN); From 6c4a1eba3fcc013f7d21cdb88098bdd3e7afa75b Mon Sep 17 00:00:00 2001 From: Yao Yuan Date: Sat, 5 Dec 2015 14:59:13 +0800 Subject: [PATCH 19/31] armv7/fsl-ls102xa: Workaround for DDR erratum A008514 This is a workaround for hardware erratum. Write the value of 63b2_0042h to EDDRTQCFG will optimal the memory controller performance. The value: 63b2_0042h comes from the hardware team. Signed-off-by: Yuan Yao Reviewed-by: York Sun --- arch/arm/cpu/armv7/ls102xa/soc.c | 10 ++++++++++ arch/arm/include/asm/arch-ls102xa/immap_ls102xa.h | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/arch/arm/cpu/armv7/ls102xa/soc.c b/arch/arm/cpu/armv7/ls102xa/soc.c index 97ba6d5179..79ae883b13 100644 --- a/arch/arm/cpu/armv7/ls102xa/soc.c +++ b/arch/arm/cpu/armv7/ls102xa/soc.c @@ -76,5 +76,15 @@ int arch_soc_init(void) SCFG_SNPCNFGCR_DBG_RD_WR | SCFG_SNPCNFGCR_EDMA_SNP); + /* + * Memory controller require a register write before being enabled. + * Affects: DDR + * Register: EDDRTQCFG + * Description: Memory controller performance is not optimal with + * default internal target queue register values. + * Workaround: Write a value of 63b2_0042h to address: 157_020Ch. + */ + out_be32(&scfg->eddrtqcfg, 0x63b20042); + return 0; } diff --git a/arch/arm/include/asm/arch-ls102xa/immap_ls102xa.h b/arch/arm/include/asm/arch-ls102xa/immap_ls102xa.h index 931727275c..89339fe0ef 100644 --- a/arch/arm/include/asm/arch-ls102xa/immap_ls102xa.h +++ b/arch/arm/include/asm/arch-ls102xa/immap_ls102xa.h @@ -230,7 +230,7 @@ struct ccsr_scfg { u32 scfgrevcr; u32 coresrencr; u32 pex2pmrdsr; - u32 ddrc1cr; + u32 eddrtqcfg; u32 ddrc2cr; u32 ddrc3cr; u32 ddrc4cr; From 000f4e7686f4291fbd74d8920b586caf10f9241f Mon Sep 17 00:00:00 2001 From: Yao Yuan Date: Sat, 5 Dec 2015 14:59:14 +0800 Subject: [PATCH 20/31] move erratum a008336 and a008514 to soc specific file As the errata A008336 and A008514 do not apply to all LS series SoCs (such as LS1021A, LS1043A) we move them to an soc specific file Signed-off-by: Yuan Yao Reviewed-by: York Sun --- arch/arm/cpu/armv8/fsl-layerscape/soc.c | 37 +++++++++++++++++++++++++ drivers/ddr/fsl/fsl_ddr_gen4.c | 34 ----------------------- 2 files changed, 37 insertions(+), 34 deletions(-) diff --git a/arch/arm/cpu/armv8/fsl-layerscape/soc.c b/arch/arm/cpu/armv8/fsl-layerscape/soc.c index 8896b70e78..a0de4becd1 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/soc.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/soc.c @@ -14,6 +14,41 @@ DECLARE_GLOBAL_DATA_PTR; #if defined(CONFIG_LS2080A) || defined(CONFIG_LS2085A) +/* + * This erratum requires setting a value to eddrtqcr1 to + * optimal the DDR performance. + */ +static void erratum_a008336(void) +{ + u32 *eddrtqcr1; + +#ifdef CONFIG_SYS_FSL_ERRATUM_A008336 +#ifdef CONFIG_SYS_FSL_DCSR_DDR_ADDR + eddrtqcr1 = (void *)CONFIG_SYS_FSL_DCSR_DDR_ADDR + 0x800; + out_le32(eddrtqcr1, 0x63b30002); +#endif +#ifdef CONFIG_SYS_FSL_DCSR_DDR2_ADDR + eddrtqcr1 = (void *)CONFIG_SYS_FSL_DCSR_DDR2_ADDR + 0x800; + out_le32(eddrtqcr1, 0x63b30002); +#endif +#endif +} + +/* + * This erratum requires a register write before being Memory + * controller 3 being enabled. + */ +static void erratum_a008514(void) +{ + u32 *eddrtqcr1; + +#ifdef CONFIG_SYS_FSL_ERRATUM_A008514 +#ifdef CONFIG_SYS_FSL_DCSR_DDR3_ADDR + eddrtqcr1 = (void *)CONFIG_SYS_FSL_DCSR_DDR3_ADDR + 0x800; + out_le32(eddrtqcr1, 0x63b20002); +#endif +#endif +} #ifdef CONFIG_SYS_FSL_ERRATUM_A009635 #define PLATFORM_CYCLE_ENV_VAR "a009635_interval_val" @@ -118,6 +153,8 @@ void fsl_lsch3_early_init_f(void) erratum_rcw_src(); init_early_memctl_regs(); /* tighten IFC timing */ erratum_a009203(); + erratum_a008514(); + erratum_a008336(); } #elif defined(CONFIG_LS1043A) diff --git a/drivers/ddr/fsl/fsl_ddr_gen4.c b/drivers/ddr/fsl/fsl_ddr_gen4.c index 0755ff7c24..3fca5c2684 100644 --- a/drivers/ddr/fsl/fsl_ddr_gen4.c +++ b/drivers/ddr/fsl/fsl_ddr_gen4.c @@ -49,10 +49,6 @@ 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 */ @@ -70,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: @@ -110,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); From e81495224f732f17ae6f379baf23b90cd1d5cb5f Mon Sep 17 00:00:00 2001 From: York Sun Date: Fri, 4 Dec 2015 11:57:07 -0800 Subject: [PATCH 21/31] Reserve secure memory Secure memory is at the end of memory, separated and reserved from OS, tracked by gd->secure_ram. Secure memory can host MMU tables, security monitor, etc. This is different from PRAM used to reserve private memory. PRAM offers memory at the top of u-boot memory, not necessarily the real end of memory for systems with very large DDR. Using the end of memory simplifies MMU setup and avoid memory fragmentation. "bdinfo" command shows gd->secure_ram value if this memory is marked as secured. Signed-off-by: York Sun --- README | 8 ++++++++ common/board_f.c | 9 +++++++++ common/cmd_bdinfo.c | 6 ++++++ include/asm-generic/global_data.h | 14 ++++++++++++++ 4 files changed, 37 insertions(+) diff --git a/README b/README index 4fee7066d5..6ea1af2678 100644 --- a/README +++ b/README @@ -3869,6 +3869,14 @@ Configuration Settings: Scratch address used by the alternate memory test You only need to set this if address zero isn't writeable +- CONFIG_SYS_MEM_RESERVE_SECURE + If defined, the size of CONFIG_SYS_MEM_RESERVE_SECURE memory + is substracted from total RAM and won't be reported to OS. + This memory can be used as secure memory. A variable + gd->secure_ram is used to track the location. In systems + the RAM base is not zero, or RAM is divided into banks, + this variable needs to be recalcuated to get the address. + - CONFIG_SYS_MEM_TOP_HIDE (PPC only): If CONFIG_SYS_MEM_TOP_HIDE is defined in the board config header, this specified memory area will get subtracted from the top diff --git a/common/board_f.c b/common/board_f.c index b40735438b..bd5a486248 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -324,6 +324,15 @@ static int setup_dest_addr(void) * Ram is setup, size stored in gd !! */ debug("Ram size: %08lX\n", (ulong)gd->ram_size); +#ifdef CONFIG_SYS_MEM_RESERVE_SECURE + /* Reserve memory for secure MMU tables, and/or security monitor */ + gd->ram_size -= CONFIG_SYS_MEM_RESERVE_SECURE; + /* + * Record secure memory location. Need recalcuate if memory splits + * into banks, or the ram base is not zero. + */ + gd->secure_ram = gd->ram_size; +#endif #if defined(CONFIG_SYS_MEM_TOP_HIDE) /* * Subtract specified amount of memory to hide so that it won't diff --git a/common/cmd_bdinfo.c b/common/cmd_bdinfo.c index adda55a263..deed6d8255 100644 --- a/common/cmd_bdinfo.c +++ b/common/cmd_bdinfo.c @@ -382,6 +382,12 @@ static int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, print_num("-> size", bd->bi_dram[i].size); } +#ifdef CONFIG_SYS_MEM_RESERVE_SECURE + if (gd->secure_ram & MEM_RESERVE_SECURE_SECURED) { + print_num("Secure ram", + gd->secure_ram & MEM_RESERVE_SECURE_ADDR_MASK); + } +#endif #if defined(CONFIG_CMD_NET) && !defined(CONFIG_DM_ETH) print_eths(); #endif diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h index 1abdcaa6b7..5d8b043f14 100644 --- a/include/asm-generic/global_data.h +++ b/include/asm-generic/global_data.h @@ -59,6 +59,20 @@ typedef struct global_data { unsigned long relocaddr; /* Start address of U-Boot in RAM */ phys_size_t ram_size; /* RAM size */ +#ifdef CONFIG_SYS_MEM_RESERVE_SECURE +#define MEM_RESERVE_SECURE_SECURED 0x1 +#define MEM_RESERVE_SECURE_MAINTAINED 0x2 +#define MEM_RESERVE_SECURE_ADDR_MASK (~0x3) + /* + * Secure memory addr + * This variable needs maintenance if the RAM base is not zero, + * or if RAM splits into non-consecutive banks. It also has a + * flag indicating the secure memory is marked as secure by MMU. + * Flags used: 0x1 secured + * 0x2 maintained + */ + phys_addr_t secure_ram; +#endif unsigned long mon_len; /* monitor len */ unsigned long irq_sp; /* irq stack pointer */ unsigned long start_addr_sp; /* start_addr_stackpointer */ From c107c0c05c988ac6cfba6de60c90f105bbea0e1e Mon Sep 17 00:00:00 2001 From: York Sun Date: Fri, 4 Dec 2015 11:57:08 -0800 Subject: [PATCH 22/31] armv8: fsl-layerscape: Make DDR non secure in MMU tables DDR has been set as secure in MMU tables. Non-secure master such as SDHC DMA cannot access data correctly. Mixing secure and non- secure MMU entries requirs the MMU tables themselves in secure memory. This patch moves MMU tables into a secure DDR area. Early MMU tables are changed to set DDR as non-secure. A new table is added into final MMU tables so secure memory can have 2MB granuality. gd->secure_ram tracks the location of this secure memory. For ARMv8 SoCs, the RAM base is not zero and RAM is divided into several banks. gd->secure_ram needs to be maintained before using. This maintenance is board-specific, depending on the SoC and memory bank of the secure memory falls into. Signed-off-by: York Sun --- arch/arm/cpu/armv8/fsl-layerscape/cpu.c | 121 ++++++++++++++++-- .../include/asm/arch-fsl-layerscape/config.h | 6 + .../arm/include/asm/arch-fsl-layerscape/cpu.h | 14 +- board/freescale/ls1043aqds/ddr.c | 9 ++ board/freescale/ls1043ardb/ddr.c | 15 +++ board/freescale/ls2080a/ddr.c | 15 +++ board/freescale/ls2080aqds/ddr.c | 15 +++ board/freescale/ls2080ardb/ddr.c | 15 +++ 8 files changed, 191 insertions(+), 19 deletions(-) diff --git a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c index 8847fc0287..87ccaf166f 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c @@ -206,11 +206,65 @@ static inline void early_mmu_setup(void) set_sctlr(get_sctlr() | CR_M); } +#ifdef CONFIG_SYS_MEM_RESERVE_SECURE +/* + * Called from final mmu setup. The phys_addr is new, non-existing + * address. A new sub table is created @level2_table_secure to cover + * size of CONFIG_SYS_MEM_RESERVE_SECURE memory. + */ +static inline int final_secure_ddr(u64 *level0_table, + u64 *level2_table_secure, + phys_addr_t phys_addr) +{ + int ret = -EINVAL; + struct table_info table = {}; + struct sys_mmu_table ddr_entry = { + 0, 0, BLOCK_SIZE_L1, MT_NORMAL, + PMD_SECT_OUTER_SHARE | PMD_SECT_NS + }; + u64 index; + + /* Need to create a new table */ + ddr_entry.virt_addr = phys_addr & ~(BLOCK_SIZE_L1 - 1); + ddr_entry.phys_addr = phys_addr & ~(BLOCK_SIZE_L1 - 1); + ret = find_table(&ddr_entry, &table, level0_table); + if (ret) + return ret; + index = (ddr_entry.virt_addr - table.table_base) >> SECTION_SHIFT_L1; + set_pgtable_table(table.ptr, index, level2_table_secure); + table.ptr = level2_table_secure; + table.table_base = ddr_entry.virt_addr; + table.entry_size = BLOCK_SIZE_L2; + ret = set_block_entry(&ddr_entry, &table); + if (ret) { + printf("MMU error: could not fill non-secure ddr block entries\n"); + return ret; + } + ddr_entry.virt_addr = phys_addr; + ddr_entry.phys_addr = phys_addr; + ddr_entry.size = CONFIG_SYS_MEM_RESERVE_SECURE; + ddr_entry.attribute = PMD_SECT_OUTER_SHARE; + ret = find_table(&ddr_entry, &table, level0_table); + if (ret) { + printf("MMU error: could not find secure ddr table\n"); + return ret; + } + ret = set_block_entry(&ddr_entry, &table); + if (ret) + printf("MMU error: could not set secure ddr block entry\n"); + + return ret; +} +#endif + /* * The final tables look similar to early tables, but different in detail. * These tables are in DRAM. Sub tables are added to enable cache for * QBMan and OCRAM. * + * Put the MMU table in secure memory if gd->secure_ram is valid. + * OCRAM will be not used for this purpose so gd->secure_ram can't be 0. + * * Level 1 table 0 contains 512 entries for each 1GB from 0 to 512GB. * Level 1 table 1 contains 512 entries for each 1GB from 512GB to 1TB. * Level 2 table 0 contains 512 entries for each 2MB from 0 to 1GB. @@ -223,18 +277,40 @@ static inline void early_mmu_setup(void) */ static inline void final_mmu_setup(void) { - unsigned int el, i; + unsigned int el = current_el(); + unsigned int i; u64 *level0_table = (u64 *)gd->arch.tlb_addr; - u64 *level1_table0 = (u64 *)(gd->arch.tlb_addr + 0x1000); - u64 *level1_table1 = (u64 *)(gd->arch.tlb_addr + 0x2000); - u64 *level2_table0 = (u64 *)(gd->arch.tlb_addr + 0x3000); -#ifdef CONFIG_FSL_LSCH3 - u64 *level2_table1 = (u64 *)(gd->arch.tlb_addr + 0x4000); -#elif defined(CONFIG_FSL_LSCH2) - u64 *level2_table1 = (u64 *)(gd->arch.tlb_addr + 0x4000); - u64 *level2_table2 = (u64 *)(gd->arch.tlb_addr + 0x5000); + u64 *level1_table0; + u64 *level1_table1; + u64 *level2_table0; + u64 *level2_table1; +#ifdef CONFIG_FSL_LSCH2 + u64 *level2_table2; #endif - struct table_info table = {level0_table, 0, BLOCK_SIZE_L0}; + struct table_info table = {NULL, 0, BLOCK_SIZE_L0}; + +#ifdef CONFIG_SYS_MEM_RESERVE_SECURE + u64 *level2_table_secure; + + if (el == 3) { + /* + * Only use gd->secure_ram if the address is recalculated + * Align to 4KB for MMU table + */ + if (gd->secure_ram & MEM_RESERVE_SECURE_MAINTAINED) + level0_table = (u64 *)(gd->secure_ram & ~0xfff); + else + printf("MMU warning: gd->secure_ram is not maintained, disabled.\n"); + } +#endif + level1_table0 = level0_table + 512; + level1_table1 = level1_table0 + 512; + level2_table0 = level1_table1 + 512; + level2_table1 = level2_table0 + 512; +#ifdef CONFIG_FSL_LSCH2 + level2_table2 = level2_table1 + 512; +#endif + table.ptr = level0_table; /* Invalidate all table entries */ memset(level0_table, 0, PGTABLE_SIZE); @@ -269,17 +345,34 @@ static inline void final_mmu_setup(void) &final_mmu_table[i]); } } + /* Set the secure memory to secure in MMU */ +#ifdef CONFIG_SYS_MEM_RESERVE_SECURE + if (el == 3 && gd->secure_ram & MEM_RESERVE_SECURE_MAINTAINED) { +#ifdef CONFIG_FSL_LSCH3 + level2_table_secure = level2_table1 + 512; +#elif defined(CONFIG_FSL_LSCH2) + level2_table_secure = level2_table2 + 512; +#endif + if (!final_secure_ddr(level0_table, + level2_table_secure, + gd->secure_ram & ~0x3)) { + gd->secure_ram |= MEM_RESERVE_SECURE_SECURED; + debug("Now MMU table is in secured memory at 0x%llx\n", + gd->secure_ram & ~0x3); + } else { + printf("MMU warning: Failed to secure DDR\n"); + } + } +#endif /* flush new MMU table */ - flush_dcache_range(gd->arch.tlb_addr, - gd->arch.tlb_addr + gd->arch.tlb_size); + flush_dcache_range((ulong)level0_table, + (ulong)level0_table + gd->arch.tlb_size); #ifdef CONFIG_SYS_DPAA_FMAN flush_dcache_all(); #endif /* point TTBR to the new table */ - el = current_el(); - set_ttbr_tcr_mair(el, (u64)level0_table, LAYERSCAPE_TCR_FINAL, MEMORY_ATTRIBUTES); /* diff --git a/arch/arm/include/asm/arch-fsl-layerscape/config.h b/arch/arm/include/asm/arch-fsl-layerscape/config.h index 7217a87502..b39281260d 100644 --- a/arch/arm/include/asm/arch-fsl-layerscape/config.h +++ b/arch/arm/include/asm/arch-fsl-layerscape/config.h @@ -17,6 +17,12 @@ #define CONFIG_SYS_FSL_DDR /* Freescale DDR driver */ #define CONFIG_SYS_FSL_DDR_VER FSL_DDR_VER_5_0 +/* + * Reserve secure memory + * To be aligned with MMU block size + */ +#define CONFIG_SYS_MEM_RESERVE_SECURE (2048 * 1024) /* 2MB */ + #if defined(CONFIG_LS2080A) || defined(CONFIG_LS2085A) #define CONFIG_MAX_CPUS 16 #define CONFIG_SYS_FSL_IFC_BANK_COUNT 8 diff --git a/arch/arm/include/asm/arch-fsl-layerscape/cpu.h b/arch/arm/include/asm/arch-fsl-layerscape/cpu.h index 454409488a..e030430786 100644 --- a/arch/arm/include/asm/arch-fsl-layerscape/cpu.h +++ b/arch/arm/include/asm/arch-fsl-layerscape/cpu.h @@ -129,7 +129,8 @@ static const struct sys_mmu_table early_mmu_table[] = { { CONFIG_SYS_FLASH_BASE, CONFIG_SYS_FSL_IFC_BASE1, CONFIG_SYS_FSL_IFC_SIZE1, MT_DEVICE_NGNRNE, PMD_SECT_NON_SHARE }, { CONFIG_SYS_FSL_DRAM_BASE1, CONFIG_SYS_FSL_DRAM_BASE1, - CONFIG_SYS_FSL_DRAM_SIZE1, MT_NORMAL, PMD_SECT_OUTER_SHARE }, + CONFIG_SYS_FSL_DRAM_SIZE1, MT_NORMAL, + PMD_SECT_OUTER_SHARE | PMD_SECT_NS }, /* Map IFC region #2 up to CONFIG_SYS_FLASH_BASE for NAND boot */ { CONFIG_SYS_FSL_IFC_BASE2, CONFIG_SYS_FSL_IFC_BASE2, CONFIG_SYS_FLASH_BASE - CONFIG_SYS_FSL_IFC_BASE2, @@ -138,7 +139,8 @@ static const struct sys_mmu_table early_mmu_table[] = { CONFIG_SYS_FSL_DCSR_SIZE, MT_DEVICE_NGNRNE, PMD_SECT_NON_SHARE | PMD_SECT_PXN | PMD_SECT_UXN }, { CONFIG_SYS_FSL_DRAM_BASE2, CONFIG_SYS_FSL_DRAM_BASE2, - CONFIG_SYS_FSL_DRAM_SIZE2, MT_NORMAL, PMD_SECT_OUTER_SHARE }, + CONFIG_SYS_FSL_DRAM_SIZE2, MT_NORMAL, + PMD_SECT_OUTER_SHARE | PMD_SECT_NS }, #elif defined(CONFIG_FSL_LSCH2) { CONFIG_SYS_FSL_CCSR_BASE, CONFIG_SYS_FSL_CCSR_BASE, CONFIG_SYS_FSL_CCSR_SIZE, MT_DEVICE_NGNRNE, @@ -165,7 +167,8 @@ static const struct sys_mmu_table final_mmu_table[] = { { CONFIG_SYS_FSL_OCRAM_BASE, CONFIG_SYS_FSL_OCRAM_BASE, CONFIG_SYS_FSL_OCRAM_SIZE, MT_NORMAL, PMD_SECT_NON_SHARE }, { CONFIG_SYS_FSL_DRAM_BASE1, CONFIG_SYS_FSL_DRAM_BASE1, - CONFIG_SYS_FSL_DRAM_SIZE1, MT_NORMAL, PMD_SECT_OUTER_SHARE }, + CONFIG_SYS_FSL_DRAM_SIZE1, MT_NORMAL, + PMD_SECT_OUTER_SHARE | PMD_SECT_NS }, { CONFIG_SYS_FSL_QSPI_BASE2, CONFIG_SYS_FSL_QSPI_BASE2, CONFIG_SYS_FSL_QSPI_SIZE2, MT_DEVICE_NGNRNE, PMD_SECT_NON_SHARE | PMD_SECT_PXN | PMD_SECT_UXN }, @@ -183,7 +186,7 @@ static const struct sys_mmu_table final_mmu_table[] = { /* For QBMAN portal, only the first 64MB is cache-enabled */ { CONFIG_SYS_FSL_QBMAN_BASE, CONFIG_SYS_FSL_QBMAN_BASE, CONFIG_SYS_FSL_QBMAN_SIZE_1, MT_NORMAL, - PMD_SECT_NON_SHARE | PMD_SECT_PXN | PMD_SECT_UXN }, + PMD_SECT_NON_SHARE | PMD_SECT_PXN | PMD_SECT_UXN | PMD_SECT_NS }, { CONFIG_SYS_FSL_QBMAN_BASE + CONFIG_SYS_FSL_QBMAN_SIZE_1, CONFIG_SYS_FSL_QBMAN_BASE + CONFIG_SYS_FSL_QBMAN_SIZE_1, CONFIG_SYS_FSL_QBMAN_SIZE - CONFIG_SYS_FSL_QBMAN_SIZE_1, @@ -212,7 +215,8 @@ static const struct sys_mmu_table final_mmu_table[] = { CONFIG_SYS_FSL_PEBUF_SIZE, MT_DEVICE_NGNRNE, PMD_SECT_NON_SHARE | PMD_SECT_PXN | PMD_SECT_UXN }, { CONFIG_SYS_FSL_DRAM_BASE2, CONFIG_SYS_FSL_DRAM_BASE2, - CONFIG_SYS_FSL_DRAM_SIZE2, MT_NORMAL, PMD_SECT_OUTER_SHARE }, + CONFIG_SYS_FSL_DRAM_SIZE2, MT_NORMAL, + PMD_SECT_OUTER_SHARE | PMD_SECT_NS }, #elif defined(CONFIG_FSL_LSCH2) { CONFIG_SYS_FSL_BOOTROM_BASE, CONFIG_SYS_FSL_BOOTROM_BASE, CONFIG_SYS_FSL_BOOTROM_SIZE, MT_DEVICE_NGNRNE, diff --git a/board/freescale/ls1043aqds/ddr.c b/board/freescale/ls1043aqds/ddr.c index 705e3843f4..42d906824a 100644 --- a/board/freescale/ls1043aqds/ddr.c +++ b/board/freescale/ls1043aqds/ddr.c @@ -126,6 +126,15 @@ phys_size_t initdram(int board_type) void dram_init_banksize(void) { + /* + * gd->secure_ram tracks the location of secure memory. + * It was set as if the memory starts from 0. + * The address needs to add the offset of its bank. + */ gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE; gd->bd->bi_dram[0].size = gd->ram_size; +#ifdef CONFIG_SYS_MEM_RESERVE_SECURE + gd->secure_ram = gd->bd->bi_dram[0].start + gd->secure_ram; + gd->secure_ram |= MEM_RESERVE_SECURE_MAINTAINED; +#endif } diff --git a/board/freescale/ls1043ardb/ddr.c b/board/freescale/ls1043ardb/ddr.c index 249d0565fc..11bc0f24d9 100644 --- a/board/freescale/ls1043ardb/ddr.c +++ b/board/freescale/ls1043ardb/ddr.c @@ -186,13 +186,28 @@ phys_size_t initdram(int board_type) void dram_init_banksize(void) { + /* + * gd->secure_ram tracks the location of secure memory. + * It was set as if the memory starts from 0. + * The address needs to add the offset of its bank. + */ gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE; if (gd->ram_size > CONFIG_SYS_DDR_BLOCK1_SIZE) { gd->bd->bi_dram[0].size = CONFIG_SYS_DDR_BLOCK1_SIZE; gd->bd->bi_dram[1].start = CONFIG_SYS_DDR_BLOCK2_BASE; gd->bd->bi_dram[1].size = gd->ram_size - CONFIG_SYS_DDR_BLOCK1_SIZE; +#ifdef CONFIG_SYS_MEM_RESERVE_SECURE + gd->secure_ram = gd->bd->bi_dram[1].start + + gd->secure_ram - + CONFIG_SYS_DDR_BLOCK1_SIZE; + gd->secure_ram |= MEM_RESERVE_SECURE_MAINTAINED; +#endif } else { gd->bd->bi_dram[0].size = gd->ram_size; +#ifdef CONFIG_SYS_MEM_RESERVE_SECURE + gd->secure_ram = gd->bd->bi_dram[0].start + gd->secure_ram; + gd->secure_ram |= MEM_RESERVE_SECURE_MAINTAINED; +#endif } } diff --git a/board/freescale/ls2080a/ddr.c b/board/freescale/ls2080a/ddr.c index 47d73ef75a..56c5d96e99 100644 --- a/board/freescale/ls2080a/ddr.c +++ b/board/freescale/ls2080a/ddr.c @@ -175,14 +175,29 @@ void dram_init_banksize(void) phys_size_t dp_ddr_size; #endif + /* + * gd->secure_ram tracks the location of secure memory. + * It was set as if the memory starts from 0. + * The address needs to add the offset of its bank. + */ gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE; if (gd->ram_size > CONFIG_SYS_LS2_DDR_BLOCK1_SIZE) { gd->bd->bi_dram[0].size = CONFIG_SYS_LS2_DDR_BLOCK1_SIZE; gd->bd->bi_dram[1].start = CONFIG_SYS_DDR_BLOCK2_BASE; gd->bd->bi_dram[1].size = gd->ram_size - CONFIG_SYS_LS2_DDR_BLOCK1_SIZE; +#ifdef CONFIG_SYS_MEM_RESERVE_SECURE + gd->secure_ram = gd->bd->bi_dram[1].start + + gd->secure_ram - + CONFIG_SYS_LS2_DDR_BLOCK1_SIZE; + gd->secure_ram |= MEM_RESERVE_SECURE_MAINTAINED; +#endif } else { gd->bd->bi_dram[0].size = gd->ram_size; +#ifdef CONFIG_SYS_MEM_RESERVE_SECURE + gd->secure_ram = gd->bd->bi_dram[0].start + gd->secure_ram; + gd->secure_ram |= MEM_RESERVE_SECURE_MAINTAINED; +#endif } #ifdef CONFIG_SYS_DP_DDR_BASE_PHY diff --git a/board/freescale/ls2080aqds/ddr.c b/board/freescale/ls2080aqds/ddr.c index 7e67ee0335..9fb5e112db 100644 --- a/board/freescale/ls2080aqds/ddr.c +++ b/board/freescale/ls2080aqds/ddr.c @@ -175,14 +175,29 @@ void dram_init_banksize(void) phys_size_t dp_ddr_size; #endif + /* + * gd->secure_ram tracks the location of secure memory. + * It was set as if the memory starts from 0. + * The address needs to add the offset of its bank. + */ gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE; if (gd->ram_size > CONFIG_SYS_LS2_DDR_BLOCK1_SIZE) { gd->bd->bi_dram[0].size = CONFIG_SYS_LS2_DDR_BLOCK1_SIZE; gd->bd->bi_dram[1].start = CONFIG_SYS_DDR_BLOCK2_BASE; gd->bd->bi_dram[1].size = gd->ram_size - CONFIG_SYS_LS2_DDR_BLOCK1_SIZE; +#ifdef CONFIG_SYS_MEM_RESERVE_SECURE + gd->secure_ram = gd->bd->bi_dram[1].start + + gd->secure_ram - + CONFIG_SYS_LS2_DDR_BLOCK1_SIZE; + gd->secure_ram |= MEM_RESERVE_SECURE_MAINTAINED; +#endif } else { gd->bd->bi_dram[0].size = gd->ram_size; +#ifdef CONFIG_SYS_MEM_RESERVE_SECURE + gd->secure_ram = gd->bd->bi_dram[0].start + gd->secure_ram; + gd->secure_ram |= MEM_RESERVE_SECURE_MAINTAINED; +#endif } #ifdef CONFIG_SYS_DP_DDR_BASE_PHY diff --git a/board/freescale/ls2080ardb/ddr.c b/board/freescale/ls2080ardb/ddr.c index 76f3b59e4e..6c191738ec 100644 --- a/board/freescale/ls2080ardb/ddr.c +++ b/board/freescale/ls2080ardb/ddr.c @@ -175,14 +175,29 @@ void dram_init_banksize(void) phys_size_t dp_ddr_size; #endif + /* + * gd->secure_ram tracks the location of secure memory. + * It was set as if the memory starts from 0. + * The address needs to add the offset of its bank. + */ gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE; if (gd->ram_size > CONFIG_SYS_LS2_DDR_BLOCK1_SIZE) { gd->bd->bi_dram[0].size = CONFIG_SYS_LS2_DDR_BLOCK1_SIZE; gd->bd->bi_dram[1].start = CONFIG_SYS_DDR_BLOCK2_BASE; gd->bd->bi_dram[1].size = gd->ram_size - CONFIG_SYS_LS2_DDR_BLOCK1_SIZE; +#ifdef CONFIG_SYS_MEM_RESERVE_SECURE + gd->secure_ram = gd->bd->bi_dram[1].start + + gd->secure_ram - + CONFIG_SYS_LS2_DDR_BLOCK1_SIZE; + gd->secure_ram |= MEM_RESERVE_SECURE_MAINTAINED; +#endif } else { gd->bd->bi_dram[0].size = gd->ram_size; +#ifdef CONFIG_SYS_MEM_RESERVE_SECURE + gd->secure_ram = gd->bd->bi_dram[0].start + gd->secure_ram; + gd->secure_ram |= MEM_RESERVE_SECURE_MAINTAINED; +#endif } #ifdef CONFIG_SYS_DP_DDR_BASE_PHY From aabd7ddb889aec3c6c4139974f66a44e2ce46ba5 Mon Sep 17 00:00:00 2001 From: York Sun Date: Mon, 7 Dec 2015 11:05:29 -0800 Subject: [PATCH 23/31] common: Rewrite hiding the end of memory As the name may be confusing, the CONFIG_SYS_MEM_TOP_HIDE reserves some memory from the end of ram, tracked by gd->ram_size. It is not always the top of u-boot visible memory. Rewrite the macro with a weak function to provide flexibility for complex calcuation. Legacy use of this macro is still supported. Signed-off-by: York Sun Reviewed-by: Simon Glass --- README | 2 +- common/board_f.c | 23 +++++++++++++++-------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/README b/README index 6ea1af2678..4aa2aaeb23 100644 --- a/README +++ b/README @@ -3877,7 +3877,7 @@ Configuration Settings: the RAM base is not zero, or RAM is divided into banks, this variable needs to be recalcuated to get the address. -- CONFIG_SYS_MEM_TOP_HIDE (PPC only): +- CONFIG_SYS_MEM_TOP_HIDE: If CONFIG_SYS_MEM_TOP_HIDE is defined in the board config header, this specified memory area will get subtracted from the top (end) of RAM and won't get "touched" at all by U-Boot. By diff --git a/common/board_f.c b/common/board_f.c index bd5a486248..8094ac4efe 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -317,6 +317,15 @@ __weak ulong board_get_usable_ram_top(ulong total_size) return gd->ram_top; } +__weak phys_size_t board_reserve_ram_top(phys_size_t ram_size) +{ +#ifdef CONFIG_SYS_MEM_TOP_HIDE + return ram_size - CONFIG_SYS_MEM_TOP_HIDE; +#else + return ram_size; +#endif +} + static int setup_dest_addr(void) { debug("Monitor len: %08lX\n", gd->mon_len); @@ -333,19 +342,17 @@ static int setup_dest_addr(void) */ gd->secure_ram = gd->ram_size; #endif -#if defined(CONFIG_SYS_MEM_TOP_HIDE) /* * Subtract specified amount of memory to hide so that it won't * get "touched" at all by U-Boot. By fixing up gd->ram_size * the Linux kernel should now get passed the now "corrected" - * memory size and won't touch it either. This should work - * for arch/ppc and arch/powerpc. Only Linux board ports in - * arch/powerpc with bootwrapper support, that recalculate the - * memory size from the SDRAM controller setup will have to - * get fixed. + * memory size and won't touch it either. This has been used + * by arch/powerpc exclusively. Now ARMv8 takes advantage of + * thie mechanism. If memory is split into banks, addresses + * need to be calculated. */ - gd->ram_size -= CONFIG_SYS_MEM_TOP_HIDE; -#endif + gd->ram_size = board_reserve_ram_top(gd->ram_size); + #ifdef CONFIG_SYS_SDRAM_BASE gd->ram_top = CONFIG_SYS_SDRAM_BASE; #endif From c04921414c087e15f8fa82d808a25e9338a7e8d5 Mon Sep 17 00:00:00 2001 From: York Sun Date: Mon, 7 Dec 2015 11:08:58 -0800 Subject: [PATCH 24/31] armv8: fsl-layerscale: Rewrite reserving memory for MC and debug server MC and debug server are not board-specific. Move reserving memory to SoC file, using the new board_reserve_ram_top function. Reduce debug server memory by 2MB to make room for secure memory. In the system with MC and debug server, the top of u-boot memory is not the end of memory. PRAM is not used for this reservation. Signed-off-by: York Sun --- README | 4 ++-- arch/arm/cpu/armv8/fsl-layerscape/cpu.c | 21 +++++++++++++++++++++ board/freescale/ls2080a/ls2080a.c | 17 ----------------- board/freescale/ls2080aqds/ls2080aqds.c | 17 ----------------- board/freescale/ls2080ardb/ls2080ardb.c | 17 ----------------- include/configs/ls2080a_common.h | 9 ++------- 6 files changed, 25 insertions(+), 60 deletions(-) diff --git a/README b/README index 4aa2aaeb23..43f307f30f 100644 --- a/README +++ b/README @@ -5056,8 +5056,8 @@ This firmware often needs to be loaded during U-Boot booting. - CONFIG_SYS_DEBUG_SERVER_DRAM_BLOCK_MIN_SIZE Define minimum DDR size required for debug server image -- CONFIG_SYS_MEM_TOP_HIDE_MIN - Define minimum DDR size to be hided from top of the DDR memory +- CONFIG_SYS_MC_RSV_MEM_ALIGN + Define alignment of reserved memory MC requires Reproducible builds ------------------- diff --git a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c index 87ccaf166f..6ea28ed5cb 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c @@ -636,3 +636,24 @@ void reset_cpu(ulong addr) val |= 0x02; scfg_out32(rstcr, val); } + +phys_size_t board_reserve_ram_top(phys_size_t ram_size) +{ + phys_size_t ram_top = ram_size; + +#ifdef CONFIG_SYS_MEM_TOP_HIDE +#error CONFIG_SYS_MEM_TOP_HIDE not to be used together with this function +#endif +/* Carve the Debug Server private DRAM block from the end of DRAM */ +#ifdef CONFIG_FSL_DEBUG_SERVER + ram_top -= debug_server_get_dram_block_size(); +#endif + +/* Carve the MC private DRAM block from the end of DRAM */ +#ifdef CONFIG_FSL_MC_ENET + ram_top -= mc_get_dram_block_size(); + ram_top &= ~(CONFIG_SYS_MC_RSV_MEM_ALIGN - 1); +#endif + + return ram_top; +} diff --git a/board/freescale/ls2080a/ls2080a.c b/board/freescale/ls2080a/ls2080a.c index 827fbf0835..7bce8b0772 100644 --- a/board/freescale/ls2080a/ls2080a.c +++ b/board/freescale/ls2080a/ls2080a.c @@ -68,23 +68,6 @@ int arch_misc_init(void) } #endif -unsigned long get_dram_size_to_hide(void) -{ - unsigned long dram_to_hide = 0; - -/* Carve the Debug Server private DRAM block from the end of DRAM */ -#ifdef CONFIG_FSL_DEBUG_SERVER - dram_to_hide += debug_server_get_dram_block_size(); -#endif - -/* Carve the MC private DRAM block from the end of DRAM */ -#ifdef CONFIG_FSL_MC_ENET - dram_to_hide += mc_get_dram_block_size(); -#endif - - return roundup(dram_to_hide, CONFIG_SYS_MEM_TOP_HIDE_MIN); -} - int board_eth_init(bd_t *bis) { int error = 0; diff --git a/board/freescale/ls2080aqds/ls2080aqds.c b/board/freescale/ls2080aqds/ls2080aqds.c index 1f990720a8..aa256a225b 100644 --- a/board/freescale/ls2080aqds/ls2080aqds.c +++ b/board/freescale/ls2080aqds/ls2080aqds.c @@ -253,23 +253,6 @@ int arch_misc_init(void) } #endif -unsigned long get_dram_size_to_hide(void) -{ - unsigned long dram_to_hide = 0; - -/* Carve the Debug Server private DRAM block from the end of DRAM */ -#ifdef CONFIG_FSL_DEBUG_SERVER - dram_to_hide += debug_server_get_dram_block_size(); -#endif - -/* Carve the MC private DRAM block from the end of DRAM */ -#ifdef CONFIG_FSL_MC_ENET - dram_to_hide += mc_get_dram_block_size(); -#endif - - return roundup(dram_to_hide, CONFIG_SYS_MEM_TOP_HIDE_MIN); -} - #ifdef CONFIG_FSL_MC_ENET void fdt_fixup_board_enet(void *fdt) { diff --git a/board/freescale/ls2080ardb/ls2080ardb.c b/board/freescale/ls2080ardb/ls2080ardb.c index 2ae9d6cf45..c63b639625 100644 --- a/board/freescale/ls2080ardb/ls2080ardb.c +++ b/board/freescale/ls2080ardb/ls2080ardb.c @@ -219,23 +219,6 @@ int arch_misc_init(void) } #endif -unsigned long get_dram_size_to_hide(void) -{ - unsigned long dram_to_hide = 0; - -/* Carve the Debug Server private DRAM block from the end of DRAM */ -#ifdef CONFIG_FSL_DEBUG_SERVER - dram_to_hide += debug_server_get_dram_block_size(); -#endif - -/* Carve the MC private DRAM block from the end of DRAM */ -#ifdef CONFIG_FSL_MC_ENET - dram_to_hide += mc_get_dram_block_size(); -#endif - - return roundup(dram_to_hide, CONFIG_SYS_MEM_TOP_HIDE_MIN); -} - #ifdef CONFIG_FSL_MC_ENET void fdt_fixup_board_enet(void *fdt) { diff --git a/include/configs/ls2080a_common.h b/include/configs/ls2080a_common.h index 969aed698c..4ae7d11685 100644 --- a/include/configs/ls2080a_common.h +++ b/include/configs/ls2080a_common.h @@ -195,10 +195,9 @@ unsigned long long get_qixis_addr(void); * 512MB aligned, so the min size to hide is 512MB. */ #if defined(CONFIG_FSL_MC_ENET) || defined(CONFIG_FSL_DEBUG_SERVER) -#define CONFIG_SYS_DEBUG_SERVER_DRAM_BLOCK_MIN_SIZE (256UL * 1024 * 1024) +#define CONFIG_SYS_DEBUG_SERVER_DRAM_BLOCK_MIN_SIZE (254UL * 1024 * 1024) #define CONFIG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE (256UL * 1024 * 1024) -#define CONFIG_SYS_MEM_TOP_HIDE_MIN (512UL * 1024 * 1024) -#define CONFIG_SYS_MEM_TOP_HIDE get_dram_size_to_hide() +#define CONFIG_SYS_MC_RSV_MEM_ALIGN (512UL * 1024 * 1024) #endif /* PCIe */ @@ -290,10 +289,6 @@ unsigned long long get_qixis_addr(void); #define CONFIG_AUTO_COMPLETE #define CONFIG_SYS_MAXARGS 64 /* max command args */ -#ifndef __ASSEMBLY__ -unsigned long get_dram_size_to_hide(void); -#endif - #define CONFIG_PANIC_HANG /* do not reset board on panic */ #define CONFIG_SPL_BSS_START_ADDR 0x80100000 From beedbc2ea0e71c779b92e4d74b928a266d3e86f9 Mon Sep 17 00:00:00 2001 From: Alexander Stein Date: Wed, 4 Nov 2015 09:19:10 +0100 Subject: [PATCH 25/31] fsl_qspi: Pet the watchdog while reading/writing When reading a large blob. e.g. a linux kernel (several MiBs) a watchdog timeout might occur meanwhile. So pet the watchdog while operating on the flash. Signed-off-by: Alexander Stein Reviewed-by: York Sun --- drivers/spi/fsl_qspi.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/spi/fsl_qspi.c b/drivers/spi/fsl_qspi.c index ed391142be..feec3e80b6 100644 --- a/drivers/spi/fsl_qspi.c +++ b/drivers/spi/fsl_qspi.c @@ -13,6 +13,7 @@ #include #include #include +#include #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, ®s->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, ®s->ipcr, (SEQID_WREN << QSPI_IPCR_SEQID_SHIFT) | 0); while (qspi_read32(priv->flags, ®s->sr) & QSPI_SR_BUSY_MASK) From b644d3e932f133bbb8b577c1965eae399b7df99e Mon Sep 17 00:00:00 2001 From: Aneesh Bansal Date: Tue, 8 Dec 2015 13:54:26 +0530 Subject: [PATCH 26/31] armv8: define usec2ticks function usec2ticks() function has been defined for ARMv8 which will be used by SEC Driver. Signed-off-by: Aneesh Bansal Reviewed-by: York Sun --- arch/arm/cpu/armv8/generic_timer.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/arch/arm/cpu/armv8/generic_timer.c b/arch/arm/cpu/armv8/generic_timer.c index 8e60baebc5..8f47a82043 100644 --- a/arch/arm/cpu/armv8/generic_timer.c +++ b/arch/arm/cpu/armv8/generic_timer.c @@ -40,3 +40,14 @@ unsigned long timer_read_counter(void) #endif return cntpct; } + +unsigned long usec2ticks(unsigned long usec) +{ + ulong ticks; + if (usec < 1000) + ticks = ((usec * (get_tbclk()/1000)) + 500) / 1000; + else + ticks = ((usec / 10) * (get_tbclk() / 100000)); + + return ticks; +} From 70f959c3c45bd408ba4f7b18a3a69afd9ccfe739 Mon Sep 17 00:00:00 2001 From: Aneesh Bansal Date: Tue, 8 Dec 2015 13:54:27 +0530 Subject: [PATCH 27/31] armv8: Make SEC read/write as snoopable for LS1043 For LS1043, SEC read/writes are made snoopable by setting the corresponding bits in SCFG to avoid coherency issues. Signed-off-by: Aneesh Bansal Reviewed-by: York Sun --- arch/arm/cpu/armv8/fsl-layerscape/soc.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm/cpu/armv8/fsl-layerscape/soc.c b/arch/arm/cpu/armv8/fsl-layerscape/soc.c index a0de4becd1..8d40405923 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/soc.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/soc.c @@ -161,11 +161,16 @@ void fsl_lsch3_early_init_f(void) void fsl_lsch2_early_init_f(void) { struct ccsr_cci400 *cci = (struct ccsr_cci400 *)CONFIG_SYS_CCI400_ADDR; + struct ccsr_scfg *scfg = (struct ccsr_scfg *)CONFIG_SYS_FSL_SCFG_ADDR; #ifdef CONFIG_FSL_IFC init_early_memctl_regs(); /* tighten IFC timing */ #endif + /* Make SEC reads and writes snoopable */ + setbits_be32(&scfg->snpcnfgcr, SCFG_SNPCNFGCR_SECRDSNP | + SCFG_SNPCNFGCR_SECWRSNP); + /* * Enable snoop requests and DVM message requests for * Slave insterface S4 (A53 core cluster) From e8f954a756a825130d11b9c8fca70101dd8b3ac5 Mon Sep 17 00:00:00 2001 From: Aneesh Bansal Date: Tue, 8 Dec 2015 13:54:28 +0530 Subject: [PATCH 28/31] include/linux: move typdef for uintptr_t uintptr_t which is a typdef for unsigned long is needed for creating pointers (32 or 64 bit depending on Core) from 32 bit variables storing the address. If a 32 bit variable (u32) is typecasted to a pointer (void *), compiler gives a warning in case size of pointer on the core is 64 bit. The typdef has been moved from include/compiler.h to include/linux/types.h Signed-off-by: Aneesh Bansal Reviewed-by: York Sun --- include/compiler.h | 3 --- include/linux/types.h | 1 + 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/include/compiler.h b/include/compiler.h index 47c296e202..f853ed4787 100644 --- a/include/compiler.h +++ b/include/compiler.h @@ -115,9 +115,6 @@ typedef unsigned int uint; #ifdef CONFIG_USE_STDINT /* Provided by gcc. */ #include -#else -/* Type for `void *' pointers. */ -typedef unsigned long int uintptr_t; #endif #include diff --git a/include/linux/types.h b/include/linux/types.h index 6f75be4253..c7e8fdb9c2 100644 --- a/include/linux/types.h +++ b/include/linux/types.h @@ -124,6 +124,7 @@ typedef __UINT64_TYPE__ u_int64_t; typedef __INT64_TYPE__ int64_t; #endif +typedef unsigned long uintptr_t; /* * Below are truly Linux-specific types that should never collide with * any application/library that wants linux/types.h. From 9711f52806655bcfa28fe5594b91fed430beb72e Mon Sep 17 00:00:00 2001 From: Aneesh Bansal Date: Tue, 8 Dec 2015 13:54:29 +0530 Subject: [PATCH 29/31] armv8/ls1043ardb: add SECURE BOOT target for NOR LS1043ARDB Secure Boot Target from NOR has been added. - Configs defined to enable esbc_validate. - ESBC Address in header is made 64 bit. - SMMU is re-configured in Bypass mode. Signed-off-by: Aneesh Bansal Reviewed-by: York Sun --- .../include/asm/arch-fsl-layerscape/config.h | 4 +-- .../asm/arch-fsl-layerscape/immap_lsch2.h | 2 +- arch/arm/include/asm/fsl_secure_boot.h | 6 +++- board/freescale/common/fsl_validate.c | 34 ++++++++++++------- board/freescale/ls1043ardb/MAINTAINERS | 5 +++ board/freescale/ls1043ardb/ls1043ardb.c | 18 +++++++++- common/cmd_blob.c | 6 ++-- configs/ls1043ardb_SECURE_BOOT_defconfig | 9 +++++ include/configs/ls1043ardb.h | 10 ++++++ include/fsl_validate.h | 9 ++++- 10 files changed, 82 insertions(+), 21 deletions(-) create mode 100644 configs/ls1043ardb_SECURE_BOOT_defconfig diff --git a/arch/arm/include/asm/arch-fsl-layerscape/config.h b/arch/arm/include/asm/arch-fsl-layerscape/config.h index b39281260d..6e5224ea1c 100644 --- a/arch/arm/include/asm/arch-fsl-layerscape/config.h +++ b/arch/arm/include/asm/arch-fsl-layerscape/config.h @@ -153,8 +153,8 @@ #define CONFIG_SYS_FSL_PCIE_COMPAT "fsl,qoriq-pcie-v2.4" #define CONFIG_SYS_FSL_SFP_VER_3_2 -#define CONFIG_SYS_FSL_SNVS_LE -#define CONFIG_SYS_FSL_SEC_LE +#define CONFIG_SYS_FSL_SEC_MON_BE +#define CONFIG_SYS_FSL_SEC_BE #define CONFIG_SYS_FSL_SFP_BE #define CONFIG_SYS_FSL_SRK_LE #define CONFIG_KEY_REVOCATION diff --git a/arch/arm/include/asm/arch-fsl-layerscape/immap_lsch2.h b/arch/arm/include/asm/arch-fsl-layerscape/immap_lsch2.h index 83caa918bd..e7def3ac4a 100644 --- a/arch/arm/include/asm/arch-fsl-layerscape/immap_lsch2.h +++ b/arch/arm/include/asm/arch-fsl-layerscape/immap_lsch2.h @@ -38,7 +38,7 @@ #define CONFIG_SYS_PCIE3_ADDR (CONFIG_SYS_IMMR + 0x2600000) #define CONFIG_SYS_FSL_SEC_ADDR (CONFIG_SYS_IMMR + 0x700000) #define CONFIG_SYS_FSL_JR0_ADDR (CONFIG_SYS_IMMR + 0x710000) -#define CONFIG_SYS_SNVS_ADDR (CONFIG_SYS_IMMR + 0xe90000) +#define CONFIG_SYS_SEC_MON_ADDR (CONFIG_SYS_IMMR + 0xe90000) #define CONFIG_SYS_SFP_ADDR (CONFIG_SYS_IMMR + 0xe80200) #define CONFIG_SYS_FSL_TIMER_ADDR 0x02b00000 diff --git a/arch/arm/include/asm/fsl_secure_boot.h b/arch/arm/include/asm/fsl_secure_boot.h index f2d4c3c5f9..806302bc61 100644 --- a/arch/arm/include/asm/fsl_secure_boot.h +++ b/arch/arm/include/asm/fsl_secure_boot.h @@ -11,13 +11,17 @@ #define CONFIG_CMD_ESBC_VALIDATE #define CONFIG_FSL_SEC_MON #define CONFIG_SHA_PROG_HW_ACCEL -#define CONFIG_DM #define CONFIG_RSA #define CONFIG_RSA_FREESCALE_EXP + #ifndef CONFIG_FSL_CAAM #define CONFIG_FSL_CAAM #endif +#ifndef CONFIG_DM +#define CONFIG_DM +#endif + #define CONFIG_KEY_REVOCATION #ifndef CONFIG_SYS_RAMBOOT /* The key used for verification of next level images diff --git a/board/freescale/common/fsl_validate.c b/board/freescale/common/fsl_validate.c index 73b6718db9..b510c71c40 100644 --- a/board/freescale/common/fsl_validate.c +++ b/board/freescale/common/fsl_validate.c @@ -15,7 +15,7 @@ #include #include #include -#ifndef CONFIG_MPC85xx +#ifdef CONFIG_LS102XA #include #endif @@ -99,7 +99,8 @@ int get_csf_base_addr(u32 *csf_addr, u32 *flash_base_addr) struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); u32 csf_hdr_addr = in_be32(&gur->scratchrw[0]); - if (memcmp((u8 *)csf_hdr_addr, barker_code, ESBC_BARKER_LEN)) + if (memcmp((u8 *)(uintptr_t)csf_hdr_addr, + barker_code, ESBC_BARKER_LEN)) return -1; *csf_addr = csf_hdr_addr; @@ -117,7 +118,7 @@ static int get_ie_info_addr(u32 *ie_addr) if (get_csf_base_addr(&csf_addr, &flash_base_addr)) return -1; - hdr = (struct fsl_secboot_img_hdr *)csf_addr; + hdr = (struct fsl_secboot_img_hdr *)(uintptr_t)csf_addr; /* For SoC's with Trust Architecture v1 with corenet bus * the sg table field in CSF header has absolute address @@ -130,7 +131,7 @@ static int get_ie_info_addr(u32 *ie_addr) (((u32)hdr->psgtable & ~(CONFIG_SYS_PBI_FLASH_BASE)) + flash_base_addr); #else - sg_tbl = (struct fsl_secboot_sg_table *)(csf_addr + + sg_tbl = (struct fsl_secboot_sg_table *)(uintptr_t)(csf_addr + (u32)hdr->psgtable); #endif @@ -379,8 +380,8 @@ static int calc_img_key_hash(struct fsl_secboot_img_priv *img) #ifdef CONFIG_KEY_REVOCATION if (check_srk(img)) { ret = algo->hash_update(algo, ctx, - (u8 *)(img->ehdrloc + img->hdr.srk_tbl_off), - img->hdr.len_kr.num_srk * sizeof(struct srk_table), 1); + (u8 *)(uintptr_t)(img->ehdrloc + img->hdr.srk_tbl_off), + img->hdr.len_kr.num_srk * sizeof(struct srk_table), 1); srk = 1; } #endif @@ -438,8 +439,8 @@ static int calc_esbchdr_esbc_hash(struct fsl_secboot_img_priv *img) #ifdef CONFIG_KEY_REVOCATION if (check_srk(img)) { ret = algo->hash_update(algo, ctx, - (u8 *)(img->ehdrloc + img->hdr.srk_tbl_off), - img->hdr.len_kr.num_srk * sizeof(struct srk_table), 0); + (u8 *)(uintptr_t)(img->ehdrloc + img->hdr.srk_tbl_off), + img->hdr.len_kr.num_srk * sizeof(struct srk_table), 0); key_hash = 1; } #endif @@ -454,8 +455,13 @@ static int calc_esbchdr_esbc_hash(struct fsl_secboot_img_priv *img) return ret; /* Update hash for actual Image */ +#ifdef CONFIG_ESBC_ADDR_64BIT ret = algo->hash_update(algo, ctx, - (u8 *)img->hdr.pimg, img->hdr.img_size, 1); + (u8 *)(uintptr_t)img->hdr.pimg64, img->hdr.img_size, 1); +#else + ret = algo->hash_update(algo, ctx, + (u8 *)(uintptr_t)img->hdr.pimg, img->hdr.img_size, 1); +#endif if (ret) return ret; @@ -533,7 +539,7 @@ static int read_validate_esbc_client_header(struct fsl_secboot_img_priv *img) { char buf[20]; struct fsl_secboot_img_hdr *hdr = &img->hdr; - void *esbc = (u8 *)img->ehdrloc; + void *esbc = (u8 *)(uintptr_t)img->ehdrloc; u8 *k, *s; #ifdef CONFIG_KEY_REVOCATION u32 ret; @@ -549,7 +555,11 @@ static int read_validate_esbc_client_header(struct fsl_secboot_img_priv *img) if (memcmp(hdr->barker, barker_code, ESBC_BARKER_LEN)) return ERROR_ESBC_CLIENT_HEADER_BARKER; +#ifdef CONFIG_ESBC_ADDR_64BIT + sprintf(buf, "%llx", hdr->pimg64); +#else sprintf(buf, "%x", hdr->pimg); +#endif setenv("img_addr", buf); if (!hdr->img_size) @@ -594,7 +604,7 @@ static int read_validate_esbc_client_header(struct fsl_secboot_img_priv *img) if (!key_found && check_ie(img)) { if (get_ie_info_addr(&img->ie_addr)) return ERROR_IE_TABLE_NOT_FOUND; - ie_info = (struct ie_key_info *)img->ie_addr; + ie_info = (struct ie_key_info *)(uintptr_t)img->ie_addr; if (ie_info->num_keys == 0 || ie_info->num_keys > 32) return ERROR_ESBC_CLIENT_HEADER_INVALID_IE_NUM_ENTRY; @@ -748,7 +758,7 @@ int fsl_secboot_validate(cmd_tbl_t *cmdtp, int flag, int argc, hdr = &img->hdr; img->ehdrloc = addr; - esbc = (u8 *)img->ehdrloc; + esbc = (u8 *)(uintptr_t)img->ehdrloc; memcpy(hdr, esbc, sizeof(struct fsl_secboot_img_hdr)); diff --git a/board/freescale/ls1043ardb/MAINTAINERS b/board/freescale/ls1043ardb/MAINTAINERS index efca5bf245..84ffb638d8 100644 --- a/board/freescale/ls1043ardb/MAINTAINERS +++ b/board/freescale/ls1043ardb/MAINTAINERS @@ -7,3 +7,8 @@ F: include/configs/ls1043ardb.h F: configs/ls1043ardb_defconfig F: configs/ls1043ardb_nand_defconfig F: configs/ls1043ardb_sdcard_defconfig + +LS1043A_SECURE_BOOT BOARD +M: Aneesh Bansal +S: Maintained +F: configs/ls1043ardb_SECURE_BOOT_defconfig diff --git a/board/freescale/ls1043ardb/ls1043ardb.c b/board/freescale/ls1043ardb/ls1043ardb.c index 4556ea8ad1..c8f723a108 100644 --- a/board/freescale/ls1043ardb/ls1043ardb.c +++ b/board/freescale/ls1043ardb/ls1043ardb.c @@ -18,6 +18,8 @@ #include #include #include +#include +#include #include "cpld.h" DECLARE_GLOBAL_DATA_PTR; @@ -123,7 +125,21 @@ int config_board_mux(void) int misc_init_r(void) { config_board_mux(); - +#ifdef CONFIG_SECURE_BOOT + /* In case of Secure Boot, the IBR configures the SMMU + * to allow only Secure transactions. + * SMMU must be reset in bypass mode. + * Set the ClientPD bit and Clear the USFCFG Bit + */ + u32 val; + val = (in_le32(SMMU_SCR0) | SCR0_CLIENTPD_MASK) & ~(SCR0_USFCFG_MASK); + out_le32(SMMU_SCR0, val); + val = (in_le32(SMMU_NSCR0) | SCR0_CLIENTPD_MASK) & ~(SCR0_USFCFG_MASK); + out_le32(SMMU_NSCR0, val); +#endif +#ifdef CONFIG_FSL_CAAM + return sec_init(); +#endif return 0; } #endif diff --git a/common/cmd_blob.c b/common/cmd_blob.c index d3f22a1afc..ac8b268e0b 100644 --- a/common/cmd_blob.c +++ b/common/cmd_blob.c @@ -73,9 +73,9 @@ static int do_blob(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) len = simple_strtoul(argv[4], NULL, 16); key_addr = simple_strtoul(argv[5], NULL, 16); - km_ptr = (uint8_t *)key_addr; - src_ptr = (uint8_t *)src_addr; - dst_ptr = (uint8_t *)dst_addr; + km_ptr = (uint8_t *)(uintptr_t)key_addr; + src_ptr = (uint8_t *)(uintptr_t)src_addr; + dst_ptr = (uint8_t *)(uintptr_t)dst_addr; if (enc) ret = blob_encap(km_ptr, src_ptr, dst_ptr, len); diff --git a/configs/ls1043ardb_SECURE_BOOT_defconfig b/configs/ls1043ardb_SECURE_BOOT_defconfig new file mode 100644 index 0000000000..d9d6c97809 --- /dev/null +++ b/configs/ls1043ardb_SECURE_BOOT_defconfig @@ -0,0 +1,9 @@ +CONFIG_ARM=y +CONFIG_TARGET_LS1043ARDB=y +CONFIG_SYS_EXTRA_OPTIONS="SYS_FSL_DDR4, SECURE_BOOT" +CONFIG_SYS_NS16550=y +CONFIG_DEFAULT_DEVICE_TREE="fsl-ls1043a-rdb" +CONFIG_OF_CONTROL=y +CONFIG_DM=y +CONFIG_SPI_FLASH=y +CONFIG_DM_SPI=y \ No newline at end of file diff --git a/include/configs/ls1043ardb.h b/include/configs/ls1043ardb.h index 683407499a..585114f3d5 100644 --- a/include/configs/ls1043ardb.h +++ b/include/configs/ls1043ardb.h @@ -291,4 +291,14 @@ #define CONFIG_CMD_EXT2 #endif +#ifdef CONFIG_SECURE_BOOT +#define CONFIG_CMD_HASH +#define CONFIG_SHA_HW_ACCEL +#define CONFIG_CMD_BLOB +/* For LS1043 (ARMv8), ESBC image Address in Header is 64 bit */ +#define CONFIG_ESBC_ADDR_64BIT +#endif + +#include + #endif /* __LS1043ARDB_H__ */ diff --git a/include/fsl_validate.h b/include/fsl_validate.h index 92dd98bb61..a62dc74e69 100644 --- a/include/fsl_validate.h +++ b/include/fsl_validate.h @@ -83,7 +83,9 @@ struct fsl_secboot_img_hdr { u32 sign_len; /* length of the signature in bytes */ union { u32 psgtable; /* ptr to SG table */ +#ifndef CONFIG_ESBC_ADDR_64BIT u32 pimg; /* ptr to ESBC client image */ +#endif }; union { u32 sg_entries; /* no of entries in SG table */ @@ -97,7 +99,12 @@ struct fsl_secboot_img_hdr { u32 reserved1[2]; u32 fsl_uid_1; u32 oem_uid_1; - u32 reserved2[2]; + union { + u32 reserved2[2]; +#ifdef CONFIG_ESBC_ADDR_64BIT + u64 pimg64; /* 64 bit pointer to ESBC Image */ +#endif + }; u32 ie_flag; u32 ie_key_sel; }; From 3a4800a5968f689788d70f7decb000a3d3e1a2f4 Mon Sep 17 00:00:00 2001 From: Aneesh Bansal Date: Tue, 8 Dec 2015 13:54:30 +0530 Subject: [PATCH 30/31] drivers/crypto/fsl: fix endianness issue in RNG For Setting and clearing the bits in SEC Block registers sec_clrbits32() and sec_setbits32() are used which work as per endianness of CAAM block. So these must be used with SEC register address as argument. If the value is read in a local variable, then the functions will not behave correctly where endianness of CAAM and core is different. Signed-off-by: Aneesh Bansal CC: Alex Porosanu Reviewed-by: York Sun --- drivers/crypto/fsl/jr.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/crypto/fsl/jr.c b/drivers/crypto/fsl/jr.c index f63eacb73e..b553e3c583 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) From 989c5f0a8f8694ac92eb0d6cff8745ae8659364f Mon Sep 17 00:00:00 2001 From: Tang Yuantian Date: Wed, 9 Dec 2015 15:32:18 +0800 Subject: [PATCH 31/31] armv8: Add sata support on Layerscape ARMv8 board Freescale ARM-based Layerscape contains a SATA controller which comply with the serial ATA 3.0 specification and the AHCI 1.3 specification. This patch adds SATA feature on ls2080aqds, ls2080ardb and ls1043aqds boards. Signed-off-by: Tang Yuantian Reviewed-by: York Sun --- arch/arm/cpu/armv8/fsl-layerscape/soc.c | 43 +++++++++++++++++++ .../asm/arch-fsl-layerscape/immap_lsch3.h | 4 ++ .../arm/include/asm/arch-fsl-layerscape/soc.h | 31 +++++++++++++ include/configs/ls1043aqds.h | 17 ++++++++ include/configs/ls2080aqds.h | 18 ++++++++ include/configs/ls2080ardb.h | 18 ++++++++ 6 files changed, 131 insertions(+) diff --git a/arch/arm/cpu/armv8/fsl-layerscape/soc.c b/arch/arm/cpu/armv8/fsl-layerscape/soc.c index 8d40405923..984eaf903e 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/soc.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/soc.c @@ -6,6 +6,8 @@ #include #include +#include +#include #include #include #include @@ -157,7 +159,44 @@ void fsl_lsch3_early_init_f(void) erratum_a008336(); } +#ifdef CONFIG_SCSI_AHCI_PLAT +int sata_init(void) +{ + struct ccsr_ahci __iomem *ccsr_ahci; + + ccsr_ahci = (void *)CONFIG_SYS_SATA2; + out_le32(&ccsr_ahci->ppcfg, AHCI_PORT_PHY_1_CFG); + out_le32(&ccsr_ahci->ptc, AHCI_PORT_TRANS_CFG); + + ccsr_ahci = (void *)CONFIG_SYS_SATA1; + out_le32(&ccsr_ahci->ppcfg, AHCI_PORT_PHY_1_CFG); + out_le32(&ccsr_ahci->ptc, AHCI_PORT_TRANS_CFG); + + ahci_init((void __iomem *)CONFIG_SYS_SATA1); + scsi_scan(0); + + return 0; +} +#endif + #elif defined(CONFIG_LS1043A) +#ifdef CONFIG_SCSI_AHCI_PLAT +int sata_init(void) +{ + struct ccsr_ahci __iomem *ccsr_ahci = (void *)CONFIG_SYS_SATA; + + out_le32(&ccsr_ahci->ppcfg, AHCI_PORT_PHY_1_CFG); + out_le32(&ccsr_ahci->pp2c, AHCI_PORT_PHY_2_CFG); + out_le32(&ccsr_ahci->pp3c, AHCI_PORT_PHY_3_CFG); + out_le32(&ccsr_ahci->ptc, AHCI_PORT_TRANS_CFG); + + ahci_init((void __iomem *)CONFIG_SYS_SATA); + scsi_scan(0); + + return 0; +} +#endif + void fsl_lsch2_early_init_f(void) { struct ccsr_cci400 *cci = (struct ccsr_cci400 *)CONFIG_SYS_CCI400_ADDR; @@ -183,6 +222,10 @@ void fsl_lsch2_early_init_f(void) #ifdef CONFIG_BOARD_LATE_INIT int board_late_init(void) { +#ifdef CONFIG_SCSI_AHCI_PLAT + sata_init(); +#endif + return 0; } #endif diff --git a/arch/arm/include/asm/arch-fsl-layerscape/immap_lsch3.h b/arch/arm/include/asm/arch-fsl-layerscape/immap_lsch3.h index cd96604171..91f3ce843a 100644 --- a/arch/arm/include/asm/arch-fsl-layerscape/immap_lsch3.h +++ b/arch/arm/include/asm/arch-fsl-layerscape/immap_lsch3.h @@ -69,6 +69,10 @@ #define TZASC_REGION_ATTRIBUTES_0(x) ((TZASC1_BASE + (x * 0x10000)) + 0x110) #define TZASC_REGION_ID_ACCESS_0(x) ((TZASC1_BASE + (x * 0x10000)) + 0x114) +/* SATA */ +#define AHCI_BASE_ADDR1 (CONFIG_SYS_IMMR + 0x02200000) +#define AHCI_BASE_ADDR2 (CONFIG_SYS_IMMR + 0x02210000) + /* PCIe */ #define CONFIG_SYS_PCIE1_ADDR (CONFIG_SYS_IMMR + 0x2400000) #define CONFIG_SYS_PCIE2_ADDR (CONFIG_SYS_IMMR + 0x2500000) diff --git a/arch/arm/include/asm/arch-fsl-layerscape/soc.h b/arch/arm/include/asm/arch-fsl-layerscape/soc.h index 504c1f9197..1565592996 100644 --- a/arch/arm/include/asm/arch-fsl-layerscape/soc.h +++ b/arch/arm/include/asm/arch-fsl-layerscape/soc.h @@ -51,6 +51,37 @@ struct cpu_type { #define SVR_SOC_VER(svr) (((svr) >> 8) & SVR_WO_E) #define IS_E_PROCESSOR(svr) (!((svr >> 8) & 0x1)) +/* ahci port register default value */ +#define AHCI_PORT_PHY_1_CFG 0xa003fffe +#define AHCI_PORT_PHY_2_CFG 0x28184d1f +#define AHCI_PORT_PHY_3_CFG 0x0e081509 +#define AHCI_PORT_TRANS_CFG 0x08000029 + +/* AHCI (sata) register map */ +struct ccsr_ahci { + u32 res1[0xa4/4]; /* 0x0 - 0xa4 */ + u32 pcfg; /* port config */ + u32 ppcfg; /* port phy1 config */ + u32 pp2c; /* port phy2 config */ + u32 pp3c; /* port phy3 config */ + u32 pp4c; /* port phy4 config */ + u32 pp5c; /* port phy5 config */ + u32 axicc; /* AXI cache control */ + u32 paxic; /* port AXI config */ + u32 axipc; /* AXI PROT control */ + u32 ptc; /* port Trans Config */ + u32 pts; /* port Trans Status */ + u32 plc; /* port link config */ + u32 plc1; /* port link config1 */ + u32 plc2; /* port link config2 */ + u32 pls; /* port link status */ + u32 pls1; /* port link status1 */ + u32 pcmdc; /* port CMD config */ + u32 ppcs; /* port phy control status */ + u32 pberr; /* port 0/1 BIST error */ + u32 cmds; /* port 0/1 CMD status error */ +}; + #ifdef CONFIG_FSL_LSCH3 void fsl_lsch3_early_init_f(void); #elif defined(CONFIG_FSL_LSCH2) diff --git a/include/configs/ls1043aqds.h b/include/configs/ls1043aqds.h index 4aeb2382fc..398f1c3f77 100644 --- a/include/configs/ls1043aqds.h +++ b/include/configs/ls1043aqds.h @@ -88,6 +88,23 @@ unsigned long get_board_ddr_clk(void); #define CONFIG_SYS_FSL_PBL_RCW board/freescale/ls1043aqds/ls1043aqds_rcw_sd_ifc.cfg #endif +/* SATA */ +#define CONFIG_LIBATA +#define CONFIG_SCSI_AHCI +#define CONFIG_SCSI_AHCI_PLAT +#define CONFIG_CMD_SCSI +#define CONFIG_CMD_FAT +#define CONFIG_CMD_EXT2 +#define CONFIG_DOS_PARTITION +#define CONFIG_BOARD_LATE_INIT + +#define CONFIG_SYS_SATA AHCI_BASE_ADDR + +#define CONFIG_SYS_SCSI_MAX_SCSI_ID 1 +#define CONFIG_SYS_SCSI_MAX_LUN 1 +#define CONFIG_SYS_SCSI_MAX_DEVICE (CONFIG_SYS_SCSI_MAX_SCSI_ID * \ + CONFIG_SYS_SCSI_MAX_LUN) + /* * IFC Definitions */ diff --git a/include/configs/ls2080aqds.h b/include/configs/ls2080aqds.h index 54bcae9fe8..ba84248081 100644 --- a/include/configs/ls2080aqds.h +++ b/include/configs/ls2080aqds.h @@ -40,6 +40,24 @@ unsigned long get_board_ddr_clk(void); #endif #define CONFIG_FSL_DDR_BIST /* enable built-in memory test */ +/* SATA */ +#define CONFIG_LIBATA +#define CONFIG_SCSI_AHCI +#define CONFIG_SCSI_AHCI_PLAT +#define CONFIG_CMD_SCSI +#define CONFIG_CMD_FAT +#define CONFIG_CMD_EXT2 +#define CONFIG_DOS_PARTITION +#define CONFIG_BOARD_LATE_INIT + +#define CONFIG_SYS_SATA1 AHCI_BASE_ADDR1 +#define CONFIG_SYS_SATA2 AHCI_BASE_ADDR2 + +#define CONFIG_SYS_SCSI_MAX_SCSI_ID 1 +#define CONFIG_SYS_SCSI_MAX_LUN 1 +#define CONFIG_SYS_SCSI_MAX_DEVICE (CONFIG_SYS_SCSI_MAX_SCSI_ID * \ + CONFIG_SYS_SCSI_MAX_LUN) + /* undefined CONFIG_FSL_DDR_SYNC_REFRESH for simulator */ #define CONFIG_SYS_NOR0_CSPR_EXT (0x0) diff --git a/include/configs/ls2080ardb.h b/include/configs/ls2080ardb.h index faccc6f35b..116dbcde5b 100644 --- a/include/configs/ls2080ardb.h +++ b/include/configs/ls2080ardb.h @@ -42,6 +42,24 @@ unsigned long get_board_sys_clk(void); #endif #define CONFIG_FSL_DDR_BIST /* enable built-in memory test */ +/* SATA */ +#define CONFIG_LIBATA +#define CONFIG_SCSI_AHCI +#define CONFIG_SCSI_AHCI_PLAT +#define CONFIG_CMD_SCSI +#define CONFIG_CMD_FAT +#define CONFIG_CMD_EXT2 +#define CONFIG_DOS_PARTITION +#define CONFIG_BOARD_LATE_INIT + +#define CONFIG_SYS_SATA1 AHCI_BASE_ADDR1 +#define CONFIG_SYS_SATA2 AHCI_BASE_ADDR2 + +#define CONFIG_SYS_SCSI_MAX_SCSI_ID 1 +#define CONFIG_SYS_SCSI_MAX_LUN 1 +#define CONFIG_SYS_SCSI_MAX_DEVICE (CONFIG_SYS_SCSI_MAX_SCSI_ID * \ + CONFIG_SYS_SCSI_MAX_LUN) + /* undefined CONFIG_FSL_DDR_SYNC_REFRESH for simulator */ #define CONFIG_SYS_NOR0_CSPR_EXT (0x0)